seroval 1.0.3 → 1.0.4

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.
Files changed (34) hide show
  1. package/dist/cjs/development/index.cjs +330 -225
  2. package/dist/cjs/development/index.cjs.map +3 -3
  3. package/dist/cjs/production/index.cjs +17 -3
  4. package/dist/esm/development/index.mjs +330 -225
  5. package/dist/esm/development/index.mjs.map +3 -3
  6. package/dist/esm/production/index.mjs +17 -3
  7. package/dist/types/core/base-primitives.d.ts.map +1 -1
  8. package/dist/types/core/context/deserializer.d.ts.map +1 -1
  9. package/dist/types/core/context/parser/async.d.ts.map +1 -1
  10. package/dist/types/core/context/parser/sync.d.ts.map +1 -1
  11. package/dist/types/core/context/parser.d.ts.map +1 -1
  12. package/dist/types/core/context/serializer.d.ts.map +1 -1
  13. package/dist/types/core/errors.d.ts +38 -0
  14. package/dist/types/core/errors.d.ts.map +1 -0
  15. package/dist/types/core/reference.d.ts.map +1 -1
  16. package/dist/types/core/tree/serializer.d.ts.map +1 -1
  17. package/dist/types/core/utils/typed-array.d.ts.map +1 -1
  18. package/dist/types/index.d.ts +1 -0
  19. package/dist/types/index.d.ts.map +1 -1
  20. package/package.json +2 -2
  21. package/src/core/base-primitives.ts +0 -5
  22. package/src/core/context/deserializer.ts +86 -76
  23. package/src/core/context/parser/async.ts +30 -26
  24. package/src/core/context/parser/sync.ts +30 -26
  25. package/src/core/context/parser.ts +3 -10
  26. package/src/core/context/serializer.ts +104 -95
  27. package/src/core/errors.ts +99 -0
  28. package/src/core/reference.ts +6 -2
  29. package/src/core/tree/serializer.ts +4 -3
  30. package/src/core/utils/typed-array.ts +3 -1
  31. package/src/index.ts +1 -0
  32. package/dist/types/core/UnsupportedTypeError.d.ts +0 -5
  33. package/dist/types/core/UnsupportedTypeError.d.ts.map +0 -1
  34. package/src/core/UnsupportedTypeError.ts +0 -7
@@ -6,6 +6,11 @@ import {
6
6
  SerovalNodeType,
7
7
  SerovalObjectFlags,
8
8
  } from '../constants';
9
+ import {
10
+ SerovalMissingPluginError,
11
+ SerovalSerializationError,
12
+ SerovalUnsupportedNodeError,
13
+ } from '../errors';
9
14
  import { REFERENCES_KEY } from '../keys';
10
15
  import type { Plugin, PluginAccessOptions, SerovalMode } from '../plugin';
11
16
  import { SpecialReference } from '../special-reference';
@@ -446,19 +451,19 @@ export default abstract class BaseSerializerContext
446
451
  ): string {
447
452
  if (typeof key === 'string') {
448
453
  const check = Number(key);
449
- const isIdentifier = (
454
+ const isIdentifier =
450
455
  // Test if key is a valid positive number or JS identifier
451
456
  // so that we don't have to serialize the key and wrap with brackets
452
- check >= 0
453
- // It's also important to consider that if the key is
454
- // indeed numeric, we need to make sure that when
455
- // converted back into a string, it's still the same
456
- // to the original key. This allows us to differentiate
457
- // keys that has numeric formats but in a different
458
- // format, which can cause unintentional key declaration
459
- // Example: { 0x1: 1 } vs { '0x1': 1 }
460
- && check.toString() === key
461
- ) || isValidIdentifier(key);
457
+ (check >= 0 &&
458
+ // It's also important to consider that if the key is
459
+ // indeed numeric, we need to make sure that when
460
+ // converted back into a string, it's still the same
461
+ // to the original key. This allows us to differentiate
462
+ // keys that has numeric formats but in a different
463
+ // format, which can cause unintentional key declaration
464
+ // Example: { 0x1: 1 } vs { '0x1': 1 }
465
+ check.toString() === key) ||
466
+ isValidIdentifier(key);
462
467
  if (this.isIndexedValueInStack(val)) {
463
468
  const refParam = this.getRefParam((val as SerovalIndexedValueNode).i);
464
469
  this.markRef(source.i);
@@ -528,19 +533,19 @@ export default abstract class BaseSerializerContext
528
533
  ): void {
529
534
  const serialized = this.serialize(value);
530
535
  const check = Number(key);
531
- const isIdentifier = (
536
+ const isIdentifier =
532
537
  // Test if key is a valid positive number or JS identifier
533
538
  // so that we don't have to serialize the key and wrap with brackets
534
- check >= 0
535
- // It's also important to consider that if the key is
536
- // indeed numeric, we need to make sure that when
537
- // converted back into a string, it's still the same
538
- // to the original key. This allows us to differentiate
539
- // keys that has numeric formats but in a different
540
- // format, which can cause unintentional key declaration
541
- // Example: { 0x1: 1 } vs { '0x1': 1 }
542
- && check.toString() === key
543
- ) || isValidIdentifier(key);
539
+ (check >= 0 &&
540
+ // It's also important to consider that if the key is
541
+ // indeed numeric, we need to make sure that when
542
+ // converted back into a string, it's still the same
543
+ // to the original key. This allows us to differentiate
544
+ // keys that has numeric formats but in a different
545
+ // format, which can cause unintentional key declaration
546
+ // Example: { 0x1: 1 } vs { '0x1': 1 }
547
+ check.toString() === key) ||
548
+ isValidIdentifier(key);
544
549
  if (this.isIndexedValueInStack(value)) {
545
550
  // Strict identifier check, make sure
546
551
  // that it isn't numeric (except NaN)
@@ -899,7 +904,7 @@ export default abstract class BaseSerializerContext
899
904
  }
900
905
  }
901
906
  }
902
- throw new Error('Missing plugin for tag "' + node.c + '".');
907
+ throw new SerovalMissingPluginError(node.c);
903
908
  }
904
909
 
905
910
  private getConstructor(node: SerovalNodeWithID): string {
@@ -1155,78 +1160,82 @@ export default abstract class BaseSerializerContext
1155
1160
  }
1156
1161
 
1157
1162
  serialize(node: SerovalNode): string {
1158
- switch (node.t) {
1159
- case SerovalNodeType.Constant:
1160
- return CONSTANT_STRING[node.s];
1161
- case SerovalNodeType.Number:
1162
- return '' + node.s;
1163
- case SerovalNodeType.String:
1164
- return '"' + node.s + '"';
1165
- case SerovalNodeType.BigInt:
1166
- return node.s + 'n';
1167
- case SerovalNodeType.IndexedValue:
1168
- return this.getRefParam(node.i);
1169
- case SerovalNodeType.Reference:
1170
- return this.serializeReference(node);
1171
- case SerovalNodeType.Array:
1172
- return this.serializeArray(node);
1173
- case SerovalNodeType.Object:
1174
- return this.serializeObject(node);
1175
- case SerovalNodeType.NullConstructor:
1176
- return this.serializeNullConstructor(node);
1177
- case SerovalNodeType.Date:
1178
- return this.serializeDate(node);
1179
- case SerovalNodeType.RegExp:
1180
- return this.serializeRegExp(node);
1181
- case SerovalNodeType.Set:
1182
- return this.serializeSet(node);
1183
- case SerovalNodeType.Map:
1184
- return this.serializeMap(node);
1185
- case SerovalNodeType.ArrayBuffer:
1186
- return this.serializeArrayBuffer(node);
1187
- case SerovalNodeType.BigIntTypedArray:
1188
- case SerovalNodeType.TypedArray:
1189
- return this.serializeTypedArray(node);
1190
- case SerovalNodeType.DataView:
1191
- return this.serializeDataView(node);
1192
- case SerovalNodeType.AggregateError:
1193
- return this.serializeAggregateError(node);
1194
- case SerovalNodeType.Error:
1195
- return this.serializeError(node);
1196
- case SerovalNodeType.Promise:
1197
- return this.serializePromise(node);
1198
- case SerovalNodeType.WKSymbol:
1199
- return this.serializeWellKnownSymbol(node);
1200
- case SerovalNodeType.Boxed:
1201
- return this.serializeBoxed(node);
1202
- case SerovalNodeType.PromiseConstructor:
1203
- return this.serializePromiseConstructor(node);
1204
- case SerovalNodeType.PromiseResolve:
1205
- return this.serializePromiseResolve(node);
1206
- case SerovalNodeType.PromiseReject:
1207
- return this.serializePromiseReject(node);
1208
- case SerovalNodeType.Plugin:
1209
- return this.serializePlugin(node);
1210
- case SerovalNodeType.SpecialReference:
1211
- return this.serializeSpecialReference(node);
1212
- case SerovalNodeType.IteratorFactory:
1213
- return this.serializeIteratorFactory(node);
1214
- case SerovalNodeType.IteratorFactoryInstance:
1215
- return this.serializeIteratorFactoryInstance(node);
1216
- case SerovalNodeType.AsyncIteratorFactory:
1217
- return this.serializeAsyncIteratorFactory(node);
1218
- case SerovalNodeType.AsyncIteratorFactoryInstance:
1219
- return this.serializeAsyncIteratorFactoryInstance(node);
1220
- case SerovalNodeType.StreamConstructor:
1221
- return this.serializeStreamConstructor(node);
1222
- case SerovalNodeType.StreamNext:
1223
- return this.serializeStreamNext(node);
1224
- case SerovalNodeType.StreamThrow:
1225
- return this.serializeStreamThrow(node);
1226
- case SerovalNodeType.StreamReturn:
1227
- return this.serializeStreamReturn(node);
1228
- default:
1229
- throw new Error('invariant');
1163
+ try {
1164
+ switch (node.t) {
1165
+ case SerovalNodeType.Constant:
1166
+ return CONSTANT_STRING[node.s];
1167
+ case SerovalNodeType.Number:
1168
+ return '' + node.s;
1169
+ case SerovalNodeType.String:
1170
+ return '"' + node.s + '"';
1171
+ case SerovalNodeType.BigInt:
1172
+ return node.s + 'n';
1173
+ case SerovalNodeType.IndexedValue:
1174
+ return this.getRefParam(node.i);
1175
+ case SerovalNodeType.Reference:
1176
+ return this.serializeReference(node);
1177
+ case SerovalNodeType.Array:
1178
+ return this.serializeArray(node);
1179
+ case SerovalNodeType.Object:
1180
+ return this.serializeObject(node);
1181
+ case SerovalNodeType.NullConstructor:
1182
+ return this.serializeNullConstructor(node);
1183
+ case SerovalNodeType.Date:
1184
+ return this.serializeDate(node);
1185
+ case SerovalNodeType.RegExp:
1186
+ return this.serializeRegExp(node);
1187
+ case SerovalNodeType.Set:
1188
+ return this.serializeSet(node);
1189
+ case SerovalNodeType.Map:
1190
+ return this.serializeMap(node);
1191
+ case SerovalNodeType.ArrayBuffer:
1192
+ return this.serializeArrayBuffer(node);
1193
+ case SerovalNodeType.BigIntTypedArray:
1194
+ case SerovalNodeType.TypedArray:
1195
+ return this.serializeTypedArray(node);
1196
+ case SerovalNodeType.DataView:
1197
+ return this.serializeDataView(node);
1198
+ case SerovalNodeType.AggregateError:
1199
+ return this.serializeAggregateError(node);
1200
+ case SerovalNodeType.Error:
1201
+ return this.serializeError(node);
1202
+ case SerovalNodeType.Promise:
1203
+ return this.serializePromise(node);
1204
+ case SerovalNodeType.WKSymbol:
1205
+ return this.serializeWellKnownSymbol(node);
1206
+ case SerovalNodeType.Boxed:
1207
+ return this.serializeBoxed(node);
1208
+ case SerovalNodeType.PromiseConstructor:
1209
+ return this.serializePromiseConstructor(node);
1210
+ case SerovalNodeType.PromiseResolve:
1211
+ return this.serializePromiseResolve(node);
1212
+ case SerovalNodeType.PromiseReject:
1213
+ return this.serializePromiseReject(node);
1214
+ case SerovalNodeType.Plugin:
1215
+ return this.serializePlugin(node);
1216
+ case SerovalNodeType.SpecialReference:
1217
+ return this.serializeSpecialReference(node);
1218
+ case SerovalNodeType.IteratorFactory:
1219
+ return this.serializeIteratorFactory(node);
1220
+ case SerovalNodeType.IteratorFactoryInstance:
1221
+ return this.serializeIteratorFactoryInstance(node);
1222
+ case SerovalNodeType.AsyncIteratorFactory:
1223
+ return this.serializeAsyncIteratorFactory(node);
1224
+ case SerovalNodeType.AsyncIteratorFactoryInstance:
1225
+ return this.serializeAsyncIteratorFactoryInstance(node);
1226
+ case SerovalNodeType.StreamConstructor:
1227
+ return this.serializeStreamConstructor(node);
1228
+ case SerovalNodeType.StreamNext:
1229
+ return this.serializeStreamNext(node);
1230
+ case SerovalNodeType.StreamThrow:
1231
+ return this.serializeStreamThrow(node);
1232
+ case SerovalNodeType.StreamReturn:
1233
+ return this.serializeStreamReturn(node);
1234
+ default:
1235
+ throw new SerovalUnsupportedNodeError(node);
1236
+ }
1237
+ } catch (error) {
1238
+ throw new SerovalSerializationError(error);
1230
1239
  }
1231
1240
  }
1232
1241
  }
@@ -0,0 +1,99 @@
1
+ import { serializeString } from './string';
2
+ import { SerovalNode } from './types';
3
+
4
+ const { toString: objectToString } = /* @__PURE__ */ Object.prototype;
5
+
6
+ function getErrorMessage(type: string, cause: any): string {
7
+ if (cause instanceof Error) {
8
+ return `Seroval caught an error during the ${type} process.
9
+
10
+ ${cause.name}
11
+ ${cause.message}
12
+
13
+ - For more information, please check the "cause" property of this error.
14
+ - If you believe this is an error in Seroval, please submit an issue at https://github.com/lxsmnsyc/seroval/issues/new`;
15
+ }
16
+ return `Seroval caught an error during the ${type} process.
17
+
18
+ "${objectToString.call(cause)}"
19
+
20
+ For more information, please check the "cause" property of this error.`;
21
+ }
22
+
23
+ export class SerovalError extends Error {
24
+ constructor(type: string, public cause: any) {
25
+ super(getErrorMessage(type, cause));
26
+ }
27
+ }
28
+
29
+ export class SerovalParserError extends SerovalError {
30
+ constructor(cause: any) {
31
+ super('parsing', cause);
32
+ }
33
+ }
34
+
35
+ export class SerovalSerializationError extends SerovalError {
36
+ constructor(cause: any) {
37
+ super('serialization', cause);
38
+ }
39
+ }
40
+
41
+ export class SerovalDeserializationError extends SerovalError {
42
+ constructor(cause: any) {
43
+ super('deserialization', cause);
44
+ }
45
+ }
46
+
47
+ export class SerovalUnsupportedTypeError extends Error {
48
+ constructor(public value: unknown) {
49
+ super(
50
+ `The value ${objectToString.call(value)} of type "${typeof value}" cannot be parsed/serialized.
51
+
52
+ There are few workarounds for this problem:
53
+ - Transform the value in a way that it can be serialized.
54
+ - If the reference is present on multiple runtimes (isomorphic), you can use the Reference API to map the references.`,
55
+ );
56
+ }
57
+ }
58
+
59
+ export class SerovalUnsupportedNodeError extends Error {
60
+ constructor(node: SerovalNode) {
61
+ super('Unsupported node type "' + node.t + '".');
62
+ }
63
+ }
64
+
65
+ export class SerovalMissingPluginError extends Error {
66
+ constructor(tag: string) {
67
+ super('Missing plugin for tag "' + tag + '".');
68
+ }
69
+ }
70
+
71
+ export class SerovalMissingInstanceError extends Error {
72
+ constructor(tag: string) {
73
+ super('Missing "' + tag + '" instance.');
74
+ }
75
+ }
76
+
77
+ export class SerovalMissingReferenceError extends Error {
78
+ constructor(public value: unknown) {
79
+ super(
80
+ 'Missing reference for the value "' +
81
+ objectToString.call(value) +
82
+ '" of type "' +
83
+ typeof value +
84
+ '"',
85
+ );
86
+ }
87
+ }
88
+
89
+ export class SerovalMissingReferenceForIdError extends Error {
90
+ constructor(id: string) {
91
+ super('Missing reference for id "' + serializeString(id) + '"');
92
+ }
93
+ }
94
+
95
+ export class SerovalUnknownTypedArrayError extends Error {
96
+ constructor(name: string) {
97
+ super('Unknown TypedArray "' + name + '"');
98
+ }
99
+ }
@@ -1,5 +1,9 @@
1
1
  import assert from './utils/assert';
2
2
  import { REFERENCES_KEY } from './keys';
3
+ import {
4
+ SerovalMissingReferenceError,
5
+ SerovalMissingReferenceForIdError,
6
+ } from '..';
3
7
 
4
8
  const REFERENCE = new Map<unknown, string>();
5
9
  const INV_REFERENCE = new Map<string, unknown>();
@@ -19,12 +23,12 @@ export function hasReference(id: string): boolean {
19
23
  }
20
24
 
21
25
  export function getReferenceID<T>(value: T): string {
22
- assert(hasReferenceID(value), new Error('Missing reference id'));
26
+ assert(hasReferenceID(value), new SerovalMissingReferenceError(value));
23
27
  return REFERENCE.get(value)!;
24
28
  }
25
29
 
26
30
  export function getReference<T>(id: string): T {
27
- assert(hasReference(id), new Error('Missing reference for id:' + id));
31
+ assert(hasReference(id), new SerovalMissingReferenceForIdError(id));
28
32
  return INV_REFERENCE.get(id) as T;
29
33
  }
30
34
 
@@ -9,6 +9,7 @@ import BaseSerializerContext from '../context/serializer';
9
9
  import getIdentifier from '../utils/get-identifier';
10
10
  import type { SerovalMode } from '../plugin';
11
11
  import { SerovalNodeType } from '../constants';
12
+ import { SerovalUnsupportedNodeError } from '../errors';
12
13
 
13
14
  export type VanillaSerializerContextOptions = BaseSerializerContextOptions;
14
15
 
@@ -61,15 +62,15 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
61
62
  protected serializePromiseConstructor(
62
63
  node: SerovalPromiseConstructorNode,
63
64
  ): string {
64
- throw new Error('Unsupported node type "' + node.t + '".');
65
+ throw new SerovalUnsupportedNodeError(node);
65
66
  }
66
67
 
67
68
  protected serializePromiseResolve(node: SerovalPromiseResolveNode): string {
68
- throw new Error('Unsupported node type "' + node.t + '".');
69
+ throw new SerovalUnsupportedNodeError(node);
69
70
  }
70
71
 
71
72
  protected serializePromiseReject(node: SerovalPromiseRejectNode): string {
72
- throw new Error('Unsupported node type "' + node.t + '".');
73
+ throw new SerovalUnsupportedNodeError(node);
73
74
  }
74
75
 
75
76
  serializeTop(tree: SerovalNode): string {
@@ -1,3 +1,5 @@
1
+ import { SerovalUnknownTypedArrayError } from '../errors';
2
+
1
3
  type TypedArrayConstructor =
2
4
  | Int8ArrayConstructor
3
5
  | Int16ArrayConstructor
@@ -49,6 +51,6 @@ export function getTypedArrayConstructor(name: string): TypedArrayConstructor {
49
51
  case 'BigUint64Array':
50
52
  return BigUint64Array;
51
53
  default:
52
- throw new Error(`Unknown TypedArray "${name}"`);
54
+ throw new SerovalUnknownTypedArrayError(name);
53
55
  }
54
56
  }
package/src/index.ts CHANGED
@@ -13,3 +13,4 @@ export type { Stream } from './core/stream';
13
13
  export { createStream } from './core/stream';
14
14
 
15
15
  export type { SerovalNode } from './core/types';
16
+ export * from './core/errors';
@@ -1,5 +0,0 @@
1
- export default class UnsupportedTypeError extends Error {
2
- value: unknown;
3
- constructor(value: unknown);
4
- }
5
- //# sourceMappingURL=UnsupportedTypeError.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"UnsupportedTypeError.d.ts","sourceRoot":"","sources":["../../../src/core/UnsupportedTypeError.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,OAAO,OAAO,oBAAqB,SAAQ,KAAK;IAClC,KAAK,EAAE,OAAO;gBAAd,KAAK,EAAE,OAAO;CAGlC"}
@@ -1,7 +0,0 @@
1
- const { toString: objectToString } = /* @__PURE__ */ Object.prototype;
2
-
3
- export default class UnsupportedTypeError extends Error {
4
- constructor(public value: unknown) {
5
- super('Unsupported type "' + objectToString.call(value) + '"');
6
- }
7
- }