json-as 0.8.5 → 0.8.7

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 (52) hide show
  1. package/.github/workflows/nodejs.yml +7 -1
  2. package/CHANGELOG +6 -1
  3. package/README.md +26 -16
  4. package/assembly/__tests__/deserialize.spec.ts +298 -0
  5. package/assembly/__tests__/serialize.spec.ts +375 -0
  6. package/assembly/deserialize/array/array.ts +31 -0
  7. package/assembly/deserialize/array/bool.ts +19 -0
  8. package/assembly/deserialize/array/float.ts +24 -0
  9. package/assembly/deserialize/array/integer.ts +24 -0
  10. package/assembly/deserialize/array/map.ts +27 -0
  11. package/assembly/deserialize/array/object.ts +27 -0
  12. package/assembly/deserialize/array/string.ts +29 -0
  13. package/assembly/deserialize/array.ts +37 -0
  14. package/assembly/deserialize/bool.ts +18 -0
  15. package/assembly/deserialize/box.ts +17 -0
  16. package/assembly/deserialize/date.ts +11 -0
  17. package/assembly/deserialize/float.ts +9 -0
  18. package/assembly/deserialize/integer.ts +7 -0
  19. package/assembly/deserialize/map.ts +182 -0
  20. package/assembly/deserialize/object.ts +136 -0
  21. package/assembly/deserialize/string.ts +88 -0
  22. package/assembly/index.d.ts +7 -1
  23. package/assembly/index.ts +129 -1
  24. package/assembly/serialize/array.ts +52 -0
  25. package/assembly/serialize/bool.ts +4 -0
  26. package/assembly/serialize/box.ts +10 -0
  27. package/assembly/serialize/date.ts +4 -0
  28. package/assembly/serialize/float.ts +4 -0
  29. package/assembly/serialize/integer.ts +5 -0
  30. package/assembly/serialize/map.ts +24 -0
  31. package/assembly/serialize/object.ts +7 -0
  32. package/assembly/serialize/string.ts +64 -0
  33. package/assembly/src/sink.ts +286 -0
  34. package/assembly/src/util.ts +6 -0
  35. package/assembly/test.ts +34 -16
  36. package/bench/benchmark.ts +7 -3
  37. package/bench.js +14 -3
  38. package/index.ts +1 -1
  39. package/package.json +6 -8
  40. package/transform/lib/index.js +296 -198
  41. package/transform/lib/index.old.js +257 -0
  42. package/transform/lib/types.js +17 -0
  43. package/transform/package.json +1 -1
  44. package/transform/src/index.old.ts +312 -0
  45. package/transform/src/index.ts +298 -234
  46. package/transform/tsconfig.json +2 -2
  47. package/tsconfig.json +94 -102
  48. package/assembly/__benches__/as-json.ts +0 -88
  49. package/assembly/__benches__/as-tral.d.ts +0 -1
  50. package/assembly/__tests__/as-json.spec.ts +0 -671
  51. package/assembly/__tests__/as-pect.d.ts +0 -1
  52. package/assembly/src/json.ts +0 -941
@@ -9,7 +9,10 @@ jobs:
9
9
 
10
10
  steps:
11
11
  - name: Checkout the repository
12
- uses: actions/checkout@v2
12
+ uses: actions/checkout@v4
13
+
14
+ - name: Install Wasmtime
15
+ uses: jcbhmr/setup-wasmtime@v2
13
16
 
14
17
  - name: Setup Node.js
15
18
  uses: actions/setup-node@v2
@@ -17,6 +20,9 @@ jobs:
17
20
  - name: Install dependencies
18
21
  if: steps.node-cache.outputs.cache-hit != 'true'
19
22
  run: yarn
23
+
24
+ - name: Build tests
25
+ run: yarn run tests:build
20
26
 
21
27
  - name: Perform tests
22
28
  run: yarn run test
package/CHANGELOG CHANGED
@@ -1,3 +1,8 @@
1
1
  v0.8.2 - Properties starting with `static` or `private` would be ignored
2
2
  v0.8.3 - Dirty fix to issue #68. Add __JSON_Stringify callable to global scope.
3
- v0.8.4 - Fix #71. Classes with the extending class overriding a property cause the property to be serialized twice.
3
+ v0.8.4 - Fix #71. Classes with the extending class overriding a property cause the property to be serialized twice.
4
+ v0.8.5 - Fix #73. Support for nullable primatives with Box<T> from as-container
5
+ v0.8.6 - Fix. Forgot to stash before publishing. Stash and push what should have been v0.8.5
6
+
7
+ v0.9.0 - Large update. Refactor all the code, nullable primitives, rewrite the transform, allow extensibility with @omit keywords, and fix a plethora of bugs
8
+ [UNRELEASED] v0.9.1 - Port JSON.Value from the `develop` branch to allow for union types, parsing of arbitrary data, and whatever the hell you want.
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
  ██║ ██║███████║ ╚█████╔╝███████║╚██████╔╝██║ ╚████║
8
8
  ╚═╝ ╚═╝╚══════╝ ╚════╝ ╚══════╝ ╚═════╝ ╚═╝ ╚═══╝
9
9
 
10
- v0.8.5
10
+ v0.9.0
11
11
  </pre>
12
12
  </h3>
13
13
 
@@ -34,6 +34,8 @@ Alternatively, add it to your `asconfig.json`
34
34
  }
35
35
  ```
36
36
 
37
+ If you'd like to see the code that the transform generates, run with `JSON_DEBUG=true`
38
+
37
39
  ## Usage
38
40
 
39
41
  ```js
@@ -53,7 +55,10 @@ class Player {
53
55
  firstName!: string;
54
56
  lastName!: string;
55
57
  lastActive!: i32[];
58
+ // Drop in a code block, function, or expression that evaluates to a boolean
59
+ @omitif("this.age < 18")
56
60
  age!: i32;
61
+ @omitnull()
57
62
  pos!: Vec3 | null;
58
63
  isVerified!: boolean;
59
64
  }
@@ -71,15 +76,17 @@ const player: Player = {
71
76
  isVerified: true
72
77
  };
73
78
 
74
- const stringified = JSON.stringify<Player>(player, true);
75
- // You can toggle on setting default values with the 2nd parameter
76
- // Alternative: use JSON.serializeTo(player, out);
79
+ const stringified = JSON.stringify<Player>(player);
77
80
 
78
81
  const parsed = JSON.parse<Player>(stringified);
79
82
  ```
80
83
 
81
84
  If you use this project in your codebase, consider dropping a [star](https://github.com/JairusSW/as-json). I would really appreciate it!
82
85
 
86
+ ## Notes
87
+
88
+ If you want a feature, drop an issue (and again, maybe a star). I'll likely add it in less than 7 days.
89
+
83
90
  ## Performance
84
91
 
85
92
  Run or view the benchmarks [here](https://github.com/JairusSW/as-json/tree/master/bench)
@@ -91,21 +98,25 @@ My library beats JSON (written in C++) on all counts *and*, I see many places wh
91
98
 
92
99
  Serialization Benchmarks:
93
100
 
94
- | Value | JavaScript (ops/s) | JSON-as (ops/s) | JSON-AS with Pages |
95
- |----------------------------|--------------------|-----------------|--------------------|
96
- | "hello world" | 28,629,598 | 64,210,666 | + 124% |
97
- | 12345 | 31,562,431 | 56,329,066 | 321,783,941 ops/s |
98
- | 1.2345 | 15,977,278 | 20,322,939 | 30,307,616 ops/s |
99
- | [[],[[]],[[],[[]]]] | 8,998,624 | 34,453,102 | + 283% |
100
-
101
+ | Value | JavaScript (ops/s) | JSON-as (ops/s) | Difference |
102
+ |----------------------------|--------------------|-----------------|------------|
103
+ | "hello world" | 28,629,598 | 64,210,666 | + 124% |
104
+ | 12345 | 31,562,431 | 56,329,066 | + 78% |
105
+ | 1.2345 | 15,977,278 | 20,322,939 | + 27% |
106
+ | [[],[[]],[[],[[]]]] | 8,998,624 | 34,453,102 | + 283% |
107
+ | { x: f64, y: f64, z: f64 } | 15,583,686 | 17,604,821 | + 12% |
101
108
 
102
109
 
103
- Deserialization Benchmarks: (WIP)
104
110
 
105
- | Value | JavaScript (ops/s) | JSON-AS (ops/s) | % Diff |
106
- |----------------------------|--------------------|-----------------|--------|
107
- | "12345" | 34,647,886 | 254,640,930 | + 635% |
111
+ Deserialization Benchmarks:
108
112
 
113
+ | Value | JavaScript (ops/s) | JSON-AS (ops/s) | Difference|
114
+ |----------------------------|--------------------|-----------------|-----------|
115
+ | "hello world" | 12,210,131 | 24,274,496 | + 98% |
116
+ | "12345" | 21,376,873 | 254,640,930 | + 1,191% |
117
+ | 1.2345 | 23,193,902 | 221,869,840 | + 987% |
118
+ | [[],[[]],[[],[[]]]] | 4,777,227 | 74,921,123 | + 1,568% |
119
+ | { x: f64, y: f64, z: f64 } | 10,973,723 | 25,214,019 | + 230% |
109
120
 
110
121
  And my PC specs:
111
122
 
@@ -115,7 +126,6 @@ And my PC specs:
115
126
  | CPU | AMD Ryzen 7 7800x3D @ 6.00 GHz |
116
127
  | Memory | T-Force DDR5 6000 MHz |
117
128
  | OS | Ubuntu WSL2 |
118
- | Graphics | AMD Radeon RX 6750XT |
119
129
 
120
130
  ## Issues
121
131
 
@@ -0,0 +1,298 @@
1
+ import { JSON } from "..";
2
+ import {
3
+ describe,
4
+ expect
5
+ } from "as-test/assembly";
6
+
7
+ @json
8
+ class BaseObject {
9
+ a: string;
10
+ constructor(a: string) {
11
+ this.a = a;
12
+ }
13
+ }
14
+
15
+ @json
16
+ class DerivedObject extends BaseObject {
17
+ b: string;
18
+ constructor(a: string, b: string) {
19
+ super(a);
20
+ this.b = b;
21
+ }
22
+ }
23
+
24
+ @json
25
+ class Map4 {
26
+ a: string;
27
+ b: string;
28
+ c: string;
29
+ d: string;
30
+ }
31
+
32
+ @json
33
+ class Vec3 {
34
+ x: f64;
35
+ y: f64;
36
+ z: f64;
37
+
38
+ static shouldIgnore: string = "should not be serialized";
39
+ }
40
+
41
+ @json
42
+ class Player {
43
+ firstName: string;
44
+ lastName: string;
45
+ lastActive: i32[];
46
+ age: i32;
47
+ pos: Vec3 | null;
48
+ isVerified: boolean;
49
+ }
50
+
51
+ class Nullable { }
52
+ type Null = Nullable | null;
53
+
54
+ describe("Should deserialize strings", () => {
55
+
56
+ expect(
57
+ JSON.parse<string>("\"abcdefg\"")
58
+ ).toBe("abcdefg");
59
+
60
+ expect(
61
+ JSON.parse<string>('"\\"st\\\\\\"ring\\\\\\" w\\\\\\"\\\\\\"ith quotes\\\\\\"\\\""')
62
+ ).toBe('"st\\"ring\\" w\\"\\"ith quotes\\""');
63
+
64
+ expect(
65
+ JSON.parse<string>('"\\"string \\\\\\"with random spa\\\\nces and \\\\nnewlines\\\\n\\\\n\\\\n\\""')
66
+ ).toBe('"string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"');
67
+
68
+ expect(
69
+ JSON.parse<string>('"\\"string with colon : comma , brace [ ] bracket { } and quote \\\\\\" and other quote \\\\\\\\\\"\\\""')
70
+ ).toBe('"string with colon : comma , brace [ ] bracket { } and quote \\" and other quote \\\\""');
71
+
72
+ });
73
+
74
+ describe("Should deserialize integers", () => {
75
+
76
+ expect(
77
+ JSON.parse<i32>("0")
78
+ ).toBe(<i32>0);
79
+
80
+ expect(
81
+ JSON.parse<u32>("100")
82
+ ).toBe(<u32>100);
83
+
84
+ expect(
85
+ JSON.parse<u64>("101")
86
+ ).toBe(<u64>101);
87
+
88
+ expect(
89
+ JSON.parse<i32>("-100")
90
+ ).toBe(<i32>-100);
91
+
92
+ expect(
93
+ JSON.parse<i64>("-101")
94
+ ).toBe(<i64>-101);
95
+
96
+ });
97
+
98
+ describe("Should deserialize floats", () => {
99
+
100
+ expect(
101
+ JSON.parse<f64>("7.23")
102
+ ).toBe(7.23);
103
+
104
+ expect(
105
+ JSON.parse<f64>("1000.0")
106
+ ).toBe(1000.0);
107
+
108
+ expect(
109
+ JSON.parse<f64>("1.23456")
110
+ ).toBe(1.23456);
111
+
112
+ expect(
113
+ JSON.parse<f64>("0.0")
114
+ ).toBe(0.0);
115
+
116
+ expect(
117
+ JSON.parse<f64>("-7.23")
118
+ ).toBe(-7.23);
119
+
120
+ expect(
121
+ JSON.parse<f64>("0.000001")
122
+ ).toBe(0.000001);
123
+
124
+ expect(
125
+ JSON.parse<f64>("1e-7")
126
+ ).toBe(1e-7);
127
+
128
+ expect(
129
+ JSON.parse<f64>("100000000000000000000.0")
130
+ ).toBe(1e20);
131
+
132
+ expect(
133
+ JSON.parse<f64>("1e+21")
134
+ ).toBe(1e21);
135
+
136
+ });
137
+
138
+ describe("Should deserialize booleans", () => {
139
+
140
+ expect(
141
+ JSON.parse<boolean>("true")
142
+ ).toBe(true);
143
+
144
+ expect(
145
+ JSON.parse<boolean>("false")
146
+ ).toBe(false);
147
+
148
+ });
149
+
150
+ describe("Should deserialize class inheritance", () => {
151
+
152
+ const jsonStr = "{\"a\":\"1\",\"b\":\"2\"}";
153
+ const obj = JSON.parse<DerivedObject>(jsonStr);
154
+
155
+ expect(obj instanceof DerivedObject).toBe(true);
156
+ expect(obj.a).toBe("1");
157
+ expect(obj.b).toBe("2");
158
+ });
159
+
160
+ describe("Should deserialize nulls", () => {
161
+
162
+ expect(
163
+ JSON.stringify(JSON.parse<Null>("null"))
164
+ ).toBe("null");
165
+
166
+ });
167
+
168
+ describe("Should deserialize integer arrays", () => {
169
+
170
+ expect(
171
+ JSON.stringify(JSON.parse<u32[]>("[0,100,101]"))
172
+ ).toBe(JSON.stringify([0, 100, 101]));
173
+
174
+ expect(
175
+ JSON.stringify(JSON.parse<i32[]>("[0,100,101,-100,-101]"))
176
+ ).toBe(JSON.stringify([0, 100, 101, -100, -101]));
177
+
178
+ });
179
+
180
+ describe("Should deserialize float arrays", () => {
181
+
182
+ expect(
183
+ JSON.stringify(JSON.parse<f64[]>("[7.23,1000.0,1000.0,1.23456,1.23456,0.0,7.23]"))
184
+ ).toBe(JSON.stringify([7.23, 1000.0, 1000.0, 1.23456, 1.23456, 0.0, 7.23]));
185
+
186
+ expect(
187
+ JSON.stringify(JSON.parse<f64[]>("[1e+21,1e+22,1e-7,1e-8,1e-9]"))
188
+ ).toBe(JSON.stringify([1e21, 1e22, 1e-7, 1e-8, 1e-9]));
189
+
190
+ });
191
+
192
+ describe("Should deserialize boolean arrays", () => {
193
+
194
+ expect(
195
+ JSON.stringify(JSON.parse<boolean[]>("[true,false]"))
196
+ ).toBe(JSON.stringify([true, false]));
197
+
198
+ });
199
+
200
+ describe("Should deserialize string arrays", () => {
201
+
202
+ expect(
203
+ JSON.stringify(JSON.parse<string[]>('["string \\"with random spa\\nces and \\nnewlines\\n\\n\\n"]'))
204
+ ).toBe(JSON.stringify([ 'string "with random spa\nces and \nnewlines\n\n\n' ]));
205
+
206
+ });
207
+
208
+ describe("Should deserialize nested integer arrays", () => {
209
+
210
+ expect(
211
+ JSON.stringify(JSON.parse<i64[][]>("[[100,101],[-100,-101],[0]]"))
212
+ ).toBe(JSON.stringify([[100, 101], [-100, -101], [0]]));
213
+
214
+ });
215
+
216
+ describe("Should deserialize nested float arrays", () => {
217
+
218
+ expect(
219
+ JSON.stringify(JSON.parse<f64[][]>("[[7.23],[1000.0],[1000.0],[1.23456],[1.23456],[0.0],[7.23]]"))
220
+ ).toBe(JSON.stringify([[7.23], [1000.0], [1000.0], [1.23456], [1.23456], [0.0], [7.23]]));
221
+
222
+ });
223
+
224
+ describe("Should deserialize nested boolean arrays", () => {
225
+
226
+ expect(
227
+ JSON.stringify(JSON.parse<boolean[][]>("[[true],[false]]"))
228
+ ).toBe(JSON.stringify([[true], [false]]));
229
+
230
+ });
231
+
232
+ describe("Should deserialize object arrays", () => {
233
+
234
+ expect(
235
+ JSON.stringify(JSON.parse<Vec3[]>('[{"x":3.4,"y":1.2,"z":8.3},{"x":3.4,"y":-2.1,"z":9.3}]'))
236
+ ).toBe(JSON.stringify(<Vec3[]>[
237
+ { x: 3.4, y: 1.2, z: 8.3 },
238
+ { x: 3.4, y: -2.1, z: 9.3 }
239
+ ]));
240
+
241
+ });
242
+
243
+ describe("Ser/de Objects", () => {
244
+
245
+ expect(
246
+ JSON.stringify(JSON.parse<Vec3>('{"x":3.4,"y":1.2,"z":8.3}'))
247
+ ).toBe(JSON.stringify(<Vec3>{ x: 3.4, y: 1.2, z: 8.3 }));
248
+
249
+ expect(
250
+ JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}'))
251
+ ).toBe(JSON.stringify(<Player>{
252
+ firstName: "Emmet",
253
+ lastName: "West",
254
+ lastActive: [8, 27, 2022],
255
+ age: 23,
256
+ pos: { x: 3.4, y: 1.2, z: 8.3 },
257
+ isVerified: true
258
+ }));
259
+
260
+ expect(
261
+ JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":7.23}'))
262
+ ).toBe(JSON.stringify(<ObjectWithFloat>{ f: 7.23 }));
263
+
264
+ expect(
265
+ JSON.stringify(JSON.parse<ObjectWithFloat>('{"f":0.000001}'))
266
+ ).toBe(JSON.stringify(<ObjectWithFloat>{ f: 0.000001 }));
267
+
268
+ expect(
269
+ JSON.stringify(JSON.parse<ObjWithStrangeKey<string>>('{"a\\\\\\t\\"\\u0002b`c":"foo"}'))
270
+ ).toBe(JSON.stringify(<ObjWithStrangeKey<string>>{ data: "foo" }));
271
+
272
+ });
273
+
274
+ @json
275
+ class ObjWithString {
276
+ s!: string;
277
+ }
278
+
279
+ @json
280
+ class ObjectWithStringArray {
281
+ sa!: string[];
282
+ }
283
+
284
+ @json
285
+ class ObjectWithFloat {
286
+ f!: f64;
287
+ }
288
+
289
+ @json
290
+ class ObjectWithFloatArray {
291
+ fa!: f64[];
292
+ }
293
+
294
+ @json
295
+ class ObjWithStrangeKey<T> {
296
+ @alias('a\\\t"\x02b`c')
297
+ data!: T;
298
+ }