seroval 0.3.0 → 0.4.0-alpha.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.
@@ -61,38 +61,6 @@ function quote(str) {
61
61
  return `"${result}"`;
62
62
  }
63
63
 
64
- // src/serialize-primitive.ts
65
- function serializePrimitive(value) {
66
- if (value === true) {
67
- return "!0";
68
- }
69
- if (value === false) {
70
- return "!1";
71
- }
72
- if (value === void 0) {
73
- return "void 0";
74
- }
75
- if (value === null) {
76
- return "null";
77
- }
78
- if (typeof value === "bigint") {
79
- return `${value}n`;
80
- }
81
- if (typeof value === "string") {
82
- return quote(value);
83
- }
84
- if (Object.is(value, -0)) {
85
- return "-0";
86
- }
87
- if (Object.is(value, Infinity)) {
88
- return "1/0";
89
- }
90
- if (Object.is(value, -Infinity)) {
91
- return "-1/0";
92
- }
93
- return String(value);
94
- }
95
-
96
64
  // src/get-identifier.ts
97
65
  var REF_START_CHARS = "hjkmoquxzABCDEFGHIJKLNPQRTUVWXYZ$_";
98
66
  var REF_START_CHARS_LEN = REF_START_CHARS.length;
@@ -110,15 +78,221 @@ function getIdentifier(index) {
110
78
  return ref;
111
79
  }
112
80
 
81
+ // src/assert.ts
82
+ function assert(cond, error) {
83
+ if (!cond) {
84
+ throw new Error(error);
85
+ }
86
+ }
87
+
88
+ // src/compat.ts
89
+ function compareVersion(left, right) {
90
+ let diff = left[0] - right[0];
91
+ if (diff === 0) {
92
+ diff = left[1] - right[1];
93
+ }
94
+ if (diff === 0) {
95
+ diff = left[2] - right[2];
96
+ }
97
+ return diff;
98
+ }
99
+ var VERSION_TABLE = {
100
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError#browser_compatibility
101
+ "aggregate-error": {
102
+ es: [2021, 0, 0],
103
+ chrome: [85, 0, 0],
104
+ edge: [85, 0, 0],
105
+ firefox: [79, 0, 0],
106
+ opera: [71, 0, 0],
107
+ safari: [14, 0, 0],
108
+ ios: [14, 0, 0],
109
+ samsung: [14, 0, 0],
110
+ deno: [1, 2, 0],
111
+ node: [15, 0, 0]
112
+ },
113
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values#browser_compatibility
114
+ "array-values": {
115
+ es: [6, 0, 0],
116
+ chrome: [66, 0, 0],
117
+ edge: [14, 0, 0],
118
+ firefox: [60, 0, 0],
119
+ opera: [53, 0, 0],
120
+ safari: [9, 0, 0],
121
+ ios: [9, 0, 0],
122
+ samsung: [9, 0, 0],
123
+ deno: [1, 0, 0],
124
+ node: [10, 9, 0]
125
+ },
126
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#browser_compatibility
127
+ "arrow-function": {
128
+ es: [6, 0, 0],
129
+ chrome: [45, 0, 0],
130
+ edge: [12, 0, 0],
131
+ firefox: [24, 0, 0],
132
+ opera: [32, 0, 0],
133
+ safari: [10, 0, 0],
134
+ ios: [10, 0, 0],
135
+ samsung: [5, 0, 0],
136
+ deno: [1, 0, 0],
137
+ node: [4, 0, 0]
138
+ },
139
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#browser_compatibility
140
+ bigint: {
141
+ es: [2020, 0, 0],
142
+ chrome: [67, 0, 0],
143
+ edge: [79, 0, 0],
144
+ firefox: [68, 0, 0],
145
+ opera: [54, 0, 0],
146
+ safari: [14, 0, 0],
147
+ ios: [14, 0, 0],
148
+ samsung: [9, 0, 0],
149
+ deno: [1, 0, 0],
150
+ node: [10, 4, 0]
151
+ },
152
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#browser_compatibility
153
+ map: {
154
+ es: [6, 0, 0],
155
+ chrome: [38, 0, 0],
156
+ edge: [12, 0, 0],
157
+ firefox: [13, 0, 0],
158
+ opera: [25, 0, 0],
159
+ safari: [8, 0, 0],
160
+ ios: [8, 0, 0],
161
+ samsung: [3, 0, 0],
162
+ deno: [1, 0, 0],
163
+ node: [0, 12, 0]
164
+ },
165
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions#browser_compatibility
166
+ "method-shorthand": {
167
+ es: [6, 0, 0],
168
+ chrome: [39, 0, 0],
169
+ edge: [12, 0, 0],
170
+ firefox: [34, 0, 0],
171
+ opera: [26, 0, 0],
172
+ safari: [9, 0, 0],
173
+ ios: [9, 0, 0],
174
+ samsung: [4, 0, 0],
175
+ deno: [1, 0, 0],
176
+ node: [4, 0, 0]
177
+ },
178
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#browser_compatibility
179
+ "object-assign": {
180
+ es: [6, 0, 0],
181
+ chrome: [45, 0, 0],
182
+ edge: [12, 0, 0],
183
+ firefox: [34, 0, 0],
184
+ opera: [32, 0, 0],
185
+ safari: [9, 0, 0],
186
+ ios: [9, 0, 0],
187
+ samsung: [5, 0, 0],
188
+ deno: [1, 0, 0],
189
+ node: [4, 0, 0]
190
+ },
191
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#browser_compatibility
192
+ promise: {
193
+ es: [6, 0, 0],
194
+ chrome: [32, 0, 0],
195
+ edge: [12, 0, 0],
196
+ firefox: [29, 0, 0],
197
+ opera: [19, 0, 0],
198
+ safari: [8, 0, 0],
199
+ ios: [8, 0, 0],
200
+ samsung: [2, 0, 0],
201
+ deno: [1, 0, 0],
202
+ node: [0, 12, 0]
203
+ },
204
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#browser_compatibility
205
+ set: {
206
+ es: [6, 0, 0],
207
+ chrome: [38, 0, 0],
208
+ edge: [12, 0, 0],
209
+ firefox: [13, 0, 0],
210
+ opera: [25, 0, 0],
211
+ safari: [8, 0, 0],
212
+ ios: [8, 0, 0],
213
+ samsung: [3, 0, 0],
214
+ deno: [1, 0, 0],
215
+ node: [0, 12, 0]
216
+ },
217
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator#browser_compatibility
218
+ "symbol-iterator": {
219
+ es: [6, 0, 0],
220
+ chrome: [43, 0, 0],
221
+ edge: [12, 0, 0],
222
+ firefox: [36, 0, 0],
223
+ opera: [30, 0, 0],
224
+ safari: [10, 0, 0],
225
+ ios: [10, 0, 0],
226
+ samsung: [4, 0, 0],
227
+ deno: [1, 0, 0],
228
+ node: [0, 12, 0]
229
+ },
230
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#browser_compatibility
231
+ "typed-arrays": {
232
+ es: [6, 0, 0],
233
+ chrome: [7, 0, 0],
234
+ edge: [12, 0, 0],
235
+ firefox: [4, 0, 0],
236
+ opera: [11, 6, 0],
237
+ safari: [5, 1, 0],
238
+ ios: [4, 2, 0],
239
+ samsung: [1, 0, 0],
240
+ deno: [1, 0, 0],
241
+ node: [0, 10, 0]
242
+ }
243
+ };
244
+ var TARGET_REGEX = /^(es|chrome|edge|safari|firefox|opera|ios|samsung|deno|node)([0-9]+(\.[0-9]+(\.[0-9]+)?)?)$/i;
245
+ function parseTarget(target) {
246
+ const result = TARGET_REGEX.exec(target);
247
+ assert(result, `Invalid target "${target}"`);
248
+ const [, platform, version] = result;
249
+ const [major, minor = "0", patch = "0"] = version.split(".");
250
+ return [platform, [Number(major), Number(minor), Number(patch)]];
251
+ }
252
+ function getTargetVersions(targets) {
253
+ if (Array.isArray(targets)) {
254
+ const versions = [];
255
+ for (const target of targets) {
256
+ versions.push(parseTarget(target));
257
+ }
258
+ return versions;
259
+ }
260
+ return [parseTarget(targets)];
261
+ }
262
+ function isFeatureSupported(key, targets) {
263
+ const base = VERSION_TABLE[key];
264
+ let flag = true;
265
+ for (const [platform, version] of targets) {
266
+ const baseVersion = base[platform];
267
+ flag = flag && !!baseVersion && compareVersion(baseVersion, version) <= 0;
268
+ }
269
+ return flag;
270
+ }
271
+ function parseTargets(targets) {
272
+ const parsed = getTargetVersions(targets);
273
+ const flags = /* @__PURE__ */ new Set();
274
+ for (const key in VERSION_TABLE) {
275
+ if (isFeatureSupported(key, parsed)) {
276
+ flags.add(key);
277
+ }
278
+ }
279
+ return flags;
280
+ }
281
+
113
282
  // src/tree.ts
114
- function createSerializationContext() {
283
+ var DEFAULT_OPTIONS = {
284
+ target: "es2023"
285
+ };
286
+ function createSerializationContext(options = {}) {
287
+ const result = Object.assign({}, DEFAULT_OPTIONS, options || {});
115
288
  return {
116
289
  markedRefs: [],
117
290
  stack: [],
118
291
  refs: /* @__PURE__ */ new Map(),
119
292
  vars: [],
120
293
  assignments: [],
121
- validRefs: /* @__PURE__ */ new Map()
294
+ validRefs: /* @__PURE__ */ new Map(),
295
+ features: parseTargets(result.target)
122
296
  };
123
297
  }
124
298
  function getAssignmentExpression(assignment) {
@@ -133,12 +307,12 @@ function getAssignmentExpression(assignment) {
133
307
  return "";
134
308
  }
135
309
  }
136
- function mergeAssignments(ctx) {
310
+ function mergeAssignments(assignments) {
137
311
  const newAssignments = [];
138
- let current = ctx.assignments[0];
312
+ let current = assignments[0];
139
313
  let prev = current;
140
- for (let i = 1, len = ctx.assignments.length; i < len; i += 1) {
141
- const item = ctx.assignments[i];
314
+ for (let i = 1, len = assignments.length; i < len; i++) {
315
+ const item = assignments[i];
142
316
  if (item.type === prev.type) {
143
317
  if (item.type === "index" && item.value === prev.value) {
144
318
  current = {
@@ -172,15 +346,19 @@ function mergeAssignments(ctx) {
172
346
  newAssignments.push(current);
173
347
  return newAssignments;
174
348
  }
175
- function resolvePatches(ctx) {
176
- if (ctx.assignments.length) {
349
+ function resolveAssignments(assignments) {
350
+ if (assignments.length) {
177
351
  let result = "";
178
- for (const assignment of mergeAssignments(ctx)) {
179
- result += `${getAssignmentExpression(assignment)},`;
352
+ const merged = mergeAssignments(assignments);
353
+ for (let i = 0, len = merged.length; i < len; i++) {
354
+ result += `${getAssignmentExpression(merged[i])},`;
180
355
  }
181
356
  return result;
182
357
  }
183
- return "";
358
+ return void 0;
359
+ }
360
+ function resolvePatches(ctx) {
361
+ return resolveAssignments(ctx.assignments);
184
362
  }
185
363
  function markRef(ctx, current) {
186
364
  ctx.markedRefs[current] = true;
@@ -275,12 +453,6 @@ function getErrorConstructor(error) {
275
453
  }
276
454
  return "Error";
277
455
  }
278
- var EXCLUDED_ERROR_KEYS = {
279
- name: true,
280
- cause: true,
281
- stack: true,
282
- message: true
283
- };
284
456
  function getErrorOptions(error) {
285
457
  let options;
286
458
  const constructor = getErrorConstructor(error);
@@ -291,7 +463,7 @@ function getErrorOptions(error) {
291
463
  }
292
464
  const names = Object.getOwnPropertyNames(error);
293
465
  for (const name of names) {
294
- if (!(name in EXCLUDED_ERROR_KEYS)) {
466
+ if (name !== "name" && name !== "message") {
295
467
  options = options || {};
296
468
  options[name] = error[name];
297
469
  }
@@ -323,7 +495,7 @@ function generateRef(ctx, current) {
323
495
  ctx.refs.set(current, id);
324
496
  return id;
325
497
  }
326
- function generateSemiPrimitiveValue(current, id) {
498
+ function generateSemiPrimitiveValue(ctx, current, id) {
327
499
  if (constructorCheck(current, Date)) {
328
500
  return [2 /* Date */, current, id];
329
501
  }
@@ -331,41 +503,81 @@ function generateSemiPrimitiveValue(current, id) {
331
503
  return [3 /* RegExp */, current, id];
332
504
  }
333
505
  if (constructorCheck(current, Int8Array)) {
334
- return [13 /* TypedArray */, { constructor: "Int8Array", array: current }, id];
506
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Int8Array"');
507
+ return [13 /* TypedArray */, ["Int8Array", current], id];
335
508
  }
336
509
  if (constructorCheck(current, Int16Array)) {
337
- return [13 /* TypedArray */, { constructor: "Int16Array", array: current }, id];
510
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Int16Array"');
511
+ return [13 /* TypedArray */, ["Int16Array", current], id];
338
512
  }
339
513
  if (constructorCheck(current, Int32Array)) {
340
- return [13 /* TypedArray */, { constructor: "Int32Array", array: current }, id];
514
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Int32Array"');
515
+ return [13 /* TypedArray */, ["Int32Array", current], id];
341
516
  }
342
517
  if (constructorCheck(current, Uint8Array)) {
343
- return [13 /* TypedArray */, { constructor: "Uint8Array", array: current }, id];
518
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Uint8Array"');
519
+ return [13 /* TypedArray */, ["Uint8Array", current], id];
344
520
  }
345
521
  if (constructorCheck(current, Uint16Array)) {
346
- return [13 /* TypedArray */, { constructor: "Uint16Array", array: current }, id];
522
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Uint16Array"');
523
+ return [13 /* TypedArray */, ["Uint16Array", current], id];
347
524
  }
348
525
  if (constructorCheck(current, Uint32Array)) {
349
- return [13 /* TypedArray */, { constructor: "Uint32Array", array: current }, id];
526
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Uint32Array"');
527
+ return [13 /* TypedArray */, ["Uint32Array", current], id];
350
528
  }
351
529
  if (constructorCheck(current, Uint8ClampedArray)) {
352
- return [13 /* TypedArray */, { constructor: "Uint8ClampedArray", array: current }, id];
530
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Uint8ClampedArray"');
531
+ return [13 /* TypedArray */, ["Uint8ClampedArray", current], id];
353
532
  }
354
533
  if (constructorCheck(current, Float32Array)) {
355
- return [13 /* TypedArray */, { constructor: "Float32Array", array: current }, id];
534
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Float32Array"');
535
+ return [13 /* TypedArray */, ["Float32Array", current], id];
356
536
  }
357
537
  if (constructorCheck(current, Float64Array)) {
358
- return [13 /* TypedArray */, { constructor: "Float64Array", array: current }, id];
538
+ assert(ctx.features.has("typed-arrays"), 'Unsupported value type "Float64Array"');
539
+ return [13 /* TypedArray */, ["Float64Array", current], id];
359
540
  }
360
541
  if (constructorCheck(current, BigInt64Array)) {
361
- return [13 /* TypedArray */, { constructor: "BigInt64Array", array: current }, id];
542
+ assert(
543
+ ctx.features.has("typed-arrays") && ctx.features.has("bigint"),
544
+ 'Unsupported value type "BigInt64Array"'
545
+ );
546
+ return [13 /* TypedArray */, ["BigInt64Array", current], id];
362
547
  }
363
548
  if (constructorCheck(current, BigUint64Array)) {
364
- return [13 /* TypedArray */, { constructor: "BigUint64Array", array: current }, id];
549
+ assert(
550
+ ctx.features.has("typed-arrays") && ctx.features.has("bigint"),
551
+ 'Unsupported value type "BigUint64Array"'
552
+ );
553
+ return [13 /* TypedArray */, ["BigUint64Array", current], id];
365
554
  }
366
555
  return void 0;
367
556
  }
368
557
  function generateTreeSync(ctx, current) {
558
+ function serializeProperties(properties) {
559
+ const keyNodes = [];
560
+ const valueNodes = [];
561
+ const deferredKeys = [];
562
+ const deferredValues = [];
563
+ const keys = Object.keys(properties);
564
+ let deferredSize = 0;
565
+ for (const key of keys) {
566
+ if (isIterable(properties[key])) {
567
+ deferredKeys.push(key);
568
+ deferredValues.push(properties[key]);
569
+ deferredSize++;
570
+ } else {
571
+ keyNodes.push(key);
572
+ valueNodes.push(generateTreeSync(ctx, properties[key]));
573
+ }
574
+ }
575
+ for (let i = 0; i < deferredSize; i++) {
576
+ keyNodes.push(deferredKeys[i]);
577
+ valueNodes.push(generateTreeSync(ctx, deferredValues[i]));
578
+ }
579
+ return [keyNodes, valueNodes, keys.length];
580
+ }
369
581
  if (isPrimitive(current)) {
370
582
  return [0 /* Primitive */, current];
371
583
  }
@@ -373,11 +585,12 @@ function generateTreeSync(ctx, current) {
373
585
  if (Array.isArray(id)) {
374
586
  return id;
375
587
  }
376
- const semiPrimitive = generateSemiPrimitiveValue(current, id);
588
+ const semiPrimitive = generateSemiPrimitiveValue(ctx, current, id);
377
589
  if (semiPrimitive) {
378
590
  return semiPrimitive;
379
591
  }
380
592
  if (constructorCheck(current, Set)) {
593
+ assert(ctx.features.has("set"), 'Unsupported type "Set"');
381
594
  const nodes = [];
382
595
  const deferred = [];
383
596
  for (const item of current.keys()) {
@@ -387,95 +600,112 @@ function generateTreeSync(ctx, current) {
387
600
  nodes.push(generateTreeSync(ctx, item));
388
601
  }
389
602
  }
390
- for (const item of deferred) {
391
- nodes.push(generateTreeSync(ctx, item));
603
+ for (let i = 0, len = deferred.length; i < len; i++) {
604
+ nodes.push(generateTreeSync(ctx, deferred[i]));
392
605
  }
393
606
  return [4 /* Set */, nodes, id];
394
607
  }
395
608
  if (constructorCheck(current, Map)) {
396
- const nodes = [];
397
- const deferred = [];
609
+ assert(ctx.features.has("map"), 'Unsupported type "Map"');
610
+ const keyNodes = [];
611
+ const valueNodes = [];
612
+ const deferredKey = [];
613
+ const deferredValue = [];
614
+ let deferredSize = 0;
398
615
  for (const [key, value] of current.entries()) {
399
616
  if (isIterable(key) || isIterable(value)) {
400
- deferred.push([key, value]);
617
+ deferredKey.push(key);
618
+ deferredValue.push(value);
619
+ deferredSize++;
401
620
  } else {
402
- const keyNode = generateTreeSync(ctx, key);
403
- const valueNode = generateTreeSync(ctx, value);
404
- nodes.push([keyNode, valueNode]);
621
+ keyNodes.push(generateTreeSync(ctx, key));
622
+ valueNodes.push(generateTreeSync(ctx, value));
405
623
  }
406
624
  }
407
- for (const [key, value] of deferred) {
408
- const keyNode = generateTreeSync(ctx, key);
409
- const valueNode = generateTreeSync(ctx, value);
410
- nodes.push([keyNode, valueNode]);
625
+ for (let i = 0; i < deferredSize; i++) {
626
+ keyNodes.push(generateTreeSync(ctx, deferredKey[i]));
627
+ valueNodes.push(generateTreeSync(ctx, deferredValue[i]));
411
628
  }
412
- return [5 /* Map */, nodes, id];
629
+ return [5 /* Map */, [keyNodes, valueNodes, current.size], id];
413
630
  }
414
631
  if (Array.isArray(current)) {
415
- const nodes = new Array(current.length);
416
- const deferred = new Array(current.length);
417
- for (const key in current) {
418
- const item = current[key];
419
- if (isIterable(item)) {
420
- deferred[key] = item;
421
- } else {
422
- nodes[key] = generateTreeSync(ctx, item);
632
+ const size = current.length;
633
+ const nodes = new Array(size);
634
+ const deferred = new Array(size);
635
+ for (let i = 0; i < size; i++) {
636
+ if (i in current) {
637
+ if (isIterable(current[i])) {
638
+ deferred[i] = current[i];
639
+ } else {
640
+ nodes[i] = generateTreeSync(ctx, current[i]);
641
+ }
423
642
  }
424
643
  }
425
- for (const key in deferred) {
426
- nodes[key] = generateTreeSync(ctx, deferred[key]);
644
+ for (let i = 0; i < size; i++) {
645
+ if (i in deferred) {
646
+ nodes[i] = generateTreeSync(ctx, deferred[i]);
647
+ }
427
648
  }
428
649
  return [6 /* Array */, nodes, id];
429
650
  }
430
- if (current instanceof AggregateError) {
651
+ if (current instanceof AggregateError && ctx.features.has("aggregate-error")) {
431
652
  const options = getErrorOptions(current);
432
- return [11 /* AggregateError */, {
433
- message: current.message,
434
- options: options ? generateTreeSync(ctx, options) : void 0,
435
- cause: "cause" in current ? generateTreeSync(ctx, { cause: current.cause }) : void 0,
436
- errors: generateTreeSync(ctx, current.errors)
437
- }, id];
653
+ const optionsNode = options ? serializeProperties(options) : void 0;
654
+ const errorsNode = generateTreeSync(ctx, current.errors);
655
+ return [11 /* AggregateError */, [current.message, optionsNode, errorsNode], id];
438
656
  }
439
657
  if (current instanceof Error) {
440
658
  const options = getErrorOptions(current);
441
- return [10 /* Error */, {
442
- constructor: getErrorConstructor(current),
443
- message: current.message,
444
- options: options ? generateTreeSync(ctx, options) : void 0,
445
- cause: "cause" in current ? generateTreeSync(ctx, { cause: current.cause }) : void 0
446
- }, id];
659
+ const optionsNode = options ? serializeProperties(options) : void 0;
660
+ return [
661
+ 10 /* Error */,
662
+ [getErrorConstructor(current), current.message, optionsNode],
663
+ id
664
+ ];
447
665
  }
448
666
  if (isIterable(current)) {
667
+ assert(ctx.features.has("symbol-iterator"), 'Unsupported type "Iterable"');
449
668
  const options = getIterableOptions(current);
450
- return [12 /* Iterable */, {
669
+ return [12 /* Iterable */, [
451
670
  // Parse options first before the items
452
- options: options ? generateTreeSync(ctx, options) : void 0,
453
- items: generateTreeSync(ctx, Array.from(current))
454
- }, id];
671
+ options ? serializeProperties(options) : void 0,
672
+ generateTreeSync(ctx, Array.from(current))
673
+ ], id];
455
674
  }
456
675
  const empty = current.constructor == null;
457
676
  if (current.constructor === Object || empty) {
458
- const nodes = {};
459
- const deferred = {};
460
- for (const [key, item] of Object.entries(current)) {
461
- if (isIterable(item)) {
462
- deferred[key] = item;
463
- } else {
464
- nodes[key] = generateTreeSync(ctx, item);
465
- }
466
- }
467
- for (const [key, item] of Object.entries(deferred)) {
468
- nodes[key] = generateTreeSync(ctx, item);
469
- }
470
677
  return [
471
678
  empty ? 8 /* NullConstructor */ : 7 /* Object */,
472
- nodes,
679
+ serializeProperties(current),
473
680
  id
474
681
  ];
475
682
  }
476
683
  throw new Error("Unsupported value");
477
684
  }
478
685
  async function generateTreeAsync(ctx, current) {
686
+ async function serializeProperties(properties) {
687
+ const keyNodes = [];
688
+ const valueNodes = [];
689
+ const deferredKeys = [];
690
+ const deferredValues = [];
691
+ const keys = Object.keys(properties);
692
+ let deferredSize = 0;
693
+ for (const key of keys) {
694
+ if (isIterable(properties[key])) {
695
+ deferredKeys.push(key);
696
+ deferredValues.push(properties[key]);
697
+ deferredSize++;
698
+ } else {
699
+ keyNodes.push(key);
700
+ valueNodes.push(await generateTreeAsync(ctx, properties[key]));
701
+ }
702
+ }
703
+ for (let i = 0; i < deferredSize; i++) {
704
+ keyNodes.push(deferredKeys[i]);
705
+ valueNodes.push(await generateTreeAsync(ctx, deferredValues[i]));
706
+ }
707
+ return [keyNodes, valueNodes, keys.length];
708
+ }
479
709
  if (isPrimitive(current)) {
480
710
  return [0 /* Primitive */, current];
481
711
  }
@@ -483,11 +713,12 @@ async function generateTreeAsync(ctx, current) {
483
713
  if (Array.isArray(id)) {
484
714
  return id;
485
715
  }
486
- const semiPrimitive = generateSemiPrimitiveValue(current, id);
716
+ const semiPrimitive = generateSemiPrimitiveValue(ctx, current, id);
487
717
  if (semiPrimitive) {
488
718
  return semiPrimitive;
489
719
  }
490
720
  if (isPromise(current)) {
721
+ assert(ctx.features.has("promise"), 'Unsupported type "Promise"');
491
722
  return current.then(async (value) => [
492
723
  9 /* Promise */,
493
724
  await generateTreeAsync(ctx, value),
@@ -495,6 +726,7 @@ async function generateTreeAsync(ctx, current) {
495
726
  ]);
496
727
  }
497
728
  if (constructorCheck(current, Set)) {
729
+ assert(ctx.features.has("set"), 'Unsupported type "Set"');
498
730
  const nodes = [];
499
731
  const deferred = [];
500
732
  for (const item of current.keys()) {
@@ -504,97 +736,177 @@ async function generateTreeAsync(ctx, current) {
504
736
  nodes.push(await generateTreeAsync(ctx, item));
505
737
  }
506
738
  }
507
- for (const item of deferred) {
508
- nodes.push(await generateTreeAsync(ctx, item));
739
+ for (let i = 0, len = deferred.length; i < len; i++) {
740
+ nodes.push(await generateTreeAsync(ctx, deferred[i]));
509
741
  }
510
742
  return [4 /* Set */, nodes, id];
511
743
  }
512
744
  if (constructorCheck(current, Map)) {
513
- const nodes = [];
514
- const deferred = [];
745
+ assert(ctx.features.has("map"), 'Unsupported type "Map"');
746
+ const keyNodes = [];
747
+ const valueNodes = [];
748
+ const deferredKey = [];
749
+ const deferredValue = [];
750
+ let deferredSize = 0;
515
751
  for (const [key, value] of current.entries()) {
516
752
  if (isIterable(key) || isIterable(value)) {
517
- deferred.push([key, value]);
753
+ deferredKey.push(key);
754
+ deferredValue.push(value);
755
+ deferredSize++;
518
756
  } else {
519
- const keyNode = await generateTreeAsync(ctx, key);
520
- const valueNode = await generateTreeAsync(ctx, value);
521
- nodes.push([keyNode, valueNode]);
757
+ keyNodes.push(await generateTreeAsync(ctx, key));
758
+ valueNodes.push(await generateTreeAsync(ctx, value));
522
759
  }
523
760
  }
524
- for (const [key, value] of deferred) {
525
- const keyNode = await generateTreeAsync(ctx, key);
526
- const valueNode = await generateTreeAsync(ctx, value);
527
- nodes.push([keyNode, valueNode]);
761
+ for (let i = 0; i < deferredSize; i++) {
762
+ keyNodes.push(await generateTreeAsync(ctx, deferredKey[i]));
763
+ valueNodes.push(await generateTreeAsync(ctx, deferredValue[i]));
528
764
  }
529
- return [5 /* Map */, nodes, id];
765
+ return [5 /* Map */, [keyNodes, valueNodes, current.size], id];
530
766
  }
531
767
  if (Array.isArray(current)) {
532
- const nodes = new Array(current.length);
533
- const deferred = new Array(current.length);
534
- for (const key in current) {
535
- const item = current[key];
536
- if (isIterable(item)) {
537
- deferred[key] = item;
538
- } else {
539
- nodes[key] = await generateTreeAsync(ctx, item);
768
+ const size = current.length;
769
+ const nodes = new Array(size);
770
+ const deferred = new Array(size);
771
+ for (let i = 0; i < size; i++) {
772
+ const item = current[i];
773
+ if (i in current) {
774
+ if (isIterable(item)) {
775
+ deferred[i] = item;
776
+ } else {
777
+ nodes[i] = await generateTreeAsync(ctx, item);
778
+ }
540
779
  }
541
780
  }
542
- for (const key in deferred) {
543
- nodes[key] = await generateTreeAsync(ctx, deferred[key]);
781
+ for (let i = 0; i < size; i++) {
782
+ if (i in deferred) {
783
+ nodes[i] = await generateTreeAsync(ctx, deferred[i]);
784
+ }
544
785
  }
545
786
  return [6 /* Array */, nodes, id];
546
787
  }
547
788
  if (current instanceof AggregateError) {
548
789
  const options = getErrorOptions(current);
549
- return [11 /* AggregateError */, {
550
- message: current.message,
551
- options: options ? generateTreeSync(ctx, options) : void 0,
552
- cause: "cause" in current ? await generateTreeAsync(ctx, { cause: current.cause }) : void 0,
553
- errors: await generateTreeAsync(ctx, current.errors)
554
- }, id];
790
+ const optionsNode = options ? await serializeProperties(options) : void 0;
791
+ const errorsNode = await generateTreeAsync(ctx, current.errors);
792
+ return [11 /* AggregateError */, [current.message, optionsNode, errorsNode], id];
555
793
  }
556
794
  if (current instanceof Error) {
557
795
  const options = getErrorOptions(current);
558
- return [10 /* Error */, {
559
- constructor: getErrorConstructor(current),
560
- message: current.message,
561
- options: options ? await generateTreeAsync(ctx, options) : void 0,
562
- cause: "cause" in current ? await generateTreeAsync(ctx, { cause: current.cause }) : void 0
563
- }, id];
796
+ const optionsNode = options ? await serializeProperties(options) : void 0;
797
+ return [
798
+ 10 /* Error */,
799
+ [getErrorConstructor(current), current.message, optionsNode],
800
+ id
801
+ ];
564
802
  }
565
803
  if (isIterable(current)) {
804
+ assert(ctx.features.has("symbol-iterator"), 'Unsupported type "Iterable"');
566
805
  const options = getIterableOptions(current);
567
- return [12 /* Iterable */, {
568
- options: options ? await generateTreeAsync(ctx, options) : void 0,
569
- items: await generateTreeAsync(ctx, Array.from(current))
570
- }, id];
806
+ return [12 /* Iterable */, [
807
+ options ? await serializeProperties(options) : void 0,
808
+ await generateTreeAsync(ctx, Array.from(current))
809
+ ], id];
571
810
  }
572
811
  const empty = current.constructor == null;
573
812
  if (current.constructor === Object || empty) {
574
- const nodes = {};
575
- const deferred = {};
576
- for (const [key, item] of Object.entries(current)) {
577
- if (isIterable(item)) {
578
- deferred[key] = item;
579
- } else {
580
- nodes[key] = await generateTreeAsync(ctx, item);
581
- }
582
- }
583
- for (const [key, item] of Object.entries(deferred)) {
584
- nodes[key] = await generateTreeAsync(ctx, item);
585
- }
586
813
  return [
587
814
  empty ? 8 /* NullConstructor */ : 7 /* Object */,
588
- nodes,
815
+ await serializeProperties(current),
589
816
  id
590
817
  ];
591
818
  }
592
819
  throw new Error("Unsupported value");
593
820
  }
821
+ function serializePrimitive(ctx, value) {
822
+ if (value === true) {
823
+ return "!0";
824
+ }
825
+ if (value === false) {
826
+ return "!1";
827
+ }
828
+ if (value === void 0) {
829
+ return "void 0";
830
+ }
831
+ if (value === null) {
832
+ return "null";
833
+ }
834
+ if (typeof value === "bigint") {
835
+ assert(ctx.features.has("bigint"), 'Unsupported type "BigInt"');
836
+ return `${value}n`;
837
+ }
838
+ if (typeof value === "string") {
839
+ return quote(value);
840
+ }
841
+ if (Object.is(value, -0)) {
842
+ return "-0";
843
+ }
844
+ if (Object.is(value, Infinity)) {
845
+ return "1/0";
846
+ }
847
+ if (Object.is(value, -Infinity)) {
848
+ return "-1/0";
849
+ }
850
+ return String(value);
851
+ }
594
852
  function serializeTree(ctx, [type, value, id]) {
853
+ function serializeAssignments(targetRef, [keys, values, size]) {
854
+ ctx.stack.push(targetRef);
855
+ const mainAssignments = [];
856
+ for (let i = 0; i < size; i++) {
857
+ const parentStack = ctx.stack;
858
+ ctx.stack = [];
859
+ const refParam = serializeTree(ctx, values[i]);
860
+ ctx.stack = parentStack;
861
+ const key = keys[i];
862
+ const check = Number(key);
863
+ const parentAssignment = ctx.assignments;
864
+ ctx.assignments = mainAssignments;
865
+ if (check >= 0 || Number.isNaN(check) && /^([$A-Z_][0-9A-Z_$]*)$/i.test(key)) {
866
+ if (!Number.isNaN(check)) {
867
+ createObjectComputedAssign(ctx, targetRef, key, refParam);
868
+ } else {
869
+ createObjectIdentifierAssign(ctx, targetRef, key, refParam);
870
+ }
871
+ } else {
872
+ createObjectComputedAssign(ctx, targetRef, quote(key), refParam);
873
+ }
874
+ ctx.assignments = parentAssignment;
875
+ }
876
+ ctx.stack.pop();
877
+ return resolveAssignments(mainAssignments);
878
+ }
879
+ function serializeObject(sourceID, [keys, values, size]) {
880
+ let result = "";
881
+ ctx.stack.push(sourceID);
882
+ for (let i = 0; i < size; i++) {
883
+ const key = keys[i];
884
+ const val = values[i];
885
+ const check = Number(key);
886
+ if (check >= 0 || Number.isNaN(check) && /^([$A-Z_][0-9A-Z_$]*)$/i.test(key)) {
887
+ if (isReferenceInStack(ctx, val)) {
888
+ const refParam = getRefParam(ctx, val[1]);
889
+ if (!Number.isNaN(check)) {
890
+ createObjectComputedAssign(ctx, sourceID, key, refParam);
891
+ } else {
892
+ createObjectIdentifierAssign(ctx, sourceID, key, refParam);
893
+ }
894
+ } else {
895
+ result += `${key}:${serializeTree(ctx, val)},`;
896
+ }
897
+ } else if (isReferenceInStack(ctx, val)) {
898
+ const refParam = getRefParam(ctx, val[1]);
899
+ createObjectComputedAssign(ctx, sourceID, quote(key), refParam);
900
+ } else {
901
+ result += `${quote(key)}:${serializeTree(ctx, val)},`;
902
+ }
903
+ }
904
+ ctx.stack.pop();
905
+ return `{${result.substring(0, result.length - 1)}}`;
906
+ }
595
907
  switch (type) {
596
908
  case 0 /* Primitive */:
597
- return serializePrimitive(value);
909
+ return serializePrimitive(ctx, value);
598
910
  case 1 /* Reference */:
599
911
  return getRefParam(ctx, value);
600
912
  case 9 /* Promise */: {
@@ -614,38 +926,46 @@ function serializeTree(ctx, [type, value, id]) {
614
926
  case 3 /* RegExp */:
615
927
  return assignRef(ctx, id, String(value));
616
928
  case 13 /* TypedArray */: {
617
- const values = [...value.array].map(serializePrimitive).join(",");
618
- let args = `[${values}]`;
619
- if (value.array.byteOffset !== 0) {
620
- args += `,${value.array.byteOffset}`;
929
+ let values = "";
930
+ for (let i = 0, len = value[1].length; i < len; i++) {
931
+ values += `${serializePrimitive(ctx, value[1][i])},`;
621
932
  }
622
- return assignRef(ctx, id, `new ${value.constructor}(${args})`);
933
+ let args = values ? `[${values.substring(0, values.length - 1)}]` : "[]";
934
+ if (value[1].byteOffset !== 0) {
935
+ args += `,${value[1].byteOffset}`;
936
+ }
937
+ return assignRef(ctx, id, `new ${value[0]}(${args})`);
623
938
  }
624
939
  case 4 /* Set */: {
625
940
  let serialized = "new Set";
626
- if (value.length) {
627
- const values = [];
941
+ const size = value.length;
942
+ if (size) {
943
+ let result = "";
628
944
  ctx.stack.push(id);
629
- for (const item of value) {
945
+ for (let i = 0; i < size; i++) {
946
+ const item = value[i];
630
947
  if (isReferenceInStack(ctx, item)) {
631
948
  createSetAdd(ctx, id, getRefParam(ctx, item[1]));
632
949
  } else {
633
- values.push(serializeTree(ctx, item));
950
+ result += `${serializeTree(ctx, item)},`;
634
951
  }
635
952
  }
636
953
  ctx.stack.pop();
637
- if (values.length) {
638
- serialized += `([${values.join(",")}])`;
954
+ if (result) {
955
+ serialized += `([${result.substring(0, result.length - 1)}])`;
639
956
  }
640
957
  }
641
958
  return assignRef(ctx, id, serialized);
642
959
  }
643
960
  case 5 /* Map */: {
644
961
  let serialized = "new Map";
645
- if (value.length) {
646
- const values = [];
962
+ const size = value[2];
963
+ if (size) {
964
+ let result = "";
647
965
  ctx.stack.push(id);
648
- for (const [key, val] of value) {
966
+ for (let i = 0; i < size; i++) {
967
+ const key = value[0][i];
968
+ const val = value[1][i];
649
969
  if (isReferenceInStack(ctx, key)) {
650
970
  const keyRef = getRefParam(ctx, key[1]);
651
971
  if (isReferenceInStack(ctx, val)) {
@@ -664,20 +984,21 @@ function serializeTree(ctx, [type, value, id]) {
664
984
  createMapSet(ctx, id, serializeTree(ctx, key), valueRef);
665
985
  ctx.stack = parent;
666
986
  } else {
667
- values.push(`[${serializeTree(ctx, key)},${serializeTree(ctx, val)}]`);
987
+ result += `[${serializeTree(ctx, key)},${serializeTree(ctx, val)}],`;
668
988
  }
669
989
  }
670
990
  ctx.stack.pop();
671
- if (values.length) {
672
- serialized += `([${values.join(",")}])`;
991
+ if (result) {
992
+ serialized += `([${result.substring(0, result.length - 1)}])`;
673
993
  }
674
994
  }
675
995
  return assignRef(ctx, id, serialized);
676
996
  }
677
997
  case 6 /* Array */: {
998
+ const size = value.length;
678
999
  let values = "";
679
1000
  ctx.stack.push(id);
680
- for (let i = 0, len = value.length; i < len; i++) {
1001
+ for (let i = 0; i < size; i++) {
681
1002
  const item = value[i];
682
1003
  if (i in value) {
683
1004
  if (isReferenceInStack(ctx, item)) {
@@ -685,7 +1006,7 @@ function serializeTree(ctx, [type, value, id]) {
685
1006
  values += ",";
686
1007
  } else {
687
1008
  values += serializeTree(ctx, item);
688
- if (i < value.length - 1) {
1009
+ if (i < size - 1) {
689
1010
  values += ",";
690
1011
  }
691
1012
  }
@@ -697,74 +1018,93 @@ function serializeTree(ctx, [type, value, id]) {
697
1018
  return assignRef(ctx, id, `[${values}]`);
698
1019
  }
699
1020
  case 11 /* AggregateError */: {
700
- const args = [serializeTree(ctx, value.errors), quote(value.message)];
701
- if (value.cause) {
702
- args.push(serializeTree(ctx, value.cause));
703
- }
704
- let serialized = `new AggregateError(${args.join(",")})`;
705
- if (value.options) {
706
- const options = serializeTree(ctx, value.options);
707
- serialized = `Object.assign(${serialized},${options})`;
1021
+ ctx.stack.push(id);
1022
+ let serialized = `new AggregateError(${serializeTree(ctx, value[2])},${quote(value[0])})`;
1023
+ ctx.stack.pop();
1024
+ if (value[1]) {
1025
+ if (ctx.features.has("object-assign")) {
1026
+ const options = serializeObject(id, value[1]);
1027
+ serialized = `Object.assign(${serialized},${options})`;
1028
+ } else {
1029
+ markRef(ctx, id);
1030
+ const assignments = serializeAssignments(id, value[1]);
1031
+ if (assignments) {
1032
+ const ref = getRefParam(ctx, id);
1033
+ return `(${assignRef(ctx, id, serialized)},${assignments}${ref})`;
1034
+ }
1035
+ }
708
1036
  }
709
1037
  return assignRef(ctx, id, serialized);
710
1038
  }
711
1039
  case 10 /* Error */: {
712
- const args = [quote(value.message)];
713
- if (value.cause) {
714
- args.push(serializeTree(ctx, value.cause));
715
- }
716
- let serialized = `new ${value.constructor}(${args.join(",")})`;
717
- if (value.options) {
718
- const options = serializeTree(ctx, value.options);
719
- serialized = `Object.assign(${serialized},${options})`;
1040
+ let serialized = `new ${value[0]}(${quote(value[1])})`;
1041
+ if (value[2]) {
1042
+ if (ctx.features.has("object-assign")) {
1043
+ const options = serializeObject(id, value[2]);
1044
+ serialized = `Object.assign(${serialized},${options})`;
1045
+ } else {
1046
+ markRef(ctx, id);
1047
+ const assignments = serializeAssignments(id, value[2]);
1048
+ if (assignments) {
1049
+ const ref = getRefParam(ctx, id);
1050
+ return `(${assignRef(ctx, id, serialized)},${assignments}${ref})`;
1051
+ }
1052
+ }
720
1053
  }
721
1054
  return assignRef(ctx, id, serialized);
722
1055
  }
723
1056
  case 12 /* Iterable */: {
724
1057
  const parent = ctx.stack;
725
1058
  ctx.stack = [];
726
- const values = serializeTree(ctx, value.items);
1059
+ const values = serializeTree(ctx, value[1]);
727
1060
  ctx.stack = parent;
728
- let serialized = `{[Symbol.iterator]:()=>${values}.values()}`;
729
- if (value.options) {
730
- ctx.stack.push(id);
731
- const options = serializeTree(ctx, value.options);
732
- ctx.stack.pop();
733
- serialized = `Object.assign(${serialized},${options})`;
1061
+ let serialized;
1062
+ if (ctx.features.has("array-values")) {
1063
+ serialized = `${values}.values()`;
1064
+ } else {
1065
+ serialized = `${values}[Symbol.iterator]()`;
734
1066
  }
735
- return assignRef(ctx, id, serialized);
736
- }
737
- case 8 /* NullConstructor */:
738
- case 7 /* Object */: {
739
- const values = [];
740
- ctx.stack.push(id);
741
- for (const [key, val] of Object.entries(value)) {
742
- const check = Number(key);
743
- if (check >= 0 || Number.isNaN(check) && /^([$A-Z_][0-9A-Z_$]*)$/i.test(key)) {
744
- if (isReferenceInStack(ctx, val)) {
745
- const refParam = getRefParam(ctx, val[1]);
746
- if (!Number.isNaN(check)) {
747
- createObjectComputedAssign(ctx, id, key, refParam);
748
- } else {
749
- createObjectIdentifierAssign(ctx, id, key, refParam);
750
- }
751
- } else {
752
- values.push(`${key}:${serializeTree(ctx, val)}`);
753
- }
754
- } else if (isReferenceInStack(ctx, val)) {
755
- const refParam = getRefParam(ctx, val[1]);
756
- createObjectComputedAssign(ctx, id, quote(key), refParam);
1067
+ if (ctx.features.has("arrow-function")) {
1068
+ serialized = `{[Symbol.iterator]:()=>${serialized}}`;
1069
+ } else if (ctx.features.has("method-shorthand")) {
1070
+ serialized = `{[Symbol.iterator](){return ${serialized}}}`;
1071
+ } else {
1072
+ serialized = `{[Symbol.iterator]:function(){return ${serialized}}}`;
1073
+ }
1074
+ if (value[0]) {
1075
+ if (ctx.features.has("object-assign")) {
1076
+ const options = serializeObject(id, value[0]);
1077
+ serialized = `Object.assign(${serialized},${options})`;
757
1078
  } else {
758
- values.push(`${quote(key)}:${serializeTree(ctx, val)}`);
1079
+ markRef(ctx, id);
1080
+ const assignments = serializeAssignments(id, value[0]);
1081
+ if (assignments) {
1082
+ const ref = getRefParam(ctx, id);
1083
+ return `(${assignRef(ctx, id, serialized)},${assignments}${ref})`;
1084
+ }
759
1085
  }
760
1086
  }
761
- ctx.stack.pop();
762
- let serialized = `{${values.join(",")}}`;
763
- if (type === 8 /* NullConstructor */) {
764
- serialized = `Object.assign(Object.create(null),${serialized})`;
1087
+ return assignRef(ctx, id, serialized);
1088
+ }
1089
+ case 8 /* NullConstructor */: {
1090
+ let serialized = "Object.create(null)";
1091
+ if (ctx.features.has("object-assign")) {
1092
+ const fields = serializeObject(id, value);
1093
+ if (fields !== "{}") {
1094
+ serialized = `Object.assign(${serialized},${fields})`;
1095
+ }
1096
+ } else {
1097
+ markRef(ctx, id);
1098
+ const assignments = serializeAssignments(id, value);
1099
+ if (assignments) {
1100
+ const ref = getRefParam(ctx, id);
1101
+ return `(${assignRef(ctx, id, serialized)},${assignments}${ref})`;
1102
+ }
765
1103
  }
766
1104
  return assignRef(ctx, id, serialized);
767
1105
  }
1106
+ case 7 /* Object */:
1107
+ return assignRef(ctx, id, serializeObject(id, value));
768
1108
  default:
769
1109
  throw new Error("Unsupported type");
770
1110
  }
@@ -773,33 +1113,42 @@ function serializeTree(ctx, [type, value, id]) {
773
1113
  // src/index.ts
774
1114
  function finalize(ctx, source, result) {
775
1115
  if (ctx.vars.length) {
776
- const index = getRefParam(ctx, createRef(ctx, source));
777
1116
  const patches = resolvePatches(ctx);
778
- const params = ctx.vars.length > 1 ? `(${ctx.vars.join(",")})` : ctx.vars[0];
779
- if (result.startsWith(`${index}=`)) {
780
- return `(${params}=>(${result},${patches}${index}))()`;
1117
+ let body = result;
1118
+ if (patches) {
1119
+ const index = getRefParam(ctx, createRef(ctx, source));
1120
+ if (result.startsWith(`${index}=`)) {
1121
+ body = `${result},${patches}${index}`;
1122
+ } else {
1123
+ body = `${index}=${result},${patches}${index}`;
1124
+ }
1125
+ }
1126
+ let params = ctx.vars.length > 1 ? ctx.vars.join(",") : ctx.vars[0];
1127
+ if (ctx.features.has("arrow-function")) {
1128
+ params = ctx.vars.length > 1 || ctx.vars.length === 0 ? `(${params})` : params;
1129
+ return `(${params}=>(${body}))()`;
781
1130
  }
782
- return `(${params}=>(${index}=${result},${patches}${index}))()`;
1131
+ return `(function(${params}){return ${body}})()`;
783
1132
  }
784
1133
  if (source.constructor === Object) {
785
1134
  return `(${result})`;
786
1135
  }
787
1136
  return result;
788
1137
  }
789
- function serialize(source) {
1138
+ function serialize(source, options) {
1139
+ const ctx = createSerializationContext(options);
790
1140
  if (isPrimitive(source)) {
791
- return serializePrimitive(source);
1141
+ return serializePrimitive(ctx, source);
792
1142
  }
793
- const ctx = createSerializationContext();
794
1143
  const tree = generateTreeSync(ctx, source);
795
1144
  const result = serializeTree(ctx, tree);
796
1145
  return finalize(ctx, source, result);
797
1146
  }
798
- async function serializeAsync(source) {
1147
+ async function serializeAsync(source, options) {
1148
+ const ctx = createSerializationContext(options);
799
1149
  if (isPrimitive(source)) {
800
- return serializePrimitive(source);
1150
+ return serializePrimitive(ctx, source);
801
1151
  }
802
- const ctx = createSerializationContext();
803
1152
  const tree = await generateTreeAsync(ctx, source);
804
1153
  const result = serializeTree(ctx, tree);
805
1154
  return finalize(ctx, source, result);