json-as 1.1.16 → 1.1.18

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.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 2025-06-30 - 1.1.18
4
+
5
+ - fix: [#150](https://github.com/JairusSW/json-as/issues/150)
6
+
7
+ ## 2025-06-17 - 1.1.17
8
+
9
+ - fix: add support for classes within namespaces [#147](https://github.com/JairusSW/json-as/pull/147)
10
+
3
11
  ## 2025-06-12 - 1.1.16
4
12
 
5
13
  - tests: properly support nulls (in testing lib)
package/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  ██ ██ ██ ██ ██ ██ ██ ██ ██ ██ ██
7
7
  █████ ███████ ██████ ██ ████ ██ ██ ███████
8
8
  </span>
9
- AssemblyScript - v1.1.16
9
+ AssemblyScript - v1.1.18
10
10
  </pre>
11
11
  </h6>
12
12
 
@@ -0,0 +1,63 @@
1
+ import { JSON } from "..";
2
+ import { describe, expect } from "./lib";
3
+
4
+ describe("Should serialize namespaced derived structs", () => {
5
+ const obj: Namespace.DerivedObject = { a: "foo", b: "bar" };
6
+ expect(JSON.stringify(obj)).toBe(`{"a":"foo","b":"bar"}`);
7
+ });
8
+
9
+ describe("Should serialize namespaced derived structs with nested object", () => {
10
+ const bar: Namespace.Bar = { value: "baz" };
11
+ const obj: Namespace.DerivedObjectWithNestedObject = { a: "foo", b: "bar", c: bar };
12
+ expect(JSON.stringify(obj)).toBe(`{"a":"foo","b":"bar","c":{"value":"baz"}}`);
13
+ });
14
+
15
+ describe("Should deserialize namespaced object with alias property", () => {
16
+ expect(JSON.stringify(JSON.parse<Namespace.ObjectWithAliasProperty>(`{"a":"foo","value":42}`))).toBe(`{"a":"foo","value":42}`);
17
+ });
18
+
19
+ describe("Should deserialize namespaced derived structs", () => {
20
+ expect(JSON.stringify(JSON.parse<Namespace.DerivedObject>(`{"a":"foo","b":"bar"}`))).toBe(`{"a":"foo","b":"bar"}`);
21
+ expect(JSON.stringify(JSON.parse<Namespace.DerivedObject>(`{"b":"bar","a":"foo"}`))).toBe(`{"a":"foo","b":"bar"}`);
22
+ });
23
+
24
+ describe("Should deserialize namespaced derived structs with nested object", () => {
25
+ expect(JSON.stringify(JSON.parse<Namespace.DerivedObjectWithNestedObject>(`{"a":"foo","b":"bar","c":{"value":"baz"}}`))).toBe(`{"a":"foo","b":"bar","c":{"value":"baz"}}`);
26
+ expect(JSON.stringify(JSON.parse<Namespace.DerivedObjectWithNestedObject>(`{"c":{"value":"baz"},"a":"foo","b":"bar"}`))).toBe(`{"a":"foo","b":"bar","c":{"value":"baz"}}`);
27
+ });
28
+
29
+ type NumberAlias = i64;
30
+
31
+ namespace Namespace {
32
+
33
+ @json
34
+ export class Base {
35
+ a: string = "";
36
+ }
37
+
38
+
39
+ @json
40
+ export class Bar {
41
+ value: string = "";
42
+ }
43
+
44
+
45
+ @json
46
+ export class ObjectWithAliasProperty {
47
+ a: string = "";
48
+ value: NumberAlias = 0;
49
+ }
50
+
51
+
52
+ @json
53
+ export class DerivedObject extends Base {
54
+ b: string = "";
55
+ }
56
+
57
+
58
+ @json
59
+ export class DerivedObjectWithNestedObject extends Base {
60
+ b: string = "";
61
+ c: Bar = new Bar();
62
+ }
63
+ }
package/assembly/index.ts CHANGED
@@ -605,7 +605,7 @@ export namespace JSON {
605
605
  if (isDefined(type.__DESERIALIZE)) {
606
606
  const out = changetype<nonnull<T>>(dst || __new(offsetof<nonnull<T>>(), idof<nonnull<T>>()));
607
607
  // @ts-ignore: Defined by transform
608
- if (isDefined(type.__INITIALIZE)) out.__INITIALIZE();
608
+ if (isNullable<T>() && isDefined(type.__INITIALIZE)) out.__INITIALIZE();
609
609
  // @ts-ignore: Defined by transform
610
610
  return out.__DESERIALIZE(srcStart, srcEnd, out);
611
611
  } else if (type instanceof Map) {
@@ -1,5 +1,5 @@
1
+ import { JSON } from "../assembly/index";
1
2
  import { bs } from "../lib/as-bs";
2
- import { JSON } from ".";
3
3
 
4
4
  @json
5
5
  class Vec3 {
@@ -214,13 +214,10 @@ class Player {
214
214
 
215
215
  @omitif((self: this): boolean => self.age < 18)
216
216
  age!: i32;
217
-
218
- @omitnull()
219
217
  pos!: Vec3 | null;
220
218
  isVerified!: boolean;
221
219
  __SERIALIZE(ptr: usize): void {
222
- bs.proposeSize(160);
223
- let block: usize = 0;
220
+ bs.proposeSize(158);
224
221
  store<u16>(bs.offset, 123, 0);
225
222
  bs.offset += 2;
226
223
  if (!((self: this): boolean => self.age < 18)(this)) {
@@ -231,14 +228,6 @@ class Player {
231
228
  store<u16>(bs.offset, 44, 0);
232
229
  bs.offset += 2;
233
230
  }
234
- if ((block = load<usize>(ptr, offsetof<this>("pos"))) !== 0) {
235
- store<u64>(bs.offset, 32370099070435362, 0);
236
- store<u32>(bs.offset, 3801122, 8);
237
- bs.offset += 12;
238
- JSON.__serialize<Vec3 | null>(load<Vec3 | null>(ptr, offsetof<this>("pos")));
239
- store<u16>(bs.offset, 44, 0);
240
- bs.offset += 2;
241
- }
242
231
  store<u64>(bs.offset, 32088598323265570, 0);
243
232
  store<u64>(bs.offset, 30962384884727923, 8);
244
233
  store<u64>(bs.offset, 9570583007002721, 16);
@@ -256,6 +245,11 @@ class Player {
256
245
  store<u32>(bs.offset, 3801122, 24);
257
246
  bs.offset += 28;
258
247
  JSON.__serialize<Array<i32>>(load<Array<i32>>(ptr, offsetof<this>("lastActive")));
248
+ store<u64>(bs.offset, 31244203453448236, 0);
249
+ store<u32>(bs.offset, 2228339, 8);
250
+ store<u16>(bs.offset, 58, 12);
251
+ bs.offset += 14;
252
+ JSON.__serialize<Vec3 | null>(load<Vec3 | null>(ptr, offsetof<this>("pos")));
259
253
  store<u64>(bs.offset, 32370073295519788, 0);
260
254
  store<u64>(bs.offset, 29555362187509846, 8);
261
255
  store<u64>(bs.offset, 28147931469643878, 16);
@@ -552,10 +546,12 @@ class Player {
552
546
  if (load<u64>(srcStart) == 30399761348886638) {
553
547
  srcStart += 8;
554
548
  switch (<u32>keyEnd - <u32>keyStart) {
555
- case 6: {
556
- const code48 = load<u64>(keyStart) & 281474976710655;
557
- if (code48 == 493928513648) {
558
- store<usize>(changetype<usize>(out), 0, offsetof<this>("pos"));
549
+ case 20: {
550
+ const codeS8 = load<u64>(keyStart, 0);
551
+ const codeS16 = load<u64>(keyStart, 8);
552
+ const codeS20 = load<u32>(keyStart, 16);
553
+ if (codeS8 == 32370111954878566 && codeS16 == 27303545189433460 && codeS20 == 6619245) {
554
+ store<usize>(changetype<usize>(out), 0, offsetof<this>("firstName"));
559
555
  srcStart += 2;
560
556
  keyStart = 0;
561
557
  break;
@@ -566,12 +562,10 @@ class Player {
566
562
  }
567
563
  }
568
564
 
569
- case 20: {
570
- const codeS8 = load<u64>(keyStart, 0);
571
- const codeS16 = load<u64>(keyStart, 8);
572
- const codeS20 = load<u32>(keyStart, 16);
573
- if (codeS8 == 32370111954878566 && codeS16 == 27303545189433460 && codeS20 == 6619245) {
574
- store<usize>(changetype<usize>(out), 0, offsetof<this>("firstName"));
565
+ case 6: {
566
+ const code48 = load<u64>(keyStart) & 281474976710655;
567
+ if (code48 == 493928513648) {
568
+ store<usize>(changetype<usize>(out), 0, offsetof<this>("pos"));
575
569
  srcStart += 2;
576
570
  keyStart = 0;
577
571
  break;
@@ -598,6 +592,7 @@ class Player {
598
592
  }
599
593
  }
600
594
  const player: Player = {
595
+ firstName: "Jairus",
601
596
  lastName: "Tanaka",
602
597
  lastActive: [3, 9, 2025],
603
598
  age: 18,
package/assembly/test.ts CHANGED
@@ -1,4 +1,3 @@
1
- import { JSON } from ".";
2
1
 
3
2
  @json
4
3
  class Vec3 {
@@ -19,7 +18,6 @@ class Player {
19
18
  @omitif((self: Player) => self.age < 18)
20
19
  age!: i32;
21
20
 
22
- @omitnull()
23
21
  pos!: Vec3 | null;
24
22
  isVerified!: boolean;
25
23
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "1.1.16",
3
+ "version": "1.1.18",
4
4
  "author": "Jairus Tanaka",
5
5
  "repository": {
6
6
  "type": "git",
@@ -9,11 +9,11 @@
9
9
  "main": "transform/lib/index.js",
10
10
  "devDependencies": {
11
11
  "@assemblyscript/wasi-shim": "^0.1.0",
12
- "@types/node": "^22.15.24",
13
- "assemblyscript": "^0.28.1",
12
+ "@types/node": "^22.15.34",
13
+ "assemblyscript": "^0.28.2",
14
14
  "assemblyscript-prettier": "^3.0.1",
15
- "prettier": "^3.5.3",
16
- "tsx": "^4.19.4",
15
+ "prettier": "^3.6.2",
16
+ "tsx": "^4.20.3",
17
17
  "typescript": "^5.8.3"
18
18
  },
19
19
  "bugs": {
package/run-bench.as.sh CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/bin/bash
2
2
  RUNTIMES=${RUNTIMES:-"minimal stub"}
3
3
  ENGINES=${ENGINES:-"liftoff ignition sparkplug turbofan llvm"}
4
- for file in ./assembly/__benches__/large.bench.ts; do
4
+ for file in ./assembly/__benches__/medium.bench.ts; do
5
5
  filename=$(basename -- "$file")
6
6
  output_wasi=
7
7
  for runtime in $RUNTIMES; do
package/run-tests.sh CHANGED
@@ -4,24 +4,28 @@ mkdir -p ./build
4
4
 
5
5
  for file in ./assembly/__tests__/*.spec.ts; do
6
6
  filename=$(basename -- "$file")
7
- output="./build/${filename%.ts}.wasm"
7
+ if [ -z "$1" ] || [ "$1" = "$filename" ]; then
8
+ output="./build/${filename%.ts}.wasm"
8
9
 
9
- start_time=$(date +%s%3N)
10
- npx asc "$file" --transform ./transform -o "$output" --enable simd --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --disableWarning 226 || { echo "Tests failed"; exit 1; }
11
- end_time=$(date +%s%3N)
10
+ start_time=$(date +%s%3N)
11
+ npx asc "$file" --transform ./transform -o "$output" --enable simd --config ./node_modules/@assemblyscript/wasi-shim/asconfig.json --disableWarning 226 || { echo "Tests failed"; exit 1; }
12
+ end_time=$(date +%s%3N)
12
13
 
13
- build_time=$((end_time - start_time))
14
+ build_time=$((end_time - start_time))
14
15
 
15
- if [ "$build_time" -ge 60000 ]; then
16
- formatted_time="$(bc <<< "scale=2; $build_time/60000")m"
17
- elif [ "$build_time" -ge 1000 ]; then
18
- formatted_time="$(bc <<< "scale=2; $build_time/1000")s"
16
+ if [ "$build_time" -ge 60000 ]; then
17
+ formatted_time="$(bc <<< "scale=2; $build_time/60000")m"
18
+ elif [ "$build_time" -ge 1000 ]; then
19
+ formatted_time="$(bc <<< "scale=2; $build_time/1000")s"
20
+ else
21
+ formatted_time="${build_time}ms"
22
+ fi
23
+
24
+ echo " -> $filename (built in $formatted_time)"
25
+ wasmtime "$output" || { echo "Tests failed"; exit 1; }
19
26
  else
20
- formatted_time="${build_time}ms"
27
+ echo " -> $filename (skipped)"
21
28
  fi
22
-
23
- echo " -> $filename (built in $formatted_time)"
24
- wasmtime "$output" || { echo "Tests failed"; exit 1; }
25
29
  done
26
30
 
27
31
  echo "All tests passed"
@@ -4,14 +4,13 @@ import { Visitor } from "./visitor.js";
4
4
  import { isStdlib, removeExtension, SimpleParser, toString } from "./util.js";
5
5
  import * as path from "path";
6
6
  import { fileURLToPath } from "url";
7
- import { Property, PropertyFlags, Schema, Src } from "./types.js";
8
- import { getClass, getImportedClass } from "./linkers/classes.js";
9
- import { writeFileSync } from "fs";
7
+ import { Property, PropertyFlags, Schema, SourceSet } from "./types.js";
8
+ import { readFileSync, writeFileSync } from "fs";
10
9
  import { CustomTransform } from "./linkers/custom.js";
11
10
  let indent = " ";
12
11
  let id = 0;
13
- const WRITE = process.env["JSON_WRITE"];
14
- const rawValue = process.env["JSON_DEBUG"];
12
+ const WRITE = process.env["JSON_WRITE"]?.trim();
13
+ const rawValue = process.env["JSON_DEBUG"]?.trim();
15
14
  const DEBUG = rawValue === "true" ? 1 : rawValue === "false" || rawValue === "" ? 0 : isNaN(Number(rawValue)) ? 0 : Number(rawValue);
16
15
  const STRICT = process.env["JSON_STRICT"] && process.env["JSON_STRICT"] == "true";
17
16
  export class JSONTransform extends Visitor {
@@ -21,8 +20,7 @@ export class JSONTransform extends Visitor {
21
20
  parser;
22
21
  schemas = new Map();
23
22
  schema;
24
- src;
25
- sources = new Map();
23
+ sources = new SourceSet();
26
24
  imports = [];
27
25
  simdStatements = [];
28
26
  visitedClasses = new Set();
@@ -43,14 +41,9 @@ export class JSONTransform extends Visitor {
43
41
  return name === "json" || name === "serializable";
44
42
  }))
45
43
  return;
46
- const source = node.range.source;
47
- if (!this.sources.has(source.internalPath)) {
48
- this.src = new Src(source);
49
- this.sources.set(source.internalPath, this.src);
50
- }
51
- else
52
- this.src = this.sources.get(source.internalPath);
53
- if (this.visitedClasses.has(source.internalPath + node.name.text))
44
+ const source = this.sources.get(node.range.source);
45
+ const fullClassPath = source.getFullPath(node);
46
+ if (this.visitedClasses.has(fullClassPath))
54
47
  return;
55
48
  if (!this.schemas.has(source.internalPath))
56
49
  this.schemas.set(source.internalPath, []);
@@ -59,9 +52,9 @@ export class JSONTransform extends Visitor {
59
52
  const deserializers = [...node.members.filter((v) => v.kind === 58 && v.decorators && v.decorators.some((e) => e.name.text.toLowerCase() === "deserializer"))];
60
53
  const schema = new Schema();
61
54
  schema.node = node;
62
- schema.name = node.name.text;
55
+ schema.name = source.getQualifiedName(node);
63
56
  if (node.extendsType) {
64
- const extendsName = node.extendsType?.name.identifier.text;
57
+ const extendsName = source.resolveExtendsName(node);
65
58
  if (!schema.parent) {
66
59
  const depSearch = schema.deps.find((v) => v.name == extendsName);
67
60
  if (depSearch) {
@@ -72,36 +65,37 @@ export class JSONTransform extends Visitor {
72
65
  schema.parent = depSearch;
73
66
  }
74
67
  else {
75
- const internalSearch = getClass(extendsName, source);
68
+ const internalSearch = source.getClass(extendsName);
76
69
  if (internalSearch) {
77
70
  if (DEBUG > 0)
78
71
  console.log("Found " + extendsName + " internally from " + source.internalPath);
79
- if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
72
+ if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
80
73
  this.visitClassDeclarationRef(internalSearch);
81
74
  this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
82
75
  this.visitClassDeclaration(node);
83
76
  return;
84
77
  }
85
- const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == internalSearch.name.text);
78
+ const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == extendsName);
86
79
  if (!schem)
87
80
  throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
88
81
  schema.deps.push(schem);
89
82
  schema.parent = schem;
90
83
  }
91
84
  else {
92
- const externalSearch = getImportedClass(extendsName, source, this.parser);
85
+ const externalSearch = source.getImportedClass(extendsName, this.parser);
93
86
  if (externalSearch) {
94
87
  if (DEBUG > 0)
95
88
  console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
96
- if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
89
+ const externalSource = this.sources.get(externalSearch.range.source);
90
+ if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
97
91
  this.visitClassDeclarationRef(externalSearch);
98
- this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
92
+ this.schemas.get(externalSource.internalPath).push(this.schema);
99
93
  this.visitClassDeclaration(node);
100
94
  return;
101
95
  }
102
- const schem = this.schemas.get(externalSearch.range.source.internalPath)?.find((s) => s.name == externalSearch.name.text);
96
+ const schem = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == extendsName);
103
97
  if (!schem)
104
- throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSearch.range.source.internalPath);
98
+ throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSource.internalPath);
105
99
  schema.deps.push(schem);
106
100
  schema.parent = schem;
107
101
  }
@@ -119,7 +113,7 @@ export class JSONTransform extends Visitor {
119
113
  }
120
114
  const getUnknownTypes = (type, types = []) => {
121
115
  type = stripNull(type);
122
- type = this.src.aliases.find((v) => stripNull(v.name) == type)?.getBaseType() || type;
116
+ type = source.aliases.find((v) => stripNull(v.name) == type)?.getBaseType() || type;
123
117
  if (type.startsWith("Array<")) {
124
118
  return getUnknownTypes(type.slice(6, -1));
125
119
  }
@@ -155,39 +149,40 @@ export class JSONTransform extends Visitor {
155
149
  }
156
150
  }
157
151
  else {
158
- const internalSearch = getClass(unknownType, source);
152
+ const internalSearch = source.getClass(unknownType);
159
153
  if (internalSearch) {
160
154
  if (DEBUG > 0)
161
155
  console.log("Found " + unknownType + " internally from " + source.internalPath);
162
- if (!this.visitedClasses.has(internalSearch.range.source.internalPath + internalSearch.name.text)) {
156
+ if (!this.visitedClasses.has(source.getFullPath(internalSearch))) {
163
157
  this.visitClassDeclarationRef(internalSearch);
164
- const internalSchema = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == internalSearch.name.text);
158
+ const internalSchema = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == unknownType);
165
159
  schema.deps.push(internalSchema);
166
160
  this.schemas.get(internalSearch.range.source.internalPath).push(this.schema);
167
161
  this.visitClassDeclaration(node);
168
162
  return;
169
163
  }
170
- const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == internalSearch.name.text);
164
+ const schem = this.schemas.get(internalSearch.range.source.internalPath)?.find((s) => s.name == unknownType);
171
165
  if (!schem)
172
166
  throw new Error("Could not find schema for " + internalSearch.name.text + " in " + internalSearch.range.source.internalPath);
173
167
  schema.deps.push(schem);
174
168
  }
175
169
  else {
176
- const externalSearch = getImportedClass(unknownType, source, this.parser);
170
+ const externalSearch = source.getImportedClass(unknownType, this.parser);
177
171
  if (externalSearch) {
178
172
  if (DEBUG > 0)
179
173
  console.log("Found " + externalSearch.name.text + " externally from " + source.internalPath);
180
- if (!this.visitedClasses.has(externalSearch.range.source.internalPath + externalSearch.name.text)) {
174
+ const externalSource = this.sources.get(externalSearch.range.source);
175
+ if (!this.visitedClasses.has(externalSource.getFullPath(externalSearch))) {
181
176
  this.visitClassDeclarationRef(externalSearch);
182
- const externalSchema = this.schemas.get(externalSearch.range.source.internalPath)?.find((s) => s.name == externalSearch.name.text);
177
+ const externalSchema = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == unknownType);
183
178
  schema.deps.push(externalSchema);
184
- this.schemas.get(externalSearch.range.source.internalPath).push(this.schema);
179
+ this.schemas.get(externalSource.internalPath).push(this.schema);
185
180
  this.visitClassDeclaration(node);
186
181
  return;
187
182
  }
188
- const schem = this.schemas.get(externalSearch.range.source.internalPath)?.find((s) => s.name == externalSearch.name.text);
183
+ const schem = this.schemas.get(externalSource.internalPath)?.find((s) => s.name == unknownType);
189
184
  if (!schem)
190
- throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSearch.range.source.internalPath);
185
+ throw new Error("Could not find schema for " + externalSearch.name.text + " in " + externalSource.internalPath);
191
186
  schema.deps.push(schem);
192
187
  }
193
188
  }
@@ -196,7 +191,7 @@ export class JSONTransform extends Visitor {
196
191
  }
197
192
  this.schemas.get(source.internalPath).push(schema);
198
193
  this.schema = schema;
199
- this.visitedClasses.add(source.internalPath + node.name.text);
194
+ this.visitedClasses.add(fullClassPath);
200
195
  let SERIALIZE = "__SERIALIZE(ptr: usize): void {\n";
201
196
  let INITIALIZE = "@inline __INITIALIZE(): this {\n";
202
197
  let DESERIALIZE = "__DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n";
@@ -257,7 +252,7 @@ export class JSONTransform extends Visitor {
257
252
  if (!member.type)
258
253
  throwError("Fields must be strongly typed", node.range);
259
254
  let type = toString(member.type);
260
- type = this.src.aliases.find((v) => stripNull(v.name) == stripNull(type))?.getBaseType() || type;
255
+ type = source.aliases.find((v) => stripNull(v.name) == stripNull(type))?.getBaseType() || type;
261
256
  const name = member.name;
262
257
  const value = member.initializer ? toString(member.initializer) : null;
263
258
  if (type.startsWith("(") && type.includes("=>"))
@@ -324,8 +319,8 @@ export class JSONTransform extends Visitor {
324
319
  const aliasName = JSON.stringify(member.alias || member.name);
325
320
  const realName = member.name;
326
321
  const isLast = i == this.schema.members.length - 1;
327
- if (member.value && member.type == stripNull(member.type)) {
328
- if (!(member.value == "null" || member.value == "0" || member.value == "0.0" || member.value == "false")) {
322
+ if (member.value) {
323
+ if (member.value != "null" && member.value != "0" && member.value != "0.0" && member.value != "false") {
329
324
  INITIALIZE += ` store<${member.type}>(changetype<usize>(this), ${member.value}, offsetof<this>(${JSON.stringify(member.name)}));\n`;
330
325
  }
331
326
  }
@@ -938,7 +933,7 @@ export class JSONTransform extends Visitor {
938
933
  generateEmptyMethods(node) {
939
934
  let SERIALIZE_EMPTY = "@inline __SERIALIZE(ptr: usize): void {\n bs.proposeSize(4);\n store<u32>(bs.offset, 8192123);\n bs.offset += 4;\n}";
940
935
  let INITIALIZE_EMPTY = "@inline __INITIALIZE(): this {\n return this;\n}";
941
- let DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n return this;\n}";
936
+ let DESERIALIZE_EMPTY = "@inline __DESERIALIZE<__JSON_T>(srcStart: usize, srcEnd: usize, out: __JSON_T): __JSON_T {\n return out;\n}";
942
937
  if (DEBUG > 0) {
943
938
  console.log(SERIALIZE_EMPTY);
944
939
  console.log(INITIALIZE_EMPTY);
@@ -965,14 +960,22 @@ export class JSONTransform extends Visitor {
965
960
  addImports(node) {
966
961
  this.baseCWD = this.baseCWD.replaceAll("/", path.sep);
967
962
  const baseDir = path.resolve(fileURLToPath(import.meta.url), "..", "..", "..");
968
- const pkgPath = path.join(this.baseCWD, "node_modules");
969
963
  let fromPath = node.range.source.normalizedPath.replaceAll("/", path.sep);
964
+ const isLib = path.dirname(baseDir).endsWith("node_modules");
965
+ if (!isLib && !this.parser.sources.some((s) => s.normalizedPath.startsWith("assembly/index"))) {
966
+ const newPath = "./assembly/index.ts";
967
+ this.parser.parseFile(readFileSync(path.join(...newPath.split("/"))).toString(), newPath, false);
968
+ }
969
+ else if (isLib && !this.parser.sources.some((s) => s.normalizedPath.startsWith("~lib/json-as/assembly/index"))) {
970
+ const newPath = "~lib/json-as/assembly/index.ts";
971
+ this.parser.parseFile(readFileSync(path.join(...newPath.split("/"))).toString(), newPath, false);
972
+ }
970
973
  fromPath = fromPath.startsWith("~lib") ? fromPath.slice(5) : path.join(this.baseCWD, fromPath);
971
974
  const bsImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "bs" || d.name.text == "bs"));
972
975
  const jsonImport = this.imports.find((i) => i.declarations?.find((d) => d.foreignName.text == "JSON" || d.name.text == "JSON"));
973
976
  let baseRel = path.posix.join(...path.relative(path.dirname(fromPath), path.join(baseDir)).split(path.sep));
974
- if (baseRel.endsWith("node_modules/json-as")) {
975
- baseRel = "json-as" + baseRel.slice(baseRel.indexOf("node_modules/json-as") + 20);
977
+ if (baseRel.endsWith("json-as")) {
978
+ baseRel = "json-as" + baseRel.slice(baseRel.indexOf("json-as") + 7);
976
979
  }
977
980
  else if (!baseRel.startsWith(".") && !baseRel.startsWith("/") && !baseRel.startsWith("json-as")) {
978
981
  baseRel = "./" + baseRel;
@@ -1217,16 +1220,6 @@ function isPrimitive(type) {
1217
1220
  function isBoolean(type) {
1218
1221
  return type == "bool" || type == "boolean";
1219
1222
  }
1220
- function isStruct(type) {
1221
- type = stripNull(type);
1222
- const schema = JSONTransform.SN.schema;
1223
- if (schema.name == type)
1224
- return true;
1225
- const depSearch = schema.deps.some((v) => v.name == type);
1226
- if (depSearch)
1227
- return true;
1228
- return false;
1229
- }
1230
1223
  function isString(type) {
1231
1224
  return stripNull(type) == "string" || stripNull(type) == "String";
1232
1225
  }