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