seroval 1.7.0 → 1.7.2

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.
@@ -1018,6 +1018,20 @@ var Stream = class {
1018
1018
  }
1019
1019
  };
1020
1020
  }
1021
+ /**
1022
+ * Returns the events of a stream that has ended, without subscribing, so a
1023
+ * live receiver is not consumed. The last value is the `return` or `throw`
1024
+ * value. Returns `undefined` while the stream is open, or when a live
1025
+ * receiver was already consumed and has no events left.
1026
+ * @internal
1027
+ */
1028
+ endedEvents() {
1029
+ if (this.alive || this.live > 1) return void 0;
1030
+ return {
1031
+ values: this.buffer.slice(),
1032
+ success: this.success
1033
+ };
1034
+ }
1021
1035
  next(value) {
1022
1036
  if (this.alive) this.flush(value, "next");
1023
1037
  }
@@ -1689,8 +1703,10 @@ function guardIndexedValue(ctx, id) {
1689
1703
  function isThennable(value) {
1690
1704
  return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
1691
1705
  }
1706
+ const ignoreRejection = () => {};
1692
1707
  function assignIndexedValue$1(ctx, id, value) {
1693
1708
  guardIndexedValue(ctx.base, id);
1709
+ if (value instanceof Promise) value.catch(ignoreRejection);
1694
1710
  const marked = ctx.marked;
1695
1711
  if (!marked || marked.has(id)) ctx.base.refs.set(id, value);
1696
1712
  return value;
@@ -2800,9 +2816,10 @@ function parseProperties(ctx, depth, properties) {
2800
2816
  };
2801
2817
  }
2802
2818
  function parseAsyncIterable(ctx, depth, current) {
2819
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2803
2820
  const id = createIndexForValue(ctx.base, {});
2804
2821
  const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2805
- if (ctx.type === 2) ctx.state.iterable(ctx, depth, id, current);
2822
+ ctx.state.iterable(ctx, depth, id, current);
2806
2823
  return result;
2807
2824
  }
2808
2825
  function parsePlainObject(ctx, depth, id, current, empty) {
@@ -2837,15 +2854,34 @@ function parseSet(ctx, depth, id, current) {
2837
2854
  for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item);
2838
2855
  return createSetNode(id, items);
2839
2856
  }
2857
+ /**
2858
+ * Sends the events of a stream that has ended, so the copy gets all of them.
2859
+ * A stream that is still open throws, because the other sync modes cannot
2860
+ * send its later events.
2861
+ */
2862
+ function parseEndedStream(ctx, depth, id, current) {
2863
+ const events = current.endedEvents();
2864
+ if (!events) throw new SerovalUnsupportedTypeError(current);
2865
+ const values = events.values;
2866
+ const last = values.length - 1;
2867
+ const sequence = new Array(values.length);
2868
+ if (last >= 0) markParserRef(ctx.base, id);
2869
+ for (let i = 0; i <= last; i++) sequence[i] = createStreamEventNode(i < last ? 32 : events.success ? 34 : 33, id, parseSOS(ctx, depth, values[i]));
2870
+ return sequence;
2871
+ }
2840
2872
  function parseStream(ctx, depth, id, current) {
2841
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2842
- if (ctx.type === 2) ctx.state.stream(ctx, depth, id, current);
2843
- return result;
2873
+ const reference = parseSpecialReference(ctx.base, 4);
2874
+ if (ctx.type === 2) {
2875
+ const result = createStreamConstructorNode(id, reference, []);
2876
+ ctx.state.stream(ctx, depth, id, current);
2877
+ return result;
2878
+ }
2879
+ return createStreamConstructorNode(id, reference, parseEndedStream(ctx, depth, id, current));
2844
2880
  }
2845
2881
  function parseLiveStream(ctx, depth, id, current) {
2846
- const stream = ctx.type === 2;
2847
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], stream ? 1 : void 0);
2848
- if (stream) ctx.state.live(ctx, depth, id, current);
2882
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2883
+ const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1);
2884
+ ctx.state.live(ctx, depth, id, current);
2849
2885
  return result;
2850
2886
  }
2851
2887
  function parsePromise(ctx, depth, id, current) {
@@ -418,6 +418,17 @@ export declare class Stream<T> {
418
418
  private flush;
419
419
  private replay;
420
420
  on(listener: StreamListener<T>): () => void;
421
+ /**
422
+ * Returns the events of a stream that has ended, without subscribing, so a
423
+ * live receiver is not consumed. The last value is the `return` or `throw`
424
+ * value. Returns `undefined` while the stream is open, or when a live
425
+ * receiver was already consumed and has no events left.
426
+ * @internal
427
+ */
428
+ endedEvents(): {
429
+ values: unknown[];
430
+ success: boolean;
431
+ } | undefined;
421
432
  next(value: T): void;
422
433
  throw(value: unknown): void;
423
434
  return(value: T): void;
@@ -418,6 +418,17 @@ export declare class Stream<T> {
418
418
  private flush;
419
419
  private replay;
420
420
  on(listener: StreamListener<T>): () => void;
421
+ /**
422
+ * Returns the events of a stream that has ended, without subscribing, so a
423
+ * live receiver is not consumed. The last value is the `return` or `throw`
424
+ * value. Returns `undefined` while the stream is open, or when a live
425
+ * receiver was already consumed and has no events left.
426
+ * @internal
427
+ */
428
+ endedEvents(): {
429
+ values: unknown[];
430
+ success: boolean;
431
+ } | undefined;
421
432
  next(value: T): void;
422
433
  throw(value: unknown): void;
423
434
  return(value: T): void;
package/dist/dev/index.js CHANGED
@@ -1017,6 +1017,20 @@ var Stream = class {
1017
1017
  }
1018
1018
  };
1019
1019
  }
1020
+ /**
1021
+ * Returns the events of a stream that has ended, without subscribing, so a
1022
+ * live receiver is not consumed. The last value is the `return` or `throw`
1023
+ * value. Returns `undefined` while the stream is open, or when a live
1024
+ * receiver was already consumed and has no events left.
1025
+ * @internal
1026
+ */
1027
+ endedEvents() {
1028
+ if (this.alive || this.live > 1) return void 0;
1029
+ return {
1030
+ values: this.buffer.slice(),
1031
+ success: this.success
1032
+ };
1033
+ }
1020
1034
  next(value) {
1021
1035
  if (this.alive) this.flush(value, "next");
1022
1036
  }
@@ -1688,8 +1702,10 @@ function guardIndexedValue(ctx, id) {
1688
1702
  function isThennable(value) {
1689
1703
  return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
1690
1704
  }
1705
+ const ignoreRejection = () => {};
1691
1706
  function assignIndexedValue$1(ctx, id, value) {
1692
1707
  guardIndexedValue(ctx.base, id);
1708
+ if (value instanceof Promise) value.catch(ignoreRejection);
1693
1709
  const marked = ctx.marked;
1694
1710
  if (!marked || marked.has(id)) ctx.base.refs.set(id, value);
1695
1711
  return value;
@@ -2799,9 +2815,10 @@ function parseProperties(ctx, depth, properties) {
2799
2815
  };
2800
2816
  }
2801
2817
  function parseAsyncIterable(ctx, depth, current) {
2818
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2802
2819
  const id = createIndexForValue(ctx.base, {});
2803
2820
  const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2804
- if (ctx.type === 2) ctx.state.iterable(ctx, depth, id, current);
2821
+ ctx.state.iterable(ctx, depth, id, current);
2805
2822
  return result;
2806
2823
  }
2807
2824
  function parsePlainObject(ctx, depth, id, current, empty) {
@@ -2836,15 +2853,34 @@ function parseSet(ctx, depth, id, current) {
2836
2853
  for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item);
2837
2854
  return createSetNode(id, items);
2838
2855
  }
2856
+ /**
2857
+ * Sends the events of a stream that has ended, so the copy gets all of them.
2858
+ * A stream that is still open throws, because the other sync modes cannot
2859
+ * send its later events.
2860
+ */
2861
+ function parseEndedStream(ctx, depth, id, current) {
2862
+ const events = current.endedEvents();
2863
+ if (!events) throw new SerovalUnsupportedTypeError(current);
2864
+ const values = events.values;
2865
+ const last = values.length - 1;
2866
+ const sequence = new Array(values.length);
2867
+ if (last >= 0) markParserRef(ctx.base, id);
2868
+ for (let i = 0; i <= last; i++) sequence[i] = createStreamEventNode(i < last ? 32 : events.success ? 34 : 33, id, parseSOS(ctx, depth, values[i]));
2869
+ return sequence;
2870
+ }
2839
2871
  function parseStream(ctx, depth, id, current) {
2840
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2841
- if (ctx.type === 2) ctx.state.stream(ctx, depth, id, current);
2842
- return result;
2872
+ const reference = parseSpecialReference(ctx.base, 4);
2873
+ if (ctx.type === 2) {
2874
+ const result = createStreamConstructorNode(id, reference, []);
2875
+ ctx.state.stream(ctx, depth, id, current);
2876
+ return result;
2877
+ }
2878
+ return createStreamConstructorNode(id, reference, parseEndedStream(ctx, depth, id, current));
2843
2879
  }
2844
2880
  function parseLiveStream(ctx, depth, id, current) {
2845
- const stream = ctx.type === 2;
2846
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], stream ? 1 : void 0);
2847
- if (stream) ctx.state.live(ctx, depth, id, current);
2881
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2882
+ const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1);
2883
+ ctx.state.live(ctx, depth, id, current);
2848
2884
  return result;
2849
2885
  }
2850
2886
  function parsePromise(ctx, depth, id, current) {
package/dist/index.cjs CHANGED
@@ -1002,6 +1002,20 @@ var Stream = class {
1002
1002
  }
1003
1003
  };
1004
1004
  }
1005
+ /**
1006
+ * Returns the events of a stream that has ended, without subscribing, so a
1007
+ * live receiver is not consumed. The last value is the `return` or `throw`
1008
+ * value. Returns `undefined` while the stream is open, or when a live
1009
+ * receiver was already consumed and has no events left.
1010
+ * @internal
1011
+ */
1012
+ endedEvents() {
1013
+ if (this.alive || this.live > 1) return void 0;
1014
+ return {
1015
+ values: this.buffer.slice(),
1016
+ success: this.success
1017
+ };
1018
+ }
1005
1019
  next(value) {
1006
1020
  if (this.alive) this.flush(value, "next");
1007
1021
  }
@@ -1673,8 +1687,10 @@ function guardIndexedValue(ctx, id) {
1673
1687
  function isThennable(value) {
1674
1688
  return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
1675
1689
  }
1690
+ const ignoreRejection = () => {};
1676
1691
  function assignIndexedValue$1(ctx, id, value) {
1677
1692
  guardIndexedValue(ctx.base, id);
1693
+ if (value instanceof Promise) value.catch(ignoreRejection);
1678
1694
  const marked = ctx.marked;
1679
1695
  if (!marked || marked.has(id)) ctx.base.refs.set(id, value);
1680
1696
  return value;
@@ -2784,9 +2800,10 @@ function parseProperties(ctx, depth, properties) {
2784
2800
  };
2785
2801
  }
2786
2802
  function parseAsyncIterable(ctx, depth, current) {
2803
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2787
2804
  const id = createIndexForValue(ctx.base, {});
2788
2805
  const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2789
- if (ctx.type === 2) ctx.state.iterable(ctx, depth, id, current);
2806
+ ctx.state.iterable(ctx, depth, id, current);
2790
2807
  return result;
2791
2808
  }
2792
2809
  function parsePlainObject(ctx, depth, id, current, empty) {
@@ -2821,15 +2838,34 @@ function parseSet(ctx, depth, id, current) {
2821
2838
  for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item);
2822
2839
  return createSetNode(id, items);
2823
2840
  }
2841
+ /**
2842
+ * Sends the events of a stream that has ended, so the copy gets all of them.
2843
+ * A stream that is still open throws, because the other sync modes cannot
2844
+ * send its later events.
2845
+ */
2846
+ function parseEndedStream(ctx, depth, id, current) {
2847
+ const events = current.endedEvents();
2848
+ if (!events) throw new SerovalUnsupportedTypeError(current);
2849
+ const values = events.values;
2850
+ const last = values.length - 1;
2851
+ const sequence = new Array(values.length);
2852
+ if (last >= 0) markParserRef(ctx.base, id);
2853
+ for (let i = 0; i <= last; i++) sequence[i] = createStreamEventNode(i < last ? 32 : events.success ? 34 : 33, id, parseSOS(ctx, depth, values[i]));
2854
+ return sequence;
2855
+ }
2824
2856
  function parseStream(ctx, depth, id, current) {
2825
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2826
- if (ctx.type === 2) ctx.state.stream(ctx, depth, id, current);
2827
- return result;
2857
+ const reference = parseSpecialReference(ctx.base, 4);
2858
+ if (ctx.type === 2) {
2859
+ const result = createStreamConstructorNode(id, reference, []);
2860
+ ctx.state.stream(ctx, depth, id, current);
2861
+ return result;
2862
+ }
2863
+ return createStreamConstructorNode(id, reference, parseEndedStream(ctx, depth, id, current));
2828
2864
  }
2829
2865
  function parseLiveStream(ctx, depth, id, current) {
2830
- const stream = ctx.type === 2;
2831
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], stream ? 1 : void 0);
2832
- if (stream) ctx.state.live(ctx, depth, id, current);
2866
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2867
+ const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1);
2868
+ ctx.state.live(ctx, depth, id, current);
2833
2869
  return result;
2834
2870
  }
2835
2871
  function parsePromise(ctx, depth, id, current) {
package/dist/index.d.cts CHANGED
@@ -418,6 +418,17 @@ export declare class Stream<T> {
418
418
  private flush;
419
419
  private replay;
420
420
  on(listener: StreamListener<T>): () => void;
421
+ /**
422
+ * Returns the events of a stream that has ended, without subscribing, so a
423
+ * live receiver is not consumed. The last value is the `return` or `throw`
424
+ * value. Returns `undefined` while the stream is open, or when a live
425
+ * receiver was already consumed and has no events left.
426
+ * @internal
427
+ */
428
+ endedEvents(): {
429
+ values: unknown[];
430
+ success: boolean;
431
+ } | undefined;
421
432
  next(value: T): void;
422
433
  throw(value: unknown): void;
423
434
  return(value: T): void;
package/dist/index.d.ts CHANGED
@@ -418,6 +418,17 @@ export declare class Stream<T> {
418
418
  private flush;
419
419
  private replay;
420
420
  on(listener: StreamListener<T>): () => void;
421
+ /**
422
+ * Returns the events of a stream that has ended, without subscribing, so a
423
+ * live receiver is not consumed. The last value is the `return` or `throw`
424
+ * value. Returns `undefined` while the stream is open, or when a live
425
+ * receiver was already consumed and has no events left.
426
+ * @internal
427
+ */
428
+ endedEvents(): {
429
+ values: unknown[];
430
+ success: boolean;
431
+ } | undefined;
421
432
  next(value: T): void;
422
433
  throw(value: unknown): void;
423
434
  return(value: T): void;
package/dist/index.js CHANGED
@@ -1001,6 +1001,20 @@ var Stream = class {
1001
1001
  }
1002
1002
  };
1003
1003
  }
1004
+ /**
1005
+ * Returns the events of a stream that has ended, without subscribing, so a
1006
+ * live receiver is not consumed. The last value is the `return` or `throw`
1007
+ * value. Returns `undefined` while the stream is open, or when a live
1008
+ * receiver was already consumed and has no events left.
1009
+ * @internal
1010
+ */
1011
+ endedEvents() {
1012
+ if (this.alive || this.live > 1) return void 0;
1013
+ return {
1014
+ values: this.buffer.slice(),
1015
+ success: this.success
1016
+ };
1017
+ }
1004
1018
  next(value) {
1005
1019
  if (this.alive) this.flush(value, "next");
1006
1020
  }
@@ -1672,8 +1686,10 @@ function guardIndexedValue(ctx, id) {
1672
1686
  function isThennable(value) {
1673
1687
  return !!value && (typeof value === "object" || typeof value === "function") && "then" in value && typeof value.then === "function";
1674
1688
  }
1689
+ const ignoreRejection = () => {};
1675
1690
  function assignIndexedValue$1(ctx, id, value) {
1676
1691
  guardIndexedValue(ctx.base, id);
1692
+ if (value instanceof Promise) value.catch(ignoreRejection);
1677
1693
  const marked = ctx.marked;
1678
1694
  if (!marked || marked.has(id)) ctx.base.refs.set(id, value);
1679
1695
  return value;
@@ -2783,9 +2799,10 @@ function parseProperties(ctx, depth, properties) {
2783
2799
  };
2784
2800
  }
2785
2801
  function parseAsyncIterable(ctx, depth, current) {
2802
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2786
2803
  const id = createIndexForValue(ctx.base, {});
2787
2804
  const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2788
- if (ctx.type === 2) ctx.state.iterable(ctx, depth, id, current);
2805
+ ctx.state.iterable(ctx, depth, id, current);
2789
2806
  return result;
2790
2807
  }
2791
2808
  function parsePlainObject(ctx, depth, id, current, empty) {
@@ -2820,15 +2837,34 @@ function parseSet(ctx, depth, id, current) {
2820
2837
  for (const item of current.keys()) items[i++] = parseSOS(ctx, depth, item);
2821
2838
  return createSetNode(id, items);
2822
2839
  }
2840
+ /**
2841
+ * Sends the events of a stream that has ended, so the copy gets all of them.
2842
+ * A stream that is still open throws, because the other sync modes cannot
2843
+ * send its later events.
2844
+ */
2845
+ function parseEndedStream(ctx, depth, id, current) {
2846
+ const events = current.endedEvents();
2847
+ if (!events) throw new SerovalUnsupportedTypeError(current);
2848
+ const values = events.values;
2849
+ const last = values.length - 1;
2850
+ const sequence = new Array(values.length);
2851
+ if (last >= 0) markParserRef(ctx.base, id);
2852
+ for (let i = 0; i <= last; i++) sequence[i] = createStreamEventNode(i < last ? 32 : events.success ? 34 : 33, id, parseSOS(ctx, depth, values[i]));
2853
+ return sequence;
2854
+ }
2823
2855
  function parseStream(ctx, depth, id, current) {
2824
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), []);
2825
- if (ctx.type === 2) ctx.state.stream(ctx, depth, id, current);
2826
- return result;
2856
+ const reference = parseSpecialReference(ctx.base, 4);
2857
+ if (ctx.type === 2) {
2858
+ const result = createStreamConstructorNode(id, reference, []);
2859
+ ctx.state.stream(ctx, depth, id, current);
2860
+ return result;
2861
+ }
2862
+ return createStreamConstructorNode(id, reference, parseEndedStream(ctx, depth, id, current));
2827
2863
  }
2828
2864
  function parseLiveStream(ctx, depth, id, current) {
2829
- const stream = ctx.type === 2;
2830
- const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], stream ? 1 : void 0);
2831
- if (stream) ctx.state.live(ctx, depth, id, current);
2865
+ if (ctx.type !== 2) throw new SerovalUnsupportedTypeError(current);
2866
+ const result = createStreamConstructorNode(id, parseSpecialReference(ctx.base, 4), [], 1);
2867
+ ctx.state.live(ctx, depth, id, current);
2832
2868
  return result;
2833
2869
  }
2834
2870
  function parsePromise(ctx, depth, id, current) {
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "seroval",
3
3
  "type": "module",
4
4
  "sideEffects": false,
5
- "version": "1.7.0",
5
+ "version": "1.7.2",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
@@ -18,14 +18,14 @@
18
18
  ],
19
19
  "devDependencies": {
20
20
  "@types/node": "^26.6.5",
21
- "@vitest/ui": "^5.0.4",
21
+ "@vitest/ui": "^5.0.5",
22
22
  "esbuild": "^0.28.2",
23
23
  "temporal-polyfill": "^1.0.6",
24
24
  "ts-prune": "^0.10.3",
25
25
  "tsdown": "^0.23.1",
26
26
  "tslib": "^2.8.1",
27
27
  "typescript": "^7.0.2",
28
- "vitest": "^5.0.4"
28
+ "vitest": "^5.0.5"
29
29
  },
30
30
  "private": false,
31
31
  "description": "Stringify JS values",