json-as 0.4.1 → 0.4.4
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/README.md +34 -4
- package/as-pect.asconfig.json +24 -0
- package/as-pect.config.js +30 -0
- package/assembly/__benches__/benchmark.ts +9 -9
- package/assembly/__tests__/as-pect.d.ts +1 -0
- package/assembly/__tests__/example.spec.ts +40 -0
- package/assembly/chars.ts +1 -1
- package/assembly/index.ts +29 -55
- package/assembly/test.ts +45 -5
- package/assembly/util.ts +21 -0
- package/package.json +5 -6
- package/transform/lib/index.js +15 -20
- package/transform/package.json +5 -3
- package/transform/src/index.ts +16 -19
- package/transform/tsconfig.json +1 -1
package/README.md
CHANGED
|
@@ -67,14 +67,44 @@ const data: Player = {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
const stringified = JSON.stringify<Player>(data);
|
|
70
|
-
//
|
|
70
|
+
// {
|
|
71
|
+
// "firstName": "Emmet",
|
|
72
|
+
// "lastName": "West",
|
|
73
|
+
// "lastActive": [8, 27, 2022],
|
|
74
|
+
// "age": 23,
|
|
75
|
+
// "pos": {
|
|
76
|
+
// "x": -3.4000000953674318,
|
|
77
|
+
// "y": 1.2000000476837159
|
|
78
|
+
// }
|
|
79
|
+
// }
|
|
71
80
|
console.log(`Stringified: ${stringified}`);
|
|
72
81
|
|
|
73
|
-
const parsed = JSON.parse<Player>(stringified)
|
|
74
|
-
// {
|
|
75
|
-
|
|
82
|
+
const parsed = JSON.parse<Player>(stringified);
|
|
83
|
+
// Player {
|
|
84
|
+
// firstName: "Emmet",
|
|
85
|
+
// lastName: "West",
|
|
86
|
+
// lastActive: [8, 27, 2022],
|
|
87
|
+
// age: 23,
|
|
88
|
+
// pos: {
|
|
89
|
+
// x: -3.4000000953674318,
|
|
90
|
+
// y: 1.2000000476837159
|
|
91
|
+
// }
|
|
92
|
+
// }
|
|
93
|
+
console.log(`Parsed: ${JSON.stringify(parsed)}`);
|
|
76
94
|
```
|
|
77
95
|
|
|
96
|
+
## FAQ
|
|
97
|
+
|
|
98
|
+
- Does it support the full JSON spec?
|
|
99
|
+
Yes, as-json supports the full JSON specification and trys to mimic the JSON API as much as possible
|
|
100
|
+
- What are the differences between as-json and the JSON API?
|
|
101
|
+
The main difference between as-json and the JSON API is the ability to create new fields in objects during runtime. Since classes are static, Map ser/de support will be added soon allowing the user to parse and stringify dynamic objects and their properties
|
|
102
|
+
- Does this support nested structures?
|
|
103
|
+
Yes, as-json supports nested structures
|
|
104
|
+
- Does this support whitespace?
|
|
105
|
+
Yes, as-json supports whitespace although the current implementation is deathly slow
|
|
106
|
+
- How fast is it?
|
|
107
|
+
Really fast. For example, here are some benchmarks for ser/de a Vec2 with as-json
|
|
78
108
|
## Issues
|
|
79
109
|
|
|
80
110
|
Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"targets": {
|
|
3
|
+
"coverage": {
|
|
4
|
+
"lib": ["./node_modules/@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": ["./@as-pect/assembly/assembly/index.ts"]
|
|
24
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export default {
|
|
2
|
+
/**
|
|
3
|
+
* A set of globs passed to the glob package that qualify typescript files for testing.
|
|
4
|
+
*/
|
|
5
|
+
entries: ["assembly/__tests__/**/*.spec.ts"],
|
|
6
|
+
/**
|
|
7
|
+
* A set of globs passed to the glob package that quality files to be added to each test.
|
|
8
|
+
*/
|
|
9
|
+
include: ["assembly/__tests__/**/*.include.ts"],
|
|
10
|
+
/**
|
|
11
|
+
* A set of regexp that will disclude source files from testing.
|
|
12
|
+
*/
|
|
13
|
+
disclude: [/node_modules/],
|
|
14
|
+
/**
|
|
15
|
+
* Add your required AssemblyScript imports here.
|
|
16
|
+
*/
|
|
17
|
+
async instantiate(memory, createImports, instantiate, binary) {
|
|
18
|
+
let instance; // Imports can reference this
|
|
19
|
+
const myImports = {
|
|
20
|
+
// put your web assembly imports here, and return the module
|
|
21
|
+
};
|
|
22
|
+
return instantiate(binary, createImports(myImports));
|
|
23
|
+
},
|
|
24
|
+
/** Enable code coverage. */
|
|
25
|
+
// coverage: ["assembly/**/*.ts"],
|
|
26
|
+
/**
|
|
27
|
+
* Specify if the binary wasm file should be written to the file system.
|
|
28
|
+
*/
|
|
29
|
+
outputBinary: false,
|
|
30
|
+
};
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { JSON
|
|
1
|
+
import { JSON } from "..";
|
|
2
2
|
@json
|
|
3
|
-
class
|
|
3
|
+
class Vec2 {
|
|
4
4
|
x: f32;
|
|
5
5
|
y: f32;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
const vec:
|
|
8
|
+
const vec: Vec2 = blackbox<Vec2>({
|
|
9
9
|
x: 0.0,
|
|
10
10
|
y: 0.0,
|
|
11
11
|
});
|
|
@@ -26,7 +26,7 @@ bench("Stringify Float", () => {
|
|
|
26
26
|
blackbox(JSON.stringify(blackbox(3.14)));
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
-
bench("Stringify
|
|
29
|
+
bench("Stringify Object (Vec2)", () => {
|
|
30
30
|
blackbox(JSON.stringify(vec));
|
|
31
31
|
});
|
|
32
32
|
|
|
@@ -50,20 +50,20 @@ bench("Parse Float", () => {
|
|
|
50
50
|
blackbox(JSON.parse<f32>(blackbox("3.14")));
|
|
51
51
|
});
|
|
52
52
|
|
|
53
|
-
bench("Parse
|
|
54
|
-
blackbox(
|
|
53
|
+
bench("Parse Object (Vec2)", () => {
|
|
54
|
+
blackbox(JSON.parse<Vec2>(blackbox('{"x":0.0,"y":0.0}')));
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
bench("Parse Boolean Array", () => {
|
|
58
58
|
blackbox(
|
|
59
|
-
|
|
59
|
+
JSON.parse<boolean[]>(blackbox("[true,false,true,false,true]"))
|
|
60
60
|
);
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
bench("Parse Integer Array", () => {
|
|
64
|
-
blackbox(
|
|
64
|
+
blackbox(JSON.parse<u32[]>(blackbox("[1,2,3,4,5]")));
|
|
65
65
|
});
|
|
66
66
|
|
|
67
67
|
bench("Parse Float Array", () => {
|
|
68
|
-
blackbox(
|
|
68
|
+
blackbox(JSON.parse<f32[]>(blackbox("[1.0,2.0,3.0,4.0,5.0]")));
|
|
69
69
|
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/// <reference types="@as-pect/assembly/types/as-pect" />
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { JSON } from "../"
|
|
2
|
+
describe("JSON Stringify Test", () => {
|
|
3
|
+
it("Stringify String", () => {
|
|
4
|
+
expect<string>().toBe(42, "19 + 23 is 42");
|
|
5
|
+
});
|
|
6
|
+
|
|
7
|
+
it("should be the same reference", () => {
|
|
8
|
+
let ref = new Vec3();
|
|
9
|
+
expect<Vec3>(ref).toBe(ref, "Reference Equality");
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it("should perform a memory comparison", () => {
|
|
13
|
+
let a = new Vec3(1, 2, 3);
|
|
14
|
+
let b = new Vec3(1, 2, 3);
|
|
15
|
+
|
|
16
|
+
expect<Vec3>(a).toStrictEqual(
|
|
17
|
+
b,
|
|
18
|
+
"a and b have the same values, (discluding child references)",
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("should compare strings", () => {
|
|
23
|
+
expect<string>("a=" + "200").toBe("a=200", "both strings are equal");
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("should compare values", () => {
|
|
27
|
+
expect<i32>(10).toBeLessThan(200);
|
|
28
|
+
expect<i32>(1000).toBeGreaterThan(200);
|
|
29
|
+
expect<i32>(1000).toBeGreaterThanOrEqual(1000);
|
|
30
|
+
expect<i32>(1000).toBeLessThanOrEqual(1000);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it("can log some values to the console", () => {
|
|
34
|
+
log<string>("Hello world!"); // strings!
|
|
35
|
+
log<f64>(3.1415); // floats!
|
|
36
|
+
log<u8>(244); // integers!
|
|
37
|
+
log<u64>(0xffffffff); // long values!
|
|
38
|
+
log<ArrayBuffer>(new ArrayBuffer(50)); // bytes!
|
|
39
|
+
});
|
|
40
|
+
});
|
package/assembly/chars.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const commaCode = ",".charCodeAt(0);
|
|
2
|
-
export const quoteCode = "".charCodeAt(0);
|
|
2
|
+
export const quoteCode = "\"".charCodeAt(0);
|
|
3
3
|
export const backSlashCode = "\\".charCodeAt(0);
|
|
4
4
|
export const leftBraceCode = "{".charCodeAt(0);
|
|
5
5
|
export const rightBraceCode = "}".charCodeAt(0);
|
package/assembly/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
rightBraceCode,
|
|
11
11
|
rightBracketCode
|
|
12
12
|
} from "./chars";
|
|
13
|
+
import { removeWhitespace } from "./util";
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* JSON Encoder/Decoder for AssemblyScript
|
|
@@ -26,17 +27,13 @@ export namespace JSON {
|
|
|
26
27
|
*/
|
|
27
28
|
export function stringify<T = Nullable | null>(data: T): string {
|
|
28
29
|
// String
|
|
29
|
-
if (isString(
|
|
30
|
-
return
|
|
30
|
+
if (isString<T>()) {
|
|
31
|
+
return '"' + (<string>data).replaceAll('"', '\\"') + '"';
|
|
31
32
|
}
|
|
32
33
|
// Boolean
|
|
33
|
-
else if (isBoolean(
|
|
34
|
+
else if (isBoolean<T>()) {
|
|
34
35
|
return data ? "true" : "false";
|
|
35
36
|
}
|
|
36
|
-
// Null
|
|
37
|
-
else if (isNullable<T>() && data == null) {
|
|
38
|
-
return "null";
|
|
39
|
-
}
|
|
40
37
|
// Integers/Floats
|
|
41
38
|
// @ts-ignore
|
|
42
39
|
else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
|
|
@@ -46,20 +43,28 @@ export namespace JSON {
|
|
|
46
43
|
// Class-Based serialization
|
|
47
44
|
// @ts-ignore
|
|
48
45
|
else if (isDefined(data.__JSON_Serialize)) {
|
|
49
|
-
|
|
46
|
+
// @ts-ignore
|
|
50
47
|
return data.__JSON_Serialize();
|
|
51
48
|
}
|
|
52
49
|
// ArrayLike
|
|
53
|
-
else if (isArrayLike(
|
|
50
|
+
else if (isArrayLike<T>()) {
|
|
54
51
|
let result = new StringSink("[");
|
|
52
|
+
// @ts-ignore
|
|
55
53
|
if (data.length == 0) return "[]";
|
|
54
|
+
// @ts-ignore
|
|
56
55
|
for (let i = 0; i < data.length - 1; i++) {
|
|
56
|
+
// @ts-ignore
|
|
57
57
|
result.write(stringify(unchecked(data[i])));
|
|
58
58
|
result.write(",");
|
|
59
59
|
}
|
|
60
|
+
// @ts-ignore
|
|
60
61
|
result.write(stringify(unchecked(data[data.length - 1])));
|
|
61
62
|
result.write("]");
|
|
62
63
|
return result.toString();
|
|
64
|
+
}
|
|
65
|
+
// Null
|
|
66
|
+
else if (isNullable<T>() && data == null) {
|
|
67
|
+
return "null";
|
|
63
68
|
} else {
|
|
64
69
|
return "null";
|
|
65
70
|
}
|
|
@@ -73,6 +78,7 @@ export namespace JSON {
|
|
|
73
78
|
* @returns T
|
|
74
79
|
*/
|
|
75
80
|
export function parse<T = Variant>(data: string): T {
|
|
81
|
+
data = removeWhitespace(data);
|
|
76
82
|
let type!: T;
|
|
77
83
|
if (isString<T>()) {
|
|
78
84
|
// @ts-ignore
|
|
@@ -91,18 +97,20 @@ export namespace JSON {
|
|
|
91
97
|
const result = new Map<string, string>()
|
|
92
98
|
let lastPos: u32 = 1
|
|
93
99
|
let key: string = ''
|
|
94
|
-
let instr:
|
|
100
|
+
let instr: boolean = false
|
|
95
101
|
let char: u32 = 0
|
|
96
102
|
let depth: u32 = 0
|
|
97
103
|
let fdepth: u32 = 0
|
|
98
104
|
for (let i: u32 = 1; i < len; i++) {
|
|
99
|
-
char = data.charCodeAt(i)
|
|
100
|
-
if (
|
|
101
|
-
else if (instr === 0)
|
|
105
|
+
char = data.charCodeAt(i);
|
|
106
|
+
if (instr === false && char === quoteCode) instr = true;
|
|
107
|
+
else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = false;
|
|
108
|
+
if (instr === false) {
|
|
102
109
|
if (char === leftBraceCode || char === leftBracketCode) depth++
|
|
103
110
|
if (char === rightBraceCode || char === rightBracketCode) fdepth++
|
|
104
111
|
}
|
|
105
112
|
if (depth !== 0 && depth === fdepth) {
|
|
113
|
+
//console.log(`Found Struct: ${data.slice(lastPos + 1, i + 1)}`)
|
|
106
114
|
result.set(key, data.slice(lastPos + 1, i + 1))
|
|
107
115
|
// Reset the depth
|
|
108
116
|
depth = 0
|
|
@@ -110,19 +118,22 @@ export namespace JSON {
|
|
|
110
118
|
// Set new lastPos
|
|
111
119
|
lastPos = i + 1
|
|
112
120
|
}
|
|
113
|
-
if (depth === 0) {
|
|
121
|
+
if (!instr && depth === 0) {
|
|
114
122
|
if (char === colonCode) {
|
|
115
123
|
key = data.slice(lastPos + 1, i - 1)
|
|
124
|
+
//console.log(`Found Key: ${data.slice(lastPos + 1, i - 1)}`)
|
|
116
125
|
lastPos = i
|
|
117
|
-
}
|
|
118
|
-
|
|
126
|
+
} else if (char === commaCode) {
|
|
127
|
+
//console.log(`Found Comma: ${data.slice(lastPos + 1, i)}`)
|
|
119
128
|
if ((i - lastPos) > 0) result.set(key, data.slice(lastPos + 1, i))
|
|
120
129
|
lastPos = i + 1
|
|
121
130
|
}
|
|
122
131
|
}
|
|
123
132
|
}
|
|
124
133
|
|
|
125
|
-
if ((len - lastPos) >
|
|
134
|
+
if ((len - lastPos) > 1 && (len - lastPos) !== 0) {
|
|
135
|
+
result.set(key, data.slice(lastPos + 1, len))
|
|
136
|
+
}
|
|
126
137
|
// @ts-ignore
|
|
127
138
|
return schema.__JSON_Deserialize(result)
|
|
128
139
|
} else {
|
|
@@ -132,11 +143,7 @@ export namespace JSON {
|
|
|
132
143
|
}
|
|
133
144
|
}
|
|
134
145
|
|
|
135
|
-
|
|
136
|
-
@inline
|
|
137
|
-
function serializeString(data: string): string {
|
|
138
|
-
return '"' + data.replaceAll('"', '\\"') + '"';
|
|
139
|
-
}
|
|
146
|
+
|
|
140
147
|
// @ts-ignore
|
|
141
148
|
@inline
|
|
142
149
|
function parseString(data: string): string {
|
|
@@ -301,37 +308,4 @@ export namespace JSON {
|
|
|
301
308
|
return result;
|
|
302
309
|
}
|
|
303
310
|
|
|
304
|
-
export function parseObject(data: string): void {
|
|
305
|
-
//const obj = instantiate<T>()
|
|
306
|
-
const result = new Array<string>();
|
|
307
|
-
let lastPos: u32 = 0;
|
|
308
|
-
let char: u32 = 0;
|
|
309
|
-
let i: u32 = 1;
|
|
310
|
-
let key: string = "";
|
|
311
|
-
let isKey: boolean = false;
|
|
312
|
-
for (; i < u32(data.length - 1); i++) {
|
|
313
|
-
char = data.charCodeAt(i);
|
|
314
|
-
if (isKey == false) {
|
|
315
|
-
if (char == colonCode) {
|
|
316
|
-
key = data.slice(lastPos + 2, i - 1);
|
|
317
|
-
//console.log(`Found Key: ${key}`);
|
|
318
|
-
result.push(key);
|
|
319
|
-
lastPos = ++i;
|
|
320
|
-
isKey = true;
|
|
321
|
-
}
|
|
322
|
-
} else {
|
|
323
|
-
if (char == commaCode) {
|
|
324
|
-
const val = data.slice(lastPos, i);
|
|
325
|
-
lastPos = i;
|
|
326
|
-
isKey = false;
|
|
327
|
-
//console.log(`Found Val: ${val}`)
|
|
328
|
-
result.push(val);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
result.push(data.slice(lastPos, data.length - 1));
|
|
333
|
-
//console.log(stringify(result))
|
|
334
|
-
//return obj
|
|
335
|
-
}
|
|
336
|
-
|
|
337
311
|
class Nullable { }
|
package/assembly/test.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
import "wasi";
|
|
2
2
|
import { JSON } from ".";
|
|
3
|
+
import { removeWhitespace } from "./util";
|
|
3
4
|
|
|
5
|
+
// @ts-ignore
|
|
4
6
|
@json
|
|
5
7
|
class Vec2 {
|
|
6
8
|
x: f32
|
|
7
9
|
y: f32
|
|
8
10
|
}
|
|
11
|
+
|
|
12
|
+
// @ts-ignore
|
|
9
13
|
@json
|
|
10
14
|
class Player {
|
|
11
15
|
firstName: string
|
|
@@ -27,9 +31,45 @@ const data: Player = {
|
|
|
27
31
|
}
|
|
28
32
|
|
|
29
33
|
const stringified = JSON.stringify<Player>(data);
|
|
30
|
-
//
|
|
34
|
+
// {
|
|
35
|
+
// "firstName": "Emmet",
|
|
36
|
+
// "lastName": "West",
|
|
37
|
+
// "lastActive": [8, 27, 2022],
|
|
38
|
+
// "age": 23,
|
|
39
|
+
// "pos": {
|
|
40
|
+
// "x": -3.4000000953674318,
|
|
41
|
+
// "y": 1.2000000476837159
|
|
42
|
+
// }
|
|
43
|
+
// }
|
|
31
44
|
console.log(`Stringified: ${stringified}`);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
45
|
+
console.log(`Whitespace: ${removeWhitespace(`{
|
|
46
|
+
"firstName": "Emmet",
|
|
47
|
+
"lastName": "West",
|
|
48
|
+
"lastActive": [8, 27, 2022],
|
|
49
|
+
"age": 23,
|
|
50
|
+
"pos": {
|
|
51
|
+
"x": -3.4000000953674318,
|
|
52
|
+
"y": 1.2000000476837159
|
|
53
|
+
}
|
|
54
|
+
}`)}`)
|
|
55
|
+
const parsed = JSON.parse<Player>(`{
|
|
56
|
+
"firstName": "Emmet",
|
|
57
|
+
"lastName": "West",
|
|
58
|
+
"lastActive": [8, 27, 2022],
|
|
59
|
+
"age": 23,
|
|
60
|
+
"pos": {
|
|
61
|
+
"x": -3.4000000953674318,
|
|
62
|
+
"y": 1.2000000476837159
|
|
63
|
+
}
|
|
64
|
+
}`);
|
|
65
|
+
// Player {
|
|
66
|
+
// firstName: "Emmet",
|
|
67
|
+
// lastName: "West",
|
|
68
|
+
// lastActive: [8, 27, 2022],
|
|
69
|
+
// age: 23,
|
|
70
|
+
// pos: {
|
|
71
|
+
// x: -3.4000000953674318,
|
|
72
|
+
// y: 1.2000000476837159
|
|
73
|
+
// }
|
|
74
|
+
// }
|
|
75
|
+
console.log(`Parsed: ${JSON.stringify(parsed)}`);
|
package/assembly/util.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { StringSink } from "as-string-sink/assembly";
|
|
2
|
+
import { isSpace } from "assemblyscript/std/assembly/util/string";
|
|
3
|
+
import { backSlashCode, quoteCode } from "./chars";
|
|
4
|
+
|
|
5
|
+
export function removeWhitespace(data: string): string {
|
|
6
|
+
const result = new StringSink()
|
|
7
|
+
let instr = false;
|
|
8
|
+
for (let i = 0; i < data.length; i++) {
|
|
9
|
+
const char = data.charCodeAt(i);
|
|
10
|
+
if (instr === false && char === quoteCode) instr = true
|
|
11
|
+
else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== backSlashCode) instr = false;
|
|
12
|
+
|
|
13
|
+
if (instr === false) {
|
|
14
|
+
if (!isSpace(char)) result.write(data.charAt(i))
|
|
15
|
+
} else {
|
|
16
|
+
result.write(data.charAt(i))
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
}
|
|
20
|
+
return result.toString()
|
|
21
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -17,18 +17,16 @@
|
|
|
17
17
|
"test:wasm3": "wasm3 ./build/test.wasm"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
+
"@as-pect/cli": "^7.0.7",
|
|
20
21
|
"@as-tral/cli": "^1.1.1",
|
|
21
22
|
"as-console": "^6.0.2",
|
|
22
23
|
"assemblyscript": "^0.20.7",
|
|
23
24
|
"assemblyscript-prettier": "^1.0.2",
|
|
24
|
-
"benchmark": "^2.1.4",
|
|
25
|
-
"microtime": "^3.0.0",
|
|
26
25
|
"typescript": "^4.7.2"
|
|
27
26
|
},
|
|
28
27
|
"dependencies": {
|
|
29
28
|
"as-string-sink": "^0.5.0",
|
|
30
|
-
"as-variant": "^0.
|
|
31
|
-
"visitor-as": "^0.10.0"
|
|
29
|
+
"as-variant": "^0.4.0"
|
|
32
30
|
},
|
|
33
31
|
"repository": {
|
|
34
32
|
"type": "git",
|
|
@@ -39,7 +37,8 @@
|
|
|
39
37
|
"json",
|
|
40
38
|
"serialize",
|
|
41
39
|
"deserialize",
|
|
42
|
-
"dynamic"
|
|
40
|
+
"dynamic",
|
|
41
|
+
"serde"
|
|
43
42
|
],
|
|
44
43
|
"bugs": {
|
|
45
44
|
"url": "https://github.com/JairusSW/as-json/issues"
|
package/transform/lib/index.js
CHANGED
|
@@ -5,8 +5,8 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
5
5
|
constructor() {
|
|
6
6
|
super(...arguments);
|
|
7
7
|
this.sources = [];
|
|
8
|
-
this.encodeStmts =
|
|
9
|
-
this.
|
|
8
|
+
this.encodeStmts = [];
|
|
9
|
+
this.decodeStmts = [];
|
|
10
10
|
}
|
|
11
11
|
visitMethodDeclaration(node) { }
|
|
12
12
|
visitFieldDeclaration(node) {
|
|
@@ -15,15 +15,10 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
15
15
|
throw new Error(`Field ${name} is missing a type declaration`);
|
|
16
16
|
}
|
|
17
17
|
const type = getName(node.type);
|
|
18
|
-
const className = this.currentClass.name.text;
|
|
19
|
-
if (!this.encodeStmts.has(className))
|
|
20
|
-
this.encodeStmts.set(className, []);
|
|
21
|
-
if (!this.decodeCode.has(className))
|
|
22
|
-
this.decodeCode.set(className, []);
|
|
23
18
|
// @ts-ignore
|
|
24
|
-
this.encodeStmts.
|
|
19
|
+
this.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
|
|
25
20
|
// @ts-ignore
|
|
26
|
-
this.
|
|
21
|
+
this.decodeStmts.push(`${name}: JSON.parse<${type}>(values.get("${name}")),\n`);
|
|
27
22
|
}
|
|
28
23
|
visitClassDeclaration(node) {
|
|
29
24
|
if (!node.members) {
|
|
@@ -31,39 +26,39 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
31
26
|
}
|
|
32
27
|
this.currentClass = node;
|
|
33
28
|
const name = getName(node);
|
|
34
|
-
this.encodeStmts.delete(name);
|
|
35
|
-
this.decodeCode.delete(name);
|
|
36
29
|
this.visit(node.members);
|
|
37
30
|
const serializedProp = `__JSON_Serialized: string = "";`;
|
|
38
31
|
let serializeFunc = ``;
|
|
39
|
-
if (this.encodeStmts.
|
|
32
|
+
if (this.encodeStmts.length > 0) {
|
|
33
|
+
const stmt = this.encodeStmts[this.encodeStmts.length - 1];
|
|
34
|
+
this.encodeStmts[this.encodeStmts.length - 1] = stmt.slice(0, stmt.length - 1);
|
|
40
35
|
serializeFunc = `
|
|
36
|
+
@inline
|
|
41
37
|
__JSON_Serialize(): string {
|
|
42
|
-
|
|
43
|
-
${ // @ts-ignore
|
|
44
|
-
this.encodeStmts.get(name).join("\n")};
|
|
45
|
-
this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
|
|
46
|
-
}
|
|
47
|
-
return this.__JSON_Serialized;
|
|
38
|
+
return \`{${this.encodeStmts.join("")}}\`;
|
|
48
39
|
}
|
|
49
40
|
`;
|
|
50
41
|
}
|
|
51
42
|
else {
|
|
52
43
|
serializeFunc = `
|
|
44
|
+
@inline
|
|
53
45
|
__JSON_Serialize(): string {
|
|
54
46
|
return "{}";
|
|
55
47
|
}
|
|
56
48
|
`;
|
|
57
49
|
}
|
|
58
50
|
const deserializeFunc = `
|
|
51
|
+
@inline
|
|
59
52
|
__JSON_Deserialize(values: Map<string, string>): ${name} {
|
|
60
53
|
return {
|
|
61
54
|
${ // @ts-ignore
|
|
62
|
-
this.
|
|
55
|
+
this.decodeStmts.join("")}
|
|
63
56
|
}
|
|
64
57
|
}
|
|
65
58
|
`;
|
|
66
|
-
|
|
59
|
+
this.encodeStmts = [];
|
|
60
|
+
this.decodeStmts = [];
|
|
61
|
+
//console.log(serializeFunc, deserializeFunc)
|
|
67
62
|
const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);
|
|
68
63
|
node.members.push(serializedProperty);
|
|
69
64
|
const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
|
package/transform/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-as/transform",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -10,7 +10,9 @@
|
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"scripts": {},
|
|
12
12
|
"devDependencies": {},
|
|
13
|
-
"dependencies": {
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"visitor-as": "^0.10.2"
|
|
15
|
+
},
|
|
14
16
|
"repository": {
|
|
15
17
|
"type": "git",
|
|
16
18
|
"url": "git+https://github.com/JairusSW/as-json.git"
|
|
@@ -28,4 +30,4 @@
|
|
|
28
30
|
"homepage": "https://github.com/JairusSW/as-json#readme",
|
|
29
31
|
"type": "module",
|
|
30
32
|
"exports": "./lib/index.js"
|
|
31
|
-
}
|
|
33
|
+
}
|
package/transform/src/index.ts
CHANGED
|
@@ -11,8 +11,8 @@ import { SimpleParser } from "visitor-as/dist/index.js";
|
|
|
11
11
|
class AsJSONTransform extends ClassDecorator {
|
|
12
12
|
public currentClass!: ClassDeclaration;
|
|
13
13
|
public sources: Source[] = [];
|
|
14
|
-
public encodeStmts =
|
|
15
|
-
public
|
|
14
|
+
public encodeStmts: string[] = [];
|
|
15
|
+
public decodeStmts: string[] = [];
|
|
16
16
|
|
|
17
17
|
visitMethodDeclaration(node: MethodDeclaration): void {}
|
|
18
18
|
visitFieldDeclaration(node: FieldDeclaration): void {
|
|
@@ -23,16 +23,13 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
23
23
|
|
|
24
24
|
const type = getName(node.type);
|
|
25
25
|
|
|
26
|
-
const className = this.currentClass!.name.text
|
|
27
|
-
if (!this.encodeStmts.has(className)) this.encodeStmts.set(className, [])
|
|
28
|
-
if (!this.decodeCode.has(className)) this.decodeCode.set(className, [])
|
|
29
26
|
// @ts-ignore
|
|
30
|
-
this.encodeStmts.
|
|
31
|
-
`
|
|
27
|
+
this.encodeStmts.push(
|
|
28
|
+
`"${name}":\${JSON.stringify<${type}>(this.${name})},`
|
|
32
29
|
);
|
|
33
30
|
|
|
34
31
|
// @ts-ignore
|
|
35
|
-
this.
|
|
32
|
+
this.decodeStmts.push(
|
|
36
33
|
`${name}: JSON.parse<${type}>(values.get("${name}")),\n`
|
|
37
34
|
);
|
|
38
35
|
}
|
|
@@ -45,27 +42,24 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
45
42
|
|
|
46
43
|
const name = getName(node);
|
|
47
44
|
|
|
48
|
-
this.encodeStmts.delete(name);
|
|
49
|
-
this.decodeCode.delete(name);
|
|
50
45
|
this.visit(node.members);
|
|
51
46
|
|
|
52
47
|
const serializedProp = `__JSON_Serialized: string = "";`
|
|
53
48
|
|
|
54
49
|
let serializeFunc = ``
|
|
55
50
|
|
|
56
|
-
if (this.encodeStmts.
|
|
51
|
+
if (this.encodeStmts.length > 0) {
|
|
52
|
+
const stmt = this.encodeStmts[this.encodeStmts.length - 1]!
|
|
53
|
+
this.encodeStmts[this.encodeStmts.length - 1] = stmt!.slice(0, stmt.length - 1)
|
|
57
54
|
serializeFunc = `
|
|
55
|
+
@inline
|
|
58
56
|
__JSON_Serialize(): string {
|
|
59
|
-
|
|
60
|
-
${// @ts-ignore
|
|
61
|
-
this.encodeStmts.get(name).join("\n")};
|
|
62
|
-
this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
|
|
63
|
-
}
|
|
64
|
-
return this.__JSON_Serialized;
|
|
57
|
+
return \`{${this.encodeStmts.join("")}}\`;
|
|
65
58
|
}
|
|
66
59
|
`
|
|
67
60
|
} else {
|
|
68
61
|
serializeFunc = `
|
|
62
|
+
@inline
|
|
69
63
|
__JSON_Serialize(): string {
|
|
70
64
|
return "{}";
|
|
71
65
|
}
|
|
@@ -73,14 +67,17 @@ class AsJSONTransform extends ClassDecorator {
|
|
|
73
67
|
}
|
|
74
68
|
|
|
75
69
|
const deserializeFunc = `
|
|
70
|
+
@inline
|
|
76
71
|
__JSON_Deserialize(values: Map<string, string>): ${name} {
|
|
77
72
|
return {
|
|
78
73
|
${// @ts-ignore
|
|
79
|
-
this.
|
|
74
|
+
this.decodeStmts.join("")}
|
|
80
75
|
}
|
|
81
76
|
}
|
|
82
77
|
`;
|
|
83
|
-
|
|
78
|
+
this.encodeStmts = [];
|
|
79
|
+
this.decodeStmts = [];
|
|
80
|
+
//console.log(serializeFunc, deserializeFunc)
|
|
84
81
|
const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);
|
|
85
82
|
node.members.push(serializedProperty);
|
|
86
83
|
|
package/transform/tsconfig.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
|
|
15
15
|
"sourceMap": false /* Generates corresponding '.map' file. */,
|
|
16
16
|
// "outFile": "./", /* Concatenate and emit output to single file. */
|
|
17
|
-
"outDir": "./lib
|
|
17
|
+
"outDir": "./lib" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
|
|
18
18
|
// "composite": true, /* Enable project compilation */
|
|
19
19
|
// "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
|
|
20
20
|
// "removeComments": true, /* Do not emit comments to output. */
|