seroval 0.15.0 → 1.0.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/README.md +3 -3
- package/dist/cjs/development/index.cjs +1278 -1929
- package/dist/cjs/development/index.cjs.map +3 -3
- package/dist/cjs/production/index.cjs +3 -3
- package/dist/esm/development/index.mjs +1278 -1929
- package/dist/esm/development/index.mjs.map +3 -3
- package/dist/esm/production/index.mjs +3 -3
- package/dist/types/core/Serializer.d.ts +2 -1
- package/dist/types/core/Serializer.d.ts.map +1 -1
- package/dist/types/core/UnsupportedTypeError.d.ts.map +1 -1
- package/dist/types/core/base-primitives.d.ts +6 -2
- package/dist/types/core/base-primitives.d.ts.map +1 -1
- package/dist/types/core/compat.d.ts +5 -13
- package/dist/types/core/compat.d.ts.map +1 -1
- package/dist/types/core/constants.d.ts +17 -29
- package/dist/types/core/constants.d.ts.map +1 -1
- package/dist/types/core/context/deserializer.d.ts +6 -16
- package/dist/types/core/context/deserializer.d.ts.map +1 -1
- package/dist/types/core/context/parser/async.d.ts +2 -11
- package/dist/types/core/context/parser/async.d.ts.map +1 -1
- package/dist/types/core/context/parser/stream.d.ts +10 -10
- package/dist/types/core/context/parser/stream.d.ts.map +1 -1
- package/dist/types/core/context/parser/sync.d.ts +5 -7
- package/dist/types/core/context/parser/sync.d.ts.map +1 -1
- package/dist/types/core/context/parser.d.ts +19 -4
- package/dist/types/core/context/parser.d.ts.map +1 -1
- package/dist/types/core/context/serializer.d.ts +11 -25
- package/dist/types/core/context/serializer.d.ts.map +1 -1
- package/dist/types/core/cross/async.d.ts.map +1 -1
- package/dist/types/core/cross/deserializer.d.ts.map +1 -1
- package/dist/types/core/cross/index.d.ts.map +1 -1
- package/dist/types/core/cross/parser.d.ts.map +1 -1
- package/dist/types/core/cross/serializer.d.ts +1 -1
- package/dist/types/core/cross/serializer.d.ts.map +1 -1
- package/dist/types/core/cross/stream.d.ts.map +1 -1
- package/dist/types/core/cross/sync.d.ts.map +1 -1
- package/dist/types/core/keys.d.ts.map +1 -1
- package/dist/types/core/literals.d.ts.map +1 -1
- package/dist/types/core/plugin.d.ts +21 -0
- package/dist/types/core/plugin.d.ts.map +1 -1
- package/dist/types/core/reference.d.ts.map +1 -1
- package/dist/types/core/special-reference.d.ts +4 -9
- package/dist/types/core/special-reference.d.ts.map +1 -1
- package/dist/types/core/stream.d.ts +18 -0
- package/dist/types/core/stream.d.ts.map +1 -0
- package/dist/types/core/string.d.ts.map +1 -1
- package/dist/types/core/tree/async.d.ts.map +1 -1
- package/dist/types/core/tree/deserializer.d.ts.map +1 -1
- package/dist/types/core/tree/index.d.ts +1 -1
- package/dist/types/core/tree/index.d.ts.map +1 -1
- package/dist/types/core/tree/serializer.d.ts +3 -11
- package/dist/types/core/tree/serializer.d.ts.map +1 -1
- package/dist/types/core/types.d.ts +28 -122
- package/dist/types/core/types.d.ts.map +1 -1
- package/dist/types/core/utils/deferred.d.ts +0 -7
- package/dist/types/core/utils/deferred.d.ts.map +1 -1
- package/dist/types/core/utils/error.d.ts +2 -1
- package/dist/types/core/utils/error.d.ts.map +1 -1
- package/dist/types/core/utils/get-identifier.d.ts.map +1 -1
- package/dist/types/core/utils/is-valid-identifier.d.ts.map +1 -1
- package/dist/types/core/utils/iterator-to-sequence.d.ts +0 -12
- package/dist/types/core/utils/iterator-to-sequence.d.ts.map +1 -1
- package/dist/types/core/utils/typed-array.d.ts +2 -0
- package/dist/types/core/utils/typed-array.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -3
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/core/Serializer.ts +44 -28
- package/src/core/UnsupportedTypeError.ts +2 -3
- package/src/core/base-primitives.ts +124 -38
- package/src/core/compat.ts +5 -14
- package/src/core/constants.ts +28 -39
- package/src/core/context/deserializer.ts +122 -308
- package/src/core/context/parser/async.ts +163 -375
- package/src/core/context/parser/stream.ts +109 -367
- package/src/core/context/parser/sync.ts +139 -266
- package/src/core/context/parser.ts +93 -68
- package/src/core/context/serializer.ts +370 -439
- package/src/core/cross/async.ts +1 -1
- package/src/core/cross/deserializer.ts +1 -4
- package/src/core/cross/index.ts +28 -31
- package/src/core/cross/parser.ts +1 -1
- package/src/core/cross/serializer.ts +30 -20
- package/src/core/cross/stream.ts +1 -1
- package/src/core/cross/sync.ts +1 -1
- package/src/core/keys.ts +3 -1
- package/src/core/literals.ts +22 -8
- package/src/core/plugin.ts +48 -10
- package/src/core/reference.ts +4 -5
- package/src/core/special-reference.ts +5 -15
- package/src/core/stream.ts +205 -0
- package/src/core/string.ts +53 -22
- package/src/core/tree/async.ts +1 -1
- package/src/core/tree/deserializer.ts +4 -9
- package/src/core/tree/index.ts +15 -10
- package/src/core/tree/serializer.ts +6 -50
- package/src/core/types.ts +39 -179
- package/src/core/utils/deferred.ts +0 -27
- package/src/core/utils/error.ts +26 -15
- package/src/core/utils/get-identifier.ts +5 -4
- package/src/core/utils/is-valid-identifier.ts +6 -5
- package/src/core/utils/iterator-to-sequence.ts +0 -174
- package/src/core/utils/typed-array.ts +35 -11
- package/src/index.ts +5 -12
- package/dist/types/core/utils/constructors.d.ts +0 -5
- package/dist/types/core/utils/constructors.d.ts.map +0 -1
- package/dist/types/core/web-api.d.ts +0 -8
- package/dist/types/core/web-api.d.ts.map +0 -1
- package/dist/types/types.d.ts +0 -21
- package/dist/types/types.d.ts.map +0 -1
- package/src/core/utils/constructors.ts +0 -49
- package/src/core/web-api.ts +0 -138
- package/src/example.ts +0 -25
- package/src/types.ts +0 -84
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
import type { Deferred } from './utils/deferred';
|
|
2
|
+
import { createDeferred } from './utils/deferred';
|
|
3
|
+
|
|
4
|
+
interface StreamListener<T> {
|
|
5
|
+
next(value: T): void;
|
|
6
|
+
throw(value: unknown): void;
|
|
7
|
+
return(value: T): void;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Stream<T> {
|
|
11
|
+
__SEROVAL_STREAM__: true;
|
|
12
|
+
|
|
13
|
+
on(listener: StreamListener<T>): () => void;
|
|
14
|
+
|
|
15
|
+
next(value: T): void;
|
|
16
|
+
throw(value: unknown): void;
|
|
17
|
+
return(value: T): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function isStream<T>(value: object): value is Stream<T> {
|
|
21
|
+
return '__SEROVAL_STREAM__' in value;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function createStream<T>(): Stream<T> {
|
|
25
|
+
const listeners = new Set<StreamListener<T>>();
|
|
26
|
+
const buffer: unknown[] = [];
|
|
27
|
+
let alive = true;
|
|
28
|
+
let success = false;
|
|
29
|
+
|
|
30
|
+
function flushNext(value: T): void {
|
|
31
|
+
for (const listener of listeners.keys()) {
|
|
32
|
+
listener.next(value);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function flushThrow(value: unknown): void {
|
|
37
|
+
for (const listener of listeners.keys()) {
|
|
38
|
+
listener.throw(value);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function flushReturn(value: T): void {
|
|
43
|
+
for (const listener of listeners.keys()) {
|
|
44
|
+
listener.return(value);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
__SEROVAL_STREAM__: true,
|
|
50
|
+
on(listener: StreamListener<T>): () => void {
|
|
51
|
+
if (alive) {
|
|
52
|
+
listeners.add(listener);
|
|
53
|
+
}
|
|
54
|
+
for (let i = 0, len = buffer.length; i < len; i++) {
|
|
55
|
+
const value = buffer[i];
|
|
56
|
+
if (i === len - 1) {
|
|
57
|
+
if (success) {
|
|
58
|
+
listener.return(value as T);
|
|
59
|
+
} else {
|
|
60
|
+
listener.throw(value);
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
listener.next(value as T);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return () => {
|
|
67
|
+
if (alive) {
|
|
68
|
+
listeners.delete(listener);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
next(value): void {
|
|
73
|
+
if (alive) {
|
|
74
|
+
buffer.push(value);
|
|
75
|
+
flushNext(value);
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
throw(value): void {
|
|
79
|
+
if (alive) {
|
|
80
|
+
buffer.push(value);
|
|
81
|
+
flushThrow(value);
|
|
82
|
+
alive = false;
|
|
83
|
+
success = false;
|
|
84
|
+
listeners.clear();
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
return(value): void {
|
|
88
|
+
if (alive) {
|
|
89
|
+
buffer.push(value);
|
|
90
|
+
flushReturn(value);
|
|
91
|
+
alive = false;
|
|
92
|
+
success = true;
|
|
93
|
+
listeners.clear();
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export function createStreamFromAsyncIterable<T>(
|
|
100
|
+
iterable: AsyncIterable<T>,
|
|
101
|
+
): Stream<T> {
|
|
102
|
+
const stream = createStream<T>();
|
|
103
|
+
|
|
104
|
+
const iterator = iterable[Symbol.asyncIterator]();
|
|
105
|
+
|
|
106
|
+
async function push(): Promise<void> {
|
|
107
|
+
try {
|
|
108
|
+
const value = await iterator.next();
|
|
109
|
+
if (value.done) {
|
|
110
|
+
stream.return(value.value as T);
|
|
111
|
+
} else {
|
|
112
|
+
stream.next(value.value);
|
|
113
|
+
await push();
|
|
114
|
+
}
|
|
115
|
+
} catch (error) {
|
|
116
|
+
stream.throw(error);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
push().catch(() => {
|
|
121
|
+
// no-op
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
return stream;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
export function streamToAsyncIterable<T>(
|
|
128
|
+
stream: Stream<T>,
|
|
129
|
+
): () => AsyncIterableIterator<T> {
|
|
130
|
+
return (): AsyncIterableIterator<T> => {
|
|
131
|
+
const buffer: T[] = [];
|
|
132
|
+
const pending: Deferred[] = [];
|
|
133
|
+
let count = 0;
|
|
134
|
+
let doneAt = -1;
|
|
135
|
+
let isThrow = false;
|
|
136
|
+
|
|
137
|
+
function resolveAll(): void {
|
|
138
|
+
for (let i = 0, len = pending.length; i < len; i++) {
|
|
139
|
+
pending[i].resolve({ done: true, value: undefined });
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
stream.on({
|
|
144
|
+
next(value) {
|
|
145
|
+
const current = pending.shift();
|
|
146
|
+
if (current) {
|
|
147
|
+
current.resolve({ done: false, value });
|
|
148
|
+
}
|
|
149
|
+
buffer.push(value);
|
|
150
|
+
},
|
|
151
|
+
throw(value) {
|
|
152
|
+
const current = pending.shift();
|
|
153
|
+
if (current) {
|
|
154
|
+
current.reject(value);
|
|
155
|
+
}
|
|
156
|
+
resolveAll();
|
|
157
|
+
doneAt = buffer.length;
|
|
158
|
+
buffer.push(value as T);
|
|
159
|
+
isThrow = true;
|
|
160
|
+
},
|
|
161
|
+
return(value) {
|
|
162
|
+
const current = pending.shift();
|
|
163
|
+
if (current) {
|
|
164
|
+
current.resolve({ done: true, value });
|
|
165
|
+
}
|
|
166
|
+
resolveAll();
|
|
167
|
+
doneAt = buffer.length;
|
|
168
|
+
buffer.push(value);
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
function finalize() {
|
|
173
|
+
const current = count++;
|
|
174
|
+
const value = buffer[current];
|
|
175
|
+
if (current !== doneAt) {
|
|
176
|
+
return { done: false, value };
|
|
177
|
+
}
|
|
178
|
+
if (isThrow) {
|
|
179
|
+
throw value;
|
|
180
|
+
}
|
|
181
|
+
return { done: true, value };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
return {
|
|
185
|
+
[Symbol.asyncIterator](): AsyncIterableIterator<T> {
|
|
186
|
+
return this;
|
|
187
|
+
},
|
|
188
|
+
async next(): Promise<IteratorResult<T>> {
|
|
189
|
+
if (doneAt === -1) {
|
|
190
|
+
const current = count++;
|
|
191
|
+
if (current >= buffer.length) {
|
|
192
|
+
const deferred = createDeferred();
|
|
193
|
+
pending.push(deferred);
|
|
194
|
+
return (await deferred.promise) as Promise<IteratorResult<T>>;
|
|
195
|
+
}
|
|
196
|
+
return { done: false, value: buffer[current] };
|
|
197
|
+
}
|
|
198
|
+
if (count > doneAt) {
|
|
199
|
+
return { done: true, value: undefined };
|
|
200
|
+
}
|
|
201
|
+
return finalize();
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
}
|
package/src/core/string.ts
CHANGED
|
@@ -1,16 +1,27 @@
|
|
|
1
1
|
export function serializeChar(str: string): string | undefined {
|
|
2
2
|
switch (str) {
|
|
3
|
-
case '"':
|
|
4
|
-
|
|
5
|
-
case '
|
|
6
|
-
|
|
7
|
-
case '\
|
|
8
|
-
|
|
9
|
-
case '\
|
|
10
|
-
|
|
11
|
-
case '\
|
|
12
|
-
|
|
13
|
-
|
|
3
|
+
case '"':
|
|
4
|
+
return '\\"';
|
|
5
|
+
case '\\':
|
|
6
|
+
return '\\\\';
|
|
7
|
+
case '\n':
|
|
8
|
+
return '\\n';
|
|
9
|
+
case '\r':
|
|
10
|
+
return '\\r';
|
|
11
|
+
case '\b':
|
|
12
|
+
return '\\b';
|
|
13
|
+
case '\t':
|
|
14
|
+
return '\\t';
|
|
15
|
+
case '\f':
|
|
16
|
+
return '\\f';
|
|
17
|
+
case '<':
|
|
18
|
+
return '\\x3C';
|
|
19
|
+
case '\u2028':
|
|
20
|
+
return '\\u2028';
|
|
21
|
+
case '\u2029':
|
|
22
|
+
return '\\u2029';
|
|
23
|
+
default:
|
|
24
|
+
return undefined;
|
|
14
25
|
}
|
|
15
26
|
}
|
|
16
27
|
|
|
@@ -38,16 +49,36 @@ export function serializeString(str: string): string {
|
|
|
38
49
|
return result;
|
|
39
50
|
}
|
|
40
51
|
|
|
52
|
+
function deserializeReplacer(str: string): string {
|
|
53
|
+
switch (str) {
|
|
54
|
+
case '\\\\':
|
|
55
|
+
return '\\';
|
|
56
|
+
case '\\"':
|
|
57
|
+
return '"';
|
|
58
|
+
case '\\n':
|
|
59
|
+
return '\n';
|
|
60
|
+
case '\\r':
|
|
61
|
+
return '\r';
|
|
62
|
+
case '\\b':
|
|
63
|
+
return '\b';
|
|
64
|
+
case '\\t':
|
|
65
|
+
return '\t';
|
|
66
|
+
case '\\f':
|
|
67
|
+
return '\f';
|
|
68
|
+
case '\\x3C':
|
|
69
|
+
return '\x3C';
|
|
70
|
+
case '\\u2028':
|
|
71
|
+
return '\u2028';
|
|
72
|
+
case '\\u2029':
|
|
73
|
+
return '\u2029';
|
|
74
|
+
default:
|
|
75
|
+
return str;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
41
79
|
export function deserializeString(str: string): string {
|
|
42
|
-
return str
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.replace(/\\r/g, '\r')
|
|
47
|
-
.replace(/\\b/g, '\b')
|
|
48
|
-
.replace(/\\t/g, '\t')
|
|
49
|
-
.replace(/\\f/g, '\f')
|
|
50
|
-
.replace(/\\x3C/g, '<')
|
|
51
|
-
.replace(/\\u2028/g, '\u2028')
|
|
52
|
-
.replace(/\\u2029/g, '\u2029');
|
|
80
|
+
return str.replace(
|
|
81
|
+
/(\\\\|\\"|\\n|\\r|\\b|\\t|\\f|\\u2028|\\u2029|\\x3C)/g,
|
|
82
|
+
deserializeReplacer,
|
|
83
|
+
);
|
|
53
84
|
}
|
package/src/core/tree/async.ts
CHANGED
|
@@ -2,7 +2,7 @@ import BaseAsyncParserContext from '../context/parser/async';
|
|
|
2
2
|
import type { BaseParserContextOptions } from '../context/parser';
|
|
3
3
|
import type { SerovalMode } from '../plugin';
|
|
4
4
|
|
|
5
|
-
export type AsyncParserContextOptions = Omit<BaseParserContextOptions, 'refs'
|
|
5
|
+
export type AsyncParserContextOptions = Omit<BaseParserContextOptions, 'refs'>;
|
|
6
6
|
|
|
7
7
|
export default class AsyncParserContext extends BaseAsyncParserContext {
|
|
8
8
|
readonly mode: SerovalMode = 'vanilla';
|
|
@@ -2,7 +2,8 @@ import BaseDeserializerContext from '../context/deserializer';
|
|
|
2
2
|
import type { BaseDeserializerOptions } from '../context/deserializer';
|
|
3
3
|
import type { SerovalMode } from '../plugin';
|
|
4
4
|
|
|
5
|
-
export interface VanillaDeserializerContextOptions
|
|
5
|
+
export interface VanillaDeserializerContextOptions
|
|
6
|
+
extends Omit<BaseDeserializerOptions, 'refs'> {
|
|
6
7
|
markedRefs: number[] | Set<number>;
|
|
7
8
|
}
|
|
8
9
|
|
|
@@ -12,17 +13,11 @@ export default class VanillaDeserializerContext extends BaseDeserializerContext
|
|
|
12
13
|
marked: Set<number>;
|
|
13
14
|
|
|
14
15
|
constructor(options: VanillaDeserializerContextOptions) {
|
|
15
|
-
super(
|
|
16
|
-
plugins: options.plugins,
|
|
17
|
-
refs: undefined,
|
|
18
|
-
});
|
|
16
|
+
super(options);
|
|
19
17
|
this.marked = new Set(options.markedRefs);
|
|
20
18
|
}
|
|
21
19
|
|
|
22
|
-
assignIndexedValue<T>(
|
|
23
|
-
index: number,
|
|
24
|
-
value: T,
|
|
25
|
-
): T {
|
|
20
|
+
assignIndexedValue<T>(index: number, value: T): T {
|
|
26
21
|
if (this.marked.has(index)) {
|
|
27
22
|
this.refs.set(index, value);
|
|
28
23
|
}
|
package/src/core/tree/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { resolvePlugins, type PluginAccessOptions } from '../plugin';
|
|
2
2
|
import type { SerovalNode } from '../types';
|
|
3
3
|
import type { AsyncParserContextOptions } from './async';
|
|
4
4
|
import AsyncParserContext from './async';
|
|
@@ -11,13 +11,14 @@ export function serialize<T>(
|
|
|
11
11
|
source: T,
|
|
12
12
|
options: SyncParserContextOptions = {},
|
|
13
13
|
): string {
|
|
14
|
+
const plugins = resolvePlugins(options.plugins);
|
|
14
15
|
const ctx = new SyncParserContext({
|
|
15
|
-
plugins
|
|
16
|
+
plugins,
|
|
16
17
|
disabledFeatures: options.disabledFeatures,
|
|
17
18
|
});
|
|
18
19
|
const tree = ctx.parse(source);
|
|
19
20
|
const serial = new VanillaSerializerContext({
|
|
20
|
-
plugins
|
|
21
|
+
plugins,
|
|
21
22
|
features: ctx.features,
|
|
22
23
|
markedRefs: ctx.marked,
|
|
23
24
|
});
|
|
@@ -28,13 +29,14 @@ export async function serializeAsync<T>(
|
|
|
28
29
|
source: T,
|
|
29
30
|
options: AsyncParserContextOptions = {},
|
|
30
31
|
): Promise<string> {
|
|
32
|
+
const plugins = resolvePlugins(options.plugins);
|
|
31
33
|
const ctx = new AsyncParserContext({
|
|
32
|
-
plugins
|
|
34
|
+
plugins,
|
|
33
35
|
disabledFeatures: options.disabledFeatures,
|
|
34
36
|
});
|
|
35
37
|
const tree = await ctx.parse(source);
|
|
36
38
|
const serial = new VanillaSerializerContext({
|
|
37
|
-
plugins
|
|
39
|
+
plugins,
|
|
38
40
|
features: ctx.features,
|
|
39
41
|
markedRefs: ctx.marked,
|
|
40
42
|
});
|
|
@@ -42,7 +44,6 @@ export async function serializeAsync<T>(
|
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
export function deserialize<T>(source: string): T {
|
|
45
|
-
// eslint-disable-next-line no-eval
|
|
46
47
|
return (0, eval)(source) as T;
|
|
47
48
|
}
|
|
48
49
|
|
|
@@ -56,8 +57,9 @@ export function toJSON<T>(
|
|
|
56
57
|
source: T,
|
|
57
58
|
options: SyncParserContextOptions = {},
|
|
58
59
|
): SerovalJSON {
|
|
60
|
+
const plugins = resolvePlugins(options.plugins);
|
|
59
61
|
const ctx = new SyncParserContext({
|
|
60
|
-
plugins
|
|
62
|
+
plugins,
|
|
61
63
|
disabledFeatures: options.disabledFeatures,
|
|
62
64
|
});
|
|
63
65
|
return {
|
|
@@ -71,8 +73,9 @@ export async function toJSONAsync<T>(
|
|
|
71
73
|
source: T,
|
|
72
74
|
options: AsyncParserContextOptions = {},
|
|
73
75
|
): Promise<SerovalJSON> {
|
|
76
|
+
const plugins = resolvePlugins(options.plugins);
|
|
74
77
|
const ctx = new AsyncParserContext({
|
|
75
|
-
plugins
|
|
78
|
+
plugins,
|
|
76
79
|
disabledFeatures: options.disabledFeatures,
|
|
77
80
|
});
|
|
78
81
|
return {
|
|
@@ -83,8 +86,9 @@ export async function toJSONAsync<T>(
|
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
export function compileJSON(source: SerovalJSON, options: PluginAccessOptions = {}): string {
|
|
89
|
+
const plugins = resolvePlugins(options.plugins);
|
|
86
90
|
const ctx = new VanillaSerializerContext({
|
|
87
|
-
plugins
|
|
91
|
+
plugins,
|
|
88
92
|
features: source.f,
|
|
89
93
|
markedRefs: source.m,
|
|
90
94
|
});
|
|
@@ -92,8 +96,9 @@ export function compileJSON(source: SerovalJSON, options: PluginAccessOptions =
|
|
|
92
96
|
}
|
|
93
97
|
|
|
94
98
|
export function fromJSON<T>(source: SerovalJSON, options: PluginAccessOptions = {}): T {
|
|
99
|
+
const plugins = resolvePlugins(options.plugins);
|
|
95
100
|
const ctx = new VanillaDeserializerContext({
|
|
96
|
-
plugins
|
|
101
|
+
plugins,
|
|
97
102
|
markedRefs: source.m,
|
|
98
103
|
});
|
|
99
104
|
return ctx.deserialize(source.t) as T;
|
|
@@ -3,10 +3,6 @@ import type {
|
|
|
3
3
|
SerovalPromiseConstructorNode,
|
|
4
4
|
SerovalPromiseRejectNode,
|
|
5
5
|
SerovalPromiseResolveNode,
|
|
6
|
-
SerovalReadableStreamCloseNode,
|
|
7
|
-
SerovalReadableStreamConstructorNode,
|
|
8
|
-
SerovalReadableStreamEnqueueNode,
|
|
9
|
-
SerovalReadableStreamErrorNode,
|
|
10
6
|
} from '../types';
|
|
11
7
|
import type { BaseSerializerContextOptions } from '../context/serializer';
|
|
12
8
|
import BaseSerializerContext from '../context/serializer';
|
|
@@ -14,7 +10,7 @@ import getIdentifier from '../utils/get-identifier';
|
|
|
14
10
|
import type { SerovalMode } from '../plugin';
|
|
15
11
|
import { SerovalNodeType } from '../constants';
|
|
16
12
|
|
|
17
|
-
export type VanillaSerializerContextOptions = BaseSerializerContextOptions
|
|
13
|
+
export type VanillaSerializerContextOptions = BaseSerializerContextOptions;
|
|
18
14
|
|
|
19
15
|
export default class VanillaSerializerContext extends BaseSerializerContext {
|
|
20
16
|
readonly mode: SerovalMode = 'vanilla';
|
|
@@ -23,7 +19,7 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
|
|
|
23
19
|
* Map tree refs to actual refs
|
|
24
20
|
* @private
|
|
25
21
|
*/
|
|
26
|
-
valid = new Map<number
|
|
22
|
+
valid = new Map<number, number>();
|
|
27
23
|
|
|
28
24
|
/**
|
|
29
25
|
* Variables
|
|
@@ -31,20 +27,11 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
|
|
|
31
27
|
*/
|
|
32
28
|
vars: string[] = [];
|
|
33
29
|
|
|
34
|
-
/**
|
|
35
|
-
* Increments the number of references the referenced value has
|
|
36
|
-
*/
|
|
37
|
-
markRef(
|
|
38
|
-
current: number,
|
|
39
|
-
): void {
|
|
40
|
-
this.marked.add(current);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
30
|
/**
|
|
44
31
|
* Creates the reference param (identifier) from the given reference ID
|
|
45
32
|
* Calling this function means the value has been referenced somewhere
|
|
46
33
|
*/
|
|
47
|
-
getRefParam(index: number
|
|
34
|
+
getRefParam(index: number): string {
|
|
48
35
|
/**
|
|
49
36
|
* Creates a new reference ID from a given reference ID
|
|
50
37
|
* This new reference ID means that the reference itself
|
|
@@ -64,10 +51,7 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
|
|
|
64
51
|
return identifier;
|
|
65
52
|
}
|
|
66
53
|
|
|
67
|
-
protected assignIndexedValue(
|
|
68
|
-
index: number,
|
|
69
|
-
value: string,
|
|
70
|
-
): string {
|
|
54
|
+
protected assignIndexedValue(index: number, value: string): string {
|
|
71
55
|
if (this.isMarked(index)) {
|
|
72
56
|
return this.getRefParam(index) + '=' + value;
|
|
73
57
|
}
|
|
@@ -80,39 +64,11 @@ export default class VanillaSerializerContext extends BaseSerializerContext {
|
|
|
80
64
|
throw new Error('Unsupported node type "' + node.t + '".');
|
|
81
65
|
}
|
|
82
66
|
|
|
83
|
-
protected serializePromiseResolve(
|
|
84
|
-
node: SerovalPromiseResolveNode,
|
|
85
|
-
): string {
|
|
86
|
-
throw new Error('Unsupported node type "' + node.t + '".');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
protected serializePromiseReject(
|
|
90
|
-
node: SerovalPromiseRejectNode,
|
|
91
|
-
): string {
|
|
67
|
+
protected serializePromiseResolve(node: SerovalPromiseResolveNode): string {
|
|
92
68
|
throw new Error('Unsupported node type "' + node.t + '".');
|
|
93
69
|
}
|
|
94
70
|
|
|
95
|
-
protected
|
|
96
|
-
node: SerovalReadableStreamConstructorNode,
|
|
97
|
-
): string {
|
|
98
|
-
throw new Error('Unsupported node type "' + node.t + '".');
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
protected serializeReadableStreamEnqueue(
|
|
102
|
-
node: SerovalReadableStreamEnqueueNode,
|
|
103
|
-
): string {
|
|
104
|
-
throw new Error('Unsupported node type "' + node.t + '".');
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
protected serializeReadableStreamError(
|
|
108
|
-
node: SerovalReadableStreamErrorNode,
|
|
109
|
-
): string {
|
|
110
|
-
throw new Error('Unsupported node type "' + node.t + '".');
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
protected serializeReadableStreamClose(
|
|
114
|
-
node: SerovalReadableStreamCloseNode,
|
|
115
|
-
): string {
|
|
71
|
+
protected serializePromiseReject(node: SerovalPromiseRejectNode): string {
|
|
116
72
|
throw new Error('Unsupported node type "' + node.t + '".');
|
|
117
73
|
}
|
|
118
74
|
|