json-as 1.0.0-alpha.4 → 1.0.0-beta.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/README.md CHANGED
@@ -1,41 +1,44 @@
1
1
  <h5 align="center">
2
2
  <pre>
3
3
  <span style="font-size: 0.8em;"> ██ ███████ ██████ ███ ██ █████ ███████
4
- ██ ██ ██ ██ ████ ██ ██ ██ ██
4
+ ██ ██ ██ ██ ████ ██ ██ ██ ██
5
5
  ██ ███████ ██ ██ ██ ██ ██ █████ ███████ ███████
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.0.0-alpha.4
9
+ AssemblyScript - v1.0.0-beta.1
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.1
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
44
  "options": {
@@ -46,7 +49,7 @@ Alternatively, add it to your `asconfig.json`
46
49
 
47
50
  If you'd like to see the code that the transform generates, run with `JSON_DEBUG=true`
48
51
 
49
- ## Usage
52
+ ## 🪄 Usage
50
53
 
51
54
  ```js
52
55
  import { JSON } from "json-as";
@@ -75,7 +78,7 @@ class Player {
75
78
  const player: Player = {
76
79
  firstName: "Jairus",
77
80
  lastName: "Tanaka",
78
- lastActive: [2, 7, 2025],
81
+ lastActive: [2, 13, 2025],
79
82
  age: 18,
80
83
  pos: {
81
84
  x: 3.4,
@@ -86,56 +89,58 @@ const player: Player = {
86
89
  };
87
90
 
88
91
  const serialized = JSON.stringify<Player>(player);
89
- const parsed = JSON.parse<Player>(serialized);
92
+ const deserialized = JSON.parse<Player>(serialized);
90
93
 
91
- console.log("Serialized: " + serialized);
92
- console.log("Parsed: " + JSON.stringify(parsed));
94
+ console.log("Serialized " + serialized);
95
+ console.log("Deserialized " + JSON.stringify(deserialized));
93
96
  ```
94
97
 
95
98
  ## Examples
96
99
 
97
- Classes can even have inheritance. Here's a nasty example
100
+ ## Performance
98
101
 
99
- ```js
100
- @json
101
- class Base {}
102
+ 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
103
 
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
- }
104
+ ### Raw Performance
115
105
 
116
- const arr: Base[] = [
117
- new Vec1(),
118
- new Vec2(),
119
- new Vec3()
120
- ];
106
+ Simple
121
107
 
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
- ```
108
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
109
+ |--------------------|-----------------------|-------------------------|----------------------|------------------------|
110
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
111
+ | Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
112
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
113
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
114
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
126
115
 
127
- You can also add it to your `asconfig.json`
116
+ SIMD
128
117
 
129
- ```json
130
- {
131
- // ...
132
- "options": {
133
- "transform": ["json-as/transform"]
134
- }
135
- }
136
- ```
118
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
119
+ |--------------------|-----------------------|-------------------------|----------------------|------------------------|
120
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
121
+ | Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
122
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
123
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
124
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
125
+
126
+ JavaScript
127
+
128
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
129
+ |--------------------|-----------------------|-------------------------|----------------------|------------------------|
130
+ | Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
131
+ | Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
132
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
133
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
134
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
135
+
136
+ ### Real-World Usage
137
+
138
+ | Scenario | JSON Size (kb) | Serialization Time (ops/s) | Deserialization Time (ops/s) | Throughput (GB/s) |
139
+ |--------------------|----------------|----------------------------|------------------------------|-------------------|
140
+ | Web API Response | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
141
+ | Database Entry | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
142
+ | File Parsing | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
137
143
 
138
- If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
139
144
 
140
145
  ## 📃 License
141
146
 
@@ -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,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
+ });
@@ -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
  }
@@ -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;
@@ -5,7 +5,7 @@ import { deserializeBooleanArray } from "./array/bool";
5
5
  import { deserializeFloatArray } from "./array/float";
6
6
  import { deserializeIntegerArray } from "./array/integer";
7
7
  import { deserializeMapArray } from "./array/map";
8
- import { deserializeObjectArray } from "./array/object";
8
+ import { deserializeStructArray } from "./array/struct";
9
9
  import { deserializeStringArray } from "./array/string";
10
10
 
11
11
  // @ts-ignore: Decorator valid here
@@ -28,21 +28,16 @@ export function deserializeArray<T extends unknown[]>(srcStart: usize, srcEnd: u
28
28
  const type = changetype<nonnull<valueof<T>>>(0);
29
29
  if (type instanceof JSON.Value) {
30
30
  // @ts-ignore: type
31
- return deserializeArbitraryArray<T>(srcStart, srcEnd, dst);
31
+ return deserializeArbitraryArray(srcStart, srcEnd, dst);
32
32
  } else if (type instanceof Map) {
33
33
  // @ts-ignore: type
34
34
  return deserializeMapArray<T>(srcStart, srcEnd, dst);
35
35
  // @ts-ignore: defined by transform
36
36
  } else if (isDefined(type.__DESERIALIZE)) {
37
- return deserializeObjectArray<T>(srcStart, srcEnd, dst);
37
+ return deserializeStructArray<T>(srcStart, srcEnd, dst);
38
38
  }
39
39
  throw new Error("Could not parse array of type " + nameof<T>() + "!");
40
40
  } else {
41
41
  throw new Error("Could not parse array of type " + nameof<T>() + "!");
42
42
  }
43
- }
44
-
45
- function isMap<T>(): boolean {
46
- let type: T = changetype<T>(0);
47
- return type instanceof Map;
48
- }
43
+ }
@@ -1,5 +1,6 @@
1
1
  import { atoi } from "../../util/atoi";
2
2
 
3
- export function deserializeInteger<T>(srcStart: usize, srcEnd: usize): T {
3
+ // @ts-ignore: inline
4
+ @inline export function deserializeInteger<T>(srcStart: usize, srcEnd: usize): T {
4
5
  return atoi<T>(srcStart, srcEnd);
5
6
  }
@@ -76,7 +76,7 @@ export function deserializeMap<T extends Map<any, any>>(srcStart: usize, srcEnd:
76
76
  srcStart += 2;
77
77
  while (srcStart < srcEnd) {
78
78
  const code = load<u16>(srcStart);
79
- if (((code ^ BRACE_RIGHT) | (code ^ BRACKET_RIGHT)) == 32) {
79
+ if (code == BRACKET_RIGHT) {
80
80
  if (--depth == 0) {
81
81
  // @ts-ignore: type
82
82
  out.set(key, JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
@@ -2,9 +2,10 @@ import { JSON } from "../..";
2
2
  import { BACK_SLASH, COMMA, CHAR_F, BRACE_LEFT, BRACKET_LEFT, CHAR_N, QUOTE, BRACE_RIGHT, BRACKET_RIGHT, CHAR_T } from "../../custom/chars";
3
3
  import { isSpace } from "../../util";
4
4
  import { ptrToStr } from "../../util/ptrToStr";
5
+ import { deserializeArbitrary } from "./arbitrary";
5
6
 
6
- export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize): T {
7
- const out = changetype<nonnull<T>>(dst || __new(offsetof<T>(), idof<T>()));
7
+ export function deserializeObject(srcStart: usize, srcEnd: usize, dst: usize): JSON.Obj {
8
+ const out = new JSON.Obj();
8
9
 
9
10
  let keyStart: usize = 0;
10
11
  let keyEnd: usize = 0;
@@ -22,7 +23,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
22
23
  if (isKey) {
23
24
  keyStart = lastIndex;
24
25
  keyEnd = srcStart;
25
- // console.log("Key: " + ptrToStr(lastIndex, srcStart));
26
+ // console.log("Key: " + ptrToStr(keyStart, keyEnd));
26
27
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart + 2)));
27
28
  srcStart += 2;
28
29
  // while (isSpace((code = load<u16>((srcStart += 2))))) {
@@ -46,8 +47,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
46
47
  const code = load<u16>(srcStart);
47
48
  if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
48
49
  // console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
49
- // @ts-ignore: exists
50
- out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart + 2, dst);
50
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart + 2, dst));
51
51
  // while (isSpace(load<u16>(srcStart))) srcStart += 2;
52
52
  srcStart += 4;
53
53
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
@@ -63,8 +63,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
63
63
  const code = load<u16>(srcStart);
64
64
  if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
65
65
  // console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
66
- // @ts-ignore: exists
67
- out.__DESERIALIZE(keyStart, keyEnd, lastIndex, srcStart, dst);
66
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart, dst));
68
67
  // while (isSpace(load<u16>((srcStart += 2)))) {
69
68
  // /* empty */
70
69
  // }
@@ -84,8 +83,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
84
83
  if (code == BRACE_RIGHT) {
85
84
  if (--depth == 0) {
86
85
  // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
87
- // @ts-ignore: exists
88
- out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), dst);
86
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
89
87
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
90
88
  keyStart = 0;
91
89
  // while (isSpace(load<u16>(srcStart))) {
@@ -105,8 +103,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
105
103
  if (code == BRACKET_RIGHT) {
106
104
  if (--depth == 0) {
107
105
  // console.log("Value (array): " + ptrToStr(lastIndex, srcStart + 2));
108
- // @ts-ignore: exists
109
- out.__DESERIALIZE(keyStart, keyEnd, lastIndex, (srcStart += 2), dst);
106
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 2, dst));
110
107
  // console.log("Next: " + String.fromCharCode(load<u16>(srcStart)));
111
108
  keyStart = 0;
112
109
  // while (isSpace(load<u16>((srcStart += 2)))) {
@@ -120,8 +117,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
120
117
  } else if (code == CHAR_T) {
121
118
  if (load<u64>(srcStart) == 28429475166421108) {
122
119
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 8));
123
- // @ts-ignore: exists
124
- out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), dst);
120
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
125
121
  // while (isSpace(load<u16>((srcStart += 2)))) {
126
122
  // /* empty */
127
123
  // }
@@ -132,8 +128,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
132
128
  } else if (code == CHAR_F) {
133
129
  if (load<u64>(srcStart, 2) == 28429466576093281) {
134
130
  // console.log("Value (bool): " + ptrToStr(srcStart, srcStart + 10));
135
- // @ts-ignore: exists
136
- out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 10), dst);
131
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 10, dst));
137
132
  // while (isSpace(load<u16>((srcStart += 2)))) {
138
133
  // /* empty */
139
134
  // }
@@ -144,8 +139,7 @@ export function deserializeObject<T>(srcStart: usize, srcEnd: usize, dst: usize)
144
139
  } else if (code == CHAR_N) {
145
140
  if (load<u64>(srcStart) == 30399761348886638) {
146
141
  // console.log("Value (null): " + ptrToStr(srcStart, srcStart + 8));
147
- // @ts-ignore: exists
148
- out.__DESERIALIZE(keyStart, keyEnd, srcStart, (srcStart += 8), dst);
142
+ out.set(ptrToStr(keyStart, keyEnd), deserializeArbitrary(lastIndex, srcStart += 8, dst));
149
143
  // while (isSpace(load<u16>((srcStart += 2)))) {
150
144
  /* empty */
151
145
  // }