json-as 0.5.67 → 0.6.0

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.
@@ -1,5 +1,6 @@
1
1
  import { StringSink } from "as-string-sink/assembly";
2
2
  import { isSpace } from "util/string";
3
+ import { E_INVALIDDATE } from "util/error";
3
4
  import {
4
5
  backSlashCode,
5
6
  commaCode,
@@ -214,7 +215,7 @@ export namespace JSON {
214
215
  return parseObject<T>(data.trimStart());
215
216
  } else if (idof<nonnull<T>>() == idof<Date>()) {
216
217
  // @ts-ignore
217
- return Date.fromString(data);
218
+ return parseDate(data);
218
219
  } else {
219
220
  // @ts-ignore
220
221
  throw new Error(
@@ -291,7 +292,7 @@ export namespace JSON {
291
292
  return parseObject<T>(data.trimStart());
292
293
  } else if (idof<nonnull<T>>() == idof<Date>()) {
293
294
  // @ts-ignore
294
- return Date.fromString(data);
295
+ return parseDate(data);
295
296
  } else {
296
297
  // @ts-ignore
297
298
  throw new Error(
@@ -711,3 +712,95 @@ export namespace JSON {
711
712
  }
712
713
  return result;
713
714
  }
715
+
716
+ // @ts-ignore: decorator
717
+ @inline const
718
+ MILLIS_PER_DAY = 1000 * 60 * 60 * 24,
719
+ MILLIS_PER_HOUR = 1000 * 60 * 60,
720
+ MILLIS_PER_MINUTE = 1000 * 60,
721
+ MILLIS_PER_SECOND = 1000,
722
+
723
+ YEARS_PER_EPOCH = 400,
724
+ DAYS_PER_EPOCH = 146097,
725
+ EPOCH_OFFSET = 719468, // Jan 1, 1970
726
+ MILLIS_LIMIT = 8640000000000000;
727
+
728
+ function parseDate(dateTimeString: string): Date {
729
+ if (!dateTimeString.length) throw new RangeError(E_INVALIDDATE);
730
+ var
731
+ hour: i32 = 0,
732
+ min: i32 = 0,
733
+ sec: i32 = 0,
734
+ ms: i32 = 0;
735
+
736
+ let dateString = dateTimeString;
737
+ let posT = dateTimeString.indexOf("T");
738
+ if (~posT) {
739
+ // includes a time component
740
+ let timeString: string;
741
+ dateString = dateTimeString.substring(0, posT);
742
+ timeString = dateTimeString.substring(posT + 1);
743
+ // parse the HH-MM-SS component
744
+ let timeParts = timeString.split(":");
745
+ let len = timeParts.length;
746
+ if (len <= 1) throw new RangeError(E_INVALIDDATE);
747
+
748
+ hour = i32.parse(timeParts[0]);
749
+ min = i32.parse(timeParts[1]);
750
+ if (len >= 3) {
751
+ let secAndMs = timeParts[2];
752
+ let posDot = secAndMs.indexOf(".");
753
+ if (~posDot) {
754
+ // includes milliseconds
755
+ sec = i32.parse(secAndMs.substring(0, posDot));
756
+ ms = i32.parse(secAndMs.substring(posDot + 1));
757
+ } else {
758
+ sec = i32.parse(secAndMs);
759
+ }
760
+ }
761
+ }
762
+ // parse the YYYY-MM-DD component
763
+ let parts = dateString.split("-");
764
+ let year = i32.parse(parts[0]);
765
+ let month = 1, day = 1;
766
+ let len = parts.length;
767
+ if (len >= 2) {
768
+ month = i32.parse(parts[1]);
769
+ if (len >= 3) {
770
+ day = i32.parse(parts[2]);
771
+ }
772
+ }
773
+ return new Date(epochMillis(year, month, day, hour, min, sec, ms));
774
+ }
775
+
776
+ function epochMillis(
777
+ year: i32,
778
+ month: i32,
779
+ day: i32,
780
+ hour: i32,
781
+ minute: i32,
782
+ second: i32,
783
+ milliseconds: i32
784
+ ): i64 {
785
+ return (
786
+ daysSinceEpoch(year, month, day) * MILLIS_PER_DAY +
787
+ hour * MILLIS_PER_HOUR +
788
+ minute * MILLIS_PER_MINUTE +
789
+ second * MILLIS_PER_SECOND +
790
+ milliseconds
791
+ );
792
+ }
793
+
794
+ function daysSinceEpoch(y: i32, m: i32, d: i32): i64 {
795
+ y -= i32(m <= 2);
796
+ let era = <u32>floorDiv(y, YEARS_PER_EPOCH);
797
+ let yoe = <u32>y - era * YEARS_PER_EPOCH; // [0, 399]
798
+ let doy = <u32>(153 * (m + (m > 2 ? -3 : 9)) + 2) / 5 + d - 1; // [0, 365]
799
+ let doe = yoe * 365 + yoe / 4 - yoe / 100 + doy; // [0, 146096]
800
+ return <i64><i32>(era * 146097 + doe - EPOCH_OFFSET);
801
+ }
802
+
803
+ // @ts-ignore: decorator
804
+ @inline function floorDiv<T extends number>(a: T, b: T): T {
805
+ return (a - (a < 0 ? b - 1 : 0)) / b as T;
806
+ }
package/assembly/test.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { JSON } from "./src/json";
2
+
2
3
  // @ts-ignore
3
4
  @json
4
5
  class Vec3 {
@@ -12,7 +13,7 @@ class Vec3 {
12
13
  class Player {
13
14
  firstName: string;
14
15
  lastName: string;
15
- lastActive: i32[];
16
+ lastActive: Date;
16
17
  age: i32;
17
18
  pos: Vec3 | null;
18
19
  isVerified: boolean;
@@ -23,7 +24,7 @@ const vec = new Vec3();
23
24
  const player: Player = {
24
25
  firstName: "Emmet",
25
26
  lastName: "West",
26
- lastActive: [8, 27, 2022],
27
+ lastActive: new Date(0),
27
28
  age: 23,
28
29
  pos: {
29
30
  x: 3.4,
@@ -43,7 +44,7 @@ console.log("Implemented: " + JSON.stringify(JSON.parse<Vec3>('{}')));
43
44
 
44
45
  console.log("Original: " + JSON.stringify(player));
45
46
  //console.log("Revised: " + vec.__JSON_Deserialize('{"x":3,"y":1,"z":8}').__JSON_Serialize());
46
- console.log("Implemented: " + JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}')));
47
+ console.log("Implemented: " + JSON.stringify(JSON.parse<Player>('{"firstName":"Emmet","lastName":"West","lastActive":2023-11-16T04:06:35.108285303Z,"age":23,"pos":{"x":3.4,"y":1.2,"z":8.3},"isVerified":true}')));
47
48
  /*
48
49
  // 9,325,755
49
50
  bench("Stringify Object (Vec3)", () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "0.5.67",
3
+ "version": "0.6.0",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "types": "assembly/index.ts",
6
6
  "author": "Jairus Tanaka",
@@ -16,8 +16,7 @@
16
16
  "scripts": {
17
17
  "test:aspect": "asp",
18
18
  "bench:astral": "astral --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior never --runtime stub",
19
- "build:test": "asc assembly/test.ts -o build/test.wasm --transform ./transform/lib/index.js --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 3 --shrinkLevel 0 --noAssert --uncheckedBehavior always --converge --runtime stub",
20
- "build:test:debug": "asc assembly/test.ts -o build/test.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 0 --shrinkLevel 0 --noAssert --uncheckedBehavior always --runtime stub",
19
+ "build:test": "asc assembly/test.ts -o build/test.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 0 --shrinkLevel 0 --noAssert --uncheckedBehavior always --runtime stub",
21
20
  "build:bench": "asc bench/benchmark.ts -o bench/benchmark.wasm --transform ./transform --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --optimizeLevel 3 --shrinkLevel 0 --converge --noAssert --uncheckedBehavior always --runtime stub",
22
21
  "bench:wasmtime": "wasmtime ./bench/benchmark.wasm",
23
22
  "bench:wavm": "wavm run ./bench/benchmark.wasm",
@@ -33,12 +32,12 @@
33
32
  "@as-tral/cli": "^2.0.1",
34
33
  "@assemblyscript/wasi-shim": "^0.1.0",
35
34
  "as-bench": "^0.0.0-alpha",
36
- "assemblyscript": "^0.27.14",
35
+ "assemblyscript": "^0.27.18",
37
36
  "assemblyscript-prettier": "^3.0.1",
38
37
  "benchmark": "^2.1.4",
39
38
  "kati": "^0.6.2",
40
39
  "microtime": "^3.1.1",
41
- "prettier": "^3.0.3",
40
+ "prettier": "^3.1.0",
42
41
  "tinybench": "^2.5.1",
43
42
  "typescript": "^5.2.2",
44
43
  "visitor-as": "^0.11.4"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-as/transform",
3
- "version": "0.5.67",
3
+ "version": "0.6.0",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "main": "./lib/index.js",
6
6
  "author": "Jairus Tanaka",
@@ -18,6 +18,7 @@ class SchemaData {
18
18
  public encodeStmts: string[] = [];
19
19
  public setDataStmts: string[] = [];
20
20
  }
21
+
21
22
  class AsJSONTransform extends BaseVisitor {
22
23
  public schemasList: SchemaData[] = [];
23
24
  public currentClass!: SchemaData;
@@ -137,18 +138,18 @@ class AsJSONTransform extends BaseVisitor {
137
138
  `
138
139
  );
139
140
  } else {
140
- this.currentClass.encodeStmts.push(
141
- `"${name}":\${JSON.stringify<${type}>(this.${name})},`
142
- );
143
- // @ts-ignore
144
- this.currentClass.setDataStmts.push(
145
- `if (key.equals("${name}")) {
141
+ this.currentClass.encodeStmts.push(
142
+ `"${name}":\${JSON.stringify<${type}>(this.${name})},`
143
+ );
144
+ // @ts-ignore
145
+ this.currentClass.setDataStmts.push(
146
+ `if (key.equals("${name}")) {
146
147
  this.${name} = __parseObjectValue<${type}>(val_start ? data.slice(val_start, val_end) : data);
147
148
  return;
148
149
  }
149
150
  `
150
- );
151
- }
151
+ );
152
+ }
152
153
  }
153
154
  }
154
155