j-templates 7.0.64 → 7.0.66
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/DOM/elements.d.ts +16 -0
- package/DOM/elements.js +3 -1
- package/DOM/index.js +1 -0
- package/DOM/svgElements.js +12 -0
- package/Node/component.d.ts +70 -7
- package/Node/component.js +106 -10
- package/Node/vNode.js +24 -8
- package/Node/vNode.types.d.ts +1 -3
- package/Store/Store/storeAsync.d.ts +78 -0
- package/Store/Store/storeAsync.js +74 -0
- package/Store/Store/storeSync.d.ts +62 -0
- package/Store/Store/storeSync.js +58 -0
- package/Store/Tree/observableScope.d.ts +2 -2
- package/Store/Tree/observableScope.js +4 -4
- package/Utils/animation.d.ts +43 -0
- package/Utils/animation.js +50 -3
- package/Utils/array.d.ts +48 -0
- package/Utils/array.js +56 -0
- package/Utils/decorators.d.ts +140 -5
- package/Utils/decorators.js +274 -27
- package/Utils/injector.d.ts +24 -0
- package/Utils/injector.js +24 -0
- package/Utils/list.js +4 -4
- package/Utils/router.js +110 -0
- package/Utils/thread.d.ts +75 -0
- package/Utils/thread.js +79 -0
- package/package.json +1 -1
package/Utils/decorators.js
CHANGED
|
@@ -1,38 +1,140 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* This module provides decorators for managing state, computed values, and dependency injection in components.
|
|
4
|
+
* These decorators are designed to work with observable data structures, allowing for efficient updates and notifications.
|
|
5
|
+
*
|
|
6
|
+
* @module Utils/Decorators
|
|
7
|
+
* @see ObservableScope
|
|
8
|
+
* @see ObservableNode
|
|
9
|
+
* @see StoreAsync
|
|
10
|
+
* @see StoreSync
|
|
11
|
+
* @see Component
|
|
12
|
+
*/
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.Bound = void 0;
|
|
3
15
|
exports.Computed = Computed;
|
|
4
16
|
exports.ComputedAsync = ComputedAsync;
|
|
5
17
|
exports.State = State;
|
|
6
18
|
exports.Value = Value;
|
|
7
19
|
exports.Scope = Scope;
|
|
20
|
+
exports.Watch = Watch;
|
|
8
21
|
exports.Inject = Inject;
|
|
9
22
|
exports.Destroy = Destroy;
|
|
23
|
+
// import { Component } from "../Node/component";
|
|
10
24
|
const observableScope_1 = require("../Store/Tree/observableScope");
|
|
25
|
+
// import { ElementNodeRefTypes } from "../Node/nodeRef.types";
|
|
11
26
|
const observableNode_1 = require("../Store/Tree/observableNode");
|
|
12
27
|
const Store_1 = require("../Store");
|
|
28
|
+
/**
|
|
29
|
+
* WeakMap for storing node instances and their associated properties.
|
|
30
|
+
* @private
|
|
31
|
+
*/
|
|
13
32
|
const nodeInstanceMap = new WeakMap();
|
|
33
|
+
/**
|
|
34
|
+
* WeakMap for storing scope instances and their associated properties.
|
|
35
|
+
* @private
|
|
36
|
+
*/
|
|
14
37
|
const scopeInstanceMap = new WeakMap();
|
|
38
|
+
const boundPrototypeMap = new WeakMap();
|
|
39
|
+
/**
|
|
40
|
+
* WeakMap for storing arrays of properties that need to be destroyed for each prototype.
|
|
41
|
+
* @private
|
|
42
|
+
*/
|
|
15
43
|
const destroyPrototypeMap = new WeakMap();
|
|
44
|
+
/**
|
|
45
|
+
* Retrieves the node map for a given instance.
|
|
46
|
+
* If the map does not exist, it creates a new one and associates it with the instance.
|
|
47
|
+
* @private
|
|
48
|
+
* @param instance The instance for which to retrieve the node map.
|
|
49
|
+
* @returns The node map associated with the instance.
|
|
50
|
+
*/
|
|
16
51
|
function GetNodeMapForInstance(instance) {
|
|
17
52
|
const map = nodeInstanceMap.get(instance) ?? {};
|
|
18
53
|
nodeInstanceMap.set(instance, map);
|
|
19
54
|
return map;
|
|
20
55
|
}
|
|
56
|
+
/**
|
|
57
|
+
* Retrieves the scope map for a given instance.
|
|
58
|
+
* If the map does not exist, it creates a new one and associates it with the instance.
|
|
59
|
+
* @private
|
|
60
|
+
* @param instance The instance for which to retrieve the scope map.
|
|
61
|
+
* @returns The scope map associated with the instance.
|
|
62
|
+
*/
|
|
21
63
|
function GetScopeMapForInstance(instance) {
|
|
22
64
|
const map = scopeInstanceMap.get(instance) ?? {};
|
|
23
65
|
scopeInstanceMap.set(instance, map);
|
|
24
66
|
return map;
|
|
25
67
|
}
|
|
26
|
-
function
|
|
27
|
-
|
|
28
|
-
|
|
68
|
+
function GetBoundArrayForPrototype(prototype, create = true) {
|
|
69
|
+
let array = boundPrototypeMap.get(prototype);
|
|
70
|
+
if (create) {
|
|
71
|
+
array ??= [];
|
|
72
|
+
boundPrototypeMap.set(prototype, array);
|
|
73
|
+
}
|
|
29
74
|
return array;
|
|
30
75
|
}
|
|
76
|
+
/**
|
|
77
|
+
* Retrieves the destroy array for a given prototype.
|
|
78
|
+
* If the array does not exist, it creates a new one and associates it with the prototype.
|
|
79
|
+
* @private
|
|
80
|
+
* @param prototype The prototype for which to retrieve the destroy array.
|
|
81
|
+
* @returns The array of properties to be destroyed for the prototype.
|
|
82
|
+
*/
|
|
83
|
+
function GetDestroyArrayForPrototype(prototype, create = true) {
|
|
84
|
+
let array = destroyPrototypeMap.get(prototype);
|
|
85
|
+
if (create) {
|
|
86
|
+
array ??= [];
|
|
87
|
+
destroyPrototypeMap.set(prototype, array);
|
|
88
|
+
}
|
|
89
|
+
return array;
|
|
90
|
+
}
|
|
91
|
+
function CreateComputedScope(getter, defaultValue, store) {
|
|
92
|
+
const getterScope = observableScope_1.ObservableScope.Create(getter, true);
|
|
93
|
+
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
94
|
+
const data = observableScope_1.ObservableScope.Value(scope);
|
|
95
|
+
store.Write(data, "root");
|
|
96
|
+
});
|
|
97
|
+
observableScope_1.ObservableScope.Init(getterScope);
|
|
98
|
+
const propertyScope = observableScope_1.ObservableScope.Create(() => store.Get("root", defaultValue));
|
|
99
|
+
observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
|
|
100
|
+
observableScope_1.ObservableScope.Destroy(getterScope);
|
|
101
|
+
if (store instanceof Store_1.StoreAsync)
|
|
102
|
+
store.Destroy();
|
|
103
|
+
});
|
|
104
|
+
return propertyScope;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Computed decorator factory for creating synchronous computed properties.
|
|
108
|
+
* A computed property is derived from other properties and automatically updates when its dependencies change.
|
|
109
|
+
*
|
|
110
|
+
* @example
|
|
111
|
+
* class MyComponent extends Component {
|
|
112
|
+
* @Computed({ count: 0 })
|
|
113
|
+
* get myComputed(): { count: number } {
|
|
114
|
+
* return { count: this.myStateValue };
|
|
115
|
+
* }
|
|
116
|
+
* }
|
|
117
|
+
*
|
|
118
|
+
* @param defaultValue The default value to be used if the computed property is not defined.
|
|
119
|
+
* @returns A property decorator that can be applied to a getter method.
|
|
120
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
121
|
+
* @remarks The computed value is backed by a StoreSync instance, which caches the latest result of the getter. When any of the getter's dependencies change, the StoreSync is updated and the computed property reflects the new value synchronously. The provided `defaultValue` is returned until the first evaluation completes.
|
|
122
|
+
*/
|
|
31
123
|
function Computed(defaultValue) {
|
|
32
124
|
return function (target, propertyKey, descriptor) {
|
|
33
125
|
return ComputedDecorator(target, propertyKey, descriptor, defaultValue);
|
|
34
126
|
};
|
|
35
127
|
}
|
|
128
|
+
/**
|
|
129
|
+
* Computed decorator implementation for creating synchronous computed properties.
|
|
130
|
+
* @private
|
|
131
|
+
* @param target The target object.
|
|
132
|
+
* @param prop The property key.
|
|
133
|
+
* @param descriptor The property descriptor.
|
|
134
|
+
* @param defaultValue The default value to be used if the computed property is not defined.
|
|
135
|
+
* @returns A property descriptor that replaces the original descriptor with a computed implementation.
|
|
136
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
137
|
+
*/
|
|
36
138
|
function ComputedDecorator(target, prop, descriptor, defaultValue) {
|
|
37
139
|
const propertyKey = prop;
|
|
38
140
|
if (!(descriptor && descriptor.get))
|
|
@@ -46,28 +148,45 @@ function ComputedDecorator(target, prop, descriptor, defaultValue) {
|
|
|
46
148
|
get: function () {
|
|
47
149
|
const scopeMap = GetScopeMapForInstance(this);
|
|
48
150
|
if (scopeMap[propertyKey] === undefined) {
|
|
49
|
-
const
|
|
50
|
-
const syncStore = new Store_1.StoreSync();
|
|
51
|
-
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
52
|
-
const data = observableScope_1.ObservableScope.Value(scope);
|
|
53
|
-
syncStore.Write(data, "root");
|
|
54
|
-
});
|
|
55
|
-
observableScope_1.ObservableScope.Init(getterScope);
|
|
56
|
-
const propertyScope = observableScope_1.ObservableScope.Create(() => syncStore.Get("root", defaultValue));
|
|
57
|
-
observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
|
|
58
|
-
observableScope_1.ObservableScope.Destroy(getterScope);
|
|
59
|
-
});
|
|
151
|
+
const propertyScope = CreateComputedScope(getter.bind(this), undefined, new Store_1.StoreSync());
|
|
60
152
|
scopeMap[propertyKey] = [propertyScope, undefined];
|
|
61
153
|
}
|
|
62
154
|
return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
|
|
63
155
|
},
|
|
64
156
|
};
|
|
65
157
|
}
|
|
158
|
+
/**
|
|
159
|
+
* ComputedAsync decorator factory for creating asynchronous computed properties.
|
|
160
|
+
* A computed property is derived from other properties and automatically updates when its dependencies change.
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* class MyComponent extends Component {
|
|
164
|
+
* @ComputedAsync({ items: [] })
|
|
165
|
+
* get myAsyncComputed(): { items: any[] } {
|
|
166
|
+
* return { items: this.myStateValue };
|
|
167
|
+
* }
|
|
168
|
+
* }
|
|
169
|
+
*
|
|
170
|
+
* @param defaultValue The default value to be used if the computed property is not defined.
|
|
171
|
+
* @returns A property decorator that can be applied to a getter method.
|
|
172
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
173
|
+
* @remarks The computed value is backed by a StoreAsync instance, which caches the result of the asynchronous getter. When dependencies change, the StoreAsync updates and the computed property resolves to the latest value. The provided `defaultValue` is returned until the async computation completes.
|
|
174
|
+
*/
|
|
66
175
|
function ComputedAsync(defaultValue) {
|
|
67
176
|
return function (target, propertyKey, descriptor) {
|
|
68
177
|
return ComputedAsyncDecorator(target, propertyKey, descriptor, defaultValue);
|
|
69
178
|
};
|
|
70
179
|
}
|
|
180
|
+
/**
|
|
181
|
+
* ComputedAsync decorator implementation for creating asynchronous computed properties.
|
|
182
|
+
* @private
|
|
183
|
+
* @param target The target object.
|
|
184
|
+
* @param prop The property key.
|
|
185
|
+
* @param descriptor The property descriptor.
|
|
186
|
+
* @param defaultValue The default value to be used if the computed property is not defined.
|
|
187
|
+
* @returns A property descriptor that replaces the original descriptor with a computed implementation.
|
|
188
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
189
|
+
*/
|
|
71
190
|
function ComputedAsyncDecorator(target, prop, descriptor, defaultValue) {
|
|
72
191
|
const propertyKey = prop;
|
|
73
192
|
if (!(descriptor && descriptor.get))
|
|
@@ -81,26 +200,36 @@ function ComputedAsyncDecorator(target, prop, descriptor, defaultValue) {
|
|
|
81
200
|
get: function () {
|
|
82
201
|
const scopeMap = GetScopeMapForInstance(this);
|
|
83
202
|
if (scopeMap[propertyKey] === undefined) {
|
|
84
|
-
const
|
|
85
|
-
const asyncStore = new Store_1.StoreAsync();
|
|
86
|
-
observableScope_1.ObservableScope.Watch(getterScope, (scope) => {
|
|
87
|
-
asyncStore.Write(observableScope_1.ObservableScope.Value(scope), "root");
|
|
88
|
-
});
|
|
89
|
-
observableScope_1.ObservableScope.Init(getterScope);
|
|
90
|
-
const propertyScope = observableScope_1.ObservableScope.Create(() => asyncStore.Get("root", defaultValue));
|
|
91
|
-
observableScope_1.ObservableScope.OnDestroyed(propertyScope, function () {
|
|
92
|
-
observableScope_1.ObservableScope.Destroy(getterScope);
|
|
93
|
-
asyncStore.Destroy();
|
|
94
|
-
});
|
|
203
|
+
const propertyScope = CreateComputedScope(getter.bind(this), defaultValue, new Store_1.StoreAsync());
|
|
95
204
|
scopeMap[propertyKey] = [propertyScope, undefined];
|
|
96
205
|
}
|
|
97
206
|
return observableScope_1.ObservableScope.Value(scopeMap[propertyKey][0]);
|
|
98
207
|
},
|
|
99
208
|
};
|
|
100
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* State decorator factory for creating state properties.
|
|
212
|
+
* A state property is a reactive value that can be read and written synchronously.
|
|
213
|
+
*
|
|
214
|
+
* @example
|
|
215
|
+
* class MyComponent extends Component {
|
|
216
|
+
* @State()
|
|
217
|
+
* myState: { count: number } = { count: 0 };
|
|
218
|
+
* }
|
|
219
|
+
*
|
|
220
|
+
* @returns A property decorator that can be applied to a property.
|
|
221
|
+
* @remarks The State decorator creates an ObservableNode to store the value. Updates to the property automatically notify any watchers of dependent scopes, making it ideal for mutable complex data structures that need to trigger reactivity.
|
|
222
|
+
*/
|
|
101
223
|
function State() {
|
|
102
224
|
return StateDecorator;
|
|
103
225
|
}
|
|
226
|
+
/**
|
|
227
|
+
* State decorator implementation for creating state properties.
|
|
228
|
+
* @private
|
|
229
|
+
* @param target The target object.
|
|
230
|
+
* @param propertyKey The property key.
|
|
231
|
+
* @returns A property descriptor that replaces the original descriptor with a state implementation.
|
|
232
|
+
*/
|
|
104
233
|
function StateDecorator(target, propertyKey) {
|
|
105
234
|
return {
|
|
106
235
|
configurable: false,
|
|
@@ -119,14 +248,40 @@ function StateDecorator(target, propertyKey) {
|
|
|
119
248
|
},
|
|
120
249
|
};
|
|
121
250
|
}
|
|
251
|
+
/**
|
|
252
|
+
* Value decorator factory for creating value properties.
|
|
253
|
+
* A value property is a reactive value that can be read and written synchronously.
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* class MyComponent extends Component {
|
|
257
|
+
* @Value()
|
|
258
|
+
* myValue: string = "Hello";
|
|
259
|
+
* }
|
|
260
|
+
*
|
|
261
|
+
* @returns A property decorator that can be applied to a property.
|
|
262
|
+
* @remarks The Value decorator lazily creates a scoped ObservableScope whose getter returns the stored value. The setter updates the stored value and invokes ObservableScope.Update on the scope, causing any dependent computed or scope decorators to re-evaluate.
|
|
263
|
+
*/
|
|
122
264
|
function Value() {
|
|
123
265
|
return ValueDecorator;
|
|
124
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Creates a value scope for a given tuple.
|
|
269
|
+
* @private
|
|
270
|
+
* @param tuple The tuple containing the scope and value.
|
|
271
|
+
* @returns An observable scope created from the tuple's value.
|
|
272
|
+
*/
|
|
125
273
|
function CreateValueScope(tuple) {
|
|
126
274
|
return observableScope_1.ObservableScope.Create(function () {
|
|
127
275
|
return tuple[1];
|
|
128
276
|
});
|
|
129
277
|
}
|
|
278
|
+
/**
|
|
279
|
+
* Value decorator implementation for creating value properties.
|
|
280
|
+
* @private
|
|
281
|
+
* @param target The target object.
|
|
282
|
+
* @param propertyKey The property key.
|
|
283
|
+
* @returns A property descriptor that replaces the original descriptor with a value implementation.
|
|
284
|
+
*/
|
|
130
285
|
function ValueDecorator(target, propertyKey) {
|
|
131
286
|
return {
|
|
132
287
|
configurable: false,
|
|
@@ -146,9 +301,33 @@ function ValueDecorator(target, propertyKey) {
|
|
|
146
301
|
},
|
|
147
302
|
};
|
|
148
303
|
}
|
|
304
|
+
/**
|
|
305
|
+
* Scope decorator factory for creating scope properties.
|
|
306
|
+
* A scope property is a reactive value that can be read and written synchronously.
|
|
307
|
+
*
|
|
308
|
+
* @example
|
|
309
|
+
* class MyComponent extends Component {
|
|
310
|
+
* @Scope()
|
|
311
|
+
* get myScopeValue(): string {
|
|
312
|
+
* return this.myStateValue + "!";
|
|
313
|
+
* }
|
|
314
|
+
* }
|
|
315
|
+
*
|
|
316
|
+
* @returns A property decorator that can be applied to a getter method.
|
|
317
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
318
|
+
*/
|
|
149
319
|
function Scope() {
|
|
150
320
|
return ScopeDecorator;
|
|
151
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* Scope decorator implementation for creating scope properties.
|
|
324
|
+
* @private
|
|
325
|
+
* @param target The target object.
|
|
326
|
+
* @param propertyKey The property key.
|
|
327
|
+
* @param descriptor The property descriptor.
|
|
328
|
+
* @returns A property descriptor that replaces the original descriptor with a scope implementation.
|
|
329
|
+
* @throws Will throw an error if the property is not a getter or if it has a setter.
|
|
330
|
+
*/
|
|
152
331
|
function ScopeDecorator(target, propertyKey, descriptor) {
|
|
153
332
|
if (!(descriptor && descriptor.get))
|
|
154
333
|
throw "Scope decorator requires a getter";
|
|
@@ -168,6 +347,51 @@ function ScopeDecorator(target, propertyKey, descriptor) {
|
|
|
168
347
|
},
|
|
169
348
|
};
|
|
170
349
|
}
|
|
350
|
+
function Watch(scope) {
|
|
351
|
+
return function (target, propertyKey, descriptor) {
|
|
352
|
+
return WatchDecorator(target, propertyKey, descriptor, scope);
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
function WatchDecorator(target, propertyKey, descriptor, scopeFunction) {
|
|
356
|
+
if (!descriptor || typeof descriptor.value !== "function")
|
|
357
|
+
throw "Watch decorator requires a function";
|
|
358
|
+
function bindWatch(instance) {
|
|
359
|
+
function scopeFunctionWrapper() {
|
|
360
|
+
return scopeFunction(instance);
|
|
361
|
+
}
|
|
362
|
+
const [value, scope] = observableScope_1.ObservableScope.CreateIf(scopeFunctionWrapper, true);
|
|
363
|
+
if (scope) {
|
|
364
|
+
const propertyMap = GetScopeMapForInstance(this);
|
|
365
|
+
propertyMap[propertyKey] = [scope, undefined];
|
|
366
|
+
observableScope_1.ObservableScope.Watch(scope, function (scope) {
|
|
367
|
+
instance[propertyKey](observableScope_1.ObservableScope.Value(scope));
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
instance[propertyKey](value);
|
|
371
|
+
return instance;
|
|
372
|
+
}
|
|
373
|
+
const boundArray = GetBoundArrayForPrototype(target);
|
|
374
|
+
boundArray.push(bindWatch);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Inject decorator factory for creating dependency-injected properties.
|
|
378
|
+
* An injected property is automatically provided by the framework's dependency injection system.
|
|
379
|
+
*
|
|
380
|
+
* @example
|
|
381
|
+
* class MyComponent extends Component {
|
|
382
|
+
* @Inject(Token)
|
|
383
|
+
* property: ServiceForToken;
|
|
384
|
+
* }
|
|
385
|
+
*
|
|
386
|
+
* // Setting the value in the class definition
|
|
387
|
+
* class MyComponent extends Component {
|
|
388
|
+
* @Inject(Token)
|
|
389
|
+
* property: ServiceForToken = new ServiceForToken();
|
|
390
|
+
* }
|
|
391
|
+
*
|
|
392
|
+
* @param type The constructor type of the dependency to be injected.
|
|
393
|
+
* @returns A property decorator that can be applied to a property.
|
|
394
|
+
*/
|
|
171
395
|
function Inject(type) {
|
|
172
396
|
return function () {
|
|
173
397
|
return InjectDecorator(type);
|
|
@@ -185,9 +409,32 @@ function InjectDecorator(type) {
|
|
|
185
409
|
},
|
|
186
410
|
};
|
|
187
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Destroy decorator factory for marking a property to be destroyed when the component is destroyed.
|
|
414
|
+
* @example
|
|
415
|
+
* class MyComponent extends Component {
|
|
416
|
+
* @Destroy()
|
|
417
|
+
* timer: Timer;
|
|
418
|
+
* }
|
|
419
|
+
*/
|
|
188
420
|
function Destroy() {
|
|
189
421
|
return DestroyDecorator;
|
|
190
422
|
}
|
|
423
|
+
var Bound;
|
|
424
|
+
(function (Bound) {
|
|
425
|
+
function All(value) {
|
|
426
|
+
const array = GetBoundArrayForPrototype(Object.getPrototypeOf(value), false);
|
|
427
|
+
for (let x = 0; array && x < array.length; x++)
|
|
428
|
+
array[x](value);
|
|
429
|
+
}
|
|
430
|
+
Bound.All = All;
|
|
431
|
+
})(Bound || (exports.Bound = Bound = {}));
|
|
432
|
+
/**
|
|
433
|
+
* Utility to destroy all observable scopes and invoke destroy on marked properties of an instance.
|
|
434
|
+
* @param value The instance to clean up.
|
|
435
|
+
* @example
|
|
436
|
+
* Destroy.All(this);
|
|
437
|
+
*/
|
|
191
438
|
(function (Destroy) {
|
|
192
439
|
function All(value) {
|
|
193
440
|
const scopeMap = scopeInstanceMap.get(value);
|
|
@@ -196,8 +443,8 @@ function Destroy() {
|
|
|
196
443
|
for (let x = 0; x < values.length; x++)
|
|
197
444
|
observableScope_1.ObservableScope.Destroy(values[x][0]);
|
|
198
445
|
}
|
|
199
|
-
const array = GetDestroyArrayForPrototype(Object.getPrototypeOf(value));
|
|
200
|
-
for (let x = 0; x < array.length; x++)
|
|
446
|
+
const array = GetDestroyArrayForPrototype(Object.getPrototypeOf(value), false);
|
|
447
|
+
for (let x = 0; array && x < array.length; x++)
|
|
201
448
|
value[array[x]].Destroy();
|
|
202
449
|
}
|
|
203
450
|
Destroy.All = All;
|
package/Utils/injector.d.ts
CHANGED
|
@@ -1,12 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Simple scoped dependency injection class. Manages types/instances as key/value pairs.
|
|
3
|
+
*/
|
|
1
4
|
export declare class Injector {
|
|
2
5
|
private parent;
|
|
3
6
|
private typeMap;
|
|
4
7
|
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Get instance/value based on a key type. Searches for a match
|
|
10
|
+
* through all parent Injectors.
|
|
11
|
+
*
|
|
12
|
+
* @param type Key to retrieve from the Injector map
|
|
13
|
+
*/
|
|
5
14
|
Get<T>(type: any): T;
|
|
15
|
+
/**
|
|
16
|
+
* Set instance/value based on a key type at this scope.
|
|
17
|
+
*
|
|
18
|
+
* @param type Type key
|
|
19
|
+
* @param instance Value instance for this type key
|
|
20
|
+
*/
|
|
6
21
|
Set<T>(type: any, instance: T): T;
|
|
7
22
|
}
|
|
8
23
|
export declare namespace Injector {
|
|
24
|
+
/**
|
|
25
|
+
* Get the current Injector scope.
|
|
26
|
+
*/
|
|
9
27
|
function Current(): Injector;
|
|
28
|
+
/**
|
|
29
|
+
* Creates a child scope with the passed Injector instance.
|
|
30
|
+
*
|
|
31
|
+
* @param injector Injector instance for this scope
|
|
32
|
+
* @param action Callback to invoke for this scope
|
|
33
|
+
*/
|
|
10
34
|
function Scope<R = void, P extends any[] = []>(injector: Injector, action: {
|
|
11
35
|
(...args: P): R;
|
|
12
36
|
}, ...args: P): R;
|
package/Utils/injector.js
CHANGED
|
@@ -1,17 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Injector = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Simple scoped dependency injection class. Manages types/instances as key/value pairs.
|
|
6
|
+
*/
|
|
4
7
|
class Injector {
|
|
5
8
|
constructor() {
|
|
6
9
|
this.parent = Injector.Current();
|
|
7
10
|
this.typeMap = new Map();
|
|
8
11
|
}
|
|
12
|
+
/**
|
|
13
|
+
* Get instance/value based on a key type. Searches for a match
|
|
14
|
+
* through all parent Injectors.
|
|
15
|
+
*
|
|
16
|
+
* @param type Key to retrieve from the Injector map
|
|
17
|
+
*/
|
|
9
18
|
Get(type) {
|
|
10
19
|
if (this.typeMap.has(type)) {
|
|
11
20
|
return this.typeMap.get(type);
|
|
12
21
|
}
|
|
13
22
|
return this.parent ? this.parent.Get(type) : undefined;
|
|
14
23
|
}
|
|
24
|
+
/**
|
|
25
|
+
* Set instance/value based on a key type at this scope.
|
|
26
|
+
*
|
|
27
|
+
* @param type Type key
|
|
28
|
+
* @param instance Value instance for this type key
|
|
29
|
+
*/
|
|
15
30
|
Set(type, instance) {
|
|
16
31
|
this.typeMap.set(type, instance);
|
|
17
32
|
return instance;
|
|
@@ -20,10 +35,19 @@ class Injector {
|
|
|
20
35
|
exports.Injector = Injector;
|
|
21
36
|
(function (Injector) {
|
|
22
37
|
var scope = null;
|
|
38
|
+
/**
|
|
39
|
+
* Get the current Injector scope.
|
|
40
|
+
*/
|
|
23
41
|
function Current() {
|
|
24
42
|
return scope;
|
|
25
43
|
}
|
|
26
44
|
Injector.Current = Current;
|
|
45
|
+
/**
|
|
46
|
+
* Creates a child scope with the passed Injector instance.
|
|
47
|
+
*
|
|
48
|
+
* @param injector Injector instance for this scope
|
|
49
|
+
* @param action Callback to invoke for this scope
|
|
50
|
+
*/
|
|
27
51
|
function Scope(injector, action, ...args) {
|
|
28
52
|
const parent = Current();
|
|
29
53
|
scope = injector;
|
package/Utils/list.js
CHANGED
|
@@ -44,7 +44,7 @@ var List;
|
|
|
44
44
|
}
|
|
45
45
|
List.Clear = Clear;
|
|
46
46
|
function Push(list, data) {
|
|
47
|
-
const node = CreateNode(data);
|
|
47
|
+
const node = CreateNode(data); // { previous: null, next: null, data: data };
|
|
48
48
|
if (list.size === 0) {
|
|
49
49
|
list.head = node;
|
|
50
50
|
list.tail = node;
|
|
@@ -81,7 +81,7 @@ var List;
|
|
|
81
81
|
}
|
|
82
82
|
List.Pop = Pop;
|
|
83
83
|
function Add(list, data) {
|
|
84
|
-
const node = CreateNode(data);
|
|
84
|
+
const node = CreateNode(data); // { previous: null, next: null, data: data };
|
|
85
85
|
return AddNode(list, node);
|
|
86
86
|
}
|
|
87
87
|
List.Add = Add;
|
|
@@ -103,7 +103,7 @@ var List;
|
|
|
103
103
|
function AddBefore(list, node, data) {
|
|
104
104
|
if (!node)
|
|
105
105
|
return List.Add(list, data);
|
|
106
|
-
const newNode = CreateNode(data);
|
|
106
|
+
const newNode = CreateNode(data); // { previous: null, next: null, data: data };
|
|
107
107
|
const prevNode = node.previous;
|
|
108
108
|
newNode.next = node;
|
|
109
109
|
node.previous = newNode;
|
|
@@ -120,7 +120,7 @@ var List;
|
|
|
120
120
|
function AddAfter(list, node, data) {
|
|
121
121
|
if (!node)
|
|
122
122
|
return List.Push(list, data);
|
|
123
|
-
const newNode = CreateNode(data);
|
|
123
|
+
const newNode = CreateNode(data); // { previous: null, next: null, data: data };
|
|
124
124
|
const nextNode = node.next;
|
|
125
125
|
node.next = newNode;
|
|
126
126
|
newNode.previous = node;
|
package/Utils/router.js
CHANGED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// import { ObservableScope, IObservableScope } from "../Store/Tree/observableScope";
|
|
2
|
+
// import { wndw } from "../DOM/window";
|
|
3
|
+
// import { Store } from "../Store";
|
|
4
|
+
// export abstract class Router<T extends {}> {
|
|
5
|
+
// private routeScope: IObservableScope<string>;
|
|
6
|
+
// private initPromise: Promise<void>;
|
|
7
|
+
// protected get State() {
|
|
8
|
+
// return this.store.Root.Value;
|
|
9
|
+
// }
|
|
10
|
+
// protected get ReplaceHistory() {
|
|
11
|
+
// return false;
|
|
12
|
+
// }
|
|
13
|
+
// public get Init() {
|
|
14
|
+
// return this.initPromise;
|
|
15
|
+
// }
|
|
16
|
+
// constructor(private store: Store<T>) {
|
|
17
|
+
// this.initPromise = new Promise(async (resolve, reject) => {
|
|
18
|
+
// try{
|
|
19
|
+
// this.routeScope = ObservableScope.Create(() => this.CreateRoutePart());
|
|
20
|
+
// await Router.Register(this);
|
|
21
|
+
// ObservableScope.Watch(this.routeScope, () => this.ReplaceHistory ? Router.ReplaceRoute() : Router.PushRoute());
|
|
22
|
+
// resolve();
|
|
23
|
+
// }
|
|
24
|
+
// catch(e) {
|
|
25
|
+
// reject(e);
|
|
26
|
+
// }
|
|
27
|
+
// })
|
|
28
|
+
// }
|
|
29
|
+
// protected abstract CreateRoutePart(): string;
|
|
30
|
+
// public abstract GetRoutePart(route: string): string;
|
|
31
|
+
// public abstract Read(routePart: string): Promise<void>;
|
|
32
|
+
// public Route() {
|
|
33
|
+
// return ObservableScope.Value(this.routeScope);
|
|
34
|
+
// }
|
|
35
|
+
// public JSON() {
|
|
36
|
+
// var state = this.State;
|
|
37
|
+
// return (state as any).toJSON ? (state as any).toJSON() : state;
|
|
38
|
+
// }
|
|
39
|
+
// public async SetState(state: Partial<T>) {
|
|
40
|
+
// await this.store.Merge(state);
|
|
41
|
+
// }
|
|
42
|
+
// public Destroy() {
|
|
43
|
+
// this.routeScope.Destroy();
|
|
44
|
+
// Router.Destroy(this);
|
|
45
|
+
// }
|
|
46
|
+
// }
|
|
47
|
+
// export namespace Router {
|
|
48
|
+
// var leadingSlash = /^\//;
|
|
49
|
+
// var routers = [] as Array<Router<any>>;
|
|
50
|
+
// var updateScheduled = false;
|
|
51
|
+
// export function PushRoute() {
|
|
52
|
+
// if(updateScheduled)
|
|
53
|
+
// return;
|
|
54
|
+
// updateScheduled = true;
|
|
55
|
+
// setTimeout(() => {
|
|
56
|
+
// var route = routers.map(r => r.Route()).filter(r => r).join("/");
|
|
57
|
+
// route = "/" + route;
|
|
58
|
+
// var state = routers.map(r => r.JSON());
|
|
59
|
+
// if(route === wndw.location.pathname)
|
|
60
|
+
// wndw.history.replaceState(state, "", route);
|
|
61
|
+
// else
|
|
62
|
+
// wndw.history.pushState(state, "", route);
|
|
63
|
+
// updateScheduled = false;
|
|
64
|
+
// }, 250);
|
|
65
|
+
// }
|
|
66
|
+
// var replaceScheduled = false;
|
|
67
|
+
// export function ReplaceRoute() {
|
|
68
|
+
// if(replaceScheduled || updateScheduled)
|
|
69
|
+
// return;
|
|
70
|
+
// replaceScheduled = true;
|
|
71
|
+
// setTimeout(() => {
|
|
72
|
+
// replaceScheduled = false;
|
|
73
|
+
// if(updateScheduled)
|
|
74
|
+
// return;
|
|
75
|
+
// var route = routers.map(r => r.Route()).filter(r => r).join("/");
|
|
76
|
+
// route = "/" + route;
|
|
77
|
+
// var state = routers.map(r => r.JSON());
|
|
78
|
+
// wndw.history.replaceState(state, "", route);
|
|
79
|
+
// }, 250);
|
|
80
|
+
// }
|
|
81
|
+
// export function Destroy(router: Router<any>) {
|
|
82
|
+
// var index = routers.indexOf(router);
|
|
83
|
+
// if(index >= 0) {
|
|
84
|
+
// routers.splice(index, 1);
|
|
85
|
+
// ReplaceRoute();
|
|
86
|
+
// }
|
|
87
|
+
// }
|
|
88
|
+
// export async function Register(router: Router<any>) {
|
|
89
|
+
// var index = routers.indexOf(router);
|
|
90
|
+
// if(index < 0) {
|
|
91
|
+
// var route = wndw.location.pathname.replace(leadingSlash, "");
|
|
92
|
+
// for(var x=0; x<routers.length; x++) {
|
|
93
|
+
// route = route.replace(routers[x].GetRoutePart(route), "");
|
|
94
|
+
// route = route.replace(leadingSlash, "");
|
|
95
|
+
// }
|
|
96
|
+
// var routePart = router.GetRoutePart(route);
|
|
97
|
+
// if(routePart)
|
|
98
|
+
// await router.Read(routePart);
|
|
99
|
+
// routers.push(router);
|
|
100
|
+
// ReplaceRoute();
|
|
101
|
+
// }
|
|
102
|
+
// }
|
|
103
|
+
// wndw.onpopstate = function(e: PopStateEvent) {
|
|
104
|
+
// var state = e.state as Array<any>;
|
|
105
|
+
// for(var x=0; x<state.length; x++) {
|
|
106
|
+
// if(x < routers.length)
|
|
107
|
+
// routers[x].SetState(state[x]);
|
|
108
|
+
// }
|
|
109
|
+
// }
|
|
110
|
+
// }
|