json-as 0.4.1 → 0.4.4

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/README.md CHANGED
@@ -67,14 +67,44 @@ const data: Player = {
67
67
  }
68
68
 
69
69
  const stringified = JSON.stringify<Player>(data);
70
- // '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23}'
70
+ // {
71
+ // "firstName": "Emmet",
72
+ // "lastName": "West",
73
+ // "lastActive": [8, 27, 2022],
74
+ // "age": 23,
75
+ // "pos": {
76
+ // "x": -3.4000000953674318,
77
+ // "y": 1.2000000476837159
78
+ // }
79
+ // }
71
80
  console.log(`Stringified: ${stringified}`);
72
81
 
73
- const parsed = JSON.parse<Player>(stringified)
74
- // { firstName: "Emmet", lastName: "West", "lastActive": [8,27,2022], age: 23 }
75
- console.log(`Parsed: ${JSON.stringify(parsed)}`)
82
+ const parsed = JSON.parse<Player>(stringified);
83
+ // Player {
84
+ // firstName: "Emmet",
85
+ // lastName: "West",
86
+ // lastActive: [8, 27, 2022],
87
+ // age: 23,
88
+ // pos: {
89
+ // x: -3.4000000953674318,
90
+ // y: 1.2000000476837159
91
+ // }
92
+ // }
93
+ console.log(`Parsed: ${JSON.stringify(parsed)}`);
76
94
  ```
77
95
 
96
+ ## FAQ
97
+
98
+ - Does it support the full JSON spec?
99
+ Yes, as-json supports the full JSON specification and trys to mimic the JSON API as much as possible
100
+ - What are the differences between as-json and the JSON API?
101
+ The main difference between as-json and the JSON API is the ability to create new fields in objects during runtime. Since classes are static, Map ser/de support will be added soon allowing the user to parse and stringify dynamic objects and their properties
102
+ - Does this support nested structures?
103
+ Yes, as-json supports nested structures
104
+ - Does this support whitespace?
105
+ Yes, as-json supports whitespace although the current implementation is deathly slow
106
+ - How fast is it?
107
+ Really fast. For example, here are some benchmarks for ser/de a Vec2 with as-json
78
108
  ## Issues
79
109
 
80
110
  Please submit an issue to https://github.com/JairusSW/as-json/issues if you find anything wrong with this library
@@ -0,0 +1,24 @@
1
+ {
2
+ "targets": {
3
+ "coverage": {
4
+ "lib": ["./node_modules/@as-covers/assembly/index.ts"],
5
+ "transform": ["@as-covers/transform", "@as-pect/transform"]
6
+ },
7
+ "noCoverage": {
8
+ "transform": ["@as-pect/transform"]
9
+ }
10
+ },
11
+ "options": {
12
+ "exportMemory": true,
13
+ "outFile": "output.wasm",
14
+ "textFile": "output.wat",
15
+ "bindings": "raw",
16
+ "exportStart": "_start",
17
+ "exportRuntime": true,
18
+ "use": ["RTRACE=1"],
19
+ "debug": true,
20
+ "exportTable": true
21
+ },
22
+ "extends": "./asconfig.json",
23
+ "entries": ["./@as-pect/assembly/assembly/index.ts"]
24
+ }
@@ -0,0 +1,30 @@
1
+ export default {
2
+ /**
3
+ * A set of globs passed to the glob package that qualify typescript files for testing.
4
+ */
5
+ entries: ["assembly/__tests__/**/*.spec.ts"],
6
+ /**
7
+ * A set of globs passed to the glob package that quality files to be added to each test.
8
+ */
9
+ include: ["assembly/__tests__/**/*.include.ts"],
10
+ /**
11
+ * A set of regexp that will disclude source files from testing.
12
+ */
13
+ disclude: [/node_modules/],
14
+ /**
15
+ * Add your required AssemblyScript imports here.
16
+ */
17
+ async instantiate(memory, createImports, instantiate, binary) {
18
+ let instance; // Imports can reference this
19
+ const myImports = {
20
+ // put your web assembly imports here, and return the module
21
+ };
22
+ return instantiate(binary, createImports(myImports));
23
+ },
24
+ /** Enable code coverage. */
25
+ // coverage: ["assembly/**/*.ts"],
26
+ /**
27
+ * Specify if the binary wasm file should be written to the file system.
28
+ */
29
+ outputBinary: false,
30
+ };
@@ -1,11 +1,11 @@
1
- import { JSON, parseBooleanArray, parseMap, parseNumberArray } from "..";
1
+ import { JSON } from "..";
2
2
  @json
3
- class Vector {
3
+ class Vec2 {
4
4
  x: f32;
5
5
  y: f32;
6
6
  }
7
7
 
8
- const vec: Vector = blackbox<Vector>({
8
+ const vec: Vec2 = blackbox<Vec2>({
9
9
  x: 0.0,
10
10
  y: 0.0,
11
11
  });
@@ -26,7 +26,7 @@ bench("Stringify Float", () => {
26
26
  blackbox(JSON.stringify(blackbox(3.14)));
27
27
  });
28
28
 
29
- bench("Stringify Vector", () => {
29
+ bench("Stringify Object (Vec2)", () => {
30
30
  blackbox(JSON.stringify(vec));
31
31
  });
32
32
 
@@ -50,20 +50,20 @@ bench("Parse Float", () => {
50
50
  blackbox(JSON.parse<f32>(blackbox("3.14")));
51
51
  });
52
52
 
53
- bench("Parse Vector", () => {
54
- blackbox(parseMap<Map<string, f32>>(blackbox('{"x":0.0,"y":0.0}')));
53
+ bench("Parse Object (Vec2)", () => {
54
+ blackbox(JSON.parse<Vec2>(blackbox('{"x":0.0,"y":0.0}')));
55
55
  });
56
56
 
57
57
  bench("Parse Boolean Array", () => {
58
58
  blackbox(
59
- parseBooleanArray<boolean[]>(blackbox("[true,false,true,false,true]"))
59
+ JSON.parse<boolean[]>(blackbox("[true,false,true,false,true]"))
60
60
  );
61
61
  });
62
62
 
63
63
  bench("Parse Integer Array", () => {
64
- blackbox(parseNumberArray<u32[]>(blackbox("[1,2,3,4,5]")));
64
+ blackbox(JSON.parse<u32[]>(blackbox("[1,2,3,4,5]")));
65
65
  });
66
66
 
67
67
  bench("Parse Float Array", () => {
68
- blackbox(parseNumberArray<f32[]>(blackbox("[1.0,2.0,3.0,4.0,5.0]")));
68
+ blackbox(JSON.parse<f32[]>(blackbox("[1.0,2.0,3.0,4.0,5.0]")));
69
69
  });
@@ -0,0 +1 @@
1
+ /// <reference types="@as-pect/assembly/types/as-pect" />
@@ -0,0 +1,40 @@
1
+ import { JSON } from "../"
2
+ describe("JSON Stringify Test", () => {
3
+ it("Stringify String", () => {
4
+ expect<string>().toBe(42, "19 + 23 is 42");
5
+ });
6
+
7
+ it("should be the same reference", () => {
8
+ let ref = new Vec3();
9
+ expect<Vec3>(ref).toBe(ref, "Reference Equality");
10
+ });
11
+
12
+ it("should perform a memory comparison", () => {
13
+ let a = new Vec3(1, 2, 3);
14
+ let b = new Vec3(1, 2, 3);
15
+
16
+ expect<Vec3>(a).toStrictEqual(
17
+ b,
18
+ "a and b have the same values, (discluding child references)",
19
+ );
20
+ });
21
+
22
+ it("should compare strings", () => {
23
+ expect<string>("a=" + "200").toBe("a=200", "both strings are equal");
24
+ });
25
+
26
+ it("should compare values", () => {
27
+ expect<i32>(10).toBeLessThan(200);
28
+ expect<i32>(1000).toBeGreaterThan(200);
29
+ expect<i32>(1000).toBeGreaterThanOrEqual(1000);
30
+ expect<i32>(1000).toBeLessThanOrEqual(1000);
31
+ });
32
+
33
+ it("can log some values to the console", () => {
34
+ log<string>("Hello world!"); // strings!
35
+ log<f64>(3.1415); // floats!
36
+ log<u8>(244); // integers!
37
+ log<u64>(0xffffffff); // long values!
38
+ log<ArrayBuffer>(new ArrayBuffer(50)); // bytes!
39
+ });
40
+ });
package/assembly/chars.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  export const commaCode = ",".charCodeAt(0);
2
- export const quoteCode = "".charCodeAt(0);
2
+ export const quoteCode = "\"".charCodeAt(0);
3
3
  export const backSlashCode = "\\".charCodeAt(0);
4
4
  export const leftBraceCode = "{".charCodeAt(0);
5
5
  export const rightBraceCode = "}".charCodeAt(0);
package/assembly/index.ts CHANGED
@@ -10,6 +10,7 @@ import {
10
10
  rightBraceCode,
11
11
  rightBracketCode
12
12
  } from "./chars";
13
+ import { removeWhitespace } from "./util";
13
14
 
14
15
  /**
15
16
  * JSON Encoder/Decoder for AssemblyScript
@@ -26,17 +27,13 @@ export namespace JSON {
26
27
  */
27
28
  export function stringify<T = Nullable | null>(data: T): string {
28
29
  // String
29
- if (isString(data)) {
30
- return serializeString(<string>data);
30
+ if (isString<T>()) {
31
+ return '"' + (<string>data).replaceAll('"', '\\"') + '"';
31
32
  }
32
33
  // Boolean
33
- else if (isBoolean(data)) {
34
+ else if (isBoolean<T>()) {
34
35
  return data ? "true" : "false";
35
36
  }
36
- // Null
37
- else if (isNullable<T>() && data == null) {
38
- return "null";
39
- }
40
37
  // Integers/Floats
41
38
  // @ts-ignore
42
39
  else if ((isInteger<T>() || isFloat<T>()) && isFinite(data)) {
@@ -46,20 +43,28 @@ export namespace JSON {
46
43
  // Class-Based serialization
47
44
  // @ts-ignore
48
45
  else if (isDefined(data.__JSON_Serialize)) {
49
- //@ts-ignore
46
+ // @ts-ignore
50
47
  return data.__JSON_Serialize();
51
48
  }
52
49
  // ArrayLike
53
- else if (isArrayLike(data)) {
50
+ else if (isArrayLike<T>()) {
54
51
  let result = new StringSink("[");
52
+ // @ts-ignore
55
53
  if (data.length == 0) return "[]";
54
+ // @ts-ignore
56
55
  for (let i = 0; i < data.length - 1; i++) {
56
+ // @ts-ignore
57
57
  result.write(stringify(unchecked(data[i])));
58
58
  result.write(",");
59
59
  }
60
+ // @ts-ignore
60
61
  result.write(stringify(unchecked(data[data.length - 1])));
61
62
  result.write("]");
62
63
  return result.toString();
64
+ }
65
+ // Null
66
+ else if (isNullable<T>() && data == null) {
67
+ return "null";
63
68
  } else {
64
69
  return "null";
65
70
  }
@@ -73,6 +78,7 @@ export namespace JSON {
73
78
  * @returns T
74
79
  */
75
80
  export function parse<T = Variant>(data: string): T {
81
+ data = removeWhitespace(data);
76
82
  let type!: T;
77
83
  if (isString<T>()) {
78
84
  // @ts-ignore
@@ -91,18 +97,20 @@ export namespace JSON {
91
97
  const result = new Map<string, string>()
92
98
  let lastPos: u32 = 1
93
99
  let key: string = ''
94
- let instr: u32 = 0
100
+ let instr: boolean = false
95
101
  let char: u32 = 0
96
102
  let depth: u32 = 0
97
103
  let fdepth: u32 = 0
98
104
  for (let i: u32 = 1; i < len; i++) {
99
- char = data.charCodeAt(i)
100
- if (char === "\"".charCodeAt(0) && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = (instr ? 0 : 1)
101
- else if (instr === 0) {
105
+ char = data.charCodeAt(i);
106
+ if (instr === false && char === quoteCode) instr = true;
107
+ else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== "/".charCodeAt(0)) instr = false;
108
+ if (instr === false) {
102
109
  if (char === leftBraceCode || char === leftBracketCode) depth++
103
110
  if (char === rightBraceCode || char === rightBracketCode) fdepth++
104
111
  }
105
112
  if (depth !== 0 && depth === fdepth) {
113
+ //console.log(`Found Struct: ${data.slice(lastPos + 1, i + 1)}`)
106
114
  result.set(key, data.slice(lastPos + 1, i + 1))
107
115
  // Reset the depth
108
116
  depth = 0
@@ -110,19 +118,22 @@ export namespace JSON {
110
118
  // Set new lastPos
111
119
  lastPos = i + 1
112
120
  }
113
- if (depth === 0) {
121
+ if (!instr && depth === 0) {
114
122
  if (char === colonCode) {
115
123
  key = data.slice(lastPos + 1, i - 1)
124
+ //console.log(`Found Key: ${data.slice(lastPos + 1, i - 1)}`)
116
125
  lastPos = i
117
- }
118
- else if (char === commaCode) {
126
+ } else if (char === commaCode) {
127
+ //console.log(`Found Comma: ${data.slice(lastPos + 1, i)}`)
119
128
  if ((i - lastPos) > 0) result.set(key, data.slice(lastPos + 1, i))
120
129
  lastPos = i + 1
121
130
  }
122
131
  }
123
132
  }
124
133
 
125
- if ((len - lastPos) > 0) result.set(key, data.slice(lastPos + 1, len))
134
+ if ((len - lastPos) > 1 && (len - lastPos) !== 0) {
135
+ result.set(key, data.slice(lastPos + 1, len))
136
+ }
126
137
  // @ts-ignore
127
138
  return schema.__JSON_Deserialize(result)
128
139
  } else {
@@ -132,11 +143,7 @@ export namespace JSON {
132
143
  }
133
144
  }
134
145
 
135
- // @ts-ignore
136
- @inline
137
- function serializeString(data: string): string {
138
- return '"' + data.replaceAll('"', '\\"') + '"';
139
- }
146
+
140
147
  // @ts-ignore
141
148
  @inline
142
149
  function parseString(data: string): string {
@@ -301,37 +308,4 @@ export namespace JSON {
301
308
  return result;
302
309
  }
303
310
 
304
- export function parseObject(data: string): void {
305
- //const obj = instantiate<T>()
306
- const result = new Array<string>();
307
- let lastPos: u32 = 0;
308
- let char: u32 = 0;
309
- let i: u32 = 1;
310
- let key: string = "";
311
- let isKey: boolean = false;
312
- for (; i < u32(data.length - 1); i++) {
313
- char = data.charCodeAt(i);
314
- if (isKey == false) {
315
- if (char == colonCode) {
316
- key = data.slice(lastPos + 2, i - 1);
317
- //console.log(`Found Key: ${key}`);
318
- result.push(key);
319
- lastPos = ++i;
320
- isKey = true;
321
- }
322
- } else {
323
- if (char == commaCode) {
324
- const val = data.slice(lastPos, i);
325
- lastPos = i;
326
- isKey = false;
327
- //console.log(`Found Val: ${val}`)
328
- result.push(val);
329
- }
330
- }
331
- }
332
- result.push(data.slice(lastPos, data.length - 1));
333
- //console.log(stringify(result))
334
- //return obj
335
- }
336
-
337
311
  class Nullable { }
package/assembly/test.ts CHANGED
@@ -1,11 +1,15 @@
1
1
  import "wasi";
2
2
  import { JSON } from ".";
3
+ import { removeWhitespace } from "./util";
3
4
 
5
+ // @ts-ignore
4
6
  @json
5
7
  class Vec2 {
6
8
  x: f32
7
9
  y: f32
8
10
  }
11
+
12
+ // @ts-ignore
9
13
  @json
10
14
  class Player {
11
15
  firstName: string
@@ -27,9 +31,45 @@ const data: Player = {
27
31
  }
28
32
 
29
33
  const stringified = JSON.stringify<Player>(data);
30
- // '{"firstName":"Emmet","lastName":"West","lastActive":[8,27,2022],"age":23}'
34
+ // {
35
+ // "firstName": "Emmet",
36
+ // "lastName": "West",
37
+ // "lastActive": [8, 27, 2022],
38
+ // "age": 23,
39
+ // "pos": {
40
+ // "x": -3.4000000953674318,
41
+ // "y": 1.2000000476837159
42
+ // }
43
+ // }
31
44
  console.log(`Stringified: ${stringified}`);
32
-
33
- const parsed = JSON.parse<Player>(stringified)
34
- // { firstName: "Emmet", lastName: "West", "lastActive": [8,27,2022], age: 23 }
35
- console.log(`Parsed: ${JSON.stringify(parsed)}`)
45
+ console.log(`Whitespace: ${removeWhitespace(`{
46
+ "firstName": "Emmet",
47
+ "lastName": "West",
48
+ "lastActive": [8, 27, 2022],
49
+ "age": 23,
50
+ "pos": {
51
+ "x": -3.4000000953674318,
52
+ "y": 1.2000000476837159
53
+ }
54
+ }`)}`)
55
+ const parsed = JSON.parse<Player>(`{
56
+ "firstName": "Emmet",
57
+ "lastName": "West",
58
+ "lastActive": [8, 27, 2022],
59
+ "age": 23,
60
+ "pos": {
61
+ "x": -3.4000000953674318,
62
+ "y": 1.2000000476837159
63
+ }
64
+ }`);
65
+ // Player {
66
+ // firstName: "Emmet",
67
+ // lastName: "West",
68
+ // lastActive: [8, 27, 2022],
69
+ // age: 23,
70
+ // pos: {
71
+ // x: -3.4000000953674318,
72
+ // y: 1.2000000476837159
73
+ // }
74
+ // }
75
+ console.log(`Parsed: ${JSON.stringify(parsed)}`);
@@ -0,0 +1,21 @@
1
+ import { StringSink } from "as-string-sink/assembly";
2
+ import { isSpace } from "assemblyscript/std/assembly/util/string";
3
+ import { backSlashCode, quoteCode } from "./chars";
4
+
5
+ export function removeWhitespace(data: string): string {
6
+ const result = new StringSink()
7
+ let instr = false;
8
+ for (let i = 0; i < data.length; i++) {
9
+ const char = data.charCodeAt(i);
10
+ if (instr === false && char === quoteCode) instr = true
11
+ else if (instr === true && char === quoteCode && data.charCodeAt(i - 1) !== backSlashCode) instr = false;
12
+
13
+ if (instr === false) {
14
+ if (!isSpace(char)) result.write(data.charAt(i))
15
+ } else {
16
+ result.write(data.charAt(i))
17
+ }
18
+
19
+ }
20
+ return result.toString()
21
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "json-as",
3
- "version": "0.4.1",
3
+ "version": "0.4.4",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "types": "assembly/index.ts",
6
6
  "author": "Jairus Tanaka",
@@ -17,18 +17,16 @@
17
17
  "test:wasm3": "wasm3 ./build/test.wasm"
18
18
  },
19
19
  "devDependencies": {
20
+ "@as-pect/cli": "^7.0.7",
20
21
  "@as-tral/cli": "^1.1.1",
21
22
  "as-console": "^6.0.2",
22
23
  "assemblyscript": "^0.20.7",
23
24
  "assemblyscript-prettier": "^1.0.2",
24
- "benchmark": "^2.1.4",
25
- "microtime": "^3.0.0",
26
25
  "typescript": "^4.7.2"
27
26
  },
28
27
  "dependencies": {
29
28
  "as-string-sink": "^0.5.0",
30
- "as-variant": "^0.3.0",
31
- "visitor-as": "^0.10.0"
29
+ "as-variant": "^0.4.0"
32
30
  },
33
31
  "repository": {
34
32
  "type": "git",
@@ -39,7 +37,8 @@
39
37
  "json",
40
38
  "serialize",
41
39
  "deserialize",
42
- "dynamic"
40
+ "dynamic",
41
+ "serde"
43
42
  ],
44
43
  "bugs": {
45
44
  "url": "https://github.com/JairusSW/as-json/issues"
@@ -5,8 +5,8 @@ class AsJSONTransform extends ClassDecorator {
5
5
  constructor() {
6
6
  super(...arguments);
7
7
  this.sources = [];
8
- this.encodeStmts = new Map();
9
- this.decodeCode = new Map();
8
+ this.encodeStmts = [];
9
+ this.decodeStmts = [];
10
10
  }
11
11
  visitMethodDeclaration(node) { }
12
12
  visitFieldDeclaration(node) {
@@ -15,15 +15,10 @@ class AsJSONTransform extends ClassDecorator {
15
15
  throw new Error(`Field ${name} is missing a type declaration`);
16
16
  }
17
17
  const type = getName(node.type);
18
- const className = this.currentClass.name.text;
19
- if (!this.encodeStmts.has(className))
20
- this.encodeStmts.set(className, []);
21
- if (!this.decodeCode.has(className))
22
- this.decodeCode.set(className, []);
23
18
  // @ts-ignore
24
- this.encodeStmts.get(className).push(`this.__JSON_Serialized += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`);
19
+ this.encodeStmts.push(`"${name}":\${JSON.stringify<${type}>(this.${name})},`);
25
20
  // @ts-ignore
26
- this.decodeCode.get(className).push(`${name}: JSON.parse<${type}>(values.get("${name}")),\n`);
21
+ this.decodeStmts.push(`${name}: JSON.parse<${type}>(values.get("${name}")),\n`);
27
22
  }
28
23
  visitClassDeclaration(node) {
29
24
  if (!node.members) {
@@ -31,39 +26,39 @@ class AsJSONTransform extends ClassDecorator {
31
26
  }
32
27
  this.currentClass = node;
33
28
  const name = getName(node);
34
- this.encodeStmts.delete(name);
35
- this.decodeCode.delete(name);
36
29
  this.visit(node.members);
37
30
  const serializedProp = `__JSON_Serialized: string = "";`;
38
31
  let serializeFunc = ``;
39
- if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
32
+ if (this.encodeStmts.length > 0) {
33
+ const stmt = this.encodeStmts[this.encodeStmts.length - 1];
34
+ this.encodeStmts[this.encodeStmts.length - 1] = stmt.slice(0, stmt.length - 1);
40
35
  serializeFunc = `
36
+ @inline
41
37
  __JSON_Serialize(): string {
42
- if (!this.__JSON_Serialized) {
43
- ${ // @ts-ignore
44
- this.encodeStmts.get(name).join("\n")};
45
- this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
46
- }
47
- return this.__JSON_Serialized;
38
+ return \`{${this.encodeStmts.join("")}}\`;
48
39
  }
49
40
  `;
50
41
  }
51
42
  else {
52
43
  serializeFunc = `
44
+ @inline
53
45
  __JSON_Serialize(): string {
54
46
  return "{}";
55
47
  }
56
48
  `;
57
49
  }
58
50
  const deserializeFunc = `
51
+ @inline
59
52
  __JSON_Deserialize(values: Map<string, string>): ${name} {
60
53
  return {
61
54
  ${ // @ts-ignore
62
- this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ""}
55
+ this.decodeStmts.join("")}
63
56
  }
64
57
  }
65
58
  `;
66
- //console.log(serializedProp, serializeFunc, deserializeFunc)
59
+ this.encodeStmts = [];
60
+ this.decodeStmts = [];
61
+ //console.log(serializeFunc, deserializeFunc)
67
62
  const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);
68
63
  node.members.push(serializedProperty);
69
64
  const serializeMethod = SimpleParser.parseClassMember(serializeFunc, node);
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@json-as/transform",
3
- "version": "0.4.0",
3
+ "version": "0.4.4",
4
4
  "description": "JSON encoder/decoder for AssemblyScript",
5
5
  "main": "./lib/index.js",
6
6
  "author": "Jairus Tanaka",
@@ -10,7 +10,9 @@
10
10
  "license": "MIT",
11
11
  "scripts": {},
12
12
  "devDependencies": {},
13
- "dependencies": {},
13
+ "dependencies": {
14
+ "visitor-as": "^0.10.2"
15
+ },
14
16
  "repository": {
15
17
  "type": "git",
16
18
  "url": "git+https://github.com/JairusSW/as-json.git"
@@ -28,4 +30,4 @@
28
30
  "homepage": "https://github.com/JairusSW/as-json#readme",
29
31
  "type": "module",
30
32
  "exports": "./lib/index.js"
31
- }
33
+ }
@@ -11,8 +11,8 @@ import { SimpleParser } from "visitor-as/dist/index.js";
11
11
  class AsJSONTransform extends ClassDecorator {
12
12
  public currentClass!: ClassDeclaration;
13
13
  public sources: Source[] = [];
14
- public encodeStmts = new Map<string, string[]>();
15
- public decodeCode = new Map<string, string[]>();
14
+ public encodeStmts: string[] = [];
15
+ public decodeStmts: string[] = [];
16
16
 
17
17
  visitMethodDeclaration(node: MethodDeclaration): void {}
18
18
  visitFieldDeclaration(node: FieldDeclaration): void {
@@ -23,16 +23,13 @@ class AsJSONTransform extends ClassDecorator {
23
23
 
24
24
  const type = getName(node.type);
25
25
 
26
- const className = this.currentClass!.name.text
27
- if (!this.encodeStmts.has(className)) this.encodeStmts.set(className, [])
28
- if (!this.decodeCode.has(className)) this.decodeCode.set(className, [])
29
26
  // @ts-ignore
30
- this.encodeStmts.get(className).push(
31
- `this.__JSON_Serialized += '' + '"' + '${name}' + '"' + ':' + JSON.stringify<${type}>(this.${name}) + ',';`
27
+ this.encodeStmts.push(
28
+ `"${name}":\${JSON.stringify<${type}>(this.${name})},`
32
29
  );
33
30
 
34
31
  // @ts-ignore
35
- this.decodeCode.get(className).push(
32
+ this.decodeStmts.push(
36
33
  `${name}: JSON.parse<${type}>(values.get("${name}")),\n`
37
34
  );
38
35
  }
@@ -45,27 +42,24 @@ class AsJSONTransform extends ClassDecorator {
45
42
 
46
43
  const name = getName(node);
47
44
 
48
- this.encodeStmts.delete(name);
49
- this.decodeCode.delete(name);
50
45
  this.visit(node.members);
51
46
 
52
47
  const serializedProp = `__JSON_Serialized: string = "";`
53
48
 
54
49
  let serializeFunc = ``
55
50
 
56
- if (this.encodeStmts.has(name) && this.encodeStmts.get(name)) {
51
+ if (this.encodeStmts.length > 0) {
52
+ const stmt = this.encodeStmts[this.encodeStmts.length - 1]!
53
+ this.encodeStmts[this.encodeStmts.length - 1] = stmt!.slice(0, stmt.length - 1)
57
54
  serializeFunc = `
55
+ @inline
58
56
  __JSON_Serialize(): string {
59
- if (!this.__JSON_Serialized) {
60
- ${// @ts-ignore
61
- this.encodeStmts.get(name).join("\n")};
62
- this.__JSON_Serialized = "{" + this.__JSON_Serialized.slice(0, this.__JSON_Serialized.length - 1) + "}";
63
- }
64
- return this.__JSON_Serialized;
57
+ return \`{${this.encodeStmts.join("")}}\`;
65
58
  }
66
59
  `
67
60
  } else {
68
61
  serializeFunc = `
62
+ @inline
69
63
  __JSON_Serialize(): string {
70
64
  return "{}";
71
65
  }
@@ -73,14 +67,17 @@ class AsJSONTransform extends ClassDecorator {
73
67
  }
74
68
 
75
69
  const deserializeFunc = `
70
+ @inline
76
71
  __JSON_Deserialize(values: Map<string, string>): ${name} {
77
72
  return {
78
73
  ${// @ts-ignore
79
- this.decodeCode.get(name) ? this.decodeCode.get(name).join("") : ""}
74
+ this.decodeStmts.join("")}
80
75
  }
81
76
  }
82
77
  `;
83
- //console.log(serializedProp, serializeFunc, deserializeFunc)
78
+ this.encodeStmts = [];
79
+ this.decodeStmts = [];
80
+ //console.log(serializeFunc, deserializeFunc)
84
81
  const serializedProperty = SimpleParser.parseClassMember(serializedProp, node);
85
82
  node.members.push(serializedProperty);
86
83
 
@@ -14,7 +14,7 @@
14
14
  // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
15
15
  "sourceMap": false /* Generates corresponding '.map' file. */,
16
16
  // "outFile": "./", /* Concatenate and emit output to single file. */
17
- "outDir": "./lib/" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
17
+ "outDir": "./lib" /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */,
18
18
  // "composite": true, /* Enable project compilation */
19
19
  // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */
20
20
  // "removeComments": true, /* Do not emit comments to output. */