fractostate 1.0.1 → 1.0.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/dist/cjs/index.js +2 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/src/index.js +66 -0
- package/dist/cjs/src/index.js.map +1 -0
- package/dist/cjs/src/proxy.js +289 -0
- package/dist/cjs/src/proxy.js.map +1 -0
- package/dist/cjs/src/store.js +373 -0
- package/dist/cjs/src/store.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/src/index.js +63 -0
- package/dist/esm/src/index.js.map +1 -0
- package/dist/esm/src/proxy.js +286 -0
- package/dist/esm/src/proxy.js.map +1 -0
- package/dist/esm/src/store.js +371 -0
- package/dist/esm/src/store.js.map +1 -0
- package/dist/index.d.ts +124 -0
- package/package.json +48 -8
- package/docs/api-reference.md +0 -46
- package/docs/architecture.md +0 -27
- package/docs/getting-started.md +0 -94
- package/src/index.ts +0 -82
- package/src/proxy.ts +0 -313
- package/src/store.ts +0 -324
- package/src/types.ts +0 -126
- package/test/README.md +0 -73
- package/test/eslint.config.js +0 -23
- package/test/index.html +0 -13
- package/test/package.json +0 -47
- package/test/postcss.config.mjs +0 -7
- package/test/public/vite.svg +0 -1
- package/test/src/App.css +0 -42
- package/test/src/App.tsx +0 -44
- package/test/src/assets/react.svg +0 -1
- package/test/src/components/CartDrawer.tsx +0 -79
- package/test/src/components/Navbar.tsx +0 -48
- package/test/src/components/Notifications.tsx +0 -27
- package/test/src/components/ProductList.tsx +0 -56
- package/test/src/flows.ts +0 -7
- package/test/src/index.css +0 -33
- package/test/src/layout/Layout.tsx +0 -68
- package/test/src/layout/ProtectedRoute.tsx +0 -19
- package/test/src/main.tsx +0 -10
- package/test/src/pages/LoginPage.tsx +0 -86
- package/test/src/pages/ProfilePage.tsx +0 -48
- package/test/src/pages/ShopPage.tsx +0 -54
- package/test/src/store/auth.ts +0 -39
- package/test/src/store/flows.ts +0 -74
- package/test/tsconfig.app.json +0 -31
- package/test/tsconfig.json +0 -7
- package/test/tsconfig.node.json +0 -29
- package/test/vite.config.ts +0 -16
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fast & Secure Memory Vault
|
|
3
|
+
* Ultra-performant in-memory store with deep cloning and batching
|
|
4
|
+
* NO PERSISTENCE - Pure memory for maximum safety and speed
|
|
5
|
+
*/
|
|
6
|
+
class SecureVault {
|
|
7
|
+
constructor() {
|
|
8
|
+
Object.defineProperty(this, "vault", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
configurable: true,
|
|
11
|
+
writable: true,
|
|
12
|
+
value: new Map()
|
|
13
|
+
});
|
|
14
|
+
Object.defineProperty(this, "initialValues", {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true,
|
|
18
|
+
value: new Map()
|
|
19
|
+
});
|
|
20
|
+
Object.defineProperty(this, "listeners", {
|
|
21
|
+
enumerable: true,
|
|
22
|
+
configurable: true,
|
|
23
|
+
writable: true,
|
|
24
|
+
value: new Map()
|
|
25
|
+
});
|
|
26
|
+
Object.defineProperty(this, "histories", {
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
writable: true,
|
|
30
|
+
value: new Map()
|
|
31
|
+
});
|
|
32
|
+
Object.defineProperty(this, "redoStacks", {
|
|
33
|
+
enumerable: true,
|
|
34
|
+
configurable: true,
|
|
35
|
+
writable: true,
|
|
36
|
+
value: new Map()
|
|
37
|
+
});
|
|
38
|
+
Object.defineProperty(this, "debounceTimers", {
|
|
39
|
+
enumerable: true,
|
|
40
|
+
configurable: true,
|
|
41
|
+
writable: true,
|
|
42
|
+
value: new Map()
|
|
43
|
+
});
|
|
44
|
+
Object.defineProperty(this, "batchQueue", {
|
|
45
|
+
enumerable: true,
|
|
46
|
+
configurable: true,
|
|
47
|
+
writable: true,
|
|
48
|
+
value: new Set()
|
|
49
|
+
});
|
|
50
|
+
Object.defineProperty(this, "batchScheduled", {
|
|
51
|
+
enumerable: true,
|
|
52
|
+
configurable: true,
|
|
53
|
+
writable: true,
|
|
54
|
+
value: false
|
|
55
|
+
});
|
|
56
|
+
this.setupSecureAccess();
|
|
57
|
+
this.setupAutoCleanup();
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Protects the vault instance from global window inspection.
|
|
61
|
+
*/
|
|
62
|
+
setupSecureAccess() {
|
|
63
|
+
if (typeof window !== "undefined") {
|
|
64
|
+
Object.defineProperty(window, "__FRACTO_VAULT__", {
|
|
65
|
+
get: () => "🔒 Access Denied: Secure Memory Instance",
|
|
66
|
+
configurable: false,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Periodically cleans up orphaned listeners.
|
|
72
|
+
*/
|
|
73
|
+
setupAutoCleanup() {
|
|
74
|
+
if (typeof setInterval !== "undefined") {
|
|
75
|
+
setInterval(() => {
|
|
76
|
+
this.listeners.forEach((set, key) => {
|
|
77
|
+
if (set.size === 0 && !this.vault.has(key)) {
|
|
78
|
+
this.listeners.delete(key);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}, 300000); // 5 min
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Lightweight but ultra-fast obfuscation for memory protection.
|
|
86
|
+
*/
|
|
87
|
+
obfuscate(data) {
|
|
88
|
+
if (data === undefined)
|
|
89
|
+
return undefined;
|
|
90
|
+
try {
|
|
91
|
+
const str = JSON.stringify(data);
|
|
92
|
+
// Simple scrambling to prevent plain-text memory inspection
|
|
93
|
+
return { _: btoa(encodeURIComponent(str)), t: Date.now() };
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return data;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Reverts obfuscation to retrieve original data structure.
|
|
101
|
+
*/
|
|
102
|
+
deobfuscate(vaultItem) {
|
|
103
|
+
if (!vaultItem || typeof vaultItem !== "object" || !vaultItem._)
|
|
104
|
+
return vaultItem;
|
|
105
|
+
try {
|
|
106
|
+
const decoded = decodeURIComponent(atob(vaultItem._));
|
|
107
|
+
return JSON.parse(decoded);
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Retrieves state from the vault. Initializes if a value is provided and the key is missing.
|
|
115
|
+
*/
|
|
116
|
+
get(key, initialValue) {
|
|
117
|
+
if (!this.vault.has(key)) {
|
|
118
|
+
if (initialValue === undefined)
|
|
119
|
+
return undefined;
|
|
120
|
+
const cloned = deepClone(initialValue);
|
|
121
|
+
this.vault.set(key, this.obfuscate(cloned));
|
|
122
|
+
this.initialValues.set(key, deepClone(cloned));
|
|
123
|
+
this.histories.set(key, new CircularBuffer(100, [cloned]));
|
|
124
|
+
this.redoStacks.set(key, []);
|
|
125
|
+
}
|
|
126
|
+
const val = this.deobfuscate(this.vault.get(key));
|
|
127
|
+
return val === undefined ? initialValue : val;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Updates state in the vault with optional debouncing and middleware support.
|
|
131
|
+
*/
|
|
132
|
+
set(key, newValue, options = {}) {
|
|
133
|
+
const prevState = this.deobfuscate(this.vault.get(key));
|
|
134
|
+
let stateToSet = deepClone(newValue);
|
|
135
|
+
// Apply synchronous middleware
|
|
136
|
+
if (options.middleware) {
|
|
137
|
+
for (const fn of options.middleware) {
|
|
138
|
+
stateToSet = fn(stateToSet);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Skip update if state has not changed (Deep equality check)
|
|
142
|
+
if (deepEqual(prevState, stateToSet))
|
|
143
|
+
return;
|
|
144
|
+
if (options.debounce) {
|
|
145
|
+
this.debouncedSet(key, stateToSet, options);
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
this.applySet(key, stateToSet, options);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Executes a debounced state update.
|
|
152
|
+
*/
|
|
153
|
+
debouncedSet(key, value, options) {
|
|
154
|
+
const existing = this.debounceTimers.get(key);
|
|
155
|
+
if (existing)
|
|
156
|
+
clearTimeout(existing);
|
|
157
|
+
const timer = setTimeout(() => {
|
|
158
|
+
this.applySet(key, value, options);
|
|
159
|
+
this.debounceTimers.delete(key);
|
|
160
|
+
}, options.debounce);
|
|
161
|
+
this.debounceTimers.set(key, timer);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Core logic for applying a state update and managing history.
|
|
165
|
+
*/
|
|
166
|
+
applySet(key, stateToSet, options) {
|
|
167
|
+
this.vault.set(key, this.obfuscate(stateToSet));
|
|
168
|
+
if (options.timeTravel) {
|
|
169
|
+
const history = this.histories.get(key);
|
|
170
|
+
if (history)
|
|
171
|
+
history.push(deepClone(stateToSet));
|
|
172
|
+
const redo = this.redoStacks.get(key);
|
|
173
|
+
if (redo)
|
|
174
|
+
redo.length = 0;
|
|
175
|
+
}
|
|
176
|
+
this.scheduleBatchNotify(key);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Schedules a microtask to batch notifications and optimize React renders.
|
|
180
|
+
*/
|
|
181
|
+
scheduleBatchNotify(key) {
|
|
182
|
+
this.batchQueue.add(key);
|
|
183
|
+
if (this.batchScheduled)
|
|
184
|
+
return;
|
|
185
|
+
this.batchScheduled = true;
|
|
186
|
+
queueMicrotask(() => this.flushBatchNotify());
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Flushes and notifies all queued listeners.
|
|
190
|
+
*/
|
|
191
|
+
flushBatchNotify() {
|
|
192
|
+
const keys = Array.from(this.batchQueue);
|
|
193
|
+
this.batchQueue.clear();
|
|
194
|
+
this.batchScheduled = false;
|
|
195
|
+
keys.forEach((key) => this.notify(key));
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Connects a listener to a specific flow key.
|
|
199
|
+
*/
|
|
200
|
+
subscribe(key, listener) {
|
|
201
|
+
if (!this.listeners.has(key))
|
|
202
|
+
this.listeners.set(key, new Set());
|
|
203
|
+
this.listeners.get(key).add(listener);
|
|
204
|
+
return () => {
|
|
205
|
+
this.listeners.get(key)?.delete(listener);
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Directly notifies all listeners of a specific key.
|
|
210
|
+
*/
|
|
211
|
+
notify(key) {
|
|
212
|
+
this.listeners.get(key)?.forEach((l) => l());
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Reverts the state to the previous version in history.
|
|
216
|
+
*/
|
|
217
|
+
undo(key) {
|
|
218
|
+
const history = this.histories.get(key);
|
|
219
|
+
const redo = this.redoStacks.get(key);
|
|
220
|
+
if (history && history.length() > 1) {
|
|
221
|
+
const current = history.pop();
|
|
222
|
+
if (current)
|
|
223
|
+
redo?.push(current);
|
|
224
|
+
const prev = history.peek();
|
|
225
|
+
this.vault.set(key, this.obfuscate(prev));
|
|
226
|
+
this.notify(key);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Restores the state to the next version in the redo stack.
|
|
231
|
+
*/
|
|
232
|
+
redo(key) {
|
|
233
|
+
const history = this.histories.get(key);
|
|
234
|
+
const redo = this.redoStacks.get(key);
|
|
235
|
+
if (redo && redo.length > 0) {
|
|
236
|
+
const next = redo.pop();
|
|
237
|
+
history?.push(next);
|
|
238
|
+
this.vault.set(key, this.obfuscate(next));
|
|
239
|
+
this.notify(key);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* Resets a flow to its initial value.
|
|
244
|
+
*/
|
|
245
|
+
reset(key) {
|
|
246
|
+
const initial = this.initialValues.get(key);
|
|
247
|
+
if (initial !== undefined)
|
|
248
|
+
this.set(key, initial);
|
|
249
|
+
}
|
|
250
|
+
getHistory(key) {
|
|
251
|
+
return this.histories.get(key)?.toArray() || [];
|
|
252
|
+
}
|
|
253
|
+
getRedoStack(key) {
|
|
254
|
+
return this.redoStacks.get(key) || [];
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Clears the entire store and all timers.
|
|
258
|
+
*/
|
|
259
|
+
clearAll() {
|
|
260
|
+
this.debounceTimers.forEach((t) => clearTimeout(t));
|
|
261
|
+
this.vault.clear();
|
|
262
|
+
this.initialValues.clear();
|
|
263
|
+
this.listeners.clear();
|
|
264
|
+
this.histories.clear();
|
|
265
|
+
this.redoStacks.clear();
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Circular Buffer implementation for high-performance memory-efficient history.
|
|
270
|
+
*/
|
|
271
|
+
class CircularBuffer {
|
|
272
|
+
constructor(maxSize, initial = []) {
|
|
273
|
+
Object.defineProperty(this, "buffer", {
|
|
274
|
+
enumerable: true,
|
|
275
|
+
configurable: true,
|
|
276
|
+
writable: true,
|
|
277
|
+
value: void 0
|
|
278
|
+
});
|
|
279
|
+
Object.defineProperty(this, "head", {
|
|
280
|
+
enumerable: true,
|
|
281
|
+
configurable: true,
|
|
282
|
+
writable: true,
|
|
283
|
+
value: 0
|
|
284
|
+
});
|
|
285
|
+
Object.defineProperty(this, "size", {
|
|
286
|
+
enumerable: true,
|
|
287
|
+
configurable: true,
|
|
288
|
+
writable: true,
|
|
289
|
+
value: 0
|
|
290
|
+
});
|
|
291
|
+
Object.defineProperty(this, "maxSize", {
|
|
292
|
+
enumerable: true,
|
|
293
|
+
configurable: true,
|
|
294
|
+
writable: true,
|
|
295
|
+
value: void 0
|
|
296
|
+
});
|
|
297
|
+
this.maxSize = maxSize;
|
|
298
|
+
this.buffer = new Array(maxSize);
|
|
299
|
+
initial.forEach((i) => this.push(i));
|
|
300
|
+
}
|
|
301
|
+
push(item) {
|
|
302
|
+
this.buffer[this.head] = item;
|
|
303
|
+
this.head = (this.head + 1) % this.maxSize;
|
|
304
|
+
if (this.size < this.maxSize)
|
|
305
|
+
this.size++;
|
|
306
|
+
}
|
|
307
|
+
pop() {
|
|
308
|
+
if (this.size <= 0)
|
|
309
|
+
return undefined;
|
|
310
|
+
this.head = (this.head - 1 + this.maxSize) % this.maxSize;
|
|
311
|
+
this.size--;
|
|
312
|
+
return this.buffer[this.head];
|
|
313
|
+
}
|
|
314
|
+
peek() {
|
|
315
|
+
return this.size > 0
|
|
316
|
+
? this.buffer[(this.head - 1 + this.maxSize) % this.maxSize]
|
|
317
|
+
: undefined;
|
|
318
|
+
}
|
|
319
|
+
length() {
|
|
320
|
+
return this.size;
|
|
321
|
+
}
|
|
322
|
+
toArray() {
|
|
323
|
+
const res = [];
|
|
324
|
+
for (let i = 0; i < this.size; i++) {
|
|
325
|
+
res.push(this.buffer[(this.head - this.size + i + this.maxSize) % this.maxSize]);
|
|
326
|
+
}
|
|
327
|
+
return res;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* High-performance deep cloning utility.
|
|
332
|
+
*/
|
|
333
|
+
function deepClone(obj) {
|
|
334
|
+
if (obj === null || typeof obj !== "object")
|
|
335
|
+
return obj;
|
|
336
|
+
if (Array.isArray(obj))
|
|
337
|
+
return obj.map(deepClone);
|
|
338
|
+
const cloned = {};
|
|
339
|
+
for (const key in obj) {
|
|
340
|
+
if (Object.prototype.hasOwnProperty.call(obj, key))
|
|
341
|
+
cloned[key] = deepClone(obj[key]);
|
|
342
|
+
}
|
|
343
|
+
return cloned;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* High-performance deep equality utility.
|
|
347
|
+
*/
|
|
348
|
+
function deepEqual(a, b) {
|
|
349
|
+
if (a === b)
|
|
350
|
+
return true;
|
|
351
|
+
if (typeof a !== typeof b || a === null || b === null)
|
|
352
|
+
return false;
|
|
353
|
+
if (typeof a === "object") {
|
|
354
|
+
const keysA = Object.keys(a);
|
|
355
|
+
const keysB = Object.keys(b);
|
|
356
|
+
if (keysA.length !== keysB.length)
|
|
357
|
+
return false;
|
|
358
|
+
for (const key of keysA) {
|
|
359
|
+
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
360
|
+
return false;
|
|
361
|
+
if (!deepEqual(a[key], b[key]))
|
|
362
|
+
return false;
|
|
363
|
+
}
|
|
364
|
+
return true;
|
|
365
|
+
}
|
|
366
|
+
return false;
|
|
367
|
+
}
|
|
368
|
+
const store = new SecureVault();
|
|
369
|
+
|
|
370
|
+
export { store };
|
|
371
|
+
//# sourceMappingURL=store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sources":["../../../src/store.ts"],"sourcesContent":["import type { FlowOptions } from \"./types\";\n\n/**\n * Fast & Secure Memory Vault\n * Ultra-performant in-memory store with deep cloning and batching\n * NO PERSISTENCE - Pure memory for maximum safety and speed\n */\nclass SecureVault {\n private vault = new Map<string, any>();\n private initialValues = new Map<string, any>();\n private listeners = new Map<string, Set<() => void>>();\n private histories = new Map<string, CircularBuffer<any>>();\n private redoStacks = new Map<string, any[]>();\n private debounceTimers = new Map<string, number>();\n private batchQueue = new Set<string>();\n private batchScheduled = false;\n\n constructor() {\n this.setupSecureAccess();\n this.setupAutoCleanup();\n }\n\n /**\n * Protects the vault instance from global window inspection.\n */\n private setupSecureAccess() {\n if (typeof window !== \"undefined\") {\n Object.defineProperty(window, \"__FRACTO_VAULT__\", {\n get: () => \"🔒 Access Denied: Secure Memory Instance\",\n configurable: false,\n });\n }\n }\n\n /**\n * Periodically cleans up orphaned listeners.\n */\n private setupAutoCleanup() {\n if (typeof setInterval !== \"undefined\") {\n setInterval(() => {\n this.listeners.forEach((set, key) => {\n if (set.size === 0 && !this.vault.has(key)) {\n this.listeners.delete(key);\n }\n });\n }, 300000); // 5 min\n }\n }\n\n /**\n * Lightweight but ultra-fast obfuscation for memory protection.\n */\n private obfuscate(data: any): any {\n if (data === undefined) return undefined;\n try {\n const str = JSON.stringify(data);\n // Simple scrambling to prevent plain-text memory inspection\n return { _: btoa(encodeURIComponent(str)), t: Date.now() };\n } catch {\n return data;\n }\n }\n\n /**\n * Reverts obfuscation to retrieve original data structure.\n */\n private deobfuscate(vaultItem: any): any {\n if (!vaultItem || typeof vaultItem !== \"object\" || !vaultItem._)\n return vaultItem;\n try {\n const decoded = decodeURIComponent(atob(vaultItem._));\n return JSON.parse(decoded);\n } catch {\n return undefined;\n }\n }\n\n /**\n * Retrieves state from the vault. Initializes if a value is provided and the key is missing.\n */\n get(key: string, initialValue?: any) {\n if (!this.vault.has(key)) {\n if (initialValue === undefined) return undefined;\n\n const cloned = deepClone(initialValue);\n this.vault.set(key, this.obfuscate(cloned));\n this.initialValues.set(key, deepClone(cloned));\n this.histories.set(key, new CircularBuffer(100, [cloned]));\n this.redoStacks.set(key, []);\n }\n\n const val = this.deobfuscate(this.vault.get(key));\n return val === undefined ? initialValue : val;\n }\n\n /**\n * Updates state in the vault with optional debouncing and middleware support.\n */\n set(key: string, newValue: any, options: FlowOptions = {}) {\n const prevState = this.deobfuscate(this.vault.get(key));\n let stateToSet = deepClone(newValue);\n\n // Apply synchronous middleware\n if (options.middleware) {\n for (const fn of options.middleware) {\n stateToSet = fn(stateToSet);\n }\n }\n\n // Skip update if state has not changed (Deep equality check)\n if (deepEqual(prevState, stateToSet)) return;\n\n if (options.debounce) {\n this.debouncedSet(key, stateToSet, options);\n return;\n }\n\n this.applySet(key, stateToSet, options);\n }\n\n /**\n * Executes a debounced state update.\n */\n private debouncedSet(key: string, value: any, options: FlowOptions) {\n const existing = this.debounceTimers.get(key);\n if (existing) clearTimeout(existing);\n\n const timer = setTimeout(() => {\n this.applySet(key, value, options);\n this.debounceTimers.delete(key);\n }, options.debounce);\n\n this.debounceTimers.set(key, timer as any);\n }\n\n /**\n * Core logic for applying a state update and managing history.\n */\n private applySet(key: string, stateToSet: any, options: FlowOptions) {\n this.vault.set(key, this.obfuscate(stateToSet));\n\n if (options.timeTravel) {\n const history = this.histories.get(key);\n if (history) history.push(deepClone(stateToSet));\n const redo = this.redoStacks.get(key);\n if (redo) redo.length = 0;\n }\n\n this.scheduleBatchNotify(key);\n }\n\n /**\n * Schedules a microtask to batch notifications and optimize React renders.\n */\n private scheduleBatchNotify(key: string) {\n this.batchQueue.add(key);\n if (this.batchScheduled) return;\n this.batchScheduled = true;\n queueMicrotask(() => this.flushBatchNotify());\n }\n\n /**\n * Flushes and notifies all queued listeners.\n */\n private flushBatchNotify() {\n const keys = Array.from(this.batchQueue);\n this.batchQueue.clear();\n this.batchScheduled = false;\n keys.forEach((key) => this.notify(key));\n }\n\n /**\n * Connects a listener to a specific flow key.\n */\n subscribe(key: string, listener: () => void) {\n if (!this.listeners.has(key)) this.listeners.set(key, new Set());\n this.listeners.get(key)!.add(listener);\n return () => {\n this.listeners.get(key)?.delete(listener);\n };\n }\n\n /**\n * Directly notifies all listeners of a specific key.\n */\n private notify(key: string) {\n this.listeners.get(key)?.forEach((l) => l());\n }\n\n /**\n * Reverts the state to the previous version in history.\n */\n undo(key: string) {\n const history = this.histories.get(key);\n const redo = this.redoStacks.get(key);\n if (history && history.length() > 1) {\n const current = history.pop();\n if (current) redo?.push(current);\n const prev = history.peek();\n this.vault.set(key, this.obfuscate(prev));\n this.notify(key);\n }\n }\n\n /**\n * Restores the state to the next version in the redo stack.\n */\n redo(key: string) {\n const history = this.histories.get(key);\n const redo = this.redoStacks.get(key);\n if (redo && redo.length > 0) {\n const next = redo.pop();\n history?.push(next);\n this.vault.set(key, this.obfuscate(next));\n this.notify(key);\n }\n }\n\n /**\n * Resets a flow to its initial value.\n */\n reset(key: string) {\n const initial = this.initialValues.get(key);\n if (initial !== undefined) this.set(key, initial);\n }\n\n getHistory(key: string) {\n return this.histories.get(key)?.toArray() || [];\n }\n getRedoStack(key: string) {\n return this.redoStacks.get(key) || [];\n }\n\n /**\n * Clears the entire store and all timers.\n */\n clearAll() {\n this.debounceTimers.forEach((t) => clearTimeout(t));\n this.vault.clear();\n this.initialValues.clear();\n this.listeners.clear();\n this.histories.clear();\n this.redoStacks.clear();\n }\n}\n\n/**\n * Circular Buffer implementation for high-performance memory-efficient history.\n */\nclass CircularBuffer<T> {\n private buffer: T[];\n private head = 0;\n private size = 0;\n private maxSize: number;\n\n constructor(maxSize: number, initial: T[] = []) {\n this.maxSize = maxSize;\n this.buffer = new Array(maxSize);\n initial.forEach((i) => this.push(i));\n }\n push(item: T) {\n this.buffer[this.head] = item;\n this.head = (this.head + 1) % this.maxSize;\n if (this.size < this.maxSize) this.size++;\n }\n pop(): T | undefined {\n if (this.size <= 0) return undefined;\n this.head = (this.head - 1 + this.maxSize) % this.maxSize;\n this.size--;\n return this.buffer[this.head];\n }\n peek(): T | undefined {\n return this.size > 0\n ? this.buffer[(this.head - 1 + this.maxSize) % this.maxSize]\n : undefined;\n }\n length() {\n return this.size;\n }\n toArray(): T[] {\n const res = [];\n for (let i = 0; i < this.size; i++) {\n res.push(\n this.buffer[(this.head - this.size + i + this.maxSize) % this.maxSize],\n );\n }\n return res;\n }\n}\n\n/**\n * High-performance deep cloning utility.\n */\nfunction deepClone<T>(obj: T): T {\n if (obj === null || typeof obj !== \"object\") return obj;\n if (Array.isArray(obj)) return obj.map(deepClone) as any;\n const cloned: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key))\n cloned[key] = deepClone(obj[key]);\n }\n return cloned;\n}\n\n/**\n * High-performance deep equality utility.\n */\nfunction deepEqual(a: any, b: any): boolean {\n if (a === b) return true;\n if (typeof a !== typeof b || a === null || b === null) return false;\n if (typeof a === \"object\") {\n const keysA = Object.keys(a);\n const keysB = Object.keys(b);\n if (keysA.length !== keysB.length) return false;\n for (const key of keysA) {\n if (!Object.prototype.hasOwnProperty.call(b, key)) return false;\n if (!deepEqual(a[key], b[key])) return false;\n }\n return true;\n }\n return false;\n}\n\nexport const store = new SecureVault();\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
interface FlowOptions<T = any> {
|
|
2
|
+
/** Enable history tracking for undo/redo functionality */
|
|
3
|
+
timeTravel?: boolean;
|
|
4
|
+
/** Maximum number of states to keep in history (default: 100) */
|
|
5
|
+
maxHistory?: number;
|
|
6
|
+
/** Debounce state updates in milliseconds */
|
|
7
|
+
debounce?: number;
|
|
8
|
+
/** Array of functions to transform state before it is saved */
|
|
9
|
+
middleware?: Array<(state: T) => T>;
|
|
10
|
+
}
|
|
11
|
+
type BaseOps<T> = {
|
|
12
|
+
/** Replaces the entire value at this path */
|
|
13
|
+
set: (value: T) => void;
|
|
14
|
+
};
|
|
15
|
+
type NumberOps = BaseOps<number> & {
|
|
16
|
+
/** Adds 1 (or amount) to the number */
|
|
17
|
+
increment: (amount?: number) => void;
|
|
18
|
+
/** Subtracts 1 (or amount) from the number */
|
|
19
|
+
decrement: (amount?: number) => void;
|
|
20
|
+
/** Adds the given amount */
|
|
21
|
+
add: (amount: number) => void;
|
|
22
|
+
/** Subtracts the given amount */
|
|
23
|
+
subtract: (amount: number) => void;
|
|
24
|
+
/** Multiplies by the given amount */
|
|
25
|
+
multiply: (amount: number) => void;
|
|
26
|
+
/** Divides by the given amount */
|
|
27
|
+
divide: (amount: number) => void;
|
|
28
|
+
};
|
|
29
|
+
type StringOps = BaseOps<string> & {
|
|
30
|
+
/** Appends a string to the end */
|
|
31
|
+
append: (str: string) => void;
|
|
32
|
+
/** Prepends a string to the beginning */
|
|
33
|
+
prepend: (str: string) => void;
|
|
34
|
+
/** Converts to uppercase */
|
|
35
|
+
uppercase: () => void;
|
|
36
|
+
/** Converts to lowercase */
|
|
37
|
+
lowercase: () => void;
|
|
38
|
+
/** Removes whitespace from both ends */
|
|
39
|
+
trim: () => void;
|
|
40
|
+
/** Replaces a substring or regex match */
|
|
41
|
+
replace: (search: string | RegExp, replace: string) => void;
|
|
42
|
+
};
|
|
43
|
+
type ArrayOps<T> = BaseOps<T[]> & {
|
|
44
|
+
/** Appends an item to the end */
|
|
45
|
+
push: (item: T) => void;
|
|
46
|
+
/** Removes the last item */
|
|
47
|
+
pop: () => void;
|
|
48
|
+
/** Removes the first item */
|
|
49
|
+
shift: () => void;
|
|
50
|
+
/** Adds an item to the beginning */
|
|
51
|
+
unshift: (item: T) => void;
|
|
52
|
+
/** Filters the array based on a predicate */
|
|
53
|
+
filter: (predicate: (item: T, index: number) => boolean) => void;
|
|
54
|
+
/** Transforms each item in the array */
|
|
55
|
+
map: (fn: (item: T, index: number) => T) => void;
|
|
56
|
+
/** Adds/removes items at a specific index */
|
|
57
|
+
splice: (start: number, deleteCount?: number, ...items: T[]) => void;
|
|
58
|
+
/** Removes the item at the specified index */
|
|
59
|
+
removeAt: (index: number) => void;
|
|
60
|
+
/** Inserts an item at the specified index */
|
|
61
|
+
insertAt: (index: number, item: T) => void;
|
|
62
|
+
};
|
|
63
|
+
type ObjectOps<T> = BaseOps<T> & {
|
|
64
|
+
/** Merges the given object into the current one */
|
|
65
|
+
merge: (partial: Partial<T>) => void;
|
|
66
|
+
/** Deletes a property from the object */
|
|
67
|
+
delete: (key: keyof T) => void;
|
|
68
|
+
} & {
|
|
69
|
+
[K in keyof T]-?: TypeAwareOps<T[K]>;
|
|
70
|
+
};
|
|
71
|
+
type BooleanOps = BaseOps<boolean> & {
|
|
72
|
+
/** Inverts the current boolean value */
|
|
73
|
+
toggle: () => void;
|
|
74
|
+
};
|
|
75
|
+
type TypeAwareOps<T> = T extends number ? NumberOps : T extends string ? StringOps : T extends boolean ? BooleanOps : T extends Array<infer U> ? ArrayOps<U> : T extends object ? ObjectOps<T> : BaseOps<T>;
|
|
76
|
+
interface FlowDefinition<T> {
|
|
77
|
+
key: string;
|
|
78
|
+
initial: T;
|
|
79
|
+
options?: FlowOptions<T>;
|
|
80
|
+
}
|
|
81
|
+
interface FlowOperations<T> {
|
|
82
|
+
ops: {
|
|
83
|
+
/**
|
|
84
|
+
* Recursive, type-aware proxy that provides surgical atomic operations
|
|
85
|
+
* tailored to the shape of your state. It allows direct-like manipulation
|
|
86
|
+
* that is internally processed as immutable updates.
|
|
87
|
+
*/
|
|
88
|
+
self: TypeAwareOps<T>;
|
|
89
|
+
};
|
|
90
|
+
/** Reverts to the previous state in history */
|
|
91
|
+
undo: () => void;
|
|
92
|
+
/** Restores the previously undone state */
|
|
93
|
+
redo: () => void;
|
|
94
|
+
/** Array of past states (requires timeTravel: true) */
|
|
95
|
+
history: T[];
|
|
96
|
+
/** Whether there is a previous state to undo */
|
|
97
|
+
canUndo: boolean;
|
|
98
|
+
/** Whether there is a next state to redo */
|
|
99
|
+
canRedo: boolean;
|
|
100
|
+
/** Manually sets the entire state or applies a transformation function */
|
|
101
|
+
set: (val: T | ((prev: T) => T)) => void;
|
|
102
|
+
/** Restores the state to its initial value */
|
|
103
|
+
reset: () => void;
|
|
104
|
+
/** Current flow configuration options */
|
|
105
|
+
cf: FlowOptions<T>;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Defines a flow in a centralized manner.
|
|
110
|
+
* Allows defining the key, initial state, and options in a single reusable object.
|
|
111
|
+
*/
|
|
112
|
+
declare function defineFlow<T>(key: string, initial: T, options?: FlowOptions<T>): FlowDefinition<T>;
|
|
113
|
+
/**
|
|
114
|
+
* Unique "All-in-One" hook to create or consume a FractoState flow.
|
|
115
|
+
* - If called with a FlowDefinition or an initial value: initializes the flow if it doesn't exist.
|
|
116
|
+
* - If called with just a key: connects to the existing flow.
|
|
117
|
+
*
|
|
118
|
+
* Returns a 2-element array: [state, toolbox]
|
|
119
|
+
* where toolbox contains { ops, set, undo, redo, history, ... }
|
|
120
|
+
*/
|
|
121
|
+
declare function useFlow<T>(keyOrDef: string | FlowDefinition<T>, maybeInitialValue?: T, options?: FlowOptions<T>): [T, FlowOperations<T>];
|
|
122
|
+
|
|
123
|
+
export { defineFlow, useFlow };
|
|
124
|
+
export type { ArrayOps, BaseOps, BooleanOps, FlowDefinition, FlowOperations, FlowOptions, NumberOps, ObjectOps, StringOps, TypeAwareOps };
|
package/package.json
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
{
|
|
2
|
-
"author":
|
|
2
|
+
"author": {
|
|
3
|
+
"name": "Nehonix",
|
|
4
|
+
"url": "https://nehonix.com",
|
|
5
|
+
"email": "support@team.nehonix.com"
|
|
6
|
+
},
|
|
3
7
|
"dependencies": {
|
|
4
8
|
"vite": "^7.3.1"
|
|
5
9
|
},
|
|
@@ -8,9 +12,21 @@
|
|
|
8
12
|
"@types/react": "^19.2.9",
|
|
9
13
|
"react": "^18.0.0",
|
|
10
14
|
"tsup": "^8.0.0",
|
|
11
|
-
"typescript": "^5.
|
|
12
|
-
"vitest": "^1.0.0"
|
|
15
|
+
"typescript": "^5.9.3",
|
|
16
|
+
"vitest": "^1.0.0",
|
|
17
|
+
"@rollup/plugin-commonjs": "^29.0.0",
|
|
18
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
19
|
+
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
20
|
+
"@rollup/plugin-typescript": "^12.3.0",
|
|
21
|
+
"rollup-plugin-dts": "^6.3.0",
|
|
22
|
+
"tsc": "^2.0.4",
|
|
23
|
+
"tslib": "^2.8.1"
|
|
13
24
|
},
|
|
25
|
+
"files": [
|
|
26
|
+
"dist",
|
|
27
|
+
"LICENSE",
|
|
28
|
+
"README.md"
|
|
29
|
+
],
|
|
14
30
|
"keywords": [
|
|
15
31
|
"react",
|
|
16
32
|
"state",
|
|
@@ -20,18 +36,42 @@
|
|
|
20
36
|
"hooks"
|
|
21
37
|
],
|
|
22
38
|
"license": "NOSL v1.0",
|
|
23
|
-
"main": "dist/index.js",
|
|
24
|
-
"module": "dist/index.
|
|
39
|
+
"main": "dist/cjs/index.js",
|
|
40
|
+
"module": "dist/esm/index.js",
|
|
25
41
|
"name": "fractostate",
|
|
42
|
+
"types": "dist/index.d.ts",
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"types": "./dist/index.d.ts",
|
|
46
|
+
"import": {
|
|
47
|
+
"types": "./dist/index.d.ts",
|
|
48
|
+
"default": "./dist/esm/index.js"
|
|
49
|
+
},
|
|
50
|
+
"require": {
|
|
51
|
+
"types": "./dist/index.d.ts",
|
|
52
|
+
"default": "./dist/cjs/index.js"
|
|
53
|
+
},
|
|
54
|
+
"node": {
|
|
55
|
+
"import": "./dist/esm/index.js",
|
|
56
|
+
"require": "./dist/cjs/index.js"
|
|
57
|
+
},
|
|
58
|
+
"default": "./dist/cjs/index.js"
|
|
59
|
+
},
|
|
60
|
+
"./package.json": "./package.json"
|
|
61
|
+
},
|
|
26
62
|
"peerDependencies": {
|
|
27
63
|
"react": ">=16.8.0"
|
|
28
64
|
},
|
|
65
|
+
"repository": {
|
|
66
|
+
"type": "git",
|
|
67
|
+
"url": "https://github.com/Nehonix-Team/FractoState.git"
|
|
68
|
+
},
|
|
69
|
+
"type": "module",
|
|
29
70
|
"scripts": {
|
|
30
|
-
"build": "
|
|
71
|
+
"build": "rollup -c",
|
|
31
72
|
"dev": "tsup src/index.ts --watch --dts --format esm,cjs",
|
|
32
73
|
"lint": "eslint src",
|
|
33
74
|
"test": "vitest"
|
|
34
75
|
},
|
|
35
|
-
"
|
|
36
|
-
"version": "1.0.1"
|
|
76
|
+
"version": "1.0.2"
|
|
37
77
|
}
|
package/docs/api-reference.md
DELETED
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
# API Reference
|
|
2
|
-
|
|
3
|
-
A detailed breakdown of the FractoState interface.
|
|
4
|
-
|
|
5
|
-
## defineFlow<T>(key, initialValue, options?)
|
|
6
|
-
|
|
7
|
-
Creates a reusable definition for a state flow.
|
|
8
|
-
|
|
9
|
-
- **key**: A unique string identifying the flow in the global vault.
|
|
10
|
-
- **initialValue**: The default state structure.
|
|
11
|
-
- **options**: Configuration object (timeTravel, debounce, middleware).
|
|
12
|
-
|
|
13
|
-
Returns a `FlowDefinition<T>`.
|
|
14
|
-
|
|
15
|
-
## useFlow<T>(identifier, initialValue?, options?)
|
|
16
|
-
|
|
17
|
-
The primary hook to interact with the state vault.
|
|
18
|
-
|
|
19
|
-
- **identifier**: Either a string `key` or a `FlowDefinition`.
|
|
20
|
-
- **initialValue**: Required only if identifier is a string and the flow hasn't been initialized.
|
|
21
|
-
- **options**: Overrides for the flow configuration.
|
|
22
|
-
|
|
23
|
-
Returns `[state, toolbox]`.
|
|
24
|
-
|
|
25
|
-
### The Toolbox Object
|
|
26
|
-
|
|
27
|
-
The second element returned by `useFlow` provides powerful control:
|
|
28
|
-
|
|
29
|
-
- **ops.self**: A recursive proxy providing type-aware methods:
|
|
30
|
-
- **Numbers**: `increment()`, `decrement()`, `add()`, `multiply()`, `divide()`, `set()`.
|
|
31
|
-
- **Strings**: `append()`, `prepend()`, `uppercase()`, `replace()`, `set()`.
|
|
32
|
-
- **Arrays**: `push()`, `pop()`, `filter()`, `map()`, `insertAt()`, `removeAt()`, `set()`.
|
|
33
|
-
- **Objects**: `merge()`, `delete()`, `set()`.
|
|
34
|
-
- **set(value | fn)**: Manually sets the entire state or applies a transformation function.
|
|
35
|
-
- **undo()**: Reverts to the previous state.
|
|
36
|
-
- **redo()**: Restores the previously undone state.
|
|
37
|
-
- **history**: The full history buffer of the flow.
|
|
38
|
-
- **canUndo / canRedo**: Boolean flags for UI control.
|
|
39
|
-
- **reset()**: Restores the state to its defined initial value.
|
|
40
|
-
|
|
41
|
-
## FlowOptions
|
|
42
|
-
|
|
43
|
-
- **timeTravel**: Enable undo/redo functionality (default: false).
|
|
44
|
-
- **maxHistory**: Maximum number of states maintained in the circular buffer (default: 100).
|
|
45
|
-
- **debounce**: Delay in milliseconds before state updates are applied.
|
|
46
|
-
- **middleware**: Array of functions `(state) => state` to intercept and transform values during updates.
|