json-as 0.5.51 → 0.5.54
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 +17 -17
- package/README.md +0 -23
- package/assembly/__benches__/as-json.ts +23 -61
- package/assembly/__tests__/as-json.spec.ts +14 -26
- package/assembly/src/json.ts +47 -82
- package/assembly/src/util.ts +217 -56
- package/assembly/test.ts +4 -277
- package/bench-results/INTEGER-PARSING.md +52 -0
- package/bench.js +1 -3
- package/package.json +11 -8
- package/transform/lib/index.js +77 -48
- package/transform/package.json +1 -1
- package/asconfig.json +0 -15
package/bench.js
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { Bench } from "tinybench";
|
|
2
2
|
// Trying a new benchmarking lib.
|
|
3
|
-
// It seems to not warmup long at all, so its probably bad.
|
|
4
|
-
// benchmark will probably be best here
|
|
5
3
|
|
|
6
4
|
// JavaScript Results
|
|
7
5
|
// ┌─────────┬───────────────────────────┬─────────────┬────────────────────┬──────────┬─────────┐
|
|
@@ -35,7 +33,7 @@ const vec = {
|
|
|
35
33
|
|
|
36
34
|
let data;
|
|
37
35
|
|
|
38
|
-
const bench = new Bench({ time:
|
|
36
|
+
const bench = new Bench({ time: 1000 })
|
|
39
37
|
|
|
40
38
|
.add("Stringify Object (Vec3)", () => {
|
|
41
39
|
data = JSON.stringify(vec);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.54",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -13,9 +13,9 @@
|
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
15
|
"scripts": {
|
|
16
|
-
"aspect": "asp",
|
|
17
|
-
"bench:astral": "astral
|
|
18
|
-
"build:test": "asc assembly/test.ts --target test
|
|
16
|
+
"test:aspect": "asp",
|
|
17
|
+
"bench:astral": "astral --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior never --runtime stub",
|
|
18
|
+
"build:test": "asc assembly/test.ts --target test",
|
|
19
19
|
"build:transform": "tsc -p ./transform",
|
|
20
20
|
"test:wasmtime": "wasmtime ./build/test.wasm",
|
|
21
21
|
"test:lunatic": "lunatic ./build/test.wasm",
|
|
@@ -26,11 +26,14 @@
|
|
|
26
26
|
"@as-pect/cli": "^8.0.1",
|
|
27
27
|
"@as-tral/cli": "^2.0.0",
|
|
28
28
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
29
|
-
"assemblyscript": "^0.27.
|
|
30
|
-
"assemblyscript-prettier": "^
|
|
31
|
-
"
|
|
29
|
+
"assemblyscript": "^0.27.8",
|
|
30
|
+
"assemblyscript-prettier": "^2.0.2",
|
|
31
|
+
"benchmark": "^2.1.4",
|
|
32
|
+
"kati": "^0.6.2",
|
|
33
|
+
"microtime": "^3.1.1",
|
|
34
|
+
"prettier": "^3.0.1",
|
|
32
35
|
"tinybench": "^2.5.0",
|
|
33
|
-
"typescript": "^
|
|
36
|
+
"typescript": "^5.1.6",
|
|
34
37
|
"visitor-as": "^0.11.4"
|
|
35
38
|
},
|
|
36
39
|
"dependencies": {
|
package/transform/lib/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
2
2
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
3
3
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
4
4
|
class SchemaData {
|
|
@@ -19,48 +19,23 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
19
19
|
this.sources = [];
|
|
20
20
|
}
|
|
21
21
|
visitMethodDeclaration() { }
|
|
22
|
-
visitFieldDeclaration(node) {
|
|
23
|
-
if (toString(node).startsWith("static"))
|
|
24
|
-
return;
|
|
25
|
-
const lineText = toString(node);
|
|
26
|
-
if (lineText.startsWith("private"))
|
|
27
|
-
return;
|
|
28
|
-
const name = getName(node);
|
|
29
|
-
if (!node.type) {
|
|
30
|
-
throw new Error(`Field ${name} is missing a type declaration`);
|
|
31
|
-
}
|
|
32
|
-
let type = getName(node.type);
|
|
33
|
-
// @ts-ignore
|
|
34
|
-
this.currentClass.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
35
|
-
// @ts-ignore
|
|
36
|
-
//this.decodeStmts.push(
|
|
37
|
-
// `${name}: JSON.parseObjectValue<${type}>(values.get("${name}")),\n`
|
|
38
|
-
//);
|
|
39
|
-
// @ts-ignore
|
|
40
|
-
this.currentClass.setDataStmts.push(`if (key.length === ${name.length} && (memory.compare(changetype<usize>("${name}"), changetype<usize>(key), ${name.length}) == 0)) {
|
|
41
|
-
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
42
|
-
return;
|
|
43
|
-
}
|
|
44
|
-
`);
|
|
45
|
-
// @ts-ignore
|
|
46
|
-
//this.checkDecodeStmts.push(
|
|
47
|
-
// ' if (!values.has("${name}")) throw new Error("Key "${name}" was not found. Cannot instantiate object.");\n'
|
|
48
|
-
//);
|
|
49
|
-
}
|
|
50
22
|
visitClassDeclaration(node) {
|
|
51
|
-
var
|
|
23
|
+
var _c;
|
|
52
24
|
const className = node.name.text;
|
|
53
|
-
if (!((
|
|
25
|
+
if (!((_c = node.decorators) === null || _c === void 0 ? void 0 : _c.length))
|
|
54
26
|
return;
|
|
55
27
|
let foundDecorator = false;
|
|
56
28
|
for (const decorator of node.decorators) {
|
|
29
|
+
if (
|
|
57
30
|
// @ts-ignore
|
|
58
|
-
|
|
31
|
+
decorator.name.text.toLowerCase() == "json" ||
|
|
32
|
+
// @ts-ignore
|
|
33
|
+
decorator.name.text.toLowerCase() == "serializable")
|
|
59
34
|
foundDecorator = true;
|
|
60
35
|
}
|
|
61
36
|
if (!foundDecorator)
|
|
62
37
|
return;
|
|
63
|
-
// Prevent from being triggered twice
|
|
38
|
+
// Prevent from being triggered twice.
|
|
64
39
|
for (const member of node.members) {
|
|
65
40
|
if (member.name.text == "__JSON_Serialize")
|
|
66
41
|
return;
|
|
@@ -73,7 +48,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
73
48
|
parent: node.extendsType ? toString(node.extendsType) : "",
|
|
74
49
|
node: node,
|
|
75
50
|
encodeStmts: [],
|
|
76
|
-
setDataStmts: []
|
|
51
|
+
setDataStmts: [],
|
|
77
52
|
};
|
|
78
53
|
if (this.currentClass.parent.length > 0) {
|
|
79
54
|
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
@@ -82,17 +57,64 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
82
57
|
this.currentClass.encodeStmts.push(...parentSchema === null || parentSchema === void 0 ? void 0 : parentSchema.encodeStmts);
|
|
83
58
|
}
|
|
84
59
|
else {
|
|
85
|
-
console.error("Class extends " +
|
|
60
|
+
console.error("Class extends " +
|
|
61
|
+
this.currentClass.parent +
|
|
62
|
+
", but parent class not found. Maybe add the @json decorator over parent class?");
|
|
86
63
|
}
|
|
87
64
|
}
|
|
88
65
|
const parentSchema = this.schemasList.find((v) => v.name == this.currentClass.parent);
|
|
89
|
-
const members = [
|
|
90
|
-
|
|
66
|
+
const members = [
|
|
67
|
+
...node.members,
|
|
68
|
+
...(parentSchema ? parentSchema.node.members : []),
|
|
69
|
+
];
|
|
70
|
+
for (const mem of members) {
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
if (mem.type && mem.type.name && mem.type.name.identifier.text) {
|
|
73
|
+
const member = mem;
|
|
74
|
+
if (toString(member).startsWith("static"))
|
|
75
|
+
return;
|
|
76
|
+
const lineText = toString(member);
|
|
77
|
+
if (lineText.startsWith("private"))
|
|
78
|
+
return;
|
|
79
|
+
// @ts-ignore
|
|
80
|
+
let type = toString(member.type);
|
|
81
|
+
const name = member.name.text;
|
|
82
|
+
this.currentClass.keys.push(name);
|
|
83
|
+
// @ts-ignore
|
|
84
|
+
this.currentClass.types.push(type);
|
|
85
|
+
// @ts-ignore
|
|
86
|
+
if ([
|
|
87
|
+
"u8",
|
|
88
|
+
"i8",
|
|
89
|
+
"u16",
|
|
90
|
+
"i16",
|
|
91
|
+
"u32",
|
|
92
|
+
"i32",
|
|
93
|
+
"f32",
|
|
94
|
+
"u64",
|
|
95
|
+
"i64",
|
|
96
|
+
"f64",
|
|
97
|
+
].includes(type.toLowerCase())) {
|
|
98
|
+
this.currentClass.encodeStmts.push(`"${name}":\${this.${name}.toString()},`);
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
this.currentClass.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
102
|
+
}
|
|
103
|
+
// @ts-ignore
|
|
104
|
+
this.currentClass.setDataStmts.push(`if (key == "${name}") {
|
|
105
|
+
this.${name} = JSON.parseObjectValue<${type}>(value);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
91
111
|
let serializeFunc = "";
|
|
92
112
|
if (this.currentClass.encodeStmts.length > 0) {
|
|
93
113
|
const stmt = this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1];
|
|
94
|
-
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
114
|
+
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
115
|
+
stmt.slice(0, stmt.length - 1);
|
|
95
116
|
serializeFunc = `
|
|
117
|
+
@inline
|
|
96
118
|
__JSON_Serialize(): string {
|
|
97
119
|
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
98
120
|
}
|
|
@@ -100,16 +122,18 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
100
122
|
}
|
|
101
123
|
else {
|
|
102
124
|
serializeFunc = `
|
|
125
|
+
@inline
|
|
103
126
|
__JSON_Serialize(): string {
|
|
104
127
|
return "{}";
|
|
105
128
|
}
|
|
106
129
|
`;
|
|
107
130
|
}
|
|
108
131
|
const setKeyFunc = `
|
|
132
|
+
@inline
|
|
109
133
|
__JSON_Set_Key(key: string, value: string): void {
|
|
110
134
|
${
|
|
111
|
-
|
|
112
|
-
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
this.currentClass.setDataStmts.join("")}
|
|
113
137
|
}
|
|
114
138
|
`;
|
|
115
139
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
|
@@ -127,18 +151,23 @@ export default class Transformer extends Transform {
|
|
|
127
151
|
afterParse(parser) {
|
|
128
152
|
// Create new transform
|
|
129
153
|
const transformer = new AsJSONTransform();
|
|
130
|
-
//
|
|
131
|
-
const sources = parser.sources
|
|
132
|
-
|
|
133
|
-
|
|
154
|
+
// Sort the sources so that user scripts are visited last
|
|
155
|
+
const sources = parser.sources
|
|
156
|
+
.filter((source) => !isStdlib(source))
|
|
157
|
+
.sort((_a, _b) => {
|
|
158
|
+
const a = _a.internalPath;
|
|
159
|
+
const b = _b.internalPath;
|
|
134
160
|
if (a[0] === "~" && b[0] !== "~") {
|
|
135
161
|
return -1;
|
|
136
|
-
}
|
|
162
|
+
}
|
|
163
|
+
else if (a[0] !== "~" && b[0] === "~") {
|
|
137
164
|
return 1;
|
|
138
|
-
}
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
139
167
|
return 0;
|
|
140
168
|
}
|
|
141
|
-
})
|
|
169
|
+
});
|
|
170
|
+
// Loop over every source
|
|
142
171
|
for (const source of sources) {
|
|
143
172
|
// Ignore all lib and std. Visit everything else.
|
|
144
173
|
if (!isStdlib(source)) {
|
|
@@ -146,4 +175,4 @@ export default class Transformer extends Transform {
|
|
|
146
175
|
}
|
|
147
176
|
}
|
|
148
177
|
}
|
|
149
|
-
}
|
|
178
|
+
}
|
package/transform/package.json
CHANGED
package/asconfig.json
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
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
|
-
}
|