@signaltree/core 4.0.15 → 4.1.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 (109) hide show
  1. package/README.md +106 -38
  2. package/dist/constants.js +6 -0
  3. package/dist/deep-clone.js +80 -0
  4. package/dist/deep-equal.js +41 -0
  5. package/dist/enhancers/batching/lib/batching.js +141 -135
  6. package/dist/enhancers/computed/lib/computed.js +18 -16
  7. package/dist/enhancers/devtools/lib/devtools.js +303 -260
  8. package/dist/enhancers/entities/lib/entities.js +109 -104
  9. package/dist/enhancers/index.js +65 -77
  10. package/dist/enhancers/memoization/lib/memoization.js +339 -351
  11. package/dist/enhancers/middleware/lib/async-helpers.js +71 -79
  12. package/dist/enhancers/middleware/lib/middleware.js +126 -169
  13. package/dist/enhancers/presets/lib/presets.js +82 -71
  14. package/dist/enhancers/serialization/constants.js +14 -13
  15. package/dist/enhancers/serialization/lib/serialization.js +615 -623
  16. package/dist/enhancers/time-travel/lib/time-travel.js +178 -177
  17. package/dist/index.d.ts +1 -17
  18. package/dist/index.js +19 -16
  19. package/dist/is-built-in-object.js +23 -0
  20. package/dist/lib/constants.js +51 -55
  21. package/dist/lib/memory/memory-manager.js +152 -154
  22. package/dist/lib/performance/diff-engine.js +141 -141
  23. package/dist/lib/performance/path-index.js +139 -137
  24. package/dist/lib/performance/update-engine.js +171 -176
  25. package/dist/lib/security/security-validator.js +110 -128
  26. package/dist/lib/signal-tree.js +577 -611
  27. package/dist/lib/types.js +3 -9
  28. package/dist/lib/utils.js +236 -268
  29. package/dist/lru-cache.js +64 -0
  30. package/dist/parse-path.js +13 -0
  31. package/package.json +30 -16
  32. package/src/index.d.ts +17 -0
  33. package/{dist → src}/lib/utils.d.ts +1 -0
  34. package/dist/enhancers/batching/index.js +0 -1
  35. package/dist/enhancers/batching/jest.config.js +0 -21
  36. package/dist/enhancers/batching/test-setup.js +0 -5
  37. package/dist/enhancers/computed/index.js +0 -1
  38. package/dist/enhancers/computed/jest.config.js +0 -21
  39. package/dist/enhancers/devtools/index.js +0 -1
  40. package/dist/enhancers/devtools/jest.config.js +0 -21
  41. package/dist/enhancers/devtools/test-setup.js +0 -5
  42. package/dist/enhancers/entities/index.js +0 -1
  43. package/dist/enhancers/entities/jest.config.js +0 -21
  44. package/dist/enhancers/entities/test-setup.js +0 -5
  45. package/dist/enhancers/memoization/index.js +0 -1
  46. package/dist/enhancers/memoization/jest.config.js +0 -21
  47. package/dist/enhancers/memoization/test-setup.js +0 -5
  48. package/dist/enhancers/middleware/index.js +0 -2
  49. package/dist/enhancers/middleware/jest.config.js +0 -21
  50. package/dist/enhancers/middleware/test-setup.js +0 -5
  51. package/dist/enhancers/presets/index.js +0 -1
  52. package/dist/enhancers/presets/jest.config.js +0 -21
  53. package/dist/enhancers/presets/test-setup.js +0 -5
  54. package/dist/enhancers/serialization/index.js +0 -2
  55. package/dist/enhancers/serialization/jest.config.js +0 -21
  56. package/dist/enhancers/serialization/test-setup.js +0 -5
  57. package/dist/enhancers/time-travel/index.js +0 -1
  58. package/dist/enhancers/time-travel/jest.config.js +0 -21
  59. package/dist/enhancers/time-travel/lib/utils.js +0 -1
  60. package/dist/enhancers/time-travel/test-setup.js +0 -5
  61. package/dist/enhancers/types.js +0 -0
  62. /package/{dist → src}/enhancers/batching/index.d.ts +0 -0
  63. /package/{dist → src}/enhancers/batching/jest.config.d.ts +0 -0
  64. /package/{dist → src}/enhancers/batching/lib/batching.d.ts +0 -0
  65. /package/{dist → src}/enhancers/batching/test-setup.d.ts +0 -0
  66. /package/{dist → src}/enhancers/computed/index.d.ts +0 -0
  67. /package/{dist → src}/enhancers/computed/jest.config.d.ts +0 -0
  68. /package/{dist → src}/enhancers/computed/lib/computed.d.ts +0 -0
  69. /package/{dist → src}/enhancers/devtools/index.d.ts +0 -0
  70. /package/{dist → src}/enhancers/devtools/jest.config.d.ts +0 -0
  71. /package/{dist → src}/enhancers/devtools/lib/devtools.d.ts +0 -0
  72. /package/{dist → src}/enhancers/devtools/test-setup.d.ts +0 -0
  73. /package/{dist → src}/enhancers/entities/index.d.ts +0 -0
  74. /package/{dist → src}/enhancers/entities/jest.config.d.ts +0 -0
  75. /package/{dist → src}/enhancers/entities/lib/entities.d.ts +0 -0
  76. /package/{dist → src}/enhancers/entities/test-setup.d.ts +0 -0
  77. /package/{dist → src}/enhancers/index.d.ts +0 -0
  78. /package/{dist → src}/enhancers/memoization/index.d.ts +0 -0
  79. /package/{dist → src}/enhancers/memoization/jest.config.d.ts +0 -0
  80. /package/{dist → src}/enhancers/memoization/lib/memoization.d.ts +0 -0
  81. /package/{dist → src}/enhancers/memoization/test-setup.d.ts +0 -0
  82. /package/{dist → src}/enhancers/middleware/index.d.ts +0 -0
  83. /package/{dist → src}/enhancers/middleware/jest.config.d.ts +0 -0
  84. /package/{dist → src}/enhancers/middleware/lib/async-helpers.d.ts +0 -0
  85. /package/{dist → src}/enhancers/middleware/lib/middleware.d.ts +0 -0
  86. /package/{dist → src}/enhancers/middleware/test-setup.d.ts +0 -0
  87. /package/{dist → src}/enhancers/presets/index.d.ts +0 -0
  88. /package/{dist → src}/enhancers/presets/jest.config.d.ts +0 -0
  89. /package/{dist → src}/enhancers/presets/lib/presets.d.ts +0 -0
  90. /package/{dist → src}/enhancers/presets/test-setup.d.ts +0 -0
  91. /package/{dist → src}/enhancers/serialization/constants.d.ts +0 -0
  92. /package/{dist → src}/enhancers/serialization/index.d.ts +0 -0
  93. /package/{dist → src}/enhancers/serialization/jest.config.d.ts +0 -0
  94. /package/{dist → src}/enhancers/serialization/lib/serialization.d.ts +0 -0
  95. /package/{dist → src}/enhancers/serialization/test-setup.d.ts +0 -0
  96. /package/{dist → src}/enhancers/time-travel/index.d.ts +0 -0
  97. /package/{dist → src}/enhancers/time-travel/jest.config.d.ts +0 -0
  98. /package/{dist → src}/enhancers/time-travel/lib/time-travel.d.ts +0 -0
  99. /package/{dist → src}/enhancers/time-travel/lib/utils.d.ts +0 -0
  100. /package/{dist → src}/enhancers/time-travel/test-setup.d.ts +0 -0
  101. /package/{dist → src}/enhancers/types.d.ts +0 -0
  102. /package/{dist → src}/lib/constants.d.ts +0 -0
  103. /package/{dist → src}/lib/memory/memory-manager.d.ts +0 -0
  104. /package/{dist → src}/lib/performance/diff-engine.d.ts +0 -0
  105. /package/{dist → src}/lib/performance/path-index.d.ts +0 -0
  106. /package/{dist → src}/lib/performance/update-engine.d.ts +0 -0
  107. /package/{dist → src}/lib/security/security-validator.d.ts +0 -0
  108. /package/{dist → src}/lib/signal-tree.d.ts +0 -0
  109. /package/{dist → src}/lib/types.d.ts +0 -0
@@ -1,278 +1,321 @@
1
1
  import { signal } from '@angular/core';
2
+
2
3
  function createActivityTracker() {
3
- const modules = new Map();
4
- return {
5
- trackMethodCall: (module, method, duration) => {
6
- const existing = modules.get(module);
7
- if (existing) {
8
- existing.lastActivity = new Date();
9
- existing.operationCount++;
10
- existing.averageExecutionTime =
11
- (existing.averageExecutionTime * (existing.operationCount - 1) +
12
- duration) /
13
- existing.operationCount;
14
- }
15
- else {
16
- modules.set(module, {
17
- name: module,
18
- methods: [method],
19
- addedAt: new Date(),
20
- lastActivity: new Date(),
21
- operationCount: 1,
22
- averageExecutionTime: duration,
23
- errorCount: 0,
24
- });
25
- }
26
- },
27
- trackError: (module, error, context) => {
28
- const existing = modules.get(module);
29
- if (existing) {
30
- existing.errorCount++;
31
- }
32
- console.error(`❌ [${module}] Error${context ? ` in ${context}` : ''}:`, error);
33
- },
34
- getModuleActivity: (module) => modules.get(module),
35
- getAllModules: () => Array.from(modules.values()),
36
- };
4
+ const modules = new Map();
5
+ return {
6
+ trackMethodCall: (module, method, duration) => {
7
+ const existing = modules.get(module);
8
+ if (existing) {
9
+ existing.lastActivity = new Date();
10
+ existing.operationCount++;
11
+ existing.averageExecutionTime = (existing.averageExecutionTime * (existing.operationCount - 1) + duration) / existing.operationCount;
12
+ } else {
13
+ modules.set(module, {
14
+ name: module,
15
+ methods: [method],
16
+ addedAt: new Date(),
17
+ lastActivity: new Date(),
18
+ operationCount: 1,
19
+ averageExecutionTime: duration,
20
+ errorCount: 0
21
+ });
22
+ }
23
+ },
24
+ trackError: (module, error, context) => {
25
+ const existing = modules.get(module);
26
+ if (existing) {
27
+ existing.errorCount++;
28
+ }
29
+ console.error(`❌ [${module}] Error${context ? ` in ${context}` : ''}:`, error);
30
+ },
31
+ getModuleActivity: module => modules.get(module),
32
+ getAllModules: () => Array.from(modules.values())
33
+ };
37
34
  }
38
35
  function createCompositionLogger() {
39
- const logs = [];
40
- const addLog = (module, type, data) => {
41
- logs.push({ timestamp: new Date(), module, type, data });
42
- if (logs.length > 1000) {
43
- logs.splice(0, logs.length - 1000);
44
- }
45
- };
46
- return {
47
- logComposition: (modules, action) => {
48
- addLog('core', 'composition', { modules, action });
49
- console.log(`🔗 Composition ${action}:`, modules.join(' → '));
50
- },
51
- logMethodExecution: (module, method, args, result) => {
52
- addLog(module, 'method', { method, args, result });
53
- console.debug(`🔧 [${module}] ${method}`, { args, result });
54
- },
55
- logStateChange: (module, path, oldValue, newValue) => {
56
- addLog(module, 'state', { path, oldValue, newValue });
57
- console.debug(`📝 [${module}] State change at ${path}:`, {
58
- from: oldValue,
59
- to: newValue,
60
- });
61
- },
62
- logPerformanceWarning: (module, operation, duration, threshold) => {
63
- addLog(module, 'performance', { operation, duration, threshold });
64
- console.warn(`⚠️ [${module}] Slow ${operation}: ${duration.toFixed(2)}ms (threshold: ${threshold}ms)`);
65
- },
66
- exportLogs: () => [...logs],
67
- };
36
+ const logs = [];
37
+ const addLog = (module, type, data) => {
38
+ logs.push({
39
+ timestamp: new Date(),
40
+ module,
41
+ type,
42
+ data
43
+ });
44
+ if (logs.length > 1000) {
45
+ logs.splice(0, logs.length - 1000);
46
+ }
47
+ };
48
+ return {
49
+ logComposition: (modules, action) => {
50
+ addLog('core', 'composition', {
51
+ modules,
52
+ action
53
+ });
54
+ console.log(`🔗 Composition ${action}:`, modules.join(' '));
55
+ },
56
+ logMethodExecution: (module, method, args, result) => {
57
+ addLog(module, 'method', {
58
+ method,
59
+ args,
60
+ result
61
+ });
62
+ console.debug(`🔧 [${module}] ${method}`, {
63
+ args,
64
+ result
65
+ });
66
+ },
67
+ logStateChange: (module, path, oldValue, newValue) => {
68
+ addLog(module, 'state', {
69
+ path,
70
+ oldValue,
71
+ newValue
72
+ });
73
+ console.debug(`📝 [${module}] State change at ${path}:`, {
74
+ from: oldValue,
75
+ to: newValue
76
+ });
77
+ },
78
+ logPerformanceWarning: (module, operation, duration, threshold) => {
79
+ addLog(module, 'performance', {
80
+ operation,
81
+ duration,
82
+ threshold
83
+ });
84
+ console.warn(`⚠️ [${module}] Slow ${operation}: ${duration.toFixed(2)}ms (threshold: ${threshold}ms)`);
85
+ },
86
+ exportLogs: () => [...logs]
87
+ };
68
88
  }
69
89
  function createModularMetrics() {
70
- const metricsSignal = signal({
71
- totalUpdates: 0,
72
- moduleUpdates: {},
73
- modulePerformance: {},
74
- compositionChain: [],
75
- signalGrowth: {},
76
- memoryDelta: {},
77
- moduleCacheStats: {},
78
- });
79
- return {
80
- signal: metricsSignal.asReadonly(),
81
- updateMetrics: (updates) => {
82
- metricsSignal.update((current) => ({ ...current, ...updates }));
90
+ const metricsSignal = signal({
91
+ totalUpdates: 0,
92
+ moduleUpdates: {},
93
+ modulePerformance: {},
94
+ compositionChain: [],
95
+ signalGrowth: {},
96
+ memoryDelta: {},
97
+ moduleCacheStats: {}
98
+ });
99
+ return {
100
+ signal: metricsSignal.asReadonly(),
101
+ updateMetrics: updates => {
102
+ metricsSignal.update(current => ({
103
+ ...current,
104
+ ...updates
105
+ }));
106
+ },
107
+ trackModuleUpdate: (module, duration) => {
108
+ metricsSignal.update(current => ({
109
+ ...current,
110
+ totalUpdates: current.totalUpdates + 1,
111
+ moduleUpdates: {
112
+ ...current.moduleUpdates,
113
+ [module]: (current.moduleUpdates[module] || 0) + 1
114
+ },
115
+ modulePerformance: {
116
+ ...current.modulePerformance,
117
+ [module]: duration
118
+ }
119
+ }));
120
+ }
121
+ };
122
+ }
123
+ function withDevTools(config = {}) {
124
+ const {
125
+ enabled = true,
126
+ treeName = 'ModularSignalTree',
127
+ enableBrowserDevTools = true,
128
+ enableLogging = true,
129
+ performanceThreshold = 16
130
+ } = config;
131
+ return tree => {
132
+ if (!enabled) {
133
+ const createNoopInterface = () => ({
134
+ activityTracker: {
135
+ trackMethodCall: () => undefined,
136
+ trackError: () => undefined,
137
+ getModuleActivity: () => undefined,
138
+ getAllModules: () => []
83
139
  },
84
- trackModuleUpdate: (module, duration) => {
85
- metricsSignal.update((current) => ({
86
- ...current,
87
- totalUpdates: current.totalUpdates + 1,
88
- moduleUpdates: {
89
- ...current.moduleUpdates,
90
- [module]: (current.moduleUpdates[module] || 0) + 1,
91
- },
92
- modulePerformance: {
93
- ...current.modulePerformance,
94
- [module]: duration,
95
- },
96
- }));
140
+ logger: {
141
+ logComposition: () => undefined,
142
+ logMethodExecution: () => undefined,
143
+ logStateChange: () => undefined,
144
+ logPerformanceWarning: () => undefined,
145
+ exportLogs: () => []
97
146
  },
147
+ metrics: signal({
148
+ totalUpdates: 0,
149
+ moduleUpdates: {},
150
+ modulePerformance: {},
151
+ compositionChain: [],
152
+ signalGrowth: {},
153
+ memoryDelta: {},
154
+ moduleCacheStats: {}
155
+ }).asReadonly(),
156
+ trackComposition: () => undefined,
157
+ startModuleProfiling: () => '',
158
+ endModuleProfiling: () => undefined,
159
+ connectDevTools: () => undefined,
160
+ exportDebugSession: () => ({
161
+ metrics: {
162
+ totalUpdates: 0,
163
+ moduleUpdates: {},
164
+ modulePerformance: {},
165
+ compositionChain: [],
166
+ signalGrowth: {},
167
+ memoryDelta: {},
168
+ moduleCacheStats: {}
169
+ },
170
+ modules: [],
171
+ logs: [],
172
+ compositionHistory: []
173
+ })
174
+ });
175
+ return Object.assign(tree, {
176
+ __devTools: createNoopInterface()
177
+ });
178
+ }
179
+ const activityTracker = createActivityTracker();
180
+ const logger = enableLogging ? createCompositionLogger() : {
181
+ logComposition: () => undefined,
182
+ logMethodExecution: () => undefined,
183
+ logStateChange: () => undefined,
184
+ logPerformanceWarning: () => undefined,
185
+ exportLogs: () => []
98
186
  };
99
- }
100
- export function withDevTools(config = {}) {
101
- const { enabled = true, treeName = 'ModularSignalTree', enableBrowserDevTools = true, enableLogging = true, performanceThreshold = 16, } = config;
102
- return (tree) => {
103
- if (!enabled) {
104
- const createNoopInterface = () => ({
105
- activityTracker: {
106
- trackMethodCall: () => undefined,
107
- trackError: () => undefined,
108
- getModuleActivity: () => undefined,
109
- getAllModules: () => [],
110
- },
111
- logger: {
112
- logComposition: () => undefined,
113
- logMethodExecution: () => undefined,
114
- logStateChange: () => undefined,
115
- logPerformanceWarning: () => undefined,
116
- exportLogs: () => [],
117
- },
118
- metrics: signal({
119
- totalUpdates: 0,
120
- moduleUpdates: {},
121
- modulePerformance: {},
122
- compositionChain: [],
123
- signalGrowth: {},
124
- memoryDelta: {},
125
- moduleCacheStats: {},
126
- }).asReadonly(),
127
- trackComposition: () => undefined,
128
- startModuleProfiling: () => '',
129
- endModuleProfiling: () => undefined,
130
- connectDevTools: () => undefined,
131
- exportDebugSession: () => ({
132
- metrics: {
133
- totalUpdates: 0,
134
- moduleUpdates: {},
135
- modulePerformance: {},
136
- compositionChain: [],
137
- signalGrowth: {},
138
- memoryDelta: {},
139
- moduleCacheStats: {},
140
- },
141
- modules: [],
142
- logs: [],
143
- compositionHistory: [],
144
- }),
145
- });
146
- return Object.assign(tree, { __devTools: createNoopInterface() });
187
+ const metrics = createModularMetrics();
188
+ const compositionHistory = [];
189
+ const activeProfiles = new Map();
190
+ let browserDevTools = null;
191
+ if (enableBrowserDevTools && typeof window !== 'undefined' && '__REDUX_DEVTOOLS_EXTENSION__' in window) {
192
+ const devToolsExt = window['__REDUX_DEVTOOLS_EXTENSION__'];
193
+ const connection = devToolsExt.connect({
194
+ name: treeName,
195
+ features: {
196
+ dispatch: true,
197
+ jump: true,
198
+ skip: true
147
199
  }
148
- const activityTracker = createActivityTracker();
149
- const logger = enableLogging
150
- ? createCompositionLogger()
151
- : {
152
- logComposition: () => undefined,
153
- logMethodExecution: () => undefined,
154
- logStateChange: () => undefined,
155
- logPerformanceWarning: () => undefined,
156
- exportLogs: () => [],
157
- };
158
- const metrics = createModularMetrics();
159
- const compositionHistory = [];
160
- const activeProfiles = new Map();
161
- let browserDevTools = null;
162
- if (enableBrowserDevTools &&
163
- typeof window !== 'undefined' &&
164
- '__REDUX_DEVTOOLS_EXTENSION__' in window) {
165
- const devToolsExt = window['__REDUX_DEVTOOLS_EXTENSION__'];
166
- const connection = devToolsExt.connect({
167
- name: treeName,
168
- features: { dispatch: true, jump: true, skip: true },
169
- });
170
- browserDevTools = { send: connection.send };
200
+ });
201
+ browserDevTools = {
202
+ send: connection.send
203
+ };
204
+ }
205
+ const originalTreeCall = tree.bind(tree);
206
+ const enhancedTree = function (...args) {
207
+ if (args.length === 0) {
208
+ return originalTreeCall();
209
+ } else {
210
+ const startTime = performance.now();
211
+ let result;
212
+ if (args.length === 1) {
213
+ const arg = args[0];
214
+ if (typeof arg === 'function') {
215
+ result = originalTreeCall(arg);
216
+ } else {
217
+ result = originalTreeCall(arg);
218
+ }
171
219
  }
172
- const originalTreeCall = tree.bind(tree);
173
- const enhancedTree = function (...args) {
174
- if (args.length === 0) {
175
- return originalTreeCall();
176
- }
177
- else {
178
- const startTime = performance.now();
179
- let result;
180
- if (args.length === 1) {
181
- const arg = args[0];
182
- if (typeof arg === 'function') {
183
- result = originalTreeCall(arg);
184
- }
185
- else {
186
- result = originalTreeCall(arg);
187
- }
188
- }
189
- const duration = performance.now() - startTime;
190
- const newState = originalTreeCall();
191
- metrics.trackModuleUpdate('core', duration);
192
- if (duration > performanceThreshold) {
193
- logger.logPerformanceWarning('core', 'update', duration, performanceThreshold);
194
- }
195
- if (browserDevTools) {
196
- browserDevTools.send('UPDATE', newState);
197
- }
198
- return result;
199
- }
200
- };
201
- Object.setPrototypeOf(enhancedTree, Object.getPrototypeOf(tree));
202
- Object.assign(enhancedTree, tree);
203
- if ('state' in tree) {
204
- Object.defineProperty(enhancedTree, 'state', {
205
- value: tree.state,
206
- enumerable: false,
207
- configurable: true,
208
- });
220
+ const duration = performance.now() - startTime;
221
+ const newState = originalTreeCall();
222
+ metrics.trackModuleUpdate('core', duration);
223
+ if (duration > performanceThreshold) {
224
+ logger.logPerformanceWarning('core', 'update', duration, performanceThreshold);
209
225
  }
210
- if ('$' in tree) {
211
- Object.defineProperty(enhancedTree, '$', {
212
- value: tree['$'],
213
- enumerable: false,
214
- configurable: true,
215
- });
226
+ if (browserDevTools) {
227
+ browserDevTools.send('UPDATE', newState);
216
228
  }
217
- const devToolsInterface = {
218
- activityTracker,
219
- logger,
220
- metrics: metrics.signal,
221
- trackComposition: (modules) => {
222
- compositionHistory.push({ timestamp: new Date(), chain: [...modules] });
223
- metrics.updateMetrics({ compositionChain: modules });
224
- logger.logComposition(modules, 'with');
225
- },
226
- startModuleProfiling: (module) => {
227
- const profileId = `${module}_${Date.now()}`;
228
- activeProfiles.set(profileId, {
229
- module,
230
- operation: 'profile',
231
- startTime: performance.now(),
232
- });
233
- return profileId;
234
- },
235
- endModuleProfiling: (profileId) => {
236
- const profile = activeProfiles.get(profileId);
237
- if (profile) {
238
- const duration = performance.now() - profile.startTime;
239
- activityTracker.trackMethodCall(profile.module, profile.operation, duration);
240
- activeProfiles.delete(profileId);
241
- }
242
- },
243
- connectDevTools: (name) => {
244
- if (browserDevTools) {
245
- browserDevTools.send('@@INIT', originalTreeCall());
246
- console.log(`🔗 Connected to Redux DevTools as "${name}"`);
247
- }
248
- },
249
- exportDebugSession: () => ({
250
- metrics: metrics.signal(),
251
- modules: activityTracker.getAllModules(),
252
- logs: logger.exportLogs(),
253
- compositionHistory: [...compositionHistory],
254
- }),
255
- };
256
- return Object.assign(enhancedTree, { __devTools: devToolsInterface });
229
+ return result;
230
+ }
257
231
  };
232
+ Object.setPrototypeOf(enhancedTree, Object.getPrototypeOf(tree));
233
+ Object.assign(enhancedTree, tree);
234
+ if ('state' in tree) {
235
+ Object.defineProperty(enhancedTree, 'state', {
236
+ value: tree.state,
237
+ enumerable: false,
238
+ configurable: true
239
+ });
240
+ }
241
+ if ('$' in tree) {
242
+ Object.defineProperty(enhancedTree, '$', {
243
+ value: tree['$'],
244
+ enumerable: false,
245
+ configurable: true
246
+ });
247
+ }
248
+ const devToolsInterface = {
249
+ activityTracker,
250
+ logger,
251
+ metrics: metrics.signal,
252
+ trackComposition: modules => {
253
+ compositionHistory.push({
254
+ timestamp: new Date(),
255
+ chain: [...modules]
256
+ });
257
+ metrics.updateMetrics({
258
+ compositionChain: modules
259
+ });
260
+ logger.logComposition(modules, 'with');
261
+ },
262
+ startModuleProfiling: module => {
263
+ const profileId = `${module}_${Date.now()}`;
264
+ activeProfiles.set(profileId, {
265
+ module,
266
+ operation: 'profile',
267
+ startTime: performance.now()
268
+ });
269
+ return profileId;
270
+ },
271
+ endModuleProfiling: profileId => {
272
+ const profile = activeProfiles.get(profileId);
273
+ if (profile) {
274
+ const duration = performance.now() - profile.startTime;
275
+ activityTracker.trackMethodCall(profile.module, profile.operation, duration);
276
+ activeProfiles.delete(profileId);
277
+ }
278
+ },
279
+ connectDevTools: name => {
280
+ if (browserDevTools) {
281
+ browserDevTools.send('@@INIT', originalTreeCall());
282
+ console.log(`🔗 Connected to Redux DevTools as "${name}"`);
283
+ }
284
+ },
285
+ exportDebugSession: () => ({
286
+ metrics: metrics.signal(),
287
+ modules: activityTracker.getAllModules(),
288
+ logs: logger.exportLogs(),
289
+ compositionHistory: [...compositionHistory]
290
+ })
291
+ };
292
+ return Object.assign(enhancedTree, {
293
+ __devTools: devToolsInterface
294
+ });
295
+ };
258
296
  }
259
- export function enableDevTools(treeName = 'SignalTree') {
260
- return withDevTools({ treeName, enabled: true });
297
+ function enableDevTools(treeName = 'SignalTree') {
298
+ return withDevTools({
299
+ treeName,
300
+ enabled: true
301
+ });
261
302
  }
262
- export function withFullDevTools(treeName = 'SignalTree') {
263
- return withDevTools({
264
- treeName,
265
- enabled: true,
266
- enableBrowserDevTools: true,
267
- enableLogging: true,
268
- performanceThreshold: 10,
269
- });
303
+ function withFullDevTools(treeName = 'SignalTree') {
304
+ return withDevTools({
305
+ treeName,
306
+ enabled: true,
307
+ enableBrowserDevTools: true,
308
+ enableLogging: true,
309
+ performanceThreshold: 10
310
+ });
270
311
  }
271
- export function withProductionDevTools() {
272
- return withDevTools({
273
- enabled: true,
274
- enableBrowserDevTools: false,
275
- enableLogging: false,
276
- performanceThreshold: 50,
277
- });
312
+ function withProductionDevTools() {
313
+ return withDevTools({
314
+ enabled: true,
315
+ enableBrowserDevTools: false,
316
+ enableLogging: false,
317
+ performanceThreshold: 50
318
+ });
278
319
  }
320
+
321
+ export { enableDevTools, withDevTools, withFullDevTools, withProductionDevTools };