fractostate 3.0.0 → 3.1.2
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 +60 -75
- package/dist/cjs/src/proxy.js +46 -202
- package/dist/cjs/src/proxy.js.map +1 -1
- package/dist/cjs/src/store.js +5 -3
- package/dist/cjs/src/store.js.map +1 -1
- package/dist/esm/src/proxy.js +46 -202
- package/dist/esm/src/proxy.js.map +1 -1
- package/dist/esm/src/store.js +5 -3
- package/dist/esm/src/store.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/plugins.d.ts +1 -1
- package/dist/{types-DfJr6pGC.d.ts → types-Q_jlbhuA.d.ts} +2 -0
- package/package.json +16 -12
package/README.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
# FractoState
|
|
1
|
+
# FractoState | Decentralized State Management for React
|
|
2
2
|
|
|
3
3
|
<p align="center">
|
|
4
4
|
<img src="https://dll.nehonix.com/assets/FractoState/logo.png" alt="FractoState Logo" width="600" />
|
|
5
5
|
</p>
|
|
6
6
|
|
|
7
|
-
FractoState is a high-performance, decentralized state management
|
|
7
|
+
FractoState is a high-performance, decentralized state management engine for React applications. It provides surgical state updates through an atomic proxy architecture, ensuring absolute type safety and zero boilerplate.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## Technical Demonstration
|
|
10
10
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<video
|
|
@@ -18,59 +18,55 @@ FractoState is a high-performance, decentralized state management library for Re
|
|
|
18
18
|
></video>
|
|
19
19
|
</p>
|
|
20
20
|
|
|
21
|
-
>
|
|
22
|
-
> Autoplay is disabled on GitHub.
|
|
21
|
+
> [!NOTE]
|
|
22
|
+
> Autoplay is disabled on GitHub. Please click below to view the demonstration video.
|
|
23
23
|
|
|
24
24
|
<p align="center">
|
|
25
25
|
<a href="https://dll.nehonix.com/assets/FractoState/fracto_demo.mp4">
|
|
26
|
-
|
|
26
|
+
<strong>View FractoState Demonstration (MP4)</strong>
|
|
27
27
|
</a>
|
|
28
28
|
</p>
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## Architectural Objectives
|
|
31
31
|
|
|
32
|
-
Traditional state management
|
|
32
|
+
Traditional state management patterns often encounter significant performance and maintainability limitations:
|
|
33
33
|
|
|
34
|
-
1. **
|
|
35
|
-
2. **Boilerplate
|
|
36
|
-
3. **
|
|
37
|
-
4. **
|
|
34
|
+
1. **Context Overhead**: Dependency on high-level providers often results in unnecessary re-renders across the component tree.
|
|
35
|
+
2. **Boilerplate Rigidity**: Redux-like architectures introduce significant cognitive overhead for routine state transitions.
|
|
36
|
+
3. **Memory Latency**: Standard immutable patterns in JavaScript frequently require expensive deep-cloning operations.
|
|
37
|
+
4. **Namespace Pollution**: Global state exposure increases the risk of side effects and non-deterministic mutations.
|
|
38
38
|
|
|
39
|
-
##
|
|
39
|
+
## Core Engineered Solutions
|
|
40
40
|
|
|
41
|
-
FractoState
|
|
41
|
+
FractoState redefines state management via three architectural pillars:
|
|
42
42
|
|
|
43
|
-
- **Isolated Memory Vault**: State is
|
|
44
|
-
- **
|
|
45
|
-
- **
|
|
43
|
+
- **Isolated Memory Vault**: State is encapsulated within private closures, preventing unauthorized external mutations and ensuring data integrity.
|
|
44
|
+
- **Atomic Proxy Engine**: Utilizes recursive Proxies to provide a direct mutation API while maintaining strict immutability and surgical update resolution under the hood.
|
|
45
|
+
- **Direct Subscription Model**: Components subscribe directly to specific Vault keys, bypassing the React Context tree to ensure minimal O(1) render targeting.
|
|
46
46
|
|
|
47
47
|
## Installation
|
|
48
48
|
|
|
49
49
|
```bash
|
|
50
|
-
# xfpm
|
|
50
|
+
# xfpm (recommended)
|
|
51
51
|
xfpm install fractostate
|
|
52
52
|
|
|
53
|
-
#
|
|
53
|
+
# standard package managers
|
|
54
54
|
npm install fractostate
|
|
55
|
-
|
|
56
|
-
# yarn
|
|
57
55
|
yarn add fractostate
|
|
58
|
-
|
|
59
|
-
# pnpm
|
|
60
56
|
pnpm add fractostate
|
|
61
57
|
```
|
|
62
58
|
|
|
63
|
-
## Quick
|
|
59
|
+
## Quick Implementation
|
|
64
60
|
|
|
65
|
-
|
|
61
|
+
Example of a decentralized cart state:
|
|
66
62
|
|
|
67
63
|
```tsx
|
|
68
64
|
import { defineFlow, useFlow } from "fractostate";
|
|
69
65
|
|
|
70
|
-
//
|
|
66
|
+
// ◈ Define the flow definition
|
|
71
67
|
const CartFlow = defineFlow("cart", { items: [], total: 0 });
|
|
72
68
|
|
|
73
|
-
//
|
|
69
|
+
// ◈ Interaction in any component
|
|
74
70
|
function AddToCartButton({ product }) {
|
|
75
71
|
const [, { ops }] = useFlow(CartFlow);
|
|
76
72
|
|
|
@@ -79,78 +75,67 @@ function AddToCartButton({ product }) {
|
|
|
79
75
|
);
|
|
80
76
|
}
|
|
81
77
|
|
|
82
|
-
//
|
|
78
|
+
// ◈ Focused reactivity
|
|
83
79
|
function CartIcon() {
|
|
84
80
|
const [cart] = useFlow(CartFlow);
|
|
85
|
-
return <span>{cart.items.length}
|
|
81
|
+
return <span>{cart.items.length} units</span>;
|
|
86
82
|
}
|
|
87
83
|
```
|
|
88
84
|
|
|
89
|
-
##
|
|
85
|
+
## Engineering Highlights (v3.1)
|
|
90
86
|
|
|
91
|
-
FractoState
|
|
87
|
+
FractoState v3 introduces advanced primitives designed for enterprise-scale requirements.
|
|
92
88
|
|
|
93
|
-
###
|
|
89
|
+
### Computed Flows
|
|
94
90
|
|
|
95
|
-
|
|
91
|
+
Reactive, read-only state nodes derived from source flows.
|
|
96
92
|
|
|
97
|
-
|
|
98
|
-
const TotalPrice = defineDerived(CartFlow, (state) =>
|
|
99
|
-
state.items.reduce((acc, item) => acc + item.price, 0),
|
|
100
|
-
);
|
|
101
|
-
```
|
|
93
|
+
- [Documentation: Computed Flows](./docs/computed-flows.md)
|
|
102
94
|
|
|
103
|
-
###
|
|
95
|
+
### Native Async Actions
|
|
104
96
|
|
|
105
|
-
|
|
97
|
+
Encapsulated business logic with direct access to surgical operation proxies.
|
|
106
98
|
|
|
107
|
-
|
|
108
|
-
actions: {
|
|
109
|
-
login: (creds) => async (ops) => {
|
|
110
|
-
ops.self.loading._set(true);
|
|
111
|
-
await api.login(creds);
|
|
112
|
-
ops.self.loading._set(false);
|
|
113
|
-
};
|
|
114
|
-
}
|
|
115
|
-
```
|
|
99
|
+
- [Documentation: Async Actions](./docs/native-async-actions.md)
|
|
116
100
|
|
|
117
|
-
###
|
|
101
|
+
### Extensible Plugin Interface
|
|
118
102
|
|
|
119
|
-
|
|
103
|
+
Unified API for state persistence, telemetry, and debugging.
|
|
120
104
|
|
|
121
|
-
|
|
122
|
-
plugins: [persist(), logger()];
|
|
123
|
-
```
|
|
105
|
+
- [Documentation: Plugins](./docs/plugins-and-devtools.md)
|
|
124
106
|
|
|
125
|
-
###
|
|
107
|
+
### Surgical DevTools
|
|
126
108
|
|
|
127
|
-
|
|
109
|
+
Real-time state inspector with zero-configuration overhead.
|
|
128
110
|
|
|
129
|
-
|
|
130
|
-
<FractoDevTools />
|
|
131
|
-
```
|
|
111
|
+
- [Documentation: DevTools](./docs/plugins-and-devtools.md#ghost-inspector-devtools)
|
|
132
112
|
|
|
133
|
-
|
|
113
|
+
## Performance Benchmarks
|
|
134
114
|
|
|
135
|
-
FractoState
|
|
115
|
+
FractoState is engineered for high-throughput environments. Current benchmarks demonstrate performance parity with minimalist libraries while significantly outperforming traditional Redux patterns.
|
|
136
116
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
117
|
+
| Scenario | Objective | FractoState | Industry Standard |
|
|
118
|
+
| :------------------------- | :--------------- | :------------ | :------------------------- |
|
|
119
|
+
| **Big Data (1M nodes)** | Mutation Latency | **2.1s** | 3.1s (Redux Toolkit) |
|
|
120
|
+
| **Deep Update (1k nodes)** | Throughput | **887 ops/s** | 430 ops/s (Standard React) |
|
|
121
|
+
| **Store Initialization** | Setup Latency | **2.2ms** | 6.5ms (Redux Toolkit) |
|
|
140
122
|
|
|
141
|
-
|
|
123
|
+
### Scalability Analysis
|
|
142
124
|
|
|
143
|
-
|
|
144
|
-
- [API Reference](./docs/api-reference.md)
|
|
145
|
-
- [Architecture](./docs/architecture.md)
|
|
146
|
-
- [Computed Flows](./docs/computed-flows.md)
|
|
147
|
-
- [Native Async Actions](./docs/native-async-actions.md)
|
|
148
|
-
- [Plugins & DevTools](./docs/plugins-and-devtools.md)
|
|
149
|
-
- [Advanced Features (v2.1)](./docs/advanced-features.md)
|
|
150
|
-
- [Surgical Updates: \_set vs \_patch](./docs/set-vs-patch.md)
|
|
125
|
+
While libraries like Zustand require manual immutable spreading for deep updates, FractoState achieves similar throughput with a declarative API: `ops.registry[id].child._set(data)`. This eliminates developer error in complex state transitions without sacrificing performance.
|
|
151
126
|
|
|
152
|
-
|
|
127
|
+
Detailed technical analysis available in: [Performance Specifications](./docs/benchmarks.md).
|
|
128
|
+
|
|
129
|
+
## Documentation Reference
|
|
130
|
+
|
|
131
|
+
- [◈ Getting Started](./docs/getting-started.md)
|
|
132
|
+
- [◈ Computed Flows](./docs/computed-flows.md)
|
|
133
|
+
- [◈ Native Async Actions](./docs/native-async-actions.md)
|
|
134
|
+
- [◈ Plugin Architecture](./docs/plugins-and-devtools.md)
|
|
135
|
+
- [◈ Advanced State Control](./docs/advanced-features.md)
|
|
136
|
+
- [◈ Surgical Update Logic](./docs/set-vs-patch.md)
|
|
137
|
+
- [◈ Benchmark Analysis](./docs/benchmarks.md)
|
|
153
138
|
|
|
154
139
|
---
|
|
155
140
|
|
|
156
|
-
FractoState
|
|
141
|
+
FractoState | Engineered for Precision. Optimized for Performance.
|
package/dist/cjs/src/proxy.js
CHANGED
|
@@ -12,91 +12,55 @@ function createDeepProxy(key, path, currentVal, options) {
|
|
|
12
12
|
if (typeof prop === "symbol")
|
|
13
13
|
return undefined;
|
|
14
14
|
const newPath = [...path, prop];
|
|
15
|
+
/**
|
|
16
|
+
* CORE COMMITTER
|
|
17
|
+
* Always resolves the freshest state from the store before applying the path update.
|
|
18
|
+
* This prevents "stale state" issues during mass sequential updates.
|
|
19
|
+
*/
|
|
20
|
+
const commit = (val, forceful, skipEquality = false) => {
|
|
21
|
+
try {
|
|
22
|
+
const currentState = store.store.get(key, undefined);
|
|
23
|
+
const newState = setInPath(currentState, path, val);
|
|
24
|
+
store.store.set(key, newState, {
|
|
25
|
+
...options,
|
|
26
|
+
force: forceful,
|
|
27
|
+
skipEquality,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
console.error(`[FlowProxy] Commit error at path ${path.join(".")}:`, error);
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
15
35
|
// --- Meta-Operations ---
|
|
16
36
|
// Read current value
|
|
17
37
|
if (prop === "_val")
|
|
18
38
|
return currentVal;
|
|
19
39
|
// Generic property replacement (Forceful)
|
|
20
|
-
if (prop === "_set")
|
|
21
|
-
return (val) =>
|
|
22
|
-
try {
|
|
23
|
-
const currentState = store.store.get(key, undefined);
|
|
24
|
-
const newState = setInPath(currentState, path, val);
|
|
25
|
-
store.store.set(key, newState, { ...options, force: true });
|
|
26
|
-
}
|
|
27
|
-
catch (error) {
|
|
28
|
-
console.error(`[FlowProxy] Error setting value at path ${path.join(".")}:`, error);
|
|
29
|
-
throw error;
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
}
|
|
40
|
+
if (prop === "_set")
|
|
41
|
+
return (val) => commit(val, true);
|
|
33
42
|
// Smart property replacement (Skip if equal)
|
|
34
|
-
if (prop === "_patch")
|
|
35
|
-
return (val) =>
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const newState = setInPath(currentState, path, val);
|
|
39
|
-
store.store.set(key, newState, { ...options, force: false });
|
|
40
|
-
}
|
|
41
|
-
catch (error) {
|
|
42
|
-
console.error(`[FlowProxy] Error patching value at path ${path.join(".")}:`, error);
|
|
43
|
-
throw error;
|
|
44
|
-
}
|
|
45
|
-
};
|
|
46
|
-
}
|
|
43
|
+
if (prop === "_patch")
|
|
44
|
+
return (val) => commit(val, false);
|
|
45
|
+
// Helper for type-specific operators
|
|
46
|
+
const update = (val) => commit(val, false, true);
|
|
47
47
|
// --- Type-Specific Atomic Operations ---
|
|
48
48
|
// Number Operations
|
|
49
49
|
if (typeof currentVal === "number") {
|
|
50
50
|
if (prop === "_increment")
|
|
51
|
-
return (amount = 1) =>
|
|
52
|
-
if (typeof amount !== "number" || !isFinite(amount)) {
|
|
53
|
-
console.warn(`[FlowProxy] Invalid increment amount: ${amount}`);
|
|
54
|
-
return;
|
|
55
|
-
}
|
|
56
|
-
update(currentVal + amount);
|
|
57
|
-
};
|
|
51
|
+
return (amount = 1) => update(currentVal + amount);
|
|
58
52
|
if (prop === "_decrement")
|
|
59
|
-
return (amount = 1) =>
|
|
60
|
-
if (typeof amount !== "number" || !isFinite(amount)) {
|
|
61
|
-
console.warn(`[FlowProxy] Invalid decrement amount: ${amount}`);
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
update(currentVal - amount);
|
|
65
|
-
};
|
|
53
|
+
return (amount = 1) => update(currentVal - amount);
|
|
66
54
|
if (prop === "_add")
|
|
67
|
-
return (amount) =>
|
|
68
|
-
if (typeof amount !== "number" || !isFinite(amount)) {
|
|
69
|
-
console.warn(`[FlowProxy] Invalid add amount: ${amount}`);
|
|
70
|
-
return;
|
|
71
|
-
}
|
|
72
|
-
update(currentVal + amount);
|
|
73
|
-
};
|
|
55
|
+
return (amount) => update(currentVal + amount);
|
|
74
56
|
if (prop === "_subtract")
|
|
75
|
-
return (amount) =>
|
|
76
|
-
if (typeof amount !== "number" || !isFinite(amount)) {
|
|
77
|
-
console.warn(`[FlowProxy] Invalid subtract amount: ${amount}`);
|
|
78
|
-
return;
|
|
79
|
-
}
|
|
80
|
-
update(currentVal - amount);
|
|
81
|
-
};
|
|
57
|
+
return (amount) => update(currentVal - amount);
|
|
82
58
|
if (prop === "_multiply")
|
|
83
|
-
return (amount) =>
|
|
84
|
-
if (typeof amount !== "number" || !isFinite(amount)) {
|
|
85
|
-
console.warn(`[FlowProxy] Invalid multiply amount: ${amount}`);
|
|
86
|
-
return;
|
|
87
|
-
}
|
|
88
|
-
update(currentVal * amount);
|
|
89
|
-
};
|
|
59
|
+
return (amount) => update(currentVal * amount);
|
|
90
60
|
if (prop === "_divide")
|
|
91
61
|
return (amount) => {
|
|
92
|
-
if (
|
|
93
|
-
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (amount === 0) {
|
|
97
|
-
console.error(`[FlowProxy] Cannot divide by zero`);
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
62
|
+
if (amount === 0)
|
|
63
|
+
throw new Error("[FlowProxy] Division by zero");
|
|
100
64
|
update(currentVal / amount);
|
|
101
65
|
};
|
|
102
66
|
}
|
|
@@ -105,85 +69,19 @@ function createDeepProxy(key, path, currentVal, options) {
|
|
|
105
69
|
if (prop === "_push")
|
|
106
70
|
return (item) => update([...currentVal, item]);
|
|
107
71
|
if (prop === "_pop")
|
|
108
|
-
return () =>
|
|
109
|
-
if (currentVal.length === 0) {
|
|
110
|
-
console.warn(`[FlowProxy] Cannot pop from empty array`);
|
|
111
|
-
return;
|
|
112
|
-
}
|
|
113
|
-
update(currentVal.slice(0, -1));
|
|
114
|
-
};
|
|
72
|
+
return () => update(currentVal.slice(0, -1));
|
|
115
73
|
if (prop === "_shift")
|
|
116
|
-
return () =>
|
|
117
|
-
if (currentVal.length === 0) {
|
|
118
|
-
console.warn(`[FlowProxy] Cannot shift from empty array`);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
update(currentVal.slice(1));
|
|
122
|
-
};
|
|
74
|
+
return () => update(currentVal.slice(1));
|
|
123
75
|
if (prop === "_unshift")
|
|
124
76
|
return (item) => update([item, ...currentVal]);
|
|
125
77
|
if (prop === "_filter")
|
|
126
|
-
return (fn) =>
|
|
127
|
-
if (typeof fn !== "function") {
|
|
128
|
-
console.error(`[FlowProxy] Filter requires a function`);
|
|
129
|
-
return;
|
|
130
|
-
}
|
|
131
|
-
try {
|
|
132
|
-
update(currentVal.filter(fn));
|
|
133
|
-
}
|
|
134
|
-
catch (error) {
|
|
135
|
-
console.error(`[FlowProxy] Filter function threw error:`, error);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
78
|
+
return (fn) => update(currentVal.filter(fn));
|
|
138
79
|
if (prop === "_map")
|
|
139
|
-
return (fn) =>
|
|
140
|
-
if (typeof fn !== "function") {
|
|
141
|
-
console.error(`[FlowProxy] Map requires a function`);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
try {
|
|
145
|
-
update(currentVal.map(fn));
|
|
146
|
-
}
|
|
147
|
-
catch (error) {
|
|
148
|
-
console.error(`[FlowProxy] Map function threw error:`, error);
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
if (prop === "_splice")
|
|
152
|
-
return (...args) => {
|
|
153
|
-
try {
|
|
154
|
-
const next = [...currentVal];
|
|
155
|
-
const start = args[0] ?? 0;
|
|
156
|
-
const deleteCount = args[1] ?? 0;
|
|
157
|
-
if (typeof start !== "number" ||
|
|
158
|
-
typeof deleteCount !== "number") {
|
|
159
|
-
console.error(`[FlowProxy] Splice requires numeric arguments`);
|
|
160
|
-
return;
|
|
161
|
-
}
|
|
162
|
-
next.splice(start, deleteCount, ...args.slice(2));
|
|
163
|
-
update(next);
|
|
164
|
-
}
|
|
165
|
-
catch (error) {
|
|
166
|
-
console.error(`[FlowProxy] Splice error:`, error);
|
|
167
|
-
}
|
|
168
|
-
};
|
|
80
|
+
return (fn) => update(currentVal.map(fn));
|
|
169
81
|
if (prop === "_removeAt")
|
|
170
|
-
return (index) =>
|
|
171
|
-
if (typeof index !== "number" ||
|
|
172
|
-
index < 0 ||
|
|
173
|
-
index >= currentVal.length) {
|
|
174
|
-
console.warn(`[FlowProxy] Invalid index: ${index}`);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
update(currentVal.filter((_, i) => i !== index));
|
|
178
|
-
};
|
|
82
|
+
return (index) => update(currentVal.filter((_, i) => i !== index));
|
|
179
83
|
if (prop === "_insertAt")
|
|
180
84
|
return (index, item) => {
|
|
181
|
-
if (typeof index !== "number" ||
|
|
182
|
-
index < 0 ||
|
|
183
|
-
index > currentVal.length) {
|
|
184
|
-
console.warn(`[FlowProxy] Invalid index: ${index}`);
|
|
185
|
-
return;
|
|
186
|
-
}
|
|
187
85
|
const next = [...currentVal];
|
|
188
86
|
next.splice(index, 0, item);
|
|
189
87
|
update(next);
|
|
@@ -192,84 +90,33 @@ function createDeepProxy(key, path, currentVal, options) {
|
|
|
192
90
|
// String Operations
|
|
193
91
|
if (typeof currentVal === "string") {
|
|
194
92
|
if (prop === "_append")
|
|
195
|
-
return (str) =>
|
|
196
|
-
if (typeof str !== "string") {
|
|
197
|
-
console.warn(`[FlowProxy] Append requires a string`);
|
|
198
|
-
return;
|
|
199
|
-
}
|
|
200
|
-
update(currentVal + str);
|
|
201
|
-
};
|
|
93
|
+
return (str) => update(currentVal + str);
|
|
202
94
|
if (prop === "_prepend")
|
|
203
|
-
return (str) =>
|
|
204
|
-
if (typeof str !== "string") {
|
|
205
|
-
console.warn(`[FlowProxy] Prepend requires a string`);
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
update(str + currentVal);
|
|
209
|
-
};
|
|
95
|
+
return (str) => update(str + currentVal);
|
|
210
96
|
if (prop === "_uppercase")
|
|
211
97
|
return () => update(currentVal.toUpperCase());
|
|
212
98
|
if (prop === "_lowercase")
|
|
213
99
|
return () => update(currentVal.toLowerCase());
|
|
214
100
|
if (prop === "_trim")
|
|
215
101
|
return () => update(currentVal.trim());
|
|
216
|
-
if (prop === "_replace")
|
|
217
|
-
return (search, replace) => {
|
|
218
|
-
if (typeof replace !== "string") {
|
|
219
|
-
console.warn(`[FlowProxy] Replace requires a string replacement`);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
try {
|
|
223
|
-
update(currentVal.replace(search, replace));
|
|
224
|
-
}
|
|
225
|
-
catch (error) {
|
|
226
|
-
console.error(`[FlowProxy] Replace error:`, error);
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
102
|
}
|
|
230
103
|
// Object Operations
|
|
231
104
|
if (currentVal !== null &&
|
|
232
105
|
typeof currentVal === "object" &&
|
|
233
106
|
!Array.isArray(currentVal)) {
|
|
234
107
|
if (prop === "_merge")
|
|
235
|
-
return (obj) => {
|
|
236
|
-
if (typeof obj !== "object" || obj === null || Array.isArray(obj)) {
|
|
237
|
-
console.warn(`[FlowProxy] Merge requires an object`);
|
|
238
|
-
return;
|
|
239
|
-
}
|
|
240
|
-
update({ ...currentVal, ...obj });
|
|
241
|
-
};
|
|
108
|
+
return (obj) => update({ ...currentVal, ...obj });
|
|
242
109
|
if (prop === "_delete")
|
|
243
110
|
return (keyToDel) => {
|
|
244
|
-
if (typeof keyToDel !== "string") {
|
|
245
|
-
console.warn(`[FlowProxy] Delete requires a string key`);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
if (!(keyToDel in currentVal)) {
|
|
249
|
-
console.warn(`[FlowProxy] Key "${keyToDel}" does not exist`);
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
111
|
const next = { ...currentVal };
|
|
253
112
|
delete next[keyToDel];
|
|
254
113
|
update(next);
|
|
255
114
|
};
|
|
256
115
|
}
|
|
257
|
-
/**
|
|
258
|
-
* Internal helper to commit a value update to the store.
|
|
259
|
-
*/
|
|
260
|
-
function update(val) {
|
|
261
|
-
try {
|
|
262
|
-
const currentState = store.store.get(key, undefined);
|
|
263
|
-
const newState = setInPath(currentState, path, val);
|
|
264
|
-
store.store.set(key, newState, options);
|
|
265
|
-
}
|
|
266
|
-
catch (error) {
|
|
267
|
-
console.error(`[FlowProxy] Error updating value at path ${path.join(".")}:`, error);
|
|
268
|
-
throw error;
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
116
|
// Recursive step: create a new proxy for the child property
|
|
272
|
-
const nextVal = currentVal
|
|
117
|
+
const nextVal = currentVal !== null && currentVal !== undefined
|
|
118
|
+
? currentVal[prop]
|
|
119
|
+
: undefined;
|
|
273
120
|
return createDeepProxy(key, newPath, nextVal, options);
|
|
274
121
|
},
|
|
275
122
|
apply(_target, _thisArg, args) {
|
|
@@ -289,17 +136,14 @@ function setInPath(obj, path, value) {
|
|
|
289
136
|
const [head, ...tail] = path;
|
|
290
137
|
if (Array.isArray(obj)) {
|
|
291
138
|
const index = parseInt(head, 10);
|
|
292
|
-
if (isNaN(index) || index < 0)
|
|
139
|
+
if (isNaN(index) || index < 0)
|
|
293
140
|
throw new Error(`[FlowProxy] Invalid array index: ${head}`);
|
|
294
|
-
}
|
|
295
141
|
const newArr = [...obj];
|
|
296
|
-
if (index >= newArr.length)
|
|
142
|
+
if (index >= newArr.length)
|
|
297
143
|
newArr.length = index + 1;
|
|
298
|
-
}
|
|
299
144
|
newArr[index] = setInPath(newArr[index], tail, value);
|
|
300
145
|
return newArr;
|
|
301
146
|
}
|
|
302
|
-
// Handle nested objects (including null/undefined recovery)
|
|
303
147
|
const currentObj = obj ?? {};
|
|
304
148
|
return {
|
|
305
149
|
...currentObj,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"proxy.js","sources":["../../../src/proxy.ts"],"sourcesContent":["import type { FlowOptions, TypeAwareOps } from \"./types\";\nimport { store } from \"./store\";\n\n/**\n * Creates a deep proxy that provides type-specific atomic operations for a flow.\n * The proxy tracks its path within the state tree and maps access to specific update logic.\n */\nexport function createDeepProxy<T = any>(\n key: string,\n path: string[],\n currentVal: any,\n options: FlowOptions<any>,\n): TypeAwareOps<T> {\n return new Proxy(() => {}, {\n get(_target: any, prop: any) {\n if (typeof prop === \"symbol\") return undefined;\n\n const newPath = [...path, prop];\n\n // --- Meta-Operations ---\n\n // Read current value\n if (prop === \"_val\") return currentVal;\n\n // Generic property replacement (Forceful)\n if (prop === \"_set\") {\n return (val: any) => {\n try {\n const currentState = store.get(key, undefined);\n const newState = setInPath(currentState, path, val);\n store.set(key, newState, { ...options, force: true });\n } catch (error) {\n console.error(\n `[FlowProxy] Error setting value at path ${path.join(\".\")}:`,\n error,\n );\n throw error;\n }\n };\n }\n\n // Smart property replacement (Skip if equal)\n if (prop === \"_patch\") {\n return (val: any) => {\n try {\n const currentState = store.get(key, undefined);\n const newState = setInPath(currentState, path, val);\n store.set(key, newState, { ...options, force: false });\n } catch (error) {\n console.error(\n `[FlowProxy] Error patching value at path ${path.join(\".\")}:`,\n error,\n );\n throw error;\n }\n };\n }\n\n // --- Type-Specific Atomic Operations ---\n\n // Number Operations\n if (typeof currentVal === \"number\") {\n if (prop === \"_increment\")\n return (amount = 1) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid increment amount: ${amount}`);\n return;\n }\n update(currentVal + amount);\n };\n if (prop === \"_decrement\")\n return (amount = 1) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid decrement amount: ${amount}`);\n return;\n }\n update(currentVal - amount);\n };\n if (prop === \"_add\")\n return (amount: number) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid add amount: ${amount}`);\n return;\n }\n update(currentVal + amount);\n };\n if (prop === \"_subtract\")\n return (amount: number) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid subtract amount: ${amount}`);\n return;\n }\n update(currentVal - amount);\n };\n if (prop === \"_multiply\")\n return (amount: number) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid multiply amount: ${amount}`);\n return;\n }\n update(currentVal * amount);\n };\n if (prop === \"_divide\")\n return (amount: number) => {\n if (typeof amount !== \"number\" || !isFinite(amount)) {\n console.warn(`[FlowProxy] Invalid divide amount: ${amount}`);\n return;\n }\n if (amount === 0) {\n console.error(`[FlowProxy] Cannot divide by zero`);\n return;\n }\n update(currentVal / amount);\n };\n }\n\n // Array Operations\n if (Array.isArray(currentVal)) {\n if (prop === \"_push\")\n return (item: any) => update([...currentVal, item]);\n if (prop === \"_pop\")\n return () => {\n if (currentVal.length === 0) {\n console.warn(`[FlowProxy] Cannot pop from empty array`);\n return;\n }\n update(currentVal.slice(0, -1));\n };\n if (prop === \"_shift\")\n return () => {\n if (currentVal.length === 0) {\n console.warn(`[FlowProxy] Cannot shift from empty array`);\n return;\n }\n update(currentVal.slice(1));\n };\n if (prop === \"_unshift\")\n return (item: any) => update([item, ...currentVal]);\n if (prop === \"_filter\")\n return (fn: any) => {\n if (typeof fn !== \"function\") {\n console.error(`[FlowProxy] Filter requires a function`);\n return;\n }\n try {\n update(currentVal.filter(fn));\n } catch (error) {\n console.error(`[FlowProxy] Filter function threw error:`, error);\n }\n };\n if (prop === \"_map\")\n return (fn: any) => {\n if (typeof fn !== \"function\") {\n console.error(`[FlowProxy] Map requires a function`);\n return;\n }\n try {\n update(currentVal.map(fn));\n } catch (error) {\n console.error(`[FlowProxy] Map function threw error:`, error);\n }\n };\n if (prop === \"_splice\")\n return (...args: any[]) => {\n try {\n const next = [...currentVal];\n const start = args[0] ?? 0;\n const deleteCount = args[1] ?? 0;\n\n if (\n typeof start !== \"number\" ||\n typeof deleteCount !== \"number\"\n ) {\n console.error(`[FlowProxy] Splice requires numeric arguments`);\n return;\n }\n\n next.splice(start, deleteCount, ...args.slice(2));\n update(next);\n } catch (error) {\n console.error(`[FlowProxy] Splice error:`, error);\n }\n };\n if (prop === \"_removeAt\")\n return (index: number) => {\n if (\n typeof index !== \"number\" ||\n index < 0 ||\n index >= currentVal.length\n ) {\n console.warn(`[FlowProxy] Invalid index: ${index}`);\n return;\n }\n update(currentVal.filter((_, i) => i !== index));\n };\n if (prop === \"_insertAt\")\n return (index: number, item: any) => {\n if (\n typeof index !== \"number\" ||\n index < 0 ||\n index > currentVal.length\n ) {\n console.warn(`[FlowProxy] Invalid index: ${index}`);\n return;\n }\n const next = [...currentVal];\n next.splice(index, 0, item);\n update(next);\n };\n }\n\n // String Operations\n if (typeof currentVal === \"string\") {\n if (prop === \"_append\")\n return (str: string) => {\n if (typeof str !== \"string\") {\n console.warn(`[FlowProxy] Append requires a string`);\n return;\n }\n update(currentVal + str);\n };\n if (prop === \"_prepend\")\n return (str: string) => {\n if (typeof str !== \"string\") {\n console.warn(`[FlowProxy] Prepend requires a string`);\n return;\n }\n update(str + currentVal);\n };\n if (prop === \"_uppercase\")\n return () => update(currentVal.toUpperCase());\n if (prop === \"_lowercase\")\n return () => update(currentVal.toLowerCase());\n if (prop === \"_trim\") return () => update(currentVal.trim());\n if (prop === \"_replace\")\n return (search: string | RegExp, replace: string) => {\n if (typeof replace !== \"string\") {\n console.warn(`[FlowProxy] Replace requires a string replacement`);\n return;\n }\n try {\n update(currentVal.replace(search, replace));\n } catch (error) {\n console.error(`[FlowProxy] Replace error:`, error);\n }\n };\n }\n\n // Object Operations\n if (\n currentVal !== null &&\n typeof currentVal === \"object\" &&\n !Array.isArray(currentVal)\n ) {\n if (prop === \"_merge\")\n return (obj: any) => {\n if (typeof obj !== \"object\" || obj === null || Array.isArray(obj)) {\n console.warn(`[FlowProxy] Merge requires an object`);\n return;\n }\n update({ ...currentVal, ...obj });\n };\n if (prop === \"_delete\")\n return (keyToDel: string) => {\n if (typeof keyToDel !== \"string\") {\n console.warn(`[FlowProxy] Delete requires a string key`);\n return;\n }\n if (!(keyToDel in currentVal)) {\n console.warn(`[FlowProxy] Key \"${keyToDel}\" does not exist`);\n return;\n }\n const next = { ...currentVal };\n delete next[keyToDel];\n update(next);\n };\n }\n\n /**\n * Internal helper to commit a value update to the store.\n */\n function update(val: any) {\n try {\n const currentState = store.get(key, undefined);\n const newState = setInPath(currentState, path, val);\n store.set(key, newState, options);\n } catch (error) {\n console.error(\n `[FlowProxy] Error updating value at path ${path.join(\".\")}:`,\n error,\n );\n throw error;\n }\n }\n\n // Recursive step: create a new proxy for the child property\n const nextVal = currentVal ? currentVal[prop] : undefined;\n return createDeepProxy(key, newPath, nextVal, options);\n },\n apply(_target, _thisArg, args) {\n if (typeof currentVal === \"function\") {\n return currentVal(...args);\n }\n console.warn(\n `[FlowProxy] Attempted to call a non-function value at path: ${path.join(\".\")}`,\n );\n },\n }) as unknown as TypeAwareOps<T>;\n}\n\n/**\n * Immutable update utility that sets a value at a specific path within an object/array.\n */\nexport function setInPath(obj: any, path: string[], value: any): any {\n if (path.length === 0) return value;\n\n const [head, ...tail] = path;\n\n if (Array.isArray(obj)) {\n const index = parseInt(head, 10);\n\n if (isNaN(index) || index < 0) {\n throw new Error(`[FlowProxy] Invalid array index: ${head}`);\n }\n\n const newArr = [...obj];\n\n if (index >= newArr.length) {\n newArr.length = index + 1;\n }\n\n newArr[index] = setInPath(newArr[index], tail, value);\n return newArr;\n }\n\n // Handle nested objects (including null/undefined recovery)\n const currentObj = obj ?? {};\n\n return {\n ...currentObj,\n [head]: setInPath(currentObj[head], tail, value),\n };\n}\n"],"names":["store"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"proxy.js","sources":["../../../src/proxy.ts"],"sourcesContent":["import type { FlowOptions, TypeAwareOps } from \"./types\";\nimport { store } from \"./store\";\n\n/**\n * Creates a deep proxy that provides type-specific atomic operations for a flow.\n * The proxy tracks its path within the state tree and maps access to specific update logic.\n */\nexport function createDeepProxy<T = any>(\n key: string,\n path: string[],\n currentVal: any,\n options: FlowOptions<any>,\n): TypeAwareOps<T> {\n return new Proxy(() => {}, {\n get(_target: any, prop: any) {\n if (typeof prop === \"symbol\") return undefined;\n\n const newPath = [...path, prop];\n\n /**\n * CORE COMMITTER\n * Always resolves the freshest state from the store before applying the path update.\n * This prevents \"stale state\" issues during mass sequential updates.\n */\n const commit = (val: any, forceful: boolean, skipEquality = false) => {\n try {\n const currentState = store.get(key, undefined);\n const newState = setInPath(currentState, path, val);\n store.set(key, newState, {\n ...options,\n force: forceful,\n skipEquality,\n });\n } catch (error) {\n console.error(\n `[FlowProxy] Commit error at path ${path.join(\".\")}:`,\n error,\n );\n throw error;\n }\n };\n\n // --- Meta-Operations ---\n\n // Read current value\n if (prop === \"_val\") return currentVal;\n\n // Generic property replacement (Forceful)\n if (prop === \"_set\") return (val: any) => commit(val, true);\n\n // Smart property replacement (Skip if equal)\n if (prop === \"_patch\") return (val: any) => commit(val, false);\n\n // Helper for type-specific operators\n const update = (val: any) => commit(val, false, true);\n\n // --- Type-Specific Atomic Operations ---\n\n // Number Operations\n if (typeof currentVal === \"number\") {\n if (prop === \"_increment\")\n return (amount = 1) => update(currentVal + amount);\n if (prop === \"_decrement\")\n return (amount = 1) => update(currentVal - amount);\n if (prop === \"_add\")\n return (amount: number) => update(currentVal + amount);\n if (prop === \"_subtract\")\n return (amount: number) => update(currentVal - amount);\n if (prop === \"_multiply\")\n return (amount: number) => update(currentVal * amount);\n if (prop === \"_divide\")\n return (amount: number) => {\n if (amount === 0) throw new Error(\"[FlowProxy] Division by zero\");\n update(currentVal / amount);\n };\n }\n\n // Array Operations\n if (Array.isArray(currentVal)) {\n if (prop === \"_push\")\n return (item: any) => update([...currentVal, item]);\n if (prop === \"_pop\") return () => update(currentVal.slice(0, -1));\n if (prop === \"_shift\") return () => update(currentVal.slice(1));\n if (prop === \"_unshift\")\n return (item: any) => update([item, ...currentVal]);\n if (prop === \"_filter\")\n return (fn: any) => update(currentVal.filter(fn));\n if (prop === \"_map\") return (fn: any) => update(currentVal.map(fn));\n if (prop === \"_removeAt\")\n return (index: number) =>\n update(currentVal.filter((_, i) => i !== index));\n if (prop === \"_insertAt\")\n return (index: number, item: any) => {\n const next = [...currentVal];\n next.splice(index, 0, item);\n update(next);\n };\n }\n\n // String Operations\n if (typeof currentVal === \"string\") {\n if (prop === \"_append\")\n return (str: string) => update(currentVal + str);\n if (prop === \"_prepend\")\n return (str: string) => update(str + currentVal);\n if (prop === \"_uppercase\")\n return () => update(currentVal.toUpperCase());\n if (prop === \"_lowercase\")\n return () => update(currentVal.toLowerCase());\n if (prop === \"_trim\") return () => update(currentVal.trim());\n }\n\n // Object Operations\n if (\n currentVal !== null &&\n typeof currentVal === \"object\" &&\n !Array.isArray(currentVal)\n ) {\n if (prop === \"_merge\")\n return (obj: any) => update({ ...currentVal, ...obj });\n if (prop === \"_delete\")\n return (keyToDel: string) => {\n const next = { ...currentVal };\n delete next[keyToDel];\n update(next);\n };\n }\n\n // Recursive step: create a new proxy for the child property\n const nextVal =\n currentVal !== null && currentVal !== undefined\n ? currentVal[prop]\n : undefined;\n return createDeepProxy(key, newPath, nextVal, options);\n },\n apply(_target, _thisArg, args) {\n if (typeof currentVal === \"function\") {\n return currentVal(...args);\n }\n console.warn(\n `[FlowProxy] Attempted to call a non-function value at path: ${path.join(\".\")}`,\n );\n },\n }) as unknown as TypeAwareOps<T>;\n}\n\n/**\n * Immutable update utility that sets a value at a specific path within an object/array.\n */\nexport function setInPath(obj: any, path: string[], value: any): any {\n if (path.length === 0) return value;\n\n const [head, ...tail] = path;\n\n if (Array.isArray(obj)) {\n const index = parseInt(head, 10);\n if (isNaN(index) || index < 0)\n throw new Error(`[FlowProxy] Invalid array index: ${head}`);\n const newArr = [...obj];\n if (index >= newArr.length) newArr.length = index + 1;\n newArr[index] = setInPath(newArr[index], tail, value);\n return newArr;\n }\n\n const currentObj = obj ?? {};\n return {\n ...currentObj,\n [head]: setInPath(currentObj[head], tail, value),\n };\n}\n"],"names":["store"],"mappings":"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"}
|
package/dist/cjs/src/store.js
CHANGED
|
@@ -144,15 +144,17 @@ class MemoryVault {
|
|
|
144
144
|
*/
|
|
145
145
|
set(key, newValue, options = {}) {
|
|
146
146
|
const prevState = this.vault.get(key);
|
|
147
|
-
let stateToSet =
|
|
147
|
+
let stateToSet = newValue;
|
|
148
148
|
// Apply synchronous middleware
|
|
149
149
|
if (options.middleware) {
|
|
150
150
|
for (const fn of options.middleware) {
|
|
151
151
|
stateToSet = fn(stateToSet);
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
|
-
// Skip update if state has not changed (Deep equality check) unless 'force' is true
|
|
155
|
-
if (!options.force &&
|
|
154
|
+
// Skip update if state has not changed (Deep equality check) unless 'force' or 'skipEquality' is true
|
|
155
|
+
if (!options.force &&
|
|
156
|
+
!options.skipEquality &&
|
|
157
|
+
deepEqual(prevState, stateToSet))
|
|
156
158
|
return;
|
|
157
159
|
if (options.debounce) {
|
|
158
160
|
this.debouncedSet(key, stateToSet, options);
|