json-as 1.0.0-beta.1 → 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 (70) 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 +275 -25
  7. package/assembly/__benches__/misc.bench.ts +0 -1
  8. package/assembly/__benches__/string.bench.ts +23 -0
  9. package/assembly/__benches__/struct.bench.ts +21 -0
  10. package/assembly/__tests__/arbitrary.spec.ts +1 -1
  11. package/assembly/__tests__/array.spec.ts +42 -1
  12. package/assembly/__tests__/bool.spec.ts +1 -1
  13. package/assembly/__tests__/box.spec.ts +1 -1
  14. package/assembly/__tests__/custom.spec.ts +42 -0
  15. package/assembly/__tests__/date.spec.ts +1 -1
  16. package/assembly/__tests__/float.spec.ts +4 -4
  17. package/assembly/__tests__/integer.spec.ts +1 -1
  18. package/assembly/__tests__/null.spec.ts +1 -1
  19. package/assembly/__tests__/raw.spec.ts +23 -0
  20. package/assembly/__tests__/string.spec.ts +1 -1
  21. package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
  22. package/assembly/__tests__/test.spec.ts +1 -1
  23. package/assembly/as-bs.d.ts +53 -0
  24. package/assembly/custom/bench.ts +26 -0
  25. package/assembly/deserialize/simple/array/arbitrary.ts +1 -2
  26. package/assembly/deserialize/simple/array/array.ts +4 -3
  27. package/assembly/deserialize/simple/array/bool.ts +7 -7
  28. package/assembly/deserialize/simple/array/float.ts +1 -1
  29. package/assembly/deserialize/simple/array/integer.ts +1 -1
  30. package/assembly/deserialize/simple/array/map.ts +1 -1
  31. package/assembly/deserialize/simple/array/string.ts +3 -3
  32. package/assembly/deserialize/simple/array/struct.ts +14 -3
  33. package/assembly/deserialize/simple/array.ts +3 -0
  34. package/assembly/deserialize/simple/map.ts +92 -67
  35. package/assembly/deserialize/simple/object.ts +3 -2
  36. package/assembly/deserialize/simple/raw.ts +6 -0
  37. package/assembly/deserialize/simple/struct.ts +29 -16
  38. package/assembly/index.d.ts +15 -1
  39. package/assembly/index.ts +94 -13
  40. package/assembly/serialize/simd/string.ts +0 -1
  41. package/assembly/serialize/simple/array.ts +0 -1
  42. package/assembly/serialize/simple/bool.ts +0 -2
  43. package/assembly/serialize/simple/date.ts +0 -1
  44. package/assembly/serialize/simple/float.ts +0 -1
  45. package/assembly/serialize/simple/integer.ts +0 -1
  46. package/assembly/serialize/simple/map.ts +0 -1
  47. package/assembly/serialize/simple/object.ts +0 -1
  48. package/assembly/serialize/simple/raw.ts +14 -0
  49. package/assembly/serialize/simple/string.ts +0 -1
  50. package/assembly/test.ts +69 -28
  51. package/bench/bench.ts +15 -0
  52. package/bench/schemas.ts +5 -0
  53. package/bench/string.bench.ts +16 -0
  54. package/index.ts +1 -1
  55. package/lib/tsconfig.json +8 -0
  56. package/package.json +9 -6
  57. package/run-tests.sh +1 -1
  58. package/transform/lib/index.js +120 -46
  59. package/transform/lib/index.js.map +1 -1
  60. package/transform/src/index.ts +137 -54
  61. package/.gitmodules +0 -0
  62. package/as-test.config.json +0 -18
  63. package/modules/as-bs/LICENSE +0 -21
  64. package/modules/as-bs/README.md +0 -95
  65. package/modules/as-bs/assembly/state.ts +0 -8
  66. package/modules/as-bs/assembly/tsconfig.json +0 -97
  67. package/modules/as-bs/index.ts +0 -1
  68. package/modules/as-bs/package.json +0 -32
  69. /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
  70. /package/{modules/as-bs/assembly/index.ts → lib/as-bs.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
@@ -1,48 +1,52 @@
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-beta.1
9
+ AssemblyScript - v1.0.0-beta.10
10
10
  </pre>
11
11
  </h5>
12
12
 
13
+ ## 📝 About
14
+
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.
16
+
13
17
  ## 📚 Contents
14
18
 
15
- - [About](#-about)
16
19
  - [Installation](#-installation)
17
20
  - [Usage](#-usage)
18
- - [Examples](#examples)
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)
19
27
  - [Performance](#-performance)
20
28
  - [License](#-license)
21
29
  - [Contact](#-contact)
22
30
 
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
31
  ## 💾 Installation
28
32
 
29
33
  ```bash
30
- npm install json-as@1.0.0-beta.1
34
+ npm install json-as@1.0.0-beta.10
31
35
  ```
32
36
 
33
37
  Add the `--transform` to your `asc` command (e.g. in package.json)
34
38
 
35
39
  ```bash
36
- --transform json-as/transform
40
+ --transform json-as/transform --lib json-as/lib
37
41
  ```
38
42
 
39
43
  Alternatively, add it to your `asconfig.json`
40
44
 
41
45
  ```json
42
46
  {
43
- // ...
44
47
  "options": {
45
- "transform": ["json-as/transform"]
48
+ "transform": ["json-as/transform"],
49
+ "lib": ["json-as/lib"]
46
50
  }
47
51
  }
48
52
  ```
@@ -95,7 +99,254 @@ console.log("Serialized " + serialized);
95
99
  console.log("Deserialized " + JSON.stringify(deserialized));
96
100
  ```
97
101
 
98
- ## 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**
109
+
110
+ This decorator excludes a field from serialization entirely.
111
+
112
+ ```js
113
+ @json
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
+ ```
126
+
127
+ **@omitnull**
128
+
129
+ This decorator omits a field only if its value is null.
130
+
131
+ ```js
132
+ @json
133
+ class Example {
134
+ name!: string;
135
+ @omitnull()
136
+ optionalField!: string | null;
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
+
149
+ @json
150
+ class Example {
151
+ name!: string;
152
+ @omitif((self: Example) => self.age < 18)
153
+ age!: number;
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
182
+ @json
183
+ class Person {
184
+ name: string;
185
+ age: JSON.Box<i32> | null = null;
186
+ constructor(name: string) {
187
+ this.name = name;
188
+ }
189
+ }
190
+
191
+ const person = new Person("Bob");
192
+ console.log(JSON.stringify(person)); // {"name":"Bob","age":null}
193
+
194
+ person.age = new JSON.Box<i32>(18); // Set age to 18
195
+ console.log(JSON.stringify(person)); // {"name":"Bob","age":18}
196
+ ```
197
+
198
+ ### 📤 Working with unknown or dynamic data
199
+
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
+ );
326
+ }
327
+ }
328
+ ```
329
+
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.
99
350
 
100
351
  ## ⚡ Performance
101
352
 
@@ -106,7 +357,7 @@ The `json-as` library has been optimized to achieve near-gigabyte-per-second JSO
106
357
  Simple
107
358
 
108
359
  | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
109
- |--------------------|-----------------------|-------------------------|----------------------|------------------------|
360
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
110
361
  | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
111
362
  | Alphabet String | 4,928,856 ops/s | 7,567,360 ops/s | 975 MB/s | 1,498 MB/s |
112
363
  | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
@@ -116,7 +367,7 @@ Simple
116
367
  SIMD
117
368
 
118
369
  | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
119
- |--------------------|-----------------------|-------------------------|----------------------|------------------------|
370
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
120
371
  | Vector3 Object | 32,642,320 ops/s | 9,736,272 ops/s | 1,240 MB/s | 369 MB/s |
121
372
  | Alphabet String | 20,368,584 ops/s | 28,467,424 ops/s | 3,910 MB/s | 5,636 MB/s |
122
373
  | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
@@ -126,7 +377,7 @@ SIMD
126
377
  JavaScript
127
378
 
128
379
  | Test Case | Serialization (ops/s) | Deserialization (ops/s) | Serialization (MB/s) | Deserialization (MB/s) |
129
- |--------------------|-----------------------|-------------------------|----------------------|------------------------|
380
+ | ------------------ | --------------------- | ----------------------- | -------------------- | ---------------------- |
130
381
  | Vector3 Object | 2,548,013 ops/s | 1,942,440 ops/s | 97 MB/s | 73 MB/s |
131
382
  | Alphabet String | 3,221,556 ops/s | 2,716,617 ops/s | 624 MB/s | 537 MB/s |
132
383
  | Small JSON Object | [Fill Value] | [Fill Value] | [Fill Value] | [Fill Value] |
@@ -135,12 +386,11 @@ JavaScript
135
386
 
136
387
  ### Real-World Usage
137
388
 
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] |
143
-
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] |
144
394
 
145
395
  ## 📃 License
146
396
 
@@ -148,9 +398,9 @@ This project is distributed under an open source license. You can view the full
148
398
 
149
399
  ## 📫 Contact
150
400
 
151
- 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)
152
402
 
153
403
  - **Email:** Send me inquiries, questions, or requests at [me@jairus.dev](mailto:me@jairus.dev)
154
- - **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)
155
405
  - **Website:** Visit my official website at [jairus.dev](https://jairus.dev/)
156
- - **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/)
@@ -1,7 +1,6 @@
1
1
  import { bench } from "as-bench/assembly";
2
2
  import { JSON } from "..";
3
3
  import { Vec3 } from "./schemas";
4
- import { bs } from "../../modules/as-bs/assembly";
5
4
  import { serializeString_SIMD } from "../serialize/simd/string";
6
5
  import { serializeString } from "../serialize/simple/string";
7
6
  import { deserializeString } from "../deserialize/simple/string";
@@ -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
+ // });
@@ -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
  import { Vec3 } from "./types";
4
4
 
5
5
  describe("Should serialize arbitrary types", () => {
@@ -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
+ });