seroval 0.3.0 → 0.4.0-alpha.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.
- package/README.md +88 -3
- package/dist/cjs/development/index.cjs +596 -250
- package/dist/cjs/development/index.cjs.map +3 -3
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +596 -250
- package/dist/esm/development/index.mjs.map +3 -3
- package/dist/esm/production/index.mjs +2 -2
- package/dist/types/assert.d.ts +1 -0
- package/dist/types/compat.d.ts +35 -0
- package/dist/types/index.d.ts +3 -2
- package/dist/types/tree.d.ts +44 -25
- package/package.json +2 -2
- package/src/assert.ts +5 -0
- package/src/compat.ts +246 -0
- package/src/index.ts +35 -16
- package/src/tree.ts +484 -269
- package/dist/types/serialize-primitive.d.ts +0 -2
- package/src/serialize-primitive.ts +0 -35
package/src/compat.ts
ADDED
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
/* eslint-disable guard-for-in */
|
|
2
|
+
/**
|
|
3
|
+
* References
|
|
4
|
+
* - https://kangax.github.io/compat-table/es6/
|
|
5
|
+
* - MDN
|
|
6
|
+
* - ESBuild
|
|
7
|
+
*/
|
|
8
|
+
|
|
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
|
+
export const enum Feature {
|
|
43
|
+
AggregateError,
|
|
44
|
+
ArrayPrototypeValues,
|
|
45
|
+
ArrowFunction,
|
|
46
|
+
BigInt,
|
|
47
|
+
Map,
|
|
48
|
+
MethodShorthand,
|
|
49
|
+
ObjectAssign,
|
|
50
|
+
Promise,
|
|
51
|
+
Set,
|
|
52
|
+
SymbolIterator,
|
|
53
|
+
TypedArray,
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
type VersionTable = {
|
|
57
|
+
[key in Feature]: PlatformVersion;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const VERSION_TABLE: VersionTable = {
|
|
61
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AggregateError#browser_compatibility
|
|
62
|
+
[Feature.AggregateError]: {
|
|
63
|
+
es: [2021, 0, 0],
|
|
64
|
+
chrome: [85, 0, 0],
|
|
65
|
+
edge: [85, 0, 0],
|
|
66
|
+
firefox: [79, 0, 0],
|
|
67
|
+
opera: [71, 0, 0],
|
|
68
|
+
safari: [14, 0, 0],
|
|
69
|
+
ios: [14, 0, 0],
|
|
70
|
+
samsung: [14, 0, 0],
|
|
71
|
+
deno: [1, 2, 0],
|
|
72
|
+
node: [15, 0, 0],
|
|
73
|
+
},
|
|
74
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values#browser_compatibility
|
|
75
|
+
[Feature.ArrayPrototypeValues]: {
|
|
76
|
+
es: [6, 0, 0],
|
|
77
|
+
chrome: [66, 0, 0],
|
|
78
|
+
edge: [14, 0, 0],
|
|
79
|
+
firefox: [60, 0, 0],
|
|
80
|
+
opera: [53, 0, 0],
|
|
81
|
+
safari: [9, 0, 0],
|
|
82
|
+
ios: [9, 0, 0],
|
|
83
|
+
samsung: [9, 0, 0],
|
|
84
|
+
deno: [1, 0, 0],
|
|
85
|
+
node: [10, 9, 0],
|
|
86
|
+
},
|
|
87
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions#browser_compatibility
|
|
88
|
+
[Feature.ArrowFunction]: {
|
|
89
|
+
es: [6, 0, 0],
|
|
90
|
+
chrome: [45, 0, 0],
|
|
91
|
+
edge: [12, 0, 0],
|
|
92
|
+
firefox: [24, 0, 0],
|
|
93
|
+
opera: [32, 0, 0],
|
|
94
|
+
safari: [10, 0, 0],
|
|
95
|
+
ios: [10, 0, 0],
|
|
96
|
+
samsung: [5, 0, 0],
|
|
97
|
+
deno: [1, 0, 0],
|
|
98
|
+
node: [4, 0, 0],
|
|
99
|
+
},
|
|
100
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt#browser_compatibility
|
|
101
|
+
[Feature.BigInt]: {
|
|
102
|
+
es: [2020, 0, 0],
|
|
103
|
+
chrome: [67, 0, 0],
|
|
104
|
+
edge: [79, 0, 0],
|
|
105
|
+
firefox: [68, 0, 0],
|
|
106
|
+
opera: [54, 0, 0],
|
|
107
|
+
safari: [14, 0, 0],
|
|
108
|
+
ios: [14, 0, 0],
|
|
109
|
+
samsung: [9, 0, 0],
|
|
110
|
+
deno: [1, 0, 0],
|
|
111
|
+
node: [10, 4, 0],
|
|
112
|
+
},
|
|
113
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map#browser_compatibility
|
|
114
|
+
[Feature.Map]: {
|
|
115
|
+
es: [6, 0, 0],
|
|
116
|
+
chrome: [38, 0, 0],
|
|
117
|
+
edge: [12, 0, 0],
|
|
118
|
+
firefox: [13, 0, 0],
|
|
119
|
+
opera: [25, 0, 0],
|
|
120
|
+
safari: [8, 0, 0],
|
|
121
|
+
ios: [8, 0, 0],
|
|
122
|
+
samsung: [3, 0, 0],
|
|
123
|
+
deno: [1, 0, 0],
|
|
124
|
+
node: [0, 12, 0],
|
|
125
|
+
},
|
|
126
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions#browser_compatibility
|
|
127
|
+
[Feature.MethodShorthand]: {
|
|
128
|
+
es: [6, 0, 0],
|
|
129
|
+
chrome: [39, 0, 0],
|
|
130
|
+
edge: [12, 0, 0],
|
|
131
|
+
firefox: [34, 0, 0],
|
|
132
|
+
opera: [26, 0, 0],
|
|
133
|
+
safari: [9, 0, 0],
|
|
134
|
+
ios: [9, 0, 0],
|
|
135
|
+
samsung: [4, 0, 0],
|
|
136
|
+
deno: [1, 0, 0],
|
|
137
|
+
node: [4, 0, 0],
|
|
138
|
+
},
|
|
139
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#browser_compatibility
|
|
140
|
+
[Feature.ObjectAssign]: {
|
|
141
|
+
es: [6, 0, 0],
|
|
142
|
+
chrome: [45, 0, 0],
|
|
143
|
+
edge: [12, 0, 0],
|
|
144
|
+
firefox: [34, 0, 0],
|
|
145
|
+
opera: [32, 0, 0],
|
|
146
|
+
safari: [9, 0, 0],
|
|
147
|
+
ios: [9, 0, 0],
|
|
148
|
+
samsung: [5, 0, 0],
|
|
149
|
+
deno: [1, 0, 0],
|
|
150
|
+
node: [4, 0, 0],
|
|
151
|
+
},
|
|
152
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise#browser_compatibility
|
|
153
|
+
[Feature.Promise]: {
|
|
154
|
+
es: [6, 0, 0],
|
|
155
|
+
chrome: [32, 0, 0],
|
|
156
|
+
edge: [12, 0, 0],
|
|
157
|
+
firefox: [29, 0, 0],
|
|
158
|
+
opera: [19, 0, 0],
|
|
159
|
+
safari: [8, 0, 0],
|
|
160
|
+
ios: [8, 0, 0],
|
|
161
|
+
samsung: [2, 0, 0],
|
|
162
|
+
deno: [1, 0, 0],
|
|
163
|
+
node: [0, 12, 0],
|
|
164
|
+
},
|
|
165
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#browser_compatibility
|
|
166
|
+
[Feature.Set]: {
|
|
167
|
+
es: [6, 0, 0],
|
|
168
|
+
chrome: [38, 0, 0],
|
|
169
|
+
edge: [12, 0, 0],
|
|
170
|
+
firefox: [13, 0, 0],
|
|
171
|
+
opera: [25, 0, 0],
|
|
172
|
+
safari: [8, 0, 0],
|
|
173
|
+
ios: [8, 0, 0],
|
|
174
|
+
samsung: [3, 0, 0],
|
|
175
|
+
deno: [1, 0, 0],
|
|
176
|
+
node: [0, 12, 0],
|
|
177
|
+
},
|
|
178
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator#browser_compatibility
|
|
179
|
+
[Feature.SymbolIterator]: {
|
|
180
|
+
es: [6, 0, 0],
|
|
181
|
+
chrome: [43, 0, 0],
|
|
182
|
+
edge: [12, 0, 0],
|
|
183
|
+
firefox: [36, 0, 0],
|
|
184
|
+
opera: [30, 0, 0],
|
|
185
|
+
safari: [10, 0, 0],
|
|
186
|
+
ios: [10, 0, 0],
|
|
187
|
+
samsung: [4, 0, 0],
|
|
188
|
+
deno: [1, 0, 0],
|
|
189
|
+
node: [0, 12, 0],
|
|
190
|
+
},
|
|
191
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray#browser_compatibility
|
|
192
|
+
[Feature.TypedArray]: {
|
|
193
|
+
es: [6, 0, 0],
|
|
194
|
+
chrome: [7, 0, 0],
|
|
195
|
+
edge: [12, 0, 0],
|
|
196
|
+
firefox: [4, 0, 0],
|
|
197
|
+
opera: [11, 6, 0],
|
|
198
|
+
safari: [5, 1, 0],
|
|
199
|
+
ios: [4, 2, 0],
|
|
200
|
+
samsung: [1, 0, 0],
|
|
201
|
+
deno: [1, 0, 0],
|
|
202
|
+
node: [0, 10, 0],
|
|
203
|
+
},
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
const TARGET_REGEX = /^(es|chrome|edge|safari|firefox|opera|ios|samsung|deno|node)([0-9]+(\.[0-9]+(\.[0-9]+)?)?)$/i;
|
|
207
|
+
|
|
208
|
+
export type Target = [platform: Platform, version: Version];
|
|
209
|
+
|
|
210
|
+
function parseTarget(target: string): Target {
|
|
211
|
+
const result = TARGET_REGEX.exec(target);
|
|
212
|
+
assert(result, `Invalid target "${target}"`);
|
|
213
|
+
const [, platform, version] = result;
|
|
214
|
+
const [major, minor = '0', patch = '0'] = version.split('.');
|
|
215
|
+
return [platform as Platform, [Number(major), Number(minor), Number(patch)]];
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
function getTargetVersions(targets: string | string[]): Target[] {
|
|
219
|
+
if (Array.isArray(targets)) {
|
|
220
|
+
const versions: Target[] = [];
|
|
221
|
+
for (const target of targets) {
|
|
222
|
+
versions.push(parseTarget(target));
|
|
223
|
+
}
|
|
224
|
+
return versions;
|
|
225
|
+
}
|
|
226
|
+
return [parseTarget(targets)];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function parseTargets(targets: string | string[]): Set<Feature> {
|
|
230
|
+
const parsed = getTargetVersions(targets);
|
|
231
|
+
const flags = new Set<Feature>();
|
|
232
|
+
|
|
233
|
+
for (const key in VERSION_TABLE) {
|
|
234
|
+
const base = VERSION_TABLE[key as unknown as Feature];
|
|
235
|
+
let flag = true;
|
|
236
|
+
for (const [platform, version] of parsed) {
|
|
237
|
+
const baseVersion = base[platform];
|
|
238
|
+
flag = flag && !!baseVersion && (compareVersion(baseVersion, version) <= 0);
|
|
239
|
+
}
|
|
240
|
+
if (flag) {
|
|
241
|
+
flags.add(Number(key) as unknown as Feature);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
return flags;
|
|
246
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/* eslint-disable no-await-in-loop */
|
|
2
2
|
import { isPrimitive } from './checks';
|
|
3
|
-
import
|
|
3
|
+
import { Feature } from './compat';
|
|
4
4
|
import {
|
|
5
5
|
createRef,
|
|
6
6
|
createSerializationContext,
|
|
7
7
|
generateTreeAsync,
|
|
8
8
|
generateTreeSync,
|
|
9
9
|
getRefParam,
|
|
10
|
+
Options,
|
|
10
11
|
resolvePatches,
|
|
11
12
|
SerializationContext,
|
|
13
|
+
serializePrimitive,
|
|
12
14
|
serializeTree,
|
|
13
15
|
} from './tree';
|
|
14
16
|
import {
|
|
@@ -30,24 +32,35 @@ export {
|
|
|
30
32
|
ErrorValue,
|
|
31
33
|
};
|
|
32
34
|
|
|
33
|
-
function finalize<T extends ServerValue | AsyncServerValue
|
|
35
|
+
function finalize<T extends NonPrimitiveServerValue<ServerValue | AsyncServerValue>>(
|
|
34
36
|
ctx: SerializationContext,
|
|
35
|
-
source:
|
|
37
|
+
source: T,
|
|
36
38
|
result: string,
|
|
37
39
|
) {
|
|
38
40
|
// Shared references detected
|
|
39
41
|
if (ctx.vars.length) {
|
|
40
|
-
// Get (or create) a ref from the source
|
|
41
|
-
const index = getRefParam(ctx, createRef(ctx, source));
|
|
42
42
|
const patches = resolvePatches(ctx);
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
let body = result;
|
|
44
|
+
if (patches) {
|
|
45
|
+
// Get (or create) a ref from the source
|
|
46
|
+
const index = getRefParam(ctx, createRef(ctx, source));
|
|
47
|
+
if (result.startsWith(`${index}=`)) {
|
|
48
|
+
body = `${result},${patches}${index}`;
|
|
49
|
+
} else {
|
|
50
|
+
body = `${index}=${result},${patches}${index}`;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
let params = ctx.vars.length > 1
|
|
54
|
+
? ctx.vars.join(',')
|
|
45
55
|
: ctx.vars[0];
|
|
46
56
|
// Source is probably already assigned
|
|
47
|
-
if (
|
|
48
|
-
|
|
57
|
+
if (ctx.features.has(Feature.ArrowFunction)) {
|
|
58
|
+
params = ctx.vars.length > 1 || ctx.vars.length === 0
|
|
59
|
+
? `(${params})`
|
|
60
|
+
: params;
|
|
61
|
+
return `(${params}=>(${body}))()`;
|
|
49
62
|
}
|
|
50
|
-
return `(${params}
|
|
63
|
+
return `(function(${params}){return ${body}})()`;
|
|
51
64
|
}
|
|
52
65
|
if (source.constructor === Object) {
|
|
53
66
|
return `(${result})`;
|
|
@@ -55,21 +68,27 @@ function finalize<T extends ServerValue | AsyncServerValue>(
|
|
|
55
68
|
return result;
|
|
56
69
|
}
|
|
57
70
|
|
|
58
|
-
export function serialize
|
|
71
|
+
export function serialize<T extends ServerValue>(
|
|
72
|
+
source: T,
|
|
73
|
+
options?: Partial<Options>,
|
|
74
|
+
) {
|
|
75
|
+
const ctx = createSerializationContext(options);
|
|
59
76
|
if (isPrimitive(source)) {
|
|
60
|
-
return serializePrimitive(source);
|
|
77
|
+
return serializePrimitive(ctx, source);
|
|
61
78
|
}
|
|
62
|
-
const ctx = createSerializationContext();
|
|
63
79
|
const tree = generateTreeSync(ctx, source);
|
|
64
80
|
const result = serializeTree(ctx, tree);
|
|
65
81
|
return finalize(ctx, source, result);
|
|
66
82
|
}
|
|
67
83
|
|
|
68
|
-
export async function serializeAsync
|
|
84
|
+
export async function serializeAsync<T extends AsyncServerValue>(
|
|
85
|
+
source: T,
|
|
86
|
+
options?: Partial<Options>,
|
|
87
|
+
) {
|
|
88
|
+
const ctx = createSerializationContext(options);
|
|
69
89
|
if (isPrimitive(source)) {
|
|
70
|
-
return serializePrimitive(source);
|
|
90
|
+
return serializePrimitive(ctx, source);
|
|
71
91
|
}
|
|
72
|
-
const ctx = createSerializationContext();
|
|
73
92
|
const tree = await generateTreeAsync(ctx, source);
|
|
74
93
|
const result = serializeTree(ctx, tree);
|
|
75
94
|
return finalize(ctx, source, result);
|