@signaltree/core 5.1.6 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/package.json +1 -6
  2. package/dist/constants.js +0 -6
  3. package/dist/deep-clone.js +0 -80
  4. package/dist/deep-equal.js +0 -41
  5. package/dist/enhancers/batching/lib/batching.js +0 -161
  6. package/dist/enhancers/computed/lib/computed.js +0 -21
  7. package/dist/enhancers/devtools/lib/devtools.js +0 -321
  8. package/dist/enhancers/entities/lib/entities.js +0 -66
  9. package/dist/enhancers/index.js +0 -72
  10. package/dist/enhancers/memoization/lib/memoization.js +0 -410
  11. package/dist/enhancers/presets/lib/presets.js +0 -87
  12. package/dist/enhancers/serialization/constants.js +0 -15
  13. package/dist/enhancers/serialization/lib/serialization.js +0 -662
  14. package/dist/enhancers/time-travel/lib/time-travel.js +0 -193
  15. package/dist/index.js +0 -19
  16. package/dist/is-built-in-object.js +0 -23
  17. package/dist/lib/async-helpers.js +0 -77
  18. package/dist/lib/constants.js +0 -56
  19. package/dist/lib/entity-signal.js +0 -283
  20. package/dist/lib/memory/memory-manager.js +0 -164
  21. package/dist/lib/path-notifier.js +0 -106
  22. package/dist/lib/performance/diff-engine.js +0 -156
  23. package/dist/lib/performance/path-index.js +0 -156
  24. package/dist/lib/performance/update-engine.js +0 -188
  25. package/dist/lib/security/security-validator.js +0 -121
  26. package/dist/lib/signal-tree.js +0 -617
  27. package/dist/lib/types.js +0 -9
  28. package/dist/lib/utils.js +0 -261
  29. package/dist/lru-cache.js +0 -64
  30. package/dist/parse-path.js +0 -13
  31. package/src/async-helpers.d.ts +0 -8
  32. package/src/batching.d.ts +0 -16
  33. package/src/computed.d.ts +0 -12
  34. package/src/constants.d.ts +0 -14
  35. package/src/devtools.d.ts +0 -77
  36. package/src/diff-engine.d.ts +0 -33
  37. package/src/enhancers/batching/index.d.ts +0 -1
  38. package/src/enhancers/batching/lib/batching.d.ts +0 -16
  39. package/src/enhancers/batching/test-setup.d.ts +0 -3
  40. package/src/enhancers/computed/index.d.ts +0 -1
  41. package/src/enhancers/computed/lib/computed.d.ts +0 -12
  42. package/src/enhancers/devtools/index.d.ts +0 -1
  43. package/src/enhancers/devtools/lib/devtools.d.ts +0 -77
  44. package/src/enhancers/devtools/test-setup.d.ts +0 -3
  45. package/src/enhancers/entities/index.d.ts +0 -1
  46. package/src/enhancers/entities/lib/entities.d.ts +0 -17
  47. package/src/enhancers/entities/test-setup.d.ts +0 -3
  48. package/src/enhancers/index.d.ts +0 -3
  49. package/src/enhancers/memoization/index.d.ts +0 -1
  50. package/src/enhancers/memoization/lib/memoization.d.ts +0 -65
  51. package/src/enhancers/memoization/test-setup.d.ts +0 -3
  52. package/src/enhancers/presets/index.d.ts +0 -1
  53. package/src/enhancers/presets/lib/presets.d.ts +0 -11
  54. package/src/enhancers/presets/test-setup.d.ts +0 -3
  55. package/src/enhancers/serialization/constants.d.ts +0 -14
  56. package/src/enhancers/serialization/index.d.ts +0 -2
  57. package/src/enhancers/serialization/lib/serialization.d.ts +0 -59
  58. package/src/enhancers/serialization/test-setup.d.ts +0 -3
  59. package/src/enhancers/time-travel/index.d.ts +0 -1
  60. package/src/enhancers/time-travel/lib/time-travel.d.ts +0 -36
  61. package/src/enhancers/time-travel/lib/utils.d.ts +0 -1
  62. package/src/enhancers/time-travel/test-setup.d.ts +0 -3
  63. package/src/enhancers/types.d.ts +0 -74
  64. package/src/entities.d.ts +0 -28
  65. package/src/entity-signal.d.ts +0 -1
  66. package/src/index.d.ts +0 -18
  67. package/src/lib/async-helpers.d.ts +0 -8
  68. package/src/lib/constants.d.ts +0 -41
  69. package/src/lib/entity-signal.d.ts +0 -1
  70. package/src/lib/memory/memory-manager.d.ts +0 -30
  71. package/src/lib/path-notifier.d.ts +0 -4
  72. package/src/lib/performance/diff-engine.d.ts +0 -33
  73. package/src/lib/performance/path-index.d.ts +0 -25
  74. package/src/lib/performance/update-engine.d.ts +0 -32
  75. package/src/lib/security/security-validator.d.ts +0 -33
  76. package/src/lib/signal-tree.d.ts +0 -8
  77. package/src/lib/types.d.ts +0 -270
  78. package/src/lib/utils.d.ts +0 -28
  79. package/src/memoization.d.ts +0 -65
  80. package/src/memory-manager.d.ts +0 -30
  81. package/src/path-index.d.ts +0 -25
  82. package/src/path-notifier.d.ts +0 -12
  83. package/src/presets.d.ts +0 -11
  84. package/src/security-validator.d.ts +0 -33
  85. package/src/serialization.d.ts +0 -59
  86. package/src/signal-tree.d.ts +0 -8
  87. package/src/test-setup.d.ts +0 -3
  88. package/src/time-travel.d.ts +0 -36
  89. package/src/types.d.ts +0 -436
  90. package/src/update-engine.d.ts +0 -32
  91. package/src/utils.d.ts +0 -1
@@ -1,617 +0,0 @@
1
- import { signal, isSignal, computed, effect, inject, DestroyRef } from '@angular/core';
2
- import { resolveEnhancerOrder } from '../enhancers/index.js';
3
- import { SIGNAL_TREE_MESSAGES, SIGNAL_TREE_CONSTANTS } from './constants.js';
4
- import { SignalMemoryManager } from './memory/memory-manager.js';
5
- import { OptimizedUpdateEngine } from './performance/update-engine.js';
6
- import { SecurityValidator } from './security/security-validator.js';
7
- import { createLazySignalTree, unwrap } from './utils.js';
8
- import { deepEqual } from '../deep-equal.js';
9
- import { isBuiltInObject } from '../is-built-in-object.js';
10
-
11
- const NODE_ACCESSOR_SYMBOL = Symbol.for('NodeAccessor');
12
- function makeNodeAccessor() {
13
- const accessor = function (arg) {
14
- if (arguments.length === 0) {
15
- return unwrap(accessor);
16
- }
17
- if (typeof arg === 'function') {
18
- const updater = arg;
19
- const currentValue = unwrap(accessor);
20
- const newValue = updater(currentValue);
21
- recursiveUpdate(accessor, newValue);
22
- } else {
23
- recursiveUpdate(accessor, arg);
24
- }
25
- };
26
- accessor[NODE_ACCESSOR_SYMBOL] = true;
27
- return accessor;
28
- }
29
- function makeRootNodeAccessor(readSignal, writeSignal) {
30
- const accessor = function (arg) {
31
- if (arguments.length === 0) {
32
- return readSignal();
33
- }
34
- if (typeof arg === 'function') {
35
- const updater = arg;
36
- writeSignal.set(updater(readSignal()));
37
- } else {
38
- writeSignal.set(arg);
39
- }
40
- };
41
- accessor[NODE_ACCESSOR_SYMBOL] = true;
42
- return accessor;
43
- }
44
- function recursiveUpdate(target, updates) {
45
- if (!updates || typeof updates !== 'object') {
46
- return;
47
- }
48
- let targetObj;
49
- if (isNodeAccessor(target)) {
50
- targetObj = target;
51
- } else if (target && typeof target === 'object') {
52
- targetObj = target;
53
- } else {
54
- return;
55
- }
56
- const updatesObj = updates;
57
- for (const key in updatesObj) {
58
- if (!(key in targetObj)) {
59
- continue;
60
- }
61
- const targetProp = targetObj[key];
62
- const updateValue = updatesObj[key];
63
- if (isSignal(targetProp)) {
64
- if ('set' in targetProp && typeof targetProp.set === 'function') {
65
- targetProp.set(updateValue);
66
- }
67
- } else if (isNodeAccessor(targetProp)) {
68
- if (updateValue && typeof updateValue === 'object') {
69
- recursiveUpdate(targetProp, updateValue);
70
- } else {
71
- targetProp(updateValue);
72
- }
73
- }
74
- }
75
- }
76
- function isNodeAccessor(value) {
77
- return typeof value === 'function' && value && value[NODE_ACCESSOR_SYMBOL] === true;
78
- }
79
- function estimateObjectSize(obj, maxDepth = SIGNAL_TREE_CONSTANTS.ESTIMATE_MAX_DEPTH, currentDepth = 0) {
80
- if (currentDepth >= maxDepth) return 1;
81
- if (obj === null || obj === undefined) return 0;
82
- if (typeof obj !== 'object') return 1;
83
- let size = 0;
84
- try {
85
- if (Array.isArray(obj)) {
86
- size = obj.length;
87
- const sampleSize = Math.min(SIGNAL_TREE_CONSTANTS.ESTIMATE_SAMPLE_SIZE_ARRAY, obj.length);
88
- for (let i = 0; i < sampleSize; i++) {
89
- size += estimateObjectSize(obj[i], maxDepth, currentDepth + 1) * 0.1;
90
- }
91
- } else {
92
- const keys = Object.keys(obj);
93
- size = keys.length;
94
- const sampleSize = Math.min(SIGNAL_TREE_CONSTANTS.ESTIMATE_SAMPLE_SIZE_OBJECT, keys.length);
95
- for (let i = 0; i < sampleSize; i++) {
96
- const value = obj[keys[i]];
97
- size += estimateObjectSize(value, maxDepth, currentDepth + 1) * 0.5;
98
- }
99
- }
100
- } catch {
101
- return 1;
102
- }
103
- return Math.floor(size);
104
- }
105
- function shouldUseLazy(obj, config, precomputedSize) {
106
- if (config.useLazySignals !== undefined) return config.useLazySignals;
107
- if (config.debugMode || config.enableDevTools) return false;
108
- if (config.batchUpdates && config.useMemoization) return true;
109
- const estimatedSize = precomputedSize ?? estimateObjectSize(obj);
110
- return estimatedSize > SIGNAL_TREE_CONSTANTS.LAZY_THRESHOLD;
111
- }
112
- function validateTree(obj, config, path = []) {
113
- if (!config.security) {
114
- return;
115
- }
116
- const validator = new SecurityValidator(config.security);
117
- function validate(value, currentPath) {
118
- if (value === null || value === undefined) {
119
- return;
120
- }
121
- if (typeof value !== 'object') {
122
- validator.validateValue(value);
123
- return;
124
- }
125
- if (isBuiltInObject(value)) {
126
- return;
127
- }
128
- if (Array.isArray(value)) {
129
- value.forEach((item, index) => {
130
- validate(item, [...currentPath, String(index)]);
131
- });
132
- return;
133
- }
134
- const keys = [...Object.keys(value), ...Object.getOwnPropertyNames(value)];
135
- const uniqueKeys = [...new Set(keys)];
136
- for (const key of uniqueKeys) {
137
- if (typeof key === 'symbol') continue;
138
- try {
139
- validator.validateKey(key);
140
- } catch (error) {
141
- const err = error;
142
- throw new Error(`${err.message}\nPath: ${[...currentPath, key].join('.')}`);
143
- }
144
- const val = value[key];
145
- try {
146
- validator.validateValue(val);
147
- } catch (error) {
148
- const err = error;
149
- throw new Error(`${err.message}\nPath: ${[...currentPath, key].join('.')}`);
150
- }
151
- validate(val, [...currentPath, key]);
152
- }
153
- }
154
- validate(obj, path);
155
- }
156
- function createEqualityFn(useShallowComparison) {
157
- return useShallowComparison ? Object.is : deepEqual;
158
- }
159
- function createSignalStore(obj, equalityFn) {
160
- if (obj === null || obj === undefined || typeof obj !== 'object') {
161
- return signal(obj, {
162
- equal: equalityFn
163
- });
164
- }
165
- if (Array.isArray(obj)) {
166
- return signal(obj, {
167
- equal: equalityFn
168
- });
169
- }
170
- if (isBuiltInObject(obj)) {
171
- return signal(obj, {
172
- equal: equalityFn
173
- });
174
- }
175
- const store = {};
176
- const processedObjects = new WeakSet();
177
- if (processedObjects.has(obj)) {
178
- console.warn(SIGNAL_TREE_MESSAGES.CIRCULAR_REF);
179
- return signal(obj, {
180
- equal: equalityFn
181
- });
182
- }
183
- processedObjects.add(obj);
184
- try {
185
- for (const [key, value] of Object.entries(obj)) {
186
- try {
187
- if (typeof key === 'symbol') continue;
188
- if (isEntityMapMarker(value)) {
189
- store[key] = value;
190
- continue;
191
- }
192
- if (isSignal(value)) {
193
- store[key] = value;
194
- continue;
195
- }
196
- if (value === null || value === undefined) {
197
- store[key] = signal(value, {
198
- equal: equalityFn
199
- });
200
- } else if (typeof value !== 'object') {
201
- store[key] = signal(value, {
202
- equal: equalityFn
203
- });
204
- } else if (Array.isArray(value) || isBuiltInObject(value)) {
205
- store[key] = signal(value, {
206
- equal: equalityFn
207
- });
208
- } else {
209
- const branch = createSignalStore(value, equalityFn);
210
- const callableBranch = makeNodeAccessor();
211
- for (const branchKey in branch) {
212
- if (Object.prototype.hasOwnProperty.call(branch, branchKey)) {
213
- try {
214
- Object.defineProperty(callableBranch, branchKey, {
215
- value: branch[branchKey],
216
- enumerable: true,
217
- configurable: true
218
- });
219
- } catch {}
220
- }
221
- }
222
- store[key] = callableBranch;
223
- }
224
- } catch (error) {
225
- console.warn(`${SIGNAL_TREE_MESSAGES.SIGNAL_CREATION_FAILED} "${key}":`, error);
226
- store[key] = signal(value, {
227
- equal: equalityFn
228
- });
229
- }
230
- }
231
- const symbols = Object.getOwnPropertySymbols(obj);
232
- for (const sym of symbols) {
233
- const value = obj[sym];
234
- try {
235
- if (isEntityMapMarker(value)) {
236
- store[sym] = value;
237
- continue;
238
- }
239
- if (isSignal(value)) {
240
- store[sym] = value;
241
- } else {
242
- store[sym] = signal(value, {
243
- equal: equalityFn
244
- });
245
- }
246
- } catch (error) {
247
- console.warn(SIGNAL_TREE_MESSAGES.SIGNAL_CREATION_FAILED, error);
248
- }
249
- }
250
- } catch (error) {
251
- throw new Error(`Failed to create signal store: ${error instanceof Error ? error.message : 'Unknown error'}`);
252
- }
253
- return store;
254
- }
255
- function isEntityMapMarker(value) {
256
- return Boolean(value && typeof value === 'object' && value['__isEntityMap'] === true);
257
- }
258
- function enhanceTree(tree, config = {}) {
259
- const isLazy = config.useLazySignals ?? shouldUseLazy(tree.state, config);
260
- tree.with = (...enhancers) => {
261
- if (enhancers.length === 0) {
262
- return tree;
263
- }
264
- const coreCapabilities = new Set();
265
- if (config.batchUpdates) coreCapabilities.add('batchUpdate');
266
- if (config.useMemoization) coreCapabilities.add('memoize');
267
- if (config.enableTimeTravel) coreCapabilities.add('undo');
268
- if (config.enableDevTools) coreCapabilities.add('connectDevTools');
269
- try {
270
- for (const key of Object.keys(tree)) coreCapabilities.add(String(key));
271
- } catch {}
272
- const hasMetadata = enhancers.some(e => Boolean(e.metadata && (e.metadata.requires || e.metadata.provides)));
273
- let orderedEnhancers = enhancers;
274
- if (hasMetadata) {
275
- try {
276
- orderedEnhancers = resolveEnhancerOrder(enhancers, coreCapabilities, config.debugMode);
277
- } catch (err) {
278
- console.warn(SIGNAL_TREE_MESSAGES.ENHANCER_ORDER_FAILED, err);
279
- }
280
- }
281
- const provided = new Set(coreCapabilities);
282
- let currentTree = tree;
283
- for (let i = 0; i < orderedEnhancers.length; i++) {
284
- const enhancer = orderedEnhancers[i];
285
- if (typeof enhancer !== 'function') {
286
- throw new Error(SIGNAL_TREE_MESSAGES.ENHANCER_NOT_FUNCTION.replace('%d', String(i)));
287
- }
288
- const reqs = enhancer.metadata?.requires ?? [];
289
- for (const r of reqs) {
290
- if (!(r in currentTree) && !provided.has(r)) {
291
- const name = enhancer.metadata?.name ?? `enhancer#${i}`;
292
- const msg = SIGNAL_TREE_MESSAGES.ENHANCER_REQUIREMENT_MISSING.replace('%s', name).replace('%s', r);
293
- if (config.debugMode) {
294
- throw new Error(msg);
295
- } else {
296
- console.warn(msg);
297
- }
298
- }
299
- }
300
- try {
301
- const result = enhancer(currentTree);
302
- if (result !== currentTree) currentTree = result;
303
- const provs = enhancer.metadata?.provides ?? [];
304
- for (const p of provs) provided.add(p);
305
- if (config.debugMode && provs.length > 0) {
306
- for (const p of provs) {
307
- if (!(p in currentTree)) {
308
- console.warn(SIGNAL_TREE_MESSAGES.ENHANCER_PROVIDES_MISSING.replace('%s', enhancer.metadata?.name ?? String(i)).replace('%s', p));
309
- }
310
- }
311
- }
312
- } catch (error) {
313
- const name = enhancer.metadata?.name || `enhancer at index ${i}`;
314
- console.error(SIGNAL_TREE_MESSAGES.ENHANCER_FAILED.replace('%s', name), error);
315
- if (config.debugMode) {
316
- console.error('[SignalTree] Enhancer stack trace:', enhancer);
317
- console.error('[SignalTree] Tree state at failure:', currentTree);
318
- }
319
- throw error;
320
- }
321
- }
322
- return currentTree;
323
- };
324
- tree.destroy = () => {
325
- try {
326
- if (isLazy) {
327
- const state = tree.state;
328
- if (state && typeof state === 'object' && '__cleanup__' in state) {
329
- const cleanup = state.__cleanup__;
330
- if (typeof cleanup === 'function') {
331
- cleanup();
332
- }
333
- }
334
- }
335
- if (config.debugMode) {
336
- console.log(SIGNAL_TREE_MESSAGES.TREE_DESTROYED);
337
- }
338
- } catch (error) {
339
- console.error(SIGNAL_TREE_MESSAGES.CLEANUP_ERROR, error);
340
- }
341
- };
342
- addStubMethods(tree, config);
343
- return tree;
344
- }
345
- function addStubMethods(tree, config) {
346
- tree.batchUpdate = updater => {
347
- console.warn(SIGNAL_TREE_MESSAGES.BATCH_NOT_ENABLED);
348
- tree(current => {
349
- const partial = updater(current);
350
- return {
351
- ...current,
352
- ...partial
353
- };
354
- });
355
- };
356
- tree.memoize = (fn, cacheKey) => {
357
- console.warn(SIGNAL_TREE_MESSAGES.MEMOIZE_NOT_ENABLED);
358
- return computed(() => fn(tree()));
359
- };
360
- tree.memoizedUpdate = updater => {
361
- if (config.debugMode) {
362
- console.warn(SIGNAL_TREE_MESSAGES.MEMOIZE_NOT_ENABLED);
363
- }
364
- tree(current => ({
365
- ...current,
366
- ...updater(current)
367
- }));
368
- };
369
- tree.clearMemoCache = () => {
370
- if (config.debugMode) {
371
- console.warn(SIGNAL_TREE_MESSAGES.MEMOIZE_NOT_ENABLED);
372
- }
373
- };
374
- tree.getCacheStats = () => ({
375
- size: 0,
376
- hitRate: 0,
377
- totalHits: 0,
378
- totalMisses: 0,
379
- keys: []
380
- });
381
- tree.effect = fn => {
382
- try {
383
- effect(() => fn(tree()));
384
- } catch (error) {
385
- if (config.debugMode) {
386
- console.warn(SIGNAL_TREE_MESSAGES.EFFECT_NO_CONTEXT, error);
387
- }
388
- }
389
- };
390
- tree.subscribe = fn => {
391
- try {
392
- const destroyRef = inject(DestroyRef);
393
- let isDestroyed = false;
394
- const effectRef = effect(() => {
395
- if (!isDestroyed) {
396
- fn(tree());
397
- }
398
- });
399
- const unsubscribe = () => {
400
- isDestroyed = true;
401
- effectRef.destroy();
402
- };
403
- destroyRef.onDestroy(unsubscribe);
404
- return unsubscribe;
405
- } catch (error) {
406
- if (config.debugMode) {
407
- console.warn(SIGNAL_TREE_MESSAGES.SUBSCRIBE_NO_CONTEXT, error);
408
- }
409
- throw error;
410
- }
411
- };
412
- tree.optimize = () => {
413
- if (config.debugMode) {
414
- console.warn(SIGNAL_TREE_MESSAGES.OPTIMIZE_NOT_AVAILABLE);
415
- }
416
- };
417
- tree.clearCache = () => {
418
- if (config.debugMode) {
419
- console.warn(SIGNAL_TREE_MESSAGES.CACHE_NOT_AVAILABLE);
420
- }
421
- };
422
- tree.invalidatePattern = () => {
423
- if (config.debugMode) {
424
- console.warn(SIGNAL_TREE_MESSAGES.PERFORMANCE_NOT_ENABLED);
425
- }
426
- return 0;
427
- };
428
- const treeWithEngine = tree;
429
- if (!treeWithEngine.updateEngine) {
430
- treeWithEngine.updateEngine = new OptimizedUpdateEngine(tree);
431
- }
432
- tree.updateOptimized = (updates, options = {}) => {
433
- const treeWithEngine = tree;
434
- const engine = treeWithEngine.updateEngine;
435
- if (!engine) {
436
- if (config.debugMode) {
437
- console.warn(SIGNAL_TREE_MESSAGES.UPDATE_OPTIMIZED_NOT_AVAILABLE);
438
- }
439
- tree(current => ({
440
- ...current,
441
- ...updates
442
- }));
443
- return {
444
- changed: true,
445
- duration: 0,
446
- changedPaths: Object.keys(updates),
447
- stats: undefined
448
- };
449
- }
450
- return engine.update(tree(), updates, options);
451
- };
452
- tree.entities = () => {
453
- console.warn('[@signaltree/core] tree.entities() is deprecated and will be removed in v6.0. ' + 'Use entityMap<E>() + withEntities() + tree.$.collectionName instead. ' + 'See https://signaltree.dev/docs/migration for migration guide.');
454
- if (config.debugMode) {
455
- console.warn(SIGNAL_TREE_MESSAGES.ENTITY_HELPERS_NOT_AVAILABLE);
456
- }
457
- return {};
458
- };
459
- tree.undo = () => {
460
- if (config.debugMode) {
461
- console.warn(SIGNAL_TREE_MESSAGES.TIME_TRAVEL_NOT_AVAILABLE);
462
- }
463
- };
464
- tree.redo = () => {
465
- if (config.debugMode) {
466
- console.warn(SIGNAL_TREE_MESSAGES.TIME_TRAVEL_NOT_AVAILABLE);
467
- }
468
- };
469
- tree.getHistory = () => {
470
- if (config.debugMode) {
471
- console.warn(SIGNAL_TREE_MESSAGES.TIME_TRAVEL_NOT_AVAILABLE);
472
- }
473
- return [];
474
- };
475
- tree.resetHistory = () => {
476
- if (config.debugMode) {
477
- console.warn(SIGNAL_TREE_MESSAGES.TIME_TRAVEL_NOT_AVAILABLE);
478
- }
479
- };
480
- }
481
- function create(obj, config = {}) {
482
- if (obj === null || obj === undefined) {
483
- throw new Error(SIGNAL_TREE_MESSAGES.NULL_OR_UNDEFINED);
484
- }
485
- validateTree(obj, config);
486
- const estimatedSize = estimateObjectSize(obj);
487
- const equalityFn = createEqualityFn(config.useShallowComparison ?? false);
488
- if (Array.isArray(obj)) {
489
- const signalState = signal(obj, {
490
- equal: equalityFn
491
- });
492
- const tree = makeRootNodeAccessor(signalState, signalState);
493
- Object.defineProperty(tree, 'state', {
494
- value: signalState,
495
- enumerable: false
496
- });
497
- Object.defineProperty(tree, '$', {
498
- value: signalState,
499
- enumerable: false
500
- });
501
- enhanceTree(tree, config);
502
- return tree;
503
- }
504
- const useLazy = shouldUseLazy(obj, config, estimatedSize);
505
- if (config.debugMode) {
506
- console.log(SIGNAL_TREE_MESSAGES.STRATEGY_SELECTION.replace('%s', useLazy ? 'lazy' : 'eager').replace('%d', String(estimatedSize)));
507
- }
508
- let signalState;
509
- let memoryManager;
510
- try {
511
- if (useLazy && typeof obj === 'object') {
512
- memoryManager = new SignalMemoryManager();
513
- signalState = createLazySignalTree(obj, equalityFn, '', memoryManager);
514
- } else {
515
- signalState = createSignalStore(obj, equalityFn);
516
- }
517
- } catch (error) {
518
- if (useLazy) {
519
- console.warn(SIGNAL_TREE_MESSAGES.LAZY_FALLBACK, error);
520
- signalState = createSignalStore(obj, equalityFn);
521
- memoryManager = undefined;
522
- } else {
523
- throw error;
524
- }
525
- }
526
- const tree = function (arg) {
527
- if (arguments.length === 0) {
528
- return unwrap(signalState);
529
- }
530
- if (typeof arg === 'function') {
531
- const updater = arg;
532
- const currentValue = unwrap(signalState);
533
- const newValue = updater(currentValue);
534
- recursiveUpdate(signalState, newValue);
535
- } else {
536
- recursiveUpdate(signalState, arg);
537
- }
538
- };
539
- Object.defineProperty(tree, NODE_ACCESSOR_SYMBOL, {
540
- value: true,
541
- enumerable: false
542
- });
543
- Object.defineProperty(tree, 'state', {
544
- value: signalState,
545
- enumerable: false
546
- });
547
- Object.defineProperty(tree, '$', {
548
- value: signalState,
549
- enumerable: false
550
- });
551
- if (memoryManager) {
552
- Object.defineProperty(tree, 'dispose', {
553
- value: () => {
554
- memoryManager?.dispose();
555
- const cleanup = signalState.__cleanup__;
556
- if (typeof cleanup === 'function') {
557
- cleanup();
558
- }
559
- },
560
- enumerable: false,
561
- writable: false
562
- });
563
- }
564
- enhanceTree(tree, config);
565
- for (const key in signalState) {
566
- if (Object.prototype.hasOwnProperty.call(signalState, key)) {
567
- if (!(key in tree)) {
568
- try {
569
- Object.defineProperty(tree, key, {
570
- value: signalState[key],
571
- enumerable: true,
572
- configurable: true
573
- });
574
- } catch {}
575
- }
576
- }
577
- }
578
- return tree;
579
- }
580
- const presetConfigs = {
581
- basic: {
582
- useLazySignals: false,
583
- debugMode: false
584
- },
585
- performance: {
586
- useLazySignals: true,
587
- batchUpdates: true,
588
- useMemoization: true,
589
- useShallowComparison: true
590
- },
591
- development: {
592
- useLazySignals: false,
593
- debugMode: true,
594
- enableDevTools: true,
595
- trackPerformance: true
596
- },
597
- production: {
598
- useLazySignals: true,
599
- batchUpdates: true,
600
- useMemoization: true,
601
- debugMode: false
602
- }
603
- };
604
- function signalTree(obj, configOrPreset) {
605
- if (typeof configOrPreset === 'string') {
606
- const config = presetConfigs[configOrPreset];
607
- if (!config) {
608
- console.warn(SIGNAL_TREE_MESSAGES.PRESET_UNKNOWN.replace('%s', configOrPreset));
609
- return create(obj, {});
610
- }
611
- return create(obj, config);
612
- }
613
- const config = configOrPreset || {};
614
- return create(obj, config);
615
- }
616
-
617
- export { isNodeAccessor, signalTree };
package/dist/lib/types.js DELETED
@@ -1,9 +0,0 @@
1
- const ENHANCER_META = Symbol('signaltree:enhancer:meta');
2
- function entityMap(config) {
3
- return {
4
- __isEntityMap: true,
5
- __entityMapConfig: config ?? {}
6
- };
7
- }
8
-
9
- export { ENHANCER_META, entityMap };