vsn 0.1.43 → 0.1.46

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 (98) hide show
  1. package/demo/demo.html +7 -2
  2. package/demo/markup.html +2 -0
  3. package/demo/vsn.js +1 -1
  4. package/demo/xhr.vsn +4 -0
  5. package/dist/AST/ArithmeticAssignmentNode.js +8 -1
  6. package/dist/AST/ArithmeticAssignmentNode.js.map +1 -1
  7. package/dist/AST/FunctionNode.d.ts +0 -0
  8. package/dist/AST/FunctionNode.js +1 -0
  9. package/dist/AST/FunctionNode.js.map +1 -0
  10. package/dist/AST/StringFormatNode.d.ts +18 -0
  11. package/dist/{attributes/ClickToggleClass.js → AST/StringFormatNode.js} +49 -49
  12. package/dist/AST/StringFormatNode.js.map +1 -0
  13. package/dist/AST/WASM/Context.d.ts +4 -0
  14. package/dist/AST/WASM/Context.js +18 -0
  15. package/dist/AST/WASM/Context.js.map +1 -0
  16. package/dist/AST/WASM/Function.d.ts +22 -0
  17. package/dist/AST/WASM/Function.js +110 -0
  18. package/dist/AST/WASM/Function.js.map +1 -0
  19. package/dist/AST/WASM/Memory.d.ts +12 -0
  20. package/dist/AST/WASM/Memory.js +22 -0
  21. package/dist/AST/WASM/Memory.js.map +1 -0
  22. package/dist/AST/WASM/Section.d.ts +5 -0
  23. package/dist/AST/WASM/Section.js +11 -0
  24. package/dist/AST/WASM/Section.js.map +1 -0
  25. package/dist/AST/WASM.d.ts +58 -0
  26. package/dist/AST/WASM.js +277 -0
  27. package/dist/AST/WASM.js.map +1 -0
  28. package/dist/AST/XHRNode.d.ts +15 -0
  29. package/dist/AST/XHRNode.js +146 -0
  30. package/dist/AST/XHRNode.js.map +1 -0
  31. package/dist/AST.d.ts +62 -55
  32. package/dist/AST.js +123 -83
  33. package/dist/AST.js.map +1 -1
  34. package/dist/DOM/DOMObject.d.ts +1 -0
  35. package/dist/DOM/DOMObject.js +6 -0
  36. package/dist/DOM/DOMObject.js.map +1 -1
  37. package/dist/DOM.js +61 -90
  38. package/dist/DOM.js.map +1 -1
  39. package/dist/Registry.d.ts +2 -0
  40. package/dist/Registry.js +13 -9
  41. package/dist/Registry.js.map +1 -1
  42. package/dist/Scope/ScopeDataAbstract.js +2 -2
  43. package/dist/Scope/ScopeDataAbstract.js.map +1 -1
  44. package/dist/Scope/properties/Property.d.ts +5 -6
  45. package/dist/Scope/properties/Property.js +17 -25
  46. package/dist/Scope/properties/Property.js.map +1 -1
  47. package/dist/Scope/properties/_imports.d.ts +1 -1
  48. package/dist/Scope/properties/_imports.js.map +1 -1
  49. package/dist/Tag.d.ts +1 -0
  50. package/dist/Tag.js +9 -11
  51. package/dist/Tag.js.map +1 -1
  52. package/dist/attributes/StandardAttribute.js +4 -1
  53. package/dist/attributes/StandardAttribute.js.map +1 -1
  54. package/dist/attributes/_imports.d.ts +0 -2
  55. package/dist/attributes/_imports.js +1 -5
  56. package/dist/attributes/_imports.js.map +1 -1
  57. package/dist/helpers/VisionHelper.d.ts +1 -0
  58. package/dist/helpers/VisionHelper.js +17 -0
  59. package/dist/helpers/VisionHelper.js.map +1 -1
  60. package/dist/vsn.d.ts +3 -2
  61. package/dist/vsn.js +7 -3
  62. package/dist/vsn.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/AST/ArithmeticAssignmentNode.ts +9 -2
  65. package/src/AST/FunctionNode.ts +0 -0
  66. package/src/AST/StringFormatNode.ts +43 -0
  67. package/src/AST/WASM/Context.ts +12 -0
  68. package/src/AST/WASM/Function.ts +67 -0
  69. package/src/AST/WASM/Memory.ts +21 -0
  70. package/src/AST/WASM/Section.ts +6 -0
  71. package/src/AST/WASM.ts +244 -0
  72. package/src/AST/XHRNode.ts +81 -0
  73. package/src/AST.ts +66 -31
  74. package/src/DOM/DOMObject.ts +6 -0
  75. package/src/DOM.ts +11 -25
  76. package/src/Registry.ts +12 -9
  77. package/src/Scope/ScopeDataAbstract.ts +2 -2
  78. package/src/Scope/properties/Property.ts +17 -28
  79. package/src/Scope/properties/_imports.ts +1 -1
  80. package/src/Tag.ts +10 -9
  81. package/src/attributes/AddClassIf.ts +1 -1
  82. package/src/attributes/StandardAttribute.ts +4 -2
  83. package/src/attributes/_imports.ts +0 -2
  84. package/src/helpers/VisionHelper.ts +13 -0
  85. package/src/vsn.ts +3 -2
  86. package/test/AST/ArithmeticAssignmentNode.spec.ts +0 -2
  87. package/test/AST/StringFormatNode.spec.ts +12 -0
  88. package/test/AST/WASM.spec.ts +63 -0
  89. package/test/AST/XHRNode.spec.ts +10 -0
  90. package/test/Scope/ScopeData.spec.ts +5 -5
  91. package/types/vsn-component.d.ts +5 -0
  92. package/dist/attributes/ClickRemoveClass.d.ts +0 -8
  93. package/dist/attributes/ClickRemoveClass.js +0 -114
  94. package/dist/attributes/ClickRemoveClass.js.map +0 -1
  95. package/dist/attributes/ClickToggleClass.d.ts +0 -8
  96. package/dist/attributes/ClickToggleClass.js.map +0 -1
  97. package/src/attributes/ClickRemoveClass.ts +0 -30
  98. package/src/attributes/ClickToggleClass.ts +0 -30
@@ -0,0 +1,244 @@
1
+ import {VisionHelper} from "../helpers/VisionHelper";
2
+ import {FunctionSection} from "./WASM/Function";
3
+
4
+
5
+ const dummyFunc = (...args: any[]): any => null;
6
+ const dummyVal = null;
7
+
8
+ let _ieee754 = dummyFunc;
9
+ let _encodeString = dummyFunc;
10
+ let _signedLEB128 = dummyFunc;
11
+ let _unsignedLEB128 = dummyFunc;
12
+
13
+
14
+ _ieee754 = (n: number) => {
15
+ const buf = Buffer.allocUnsafe(4);
16
+ buf.writeFloatLE(n, 0);
17
+ return Uint8Array.from(buf);
18
+ };
19
+
20
+ _encodeString = (str: string) => [
21
+ str.length,
22
+ ...str.split("").map(s => s.charCodeAt(0))
23
+ ];
24
+
25
+ _signedLEB128 = (n: number) => {
26
+ const buffer = [];
27
+ let more = true;
28
+ const isNegative = n < 0;
29
+ const bitCount = Math.ceil(Math.log2(Math.abs(n))) + 1;
30
+ while (more) {
31
+ let byte = n & 0x7f;
32
+ n >>= 7;
33
+ if (isNegative) {
34
+ n = n | -(1 << (bitCount - 8));
35
+ }
36
+ if ((n === 0 && (byte & 0x40) === 0) || (n === -1 && (byte & 0x40) !== 0x40)) {
37
+ more = false;
38
+ } else {
39
+ byte |= 0x80;
40
+ }
41
+ buffer.push(byte);
42
+ }
43
+ return buffer;
44
+ };
45
+
46
+ _unsignedLEB128 = (n: number) => {
47
+ const buffer = [];
48
+ do {
49
+ let byte = n & 0x7f;
50
+ n >>>= 7;
51
+ if (n !== 0) {
52
+ byte |= 0x80;
53
+ }
54
+ buffer.push(byte);
55
+ } while (n !== 0);
56
+ return buffer;
57
+ };
58
+
59
+
60
+ export const ieee754 = _ieee754;
61
+ export const encodeString = _encodeString;
62
+ export const signedLEB128 = _signedLEB128;
63
+ export const unsignedLEB128 = _unsignedLEB128;
64
+
65
+ export const flatten = (arr: any[]) => {
66
+ return [].concat.apply([], arr);
67
+ }
68
+
69
+ enum ESectionType {
70
+ custom = 0,
71
+ type = 1,
72
+ import = 2,
73
+ func = 3,
74
+ table = 4,
75
+ memory = 5,
76
+ global = 6,
77
+ export = 7,
78
+ start = 8,
79
+ element = 9,
80
+ code = 10,
81
+ data = 11
82
+ }
83
+
84
+ // https://webassembly.github.io/spec/core/binary/types.html
85
+ export enum EValueType {
86
+ i32 = 0x7f,
87
+ f32 = 0x7d
88
+ }
89
+
90
+ // https://webassembly.github.io/spec/core/binary/types.html#binary-blocktype
91
+ export enum EBlockType {
92
+ void = 0x40
93
+ }
94
+
95
+ // https://webassembly.github.io/spec/core/binary/instructions.html
96
+ export enum EOpCode {
97
+ block = 0x02,
98
+ loop = 0x03,
99
+ br = 0x0c,
100
+ br_if = 0x0d,
101
+ end = 0x0b,
102
+ call = 0x10,
103
+ get_local = 0x20,
104
+ set_local = 0x21,
105
+ i32_store_8 = 0x3a,
106
+ i32_const = 0x41,
107
+ f32_const = 0x43,
108
+ i32_add = 0x6a,
109
+ i32_sub = 0x6B,
110
+ i32_mul = 0x6C,
111
+ i32_div = 0x6D,
112
+ i32_eqz = 0x45,
113
+ i32_eq = 0x46,
114
+ f32_eq = 0x5b,
115
+ f32_lt = 0x5d,
116
+ f32_gt = 0x5e,
117
+ i32_and = 0x71,
118
+ f32_add = 0x92,
119
+ f32_sub = 0x93,
120
+ f32_mul = 0x94,
121
+ f32_div = 0x95,
122
+ i32_trunc_f32_s = 0xa8,
123
+ memory_size = 0x3f,
124
+ memory_grow = 0x40,
125
+
126
+ // Vision op codes
127
+ scope_get = 0x400,
128
+ scope_set = 0x401
129
+ }
130
+
131
+ const binaryOpcode = {
132
+ "+": EOpCode.f32_add,
133
+ "-": EOpCode.f32_sub,
134
+ "*": EOpCode.f32_mul,
135
+ "/": EOpCode.f32_div,
136
+ "==": EOpCode.f32_eq,
137
+ ">": EOpCode.f32_gt,
138
+ "<": EOpCode.f32_lt,
139
+ "&&": EOpCode.i32_and
140
+ };
141
+
142
+ // http://webassembly.github.io/spec/core/binary/modules.html#export-section
143
+ export enum EExportType {
144
+ func = 0x00,
145
+ table = 0x01,
146
+ mem = 0x02,
147
+ global = 0x03
148
+ }
149
+
150
+ // http://webassembly.github.io/spec/core/binary/types.html#function-types
151
+ export const functionType = 0x60;
152
+
153
+ export const emptyArray = 0x0;
154
+
155
+ // https://webassembly.github.io/spec/core/binary/modules.html#binary-module
156
+ const magicModuleHeader = [0x00, 0x61, 0x73, 0x6d];
157
+ const moduleVersion = [0x01, 0x00, 0x00, 0x00];
158
+
159
+ // https://webassembly.github.io/spec/core/binary/conventions.html#binary-vec
160
+ // Vectors are encoded with their length followed by their element sequence
161
+ export const encodeVector = (data: any[]) => [
162
+ ...unsignedLEB128(data.length),
163
+ ...flatten(data)
164
+ ];
165
+
166
+ // https://webassembly.github.io/spec/core/binary/modules.html#code-section
167
+ export const encodeLocal = (count: number, type: EValueType) => [
168
+ ...unsignedLEB128(count),
169
+ type
170
+ ];
171
+
172
+ // https://webassembly.github.io/spec/core/binary/modules.html#sections
173
+ // sections are encoded by their type followed by their vector contents
174
+ const createSection = (sectionType: ESectionType, data: any[]) => [
175
+ sectionType,
176
+ ...encodeVector(data)
177
+ ];
178
+
179
+ /*
180
+ Building a WASM program...
181
+ Based off of Chasm:
182
+ https://github.com/ColinEberhardt/chasm/blob/master/src/emitter.ts
183
+ https://webassembly.github.io/wabt/demo/wat2wasm/
184
+ */
185
+
186
+ export const emitter = (functions: FunctionSection[]) => {
187
+ // Types section
188
+ const typesSection = createSection(ESectionType.type, [
189
+ functions.length, // Number of types
190
+ ...flatten(functions.map((func) => func.sectionTypes))
191
+ ]);
192
+
193
+ // Functions section
194
+ const functionsSection = createSection(ESectionType.func, [
195
+ functions.length, // number of functions
196
+ ...functions.map((func, i) => i)
197
+ ]);
198
+
199
+ // Export section
200
+ const exportSection = createSection(
201
+ ESectionType.export,
202
+ encodeVector(functions.map((func,i) => [...func.sectionExport, i]))
203
+ );
204
+
205
+ const codeSection = createSection(ESectionType.code, [
206
+ functions.length, // Number of functions
207
+ ...flatten(functions.map((func) => func.sectionCode))
208
+ ]);
209
+
210
+ return Uint8Array.from([
211
+ ...magicModuleHeader,
212
+ ...moduleVersion,
213
+ ...typesSection,
214
+ ...functionsSection,
215
+ ...exportSection,
216
+ ...codeSection
217
+ ]);
218
+ }
219
+
220
+ const defaultMemory: WebAssembly.Memory = new WebAssembly.Memory({initial: 10, maximum: 100, shared: true} as WebAssembly.MemoryDescriptor);
221
+
222
+ export async function compile(functions: FunctionSection[], memory?: WebAssembly.Memory) {
223
+ memory = memory || defaultMemory;
224
+ const wasm = emitter(functions);
225
+ return await WebAssembly.instantiate(wasm, {
226
+ js: {
227
+ memory: memory
228
+ }
229
+ });
230
+ }
231
+
232
+ export async function run(functions: FunctionSection | FunctionSection[], ...args) {
233
+ const memory = args[0] instanceof WebAssembly.Memory && args[0] || defaultMemory;
234
+ if (functions instanceof FunctionSection)
235
+ functions = [functions];
236
+
237
+ const wasm = await compile(functions, memory);
238
+ return 'main' in wasm.instance.exports ? (wasm.instance.exports.main as any)(...args) : wasm;
239
+ }
240
+
241
+ if (VisionHelper.window)
242
+ window['wasm'] = {
243
+ compile: compile
244
+ }
@@ -0,0 +1,81 @@
1
+ import {Node} from "./Node";
2
+ import {Token, TokenType, Tree, TreeNode} from "../AST";
3
+ import {Scope} from "../Scope";
4
+ import {DOM} from "../DOM";
5
+ import {Tag} from "../Tag";
6
+ import {ScopeDataAbstract} from "../Scope/ScopeDataAbstract";
7
+
8
+ export class XHRNode extends Node implements TreeNode {
9
+ constructor(
10
+ public readonly left: Node | null,
11
+ public readonly requestType: TokenType,
12
+ public readonly url: Node
13
+ ) {
14
+ super();
15
+ }
16
+
17
+ public getChildNodes(): Node[] {
18
+ const nodes = [this.url];
19
+ if (this.left)
20
+ nodes.push(this.left);
21
+ return nodes;
22
+ }
23
+
24
+ async evaluate(scope: Scope, dom: DOM, tag?: Tag) {
25
+ const url = await this.url.evaluate(scope, dom, tag);
26
+ let method: string;
27
+ let data = this.left ? await this.left.evaluate(scope, dom, tag) : {};
28
+
29
+ if (data instanceof Scope)
30
+ data = data.data;
31
+
32
+ if (data instanceof ScopeDataAbstract)
33
+ data = data.getData();
34
+
35
+ switch (this.requestType) {
36
+ case TokenType.XHR_POST:
37
+ method = "POST";
38
+ break;
39
+ case TokenType.XHR_PUT:
40
+ method = "PUT";
41
+ break;
42
+ case TokenType.XHR_DELETE:
43
+ method = "DELETE";
44
+ break;
45
+ default:
46
+ method = "GET";
47
+ }
48
+
49
+ let request = {
50
+ method: method
51
+ };
52
+
53
+ if (request.method === 'GET') {
54
+
55
+ } else {
56
+ request['body'] = (typeof data === "string") ? data : JSON.stringify(data);
57
+ }
58
+
59
+ const response = await fetch(url, request);
60
+ const contentType = response.headers.get('content-type');
61
+ if (contentType && contentType.includes('application/json')) {
62
+ return await response.json();
63
+ }
64
+ return await response.text();
65
+ }
66
+
67
+ public static parse(node: Node, token: Token, tokens: Token[]): XHRNode {
68
+ tokens.splice(0, 1); // Consume request type
69
+ const url = Tree.processTokens(Tree.getNextStatementTokens(tokens, false, false, false));
70
+ return new XHRNode(node, token.type, url);
71
+ }
72
+
73
+ public static match(tokens: Token[]) {
74
+ return [
75
+ TokenType.XHR_POST,
76
+ TokenType.XHR_PUT,
77
+ TokenType.XHR_GET,
78
+ TokenType.XHR_DELETE,
79
+ ].indexOf(tokens[0].type) > -1;
80
+ }
81
+ }
package/src/AST.ts CHANGED
@@ -24,6 +24,8 @@ import {ArithmeticAssignmentNode} from "./AST/ArithmeticAssignmentNode";
24
24
  import {UnitLiteralNode} from "./AST/UnitLiteralNode";
25
25
  import {BooleanLiteralNode} from "./AST/BooleanLiteralNode";
26
26
  import {NotNode} from "./AST/NotNode";
27
+ import {XHRNode} from "./AST/XHRNode";
28
+ import {StringFormatNode} from "./AST/StringFormatNode";
27
29
 
28
30
  function lower(str: string): string {
29
31
  return str ? str.toLowerCase() : null;
@@ -47,6 +49,7 @@ export enum BlockType {
47
49
  }
48
50
 
49
51
  export enum TokenType {
52
+ NULL,
50
53
  WHITESPACE,
51
54
  TYPE_INT,
52
55
  TYPE_UINT,
@@ -71,7 +74,8 @@ export enum TokenType {
71
74
  PERIOD,
72
75
  COMMA,
73
76
  COLON,
74
- SEMI_COLON,
77
+ SEMICOLON,
78
+ STRING_FORMAT,
75
79
  STRING_LITERAL,
76
80
  NUMBER_LITERAL,
77
81
  BOOLEAN_LITERAL,
@@ -101,6 +105,10 @@ export enum TokenType {
101
105
  ELEMENT_STYLE,
102
106
  ELEMENT_QUERY,
103
107
  UNIT,
108
+ XHR_GET,
109
+ XHR_POST,
110
+ XHR_PUT,
111
+ XHR_DELETE,
104
112
  }
105
113
 
106
114
  const TOKEN_PATTERNS: TokenPattern[] = [
@@ -108,6 +116,22 @@ const TOKEN_PATTERNS: TokenPattern[] = [
108
116
  type: TokenType.WHITESPACE,
109
117
  pattern: /^[\s\n\r]+/
110
118
  },
119
+ {
120
+ type: TokenType.XHR_POST,
121
+ pattern: /^>>/
122
+ },
123
+ {
124
+ type: TokenType.XHR_PUT,
125
+ pattern: /^<>/
126
+ },
127
+ {
128
+ type: TokenType.XHR_GET,
129
+ pattern: /^<</
130
+ },
131
+ {
132
+ type: TokenType.XHR_DELETE,
133
+ pattern: /^></
134
+ },
111
135
  {
112
136
  type: TokenType.TYPE_INT,
113
137
  pattern: /^int+/
@@ -257,9 +281,13 @@ const TOKEN_PATTERNS: TokenPattern[] = [
257
281
  pattern: /^:/
258
282
  },
259
283
  {
260
- type: TokenType.SEMI_COLON,
284
+ type: TokenType.SEMICOLON,
261
285
  pattern: /^;/
262
286
  },
287
+ {
288
+ type: TokenType.STRING_FORMAT,
289
+ pattern: /^`([^`]*)`/
290
+ },
263
291
  {
264
292
  type: TokenType.STRING_LITERAL,
265
293
  pattern: /^"([^"]*)"/
@@ -341,36 +369,38 @@ export const AttributableNodes = [
341
369
 
342
370
  export class Tree {
343
371
  protected static cache: { [key: string]: Node } = {};
344
- protected rootNode: Node;
372
+ protected _root: Node;
345
373
 
346
374
  constructor(
347
375
  public readonly code: string
348
376
  ) {
349
377
  if (Tree.cache[code]) {
350
- this.rootNode = Tree.cache[code];
378
+ this._root = Tree.cache[code];
351
379
  } else {
352
380
  this.parse();
353
- Tree.cache[code] = this.rootNode;
381
+ Tree.cache[code] = this._root;
354
382
  }
355
383
  }
356
384
 
385
+ public get root(): Node { return this._root; }
386
+
357
387
  public parse() {
358
388
  const tokens = Tree.tokenize(this.code);
359
- this.rootNode = Tree.processTokens(tokens);
389
+ this._root = Tree.processTokens(tokens);
360
390
  }
361
391
 
362
392
  async evaluate(scope: Scope, dom: DOM, tag: Tag = null) {
363
- return await this.rootNode.evaluate(scope, dom, tag);
393
+ return await this._root.evaluate(scope, dom, tag);
364
394
  }
365
395
 
366
396
  async prepare(scope: Scope, dom: DOM, tag: Tag = null) {
367
- if (!this.rootNode.isPreparationRequired())
397
+ if (!this._root.isPreparationRequired())
368
398
  return;
369
- return await this.rootNode.prepare(scope, dom, tag);
399
+ return await this._root.prepare(scope, dom, tag);
370
400
  }
371
401
 
372
402
  async bindToScopeChanges(scope, fnc, dom: DOM, tag: Tag = null) {
373
- for (const node of this.rootNode.findChildrenByTypes<ScopeMemberNode | ElementAttributeNode>([RootScopeMemberNode, ScopeMemberNode, ElementAttributeNode], 'ScopeMemberNodes')) {
403
+ for (const node of this._root.findChildrenByTypes<ScopeMemberNode | ElementAttributeNode>([RootScopeMemberNode, ScopeMemberNode, ElementAttributeNode], 'ScopeMemberNodes')) {
374
404
  let _scope: Scope = scope;
375
405
  if (node instanceof ScopeMemberNode)
376
406
  _scope = await node.scope.evaluate(scope, dom);
@@ -431,14 +461,16 @@ export class Tree {
431
461
  if (count > 1000) break; // Limit to 1000 iterations while in development
432
462
 
433
463
  if (tokens[0].type === TokenType.RETURN)
434
- tokens.splice(0, 1);
464
+ tokens.shift()
435
465
 
436
466
  const token: Token = tokens[0];
437
467
  if (token.type === TokenType.NAME) {
438
468
  node = new RootScopeMemberNode<string>(
439
469
  new LiteralNode<string>(token.value)
440
470
  );
441
- tokens.splice(0, 1);
471
+ tokens.shift()
472
+ } else if (XHRNode.match(tokens)) {
473
+ node = XHRNode.parse(node, tokens[0], tokens);
442
474
  } else if (token.type === TokenType.IF) {
443
475
  node = IfStatementNode.parse(node, token, tokens);
444
476
  blockNodes.push(node);
@@ -447,18 +479,20 @@ export class Tree {
447
479
  node = ForStatementNode.parse(node, token, tokens);
448
480
  blockNodes.push(node);
449
481
  node = null;
482
+ } else if (StringFormatNode.match(tokens)) {
483
+ node = StringFormatNode.parse(node, tokens[0], tokens);
450
484
  } else if (token.type === TokenType.STRING_LITERAL) {
451
485
  node = new LiteralNode(token.value);
452
- tokens.splice(0, 1);
486
+ tokens.shift()
453
487
  } else if (token.type === TokenType.NUMBER_LITERAL) {
454
488
  node = new NumberLiteralNode(token.value);
455
- tokens.splice(0, 1);
489
+ tokens.shift()
456
490
  } else if (tokens[0].type === TokenType.ELEMENT_REFERENCE) {
457
491
  node = new ElementQueryNode(tokens[0].value, true);
458
- tokens.splice(0, 1);
492
+ tokens.shift()
459
493
  } else if (tokens[0].type === TokenType.ELEMENT_QUERY) {
460
494
  node = new ElementQueryNode(tokens[0].value);
461
- tokens.splice(0, 1);
495
+ tokens.shift()
462
496
  } else if (tokens[0].type === TokenType.L_BRACKET) {
463
497
  if (node) {
464
498
  node = IndexNode.parse(node, token, tokens);
@@ -469,10 +503,10 @@ export class Tree {
469
503
  node = ObjectNode.parse(node, token, tokens);
470
504
  } else if (tokens[0].type === TokenType.ELEMENT_ATTRIBUTE) {
471
505
  node = new ElementAttributeNode(node as any, tokens[0].value);
472
- tokens.splice(0, 1);
506
+ tokens.shift()
473
507
  } else if (tokens[0].type === TokenType.ELEMENT_STYLE) {
474
508
  node = new ElementStyleNode(node as any, tokens[0].value);
475
- tokens.splice(0, 1);
509
+ tokens.shift()
476
510
  } else if (node !== null && token.type === TokenType.PERIOD && tokens[1].type === TokenType.NAME) {
477
511
  node = new ScopeMemberNode(
478
512
  node,
@@ -493,12 +527,12 @@ export class Tree {
493
527
  } else {
494
528
  node = new BlockNode(nodes);
495
529
  }
496
- } else if (tokens[0].type === TokenType.SEMI_COLON) {
530
+ } else if (tokens[0].type === TokenType.SEMICOLON) {
497
531
  if (node) {
498
532
  blockNodes.push(node);
499
533
  }
500
534
  node = null;
501
- tokens.splice(0, 1);
535
+ tokens.shift()
502
536
  } else if (InNode.match(tokens)) {
503
537
  node = InNode.parse(node, token, tokens);
504
538
  } else if (ComparisonNode.match(tokens)) {
@@ -508,16 +542,16 @@ export class Tree {
508
542
  } else if (ArithmeticAssignmentNode.match(tokens)) {
509
543
  node = ArithmeticAssignmentNode.parse(node, token, tokens);
510
544
  } else if (tokens[0].type === TokenType.WHITESPACE) {
511
- tokens.splice(0, 1);
545
+ tokens.shift()
512
546
  } else if (tokens[0].type === TokenType.UNIT) {
513
547
  node = new UnitLiteralNode(tokens[0].value);
514
- tokens.splice(0, 1);
548
+ tokens.shift()
515
549
  } else if (tokens[0].type === TokenType.BOOLEAN_LITERAL) {
516
550
  node = new BooleanLiteralNode(tokens[0].value);
517
- tokens.splice(0, 1);
551
+ tokens.shift()
518
552
  } else if (tokens[0].type === TokenType.NULL_LITERAL) {
519
553
  node = new LiteralNode(null);
520
- tokens.splice(0, 1);
554
+ tokens.shift()
521
555
  } else if (tokens[0].type === TokenType.EXCLAMATION_POINT) {
522
556
  node = NotNode.parse(node, tokens[0], tokens);
523
557
  } else {
@@ -583,7 +617,7 @@ export class Tree {
583
617
  break;
584
618
  default:
585
619
  open = null;
586
- close = TokenType.SEMI_COLON;
620
+ close = TokenType.SEMICOLON;
587
621
  openCharacter = null;
588
622
  closeCharacter = ';';
589
623
  break;
@@ -603,7 +637,7 @@ export class Tree {
603
637
 
604
638
  // Consume opening block token
605
639
  if (consumeOpeningToken && tokens[0].type === blockInfo.open) {
606
- tokens.splice(0, 1);
640
+ tokens.shift()
607
641
  }
608
642
 
609
643
  return Tree.getTokensUntil(tokens, blockInfo.close, consumeClosingToken, includeClosingToken);
@@ -632,7 +666,7 @@ export class Tree {
632
666
  }
633
667
 
634
668
  // Consume token
635
- tokens.splice(0, 1);
669
+ tokens.shift()
636
670
  i--;
637
671
  if (openBlocks === 0) {
638
672
  if (arg.length > 0)
@@ -644,7 +678,7 @@ export class Tree {
644
678
  throw Error(`Invalid Syntax, missing ${blockInfo.closeCharacter}`);
645
679
  }
646
680
 
647
- public static getTokensUntil(tokens: Token[], terminator: TokenType = TokenType.SEMI_COLON, consumeTerminator: boolean = true, includeTerminator: boolean = false, validIfTerminatorNotFound: boolean = false, blockInfo: IBlockInfo = null): Token[] {
681
+ public static getTokensUntil(tokens: Token[], terminator: TokenType = TokenType.SEMICOLON, consumeTerminator: boolean = true, includeTerminator: boolean = false, validIfTerminatorNotFound: boolean = false, blockInfo: IBlockInfo = null): Token[] {
648
682
  const statementTokens: Token[] = [];
649
683
  blockInfo = blockInfo || Tree.getBlockInfo(tokens);
650
684
 
@@ -681,8 +715,9 @@ export class Tree {
681
715
  if (includeTerminator)
682
716
  statementTokens.push(token);
683
717
 
684
- if ((includeTerminator || consumeTerminator) && token.type !== TokenType.SEMI_COLON)
685
- tokens.splice(0, 1); // Consume end of block
718
+ //if (consumeTerminator && token.type !== TokenType.SEMICOLON)
719
+ if ((includeTerminator || consumeTerminator) && token.type !== TokenType.SEMICOLON)
720
+ tokens.shift() // Consume end of block
686
721
  break;
687
722
  } else if (token.type === terminator && (openParens > 0 || openBraces > 0 || openBrackets > 0)) {
688
723
  } else {
@@ -693,7 +728,7 @@ export class Tree {
693
728
  }
694
729
 
695
730
  statementTokens.push(token);
696
- tokens.splice(0, 1); // Consume part of statement
731
+ tokens.shift() // Consume part of statement
697
732
  i--;
698
733
  }
699
734
  return statementTokens;
@@ -31,4 +31,10 @@ export abstract class DOMObject extends EventDispatcher {
31
31
  public watchStyle(style: string) {
32
32
 
33
33
  }
34
+
35
+ public deconstruct() {
36
+ if (this._uniqueScope)
37
+ this.scope?.deconstruct();
38
+ super.deconstruct();
39
+ }
34
40
  }