@signaltree/core 4.0.15 → 4.0.16
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 +79 -38
- package/package.json +1 -1
- package/dist/enhancers/batching/index.d.ts +0 -1
- package/dist/enhancers/batching/index.js +0 -1
- package/dist/enhancers/batching/jest.config.d.ts +0 -15
- package/dist/enhancers/batching/jest.config.js +0 -21
- package/dist/enhancers/batching/lib/batching.d.ts +0 -16
- package/dist/enhancers/batching/lib/batching.js +0 -155
- package/dist/enhancers/batching/test-setup.d.ts +0 -1
- package/dist/enhancers/batching/test-setup.js +0 -5
- package/dist/enhancers/computed/index.d.ts +0 -1
- package/dist/enhancers/computed/index.js +0 -1
- package/dist/enhancers/computed/jest.config.d.ts +0 -15
- package/dist/enhancers/computed/jest.config.js +0 -21
- package/dist/enhancers/computed/lib/computed.d.ts +0 -12
- package/dist/enhancers/computed/lib/computed.js +0 -19
- package/dist/enhancers/devtools/index.d.ts +0 -1
- package/dist/enhancers/devtools/index.js +0 -1
- package/dist/enhancers/devtools/jest.config.d.ts +0 -15
- package/dist/enhancers/devtools/jest.config.js +0 -21
- package/dist/enhancers/devtools/lib/devtools.d.ts +0 -77
- package/dist/enhancers/devtools/lib/devtools.js +0 -278
- package/dist/enhancers/devtools/test-setup.d.ts +0 -1
- package/dist/enhancers/devtools/test-setup.js +0 -5
- package/dist/enhancers/entities/index.d.ts +0 -1
- package/dist/enhancers/entities/index.js +0 -1
- package/dist/enhancers/entities/jest.config.d.ts +0 -15
- package/dist/enhancers/entities/jest.config.js +0 -21
- package/dist/enhancers/entities/lib/entities.d.ts +0 -22
- package/dist/enhancers/entities/lib/entities.js +0 -110
- package/dist/enhancers/entities/test-setup.d.ts +0 -1
- package/dist/enhancers/entities/test-setup.js +0 -5
- package/dist/enhancers/index.d.ts +0 -3
- package/dist/enhancers/index.js +0 -84
- package/dist/enhancers/memoization/index.d.ts +0 -1
- package/dist/enhancers/memoization/index.js +0 -1
- package/dist/enhancers/memoization/jest.config.d.ts +0 -15
- package/dist/enhancers/memoization/jest.config.js +0 -21
- package/dist/enhancers/memoization/lib/memoization.d.ts +0 -65
- package/dist/enhancers/memoization/lib/memoization.js +0 -391
- package/dist/enhancers/memoization/test-setup.d.ts +0 -1
- package/dist/enhancers/memoization/test-setup.js +0 -5
- package/dist/enhancers/middleware/index.d.ts +0 -2
- package/dist/enhancers/middleware/index.js +0 -2
- package/dist/enhancers/middleware/jest.config.d.ts +0 -15
- package/dist/enhancers/middleware/jest.config.js +0 -21
- package/dist/enhancers/middleware/lib/async-helpers.d.ts +0 -8
- package/dist/enhancers/middleware/lib/async-helpers.js +0 -85
- package/dist/enhancers/middleware/lib/middleware.d.ts +0 -11
- package/dist/enhancers/middleware/lib/middleware.js +0 -179
- package/dist/enhancers/middleware/test-setup.d.ts +0 -1
- package/dist/enhancers/middleware/test-setup.js +0 -5
- package/dist/enhancers/presets/index.d.ts +0 -1
- package/dist/enhancers/presets/index.js +0 -1
- package/dist/enhancers/presets/jest.config.d.ts +0 -15
- package/dist/enhancers/presets/jest.config.js +0 -21
- package/dist/enhancers/presets/lib/presets.d.ts +0 -11
- package/dist/enhancers/presets/lib/presets.js +0 -77
- package/dist/enhancers/presets/test-setup.d.ts +0 -1
- package/dist/enhancers/presets/test-setup.js +0 -5
- package/dist/enhancers/serialization/constants.d.ts +0 -14
- package/dist/enhancers/serialization/constants.js +0 -14
- package/dist/enhancers/serialization/index.d.ts +0 -2
- package/dist/enhancers/serialization/index.js +0 -2
- package/dist/enhancers/serialization/jest.config.d.ts +0 -15
- package/dist/enhancers/serialization/jest.config.js +0 -21
- package/dist/enhancers/serialization/lib/serialization.d.ts +0 -59
- package/dist/enhancers/serialization/lib/serialization.js +0 -668
- package/dist/enhancers/serialization/test-setup.d.ts +0 -1
- package/dist/enhancers/serialization/test-setup.js +0 -5
- package/dist/enhancers/time-travel/index.d.ts +0 -1
- package/dist/enhancers/time-travel/index.js +0 -1
- package/dist/enhancers/time-travel/jest.config.d.ts +0 -15
- package/dist/enhancers/time-travel/jest.config.js +0 -21
- package/dist/enhancers/time-travel/lib/time-travel.d.ts +0 -36
- package/dist/enhancers/time-travel/lib/time-travel.js +0 -192
- package/dist/enhancers/time-travel/lib/utils.d.ts +0 -1
- package/dist/enhancers/time-travel/lib/utils.js +0 -1
- package/dist/enhancers/time-travel/test-setup.d.ts +0 -1
- package/dist/enhancers/time-travel/test-setup.js +0 -5
- package/dist/enhancers/types.d.ts +0 -105
- package/dist/enhancers/types.js +0 -0
- package/dist/index.d.ts +0 -17
- package/dist/index.js +0 -16
- package/dist/lib/constants.d.ts +0 -42
- package/dist/lib/constants.js +0 -61
- package/dist/lib/memory/memory-manager.d.ts +0 -30
- package/dist/lib/memory/memory-manager.js +0 -166
- package/dist/lib/performance/diff-engine.d.ts +0 -33
- package/dist/lib/performance/diff-engine.js +0 -156
- package/dist/lib/performance/path-index.d.ts +0 -25
- package/dist/lib/performance/path-index.js +0 -154
- package/dist/lib/performance/update-engine.d.ts +0 -32
- package/dist/lib/performance/update-engine.js +0 -193
- package/dist/lib/security/security-validator.d.ts +0 -33
- package/dist/lib/security/security-validator.js +0 -139
- package/dist/lib/signal-tree.d.ts +0 -8
- package/dist/lib/signal-tree.js +0 -665
- package/dist/lib/types.d.ts +0 -164
- package/dist/lib/types.js +0 -9
- package/dist/lib/utils.d.ts +0 -27
- package/dist/lib/utils.js +0 -286
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import { Signal } from '@angular/core';
|
|
2
|
-
import type { SignalTree } from '../../../lib/types';
|
|
3
|
-
export interface ModuleMetadata {
|
|
4
|
-
name: string;
|
|
5
|
-
methods: string[];
|
|
6
|
-
addedAt: Date;
|
|
7
|
-
lastActivity: Date;
|
|
8
|
-
operationCount: number;
|
|
9
|
-
averageExecutionTime: number;
|
|
10
|
-
errorCount: number;
|
|
11
|
-
}
|
|
12
|
-
export interface ModularPerformanceMetrics {
|
|
13
|
-
totalUpdates: number;
|
|
14
|
-
moduleUpdates: Record<string, number>;
|
|
15
|
-
modulePerformance: Record<string, number>;
|
|
16
|
-
compositionChain: string[];
|
|
17
|
-
signalGrowth: Record<string, number>;
|
|
18
|
-
memoryDelta: Record<string, number>;
|
|
19
|
-
moduleCacheStats: Record<string, {
|
|
20
|
-
hits: number;
|
|
21
|
-
misses: number;
|
|
22
|
-
}>;
|
|
23
|
-
}
|
|
24
|
-
export interface ModuleActivityTracker {
|
|
25
|
-
trackMethodCall: (module: string, method: string, duration: number) => void;
|
|
26
|
-
trackError: (module: string, error: Error, context?: string) => void;
|
|
27
|
-
getModuleActivity: (module: string) => ModuleMetadata | undefined;
|
|
28
|
-
getAllModules: () => ModuleMetadata[];
|
|
29
|
-
}
|
|
30
|
-
export interface CompositionLogger {
|
|
31
|
-
logComposition: (modules: string[], action: 'with' | 'enhance') => void;
|
|
32
|
-
logMethodExecution: (module: string, method: string, args: unknown[], result: unknown) => void;
|
|
33
|
-
logStateChange: (module: string, path: string, oldValue: unknown, newValue: unknown) => void;
|
|
34
|
-
logPerformanceWarning: (module: string, operation: string, duration: number, threshold: number) => void;
|
|
35
|
-
exportLogs: () => Array<{
|
|
36
|
-
timestamp: Date;
|
|
37
|
-
module: string;
|
|
38
|
-
type: 'composition' | 'method' | 'state' | 'performance';
|
|
39
|
-
data: unknown;
|
|
40
|
-
}>;
|
|
41
|
-
}
|
|
42
|
-
export interface ModularDevToolsInterface<T = unknown> {
|
|
43
|
-
activityTracker: ModuleActivityTracker;
|
|
44
|
-
logger: CompositionLogger;
|
|
45
|
-
metrics: Signal<ModularPerformanceMetrics>;
|
|
46
|
-
trackComposition: (modules: string[]) => void;
|
|
47
|
-
startModuleProfiling: (module: string) => string;
|
|
48
|
-
endModuleProfiling: (profileId: string) => void;
|
|
49
|
-
connectDevTools: (treeName: string) => void;
|
|
50
|
-
exportDebugSession: () => {
|
|
51
|
-
metrics: ModularPerformanceMetrics;
|
|
52
|
-
modules: ModuleMetadata[];
|
|
53
|
-
logs: Array<unknown>;
|
|
54
|
-
compositionHistory: Array<{
|
|
55
|
-
timestamp: Date;
|
|
56
|
-
chain: string[];
|
|
57
|
-
}>;
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
export declare function withDevTools<T>(config?: {
|
|
61
|
-
enabled?: boolean;
|
|
62
|
-
treeName?: string;
|
|
63
|
-
enableBrowserDevTools?: boolean;
|
|
64
|
-
enableLogging?: boolean;
|
|
65
|
-
performanceThreshold?: number;
|
|
66
|
-
}): (tree: SignalTree<T>) => SignalTree<T> & {
|
|
67
|
-
__devTools: ModularDevToolsInterface<T>;
|
|
68
|
-
};
|
|
69
|
-
export declare function enableDevTools<T>(treeName?: string): (tree: SignalTree<T>) => SignalTree<T> & {
|
|
70
|
-
__devTools: ModularDevToolsInterface<T>;
|
|
71
|
-
};
|
|
72
|
-
export declare function withFullDevTools<T>(treeName?: string): (tree: SignalTree<T>) => SignalTree<T> & {
|
|
73
|
-
__devTools: ModularDevToolsInterface<T>;
|
|
74
|
-
};
|
|
75
|
-
export declare function withProductionDevTools<T>(): (tree: SignalTree<T>) => SignalTree<T> & {
|
|
76
|
-
__devTools: ModularDevToolsInterface<T>;
|
|
77
|
-
};
|
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import { signal } from '@angular/core';
|
|
2
|
-
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
|
-
};
|
|
37
|
-
}
|
|
38
|
-
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
|
-
};
|
|
68
|
-
}
|
|
69
|
-
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 }));
|
|
83
|
-
},
|
|
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
|
-
}));
|
|
97
|
-
},
|
|
98
|
-
};
|
|
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() });
|
|
147
|
-
}
|
|
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 };
|
|
171
|
-
}
|
|
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
|
-
});
|
|
209
|
-
}
|
|
210
|
-
if ('$' in tree) {
|
|
211
|
-
Object.defineProperty(enhancedTree, '$', {
|
|
212
|
-
value: tree['$'],
|
|
213
|
-
enumerable: false,
|
|
214
|
-
configurable: true,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
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 });
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
export function enableDevTools(treeName = 'SignalTree') {
|
|
260
|
-
return withDevTools({ treeName, enabled: true });
|
|
261
|
-
}
|
|
262
|
-
export function withFullDevTools(treeName = 'SignalTree') {
|
|
263
|
-
return withDevTools({
|
|
264
|
-
treeName,
|
|
265
|
-
enabled: true,
|
|
266
|
-
enableBrowserDevTools: true,
|
|
267
|
-
enableLogging: true,
|
|
268
|
-
performanceThreshold: 10,
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
export function withProductionDevTools() {
|
|
272
|
-
return withDevTools({
|
|
273
|
-
enabled: true,
|
|
274
|
-
enableBrowserDevTools: false,
|
|
275
|
-
enableLogging: false,
|
|
276
|
-
performanceThreshold: 50,
|
|
277
|
-
});
|
|
278
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/entities';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/entities';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
displayName: string;
|
|
3
|
-
preset: string;
|
|
4
|
-
setupFilesAfterEnv: string[];
|
|
5
|
-
coverageDirectory: string;
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.(ts|mjs|js|html)$': (string | {
|
|
8
|
-
tsconfig: string;
|
|
9
|
-
stringifyContentPathRegex: string;
|
|
10
|
-
})[];
|
|
11
|
-
};
|
|
12
|
-
transformIgnorePatterns: string[];
|
|
13
|
-
snapshotSerializers: string[];
|
|
14
|
-
};
|
|
15
|
-
export default _default;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
export default {
|
|
2
|
-
displayName: 'entities',
|
|
3
|
-
preset: '../../../jest.preset.js',
|
|
4
|
-
setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'],
|
|
5
|
-
coverageDirectory: '../../../coverage/packages/core/enhancers/entities',
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.(ts|mjs|js|html)$': [
|
|
8
|
-
'jest-preset-angular',
|
|
9
|
-
{
|
|
10
|
-
tsconfig: '<rootDir>/tsconfig.spec.json',
|
|
11
|
-
stringifyContentPathRegex: '\\.(html|svg)$',
|
|
12
|
-
},
|
|
13
|
-
],
|
|
14
|
-
},
|
|
15
|
-
transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'],
|
|
16
|
-
snapshotSerializers: [
|
|
17
|
-
'jest-preset-angular/build/serializers/no-ng-attributes',
|
|
18
|
-
'jest-preset-angular/build/serializers/ng-snapshot',
|
|
19
|
-
'jest-preset-angular/build/serializers/html-comment',
|
|
20
|
-
],
|
|
21
|
-
};
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import type { SignalTree, EntityHelpers } from '../../../lib/types';
|
|
2
|
-
interface EntityConfig {
|
|
3
|
-
enabled?: boolean;
|
|
4
|
-
trackChanges?: boolean;
|
|
5
|
-
validateIds?: boolean;
|
|
6
|
-
}
|
|
7
|
-
export declare function withEntities(config?: EntityConfig): <T>(tree: SignalTree<T>) => SignalTree<T> & {
|
|
8
|
-
entities<E extends {
|
|
9
|
-
id: string | number;
|
|
10
|
-
}>(entityKey: keyof T): EntityHelpers<E>;
|
|
11
|
-
};
|
|
12
|
-
export declare function enableEntities(): <T>(tree: SignalTree<T>) => SignalTree<T> & {
|
|
13
|
-
entities<E extends {
|
|
14
|
-
id: string | number;
|
|
15
|
-
}>(entityKey: keyof T): EntityHelpers<E>;
|
|
16
|
-
};
|
|
17
|
-
export declare function withHighPerformanceEntities(): <T>(tree: SignalTree<T>) => SignalTree<T> & {
|
|
18
|
-
entities<E extends {
|
|
19
|
-
id: string | number;
|
|
20
|
-
}>(entityKey: keyof T): EntityHelpers<E>;
|
|
21
|
-
};
|
|
22
|
-
export {};
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { computed } from '@angular/core';
|
|
2
|
-
import { isAnySignal, isNodeAccessor } from '../../../lib/utils';
|
|
3
|
-
function createEntityHelpers(tree, entityKey) {
|
|
4
|
-
const getEntitySignal = () => {
|
|
5
|
-
const stateProperty = tree.state[entityKey];
|
|
6
|
-
if (!stateProperty) {
|
|
7
|
-
throw new Error(`Entity key '${String(entityKey)}' does not exist in the state`);
|
|
8
|
-
}
|
|
9
|
-
if (!isAnySignal(stateProperty)) {
|
|
10
|
-
throw new Error(`Entity key '${String(entityKey)}' is not a signal. This should not happen with SignalTree.`);
|
|
11
|
-
}
|
|
12
|
-
const signal = stateProperty;
|
|
13
|
-
const value = signal();
|
|
14
|
-
if (!Array.isArray(value)) {
|
|
15
|
-
throw new Error(`Entity key '${String(entityKey)}' does not contain an array. Current type: ${typeof value}`);
|
|
16
|
-
}
|
|
17
|
-
return signal;
|
|
18
|
-
};
|
|
19
|
-
const setSignalValue = (signal, value) => {
|
|
20
|
-
if (isNodeAccessor(signal)) {
|
|
21
|
-
signal(value);
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
signal.set(value);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
return {
|
|
28
|
-
add: (entity) => {
|
|
29
|
-
const entitySignal = getEntitySignal();
|
|
30
|
-
const currentEntities = entitySignal();
|
|
31
|
-
if (currentEntities.some((e) => e.id === entity.id)) {
|
|
32
|
-
throw new Error(`Entity with id '${entity.id}' already exists`);
|
|
33
|
-
}
|
|
34
|
-
setSignalValue(entitySignal, [...currentEntities, entity]);
|
|
35
|
-
},
|
|
36
|
-
update: (id, updates) => {
|
|
37
|
-
const entitySignal = getEntitySignal();
|
|
38
|
-
const currentEntities = entitySignal();
|
|
39
|
-
const updatedEntities = currentEntities.map((entity) => entity.id === id ? { ...entity, ...updates } : entity);
|
|
40
|
-
setSignalValue(entitySignal, updatedEntities);
|
|
41
|
-
},
|
|
42
|
-
remove: (id) => {
|
|
43
|
-
const entitySignal = getEntitySignal();
|
|
44
|
-
const currentEntities = entitySignal();
|
|
45
|
-
const filteredEntities = currentEntities.filter((entity) => entity.id !== id);
|
|
46
|
-
setSignalValue(entitySignal, filteredEntities);
|
|
47
|
-
},
|
|
48
|
-
upsert: (entity) => {
|
|
49
|
-
const entitySignal = getEntitySignal();
|
|
50
|
-
const currentEntities = entitySignal();
|
|
51
|
-
const index = currentEntities.findIndex((e) => e.id === entity.id);
|
|
52
|
-
if (index >= 0) {
|
|
53
|
-
const updatedEntities = [...currentEntities];
|
|
54
|
-
updatedEntities[index] = entity;
|
|
55
|
-
setSignalValue(entitySignal, updatedEntities);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
setSignalValue(entitySignal, [...currentEntities, entity]);
|
|
59
|
-
}
|
|
60
|
-
},
|
|
61
|
-
selectById: (id) => {
|
|
62
|
-
const entitySignal = getEntitySignal();
|
|
63
|
-
return computed(() => entitySignal().find((entity) => entity.id === id));
|
|
64
|
-
},
|
|
65
|
-
selectBy: (predicate) => {
|
|
66
|
-
const entitySignal = getEntitySignal();
|
|
67
|
-
return computed(() => entitySignal().filter(predicate));
|
|
68
|
-
},
|
|
69
|
-
selectIds: () => {
|
|
70
|
-
const entitySignal = getEntitySignal();
|
|
71
|
-
return computed(() => entitySignal().map((entity) => entity.id));
|
|
72
|
-
},
|
|
73
|
-
selectAll: () => {
|
|
74
|
-
const entitySignal = getEntitySignal();
|
|
75
|
-
return entitySignal;
|
|
76
|
-
},
|
|
77
|
-
selectTotal: () => {
|
|
78
|
-
const entitySignal = getEntitySignal();
|
|
79
|
-
return computed(() => entitySignal().length);
|
|
80
|
-
},
|
|
81
|
-
clear: () => {
|
|
82
|
-
const entitySignal = getEntitySignal();
|
|
83
|
-
setSignalValue(entitySignal, []);
|
|
84
|
-
},
|
|
85
|
-
};
|
|
86
|
-
}
|
|
87
|
-
export function withEntities(config = {}) {
|
|
88
|
-
const { enabled = true } = config;
|
|
89
|
-
return function enhanceWithEntities(tree) {
|
|
90
|
-
if (!enabled) {
|
|
91
|
-
return tree;
|
|
92
|
-
}
|
|
93
|
-
const enhancedTree = Object.assign(tree, {
|
|
94
|
-
entities(entityKey) {
|
|
95
|
-
return createEntityHelpers(tree, entityKey);
|
|
96
|
-
},
|
|
97
|
-
});
|
|
98
|
-
return enhancedTree;
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
export function enableEntities() {
|
|
102
|
-
return withEntities({ enabled: true });
|
|
103
|
-
}
|
|
104
|
-
export function withHighPerformanceEntities() {
|
|
105
|
-
return withEntities({
|
|
106
|
-
enabled: true,
|
|
107
|
-
trackChanges: true,
|
|
108
|
-
validateIds: true,
|
|
109
|
-
});
|
|
110
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { EnhancerMeta, EnhancerWithMeta } from '../lib/types';
|
|
2
|
-
export declare function createEnhancer<I = unknown, O = unknown>(meta: EnhancerMeta, enhancerFn: (input: I) => O): EnhancerWithMeta<I, O>;
|
|
3
|
-
export declare function resolveEnhancerOrder(enhancers: EnhancerWithMeta<unknown, unknown>[], availableCapabilities?: Set<string>, debugMode?: boolean): EnhancerWithMeta<unknown, unknown>[];
|
package/dist/enhancers/index.js
DELETED
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
import { SIGNAL_TREE_MESSAGES } from '../lib/constants';
|
|
2
|
-
import { ENHANCER_META } from '../lib/types';
|
|
3
|
-
export function createEnhancer(meta, enhancerFn) {
|
|
4
|
-
const fn = enhancerFn;
|
|
5
|
-
try {
|
|
6
|
-
fn.metadata = meta;
|
|
7
|
-
try {
|
|
8
|
-
fn[ENHANCER_META] = meta;
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
catch {
|
|
14
|
-
}
|
|
15
|
-
return fn;
|
|
16
|
-
}
|
|
17
|
-
export function resolveEnhancerOrder(enhancers, availableCapabilities = new Set(), debugMode = false) {
|
|
18
|
-
const nodes = enhancers.map((e, idx) => ({
|
|
19
|
-
fn: e,
|
|
20
|
-
name: e.metadata && e.metadata.name
|
|
21
|
-
? String(e.metadata.name)
|
|
22
|
-
: `enhancer#${idx}`,
|
|
23
|
-
requires: new Set(e.metadata?.requires ?? []),
|
|
24
|
-
provides: new Set(e.metadata?.provides ?? []),
|
|
25
|
-
}));
|
|
26
|
-
const adj = new Map();
|
|
27
|
-
const nameToNode = new Map();
|
|
28
|
-
for (const n of nodes) {
|
|
29
|
-
nameToNode.set(n.name, n);
|
|
30
|
-
adj.set(n.name, new Set());
|
|
31
|
-
}
|
|
32
|
-
for (const a of nodes) {
|
|
33
|
-
for (const b of nodes) {
|
|
34
|
-
if (a === b)
|
|
35
|
-
continue;
|
|
36
|
-
for (const req of b.requires) {
|
|
37
|
-
if (availableCapabilities.has(req))
|
|
38
|
-
continue;
|
|
39
|
-
if (a.provides.has(req)) {
|
|
40
|
-
const set = adj.get(a.name);
|
|
41
|
-
if (set)
|
|
42
|
-
set.add(b.name);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
const inDegree = new Map();
|
|
48
|
-
for (const entry of adj.keys())
|
|
49
|
-
inDegree.set(entry, 0);
|
|
50
|
-
for (const [, outs] of adj) {
|
|
51
|
-
for (const to of outs)
|
|
52
|
-
inDegree.set(to, (inDegree.get(to) || 0) + 1);
|
|
53
|
-
}
|
|
54
|
-
const queue = [];
|
|
55
|
-
for (const [name, deg] of inDegree.entries()) {
|
|
56
|
-
if (deg === 0)
|
|
57
|
-
queue.push(name);
|
|
58
|
-
}
|
|
59
|
-
const ordered = [];
|
|
60
|
-
while (queue.length > 0) {
|
|
61
|
-
const n = queue.shift();
|
|
62
|
-
if (!n)
|
|
63
|
-
break;
|
|
64
|
-
ordered.push(n);
|
|
65
|
-
const outs = adj.get(n);
|
|
66
|
-
if (!outs)
|
|
67
|
-
continue;
|
|
68
|
-
for (const m of outs) {
|
|
69
|
-
inDegree.set(m, (inDegree.get(m) || 0) - 1);
|
|
70
|
-
if (inDegree.get(m) === 0)
|
|
71
|
-
queue.push(m);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
if (ordered.length !== nodes.length) {
|
|
75
|
-
if (debugMode) {
|
|
76
|
-
console.warn(SIGNAL_TREE_MESSAGES.ENHANCER_CYCLE_DETECTED);
|
|
77
|
-
}
|
|
78
|
-
return enhancers;
|
|
79
|
-
}
|
|
80
|
-
return ordered.map((name) => {
|
|
81
|
-
const n = nameToNode.get(name);
|
|
82
|
-
return (n ? n.fn : enhancers[0]);
|
|
83
|
-
});
|
|
84
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/memoization';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './lib/memoization';
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
declare const _default: {
|
|
2
|
-
displayName: string;
|
|
3
|
-
preset: string;
|
|
4
|
-
setupFilesAfterEnv: string[];
|
|
5
|
-
coverageDirectory: string;
|
|
6
|
-
transform: {
|
|
7
|
-
'^.+\\.(ts|mjs|js|html)$': (string | {
|
|
8
|
-
tsconfig: string;
|
|
9
|
-
stringifyContentPathRegex: string;
|
|
10
|
-
})[];
|
|
11
|
-
};
|
|
12
|
-
transformIgnorePatterns: string[];
|
|
13
|
-
snapshotSerializers: string[];
|
|
14
|
-
};
|
|
15
|
-
export default _default;
|