seroval 1.6.5 → 1.6.6

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/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;
@@ -516,7 +519,10 @@ const STREAM_CONSTRUCTOR = () => {
516
519
  let count = 0;
517
520
  const internal = {
518
521
  flush(value, mode, x) {
519
- for (x = 0; x < count; x++) if (listeners[x]) listeners[x][mode](value);
522
+ for (x = 0; x < count; x++) {
523
+ const listener = listeners[x];
524
+ if (listener) listener[mode](value);
525
+ }
520
526
  },
521
527
  up(listener, x, z, current) {
522
528
  for (x = 0, z = buffer.length; x < z; x++) {
@@ -525,16 +531,20 @@ const STREAM_CONSTRUCTOR = () => {
525
531
  else listener.next(current);
526
532
  }
527
533
  },
528
- on(listener, temp) {
534
+ on(listener, temp = 0) {
535
+ let subscribed = alive;
529
536
  if (alive) {
530
- temp = count++;
537
+ for (temp = 0; temp < count; temp++) if (!listeners[temp]) break;
538
+ if (temp === count) count++;
531
539
  listeners[temp] = listener;
532
540
  }
533
541
  internal.up(listener);
534
542
  return () => {
535
- if (alive) {
536
- listeners[temp] = listeners[count];
537
- listeners[count--] = void 0;
543
+ if (alive && subscribed) {
544
+ subscribed = false;
545
+ listeners[temp] = void 0;
546
+ while (count > 0 && !listeners[count - 1]) count--;
547
+ listeners.length = count;
538
548
  }
539
549
  };
540
550
  }
@@ -745,19 +755,35 @@ function isStream(value) {
745
755
  function createStream() {
746
756
  return STREAM_CONSTRUCTOR();
747
757
  }
748
- function createStreamFromAsyncIterable(iterable) {
758
+ function createStreamFromAsyncIterable(iterable, cleanups) {
749
759
  const stream = createStream();
750
760
  const iterator = iterable[SYM_ASYNC_ITERATOR]();
761
+ let cancelled = false;
762
+ let done = false;
763
+ cleanups === null || cleanups === void 0 || cleanups.push(() => {
764
+ if (!(done || cancelled)) {
765
+ cancelled = true;
766
+ Promise.resolve().then(() => {
767
+ var _iterator$return;
768
+ return (_iterator$return = iterator.return) === null || _iterator$return === void 0 ? void 0 : _iterator$return.call(iterator);
769
+ }).catch(() => {});
770
+ }
771
+ });
751
772
  async function push() {
752
773
  try {
753
- const value = await iterator.next();
754
- if (value.done) stream.return(value.value);
755
- else {
774
+ while (!cancelled) {
775
+ const value = await iterator.next();
776
+ if (cancelled) return;
777
+ if (value.done) {
778
+ done = true;
779
+ stream.return(value.value);
780
+ break;
781
+ }
756
782
  stream.next(value.value);
757
- await push();
758
783
  }
759
784
  } catch (error) {
760
- stream.throw(error);
785
+ done = true;
786
+ if (!cancelled) stream.throw(error);
761
787
  }
762
788
  }
763
789
  push().catch(() => {});
@@ -779,13 +805,15 @@ async function promiseToResult(current) {
779
805
  //#endregion
780
806
  //#region src/core/context/parser.ts
781
807
  function createBaseParserContext(mode, options) {
808
+ var _options$compactArray;
782
809
  return {
783
810
  plugins: options.plugins,
784
811
  mode,
785
812
  marked: /* @__PURE__ */ new Set(),
786
813
  features: 127 ^ (options.disabledFeatures || 0),
787
814
  refs: options.refs || /* @__PURE__ */ new Map(),
788
- depthLimit: options.depthLimit || 1e3
815
+ depthLimit: options.depthLimit || 1e3,
816
+ compactArrayBufferViews: (_options$compactArray = options.compactArrayBufferViews) !== null && _options$compactArray !== void 0 ? _options$compactArray : false
789
817
  };
790
818
  }
791
819
  /**
@@ -865,11 +893,22 @@ function createMapNode(ctx, id, k, v) {
865
893
  function createPromiseConstructorNode(ctx, id, resolver) {
866
894
  return createSerovalNode(22, id, resolver, void 0, void 0, void 0, void 0, void 0, parseSpecialReference(ctx, 1), void 0, void 0, void 0);
867
895
  }
868
- function createArrayBufferNode(ctx, id, current) {
896
+ function getArrayBufferView(ctx, current) {
897
+ if (!ctx.compactArrayBufferViews) return current;
898
+ const buffer = new Uint8Array(current.buffer, current.byteOffset, current.byteLength).slice().buffer;
899
+ const Constructor = current.constructor;
900
+ return new Constructor(buffer);
901
+ }
902
+ function encodeArrayBuffer(current) {
903
+ if (typeof Buffer !== "undefined") return Buffer.from(current).toString("base64");
869
904
  const bytes = new Uint8Array(current);
905
+ if (typeof bytes.toBase64 === "function") return bytes.toBase64();
870
906
  let result = "";
871
907
  for (let i = 0, len = bytes.length; i < len; i++) result += String.fromCharCode(bytes[i]);
872
- 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);
908
+ return btoa(result);
909
+ }
910
+ function createArrayBufferNode(ctx, id, current) {
911
+ 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);
873
912
  }
874
913
  //#endregion
875
914
  //#region src/core/context/async-parser.ts
@@ -933,12 +972,15 @@ async function parseBoxed$1(ctx, depth, id, current) {
933
972
  return createBoxedNode(id, await parseAsync(ctx, depth, current.valueOf()));
934
973
  }
935
974
  async function parseTypedArray$1(ctx, depth, id, current) {
975
+ current = getArrayBufferView(ctx.base, current);
936
976
  return createTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
937
977
  }
938
978
  async function parseBigIntTypedArray$1(ctx, depth, id, current) {
979
+ current = getArrayBufferView(ctx.base, current);
939
980
  return createBigIntTypedArrayNode(id, current, await parseAsync(ctx, depth, current.buffer));
940
981
  }
941
982
  async function parseDataView$1(ctx, depth, id, current) {
983
+ current = getArrayBufferView(ctx.base, current);
942
984
  return createDataViewNode(id, current, await parseAsync(ctx, depth, current.buffer));
943
985
  }
944
986
  async function parseError$1(ctx, depth, id, current) {
@@ -1183,7 +1225,7 @@ function isValidSymbol(symbol) {
1183
1225
  }
1184
1226
  //#endregion
1185
1227
  //#region src/core/context/deserializer.ts
1186
- const MAX_BASE64_LENGTH = 1e6;
1228
+ const DEFAULT_MAX_BASE64_LENGTH = 1e6;
1187
1229
  const MAX_BIGINT_LENGTH = 1e4;
1188
1230
  const MAX_REGEXP_SOURCE_LENGTH = 2e4;
1189
1231
  function applyObjectFlag(obj, flag) {
@@ -1196,7 +1238,9 @@ function applyObjectFlag(obj, flag) {
1196
1238
  }
1197
1239
  const DEFAULT_DEPTH_LIMIT = 1e3;
1198
1240
  function createBaseDeserializerContext(mode, options) {
1199
- var _options$features;
1241
+ var _options$maxBase64Len, _options$features;
1242
+ const maxBase64Length = (_options$maxBase64Len = options.maxBase64Length) !== null && _options$maxBase64Len !== void 0 ? _options$maxBase64Len : DEFAULT_MAX_BASE64_LENGTH;
1243
+ if (!Number.isSafeInteger(maxBase64Length) || maxBase64Length < 0) throw new RangeError("maxBase64Length must be a non-negative safe integer");
1200
1244
  const refs = options.refs || /* @__PURE__ */ new Map();
1201
1245
  if (!("types" in refs)) Object.assign(refs, { types: /* @__PURE__ */ new Map() });
1202
1246
  return {
@@ -1204,7 +1248,8 @@ function createBaseDeserializerContext(mode, options) {
1204
1248
  plugins: options.plugins,
1205
1249
  refs,
1206
1250
  features: (_options$features = options.features) !== null && _options$features !== void 0 ? _options$features : 127 ^ (options.disabledFeatures || 0),
1207
- depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT
1251
+ depthLimit: options.depthLimit || DEFAULT_DEPTH_LIMIT,
1252
+ maxBase64Length
1208
1253
  };
1209
1254
  }
1210
1255
  function createVanillaDeserializerContext(options) {
@@ -1367,7 +1412,8 @@ function deserializeMap(ctx, depth, node) {
1367
1412
  return result;
1368
1413
  }
1369
1414
  function deserializeArrayBuffer(ctx, node) {
1370
- if (node.s.length > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1415
+ if (typeof node.s !== "string") throw new SerovalMalformedNodeError(node);
1416
+ if (node.s.length > ctx.base.maxBase64Length) throw new RangeError("ArrayBuffer exceeds maxBase64Length (" + ctx.base.maxBase64Length + ")");
1371
1417
  return assignIndexedValue$1(ctx, node.i, ARRAY_BUFFER_CONSTRUCTOR(deserializeString(node.s)));
1372
1418
  }
1373
1419
  function deserializeTypedArray(ctx, depth, node) {
@@ -1376,7 +1422,7 @@ function deserializeTypedArray(ctx, depth, node) {
1376
1422
  const source = deserialize$1(ctx, depth, node.f);
1377
1423
  if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1378
1424
  const offset = (_node$b = node.b) !== null && _node$b !== void 0 ? _node$b : 0;
1379
- if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1425
+ if (offset < 0 || offset > source.byteLength || node.l > ctx.base.maxBase64Length) throw new SerovalMalformedNodeError(node);
1380
1426
  return assignIndexedValue$1(ctx, node.i, new construct(source, offset, node.l));
1381
1427
  }
1382
1428
  function deserializeDataView(ctx, depth, node) {
@@ -1384,7 +1430,7 @@ function deserializeDataView(ctx, depth, node) {
1384
1430
  const source = deserialize$1(ctx, depth, node.f);
1385
1431
  if (!(source instanceof ArrayBuffer)) throw new SerovalMalformedNodeError(node);
1386
1432
  const offset = (_node$b2 = node.b) !== null && _node$b2 !== void 0 ? _node$b2 : 0;
1387
- if (offset < 0 || offset > source.byteLength || node.l > MAX_BASE64_LENGTH) throw new SerovalMalformedNodeError(node);
1433
+ if (offset < 0 || offset > source.byteLength || node.l > ctx.base.maxBase64Length) throw new SerovalMalformedNodeError(node);
1388
1434
  return assignIndexedValue$1(ctx, node.i, new DataView(source, offset, node.l));
1389
1435
  }
1390
1436
  function deserializeDictionary(ctx, depth, node, result) {
@@ -2404,7 +2450,7 @@ function parseProperties(ctx, depth, properties) {
2404
2450
  }
2405
2451
  if (SYM_ASYNC_ITERATOR in properties) {
2406
2452
  keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_ASYNC_ITERATOR));
2407
- valueNodes.push(createAsyncIteratorFactoryInstanceNode(parseAsyncIteratorFactory(ctx.base), parseSOS(ctx, depth, ctx.type === 1 ? createStream() : createStreamFromAsyncIterable(properties))));
2453
+ valueNodes.push(createAsyncIteratorFactoryInstanceNode(parseAsyncIteratorFactory(ctx.base), parseSOS(ctx, depth, ctx.type === 1 ? createStream() : createStreamFromAsyncIterable(properties, ctx.state.cleanups))));
2408
2454
  }
2409
2455
  if (SYM_TO_STRING_TAG in properties) {
2410
2456
  keyNodes.push(parseWellKnownSymbol(ctx.base, SYM_TO_STRING_TAG));
@@ -2426,12 +2472,15 @@ function parseBoxed(ctx, depth, id, current) {
2426
2472
  return createBoxedNode(id, parseSOS(ctx, depth, current.valueOf()));
2427
2473
  }
2428
2474
  function parseTypedArray(ctx, depth, id, current) {
2475
+ current = getArrayBufferView(ctx.base, current);
2429
2476
  return createTypedArrayNode(id, current, parseSOS(ctx, depth, current.buffer));
2430
2477
  }
2431
2478
  function parseBigIntTypedArray(ctx, depth, id, current) {
2479
+ current = getArrayBufferView(ctx.base, current);
2432
2480
  return createBigIntTypedArrayNode(id, current, parseSOS(ctx, depth, current.buffer));
2433
2481
  }
2434
2482
  function parseDataView(ctx, depth, id, current) {
2483
+ current = getArrayBufferView(ctx.base, current);
2435
2484
  return createDataViewNode(id, current, parseSOS(ctx, depth, current.buffer));
2436
2485
  }
2437
2486
  function parseError(ctx, depth, id, current) {
@@ -2682,6 +2731,7 @@ function destroyStreamParse(ctx) {
2682
2731
  function crossSerialize(source, options = {}) {
2683
2732
  const plugins = resolvePlugins(options.plugins);
2684
2733
  const ctx = createSyncParserContext(2, {
2734
+ compactArrayBufferViews: options.compactArrayBufferViews,
2685
2735
  plugins,
2686
2736
  disabledFeatures: options.disabledFeatures,
2687
2737
  refs: options.refs
@@ -2697,6 +2747,7 @@ function crossSerialize(source, options = {}) {
2697
2747
  async function crossSerializeAsync(source, options = {}) {
2698
2748
  const plugins = resolvePlugins(options.plugins);
2699
2749
  const ctx = createAsyncParserContext(2, {
2750
+ compactArrayBufferViews: options.compactArrayBufferViews,
2700
2751
  plugins,
2701
2752
  disabledFeatures: options.disabledFeatures,
2702
2753
  refs: options.refs
@@ -2710,15 +2761,19 @@ async function crossSerializeAsync(source, options = {}) {
2710
2761
  }), tree);
2711
2762
  }
2712
2763
  function toCrossJSON(source, options = {}) {
2764
+ const plugins = resolvePlugins(options.plugins);
2713
2765
  return parseTop(createSyncParserContext(2, {
2714
- plugins: resolvePlugins(options.plugins),
2766
+ compactArrayBufferViews: options.compactArrayBufferViews,
2767
+ plugins,
2715
2768
  disabledFeatures: options.disabledFeatures,
2716
2769
  refs: options.refs
2717
2770
  }), source);
2718
2771
  }
2719
2772
  async function toCrossJSONAsync(source, options = {}) {
2773
+ const plugins = resolvePlugins(options.plugins);
2720
2774
  return await parseTopAsync(createAsyncParserContext(2, {
2721
- plugins: resolvePlugins(options.plugins),
2775
+ compactArrayBufferViews: options.compactArrayBufferViews,
2776
+ plugins,
2722
2777
  disabledFeatures: options.disabledFeatures,
2723
2778
  refs: options.refs
2724
2779
  }), source);
@@ -2726,6 +2781,7 @@ async function toCrossJSONAsync(source, options = {}) {
2726
2781
  function crossSerializeStream(source, options) {
2727
2782
  const plugins = resolvePlugins(options.plugins);
2728
2783
  const ctx = createStreamParserContext({
2784
+ compactArrayBufferViews: options.compactArrayBufferViews,
2729
2785
  plugins,
2730
2786
  refs: options.refs,
2731
2787
  disabledFeatures: options.disabledFeatures,
@@ -2752,8 +2808,10 @@ function crossSerializeStream(source, options) {
2752
2808
  return destroyStreamParse.bind(null, ctx);
2753
2809
  }
2754
2810
  function toCrossJSONStream(source, options) {
2811
+ const plugins = resolvePlugins(options.plugins);
2755
2812
  const ctx = createStreamParserContext({
2756
- plugins: resolvePlugins(options.plugins),
2813
+ compactArrayBufferViews: options.compactArrayBufferViews,
2814
+ plugins,
2757
2815
  refs: options.refs,
2758
2816
  disabledFeatures: options.disabledFeatures,
2759
2817
  depthLimit: options.depthLimit,
@@ -2765,8 +2823,10 @@ function toCrossJSONStream(source, options) {
2765
2823
  return destroyStreamParse.bind(null, ctx);
2766
2824
  }
2767
2825
  function fromCrossJSON(source, options) {
2826
+ const plugins = resolvePlugins(options.plugins);
2768
2827
  return deserializeTop(createCrossDeserializerContext({
2769
- plugins: resolvePlugins(options.plugins),
2828
+ maxBase64Length: options.maxBase64Length,
2829
+ plugins,
2770
2830
  refs: options.refs,
2771
2831
  features: options.features,
2772
2832
  disabledFeatures: options.disabledFeatures,
@@ -2797,6 +2857,7 @@ var Serializer = class {
2797
2857
  scopeId: this.options.scopeId,
2798
2858
  refs: this.refs,
2799
2859
  disabledFeatures: this.options.disabledFeatures,
2860
+ compactArrayBufferViews: this.options.compactArrayBufferViews,
2800
2861
  onError: this.options.onError,
2801
2862
  onSerialize: (data, initial) => {
2802
2863
  if (this.alive) this.options.onData(initial ? this.options.globalIdentifier + "[\"" + serializeString(key) + "\"]=" + data : data);
@@ -2847,6 +2908,7 @@ var Serializer = class {
2847
2908
  function serialize(source, options = {}) {
2848
2909
  const plugins = resolvePlugins(options.plugins);
2849
2910
  const ctx = createSyncParserContext(1, {
2911
+ compactArrayBufferViews: options.compactArrayBufferViews,
2850
2912
  plugins,
2851
2913
  disabledFeatures: options.disabledFeatures
2852
2914
  });
@@ -2860,6 +2922,7 @@ function serialize(source, options = {}) {
2860
2922
  async function serializeAsync(source, options = {}) {
2861
2923
  const plugins = resolvePlugins(options.plugins);
2862
2924
  const ctx = createAsyncParserContext(1, {
2925
+ compactArrayBufferViews: options.compactArrayBufferViews,
2863
2926
  plugins,
2864
2927
  disabledFeatures: options.disabledFeatures
2865
2928
  });
@@ -2874,8 +2937,10 @@ function deserialize(source) {
2874
2937
  return (0, eval)(source);
2875
2938
  }
2876
2939
  function toJSON(source, options = {}) {
2940
+ const plugins = resolvePlugins(options.plugins);
2877
2941
  const ctx = createSyncParserContext(1, {
2878
- plugins: resolvePlugins(options.plugins),
2942
+ compactArrayBufferViews: options.compactArrayBufferViews,
2943
+ plugins,
2879
2944
  disabledFeatures: options.disabledFeatures
2880
2945
  });
2881
2946
  return {
@@ -2885,8 +2950,10 @@ function toJSON(source, options = {}) {
2885
2950
  };
2886
2951
  }
2887
2952
  async function toJSONAsync(source, options = {}) {
2953
+ const plugins = resolvePlugins(options.plugins);
2888
2954
  const ctx = createAsyncParserContext(1, {
2889
- plugins: resolvePlugins(options.plugins),
2955
+ compactArrayBufferViews: options.compactArrayBufferViews,
2956
+ plugins,
2890
2957
  disabledFeatures: options.disabledFeatures
2891
2958
  });
2892
2959
  return {
@@ -2908,6 +2975,7 @@ function fromJSON(source, options = {}) {
2908
2975
  const disabledFeatures = options.disabledFeatures || 0;
2909
2976
  const sourceFeatures = (_source$f = source.f) !== null && _source$f !== void 0 ? _source$f : 127;
2910
2977
  return deserializeTop(createVanillaDeserializerContext({
2978
+ maxBase64Length: options.maxBase64Length,
2911
2979
  plugins,
2912
2980
  markedRefs: source.m,
2913
2981
  features: sourceFeatures & ~disabledFeatures,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "1.6.5",
4
+ "version": "1.6.6",
5
5
  "files": [
6
6
  "dist"
7
7
  ],