json-as 0.8.6 → 0.8.8
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/CHANGELOG +2 -1
- package/assembly/__benches__/as-json.ts +1 -1
- package/assembly/deserialize/array/array.ts +31 -0
- package/assembly/deserialize/array/bool.ts +19 -0
- package/assembly/deserialize/array/float.ts +24 -0
- package/assembly/deserialize/array/integer.ts +24 -0
- package/assembly/deserialize/array/map.ts +27 -0
- package/assembly/deserialize/array/object.ts +27 -0
- package/assembly/deserialize/array/string.ts +29 -0
- package/assembly/deserialize/array.ts +37 -0
- package/assembly/deserialize/bool.ts +18 -0
- package/assembly/deserialize/box.ts +14 -0
- package/assembly/deserialize/date.ts +11 -0
- package/assembly/deserialize/float.ts +9 -0
- package/assembly/deserialize/integer.ts +7 -0
- package/assembly/deserialize/map.ts +182 -0
- package/assembly/deserialize/object.ts +139 -0
- package/assembly/deserialize/string.ts +88 -0
- package/assembly/serialize/array.ts +51 -0
- package/assembly/serialize/bool.ts +4 -0
- package/assembly/serialize/box.ts +10 -0
- package/assembly/serialize/date.ts +4 -0
- package/assembly/serialize/float.ts +4 -0
- package/assembly/serialize/integer.ts +5 -0
- package/assembly/serialize/map.ts +24 -0
- package/assembly/serialize/object.ts +7 -0
- package/assembly/serialize/string.ts +64 -0
- package/assembly/src/json.ts +55 -872
- package/assembly/src/sink.ts +286 -0
- package/assembly/src/util.ts +6 -0
- package/assembly/test.ts +8 -1
- package/package.json +1 -1
- package/transform/lib/index.js +3 -3
- package/transform/package.json +1 -1
- package/transform/src/index.ts +3 -3
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { itoa_buffered, dtoa_buffered } from "util/number";
|
|
2
|
+
|
|
3
|
+
const MIN_BUFFER_LEN = 32;
|
|
4
|
+
const MIN_BUFFER_SIZE: u32 = MIN_BUFFER_LEN << 1;
|
|
5
|
+
|
|
6
|
+
const NEW_LINE_CHAR: u16 = 0x0A; // \n
|
|
7
|
+
|
|
8
|
+
// @ts-ignore: decorator
|
|
9
|
+
@inline function nextPowerOf2(n: u32): u32 {
|
|
10
|
+
return 1 << 32 - clz(n - 1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export class Sink {
|
|
14
|
+
public buffer!: ArrayBuffer;
|
|
15
|
+
public offset: u32 = 0;
|
|
16
|
+
|
|
17
|
+
static withCapacity(capacity: i32): Sink {
|
|
18
|
+
const sink = new Sink();
|
|
19
|
+
sink.buffer = changetype<ArrayBuffer>(__new(
|
|
20
|
+
max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1),
|
|
21
|
+
idof<ArrayBuffer>())
|
|
22
|
+
);
|
|
23
|
+
return sink;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
static fromString(initial: string = "", capacity: i32 = MIN_BUFFER_LEN): Sink {
|
|
27
|
+
const sink = new Sink();
|
|
28
|
+
const size = <u32>initial.length << 1;
|
|
29
|
+
sink.buffer = changetype<ArrayBuffer>(__new(
|
|
30
|
+
max<u32>(size, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1)),
|
|
31
|
+
idof<ArrayBuffer>())
|
|
32
|
+
);
|
|
33
|
+
if (size) {
|
|
34
|
+
memory.copy(
|
|
35
|
+
changetype<usize>(sink.buffer),
|
|
36
|
+
changetype<usize>(initial),
|
|
37
|
+
size
|
|
38
|
+
);
|
|
39
|
+
sink.offset += size;
|
|
40
|
+
}
|
|
41
|
+
return sink;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static fromStringLiteral(initial: string = ""): Sink {
|
|
45
|
+
const sink = new Sink();
|
|
46
|
+
const size = <u32>initial.length << 1;
|
|
47
|
+
sink.buffer = changetype<ArrayBuffer>(__new(
|
|
48
|
+
size,
|
|
49
|
+
idof<ArrayBuffer>())
|
|
50
|
+
);
|
|
51
|
+
if (size) {
|
|
52
|
+
memory.copy(
|
|
53
|
+
changetype<usize>(sink.buffer),
|
|
54
|
+
changetype<usize>(initial),
|
|
55
|
+
size
|
|
56
|
+
);
|
|
57
|
+
sink.offset += size;
|
|
58
|
+
}
|
|
59
|
+
return sink;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
static fromBuffer(initial: ArrayBuffer, capacity: i32 = MIN_BUFFER_LEN): Sink {
|
|
63
|
+
const sink = new Sink();
|
|
64
|
+
const size = <u32>initial.byteLength;
|
|
65
|
+
sink.buffer = changetype<ArrayBuffer>(__new(
|
|
66
|
+
max<u32>(size, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1)),
|
|
67
|
+
idof<ArrayBuffer>())
|
|
68
|
+
);
|
|
69
|
+
if (size) {
|
|
70
|
+
memory.copy(
|
|
71
|
+
changetype<usize>(sink.buffer),
|
|
72
|
+
changetype<usize>(initial),
|
|
73
|
+
size
|
|
74
|
+
);
|
|
75
|
+
sink.offset = size;
|
|
76
|
+
}
|
|
77
|
+
return sink;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
constructor() { }
|
|
81
|
+
|
|
82
|
+
@inline get length(): i32 {
|
|
83
|
+
return this.offset >> 1;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
@inline get capacity(): i32 {
|
|
87
|
+
return this.buffer.byteLength >>> 1;
|
|
88
|
+
}
|
|
89
|
+
@inline reset(): void {
|
|
90
|
+
this.offset = 0;
|
|
91
|
+
}
|
|
92
|
+
@inline write(src: string, start: i32 = 0, end: i32 = i32.MAX_VALUE): Sink | null {
|
|
93
|
+
let len = src.length as u32;
|
|
94
|
+
|
|
95
|
+
if (start != 0 || end != i32.MAX_VALUE) {
|
|
96
|
+
let from: i32;
|
|
97
|
+
from = min<i32>(max(start, 0), len);
|
|
98
|
+
end = min<i32>(max(end, 0), len);
|
|
99
|
+
start = min<i32>(from, end);
|
|
100
|
+
end = max<i32>(from, end);
|
|
101
|
+
len = end - start;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (!len) return null;
|
|
105
|
+
|
|
106
|
+
let size = len << 1;
|
|
107
|
+
this.ensureCapacity(size);
|
|
108
|
+
let offset = this.offset;
|
|
109
|
+
|
|
110
|
+
memory.copy(
|
|
111
|
+
changetype<usize>(this.buffer) + offset,
|
|
112
|
+
changetype<usize>(src) + (<usize>start << 1),
|
|
113
|
+
size
|
|
114
|
+
);
|
|
115
|
+
this.offset = offset + size;
|
|
116
|
+
return this;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
@inline writeLn(src: string = "", start: i32 = 0, end: i32 = i32.MAX_VALUE): Sink {
|
|
120
|
+
let len = src.length as u32;
|
|
121
|
+
if (start != 0 || end != i32.MAX_VALUE) {
|
|
122
|
+
let from: i32;
|
|
123
|
+
from = min<i32>(max(start, 0), len);
|
|
124
|
+
end = min<i32>(max(end, 0), len);
|
|
125
|
+
start = min<i32>(from, end);
|
|
126
|
+
end = max<i32>(from, end);
|
|
127
|
+
len = end - start;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let size = len << 1;
|
|
131
|
+
this.ensureCapacity(size + 2);
|
|
132
|
+
let offset = this.offset;
|
|
133
|
+
let dest = changetype<usize>(this.buffer) + offset;
|
|
134
|
+
if (size) memory.copy(dest, changetype<usize>(src) + (<usize>start << 1), size);
|
|
135
|
+
store<u16>(dest + size, NEW_LINE_CHAR);
|
|
136
|
+
this.offset = offset + (size + 2);
|
|
137
|
+
return this;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
@inline writeCodePoint(code: i32): Sink {
|
|
141
|
+
let hasSur = <u32>code > 0xFFFF;
|
|
142
|
+
this.ensureCapacity(2 << i32(hasSur));
|
|
143
|
+
|
|
144
|
+
let offset = this.offset;
|
|
145
|
+
let dest = changetype<usize>(this.buffer) + offset;
|
|
146
|
+
|
|
147
|
+
if (!hasSur) {
|
|
148
|
+
store<u16>(dest, <u16>code);
|
|
149
|
+
this.offset = offset + 2;
|
|
150
|
+
} else {
|
|
151
|
+
assert(<u32>code <= 0x10FFFF);
|
|
152
|
+
code -= 0x10000;
|
|
153
|
+
let hi = (code & 0x03FF) | 0xDC00;
|
|
154
|
+
let lo = code >>> 10 | 0xD800;
|
|
155
|
+
store<u32>(dest, lo | hi << 16);
|
|
156
|
+
this.offset = offset + 4;
|
|
157
|
+
}
|
|
158
|
+
return this;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@inline writeCodePoint16(code: i32): Sink {
|
|
162
|
+
this.ensureCapacity(2);
|
|
163
|
+
|
|
164
|
+
let offset = this.offset;
|
|
165
|
+
let dest = changetype<usize>(this.buffer) + offset;
|
|
166
|
+
|
|
167
|
+
store<u16>(dest, <u16>code);
|
|
168
|
+
this.offset = offset + 2;
|
|
169
|
+
|
|
170
|
+
return this;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
@inline writeCodePointUnsafe(code: i32): Sink {
|
|
174
|
+
this.ensureCapacity(2);
|
|
175
|
+
|
|
176
|
+
let offset = this.offset;
|
|
177
|
+
let dest = changetype<usize>(this.buffer) + offset;
|
|
178
|
+
|
|
179
|
+
code -= 0x10000;
|
|
180
|
+
let hi = (code & 0x03FF) | 0xDC00;
|
|
181
|
+
let lo = code >>> 10 | 0xD800;
|
|
182
|
+
store<u32>(dest, lo | hi << 16);
|
|
183
|
+
this.offset = offset + 4;
|
|
184
|
+
return this;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
@inline writeNumber<T extends number>(value: T): Sink {
|
|
188
|
+
let offset = this.offset;
|
|
189
|
+
if (isInteger<T>()) {
|
|
190
|
+
let maxCapacity = 0;
|
|
191
|
+
// this also include size for sign
|
|
192
|
+
if (sizeof<T>() == 1) {
|
|
193
|
+
maxCapacity = 4 << 1;
|
|
194
|
+
} else if (sizeof<T>() == 2) {
|
|
195
|
+
maxCapacity = 6 << 1;
|
|
196
|
+
} else if (sizeof<T>() == 4) {
|
|
197
|
+
maxCapacity = 11 << 1;
|
|
198
|
+
} else if (sizeof<T>() == 8) {
|
|
199
|
+
maxCapacity = 21 << 1;
|
|
200
|
+
}
|
|
201
|
+
this.ensureCapacity(maxCapacity);
|
|
202
|
+
offset += itoa_buffered(
|
|
203
|
+
changetype<usize>(this.buffer) + offset,
|
|
204
|
+
value
|
|
205
|
+
) << 1;
|
|
206
|
+
} else {
|
|
207
|
+
this.ensureCapacity(32 << 1);
|
|
208
|
+
offset += dtoa_buffered(
|
|
209
|
+
changetype<usize>(this.buffer) + offset,
|
|
210
|
+
value
|
|
211
|
+
) << 1;
|
|
212
|
+
}
|
|
213
|
+
this.offset = offset;
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
@inline writeNumberUnsafe<T extends number>(value: T): Sink {
|
|
217
|
+
let offset = this.offset;
|
|
218
|
+
if (isInteger<T>()) {
|
|
219
|
+
offset += itoa_buffered(
|
|
220
|
+
changetype<usize>(this.buffer) + offset,
|
|
221
|
+
value
|
|
222
|
+
) << 1;
|
|
223
|
+
} else {
|
|
224
|
+
offset += dtoa_buffered(
|
|
225
|
+
changetype<usize>(this.buffer) + offset,
|
|
226
|
+
value
|
|
227
|
+
) << 1;
|
|
228
|
+
}
|
|
229
|
+
this.offset = offset;
|
|
230
|
+
return this;
|
|
231
|
+
}
|
|
232
|
+
@inline writeIntegerUnsafe<T extends number>(value: T): Sink {
|
|
233
|
+
let offset = this.offset;
|
|
234
|
+
if (isInteger<T>()) {
|
|
235
|
+
offset += itoa_buffered(
|
|
236
|
+
changetype<usize>(this.buffer) + offset,
|
|
237
|
+
value
|
|
238
|
+
) << 1;
|
|
239
|
+
} else {
|
|
240
|
+
offset += dtoa_buffered(
|
|
241
|
+
changetype<usize>(this.buffer) + offset,
|
|
242
|
+
value
|
|
243
|
+
) << 1;
|
|
244
|
+
}
|
|
245
|
+
this.offset = offset;
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
@inline reserve(capacity: i32, clear: bool = false): void {
|
|
250
|
+
if (clear) this.offset = 0;
|
|
251
|
+
this.buffer = changetype<ArrayBuffer>(__renew(
|
|
252
|
+
changetype<usize>(this.buffer),
|
|
253
|
+
max<u32>(this.offset, max<u32>(MIN_BUFFER_SIZE, <u32>capacity << 1))
|
|
254
|
+
));
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
@inline shrink(): void {
|
|
258
|
+
this.buffer = changetype<ArrayBuffer>(__renew(
|
|
259
|
+
changetype<usize>(this.buffer),
|
|
260
|
+
max<u32>(this.offset, MIN_BUFFER_SIZE)
|
|
261
|
+
));
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
@inline clear(): void {
|
|
265
|
+
this.reserve(0, true);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
@inline toString(): string {
|
|
269
|
+
let size = this.offset;
|
|
270
|
+
if (!size) return "";
|
|
271
|
+
let out = changetype<string>(__new(size, idof<string>()));
|
|
272
|
+
memory.copy(changetype<usize>(out), changetype<usize>(this.buffer), size);
|
|
273
|
+
return out;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
@inline ensureCapacity(deltaBytes: u32): void {
|
|
277
|
+
let buffer = this.buffer;
|
|
278
|
+
let newSize = this.offset + deltaBytes;
|
|
279
|
+
if (newSize > <u32>buffer.byteLength) {
|
|
280
|
+
this.buffer = changetype<ArrayBuffer>(__renew(
|
|
281
|
+
changetype<usize>(buffer),
|
|
282
|
+
nextPowerOf2(newSize)
|
|
283
|
+
));
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
package/assembly/src/util.ts
CHANGED
|
@@ -2,6 +2,12 @@ import { StringSink } from "as-string-sink/assembly";
|
|
|
2
2
|
import { isSpace } from "util/string";
|
|
3
3
|
import { backSlashCode, quoteCode } from "./chars";
|
|
4
4
|
|
|
5
|
+
// @ts-ignore: Decorator
|
|
6
|
+
@inline export function isMap<T>(): bool {
|
|
7
|
+
let type = changetype<T>(0);
|
|
8
|
+
return type instanceof Map;
|
|
9
|
+
}
|
|
10
|
+
|
|
5
11
|
// @ts-ignore: Decorator
|
|
6
12
|
@inline export function unsafeCharCodeAt(data: string, pos: i32): i32 {
|
|
7
13
|
return load<u16>(changetype<usize>(data) + ((<usize>pos) << 1));
|
package/assembly/test.ts
CHANGED
|
@@ -9,11 +9,18 @@ class Foo {
|
|
|
9
9
|
tristateValue: Box<bool> | null = null;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
@json
|
|
13
|
+
class TestBody {
|
|
14
|
+
a!: string;
|
|
15
|
+
b!: u8;
|
|
16
|
+
}
|
|
17
|
+
|
|
12
18
|
const foo: Foo = {
|
|
13
19
|
optionalNumber: null,
|
|
14
20
|
tristateValue: Box.from(true)
|
|
15
21
|
}
|
|
16
|
-
|
|
22
|
+
console.log(JSON.stringify(JSON.parse<TestBody[]>('[{"a":"hi","b":5},{"a":"bye","b":6}]')))
|
|
23
|
+
console.log(JSON.stringify([foo, foo]))
|
|
17
24
|
console.log(JSON.stringify(foo));
|
|
18
25
|
|
|
19
26
|
const p1 = JSON.parse<Box<i32> | null>("null");
|
package/package.json
CHANGED
package/transform/lib/index.js
CHANGED
|
@@ -39,7 +39,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
39
39
|
return;
|
|
40
40
|
// Prevent from being triggered twice.
|
|
41
41
|
for (const member of node.members) {
|
|
42
|
-
if (member.name.text == "
|
|
42
|
+
if (member.name.text == "__SERIALIZE")
|
|
43
43
|
return;
|
|
44
44
|
}
|
|
45
45
|
this.currentClass = {
|
|
@@ -151,13 +151,13 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
151
151
|
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
152
152
|
stmt.slice(0, stmt.length - 1);
|
|
153
153
|
serializeFunc = `
|
|
154
|
-
|
|
154
|
+
__SERIALIZE(): string {
|
|
155
155
|
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
156
156
|
}`;
|
|
157
157
|
}
|
|
158
158
|
else {
|
|
159
159
|
serializeFunc = `
|
|
160
|
-
|
|
160
|
+
__SERIALIZE(): string {
|
|
161
161
|
return "{}";
|
|
162
162
|
}`;
|
|
163
163
|
}
|
package/transform/package.json
CHANGED
package/transform/src/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
46
46
|
|
|
47
47
|
// Prevent from being triggered twice.
|
|
48
48
|
for (const member of node.members) {
|
|
49
|
-
if (member.name.text == "
|
|
49
|
+
if (member.name.text == "__SERIALIZE") return;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
this.currentClass = {
|
|
@@ -194,12 +194,12 @@ class AsJSONTransform extends BaseVisitor {
|
|
|
194
194
|
this.currentClass.encodeStmts[this.currentClass.encodeStmts.length - 1] =
|
|
195
195
|
stmt!.slice(0, stmt.length - 1);
|
|
196
196
|
serializeFunc = `
|
|
197
|
-
|
|
197
|
+
__SERIALIZE(): string {
|
|
198
198
|
return \`{${this.currentClass.encodeStmts.join("")}}\`;
|
|
199
199
|
}`;
|
|
200
200
|
} else {
|
|
201
201
|
serializeFunc = `
|
|
202
|
-
|
|
202
|
+
__SERIALIZE(): string {
|
|
203
203
|
return "{}";
|
|
204
204
|
}`;
|
|
205
205
|
}
|