fractostate 4.0.1 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. package/dist/cjs/index.js +22 -7
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/src/devtools/DevToolsFlow.js +21 -19
  4. package/dist/cjs/src/devtools/DevToolsFlow.js.map +1 -1
  5. package/dist/cjs/src/devtools/FractoDevTools.css.js +1 -1
  6. package/dist/cjs/src/devtools/FractoDevTools.js +40 -16
  7. package/dist/cjs/src/devtools/FractoDevTools.js.map +1 -1
  8. package/dist/cjs/src/devtools/MapUtils.js +31 -0
  9. package/dist/cjs/src/devtools/MapUtils.js.map +1 -0
  10. package/dist/cjs/src/devtools/MentalMap.css.js +10 -0
  11. package/dist/cjs/src/devtools/MentalMap.css.js.map +1 -0
  12. package/dist/cjs/src/devtools/MentalMap.js +220 -0
  13. package/dist/cjs/src/devtools/MentalMap.js.map +1 -0
  14. package/dist/cjs/src/proxy.js +41 -25
  15. package/dist/cjs/src/proxy.js.map +1 -1
  16. package/dist/cjs/src/store.js +61 -7
  17. package/dist/cjs/src/store.js.map +1 -1
  18. package/dist/devtools.d.ts +6 -0
  19. package/dist/esm/index.js +22 -7
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/src/devtools/DevToolsFlow.js +21 -19
  22. package/dist/esm/src/devtools/DevToolsFlow.js.map +1 -1
  23. package/dist/esm/src/devtools/FractoDevTools.css.js +1 -1
  24. package/dist/esm/src/devtools/FractoDevTools.js +42 -18
  25. package/dist/esm/src/devtools/FractoDevTools.js.map +1 -1
  26. package/dist/esm/src/devtools/MapUtils.js +27 -0
  27. package/dist/esm/src/devtools/MapUtils.js.map +1 -0
  28. package/dist/esm/src/devtools/MentalMap.css.js +8 -0
  29. package/dist/esm/src/devtools/MentalMap.css.js.map +1 -0
  30. package/dist/esm/src/devtools/MentalMap.js +218 -0
  31. package/dist/esm/src/devtools/MentalMap.js.map +1 -0
  32. package/dist/esm/src/proxy.js +41 -25
  33. package/dist/esm/src/proxy.js.map +1 -1
  34. package/dist/esm/src/store.js +61 -7
  35. package/dist/esm/src/store.js.map +1 -1
  36. package/dist/index.d.ts +8 -16
  37. package/dist/plugins.d.ts +1 -1
  38. package/dist/types-Cazb5ndN.d.ts +177 -0
  39. package/dist/types-sg0rN5WO.d.ts +172 -0
  40. package/package.json +22 -9
package/dist/cjs/index.js CHANGED
@@ -69,7 +69,7 @@ function useFlow(keyOrDef, initial, options) {
69
69
  ? keyOrDef.source.initial
70
70
  : initial;
71
71
  const flowOptions = isDef
72
- ? { ...(keyOrDef.options || {}), ...options }
72
+ ? { ...(keyOrDef.options || {}), ...(initial || {}) }
73
73
  : isDerived
74
74
  ? keyOrDef.source.options
75
75
  : options;
@@ -81,20 +81,27 @@ function useFlow(keyOrDef, initial, options) {
81
81
  return store.store.subscribe(key, () => {
82
82
  const raw = store.store.get(key, initialVal);
83
83
  setState(isDerived ? keyOrDef.selector(raw) : raw);
84
- });
85
- }, [key, isDerived]);
84
+ }, flowOptions?.name || flowOptions?.actor);
85
+ }, [key, isDerived, flowOptions?.name, flowOptions?.actor]);
86
86
  const toolbox = react.useMemo(() => {
87
87
  if (isDerived)
88
88
  return {};
89
+ const boundActions = {};
89
90
  const defaultOps = {
90
91
  get self() {
91
- return proxy.createDeepProxy(key, [], store.store.get(key, initialVal), flowOptions);
92
+ return proxy.createDeepProxy(key, [], store.store.get(key, initialVal), {
93
+ ...flowOptions,
94
+ actions: boundActions,
95
+ actor: flowOptions?.name || flowOptions?.actor,
96
+ });
92
97
  },
93
98
  get state() {
94
99
  return store.store.get(key, initialVal);
95
100
  },
101
+ get actions() {
102
+ return boundActions;
103
+ },
96
104
  };
97
- const boundActions = {};
98
105
  const actions = keyOrDef?.options?.actions || flowOptions?.actions;
99
106
  if (actions) {
100
107
  for (const [name, fn] of Object.entries(actions)) {
@@ -111,11 +118,19 @@ function useFlow(keyOrDef, initial, options) {
111
118
  _canRedo: store.store.getRedoStack(key).length > 0,
112
119
  _set: (val) => {
113
120
  const next = typeof val === "function" ? val(store.store.get(key)) : val;
114
- store.store.set(key, next, { ...flowOptions, force: true });
121
+ store.store.set(key, next, {
122
+ ...flowOptions,
123
+ force: true,
124
+ actor: flowOptions?.name || flowOptions?.actor,
125
+ });
115
126
  },
116
127
  _patch: (val) => {
117
128
  const next = typeof val === "function" ? val(store.store.get(key)) : val;
118
- store.store.set(key, next, { ...flowOptions, force: false });
129
+ store.store.set(key, next, {
130
+ ...flowOptions,
131
+ force: false,
132
+ actor: flowOptions?.name || flowOptions?.actor,
133
+ });
119
134
  },
120
135
  _reset: () => store.store.reset(key),
121
136
  cf: flowOptions || {},
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["/* *****************************************************************************\n * FractoSate\n *\n * ACCESS RESTRICTIONS:\n * - This software is exclusively for use by Authorized Personnel of NEHONIX\n * - Intended for Internal Use only within NEHONIX operations\n * - No rights granted to unauthorized individuals or entities\n * - All modifications are works made for hire assigned to NEHONIX\n *\n * PROHIBITED ACTIVITIES:\n * - Copying, distributing, or sublicensing without written permission\n * - Reverse engineering, decompiling, or disassembling\n * - Creating derivative works without explicit authorization\n * - External use or commercial distribution outside NEHONIX\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * For questions or permissions, contact:\n * NEHONIX Legal Department\n * Email: legal@nehonix.com\n * Website: www.nehonix.com\n ***************************************************************************** */\n\nimport { useState, useEffect, useMemo } from \"react\";\nimport type {\n FlowOperations,\n FlowDefinition,\n DerivedFlowDefinition,\n FlowOptions,\n FlowOpsObject,\n} from \"./types\";\nimport { store } from \"./store\";\nimport { createDeepProxy } from \"./proxy\";\n\n// Connect proxy creator to store for internal effects\nstore.setProxyCreator(createDeepProxy);\n\nexport * from \"./types\";\n\n/**\n * Manually initializes a flow to ensure its effects run immediately.\n * This is useful for flows that need to start working before any component subscribes to them.\n */\nexport function initFlow<T, A>(flow: FlowDefinition<T, A>) {\n store.get(flow.key, flow.initial, flow.options);\n}\n\n/**\n * Defines a derived flow that reacts to changes in a source flow.\n * Use this for computed values that shouldn't be manually modified.\n */\nexport function defineDerived<T, R>(\n source: FlowDefinition<T, any>,\n selector: (state: T) => R,\n derivedKey?: string,\n): DerivedFlowDefinition<T, R> {\n return {\n key: derivedKey || `${source.key}_derived_${Date.now()}`,\n source,\n selector,\n };\n}\n\n/**\n * Defines a state flow with 100% type inference for state and actions.\n * @param key Unique key for the flow\n * @param initial Initial state value\n * @param options Flow configuration and optional actions\n */\nexport function defineFlow<T, A>(\n key: string,\n initial: T,\n options: FlowOptions<NoInfer<T>> & {\n actions: A & {\n [K in keyof A]: (...args: any[]) => (ops: FlowOpsObject<T>) => any;\n };\n },\n): FlowDefinition<T, A>;\nexport function defineFlow<T>(\n key: string,\n initial: T,\n options?: FlowOptions<NoInfer<T>>,\n): FlowDefinition<T, {}>;\nexport function defineFlow<T, A>(\n key: string,\n initial: T,\n options?: FlowOptions<T> & { actions?: A },\n): FlowDefinition<T, A> {\n return { key, initial, options: options as any };\n}\n\n/**\n * Main hook to consume and interact with a FractoState flow.\n * Returns a tuple containing the current [State, Toolbox].\n */\nexport function useFlow<K extends string, T = any>(\n key: K,\n initial?: T,\n options?: FlowOptions<T>,\n): [T, FlowOperations<T, {}>];\n\nexport function useFlow<T, A>(\n def: FlowDefinition<T, A>,\n options?: FlowOptions<T>,\n): [T, FlowOperations<T, A>];\n\nexport function useFlow<T, R>(def: DerivedFlowDefinition<T, R>): [R, {}];\n\nexport function useFlow(\n keyOrDef: any,\n initial?: any,\n options?: any,\n): [any, any] {\n const isDerived = typeof keyOrDef === \"object\" && \"selector\" in keyOrDef;\n const isDef = typeof keyOrDef === \"object\" && \"key\" in keyOrDef && !isDerived;\n\n const key = isDef\n ? (keyOrDef as any).key\n : isDerived\n ? (keyOrDef as any).source.key\n : (keyOrDef as string);\n const initialVal = isDef\n ? (keyOrDef as any).initial\n : isDerived\n ? (keyOrDef as any).source.initial\n : initial;\n const flowOptions = isDef\n ? { ...((keyOrDef as any).options || {}), ...options }\n : isDerived\n ? (keyOrDef as any).source.options\n : options;\n\n const [state, setState] = useState(() => {\n const raw = store.get(key, initialVal, flowOptions);\n return isDerived ? (keyOrDef as any).selector(raw) : raw;\n });\n\n useEffect(() => {\n return store.subscribe(key, () => {\n const raw = store.get(key, initialVal);\n setState(isDerived ? (keyOrDef as any).selector(raw) : raw);\n });\n }, [key, isDerived]);\n\n const toolbox = useMemo(() => {\n if (isDerived) return {};\n\n const defaultOps = {\n get self() {\n return createDeepProxy(\n key,\n [],\n store.get(key, initialVal),\n flowOptions,\n );\n },\n get state() {\n return store.get(key, initialVal);\n },\n };\n\n const boundActions = {} as any;\n const actions = (keyOrDef as any)?.options?.actions || flowOptions?.actions;\n\n if (actions) {\n for (const [name, fn] of Object.entries(actions)) {\n boundActions[name] = (...args: any[]) =>\n (fn as Function)(...args)(defaultOps);\n }\n }\n\n return {\n ops: defaultOps,\n actions: boundActions,\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 _set: (val: any) => {\n const next = typeof val === \"function\" ? val(store.get(key)) : val;\n store.set(key, next, { ...flowOptions, force: true });\n },\n _patch: (val: any) => {\n const next = typeof val === \"function\" ? val(store.get(key)) : val;\n store.set(key, next, { ...flowOptions, force: false });\n },\n _reset: () => store.reset(key),\n cf: flowOptions || {},\n isHydrating: !!store.__hydrating__?.has(key),\n };\n }, [key, isDerived, state, flowOptions]);\n\n return [state, toolbox] as any;\n}\n"],"names":["store","createDeepProxy","useState","useEffect","useMemo"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["/* *****************************************************************************\n * FractoSate\n *\n * ACCESS RESTRICTIONS:\n * - This software is exclusively for use by Authorized Personnel of NEHONIX\n * - Intended for Internal Use only within NEHONIX operations\n * - No rights granted to unauthorized individuals or entities\n * - All modifications are works made for hire assigned to NEHONIX\n *\n * PROHIBITED ACTIVITIES:\n * - Copying, distributing, or sublicensing without written permission\n * - Reverse engineering, decompiling, or disassembling\n * - Creating derivative works without explicit authorization\n * - External use or commercial distribution outside NEHONIX\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n *\n * For questions or permissions, contact:\n * NEHONIX Legal Department\n * Email: legal@nehonix.com\n * Website: www.nehonix.com\n ***************************************************************************** */\n\nimport { useState, useEffect, useMemo } from \"react\";\nimport type {\n FlowOperations,\n FlowDefinition,\n DerivedFlowDefinition,\n FlowOptions,\n UseFlowOptions,\n FlowOpsObject,\n} from \"./types\";\nimport { store } from \"./store\";\nimport { createDeepProxy } from \"./proxy\";\n\n// Connect proxy creator to store for internal effects\nstore.setProxyCreator(createDeepProxy);\n\nexport * from \"./types\";\n\n/**\n * Manually initializes a flow to ensure its effects run immediately.\n * This is useful for flows that need to start working before any component subscribes to them.\n */\nexport function initFlow<T, A>(flow: FlowDefinition<T, A>) {\n store.get(flow.key, flow.initial, flow.options);\n}\n\n/**\n * Defines a derived flow that reacts to changes in a source flow.\n * Use this for computed values that shouldn't be manually modified.\n */\nexport function defineDerived<T, R>(\n source: FlowDefinition<T, any>,\n selector: (state: T) => R,\n derivedKey?: string,\n): DerivedFlowDefinition<T, R> {\n return {\n key: derivedKey || `${source.key}_derived_${Date.now()}`,\n source,\n selector,\n };\n}\n\nexport function defineFlow<\n T,\n A extends Record<\n string,\n (...args: any[]) => (ops: FlowOpsObject<T, A>) => any\n >,\n>(\n key: string,\n initial: T,\n options: FlowOptions<NoInfer<T>, A> & {\n actions: A;\n },\n): FlowDefinition<T, A>;\nexport function defineFlow<T>(\n key: string,\n initial: T,\n options?: FlowOptions<NoInfer<T>, {}>,\n): FlowDefinition<T, {}>;\nexport function defineFlow<T, A>(\n key: string,\n initial: T,\n options?: FlowOptions<T> & { actions?: A },\n): FlowDefinition<T, A> {\n return { key, initial, options: options as any };\n}\n\n/**\n * Main hook to consume and interact with a FractoState flow.\n * Returns a tuple containing the current [State, Toolbox].\n */\nexport function useFlow<K extends string, T = any>(\n key: K,\n initial?: T,\n options?: UseFlowOptions<T>,\n): [T, FlowOperations<T, {}>];\n\nexport function useFlow<T, A>(\n def: FlowDefinition<T, A>,\n options?: UseFlowOptions<T>,\n): [T, FlowOperations<T, A>];\n\nexport function useFlow<T, R>(def: DerivedFlowDefinition<T, R>): [R, {}];\n\nexport function useFlow(\n keyOrDef: any,\n initial?: any,\n options?: any,\n): [any, any] {\n const isDerived = typeof keyOrDef === \"object\" && \"selector\" in keyOrDef;\n const isDef = typeof keyOrDef === \"object\" && \"key\" in keyOrDef && !isDerived;\n\n const key = isDef\n ? (keyOrDef as any).key\n : isDerived\n ? (keyOrDef as any).source.key\n : (keyOrDef as string);\n const initialVal = isDef\n ? (keyOrDef as any).initial\n : isDerived\n ? (keyOrDef as any).source.initial\n : initial;\n const flowOptions = isDef\n ? { ...((keyOrDef as any).options || {}), ...(initial || {}) }\n : isDerived\n ? (keyOrDef as any).source.options\n : options;\n\n const [state, setState] = useState(() => {\n const raw = store.get(key, initialVal, flowOptions);\n return isDerived ? (keyOrDef as any).selector(raw) : raw;\n });\n\n useEffect(() => {\n return store.subscribe(\n key,\n () => {\n const raw = store.get(key, initialVal);\n setState(isDerived ? (keyOrDef as any).selector(raw) : raw);\n },\n flowOptions?.name || flowOptions?.actor,\n );\n }, [key, isDerived, flowOptions?.name, flowOptions?.actor]);\n\n const toolbox = useMemo(() => {\n if (isDerived) return {};\n\n const boundActions = {} as any;\n const defaultOps = {\n get self() {\n return createDeepProxy(key, [], store.get(key, initialVal), {\n ...flowOptions,\n actions: boundActions,\n actor: flowOptions?.name || flowOptions?.actor,\n });\n },\n get state() {\n return store.get(key, initialVal);\n },\n get actions() {\n return boundActions;\n },\n };\n\n const actions = (keyOrDef as any)?.options?.actions || flowOptions?.actions;\n\n if (actions) {\n for (const [name, fn] of Object.entries(actions)) {\n boundActions[name] = (...args: any[]) =>\n (fn as Function)(...args)(defaultOps);\n }\n }\n\n return {\n ops: defaultOps,\n actions: boundActions,\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 _set: (val: any) => {\n const next = typeof val === \"function\" ? val(store.get(key)) : val;\n store.set(key, next, {\n ...flowOptions,\n force: true,\n actor: flowOptions?.name || flowOptions?.actor,\n });\n },\n _patch: (val: any) => {\n const next = typeof val === \"function\" ? val(store.get(key)) : val;\n store.set(key, next, {\n ...flowOptions,\n force: false,\n actor: flowOptions?.name || flowOptions?.actor,\n });\n },\n _reset: () => store.reset(key),\n cf: flowOptions || {},\n isHydrating: !!store.__hydrating__?.has(key),\n };\n }, [key, isDerived, state, flowOptions]);\n\n return [state, toolbox] as any;\n}\n"],"names":["store","createDeepProxy","useState","useEffect","useMemo"],"mappings":"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"}
@@ -3,10 +3,6 @@
3
3
  var index = require('../../index.js');
4
4
  var store = require('../store.js');
5
5
 
6
- /**
7
- * Internal Flow for DevTools state management.
8
- * This allows the DevTools to "dogfood" FractoState for its own UI and monitoring logic.
9
- */
10
6
  const DevToolsFlow = index.defineFlow("__fracto_devtools__", {
11
7
  ui: {
12
8
  isOpen: false,
@@ -21,34 +17,40 @@ const DevToolsFlow = index.defineFlow("__fracto_devtools__", {
21
17
  snapshot: {},
22
18
  flowCount: 0,
23
19
  lastUpdate: 0,
24
- indicators: { red: false, yellow: false, green: false },
20
+ indicators: {
21
+ red: false,
22
+ yellow: false,
23
+ green: false,
24
+ },
25
25
  },
26
26
  isInitialized: false,
27
27
  }, {
28
28
  actions: {
29
29
  toggleOpen: () => (ops) => ops.self.ui.isOpen._toggle(),
30
30
  setOpen: (open) => (ops) => ops.self.ui.isOpen._set(open),
31
- setSearch: (q) => (ops) => ops.self.ui.searchQuery._set(q),
32
- setMode: (m) => (ops) => ops.self.ui.viewMode._set(m),
33
- setCoords: (x, y) => (ops) => {
34
- ops.self.ui.coords.x._set(x);
35
- ops.self.ui.coords.y._set(y);
36
- },
31
+ setSearch: (query) => (ops) => ops.self.ui.searchQuery._set(query),
32
+ setMode: (mode) => (ops) => ops.self.ui.viewMode._set(mode),
33
+ setCoords: (x, y) => (ops) => ops.self.ui.coords._set({ x, y }),
37
34
  setDragging: (dragging) => (ops) => ops.self.ui.isDragging._set(dragging),
38
35
  setCopiedKey: (key) => (ops) => ops.self.ui.copiedKey._set(key),
39
36
  toggleCollapse: (key) => (ops) => {
40
- const flows = ops.state.ui.collapsedFlows;
41
- const idx = flows.indexOf(key);
42
- if (idx > -1)
43
- ops.self.ui.collapsedFlows._removeAt(idx);
37
+ const list = [...ops.state.ui.collapsedFlows];
38
+ const index = list.indexOf(key);
39
+ if (index === -1)
40
+ list.push(key);
44
41
  else
45
- ops.self.ui.collapsedFlows._push(key);
42
+ list.splice(index, 1);
43
+ ops.self.ui.collapsedFlows._set(list);
46
44
  },
47
45
  collapseAll: (keys) => (ops) => ops.self.ui.collapsedFlows._set(keys),
48
46
  expandAll: () => (ops) => ops.self.ui.collapsedFlows._set([]),
49
47
  syncFlowCount: () => (ops) => {
50
- ops.state.monitor.flowCount !== store.store.getFlowCount() &&
51
- ops.self.monitor.flowCount._set(store.store.getFlowCount());
48
+ const count = store.store.getFlowCount
49
+ ? store.store.getFlowCount()
50
+ : Object.keys(store.store.getDebugSnapshot()).length;
51
+ if (ops.state.monitor.flowCount !== count) {
52
+ ops.self.monitor.flowCount._set(count);
53
+ }
52
54
  },
53
55
  syncSnapshot: () => (ops) => {
54
56
  const snap = store.store.getDebugSnapshot();
@@ -57,7 +59,7 @@ const DevToolsFlow = index.defineFlow("__fracto_devtools__", {
57
59
  flowCount: Object.keys(snap).length,
58
60
  lastUpdate: Date.now(),
59
61
  });
60
- if (!ops.state.isInitialized && Object.keys(snap).length > 0) {
62
+ if (!ops.state.isInitialized) {
61
63
  ops.self.isInitialized._set(true);
62
64
  }
63
65
  },
@@ -1 +1 @@
1
- {"version":3,"file":"DevToolsFlow.js","sources":["../../../../src/devtools/DevToolsFlow.ts"],"sourcesContent":["import { defineFlow } from \"..\";\nimport { store } from \"../store\";\nimport { ViewMode } from \"./fracto_dev_tools\";\n\n/**\n * Internal Flow for DevTools state management.\n * This allows the DevTools to \"dogfood\" FractoState for its own UI and monitoring logic.\n */\nexport const DevToolsFlow = defineFlow(\n \"__fracto_devtools__\",\n {\n ui: {\n isOpen: false,\n searchQuery: \"\",\n viewMode: \"all\" as ViewMode,\n collapsedFlows: [] as string[],\n coords: { x: 20, y: 20 },\n isDragging: false,\n copiedKey: null as string | null,\n },\n monitor: {\n snapshot: {} as Record<string, { value: any; meta: any }>,\n flowCount: 0,\n lastUpdate: 0,\n indicators: { red: false, yellow: false, green: false },\n },\n isInitialized: false,\n },\n {\n actions: {\n toggleOpen: () => (ops) => ops.self.ui.isOpen._toggle(),\n setOpen: (open: boolean) => (ops) => ops.self.ui.isOpen._set(open),\n setSearch: (q: string) => (ops) => ops.self.ui.searchQuery._set(q),\n setMode: (m: ViewMode) => (ops) => ops.self.ui.viewMode._set(m),\n setCoords: (x: number, y: number) => (ops) => {\n ops.self.ui.coords.x._set(x);\n ops.self.ui.coords.y._set(y);\n },\n setDragging: (dragging: boolean) => (ops) =>\n ops.self.ui.isDragging._set(dragging),\n setCopiedKey: (key: string | null) => (ops) =>\n ops.self.ui.copiedKey._set(key),\n\n toggleCollapse: (key: string) => (ops) => {\n const flows = ops.state.ui.collapsedFlows;\n const idx = flows.indexOf(key);\n if (idx > -1) ops.self.ui.collapsedFlows._removeAt(idx);\n else ops.self.ui.collapsedFlows._push(key);\n },\n collapseAll: (keys: string[]) => (ops) =>\n ops.self.ui.collapsedFlows._set(keys),\n expandAll: () => (ops) => ops.self.ui.collapsedFlows._set([]),\n\n syncFlowCount: () => (ops) => {\n ops.state.monitor.flowCount !== store.getFlowCount() &&\n ops.self.monitor.flowCount._set(store.getFlowCount());\n },\n\n syncSnapshot: () => (ops) => {\n const snap = store.getDebugSnapshot();\n ops.self.monitor._merge({\n snapshot: snap,\n flowCount: Object.keys(snap).length,\n lastUpdate: Date.now(),\n });\n\n if (!ops.state.isInitialized && Object.keys(snap).length > 0) {\n ops.self.isInitialized._set(true);\n }\n },\n\n triggerIndicator: (color: \"red\" | \"yellow\" | \"green\") => (ops) => {\n ops.self.monitor.indicators[color]._set(true);\n setTimeout(() => {\n ops.self.monitor.indicators[color]._set(false);\n }, 150);\n },\n },\n },\n);\n"],"names":["defineFlow","store"],"mappings":"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"}
1
+ {"version":3,"file":"DevToolsFlow.js","sources":["../../../../src/devtools/DevToolsFlow.ts"],"sourcesContent":["import { defineFlow } from \"../index\";\nimport { store } from \"../store\";\n\nexport const DevToolsFlow = defineFlow(\n \"__fracto_devtools__\",\n {\n ui: {\n isOpen: false,\n searchQuery: \"\",\n viewMode: \"all\",\n collapsedFlows: [] as string[],\n coords: { x: 20, y: 20 },\n isDragging: false,\n copiedKey: null as string | null,\n },\n monitor: {\n snapshot: {} as Record<string, any>,\n flowCount: 0,\n lastUpdate: 0,\n indicators: {\n red: false,\n yellow: false,\n green: false,\n },\n },\n isInitialized: false,\n },\n {\n actions: {\n toggleOpen: () => (ops: any) => ops.self.ui.isOpen._toggle(),\n setOpen: (open: boolean) => (ops: any) => ops.self.ui.isOpen._set(open),\n setSearch: (query: string) => (ops: any) =>\n ops.self.ui.searchQuery._set(query),\n setMode: (mode: string) => (ops: any) => ops.self.ui.viewMode._set(mode),\n setCoords: (x: number, y: number) => (ops: any) =>\n ops.self.ui.coords._set({ x, y }),\n setDragging: (dragging: boolean) => (ops: any) =>\n ops.self.ui.isDragging._set(dragging),\n setCopiedKey: (key: string | null) => (ops: any) =>\n ops.self.ui.copiedKey._set(key),\n\n toggleCollapse: (key: string) => (ops: any) => {\n const list = [...ops.state.ui.collapsedFlows];\n const index = list.indexOf(key);\n if (index === -1) list.push(key);\n else list.splice(index, 1);\n ops.self.ui.collapsedFlows._set(list);\n },\n collapseAll: (keys: string[]) => (ops: any) =>\n ops.self.ui.collapsedFlows._set(keys),\n expandAll: () => (ops: any) => ops.self.ui.collapsedFlows._set([]),\n\n syncFlowCount: () => (ops: any) => {\n const count = (store as any).getFlowCount\n ? (store as any).getFlowCount()\n : Object.keys(store.getDebugSnapshot()).length;\n if (ops.state.monitor.flowCount !== count) {\n ops.self.monitor.flowCount._set(count);\n }\n },\n\n syncSnapshot: () => (ops: any) => {\n const snap = store.getDebugSnapshot();\n ops.self.monitor._merge({\n snapshot: snap,\n flowCount: Object.keys(snap).length,\n lastUpdate: Date.now(),\n });\n if (!ops.state.isInitialized) {\n ops.self.isInitialized._set(true);\n }\n },\n\n triggerIndicator: (color: \"red\" | \"yellow\" | \"green\") => (ops: any) => {\n ops.self.monitor.indicators[color]._set(true);\n setTimeout(() => {\n ops.self.monitor.indicators[color]._set(false);\n }, 150);\n },\n },\n },\n);\n"],"names":["defineFlow","store"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var css_248z = ".fracto-devtools-button{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,#1a1a2e,#16213e);border:2px solid rgba(0,212,255,.4);border-radius:16px;bottom:20px;box-shadow:0 8px 32px rgba(0,212,255,.3),inset 0 0 20px rgba(0,212,255,.2);color:#fff;cursor:pointer;display:flex;font-family:system-ui,-apple-system,sans-serif;font-size:28px;font-weight:700;height:56px;justify-content:center;position:fixed;transition:all .3s cubic-bezier(.4,0,.2,1);width:56px;z-index:9999}.fracto-devtools-button:hover{border-color:rgba(0,212,255,.7);box-shadow:0 12px 48px rgba(0,212,255,.5),inset 0 0 30px rgba(0,212,255,.3);transform:scale(1.1) rotate(5deg)}.fracto-devtools-button.position-right{right:20px}.fracto-devtools-button.position-left{left:20px}.fracto-devtools-panel{backdrop-filter:blur(20px);background:linear-gradient(145deg,rgba(10,10,15,.98),rgba(15,15,25,.98));border:1px solid rgba(0,212,255,.3);border-radius:20px;bottom:20px;box-shadow:0 20px 60px rgba(0,0,0,.5),inset 0 0 1px rgba(0,212,255,.5);color:#e0e0e0;display:flex;flex-direction:column;font-family:system-ui,-apple-system,monospace;height:600px;overflow:hidden;position:fixed;width:420px;z-index:9999}.fracto-devtools-panel.position-right{right:20px}.fracto-devtools-panel.position-left{left:20px}.fracto-devtools-header{align-items:center;background:linear-gradient(135deg,rgba(0,168,255,.1),rgba(0,212,255,.05));border-bottom:1px solid rgba(0,212,255,.2);display:flex;justify-content:space-between;padding:16px 20px}.fracto-devtools-dot{align-items:center;border:none;border-radius:50%;cursor:pointer;display:flex;height:12px;justify-content:center;position:relative;transition:all .2s;width:12px}.fracto-devtools-dot.red{background:#ff5f57;border:1px solid #e0443e}.fracto-devtools-dot.yellow{background:#ffbd2e;border:1px solid #dea123}.fracto-devtools-dot.green{background:#28c940;border:1px solid #1aab29}.fracto-devtools-dot.blue{background:#00d4ff;border:1px solid #00a8ff}.fracto-devtools-dot:hover{filter:brightness(1.1);transform:scale(1.1)}.fracto-devtools-header.mode-indicators{flex-direction:row}.fracto-devtools-header.mode-controls.controls-right{flex-direction:row-reverse}.fracto-devtools-header.mode-controls.controls-right .fracto-devtools-window-controls{margin-left:12px;margin-right:0}.fracto-devtools-header.mode-indicators.controls-left{flex-direction:row-reverse}.fracto-devtools-header.mode-indicators.controls-right{flex-direction:row}.fracto-devtools-window-controls{display:flex;gap:8px;margin-right:12px}.fracto-devtools-window-indicators{align-items:center;display:flex;gap:8px}.mode-indicators .fracto-devtools-dot{opacity:.3;transform:scale(.9);transition:all .2s}.mode-indicators .fracto-devtools-dot.active{animation:ledFlash .2s ease-out;filter:brightness(1.5);opacity:1}.mode-indicators .fracto-devtools-dot.green.active{animation:ledHeartbeat 2s ease-in-out infinite;filter:brightness(1.2);opacity:1}.mode-controls .fracto-devtools-dot{animation:none!important;filter:none;opacity:1;transform:none}@keyframes ledFlash{0%{box-shadow:0 0 0 hsla(0,0%,100%,0);transform:scale(1)}50%{box-shadow:0 0 20px currentColor;transform:scale(1.4)}to{box-shadow:0 0 5px currentColor;transform:scale(1)}}@keyframes ledHeartbeat{0%{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}15%{box-shadow:0 0 10px rgba(40,201,64,.6);opacity:1;transform:scale(1.2)}30%{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}45%{box-shadow:0 0 10px rgba(40,201,64,.6);opacity:1;transform:scale(1.2)}to{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}}.fracto-devtools-dot.red.active{color:#ff5f57}.fracto-devtools-dot.yellow.active{color:#ffbd2e}.fracto-devtools-dot.green.active{color:#28c940}.fracto-devtools-dot.blue.active{color:#00d4ff}.fracto-devtools-close-minimal{background:none;border:none;color:#555;cursor:pointer;font-size:18px;margin-left:8px;padding:0 4px;transition:color .2s}.fracto-devtools-close-minimal:hover{color:#ff5f57}.fracto-devtools-dot:after{color:rgba(0,0,0,.5);content:\"\";font-size:8px;font-weight:700;opacity:0;transition:opacity .2s}.fracto-devtools-dot.red:hover:after{content:\"×\";opacity:1}.fracto-devtools-dot.yellow:hover:after{content:\"−\";opacity:1}.fracto-devtools-dot.green:hover:after{content:\"+\";opacity:1}.fracto-devtools-dot.blue:hover:after{content:\"↗\";font-size:10px;line-height:1;opacity:1}.fracto-devtools-logo.pulse{animation:logoPulse .4s cubic-bezier(.4,0,.2,1)}@keyframes logoPulse{0%{box-shadow:0 4px 12px rgba(0,212,255,.3);transform:scale(1)}50%{box-shadow:0 0 20px rgba(0,212,255,.6);transform:scale(1.1)}to{box-shadow:0 4px 12px rgba(0,212,255,.3);transform:scale(1)}}.fracto-devtools-header-content{align-items:center;display:flex;gap:10px}.fracto-devtools-logo{align-items:center;background:linear-gradient(135deg,#1a1a2e,#16213e);border:1px solid rgba(0,212,255,.4);border-radius:8px;box-shadow:0 4px 12px rgba(0,212,255,.3),inset 0 0 15px rgba(0,212,255,.2);color:#fff;display:flex;font-size:18px;font-weight:700;height:32px;justify-content:center;transition:all .3s;width:32px}.fracto-devtools-title{color:#fff;font-size:16px;font-weight:700;line-height:1.2}.fracto-devtools-title-state{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text}.fracto-devtools-subtitle{color:#888;font-size:10px;margin-top:2px}.fracto-devtools-toolbar{background:rgba(0,0,0,.2);border-bottom:1px solid rgba(0,212,255,.15);display:flex;flex-direction:column;gap:10px;padding:12px 16px}.fracto-devtools-search-container{align-items:center;display:flex;position:relative}.fracto-devtools-search-icon{color:#666;font-size:14px;left:12px;pointer-events:none;position:absolute}.fracto-devtools-search{background:rgba(0,0,0,.4);border:1px solid rgba(0,212,255,.2);border-radius:8px;color:#fff;font-family:inherit;font-size:12px;outline:none;padding:8px 12px 8px 36px;transition:all .2s;width:100%}.fracto-devtools-search::placeholder{color:#666}.fracto-devtools-search:focus{background:rgba(0,0,0,.6);border-color:rgba(0,212,255,.5);box-shadow:0 0 0 3px rgba(0,212,255,.1)}.fracto-devtools-clear-search{background:rgba(0,212,255,.1);border:none;border-radius:4px;color:#00d4ff;cursor:pointer;font-size:12px;padding:4px 8px;position:absolute;right:8px;transition:all .2s}.fracto-devtools-clear-search:hover{background:rgba(0,212,255,.2)}.fracto-devtools-filters{align-items:center;display:flex;gap:8px}.fracto-devtools-filter-label{color:#888;font-size:11px}.fracto-devtools-filter-buttons{display:flex;flex-wrap:wrap;gap:6px}.fracto-devtools-filter-button{background:rgba(0,0,0,.4);border:1px solid rgba(0,212,255,.2);border-radius:6px;color:#999;cursor:pointer;font-size:11px;padding:4px 10px;transition:all .2s}.fracto-devtools-filter-button:hover{border-color:rgba(0,212,255,.4);color:#bbb}.fracto-devtools-filter-button.active{background:rgba(0,212,255,.2);border-color:rgba(0,212,255,.5);color:#00d4ff}.fracto-devtools-stats{color:#666;display:flex;font-size:10px;gap:12px}.fracto-devtools-stat{align-items:center;display:flex;gap:4px}.fracto-devtools-stat-value{color:#00d4ff;font-weight:700}.fracto-devtools-content{flex:1;overflow:auto;padding:16px}.fracto-devtools-content::-webkit-scrollbar{width:8px}.fracto-devtools-content::-webkit-scrollbar-track{background:hsla(0,0%,100%,.02);border-radius:4px}.fracto-devtools-content::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#00d4ff,#00a8ff);border-radius:4px}.fracto-devtools-content::-webkit-scrollbar-thumb:hover{background:linear-gradient(135deg,#00e4ff,#00b8ff)}.fracto-devtools-empty{align-items:center;color:#666;display:flex;flex-direction:column;gap:12px;padding:40px 20px;text-align:center}.fracto-devtools-empty-icon{align-items:center;background:linear-gradient(135deg,rgba(0,212,255,.1),rgba(0,168,255,.05));border:1px solid rgba(0,212,255,.2);border-radius:16px;display:flex;font-size:32px;height:64px;justify-content:center;opacity:.5;width:64px}.fracto-devtools-empty-title{font-size:14px;font-weight:500}.fracto-devtools-empty-subtitle{color:#555;font-size:12px}.fracto-devtools-flow{background:rgba(0,0,0,.3);border:1px solid rgba(0,212,255,.2);border-radius:10px;margin-bottom:12px;overflow:hidden;transition:all .2s}.fracto-devtools-flow:hover{border-color:rgba(0,212,255,.5);box-shadow:0 4px 16px rgba(0,212,255,.2)}.fracto-devtools-flow.collapsed .fracto-devtools-flow-content{display:none}.fracto-devtools-flow-header{align-items:center;background:linear-gradient(135deg,rgba(0,212,255,.1),rgba(0,168,255,.05));border-bottom:1px solid rgba(0,212,255,.2);cursor:pointer;display:flex;justify-content:space-between;padding:10px 14px;user-select:none}.fracto-devtools-flow.collapsed .fracto-devtools-flow-header{border-bottom:none}.fracto-devtools-flow-header-left{align-items:center;display:flex;flex:1;gap:8px;min-width:0}.fracto-devtools-flow-collapse-icon{color:#00d4ff;flex-shrink:0;font-size:12px;transition:transform .2s}.fracto-devtools-flow.collapsed .fracto-devtools-flow-collapse-icon{transform:rotate(-90deg)}.fracto-devtools-flow-key{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text;font-size:13px;font-weight:700;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fracto-devtools-flow-actions{align-items:center;display:flex;gap:6px}.fracto-devtools-flow-badge{background:rgba(0,212,255,.15);border:1px solid rgba(0,212,255,.3);border-radius:4px;color:#00d4ff;font-size:10px;padding:2px 8px}.fracto-devtools-flow-action{align-items:center;background:rgba(0,0,0,.3);border:1px solid rgba(0,212,255,.2);border-radius:4px;color:#666;cursor:pointer;display:flex;font-size:12px;height:24px;justify-content:center;transition:all .2s;width:24px}.fracto-devtools-flow-action:hover{background:rgba(0,212,255,.1);border-color:rgba(0,212,255,.4);color:#00d4ff}.fracto-devtools-flow-content{background-color:rgba(0,0,0,.5);color:#ddd;font-size:11px;line-height:1.6;margin:0;max-height:300px;overflow-x:auto;overflow-y:auto;padding:12px 14px}.fracto-devtools-flow-content::-webkit-scrollbar{height:6px;width:6px}.fracto-devtools-flow-content::-webkit-scrollbar-track{background:hsla(0,0%,100%,.02)}.fracto-devtools-flow-content::-webkit-scrollbar-thumb{background:rgba(0,212,255,.3);border-radius:3px}.fracto-devtools-flow-content::-webkit-scrollbar-thumb:hover{background:rgba(0,212,255,.5)}.fracto-devtools-footer{align-items:center;background:rgba(0,0,0,.3);border-top:1px solid rgba(0,212,255,.2);color:#666;display:flex;font-size:10px;justify-content:space-between;padding:10px 20px}.fracto-devtools-footer-count{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text;font-weight:700}.fracto-devtools-no-results{color:#666;padding:40px 20px;text-align:center}.fracto-devtools-no-results-icon{font-size:48px;margin-bottom:12px;opacity:.3}.fracto-devtools-no-results-title{font-size:14px;font-weight:500;margin-bottom:6px}.fracto-devtools-no-results-subtitle{color:#555;font-size:12px}.fracto-devtools-meta-tag{animation:pulse 1.5s infinite;background:rgba(0,212,255,.2);border-radius:4px;color:#00d4ff;font-size:10px;margin-left:8px;padding:1px 4px}@keyframes pulse{0%{opacity:.6}50%{opacity:1}to{opacity:.6}}.fracto-devtools-flow-expanded{background:rgba(0,0,0,.2);border-top:1px solid rgba(0,212,255,.1)}.fracto-devtools-meta-grid{background:rgba(0,212,255,.1);border-bottom:1px solid rgba(0,212,255,.1);display:grid;gap:1px;grid-template-columns:repeat(3,1fr)}.fracto-devtools-meta-item{align-items:center;background:#0a0a0f;display:flex;flex-direction:column;padding:6px 12px}.fracto-devtools-meta-item .label{color:#666;font-size:9px;letter-spacing:.5px;text-transform:uppercase}.fracto-devtools-meta-item .value{color:#00d4ff;font-size:12px;font-weight:700}.fracto-devtools-copy-toast{animation:slideDown .2s ease-out;background:#4caf50;border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#fff;font-size:10px;font-weight:700;padding:4px 10px;position:absolute;right:14px;top:40px;z-index:10}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.fracto-devtools-flow-action.copied{background:rgba(76,175,80,.1);border-color:rgba(76,175,80,.5);color:#4caf50}.fracto-devtools-badge-count{align-items:center;animation:badgePop .3s cubic-bezier(.175,.885,.32,1.275);background:#f05;border:2px solid #0a0a0f;border-radius:9px;box-shadow:0 4px 8px rgba(255,0,85,.4);color:#fff;display:flex;font-size:10px;font-weight:900;height:18px;justify-content:center;min-width:18px;padding:0 4px;position:absolute;right:-5px;top:-5px}@keyframes badgePop{0%{transform:scale(0)}to{transform:scale(1)}}.fracto-devtools-button{cursor:grab;user-select:none}.fracto-devtools-button:active{cursor:grabbing}.fracto-devtools-actions{display:flex;gap:4px;margin-left:auto}.fracto-devtools-action-btn{align-items:center;background:rgba(0,212,255,.1);border:1px solid rgba(0,212,255,.3);border-radius:4px;color:#00d4ff;cursor:pointer;display:flex;font-size:14px;height:24px;justify-content:center;transition:all .2s;width:24px}.fracto-devtools-action-btn:hover{background:rgba(0,212,255,.2);border-color:rgba(0,212,255,.5)}.fracto-devtools-action-btn.is-dirty,.fracto-devtools-flow-action.is-dirty{background:rgba(74,222,128,.1)!important;border-color:rgba(74,222,128,.5)!important;box-shadow:0 0 10px rgba(74,222,128,.2);color:#4ade80!important}.fracto-devtools-action-btn.danger.is-dirty{background:rgba(255,77,77,.15)!important;border-color:rgba(255,77,77,.6)!important;box-shadow:0 0 12px rgba(255,77,77,.3);color:#ff4d4d!important}.fracto-devtools-action-btn.danger{background:rgba(255,77,77,.05);border-color:rgba(255,77,77,.1);color:#666}.fracto-devtools-action-btn.danger:hover{background:rgba(255,77,77,.2);border-color:rgba(255,77,77,.5)}.fracto-devtools-panel.is-maximized{border-radius:24px;bottom:20px!important;height:calc(100vh - 40px)!important;left:20px!important;right:20px!important;top:20px!important;width:calc(100vw - 40px)!important}:fullscreen .fracto-devtools-panel.is-maximized{border-radius:0;bottom:0!important;height:100vh!important;left:0!important;right:0!important;top:0!important;width:100vw!important}.fracto-devtools-max-minimal{align-items:center;background:none;border:none;color:#555;cursor:pointer;display:flex;font-size:14px;justify-content:center;margin-left:8px;padding:0 4px;transition:all .2s}.fracto-devtools-max-minimal:hover{color:#00d4ff}";
3
+ var css_248z = ".fracto-devtools-button{align-items:center;backdrop-filter:blur(10px);background:linear-gradient(135deg,#1a1a2e,#16213e);border:2px solid rgba(0,212,255,.4);border-radius:16px;bottom:20px;box-shadow:0 8px 32px rgba(0,212,255,.3),inset 0 0 20px rgba(0,212,255,.2);color:#fff;cursor:pointer;display:flex;font-family:system-ui,-apple-system,sans-serif;font-size:28px;font-weight:700;height:56px;justify-content:center;position:fixed;transition:all .3s cubic-bezier(.4,0,.2,1);width:56px;z-index:9999}.fracto-devtools-button:hover{border-color:rgba(0,212,255,.7);box-shadow:0 12px 48px rgba(0,212,255,.5),inset 0 0 30px rgba(0,212,255,.3);transform:scale(1.1) rotate(5deg)}.fracto-devtools-button.position-right{right:20px}.fracto-devtools-button.position-left{left:20px}.fracto-devtools-panel{backdrop-filter:blur(20px);background:linear-gradient(145deg,rgba(10,10,15,.98),rgba(15,15,25,.98));border:1px solid rgba(0,212,255,.3);border-radius:20px;bottom:20px;box-shadow:0 20px 60px rgba(0,0,0,.5),inset 0 0 1px rgba(0,212,255,.5);color:#e0e0e0;display:flex;flex-direction:column;font-family:system-ui,-apple-system,monospace;height:600px;overflow:hidden;position:fixed;width:420px;z-index:9999}.fracto-devtools-panel.position-right{right:20px}.fracto-devtools-panel.position-left{left:20px}.fracto-devtools-header{align-items:center;background:linear-gradient(135deg,rgba(0,168,255,.1),rgba(0,212,255,.05));border-bottom:1px solid rgba(0,212,255,.2);display:flex;justify-content:space-between;padding:16px 20px}.fracto-devtools-dot{align-items:center;border:none;border-radius:50%;cursor:pointer;display:flex;height:12px;justify-content:center;position:relative;transition:all .2s;width:12px}.fracto-devtools-dot.red{background:#ff5f57;border:1px solid #e0443e}.fracto-devtools-dot.yellow{background:#ffbd2e;border:1px solid #dea123}.fracto-devtools-dot.green{background:#28c940;border:1px solid #1aab29}.fracto-devtools-dot.blue{background:#00d4ff;border:1px solid #00a8ff}.fracto-devtools-dot:hover{filter:brightness(1.1);transform:scale(1.1)}.fracto-devtools-header.mode-indicators{flex-direction:row}.fracto-devtools-header.mode-controls.controls-right{flex-direction:row-reverse}.fracto-devtools-header.mode-controls.controls-right .fracto-devtools-window-controls{margin-left:12px;margin-right:0}.fracto-devtools-header.mode-indicators.controls-left{flex-direction:row-reverse}.fracto-devtools-header.mode-indicators.controls-right{flex-direction:row}.fracto-devtools-window-controls{display:flex;gap:8px;margin-right:12px}.fracto-devtools-window-indicators{align-items:center;display:flex;gap:8px}.mode-indicators .fracto-devtools-dot{opacity:.3;transform:scale(.9);transition:all .2s}.mode-indicators .fracto-devtools-dot.active{animation:ledFlash .2s ease-out;filter:brightness(1.5);opacity:1}.mode-indicators .fracto-devtools-dot.green.active{animation:ledHeartbeat 2s ease-in-out infinite;filter:brightness(1.2);opacity:1}.mode-controls .fracto-devtools-dot{animation:none!important;filter:none;opacity:1;transform:none}@keyframes ledFlash{0%{box-shadow:0 0 0 hsla(0,0%,100%,0);transform:scale(1)}50%{box-shadow:0 0 20px currentColor;transform:scale(1.4)}to{box-shadow:0 0 5px currentColor;transform:scale(1)}}@keyframes ledHeartbeat{0%{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}15%{box-shadow:0 0 10px rgba(40,201,64,.6);opacity:1;transform:scale(1.2)}30%{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}45%{box-shadow:0 0 10px rgba(40,201,64,.6);opacity:1;transform:scale(1.2)}to{box-shadow:0 0 0 rgba(40,201,64,0);opacity:.6;transform:scale(1)}}.fracto-devtools-dot.red.active{color:#ff5f57}.fracto-devtools-dot.yellow.active{color:#ffbd2e}.fracto-devtools-dot.green.active{color:#28c940}.fracto-devtools-dot.blue.active{color:#00d4ff}.fracto-devtools-close-minimal{background:none;border:none;color:#555;cursor:pointer;font-size:18px;margin-left:8px;padding:0 4px;transition:color .2s}.fracto-devtools-close-minimal:hover{color:#ff5f57}.fracto-devtools-dot:after{color:rgba(0,0,0,.5);content:\"\";font-size:8px;font-weight:700;opacity:0;transition:opacity .2s}.fracto-devtools-dot.red:hover:after{content:\"×\";opacity:1}.fracto-devtools-dot.yellow:hover:after{content:\"−\";opacity:1}.fracto-devtools-dot.green:hover:after{content:\"+\";opacity:1}.fracto-devtools-dot.blue:hover:after{content:\"↗\";font-size:10px;line-height:1;opacity:1}.fracto-devtools-logo.pulse{animation:logoPulse .4s cubic-bezier(.4,0,.2,1)}@keyframes logoPulse{0%{box-shadow:0 4px 12px rgba(0,212,255,.3);transform:scale(1)}50%{box-shadow:0 0 20px rgba(0,212,255,.6);transform:scale(1.1)}to{box-shadow:0 4px 12px rgba(0,212,255,.3);transform:scale(1)}}.fracto-devtools-header-content{align-items:center;display:flex;gap:10px}.fracto-devtools-logo{align-items:center;background:linear-gradient(135deg,#1a1a2e,#16213e);border:1px solid rgba(0,212,255,.4);border-radius:8px;box-shadow:0 4px 12px rgba(0,212,255,.3),inset 0 0 15px rgba(0,212,255,.2);color:#fff;display:flex;font-size:18px;font-weight:700;height:32px;justify-content:center;transition:all .3s;width:32px}.fracto-devtools-title{color:#fff;font-size:16px;font-weight:700;line-height:1.2}.fracto-devtools-title-state{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text}.fracto-devtools-subtitle{color:#888;font-size:10px;margin-top:2px}.fracto-devtools-toolbar{background:rgba(0,0,0,.2);border-bottom:1px solid rgba(0,212,255,.15);display:flex;flex-direction:column;gap:10px;padding:12px 16px}.fracto-devtools-search-container{align-items:center;display:flex;position:relative}.fracto-devtools-search-icon{color:#666;font-size:14px;left:12px;pointer-events:none;position:absolute}.fracto-devtools-search{background:rgba(0,0,0,.4);border:1px solid rgba(0,212,255,.2);border-radius:8px;color:#fff;font-family:inherit;font-size:12px;outline:none;padding:8px 12px 8px 36px;transition:all .2s;width:100%}.fracto-devtools-search::placeholder{color:#666}.fracto-devtools-search:focus{background:rgba(0,0,0,.6);border-color:rgba(0,212,255,.5);box-shadow:0 0 0 3px rgba(0,212,255,.1)}.fracto-devtools-clear-search{background:rgba(0,212,255,.1);border:none;border-radius:4px;color:#00d4ff;cursor:pointer;font-size:12px;padding:4px 8px;position:absolute;right:8px;transition:all .2s}.fracto-devtools-clear-search:hover{background:rgba(0,212,255,.2)}.fracto-devtools-filters{align-items:center;display:flex;gap:8px}.fracto-devtools-filter-label{color:#888;font-size:11px}.fracto-devtools-filter-buttons{display:flex;flex-wrap:wrap;gap:6px}.fracto-devtools-filter-button{background:rgba(0,0,0,.4);border:1px solid rgba(0,212,255,.2);border-radius:6px;color:#999;cursor:pointer;font-size:11px;padding:4px 10px;transition:all .2s}.fracto-devtools-filter-button:hover{border-color:rgba(0,212,255,.4);color:#bbb}.fracto-devtools-filter-button.active{background:rgba(0,212,255,.2);border-color:rgba(0,212,255,.5);color:#00d4ff}.fracto-devtools-stats{color:#666;display:flex;font-size:10px;gap:12px}.fracto-devtools-stat{align-items:center;display:flex;gap:4px}.fracto-devtools-stat-value{color:#00d4ff;font-weight:700}.fracto-devtools-content{flex:1;overflow:auto;padding:16px}.fracto-devtools-content::-webkit-scrollbar{width:8px}.fracto-devtools-content::-webkit-scrollbar-track{background:hsla(0,0%,100%,.02);border-radius:4px}.fracto-devtools-content::-webkit-scrollbar-thumb{background:linear-gradient(135deg,#00d4ff,#00a8ff);border-radius:4px}.fracto-devtools-content::-webkit-scrollbar-thumb:hover{background:linear-gradient(135deg,#00e4ff,#00b8ff)}.fracto-devtools-empty{align-items:center;color:#666;display:flex;flex-direction:column;gap:12px;padding:40px 20px;text-align:center}.fracto-devtools-empty-icon{align-items:center;background:linear-gradient(135deg,rgba(0,212,255,.1),rgba(0,168,255,.05));border:1px solid rgba(0,212,255,.2);border-radius:16px;display:flex;font-size:32px;height:64px;justify-content:center;opacity:.5;width:64px}.fracto-devtools-empty-title{font-size:14px;font-weight:500}.fracto-devtools-empty-subtitle{color:#555;font-size:12px}.fracto-devtools-flow{background:rgba(0,0,0,.3);border:1px solid rgba(0,212,255,.2);border-radius:10px;margin-bottom:12px;overflow:hidden;transition:all .2s}.fracto-devtools-flow:hover{border-color:rgba(0,212,255,.5);box-shadow:0 4px 16px rgba(0,212,255,.2)}.fracto-devtools-flow.collapsed .fracto-devtools-flow-content{display:none}.fracto-devtools-flow-header{align-items:center;background:linear-gradient(135deg,rgba(0,212,255,.1),rgba(0,168,255,.05));border-bottom:1px solid rgba(0,212,255,.2);cursor:pointer;display:flex;justify-content:space-between;padding:10px 14px;user-select:none}.fracto-devtools-flow.collapsed .fracto-devtools-flow-header{border-bottom:none}.fracto-devtools-flow-header-left{align-items:center;display:flex;flex:1;gap:8px;min-width:0}.fracto-devtools-flow-collapse-icon{color:#00d4ff;flex-shrink:0;font-size:12px;transition:transform .2s}.fracto-devtools-flow.collapsed .fracto-devtools-flow-collapse-icon{transform:rotate(-90deg)}.fracto-devtools-flow-key{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text;font-size:13px;font-weight:700;letter-spacing:.5px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.fracto-devtools-flow-actions{align-items:center;display:flex;gap:6px}.fracto-devtools-flow-badge{background:rgba(0,212,255,.15);border:1px solid rgba(0,212,255,.3);border-radius:4px;color:#00d4ff;font-size:10px;padding:2px 8px}.fracto-devtools-flow-action{align-items:center;background:rgba(0,0,0,.3);border:1px solid rgba(0,212,255,.2);border-radius:4px;color:#666;cursor:pointer;display:flex;font-size:12px;height:24px;justify-content:center;transition:all .2s;width:24px}.fracto-devtools-flow-action:hover{background:rgba(0,212,255,.1);border-color:rgba(0,212,255,.4);color:#00d4ff}.fracto-devtools-flow-content{background-color:rgba(0,0,0,.5);color:#ddd;font-size:11px;line-height:1.6;margin:0;max-height:300px;overflow-x:auto;overflow-y:auto;padding:12px 14px}.fracto-devtools-flow-content::-webkit-scrollbar{height:6px;width:6px}.fracto-devtools-flow-content::-webkit-scrollbar-track{background:hsla(0,0%,100%,.02)}.fracto-devtools-flow-content::-webkit-scrollbar-thumb{background:rgba(0,212,255,.3);border-radius:3px}.fracto-devtools-flow-content::-webkit-scrollbar-thumb:hover{background:rgba(0,212,255,.5)}.fracto-devtools-footer{align-items:center;background:rgba(0,0,0,.3);border-top:1px solid rgba(0,212,255,.2);color:#666;display:flex;font-size:10px;justify-content:space-between;padding:10px 20px}.fracto-devtools-footer-count{-webkit-text-fill-color:transparent;background:linear-gradient(135deg,#00d4ff,#00a8ff);-webkit-background-clip:text;background-clip:text;font-weight:700}.fracto-devtools-no-results{color:#666;padding:40px 20px;text-align:center}.fracto-devtools-no-results-icon{font-size:48px;margin-bottom:12px;opacity:.3}.fracto-devtools-no-results-title{font-size:14px;font-weight:500;margin-bottom:6px}.fracto-devtools-no-results-subtitle{color:#555;font-size:12px}.fracto-devtools-meta-tag{animation:pulse 1.5s infinite;background:rgba(0,212,255,.2);border-radius:4px;color:#00d4ff;font-size:10px;margin-left:8px;padding:1px 4px}@keyframes pulse{0%{opacity:.6}50%{opacity:1}to{opacity:.6}}.fracto-devtools-flow-expanded{background:rgba(0,0,0,.2);border-top:1px solid rgba(0,212,255,.1)}.fracto-devtools-meta-grid{background:rgba(0,212,255,.1);border-bottom:1px solid rgba(0,212,255,.1);display:grid;gap:1px;grid-template-columns:repeat(3,1fr)}.fracto-devtools-meta-item{align-items:center;background:#0a0a0f;display:flex;flex-direction:column;padding:6px 12px}.fracto-devtools-meta-item .label{color:#666;font-size:9px;letter-spacing:.5px;text-transform:uppercase}.fracto-devtools-meta-item .value{color:#00d4ff;font-size:12px;font-weight:700}.fracto-devtools-copy-toast{animation:slideDown .2s ease-out;background:#4caf50;border-radius:6px;box-shadow:0 4px 12px rgba(0,0,0,.5);color:#fff;font-size:10px;font-weight:700;padding:4px 10px;position:absolute;right:14px;top:40px;z-index:10}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}.fracto-devtools-flow-action.copied{background:rgba(76,175,80,.1);border-color:rgba(76,175,80,.5);color:#4caf50}.fracto-devtools-badge-count{align-items:center;animation:badgePop .3s cubic-bezier(.175,.885,.32,1.275);background:#f05;border:2px solid #0a0a0f;border-radius:9px;box-shadow:0 4px 8px rgba(255,0,85,.4);color:#fff;display:flex;font-size:10px;font-weight:900;height:18px;justify-content:center;min-width:18px;padding:0 4px;position:absolute;right:-5px;top:-5px}@keyframes badgePop{0%{transform:scale(0)}to{transform:scale(1)}}.fracto-devtools-button{cursor:grab;user-select:none}.fracto-devtools-button:active{cursor:grabbing}.fracto-devtools-actions{display:flex;gap:4px;margin-left:auto}.fracto-devtools-action-btn{align-items:center;background:rgba(0,212,255,.1);border:1px solid rgba(0,212,255,.3);border-radius:4px;color:#00d4ff;cursor:pointer;display:flex;font-size:14px;height:24px;justify-content:center;transition:all .2s;width:24px}.fracto-devtools-action-btn:hover{background:rgba(0,212,255,.2);border-color:rgba(0,212,255,.5)}.fracto-devtools-action-btn.is-dirty,.fracto-devtools-flow-action.is-dirty{background:rgba(74,222,128,.1)!important;border-color:rgba(74,222,128,.5)!important;box-shadow:0 0 10px rgba(74,222,128,.2);color:#4ade80!important}.fracto-devtools-action-btn.danger.is-dirty{background:rgba(255,77,77,.15)!important;border-color:rgba(255,77,77,.6)!important;box-shadow:0 0 12px rgba(255,77,77,.3);color:#ff4d4d!important}.fracto-devtools-action-btn.danger{background:rgba(255,77,77,.05);border-color:rgba(255,77,77,.1);color:#666}.fracto-devtools-action-btn.danger:hover{background:rgba(255,77,77,.2);border-color:rgba(255,77,77,.5)}.fracto-devtools-panel.is-maximized{border-radius:24px;bottom:20px!important;height:calc(100vh - 40px)!important;left:20px!important;right:20px!important;top:20px!important;width:calc(100vw - 40px)!important}:fullscreen .fracto-devtools-panel.is-maximized{border-radius:0;bottom:0!important;height:100vh!important;left:0!important;right:0!important;top:0!important;width:100vw!important}.fracto-devtools-max-minimal{align-items:center;background:none;border:none;color:#555;cursor:pointer;display:flex;font-size:14px;justify-content:center;margin-left:8px;padding:0 4px;transition:all .2s}.fracto-devtools-max-minimal:hover{color:#00d4ff}@keyframes spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.spinning{animation:spin 2s linear infinite}";
4
4
  if (typeof document !== 'undefined') {
5
5
  var style = document.createElement('style');
6
6
  style.setAttribute('type', 'text/css');
@@ -2,12 +2,17 @@
2
2
 
3
3
  var jsxRuntime = require('react/jsx-runtime');
4
4
  var react = require('react');
5
+ var reactDom = require('react-dom');
5
6
  var store = require('../store.js');
6
7
  require('./FractoDevTools.css.js');
8
+ require('./MentalMap.css.js');
9
+ var MentalMap = require('./MentalMap.js');
10
+ var lucideReact = require('lucide-react');
7
11
 
8
12
  const FractoDevTools = ({ position = "left", initialOpen = false, expanded = false, trafficLightsMode = "indicators", controlsPosition = "right", maximizeMode = "overlay", }) => {
9
13
  const [isOpen, setIsOpen] = react.useState(initialOpen);
10
14
  const [isMaximized, setIsMaximized] = react.useState(false);
15
+ const [showMentalMap, setShowMentalMap] = react.useState(false);
11
16
  const [snapshot, setSnapshot] = react.useState({});
12
17
  const [isInitialized, setIsInitialized] = react.useState(false);
13
18
  const [lastUpdate, setLastUpdate] = react.useState(0);
@@ -16,6 +21,7 @@ const FractoDevTools = ({ position = "left", initialOpen = false, expanded = fal
16
21
  const [collapsedFlows, setCollapsedFlows] = react.useState(new Set());
17
22
  const [copiedKey, setCopiedKey] = react.useState(null);
18
23
  const [flowCount, setFlowCount] = react.useState(0);
24
+ const [mentalMapSide, setMentalMapSide] = react.useState(position);
19
25
  // Dragging state
20
26
  const [coords, setCoords] = react.useState({ x: 20, y: 20 });
21
27
  const [isDragging, setIsDragging] = react.useState(false);
@@ -48,7 +54,7 @@ const FractoDevTools = ({ position = "left", initialOpen = false, expanded = fal
48
54
  return store.store.subscribeGlobal(updateCount);
49
55
  }, []);
50
56
  react.useEffect(() => {
51
- if (!isOpen)
57
+ if (!isOpen && !showMentalMap)
52
58
  return;
53
59
  setSnapshot(store.store.getDebugSnapshot());
54
60
  const unsub = store.store.subscribeGlobal(() => {
@@ -58,7 +64,7 @@ const FractoDevTools = ({ position = "left", initialOpen = false, expanded = fal
58
64
  setLastUpdate(Date.now());
59
65
  });
60
66
  return unsub;
61
- }, [isOpen]);
67
+ }, [isOpen, showMentalMap]);
62
68
  react.useEffect(() => {
63
69
  if (!isInitialized && Object.keys(snapshot).length > 0) {
64
70
  if (!expanded) {
@@ -139,18 +145,24 @@ const FractoDevTools = ({ position = "left", initialOpen = false, expanded = fal
139
145
  // Escape key handler
140
146
  react.useEffect(() => {
141
147
  const handleEsc = (e) => {
142
- if (e.key === "Escape" && isMaximized) {
143
- if (document.fullscreenElement) {
144
- document.exitFullscreen();
148
+ if (e.key === "Escape") {
149
+ if (showMentalMap) {
150
+ setShowMentalMap(false);
151
+ return;
145
152
  }
146
- else {
147
- setIsMaximized(false);
153
+ if (isMaximized) {
154
+ if (document.fullscreenElement) {
155
+ document.exitFullscreen();
156
+ }
157
+ else {
158
+ setIsMaximized(false);
159
+ }
148
160
  }
149
161
  }
150
162
  };
151
163
  window.addEventListener("keydown", handleEsc);
152
164
  return () => window.removeEventListener("keydown", handleEsc);
153
- }, [isMaximized]);
165
+ }, [isMaximized, showMentalMap]);
154
166
  const filteredEntries = react.useMemo(() => {
155
167
  let entries = Object.entries(snapshot);
156
168
  if (searchQuery.trim()) {
@@ -272,22 +284,34 @@ const FractoDevTools = ({ position = "left", initialOpen = false, expanded = fal
272
284
  [position]: `${coords.x}px`,
273
285
  bottom: `${coords.y}px`,
274
286
  };
275
- if (!isOpen) {
276
- return (jsxRuntime.jsxs("button", { onMouseDown: handleMouseDown, onClick: () => !isDragging && setIsOpen(true), className: `fracto-devtools-button position-${position}`, style: { ...positionStyle, cursor: isDragging ? "grabbing" : "grab" }, title: "Open FractoState DevTools (Draggable)", children: ["F", flowCount > 0 && (jsxRuntime.jsx("span", { className: "fracto-devtools-badge-count", children: flowCount }))] }));
277
- }
278
- return (jsxRuntime.jsxs("div", { className: `fracto-devtools-panel position-${position} ${isMaximized ? "is-maximized" : ""}`, style: isMaximized ? {} : positionStyle, children: [jsxRuntime.jsxs("div", { className: `fracto-devtools-header mode-${trafficLightsMode} controls-${controlsPosition}`, children: [trafficLightsMode === "controls" && (jsxRuntime.jsxs("div", { className: "fracto-devtools-window-controls", children: [jsxRuntime.jsx("button", { className: "fracto-devtools-dot red", onClick: () => setIsOpen(false), title: "Close Inspector" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot yellow", onClick: collapseAll, title: "Collapse All" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot green", onClick: expandAll, title: "Expand All" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot blue", onClick: toggleMaximize, title: isMaximized ? "Restore" : "Maximize" })] })), jsxRuntime.jsxs("div", { className: "fracto-devtools-header-content", children: [jsxRuntime.jsx("div", { className: `fracto-devtools-logo ${lastUpdate ? "pulse" : ""}`, children: "F" }, lastUpdate), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-title", children: ["Fracto", jsxRuntime.jsx("span", { className: "fracto-devtools-title-state", children: "State" })] }), jsxRuntime.jsx("div", { className: "fracto-devtools-subtitle", children: "Advanced Inspector" })] })] }), trafficLightsMode === "indicators" && (jsxRuntime.jsxs("div", { className: "fracto-devtools-window-indicators", children: [jsxRuntime.jsx("div", { className: `fracto-devtools-dot red ${activeIndicators.red ? "active" : ""}`, title: "State Reset/Undo" }), jsxRuntime.jsx("div", { className: `fracto-devtools-dot yellow ${activeIndicators.yellow ? "active" : ""}`, title: "State Activity (Read/Write)" }), jsxRuntime.jsx("div", { className: `fracto-devtools-dot green ${flowCount > 0 ? "active" : ""}`, title: flowCount > 0
287
+ // Stable handler for minimize change.
288
+ // We ensure the main panel stays closed when Mental Map is active/minimized.
289
+ const handleMinimizeChange = react.useCallback((_min) => {
290
+ setIsOpen(false);
291
+ }, []);
292
+ const mentalMapPortal = showMentalMap &&
293
+ reactDom.createPortal(jsxRuntime.jsx(MentalMap.MentalMap, { snapshot: snapshot, onClose: () => {
294
+ setShowMentalMap(false);
295
+ setIsOpen(true);
296
+ }, onMinimizeChange: handleMinimizeChange, minimizedSide: mentalMapSide, setIsOpen: setIsOpen }), document.body);
297
+ const buttonContent = (jsxRuntime.jsxs("button", { onMouseDown: handleMouseDown, onClick: () => !isDragging && setIsOpen(true), className: `fracto-devtools-button position-${position}`, style: { ...positionStyle, cursor: isDragging ? "grabbing" : "grab" }, title: "Open FractoState DevTools (Draggable)", children: ["F", flowCount > 0 && (jsxRuntime.jsx("span", { className: "fracto-devtools-badge-count", children: flowCount }))] }));
298
+ const panelContent = (jsxRuntime.jsxs("div", { className: `fracto-devtools-panel position-${position} ${isMaximized ? "is-maximized" : ""}`, style: isMaximized ? {} : positionStyle, children: [jsxRuntime.jsxs("div", { className: `fracto-devtools-header mode-${trafficLightsMode} controls-${controlsPosition}`, children: [trafficLightsMode === "controls" && (jsxRuntime.jsxs("div", { className: "fracto-devtools-window-controls", children: [jsxRuntime.jsx("button", { className: "fracto-devtools-dot red", onClick: () => setIsOpen(false), title: "Close Inspector" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot yellow", onClick: collapseAll, title: "Collapse All" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot green", onClick: expandAll, title: "Expand All" }), jsxRuntime.jsx("button", { className: "fracto-devtools-dot blue", onClick: toggleMaximize, title: isMaximized ? "Restore" : "Maximize" })] })), jsxRuntime.jsxs("div", { className: "fracto-devtools-header-content", children: [jsxRuntime.jsx("div", { className: `fracto-devtools-logo ${lastUpdate ? "pulse" : ""}`, children: "F" }, lastUpdate), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-title", children: ["Fracto", jsxRuntime.jsx("span", { className: "fracto-devtools-title-state", children: "State" })] }), jsxRuntime.jsx("div", { className: "fracto-devtools-subtitle", children: "Advanced Inspector" })] })] }), trafficLightsMode === "indicators" && (jsxRuntime.jsxs("div", { className: "fracto-devtools-window-indicators", children: [jsxRuntime.jsx("div", { className: `fracto-devtools-dot red ${activeIndicators.red ? "active" : ""}`, title: "State Reset/Undo" }), jsxRuntime.jsx("div", { className: `fracto-devtools-dot yellow ${activeIndicators.yellow ? "active" : ""}`, title: "State Activity (Read/Write)" }), jsxRuntime.jsx("div", { className: `fracto-devtools-dot green ${flowCount > 0 ? "active" : ""}`, title: flowCount > 0
279
299
  ? "Engine Online: Flows Active"
280
- : "Engine Standby: No Flows" }), jsxRuntime.jsx("button", { className: "fracto-devtools-max-minimal", onClick: toggleMaximize, title: isMaximized ? "Minimize" : "Maximize", children: isMaximized ? (jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M8 3v5H3M21 8h-5V3M3 16h5v5M16 21v-5h5" }) })) : (jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2.5", strokeLinecap: "round", strokeLinejoin: "round", children: jsxRuntime.jsx("path", { d: "M15 3h6v6M9 21H3v-6M21 3l-7 7M3 21l7-7" }) })) }), jsxRuntime.jsx("button", { className: "fracto-devtools-close-minimal", onClick: () => setIsOpen(false), title: "Close", children: "\u00D7" })] }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-toolbar", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-search-container", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-search-icon", children: "\uD83D\uDD0D" }), jsxRuntime.jsx("input", { type: "text", className: "fracto-devtools-search", placeholder: "Search flows...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value) }), searchQuery && (jsxRuntime.jsx("button", { className: "fracto-devtools-clear-search", onClick: () => setSearchQuery(""), children: "Clear" }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-filters", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-filter-buttons", children: [jsxRuntime.jsxs("button", { className: `fracto-devtools-filter-button ${viewMode === "all" ? "active" : ""}`, onClick: () => setViewMode("all"), children: ["All (", stats.total, ")"] }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "objects" ? "active" : ""}`, onClick: () => setViewMode("objects"), children: "Objects" }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "arrays" ? "active" : ""}`, onClick: () => setViewMode("arrays"), children: "Arrays" }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "primitives" ? "active" : ""}`, onClick: () => setViewMode("primitives"), children: "Primitives" })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-actions", children: [jsxRuntime.jsx("button", { onClick: handleResetAll, className: `fracto-devtools-action-btn danger ${isGlobalDirty ? "is-dirty" : ""}`, title: isGlobalDirty
300
+ : "Engine Standby: No Flows" }), jsxRuntime.jsx("button", { className: "fracto-devtools-max-minimal", onClick: toggleMaximize, title: isMaximized ? "Minimize" : "Maximize", children: isMaximized ? (jsxRuntime.jsx(lucideReact.Minimize2, { size: 12, strokeWidth: 2.5 })) : (jsxRuntime.jsx(lucideReact.Maximize2, { size: 12, strokeWidth: 2.5 })) }), jsxRuntime.jsx("button", { className: "fracto-devtools-close-minimal", onClick: () => setIsOpen(false), title: "Close", children: jsxRuntime.jsx(lucideReact.X, { size: 14, strokeWidth: 2.5 }) })] }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-toolbar", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-search-container", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-search-icon", children: "\uD83D\uDD0D" }), jsxRuntime.jsx("input", { type: "text", className: "fracto-devtools-search", placeholder: "Search flows...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value) }), searchQuery && (jsxRuntime.jsx("button", { className: "fracto-devtools-clear-search", onClick: () => setSearchQuery(""), children: "Clear" }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-filters", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-filter-buttons", children: [jsxRuntime.jsxs("button", { className: `fracto-devtools-filter-button ${viewMode === "all" ? "active" : ""}`, onClick: () => setViewMode("all"), children: ["All (", stats.total, ")"] }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "objects" ? "active" : ""}`, onClick: () => setViewMode("objects"), children: "Objects" }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "arrays" ? "active" : ""}`, onClick: () => setViewMode("arrays"), children: "Arrays" }), jsxRuntime.jsx("button", { className: `fracto-devtools-filter-button ${viewMode === "primitives" ? "active" : ""}`, onClick: () => setViewMode("primitives"), children: "Primitives" })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-actions", children: [jsxRuntime.jsx("button", { onClick: handleResetAll, className: `fracto-devtools-action-btn danger ${isGlobalDirty ? "is-dirty" : ""}`, title: isGlobalDirty
281
301
  ? "Reset All Flows"
282
- : "All flows are at initial state", children: "\u21BA" }), jsxRuntime.jsx("button", { onClick: collapseAll, className: "fracto-devtools-action-btn", title: "Collapse All", children: "\u21CA" }), jsxRuntime.jsx("button", { onClick: expandAll, className: "fracto-devtools-action-btn", title: "Expand All", children: "\u21C8" })] })] })] }), jsxRuntime.jsx("div", { className: "fracto-devtools-content", children: filteredEntries.length === 0 ? (jsxRuntime.jsx("div", { className: "fracto-devtools-empty", children: "No flows detected" })) : (filteredEntries.map(([key, data]) => (jsxRuntime.jsxs("div", { className: `fracto-devtools-flow ${collapsedFlows.has(key) ? "collapsed" : ""}`, children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-header", onClick: () => toggleCollapse(key), children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-header-left", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-flow-collapse-icon", children: "\u25BC" }), jsxRuntime.jsx("div", { className: "fracto-devtools-flow-key", children: key }), data.meta.isDebouncing && (jsxRuntime.jsx("span", { className: "fracto-devtools-meta-tag", title: "Sync pending", children: "\u23F3" }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-actions", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-flow-badge", children: getValueType(data.value) }), jsxRuntime.jsx("button", { className: `fracto-devtools-flow-action ${data.meta.isDirty ? "is-dirty" : ""}`, onClick: (e) => {
302
+ : "All flows are at initial state", children: jsxRuntime.jsx(lucideReact.RotateCcw, { size: 16 }) }), jsxRuntime.jsx("button", { onClick: () => setMentalMapSide((prev) => (prev === "left" ? "right" : "left")), className: "fracto-devtools-action-btn", title: `Map Logo default: ${mentalMapSide}`, children: mentalMapSide === "left" ? (jsxRuntime.jsx(lucideReact.ChevronLeft, { size: 16 })) : (jsxRuntime.jsx(lucideReact.ChevronRight, { size: 16 })) }), jsxRuntime.jsx("button", { onClick: () => {
303
+ setShowMentalMap(true);
304
+ setIsOpen(false);
305
+ }, className: "fracto-devtools-action-btn", style: { fontSize: "16px" }, title: "Mental Map & Traces", children: jsxRuntime.jsx(lucideReact.Activity, { size: 18 }) }), jsxRuntime.jsx("button", { onClick: collapseAll, className: "fracto-devtools-action-btn", title: "Collapse All", children: jsxRuntime.jsx(lucideReact.ArrowDownToLine, { size: 16 }) }), jsxRuntime.jsx("button", { onClick: expandAll, className: "fracto-devtools-action-btn", title: "Expand All", children: jsxRuntime.jsx(lucideReact.ArrowUpToLine, { size: 16 }) })] })] })] }), jsxRuntime.jsx("div", { className: "fracto-devtools-content", children: filteredEntries.length === 0 ? (jsxRuntime.jsx("div", { className: "fracto-devtools-empty", children: "No flows detected" })) : (filteredEntries.map(([key, data]) => (jsxRuntime.jsxs("div", { className: `fracto-devtools-flow ${collapsedFlows.has(key) ? "collapsed" : ""}`, children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-header", onClick: () => toggleCollapse(key), children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-header-left", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-flow-collapse-icon", children: collapsedFlows.has(key) ? (jsxRuntime.jsx(lucideReact.ChevronRight, { size: 14 })) : (jsxRuntime.jsx(lucideReact.ChevronDown, { size: 14 })) }), jsxRuntime.jsx("div", { className: "fracto-devtools-flow-key", children: key }), data.meta.isDebouncing && (jsxRuntime.jsx("span", { className: "fracto-devtools-meta-tag", title: "Sync pending", children: jsxRuntime.jsx(lucideReact.History, { size: 12, className: "spinning" }) }))] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-actions", children: [jsxRuntime.jsx("span", { className: "fracto-devtools-flow-badge", children: getValueType(data.value) }), jsxRuntime.jsx("button", { className: `fracto-devtools-flow-action ${data.meta.isDirty ? "is-dirty" : ""}`, onClick: (e) => {
283
306
  e.stopPropagation();
284
307
  handleResetFlow(key, data.meta.isDirty);
285
308
  }, title: data.meta.isDirty
286
309
  ? "Reset Flow"
287
- : "Flow is at initial state", children: "\u21BA" }), jsxRuntime.jsx("button", { className: `fracto-devtools-flow-action ${copiedKey === key ? "copied" : ""}`, onClick: (e) => {
310
+ : "Flow is at initial state", children: jsxRuntime.jsx(lucideReact.RotateCcw, { size: 14 }) }), jsxRuntime.jsx("button", { className: `fracto-devtools-flow-action ${copiedKey === key ? "copied" : ""}`, onClick: (e) => {
288
311
  e.stopPropagation();
289
312
  handleCopy(key, data.value);
290
- }, children: copiedKey === key ? "✓" : "❐" })] })] }), !collapsedFlows.has(key) && (jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-expanded", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-grid", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "Listeners:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.listeners })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "History:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.historySize })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "Redo:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.redoSize })] })] }), jsxRuntime.jsx("pre", { className: "fracto-devtools-flow-content", children: JSON.stringify(data.value, null, 2) })] })), copiedKey === key && (jsxRuntime.jsx("div", { className: "fracto-devtools-copy-toast", children: "Copied!" }))] }, key)))) }), jsxRuntime.jsxs("div", { className: "fracto-devtools-footer", children: [jsxRuntime.jsx("span", { children: "FractoState Engine v1.0.2" }), jsxRuntime.jsxs("span", { className: "fracto-devtools-footer-count", children: [filteredEntries.length, " items"] })] })] }));
313
+ }, children: copiedKey === key ? (jsxRuntime.jsx(lucideReact.Zap, { size: 14 })) : (jsxRuntime.jsx(lucideReact.Monitor, { size: 14 })) })] })] }), !collapsedFlows.has(key) && (jsxRuntime.jsxs("div", { className: "fracto-devtools-flow-expanded", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-grid", children: [jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "Listeners:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.listeners })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "History:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.historySize })] }), jsxRuntime.jsxs("div", { className: "fracto-devtools-meta-item", children: [jsxRuntime.jsx("span", { className: "label", children: "Redo:" }), jsxRuntime.jsx("span", { className: "value", children: data.meta.redoSize })] })] }), jsxRuntime.jsx("pre", { className: "fracto-devtools-flow-content", children: JSON.stringify(data.value, null, 2) })] })), copiedKey === key && (jsxRuntime.jsx("div", { className: "fracto-devtools-copy-toast", children: "Copied!" }))] }, key)))) }), jsxRuntime.jsxs("div", { className: "fracto-devtools-footer", children: [jsxRuntime.jsx("span", { children: "FractoState Engine v5" }), jsxRuntime.jsxs("span", { className: "fracto-devtools-footer-count", children: [filteredEntries.length, " items"] })] })] }));
314
+ return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [isOpen ? panelContent : showMentalMap ? null : buttonContent, mentalMapPortal] }));
291
315
  };
292
316
 
293
317
  exports.FractoDevTools = FractoDevTools;