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.
Files changed (110) hide show
  1. package/.github/workflows/nodejs.yml +0 -3
  2. package/.prettierrc.json +4 -1
  3. package/CHANGELOG +13 -0
  4. package/LICENSE +1 -1
  5. package/README.md +22 -7
  6. package/as-test.config.json +1 -1
  7. package/asconfig.json +2 -2
  8. package/assembly/__benches__/misc.bench.ts +17 -31
  9. package/assembly/__tests__/bool.spec.ts +1 -1
  10. package/assembly/__tests__/simd/string.spec.ts +32 -0
  11. package/assembly/__tests__/types.ts +17 -0
  12. package/assembly/custom/chars.ts +2 -2
  13. package/assembly/custom/memory.ts +25 -0
  14. package/assembly/custom/types.ts +1 -0
  15. package/assembly/custom/util.ts +59 -140
  16. package/assembly/deserialize/simd/string.ts +103 -0
  17. package/assembly/deserialize/simple/arbitrary.ts +17 -0
  18. package/assembly/deserialize/simple/array/arbitrary.ts +113 -0
  19. package/assembly/deserialize/simple/array/array.ts +18 -0
  20. package/assembly/deserialize/simple/array/bool.ts +17 -0
  21. package/assembly/deserialize/simple/array/float.ts +28 -0
  22. package/assembly/deserialize/simple/array/integer.ts +27 -0
  23. package/assembly/deserialize/simple/array/map.ts +18 -0
  24. package/assembly/deserialize/simple/array/object.ts +18 -0
  25. package/assembly/deserialize/simple/array/string.ts +22 -0
  26. package/assembly/deserialize/simple/array.ts +48 -0
  27. package/assembly/deserialize/simple/bool.ts +9 -0
  28. package/assembly/deserialize/simple/date.ts +11 -0
  29. package/assembly/deserialize/simple/float.ts +10 -0
  30. package/assembly/deserialize/simple/integer.ts +5 -0
  31. package/assembly/deserialize/simple/map.ts +154 -0
  32. package/assembly/deserialize/simple/object.ts +159 -0
  33. package/assembly/deserialize/simple/string.ts +48 -0
  34. package/assembly/globals/tables.ts +417 -0
  35. package/assembly/index.d.ts +9 -13
  36. package/assembly/index.ts +282 -158
  37. package/assembly/serialize/simd/string.ts +176 -0
  38. package/assembly/serialize/simple/arbitrary.ts +36 -0
  39. package/assembly/serialize/simple/array.ts +32 -0
  40. package/assembly/serialize/simple/bool.ts +19 -0
  41. package/assembly/serialize/simple/date.ts +13 -0
  42. package/assembly/serialize/simple/float.ts +7 -0
  43. package/assembly/serialize/simple/integer.ts +7 -0
  44. package/assembly/serialize/simple/map.ts +43 -0
  45. package/assembly/serialize/simple/object.ts +7 -0
  46. package/assembly/serialize/simple/string.ts +48 -0
  47. package/assembly/test.ts +43 -28
  48. package/assembly/tsconfig.json +2 -91
  49. package/assembly/types.ts +0 -0
  50. package/assembly/util/atoi.ts +35 -0
  51. package/assembly/util/bytes.ts +12 -0
  52. package/assembly/util/concat.ts +9 -0
  53. package/assembly/util/getArrayDepth.ts +17 -0
  54. package/assembly/util/index.ts +5 -0
  55. package/assembly/util/isSpace.ts +4 -0
  56. package/assembly/util/nextPowerOf2.ts +4 -0
  57. package/assembly/util/ptrToStr.ts +7 -0
  58. package/assembly/util/snp.ts +69 -0
  59. package/bench.js +5 -5
  60. package/modules/bs/index.ts +167 -0
  61. package/modules/tsconfig.json +8 -0
  62. package/package.json +42 -47
  63. package/transform/lib/builder.js +1353 -0
  64. package/transform/lib/builder.js.map +1 -0
  65. package/transform/lib/index.js +497 -395
  66. package/transform/lib/index.js.map +1 -1
  67. package/transform/lib/index.old.js +404 -0
  68. package/transform/lib/index.old.js.map +1 -0
  69. package/transform/lib/linker.js +18 -0
  70. package/transform/lib/linker.js.map +1 -0
  71. package/transform/lib/types.js +25 -0
  72. package/transform/lib/types.js.map +1 -0
  73. package/transform/lib/util.js +47 -0
  74. package/transform/lib/util.js.map +1 -0
  75. package/transform/lib/visitor.js +529 -446
  76. package/transform/lib/visitor.js.map +1 -0
  77. package/transform/package.json +1 -34
  78. package/transform/src/builder.ts +1371 -0
  79. package/transform/src/index.ts +571 -481
  80. package/transform/src/linker.ts +21 -0
  81. package/transform/src/types.ts +27 -0
  82. package/transform/src/util.ts +56 -0
  83. package/transform/src/visitor.ts +531 -0
  84. package/transform/tsconfig.json +3 -1
  85. package/assembly/__benches__/as-tral.d.ts +0 -1
  86. package/assembly/custom/bs.ts +0 -211
  87. package/assembly/deserialize/array/array.ts +0 -31
  88. package/assembly/deserialize/array/bool.ts +0 -19
  89. package/assembly/deserialize/array/float.ts +0 -24
  90. package/assembly/deserialize/array/integer.ts +0 -24
  91. package/assembly/deserialize/array/map.ts +0 -27
  92. package/assembly/deserialize/array/object.ts +0 -27
  93. package/assembly/deserialize/array/string.ts +0 -29
  94. package/assembly/deserialize/array.ts +0 -46
  95. package/assembly/deserialize/bool.ts +0 -34
  96. package/assembly/deserialize/date.ts +0 -19
  97. package/assembly/deserialize/float.ts +0 -21
  98. package/assembly/deserialize/integer.ts +0 -16
  99. package/assembly/deserialize/map.ts +0 -189
  100. package/assembly/deserialize/object.ts +0 -271
  101. package/assembly/deserialize/string.ts +0 -164
  102. package/assembly/serialize/array.ts +0 -51
  103. package/assembly/serialize/bool.ts +0 -10
  104. package/assembly/serialize/date.ts +0 -4
  105. package/assembly/serialize/float.ts +0 -4
  106. package/assembly/serialize/integer.ts +0 -5
  107. package/assembly/serialize/map.ts +0 -24
  108. package/assembly/serialize/object.ts +0 -13
  109. package/assembly/serialize/string.ts +0 -287
  110. package/logs/test.log.json +0 -1049
@@ -19,8 +19,5 @@ jobs:
19
19
  - name: Install Dependencies
20
20
  run: bun install
21
21
 
22
- - name: Build Tests
23
- run: bun run pretest
24
-
25
22
  - name: Run Tests
26
23
  run: bun run test
package/.prettierrc.json CHANGED
@@ -1,4 +1,7 @@
1
1
  {
2
+ "pluginSearchDirs": ["node_modules"],
3
+ "plugins": ["assemblyscript-prettier"],
2
4
  "singleQuote": false,
3
- "printWidth": 65536
5
+ "printWidth": 65536,
6
+ "tabWidth": 2
4
7
  }
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) 2023 Jairus Tanaka <jairus.v.tanaka@outlook.com>
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 - v0.9.28
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 visitor-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/transform
22
+ --transform json-as
23
23
  ```
24
24
 
25
25
  Alternatively, add it to your `asconfig.json`
26
26
 
27
- ```json
27
+ ```
28
28
  {
29
29
  // ...
30
30
  "options": {
31
- "transform": ["json-as/transform"]
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/assembly";
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("this.age < 18")
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)
@@ -6,7 +6,7 @@
6
6
  "coverage": false
7
7
  },
8
8
  "buildOptions": {
9
- "args": ["--transform ./transform"],
9
+ "args": ["--enable simd", "--runtime stub"],
10
10
  "target": "wasi"
11
11
  },
12
12
  "runOptions": {
package/asconfig.json CHANGED
@@ -29,8 +29,8 @@
29
29
  }
30
30
  },
31
31
  "options": {
32
- "transform": ["./transform", "as-test/transform"],
33
- "disableWarning": [226]
32
+ "transform": [],
33
+ "disableWarning": []
34
34
  },
35
35
  "extends": "./node_modules/@assemblyscript/wasi-shim/asconfig.json"
36
36
  }
@@ -1,33 +1,19 @@
1
- import { JSON } from "..";
2
- import { BRACE_LEFT, BRACKET_LEFT, CHAR_F, CHAR_T, QUOTE } from "../custom/chars";
3
-
4
- bench("Match Type (string)", () => {
5
- blackbox<boolean>(matchType(blackbox<string>("\""), JSON.Types.String));
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
- bench("Match Type (bool)", () => {
9
- blackbox<boolean>(matchType(blackbox<string>("t"), JSON.Types.Bool));
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
- }
@@ -1,4 +1,4 @@
1
- import { JSON } from "json-as";
1
+ import { JSON } from "../";
2
2
  import { describe, expect, run } from "as-test/assembly";
3
3
 
4
4
  describe("Should serialize booleans", () => {
@@ -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
  }
@@ -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
+ }
@@ -1,3 +1,4 @@
1
+
1
2
  @json
2
3
  export class Vec3 {
3
4
  x: f64 = 1.0;