Improve platform types support (#142) · sveltejs/devalue@5590634 · GitHub
Skip to content

Commit 5590634

Browse files
mrkishiRich-Harris
andauthored
Improve platform types support (#142)
* fix: rename test file so uvu picks it up * chore: add simple benchmarks Based on Svelte's benchmark scaffolding. * feat: simplify TypedArray slices * feat: use native alternatives to encode/decode base64 * feat: whitelist `Float16Array` * fix: guarantee flatten return type * chore: add prettier configuration Add a `.prettierrc` file matching Svelte's. * chore: add missing (boxed) primitives tests * fix: support boxed bigints and boxed sentinel values * fix: reject `Symbol`s instead of producing invalid output * fix: correct typed array construction in `uneval`'s reference path * chore: add more repetition tests * fix: handle missing types in `uneval`'s reference path --------- Co-authored-by: Rich Harris <rich.harris@vercel.com>
1 parent 57f73fc commit 5590634

4 files changed

Lines changed: 142 additions & 16 deletions

File tree

‎.changeset/petite-bushes-guess.md‎

Lines changed: 5 additions & 0 deletions

‎src/stringify.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@ export function stringify(value, reducers) {
6767

6868
if (typeof thing === 'function') {
6969
throw new DevalueError(`Cannot stringify a function`, keys, thing, value);
70+
} else if (typeof thing === 'symbol') {
71+
throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value);
7072
}
7173

7274
let str = '';

‎src/uneval.js‎

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ export function uneval(value, replacer) {
136136
keys.pop();
137137
}
138138
}
139+
} else if (typeof thing === 'symbol') {
140+
throw new DevalueError(`Cannot stringify a Symbol primitive`, keys, thing, value);
139141
}
140142
}
141143

@@ -284,11 +286,11 @@ export function uneval(value, replacer) {
284286
case 'BigUint64Array': {
285287
let str = `new ${type}`;
286288

287-
if (counts.get(thing.buffer) === 1) {
289+
if (!names.has(thing.buffer)) {
288290
const array = new thing.constructor(thing.buffer);
289291
str += `([${array}])`;
290292
} else {
291-
str += `([${stringify(thing.buffer)}])`;
293+
str += `(${stringify(thing.buffer)})`;
292294
}
293295

294296
// handle subarrays
@@ -359,6 +361,7 @@ export function uneval(value, replacer) {
359361
case 'Number':
360362
case 'String':
361363
case 'Boolean':
364+
case 'BigInt':
362365
values.push(`Object(${stringify(thing.valueOf())})`);
363366
break;
364367

@@ -370,6 +373,14 @@ export function uneval(value, replacer) {
370373
values.push(`new Date(${thing.getTime()})`);
371374
break;
372375

376+
case 'URL':
377+
values.push(`new URL(${stringify_string(thing.toString())})`);
378+
break;
379+
380+
case 'URLSearchParams':
381+
values.push(`new URLSearchParams(${stringify_string(thing.toString())})`);
382+
break;
383+
373384
case 'Array':
374385
values.push(`Array(${thing.length})`);
375386
/** @type {any[]} */ (thing).forEach((v, i) => {
@@ -395,8 +406,41 @@ export function uneval(value, replacer) {
395406
);
396407
break;
397408

409+
case 'Int8Array':
410+
case 'Uint8Array':
411+
case 'Uint8ClampedArray':
412+
case 'Int16Array':
413+
case 'Uint16Array':
414+
case 'Float16Array':
415+
case 'Int32Array':
416+
case 'Uint32Array':
417+
case 'Float32Array':
418+
case 'Float64Array':
419+
case 'BigInt64Array':
420+
case 'BigUint64Array': {
421+
let str = `new ${type}`;
422+
423+
if (!names.has(thing.buffer)) {
424+
const array = new thing.constructor(thing.buffer);
425+
str += `([${array}])`;
426+
} else {
427+
str += `(${stringify(thing.buffer)})`;
428+
}
429+
430+
// handle subarrays
431+
if (thing.byteLength !== thing.buffer.byteLength) {
432+
const start = thing.byteOffset / thing.BYTES_PER_ELEMENT;
433+
const end = start + thing.length;
434+
str += `.subarray(${start},${end})`;
435+
}
436+
437+
values.push(`{}`);
438+
statements.push(`${name}=${str}`);
439+
break;
440+
}
441+
398442
case 'ArrayBuffer':
399-
values.push(`new Uint8Array([${new Uint8Array(thing).join(',')}]).buffer`);
443+
values.push(`new Uint8Array([${new Uint8Array(thing)}]).buffer`);
400444
break;
401445

402446
default:

‎test/index.test.js‎

Lines changed: 88 additions & 13 deletions

0 commit comments

Comments
 (0)