diff --git a/.changeset/dataview-subview.md b/.changeset/dataview-subview.md new file mode 100644 index 00000000..dfc1d3b0 --- /dev/null +++ b/.changeset/dataview-subview.md @@ -0,0 +1,5 @@ +--- +"devalue": patch +--- + +fix: serialize DataView subviews with the correct byte offset and length diff --git a/src/stringify.js b/src/stringify.js index 35dadffb..ce8b1150 100644 --- a/src/stringify.js +++ b/src/stringify.js @@ -289,15 +289,13 @@ function run(async, value, reducers) { case 'Float32Array': case 'Float64Array': case 'BigInt64Array': - case 'BigUint64Array': - case 'DataView': { + case 'BigUint64Array': { /** @type {import("./types.js").TypedArray} */ const typedArray = thing; str = '["' + type + '",' + flatten(typedArray.buffer); // handle subarrays if (typedArray.byteLength !== typedArray.buffer.byteLength) { - // to be used with `new TypedArray(buffer, byteOffset, length)` str += `,${typedArray.byteOffset},${typedArray.length}`; } @@ -305,6 +303,19 @@ function run(async, value, reducers) { break; } + case 'DataView': { + /** @type {DataView} */ + const view = thing; + str = '["' + type + '",' + flatten(view.buffer); + + if (view.byteLength !== view.buffer.byteLength) { + str += `,${view.byteOffset},${view.byteLength}`; + } + + str += ']'; + break; + } + case 'ArrayBuffer': { /** @type {ArrayBuffer} */ const arraybuffer = thing; diff --git a/src/uneval.js b/src/uneval.js index 5c1f39e3..af2afbb3 100644 --- a/src/uneval.js +++ b/src/uneval.js @@ -318,7 +318,7 @@ export function uneval(value, replacer) { // handle subviews if (thing.byteLength !== thing.buffer.byteLength) { - str += `,${thing.startOffset},${thing.byteLength}`; + str += `,${thing.byteOffset},${thing.byteLength}`; } return str + ')'; diff --git a/test/index.test.js b/test/index.test.js index a80125a8..52bac4e7 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -311,6 +311,12 @@ const fixtures = { js: 'new DataView(new Uint8Array([1,2,3]).buffer)', json: '[["DataView",1],["ArrayBuffer","AQID"]]' }, + { + name: 'DataView subview', + value: new DataView(new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer, 2, 4), + js: 'new DataView(new Uint8Array([0,1,2,3,4,5,6,7,8,9]).buffer,2,4)', + json: '[["DataView",1,2,4],["ArrayBuffer","AAECAwQFBgcICQ=="]]' + }, { name: 'URL', value: new URL('https://user:password@example.com/