seroval 0.12.3 → 0.13.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 (140) hide show
  1. package/dist/cjs/development/index.cjs +1432 -958
  2. package/dist/cjs/development/index.cjs.map +3 -3
  3. package/dist/cjs/production/index.cjs +3 -3
  4. package/dist/esm/development/index.mjs +1432 -958
  5. package/dist/esm/development/index.mjs.map +3 -3
  6. package/dist/esm/production/index.mjs +3 -3
  7. package/dist/types/core/Serializer.d.ts +2 -1
  8. package/dist/types/core/Serializer.d.ts.map +1 -1
  9. package/dist/types/core/base-primitives.d.ts +12 -1
  10. package/dist/types/core/base-primitives.d.ts.map +1 -1
  11. package/dist/types/core/compat.d.ts +0 -2
  12. package/dist/types/core/compat.d.ts.map +1 -1
  13. package/dist/types/core/constants.d.ts +8 -2
  14. package/dist/types/core/constants.d.ts.map +1 -1
  15. package/dist/types/core/{tree/deserialize.d.ts → context/deserializer.d.ts} +19 -13
  16. package/dist/types/core/context/deserializer.d.ts.map +1 -0
  17. package/dist/types/core/{base → context/parser}/async.d.ts +6 -5
  18. package/dist/types/core/context/parser/async.d.ts.map +1 -0
  19. package/dist/types/core/{base → context/parser}/stream.d.ts +2 -1
  20. package/dist/types/core/context/parser/stream.d.ts.map +1 -0
  21. package/dist/types/core/{base → context/parser}/sync.d.ts +7 -9
  22. package/dist/types/core/context/parser/sync.d.ts.map +1 -0
  23. package/dist/types/core/context/parser.d.ts +27 -0
  24. package/dist/types/core/context/parser.d.ts.map +1 -0
  25. package/dist/types/core/{serializer-context.old.d.ts → context/serializer.d.ts} +21 -22
  26. package/dist/types/core/context/serializer.d.ts.map +1 -0
  27. package/dist/types/core/cross/async.d.ts +2 -2
  28. package/dist/types/core/cross/async.d.ts.map +1 -1
  29. package/dist/types/core/cross/deserializer.d.ts +9 -0
  30. package/dist/types/core/cross/deserializer.d.ts.map +1 -0
  31. package/dist/types/core/cross/index.d.ts +11 -1
  32. package/dist/types/core/cross/index.d.ts.map +1 -1
  33. package/dist/types/core/cross/parser.d.ts +6 -0
  34. package/dist/types/core/cross/parser.d.ts.map +1 -0
  35. package/dist/types/core/cross/{serialize.d.ts → serializer.d.ts} +6 -5
  36. package/dist/types/core/cross/serializer.d.ts.map +1 -0
  37. package/dist/types/core/cross/stream.d.ts +2 -2
  38. package/dist/types/core/cross/stream.d.ts.map +1 -1
  39. package/dist/types/core/cross/sync.d.ts +2 -2
  40. package/dist/types/core/cross/sync.d.ts.map +1 -1
  41. package/dist/types/core/keys.d.ts +3 -1
  42. package/dist/types/core/keys.d.ts.map +1 -1
  43. package/dist/types/core/plugin.d.ts +6 -7
  44. package/dist/types/core/plugin.d.ts.map +1 -1
  45. package/dist/types/core/special-reference.d.ts +6 -0
  46. package/dist/types/core/special-reference.d.ts.map +1 -0
  47. package/dist/types/core/tree/async.d.ts +2 -2
  48. package/dist/types/core/tree/async.d.ts.map +1 -1
  49. package/dist/types/core/tree/deserializer.d.ts +13 -0
  50. package/dist/types/core/tree/deserializer.d.ts.map +1 -0
  51. package/dist/types/core/tree/{serialize.d.ts → serializer.d.ts} +4 -4
  52. package/dist/types/core/tree/serializer.d.ts.map +1 -0
  53. package/dist/types/core/tree/sync.d.ts +2 -2
  54. package/dist/types/core/tree/sync.d.ts.map +1 -1
  55. package/dist/types/core/types.d.ts +47 -6
  56. package/dist/types/core/types.d.ts.map +1 -1
  57. package/dist/types/core/utils/assert.d.ts.map +1 -0
  58. package/dist/types/core/utils/constructors.d.ts.map +1 -0
  59. package/dist/types/core/utils/deferred.d.ts +14 -0
  60. package/dist/types/core/utils/deferred.d.ts.map +1 -0
  61. package/dist/types/core/utils/error.d.ts +5 -0
  62. package/dist/types/core/utils/error.d.ts.map +1 -0
  63. package/dist/types/core/utils/get-identifier.d.ts.map +1 -0
  64. package/dist/types/core/utils/get-object-flag.d.ts +3 -0
  65. package/dist/types/core/utils/get-object-flag.d.ts.map +1 -0
  66. package/dist/types/core/utils/is-valid-identifier.d.ts +2 -0
  67. package/dist/types/core/utils/is-valid-identifier.d.ts.map +1 -0
  68. package/dist/types/core/utils/iterator-to-sequence.d.ts +20 -0
  69. package/dist/types/core/utils/iterator-to-sequence.d.ts.map +1 -0
  70. package/dist/types/core/utils/promise-to-result.d.ts.map +1 -0
  71. package/dist/types/core/utils/typed-array.d.ts +4 -0
  72. package/dist/types/core/utils/typed-array.d.ts.map +1 -0
  73. package/dist/types/core/web-api.d.ts +4 -1
  74. package/dist/types/core/web-api.d.ts.map +1 -1
  75. package/package.json +2 -2
  76. package/src/core/Serializer.ts +3 -1
  77. package/src/core/base-primitives.ts +229 -1
  78. package/src/core/compat.ts +0 -2
  79. package/src/core/constants.ts +7 -2
  80. package/src/core/{tree/deserialize.ts → context/deserializer.ts} +159 -66
  81. package/src/core/{base → context/parser}/async.ts +181 -309
  82. package/src/core/{base → context/parser}/stream.ts +86 -11
  83. package/src/core/{base → context/parser}/sync.ts +120 -281
  84. package/src/core/context/parser.ts +259 -0
  85. package/src/core/{serializer-context.old.ts → context/serializer.ts} +241 -166
  86. package/src/core/cross/async.ts +2 -2
  87. package/src/core/cross/deserializer.ts +19 -0
  88. package/src/core/cross/index.ts +68 -47
  89. package/src/core/cross/parser.ts +7 -0
  90. package/src/core/cross/{serialize.ts → serializer.ts} +31 -12
  91. package/src/core/cross/stream.ts +2 -2
  92. package/src/core/cross/sync.ts +2 -2
  93. package/src/core/is-serializable.new.ts +1 -1
  94. package/src/core/keys.ts +8 -2
  95. package/src/core/plugin.ts +7 -7
  96. package/src/core/reference.ts +1 -1
  97. package/src/core/special-reference.ts +9 -0
  98. package/src/core/tree/async.ts +2 -2
  99. package/src/core/tree/deserializer.ts +31 -0
  100. package/src/core/tree/index.ts +2 -2
  101. package/src/core/tree/{serialize.ts → serializer.ts} +5 -16
  102. package/src/core/tree/sync.ts +2 -2
  103. package/src/core/types.ts +60 -7
  104. package/src/core/utils/deferred.ts +49 -0
  105. package/src/core/{shared.ts → utils/error.ts} +3 -60
  106. package/src/core/utils/get-object-flag.ts +14 -0
  107. package/src/core/utils/is-valid-identifier.ts +11 -0
  108. package/src/core/utils/iterator-to-sequence.ts +238 -0
  109. package/src/core/utils/typed-array.ts +30 -0
  110. package/src/core/web-api.ts +75 -1
  111. package/src/example.ts +0 -3
  112. package/dist/types/core/assert.d.ts.map +0 -1
  113. package/dist/types/core/base/async.d.ts.map +0 -1
  114. package/dist/types/core/base/stream.d.ts.map +0 -1
  115. package/dist/types/core/base/sync.d.ts.map +0 -1
  116. package/dist/types/core/constructors.d.ts.map +0 -1
  117. package/dist/types/core/cross/cross-parser.d.ts +0 -8
  118. package/dist/types/core/cross/cross-parser.d.ts.map +0 -1
  119. package/dist/types/core/cross/serialize.d.ts.map +0 -1
  120. package/dist/types/core/get-identifier.d.ts.map +0 -1
  121. package/dist/types/core/parser-context.d.ts +0 -23
  122. package/dist/types/core/parser-context.d.ts.map +0 -1
  123. package/dist/types/core/promise-to-result.d.ts.map +0 -1
  124. package/dist/types/core/serializer-context.old.d.ts.map +0 -1
  125. package/dist/types/core/shared.d.ts +0 -10
  126. package/dist/types/core/shared.d.ts.map +0 -1
  127. package/dist/types/core/tree/deserialize.d.ts.map +0 -1
  128. package/dist/types/core/tree/serialize.d.ts.map +0 -1
  129. package/src/core/cross/cross-parser.ts +0 -9
  130. package/src/core/parser-context.ts +0 -131
  131. package/src/core/serializer-context.new.ts +0 -1168
  132. package/src/core/tree/parser.ts +0 -45
  133. /package/dist/types/core/{assert.d.ts → utils/assert.d.ts} +0 -0
  134. /package/dist/types/core/{constructors.d.ts → utils/constructors.d.ts} +0 -0
  135. /package/dist/types/core/{get-identifier.d.ts → utils/get-identifier.d.ts} +0 -0
  136. /package/dist/types/core/{promise-to-result.d.ts → utils/promise-to-result.d.ts} +0 -0
  137. /package/src/core/{assert.ts → utils/assert.ts} +0 -0
  138. /package/src/core/{constructors.ts → utils/constructors.ts} +0 -0
  139. /package/src/core/{get-identifier.ts → utils/get-identifier.ts} +0 -0
  140. /package/src/core/{promise-to-result.ts → utils/promise-to-result.ts} +0 -0
@@ -1,27 +1,34 @@
1
- import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
2
- import UnsupportedTypeError from '../UnsupportedTypeError';
1
+ import type { BigIntTypedArrayValue, TypedArrayValue } from '../../../types';
2
+ import UnsupportedTypeError from '../../UnsupportedTypeError';
3
3
  import {
4
4
  createArrayBufferNode,
5
+ createAsyncIteratorFactoryInstanceNode,
5
6
  createDateNode,
7
+ createIteratorFactoryInstanceNode,
6
8
  createPluginNode,
7
9
  createRegExpNode,
8
- } from '../base-primitives';
10
+ createStringNode,
11
+ } from '../../base-primitives';
9
12
  import type { BaseSyncParserContextOptions } from './sync';
10
13
  import BaseSyncParserContext from './sync';
11
- import { BIGINT_FLAG, Feature } from '../compat';
12
- import { SerovalNodeType, UNIVERSAL_SENTINEL } from '../constants';
13
- import { createRequestOptions, createResponseOptions } from '../constructors';
14
- import { NULL_NODE } from '../literals';
15
- import { serializeString } from '../string';
14
+ import { BIGINT_FLAG, Feature } from '../../compat';
15
+ import { SerovalNodeType } from '../../constants';
16
+ import { createRequestOptions, createResponseOptions } from '../../utils/constructors';
17
+ import { FALSE_NODE, NULL_NODE, TRUE_NODE } from '../../literals';
18
+ import { serializeString } from '../../string';
16
19
  import type {
17
20
  SerovalNode,
21
+ SerovalObjectRecordKey,
22
+ SerovalObjectRecordNode,
18
23
  SerovalPluginNode,
19
24
  SerovalPromiseConstructorNode,
20
25
  SerovalReadableStreamConstructorNode,
21
26
  SerovalRequestNode,
22
27
  SerovalResponseNode,
23
- } from '../types';
24
- import { createDOMExceptionNode, createURLNode, createURLSearchParamsNode } from '../web-api';
28
+ } from '../../types';
29
+ import { createDOMExceptionNode, createURLNode, createURLSearchParamsNode } from '../../web-api';
30
+ import { asyncIteratorToReadableStream, iteratorToSequence } from '../../utils/iterator-to-sequence';
31
+ import { UNIVERSAL_SENTINEL } from '../../special-reference';
25
32
 
26
33
  export interface BaseStreamParserContextOptions extends BaseSyncParserContextOptions {
27
34
  onParse: (node: SerovalNode, initial: boolean) => void;
@@ -84,6 +91,71 @@ export default abstract class BaseStreamParserContext extends BaseSyncParserCont
84
91
  }
85
92
  }
86
93
 
94
+ protected parseProperties(
95
+ properties: Record<string | symbol, unknown>,
96
+ ): SerovalObjectRecordNode {
97
+ const entries = Object.entries(properties);
98
+ const keyNodes: SerovalObjectRecordKey[] = [];
99
+ const valueNodes: SerovalNode[] = [];
100
+ for (
101
+ let i = 0, len = entries.length;
102
+ i < len;
103
+ i++
104
+ ) {
105
+ keyNodes.push(serializeString(entries[i][0]));
106
+ valueNodes.push(this.parse(entries[i][1]));
107
+ }
108
+ // Check special properties, symbols in this case
109
+ if (this.features & Feature.Symbol) {
110
+ let symbol = Symbol.iterator;
111
+ if (symbol in properties) {
112
+ keyNodes.push(
113
+ this.parseWKSymbol(symbol),
114
+ );
115
+ valueNodes.push(
116
+ createIteratorFactoryInstanceNode(
117
+ this.parseIteratorFactory(),
118
+ this.parse(
119
+ iteratorToSequence(properties as unknown as Iterable<unknown>),
120
+ ),
121
+ ),
122
+ );
123
+ }
124
+ symbol = Symbol.asyncIterator;
125
+ if (symbol in properties) {
126
+ keyNodes.push(
127
+ this.parseWKSymbol(symbol),
128
+ );
129
+ valueNodes.push(
130
+ createAsyncIteratorFactoryInstanceNode(
131
+ this.parseAsyncIteratorFactory(),
132
+ this.parse(
133
+ asyncIteratorToReadableStream(
134
+ properties as unknown as AsyncIterable<unknown>,
135
+ this,
136
+ ),
137
+ ),
138
+ ),
139
+ );
140
+ }
141
+ symbol = Symbol.toStringTag;
142
+ if (symbol in properties) {
143
+ keyNodes.push(this.parseWKSymbol(symbol));
144
+ valueNodes.push(createStringNode(properties[symbol] as string));
145
+ }
146
+ symbol = Symbol.isConcatSpreadable;
147
+ if (symbol in properties) {
148
+ keyNodes.push(this.parseWKSymbol(symbol));
149
+ valueNodes.push(properties[symbol] ? TRUE_NODE : FALSE_NODE);
150
+ }
151
+ }
152
+ return {
153
+ k: keyNodes,
154
+ v: valueNodes,
155
+ s: keyNodes.length,
156
+ };
157
+ }
158
+
87
159
  private pushReadableStreamReader(
88
160
  id: number,
89
161
  reader: ReadableStreamDefaultReader,
@@ -450,7 +522,10 @@ export default abstract class BaseStreamParserContext extends BaseSyncParserCont
450
522
  }
451
523
  // Generator functions don't have a global constructor
452
524
  // despite existing
453
- if (currentFeatures & Feature.Symbol && Symbol.iterator in current) {
525
+ if (
526
+ currentFeatures & Feature.Symbol
527
+ && (Symbol.iterator in current || Symbol.asyncIterator in current)
528
+ ) {
454
529
  return this.parsePlainObject(id, current, !!currentClass);
455
530
  }
456
531
  throw new UnsupportedTypeError(current);
@@ -1,35 +1,44 @@
1
1
  /* eslint-disable prefer-destructuring */
2
- import type { BigIntTypedArrayValue, TypedArrayValue } from '../../types';
3
- import UnsupportedTypeError from '../UnsupportedTypeError';
4
- import assert from '../assert';
2
+ import type { BigIntTypedArrayValue, TypedArrayValue } from '../../../types';
3
+ import UnsupportedTypeError from '../../UnsupportedTypeError';
4
+ import assert from '../../utils/assert';
5
5
  import {
6
+ createAggregateErrorNode,
6
7
  createArrayBufferNode,
8
+ createArrayNode,
7
9
  createBigIntNode,
10
+ createBigIntTypedArrayNode,
11
+ createBoxedNode,
12
+ createDataViewNode,
8
13
  createDateNode,
14
+ createErrorNode,
15
+ createIteratorFactoryInstanceNode,
9
16
  createNumberNode,
10
17
  createPluginNode,
11
18
  createRegExpNode,
19
+ createSetNode,
12
20
  createStringNode,
21
+ createTypedArrayNode,
13
22
  createWKSymbolNode,
14
- } from '../base-primitives';
15
- import { BIGINT_FLAG, Feature } from '../compat';
16
- import type { WellKnownSymbols } from '../constants';
23
+ } from '../../base-primitives';
24
+ import { BIGINT_FLAG, Feature } from '../../compat';
25
+ import type { WellKnownSymbols } from '../../constants';
17
26
  import {
18
- SerovalNodeType, UNIVERSAL_SENTINEL,
19
- } from '../constants';
20
- import { createCustomEventOptions, createEventOptions } from '../constructors';
27
+ SerovalNodeType,
28
+ } from '../../constants';
29
+ import { createCustomEventOptions, createEventOptions } from '../../utils/constructors';
21
30
  import {
22
31
  FALSE_NODE,
23
32
  NULL_NODE,
24
33
  TRUE_NODE,
25
34
  UNDEFINED_NODE,
26
- } from '../literals';
27
- import type { BaseParserContextOptions } from '../parser-context';
28
- import { BaseParserContext } from '../parser-context';
29
- import { hasReferenceID } from '../reference';
30
- import { getErrorConstructor, getErrorOptions, getObjectFlag } from '../shared';
31
- import { serializeString } from '../string';
32
- import { SerovalObjectRecordSpecialKey } from '../types';
35
+ } from '../../literals';
36
+ import { iteratorToSequence } from '../../utils/iterator-to-sequence';
37
+ import type { BaseParserContextOptions } from '../parser';
38
+ import { BaseParserContext } from '../parser';
39
+ import { hasReferenceID } from '../../reference';
40
+ import { getErrorOptions } from '../../utils/error';
41
+ import { serializeString } from '../../string';
33
42
  import type {
34
43
  SerovalBoxedNode,
35
44
  SerovalArrayNode,
@@ -51,37 +60,30 @@ import type {
51
60
  SerovalTypedArrayNode,
52
61
  SerovalBigIntTypedArrayNode,
53
62
  SerovalDataViewNode,
54
- } from '../types';
55
- import { createDOMExceptionNode, createURLNode, createURLSearchParamsNode } from '../web-api';
63
+ } from '../../types';
64
+ import {
65
+ createCustomEventNode,
66
+ createDOMExceptionNode,
67
+ createEventNode,
68
+ createURLNode,
69
+ createURLSearchParamsNode,
70
+ } from '../../web-api';
71
+ import { UNIVERSAL_SENTINEL } from '../../special-reference';
56
72
 
57
73
  type ObjectLikeNode =
58
74
  | SerovalObjectNode
59
75
  | SerovalNullConstructorNode;
60
76
 
61
- export interface BaseSyncParserContextOptions extends BaseParserContextOptions {
62
- refs?: Map<unknown, number>;
63
- }
77
+ export type BaseSyncParserContextOptions = BaseParserContextOptions
64
78
 
65
79
  export default abstract class BaseSyncParserContext extends BaseParserContext {
66
80
  protected parseItems(
67
81
  current: unknown[],
68
82
  ): SerovalNode[] {
69
- const size = current.length;
70
83
  const nodes = [];
71
- const deferred = [];
72
- for (let i = 0, item: unknown; i < size; i++) {
84
+ for (let i = 0, len = current.length; i < len; i++) {
73
85
  if (i in current) {
74
- item = current[i];
75
- if (this.isIterable(item)) {
76
- deferred[i] = item;
77
- } else {
78
- nodes[i] = this.parse(item);
79
- }
80
- }
81
- }
82
- for (let i = 0; i < size; i++) {
83
- if (i in deferred) {
84
- nodes[i] = this.parse(deferred[i]);
86
+ nodes[i] = this.parse(current[i]);
85
87
  }
86
88
  }
87
89
  return nodes;
@@ -91,56 +93,52 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
91
93
  id: number,
92
94
  current: unknown[],
93
95
  ): SerovalArrayNode {
94
- return {
95
- t: SerovalNodeType.Array,
96
- i: id,
97
- s: undefined,
98
- l: current.length,
99
- c: undefined,
100
- m: undefined,
101
- p: undefined,
102
- e: undefined,
103
- a: this.parseItems(current),
104
- f: undefined,
105
- b: undefined,
106
- o: getObjectFlag(current),
107
- };
96
+ return createArrayNode(
97
+ id,
98
+ current,
99
+ this.parseItems(current),
100
+ );
108
101
  }
109
102
 
110
103
  protected parseProperties(
111
- properties: Record<string, unknown>,
104
+ properties: Record<string | symbol, unknown>,
112
105
  ): SerovalObjectRecordNode {
113
106
  const entries = Object.entries(properties);
114
107
  const keyNodes: SerovalObjectRecordKey[] = [];
115
108
  const valueNodes: SerovalNode[] = [];
116
- const deferredKeys: string[] = [];
117
- const deferredValues: unknown[] = [];
118
109
  for (
119
- let i = 0, len = entries.length, key: string, item: unknown;
110
+ let i = 0, len = entries.length;
120
111
  i < len;
121
112
  i++
122
113
  ) {
123
- key = serializeString(entries[i][0]);
124
- item = entries[i][1];
125
- // Defer iterables since iterables have lazy evaluation.
126
- // Of course this doesn't include types seroval supports.
127
- if (this.isIterable(item)) {
128
- deferredKeys.push(key);
129
- deferredValues.push(item);
130
- } else {
131
- keyNodes.push(key);
132
- valueNodes.push(this.parse(item));
133
- }
134
- }
135
- for (let i = 0, len = deferredKeys.length; i < len; i++) {
136
- keyNodes.push(deferredKeys[i]);
137
- valueNodes.push(this.parse(deferredValues[i]));
114
+ keyNodes.push(serializeString(entries[i][0]));
115
+ valueNodes.push(this.parse(entries[i][1]));
138
116
  }
139
117
  // Check special properties, symbols in this case
140
118
  if (this.features & Feature.Symbol) {
141
- if (Symbol.iterator in properties) {
142
- keyNodes.push(SerovalObjectRecordSpecialKey.SymbolIterator);
143
- valueNodes.push(this.parse(Array.from(properties as Iterable<unknown>)));
119
+ let symbol = Symbol.iterator;
120
+ if (symbol in properties) {
121
+ keyNodes.push(
122
+ this.parseWKSymbol(symbol),
123
+ );
124
+ valueNodes.push(
125
+ createIteratorFactoryInstanceNode(
126
+ this.parseIteratorFactory(),
127
+ this.parse(
128
+ iteratorToSequence(properties as unknown as Iterable<unknown>),
129
+ ),
130
+ ),
131
+ );
132
+ }
133
+ symbol = Symbol.toStringTag;
134
+ if (symbol in properties) {
135
+ keyNodes.push(this.parseWKSymbol(symbol));
136
+ valueNodes.push(createStringNode(properties[symbol] as string));
137
+ }
138
+ symbol = Symbol.isConcatSpreadable;
139
+ if (symbol in properties) {
140
+ keyNodes.push(this.parseWKSymbol(symbol));
141
+ valueNodes.push(properties[symbol] ? TRUE_NODE : FALSE_NODE);
144
142
  }
145
143
  }
146
144
  return {
@@ -155,100 +153,40 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
155
153
  current: Record<string, unknown>,
156
154
  empty: boolean,
157
155
  ): ObjectLikeNode {
158
- return {
159
- t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
160
- i: id,
161
- s: undefined,
162
- l: undefined,
163
- c: undefined,
164
- m: undefined,
165
- p: this.parseProperties(current),
166
- e: undefined,
167
- a: undefined,
168
- f: undefined,
169
- b: undefined,
170
- o: getObjectFlag(current),
171
- };
156
+ return this.createObjectNode(
157
+ id,
158
+ current,
159
+ empty,
160
+ this.parseProperties(current),
161
+ );
172
162
  }
173
163
 
174
164
  protected parseBoxed(
175
165
  id: number,
176
166
  current: object,
177
167
  ): SerovalBoxedNode {
178
- return {
179
- t: SerovalNodeType.Boxed,
180
- i: id,
181
- s: undefined,
182
- l: undefined,
183
- c: undefined,
184
- m: undefined,
185
- p: undefined,
186
- e: undefined,
187
- a: undefined,
188
- f: this.parse(current.valueOf()),
189
- b: undefined,
190
- o: undefined,
191
- };
168
+ return createBoxedNode(id, this.parse(current.valueOf()));
192
169
  }
193
170
 
194
171
  protected parseTypedArray(
195
172
  id: number,
196
173
  current: TypedArrayValue,
197
174
  ): SerovalTypedArrayNode {
198
- return {
199
- t: SerovalNodeType.TypedArray,
200
- i: id,
201
- s: undefined,
202
- l: current.length,
203
- c: current.constructor.name,
204
- m: undefined,
205
- p: undefined,
206
- e: undefined,
207
- a: undefined,
208
- f: this.parse(current.buffer),
209
- b: current.byteOffset,
210
- o: undefined,
211
- };
175
+ return createTypedArrayNode(id, current, this.parse(current.buffer));
212
176
  }
213
177
 
214
178
  protected parseBigIntTypedArray(
215
179
  id: number,
216
180
  current: BigIntTypedArrayValue,
217
181
  ): SerovalBigIntTypedArrayNode {
218
- return {
219
- t: SerovalNodeType.BigIntTypedArray,
220
- i: id,
221
- s: undefined,
222
- l: current.length,
223
- c: current.constructor.name,
224
- m: undefined,
225
- p: undefined,
226
- e: undefined,
227
- a: undefined,
228
- f: this.parse(current.buffer),
229
- b: current.byteOffset,
230
- o: undefined,
231
- };
182
+ return createBigIntTypedArrayNode(id, current, this.parse(current.buffer));
232
183
  }
233
184
 
234
185
  protected parseDataView(
235
186
  id: number,
236
187
  current: DataView,
237
188
  ): SerovalDataViewNode {
238
- return {
239
- t: SerovalNodeType.DataView,
240
- i: id,
241
- s: undefined,
242
- l: current.byteLength,
243
- c: undefined,
244
- m: undefined,
245
- p: undefined,
246
- e: undefined,
247
- a: undefined,
248
- f: this.parse(current.buffer),
249
- b: current.byteOffset,
250
- o: undefined,
251
- };
189
+ return createDataViewNode(id, current, this.parse(current.buffer));
252
190
  }
253
191
 
254
192
  protected parseError(
@@ -256,23 +194,27 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
256
194
  current: Error,
257
195
  ): SerovalErrorNode {
258
196
  const options = getErrorOptions(current, this.features);
259
- const optionsNode = options
260
- ? this.parseProperties(options)
261
- : undefined;
262
- return {
263
- t: SerovalNodeType.Error,
264
- i: id,
265
- s: getErrorConstructor(current),
266
- l: undefined,
267
- c: undefined,
268
- m: serializeString(current.message),
269
- p: optionsNode,
270
- e: undefined,
271
- a: undefined,
272
- f: undefined,
273
- b: undefined,
274
- o: undefined,
275
- };
197
+ return createErrorNode(
198
+ id,
199
+ current,
200
+ options
201
+ ? this.parseProperties(options)
202
+ : undefined,
203
+ );
204
+ }
205
+
206
+ protected parseAggregateError(
207
+ id: number,
208
+ current: AggregateError,
209
+ ): SerovalAggregateErrorNode {
210
+ const options = getErrorOptions(current, this.features);
211
+ return createAggregateErrorNode(
212
+ id,
213
+ current,
214
+ options
215
+ ? this.parseProperties(options)
216
+ : undefined,
217
+ );
276
218
  }
277
219
 
278
220
  protected parseMap(
@@ -281,70 +223,27 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
281
223
  ): SerovalMapNode {
282
224
  const keyNodes: SerovalNode[] = [];
283
225
  const valueNodes: SerovalNode[] = [];
284
- const deferredKey: unknown[] = [];
285
- const deferredValue: unknown[] = [];
286
226
  for (const [key, value] of current.entries()) {
287
- // Either key or value might be an iterable
288
- if (this.isIterable(key) || this.isIterable(value)) {
289
- deferredKey.push(key);
290
- deferredValue.push(value);
291
- } else {
292
- keyNodes.push(this.parse(key));
293
- valueNodes.push(this.parse(value));
294
- }
227
+ keyNodes.push(this.parse(key));
228
+ valueNodes.push(this.parse(value));
295
229
  }
296
- for (let i = 0, len = deferredKey.length; i < len; i++) {
297
- keyNodes.push(this.parse(deferredKey[i]));
298
- valueNodes.push(this.parse(deferredValue[i]));
299
- }
300
- return {
301
- t: SerovalNodeType.Map,
302
- i: id,
303
- s: undefined,
304
- l: undefined,
305
- c: undefined,
306
- m: undefined,
307
- p: undefined,
308
- e: { k: keyNodes, v: valueNodes, s: current.size },
309
- a: undefined,
310
- f: undefined,
311
- b: undefined,
312
- o: undefined,
313
- };
230
+ return this.createMapNode(
231
+ id,
232
+ keyNodes,
233
+ valueNodes,
234
+ current.size,
235
+ );
314
236
  }
315
237
 
316
238
  protected parseSet(
317
239
  id: number,
318
240
  current: Set<unknown>,
319
241
  ): SerovalSetNode {
320
- const nodes: SerovalNode[] = [];
321
- const deferred: unknown[] = [];
242
+ const items: SerovalNode[] = [];
322
243
  for (const item of current.keys()) {
323
- // Iterables are lazy, so the evaluation must be deferred
324
- if (this.isIterable(item)) {
325
- deferred.push(item);
326
- } else {
327
- nodes.push(this.parse(item));
328
- }
244
+ items.push(this.parse(item));
329
245
  }
330
- // Parse deferred items
331
- for (let i = 0, len = deferred.length; i < len; i++) {
332
- nodes.push(this.parse(deferred[i]));
333
- }
334
- return {
335
- t: SerovalNodeType.Set,
336
- i: id,
337
- s: undefined,
338
- l: current.size,
339
- c: undefined,
340
- m: undefined,
341
- p: undefined,
342
- e: undefined,
343
- a: nodes,
344
- f: undefined,
345
- b: undefined,
346
- o: undefined,
347
- };
246
+ return createSetNode(id, current.size, items);
348
247
  }
349
248
 
350
249
  protected parsePlainProperties(
@@ -353,22 +252,9 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
353
252
  const size = entries.length;
354
253
  const keyNodes: string[] = [];
355
254
  const valueNodes: SerovalNode[] = [];
356
- const deferredKeys: string[] = [];
357
- const deferredValues: unknown[] = [];
358
- for (let i = 0, key: string, item: unknown; i < size; i++) {
359
- key = serializeString(entries[i][0]);
360
- item = entries[i][1];
361
- if (this.isIterable(item)) {
362
- deferredKeys.push(key);
363
- deferredValues.push(item);
364
- } else {
365
- keyNodes.push(key);
366
- valueNodes.push(this.parse(item));
367
- }
368
- }
369
- for (let i = 0, len = deferredKeys.length; i < len; i++) {
370
- keyNodes.push(deferredKeys[i]);
371
- valueNodes.push(this.parse(deferredValues[i]));
255
+ for (let i = 0; i < size; i++) {
256
+ keyNodes.push(serializeString(entries[i][0]));
257
+ valueNodes.push(this.parse(entries[i][1]));
372
258
  }
373
259
  return {
374
260
  k: keyNodes,
@@ -429,64 +315,14 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
429
315
  id: number,
430
316
  current: Event,
431
317
  ): SerovalEventNode {
432
- return {
433
- t: SerovalNodeType.Event,
434
- i: id,
435
- s: serializeString(current.type),
436
- l: undefined,
437
- c: undefined,
438
- m: undefined,
439
- p: undefined,
440
- e: undefined,
441
- a: undefined,
442
- f: this.parse(createEventOptions(current)),
443
- b: undefined,
444
- o: undefined,
445
- };
318
+ return createEventNode(id, current.type, this.parse(createEventOptions(current)));
446
319
  }
447
320
 
448
321
  protected parseCustomEvent(
449
322
  id: number,
450
323
  current: CustomEvent,
451
324
  ): SerovalCustomEventNode {
452
- return {
453
- t: SerovalNodeType.CustomEvent,
454
- i: id,
455
- s: serializeString(current.type),
456
- l: undefined,
457
- c: undefined,
458
- m: undefined,
459
- p: undefined,
460
- e: undefined,
461
- a: undefined,
462
- f: this.parse(createCustomEventOptions(current)),
463
- b: undefined,
464
- o: undefined,
465
- };
466
- }
467
-
468
- protected parseAggregateError(
469
- id: number,
470
- current: AggregateError,
471
- ): SerovalAggregateErrorNode {
472
- const options = getErrorOptions(current, this.features);
473
- const optionsNode = options
474
- ? this.parseProperties(options)
475
- : undefined;
476
- return {
477
- t: SerovalNodeType.AggregateError,
478
- i: id,
479
- s: undefined,
480
- l: undefined,
481
- c: undefined,
482
- m: serializeString(current.message),
483
- p: optionsNode,
484
- e: undefined,
485
- a: undefined,
486
- f: undefined,
487
- b: undefined,
488
- o: undefined,
489
- };
325
+ return createCustomEventNode(id, current.type, this.parse(createCustomEventOptions(current)));
490
326
  }
491
327
 
492
328
  protected parsePlugin(
@@ -636,7 +472,10 @@ export default abstract class BaseSyncParserContext extends BaseParserContext {
636
472
  }
637
473
  // Generator functions don't have a global constructor
638
474
  // despite existing
639
- if (currentFeatures & Feature.Symbol && Symbol.iterator in current) {
475
+ if (
476
+ currentFeatures & Feature.Symbol
477
+ && Symbol.iterator in current
478
+ ) {
640
479
  return this.parsePlainObject(id, current, !!currentClass);
641
480
  }
642
481
  throw new UnsupportedTypeError(current);