seroval 0.11.5 → 0.12.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 (122) hide show
  1. package/README.md +29 -16
  2. package/dist/cjs/development/index.cjs +3012 -4790
  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 +3010 -4790
  6. package/dist/esm/development/index.mjs.map +4 -4
  7. package/dist/esm/production/index.mjs +3 -3
  8. package/dist/types/core/Serializer.d.ts +2 -0
  9. package/dist/types/core/Serializer.d.ts.map +1 -0
  10. package/dist/types/core/UnsupportedTypeError.d.ts +1 -0
  11. package/dist/types/core/UnsupportedTypeError.d.ts.map +1 -0
  12. package/dist/types/core/assert.d.ts +1 -0
  13. package/dist/types/core/assert.d.ts.map +1 -0
  14. package/dist/types/core/base/async.d.ts +30 -0
  15. package/dist/types/core/base/async.d.ts.map +1 -0
  16. package/dist/types/core/base/stream.d.ts +40 -0
  17. package/dist/types/core/base/stream.d.ts.map +1 -0
  18. package/dist/types/core/base/sync.d.ts +32 -0
  19. package/dist/types/core/base/sync.d.ts.map +1 -0
  20. package/dist/types/core/base-primitives.d.ts +3 -1
  21. package/dist/types/core/base-primitives.d.ts.map +1 -0
  22. package/dist/types/core/compat.d.ts +1 -0
  23. package/dist/types/core/compat.d.ts.map +1 -0
  24. package/dist/types/core/constants.d.ts +19 -4
  25. package/dist/types/core/constants.d.ts.map +1 -0
  26. package/dist/types/core/constructors.d.ts +1 -0
  27. package/dist/types/core/constructors.d.ts.map +1 -0
  28. package/dist/types/core/cross/async.d.ts +8 -3
  29. package/dist/types/core/cross/async.d.ts.map +1 -0
  30. package/dist/types/core/cross/cross-parser.d.ts +8 -0
  31. package/dist/types/core/cross/cross-parser.d.ts.map +1 -0
  32. package/dist/types/core/cross/index.d.ts +12 -5
  33. package/dist/types/core/cross/index.d.ts.map +1 -0
  34. package/dist/types/core/cross/serialize.d.ts +23 -5
  35. package/dist/types/core/cross/serialize.d.ts.map +1 -0
  36. package/dist/types/core/cross/stream.d.ts +8 -3
  37. package/dist/types/core/cross/stream.d.ts.map +1 -0
  38. package/dist/types/core/cross/sync.d.ts +8 -3
  39. package/dist/types/core/cross/sync.d.ts.map +1 -0
  40. package/dist/types/core/get-identifier.d.ts +1 -0
  41. package/dist/types/core/get-identifier.d.ts.map +1 -0
  42. package/dist/types/core/keys.d.ts +1 -0
  43. package/dist/types/core/keys.d.ts.map +1 -0
  44. package/dist/types/core/literals.d.ts +1 -0
  45. package/dist/types/core/literals.d.ts.map +1 -0
  46. package/dist/types/core/parser-context.d.ts +23 -0
  47. package/dist/types/core/parser-context.d.ts.map +1 -0
  48. package/dist/types/core/plugin.d.ts +26 -0
  49. package/dist/types/core/plugin.d.ts.map +1 -0
  50. package/dist/types/core/promise-to-result.d.ts +1 -0
  51. package/dist/types/core/promise-to-result.d.ts.map +1 -0
  52. package/dist/types/core/reference.d.ts +1 -0
  53. package/dist/types/core/reference.d.ts.map +1 -0
  54. package/dist/types/core/serializer-context.old.d.ts +165 -0
  55. package/dist/types/core/serializer-context.old.d.ts.map +1 -0
  56. package/dist/types/core/shared.d.ts +4 -7
  57. package/dist/types/core/shared.d.ts.map +1 -0
  58. package/dist/types/core/string.d.ts +1 -0
  59. package/dist/types/core/string.d.ts.map +1 -0
  60. package/dist/types/core/tree/async.d.ts +8 -3
  61. package/dist/types/core/tree/async.d.ts.map +1 -0
  62. package/dist/types/core/tree/deserialize.d.ts +49 -2
  63. package/dist/types/core/tree/deserialize.d.ts.map +1 -0
  64. package/dist/types/core/tree/index.d.ts +10 -7
  65. package/dist/types/core/tree/index.d.ts.map +1 -0
  66. package/dist/types/core/tree/serialize.d.ts +37 -4
  67. package/dist/types/core/tree/serialize.d.ts.map +1 -0
  68. package/dist/types/core/tree/sync.d.ts +8 -3
  69. package/dist/types/core/tree/sync.d.ts.map +1 -0
  70. package/dist/types/core/types.d.ts +10 -3
  71. package/dist/types/core/types.d.ts.map +1 -0
  72. package/dist/types/core/web-api.d.ts +1 -0
  73. package/dist/types/core/web-api.d.ts.map +1 -0
  74. package/dist/types/index.d.ts +3 -0
  75. package/dist/types/index.d.ts.map +1 -0
  76. package/dist/types/types.d.ts +1 -0
  77. package/dist/types/types.d.ts.map +1 -0
  78. package/package.json +2 -2
  79. package/src/core/Serializer.ts +2 -0
  80. package/src/core/base/async.ts +804 -0
  81. package/src/core/base/stream.ts +496 -0
  82. package/src/core/base/sync.ts +675 -0
  83. package/src/core/base-primitives.ts +22 -0
  84. package/src/core/constants.ts +61 -45
  85. package/src/core/cross/async.ts +6 -743
  86. package/src/core/cross/cross-parser.ts +9 -0
  87. package/src/core/cross/index.ts +62 -84
  88. package/src/core/cross/serialize.ts +71 -862
  89. package/src/core/cross/stream.ts +6 -868
  90. package/src/core/cross/sync.ts +6 -623
  91. package/src/core/is-serializable.new.ts +208 -0
  92. package/src/core/keys.ts +1 -1
  93. package/src/core/parser-context.ts +131 -0
  94. package/src/core/plugin.ts +55 -0
  95. package/src/core/serializer-context.new.ts +1168 -0
  96. package/src/core/serializer-context.old.ts +1126 -0
  97. package/src/core/shared.ts +46 -124
  98. package/src/core/tree/async.ts +6 -742
  99. package/src/core/tree/deserialize.ts +423 -420
  100. package/src/core/tree/index.ts +49 -91
  101. package/src/core/tree/parser.ts +45 -0
  102. package/src/core/tree/serialize.ts +122 -828
  103. package/src/core/tree/sync.ts +6 -623
  104. package/src/core/types.ts +13 -2
  105. package/src/example.ts +28 -0
  106. package/src/index.ts +3 -0
  107. package/dist/types/core/assignments.d.ts +0 -33
  108. package/dist/types/core/context.d.ts +0 -9
  109. package/dist/types/core/cross/context.d.ts +0 -37
  110. package/dist/types/core/cross/primitives.d.ts +0 -9
  111. package/dist/types/core/cross/web-api.d.ts +0 -4
  112. package/dist/types/core/tree/context.d.ts +0 -44
  113. package/dist/types/core/tree/primitives.d.ts +0 -9
  114. package/dist/types/core/tree/web-api.d.ts +0 -4
  115. package/src/core/assignments.ts +0 -159
  116. package/src/core/context.ts +0 -15
  117. package/src/core/cross/context.ts +0 -102
  118. package/src/core/cross/primitives.ts +0 -128
  119. package/src/core/cross/web-api.ts +0 -50
  120. package/src/core/tree/context.ts +0 -125
  121. package/src/core/tree/primitives.ts +0 -123
  122. package/src/core/tree/web-api.ts +0 -50
@@ -1,626 +1,9 @@
1
- /* eslint-disable @typescript-eslint/no-use-before-define */
2
- import { BIGINT_FLAG, Feature } from '../compat';
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
- import {
9
- TRUE_NODE,
10
- FALSE_NODE,
11
- UNDEFINED_NODE,
12
- NULL_NODE,
13
- } from '../literals';
14
- import {
15
- createBigIntTypedArrayNode,
16
- createTypedArrayNode,
17
- createDataViewNode,
18
- createSymbolNode,
19
- createFunctionNode,
20
- } from './primitives';
21
- import {
22
- hasReferenceID,
23
- } from '../reference';
24
- import {
25
- getErrorConstructorName,
26
- getErrorOptions,
27
- getObjectFlag,
28
- isIterable,
29
- } from '../shared';
30
- import type {
31
- SerovalAggregateErrorNode,
32
- SerovalArrayNode,
33
- SerovalBoxedNode,
34
- SerovalCustomEventNode,
35
- SerovalErrorNode,
36
- SerovalEventNode,
37
- SerovalFormDataNode,
38
- SerovalHeadersNode,
39
- SerovalMapNode,
40
- SerovalNullConstructorNode,
41
- SerovalObjectNode,
42
- SerovalObjectRecordKey,
43
- SerovalObjectRecordNode,
44
- SerovalPlainRecordNode,
45
- SerovalSetNode,
46
- SerovalSyncNode,
47
- } from '../types';
48
- import {
49
- SerovalObjectRecordSpecialKey,
50
- } from '../types';
51
- import { SerovalNodeType } from '../constants';
52
- import {
53
- createArrayBufferNode,
54
- createBigIntNode,
55
- createDateNode,
56
- createIndexedValueNode,
57
- createNumberNode,
58
- createReferenceNode,
59
- createRegExpNode,
60
- createStringNode,
61
- } from '../base-primitives';
62
- import { createDOMExceptionNode, createURLNode, createURLSearchParamsNode } from '../web-api';
63
- import { createCustomEventOptions, createEventOptions } from '../constructors';
1
+ import BaseSyncParserContext from '../base/sync';
2
+ import type { BaseParserContextOptions } from '../parser-context';
3
+ import type { SerovalMode } from '../plugin';
64
4
 
65
- type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode;
5
+ export type SyncParserContextOptions = Omit<BaseParserContextOptions, 'refs'>;
66
6
 
67
- function generateNodeList(ctx: ParserContext, current: unknown[]): SerovalSyncNode[] {
68
- const size = current.length;
69
- const nodes = new Array<SerovalSyncNode>(size);
70
- const deferred = new Array<unknown>(size);
71
- let item: unknown;
72
- for (let i = 0; i < size; i++) {
73
- if (i in current) {
74
- item = current[i];
75
- if (isIterable(ctx, item)) {
76
- deferred[i] = item;
77
- } else {
78
- nodes[i] = parseSync(ctx, item);
79
- }
80
- }
81
- }
82
- for (let i = 0; i < size; i++) {
83
- if (i in deferred) {
84
- nodes[i] = parseSync(ctx, deferred[i]);
85
- }
86
- }
87
- return nodes;
88
- }
89
-
90
- function generateArrayNode(
91
- ctx: ParserContext,
92
- id: number,
93
- current: unknown[],
94
- ): SerovalArrayNode {
95
- return {
96
- t: SerovalNodeType.Array,
97
- i: id,
98
- s: undefined,
99
- l: current.length,
100
- c: undefined,
101
- m: undefined,
102
- p: undefined,
103
- e: undefined,
104
- a: generateNodeList(ctx, current),
105
- f: undefined,
106
- b: undefined,
107
- o: getObjectFlag(current),
108
- };
109
- }
110
-
111
- function generateMapNode(
112
- ctx: ParserContext,
113
- id: number,
114
- current: Map<unknown, unknown>,
115
- ): SerovalMapNode {
116
- const len = current.size;
117
- const keyNodes = new Array<SerovalSyncNode>(len);
118
- const valueNodes = new Array<SerovalSyncNode>(len);
119
- const deferredKey = new Array<unknown>(len);
120
- const deferredValue = new Array<unknown>(len);
121
- let deferredSize = 0;
122
- let nodeSize = 0;
123
- for (const [key, value] of current.entries()) {
124
- // Either key or value might be an iterable
125
- if (isIterable(ctx, key) || isIterable(ctx, value)) {
126
- deferredKey[deferredSize] = key;
127
- deferredValue[deferredSize] = value;
128
- deferredSize++;
129
- } else {
130
- keyNodes[nodeSize] = parseSync(ctx, key);
131
- valueNodes[nodeSize] = parseSync(ctx, value);
132
- nodeSize++;
133
- }
134
- }
135
- for (let i = 0; i < deferredSize; i++) {
136
- keyNodes[nodeSize + i] = parseSync(ctx, deferredKey[i]);
137
- valueNodes[nodeSize + i] = parseSync(ctx, deferredValue[i]);
138
- }
139
- return {
140
- t: SerovalNodeType.Map,
141
- i: id,
142
- s: undefined,
143
- l: undefined,
144
- c: undefined,
145
- m: undefined,
146
- p: undefined,
147
- e: { k: keyNodes, v: valueNodes, s: len },
148
- a: undefined,
149
- f: undefined,
150
- b: undefined,
151
- o: undefined,
152
- };
153
- }
154
-
155
- function generateSetNode(
156
- ctx: ParserContext,
157
- id: number,
158
- current: Set<unknown>,
159
- ): SerovalSetNode {
160
- const len = current.size;
161
- const nodes = new Array<SerovalSyncNode>(len);
162
- const deferred = new Array<unknown>(len);
163
- let deferredSize = 0;
164
- let nodeSize = 0;
165
- for (const item of current.keys()) {
166
- // Iterables are lazy, so the evaluation must be deferred
167
- if (isIterable(ctx, item)) {
168
- deferred[deferredSize++] = item;
169
- } else {
170
- nodes[nodeSize++] = parseSync(ctx, item);
171
- }
172
- }
173
- // Parse deferred items
174
- for (let i = 0; i < deferredSize; i++) {
175
- nodes[nodeSize + i] = parseSync(ctx, deferred[i]);
176
- }
177
- return {
178
- t: SerovalNodeType.Set,
179
- i: id,
180
- s: undefined,
181
- l: len,
182
- c: undefined,
183
- m: undefined,
184
- p: undefined,
185
- e: undefined,
186
- a: nodes,
187
- f: undefined,
188
- b: undefined,
189
- o: undefined,
190
- };
191
- }
192
-
193
- function generateProperties(
194
- ctx: ParserContext,
195
- properties: Record<string, unknown>,
196
- ): SerovalObjectRecordNode {
197
- const keys = Object.keys(properties);
198
- let size = keys.length;
199
- const keyNodes = new Array<SerovalObjectRecordKey>(size);
200
- const valueNodes = new Array<SerovalSyncNode>(size);
201
- const deferredKeys = new Array<SerovalObjectRecordKey>(size);
202
- const deferredValues = new Array<unknown>(size);
203
- let deferredSize = 0;
204
- let nodesSize = 0;
205
- let item: unknown;
206
- let escaped: SerovalObjectRecordKey;
207
- for (const key of keys) {
208
- item = properties[key];
209
- escaped = serializeString(key);
210
- if (isIterable(ctx, item)) {
211
- deferredKeys[deferredSize] = escaped;
212
- deferredValues[deferredSize] = item;
213
- deferredSize++;
214
- } else {
215
- keyNodes[nodesSize] = escaped;
216
- valueNodes[nodesSize] = parseSync(ctx, item);
217
- nodesSize++;
218
- }
219
- }
220
- for (let i = 0; i < deferredSize; i++) {
221
- keyNodes[nodesSize + i] = deferredKeys[i];
222
- valueNodes[nodesSize + i] = parseSync(ctx, deferredValues[i]);
223
- }
224
- if (ctx.features & Feature.Symbol) {
225
- if (Symbol.iterator in properties) {
226
- keyNodes[size] = SerovalObjectRecordSpecialKey.SymbolIterator;
227
- const items = Array.from(properties as Iterable<unknown>);
228
- const id = createIndexedValue(ctx, items);
229
- valueNodes[size] = generateArrayNode(ctx, id, items);
230
- size++;
231
- }
232
- }
233
- return {
234
- k: keyNodes,
235
- v: valueNodes,
236
- s: size,
237
- };
238
- }
239
-
240
- function generatePlainProperties(
241
- ctx: ParserContext,
242
- properties: Record<string, unknown>,
243
- ): SerovalPlainRecordNode {
244
- const keys = Object.keys(properties);
245
- const size = keys.length;
246
- const keyNodes = new Array<string>(size);
247
- const valueNodes = new Array<SerovalSyncNode>(size);
248
- const deferredKeys = new Array<string>(size);
249
- const deferredValues = new Array<unknown>(size);
250
- let deferredSize = 0;
251
- let nodesSize = 0;
252
- let item: unknown;
253
- let escaped: string;
254
- for (const key of keys) {
255
- item = properties[key];
256
- escaped = serializeString(key);
257
- if (isIterable(ctx, item)) {
258
- deferredKeys[deferredSize] = escaped;
259
- deferredValues[deferredSize] = item;
260
- deferredSize++;
261
- } else {
262
- keyNodes[nodesSize] = escaped;
263
- valueNodes[nodesSize] = parseSync(ctx, item);
264
- nodesSize++;
265
- }
266
- }
267
- for (let i = 0; i < deferredSize; i++) {
268
- keyNodes[nodesSize + i] = deferredKeys[i];
269
- valueNodes[nodesSize + i] = parseSync(ctx, deferredValues[i]);
270
- }
271
- return {
272
- k: keyNodes,
273
- v: valueNodes,
274
- s: size,
275
- };
276
- }
277
-
278
- function generateObjectNode(
279
- ctx: ParserContext,
280
- id: number,
281
- current: Record<string, unknown>,
282
- empty: boolean,
283
- ): ObjectLikeNode {
284
- return {
285
- t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
286
- i: id,
287
- s: undefined,
288
- l: undefined,
289
- c: undefined,
290
- m: undefined,
291
- p: generateProperties(ctx, current),
292
- e: undefined,
293
- a: undefined,
294
- f: undefined,
295
- b: undefined,
296
- o: getObjectFlag(current),
297
- };
298
- }
299
-
300
- function generateAggregateErrorNode(
301
- ctx: ParserContext,
302
- id: number,
303
- current: AggregateError,
304
- ): SerovalAggregateErrorNode {
305
- const options = getErrorOptions(ctx, current);
306
- const optionsNode = options
307
- ? generateProperties(ctx, options)
308
- : undefined;
309
- return {
310
- t: SerovalNodeType.AggregateError,
311
- i: id,
312
- s: undefined,
313
- l: undefined,
314
- c: undefined,
315
- m: serializeString(current.message),
316
- p: optionsNode,
317
- e: undefined,
318
- a: undefined,
319
- f: undefined,
320
- b: undefined,
321
- o: undefined,
322
- };
323
- }
324
-
325
- function generateErrorNode(
326
- ctx: ParserContext,
327
- id: number,
328
- current: Error,
329
- ): SerovalErrorNode {
330
- const options = getErrorOptions(ctx, current);
331
- const optionsNode = options
332
- ? generateProperties(ctx, options)
333
- : undefined;
334
- return {
335
- t: SerovalNodeType.Error,
336
- i: id,
337
- s: undefined,
338
- l: undefined,
339
- c: getErrorConstructorName(current),
340
- m: serializeString(current.message),
341
- p: optionsNode,
342
- e: undefined,
343
- a: undefined,
344
- f: undefined,
345
- b: undefined,
346
- o: undefined,
347
- };
348
- }
349
-
350
- function generateHeadersNode(
351
- ctx: ParserContext,
352
- id: number,
353
- current: Headers,
354
- ): SerovalHeadersNode {
355
- const items: Record<string, string> = {};
356
- // TS Headers not an Iterable
357
- current.forEach((value, key) => {
358
- items[key] = value;
359
- });
360
- return {
361
- t: SerovalNodeType.Headers,
362
- i: id,
363
- s: undefined,
364
- l: undefined,
365
- c: undefined,
366
- m: undefined,
367
- p: undefined,
368
- e: generatePlainProperties(ctx, items),
369
- a: undefined,
370
- f: undefined,
371
- b: undefined,
372
- o: undefined,
373
- };
374
- }
375
-
376
- function generateFormDataNode(
377
- ctx: ParserContext,
378
- id: number,
379
- current: FormData,
380
- ): SerovalFormDataNode {
381
- const items: Record<string, FormDataEntryValue> = {};
382
- // TS FormData isn't an Iterable sadly
383
- current.forEach((value, key) => {
384
- items[key] = value;
385
- });
386
- return {
387
- t: SerovalNodeType.FormData,
388
- i: id,
389
- s: undefined,
390
- l: undefined,
391
- c: undefined,
392
- m: undefined,
393
- p: undefined,
394
- e: generatePlainProperties(ctx, items),
395
- a: undefined,
396
- f: undefined,
397
- b: undefined,
398
- o: undefined,
399
- };
400
- }
401
-
402
- function generateBoxedNode(
403
- ctx: ParserContext,
404
- id: number,
405
- current: object,
406
- ): SerovalBoxedNode {
407
- return {
408
- t: SerovalNodeType.Boxed,
409
- i: id,
410
- s: undefined,
411
- l: undefined,
412
- c: undefined,
413
- m: undefined,
414
- p: undefined,
415
- e: undefined,
416
- a: undefined,
417
- f: parseSync(ctx, current.valueOf()),
418
- b: undefined,
419
- o: undefined,
420
- };
421
- }
422
-
423
- function generateEventNode(ctx: ParserContext, id: number, current: Event): SerovalEventNode {
424
- return {
425
- t: SerovalNodeType.Event,
426
- i: id,
427
- s: serializeString(current.type),
428
- l: undefined,
429
- c: undefined,
430
- m: undefined,
431
- p: undefined,
432
- e: undefined,
433
- a: undefined,
434
- f: parseObject(ctx, createEventOptions(current)),
435
- b: undefined,
436
- o: undefined,
437
- };
438
- }
439
-
440
- function generateCustomEventNode(
441
- ctx: ParserContext,
442
- id: number,
443
- current: CustomEvent,
444
- ): SerovalCustomEventNode {
445
- return {
446
- t: SerovalNodeType.CustomEvent,
447
- i: id,
448
- s: serializeString(current.type),
449
- l: undefined,
450
- c: undefined,
451
- m: undefined,
452
- p: undefined,
453
- e: undefined,
454
- a: undefined,
455
- f: parseObject(ctx, createCustomEventOptions(current)),
456
- b: undefined,
457
- o: undefined,
458
- };
459
- }
460
-
461
- function parseObject(
462
- ctx: ParserContext,
463
- current: object | null,
464
- ): SerovalSyncNode {
465
- if (!current) {
466
- return NULL_NODE;
467
- }
468
- // Non-primitive values needs a reference ID
469
- // mostly because the values themselves are stateful
470
- const id = createIndexedValue(ctx, current);
471
- if (ctx.reference.marked.has(id)) {
472
- return createIndexedValueNode(id);
473
- }
474
- if (hasReferenceID(current)) {
475
- return createReferenceNode(id, current);
476
- }
477
- // Well well well
478
- if (Array.isArray(current)) {
479
- return generateArrayNode(ctx, id, current);
480
- }
481
- const currentClass = current.constructor;
482
- // Fast path
483
- switch (currentClass) {
484
- case Number:
485
- case Boolean:
486
- case String:
487
- case BigInt:
488
- return generateBoxedNode(ctx, id, current);
489
- case Date:
490
- return createDateNode(id, current as unknown as Date);
491
- case RegExp:
492
- return createRegExpNode(id, current as unknown as RegExp);
493
- case Object:
494
- return generateObjectNode(
495
- ctx,
496
- id,
497
- current as unknown as Record<string, unknown>,
498
- false,
499
- );
500
- case undefined:
501
- return generateObjectNode(
502
- ctx,
503
- id,
504
- current as unknown as Record<string, unknown>,
505
- true,
506
- );
507
- case Error:
508
- case EvalError:
509
- case RangeError:
510
- case ReferenceError:
511
- case SyntaxError:
512
- case TypeError:
513
- case URIError:
514
- return generateErrorNode(ctx, id, current as unknown as Error);
515
- default:
516
- break;
517
- }
518
- // Typed Arrays
519
- if (ctx.features & Feature.TypedArray) {
520
- switch (currentClass) {
521
- case ArrayBuffer:
522
- return createArrayBufferNode(id, current as unknown as ArrayBuffer);
523
- case Int8Array:
524
- case Int16Array:
525
- case Int32Array:
526
- case Uint8Array:
527
- case Uint16Array:
528
- case Uint32Array:
529
- case Uint8ClampedArray:
530
- case Float32Array:
531
- case Float64Array:
532
- return createTypedArrayNode(ctx, id, current as unknown as TypedArrayValue);
533
- case DataView:
534
- return createDataViewNode(ctx, id, current as unknown as DataView);
535
- default:
536
- break;
537
- }
538
- }
539
- // BigInt Typed Arrays
540
- if ((ctx.features & BIGINT_FLAG) === BIGINT_FLAG) {
541
- switch (currentClass) {
542
- case BigInt64Array:
543
- case BigUint64Array:
544
- return createBigIntTypedArrayNode(ctx, id, current as unknown as BigIntTypedArrayValue);
545
- default:
546
- break;
547
- }
548
- }
549
- // ES Collection
550
- if (ctx.features & Feature.Map && currentClass === Map) {
551
- return generateMapNode(ctx, id, current as unknown as Map<unknown, unknown>);
552
- }
553
- if (ctx.features & Feature.Set && currentClass === Set) {
554
- return generateSetNode(ctx, id, current as unknown as Set<unknown>);
555
- }
556
- // Web APIs
557
- if (ctx.features & Feature.WebAPI) {
558
- switch (currentClass) {
559
- case URL:
560
- return createURLNode(id, current as unknown as URL);
561
- case URLSearchParams:
562
- return createURLSearchParamsNode(id, current as unknown as URLSearchParams);
563
- case Headers:
564
- return generateHeadersNode(ctx, id, current as unknown as Headers);
565
- case FormData:
566
- return generateFormDataNode(ctx, id, current as unknown as FormData);
567
- case Event:
568
- return generateEventNode(ctx, id, current as unknown as Event);
569
- case CustomEvent:
570
- return generateCustomEventNode(ctx, id, current as unknown as CustomEvent);
571
- case DOMException:
572
- return createDOMExceptionNode(id, current as unknown as DOMException);
573
- default:
574
- break;
575
- }
576
- }
577
- if (
578
- (ctx.features & Feature.AggregateError)
579
- && (
580
- currentClass === AggregateError
581
- || current instanceof AggregateError
582
- )
583
- ) {
584
- return generateAggregateErrorNode(ctx, id, current as unknown as AggregateError);
585
- }
586
- // Slow path. We only need to handle Errors and Iterators
587
- // since they have very broad implementations.
588
- if (current instanceof Error) {
589
- return generateErrorNode(ctx, id, current);
590
- }
591
- // Generator functions don't have a global constructor
592
- // despite existing
593
- if ((ctx.features & Feature.Symbol) && Symbol.iterator in current) {
594
- return generateObjectNode(ctx, id, current, !!currentClass);
595
- }
596
- throw new UnsupportedTypeError(current);
597
- }
598
-
599
- export default function parseSync<T>(
600
- ctx: ParserContext,
601
- current: T,
602
- ): SerovalSyncNode {
603
- const t = typeof current;
604
- if (ctx.features & Feature.BigInt && t === 'bigint') {
605
- return createBigIntNode(current as bigint);
606
- }
607
- switch (t) {
608
- case 'boolean':
609
- return current ? TRUE_NODE : FALSE_NODE;
610
- case 'undefined':
611
- return UNDEFINED_NODE;
612
- case 'string':
613
- return createStringNode(current as string);
614
- case 'number':
615
- return createNumberNode(current as number);
616
- case 'object':
617
- return parseObject(ctx, current as object);
618
- case 'symbol':
619
- return createSymbolNode(ctx, current as symbol);
620
- case 'function':
621
- // eslint-disable-next-line @typescript-eslint/ban-types
622
- return createFunctionNode(ctx, current as Function);
623
- default:
624
- throw new UnsupportedTypeError(current);
625
- }
7
+ export default class SyncParserContext extends BaseSyncParserContext {
8
+ readonly mode: SerovalMode = 'vanilla';
626
9
  }
package/src/core/types.ts CHANGED
@@ -3,6 +3,7 @@ import type {
3
3
  SerovalObjectFlags,
4
4
  SerovalConstant,
5
5
  Symbols,
6
+ ErrorConstructorTag,
6
7
  } from './constants';
7
8
 
8
9
  export interface SerovalBaseNode {
@@ -204,7 +205,7 @@ export interface SerovalPromiseNode extends SerovalBaseNode {
204
205
  export interface SerovalErrorNode extends SerovalBaseNode {
205
206
  t: SerovalNodeType.Error;
206
207
  // constructor name
207
- c: string;
208
+ s: ErrorConstructorTag;
208
209
  // message
209
210
  m: string;
210
211
  // other properties
@@ -382,6 +383,15 @@ export interface SerovalDOMExceptionNode extends SerovalBaseNode {
382
383
  c: string;
383
384
  }
384
385
 
386
+ export interface SerovalPluginNode extends SerovalBaseNode {
387
+ t: SerovalNodeType.Plugin;
388
+ i: number;
389
+ // value
390
+ s: unknown;
391
+ // tag name
392
+ c: string;
393
+ }
394
+
385
395
  export type SerovalSyncNode =
386
396
  | SerovalPrimitiveNode
387
397
  | SerovalIndexedValueNode
@@ -407,7 +417,8 @@ export type SerovalSyncNode =
407
417
  | SerovalBoxedNode
408
418
  | SerovalEventNode
409
419
  | SerovalCustomEventNode
410
- | SerovalDOMExceptionNode;
420
+ | SerovalDOMExceptionNode
421
+ | SerovalPluginNode;
411
422
 
412
423
  export type SerovalAsyncNode =
413
424
  | SerovalPromiseNode
package/src/example.ts ADDED
@@ -0,0 +1,28 @@
1
+ import { createPlugin, type SerovalNode } from '..';
2
+
3
+ const BufferPlugin = createPlugin<Buffer, SerovalNode>({
4
+ tag: 'Buffer',
5
+ test(value) {
6
+ return value instanceof Buffer;
7
+ },
8
+ parse: {
9
+ sync(value, ctx) {
10
+ return ctx.parse(value.toString('base64'));
11
+ },
12
+ async async(value, ctx) {
13
+ return ctx.parse(value.toString('base64'));
14
+ },
15
+ stream(value, ctx) {
16
+ return ctx.parse(value.toString('base64'));
17
+ },
18
+ },
19
+ serialize(node, ctx) {
20
+ return `Buffer.from(${ctx.serialize(node)}, "base64")`;
21
+ },
22
+ deserialize(node, ctx) {
23
+ return Buffer.from(ctx.deserialize(node) as string, 'base64');
24
+ },
25
+ isIterable() {
26
+ return true;
27
+ },
28
+ });
package/src/index.ts CHANGED
@@ -17,5 +17,8 @@ export * from './core/cross';
17
17
  export { GLOBAL_CONTEXT_API_SCRIPT, getCrossReferenceHeader } from './core/keys';
18
18
 
19
19
  export { default as Serializer } from './core/Serializer';
20
+ export * from './core/plugin';
21
+
22
+ export type { SerovalNode } from './core/types';
20
23
 
21
24
  export default serialize;