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.
Files changed (52) hide show
  1. package/dist/cjs/index.js +2 -0
  2. package/dist/cjs/package.json +3 -0
  3. package/dist/cjs/src/index.js +66 -0
  4. package/dist/cjs/src/index.js.map +1 -0
  5. package/dist/cjs/src/proxy.js +289 -0
  6. package/dist/cjs/src/proxy.js.map +1 -0
  7. package/dist/cjs/src/store.js +373 -0
  8. package/dist/cjs/src/store.js.map +1 -0
  9. package/dist/esm/index.js +2 -0
  10. package/dist/esm/package.json +3 -0
  11. package/dist/esm/src/index.js +63 -0
  12. package/dist/esm/src/index.js.map +1 -0
  13. package/dist/esm/src/proxy.js +286 -0
  14. package/dist/esm/src/proxy.js.map +1 -0
  15. package/dist/esm/src/store.js +371 -0
  16. package/dist/esm/src/store.js.map +1 -0
  17. package/dist/index.d.ts +124 -0
  18. package/package.json +48 -8
  19. package/docs/api-reference.md +0 -46
  20. package/docs/architecture.md +0 -27
  21. package/docs/getting-started.md +0 -94
  22. package/src/index.ts +0 -82
  23. package/src/proxy.ts +0 -313
  24. package/src/store.ts +0 -324
  25. package/src/types.ts +0 -126
  26. package/test/README.md +0 -73
  27. package/test/eslint.config.js +0 -23
  28. package/test/index.html +0 -13
  29. package/test/package.json +0 -47
  30. package/test/postcss.config.mjs +0 -7
  31. package/test/public/vite.svg +0 -1
  32. package/test/src/App.css +0 -42
  33. package/test/src/App.tsx +0 -44
  34. package/test/src/assets/react.svg +0 -1
  35. package/test/src/components/CartDrawer.tsx +0 -79
  36. package/test/src/components/Navbar.tsx +0 -48
  37. package/test/src/components/Notifications.tsx +0 -27
  38. package/test/src/components/ProductList.tsx +0 -56
  39. package/test/src/flows.ts +0 -7
  40. package/test/src/index.css +0 -33
  41. package/test/src/layout/Layout.tsx +0 -68
  42. package/test/src/layout/ProtectedRoute.tsx +0 -19
  43. package/test/src/main.tsx +0 -10
  44. package/test/src/pages/LoginPage.tsx +0 -86
  45. package/test/src/pages/ProfilePage.tsx +0 -48
  46. package/test/src/pages/ShopPage.tsx +0 -54
  47. package/test/src/store/auth.ts +0 -39
  48. package/test/src/store/flows.ts +0 -74
  49. package/test/tsconfig.app.json +0 -31
  50. package/test/tsconfig.json +0 -7
  51. package/test/tsconfig.node.json +0 -29
  52. package/test/vite.config.ts +0 -16
@@ -0,0 +1,373 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Fast & Secure Memory Vault
5
+ * Ultra-performant in-memory store with deep cloning and batching
6
+ * NO PERSISTENCE - Pure memory for maximum safety and speed
7
+ */
8
+ class SecureVault {
9
+ constructor() {
10
+ Object.defineProperty(this, "vault", {
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true,
14
+ value: new Map()
15
+ });
16
+ Object.defineProperty(this, "initialValues", {
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true,
20
+ value: new Map()
21
+ });
22
+ Object.defineProperty(this, "listeners", {
23
+ enumerable: true,
24
+ configurable: true,
25
+ writable: true,
26
+ value: new Map()
27
+ });
28
+ Object.defineProperty(this, "histories", {
29
+ enumerable: true,
30
+ configurable: true,
31
+ writable: true,
32
+ value: new Map()
33
+ });
34
+ Object.defineProperty(this, "redoStacks", {
35
+ enumerable: true,
36
+ configurable: true,
37
+ writable: true,
38
+ value: new Map()
39
+ });
40
+ Object.defineProperty(this, "debounceTimers", {
41
+ enumerable: true,
42
+ configurable: true,
43
+ writable: true,
44
+ value: new Map()
45
+ });
46
+ Object.defineProperty(this, "batchQueue", {
47
+ enumerable: true,
48
+ configurable: true,
49
+ writable: true,
50
+ value: new Set()
51
+ });
52
+ Object.defineProperty(this, "batchScheduled", {
53
+ enumerable: true,
54
+ configurable: true,
55
+ writable: true,
56
+ value: false
57
+ });
58
+ this.setupSecureAccess();
59
+ this.setupAutoCleanup();
60
+ }
61
+ /**
62
+ * Protects the vault instance from global window inspection.
63
+ */
64
+ setupSecureAccess() {
65
+ if (typeof window !== "undefined") {
66
+ Object.defineProperty(window, "__FRACTO_VAULT__", {
67
+ get: () => "🔒 Access Denied: Secure Memory Instance",
68
+ configurable: false,
69
+ });
70
+ }
71
+ }
72
+ /**
73
+ * Periodically cleans up orphaned listeners.
74
+ */
75
+ setupAutoCleanup() {
76
+ if (typeof setInterval !== "undefined") {
77
+ setInterval(() => {
78
+ this.listeners.forEach((set, key) => {
79
+ if (set.size === 0 && !this.vault.has(key)) {
80
+ this.listeners.delete(key);
81
+ }
82
+ });
83
+ }, 300000); // 5 min
84
+ }
85
+ }
86
+ /**
87
+ * Lightweight but ultra-fast obfuscation for memory protection.
88
+ */
89
+ obfuscate(data) {
90
+ if (data === undefined)
91
+ return undefined;
92
+ try {
93
+ const str = JSON.stringify(data);
94
+ // Simple scrambling to prevent plain-text memory inspection
95
+ return { _: btoa(encodeURIComponent(str)), t: Date.now() };
96
+ }
97
+ catch {
98
+ return data;
99
+ }
100
+ }
101
+ /**
102
+ * Reverts obfuscation to retrieve original data structure.
103
+ */
104
+ deobfuscate(vaultItem) {
105
+ if (!vaultItem || typeof vaultItem !== "object" || !vaultItem._)
106
+ return vaultItem;
107
+ try {
108
+ const decoded = decodeURIComponent(atob(vaultItem._));
109
+ return JSON.parse(decoded);
110
+ }
111
+ catch {
112
+ return undefined;
113
+ }
114
+ }
115
+ /**
116
+ * Retrieves state from the vault. Initializes if a value is provided and the key is missing.
117
+ */
118
+ get(key, initialValue) {
119
+ if (!this.vault.has(key)) {
120
+ if (initialValue === undefined)
121
+ return undefined;
122
+ const cloned = deepClone(initialValue);
123
+ this.vault.set(key, this.obfuscate(cloned));
124
+ this.initialValues.set(key, deepClone(cloned));
125
+ this.histories.set(key, new CircularBuffer(100, [cloned]));
126
+ this.redoStacks.set(key, []);
127
+ }
128
+ const val = this.deobfuscate(this.vault.get(key));
129
+ return val === undefined ? initialValue : val;
130
+ }
131
+ /**
132
+ * Updates state in the vault with optional debouncing and middleware support.
133
+ */
134
+ set(key, newValue, options = {}) {
135
+ const prevState = this.deobfuscate(this.vault.get(key));
136
+ let stateToSet = deepClone(newValue);
137
+ // Apply synchronous middleware
138
+ if (options.middleware) {
139
+ for (const fn of options.middleware) {
140
+ stateToSet = fn(stateToSet);
141
+ }
142
+ }
143
+ // Skip update if state has not changed (Deep equality check)
144
+ if (deepEqual(prevState, stateToSet))
145
+ return;
146
+ if (options.debounce) {
147
+ this.debouncedSet(key, stateToSet, options);
148
+ return;
149
+ }
150
+ this.applySet(key, stateToSet, options);
151
+ }
152
+ /**
153
+ * Executes a debounced state update.
154
+ */
155
+ debouncedSet(key, value, options) {
156
+ const existing = this.debounceTimers.get(key);
157
+ if (existing)
158
+ clearTimeout(existing);
159
+ const timer = setTimeout(() => {
160
+ this.applySet(key, value, options);
161
+ this.debounceTimers.delete(key);
162
+ }, options.debounce);
163
+ this.debounceTimers.set(key, timer);
164
+ }
165
+ /**
166
+ * Core logic for applying a state update and managing history.
167
+ */
168
+ applySet(key, stateToSet, options) {
169
+ this.vault.set(key, this.obfuscate(stateToSet));
170
+ if (options.timeTravel) {
171
+ const history = this.histories.get(key);
172
+ if (history)
173
+ history.push(deepClone(stateToSet));
174
+ const redo = this.redoStacks.get(key);
175
+ if (redo)
176
+ redo.length = 0;
177
+ }
178
+ this.scheduleBatchNotify(key);
179
+ }
180
+ /**
181
+ * Schedules a microtask to batch notifications and optimize React renders.
182
+ */
183
+ scheduleBatchNotify(key) {
184
+ this.batchQueue.add(key);
185
+ if (this.batchScheduled)
186
+ return;
187
+ this.batchScheduled = true;
188
+ queueMicrotask(() => this.flushBatchNotify());
189
+ }
190
+ /**
191
+ * Flushes and notifies all queued listeners.
192
+ */
193
+ flushBatchNotify() {
194
+ const keys = Array.from(this.batchQueue);
195
+ this.batchQueue.clear();
196
+ this.batchScheduled = false;
197
+ keys.forEach((key) => this.notify(key));
198
+ }
199
+ /**
200
+ * Connects a listener to a specific flow key.
201
+ */
202
+ subscribe(key, listener) {
203
+ if (!this.listeners.has(key))
204
+ this.listeners.set(key, new Set());
205
+ this.listeners.get(key).add(listener);
206
+ return () => {
207
+ this.listeners.get(key)?.delete(listener);
208
+ };
209
+ }
210
+ /**
211
+ * Directly notifies all listeners of a specific key.
212
+ */
213
+ notify(key) {
214
+ this.listeners.get(key)?.forEach((l) => l());
215
+ }
216
+ /**
217
+ * Reverts the state to the previous version in history.
218
+ */
219
+ undo(key) {
220
+ const history = this.histories.get(key);
221
+ const redo = this.redoStacks.get(key);
222
+ if (history && history.length() > 1) {
223
+ const current = history.pop();
224
+ if (current)
225
+ redo?.push(current);
226
+ const prev = history.peek();
227
+ this.vault.set(key, this.obfuscate(prev));
228
+ this.notify(key);
229
+ }
230
+ }
231
+ /**
232
+ * Restores the state to the next version in the redo stack.
233
+ */
234
+ redo(key) {
235
+ const history = this.histories.get(key);
236
+ const redo = this.redoStacks.get(key);
237
+ if (redo && redo.length > 0) {
238
+ const next = redo.pop();
239
+ history?.push(next);
240
+ this.vault.set(key, this.obfuscate(next));
241
+ this.notify(key);
242
+ }
243
+ }
244
+ /**
245
+ * Resets a flow to its initial value.
246
+ */
247
+ reset(key) {
248
+ const initial = this.initialValues.get(key);
249
+ if (initial !== undefined)
250
+ this.set(key, initial);
251
+ }
252
+ getHistory(key) {
253
+ return this.histories.get(key)?.toArray() || [];
254
+ }
255
+ getRedoStack(key) {
256
+ return this.redoStacks.get(key) || [];
257
+ }
258
+ /**
259
+ * Clears the entire store and all timers.
260
+ */
261
+ clearAll() {
262
+ this.debounceTimers.forEach((t) => clearTimeout(t));
263
+ this.vault.clear();
264
+ this.initialValues.clear();
265
+ this.listeners.clear();
266
+ this.histories.clear();
267
+ this.redoStacks.clear();
268
+ }
269
+ }
270
+ /**
271
+ * Circular Buffer implementation for high-performance memory-efficient history.
272
+ */
273
+ class CircularBuffer {
274
+ constructor(maxSize, initial = []) {
275
+ Object.defineProperty(this, "buffer", {
276
+ enumerable: true,
277
+ configurable: true,
278
+ writable: true,
279
+ value: void 0
280
+ });
281
+ Object.defineProperty(this, "head", {
282
+ enumerable: true,
283
+ configurable: true,
284
+ writable: true,
285
+ value: 0
286
+ });
287
+ Object.defineProperty(this, "size", {
288
+ enumerable: true,
289
+ configurable: true,
290
+ writable: true,
291
+ value: 0
292
+ });
293
+ Object.defineProperty(this, "maxSize", {
294
+ enumerable: true,
295
+ configurable: true,
296
+ writable: true,
297
+ value: void 0
298
+ });
299
+ this.maxSize = maxSize;
300
+ this.buffer = new Array(maxSize);
301
+ initial.forEach((i) => this.push(i));
302
+ }
303
+ push(item) {
304
+ this.buffer[this.head] = item;
305
+ this.head = (this.head + 1) % this.maxSize;
306
+ if (this.size < this.maxSize)
307
+ this.size++;
308
+ }
309
+ pop() {
310
+ if (this.size <= 0)
311
+ return undefined;
312
+ this.head = (this.head - 1 + this.maxSize) % this.maxSize;
313
+ this.size--;
314
+ return this.buffer[this.head];
315
+ }
316
+ peek() {
317
+ return this.size > 0
318
+ ? this.buffer[(this.head - 1 + this.maxSize) % this.maxSize]
319
+ : undefined;
320
+ }
321
+ length() {
322
+ return this.size;
323
+ }
324
+ toArray() {
325
+ const res = [];
326
+ for (let i = 0; i < this.size; i++) {
327
+ res.push(this.buffer[(this.head - this.size + i + this.maxSize) % this.maxSize]);
328
+ }
329
+ return res;
330
+ }
331
+ }
332
+ /**
333
+ * High-performance deep cloning utility.
334
+ */
335
+ function deepClone(obj) {
336
+ if (obj === null || typeof obj !== "object")
337
+ return obj;
338
+ if (Array.isArray(obj))
339
+ return obj.map(deepClone);
340
+ const cloned = {};
341
+ for (const key in obj) {
342
+ if (Object.prototype.hasOwnProperty.call(obj, key))
343
+ cloned[key] = deepClone(obj[key]);
344
+ }
345
+ return cloned;
346
+ }
347
+ /**
348
+ * High-performance deep equality utility.
349
+ */
350
+ function deepEqual(a, b) {
351
+ if (a === b)
352
+ return true;
353
+ if (typeof a !== typeof b || a === null || b === null)
354
+ return false;
355
+ if (typeof a === "object") {
356
+ const keysA = Object.keys(a);
357
+ const keysB = Object.keys(b);
358
+ if (keysA.length !== keysB.length)
359
+ return false;
360
+ for (const key of keysA) {
361
+ if (!Object.prototype.hasOwnProperty.call(b, key))
362
+ return false;
363
+ if (!deepEqual(a[key], b[key]))
364
+ return false;
365
+ }
366
+ return true;
367
+ }
368
+ return false;
369
+ }
370
+ const store = new SecureVault();
371
+
372
+ exports.store = store;
373
+ //# 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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"}
@@ -0,0 +1,2 @@
1
+ // ESM re-export from src directory
2
+ export * from './src/index.js';
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -0,0 +1,63 @@
1
+ import { useState, useEffect, useCallback, useMemo } from 'react';
2
+ import { store } from './store.js';
3
+ import { createDeepProxy } from './proxy.js';
4
+
5
+ /**
6
+ * Defines a flow in a centralized manner.
7
+ * Allows defining the key, initial state, and options in a single reusable object.
8
+ */
9
+ function defineFlow(key, initial, options) {
10
+ return { key, initial, options };
11
+ }
12
+ /**
13
+ * Unique "All-in-One" hook to create or consume a FractoState flow.
14
+ * - If called with a FlowDefinition or an initial value: initializes the flow if it doesn't exist.
15
+ * - If called with just a key: connects to the existing flow.
16
+ *
17
+ * Returns a 2-element array: [state, toolbox]
18
+ * where toolbox contains { ops, set, undo, redo, history, ... }
19
+ */
20
+ function useFlow(keyOrDef, maybeInitialValue, options = {}) {
21
+ // Argument analysis to unify initialization and consumption
22
+ const isDef = typeof keyOrDef !== "string";
23
+ const key = isDef ? keyOrDef.key : keyOrDef;
24
+ // Initial data comes either from the definition or the direct argument
25
+ const initialValue = isDef ? keyOrDef.initial : maybeInitialValue;
26
+ // Merge options
27
+ const opt = isDef ? { ...keyOrDef.options, ...options } : options;
28
+ // Store access: store.get handles initialization if initialValue is present
29
+ const [state, setState] = useState(() => store.get(key, initialValue));
30
+ useEffect(() => {
31
+ // Subscribe to store changes
32
+ const unsub = store.subscribe(key, () => {
33
+ setState(store.get(key, initialValue));
34
+ });
35
+ return unsub;
36
+ }, [key, initialValue]);
37
+ const setManual = useCallback((val) => {
38
+ const current = store.get(key, initialValue);
39
+ const next = typeof val === "function" ? val(current) : val;
40
+ store.set(key, next, opt);
41
+ }, [key, initialValue, opt]);
42
+ const toolbox = useMemo(() => {
43
+ return {
44
+ ops: {
45
+ get self() {
46
+ return createDeepProxy(key, [], store.get(key, initialValue), opt);
47
+ },
48
+ },
49
+ set: setManual,
50
+ undo: () => store.undo(key),
51
+ redo: () => store.redo(key),
52
+ history: store.getHistory(key),
53
+ canUndo: store.getHistory(key).length > 1,
54
+ canRedo: store.getRedoStack(key).length > 0,
55
+ reset: () => store.reset(key),
56
+ cf: opt,
57
+ };
58
+ }, [key, opt, state, initialValue, setManual]);
59
+ return [state, toolbox];
60
+ }
61
+
62
+ export { defineFlow, useFlow };
63
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../../../src/index.ts"],"sourcesContent":["import { useState, useEffect, useCallback, useMemo } from \"react\";\nimport type { FlowOptions, FlowOperations, FlowDefinition } from \"./types\";\nimport { store } from \"./store\";\nimport { createDeepProxy } from \"./proxy\";\n\nexport * from \"./types\";\n\n/**\n * Defines a flow in a centralized manner.\n * Allows defining the key, initial state, and options in a single reusable object.\n */\nexport function defineFlow<T>(\n key: string,\n initial: T,\n options?: FlowOptions<T>,\n): FlowDefinition<T> {\n return { key, initial, options };\n}\n\n/**\n * Unique \"All-in-One\" hook to create or consume a FractoState flow.\n * - If called with a FlowDefinition or an initial value: initializes the flow if it doesn't exist.\n * - If called with just a key: connects to the existing flow.\n *\n * Returns a 2-element array: [state, toolbox]\n * where toolbox contains { ops, set, undo, redo, history, ... }\n */\nexport function useFlow<T>(\n keyOrDef: string | FlowDefinition<T>,\n maybeInitialValue?: T,\n options: FlowOptions<T> = {},\n): [T, FlowOperations<T>] {\n // Argument analysis to unify initialization and consumption\n const isDef = typeof keyOrDef !== \"string\";\n const key = isDef ? keyOrDef.key : keyOrDef;\n\n // Initial data comes either from the definition or the direct argument\n const initialValue = isDef ? keyOrDef.initial : maybeInitialValue;\n\n // Merge options\n const opt = isDef ? { ...keyOrDef.options, ...options } : options;\n\n // Store access: store.get handles initialization if initialValue is present\n const [state, setState] = useState(() => store.get(key, initialValue));\n\n useEffect(() => {\n // Subscribe to store changes\n const unsub = store.subscribe(key, () => {\n setState(store.get(key, initialValue));\n });\n return unsub;\n }, [key, initialValue]);\n\n const setManual = useCallback(\n (val: T | ((prev: T) => T)) => {\n const current = store.get(key, initialValue);\n const next = typeof val === \"function\" ? (val as any)(current) : val;\n store.set(key, next, opt);\n },\n [key, initialValue, opt],\n );\n\n const toolbox = useMemo((): FlowOperations<T> => {\n return {\n ops: {\n get self() {\n return createDeepProxy<T>(key, [], store.get(key, initialValue), opt);\n },\n },\n set: setManual,\n undo: () => store.undo(key),\n redo: () => store.redo(key),\n history: store.getHistory(key),\n canUndo: store.getHistory(key).length > 1,\n canRedo: store.getRedoStack(key).length > 0,\n reset: () => store.reset(key),\n cf: opt,\n };\n }, [key, opt, state, initialValue, setManual]);\n\n return [state, toolbox];\n}\n"],"names":[],"mappings":";;;;AAOA;;;AAGG;SACa,UAAU,CACxB,GAAW,EACX,OAAU,EACV,OAAwB,EAAA;AAExB,IAAA,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,OAAO,EAAE;AAClC;AAEA;;;;;;;AAOG;AACG,SAAU,OAAO,CACrB,QAAoC,EACpC,iBAAqB,EACrB,UAA0B,EAAE,EAAA;;AAG5B,IAAA,MAAM,KAAK,GAAG,OAAO,QAAQ,KAAK,QAAQ;AAC1C,IAAA,MAAM,GAAG,GAAG,KAAK,GAAG,QAAQ,CAAC,GAAG,GAAG,QAAQ;;AAG3C,IAAA,MAAM,YAAY,GAAG,KAAK,GAAG,QAAQ,CAAC,OAAO,GAAG,iBAAiB;;AAGjE,IAAA,MAAM,GAAG,GAAG,KAAK,GAAG,EAAE,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO;;IAGjE,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IAEtE,SAAS,CAAC,MAAK;;QAEb,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE,MAAK;YACtC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AACxC,QAAA,CAAC,CAAC;AACF,QAAA,OAAO,KAAK;AACd,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;AAEvB,IAAA,MAAM,SAAS,GAAG,WAAW,CAC3B,CAAC,GAAyB,KAAI;QAC5B,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC;AAC5C,QAAA,MAAM,IAAI,GAAG,OAAO,GAAG,KAAK,UAAU,GAAI,GAAW,CAAC,OAAO,CAAC,GAAG,GAAG;QACpE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,EAAE,GAAG,CAAC;IAC3B,CAAC,EACD,CAAC,GAAG,EAAE,YAAY,EAAE,GAAG,CAAC,CACzB;AAED,IAAA,MAAM,OAAO,GAAG,OAAO,CAAC,MAAwB;QAC9C,OAAO;AACL,YAAA,GAAG,EAAE;AACH,gBAAA,IAAI,IAAI,GAAA;AACN,oBAAA,OAAO,eAAe,CAAI,GAAG,EAAE,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,EAAE,GAAG,CAAC;gBACvE,CAAC;AACF,aAAA;AACD,YAAA,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;YAC3B,IAAI,EAAE,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;AAC3B,YAAA,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC;YAC9B,OAAO,EAAE,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC;YACzC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,MAAM,GAAG,CAAC;YAC3C,KAAK,EAAE,MAAM,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC;AAC7B,YAAA,EAAE,EAAE,GAAG;SACR;AACH,IAAA,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;AAE9C,IAAA,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC;AACzB;;;;"}