json-as 0.5.36 → 0.5.38

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.
package/LICENSE CHANGED
File without changes
package/README.md CHANGED
@@ -1,122 +1,118 @@
1
- # AS-JSON
2
- ![AssemblyScript](https://img.shields.io/badge/AssemblyScript-blue)
3
- ![WebAssembly](https://img.shields.io/badge/WebAssemby-purple)
4
-
5
- JSON for AssemblyScript focused on performance, low-overhead, and ease-of-use.
6
- ## Installation
7
-
8
- ```bash
9
- npm install json-as
10
- ```
11
- ```bash
12
- npm install visitor-as --save-dev
13
- ```
14
-
15
- For arbitrary-length numbers, use
16
-
17
- ```bash
18
- npm install as-bignum
19
- ```
20
-
21
- Add the transform to your `asc` command (e.g. in package.json)
22
-
23
- ```bash
24
- --transform json-as/transform
25
- ```
26
-
27
- Alternatively, add it to your `asconfig.json`
28
-
29
- ```
30
- {
31
- "options": {
32
- "transform": ["json-as/transform"]
33
- }
34
- }
35
- ```
36
-
37
- ## Usage
38
-
39
- ```js
40
- import { JSON } from "json-as/assembly";
41
-
42
- // @json or @serializable work here
43
- @json
44
- class Vec3 {
45
- x!: f32;
46
- y!: f32;
47
- z!: f32;
48
- }
49
-
50
- @json
51
- class Player {
52
- firstName!: string;
53
- lastName!: string;
54
- lastActive!: i32[];
55
- age!: i32;
56
- pos!: Vec3 | null;
57
- isVerified!: boolean;
58
- }
59
-
60
- const player: Player = {
61
- firstName: "Emmet",
62
- lastName: "West",
63
- lastActive: [8, 27, 2022],
64
- age: 23,
65
- pos: {
66
- x: 3.4,
67
- y: 1.2,
68
- z: 8.3
69
- },
70
- isVerified: true
71
- };
72
-
73
- const stringified = JSON.stringify<Player>(player);
74
-
75
- const parsed = JSON.parse<Player>(stringified);
76
- ```
77
-
78
- ## Planned Features
79
-
80
- - [x] Serialize
81
- - [x] Objects
82
- - [x] Other Types
83
- - [ ] Dynamic Types
84
- - [x] Deserialize
85
- - [x] Objects
86
- - [x] Other Types
87
- - [ ] Dynamic Types
88
- - [ ] Streaming API
89
- - [ ] Whitespace support
90
- - [ ] Integrate features from SIMDJson
91
- - [x] Optimize
92
- - [x] Strings
93
- - [x] Int/Float
94
- - [x] Bool
95
- - [x] Object Serialization
96
- - [ ] Object Parsing
97
- - [ ] Arrays
98
- ## Performance
99
-
100
- Number parsing speed has doubled over the last 5 versions due to the use of a `atoi_fast` function found in `assembly/util.ts`. This can be further optimized with SIMD.
101
-
102
- String serialization has more than tripled in performance (+360%). The algorithm was rewritten for less if statements and more traps.
103
-
104
- String deserialization was quadrupled from 3.4m ops to 14.8 ops (435%). It went from using `.replaceAll` to a specialized algorithm.
105
-
106
- Schema (object) parsing is being optimized on GitHub and should be at least doubled if not tripled. (Current speed of barely-optimized version is 6.9m ops) This is due to taking advantage of the types with a type map and eliminating extra checking.
107
-
108
- **Serialize Object (Vec3):** 6.7m ops/5s
109
-
110
- **Deserialize Object (Vec3):** 3.8m ops/5s
111
-
112
- **Serialize Array (int[]):** 6.6m ops/5s
113
-
114
- **Deserialize Array (int[]):** 8.6m ops/5s
115
-
116
- **Serialize String (5):** 5.9m ops/5s
117
-
118
- **Deserialize String (5):** 16.3m ops/5s
119
-
120
- ## Issues
121
-
122
- Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
1
+ # AS-JSON
2
+
3
+ ![AssemblyScript](https://img.shields.io/badge/AssemblyScript-blue)
4
+ ![WebAssembly](https://img.shields.io/badge/WebAssemby-purple)
5
+
6
+ JSON for AssemblyScript focused on performance, low-overhead, and ease-of-use.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ npm install json-as
12
+ ```
13
+
14
+ Add the transform to your `asc` command (e.g. in package.json)
15
+
16
+ ```bash
17
+ --transform json-as/transform
18
+ ```
19
+
20
+ Alternatively, add it to your `asconfig.json`
21
+
22
+ ```
23
+ {
24
+ "options": {
25
+ "transform": ["json-as/transform"]
26
+ }
27
+ }
28
+ ```
29
+
30
+ ## Usage
31
+
32
+ ```js
33
+ import { JSON } from "json-as/assembly";
34
+
35
+ // @json or @serializable work here
36
+ @json
37
+ class Vec3 {
38
+ x!: f32;
39
+ y!: f32;
40
+ z!: f32;
41
+ }
42
+
43
+ @json
44
+ class Player {
45
+ firstName!: string;
46
+ lastName!: string;
47
+ lastActive!: i32[];
48
+ age!: i32;
49
+ pos!: Vec3 | null;
50
+ isVerified!: boolean;
51
+ }
52
+
53
+ const player: Player = {
54
+ firstName: "Emmet",
55
+ lastName: "West",
56
+ lastActive: [8, 27, 2022],
57
+ age: 23,
58
+ pos: {
59
+ x: 3.4,
60
+ y: 1.2,
61
+ z: 8.3
62
+ },
63
+ isVerified: true
64
+ };
65
+
66
+ const stringified = JSON.stringify<Player>(player);
67
+
68
+ const parsed = JSON.parse<Player>(stringified);
69
+ ```
70
+
71
+ ## Deviations from the spec
72
+
73
+ This implementation does not hold strongly to the JSON specification. Rather, design and behavior are inspired by the JSON implementation found in Google's v8 engine.
74
+
75
+ - No support for dynamic types
76
+ - Unsafe by design--parser assumes valid JSON
77
+ - Partial whitespace support--parser prefers speed over handling whitespace effectively. Users may use the `removeWhitespace` function provided by `json-as/src/util.ts`
78
+ - Is not based off of the official spec, but rather the behavior of the JSON C implementation found in google's v8 engine
79
+ - Support for scientific notation on integers. Float support coming soon.
80
+
81
+ ## Implemented features
82
+
83
+ Fully supports:
84
+
85
+ - Strings
86
+ - Integers
87
+ - Floats (Scientific notation not implemented)
88
+ - Booleans
89
+ - Arrays
90
+ - Objects
91
+ - Date
92
+ - Null
93
+
94
+ ## Performance
95
+
96
+ Number parsing speed has doubled over the last 5 versions due to the use of a `atoi_fast` function found in `assembly/util.ts`. This can be further optimized with SIMD.
97
+
98
+ String serialization has more than tripled in performance (+360%). The algorithm was rewritten for less if statements and more traps.
99
+
100
+ String deserialization was quadrupled from 3.4m ops to 14.8 ops (435%). It went from using `.replaceAll` to a specialized algorithm.
101
+
102
+ Schema (object) parsing is being optimized on GitHub and should be at least doubled if not tripled. (Current speed of barely-optimized version is 6.9m ops) This is due to taking advantage of the types with a type map and eliminating extra checking.
103
+
104
+ **Serialize Object (Vec3):** 6.7m ops/5s
105
+
106
+ **Deserialize Object (Vec3):** 5.1m ops/5s
107
+
108
+ **Serialize Array (int[]):** 6.6m ops/5s
109
+
110
+ **Deserialize Array (int[]):** 8.6m ops/5s
111
+
112
+ **Serialize String (5):** 5.9m ops/5s
113
+
114
+ **Deserialize String (5):** 16.3m ops/5s
115
+
116
+ ## Issues
117
+
118
+ Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
@@ -1,24 +1,24 @@
1
- {
2
- "targets": {
3
- "coverage": {
4
- "lib": ["@as-covers/assembly/index.ts"],
5
- "transform": ["@as-covers/transform", "@as-pect/transform"]
6
- },
7
- "noCoverage": {
8
- "transform": ["@as-pect/transform"]
9
- }
10
- },
11
- "options": {
12
- "exportMemory": true,
13
- "outFile": "output.wasm",
14
- "textFile": "output.wat",
15
- "bindings": "raw",
16
- "exportStart": "_start",
17
- "exportRuntime": true,
18
- "use": ["RTRACE=1"],
19
- "debug": true,
20
- "exportTable": true
21
- },
22
- "extends": "./asconfig.json",
23
- "entries": ["./node_modules/@as-pect/assembly/assembly/index.ts"]
24
- }
1
+ {
2
+ "targets": {
3
+ "coverage": {
4
+ "lib": ["@as-covers/assembly/index.ts"],
5
+ "transform": ["@as-covers/transform", "@as-pect/transform"]
6
+ },
7
+ "noCoverage": {
8
+ "transform": ["@as-pect/transform"]
9
+ }
10
+ },
11
+ "options": {
12
+ "exportMemory": true,
13
+ "outFile": "output.wasm",
14
+ "textFile": "output.wat",
15
+ "bindings": "raw",
16
+ "exportStart": "_start",
17
+ "exportRuntime": true,
18
+ "use": ["RTRACE=1"],
19
+ "debug": true,
20
+ "exportTable": true
21
+ },
22
+ "extends": "./asconfig.json",
23
+ "entries": ["./node_modules/@as-pect/assembly/assembly/index.ts"]
24
+ }
package/as-pect.config.js CHANGED
File without changes
package/asconfig.json CHANGED
@@ -1,17 +1,18 @@
1
- {
2
- "targets": {
3
- "test": {
4
- "outFile": "build/test.wasm",
5
- "sourceMap": false,
6
- "optimizeLevel": 0,
7
- "shrinkLevel": 0,
8
- "converge": false,
9
- "noAssert": false
10
- }
11
- },
12
- "options": {
13
- "transform": [
14
- "./transform"
15
- ]
16
- }
17
- }
1
+ {
2
+ "targets": {
3
+ "test": {
4
+ "outFile": "build/test.wasm",
5
+ "sourceMap": false,
6
+ "optimizeLevel": 0,
7
+ "shrinkLevel": 0,
8
+ "converge": false,
9
+ "noAssert": false
10
+ }
11
+ },
12
+ "options": {
13
+ "transform": ["./transform"],
14
+ "bindings": "esm",
15
+ "exportStart": "_start"
16
+ },
17
+ "extends": "./node_modules/@assemblyscript/wasi-shim/asconfig.json"
18
+ }
@@ -1,6 +1,6 @@
1
1
  import { JSON } from "..";
2
2
  import { backSlashCode, quoteCode } from "../src/chars";
3
- import { parseJSONInt, unsafeCharCodeAt } from "../src/util";
3
+ import { atoi_fast, parseSciInteger, unsafeCharCodeAt } from "../src/util";
4
4
  import { HASH } from "util/hash";
5
5
 
6
6
  @json
@@ -8,11 +8,6 @@ class Vec3 {
8
8
  x: i32;
9
9
  y: i32;
10
10
  z: i32;
11
-
12
- /*@inline __JSON_Serialize(data: Vec3): string {
13
- return `{"x":${data.x.toString()},"y":${data.y.toString()},"z":${data.z.toString()}}`;
14
- }*/
15
-
16
11
  @inline __JSON_Deserialize(data: string, to: Vec3): Vec3 {
17
12
  let last = 1;
18
13
  let char = 0;
@@ -24,11 +19,11 @@ class Vec3 {
24
19
  if (inStr === false && char === quoteCode) {
25
20
  if (key != null) {
26
21
  if (unsafeCharCodeAt(key, 0) == 120) {
27
- to.x = parseJSONInt<i32>(data.substring(last, pos - 1))
22
+ to.x = parseSciInteger<i32>(data.substring(last, pos - 1))
28
23
  } else if (unsafeCharCodeAt(key, 0) == 121) {
29
- to.y = parseJSONInt<i32>(data.substring(last, pos - 1))
24
+ to.y = parseSciInteger<i32>(data.substring(last, pos - 1))
30
25
  } else if (unsafeCharCodeAt(key, 0) == 122) {
31
- to.z = parseJSONInt<i32>(data.substring(last, pos - 1))
26
+ to.z = parseSciInteger<i32>(data.substring(last, pos - 1))
32
27
  }
33
28
  }
34
29
  last = ++pos;
@@ -41,11 +36,11 @@ class Vec3 {
41
36
  }
42
37
  if (key != null) {
43
38
  if (unsafeCharCodeAt(key, 0) == 120) {
44
- to.x = parseJSONInt<i32>(data.substring(last, pos - 1))
39
+ to.x = parseSciInteger<i32>(data.substring(last, pos - 1))
45
40
  } else if (unsafeCharCodeAt(key, 0) == 121) {
46
- to.y = parseJSONInt<i32>(data.substring(last, pos - 1))
41
+ to.y = parseSciInteger<i32>(data.substring(last, pos - 1))
47
42
  } else if (unsafeCharCodeAt(key, 0) == 122) {
48
- to.z = parseJSONInt<i32>(data.substring(last, pos - 1))
43
+ to.z = parseSciInteger<i32>(data.substring(last, pos - 1))
49
44
  }
50
45
  }
51
46
  return to;
@@ -55,20 +50,38 @@ class Vec3 {
55
50
  const vec: Vec3 = {
56
51
  x: 3,
57
52
  y: 1,
58
- z: 8
53
+ z: 8,
59
54
  };
60
55
 
61
- const vecOut = new Vec3();
56
+ @inline function istr8<T extends number>(int: T): string {
57
+ if (int >= 100) {
58
+ const str = changetype<string>(__new(6, idof<String>()));
59
+ store<u16>(changetype<usize>(str), ((int / 100) % 10) + 48);
60
+ store<u16>(changetype<usize>(str), ((int / 10) % 10) + 48, 2);
61
+ store<u16>(changetype<usize>(str), (int % 10) + 48, 4);
62
+ return str;
63
+ } else if (int >= 10) {
64
+ const str = changetype<string>(__new(4, idof<String>()));
65
+ store<u16>(changetype<usize>(str), ((int / 10) % 10) + 48);
66
+ store<u16>(changetype<usize>(str), (int % 10) + 48, 2);
67
+ return str;
68
+ } else {
69
+ const str = changetype<string>(__new(2, idof<String>()));
70
+ store<u16>(changetype<usize>(str), (int % 10) + 48);
71
+ return str;
72
+ }
73
+ }
62
74
 
63
- const i32Max = blackbox("429496729");
64
- /*
75
+ bench("strint", () => {
76
+ blackbox<string>(istr8<i32>(123));
77
+ })
78
+ bench("tostr", () => {
79
+ blackbox<string>((<i32>123).toString());
80
+ })
65
81
  bench("Stringify Object (Vec3)", () => {
66
- blackbox<string>(vec.__JSON_Serialize(vec));
67
- });*/
82
+ blackbox<string>(vec.__JSON_Serialize());
83
+ });
68
84
 
69
- bench("HASH String", () => {
70
- blackbox<number>(HASH("Hello"));
71
- })
72
85
  // TODO: Make this allocate without crashing
73
86
  bench("Parse Object (Vec3)", () => {
74
87
  blackbox<Vec3>(vec.__JSON_Deserialize('{"x":0,"y":0,"z":0}', vec));
@@ -91,11 +104,11 @@ bench("Stringify String Array", () => {
91
104
  });
92
105
 
93
106
  bench("Stringify String", () => {
94
- blackbox(JSON.stringify(blackbox("Hello \"World!")));
107
+ blackbox(JSON.stringify(blackbox('Hello "World!')));
95
108
  });
96
109
 
97
110
  bench("Parse String", () => {
98
- blackbox(JSON.parse<string>(blackbox('"Hello \"World!"')));
111
+ blackbox(JSON.parse<string>(blackbox('"Hello "World!"')));
99
112
  });
100
113
 
101
114
  bench("Stringify Boolean", () => {
@@ -120,4 +133,4 @@ bench("Stringify Float", () => {
120
133
 
121
134
  bench("Parse Float", () => {
122
135
  blackbox(JSON.parse<f32>(blackbox("3.14")));
123
- });
136
+ });
File without changes
@@ -1,5 +1,13 @@
1
1
  import { JSON } from "..";
2
- import { u128, u128Safe, u256, u256Safe, i128, i128Safe, i256Safe } from "as-bignum/assembly";
2
+ import {
3
+ u128,
4
+ u128Safe,
5
+ u256,
6
+ u256Safe,
7
+ i128,
8
+ i128Safe,
9
+ i256Safe,
10
+ } from "as-bignum/assembly";
3
11
  function canSerde<T>(data: T): void {
4
12
  const serialized = JSON.stringify<T>(data);
5
13
  const deserialized = JSON.stringify<T>(JSON.parse<T>(serialized));
@@ -41,11 +49,11 @@ describe("Ser/de Numbers", () => {
41
49
  canSerde<i32>(-100);
42
50
  canSerde<i64>(-101);
43
51
 
44
- // canSerde<u128>(u128.from("0"))
45
- // canSerde<u128>(u128.from("100"))
46
- // canSerde<u128>(u128.from("101"))
52
+ // canSerde<u128>(u128.from("0"))
53
+ // canSerde<u128>(u128.from("100"))
54
+ // canSerde<u128>(u128.from("101"))
47
55
 
48
- /* canSerde<u128Safe>(u128Safe.from("0"))
56
+ /* canSerde<u128Safe>(u128Safe.from("0"))
49
57
  canSerde<u128Safe>(u128Safe.from("100"))
50
58
  canSerde<u128Safe>(u128Safe.from("101"))
51
59
 
@@ -102,7 +110,7 @@ describe("Ser/de Numbers", () => {
102
110
  });
103
111
 
104
112
  it("should ser/de BigInt objects", () => {
105
- /* canSerde<i32>(0);
113
+ /* canSerde<i32>(0);
106
114
 
107
115
  canSerde<u32>(100);
108
116
  canSerde<u64>(101);
@@ -114,7 +122,7 @@ describe("Ser/de Numbers", () => {
114
122
  canSerde<u128>(u128.from("-100"))
115
123
  canSerde<u128>(u128.from("-101"))
116
124
  */
117
- })
125
+ });
118
126
  });
119
127
 
120
128
  describe("Ser/de Array", () => {
@@ -178,19 +186,19 @@ describe("Ser/de Array", () => {
178
186
  });
179
187
 
180
188
  it("should ser/de object arrays", () => {
181
- canSerde<Vec3[]>([{
182
- x: 3.4,
183
- y: 1.2,
184
- z: 8.3
185
- },
186
- {
187
- x: 3.4,
188
- y: -2.1,
189
- z: 9.3
190
- }
189
+ canSerde<Vec3[]>([
190
+ {
191
+ x: 3.4,
192
+ y: 1.2,
193
+ z: 8.3,
194
+ },
195
+ {
196
+ x: 3.4,
197
+ y: -2.1,
198
+ z: 9.3,
199
+ },
191
200
  ]);
192
-
193
- })
201
+ });
194
202
  });
195
203
 
196
204
  describe("Ser/de Objects", () => {
@@ -198,7 +206,7 @@ describe("Ser/de Objects", () => {
198
206
  canSerde<Vec3>({
199
207
  x: 3.4,
200
208
  y: 1.2,
201
- z: 8.3
209
+ z: 8.3,
202
210
  });
203
211
  });
204
212
  it("should ser/de deep objects", () => {
@@ -210,9 +218,9 @@ describe("Ser/de Objects", () => {
210
218
  pos: {
211
219
  x: 3.4,
212
220
  y: 1.2,
213
- z: 8.3
221
+ z: 8.3,
214
222
  },
215
223
  isVerified: true,
216
224
  });
217
225
  });
218
- });
226
+ });
File without changes
package/assembly/index.ts CHANGED
@@ -1 +1 @@
1
- export { JSON } from "./src/json";
1
+ export { JSON } from "./src/json";
@@ -26,4 +26,4 @@ export const emptyArrayWord = "[]";
26
26
  export const commaWord = ",";
27
27
  export const rightBracketWord = "]";
28
28
  // Escape Codes
29
- export const newLineCode = "\n".charCodeAt(0);
29
+ export const newLineCode = "\n".charCodeAt(0);