json-as 0.5.52 → 0.5.56
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/.github/workflows/nodejs.yml +25 -0
- package/LICENSE +1 -1
- package/README.md +0 -23
- package/asconfig.json +2 -2
- package/assembly/__benches__/as-json.ts +10 -64
- package/assembly/__tests__/as-json.spec.ts +4 -13
- package/assembly/src/chars.ts +52 -26
- package/assembly/src/json.ts +130 -204
- package/assembly/src/util.ts +175 -148
- package/assembly/test.ts +51 -72
- package/bench/benchmark.ts +206 -0
- package/bench/tsconfig.json +99 -0
- package/bench-results/INTEGER-PARSING.md +52 -0
- package/package.json +16 -10
- package/transform/lib/index.js +26 -11
- package/transform/package.json +1 -1
- package/transform/src/index.ts +44 -22
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
name: Node.js CI
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
build:
|
|
7
|
+
|
|
8
|
+
runs-on: ubuntu-latest
|
|
9
|
+
|
|
10
|
+
steps:
|
|
11
|
+
- name: Checkout the repository
|
|
12
|
+
uses: actions/checkout@v2
|
|
13
|
+
|
|
14
|
+
- name: Setup Node.js
|
|
15
|
+
uses: actions/setup-node@v2
|
|
16
|
+
|
|
17
|
+
- name: Install dependencies
|
|
18
|
+
if: steps.node-cache.outputs.cache-hit != 'true'
|
|
19
|
+
run: yarn
|
|
20
|
+
|
|
21
|
+
- name: Test to see if the project compiles
|
|
22
|
+
run: yarn build:test
|
|
23
|
+
|
|
24
|
+
- name: Perform tests
|
|
25
|
+
run: yarn run test:aspect
|
package/LICENSE
CHANGED
|
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
18
18
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
19
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
20
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -68,29 +68,6 @@ const stringified = JSON.stringify<Player>(player);
|
|
|
68
68
|
const parsed = JSON.parse<Player>(stringified);
|
|
69
69
|
```
|
|
70
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
71
|
## Performance
|
|
95
72
|
|
|
96
73
|
Here are some benchmarks I took with `tinybench` (JavaScript) and `astral` (AssemblyScript).
|
package/asconfig.json
CHANGED
|
@@ -1,64 +1,10 @@
|
|
|
1
1
|
import { JSON } from "..";
|
|
2
|
-
import {
|
|
3
|
-
import { atoi_fast, parseSciInteger, snip_fast, unsafeCharCodeAt } from "../src/util";
|
|
4
|
-
import { HASH } from "util/hash";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let last = 1;
|
|
8
|
-
let char = 0;
|
|
9
|
-
let inStr = false;
|
|
10
|
-
let key: string | null = null;
|
|
11
|
-
let pos = 0;
|
|
12
|
-
|
|
2
|
+
import { __atoi_fast, snip_fast } from "../src/util";
|
|
13
3
|
@json
|
|
14
4
|
class Vec3 {
|
|
15
5
|
x: i32;
|
|
16
6
|
y: i32;
|
|
17
7
|
z: i32;
|
|
18
|
-
@inline __JSON_Deserialize(
|
|
19
|
-
data: string,
|
|
20
|
-
to: Vec3
|
|
21
|
-
): Vec3 {
|
|
22
|
-
for (; pos < data.length - 1; pos++) {
|
|
23
|
-
char = unsafeCharCodeAt(data, pos);
|
|
24
|
-
if (inStr === false && char === quoteCode) {
|
|
25
|
-
if (key != null) {
|
|
26
|
-
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
27
|
-
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
28
|
-
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
29
|
-
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
30
|
-
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
31
|
-
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
last = ++pos;
|
|
35
|
-
inStr = true;
|
|
36
|
-
} else if (
|
|
37
|
-
char === quoteCode &&
|
|
38
|
-
unsafeCharCodeAt(data, pos - 1) != backSlashCode
|
|
39
|
-
) {
|
|
40
|
-
inStr = false;
|
|
41
|
-
key = data.substring(last, pos);
|
|
42
|
-
last = pos += 2;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
if (key != null) {
|
|
46
|
-
if (unsafeCharCodeAt(key!, 0) == 120) {
|
|
47
|
-
to.x = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
48
|
-
} else if (unsafeCharCodeAt(key!, 0) == 121) {
|
|
49
|
-
to.y = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
50
|
-
} else if (unsafeCharCodeAt(key!, 0) == 122) {
|
|
51
|
-
to.z = parseSciInteger<i32>(data.substring(last, pos - 1));
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
last = 1;
|
|
56
|
-
char = 0;
|
|
57
|
-
inStr = false;
|
|
58
|
-
key = null;
|
|
59
|
-
pos = 0;
|
|
60
|
-
return to;
|
|
61
|
-
}
|
|
62
8
|
}
|
|
63
9
|
|
|
64
10
|
const vec: Vec3 = {
|
|
@@ -66,13 +12,13 @@ const vec: Vec3 = {
|
|
|
66
12
|
y: 1,
|
|
67
13
|
z: 8,
|
|
68
14
|
}
|
|
69
|
-
|
|
15
|
+
/*
|
|
70
16
|
bench("Parse Number SNIP", () => {
|
|
71
17
|
blackbox<i32>(snip_fast<i32>("12345"));
|
|
72
18
|
});
|
|
73
19
|
|
|
74
20
|
bench("Parse Number ATOI", () => {
|
|
75
|
-
blackbox<i32>(
|
|
21
|
+
blackbox<i32>(__atoi_fast<i32>("12345"));
|
|
76
22
|
})
|
|
77
23
|
|
|
78
24
|
bench("Parse Number STDLIB", () => {
|
|
@@ -85,13 +31,13 @@ bench("Parse Number OLD", () => {
|
|
|
85
31
|
|
|
86
32
|
bench("Stringify Object (Vec3)", () => {
|
|
87
33
|
blackbox<string>(vec.__JSON_Serialize());
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
// TODO: Make this allocate without crashing
|
|
91
|
-
/*bench("Parse Object (Vec3)", () => {
|
|
92
|
-
blackbox<Vec3>(vec.__JSON_Deserialize('{"x":0,"y":0,"z":0}', vec));
|
|
93
34
|
});*/
|
|
94
35
|
|
|
36
|
+
// TODO: Make this allocate without crashing
|
|
37
|
+
bench("Parse Object (Vec3)", () => {
|
|
38
|
+
blackbox<Vec3>(JSON.parse<Vec3>('{"x":0,"y":0,"z":0}'));
|
|
39
|
+
});
|
|
40
|
+
/*
|
|
95
41
|
bench("Stringify Number Array", () => {
|
|
96
42
|
blackbox(JSON.stringify<i32[]>([1, 2, 3]));
|
|
97
43
|
});
|
|
@@ -126,12 +72,12 @@ bench("Parse Boolean", () => {
|
|
|
126
72
|
|
|
127
73
|
bench("Stringify Integer", () => {
|
|
128
74
|
blackbox(JSON.stringify(blackbox(314)));
|
|
129
|
-
})
|
|
75
|
+
});*/
|
|
130
76
|
|
|
131
77
|
bench("Parse Integer", () => {
|
|
132
78
|
blackbox(JSON.parse<i32>(blackbox("314")));
|
|
133
79
|
});
|
|
134
|
-
|
|
80
|
+
/*
|
|
135
81
|
bench("Stringify Float", () => {
|
|
136
82
|
blackbox(JSON.stringify(blackbox(3.14)));
|
|
137
83
|
});
|
|
@@ -46,10 +46,10 @@ describe("Ser/de Numbers", () => {
|
|
|
46
46
|
it("should ser/de integers", () => {
|
|
47
47
|
canSerde<i32>(0);
|
|
48
48
|
|
|
49
|
-
canSerde<u32>(100);
|
|
50
|
-
canSerde<u64>(101);
|
|
51
|
-
canSerde<i32>(-100);
|
|
52
|
-
canSerde<i64>(-101);
|
|
49
|
+
canSerde<u32>(100, "100");
|
|
50
|
+
canSerde<u64>(101, "101");
|
|
51
|
+
canSerde<i32>(-100, "-100");
|
|
52
|
+
canSerde<i64>(-101, "-101");
|
|
53
53
|
});
|
|
54
54
|
|
|
55
55
|
it("should ser/de floats", () => {
|
|
@@ -68,15 +68,6 @@ describe("Ser/de Numbers", () => {
|
|
|
68
68
|
canSerde<boolean>(true);
|
|
69
69
|
canSerde<boolean>(false);
|
|
70
70
|
});
|
|
71
|
-
|
|
72
|
-
it("should ser/de BigInt objects", () => {
|
|
73
|
-
canSerde<i32>(0);
|
|
74
|
-
|
|
75
|
-
canSerde<u32>(100);
|
|
76
|
-
canSerde<u64>(101);
|
|
77
|
-
canSerde<i32>(-100);
|
|
78
|
-
canSerde<i64>(-101);
|
|
79
|
-
});
|
|
80
71
|
});
|
|
81
72
|
|
|
82
73
|
describe("Ser/de Array", () => {
|
package/assembly/src/chars.ts
CHANGED
|
@@ -1,29 +1,55 @@
|
|
|
1
1
|
// Characters
|
|
2
|
-
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
export const
|
|
6
|
-
|
|
7
|
-
export const
|
|
8
|
-
|
|
9
|
-
export const
|
|
10
|
-
|
|
11
|
-
export const
|
|
12
|
-
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
export const
|
|
16
|
-
|
|
17
|
-
export const
|
|
18
|
-
|
|
19
|
-
export const
|
|
2
|
+
// @ts-ignore = Decorator is valid here
|
|
3
|
+
@inline export const commaCode = 44;
|
|
4
|
+
// @ts-ignore = Decorator is valid here
|
|
5
|
+
@inline export const quoteCode = 34;
|
|
6
|
+
// @ts-ignore = Decorator is valid here
|
|
7
|
+
@inline export const backSlashCode = 92;
|
|
8
|
+
// @ts-ignore: Decorator is valid here
|
|
9
|
+
@inline export const forwardSlashCode = 47;
|
|
10
|
+
// @ts-ignore: Decorator is valid here
|
|
11
|
+
@inline export const leftBraceCode = 123;
|
|
12
|
+
// @ts-ignore: Decorator is valid here
|
|
13
|
+
@inline export const rightBraceCode = 125;
|
|
14
|
+
// @ts-ignore: Decorator is valid here
|
|
15
|
+
@inline export const leftBracketCode = 91;
|
|
16
|
+
// @ts-ignore: Decorator is valid here
|
|
17
|
+
@inline export const rightBracketCode = 93;
|
|
18
|
+
// @ts-ignore: Decorator is valid here
|
|
19
|
+
@inline export const colonCode = 58;
|
|
20
|
+
// @ts-ignore: Decorator is valid here
|
|
21
|
+
@inline export const tCode = 116;
|
|
22
|
+
// @ts-ignore: Decorator is valid here
|
|
23
|
+
@inline export const rCode = 114;
|
|
24
|
+
// @ts-ignore: Decorator is valid here
|
|
25
|
+
@inline export const uCode = 117;
|
|
26
|
+
// @ts-ignore: Decorator is valid here
|
|
27
|
+
@inline export const eCode = 101;
|
|
28
|
+
// @ts-ignore: Decorator is valid here
|
|
29
|
+
@inline export const fCode = 102;
|
|
30
|
+
// @ts-ignore: Decorator is valid here
|
|
31
|
+
@inline export const aCode = 97;
|
|
32
|
+
// @ts-ignore: Decorator is valid here
|
|
33
|
+
@inline export const lCode = 108;
|
|
34
|
+
// @ts-ignore: Decorator is valid here
|
|
35
|
+
@inline export const sCode = 115;
|
|
36
|
+
// @ts-ignore = Decorator is valid here
|
|
37
|
+
@inline export const nCode = 110;
|
|
20
38
|
// Strings
|
|
21
|
-
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
export const
|
|
25
|
-
|
|
26
|
-
export const
|
|
27
|
-
|
|
39
|
+
// @ts-ignore: Decorator is valid here
|
|
40
|
+
@inline export const trueWord = "true";
|
|
41
|
+
// @ts-ignore: Decorator is valid here
|
|
42
|
+
@inline export const falseWord = "false";
|
|
43
|
+
// @ts-ignore: Decorator is valid here
|
|
44
|
+
@inline export const nullWord = "null";
|
|
45
|
+
// @ts-ignore: Decorator is valid here
|
|
46
|
+
@inline export const leftBracketWord = "[";
|
|
47
|
+
// @ts-ignore: Decorator is valid here
|
|
48
|
+
@inline export const emptyArrayWord = "[]";
|
|
49
|
+
// @ts-ignore: Decorator is valid here
|
|
50
|
+
@inline export const commaWord = ",";
|
|
51
|
+
// @ts-ignore: Decorator is valid here
|
|
52
|
+
@inline export const rightBracketWord = "]";
|
|
28
53
|
// Escape Codes
|
|
29
|
-
|
|
54
|
+
// @ts-ignore: Decorator is valid here
|
|
55
|
+
@inline export const newLineCode = 10;
|