json-as 1.0.0-alpha.4 → 1.0.0-beta.10

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.
Files changed (79) hide show
  1. package/.trunk/configs/.markdownlint.yaml +2 -0
  2. package/.trunk/configs/.shellcheckrc +7 -0
  3. package/.trunk/configs/.yamllint.yaml +7 -0
  4. package/.trunk/trunk.yaml +37 -0
  5. package/CHANGELOG +60 -0
  6. package/README.md +303 -48
  7. package/assembly/__benches__/misc.bench.ts +47 -0
  8. package/assembly/__benches__/schemas.ts +25 -0
  9. package/assembly/__benches__/string.bench.ts +23 -0
  10. package/assembly/__benches__/struct.bench.ts +21 -0
  11. package/assembly/__tests__/arbitrary.spec.ts +19 -0
  12. package/assembly/__tests__/array.spec.ts +42 -1
  13. package/assembly/__tests__/bool.spec.ts +1 -1
  14. package/assembly/__tests__/box.spec.ts +1 -1
  15. package/assembly/__tests__/custom.spec.ts +42 -0
  16. package/assembly/__tests__/date.spec.ts +1 -1
  17. package/assembly/__tests__/float.spec.ts +4 -4
  18. package/assembly/__tests__/integer.spec.ts +1 -1
  19. package/assembly/__tests__/null.spec.ts +1 -1
  20. package/assembly/__tests__/raw.spec.ts +23 -0
  21. package/assembly/__tests__/string.spec.ts +1 -1
  22. package/assembly/__tests__/{obj.spec.ts → struct.spec.ts} +18 -4
  23. package/assembly/__tests__/test.spec.ts +1 -1
  24. package/assembly/__tests__/types.ts +3 -3
  25. package/assembly/as-bs.d.ts +53 -0
  26. package/assembly/custom/bench.ts +26 -0
  27. package/assembly/deserialize/simd/string.ts +1 -1
  28. package/assembly/deserialize/simple/arbitrary.ts +1 -1
  29. package/assembly/deserialize/simple/array/arbitrary.ts +46 -24
  30. package/assembly/deserialize/simple/array/array.ts +4 -3
  31. package/assembly/deserialize/simple/array/bool.ts +7 -7
  32. package/assembly/deserialize/simple/array/float.ts +1 -1
  33. package/assembly/deserialize/simple/array/integer.ts +1 -1
  34. package/assembly/deserialize/simple/array/map.ts +1 -1
  35. package/assembly/deserialize/simple/array/string.ts +3 -3
  36. package/assembly/deserialize/simple/array/struct.ts +29 -0
  37. package/assembly/deserialize/simple/array.ts +7 -9
  38. package/assembly/deserialize/simple/integer.ts +2 -1
  39. package/assembly/deserialize/simple/map.ts +92 -67
  40. package/assembly/deserialize/simple/object.ts +14 -19
  41. package/assembly/deserialize/simple/raw.ts +6 -0
  42. package/assembly/deserialize/simple/struct.ts +171 -0
  43. package/assembly/index.d.ts +15 -1
  44. package/assembly/index.ts +202 -25
  45. package/assembly/serialize/simd/string.ts +0 -1
  46. package/assembly/serialize/simple/arbitrary.ts +15 -2
  47. package/assembly/serialize/simple/array.ts +0 -1
  48. package/assembly/serialize/simple/bool.ts +0 -2
  49. package/assembly/serialize/simple/date.ts +0 -1
  50. package/assembly/serialize/simple/float.ts +0 -1
  51. package/assembly/serialize/simple/integer.ts +0 -1
  52. package/assembly/serialize/simple/map.ts +0 -1
  53. package/assembly/serialize/simple/object.ts +42 -6
  54. package/assembly/serialize/simple/raw.ts +14 -0
  55. package/assembly/serialize/simple/string.ts +0 -1
  56. package/assembly/serialize/simple/struct.ts +7 -0
  57. package/assembly/test.ts +80 -13
  58. package/assembly/util/atoi.ts +1 -1
  59. package/bench/bench.ts +15 -0
  60. package/bench/schemas.ts +5 -0
  61. package/bench/string.bench.ts +16 -0
  62. package/bench.js +11 -2
  63. package/index.ts +1 -1
  64. package/{modules/as-bs/assembly/index.ts → lib/as-bs.ts} +3 -3
  65. package/lib/tsconfig.json +8 -0
  66. package/package.json +10 -6
  67. package/run-tests.sh +1 -1
  68. package/transform/lib/index.js +124 -55
  69. package/transform/lib/index.js.map +1 -1
  70. package/transform/src/index.ts +141 -62
  71. package/.gitmodules +0 -0
  72. package/as-test.config.json +0 -18
  73. package/assembly/deserialize/simple/array/object.ts +0 -18
  74. package/modules/as-bs/LICENSE +0 -21
  75. package/modules/as-bs/README.md +0 -95
  76. package/modules/as-bs/assembly/tsconfig.json +0 -97
  77. package/modules/as-bs/index.ts +0 -1
  78. package/modules/as-bs/package.json +0 -32
  79. /package/{modules/test/assembly → assembly/__tests__/lib}/index.ts +0 -0
package/assembly/index.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  /// <reference path="./index.d.ts" />
2
- import { bs } from "../modules/as-bs";
3
2
 
4
3
  import { serializeString } from "./serialize/simple/string";
5
4
  import { serializeArray } from "./serialize/simple/array";
@@ -7,7 +6,7 @@ import { serializeMap } from "./serialize/simple/map";
7
6
  import { deserializeBoolean } from "./deserialize/simple/bool";
8
7
  import { deserializeArray } from "./deserialize/simple/array";
9
8
  import { deserializeFloat } from "./deserialize/simple/float";
10
- import { deserializeObject } from "./deserialize/simple/object";
9
+ import { deserializeStruct } from "./deserialize/simple/struct";
11
10
  import { deserializeMap } from "./deserialize/simple/map";
12
11
  import { deserializeDate } from "./deserialize/simple/date";
13
12
  import { deserializeInteger } from "./deserialize/simple/integer";
@@ -20,11 +19,14 @@ import { dtoa_buffered, itoa_buffered } from "util/number";
20
19
  import { serializeBool } from "./serialize/simple/bool";
21
20
  import { serializeInteger } from "./serialize/simple/integer";
22
21
  import { serializeFloat } from "./serialize/simple/float";
23
- import { serializeObject } from "./serialize/simple/object";
22
+ import { serializeStruct } from "./serialize/simple/struct";
24
23
  import { ptrToStr } from "./util/ptrToStr";
25
- import { bytes } from "./util";
26
-
27
- export type Raw = string;
24
+ import { atoi, bytes } from "./util";
25
+ import { deserializeArbitrary } from "./deserialize/simple/arbitrary";
26
+ import { serializeObject } from "./serialize/simple/object";
27
+ import { deserializeObject } from "./deserialize/simple/object";
28
+ import { serializeRaw } from "./serialize/simple/raw";
29
+ import { deserializeRaw } from "./deserialize/simple/raw";
28
30
 
29
31
  /**
30
32
  * Offset of the 'storage' property in the JSON.Value class.
@@ -49,7 +51,8 @@ export namespace JSON {
49
51
  * @param data T
50
52
  * @returns string
51
53
  */
52
- export function stringify<T>(data: T, out: string | null = null): string {
54
+ // @ts-ignore: inline
55
+ @inline export function stringify<T>(data: T, out: string | null = null): string {
53
56
  if (isBoolean<T>()) {
54
57
  if (out) {
55
58
  if (<bool>data == true) {
@@ -112,6 +115,11 @@ export namespace JSON {
112
115
  serializeString(changetype<string>(data));
113
116
  return bs.out<string>();
114
117
  // @ts-ignore: Supplied by transform
118
+ } else if (isDefined(data.__SERIALIZE_CUSTOM)) {
119
+ // @ts-ignore
120
+ data.__SERIALIZE_CUSTOM(changetype<usize>(data));
121
+ return bs.out<string>();
122
+ // @ts-ignore: Supplied by transform
115
123
  } else if (isDefined(data.__SERIALIZE)) {
116
124
  // @ts-ignore
117
125
  data.__SERIALIZE(changetype<usize>(data));
@@ -132,9 +140,15 @@ export namespace JSON {
132
140
  // @ts-ignore
133
141
  serializeMap(changetype<nonnull<T>>(data));
134
142
  return bs.out<string>();
143
+ } else if (data instanceof JSON.Raw) {
144
+ serializeRaw(data);
145
+ return bs.out<string>();
135
146
  } else if (data instanceof JSON.Value) {
136
147
  serializeArbitrary(data);
137
148
  return bs.out<string>();
149
+ } else if (data instanceof JSON.Obj) {
150
+ serializeObject(data);
151
+ return bs.out<string>();
138
152
  } else if (data instanceof JSON.Box) {
139
153
  return JSON.stringify(data.value);
140
154
  } else {
@@ -150,7 +164,8 @@ export namespace JSON {
150
164
  * @param data string
151
165
  * @returns T
152
166
  */
153
- export function parse<T>(data: string): T {
167
+ // @ts-ignore: inline
168
+ @inline export function parse<T>(data: string): T {
154
169
  const dataSize = bytes(data);
155
170
  const dataPtr = changetype<usize>(data);
156
171
  if (isBoolean<T>()) {
@@ -171,18 +186,34 @@ export namespace JSON {
171
186
  }
172
187
  let type: nonnull<T> = changetype<nonnull<T>>(0);
173
188
  // @ts-ignore: Defined by transform
174
- if (isDefined(type.__DESERIALIZE) && isDefined(type.__INITIALIZE)) {
175
- const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
189
+ if (isDefined(type.__DESERIALIZE_CUSTOM)) {
190
+ const out = changetype<nonnull<T>>(0);
191
+ // @ts-ignore: Defined by transform
192
+ if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
176
193
  // @ts-ignore
177
- changetype<nonnull<T>>(out).__INITIALIZE();
194
+ return out.__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
195
+ // @ts-ignore: Defined by transform
196
+ } else if (isDefined(type.__DESERIALIZE)) {
197
+ const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
198
+ // @ts-ignore: Defined by transform
199
+ if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
178
200
  // @ts-ignore
179
- return deserializeObject<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
201
+ return deserializeStruct<nonnull<T>>(dataPtr, dataPtr + dataSize, out);
180
202
  } else if (type instanceof Map) {
181
203
  // @ts-ignore
182
- return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize);
204
+ return deserializeMap<nonnull<T>>(dataPtr, dataPtr + dataSize, 0);
183
205
  } else if (type instanceof Date) {
184
206
  // @ts-ignore
185
207
  return deserializeDate(dataPtr, dataPtr + dataSize);
208
+ } else if (type instanceof JSON.Raw) {
209
+ // @ts-ignore: type
210
+ return deserializeRaw(dataPtr, dataPtr + dataSize);
211
+ } else if (type instanceof JSON.Value) {
212
+ // @ts-ignorew
213
+ return deserializeArbitrary(dataPtr, dataPtr + dataSize, 0);
214
+ } else if (type instanceof JSON.Obj) {
215
+ // @ts-ignore
216
+ return deserializeObject(dataPtr, dataPtr + dataSize, 0);
186
217
  } else if (type instanceof JSON.Box) {
187
218
  // @ts-ignore
188
219
  return new JSON.Box(parseBox(data, changetype<nonnull<T>>(0).value));
@@ -209,19 +240,41 @@ export namespace JSON {
209
240
  Struct = 11,
210
241
  }
211
242
 
212
- export type Raw = string;
243
+ export class Raw {
244
+ public data: string;
245
+ constructor(data: string) {
246
+ this.data = data;
247
+ }
248
+ set(data: string): void {
249
+ this.data = data;
250
+ }
251
+ toString(): string {
252
+ return this.data;
253
+ }
254
+ // @ts-ignore: inline
255
+ @inline static from(data: string): JSON.Raw {
256
+ return new JSON.Raw(data);
257
+ }
258
+ }
213
259
 
214
260
  export class Value {
215
261
  static METHODS: Map<u32, u32> = new Map<u32, u32>();
216
262
  public type: i32;
217
263
 
218
- // @ts-ignore
219
264
  private storage: u64;
220
265
 
221
266
  private constructor() {
222
267
  unreachable();
223
268
  }
224
269
 
270
+ /**
271
+ * Creates an JSON.Value instance with no set value.
272
+ * @returns An instance of JSON.Value.
273
+ */
274
+ @inline static empty(): JSON.Value {
275
+ return changetype<JSON.Value>(__new(offsetof<JSON.Value>(), idof<JSON.Value>()));
276
+ }
277
+
225
278
  /**
226
279
  * Creates an JSON.Value instance from a given value.
227
280
  * @param value - The value to be encapsulated.
@@ -257,7 +310,7 @@ export namespace JSON {
257
310
  this.type = JSON.Types.U64;
258
311
  store<T>(changetype<usize>(this), value, STORAGE);
259
312
  } else if (value instanceof f32) {
260
- this.type = JSON.Types.F64;
313
+ this.type = JSON.Types.F32;
261
314
  store<T>(changetype<usize>(this), value, STORAGE);
262
315
  } else if (value instanceof f64) {
263
316
  this.type = JSON.Types.F64;
@@ -265,18 +318,31 @@ export namespace JSON {
265
318
  } else if (isString<T>()) {
266
319
  this.type = JSON.Types.String;
267
320
  store<T>(changetype<usize>(this), value, STORAGE);
321
+ } else if (value instanceof JSON.Raw) {
322
+ this.type = JSON.Types.Raw;
323
+ store<T>(changetype<usize>(this), value, STORAGE);
268
324
  } else if (value instanceof Map) {
269
325
  if (idof<T>() !== idof<Map<string, JSON.Value>>()) {
270
326
  abort("Maps must be of type Map<string, JSON.Value>!");
271
327
  }
272
328
  this.type = JSON.Types.Struct;
273
329
  store<T>(changetype<usize>(this), value, STORAGE);
330
+ // @ts-ignore: supplied by transform
331
+ } else if (isDefined(value.__SERIALIZE_CUSTOM)) {
332
+ this.type = idof<T>() + JSON.Types.Struct;
274
333
  // @ts-ignore
334
+ if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE_CUSTOM.index);
335
+ // @ts-ignore
336
+ store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
337
+ // @ts-ignore: supplied by transform
275
338
  } else if (isDefined(value.__SERIALIZE)) {
276
339
  this.type = idof<T>() + JSON.Types.Struct;
277
340
  // @ts-ignore
278
341
  if (!JSON.Value.METHODS.has(idof<T>())) JSON.Value.METHODS.set(idof<T>(), value.__SERIALIZE.index);
279
342
  // @ts-ignore
343
+ store<usize>(changetype<usize>(this), changetype<usize>(value), STORAGE);
344
+ } else if (value instanceof JSON.Obj) {
345
+ this.type = JSON.Types.Object;
280
346
  store<T>(changetype<usize>(this), value, STORAGE);
281
347
  // @ts-ignore
282
348
  } else if (isArray<T>() && idof<valueof<T>>() == idof<JSON.Value>()) {
@@ -308,10 +374,17 @@ export namespace JSON {
308
374
  return this.get<u32>().toString();
309
375
  case JSON.Types.U64:
310
376
  return this.get<u64>().toString();
377
+ case JSON.Types.F32:
378
+ return this.get<f32>().toString();
379
+ case JSON.Types.F64:
380
+ return this.get<f64>().toString();
311
381
  case JSON.Types.String:
312
382
  return '"' + this.get<string>() + '"';
313
383
  case JSON.Types.Bool:
314
384
  return this.get<boolean>() ? "true" : "false";
385
+ case JSON.Types.Raw: {
386
+ return this.get<JSON.Raw>().toString();
387
+ }
315
388
  case JSON.Types.Array: {
316
389
  const arr = this.get<JSON.Value[]>();
317
390
  if (!arr.length) return "[]";
@@ -329,15 +402,81 @@ export namespace JSON {
329
402
  out.write("]");
330
403
  return out.toString();
331
404
  }
405
+ case JSON.Types.Object: {
406
+ return JSON.stringify(this.get<JSON.Obj>());
407
+ }
332
408
  default: {
333
409
  const fn = JSON.Value.METHODS.get(this.type - JSON.Types.Struct);
334
410
  const value = this.get<usize>();
335
- return call_indirect<string>(fn, 0, value);
411
+ call_indirect<void>(fn, 0, value);
412
+ return bs.out<string>();
336
413
  }
337
414
  }
338
415
  }
339
416
  }
340
417
 
418
+ export class Obj {
419
+ // When accessing stackSize, subtract 2
420
+ // @ts-ignore: type
421
+ private stackSize: u32 = 6;
422
+ // @ts-ignore: type
423
+ private storage: Map<string, JSON.Value> = new Map<string, JSON.Value>();
424
+
425
+ constructor() { }
426
+
427
+ // @ts-ignore: decorator
428
+ @inline get size(): i32 {
429
+ return this.storage.size;
430
+ }
431
+
432
+ // @ts-ignore: decorator
433
+ @inline set<T>(key: string, value: T): void {
434
+ if (!this.storage.has(key)) this.stackSize += bytes(key) + 8;
435
+ this.storage.set(key, JSON.Value.from<T>(value));
436
+ }
437
+
438
+ // @ts-ignore: decorator
439
+ @inline get(key: string): JSON.Value | null {
440
+ if (!this.storage.has(key)) return null;
441
+ return this.storage.get(key);
442
+ }
443
+
444
+ // @ts-ignore: decorator
445
+ @inline has(key: string): bool {
446
+ return this.storage.has(key);
447
+ }
448
+
449
+ // @ts-ignore: decorator
450
+ @inline delete(key: string): bool {
451
+ return this.storage.delete(key);
452
+ }
453
+
454
+ // @ts-ignore: decorator
455
+ @inline keys(): string[] {
456
+ return this.storage.keys();
457
+ }
458
+
459
+ // @ts-ignore: decorator
460
+ @inline values(): JSON.Value[] {
461
+ return this.storage.values();
462
+ }
463
+
464
+ // @ts-ignore: decorator
465
+ @inline toString(): string {
466
+ return JSON.stringify(this);
467
+ }
468
+
469
+ // @ts-ignore: decorator
470
+ @inline static from<T>(value: T): JSON.Obj {
471
+ if (value instanceof JSON.Obj) return value;
472
+ const out = changetype<JSON.Obj>(__new(offsetof<JSON.Obj>(), idof<JSON.Obj>()));
473
+
474
+ if (value instanceof Map) {
475
+
476
+ }
477
+ return out;
478
+ }
479
+ }
341
480
  /**
342
481
  * Box for primitive types
343
482
  */
@@ -345,6 +484,15 @@ export namespace JSON {
345
484
  constructor(public value: T) {
346
485
  if (!isInteger<T>() && !isFloat<T>()) ERROR("JSON.Box should only hold primitive types!");
347
486
  }
487
+ /**
488
+ * Set the internal value of Box to new value
489
+ * @param value T
490
+ * @returns this
491
+ */
492
+ @inline set(value: T): Box<T> {
493
+ this.value = value;
494
+ return this;
495
+ }
348
496
  /**
349
497
  * Creates a reference to a primitive type
350
498
  * This means that it can create a nullable primitive
@@ -366,7 +514,8 @@ export namespace JSON {
366
514
  }
367
515
  }
368
516
 
369
- export function __serialize<T>(src: T): void {
517
+ // @ts-ignore: inline
518
+ @inline export function __serialize<T>(src: T): void {
370
519
  if (isBoolean<T>()) {
371
520
  serializeBool(src as bool);
372
521
  } else if (isInteger<T>() && nameof<T>() == "usize" && src == 0) {
@@ -387,9 +536,13 @@ export namespace JSON {
387
536
  } else if (isString<nonnull<T>>()) {
388
537
  serializeString(src as string);
389
538
  // @ts-ignore: Supplied by transform
539
+ } else if (isDefined(src.__SERIALIZE_CUSTOM)) {
540
+ // @ts-ignore
541
+ return src.__SERIALIZE_CUSTOM(changetype<nonnull<T>>(src));
542
+ // @ts-ignore: Supplied by transform
390
543
  } else if (isDefined(src.__SERIALIZE)) {
391
544
  // @ts-ignore
392
- serializeObject(changetype<nonnull<T>>(src));
545
+ serializeStruct(changetype<nonnull<T>>(src));
393
546
  } else if (src instanceof Date) {
394
547
  // @ts-ignore
395
548
  serializeDate(changetype<nonnull<T>>(src));
@@ -399,20 +552,26 @@ export namespace JSON {
399
552
  } else if (src instanceof Map) {
400
553
  // @ts-ignore
401
554
  serializeMap(changetype<nonnull<T>>(src));
555
+ } else if (src instanceof JSON.Raw) {
556
+ serializeRaw(src);
402
557
  } else if (src instanceof JSON.Value) {
403
558
  serializeArbitrary(src);
559
+ } else if (src instanceof JSON.Obj) {
560
+ serializeObject(src);
404
561
  } else if (src instanceof JSON.Box) {
405
562
  __serialize(src.value);
406
563
  } else {
407
564
  throw new Error(`Could not serialize provided data. Make sure to add the correct decorators to classes.`);
408
565
  }
409
566
  }
410
- export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
567
+
568
+ // @ts-ignore: inline
569
+ @inline export function __deserialize<T>(srcStart: usize, srcEnd: usize, dst: usize = 0): T {
411
570
  if (isBoolean<T>()) {
412
571
  // @ts-ignore: type
413
572
  return deserializeBoolean(srcStart, srcEnd);
414
573
  } else if (isInteger<T>()) {
415
- return deserializeInteger<T>(srcStart, srcEnd);
574
+ return atoi<T>(srcStart, srcEnd);
416
575
  } else if (isFloat<T>()) {
417
576
  return deserializeFloat<T>(srcStart, srcEnd);
418
577
  } else if (isString<T>()) {
@@ -423,15 +582,28 @@ export namespace JSON {
423
582
  return deserializeArray<T>(srcStart, srcEnd, dst);
424
583
  } else {
425
584
  let type: nonnull<T> = changetype<nonnull<T>>(0);
426
- // @ts-ignore: declared by transform
427
- if (isDefined(type.__DESERIALIZE)) {
428
- return deserializeObject<T>(srcStart, srcEnd, dst);
585
+ // @ts-ignore: Defined by transform
586
+ if (isDefined(type.__DESERIALIZE_CUSTOM)) {
587
+ const out = __new(offsetof<nonnull<T>>(), idof<nonnull<T>>());
588
+ // @ts-ignore: Defined by transform
589
+ if (isDefined(type.__INITIALIZE)) changetype<nonnull<T>>(out).__INITIALIZE();
590
+ // @ts-ignore
591
+ return changetype<nonnull<T>>(out).__DESERIALIZE_CUSTOM(ptrToStr(dataPtr, dataPtr + dataSize));
592
+ // @ts-ignore: Defined by transform
593
+ } else if (isDefined(type.__DESERIALIZE)) {
594
+ return deserializeStruct<T>(srcStart, srcEnd, dst);
429
595
  } else if (type instanceof Map) {
430
596
  // @ts-ignore: type
431
597
  return deserializeMap<T>(srcStart, srcEnd, dst);
432
598
  } else if (type instanceof Date) {
433
599
  // @ts-ignore: type
434
600
  return deserializeDate(srcStart, srcEnd);
601
+ } else if (type instanceof JSON.Raw) {
602
+ // @ts-ignore: type
603
+ return deserializeRaw(srcStart, srcEnd);
604
+ } else if (type instanceof JSON.Value) {
605
+ // @ts-ignore: type
606
+ return deserializeArbitrary(srcStart, srcEnd, 0);
435
607
  } else if (type instanceof JSON.Box) {
436
608
  // @ts-ignore: type
437
609
  return new JSON.Box(deserializeBox(srcStart, srcEnd, dst, changetype<nonnull<T>>(0).value));
@@ -448,4 +620,9 @@ export namespace JSON {
448
620
 
449
621
  function deserializeBox<T>(srcStart: usize, srcEnd: usize, dst: usize, ty: T): T {
450
622
  return JSON.__deserialize<T>(srcStart, srcEnd, dst);
451
- }
623
+ }
624
+
625
+ export function toRaw(data: string): JSON.Raw { return new JSON.Raw(data) }
626
+ export function fromRaw(data: JSON.Raw): string { return data.data }
627
+
628
+ export function toBox<T>(data: T): JSON.Box<T> { return new JSON.Box<T>(data) }
@@ -1,4 +1,3 @@
1
- import { bs } from "../../../modules/as-bs";
2
1
  import { BACK_SLASH } from "../../custom/chars";
3
2
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
4
3
  import { OBJECT, TOTAL_OVERHEAD } from "rt/common";
@@ -1,7 +1,9 @@
1
1
  import { JSON } from "../..";
2
2
  import { serializeArray } from "./array";
3
3
  import { serializeBool } from "./bool";
4
+ import { serializeFloat } from "./float";
4
5
  import { serializeInteger } from "./integer";
6
+ import { serializeObject } from "./object";
5
7
  import { serializeString } from "./string";
6
8
 
7
9
  export function serializeArbitrary(src: JSON.Value): void {
@@ -18,19 +20,30 @@ export function serializeArbitrary(src: JSON.Value): void {
18
20
  case JSON.Types.U64:
19
21
  serializeInteger<u64>(src.get<u64>());
20
22
  break;
23
+ case JSON.Types.F32:
24
+ serializeFloat<f32>(src.get<f32>());
25
+ break;
26
+ case JSON.Types.F64:
27
+ serializeFloat<f64>(src.get<f64>());
28
+ break;
21
29
  case JSON.Types.String:
22
30
  serializeString(src.get<string>());
23
31
  break;
24
32
  case JSON.Types.Bool:
25
33
  serializeBool(src.get<bool>());
34
+ break;
26
35
  case JSON.Types.Array: {
27
36
  serializeArray(src.get<JSON.Value[]>());
28
37
  break;
29
38
  }
39
+ case JSON.Types.Object: {
40
+ serializeObject(src.get<JSON.Obj>());
41
+ break;
42
+ }
30
43
  default: {
31
44
  const fn = JSON.Value.METHODS.get(src.type - JSON.Types.Struct);
32
- const value = src.get<usize>();
33
- call_indirect<string>(fn, 0, value);
45
+ const ptr = src.get<usize>();
46
+ call_indirect<void>(fn, 0, ptr);
34
47
  }
35
48
  }
36
49
  }
@@ -1,4 +1,3 @@
1
- import { bs } from "../../../modules/as-bs";
2
1
  import { COMMA, BRACKET_RIGHT, BRACKET_LEFT } from "../../custom/chars";
3
2
  import { JSON } from "../..";
4
3
 
@@ -1,5 +1,3 @@
1
- import { bs } from "../../../modules/as-bs";
2
-
3
1
  /**
4
2
  * Serialize a bool to type string
5
3
  * @param data data to serialize
@@ -1,4 +1,3 @@
1
- import { bs } from "../../../modules/as-bs";
2
1
  import { QUOTE } from "../../custom/chars";
3
2
  import { bytes } from "../../util/bytes";
4
3
 
@@ -1,5 +1,4 @@
1
1
  import { dtoa_buffered } from "util/number";
2
- import { bs } from "../../../modules/as-bs";
3
2
 
4
3
  export function serializeFloat<T extends number>(data: T): void {
5
4
  bs.ensureSize(64);
@@ -1,5 +1,4 @@
1
1
  import { itoa_buffered } from "util/number";
2
- import { bs } from "../../../modules/as-bs";
3
2
 
4
3
  export function serializeInteger<T extends number>(data: T): void {
5
4
  bs.ensureSize(sizeof<T>() << 3);
@@ -1,6 +1,5 @@
1
1
  import { JSON } from "../..";
2
2
  import { BRACE_LEFT, BRACE_RIGHT, COLON, COMMA } from "../../custom/chars";
3
- import { bs } from "../../../modules/as-bs";
4
3
 
5
4
  export function serializeMap<T extends Map<any, any>>(src: T): void {
6
5
  const srcSize = src.size;
@@ -1,7 +1,43 @@
1
- interface GeneratedInterface {
2
- __SERIALIZE(ptr: usize): string;
3
- }
1
+ import { JSON } from "../..";
2
+ import { BRACE_LEFT, BRACE_RIGHT, QUOTE } from "../../custom/chars";
3
+ import { bytes } from "../../util";
4
4
 
5
- export function serializeObject<T extends GeneratedInterface>(data: T): void {
6
- changetype<nonnull<T>>(data).__SERIALIZE(changetype<usize>(data));
7
- }
5
+ export function serializeObject(data: JSON.Obj): void {
6
+ if (!data.size) {
7
+ store<u32>(bs.offset, 0);
8
+ bs.offset += 4;
9
+ return;
10
+ }
11
+
12
+ // This grabs `JSON.Obj.stackSize` which is private
13
+ bs.ensureSize(load<u32>(changetype<usize>(data), offsetof<JSON.Obj>("stackSize")) - 2);
14
+ const keys = data.keys();
15
+ const values = data.values();
16
+
17
+ // console.log(" Keys " + keys.join(" "));
18
+ // console.log(" Values " + values.map<string>(v => v.toString()).join(" "))
19
+
20
+ store<u16>(bs.offset, BRACE_LEFT);
21
+ bs.offset += 2;
22
+
23
+ const firstKey = unchecked(keys[0]);
24
+ const keySize = bytes(firstKey);
25
+ store<u16>(bs.offset, QUOTE);
26
+ memory.copy(bs.offset + 2, changetype<usize>(firstKey), keySize);
27
+ store<u32>(bs.offset += keySize + 2, 3801122); // ":
28
+ bs.offset += 4;
29
+ JSON.__serialize(unchecked(values[0]));
30
+
31
+ for (let i = 1; i < keys.length; i++) {
32
+ const key = unchecked(keys[i]);
33
+ const keySize = bytes(key);
34
+ store<u32>(bs.offset, 2228268); // ,"
35
+ memory.copy(bs.offset + 4, changetype<usize>(key), keySize);
36
+ store<u32>(bs.offset += keySize + 4, 3801122); // ":
37
+ bs.offset += 4;
38
+ JSON.__serialize(unchecked(values[i]));
39
+ }
40
+
41
+ store<u16>(bs.offset, BRACE_RIGHT);
42
+ bs.offset += 2;
43
+ }
@@ -0,0 +1,14 @@
1
+ import { JSON } from "../..";
2
+ import { bytes } from "../../util";
3
+
4
+ /**
5
+ * Serialize raw data to itself
6
+ * @param data data to serialize
7
+ * @returns void
8
+ */
9
+ export function serializeRaw(data: JSON.Raw): void {
10
+ const dataSize = bytes(data.data);
11
+ bs.proposeSize(dataSize);
12
+ memory.copy(changetype<usize>(bs.offset), changetype<usize>(data.data), dataSize);
13
+ bs.offset += dataSize;
14
+ }
@@ -1,6 +1,5 @@
1
1
  import { _intTo16 } from "../../custom/util";
2
2
  import { bytes } from "../../util/bytes";
3
- import { bs } from "../../../modules/as-bs";
4
3
  import { BACK_SLASH, QUOTE } from "../../custom/chars";
5
4
  import { SERIALIZE_ESCAPE_TABLE } from "../../globals/tables";
6
5
 
@@ -0,0 +1,7 @@
1
+ interface GeneratedInterface {
2
+ __SERIALIZE(ptr: usize): string;
3
+ }
4
+
5
+ export function serializeStruct<T extends GeneratedInterface>(data: T): void {
6
+ changetype<nonnull<T>>(data).__SERIALIZE(changetype<usize>(data));
7
+ }