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

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 (79) 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 +37 -0
  5. package/CHANGELOG +60 -0
  6. package/README.md +303 -48
  7. package/assembly/__benches__/misc.bench.ts +47 -0
  8. package/assembly/__benches__/schemas.ts +25 -0
  9. package/assembly/__benches__/string.bench.ts +23 -0
  10. package/assembly/__benches__/struct.bench.ts +21 -0
  11. package/assembly/__tests__/arbitrary.spec.ts +19 -0
  12. package/assembly/__tests__/array.spec.ts +42 -1
  13. package/assembly/__tests__/bool.spec.ts +1 -1
  14. package/assembly/__tests__/box.spec.ts +1 -1
  15. package/assembly/__tests__/custom.spec.ts +42 -0
  16. package/assembly/__tests__/date.spec.ts +1 -1
  17. package/assembly/__tests__/float.spec.ts +4 -4
  18. package/assembly/__tests__/integer.spec.ts +1 -1
  19. package/assembly/__tests__/null.spec.ts +1 -1
  20. package/assembly/__tests__/raw.spec.ts +23 -0
  21. package/assembly/__tests__/string.spec.ts +1 -1
  22. package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
  23. package/assembly/__tests__/test.spec.ts +1 -1
  24. package/assembly/__tests__/types.ts +3 -3
  25. package/assembly/as-bs.d.ts +53 -0
  26. package/assembly/custom/bench.ts +26 -0
  27. package/assembly/deserialize/simd/string.ts +1 -1
  28. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  29. package/assembly/deserialize/simple/array/arbitrary.ts +46 -24
  30. package/assembly/deserialize/simple/array/array.ts +4 -3
  31. package/assembly/deserialize/simple/array/bool.ts +7 -7
  32. package/assembly/deserialize/simple/array/float.ts +1 -1
  33. package/assembly/deserialize/simple/array/integer.ts +1 -1
  34. package/assembly/deserialize/simple/array/map.ts +1 -1
  35. package/assembly/deserialize/simple/array/string.ts +3 -3
  36. package/assembly/deserialize/simple/array/struct.ts +29 -0
  37. package/assembly/deserialize/simple/array.ts +7 -9
  38. package/assembly/deserialize/simple/integer.ts +2 -1
  39. package/assembly/deserialize/simple/map.ts +92 -67
  40. package/assembly/deserialize/simple/object.ts +14 -19
  41. package/assembly/deserialize/simple/raw.ts +6 -0
  42. package/assembly/deserialize/simple/struct.ts +171 -0
  43. package/assembly/index.d.ts +15 -1
  44. package/assembly/index.ts +202 -25
  45. package/assembly/serialize/simd/string.ts +0 -1
  46. package/assembly/serialize/simple/arbitrary.ts +15 -2
  47. package/assembly/serialize/simple/array.ts +0 -1
  48. package/assembly/serialize/simple/bool.ts +0 -2
  49. package/assembly/serialize/simple/date.ts +0 -1
  50. package/assembly/serialize/simple/float.ts +0 -1
  51. package/assembly/serialize/simple/integer.ts +0 -1
  52. package/assembly/serialize/simple/map.ts +0 -1
  53. package/assembly/serialize/simple/object.ts +42 -6
  54. package/assembly/serialize/simple/raw.ts +14 -0
  55. package/assembly/serialize/simple/string.ts +0 -1
  56. package/assembly/serialize/simple/struct.ts +7 -0
  57. package/assembly/test.ts +80 -13
  58. package/assembly/util/atoi.ts +1 -1
  59. package/bench/bench.ts +15 -0
  60. package/bench/schemas.ts +5 -0
  61. package/bench/string.bench.ts +16 -0
  62. package/bench.js +11 -2
  63. package/index.ts +1 -1
  64. package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +3 -3
  65. package/lib/tsconfig.json +8 -0
  66. package/package.json +10 -6
  67. package/run-tests.sh +1 -1
  68. package/transform/lib/index.js +124 -55
  69. package/transform/lib/index.js.map +1 -1
  70. package/transform/src/index.ts +141 -62
  71. package/.gitmodules +0 -0
  72. package/as-test.config.json +0 -18
  73. package/assembly/deserialize/simple/array/object.ts +0 -18
  74. package/modules/as-bs/LICENSE +0 -21
  75. package/modules/as-bs/README.md +0 -95
  76. package/modules/as-bs/assembly/tsconfig.json +0 -97
  77. package/modules/as-bs/index.ts +0 -1
  78. package/modules/as-bs/package.json +0 -32
  79. /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
@@ -0,0 +1,19 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
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
+ });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize integer arrays", () => {
5
5
  expect(JSON.stringify<u32[]>([0, 100, 101])).toBe("[0,100,101]");
@@ -58,6 +58,47 @@ describe("Should serialize object arrays", () => {
58
58
  ).toBe('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]');
59
59
  });
60
60
 
61
+ describe("Should deserialize integer arrays", () => {
62
+ expect(JSON.stringify(JSON.parse<u32[]>("[0,100,101]"))).toBe('[0,100,101]');
63
+ expect(JSON.stringify(JSON.parse<u64[]>("[0,100,101]"))).toBe('[0,100,101]');
64
+ expect(JSON.stringify(JSON.parse<i32[]>("[0,100,101,-100,-101]"))).toBe("[0,100,101,-100,-101]");
65
+ expect(JSON.stringify(JSON.parse<i64[]>("[0,100,101,-100,-101]"))).toBe("[0,100,101,-100,-101]");
66
+ });
67
+
68
+ describe("Should deserialize float arrays", () => {
69
+ expect(JSON.stringify(JSON.parse<f64[]>("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]"))).toBe("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]");
70
+ expect(JSON.stringify(JSON.parse<f64[]>("[1e+21,1e+22,1e-7,1e-8,1e-9]"))).toBe("[1e+21,1e+22,1e-7,1e-8,1e-9]");
71
+ });
72
+
73
+ describe("Should deserialize boolean arrays", () => {
74
+ expect(JSON.stringify(JSON.parse<bool[]>("[true,false]"))).toBe("[true,false]");
75
+ expect(JSON.stringify(JSON.parse<boolean[]>("[true,false]"))).toBe("[true,false]");
76
+ });
77
+
78
+ describe("Should deserialize string arrays", () => {
79
+ expect(JSON.stringify(JSON.parse<string[]>("[\"string \\\"with random spa\\nces and \\nnewlines\\n\\n\\n\"]"))).toBe("[\"string \\\"with random spa\\nces and \\nnewlines\\n\\n\\n\"]");
80
+ });
81
+
82
+ describe("Should deserialize nested integer arrays", () => {
83
+ expect(JSON.stringify(JSON.parse<i64[][]>("[[100,101],[-100,-101],[0]]"))).toBe("[[100,101],[-100,-101],[0]]");
84
+ });
85
+
86
+ describe("Should deserialize nested float arrays", () => {
87
+ expect(JSON.stringify(JSON.parse<f64[][]>("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]"))).toBe("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]");
88
+ });
89
+
90
+ describe("Should deserialize nested boolean arrays", () => {
91
+ expect(JSON.stringify(JSON.parse<bool[][]>("[[true],[false]]"))).toBe("[[true],[false]]");
92
+ expect(JSON.stringify(JSON.parse<boolean[][]>("[[true],[false]]"))).toBe("[[true],[false]]");
93
+ });
94
+
95
+ describe("Should deserialize object arrays", () => {
96
+ expect(
97
+ JSON.stringify(JSON.parse<Vec3[]>(
98
+ '[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]'
99
+ )
100
+ )).toBe('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]');
101
+ });
61
102
 
62
103
  @json
63
104
  class Vec3 {
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize booleans", () => {
5
5
  expect(JSON.stringify<bool>(true)).toBe("true");
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize JSON.Box<T>", () => {
5
5
  expect(JSON.stringify<JSON.Box<i32> | null>(null))
@@ -0,0 +1,42 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
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
+ });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize Date", () => {
5
5
  expect(JSON.stringify<Date>(new Date(0)))
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize floats", () => {
5
5
  expect(JSON.stringify<f64>(7.23)).toBe("7.23");
@@ -34,9 +34,9 @@ describe("Should deserialize floats", () => {
34
34
 
35
35
  expect(JSON.parse<f64>("0.000001").toString()).toBe("0.000001");
36
36
 
37
- // expect(JSON.parse<f64>("1e-7")).toBe(1e-7);
37
+ expect(JSON.parse<f64>("1e-7").toString()).toBe(1e-7.toString());
38
38
 
39
- // expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20);
39
+ expect(JSON.parse<f64>("100000000000000000000.0").toString()).toBe(1e20.toString());
40
40
 
41
- // expect(JSON.parse<f64>("1e+21")).toBe(1e21);
41
+ expect(JSON.parse<f64>("1e+21").toString()).toBe(1e21.toString());
42
42
  });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize integers", () => {
5
5
  expect(JSON.stringify(0)).toBe("0");
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize null", () => {
5
5
  expect(JSON.stringify(null)).toBe("null");
@@ -0,0 +1,23 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
3
+
4
+ describe("Should serialize JSON.Raw", () => {
5
+ expect(JSON.stringify<JSON.Raw>(JSON.Raw.from('{"x":1.0,"y":2.0,"z":3.0}'))).toBe('{"x":1.0,"y":2.0,"z":3.0}');
6
+ });
7
+
8
+ describe("Should deserialize JSON.Raw", () => {
9
+ expect(JSON.parse<JSON.Raw>('{"x":1.0,"y":2.0,"z":3.0}').toString()).toBe('{"x":1.0,"y":2.0,"z":3.0}');
10
+ });
11
+
12
+ describe("Should serialize Map<string, JSON.Raw>", () => {
13
+ const m1 = new Map<string, JSON.Raw>();
14
+ m1.set("hello", new JSON.Raw("\"world\""));
15
+ m1.set("pos", new JSON.Raw("{\"x\":1.0,\"y\":2.0,\"z\":3.0}"));
16
+
17
+ expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
18
+ });
19
+
20
+ describe("Should deserialize Map<string, JSON.Raw>", () => {
21
+ const m1 = JSON.parse<Map<string, JSON.Raw>>('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
22
+ expect(JSON.stringify(m1)).toBe('{"hello":"world","pos":{"x":1.0,"y":2.0,"z":3.0}}');
23
+ });
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
4
  describe("Should serialize strings", () => {
5
5
  expect(JSON.stringify("abcdefg")).toBe('"abcdefg"');
@@ -1,7 +1,7 @@
1
1
  import { JSON } from "..";
2
- import { describe, expect } from "../../modules/test/assembly";
2
+ import { describe, expect } from "./lib";
3
3
 
4
- describe("Should serialize objects", () => {
4
+ describe("Should serialize structs", () => {
5
5
  expect(
6
6
  JSON.stringify<Vec3>({
7
7
  x: 3.4,
@@ -38,7 +38,7 @@ describe("Should serialize objects", () => {
38
38
  expect(JSON.stringify<ObjWithStrangeKey<string>>({ data: "foo" })).toBe('{"a\\\\\\t\\"\\u0002b`c":"foo"}');
39
39
  });
40
40
 
41
- describe("Should serialize objects with inheritance", () => {
41
+ describe("Should serialize structs with inheritance", () => {
42
42
  const obj = new DerivedObject("1", "2");
43
43
 
44
44
  expect(JSON.stringify(obj)).toBe('{"a":"1","b":"2"}');
@@ -52,6 +52,21 @@ describe("Should ignore properties decorated with @omit", () => {
52
52
  ).toBe('{"y":1,"x":1,"z":1}');
53
53
  });
54
54
 
55
+ describe("Should deserialize structs", () => {
56
+ expect(
57
+ JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}')),
58
+ ).toBe('{"x":3.4,"y":1.2,"z":8.3}');
59
+ });
60
+
61
+ describe("Should deserialize structs with whitespace", () => {
62
+ expect(
63
+ JSON.stringify(JSON.parse<Vec3>(' { "x" : 3.4 , "y" : 1.2 , "z" : 8.3 } ')),
64
+ ).toBe('{"x":3.4,"y":1.2,"z":8.3}');
65
+ });
66
+
67
+ // describe("Should serialize Suite struct", () => {
68
+
69
+ // });
55
70
 
56
71
  @json
57
72
  class BaseObject {
@@ -99,7 +114,6 @@ class ObjWithString {
99
114
 
100
115
  @json
101
116
  class ObjWithStrangeKey<T> {
102
-
103
117
  @alias('a\\\t"\x02b`c')
104
118
  data!: T;
105
119
  }
@@ -1,5 +1,5 @@
1
1
  import { JSON } from "../";
2
- import { describe, expect } from "../../modules/test/assembly/index";
2
+ import { describe, expect } from "./lib";
3
3
  import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
4
4
 
5
5
  // describe("Should serialize objects", () => {
@@ -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,53 @@
1
+ /**
2
+ * Central buffer namespace for managing memory operations.
3
+ */
4
+ declare namespace bs {
5
+ /** Current buffer pointer. */
6
+ export let buffer: ArrayBuffer;
7
+
8
+ /** Current offset within the buffer. */
9
+ export let offset: usize;
10
+
11
+ /** Proposed size of output. */
12
+ export let stackSize: usize;
13
+
14
+ /**
15
+ * Ensures the buffer size is at least the proposed size.
16
+ * If necessary, reallocates the buffer to the exact new size.
17
+ * @param size - The size to propose.
18
+ */
19
+ export function ensureSize(size: u32): void;
20
+
21
+ /**
22
+ * Proposes that the buffer size should be at least the given size.
23
+ * If necessary, reallocates the buffer to the exact new size.
24
+ * @param size - The size to propose.
25
+ */
26
+ export function proposeSize(size: u32): void;
27
+
28
+ /**
29
+ * Increases the proposed size by nextPowerOf2(n + 64) if necessary.
30
+ * If necessary, reallocates the buffer to the exact new size.
31
+ * @param size - The size to grow by.
32
+ */
33
+ export function growSize(size: u32): void;
34
+
35
+ /**
36
+ * Resizes the buffer to the specified size.
37
+ * @param newSize - The new buffer size.
38
+ */
39
+ export function resize(newSize: u32): void;
40
+
41
+ /**
42
+ * Copies the buffer's content to a new object of a specified type.
43
+ * @returns The new object containing the buffer's content.
44
+ */
45
+ export function out<T>(): T;
46
+
47
+ /**
48
+ * Copies the buffer's content to a given destination pointer.
49
+ * @param dst - The destination pointer.
50
+ * @returns The destination pointer cast to the specified type.
51
+ */
52
+ export function outTo<T>(dst: usize): T;
53
+ }
@@ -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);
@@ -2,44 +2,64 @@ import { BACK_SLASH, BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT, CHAR_
2
2
  import { JSON } from "../../../";
3
3
  import { isSpace } from "util/string";
4
4
 
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>();
5
+ export function deserializeArbitraryArray(srcStart: usize, srcEnd: usize, dst: usize): JSON.Value[] {
6
+ const out = changetype<JSON.Value[]>(dst || changetype<usize>(instantiate<JSON.Value[]>()));
7
7
  let lastIndex: usize = 0;
8
8
  let depth: u32 = 0;
9
+ // if (load<u16>(srcStart) != BRACKET_LEFT)
10
+ srcStart += 2;
9
11
  while (srcStart < srcEnd) {
10
12
  const code = load<u16>(srcStart);
11
- if (code == QUOTE) {
13
+ // console.log("code: " + String.fromCharCode(code));
14
+ if (code == BRACE_LEFT) {
12
15
  lastIndex = srcStart;
16
+ depth++;
13
17
  srcStart += 2;
14
18
  while (srcStart < srcEnd) {
15
19
  const code = load<u16>(srcStart);
16
- if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
17
- while (isSpace(load<u16>((srcStart += 2)))) {
18
- /* empty */
20
+ if (code == BRACE_RIGHT) {
21
+ if (--depth == 0) {
22
+ // @ts-ignore: type
23
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
24
+ // console.log("Value (object): " + ptrToStr(lastIndex, srcStart + 2));
25
+ break;
19
26
  }
20
- // console.log("Value (string): " + ptrToStr(lastIndex, srcStart));
27
+ } else if (code == BRACE_LEFT) depth++;
28
+ srcStart += 2;
29
+ }
30
+ } else if (code == QUOTE) {
31
+ lastIndex = srcStart;
32
+ srcStart += 2;
33
+ while (srcStart < srcEnd) {
34
+ const code = load<u16>(srcStart);
35
+ if (code == QUOTE && load<u16>(srcStart - 2) !== BACK_SLASH) {
36
+ // while (isSpace(load<u16>((srcStart += 2)))) {
37
+ // /* empty */
38
+ // }
39
+ // console.log("Value (string): " + ptrToStr(lastIndex, srcStart + 2));
21
40
  // @ts-ignore: exists
22
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
41
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart + 2));
42
+ srcStart += 2;
23
43
  break;
24
44
  }
25
45
  srcStart += 2;
26
46
  }
47
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
27
48
  } else if (code - 48 <= 9 || code == 45) {
49
+ // console.log("trigger int")
28
50
  lastIndex = srcStart;
29
51
  srcStart += 2;
30
52
  while (srcStart < srcEnd) {
31
53
  const code = load<u16>(srcStart);
32
- if (code == COMMA || code == BRACE_RIGHT || isSpace(code)) {
54
+ if (code == COMMA || code == BRACKET_RIGHT || isSpace(code)) {
33
55
  // @ts-ignore: type
34
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
56
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
35
57
  // console.log("Value (number): " + ptrToStr(lastIndex, srcStart));
36
- while (isSpace(load<u16>((srcStart += 2)))) {
37
- /* empty */
38
- }
39
58
  break;
40
59
  }
41
60
  srcStart += 2;
42
61
  }
62
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
43
63
  } else if (code == BRACE_LEFT) {
44
64
  lastIndex = srcStart;
45
65
  depth++;
@@ -49,7 +69,7 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
49
69
  if (code == BRACE_RIGHT) {
50
70
  if (--depth == 0) {
51
71
  // @ts-ignore: type
52
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
72
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
53
73
  // console.log("Value (object): " + ptrToStr(lastIndex, srcStart));
54
74
  while (isSpace(load<u16>((srcStart += 2)))) {
55
75
  /* empty */
@@ -68,7 +88,7 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
68
88
  if (code == BRACKET_RIGHT) {
69
89
  if (--depth == 0) {
70
90
  // @ts-ignore: type
71
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
91
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, srcStart));
72
92
  // console.log("Value (array): " + ptrToStr(lastIndex, srcStart));
73
93
  while (isSpace(load<u16>((srcStart += 2)))) {
74
94
  /* empty */
@@ -81,25 +101,27 @@ export function deserializeArbitraryArray<T extends JSON.Value>(srcStart: usize,
81
101
  } else if (code == CHAR_T) {
82
102
  if (load<u64>(srcStart) == 28429475166421108) {
83
103
  // @ts-ignore: type
84
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
104
+ out.push(JSON.__deserialize<JSON.Value>(srcStart, (srcStart += 8)));
85
105
  // console.log("Value (bool): " + ptrToStr(srcStart - 8, srcStart));
86
- while (isSpace(load<u16>((srcStart += 2)))) {
87
- /* empty */
88
- }
106
+ // while (isSpace(load<u16>((srcStart += 2)))) {
107
+ // /* empty */
108
+ // }
109
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
89
110
  }
90
111
  } else if (code == CHAR_F) {
91
112
  if (load<u64>(srcStart, 2) == 28429466576093281) {
92
113
  // @ts-ignore: type
93
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 10)));
114
+ out.push(JSON.__deserialize<JSON.Value>(srcStart, (srcStart += 10)));
94
115
  // console.log("Value (bool): " + ptrToStr(srcStart - 10, srcStart));
95
- while (isSpace(load<u16>((srcStart += 2)))) {
96
- /* empty */
97
- }
116
+ // while (isSpace(load<u16>((srcStart += 2)))) {
117
+ // /* empty */
118
+ // }
119
+ // console.log("next: " + String.fromCharCode(load<u16>(srcStart)));
98
120
  }
99
121
  } else if (code == CHAR_N) {
100
122
  if (load<u64>(srcStart) == 30399761348886638) {
101
123
  // @ts-ignore: type
102
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, (srcStart += 8)));
124
+ out.push(JSON.__deserialize<JSON.Value>(lastIndex, (srcStart += 8)));
103
125
  // console.log("Value (null): " + ptrToStr(srcStart - 8, srcStart));
104
126
  while (isSpace(load<u16>((srcStart += 2)))) {
105
127
  /* empty */
@@ -2,15 +2,16 @@ import { BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../../";
3
3
 
4
4
  export function deserializeArrayArray<T extends unknown[][]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  let depth: u32 = 0;
8
- while (srcStart < srcEnd) {
8
+ srcStart += 2;
9
+ while (srcStart < srcEnd - 2) {
9
10
  const code = load<u16>(srcStart);
10
11
  if (code == BRACKET_LEFT && depth++ == 0) {
11
12
  lastIndex = srcStart;
12
13
  } else if (code == BRACKET_RIGHT && --depth == 0) {
13
- out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart));
14
+ out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart + 2));
14
15
  }
15
16
  srcStart += 2;
16
17
  }
@@ -1,17 +1,17 @@
1
- import { CHAR_E, CHAR_F, CHAR_T } from "../../../custom/chars";
2
-
3
1
  export function deserializeBooleanArray<T extends boolean[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
4
- const out = dst ? changetype<T>(dst) : instantiate<T>();
2
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
3
+ srcStart += 2; // skip [
5
4
  while (srcStart < srcEnd) {
6
- const code = load<u16>(srcStart);
7
- if (code == CHAR_T && load<u16>(srcStart, 8) == CHAR_E) {
5
+ const block = load<u64>(srcStart);
6
+ if (block == 28429475166421108) {
8
7
  out.push(true);
9
8
  srcStart += 10;
10
- } else if (code == CHAR_F && load<u16>(srcStart, 10) == CHAR_E) {
9
+ } else if (block == 32370086184550502 && load<u16>(srcStart, 8) == 101) {
11
10
  out.push(false);
12
11
  srcStart += 12;
12
+ } else {
13
+ srcStart += 2;
13
14
  }
14
- srcStart += 2;
15
15
  }
16
16
  return out;
17
17
  }
@@ -3,7 +3,7 @@ import { COMMA, BRACE_RIGHT, BRACKET_RIGHT } from "../../../custom/chars";
3
3
  import { JSON } from "../../..";
4
4
 
5
5
  export function deserializeFloatArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
6
- const out = dst ? changetype<T>(dst) : instantiate<T>();
6
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
7
7
  let lastIndex: usize = 0;
8
8
  while (srcStart < srcEnd) {
9
9
  const code = load<u16>(srcStart);
@@ -2,7 +2,7 @@ import { atoi, isSpace } from "../../../util";
2
2
  import { COMMA, BRACKET_RIGHT } from "../../../custom/chars";
3
3
 
4
4
  export function deserializeIntegerArray<T extends number[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out: T = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  while (srcStart < srcEnd) {
8
8
  const code = load<u16>(srcStart);
@@ -2,7 +2,7 @@ import { BRACE_LEFT, BRACE_RIGHT } from "../../../custom/chars";
2
2
  import { JSON } from "../../..";
3
3
 
4
4
  export function deserializeMapArray<T extends Map<any, any>[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
5
- const out = dst ? changetype<T>(dst) : instantiate<T>();
5
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
6
6
  let lastIndex: usize = 0;
7
7
  let depth: u32 = 0;
8
8
  while (srcStart < srcEnd) {
@@ -2,8 +2,8 @@ import { JSON } from "../../..";
2
2
  import { BACK_SLASH, QUOTE } from "../../../custom/chars";
3
3
 
4
4
  export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usize): string[] {
5
- const out = dst ? changetype<string[]>(dst) : new Array<string>();
6
- let lastPos = 2;
5
+ const out = changetype<string[]>(dst || changetype<usize>(instantiate<string[]>()));
6
+ let lastPos: usize = 2;
7
7
  let inString = false;
8
8
  while (srcStart < srcEnd) {
9
9
  const code = load<u16>(srcStart);
@@ -12,7 +12,7 @@ export function deserializeStringArray(srcStart: usize, srcEnd: usize, dst: usiz
12
12
  inString = true;
13
13
  lastPos = srcStart;
14
14
  } else if (load<u16>(srcStart - 2) != BACK_SLASH) {
15
- out.push(JSON.__deserialize<string>(lastPos, srcStart));
15
+ out.push(JSON.__deserialize<string>(lastPos, srcStart + 2));
16
16
  inString = false;
17
17
  }
18
18
  }
@@ -0,0 +1,29 @@
1
+ import { BRACE_LEFT, BRACE_RIGHT, BRACKET_LEFT, BRACKET_RIGHT } from "../../../custom/chars";
2
+ import { JSON } from "../../..";
3
+ import { isSpace } from "util/string";
4
+
5
+ export function deserializeStructArray<T extends unknown[]>(srcStart: usize, srcEnd: usize, dst: usize): T {
6
+ const out = changetype<nonnull<T>>(dst || changetype<usize>(instantiate<T>()));
7
+ let lastIndex: usize = 0;
8
+ let depth: u32 = 0;
9
+
10
+ while (srcStart < srcEnd && isSpace(load<u16>(srcStart))) srcStart += 2;
11
+ while (srcEnd > srcStart && isSpace(load<u16>(srcEnd - 2))) srcEnd -= 2;
12
+
13
+ if (srcStart - srcEnd == 0)
14
+ throw new Error("Input string had zero length or was all whitespace");
15
+
16
+ if (load<u16>(srcStart) != BRACKET_LEFT) throw new Error("Expected '[' at start of object at position " + (srcEnd - srcStart).toString());
17
+ if (load<u16>(srcEnd - 2) != BRACKET_RIGHT) throw new Error("Expected ']' at end of object at position " + (srcEnd - srcStart).toString());
18
+
19
+ while (srcStart < srcEnd) {
20
+ const code = load<u16>(srcStart);
21
+ if (code == BRACE_LEFT && depth++ == 0) {
22
+ lastIndex = srcStart;
23
+ } else if (code == BRACE_RIGHT && --depth == 0) {
24
+ out.push(JSON.__deserialize<valueof<T>>(lastIndex, srcStart += 2));
25
+ }
26
+ srcStart += 2;
27
+ }
28
+ return out;
29
+ }