seroval 0.4.0-alpha.9 → 0.4.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.
@@ -1,40 +1,42 @@
1
1
  interface IndexAssignment {
2
- type: 'index';
3
- source: string;
4
- value: string;
2
+ t: 'index';
3
+ s: string;
4
+ k: undefined;
5
+ v: string;
5
6
  }
6
7
  interface MapAssignment {
7
- type: 'map';
8
- source: string;
9
- key: string;
10
- value: string;
8
+ t: 'map';
9
+ s: string;
10
+ k: string;
11
+ v: string;
11
12
  }
12
13
  interface SetAssignment {
13
- type: 'set';
14
- source: string;
15
- value: string;
14
+ t: 'set';
15
+ s: string;
16
+ k: undefined;
17
+ v: string;
16
18
  }
17
19
  export type Assignment = IndexAssignment | MapAssignment | SetAssignment;
18
20
  export interface ParserContext {
19
21
  refs: Map<unknown, number>;
20
- markedRefs: Record<number, number>;
22
+ markedRefs: Set<number>;
21
23
  features: number;
22
24
  }
23
25
  export interface SerializationContext {
24
26
  stack: number[];
25
27
  validRefs: number[];
26
28
  refSize: number;
27
- markedRefs: Record<number, number>;
29
+ markedRefs: Set<number>;
28
30
  vars: string[];
29
31
  assignments: Assignment[];
30
32
  features: number;
31
33
  }
32
34
  export interface Options {
33
- target: string | string[];
35
+ disabledFeatures: number;
34
36
  }
35
37
  export declare function createParserContext(options?: Partial<Options>): ParserContext;
36
38
  export interface SerializationOptions {
37
- markedRefs: Record<number, number>;
39
+ markedRefs: number[] | Set<number>;
38
40
  features: number;
39
41
  }
40
42
  export declare function createSerializationContext(options: SerializationOptions): SerializationContext;
@@ -50,5 +52,5 @@ export declare function getRefParam(ctx: SerializationContext, index: number): s
50
52
  /**
51
53
  * Creates a reference ID from the given values
52
54
  */
53
- export declare function createRef(ctx: ParserContext, index: unknown): number;
55
+ export declare function createRef(ctx: ParserContext, current: unknown, mark: boolean): number;
54
56
  export {};
@@ -1,11 +1,20 @@
1
+ import { Feature } from './compat';
1
2
  import { Options } from './context';
3
+ import { SerovalNode } from './tree/types';
2
4
  import { AsyncServerValue, PrimitiveValue, ServerValue, CommonServerValue, SemiPrimitiveValue, ErrorValue } from './types';
3
- export { AsyncServerValue, ServerValue, PrimitiveValue, CommonServerValue, SemiPrimitiveValue, ErrorValue, };
5
+ export { AsyncServerValue, ServerValue, PrimitiveValue, CommonServerValue, SemiPrimitiveValue, ErrorValue, Feature, };
4
6
  export declare function serialize<T extends ServerValue>(source: T, options?: Partial<Options>): string;
5
7
  export declare function serializeAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<string>;
6
8
  export declare function deserialize<T extends AsyncServerValue>(source: string): T;
7
- export declare function toJSON<T extends ServerValue>(source: T, options?: Partial<Options>): string;
8
- export declare function toJSONAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<string>;
9
- export declare function compileJSON(source: string): string;
10
- export declare function fromJSON<T extends AsyncServerValue>(source: string): T;
9
+ export interface SerovalJSON {
10
+ t: SerovalNode;
11
+ r: number;
12
+ i: boolean;
13
+ f: number;
14
+ m: number[];
15
+ }
16
+ export declare function toJSON<T extends ServerValue>(source: T, options?: Partial<Options>): SerovalJSON;
17
+ export declare function toJSONAsync<T extends AsyncServerValue>(source: T, options?: Partial<Options>): Promise<SerovalJSON>;
18
+ export declare function compileJSON(source: SerovalJSON): string;
19
+ export declare function fromJSON<T extends AsyncServerValue>(source: SerovalJSON): T;
11
20
  export default serialize;
@@ -0,0 +1,17 @@
1
+ import { ParserContext } from '../context';
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;
12
+ export declare function createBigIntNode(ctx: ParserContext, current: bigint): SerovalBigIntNode;
13
+ export declare function createReferenceNode(id: number): SerovalReferenceNode;
14
+ export declare function createDateNode(id: number, current: Date): SerovalDateNode;
15
+ export declare function createRegExpNode(id: number, current: RegExp): SerovalRegExpNode;
16
+ export declare function createTypedArrayNode(ctx: ParserContext, id: number, current: TypedArrayValue): SerovalTypedArrayNode;
17
+ export declare function createBigIntTypedArrayNode(ctx: ParserContext, id: number, current: BigIntTypedArrayValue): SerovalBigIntTypedArrayNode;
@@ -1,10 +1,6 @@
1
- import { SerializationContext, ParserContext } from '../context';
2
- import { ErrorValue, PrimitiveValue } from '../types';
3
- import { SerovalNode, SerovalReferenceNode } from './types';
1
+ import { ParserContext } from '../context';
2
+ import { AsyncServerValue, ErrorValue } from '../types';
4
3
  export declare function getErrorConstructor(error: ErrorValue): "EvalError" | "RangeError" | "ReferenceError" | "SyntaxError" | "TypeError" | "URIError" | "Error";
5
- export declare function getErrorOptions(error: Error): Record<string, any> | undefined;
4
+ export declare function getErrorOptions(ctx: ParserContext, error: Error): Record<string, any> | undefined;
6
5
  export declare function getIterableOptions(obj: Iterable<any>): Record<string, unknown> | undefined;
7
- export declare function isReferenceInStack(ctx: SerializationContext, node: SerovalNode): node is SerovalReferenceNode;
8
- export declare function generateRef(ctx: ParserContext, current: unknown): number | SerovalReferenceNode;
9
- export declare function generateSemiPrimitiveValue(ctx: ParserContext, current: unknown, id: number): SerovalNode | undefined;
10
- export declare function serializePrimitive(value: PrimitiveValue): string | number | null;
6
+ export declare function isIterable(value: unknown): value is Iterable<AsyncServerValue>;
@@ -1,7 +1,8 @@
1
1
  export type PrimitiveValue = boolean | string | number | undefined | null;
2
2
  export type ErrorValue = Error | AggregateError | EvalError | RangeError | ReferenceError | TypeError | SyntaxError | URIError;
3
- export type TypedArrayValue = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array | BigInt64Array | BigUint64Array;
4
- export type SemiPrimitiveValue = RegExp | Date | TypedArrayValue | bigint;
3
+ export type TypedArrayValue = Int8Array | Int16Array | Int32Array | Uint8Array | Uint16Array | Uint32Array | Uint8ClampedArray | Float32Array | Float64Array;
4
+ export type BigIntTypedArrayValue = BigInt64Array | BigUint64Array;
5
+ export type SemiPrimitiveValue = RegExp | Date | TypedArrayValue | BigIntTypedArrayValue | bigint;
5
6
  export type CommonServerValue = PrimitiveValue | SemiPrimitiveValue | ErrorValue;
6
7
  export type ServerValue = CommonServerValue | Array<ServerValue> | readonly ServerValue[] | Iterable<ServerValue> | {
7
8
  [key: string | number]: ServerValue;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "seroval",
3
3
  "type": "module",
4
- "version": "0.4.0-alpha.9",
4
+ "version": "0.4.1",
5
5
  "files": [
6
6
  "dist",
7
7
  "src"
@@ -64,5 +64,5 @@
64
64
  "typesVersions": {
65
65
  "*": {}
66
66
  },
67
- "gitHead": "27ff8d23e589e5968ebe968b14d050cd468ca49f"
67
+ "gitHead": "a3cfb8eae6e1f9a2d2939b03c5ae88fa24c738f8"
68
68
  }
package/src/compat.ts CHANGED
@@ -3,258 +3,22 @@
3
3
  * References
4
4
  * - https://kangax.github.io/compat-table/es6/
5
5
  * - MDN
6
- * - ESBuild
7
6
  */
8
7
 
9
- import assert from './assert';
10
-
11
- export type Version = [major: number, minor: number, patch: number];
12
-
13
- function compareVersion(left: Version, right: Version) {
14
- let diff = left[0] - right[0];
15
- if (diff === 0) {
16
- diff = left[1] - right[1];
17
- }
18
- if (diff === 0) {
19
- diff = left[2] - right[2];
20
- }
21
- return diff;
22
- }
23
-
24
- export interface PlatformVersion {
25
- es: Version;
26
- // desktop
27
- chrome?: Version;
28
- edge?: Version;
29
- safari?: Version;
30
- firefox?: Version;
31
- opera?: Version;
32
- // mobile
33
- ios?: Version;
34
- samsung?: Version;
35
- // js runtimes
36
- deno?: Version;
37
- node?: Version;
38
- }
39
-
40
- export type Platform = keyof PlatformVersion;
41
-
42
8
  export const enum Feature {
43
9
  AggregateError = 0x01,
44
10
  ArrayPrototypeValues = 0x02,
45
11
  ArrowFunction = 0x04,
46
12
  BigInt = 0x08,
47
- Map = 0x10,
48
- MethodShorthand = 0x20,
49
- ObjectAssign = 0x40,
50
- Promise = 0x80,
51
- Set = 0x100,
52
- SymbolIterator = 0x200,
53
- TypedArray = 0x400,
54
- BigIntTypedArray = 0x800,
13
+ ErrorPrototypeStack = 0x10,
14
+ Map = 0x20,
15
+ MethodShorthand = 0x40,
16
+ ObjectAssign = 0x80,
17
+ Promise = 0x100,
18
+ Set = 0x200,
19
+ SymbolIterator = 0x400,
20
+ TypedArray = 0x800,
21
+ BigIntTypedArray = 0x1000,
55
22
  }
56
23
 
57
- type VersionTable = {
58
- [key in Feature]: PlatformVersion;
59
- }
60
-
61
- const VERSION_TABLE: VersionTable = {
62
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError#browser_compatibility
63
- [Feature.AggregateError]: {
64
- es: [2021, 0, 0],
65
- chrome: [85, 0, 0],
66
- edge: [85, 0, 0],
67
- firefox: [79, 0, 0],
68
- opera: [71, 0, 0],
69
- safari: [14, 0, 0],
70
- ios: [14, 0, 0],
71
- samsung: [14, 0, 0],
72
- deno: [1, 2, 0],
73
- node: [15, 0, 0],
74
- },
75
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values#browser_compatibility
76
- [Feature.ArrayPrototypeValues]: {
77
- es: [6, 0, 0],
78
- chrome: [66, 0, 0],
79
- edge: [14, 0, 0],
80
- firefox: [60, 0, 0],
81
- opera: [53, 0, 0],
82
- safari: [9, 0, 0],
83
- ios: [9, 0, 0],
84
- samsung: [9, 0, 0],
85
- deno: [1, 0, 0],
86
- node: [10, 9, 0],
87
- },
88
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#browser_compatibility
89
- [Feature.ArrowFunction]: {
90
- es: [6, 0, 0],
91
- chrome: [45, 0, 0],
92
- edge: [12, 0, 0],
93
- firefox: [24, 0, 0],
94
- opera: [32, 0, 0],
95
- safari: [10, 0, 0],
96
- ios: [10, 0, 0],
97
- samsung: [5, 0, 0],
98
- deno: [1, 0, 0],
99
- node: [4, 0, 0],
100
- },
101
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#browser_compatibility
102
- [Feature.BigInt]: {
103
- es: [2020, 0, 0],
104
- chrome: [67, 0, 0],
105
- edge: [79, 0, 0],
106
- firefox: [68, 0, 0],
107
- opera: [54, 0, 0],
108
- safari: [14, 0, 0],
109
- ios: [14, 0, 0],
110
- samsung: [9, 0, 0],
111
- deno: [1, 0, 0],
112
- node: [10, 4, 0],
113
- },
114
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#browser_compatibility
115
- [Feature.Map]: {
116
- es: [6, 0, 0],
117
- chrome: [38, 0, 0],
118
- edge: [12, 0, 0],
119
- firefox: [13, 0, 0],
120
- opera: [25, 0, 0],
121
- safari: [8, 0, 0],
122
- ios: [8, 0, 0],
123
- samsung: [3, 0, 0],
124
- deno: [1, 0, 0],
125
- node: [0, 12, 0],
126
- },
127
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions#browser_compatibility
128
- [Feature.MethodShorthand]: {
129
- es: [6, 0, 0],
130
- chrome: [39, 0, 0],
131
- edge: [12, 0, 0],
132
- firefox: [34, 0, 0],
133
- opera: [26, 0, 0],
134
- safari: [9, 0, 0],
135
- ios: [9, 0, 0],
136
- samsung: [4, 0, 0],
137
- deno: [1, 0, 0],
138
- node: [4, 0, 0],
139
- },
140
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#browser_compatibility
141
- [Feature.ObjectAssign]: {
142
- es: [6, 0, 0],
143
- chrome: [45, 0, 0],
144
- edge: [12, 0, 0],
145
- firefox: [34, 0, 0],
146
- opera: [32, 0, 0],
147
- safari: [9, 0, 0],
148
- ios: [9, 0, 0],
149
- samsung: [5, 0, 0],
150
- deno: [1, 0, 0],
151
- node: [4, 0, 0],
152
- },
153
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#browser_compatibility
154
- [Feature.Promise]: {
155
- es: [6, 0, 0],
156
- chrome: [32, 0, 0],
157
- edge: [12, 0, 0],
158
- firefox: [29, 0, 0],
159
- opera: [19, 0, 0],
160
- safari: [8, 0, 0],
161
- ios: [8, 0, 0],
162
- samsung: [2, 0, 0],
163
- deno: [1, 0, 0],
164
- node: [0, 12, 0],
165
- },
166
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#browser_compatibility
167
- [Feature.Set]: {
168
- es: [6, 0, 0],
169
- chrome: [38, 0, 0],
170
- edge: [12, 0, 0],
171
- firefox: [13, 0, 0],
172
- opera: [25, 0, 0],
173
- safari: [8, 0, 0],
174
- ios: [8, 0, 0],
175
- samsung: [3, 0, 0],
176
- deno: [1, 0, 0],
177
- node: [0, 12, 0],
178
- },
179
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator#browser_compatibility
180
- [Feature.SymbolIterator]: {
181
- es: [6, 0, 0],
182
- chrome: [43, 0, 0],
183
- edge: [12, 0, 0],
184
- firefox: [36, 0, 0],
185
- opera: [30, 0, 0],
186
- safari: [10, 0, 0],
187
- ios: [10, 0, 0],
188
- samsung: [4, 0, 0],
189
- deno: [1, 0, 0],
190
- node: [0, 12, 0],
191
- },
192
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#browser_compatibility
193
- [Feature.TypedArray]: {
194
- es: [6, 0, 0],
195
- chrome: [7, 0, 0],
196
- edge: [12, 0, 0],
197
- firefox: [4, 0, 0],
198
- opera: [11, 6, 0],
199
- safari: [5, 1, 0],
200
- ios: [4, 2, 0],
201
- samsung: [1, 0, 0],
202
- deno: [1, 0, 0],
203
- node: [0, 10, 0],
204
- },
205
- // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt64Array#browser_compatibility
206
- [Feature.BigIntTypedArray]: {
207
- es: [2020, 0, 0],
208
- chrome: [67, 0, 0],
209
- edge: [79, 0, 0],
210
- firefox: [68, 0, 0],
211
- opera: [54, 6, 0],
212
- safari: [15, 1, 0],
213
- ios: [15, 2, 0],
214
- samsung: [9, 0, 0],
215
- deno: [1, 0, 0],
216
- node: [10, 4, 0],
217
- },
218
- };
219
-
220
- const TARGET_REGEX = /^(es|chrome|edge|safari|firefox|opera|ios|samsung|deno|node)([0-9]+(\.[0-9]+(\.[0-9]+)?)?)$/i;
221
-
222
- export type Target = [platform: Platform, version: Version];
223
-
224
- function parseTarget(target: string): Target {
225
- const result = TARGET_REGEX.exec(target);
226
- assert(result, `Invalid target "${target}"`);
227
- const [, platform, version] = result;
228
- const [major, minor = '0', patch = '0'] = version.split('.');
229
- return [platform as Platform, [Number(major), Number(minor), Number(patch)]];
230
- }
231
-
232
- function getTargetVersions(targets: string | string[]): Target[] {
233
- if (Array.isArray(targets)) {
234
- const versions: Target[] = [];
235
- for (const target of targets) {
236
- versions.push(parseTarget(target));
237
- }
238
- return versions;
239
- }
240
- return [parseTarget(targets)];
241
- }
242
-
243
- export function parseTargets(targets: string | string[]): number {
244
- const parsed = getTargetVersions(targets);
245
- let flags = 0;
246
-
247
- for (const key in VERSION_TABLE) {
248
- const base = VERSION_TABLE[key as unknown as Feature];
249
- let flag = true;
250
- for (const [platform, version] of parsed) {
251
- const baseVersion = base[platform];
252
- flag = flag && !!baseVersion && (compareVersion(baseVersion, version) <= 0);
253
- }
254
- if (flag) {
255
- flags |= Number(key);
256
- }
257
- }
258
-
259
- return flags;
260
- }
24
+ export const ALL_ENABLED = 0x1FFF;
package/src/context.ts CHANGED
@@ -1,23 +1,25 @@
1
- import { parseTargets } from './compat';
1
+ import { ALL_ENABLED } from './compat';
2
2
  import getIdentifier from './get-identifier';
3
3
 
4
4
  interface IndexAssignment {
5
- type: 'index';
6
- source: string;
7
- value: string;
5
+ t: 'index';
6
+ s: string;
7
+ k: undefined;
8
+ v: string;
8
9
  }
9
10
 
10
11
  interface MapAssignment {
11
- type: 'map';
12
- source: string;
13
- key: string;
14
- value: string;
12
+ t: 'map';
13
+ s: string;
14
+ k: string;
15
+ v: string;
15
16
  }
16
17
 
17
18
  interface SetAssignment {
18
- type: 'set';
19
- source: string;
20
- value: string;
19
+ t: 'set';
20
+ s: string;
21
+ k: undefined;
22
+ v: string;
21
23
  }
22
24
 
23
25
  // Array of assignments to be done (used for recursion)
@@ -28,7 +30,7 @@ export type Assignment =
28
30
 
29
31
  export interface ParserContext {
30
32
  refs: Map<unknown, number>;
31
- markedRefs: Record<number, number>;
33
+ markedRefs: Set<number>;
32
34
  features: number;
33
35
  }
34
36
 
@@ -38,7 +40,7 @@ export interface SerializationContext {
38
40
  validRefs: number[];
39
41
  refSize: number;
40
42
  // Refs that are...referenced
41
- markedRefs: Record<number, number>;
43
+ markedRefs: Set<number>;
42
44
  // Variables
43
45
  vars: string[];
44
46
  // Array of assignments to be done (used for recursion)
@@ -48,25 +50,25 @@ export interface SerializationContext {
48
50
  }
49
51
 
50
52
  export interface Options {
51
- target: string | string[];
53
+ disabledFeatures: number;
52
54
  }
53
55
 
54
56
  const DEFAULT_OPTIONS: Options = {
55
- target: 'es2023',
57
+ disabledFeatures: 0,
56
58
  };
57
59
 
58
60
  export function createParserContext(options: Partial<Options> = {}): ParserContext {
59
61
  // eslint-disable-next-line prefer-object-spread
60
62
  const result = Object.assign({}, DEFAULT_OPTIONS, options || {});
61
63
  return {
62
- markedRefs: {},
64
+ markedRefs: new Set(),
63
65
  refs: new Map(),
64
- features: parseTargets(result.target),
66
+ features: ALL_ENABLED ^ result.disabledFeatures,
65
67
  };
66
68
  }
67
69
 
68
70
  export interface SerializationOptions {
69
- markedRefs: Record<number, number>;
71
+ markedRefs: number[] | Set<number>;
70
72
  features: number;
71
73
  }
72
74
 
@@ -78,7 +80,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
78
80
  validRefs: [],
79
81
  refSize: 0,
80
82
  features: options.features,
81
- markedRefs: options.markedRefs,
83
+ markedRefs: new Set(options.markedRefs),
82
84
  };
83
85
  }
84
86
 
@@ -86,7 +88,7 @@ export function createSerializationContext(options: SerializationOptions): Seria
86
88
  * Increments the number of references the referenced value has
87
89
  */
88
90
  export function markRef(ctx: ParserContext | SerializationContext, current: number) {
89
- ctx.markedRefs[current] = 1;
91
+ ctx.markedRefs.add(current);
90
92
  }
91
93
 
92
94
  /**
@@ -127,13 +129,22 @@ export function getRefParam(ctx: SerializationContext, index: number) {
127
129
  */
128
130
  export function createRef(
129
131
  ctx: ParserContext,
130
- index: unknown,
131
- ) {
132
- const current = ctx.refs.get(index);
133
- if (current != null) {
134
- return current;
132
+ current: unknown,
133
+ mark: boolean,
134
+ ): number {
135
+ // Check if reference number already exists
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;
135
145
  }
146
+ // Create a new reference ID
136
147
  const id = ctx.refs.size;
137
- ctx.refs.set(index, id);
148
+ ctx.refs.set(current, id);
138
149
  return id;
139
150
  }