j-templates 6.1.11 → 6.1.12
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/domNodeConfig.js +1 -1
- package/Node/nodeRef.js +12 -11
- package/Store/Tree/observableScope.d.ts +1 -4
- package/Store/Tree/observableScope.js +41 -64
- package/Utils/avlTree.d.ts +15 -0
- package/Utils/avlTree.js +140 -0
- package/Utils/distinctArray.d.ts +10 -0
- package/Utils/distinctArray.js +26 -0
- package/Utils/emitter.d.ts +2 -0
- package/Utils/emitter.js +5 -0
- package/package.json +1 -1
package/DOM/domNodeConfig.js
CHANGED
package/Node/nodeRef.js
CHANGED
|
@@ -8,6 +8,7 @@ const elementNode_1 = require("./elementNode");
|
|
|
8
8
|
const componentNode_1 = require("./componentNode");
|
|
9
9
|
const list_1 = require("../Utils/list");
|
|
10
10
|
const Store_1 = require("../Store");
|
|
11
|
+
const domNodeConfig_1 = require("../DOM/domNodeConfig");
|
|
11
12
|
var NodeRefType;
|
|
12
13
|
(function (NodeRefType) {
|
|
13
14
|
NodeRefType[NodeRefType["NodeRef"] = 0] = "NodeRef";
|
|
@@ -116,10 +117,10 @@ var NodeRef;
|
|
|
116
117
|
}
|
|
117
118
|
NodeRef.Create = Create;
|
|
118
119
|
function Init(nodeRef) {
|
|
119
|
-
if (nodeRef.
|
|
120
|
+
if (nodeRef.type === NodeRefType.TextNode || nodeRef.node)
|
|
120
121
|
return;
|
|
121
|
-
nodeRef.node =
|
|
122
|
-
nodeRef.childNodes = nodeRef.nodeType !==
|
|
122
|
+
nodeRef.node = nodeConfig_1.NodeConfig.createNode(nodeRef.nodeType, nodeRef.nodeNamespace);
|
|
123
|
+
nodeRef.childNodes = nodeRef.nodeType !== NodeRefType.TextNode ? [] : null;
|
|
123
124
|
switch (nodeRef.type) {
|
|
124
125
|
case NodeRefType.BoundNode:
|
|
125
126
|
boundNode_1.BoundNode.Init(nodeRef);
|
|
@@ -189,15 +190,15 @@ var NodeRef;
|
|
|
189
190
|
for (let x = 0; x < curDataNode.data.nodes.length; x++) {
|
|
190
191
|
const virtualNode = curDataNode.data.nodes[x];
|
|
191
192
|
const actualNode = priorNode ? nodeConfig_1.NodeConfig.getNextSibling(priorNode) : nodeConfig_1.NodeConfig.getFirstChild(rootNode);
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
193
|
+
if (virtualNode.type === NodeRefType.TextNode && virtualNode.node === null) {
|
|
194
|
+
if (domNodeConfig_1.DOMNodeConfig.isTextNode(actualNode)) {
|
|
195
|
+
domNodeConfig_1.DOMNodeConfig.setText(actualNode, virtualNode.value);
|
|
196
|
+
virtualNode.node = actualNode;
|
|
197
|
+
}
|
|
198
|
+
else
|
|
199
|
+
virtualNode.node = domNodeConfig_1.DOMNodeConfig.createTextNode(virtualNode.value);
|
|
196
200
|
}
|
|
197
|
-
|
|
198
|
-
expectedNode = nodeConfig_1.NodeConfig.createTextNode(virtualNode.value);
|
|
199
|
-
else
|
|
200
|
-
expectedNode = virtualNode.node;
|
|
201
|
+
const expectedNode = virtualNode.node;
|
|
201
202
|
if (actualNode !== expectedNode) {
|
|
202
203
|
nodeConfig_1.NodeConfig.addChildBefore(rootNode, actualNode, expectedNode);
|
|
203
204
|
!remove && insert && actualNode && nodeConfig_1.NodeConfig.removeChild(rootNode, actualNode);
|
|
@@ -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>[]
|
|
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 {
|
|
@@ -55,7 +53,6 @@ export declare namespace ObservableScope {
|
|
|
55
53
|
function Register(emitter: Emitter): void;
|
|
56
54
|
function Init<T>(scope: IObservableScope<T>): void;
|
|
57
55
|
function Value<T>(scope: IObservableScope<T>): T;
|
|
58
|
-
function Watching(): boolean;
|
|
59
56
|
function Touch<T>(scope: IObservableScope<T>): void;
|
|
60
57
|
function Watch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T>]>): void;
|
|
61
58
|
function Unwatch<T>(scope: IObservableScope<T>, callback: EmitterCallback<[IObservableScope<T> | ObservableScopeValue<T>]>): void;
|
|
@@ -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 avlTree_1 = require("../../Utils/avlTree");
|
|
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,22 @@ class ObservableScope extends ObservableScopeWrapper {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
exports.ObservableScope = ObservableScope;
|
|
51
|
-
let
|
|
52
|
-
let currentlyWatching = false;
|
|
51
|
+
let watchState = null;
|
|
53
52
|
function WatchScope(scope) {
|
|
54
|
-
const
|
|
55
|
-
|
|
56
|
-
watchingScope = scope;
|
|
57
|
-
currentlyWatching = true;
|
|
53
|
+
const parent = watchState;
|
|
54
|
+
watchState = [avlTree_1.AVL.Create(emitter_1.Emitter.Compare), []];
|
|
58
55
|
const value = scope.getFunction();
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return value;
|
|
56
|
+
const result = [value, avlTree_1.AVL.ToArray(watchState[0]), watchState[1]];
|
|
57
|
+
watchState = parent;
|
|
58
|
+
return result;
|
|
63
59
|
}
|
|
64
60
|
function CalcScope(callback) {
|
|
65
61
|
const value = callback();
|
|
66
|
-
if (
|
|
67
|
-
|
|
68
|
-
watchingScope.calcFunctions.push({
|
|
62
|
+
if (watchState !== null)
|
|
63
|
+
watchState[1].push({
|
|
69
64
|
getFunction: callback,
|
|
70
65
|
value
|
|
71
66
|
});
|
|
72
|
-
}
|
|
73
67
|
return value;
|
|
74
68
|
}
|
|
75
69
|
(function (ObservableScope) {
|
|
@@ -82,11 +76,9 @@ function CalcScope(callback) {
|
|
|
82
76
|
dirty: true,
|
|
83
77
|
emitter: emitter_1.Emitter.Create(),
|
|
84
78
|
emitters: [],
|
|
85
|
-
calcFunctions:
|
|
79
|
+
calcFunctions: [],
|
|
86
80
|
onDestroyed: null,
|
|
87
81
|
destroyed: false,
|
|
88
|
-
watchEmitters: null,
|
|
89
|
-
watchEmittersSet: null,
|
|
90
82
|
setCallback: function () {
|
|
91
83
|
return OnSet(scope);
|
|
92
84
|
},
|
|
@@ -95,35 +87,25 @@ function CalcScope(callback) {
|
|
|
95
87
|
}
|
|
96
88
|
ObservableScope.Create = Create;
|
|
97
89
|
function Register(emitter) {
|
|
98
|
-
if (
|
|
90
|
+
if (watchState === null)
|
|
99
91
|
return;
|
|
100
|
-
|
|
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
|
-
}
|
|
92
|
+
avlTree_1.AVL.Insert(watchState[0], emitter);
|
|
107
93
|
}
|
|
108
94
|
ObservableScope.Register = Register;
|
|
109
95
|
function Init(scope) {
|
|
110
96
|
if (!scope)
|
|
111
97
|
return;
|
|
112
|
-
|
|
98
|
+
UpdateValue(scope);
|
|
113
99
|
}
|
|
114
100
|
ObservableScope.Init = Init;
|
|
115
101
|
function Value(scope) {
|
|
116
102
|
if (!scope)
|
|
117
103
|
return undefined;
|
|
118
104
|
Register(scope.emitter);
|
|
119
|
-
|
|
105
|
+
UpdateValue(scope);
|
|
120
106
|
return scope.value;
|
|
121
107
|
}
|
|
122
108
|
ObservableScope.Value = Value;
|
|
123
|
-
function Watching() {
|
|
124
|
-
return currentlyWatching;
|
|
125
|
-
}
|
|
126
|
-
ObservableScope.Watching = Watching;
|
|
127
109
|
function Touch(scope) {
|
|
128
110
|
if (!scope || !scope.emitter)
|
|
129
111
|
return;
|
|
@@ -148,6 +130,8 @@ function CalcScope(callback) {
|
|
|
148
130
|
}
|
|
149
131
|
ObservableScope.OnDestroyed = OnDestroyed;
|
|
150
132
|
function Update(scope) {
|
|
133
|
+
if (!scope || scope.dirty || scope.destroyed)
|
|
134
|
+
return;
|
|
151
135
|
OnSet(scope);
|
|
152
136
|
}
|
|
153
137
|
ObservableScope.Update = Update;
|
|
@@ -156,25 +140,6 @@ function CalcScope(callback) {
|
|
|
156
140
|
}
|
|
157
141
|
ObservableScope.Destroy = Destroy;
|
|
158
142
|
})(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
143
|
function CalcChanged(calc) {
|
|
179
144
|
const value = calc.getFunction();
|
|
180
145
|
const changed = calc.value !== value;
|
|
@@ -182,35 +147,48 @@ function CalcChanged(calc) {
|
|
|
182
147
|
return changed;
|
|
183
148
|
}
|
|
184
149
|
function DirtyScope(scope) {
|
|
185
|
-
scope.dirty
|
|
186
|
-
|
|
150
|
+
if (scope.dirty || !scope.getFunction)
|
|
151
|
+
return;
|
|
152
|
+
scope.dirty = scope.calcFunctions.length === 0 || scope.calcFunctions.some(CalcChanged);
|
|
153
|
+
scope.dirty && emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
154
|
+
}
|
|
155
|
+
const scopeQueue = new Set();
|
|
156
|
+
function ProcessScopeQueue() {
|
|
157
|
+
const scopes = Array.from(scopeQueue);
|
|
158
|
+
scopeQueue.clear();
|
|
159
|
+
for (let x = 0; x < scopes.length; x++)
|
|
160
|
+
DirtyScope(scopes[x]);
|
|
187
161
|
}
|
|
188
162
|
function OnSet(scope) {
|
|
189
|
-
if (
|
|
190
|
-
return
|
|
163
|
+
if (scope.destroyed)
|
|
164
|
+
return true;
|
|
165
|
+
if (scope.async || scope.calcFunctions.length > 0) {
|
|
166
|
+
if (scopeQueue.size === 0)
|
|
167
|
+
queueMicrotask(ProcessScopeQueue);
|
|
168
|
+
scopeQueue.add(scope);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
191
171
|
DirtyScope(scope);
|
|
192
|
-
return false;
|
|
193
172
|
}
|
|
194
173
|
function UpdateValue(scope) {
|
|
195
174
|
if (!scope.dirty)
|
|
196
175
|
return;
|
|
197
176
|
scope.dirty = false;
|
|
198
|
-
|
|
199
|
-
scope.calcFunctions = null;
|
|
200
|
-
const value = WatchScope(scope);
|
|
177
|
+
const [value, emitters, calcFunctions] = WatchScope(scope);
|
|
201
178
|
if (scope.async) {
|
|
202
179
|
scope.promise = value.then(function (result) {
|
|
203
180
|
scope.value = result;
|
|
181
|
+
emitter_1.Emitter.Emit(scope.emitter, scope);
|
|
204
182
|
return result;
|
|
205
183
|
});
|
|
206
184
|
}
|
|
207
185
|
else
|
|
208
186
|
scope.value = value;
|
|
209
|
-
|
|
187
|
+
scope.calcFunctions = calcFunctions;
|
|
188
|
+
UpdateEmitters(scope, emitters);
|
|
210
189
|
}
|
|
211
|
-
function UpdateEmitters(scope) {
|
|
212
|
-
|
|
213
|
-
if (right === null) {
|
|
190
|
+
function UpdateEmitters(scope, right) {
|
|
191
|
+
if (right.length === 0) {
|
|
214
192
|
if (scope.emitters.length > 0) {
|
|
215
193
|
for (let x = 0; x < scope.emitters.length; x++)
|
|
216
194
|
emitter_1.Emitter.Remove(scope.emitters[x], scope.setCallback);
|
|
@@ -218,7 +196,6 @@ function UpdateEmitters(scope) {
|
|
|
218
196
|
}
|
|
219
197
|
return;
|
|
220
198
|
}
|
|
221
|
-
emitter_1.Emitter.Sort(right);
|
|
222
199
|
(0, array_1.ReconcileSortedArrays)(scope.emitters, right, function (emitter) {
|
|
223
200
|
emitter_1.Emitter.On(emitter, scope.setCallback);
|
|
224
201
|
}, 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 {};
|
package/Utils/avlTree.js
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AVL = void 0;
|
|
4
|
+
const VALUE = 0;
|
|
5
|
+
const BALANCE = 1;
|
|
6
|
+
const HEIGHT = 2;
|
|
7
|
+
const LEFT = 3;
|
|
8
|
+
const RIGHT = 4;
|
|
9
|
+
function Squash(x) {
|
|
10
|
+
return x ? x < 0 ? -1 : 1 : 0;
|
|
11
|
+
}
|
|
12
|
+
var AVL;
|
|
13
|
+
(function (AVL) {
|
|
14
|
+
function Create(compare) {
|
|
15
|
+
return CreateTree(compare);
|
|
16
|
+
}
|
|
17
|
+
AVL.Create = Create;
|
|
18
|
+
function Clear(tree) {
|
|
19
|
+
tree.root = null;
|
|
20
|
+
tree.size = 0;
|
|
21
|
+
}
|
|
22
|
+
AVL.Clear = Clear;
|
|
23
|
+
function Insert(tree, value) {
|
|
24
|
+
if (tree.size === 0) {
|
|
25
|
+
tree.root = CreateNode(value);
|
|
26
|
+
tree.size = 1;
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
InsertValue(tree, value);
|
|
30
|
+
}
|
|
31
|
+
AVL.Insert = Insert;
|
|
32
|
+
function ForEach(tree, callback) {
|
|
33
|
+
PreOrder(tree.root, callback);
|
|
34
|
+
}
|
|
35
|
+
AVL.ForEach = ForEach;
|
|
36
|
+
function ToArray(tree) {
|
|
37
|
+
const result = new Array(tree.size);
|
|
38
|
+
let index = 0;
|
|
39
|
+
ForEach(tree, function (value) {
|
|
40
|
+
result[index++] = value;
|
|
41
|
+
});
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
AVL.ToArray = ToArray;
|
|
45
|
+
})(AVL || (exports.AVL = AVL = {}));
|
|
46
|
+
function PreOrder(node, callback) {
|
|
47
|
+
if (node === null)
|
|
48
|
+
return;
|
|
49
|
+
PreOrder(node[LEFT], callback);
|
|
50
|
+
callback(node[VALUE]);
|
|
51
|
+
PreOrder(node[RIGHT], callback);
|
|
52
|
+
}
|
|
53
|
+
function CreateTree(compare) {
|
|
54
|
+
return {
|
|
55
|
+
size: 0,
|
|
56
|
+
compare,
|
|
57
|
+
root: null,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
function CreateNode(value) {
|
|
61
|
+
return [value, 0, 1, null, null];
|
|
62
|
+
}
|
|
63
|
+
function InsertValue(tree, value) {
|
|
64
|
+
const startSize = tree.size;
|
|
65
|
+
let node = tree.root;
|
|
66
|
+
let comp = 0;
|
|
67
|
+
const path = [];
|
|
68
|
+
while (node !== null) {
|
|
69
|
+
comp = Squash(tree.compare(value, node[VALUE]));
|
|
70
|
+
path.push([comp, node]);
|
|
71
|
+
switch (comp) {
|
|
72
|
+
case 0:
|
|
73
|
+
node = null;
|
|
74
|
+
break;
|
|
75
|
+
case -1:
|
|
76
|
+
node = node[LEFT] ??= (tree.size++, CreateNode(value));
|
|
77
|
+
break;
|
|
78
|
+
case 1:
|
|
79
|
+
node = node[RIGHT] ??= (tree.size++, CreateNode(value));
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
if (tree.size === startSize)
|
|
84
|
+
return;
|
|
85
|
+
for (let x = path.length - 2; x >= 0; x--) {
|
|
86
|
+
SetHeight(path[x][1]);
|
|
87
|
+
if (Math.abs(path[x][1][BALANCE]) === 2) {
|
|
88
|
+
const newRoot = BalanceNode(path[x][1]);
|
|
89
|
+
if (x === 0)
|
|
90
|
+
tree.root = newRoot;
|
|
91
|
+
else {
|
|
92
|
+
const [comp, parent] = path[x - 1];
|
|
93
|
+
switch (comp) {
|
|
94
|
+
case -1:
|
|
95
|
+
parent[LEFT] = newRoot;
|
|
96
|
+
break;
|
|
97
|
+
case 1:
|
|
98
|
+
parent[RIGHT] = newRoot;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function BalanceNode(node) {
|
|
106
|
+
if (node[BALANCE] < 0) {
|
|
107
|
+
if (node[LEFT][BALANCE] > 0)
|
|
108
|
+
node[LEFT] = RotateLeft(node[LEFT]);
|
|
109
|
+
return RotateRight(node);
|
|
110
|
+
}
|
|
111
|
+
if (node[RIGHT][BALANCE] < 0)
|
|
112
|
+
node[RIGHT] = RotateRight(node[RIGHT]);
|
|
113
|
+
return RotateLeft(node);
|
|
114
|
+
}
|
|
115
|
+
function RotateLeft(node) {
|
|
116
|
+
const startRightLeft = node[RIGHT][LEFT];
|
|
117
|
+
const root = node[RIGHT];
|
|
118
|
+
root[LEFT] = node;
|
|
119
|
+
node[RIGHT] = startRightLeft;
|
|
120
|
+
SetHeight(node);
|
|
121
|
+
SetHeight(root);
|
|
122
|
+
return root;
|
|
123
|
+
}
|
|
124
|
+
function RotateRight(node) {
|
|
125
|
+
const startLeftRight = node[LEFT][RIGHT];
|
|
126
|
+
const root = node[LEFT];
|
|
127
|
+
root[RIGHT] = node;
|
|
128
|
+
node[LEFT] = startLeftRight;
|
|
129
|
+
SetHeight(node);
|
|
130
|
+
SetHeight(root);
|
|
131
|
+
return root;
|
|
132
|
+
}
|
|
133
|
+
function SetHeight(node) {
|
|
134
|
+
const leftHeight = node[LEFT]?.[HEIGHT] ?? 0;
|
|
135
|
+
const rightHeight = node[RIGHT]?.[HEIGHT] ?? 0;
|
|
136
|
+
const balance = rightHeight - leftHeight;
|
|
137
|
+
const height = leftHeight > rightHeight ? leftHeight : rightHeight;
|
|
138
|
+
node[HEIGHT] = height + 1;
|
|
139
|
+
node[BALANCE] = balance;
|
|
140
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DistinctArray<T> = {
|
|
2
|
+
id: (value: T) => number;
|
|
3
|
+
distinct: T[];
|
|
4
|
+
array: T[];
|
|
5
|
+
};
|
|
6
|
+
export declare namespace DistinctArray {
|
|
7
|
+
function Create<T>(id: (value: T) => number): DistinctArray<T>;
|
|
8
|
+
function Push<T>({ id, distinct, array }: DistinctArray<T>, value: T): void;
|
|
9
|
+
function Get<T>({ array }: DistinctArray<T>): T[];
|
|
10
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DistinctArray = void 0;
|
|
4
|
+
var DistinctArray;
|
|
5
|
+
(function (DistinctArray) {
|
|
6
|
+
function Create(id) {
|
|
7
|
+
return {
|
|
8
|
+
id,
|
|
9
|
+
distinct: [],
|
|
10
|
+
array: []
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
DistinctArray.Create = Create;
|
|
14
|
+
function Push({ id, distinct, array }, value) {
|
|
15
|
+
const vId = id(value);
|
|
16
|
+
if (distinct[vId] === undefined) {
|
|
17
|
+
distinct[vId] = value;
|
|
18
|
+
array.push(value);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
DistinctArray.Push = Push;
|
|
22
|
+
function Get({ array }) {
|
|
23
|
+
return array;
|
|
24
|
+
}
|
|
25
|
+
DistinctArray.Get = Get;
|
|
26
|
+
})(DistinctArray || (exports.DistinctArray = DistinctArray = {}));
|
package/Utils/emitter.d.ts
CHANGED
|
@@ -2,9 +2,11 @@ export type EmitterCallback<T extends readonly any[] = any[]> = (...args: T) =>
|
|
|
2
2
|
export type Emitter = [number, ...EmitterCallback[]];
|
|
3
3
|
export declare namespace Emitter {
|
|
4
4
|
function Create(): Emitter;
|
|
5
|
+
function GetId(emitter: Emitter): number;
|
|
5
6
|
function On(emitter: Emitter, callback: EmitterCallback): void;
|
|
6
7
|
function Emit(emitter: Emitter, ...args: any[]): void;
|
|
7
8
|
function Remove(emitter: Emitter, callback: EmitterCallback): void;
|
|
8
9
|
function Clear(emitter: Emitter): void;
|
|
9
10
|
function Sort(emitters: Emitter[]): Emitter[];
|
|
11
|
+
function Compare(a: Emitter, b: Emitter): number;
|
|
10
12
|
}
|
package/Utils/emitter.js
CHANGED
|
@@ -10,6 +10,10 @@ var Emitter;
|
|
|
10
10
|
return emitter;
|
|
11
11
|
}
|
|
12
12
|
Emitter.Create = Create;
|
|
13
|
+
function GetId(emitter) {
|
|
14
|
+
return emitter[0];
|
|
15
|
+
}
|
|
16
|
+
Emitter.GetId = GetId;
|
|
13
17
|
function On(emitter, callback) {
|
|
14
18
|
emitter.push(callback);
|
|
15
19
|
}
|
|
@@ -43,4 +47,5 @@ var Emitter;
|
|
|
43
47
|
function Compare(a, b) {
|
|
44
48
|
return a[0] - b[0];
|
|
45
49
|
}
|
|
50
|
+
Emitter.Compare = Compare;
|
|
46
51
|
})(Emitter || (exports.Emitter = Emitter = {}));
|