json-as 1.0.0 → 1.0.2

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 (41) hide show
  1. package/.github/workflows/{nodejs.yml → tests.yml} +1 -1
  2. package/CHANGELOG.md +8 -0
  3. package/README.md +60 -12
  4. package/assembly/__benches__/abc.bench.ts +21 -0
  5. package/assembly/__benches__/large.bench.ts +174 -0
  6. package/assembly/__benches__/lib/index.ts +26 -0
  7. package/assembly/__benches__/medium.bench.ts +46 -0
  8. package/assembly/__benches__/small.bench.ts +33 -0
  9. package/assembly/__benches__/vec3.bench.ts +72 -0
  10. package/assembly/__tests__/struct.spec.ts +20 -22
  11. package/assembly/deserialize/simple/bool.ts +2 -1
  12. package/assembly/deserialize/simple/date.ts +2 -1
  13. package/assembly/deserialize/simple/float.ts +2 -1
  14. package/assembly/deserialize/simple/raw.ts +2 -1
  15. package/assembly/deserialize/simple/string.ts +2 -1
  16. package/assembly/deserialize/simple/struct.ts +0 -1
  17. package/assembly/index.ts +65 -58
  18. package/assembly/serialize/simple/float.ts +2 -1
  19. package/assembly/serialize/simple/integer.ts +2 -1
  20. package/assembly/serialize/simple/raw.ts +2 -1
  21. package/assembly/serialize/simple/string.ts +2 -1
  22. package/assembly/test.ts +12 -1
  23. package/bench/abc.bench.ts +20 -0
  24. package/bench/large.bench.ts +126 -0
  25. package/bench/medium.bench.ts +43 -0
  26. package/bench/small.bench.ts +30 -0
  27. package/bench/vec3.bench.ts +26 -0
  28. package/package.json +28 -31
  29. package/run-bench.as.sh +27 -0
  30. package/run-bench.js.sh +12 -0
  31. package/run-tests.sh +14 -2
  32. package/transform/lib/index.js +2 -2
  33. package/transform/lib/index.js.map +1 -1
  34. package/transform/src/index.ts +2 -2
  35. package/assembly/__benches__/misc.bench.ts +0 -47
  36. package/assembly/__benches__/schemas.ts +0 -25
  37. package/assembly/__benches__/string.bench.ts +0 -23
  38. package/assembly/__benches__/struct.bench.ts +0 -21
  39. package/bench/schemas.ts +0 -5
  40. package/bench/string.bench.ts +0 -16
  41. /package/bench/{bench.ts → lib/bench.ts} +0 -0
package/assembly/index.ts CHANGED
@@ -118,12 +118,12 @@ export namespace JSON {
118
118
  // @ts-ignore: Supplied by transform
119
119
  } else if (isDefined(data.__SERIALIZE_CUSTOM)) {
120
120
  // @ts-ignore
121
- data.__SERIALIZE_CUSTOM(changetype<usize>(data));
121
+ inline.always(data.__SERIALIZE_CUSTOM(changetype<usize>(data)));
122
122
  return bs.out<string>();
123
123
  // @ts-ignore: Supplied by transform
124
124
  } else if (isDefined(data.__SERIALIZE)) {
125
125
  // @ts-ignore
126
- data.__SERIALIZE(changetype<usize>(data));
126
+ inline.always(data.__SERIALIZE(changetype<usize>(data)));
127
127
  return bs.out<string>();
128
128
  // @ts-ignore: Supplied by transform
129
129
  } else if (data instanceof Date) {
@@ -135,20 +135,20 @@ export namespace JSON {
135
135
  return changetype<string>(out);
136
136
  } else if (data instanceof Array) {
137
137
  // @ts-ignore
138
- serializeArray(changetype<nonnull<T>>(data));
138
+ inline.always(serializeArray(changetype<nonnull<T>>(data)));
139
139
  return bs.out<string>();
140
140
  } else if (data instanceof Map) {
141
141
  // @ts-ignore
142
- serializeMap(changetype<nonnull<T>>(data));
142
+ inline.always(serializeMap(changetype<nonnull<T>>(data)));
143
143
  return bs.out<string>();
144
144
  } else if (data instanceof JSON.Raw) {
145
- serializeRaw(data);
145
+ inline.always(serializeRaw(data));
146
146
  return bs.out<string>();
147
147
  } else if (data instanceof JSON.Value) {
148
- serializeArbitrary(data);
148
+ inline.always(serializeArbitrary(data));
149
149
  return bs.out<string>();
150
150
  } else if (data instanceof JSON.Obj) {
151
- serializeObject(data);
151
+ inline.always(serializeObject(data));
152
152
  return bs.out<string>();
153
153
  } else if (data instanceof JSON.Box) {
154
154
  return JSON.stringify(data.value);
@@ -183,43 +183,44 @@ export namespace JSON {
183
183
  return deserializeString(dataPtr, dataPtr + dataSize, __new(dataSize - 4, idof<string>()));
184
184
  } else if (isArray<T>()) {
185
185
  // @ts-ignore
186
- return deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>()));
187
- }
188
- let type: nonnull<T> = changetype<nonnull<T>>(0);
189
- // @ts-ignore: Defined by transform
190
- if (isDefined(type.__DESERIALIZE_CUSTOM)) {
191
- const out = changetype<nonnull<T>>(0);
192
- // @ts-ignore: Defined by transform
193
- if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
194
- // @ts-ignore
195
- return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
196
- // @ts-ignore: Defined by transform
197
- } else if (isDefined(type.__DESERIALIZE)) {
198
- const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
199
- // @ts-ignore: Defined by transform
200
- if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
201
- // @ts-ignore
202
- return deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
203
- } else if (type instanceof Map) {
204
- // @ts-ignore
205
- return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0);
206
- } else if (type instanceof Date) {
207
- // @ts-ignore
208
- return deserializeDate(dataPtr, dataPtr + dataSize);
209
- } else if (type instanceof JSON.Raw) {
210
- // @ts-ignore: type
211
- return deserializeRaw(dataPtr, dataPtr + dataSize);
212
- } else if (type instanceof JSON.Value) {
213
- // @ts-ignorew
214
- return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
215
- } else if (type instanceof JSON.Obj) {
216
- // @ts-ignore
217
- return deserializeObject(dataPtr, dataPtr + dataSize, 0);
218
- } else if (type instanceof JSON.Box) {
219
- // @ts-ignore
220
- return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
186
+ return inline.always(deserializeArray<nonnull<T>>(dataPtr, dataPtr + dataSize, changetype<usize>(instantiate<T>())));
221
187
  } else {
222
- throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
188
+ let type: nonnull<T> = changetype<nonnull<T>>(0);
189
+ // @ts-ignore: Defined by transform
190
+ if (isDefined(type.__DESERIALIZE_CUSTOM)) {
191
+ const out = changetype<nonnull<T>>(0);
192
+ // @ts-ignore: Defined by transform
193
+ if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
194
+ // @ts-ignore
195
+ return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
196
+ // @ts-ignore: Defined by transform
197
+ } else if (isDefined(type.__DESERIALIZE)) {
198
+ const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
199
+ // @ts-ignore: Defined by transform
200
+ if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
201
+ // @ts-ignore
202
+ return inline.always(deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out));
203
+ } else if (type instanceof Map) {
204
+ // @ts-ignore
205
+ return inline.always(deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0));
206
+ } else if (type instanceof Date) {
207
+ // @ts-ignore
208
+ return deserializeDate(dataPtr, dataPtr + dataSize);
209
+ } else if (type instanceof JSON.Raw) {
210
+ // @ts-ignore: type
211
+ return deserializeRaw(dataPtr, dataPtr + dataSize);
212
+ } else if (type instanceof JSON.Value) {
213
+ // @ts-ignore
214
+ return inline.always(deserializeArbitrary(dataPtr, dataPtr + dataSize, 0));
215
+ } else if (type instanceof JSON.Obj) {
216
+ // @ts-ignore
217
+ return inline.always(deserializeObject(dataPtr, dataPtr + dataSize, 0));
218
+ } else if (type instanceof JSON.Box) {
219
+ // @ts-ignore
220
+ return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
221
+ } else {
222
+ throw new Error(`Could not deserialize data ${data} to type ${nameof<T>()}. Make sure to add the correct decorators to classes.`);
223
+ }
223
224
  }
224
225
  }
225
226
 
@@ -546,22 +547,22 @@ export namespace JSON {
546
547
  // @ts-ignore: Supplied by transform
547
548
  } else if (isDefined(src.__SERIALIZE)) {
548
549
  // @ts-ignore
549
- serializeStruct(changetype<nonnull<T>>(src));
550
+ inline.always(serializeStruct(changetype<nonnull<T>>(src)));
550
551
  } else if (src instanceof Date) {
551
552
  // @ts-ignore
552
- serializeDate(changetype<nonnull<T>>(src));
553
+ inline.always(serializeDate(changetype<nonnull<T>>(src)));
553
554
  } else if (src instanceof Array) {
554
555
  // @ts-ignore
555
- serializeArray(changetype<nonnull<T>>(src));
556
+ inline.always(serializeArray(changetype<nonnull<T>>(src)));
556
557
  } else if (src instanceof Map) {
557
558
  // @ts-ignore
558
- serializeMap(changetype<nonnull<T>>(src));
559
+ inline.always(serializeMap(changetype<nonnull<T>>(src)));
559
560
  } else if (src instanceof JSON.Raw) {
560
561
  serializeRaw(src);
561
562
  } else if (src instanceof JSON.Value) {
562
- serializeArbitrary(src);
563
+ inline.always(serializeArbitrary(src));
563
564
  } else if (src instanceof JSON.Obj) {
564
- serializeObject(src);
565
+ inline.always(serializeObject(src));
565
566
  } else if (src instanceof JSON.Box) {
566
567
  __serialize(src.value);
567
568
  } else {
@@ -581,8 +582,11 @@ export namespace JSON {
581
582
  // @ts-ignore: type
582
583
  return deserializeString(srcStart, srcEnd, dst);
583
584
  } else if (isArray<T>()) {
585
+ // @ts-ignore: type
586
+ return inline.always(deserializeArray<T>(srcStart, srcEnd, dst));
587
+ } else if (isNullable<T>() && srcEnd - srcStart == 8 && load<u64>(srcStart) == 30399761348886638) {
584
588
  // @ts-ignore
585
- return deserializeArray<T>(srcStart, srcEnd, dst);
589
+ return null;
586
590
  } else {
587
591
  let type: nonnull<T> = changetype<nonnull<T>>(0);
588
592
  // @ts-ignore: Defined by transform
@@ -594,10 +598,10 @@ export namespace JSON {
594
598
  return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(srcStart, srcEnd));
595
599
  // @ts-ignore: Defined by transform
596
600
  } else if (isDefined(type.__DESERIALIZE)) {
597
- return deserializeStruct<T>(srcStart, srcEnd, dst);
601
+ return inline.always(deserializeStruct<T>(srcStart, srcEnd, dst));
598
602
  } else if (type instanceof Map) {
599
603
  // @ts-ignore: type
600
- return deserializeMap<T>(srcStart, srcEnd, dst);
604
+ return inline.always(deserializeMap<T>(srcStart, srcEnd, dst));
601
605
  } else if (type instanceof Date) {
602
606
  // @ts-ignore: type
603
607
  return deserializeDate(srcStart, srcEnd);
@@ -606,7 +610,7 @@ export namespace JSON {
606
610
  return deserializeRaw(srcStart, srcEnd);
607
611
  } else if (type instanceof JSON.Value) {
608
612
  // @ts-ignore: type
609
- return deserializeArbitrary(srcStart, srcEnd, 0);
613
+ return inline.always(deserializeArbitrary(srcStart, srcEnd, 0));
610
614
  } else if (type instanceof JSON.Box) {
611
615
  // @ts-ignore: type
612
616
  return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
@@ -620,12 +624,15 @@ export namespace JSON {
620
624
  @inline function parseBox<T>(data: string, ty: T): T {
621
625
  return JSON.parse<T>(data);
622
626
  }
623
-
624
- function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
627
+ // @ts-ignore: inline
628
+ @inline function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
625
629
  return JSON.__deserialize<T>(srcStart, srcEnd, dst);
626
630
  }
627
631
 
628
- export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
629
- export function fromRaw(data: JSON.Raw): string { return data.data }
632
+ // @ts-ignore: inline
633
+ @inline export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
634
+ // @ts-ignore: inline
635
+ @inline export function fromRaw(data: JSON.Raw): string { return data.data }
630
636
 
631
- export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
637
+ // @ts-ignore: inline
638
+ @inline export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
@@ -1,7 +1,8 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { dtoa_buffered } from "util/number";
3
3
 
4
- export function serializeFloat<T extends number>(data: T): void {
4
+ // @ts-ignore: inline
5
+ @inline export function serializeFloat<T extends number>(data: T): void {
5
6
  bs.ensureSize(64);
6
7
  bs.offset += dtoa_buffered(bs.offset, data) << 1;
7
8
  }
@@ -1,7 +1,8 @@
1
1
  import { bs } from "../../../lib/as-bs";
2
2
  import { itoa_buffered } from "util/number";
3
3
 
4
- export function serializeInteger<T extends number>(data: T): void {
4
+ // @ts-ignore: inline
5
+ @inline export function serializeInteger<T extends number>(data: T): void {
5
6
  bs.ensureSize(sizeof<T>() << 3);
6
7
  const bytesWritten = itoa_buffered(bs.offset, data) << 1;
7
8
  bs.offset += bytesWritten;
@@ -7,7 +7,8 @@ import { bytes } from "../../util";
7
7
  * @param data data to serialize
8
8
  * @returns void
9
9
  */
10
- export function serializeRaw(data: JSON.Raw): void {
10
+ // @ts-ignore: inline
11
+ @inline export function serializeRaw(data: JSON.Raw): void {
11
12
  const dataSize = bytes(data.data);
12
13
  bs.proposeSize(dataSize);
13
14
  memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
@@ -9,7 +9,8 @@ import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
9
9
  * @param src string
10
10
  * @returns void
11
11
  */
12
- export function serializeString(src: string): void {
12
+ // @ts-ignore: inline
13
+ @inline export function serializeString(src: string): void {
13
14
  const srcSize = bytes(src);
14
15
  bs.proposeSize(srcSize + 4);
15
16
  let srcPtr = changetype<usize>(src);
package/assembly/test.ts CHANGED
@@ -137,4 +137,15 @@ console.log("a11: " + JSON.stringify(a11));
137
137
 
138
138
  const a12 = JSON.parse<InnerObj<ObjWithBracketString>>('{"obj":{"data":"hello} world"}}');
139
139
 
140
- console.log("a12: " + JSON.stringify(a12))
140
+ console.log("a12: " + JSON.stringify(a12))
141
+
142
+
143
+ @json
144
+ class NullableObj {
145
+ bar: Bar | null = null;
146
+ }
147
+
148
+ @json
149
+ class Bar {
150
+ value: string = "";
151
+ }
@@ -0,0 +1,20 @@
1
+ import { bench } from "./lib/bench";
2
+
3
+ const v1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
4
+ const v2 = '"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"';
5
+
6
+ bench(
7
+ "Serialize Alphabet",
8
+ () => {
9
+ JSON.stringify(v1);
10
+ },
11
+ 64_000_00,
12
+ );
13
+
14
+ bench(
15
+ "Deserialize Alphabet",
16
+ () => {
17
+ JSON.parse(v2);
18
+ },
19
+ 64_000_00,
20
+ );
@@ -0,0 +1,126 @@
1
+ import { bench } from "./lib/bench";
2
+
3
+ class Vec3 {
4
+ public x!: number;
5
+ public y!: number;
6
+ public z!: number;
7
+ }
8
+
9
+ class LargeJSON {
10
+ public id!: number;
11
+ public name!: string;
12
+ public age!: number;
13
+ public email!: string;
14
+ public street!: string;
15
+ public city!: string;
16
+ public state!: string;
17
+ public zip!: string;
18
+ public tags!: string[];
19
+ public theme!: string;
20
+ public notifications!: boolean;
21
+ public language!: string;
22
+ public movement!: Vec3[];
23
+ }
24
+
25
+ const v1: LargeJSON = {
26
+ id: 2,
27
+ name: "Medium Object",
28
+ age: 18,
29
+ email: "me@jairus.dev",
30
+ street: "I don't want to say my street",
31
+ city: "I don't want to say this either",
32
+ state: "It really depends",
33
+ zip: "I forget what it is",
34
+ tags: ["me", "dogs", "mountains", "bar", "foo"],
35
+ theme: "Hyper Term Black",
36
+ notifications: true,
37
+ language: "en-US",
38
+ movement: [
39
+ { x: 1, y: 2, z: 3 },
40
+ { x: 1, y: 2, z: 3 },
41
+ { x: 1, y: 2, z: 3 },
42
+ { x: 1, y: 2, z: 3 },
43
+ { x: 1, y: 2, z: 3 },
44
+ { x: 1, y: 2, z: 3 },
45
+ { x: 1, y: 2, z: 3 },
46
+ { x: 1, y: 2, z: 3 },
47
+ { x: 1, y: 2, z: 3 },
48
+ { x: 1, y: 2, z: 3 },
49
+ { x: 1, y: 2, z: 3 },
50
+ { x: 1, y: 2, z: 3 },
51
+ { x: 1, y: 2, z: 3 },
52
+ { x: 1, y: 2, z: 3 },
53
+ { x: 1, y: 2, z: 3 },
54
+ { x: 1, y: 2, z: 3 },
55
+ { x: 1, y: 2, z: 3 },
56
+ { x: 1, y: 2, z: 3 },
57
+ { x: 1, y: 2, z: 3 },
58
+ { x: 1, y: 2, z: 3 },
59
+ { x: 1, y: 2, z: 3 },
60
+ { x: 1, y: 2, z: 3 },
61
+ { x: 1, y: 2, z: 3 },
62
+ { x: 1, y: 2, z: 3 },
63
+ { x: 1, y: 2, z: 3 },
64
+ { x: 1, y: 2, z: 3 },
65
+ { x: 1, y: 2, z: 3 },
66
+ { x: 1, y: 2, z: 3 },
67
+ { x: 1, y: 2, z: 3 },
68
+ { x: 1, y: 2, z: 3 },
69
+ { x: 1, y: 2, z: 3 },
70
+ { x: 1, y: 2, z: 3 },
71
+ { x: 1, y: 2, z: 3 },
72
+ { x: 1, y: 2, z: 3 },
73
+ { x: 1, y: 2, z: 3 },
74
+ { x: 1, y: 2, z: 3 },
75
+ { x: 1, y: 2, z: 3 },
76
+ { x: 1, y: 2, z: 3 },
77
+ { x: 1, y: 2, z: 3 },
78
+ { x: 1, y: 2, z: 3 },
79
+ { x: 1, y: 2, z: 3 },
80
+ { x: 1, y: 2, z: 3 },
81
+ { x: 1, y: 2, z: 3 },
82
+ { x: 1, y: 2, z: 3 },
83
+ { x: 1, y: 2, z: 3 },
84
+ { x: 1, y: 2, z: 3 },
85
+ { x: 1, y: 2, z: 3 },
86
+ { x: 1, y: 2, z: 3 },
87
+ { x: 1, y: 2, z: 3 },
88
+ { x: 1, y: 2, z: 3 },
89
+ { x: 1, y: 2, z: 3 },
90
+ { x: 1, y: 2, z: 3 },
91
+ { x: 1, y: 2, z: 3 },
92
+ { x: 1, y: 2, z: 3 },
93
+ { x: 1, y: 2, z: 3 },
94
+ { x: 1, y: 2, z: 3 },
95
+ { x: 1, y: 2, z: 3 },
96
+ { x: 1, y: 2, z: 3 },
97
+ { x: 1, y: 2, z: 3 },
98
+ { x: 1, y: 2, z: 3 },
99
+ { x: 1, y: 2, z: 3 },
100
+ { x: 1, y: 2, z: 3 },
101
+ { x: 1, y: 2, z: 3 },
102
+ { x: 1, y: 2, z: 3 },
103
+ { x: 1, y: 2, z: 3 },
104
+ { x: 1, y: 2, z: 3 },
105
+ { x: 1, y: 2, z: 3 },
106
+ { x: 1, y: 2, z: 3 },
107
+ ],
108
+ };
109
+
110
+ const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"],"theme":"Hyper Term Black","notifications":true,"language":"en-US","movement":[{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3},{"x":1,"y":2,"z":3}]}`;
111
+
112
+ bench(
113
+ "Serialize Medium Object",
114
+ () => {
115
+ JSON.stringify(v1);
116
+ },
117
+ 3_000_00,
118
+ );
119
+
120
+ bench(
121
+ "Deserialize Medium Object",
122
+ () => {
123
+ JSON.parse(v2);
124
+ },
125
+ 3_000_00,
126
+ );
@@ -0,0 +1,43 @@
1
+ import { bench } from "./lib/bench";
2
+
3
+ class MediumJSON {
4
+ public id!: number;
5
+ public name!: string;
6
+ public age!: number;
7
+ public email!: string;
8
+ public street!: string;
9
+ public city!: string;
10
+ public state!: string;
11
+ public zip!: string;
12
+ public tags!: string[];
13
+ }
14
+
15
+ const v1: MediumJSON = {
16
+ id: 2,
17
+ name: "Medium Object",
18
+ age: 18,
19
+ email: "me@jairus.dev",
20
+ street: "I don't want to say my street",
21
+ city: "I don't want to say this either",
22
+ state: "It really depends",
23
+ zip: "I forget what it is",
24
+ tags: ["me", "dogs", "mountains", "bar", "foo"],
25
+ };
26
+
27
+ const v2 = `{"id":2,"name":"Medium Object","age":18,"email":"me@jairus.dev","street":"I don't want to say my street","city":"I don't want to say this either","state":"It really depends","zip":"I forget what it is","tags":["me","dogs","mountains","bar","foo"]}`;
28
+
29
+ bench(
30
+ "Serialize Medium Object",
31
+ () => {
32
+ JSON.stringify(v1);
33
+ },
34
+ 8_000_00,
35
+ );
36
+
37
+ bench(
38
+ "Deserialize Medium Object",
39
+ () => {
40
+ JSON.parse(v2);
41
+ },
42
+ 8_000_00,
43
+ );
@@ -0,0 +1,30 @@
1
+ import { bench } from "./lib/bench";
2
+
3
+ class SmallJSON {
4
+ public id!: number;
5
+ public name!: string;
6
+ public active!: boolean;
7
+ }
8
+
9
+ const v1: SmallJSON = {
10
+ id: 1,
11
+ name: "Small Object",
12
+ active: true,
13
+ };
14
+ const v2 = '{"id":1,"name":"Small Object","active":true}';
15
+
16
+ bench(
17
+ "Serialize Small Object",
18
+ () => {
19
+ JSON.stringify(v1);
20
+ },
21
+ 16_000_00,
22
+ );
23
+
24
+ bench(
25
+ "Deserialize Small Object",
26
+ () => {
27
+ JSON.parse(v2);
28
+ },
29
+ 16_000_00,
30
+ );
@@ -0,0 +1,26 @@
1
+ import { bench } from "./lib/bench";
2
+
3
+ class Vec3 {
4
+ public x!: number;
5
+ public y!: number;
6
+ public z!: number;
7
+ }
8
+
9
+ const v1: Vec3 = { x: 1, y: 2, z: 3 };
10
+ const v2 = '{"x":1,"y":2,"z":3}';
11
+
12
+ bench(
13
+ "Serialize Vec3",
14
+ () => {
15
+ JSON.stringify(v1);
16
+ },
17
+ 16_000_00,
18
+ );
19
+
20
+ bench(
21
+ "Deserialize Vec3",
22
+ () => {
23
+ JSON.parse(v2);
24
+ },
25
+ 16_000_00,
26
+ );
package/package.json CHANGED
@@ -1,25 +1,40 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "author": "Jairus Tanaka",
5
+ "description": "The only JSON library you'll need for AssemblyScript. SIMD enabled",
6
+ "types": "assembly/index.ts",
7
+ "main": "transform/lib/index.js",
8
+ "homepage": "https://github.com/JairusSW/json-as#readme",
9
+ "license": "MIT",
5
10
  "repository": {
6
11
  "type": "git",
7
12
  "url": "git+https://github.com/JairusSW/json-as.git"
8
13
  },
9
- "main": "transform/lib/index.js",
14
+ "bugs": {
15
+ "url": "https://github.com/JairusSW/json-as/issues"
16
+ },
17
+ "scripts": {
18
+ "test": "bash ./run-tests.sh",
19
+ "bench:as": "bash ./run-bench.as.sh",
20
+ "bench:js": "bash ./run-bench.js.sh",
21
+ "build:time": "time npx asc ./assembly/__benches__/abc.bench.ts --transform ./transform -o ./build/abc.bench.wasm --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory",
22
+ "build:test": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0",
23
+ "build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd",
24
+ "test:wasmtime": "wasmtime ./build/test.wasm",
25
+ "test:wasmer": "wasmer ./build/test.wasm",
26
+ "build:transform": "tsc -p ./transform",
27
+ "bench:wasmer": "wasmer ./build/bench.wasm --llvm",
28
+ "prettier": "prettier -w ."
29
+ },
10
30
  "devDependencies": {
11
31
  "@assemblyscript/wasi-shim": "^0.1.0",
12
- "@types/node": "^22.13.1",
13
- "as-bench": "JairusSW/as-bench",
14
- "as-console": "^7.0.0",
15
- "as-test": "^0.4.0-beta.3",
16
- "assemblyscript": "^0.27.34",
32
+ "@types/node": "^22.13.10",
33
+ "assemblyscript": "^0.27.35",
17
34
  "assemblyscript-prettier": "^3.0.1",
18
- "prettier": "^3.5.0",
19
- "typescript": "^5.7.3"
20
- },
21
- "bugs": {
22
- "url": "https://github.com/JairusSW/json-as/issues"
35
+ "prettier": "^3.5.3",
36
+ "tsx": "^4.19.3",
37
+ "typescript": "^5.8.2"
23
38
  },
24
39
  "contributors": [
25
40
  "DogWhich",
@@ -31,8 +46,6 @@
31
46
  "Matt Johnson-Pint",
32
47
  "Tomáš Hromada"
33
48
  ],
34
- "description": "The only JSON library you'll need for AssemblyScript. SIMD enabled",
35
- "homepage": "https://github.com/JairusSW/json-as#readme",
36
49
  "keywords": [
37
50
  "assemblyscript",
38
51
  "json",
@@ -48,24 +61,8 @@
48
61
  "fast",
49
62
  "algorithm"
50
63
  ],
51
- "license": "MIT",
52
- "overrides": {
53
- "assemblyscript": "$assemblyscript"
54
- },
55
64
  "publishConfig": {
56
65
  "@JairusSW:registry": "https://npm.pkg.github.com"
57
66
  },
58
- "scripts": {
59
- "test": "bash ./run-tests.sh",
60
- "build:bench": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/__benches__/string.bench.ts -o ./build/bench.wasm --textFile ./build/bench.wat --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory",
61
- "build:test": "rm -rf ./build/ && JSON_DEBUG=true asc --lib ./lib/ assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0",
62
- "build:test:simd": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm --textFile ./build/test.wat --optimizeLevel 3 --shrinkLevel 0 --enable simd",
63
- "test:wasmtime": "wasmtime ./build/test.wasm",
64
- "test:wasmer": "wasmer ./build/test.wasm",
65
- "build:transform": "tsc -p ./transform",
66
- "bench:wasmer": "wasmer ./build/bench.wasm --llvm",
67
- "prettier": "prettier -w ."
68
- },
69
- "type": "module",
70
- "types": "assembly/index.ts"
67
+ "type": "module"
71
68
  }
@@ -0,0 +1,27 @@
1
+ #!/bin/bash
2
+
3
+ mkdir -p ./build
4
+
5
+ for file in ./assembly/__benches__/*.bench.ts; do
6
+ filename=$(basename -- "$file")
7
+ output="./build/${filename%.ts}.wasm"
8
+
9
+ start_time=$(date +%s%3N)
10
+ npx asc "$file" --transform ./transform -o "$output" --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub --enable simd --enable bulk-memory || { echo "Build failed"; exit 1; }
11
+ end_time=$(date +%s%3N)
12
+
13
+ build_time=$((end_time - start_time))
14
+
15
+ if [ "$build_time" -ge 60000 ]; then
16
+ formatted_time="$(bc <<< "scale=2; $build_time/60000")m"
17
+ elif [ "$build_time" -ge 1000 ]; then
18
+ formatted_time="$(bc <<< "scale=2; $build_time/1000")s"
19
+ else
20
+ formatted_time="${build_time}ms"
21
+ fi
22
+
23
+ echo -e "$filename (built in $formatted_time)\n"
24
+ wasmer "$output" --llvm || { echo "Benchmarked failed."; exit 1; }
25
+ done
26
+
27
+ echo "Finished benchmarks."
@@ -0,0 +1,12 @@
1
+ #!/bin/bash
2
+
3
+ mkdir -p ./build
4
+
5
+ for file in ./bench/*.bench.ts; do
6
+ filename=$(basename -- "$file")
7
+
8
+ echo -e "$filename\n"
9
+ npx tsx "$file" || { echo "Benchmark failed."; exit 1; }
10
+ done
11
+
12
+ echo "Finished benchmarks."