seroval 1.6.5 → 1.6.7

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.
package/dist/dev/index.js CHANGED
@@ -147,6 +147,8 @@ const NEG_INFINITY_NODE = /* @__PURE__ */ createConstantNode(6);
147
147
  const NAN_NODE = /* @__PURE__ */ createConstantNode(7);
148
148
  //#endregion
149
149
  //#region src/core/string.ts
150
+ const MIN_JSON_STRINGIFY_LENGTH = 64;
151
+ const JSON_ESCAPE_DIFFERENCES = /[\x00-\x07\x0b\x0e-\x1f<\u2028\u2029\ud800-\udfff]/;
150
152
  function serializeChar(str) {
151
153
  switch (str) {
152
154
  case "\"": return "\\\"";
@@ -163,6 +165,7 @@ function serializeChar(str) {
163
165
  }
164
166
  }
165
167
  function serializeString(str) {
168
+ if (str.length >= MIN_JSON_STRINGIFY_LENGTH && !JSON_ESCAPE_DIFFERENCES.test(str)) return JSON.stringify(str).slice(1, -1);
166
169
  let result = "";
167
170
  let lastPos = 0;
168
171
  let replacement;
@@ -193,6 +196,7 @@ function deserializeReplacer(str) {
193
196
  }
194
197
  }
195
198
  function deserializeString(str) {
199
+ if (typeof str === "string" && !str.includes("\\")) return str;
196
200
  return str.replace(/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g, deserializeReplacer);
197
201
  }
198
202
  //#endregion
@@ -523,7 +527,10 @@ const STREAM_CONSTRUCTOR = () => {
523
527
  let count = 0;
524
528
  const internal = {
525
529
  flush(value, mode, x) {
526
- for (x = 0; x < count; x++) if (listeners[x]) listeners[x][mode](value);
530
+ for (x = 0; x < count; x++) {
531
+ const listener = listeners[x];
532
+ if (listener) listener[mode](value);
533
+ }
527
534
  },
528
535
  up(listener, x, z, current) {
529
536
  for (x = 0, z = buffer.length; x < z; x++) {
@@ -532,16 +539,20 @@ const STREAM_CONSTRUCTOR = () => {
532
539
  else listener.next(current);
533
540
  }
534
541
  },
535
- on(listener, temp) {
542
+ on(listener, temp = 0) {
543
+ let subscribed = alive;
536
544
  if (alive) {
537
- temp = count++;
545
+ for (temp = 0; temp < count; temp++) if (!listeners[temp]) break;
546
+ if (temp === count) count++;
538
547
  listeners[temp] = listener;
539
548
  }
540
549
  internal.up(listener);
541
550
  return () => {
542
- if (alive) {
543
- listeners[temp] = listeners[count];
544
- listeners[count--] = void 0;
551
+ if (alive && subscribed) {
552
+ subscribed = false;
553
+ listeners[temp] = void 0;
554
+ while (count > 0 && !listeners[count - 1]) count--;
555
+ listeners.length = count;
545
556
  }
546
557
  };
547
558
  }
@@ -752,19 +763,35 @@ function isStream(value) {
752
763
  function createStream() {
753
764
  return STREAM_CONSTRUCTOR();
754
765
  }
755
- function createStreamFromAsyncIterable(iterable) {
766
+ function createStreamFromAsyncIterable(iterable, cleanups) {
756
767
  const stream = createStream();
757
768
  const iterator = iterable[SYM_ASYNC_ITERATOR]();
769
+ let cancelled = false;
770
+ let done = false;
771
+ cleanups === null || cleanups === void 0 || cleanups.push(() => {
772
+ if (!(done || cancelled)) {
773
+ cancelled = true;
774
+ Promise.resolve().then(() => {
775
+ var _iterator$return;
776
+ return (_iterator$return = iterator.return) === null || _iterator$return === void 0 ? void 0 : _iterator$return.call(iterator);
777
+ }).catch(() => {});
778
+ }
779
+ });
758
780
  async function push() {
759
781
  try {
760
- const value = await iterator.next();
761
- if (value.done) stream.return(value.value);
762
- else {
782
+ while (!cancelled) {
783
+ const value = await iterator.next();
784
+ if (cancelled) return;
785
+ if (value.done) {
786
+ done = true;
787
+ stream.return(value.value);
788
+ break;
789
+ }
763
790
  stream.next(value.value);
764
- await push();
765
791
  }
766
792
  } catch (error) {
767
- stream.throw(error);
793
+ done = true;
794
+ if (!cancelled) stream.throw(error);
768
795
  }
769
796
  }
770
797
  push().catch(() => {});
@@ -786,13 +813,15 @@ async function promiseToResult(current) {
786
813
  //#endregion
787
814
  //#region src/core/context/parser.ts
788
815
  function createBaseParserContext(mode, options) {
816
+ var _options$compactArray;
789
817
  return {
790
818
  plugins: options.plugins,
791
819
  mode,
792
820
  marked: /* @__PURE__ */ new Set(),
793
821
  features: 127 ^ (options.disabledFeatures || 0),
794
822
  refs: options.refs || /* @__PURE__ */ new Map(),
795
- depthLimit: options.depthLimit || 1e3
823
+ depthLimit: options.depthLimit || 1e3,
824
+ compactArrayBufferViews: (_options$compactArray = options.compactArrayBufferViews) !== null && _options$compactArray !== void 0 ? _options$compactArray : false
796
825
  };
797
826
  }
798
827
  /**
@@ -872,11 +901,22 @@ function createMapNode(ctx, id, k, v) {
872
901
  function createPromiseConstructorNode(ctx, id, resolver) {
873
902
  return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
874
903
  }
875
- function createArrayBufferNode(ctx, id, current) {
904
+ function getArrayBufferView(ctx, current) {
905
+ if (!ctx.compactArrayBufferViews) return current;
906
+ const buffer = new Uint8Array(current.buffer, current.byteOffset, current.byteLength).slice().buffer;
907
+ const Constructor = current.constructor;
908
+ return new Constructor(buffer);
909
+ }
910
+ function encodeArrayBuffer(current) {
911
+ if (typeof Buffer !== "undefined") return Buffer.from(current).toString("base64");
876
912
  const bytes = new Uint8Array(current);
913
+ if (typeof bytes.toBase64 === "function") return bytes.toBase64();
877
914
  let result = "";
878
915
  for (let i = 0, len = bytes.length; i < len; i++) result += String.fromCharCode(bytes[i]);
879
- return createSerovalNode(19, id, serializeString(btoa(result)), void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 5), void 0, void 0, void 0);
916
+ return btoa(result);
917
+ }
918
+ function createArrayBufferNode(ctx, id, current) {
919
+ return createSerovalNode(19, id, encodeArrayBuffer(current), void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 5), void 0, void 0, void 0);
880
920
  }
881
921
  //#endregion
882
922
  //#region src/core/context/async-parser.ts
@@ -940,12 +980,15 @@ async function parseBoxed$1(ctx, depth, id, current) {
940
980
  return createBoxedNode(id, await parseAsync(ctx, depth, current.valueOf()));
941
981
  }
942
982
  async function parseTypedArray$1(ctx, depth, id, current) {
983
+ current = getArrayBufferView(ctx.base, current);
943
984
  return createTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
944
985
  }
945
986
  async function parseBigIntTypedArray$1(ctx, depth, id, current) {
987
+ current = getArrayBufferView(ctx.base, current);
946
988
  return createBigIntTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
947
989
  }
948
990
  async function parseDataView$1(ctx, depth, id, current) {
991
+ current = getArrayBufferView(ctx.base, current);
949
992
  return createDataViewNode(id, current, await parseAsync(ctx, depth, current.buffer));
950
993
  }
951
994
  async function parseError$1(ctx, depth, id, current) {
@@ -1190,7 +1233,8 @@ function isValidSymbol(symbol) {
1190
1233
  }
1191
1234
  //#endregion
1192
1235
  //#region src/core/context/deserializer.ts
1193
- const MAX_BASE64_LENGTH = 1e6;
1236
+ const DEFAULT_MAX_BASE64_LENGTH = 1e6;
1237
+ const MIN_NATIVE_BASE64_LENGTH = 512;
1194
1238
  const MAX_BIGINT_LENGTH = 1e4;
1195
1239
  const MAX_REGEXP_SOURCE_LENGTH = 2e4;
1196
1240
  function applyObjectFlag(obj, flag) {
@@ -1203,7 +1247,9 @@ function applyObjectFlag(obj, flag) {
1203
1247
  }
1204
1248
  const DEFAULT_DEPTH_LIMIT = 1e3;
1205
1249
  function createBaseDeserializerContext(mode, options) {
1206
- var _options$features;
1250
+ var _options$maxBase64Len, _options$features;
1251
+ const maxBase64Length = (_options$maxBase64Len = options.maxBase64Length) !== null && _options$maxBase64Len !== void 0 ? _options$maxBase64Len : DEFAULT_MAX_BASE64_LENGTH;
1252
+ if (!Number.isSafeInteger(maxBase64Length) || maxBase64Length < 0) throw new RangeError("maxBase64Length must be a non-negative safe integer");
1207
1253
  const refs = options.refs || /* @__PURE__ */ new Map();
1208
1254
  if (!("types" in refs)) Object.assign(refs, { types: /* @__PURE__ */ new Map() });
1209
1255
  return {
@@ -1211,7 +1257,8 @@ function createBaseDeserializerContext(mode, options) {
1211
1257
  plugins: options.plugins,
1212
1258
  refs,
1213
1259
  features: (_options$features = options.features) !== null && _options$features !== void 0 ? _options$features : 127 ^ (options.disabledFeatures || 0),
1214
- depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT
1260
+ depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT,
1261
+ maxBase64Length
1215
1262
  };
1216
1263
  }
1217
1264
  function createVanillaDeserializerContext(options) {
@@ -1374,8 +1421,17 @@ function deserializeMap(ctx, depth, node) {
1374
1421
  return result;
1375
1422
  }
1376
1423
  function deserializeArrayBuffer(ctx, node) {
1377
- if (node.s.length > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1378
- return assignIndexedValue$1(ctx, node.i, ARRAY_BUFFER_CONSTRUCTOR(deserializeString(node.s)));
1424
+ if (typeof node.s !== "string") throw new SerovalMalformedNodeError(node);
1425
+ if (node.s.length > ctx.base.maxBase64Length) throw new RangeError("ArrayBuffer exceeds maxBase64Length (" + ctx.base.maxBase64Length + ")");
1426
+ const source = deserializeString(node.s);
1427
+ let buffer;
1428
+ if (source.length < MIN_NATIVE_BASE64_LENGTH || typeof Buffer === "undefined") buffer = ARRAY_BUFFER_CONSTRUCTOR(source);
1429
+ else {
1430
+ const decoded = atob(source);
1431
+ buffer = new ArrayBuffer(decoded.length);
1432
+ Buffer.from(buffer).write(decoded, "latin1");
1433
+ }
1434
+ return assignIndexedValue$1(ctx, node.i, buffer);
1379
1435
  }
1380
1436
  function deserializeTypedArray(ctx, depth, node) {
1381
1437
  var _node$b;
@@ -1383,7 +1439,7 @@ function deserializeTypedArray(ctx, depth, node) {
1383
1439
  const source = deserialize$1(ctx, depth, node.f);
1384
1440
  if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1385
1441
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1386
- if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1442
+ if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1387
1443
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1388
1444
  }
1389
1445
  function deserializeDataView(ctx, depth, node) {
@@ -1391,7 +1447,7 @@ function deserializeDataView(ctx, depth, node) {
1391
1447
  const source = deserialize$1(ctx, depth, node.f);
1392
1448
  if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1393
1449
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1394
- if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1450
+ if (offset < 0 || offset > source.byteLength) throw new SerovalMalformedNodeError(node);
1395
1451
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1396
1452
  }
1397
1453
  function deserializeDictionary(ctx, depth, node, result) {
@@ -2411,7 +2467,7 @@ function parseProperties(ctx, depth, properties) {
2411
2467
  }
2412
2468
  if (SYM_ASYNC_ITERATOR in properties) {
2413
2469
  keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
2414
- valueNodes.push(createAsyncIteratorFactoryInstanceNode(parseAsyncIteratorFactory(ctx.base), parseSOS(ctx, depth, ctx.type === 1 ? createStream() : createStreamFromAsyncIterable(properties))));
2470
+ valueNodes.push(createAsyncIteratorFactoryInstanceNode(parseAsyncIteratorFactory(ctx.base), parseSOS(ctx, depth, ctx.type === 1 ? createStream() : createStreamFromAsyncIterable(properties, ctx.state.cleanups))));
2415
2471
  }
2416
2472
  if (SYM_TO_STRING_TAG in properties) {
2417
2473
  keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
@@ -2433,12 +2489,15 @@ function parseBoxed(ctx, depth, id, current) {
2433
2489
  return createBoxedNode(id, parseSOS(ctx, depth, current.valueOf()));
2434
2490
  }
2435
2491
  function parseTypedArray(ctx, depth, id, current) {
2492
+ current = getArrayBufferView(ctx.base, current);
2436
2493
  return createTypedArrayNode(id, current, parseSOS(ctx, depth, current.buffer));
2437
2494
  }
2438
2495
  function parseBigIntTypedArray(ctx, depth, id, current) {
2496
+ current = getArrayBufferView(ctx.base, current);
2439
2497
  return createBigIntTypedArrayNode(id, current, parseSOS(ctx, depth, current.buffer));
2440
2498
  }
2441
2499
  function parseDataView(ctx, depth, id, current) {
2500
+ current = getArrayBufferView(ctx.base, current);
2442
2501
  return createDataViewNode(id, current, parseSOS(ctx, depth, current.buffer));
2443
2502
  }
2444
2503
  function parseError(ctx, depth, id, current) {
@@ -2689,6 +2748,7 @@ function destroyStreamParse(ctx) {
2689
2748
  function crossSerialize(source, options = {}) {
2690
2749
  const plugins = resolvePlugins(options.plugins);
2691
2750
  const ctx = createSyncParserContext(2, {
2751
+ compactArrayBufferViews: options.compactArrayBufferViews,
2692
2752
  plugins,
2693
2753
  disabledFeatures: options.disabledFeatures,
2694
2754
  refs: options.refs
@@ -2704,6 +2764,7 @@ function crossSerialize(source, options = {}) {
2704
2764
  async function crossSerializeAsync(source, options = {}) {
2705
2765
  const plugins = resolvePlugins(options.plugins);
2706
2766
  const ctx = createAsyncParserContext(2, {
2767
+ compactArrayBufferViews: options.compactArrayBufferViews,
2707
2768
  plugins,
2708
2769
  disabledFeatures: options.disabledFeatures,
2709
2770
  refs: options.refs
@@ -2717,15 +2778,19 @@ async function crossSerializeAsync(source, options = {}) {
2717
2778
  }), tree);
2718
2779
  }
2719
2780
  function toCrossJSON(source, options = {}) {
2781
+ const plugins = resolvePlugins(options.plugins);
2720
2782
  return parseTop(createSyncParserContext(2, {
2721
- plugins: resolvePlugins(options.plugins),
2783
+ compactArrayBufferViews: options.compactArrayBufferViews,
2784
+ plugins,
2722
2785
  disabledFeatures: options.disabledFeatures,
2723
2786
  refs: options.refs
2724
2787
  }), source);
2725
2788
  }
2726
2789
  async function toCrossJSONAsync(source, options = {}) {
2790
+ const plugins = resolvePlugins(options.plugins);
2727
2791
  return await parseTopAsync(createAsyncParserContext(2, {
2728
- plugins: resolvePlugins(options.plugins),
2792
+ compactArrayBufferViews: options.compactArrayBufferViews,
2793
+ plugins,
2729
2794
  disabledFeatures: options.disabledFeatures,
2730
2795
  refs: options.refs
2731
2796
  }), source);
@@ -2733,6 +2798,7 @@ async function toCrossJSONAsync(source, options = {}) {
2733
2798
  function crossSerializeStream(source, options) {
2734
2799
  const plugins = resolvePlugins(options.plugins);
2735
2800
  const ctx = createStreamParserContext({
2801
+ compactArrayBufferViews: options.compactArrayBufferViews,
2736
2802
  plugins,
2737
2803
  refs: options.refs,
2738
2804
  disabledFeatures: options.disabledFeatures,
@@ -2759,8 +2825,10 @@ function crossSerializeStream(source, options) {
2759
2825
  return destroyStreamParse.bind(null, ctx);
2760
2826
  }
2761
2827
  function toCrossJSONStream(source, options) {
2828
+ const plugins = resolvePlugins(options.plugins);
2762
2829
  const ctx = createStreamParserContext({
2763
- plugins: resolvePlugins(options.plugins),
2830
+ compactArrayBufferViews: options.compactArrayBufferViews,
2831
+ plugins,
2764
2832
  refs: options.refs,
2765
2833
  disabledFeatures: options.disabledFeatures,
2766
2834
  depthLimit: options.depthLimit,
@@ -2772,8 +2840,10 @@ function toCrossJSONStream(source, options) {
2772
2840
  return destroyStreamParse.bind(null, ctx);
2773
2841
  }
2774
2842
  function fromCrossJSON(source, options) {
2843
+ const plugins = resolvePlugins(options.plugins);
2775
2844
  return deserializeTop(createCrossDeserializerContext({
2776
- plugins: resolvePlugins(options.plugins),
2845
+ maxBase64Length: options.maxBase64Length,
2846
+ plugins,
2777
2847
  refs: options.refs,
2778
2848
  features: options.features,
2779
2849
  disabledFeatures: options.disabledFeatures,
@@ -2804,6 +2874,7 @@ var Serializer = class {
2804
2874
  scopeId: this.options.scopeId,
2805
2875
  refs: this.refs,
2806
2876
  disabledFeatures: this.options.disabledFeatures,
2877
+ compactArrayBufferViews: this.options.compactArrayBufferViews,
2807
2878
  onError: this.options.onError,
2808
2879
  onSerialize: (data, initial) => {
2809
2880
  if (this.alive) this.options.onData(initial ? this.options.globalIdentifier + "[\"" + serializeString(key) + "\"]=" + data : data);
@@ -2854,6 +2925,7 @@ var Serializer = class {
2854
2925
  function serialize(source, options = {}) {
2855
2926
  const plugins = resolvePlugins(options.plugins);
2856
2927
  const ctx = createSyncParserContext(1, {
2928
+ compactArrayBufferViews: options.compactArrayBufferViews,
2857
2929
  plugins,
2858
2930
  disabledFeatures: options.disabledFeatures
2859
2931
  });
@@ -2867,6 +2939,7 @@ function serialize(source, options = {}) {
2867
2939
  async function serializeAsync(source, options = {}) {
2868
2940
  const plugins = resolvePlugins(options.plugins);
2869
2941
  const ctx = createAsyncParserContext(1, {
2942
+ compactArrayBufferViews: options.compactArrayBufferViews,
2870
2943
  plugins,
2871
2944
  disabledFeatures: options.disabledFeatures
2872
2945
  });
@@ -2881,8 +2954,10 @@ function deserialize(source) {
2881
2954
  return (0, eval)(source);
2882
2955
  }
2883
2956
  function toJSON(source, options = {}) {
2957
+ const plugins = resolvePlugins(options.plugins);
2884
2958
  const ctx = createSyncParserContext(1, {
2885
- plugins: resolvePlugins(options.plugins),
2959
+ compactArrayBufferViews: options.compactArrayBufferViews,
2960
+ plugins,
2886
2961
  disabledFeatures: options.disabledFeatures
2887
2962
  });
2888
2963
  return {
@@ -2892,8 +2967,10 @@ function toJSON(source, options = {}) {
2892
2967
  };
2893
2968
  }
2894
2969
  async function toJSONAsync(source, options = {}) {
2970
+ const plugins = resolvePlugins(options.plugins);
2895
2971
  const ctx = createAsyncParserContext(1, {
2896
- plugins: resolvePlugins(options.plugins),
2972
+ compactArrayBufferViews: options.compactArrayBufferViews,
2973
+ plugins,
2897
2974
  disabledFeatures: options.disabledFeatures
2898
2975
  });
2899
2976
  return {
@@ -2915,6 +2992,7 @@ function fromJSON(source, options = {}) {
2915
2992
  const disabledFeatures = options.disabledFeatures || 0;
2916
2993
  const sourceFeatures = (_source$f = source.f) !== null && _source$f !== void 0 ? _source$f : 127;
2917
2994
  return deserializeTop(createVanillaDeserializerContext({
2995
+ maxBase64Length: options.maxBase64Length,
2918
2996
  plugins,
2919
2997
  markedRefs: source.m,
2920
2998
  features: sourceFeatures & ~disabledFeatures,