@signaltree/core 8.0.2 → 9.0.1
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/README.md +52 -66
- package/dist/edit-session.js +1 -0
- package/dist/enhancers/batching/batching.js +19 -16
- package/dist/enhancers/devtools/devtools.js +14 -1
- package/dist/enhancers/serialization/serialization.js +38 -17
- package/dist/enhancers/time-travel/time-travel.js +15 -7
- package/dist/index.js +6 -13
- package/dist/lib/constants.js +2 -1
- package/dist/lib/signal-tree.js +59 -1
- package/dist/security.js +1 -0
- package/dist/storage.js +1 -0
- package/package.json +16 -1
- package/src/edit-session.d.ts +1 -0
- package/src/enhancers/types.d.ts +1 -1
- package/src/enhancers/typing/helpers-types.d.ts +1 -1
- package/src/index.d.ts +7 -13
- package/src/lib/types.d.ts +3 -26
- package/src/security.d.ts +1 -0
- package/src/storage.d.ts +2 -0
- package/dist/enhancers/effects/effects.js +0 -66
- package/dist/enhancers/entities/entities.js +0 -7
- package/dist/enhancers/memoization/memoization.js +0 -420
- package/dist/enhancers/presets/lib/presets.js +0 -27
- package/dist/lib/async-helpers.js +0 -77
- package/dist/lib/presets.js +0 -20
- package/src/enhancers/memoization/index.d.ts +0 -1
- package/src/enhancers/memoization/memoization.d.ts +0 -54
- package/src/enhancers/memoization/memoization.types.d.ts +0 -1
- package/src/enhancers/memoization/test-setup.d.ts +0 -3
- package/src/enhancers/presets/index.d.ts +0 -1
- package/src/enhancers/presets/lib/presets.d.ts +0 -8
- package/src/lib/presets.d.ts +0 -34
|
@@ -1,420 +0,0 @@
|
|
|
1
|
-
import { computed } from '@angular/core';
|
|
2
|
-
import { isNodeAccessor } from '../../lib/utils.js';
|
|
3
|
-
import { deepEqual } from '../../shared/lib/deep-equal.js';
|
|
4
|
-
import { LRUCache } from '../../shared/lib/lru-cache.js';
|
|
5
|
-
|
|
6
|
-
function isDevMode() {
|
|
7
|
-
if (typeof __DEV__ !== 'undefined') {
|
|
8
|
-
return __DEV__;
|
|
9
|
-
}
|
|
10
|
-
return false;
|
|
11
|
-
}
|
|
12
|
-
const MAX_CACHE_SIZE = 1000;
|
|
13
|
-
const DEFAULT_TTL = 5 * 60 * 1000;
|
|
14
|
-
const memoizationCache = new Map();
|
|
15
|
-
function createMemoCacheStore(maxSize, enableLRU) {
|
|
16
|
-
if (enableLRU) {
|
|
17
|
-
const cache = new LRUCache(maxSize);
|
|
18
|
-
const shadow = new Map();
|
|
19
|
-
const pruneShadow = () => {
|
|
20
|
-
while (shadow.size > cache.size()) {
|
|
21
|
-
const oldestKey = shadow.keys().next().value;
|
|
22
|
-
if (oldestKey === undefined) {
|
|
23
|
-
break;
|
|
24
|
-
}
|
|
25
|
-
shadow.delete(oldestKey);
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
return {
|
|
29
|
-
get: key => {
|
|
30
|
-
const value = cache.get(key);
|
|
31
|
-
if (value !== undefined) {
|
|
32
|
-
shadow.set(key, value);
|
|
33
|
-
} else if (shadow.has(key)) {
|
|
34
|
-
shadow.delete(key);
|
|
35
|
-
}
|
|
36
|
-
return value;
|
|
37
|
-
},
|
|
38
|
-
set: (key, value) => {
|
|
39
|
-
cache.set(key, value);
|
|
40
|
-
shadow.set(key, value);
|
|
41
|
-
pruneShadow();
|
|
42
|
-
},
|
|
43
|
-
delete: key => {
|
|
44
|
-
cache.delete(key);
|
|
45
|
-
shadow.delete(key);
|
|
46
|
-
},
|
|
47
|
-
clear: () => {
|
|
48
|
-
cache.clear();
|
|
49
|
-
shadow.clear();
|
|
50
|
-
},
|
|
51
|
-
size: () => shadow.size,
|
|
52
|
-
forEach: callback => {
|
|
53
|
-
shadow.forEach((value, key) => callback(value, key));
|
|
54
|
-
},
|
|
55
|
-
keys: () => shadow.keys()
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
const store = new Map();
|
|
59
|
-
return {
|
|
60
|
-
get: key => store.get(key),
|
|
61
|
-
set: (key, value) => {
|
|
62
|
-
store.set(key, value);
|
|
63
|
-
},
|
|
64
|
-
delete: key => store.delete(key),
|
|
65
|
-
clear: () => store.clear(),
|
|
66
|
-
size: () => store.size,
|
|
67
|
-
forEach: callback => {
|
|
68
|
-
store.forEach((value, key) => callback(value, key));
|
|
69
|
-
},
|
|
70
|
-
keys: () => store.keys()
|
|
71
|
-
};
|
|
72
|
-
}
|
|
73
|
-
function getCleanupInterval(tree) {
|
|
74
|
-
return tree._memoCleanupInterval;
|
|
75
|
-
}
|
|
76
|
-
function setCleanupInterval(tree, interval) {
|
|
77
|
-
if (interval === undefined) {
|
|
78
|
-
delete tree._memoCleanupInterval;
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
tree._memoCleanupInterval = interval;
|
|
82
|
-
}
|
|
83
|
-
function clearCleanupInterval(tree) {
|
|
84
|
-
const interval = getCleanupInterval(tree);
|
|
85
|
-
if (!interval) {
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
try {
|
|
89
|
-
clearInterval(interval);
|
|
90
|
-
} catch {}
|
|
91
|
-
setCleanupInterval(tree);
|
|
92
|
-
}
|
|
93
|
-
function resetMemoizationCaches() {
|
|
94
|
-
memoizationCache.forEach((cache, tree) => {
|
|
95
|
-
cache.clear();
|
|
96
|
-
clearCleanupInterval(tree);
|
|
97
|
-
});
|
|
98
|
-
memoizationCache.clear();
|
|
99
|
-
}
|
|
100
|
-
function shallowEqual(a, b) {
|
|
101
|
-
if (a === b) return true;
|
|
102
|
-
if (a == null || b == null) return false;
|
|
103
|
-
if (typeof a !== typeof b) return false;
|
|
104
|
-
if (typeof a === 'object' && typeof b === 'object') {
|
|
105
|
-
const objA = a;
|
|
106
|
-
const objB = b;
|
|
107
|
-
let countA = 0;
|
|
108
|
-
for (const key in objA) {
|
|
109
|
-
if (!Object.prototype.hasOwnProperty.call(objA, key)) continue;
|
|
110
|
-
countA++;
|
|
111
|
-
if (!(key in objB) || objA[key] !== objB[key]) return false;
|
|
112
|
-
}
|
|
113
|
-
let countB = 0;
|
|
114
|
-
for (const key in objB) {
|
|
115
|
-
if (Object.prototype.hasOwnProperty.call(objB, key)) countB++;
|
|
116
|
-
}
|
|
117
|
-
return countA === countB;
|
|
118
|
-
}
|
|
119
|
-
return false;
|
|
120
|
-
}
|
|
121
|
-
function generateCacheKey(fn, args) {
|
|
122
|
-
try {
|
|
123
|
-
return `${fn.name || 'anonymous'}_${JSON.stringify(args)}`;
|
|
124
|
-
} catch {
|
|
125
|
-
return `${fn.name || 'anonymous'}_${args.length}`;
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
function getEqualityFn(strategy) {
|
|
129
|
-
switch (strategy) {
|
|
130
|
-
case 'shallow':
|
|
131
|
-
return shallowEqual;
|
|
132
|
-
case 'reference':
|
|
133
|
-
return (a, b) => a === b;
|
|
134
|
-
case 'deep':
|
|
135
|
-
default:
|
|
136
|
-
return deepEqual;
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
function memoize(fn, keyFn, config = {}) {
|
|
140
|
-
const maxSize = config.maxCacheSize ?? MAX_CACHE_SIZE;
|
|
141
|
-
const ttl = config.ttl ?? DEFAULT_TTL;
|
|
142
|
-
const equality = getEqualityFn(config.equality ?? 'shallow');
|
|
143
|
-
const enableLRU = config.enableLRU ?? false;
|
|
144
|
-
const cache = createMemoCacheStore(maxSize, enableLRU);
|
|
145
|
-
const cleanExpiredEntries = () => {
|
|
146
|
-
if (!ttl) return;
|
|
147
|
-
const now = Date.now();
|
|
148
|
-
cache.forEach((entry, key) => {
|
|
149
|
-
if (entry.timestamp && now - entry.timestamp > ttl) {
|
|
150
|
-
cache.delete(key);
|
|
151
|
-
}
|
|
152
|
-
});
|
|
153
|
-
};
|
|
154
|
-
return (...args) => {
|
|
155
|
-
if (ttl && Math.random() < 0.01) {
|
|
156
|
-
cleanExpiredEntries();
|
|
157
|
-
}
|
|
158
|
-
const key = keyFn ? keyFn(...args) : generateCacheKey(fn, args);
|
|
159
|
-
const cached = cache.get(key);
|
|
160
|
-
if (cached && (keyFn || equality(cached.deps, args))) {
|
|
161
|
-
if (enableLRU) {
|
|
162
|
-
cached.hitCount += 1;
|
|
163
|
-
}
|
|
164
|
-
return cached.value;
|
|
165
|
-
}
|
|
166
|
-
const result = fn(...args);
|
|
167
|
-
cache.set(key, {
|
|
168
|
-
value: result,
|
|
169
|
-
deps: args,
|
|
170
|
-
timestamp: Date.now(),
|
|
171
|
-
hitCount: 1
|
|
172
|
-
});
|
|
173
|
-
return result;
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
function memoizeShallow(fn, keyFn) {
|
|
177
|
-
return memoize(fn, keyFn, {
|
|
178
|
-
equality: 'shallow',
|
|
179
|
-
enableLRU: false,
|
|
180
|
-
ttl: undefined,
|
|
181
|
-
maxCacheSize: 100
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
function memoizeReference(fn, keyFn) {
|
|
185
|
-
return memoize(fn, keyFn, {
|
|
186
|
-
equality: 'reference',
|
|
187
|
-
enableLRU: false,
|
|
188
|
-
ttl: undefined,
|
|
189
|
-
maxCacheSize: 50
|
|
190
|
-
});
|
|
191
|
-
}
|
|
192
|
-
const MEMOIZATION_PRESETS = {
|
|
193
|
-
selector: {
|
|
194
|
-
equality: 'reference',
|
|
195
|
-
maxCacheSize: 10,
|
|
196
|
-
enableLRU: false,
|
|
197
|
-
ttl: undefined
|
|
198
|
-
},
|
|
199
|
-
computed: {
|
|
200
|
-
equality: 'shallow',
|
|
201
|
-
maxCacheSize: 100,
|
|
202
|
-
enableLRU: false,
|
|
203
|
-
ttl: undefined
|
|
204
|
-
},
|
|
205
|
-
deepState: {
|
|
206
|
-
equality: 'deep',
|
|
207
|
-
maxCacheSize: 1000,
|
|
208
|
-
enableLRU: true,
|
|
209
|
-
ttl: 5 * 60 * 1000
|
|
210
|
-
},
|
|
211
|
-
highFrequency: {
|
|
212
|
-
equality: 'reference',
|
|
213
|
-
maxCacheSize: 5,
|
|
214
|
-
enableLRU: false,
|
|
215
|
-
ttl: undefined
|
|
216
|
-
}
|
|
217
|
-
};
|
|
218
|
-
function selectorMemoization() {
|
|
219
|
-
return memoization(MEMOIZATION_PRESETS.selector);
|
|
220
|
-
}
|
|
221
|
-
function computedMemoization() {
|
|
222
|
-
return memoization(MEMOIZATION_PRESETS.computed);
|
|
223
|
-
}
|
|
224
|
-
function deepStateMemoization() {
|
|
225
|
-
return memoization(MEMOIZATION_PRESETS.deepState);
|
|
226
|
-
}
|
|
227
|
-
function highFrequencyMemoization() {
|
|
228
|
-
return memoization(MEMOIZATION_PRESETS.highFrequency);
|
|
229
|
-
}
|
|
230
|
-
Object.assign((config = {}) => memoization(config), {
|
|
231
|
-
selector: selectorMemoization,
|
|
232
|
-
computed: computedMemoization,
|
|
233
|
-
deep: deepStateMemoization,
|
|
234
|
-
fast: highFrequencyMemoization
|
|
235
|
-
});
|
|
236
|
-
function memoization(config = {}) {
|
|
237
|
-
const {
|
|
238
|
-
enabled = true,
|
|
239
|
-
maxCacheSize = 1000,
|
|
240
|
-
ttl,
|
|
241
|
-
equality = 'deep',
|
|
242
|
-
enableLRU = true
|
|
243
|
-
} = config;
|
|
244
|
-
const enhancer = tree => {
|
|
245
|
-
const originalTreeCall = tree.bind(tree);
|
|
246
|
-
const applyUpdateResult = result => {
|
|
247
|
-
Object.entries(result).forEach(([propKey, value]) => {
|
|
248
|
-
const property = tree.state[propKey];
|
|
249
|
-
if (property && 'set' in property) {
|
|
250
|
-
property.set(value);
|
|
251
|
-
} else if (isNodeAccessor(property)) {
|
|
252
|
-
property(value);
|
|
253
|
-
}
|
|
254
|
-
});
|
|
255
|
-
};
|
|
256
|
-
if (!enabled) {
|
|
257
|
-
const memoTree = tree;
|
|
258
|
-
memoTree.memoize = (fn, _cacheKey) => {
|
|
259
|
-
return computed(() => fn(originalTreeCall()));
|
|
260
|
-
};
|
|
261
|
-
memoTree.memoizedUpdate = updater => {
|
|
262
|
-
const currentState = originalTreeCall();
|
|
263
|
-
const result = updater(currentState);
|
|
264
|
-
applyUpdateResult(result);
|
|
265
|
-
};
|
|
266
|
-
memoTree.clearMemoCache = () => {};
|
|
267
|
-
memoTree.clearCache = memoTree.clearMemoCache;
|
|
268
|
-
memoTree.getCacheStats = () => ({
|
|
269
|
-
size: 0,
|
|
270
|
-
hitRate: 0,
|
|
271
|
-
totalHits: 0,
|
|
272
|
-
totalMisses: 0,
|
|
273
|
-
keys: []
|
|
274
|
-
});
|
|
275
|
-
return memoTree;
|
|
276
|
-
}
|
|
277
|
-
const cache = createMemoCacheStore(maxCacheSize, enableLRU);
|
|
278
|
-
memoizationCache.set(tree, cache);
|
|
279
|
-
const equalityFn = getEqualityFn(equality);
|
|
280
|
-
tree.memoizedUpdate = (updater, cacheKey) => {
|
|
281
|
-
const currentState = originalTreeCall();
|
|
282
|
-
const key = cacheKey || generateCacheKey(updater, [currentState]);
|
|
283
|
-
const cached = cache.get(key);
|
|
284
|
-
if (cached && equalityFn(cached.deps, [currentState])) {
|
|
285
|
-
const cachedUpdate = cached.value;
|
|
286
|
-
applyUpdateResult(cachedUpdate);
|
|
287
|
-
return;
|
|
288
|
-
}
|
|
289
|
-
const result = updater(currentState);
|
|
290
|
-
cache.set(key, {
|
|
291
|
-
value: result,
|
|
292
|
-
deps: [currentState],
|
|
293
|
-
timestamp: Date.now(),
|
|
294
|
-
hitCount: 1
|
|
295
|
-
});
|
|
296
|
-
applyUpdateResult(result);
|
|
297
|
-
};
|
|
298
|
-
const memoizeResultCache = createMemoCacheStore(MAX_CACHE_SIZE, true);
|
|
299
|
-
tree.memoize = (fn, cacheKey) => {
|
|
300
|
-
return computed(() => {
|
|
301
|
-
const currentState = originalTreeCall();
|
|
302
|
-
const key = cacheKey || generateCacheKey(fn, [currentState]);
|
|
303
|
-
const cached = memoizeResultCache.get(key);
|
|
304
|
-
if (cached && equalityFn(cached.deps, [currentState])) {
|
|
305
|
-
return cached.value;
|
|
306
|
-
}
|
|
307
|
-
if (isDevMode() && tree.__devHooks?.onRecompute) {
|
|
308
|
-
try {
|
|
309
|
-
tree.__devHooks.onRecompute(key, 1);
|
|
310
|
-
} catch {}
|
|
311
|
-
}
|
|
312
|
-
const result = fn(currentState);
|
|
313
|
-
memoizeResultCache.set(key, {
|
|
314
|
-
value: result,
|
|
315
|
-
deps: [currentState],
|
|
316
|
-
timestamp: Date.now(),
|
|
317
|
-
hitCount: 1
|
|
318
|
-
});
|
|
319
|
-
return result;
|
|
320
|
-
});
|
|
321
|
-
};
|
|
322
|
-
tree.clearMemoCache = key => {
|
|
323
|
-
if (key) {
|
|
324
|
-
cache.delete(key);
|
|
325
|
-
} else {
|
|
326
|
-
cache.clear();
|
|
327
|
-
}
|
|
328
|
-
};
|
|
329
|
-
tree.clearCache = tree.clearMemoCache;
|
|
330
|
-
tree.getCacheStats = () => {
|
|
331
|
-
let totalHits = 0;
|
|
332
|
-
let totalMisses = 0;
|
|
333
|
-
cache.forEach(entry => {
|
|
334
|
-
totalHits += entry.hitCount || 0;
|
|
335
|
-
totalMisses += Math.floor((entry.hitCount || 0) / 2);
|
|
336
|
-
});
|
|
337
|
-
const hitRate = totalHits + totalMisses > 0 ? totalHits / (totalHits + totalMisses) : 0;
|
|
338
|
-
return {
|
|
339
|
-
size: cache.size(),
|
|
340
|
-
hitRate,
|
|
341
|
-
totalHits,
|
|
342
|
-
totalMisses,
|
|
343
|
-
keys: Array.from(cache.keys())
|
|
344
|
-
};
|
|
345
|
-
};
|
|
346
|
-
const maybeInterval = getCleanupInterval(tree);
|
|
347
|
-
if (maybeInterval) {
|
|
348
|
-
const origClear = tree.clearMemoCache.bind(tree);
|
|
349
|
-
tree.clearMemoCache = key => {
|
|
350
|
-
origClear(key);
|
|
351
|
-
clearCleanupInterval(tree);
|
|
352
|
-
};
|
|
353
|
-
}
|
|
354
|
-
tree.clearCache = tree.clearMemoCache;
|
|
355
|
-
if (ttl) {
|
|
356
|
-
const cleanup = () => {
|
|
357
|
-
const now = Date.now();
|
|
358
|
-
cache.forEach((entry, key) => {
|
|
359
|
-
if (entry.timestamp && now - entry.timestamp > ttl) {
|
|
360
|
-
cache.delete(key);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
};
|
|
364
|
-
const intervalId = setInterval(cleanup, ttl);
|
|
365
|
-
setCleanupInterval(tree, intervalId);
|
|
366
|
-
}
|
|
367
|
-
return tree;
|
|
368
|
-
};
|
|
369
|
-
return enhancer;
|
|
370
|
-
}
|
|
371
|
-
function highPerformanceMemoization() {
|
|
372
|
-
return memoization({
|
|
373
|
-
enabled: true,
|
|
374
|
-
maxCacheSize: 10000,
|
|
375
|
-
ttl: 300000,
|
|
376
|
-
equality: 'shallow',
|
|
377
|
-
enableLRU: true
|
|
378
|
-
});
|
|
379
|
-
}
|
|
380
|
-
function lightweightMemoization() {
|
|
381
|
-
return memoization({
|
|
382
|
-
enabled: true,
|
|
383
|
-
maxCacheSize: 100,
|
|
384
|
-
ttl: undefined,
|
|
385
|
-
equality: 'reference',
|
|
386
|
-
enableLRU: false
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
function shallowMemoization() {
|
|
390
|
-
return memoization({
|
|
391
|
-
enabled: true,
|
|
392
|
-
maxCacheSize: 1000,
|
|
393
|
-
ttl: 60000,
|
|
394
|
-
equality: 'shallow',
|
|
395
|
-
enableLRU: true
|
|
396
|
-
});
|
|
397
|
-
}
|
|
398
|
-
function clearAllCaches() {
|
|
399
|
-
resetMemoizationCaches();
|
|
400
|
-
}
|
|
401
|
-
function getGlobalCacheStats() {
|
|
402
|
-
let totalSize = 0;
|
|
403
|
-
let totalHits = 0;
|
|
404
|
-
let treeCount = 0;
|
|
405
|
-
memoizationCache.forEach(cache => {
|
|
406
|
-
treeCount++;
|
|
407
|
-
totalSize += cache.size();
|
|
408
|
-
cache.forEach(entry => {
|
|
409
|
-
totalHits += entry.hitCount || 0;
|
|
410
|
-
});
|
|
411
|
-
});
|
|
412
|
-
return {
|
|
413
|
-
treeCount,
|
|
414
|
-
totalSize,
|
|
415
|
-
totalHits,
|
|
416
|
-
averageCacheSize: treeCount > 0 ? totalSize / treeCount : 0
|
|
417
|
-
};
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
export { MEMOIZATION_PRESETS, clearAllCaches, computedMemoization, deepStateMemoization, getGlobalCacheStats, highFrequencyMemoization, highPerformanceMemoization, lightweightMemoization, memoization, memoize, memoizeReference, memoizeShallow, selectorMemoization, shallowMemoization };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
const TREE_PRESETS = {};
|
|
2
|
-
function createPresetConfig(preset, overrides = {}) {
|
|
3
|
-
return {
|
|
4
|
-
...overrides
|
|
5
|
-
};
|
|
6
|
-
}
|
|
7
|
-
function validatePreset(preset) {
|
|
8
|
-
return typeof preset === 'string';
|
|
9
|
-
}
|
|
10
|
-
function getAvailablePresets() {
|
|
11
|
-
return Object.keys(TREE_PRESETS);
|
|
12
|
-
}
|
|
13
|
-
function combinePresets(presets, overrides = {}) {
|
|
14
|
-
let combined = {};
|
|
15
|
-
for (const p of presets) {
|
|
16
|
-
combined = {
|
|
17
|
-
...combined,
|
|
18
|
-
...TREE_PRESETS[p]
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
return {
|
|
22
|
-
...combined,
|
|
23
|
-
...overrides
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export { TREE_PRESETS, combinePresets, createPresetConfig, getAvailablePresets, validatePreset };
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { signal } from '@angular/core';
|
|
2
|
-
|
|
3
|
-
function createAsyncOperation(name, operation) {
|
|
4
|
-
return async tree => {
|
|
5
|
-
if (typeof tree['batchUpdate'] === 'function') {
|
|
6
|
-
const pendingPatch = {
|
|
7
|
-
[`${name}_PENDING`]: true
|
|
8
|
-
};
|
|
9
|
-
tree['batchUpdate'](() => pendingPatch);
|
|
10
|
-
} else if ('$' in tree) {
|
|
11
|
-
try {
|
|
12
|
-
tree['$'][`${name}_PENDING`]?.set?.(true);
|
|
13
|
-
} catch (e) {
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
try {
|
|
17
|
-
const result = await operation();
|
|
18
|
-
if (typeof tree['batchUpdate'] === 'function') {
|
|
19
|
-
const resultPatch = {
|
|
20
|
-
[`${name}_RESULT`]: result,
|
|
21
|
-
[`${name}_PENDING`]: false
|
|
22
|
-
};
|
|
23
|
-
tree['batchUpdate'](() => resultPatch);
|
|
24
|
-
} else if ('$' in tree) {
|
|
25
|
-
try {
|
|
26
|
-
tree['$'][`${name}_RESULT`]?.set?.(result);
|
|
27
|
-
tree['$'][`${name}_PENDING`]?.set?.(false);
|
|
28
|
-
} catch (e) {
|
|
29
|
-
void e;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return result;
|
|
33
|
-
} catch (error) {
|
|
34
|
-
if (typeof tree['batchUpdate'] === 'function') {
|
|
35
|
-
const errorPatch = {
|
|
36
|
-
[`${name}_ERROR`]: error,
|
|
37
|
-
[`${name}_PENDING`]: false
|
|
38
|
-
};
|
|
39
|
-
tree['batchUpdate'](() => errorPatch);
|
|
40
|
-
} else if ('$' in tree) {
|
|
41
|
-
try {
|
|
42
|
-
tree['$'][`${name}_ERROR`]?.set?.(error);
|
|
43
|
-
tree['$'][`${name}_PENDING`]?.set?.(false);
|
|
44
|
-
} catch (e) {
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
function trackAsync(operation) {
|
|
52
|
-
const pending = signal(false);
|
|
53
|
-
const error = signal(null);
|
|
54
|
-
const result = signal(null);
|
|
55
|
-
return {
|
|
56
|
-
pending: pending.asReadonly(),
|
|
57
|
-
error: error.asReadonly(),
|
|
58
|
-
result: result.asReadonly(),
|
|
59
|
-
execute: async () => {
|
|
60
|
-
pending.set(true);
|
|
61
|
-
error.set(null);
|
|
62
|
-
try {
|
|
63
|
-
const res = await operation();
|
|
64
|
-
result.set(res);
|
|
65
|
-
return res;
|
|
66
|
-
} catch (e) {
|
|
67
|
-
const err = e instanceof Error ? e : new Error(String(e));
|
|
68
|
-
error.set(err);
|
|
69
|
-
throw err;
|
|
70
|
-
} finally {
|
|
71
|
-
pending.set(false);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { createAsyncOperation, trackAsync };
|
package/dist/lib/presets.js
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import { signalTree } from './signal-tree.js';
|
|
2
|
-
import { effects } from '../enhancers/effects/effects.js';
|
|
3
|
-
import { batching } from '../enhancers/batching/batching.js';
|
|
4
|
-
import { memoization } from '../enhancers/memoization/memoization.js';
|
|
5
|
-
import { timeTravel } from '../enhancers/time-travel/time-travel.js';
|
|
6
|
-
import { devTools } from '../enhancers/devtools/devtools.js';
|
|
7
|
-
|
|
8
|
-
function createDevTree(initialState, config = {}) {
|
|
9
|
-
if (arguments.length === 0) {
|
|
10
|
-
const enhancer = tree => tree.with(effects()).with(batching()).with(memoization()).with(timeTravel()).with(devTools());
|
|
11
|
-
return {
|
|
12
|
-
enhancer
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const base = signalTree(initialState, config);
|
|
16
|
-
const enhanced = base.with(effects()).with(batching(config.batching)).with(memoization(config.memoization)).with(timeTravel(config.timeTravel)).with(devTools(config.devTools));
|
|
17
|
-
return enhanced;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export { createDevTree };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './memoization';
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import type { ISignalTree } from '../../lib/types';
|
|
2
|
-
export declare function cleanupMemoizationCache(): void;
|
|
3
|
-
import type { MemoizationConfig, MemoizationMethods } from '../../lib/types';
|
|
4
|
-
export declare function memoize<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn, keyFn?: (...args: TArgs) => string, config?: MemoizationConfig): (...args: TArgs) => TReturn;
|
|
5
|
-
export declare function memoizeShallow<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn, keyFn?: (...args: TArgs) => string): (...args: TArgs) => TReturn;
|
|
6
|
-
export declare function memoizeReference<TArgs extends unknown[], TReturn>(fn: (...args: TArgs) => TReturn, keyFn?: (...args: TArgs) => string): (...args: TArgs) => TReturn;
|
|
7
|
-
export declare const MEMOIZATION_PRESETS: {
|
|
8
|
-
readonly selector: {
|
|
9
|
-
readonly equality: "reference";
|
|
10
|
-
readonly maxCacheSize: 10;
|
|
11
|
-
readonly enableLRU: false;
|
|
12
|
-
readonly ttl: undefined;
|
|
13
|
-
};
|
|
14
|
-
readonly computed: {
|
|
15
|
-
readonly equality: "shallow";
|
|
16
|
-
readonly maxCacheSize: 100;
|
|
17
|
-
readonly enableLRU: false;
|
|
18
|
-
readonly ttl: undefined;
|
|
19
|
-
};
|
|
20
|
-
readonly deepState: {
|
|
21
|
-
readonly equality: "deep";
|
|
22
|
-
readonly maxCacheSize: 1000;
|
|
23
|
-
readonly enableLRU: true;
|
|
24
|
-
readonly ttl: number;
|
|
25
|
-
};
|
|
26
|
-
readonly highFrequency: {
|
|
27
|
-
readonly equality: "reference";
|
|
28
|
-
readonly maxCacheSize: 5;
|
|
29
|
-
readonly enableLRU: false;
|
|
30
|
-
readonly ttl: undefined;
|
|
31
|
-
};
|
|
32
|
-
};
|
|
33
|
-
export declare function selectorMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
34
|
-
export declare function computedMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
35
|
-
export declare function deepStateMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
36
|
-
export declare function highFrequencyMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
37
|
-
export declare const withMemoization: ((config?: MemoizationConfig) => <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>) & {
|
|
38
|
-
selector: typeof selectorMemoization;
|
|
39
|
-
computed: typeof computedMemoization;
|
|
40
|
-
deep: typeof deepStateMemoization;
|
|
41
|
-
fast: typeof highFrequencyMemoization;
|
|
42
|
-
};
|
|
43
|
-
export declare function memoization(config?: MemoizationConfig): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
44
|
-
export declare function enableMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
45
|
-
export declare function highPerformanceMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
46
|
-
export declare function lightweightMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
47
|
-
export declare function shallowMemoization(): <T>(tree: ISignalTree<T>) => ISignalTree<T> & MemoizationMethods<T>;
|
|
48
|
-
export declare function clearAllCaches(): void;
|
|
49
|
-
export declare function getGlobalCacheStats(): {
|
|
50
|
-
treeCount: number;
|
|
51
|
-
totalSize: number;
|
|
52
|
-
totalHits: number;
|
|
53
|
-
averageCacheSize: number;
|
|
54
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/presets';
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { createDevTree, createMinimalTree, createProdTree } from '../../../lib/presets';
|
|
2
|
-
import type { TreeConfig, TreePreset } from '../../../lib/types';
|
|
3
|
-
export declare const TREE_PRESETS: Record<TreePreset, Partial<TreeConfig>>;
|
|
4
|
-
export declare function createPresetConfig(preset: TreePreset, overrides?: Partial<TreeConfig>): TreeConfig;
|
|
5
|
-
export declare function validatePreset(preset: TreePreset): boolean;
|
|
6
|
-
export declare function getAvailablePresets(): TreePreset[];
|
|
7
|
-
export declare function combinePresets(presets: TreePreset[], overrides?: Partial<TreeConfig>): TreeConfig;
|
|
8
|
-
export { createDevTree, createProdTree, createMinimalTree };
|
package/src/lib/presets.d.ts
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import type { ISignalTree, TreeConfig, BatchingConfig, MemoizationConfig, TimeTravelConfig, DevToolsConfig, BatchingMethods, MemoizationMethods, TimeTravelMethods, DevToolsMethods, EffectsMethods, EntitiesEnabled } from './types';
|
|
2
|
-
export interface DevTreeConfig extends TreeConfig {
|
|
3
|
-
effects?: Record<string, never>;
|
|
4
|
-
batching?: BatchingConfig;
|
|
5
|
-
memoization?: MemoizationConfig;
|
|
6
|
-
timeTravel?: TimeTravelConfig;
|
|
7
|
-
devTools?: DevToolsConfig;
|
|
8
|
-
entities?: Record<string, never>;
|
|
9
|
-
}
|
|
10
|
-
export interface ProdTreeConfig extends TreeConfig {
|
|
11
|
-
effects?: Record<string, never>;
|
|
12
|
-
batching?: BatchingConfig;
|
|
13
|
-
memoization?: MemoizationConfig;
|
|
14
|
-
entities?: Record<string, never>;
|
|
15
|
-
}
|
|
16
|
-
export interface MinimalTreeConfig extends TreeConfig {
|
|
17
|
-
effects?: Record<string, never>;
|
|
18
|
-
}
|
|
19
|
-
export type FullSignalTree<T> = ISignalTree<T> & EffectsMethods<T> & BatchingMethods & MemoizationMethods<T> & EntitiesEnabled & TimeTravelMethods & DevToolsMethods;
|
|
20
|
-
export type ProdSignalTree<T> = ISignalTree<T> & EffectsMethods<T> & BatchingMethods & MemoizationMethods<T> & EntitiesEnabled;
|
|
21
|
-
export type MinimalSignalTree<T> = ISignalTree<T> & EffectsMethods<T>;
|
|
22
|
-
export declare function createDevTree<T extends object>(initialState: T, config?: DevTreeConfig): FullSignalTree<T>;
|
|
23
|
-
export declare function createDevTree(): {
|
|
24
|
-
enhancer: <T>(tree: ISignalTree<T>) => ISignalTree<T> & EffectsMethods<T> & BatchingMethods<T> & MemoizationMethods<T> & EntitiesEnabled & TimeTravelMethods<T> & DevToolsMethods;
|
|
25
|
-
};
|
|
26
|
-
export declare function createProdTree<T extends object>(initialState: T, config?: ProdTreeConfig): ProdSignalTree<T>;
|
|
27
|
-
export declare function createMinimalTree<T extends object>(initialState: T, config?: MinimalTreeConfig): MinimalSignalTree<T>;
|
|
28
|
-
export declare const devTree: typeof createDevTree;
|
|
29
|
-
export declare const prodTree: typeof createProdTree;
|
|
30
|
-
export declare const minimalTree: typeof createMinimalTree;
|
|
31
|
-
export declare function buildTree<T extends object>(initialState: T, config?: TreeConfig): {
|
|
32
|
-
add<R>(enhancer: (t: ISignalTree<T>) => R): any;
|
|
33
|
-
done(): ISignalTree<T>;
|
|
34
|
-
};
|