seroval 0.11.6 → 0.12.1

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 +3088 -4876
  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 +3085 -4875
  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 +6 -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 +20 -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 -751
  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 -873
  90. package/src/core/cross/sync.ts +6 -624
  91. package/src/core/is-serializable.new.ts +208 -0
  92. package/src/core/keys.ts +5 -3
  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 -123
  98. package/src/core/tree/async.ts +6 -750
  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 -624
  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,37 +1,4 @@
1
- /* eslint-disable @typescript-eslint/no-use-before-define */
2
- import { Feature } from '../compat';
3
- import type {
4
- CrossSerializerContext,
5
- } from './context';
6
- import { isValidIdentifier } from '../shared';
7
1
  import type {
8
- SerovalAggregateErrorNode,
9
- SerovalArrayNode,
10
- SerovalBigIntTypedArrayNode,
11
- SerovalErrorNode,
12
- SerovalMapNode,
13
- SerovalNode,
14
- SerovalNullConstructorNode,
15
- SerovalObjectNode,
16
- SerovalPromiseNode,
17
- SerovalIndexedValueNode,
18
- SerovalSetNode,
19
- SerovalTypedArrayNode,
20
- SerovalArrayBufferNode,
21
- SerovalDataViewNode,
22
- SerovalBlobNode,
23
- SerovalFileNode,
24
- SerovalHeadersNode,
25
- SerovalRegExpNode,
26
- SerovalDateNode,
27
- SerovalURLNode,
28
- SerovalURLSearchParamsNode,
29
- SerovalReferenceNode,
30
- SerovalFormDataNode,
31
- SerovalObjectRecordNode,
32
- SerovalObjectRecordKey,
33
- SerovalBoxedNode,
34
- SerovalWKSymbolNode,
35
2
  SerovalPromiseConstructorNode,
36
3
  SerovalPromiseResolveNode,
37
4
  SerovalPromiseRejectNode,
@@ -39,870 +6,112 @@ import type {
39
6
  SerovalReadableStreamEnqueueNode,
40
7
  SerovalReadableStreamErrorNode,
41
8
  SerovalReadableStreamConstructorNode,
42
- SerovalRequestNode,
43
- SerovalResponseNode,
44
- SerovalEventNode,
45
- SerovalCustomEventNode,
46
- SerovalDOMExceptionNode,
47
- } from '../types';
48
- import {
49
- SerovalObjectRecordSpecialKey,
9
+ SerovalNode,
50
10
  } from '../types';
51
- import {
52
- SerovalObjectFlags,
53
- SerovalNodeType,
54
- SYMBOL_STRING,
55
- serializeConstant,
56
- } from '../constants';
57
- import type { Assignment } from '../assignments';
58
- import { resolveAssignments, resolveFlags } from '../assignments';
59
11
  import {
60
12
  GLOBAL_CONTEXT_PROMISE_REJECT,
61
13
  GLOBAL_CONTEXT_PROMISE_RESOLVE,
62
14
  GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR,
63
15
  GLOBAL_CONTEXT_REFERENCES,
64
- REFERENCES_KEY,
65
16
  GLOBAL_CONTEXT_STREAM_CONSTRUCTOR,
66
17
  GLOBAL_CONTEXT_STREAM_EMIT,
67
18
  GLOBAL_CONTEXT_API,
68
19
  } from '../keys';
20
+ import type { BaseSerializerContextOptions } from '../serializer-context.old';
21
+ import BaseSerializerContext from '../serializer-context.old';
22
+ import type { SerovalMode } from '../plugin';
23
+ import { Feature } from '../compat';
24
+ import { serializeString } from '../string';
25
+ import type { CrossContextOptions } from './cross-parser';
69
26
 
70
- export function getRefExpr(id: number): string {
71
- return GLOBAL_CONTEXT_REFERENCES + '[' + id + ']';
72
- }
73
-
74
- function pushObjectFlag(
75
- ctx: CrossSerializerContext,
76
- flag: SerovalObjectFlags,
77
- id: number,
78
- ): void {
79
- if (flag !== SerovalObjectFlags.None) {
80
- ctx.flags.push({
81
- type: flag,
82
- value: getRefExpr(id),
83
- });
84
- }
85
- }
86
-
87
- export function resolvePatches(ctx: CrossSerializerContext): string | undefined {
88
- const assignments = resolveAssignments(ctx.assignments);
89
- const flags = resolveFlags(ctx.flags);
90
- if (assignments) {
91
- if (flags) {
92
- return assignments + flags;
93
- }
94
- return assignments;
95
- }
96
- return flags;
97
- }
98
-
99
- /**
100
- * Generates the inlined assignment for the reference
101
- * This is different from the assignments array as this one
102
- * signifies creation rather than mutation
103
- */
104
-
105
- function createAssignment(
106
- ctx: CrossSerializerContext,
107
- source: string,
108
- value: string,
109
- ): void {
110
- ctx.assignments.push({
111
- t: 'index',
112
- s: source,
113
- k: undefined,
114
- v: value,
115
- });
116
- }
117
-
118
- function createAddAssignment(
119
- ctx: CrossSerializerContext,
120
- ref: number,
121
- value: string,
122
- ): void {
123
- ctx.assignments.push({
124
- t: 'add',
125
- s: getRefExpr(ref),
126
- k: undefined,
127
- v: value,
128
- });
129
- }
130
-
131
- function createSetAssignment(
132
- ctx: CrossSerializerContext,
133
- ref: number,
134
- key: string,
135
- value: string,
136
- ): void {
137
- ctx.assignments.push({
138
- t: 'set',
139
- s: getRefExpr(ref),
140
- k: key,
141
- v: value,
142
- });
143
- }
144
-
145
- function createAppendAssignment(
146
- ctx: CrossSerializerContext,
147
- ref: number,
148
- key: string,
149
- value: string,
150
- ): void {
151
- ctx.assignments.push({
152
- t: 'append',
153
- s: getRefExpr(ref),
154
- k: key,
155
- v: value,
156
- });
157
- }
158
-
159
- function createArrayAssign(
160
- ctx: CrossSerializerContext,
161
- ref: number,
162
- index: number | string,
163
- value: string,
164
- ): void {
165
- createAssignment(ctx, getRefExpr(ref) + '[' + index + ']', value);
166
- }
167
-
168
- function createObjectAssign(
169
- ctx: CrossSerializerContext,
170
- ref: number,
171
- key: string,
172
- value: string,
173
- ): void {
174
- createAssignment(ctx, getRefExpr(ref) + '.' + key, value);
175
- }
176
-
177
- function assignIndexedValue(
178
- index: number,
179
- value: string,
180
- ): string {
181
- return getRefExpr(index) + '=' + value;
182
- }
183
-
184
- function isIndexedValueInStack(
185
- ctx: CrossSerializerContext,
186
- node: SerovalNode,
187
- ): node is SerovalIndexedValueNode {
188
- return node.t === SerovalNodeType.IndexedValue && ctx.stack.includes(node.i);
27
+ export interface CrossSerializerContextOptions
28
+ extends BaseSerializerContextOptions, CrossContextOptions {
189
29
  }
190
30
 
191
- function serializeArray(
192
- ctx: CrossSerializerContext,
193
- node: SerovalArrayNode,
194
- ): string {
195
- const id = node.i;
196
- ctx.stack.push(id);
197
- // This is different than Map and Set
198
- // because we also need to serialize
199
- // the holes of the Array
200
- let values = '';
201
- let item: SerovalNode | undefined;
202
- let isHoley = false;
203
- const list = node.a;
204
- for (let i = 0, len = node.l; i < len; i++) {
205
- if (i !== 0) {
206
- // Add an empty item
207
- values += ',';
208
- }
209
- item = list[i];
210
- // Check if index is a hole
211
- if (item) {
212
- // Check if item is a parent
213
- if (isIndexedValueInStack(ctx, item)) {
214
- createArrayAssign(ctx, id, i, getRefExpr(item.i));
215
- isHoley = true;
216
- } else {
217
- values += crossSerializeTree(ctx, item);
218
- isHoley = false;
219
- }
220
- } else {
221
- isHoley = true;
222
- }
223
- }
224
- ctx.stack.pop();
225
- pushObjectFlag(ctx, node.o, node.i);
226
- return assignIndexedValue(id, '[' + values + (isHoley ? ',]' : ']'));
227
- }
31
+ export default class CrossSerializerContext extends BaseSerializerContext {
32
+ readonly mode: SerovalMode = 'cross';
228
33
 
229
- function getIterableAccess(ctx: CrossSerializerContext): string {
230
- return ctx.features & Feature.ArrayPrototypeValues
231
- ? '.values()'
232
- : '[Symbol.iterator]()';
233
- }
34
+ scopeId?: string;
234
35
 
235
- function serializeIterable(
236
- ctx: CrossSerializerContext,
237
- node: SerovalNode,
238
- ): string {
239
- const parent = ctx.stack;
240
- ctx.stack = [];
241
- let serialized = crossSerializeTree(ctx, node) + getIterableAccess(ctx);
242
- ctx.stack = parent;
243
- if (ctx.features & Feature.ArrowFunction) {
244
- serialized = '[Symbol.iterator]:()=>' + serialized;
245
- } else if (ctx.features & Feature.MethodShorthand) {
246
- serialized = '[Symbol.iterator](){return ' + serialized + '}';
247
- } else {
248
- serialized = '[Symbol.iterator]:function(){return ' + serialized + '}';
36
+ constructor(options: CrossSerializerContextOptions) {
37
+ super(options);
38
+ this.scopeId = options.scopeId;
249
39
  }
250
- return serialized;
251
- }
252
40
 
253
- function serializeProperties(
254
- ctx: CrossSerializerContext,
255
- sourceID: number,
256
- node: SerovalObjectRecordNode,
257
- ): string {
258
- const len = node.s;
259
- if (len === 0) {
260
- return '{}';
261
- }
262
- let result = '';
263
- ctx.stack.push(sourceID);
264
- let key: SerovalObjectRecordKey;
265
- let val: SerovalNode;
266
- let check: number;
267
- let isIdentifier: boolean;
268
- let refParam: string;
269
- let hasPrev = false;
270
- const keys = node.k;
271
- const values = node.v;
272
- for (let i = 0; i < len; i++) {
273
- key = keys[i];
274
- val = values[i];
275
- switch (key) {
276
- case SerovalObjectRecordSpecialKey.SymbolIterator:
277
- result += (hasPrev ? ',' : '') + serializeIterable(ctx, val);
278
- hasPrev = true;
279
- break;
280
- default:
281
- check = Number(key);
282
- // Test if key is a valid number or JS identifier
283
- // so that we don't have to serialize the key and wrap with brackets
284
- isIdentifier = check >= 0 || isValidIdentifier(key);
285
- if (isIndexedValueInStack(ctx, val)) {
286
- refParam = getRefExpr(val.i);
287
- if (isIdentifier && Number.isNaN(check)) {
288
- createObjectAssign(ctx, sourceID, key, refParam);
289
- } else {
290
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), refParam);
291
- }
292
- } else {
293
- result += (hasPrev ? ',' : '')
294
- + (isIdentifier ? key : ('"' + key + '"'))
295
- + ':' + crossSerializeTree(ctx, val);
296
- hasPrev = true;
297
- }
298
- break;
41
+ getRefParam(id: number | string): string {
42
+ if (typeof id === 'string') {
43
+ return GLOBAL_CONTEXT_REFERENCES + '.' + id;
299
44
  }
45
+ return GLOBAL_CONTEXT_REFERENCES + '[' + id + ']';
300
46
  }
301
- ctx.stack.pop();
302
- return '{' + result + '}';
303
- }
304
47
 
305
- function serializeWithObjectAssign(
306
- ctx: CrossSerializerContext,
307
- value: SerovalObjectRecordNode,
308
- id: number,
309
- serialized: string,
310
- ): string {
311
- const fields = serializeProperties(ctx, id, value);
312
- if (fields !== '{}') {
313
- return 'Object.assign(' + serialized + ',' + fields + ')';
48
+ protected assignIndexedValue(
49
+ index: number,
50
+ value: string,
51
+ ): string {
52
+ return this.getRefParam(index) + '=' + value;
314
53
  }
315
- return serialized;
316
- }
317
-
318
- function serializeAssignments(
319
- ctx: CrossSerializerContext,
320
- sourceID: number,
321
- node: SerovalObjectRecordNode,
322
- ): string | undefined {
323
- ctx.stack.push(sourceID);
324
- const mainAssignments: Assignment[] = [];
325
- let key: SerovalObjectRecordKey;
326
- let value: SerovalNode;
327
- let parentAssignment: Assignment[];
328
- const keys = node.k;
329
- const values = node.v;
330
- for (let i = 0, len = node.s; i < len; i++) {
331
- key = keys[i];
332
- value = values[i];
333
- switch (key) {
334
- case SerovalObjectRecordSpecialKey.SymbolIterator: {
335
- const parent = ctx.stack;
336
- ctx.stack = [];
337
- const serialized = crossSerializeTree(ctx, value) + getIterableAccess(ctx);
338
- ctx.stack = parent;
339
- parentAssignment = ctx.assignments;
340
- ctx.assignments = mainAssignments;
341
- createArrayAssign(
342
- ctx,
343
- sourceID,
344
- 'Symbol.iterator',
345
- ctx.features & Feature.ArrowFunction
346
- ? '()=>' + serialized
347
- : 'function(){return ' + serialized + '}',
348
- );
349
- ctx.assignments = parentAssignment;
350
- }
351
- break;
352
- default: {
353
- const serialized = crossSerializeTree(ctx, value);
354
- const check = Number(key);
355
- const isIdentifier = check >= 0 || isValidIdentifier(key);
356
- if (isIndexedValueInStack(ctx, value)) {
357
- // Test if key is a valid number or JS identifier
358
- // so that we don't have to serialize the key and wrap with brackets
359
- if (isIdentifier && Number.isNaN(check)) {
360
- createObjectAssign(ctx, sourceID, key, serialized);
361
- } else {
362
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), serialized);
363
- }
364
- } else {
365
- // Test if key is a valid number or JS identifier
366
- // so that we don't have to serialize the key and wrap with brackets
367
- parentAssignment = ctx.assignments;
368
- ctx.assignments = mainAssignments;
369
- if (isIdentifier && Number.isNaN(check)) {
370
- createObjectAssign(ctx, sourceID, key, serialized);
371
- } else {
372
- createArrayAssign(ctx, sourceID, isIdentifier ? key : ('"' + key + '"'), serialized);
373
- }
374
- ctx.assignments = parentAssignment;
375
- }
376
- }
377
- }
378
- }
379
- ctx.stack.pop();
380
- return resolveAssignments(mainAssignments);
381
- }
382
54
 
383
- function serializeDictionary(
384
- ctx: CrossSerializerContext,
385
- i: number,
386
- p: SerovalObjectRecordNode | undefined,
387
- init: string,
388
- ): string {
389
- if (p) {
390
- if (ctx.features & Feature.ObjectAssign) {
391
- init = serializeWithObjectAssign(ctx, p, i, init);
392
- } else {
393
- const assignments = serializeAssignments(ctx, i, p);
394
- if (assignments) {
395
- return '(' + assignIndexedValue(i, init) + ',' + assignments + getRefExpr(i) + ')';
396
- }
397
- }
55
+ protected serializePromiseConstructor(
56
+ node: SerovalPromiseConstructorNode,
57
+ ): string {
58
+ return this.assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR + '()');
398
59
  }
399
- return assignIndexedValue(i, init);
400
- }
401
-
402
- const NULL_CONSTRUCTOR = 'Object.create(null)';
403
-
404
- function serializeNullConstructor(
405
- ctx: CrossSerializerContext,
406
- node: SerovalNullConstructorNode,
407
- ): string {
408
- pushObjectFlag(ctx, node.o, node.i);
409
- return serializeDictionary(ctx, node.i, node.p, NULL_CONSTRUCTOR);
410
- }
411
-
412
- function serializeObject(
413
- ctx: CrossSerializerContext,
414
- node: SerovalObjectNode,
415
- ): string {
416
- pushObjectFlag(ctx, node.o, node.i);
417
- return assignIndexedValue(node.i, serializeProperties(ctx, node.i, node.p));
418
- }
419
60
 
420
- function serializeSet(
421
- ctx: CrossSerializerContext,
422
- node: SerovalSetNode,
423
- ): string {
424
- let serialized = 'new Set';
425
- const size = node.l;
426
- const id = node.i;
427
- if (size) {
428
- let result = '';
429
- let item: SerovalNode;
430
- let hasPrev = false;
431
- const items = node.a;
432
- ctx.stack.push(id);
433
- for (let i = 0; i < size; i++) {
434
- item = items[i];
435
- if (isIndexedValueInStack(ctx, item)) {
436
- createAddAssignment(ctx, id, getRefExpr(item.i));
437
- } else {
438
- // Push directly
439
- result += (hasPrev ? ',' : '') + crossSerializeTree(ctx, item);
440
- hasPrev = true;
441
- }
442
- }
443
- ctx.stack.pop();
444
- if (result) {
445
- serialized += '([' + result + '])';
446
- }
61
+ protected serializePromiseResolve(
62
+ node: SerovalPromiseResolveNode,
63
+ ): string {
64
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_RESOLVE + '(' + this.getRefParam(node.i) + ',' + this.serialize(node.f) + ')';
447
65
  }
448
- return assignIndexedValue(id, serialized);
449
- }
450
66
 
451
- function serializeMap(
452
- ctx: CrossSerializerContext,
453
- node: SerovalMapNode,
454
- ): string {
455
- let serialized = 'new Map';
456
- const size = node.e.s;
457
- const id = node.i;
458
- if (size) {
459
- let result = '';
460
- let key: SerovalNode;
461
- let val: SerovalNode;
462
- let keyRef: string;
463
- let valueRef: string;
464
- let parent: number[];
465
- let hasPrev = false;
466
- const keys = node.e.k;
467
- const vals = node.e.v;
468
- ctx.stack.push(id);
469
- for (let i = 0; i < size; i++) {
470
- // Check if key is a parent
471
- key = keys[i];
472
- val = vals[i];
473
- if (isIndexedValueInStack(ctx, key)) {
474
- // Create reference for the map instance
475
- keyRef = getRefExpr(id);
476
- // Check if value is a parent
477
- if (isIndexedValueInStack(ctx, val)) {
478
- valueRef = getRefExpr(val.i);
479
- // Register an assignment since
480
- // both key and value are a parent of this
481
- // Map instance
482
- createSetAssignment(ctx, id, keyRef, valueRef);
483
- } else {
484
- // Reset the stack
485
- // This is required because the serialized
486
- // value is no longer part of the expression
487
- // tree and has been moved to the deferred
488
- // assignment
489
- parent = ctx.stack;
490
- ctx.stack = [];
491
- createSetAssignment(ctx, id, keyRef, crossSerializeTree(ctx, val));
492
- ctx.stack = parent;
493
- }
494
- } else if (isIndexedValueInStack(ctx, val)) {
495
- // Create ref for the Map instance
496
- valueRef = getRefExpr(val.i);
497
- // Reset stack for the key serialization
498
- parent = ctx.stack;
499
- ctx.stack = [];
500
- createSetAssignment(ctx, id, crossSerializeTree(ctx, key), valueRef);
501
- ctx.stack = parent;
502
- } else {
503
- result += (hasPrev ? ',[' : '[') + crossSerializeTree(ctx, key) + ',' + crossSerializeTree(ctx, val) + ']';
504
- hasPrev = true;
505
- }
506
- }
507
- ctx.stack.pop();
508
- // Check if there are any values
509
- // so that the empty Map constructor
510
- // can be used instead
511
- if (result) {
512
- serialized += '([' + result + '])';
513
- }
67
+ protected serializePromiseReject(
68
+ node: SerovalPromiseRejectNode,
69
+ ): string {
70
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_REJECT + '(' + this.getRefParam(node.i) + ',' + this.serialize(node.f) + ')';
514
71
  }
515
- return assignIndexedValue(id, serialized);
516
- }
517
-
518
- function serializeAggregateError(
519
- ctx: CrossSerializerContext,
520
- node: SerovalAggregateErrorNode,
521
- ): string {
522
- // Serialize the required arguments
523
- const id = node.i;
524
- ctx.stack.push(id);
525
- const serialized = 'new AggregateError([],"' + node.m + '")';
526
- ctx.stack.pop();
527
- // `AggregateError` might've been extended
528
- // either through class or custom properties
529
- // Make sure to assign extra properties
530
- return serializeDictionary(ctx, id, node.p, serialized);
531
- }
532
72
 
533
- function serializeError(
534
- ctx: CrossSerializerContext,
535
- node: SerovalErrorNode,
536
- ): string {
537
- return serializeDictionary(ctx, node.i, node.p, 'new ' + node.c + '("' + node.m + '")');
538
- }
539
-
540
- const PROMISE_RESOLVE = 'Promise.resolve';
541
- const PROMISE_REJECT = 'Promise.reject';
542
-
543
- function serializePromise(
544
- ctx: CrossSerializerContext,
545
- node: SerovalPromiseNode,
546
- ): string {
547
- let serialized: string;
548
- // Check if resolved value is a parent expression
549
- const fulfilled = node.f;
550
- const id = node.i;
551
- const constructor = node.s ? PROMISE_RESOLVE : PROMISE_REJECT;
552
- if (isIndexedValueInStack(ctx, fulfilled)) {
553
- // A Promise trick, reference the value
554
- // inside the `then` expression so that
555
- // the Promise evaluates after the parent
556
- // has initialized
557
- const ref = getRefExpr(fulfilled.i);
558
- if (ctx.features & Feature.ArrowFunction) {
559
- if (node.s) {
560
- serialized = constructor + '().then(()=>' + ref + ')';
561
- } else {
562
- serialized = constructor + '().catch(()=>{throw ' + ref + '})';
563
- }
564
- } else if (node.s) {
565
- serialized = constructor + '().then(function(){return ' + ref + '})';
566
- } else {
567
- serialized = constructor + '().catch(function(){throw ' + ref + '})';
568
- }
569
- } else {
570
- ctx.stack.push(id);
571
- const result = crossSerializeTree(ctx, fulfilled);
572
- ctx.stack.pop();
573
- // just inline the value/reference here
574
- serialized = constructor + '(' + result + ')';
73
+ protected serializeReadableStreamConstructor(
74
+ node: SerovalReadableStreamConstructorNode,
75
+ ): string {
76
+ return this.assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_CONSTRUCTOR + '()');
575
77
  }
576
- return assignIndexedValue(id, serialized);
577
- }
578
78
 
579
- function serializeArrayBuffer(
580
- node: SerovalArrayBufferNode,
581
- ): string {
582
- let result = 'new Uint8Array(';
583
- const buffer = node.s;
584
- const len = buffer.length;
585
- if (len) {
586
- result += '[';
587
- for (let i = 0; i < len; i++) {
588
- result += ((i > 0) ? ',' : '') + buffer[i];
589
- }
590
- result += ']';
79
+ protected serializeReadableStreamEnqueue(
80
+ node: SerovalReadableStreamEnqueueNode,
81
+ ): string {
82
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + this.getRefParam(node.i) + ',0,' + this.serialize(node.f) + ')';
591
83
  }
592
- return assignIndexedValue(node.i, result + ').buffer');
593
- }
594
-
595
- function serializeTypedArray(
596
- ctx: CrossSerializerContext,
597
- node: SerovalTypedArrayNode | SerovalBigIntTypedArrayNode,
598
- ): string {
599
- return assignIndexedValue(
600
- node.i,
601
- 'new ' + node.c + '(' + crossSerializeTree(ctx, node.f) + ',' + node.b + ',' + node.l + ')',
602
- );
603
- }
604
-
605
- function serializeDate(
606
- node: SerovalDateNode,
607
- ): string {
608
- return assignIndexedValue(node.i, 'new Date("' + node.s + '")');
609
- }
610
-
611
- function serializeRegExp(
612
- node: SerovalRegExpNode,
613
- ): string {
614
- return assignIndexedValue(node.i, '/' + node.c + '/' + node.m);
615
- }
616
-
617
- function serializeURL(
618
- node: SerovalURLNode,
619
- ): string {
620
- return assignIndexedValue(node.i, 'new URL("' + node.s + '")');
621
- }
622
84
 
623
- function serializeURLSearchParams(
624
- node: SerovalURLSearchParamsNode,
625
- ): string {
626
- return assignIndexedValue(
627
- node.i,
628
- node.s ? 'new URLSearchParams("' + node.s + '")' : 'new URLSearchParams',
629
- );
630
- }
631
-
632
- function serializeReference(
633
- node: SerovalReferenceNode,
634
- ): string {
635
- return assignIndexedValue(node.i, REFERENCES_KEY + '.get("' + node.s + '")');
636
- }
637
-
638
- function serializeDataView(
639
- ctx: CrossSerializerContext,
640
- node: SerovalDataViewNode,
641
- ): string {
642
- return assignIndexedValue(
643
- node.i,
644
- 'new DataView(' + crossSerializeTree(ctx, node.f) + ',' + node.b + ',' + node.l + ')',
645
- );
646
- }
647
-
648
- function serializeBlob(
649
- ctx: CrossSerializerContext,
650
- node: SerovalBlobNode,
651
- ): string {
652
- return assignIndexedValue(
653
- node.i,
654
- 'new Blob([' + crossSerializeTree(ctx, node.f) + '],{type:"' + node.c + '"})',
655
- );
656
- }
657
-
658
- function serializeFile(
659
- ctx: CrossSerializerContext,
660
- node: SerovalFileNode,
661
- ): string {
662
- return assignIndexedValue(
663
- node.i,
664
- 'new File([' + crossSerializeTree(ctx, node.f) + '],"' + node.m + '",{type:"' + node.c + '",lastModified:' + node.b + '})',
665
- );
666
- }
667
-
668
- function serializeHeaders(
669
- ctx: CrossSerializerContext,
670
- node: SerovalHeadersNode,
671
- ): string {
672
- return assignIndexedValue(
673
- node.i,
674
- 'new Headers(' + serializeProperties(ctx, node.i, node.e) + ')',
675
- );
676
- }
677
-
678
- function serializeFormDataEntries(
679
- ctx: CrossSerializerContext,
680
- node: SerovalFormDataNode,
681
- ): string | undefined {
682
- let value: string;
683
- let key: string;
684
- const keys = node.e.k;
685
- const vals = node.e.v;
686
- const id = node.i;
687
- const mainAssignments: Assignment[] = [];
688
- let parentAssignment: Assignment[];
689
- ctx.stack.push(id);
690
- for (let i = 0, len = node.e.s; i < len; i++) {
691
- key = keys[i];
692
- value = crossSerializeTree(ctx, vals[i]);
693
- parentAssignment = ctx.assignments;
694
- ctx.assignments = mainAssignments;
695
- createAppendAssignment(ctx, id, '"' + key + '"', value);
696
- ctx.assignments = parentAssignment;
85
+ protected serializeReadableStreamError(
86
+ node: SerovalReadableStreamErrorNode,
87
+ ): string {
88
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + this.getRefParam(node.i) + ',1,' + this.serialize(node.f) + ')';
697
89
  }
698
- ctx.stack.pop();
699
- return resolveAssignments(mainAssignments);
700
- }
701
90
 
702
- function serializeFormData(
703
- ctx: CrossSerializerContext,
704
- node: SerovalFormDataNode,
705
- ): string {
706
- const size = node.e.s;
707
- const id = node.i;
708
- const result = assignIndexedValue(id, 'new FormData()');
709
- if (size) {
710
- const entries = serializeFormDataEntries(ctx, node);
711
- return '(' + result + ',' + (entries == null ? '' : entries) + getRefExpr(id) + ')';
91
+ protected serializeReadableStreamClose(
92
+ node: SerovalReadableStreamCloseNode,
93
+ ): string {
94
+ return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + this.getRefParam(node.i) + ',2)';
712
95
  }
713
- return result;
714
- }
715
-
716
- function serializeBoxed(
717
- ctx: CrossSerializerContext,
718
- node: SerovalBoxedNode,
719
- ): string {
720
- return assignIndexedValue(node.i, 'Object(' + crossSerializeTree(ctx, node.f) + ')');
721
- }
722
-
723
- function serializeWKSymbol(
724
- node: SerovalWKSymbolNode,
725
- ): string {
726
- return assignIndexedValue(node.i, SYMBOL_STRING[node.s]);
727
- }
728
-
729
- function serializePromiseResolve(
730
- ctx: CrossSerializerContext,
731
- node: SerovalPromiseResolveNode,
732
- ): string {
733
- return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_RESOLVE + '(' + getRefExpr(node.i) + ',' + crossSerializeTree(ctx, node.f) + ')';
734
- }
735
-
736
- function serializePromiseReject(
737
- ctx: CrossSerializerContext,
738
- node: SerovalPromiseRejectNode,
739
- ): string {
740
- return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_REJECT + '(' + getRefExpr(node.i) + ',' + crossSerializeTree(ctx, node.f) + ')';
741
- }
742
-
743
- function serializePromiseConstructor(
744
- node: SerovalPromiseConstructorNode,
745
- ): string {
746
- return assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_PROMISE_CONSTRUCTOR + '()');
747
- }
748
-
749
- function serializeReadableStreamClose(
750
- node: SerovalReadableStreamCloseNode,
751
- ): string {
752
- return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',2)';
753
- }
754
-
755
- function serializeReadableStreamEnqueue(
756
- ctx: CrossSerializerContext,
757
- node: SerovalReadableStreamEnqueueNode,
758
- ): string {
759
- return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',0,' + crossSerializeTree(ctx, node.f) + ')';
760
- }
761
-
762
- function serializeReadableStreamError(
763
- ctx: CrossSerializerContext,
764
- node: SerovalReadableStreamErrorNode,
765
- ): string {
766
- return GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_EMIT + '(' + getRefExpr(node.i) + ',1,' + crossSerializeTree(ctx, node.f) + ')';
767
- }
768
96
 
769
- function serializeReadableStreamConstructor(
770
- node: SerovalReadableStreamConstructorNode,
771
- ): string {
772
- return assignIndexedValue(node.i, GLOBAL_CONTEXT_API + '.' + GLOBAL_CONTEXT_STREAM_CONSTRUCTOR + '()');
773
- }
774
-
775
- function serializeRequest(
776
- ctx: CrossSerializerContext,
777
- node: SerovalRequestNode,
778
- ): string {
779
- return assignIndexedValue(node.i, 'new Request("' + node.s + '",' + crossSerializeTree(ctx, node.f) + ')');
780
- }
781
-
782
- function serializeResponse(
783
- ctx: CrossSerializerContext,
784
- node: SerovalResponseNode,
785
- ): string {
786
- return assignIndexedValue(
787
- node.i,
788
- 'new Response(' + crossSerializeTree(ctx, node.a[0]) + ',' + crossSerializeTree(ctx, node.a[1]) + ')',
789
- );
790
- }
791
-
792
- function serializeEvent(
793
- ctx: CrossSerializerContext,
794
- node: SerovalEventNode,
795
- ): string {
796
- return assignIndexedValue(
797
- node.i,
798
- 'new Event("' + node.s + '",' + crossSerializeTree(ctx, node.f) + ')',
799
- );
800
- }
801
-
802
- function serializeCustomEvent(
803
- ctx: CrossSerializerContext,
804
- node: SerovalCustomEventNode,
805
- ): string {
806
- return assignIndexedValue(
807
- node.i,
808
- 'new CustomEvent("' + node.s + '",' + crossSerializeTree(ctx, node.f) + ')',
809
- );
810
- }
811
-
812
- function serializeDOMException(
813
- node: SerovalDOMExceptionNode,
814
- ): string {
815
- return assignIndexedValue(
816
- node.i,
817
- 'new DOMException("' + node.s + '","' + node.c + '")',
818
- );
819
- }
820
-
821
- export default function crossSerializeTree(
822
- ctx: CrossSerializerContext,
823
- node: SerovalNode,
824
- ): string {
825
- switch (node.t) {
826
- case SerovalNodeType.Number:
827
- return '' + node.s;
828
- case SerovalNodeType.String:
829
- return '"' + node.s + '"';
830
- case SerovalNodeType.Constant:
831
- return serializeConstant(node);
832
- case SerovalNodeType.BigInt:
833
- return node.s + 'n';
834
- case SerovalNodeType.IndexedValue:
835
- return getRefExpr(node.i);
836
- case SerovalNodeType.Array:
837
- return serializeArray(ctx, node);
838
- case SerovalNodeType.Object:
839
- return serializeObject(ctx, node);
840
- case SerovalNodeType.NullConstructor:
841
- return serializeNullConstructor(ctx, node);
842
- case SerovalNodeType.Date:
843
- return serializeDate(node);
844
- case SerovalNodeType.RegExp:
845
- return serializeRegExp(node);
846
- case SerovalNodeType.Set:
847
- return serializeSet(ctx, node);
848
- case SerovalNodeType.Map:
849
- return serializeMap(ctx, node);
850
- case SerovalNodeType.ArrayBuffer:
851
- return serializeArrayBuffer(node);
852
- case SerovalNodeType.BigIntTypedArray:
853
- case SerovalNodeType.TypedArray:
854
- return serializeTypedArray(ctx, node);
855
- case SerovalNodeType.DataView:
856
- return serializeDataView(ctx, node);
857
- case SerovalNodeType.AggregateError:
858
- return serializeAggregateError(ctx, node);
859
- case SerovalNodeType.Error:
860
- return serializeError(ctx, node);
861
- case SerovalNodeType.Promise:
862
- return serializePromise(ctx, node);
863
- case SerovalNodeType.WKSymbol:
864
- return serializeWKSymbol(node);
865
- case SerovalNodeType.URL:
866
- return serializeURL(node);
867
- case SerovalNodeType.URLSearchParams:
868
- return serializeURLSearchParams(node);
869
- case SerovalNodeType.Reference:
870
- return serializeReference(node);
871
- case SerovalNodeType.Blob:
872
- return serializeBlob(ctx, node);
873
- case SerovalNodeType.File:
874
- return serializeFile(ctx, node);
875
- case SerovalNodeType.Headers:
876
- return serializeHeaders(ctx, node);
877
- case SerovalNodeType.FormData:
878
- return serializeFormData(ctx, node);
879
- case SerovalNodeType.Boxed:
880
- return serializeBoxed(ctx, node);
881
- case SerovalNodeType.PromiseResolve:
882
- return serializePromiseResolve(ctx, node);
883
- case SerovalNodeType.PromiseReject:
884
- return serializePromiseReject(ctx, node);
885
- case SerovalNodeType.PromiseConstructor:
886
- return serializePromiseConstructor(node);
887
- case SerovalNodeType.ReadableStreamClose:
888
- return serializeReadableStreamClose(node);
889
- case SerovalNodeType.ReadableStreamConstructor:
890
- return serializeReadableStreamConstructor(node);
891
- case SerovalNodeType.ReadableStreamEnqueue:
892
- return serializeReadableStreamEnqueue(ctx, node);
893
- case SerovalNodeType.ReadableStreamError:
894
- return serializeReadableStreamError(ctx, node);
895
- case SerovalNodeType.Request:
896
- return serializeRequest(ctx, node);
897
- case SerovalNodeType.Response:
898
- return serializeResponse(ctx, node);
899
- case SerovalNodeType.Event:
900
- return serializeEvent(ctx, node);
901
- case SerovalNodeType.CustomEvent:
902
- return serializeCustomEvent(ctx, node);
903
- case SerovalNodeType.DOMException:
904
- return serializeDOMException(node);
905
- default:
906
- throw new Error('invariant');
97
+ serializeTop(tree: SerovalNode): string {
98
+ const result = this.serialize(tree);
99
+ const id = tree.i;
100
+ if (id == null) {
101
+ return result;
102
+ }
103
+ const patches = this.resolvePatches();
104
+ const ref = this.getRefParam(id);
105
+ const params = this.scopeId == null ? '' : GLOBAL_CONTEXT_REFERENCES;
106
+ const mainBody = patches ? result + ',' + patches : result;
107
+ if (params === '') {
108
+ return patches ? '(' + mainBody + ref + ')' : mainBody;
109
+ }
110
+ const args = this.scopeId == null ? '()' : '(' + GLOBAL_CONTEXT_REFERENCES + '["' + serializeString(this.scopeId) + '"])';
111
+ const body = mainBody + (patches ? ref : '');
112
+ if (this.features & Feature.ArrowFunction) {
113
+ return '(' + params + '=>(' + body + '))' + args;
114
+ }
115
+ return '(function(' + params + '){return ' + body + '})' + args;
907
116
  }
908
117
  }