@signaltree/core 4.0.16 → 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.
- package/README.md +27 -0
- package/dist/constants.js +6 -0
- package/dist/deep-clone.js +80 -0
- package/dist/deep-equal.js +41 -0
- package/dist/enhancers/batching/lib/batching.js +161 -0
- package/dist/enhancers/computed/lib/computed.js +21 -0
- package/dist/enhancers/devtools/lib/devtools.js +321 -0
- package/dist/enhancers/entities/lib/entities.js +115 -0
- package/dist/enhancers/index.js +72 -0
- package/dist/enhancers/memoization/lib/memoization.js +379 -0
- package/dist/enhancers/middleware/lib/async-helpers.js +77 -0
- package/dist/enhancers/middleware/lib/middleware.js +136 -0
- package/dist/enhancers/presets/lib/presets.js +88 -0
- package/dist/enhancers/serialization/constants.js +15 -0
- package/dist/enhancers/serialization/lib/serialization.js +660 -0
- package/dist/enhancers/time-travel/lib/time-travel.js +193 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +19 -0
- package/dist/is-built-in-object.js +23 -0
- package/dist/lib/constants.js +57 -0
- package/dist/lib/memory/memory-manager.js +164 -0
- package/dist/lib/performance/diff-engine.js +156 -0
- package/dist/lib/performance/path-index.js +156 -0
- package/dist/lib/performance/update-engine.js +188 -0
- package/dist/lib/security/security-validator.js +121 -0
- package/dist/lib/signal-tree.js +631 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/utils.js +254 -0
- package/dist/lru-cache.js +64 -0
- package/dist/parse-path.js +13 -0
- package/package.json +30 -16
- package/src/enhancers/batching/index.d.ts +1 -0
- package/src/enhancers/batching/jest.config.d.ts +15 -0
- package/src/enhancers/batching/lib/batching.d.ts +16 -0
- package/src/enhancers/batching/test-setup.d.ts +1 -0
- package/src/enhancers/computed/index.d.ts +1 -0
- package/src/enhancers/computed/jest.config.d.ts +15 -0
- package/src/enhancers/computed/lib/computed.d.ts +12 -0
- package/src/enhancers/devtools/index.d.ts +1 -0
- package/src/enhancers/devtools/jest.config.d.ts +15 -0
- package/src/enhancers/devtools/lib/devtools.d.ts +77 -0
- package/src/enhancers/devtools/test-setup.d.ts +1 -0
- package/src/enhancers/entities/index.d.ts +1 -0
- package/src/enhancers/entities/jest.config.d.ts +15 -0
- package/src/enhancers/entities/lib/entities.d.ts +22 -0
- package/src/enhancers/entities/test-setup.d.ts +1 -0
- package/src/enhancers/index.d.ts +3 -0
- package/src/enhancers/memoization/index.d.ts +1 -0
- package/src/enhancers/memoization/jest.config.d.ts +15 -0
- package/src/enhancers/memoization/lib/memoization.d.ts +65 -0
- package/src/enhancers/memoization/test-setup.d.ts +1 -0
- package/src/enhancers/middleware/index.d.ts +2 -0
- package/src/enhancers/middleware/jest.config.d.ts +15 -0
- package/src/enhancers/middleware/lib/async-helpers.d.ts +8 -0
- package/src/enhancers/middleware/lib/middleware.d.ts +11 -0
- package/src/enhancers/middleware/test-setup.d.ts +1 -0
- package/src/enhancers/presets/index.d.ts +1 -0
- package/src/enhancers/presets/jest.config.d.ts +15 -0
- package/src/enhancers/presets/lib/presets.d.ts +11 -0
- package/src/enhancers/presets/test-setup.d.ts +1 -0
- package/src/enhancers/serialization/constants.d.ts +14 -0
- package/src/enhancers/serialization/index.d.ts +2 -0
- package/src/enhancers/serialization/jest.config.d.ts +15 -0
- package/src/enhancers/serialization/lib/serialization.d.ts +59 -0
- package/src/enhancers/serialization/test-setup.d.ts +1 -0
- package/src/enhancers/time-travel/index.d.ts +1 -0
- package/src/enhancers/time-travel/jest.config.d.ts +15 -0
- package/src/enhancers/time-travel/lib/time-travel.d.ts +36 -0
- package/src/enhancers/time-travel/lib/utils.d.ts +1 -0
- package/src/enhancers/time-travel/test-setup.d.ts +1 -0
- package/src/enhancers/types.d.ts +105 -0
- package/src/index.d.ts +17 -0
- package/src/lib/constants.d.ts +42 -0
- package/src/lib/memory/memory-manager.d.ts +30 -0
- package/src/lib/performance/diff-engine.d.ts +33 -0
- package/src/lib/performance/path-index.d.ts +25 -0
- package/src/lib/performance/update-engine.d.ts +32 -0
- package/src/lib/security/security-validator.d.ts +33 -0
- package/src/lib/signal-tree.d.ts +8 -0
- package/src/lib/types.d.ts +164 -0
- package/src/lib/utils.d.ts +28 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
const middlewareMap = new WeakMap();
|
|
2
|
+
function withMiddleware(middlewares = []) {
|
|
3
|
+
return tree => {
|
|
4
|
+
middlewareMap.set(tree, [...middlewares]);
|
|
5
|
+
const originalTreeCall = tree.bind(tree);
|
|
6
|
+
const enhancedTree = function (...args) {
|
|
7
|
+
if (args.length === 0) {
|
|
8
|
+
return originalTreeCall();
|
|
9
|
+
} else {
|
|
10
|
+
const action = 'UPDATE';
|
|
11
|
+
const currentState = originalTreeCall();
|
|
12
|
+
const treeMiddlewares = middlewareMap.get(tree) || [];
|
|
13
|
+
let updateResult;
|
|
14
|
+
if (args.length === 1) {
|
|
15
|
+
const arg = args[0];
|
|
16
|
+
if (typeof arg === 'function') {
|
|
17
|
+
updateResult = arg(currentState);
|
|
18
|
+
} else {
|
|
19
|
+
updateResult = arg;
|
|
20
|
+
}
|
|
21
|
+
} else {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
for (const middleware of treeMiddlewares) {
|
|
25
|
+
if (middleware.before && !middleware.before(action, updateResult, currentState)) {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
const previousState = currentState;
|
|
30
|
+
if (args.length === 1) {
|
|
31
|
+
const arg = args[0];
|
|
32
|
+
if (typeof arg === 'function') {
|
|
33
|
+
originalTreeCall(arg);
|
|
34
|
+
} else {
|
|
35
|
+
originalTreeCall(arg);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const newState = originalTreeCall();
|
|
39
|
+
for (const middleware of treeMiddlewares) {
|
|
40
|
+
if (middleware.after) {
|
|
41
|
+
middleware.after(action, updateResult, previousState, newState);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
Object.setPrototypeOf(enhancedTree, Object.getPrototypeOf(tree));
|
|
47
|
+
Object.assign(enhancedTree, tree);
|
|
48
|
+
if ('state' in tree) {
|
|
49
|
+
Object.defineProperty(enhancedTree, 'state', {
|
|
50
|
+
value: tree.state,
|
|
51
|
+
enumerable: false,
|
|
52
|
+
configurable: true
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if ('$' in tree) {
|
|
56
|
+
Object.defineProperty(enhancedTree, '$', {
|
|
57
|
+
value: tree['$'],
|
|
58
|
+
enumerable: false,
|
|
59
|
+
configurable: true
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
enhancedTree.addTap = middleware => {
|
|
63
|
+
const treeMiddlewares = middlewareMap.get(tree) || [];
|
|
64
|
+
const existingIndex = treeMiddlewares.findIndex(m => m.id === middleware.id);
|
|
65
|
+
if (existingIndex >= 0) {
|
|
66
|
+
treeMiddlewares[existingIndex] = middleware;
|
|
67
|
+
} else {
|
|
68
|
+
treeMiddlewares.push(middleware);
|
|
69
|
+
}
|
|
70
|
+
middlewareMap.set(tree, treeMiddlewares);
|
|
71
|
+
};
|
|
72
|
+
enhancedTree.removeTap = id => {
|
|
73
|
+
const treeMiddlewares = middlewareMap.get(tree) || [];
|
|
74
|
+
const filtered = treeMiddlewares.filter(m => m.id !== id);
|
|
75
|
+
middlewareMap.set(tree, filtered);
|
|
76
|
+
};
|
|
77
|
+
const originalBatchUpdate = tree.batchUpdate;
|
|
78
|
+
if (originalBatchUpdate) {
|
|
79
|
+
enhancedTree.batchUpdate = updater => {
|
|
80
|
+
const action = 'BATCH_UPDATE';
|
|
81
|
+
const currentState = originalTreeCall();
|
|
82
|
+
const updateResult = updater(currentState);
|
|
83
|
+
const treeMiddlewares = middlewareMap.get(tree) || [];
|
|
84
|
+
for (const middleware of treeMiddlewares) {
|
|
85
|
+
if (middleware.before && !middleware.before(action, updateResult, currentState)) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const previousState = currentState;
|
|
90
|
+
originalBatchUpdate.call(tree, updater);
|
|
91
|
+
const newState = originalTreeCall();
|
|
92
|
+
for (const middleware of treeMiddlewares) {
|
|
93
|
+
if (middleware.after) {
|
|
94
|
+
middleware.after(action, updateResult, previousState, newState);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const originalDestroy = tree.destroy;
|
|
100
|
+
enhancedTree.destroy = () => {
|
|
101
|
+
middlewareMap.delete(tree);
|
|
102
|
+
if (originalDestroy) {
|
|
103
|
+
originalDestroy.call(tree);
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
return enhancedTree;
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
function createLoggingMiddleware(treeName) {
|
|
110
|
+
return {
|
|
111
|
+
id: 'logging',
|
|
112
|
+
before: (action, payload, state) => {
|
|
113
|
+
console.group(`🏪 ${treeName}: ${action}`);
|
|
114
|
+
console.log('Previous state:', state);
|
|
115
|
+
console.log('Payload:', typeof payload === 'function' ? 'Function' : payload);
|
|
116
|
+
return true;
|
|
117
|
+
},
|
|
118
|
+
after: (action, payload, state, newState) => {
|
|
119
|
+
console.log('New state:', newState);
|
|
120
|
+
console.groupEnd();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function createValidationMiddleware(validator) {
|
|
125
|
+
return {
|
|
126
|
+
id: 'validation',
|
|
127
|
+
after: (action, payload, state, newState) => {
|
|
128
|
+
const error = validator(newState);
|
|
129
|
+
if (error) {
|
|
130
|
+
console.error(`Validation failed after ${action}:`, error);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export { createLoggingMiddleware, createValidationMiddleware, withMiddleware };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { composeEnhancers } from '../../../lib/utils.js';
|
|
2
|
+
import { withHighPerformanceBatching, withBatching } from '../../batching/lib/batching.js';
|
|
3
|
+
import { withDevTools } from '../../devtools/lib/devtools.js';
|
|
4
|
+
import { withHighPerformanceMemoization, withMemoization } from '../../memoization/lib/memoization.js';
|
|
5
|
+
import { withMiddleware } from '../../middleware/lib/middleware.js';
|
|
6
|
+
import { withTimeTravel } from '../../time-travel/lib/time-travel.js';
|
|
7
|
+
|
|
8
|
+
const TREE_PRESETS = {
|
|
9
|
+
basic: {
|
|
10
|
+
batchUpdates: false,
|
|
11
|
+
useMemoization: false,
|
|
12
|
+
trackPerformance: false,
|
|
13
|
+
enableTimeTravel: false,
|
|
14
|
+
enableDevTools: false,
|
|
15
|
+
debugMode: false
|
|
16
|
+
},
|
|
17
|
+
performance: {
|
|
18
|
+
batchUpdates: true,
|
|
19
|
+
useMemoization: true,
|
|
20
|
+
trackPerformance: false,
|
|
21
|
+
enableTimeTravel: false,
|
|
22
|
+
enableDevTools: false,
|
|
23
|
+
debugMode: false,
|
|
24
|
+
useShallowComparison: true,
|
|
25
|
+
maxCacheSize: 200
|
|
26
|
+
},
|
|
27
|
+
development: {
|
|
28
|
+
batchUpdates: true,
|
|
29
|
+
useMemoization: true,
|
|
30
|
+
trackPerformance: true,
|
|
31
|
+
enableTimeTravel: true,
|
|
32
|
+
enableDevTools: true,
|
|
33
|
+
debugMode: true,
|
|
34
|
+
maxCacheSize: 100
|
|
35
|
+
},
|
|
36
|
+
production: {
|
|
37
|
+
batchUpdates: true,
|
|
38
|
+
useMemoization: true,
|
|
39
|
+
trackPerformance: false,
|
|
40
|
+
enableTimeTravel: false,
|
|
41
|
+
enableDevTools: false,
|
|
42
|
+
debugMode: false,
|
|
43
|
+
useShallowComparison: true,
|
|
44
|
+
maxCacheSize: 200
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
function createPresetConfig(preset, overrides = {}) {
|
|
48
|
+
const baseConfig = TREE_PRESETS[preset];
|
|
49
|
+
return {
|
|
50
|
+
...baseConfig,
|
|
51
|
+
...overrides
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function validatePreset(preset) {
|
|
55
|
+
if (!TREE_PRESETS[preset]) {
|
|
56
|
+
throw new Error(`Invalid preset: ${preset}. Valid presets are: ${Object.keys(TREE_PRESETS).join(', ')}`);
|
|
57
|
+
}
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
function getAvailablePresets() {
|
|
61
|
+
return Object.keys(TREE_PRESETS);
|
|
62
|
+
}
|
|
63
|
+
function combinePresets(presets, overrides = {}) {
|
|
64
|
+
let combined = {};
|
|
65
|
+
for (const preset of presets) {
|
|
66
|
+
validatePreset(preset);
|
|
67
|
+
combined = {
|
|
68
|
+
...combined,
|
|
69
|
+
...TREE_PRESETS[preset]
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
...combined,
|
|
74
|
+
...overrides
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createDevTree(overrides = {}) {
|
|
78
|
+
const config = createPresetConfig('development', overrides);
|
|
79
|
+
const composed = composeEnhancers(withBatching(), withHighPerformanceBatching(), withMemoization(), withHighPerformanceMemoization(), withMiddleware(), withTimeTravel(), withDevTools({
|
|
80
|
+
treeName: config.treeName ?? 'SignalTree Dev'
|
|
81
|
+
}));
|
|
82
|
+
return {
|
|
83
|
+
config,
|
|
84
|
+
enhancer: composed
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export { TREE_PRESETS, combinePresets, createDevTree, createPresetConfig, getAvailablePresets, validatePreset };
|