seroval 0.1.0 → 0.2.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/LICENSE +1 -1
- package/README.md +35 -4
- package/dist/cjs/development/index.cjs +423 -255
- package/dist/cjs/development/index.cjs.map +4 -4
- package/dist/cjs/production/index.cjs +2 -2
- package/dist/esm/development/index.mjs +423 -255
- package/dist/esm/development/index.mjs.map +4 -4
- package/dist/esm/production/index.mjs +2 -2
- package/dist/types/async.d.ts +4 -0
- package/dist/types/context.d.ts +33 -0
- package/dist/types/index.d.ts +6 -5
- package/dist/types/is-primitive.d.ts +2 -0
- package/dist/types/is-promise.d.ts +1 -0
- package/dist/types/serialize-primitive.d.ts +2 -0
- package/dist/types/sync.d.ts +4 -0
- package/dist/types/types.d.ts +13 -0
- package/package.json +2 -2
- package/src/async.ts +229 -0
- package/src/context.ts +200 -0
- package/src/get-identifier.ts +1 -0
- package/src/index.ts +69 -453
- package/src/is-primitive.ts +14 -0
- package/src/is-promise.ts +6 -0
- package/src/serialize-primitive.ts +32 -0
- package/src/sync.ts +199 -0
- package/src/types.ts +36 -0
|
@@ -20,7 +20,10 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var src_exports = {};
|
|
22
22
|
__export(src_exports, {
|
|
23
|
-
default: () =>
|
|
23
|
+
default: () => src_default,
|
|
24
|
+
deserialize: () => deserialize,
|
|
25
|
+
serialize: () => serialize,
|
|
26
|
+
serializeAsync: () => serializeAsync
|
|
24
27
|
});
|
|
25
28
|
module.exports = __toCommonJS(src_exports);
|
|
26
29
|
|
|
@@ -60,73 +63,26 @@ function getIdentifier(index) {
|
|
|
60
63
|
return ref;
|
|
61
64
|
}
|
|
62
65
|
|
|
63
|
-
// src/
|
|
64
|
-
function quote(str) {
|
|
65
|
-
let result = "";
|
|
66
|
-
let lastPos = 0;
|
|
67
|
-
for (let i = 0, len = str.length; i < len; i++) {
|
|
68
|
-
let replacement;
|
|
69
|
-
switch (str[i]) {
|
|
70
|
-
case '"':
|
|
71
|
-
replacement = '\\"';
|
|
72
|
-
break;
|
|
73
|
-
case "\\":
|
|
74
|
-
replacement = "\\\\";
|
|
75
|
-
break;
|
|
76
|
-
case "<":
|
|
77
|
-
replacement = "\\x3C";
|
|
78
|
-
break;
|
|
79
|
-
case "\n":
|
|
80
|
-
replacement = "\\n";
|
|
81
|
-
break;
|
|
82
|
-
case "\r":
|
|
83
|
-
replacement = "\\r";
|
|
84
|
-
break;
|
|
85
|
-
case "\u2028":
|
|
86
|
-
replacement = "\\u2028";
|
|
87
|
-
break;
|
|
88
|
-
case "\u2029":
|
|
89
|
-
replacement = "\\u2029";
|
|
90
|
-
break;
|
|
91
|
-
default:
|
|
92
|
-
continue;
|
|
93
|
-
}
|
|
94
|
-
result += str.slice(lastPos, i) + replacement;
|
|
95
|
-
lastPos = i + 1;
|
|
96
|
-
}
|
|
97
|
-
if (lastPos === 0) {
|
|
98
|
-
result = str;
|
|
99
|
-
} else {
|
|
100
|
-
result += str.slice(lastPos);
|
|
101
|
-
}
|
|
102
|
-
return `"${result}"`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// src/index.ts
|
|
66
|
+
// src/context.ts
|
|
106
67
|
var EMPTY_SET = "new Set";
|
|
107
68
|
var EMPTY_MAP = "new Map";
|
|
108
69
|
var EMPTY_ARRAY = "[]";
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
SET_ADDS = [];
|
|
121
|
-
VARS = [];
|
|
122
|
-
REF_COUNT.clear();
|
|
123
|
-
REFS.clear();
|
|
124
|
-
ASSIGNED_REFS.clear();
|
|
70
|
+
function createSerializationContext() {
|
|
71
|
+
return {
|
|
72
|
+
refCount: /* @__PURE__ */ new Map(),
|
|
73
|
+
stack: /* @__PURE__ */ new Set(),
|
|
74
|
+
refs: /* @__PURE__ */ new Map(),
|
|
75
|
+
assignedRefs: /* @__PURE__ */ new Set(),
|
|
76
|
+
vars: [],
|
|
77
|
+
assignments: [],
|
|
78
|
+
mapSets: [],
|
|
79
|
+
setAdds: []
|
|
80
|
+
};
|
|
125
81
|
}
|
|
126
|
-
function resolveAssignments() {
|
|
127
|
-
if (
|
|
82
|
+
function resolveAssignments(ctx) {
|
|
83
|
+
if (ctx.assignments.length) {
|
|
128
84
|
const result = {};
|
|
129
|
-
forEach(
|
|
85
|
+
forEach(ctx.assignments, ([source, value]) => {
|
|
130
86
|
if (value in result) {
|
|
131
87
|
result[value] = `${source}=${result[value]}`;
|
|
132
88
|
} else {
|
|
@@ -137,10 +93,10 @@ function resolveAssignments() {
|
|
|
137
93
|
}
|
|
138
94
|
return "";
|
|
139
95
|
}
|
|
140
|
-
function resolveMapSets() {
|
|
141
|
-
if (
|
|
96
|
+
function resolveMapSets(ctx) {
|
|
97
|
+
if (ctx.mapSets.length) {
|
|
142
98
|
const result = {};
|
|
143
|
-
forEach(
|
|
99
|
+
forEach(ctx.mapSets, ([source, key, value]) => {
|
|
144
100
|
if (source in result) {
|
|
145
101
|
result[source] = `${result[source]}.set(${key},${value})`;
|
|
146
102
|
} else {
|
|
@@ -151,10 +107,10 @@ function resolveMapSets() {
|
|
|
151
107
|
}
|
|
152
108
|
return "";
|
|
153
109
|
}
|
|
154
|
-
function resolveSetAdds() {
|
|
155
|
-
if (
|
|
110
|
+
function resolveSetAdds(ctx) {
|
|
111
|
+
if (ctx.setAdds.length) {
|
|
156
112
|
const result = {};
|
|
157
|
-
forEach(
|
|
113
|
+
forEach(ctx.setAdds, ([source, value]) => {
|
|
158
114
|
if (source in result) {
|
|
159
115
|
result[source] = `${result[source]}.add(${value})`;
|
|
160
116
|
} else {
|
|
@@ -165,88 +121,114 @@ function resolveSetAdds() {
|
|
|
165
121
|
}
|
|
166
122
|
return "";
|
|
167
123
|
}
|
|
168
|
-
function resolvePatches() {
|
|
169
|
-
return `${resolveAssignments()}${resolveMapSets()}${resolveSetAdds()}`;
|
|
124
|
+
function resolvePatches(ctx) {
|
|
125
|
+
return `${resolveAssignments(ctx)}${resolveMapSets(ctx)}${resolveSetAdds(ctx)}`;
|
|
170
126
|
}
|
|
171
|
-
function insertRef(current) {
|
|
172
|
-
const count =
|
|
173
|
-
|
|
127
|
+
function insertRef(ctx, current) {
|
|
128
|
+
const count = ctx.refCount.get(current) || 0;
|
|
129
|
+
ctx.refCount.set(current, count + 1);
|
|
174
130
|
return count === 0;
|
|
175
131
|
}
|
|
176
132
|
function constructorCheck(value, constructor) {
|
|
177
133
|
return value.constructor === constructor;
|
|
178
134
|
}
|
|
179
|
-
function
|
|
180
|
-
|
|
181
|
-
return true;
|
|
182
|
-
}
|
|
183
|
-
const type = typeof current;
|
|
184
|
-
const classConst = current.constructor;
|
|
185
|
-
return type === "number" || type === "string" || type === "bigint" || classConst === Date || classConst === RegExp;
|
|
186
|
-
}
|
|
187
|
-
function lookupRefs(current) {
|
|
188
|
-
if (isPrimitive(current)) {
|
|
189
|
-
return;
|
|
190
|
-
}
|
|
191
|
-
if (Array.isArray(current)) {
|
|
192
|
-
if (insertRef(current)) {
|
|
193
|
-
forEach(current, lookupRefs);
|
|
194
|
-
}
|
|
195
|
-
} else if (constructorCheck(current, Set)) {
|
|
196
|
-
if (insertRef(current)) {
|
|
197
|
-
for (const item of current.keys()) {
|
|
198
|
-
lookupRefs(item);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
} else if (constructorCheck(current, Map)) {
|
|
202
|
-
if (insertRef(current)) {
|
|
203
|
-
for (const [key, value] of current.entries()) {
|
|
204
|
-
lookupRefs(key);
|
|
205
|
-
lookupRefs(value);
|
|
206
|
-
}
|
|
207
|
-
}
|
|
208
|
-
} else if (current.constructor === Object && insertRef(current)) {
|
|
209
|
-
forEach(Object.values(current), lookupRefs);
|
|
210
|
-
}
|
|
211
|
-
}
|
|
212
|
-
function createRef(value) {
|
|
213
|
-
const current = REFS.get(value);
|
|
135
|
+
function createRef(ctx, value) {
|
|
136
|
+
const current = ctx.refs.get(value);
|
|
214
137
|
if (current != null) {
|
|
215
138
|
return current;
|
|
216
139
|
}
|
|
217
|
-
const id =
|
|
218
|
-
|
|
140
|
+
const id = ctx.refs.size;
|
|
141
|
+
ctx.refs.set(value, id);
|
|
219
142
|
return id;
|
|
220
143
|
}
|
|
221
|
-
function getRefParam(index) {
|
|
222
|
-
if (
|
|
223
|
-
return
|
|
144
|
+
function getRefParam(ctx, index) {
|
|
145
|
+
if (ctx.vars[index]) {
|
|
146
|
+
return ctx.vars[index];
|
|
224
147
|
}
|
|
225
148
|
const result = getIdentifier(index);
|
|
226
|
-
|
|
149
|
+
ctx.vars[index] = result;
|
|
227
150
|
return result;
|
|
228
151
|
}
|
|
229
|
-
function assignRef(index, value) {
|
|
230
|
-
return `${getRefParam(index)}=${value}`;
|
|
152
|
+
function assignRef(ctx, index, value) {
|
|
153
|
+
return `${getRefParam(ctx, index)}=${value}`;
|
|
154
|
+
}
|
|
155
|
+
function createAssignment(ctx, source, value) {
|
|
156
|
+
ctx.assignments.push([source, value]);
|
|
231
157
|
}
|
|
232
|
-
function
|
|
233
|
-
|
|
158
|
+
function createSetAdd(ctx, ref, value) {
|
|
159
|
+
ctx.setAdds.push([getRefParam(ctx, ref), value]);
|
|
234
160
|
}
|
|
235
|
-
function
|
|
236
|
-
|
|
161
|
+
function createMapSet(ctx, ref, key, value) {
|
|
162
|
+
ctx.mapSets.push([getRefParam(ctx, ref), key, value]);
|
|
237
163
|
}
|
|
238
|
-
function
|
|
239
|
-
|
|
164
|
+
function createArrayAssign(ctx, ref, index, value) {
|
|
165
|
+
createAssignment(ctx, `${getRefParam(ctx, ref)}[${index}]`, value);
|
|
240
166
|
}
|
|
241
|
-
function
|
|
242
|
-
createAssignment(`${getRefParam(ref)}
|
|
167
|
+
function createObjectIdentifierAssign(ctx, ref, key, value) {
|
|
168
|
+
createAssignment(ctx, `${getRefParam(ctx, ref)}.${key}`, value);
|
|
243
169
|
}
|
|
244
|
-
function
|
|
245
|
-
createAssignment(`${getRefParam(ref)}
|
|
170
|
+
function createObjectComputedAssign(ctx, ref, key, value) {
|
|
171
|
+
createAssignment(ctx, `${getRefParam(ctx, ref)}[${key}]`, value);
|
|
246
172
|
}
|
|
247
|
-
|
|
248
|
-
|
|
173
|
+
|
|
174
|
+
// src/is-primitive.ts
|
|
175
|
+
function isPrimitive(current) {
|
|
176
|
+
if (!current || current === true) {
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
const type = typeof current;
|
|
180
|
+
const classConst = current.constructor;
|
|
181
|
+
return type === "number" || type === "string" || type === "bigint" || classConst === Date || classConst === RegExp;
|
|
249
182
|
}
|
|
183
|
+
|
|
184
|
+
// src/is-promise.ts
|
|
185
|
+
function isPromise(obj) {
|
|
186
|
+
return !!obj && (typeof obj === "object" || typeof obj === "function") && "then" in obj && typeof obj.then === "function";
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// src/quote.ts
|
|
190
|
+
function quote(str) {
|
|
191
|
+
let result = "";
|
|
192
|
+
let lastPos = 0;
|
|
193
|
+
for (let i = 0, len = str.length; i < len; i++) {
|
|
194
|
+
let replacement;
|
|
195
|
+
switch (str[i]) {
|
|
196
|
+
case '"':
|
|
197
|
+
replacement = '\\"';
|
|
198
|
+
break;
|
|
199
|
+
case "\\":
|
|
200
|
+
replacement = "\\\\";
|
|
201
|
+
break;
|
|
202
|
+
case "<":
|
|
203
|
+
replacement = "\\x3C";
|
|
204
|
+
break;
|
|
205
|
+
case "\n":
|
|
206
|
+
replacement = "\\n";
|
|
207
|
+
break;
|
|
208
|
+
case "\r":
|
|
209
|
+
replacement = "\\r";
|
|
210
|
+
break;
|
|
211
|
+
case "\u2028":
|
|
212
|
+
replacement = "\\u2028";
|
|
213
|
+
break;
|
|
214
|
+
case "\u2029":
|
|
215
|
+
replacement = "\\u2029";
|
|
216
|
+
break;
|
|
217
|
+
default:
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
result += str.slice(lastPos, i) + replacement;
|
|
221
|
+
lastPos = i + 1;
|
|
222
|
+
}
|
|
223
|
+
if (lastPos === 0) {
|
|
224
|
+
result = str;
|
|
225
|
+
} else {
|
|
226
|
+
result += str.slice(lastPos);
|
|
227
|
+
}
|
|
228
|
+
return `"${result}"`;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// src/serialize-primitive.ts
|
|
250
232
|
function serializePrimitive(value) {
|
|
251
233
|
if (value === true) {
|
|
252
234
|
return "!0";
|
|
@@ -274,122 +256,294 @@ function serializePrimitive(value) {
|
|
|
274
256
|
}
|
|
275
257
|
return String(value);
|
|
276
258
|
}
|
|
277
|
-
|
|
259
|
+
|
|
260
|
+
// src/async.ts
|
|
261
|
+
async function lookupRefsAsync(ctx, current) {
|
|
262
|
+
if (isPrimitive(current)) {
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
if (isPromise(current)) {
|
|
266
|
+
if (insertRef(ctx, current)) {
|
|
267
|
+
await current.then((value) => lookupRefsAsync(ctx, value));
|
|
268
|
+
}
|
|
269
|
+
} else if (Array.isArray(current)) {
|
|
270
|
+
if (insertRef(ctx, current)) {
|
|
271
|
+
for (const value of current) {
|
|
272
|
+
await lookupRefsAsync(ctx, value);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
} else if (constructorCheck(current, Set)) {
|
|
276
|
+
if (insertRef(ctx, current)) {
|
|
277
|
+
for (const item of current.keys()) {
|
|
278
|
+
await lookupRefsAsync(ctx, item);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
} else if (constructorCheck(current, Map)) {
|
|
282
|
+
if (insertRef(ctx, current)) {
|
|
283
|
+
for (const [key, value] of current.entries()) {
|
|
284
|
+
await lookupRefsAsync(ctx, key);
|
|
285
|
+
await lookupRefsAsync(ctx, value);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
} else if ((current.constructor === Object || current.constructor == null) && insertRef(ctx, current)) {
|
|
289
|
+
for (const value of Object.values(current)) {
|
|
290
|
+
await lookupRefsAsync(ctx, value);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
async function traverseAsync(ctx, current) {
|
|
278
295
|
if (isPrimitive(current)) {
|
|
279
296
|
return serializePrimitive(current);
|
|
280
297
|
}
|
|
281
|
-
let refResult =
|
|
298
|
+
let refResult = ctx.refs.get(current);
|
|
282
299
|
if (refResult != null) {
|
|
283
|
-
if (
|
|
284
|
-
return
|
|
300
|
+
if (ctx.assignedRefs.has(refResult)) {
|
|
301
|
+
return getRefParam(ctx, refResult);
|
|
285
302
|
}
|
|
286
|
-
|
|
303
|
+
ctx.assignedRefs.add(refResult);
|
|
304
|
+
}
|
|
305
|
+
function getCurrentRef() {
|
|
306
|
+
if (refResult == null) {
|
|
307
|
+
refResult = createRef(ctx, current);
|
|
308
|
+
}
|
|
309
|
+
return refResult;
|
|
310
|
+
}
|
|
311
|
+
function processRef(value) {
|
|
312
|
+
if (refResult != null) {
|
|
313
|
+
return assignRef(ctx, refResult, value);
|
|
314
|
+
}
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
if (isPromise(current)) {
|
|
318
|
+
return current.then(async (value) => {
|
|
319
|
+
ctx.stack.add(current);
|
|
320
|
+
let result;
|
|
321
|
+
if (ctx.stack.has(value)) {
|
|
322
|
+
const refParam = getRefParam(ctx, createRef(ctx, value));
|
|
323
|
+
result = `Promise.resolve().then(()=>${refParam})`;
|
|
324
|
+
} else {
|
|
325
|
+
result = `Promise.resolve(${await traverseAsync(ctx, value)})`;
|
|
326
|
+
}
|
|
327
|
+
ctx.stack.delete(current);
|
|
328
|
+
return processRef(result);
|
|
329
|
+
});
|
|
287
330
|
}
|
|
288
331
|
if (constructorCheck(current, Set)) {
|
|
289
332
|
if (current.size) {
|
|
290
333
|
const values = [];
|
|
291
|
-
|
|
292
|
-
for (const
|
|
293
|
-
if (
|
|
294
|
-
|
|
295
|
-
refResult = createRef(current);
|
|
296
|
-
}
|
|
297
|
-
createSetAdd(refResult, getRefParam(createRef(value2)));
|
|
334
|
+
ctx.stack.add(current);
|
|
335
|
+
for (const value of current.keys()) {
|
|
336
|
+
if (ctx.stack.has(value)) {
|
|
337
|
+
createSetAdd(ctx, getCurrentRef(), getRefParam(ctx, createRef(ctx, value)));
|
|
298
338
|
} else {
|
|
299
|
-
|
|
300
|
-
if (typeof result === "string") {
|
|
301
|
-
values.push(result);
|
|
302
|
-
} else {
|
|
303
|
-
values.push(result.referred);
|
|
304
|
-
}
|
|
339
|
+
values.push(await traverseAsync(ctx, value));
|
|
305
340
|
}
|
|
306
341
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (refResult != null) {
|
|
310
|
-
return assignRef(refResult, value);
|
|
311
|
-
}
|
|
312
|
-
return value;
|
|
342
|
+
ctx.stack.delete(current);
|
|
343
|
+
return processRef(values.length ? `new Set([${join(values, ",")}])` : EMPTY_SET);
|
|
313
344
|
}
|
|
314
345
|
return EMPTY_SET;
|
|
315
346
|
}
|
|
316
347
|
if (constructorCheck(current, Map)) {
|
|
317
348
|
if (current.size) {
|
|
318
349
|
const values = [];
|
|
319
|
-
|
|
320
|
-
for (const [key,
|
|
321
|
-
if (
|
|
322
|
-
|
|
323
|
-
|
|
350
|
+
ctx.stack.add(current);
|
|
351
|
+
for (const [key, value] of current.entries()) {
|
|
352
|
+
if (ctx.stack.has(key)) {
|
|
353
|
+
const ref = getCurrentRef();
|
|
354
|
+
const keyRef = getRefParam(ctx, createRef(ctx, key));
|
|
355
|
+
if (ctx.stack.has(value)) {
|
|
356
|
+
const valueRef = getRefParam(ctx, createRef(ctx, value));
|
|
357
|
+
createMapSet(ctx, ref, keyRef, valueRef);
|
|
358
|
+
} else {
|
|
359
|
+
const valueResult = await traverseAsync(ctx, value);
|
|
360
|
+
createMapSet(ctx, ref, keyRef, valueResult);
|
|
324
361
|
}
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
362
|
+
} else if (ctx.stack.has(value)) {
|
|
363
|
+
const valueRef = getRefParam(ctx, createRef(ctx, value));
|
|
364
|
+
const keyResult = await traverseAsync(ctx, key);
|
|
365
|
+
createMapSet(ctx, getCurrentRef(), keyResult, valueRef);
|
|
366
|
+
} else {
|
|
367
|
+
const keyResult = await traverseAsync(ctx, key);
|
|
368
|
+
const valueResult = await traverseAsync(ctx, value);
|
|
369
|
+
values.push(`[${keyResult},${valueResult}]`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
ctx.stack.delete(current);
|
|
373
|
+
return processRef(values.length ? `new Map([${join(values, ",")}])` : EMPTY_MAP);
|
|
374
|
+
}
|
|
375
|
+
return EMPTY_MAP;
|
|
376
|
+
}
|
|
377
|
+
if (Array.isArray(current)) {
|
|
378
|
+
if (current.length) {
|
|
379
|
+
let values = "";
|
|
380
|
+
ctx.stack.add(current);
|
|
381
|
+
for (let i = 0, len = current.length; i < len; i += 1) {
|
|
382
|
+
if (i in current) {
|
|
383
|
+
const item = current[i];
|
|
384
|
+
if (ctx.stack.has(item)) {
|
|
385
|
+
const refParam = getRefParam(ctx, createRef(ctx, item));
|
|
386
|
+
createArrayAssign(ctx, getCurrentRef(), i, refParam);
|
|
387
|
+
values += ",";
|
|
328
388
|
} else {
|
|
329
|
-
|
|
330
|
-
if (
|
|
331
|
-
|
|
332
|
-
} else {
|
|
333
|
-
createMapSet(refResult, keyRef, valueResult.referred);
|
|
389
|
+
values += await traverseAsync(ctx, item);
|
|
390
|
+
if (i < current.length - 1) {
|
|
391
|
+
values += ",";
|
|
334
392
|
}
|
|
335
393
|
}
|
|
336
|
-
} else
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
394
|
+
} else {
|
|
395
|
+
values += ",";
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
ctx.stack.delete(current);
|
|
399
|
+
return processRef(`[${values}]`);
|
|
400
|
+
}
|
|
401
|
+
return EMPTY_ARRAY;
|
|
402
|
+
}
|
|
403
|
+
const empty = current.constructor == null;
|
|
404
|
+
if (current.constructor === Object || empty) {
|
|
405
|
+
const values = [];
|
|
406
|
+
ctx.stack.add(current);
|
|
407
|
+
for (const [key, value2] of Object.entries(current)) {
|
|
408
|
+
const check = Number(key);
|
|
409
|
+
if (check >= 0 || Number.isNaN(check) && /^([$A-Z_][0-9A-Z_$]*)$/i.test(key)) {
|
|
410
|
+
if (ctx.stack.has(value2)) {
|
|
411
|
+
const ref = getCurrentRef();
|
|
412
|
+
const refParam = getRefParam(ctx, createRef(ctx, value2));
|
|
413
|
+
if (Number.isNaN(check)) {
|
|
414
|
+
createObjectIdentifierAssign(ctx, ref, key, refParam);
|
|
344
415
|
} else {
|
|
345
|
-
|
|
416
|
+
createObjectComputedAssign(ctx, ref, key, refParam);
|
|
346
417
|
}
|
|
347
418
|
} else {
|
|
348
|
-
const
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
419
|
+
const valueResult = await traverseAsync(ctx, value2);
|
|
420
|
+
values.push(`${key}:${valueResult}`);
|
|
421
|
+
}
|
|
422
|
+
} else if (ctx.stack.has(value2)) {
|
|
423
|
+
const refParam = getRefParam(ctx, createRef(ctx, value2));
|
|
424
|
+
createObjectComputedAssign(ctx, getCurrentRef(), quote(key), refParam);
|
|
425
|
+
} else {
|
|
426
|
+
const valueResult = await traverseAsync(ctx, value2);
|
|
427
|
+
values.push(`${quote(key)}:${valueResult}`);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
ctx.stack.delete(current);
|
|
431
|
+
const value = `{${join(values, ",")}}`;
|
|
432
|
+
if (empty) {
|
|
433
|
+
return processRef(`Object.assign(Object.create(null),${value})`);
|
|
434
|
+
}
|
|
435
|
+
return processRef(value);
|
|
436
|
+
}
|
|
437
|
+
throw new Error("Unserializable value");
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/sync.ts
|
|
441
|
+
function lookupRefs(ctx, current) {
|
|
442
|
+
if (isPrimitive(current)) {
|
|
443
|
+
return;
|
|
444
|
+
}
|
|
445
|
+
if (Array.isArray(current)) {
|
|
446
|
+
if (insertRef(ctx, current)) {
|
|
447
|
+
forEach(current, (value) => {
|
|
448
|
+
lookupRefs(ctx, value);
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
} else if (constructorCheck(current, Set)) {
|
|
452
|
+
if (insertRef(ctx, current)) {
|
|
453
|
+
for (const item of current.keys()) {
|
|
454
|
+
lookupRefs(ctx, item);
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
} else if (constructorCheck(current, Map)) {
|
|
458
|
+
if (insertRef(ctx, current)) {
|
|
459
|
+
for (const [key, value] of current.entries()) {
|
|
460
|
+
lookupRefs(ctx, key);
|
|
461
|
+
lookupRefs(ctx, value);
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
} else if ((current.constructor === Object || current.constructor == null) && insertRef(ctx, current)) {
|
|
465
|
+
forEach(Object.values(current), (value) => {
|
|
466
|
+
lookupRefs(ctx, value);
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
function traverseSync(ctx, current) {
|
|
471
|
+
if (isPrimitive(current)) {
|
|
472
|
+
return serializePrimitive(current);
|
|
473
|
+
}
|
|
474
|
+
let refResult = ctx.refs.get(current);
|
|
475
|
+
if (refResult != null) {
|
|
476
|
+
if (ctx.assignedRefs.has(refResult)) {
|
|
477
|
+
return getRefParam(ctx, refResult);
|
|
478
|
+
}
|
|
479
|
+
ctx.assignedRefs.add(refResult);
|
|
480
|
+
}
|
|
481
|
+
function getCurrentRef() {
|
|
482
|
+
if (refResult == null) {
|
|
483
|
+
refResult = createRef(ctx, current);
|
|
484
|
+
}
|
|
485
|
+
return refResult;
|
|
486
|
+
}
|
|
487
|
+
function processRef(value) {
|
|
488
|
+
if (refResult != null) {
|
|
489
|
+
return assignRef(ctx, refResult, value);
|
|
490
|
+
}
|
|
491
|
+
return value;
|
|
492
|
+
}
|
|
493
|
+
if (constructorCheck(current, Set)) {
|
|
494
|
+
if (current.size) {
|
|
495
|
+
const values = [];
|
|
496
|
+
ctx.stack.add(current);
|
|
497
|
+
for (const value of current.keys()) {
|
|
498
|
+
if (ctx.stack.has(value)) {
|
|
499
|
+
createSetAdd(ctx, getCurrentRef(), getRefParam(ctx, createRef(ctx, value)));
|
|
500
|
+
} else {
|
|
501
|
+
values.push(traverseSync(ctx, value));
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
ctx.stack.delete(current);
|
|
505
|
+
return processRef(values.length ? `new Set([${join(values, ",")}])` : EMPTY_SET);
|
|
506
|
+
}
|
|
507
|
+
return EMPTY_SET;
|
|
508
|
+
}
|
|
509
|
+
if (constructorCheck(current, Map)) {
|
|
510
|
+
if (current.size) {
|
|
511
|
+
const values = [];
|
|
512
|
+
ctx.stack.add(current);
|
|
513
|
+
for (const [key, value] of current.entries()) {
|
|
514
|
+
if (ctx.stack.has(key)) {
|
|
515
|
+
const ref = getCurrentRef();
|
|
516
|
+
const keyRef = getRefParam(ctx, createRef(ctx, key));
|
|
517
|
+
if (ctx.stack.has(value)) {
|
|
518
|
+
const valueRef = getRefParam(ctx, createRef(ctx, value));
|
|
519
|
+
createMapSet(ctx, ref, keyRef, valueRef);
|
|
356
520
|
} else {
|
|
357
|
-
|
|
358
|
-
values.push(`[${keyResult.referred},${valueResult}]`);
|
|
359
|
-
} else {
|
|
360
|
-
values.push(`[${keyResult.referred},${valueResult.referred}]`);
|
|
361
|
-
}
|
|
521
|
+
createMapSet(ctx, ref, keyRef, traverseSync(ctx, value));
|
|
362
522
|
}
|
|
523
|
+
} else if (ctx.stack.has(value)) {
|
|
524
|
+
const valueRef = getRefParam(ctx, createRef(ctx, value));
|
|
525
|
+
createMapSet(ctx, getCurrentRef(), traverseSync(ctx, key), valueRef);
|
|
526
|
+
} else {
|
|
527
|
+
values.push(`[${traverseSync(ctx, key)},${traverseSync(ctx, value)}]`);
|
|
363
528
|
}
|
|
364
529
|
}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
if (refResult != null) {
|
|
368
|
-
return assignRef(refResult, value);
|
|
369
|
-
}
|
|
370
|
-
return value;
|
|
530
|
+
ctx.stack.delete(current);
|
|
531
|
+
return processRef(values.length ? `new Map([${join(values, ",")}])` : EMPTY_MAP);
|
|
371
532
|
}
|
|
372
533
|
return EMPTY_MAP;
|
|
373
534
|
}
|
|
374
535
|
if (Array.isArray(current)) {
|
|
375
536
|
if (current.length) {
|
|
376
537
|
let values = "";
|
|
377
|
-
|
|
538
|
+
ctx.stack.add(current);
|
|
378
539
|
forEach(current, (item, i) => {
|
|
379
540
|
if (i in current) {
|
|
380
|
-
if (
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
createArrayAssign(refResult, i, getRefParam(createRef(item)));
|
|
541
|
+
if (ctx.stack.has(item)) {
|
|
542
|
+
const refParam = getRefParam(ctx, createRef(ctx, item));
|
|
543
|
+
createArrayAssign(ctx, getCurrentRef(), i, refParam);
|
|
385
544
|
values += ",";
|
|
386
545
|
} else {
|
|
387
|
-
|
|
388
|
-
if (typeof result === "string") {
|
|
389
|
-
values += result;
|
|
390
|
-
} else {
|
|
391
|
-
values += result.referred;
|
|
392
|
-
}
|
|
546
|
+
values += traverseSync(ctx, item);
|
|
393
547
|
if (i < current.length - 1) {
|
|
394
548
|
values += ",";
|
|
395
549
|
}
|
|
@@ -398,84 +552,98 @@ function traverse(current) {
|
|
|
398
552
|
values += ",";
|
|
399
553
|
}
|
|
400
554
|
});
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
if (refResult != null) {
|
|
404
|
-
return assignRef(refResult, value);
|
|
405
|
-
}
|
|
406
|
-
return value;
|
|
555
|
+
ctx.stack.delete(current);
|
|
556
|
+
return processRef(`[${values}]`);
|
|
407
557
|
}
|
|
408
558
|
return EMPTY_ARRAY;
|
|
409
559
|
}
|
|
410
|
-
|
|
560
|
+
const empty = current.constructor == null;
|
|
561
|
+
if (current.constructor === Object || empty) {
|
|
411
562
|
const values = [];
|
|
412
|
-
|
|
563
|
+
ctx.stack.add(current);
|
|
413
564
|
forEach(Object.entries(current), ([key, value2]) => {
|
|
414
565
|
const check = Number(key);
|
|
415
|
-
if (Number.isNaN(check)
|
|
416
|
-
if (
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
} else {
|
|
422
|
-
const result = traverse(value2);
|
|
423
|
-
if (typeof result === "string") {
|
|
424
|
-
values.push(`${key}:${result}`);
|
|
566
|
+
if (check >= 0 || Number.isNaN(check) && /^([$A-Z_][0-9A-Z_$]*)$/i.test(key)) {
|
|
567
|
+
if (ctx.stack.has(value2)) {
|
|
568
|
+
const ref = getCurrentRef();
|
|
569
|
+
const refParam = getRefParam(ctx, createRef(ctx, value2));
|
|
570
|
+
if (!Number.isNaN(check)) {
|
|
571
|
+
createObjectComputedAssign(ctx, ref, key, refParam);
|
|
425
572
|
} else {
|
|
426
|
-
|
|
573
|
+
createObjectIdentifierAssign(ctx, ref, key, refParam);
|
|
427
574
|
}
|
|
428
|
-
}
|
|
429
|
-
} else if (STACK.has(value2)) {
|
|
430
|
-
if (refResult == null) {
|
|
431
|
-
refResult = createRef(current);
|
|
432
|
-
}
|
|
433
|
-
createObjectStringAssign(refResult, key, getRefParam(createRef(value2)));
|
|
434
|
-
} else {
|
|
435
|
-
const result = traverse(value2);
|
|
436
|
-
if (typeof result === "string") {
|
|
437
|
-
values.push(`${quote(key)}:${result}`);
|
|
438
575
|
} else {
|
|
439
|
-
values.push(`${
|
|
576
|
+
values.push(`${key}:${traverseSync(ctx, value2)}`);
|
|
440
577
|
}
|
|
578
|
+
} else if (ctx.stack.has(value2)) {
|
|
579
|
+
const refParam = getRefParam(ctx, createRef(ctx, value2));
|
|
580
|
+
createObjectComputedAssign(ctx, getCurrentRef(), quote(key), refParam);
|
|
581
|
+
} else {
|
|
582
|
+
values.push(`${quote(key)}:${traverseSync(ctx, value2)}`);
|
|
441
583
|
}
|
|
442
584
|
});
|
|
443
|
-
|
|
585
|
+
ctx.stack.delete(current);
|
|
444
586
|
const value = `{${join(values, ",")}}`;
|
|
445
|
-
if (
|
|
446
|
-
return
|
|
587
|
+
if (empty) {
|
|
588
|
+
return processRef(`Object.assign(Object.create(null),${value})`);
|
|
447
589
|
}
|
|
448
|
-
return value;
|
|
590
|
+
return processRef(value);
|
|
449
591
|
}
|
|
450
592
|
throw new Error("Unserializable value");
|
|
451
593
|
}
|
|
594
|
+
|
|
595
|
+
// src/index.ts
|
|
596
|
+
function finalize(ctx, source, result) {
|
|
597
|
+
if (ctx.vars.length) {
|
|
598
|
+
const index = getRefParam(ctx, createRef(ctx, source));
|
|
599
|
+
const patches = resolvePatches(ctx);
|
|
600
|
+
const params = ctx.vars.length > 1 ? `(${join(ctx.vars, ",")})` : ctx.vars[0];
|
|
601
|
+
if (result.startsWith(`${index}=`)) {
|
|
602
|
+
return `(${params}=>(${result},${patches}${index}))()`;
|
|
603
|
+
}
|
|
604
|
+
return `(${params}=>(${index}=${result},${patches}${index}))()`;
|
|
605
|
+
}
|
|
606
|
+
if (source.constructor === Object) {
|
|
607
|
+
return `(${result})`;
|
|
608
|
+
}
|
|
609
|
+
return result;
|
|
610
|
+
}
|
|
452
611
|
function serialize(source) {
|
|
453
612
|
if (isPrimitive(source)) {
|
|
454
613
|
return serializePrimitive(source);
|
|
455
614
|
}
|
|
456
|
-
|
|
457
|
-
lookupRefs(source);
|
|
458
|
-
for (const [key, value] of
|
|
615
|
+
const ctx = createSerializationContext();
|
|
616
|
+
lookupRefs(ctx, source);
|
|
617
|
+
for (const [key, value] of ctx.refCount.entries()) {
|
|
459
618
|
if (value > 1) {
|
|
460
|
-
createRef(key);
|
|
619
|
+
createRef(ctx, key);
|
|
461
620
|
}
|
|
462
621
|
}
|
|
463
|
-
const result =
|
|
622
|
+
const result = traverseSync(ctx, source);
|
|
464
623
|
if (typeof result !== "string") {
|
|
465
624
|
throw new Error("Unreachable error");
|
|
466
625
|
}
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
626
|
+
return finalize(ctx, source, result);
|
|
627
|
+
}
|
|
628
|
+
async function serializeAsync(source) {
|
|
629
|
+
if (isPrimitive(source)) {
|
|
630
|
+
return serializePrimitive(source);
|
|
631
|
+
}
|
|
632
|
+
const ctx = createSerializationContext();
|
|
633
|
+
await lookupRefsAsync(ctx, source);
|
|
634
|
+
for (const [key, value] of ctx.refCount.entries()) {
|
|
635
|
+
if (value > 1) {
|
|
636
|
+
createRef(ctx, key);
|
|
473
637
|
}
|
|
474
|
-
return `(${params}=>(${index}=${result},${patches}${index}))()`;
|
|
475
638
|
}
|
|
476
|
-
|
|
477
|
-
|
|
639
|
+
const result = await traverseAsync(ctx, source);
|
|
640
|
+
if (typeof result !== "string") {
|
|
641
|
+
throw new Error("Unreachable error");
|
|
478
642
|
}
|
|
479
|
-
return result;
|
|
643
|
+
return finalize(ctx, source, result);
|
|
644
|
+
}
|
|
645
|
+
function deserialize(source) {
|
|
646
|
+
return (0, eval)(source);
|
|
480
647
|
}
|
|
648
|
+
var src_default = serialize;
|
|
481
649
|
//# sourceMappingURL=index.cjs.map
|