json-as 1.0.0-alpha.4 → 1.0.0-beta.2

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.
Files changed (40) hide show
  1. package/.trunk/configs/.markdownlint.yaml +2 -0
  2. package/.trunk/configs/.shellcheckrc +7 -0
  3. package/.trunk/configs/.yamllint.yaml +7 -0
  4. package/.trunk/trunk.yaml +36 -0
  5. package/CHANGELOG +23 -0
  6. package/README.md +59 -57
  7. package/assembly/__benches__/misc.bench.ts +48 -0
  8. package/assembly/__benches__/schemas.ts +25 -0
  9. package/assembly/__benches__/string.bench.ts +24 -0
  10. package/assembly/__benches__/struct.bench.ts +22 -0
  11. package/assembly/__tests__/arbitrary.spec.ts +19 -0
  12. package/assembly/__tests__/custom.spec.ts +42 -0
  13. package/assembly/__tests__/types.ts +3 -3
  14. package/assembly/custom/bench.ts +26 -0
  15. package/assembly/deserialize/simd/string.ts +1 -1
  16. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  17. package/assembly/deserialize/simple/array/arbitrary.ts +47 -24
  18. package/assembly/deserialize/simple/array/{object.ts → struct.ts} +1 -1
  19. package/assembly/deserialize/simple/array.ts +4 -9
  20. package/assembly/deserialize/simple/integer.ts +2 -1
  21. package/assembly/deserialize/simple/map.ts +1 -1
  22. package/assembly/deserialize/simple/object.ts +11 -17
  23. package/assembly/deserialize/simple/struct.ts +158 -0
  24. package/assembly/index.d.ts +15 -1
  25. package/assembly/index.ts +144 -18
  26. package/assembly/serialize/simple/arbitrary.ts +15 -2
  27. package/assembly/serialize/simple/object.ts +43 -6
  28. package/assembly/serialize/simple/struct.ts +7 -0
  29. package/assembly/test.ts +61 -3
  30. package/assembly/util/atoi.ts +1 -1
  31. package/bench/bench.ts +15 -0
  32. package/bench/schemas.ts +5 -0
  33. package/bench/string.bench.ts +16 -0
  34. package/bench.js +11 -2
  35. package/modules/as-bs/assembly/index.ts +3 -3
  36. package/modules/as-bs/assembly/state.ts +8 -0
  37. package/package.json +3 -2
  38. package/transform/lib/index.js +59 -9
  39. package/transform/lib/index.js.map +1 -1
  40. package/transform/src/index.ts +75 -9
@@ -0,0 +1,2 @@
1
+ # Prettier friendly markdownlint config (all formatting rules disabled)
2
+ extends: markdownlint/style/prettier
@@ -0,0 +1,7 @@
1
+ enable=all
2
+ source-path=SCRIPTDIR
3
+ disable=SC2154
4
+
5
+ # If you're having issues with shellcheck following source, disable the errors via:
6
+ # disable=SC1090
7
+ # disable=SC1091
@@ -0,0 +1,7 @@
1
+ rules:
2
+ quoted-strings:
3
+ required: only-when-needed
4
+ extra-allowed: ["{|}"]
5
+ key-duplicates: {}
6
+ octal-values:
7
+ forbid-implicit-octal: true
@@ -0,0 +1,36 @@
1
+ # This file controls the behavior of Trunk: https://docs.trunk.io/cli
2
+ # To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
3
+ version: 0.1
4
+ cli:
5
+ version: 1.22.10
6
+ # Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
7
+ plugins:
8
+ sources:
9
+ - id: trunk
10
+ ref: v1.6.7
11
+ uri: https://github.com/trunk-io/plugins
12
+ # Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
13
+ runtimes:
14
+ enabled:
15
+ - go@1.21.0
16
+ - node@18.20.5
17
+ - python@3.10.8
18
+ # This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
19
+ lint:
20
+ enabled:
21
+ - actionlint@1.7.7
22
+ - checkov@3.2.374
23
+ - git-diff-check
24
+ - markdownlint@0.44.0
25
+ - prettier@3.5.2
26
+ - shellcheck@0.10.0
27
+ - shfmt@3.6.0
28
+ - trufflehog@3.88.12
29
+ - yamllint@1.35.1
30
+ actions:
31
+ disabled:
32
+ - trunk-announce
33
+ - trunk-check-pre-push
34
+ - trunk-fmt-pre-commit
35
+ enabled:
36
+ - trunk-upgrade-available
package/CHANGELOG CHANGED
@@ -1,5 +1,28 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-02-25 - 1.0.0-beta.2
4
+
5
+ - feat: add support for custom serializers and deserializers [#110](https://github.com/JairusSW/as-json/pull/110)
6
+
7
+ ## 2025-02-22 - 1.0.0-beta.1
8
+
9
+ - perf: add benchmarks for both AssemblyScript and JavaScript
10
+ - docs: publish preliminary benchmark results
11
+ - tests: ensure nested serialization works and add to tests
12
+ - feat: finish arbitrary type implementation
13
+ - feat: introduce `JSON.Obj` to handle objects effectively
14
+ - feat: reimplement arbitrary array deserialization
15
+ - fix: remove brace check on array deserialization
16
+ - feat: introduce native support for `JSON.Obj` transformations
17
+ - feat: implement arbitrary object serialization
18
+ - fix: deserialization of booleans panics on `false`
19
+ - fix: `bs.resize` should be type-safe
20
+ - impl: add `JSON.Obj` type as prototype to handle arbitrary object structures
21
+ - chore: rename static objects (schemas) to structs and name arbitrary objects as `obj`
22
+ - tests: add proper tests for arbitrary types
23
+ - fix: empty method generation using outdated function signature
24
+ - docs: update readme to be more concise
25
+
3
26
  ## 2025-02-13 - 1.0.0-alpha.4
4
27
 
5
28
  - feat: reintroduce support for `Box<T>`-wrapped primitive types
package/README.md CHANGED
@@ -6,47 +6,48 @@
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.0.0-alpha.4
9
+ AssemblyScript - v1.0.0-beta.2
10
10
  </pre>
11
11
  </h5>
12
12
 
13
- ## Contents
14
- - [About](#about)
15
- - [Installation](#installation)
16
- - [Usage](#usage)
17
- - [Examples](#examples)
18
- - [Performance](#performance)
19
- - [License](#license)
20
- - [Contact](#contact)
13
+ ## 📚 Contents
21
14
 
22
- ## About
15
+ - [About](#-about)
16
+ - [Installation](#-installation)
17
+ - [Usage](#-usage)
18
+ - [Examples](#examples)
19
+ - [Performance](#-performance)
20
+ - [License](#-license)
21
+ - [Contact](#-contact)
23
22
 
24
- ## Installation
23
+ ## 📝 About
24
+
25
+ JSON is the de-facto serialization format of modern web applications, but its serialization and deserialization remain a significant performance bottleneck, especially at scale. Traditional parsing approaches are computationally expensive, adding unnecessary overhead to both clients and servers. This library is designed to mitigate this by leveraging SIMD acceleration and highly optimized transformations.
26
+
27
+ ## 💾 Installation
25
28
 
26
29
  ```bash
27
- npm install json-as@1.0.0-alpha.3
30
+ npm install json-as@1.0.0-beta.2
28
31
  ```
29
32
 
30
33
  Add the `--transform` to your `asc` command (e.g. in package.json)
31
34
 
32
35
  ```bash
33
- --transform json-as
36
+ --transform json-as/transform
34
37
  ```
35
38
 
36
39
  Alternatively, add it to your `asconfig.json`
37
40
 
38
- ```
41
+ ```json
39
42
  {
40
43
  // ...
41
- "options": {
42
- "transform": ["json-as/transform"]
43
- }
44
+ "options": {"transform": ["json-as/transform"]}
44
45
  }
45
46
  ```
46
47
 
47
48
  If you'd like to see the code that the transform generates, run with `JSON_DEBUG=true`
48
49
 
49
- ## Usage
50
+ ## 🪄 Usage
50
51
 
51
52
  ```js
52
53
  import { JSON } from "json-as";
@@ -75,7 +76,7 @@ class Player {
75
76
  const player: Player = {
76
77
  firstName: "Jairus",
77
78
  lastName: "Tanaka",
78
- lastActive: [2, 7, 2025],
79
+ lastActive: [2, 13, 2025],
79
80
  age: 18,
80
81
  pos: {
81
82
  x: 3.4,
@@ -86,56 +87,57 @@ const player: Player = {
86
87
  };
87
88
 
88
89
  const serialized = JSON.stringify<Player>(player);
89
- const parsed = JSON.parse<Player>(serialized);
90
+ const deserialized = JSON.parse<Player>(serialized);
90
91
 
91
- console.log("Serialized: " + serialized);
92
- console.log("Parsed: " + JSON.stringify(parsed));
92
+ console.log("Serialized " + serialized);
93
+ console.log("Deserialized " + JSON.stringify(deserialized));
93
94
  ```
94
95
 
95
96
  ## Examples
96
97
 
97
- Classes can even have inheritance. Here's a nasty example
98
+ ## Performance
98
99
 
99
- ```js
100
- @json
101
- class Base {}
100
+ The `json-as` library has been optimized to achieve near-gigabyte-per-second JSON processing speeds through SIMD acceleration and highly efficient transformations. Below are some key performance benchmarks to give you an idea of how it performs.
102
101
 
103
- @json
104
- class Vec1 extends Base {
105
- x: f32 = 1.0;
106
- }
107
- @json
108
- class Vec2 extends Vec1 {
109
- y: f32 = 2.0;
110
- }
111
- @json
112
- class Vec3 extends Vec2 {
113
- z: f32 = 3.0;
114
- }
102
+ ### Raw Performance
115
103
 
116
- const arr: Base[] = [
117
- new Vec1(),
118
- new Vec2(),
119
- new Vec3()
120
- ];
104
+ Simple
121
105
 
122
- const serialized = JSON.stringify(arr);
123
- // [{"x":1.0},{"x":1.0,"y":2.0},{"y":2.0,"x":1.0,"z":3.0}]
124
- const parsed = JSON.parse<Base[]>(serialized);
125
- ```
106
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
107
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
108
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
109
+ | Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
110
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
111
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
112
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
126
113
 
127
- You can also add it to your `asconfig.json`
114
+ SIMD
128
115
 
129
- ```json
130
- {
131
- // ...
132
- "options": {
133
- "transform": ["json-as/transform"]
134
- }
135
- }
136
- ```
116
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
117
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
118
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
119
+ | Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
120
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
121
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
122
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
123
+
124
+ JavaScript
125
+
126
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
127
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
128
+ | Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
129
+ | Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
130
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
131
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
132
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
133
+
134
+ ### Real-World Usage
137
135
 
138
- If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
136
+ | Scenario | JSON Size (kb) | Serialization Time (ops/s) | Deserialization Time (ops/s) | Throughput (GB/s) |
137
+ | ---------------- | -------------- | -------------------------- | ---------------------------- | ----------------- |
138
+ | Web API Response | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
139
+ | Database Entry | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
140
+ | File Parsing | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
139
141
 
140
142
  ## 📃 License
141
143
 
@@ -0,0 +1,48 @@
1
+ import { bench } from "as-bench/assembly";
2
+ import { JSON } from "..";
3
+ import { Vec3 } from "./schemas";
4
+ import { bs } from "../../modules/as-bs/assembly";
5
+ import { serializeString_SIMD } from "../serialize/simd/string";
6
+ import { serializeString } from "../serialize/simple/string";
7
+ import { deserializeString } from "../deserialize/simple/string";
8
+ import { bytes } from "../util";
9
+ import { deserializeString_SIMD } from "../deserialize/simd/string";
10
+
11
+ const vec: Vec3 = {
12
+ x: 1,
13
+ y: 2,
14
+ z: 3
15
+ }
16
+
17
+ bs.ensureSize(4096);
18
+ // bench("Serialize Vector3", () => {
19
+ // JSON.stringify(vec);
20
+ // });
21
+
22
+ // bench("Deserialize Vector3", () => {
23
+ // JSON.parse<Vec3>('{"x":1,"y":2,"z":3}');
24
+ // });
25
+
26
+ // bench("Serialize String SIMD", () => {
27
+ // serializeString_SIMD("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
28
+ // bs.offset = changetype<usize>(bs.buffer);
29
+ // bs.stackSize = 0;
30
+ // });
31
+
32
+ // bench("Serialize String", () => {
33
+ // serializeString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
34
+ // bs.offset = changetype<usize>(bs.buffer);
35
+ // bs.stackSize = 0;
36
+ // });
37
+
38
+ const src = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\\\:;\\"\'?/>.<,\'\\"}"';
39
+ const srcStart = changetype<usize>(src);
40
+ const srcEnd = srcStart + bytes(src);
41
+ const out = changetype<usize>(new ArrayBuffer(256));
42
+ bench("Deserialize String", () => {
43
+ deserializeString(srcStart, srcEnd, out);
44
+ });
45
+
46
+ bench("Deserialize String SIMD", () => {
47
+ deserializeString_SIMD(srcStart, srcEnd, out);
48
+ })
@@ -0,0 +1,25 @@
1
+ import { JSON } from "..";
2
+
3
+ @json
4
+ export class Vec3 {
5
+ public x!: i32;
6
+ public y!: i32;
7
+ public z!: i32;
8
+ __DESERIALIZE(keyStart: usize, keyEnd: usize, valStart: usize, valEnd: usize, ptr: usize): void {
9
+ switch (load<u16>(keyStart)) {
10
+ case 120: { // x
11
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("x"));
12
+ return;
13
+ }
14
+ case 121: { // y
15
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("y"));
16
+ return;
17
+ }
18
+ case 122: { // z
19
+ store<i32>(ptr, JSON.__deserialize<i32>(valStart, valEnd, 0), offsetof<this>("z"));
20
+ return;
21
+ }
22
+ }
23
+ return;
24
+ }
25
+ }
@@ -0,0 +1,24 @@
1
+ import {JSON} from "..";
2
+ import {Vec3} from "./schemas";
3
+ import {bs} from "../../modules/as-bs/assembly";
4
+ import {bench} from "../custom/bench";
5
+ import {serializeString_SIMD} from "../serialize/simd/string";
6
+ import {deserializeString_SIMD} from "../deserialize/simd/string";
7
+ import {serializeString} from "../serialize/simple/string";
8
+ import {deserializeString} from "../deserialize/simple/string";
9
+
10
+ const vec: Vec3 = {x: 1, y: 2, z: 3};
11
+
12
+ bs.ensureSize(4096);
13
+
14
+ bench(
15
+ "Serialize String (Simple)",
16
+ () => {
17
+ serializeString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
18
+ },
19
+ 25_000_000
20
+ );
21
+
22
+ // bench("Deserialize String Simple", () => {
23
+ // deserializeString_SIMD("\"hello world\"")
24
+ // });
@@ -0,0 +1,22 @@
1
+ import {JSON} from "..";
2
+ import {Vec3} from "./schemas";
3
+ import {bs} from "../../modules/as-bs/assembly";
4
+ import {bench} from "./bench";
5
+
6
+ const vec: Vec3 = {x: 1, y: 2, z: 3};
7
+
8
+ bs.ensureSize(4096);
9
+ bench(
10
+ "Serialize Vector3",
11
+ () => {
12
+ // JSON.__serialize(vec);
13
+ // bs.offset = changetype<usize>(bs.buffer);
14
+ // bs.stackSize = 0;
15
+ JSON.stringify(vec);
16
+ },
17
+ 25_000_000
18
+ );
19
+
20
+ // bench("Deserialize Vector3", () => {
21
+ // JSON.parse<Vec3>('{"x":1,"y":2,"z":3}');
22
+ // });
@@ -0,0 +1,19 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "../../modules/test/assembly";
3
+ import { Vec3 } from "./types";
4
+
5
+ describe("Should serialize arbitrary types", () => {
6
+ expect(JSON.stringify(JSON.Value.from("hello world"))).toBe("\"hello world\"");
7
+ expect(JSON.stringify(JSON.Value.from(0))).toBe("0");
8
+ expect(JSON.stringify(JSON.Value.from(true))).toBe("true");
9
+ expect(JSON.stringify(JSON.Value.from(new Vec3()))).toBe('{"x":1.0,"y":2.0,"z":3.0}');
10
+ expect(JSON.stringify([JSON.Value.from("string"), JSON.Value.from(true), JSON.Value.from(3.14), JSON.Value.from(new Vec3())])).toBe('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0}]');
11
+ });
12
+
13
+ describe("Should deserialize arbitrary types", () => {
14
+ expect(JSON.parse<JSON.Value>("\"hello world\"").get<string>()).toBe("hello world");
15
+ expect(JSON.parse<JSON.Value>("0.0").toString()).toBe("0.0");
16
+ expect(JSON.parse<JSON.Value>("true").toString()).toBe("true");
17
+ expect(JSON.stringify(JSON.parse<JSON.Value>('{"x":1.0,"y":2.0,"z":3.0}'))).toBe('{"x":1.0,"y":2.0,"z":3.0}');
18
+ expect(JSON.stringify(JSON.parse<JSON.Value[]>('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0},[1.0,2.0,3,true]]'))).toBe('["string",true,3.14,{"x":1.0,"y":2.0,"z":3.0},[1.0,2.0,3.0,true]]');
19
+ });
@@ -0,0 +1,42 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "../../modules/test/assembly";
3
+ import { bytes } from "../util";
4
+
5
+ @json
6
+ class Point {
7
+ x: f64 = 0.0;
8
+ y: f64 = 0.0;
9
+ constructor(x: f64, y: f64) {
10
+ this.x = x;
11
+ this.y = y;
12
+ }
13
+ @serializer
14
+ serializer(self: Point): string {
15
+ return `(${self.x},${self.y})`;
16
+ }
17
+ @deserializer
18
+ deserializer(data: string): Point {
19
+ const dataSize = bytes(data);
20
+ if (dataSize <= 2) throw new Error("Could not deserialize provided data as type Point");
21
+
22
+ const c = data.indexOf(",");
23
+ const x = data.slice(1, c);
24
+ const y = data.slice(c + 1, data.length - 1);
25
+
26
+ return new Point(
27
+ f64.parse(x),
28
+ f64.parse(y)
29
+ );
30
+ }
31
+ }
32
+
33
+
34
+ describe("Should serialize using custom serializers", () => {
35
+ expect(JSON.stringify<Point>(new Point(1,2))).toBe("(1.0,2.0)");
36
+ });
37
+
38
+ describe("Should deserialize using custom deserializers", () => {
39
+ const p1 = JSON.parse<Point>("(1.0,2.0)");
40
+ expect(p1.x.toString()).toBe("1.0");
41
+ expect(p1.y.toString()).toBe("2.0");
42
+ });
@@ -61,9 +61,9 @@ export class Map4 {
61
61
 
62
62
  @json
63
63
  export class Vec3 {
64
- x: f64;
65
- y: f64;
66
- z: f64;
64
+ x: f64 = 1.0;
65
+ y: f64 = 2.0;
66
+ z: f64 = 3.0;
67
67
 
68
68
  static shouldIgnore: string = "should not be serialized";
69
69
  }
@@ -0,0 +1,26 @@
1
+ export function bench(description: string, routine: () => void, ops: u64 = 1_000_000): void {
2
+ console.log(" - Benchmarking " + description);
3
+ const start = Date.now();
4
+ let count = ops;
5
+ while (count != 0) {
6
+ routine();
7
+ count--;
8
+ }
9
+ const elapsed = Date.now() - start;
10
+
11
+ let opsPerSecond = (ops * 1000) / elapsed;
12
+
13
+ console.log(` Completed benchmark in ${formatNumber(elapsed)}ms at ${formatNumber(opsPerSecond)} ops/s\n`);
14
+ }
15
+
16
+ function formatNumber(n: u64): string {
17
+ let str = n.toString();
18
+ let len = str.length;
19
+ let result = "";
20
+ let commaOffset = len % 3;
21
+ for (let i = 0; i < len; i++) {
22
+ if (i > 0 && (i - commaOffset) % 3 == 0) result += ",";
23
+ result += str.charAt(i);
24
+ }
25
+ return result;
26
+ }
@@ -10,7 +10,7 @@ const SPLAT_92 = i16x8.splat(92); /* \ */
10
10
  * @returns number of bytes written
11
11
  */
12
12
  // todo: optimize and stuff. it works, its not pretty. ideally, i'd like this to be (nearly) branchless
13
- export function deserializeString_SIMD(src: string, srcStart: usize, srcEnd: usize, dst: usize): usize {
13
+ export function deserializeString_SIMD(srcStart: usize, srcEnd: usize, dst: usize): usize {
14
14
  let src_ptr = srcStart + 2;
15
15
  let dst_ptr = changetype<usize>(dst);
16
16
 
@@ -2,8 +2,8 @@ import { JSON } from "../..";
2
2
  import { deserializeArray } from "./array";
3
3
  import { deserializeBoolean } from "./bool";
4
4
  import { deserializeFloat } from "./float";
5
- import { deserializeObject } from "./object";
6
5
  import { deserializeString } from "./string";
6
+ import { deserializeObject } from "./object";
7
7
 
8
8
  export function deserializeArbitrary(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value {
9
9
  const firstChar = load<u16>(srcStart);
@@ -1,45 +1,66 @@
1
1
  import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, CHAR_F, CHAR_N, CHAR_T, COMMA, QUOTE } from "../../../custom/chars";
2
2
  import { JSON } from "../../../";
3
3
  import { isSpace } from "util/string";
4
+ import { ptrToStr } from "../../../util/ptrToStr";
4
5
 
5
- export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
6
- const out = dst ? changetype<T>(dst) : instantiate<T>();
6
+ export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
7
+ const out = dst ? changetype<JSON.Value[]>(dst) : instantiate<JSON.Value[]>();
7
8
  let lastIndex: usize = 0;
8
9
  let depth: u32 = 0;
10
+ // if (load<u16>(srcStart) != BRACKET_LEFT)
11
+ srcStart += 2;
9
12
  while (srcStart < srcEnd) {
10
13
  const code = load<u16>(srcStart);
11
- if (code == QUOTE) {
14
+ // console.log("code: " + String.fromCharCode(code));
15
+ if (code == BRACE_LEFT) {
12
16
  lastIndex = srcStart;
17
+ depth++;
13
18
  srcStart += 2;
14
19
  while (srcStart < srcEnd) {
15
20
  const code = load<u16>(srcStart);
16
- if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
17
- while (isSpace(load<u16>((srcStart += 2)))) {
18
- /* empty */
21
+ if (code == BRACE_RIGHT) {
22
+ if (--depth == 0) {
23
+ // @ts-ignore: type
24
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
25
+ // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
26
+ break;
19
27
  }
20
- // console.log("Value (string): " + ptrToStr(lastIndex, srcStart));
28
+ } else if (code == BRACE_LEFT) depth++;
29
+ srcStart += 2;
30
+ }
31
+ } else if (code == QUOTE) {
32
+ lastIndex = srcStart;
33
+ srcStart += 2;
34
+ while (srcStart < srcEnd) {
35
+ const code = load<u16>(srcStart);
36
+ if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
37
+ // while (isSpace(load<u16>((srcStart += 2)))) {
38
+ // /* empty */
39
+ // }
40
+ // console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
21
41
  // @ts-ignore: exists
22
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
42
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
43
+ srcStart += 2;
23
44
  break;
24
45
  }
25
46
  srcStart += 2;
26
47
  }
48
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
27
49
  } else if (code - 48 <= 9 || code == 45) {
50
+ // console.log("trigger int")
28
51
  lastIndex = srcStart;
29
52
  srcStart += 2;
30
53
  while (srcStart < srcEnd) {
31
54
  const code = load<u16>(srcStart);
32
- if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
55
+ if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
33
56
  // @ts-ignore: type
34
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
57
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
35
58
  // console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
36
- while (isSpace(load<u16>((srcStart += 2)))) {
37
- /* empty */
38
- }
39
59
  break;
40
60
  }
41
61
  srcStart += 2;
42
62
  }
63
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
43
64
  } else if (code == BRACE_LEFT) {
44
65
  lastIndex = srcStart;
45
66
  depth++;
@@ -49,7 +70,7 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
49
70
  if (code == BRACE_RIGHT) {
50
71
  if (--depth == 0) {
51
72
  // @ts-ignore: type
52
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
73
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
53
74
  // console.log("Value (object): " + ptrToStr(lastIndex, srcStart));
54
75
  while (isSpace(load<u16>((srcStart += 2)))) {
55
76
  /* empty */
@@ -68,7 +89,7 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
68
89
  if (code == BRACKET_RIGHT) {
69
90
  if (--depth == 0) {
70
91
  // @ts-ignore: type
71
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
92
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
72
93
  // console.log("Value (array): " + ptrToStr(lastIndex, srcStart));
73
94
  while (isSpace(load<u16>((srcStart += 2)))) {
74
95
  /* empty */
@@ -81,25 +102,27 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
81
102
  } else if (code == CHAR_T) {
82
103
  if (load<u64>(srcStart) == 28429475166421108) {
83
104
  // @ts-ignore: type
84
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
105
+ out.push(JSON.__deserialize<JSON.Value>(srcStart, (srcStart += 8)));
85
106
  // console.log("Value (bool): " + ptrToStr(srcStart - 8, srcStart));
86
- while (isSpace(load<u16>((srcStart += 2)))) {
87
- /* empty */
88
- }
107
+ // while (isSpace(load<u16>((srcStart += 2)))) {
108
+ // /* empty */
109
+ // }
110
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
89
111
  }
90
112
  } else if (code == CHAR_F) {
91
113
  if (load<u64>(srcStart, 2) == 28429466576093281) {
92
114
  // @ts-ignore: type
93
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 10)));
115
+ out.push(JSON.__deserialize<JSON.Value>(srcStart, (srcStart += 10)));
94
116
  // console.log("Value (bool): " + ptrToStr(srcStart - 10, srcStart));
95
- while (isSpace(load<u16>((srcStart += 2)))) {
96
- /* empty */
97
- }
117
+ // while (isSpace(load<u16>((srcStart += 2)))) {
118
+ // /* empty */
119
+ // }
120
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
98
121
  }
99
122
  } else if (code == CHAR_N) {
100
123
  if (load<u64>(srcStart) == 30399761348886638) {
101
124
  // @ts-ignore: type
102
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
125
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, (srcStart += 8)));
103
126
  // console.log("Value (null): " + ptrToStr(srcStart - 8, srcStart));
104
127
  while (isSpace(load<u16>((srcStart += 2)))) {
105
128
  /* empty */
@@ -1,7 +1,7 @@
1
1
  import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../..";
3
3
 
4
- export function deserializeObjectArray<T extends unknown[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
4
+ export function deserializeStructArray<T extends unknown[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
5
  const out = dst ? changetype<T>(dst) : instantiate<T>();
6
6
  let lastIndex: usize = 0;
7
7
  let depth: u32 = 0;