seroval 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/README.md +15 -3
  2. package/dist/cjs/development/index.cjs +1431 -991
  3. package/dist/cjs/development/index.cjs.map +4 -4
  4. package/dist/cjs/production/index.cjs +3 -3
  5. package/dist/esm/development/index.mjs +1431 -991
  6. package/dist/esm/development/index.mjs.map +4 -4
  7. package/dist/esm/production/index.mjs +3 -3
  8. package/dist/types/assert.d.ts +1 -1
  9. package/dist/types/compat.d.ts +1 -1
  10. package/dist/types/context.d.ts +13 -7
  11. package/dist/types/index.d.ts +3 -4
  12. package/dist/types/string.d.ts +3 -0
  13. package/dist/types/tree/UnsupportedTypeError.d.ts +3 -0
  14. package/dist/types/tree/async.d.ts +3 -3
  15. package/dist/types/tree/constants.d.ts +11 -0
  16. package/dist/types/tree/deserialize.d.ts +2 -2
  17. package/dist/types/tree/primitives.d.ts +11 -14
  18. package/dist/types/tree/serialize.d.ts +2 -2
  19. package/dist/types/tree/shared.d.ts +10 -8
  20. package/dist/types/tree/sync.d.ts +3 -3
  21. package/dist/types/tree/types.d.ts +106 -70
  22. package/dist/types/tree/web-api.d.ts +4 -2
  23. package/dist/types/types.d.ts +4 -4
  24. package/package.json +11 -8
  25. package/src/assert.ts +2 -2
  26. package/src/compat.ts +1 -2
  27. package/src/context.ts +24 -13
  28. package/src/get-identifier.ts +1 -1
  29. package/src/index.ts +35 -26
  30. package/src/string.ts +53 -0
  31. package/src/tree/UnsupportedTypeError.ts +8 -0
  32. package/src/tree/async.ts +313 -222
  33. package/src/tree/constants.ts +72 -0
  34. package/src/tree/deserialize.ts +239 -119
  35. package/src/tree/primitives.ts +154 -143
  36. package/src/tree/reference.ts +4 -3
  37. package/src/tree/serialize.ts +394 -170
  38. package/src/tree/shared.ts +31 -22
  39. package/src/tree/symbols.ts +13 -13
  40. package/src/tree/sync.ts +288 -191
  41. package/src/tree/types.ts +173 -91
  42. package/src/tree/web-api.ts +59 -6
  43. package/src/types.ts +7 -3
  44. package/dist/types/quote.d.ts +0 -2
  45. package/src/quote.ts +0 -56
@@ -1,145 +1,78 @@
1
1
  import assert from '../assert';
2
2
  import { Feature } from '../compat';
3
- import { ParserContext } from '../context';
4
- import quote from '../quote';
5
- import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
6
- import { getReferenceID } from './reference';
7
- import { INV_SYMBOL_REF, WellKnownSymbols } from './symbols';
3
+ import type { ParserContext } from '../context';
4
+ import { createIndexedValue } from '../context';
5
+ import { serializeString } from '../string';
6
+ import type { BigIntTypedArrayValue, TypedArrayValue } from '../types';
7
+ import UnsupportedTypeError from './UnsupportedTypeError';
8
8
  import {
9
+ INFINITY_NODE,
10
+ NEG_INFINITY_NODE,
11
+ NAN_NODE,
12
+ NEG_ZERO_NODE,
13
+ } from './constants';
14
+ import { getReferenceID, hasReferenceID } from './reference';
15
+ import type { WellKnownSymbols } from './symbols';
16
+ import { INV_SYMBOL_REF } from './symbols';
17
+ import type {
9
18
  SerovalBigIntNode,
10
19
  SerovalBigIntTypedArrayNode,
11
- SerovalBooleanNode,
12
20
  SerovalDateNode,
13
- SerovalInfinityNode,
14
- SerovalNaNNode,
15
- SerovalNegativeInfinityNode,
16
- SerovalNegativeZeroNode,
17
- SerovalNodeType,
18
- SerovalNullNode,
19
- SerovalNumberNode,
20
21
  SerovalIndexedValueNode,
21
22
  SerovalRegExpNode,
22
23
  SerovalStringNode,
23
24
  SerovalTypedArrayNode,
24
- SerovalUndefinedNode,
25
25
  SerovalWKSymbolNode,
26
26
  SerovalReferenceNode,
27
+ SerovalArrayBufferNode,
28
+ SerovalDataViewNode,
29
+ SerovalNode,
30
+ } from './types';
31
+ import {
32
+ SerovalNodeType,
27
33
  } from './types';
28
34
 
29
- export const TRUE_NODE: SerovalBooleanNode = {
30
- t: SerovalNodeType.Boolean,
31
- i: undefined,
32
- s: true,
33
- l: undefined,
34
- c: undefined,
35
- m: undefined,
36
- d: undefined,
37
- a: undefined,
38
- f: undefined,
39
- };
40
- export const FALSE_NODE: SerovalBooleanNode = {
41
- t: SerovalNodeType.Boolean,
42
- i: undefined,
43
- s: false,
44
- l: undefined,
45
- c: undefined,
46
- m: undefined,
47
- d: undefined,
48
- a: undefined,
49
- f: undefined,
50
- };
51
- export const UNDEFINED_NODE: SerovalUndefinedNode = {
52
- t: SerovalNodeType.Undefined,
53
- i: undefined,
54
- s: undefined,
55
- l: undefined,
56
- c: undefined,
57
- m: undefined,
58
- d: undefined,
59
- a: undefined,
60
- f: undefined,
61
- };
62
- export const NULL_NODE: SerovalNullNode = {
63
- t: SerovalNodeType.Null,
64
- i: undefined,
65
- s: undefined,
66
- l: undefined,
67
- c: undefined,
68
- m: undefined,
69
- d: undefined,
70
- a: undefined,
71
- f: undefined,
72
- };
73
- export const NEG_ZERO_NODE: SerovalNegativeZeroNode = {
74
- t: SerovalNodeType.NegativeZero,
75
- i: undefined,
76
- s: undefined,
77
- l: undefined,
78
- c: undefined,
79
- m: undefined,
80
- d: undefined,
81
- a: undefined,
82
- f: undefined,
83
- };
84
- export const INFINITY_NODE: SerovalInfinityNode = {
85
- t: SerovalNodeType.Infinity,
86
- i: undefined,
87
- s: undefined,
88
- l: undefined,
89
- c: undefined,
90
- m: undefined,
91
- d: undefined,
92
- a: undefined,
93
- f: undefined,
94
- };
95
- export const NEG_INFINITY_NODE: SerovalNegativeInfinityNode = {
96
- t: SerovalNodeType.NegativeInfinity,
97
- i: undefined,
98
- s: undefined,
99
- l: undefined,
100
- c: undefined,
101
- m: undefined,
102
- d: undefined,
103
- a: undefined,
104
- f: undefined,
105
- };
106
- export const NAN_NODE: SerovalNaNNode = {
107
- t: SerovalNodeType.NaN,
108
- i: undefined,
109
- s: undefined,
110
- l: undefined,
111
- c: undefined,
112
- m: undefined,
113
- d: undefined,
114
- a: undefined,
115
- f: undefined,
116
- };
117
-
118
- export function createNumberNode(value: number): SerovalNumberNode {
119
- return {
120
- t: SerovalNodeType.Number,
121
- i: undefined,
122
- s: value,
123
- l: undefined,
124
- c: undefined,
125
- m: undefined,
126
- d: undefined,
127
- a: undefined,
128
- f: undefined,
129
- };
35
+ export function createNumberNode(value: number): SerovalNode {
36
+ switch (value) {
37
+ case Infinity:
38
+ return INFINITY_NODE;
39
+ case -Infinity:
40
+ return NEG_INFINITY_NODE;
41
+ default:
42
+ // eslint-disable-next-line no-self-compare
43
+ if (value !== value) {
44
+ return NAN_NODE;
45
+ }
46
+ if (Object.is(value, -0)) {
47
+ return NEG_ZERO_NODE;
48
+ }
49
+ return {
50
+ t: SerovalNodeType.Number,
51
+ i: undefined,
52
+ s: value,
53
+ l: undefined,
54
+ c: undefined,
55
+ m: undefined,
56
+ d: undefined,
57
+ a: undefined,
58
+ f: undefined,
59
+ b: undefined,
60
+ };
61
+ }
130
62
  }
131
63
 
132
64
  export function createStringNode(value: string): SerovalStringNode {
133
65
  return {
134
66
  t: SerovalNodeType.String,
135
67
  i: undefined,
136
- s: quote(value),
68
+ s: serializeString(value),
137
69
  l: undefined,
138
70
  c: undefined,
139
71
  m: undefined,
140
72
  d: undefined,
141
73
  a: undefined,
142
74
  f: undefined,
75
+ b: undefined,
143
76
  };
144
77
  }
145
78
 
@@ -147,7 +80,7 @@ export function createBigIntNode(
147
80
  ctx: ParserContext,
148
81
  current: bigint,
149
82
  ): SerovalBigIntNode {
150
- assert(ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
83
+ assert(ctx.features & Feature.BigInt, new UnsupportedTypeError(current));
151
84
  return {
152
85
  t: SerovalNodeType.BigInt,
153
86
  i: undefined,
@@ -158,6 +91,7 @@ export function createBigIntNode(
158
91
  d: undefined,
159
92
  a: undefined,
160
93
  f: undefined,
94
+ b: undefined,
161
95
  };
162
96
  }
163
97
 
@@ -172,6 +106,7 @@ export function createIndexedValueNode(id: number): SerovalIndexedValueNode {
172
106
  d: undefined,
173
107
  a: undefined,
174
108
  f: undefined,
109
+ b: undefined,
175
110
  };
176
111
  }
177
112
 
@@ -186,6 +121,7 @@ export function createDateNode(id: number, current: Date): SerovalDateNode {
186
121
  d: undefined,
187
122
  f: undefined,
188
123
  a: undefined,
124
+ b: undefined,
189
125
  };
190
126
  }
191
127
 
@@ -200,31 +136,62 @@ export function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode
200
136
  d: undefined,
201
137
  a: undefined,
202
138
  f: undefined,
139
+ b: undefined,
140
+ };
141
+ }
142
+
143
+ export function createArrayBufferNode(
144
+ id: number,
145
+ current: ArrayBuffer,
146
+ ): SerovalArrayBufferNode {
147
+ const bytes = new Uint8Array(current);
148
+ const len = bytes.length;
149
+ const values = new Array<number>(len);
150
+ for (let i = 0; i < len; i++) {
151
+ values[i] = bytes[i];
152
+ }
153
+ return {
154
+ t: SerovalNodeType.ArrayBuffer,
155
+ i: id,
156
+ s: values,
157
+ l: undefined,
158
+ c: undefined,
159
+ m: undefined,
160
+ d: undefined,
161
+ a: undefined,
162
+ f: undefined,
163
+ b: undefined,
203
164
  };
204
165
  }
205
166
 
167
+ export function serializeArrayBuffer(
168
+ ctx: ParserContext,
169
+ current: ArrayBuffer,
170
+ ): SerovalNode {
171
+ const id = createIndexedValue(ctx, current);
172
+ if (ctx.markedRefs.has(id)) {
173
+ return createIndexedValueNode(id);
174
+ }
175
+ return createArrayBufferNode(id, current);
176
+ }
177
+
206
178
  export function createTypedArrayNode(
207
179
  ctx: ParserContext,
208
180
  id: number,
209
181
  current: TypedArrayValue,
210
182
  ): SerovalTypedArrayNode {
211
- const constructor = current.constructor.name;
212
- assert(ctx.features & Feature.TypedArray, `Unsupported value type "${constructor}"`);
213
- const len = current.length;
214
- const values = new Array<string>(len);
215
- for (let i = 0; i < len; i++) {
216
- values[i] = '' + current[i];
217
- }
183
+ assert(ctx.features & Feature.TypedArray, new UnsupportedTypeError(current));
218
184
  return {
219
185
  t: SerovalNodeType.TypedArray,
220
186
  i: id,
221
- s: values,
222
- l: current.byteOffset,
223
- c: constructor,
187
+ s: undefined,
188
+ l: current.length,
189
+ c: current.constructor.name,
224
190
  m: undefined,
225
191
  d: undefined,
226
192
  a: undefined,
227
- f: undefined,
193
+ f: serializeArrayBuffer(ctx, current.buffer),
194
+ b: current.byteOffset,
228
195
  };
229
196
  }
230
197
 
@@ -235,38 +202,34 @@ export function createBigIntTypedArrayNode(
235
202
  id: number,
236
203
  current: BigIntTypedArrayValue,
237
204
  ): SerovalBigIntTypedArrayNode {
238
- const constructor = current.constructor.name;
239
205
  assert(
240
206
  (ctx.features & BIGINT_FLAG) === BIGINT_FLAG,
241
- `Unsupported value type "${constructor}"`,
207
+ new UnsupportedTypeError(current),
242
208
  );
243
- const len = current.length;
244
- const values = new Array<string>(len);
245
- for (let i = 0; i < len; i++) {
246
- values[i] = '' + current[i];
247
- }
248
209
  return {
249
210
  t: SerovalNodeType.BigIntTypedArray,
250
211
  i: id,
251
- s: values,
252
- l: current.byteOffset,
253
- c: constructor,
212
+ s: undefined,
213
+ l: current.length,
214
+ c: current.constructor.name,
254
215
  m: undefined,
255
216
  d: undefined,
256
217
  a: undefined,
257
- f: undefined,
218
+ f: serializeArrayBuffer(ctx, current.buffer),
219
+ b: current.byteOffset,
258
220
  };
259
221
  }
260
222
 
261
223
  export function createWKSymbolNode(
262
224
  ctx: ParserContext,
225
+ id: number,
263
226
  current: WellKnownSymbols,
264
227
  ): SerovalWKSymbolNode {
265
- assert(ctx.features & Feature.Symbol, 'Unsupported type "symbol"');
266
- assert(current in INV_SYMBOL_REF, 'seroval only supports well-known symbols');
228
+ assert(ctx.features & Feature.Symbol, new UnsupportedTypeError(current));
229
+ assert(current in INV_SYMBOL_REF, new Error('Only well-known symbols are supported.'));
267
230
  return {
268
231
  t: SerovalNodeType.WKSymbol,
269
- i: undefined,
232
+ i: id,
270
233
  s: INV_SYMBOL_REF[current],
271
234
  l: undefined,
272
235
  c: undefined,
@@ -274,6 +237,7 @@ export function createWKSymbolNode(
274
237
  d: undefined,
275
238
  a: undefined,
276
239
  f: undefined,
240
+ b: undefined,
277
241
  };
278
242
  }
279
243
 
@@ -284,12 +248,59 @@ export function createReferenceNode<T>(
284
248
  return {
285
249
  t: SerovalNodeType.Reference,
286
250
  i: id,
287
- s: quote(getReferenceID(ref)),
251
+ s: serializeString(getReferenceID(ref)),
288
252
  l: undefined,
289
253
  c: undefined,
290
254
  m: undefined,
291
255
  d: undefined,
292
256
  a: undefined,
293
257
  f: undefined,
258
+ b: undefined,
259
+ };
260
+ }
261
+
262
+ export function createDataViewNode(
263
+ ctx: ParserContext,
264
+ id: number,
265
+ current: DataView,
266
+ ): SerovalDataViewNode {
267
+ return {
268
+ t: SerovalNodeType.DataView,
269
+ i: id,
270
+ s: undefined,
271
+ l: current.byteLength,
272
+ c: undefined,
273
+ m: undefined,
274
+ d: undefined,
275
+ a: undefined,
276
+ f: serializeArrayBuffer(ctx, current.buffer),
277
+ b: current.byteOffset,
294
278
  };
295
279
  }
280
+
281
+ export function createSymbolNode(
282
+ ctx: ParserContext,
283
+ current: symbol,
284
+ ): SerovalNode {
285
+ const id = createIndexedValue(ctx, current);
286
+ if (ctx.markedRefs.has(id)) {
287
+ return createIndexedValueNode(id);
288
+ }
289
+ if (hasReferenceID(current)) {
290
+ return createReferenceNode(id, current);
291
+ }
292
+ return createWKSymbolNode(ctx, id, current as WellKnownSymbols);
293
+ }
294
+
295
+ export function createFunctionNode(
296
+ ctx: ParserContext,
297
+ // eslint-disable-next-line @typescript-eslint/ban-types
298
+ current: Function,
299
+ ): SerovalNode {
300
+ assert(hasReferenceID(current), new Error('Cannot serialize function without reference ID.'));
301
+ const id = createIndexedValue(ctx, current);
302
+ if (ctx.markedRefs.has(id)) {
303
+ return createIndexedValueNode(id);
304
+ }
305
+ return createReferenceNode(id, current);
306
+ }
@@ -1,3 +1,4 @@
1
+ /* eslint-disable @typescript-eslint/no-unnecessary-condition */
1
2
  /* eslint-disable no-restricted-globals */
2
3
  import assert from '../assert';
3
4
 
@@ -19,12 +20,12 @@ export function hasReference(id: string): boolean {
19
20
  }
20
21
 
21
22
  export function getReferenceID<T>(value: T): string {
22
- assert(hasReferenceID(value), 'Missing reference id');
23
- return REFERENCE.get(value) as string;
23
+ assert(hasReferenceID(value), new Error('Missing reference id'));
24
+ return REFERENCE.get(value)!;
24
25
  }
25
26
 
26
27
  export function getReference<T>(id: string): T {
27
- assert(hasReference(id), 'Missing reference for id:' + id);
28
+ assert(hasReference(id), new Error('Missing reference for id:' + id));
28
29
  return INV_REFERENCE.get(id) as T;
29
30
  }
30
31