seroval 0.7.0 → 0.9.0
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/cjs/development/index.cjs +1247 -1069
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +3 -3
- package/dist/esm/development/index.mjs +1247 -1069
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +3 -3
- package/dist/types/assert.d.ts +1 -1
- package/dist/types/context.d.ts +8 -2
- package/dist/types/index.d.ts +3 -4
- package/dist/types/string.d.ts +1 -1
- package/dist/types/tree/UnsupportedTypeError.d.ts +3 -0
- package/dist/types/tree/async.d.ts +3 -3
- package/dist/types/tree/constants.d.ts +11 -0
- package/dist/types/tree/deserialize.d.ts +2 -2
- package/dist/types/tree/primitives.d.ts +9 -15
- package/dist/types/tree/serialize.d.ts +2 -2
- package/dist/types/tree/shared.d.ts +12 -8
- package/dist/types/tree/sync.d.ts +3 -3
- package/dist/types/tree/types.d.ts +74 -71
- package/dist/types/tree/web-api.d.ts +2 -2
- package/dist/types/types.d.ts +4 -4
- package/package.json +11 -9
- package/src/assert.ts +2 -2
- package/src/compat.ts +0 -1
- package/src/context.ts +20 -7
- package/src/get-identifier.ts +1 -1
- package/src/index.ts +35 -26
- package/src/string.ts +2 -2
- package/src/tree/UnsupportedTypeError.ts +8 -0
- package/src/tree/async.ts +256 -233
- package/src/tree/constants.ts +73 -0
- package/src/tree/deserialize.ts +112 -93
- package/src/tree/primitives.ts +93 -134
- package/src/tree/reference.ts +3 -3
- package/src/tree/serialize.ts +307 -201
- package/src/tree/shared.ts +45 -22
- package/src/tree/symbols.ts +13 -13
- package/src/tree/sync.ts +236 -198
- package/src/tree/types.ts +87 -94
- package/src/tree/web-api.ts +14 -7
- package/src/types.ts +7 -3
- package/src/tree/iterator.ts +0 -14
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 type { SerovalObjectFlags } from './tree/types';
|
|
3
4
|
|
|
4
5
|
interface IndexAssignment {
|
|
5
6
|
t: 'index';
|
|
@@ -42,21 +43,29 @@ export interface ParserContext {
|
|
|
42
43
|
features: number;
|
|
43
44
|
}
|
|
44
45
|
|
|
46
|
+
export interface FlaggedObject {
|
|
47
|
+
type: SerovalObjectFlags;
|
|
48
|
+
value: string;
|
|
49
|
+
}
|
|
50
|
+
|
|
45
51
|
export interface SerializationContext {
|
|
46
52
|
stack: number[];
|
|
47
53
|
// Map tree refs to actual refs
|
|
48
|
-
validRefs: number[];
|
|
54
|
+
validRefs: (number | undefined)[];
|
|
49
55
|
refSize: number;
|
|
50
56
|
// Refs that are...referenced
|
|
51
57
|
markedRefs: Set<number>;
|
|
52
58
|
// Variables
|
|
53
|
-
vars: string[];
|
|
59
|
+
vars: (string | undefined)[];
|
|
54
60
|
// Array of assignments to be done (used for recursion)
|
|
55
61
|
assignments: Assignment[];
|
|
56
62
|
// Supported features
|
|
57
63
|
features: number;
|
|
58
64
|
|
|
59
65
|
valueMap: Map<number, unknown>;
|
|
66
|
+
|
|
67
|
+
// Object flags
|
|
68
|
+
flags: FlaggedObject[];
|
|
60
69
|
}
|
|
61
70
|
|
|
62
71
|
export interface Options {
|
|
@@ -69,7 +78,7 @@ const DEFAULT_OPTIONS: Options = {
|
|
|
69
78
|
|
|
70
79
|
export function createParserContext(options: Partial<Options> = {}): ParserContext {
|
|
71
80
|
// eslint-disable-next-line prefer-object-spread
|
|
72
|
-
const result = Object.assign({}, DEFAULT_OPTIONS, options
|
|
81
|
+
const result = Object.assign({}, DEFAULT_OPTIONS, options);
|
|
73
82
|
return {
|
|
74
83
|
markedRefs: new Set(),
|
|
75
84
|
refs: new Map(),
|
|
@@ -92,20 +101,24 @@ export function createSerializationContext(options: SerializationOptions): Seria
|
|
|
92
101
|
features: options.features,
|
|
93
102
|
markedRefs: new Set(options.markedRefs),
|
|
94
103
|
valueMap: new Map(),
|
|
104
|
+
flags: [],
|
|
95
105
|
};
|
|
96
106
|
}
|
|
97
107
|
|
|
98
108
|
/**
|
|
99
109
|
* Increments the number of references the referenced value has
|
|
100
110
|
*/
|
|
101
|
-
export function markRef(
|
|
111
|
+
export function markRef(
|
|
112
|
+
ctx: ParserContext | SerializationContext,
|
|
113
|
+
current: number,
|
|
114
|
+
): void {
|
|
102
115
|
ctx.markedRefs.add(current);
|
|
103
116
|
}
|
|
104
117
|
/**
|
|
105
118
|
* Creates the reference param (identifier) from the given reference ID
|
|
106
119
|
* Calling this function means the value has been referenced somewhere
|
|
107
120
|
*/
|
|
108
|
-
export function getRefParam(ctx: SerializationContext, index: number) {
|
|
121
|
+
export function getRefParam(ctx: SerializationContext, index: number): string {
|
|
109
122
|
/**
|
|
110
123
|
* Creates a new reference ID from a given reference ID
|
|
111
124
|
* This new reference ID means that the reference itself
|
|
@@ -128,7 +141,7 @@ export function getRefParam(ctx: SerializationContext, index: number) {
|
|
|
128
141
|
export function getRootID<T>(
|
|
129
142
|
ctx: ParserContext,
|
|
130
143
|
current: T,
|
|
131
|
-
) {
|
|
144
|
+
): number {
|
|
132
145
|
const ref = ctx.refs.get(current);
|
|
133
146
|
if (ref == null) {
|
|
134
147
|
return ctx.refs.size;
|
|
@@ -139,7 +152,7 @@ export function getRootID<T>(
|
|
|
139
152
|
export function createIndexedValue<T>(
|
|
140
153
|
ctx: ParserContext,
|
|
141
154
|
current: T,
|
|
142
|
-
) {
|
|
155
|
+
): number {
|
|
143
156
|
const ref = ctx.refs.get(current);
|
|
144
157
|
if (ref == null) {
|
|
145
158
|
const id = ctx.refs.size;
|
package/src/get-identifier.ts
CHANGED
|
@@ -4,7 +4,7 @@ const REF_START_CHARS_LEN = REF_START_CHARS.length;
|
|
|
4
4
|
const REF_CHARS = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$_';
|
|
5
5
|
const REF_CHARS_LEN = REF_CHARS.length;
|
|
6
6
|
|
|
7
|
-
export default function getIdentifier(index: number) {
|
|
7
|
+
export default function getIdentifier(index: number): string {
|
|
8
8
|
let mod = index % REF_START_CHARS_LEN;
|
|
9
9
|
let ref = REF_START_CHARS[mod];
|
|
10
10
|
index = (index - mod) / REF_START_CHARS_LEN;
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
2
|
import { Feature } from './compat';
|
|
3
|
-
import {
|
|
3
|
+
import type {
|
|
4
4
|
SerializationContext,
|
|
5
|
-
getRefParam,
|
|
6
5
|
Options,
|
|
6
|
+
} from './context';
|
|
7
|
+
import {
|
|
8
|
+
getRefParam,
|
|
7
9
|
createParserContext,
|
|
8
10
|
createSerializationContext,
|
|
11
|
+
getRootID,
|
|
9
12
|
} from './context';
|
|
13
|
+
import parseSync from './tree/sync';
|
|
10
14
|
import parseAsync from './tree/async';
|
|
11
15
|
import deserializeTree from './tree/deserialize';
|
|
12
16
|
import serializeTree, { resolvePatches } from './tree/serialize';
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
17
|
+
import type { SerovalNode } from './tree/types';
|
|
18
|
+
import { SerovalNodeType } from './tree/types';
|
|
15
19
|
|
|
16
|
-
export {
|
|
20
|
+
export type {
|
|
17
21
|
AsyncServerValue,
|
|
18
22
|
ServerValue,
|
|
19
23
|
PrimitiveValue,
|
|
@@ -28,7 +32,7 @@ function finalize(
|
|
|
28
32
|
rootID: number,
|
|
29
33
|
isObject: boolean,
|
|
30
34
|
result: string,
|
|
31
|
-
) {
|
|
35
|
+
): string {
|
|
32
36
|
// Shared references detected
|
|
33
37
|
if (ctx.vars.length) {
|
|
34
38
|
const patches = resolvePatches(ctx);
|
|
@@ -62,23 +66,33 @@ function finalize(
|
|
|
62
66
|
export function serialize<T>(
|
|
63
67
|
source: T,
|
|
64
68
|
options?: Partial<Options>,
|
|
65
|
-
) {
|
|
69
|
+
): string {
|
|
66
70
|
const ctx = createParserContext(options);
|
|
67
|
-
const
|
|
71
|
+
const tree = parseSync(ctx, source);
|
|
68
72
|
const serial = createSerializationContext(ctx);
|
|
69
73
|
const result = serializeTree(serial, tree);
|
|
70
|
-
return finalize(
|
|
74
|
+
return finalize(
|
|
75
|
+
serial,
|
|
76
|
+
getRootID(ctx, source),
|
|
77
|
+
tree.t === SerovalNodeType.Object,
|
|
78
|
+
result,
|
|
79
|
+
);
|
|
71
80
|
}
|
|
72
81
|
|
|
73
82
|
export async function serializeAsync<T>(
|
|
74
83
|
source: T,
|
|
75
84
|
options?: Partial<Options>,
|
|
76
|
-
) {
|
|
85
|
+
): Promise<string> {
|
|
77
86
|
const ctx = createParserContext(options);
|
|
78
|
-
const
|
|
87
|
+
const tree = await parseAsync(ctx, source);
|
|
79
88
|
const serial = createSerializationContext(ctx);
|
|
80
89
|
const result = serializeTree(serial, tree);
|
|
81
|
-
return finalize(
|
|
90
|
+
return finalize(
|
|
91
|
+
serial,
|
|
92
|
+
getRootID(ctx, source),
|
|
93
|
+
tree.t === SerovalNodeType.Object,
|
|
94
|
+
result,
|
|
95
|
+
);
|
|
82
96
|
}
|
|
83
97
|
|
|
84
98
|
export function deserialize<T>(source: string): T {
|
|
@@ -87,11 +101,10 @@ export function deserialize<T>(source: string): T {
|
|
|
87
101
|
}
|
|
88
102
|
|
|
89
103
|
export interface SerovalJSON {
|
|
90
|
-
t: SerovalNode
|
|
91
|
-
r: number
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
m: number[],
|
|
104
|
+
t: SerovalNode;
|
|
105
|
+
r: number;
|
|
106
|
+
f: number;
|
|
107
|
+
m: number[];
|
|
95
108
|
}
|
|
96
109
|
|
|
97
110
|
export function toJSON<T>(
|
|
@@ -99,11 +112,9 @@ export function toJSON<T>(
|
|
|
99
112
|
options?: Partial<Options>,
|
|
100
113
|
): SerovalJSON {
|
|
101
114
|
const ctx = createParserContext(options);
|
|
102
|
-
const [tree, root, isObject] = parseSync(ctx, source);
|
|
103
115
|
return {
|
|
104
|
-
t:
|
|
105
|
-
r:
|
|
106
|
-
i: isObject,
|
|
116
|
+
t: parseSync(ctx, source),
|
|
117
|
+
r: getRootID(ctx, source),
|
|
107
118
|
f: ctx.features,
|
|
108
119
|
m: Array.from(ctx.markedRefs),
|
|
109
120
|
};
|
|
@@ -114,11 +125,9 @@ export async function toJSONAsync<T>(
|
|
|
114
125
|
options?: Partial<Options>,
|
|
115
126
|
): Promise<SerovalJSON> {
|
|
116
127
|
const ctx = createParserContext(options);
|
|
117
|
-
const [tree, root, isObject] = await parseAsync(ctx, source);
|
|
118
128
|
return {
|
|
119
|
-
t:
|
|
120
|
-
r:
|
|
121
|
-
i: isObject,
|
|
129
|
+
t: await parseAsync(ctx, source),
|
|
130
|
+
r: getRootID(ctx, source),
|
|
122
131
|
f: ctx.features,
|
|
123
132
|
m: Array.from(ctx.markedRefs),
|
|
124
133
|
};
|
|
@@ -130,7 +139,7 @@ export function compileJSON(source: SerovalJSON): string {
|
|
|
130
139
|
markedRefs: source.m,
|
|
131
140
|
});
|
|
132
141
|
const result = serializeTree(serial, source.t);
|
|
133
|
-
return finalize(serial, source.r, source.i, result);
|
|
142
|
+
return finalize(serial, source.r, source.t.i === SerovalNodeType.Object, result);
|
|
134
143
|
}
|
|
135
144
|
|
|
136
145
|
export function fromJSON<T>(source: SerovalJSON): T {
|
package/src/string.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function serializeChar(str: string) {
|
|
1
|
+
export function serializeChar(str: string): string | undefined {
|
|
2
2
|
switch (str) {
|
|
3
3
|
case '"': return '\\"';
|
|
4
4
|
case '\\': return '\\\\';
|
|
@@ -19,7 +19,7 @@ export function serializeChar(str: string) {
|
|
|
19
19
|
// not listed as DoubleStringCharacters on
|
|
20
20
|
// Also includes "<" to escape "</script>" and "\" to avoid invalid escapes in the output.
|
|
21
21
|
// http://www.ecma-international.org/ecma-262/5.1/#sec-7.8.4
|
|
22
|
-
export function serializeString(str: string) {
|
|
22
|
+
export function serializeString(str: string): string {
|
|
23
23
|
let result = '';
|
|
24
24
|
let lastPos = 0;
|
|
25
25
|
let replacement: string | undefined;
|