seroval 0.4.0-alpha.13 → 0.4.0-alpha.14

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.
@@ -1,13 +1,7 @@
1
- import { SerializationContext } from '../context';
2
1
  import {
3
2
  AsyncServerValue,
4
3
  ErrorValue,
5
4
  } from '../types';
6
- import {
7
- SerovalNode,
8
- SerovalReferenceNode,
9
- SerovalNodeType,
10
- } from './types';
11
5
 
12
6
  export function getErrorConstructor(error: ErrorValue) {
13
7
  if (error instanceof EvalError) {
@@ -66,13 +60,6 @@ export function getIterableOptions(obj: Iterable<any>) {
66
60
  return undefined;
67
61
  }
68
62
 
69
- export function isReferenceInStack(
70
- ctx: SerializationContext,
71
- node: SerovalNode,
72
- ): node is SerovalReferenceNode {
73
- return node.t === SerovalNodeType.Reference && ctx.stack.includes(node.i);
74
- }
75
-
76
63
  export function isIterable(
77
64
  value: unknown,
78
65
  ): value is Iterable<AsyncServerValue> {
package/src/tree/sync.ts CHANGED
@@ -5,9 +5,14 @@ import { createRef, ParserContext } from '../context';
5
5
  import quote from '../quote';
6
6
  import { BigIntTypedArrayValue, ServerValue, TypedArrayValue } from '../types';
7
7
  import {
8
+ createBigIntNode,
9
+ createBigIntTypedArrayNode,
10
+ createDateNode,
11
+ createPrimitiveNode,
12
+ createReferenceNode,
13
+ createRegExpNode,
14
+ createTypedArrayNode,
8
15
  FALSE_NODE,
9
- INFINITY_NODE,
10
- NEG_INFINITY_NODE,
11
16
  NEG_ZERO_NODE,
12
17
  NULL_NODE,
13
18
  TRUE_NODE,
@@ -22,23 +27,15 @@ import {
22
27
  import {
23
28
  SerovalAggregateErrorNode,
24
29
  SerovalArrayNode,
25
- SerovalBigIntNode,
26
- SerovalBigIntTypedArrayNode,
27
- SerovalDateNode,
28
30
  SerovalErrorNode,
29
31
  SerovalIterableNode,
30
32
  SerovalMapNode,
31
- SerovalMapRecordNode,
32
33
  SerovalNode,
33
34
  SerovalNodeType,
34
35
  SerovalNullConstructorNode,
35
36
  SerovalObjectNode,
36
37
  SerovalObjectRecordNode,
37
- SerovalPrimitiveNode,
38
- SerovalReferenceNode,
39
- SerovalRegExpNode,
40
38
  SerovalSetNode,
41
- SerovalTypedArrayNode,
42
39
  } from './types';
43
40
 
44
41
  type ObjectLikeNode = SerovalObjectNode | SerovalNullConstructorNode | SerovalIterableNode;
@@ -74,7 +71,17 @@ class SyncParser {
74
71
  }
75
72
 
76
73
  generateArrayNode(id: number, current: ServerValue[]): SerovalArrayNode {
77
- return new SerovalArrayNode(id, this.generateNodeList(current));
74
+ return {
75
+ t: SerovalNodeType.Array,
76
+ i: id,
77
+ s: undefined,
78
+ l: undefined,
79
+ c: undefined,
80
+ m: undefined,
81
+ d: undefined,
82
+ a: this.generateNodeList(current),
83
+ n: undefined,
84
+ };
78
85
  }
79
86
 
80
87
  generateMapNode(
@@ -105,7 +112,17 @@ class SyncParser {
105
112
  keyNodes[nodeSize + i] = this.parse(deferredKey[i]);
106
113
  valueNodes[nodeSize + i] = this.parse(deferredValue[i]);
107
114
  }
108
- return new SerovalMapNode(id, new SerovalMapRecordNode(keyNodes, valueNodes, len));
115
+ return {
116
+ t: SerovalNodeType.Map,
117
+ i: id,
118
+ s: undefined,
119
+ l: undefined,
120
+ c: undefined,
121
+ m: undefined,
122
+ d: { k: keyNodes, v: valueNodes, s: len },
123
+ a: undefined,
124
+ n: undefined,
125
+ };
109
126
  }
110
127
 
111
128
  generateSetNode(
@@ -130,7 +147,17 @@ class SyncParser {
130
147
  for (let i = 0; i < deferredSize; i++) {
131
148
  nodes[nodeSize + i] = this.parse(deferred[i]);
132
149
  }
133
- return new SerovalSetNode(id, nodes);
150
+ return {
151
+ t: SerovalNodeType.Set,
152
+ i: id,
153
+ s: undefined,
154
+ l: undefined,
155
+ c: undefined,
156
+ m: undefined,
157
+ d: undefined,
158
+ a: nodes,
159
+ n: undefined,
160
+ };
134
161
  }
135
162
 
136
163
  generateProperties(properties: Record<string, ServerValue>): SerovalObjectRecordNode {
@@ -172,14 +199,20 @@ class SyncParser {
172
199
  ): SerovalIterableNode {
173
200
  assert(this.ctx.features & Feature.SymbolIterator, 'Unsupported type "Iterable"');
174
201
  const options = getIterableOptions(current);
175
- return new SerovalIterableNode(
176
- id,
202
+ return {
203
+ t: SerovalNodeType.Iterable,
204
+ i: id,
205
+ s: undefined,
206
+ l: undefined,
207
+ c: undefined,
208
+ m: undefined,
177
209
  // Parse options first before the items
178
- options
210
+ d: options
179
211
  ? this.generateProperties(options as Record<string, ServerValue>)
180
212
  : undefined,
181
- this.generateNodeList(Array.from(current)),
182
- );
213
+ a: this.generateNodeList(Array.from(current)),
214
+ n: undefined,
215
+ };
183
216
  }
184
217
 
185
218
  generateObjectNode(
@@ -190,10 +223,17 @@ class SyncParser {
190
223
  if (Symbol.iterator in current) {
191
224
  return this.generateIterableNode(id, current);
192
225
  }
193
- if (empty) {
194
- return new SerovalNullConstructorNode(id, this.generateProperties(current));
195
- }
196
- return new SerovalObjectNode(id, this.generateProperties(current));
226
+ return {
227
+ t: empty ? SerovalNodeType.NullConstructor : SerovalNodeType.Object,
228
+ i: id,
229
+ s: undefined,
230
+ l: undefined,
231
+ c: undefined,
232
+ m: undefined,
233
+ d: this.generateProperties(current),
234
+ a: undefined,
235
+ n: undefined,
236
+ };
197
237
  }
198
238
 
199
239
  generateAggregateErrorNode(
@@ -204,12 +244,17 @@ class SyncParser {
204
244
  const optionsNode = options
205
245
  ? this.generateProperties(options)
206
246
  : undefined;
207
- return new SerovalAggregateErrorNode(
208
- id,
209
- current.message,
210
- optionsNode,
211
- this.parse(current.errors),
212
- );
247
+ return {
248
+ t: SerovalNodeType.AggregateError,
249
+ i: id,
250
+ s: undefined,
251
+ l: undefined,
252
+ c: undefined,
253
+ m: current.message,
254
+ d: optionsNode,
255
+ a: undefined,
256
+ n: this.parse(current.errors),
257
+ };
213
258
  }
214
259
 
215
260
  generateErrorNode(
@@ -220,7 +265,17 @@ class SyncParser {
220
265
  const optionsNode = options
221
266
  ? this.generateProperties(options)
222
267
  : undefined;
223
- return new SerovalErrorNode(id, getErrorConstructor(current), current.message, optionsNode);
268
+ return {
269
+ t: SerovalNodeType.Error,
270
+ i: id,
271
+ s: undefined,
272
+ l: undefined,
273
+ c: getErrorConstructor(current),
274
+ m: current.message,
275
+ d: optionsNode,
276
+ a: undefined,
277
+ n: undefined,
278
+ };
224
279
  }
225
280
 
226
281
  parse(current: ServerValue): SerovalNode {
@@ -230,21 +285,20 @@ class SyncParser {
230
285
  case 'undefined':
231
286
  return UNDEFINED_NODE;
232
287
  case 'string':
233
- return new SerovalPrimitiveNode(quote(current));
288
+ return createPrimitiveNode(quote(current));
234
289
  case 'number':
235
290
  if (Object.is(current, -0)) {
236
291
  return NEG_ZERO_NODE;
237
292
  }
238
293
  if (Object.is(current, Infinity)) {
239
- return INFINITY_NODE;
294
+ return createPrimitiveNode('1/0');
240
295
  }
241
296
  if (Object.is(current, -Infinity)) {
242
- return NEG_INFINITY_NODE;
297
+ return createPrimitiveNode('-1/0');
243
298
  }
244
- return new SerovalPrimitiveNode(current);
299
+ return createPrimitiveNode(current);
245
300
  case 'bigint':
246
- assert(this.ctx.features & Feature.BigInt, 'Unsupported type "BigInt"');
247
- return new SerovalBigIntNode(current);
301
+ return createBigIntNode(this.ctx, current);
248
302
  case 'object': {
249
303
  if (!current) {
250
304
  return NULL_NODE;
@@ -252,17 +306,17 @@ class SyncParser {
252
306
  // Non-primitive values needs a reference ID
253
307
  // mostly because the values themselves are stateful
254
308
  const id = createRef(this.ctx, current, true);
255
- if (this.ctx.markedRefs[id]) {
256
- return new SerovalReferenceNode(id);
309
+ if (this.ctx.markedRefs.has(id)) {
310
+ return createReferenceNode(id);
257
311
  }
258
312
  if (Array.isArray(current)) {
259
313
  return this.generateArrayNode(id, current);
260
314
  }
261
315
  switch (current.constructor) {
262
316
  case Date:
263
- return new SerovalDateNode(id, current as Date);
317
+ return createDateNode(id, current as Date);
264
318
  case RegExp:
265
- return new SerovalRegExpNode(id, current as RegExp);
319
+ return createRegExpNode(id, current as RegExp);
266
320
  case Int8Array:
267
321
  case Int16Array:
268
322
  case Int32Array:
@@ -272,15 +326,10 @@ class SyncParser {
272
326
  case Uint8ClampedArray:
273
327
  case Float32Array:
274
328
  case Float64Array:
275
- assert(this.ctx.features & Feature.TypedArray, `Unsupported value type "${current.constructor.name}"`);
276
- return new SerovalTypedArrayNode(id, current as TypedArrayValue);
329
+ return createTypedArrayNode(this.ctx, id, current as TypedArrayValue);
277
330
  case BigInt64Array:
278
331
  case BigUint64Array:
279
- assert(
280
- this.ctx.features & (Feature.BigIntTypedArray),
281
- `Unsupported value type "${current.constructor.name}"`,
282
- );
283
- return new SerovalBigIntTypedArrayNode(id, current as BigIntTypedArrayValue);
332
+ return createBigIntTypedArrayNode(this.ctx, id, current as BigIntTypedArrayValue);
284
333
  case Map:
285
334
  return this.generateMapNode(id, current as Map<ServerValue, ServerValue>);
286
335
  case Set:
package/src/tree/types.ts CHANGED
@@ -1,5 +1,4 @@
1
- /* eslint-disable max-classes-per-file */
2
- import { BigIntTypedArrayValue, PrimitiveValue, TypedArrayValue } from '../types';
1
+ import { PrimitiveValue } from '../types';
3
2
 
4
3
  export const enum SerovalNodeType {
5
4
  Primitive,
@@ -22,156 +21,81 @@ export const enum SerovalNodeType {
22
21
 
23
22
  export interface SerovalBaseNode {
24
23
  // Type of the node
25
- t?: SerovalNodeType;
24
+ t: SerovalNodeType;
26
25
  // Serialized value
27
- s?: PrimitiveValue;
26
+ s: PrimitiveValue | undefined;
28
27
  // Reference ID
29
- i?: number;
28
+ i: number | undefined;
30
29
  // Size/Byte offset
31
- l?: number;
30
+ l: number | undefined;
32
31
  // Constructor name
33
- c?: string;
32
+ c: string | undefined;
34
33
  // dictionary
35
- d?: SerovalDictionaryNode;
34
+ d: SerovalDictionaryNode | undefined;
36
35
  // message
37
- m?: string;
36
+ m: string | undefined;
38
37
  // next node
39
- n?: SerovalNode;
38
+ n: SerovalNode | undefined;
40
39
  // array of nodes
41
- a?: SerovalNode[];
40
+ a: SerovalNode[] | undefined;
42
41
  }
43
42
 
44
- export class SerovalObjectRecordNode {
43
+ export interface SerovalObjectRecordNode {
45
44
  k: string[];
46
-
47
45
  v: SerovalNode[];
48
-
49
46
  s: number;
50
-
51
- constructor(k: string[], v: SerovalNode[], s: number) {
52
- this.k = k;
53
- this.v = v;
54
- this.s = s;
55
- }
56
47
  }
57
48
 
58
- export class SerovalMapRecordNode {
49
+ export interface SerovalMapRecordNode {
59
50
  k: SerovalNode[];
60
-
61
51
  v: SerovalNode[];
62
-
63
52
  s: number;
64
-
65
- constructor(k: SerovalNode[], v: SerovalNode[], s: number) {
66
- this.k = k;
67
- this.v = v;
68
- this.s = s;
69
- }
70
53
  }
71
54
 
72
55
  export type SerovalDictionaryNode =
73
56
  | SerovalObjectRecordNode
74
57
  | SerovalMapRecordNode;
75
58
 
76
- export class SerovalPrimitiveNode implements SerovalBaseNode {
77
- t: SerovalNodeType.Primitive = SerovalNodeType.Primitive;
78
-
79
- s: string | number | null;
80
-
81
- constructor(current: string | number | null) {
82
- this.s = current;
83
- }
59
+ export interface SerovalPrimitiveNode extends SerovalBaseNode {
60
+ t: SerovalNodeType.Primitive;
84
61
  }
85
62
 
86
- export class SerovalReferenceNode implements SerovalBaseNode {
87
- t: SerovalNodeType.Reference = SerovalNodeType.Reference;
88
-
63
+ export interface SerovalReferenceNode extends SerovalBaseNode {
64
+ t: SerovalNodeType.Reference;
89
65
  i: number;
90
-
91
- constructor(id: number) {
92
- this.i = id;
93
- }
94
66
  }
95
67
 
96
- export class SerovalBigIntNode implements SerovalBaseNode {
97
- t: SerovalNodeType.BigInt = SerovalNodeType.BigInt;
98
-
68
+ export interface SerovalBigIntNode extends SerovalBaseNode {
69
+ t: SerovalNodeType.BigInt;
99
70
  s: string;
100
-
101
- constructor(current: bigint) {
102
- this.s = `${current}n`;
103
- }
104
71
  }
105
72
 
106
- export class SerovalDateNode implements SerovalBaseNode {
107
- t: SerovalNodeType.Date = SerovalNodeType.Date;
108
-
73
+ export interface SerovalDateNode extends SerovalBaseNode {
74
+ t: SerovalNodeType.Date;
109
75
  i: number;
110
-
111
76
  s: string;
112
-
113
- constructor(id: number, current: Date) {
114
- this.i = id;
115
- this.s = current.toISOString();
116
- }
117
77
  }
118
78
 
119
- export class SerovalRegExpNode implements SerovalBaseNode {
120
- t: SerovalNodeType.RegExp = SerovalNodeType.RegExp;
121
-
79
+ export interface SerovalRegExpNode extends SerovalBaseNode {
80
+ t: SerovalNodeType.RegExp;
122
81
  i: number;
123
-
124
82
  s: string;
125
-
126
- constructor(id: number, current: RegExp) {
127
- this.i = id;
128
- this.s = String(current);
129
- }
130
83
  }
131
84
 
132
- export class SerovalTypedArrayNode implements SerovalBaseNode {
133
- t: SerovalNodeType.TypedArray = SerovalNodeType.TypedArray;
134
-
85
+ export interface SerovalTypedArrayNode extends SerovalBaseNode {
86
+ t: SerovalNodeType.TypedArray;
135
87
  i: number;
136
-
137
88
  s: string;
138
-
139
89
  l: number;
140
-
141
90
  c: string;
142
-
143
- constructor(id: number, current: TypedArrayValue) {
144
- this.i = id;
145
- this.s = current.toString();
146
- this.l = current.byteOffset;
147
- this.c = current.constructor.name;
148
- }
149
91
  }
150
92
 
151
- export class SerovalBigIntTypedArrayNode implements SerovalBaseNode {
152
- t: SerovalNodeType.BigIntTypedArray = SerovalNodeType.BigIntTypedArray;
153
-
93
+ export interface SerovalBigIntTypedArrayNode extends SerovalBaseNode {
94
+ t: SerovalNodeType.BigIntTypedArray;
154
95
  i: number;
155
-
156
96
  s: string;
157
-
158
97
  l: number;
159
-
160
98
  c: string;
161
-
162
- constructor(id: number, current: BigIntTypedArrayValue) {
163
- let result = '';
164
- const cap = current.length - 1;
165
- for (let i = 0; i < cap; i++) {
166
- result += `${current[i]}n,`;
167
- }
168
- result += `"${current[cap]}"`;
169
-
170
- this.i = id;
171
- this.s = result;
172
- this.l = current.byteOffset;
173
- this.c = current.constructor.name;
174
- }
175
99
  }
176
100
 
177
101
  export type SerovalSemiPrimitiveNode =
@@ -181,136 +105,63 @@ export type SerovalSemiPrimitiveNode =
181
105
  | SerovalTypedArrayNode
182
106
  | SerovalBigIntTypedArrayNode;
183
107
 
184
- export class SerovalSetNode implements SerovalBaseNode {
185
- t: SerovalNodeType.Set = SerovalNodeType.Set;
186
-
187
- i: number;
188
-
108
+ export interface SerovalSetNode extends SerovalBaseNode {
109
+ t: SerovalNodeType.Set;
189
110
  a: SerovalNode[];
190
-
191
- constructor(id: number, a: SerovalNode[]) {
192
- this.i = id;
193
- this.a = a;
194
- }
195
- }
196
-
197
- export class SerovalMapNode implements SerovalBaseNode {
198
- t: SerovalNodeType.Map = SerovalNodeType.Map;
199
-
200
111
  i: number;
201
-
202
- d: SerovalMapRecordNode;
203
-
204
- constructor(id: number, d: SerovalMapRecordNode) {
205
- this.i = id;
206
- this.d = d;
207
- }
208
112
  }
209
113
 
210
- export class SerovalArrayNode implements SerovalBaseNode {
211
- t: SerovalNodeType.Array = SerovalNodeType.Array;
212
-
114
+ export interface SerovalMapNode extends SerovalBaseNode {
115
+ t: SerovalNodeType.Map;
116
+ d: SerovalMapRecordNode;
213
117
  i: number;
214
-
215
- a: SerovalNode[];
216
-
217
- constructor(id: number, a: SerovalNode[]) {
218
- this.i = id;
219
- this.a = a;
220
- }
221
118
  }
222
119
 
223
- export class SerovalObjectNode implements SerovalBaseNode {
224
- t: SerovalNodeType.Object = SerovalNodeType.Object;
225
-
120
+ export interface SerovalArrayNode extends SerovalBaseNode {
121
+ t: SerovalNodeType.Array;
122
+ a: SerovalNode[];
226
123
  i: number;
227
-
228
- d: SerovalObjectRecordNode;
229
-
230
- constructor(id: number, d: SerovalObjectRecordNode) {
231
- this.i = id;
232
- this.d = d;
233
- }
234
124
  }
235
125
 
236
- export class SerovalNullConstructorNode implements SerovalBaseNode {
237
- t: SerovalNodeType.NullConstructor = SerovalNodeType.NullConstructor;
238
-
239
- i: number;
240
-
126
+ export interface SerovalObjectNode extends SerovalBaseNode {
127
+ t: SerovalNodeType.Object;
241
128
  d: SerovalObjectRecordNode;
242
-
243
- constructor(id: number, d: SerovalObjectRecordNode) {
244
- this.i = id;
245
- this.d = d;
246
- }
129
+ i: number;
247
130
  }
248
131
 
249
- export class SerovalPromiseNode implements SerovalBaseNode {
250
- t: SerovalNodeType.Promise = SerovalNodeType.Promise;
251
-
132
+ export interface SerovalNullConstructorNode extends SerovalBaseNode {
133
+ t: SerovalNodeType.NullConstructor;
134
+ d: SerovalObjectRecordNode;
252
135
  i: number;
253
-
254
- n: SerovalNode;
255
-
256
- constructor(id: number, n: SerovalNode) {
257
- this.i = id;
258
- this.n = n;
259
- }
260
136
  }
261
137
 
262
- export class SerovalErrorNode implements SerovalBaseNode {
263
- t: SerovalNodeType.Error = SerovalNodeType.Error;
264
-
138
+ export interface SerovalPromiseNode extends SerovalBaseNode {
139
+ t: SerovalNodeType.Promise;
140
+ n: SerovalNode;
265
141
  i: number;
142
+ }
266
143
 
144
+ export interface SerovalErrorNode extends SerovalBaseNode {
145
+ t: SerovalNodeType.Error;
267
146
  c: string;
268
-
269
147
  m: string;
270
-
271
148
  d: SerovalObjectRecordNode | undefined;
272
-
273
- constructor(id: number, c: string, m: string, d: SerovalObjectRecordNode | undefined) {
274
- this.i = id;
275
- this.c = c;
276
- this.m = m;
277
- this.d = d;
278
- }
279
- }
280
-
281
- export class SerovalAggregateErrorNode implements SerovalBaseNode {
282
- t: SerovalNodeType.AggregateError = SerovalNodeType.AggregateError;
283
-
284
149
  i: number;
150
+ }
285
151
 
152
+ export interface SerovalAggregateErrorNode extends SerovalBaseNode {
153
+ t: SerovalNodeType.AggregateError;
286
154
  m: string;
287
-
288
155
  d: SerovalObjectRecordNode | undefined;
289
-
290
156
  n: SerovalNode;
291
-
292
- constructor(id: number, m: string, d: SerovalObjectRecordNode | undefined, n: SerovalNode) {
293
- this.i = id;
294
- this.m = m;
295
- this.d = d;
296
- this.n = n;
297
- }
298
- }
299
-
300
- export class SerovalIterableNode implements SerovalBaseNode {
301
- t: SerovalNodeType.Iterable = SerovalNodeType.Iterable;
302
-
303
157
  i: number;
158
+ }
304
159
 
160
+ export interface SerovalIterableNode extends SerovalBaseNode {
161
+ t: SerovalNodeType.Iterable;
305
162
  d: SerovalObjectRecordNode | undefined;
306
-
307
163
  a: SerovalNode[];
308
-
309
- constructor(id: number, d: SerovalObjectRecordNode | undefined, a: SerovalNode[]) {
310
- this.i = id;
311
- this.d = d;
312
- this.a = a;
313
- }
164
+ i: number;
314
165
  }
315
166
 
316
167
  export type SerovalNode =