seroval 1.2.1 → 1.3.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 (50) hide show
  1. package/LICENSE +1 -1
  2. package/dist/cjs/development/index.cjs +259 -381
  3. package/dist/cjs/development/index.cjs.map +3 -3
  4. package/dist/cjs/production/index.cjs +6 -6
  5. package/dist/esm/development/index.mjs +259 -381
  6. package/dist/esm/development/index.mjs.map +3 -3
  7. package/dist/esm/production/index.mjs +6 -6
  8. package/dist/types/core/base-primitives.d.ts +1 -2
  9. package/dist/types/core/base-primitives.d.ts.map +1 -1
  10. package/dist/types/core/compat.d.ts +2 -3
  11. package/dist/types/core/compat.d.ts.map +1 -1
  12. package/dist/types/core/constants.d.ts +3 -6
  13. package/dist/types/core/constants.d.ts.map +1 -1
  14. package/dist/types/core/context/deserializer.d.ts +0 -3
  15. package/dist/types/core/context/deserializer.d.ts.map +1 -1
  16. package/dist/types/core/context/parser/async.d.ts +1 -2
  17. package/dist/types/core/context/parser/async.d.ts.map +1 -1
  18. package/dist/types/core/context/parser/stream.d.ts +8 -8
  19. package/dist/types/core/context/parser/stream.d.ts.map +1 -1
  20. package/dist/types/core/context/parser/sync.d.ts +2 -3
  21. package/dist/types/core/context/parser/sync.d.ts.map +1 -1
  22. package/dist/types/core/context/parser.d.ts +3 -3
  23. package/dist/types/core/context/parser.d.ts.map +1 -1
  24. package/dist/types/core/context/serializer.d.ts +1 -5
  25. package/dist/types/core/context/serializer.d.ts.map +1 -1
  26. package/dist/types/core/function-string.d.ts +3 -0
  27. package/dist/types/core/function-string.d.ts.map +1 -0
  28. package/dist/types/core/special-reference.d.ts +4 -5
  29. package/dist/types/core/special-reference.d.ts.map +1 -1
  30. package/dist/types/core/tree/serializer.d.ts +1 -2
  31. package/dist/types/core/tree/serializer.d.ts.map +1 -1
  32. package/dist/types/core/types.d.ts +5 -19
  33. package/dist/types/core/types.d.ts.map +1 -1
  34. package/package.json +8 -8
  35. package/src/core/base-primitives.ts +2 -22
  36. package/src/core/compat.ts +6 -2
  37. package/src/core/constants.ts +2 -5
  38. package/src/core/context/deserializer.ts +2 -35
  39. package/src/core/context/parser/async.ts +54 -83
  40. package/src/core/context/parser/stream.ts +64 -111
  41. package/src/core/context/parser/sync.ts +53 -83
  42. package/src/core/context/parser.ts +9 -24
  43. package/src/core/context/serializer.ts +12 -128
  44. package/src/core/function-string.ts +31 -0
  45. package/src/core/special-reference.ts +96 -8
  46. package/src/core/tree/serializer.ts +0 -7
  47. package/src/core/types.ts +5 -27
  48. package/dist/types/core/abort-signal.d.ts +0 -2
  49. package/dist/types/core/abort-signal.d.ts.map +0 -1
  50. package/src/core/abort-signal.ts +0 -19
@@ -12,13 +12,11 @@ import {
12
12
  SerovalSerializationError,
13
13
  SerovalUnsupportedNodeError,
14
14
  } from '../errors';
15
+ import { createEffectfulFunction, createFunction } from '../function-string';
15
16
  import { REFERENCES_KEY } from '../keys';
16
17
  import type { Plugin, PluginAccessOptions, SerovalMode } from '../plugin';
17
- import { SpecialReference } from '../special-reference';
18
+ import { serializeSpecialReferenceValue } from '../special-reference';
18
19
  import type {
19
- SerovalAbortSignalAbortNode,
20
- SerovalAbortSignalConstructorNode,
21
- SerovalAbortSignalSyncNode,
22
20
  SerovalAggregateErrorNode,
23
21
  SerovalArrayBufferNode,
24
22
  SerovalArrayNode,
@@ -253,25 +251,11 @@ export default abstract class BaseSerializerContext
253
251
  abstract readonly mode: SerovalMode;
254
252
 
255
253
  createFunction(parameters: string[], body: string): string {
256
- if (this.features & Feature.ArrowFunction) {
257
- const joined =
258
- parameters.length === 1
259
- ? parameters[0]
260
- : '(' + parameters.join(',') + ')';
261
- return joined + '=>' + (body.startsWith('{') ? '(' + body + ')' : body);
262
- }
263
- return 'function(' + parameters.join(',') + '){return ' + body + '}';
254
+ return createFunction(this.features, parameters, body);
264
255
  }
265
256
 
266
257
  createEffectfulFunction(parameters: string[], body: string): string {
267
- if (this.features & Feature.ArrowFunction) {
268
- const joined =
269
- parameters.length === 1
270
- ? parameters[0]
271
- : '(' + parameters.join(',') + ')';
272
- return joined + '=>{' + body + '}';
273
- }
274
- return 'function(' + parameters.join(',') + '){' + body + '}';
258
+ return createEffectfulFunction(this.features, parameters, body);
275
259
  }
276
260
 
277
261
  /**
@@ -919,7 +903,11 @@ export default abstract class BaseSerializerContext
919
903
  protected serializePromiseConstructor(
920
904
  node: SerovalPromiseConstructorNode,
921
905
  ): string {
922
- return this.assignIndexedValue(node.i, this.getConstructor(node.f) + '()');
906
+ const resolver = this.assignIndexedValue(node.s, '{p:0,s:0,f:0}');
907
+ return this.assignIndexedValue(
908
+ node.i,
909
+ this.getConstructor(node.f) + '(' + resolver + ')',
910
+ );
923
911
  }
924
912
 
925
913
  protected serializePromiseResolve(node: SerovalPromiseResolveNode): string {
@@ -944,84 +932,12 @@ export default abstract class BaseSerializerContext
944
932
  );
945
933
  }
946
934
 
947
- private serializeSpecialReferenceValue(ref: SpecialReference): string {
948
- switch (ref) {
949
- case SpecialReference.MapSentinel:
950
- return '[]';
951
- case SpecialReference.PromiseConstructor:
952
- return this.createFunction(
953
- ['s', 'f', 'p'],
954
- '((p=new Promise(' +
955
- this.createEffectfulFunction(['a', 'b'], 's=a,f=b') +
956
- ')).s=s,p.f=f,p)',
957
- );
958
- case SpecialReference.PromiseResolve:
959
- return this.createEffectfulFunction(
960
- ['p', 'd'],
961
- 'p.s(d),p.status="success",p.value=d;delete p.s;delete p.f',
962
- );
963
- case SpecialReference.PromiseReject:
964
- return this.createEffectfulFunction(
965
- ['p', 'd'],
966
- 'p.f(d),p.status="failure",p.value=d;delete p.s;delete p.f',
967
- );
968
- case SpecialReference.StreamConstructor:
969
- return this.createFunction(
970
- ['b', 'a', 's', 'l', 'p', 'f', 'e', 'n'],
971
- '(b=[],a=!0,s=!1,l=[],p=0,f=' +
972
- this.createEffectfulFunction(
973
- ['v', 'm', 'x'],
974
- 'for(x=0;x<p;x++)l[x]&&l[x][m](v)',
975
- ) +
976
- ',n=' +
977
- this.createEffectfulFunction(
978
- ['o', 'x', 'z', 'c'],
979
- 'for(x=0,z=b.length;x<z;x++)(c=b[x],(!a&&x===z-1)?o[s?"return":"throw"](c):o.next(c))',
980
- ) +
981
- ',e=' +
982
- this.createFunction(
983
- ['o', 't'],
984
- '(a&&(l[t=p++]=o),n(o),' +
985
- this.createEffectfulFunction([], 'a&&(l[t]=void 0)') +
986
- ')',
987
- ) +
988
- ',{__SEROVAL_STREAM__:!0,on:' +
989
- this.createFunction(['o'], 'e(o)') +
990
- ',next:' +
991
- this.createEffectfulFunction(['v'], 'a&&(b.push(v),f(v,"next"))') +
992
- ',throw:' +
993
- this.createEffectfulFunction(
994
- ['v'],
995
- 'a&&(b.push(v),f(v,"throw"),a=s=!1,l.length=0)',
996
- ) +
997
- ',return:' +
998
- this.createEffectfulFunction(
999
- ['v'],
1000
- 'a&&(b.push(v),f(v,"return"),a=!1,s=!0,l.length=0)',
1001
- ) +
1002
- '})',
1003
- );
1004
- case SpecialReference.AbortSignalConstructor:
1005
- return this.createFunction(
1006
- ['a', 's'],
1007
- '((s=(a=new AbortController).signal).a=a,s)',
1008
- );
1009
- case SpecialReference.AbortSignalAbort:
1010
- return this.createEffectfulFunction(
1011
- ['s', 'r'],
1012
- 's.a.abort(r);delete s.a',
1013
- );
1014
- default:
1015
- return '';
1016
- }
1017
- }
1018
-
1019
935
  protected serializeSpecialReference(
1020
936
  node: SerovalSpecialReferenceNode,
1021
937
  ): string {
1022
938
  return this.assignIndexedValue(
1023
939
  node.i,
1024
- this.serializeSpecialReferenceValue(node.s),
940
+ serializeSpecialReferenceValue(this.features, node.s),
1025
941
  );
1026
942
  }
1027
943
 
@@ -1173,32 +1089,6 @@ export default abstract class BaseSerializerContext
1173
1089
  return this.getRefParam(node.i) + '.return(' + this.serialize(node.f) + ')';
1174
1090
  }
1175
1091
 
1176
- protected serializeAbortSignalSync(node: SerovalAbortSignalSyncNode): string {
1177
- return this.assignIndexedValue(
1178
- node.i,
1179
- 'AbortSignal.abort(' + this.serialize(node.f) + ')',
1180
- );
1181
- }
1182
-
1183
- protected serializeAbortSignalConstructor(
1184
- node: SerovalAbortSignalConstructorNode,
1185
- ): string {
1186
- return this.assignIndexedValue(node.i, this.getConstructor(node.f) + '()');
1187
- }
1188
-
1189
- protected serializeAbortSignalAbort(
1190
- node: SerovalAbortSignalAbortNode,
1191
- ): string {
1192
- return (
1193
- this.getConstructor(node.a[0]) +
1194
- '(' +
1195
- this.getRefParam(node.i) +
1196
- ',' +
1197
- this.serialize(node.a[1]) +
1198
- ')'
1199
- );
1200
- }
1201
-
1202
1092
  serialize(node: SerovalNode): string {
1203
1093
  try {
1204
1094
  switch (node.t) {
@@ -1247,9 +1137,9 @@ export default abstract class BaseSerializerContext
1247
1137
  return this.serializeBoxed(node);
1248
1138
  case SerovalNodeType.PromiseConstructor:
1249
1139
  return this.serializePromiseConstructor(node);
1250
- case SerovalNodeType.PromiseResolve:
1140
+ case SerovalNodeType.PromiseSuccess:
1251
1141
  return this.serializePromiseResolve(node);
1252
- case SerovalNodeType.PromiseReject:
1142
+ case SerovalNodeType.PromiseFailure:
1253
1143
  return this.serializePromiseReject(node);
1254
1144
  case SerovalNodeType.Plugin:
1255
1145
  return this.serializePlugin(node);
@@ -1271,12 +1161,6 @@ export default abstract class BaseSerializerContext
1271
1161
  return this.serializeStreamThrow(node);
1272
1162
  case SerovalNodeType.StreamReturn:
1273
1163
  return this.serializeStreamReturn(node);
1274
- case SerovalNodeType.AbortSignalAbort:
1275
- return this.serializeAbortSignalAbort(node);
1276
- case SerovalNodeType.AbortSignalConstructor:
1277
- return this.serializeAbortSignalConstructor(node);
1278
- case SerovalNodeType.AbortSignalSync:
1279
- return this.serializeAbortSignalSync(node);
1280
1164
  default:
1281
1165
  throw new SerovalUnsupportedNodeError(node);
1282
1166
  }
@@ -0,0 +1,31 @@
1
+ import { Feature } from './compat';
2
+
3
+ export function createFunction(
4
+ features: number,
5
+ parameters: string[],
6
+ body: string,
7
+ ): string {
8
+ if (features & Feature.ArrowFunction) {
9
+ const joined =
10
+ parameters.length === 1
11
+ ? parameters[0]
12
+ : '(' + parameters.join(',') + ')';
13
+ return joined + '=>' + (body.startsWith('{') ? '(' + body + ')' : body);
14
+ }
15
+ return 'function(' + parameters.join(',') + '){return ' + body + '}';
16
+ }
17
+
18
+ export function createEffectfulFunction(
19
+ features: number,
20
+ parameters: string[],
21
+ body: string,
22
+ ): string {
23
+ if (features & Feature.ArrowFunction) {
24
+ const joined =
25
+ parameters.length === 1
26
+ ? parameters[0]
27
+ : '(' + parameters.join(',') + ')';
28
+ return joined + '=>{' + body + '}';
29
+ }
30
+ return 'function(' + parameters.join(',') + '){' + body + '}';
31
+ }
@@ -1,3 +1,5 @@
1
+ import { createEffectfulFunction, createFunction } from './function-string';
2
+
1
3
  export const ITERATOR = {};
2
4
 
3
5
  export const ASYNC_ITERATOR = {};
@@ -5,11 +7,9 @@ export const ASYNC_ITERATOR = {};
5
7
  export const enum SpecialReference {
6
8
  MapSentinel = 0,
7
9
  PromiseConstructor = 1,
8
- PromiseResolve = 2,
9
- PromiseReject = 3,
10
+ PromiseSuccess = 2,
11
+ PromiseFailure = 3,
10
12
  StreamConstructor = 4,
11
- AbortSignalConstructor = 5,
12
- AbortSignalAbort = 6,
13
13
  }
14
14
 
15
15
  /**
@@ -18,9 +18,97 @@ export const enum SpecialReference {
18
18
  export const SPECIAL_REFS: Record<SpecialReference, unknown> = {
19
19
  [SpecialReference.MapSentinel]: {},
20
20
  [SpecialReference.PromiseConstructor]: {},
21
- [SpecialReference.PromiseResolve]: {},
22
- [SpecialReference.PromiseReject]: {},
21
+ [SpecialReference.PromiseSuccess]: {},
22
+ [SpecialReference.PromiseFailure]: {},
23
23
  [SpecialReference.StreamConstructor]: {},
24
- [SpecialReference.AbortSignalConstructor]: {},
25
- [SpecialReference.AbortSignalAbort]: {},
26
24
  };
25
+
26
+ function serializePromiseConstructor(features: number): string {
27
+ return createFunction(
28
+ features,
29
+ ['r'],
30
+ '(r.p=new Promise(' +
31
+ createEffectfulFunction(features, ['s', 'f'], 'r.s=s,r.f=f') +
32
+ '))',
33
+ );
34
+ }
35
+
36
+ function serializePromiseSuccess(features: number): string {
37
+ return createEffectfulFunction(
38
+ features,
39
+ ['r', 'd'],
40
+ 'r.s(d),r.p.s=1,r.p.v=d',
41
+ );
42
+ }
43
+
44
+ function serializePromiseFailure(features: number): string {
45
+ return createEffectfulFunction(
46
+ features,
47
+ ['r', 'd'],
48
+ 'r.f(d),r.p.s=2,r.p.v=d',
49
+ );
50
+ }
51
+
52
+ function serializeStreamConstructor(features: number): string {
53
+ return createFunction(
54
+ features,
55
+ ['b', 'a', 's', 'l', 'p', 'f', 'e', 'n'],
56
+ '(b=[],a=!0,s=!1,l=[],p=0,f=' +
57
+ createEffectfulFunction(
58
+ features,
59
+ ['v', 'm', 'x'],
60
+ 'for(x=0;x<p;x++)l[x]&&l[x][m](v)',
61
+ ) +
62
+ ',n=' +
63
+ createEffectfulFunction(
64
+ features,
65
+ ['o', 'x', 'z', 'c'],
66
+ 'for(x=0,z=b.length;x<z;x++)(c=b[x],(!a&&x===z-1)?o[s?"return":"throw"](c):o.next(c))',
67
+ ) +
68
+ ',e=' +
69
+ createFunction(
70
+ features,
71
+ ['o', 't'],
72
+ '(a&&(l[t=p++]=o),n(o),' +
73
+ createEffectfulFunction(features, [], 'a&&(l[t]=void 0)') +
74
+ ')',
75
+ ) +
76
+ ',{__SEROVAL_STREAM__:!0,on:' +
77
+ createFunction(features, ['o'], 'e(o)') +
78
+ ',next:' +
79
+ createEffectfulFunction(features, ['v'], 'a&&(b.push(v),f(v,"next"))') +
80
+ ',throw:' +
81
+ createEffectfulFunction(
82
+ features,
83
+ ['v'],
84
+ 'a&&(b.push(v),f(v,"throw"),a=s=!1,l.length=0)',
85
+ ) +
86
+ ',return:' +
87
+ createEffectfulFunction(
88
+ features,
89
+ ['v'],
90
+ 'a&&(b.push(v),f(v,"return"),a=!1,s=!0,l.length=0)',
91
+ ) +
92
+ '})',
93
+ );
94
+ }
95
+
96
+ export function serializeSpecialReferenceValue(
97
+ features: number,
98
+ ref: SpecialReference,
99
+ ): string {
100
+ switch (ref) {
101
+ case SpecialReference.MapSentinel:
102
+ return '[]';
103
+ case SpecialReference.PromiseConstructor:
104
+ return serializePromiseConstructor(features);
105
+ case SpecialReference.PromiseSuccess:
106
+ return serializePromiseSuccess(features);
107
+ case SpecialReference.PromiseFailure:
108
+ return serializePromiseFailure(features);
109
+ case SpecialReference.StreamConstructor:
110
+ return serializeStreamConstructor(features);
111
+ default:
112
+ return '';
113
+ }
114
+ }
@@ -4,7 +4,6 @@ import BaseSerializerContext from '../context/serializer';
4
4
  import { SerovalUnsupportedNodeError } from '../errors';
5
5
  import type { SerovalMode } from '../plugin';
6
6
  import type {
7
- SerovalAbortSignalAbortNode,
8
7
  SerovalNode,
9
8
  SerovalPromiseConstructorNode,
10
9
  SerovalPromiseRejectNode,
@@ -74,12 +73,6 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
74
73
  throw new SerovalUnsupportedNodeError(node);
75
74
  }
76
75
 
77
- protected serializeAbortSignalAbort(
78
- node: SerovalAbortSignalAbortNode,
79
- ): string {
80
- throw new SerovalUnsupportedNodeError(node);
81
- }
82
-
83
76
  serializeTop(tree: SerovalNode): string {
84
77
  const result = this.serialize(tree);
85
78
  // Shared references detected
package/src/core/types.ts CHANGED
@@ -245,17 +245,18 @@ export interface SerovalBoxedNode extends SerovalBaseNode {
245
245
  export interface SerovalPromiseConstructorNode extends SerovalBaseNode {
246
246
  t: SerovalNodeType.PromiseConstructor;
247
247
  i: number;
248
+ s: number;
248
249
  f: SerovalNodeWithID;
249
250
  }
250
251
 
251
252
  export interface SerovalPromiseResolveNode extends SerovalBaseNode {
252
- t: SerovalNodeType.PromiseResolve;
253
+ t: SerovalNodeType.PromiseSuccess;
253
254
  i: number;
254
255
  a: [resolver: SerovalNodeWithID, resolved: SerovalNode];
255
256
  }
256
257
 
257
258
  export interface SerovalPromiseRejectNode extends SerovalBaseNode {
258
- t: SerovalNodeType.PromiseReject;
259
+ t: SerovalNodeType.PromiseFailure;
259
260
  i: number;
260
261
  a: [resolver: SerovalNodeWithID, resolved: SerovalNode];
261
262
  }
@@ -330,26 +331,6 @@ export interface SerovalStreamReturnNode extends SerovalBaseNode {
330
331
  f: SerovalNode;
331
332
  }
332
333
 
333
- export interface SerovalAbortSignalConstructorNode extends SerovalBaseNode {
334
- t: SerovalNodeType.AbortSignalConstructor;
335
- i: number;
336
- // special reference to the constructor
337
- f: SerovalNodeWithID;
338
- }
339
-
340
- export interface SerovalAbortSignalAbortNode extends SerovalBaseNode {
341
- t: SerovalNodeType.AbortSignalAbort;
342
- i: number;
343
- a: [resolver: SerovalNodeWithID, resolved: SerovalNode];
344
- }
345
-
346
- export interface SerovalAbortSignalSyncNode extends SerovalBaseNode {
347
- t: SerovalNodeType.AbortSignalSync;
348
- i: number;
349
- // Abort reason
350
- f: SerovalNode;
351
- }
352
-
353
334
  export type SerovalSyncNode =
354
335
  | SerovalPrimitiveNode
355
336
  | SerovalIndexedValueNode
@@ -372,8 +353,7 @@ export type SerovalSyncNode =
372
353
  | SerovalIteratorFactoryNode
373
354
  | SerovalIteratorFactoryInstanceNode
374
355
  | SerovalAsyncIteratorFactoryNode
375
- | SerovalAsyncIteratorFactoryInstanceNode
376
- | SerovalAbortSignalSyncNode;
356
+ | SerovalAsyncIteratorFactoryInstanceNode;
377
357
 
378
358
  export type SerovalAsyncNode =
379
359
  | SerovalPromiseNode
@@ -383,9 +363,7 @@ export type SerovalAsyncNode =
383
363
  | SerovalStreamConstructorNode
384
364
  | SerovalStreamNextNode
385
365
  | SerovalStreamThrowNode
386
- | SerovalStreamReturnNode
387
- | SerovalAbortSignalConstructorNode
388
- | SerovalAbortSignalAbortNode;
366
+ | SerovalStreamReturnNode;
389
367
 
390
368
  export type SerovalNode = SerovalSyncNode | SerovalAsyncNode;
391
369
 
@@ -1,2 +0,0 @@
1
- export declare function abortSignalToPromise(signal: AbortSignal): Promise<any>;
2
- //# sourceMappingURL=abort-signal.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"abort-signal.d.ts","sourceRoot":"","sources":["../../../src/core/abort-signal.ts"],"names":[],"mappings":"AAgBA,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,CAEtE"}
@@ -1,19 +0,0 @@
1
- function resolveAbortSignalResult(
2
- this: AbortSignal,
3
- resolve: (value: any) => void,
4
- ): void {
5
- resolve(this.reason);
6
- }
7
-
8
- function resolveAbortSignal(
9
- this: AbortSignal,
10
- resolve: (value: any) => void,
11
- ): void {
12
- this.addEventListener('abort', resolveAbortSignalResult.bind(this, resolve), {
13
- once: true,
14
- });
15
- }
16
-
17
- export function abortSignalToPromise(signal: AbortSignal): Promise<any> {
18
- return new Promise(resolveAbortSignal.bind(signal));
19
- }