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,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,37 @@
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
+ disabled:
21
+ - markdownlint
22
+ enabled:
23
+ - actionlint@1.7.7
24
+ - checkov@3.2.377
25
+ - git-diff-check
26
+ - prettier@3.5.2
27
+ - shellcheck@0.10.0
28
+ - shfmt@3.6.0
29
+ - trufflehog@3.88.13
30
+ - yamllint@1.35.1
31
+ actions:
32
+ disabled:
33
+ - trunk-announce
34
+ - trunk-check-pre-push
35
+ - trunk-fmt-pre-commit
36
+ enabled:
37
+ - trunk-upgrade-available
package/CHANGELOG CHANGED
@@ -1,5 +1,65 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-03-04 - 1.0.0-beta.10
4
+
5
+ - fix: transform not generating the right load operations for keys
6
+ - fix: whitespace not working in objects or struct deserialization
7
+ - fix: JSON.Raw not working when deserializing as Map<string, JSON.Raw>
8
+
9
+ ## 2025-03-03 - 1.0.0-beta.9
10
+
11
+ - rename: change libs folder to lib
12
+
13
+ ## 2025-03-03 - 1.0.0-beta.8
14
+
15
+ - docs: add instructions for using `--lib` in README
16
+
17
+ ## 2025-03-03 - 1.0.0-beta.7
18
+
19
+ - fix: add as-bs to `--lib` section
20
+ - chore: clean up transform
21
+ - refactor: transform should import `~lib/as-bs.ts` instead of relative path
22
+
23
+ ## 2025-03-01 - 1.0.0-beta.6
24
+
25
+ - fix: import from base directory index.ts
26
+
27
+ ## 2025-03-01 - 1.0.0-beta.5
28
+
29
+ - fix: revert pull request [#112](https://github.com/JairusSW/json-as/pull/112)
30
+
31
+ ## 2025-02-25 - 1.0.0-beta.4
32
+
33
+ - fix: warn on presence of invalid types contained in a schema [#112](https://github.com/JairusSW/json-as/pull/112)
34
+
35
+ ## 2025-02-25 - 1.0.0-beta.3
36
+
37
+ - feat: change `JSON.Raw` to actual class to facilitate proper support without transformations
38
+ - fix: remove old `JSON.Raw` logic from transform code
39
+
40
+ ## 2025-02-25 - 1.0.0-beta.2
41
+
42
+ - feat: add support for custom serializers and deserializers [#110](https://github.com/JairusSW/json-as/pull/110)
43
+
44
+ ## 2025-02-22 - 1.0.0-beta.1
45
+
46
+ - perf: add benchmarks for both AssemblyScript and JavaScript
47
+ - docs: publish preliminary benchmark results
48
+ - tests: ensure nested serialization works and add to tests
49
+ - feat: finish arbitrary type implementation
50
+ - feat: introduce `JSON.Obj` to handle objects effectively
51
+ - feat: reimplement arbitrary array deserialization
52
+ - fix: remove brace check on array deserialization
53
+ - feat: introduce native support for `JSON.Obj` transformations
54
+ - feat: implement arbitrary object serialization
55
+ - fix: deserialization of booleans panics on `false`
56
+ - fix: `bs.resize` should be type-safe
57
+ - impl: add `JSON.Obj` type as prototype to handle arbitrary object structures
58
+ - chore: rename static objects (schemas) to structs and name arbitrary objects as `obj`
59
+ - tests: add proper tests for arbitrary types
60
+ - fix: empty method generation using outdated function signature
61
+ - docs: update readme to be more concise
62
+
3
63
  ## 2025-02-13 - 1.0.0-alpha.4
4
64
 
5
65
  - feat: reintroduce support for `Box<T>`-wrapped primitive types
package/README.md CHANGED
@@ -6,47 +6,54 @@
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.0.0-alpha.4
9
+ AssemblyScript - v1.0.0-beta.10
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
+ ## 📝 About
21
14
 
22
- ## About
15
+ 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.
23
16
 
24
- ## Installation
17
+ ## 📚 Contents
18
+
19
+ - [Installation](#-installation)
20
+ - [Usage](#-usage)
21
+ - [Examples](#-examples)
22
+ - [Omitting Fields](#️-omitting-fields)
23
+ - [Nullable Primitives](#️-using-nullable-primitives)
24
+ - [Unknown or Dynamic Data](#-working-with-unknown-or-dynamic-data)
25
+ - [Using Raw JSON Strings](#️-using-raw-json-strings)
26
+ - [Custom Serializers](#️-using-custom-serializers-or-deserializers)
27
+ - [Performance](#-performance)
28
+ - [License](#-license)
29
+ - [Contact](#-contact)
30
+
31
+ ## 💾 Installation
25
32
 
26
33
  ```bash
27
- npm install json-as@1.0.0-alpha.3
34
+ npm install json-as@1.0.0-beta.10
28
35
  ```
29
36
 
30
37
  Add the `--transform` to your `asc` command (e.g. in package.json)
31
38
 
32
39
  ```bash
33
- --transform json-as
40
+ --transform json-as/transform --lib json-as/lib
34
41
  ```
35
42
 
36
43
  Alternatively, add it to your `asconfig.json`
37
44
 
38
- ```
45
+ ```json
39
46
  {
40
- // ...
41
47
  "options": {
42
- "transform": ["json-as/transform"]
48
+ "transform": ["json-as/transform"],
49
+ "lib": ["json-as/lib"]
43
50
  }
44
51
  }
45
52
  ```
46
53
 
47
54
  If you'd like to see the code that the transform generates, run with `JSON_DEBUG=true`
48
55
 
49
- ## Usage
56
+ ## 🪄 Usage
50
57
 
51
58
  ```js
52
59
  import { JSON } from "json-as";
@@ -75,7 +82,7 @@ class Player {
75
82
  const player: Player = {
76
83
  firstName: "Jairus",
77
84
  lastName: "Tanaka",
78
- lastActive: [2, 7, 2025],
85
+ lastActive: [2, 13, 2025],
79
86
  age: 18,
80
87
  pos: {
81
88
  x: 3.4,
@@ -86,56 +93,304 @@ const player: Player = {
86
93
  };
87
94
 
88
95
  const serialized = JSON.stringify<Player>(player);
89
- const parsed = JSON.parse<Player>(serialized);
96
+ const deserialized = JSON.parse<Player>(serialized);
90
97
 
91
- console.log("Serialized: " + serialized);
92
- console.log("Parsed: " + JSON.stringify(parsed));
98
+ console.log("Serialized " + serialized);
99
+ console.log("Deserialized " + JSON.stringify(deserialized));
93
100
  ```
94
101
 
95
- ## Examples
102
+ ## 🔍 Examples
103
+
104
+ ### 🏷️ Omitting Fields
105
+
106
+ This library allows selective omission of fields during serialization using the following decorators:
107
+
108
+ **@omit**
96
109
 
97
- Classes can even have inheritance. Here's a nasty example
110
+ This decorator excludes a field from serialization entirely.
98
111
 
99
112
  ```js
100
113
  @json
101
- class Base {}
114
+ class Example {
115
+ name!: string;
116
+ @omit
117
+ secret!: string;
118
+ }
119
+
120
+ const obj = new Example();
121
+ obj.name = "Visible";
122
+ obj.secret = "Hidden";
123
+
124
+ console.log(JSON.stringify(obj)); // { "name": "Visible" }
125
+ ```
102
126
 
127
+ **@omitnull**
128
+
129
+ This decorator omits a field only if its value is null.
130
+
131
+ ```js
103
132
  @json
104
- class Vec1 extends Base {
105
- x: f32 = 1.0;
133
+ class Example {
134
+ name!: string;
135
+ @omitnull()
136
+ optionalField!: string | null;
106
137
  }
138
+
139
+ const obj = new Example();
140
+ obj.name = "Present";
141
+ obj.optionalField = null;
142
+
143
+ console.log(JSON.stringify(obj)); // { "name": "Present" }
144
+
145
+ @omitif((self: this) => condition)
146
+
147
+ This decorator omits a field based on a custom predicate function.
148
+
107
149
  @json
108
- class Vec2 extends Vec1 {
109
- y: f32 = 2.0;
150
+ class Example {
151
+ name!: string;
152
+ @omitif((self: Example) => self.age < 18)
153
+ age!: number;
110
154
  }
155
+
156
+ const obj = new Example();
157
+ obj.name = "John";
158
+ obj.age = 16;
159
+
160
+ console.log(JSON.stringify(obj)); // { "name": "John" }
161
+ ```
162
+
163
+ If age were 18 or higher, it would be included in the serialization.
164
+
165
+ ### 🗳️ Using nullable primitives
166
+
167
+ AssemblyScript doesn't support using nullable primitive types, so instead, json-as offers the `JSON.Box` class to remedy it.
168
+
169
+ For example, this schema won't compile in AssemblyScript:
170
+
171
+ ```js
172
+ @json
173
+ class Person {
174
+ name!: string;
175
+ age: i32 | null = null;
176
+ }
177
+ ```
178
+
179
+ Instead, use `JSON.Box` to allow nullable primitives:
180
+
181
+ ```js
111
182
  @json
112
- class Vec3 extends Vec2 {
113
- z: f32 = 3.0;
183
+ class Person {
184
+ name: string;
185
+ age: JSON.Box<i32> | null = null;
186
+ constructor(name: string) {
187
+ this.name = name;
188
+ }
114
189
  }
115
190
 
116
- const arr: Base[] = [
117
- new Vec1(),
118
- new Vec2(),
119
- new Vec3()
120
- ];
191
+ const person = new Person("Bob");
192
+ console.log(JSON.stringify(person)); // {"name":"Bob","age":null}
121
193
 
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);
194
+ person.age = new JSON.Box<i32>(18); // Set age to 18
195
+ console.log(JSON.stringify(person)); // {"name":"Bob","age":18}
125
196
  ```
126
197
 
127
- You can also add it to your `asconfig.json`
198
+ ### 📤 Working with unknown or dynamic data
128
199
 
129
- ```json
130
- {
131
- // ...
132
- "options": {
133
- "transform": ["json-as/transform"]
200
+ Sometimes it's necessary to work with unknown data or data with dynamic types.
201
+
202
+ Because AssemblyScript is a statically-typed language, that typically isn't allowed, so json-as provides the `JSON.Value` and `JSON.Obj` types.
203
+
204
+ Here's a few examples:
205
+
206
+ **Working with multi-type arrays**
207
+
208
+ When dealing with arrays that have multiple types within them, eg. `["string",true,null,["array"]]`, use `JSON.Value[]`
209
+
210
+ ```js
211
+ const a1 = JSON.parse<JSON.Value[]>('["string",true,null,["array"]]');
212
+ console.log(JSON.stringify(a[0])); // "string"
213
+ console.log(JSON.stringify(a[1])); // true
214
+ console.log(JSON.stringify(a[2])); // null
215
+ console.log(JSON.stringify(a[3])); // ["array"]
216
+ ```
217
+
218
+ **Working with unknown objects**
219
+
220
+ When dealing with an object with an unknown structure, use the `JSON.Obj` type
221
+
222
+ ```js
223
+ const o1 = JSON.parse<JSON.Obj>('{"a":3.14,"b":true,"c":[1,2,3],"d":{"x":1,"y":2,"z":3}}');
224
+
225
+ console.log(o1.keys().join(" ")); // a b c d
226
+ console.log(
227
+ o1.values()
228
+ .map<string>((v) => JSON.stringify(v))
229
+ .join(" ")
230
+ ); // 3.14 true [1,2,3] {"x":1,"y":2,"z":3}
231
+
232
+ const y = o1.get("d").get<JSON.Obj>().get<i32>();
233
+ console.log('o1["d"]["y"] = ' + y.toString()); // o1["d"]["y"] = 2
234
+ ```
235
+
236
+ **Working with dynamic types within a schema**
237
+
238
+ More often, objects will be completely statically typed except for one or two values.
239
+
240
+ In such cases, `JSON.Value` can be used to handle fields that may hold different types at runtime.
241
+
242
+ ```js
243
+ @json
244
+ class DynamicObj {
245
+ id: i32 = 0;
246
+ name: string = "";
247
+ data!: JSON.Value; // Can hold any type of value
248
+ }
249
+
250
+ const obj = new DynamicObj();
251
+ obj.id = 1;
252
+ obj.name = "Example";
253
+ obj.data = JSON.parse<JSON.Value>('{"key":"value"}'); // Assigning an object
254
+
255
+ console.log(JSON.stringify(obj)); // {"id":1,"name":"Example","data":{"key":"value"}}
256
+
257
+ obj.data = JSON.Value.from<i32>(42); // Changing to an integer
258
+ console.log(JSON.stringify(obj)); // {"id":1,"name":"Example","data":42}
259
+
260
+ obj.data = JSON.Value.from("a string"); // Changing to a string
261
+ console.log(JSON.stringify(obj)); // {"id":1,"name":"Example","data":"a string"}
262
+ ```
263
+
264
+ ### 🏗️ Using Raw JSON strings
265
+
266
+ Sometimes its necessary to simply copy a string instead of serializing it.
267
+
268
+ For example, the following data would typically be serialized as:
269
+
270
+ ```js
271
+ const m1 = new Map<string, string>();
272
+ m1.set('pos', '{"x":1.0,"y":2.0,"z":3.0}');
273
+
274
+ const a1 = JSON.stringify(m1);
275
+ console.log("a1: " + a1);
276
+ // {"pos":"{\"x\":1.0,\"y\":2.0,\"z\":3.0}"}
277
+ // pos's value (Vec3) is contained within a string... ideally, it should be left alone
278
+ ```
279
+
280
+ If, instead, one wanted to insert Raw JSON into an existing schema/data structure, they could make use of the JSON.Raw type to do so:
281
+
282
+ ```js
283
+ const m1 = new Map<string, JSON.Raw>();
284
+ m1.set('pos', new JSON.Raw('{"x":1.0,"y":2.0,"z":3.0}'));
285
+
286
+ const a1 = JSON.stringify(m1);
287
+ console.log("a1: " + a1);
288
+ // {"pos":{"x":1.0,"y":2.0,"z":3.0}}
289
+ // Now its properly formatted JSON where pos's value is of type Vec3 not string!
290
+ ```
291
+
292
+ ### ⚒️ Using custom serializers or deserializers
293
+
294
+ This library supports custom serialization and deserialization methods, which can be defined using the `@serializer` and `@deserializer` decorators.
295
+
296
+ Here's an example of creating a custom data type called `Point` which serializes to `(x,y)`
297
+
298
+ ```js
299
+ @json
300
+ class Point {
301
+ x: f64 = 0.0;
302
+ y: f64 = 0.0;
303
+ constructor(x: f64, y: f64) {
304
+ this.x = x;
305
+ this.y = y;
306
+ }
307
+
308
+ @serializer
309
+ serializer(self: Point): string {
310
+ return `(${self.x},${self.y})`;
311
+ }
312
+
313
+ @deserializer
314
+ deserializer(data: string): Point {
315
+ const dataSize = bytes(data);
316
+ if (dataSize <= 2) throw new Error("Could not deserialize provided data as type Point");
317
+
318
+ const c = data.indexOf(",");
319
+ const x = data.slice(1, c);
320
+ const y = data.slice(c + 1, data.length - 1);
321
+
322
+ return new Point(
323
+ f64.parse(x),
324
+ f64.parse(y)
325
+ );
134
326
  }
135
327
  }
136
328
  ```
137
329
 
138
- If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
330
+ The serializer function converts a `Point` instance into a string format `(x,y)`.
331
+
332
+ The deserializer function parses the string `(x,y)` back into a `Point` instance.
333
+
334
+ These functions are then wrapped before being consumed by the json-as library:
335
+
336
+ ```js
337
+ @inline __SERIALIZE_CUSTOM(ptr: usize): void {
338
+ const data = this.serializer(changetype<Point>(ptr));
339
+ const dataSize = data.length << 1;
340
+ memory.copy(bs.offset, changetype<usize>(data), dataSize);
341
+ bs.offset += dataSize;
342
+ }
343
+
344
+ @inline __DESERIALIZE_CUSTOM(data: string): Point {
345
+ return this.deserializer(data);
346
+ }
347
+ ```
348
+
349
+ This allows custom serialization while maintaining a generic interface for the library to access.
350
+
351
+ ## ⚡ Performance
352
+
353
+ 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.
354
+
355
+ ### Raw Performance
356
+
357
+ Simple
358
+
359
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
360
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
361
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
362
+ | Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
363
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
364
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
365
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
366
+
367
+ SIMD
368
+
369
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
370
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
371
+ | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
372
+ | Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
373
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
374
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
375
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
376
+
377
+ JavaScript
378
+
379
+ | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
380
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
381
+ | Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
382
+ | Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
383
+ | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
384
+ | Medium JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
385
+ | Large JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
386
+
387
+ ### Real-World Usage
388
+
389
+ | Scenario | JSON Size (kb) | Serialization Time (ops/s) | Deserialization Time (ops/s) | Throughput (GB/s) |
390
+ | ---------------- | -------------- | -------------------------- | ---------------------------- | ----------------- |
391
+ | Web API Response | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
392
+ | Database Entry | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
393
+ | File Parsing | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
139
394
 
140
395
  ## 📃 License
141
396
 
@@ -143,9 +398,9 @@ This project is distributed under an open source license. You can view the full
143
398
 
144
399
  ## 📫 Contact
145
400
 
146
- Please send all issues to [GitHub Issues](https://github.com/JairusSW/as-json/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
401
+ Please send all issues to [GitHub Issues](https://github.com/JairusSW/json-as/issues) and to converse, please send me an email at [me@jairus.dev](mailto:me@jairus.dev)
147
402
 
148
403
  - **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)
149
- - **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/as-json)
404
+ - **GitHub:** Visit the official GitHub repository [Here](https://github.com/JairusSW/json-as)
150
405
  - **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
151
- - **Discord:** Converse with me on [My Discord](discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
406
+ - **Discord:** Contact me at [My Discord](https://discord.com/users/600700584038760448) or on the [AssemblyScript Discord Server](https://discord.gg/assemblyscript/)
@@ -0,0 +1,47 @@
1
+ import { bench } from "as-bench/assembly";
2
+ import { JSON } from "..";
3
+ import { Vec3 } from "./schemas";
4
+ import { serializeString_SIMD } from "../serialize/simd/string";
5
+ import { serializeString } from "../serialize/simple/string";
6
+ import { deserializeString } from "../deserialize/simple/string";
7
+ import { bytes } from "../util";
8
+ import { deserializeString_SIMD } from "../deserialize/simd/string";
9
+
10
+ const vec: Vec3 = {
11
+ x: 1,
12
+ y: 2,
13
+ z: 3
14
+ }
15
+
16
+ bs.ensureSize(4096);
17
+ // bench("Serialize Vector3", () => {
18
+ // JSON.stringify(vec);
19
+ // });
20
+
21
+ // bench("Deserialize Vector3", () => {
22
+ // JSON.parse<Vec3>('{"x":1,"y":2,"z":3}');
23
+ // });
24
+
25
+ // bench("Serialize String SIMD", () => {
26
+ // serializeString_SIMD("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
27
+ // bs.offset = changetype<usize>(bs.buffer);
28
+ // bs.stackSize = 0;
29
+ // });
30
+
31
+ // bench("Serialize String", () => {
32
+ // serializeString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
33
+ // bs.offset = changetype<usize>(bs.buffer);
34
+ // bs.stackSize = 0;
35
+ // });
36
+
37
+ const src = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\\\:;\\"\'?/>.<,\'\\"}"';
38
+ const srcStart = changetype<usize>(src);
39
+ const srcEnd = srcStart + bytes(src);
40
+ const out = changetype<usize>(new ArrayBuffer(256));
41
+ bench("Deserialize String", () => {
42
+ deserializeString(srcStart, srcEnd, out);
43
+ });
44
+
45
+ bench("Deserialize String SIMD", () => {
46
+ deserializeString_SIMD(srcStart, srcEnd, out);
47
+ })
@@ -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,23 @@
1
+ import {JSON} from "..";
2
+ import {Vec3} from "./schemas";
3
+ import {bench} from "../custom/bench";
4
+ import {serializeString_SIMD} from "../serialize/simd/string";
5
+ import {deserializeString_SIMD} from "../deserialize/simd/string";
6
+ import {serializeString} from "../serialize/simple/string";
7
+ import {deserializeString} from "../deserialize/simple/string";
8
+
9
+ const vec: Vec3 = {x: 1, y: 2, z: 3};
10
+
11
+ bs.ensureSize(4096);
12
+
13
+ bench(
14
+ "Serialize String (Simple)",
15
+ () => {
16
+ serializeString("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789~`!@#$%^&*()-_=+{[}]|\\:;\"'?/>.<,'\"}");
17
+ },
18
+ 25_000_000
19
+ );
20
+
21
+ // bench("Deserialize String Simple", () => {
22
+ // deserializeString_SIMD("\"hello world\"")
23
+ // });
@@ -0,0 +1,21 @@
1
+ import {JSON} from "..";
2
+ import {Vec3} from "./schemas";
3
+ import {bench} from "./bench";
4
+
5
+ const vec: Vec3 = {x: 1, y: 2, z: 3};
6
+
7
+ bs.ensureSize(4096);
8
+ bench(
9
+ "Serialize Vector3",
10
+ () => {
11
+ // JSON.__serialize(vec);
12
+ // bs.offset = changetype<usize>(bs.buffer);
13
+ // bs.stackSize = 0;
14
+ JSON.stringify(vec);
15
+ },
16
+ 25_000_000
17
+ );
18
+
19
+ // bench("Deserialize Vector3", () => {
20
+ // JSON.parse<Vec3>('{"x":1,"y":2,"z":3}');
21
+ // });