json-as 0.9.28 → 1.0.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/.github/workflows/nodejs.yml +0 -3
- package/.prettierrc.json +4 -1
- package/CHANGELOG +13 -0
- package/LICENSE +1 -1
- package/README.md +22 -7
- package/as-test.config.json +1 -1
- package/asconfig.json +2 -2
- package/assembly/__benches__/misc.bench.ts +17 -31
- package/assembly/__tests__/bool.spec.ts +1 -1
- package/assembly/__tests__/simd/string.spec.ts +32 -0
- package/assembly/__tests__/types.ts +17 -0
- package/assembly/custom/chars.ts +2 -2
- package/assembly/custom/memory.ts +25 -0
- package/assembly/custom/types.ts +1 -0
- package/assembly/custom/util.ts +59 -140
- package/assembly/deserialize/simd/string.ts +103 -0
- package/assembly/deserialize/simple/arbitrary.ts +17 -0
- package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
- package/assembly/deserialize/simple/array/array.ts +18 -0
- package/assembly/deserialize/simple/array/bool.ts +17 -0
- package/assembly/deserialize/simple/array/float.ts +28 -0
- package/assembly/deserialize/simple/array/integer.ts +27 -0
- package/assembly/deserialize/simple/array/map.ts +18 -0
- package/assembly/deserialize/simple/array/object.ts +18 -0
- package/assembly/deserialize/simple/array/string.ts +22 -0
- package/assembly/deserialize/simple/array.ts +48 -0
- package/assembly/deserialize/simple/bool.ts +9 -0
- package/assembly/deserialize/simple/date.ts +11 -0
- package/assembly/deserialize/simple/float.ts +10 -0
- package/assembly/deserialize/simple/integer.ts +5 -0
- package/assembly/deserialize/simple/map.ts +154 -0
- package/assembly/deserialize/simple/object.ts +159 -0
- package/assembly/deserialize/simple/string.ts +48 -0
- package/assembly/globals/tables.ts +417 -0
- package/assembly/index.d.ts +9 -13
- package/assembly/index.ts +282 -158
- package/assembly/serialize/simd/string.ts +176 -0
- package/assembly/serialize/simple/arbitrary.ts +36 -0
- package/assembly/serialize/simple/array.ts +32 -0
- package/assembly/serialize/simple/bool.ts +19 -0
- package/assembly/serialize/simple/date.ts +13 -0
- package/assembly/serialize/simple/float.ts +7 -0
- package/assembly/serialize/simple/integer.ts +7 -0
- package/assembly/serialize/simple/map.ts +43 -0
- package/assembly/serialize/simple/object.ts +7 -0
- package/assembly/serialize/simple/string.ts +48 -0
- package/assembly/test.ts +43 -28
- package/assembly/tsconfig.json +2 -91
- package/assembly/types.ts +0 -0
- package/assembly/util/atoi.ts +35 -0
- package/assembly/util/bytes.ts +12 -0
- package/assembly/util/concat.ts +9 -0
- package/assembly/util/getArrayDepth.ts +17 -0
- package/assembly/util/index.ts +5 -0
- package/assembly/util/isSpace.ts +4 -0
- package/assembly/util/nextPowerOf2.ts +4 -0
- package/assembly/util/ptrToStr.ts +7 -0
- package/assembly/util/snp.ts +69 -0
- package/bench.js +5 -5
- package/modules/bs/index.ts +167 -0
- package/modules/tsconfig.json +8 -0
- package/package.json +42 -47
- package/transform/lib/builder.js +1353 -0
- package/transform/lib/builder.js.map +1 -0
- package/transform/lib/index.js +497 -395
- package/transform/lib/index.js.map +1 -1
- package/transform/lib/index.old.js +404 -0
- package/transform/lib/index.old.js.map +1 -0
- package/transform/lib/linker.js +18 -0
- package/transform/lib/linker.js.map +1 -0
- package/transform/lib/types.js +25 -0
- package/transform/lib/types.js.map +1 -0
- package/transform/lib/util.js +47 -0
- package/transform/lib/util.js.map +1 -0
- package/transform/lib/visitor.js +529 -446
- package/transform/lib/visitor.js.map +1 -0
- package/transform/package.json +1 -34
- package/transform/src/builder.ts +1371 -0
- package/transform/src/index.ts +571 -481
- package/transform/src/linker.ts +21 -0
- package/transform/src/types.ts +27 -0
- package/transform/src/util.ts +56 -0
- package/transform/src/visitor.ts +531 -0
- package/transform/tsconfig.json +3 -1
- package/assembly/__benches__/as-tral.d.ts +0 -1
- package/assembly/custom/bs.ts +0 -211
- package/assembly/deserialize/array/array.ts +0 -31
- package/assembly/deserialize/array/bool.ts +0 -19
- package/assembly/deserialize/array/float.ts +0 -24
- package/assembly/deserialize/array/integer.ts +0 -24
- package/assembly/deserialize/array/map.ts +0 -27
- package/assembly/deserialize/array/object.ts +0 -27
- package/assembly/deserialize/array/string.ts +0 -29
- package/assembly/deserialize/array.ts +0 -46
- package/assembly/deserialize/bool.ts +0 -34
- package/assembly/deserialize/date.ts +0 -19
- package/assembly/deserialize/float.ts +0 -21
- package/assembly/deserialize/integer.ts +0 -16
- package/assembly/deserialize/map.ts +0 -189
- package/assembly/deserialize/object.ts +0 -271
- package/assembly/deserialize/string.ts +0 -164
- package/assembly/serialize/array.ts +0 -51
- package/assembly/serialize/bool.ts +0 -10
- package/assembly/serialize/date.ts +0 -4
- package/assembly/serialize/float.ts +0 -4
- package/assembly/serialize/integer.ts +0 -5
- package/assembly/serialize/map.ts +0 -24
- package/assembly/serialize/object.ts +0 -13
- package/assembly/serialize/string.ts +0 -287
- package/logs/test.log.json +0 -1049
package/.prettierrc.json
CHANGED
package/CHANGELOG
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Change Log
|
|
2
|
+
|
|
3
|
+
## UNRELEASED
|
|
4
|
+
|
|
5
|
+
## 2025-01-20 - 1.0.0-alpha.1
|
|
6
|
+
|
|
7
|
+
- feat: finish implementation of arbitrary data serialization and deserialization using JSON.Value
|
|
8
|
+
- feat: reinstate usage of `JSON.Box<T>()` to support nullable primitive types
|
|
9
|
+
- feat: eliminate the need to import the `JSON` namespace when defining a schema
|
|
10
|
+
- feat: reduce memory usage so that it is viable for low-memory environments
|
|
11
|
+
- feat: write to a central buffer and reduce memory overhead
|
|
12
|
+
- feat: rewrite the transform to properly resolve schemas and link them together
|
|
13
|
+
- feat: pre-allocate and compute the minimum size of a schema to avoid memory out of range errors
|
package/LICENSE
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c)
|
|
3
|
+
Copyright (c) 2025 Jairus Tanaka <me@jairus.dev>
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
package/README.md
CHANGED
|
@@ -6,29 +6,29 @@
|
|
|
6
6
|
██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
|
|
7
7
|
█████ ███████ ██████ ██ ████ ██ ██ ███████
|
|
8
8
|
</span>
|
|
9
|
-
AssemblyScript -
|
|
9
|
+
AssemblyScript - v1.0.0-alpha.1
|
|
10
10
|
</pre>
|
|
11
11
|
</h5>
|
|
12
12
|
|
|
13
13
|
## Installation
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
npm install json-as
|
|
16
|
+
npm install json-as@1.0.0-alpha.1
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Add the `--transform` to your `asc` command (e.g. in package.json)
|
|
20
20
|
|
|
21
21
|
```bash
|
|
22
|
-
--transform json-as
|
|
22
|
+
--transform json-as
|
|
23
23
|
```
|
|
24
24
|
|
|
25
25
|
Alternatively, add it to your `asconfig.json`
|
|
26
26
|
|
|
27
|
-
```
|
|
27
|
+
```
|
|
28
28
|
{
|
|
29
29
|
// ...
|
|
30
30
|
"options": {
|
|
31
|
-
"transform": ["json-as
|
|
31
|
+
"transform": ["json-as"]
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
```
|
|
@@ -38,7 +38,7 @@ If you'd like to see the code that the transform generates, run with `JSON_DEBUG
|
|
|
38
38
|
## Usage
|
|
39
39
|
|
|
40
40
|
```js
|
|
41
|
-
import { JSON } from "json-as
|
|
41
|
+
import { JSON } from "json-as";
|
|
42
42
|
|
|
43
43
|
// @json or @serializable work here
|
|
44
44
|
@json
|
|
@@ -55,7 +55,7 @@ class Player {
|
|
|
55
55
|
lastName!: string;
|
|
56
56
|
lastActive!: i32[];
|
|
57
57
|
// Drop in a code block, function, or expression that evaluates to a boolean
|
|
58
|
-
@omitif(
|
|
58
|
+
@omitif((age) => age < 18)
|
|
59
59
|
age!: i32;
|
|
60
60
|
@omitnull()
|
|
61
61
|
pos!: Vec3 | null;
|
|
@@ -110,8 +110,23 @@ const serialized = JSON.stringify(arr);
|
|
|
110
110
|
const parsed = JSON.parse<Base[]>(serialized);
|
|
111
111
|
```
|
|
112
112
|
|
|
113
|
+
You can also add it to your `asconfig.json`
|
|
114
|
+
|
|
115
|
+
```json
|
|
116
|
+
{
|
|
117
|
+
// ...
|
|
118
|
+
"options": {
|
|
119
|
+
"transform": ["json-as/transform"]
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
113
124
|
If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
|
|
114
125
|
|
|
126
|
+
## Notes
|
|
127
|
+
|
|
128
|
+
If you want a feature, drop an issue (and again, maybe a star). I'll likely add it in less than 7 days.
|
|
129
|
+
|
|
115
130
|
## Contact
|
|
116
131
|
|
|
117
132
|
- [Email](mailto:me@jairus.dev)
|
package/as-test.config.json
CHANGED
package/asconfig.json
CHANGED
|
@@ -1,33 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { bench } from "as-bench/assembly/bench";
|
|
2
|
+
import { bs } from "../../modules/bs";
|
|
3
|
+
import { deserializeString_SIMD } from "../deserialize/simd/string";
|
|
4
|
+
import { deserializeString } from "../deserialize/simple/string";
|
|
5
|
+
import { bytes } from "../util/bytes";
|
|
6
|
+
const str = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()\\\"\t\r\f\n\u0000';
|
|
7
|
+
const str2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()\\\\\\"\\t\\r\\f\\n\\u0000"';
|
|
8
|
+
const srcStart = changetype<usize>(str);
|
|
9
|
+
const srcEnd = srcStart + bytes(str);
|
|
10
|
+
bs.ensureSize(2048);
|
|
11
|
+
bench("Deserialize String (Simple)", () => {
|
|
12
|
+
deserializeStrin(str2);
|
|
6
13
|
});
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
14
|
+
// bench("Deserialize String (SIMD)", () => {
|
|
15
|
+
// (str2, bs.buffer);
|
|
16
|
+
// });
|
|
17
|
+
bench("Deserialize String (SIMD)", () => {
|
|
18
|
+
deserializeString_SIMD(str2, srcStart, srcEnd, __new(158, idof<string>()));
|
|
10
19
|
});
|
|
11
|
-
|
|
12
|
-
bench("Match Type (array)", () => {
|
|
13
|
-
blackbox<boolean>(matchType(blackbox<string>("["), JSON.Types.Array));
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
bench("Match Type (struct)", () => {
|
|
17
|
-
blackbox<boolean>(matchType(blackbox<string>("{"), JSON.Types.Obj));
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
bench("Match Type (raw)", () => {
|
|
21
|
-
blackbox<boolean>(matchType(blackbox<string>("\""), JSON.Types.Raw));
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
@inline function matchType(data: string, type: JSON.Types): boolean {
|
|
25
|
-
const firstChar = load<u8>(changetype<usize>(data));
|
|
26
|
-
if (JSON.Types.String == type && firstChar == QUOTE) return true;
|
|
27
|
-
else if (JSON.Types.Bool == type && (firstChar == CHAR_T || firstChar == CHAR_F)) return true;
|
|
28
|
-
else if (JSON.Types.Array == type && firstChar == BRACKET_LEFT) return true;
|
|
29
|
-
else if (JSON.Types.Obj == type && firstChar == BRACE_LEFT) return true;
|
|
30
|
-
else if (type < 7 && type > 0 && (firstChar < 58 && firstChar > 46)) return true;
|
|
31
|
-
else if (JSON.Types.Raw == type) return true;
|
|
32
|
-
else return false;
|
|
33
|
-
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { describe, expect, run } from "as-test/assembly";
|
|
2
|
+
import { serializeString_SIMD } from "../../serialize/simd/string";
|
|
3
|
+
import { deserializeString_SIMD } from "../../deserialize/simd/string";
|
|
4
|
+
|
|
5
|
+
const out = changetype<usize>(new ArrayBuffer(512));
|
|
6
|
+
|
|
7
|
+
const serialize_simd = (data: string): string => String.UTF16.decodeUnsafe(out, serializeString_SIMD(data, out));
|
|
8
|
+
const deserialize_simd = (data: string): string => String.UTF16.decodeUnsafe(out, deserializeString_SIMD(data, out));
|
|
9
|
+
describe("Should serialize strings", () => {
|
|
10
|
+
expect(serialize_simd("abcdefg")).toBe('"abcdefg"');
|
|
11
|
+
|
|
12
|
+
expect(serialize_simd('st"ring" w""ith quotes"')).toBe('"st\\"ring\\" w\\"\\"ith quotes\\""');
|
|
13
|
+
|
|
14
|
+
expect(serialize_simd('string "with random spa\nces and \nnewlines\n\n\n')).toBe('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"');
|
|
15
|
+
|
|
16
|
+
expect(serialize_simd('string with colon : comma , brace [ ] bracket { } and quote " and other quote "')).toBe('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\""');
|
|
17
|
+
|
|
18
|
+
expect(serialize_simd("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f")).toBe('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe("Should deserialize strings", () => {
|
|
22
|
+
expect(deserialize_simd('"abcdefg"')).toBe("abcdefg");
|
|
23
|
+
expect(deserialize_simd('"st\\"ring\\" w\\"\\"ith quotes\\""')).toBe('st"ring" w""ith quotes"');
|
|
24
|
+
|
|
25
|
+
expect(deserialize_simd('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"')).toBe('string "with random spa\nces and \nnewlines\n\n\n');
|
|
26
|
+
|
|
27
|
+
expect(deserialize_simd('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\""')).toBe('string with colon : comma , brace [ ] bracket { } and quote " and other quote "');
|
|
28
|
+
|
|
29
|
+
expect(deserialize_simd('"\\u0000\\u0001\\u0002\\u0003\\u0004\\u0005\\u0006\\u0007\\b\\t\\n\\u000b\\f\\r\\u000e\\u000f\\u000f\\u0011\\u0012\\u0013\\u0014\\u0015\\u0016\\u0017\\u0018\\u0019\\u001a\\u001b\\u001c\\u001d\\u001e\\u001f"')).toBe("\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f\u000f\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f");
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
run();
|
|
@@ -1,28 +1,36 @@
|
|
|
1
|
+
|
|
1
2
|
@json
|
|
2
3
|
export class ObjWithString {
|
|
3
4
|
s!: string;
|
|
4
5
|
}
|
|
5
6
|
|
|
7
|
+
|
|
6
8
|
@json
|
|
7
9
|
export class ObjWithStrangeKey<T> {
|
|
10
|
+
|
|
8
11
|
@alias('a\\\t"\x02b`c')
|
|
9
12
|
data!: T;
|
|
10
13
|
}
|
|
14
|
+
|
|
15
|
+
|
|
11
16
|
@json
|
|
12
17
|
export class ObjectWithStringArray {
|
|
13
18
|
sa!: string[];
|
|
14
19
|
}
|
|
15
20
|
|
|
21
|
+
|
|
16
22
|
@json
|
|
17
23
|
export class ObjectWithFloat {
|
|
18
24
|
f!: f64;
|
|
19
25
|
}
|
|
20
26
|
|
|
27
|
+
|
|
21
28
|
@json
|
|
22
29
|
export class ObjectWithFloatArray {
|
|
23
30
|
fa!: f64[];
|
|
24
31
|
}
|
|
25
32
|
|
|
33
|
+
|
|
26
34
|
@json
|
|
27
35
|
export class BaseObject {
|
|
28
36
|
a: string;
|
|
@@ -31,6 +39,7 @@ export class BaseObject {
|
|
|
31
39
|
}
|
|
32
40
|
}
|
|
33
41
|
|
|
42
|
+
|
|
34
43
|
@json
|
|
35
44
|
export class DerivedObject extends BaseObject {
|
|
36
45
|
b: string;
|
|
@@ -40,6 +49,7 @@ export class DerivedObject extends BaseObject {
|
|
|
40
49
|
}
|
|
41
50
|
}
|
|
42
51
|
|
|
52
|
+
|
|
43
53
|
@json
|
|
44
54
|
export class Map4 {
|
|
45
55
|
a: string;
|
|
@@ -48,6 +58,7 @@ export class Map4 {
|
|
|
48
58
|
d: string;
|
|
49
59
|
}
|
|
50
60
|
|
|
61
|
+
|
|
51
62
|
@json
|
|
52
63
|
export class Vec3 {
|
|
53
64
|
x: f64;
|
|
@@ -57,6 +68,7 @@ export class Vec3 {
|
|
|
57
68
|
static shouldIgnore: string = "should not be serialized";
|
|
58
69
|
}
|
|
59
70
|
|
|
71
|
+
|
|
60
72
|
@json
|
|
61
73
|
export class Player {
|
|
62
74
|
firstName: string;
|
|
@@ -70,12 +82,17 @@ export class Player {
|
|
|
70
82
|
export class Nullable {}
|
|
71
83
|
export type Null = Nullable | null;
|
|
72
84
|
|
|
85
|
+
|
|
73
86
|
@json
|
|
74
87
|
export class OmitIf {
|
|
75
88
|
x: i32 = 1;
|
|
89
|
+
|
|
90
|
+
|
|
76
91
|
@omitif("this.y == -1")
|
|
77
92
|
y: i32 = -1;
|
|
78
93
|
z: i32 = 1;
|
|
94
|
+
|
|
95
|
+
|
|
79
96
|
@omitnull()
|
|
80
97
|
foo: string | null = null;
|
|
81
98
|
}
|
package/assembly/custom/chars.ts
CHANGED
|
@@ -59,9 +59,9 @@
|
|
|
59
59
|
// @ts-ignore: Decorator is valid here
|
|
60
60
|
@inline export const BRACKET_RIGHT_WORD = "]";
|
|
61
61
|
// @ts-ignore: Decorator is valid here
|
|
62
|
-
@inline export const QUOTE_WORD = "
|
|
62
|
+
@inline export const QUOTE_WORD = '"';
|
|
63
63
|
// @ts-ignore: Decorator is valid here
|
|
64
|
-
@inline export const EMPTY_QUOTE_WORD = "
|
|
64
|
+
@inline export const EMPTY_QUOTE_WORD = '""';
|
|
65
65
|
|
|
66
66
|
// Escape Codes
|
|
67
67
|
// @ts-ignore: Decorator is valid here
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { BLOCK_MAXSIZE, OBJECT, TOTAL_OVERHEAD } from "rt/common";
|
|
2
|
+
import { E_INVALIDLENGTH } from "util/error";
|
|
3
|
+
|
|
4
|
+
// @ts-ignore: Decorator valid here
|
|
5
|
+
@inline export function ensureCapacity<T>(obj: T, newSize: usize): usize {
|
|
6
|
+
const ptr = changetype<usize>(obj);
|
|
7
|
+
const oldCapacity = changetype<OBJECT>(ptr - TOTAL_OVERHEAD).rtSize;
|
|
8
|
+
if (newSize > oldCapacity) {
|
|
9
|
+
if (newSize > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH);
|
|
10
|
+
const newCapacity = max(min(oldCapacity << 1, BLOCK_MAXSIZE), newSize);
|
|
11
|
+
const newObj = __renew(ptr, newCapacity);
|
|
12
|
+
return newObj;
|
|
13
|
+
}
|
|
14
|
+
return ptr;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// @ts-ignore: Decorator valid here
|
|
18
|
+
@inline export function setCapacity<T>(obj: T, oldCapacity: usize, newCapacity: usize): usize {
|
|
19
|
+
const ptr = changetype<usize>(obj);
|
|
20
|
+
if (newCapacity > oldCapacity) {
|
|
21
|
+
if (newCapacity > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH);
|
|
22
|
+
return __renew(ptr, newCapacity);
|
|
23
|
+
}
|
|
24
|
+
return ptr;
|
|
25
|
+
}
|
package/assembly/custom/types.ts
CHANGED