@nice-code/state 0.7.0 → 0.9.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 (37) hide show
  1. package/build/Store-B65MojT2.d.ts +201 -0
  2. package/build/Store-CI9N0P6I.js +366 -0
  3. package/build/Store-CI9N0P6I.js.map +1 -0
  4. package/build/Store-PjfFkZ2I.js +349 -0
  5. package/build/Store-PjfFkZ2I.js.map +1 -0
  6. package/build/devtools/browser/index.d.ts +120 -0
  7. package/build/devtools/browser/index.js +2750 -2357
  8. package/build/devtools/browser/index.js.map +1 -0
  9. package/build/index.d.ts +2 -0
  10. package/build/index.js +2 -244
  11. package/build/react/index.d.ts +58 -0
  12. package/build/react/index.js +59 -308
  13. package/build/react/index.js.map +1 -0
  14. package/package.json +29 -26
  15. package/build/types/core/Store.d.ts +0 -136
  16. package/build/types/core/index.d.ts +0 -1
  17. package/build/types/devtools/browser/NiceStateDevtools.d.ts +0 -10
  18. package/build/types/devtools/browser/components/ChangeDetailPanel.d.ts +0 -12
  19. package/build/types/devtools/browser/components/ChangeList.d.ts +0 -9
  20. package/build/types/devtools/browser/components/DiffView.d.ts +0 -13
  21. package/build/types/devtools/browser/components/JsonDiffView.d.ts +0 -24
  22. package/build/types/devtools/browser/components/JsonView.d.ts +0 -7
  23. package/build/types/devtools/browser/components/PanelChrome.d.ts +0 -54
  24. package/build/types/devtools/browser/components/SectionLabel.d.ts +0 -4
  25. package/build/types/devtools/browser/components/StateInspector.d.ts +0 -16
  26. package/build/types/devtools/browser/components/StoreTabs.d.ts +0 -12
  27. package/build/types/devtools/browser/components/utils.d.ts +0 -98
  28. package/build/types/devtools/browser/devtools_dock.d.ts +0 -54
  29. package/build/types/devtools/browser/index.d.ts +0 -3
  30. package/build/types/devtools/core/StateDevtools.types.d.ts +0 -43
  31. package/build/types/devtools/core/StateDevtoolsCore.d.ts +0 -56
  32. package/build/types/devtools/core/devtools_colors.d.ts +0 -26
  33. package/build/types/index.d.ts +0 -1
  34. package/build/types/react/InjectStoreState.d.ts +0 -18
  35. package/build/types/react/index.d.ts +0 -3
  36. package/build/types/react/useLocalStore.d.ts +0 -8
  37. package/build/types/react/useStoreState.d.ts +0 -23
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":["ADDED_BG","REMOVED_BG"],"sources":["../../../src/devtools/core/StateDevtoolsCore.ts","../../../../nice-devtools-shared/src/colors.ts","../../../../nice-devtools-shared/src/format.ts","../../../../nice-devtools-shared/src/json.tsx","../../../../nice-devtools-shared/src/dock.ts","../../../../nice-devtools-shared/src/list.ts","../../../../nice-devtools-shared/src/components/SectionLabel.tsx","../../../../../node_modules/.bun/react-dom@19.2.7+e14d3f224186685e/node_modules/react-dom/cjs/react-dom.production.js","../../../../../node_modules/.bun/react-dom@19.2.7+e14d3f224186685e/node_modules/react-dom/index.js","../../../../nice-devtools-shared/src/components/Tooltip.tsx","../../../../nice-devtools-shared/src/components/PanelChrome.tsx","../../../../nice-devtools-shared/src/components/FollowLatestToggles.tsx","../../../../nice-devtools-shared/src/components/VirtualList.tsx","../../../src/devtools/core/devtools_colors.ts","../../../src/devtools/browser/components/utils.ts","../../../src/devtools/browser/components/DiffView.tsx","../../../src/devtools/browser/components/JsonDiffView.tsx","../../../src/devtools/browser/components/ChangeDetailPanel.tsx","../../../src/devtools/browser/components/ChangeList.tsx","../../../src/devtools/browser/components/StateInspector.tsx","../../../src/devtools/browser/components/StoreTabs.tsx","../../../src/devtools/browser/NiceStateDevtools.tsx"],"sourcesContent":["import type { Patch } from \"immer\";\nimport type { Store } from \"../../core/Store\";\nimport type {\n IDevtoolsStateChange,\n IDevtoolsStoreInfo,\n IStateDevtoolsSnapshot,\n TStateChangeSource,\n TStateDevtoolsListener,\n} from \"./StateDevtools.types\";\n\nexport interface IStateDevtoolsCoreOptions {\n /** Cap on retained changes across all stores (oldest dropped first). */\n maxChanges?: number;\n}\n\ninterface IRegisteredStore {\n id: string;\n label: string;\n // biome-ignore lint/suspicious/noExplicitAny: the core observes stores of any shape.\n store: Store<any>;\n currentState: unknown;\n changeCount: number;\n lastChangeTime?: number;\n unsubscribe: () => void;\n}\n\n/**\n * Framework-agnostic collector for nice-state stores.\n *\n * Register any {@link Store} and the core hooks its patch + update streams,\n * pairing the two so each committed mutation becomes a single\n * {@link IDevtoolsStateChange} with patches and full before/after snapshots.\n * The browser panel ({@link NiceStateDevtools}) renders whatever this exposes.\n *\n * Registering a store attaches a patch listener, which makes Immer compute\n * patches for that store's updates — a negligible dev-time cost. Keep this out\n * of production bundles (the panel is dev-gated, but the core is not).\n */\nexport class StateDevtoolsCore {\n private readonly _stores = new Map<string, IRegisteredStore>();\n private _changes: IDevtoolsStateChange[] = [];\n private readonly _listeners = new Set<TStateDevtoolsListener>();\n private readonly _maxChanges: number;\n private _paused = false;\n private _cuidCounter = 0;\n\n // Set immediately before a devtools-initiated write so the synchronous\n // subscribe callback can attribute the resulting change. Always cleared in a\n // `finally`, so a no-op write can never leak it onto the next real change.\n private _sourceOverride: TStateChangeSource | null = null;\n\n constructor(options: IStateDevtoolsCoreOptions = {}) {\n this._maxChanges = options.maxChanges ?? 250;\n }\n\n /**\n * Start observing a store under a human-readable label. Returns an\n * unregister function. If the label collides with an existing store, a numeric\n * suffix is appended to keep ids unique.\n */\n // biome-ignore lint/suspicious/noExplicitAny: accepts a store of any state shape.\n registerStore(label: string, store: Store<any>): () => void {\n const id = this._uniqueId(label);\n\n let lastSnapshot: unknown = store.getRawState();\n let pendingPatches: Patch[] = [];\n let pendingInverse: Patch[] = [];\n\n // Patches are emitted before the subscribe notification on the `update`\n // path, and during it for reaction-derived changes — either way they are\n // all queued before the subscribe callback below drains them.\n const unsubPatches = store.listenToPatches((patches, inverse) => {\n for (const p of patches) pendingPatches.push(p);\n for (const p of inverse) pendingInverse.push(p);\n });\n\n const unsubUpdate = store.subscribe(() => {\n const snapshot = store.getRawState();\n const patches = pendingPatches;\n const inverse = pendingInverse;\n pendingPatches = [];\n pendingInverse = [];\n\n const reg = this._stores.get(id);\n if (reg != null) reg.currentState = snapshot;\n\n const source: TStateChangeSource =\n this._sourceOverride ?? (patches.length > 0 ? \"update\" : \"replace\");\n\n const prevSnapshot = lastSnapshot;\n lastSnapshot = snapshot;\n\n if (this._paused) {\n // Keep the inspector live but don't grow the timeline while paused.\n this._notify();\n return;\n }\n\n this._recordChange(id, {\n cuid: `chg_${++this._cuidCounter}`,\n storeId: id,\n storeLabel: label,\n timestamp: Date.now(),\n patches,\n inversePatches: inverse,\n prevSnapshot,\n snapshot,\n source,\n });\n });\n\n this._stores.set(id, {\n id,\n label,\n store,\n currentState: lastSnapshot,\n changeCount: 0,\n unsubscribe: () => {\n unsubPatches();\n unsubUpdate();\n },\n });\n\n this._notify();\n\n return () => this.unregisterStore(id);\n }\n\n unregisterStore(id: string): void {\n const reg = this._stores.get(id);\n if (reg == null) return;\n reg.unsubscribe();\n this._stores.delete(id);\n this._changes = this._changes.filter((c) => c.storeId !== id);\n this._notify();\n }\n\n /**\n * Replace a registered store's state wholesale — the primary \"edit directly\n * for testing\" entry point. The resulting change is tagged `devtools-edit`.\n */\n applyEdit(storeId: string, newState: unknown): void {\n const reg = this._stores.get(storeId);\n if (reg == null) return;\n this._sourceOverride = \"devtools-edit\";\n try {\n reg.store.replace(newState);\n } finally {\n this._sourceOverride = null;\n }\n }\n\n /**\n * Undo a change by applying its inverse patches. Cleanest for the most recent\n * change of a store; older reverts may not apply if later changes touched the\n * same paths. The resulting change is tagged `devtools-revert`.\n */\n revertChange(change: IDevtoolsStateChange): void {\n const reg = this._stores.get(change.storeId);\n if (reg == null || change.inversePatches.length === 0) return;\n this._sourceOverride = \"devtools-revert\";\n try {\n reg.store.applyPatches(change.inversePatches);\n } finally {\n this._sourceOverride = null;\n }\n }\n\n setPaused(paused: boolean): void {\n if (this._paused === paused) return;\n this._paused = paused;\n this._notify();\n }\n\n togglePaused(): void {\n this.setPaused(!this._paused);\n }\n\n /** Drop the recorded timeline; registered stores and their state remain. */\n clear(): void {\n this._changes = [];\n for (const reg of this._stores.values()) {\n reg.changeCount = 0;\n reg.lastChangeTime = undefined;\n }\n this._notify();\n }\n\n getSnapshot(): IStateDevtoolsSnapshot {\n return this._buildSnapshot();\n }\n\n subscribe(listener: TStateDevtoolsListener): () => void {\n this._listeners.add(listener);\n listener(this._buildSnapshot());\n return () => {\n this._listeners.delete(listener);\n };\n }\n\n private _recordChange(id: string, change: IDevtoolsStateChange): void {\n const reg = this._stores.get(id);\n if (reg != null) {\n reg.changeCount += 1;\n reg.lastChangeTime = change.timestamp;\n }\n this._changes = [change, ...this._changes];\n if (this._changes.length > this._maxChanges) {\n this._changes.length = this._maxChanges;\n }\n this._notify();\n }\n\n private _uniqueId(label: string): string {\n if (!this._stores.has(label)) return label;\n let n = 2;\n while (this._stores.has(`${label} (${n})`)) n += 1;\n return `${label} (${n})`;\n }\n\n private _buildSnapshot(): IStateDevtoolsSnapshot {\n const stores: IDevtoolsStoreInfo[] = [];\n for (const reg of this._stores.values()) {\n stores.push({\n id: reg.id,\n label: reg.label,\n currentState: reg.currentState,\n changeCount: reg.changeCount,\n lastChangeTime: reg.lastChangeTime,\n });\n }\n return { stores, changes: this._changes, paused: this._paused };\n }\n\n private _notify(): void {\n const snapshot = this._buildSnapshot();\n for (const listener of this._listeners) listener(snapshot);\n }\n}\n","// Shared visual language for the nice-* devtools (nice-action + nice-state).\n//\n// These tokens are the single source of truth for the palette both devtools\n// suites paint with, so the two feel like siblings when used side by side.\n// Package-specific colours (e.g. nice-action's handler/stack-frame roles or\n// nice-state's editor surface) live in each package's own `devtools_colors`\n// module, which re-exports everything from here.\n\n// ─── The 5 canonical semantic tokens ─────────────────────────────────────────\n// Every status / role colour in the devtools must resolve to one of these five.\nexport const DEVTOOL_COLOR_SEMANTIC_ERROR = \"#FF5C5C\"; // Critical failures, error messages, error borders\nexport const DEVTOOL_COLOR_SEMANTIC_SUCCESS = \"#A3E635\"; // Successful execution, routing hops, add patches\nexport const DEVTOOL_COLOR_SEMANTIC_SYSTEM = \"#38BDF8\"; // System actions, domain/store tags, clickable links\nexport const DEVTOOL_COLOR_SEMANTIC_WARNING = \"#FB923C\"; // Intermediate statuses, timing highlights, edits\nexport const DEVTOOL_COLOR_SEMANTIC_METADATA = \"#A1A1AA\"; // Timestamps, non-interactive labels, timeline\n\n// ─── Text hierarchy (4 levels — no intermediate aliases) ─────────────────────\nexport const DEVTOOL_COLOR_TEXT_EMPHASIS = \"#f1f5f9\"; // Primary content — names, headings\nexport const DEVTOOL_COLOR_TEXT_SECONDARY = \"#cbd5e1\"; // General readable content\nexport const DEVTOOL_COLOR_TEXT_MUTED = \"#64748b\"; // Supporting / subdued labels\nexport const DEVTOOL_COLOR_TEXT_FAINT = \"#334155\"; // Near-invisible chrome, expand arrows\n\n// ─── Surface / layout palette ─────────────────────────────────────────────────\nexport const DEVTOOL_LIST_BASE_BACKGROUND = \"#0f172a\";\nexport const DEVTOOL_LIST_SELECTED_BACKGROUND = \"#1d2942\";\nexport const DEVTOOL_DETAIL_BASE_BACKGROUND = \"#0d1729\";\nexport const DEVTOOL_DETAIL_HEADER_BACKGROUND = \"#131f35\";\nexport const DEVTOOL_SECTION_BACKGROUND = \"#1e293b\";\nexport const DEVTOOL_SECTION_STRING_BACKGROUND = \"#0d131f\";\nexport const DEVTOOL_PANEL_BORDER = \"#1e293b\";\nexport const DEVTOOL_PANEL_DIVIDER_BORDER = \"#1d3352\";\n\n// ─── Error display surface ────────────────────────────────────────────────────\nexport const DEVTOOL_ERROR_BACKGROUND = \"#1e0a0a\";\n\n// ─── Tooltip ──────────────────────────────────────────────────────────────────\nexport const DEVTOOL_TOOLTIP_BACKGROUND = \"#0c1526\";\nexport const DEVTOOL_TOOLTIP_TITLE_BACKGROUND = \"#101b2e\";\nexport const DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER = \"#211f5f\";\nexport const DEVTOOL_TOOLTIP_BORDER = \"#312e81\";\n\n// ─── JSON syntax highlighting ─────────────────────────────────────────────────\nexport const DEVTOOL_JSON_KEY = \"#a5b4fc\";\nexport const DEVTOOL_JSON_STRING = \"#fbbf24\";\nexport const DEVTOOL_JSON_NUMBER = \"#34d399\";\nexport const DEVTOOL_JSON_KEYWORD = \"#a78bfa\";\nexport const DEVTOOL_JSON_PUNCTUATION = \"#475569\";\n\n// ─── Fonts ──────────────────────────────────────────────────────────────────--\nexport const MONO_FONT = \"ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace\";\nexport const SANS_FONT = \"ui-sans-serif, system-ui, sans-serif\";\n","// Small, dependency-free formatting helpers shared by both devtools suites.\n\n/** Pretty-print any value to JSON, degrading gracefully for cyclic / non-JSON values. */\nexport function safeStringify(value: unknown, indent = 2): string {\n if (value === undefined) return \"undefined\";\n if (value === null) return \"null\";\n try {\n return JSON.stringify(value, null, indent);\n } catch {\n return String(value);\n }\n}\n\n/** Wall-clock time of day, e.g. `14:03:09`. */\nexport function formatTimestamp(ms: number): string {\n return new Date(ms).toLocaleTimeString([], {\n hour: \"2-digit\",\n minute: \"2-digit\",\n second: \"2-digit\",\n hour12: false,\n });\n}\n\n/** Compact relative age: `850ms`, `3.2s`, `4m`. */\nexport function formatRelativeAge(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60_000) return `${(ms / 1000).toFixed(1)}s`;\n return `${Math.floor(ms / 60_000)}m`;\n}\n","import type { CSSProperties, ReactNode } from \"react\";\nimport {\n DEVTOOL_JSON_KEY,\n DEVTOOL_JSON_KEYWORD,\n DEVTOOL_JSON_NUMBER,\n DEVTOOL_JSON_PUNCTUATION,\n DEVTOOL_JSON_STRING,\n DEVTOOL_SECTION_STRING_BACKGROUND,\n MONO_FONT,\n} from \"./colors\";\nimport { safeStringify } from \"./format\";\n\n// Regex-based JSON tokenizer — strings (and the `:` that may follow a key),\n// numbers, keywords and structural punctuation each get their own colour.\nconst JSON_TOKEN_RE =\n /(\"(?:\\\\.|[^\"\\\\])*\")(\\s*:)?|(-?\\d+(?:\\.\\d+)?(?:[eE][+-]?\\d+)?)|(\\btrue\\b|\\bfalse\\b|\\bnull\\b|\\bundefined\\b)|([{}[\\],])/g;\n\n/** Tokenize a JSON string into coloured <span> nodes for inline rendering. */\nexport function renderColoredJson(text: string): ReactNode[] {\n const nodes: ReactNode[] = [];\n let last = 0;\n let i = 0;\n JSON_TOKEN_RE.lastIndex = 0;\n for (let m = JSON_TOKEN_RE.exec(text); m !== null; m = JSON_TOKEN_RE.exec(text)) {\n if (m.index > last) nodes.push(text.slice(last, m.index));\n const [, str, colon, num, kw, punct] = m;\n if (str != null) {\n if (colon != null) {\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_KEY }}>\n {str}\n </span>,\n );\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_PUNCTUATION }}>\n {colon}\n </span>,\n );\n } else {\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_STRING }}>\n {str}\n </span>,\n );\n }\n } else if (num != null) {\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_NUMBER }}>\n {num}\n </span>,\n );\n } else if (kw != null) {\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_KEYWORD }}>\n {kw}\n </span>,\n );\n } else if (punct != null) {\n nodes.push(\n <span key={i++} style={{ color: DEVTOOL_JSON_PUNCTUATION }}>\n {punct}\n </span>,\n );\n }\n last = JSON_TOKEN_RE.lastIndex;\n }\n if (last < text.length) nodes.push(text.slice(last));\n return nodes;\n}\n\n/** A pre-formatted, syntax-highlighted JSON block. */\nexport function JsonView({\n value,\n indent = 2,\n style,\n}: {\n value: unknown;\n indent?: number;\n style?: CSSProperties;\n}) {\n const text = safeStringify(value, indent);\n return (\n <pre\n style={{\n margin: 0,\n padding: \"8px 10px\",\n borderRadius: \"4px\",\n fontSize: \"11px\",\n lineHeight: 1.5,\n fontFamily: MONO_FONT,\n background: DEVTOOL_SECTION_STRING_BACKGROUND,\n overflowX: \"auto\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n ...style,\n }}\n >\n {renderColoredJson(text)}\n </pre>\n );\n}\n","// ─── Shared devtools dock coordinator ────────────────────────────────────────\n//\n// The nice-action and nice-state devtools are independent packages, but when\n// both are mounted on the same page their panels would fight over screen space,\n// over `document.body`'s margins, and their collapsed launch buttons would land\n// on top of each other. This coordinator lets them cooperate WITHOUT importing\n// each other: it lives on a single versioned `window` global (the same approach\n// the React DevTools hook uses), so whichever package loads first installs the\n// engine and the other simply reuses it.\n//\n// Responsibilities:\n// • Own all four `document.body` margins centrally (no more stomping).\n// • Stack panels docked to the same side so they sit edge-to-edge (`dockOffset`).\n// • Provide a single \"primary\" devtool that renders ONE combined launcher\n// listing every devtool while they are all closed.\n// • Tell each OPEN panel which other devtools are still closed, so it can offer\n// to open them from its own header.\n//\n// This now lives in nice-devtools-shared so both packages link the SAME engine\n// at the source level. The `window` global + VERSION guard is still kept so a\n// page mixing mismatched published versions falls back gracefully.\n\nexport type TDockSide = \"top\" | \"bottom\" | \"left\" | \"right\";\n\n/** A handle to one registered devtool, used to render launch controls. */\nexport interface IDockDevtoolRef {\n id: string;\n label: string;\n icon: string;\n badge?: string;\n onOpen: () => void;\n}\n\n/** The live, syncable part of a devtool's registration. */\nexport interface IDockDevtoolSync {\n side: TDockSide;\n size: number;\n open: boolean;\n badge?: string;\n}\n\nexport interface IDockDevtoolInput extends IDockDevtoolSync {\n id: string;\n label: string;\n icon: string;\n onOpen: () => void;\n}\n\nexport interface IDockView {\n /** Offset (px) from the docked edge — stacks open panels on the same side. */\n dockOffset: number;\n /**\n * True when this panel shares its dock side with another open panel (stacked\n * either nearer or further from the edge). Stacked panels square off all their\n * corners so they sit flush as one continuous block — only a panel alone on\n * its side keeps its rounded, page-facing corners.\n */\n stacked: boolean;\n /** Is any devtool on the page currently open? */\n anyOpen: boolean;\n /** First-registered devtool — the one that renders the combined launcher. */\n isPrimary: boolean;\n /** Every registered devtool, for the combined launcher. */\n devtools: IDockDevtoolRef[];\n /** Closed devtools other than this one, for an open panel's header. */\n otherClosed: IDockDevtoolRef[];\n}\n\nexport interface IDevtoolsDockCoordinator {\n version: number;\n register(panel: IDockDevtoolInput): () => void;\n update(id: string, next: IDockDevtoolSync): void;\n getView(id: string): IDockView;\n subscribe(listener: () => void): () => void;\n}\n\nconst GLOBAL_KEY = \"__NICE_DEVTOOLS_DOCK__\";\nconst VERSION = 4;\n\nfunction createCoordinator(): IDevtoolsDockCoordinator {\n // Insertion order is preserved by Map, giving panels a stable stacking order\n // and a deterministic \"primary\" (the first registered).\n const panels = new Map<string, IDockDevtoolInput>();\n const listeners = new Set<() => void>();\n\n function toRef(panel: IDockDevtoolInput): IDockDevtoolRef {\n return {\n id: panel.id,\n label: panel.label,\n icon: panel.icon,\n badge: panel.badge,\n onOpen: panel.onOpen,\n };\n }\n\n function applyBodyMargins(): void {\n if (typeof document === \"undefined\") return;\n const margins: Record<TDockSide, number> = { top: 0, bottom: 0, left: 0, right: 0 };\n for (const panel of panels.values()) {\n if (panel.open) margins[panel.side] += panel.size;\n }\n const sides: TDockSide[] = [\"top\", \"bottom\", \"left\", \"right\"];\n for (const side of sides) {\n if (margins[side] > 0) {\n document.body.style.setProperty(`margin-${side}`, `${margins[side]}px`);\n } else {\n document.body.style.removeProperty(`margin-${side}`);\n }\n }\n }\n\n function notify(): void {\n applyBodyMargins();\n for (const listener of listeners) listener();\n }\n\n return {\n version: VERSION,\n register(panel) {\n panels.set(panel.id, { ...panel });\n notify();\n return () => {\n panels.delete(panel.id);\n notify();\n };\n },\n update(id, next) {\n const existing = panels.get(id);\n if (existing == null) return;\n if (\n existing.side === next.side &&\n existing.size === next.size &&\n existing.open === next.open &&\n existing.badge === next.badge\n ) {\n return;\n }\n panels.set(id, { ...existing, ...next });\n notify();\n },\n getView(id) {\n const list = [...panels.values()];\n const anyOpen = list.some((p) => p.open);\n const firstId = list.length > 0 ? list[0].id : null;\n\n let dockOffset = 0;\n let stacked = false;\n const self = panels.get(id);\n if (self != null && self.open) {\n let seenSelf = false;\n for (const panel of list) {\n if (panel.id === id) {\n seenSelf = true;\n continue;\n }\n if (panel.open && panel.side === self.side) {\n // Any open neighbour on the same side means we're stacked. Panels\n // earlier in the list stack closer to the dock edge (and add to our\n // offset); later ones stack beyond us, away from the edge.\n stacked = true;\n if (!seenSelf) dockOffset += panel.size;\n }\n }\n }\n\n return {\n dockOffset,\n stacked,\n anyOpen,\n isPrimary: id === firstId,\n devtools: list.map(toRef),\n otherClosed: list.filter((p) => !p.open && p.id !== id).map(toRef),\n };\n },\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n };\n}\n\n/**\n * Returns the page-wide dock coordinator, installing it on `window` the first\n * time it is requested. On the server (no `window`) a throwaway instance is\n * returned so callers can use it unconditionally.\n */\nexport function getDevtoolsDockCoordinator(): IDevtoolsDockCoordinator {\n if (typeof window === \"undefined\") return createCoordinator();\n\n const host = window as unknown as Record<string, IDevtoolsDockCoordinator | undefined>;\n const existing = host[GLOBAL_KEY];\n if (existing != null && existing.version === VERSION) return existing;\n\n const created = createCoordinator();\n host[GLOBAL_KEY] = created;\n return created;\n}\n","import type { Virtualizer } from \"@tanstack/react-virtual\";\nimport { type RefObject, useCallback, useLayoutEffect, useRef } from \"react\";\n\n/**\n * Pin a virtualized list's viewport to a stable anchor row across list\n * mutations. Both devtools timelines are newest-first, so new entries (and\n * merges) prepend at the top; without this they shove whatever the user is\n * looking at downward. The anchor is the selected row when one is visible,\n * otherwise the first visible row, so \"the thing I selected / am reading\" stays\n * put at the same screen position. Returns an `onScroll` handler that must be\n * wired to the scroll container.\n *\n * `hoveringRef` is optional. When provided, the hook keeps the viewport still\n * even across selection changes while the cursor is over the list — the caller\n * is expected to suppress its own scroll-into-view in that case and let this\n * hold the view rock-still (nice-action's pause-on-hover behaviour). When\n * omitted, a selection change yields to the caller's scroll-into-view effect.\n */\nexport function useListScrollAnchor({\n containerRef,\n virtualizer,\n itemKeys,\n selectedKey,\n hoveringRef,\n}: {\n containerRef: RefObject<HTMLDivElement | null>;\n virtualizer: Virtualizer<HTMLDivElement, Element>;\n itemKeys: string[];\n selectedKey: string | null;\n hoveringRef?: RefObject<boolean>;\n}): () => void {\n const anchorRef = useRef<{ key: string; delta: number } | null>(null);\n const selectedKeyRef = useRef(selectedKey);\n selectedKeyRef.current = selectedKey;\n\n // Record where the anchor row sits relative to the viewport top. Called on every scroll (incl.\n // programmatic ones), so it always reflects the last position the user actually saw.\n const captureAnchor = useCallback(() => {\n const el = containerRef.current;\n if (el == null) return;\n const items = virtualizer.getVirtualItems();\n if (items.length === 0) {\n anchorRef.current = null;\n return;\n }\n const scrollTop = el.scrollTop;\n const sel = selectedKeyRef.current;\n const chosen =\n (sel != null ? items.find((vi) => String(vi.key) === sel) : undefined) ??\n items.find((vi) => vi.end > scrollTop) ??\n items[0];\n anchorRef.current = { key: String(chosen.key), delta: chosen.start - scrollTop };\n }, [containerRef, virtualizer]);\n\n const prevSelectedRef = useRef(selectedKey);\n useLayoutEffect(() => {\n const selectionChanged = prevSelectedRef.current !== selectedKey;\n prevSelectedRef.current = selectedKey;\n // A selection change is normally handled by the caller's scroll-into-view effect — don't fight it.\n // We only re-pin when the list data shifted underneath a stable selection. The exception is while\n // hovering: the caller suppresses its scroll-into-view, so we own keeping the view still and must\n // re-pin through selection changes (e.g. \"stay on latest\" re-selecting each new entry) too.\n if (selectionChanged && !(hoveringRef?.current ?? false)) return;\n const anchor = anchorRef.current;\n if (anchor == null) return;\n const index = itemKeys.indexOf(anchor.key);\n if (index < 0) return;\n const offset = virtualizer.getOffsetForIndex(index, \"start\")?.[0];\n if (offset == null) return;\n const target = Math.max(0, offset - anchor.delta);\n const current = virtualizer.scrollOffset ?? 0;\n if (Math.abs(target - current) > 1) virtualizer.scrollToOffset(target);\n }, [itemKeys, selectedKey, virtualizer, hoveringRef]);\n\n return captureAnchor;\n}\n","import { DEVTOOL_COLOR_SEMANTIC_SYSTEM } from \"../colors\";\n\n/** Small uppercase heading used above a detail/section block. */\nexport function SectionLabel({\n label,\n color = DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n}: {\n label: string;\n color?: string;\n}) {\n return (\n <div\n style={{\n color,\n fontSize: \"0.85em\",\n marginBottom: \"3px\",\n textTransform: \"uppercase\",\n letterSpacing: \"0.05em\",\n fontWeight: 500,\n textAlign: \"left\",\n }}\n >\n {label}\n </div>\n );\n}\n","/**\n * @license React\n * react-dom.production.js\n *\n * Copyright (c) Meta Platforms, Inc. and affiliates.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n\"use strict\";\nvar React = require(\"react\");\nfunction formatProdErrorMessage(code) {\n var url = \"https://react.dev/errors/\" + code;\n if (1 < arguments.length) {\n url += \"?args[]=\" + encodeURIComponent(arguments[1]);\n for (var i = 2; i < arguments.length; i++)\n url += \"&args[]=\" + encodeURIComponent(arguments[i]);\n }\n return (\n \"Minified React error #\" +\n code +\n \"; visit \" +\n url +\n \" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.\"\n );\n}\nfunction noop() {}\nvar Internals = {\n d: {\n f: noop,\n r: function () {\n throw Error(formatProdErrorMessage(522));\n },\n D: noop,\n C: noop,\n L: noop,\n m: noop,\n X: noop,\n S: noop,\n M: noop\n },\n p: 0,\n findDOMNode: null\n },\n REACT_PORTAL_TYPE = Symbol.for(\"react.portal\");\nfunction createPortal$1(children, containerInfo, implementation) {\n var key =\n 3 < arguments.length && void 0 !== arguments[3] ? arguments[3] : null;\n return {\n $$typeof: REACT_PORTAL_TYPE,\n key: null == key ? null : \"\" + key,\n children: children,\n containerInfo: containerInfo,\n implementation: implementation\n };\n}\nvar ReactSharedInternals =\n React.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE;\nfunction getCrossOriginStringAs(as, input) {\n if (\"font\" === as) return \"\";\n if (\"string\" === typeof input)\n return \"use-credentials\" === input ? input : \"\";\n}\nexports.__DOM_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE =\n Internals;\nexports.createPortal = function (children, container) {\n var key =\n 2 < arguments.length && void 0 !== arguments[2] ? arguments[2] : null;\n if (\n !container ||\n (1 !== container.nodeType &&\n 9 !== container.nodeType &&\n 11 !== container.nodeType)\n )\n throw Error(formatProdErrorMessage(299));\n return createPortal$1(children, container, null, key);\n};\nexports.flushSync = function (fn) {\n var previousTransition = ReactSharedInternals.T,\n previousUpdatePriority = Internals.p;\n try {\n if (((ReactSharedInternals.T = null), (Internals.p = 2), fn)) return fn();\n } finally {\n (ReactSharedInternals.T = previousTransition),\n (Internals.p = previousUpdatePriority),\n Internals.d.f();\n }\n};\nexports.preconnect = function (href, options) {\n \"string\" === typeof href &&\n (options\n ? ((options = options.crossOrigin),\n (options =\n \"string\" === typeof options\n ? \"use-credentials\" === options\n ? options\n : \"\"\n : void 0))\n : (options = null),\n Internals.d.C(href, options));\n};\nexports.prefetchDNS = function (href) {\n \"string\" === typeof href && Internals.d.D(href);\n};\nexports.preinit = function (href, options) {\n if (\"string\" === typeof href && options && \"string\" === typeof options.as) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin),\n integrity =\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n fetchPriority =\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0;\n \"style\" === as\n ? Internals.d.S(\n href,\n \"string\" === typeof options.precedence ? options.precedence : void 0,\n {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority\n }\n )\n : \"script\" === as &&\n Internals.d.X(href, {\n crossOrigin: crossOrigin,\n integrity: integrity,\n fetchPriority: fetchPriority,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n};\nexports.preinitModule = function (href, options) {\n if (\"string\" === typeof href)\n if (\"object\" === typeof options && null !== options) {\n if (null == options.as || \"script\" === options.as) {\n var crossOrigin = getCrossOriginStringAs(\n options.as,\n options.crossOrigin\n );\n Internals.d.M(href, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0\n });\n }\n } else null == options && Internals.d.M(href);\n};\nexports.preload = function (href, options) {\n if (\n \"string\" === typeof href &&\n \"object\" === typeof options &&\n null !== options &&\n \"string\" === typeof options.as\n ) {\n var as = options.as,\n crossOrigin = getCrossOriginStringAs(as, options.crossOrigin);\n Internals.d.L(href, as, {\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0,\n nonce: \"string\" === typeof options.nonce ? options.nonce : void 0,\n type: \"string\" === typeof options.type ? options.type : void 0,\n fetchPriority:\n \"string\" === typeof options.fetchPriority\n ? options.fetchPriority\n : void 0,\n referrerPolicy:\n \"string\" === typeof options.referrerPolicy\n ? options.referrerPolicy\n : void 0,\n imageSrcSet:\n \"string\" === typeof options.imageSrcSet ? options.imageSrcSet : void 0,\n imageSizes:\n \"string\" === typeof options.imageSizes ? options.imageSizes : void 0,\n media: \"string\" === typeof options.media ? options.media : void 0\n });\n }\n};\nexports.preloadModule = function (href, options) {\n if (\"string\" === typeof href)\n if (options) {\n var crossOrigin = getCrossOriginStringAs(options.as, options.crossOrigin);\n Internals.d.m(href, {\n as:\n \"string\" === typeof options.as && \"script\" !== options.as\n ? options.as\n : void 0,\n crossOrigin: crossOrigin,\n integrity:\n \"string\" === typeof options.integrity ? options.integrity : void 0\n });\n } else Internals.d.m(href);\n};\nexports.requestFormReset = function (form) {\n Internals.d.r(form);\n};\nexports.unstable_batchedUpdates = function (fn, a) {\n return fn(a);\n};\nexports.useFormState = function (action, initialState, permalink) {\n return ReactSharedInternals.H.useFormState(action, initialState, permalink);\n};\nexports.useFormStatus = function () {\n return ReactSharedInternals.H.useHostTransitionStatus();\n};\nexports.version = \"19.2.7\";\n","'use strict';\n\nfunction checkDCE() {\n /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */\n if (\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined' ||\n typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE !== 'function'\n ) {\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n // This branch is unreachable because this function is only called\n // in production, but the condition is true only in development.\n // Therefore if the branch is still here, dead code elimination wasn't\n // properly applied.\n // Don't change the message. React DevTools relies on it. Also make sure\n // this message doesn't occur elsewhere in this function, or it will cause\n // a false positive.\n throw new Error('^_^');\n }\n try {\n // Verify that the code above has been dead code eliminated (DCE'd).\n __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(checkDCE);\n } catch (err) {\n // DevTools shouldn't crash React, no matter what.\n // We should still report in case we break this code.\n console.error(err);\n }\n}\n\nif (process.env.NODE_ENV === 'production') {\n // DCE check should happen before ReactDOM bundle executes so that\n // DevTools can report bad minification during injection.\n checkDCE();\n module.exports = require('./cjs/react-dom.production.js');\n} else {\n module.exports = require('./cjs/react-dom.development.js');\n}\n","import { type CSSProperties, type ReactNode, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport {\n DEVTOOL_COLOR_TEXT_SECONDARY,\n DEVTOOL_TOOLTIP_BACKGROUND,\n DEVTOOL_TOOLTIP_BORDER,\n DEVTOOL_TOOLTIP_TITLE_BACKGROUND,\n DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER,\n} from \"../colors\";\n\nexport interface ITooltipConfig {\n content: ReactNode;\n title?: ReactNode;\n /** \"center\" centers the tooltip above/below the anchor (default).\n * \"edge\" aligns the nearer horizontal edge with the anchor edge. */\n align?: \"center\" | \"edge\";\n maxWidth?: number;\n}\n\nexport function Tooltip({\n anchor,\n config,\n children,\n}: {\n anchor: DOMRect;\n config: ITooltipConfig;\n children?: ReactNode;\n}) {\n const resolvedTitle = config?.title;\n const resolvedAlign = config?.align;\n const resolvedMaxWidth = config?.maxWidth ?? 400;\n const resolvedContent = config != null ? config.content : children;\n\n const showAbove = anchor.top >= window.innerHeight - anchor.bottom;\n const gap = 6;\n const screenMargin = 16;\n const top = showAbove ? Math.round(anchor.top - gap) : Math.round(anchor.bottom + gap);\n const maxHeight = showAbove\n ? Math.round(anchor.top - gap - screenMargin)\n : Math.round(window.innerHeight - anchor.bottom - gap - screenMargin);\n\n let left: number | undefined;\n let right: number | undefined;\n let transform: string | undefined;\n\n if (resolvedAlign === \"center\") {\n const halfMax = resolvedMaxWidth != null ? resolvedMaxWidth / 2 : 120;\n const center = Math.round(anchor.left + anchor.width / 2);\n left = Math.max(\n halfMax + screenMargin,\n Math.min(center, window.innerWidth - halfMax - screenMargin),\n );\n transform = showAbove ? \"translateX(-50%) translateY(-100%)\" : \"translateX(-50%)\";\n } else {\n const anchorMidX = anchor.left + anchor.width / 2;\n if (anchorMidX <= window.innerWidth / 2) {\n left = Math.max(screenMargin, anchor.left);\n } else {\n right = Math.max(screenMargin, window.innerWidth - anchor.right);\n }\n if (showAbove) transform = \"translateY(-100%)\";\n }\n\n // Render into a portal at the document root. The tooltip is positioned in viewport coordinates\n // (position: fixed), but list rows are virtualized inside a `transform: translateY()` container —\n // a transformed ancestor becomes the containing block for fixed descendants and (with its\n // `overflow: hidden`) clips them, mispositioning and hiding the tooltip. Portaling out of that\n // subtree restores true viewport-fixed behaviour everywhere.\n return createPortal(\n <div\n style={{\n position: \"fixed\",\n left,\n right,\n top,\n transform,\n zIndex: 2147483647,\n background: DEVTOOL_TOOLTIP_BACKGROUND,\n border: `1px solid ${DEVTOOL_TOOLTIP_BORDER}`,\n borderRadius: \"5px\",\n boxShadow: \"0 4px 20px rgba(0,0,0,0.6)\",\n pointerEvents: \"none\",\n maxWidth: resolvedMaxWidth != null ? `${resolvedMaxWidth}px` : undefined,\n maxHeight: `${maxHeight}px`,\n overflowY: \"auto\",\n overflowX: \"hidden\",\n // Reset inherited white-space: tooltips are DOM descendants of anchors\n // (e.g. Chip sets `nowrap`), which would otherwise stop content wrapping.\n whiteSpace: \"normal\",\n wordBreak: \"break-word\",\n overflowWrap: \"anywhere\",\n }}\n >\n {resolvedTitle != null && (\n <div\n style={{\n background: DEVTOOL_TOOLTIP_TITLE_BACKGROUND,\n padding: \"6px 8px\",\n alignSelf: \"start\",\n textAlign: \"left\",\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\n fontSize: \"0.75rem\",\n fontWeight: 600,\n paddingBottom: \"4px\",\n marginBottom: \"4px\",\n borderBottom: `1px solid ${DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER}`,\n }}\n >\n {resolvedTitle}\n </div>\n )}\n <div\n style={{\n padding: \"6px 8px\",\n }}\n >\n {resolvedContent}\n </div>\n </div>,\n document.body,\n );\n}\n\n/**\n * Wraps inline content so it shows `config` as a hover tooltip. When `config` is null the children\n * render untouched (no hover handlers, no tooltip). Useful for non-Chip text labels that still need\n * the same tooltip treatment as Chips.\n */\nexport function HoverTooltip({\n config,\n children,\n style,\n}: {\n config?: ITooltipConfig;\n children: ReactNode;\n style?: CSSProperties;\n}) {\n const [anchor, setAnchor] = useState<DOMRect | null>(null);\n const enabled = config != null;\n\n return (\n <>\n <span\n onMouseEnter={\n enabled ? (e) => setAnchor(e.currentTarget.getBoundingClientRect()) : undefined\n }\n onMouseLeave={enabled ? () => setAnchor(null) : undefined}\n style={{ ...style, cursor: enabled ? \"default\" : style?.cursor }}\n >\n {children}\n </span>\n {enabled && anchor != null && config != null && <Tooltip anchor={anchor} config={config} />}\n </>\n );\n}\n","import {\n type CSSProperties,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n useState,\n} from \"react\";\nimport {\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n DEVTOOL_COLOR_TEXT_FAINT,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_COLOR_TEXT_SECONDARY,\n DEVTOOL_LIST_BASE_BACKGROUND,\n DEVTOOL_SECTION_BACKGROUND,\n MONO_FONT,\n SANS_FONT,\n} from \"../colors\";\nimport type { TDockSide } from \"../dock\";\n\n/** Where a devtools panel is docked. */\nexport type TDevtoolsPosition = \"dock-bottom\" | \"dock-top\" | \"dock-left\" | \"dock-right\";\n\nexport interface IDevtoolsLauncherItem {\n id: string;\n label: string;\n icon: string;\n badge?: string;\n onOpen: () => void;\n}\n\nconst DOCKED_SIZE_MIN = 140;\n\n// 3×3 picker grid. Each slot has a stable key so the empty corners don't collide\n// (a single shared key for all of them triggers React's duplicate-key warning).\nconst POSITION_GRID: { key: string; pos: TDevtoolsPosition | null }[] = [\n { key: \"tl\", pos: null },\n { key: \"tc\", pos: \"dock-top\" },\n { key: \"tr\", pos: null },\n { key: \"ml\", pos: \"dock-left\" },\n { key: \"mc\", pos: null },\n { key: \"mr\", pos: \"dock-right\" },\n { key: \"bl\", pos: null },\n { key: \"bc\", pos: \"dock-bottom\" },\n { key: \"br\", pos: null },\n];\n\nexport function getDockSide(pos: TDevtoolsPosition): TDockSide {\n switch (pos) {\n case \"dock-top\":\n return \"top\";\n case \"dock-left\":\n return \"left\";\n case \"dock-right\":\n return \"right\";\n default:\n return \"bottom\";\n }\n}\n\nfunction chromeButtonStyle(color: string): CSSProperties {\n return {\n background: \"none\",\n border: \"none\",\n color,\n cursor: \"pointer\",\n fontSize: \"11px\",\n padding: 0,\n fontFamily: SANS_FONT,\n whiteSpace: \"nowrap\",\n };\n}\n\n/**\n * The panel's top chrome: a brand/title on the left (plus pills to open any other\n * closed devtools), and the panel controls on the right. The controls column\n * holds any caller-provided `children` (e.g. a mode switch) above a row of the\n * pause/clear actions, then the dock-position picker and the close button.\n *\n * `onTogglePause` is optional — when omitted no pause control is shown (the\n * nice-action timeline has nothing to pause), keeping a single header component\n * consistent across both devtools suites.\n */\nexport function PanelHeader({\n title,\n position,\n onPositionChange,\n onClose,\n onClear,\n paused,\n onTogglePause,\n openOthers,\n children,\n}: {\n title: string;\n position: TDevtoolsPosition;\n onPositionChange: (p: TDevtoolsPosition) => void;\n onClose: () => void;\n onClear?: () => void;\n paused?: boolean;\n onTogglePause?: () => void;\n openOthers?: IDevtoolsLauncherItem[];\n children?: ReactNode;\n}) {\n const hasActionsRow = onTogglePause != null || onClear != null;\n return (\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"6px 11px\",\n gap: \"10px\",\n background: DEVTOOL_SECTION_BACKGROUND,\n borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,\n flexShrink: 0,\n }}\n >\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\", minWidth: 0 }}>\n <span\n style={{\n color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n fontWeight: \"bold\",\n fontSize: \"11px\",\n whiteSpace: \"nowrap\",\n }}\n >\n {title}\n </span>\n {openOthers?.map((item) => (\n <button\n key={item.id}\n onClick={item.onOpen}\n title={`Open ${item.label} devtools`}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"4px\",\n background: DEVTOOL_LIST_BASE_BACKGROUND,\n border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,\n borderRadius: \"999px\",\n color: DEVTOOL_COLOR_TEXT_MUTED,\n cursor: \"pointer\",\n fontSize: \"10px\",\n padding: \"1px 7px 1px 6px\",\n fontFamily: SANS_FONT,\n whiteSpace: \"nowrap\",\n }}\n >\n <span>{item.icon}</span>\n <span>{item.label}</span>\n {item.badge != null && (\n <span style={{ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM }}>{item.badge}</span>\n )}\n </button>\n ))}\n </div>\n <div style={{ display: \"flex\", gap: \"10px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", flexDirection: \"column\", alignItems: \"stretch\" }}>\n {children}\n {hasActionsRow && (\n <div\n style={{\n display: \"flex\",\n gap: \"10px\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n padding: \"3px\",\n }}\n >\n {onTogglePause != null && (\n <button\n onClick={onTogglePause}\n title={paused ? \"Resume recording\" : \"Pause recording\"}\n style={chromeButtonStyle(\n paused ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_MUTED,\n )}\n >\n {paused ? \"▶ resume\" : \"⏸ pause\"}\n </button>\n )}\n {onClear != null && (\n <button onClick={onClear} style={chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED)}>\n clear\n </button>\n )}\n </div>\n )}\n </div>\n <PositionPicker position={position} onChange={onPositionChange} />\n <button\n onClick={onClose}\n style={{ ...chromeButtonStyle(DEVTOOL_COLOR_TEXT_MUTED), fontSize: \"16px\", lineHeight: \"1\" }}\n >\n ×\n </button>\n </div>\n </div>\n );\n}\n\nfunction PositionPicker({\n position,\n onChange,\n}: {\n position: TDevtoolsPosition;\n onChange: (p: TDevtoolsPosition) => void;\n}) {\n return (\n <div\n title=\"Move / dock panel\"\n style={{ display: \"grid\", gridTemplateColumns: \"repeat(3, 9px)\", gap: \"2px\", padding: \"2px\" }}\n >\n {POSITION_GRID.map(({ key, pos }) => {\n if (pos == null) return <div key={key} style={{ width: \"9px\", height: \"9px\" }} />;\n const isTopBottom = pos === \"dock-top\" || pos === \"dock-bottom\";\n const isActive = pos === position;\n return (\n <div\n key={key}\n title={pos}\n onClick={() => onChange(pos)}\n style={{\n width: \"9px\",\n height: \"9px\",\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"center\",\n cursor: \"pointer\",\n }}\n >\n <div\n style={{\n width: isTopBottom ? \"9px\" : \"3px\",\n height: isTopBottom ? \"3px\" : \"9px\",\n borderRadius: \"1px\",\n background: isActive ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT,\n }}\n />\n </div>\n );\n })}\n </div>\n );\n}\n\nexport function ResizeHandle({\n dockSide,\n dockedSize,\n onChange,\n}: {\n dockSide: TDockSide;\n dockedSize: number;\n onChange: (size: number) => void;\n}) {\n const isHoriz = dockSide === \"left\" || dockSide === \"right\";\n\n const onMouseDown = (e: ReactMouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n const startCoord = isHoriz ? e.clientX : e.clientY;\n const startSize = dockedSize;\n const maxSize = isHoriz ? window.innerWidth * 0.85 : window.innerHeight * 0.85;\n const sign = dockSide === \"bottom\" || dockSide === \"right\" ? -1 : 1;\n\n const onMove = (me: MouseEvent) => {\n const delta = (isHoriz ? me.clientX : me.clientY) - startCoord;\n onChange(Math.max(DOCKED_SIZE_MIN, Math.min(maxSize, startSize + sign * delta)));\n };\n const onUp = () => {\n window.removeEventListener(\"mousemove\", onMove);\n window.removeEventListener(\"mouseup\", onUp);\n };\n window.addEventListener(\"mousemove\", onMove);\n window.addEventListener(\"mouseup\", onUp);\n };\n\n const edgeStyle: CSSProperties =\n dockSide === \"bottom\"\n ? { top: 0, left: 0, right: 0, height: \"5px\", cursor: \"ns-resize\" }\n : dockSide === \"top\"\n ? { bottom: 0, left: 0, right: 0, height: \"5px\", cursor: \"ns-resize\" }\n : dockSide === \"right\"\n ? { top: 0, bottom: 0, left: 0, width: \"5px\", cursor: \"ew-resize\" }\n : { top: 0, bottom: 0, right: 0, width: \"5px\", cursor: \"ew-resize\" };\n\n return (\n <div\n onMouseDown={onMouseDown}\n style={{ position: \"absolute\", zIndex: 10, background: \"transparent\", ...edgeStyle }}\n />\n );\n}\n\nconst SPLIT_RATIO_MIN = 0.15;\nconst SPLIT_RATIO_MAX = 0.85;\n\n/**\n * Draggable divider between the list and the detail pane. `horizontal` refers to\n * the split axis: a row layout (dock top/bottom) splits horizontally and drags\n * left/right; a column layout (dock left/right) splits vertically. The reported\n * ratio is the fraction of the container the *detail* pane should occupy.\n */\nexport function SplitHandle({\n horizontal,\n onRatioChange,\n}: {\n horizontal: boolean;\n onRatioChange: (ratio: number) => void;\n}) {\n const [hovered, setHovered] = useState(false);\n\n const onMouseDown = (e: ReactMouseEvent<HTMLDivElement>) => {\n e.preventDefault();\n const container = e.currentTarget.parentElement;\n if (container == null) return;\n\n const onMove = (me: MouseEvent) => {\n const rect = container.getBoundingClientRect();\n // Detail sits after the handle (right / bottom), so its size is measured\n // from the far edge back to the cursor.\n const ratio = horizontal\n ? (rect.right - me.clientX) / rect.width\n : (rect.bottom - me.clientY) / rect.height;\n onRatioChange(Math.max(SPLIT_RATIO_MIN, Math.min(SPLIT_RATIO_MAX, ratio)));\n };\n const onUp = () => {\n window.removeEventListener(\"mousemove\", onMove);\n window.removeEventListener(\"mouseup\", onUp);\n };\n window.addEventListener(\"mousemove\", onMove);\n window.addEventListener(\"mouseup\", onUp);\n };\n\n return (\n <div\n onMouseDown={onMouseDown}\n onMouseEnter={() => setHovered(true)}\n onMouseLeave={() => setHovered(false)}\n style={{\n flex: \"0 0 5px\",\n alignSelf: \"stretch\",\n cursor: horizontal ? \"ew-resize\" : \"ns-resize\",\n background: hovered ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : \"transparent\",\n opacity: hovered ? 0.6 : 1,\n zIndex: 5,\n }}\n />\n );\n}\n\n/** A compact segmented toggle (e.g. the nice-state Timeline / State switch). */\nexport function SegmentedControl<T extends string>({\n options,\n value,\n onChange,\n}: {\n options: { value: T; label: string }[];\n value: T;\n onChange: (value: T) => void;\n}) {\n return (\n <div\n style={{\n display: \"flex\",\n border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,\n borderRadius: \"5px\",\n overflow: \"hidden\",\n }}\n >\n {options.map((opt) => {\n const active = opt.value === value;\n return (\n <button\n key={opt.value}\n onClick={() => onChange(opt.value)}\n style={{\n background: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : \"transparent\",\n color: active ? \"#0f172a\" : DEVTOOL_COLOR_TEXT_MUTED,\n border: \"none\",\n cursor: \"pointer\",\n fontSize: \"10px\",\n fontWeight: active ? 700 : 500,\n padding: \"3px 9px\",\n fontFamily: SANS_FONT,\n }}\n >\n {opt.label}\n </button>\n );\n })}\n </div>\n );\n}\n\n/**\n * The combined, page-wide launcher shown while every devtool is collapsed — one\n * grouped pill with a segment per registered devtool, so the buttons never\n * overlap or hide behind each other. Rendered by the coordinator's \"primary\"\n * devtool only.\n */\nexport function DevtoolsLauncher({ items }: { items: IDevtoolsLauncherItem[] }) {\n return (\n <div\n style={{\n position: \"fixed\",\n bottom: \"16px\",\n right: \"16px\",\n zIndex: 2147483647,\n display: \"flex\",\n fontFamily: MONO_FONT,\n fontSize: \"12px\",\n }}\n >\n <div\n style={{\n display: \"flex\",\n background: DEVTOOL_SECTION_BACKGROUND,\n border: `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}`,\n borderRadius: \"6px\",\n overflow: \"hidden\",\n boxShadow: \"0 8px 24px rgba(0,0,0,0.35)\",\n }}\n >\n {items.map((item, i) => (\n <button\n key={item.id}\n onClick={item.onOpen}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n background: \"transparent\",\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\n border: \"none\",\n borderLeft: i > 0 ? `1px solid ${DEVTOOL_COLOR_TEXT_FAINT}` : \"none\",\n cursor: \"pointer\",\n padding: \"6px 11px\",\n fontFamily: MONO_FONT,\n fontSize: \"12px\",\n lineHeight: \"1.5\",\n }}\n >\n <span>{item.icon}</span>\n <span>{item.label}</span>\n {item.badge != null && (\n <span style={{ color: DEVTOOL_COLOR_SEMANTIC_SYSTEM }}>{item.badge}</span>\n )}\n </button>\n ))}\n </div>\n </div>\n );\n}\n","import type { ReactNode } from \"react\";\nimport {\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_COLOR_TEXT_SECONDARY,\n DEVTOOL_LIST_BASE_BACKGROUND,\n DEVTOOL_SECTION_BACKGROUND,\n SANS_FONT,\n} from \"../colors\";\n\n/**\n * The \"Follow latest\" toggle pair shown above a devtools timeline list, with its\n * indented \"clicking latest re-follows\" sub-option. `noun` is the thing the\n * timeline tracks (\"action\" in nice-action, \"change\" in nice-state) and is woven\n * into the explanatory tooltips so both suites read naturally from one component.\n */\nexport function FollowLatestToggles({\n noun,\n stayOnLatest,\n onStayOnLatestChange,\n followLatestOnSelect,\n onFollowLatestOnSelectChange,\n}: {\n noun: string;\n stayOnLatest: boolean;\n onStayOnLatestChange: (next: boolean) => void;\n followLatestOnSelect: boolean;\n onFollowLatestOnSelectChange: (next: boolean) => void;\n}) {\n return (\n <div\n style={{\n display: \"flex\",\n flexDirection: \"column\",\n flexShrink: 0,\n paddingBottom: \"3px\",\n background: DEVTOOL_SECTION_BACKGROUND,\n borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,\n }}\n >\n <ToggleLabel\n title={`Auto-select the most recent ${noun} so the detail pane keeps showing the latest as new ${noun}s land`}\n checked={stayOnLatest}\n onChange={onStayOnLatestChange}\n >\n Follow latest\n </ToggleLabel>\n {/* Sub-option of \"Follow latest\": indented under it because it only tunes\n how following resumes when the latest entry is clicked. */}\n <div style={{ display: \"flex\", alignItems: \"center\", paddingLeft: \"12px\", marginTop: \"-4px\" }}>\n <span\n aria-hidden\n style={{\n color: DEVTOOL_COLOR_TEXT_MUTED,\n fontFamily: SANS_FONT,\n fontSize: \"10px\",\n lineHeight: 1,\n }}\n >\n └\n </span>\n <ToggleLabel\n title={`When you click the latest ${noun}, turn 'Follow latest' back on so the view resumes tracking new ${noun}s. Turn this off to pin exactly to the ${noun} you click instead.`}\n checked={followLatestOnSelect}\n onChange={onFollowLatestOnSelectChange}\n >\n clicking latest re-follows\n </ToggleLabel>\n </div>\n </div>\n );\n}\n\nfunction ToggleLabel({\n checked,\n onChange,\n title,\n children,\n}: {\n checked: boolean;\n onChange: (next: boolean) => void;\n title: string;\n children: ReactNode;\n}) {\n return (\n <label\n title={title}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n padding: \"5px 10px\",\n cursor: \"pointer\",\n userSelect: \"none\",\n color: checked ? DEVTOOL_COLOR_TEXT_SECONDARY : DEVTOOL_COLOR_TEXT_MUTED,\n fontSize: \"10px\",\n fontFamily: SANS_FONT,\n }}\n >\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n style={{ accentColor: DEVTOOL_COLOR_SEMANTIC_SYSTEM, cursor: \"pointer\", margin: 0 }}\n />\n {children}\n </label>\n );\n}\n","import { useVirtualizer } from \"@tanstack/react-virtual\";\nimport { type CSSProperties, type ReactNode, useEffect, useMemo, useRef, useState } from \"react\";\nimport { DEVTOOL_COLOR_SEMANTIC_WARNING, DEVTOOL_TOOLTIP_BACKGROUND, SANS_FONT } from \"../colors\";\nimport { useListScrollAnchor } from \"../list\";\n\n/**\n * The shared, virtualized timeline list used by both the nice-action and\n * nice-state devtools. It owns everything about *how the list behaves* — windowed\n * rendering, viewport anchoring across prepends, scroll-the-selection-into-view,\n * and pause-on-hover with a \"N new\" catch-up hint — while each devtool supplies\n * its own `renderItem` for the row content (which stays unique per devtool).\n *\n * Behaviour notes:\n * • The list is assumed newest-first: new rows prepend at the top. While the\n * cursor is over the list the viewport is held perfectly still (so reading\n * isn't disrupted); fresh rows still render above and a sticky \"↑ N new\"\n * badge hints they're there. Move the cursor away and normal follow resumes.\n * • `selectedKey` is the stable item key of the selected row (NOT necessarily a\n * sub-selection inside it). When it changes the row is scrolled into view —\n * unless the cursor is hovering, in which case the view is left untouched.\n */\nexport function DevtoolsVirtualList<T>({\n items,\n getItemKey,\n renderItem,\n selectedKey,\n estimateSize,\n overscan = 8,\n rowStyle,\n empty,\n footer,\n style,\n}: {\n items: T[];\n /** Stable identity for a row — must not change as later items merge/prepend. */\n getItemKey: (item: T, index: number) => string;\n renderItem: (item: T, index: number) => ReactNode;\n /** Key of the currently-selected row, for anchoring + scroll-into-view. */\n selectedKey: string | null;\n /** Estimated row height (px) for the virtualizer. */\n estimateSize: number;\n overscan?: number;\n /** Extra style merged onto each absolutely-positioned row wrapper. */\n rowStyle?: CSSProperties;\n /** Rendered in place of the list when there are no items. */\n empty?: ReactNode;\n /** Rendered after the rows, inside the scroll container (e.g. a \"start of history\" cap). */\n footer?: ReactNode;\n style?: CSSProperties;\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n\n // Pause-on-hover (auto-scroll only): while the cursor is over the list, new entries keep arriving\n // and rendering — the user can still scroll up to reach them — but the viewport must not move on\n // its own. A ref mirrors the state so effects can read it without re-subscribing.\n const [isHovering, setIsHovering] = useState(false);\n const hoveringRef = useRef(false);\n hoveringRef.current = isHovering;\n\n // New activity that arrived while hovering — surfaced as a small \"N new\" indicator so the user knows\n // there are fresh items above (the list is newest-first) without the view jumping to reveal them.\n const hoverBaselineCountRef = useRef(0);\n const pendingCount = isHovering ? Math.max(0, items.length - hoverBaselineCountRef.current) : 0;\n const hasPendingActivity = isHovering && pendingCount > 0;\n\n // Stable getItemKey across renders so the keys memo only recomputes when items change.\n const getItemKeyRef = useRef(getItemKey);\n getItemKeyRef.current = getItemKey;\n const itemKeys = useMemo(() => items.map((item, i) => getItemKeyRef.current(item, i)), [items]);\n\n const virtualizer = useVirtualizer({\n count: items.length,\n getScrollElement: () => containerRef.current,\n estimateSize: () => estimateSize,\n overscan,\n getItemKey: (index) => itemKeys[index],\n });\n\n const onScroll = useListScrollAnchor({\n containerRef,\n virtualizer,\n itemKeys,\n selectedKey,\n hoveringRef,\n });\n\n // Scroll the selected row into view when the selection changes. With \"follow latest\" this is also\n // what keeps the viewport pinned to the top: each new entry reselects the new latest (index 0), so\n // we scroll back up to it. The anchor hook above deliberately yields on selection changes.\n const prevSelectedRef = useRef(selectedKey);\n useEffect(() => {\n if (selectedKey === prevSelectedRef.current) return;\n prevSelectedRef.current = selectedKey;\n if (selectedKey == null) return;\n // While hovering, hold the view still — don't yank it to the (possibly auto-re-selected) latest\n // row. The scroll-anchor keeps the current position pinned; new rows still render above.\n if (hoveringRef.current) return;\n const index = itemKeys.indexOf(selectedKey);\n if (index >= 0) virtualizer.scrollToIndex(index, { align: \"auto\" });\n }, [selectedKey, itemKeys, virtualizer]);\n\n if (items.length === 0) return <>{empty}</>;\n\n return (\n <div\n ref={containerRef}\n style={style}\n onScroll={onScroll}\n onMouseEnter={() => {\n hoverBaselineCountRef.current = items.length;\n setIsHovering(true);\n }}\n onMouseLeave={() => setIsHovering(false)}\n >\n {hasPendingActivity && <PendingIndicator count={pendingCount} />}\n <div style={{ position: \"relative\", width: \"100%\", height: virtualizer.getTotalSize() }}>\n {virtualizer.getVirtualItems().map((vItem) => (\n <div\n key={vItem.key}\n data-index={vItem.index}\n ref={virtualizer.measureElement}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n transform: `translateY(${vItem.start}px)`,\n ...rowStyle,\n }}\n >\n {renderItem(items[vItem.index], vItem.index)}\n </div>\n ))}\n </div>\n {footer}\n </div>\n );\n}\n\n/**\n * A sticky, zero-height overlay floating over the rows without taking layout space. Shown only once\n * new items have arrived while hovering, hinting they're above (newest-first) so the user can scroll\n * up without the view having jumped there.\n */\nfunction PendingIndicator({ count }: { count: number }) {\n return (\n <div style={{ position: \"sticky\", top: 0, height: 0, zIndex: 5, pointerEvents: \"none\" }}>\n <div\n style={{\n position: \"absolute\",\n top: \"6px\",\n right: \"10px\",\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n padding: \"2px 7px\",\n borderRadius: \"10px\",\n fontSize: \"10px\",\n fontFamily: SANS_FONT,\n color: DEVTOOL_COLOR_SEMANTIC_WARNING,\n background: DEVTOOL_TOOLTIP_BACKGROUND,\n border: `1px solid ${DEVTOOL_COLOR_SEMANTIC_WARNING}55`,\n boxShadow: \"0 2px 8px rgba(0,0,0,0.5)\",\n whiteSpace: \"nowrap\",\n }}\n >\n ↑ {count} new\n </div>\n </div>\n );\n}\n","// The shared palette (semantic tokens, text hierarchy, surfaces, tooltip + JSON\n// colours, fonts) is the single source of truth across the nice-* devtools, so\n// the state and action suites feel like siblings when used side by side.\n// Re-exported by name (not `export *`) so bundlers reliably link the external\n// package — a bare `export *` from a dependency tripped Bun's bundler.\nexport {\n DEVTOOL_COLOR_SEMANTIC_ERROR,\n DEVTOOL_COLOR_SEMANTIC_METADATA,\n DEVTOOL_COLOR_SEMANTIC_SUCCESS,\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n DEVTOOL_COLOR_SEMANTIC_WARNING,\n DEVTOOL_COLOR_TEXT_EMPHASIS,\n DEVTOOL_COLOR_TEXT_FAINT,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_COLOR_TEXT_SECONDARY,\n DEVTOOL_DETAIL_BASE_BACKGROUND,\n DEVTOOL_DETAIL_HEADER_BACKGROUND,\n DEVTOOL_ERROR_BACKGROUND,\n DEVTOOL_JSON_KEY,\n DEVTOOL_JSON_KEYWORD,\n DEVTOOL_JSON_NUMBER,\n DEVTOOL_JSON_PUNCTUATION,\n DEVTOOL_JSON_STRING,\n DEVTOOL_LIST_BASE_BACKGROUND,\n DEVTOOL_LIST_SELECTED_BACKGROUND,\n DEVTOOL_PANEL_BORDER,\n DEVTOOL_PANEL_DIVIDER_BORDER,\n DEVTOOL_SECTION_BACKGROUND,\n DEVTOOL_SECTION_STRING_BACKGROUND,\n DEVTOOL_TOOLTIP_BACKGROUND,\n DEVTOOL_TOOLTIP_BORDER,\n DEVTOOL_TOOLTIP_TITLE_BACKGROUND,\n DEVTOOL_TOOLTIP_TITLE_BOTTOM_BORDER,\n MONO_FONT,\n SANS_FONT,\n} from \"nice-devtools-shared\";\n\n// ─── nice-state-specific editor surface ───────────────────────────────────────\nexport const DEVTOOL_EDITOR_BACKGROUND = \"#08101f\";\n","import type { Patch } from \"immer\";\r\nimport { safeStringify } from \"nice-devtools-shared\";\r\nimport {\r\n DEVTOOL_COLOR_SEMANTIC_METADATA,\r\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\r\n DEVTOOL_COLOR_SEMANTIC_WARNING,\r\n} from \"../../core/devtools_colors\";\r\nimport type { IDevtoolsStateChange, TStateChangeSource } from \"../../core/StateDevtools.types\";\r\n\r\n// Re-exported from the shared devtools package so existing imports from this\r\n// module keep working.\r\nexport { formatRelativeAge, formatTimestamp, safeStringify } from \"nice-devtools-shared\";\r\n\r\nexport const SOURCE_LABEL: Record<TStateChangeSource, string> = {\r\n update: \"UPDATE\",\r\n replace: \"REPLACE\",\r\n \"devtools-edit\": \"EDIT\",\r\n \"devtools-revert\": \"REVERT\",\r\n};\r\n\r\nexport const SOURCE_COLOR: Record<TStateChangeSource, string> = {\r\n update: DEVTOOL_COLOR_SEMANTIC_SYSTEM,\r\n replace: DEVTOOL_COLOR_SEMANTIC_METADATA,\r\n \"devtools-edit\": DEVTOOL_COLOR_SEMANTIC_WARNING,\r\n \"devtools-revert\": DEVTOOL_COLOR_SEMANTIC_WARNING,\r\n};\r\n\r\n/** Render an Immer patch path (`[\"todos\", 0, \"done\"]`) as `todos.0.done`. */\r\nexport function patchPathToString(path: Patch[\"path\"]): string {\r\n if (path.length === 0) return \"(root)\";\r\n return path.map((seg) => String(seg)).join(\".\");\r\n}\r\n\r\n/**\r\n * A terse, single-line summary of what a change touched, for the timeline row.\r\n * Prefers a `path: prev → next` form for single scalar replaces, otherwise lists\r\n * the distinct top-level paths affected.\r\n */\r\nexport function summarizeChange(change: IDevtoolsStateChange): string {\r\n const { patches } = change;\r\n if (patches.length === 0) {\r\n return change.source === \"replace\" || change.source === \"devtools-edit\"\r\n ? \"whole state replaced\"\r\n : \"no patches\";\r\n }\r\n\r\n if (patches.length === 1) {\r\n const p = patches[0];\r\n const path = patchPathToString(p.path);\r\n if (p.op === \"replace\" && isScalar(p.value)) {\r\n return `${path} → ${formatScalar(p.value)}`;\r\n }\r\n if (p.op === \"add\") return `+ ${path}`;\r\n if (p.op === \"remove\") return `− ${path}`;\r\n return path;\r\n }\r\n\r\n const paths = patches.map((p) => topLevel(p.path)).filter((s) => s.length > 0);\r\n const unique = [...new Set(paths)];\r\n const shown = unique.slice(0, 3).join(\", \");\r\n return unique.length > 3 ? `${shown} +${unique.length - 3}` : shown;\r\n}\r\n\r\nfunction topLevel(path: Patch[\"path\"]): string {\r\n return path.length > 0 ? String(path[0]) : \"(root)\";\r\n}\r\n\r\n/** A run of consecutive, structurally-equal changes collapsed into one row. */\r\nexport interface IChangeGroup {\r\n /** Newest change in the run — the one the row renders and selects. */\r\n representative: IDevtoolsStateChange;\r\n /**\r\n * Oldest change in the run — the one that actually moved the state (every later\r\n * member re-applied the same mutation as a no-op). Its `prevSnapshot` is the\r\n * real \"before\" of the whole run, so the detail panel uses it to show what the\r\n * initial update changed instead of the representative's empty self-diff.\r\n */\r\n oldest: IDevtoolsStateChange;\r\n /** How many changes the run collapses (1 = ungrouped). */\r\n count: number;\r\n}\r\n\r\n/**\r\n * Structural identity of a change by its *resulting* state: same store, same\r\n * snapshot. The feature collapses updates that \"didn't change the state from the\r\n * previous update\", so we compare the committed state itself rather than the\r\n * mutation that produced it. Keying on patches would miss the no-op cases this is\r\n * meant to catch — a fresh object reference with identical content, or a\r\n * same-value write from a different source (e.g. a devtools edit followed by an\r\n * app update). Those carry patches yet leave the state untouched, so they belong\r\n * in the run that already reached this state regardless of source.\r\n */\r\nexport function changeGroupKey(change: IDevtoolsStateChange): string {\r\n return `${change.storeId}|${safeStringify(change.snapshot, 0)}`;\r\n}\r\n\r\n/** Collapse consecutive structurally-equal changes (list is newest-first). */\r\nexport function groupChanges(changes: IDevtoolsStateChange[]): IChangeGroup[] {\r\n const groups: IChangeGroup[] = [];\r\n let lastKey: string | null = null;\r\n for (const change of changes) {\r\n const key = changeGroupKey(change);\r\n const last = groups[groups.length - 1];\r\n if (last != null && key === lastKey) {\r\n last.count++;\r\n last.oldest = change;\r\n } else {\r\n groups.push({ representative: change, oldest: change, count: 1 });\r\n }\r\n lastKey = key;\r\n }\r\n return groups;\r\n}\r\n\r\nexport type TDiffKind = \"added\" | \"removed\" | \"changed\";\r\n\r\nexport interface IDiffEntry {\r\n path: string;\r\n segments: (string | number)[];\r\n kind: TDiffKind;\r\n before?: unknown;\r\n after?: unknown;\r\n}\r\n\r\n/**\r\n * Structural diff between two snapshots, flattened to the individual leaf/branch\r\n * paths that actually changed — the data behind the test-framework-style \"Diff\"\r\n * view. Unchanged branches are skipped entirely (Immer's structural sharing\r\n * means equal branches keep their reference, so this stays cheap).\r\n */\r\nexport function computeDiff(before: unknown, after: unknown): IDiffEntry[] {\r\n const out: IDiffEntry[] = [];\r\n walkDiff([], before, after, out);\r\n return out;\r\n}\r\n\r\nfunction isPlainObjectOrArray(value: unknown): value is Record<string, unknown> {\r\n return value != null && typeof value === \"object\";\r\n}\r\n\r\nfunction walkDiff(\r\n path: (string | number)[],\r\n before: unknown,\r\n after: unknown,\r\n out: IDiffEntry[],\r\n): void {\r\n // Reference-equal (or both NaN) → nothing changed anywhere below here.\r\n if (Object.is(before, after)) return;\r\n\r\n const bothContainers = isPlainObjectOrArray(before) && isPlainObjectOrArray(after);\r\n const sameShape = bothContainers && Array.isArray(before) === Array.isArray(after);\r\n\r\n if (sameShape) {\r\n const b = before as Record<string, unknown>;\r\n const a = after as Record<string, unknown>;\r\n const keys = new Set([...Object.keys(b), ...Object.keys(a)]);\r\n for (const key of keys) {\r\n const inB = key in b;\r\n const inA = key in a;\r\n const next = [...path, key];\r\n if (inB && !inA) {\r\n out.push({ path: formatDiffPath(next), segments: next, kind: \"removed\", before: b[key] });\r\n } else if (!inB && inA) {\r\n out.push({ path: formatDiffPath(next), segments: next, kind: \"added\", after: a[key] });\r\n } else {\r\n walkDiff(next, b[key], a[key], out);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n // Leaf, or a container ↔ primitive / array ↔ object type change.\r\n out.push({ path: formatDiffPath(path), segments: [...path], kind: \"changed\", before, after });\r\n}\r\n\r\nfunction formatDiffPath(path: (string | number)[]): string {\r\n return path.length === 0 ? \"(root)\" : path.map((seg) => String(seg)).join(\".\");\r\n}\r\n\r\nexport type TLineDiffKind = \"common\" | \"removed\" | \"added\";\r\n\r\nexport interface ILineDiffOp {\r\n kind: TLineDiffKind;\r\n text: string;\r\n}\r\n\r\n/**\r\n * Classic LCS line diff between two blocks of text — the data behind the unified\r\n * git-style \"Diff View\" and the per-line highlighting in the Before / After\r\n * panels. Snapshots rendered as pretty JSON stay small, so the O(n·m) table is\r\n * comfortably cheap.\r\n */\r\nexport function computeLineDiff(beforeText: string, afterText: string): ILineDiffOp[] {\r\n const a = beforeText.split(\"\\n\");\r\n const b = afterText.split(\"\\n\");\r\n const n = a.length;\r\n const m = b.length;\r\n\r\n // lcs[i][j] = length of the longest common subsequence of a[i:] and b[j:].\r\n const lcs: number[][] = Array.from({ length: n + 1 }, () => new Array<number>(m + 1).fill(0));\r\n for (let i = n - 1; i >= 0; i--) {\r\n for (let j = m - 1; j >= 0; j--) {\r\n lcs[i][j] = a[i] === b[j] ? lcs[i + 1][j + 1] + 1 : Math.max(lcs[i + 1][j], lcs[i][j + 1]);\r\n }\r\n }\r\n\r\n const ops: ILineDiffOp[] = [];\r\n let i = 0;\r\n let j = 0;\r\n while (i < n && j < m) {\r\n if (a[i] === b[j]) {\r\n ops.push({ kind: \"common\", text: a[i] });\r\n i++;\r\n j++;\r\n } else if (lcs[i + 1][j] >= lcs[i][j + 1]) {\r\n ops.push({ kind: \"removed\", text: a[i] });\r\n i++;\r\n } else {\r\n ops.push({ kind: \"added\", text: b[j] });\r\n j++;\r\n }\r\n }\r\n while (i < n) ops.push({ kind: \"removed\", text: a[i++] });\r\n while (j < m) ops.push({ kind: \"added\", text: b[j++] });\r\n return ops;\r\n}\r\n\r\n/**\r\n * Reorder each contiguous changed hunk so additions sit above removals when\r\n * `latestFirst` is set (the new state on top). Common lines anchor the hunks in\r\n * place; only the −/+ lines within a run are regrouped, so the surrounding\r\n * context never moves. With `latestFirst` off the ops are returned untouched.\r\n */\r\nexport function orderLineDiffOps(ops: ILineDiffOp[], latestFirst: boolean): ILineDiffOp[] {\r\n if (!latestFirst) return ops;\r\n const out: ILineDiffOp[] = [];\r\n let i = 0;\r\n while (i < ops.length) {\r\n if (ops[i].kind === \"common\") {\r\n out.push(ops[i]);\r\n i++;\r\n continue;\r\n }\r\n const added: ILineDiffOp[] = [];\r\n const removed: ILineDiffOp[] = [];\r\n while (i < ops.length && ops[i].kind !== \"common\") {\r\n (ops[i].kind === \"added\" ? added : removed).push(ops[i]);\r\n i++;\r\n }\r\n out.push(...added, ...removed);\r\n }\r\n return out;\r\n}\r\n\r\nexport type TCompressedTone = \"common\" | \"added\" | \"removed\" | \"placeholder\";\r\n\r\n/** Which document a compressed diff is being rendered for. */\r\nexport type TDiffSide = \"unified\" | \"before\" | \"after\";\r\n\r\nexport interface ICompressedLine {\r\n /** Nesting depth — the renderer turns this into leading indentation. */\r\n depth: number;\r\n /** Gutter glyph: `+` added, `−` removed, or a space for structure/placeholder. */\r\n sign: string;\r\n tone: TCompressedTone;\r\n /** The line's JSON (or placeholder) text, without indentation. */\r\n text: string;\r\n}\r\n\r\ninterface IChildEntry {\r\n /** Quoted object key, or `null` for an array element (no key shown). */\r\n keyLabel: string | null;\r\n kind: \"unchanged\" | \"changed\" | \"added\" | \"removed\";\r\n before: unknown;\r\n after: unknown;\r\n}\r\n\r\n/**\r\n * A structure-aware \"address\" diff: the JSON tree pruned down to just the\r\n * branches that actually changed. Parents of a change keep their brackets so the\r\n * path stays legible, and each run of untouched siblings collapses into a single\r\n * `… N unchanged …` placeholder (which, for arrays, naturally reports the counts\r\n * before and after a change). `side` picks which document we're rebuilding —\r\n * `\"unified\"` shows removed (−) and added (+) together, while `\"before\"` /\r\n * `\"after\"` show only the lines that belong to that one snapshot.\r\n */\r\nexport function computeCompressedDiff(\r\n before: unknown,\r\n after: unknown,\r\n side: TDiffSide,\r\n latestFirst = false,\r\n): ICompressedLine[] {\r\n const lines: ICompressedLine[] = [];\r\n emitChangedNode(lines, 0, null, before, after, side, latestFirst);\r\n return lines;\r\n}\r\n\r\nfunction keyPrefix(keyLabel: string | null): string {\r\n return keyLabel != null ? `${keyLabel}: ` : \"\";\r\n}\r\n\r\n/** Emit a node already known to differ between the two sides. */\r\nfunction emitChangedNode(\r\n lines: ICompressedLine[],\r\n depth: number,\r\n keyLabel: string | null,\r\n before: unknown,\r\n after: unknown,\r\n side: TDiffSide,\r\n latestFirst: boolean,\r\n): void {\r\n const bothContainers = isPlainObjectOrArray(before) && isPlainObjectOrArray(after);\r\n const sameShape = bothContainers && Array.isArray(before) === Array.isArray(after);\r\n\r\n if (sameShape) {\r\n emitContainer(lines, depth, keyLabel, before, after, side, latestFirst);\r\n return;\r\n }\r\n\r\n // Leaf or type change: show the value on whichever side(s) this view renders.\r\n // In the unified view `latestFirst` puts the new value (+) above the old (−).\r\n const removed = () => pushValueLines(lines, depth, keyLabel, before, \"−\", \"removed\");\r\n const added = () => pushValueLines(lines, depth, keyLabel, after, \"+\", \"added\");\r\n if (side === \"before\") {\r\n removed();\r\n } else if (side === \"after\") {\r\n added();\r\n } else if (latestFirst) {\r\n added();\r\n removed();\r\n } else {\r\n removed();\r\n added();\r\n }\r\n}\r\n\r\nfunction emitContainer(\r\n lines: ICompressedLine[],\r\n depth: number,\r\n keyLabel: string | null,\r\n before: unknown,\r\n after: unknown,\r\n side: TDiffSide,\r\n latestFirst: boolean,\r\n): void {\r\n const isArray = Array.isArray(before);\r\n lines.push({ depth, sign: \" \", tone: \"common\", text: `${keyPrefix(keyLabel)}${isArray ? \"[\" : \"{\"}` });\r\n\r\n let unchanged = 0;\r\n const flush = () => {\r\n if (unchanged > 0) {\r\n lines.push({\r\n depth: depth + 1,\r\n sign: \" \",\r\n tone: \"placeholder\",\r\n text: placeholderText(unchanged, isArray),\r\n });\r\n unchanged = 0;\r\n }\r\n };\r\n\r\n for (const child of childEntries(before, after, isArray)) {\r\n // A child missing from the side we're rendering simply isn't part of that\r\n // document — don't draw it and don't count it as unchanged.\r\n if (child.kind === \"added\" && side === \"before\") continue;\r\n if (child.kind === \"removed\" && side === \"after\") continue;\r\n\r\n if (child.kind === \"unchanged\") {\r\n unchanged++;\r\n continue;\r\n }\r\n\r\n flush();\r\n if (child.kind === \"changed\") {\r\n emitChangedNode(lines, depth + 1, child.keyLabel, child.before, child.after, side, latestFirst);\r\n } else if (child.kind === \"added\") {\r\n pushValueLines(lines, depth + 1, child.keyLabel, child.after, \"+\", \"added\");\r\n } else {\r\n pushValueLines(lines, depth + 1, child.keyLabel, child.before, \"−\", \"removed\");\r\n }\r\n }\r\n flush();\r\n\r\n lines.push({ depth, sign: \" \", tone: \"common\", text: isArray ? \"]\" : \"}\" });\r\n}\r\n\r\n/** Classify each direct child as unchanged / changed / added / removed. */\r\nfunction childEntries(before: unknown, after: unknown, isArray: boolean): IChildEntry[] {\r\n if (isArray) {\r\n const b = before as unknown[];\r\n const a = after as unknown[];\r\n const len = Math.max(b.length, a.length);\r\n const out: IChildEntry[] = [];\r\n for (let i = 0; i < len; i++) {\r\n const inB = i < b.length;\r\n const inA = i < a.length;\r\n if (inB && inA) {\r\n const kind = Object.is(b[i], a[i]) ? \"unchanged\" : \"changed\";\r\n out.push({ keyLabel: null, kind, before: b[i], after: a[i] });\r\n } else if (inB) {\r\n out.push({ keyLabel: null, kind: \"removed\", before: b[i], after: undefined });\r\n } else {\r\n out.push({ keyLabel: null, kind: \"added\", before: undefined, after: a[i] });\r\n }\r\n }\r\n return out;\r\n }\r\n\r\n const b = before as Record<string, unknown>;\r\n const a = after as Record<string, unknown>;\r\n const keys = [...new Set([...Object.keys(b), ...Object.keys(a)])];\r\n return keys.map((key) => {\r\n const keyLabel = JSON.stringify(key);\r\n const inB = key in b;\r\n const inA = key in a;\r\n if (inB && inA) {\r\n const kind = Object.is(b[key], a[key]) ? \"unchanged\" : \"changed\";\r\n return { keyLabel, kind, before: b[key], after: a[key] };\r\n }\r\n if (inB) return { keyLabel, kind: \"removed\", before: b[key], after: undefined };\r\n return { keyLabel, kind: \"added\", before: undefined, after: a[key] };\r\n });\r\n}\r\n\r\nfunction placeholderText(count: number, isArray: boolean): string {\r\n const noun = isArray\r\n ? count === 1\r\n ? \"item\"\r\n : \"items\"\r\n : count === 1\r\n ? \"property\"\r\n : \"properties\";\r\n return `… ${count} unchanged ${noun}`;\r\n}\r\n\r\n/**\r\n * Render a value as pretty JSON and append it as one tone'd block, re-basing the\r\n * stringifier's own 2-space indentation onto `baseDepth` and prefixing the key\r\n * (if any) onto the first line.\r\n */\r\nfunction pushValueLines(\r\n lines: ICompressedLine[],\r\n baseDepth: number,\r\n keyLabel: string | null,\r\n value: unknown,\r\n sign: string,\r\n tone: TCompressedTone,\r\n): void {\r\n const prefix = keyPrefix(keyLabel);\r\n const raw = safeStringify(value, 2).split(\"\\n\");\r\n raw.forEach((line, idx) => {\r\n const leading = (/^ */.exec(line) as RegExpExecArray)[0].length;\r\n const content = line.slice(leading);\r\n const text = idx === 0 ? `${prefix}${content}` : content;\r\n lines.push({ depth: baseDepth + leading / 2, sign, tone, text });\r\n });\r\n}\r\n\r\nfunction isScalar(value: unknown): boolean {\r\n return value == null || typeof value !== \"object\";\r\n}\r\n\r\nfunction formatScalar(value: unknown): string {\r\n if (typeof value === \"string\") return `\"${value.length > 24 ? `${value.slice(0, 24)}…` : value}\"`;\r\n return String(value);\r\n}\r\n","import {\n DEVTOOL_COLOR_SEMANTIC_ERROR,\n DEVTOOL_COLOR_SEMANTIC_SUCCESS,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_JSON_KEY,\n DEVTOOL_SECTION_STRING_BACKGROUND,\n MONO_FONT,\n} from \"../../core/devtools_colors\";\nimport { renderColoredJson } from \"./JsonView\";\nimport { computeDiff, type IDiffEntry, safeStringify } from \"./utils\";\n\nconst ADDED_BG = \"rgba(163, 230, 53, 0.08)\";\nconst REMOVED_BG = \"rgba(255, 92, 92, 0.08)\";\n// Changed values whose single-line form fits within this many chars render\n// inline next to their key; longer ones fall back to the stacked −/+ block.\nconst INLINE_MAX = 40;\n\n/**\n * Test-framework-style diff: only the paths that changed. Changed paths are\n * grouped into a hierarchy by their shared parents — `countHistory.0` and\n * `countHistory.1` nest under a single `countHistory` node, each shown by its\n * direct key only. Single-child chains collapse to a dotted path (`a.b.c`) so\n * lone deep changes stay on one line. Short values render inline with the key\n * (`count: 0 → 1`); long ones keep the removed/added line block.\n */\nexport function DiffView({\n before,\n after,\n latestFirst = false,\n}: {\n before: unknown;\n after: unknown;\n latestFirst?: boolean;\n}) {\n const entries = computeDiff(before, after);\n\n if (entries.length === 0) {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"4px\",\n background: DEVTOOL_SECTION_STRING_BACKGROUND,\n color: DEVTOOL_COLOR_TEXT_MUTED,\n fontSize: \"11px\",\n fontStyle: \"italic\",\n }}\n >\n No differences — before and after are structurally equal.\n </div>\n );\n }\n\n const roots = [...buildTree(entries).children.values()].map(collapseChains);\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"6px\" }}>\n {roots.map((node) => (\n <DiffNode key={node.key} node={node} latestFirst={latestFirst} />\n ))}\n </div>\n );\n}\n\ninterface IDiffNode {\n key: string;\n children: Map<string, IDiffNode>;\n entry?: IDiffEntry;\n}\n\n/** Group flat diff entries into a tree keyed by their path segments. */\nfunction buildTree(entries: IDiffEntry[]): IDiffNode {\n const root: IDiffNode = { key: \"\", children: new Map() };\n for (const entry of entries) {\n const segments = entry.segments.length > 0 ? entry.segments : [\"(root)\"];\n let node = root;\n for (const seg of segments) {\n const key = String(seg);\n let child = node.children.get(key);\n if (child == null) {\n child = { key, children: new Map() };\n node.children.set(key, child);\n }\n node = child;\n }\n node.entry = entry;\n }\n return root;\n}\n\n/**\n * Collapse single-child chains into one dotted key so a lone deep change reads\n * as `a.b.c` rather than three nested headers; branches with siblings keep their\n * hierarchy.\n */\nfunction collapseChains(node: IDiffNode): IDiffNode {\n const children = new Map<string, IDiffNode>();\n for (const child of node.children.values()) {\n const collapsed = collapseChains(child);\n children.set(collapsed.key, collapsed);\n }\n let current: IDiffNode = { key: node.key, children, entry: node.entry };\n while (current.entry == null && current.children.size === 1) {\n const only = [...current.children.values()][0];\n current = { key: `${current.key}.${only.key}`, children: only.children, entry: only.entry };\n }\n return current;\n}\n\nfunction DiffNode({ node, latestFirst }: { node: IDiffNode; latestFirst: boolean }) {\n if (node.entry != null && node.children.size === 0) {\n return <DiffLeaf label={node.key} entry={node.entry} latestFirst={latestFirst} />;\n }\n return (\n <div>\n <div style={{ color: DEVTOOL_JSON_KEY, fontFamily: MONO_FONT, fontSize: \"10px\", fontWeight: 600 }}>\n {node.key}\n </div>\n <div\n style={{\n marginTop: \"4px\",\n marginLeft: \"5px\",\n paddingLeft: \"8px\",\n borderLeft: `1px solid ${DEVTOOL_SECTION_STRING_BACKGROUND}`,\n display: \"flex\",\n flexDirection: \"column\",\n gap: \"5px\",\n }}\n >\n {[...node.children.values()].map((child) => (\n <DiffNode key={child.key} node={child} latestFirst={latestFirst} />\n ))}\n </div>\n </div>\n );\n}\n\nfunction DiffLeaf({\n label,\n entry,\n latestFirst,\n}: {\n label: string;\n entry: IDiffEntry;\n latestFirst: boolean;\n}) {\n const showRemoved = entry.kind === \"removed\" || entry.kind === \"changed\";\n const showAdded = entry.kind === \"added\" || entry.kind === \"changed\";\n\n const removed = showRemoved && (\n <InlineValue sign=\"−\" color={DEVTOOL_COLOR_SEMANTIC_ERROR} background={REMOVED_BG} value={entry.before} />\n );\n const added = showAdded && (\n <InlineValue sign=\"+\" color={DEVTOOL_COLOR_SEMANTIC_SUCCESS} background={ADDED_BG} value={entry.after} />\n );\n const removedLine = showRemoved && (\n <DiffLine sign=\"−\" color={DEVTOOL_COLOR_SEMANTIC_ERROR} background={REMOVED_BG} value={entry.before} />\n );\n const addedLine = showAdded && (\n <DiffLine sign=\"+\" color={DEVTOOL_COLOR_SEMANTIC_SUCCESS} background={ADDED_BG} value={entry.after} />\n );\n\n if (isInlineLeaf(entry)) {\n return (\n <div style={{ display: \"flex\", flexWrap: \"wrap\", alignItems: \"baseline\", gap: \"6px\" }}>\n <span style={{ color: DEVTOOL_JSON_KEY, fontFamily: MONO_FONT, fontSize: \"11px\" }}>\n {label}:\n </span>\n {latestFirst ? added : removed}\n {entry.kind === \"changed\" && (\n <span style={{ color: DEVTOOL_COLOR_TEXT_MUTED }}>{latestFirst ? \"←\" : \"→\"}</span>\n )}\n {latestFirst ? removed : added}\n </div>\n );\n }\n\n return (\n <div\n style={{\n borderRadius: \"4px\",\n overflow: \"hidden\",\n border: `1px solid ${DEVTOOL_SECTION_STRING_BACKGROUND}`,\n }}\n >\n <div\n style={{\n padding: \"3px 8px\",\n background: DEVTOOL_SECTION_STRING_BACKGROUND,\n color: DEVTOOL_JSON_KEY,\n fontFamily: MONO_FONT,\n fontSize: \"10px\",\n }}\n >\n {label}\n </div>\n {latestFirst ? addedLine : removedLine}\n {latestFirst ? removedLine : addedLine}\n </div>\n );\n}\n\nfunction InlineValue({\n sign,\n color,\n background,\n value,\n}: {\n sign: string;\n color: string;\n background: string;\n value: unknown;\n}) {\n return (\n <span\n style={{\n display: \"inline-flex\",\n alignItems: \"baseline\",\n gap: \"4px\",\n padding: \"1px 6px\",\n borderRadius: \"3px\",\n background,\n fontFamily: MONO_FONT,\n fontSize: \"11px\",\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n <span style={{ color, fontWeight: 700, userSelect: \"none\" }}>{sign}</span>\n <span>{renderColoredJson(compactStringify(value))}</span>\n </span>\n );\n}\n\nfunction DiffLine({\n sign,\n color,\n background,\n value,\n}: {\n sign: string;\n color: string;\n background: string;\n value: unknown;\n}) {\n return (\n <div style={{ display: \"flex\", gap: \"6px\", padding: \"3px 8px\", background }}>\n <span style={{ color, fontWeight: 700, flexShrink: 0, userSelect: \"none\" }}>{sign}</span>\n <span\n style={{\n flex: 1,\n minWidth: 0,\n fontFamily: MONO_FONT,\n fontSize: \"11px\",\n lineHeight: 1.5,\n whiteSpace: \"pre-wrap\",\n wordBreak: \"break-word\",\n }}\n >\n {renderColoredJson(safeStringify(value, 2))}\n </span>\n </div>\n );\n}\n\n/** A leaf renders inline when every side it shows is short and single-line. */\nfunction isInlineLeaf(entry: IDiffEntry): boolean {\n const sides: string[] = [];\n if (entry.kind !== \"added\") sides.push(compactStringify(entry.before));\n if (entry.kind !== \"removed\") sides.push(compactStringify(entry.after));\n return sides.every((s) => s.length <= INLINE_MAX && !s.includes(\"\\n\"));\n}\n\n/** Single-line JSON for inline rendering (`undefined` has no JSON form). */\nfunction compactStringify(value: unknown): string {\n if (value === undefined) return \"undefined\";\n try {\n return JSON.stringify(value) ?? \"undefined\";\n } catch {\n return String(value);\n }\n}\n","import {\n DEVTOOL_COLOR_SEMANTIC_ERROR,\n DEVTOOL_COLOR_SEMANTIC_SUCCESS,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_SECTION_STRING_BACKGROUND,\n MONO_FONT,\n} from \"../../core/devtools_colors\";\nimport { renderColoredJson } from \"./JsonView\";\nimport {\n computeCompressedDiff,\n computeLineDiff,\n type ICompressedLine,\n type ILineDiffOp,\n orderLineDiffOps,\n safeStringify,\n type TDiffSide,\n} from \"./utils\";\n\nconst ADDED_BG = \"rgba(163, 230, 53, 0.13)\";\nconst REMOVED_BG = \"rgba(255, 92, 92, 0.13)\";\n\nconst SURFACE_STYLE = {\n margin: 0,\n padding: \"8px 0\",\n borderRadius: \"4px\",\n fontSize: \"11px\",\n lineHeight: 1.5,\n fontFamily: MONO_FONT,\n background: DEVTOOL_SECTION_STRING_BACKGROUND,\n overflowX: \"auto\" as const,\n};\n\nfunction emptyNotice(text: string) {\n return (\n <div\n style={{\n padding: \"10px\",\n borderRadius: \"4px\",\n background: DEVTOOL_SECTION_STRING_BACKGROUND,\n color: DEVTOOL_COLOR_TEXT_MUTED,\n fontSize: \"11px\",\n fontStyle: \"italic\",\n }}\n >\n {text}\n </div>\n );\n}\n\n/**\n * A single rendered diff line: a fixed sign gutter (`+` / `−` / blank) followed\n * by the syntax-coloured JSON text, all on a highlighted background.\n */\nfunction Line({ sign, color, background, text }: {\n sign: string;\n color: string;\n background: string;\n text: string;\n}) {\n return (\n <div style={{ display: \"flex\", background, padding: \"0 10px\", whiteSpace: \"pre\" }}>\n <span style={{ width: \"12px\", flexShrink: 0, color, fontWeight: 700, userSelect: \"none\" }}>\n {sign}\n </span>\n <span style={{ flex: 1, minWidth: 0 }}>{renderColoredJson(text)}</span>\n </div>\n );\n}\n\n/**\n * Unified, git-style diff of the entire state snapshot. Both sides are rendered\n * as pretty JSON and line-diffed, so unchanged structure stays visible for\n * context while removed lines (red, `−`) and added lines (green, `+`) call out\n * exactly which sections of the whole state moved.\n */\nexport function JsonDiffView({\n before,\n after,\n compress = false,\n latestFirst = false,\n}: {\n before: unknown;\n after: unknown;\n compress?: boolean;\n latestFirst?: boolean;\n}) {\n if (compress) {\n return (\n <CompressedDiffView before={before} after={after} side=\"unified\" latestFirst={latestFirst} />\n );\n }\n\n const ops = orderLineDiffOps(\n computeLineDiff(safeStringify(before, 2), safeStringify(after, 2)),\n latestFirst,\n );\n\n if (!ops.some((op) => op.kind !== \"common\")) {\n return emptyNotice(\"No differences — before and after are structurally equal.\");\n }\n\n return (\n <pre style={SURFACE_STYLE}>\n {ops.map((op, i) => (\n <Line\n key={i}\n sign={op.kind === \"removed\" ? \"−\" : op.kind === \"added\" ? \"+\" : \" \"}\n color={op.kind === \"removed\" ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_COLOR_SEMANTIC_SUCCESS}\n background={op.kind === \"removed\" ? REMOVED_BG : op.kind === \"added\" ? ADDED_BG : \"transparent\"}\n text={op.text}\n />\n ))}\n </pre>\n );\n}\n\n/**\n * The structure-aware \"address\" view: the JSON tree pruned to just the changed\n * branches, with runs of untouched siblings collapsed into `… N unchanged …`\n * placeholders. Shared by all three diff tabs via `side`.\n */\nfunction CompressedDiffView({\n before,\n after,\n side,\n latestFirst = false,\n}: {\n before: unknown;\n after: unknown;\n side: TDiffSide;\n latestFirst?: boolean;\n}) {\n const lines = computeCompressedDiff(before, after, side, latestFirst);\n\n if (!lines.some((line) => line.tone === \"added\" || line.tone === \"removed\")) {\n return emptyNotice(\"No differences — before and after are structurally equal.\");\n }\n\n return (\n <pre style={SURFACE_STYLE}>\n {lines.map((line, i) => (\n <CompressedLine key={i} line={line} />\n ))}\n </pre>\n );\n}\n\nfunction CompressedLine({ line }: { line: ICompressedLine }) {\n const indent = \" \".repeat(line.depth);\n\n if (line.tone === \"placeholder\") {\n return (\n <div style={{ display: \"flex\", padding: \"0 10px\", whiteSpace: \"pre\" }}>\n <span style={{ width: \"12px\", flexShrink: 0 }} />\n <span style={{ flex: 1, minWidth: 0, color: DEVTOOL_COLOR_TEXT_MUTED, fontStyle: \"italic\" }}>\n {indent}\n {line.text}\n </span>\n </div>\n );\n }\n\n const background =\n line.tone === \"removed\" ? REMOVED_BG : line.tone === \"added\" ? ADDED_BG : \"transparent\";\n const color =\n line.tone === \"removed\" ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_COLOR_SEMANTIC_SUCCESS;\n\n return (\n <div style={{ display: \"flex\", background, padding: \"0 10px\", whiteSpace: \"pre\" }}>\n <span style={{ width: \"12px\", flexShrink: 0, color, fontWeight: 700, userSelect: \"none\" }}>\n {line.sign}\n </span>\n <span style={{ flex: 1, minWidth: 0 }}>{renderColoredJson(`${indent}${line.text}`)}</span>\n </div>\n );\n}\n\n/**\n * The full JSON of one snapshot with the lines that differ from the other side\n * highlighted in place — red behind removed lines on the \"before\" side, green\n * behind added lines on the \"after\" side. Lines common to both render plainly so\n * the highlight reads as \"here is what changed within the whole state\".\n */\nexport function HighlightedJsonView({\n before,\n after,\n side,\n compress = false,\n}: {\n before: unknown;\n after: unknown;\n side: \"before\" | \"after\";\n compress?: boolean;\n}) {\n if (compress) return <CompressedDiffView before={before} after={after} side={side} />;\n\n const ops = computeLineDiff(safeStringify(before, 2), safeStringify(after, 2));\n // The \"before\" side keeps common + removed lines; the \"after\" side keeps\n // common + added lines — together they reconstruct each original document.\n const dropKind: ILineDiffOp[\"kind\"] = side === \"before\" ? \"added\" : \"removed\";\n const highlightKind: ILineDiffOp[\"kind\"] = side === \"before\" ? \"removed\" : \"added\";\n const background = side === \"before\" ? REMOVED_BG : ADDED_BG;\n const color = side === \"before\" ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_COLOR_SEMANTIC_SUCCESS;\n\n const visible = ops.filter((op) => op.kind !== dropKind);\n\n return (\n <pre style={SURFACE_STYLE}>\n {visible.map((op, i) => {\n const changed = op.kind === highlightKind;\n return (\n <Line\n key={i}\n sign={changed ? (side === \"before\" ? \"−\" : \"+\") : \" \"}\n color={color}\n background={changed ? background : \"transparent\"}\n text={op.text}\n />\n );\n })}\n </pre>\n );\n}\n","import { SegmentedControl } from \"nice-devtools-shared\";\nimport {\n DEVTOOL_COLOR_SEMANTIC_WARNING,\n DEVTOOL_COLOR_TEXT_EMPHASIS,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_DETAIL_BASE_BACKGROUND,\n DEVTOOL_DETAIL_HEADER_BACKGROUND,\n DEVTOOL_LIST_BASE_BACKGROUND,\n DEVTOOL_SECTION_BACKGROUND,\n MONO_FONT,\n SANS_FONT,\n} from \"../../core/devtools_colors\";\nimport type { IDevtoolsStateChange } from \"../../core/StateDevtools.types\";\nimport { DiffView } from \"./DiffView\";\nimport { HighlightedJsonView, JsonDiffView } from \"./JsonDiffView\";\nimport { formatTimestamp, SOURCE_COLOR, SOURCE_LABEL } from \"./utils\";\n\nexport type TChangeView = \"props\" | \"diff\" | \"before\" | \"after\";\n\nexport function ChangeDetailPanel({\n change,\n onRevert,\n view,\n onViewChange,\n compress,\n onCompressChange,\n latestFirst,\n onLatestFirstChange,\n}: {\n change: IDevtoolsStateChange;\n onRevert: (change: IDevtoolsStateChange) => void;\n view: TChangeView;\n onViewChange: (view: TChangeView) => void;\n compress: boolean;\n onCompressChange: (compress: boolean) => void;\n latestFirst: boolean;\n onLatestFirstChange: (latestFirst: boolean) => void;\n}) {\n const canRevert = change.inversePatches.length > 0;\n // The compress toggle only applies to the JSON-tree views, not \"Diff Props\".\n const showCompressToggle = view !== \"props\";\n // Diff order only matters where both sides (− and +) are shown together.\n const showOrderToggle = view === \"props\" || view === \"diff\";\n\n return (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n minHeight: 0,\n background: DEVTOOL_DETAIL_BASE_BACKGROUND,\n }}\n >\n {/* Header */}\n <div\n style={{\n padding: \"8px 12px\",\n background: DEVTOOL_DETAIL_HEADER_BACKGROUND,\n borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,\n display: \"flex\",\n alignItems: \"center\",\n gap: \"8px\",\n flexShrink: 0,\n }}\n >\n <span\n style={{\n color: DEVTOOL_COLOR_TEXT_EMPHASIS,\n fontWeight: 600,\n fontFamily: MONO_FONT,\n fontSize: \"12px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"nowrap\",\n }}\n >\n {change.storeLabel}\n </span>\n <span\n style={{\n padding: \"1px 7px\",\n borderRadius: \"999px\",\n background: SOURCE_COLOR[change.source],\n color: \"#0f172a\",\n fontSize: \"8px\",\n fontWeight: 700,\n letterSpacing: \"0.08em\",\n fontFamily: SANS_FONT,\n }}\n >\n {SOURCE_LABEL[change.source]}\n </span>\n <span style={{ flex: 1 }} />\n <span style={{ color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: \"10px\", fontFamily: MONO_FONT }}>\n {formatTimestamp(change.timestamp)}\n </span>\n <button\n onClick={() => onRevert(change)}\n disabled={!canRevert}\n title={\n canRevert\n ? \"Apply this change's inverse patches to undo it\"\n : \"No inverse patches available to revert\"\n }\n style={{\n background: \"transparent\",\n border: `1px solid ${canRevert ? DEVTOOL_COLOR_SEMANTIC_WARNING : DEVTOOL_SECTION_BACKGROUND}`,\n color: canRevert ? DEVTOOL_COLOR_SEMANTIC_WARNING : DEVTOOL_COLOR_TEXT_MUTED,\n borderRadius: \"4px\",\n cursor: canRevert ? \"pointer\" : \"not-allowed\",\n fontSize: \"10px\",\n padding: \"2px 8px\",\n fontFamily: SANS_FONT,\n flexShrink: 0,\n }}\n >\n ⟲ revert\n </button>\n </div>\n\n {/* View switcher */}\n <div\n style={{\n padding: \"6px 12px\",\n borderBottom: `1px solid ${DEVTOOL_LIST_BASE_BACKGROUND}`,\n flexShrink: 0,\n }}\n >\n <SegmentedControl<TChangeView>\n options={[\n { value: \"props\", label: \"Diff Props\" },\n { value: \"diff\", label: \"Diff View\" },\n { value: \"before\", label: \"Before\" },\n { value: \"after\", label: \"After\" },\n ]}\n value={view}\n onChange={onViewChange}\n />\n </div>\n\n {/* View body — fills remaining space */}\n <div\n style={{\n flex: 1,\n overflowY: \"auto\",\n minHeight: 0,\n padding: \"10px 12px\",\n }}\n >\n {(showCompressToggle || showOrderToggle) && (\n <div\n style={{\n display: \"flex\",\n flexWrap: \"wrap\",\n alignItems: \"center\",\n gap: \"14px\",\n marginBottom: \"8px\",\n }}\n >\n {showCompressToggle && (\n <ToggleCheckbox\n checked={compress}\n onChange={onCompressChange}\n label=\"Compress to changed paths only\"\n title=\"Collapse unchanged branches, showing only the address of what changed\"\n />\n )}\n {showOrderToggle && (\n <ToggleCheckbox\n checked={latestFirst}\n onChange={onLatestFirstChange}\n label=\"Latest (+) change first\"\n title=\"Show the new value (+) above the previous value (−); off shows previous first\"\n />\n )}\n </div>\n )}\n {view === \"props\" && (\n <DiffView\n before={change.prevSnapshot}\n after={change.snapshot}\n latestFirst={latestFirst}\n />\n )}\n {view === \"diff\" && (\n <JsonDiffView\n before={change.prevSnapshot}\n after={change.snapshot}\n compress={compress}\n latestFirst={latestFirst}\n />\n )}\n {view === \"before\" && (\n <HighlightedJsonView\n before={change.prevSnapshot}\n after={change.snapshot}\n side=\"before\"\n compress={compress}\n />\n )}\n {view === \"after\" && (\n <HighlightedJsonView\n before={change.prevSnapshot}\n after={change.snapshot}\n side=\"after\"\n compress={compress}\n />\n )}\n </div>\n </div>\n );\n}\n\nfunction ToggleCheckbox({\n checked,\n onChange,\n label,\n title,\n}: {\n checked: boolean;\n onChange: (checked: boolean) => void;\n label: string;\n title: string;\n}) {\n return (\n <label\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"6px\",\n color: DEVTOOL_COLOR_TEXT_MUTED,\n fontSize: \"10px\",\n fontFamily: SANS_FONT,\n cursor: \"pointer\",\n userSelect: \"none\",\n }}\n title={title}\n >\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(e) => onChange(e.target.checked)}\n style={{ cursor: \"pointer\", margin: 0 }}\n />\n {label}\n </label>\n );\n}\n","import { DevtoolsVirtualList } from \"nice-devtools-shared\";\r\nimport type { CSSProperties } from \"react\";\r\nimport {\r\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\r\n DEVTOOL_COLOR_TEXT_FAINT,\r\n DEVTOOL_COLOR_TEXT_MUTED,\r\n DEVTOOL_COLOR_TEXT_SECONDARY,\r\n DEVTOOL_LIST_BASE_BACKGROUND,\r\n DEVTOOL_LIST_SELECTED_BACKGROUND,\r\n DEVTOOL_SECTION_BACKGROUND,\r\n MONO_FONT,\r\n SANS_FONT,\r\n} from \"../../core/devtools_colors\";\r\nimport type { IDevtoolsStateChange } from \"../../core/StateDevtools.types\";\r\nimport { formatTimestamp, type IChangeGroup, SOURCE_COLOR, SOURCE_LABEL, summarizeChange } from \"./utils\";\r\n\r\n// Identity is the group's oldest member, not the representative: the representative\r\n// changes as newer no-op changes merge in, which would drop the highlight off a run\r\n// the user is actively reviewing (and remount the row).\r\nconst getGroupKey = (group: IChangeGroup) => group.oldest.cuid;\r\n\r\nexport function ChangeList({\r\n groups,\r\n selectedCuid,\r\n onSelect,\r\n showStore,\r\n style,\r\n}: {\r\n groups: IChangeGroup[];\r\n selectedCuid: string | null;\r\n onSelect: (cuid: string) => void;\r\n showStore: boolean;\r\n style?: CSSProperties;\r\n}) {\r\n return (\r\n <DevtoolsVirtualList<IChangeGroup>\r\n items={groups}\r\n getItemKey={getGroupKey}\r\n selectedKey={selectedCuid}\r\n estimateSize={44}\r\n overscan={12}\r\n style={style}\r\n empty={\r\n <div\r\n style={{\r\n padding: \"24px\",\r\n textAlign: \"center\",\r\n color: DEVTOOL_COLOR_TEXT_MUTED,\r\n fontSize: \"11px\",\r\n ...style,\r\n }}\r\n >\r\n No changes recorded yet. Mutate a store to see it here.\r\n </div>\r\n }\r\n renderItem={(group) => (\r\n <ChangeRow\r\n change={group.representative}\r\n count={group.count}\r\n selected={group.oldest.cuid === selectedCuid}\r\n onClick={() => onSelect(group.oldest.cuid)}\r\n showStore={showStore}\r\n />\r\n )}\r\n />\r\n );\r\n}\r\n\r\nfunction ChangeRow({\r\n change,\r\n count,\r\n selected,\r\n onClick,\r\n showStore,\r\n}: {\r\n change: IDevtoolsStateChange;\r\n count: number;\r\n selected: boolean;\r\n onClick: () => void;\r\n showStore: boolean;\r\n}) {\r\n const sourceColor = SOURCE_COLOR[change.source];\r\n return (\r\n <div\r\n onClick={onClick}\r\n style={{\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n gap: \"3px\",\r\n padding: \"6px 10px\",\r\n cursor: \"pointer\",\r\n borderBottom: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`,\r\n borderLeft: `2px solid ${selected ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : \"transparent\"}`,\r\n background: selected ? DEVTOOL_LIST_SELECTED_BACKGROUND : DEVTOOL_LIST_BASE_BACKGROUND,\r\n }}\r\n >\r\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"6px\" }}>\r\n <span\r\n style={{\r\n color: DEVTOOL_COLOR_TEXT_MUTED,\r\n fontSize: \"10px\",\r\n fontFamily: MONO_FONT,\r\n flexShrink: 0,\r\n }}\r\n >\r\n {formatTimestamp(change.timestamp)}\r\n </span>\r\n <Badge color={sourceColor}>{SOURCE_LABEL[change.source]}</Badge>\r\n {count > 1 && (\r\n <span\r\n title={`${count} consecutive identical updates`}\r\n style={{\r\n flexShrink: 0,\r\n padding: \"0 5px\",\r\n borderRadius: \"999px\",\r\n background: DEVTOOL_SECTION_BACKGROUND,\r\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\r\n fontSize: \"9px\",\r\n fontWeight: 700,\r\n fontFamily: MONO_FONT,\r\n }}\r\n >\r\n ×{count}\r\n </span>\r\n )}\r\n {showStore && (\r\n <span\r\n style={{\r\n color: DEVTOOL_COLOR_SEMANTIC_SYSTEM,\r\n fontSize: \"10px\",\r\n fontFamily: MONO_FONT,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {change.storeLabel}\r\n </span>\r\n )}\r\n <span style={{ flex: 1 }} />\r\n {change.patches.length > 0 && (\r\n <span style={{ color: DEVTOOL_COLOR_TEXT_FAINT, fontSize: \"10px\", flexShrink: 0 }}>\r\n {change.patches.length} patch{change.patches.length === 1 ? \"\" : \"es\"}\r\n </span>\r\n )}\r\n </div>\r\n <div\r\n style={{\r\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\r\n fontSize: \"11px\",\r\n fontFamily: MONO_FONT,\r\n overflow: \"hidden\",\r\n textOverflow: \"ellipsis\",\r\n whiteSpace: \"nowrap\",\r\n }}\r\n >\r\n {summarizeChange(change)}\r\n </div>\r\n </div>\r\n );\r\n}\r\n\r\nfunction Badge({ color, children }: { color: string; children: string }) {\r\n return (\r\n <span\r\n style={{\r\n flexShrink: 0,\r\n padding: \"1px 6px\",\r\n borderRadius: \"999px\",\r\n background: color,\r\n color: \"#0f172a\",\r\n fontSize: \"8px\",\r\n fontWeight: 700,\r\n letterSpacing: \"0.08em\",\r\n fontFamily: SANS_FONT,\r\n }}\r\n >\r\n {children}\r\n </span>\r\n );\r\n}\r\n","import { useEffect, useState } from \"react\";\nimport {\n DEVTOOL_COLOR_SEMANTIC_ERROR,\n DEVTOOL_COLOR_SEMANTIC_SUCCESS,\n DEVTOOL_COLOR_SEMANTIC_WARNING,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_COLOR_TEXT_SECONDARY,\n DEVTOOL_DETAIL_BASE_BACKGROUND,\n DEVTOOL_EDITOR_BACKGROUND,\n DEVTOOL_ERROR_BACKGROUND,\n DEVTOOL_PANEL_DIVIDER_BORDER,\n DEVTOOL_SECTION_BACKGROUND,\n MONO_FONT,\n SANS_FONT,\n} from \"../../core/devtools_colors\";\nimport type { IDevtoolsStoreInfo } from \"../../core/StateDevtools.types\";\nimport { JsonView } from \"./JsonView\";\nimport { SectionLabel } from \"./SectionLabel\";\nimport { safeStringify } from \"./utils\";\n\n/**\n * Live current-state view (top half) plus a direct JSON editor (bottom half) for\n * one store — a fixed 50/50 split so the editor is usable without manual\n * resizing. Editing is the \"trigger edits directly for testing\" capability: the\n * draft is parsed and handed to {@link StateDevtoolsCore.applyEdit}, which\n * replaces the store state.\n *\n * The draft is seeded from the live state only while it is clean — once the user\n * types, incoming external updates no longer clobber their edit (a \"reload\"\n * button re-syncs on demand).\n */\nexport function StateInspector({\n store,\n onApply,\n}: {\n store: IDevtoolsStoreInfo;\n onApply: (storeId: string, newState: unknown) => void;\n}) {\n const liveText = safeStringify(store.currentState, 2);\n const [draft, setDraft] = useState(liveText);\n const [dirty, setDirty] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Reset the editor whenever the selected store changes.\n // biome-ignore lint/correctness/useExhaustiveDependencies: re-seed only on store id.\n useEffect(() => {\n setDraft(liveText);\n setDirty(false);\n setError(null);\n }, [store.id]);\n\n // Keep a clean editor in sync with live external updates.\n // biome-ignore lint/correctness/useExhaustiveDependencies: intentionally driven by liveText.\n useEffect(() => {\n if (!dirty) setDraft(liveText);\n }, [liveText]);\n\n const onEdit = (value: string) => {\n setDraft(value);\n setDirty(true);\n setError(null);\n };\n\n const reload = () => {\n setDraft(liveText);\n setDirty(false);\n setError(null);\n };\n\n const apply = () => {\n let parsed: unknown;\n try {\n parsed = JSON.parse(draft);\n } catch (e) {\n setError(e instanceof Error ? e.message : \"Invalid JSON\");\n return;\n }\n onApply(store.id, parsed);\n setDirty(false);\n setError(null);\n };\n\n return (\n <div\n style={{\n flex: 1,\n display: \"flex\",\n flexDirection: \"column\",\n overflow: \"hidden\",\n minHeight: 0,\n background: DEVTOOL_DETAIL_BASE_BACKGROUND,\n }}\n >\n {/* Current state — top half */}\n <div\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n padding: \"10px 12px 8px\",\n }}\n >\n <SectionLabel label=\"Current state\" />\n <div style={{ flex: 1, minHeight: 0, overflow: \"auto\" }}>\n <JsonView value={store.currentState} style={{ minHeight: \"100%\" }} />\n </div>\n </div>\n\n {/* Edit & apply — bottom half */}\n <div\n style={{\n flex: 1,\n minHeight: 0,\n display: \"flex\",\n flexDirection: \"column\",\n padding: \"8px 12px 10px\",\n borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,\n }}\n >\n <div\n style={{\n display: \"flex\",\n alignItems: \"center\",\n justifyContent: \"space-between\",\n marginBottom: \"3px\",\n }}\n >\n <SectionLabel label=\"Edit & apply\" color={DEVTOOL_COLOR_SEMANTIC_WARNING} />\n {dirty && (\n <button onClick={reload} style={linkButtonStyle(DEVTOOL_COLOR_TEXT_MUTED)}>\n reload from store\n </button>\n )}\n </div>\n <textarea\n value={draft}\n spellCheck={false}\n onChange={(e) => onEdit(e.target.value)}\n style={{\n flex: 1,\n minHeight: 0,\n width: \"100%\",\n resize: \"none\",\n boxSizing: \"border-box\",\n background: DEVTOOL_EDITOR_BACKGROUND,\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\n border: `1px solid ${error != null ? DEVTOOL_COLOR_SEMANTIC_ERROR : DEVTOOL_SECTION_BACKGROUND}`,\n borderRadius: \"4px\",\n padding: \"8px 10px\",\n fontFamily: MONO_FONT,\n fontSize: \"11px\",\n lineHeight: 1.5,\n }}\n />\n {error != null && (\n <div\n style={{\n marginTop: \"6px\",\n padding: \"6px 8px\",\n borderRadius: \"4px\",\n background: DEVTOOL_ERROR_BACKGROUND,\n color: DEVTOOL_COLOR_SEMANTIC_ERROR,\n fontFamily: MONO_FONT,\n fontSize: \"10px\",\n flexShrink: 0,\n }}\n >\n {error}\n </div>\n )}\n <div style={{ display: \"flex\", gap: \"8px\", marginTop: \"8px\", flexShrink: 0 }}>\n <button\n onClick={apply}\n disabled={!dirty}\n style={{\n background: dirty ? DEVTOOL_COLOR_SEMANTIC_SUCCESS : DEVTOOL_SECTION_BACKGROUND,\n color: dirty ? \"#0f172a\" : DEVTOOL_COLOR_TEXT_MUTED,\n border: \"none\",\n borderRadius: \"4px\",\n cursor: dirty ? \"pointer\" : \"not-allowed\",\n fontSize: \"11px\",\n fontWeight: 600,\n padding: \"5px 14px\",\n fontFamily: SANS_FONT,\n }}\n >\n Apply to store\n </button>\n </div>\n </div>\n </div>\n );\n}\n\nfunction linkButtonStyle(color: string) {\n return {\n background: \"none\",\n border: \"none\",\n color,\n cursor: \"pointer\",\n fontSize: \"10px\",\n padding: 0,\n fontFamily: SANS_FONT,\n } as const;\n}\n","import {\n DEVTOOL_COLOR_SEMANTIC_SYSTEM,\n DEVTOOL_COLOR_TEXT_FAINT,\n DEVTOOL_COLOR_TEXT_MUTED,\n DEVTOOL_LIST_BASE_BACKGROUND,\n DEVTOOL_SECTION_BACKGROUND,\n MONO_FONT,\n} from \"../../core/devtools_colors\";\nimport type { IDevtoolsStoreInfo } from \"../../core/StateDevtools.types\";\n\n/**\n * Horizontal store filter. `null` selection means \"all stores\". When\n * `includeAll` is false (the State inspector needs a concrete store) the All\n * pill is omitted.\n */\nexport function StoreTabs({\n stores,\n selectedStoreId,\n onSelect,\n includeAll = true,\n}: {\n stores: IDevtoolsStoreInfo[];\n selectedStoreId: string | null;\n onSelect: (id: string | null) => void;\n includeAll?: boolean;\n}) {\n return (\n <div\n style={{\n display: \"flex\",\n gap: \"6px\",\n padding: \"6px 10px\",\n overflowX: \"auto\",\n background: DEVTOOL_LIST_BASE_BACKGROUND,\n borderBottom: `1px solid ${DEVTOOL_SECTION_BACKGROUND}`,\n flexWrap: \"wrap\",\n flexShrink: 0,\n }}\n >\n {includeAll && (\n <Pill active={selectedStoreId == null} onClick={() => onSelect(null)} label=\"all\" />\n )}\n {stores.length === 0 && (\n <span style={{ color: DEVTOOL_COLOR_TEXT_MUTED, fontSize: \"11px\", padding: \"2px 0\" }}>\n no stores registered\n </span>\n )}\n {stores.map((store) => (\n <Pill\n key={store.id}\n active={selectedStoreId === store.id}\n onClick={() => onSelect(store.id)}\n label={store.label}\n count={store.changeCount}\n />\n ))}\n </div>\n );\n}\n\nfunction Pill({\n active,\n onClick,\n label,\n count,\n}: {\n active: boolean;\n onClick: () => void;\n label: string;\n count?: number;\n}) {\n return (\n <button\n onClick={onClick}\n style={{\n display: \"flex\",\n alignItems: \"center\",\n gap: \"5px\",\n background: active ? DEVTOOL_SECTION_BACKGROUND : \"transparent\",\n color: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_MUTED,\n border: `1px solid ${active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT}`,\n borderRadius: \"5px\",\n cursor: \"pointer\",\n fontSize: \"11px\",\n fontFamily: MONO_FONT,\n padding: \"2px 8px\",\n whiteSpace: \"nowrap\",\n flexShrink: 0,\n }}\n >\n {label}\n {count != null && count > 0 && (\n <span\n style={{\n color: active ? DEVTOOL_COLOR_SEMANTIC_SYSTEM : DEVTOOL_COLOR_TEXT_FAINT,\n fontSize: \"10px\",\n }}\n >\n {count}\n </span>\n )}\n </button>\n );\n}\n","import {\r\n DevtoolsLauncher,\r\n FollowLatestToggles,\r\n getDevtoolsDockCoordinator,\r\n getDockSide,\r\n PanelHeader,\r\n ResizeHandle,\r\n SegmentedControl,\r\n SplitHandle,\r\n} from \"nice-devtools-shared\";\r\nimport { useEffect, useId, useMemo, useReducer, useState } from \"react\";\r\nimport {\r\n DEVTOOL_COLOR_TEXT_MUTED,\r\n DEVTOOL_COLOR_TEXT_SECONDARY,\r\n DEVTOOL_LIST_BASE_BACKGROUND,\r\n DEVTOOL_PANEL_BORDER,\r\n DEVTOOL_PANEL_DIVIDER_BORDER,\r\n} from \"../core/devtools_colors\";\r\nimport type { IStateDevtoolsSnapshot, TDevtoolsPosition } from \"../core/StateDevtools.types\";\r\nimport type { StateDevtoolsCore } from \"../core/StateDevtoolsCore\";\r\nimport { ChangeDetailPanel, type TChangeView } from \"./components/ChangeDetailPanel\";\r\nimport { ChangeList } from \"./components/ChangeList\";\r\nimport { StateInspector } from \"./components/StateInspector\";\r\nimport { StoreTabs } from \"./components/StoreTabs\";\r\nimport { groupChanges } from \"./components/utils\";\r\n\r\nif (typeof document !== \"undefined\" && !document.getElementById(\"__nice-state-devtools-styles\")) {\r\n const style = document.createElement(\"style\");\r\n style.id = \"__nice-state-devtools-styles\";\r\n style.textContent = `\r\n @keyframes __nice-state-pulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.35; }\r\n }\r\n #__nice-state-devtools-panel ::-webkit-scrollbar { width: 4px; height: 4px; }\r\n #__nice-state-devtools-panel ::-webkit-scrollbar-track { background: transparent; }\r\n #__nice-state-devtools-panel ::-webkit-scrollbar-thumb { background: #334155; border-radius: 2px; }\r\n #__nice-state-devtools-panel ::-webkit-scrollbar-thumb:hover { background: #475569; }\r\n #__nice-state-devtools-panel ::-webkit-scrollbar-corner { background: transparent; }\r\n /* Shield the panel's native form controls from the host app's global element\r\n styles (e.g. a bare \\`input {}\\`/\\`button {}\\` rule). \\`all: revert\\` drops them\r\n to the UA baseline the panel is authored against; the panel's own inline\r\n styles still win, so its look is unchanged across any host. */\r\n #__nice-state-devtools-panel input,\r\n #__nice-state-devtools-panel button,\r\n #__nice-state-devtools-panel select,\r\n #__nice-state-devtools-panel textarea { all: revert; font-family: inherit; }\r\n `;\r\n document.head?.appendChild(style);\r\n}\r\n\r\nconst PREFS_KEY = \"__nice-state-devtools-prefs\";\r\nconst DOCKED_HEIGHT_DEFAULT = 340;\r\nconst DOCKED_WIDTH_DEFAULT = 330;\r\nconst DETAIL_RATIO_DEFAULT = 0.5;\r\n\r\nconst DOCK_POSITIONS: TDevtoolsPosition[] = [\"dock-bottom\", \"dock-top\", \"dock-left\", \"dock-right\"];\r\n\r\nfunction isDockPosition(value: unknown): value is TDevtoolsPosition {\r\n return typeof value === \"string\" && (DOCK_POSITIONS as string[]).includes(value);\r\n}\r\n\r\ntype TMode = \"timeline\" | \"state\";\r\n\r\ninterface IDevtoolsPrefs {\r\n position: TDevtoolsPosition;\r\n isOpen: boolean;\r\n dockedHeight: number;\r\n dockedWidth: number;\r\n detailRatio: number;\r\n stayOnLatest: boolean;\r\n followLatestOnSelect: boolean;\r\n compressDiff: boolean;\r\n detailView: TChangeView;\r\n diffLatestFirst: boolean;\r\n}\r\n\r\nfunction readPrefs(defaultPosition: TDevtoolsPosition, initialOpen: boolean): IDevtoolsPrefs {\r\n const fallback: IDevtoolsPrefs = {\r\n position: defaultPosition,\r\n isOpen: initialOpen,\r\n dockedHeight: DOCKED_HEIGHT_DEFAULT,\r\n dockedWidth: DOCKED_WIDTH_DEFAULT,\r\n detailRatio: DETAIL_RATIO_DEFAULT,\r\n stayOnLatest: true,\r\n followLatestOnSelect: true,\r\n compressDiff: true,\r\n detailView: \"props\",\r\n diffLatestFirst: true,\r\n };\r\n try {\r\n if (typeof localStorage === \"undefined\") return fallback;\r\n const stored = localStorage.getItem(PREFS_KEY);\r\n const merged = stored != null ? { ...fallback, ...JSON.parse(stored) } : fallback;\r\n // Migrate any legacy floating-corner position to the default dock side.\r\n if (!isDockPosition(merged.position)) merged.position = defaultPosition;\r\n return merged;\r\n } catch {\r\n return fallback;\r\n }\r\n}\r\n\r\nfunction writePrefs(prefs: IDevtoolsPrefs): void {\r\n try {\r\n localStorage.setItem(PREFS_KEY, JSON.stringify(prefs));\r\n } catch {\r\n return;\r\n }\r\n}\r\n\r\nexport interface INiceStateDevtoolsProps {\r\n core: StateDevtoolsCore;\r\n position?: TDevtoolsPosition;\r\n initialOpen?: boolean;\r\n /** Show the panel even when NODE_ENV is not \"development\". */\r\n forceEnable?: boolean;\r\n}\r\n\r\nconst EMPTY_SNAPSHOT: IStateDevtoolsSnapshot = { stores: [], changes: [], paused: false };\r\n\r\nexport function NiceStateDevtools({ forceEnable, ...props }: INiceStateDevtoolsProps) {\r\n // Bracket notation bypasses Bun's dot-notation `define` substitution, so\r\n // `process[\"env\"][\"NODE_ENV\"]` stays as a live expression in the built output\r\n // and the consumer's bundler evaluates it at their build time.\r\n if (!forceEnable && process[\"env\"][\"NODE_ENV\"] !== \"development\") {\r\n return null;\r\n }\r\n return <NiceStateDevtools_Panel {...props} />;\r\n}\r\n\r\nfunction NiceStateDevtools_Panel({\r\n core,\r\n position: defaultPosition = \"dock-right\",\r\n initialOpen = false,\r\n}: INiceStateDevtoolsProps) {\r\n const [prefs, setPrefsRaw] = useState<IDevtoolsPrefs>(() =>\r\n readPrefs(defaultPosition, initialOpen),\r\n );\r\n const [snapshot, setSnapshot] = useState<IStateDevtoolsSnapshot>(EMPTY_SNAPSHOT);\r\n const [mode, setMode] = useState<TMode>(\"timeline\");\r\n const [storeFilter, setStoreFilter] = useState<string | null>(null);\r\n const [selectedChangeCuid, setSelectedChangeCuid] = useState<string | null>(null);\r\n\r\n useEffect(() => core.subscribe(setSnapshot), [core]);\r\n\r\n const setPrefs = (update: Partial<IDevtoolsPrefs>) => {\r\n setPrefsRaw((prev) => ({ ...prev, ...update }));\r\n };\r\n\r\n // Persist prefs to localStorage, debounced — a resize drag fires on every\r\n // mouse move, so writing on each one would thrash localStorage.\r\n useEffect(() => {\r\n const timer = setTimeout(() => writePrefs(prefs), 250);\r\n return () => clearTimeout(timer);\r\n }, [prefs]);\r\n\r\n const { stores, changes, paused } = snapshot;\r\n const {\r\n position,\r\n isOpen,\r\n dockedHeight,\r\n dockedWidth,\r\n detailRatio,\r\n stayOnLatest,\r\n followLatestOnSelect,\r\n compressDiff,\r\n detailView,\r\n diffLatestFirst,\r\n } = prefs;\r\n const dockSide = getDockSide(position);\r\n const isHorizDock = dockSide === \"top\" || dockSide === \"bottom\";\r\n const dockedSize = isHorizDock ? dockedHeight : dockedWidth;\r\n\r\n const filteredChanges = useMemo(\r\n () => (storeFilter == null ? changes : changes.filter((c) => c.storeId === storeFilter)),\r\n [changes, storeFilter],\r\n );\r\n const groups = useMemo(() => groupChanges(filteredChanges), [filteredChanges]);\r\n const selectedChange = useMemo(() => {\r\n if (selectedChangeCuid == null) return null;\r\n // Identify the selected group by its *oldest* member, not the representative.\r\n // The representative is the newest change in the run, so it changes whenever a\r\n // new structurally-equal change merges into the group — that would orphan the\r\n // selection and fall through to the empty self-diff below. The oldest member is\r\n // the one that actually moved the state and stays put as no-ops merge in, so it\r\n // is the stable identity of the run.\r\n const group = groups.find((g) => g.oldest.cuid === selectedChangeCuid);\r\n if (group == null) return changes.find((c) => c.cuid === selectedChangeCuid) ?? null;\r\n // A collapsed run's representative (newest) has prev === snapshot, so its own\r\n // diff is empty. Show the run's real change instead: the oldest member's\r\n // before-state through to the current after-state, and offer that member's\r\n // inverse patches so reverting undoes the whole run rather than a no-op.\r\n if (group.count > 1) {\r\n return {\r\n ...group.representative,\r\n prevSnapshot: group.oldest.prevSnapshot,\r\n inversePatches: group.oldest.inversePatches,\r\n };\r\n }\r\n return group.representative;\r\n }, [selectedChangeCuid, groups, changes]);\r\n\r\n // \"Stay on latest\": whenever a new change lands at the head of the (newest-\r\n // first) list, follow it so the detail pane always shows the latest change.\r\n // Track the head group by its oldest member to match the selection identity\r\n // used above — when a new change only merges into the head group (rather than\r\n // starting a new one) this stays stable, keeping the full run's diff in view.\r\n const latestCuid = groups.length > 0 ? groups[0].oldest.cuid : null;\r\n useEffect(() => {\r\n if (stayOnLatest && latestCuid != null) setSelectedChangeCuid(latestCuid);\r\n }, [stayOnLatest, latestCuid]);\r\n\r\n // The State inspector needs a concrete store: fall back to the first one.\r\n const activeStore =\r\n stores.find((s) => s.id === storeFilter) ?? (stores.length > 0 ? stores[0] : null);\r\n\r\n // Coordinate with any other nice-* devtools on the page so panels and launch\r\n // buttons cooperate instead of overlapping (see devtools_dock.ts).\r\n const dock = useMemo(() => getDevtoolsDockCoordinator(), []);\r\n const panelId = useId();\r\n const [, bumpView] = useReducer((n: number) => n + 1, 0);\r\n const badge = changes.length > 0 ? String(changes.length) : undefined;\r\n\r\n // biome-ignore lint/correctness/useExhaustiveDependencies: register once on mount; the effect below syncs the live fields.\r\n useEffect(() => {\r\n const unregister = dock.register({\r\n id: panelId,\r\n label: \"state\",\r\n icon: \"🧩\",\r\n side: dockSide,\r\n size: dockedSize,\r\n open: isOpen,\r\n badge,\r\n onOpen: () => setPrefs({ isOpen: true }),\r\n });\r\n const unsubscribe = dock.subscribe(bumpView);\r\n return () => {\r\n unregister();\r\n unsubscribe();\r\n };\r\n }, [dock, panelId]);\r\n\r\n useEffect(() => {\r\n dock.update(panelId, { side: dockSide, size: dockedSize, open: isOpen, badge });\r\n }, [dock, panelId, dockSide, dockedSize, isOpen, badge]);\r\n\r\n const view = dock.getView(panelId);\r\n\r\n const baseStyle: React.CSSProperties = {\r\n position: \"fixed\",\r\n zIndex: 2147483646,\r\n fontFamily: \"ui-monospace, 'Cascadia Code', 'Source Code Pro', monospace\",\r\n fontSize: \"12px\",\r\n };\r\n\r\n // While every devtool is collapsed, the primary one renders a single combined\r\n // launcher for all of them; the others render nothing.\r\n if (!isOpen) {\r\n if (view.isPrimary && !view.anyOpen) {\r\n return <DevtoolsLauncher items={view.devtools} />;\r\n }\r\n return null;\r\n }\r\n\r\n const panelStyle: React.CSSProperties = {\r\n ...baseStyle,\r\n background: DEVTOOL_LIST_BASE_BACKGROUND,\r\n border: `1px solid ${DEVTOOL_PANEL_BORDER}`,\r\n color: DEVTOOL_COLOR_TEXT_SECONDARY,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n boxShadow: \"0 -4px 24px rgba(0,0,0,0.4)\",\r\n overflow: \"hidden\",\r\n // When stacked alongside another panel on the same side, square off every\r\n // corner so the panels read as one continuous block instead of leaving a\r\n // curved seam or a rounded edge poking out behind a neighbour.\r\n ...(dockSide === \"bottom\"\r\n ? {\r\n bottom: view.dockOffset,\r\n left: 0,\r\n right: 0,\r\n height: `${dockedSize}px`,\r\n borderRadius: view.stacked ? \"0\" : \"8px 8px 0 0\",\r\n }\r\n : dockSide === \"top\"\r\n ? {\r\n top: view.dockOffset,\r\n left: 0,\r\n right: 0,\r\n height: `${dockedSize}px`,\r\n borderRadius: view.stacked ? \"0\" : \"0 0 8px 8px\",\r\n }\r\n : dockSide === \"left\"\r\n ? {\r\n top: 0,\r\n left: view.dockOffset,\r\n bottom: 0,\r\n width: `${dockedSize}px`,\r\n borderRadius: view.stacked ? \"0\" : \"0 8px 8px 0\",\r\n }\r\n : {\r\n top: 0,\r\n right: view.dockOffset,\r\n bottom: 0,\r\n width: `${dockedSize}px`,\r\n borderRadius: view.stacked ? \"0\" : \"8px 0 0 8px\",\r\n }),\r\n };\r\n\r\n return (\r\n <div id=\"__nice-state-devtools-panel\" style={panelStyle}>\r\n <ResizeHandle\r\n dockSide={dockSide}\r\n dockedSize={dockedSize}\r\n onChange={(size) => setPrefs(isHorizDock ? { dockedHeight: size } : { dockedWidth: size })}\r\n />\r\n <PanelHeader\r\n title=\"🧩 state\"\r\n position={position}\r\n onPositionChange={(p) => setPrefs({ position: p })}\r\n onClose={() => setPrefs({ isOpen: false })}\r\n onClear={\r\n changes.length > 0\r\n ? () => {\r\n core.clear();\r\n setSelectedChangeCuid(null);\r\n }\r\n : undefined\r\n }\r\n paused={paused}\r\n onTogglePause={() => core.togglePaused()}\r\n openOthers={view.otherClosed}\r\n >\r\n <SegmentedControl<TMode>\r\n options={[\r\n { value: \"timeline\", label: \"Timeline\" },\r\n { value: \"state\", label: \"State\" },\r\n ]}\r\n value={mode}\r\n onChange={setMode}\r\n />\r\n </PanelHeader>\r\n\r\n <StoreTabs\r\n stores={stores}\r\n selectedStoreId={mode === \"state\" ? (activeStore?.id ?? null) : storeFilter}\r\n onSelect={setStoreFilter}\r\n includeAll={mode === \"timeline\"}\r\n />\r\n\r\n {mode === \"state\" ? (\r\n activeStore != null ? (\r\n <StateInspector store={activeStore} onApply={(id, next) => core.applyEdit(id, next)} />\r\n ) : (\r\n <EmptyMessage>No stores registered. Call core.registerStore(...).</EmptyMessage>\r\n )\r\n ) : (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: \"flex\",\r\n flexDirection: isHorizDock ? \"row\" : \"column\",\r\n overflow: \"hidden\",\r\n minHeight: 0,\r\n }}\r\n >\r\n {/* List — shares the panel with the detail pane via the draggable split */}\r\n <div\r\n style={{\r\n flexGrow: selectedChange != null ? 1 - detailRatio : 1,\r\n flexShrink: 1,\r\n flexBasis: 0,\r\n minWidth: 0,\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n }}\r\n >\r\n <FollowLatestToggles\r\n noun=\"change\"\r\n stayOnLatest={stayOnLatest}\r\n onStayOnLatestChange={(next) => setPrefs({ stayOnLatest: next })}\r\n followLatestOnSelect={followLatestOnSelect}\r\n onFollowLatestOnSelectChange={(next) => {\r\n // Enabling this while already sitting on the latest change is itself\r\n // a \"select the latest\" intent — start following so the view tracks\r\n // new changes, matching what a fresh click on the latest would do.\r\n if (\r\n next &&\r\n latestCuid != null &&\r\n selectedChangeCuid === latestCuid &&\r\n !stayOnLatest\r\n ) {\r\n setPrefs({ followLatestOnSelect: next, stayOnLatest: true });\r\n } else {\r\n setPrefs({ followLatestOnSelect: next });\r\n }\r\n }}\r\n />\r\n <div style={{ flex: 1, minHeight: 0, display: \"flex\", flexDirection: \"column\" }}>\r\n <ChangeList\r\n style={{ flex: 1, minHeight: 0, overflowY: \"auto\" }}\r\n groups={groups}\r\n selectedCuid={selectedChangeCuid}\r\n onSelect={(cuid) => {\r\n const next = selectedChangeCuid === cuid ? null : cuid;\r\n if (next != null && next === latestCuid && followLatestOnSelect) {\r\n // Selecting the latest change means \"show me the latest\" — start\r\n // (or keep) following so the view tracks new changes as they land.\r\n if (!stayOnLatest) setPrefs({ stayOnLatest: true });\r\n } else if (stayOnLatest) {\r\n // Any other selection (a past change, or deselecting) means the\r\n // user is taking control — stop following.\r\n setPrefs({ stayOnLatest: false });\r\n }\r\n setSelectedChangeCuid(next);\r\n }}\r\n showStore={storeFilter == null}\r\n />\r\n </div>\r\n </div>\r\n {/* Detail — resizable; ratio persisted in prefs */}\r\n {selectedChange != null && (\r\n <>\r\n <SplitHandle\r\n horizontal={isHorizDock}\r\n onRatioChange={(ratio) => setPrefs({ detailRatio: ratio })}\r\n />\r\n <div\r\n style={{\r\n flexGrow: detailRatio,\r\n flexShrink: 1,\r\n flexBasis: 0,\r\n minWidth: 0,\r\n minHeight: 0,\r\n display: \"flex\",\r\n flexDirection: \"column\",\r\n overflow: \"hidden\",\r\n ...(isHorizDock\r\n ? {\r\n borderLeft: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,\r\n boxShadow: \"inset 18px 0 36px -14px rgba(0,0,0,0.8)\",\r\n }\r\n : {\r\n borderTop: `1px solid ${DEVTOOL_PANEL_DIVIDER_BORDER}`,\r\n boxShadow: \"inset 0 18px 36px -14px rgba(0,0,0,0.8)\",\r\n }),\r\n }}\r\n >\r\n {/* The selected detail tab (Diff View / Before / …) and compress\r\n toggle live in persisted prefs, so they survive both selection\r\n changes and page reloads. */}\r\n <ChangeDetailPanel\r\n change={selectedChange}\r\n onRevert={(c) => core.revertChange(c)}\r\n view={detailView}\r\n onViewChange={(v) => setPrefs({ detailView: v })}\r\n compress={compressDiff}\r\n onCompressChange={(v) => setPrefs({ compressDiff: v })}\r\n latestFirst={diffLatestFirst}\r\n onLatestFirstChange={(v) => setPrefs({ diffLatestFirst: v })}\r\n />\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )}\r\n </div>\r\n );\r\n}\r\n\r\nfunction EmptyMessage({ children }: { children: React.ReactNode }) {\r\n return (\r\n <div\r\n style={{\r\n flex: 1,\r\n display: \"flex\",\r\n alignItems: \"center\",\r\n justifyContent: \"center\",\r\n padding: \"24px\",\r\n textAlign: \"center\",\r\n color: DEVTOOL_COLOR_TEXT_MUTED,\r\n fontSize: \"11px\",\r\n }}\r\n >\r\n {children}\r\n </div>\r\n );\r\n}\r\n"],"x_google_ignoreList":[7,8],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { a as TReactionFunction, c as TStoreSubscriptionListener, d as TUpdateListener, f as applyPatchesToStore, i as TPatchesCallback, l as TStoreWatch, n as IStoreInternalOptions, o as TStoreAction, p as update, r as Store, s as TStoreActionUpdate, t as ICreateReactionOptions, u as TUpdateFunction } from "./Store-B65MojT2.js";
2
+ export { type ICreateReactionOptions, type IStoreInternalOptions, Store, type TPatchesCallback, type TReactionFunction, type TStoreAction, type TStoreActionUpdate, type TStoreSubscriptionListener, type TStoreWatch, type TUpdateFunction, type TUpdateListener, applyPatchesToStore, update };