Skip to content

Commit 64afb00

Browse files
committed
feat: implement buffers() for RawSource, OriginalSource, PrefixSource, ReplaceSource, SourceMapSource
Extend the buffers() API to every concrete Source class so callers always get a Buffer[] without falling back to the abstract Source default. Each single-buffer-backed class returns [this.buffer()]. ReplaceSource delegates to the underlying source's buffers() when no replacements are queued and otherwise materializes the replaced source into a single buffer. https://claude.ai/code/session_01EHhGq9PRFRGefVtwwasCqZ
1 parent 7c520c2 commit 64afb00

11 files changed

Lines changed: 134 additions & 0 deletions

.changeset/buffers-all-sources.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"webpack-sources": patch
3+
---
4+
5+
Add explicit `buffers()` implementations to `RawSource`, `OriginalSource`, `PrefixSource`, `ReplaceSource`, and `SourceMapSource`. `ReplaceSource` delegates to the underlying source's `buffers()` when no replacements are queued.

lib/OriginalSource.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,13 @@ class OriginalSource extends Source {
8282
return this._valueAsBuffer;
8383
}
8484

85+
/**
86+
* @returns {Buffer[]} buffers
87+
*/
88+
buffers() {
89+
return [this.buffer()];
90+
}
91+
8592
/**
8693
* Override Source.prototype.size (= `this.buffer().length`) to avoid
8794
* allocating a Buffer just to read the byte length, and memoize the

lib/PrefixSource.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ class PrefixSource extends Source {
6464

6565
// TODO efficient buffer() implementation
6666

67+
/**
68+
* @returns {Buffer[]} buffers
69+
*/
70+
buffers() {
71+
return [this.buffer()];
72+
}
73+
6774
/**
6875
* @param {MapOptions=} options map options
6976
* @returns {RawSourceMap | null} map

lib/RawSource.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,13 @@ class RawSource extends Source {
9393
return this._valueAsBuffer;
9494
}
9595

96+
/**
97+
* @returns {Buffer[]} buffers
98+
*/
99+
buffers() {
100+
return [this.buffer()];
101+
}
102+
96103
/**
97104
* Override Source.prototype.size (= `this.buffer().length`) to avoid
98105
* allocating a Buffer just to read the byte length, and memoize the

lib/ReplaceSource.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,28 @@ class ReplaceSource extends Source {
178178
return result.join("");
179179
}
180180

181+
/**
182+
* @returns {Buffer} buffer
183+
*/
184+
buffer() {
185+
if (this._replacements.length === 0) {
186+
return this._source.buffer();
187+
}
188+
return super.buffer();
189+
}
190+
191+
/**
192+
* @returns {Buffer[]} buffers
193+
*/
194+
buffers() {
195+
if (this._replacements.length === 0) {
196+
return typeof this._source.buffers === "function"
197+
? this._source.buffers()
198+
: [this._source.buffer()];
199+
}
200+
return [this.buffer()];
201+
}
202+
181203
/**
182204
* @param {MapOptions=} options map options
183205
* @returns {RawSourceMap | null} map

lib/SourceMapSource.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,13 @@ class SourceMapSource extends Source {
143143
return this._valueAsBuffer;
144144
}
145145

146+
/**
147+
* @returns {Buffer[]} buffers
148+
*/
149+
buffers() {
150+
return [this.buffer()];
151+
}
152+
146153
/**
147154
* Override Source.prototype.size (= `this.buffer().length`) to avoid
148155
* allocating a Buffer just to read the byte length, and memoize the

test/OriginalSource.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,23 @@ describe.each([
107107
expect(source.getName()).toBe("file.js");
108108
});
109109

110+
it("should expose buffers() returning a single-entry Buffer[]", () => {
111+
const content = "Line1\nLine2\n";
112+
const source = new OriginalSource(content, "file.js");
113+
const buffers = source.buffers();
114+
expect(Array.isArray(buffers)).toBe(true);
115+
expect(buffers).toHaveLength(1);
116+
expect(buffers[0]).toEqual(Buffer.from(content));
117+
});
118+
119+
it("should reuse the underlying buffer in buffers() when constructed from a Buffer", () => {
120+
const buffer = Buffer.from("Line1\nLine2\n");
121+
const source = new OriginalSource(buffer, "file.js");
122+
const buffers = source.buffers();
123+
expect(buffers).toHaveLength(1);
124+
expect(buffers[0]).toBe(buffer);
125+
});
126+
110127
it("should compute map correctly from buffer-backed source", () => {
111128
const content = "Line1\nLine2\n";
112129
const source = new OriginalSource(Buffer.from(content), "file.js");

test/PrefixSource.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,13 @@ describe("prefixSource", () => {
169169
expect(source.source()).toBe("hello\nworld\n");
170170
expect(source.sourceAndMap().source).toBe("hello\nworld\n");
171171
});
172+
173+
it("should expose buffers() returning the prefixed source as a single buffer", () => {
174+
const source = new PrefixSource("> ", new RawSource("hello\nworld"));
175+
const buffers = source.buffers();
176+
expect(Array.isArray(buffers)).toBe(true);
177+
expect(buffers).toHaveLength(1);
178+
expect(buffers[0]).toEqual(Buffer.from("> hello\n> world"));
179+
expect(Buffer.concat(buffers)).toEqual(source.buffer());
180+
});
172181
});

test/RawSource.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,4 +166,21 @@ describe("rawSource", () => {
166166
expect(source.source().toString("utf8")).toEqual(CODE_STRING);
167167
});
168168
});
169+
170+
it("should expose buffers() returning a single-entry Buffer[]", () => {
171+
const source = new RawSource(CODE_STRING);
172+
const buffers = source.buffers();
173+
expect(Array.isArray(buffers)).toBe(true);
174+
expect(buffers).toHaveLength(1);
175+
expect(buffers[0]).toEqual(Buffer.from(CODE_STRING));
176+
expect(Buffer.concat(buffers)).toEqual(source.buffer());
177+
});
178+
179+
it("should reuse the underlying buffer in buffers() when constructed from a Buffer", () => {
180+
const buffer = Buffer.from(CODE_STRING);
181+
const source = new RawSource(buffer);
182+
const buffers = source.buffers();
183+
expect(buffers).toHaveLength(1);
184+
expect(buffers[0]).toBe(buffer);
185+
});
169186
});

test/ReplaceSource.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,4 +451,23 @@ export default function StaticPage(_ref) {
451451
expect(source.source()).toBe("Hello You");
452452
expect(source.sourceAndMap()).toHaveProperty("source", "Hello You");
453453
});
454+
455+
it("should expose buffers() reflecting the replaced source", () => {
456+
const source = new ReplaceSource(new RawSource("Hello World"));
457+
source.replace(6, 10, "You");
458+
const buffers = source.buffers();
459+
expect(Array.isArray(buffers)).toBe(true);
460+
expect(buffers).toHaveLength(1);
461+
expect(buffers[0]).toEqual(Buffer.from("Hello You"));
462+
expect(Buffer.concat(buffers)).toEqual(source.buffer());
463+
});
464+
465+
it("should delegate buffers() to the underlying source when no replacements", () => {
466+
const inner = new RawSource(Buffer.from("untouched"));
467+
const source = new ReplaceSource(inner);
468+
const buffers = source.buffers();
469+
expect(buffers).toHaveLength(1);
470+
expect(buffers[0]).toBe(inner.buffer());
471+
expect(source.buffer()).toBe(inner.buffer());
472+
});
454473
});

0 commit comments

Comments
 (0)