j-templates 8.0.13 → 8.0.15
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/createAssignment.js +2 -6
- package/DOM/createAttributeAssignment.js +2 -6
- package/DOM/createEventAssignment.js +2 -6
- package/DOM/createPropertyAssignment.js +10 -14
- package/DOM/domNodeConfig.js +27 -30
- package/DOM/elements.js +102 -108
- package/DOM/index.js +3 -19
- package/Node/component.js +12 -16
- package/Node/component.types.js +1 -2
- package/Node/nodeConfig.js +2 -5
- package/Node/vNode.js +64 -67
- package/Node/vNode.types.js +5 -9
- package/Store/Diff/defaultDiffTreeWorker.d.ts +1 -0
- package/Store/Diff/defaultDiffTreeWorker.js +4 -0
- package/Store/Diff/diffAsync.d.ts +2 -4
- package/Store/Diff/diffAsync.js +4 -33
- package/Store/Diff/diffSync.js +3 -10
- package/Store/Diff/diffTree.d.ts +66 -41
- package/Store/Diff/diffTree.js +374 -426
- package/Store/Diff/diffTreeWorker.d.ts +8 -0
- package/Store/Diff/diffTreeWorker.js +27 -0
- package/Store/Diff/workerQueue.js +6 -10
- package/Store/Store/store.js +10 -14
- package/Store/Store/storeAsync.d.ts +1 -2
- package/Store/Store/storeAsync.js +10 -14
- package/Store/Store/storeSync.js +10 -14
- package/Store/Tree/observableNode.js +35 -38
- package/Store/Tree/observableScope.js +35 -42
- package/Store/index.js +5 -13
- package/Utils/animation.js +7 -11
- package/Utils/array.js +2 -6
- package/Utils/asyncQueue.js +7 -11
- package/Utils/decorators.js +44 -53
- package/Utils/emitter.js +6 -9
- package/Utils/functions.js +1 -4
- package/Utils/index.js +3 -21
- package/Utils/injector.js +2 -6
- package/Utils/json.d.ts +32 -10
- package/Utils/json.js +195 -208
- package/Utils/list.js +2 -5
- package/Utils/scheduling.js +4 -7
- package/Utils/thread.js +18 -26
- package/Utils/utils.types.js +1 -2
- package/_not_used/array.js +4 -10
- package/_not_used/avlTree.js +2 -5
- package/index.js +2 -10
- package/package.json +1 -1
- package/Store/Diff/diffWorker.d.ts +0 -3
- package/Store/Diff/diffWorker.js +0 -21
package/Utils/json.js
CHANGED
|
@@ -1,232 +1,219 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
Object.
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
const jsonProto = Object.getPrototypeOf({});
|
|
2
|
+
const arrayProto = Object.getPrototypeOf([]);
|
|
3
|
+
const strProto = Object.getPrototypeOf("");
|
|
4
|
+
const numProto = Object.getPrototypeOf(0);
|
|
5
|
+
const boolProto = Object.getPrototypeOf(false);
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @
|
|
7
|
+
* Determines the JSON type of a value.
|
|
8
|
+
* @param value - The value to check
|
|
9
|
+
* @returns "value" for primitives/null/undefined, "object" for plain objects, "array" for arrays
|
|
9
10
|
*/
|
|
10
|
-
function
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
* Determines the JSON type of a value.
|
|
18
|
-
* @param value - The value to check
|
|
19
|
-
* @returns "value" for primitives/null/undefined, "object" for plain objects, "array" for arrays
|
|
20
|
-
*/
|
|
21
|
-
function JsonType(value) {
|
|
22
|
-
if (value === null || value === undefined)
|
|
11
|
+
export function JsonType(value) {
|
|
12
|
+
if (value === null || value === undefined)
|
|
13
|
+
return "value";
|
|
14
|
+
switch (Object.getPrototypeOf(value)) {
|
|
15
|
+
case strProto:
|
|
16
|
+
case numProto:
|
|
17
|
+
case boolProto:
|
|
23
18
|
return "value";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
case boolProto:
|
|
28
|
-
return "value";
|
|
29
|
-
case jsonProto:
|
|
30
|
-
return "object";
|
|
31
|
-
case arrayProto:
|
|
32
|
-
return "array";
|
|
33
|
-
}
|
|
34
|
-
if (Array.isArray(value))
|
|
19
|
+
case jsonProto:
|
|
20
|
+
return "object";
|
|
21
|
+
case arrayProto:
|
|
35
22
|
return "array";
|
|
36
|
-
return "value";
|
|
37
23
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
24
|
+
if (Array.isArray(value))
|
|
25
|
+
return "array";
|
|
26
|
+
return "value";
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Deep merges a patch into a source value.
|
|
30
|
+
* - If types don't match, returns the patch
|
|
31
|
+
* - For objects: recursively merges properties, adds new properties
|
|
32
|
+
* - For arrays: maps over patch, merging with corresponding source elements
|
|
33
|
+
* @param source - The original value
|
|
34
|
+
* @param patch - The value to merge into source
|
|
35
|
+
* @returns The merged result
|
|
36
|
+
*/
|
|
37
|
+
export function JsonMerge(source, patch) {
|
|
38
|
+
if (patch === undefined)
|
|
39
|
+
return JsonDeepClone(source);
|
|
40
|
+
const sourceType = JsonType(source);
|
|
41
|
+
const patchType = JsonType(patch);
|
|
42
|
+
if (sourceType !== patchType)
|
|
43
|
+
return patch;
|
|
44
|
+
switch (sourceType) {
|
|
45
|
+
case "array": {
|
|
46
|
+
const typedSource = source;
|
|
47
|
+
const typedPatch = patch;
|
|
48
|
+
const result = new Array(typedPatch.length);
|
|
49
|
+
for (let x = 0; x < typedPatch.length; x++)
|
|
50
|
+
result[x] = JsonMerge(typedSource[x], typedPatch[x]);
|
|
51
|
+
return result;
|
|
52
|
+
}
|
|
53
|
+
case "object": {
|
|
54
|
+
const typedSource = source;
|
|
55
|
+
const typedPatch = patch;
|
|
56
|
+
const sourceKeys = Object.keys(typedSource);
|
|
57
|
+
const targetKeys = Object.keys(typedPatch).filter((key) => !sourceKeys.includes(key));
|
|
58
|
+
const result = {};
|
|
59
|
+
for (let x = 0; x < sourceKeys.length; x++) {
|
|
60
|
+
result[sourceKeys[x]] = JsonMerge(typedSource[sourceKeys[x]], typedPatch[sourceKeys[x]]);
|
|
62
61
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const typedPatch = patch;
|
|
66
|
-
const sourceKeys = Object.keys(typedSource);
|
|
67
|
-
const targetKeys = Object.keys(typedPatch).filter((key) => !sourceKeys.includes(key));
|
|
68
|
-
const result = {};
|
|
69
|
-
for (let x = 0; x < sourceKeys.length; x++) {
|
|
70
|
-
result[sourceKeys[x]] = JsonMerge(typedSource[sourceKeys[x]], typedPatch[sourceKeys[x]]);
|
|
71
|
-
}
|
|
72
|
-
for (let x = 0; x < targetKeys.length; x++) {
|
|
73
|
-
result[targetKeys[x]] = typedPatch[targetKeys[x]];
|
|
74
|
-
}
|
|
75
|
-
return result;
|
|
62
|
+
for (let x = 0; x < targetKeys.length; x++) {
|
|
63
|
+
result[targetKeys[x]] = typedPatch[targetKeys[x]];
|
|
76
64
|
}
|
|
77
|
-
|
|
78
|
-
return patch;
|
|
65
|
+
return result;
|
|
79
66
|
}
|
|
67
|
+
default:
|
|
68
|
+
return patch;
|
|
80
69
|
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Creates a deep clone of a JSON-compatible value.
|
|
73
|
+
* @template T - The type of the value to clone
|
|
74
|
+
* @param value - The value to clone
|
|
75
|
+
* @returns A deep clone of the value
|
|
76
|
+
*/
|
|
77
|
+
export function JsonDeepClone(value, type = JsonType(value)) {
|
|
78
|
+
switch (type) {
|
|
79
|
+
case "array": {
|
|
80
|
+
const typed = value;
|
|
81
|
+
const result = new Array(typed.length);
|
|
82
|
+
for (let x = 0; x < typed.length; x++)
|
|
83
|
+
result[x] = JsonDeepClone(typed[x]);
|
|
84
|
+
return result;
|
|
85
|
+
}
|
|
86
|
+
case "object": {
|
|
87
|
+
const ret = {};
|
|
88
|
+
const keys = Object.keys(value);
|
|
89
|
+
for (let x = 0; x < keys.length; x++)
|
|
90
|
+
ret[keys[x]] = JsonDeepClone(value[keys[x]]);
|
|
91
|
+
return ret;
|
|
92
|
+
}
|
|
93
|
+
default:
|
|
94
|
+
return value;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Computes the differences between two JSON values.
|
|
99
|
+
* Returns an array of paths and values that changed from oldValue to newValue.
|
|
100
|
+
* @template T - The type of the JSON values being compared
|
|
101
|
+
* @param newValue - The new value
|
|
102
|
+
* @param oldValue - The old value to compare against
|
|
103
|
+
* @param rootPath - Optional dot-separated string for the base path (for internal recursion)
|
|
104
|
+
* @param initResult - Optional initial result array (for internal recursion)
|
|
105
|
+
* @returns Array of change records with path and new value
|
|
106
|
+
*/
|
|
107
|
+
export function JsonDiff(newValue, oldValue, rootPath, initResult) {
|
|
108
|
+
const result = initResult ?? [];
|
|
109
|
+
const startPath = rootPath ? rootPath.split(".") : [];
|
|
110
|
+
JsonDiffRecursive(startPath, newValue, oldValue, result);
|
|
111
|
+
return result;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Recursive helper for JsonDiff that traverses and compares values.
|
|
115
|
+
* @internal
|
|
116
|
+
* @param path - Current path being evaluated
|
|
117
|
+
* @param newValue - New value at this path
|
|
118
|
+
* @param oldValue - Old value at this path
|
|
119
|
+
* @param resp - Result array to populate with changes
|
|
120
|
+
* @returns true if the entire subtree changed, false otherwise
|
|
121
|
+
*/
|
|
122
|
+
function JsonDiffRecursive(path, newValue, oldValue, resp) {
|
|
123
|
+
if (newValue === oldValue)
|
|
124
|
+
return false;
|
|
125
|
+
const newType = JsonType(newValue);
|
|
126
|
+
const oldType = JsonType(oldValue);
|
|
127
|
+
const changedPathLength = resp.length;
|
|
128
|
+
let allChildrenChanged = true;
|
|
129
|
+
if (newType === oldType)
|
|
130
|
+
switch (newType) {
|
|
89
131
|
case "array": {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
for (let x = 0; x < typed.length; x++)
|
|
93
|
-
result[x] = JsonDeepClone(typed[x]);
|
|
94
|
-
return result;
|
|
132
|
+
allChildrenChanged = JsonDiffArrays(path, newValue, oldValue, resp);
|
|
133
|
+
break;
|
|
95
134
|
}
|
|
96
135
|
case "object": {
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
for (let x = 0; x < keys.length; x++)
|
|
100
|
-
ret[keys[x]] = JsonDeepClone(value[keys[x]]);
|
|
101
|
-
return ret;
|
|
136
|
+
allChildrenChanged = JsonDiffObjects(path, newValue, oldValue, resp);
|
|
137
|
+
break;
|
|
102
138
|
}
|
|
103
|
-
default:
|
|
104
|
-
return value;
|
|
105
139
|
}
|
|
140
|
+
if (allChildrenChanged) {
|
|
141
|
+
resp.length > changedPathLength && resp.splice(changedPathLength);
|
|
142
|
+
resp.push({
|
|
143
|
+
path,
|
|
144
|
+
value: newValue,
|
|
145
|
+
});
|
|
146
|
+
return true;
|
|
106
147
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return result;
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Compares two arrays and records differences.
|
|
152
|
+
* @internal
|
|
153
|
+
* @param path - Current path being evaluated
|
|
154
|
+
* @param newValue - New array
|
|
155
|
+
* @param oldValue - Old array to compare against
|
|
156
|
+
* @param resp - Result array to populate with changes
|
|
157
|
+
* @returns true if the entire array changed, false otherwise
|
|
158
|
+
*/
|
|
159
|
+
function JsonDiffArrays(path, newValue, oldValue, resp) {
|
|
160
|
+
if (oldValue.length === 0 || newValue.length === 0) {
|
|
161
|
+
return oldValue.length !== newValue.length;
|
|
122
162
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
*/
|
|
132
|
-
function JsonDiffRecursive(path, newValue, oldValue, resp) {
|
|
133
|
-
if (newValue === oldValue)
|
|
134
|
-
return false;
|
|
135
|
-
const newType = JsonType(newValue);
|
|
136
|
-
const oldType = JsonType(oldValue);
|
|
137
|
-
const changedPathLength = resp.length;
|
|
138
|
-
let allChildrenChanged = true;
|
|
139
|
-
if (newType === oldType)
|
|
140
|
-
switch (newType) {
|
|
141
|
-
case "array": {
|
|
142
|
-
allChildrenChanged = JsonDiffArrays(path, newValue, oldValue, resp);
|
|
143
|
-
break;
|
|
144
|
-
}
|
|
145
|
-
case "object": {
|
|
146
|
-
allChildrenChanged = JsonDiffObjects(path, newValue, oldValue, resp);
|
|
147
|
-
break;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
if (allChildrenChanged) {
|
|
151
|
-
resp.length > changedPathLength && resp.splice(changedPathLength);
|
|
152
|
-
resp.push({
|
|
153
|
-
path,
|
|
154
|
-
value: newValue,
|
|
155
|
-
});
|
|
156
|
-
return true;
|
|
163
|
+
let allChildrenChanged = true;
|
|
164
|
+
if (newValue.length > 0 || oldValue.length > 0) {
|
|
165
|
+
for (let y = 0; y < newValue.length; y++) {
|
|
166
|
+
const arrayPath = path.concat(y);
|
|
167
|
+
const oldValueElem = oldValue[y];
|
|
168
|
+
allChildrenChanged =
|
|
169
|
+
JsonDiffRecursive(arrayPath, newValue[y], oldValueElem, resp) &&
|
|
170
|
+
allChildrenChanged;
|
|
157
171
|
}
|
|
158
|
-
return false;
|
|
159
172
|
}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
173
|
+
else
|
|
174
|
+
allChildrenChanged = false;
|
|
175
|
+
if (newValue.length !== oldValue.length)
|
|
176
|
+
resp.push({
|
|
177
|
+
path: path.concat("length"),
|
|
178
|
+
value: newValue.length,
|
|
179
|
+
});
|
|
180
|
+
return allChildrenChanged;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Compares two objects and records differences.
|
|
184
|
+
* Uses sorted keys and two-pointer technique for efficient comparison.
|
|
185
|
+
* @internal
|
|
186
|
+
* @param path - Current path being evaluated
|
|
187
|
+
* @param newValue - New object
|
|
188
|
+
* @param oldValue - Old object to compare against
|
|
189
|
+
* @param resp - Result array to populate with changes
|
|
190
|
+
* @returns true if the entire object should be replaced (keys removed), false otherwise
|
|
191
|
+
*/
|
|
192
|
+
function JsonDiffObjects(path, newValue, oldValue, resp) {
|
|
193
|
+
const newKeys = Object.keys(newValue).sort();
|
|
194
|
+
const oldKeys = Object.keys(oldValue).sort();
|
|
195
|
+
if (newKeys.length === 0 && oldKeys.length === 0)
|
|
196
|
+
return false;
|
|
197
|
+
if (newKeys.length < oldKeys.length)
|
|
198
|
+
return true;
|
|
199
|
+
let newKeyIndex = 0;
|
|
200
|
+
let oldKeyIndex = 0;
|
|
201
|
+
while (newKeyIndex < newKeys.length) {
|
|
202
|
+
const childPath = path.concat(newKeys[newKeyIndex]);
|
|
203
|
+
if (oldKeyIndex < oldKeys.length &&
|
|
204
|
+
newKeys[newKeyIndex] === oldKeys[oldKeyIndex]) {
|
|
205
|
+
JsonDiffRecursive(childPath, newValue[newKeys[newKeyIndex]], oldValue[oldKeys[oldKeyIndex]], resp);
|
|
206
|
+
oldKeyIndex++;
|
|
182
207
|
}
|
|
183
|
-
else
|
|
184
|
-
allChildrenChanged = false;
|
|
185
|
-
if (newValue.length !== oldValue.length)
|
|
208
|
+
else if (newValue[newKeys[newKeyIndex]] !== undefined) {
|
|
186
209
|
resp.push({
|
|
187
|
-
path:
|
|
188
|
-
value: newValue
|
|
210
|
+
path: childPath,
|
|
211
|
+
value: newValue[newKeys[newKeyIndex]],
|
|
189
212
|
});
|
|
190
|
-
return allChildrenChanged;
|
|
191
|
-
}
|
|
192
|
-
/**
|
|
193
|
-
* Compares two objects and records differences.
|
|
194
|
-
* Uses sorted keys and two-pointer technique for efficient comparison.
|
|
195
|
-
* @internal
|
|
196
|
-
* @param path - Current path being evaluated
|
|
197
|
-
* @param newValue - New object
|
|
198
|
-
* @param oldValue - Old object to compare against
|
|
199
|
-
* @param resp - Result array to populate with changes
|
|
200
|
-
* @returns true if the entire object should be replaced (keys removed), false otherwise
|
|
201
|
-
*/
|
|
202
|
-
function JsonDiffObjects(path, newValue, oldValue, resp) {
|
|
203
|
-
const newKeys = Object.keys(newValue).sort();
|
|
204
|
-
const oldKeys = Object.keys(oldValue).sort();
|
|
205
|
-
if (newKeys.length === 0 && oldKeys.length === 0)
|
|
206
|
-
return false;
|
|
207
|
-
if (newKeys.length < oldKeys.length)
|
|
208
|
-
return true;
|
|
209
|
-
let newKeyIndex = 0;
|
|
210
|
-
let oldKeyIndex = 0;
|
|
211
|
-
while (newKeyIndex < newKeys.length) {
|
|
212
|
-
const childPath = path.concat(newKeys[newKeyIndex]);
|
|
213
|
-
if (oldKeyIndex < oldKeys.length &&
|
|
214
|
-
newKeys[newKeyIndex] === oldKeys[oldKeyIndex]) {
|
|
215
|
-
JsonDiffRecursive(childPath, newValue[newKeys[newKeyIndex]], oldValue[oldKeys[oldKeyIndex]], resp);
|
|
216
|
-
oldKeyIndex++;
|
|
217
|
-
}
|
|
218
|
-
else if (newValue[newKeys[newKeyIndex]] !== undefined) {
|
|
219
|
-
resp.push({
|
|
220
|
-
path: childPath,
|
|
221
|
-
value: newValue[newKeys[newKeyIndex]],
|
|
222
|
-
});
|
|
223
|
-
}
|
|
224
|
-
newKeyIndex++;
|
|
225
213
|
}
|
|
226
|
-
|
|
227
|
-
return true;
|
|
228
|
-
return false;
|
|
214
|
+
newKeyIndex++;
|
|
229
215
|
}
|
|
230
|
-
|
|
216
|
+
if (oldKeyIndex < oldKeys.length)
|
|
217
|
+
return true;
|
|
218
|
+
return false;
|
|
231
219
|
}
|
|
232
|
-
_a = JsonDiffFactory(), exports.JsonDiff = _a.JsonDiff, exports.JsonType = _a.JsonType, exports.JsonDeepClone = _a.JsonDeepClone, exports.JsonMerge = _a.JsonMerge;
|
package/Utils/list.js
CHANGED
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.List = void 0;
|
|
4
|
-
var List;
|
|
1
|
+
export var List;
|
|
5
2
|
(function (List) {
|
|
6
3
|
function CreateNode(data) {
|
|
7
4
|
return { previous: null, next: null, data };
|
|
@@ -223,4 +220,4 @@ var List;
|
|
|
223
220
|
return map;
|
|
224
221
|
}
|
|
225
222
|
List.ToListMap = ToListMap;
|
|
226
|
-
})(List || (
|
|
223
|
+
})(List || (List = {}));
|
package/Utils/scheduling.js
CHANGED
|
@@ -1,25 +1,22 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._requestIdleCallback = exports._queueMicrotask = exports._setTimeout = exports._requestAnimationFrame = void 0;
|
|
4
1
|
const IMMEDIATE_OVERRIDE = typeof process !== "undefined" ?
|
|
5
2
|
process.env.SYNC_SCHEDULING === 'true' :
|
|
6
3
|
false;
|
|
7
|
-
|
|
4
|
+
export const _requestAnimationFrame = IMMEDIATE_OVERRIDE ?
|
|
8
5
|
function immediateRequestAnimationFrame(callback) {
|
|
9
6
|
callback(0);
|
|
10
7
|
return 0;
|
|
11
8
|
} : window.requestAnimationFrame;
|
|
12
|
-
|
|
9
|
+
export const _setTimeout = IMMEDIATE_OVERRIDE ?
|
|
13
10
|
function immediateSetTimeout(handler, timeout, ...args) {
|
|
14
11
|
if (typeof handler === "function")
|
|
15
12
|
handler(...args);
|
|
16
13
|
return 0;
|
|
17
14
|
} : window.setTimeout;
|
|
18
|
-
|
|
15
|
+
export const _queueMicrotask = IMMEDIATE_OVERRIDE ?
|
|
19
16
|
function immediateQueueMicrotask(callback) {
|
|
20
17
|
callback();
|
|
21
18
|
} : window.queueMicrotask;
|
|
22
|
-
|
|
19
|
+
export const _requestIdleCallback = IMMEDIATE_OVERRIDE ?
|
|
23
20
|
function immediateRequestIdleCallback(callback, options) {
|
|
24
21
|
callback({ didTimeout: false, timeRemaining: () => 0 });
|
|
25
22
|
return 0;
|
package/Utils/thread.js
CHANGED
|
@@ -1,13 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.Schedule = Schedule;
|
|
4
|
-
exports.After = After;
|
|
5
|
-
exports.Callback = Callback;
|
|
6
|
-
exports.Synch = Synch;
|
|
7
|
-
exports.Thread = Thread;
|
|
8
|
-
exports.ThreadAsync = ThreadAsync;
|
|
9
|
-
const list_1 = require("./list");
|
|
10
|
-
const scheduling_1 = require("./scheduling");
|
|
1
|
+
import { List } from "./list";
|
|
2
|
+
import { _queueMicrotask, _setTimeout } from "./scheduling";
|
|
11
3
|
// Constants
|
|
12
4
|
/**
|
|
13
5
|
* The maximum time allowed for work execution in milliseconds
|
|
@@ -16,7 +8,7 @@ const workTimeMs = 16;
|
|
|
16
8
|
/**
|
|
17
9
|
* Queue of thread contexts that need processing
|
|
18
10
|
*/
|
|
19
|
-
const contextQueue =
|
|
11
|
+
const contextQueue = List.Create();
|
|
20
12
|
// State variables
|
|
21
13
|
let threadContext = null;
|
|
22
14
|
let timeoutRunning = false;
|
|
@@ -44,10 +36,10 @@ function createDeadline() {
|
|
|
44
36
|
*/
|
|
45
37
|
function ProcessQueue(deadline = createDeadline()) {
|
|
46
38
|
let ctx;
|
|
47
|
-
while (deadline.timeRemaining() > 0 && (ctx =
|
|
39
|
+
while (deadline.timeRemaining() > 0 && (ctx = List.Pop(contextQueue)))
|
|
48
40
|
DoWork(ctx, deadline);
|
|
49
41
|
if (contextQueue.size > 0)
|
|
50
|
-
|
|
42
|
+
_setTimeout(ProcessQueue);
|
|
51
43
|
else
|
|
52
44
|
timeoutRunning = false;
|
|
53
45
|
}
|
|
@@ -56,11 +48,11 @@ function ProcessQueue(deadline = createDeadline()) {
|
|
|
56
48
|
* @param ctx - The thread context to schedule
|
|
57
49
|
*/
|
|
58
50
|
function ScheduleWork(ctx) {
|
|
59
|
-
|
|
51
|
+
List.Add(contextQueue, ctx);
|
|
60
52
|
if (timeoutRunning)
|
|
61
53
|
return;
|
|
62
54
|
timeoutRunning = true;
|
|
63
|
-
|
|
55
|
+
_queueMicrotask(ProcessQueue);
|
|
64
56
|
}
|
|
65
57
|
/**
|
|
66
58
|
* Invokes a callback in the specified thread context
|
|
@@ -85,7 +77,7 @@ function DoWork(ctx, deadline = createDeadline()) {
|
|
|
85
77
|
let callback;
|
|
86
78
|
while (async === ctx.async &&
|
|
87
79
|
deadline.timeRemaining() > 0 &&
|
|
88
|
-
(callback =
|
|
80
|
+
(callback = List.Pop(ctx.workList)))
|
|
89
81
|
Invoke(ctx, callback);
|
|
90
82
|
if (ctx.workList.size > 0)
|
|
91
83
|
ScheduleWork(ctx);
|
|
@@ -99,7 +91,7 @@ function CreateContext() {
|
|
|
99
91
|
return {
|
|
100
92
|
async: false,
|
|
101
93
|
workEndNode: null,
|
|
102
|
-
workList:
|
|
94
|
+
workList: List.Create(),
|
|
103
95
|
};
|
|
104
96
|
}
|
|
105
97
|
/**
|
|
@@ -112,11 +104,11 @@ function ScheduleCallback(callback, before, async) {
|
|
|
112
104
|
threadContext = threadContext || CreateContext();
|
|
113
105
|
threadContext.async = threadContext.async || async;
|
|
114
106
|
if (before)
|
|
115
|
-
|
|
107
|
+
List.AddBefore(threadContext.workList, threadContext.workEndNode, callback);
|
|
116
108
|
else if (threadContext.workEndNode)
|
|
117
|
-
|
|
109
|
+
List.AddAfter(threadContext.workList, threadContext.workEndNode, callback);
|
|
118
110
|
else
|
|
119
|
-
threadContext.workEndNode =
|
|
111
|
+
threadContext.workEndNode = List.Add(threadContext.workList, callback);
|
|
120
112
|
}
|
|
121
113
|
/**
|
|
122
114
|
* Executes a callback synchronously without using threading
|
|
@@ -135,14 +127,14 @@ function SynchWithoutThread(callback) {
|
|
|
135
127
|
* Schedules a callback to run asynchronously
|
|
136
128
|
* @param callback - The callback function to schedule
|
|
137
129
|
*/
|
|
138
|
-
function Schedule(callback) {
|
|
130
|
+
export function Schedule(callback) {
|
|
139
131
|
ScheduleCallback(callback, true, true);
|
|
140
132
|
}
|
|
141
133
|
/**
|
|
142
134
|
* Schedules a callback to run after existing callbacks in the same context
|
|
143
135
|
* @param callback - The callback function to schedule
|
|
144
136
|
*/
|
|
145
|
-
function After(callback) {
|
|
137
|
+
export function After(callback) {
|
|
146
138
|
ScheduleCallback(callback, false, false);
|
|
147
139
|
}
|
|
148
140
|
/**
|
|
@@ -150,7 +142,7 @@ function After(callback) {
|
|
|
150
142
|
* @param callback - The original callback function
|
|
151
143
|
* @returns A wrapped function that schedules execution
|
|
152
144
|
*/
|
|
153
|
-
function Callback(callback) {
|
|
145
|
+
export function Callback(callback) {
|
|
154
146
|
return function (a, b, c, d) {
|
|
155
147
|
Schedule(function () {
|
|
156
148
|
callback(a, b, c, d);
|
|
@@ -165,7 +157,7 @@ var inSynchCallback = false;
|
|
|
165
157
|
* Executes a callback synchronously or asynchronously based on context
|
|
166
158
|
* @param callback - The callback function to execute
|
|
167
159
|
*/
|
|
168
|
-
function Synch(callback) {
|
|
160
|
+
export function Synch(callback) {
|
|
169
161
|
if (threadContext || inSynchCallback)
|
|
170
162
|
callback(false);
|
|
171
163
|
else {
|
|
@@ -178,7 +170,7 @@ function Synch(callback) {
|
|
|
178
170
|
* Schedules a callback that can run either synchronously or asynchronously
|
|
179
171
|
* @param callback - The callback function to schedule
|
|
180
172
|
*/
|
|
181
|
-
function Thread(callback) {
|
|
173
|
+
export function Thread(callback) {
|
|
182
174
|
if (threadContext)
|
|
183
175
|
ScheduleCallback(callback, true, false);
|
|
184
176
|
else
|
|
@@ -189,7 +181,7 @@ function Thread(callback) {
|
|
|
189
181
|
* @param callback - The callback function to execute
|
|
190
182
|
* @returns A promise that resolves when the callback completes
|
|
191
183
|
*/
|
|
192
|
-
function ThreadAsync(callback) {
|
|
184
|
+
export function ThreadAsync(callback) {
|
|
193
185
|
return new Promise((resolve) => Thread(function (async) {
|
|
194
186
|
callback(async);
|
|
195
187
|
Thread(resolve);
|
package/Utils/utils.types.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
1
|
+
export {};
|
package/_not_used/array.js
CHANGED
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.ArrayDiff = ArrayDiff;
|
|
4
|
-
exports.ReconcileSortedEmitters = ReconcileSortedEmitters;
|
|
5
|
-
exports.InsertionSortTuples = InsertionSortTuples;
|
|
6
|
-
exports.ReconcileSortedArrays = ReconcileSortedArrays;
|
|
7
|
-
function ArrayDiff(source, target) {
|
|
1
|
+
export function ArrayDiff(source, target) {
|
|
8
2
|
if (source === target)
|
|
9
3
|
return false;
|
|
10
4
|
if (!source || !target || source.length !== target.length)
|
|
@@ -44,7 +38,7 @@ function ArrayDiff(source, target) {
|
|
|
44
38
|
* // Adds [2, 4] and removes [1]
|
|
45
39
|
* ```
|
|
46
40
|
*/
|
|
47
|
-
function ReconcileSortedEmitters(left, right, add, remove) {
|
|
41
|
+
export function ReconcileSortedEmitters(left, right, add, remove) {
|
|
48
42
|
let leftIndex = 0;
|
|
49
43
|
let rightIndex = 0;
|
|
50
44
|
while (leftIndex < left.length && rightIndex < right.length) {
|
|
@@ -68,7 +62,7 @@ function ReconcileSortedEmitters(left, right, add, remove) {
|
|
|
68
62
|
for (let ri = rightIndex; ri < right.length; ri++)
|
|
69
63
|
add(right[ri]);
|
|
70
64
|
}
|
|
71
|
-
function InsertionSortTuples(arr) {
|
|
65
|
+
export function InsertionSortTuples(arr) {
|
|
72
66
|
const n = arr.length;
|
|
73
67
|
// Start from the second element (index 1) as the first element (index 0)
|
|
74
68
|
// is trivially sorted by itself.
|
|
@@ -89,7 +83,7 @@ function InsertionSortTuples(arr) {
|
|
|
89
83
|
}
|
|
90
84
|
return arr;
|
|
91
85
|
}
|
|
92
|
-
function ReconcileSortedArrays(left, right, add, remove) {
|
|
86
|
+
export function ReconcileSortedArrays(left, right, add, remove) {
|
|
93
87
|
let leftIndex = 0;
|
|
94
88
|
let rightIndex = 0;
|
|
95
89
|
while (leftIndex < left.length && rightIndex < right.length) {
|