json-as 0.9.9 → 0.9.11
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/FUNDING.yml +1 -0
- package/.github/workflows/nodejs.yml +1 -1
- package/CHANGELOG +7 -1
- package/README.md +2 -1
- package/as-test.config.json +24 -0
- package/assembly/__tests__/test.spec.ts +1 -27
- package/assembly/deserialize/array.ts +2 -2
- package/assembly/deserialize/map.ts +2 -0
- package/assembly/index.ts +4 -191
- package/assembly/serialize/array.ts +1 -3
- package/assembly/serialize/map.ts +0 -1
- package/assembly/test.ts +29 -32
- package/package.json +11 -12
- package/transform/lib/index.js +17 -6
- package/transform/package.json +2 -4
- package/transform/src/index.ts +21 -5
- package/assembly/deserialize/mpz.ts +0 -12
- package/assembly/serialize/mpz.ts +0 -6
- package/build/test.spec.wasm +0 -0
- package/build/test.spec.wasm.map +0 -1
- package/build/test.spec.wat +0 -112683
- package/build/test.wasm +0 -0
- package/build/test.wasm.map +0 -1
- package/build/test.wat +0 -24968
- package/tsconfig.json +0 -95
|
@@ -0,0 +1 @@
|
|
|
1
|
+
github: [JairusSW]
|
package/CHANGELOG
CHANGED
|
@@ -15,10 +15,16 @@ v0.9.7 - Update testing framework and readme logo
|
|
|
15
15
|
v0.9.8 - Update dependencies
|
|
16
16
|
v0.9.8a - Fix #80 - Empty Maps were not serialized to {}, instead, threw memory out of bounds
|
|
17
17
|
v0.9.8b - Fix #81 - Revert transform
|
|
18
|
-
|
|
18
|
+
v0.9.9 - Fix #82 - Initialize maps
|
|
19
|
+
v0.9.9a - Remove extraneous logs from transform
|
|
20
|
+
v0.9.11 - Fix transform type checks. switch to nodekind checks
|
|
21
|
+
v0.9.11 - Remove MpZ--implement custom serializers and deserializers in the works
|
|
22
|
+
|
|
23
|
+
[UNRELEASED] v1.0.0
|
|
19
24
|
- Allow nullable primitives
|
|
20
25
|
- Port over JSON.Value
|
|
21
26
|
- Performance improvements
|
|
27
|
+
- Add SIMD support
|
|
22
28
|
- Introduce options
|
|
23
29
|
- Custom serializers
|
|
24
30
|
- Support arbitrary-length integers (@hypercubed/as-mpz)
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
__| || __|| || | | ___ | _ || __|
|
|
4
4
|
| | ||__ || | || | | ||___|| ||__ |
|
|
5
5
|
|_____||_____||_____||_|___| |__|__||_____|
|
|
6
|
-
v0.9.
|
|
6
|
+
v0.9.11
|
|
7
7
|
</pre>
|
|
8
8
|
</h5>
|
|
9
9
|
|
|
@@ -187,6 +187,7 @@ Below are benchmark results comparing JavaScript's built-in JSON implementation
|
|
|
187
187
|
|
|
188
188
|
My library beats JSON (written in C++) on all counts *and*, I see many places where I can pull at least a 60% uplift in performance if I implement it.
|
|
189
189
|
|
|
190
|
+
Note: SIMD is in-development and only available on the `v1` branch on GitHub
|
|
190
191
|
|
|
191
192
|
Serialization Benchmarks:
|
|
192
193
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"input": [
|
|
3
|
+
"./assembly/__tests__/*.spec.ts"
|
|
4
|
+
],
|
|
5
|
+
"outDir": "./build",
|
|
6
|
+
"config": "./asconfig.json",
|
|
7
|
+
"suites": [],
|
|
8
|
+
"coverage": {
|
|
9
|
+
"enabled": true,
|
|
10
|
+
"show": false
|
|
11
|
+
},
|
|
12
|
+
"buildOptions": {
|
|
13
|
+
"args": [],
|
|
14
|
+
"wasi": true,
|
|
15
|
+
"parallel": true,
|
|
16
|
+
"verbose": true
|
|
17
|
+
},
|
|
18
|
+
"runOptions": {
|
|
19
|
+
"runtime": {
|
|
20
|
+
"name": "wasmtime",
|
|
21
|
+
"run": "wasmtime <file>"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -5,7 +5,6 @@ import {
|
|
|
5
5
|
run
|
|
6
6
|
} from "as-test/assembly";
|
|
7
7
|
import { DerivedObject, Null, ObjWithStrangeKey, ObjectWithFloat, OmitIf, Player, Vec3 } from "./types";
|
|
8
|
-
import { MpZ } from "@hypercubed/as-mpz";
|
|
9
8
|
|
|
10
9
|
describe("Should serialize strings", () => {
|
|
11
10
|
|
|
@@ -51,18 +50,6 @@ describe("Should serialize integers", () => {
|
|
|
51
50
|
|
|
52
51
|
});
|
|
53
52
|
|
|
54
|
-
describe("Should serialize MpZ (Big Int)", () => {
|
|
55
|
-
|
|
56
|
-
expect(
|
|
57
|
-
JSON.stringify<MpZ>(MpZ.from(0))
|
|
58
|
-
).toBe("0");
|
|
59
|
-
|
|
60
|
-
expect(
|
|
61
|
-
JSON.stringify<MpZ>(MpZ.from(2).pow(512))
|
|
62
|
-
).toBe("13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096");
|
|
63
|
-
|
|
64
|
-
});
|
|
65
|
-
|
|
66
53
|
describe("Should serialize floats", () => {
|
|
67
54
|
|
|
68
55
|
expect(
|
|
@@ -370,18 +357,6 @@ describe("Should deserialize integers", () => {
|
|
|
370
357
|
|
|
371
358
|
});
|
|
372
359
|
|
|
373
|
-
describe("Should deserialize MpZ (Big Int)", () => {
|
|
374
|
-
|
|
375
|
-
expect(
|
|
376
|
-
JSON.parse<MpZ>("0").toString()
|
|
377
|
-
).toBe("0");
|
|
378
|
-
|
|
379
|
-
expect(
|
|
380
|
-
JSON.parse<MpZ>("13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096").toString()
|
|
381
|
-
).toBe("13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006084096");
|
|
382
|
-
|
|
383
|
-
});
|
|
384
|
-
|
|
385
360
|
describe("Should deserialize floats", () => {
|
|
386
361
|
|
|
387
362
|
expect(
|
|
@@ -559,6 +534,5 @@ describe("Should deserialize Objects", () => {
|
|
|
559
534
|
});
|
|
560
535
|
|
|
561
536
|
run({
|
|
562
|
-
log: true
|
|
563
|
-
coverage: true
|
|
537
|
+
log: true
|
|
564
538
|
});
|
|
@@ -31,8 +31,8 @@ export function deserializeArray<T extends unknown[]>(data: string): T {
|
|
|
31
31
|
if (isDefined(type.__DESERIALIZE)) {
|
|
32
32
|
return deserializeObjectArray<T>(data);
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
throw new Error("Could not parse array of type " + nameof<T>() + "! Make sure to add the @json decorator over classes!");
|
|
35
35
|
} else {
|
|
36
|
-
|
|
36
|
+
throw new Error("Could not parse array of type " + nameof<T>() + "!");
|
|
37
37
|
}
|
|
38
38
|
}
|
|
@@ -72,6 +72,8 @@ import { deserializeFloat } from "./float";
|
|
|
72
72
|
depth--;
|
|
73
73
|
if (depth === 0) {
|
|
74
74
|
++objectValueIndex;
|
|
75
|
+
console.log("Index: " + nameof<indexof<T>>());
|
|
76
|
+
console.log("Value: " + nameof<valueof<T>>());
|
|
75
77
|
map.set(deserializeMapKey<indexof<T>>(key), JSON.parse<valueof<T>>(data.slice(outerLoopIndex, objectValueIndex)));
|
|
76
78
|
outerLoopIndex = objectValueIndex;
|
|
77
79
|
isKey = false;
|
package/assembly/index.ts
CHANGED
|
@@ -13,198 +13,14 @@ import { deserializeFloat } from "./deserialize/float";
|
|
|
13
13
|
import { deserializeObject } from "./deserialize/object";
|
|
14
14
|
import { deserializeMap } from "./deserialize/map";
|
|
15
15
|
import { deserializeDate } from "./deserialize/date";
|
|
16
|
-
import {
|
|
16
|
+
import { NULL_WORD } from "./chars";
|
|
17
17
|
import { deserializeInteger } from "./deserialize/integer";
|
|
18
18
|
import { deserializeString } from "./deserialize/string";
|
|
19
|
-
import { Sink } from "./sink";
|
|
20
|
-
import { Variant } from "as-variant/assembly";
|
|
21
|
-
import { MpZ } from "@hypercubed/as-mpz";
|
|
22
|
-
import { serializeMpZ } from "./serialize/mpz";
|
|
23
|
-
import { deserializeMpZ } from "./deserialize/mpz";
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Offset of the 'storage' property in the JSON.Value class.
|
|
27
|
-
*/
|
|
28
|
-
// @ts-ignore: Decorator valid here
|
|
29
|
-
const STORAGE = offsetof<JSON.Value>("storage");
|
|
30
19
|
|
|
31
20
|
/**
|
|
32
21
|
* JSON Encoder/Decoder for AssemblyScript
|
|
33
22
|
*/
|
|
34
23
|
export namespace JSON {
|
|
35
|
-
/**
|
|
36
|
-
* Enum representing the different types supported by JSON.
|
|
37
|
-
*/
|
|
38
|
-
export enum Types {
|
|
39
|
-
U8,
|
|
40
|
-
U16,
|
|
41
|
-
U32,
|
|
42
|
-
U64,
|
|
43
|
-
F32,
|
|
44
|
-
F64,
|
|
45
|
-
Bool,
|
|
46
|
-
String,
|
|
47
|
-
ManagedString,
|
|
48
|
-
Struct,
|
|
49
|
-
ManagedStruct,
|
|
50
|
-
Array,
|
|
51
|
-
ManagedArray
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export class Value {
|
|
55
|
-
public type: i32;
|
|
56
|
-
// @ts-ignore: storage is set directly through memory
|
|
57
|
-
private storage: u64;
|
|
58
|
-
|
|
59
|
-
private constructor() { unreachable(); }
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Creates an JSON.Value instance from a given value.
|
|
63
|
-
* @param value - The value to be encapsulated.
|
|
64
|
-
* @returns An instance of JSON.Value.
|
|
65
|
-
*/
|
|
66
|
-
static from<T>(value: T): JSON.Value {
|
|
67
|
-
if (value instanceof Variant) {
|
|
68
|
-
// Handle
|
|
69
|
-
} else if (value instanceof JSON.Value) {
|
|
70
|
-
return value;
|
|
71
|
-
}
|
|
72
|
-
const out = changetype<JSON.Value>(__new(offsetof<JSON.Value>(), idof<JSON.Value>()));
|
|
73
|
-
out.set<T>(value);
|
|
74
|
-
return out;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Sets the value of the JSON.Value instance.
|
|
79
|
-
* @param value - The value to be set.
|
|
80
|
-
*/
|
|
81
|
-
set<T>(value: T): void {
|
|
82
|
-
if (isBoolean<T>()) {
|
|
83
|
-
this.type = JSON.Types.Bool;
|
|
84
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
85
|
-
} else if (value instanceof u8 || value instanceof i8) {
|
|
86
|
-
this.type = JSON.Types.U8;
|
|
87
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
88
|
-
} else if (value instanceof u16 || value instanceof i16) {
|
|
89
|
-
this.type = JSON.Types.U16;
|
|
90
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
91
|
-
} else if (value instanceof u32 || value instanceof i32) {
|
|
92
|
-
this.type = JSON.Types.U32;
|
|
93
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
94
|
-
} else if (value instanceof u64 || value instanceof i64) {
|
|
95
|
-
this.type = JSON.Types.U64;
|
|
96
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
97
|
-
} else if (value instanceof f32) {
|
|
98
|
-
this.type = JSON.Types.F64;
|
|
99
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
100
|
-
} else if (value instanceof f64) {
|
|
101
|
-
this.type = JSON.Types.F64;
|
|
102
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
103
|
-
} else if (isString<T>()) {
|
|
104
|
-
this.type = JSON.Types.String;
|
|
105
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
106
|
-
} else if (value instanceof Map) {
|
|
107
|
-
if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
|
|
108
|
-
throw new Error("Maps must be of type Map<string, JSON.Value>!");
|
|
109
|
-
}
|
|
110
|
-
this.type = JSON.Types.Struct;
|
|
111
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
112
|
-
// @ts-ignore: __SERIALIZE is implemented by the transform
|
|
113
|
-
} else if (isDefined(value.__SERIALIZE)) {
|
|
114
|
-
this.type = JSON.Types.Struct;
|
|
115
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
116
|
-
} else if (isArray<T>()) {
|
|
117
|
-
// @ts-ignore: T satisfies constraints of any[]
|
|
118
|
-
this.type = JSON.Types.Array + getArrayDepth<T>(0);
|
|
119
|
-
store<T>(changetype<usize>(this), value, STORAGE);
|
|
120
|
-
}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
/**
|
|
124
|
-
* Gets the value of the JSON.Value instance.
|
|
125
|
-
* @returns The encapsulated value.
|
|
126
|
-
*/
|
|
127
|
-
unwrap<T>(): T {
|
|
128
|
-
if (isManaged<T>()) {
|
|
129
|
-
if (this.type !== JSON.Types.Struct) throw new Error("Type mismatch");
|
|
130
|
-
if (idof<T>() !== load<u32>(changetype<usize>(this.storage), -8)) throw new Error("Type mismatch");
|
|
131
|
-
}
|
|
132
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Gets the value of the JSON.Value instance.
|
|
137
|
-
* @returns The encapsulated value.
|
|
138
|
-
*/
|
|
139
|
-
unwrapUnsafe<T>(): T {
|
|
140
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Gets the value of the JSON.Value instance.
|
|
145
|
-
* @returns The encapsulated value.
|
|
146
|
-
*/
|
|
147
|
-
get<T>(): T {
|
|
148
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Gets the value of the JSON.Value instance.
|
|
153
|
-
* @returns The encapsulated value.
|
|
154
|
-
*/
|
|
155
|
-
getUnsafe<T>(): T {
|
|
156
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Gets the value of the JSON.Value instance.
|
|
161
|
-
* @returns The encapsulated value.
|
|
162
|
-
*/
|
|
163
|
-
is<T>(): T {
|
|
164
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
/**
|
|
168
|
-
* Gets the value of the JSON.Value instance.
|
|
169
|
-
* @returns The encapsulated value.
|
|
170
|
-
*/
|
|
171
|
-
clone<T>(): T {
|
|
172
|
-
return load<T>(changetype<usize>(this), STORAGE);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
/**
|
|
176
|
-
* Converts the JSON.Value to a string representation.
|
|
177
|
-
* @param useString - If true, treats Buffer as a string.
|
|
178
|
-
* @returns The string representation of the JSON.Value.
|
|
179
|
-
*/
|
|
180
|
-
toString(useString: boolean = false): string {
|
|
181
|
-
switch (this.type) {
|
|
182
|
-
case JSON.Types.U8: return this.get<u8>().toString();
|
|
183
|
-
case JSON.Types.U16: return this.get<u16>().toString();
|
|
184
|
-
case JSON.Types.U32: return this.get<u32>().toString();
|
|
185
|
-
case JSON.Types.U64: return this.get<u64>().toString();
|
|
186
|
-
case JSON.Types.String: return "\"" + this.get<string>() + "\"";
|
|
187
|
-
case JSON.Types.Bool: return this.get<boolean>() ? TRUE_WORD : FALSE_WORD;
|
|
188
|
-
default: {
|
|
189
|
-
const arr = this.get<JSON.Value[]>();
|
|
190
|
-
if (!arr.length) return "[]";
|
|
191
|
-
const out = Sink.fromString("[");
|
|
192
|
-
for (let i = 0; i < arr.length - 1; i++) {
|
|
193
|
-
const element = unchecked(arr[i]);
|
|
194
|
-
out.write(element.toString(useString));
|
|
195
|
-
out.write(",");
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
const element = unchecked(arr[arr.length - 1]);
|
|
199
|
-
out.write(element.toString(useString));
|
|
200
|
-
|
|
201
|
-
out.write("]");
|
|
202
|
-
return out.toString();
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
|
|
208
24
|
export class Box<T> {
|
|
209
25
|
constructor(public value: T) {}
|
|
210
26
|
@inline static from<T>(value: T): Box<T> {
|
|
@@ -236,6 +52,7 @@ export namespace JSON {
|
|
|
236
52
|
// @ts-ignore
|
|
237
53
|
} else if (isString<nonnull<T>>()) {
|
|
238
54
|
return serializeString(changetype<string>(data));
|
|
55
|
+
// @ts-ignore: Supplied by trasnform
|
|
239
56
|
} else if (isDefined(data.__SERIALIZE)) {
|
|
240
57
|
// @ts-ignore
|
|
241
58
|
return serializeObject(changetype<nonnull<T>>(data));
|
|
@@ -248,8 +65,6 @@ export namespace JSON {
|
|
|
248
65
|
} else if (data instanceof Map) {
|
|
249
66
|
// @ts-ignore
|
|
250
67
|
return serializeMap(changetype<nonnull<T>>(data));
|
|
251
|
-
} else if (data instanceof MpZ) {
|
|
252
|
-
return serializeMpZ(data);
|
|
253
68
|
} else {
|
|
254
69
|
throw new Error(
|
|
255
70
|
`Could not serialize data of type ${nameof<T>()}. Make sure to add the correct decorators to classes.`
|
|
@@ -284,16 +99,14 @@ export namespace JSON {
|
|
|
284
99
|
return deserializeArray<nonnull<T>>(data);
|
|
285
100
|
}
|
|
286
101
|
let type: nonnull<T> = changetype<nonnull<T>>(0);
|
|
102
|
+
// @ts-ignore: Defined by trasnform
|
|
287
103
|
if (isDefined(type.__DESERIALIZE)) {
|
|
288
104
|
// @ts-ignore
|
|
289
105
|
return deserializeObject<nonnull<T>>(data.trimStart());
|
|
290
106
|
} else if (type instanceof Map) {
|
|
291
107
|
// @ts-ignore
|
|
292
108
|
return deserializeMap<nonnull<T>>(data.trimStart());
|
|
293
|
-
} else if (type instanceof
|
|
294
|
-
// @ts-ignore
|
|
295
|
-
return deserializeMpZ(data);
|
|
296
|
-
}else if (type instanceof Date) {
|
|
109
|
+
} else if (type instanceof Date) {
|
|
297
110
|
// @ts-ignore
|
|
298
111
|
return deserializeDate(data);
|
|
299
112
|
} else {
|
|
@@ -12,9 +12,7 @@ import { serializeString } from "./string";
|
|
|
12
12
|
|
|
13
13
|
// @ts-ignore: Decorator valid here
|
|
14
14
|
@inline export function serializeArray<T extends any[]>(data: T): string {
|
|
15
|
-
if (
|
|
16
|
-
// @ts-ignore
|
|
17
|
-
else if (data.length == 0) {
|
|
15
|
+
if (data.length == 0) {
|
|
18
16
|
return EMPTY_BRACKET_WORD;
|
|
19
17
|
// @ts-ignore
|
|
20
18
|
} else if (isString<valueof<T>>()) {
|
|
@@ -4,7 +4,6 @@ import { Sink } from "../sink";
|
|
|
4
4
|
|
|
5
5
|
// @ts-ignore: Decorator valid here
|
|
6
6
|
@inline export function serializeMap<T extends Map<any, any>>(data: T): string {
|
|
7
|
-
if (changetype<usize>(data) == <usize>0) return "{}";
|
|
8
7
|
let result = Sink.fromString(BRACE_LEFT_WORD);
|
|
9
8
|
if (!data.size) return "{}";
|
|
10
9
|
let keys = data.keys();
|
package/assembly/test.ts
CHANGED
|
@@ -1,41 +1,38 @@
|
|
|
1
1
|
import { JSON } from ".";
|
|
2
|
-
|
|
3
2
|
@json
|
|
4
|
-
class
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
constructor(id: u64, name: string, uri: string) {
|
|
10
|
-
this.id = id;
|
|
11
|
-
this.name = name;
|
|
12
|
-
this.uri = uri;
|
|
13
|
-
}
|
|
3
|
+
class Vec3 {
|
|
4
|
+
x: f32 = 0.0;
|
|
5
|
+
y: f32 = 0.0;
|
|
6
|
+
z: f32 = 0.0;
|
|
14
7
|
}
|
|
15
8
|
|
|
16
9
|
@json
|
|
17
|
-
class
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
this.balances = new Map<string, u64[]>();
|
|
29
|
-
}
|
|
10
|
+
class Player {
|
|
11
|
+
@alias("first name")
|
|
12
|
+
firstName!: string;
|
|
13
|
+
lastName!: string;
|
|
14
|
+
lastActive!: i32[];
|
|
15
|
+
// Drop in a code block, function, or expression that evaluates to a boolean
|
|
16
|
+
@omitif("this.age < 18")
|
|
17
|
+
age!: i32;
|
|
18
|
+
@omitnull()
|
|
19
|
+
pos!: Vec3 | null;
|
|
20
|
+
isVerified!: boolean;
|
|
30
21
|
}
|
|
31
22
|
|
|
23
|
+
const player: Player = {
|
|
24
|
+
firstName: "Emmet",
|
|
25
|
+
lastName: "West",
|
|
26
|
+
lastActive: [8, 27, 2022],
|
|
27
|
+
age: 23,
|
|
28
|
+
pos: {
|
|
29
|
+
x: 3.4,
|
|
30
|
+
y: 1.2,
|
|
31
|
+
z: 8.3
|
|
32
|
+
},
|
|
33
|
+
isVerified: true
|
|
34
|
+
};
|
|
32
35
|
|
|
33
|
-
|
|
34
|
-
'"{"owner":"","counter":0,"tokens":{},"owners":{},"balances":{}}"'
|
|
35
|
-
);
|
|
36
|
-
// let state = new NonFungibleToken();
|
|
36
|
+
const stringified = JSON.stringify<Player>(player);
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
state.balances.set("bhavya", []);
|
|
40
|
-
}
|
|
41
|
-
console.log(JSON.stringify(state))
|
|
38
|
+
const parsed = JSON.parse<Player>(stringified);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "json-as",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.11",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
],
|
|
16
16
|
"license": "MIT",
|
|
17
17
|
"scripts": {
|
|
18
|
-
"test": "
|
|
19
|
-
"pretest": "
|
|
20
|
-
"build:test": "JSON_DEBUG=true asc assembly/test.ts --
|
|
18
|
+
"test": "ast test",
|
|
19
|
+
"pretest": "rm -rf ./build/ && ast build",
|
|
20
|
+
"build:test": "rm -rf ./build/ && JSON_DEBUG=true asc assembly/test.ts --transform ./transform -o ./build/test.wasm",
|
|
21
21
|
"build:bench": "asc bench/benchmark.ts -o bench/benchmark.wasm --transform ./transform --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub",
|
|
22
22
|
"bench:wasmtime": "wasmtime ./bench/benchmark.wasm",
|
|
23
23
|
"bench:wasmer": "wasmer --llvm ./bench/benchmark.wasm",
|
|
@@ -32,22 +32,17 @@
|
|
|
32
32
|
"@assemblyscript/wasi-shim": "^0.1.0",
|
|
33
33
|
"as-bench": "^0.0.0-alpha",
|
|
34
34
|
"as-console": "^7.0.0",
|
|
35
|
+
"as-test": "0.1.7",
|
|
35
36
|
"assemblyscript": "^0.27.28",
|
|
36
37
|
"assemblyscript-prettier": "^3.0.1",
|
|
37
38
|
"benchmark": "^2.1.4",
|
|
38
|
-
"json-as": "link:json-as",
|
|
39
39
|
"microtime": "^3.1.1",
|
|
40
40
|
"prettier": "^3.3.2",
|
|
41
41
|
"tinybench": "^2.8.0",
|
|
42
42
|
"typescript": "^5.5.3",
|
|
43
43
|
"visitor-as": "^0.11.4"
|
|
44
44
|
},
|
|
45
|
-
"dependencies": {
|
|
46
|
-
"@hypercubed/as-mpz": "^2.2.0",
|
|
47
|
-
"as-string-sink": "^0.5.3",
|
|
48
|
-
"as-test": "^0.1.4",
|
|
49
|
-
"as-virtual": "^0.2.0"
|
|
50
|
-
},
|
|
45
|
+
"dependencies": { "as-virtual": "^0.2.0" },
|
|
51
46
|
"overrides": {
|
|
52
47
|
"assemblyscript": "$assemblyscript"
|
|
53
48
|
},
|
|
@@ -61,7 +56,11 @@
|
|
|
61
56
|
"serialize",
|
|
62
57
|
"deserialize",
|
|
63
58
|
"dynamic",
|
|
64
|
-
"serde"
|
|
59
|
+
"serde",
|
|
60
|
+
"SIMD",
|
|
61
|
+
"optimized",
|
|
62
|
+
"fast",
|
|
63
|
+
"algorithm"
|
|
65
64
|
],
|
|
66
65
|
"bugs": {
|
|
67
66
|
"url": "https://github.com/JairusSW/as-json/issues"
|
package/transform/lib/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { FieldDeclaration } from "assemblyscript/dist/assemblyscript.js";
|
|
2
1
|
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
3
2
|
import { BaseVisitor, SimpleParser } from "visitor-as/dist/index.js";
|
|
4
3
|
import { Transform } from "assemblyscript/dist/transform.js";
|
|
@@ -26,7 +25,7 @@ class JSONTransform extends BaseVisitor {
|
|
|
26
25
|
schema.node = node;
|
|
27
26
|
schema.name = node.name.text;
|
|
28
27
|
const members = [
|
|
29
|
-
...node.members.filter(v => v
|
|
28
|
+
...node.members.filter(v => v.kind === 54 /* NodeKind.FieldDeclaration */)
|
|
30
29
|
];
|
|
31
30
|
if (node.extendsType) {
|
|
32
31
|
schema.parent = this.schemasList.find((v) => v.name == node.extendsType?.name.identifier.text);
|
|
@@ -63,8 +62,6 @@ class JSONTransform extends BaseVisitor {
|
|
|
63
62
|
this.schemasList.push(schema);
|
|
64
63
|
}
|
|
65
64
|
for (const member of members) {
|
|
66
|
-
if (!(member instanceof FieldDeclaration))
|
|
67
|
-
continue;
|
|
68
65
|
const name = member.name;
|
|
69
66
|
if (!member.type) {
|
|
70
67
|
throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
|
|
@@ -159,8 +156,22 @@ class JSONTransform extends BaseVisitor {
|
|
|
159
156
|
else if (t === "Array") {
|
|
160
157
|
mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
161
158
|
}
|
|
162
|
-
else {
|
|
163
|
-
|
|
159
|
+
else if (t === "bool" || t === "boolean") {
|
|
160
|
+
mem.initialize = "this." + name.text + " = false";
|
|
161
|
+
}
|
|
162
|
+
else if (t === "u8" ||
|
|
163
|
+
t === "u16" ||
|
|
164
|
+
t === "u32" ||
|
|
165
|
+
t === "u64" ||
|
|
166
|
+
t === "i8" ||
|
|
167
|
+
t === "i16" ||
|
|
168
|
+
t === "i32" ||
|
|
169
|
+
t === "i64") {
|
|
170
|
+
mem.initialize = "this." + name.text + " = 0";
|
|
171
|
+
}
|
|
172
|
+
else if (t === "f32" ||
|
|
173
|
+
t === "f64") {
|
|
174
|
+
mem.initialize = "this." + name.text + " = 0.0";
|
|
164
175
|
}
|
|
165
176
|
schema.members.push(mem);
|
|
166
177
|
}
|
package/transform/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@json-as/transform",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.11",
|
|
4
4
|
"description": "JSON encoder/decoder for AssemblyScript",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -12,9 +12,7 @@
|
|
|
12
12
|
"lekiano"
|
|
13
13
|
],
|
|
14
14
|
"license": "MIT",
|
|
15
|
-
"devDependencies": {
|
|
16
|
-
"assemblyscript": "^0.27.1"
|
|
17
|
-
},
|
|
15
|
+
"devDependencies": {},
|
|
18
16
|
"dependencies": {},
|
|
19
17
|
"repository": {
|
|
20
18
|
"type": "git",
|
package/transform/src/index.ts
CHANGED
|
@@ -5,7 +5,8 @@ import {
|
|
|
5
5
|
NamedTypeNode,
|
|
6
6
|
StringLiteralExpression,
|
|
7
7
|
Parser,
|
|
8
|
-
Source
|
|
8
|
+
Source,
|
|
9
|
+
NodeKind
|
|
9
10
|
} from "assemblyscript/dist/assemblyscript.js";
|
|
10
11
|
|
|
11
12
|
import { toString, isStdlib } from "visitor-as/dist/utils.js";
|
|
@@ -38,7 +39,7 @@ class JSONTransform extends BaseVisitor {
|
|
|
38
39
|
schema.name = node.name.text;
|
|
39
40
|
|
|
40
41
|
const members = [
|
|
41
|
-
...node.members.filter(v => v
|
|
42
|
+
...node.members.filter(v => v.kind === NodeKind.FieldDeclaration)
|
|
42
43
|
];
|
|
43
44
|
|
|
44
45
|
if (node.extendsType) {
|
|
@@ -86,7 +87,6 @@ class JSONTransform extends BaseVisitor {
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
for (const member of members) {
|
|
89
|
-
if (!(member instanceof FieldDeclaration)) continue;
|
|
90
90
|
const name = member.name;
|
|
91
91
|
if (!member.type) {
|
|
92
92
|
throw new Error("Fields must be strongly typed! Found " + toString(member) + " at " + node.range.source.normalizedPath);
|
|
@@ -170,8 +170,24 @@ class JSONTransform extends BaseVisitor {
|
|
|
170
170
|
mem.initialize = "this." + name.text + " = \"\"";
|
|
171
171
|
} else if (t === "Array") {
|
|
172
172
|
mem.initialize = "this." + name.text + " = instantiate<" + mem.type + ">()";
|
|
173
|
-
} else {
|
|
174
|
-
|
|
173
|
+
} else if (t === "bool" || t === "boolean") {
|
|
174
|
+
mem.initialize = "this." + name.text + " = false";
|
|
175
|
+
} else if (
|
|
176
|
+
t === "u8" ||
|
|
177
|
+
t === "u16" ||
|
|
178
|
+
t === "u32" ||
|
|
179
|
+
t === "u64" ||
|
|
180
|
+
t === "i8" ||
|
|
181
|
+
t === "i16" ||
|
|
182
|
+
t === "i32" ||
|
|
183
|
+
t === "i64"
|
|
184
|
+
) {
|
|
185
|
+
mem.initialize = "this." + name.text + " = 0";
|
|
186
|
+
} else if (
|
|
187
|
+
t === "f32" ||
|
|
188
|
+
t === "f64"
|
|
189
|
+
) {
|
|
190
|
+
mem.initialize = "this." + name.text + " = 0.0";
|
|
175
191
|
}
|
|
176
192
|
|
|
177
193
|
schema.members.push(mem);
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { MpZ } from "@hypercubed/as-mpz";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Deserialize a string to type MpZ
|
|
5
|
-
* @param data data to parse
|
|
6
|
-
* @returns MpZ
|
|
7
|
-
*/
|
|
8
|
-
// @ts-ignore: Decorator valid here
|
|
9
|
-
@inline export function deserializeMpZ(data: string, start: i32 = 0, end: i32 = 0): MpZ {
|
|
10
|
-
if (!end) end = data.length;
|
|
11
|
-
return MpZ.from(data.slice(start, end));
|
|
12
|
-
}
|