json-as 1.3.9 → 1.4.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/CHANGELOG.md +20 -0
- package/README.md +49 -1
- package/assembly/deserialize/index/arbitrary.ts +2 -2
- package/assembly/deserialize/naive/array/arbitrary.ts +3 -136
- package/assembly/deserialize/naive/array/array.ts +30 -1
- package/assembly/deserialize/naive/array/integer.ts +1 -6
- package/assembly/deserialize/naive/array/map.ts +10 -14
- package/assembly/deserialize/naive/array/object.ts +10 -14
- package/assembly/deserialize/naive/float.ts +2 -4
- package/assembly/deserialize/naive/integer.ts +1 -2
- package/assembly/deserialize/naive/map.ts +40 -202
- package/assembly/deserialize/naive/object.ts +153 -174
- package/assembly/deserialize/naive/set.ts +1 -2
- package/assembly/deserialize/naive/staticarray.ts +1 -2
- package/assembly/deserialize/naive/string.ts +65 -18
- package/assembly/deserialize/naive/typedarray.ts +1 -2
- package/assembly/deserialize/naive/unsigned.ts +1 -2
- package/assembly/deserialize/simd/array/integer.ts +3 -6
- package/assembly/deserialize/simd/float.ts +2 -7
- package/assembly/deserialize/simd/integer.ts +4 -8
- package/assembly/deserialize/simd/string.ts +16 -21
- package/assembly/deserialize/swar/array/array.ts +1 -2
- package/assembly/deserialize/swar/array/bool.ts +1 -2
- package/assembly/deserialize/swar/array/float.ts +2 -3
- package/assembly/deserialize/swar/array/generic.ts +1 -2
- package/assembly/deserialize/swar/array/integer.ts +6 -11
- package/assembly/deserialize/swar/array/object.ts +1 -2
- package/assembly/deserialize/swar/array/shared.ts +3 -8
- package/assembly/deserialize/swar/array/string.ts +1 -2
- package/assembly/deserialize/swar/array/struct.ts +1 -1
- package/assembly/deserialize/swar/float.ts +3 -8
- package/assembly/deserialize/swar/integer.ts +4 -8
- package/assembly/deserialize/swar/string.ts +29 -41
- package/assembly/index.d.ts +248 -15
- package/assembly/index.ts +468 -146
- package/assembly/serialize/index/object.ts +18 -15
- package/assembly/serialize/naive/string.ts +9 -2
- package/assembly/serialize/swar/string.ts +1 -2
- package/assembly/util/atoi.ts +1 -2
- package/assembly/util/dragonbox.ts +0 -8
- package/assembly/util/itoa-fast.ts +3 -6
- package/assembly/util/parsefloat-fast.ts +1 -2
- package/assembly/util/scanValueEnd.ts +1 -2
- package/assembly/util/scanValueEndSimd.ts +160 -0
- package/assembly/util/scanValueEndSwar.ts +142 -0
- package/assembly/util/scientific.ts +3 -6
- package/assembly/util/simd-int.ts +4 -8
- package/assembly/util/snp.ts +1 -5
- package/assembly/util/stringScan.ts +2 -4
- package/assembly/util/swar-int.ts +3 -6
- package/lib/as-bs.ts +37 -0
- package/package.json +14 -4
- package/transform/lib/builder.d.ts +0 -1
- package/transform/lib/builder.js +0 -1
- package/transform/lib/index.d.ts +0 -1
- package/transform/lib/index.js +535 -288
- package/transform/lib/linkers/alias.d.ts +0 -1
- package/transform/lib/linkers/alias.js +0 -1
- package/transform/lib/linkers/custom.d.ts +0 -1
- package/transform/lib/linkers/custom.js +0 -1
- package/transform/lib/linkers/imports.d.ts +0 -1
- package/transform/lib/linkers/imports.js +0 -1
- package/transform/lib/types.d.ts +3 -2
- package/transform/lib/types.js +2 -1
- package/transform/lib/util.d.ts +0 -1
- package/transform/lib/util.js +0 -1
- package/transform/lib/visitor.d.ts +0 -1
- package/transform/lib/visitor.js +0 -1
- package/transform/lib/builder.d.ts.map +0 -1
- package/transform/lib/builder.js.map +0 -1
- package/transform/lib/index.d.ts.map +0 -1
- package/transform/lib/index.js.map +0 -1
- package/transform/lib/linkers/alias.d.ts.map +0 -1
- package/transform/lib/linkers/alias.js.map +0 -1
- package/transform/lib/linkers/custom.d.ts.map +0 -1
- package/transform/lib/linkers/custom.js.map +0 -1
- package/transform/lib/linkers/imports.d.ts.map +0 -1
- package/transform/lib/linkers/imports.js.map +0 -1
- package/transform/lib/types.d.ts.map +0 -1
- package/transform/lib/types.js.map +0 -1
- package/transform/lib/util.d.ts.map +0 -1
- package/transform/lib/util.js.map +0 -1
- package/transform/lib/visitor.d.ts.map +0 -1
- package/transform/lib/visitor.js.map +0 -1
|
@@ -61,8 +61,7 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
61
61
|
// NOTE: vs the prior overflow scanner this is faster on dense and sparse
|
|
62
62
|
// escaping but ~20% slower on sustained moderate-density escaping (escape
|
|
63
63
|
// every ~20 chars), where multi-escape-per-block had an edge.
|
|
64
|
-
|
|
65
|
-
@inline function deserializeEscapedString_SWAR(
|
|
64
|
+
function deserializeEscapedString_SWAR(
|
|
66
65
|
payloadStart: usize,
|
|
67
66
|
escapeStart: usize,
|
|
68
67
|
srcEnd: usize,
|
|
@@ -80,20 +79,20 @@ import { hex4_to_u16_swar } from "../../util/swar";
|
|
|
80
79
|
|
|
81
80
|
while (srcStart <= srcEnd8) {
|
|
82
81
|
const block = load<u64>(srcStart);
|
|
83
|
-
let mask =
|
|
82
|
+
let mask = backslash_mask_unsafe(block);
|
|
84
83
|
if (mask == 0) {
|
|
85
84
|
store<u64>(bs.offset, block);
|
|
86
85
|
bs.offset += 8;
|
|
87
86
|
srcStart += 8;
|
|
88
87
|
if (
|
|
89
88
|
srcStart <= srcEnd8 &&
|
|
90
|
-
|
|
89
|
+
backslash_mask_unsafe(load<u64>(srcStart)) == 0
|
|
91
90
|
) {
|
|
92
91
|
const runStart = srcStart;
|
|
93
92
|
srcStart += 8;
|
|
94
93
|
while (
|
|
95
94
|
srcStart <= srcEnd8 &&
|
|
96
|
-
|
|
95
|
+
backslash_mask_unsafe(load<u64>(srcStart)) == 0
|
|
97
96
|
) {
|
|
98
97
|
srcStart += 8;
|
|
99
98
|
}
|
|
@@ -162,8 +161,8 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
162
161
|
const srcEnd16Fast = srcEnd - 16;
|
|
163
162
|
|
|
164
163
|
while (srcStart < srcEnd16Fast) {
|
|
165
|
-
const m0 =
|
|
166
|
-
const m1 =
|
|
164
|
+
const m0 = backslash_mask_unsafe(load<u64>(srcStart));
|
|
165
|
+
const m1 = backslash_mask_unsafe(load<u64>(srcStart, 8));
|
|
167
166
|
if ((m0 | m1) != 0) break;
|
|
168
167
|
srcStart += 16;
|
|
169
168
|
}
|
|
@@ -183,7 +182,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
183
182
|
|
|
184
183
|
while (srcStart < srcEnd8) {
|
|
185
184
|
const block = load<u64>(srcStart);
|
|
186
|
-
let mask =
|
|
185
|
+
let mask = backslash_mask_unsafe(block);
|
|
187
186
|
|
|
188
187
|
if (mask === 0) {
|
|
189
188
|
srcStart += 8;
|
|
@@ -199,9 +198,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
199
198
|
// Detect false positive (code unit where low byte is 0x5C)
|
|
200
199
|
if ((header & 0xffff) !== 0x5c) continue;
|
|
201
200
|
|
|
202
|
-
return
|
|
203
|
-
deserializeEscapedString_SWAR(payloadStart, srcIdx, srcEnd),
|
|
204
|
-
);
|
|
201
|
+
return deserializeEscapedString_SWAR(payloadStart, srcIdx, srcEnd);
|
|
205
202
|
} while (mask !== 0);
|
|
206
203
|
|
|
207
204
|
srcStart += 8;
|
|
@@ -209,9 +206,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
209
206
|
|
|
210
207
|
while (srcStart < srcEnd) {
|
|
211
208
|
if (load<u16>(srcStart) == BACK_SLASH) {
|
|
212
|
-
return
|
|
213
|
-
deserializeEscapedString_SWAR(payloadStart, srcStart, srcEnd),
|
|
214
|
-
);
|
|
209
|
+
return deserializeEscapedString_SWAR(payloadStart, srcStart, srcEnd);
|
|
215
210
|
}
|
|
216
211
|
srcStart += 2;
|
|
217
212
|
}
|
|
@@ -220,8 +215,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
220
215
|
}
|
|
221
216
|
|
|
222
217
|
// Writes into the destination field, reusing or resizing the backing string.
|
|
223
|
-
|
|
224
|
-
@inline function writeStringToField(
|
|
218
|
+
function writeStringToField(
|
|
225
219
|
dstFieldPtr: usize,
|
|
226
220
|
srcStart: usize,
|
|
227
221
|
byteLength: u32,
|
|
@@ -258,8 +252,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
258
252
|
// to one bulk memory.copy for the remainder.
|
|
259
253
|
// SWAR masks carry high-byte false positives, so each hit is confirmed
|
|
260
254
|
// scalarly before acting.
|
|
261
|
-
|
|
262
|
-
@inline function deserializeEscapedStringField_SWAR(
|
|
255
|
+
function deserializeEscapedStringField_SWAR(
|
|
263
256
|
payloadStart: usize,
|
|
264
257
|
escapeStart: usize,
|
|
265
258
|
srcEnd: usize,
|
|
@@ -278,20 +271,20 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
278
271
|
|
|
279
272
|
while (srcStart <= srcEnd8) {
|
|
280
273
|
const block = load<u64>(srcStart);
|
|
281
|
-
let mask =
|
|
274
|
+
let mask = backslash_or_quote_mask(block);
|
|
282
275
|
if (mask == 0) {
|
|
283
276
|
store<u64>(bs.offset, block);
|
|
284
277
|
bs.offset += 8;
|
|
285
278
|
srcStart += 8;
|
|
286
279
|
if (
|
|
287
280
|
srcStart <= srcEnd8 &&
|
|
288
|
-
|
|
281
|
+
backslash_or_quote_mask(load<u64>(srcStart)) == 0
|
|
289
282
|
) {
|
|
290
283
|
const runStart = srcStart;
|
|
291
284
|
srcStart += 8;
|
|
292
285
|
while (
|
|
293
286
|
srcStart <= srcEnd8 &&
|
|
294
|
-
|
|
287
|
+
backslash_or_quote_mask(load<u64>(srcStart)) == 0
|
|
295
288
|
) {
|
|
296
289
|
srcStart += 8;
|
|
297
290
|
}
|
|
@@ -371,8 +364,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
371
364
|
return srcStart;
|
|
372
365
|
}
|
|
373
366
|
|
|
374
|
-
|
|
375
|
-
@inline function deserializeEscapedStringContinuation_SWAR_MergedTuned(
|
|
367
|
+
function deserializeEscapedStringContinuation_SWAR_MergedTuned(
|
|
376
368
|
lastPtr: usize,
|
|
377
369
|
srcStart: usize,
|
|
378
370
|
srcEnd: usize,
|
|
@@ -382,7 +374,7 @@ export function deserializeString_SWAR(srcStart: usize, srcEnd: usize): string {
|
|
|
382
374
|
|
|
383
375
|
while (srcStart <= srcEnd8) {
|
|
384
376
|
const blockStart = srcStart;
|
|
385
|
-
let mask =
|
|
377
|
+
let mask = backslash_or_quote_mask(load<u64>(srcStart));
|
|
386
378
|
if (mask === 0) {
|
|
387
379
|
srcStart += 8;
|
|
388
380
|
continue;
|
|
@@ -491,8 +483,8 @@ export function deserializeStringField_SWAR<T extends string | null>(
|
|
|
491
483
|
if (srcEnd >= 16) {
|
|
492
484
|
const srcEnd16 = srcEnd - 16;
|
|
493
485
|
while (srcStart <= srcEnd16) {
|
|
494
|
-
const m0 =
|
|
495
|
-
const m1 =
|
|
486
|
+
const m0 = backslash_or_quote_mask(load<u64>(srcStart));
|
|
487
|
+
const m1 = backslash_or_quote_mask(load<u64>(srcStart, 8));
|
|
496
488
|
if ((m0 | m1) != 0) break;
|
|
497
489
|
srcStart += 16;
|
|
498
490
|
}
|
|
@@ -500,7 +492,7 @@ export function deserializeStringField_SWAR<T extends string | null>(
|
|
|
500
492
|
|
|
501
493
|
const srcEnd8 = srcEnd - 8;
|
|
502
494
|
while (srcStart <= srcEnd8) {
|
|
503
|
-
let mask =
|
|
495
|
+
let mask = backslash_or_quote_mask(load<u64>(srcStart));
|
|
504
496
|
if (mask === 0) {
|
|
505
497
|
srcStart += 8;
|
|
506
498
|
continue;
|
|
@@ -520,13 +512,11 @@ export function deserializeStringField_SWAR<T extends string | null>(
|
|
|
520
512
|
return srcIdx + 2;
|
|
521
513
|
}
|
|
522
514
|
if (char != BACK_SLASH) continue;
|
|
523
|
-
return
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
dstFieldPtr,
|
|
529
|
-
),
|
|
515
|
+
return deserializeEscapedStringField_SWAR(
|
|
516
|
+
payloadStart,
|
|
517
|
+
srcIdx,
|
|
518
|
+
srcEnd,
|
|
519
|
+
dstFieldPtr,
|
|
530
520
|
);
|
|
531
521
|
} while (mask !== 0);
|
|
532
522
|
|
|
@@ -544,13 +534,11 @@ export function deserializeStringField_SWAR<T extends string | null>(
|
|
|
544
534
|
return srcStart + 2;
|
|
545
535
|
}
|
|
546
536
|
if (char == BACK_SLASH) {
|
|
547
|
-
return
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
dstFieldPtr,
|
|
553
|
-
),
|
|
537
|
+
return deserializeEscapedStringField_SWAR(
|
|
538
|
+
payloadStart,
|
|
539
|
+
srcStart,
|
|
540
|
+
srcEnd,
|
|
541
|
+
dstFieldPtr,
|
|
554
542
|
);
|
|
555
543
|
}
|
|
556
544
|
srcStart += 2;
|
package/assembly/index.d.ts
CHANGED
|
@@ -1,57 +1,290 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Options for the {@link json} class decorator: `@json({ ... })`.
|
|
3
|
+
*/
|
|
4
|
+
declare class JSONConfig {
|
|
5
|
+
/**
|
|
6
|
+
* Class-level lazy (on-demand) parsing mode. A lazy field stores its raw JSON
|
|
7
|
+
* slice at parse time and only parses it into the field's type on first
|
|
8
|
+
* access; untouched fields pass their original bytes straight through on
|
|
9
|
+
* serialize.
|
|
10
|
+
*
|
|
11
|
+
* - `"none"` *(default)* — every field is parsed eagerly, up-front.
|
|
12
|
+
* - `"auto"` — the transform defers fields whose estimated parse cost is high
|
|
13
|
+
* (nested structs, arrays, maps, long strings) and keeps cheap fields
|
|
14
|
+
* (primitives, enums, `Date`) eager. Use `@eager` to force a field back to
|
|
15
|
+
* eager, or `@lazy` to force one on.
|
|
16
|
+
* - `"all"` — every field is deferred. Best for proxy / filter / forward
|
|
17
|
+
* workloads over large payloads; note it generates a getter and a serialize
|
|
18
|
+
* branch per field, so module size grows with very wide schemas.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```ts
|
|
22
|
+
* @json({ lazy: "auto" })
|
|
23
|
+
* class Repo {
|
|
24
|
+
* name: string = ""; // cheap -> stays eager
|
|
25
|
+
* owner: Owner = new Owner; // costly -> deferred
|
|
26
|
+
* @eager id: i32 = 0; // opt back out
|
|
27
|
+
* }
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
lazy?: "none" | "auto" | "all";
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Marks a class as serializable, generating the (de)serialization methods the
|
|
35
|
+
* runtime needs. Required on every type passed to `JSON.parse` / `JSON.stringify`
|
|
36
|
+
* (including nested types).
|
|
37
|
+
*
|
|
38
|
+
* @param config - Optional {@link JSONConfig} (currently `{ lazy }`).
|
|
39
|
+
*
|
|
40
|
+
* @example
|
|
41
|
+
* ```ts
|
|
42
|
+
* @json
|
|
43
|
+
* class Vec3 {
|
|
44
|
+
* x: f64 = 0;
|
|
45
|
+
* y: f64 = 0;
|
|
46
|
+
* z: f64 = 0;
|
|
47
|
+
* }
|
|
48
|
+
*
|
|
49
|
+
* JSON.stringify(new Vec3()); // '{"x":0.0,"y":0.0,"z":0.0}'
|
|
50
|
+
* JSON.parse<Vec3>('{"x":1,"y":2,"z":3}');
|
|
51
|
+
* ```
|
|
3
52
|
*/
|
|
4
53
|
// @ts-ignore: type
|
|
5
|
-
declare function json(
|
|
54
|
+
declare function json(config?: JSONConfig): Function;
|
|
6
55
|
|
|
7
56
|
/**
|
|
8
|
-
*
|
|
57
|
+
* Alias for {@link json}. `@serializable` and `@json` are interchangeable.
|
|
9
58
|
*/
|
|
10
59
|
// @ts-ignore: type
|
|
11
60
|
declare function serializable(..._): void;
|
|
12
61
|
|
|
13
62
|
/**
|
|
14
|
-
*
|
|
63
|
+
* Field decorator that overrides the JSON key used for a property, decoupling
|
|
64
|
+
* the wire name from the AssemblyScript field name.
|
|
65
|
+
*
|
|
66
|
+
* @param newName - The key to emit and read for this field.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```ts
|
|
70
|
+
* @json
|
|
71
|
+
* class User {
|
|
72
|
+
* @alias("user_id") userId: i32 = 0; // <-> {"user_id": 0}
|
|
73
|
+
* }
|
|
74
|
+
* ```
|
|
15
75
|
*/
|
|
16
76
|
declare function alias(newName: string): Function;
|
|
17
77
|
|
|
18
78
|
/**
|
|
19
|
-
*
|
|
79
|
+
* Field decorator that excludes a property from JSON entirely: it is never
|
|
80
|
+
* serialized and is ignored during parsing.
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```ts
|
|
84
|
+
* @json
|
|
85
|
+
* class Session {
|
|
86
|
+
* token: string = "";
|
|
87
|
+
* @omit secret: string = ""; // never (de)serialized
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
20
90
|
*/
|
|
21
91
|
// @ts-ignore: type
|
|
22
92
|
declare function omit(..._): void;
|
|
23
93
|
|
|
24
94
|
/**
|
|
25
|
-
*
|
|
95
|
+
* Field decorator that omits a property from the output when a predicate holds.
|
|
96
|
+
* The field is still parsed normally; the condition only affects serialization.
|
|
97
|
+
*
|
|
98
|
+
* @param condition - A predicate that receives the **instance** and returns
|
|
99
|
+
* `true` to omit the field — `(self: T) => boolean` — or a string expression
|
|
100
|
+
* evaluated in the instance's scope (reference fields via `this`).
|
|
101
|
+
*
|
|
102
|
+
* @example
|
|
103
|
+
* ```ts
|
|
104
|
+
* @json
|
|
105
|
+
* class Player {
|
|
106
|
+
* age: i32 = 0;
|
|
107
|
+
* @omitif((self: Player) => self.age < 18) email: string = ""; // arrow form
|
|
108
|
+
* @omitif("this.age < 18") phone: string = ""; // string form
|
|
109
|
+
* }
|
|
110
|
+
* ```
|
|
26
111
|
*/
|
|
27
|
-
declare function omitif(
|
|
28
|
-
condition: string | ((value: any) => boolean),
|
|
29
|
-
): Function;
|
|
112
|
+
declare function omitif(condition: string | ((self: any) => boolean)): Function;
|
|
30
113
|
|
|
31
114
|
/**
|
|
32
|
-
*
|
|
115
|
+
* Field decorator that omits a property from the output when its value is
|
|
116
|
+
* `null`. Shorthand for the common nullable case; the field is still parsed.
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```ts
|
|
120
|
+
* @json
|
|
121
|
+
* class Profile {
|
|
122
|
+
* @omitnull bio: string | null = null; // key absent when null
|
|
123
|
+
* }
|
|
124
|
+
* ```
|
|
33
125
|
*/
|
|
34
126
|
// @ts-ignore: type
|
|
35
127
|
declare function omitnull(..._): Function;
|
|
36
128
|
|
|
37
129
|
/**
|
|
38
|
-
*
|
|
130
|
+
* Field decorator that defers parsing of a property until it is first read
|
|
131
|
+
* (on-demand / lazy parsing). The raw JSON slice is stored at parse time and
|
|
132
|
+
* materialized into the field's type on first access, then cached; an untouched
|
|
133
|
+
* field round-trips by copying its original bytes — never re-parsed or
|
|
134
|
+
* re-serialized.
|
|
135
|
+
*
|
|
136
|
+
* Equivalent to the `JSON.Lazy<T>` type-wrapper form. Pays off for fields you
|
|
137
|
+
* usually skip or forward; reading a deferred field is a one-time cost.
|
|
138
|
+
*
|
|
139
|
+
* @example
|
|
140
|
+
* ```ts
|
|
141
|
+
* @json
|
|
142
|
+
* class Repo {
|
|
143
|
+
* name: string = ""; // eager
|
|
144
|
+
* @lazy owner: Owner = new Owner; // parsed only when `repo.owner` is read
|
|
145
|
+
* }
|
|
146
|
+
* ```
|
|
147
|
+
*/
|
|
148
|
+
// @ts-ignore: type
|
|
149
|
+
declare function lazy(..._): void;
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Field decorator that forces a property to be parsed eagerly, opting it out of
|
|
153
|
+
* class-level lazy deferral (`@json({ lazy: "auto" | "all" })`). No effect on a
|
|
154
|
+
* class that is not lazy.
|
|
155
|
+
*
|
|
156
|
+
* @example
|
|
157
|
+
* ```ts
|
|
158
|
+
* @json({ lazy: "all" })
|
|
159
|
+
* class Event {
|
|
160
|
+
* @eager id: i32 = 0; // always parsed up-front
|
|
161
|
+
* payload: Payload = new Payload; // deferred
|
|
162
|
+
* }
|
|
163
|
+
* ```
|
|
164
|
+
*/
|
|
165
|
+
// @ts-ignore: type
|
|
166
|
+
declare function eager(..._): void;
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Method decorator marking a member as the class's custom serializer, replacing
|
|
170
|
+
* the generated serialization. The method receives the instance and must return
|
|
171
|
+
* a **valid JSON string**. Pair with {@link deserializer}.
|
|
172
|
+
*
|
|
173
|
+
* @param shape - Optional JSON value shape the output conforms to — one of
|
|
174
|
+
* `"any"` (default), `"string"`, `"number"`, `"object"`, `"array"`,
|
|
175
|
+
* `"boolean"`, or `"null"`.
|
|
176
|
+
*
|
|
177
|
+
* @example
|
|
178
|
+
* ```ts
|
|
179
|
+
* @json
|
|
180
|
+
* class Point {
|
|
181
|
+
* x: f64 = 0;
|
|
182
|
+
* y: f64 = 0;
|
|
183
|
+
* constructor(x: f64, y: f64) {
|
|
184
|
+
* this.x = x;
|
|
185
|
+
* this.y = y;
|
|
186
|
+
* }
|
|
187
|
+
*
|
|
188
|
+
* // Serialize a Point to a single JSON string.
|
|
189
|
+
* @serializer("string")
|
|
190
|
+
* serializer(self: Point): string {
|
|
191
|
+
* return JSON.stringify(`${self.x},${self.y}`);
|
|
192
|
+
* }
|
|
193
|
+
*
|
|
194
|
+
* // ...and back. Always return a fresh instance.
|
|
195
|
+
* @deserializer("string")
|
|
196
|
+
* deserializer(data: string): Point {
|
|
197
|
+
* const raw = JSON.parse<string>(data);
|
|
198
|
+
* const c = raw.indexOf(",");
|
|
199
|
+
* return new Point(f64.parse(raw.slice(0, c)), f64.parse(raw.slice(c + 1)));
|
|
200
|
+
* }
|
|
201
|
+
* }
|
|
202
|
+
*
|
|
203
|
+
* JSON.stringify(new Point(3.5, -9.2)); // '"3.5,-9.2"'
|
|
204
|
+
* JSON.parse<Point>('"3.5,-9.2"'); // Point { x: 3.5, y: -9.2 }
|
|
205
|
+
* ```
|
|
39
206
|
*/
|
|
40
207
|
// @ts-ignore: type
|
|
41
|
-
declare function serializer(
|
|
208
|
+
declare function serializer(
|
|
209
|
+
shape?: "any" | "string" | "number" | "object" | "array" | "boolean" | "null",
|
|
210
|
+
): any;
|
|
42
211
|
|
|
43
212
|
/**
|
|
44
|
-
* Method decorator
|
|
213
|
+
* Method decorator marking a member as the class's custom deserializer,
|
|
214
|
+
* replacing the generated deserialization. The method receives the raw JSON
|
|
215
|
+
* string and must return a **new** instance — never assume an existing
|
|
216
|
+
* destination is reused. Pair with {@link serializer} (see it for a full,
|
|
217
|
+
* round-tripping example).
|
|
218
|
+
*
|
|
219
|
+
* @param shape - Optional JSON value shape the input conforms to — one of
|
|
220
|
+
* `"any"` (default), `"string"`, `"number"`, `"object"`, `"array"`,
|
|
221
|
+
* `"boolean"`, or `"null"`.
|
|
222
|
+
*
|
|
223
|
+
* @example
|
|
224
|
+
* ```ts
|
|
225
|
+
* @deserializer("string")
|
|
226
|
+
* deserializer(data: string): Point {
|
|
227
|
+
* const raw = JSON.parse<string>(data); // unwrap the JSON string
|
|
228
|
+
* const c = raw.indexOf(",");
|
|
229
|
+
* return new Point(f64.parse(raw.slice(0, c)), f64.parse(raw.slice(c + 1)));
|
|
230
|
+
* }
|
|
231
|
+
* ```
|
|
45
232
|
*/
|
|
46
233
|
// @ts-ignore: type
|
|
47
|
-
declare function deserializer(
|
|
234
|
+
declare function deserializer(
|
|
235
|
+
shape?: "any" | "string" | "number" | "object" | "array" | "boolean" | "null",
|
|
236
|
+
): any;
|
|
48
237
|
|
|
49
|
-
|
|
238
|
+
/**
|
|
239
|
+
* Parsing/serialization strategy selected at build time via the `JSON_MODE`
|
|
240
|
+
* environment variable and exposed as {@link JSON_MODE}.
|
|
241
|
+
*/
|
|
242
|
+
declare const enum JSONMode {
|
|
243
|
+
/** Scalar/word-at-a-time (SWAR) scanning. The default; no extra flags. */
|
|
50
244
|
SWAR = 0,
|
|
245
|
+
/** 128-bit SIMD scanning. Fastest on larger payloads; needs `--enable simd`. */
|
|
51
246
|
SIMD = 1,
|
|
247
|
+
/** Straightforward byte-at-a-time scanning. Smallest code, slowest. */
|
|
52
248
|
NAIVE = 2,
|
|
53
249
|
}
|
|
54
250
|
|
|
251
|
+
/**
|
|
252
|
+
* The active {@link JSONMode}, injected by the transform from the `JSON_MODE`
|
|
253
|
+
* build-time environment variable (default `SWAR`). Set it on the `asc`
|
|
254
|
+
* command/build env; `SIMD` additionally requires `--enable simd`.
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```sh
|
|
258
|
+
* JSON_MODE=SIMD asc app.ts --transform json-as/transform --enable simd
|
|
259
|
+
* JSON_MODE=SWAR asc app.ts --transform json-as/transform # default
|
|
260
|
+
* JSON_MODE=NAIVE asc app.ts --transform json-as/transform
|
|
261
|
+
* ```
|
|
262
|
+
*/
|
|
55
263
|
declare const JSON_MODE: JSONMode;
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Whether the string cache is enabled (default off). Injected from the
|
|
267
|
+
* `JSON_CACHE` build-time environment variable. When on, repeated strings are
|
|
268
|
+
* reused to speed up string-heavy serialization.
|
|
269
|
+
*
|
|
270
|
+
* @example
|
|
271
|
+
* ```sh
|
|
272
|
+
* JSON_CACHE=true asc app.ts --transform json-as/transform # default size
|
|
273
|
+
* JSON_CACHE=512kb asc app.ts --transform json-as/transform # enable + size
|
|
274
|
+
* JSON_CACHE=false asc app.ts --transform json-as/transform # off (default)
|
|
275
|
+
* ```
|
|
276
|
+
*/
|
|
56
277
|
declare const JSON_CACHE: bool;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* The string-cache size in bytes when {@link JSON_CACHE} is enabled. Both this
|
|
281
|
+
* and {@link JSON_CACHE} are derived from the single `JSON_CACHE` build-time
|
|
282
|
+
* environment variable, which accepts raw bytes (`JSON_CACHE=1048576`), bit
|
|
283
|
+
* units (`512kb`, `2mb`, `1gb`), or byte units (`64KB`, `2MB`, `1GB`).
|
|
284
|
+
*
|
|
285
|
+
* @example
|
|
286
|
+
* ```sh
|
|
287
|
+
* JSON_CACHE=1mb asc app.ts --transform json-as/transform # JSON_CACHE_SIZE == 1048576
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
57
290
|
declare const JSON_CACHE_SIZE: usize;
|