@signaltree/core 7.1.2 → 7.1.4

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 (99) hide show
  1. package/README.md +138 -6
  2. package/package.json +2 -2
  3. package/dist/constants.js +0 -6
  4. package/dist/deep-equal.js +0 -41
  5. package/dist/enhancers/batching/batching.js +0 -230
  6. package/dist/enhancers/devtools/devtools.js +0 -318
  7. package/dist/enhancers/effects/effects.js +0 -66
  8. package/dist/enhancers/entities/entities.js +0 -24
  9. package/dist/enhancers/index.js +0 -72
  10. package/dist/enhancers/memoization/memoization.js +0 -420
  11. package/dist/enhancers/presets/lib/presets.js +0 -27
  12. package/dist/enhancers/serialization/constants.js +0 -15
  13. package/dist/enhancers/serialization/serialization.js +0 -656
  14. package/dist/enhancers/time-travel/time-travel.js +0 -283
  15. package/dist/enhancers/time-travel/utils.js +0 -11
  16. package/dist/enhancers/utils/copy-tree-properties.js +0 -20
  17. package/dist/index.js +0 -25
  18. package/dist/is-built-in-object.js +0 -23
  19. package/dist/lib/async-helpers.js +0 -77
  20. package/dist/lib/constants.js +0 -56
  21. package/dist/lib/edit-session.js +0 -84
  22. package/dist/lib/entity-signal.js +0 -544
  23. package/dist/lib/internals/batch-scope.js +0 -8
  24. package/dist/lib/internals/materialize-markers.js +0 -72
  25. package/dist/lib/internals/merge-derived.js +0 -59
  26. package/dist/lib/markers/derived.js +0 -6
  27. package/dist/lib/markers/entity-map.js +0 -20
  28. package/dist/lib/markers/status.js +0 -71
  29. package/dist/lib/markers/stored.js +0 -111
  30. package/dist/lib/memory/memory-manager.js +0 -164
  31. package/dist/lib/path-notifier.js +0 -178
  32. package/dist/lib/presets.js +0 -21
  33. package/dist/lib/security/security-validator.js +0 -121
  34. package/dist/lib/signal-tree.js +0 -415
  35. package/dist/lib/types.js +0 -3
  36. package/dist/lib/utils.js +0 -264
  37. package/dist/lru-cache.js +0 -64
  38. package/dist/parse-path.js +0 -13
  39. package/src/enhancers/batching/batching.d.ts +0 -10
  40. package/src/enhancers/batching/batching.types.d.ts +0 -1
  41. package/src/enhancers/batching/index.d.ts +0 -1
  42. package/src/enhancers/batching/test-setup.d.ts +0 -3
  43. package/src/enhancers/devtools/devtools.d.ts +0 -68
  44. package/src/enhancers/devtools/devtools.types.d.ts +0 -1
  45. package/src/enhancers/devtools/index.d.ts +0 -1
  46. package/src/enhancers/devtools/test-setup.d.ts +0 -3
  47. package/src/enhancers/effects/effects.d.ts +0 -9
  48. package/src/enhancers/effects/effects.types.d.ts +0 -1
  49. package/src/enhancers/effects/index.d.ts +0 -1
  50. package/src/enhancers/entities/entities.d.ts +0 -11
  51. package/src/enhancers/entities/entities.types.d.ts +0 -1
  52. package/src/enhancers/entities/index.d.ts +0 -1
  53. package/src/enhancers/entities/test-setup.d.ts +0 -3
  54. package/src/enhancers/index.d.ts +0 -3
  55. package/src/enhancers/memoization/index.d.ts +0 -1
  56. package/src/enhancers/memoization/memoization.d.ts +0 -54
  57. package/src/enhancers/memoization/memoization.types.d.ts +0 -1
  58. package/src/enhancers/memoization/test-setup.d.ts +0 -3
  59. package/src/enhancers/presets/index.d.ts +0 -1
  60. package/src/enhancers/presets/lib/presets.d.ts +0 -8
  61. package/src/enhancers/serialization/constants.d.ts +0 -14
  62. package/src/enhancers/serialization/index.d.ts +0 -2
  63. package/src/enhancers/serialization/serialization.d.ts +0 -68
  64. package/src/enhancers/serialization/test-setup.d.ts +0 -3
  65. package/src/enhancers/test-helpers/types-equals.d.ts +0 -2
  66. package/src/enhancers/time-travel/index.d.ts +0 -1
  67. package/src/enhancers/time-travel/test-setup.d.ts +0 -3
  68. package/src/enhancers/time-travel/time-travel.d.ts +0 -10
  69. package/src/enhancers/time-travel/time-travel.types.d.ts +0 -1
  70. package/src/enhancers/time-travel/utils.d.ts +0 -2
  71. package/src/enhancers/types.d.ts +0 -1
  72. package/src/enhancers/typing/helpers-types.d.ts +0 -2
  73. package/src/enhancers/utils/copy-tree-properties.d.ts +0 -1
  74. package/src/index.d.ts +0 -25
  75. package/src/lib/async-helpers.d.ts +0 -8
  76. package/src/lib/constants.d.ts +0 -41
  77. package/src/lib/dev-proxy.d.ts +0 -3
  78. package/src/lib/edit-session.d.ts +0 -21
  79. package/src/lib/entity-signal.d.ts +0 -1
  80. package/src/lib/internals/batch-scope.d.ts +0 -3
  81. package/src/lib/internals/builder-types.d.ts +0 -13
  82. package/src/lib/internals/derived-types.d.ts +0 -10
  83. package/src/lib/internals/materialize-markers.d.ts +0 -5
  84. package/src/lib/internals/merge-derived.d.ts +0 -4
  85. package/src/lib/markers/derived.d.ts +0 -9
  86. package/src/lib/markers/entity-map.d.ts +0 -4
  87. package/src/lib/markers/index.d.ts +0 -3
  88. package/src/lib/markers/status.d.ts +0 -32
  89. package/src/lib/markers/stored.d.ts +0 -23
  90. package/src/lib/memory/memory-manager.d.ts +0 -30
  91. package/src/lib/path-notifier.d.ts +0 -34
  92. package/src/lib/performance/diff-engine.d.ts +0 -33
  93. package/src/lib/performance/path-index.d.ts +0 -25
  94. package/src/lib/performance/update-engine.d.ts +0 -32
  95. package/src/lib/presets.d.ts +0 -34
  96. package/src/lib/security/security-validator.d.ts +0 -33
  97. package/src/lib/signal-tree.d.ts +0 -6
  98. package/src/lib/types.d.ts +0 -300
  99. package/src/lib/utils.d.ts +0 -25
@@ -1,318 +0,0 @@
1
- import { signal } from '@angular/core';
2
- import { copyTreeProperties } from '../utils/copy-tree-properties.js';
3
-
4
- function createActivityTracker() {
5
- const modules = new Map();
6
- return {
7
- trackMethodCall: (module, method, duration) => {
8
- const existing = modules.get(module);
9
- if (existing) {
10
- existing.lastActivity = new Date();
11
- existing.operationCount++;
12
- existing.averageExecutionTime = (existing.averageExecutionTime * (existing.operationCount - 1) + duration) / existing.operationCount;
13
- } else {
14
- modules.set(module, {
15
- name: module,
16
- methods: [method],
17
- addedAt: new Date(),
18
- lastActivity: new Date(),
19
- operationCount: 1,
20
- averageExecutionTime: duration,
21
- errorCount: 0
22
- });
23
- }
24
- },
25
- trackError: (module, error, context) => {
26
- const existing = modules.get(module);
27
- if (existing) {
28
- existing.errorCount++;
29
- }
30
- console.error(`❌ [${module}] Error${context ? ` in ${context}` : ''}:`, error);
31
- },
32
- getModuleActivity: module => modules.get(module),
33
- getAllModules: () => Array.from(modules.values())
34
- };
35
- }
36
- function createCompositionLogger() {
37
- const logs = [];
38
- const addLog = (module, type, data) => {
39
- logs.push({
40
- timestamp: new Date(),
41
- module,
42
- type,
43
- data
44
- });
45
- if (logs.length > 1000) {
46
- logs.splice(0, logs.length - 1000);
47
- }
48
- };
49
- return {
50
- logComposition: (modules, action) => {
51
- addLog('core', 'composition', {
52
- modules,
53
- action
54
- });
55
- console.log(`🔗 Composition ${action}:`, modules.join(' → '));
56
- },
57
- logMethodExecution: (module, method, args, result) => {
58
- addLog(module, 'method', {
59
- method,
60
- args,
61
- result
62
- });
63
- console.debug(`🔧 [${module}] ${method}`, {
64
- args,
65
- result
66
- });
67
- },
68
- logStateChange: (module, path, oldValue, newValue) => {
69
- addLog(module, 'state', {
70
- path,
71
- oldValue,
72
- newValue
73
- });
74
- console.debug(`📝 [${module}] State change at ${path}:`, {
75
- from: oldValue,
76
- to: newValue
77
- });
78
- },
79
- logPerformanceWarning: (module, operation, duration, threshold) => {
80
- addLog(module, 'performance', {
81
- operation,
82
- duration,
83
- threshold
84
- });
85
- console.warn(`⚠️ [${module}] Slow ${operation}: ${duration.toFixed(2)}ms (threshold: ${threshold}ms)`);
86
- },
87
- exportLogs: () => [...logs]
88
- };
89
- }
90
- function createNoopLogger() {
91
- return {
92
- logComposition: () => {},
93
- logMethodExecution: () => {},
94
- logStateChange: () => {},
95
- logPerformanceWarning: () => {},
96
- exportLogs: () => []
97
- };
98
- }
99
- function createModularMetrics() {
100
- const metricsSignal = signal({
101
- totalUpdates: 0,
102
- moduleUpdates: {},
103
- modulePerformance: {},
104
- compositionChain: [],
105
- signalGrowth: {},
106
- memoryDelta: {},
107
- moduleCacheStats: {}
108
- });
109
- return {
110
- signal: metricsSignal.asReadonly(),
111
- updateMetrics: updates => {
112
- metricsSignal.update(current => ({
113
- ...current,
114
- ...updates
115
- }));
116
- },
117
- trackModuleUpdate: (module, duration) => {
118
- metricsSignal.update(current => ({
119
- ...current,
120
- totalUpdates: current.totalUpdates + 1,
121
- moduleUpdates: {
122
- ...current.moduleUpdates,
123
- [module]: (current.moduleUpdates[module] || 0) + 1
124
- },
125
- modulePerformance: {
126
- ...current.modulePerformance,
127
- [module]: duration
128
- }
129
- }));
130
- }
131
- };
132
- }
133
- function devTools(config = {}) {
134
- const {
135
- enabled = true,
136
- treeName = 'SignalTree',
137
- name,
138
- enableBrowserDevTools = true,
139
- enableLogging = true,
140
- performanceThreshold = 16
141
- } = config;
142
- const displayName = name ?? treeName;
143
- return tree => {
144
- if (!enabled) {
145
- const noopMethods = {
146
- connectDevTools() {},
147
- disconnectDevTools() {}
148
- };
149
- return Object.assign(tree, noopMethods);
150
- }
151
- const activityTracker = createActivityTracker();
152
- const logger = enableLogging ? createCompositionLogger() : createNoopLogger();
153
- const metrics = createModularMetrics();
154
- const compositionHistory = [];
155
- const activeProfiles = new Map();
156
- let browserDevTools = null;
157
- const initBrowserDevTools = () => {
158
- if (!enableBrowserDevTools || typeof window === 'undefined' || !('__REDUX_DEVTOOLS_EXTENSION__' in window)) {
159
- return;
160
- }
161
- try {
162
- const devToolsExt = window['__REDUX_DEVTOOLS_EXTENSION__'];
163
- const connection = devToolsExt.connect({
164
- name: displayName,
165
- features: {
166
- dispatch: true,
167
- jump: true,
168
- skip: true
169
- }
170
- });
171
- browserDevTools = {
172
- send: connection.send
173
- };
174
- browserDevTools.send('@@INIT', tree());
175
- console.log(`🔗 Connected to Redux DevTools as "${displayName}"`);
176
- } catch (e) {
177
- console.warn('[SignalTree] Failed to connect to Redux DevTools:', e);
178
- }
179
- };
180
- const originalTreeCall = tree.bind(tree);
181
- const enhancedTree = function (...args) {
182
- if (args.length === 0) {
183
- return originalTreeCall();
184
- }
185
- const startTime = performance.now();
186
- let result;
187
- if (args.length === 1) {
188
- const arg = args[0];
189
- if (typeof arg === 'function') {
190
- result = originalTreeCall(arg);
191
- } else {
192
- result = originalTreeCall(arg);
193
- }
194
- }
195
- const duration = performance.now() - startTime;
196
- const newState = originalTreeCall();
197
- metrics.trackModuleUpdate('core', duration);
198
- if (duration > performanceThreshold) {
199
- logger.logPerformanceWarning('core', 'update', duration, performanceThreshold);
200
- }
201
- if (browserDevTools) {
202
- browserDevTools.send('UPDATE', newState);
203
- }
204
- return result;
205
- };
206
- Object.setPrototypeOf(enhancedTree, Object.getPrototypeOf(tree));
207
- copyTreeProperties(tree, enhancedTree);
208
- Object.defineProperty(enhancedTree, 'with', {
209
- value: function (enhancer) {
210
- if (typeof enhancer !== 'function') {
211
- throw new Error('Enhancer must be a function');
212
- }
213
- return enhancer(enhancedTree);
214
- },
215
- writable: false,
216
- enumerable: false,
217
- configurable: true
218
- });
219
- if ('state' in tree) {
220
- Object.defineProperty(enhancedTree, 'state', {
221
- value: tree.state,
222
- enumerable: false,
223
- configurable: true
224
- });
225
- }
226
- if ('$' in tree) {
227
- Object.defineProperty(enhancedTree, '$', {
228
- value: tree.$,
229
- enumerable: false,
230
- configurable: true
231
- });
232
- }
233
- const devToolsInterface = {
234
- activityTracker,
235
- logger,
236
- metrics: metrics.signal,
237
- trackComposition: modules => {
238
- compositionHistory.push({
239
- timestamp: new Date(),
240
- chain: [...modules]
241
- });
242
- metrics.updateMetrics({
243
- compositionChain: modules
244
- });
245
- logger.logComposition(modules, 'with');
246
- },
247
- startModuleProfiling: module => {
248
- const profileId = `${module}_${Date.now()}`;
249
- activeProfiles.set(profileId, {
250
- module,
251
- operation: 'profile',
252
- startTime: performance.now()
253
- });
254
- return profileId;
255
- },
256
- endModuleProfiling: profileId => {
257
- const profile = activeProfiles.get(profileId);
258
- if (profile) {
259
- const duration = performance.now() - profile.startTime;
260
- activityTracker.trackMethodCall(profile.module, profile.operation, duration);
261
- activeProfiles.delete(profileId);
262
- }
263
- },
264
- connectDevTools: name => {
265
- if (browserDevTools) {
266
- browserDevTools.send('@@INIT', originalTreeCall());
267
- console.log(`🔗 Connected to Redux DevTools as "${name}"`);
268
- }
269
- },
270
- exportDebugSession: () => ({
271
- metrics: metrics.signal(),
272
- modules: activityTracker.getAllModules(),
273
- logs: logger.exportLogs(),
274
- compositionHistory: [...compositionHistory]
275
- })
276
- };
277
- const methods = {
278
- connectDevTools() {
279
- initBrowserDevTools();
280
- },
281
- disconnectDevTools() {
282
- browserDevTools = null;
283
- }
284
- };
285
- enhancedTree['__devTools'] = devToolsInterface;
286
- return Object.assign(enhancedTree, methods);
287
- };
288
- }
289
- function enableDevTools(treeName = 'SignalTree') {
290
- return devTools({
291
- treeName,
292
- enabled: true
293
- });
294
- }
295
- function fullDevTools(treeName = 'SignalTree') {
296
- return devTools({
297
- treeName,
298
- enabled: true,
299
- enableBrowserDevTools: true,
300
- enableLogging: true,
301
- performanceThreshold: 10
302
- });
303
- }
304
- function productionDevTools() {
305
- return devTools({
306
- enabled: true,
307
- enableBrowserDevTools: false,
308
- enableLogging: false,
309
- performanceThreshold: 50
310
- });
311
- }
312
- Object.assign(devTools, {
313
- production: productionDevTools,
314
- full: fullDevTools,
315
- enable: enableDevTools
316
- });
317
-
318
- export { devTools, enableDevTools, fullDevTools, productionDevTools };
@@ -1,66 +0,0 @@
1
- import { effect, untracked } from '@angular/core';
2
-
3
- function effects(config = {}) {
4
- const {
5
- enabled = true
6
- } = config;
7
- return tree => {
8
- const cleanupFns = [];
9
- const methods = {
10
- effect(effectFn) {
11
- if (!enabled) {
12
- return () => {};
13
- }
14
- let innerCleanup;
15
- const effectRef = effect(() => {
16
- const state = tree();
17
- if (innerCleanup) {
18
- untracked(() => innerCleanup());
19
- }
20
- innerCleanup = untracked(() => effectFn(state));
21
- });
22
- const cleanup = () => {
23
- if (innerCleanup) {
24
- innerCleanup();
25
- }
26
- effectRef.destroy();
27
- };
28
- cleanupFns.push(cleanup);
29
- return cleanup;
30
- },
31
- subscribe(fn) {
32
- if (!enabled) {
33
- return () => {};
34
- }
35
- const effectRef = effect(() => {
36
- const state = tree();
37
- untracked(() => fn(state));
38
- });
39
- const cleanup = () => {
40
- effectRef.destroy();
41
- };
42
- cleanupFns.push(cleanup);
43
- return cleanup;
44
- }
45
- };
46
- const originalDestroy = tree.destroy?.bind(tree);
47
- tree.destroy = () => {
48
- cleanupFns.forEach(fn => fn());
49
- cleanupFns.length = 0;
50
- if (originalDestroy) {
51
- originalDestroy();
52
- }
53
- };
54
- return Object.assign(tree, methods);
55
- };
56
- }
57
- function enableEffects() {
58
- return effects({
59
- enabled: true
60
- });
61
- }
62
- Object.assign((config = {}) => effects(config), {
63
- enable: enableEffects
64
- });
65
-
66
- export { effects, enableEffects };
@@ -1,24 +0,0 @@
1
- function entities(config = {}) {
2
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
3
- console.warn('SignalTree: entities() enhancer is deprecated in v7. ' + 'EntityMap markers are now automatically processed. ' + 'Remove .with(entities()) from your code. ' + 'This enhancer will be removed in v8.');
4
- }
5
- const {
6
- enabled = true
7
- } = config;
8
- return tree => {
9
- tree.__entitiesEnabled = true;
10
- return tree;
11
- };
12
- }
13
- function enableEntities() {
14
- return entities();
15
- }
16
- function highPerformanceEntities() {
17
- return entities();
18
- }
19
- Object.assign(entities, {
20
- highPerformance: highPerformanceEntities,
21
- enable: enableEntities
22
- });
23
-
24
- export { enableEntities, entities, highPerformanceEntities };
@@ -1,72 +0,0 @@
1
- import { SIGNAL_TREE_MESSAGES } from '../lib/constants.js';
2
- import { ENHANCER_META } from '../lib/types.js';
3
-
4
- function createEnhancer(meta, enhancerFn) {
5
- const fn = enhancerFn;
6
- try {
7
- fn.metadata = meta;
8
- try {
9
- fn[ENHANCER_META] = meta;
10
- } catch {}
11
- } catch {}
12
- return fn;
13
- }
14
- function resolveEnhancerOrder(enhancers, availableCapabilities = new Set(), debugMode = false) {
15
- const nodes = enhancers.map((e, idx) => ({
16
- fn: e,
17
- name: e.metadata && e.metadata.name ? String(e.metadata.name) : `enhancer#${idx}`,
18
- requires: new Set(e.metadata?.requires ?? []),
19
- provides: new Set(e.metadata?.provides ?? [])
20
- }));
21
- const adj = new Map();
22
- const nameToNode = new Map();
23
- for (const n of nodes) {
24
- nameToNode.set(n.name, n);
25
- adj.set(n.name, new Set());
26
- }
27
- for (const a of nodes) {
28
- for (const b of nodes) {
29
- if (a === b) continue;
30
- for (const req of b.requires) {
31
- if (availableCapabilities.has(req)) continue;
32
- if (a.provides.has(req)) {
33
- const set = adj.get(a.name);
34
- if (set) set.add(b.name);
35
- }
36
- }
37
- }
38
- }
39
- const inDegree = new Map();
40
- for (const entry of adj.keys()) inDegree.set(entry, 0);
41
- for (const [, outs] of adj) {
42
- for (const to of outs) inDegree.set(to, (inDegree.get(to) || 0) + 1);
43
- }
44
- const queue = [];
45
- for (const [name, deg] of inDegree.entries()) {
46
- if (deg === 0) queue.push(name);
47
- }
48
- const ordered = [];
49
- while (queue.length > 0) {
50
- const n = queue.shift();
51
- if (!n) break;
52
- ordered.push(n);
53
- const outs = adj.get(n);
54
- if (!outs) continue;
55
- for (const m of outs) {
56
- inDegree.set(m, (inDegree.get(m) || 0) - 1);
57
- if (inDegree.get(m) === 0) queue.push(m);
58
- }
59
- }
60
- if (ordered.length !== nodes.length) {
61
- if (debugMode) {
62
- console.warn(SIGNAL_TREE_MESSAGES.ENHANCER_CYCLE_DETECTED);
63
- }
64
- return enhancers;
65
- }
66
- return ordered.map(name => {
67
- const n = nameToNode.get(name);
68
- return n ? n.fn : enhancers[0];
69
- });
70
- }
71
-
72
- export { createEnhancer, resolveEnhancerOrder };