j-templates 6.1.11 → 7.0.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.
Files changed (50) hide show
  1. package/DOM/createAssignment.js +4 -5
  2. package/DOM/createAttributeAssignment.d.ts +1 -0
  3. package/DOM/createAttributeAssignment.js +16 -0
  4. package/DOM/createPropertyAssignment.d.ts +1 -0
  5. package/DOM/createPropertyAssignment.js +7 -0
  6. package/DOM/domNodeConfig.js +41 -1
  7. package/DOM/elements.d.ts +80 -26
  8. package/DOM/elements.js +12 -101
  9. package/DOM/index.d.ts +0 -1
  10. package/DOM/index.js +0 -1
  11. package/DOM/svgElements.d.ts +0 -4
  12. package/DOM/svgElements.js +0 -16
  13. package/Node/component.d.ts +19 -16
  14. package/Node/component.js +25 -31
  15. package/Node/component.types.d.ts +5 -0
  16. package/Node/nodeConfig.d.ts +7 -0
  17. package/Node/vNode.d.ts +20 -0
  18. package/Node/vNode.js +296 -0
  19. package/Node/vNode.types.d.ts +45 -0
  20. package/Store/Tree/observableNode.js +1 -2
  21. package/Store/Tree/observableScope.d.ts +3 -4
  22. package/Store/Tree/observableScope.js +64 -66
  23. package/Utils/avlTree.d.ts +15 -0
  24. package/Utils/avlTree.js +139 -0
  25. package/Utils/decorators.d.ts +4 -25
  26. package/Utils/decorators.js +3 -61
  27. package/Utils/distinctArray.d.ts +10 -0
  28. package/Utils/distinctArray.js +26 -0
  29. package/Utils/emitter.d.ts +2 -0
  30. package/Utils/emitter.js +5 -0
  31. package/index.d.ts +1 -2
  32. package/package.json +1 -1
  33. package/Node/boundNode.d.ts +0 -4
  34. package/Node/boundNode.js +0 -115
  35. package/Node/boundNode.types.d.ts +0 -57
  36. package/Node/componentNode.d.ts +0 -7
  37. package/Node/componentNode.js +0 -123
  38. package/Node/componentNode.types.d.ts +0 -37
  39. package/Node/elementNode.d.ts +0 -5
  40. package/Node/elementNode.js +0 -176
  41. package/Node/elementNode.types.d.ts +0 -40
  42. package/Node/elementNode.types.js +0 -2
  43. package/Node/nodeRef.d.ts +0 -26
  44. package/Node/nodeRef.js +0 -252
  45. package/Node/nodeRef.types.d.ts +0 -21
  46. package/Node/nodeRef.types.js +0 -2
  47. package/Node/textNode.types.d.ts +0 -7
  48. package/Node/textNode.types.js +0 -2
  49. /package/Node/{boundNode.types.js → component.types.js} +0 -0
  50. /package/Node/{componentNode.types.js → vNode.types.js} +0 -0
package/Node/vNode.js ADDED
@@ -0,0 +1,296 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.vNode = void 0;
4
+ const Store_1 = require("../Store");
5
+ const injector_1 = require("../Utils/injector");
6
+ const list_1 = require("../Utils/list");
7
+ const thread_1 = require("../Utils/thread");
8
+ const nodeConfig_1 = require("./nodeConfig");
9
+ var vNode;
10
+ (function (vNode) {
11
+ function Create(definition) {
12
+ return {
13
+ definition,
14
+ injector: injector_1.Injector.Current() ?? new injector_1.Injector(),
15
+ node: null,
16
+ children: null,
17
+ destroyed: false,
18
+ assignProperties: null,
19
+ assignEvents: null,
20
+ assignAttributes: null,
21
+ component: null,
22
+ scopes: []
23
+ };
24
+ }
25
+ vNode.Create = Create;
26
+ function Init(vnode) {
27
+ if (vnode.node !== null)
28
+ return;
29
+ InitNode(vnode);
30
+ }
31
+ vNode.Init = Init;
32
+ function InitAll(vnodes) {
33
+ for (let x = 0; x < vnodes.length; x++)
34
+ Init(vnodes[x]);
35
+ }
36
+ vNode.InitAll = InitAll;
37
+ function Destroy(vnode) {
38
+ if (vnode.destroyed)
39
+ return;
40
+ vnode.destroyed = true;
41
+ vnode.assignEvents?.(null);
42
+ vnode.component?.Destroy();
43
+ Store_1.ObservableScope.DestroyAll(vnode.scopes);
44
+ vnode.children && DestroyAll(vnode.children);
45
+ }
46
+ vNode.Destroy = Destroy;
47
+ function DestroyAll(vnodes) {
48
+ for (let x = 0; x < vnodes.length; x++)
49
+ Destroy(vnodes[x]);
50
+ }
51
+ vNode.DestroyAll = DestroyAll;
52
+ function ToFunction(type, namespace) {
53
+ return function (config, children) {
54
+ const childrenConfig = children ? Array.isArray(children) ? { childrenArray: children } : { children } : undefined;
55
+ const definition = Object.assign({
56
+ type,
57
+ namespace: namespace ?? null
58
+ }, config, childrenConfig);
59
+ return Create(definition);
60
+ };
61
+ }
62
+ vNode.ToFunction = ToFunction;
63
+ function Attach(node, vnode) {
64
+ Init(vnode);
65
+ nodeConfig_1.NodeConfig.addChild(node, vnode.node);
66
+ return vnode;
67
+ }
68
+ vNode.Attach = Attach;
69
+ })(vNode || (exports.vNode = vNode = {}));
70
+ function InitNode(vnode) {
71
+ const { type, namespace, props, attrs, on, data, componentConstructor, children, childrenArray } = vnode.definition;
72
+ const node = nodeConfig_1.NodeConfig.createNode(type, namespace);
73
+ vnode.node = node;
74
+ if (props) {
75
+ vnode.assignProperties = nodeConfig_1.NodeConfig.createPropertyAssignment(node);
76
+ if (typeof props === 'function') {
77
+ const scope = Store_1.ObservableScope.Create(props);
78
+ vnode.scopes.push(scope);
79
+ Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
80
+ const value = Store_1.ObservableScope.Peek(scope);
81
+ vnode.assignProperties(value);
82
+ }));
83
+ const value = Store_1.ObservableScope.Peek(scope);
84
+ vnode.assignProperties(value);
85
+ }
86
+ else {
87
+ vnode.assignProperties(props);
88
+ vnode.assignProperties = null;
89
+ }
90
+ }
91
+ if (on) {
92
+ vnode.assignEvents = nodeConfig_1.NodeConfig.createEventAssignment(node);
93
+ if (typeof on === 'function') {
94
+ const scope = Store_1.ObservableScope.Create(on);
95
+ vnode.scopes.push(scope);
96
+ Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
97
+ const value = Store_1.ObservableScope.Peek(scope);
98
+ vnode.assignEvents(value);
99
+ }));
100
+ const value = Store_1.ObservableScope.Peek(scope);
101
+ vnode.assignEvents(value);
102
+ }
103
+ else
104
+ vnode.assignEvents(on);
105
+ }
106
+ if (attrs) {
107
+ vnode.assignAttributes = nodeConfig_1.NodeConfig.createAttributeAssignment(node);
108
+ if (typeof attrs === 'function') {
109
+ const scope = Store_1.ObservableScope.Create(attrs);
110
+ vnode.scopes.push(scope);
111
+ Store_1.ObservableScope.Watch(scope, CreateScheduledCallback(function () {
112
+ const value = Store_1.ObservableScope.Peek(scope);
113
+ vnode.assignAttributes(value);
114
+ }));
115
+ const value = Store_1.ObservableScope.Peek(scope);
116
+ vnode.assignAttributes(value);
117
+ }
118
+ else {
119
+ vnode.assignAttributes(attrs);
120
+ vnode.assignAttributes = null;
121
+ }
122
+ }
123
+ if (componentConstructor) {
124
+ vnode.component = new componentConstructor(vnode);
125
+ const componentScope = Store_1.ObservableScope.Create(function () {
126
+ let nodes = vnode.component.Template();
127
+ if (!Array.isArray(nodes))
128
+ nodes = [nodes];
129
+ return nodes;
130
+ });
131
+ vnode.scopes.push(componentScope);
132
+ Store_1.ObservableScope.Watch(componentScope, CreateScheduledCallback(function () {
133
+ const nodes = Store_1.ObservableScope.Peek(componentScope);
134
+ vNode.DestroyAll(vnode.children);
135
+ vnode.children = nodes;
136
+ UpdateChildren(vnode);
137
+ }));
138
+ const nodes = Store_1.ObservableScope.Peek(componentScope);
139
+ vnode.children = nodes;
140
+ }
141
+ else if (childrenArray) {
142
+ vnode.children = childrenArray;
143
+ }
144
+ else if (children) {
145
+ if (data) {
146
+ DynamicChildren(vnode, children, ToArray(data));
147
+ }
148
+ else
149
+ StaticChildren(vnode, children);
150
+ }
151
+ UpdateChildren(vnode, true);
152
+ }
153
+ function StaticChildren(vnode, children) {
154
+ const childrenScope = Store_1.ObservableScope.Create(WrapStaticChildren(vnode.injector, children));
155
+ const child = Store_1.ObservableScope.Peek(childrenScope);
156
+ if (typeof child === 'string') {
157
+ const node = vNode.Create({
158
+ type: 'text',
159
+ namespace: null,
160
+ props() {
161
+ return { nodeValue: Store_1.ObservableScope.Value(childrenScope) };
162
+ }
163
+ });
164
+ node.scopes.push(childrenScope);
165
+ vnode.children = [node];
166
+ }
167
+ else {
168
+ vnode.scopes.push(childrenScope);
169
+ Store_1.ObservableScope.Touch(childrenScope);
170
+ Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function () {
171
+ vNode.DestroyAll(vnode.children);
172
+ const nodes = Store_1.ObservableScope.Peek(childrenScope);
173
+ vnode.children = Array.isArray(nodes) ? nodes : [nodes];
174
+ UpdateChildren(vnode);
175
+ }));
176
+ vnode.children = Array.isArray(child) ? child : [child];
177
+ }
178
+ }
179
+ function WrapStaticChildren(injector, children) {
180
+ return function () {
181
+ return injector_1.Injector.Scope(injector, children, undefined);
182
+ };
183
+ }
184
+ function DestroyNodeList(nodeList) {
185
+ for (let node = nodeList.head; node !== null; node = node.next) {
186
+ vNode.DestroyAll(node.data.nodes);
187
+ Store_1.ObservableScope.Destroy(node.data.scope);
188
+ }
189
+ }
190
+ function DynamicChildren(vnode, children, data) {
191
+ const dataScope = Store_1.ObservableScope.Create(data);
192
+ vnode.scopes.push(dataScope);
193
+ const nodeList = list_1.List.Create();
194
+ const childrenScope = Store_1.ObservableScope.Create(WrapDynamicChildren(dataScope, nodeList, vnode.injector, children));
195
+ vnode.scopes.push(childrenScope);
196
+ Store_1.ObservableScope.OnDestroyed(dataScope, function () {
197
+ DestroyNodeList(nodeList);
198
+ });
199
+ Store_1.ObservableScope.Watch(childrenScope, CreateScheduledCallback(function () {
200
+ vnode.children = Store_1.ObservableScope.Peek(childrenScope);
201
+ UpdateChildren(vnode);
202
+ }));
203
+ vnode.children = Store_1.ObservableScope.Value(childrenScope);
204
+ }
205
+ function WrapDynamicChildren(dataScope, nodeList, injector, children) {
206
+ return function () {
207
+ const nextData = Store_1.ObservableScope.Value(dataScope);
208
+ const nodeMap = list_1.List.ToNodeMap(nodeList, function (data) { return data.data; });
209
+ const nextNodeList = list_1.List.Create();
210
+ const nextNodeArray = [];
211
+ for (let x = 0; x < nextData.length; x++) {
212
+ const data = nextData[x];
213
+ const existingNodeArray = nodeMap.get(data);
214
+ let existingNode = null;
215
+ ;
216
+ for (let x = 0; existingNodeArray && x < existingNodeArray.length && existingNode === null; x++) {
217
+ existingNode = existingNodeArray[x];
218
+ existingNodeArray[x] = null;
219
+ }
220
+ if (existingNode !== null) {
221
+ list_1.List.RemoveNode(nodeList, existingNode);
222
+ list_1.List.AddNode(nextNodeList, existingNode);
223
+ if (existingNode.data.scope.dirty) {
224
+ const newNodes = Store_1.ObservableScope.Value(existingNode.data.scope);
225
+ vNode.DestroyAll(existingNode.data.nodes);
226
+ existingNode.data.nodes = newNodes;
227
+ existingNode.data.nodes = Store_1.ObservableScope.Value(existingNode.data.scope);
228
+ }
229
+ }
230
+ else {
231
+ const childrenScope = Store_1.ObservableScope.Create(function () {
232
+ const childNodes = injector_1.Injector.Scope(injector, children, data);
233
+ return Array.isArray(childNodes) ? childNodes : [childNodes];
234
+ });
235
+ list_1.List.Add(nextNodeList, {
236
+ data,
237
+ nodes: Store_1.ObservableScope.Value(childrenScope),
238
+ scope: childrenScope
239
+ });
240
+ }
241
+ nextNodeArray.push(...nextNodeList.tail.data.nodes);
242
+ }
243
+ DestroyNodeList(nodeList);
244
+ list_1.List.Clear(nodeList);
245
+ list_1.List.Append(nodeList, nextNodeList);
246
+ return nextNodeArray;
247
+ };
248
+ }
249
+ function UpdateChildren(vnode, init = false) {
250
+ if (!vnode.children)
251
+ return;
252
+ const children = vnode.children;
253
+ (0, thread_1.Thread)(function () {
254
+ if (vnode.destroyed || children !== vnode.children)
255
+ return;
256
+ for (let x = 0; x < children.length; x++)
257
+ if (children[x].node === null) {
258
+ const childNode = children[x];
259
+ (0, thread_1.Schedule)(function () {
260
+ if (vnode.destroyed || children !== vnode.children)
261
+ return;
262
+ vNode.Init(childNode);
263
+ });
264
+ }
265
+ (0, thread_1.Thread)(function (async) {
266
+ if (vnode.destroyed || children !== vnode.children)
267
+ return;
268
+ if (init || !async)
269
+ nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map(vnode => vnode.node));
270
+ else
271
+ nodeConfig_1.NodeConfig.scheduleUpdate(function () {
272
+ if (vnode.destroyed || children !== vnode.children)
273
+ return;
274
+ nodeConfig_1.NodeConfig.reconcileChildren(vnode.node, vnode.children.map(vnode => vnode.node));
275
+ });
276
+ });
277
+ });
278
+ }
279
+ function ToArray(callback) {
280
+ return function (...args) {
281
+ const result = callback(...args);
282
+ if (Array.isArray(result))
283
+ return result;
284
+ if (!result)
285
+ return [];
286
+ return [result];
287
+ };
288
+ }
289
+ function CreateScheduledCallback(callback) {
290
+ let scheduled = false;
291
+ return function () {
292
+ if (scheduled)
293
+ return;
294
+ nodeConfig_1.NodeConfig.scheduleUpdate(callback);
295
+ };
296
+ }
@@ -0,0 +1,45 @@
1
+ import { Component } from "./component";
2
+ import { IObservableScope } from "../Store/Tree/observableScope";
3
+ import { Injector } from "../Utils/injector";
4
+ import { RecursivePartial } from "../Utils/utils.types";
5
+ export type FunctionOr<T> = {
6
+ (): T | Promise<T>;
7
+ } | T;
8
+ export type vNodeEvents<E extends {
9
+ [event: string]: any;
10
+ } = any> = {
11
+ [P in keyof E]?: {
12
+ (events: E[P]): void;
13
+ };
14
+ };
15
+ export type vNode = {
16
+ definition: vNodeDefinition<any, any, any>;
17
+ injector: Injector;
18
+ node: Node | null;
19
+ children: vNode[] | null;
20
+ destroyed: boolean;
21
+ assignProperties: (next: any) => void;
22
+ assignEvents: (next: {
23
+ [event: string]: (event: Event) => void;
24
+ }) => void;
25
+ assignAttributes: (next: {
26
+ [attr: string]: string;
27
+ }) => void;
28
+ scopes: IObservableScope<unknown>[];
29
+ component: Component;
30
+ };
31
+ export type vNodeDefinition<P = HTMLElement, E = HTMLElementEventMap, T = never> = {
32
+ type: string;
33
+ namespace: string | null;
34
+ props?: FunctionOr<RecursivePartial<P>>;
35
+ attrs?: FunctionOr<{
36
+ [name: string]: string;
37
+ }>;
38
+ on?: FunctionOr<vNodeEvents<E>>;
39
+ data?: () => T | Array<T> | Promise<Array<T>> | Promise<T>;
40
+ children?: (data: T) => string | vNode | vNode[];
41
+ childrenArray?: vNode[];
42
+ componentConstructor?: {
43
+ new (vnode: vNode): Component<any, any, any>;
44
+ };
45
+ };
@@ -131,8 +131,7 @@ function CreateProxyFactory(alias) {
131
131
  case "shift":
132
132
  case "sort":
133
133
  case "reverse":
134
- if (readOnly)
135
- throw `Object is readonly`;
134
+ throw "Object is readonly";
136
135
  }
137
136
  switch (prop) {
138
137
  case exports.IS_OBSERVABLE_NODE:
@@ -41,11 +41,9 @@ export interface IObservableScope<T> extends IDestroyable {
41
41
  dirty: boolean;
42
42
  emitter: Emitter;
43
43
  emitters: (Emitter | null)[];
44
- calcFunctions: ICalcFunction<any>[] | null;
44
+ calcFunctions: ICalcFunction<any>[];
45
45
  onDestroyed: Emitter | null;
46
46
  destroyed: boolean;
47
- watchEmitters: Emitter[] | null;
48
- watchEmittersSet: Set<Emitter> | null;
49
47
  }
50
48
  export declare function CalcScope<T>(callback: () => T): T;
51
49
  export declare namespace ObservableScope {
@@ -54,13 +52,14 @@ export declare namespace ObservableScope {
54
52
  }): IObservableScope<T>;
55
53
  function Register(emitter: Emitter): void;
56
54
  function Init<T>(scope: IObservableScope<T>): void;
55
+ function Peek<T>(scope: IObservableScope<T>): T;
57
56
  function Value<T>(scope: IObservableScope<T>): T;
58
- function Watching(): boolean;
59
57
  function Touch<T>(scope: IObservableScope<T>): void;
60
58
  function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
61
59
  function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
62
60
  function OnDestroyed(scope: IObservableScope<unknown>, callback: () => void): void;
63
61
  function Update(scope: IObservableScope<any>): void;
64
62
  function Destroy<T>(scope: IObservableScope<T>): void;
63
+ function DestroyAll(scopes: IObservableScope<unknown>[]): void;
65
64
  }
66
65
  export {};
@@ -3,8 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ObservableScope = exports.ObservableScopeWrapper = exports.ObservableScopeValue = void 0;
4
4
  exports.CalcScope = CalcScope;
5
5
  const array_1 = require("../../Utils/array");
6
+ const distinctArray_1 = require("../../Utils/distinctArray");
6
7
  const emitter_1 = require("../../Utils/emitter");
7
- const list_1 = require("../../Utils/list");
8
8
  class ObservableScopeValue {
9
9
  get Value() {
10
10
  return ObservableScope.Value(this.scope);
@@ -48,28 +48,24 @@ class ObservableScope extends ObservableScopeWrapper {
48
48
  }
49
49
  }
50
50
  exports.ObservableScope = ObservableScope;
51
- let watchingScope = null;
52
- let currentlyWatching = false;
51
+ let watchState = null;
53
52
  function WatchScope(scope) {
54
- const parentScope = watchingScope;
55
- const parentWatching = currentlyWatching;
56
- watchingScope = scope;
57
- currentlyWatching = true;
53
+ const parent = watchState;
54
+ watchState = [distinctArray_1.DistinctArray.Create(emitter_1.Emitter.GetId), []];
58
55
  const value = scope.getFunction();
59
- watchingScope.watchEmittersSet = null;
60
- watchingScope = parentScope;
61
- currentlyWatching = parentWatching;
62
- return value;
56
+ const emitters = distinctArray_1.DistinctArray.Get(watchState[0]);
57
+ emitters.sort(emitter_1.Emitter.Compare);
58
+ const result = [value, emitters, watchState[1]];
59
+ watchState = parent;
60
+ return result;
63
61
  }
64
62
  function CalcScope(callback) {
65
63
  const value = callback();
66
- if (currentlyWatching) {
67
- watchingScope.calcFunctions ??= [];
68
- watchingScope.calcFunctions.push({
64
+ if (watchState !== null)
65
+ watchState[1].push({
69
66
  getFunction: callback,
70
67
  value
71
68
  });
72
- }
73
69
  return value;
74
70
  }
75
71
  (function (ObservableScope) {
@@ -82,11 +78,9 @@ function CalcScope(callback) {
82
78
  dirty: true,
83
79
  emitter: emitter_1.Emitter.Create(),
84
80
  emitters: [],
85
- calcFunctions: null,
81
+ calcFunctions: [],
86
82
  onDestroyed: null,
87
83
  destroyed: false,
88
- watchEmitters: null,
89
- watchEmittersSet: null,
90
84
  setCallback: function () {
91
85
  return OnSet(scope);
92
86
  },
@@ -95,35 +89,31 @@ function CalcScope(callback) {
95
89
  }
96
90
  ObservableScope.Create = Create;
97
91
  function Register(emitter) {
98
- if (!currentlyWatching)
92
+ if (watchState === null)
99
93
  return;
100
- watchingScope.watchEmitters ??= [];
101
- if (watchingScope.watchEmitters.length === 10)
102
- watchingScope.watchEmittersSet ??= new Set(watchingScope.watchEmitters);
103
- if (watchingScope.watchEmittersSet === null ? !watchingScope.watchEmitters.includes(emitter) : !watchingScope.watchEmittersSet.has(emitter)) {
104
- watchingScope.watchEmittersSet?.add(emitter);
105
- watchingScope.watchEmitters.push(emitter);
106
- }
94
+ distinctArray_1.DistinctArray.Push(watchState[0], emitter);
107
95
  }
108
96
  ObservableScope.Register = Register;
109
97
  function Init(scope) {
110
98
  if (!scope)
111
99
  return;
112
- UpdateScope(scope);
100
+ UpdateValue(scope);
113
101
  }
114
102
  ObservableScope.Init = Init;
115
- function Value(scope) {
103
+ function Peek(scope) {
116
104
  if (!scope)
117
105
  return undefined;
118
- Register(scope.emitter);
119
- UpdateScope(scope);
106
+ UpdateValue(scope);
120
107
  return scope.value;
121
108
  }
122
- ObservableScope.Value = Value;
123
- function Watching() {
124
- return currentlyWatching;
109
+ ObservableScope.Peek = Peek;
110
+ function Value(scope) {
111
+ if (!scope)
112
+ return undefined;
113
+ Touch(scope);
114
+ return Peek(scope);
125
115
  }
126
- ObservableScope.Watching = Watching;
116
+ ObservableScope.Value = Value;
127
117
  function Touch(scope) {
128
118
  if (!scope || !scope.emitter)
129
119
  return;
@@ -148,6 +138,8 @@ function CalcScope(callback) {
148
138
  }
149
139
  ObservableScope.OnDestroyed = OnDestroyed;
150
140
  function Update(scope) {
141
+ if (!scope || scope.dirty || scope.destroyed)
142
+ return;
151
143
  OnSet(scope);
152
144
  }
153
145
  ObservableScope.Update = Update;
@@ -155,26 +147,12 @@ function CalcScope(callback) {
155
147
  DestroyScope(scope);
156
148
  }
157
149
  ObservableScope.Destroy = Destroy;
150
+ function DestroyAll(scopes) {
151
+ for (let x = 0; x < scopes.length; x++)
152
+ Destroy(scopes[x]);
153
+ }
154
+ ObservableScope.DestroyAll = DestroyAll;
158
155
  })(ObservableScope || (exports.ObservableScope = ObservableScope = {}));
159
- function UpdateScope(scope) {
160
- const prePromise = scope.promise;
161
- UpdateValue(scope);
162
- scope.async && prePromise !== scope.promise && scope.promise.then(function () {
163
- emitter_1.Emitter.Emit(scope.emitter, scope);
164
- });
165
- }
166
- const updateScopeQueue = list_1.List.Create();
167
- function ProcessScopeUpdateQueue() {
168
- const processList = list_1.List.Split(updateScopeQueue, 0);
169
- for (let node = processList.head; node !== null; node = node.next)
170
- UpdateScope(node.data);
171
- list_1.List.Clear(processList);
172
- }
173
- function QueueScopeUpdate(scope) {
174
- list_1.List.Add(updateScopeQueue, scope);
175
- if (updateScopeQueue.size === 1)
176
- queueMicrotask(ProcessScopeUpdateQueue);
177
- }
178
156
  function CalcChanged(calc) {
179
157
  const value = calc.getFunction();
180
158
  const changed = calc.value !== value;
@@ -182,22 +160,43 @@ function CalcChanged(calc) {
182
160
  return changed;
183
161
  }
184
162
  function DirtyScope(scope) {
185
- scope.dirty = scope.calcFunctions === null || scope.calcFunctions.some(CalcChanged);
186
- scope.dirty && (scope.async ? QueueScopeUpdate(scope) : emitter_1.Emitter.Emit(scope.emitter, scope));
163
+ if (scope.dirty || !scope.getFunction)
164
+ return;
165
+ scope.dirty = scope.calcFunctions.length === 0 || scope.calcFunctions.some(CalcChanged);
166
+ if (!scope.dirty)
167
+ return;
168
+ if (scope.async) {
169
+ UpdateValue(scope);
170
+ scope.promise.then(function () {
171
+ emitter_1.Emitter.Emit(scope.emitter, scope);
172
+ });
173
+ }
174
+ else
175
+ emitter_1.Emitter.Emit(scope.emitter, scope);
176
+ }
177
+ const scopeQueue = new Set();
178
+ function ProcessScopeQueue() {
179
+ const scopes = Array.from(scopeQueue);
180
+ scopeQueue.clear();
181
+ for (let x = 0; x < scopes.length; x++)
182
+ DirtyScope(scopes[x]);
187
183
  }
188
184
  function OnSet(scope) {
189
- if (!scope || scope.dirty || scope.destroyed)
190
- return scope?.destroyed;
185
+ if (scope.destroyed)
186
+ return true;
187
+ if (scope.async || scope.calcFunctions.length > 0) {
188
+ if (scopeQueue.size === 0)
189
+ queueMicrotask(ProcessScopeQueue);
190
+ scopeQueue.add(scope);
191
+ return;
192
+ }
191
193
  DirtyScope(scope);
192
- return false;
193
194
  }
194
195
  function UpdateValue(scope) {
195
196
  if (!scope.dirty)
196
197
  return;
197
198
  scope.dirty = false;
198
- scope.watchEmitters = null;
199
- scope.calcFunctions = null;
200
- const value = WatchScope(scope);
199
+ const [value, emitters, calcFunctions] = WatchScope(scope);
201
200
  if (scope.async) {
202
201
  scope.promise = value.then(function (result) {
203
202
  scope.value = result;
@@ -206,11 +205,11 @@ function UpdateValue(scope) {
206
205
  }
207
206
  else
208
207
  scope.value = value;
209
- UpdateEmitters(scope);
208
+ scope.calcFunctions = calcFunctions;
209
+ UpdateEmitters(scope, emitters);
210
210
  }
211
- function UpdateEmitters(scope) {
212
- const right = scope.watchEmitters;
213
- if (right === null) {
211
+ function UpdateEmitters(scope, right) {
212
+ if (right.length === 0) {
214
213
  if (scope.emitters.length > 0) {
215
214
  for (let x = 0; x < scope.emitters.length; x++)
216
215
  emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
@@ -218,7 +217,6 @@ function UpdateEmitters(scope) {
218
217
  }
219
218
  return;
220
219
  }
221
- emitter_1.Emitter.Sort(right);
222
220
  (0, array_1.ReconcileSortedArrays)(scope.emitters, right, function (emitter) {
223
221
  emitter_1.Emitter.On(emitter, scope.setCallback);
224
222
  }, function (emitter) {
@@ -0,0 +1,15 @@
1
+ type Compare<T> = (a: T, b: T) => number;
2
+ export interface AvlTree<T> {
3
+ size: number;
4
+ root: AvlTreeNode<T> | null;
5
+ compare: Compare<T>;
6
+ }
7
+ export type AvlTreeNode<T> = [T, number, number, AvlTreeNode<T> | null, AvlTreeNode<T> | null];
8
+ export declare namespace AVL {
9
+ function Create<T>(compare: Compare<T>): AvlTree<T>;
10
+ function Clear(tree: AvlTree<unknown>): void;
11
+ function Insert<T>(tree: AvlTree<T>, value: T): void;
12
+ function ForEach<T>(tree: AvlTree<T>, callback: (value: T) => void): void;
13
+ function ToArray<T>(tree: AvlTree<T>): T[];
14
+ }
15
+ export {};