seroval 0.4.1 → 0.5.1

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.
@@ -14,7 +14,7 @@ export declare const enum Feature {
14
14
  ObjectAssign = 128,
15
15
  Promise = 256,
16
16
  Set = 512,
17
- SymbolIterator = 1024,
17
+ Symbol = 1024,
18
18
  TypedArray = 2048,
19
19
  BigIntTypedArray = 4096
20
20
  }
@@ -1,3 +1,4 @@
1
+ import { AsyncServerValue } from './types';
1
2
  interface IndexAssignment {
2
3
  t: 'index';
3
4
  s: string;
@@ -30,6 +31,7 @@ export interface SerializationContext {
30
31
  vars: string[];
31
32
  assignments: Assignment[];
32
33
  features: number;
34
+ valueMap: Map<number, AsyncServerValue>;
33
35
  }
34
36
  export interface Options {
35
37
  disabledFeatures: number;
@@ -49,8 +51,6 @@ export declare function markRef(ctx: ParserContext | SerializationContext, curre
49
51
  * Calling this function means the value has been referenced somewhere
50
52
  */
51
53
  export declare function getRefParam(ctx: SerializationContext, index: number): string;
52
- /**
53
- * Creates a reference ID from the given values
54
- */
55
- export declare function createRef(ctx: ParserContext, current: unknown, mark: boolean): number;
54
+ export declare function getRootID(ctx: ParserContext, current: AsyncServerValue): number;
55
+ export declare function createRef(ctx: ParserContext, current: AsyncServerValue): number;
56
56
  export {};
@@ -1 +1,2 @@
1
1
  export default function quote(str: string): string;
2
+ export declare function invQuote(str: string): string;
@@ -0,0 +1,4 @@
1
+ import { SerializationContext } from '../context';
2
+ import { AsyncServerValue } from '../types';
3
+ import { SerovalNode } from './types';
4
+ export default function deserializeTree(ctx: SerializationContext, node: SerovalNode): AsyncServerValue;
@@ -1,17 +1,21 @@
1
1
  import { ParserContext } from '../context';
2
2
  import { BigIntTypedArrayValue, TypedArrayValue } from '../types';
3
- import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalDateNode, SerovalPrimitiveNode, SerovalReferenceNode, SerovalRegExpNode, SerovalTypedArrayNode } from './types';
4
- export declare function createPrimitiveNode(value: string | number | null): SerovalPrimitiveNode;
5
- export declare const TRUE_NODE: SerovalPrimitiveNode;
6
- export declare const FALSE_NODE: SerovalPrimitiveNode;
7
- export declare const UNDEFINED_NODE: SerovalPrimitiveNode;
8
- export declare const NULL_NODE: SerovalPrimitiveNode;
9
- export declare const NEG_ZERO_NODE: SerovalPrimitiveNode;
10
- export declare const INFINITY_NODE: SerovalPrimitiveNode;
11
- export declare const NEG_INFINITY_NODE: SerovalPrimitiveNode;
3
+ import { WellKnownSymbols } from './symbols';
4
+ import { SerovalBigIntNode, SerovalBigIntTypedArrayNode, SerovalBooleanNode, SerovalDateNode, SerovalInfinityNode, SerovalNaNNode, SerovalNegativeInfinityNode, SerovalNegativeZeroNode, SerovalNullNode, SerovalNumberNode, SerovalReferenceNode, SerovalRegExpNode, SerovalStringNode, SerovalTypedArrayNode, SerovalUndefinedNode, SerovalWKSymbolNode } from './types';
5
+ export declare const TRUE_NODE: SerovalBooleanNode;
6
+ export declare const FALSE_NODE: SerovalBooleanNode;
7
+ export declare const UNDEFINED_NODE: SerovalUndefinedNode;
8
+ export declare const NULL_NODE: SerovalNullNode;
9
+ export declare const NEG_ZERO_NODE: SerovalNegativeZeroNode;
10
+ export declare const INFINITY_NODE: SerovalInfinityNode;
11
+ export declare const NEG_INFINITY_NODE: SerovalNegativeInfinityNode;
12
+ export declare const NAN_NODE: SerovalNaNNode;
13
+ export declare function createNumberNode(value: number): SerovalNumberNode;
14
+ export declare function createStringNode(value: string): SerovalStringNode;
12
15
  export declare function createBigIntNode(ctx: ParserContext, current: bigint): SerovalBigIntNode;
13
16
  export declare function createReferenceNode(id: number): SerovalReferenceNode;
14
17
  export declare function createDateNode(id: number, current: Date): SerovalDateNode;
15
18
  export declare function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode;
16
19
  export declare function createTypedArrayNode(ctx: ParserContext, id: number, current: TypedArrayValue): SerovalTypedArrayNode;
17
20
  export declare function createBigIntTypedArrayNode(ctx: ParserContext, id: number, current: BigIntTypedArrayValue): SerovalBigIntTypedArrayNode;
21
+ export declare function createWKSymbolNode(current: WellKnownSymbols): SerovalWKSymbolNode;
@@ -1,6 +1,9 @@
1
1
  import { ParserContext } from '../context';
2
2
  import { AsyncServerValue, ErrorValue } from '../types';
3
- export declare function getErrorConstructor(error: ErrorValue): "EvalError" | "RangeError" | "ReferenceError" | "SyntaxError" | "TypeError" | "URIError" | "Error";
3
+ export declare function getErrorConstructorName(error: ErrorValue): "EvalError" | "RangeError" | "ReferenceError" | "SyntaxError" | "TypeError" | "URIError" | "Error";
4
+ export declare function getErrorConstructor(errorName: string): ErrorConstructor;
4
5
  export declare function getErrorOptions(ctx: ParserContext, error: Error): Record<string, any> | undefined;
5
6
  export declare function getIterableOptions(obj: Iterable<any>): Record<string, unknown> | undefined;
6
7
  export declare function isIterable(value: unknown): value is Iterable<AsyncServerValue>;
8
+ export declare function getTypedArrayConstructor(name: string): Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor | BigInt64ArrayConstructor | BigUint64ArrayConstructor;
9
+ export declare function isValidIdentifier(name: string): boolean;
@@ -0,0 +1,33 @@
1
+ export declare const enum Symbols {
2
+ AsyncIterator = 0,
3
+ HasInstance = 1,
4
+ IsConcatSpreadable = 2,
5
+ Iterator = 3,
6
+ Match = 4,
7
+ MatchAll = 5,
8
+ Replace = 6,
9
+ Search = 7,
10
+ Species = 8,
11
+ Split = 9,
12
+ ToPrimitive = 10,
13
+ ToStringTag = 11,
14
+ Unscopables = 12
15
+ }
16
+ export declare const SYMBOL_STRING: Record<Symbols, string>;
17
+ export declare const INV_SYMBOL_REF: {
18
+ [Symbol.asyncIterator]: Symbols;
19
+ [Symbol.hasInstance]: Symbols;
20
+ [Symbol.isConcatSpreadable]: Symbols;
21
+ [Symbol.iterator]: Symbols;
22
+ [Symbol.match]: Symbols;
23
+ [Symbol.matchAll]: Symbols;
24
+ [Symbol.replace]: Symbols;
25
+ [Symbol.search]: Symbols;
26
+ [Symbol.species]: Symbols;
27
+ [Symbol.split]: Symbols;
28
+ [Symbol.toPrimitive]: Symbols;
29
+ [Symbol.toStringTag]: Symbols;
30
+ [Symbol.unscopables]: Symbols;
31
+ };
32
+ export type WellKnownSymbols = keyof typeof INV_SYMBOL_REF;
33
+ export declare const SYMBOL_REF: Record<Symbols, WellKnownSymbols>;
@@ -1,32 +1,41 @@
1
- import { PrimitiveValue } from '../types';
1
+ import { Symbols } from './symbols';
2
2
  export declare const enum SerovalNodeType {
3
- Primitive = 0,
4
- BigInt = 1,
5
- Reference = 2,
6
- Date = 3,
7
- RegExp = 4,
8
- Set = 5,
9
- Map = 6,
10
- Array = 7,
11
- Object = 8,
12
- NullConstructor = 9,
13
- Promise = 10,
14
- Error = 11,
15
- AggregateError = 12,
16
- Iterable = 13,
17
- TypedArray = 14,
18
- BigIntTypedArray = 15
3
+ Number = 0,
4
+ String = 1,
5
+ Boolean = 2,
6
+ Null = 3,
7
+ Undefined = 4,
8
+ NegativeZero = 5,
9
+ Infinity = 6,
10
+ NegativeInfinity = 7,
11
+ NaN = 8,
12
+ BigInt = 9,
13
+ Reference = 10,
14
+ Date = 11,
15
+ RegExp = 12,
16
+ Set = 13,
17
+ Map = 14,
18
+ Array = 15,
19
+ Object = 16,
20
+ NullConstructor = 17,
21
+ Promise = 18,
22
+ Error = 19,
23
+ AggregateError = 20,
24
+ Iterable = 21,
25
+ TypedArray = 22,
26
+ BigIntTypedArray = 23,
27
+ WKSymbol = 24
19
28
  }
20
29
  export interface SerovalBaseNode {
21
30
  t: SerovalNodeType;
22
- s: PrimitiveValue | undefined;
23
31
  i: number | undefined;
32
+ s: any;
24
33
  l: number | undefined;
25
34
  c: string | undefined;
26
- d: SerovalDictionaryNode | undefined;
27
35
  m: string | undefined;
28
- n: SerovalNode | undefined;
36
+ d: SerovalDictionaryNode | undefined;
29
37
  a: SerovalNode[] | undefined;
38
+ f: SerovalNode | undefined;
30
39
  }
31
40
  export interface SerovalObjectRecordNode {
32
41
  k: string[];
@@ -39,9 +48,37 @@ export interface SerovalMapRecordNode {
39
48
  s: number;
40
49
  }
41
50
  export type SerovalDictionaryNode = SerovalObjectRecordNode | SerovalMapRecordNode;
42
- export interface SerovalPrimitiveNode extends SerovalBaseNode {
43
- t: SerovalNodeType.Primitive;
51
+ export interface SerovalNumberNode extends SerovalBaseNode {
52
+ t: SerovalNodeType.Number;
53
+ s: number;
54
+ }
55
+ export interface SerovalStringNode extends SerovalBaseNode {
56
+ t: SerovalNodeType.String;
57
+ s: string;
58
+ }
59
+ export interface SerovalBooleanNode extends SerovalBaseNode {
60
+ t: SerovalNodeType.Boolean;
61
+ s: boolean;
62
+ }
63
+ export interface SerovalNullNode extends SerovalBaseNode {
64
+ t: SerovalNodeType.Null;
65
+ }
66
+ export interface SerovalUndefinedNode extends SerovalBaseNode {
67
+ t: SerovalNodeType.Undefined;
68
+ }
69
+ export interface SerovalNegativeZeroNode extends SerovalBaseNode {
70
+ t: SerovalNodeType.NegativeZero;
71
+ }
72
+ export interface SerovalInfinityNode extends SerovalBaseNode {
73
+ t: SerovalNodeType.Infinity;
74
+ }
75
+ export interface SerovalNegativeInfinityNode extends SerovalBaseNode {
76
+ t: SerovalNodeType.NegativeInfinity;
77
+ }
78
+ export interface SerovalNaNNode extends SerovalBaseNode {
79
+ t: SerovalNodeType.NaN;
44
80
  }
81
+ export type SerovalPrimitiveNode = SerovalNumberNode | SerovalStringNode | SerovalBooleanNode | SerovalNullNode | SerovalUndefinedNode | SerovalNegativeZeroNode | SerovalNegativeInfinityNode | SerovalInfinityNode | SerovalNaNNode;
45
82
  export interface SerovalReferenceNode extends SerovalBaseNode {
46
83
  t: SerovalNodeType.Reference;
47
84
  i: number;
@@ -58,25 +95,27 @@ export interface SerovalDateNode extends SerovalBaseNode {
58
95
  export interface SerovalRegExpNode extends SerovalBaseNode {
59
96
  t: SerovalNodeType.RegExp;
60
97
  i: number;
61
- s: string;
98
+ c: string;
99
+ m: string;
62
100
  }
63
101
  export interface SerovalTypedArrayNode extends SerovalBaseNode {
64
102
  t: SerovalNodeType.TypedArray;
65
103
  i: number;
66
- s: string;
104
+ s: string[];
67
105
  l: number;
68
106
  c: string;
69
107
  }
70
108
  export interface SerovalBigIntTypedArrayNode extends SerovalBaseNode {
71
109
  t: SerovalNodeType.BigIntTypedArray;
72
110
  i: number;
73
- s: string;
111
+ s: string[];
74
112
  l: number;
75
113
  c: string;
76
114
  }
77
115
  export type SerovalSemiPrimitiveNode = SerovalBigIntNode | SerovalDateNode | SerovalRegExpNode | SerovalTypedArrayNode | SerovalBigIntTypedArrayNode;
78
116
  export interface SerovalSetNode extends SerovalBaseNode {
79
117
  t: SerovalNodeType.Set;
118
+ l: number;
80
119
  a: SerovalNode[];
81
120
  i: number;
82
121
  }
@@ -87,6 +126,7 @@ export interface SerovalMapNode extends SerovalBaseNode {
87
126
  }
88
127
  export interface SerovalArrayNode extends SerovalBaseNode {
89
128
  t: SerovalNodeType.Array;
129
+ l: number;
90
130
  a: SerovalNode[];
91
131
  i: number;
92
132
  }
@@ -102,7 +142,7 @@ export interface SerovalNullConstructorNode extends SerovalBaseNode {
102
142
  }
103
143
  export interface SerovalPromiseNode extends SerovalBaseNode {
104
144
  t: SerovalNodeType.Promise;
105
- n: SerovalNode;
145
+ f: SerovalNode;
106
146
  i: number;
107
147
  }
108
148
  export interface SerovalErrorNode extends SerovalBaseNode {
@@ -116,13 +156,19 @@ export interface SerovalAggregateErrorNode extends SerovalBaseNode {
116
156
  t: SerovalNodeType.AggregateError;
117
157
  m: string;
118
158
  d: SerovalObjectRecordNode | undefined;
119
- n: SerovalNode;
159
+ l: number;
160
+ a: SerovalNode[];
120
161
  i: number;
121
162
  }
122
163
  export interface SerovalIterableNode extends SerovalBaseNode {
123
164
  t: SerovalNodeType.Iterable;
124
165
  d: SerovalObjectRecordNode | undefined;
166
+ l: number;
125
167
  a: SerovalNode[];
126
168
  i: number;
127
169
  }
128
- export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode;
170
+ export interface SerovalWKSymbolNode extends SerovalBaseNode {
171
+ t: SerovalNodeType.WKSymbol;
172
+ s: Symbols;
173
+ }
174
+ export type SerovalNode = SerovalPrimitiveNode | SerovalReferenceNode | SerovalSemiPrimitiveNode | SerovalSetNode | SerovalMapNode | SerovalArrayNode | SerovalObjectNode | SerovalNullConstructorNode | SerovalPromiseNode | SerovalErrorNode | SerovalAggregateErrorNode | SerovalIterableNode | SerovalWKSymbolNode;
@@ -1,4 +1,5 @@
1
- export type PrimitiveValue = boolean | string | number | undefined | null;
1
+ import { WellKnownSymbols } from './tree/symbols';
2
+ export type PrimitiveValue = boolean | string | number | undefined | null | WellKnownSymbols;
2
3
  export type ErrorValue = Error | AggregateError | EvalError | RangeError | ReferenceError | TypeError | SyntaxError | URIError;
3
4
  export type TypedArrayValue = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
4
5
  export type BigIntTypedArrayValue = BigInt64Array | BigUint64Array;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "0.4.1",
4
+ "version": "0.5.1",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
@@ -14,10 +14,10 @@
14
14
  "pridepack"
15
15
  ],
16
16
  "devDependencies": {
17
- "@types/node": "^18.11.18",
17
+ "@types/node": "^18.15.3",
18
18
  "eslint": "^8.32.0",
19
19
  "eslint-config-lxsmnsyc": "^0.4.8",
20
- "pridepack": "2.4.0",
20
+ "pridepack": "2.4.1",
21
21
  "tslib": "^2.4.1",
22
22
  "typescript": "^4.9.4",
23
23
  "vitest": "^0.28.1"
@@ -64,5 +64,5 @@
64
64
  "typesVersions": {
65
65
  "*": {}
66
66
  },
67
- "gitHead": "a3cfb8eae6e1f9a2d2939b03c5ae88fa24c738f8"
67
+ "gitHead": "2154c039056b24f706dbb1c2006acd99383e9305"
68
68
  }
package/src/compat.ts CHANGED
@@ -16,7 +16,7 @@ export const enum Feature {
16
16
  ObjectAssign = 0x80,
17
17
  Promise = 0x100,
18
18
  Set = 0x200,
19
- SymbolIterator = 0x400,
19
+ Symbol = 0x400,
20
20
  TypedArray = 0x800,
21
21
  BigIntTypedArray = 0x1000,
22
22
  }
package/src/context.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import { ALL_ENABLED } from './compat';
2
2
  import getIdentifier from './get-identifier';
3
+ import { AsyncServerValue } from './types';
3
4
 
4
5
  interface IndexAssignment {
5
6
  t: 'index';
@@ -47,6 +48,8 @@ export interface SerializationContext {
47
48
  assignments: Assignment[];
48
49
  // Supported features
49
50
  features: number;
51
+
52
+ valueMap: Map<number, AsyncServerValue>;
50
53
  }
51
54
 
52
55
  export interface Options {
@@ -81,6 +84,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
81
84
  refSize: 0,
82
85
  features: options.features,
83
86
  markedRefs: new Set(options.markedRefs),
87
+ valueMap: new Map(),
84
88
  };
85
89
  }
86
90
 
@@ -90,61 +94,51 @@ export function createSerializationContext(options: SerializationOptions): Seria
90
94
  export function markRef(ctx: ParserContext | SerializationContext, current: number) {
91
95
  ctx.markedRefs.add(current);
92
96
  }
93
-
94
- /**
95
- * Creates a new reference ID from a given reference ID
96
- * This new reference ID means that the reference itself
97
- * has been referenced at least once, and is used to generate
98
- * the variables
99
- */
100
- function createValidRef(
101
- ctx: SerializationContext,
102
- index: number,
103
- ) {
104
- const current = ctx.validRefs[index];
105
- if (current == null) {
106
- const value = ctx.refSize++;
107
- ctx.validRefs[index] = value;
108
- return value;
109
- }
110
- return current;
111
- }
112
-
113
97
  /**
114
98
  * Creates the reference param (identifier) from the given reference ID
115
99
  * Calling this function means the value has been referenced somewhere
116
100
  */
117
101
  export function getRefParam(ctx: SerializationContext, index: number) {
118
- const actualIndex = createValidRef(ctx, index);
119
- if (ctx.vars[actualIndex]) {
120
- return ctx.vars[actualIndex];
102
+ /**
103
+ * Creates a new reference ID from a given reference ID
104
+ * This new reference ID means that the reference itself
105
+ * has been referenced at least once, and is used to generate
106
+ * the variables
107
+ */
108
+ let actualIndex = ctx.validRefs[index];
109
+ if (actualIndex == null) {
110
+ actualIndex = ctx.refSize++;
111
+ ctx.validRefs[index] = actualIndex;
112
+ }
113
+ let identifier = ctx.vars[actualIndex];
114
+ if (identifier == null) {
115
+ identifier = getIdentifier(actualIndex);
116
+ ctx.vars[actualIndex] = identifier;
121
117
  }
122
- const result = getIdentifier(actualIndex);
123
- ctx.vars[actualIndex] = result;
124
- return result;
118
+ return identifier;
119
+ }
120
+
121
+ export function getRootID(
122
+ ctx: ParserContext,
123
+ current: AsyncServerValue,
124
+ ) {
125
+ const ref = ctx.refs.get(current);
126
+ if (ref == null) {
127
+ return ctx.refs.size;
128
+ }
129
+ return ref;
125
130
  }
126
131
 
127
- /**
128
- * Creates a reference ID from the given values
129
- */
130
132
  export function createRef(
131
133
  ctx: ParserContext,
132
- current: unknown,
133
- mark: boolean,
134
- ): number {
135
- // Check if reference number already exists
134
+ current: AsyncServerValue,
135
+ ) {
136
136
  const ref = ctx.refs.get(current);
137
- if (ref != null) {
138
- // Exists, means this value is currently
139
- // being referenced
140
- // Mark reference
141
- if (mark) {
142
- markRef(ctx, ref);
143
- }
144
- return ref;
137
+ if (ref == null) {
138
+ const id = ctx.refs.size;
139
+ ctx.refs.set(current, id);
140
+ return id;
145
141
  }
146
- // Create a new reference ID
147
- const id = ctx.refs.size;
148
- ctx.refs.set(current, id);
149
- return id;
142
+ markRef(ctx, ref);
143
+ return ref;
150
144
  }
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  createSerializationContext,
9
9
  } from './context';
10
10
  import parseAsync from './tree/async';
11
+ import deserializeTree from './tree/deserialize';
11
12
  import serializeTree, { resolvePatches } from './tree/serialize';
12
13
  import parseSync from './tree/sync';
13
14
  import { SerovalNode } from './tree/types';
@@ -141,7 +142,11 @@ export function compileJSON(source: SerovalJSON): string {
141
142
  }
142
143
 
143
144
  export function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T {
144
- return deserialize<T>(compileJSON(source));
145
+ const serial = createSerializationContext({
146
+ features: source.f,
147
+ markedRefs: source.m,
148
+ });
149
+ return deserializeTree(serial, source.t) as T;
145
150
  }
146
151
 
147
152
  export default serialize;
package/src/quote.ts CHANGED
@@ -41,5 +41,16 @@ export default function quote(str: string) {
41
41
  } else {
42
42
  result += str.slice(lastPos);
43
43
  }
44
- return '"' + result + '"';
44
+ return result;
45
+ }
46
+
47
+ export function invQuote(str: string): string {
48
+ return str
49
+ .replace(/\\"/g, '"')
50
+ .replace(/\\\\/g, '\\')
51
+ .replace(/\\x3C/g, '<')
52
+ .replace(/\\n/g, '\n')
53
+ .replace(/\\r/g, '\r')
54
+ .replace(/\\u2028/g, '\u2028')
55
+ .replace(/\\u2029/g, '\u2029');
45
56
  }