@sqlite-sync/devtools 0.12.3 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -537,7 +537,7 @@ function SQLiteSyncDevtools({ className, launcher = true, hidden: hiddenProp, on
537
537
  }) : null]
538
538
  });
539
539
  }
540
- const EVENT_HLC_ACCUMULATOR_QUERY = `SELECT value FROM "worker"."kv" WHERE key = 'crdt.consistency.event_hlc_sum.v2'`;
540
+ const STATE_HASH_QUERY = `SELECT value FROM "worker"."kv" WHERE key = 'crdt.consistency.state_hash.v1'`;
541
541
  const EVENT_STATUS_COUNTS_QUERY = `SELECT status, COUNT(*) AS count FROM "worker"."crdt_events" GROUP BY status`;
542
542
  const MEMORY_DB_SIZE_QUERY = "SELECT (SELECT page_count FROM pragma_page_count()) * (SELECT page_size FROM pragma_page_size()) AS bytes";
543
543
  const WORKER_DB_SIZE_QUERY = `SELECT
@@ -624,9 +624,9 @@ function formatByteSize(bytes) {
624
624
  };
625
625
  }
626
626
  function OverviewTab({ selectedInstance, dbIdCounts }) {
627
- const [eventHlcAccumulator, setEventHlcAccumulator] = useState(null);
628
- const [accumulatorError, setAccumulatorError] = useState(null);
629
- const [isAccumulatorLoading, setIsAccumulatorLoading] = useState(false);
627
+ const [stateHash, setStateHash] = useState(null);
628
+ const [stateHashError, setStateHashError] = useState(null);
629
+ const [isStateHashLoading, setIsStateHashLoading] = useState(false);
630
630
  const [eventCounts, setEventCounts] = useState(null);
631
631
  const [eventCountsError, setEventCountsError] = useState(null);
632
632
  const [isEventCountsLoading, setIsEventCountsLoading] = useState(false);
@@ -635,22 +635,22 @@ function OverviewTab({ selectedInstance, dbIdCounts }) {
635
635
  const [workerBytes, setWorkerBytes] = useState(null);
636
636
  const [workerSizeError, setWorkerSizeError] = useState(null);
637
637
  const [isSizeLoading, setIsSizeLoading] = useState(false);
638
- const refreshEventHlcAccumulator = useCallback(async () => {
638
+ const refreshStateHash = useCallback(async () => {
639
639
  if (!selectedInstance) return;
640
- setIsAccumulatorLoading(true);
641
- setAccumulatorError(null);
640
+ setIsStateHashLoading(true);
641
+ setStateHashError(null);
642
642
  try {
643
643
  const row = (await selectedInstance.instance._internal.executeAsync({
644
- sql: EVENT_HLC_ACCUMULATOR_QUERY,
644
+ sql: STATE_HASH_QUERY,
645
645
  parameters: []
646
646
  })).rows[0];
647
647
  const value = typeof row === "object" && row !== null && "value" in row && typeof row.value === "string" ? row.value : "";
648
- setEventHlcAccumulator(value);
648
+ setStateHash(value);
649
649
  } catch (error) {
650
- setAccumulatorError(error instanceof Error ? error.message : String(error));
651
- setEventHlcAccumulator(null);
650
+ setStateHashError(error instanceof Error ? error.message : String(error));
651
+ setStateHash(null);
652
652
  } finally {
653
- setIsAccumulatorLoading(false);
653
+ setIsStateHashLoading(false);
654
654
  }
655
655
  }, [selectedInstance]);
656
656
  const refreshEventCounts = useCallback(async () => {
@@ -702,19 +702,19 @@ function OverviewTab({ selectedInstance, dbIdCounts }) {
702
702
  setIsSizeLoading(false);
703
703
  }, [selectedInstance]);
704
704
  useEffect(() => {
705
- setEventHlcAccumulator(null);
706
- setAccumulatorError(null);
705
+ setStateHash(null);
706
+ setStateHashError(null);
707
707
  setEventCounts(null);
708
708
  setEventCountsError(null);
709
709
  setMemoryBytes(null);
710
710
  setMemorySizeError(null);
711
711
  setWorkerBytes(null);
712
712
  setWorkerSizeError(null);
713
- refreshEventHlcAccumulator();
713
+ refreshStateHash();
714
714
  refreshEventCounts();
715
715
  refreshDbSizes();
716
716
  }, [
717
- refreshEventHlcAccumulator,
717
+ refreshStateHash,
718
718
  refreshEventCounts,
719
719
  refreshDbSizes
720
720
  ]);
@@ -829,23 +829,23 @@ function OverviewTab({ selectedInstance, dbIdCounts }) {
829
829
  className: "overviewSectionHeader",
830
830
  children: [/* @__PURE__ */ jsx("div", {
831
831
  className: "overviewSectionTitle",
832
- children: "Event HLC accumulator"
832
+ children: "State hash"
833
833
  }), /* @__PURE__ */ jsxs("button", {
834
834
  type: "button",
835
835
  className: "refreshButton",
836
- disabled: isAccumulatorLoading,
837
- onClick: () => void refreshEventHlcAccumulator(),
838
- children: [isAccumulatorLoading ? "…" : "↻", " Refresh"]
836
+ disabled: isStateHashLoading,
837
+ onClick: () => void refreshStateHash(),
838
+ children: [isStateHashLoading ? "…" : "↻", " Refresh"]
839
839
  })]
840
840
  }), /* @__PURE__ */ jsx("div", {
841
841
  className: "overviewAccumulatorValue",
842
- children: accumulatorError ? /* @__PURE__ */ jsx("span", {
842
+ children: stateHashError ? /* @__PURE__ */ jsx("span", {
843
843
  className: "overviewAccumulatorError",
844
- children: accumulatorError
845
- }) : isAccumulatorLoading && eventHlcAccumulator === null ? "Loading…" : eventHlcAccumulator === "" ? /* @__PURE__ */ jsx("span", {
844
+ children: stateHashError
845
+ }) : isStateHashLoading && stateHash === null ? "Loading…" : stateHash === "" ? /* @__PURE__ */ jsx("span", {
846
846
  className: "overviewAccumulatorEmpty",
847
847
  children: "(empty)"
848
- }) : eventHlcAccumulator
848
+ }) : stateHash
849
849
  })]
850
850
  }),
851
851
  /* @__PURE__ */ jsx(DataSection, {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["cssText"],"sources":["../src/devtools-registry.ts","../src/devtools.css?inline","../src/shadow-root.tsx","../src/devtools.tsx"],"sourcesContent":["import type { SyncedDb } from \"@sqlite-sync/core\";\n\nconst devtoolsRegistrySymbol = Symbol.for(\"@sqlite-sync/devtools\");\n\nexport type SQLiteSyncDevtoolsInstance = {\n instanceId: string;\n dbId: string;\n createdAt: number;\n instance: SyncedDb<any>;\n};\n\nexport type SQLiteSyncDevtoolsSnapshot = {\n instances: readonly SQLiteSyncDevtoolsInstance[];\n};\n\nexport type SQLiteSyncDevtoolsRegistry = {\n version: 1;\n instances: Map<string, SQLiteSyncDevtoolsInstance>;\n subscribe(listener: () => void): () => void;\n getSnapshot(): SQLiteSyncDevtoolsSnapshot;\n register(instance: SQLiteSyncDevtoolsInstance): () => void;\n};\n\ntype RegistryGlobal = typeof globalThis & {\n [key: symbol]: SQLiteSyncDevtoolsRegistry | undefined;\n};\n\nfunction createSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const instances = new Map<string, SQLiteSyncDevtoolsInstance>();\n const listeners = new Set<() => void>();\n let snapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n };\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const updateSnapshot = () => {\n snapshot = {\n instances: Array.from(instances.values()),\n };\n notify();\n };\n\n return {\n version: 1,\n instances,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot() {\n return snapshot;\n },\n register(instance) {\n instances.set(instance.instanceId, instance);\n updateSnapshot();\n\n let isUnregistered = false;\n return () => {\n if (isUnregistered) return;\n isUnregistered = true;\n\n if (!instances.delete(instance.instanceId)) return;\n updateSnapshot();\n };\n },\n };\n}\n\nexport function getOrCreateSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const registryGlobal = globalThis as RegistryGlobal;\n\n registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();\n\n return registryGlobal[devtoolsRegistrySymbol];\n}\n",":host {\n all: initial;\n display: block;\n position: relative;\n z-index: 9998;\n --ss-bg: #0e1015;\n --ss-bg-panel: #161921;\n --ss-bg-card: #1c2030;\n --ss-bg-input: #111318;\n --ss-border: #2a2f3e;\n --ss-border-light: #343a4f;\n --ss-text: #e2e8f0;\n --ss-text-muted: #6b7280;\n --ss-text-dim: #9ca3af;\n --ss-teal: #2dd4bf;\n --ss-teal-dim: rgba(45, 212, 191, 0.12);\n --ss-teal-glow: rgba(45, 212, 191, 0.06);\n --ss-error: #f87171;\n --ss-error-bg: rgba(248, 113, 113, 0.08);\n --ss-error-border: rgba(248, 113, 113, 0.25);\n --ss-success: #34d399;\n --ss-success-bg: rgba(52, 211, 153, 0.08);\n --ss-amber: #fbbf24;\n font-family: ui-sans-serif, system-ui, sans-serif;\n color: var(--ss-text);\n font-size: 0.88rem;\n}\n\n:host *,\n:host *::before,\n:host *::after {\n box-sizing: border-box;\n}\n\n.mono {\n font-family: ui-monospace, monospace;\n}\n\n.sm {\n font-size: 0.78rem;\n}\n\n.alignCenter {\n text-align: center;\n}\n\n.mlAuto {\n margin-left: auto;\n}\n\n.hiddenInput {\n display: none;\n}\n\n.floatingRoot {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 9998;\n}\n\n.triggerButton {\n position: absolute;\n right: 16px;\n bottom: 16px;\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n border: 1px solid var(--ss-border);\n border-radius: 8px;\n padding: 0.3rem 0.45rem;\n background: var(--ss-bg-panel);\n color: var(--ss-text);\n box-shadow:\n 0 0 0 1px var(--ss-border),\n 0 4px 16px rgba(0, 0, 0, 0.5);\n cursor: grab;\n touch-action: none;\n user-select: none;\n pointer-events: auto;\n}\n\n.triggerIcon {\n color: var(--ss-teal);\n font-size: 0.9rem;\n line-height: 1;\n}\n\n.triggerCount {\n min-width: 1.1rem;\n border-radius: 4px;\n padding: 0.05rem 0.25rem;\n background-color: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-size: 0.65rem;\n font-weight: 700;\n text-align: center;\n font-family: ui-monospace, monospace;\n}\n\n.overlay {\n position: fixed;\n inset: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.5rem;\n background-color: rgba(0, 0, 0, 0.72);\n backdrop-filter: blur(8px);\n}\n\n.dialog {\n width: min(72rem, 100%);\n height: min(90vh, 860px);\n display: flex;\n flex-direction: column;\n border: 1px solid var(--ss-border);\n border-radius: 16px;\n background: var(--ss-bg);\n box-shadow:\n 0 0 0 1px var(--ss-border),\n 0 40px 80px rgba(0, 0, 0, 0.8),\n 0 0 60px rgba(45, 212, 191, 0.04);\n overflow: hidden;\n font-family: ui-sans-serif, system-ui, sans-serif;\n color: var(--ss-text);\n font-size: 0.88rem;\n}\n\n.header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n padding: 0.85rem 1.1rem;\n border-bottom: 1px solid var(--ss-border);\n background: var(--ss-bg-panel);\n flex-shrink: 0;\n}\n\n.headerLeft {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.headerLogo {\n font-size: 1.3rem;\n color: var(--ss-teal);\n line-height: 1;\n}\n\n.eyebrow {\n font-size: 0.65rem;\n font-weight: 600;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n}\n\n.title {\n margin: 0.05rem 0 0;\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--ss-text);\n letter-spacing: -0.01em;\n}\n\n.headerRight {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.instancePickerLabel {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.instancePickerText {\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--ss-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.instancePickerSelect {\n border-radius: 7px;\n border: 1px solid var(--ss-border);\n padding: 0.35rem 0.6rem;\n background-color: var(--ss-bg-card);\n color: var(--ss-text);\n font-size: 0.82rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n}\n\n.instanceCountBadge {\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n border-radius: 5px;\n padding: 0.2rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.closeButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: transparent;\n color: var(--ss-text-muted);\n font-size: 0.82rem;\n font-weight: 600;\n cursor: pointer;\n}\n\n.hideLauncherButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.3rem 0.65rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.75rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.emptyState {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n gap: 0.75rem;\n flex: 1;\n}\n\n.emptyStateIcon {\n font-size: 2.5rem;\n color: var(--ss-text-muted);\n opacity: 0.4;\n}\n\n.emptyStateText {\n margin: 0;\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--ss-text-dim);\n}\n\n.emptyStateSubtext {\n margin: 0;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n text-align: center;\n}\n\n.inlineCode {\n font-family: ui-monospace, monospace;\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.1em 0.4em;\n font-size: 0.88em;\n color: var(--ss-teal);\n}\n\n.contentLayout {\n display: grid;\n grid-template-columns: 200px minmax(0, 1fr);\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 0;\n padding: 0.75rem;\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-panel);\n overflow-y: auto;\n}\n\n.nav {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n margin-bottom: 1rem;\n}\n\n.navIcon {\n font-size: 0.7rem;\n opacity: 0.7;\n}\n\n.sidebarInfo {\n margin-top: auto;\n padding: 0.75rem;\n border-radius: 8px;\n background: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n}\n\n.sidebarInfoLabel {\n font-size: 0.65rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n margin-bottom: 0.3rem;\n}\n\n.sidebarInfoValue {\n font-size: 0.88rem;\n font-weight: 600;\n color: var(--ss-text);\n word-break: break-word;\n font-family: ui-monospace, monospace;\n}\n\n.sidebarInfoSub {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n margin-top: 0.25rem;\n}\n\n.mainPane {\n min-width: 0;\n overflow-y: auto;\n padding: 1rem;\n}\n\n.overviewLayout {\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n\n.overviewCardsRow {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));\n gap: 0.75rem;\n}\n\n.overviewCard {\n padding: 0.9rem 1rem;\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.overviewCardLabel {\n font-size: 0.68rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n margin-bottom: 0.4rem;\n}\n\n.overviewCardValue {\n font-size: 1rem;\n font-weight: 700;\n color: var(--ss-text);\n word-break: break-word;\n}\n\n.overviewCardSub {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n margin-top: 0.25rem;\n}\n\n.overviewSection {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.overviewSectionTitle {\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n}\n\n.overviewSectionHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n}\n\n.refreshButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.35rem 0.7rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.overviewAccumulatorValue {\n padding: 0.75rem;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n font-family: ui-monospace, monospace;\n font-size: 0.78rem;\n color: var(--ss-text);\n line-height: 1.5;\n word-break: break-all;\n}\n\n.overviewAccumulatorEmpty {\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.overviewAccumulatorError {\n color: var(--ss-error);\n}\n\n.overviewEmpty {\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.eventCountGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));\n gap: 0.5rem;\n}\n\n.eventCountCard {\n padding: 0.75rem 0.85rem;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.eventCountValue {\n font-size: 1.05rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n margin-bottom: 0.35rem;\n}\n\n.eventCountValue[data-tone=\"amber\"][data-emphasize=\"true\"] {\n color: var(--ss-amber);\n}\n\n.eventCountValue[data-tone=\"success\"][data-emphasize=\"true\"] {\n color: var(--ss-success);\n}\n\n.eventCountValue[data-tone=\"error\"][data-emphasize=\"true\"] {\n color: var(--ss-error);\n}\n\n.dataActions {\n display: flex;\n gap: 0.4rem;\n}\n\n.dataButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.4rem 0.8rem;\n background-color: transparent;\n color: var(--ss-teal);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.dataStatusSuccess {\n font-size: 0.75rem;\n color: var(--ss-success);\n}\n\n.dataStatusError {\n font-size: 0.75rem;\n color: var(--ss-error);\n word-break: break-word;\n}\n\n.dangerZone {\n margin-top: auto;\n border-radius: 10px;\n border: 1px solid var(--ss-error-border);\n padding: 0.75rem 1rem;\n background: var(--ss-error-bg);\n}\n\n.dangerZoneTitle {\n font-size: 0.65rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-error);\n margin-bottom: 0.5rem;\n}\n\n.dangerZoneRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n}\n\n.dangerZoneDesc {\n font-size: 0.75rem;\n color: var(--ss-text-muted);\n line-height: 1.5;\n}\n\n.dangerZoneActions {\n display: flex;\n gap: 0.4rem;\n flex-shrink: 0;\n}\n\n.resetButton {\n flex-shrink: 0;\n border: 1px solid var(--ss-error-border);\n border-radius: 7px;\n padding: 0.35rem 0.75rem;\n background-color: transparent;\n color: var(--ss-error);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.resetCancelButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.35rem 0.65rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.resetConfirmButton {\n border: none;\n border-radius: 7px;\n padding: 0.35rem 0.75rem;\n background-color: var(--ss-error);\n color: #0e1015;\n font-size: 0.78rem;\n font-weight: 700;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.queryRunnerLayout {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n height: 100%;\n}\n\n.queryToolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.targetToggle {\n display: flex;\n gap: 0;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-card);\n}\n\n.queryToolbarRight {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.noInstanceWarning {\n font-size: 0.75rem;\n color: var(--ss-amber);\n font-weight: 500;\n}\n\n.shortcutHint {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n padding: 0.2rem 0.5rem;\n border-radius: 5px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.editorWrapper {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-input);\n}\n\n.textarea {\n width: 100%;\n min-height: 9rem;\n resize: vertical;\n border: none;\n padding: 0.85rem 1rem;\n background-color: transparent;\n color: var(--ss-text);\n font-size: 0.875rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n line-height: 1.6;\n outline: none;\n box-sizing: border-box;\n}\n\n.helperText {\n font-size: 0.75rem;\n line-height: 1.5;\n color: var(--ss-text-muted);\n}\n\n.resultPanel {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-panel);\n}\n\n.errorPanel {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.85rem 1rem;\n border-radius: 10px;\n border: 1px solid var(--ss-error-border);\n background: var(--ss-error-bg);\n}\n\n.resultHeader {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.6rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.successBadge {\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n border-radius: 5px;\n padding: 0.15rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.errorBadge {\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--ss-error);\n background-color: var(--ss-error-bg);\n border-radius: 5px;\n padding: 0.15rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.resultMeta {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n}\n\n.resultEmpty {\n padding: 1.5rem;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n text-align: center;\n}\n\n.resultRaw {\n margin: 0;\n padding: 0.85rem 1rem;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 0.8rem;\n line-height: 1.5;\n color: var(--ss-text);\n font-family: ui-monospace, monospace;\n}\n\n.errorMessage {\n margin: 0;\n font-size: 0.82rem;\n line-height: 1.6;\n color: var(--ss-error);\n font-family: ui-monospace, monospace;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.tableWrapper {\n overflow-x: auto;\n max-height: 320px;\n overflow-y: auto;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n}\n\n.table tbody tr:nth-child(even) {\n background: var(--ss-teal-glow);\n}\n\n.th {\n padding: 0.5rem 0.85rem;\n text-align: left;\n font-weight: 600;\n font-size: 0.7rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n white-space: nowrap;\n position: sticky;\n top: 0;\n}\n\n.thRowNum {\n padding: 0.5rem 0.85rem;\n text-align: right;\n font-weight: 600;\n font-size: 0.7rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n white-space: nowrap;\n position: sticky;\n top: 0;\n opacity: 0.5;\n width: 2.5rem;\n}\n\n.td {\n padding: 0.45rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n color: var(--ss-text);\n white-space: nowrap;\n max-width: 300px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tdRowNum {\n padding: 0.45rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n color: var(--ss-text-muted);\n white-space: nowrap;\n max-width: 300px;\n overflow: hidden;\n text-overflow: ellipsis;\n opacity: 0.5;\n text-align: right;\n user-select: none;\n}\n\n.nullValue {\n color: var(--ss-text-muted);\n font-style: italic;\n opacity: 0.6;\n}\n\n.jsonValue {\n color: var(--ss-text-dim);\n}\n\n.tabButton {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n border: none;\n border-radius: 7px;\n padding: 0.6rem 0.75rem;\n background: transparent;\n color: var(--ss-text-dim);\n font-size: 0.82rem;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n transition: background 0.15s;\n border-left: 2px solid transparent;\n}\n\n.tabButton[data-active=\"true\"] {\n background: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-weight: 700;\n border-left: 2px solid var(--ss-teal);\n}\n\n.targetButton {\n border: none;\n border-right: 1px solid var(--ss-border);\n padding: 0.45rem 0.85rem;\n background: transparent;\n color: var(--ss-text-muted);\n font-size: 0.78rem;\n font-weight: 500;\n cursor: pointer;\n font-family: ui-monospace, monospace;\n transition: background 0.1s;\n white-space: nowrap;\n}\n\n.targetButton[data-active=\"true\"] {\n background: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-weight: 700;\n}\n\n.runButton {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n border: none;\n border-radius: 7px;\n padding: 0.45rem 0.9rem;\n background: var(--ss-bg-card);\n color: var(--ss-text-muted);\n font-size: 0.82rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n cursor: not-allowed;\n opacity: 1;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.runButton[data-enabled=\"true\"] {\n background: var(--ss-teal);\n color: #0e1015;\n cursor: pointer;\n}\n\n.runButton[data-running=\"true\"] {\n opacity: 0.75;\n}\n\n.runningDot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: currentColor;\n}\n\n.schemaLayout {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.schemaSection {\n display: flex;\n flex-direction: column;\n gap: 0.65rem;\n}\n\n.schemaSectionHeader {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.schemaSectionTitle {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n}\n\n.schemaBadge {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n border-radius: 4px;\n padding: 0.1rem 0.4rem;\n font-family: ui-monospace, monospace;\n}\n\n.schemaVersionChip {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.1rem 0.5rem;\n}\n\n.schemaTableGrid {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n}\n\n.schemaColHeader {\n padding: 0.5rem 0.85rem;\n font-size: 0.68rem;\n font-weight: 700;\n letter-spacing: 0.07em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-right: 1px solid var(--ss-border);\n}\n\n.schemaStatusCell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.6rem 0.5rem;\n}\n\n.schemaActiveTag {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n border-radius: 4px;\n padding: 0.15rem 0.45rem;\n font-family: ui-monospace, monospace;\n}\n\n.schemaEmpty {\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.schemaTableList {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.schemaTableCard {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n overflow: hidden;\n}\n\n.schemaTableCardHeader {\n display: flex;\n flex-direction: column;\n gap: 0.45rem;\n padding: 0.75rem 0.85rem 0.7rem;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.schemaTableCardTitleRow {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.schemaTableCardName {\n font-size: 0.92rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n}\n\n.schemaTableCardDescription {\n margin: 0;\n font-size: 0.78rem;\n line-height: 1.45;\n color: var(--ss-text-dim);\n}\n\n.schemaTableCardMeta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.schemaPolicyChip {\n font-size: 0.65rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n background: var(--ss-bg-input);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.12rem 0.4rem;\n}\n\n.schemaPolicyChip[data-tone=\"warn\"] {\n color: var(--ss-amber);\n background: rgba(251, 191, 36, 0.08);\n border-color: rgba(251, 191, 36, 0.25);\n}\n\n.schemaColumnGrid {\n display: flex;\n flex-direction: column;\n overflow-x: auto;\n}\n\n.schemaColumnRow {\n display: grid;\n grid-template-columns: minmax(6.5rem, 0.7fr) minmax(8rem, 1fr) minmax(7.5rem, 0.9fr) minmax(0, 1.8fr);\n min-width: 36rem;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.schemaColumnRow:last-child {\n border-bottom: none;\n}\n\n.schemaColumnRow[data-system=\"true\"] {\n opacity: 0.62;\n}\n\n.schemaColumnHeaderRow {\n background: var(--ss-bg-panel);\n}\n\n.schemaColumnHeaderRow .schemaColHeader:last-child {\n border-right: none;\n}\n\n.schemaColumnName,\n.schemaColumnType,\n.schemaColumnFlags,\n.schemaColumnDescription {\n padding: 0.5rem 0.85rem;\n font-size: 0.76rem;\n border-right: 1px solid var(--ss-border);\n min-width: 0;\n}\n\n.schemaColumnDescription {\n border-right: none;\n color: var(--ss-text-dim);\n overflow-wrap: anywhere;\n}\n\n.schemaColumnName {\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n font-weight: 600;\n}\n\n.schemaColumnType {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-teal);\n}\n\n.schemaColumnTypeDetail {\n font-size: 0.65rem;\n color: var(--ss-text-muted);\n font-weight: 400;\n overflow-wrap: anywhere;\n}\n\n.schemaColumnFlags {\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n overflow-wrap: anywhere;\n}\n\n.liveQueryHeaderRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 220px 110px;\n gap: 0;\n background-color: var(--ss-bg-card);\n border-bottom: 1px solid var(--ss-border);\n}\n\n.liveQueryRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 220px 110px;\n gap: 0;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.liveQuerySql {\n padding: 0.6rem 0.85rem;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n border-right: 1px solid var(--ss-border);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.liveQueryParameters {\n padding: 0.6rem 0.85rem;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-dim);\n border-right: 1px solid var(--ss-border);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.liveQueryIdleTag {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.15rem 0.45rem;\n font-family: ui-monospace, monospace;\n}\n\n.eventLogLayout {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n height: 100%;\n}\n\n.eventLogToolbar {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: wrap;\n flex-shrink: 0;\n}\n\n.eventLogFilterSelect {\n border-radius: 7px;\n border: 1px solid var(--ss-border);\n padding: 0.35rem 0.6rem;\n background-color: var(--ss-bg-card);\n color: var(--ss-text);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n}\n\n.eventLogCount {\n margin-left: auto;\n font-size: 0.72rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n}\n\n.eventLogEmpty {\n padding: 2rem;\n text-align: center;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.eventLogList {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n overflow-y: auto;\n flex: 1;\n}\n\n.eventRow {\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.eventRow[data-expanded=\"true\"] {\n border: 1px solid #2dd4bf40;\n background: var(--ss-teal-glow);\n}\n\n.eventRowHeader {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n background: transparent;\n border: none;\n cursor: pointer;\n text-align: left;\n flex-wrap: wrap;\n}\n\n.eventSyncId {\n font-size: 0.7rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n min-width: 3.5rem;\n}\n\n.eventDataset {\n font-size: 0.8rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n font-weight: 600;\n}\n\n.eventItemId {\n font-size: 0.75rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.eventTimestamp {\n font-size: 0.7rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n margin-left: auto;\n}\n\n.eventChevron {\n font-size: 0.6rem;\n color: var(--ss-text-muted);\n margin-left: 0.25rem;\n}\n\n.eventPayload {\n border-top: 1px solid var(--ss-border);\n padding: 0.6rem 0.75rem;\n}\n\n.eventPayloadMeta {\n display: flex;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n}\n\n.eventMetaItem {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n}\n\n.eventPayloadPre {\n margin: 0;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.loadMoreButton {\n width: 100%;\n border: 1px solid var(--ss-border);\n border-radius: 8px;\n padding: 0.6rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.eventBadge {\n font-size: 0.65rem;\n font-weight: 700;\n border-radius: 4px;\n padding: 0.1rem 0.4rem;\n font-family: ui-monospace, monospace;\n white-space: nowrap;\n}\n\n.eventBadge[data-variant=\"create\"] {\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n}\n\n.eventBadge[data-variant=\"update\"] {\n color: #a78bfa;\n background-color: rgba(167, 139, 250, 0.12);\n}\n\n.eventBadge[data-variant=\"delete\"] {\n color: var(--ss-error);\n background-color: rgba(248, 113, 113, 0.12);\n}\n\n.eventBadge[data-variant=\"own\"],\n.eventBadge[data-variant=\"applied\"] {\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n}\n\n.eventBadge[data-variant=\"remote\"],\n.eventBadge[data-variant=\"pending\"] {\n color: var(--ss-amber);\n background-color: rgba(251, 191, 36, 0.1);\n}\n\n.eventBadge[data-variant=\"local\"] {\n color: var(--ss-text-dim);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n}\n\n.eventBadge[data-variant=\"failed\"] {\n color: var(--ss-error);\n background-color: var(--ss-error-bg);\n}\n\n.eventBadge[data-variant=\"skipped\"] {\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n}\n\n@media (max-width: 640px) {\n .overlay {\n padding: 0;\n }\n\n .dialog {\n width: 100%;\n height: 100%;\n border: none;\n border-radius: 0;\n }\n\n .header {\n flex-wrap: wrap;\n gap: 0.5rem;\n padding: 0.6rem 0.75rem;\n padding-top: max(0.6rem, env(safe-area-inset-top));\n }\n\n .headerRight {\n flex: 1;\n justify-content: flex-end;\n min-width: 0;\n }\n\n .instancePickerLabel {\n min-width: 0;\n }\n\n .instancePickerSelect {\n min-width: 0;\n max-width: 100%;\n }\n\n .instanceCountBadge {\n display: none;\n }\n\n .closeButton {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n }\n\n .contentLayout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .sidebar {\n padding: 0.4rem 0.5rem;\n border-right: none;\n border-bottom: 1px solid var(--ss-border);\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .nav {\n flex-direction: row;\n margin-bottom: 0;\n }\n\n .tabButton {\n width: auto;\n flex-shrink: 0;\n white-space: nowrap;\n border-left: none;\n border-bottom: 2px solid transparent;\n }\n\n .tabButton[data-active=\"true\"] {\n border-left: none;\n border-bottom: 2px solid var(--ss-teal);\n }\n\n .sidebarInfo {\n display: none;\n }\n\n .mainPane {\n padding: 0.75rem;\n padding-bottom: max(0.75rem, env(safe-area-inset-bottom));\n }\n\n .liveQueryHeaderRow,\n .liveQueryRow {\n grid-template-columns: minmax(0, 1fr) minmax(0, 0.6fr) 6.5rem;\n }\n\n .liveQueryHeaderRow .schemaColHeader,\n .liveQuerySql,\n .liveQueryParameters {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n }\n\n .liveQueryHeaderRow .schemaColHeader {\n letter-spacing: 0.02em;\n }\n}\n\n@media (hover: none) {\n .hideLauncherButton {\n display: none;\n }\n}\n","import { type ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport cssText from \"./devtools.css?inline\";\n\nexport function ShadowRoot({ children, className }: { children: ReactNode; className?: string }) {\n const hostRef = useRef<HTMLDivElement>(null);\n const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);\n\n useLayoutEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n setShadowRoot(host.shadowRoot ?? host.attachShadow({ mode: \"open\" }));\n }, []);\n\n return (\n <div ref={hostRef} className={className}>\n {shadowRoot\n ? createPortal(\n <>\n <style>{cssText}</style>\n {children}\n </>,\n shadowRoot,\n )\n : null}\n </div>\n );\n}\n","import type { ColumnMeta, SharedLiveQuerySnapshot, SyncedDbExport } from \"@sqlite-sync/core\";\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n getOrCreateSQLiteSyncDevtoolsRegistry,\n type SQLiteSyncDevtoolsInstance,\n type SQLiteSyncDevtoolsSnapshot,\n} from \"./devtools-registry\";\nimport { ShadowRoot } from \"./shadow-root\";\n\nexport type SQLiteSyncDevtoolsProps = {\n className?: string;\n /** Render the floating launcher button. Set to `false` to open the dialog only via `open`. Defaults to `true`. */\n launcher?: boolean;\n /** Hide the floating launcher. Omit to let the user toggle it with Ctrl+Alt+S (⌘⌥S on macOS). */\n hidden?: boolean;\n onHiddenChange?: (hidden: boolean) => void;\n /** Control whether the devtools dialog is open. Omit to let the launcher manage it. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\ntype DevtoolsTab = \"overview\" | \"schema\" | \"live-queries\" | \"event-log\" | \"query-runner\";\ntype QueryTarget = \"memory\" | \"worker\";\n\ntype QueryState =\n | {\n status: \"idle\";\n }\n | {\n status: \"running\";\n }\n | {\n status: \"success\";\n output: {\n target: QueryTarget;\n sql: string;\n rowCount: number;\n durationMs: number;\n rows: unknown[];\n };\n }\n | {\n status: \"error\";\n error: {\n target: QueryTarget;\n sql: string;\n message: string;\n };\n };\n\nconst TRIGGER_POSITION_STORAGE_KEY = \"sqlite-sync-devtools.trigger-position\";\nconst TRIGGER_HIDDEN_STORAGE_KEY = \"sqlite-sync-devtools.trigger-hidden\";\nconst DRAG_THRESHOLD_PX = 4;\nconst VIEWPORT_MARGIN_PX = 8;\nconst IS_APPLE_PLATFORM = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\nconst TOGGLE_LAUNCHER_HINT = IS_APPLE_PLATFORM ? \"⌘⌥S\" : \"Ctrl+Alt+S\";\n\ntype TriggerPosition = { x: number; y: number };\n\nfunction readStoredTriggerPosition(): TriggerPosition | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(TRIGGER_POSITION_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<TriggerPosition>;\n if (typeof parsed.x === \"number\" && typeof parsed.y === \"number\") {\n return { x: parsed.x, y: parsed.y };\n }\n } catch {}\n return null;\n}\n\nfunction clampTriggerPosition(position: TriggerPosition, button: HTMLElement): TriggerPosition {\n const maxX = window.innerWidth - button.offsetWidth - VIEWPORT_MARGIN_PX;\n const maxY = window.innerHeight - button.offsetHeight - VIEWPORT_MARGIN_PX;\n return {\n x: Math.max(VIEWPORT_MARGIN_PX, Math.min(position.x, maxX)),\n y: Math.max(VIEWPORT_MARGIN_PX, Math.min(position.y, maxY)),\n };\n}\n\nfunction useDraggableTrigger() {\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [position, setPosition] = useState<TriggerPosition | null>(readStoredTriggerPosition);\n const dragRef = useRef<{\n pointerId: number;\n startX: number;\n startY: number;\n offsetX: number;\n offsetY: number;\n moved: boolean;\n } | null>(null);\n // pointerup clears dragRef before the click event fires, so the moved flag is\n // stashed here to suppress the click that a drag gesture would otherwise emit.\n const suppressClickRef = useRef(false);\n\n const onPointerDown = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const button = buttonRef.current;\n if (!button || event.button !== 0) return;\n suppressClickRef.current = false;\n const rect = button.getBoundingClientRect();\n dragRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n offsetX: event.clientX - rect.left,\n offsetY: event.clientY - rect.top,\n moved: false,\n };\n button.setPointerCapture(event.pointerId);\n }, []);\n\n const clampToViewport = useCallback(() => {\n const button = buttonRef.current;\n if (!button) return;\n setPosition((current) => {\n if (!current) return current;\n const next = clampTriggerPosition(current, button);\n return next.x === current.x && next.y === current.y ? current : next;\n });\n }, []);\n\n const setButtonRef = useCallback(\n (button: HTMLButtonElement | null) => {\n buttonRef.current = button;\n clampToViewport();\n },\n [clampToViewport],\n );\n\n useEffect(() => {\n window.addEventListener(\"resize\", clampToViewport);\n return () => window.removeEventListener(\"resize\", clampToViewport);\n }, [clampToViewport]);\n\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const drag = dragRef.current;\n const button = buttonRef.current;\n if (!drag || !button || drag.pointerId !== event.pointerId) return;\n if (!drag.moved && Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) < DRAG_THRESHOLD_PX) {\n return;\n }\n drag.moved = true;\n setPosition(clampTriggerPosition({ x: event.clientX - drag.offsetX, y: event.clientY - drag.offsetY }, button));\n }, []);\n\n const endDrag = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== event.pointerId) return;\n dragRef.current = null;\n buttonRef.current?.releasePointerCapture(event.pointerId);\n if (!drag.moved) return;\n suppressClickRef.current = true;\n setPosition((current) => {\n if (current && typeof window !== \"undefined\") {\n try {\n window.localStorage.setItem(TRIGGER_POSITION_STORAGE_KEY, JSON.stringify(current));\n } catch {}\n }\n return current;\n });\n }, []);\n\n const consumeDragClick = useCallback(() => {\n if (!suppressClickRef.current) return false;\n suppressClickRef.current = false;\n return true;\n }, []);\n\n const positionStyle: CSSProperties = position\n ? { left: position.x, top: position.y, right: \"auto\", bottom: \"auto\" }\n : {};\n\n return {\n buttonRef: setButtonRef,\n positionStyle,\n triggerHandlers: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag },\n consumeDragClick,\n };\n}\n\nfunction readStoredTriggerHidden(): boolean {\n if (typeof window === \"undefined\") return false;\n try {\n return window.localStorage.getItem(TRIGGER_HIDDEN_STORAGE_KEY) === \"1\";\n } catch {\n return false;\n }\n}\n\nfunction isToggleLauncherShortcut(event: KeyboardEvent): boolean {\n // Option/Alt remaps event.key (Option+S is \"ß\" on US Mac), so match the physical key.\n if (event.shiftKey || !event.altKey || event.code !== \"KeyS\") return false;\n return event.ctrlKey || event.metaKey;\n}\n\nfunction useLauncherVisibility({\n launcher,\n hidden: hiddenProp,\n onHiddenChange,\n onHide,\n}: Pick<SQLiteSyncDevtoolsProps, \"hidden\" | \"onHiddenChange\"> & { launcher: boolean; onHide: () => void }) {\n const isControlled = hiddenProp !== undefined;\n const [uncontrolledHidden, setUncontrolledHidden] = useState(readStoredTriggerHidden);\n const hidden = !launcher || (isControlled ? hiddenProp : uncontrolledHidden);\n const canToggle = launcher && (!isControlled || onHiddenChange !== undefined);\n\n const setHidden = useCallback(\n (next: boolean) => {\n if (next) onHide();\n if (isControlled) {\n onHiddenChange?.(next);\n return;\n }\n setUncontrolledHidden(next);\n try {\n window.localStorage.setItem(TRIGGER_HIDDEN_STORAGE_KEY, next ? \"1\" : \"0\");\n } catch {}\n },\n [isControlled, onHiddenChange, onHide],\n );\n\n useEffect(() => {\n if (!canToggle) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!isToggleLauncherShortcut(event)) return;\n event.preventDefault();\n setHidden(!hidden);\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [canToggle, hidden, setHidden]);\n\n return { hidden, setHidden, canToggle };\n}\n\nfunction useOpenState({ open: openProp, onOpenChange }: Pick<SQLiteSyncDevtoolsProps, \"open\" | \"onOpenChange\">) {\n const isControlled = openProp !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const isOpen = isControlled ? openProp : uncontrolledOpen;\n\n const setIsOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n return { isOpen, setIsOpen };\n}\n\nexport function SQLiteSyncDevtools({\n className,\n launcher = true,\n hidden: hiddenProp,\n onHiddenChange,\n open: openProp,\n onOpenChange,\n}: SQLiteSyncDevtoolsProps) {\n const registry = getOrCreateSQLiteSyncDevtoolsRegistry();\n const snapshot = useSyncExternalStore(registry.subscribe, registry.getSnapshot, getEmptySnapshot);\n const instances = snapshot.instances;\n\n const { buttonRef, positionStyle, triggerHandlers, consumeDragClick } = useDraggableTrigger();\n const { isOpen, setIsOpen } = useOpenState({ open: openProp, onOpenChange });\n const closeDialog = useCallback(() => setIsOpen(false), [setIsOpen]);\n const { hidden, setHidden, canToggle } = useLauncherVisibility({\n launcher,\n hidden: hiddenProp,\n onHiddenChange,\n onHide: closeDialog,\n });\n\n const [activeTab, setActiveTab] = useState<DevtoolsTab>(\"overview\");\n const [selectedInstanceId, setSelectedInstanceId] = useState<string>(\"\");\n const [queryTarget, setQueryTarget] = useState<QueryTarget>(\"memory\");\n const [query, setQuery] = useState(\"\");\n const [queryState, setQueryState] = useState<QueryState>({\n status: \"idle\",\n });\n\n useEffect(() => {\n if (!isOpen) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n closeDialog();\n }\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [isOpen, closeDialog]);\n\n useEffect(() => {\n if (instances.length === 0) {\n setSelectedInstanceId(\"\");\n return;\n }\n\n if (instances.some((instance) => instance.instanceId === selectedInstanceId)) {\n return;\n }\n\n setSelectedInstanceId(instances[0]?.instanceId ?? \"\");\n }, [instances, selectedInstanceId]);\n\n const dbIdCounts = useMemo(() => {\n const counts = new Map<string, number>();\n\n for (const instance of instances) {\n counts.set(instance.dbId, (counts.get(instance.dbId) ?? 0) + 1);\n }\n\n return counts;\n }, [instances]);\n\n const selectedInstance = useMemo(() => {\n return instances.find((instance) => instance.instanceId === selectedInstanceId) ?? null;\n }, [instances, selectedInstanceId]);\n\n const canRunQuery = selectedInstance !== null && query.trim().length > 0 && queryState.status !== \"running\";\n\n const runQuery = async () => {\n if (!selectedInstance) return;\n\n let normalizedQuery = query.trim();\n\n try {\n normalizedQuery = normalizeSingleStatement(query);\n const statementKind = getStatementKind(normalizedQuery);\n\n if (queryTarget === \"worker\") {\n if (!isWorkerReadOnlyStatement(statementKind)) {\n throw new Error(\"Worker DB devtools only allows read-only SQL: SELECT, PRAGMA.\");\n }\n } else {\n const touchedTables = selectedInstance.instance._internal.getMemoryQueryTables(normalizedQuery);\n const writtenTables = touchedTables.filter((table) => table.isWrite).map((table) => table.name);\n const allowedTables = new Set(selectedInstance.instance._internal.crdtTableNames);\n\n const invalidTables = writtenTables.filter((table) => !allowedTables.has(table));\n if (invalidTables.length > 0) {\n throw new Error(\n `Memory DB writes are only allowed for CRDT tables. Rejected tables: ${invalidTables.join(\", \")}`,\n );\n }\n }\n\n setQueryState({ status: \"running\" });\n const startedAt = performance.now();\n\n const result =\n queryTarget === \"memory\"\n ? selectedInstance.instance.db.execute(normalizedQuery)\n : await selectedInstance.instance._internal.executeAsync({\n sql: normalizedQuery,\n parameters: [],\n });\n\n setQueryState({\n status: \"success\",\n output: {\n target: queryTarget,\n sql: normalizedQuery,\n rowCount: result.rows.length,\n durationMs: Number((performance.now() - startedAt).toFixed(2)),\n rows: result.rows,\n },\n });\n } catch (error) {\n setQueryState({\n status: \"error\",\n error: {\n target: queryTarget,\n sql: normalizedQuery,\n message: error instanceof Error ? error.message : String(error),\n },\n });\n }\n };\n\n return (\n <ShadowRoot className={className}>\n {hidden ? null : (\n <div className=\"floatingRoot\">\n <button\n ref={buttonRef}\n type=\"button\"\n className=\"triggerButton\"\n style={positionStyle}\n onClick={() => {\n if (consumeDragClick()) return;\n setIsOpen(true);\n }}\n title={`SQLite Sync Devtools (${TOGGLE_LAUNCHER_HINT} to hide)`}\n {...triggerHandlers}\n >\n <span className=\"triggerIcon\">◈</span>\n <span className=\"triggerCount\">{instances.length}</span>\n </button>\n </div>\n )}\n\n {isOpen ? (\n <div className=\"overlay\" onClick={closeDialog}>\n <section\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"SQLite Sync devtools\"\n className=\"dialog\"\n onClick={(event) => event.stopPropagation()}\n >\n {/* Dialog header */}\n <div className=\"header\">\n <div className=\"headerLeft\">\n <span className=\"headerLogo\">◈</span>\n <div>\n <div className=\"eyebrow\">sqlite-sync</div>\n <h2 className=\"title\">Devtools</h2>\n </div>\n </div>\n\n <div className=\"headerRight\">\n {instances.length > 0 && (\n <label className=\"instancePickerLabel\">\n <span className=\"instancePickerText\">DB</span>\n <select\n value={selectedInstanceId}\n onChange={(event) => setSelectedInstanceId(event.target.value)}\n className=\"instancePickerSelect\"\n >\n {instances.map((instance) => (\n <option key={instance.instanceId} value={instance.instanceId}>\n {formatInstanceLabel(instance.dbId, instance.instanceId, dbIdCounts.get(instance.dbId) ?? 0)}\n </option>\n ))}\n </select>\n </label>\n )}\n <span className=\"instanceCountBadge\">\n {instances.length} instance{instances.length !== 1 ? \"s\" : \"\"}\n </span>\n {canToggle && (\n <button\n type=\"button\"\n className=\"hideLauncherButton\"\n onClick={() => setHidden(true)}\n title={`Hide launcher (${TOGGLE_LAUNCHER_HINT} to show again)`}\n >\n Hide\n </button>\n )}\n <button type=\"button\" className=\"closeButton\" onClick={closeDialog} aria-label=\"Close\">\n ✕\n </button>\n </div>\n </div>\n\n {instances.length === 0 ? (\n <div className=\"emptyState\">\n <div className=\"emptyStateIcon\">◈</div>\n <p className=\"emptyStateText\">No SQLite Sync database instances registered.</p>\n <p className=\"emptyStateSubtext\">\n Call <code className=\"inlineCode\">registerDevtools(db)</code> in your app to get started.\n </p>\n </div>\n ) : (\n <div className=\"contentLayout\">\n {/* Sidebar nav */}\n <aside className=\"sidebar\">\n <nav className=\"nav\">\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"overview\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"overview\")}\n >\n <span className=\"navIcon\">▦</span>\n Overview\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"schema\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"schema\")}\n >\n <span className=\"navIcon\">⬡</span>\n Schema\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"live-queries\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"live-queries\")}\n >\n <span className=\"navIcon\">◉</span>\n Live Queries\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"event-log\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"event-log\")}\n >\n <span className=\"navIcon\">≡</span>\n Event Log\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"query-runner\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"query-runner\")}\n >\n <span className=\"navIcon\">▶</span>\n Query Runner\n </button>\n </nav>\n\n {selectedInstance && (\n <div className=\"sidebarInfo\">\n <div className=\"sidebarInfoLabel\">Active instance</div>\n <div className=\"sidebarInfoValue\">\n {formatInstanceLabel(\n selectedInstance.dbId,\n selectedInstance.instanceId,\n dbIdCounts.get(selectedInstance.dbId) ?? 0,\n )}\n </div>\n <div className=\"sidebarInfoSub\">id: {selectedInstance.instanceId.slice(0, 12)}…</div>\n </div>\n )}\n </aside>\n\n {/* Main pane */}\n <div className=\"mainPane\">\n {activeTab === \"overview\" ? (\n <OverviewTab selectedInstance={selectedInstance} dbIdCounts={dbIdCounts} />\n ) : activeTab === \"schema\" ? (\n <SchemaTab selectedInstance={selectedInstance} />\n ) : activeTab === \"live-queries\" ? (\n <LiveQueriesTab selectedInstance={selectedInstance} />\n ) : activeTab === \"event-log\" ? (\n <EventLogTab selectedInstance={selectedInstance} />\n ) : (\n <QueryRunnerTab\n selectedInstance={selectedInstance}\n queryTarget={queryTarget}\n setQueryTarget={setQueryTarget}\n query={query}\n setQuery={setQuery}\n queryState={queryState}\n canRunQuery={canRunQuery}\n runQuery={runQuery}\n />\n )}\n </div>\n </div>\n )}\n </section>\n </div>\n ) : null}\n </ShadowRoot>\n );\n}\n\nconst EVENT_HLC_ACCUMULATOR_KV_KEY = \"crdt.consistency.event_hlc_sum.v2\";\nconst EVENT_HLC_ACCUMULATOR_QUERY = `SELECT value FROM \"worker\".\"kv\" WHERE key = '${EVENT_HLC_ACCUMULATOR_KV_KEY}'`;\nconst EVENT_STATUS_COUNTS_QUERY = `SELECT status, COUNT(*) AS count FROM \"worker\".\"crdt_events\" GROUP BY status`;\nconst MEMORY_DB_SIZE_QUERY =\n \"SELECT (SELECT page_count FROM pragma_page_count()) * (SELECT page_size FROM pragma_page_size()) AS bytes\";\n// Persisted main file plus the attached worker schema (event log, kv).\nconst WORKER_DB_SIZE_QUERY = `SELECT\n (SELECT page_count FROM pragma_page_count('main')) * (SELECT page_size FROM pragma_page_size('main'))\n + (SELECT page_count FROM pragma_page_count('worker')) * (SELECT page_size FROM pragma_page_size('worker'))\n AS bytes`;\n\ntype EventStatus = \"pending\" | \"applied\" | \"failed\" | \"deduped\";\ntype EventStatusCounts = { total: number } & Record<EventStatus, number>;\n\nconst EVENT_STATUS_META: Record<EventStatus, { label: string; tone: \"amber\" | \"success\" | \"error\" | \"muted\" }> = {\n pending: { label: \"Pending\", tone: \"amber\" },\n applied: { label: \"Applied\", tone: \"success\" },\n failed: { label: \"Failed\", tone: \"error\" },\n deduped: { label: \"Deduped\", tone: \"muted\" },\n};\n\nfunction isEventStatus(value: unknown): value is EventStatus {\n return value === \"pending\" || value === \"applied\" || value === \"failed\" || value === \"deduped\";\n}\n\nfunction emptyEventStatusCounts(): EventStatusCounts {\n return { total: 0, pending: 0, applied: 0, failed: 0, deduped: 0 };\n}\n\nfunction parseEventStatusCounts(rows: readonly unknown[]): EventStatusCounts {\n const counts = emptyEventStatusCounts();\n\n for (const row of rows) {\n if (typeof row !== \"object\" || row === null || !(\"status\" in row) || !(\"count\" in row)) {\n continue;\n }\n const { status, count } = row;\n if (!isEventStatus(status)) continue;\n const n = typeof count === \"number\" ? count : Number(count);\n if (!Number.isFinite(n)) continue;\n counts[status] = n;\n counts.total += n;\n }\n\n return counts;\n}\n\nfunction readCount(rows: readonly unknown[]): number {\n const row = rows[0];\n if (typeof row !== \"object\" || row === null || !(\"count\" in row)) return 0;\n const n = typeof row.count === \"number\" ? row.count : Number(row.count);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction readBytes(rows: readonly unknown[]): number | null {\n const row = rows[0];\n if (typeof row !== \"object\" || row === null || !(\"bytes\" in row)) return null;\n const n = typeof row.bytes === \"number\" ? row.bytes : Number(row.bytes);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction formatByteSize(bytes: number): { label: string; exact: string } {\n const exact = `${bytes.toLocaleString(\"en-US\")} B`;\n if (bytes < 1024) return { label: exact, exact };\n\n const units = [\"KB\", \"MB\", \"GB\", \"TB\"] as const;\n let value = bytes / 1024;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n const decimals = value >= 100 ? 0 : value >= 10 ? 1 : 2;\n return { label: `${Number(value.toFixed(decimals))} ${units[unitIndex]}`, exact };\n}\n\nfunction OverviewTab({\n selectedInstance,\n dbIdCounts,\n}: {\n selectedInstance: SQLiteSyncDevtoolsInstance | null;\n dbIdCounts: Map<string, number>;\n}) {\n const [eventHlcAccumulator, setEventHlcAccumulator] = useState<string | null>(null);\n const [accumulatorError, setAccumulatorError] = useState<string | null>(null);\n const [isAccumulatorLoading, setIsAccumulatorLoading] = useState(false);\n const [eventCounts, setEventCounts] = useState<EventStatusCounts | null>(null);\n const [eventCountsError, setEventCountsError] = useState<string | null>(null);\n const [isEventCountsLoading, setIsEventCountsLoading] = useState(false);\n const [memoryBytes, setMemoryBytes] = useState<number | null>(null);\n const [memorySizeError, setMemorySizeError] = useState<string | null>(null);\n const [workerBytes, setWorkerBytes] = useState<number | null>(null);\n const [workerSizeError, setWorkerSizeError] = useState<string | null>(null);\n const [isSizeLoading, setIsSizeLoading] = useState(false);\n\n const refreshEventHlcAccumulator = useCallback(async () => {\n if (!selectedInstance) return;\n setIsAccumulatorLoading(true);\n setAccumulatorError(null);\n try {\n const result = await selectedInstance.instance._internal.executeAsync({\n sql: EVENT_HLC_ACCUMULATOR_QUERY,\n parameters: [],\n });\n const row = result.rows[0];\n const value =\n typeof row === \"object\" && row !== null && \"value\" in row && typeof row.value === \"string\" ? row.value : \"\";\n setEventHlcAccumulator(value);\n } catch (error) {\n setAccumulatorError(error instanceof Error ? error.message : String(error));\n setEventHlcAccumulator(null);\n } finally {\n setIsAccumulatorLoading(false);\n }\n }, [selectedInstance]);\n\n const refreshEventCounts = useCallback(async () => {\n if (!selectedInstance) return;\n setIsEventCountsLoading(true);\n setEventCountsError(null);\n try {\n const result = await selectedInstance.instance._internal.executeAsync({\n sql: EVENT_STATUS_COUNTS_QUERY,\n parameters: [],\n });\n setEventCounts(parseEventStatusCounts(result.rows));\n } catch (error) {\n setEventCountsError(error instanceof Error ? error.message : String(error));\n setEventCounts(null);\n } finally {\n setIsEventCountsLoading(false);\n }\n }, [selectedInstance]);\n\n const refreshDbSizes = useCallback(async () => {\n if (!selectedInstance) return;\n setIsSizeLoading(true);\n setMemorySizeError(null);\n setWorkerSizeError(null);\n\n const memoryResult = Promise.resolve()\n .then(() => selectedInstance.instance.db.execute(MEMORY_DB_SIZE_QUERY))\n .then((result) => {\n const bytes = readBytes(result.rows);\n if (bytes === null) throw new Error(\"Memory DB did not return a size.\");\n return bytes;\n });\n const workerResult = selectedInstance.instance._internal\n .executeAsync({ sql: WORKER_DB_SIZE_QUERY, parameters: [] })\n .then((result) => {\n const bytes = readBytes(result.rows);\n if (bytes === null) throw new Error(\"Worker DB did not return a size.\");\n return bytes;\n });\n\n const [memorySettled, workerSettled] = await Promise.allSettled([memoryResult, workerResult]);\n if (memorySettled.status === \"fulfilled\") {\n setMemoryBytes(memorySettled.value);\n } else {\n setMemoryBytes(null);\n setMemorySizeError(\n memorySettled.reason instanceof Error ? memorySettled.reason.message : String(memorySettled.reason),\n );\n }\n if (workerSettled.status === \"fulfilled\") {\n setWorkerBytes(workerSettled.value);\n } else {\n setWorkerBytes(null);\n setWorkerSizeError(\n workerSettled.reason instanceof Error ? workerSettled.reason.message : String(workerSettled.reason),\n );\n }\n setIsSizeLoading(false);\n }, [selectedInstance]);\n\n useEffect(() => {\n setEventHlcAccumulator(null);\n setAccumulatorError(null);\n setEventCounts(null);\n setEventCountsError(null);\n setMemoryBytes(null);\n setMemorySizeError(null);\n setWorkerBytes(null);\n setWorkerSizeError(null);\n void refreshEventHlcAccumulator();\n void refreshEventCounts();\n void refreshDbSizes();\n }, [refreshEventHlcAccumulator, refreshEventCounts, refreshDbSizes]);\n\n if (!selectedInstance) return null;\n\n const label = formatInstanceLabel(\n selectedInstance.dbId,\n selectedInstance.instanceId,\n dbIdCounts.get(selectedInstance.dbId) ?? 0,\n );\n\n return (\n <div className=\"overviewLayout\">\n <div className=\"overviewCardsRow\">\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">Database</div>\n <div className=\"overviewCardValue\">{label}</div>\n </div>\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">Instance ID</div>\n <div className=\"overviewCardValue mono sm\">{selectedInstance.instanceId.slice(0, 16)}…</div>\n </div>\n <DbSizeCard label=\"Memory DB\" bytes={memoryBytes} error={memorySizeError} loading={isSizeLoading} />\n <DbSizeCard label=\"Worker DB\" bytes={workerBytes} error={workerSizeError} loading={isSizeLoading} />\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">CRDT Events</div>\n <div className=\"overviewCardValue\">\n {eventCountsError ? \"—\" : isEventCountsLoading && eventCounts === null ? \"…\" : (eventCounts?.total ?? 0)}\n </div>\n </div>\n </div>\n\n <div className=\"overviewSection\">\n <div className=\"overviewSectionHeader\">\n <div className=\"overviewSectionTitle\">CRDT events</div>\n <button\n type=\"button\"\n className=\"refreshButton\"\n disabled={isEventCountsLoading || isSizeLoading}\n title=\"Refresh event counts and DB sizes\"\n onClick={() => {\n void refreshEventCounts();\n void refreshDbSizes();\n }}\n >\n {isEventCountsLoading || isSizeLoading ? \"…\" : \"↻\"} Refresh\n </button>\n </div>\n {eventCountsError ? (\n <div className=\"overviewAccumulatorError\">{eventCountsError}</div>\n ) : (\n <div className=\"eventCountGrid\">\n {([\"pending\", \"applied\", \"failed\", \"deduped\"] satisfies EventStatus[]).map((status) => {\n const item = EVENT_STATUS_META[status];\n const value = eventCounts?.[status] ?? 0;\n return (\n <div key={status} className=\"eventCountCard\">\n <div\n className=\"eventCountValue\"\n data-tone={item.tone}\n data-emphasize={value > 0 ? \"true\" : undefined}\n >\n {isEventCountsLoading && eventCounts === null ? \"…\" : value}\n </div>\n <div className=\"overviewCardLabel\">{item.label}</div>\n </div>\n );\n })}\n </div>\n )}\n <div className=\"overviewEmpty\">Counts are remaining worker log rows after GC, not lifetime history.</div>\n </div>\n\n <div className=\"overviewSection\">\n <div className=\"overviewSectionHeader\">\n <div className=\"overviewSectionTitle\">Event HLC accumulator</div>\n <button\n type=\"button\"\n className=\"refreshButton\"\n disabled={isAccumulatorLoading}\n onClick={() => void refreshEventHlcAccumulator()}\n >\n {isAccumulatorLoading ? \"…\" : \"↻\"} Refresh\n </button>\n </div>\n <div className=\"overviewAccumulatorValue\">\n {accumulatorError ? (\n <span className=\"overviewAccumulatorError\">{accumulatorError}</span>\n ) : isAccumulatorLoading && eventHlcAccumulator === null ? (\n \"Loading…\"\n ) : eventHlcAccumulator === \"\" ? (\n <span className=\"overviewAccumulatorEmpty\">(empty)</span>\n ) : (\n eventHlcAccumulator\n )}\n </div>\n </div>\n\n <DataSection\n key={selectedInstance.instanceId}\n dbId={selectedInstance.dbId}\n instance={selectedInstance.instance}\n />\n\n <ResetSection dbId={selectedInstance.dbId} instance={selectedInstance.instance} />\n </div>\n );\n}\n\nfunction DbSizeCard({\n label,\n bytes,\n error,\n loading,\n}: {\n label: string;\n bytes: number | null;\n error: string | null;\n loading: boolean;\n}) {\n let value = \"…\";\n let sub: string | undefined;\n let title: string | undefined;\n\n if (error) {\n value = \"—\";\n title = error;\n } else if (bytes !== null) {\n const formatted = formatByteSize(bytes);\n value = formatted.label;\n title = formatted.exact;\n sub = formatted.label === formatted.exact ? undefined : formatted.exact;\n } else if (!loading) {\n value = \"—\";\n }\n\n return (\n <div className=\"overviewCard\" title={title}>\n <div className=\"overviewCardLabel\">{label}</div>\n <div className=\"overviewCardValue mono\">{value}</div>\n {sub ? <div className=\"overviewCardSub\">{sub}</div> : null}\n </div>\n );\n}\n\nfunction DataSection({ dbId, instance }: { dbId: string; instance: SQLiteSyncDevtoolsInstance[\"instance\"] }) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isImporting, setIsImporting] = useState(false);\n const [status, setStatus] = useState<{ kind: \"success\" | \"error\"; message: string } | null>(null);\n\n const handleExport = () => {\n try {\n const data = instance.exportData();\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = `${dbId}-${data.exportedAt.replace(/[:.]/g, \"-\")}.json`;\n anchor.click();\n URL.revokeObjectURL(url);\n const rowCount = Object.values(data.tables).reduce((sum, rows) => sum + rows.length, 0);\n setStatus({ kind: \"success\", message: `Exported ${rowCount} row${rowCount === 1 ? \"\" : \"s\"}.` });\n } catch (error) {\n setStatus({ kind: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n };\n\n const handleImportFile = async (file: File) => {\n setIsImporting(true);\n setStatus(null);\n try {\n const data = JSON.parse(await file.text()) as SyncedDbExport;\n const result = await instance.importData(data);\n setStatus({ kind: \"success\", message: `Imported ${result.imported} row${result.imported === 1 ? \"\" : \"s\"}.` });\n } catch (error) {\n setStatus({ kind: \"error\", message: error instanceof Error ? error.message : String(error) });\n } finally {\n setIsImporting(false);\n }\n };\n\n return (\n <div className=\"overviewSection\">\n <div className=\"overviewSectionTitle\">Backup &amp; Restore</div>\n <div className=\"dangerZoneDesc\">\n Export the active rows of every CRDT table as JSON, or import a dump to seed/restore. Import overwrites rows\n with matching ids and is propagated to the server.\n </div>\n <div className=\"dataActions\">\n <button type=\"button\" className=\"dataButton\" onClick={handleExport}>\n ↓ Export JSON\n </button>\n <button\n type=\"button\"\n className=\"dataButton\"\n disabled={isImporting}\n onClick={() => fileInputRef.current?.click()}\n >\n {isImporting ? \"Importing…\" : \"↑ Import JSON\"}\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"application/json,.json\"\n className=\"hiddenInput\"\n onChange={(event) => {\n const file = event.target.files?.[0];\n event.target.value = \"\";\n if (file) void handleImportFile(file);\n }}\n />\n </div>\n {status && (\n <div className={status.kind === \"error\" ? \"dataStatusError\" : \"dataStatusSuccess\"}>{status.message}</div>\n )}\n </div>\n );\n}\n\nfunction ResetSection({ dbId, instance }: { dbId: string; instance: SQLiteSyncDevtoolsInstance[\"instance\"] }) {\n const [confirming, setConfirming] = useState(false);\n const [isResetting, setIsResetting] = useState(false);\n\n const handleReset = () => {\n setIsResetting(true);\n // Worker-owned clean reset: durably records a reset epoch, broadcasts a\n // reload to all tabs, and the next elected worker wipes the persisted DB.\n // The promise may never settle — the page unloads first.\n void instance.requestReload({ clean: true });\n };\n\n return (\n <div className=\"dangerZone\">\n <div className=\"dangerZoneTitle\">Danger Zone</div>\n <div className=\"dangerZoneRow\">\n <div className=\"dangerZoneDesc\">\n Requests a clean reload, so <code className=\"inlineCode\">{dbId}</code> is wiped on next load via{\" \"}\n <code className=\"inlineCode\">clearOnInit</code>, then reloads all tabs.\n </div>\n {confirming ? (\n <div className=\"dangerZoneActions\">\n <button\n type=\"button\"\n className=\"resetCancelButton\"\n disabled={isResetting}\n onClick={() => setConfirming(false)}\n >\n Cancel\n </button>\n <button type=\"button\" className=\"resetConfirmButton\" disabled={isResetting} onClick={handleReset}>\n {isResetting ? \"Resetting…\" : \"Confirm reset\"}\n </button>\n </div>\n ) : (\n <button type=\"button\" className=\"resetButton\" onClick={() => setConfirming(true)}>\n Reset DB\n </button>\n )}\n </div>\n </div>\n );\n}\n\nconst SYSTEM_COLUMNS = new Set([\"id\", \"tombstone\"]);\n\nfunction formatDefaultValue(value: unknown): string {\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (value === null) return \"null\";\n return JSON.stringify(value);\n}\n\nfunction SchemaTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n if (!selectedInstance) return null;\n\n const { tables, schemaVersion } = selectedInstance.instance._internal;\n const tableEntries = Object.entries(tables);\n\n return (\n <div className=\"schemaLayout\">\n <div className=\"schemaSection\">\n <div className=\"schemaSectionHeader\">\n <div className=\"schemaSectionTitle\">Tables</div>\n <span className=\"schemaBadge\">{tableEntries.length}</span>\n <span className=\"schemaVersionChip mlAuto\" title=\"Latest applied migration version\">\n applied v{schemaVersion}\n </span>\n </div>\n {tableEntries.length === 0 ? (\n <div className=\"schemaEmpty\">No tables declared on this schema.</div>\n ) : (\n <div className=\"schemaTableList\">\n {tableEntries.map(([crdtTableName, table]) => {\n const baseTableName = table.baseName ?? `_${crdtTableName}`;\n const columns = Object.entries(table.columns);\n return (\n <div key={crdtTableName} className=\"schemaTableCard\">\n <div className=\"schemaTableCardHeader\">\n <div className=\"schemaTableCardTitleRow\">\n <div className=\"schemaTableCardName\">{crdtTableName}</div>\n <span className=\"schemaBadge\">{columns.length}</span>\n </div>\n {table.description ? <p className=\"schemaTableCardDescription\">{table.description}</p> : null}\n <div className=\"schemaTableCardMeta\">\n <span className=\"schemaPolicyChip\" title=\"Base table\">\n {baseTableName}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.writeOrigin === \"server\" ? \"warn\" : undefined}\n title=\"Who may write CRDT events\"\n >\n writes {table.writeOrigin}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.aiAccess === \"read-write\" ? undefined : \"warn\"}\n title=\"AI agent access\"\n >\n ai {table.aiAccess}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.exportImport === \"ignore\" ? \"warn\" : undefined}\n title=\"Export / import\"\n >\n export {table.exportImport}\n </span>\n </div>\n </div>\n <div className=\"schemaColumnGrid\">\n <div className=\"schemaColumnRow schemaColumnHeaderRow\">\n <div className=\"schemaColHeader\">Column</div>\n <div className=\"schemaColHeader\">Type</div>\n <div className=\"schemaColHeader\">Flags</div>\n <div className=\"schemaColHeader\">Description</div>\n </div>\n {columns.map(([name, meta]) => (\n <SchemaColumnRow key={name} name={name} meta={meta} />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SchemaColumnRow({ name, meta }: { name: string; meta: ColumnMeta }) {\n const flags: string[] = [];\n if (name === \"id\") flags.push(\"pk\");\n if (meta.nullable) flags.push(\"nullable\");\n if (meta.hasDefault) flags.push(`default ${formatDefaultValue(meta.defaultValue)}`);\n\n return (\n <div className=\"schemaColumnRow\" data-system={SYSTEM_COLUMNS.has(name) ? \"true\" : undefined}>\n <div className=\"schemaColumnName\">{name}</div>\n <div className=\"schemaColumnType\">\n <span>{meta.kind}</span>\n {meta.kind === \"boolean\" ? <span className=\"schemaColumnTypeDetail\">integer 0/1</span> : null}\n {meta.kind === \"enum\" && meta.enumValues && meta.enumValues.length > 0 ? (\n <span className=\"schemaColumnTypeDetail\">{meta.enumValues.map((value) => `\"${value}\"`).join(\" | \")}</span>\n ) : null}\n </div>\n <div className=\"schemaColumnFlags\">{flags.length > 0 ? flags.join(\" · \") : \"—\"}</div>\n <div className=\"schemaColumnDescription\">{meta.description ?? \"\"}</div>\n </div>\n );\n}\n\nfunction LiveQueriesTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n const [queries, setQueries] = useState<SharedLiveQuerySnapshot[]>([]);\n\n const refresh = useCallback(() => {\n if (!selectedInstance) {\n setQueries([]);\n return;\n }\n\n setQueries(\n selectedInstance.instance._internal\n .getSharedLiveQueriesSnapshot()\n .sort(\n (a, b) =>\n a.sql.localeCompare(b.sql) ||\n formatLiveQueryParameters(a.parameters).localeCompare(formatLiveQueryParameters(b.parameters)),\n ),\n );\n }, [selectedInstance]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const totalSubscribers = queries.reduce((total, query) => total + query.subscriberCount, 0);\n\n return (\n <div className=\"schemaLayout\">\n <div className=\"schemaSection\">\n <div className=\"schemaSectionHeader\">\n <div className=\"schemaSectionTitle\">Shared Live Queries</div>\n <span className=\"schemaBadge\">{queries.length}</span>\n <span className=\"schemaVersionChip\">\n {totalSubscribers} subscriber{totalSubscribers !== 1 ? \"s\" : \"\"}\n </span>\n <button type=\"button\" className=\"refreshButton mlAuto\" onClick={refresh} disabled={!selectedInstance}>\n ↻ Refresh\n </button>\n </div>\n {queries.length === 0 ? (\n <div className=\"schemaEmpty\">\n No active live queries. Queries created via <code className=\"inlineCode\">useDbQuery</code> appear here while\n components are subscribed.\n </div>\n ) : (\n <div className=\"schemaTableGrid\">\n <div className=\"liveQueryHeaderRow\">\n <div className=\"schemaColHeader\">SQL</div>\n <div className=\"schemaColHeader\">Parameters</div>\n <div className=\"schemaColHeader alignCenter\">Subscribers</div>\n </div>\n {queries.map((query) => {\n const parameters = formatLiveQueryParameters(query.parameters);\n return (\n <div key={`${query.sql}|${parameters}`} className=\"liveQueryRow\">\n <div className=\"liveQuerySql\">{query.sql}</div>\n <div className=\"liveQueryParameters\">{parameters}</div>\n <div className=\"schemaStatusCell\">\n <span className={query.subscriberCount > 0 ? \"schemaActiveTag\" : \"liveQueryIdleTag\"}>\n {query.subscriberCount}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction formatLiveQueryParameters(parameters: readonly unknown[]): string {\n try {\n return JSON.stringify(parameters);\n } catch {\n return String(parameters);\n }\n}\n\ntype PersistedCrdtEvent = {\n sync_id: number;\n schema_version: number;\n status: \"pending\" | \"applied\" | \"failed\" | \"deduped\";\n type: \"item-created\" | \"item-updated\" | \"item-deleted\";\n timestamp: string;\n origin: \"remote\" | \"own\" | \"local\";\n source_node_id: string;\n dataset: string;\n item_id: string;\n payload: string;\n};\n\nfunction isPersistedCrdtEvent(value: unknown): value is PersistedCrdtEvent {\n if (typeof value !== \"object\" || value === null) return false;\n return (\n \"sync_id\" in value &&\n typeof value.sync_id === \"number\" &&\n \"status\" in value &&\n typeof value.status === \"string\" &&\n \"type\" in value &&\n typeof value.type === \"string\" &&\n \"origin\" in value &&\n typeof value.origin === \"string\" &&\n \"dataset\" in value &&\n typeof value.dataset === \"string\" &&\n \"item_id\" in value &&\n typeof value.item_id === \"string\" &&\n \"payload\" in value &&\n typeof value.payload === \"string\" &&\n \"timestamp\" in value &&\n typeof value.timestamp === \"string\"\n );\n}\n\ntype EventLogFilters = {\n dataset: string;\n origin: string;\n status: string;\n};\n\nconst PAGE_SIZE = 50;\n\nfunction sqlStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction eventLogWhereClause(filters: EventLogFilters, afterSyncId: number | null): string {\n const conditions: string[] = [];\n\n if (filters.dataset) conditions.push(`dataset = ${sqlStringLiteral(filters.dataset)}`);\n if (filters.origin) conditions.push(`origin = ${sqlStringLiteral(filters.origin)}`);\n if (filters.status) conditions.push(`status = ${sqlStringLiteral(filters.status)}`);\n if (afterSyncId !== null) conditions.push(`sync_id < ${afterSyncId}`);\n\n return conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n}\n\nfunction buildEventLogQuery(filters: EventLogFilters, afterSyncId: number | null): string {\n return `SELECT * FROM \"worker\".\"crdt_events\" ${eventLogWhereClause(filters, afterSyncId)} ORDER BY sync_id DESC LIMIT ${PAGE_SIZE + 1}`;\n}\n\nfunction buildEventLogCountQuery(filters: EventLogFilters): string {\n return `SELECT COUNT(*) AS count FROM \"worker\".\"crdt_events\" ${eventLogWhereClause(filters, null)}`;\n}\n\nfunction EventLogTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n const baseTableNames = useMemo(\n () => selectedInstance?.instance._internal.crdtTablesConfig.map((table) => table.baseTableName) ?? [],\n [selectedInstance],\n );\n\n const [filters, setFilters] = useState<EventLogFilters>({ dataset: \"\", origin: \"\", status: \"\" });\n const [events, setEvents] = useState<PersistedCrdtEvent[]>([]);\n const [totalCount, setTotalCount] = useState<number | null>(null);\n const [hasMore, setHasMore] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [expandedId, setExpandedId] = useState<number | null>(null);\n const afterSyncIdRef = useRef<number | null>(null);\n const isLoadingRef = useRef(false);\n\n const executeRows = useCallback(\n async (sql: string): Promise<unknown[]> => {\n if (!selectedInstance) return [];\n const result = await selectedInstance.instance._internal.executeAsync({ sql, parameters: [] });\n return result.rows;\n },\n [selectedInstance],\n );\n\n const load = useCallback(\n async (reset: boolean, currentFilters: EventLogFilters) => {\n if (!selectedInstance || isLoadingRef.current) return;\n isLoadingRef.current = true;\n setIsLoading(true);\n try {\n const afterSyncId = reset ? null : afterSyncIdRef.current;\n const sql = buildEventLogQuery(currentFilters, afterSyncId);\n const rowsPromise = executeRows(sql);\n const countPromise = reset ? executeRows(buildEventLogCountQuery(currentFilters)) : Promise.resolve(null);\n const [rows, countRows] = await Promise.all([rowsPromise, countPromise]);\n const page = rows.filter(isPersistedCrdtEvent).slice(0, PAGE_SIZE);\n setHasMore(rows.length > PAGE_SIZE);\n if (reset) {\n setEvents(page);\n setTotalCount(countRows ? readCount(countRows) : null);\n } else {\n setEvents((prev) => [...prev, ...page]);\n }\n afterSyncIdRef.current = page.at(-1)?.sync_id ?? null;\n } finally {\n isLoadingRef.current = false;\n setIsLoading(false);\n }\n },\n [selectedInstance, executeRows],\n );\n\n // Initial load and reload on instance or filter change\n useEffect(() => {\n afterSyncIdRef.current = null;\n setEvents([]);\n setTotalCount(null);\n void load(true, filters);\n }, [filters, load]);\n\n const applyFilters = (next: EventLogFilters) => {\n setFilters(next);\n };\n\n if (!selectedInstance) return null;\n\n return (\n <div className=\"eventLogLayout\">\n {/* Toolbar */}\n <div className=\"eventLogToolbar\">\n <select\n value={filters.dataset}\n onChange={(e) => applyFilters({ ...filters, dataset: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All datasets</option>\n {baseTableNames.map((name) => (\n <option key={name} value={name}>\n {name}\n </option>\n ))}\n </select>\n <select\n value={filters.origin}\n onChange={(e) => applyFilters({ ...filters, origin: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All origins</option>\n <option value=\"own\">own</option>\n <option value=\"remote\">remote</option>\n <option value=\"local\">local</option>\n </select>\n <select\n value={filters.status}\n onChange={(e) => applyFilters({ ...filters, status: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All statuses</option>\n <option value=\"applied\">applied</option>\n <option value=\"pending\">pending</option>\n <option value=\"failed\">failed</option>\n <option value=\"deduped\">deduped</option>\n </select>\n <button type=\"button\" className=\"refreshButton\" disabled={isLoading} onClick={() => void load(true, filters)}>\n {isLoading ? \"…\" : \"↻\"} Refresh\n </button>\n {totalCount !== null && (\n <span className=\"eventLogCount\">\n {events.length === totalCount\n ? `${totalCount} event${totalCount === 1 ? \"\" : \"s\"}`\n : `${events.length} of ${totalCount}`}\n </span>\n )}\n </div>\n\n {/* Event list */}\n {events.length === 0 && !isLoading ? (\n <div className=\"eventLogEmpty\">No events match the current filters.</div>\n ) : (\n <div className=\"eventLogList\">\n {events.map((event) => {\n const isExpanded = expandedId === event.sync_id;\n return (\n <div key={event.sync_id} className=\"eventRow\" data-expanded={isExpanded ? \"true\" : undefined}>\n <button\n type=\"button\"\n className=\"eventRowHeader\"\n onClick={() => setExpandedId(isExpanded ? null : event.sync_id)}\n >\n <span className=\"eventSyncId\">#{event.sync_id}</span>\n <EventTypeBadge type={event.type} />\n <EventOriginBadge origin={event.origin} />\n <EventStatusBadge status={event.status} />\n <span className=\"eventDataset\">{event.dataset}</span>\n <span className=\"eventItemId\">{event.item_id}</span>\n <span className=\"eventTimestamp\">{formatHlcTimestamp(event.timestamp)}</span>\n <span className=\"eventChevron\">{isExpanded ? \"▲\" : \"▼\"}</span>\n </button>\n\n {isExpanded && (\n <div className=\"eventPayload\">\n <div className=\"eventPayloadMeta\">\n <span className=\"eventMetaItem\">schema v{event.schema_version}</span>\n <span className=\"eventMetaItem\">node: {event.source_node_id || \"—\"}</span>\n <span className=\"eventMetaItem\">ts: {event.timestamp}</span>\n </div>\n <pre className=\"eventPayloadPre\">{formatPayload(event.payload)}</pre>\n </div>\n )}\n </div>\n );\n })}\n\n {hasMore && (\n <button\n type=\"button\"\n className=\"loadMoreButton\"\n disabled={isLoading}\n onClick={() => void load(false, filters)}\n >\n {isLoading ? \"Loading…\" : `Load ${PAGE_SIZE} more`}\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction EventTypeBadge({ type }: { type: string }) {\n const { variant, label } =\n type === \"item-created\"\n ? { variant: \"create\", label: \"create\" }\n : type === \"item-deleted\"\n ? { variant: \"delete\", label: \"delete\" }\n : { variant: \"update\", label: \"update\" };\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {label}\n </span>\n );\n}\n\nfunction EventOriginBadge({ origin }: { origin: string }) {\n const variant = origin === \"own\" ? \"own\" : origin === \"remote\" ? \"remote\" : \"local\";\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {origin}\n </span>\n );\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const variant =\n status === \"applied\" ? \"applied\" : status === \"pending\" ? \"pending\" : status === \"failed\" ? \"failed\" : \"skipped\";\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {status}\n </span>\n );\n}\n\nfunction formatHlcTimestamp(ts: string): string {\n // HLC format: \"<unix_ms>-<counter>-<node>\" or just an ISO string\n const ms = Number(ts.split(\"-\")[0]);\n if (!Number.isNaN(ms) && ms > 1e12) {\n return new Date(ms).toLocaleTimeString();\n }\n return ts.slice(0, 19).replace(\"T\", \" \");\n}\n\nfunction formatPayload(raw: string): string {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2);\n } catch {\n return raw;\n }\n}\n\nfunction QueryRunnerTab({\n selectedInstance,\n queryTarget,\n setQueryTarget,\n query,\n setQuery,\n queryState,\n canRunQuery,\n runQuery,\n}: {\n selectedInstance: unknown;\n queryTarget: QueryTarget;\n setQueryTarget: (t: QueryTarget) => void;\n query: string;\n setQuery: (q: string) => void;\n queryState: QueryState;\n canRunQuery: boolean;\n runQuery: () => Promise<void>;\n}) {\n return (\n <div className=\"queryRunnerLayout\">\n {/* Top toolbar */}\n <div className=\"queryToolbar\">\n <div className=\"targetToggle\">\n <button\n type=\"button\"\n className=\"targetButton\"\n data-active={queryTarget === \"memory\" ? \"true\" : undefined}\n onClick={() => setQueryTarget(\"memory\")}\n >\n Memory DB\n </button>\n <button\n type=\"button\"\n className=\"targetButton\"\n data-active={queryTarget === \"worker\" ? \"true\" : undefined}\n onClick={() => setQueryTarget(\"worker\")}\n >\n Worker DB\n </button>\n </div>\n\n <div className=\"queryToolbarRight\">\n {!selectedInstance && <span className=\"noInstanceWarning\">No instance selected</span>}\n <span className=\"shortcutHint\">⌘↵ to run</span>\n <button\n type=\"button\"\n className=\"runButton\"\n data-enabled={canRunQuery ? \"true\" : undefined}\n data-running={queryState.status === \"running\" ? \"true\" : undefined}\n disabled={!canRunQuery}\n onClick={() => void runQuery()}\n >\n {queryState.status === \"running\" ? (\n <>\n <span className=\"runningDot\" />\n Running…\n </>\n ) : (\n <>▶ Run</>\n )}\n </button>\n </div>\n </div>\n\n {/* SQL textarea */}\n <div className=\"editorWrapper\">\n <textarea\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === \"Enter\" && canRunQuery) {\n event.preventDefault();\n void runQuery();\n }\n }}\n className=\"textarea\"\n placeholder=\"SELECT * FROM your_table LIMIT 100\"\n spellCheck={false}\n />\n </div>\n\n {/* Constraint hint */}\n <div className=\"helperText\">\n {queryTarget === \"worker\"\n ? \"Worker DB is read-only — only SELECT, PRAGMA, and EXPLAIN are allowed.\"\n : \"Memory DB allows writes only to CRDT tables.\"}\n </div>\n\n {/* Results */}\n {queryState.status === \"error\" && (\n <div className=\"errorPanel\">\n <div className=\"resultHeader\">\n <span className=\"errorBadge\">Error</span>\n <span className=\"resultMeta\">\n {queryState.error.target} · {queryState.error.sql}\n </span>\n </div>\n <pre className=\"errorMessage\">{queryState.error.message}</pre>\n </div>\n )}\n\n {queryState.status === \"success\" && (\n <div className=\"resultPanel\">\n <div className=\"resultHeader\">\n <span className=\"successBadge\">\n {queryState.output.rowCount} row{queryState.output.rowCount !== 1 ? \"s\" : \"\"}\n </span>\n <span className=\"resultMeta\">\n {queryState.output.target} · {queryState.output.durationMs}ms\n </span>\n </div>\n <ResultTable rows={queryState.output.rows} />\n </div>\n )}\n </div>\n );\n}\n\nfunction ResultTable({ rows }: { rows: unknown[] }) {\n if (rows.length === 0) {\n return <div className=\"resultEmpty\">Query returned 0 rows.</div>;\n }\n\n const firstRow = rows[0];\n if (typeof firstRow !== \"object\" || firstRow === null) {\n return <pre className=\"resultRaw\">{JSON.stringify(rows, null, 2)}</pre>;\n }\n\n const columns = Object.keys(firstRow as object);\n\n return (\n <div className=\"tableWrapper\">\n <table className=\"table\">\n <thead>\n <tr>\n <th className=\"thRowNum\">#</th>\n {columns.map((col) => (\n <th key={col} className=\"th\">\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr key={rowIdx}>\n <td className=\"tdRowNum\">{rowIdx + 1}</td>\n {columns.map((col) => {\n const val = (row as Record<string, unknown>)[col];\n return (\n <td key={col} className=\"td\">\n {val === null ? (\n <span className=\"nullValue\">NULL</span>\n ) : typeof val === \"object\" ? (\n <span className=\"jsonValue\">{JSON.stringify(val)}</span>\n ) : (\n String(val)\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatInstanceLabel(dbId: string, instanceId: string, duplicateCount: number): string {\n if (duplicateCount < 2) {\n return dbId;\n }\n\n return `${dbId} (${instanceId.slice(0, 6)})`;\n}\n\nfunction normalizeSingleStatement(query: string): string {\n const trimmed = query.trim();\n if (!trimmed) {\n throw new Error(\"Enter a SQL statement.\");\n }\n\n const withoutTrailingSemicolons = trimmed.replace(/;+\\s*$/u, \"\");\n if (withoutTrailingSemicolons.includes(\";\")) {\n throw new Error(\"Devtools only supports a single SQL statement.\");\n }\n\n return withoutTrailingSemicolons;\n}\n\nfunction getStatementKind(query: string): string {\n const match = query.trimStart().match(/^([a-z]+)/iu);\n return match?.[1]?.toLowerCase() ?? \"\";\n}\n\nfunction isWorkerReadOnlyStatement(statementKind: string): boolean {\n return statementKind === \"select\" || statementKind === \"pragma\";\n}\n\nfunction getEmptySnapshot(): SQLiteSyncDevtoolsSnapshot {\n return emptySnapshot;\n}\n\nconst emptySnapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["cssText"],"sources":["../src/devtools-registry.ts","../src/devtools.css?inline","../src/shadow-root.tsx","../src/devtools.tsx"],"sourcesContent":["import type { SyncedDb } from \"@sqlite-sync/core\";\n\nconst devtoolsRegistrySymbol = Symbol.for(\"@sqlite-sync/devtools\");\n\nexport type SQLiteSyncDevtoolsInstance = {\n instanceId: string;\n dbId: string;\n createdAt: number;\n instance: SyncedDb<any>;\n};\n\nexport type SQLiteSyncDevtoolsSnapshot = {\n instances: readonly SQLiteSyncDevtoolsInstance[];\n};\n\nexport type SQLiteSyncDevtoolsRegistry = {\n version: 1;\n instances: Map<string, SQLiteSyncDevtoolsInstance>;\n subscribe(listener: () => void): () => void;\n getSnapshot(): SQLiteSyncDevtoolsSnapshot;\n register(instance: SQLiteSyncDevtoolsInstance): () => void;\n};\n\ntype RegistryGlobal = typeof globalThis & {\n [key: symbol]: SQLiteSyncDevtoolsRegistry | undefined;\n};\n\nfunction createSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const instances = new Map<string, SQLiteSyncDevtoolsInstance>();\n const listeners = new Set<() => void>();\n let snapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n };\n\n const notify = () => {\n for (const listener of listeners) {\n listener();\n }\n };\n\n const updateSnapshot = () => {\n snapshot = {\n instances: Array.from(instances.values()),\n };\n notify();\n };\n\n return {\n version: 1,\n instances,\n subscribe(listener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n },\n getSnapshot() {\n return snapshot;\n },\n register(instance) {\n instances.set(instance.instanceId, instance);\n updateSnapshot();\n\n let isUnregistered = false;\n return () => {\n if (isUnregistered) return;\n isUnregistered = true;\n\n if (!instances.delete(instance.instanceId)) return;\n updateSnapshot();\n };\n },\n };\n}\n\nexport function getOrCreateSQLiteSyncDevtoolsRegistry(): SQLiteSyncDevtoolsRegistry {\n const registryGlobal = globalThis as RegistryGlobal;\n\n registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();\n\n return registryGlobal[devtoolsRegistrySymbol];\n}\n",":host {\n all: initial;\n display: block;\n position: relative;\n z-index: 9998;\n --ss-bg: #0e1015;\n --ss-bg-panel: #161921;\n --ss-bg-card: #1c2030;\n --ss-bg-input: #111318;\n --ss-border: #2a2f3e;\n --ss-border-light: #343a4f;\n --ss-text: #e2e8f0;\n --ss-text-muted: #6b7280;\n --ss-text-dim: #9ca3af;\n --ss-teal: #2dd4bf;\n --ss-teal-dim: rgba(45, 212, 191, 0.12);\n --ss-teal-glow: rgba(45, 212, 191, 0.06);\n --ss-error: #f87171;\n --ss-error-bg: rgba(248, 113, 113, 0.08);\n --ss-error-border: rgba(248, 113, 113, 0.25);\n --ss-success: #34d399;\n --ss-success-bg: rgba(52, 211, 153, 0.08);\n --ss-amber: #fbbf24;\n font-family: ui-sans-serif, system-ui, sans-serif;\n color: var(--ss-text);\n font-size: 0.88rem;\n}\n\n:host *,\n:host *::before,\n:host *::after {\n box-sizing: border-box;\n}\n\n.mono {\n font-family: ui-monospace, monospace;\n}\n\n.sm {\n font-size: 0.78rem;\n}\n\n.alignCenter {\n text-align: center;\n}\n\n.mlAuto {\n margin-left: auto;\n}\n\n.hiddenInput {\n display: none;\n}\n\n.floatingRoot {\n position: fixed;\n inset: 0;\n pointer-events: none;\n z-index: 9998;\n}\n\n.triggerButton {\n position: absolute;\n right: 16px;\n bottom: 16px;\n display: inline-flex;\n align-items: center;\n gap: 0.3rem;\n border: 1px solid var(--ss-border);\n border-radius: 8px;\n padding: 0.3rem 0.45rem;\n background: var(--ss-bg-panel);\n color: var(--ss-text);\n box-shadow:\n 0 0 0 1px var(--ss-border),\n 0 4px 16px rgba(0, 0, 0, 0.5);\n cursor: grab;\n touch-action: none;\n user-select: none;\n pointer-events: auto;\n}\n\n.triggerIcon {\n color: var(--ss-teal);\n font-size: 0.9rem;\n line-height: 1;\n}\n\n.triggerCount {\n min-width: 1.1rem;\n border-radius: 4px;\n padding: 0.05rem 0.25rem;\n background-color: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-size: 0.65rem;\n font-weight: 700;\n text-align: center;\n font-family: ui-monospace, monospace;\n}\n\n.overlay {\n position: fixed;\n inset: 0;\n z-index: 9999;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 1.5rem;\n background-color: rgba(0, 0, 0, 0.72);\n backdrop-filter: blur(8px);\n}\n\n.dialog {\n width: min(72rem, 100%);\n height: min(90vh, 860px);\n display: flex;\n flex-direction: column;\n border: 1px solid var(--ss-border);\n border-radius: 16px;\n background: var(--ss-bg);\n box-shadow:\n 0 0 0 1px var(--ss-border),\n 0 40px 80px rgba(0, 0, 0, 0.8),\n 0 0 60px rgba(45, 212, 191, 0.04);\n overflow: hidden;\n font-family: ui-sans-serif, system-ui, sans-serif;\n color: var(--ss-text);\n font-size: 0.88rem;\n}\n\n.header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 1rem;\n padding: 0.85rem 1.1rem;\n border-bottom: 1px solid var(--ss-border);\n background: var(--ss-bg-panel);\n flex-shrink: 0;\n}\n\n.headerLeft {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n}\n\n.headerLogo {\n font-size: 1.3rem;\n color: var(--ss-teal);\n line-height: 1;\n}\n\n.eyebrow {\n font-size: 0.65rem;\n font-weight: 600;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n}\n\n.title {\n margin: 0.05rem 0 0;\n font-size: 0.95rem;\n font-weight: 700;\n color: var(--ss-text);\n letter-spacing: -0.01em;\n}\n\n.headerRight {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.instancePickerLabel {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.instancePickerText {\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--ss-text-muted);\n text-transform: uppercase;\n letter-spacing: 0.06em;\n}\n\n.instancePickerSelect {\n border-radius: 7px;\n border: 1px solid var(--ss-border);\n padding: 0.35rem 0.6rem;\n background-color: var(--ss-bg-card);\n color: var(--ss-text);\n font-size: 0.82rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n}\n\n.instanceCountBadge {\n font-size: 0.72rem;\n font-weight: 600;\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n border-radius: 5px;\n padding: 0.2rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.closeButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: transparent;\n color: var(--ss-text-muted);\n font-size: 0.82rem;\n font-weight: 600;\n cursor: pointer;\n}\n\n.hideLauncherButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.3rem 0.65rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.75rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.emptyState {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 4rem 2rem;\n gap: 0.75rem;\n flex: 1;\n}\n\n.emptyStateIcon {\n font-size: 2.5rem;\n color: var(--ss-text-muted);\n opacity: 0.4;\n}\n\n.emptyStateText {\n margin: 0;\n font-size: 0.95rem;\n font-weight: 600;\n color: var(--ss-text-dim);\n}\n\n.emptyStateSubtext {\n margin: 0;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n text-align: center;\n}\n\n.inlineCode {\n font-family: ui-monospace, monospace;\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.1em 0.4em;\n font-size: 0.88em;\n color: var(--ss-teal);\n}\n\n.contentLayout {\n display: grid;\n grid-template-columns: 200px minmax(0, 1fr);\n flex: 1;\n min-height: 0;\n overflow: hidden;\n}\n\n.sidebar {\n display: flex;\n flex-direction: column;\n gap: 0;\n padding: 0.75rem;\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-panel);\n overflow-y: auto;\n}\n\n.nav {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n margin-bottom: 1rem;\n}\n\n.navIcon {\n font-size: 0.7rem;\n opacity: 0.7;\n}\n\n.sidebarInfo {\n margin-top: auto;\n padding: 0.75rem;\n border-radius: 8px;\n background: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n}\n\n.sidebarInfoLabel {\n font-size: 0.65rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n margin-bottom: 0.3rem;\n}\n\n.sidebarInfoValue {\n font-size: 0.88rem;\n font-weight: 600;\n color: var(--ss-text);\n word-break: break-word;\n font-family: ui-monospace, monospace;\n}\n\n.sidebarInfoSub {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n margin-top: 0.25rem;\n}\n\n.mainPane {\n min-width: 0;\n overflow-y: auto;\n padding: 1rem;\n}\n\n.overviewLayout {\n display: flex;\n flex-direction: column;\n gap: 1.25rem;\n}\n\n.overviewCardsRow {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));\n gap: 0.75rem;\n}\n\n.overviewCard {\n padding: 0.9rem 1rem;\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.overviewCardLabel {\n font-size: 0.68rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n margin-bottom: 0.4rem;\n}\n\n.overviewCardValue {\n font-size: 1rem;\n font-weight: 700;\n color: var(--ss-text);\n word-break: break-word;\n}\n\n.overviewCardSub {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n margin-top: 0.25rem;\n}\n\n.overviewSection {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n}\n\n.overviewSectionTitle {\n font-size: 0.72rem;\n font-weight: 600;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n}\n\n.overviewSectionHeader {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n}\n\n.refreshButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.35rem 0.7rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.overviewAccumulatorValue {\n padding: 0.75rem;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n font-family: ui-monospace, monospace;\n font-size: 0.78rem;\n color: var(--ss-text);\n line-height: 1.5;\n word-break: break-all;\n}\n\n.overviewAccumulatorEmpty {\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.overviewAccumulatorError {\n color: var(--ss-error);\n}\n\n.overviewEmpty {\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.eventCountGrid {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));\n gap: 0.5rem;\n}\n\n.eventCountCard {\n padding: 0.75rem 0.85rem;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.eventCountValue {\n font-size: 1.05rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n margin-bottom: 0.35rem;\n}\n\n.eventCountValue[data-tone=\"amber\"][data-emphasize=\"true\"] {\n color: var(--ss-amber);\n}\n\n.eventCountValue[data-tone=\"success\"][data-emphasize=\"true\"] {\n color: var(--ss-success);\n}\n\n.eventCountValue[data-tone=\"error\"][data-emphasize=\"true\"] {\n color: var(--ss-error);\n}\n\n.dataActions {\n display: flex;\n gap: 0.4rem;\n}\n\n.dataButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.4rem 0.8rem;\n background-color: transparent;\n color: var(--ss-teal);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.dataStatusSuccess {\n font-size: 0.75rem;\n color: var(--ss-success);\n}\n\n.dataStatusError {\n font-size: 0.75rem;\n color: var(--ss-error);\n word-break: break-word;\n}\n\n.dangerZone {\n margin-top: auto;\n border-radius: 10px;\n border: 1px solid var(--ss-error-border);\n padding: 0.75rem 1rem;\n background: var(--ss-error-bg);\n}\n\n.dangerZoneTitle {\n font-size: 0.65rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-error);\n margin-bottom: 0.5rem;\n}\n\n.dangerZoneRow {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n}\n\n.dangerZoneDesc {\n font-size: 0.75rem;\n color: var(--ss-text-muted);\n line-height: 1.5;\n}\n\n.dangerZoneActions {\n display: flex;\n gap: 0.4rem;\n flex-shrink: 0;\n}\n\n.resetButton {\n flex-shrink: 0;\n border: 1px solid var(--ss-error-border);\n border-radius: 7px;\n padding: 0.35rem 0.75rem;\n background-color: transparent;\n color: var(--ss-error);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.resetCancelButton {\n border: 1px solid var(--ss-border);\n border-radius: 7px;\n padding: 0.35rem 0.65rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-weight: 600;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.resetConfirmButton {\n border: none;\n border-radius: 7px;\n padding: 0.35rem 0.75rem;\n background-color: var(--ss-error);\n color: #0e1015;\n font-size: 0.78rem;\n font-weight: 700;\n cursor: pointer;\n white-space: nowrap;\n}\n\n.queryRunnerLayout {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n height: 100%;\n}\n\n.queryToolbar {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 0.75rem;\n flex-wrap: wrap;\n}\n\n.targetToggle {\n display: flex;\n gap: 0;\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-card);\n}\n\n.queryToolbarRight {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.noInstanceWarning {\n font-size: 0.75rem;\n color: var(--ss-amber);\n font-weight: 500;\n}\n\n.shortcutHint {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n padding: 0.2rem 0.5rem;\n border-radius: 5px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.editorWrapper {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-input);\n}\n\n.textarea {\n width: 100%;\n min-height: 9rem;\n resize: vertical;\n border: none;\n padding: 0.85rem 1rem;\n background-color: transparent;\n color: var(--ss-text);\n font-size: 0.875rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n line-height: 1.6;\n outline: none;\n box-sizing: border-box;\n}\n\n.helperText {\n font-size: 0.75rem;\n line-height: 1.5;\n color: var(--ss-text-muted);\n}\n\n.resultPanel {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n background: var(--ss-bg-panel);\n}\n\n.errorPanel {\n display: flex;\n flex-direction: column;\n gap: 0.6rem;\n padding: 0.85rem 1rem;\n border-radius: 10px;\n border: 1px solid var(--ss-error-border);\n background: var(--ss-error-bg);\n}\n\n.resultHeader {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n padding: 0.6rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n}\n\n.successBadge {\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n border-radius: 5px;\n padding: 0.15rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.errorBadge {\n font-size: 0.72rem;\n font-weight: 700;\n color: var(--ss-error);\n background-color: var(--ss-error-bg);\n border-radius: 5px;\n padding: 0.15rem 0.5rem;\n font-family: ui-monospace, monospace;\n}\n\n.resultMeta {\n font-size: 0.72rem;\n color: var(--ss-text-muted);\n font-family: ui-monospace, monospace;\n}\n\n.resultEmpty {\n padding: 1.5rem;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n text-align: center;\n}\n\n.resultRaw {\n margin: 0;\n padding: 0.85rem 1rem;\n overflow-x: auto;\n white-space: pre-wrap;\n word-break: break-word;\n font-size: 0.8rem;\n line-height: 1.5;\n color: var(--ss-text);\n font-family: ui-monospace, monospace;\n}\n\n.errorMessage {\n margin: 0;\n font-size: 0.82rem;\n line-height: 1.6;\n color: var(--ss-error);\n font-family: ui-monospace, monospace;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.tableWrapper {\n overflow-x: auto;\n max-height: 320px;\n overflow-y: auto;\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: 0.8rem;\n font-family: ui-monospace, SFMono-Regular, Menlo, monospace;\n}\n\n.table tbody tr:nth-child(even) {\n background: var(--ss-teal-glow);\n}\n\n.th {\n padding: 0.5rem 0.85rem;\n text-align: left;\n font-weight: 600;\n font-size: 0.7rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n white-space: nowrap;\n position: sticky;\n top: 0;\n}\n\n.thRowNum {\n padding: 0.5rem 0.85rem;\n text-align: right;\n font-weight: 600;\n font-size: 0.7rem;\n letter-spacing: 0.05em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n white-space: nowrap;\n position: sticky;\n top: 0;\n opacity: 0.5;\n width: 2.5rem;\n}\n\n.td {\n padding: 0.45rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n color: var(--ss-text);\n white-space: nowrap;\n max-width: 300px;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.tdRowNum {\n padding: 0.45rem 0.85rem;\n border-bottom: 1px solid var(--ss-border);\n border-right: 1px solid var(--ss-border);\n color: var(--ss-text-muted);\n white-space: nowrap;\n max-width: 300px;\n overflow: hidden;\n text-overflow: ellipsis;\n opacity: 0.5;\n text-align: right;\n user-select: none;\n}\n\n.nullValue {\n color: var(--ss-text-muted);\n font-style: italic;\n opacity: 0.6;\n}\n\n.jsonValue {\n color: var(--ss-text-dim);\n}\n\n.tabButton {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n border: none;\n border-radius: 7px;\n padding: 0.6rem 0.75rem;\n background: transparent;\n color: var(--ss-text-dim);\n font-size: 0.82rem;\n font-weight: 500;\n text-align: left;\n cursor: pointer;\n transition: background 0.15s;\n border-left: 2px solid transparent;\n}\n\n.tabButton[data-active=\"true\"] {\n background: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-weight: 700;\n border-left: 2px solid var(--ss-teal);\n}\n\n.targetButton {\n border: none;\n border-right: 1px solid var(--ss-border);\n padding: 0.45rem 0.85rem;\n background: transparent;\n color: var(--ss-text-muted);\n font-size: 0.78rem;\n font-weight: 500;\n cursor: pointer;\n font-family: ui-monospace, monospace;\n transition: background 0.1s;\n white-space: nowrap;\n}\n\n.targetButton[data-active=\"true\"] {\n background: var(--ss-teal-dim);\n color: var(--ss-teal);\n font-weight: 700;\n}\n\n.runButton {\n display: inline-flex;\n align-items: center;\n gap: 0.4rem;\n border: none;\n border-radius: 7px;\n padding: 0.45rem 0.9rem;\n background: var(--ss-bg-card);\n color: var(--ss-text-muted);\n font-size: 0.82rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n cursor: not-allowed;\n opacity: 1;\n transition: background 0.15s;\n white-space: nowrap;\n}\n\n.runButton[data-enabled=\"true\"] {\n background: var(--ss-teal);\n color: #0e1015;\n cursor: pointer;\n}\n\n.runButton[data-running=\"true\"] {\n opacity: 0.75;\n}\n\n.runningDot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background-color: currentColor;\n}\n\n.schemaLayout {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n}\n\n.schemaSection {\n display: flex;\n flex-direction: column;\n gap: 0.65rem;\n}\n\n.schemaSectionHeader {\n display: flex;\n align-items: center;\n gap: 0.6rem;\n}\n\n.schemaSectionTitle {\n font-size: 0.72rem;\n font-weight: 700;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n}\n\n.schemaBadge {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n border-radius: 4px;\n padding: 0.1rem 0.4rem;\n font-family: ui-monospace, monospace;\n}\n\n.schemaVersionChip {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.1rem 0.5rem;\n}\n\n.schemaTableGrid {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n overflow: hidden;\n}\n\n.schemaColHeader {\n padding: 0.5rem 0.85rem;\n font-size: 0.68rem;\n font-weight: 700;\n letter-spacing: 0.07em;\n text-transform: uppercase;\n color: var(--ss-text-muted);\n border-right: 1px solid var(--ss-border);\n}\n\n.schemaStatusCell {\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.6rem 0.5rem;\n}\n\n.schemaActiveTag {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n border-radius: 4px;\n padding: 0.15rem 0.45rem;\n font-family: ui-monospace, monospace;\n}\n\n.schemaEmpty {\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.schemaTableList {\n display: flex;\n flex-direction: column;\n gap: 0.85rem;\n}\n\n.schemaTableCard {\n border-radius: 10px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n overflow: hidden;\n}\n\n.schemaTableCardHeader {\n display: flex;\n flex-direction: column;\n gap: 0.45rem;\n padding: 0.75rem 0.85rem 0.7rem;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.schemaTableCardTitleRow {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n}\n\n.schemaTableCardName {\n font-size: 0.92rem;\n font-weight: 700;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n}\n\n.schemaTableCardDescription {\n margin: 0;\n font-size: 0.78rem;\n line-height: 1.45;\n color: var(--ss-text-dim);\n}\n\n.schemaTableCardMeta {\n display: flex;\n flex-wrap: wrap;\n gap: 0.35rem;\n}\n\n.schemaPolicyChip {\n font-size: 0.65rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n background: var(--ss-bg-input);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.12rem 0.4rem;\n}\n\n.schemaPolicyChip[data-tone=\"warn\"] {\n color: var(--ss-amber);\n background: rgba(251, 191, 36, 0.08);\n border-color: rgba(251, 191, 36, 0.25);\n}\n\n.schemaColumnGrid {\n display: flex;\n flex-direction: column;\n overflow-x: auto;\n}\n\n.schemaColumnRow {\n display: grid;\n grid-template-columns: minmax(6.5rem, 0.7fr) minmax(8rem, 1fr) minmax(7.5rem, 0.9fr) minmax(0, 1.8fr);\n min-width: 36rem;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.schemaColumnRow:last-child {\n border-bottom: none;\n}\n\n.schemaColumnRow[data-system=\"true\"] {\n opacity: 0.62;\n}\n\n.schemaColumnHeaderRow {\n background: var(--ss-bg-panel);\n}\n\n.schemaColumnHeaderRow .schemaColHeader:last-child {\n border-right: none;\n}\n\n.schemaColumnName,\n.schemaColumnType,\n.schemaColumnFlags,\n.schemaColumnDescription {\n padding: 0.5rem 0.85rem;\n font-size: 0.76rem;\n border-right: 1px solid var(--ss-border);\n min-width: 0;\n}\n\n.schemaColumnDescription {\n border-right: none;\n color: var(--ss-text-dim);\n overflow-wrap: anywhere;\n}\n\n.schemaColumnName {\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n font-weight: 600;\n}\n\n.schemaColumnType {\n display: flex;\n flex-direction: column;\n gap: 0.15rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-teal);\n}\n\n.schemaColumnTypeDetail {\n font-size: 0.65rem;\n color: var(--ss-text-muted);\n font-weight: 400;\n overflow-wrap: anywhere;\n}\n\n.schemaColumnFlags {\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n overflow-wrap: anywhere;\n}\n\n.liveQueryHeaderRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 220px 110px;\n gap: 0;\n background-color: var(--ss-bg-card);\n border-bottom: 1px solid var(--ss-border);\n}\n\n.liveQueryRow {\n display: grid;\n grid-template-columns: minmax(0, 1fr) 220px 110px;\n gap: 0;\n border-bottom: 1px solid var(--ss-border);\n}\n\n.liveQuerySql {\n padding: 0.6rem 0.85rem;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n border-right: 1px solid var(--ss-border);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.liveQueryParameters {\n padding: 0.6rem 0.85rem;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-dim);\n border-right: 1px solid var(--ss-border);\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n}\n\n.liveQueryIdleTag {\n font-size: 0.68rem;\n font-weight: 700;\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n border-radius: 4px;\n padding: 0.15rem 0.45rem;\n font-family: ui-monospace, monospace;\n}\n\n.eventLogLayout {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n height: 100%;\n}\n\n.eventLogToolbar {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n flex-wrap: wrap;\n flex-shrink: 0;\n}\n\n.eventLogFilterSelect {\n border-radius: 7px;\n border: 1px solid var(--ss-border);\n padding: 0.35rem 0.6rem;\n background-color: var(--ss-bg-card);\n color: var(--ss-text);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n}\n\n.eventLogCount {\n margin-left: auto;\n font-size: 0.72rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n}\n\n.eventLogEmpty {\n padding: 2rem;\n text-align: center;\n font-size: 0.82rem;\n color: var(--ss-text-muted);\n font-style: italic;\n}\n\n.eventLogList {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n overflow-y: auto;\n flex: 1;\n}\n\n.eventRow {\n border-radius: 8px;\n border: 1px solid var(--ss-border);\n background: var(--ss-bg-card);\n overflow: hidden;\n flex-shrink: 0;\n}\n\n.eventRow[data-expanded=\"true\"] {\n border: 1px solid #2dd4bf40;\n background: var(--ss-teal-glow);\n}\n\n.eventRowHeader {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n width: 100%;\n padding: 0.5rem 0.75rem;\n background: transparent;\n border: none;\n cursor: pointer;\n text-align: left;\n flex-wrap: wrap;\n}\n\n.eventSyncId {\n font-size: 0.7rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n min-width: 3.5rem;\n}\n\n.eventDataset {\n font-size: 0.8rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n font-weight: 600;\n}\n\n.eventItemId {\n font-size: 0.75rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n flex: 1;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n}\n\n.eventTimestamp {\n font-size: 0.7rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n margin-left: auto;\n}\n\n.eventChevron {\n font-size: 0.6rem;\n color: var(--ss-text-muted);\n margin-left: 0.25rem;\n}\n\n.eventPayload {\n border-top: 1px solid var(--ss-border);\n padding: 0.6rem 0.75rem;\n}\n\n.eventPayloadMeta {\n display: flex;\n gap: 0.75rem;\n margin-bottom: 0.5rem;\n}\n\n.eventMetaItem {\n font-size: 0.68rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text-muted);\n}\n\n.eventPayloadPre {\n margin: 0;\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n color: var(--ss-text);\n line-height: 1.5;\n white-space: pre-wrap;\n word-break: break-word;\n}\n\n.loadMoreButton {\n width: 100%;\n border: 1px solid var(--ss-border);\n border-radius: 8px;\n padding: 0.6rem;\n background-color: transparent;\n color: var(--ss-text-dim);\n font-size: 0.78rem;\n font-family: ui-monospace, monospace;\n cursor: pointer;\n flex-shrink: 0;\n}\n\n.eventBadge {\n font-size: 0.65rem;\n font-weight: 700;\n border-radius: 4px;\n padding: 0.1rem 0.4rem;\n font-family: ui-monospace, monospace;\n white-space: nowrap;\n}\n\n.eventBadge[data-variant=\"create\"] {\n color: var(--ss-teal);\n background-color: var(--ss-teal-dim);\n}\n\n.eventBadge[data-variant=\"update\"] {\n color: #a78bfa;\n background-color: rgba(167, 139, 250, 0.12);\n}\n\n.eventBadge[data-variant=\"delete\"] {\n color: var(--ss-error);\n background-color: rgba(248, 113, 113, 0.12);\n}\n\n.eventBadge[data-variant=\"own\"],\n.eventBadge[data-variant=\"applied\"] {\n color: var(--ss-success);\n background-color: var(--ss-success-bg);\n}\n\n.eventBadge[data-variant=\"remote\"],\n.eventBadge[data-variant=\"pending\"] {\n color: var(--ss-amber);\n background-color: rgba(251, 191, 36, 0.1);\n}\n\n.eventBadge[data-variant=\"local\"] {\n color: var(--ss-text-dim);\n background-color: var(--ss-bg-card);\n border: 1px solid var(--ss-border);\n}\n\n.eventBadge[data-variant=\"failed\"] {\n color: var(--ss-error);\n background-color: var(--ss-error-bg);\n}\n\n.eventBadge[data-variant=\"skipped\"] {\n color: var(--ss-text-muted);\n background-color: var(--ss-bg-card);\n}\n\n@media (max-width: 640px) {\n .overlay {\n padding: 0;\n }\n\n .dialog {\n width: 100%;\n height: 100%;\n border: none;\n border-radius: 0;\n }\n\n .header {\n flex-wrap: wrap;\n gap: 0.5rem;\n padding: 0.6rem 0.75rem;\n padding-top: max(0.6rem, env(safe-area-inset-top));\n }\n\n .headerRight {\n flex: 1;\n justify-content: flex-end;\n min-width: 0;\n }\n\n .instancePickerLabel {\n min-width: 0;\n }\n\n .instancePickerSelect {\n min-width: 0;\n max-width: 100%;\n }\n\n .instanceCountBadge {\n display: none;\n }\n\n .closeButton {\n flex-shrink: 0;\n width: 36px;\n height: 36px;\n }\n\n .contentLayout {\n grid-template-columns: minmax(0, 1fr);\n grid-template-rows: auto minmax(0, 1fr);\n }\n\n .sidebar {\n padding: 0.4rem 0.5rem;\n border-right: none;\n border-bottom: 1px solid var(--ss-border);\n overflow-x: auto;\n overflow-y: hidden;\n }\n\n .nav {\n flex-direction: row;\n margin-bottom: 0;\n }\n\n .tabButton {\n width: auto;\n flex-shrink: 0;\n white-space: nowrap;\n border-left: none;\n border-bottom: 2px solid transparent;\n }\n\n .tabButton[data-active=\"true\"] {\n border-left: none;\n border-bottom: 2px solid var(--ss-teal);\n }\n\n .sidebarInfo {\n display: none;\n }\n\n .mainPane {\n padding: 0.75rem;\n padding-bottom: max(0.75rem, env(safe-area-inset-bottom));\n }\n\n .liveQueryHeaderRow,\n .liveQueryRow {\n grid-template-columns: minmax(0, 1fr) minmax(0, 0.6fr) 6.5rem;\n }\n\n .liveQueryHeaderRow .schemaColHeader,\n .liveQuerySql,\n .liveQueryParameters {\n padding-left: 0.5rem;\n padding-right: 0.5rem;\n }\n\n .liveQueryHeaderRow .schemaColHeader {\n letter-spacing: 0.02em;\n }\n}\n\n@media (hover: none) {\n .hideLauncherButton {\n display: none;\n }\n}\n","import { type ReactNode, useLayoutEffect, useRef, useState } from \"react\";\nimport { createPortal } from \"react-dom\";\nimport cssText from \"./devtools.css?inline\";\n\nexport function ShadowRoot({ children, className }: { children: ReactNode; className?: string }) {\n const hostRef = useRef<HTMLDivElement>(null);\n const [shadowRoot, setShadowRoot] = useState<ShadowRoot | null>(null);\n\n useLayoutEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n setShadowRoot(host.shadowRoot ?? host.attachShadow({ mode: \"open\" }));\n }, []);\n\n return (\n <div ref={hostRef} className={className}>\n {shadowRoot\n ? createPortal(\n <>\n <style>{cssText}</style>\n {children}\n </>,\n shadowRoot,\n )\n : null}\n </div>\n );\n}\n","import type { ColumnMeta, SharedLiveQuerySnapshot, SyncedDbExport } from \"@sqlite-sync/core\";\nimport type { CSSProperties, PointerEvent as ReactPointerEvent } from \"react\";\nimport { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from \"react\";\nimport {\n getOrCreateSQLiteSyncDevtoolsRegistry,\n type SQLiteSyncDevtoolsInstance,\n type SQLiteSyncDevtoolsSnapshot,\n} from \"./devtools-registry\";\nimport { ShadowRoot } from \"./shadow-root\";\n\nexport type SQLiteSyncDevtoolsProps = {\n className?: string;\n /** Render the floating launcher button. Set to `false` to open the dialog only via `open`. Defaults to `true`. */\n launcher?: boolean;\n /** Hide the floating launcher. Omit to let the user toggle it with Ctrl+Alt+S (⌘⌥S on macOS). */\n hidden?: boolean;\n onHiddenChange?: (hidden: boolean) => void;\n /** Control whether the devtools dialog is open. Omit to let the launcher manage it. */\n open?: boolean;\n onOpenChange?: (open: boolean) => void;\n};\n\ntype DevtoolsTab = \"overview\" | \"schema\" | \"live-queries\" | \"event-log\" | \"query-runner\";\ntype QueryTarget = \"memory\" | \"worker\";\n\ntype QueryState =\n | {\n status: \"idle\";\n }\n | {\n status: \"running\";\n }\n | {\n status: \"success\";\n output: {\n target: QueryTarget;\n sql: string;\n rowCount: number;\n durationMs: number;\n rows: unknown[];\n };\n }\n | {\n status: \"error\";\n error: {\n target: QueryTarget;\n sql: string;\n message: string;\n };\n };\n\nconst TRIGGER_POSITION_STORAGE_KEY = \"sqlite-sync-devtools.trigger-position\";\nconst TRIGGER_HIDDEN_STORAGE_KEY = \"sqlite-sync-devtools.trigger-hidden\";\nconst DRAG_THRESHOLD_PX = 4;\nconst VIEWPORT_MARGIN_PX = 8;\nconst IS_APPLE_PLATFORM = typeof navigator !== \"undefined\" && /Mac|iPhone|iPad/.test(navigator.platform);\nconst TOGGLE_LAUNCHER_HINT = IS_APPLE_PLATFORM ? \"⌘⌥S\" : \"Ctrl+Alt+S\";\n\ntype TriggerPosition = { x: number; y: number };\n\nfunction readStoredTriggerPosition(): TriggerPosition | null {\n if (typeof window === \"undefined\") return null;\n try {\n const raw = window.localStorage.getItem(TRIGGER_POSITION_STORAGE_KEY);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as Partial<TriggerPosition>;\n if (typeof parsed.x === \"number\" && typeof parsed.y === \"number\") {\n return { x: parsed.x, y: parsed.y };\n }\n } catch {}\n return null;\n}\n\nfunction clampTriggerPosition(position: TriggerPosition, button: HTMLElement): TriggerPosition {\n const maxX = window.innerWidth - button.offsetWidth - VIEWPORT_MARGIN_PX;\n const maxY = window.innerHeight - button.offsetHeight - VIEWPORT_MARGIN_PX;\n return {\n x: Math.max(VIEWPORT_MARGIN_PX, Math.min(position.x, maxX)),\n y: Math.max(VIEWPORT_MARGIN_PX, Math.min(position.y, maxY)),\n };\n}\n\nfunction useDraggableTrigger() {\n const buttonRef = useRef<HTMLButtonElement>(null);\n const [position, setPosition] = useState<TriggerPosition | null>(readStoredTriggerPosition);\n const dragRef = useRef<{\n pointerId: number;\n startX: number;\n startY: number;\n offsetX: number;\n offsetY: number;\n moved: boolean;\n } | null>(null);\n // pointerup clears dragRef before the click event fires, so the moved flag is\n // stashed here to suppress the click that a drag gesture would otherwise emit.\n const suppressClickRef = useRef(false);\n\n const onPointerDown = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const button = buttonRef.current;\n if (!button || event.button !== 0) return;\n suppressClickRef.current = false;\n const rect = button.getBoundingClientRect();\n dragRef.current = {\n pointerId: event.pointerId,\n startX: event.clientX,\n startY: event.clientY,\n offsetX: event.clientX - rect.left,\n offsetY: event.clientY - rect.top,\n moved: false,\n };\n button.setPointerCapture(event.pointerId);\n }, []);\n\n const clampToViewport = useCallback(() => {\n const button = buttonRef.current;\n if (!button) return;\n setPosition((current) => {\n if (!current) return current;\n const next = clampTriggerPosition(current, button);\n return next.x === current.x && next.y === current.y ? current : next;\n });\n }, []);\n\n const setButtonRef = useCallback(\n (button: HTMLButtonElement | null) => {\n buttonRef.current = button;\n clampToViewport();\n },\n [clampToViewport],\n );\n\n useEffect(() => {\n window.addEventListener(\"resize\", clampToViewport);\n return () => window.removeEventListener(\"resize\", clampToViewport);\n }, [clampToViewport]);\n\n const onPointerMove = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const drag = dragRef.current;\n const button = buttonRef.current;\n if (!drag || !button || drag.pointerId !== event.pointerId) return;\n if (!drag.moved && Math.hypot(event.clientX - drag.startX, event.clientY - drag.startY) < DRAG_THRESHOLD_PX) {\n return;\n }\n drag.moved = true;\n setPosition(clampTriggerPosition({ x: event.clientX - drag.offsetX, y: event.clientY - drag.offsetY }, button));\n }, []);\n\n const endDrag = useCallback((event: ReactPointerEvent<HTMLButtonElement>) => {\n const drag = dragRef.current;\n if (!drag || drag.pointerId !== event.pointerId) return;\n dragRef.current = null;\n buttonRef.current?.releasePointerCapture(event.pointerId);\n if (!drag.moved) return;\n suppressClickRef.current = true;\n setPosition((current) => {\n if (current && typeof window !== \"undefined\") {\n try {\n window.localStorage.setItem(TRIGGER_POSITION_STORAGE_KEY, JSON.stringify(current));\n } catch {}\n }\n return current;\n });\n }, []);\n\n const consumeDragClick = useCallback(() => {\n if (!suppressClickRef.current) return false;\n suppressClickRef.current = false;\n return true;\n }, []);\n\n const positionStyle: CSSProperties = position\n ? { left: position.x, top: position.y, right: \"auto\", bottom: \"auto\" }\n : {};\n\n return {\n buttonRef: setButtonRef,\n positionStyle,\n triggerHandlers: { onPointerDown, onPointerMove, onPointerUp: endDrag, onPointerCancel: endDrag },\n consumeDragClick,\n };\n}\n\nfunction readStoredTriggerHidden(): boolean {\n if (typeof window === \"undefined\") return false;\n try {\n return window.localStorage.getItem(TRIGGER_HIDDEN_STORAGE_KEY) === \"1\";\n } catch {\n return false;\n }\n}\n\nfunction isToggleLauncherShortcut(event: KeyboardEvent): boolean {\n // Option/Alt remaps event.key (Option+S is \"ß\" on US Mac), so match the physical key.\n if (event.shiftKey || !event.altKey || event.code !== \"KeyS\") return false;\n return event.ctrlKey || event.metaKey;\n}\n\nfunction useLauncherVisibility({\n launcher,\n hidden: hiddenProp,\n onHiddenChange,\n onHide,\n}: Pick<SQLiteSyncDevtoolsProps, \"hidden\" | \"onHiddenChange\"> & { launcher: boolean; onHide: () => void }) {\n const isControlled = hiddenProp !== undefined;\n const [uncontrolledHidden, setUncontrolledHidden] = useState(readStoredTriggerHidden);\n const hidden = !launcher || (isControlled ? hiddenProp : uncontrolledHidden);\n const canToggle = launcher && (!isControlled || onHiddenChange !== undefined);\n\n const setHidden = useCallback(\n (next: boolean) => {\n if (next) onHide();\n if (isControlled) {\n onHiddenChange?.(next);\n return;\n }\n setUncontrolledHidden(next);\n try {\n window.localStorage.setItem(TRIGGER_HIDDEN_STORAGE_KEY, next ? \"1\" : \"0\");\n } catch {}\n },\n [isControlled, onHiddenChange, onHide],\n );\n\n useEffect(() => {\n if (!canToggle) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (!isToggleLauncherShortcut(event)) return;\n event.preventDefault();\n setHidden(!hidden);\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => window.removeEventListener(\"keydown\", onKeyDown);\n }, [canToggle, hidden, setHidden]);\n\n return { hidden, setHidden, canToggle };\n}\n\nfunction useOpenState({ open: openProp, onOpenChange }: Pick<SQLiteSyncDevtoolsProps, \"open\" | \"onOpenChange\">) {\n const isControlled = openProp !== undefined;\n const [uncontrolledOpen, setUncontrolledOpen] = useState(false);\n const isOpen = isControlled ? openProp : uncontrolledOpen;\n\n const setIsOpen = useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange],\n );\n\n return { isOpen, setIsOpen };\n}\n\nexport function SQLiteSyncDevtools({\n className,\n launcher = true,\n hidden: hiddenProp,\n onHiddenChange,\n open: openProp,\n onOpenChange,\n}: SQLiteSyncDevtoolsProps) {\n const registry = getOrCreateSQLiteSyncDevtoolsRegistry();\n const snapshot = useSyncExternalStore(registry.subscribe, registry.getSnapshot, getEmptySnapshot);\n const instances = snapshot.instances;\n\n const { buttonRef, positionStyle, triggerHandlers, consumeDragClick } = useDraggableTrigger();\n const { isOpen, setIsOpen } = useOpenState({ open: openProp, onOpenChange });\n const closeDialog = useCallback(() => setIsOpen(false), [setIsOpen]);\n const { hidden, setHidden, canToggle } = useLauncherVisibility({\n launcher,\n hidden: hiddenProp,\n onHiddenChange,\n onHide: closeDialog,\n });\n\n const [activeTab, setActiveTab] = useState<DevtoolsTab>(\"overview\");\n const [selectedInstanceId, setSelectedInstanceId] = useState<string>(\"\");\n const [queryTarget, setQueryTarget] = useState<QueryTarget>(\"memory\");\n const [query, setQuery] = useState(\"\");\n const [queryState, setQueryState] = useState<QueryState>({\n status: \"idle\",\n });\n\n useEffect(() => {\n if (!isOpen) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key === \"Escape\") {\n closeDialog();\n }\n };\n\n window.addEventListener(\"keydown\", onKeyDown);\n return () => {\n window.removeEventListener(\"keydown\", onKeyDown);\n };\n }, [isOpen, closeDialog]);\n\n useEffect(() => {\n if (instances.length === 0) {\n setSelectedInstanceId(\"\");\n return;\n }\n\n if (instances.some((instance) => instance.instanceId === selectedInstanceId)) {\n return;\n }\n\n setSelectedInstanceId(instances[0]?.instanceId ?? \"\");\n }, [instances, selectedInstanceId]);\n\n const dbIdCounts = useMemo(() => {\n const counts = new Map<string, number>();\n\n for (const instance of instances) {\n counts.set(instance.dbId, (counts.get(instance.dbId) ?? 0) + 1);\n }\n\n return counts;\n }, [instances]);\n\n const selectedInstance = useMemo(() => {\n return instances.find((instance) => instance.instanceId === selectedInstanceId) ?? null;\n }, [instances, selectedInstanceId]);\n\n const canRunQuery = selectedInstance !== null && query.trim().length > 0 && queryState.status !== \"running\";\n\n const runQuery = async () => {\n if (!selectedInstance) return;\n\n let normalizedQuery = query.trim();\n\n try {\n normalizedQuery = normalizeSingleStatement(query);\n const statementKind = getStatementKind(normalizedQuery);\n\n if (queryTarget === \"worker\") {\n if (!isWorkerReadOnlyStatement(statementKind)) {\n throw new Error(\"Worker DB devtools only allows read-only SQL: SELECT, PRAGMA.\");\n }\n } else {\n const touchedTables = selectedInstance.instance._internal.getMemoryQueryTables(normalizedQuery);\n const writtenTables = touchedTables.filter((table) => table.isWrite).map((table) => table.name);\n const allowedTables = new Set(selectedInstance.instance._internal.crdtTableNames);\n\n const invalidTables = writtenTables.filter((table) => !allowedTables.has(table));\n if (invalidTables.length > 0) {\n throw new Error(\n `Memory DB writes are only allowed for CRDT tables. Rejected tables: ${invalidTables.join(\", \")}`,\n );\n }\n }\n\n setQueryState({ status: \"running\" });\n const startedAt = performance.now();\n\n const result =\n queryTarget === \"memory\"\n ? selectedInstance.instance.db.execute(normalizedQuery)\n : await selectedInstance.instance._internal.executeAsync({\n sql: normalizedQuery,\n parameters: [],\n });\n\n setQueryState({\n status: \"success\",\n output: {\n target: queryTarget,\n sql: normalizedQuery,\n rowCount: result.rows.length,\n durationMs: Number((performance.now() - startedAt).toFixed(2)),\n rows: result.rows,\n },\n });\n } catch (error) {\n setQueryState({\n status: \"error\",\n error: {\n target: queryTarget,\n sql: normalizedQuery,\n message: error instanceof Error ? error.message : String(error),\n },\n });\n }\n };\n\n return (\n <ShadowRoot className={className}>\n {hidden ? null : (\n <div className=\"floatingRoot\">\n <button\n ref={buttonRef}\n type=\"button\"\n className=\"triggerButton\"\n style={positionStyle}\n onClick={() => {\n if (consumeDragClick()) return;\n setIsOpen(true);\n }}\n title={`SQLite Sync Devtools (${TOGGLE_LAUNCHER_HINT} to hide)`}\n {...triggerHandlers}\n >\n <span className=\"triggerIcon\">◈</span>\n <span className=\"triggerCount\">{instances.length}</span>\n </button>\n </div>\n )}\n\n {isOpen ? (\n <div className=\"overlay\" onClick={closeDialog}>\n <section\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"SQLite Sync devtools\"\n className=\"dialog\"\n onClick={(event) => event.stopPropagation()}\n >\n {/* Dialog header */}\n <div className=\"header\">\n <div className=\"headerLeft\">\n <span className=\"headerLogo\">◈</span>\n <div>\n <div className=\"eyebrow\">sqlite-sync</div>\n <h2 className=\"title\">Devtools</h2>\n </div>\n </div>\n\n <div className=\"headerRight\">\n {instances.length > 0 && (\n <label className=\"instancePickerLabel\">\n <span className=\"instancePickerText\">DB</span>\n <select\n value={selectedInstanceId}\n onChange={(event) => setSelectedInstanceId(event.target.value)}\n className=\"instancePickerSelect\"\n >\n {instances.map((instance) => (\n <option key={instance.instanceId} value={instance.instanceId}>\n {formatInstanceLabel(instance.dbId, instance.instanceId, dbIdCounts.get(instance.dbId) ?? 0)}\n </option>\n ))}\n </select>\n </label>\n )}\n <span className=\"instanceCountBadge\">\n {instances.length} instance{instances.length !== 1 ? \"s\" : \"\"}\n </span>\n {canToggle && (\n <button\n type=\"button\"\n className=\"hideLauncherButton\"\n onClick={() => setHidden(true)}\n title={`Hide launcher (${TOGGLE_LAUNCHER_HINT} to show again)`}\n >\n Hide\n </button>\n )}\n <button type=\"button\" className=\"closeButton\" onClick={closeDialog} aria-label=\"Close\">\n ✕\n </button>\n </div>\n </div>\n\n {instances.length === 0 ? (\n <div className=\"emptyState\">\n <div className=\"emptyStateIcon\">◈</div>\n <p className=\"emptyStateText\">No SQLite Sync database instances registered.</p>\n <p className=\"emptyStateSubtext\">\n Call <code className=\"inlineCode\">registerDevtools(db)</code> in your app to get started.\n </p>\n </div>\n ) : (\n <div className=\"contentLayout\">\n {/* Sidebar nav */}\n <aside className=\"sidebar\">\n <nav className=\"nav\">\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"overview\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"overview\")}\n >\n <span className=\"navIcon\">▦</span>\n Overview\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"schema\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"schema\")}\n >\n <span className=\"navIcon\">⬡</span>\n Schema\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"live-queries\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"live-queries\")}\n >\n <span className=\"navIcon\">◉</span>\n Live Queries\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"event-log\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"event-log\")}\n >\n <span className=\"navIcon\">≡</span>\n Event Log\n </button>\n <button\n type=\"button\"\n className=\"tabButton\"\n data-active={activeTab === \"query-runner\" ? \"true\" : undefined}\n onClick={() => setActiveTab(\"query-runner\")}\n >\n <span className=\"navIcon\">▶</span>\n Query Runner\n </button>\n </nav>\n\n {selectedInstance && (\n <div className=\"sidebarInfo\">\n <div className=\"sidebarInfoLabel\">Active instance</div>\n <div className=\"sidebarInfoValue\">\n {formatInstanceLabel(\n selectedInstance.dbId,\n selectedInstance.instanceId,\n dbIdCounts.get(selectedInstance.dbId) ?? 0,\n )}\n </div>\n <div className=\"sidebarInfoSub\">id: {selectedInstance.instanceId.slice(0, 12)}…</div>\n </div>\n )}\n </aside>\n\n {/* Main pane */}\n <div className=\"mainPane\">\n {activeTab === \"overview\" ? (\n <OverviewTab selectedInstance={selectedInstance} dbIdCounts={dbIdCounts} />\n ) : activeTab === \"schema\" ? (\n <SchemaTab selectedInstance={selectedInstance} />\n ) : activeTab === \"live-queries\" ? (\n <LiveQueriesTab selectedInstance={selectedInstance} />\n ) : activeTab === \"event-log\" ? (\n <EventLogTab selectedInstance={selectedInstance} />\n ) : (\n <QueryRunnerTab\n selectedInstance={selectedInstance}\n queryTarget={queryTarget}\n setQueryTarget={setQueryTarget}\n query={query}\n setQuery={setQuery}\n queryState={queryState}\n canRunQuery={canRunQuery}\n runQuery={runQuery}\n />\n )}\n </div>\n </div>\n )}\n </section>\n </div>\n ) : null}\n </ShadowRoot>\n );\n}\n\nconst STATE_HASH_KV_KEY = \"crdt.consistency.state_hash.v1\";\nconst STATE_HASH_QUERY = `SELECT value FROM \"worker\".\"kv\" WHERE key = '${STATE_HASH_KV_KEY}'`;\nconst EVENT_STATUS_COUNTS_QUERY = `SELECT status, COUNT(*) AS count FROM \"worker\".\"crdt_events\" GROUP BY status`;\nconst MEMORY_DB_SIZE_QUERY =\n \"SELECT (SELECT page_count FROM pragma_page_count()) * (SELECT page_size FROM pragma_page_size()) AS bytes\";\n// Persisted main file plus the attached worker schema (event log, kv).\nconst WORKER_DB_SIZE_QUERY = `SELECT\n (SELECT page_count FROM pragma_page_count('main')) * (SELECT page_size FROM pragma_page_size('main'))\n + (SELECT page_count FROM pragma_page_count('worker')) * (SELECT page_size FROM pragma_page_size('worker'))\n AS bytes`;\n\ntype EventStatus = \"pending\" | \"applied\" | \"failed\" | \"deduped\";\ntype EventStatusCounts = { total: number } & Record<EventStatus, number>;\n\nconst EVENT_STATUS_META: Record<EventStatus, { label: string; tone: \"amber\" | \"success\" | \"error\" | \"muted\" }> = {\n pending: { label: \"Pending\", tone: \"amber\" },\n applied: { label: \"Applied\", tone: \"success\" },\n failed: { label: \"Failed\", tone: \"error\" },\n deduped: { label: \"Deduped\", tone: \"muted\" },\n};\n\nfunction isEventStatus(value: unknown): value is EventStatus {\n return value === \"pending\" || value === \"applied\" || value === \"failed\" || value === \"deduped\";\n}\n\nfunction emptyEventStatusCounts(): EventStatusCounts {\n return { total: 0, pending: 0, applied: 0, failed: 0, deduped: 0 };\n}\n\nfunction parseEventStatusCounts(rows: readonly unknown[]): EventStatusCounts {\n const counts = emptyEventStatusCounts();\n\n for (const row of rows) {\n if (typeof row !== \"object\" || row === null || !(\"status\" in row) || !(\"count\" in row)) {\n continue;\n }\n const { status, count } = row;\n if (!isEventStatus(status)) continue;\n const n = typeof count === \"number\" ? count : Number(count);\n if (!Number.isFinite(n)) continue;\n counts[status] = n;\n counts.total += n;\n }\n\n return counts;\n}\n\nfunction readCount(rows: readonly unknown[]): number {\n const row = rows[0];\n if (typeof row !== \"object\" || row === null || !(\"count\" in row)) return 0;\n const n = typeof row.count === \"number\" ? row.count : Number(row.count);\n return Number.isFinite(n) ? n : 0;\n}\n\nfunction readBytes(rows: readonly unknown[]): number | null {\n const row = rows[0];\n if (typeof row !== \"object\" || row === null || !(\"bytes\" in row)) return null;\n const n = typeof row.bytes === \"number\" ? row.bytes : Number(row.bytes);\n return Number.isFinite(n) ? n : null;\n}\n\nfunction formatByteSize(bytes: number): { label: string; exact: string } {\n const exact = `${bytes.toLocaleString(\"en-US\")} B`;\n if (bytes < 1024) return { label: exact, exact };\n\n const units = [\"KB\", \"MB\", \"GB\", \"TB\"] as const;\n let value = bytes / 1024;\n let unitIndex = 0;\n while (value >= 1024 && unitIndex < units.length - 1) {\n value /= 1024;\n unitIndex += 1;\n }\n const decimals = value >= 100 ? 0 : value >= 10 ? 1 : 2;\n return { label: `${Number(value.toFixed(decimals))} ${units[unitIndex]}`, exact };\n}\n\nfunction OverviewTab({\n selectedInstance,\n dbIdCounts,\n}: {\n selectedInstance: SQLiteSyncDevtoolsInstance | null;\n dbIdCounts: Map<string, number>;\n}) {\n const [stateHash, setStateHash] = useState<string | null>(null);\n const [stateHashError, setStateHashError] = useState<string | null>(null);\n const [isStateHashLoading, setIsStateHashLoading] = useState(false);\n const [eventCounts, setEventCounts] = useState<EventStatusCounts | null>(null);\n const [eventCountsError, setEventCountsError] = useState<string | null>(null);\n const [isEventCountsLoading, setIsEventCountsLoading] = useState(false);\n const [memoryBytes, setMemoryBytes] = useState<number | null>(null);\n const [memorySizeError, setMemorySizeError] = useState<string | null>(null);\n const [workerBytes, setWorkerBytes] = useState<number | null>(null);\n const [workerSizeError, setWorkerSizeError] = useState<string | null>(null);\n const [isSizeLoading, setIsSizeLoading] = useState(false);\n\n const refreshStateHash = useCallback(async () => {\n if (!selectedInstance) return;\n setIsStateHashLoading(true);\n setStateHashError(null);\n try {\n const result = await selectedInstance.instance._internal.executeAsync({\n sql: STATE_HASH_QUERY,\n parameters: [],\n });\n const row = result.rows[0];\n const value =\n typeof row === \"object\" && row !== null && \"value\" in row && typeof row.value === \"string\" ? row.value : \"\";\n setStateHash(value);\n } catch (error) {\n setStateHashError(error instanceof Error ? error.message : String(error));\n setStateHash(null);\n } finally {\n setIsStateHashLoading(false);\n }\n }, [selectedInstance]);\n\n const refreshEventCounts = useCallback(async () => {\n if (!selectedInstance) return;\n setIsEventCountsLoading(true);\n setEventCountsError(null);\n try {\n const result = await selectedInstance.instance._internal.executeAsync({\n sql: EVENT_STATUS_COUNTS_QUERY,\n parameters: [],\n });\n setEventCounts(parseEventStatusCounts(result.rows));\n } catch (error) {\n setEventCountsError(error instanceof Error ? error.message : String(error));\n setEventCounts(null);\n } finally {\n setIsEventCountsLoading(false);\n }\n }, [selectedInstance]);\n\n const refreshDbSizes = useCallback(async () => {\n if (!selectedInstance) return;\n setIsSizeLoading(true);\n setMemorySizeError(null);\n setWorkerSizeError(null);\n\n const memoryResult = Promise.resolve()\n .then(() => selectedInstance.instance.db.execute(MEMORY_DB_SIZE_QUERY))\n .then((result) => {\n const bytes = readBytes(result.rows);\n if (bytes === null) throw new Error(\"Memory DB did not return a size.\");\n return bytes;\n });\n const workerResult = selectedInstance.instance._internal\n .executeAsync({ sql: WORKER_DB_SIZE_QUERY, parameters: [] })\n .then((result) => {\n const bytes = readBytes(result.rows);\n if (bytes === null) throw new Error(\"Worker DB did not return a size.\");\n return bytes;\n });\n\n const [memorySettled, workerSettled] = await Promise.allSettled([memoryResult, workerResult]);\n if (memorySettled.status === \"fulfilled\") {\n setMemoryBytes(memorySettled.value);\n } else {\n setMemoryBytes(null);\n setMemorySizeError(\n memorySettled.reason instanceof Error ? memorySettled.reason.message : String(memorySettled.reason),\n );\n }\n if (workerSettled.status === \"fulfilled\") {\n setWorkerBytes(workerSettled.value);\n } else {\n setWorkerBytes(null);\n setWorkerSizeError(\n workerSettled.reason instanceof Error ? workerSettled.reason.message : String(workerSettled.reason),\n );\n }\n setIsSizeLoading(false);\n }, [selectedInstance]);\n\n useEffect(() => {\n setStateHash(null);\n setStateHashError(null);\n setEventCounts(null);\n setEventCountsError(null);\n setMemoryBytes(null);\n setMemorySizeError(null);\n setWorkerBytes(null);\n setWorkerSizeError(null);\n void refreshStateHash();\n void refreshEventCounts();\n void refreshDbSizes();\n }, [refreshStateHash, refreshEventCounts, refreshDbSizes]);\n\n if (!selectedInstance) return null;\n\n const label = formatInstanceLabel(\n selectedInstance.dbId,\n selectedInstance.instanceId,\n dbIdCounts.get(selectedInstance.dbId) ?? 0,\n );\n\n return (\n <div className=\"overviewLayout\">\n <div className=\"overviewCardsRow\">\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">Database</div>\n <div className=\"overviewCardValue\">{label}</div>\n </div>\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">Instance ID</div>\n <div className=\"overviewCardValue mono sm\">{selectedInstance.instanceId.slice(0, 16)}…</div>\n </div>\n <DbSizeCard label=\"Memory DB\" bytes={memoryBytes} error={memorySizeError} loading={isSizeLoading} />\n <DbSizeCard label=\"Worker DB\" bytes={workerBytes} error={workerSizeError} loading={isSizeLoading} />\n <div className=\"overviewCard\">\n <div className=\"overviewCardLabel\">CRDT Events</div>\n <div className=\"overviewCardValue\">\n {eventCountsError ? \"—\" : isEventCountsLoading && eventCounts === null ? \"…\" : (eventCounts?.total ?? 0)}\n </div>\n </div>\n </div>\n\n <div className=\"overviewSection\">\n <div className=\"overviewSectionHeader\">\n <div className=\"overviewSectionTitle\">CRDT events</div>\n <button\n type=\"button\"\n className=\"refreshButton\"\n disabled={isEventCountsLoading || isSizeLoading}\n title=\"Refresh event counts and DB sizes\"\n onClick={() => {\n void refreshEventCounts();\n void refreshDbSizes();\n }}\n >\n {isEventCountsLoading || isSizeLoading ? \"…\" : \"↻\"} Refresh\n </button>\n </div>\n {eventCountsError ? (\n <div className=\"overviewAccumulatorError\">{eventCountsError}</div>\n ) : (\n <div className=\"eventCountGrid\">\n {([\"pending\", \"applied\", \"failed\", \"deduped\"] satisfies EventStatus[]).map((status) => {\n const item = EVENT_STATUS_META[status];\n const value = eventCounts?.[status] ?? 0;\n return (\n <div key={status} className=\"eventCountCard\">\n <div\n className=\"eventCountValue\"\n data-tone={item.tone}\n data-emphasize={value > 0 ? \"true\" : undefined}\n >\n {isEventCountsLoading && eventCounts === null ? \"…\" : value}\n </div>\n <div className=\"overviewCardLabel\">{item.label}</div>\n </div>\n );\n })}\n </div>\n )}\n <div className=\"overviewEmpty\">Counts are remaining worker log rows after GC, not lifetime history.</div>\n </div>\n\n <div className=\"overviewSection\">\n <div className=\"overviewSectionHeader\">\n <div className=\"overviewSectionTitle\">State hash</div>\n <button\n type=\"button\"\n className=\"refreshButton\"\n disabled={isStateHashLoading}\n onClick={() => void refreshStateHash()}\n >\n {isStateHashLoading ? \"…\" : \"↻\"} Refresh\n </button>\n </div>\n <div className=\"overviewAccumulatorValue\">\n {stateHashError ? (\n <span className=\"overviewAccumulatorError\">{stateHashError}</span>\n ) : isStateHashLoading && stateHash === null ? (\n \"Loading…\"\n ) : stateHash === \"\" ? (\n <span className=\"overviewAccumulatorEmpty\">(empty)</span>\n ) : (\n stateHash\n )}\n </div>\n </div>\n\n <DataSection\n key={selectedInstance.instanceId}\n dbId={selectedInstance.dbId}\n instance={selectedInstance.instance}\n />\n\n <ResetSection dbId={selectedInstance.dbId} instance={selectedInstance.instance} />\n </div>\n );\n}\n\nfunction DbSizeCard({\n label,\n bytes,\n error,\n loading,\n}: {\n label: string;\n bytes: number | null;\n error: string | null;\n loading: boolean;\n}) {\n let value = \"…\";\n let sub: string | undefined;\n let title: string | undefined;\n\n if (error) {\n value = \"—\";\n title = error;\n } else if (bytes !== null) {\n const formatted = formatByteSize(bytes);\n value = formatted.label;\n title = formatted.exact;\n sub = formatted.label === formatted.exact ? undefined : formatted.exact;\n } else if (!loading) {\n value = \"—\";\n }\n\n return (\n <div className=\"overviewCard\" title={title}>\n <div className=\"overviewCardLabel\">{label}</div>\n <div className=\"overviewCardValue mono\">{value}</div>\n {sub ? <div className=\"overviewCardSub\">{sub}</div> : null}\n </div>\n );\n}\n\nfunction DataSection({ dbId, instance }: { dbId: string; instance: SQLiteSyncDevtoolsInstance[\"instance\"] }) {\n const fileInputRef = useRef<HTMLInputElement>(null);\n const [isImporting, setIsImporting] = useState(false);\n const [status, setStatus] = useState<{ kind: \"success\" | \"error\"; message: string } | null>(null);\n\n const handleExport = () => {\n try {\n const data = instance.exportData();\n const json = JSON.stringify(data, null, 2);\n const blob = new Blob([json], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement(\"a\");\n anchor.href = url;\n anchor.download = `${dbId}-${data.exportedAt.replace(/[:.]/g, \"-\")}.json`;\n anchor.click();\n URL.revokeObjectURL(url);\n const rowCount = Object.values(data.tables).reduce((sum, rows) => sum + rows.length, 0);\n setStatus({ kind: \"success\", message: `Exported ${rowCount} row${rowCount === 1 ? \"\" : \"s\"}.` });\n } catch (error) {\n setStatus({ kind: \"error\", message: error instanceof Error ? error.message : String(error) });\n }\n };\n\n const handleImportFile = async (file: File) => {\n setIsImporting(true);\n setStatus(null);\n try {\n const data = JSON.parse(await file.text()) as SyncedDbExport;\n const result = await instance.importData(data);\n setStatus({ kind: \"success\", message: `Imported ${result.imported} row${result.imported === 1 ? \"\" : \"s\"}.` });\n } catch (error) {\n setStatus({ kind: \"error\", message: error instanceof Error ? error.message : String(error) });\n } finally {\n setIsImporting(false);\n }\n };\n\n return (\n <div className=\"overviewSection\">\n <div className=\"overviewSectionTitle\">Backup &amp; Restore</div>\n <div className=\"dangerZoneDesc\">\n Export the active rows of every CRDT table as JSON, or import a dump to seed/restore. Import overwrites rows\n with matching ids and is propagated to the server.\n </div>\n <div className=\"dataActions\">\n <button type=\"button\" className=\"dataButton\" onClick={handleExport}>\n ↓ Export JSON\n </button>\n <button\n type=\"button\"\n className=\"dataButton\"\n disabled={isImporting}\n onClick={() => fileInputRef.current?.click()}\n >\n {isImporting ? \"Importing…\" : \"↑ Import JSON\"}\n </button>\n <input\n ref={fileInputRef}\n type=\"file\"\n accept=\"application/json,.json\"\n className=\"hiddenInput\"\n onChange={(event) => {\n const file = event.target.files?.[0];\n event.target.value = \"\";\n if (file) void handleImportFile(file);\n }}\n />\n </div>\n {status && (\n <div className={status.kind === \"error\" ? \"dataStatusError\" : \"dataStatusSuccess\"}>{status.message}</div>\n )}\n </div>\n );\n}\n\nfunction ResetSection({ dbId, instance }: { dbId: string; instance: SQLiteSyncDevtoolsInstance[\"instance\"] }) {\n const [confirming, setConfirming] = useState(false);\n const [isResetting, setIsResetting] = useState(false);\n\n const handleReset = () => {\n setIsResetting(true);\n // Worker-owned clean reset: durably records a reset epoch, broadcasts a\n // reload to all tabs, and the next elected worker wipes the persisted DB.\n // The promise may never settle — the page unloads first.\n void instance.requestReload({ clean: true });\n };\n\n return (\n <div className=\"dangerZone\">\n <div className=\"dangerZoneTitle\">Danger Zone</div>\n <div className=\"dangerZoneRow\">\n <div className=\"dangerZoneDesc\">\n Requests a clean reload, so <code className=\"inlineCode\">{dbId}</code> is wiped on next load via{\" \"}\n <code className=\"inlineCode\">clearOnInit</code>, then reloads all tabs.\n </div>\n {confirming ? (\n <div className=\"dangerZoneActions\">\n <button\n type=\"button\"\n className=\"resetCancelButton\"\n disabled={isResetting}\n onClick={() => setConfirming(false)}\n >\n Cancel\n </button>\n <button type=\"button\" className=\"resetConfirmButton\" disabled={isResetting} onClick={handleReset}>\n {isResetting ? \"Resetting…\" : \"Confirm reset\"}\n </button>\n </div>\n ) : (\n <button type=\"button\" className=\"resetButton\" onClick={() => setConfirming(true)}>\n Reset DB\n </button>\n )}\n </div>\n </div>\n );\n}\n\nconst SYSTEM_COLUMNS = new Set([\"id\", \"tombstone\"]);\n\nfunction formatDefaultValue(value: unknown): string {\n if (typeof value === \"string\") return JSON.stringify(value);\n if (typeof value === \"boolean\" || typeof value === \"number\") return String(value);\n if (value === null) return \"null\";\n return JSON.stringify(value);\n}\n\nfunction SchemaTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n if (!selectedInstance) return null;\n\n const { tables, schemaVersion } = selectedInstance.instance._internal;\n const tableEntries = Object.entries(tables);\n\n return (\n <div className=\"schemaLayout\">\n <div className=\"schemaSection\">\n <div className=\"schemaSectionHeader\">\n <div className=\"schemaSectionTitle\">Tables</div>\n <span className=\"schemaBadge\">{tableEntries.length}</span>\n <span className=\"schemaVersionChip mlAuto\" title=\"Latest applied migration version\">\n applied v{schemaVersion}\n </span>\n </div>\n {tableEntries.length === 0 ? (\n <div className=\"schemaEmpty\">No tables declared on this schema.</div>\n ) : (\n <div className=\"schemaTableList\">\n {tableEntries.map(([crdtTableName, table]) => {\n const baseTableName = table.baseName ?? `_${crdtTableName}`;\n const columns = Object.entries(table.columns);\n return (\n <div key={crdtTableName} className=\"schemaTableCard\">\n <div className=\"schemaTableCardHeader\">\n <div className=\"schemaTableCardTitleRow\">\n <div className=\"schemaTableCardName\">{crdtTableName}</div>\n <span className=\"schemaBadge\">{columns.length}</span>\n </div>\n {table.description ? <p className=\"schemaTableCardDescription\">{table.description}</p> : null}\n <div className=\"schemaTableCardMeta\">\n <span className=\"schemaPolicyChip\" title=\"Base table\">\n {baseTableName}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.writeOrigin === \"server\" ? \"warn\" : undefined}\n title=\"Who may write CRDT events\"\n >\n writes {table.writeOrigin}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.aiAccess === \"read-write\" ? undefined : \"warn\"}\n title=\"AI agent access\"\n >\n ai {table.aiAccess}\n </span>\n <span\n className=\"schemaPolicyChip\"\n data-tone={table.exportImport === \"ignore\" ? \"warn\" : undefined}\n title=\"Export / import\"\n >\n export {table.exportImport}\n </span>\n </div>\n </div>\n <div className=\"schemaColumnGrid\">\n <div className=\"schemaColumnRow schemaColumnHeaderRow\">\n <div className=\"schemaColHeader\">Column</div>\n <div className=\"schemaColHeader\">Type</div>\n <div className=\"schemaColHeader\">Flags</div>\n <div className=\"schemaColHeader\">Description</div>\n </div>\n {columns.map(([name, meta]) => (\n <SchemaColumnRow key={name} name={name} meta={meta} />\n ))}\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction SchemaColumnRow({ name, meta }: { name: string; meta: ColumnMeta }) {\n const flags: string[] = [];\n if (name === \"id\") flags.push(\"pk\");\n if (meta.nullable) flags.push(\"nullable\");\n if (meta.hasDefault) flags.push(`default ${formatDefaultValue(meta.defaultValue)}`);\n\n return (\n <div className=\"schemaColumnRow\" data-system={SYSTEM_COLUMNS.has(name) ? \"true\" : undefined}>\n <div className=\"schemaColumnName\">{name}</div>\n <div className=\"schemaColumnType\">\n <span>{meta.kind}</span>\n {meta.kind === \"boolean\" ? <span className=\"schemaColumnTypeDetail\">integer 0/1</span> : null}\n {meta.kind === \"enum\" && meta.enumValues && meta.enumValues.length > 0 ? (\n <span className=\"schemaColumnTypeDetail\">{meta.enumValues.map((value) => `\"${value}\"`).join(\" | \")}</span>\n ) : null}\n </div>\n <div className=\"schemaColumnFlags\">{flags.length > 0 ? flags.join(\" · \") : \"—\"}</div>\n <div className=\"schemaColumnDescription\">{meta.description ?? \"\"}</div>\n </div>\n );\n}\n\nfunction LiveQueriesTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n const [queries, setQueries] = useState<SharedLiveQuerySnapshot[]>([]);\n\n const refresh = useCallback(() => {\n if (!selectedInstance) {\n setQueries([]);\n return;\n }\n\n setQueries(\n selectedInstance.instance._internal\n .getSharedLiveQueriesSnapshot()\n .sort(\n (a, b) =>\n a.sql.localeCompare(b.sql) ||\n formatLiveQueryParameters(a.parameters).localeCompare(formatLiveQueryParameters(b.parameters)),\n ),\n );\n }, [selectedInstance]);\n\n useEffect(() => {\n refresh();\n }, [refresh]);\n\n const totalSubscribers = queries.reduce((total, query) => total + query.subscriberCount, 0);\n\n return (\n <div className=\"schemaLayout\">\n <div className=\"schemaSection\">\n <div className=\"schemaSectionHeader\">\n <div className=\"schemaSectionTitle\">Shared Live Queries</div>\n <span className=\"schemaBadge\">{queries.length}</span>\n <span className=\"schemaVersionChip\">\n {totalSubscribers} subscriber{totalSubscribers !== 1 ? \"s\" : \"\"}\n </span>\n <button type=\"button\" className=\"refreshButton mlAuto\" onClick={refresh} disabled={!selectedInstance}>\n ↻ Refresh\n </button>\n </div>\n {queries.length === 0 ? (\n <div className=\"schemaEmpty\">\n No active live queries. Queries created via <code className=\"inlineCode\">useDbQuery</code> appear here while\n components are subscribed.\n </div>\n ) : (\n <div className=\"schemaTableGrid\">\n <div className=\"liveQueryHeaderRow\">\n <div className=\"schemaColHeader\">SQL</div>\n <div className=\"schemaColHeader\">Parameters</div>\n <div className=\"schemaColHeader alignCenter\">Subscribers</div>\n </div>\n {queries.map((query) => {\n const parameters = formatLiveQueryParameters(query.parameters);\n return (\n <div key={`${query.sql}|${parameters}`} className=\"liveQueryRow\">\n <div className=\"liveQuerySql\">{query.sql}</div>\n <div className=\"liveQueryParameters\">{parameters}</div>\n <div className=\"schemaStatusCell\">\n <span className={query.subscriberCount > 0 ? \"schemaActiveTag\" : \"liveQueryIdleTag\"}>\n {query.subscriberCount}\n </span>\n </div>\n </div>\n );\n })}\n </div>\n )}\n </div>\n </div>\n );\n}\n\nfunction formatLiveQueryParameters(parameters: readonly unknown[]): string {\n try {\n return JSON.stringify(parameters);\n } catch {\n return String(parameters);\n }\n}\n\ntype PersistedCrdtEvent = {\n sync_id: number;\n schema_version: number;\n status: \"pending\" | \"applied\" | \"failed\" | \"deduped\";\n type: \"item-created\" | \"item-updated\" | \"item-deleted\";\n timestamp: string;\n origin: \"remote\" | \"own\" | \"local\";\n source_node_id: string;\n dataset: string;\n item_id: string;\n payload: string;\n};\n\nfunction isPersistedCrdtEvent(value: unknown): value is PersistedCrdtEvent {\n if (typeof value !== \"object\" || value === null) return false;\n return (\n \"sync_id\" in value &&\n typeof value.sync_id === \"number\" &&\n \"status\" in value &&\n typeof value.status === \"string\" &&\n \"type\" in value &&\n typeof value.type === \"string\" &&\n \"origin\" in value &&\n typeof value.origin === \"string\" &&\n \"dataset\" in value &&\n typeof value.dataset === \"string\" &&\n \"item_id\" in value &&\n typeof value.item_id === \"string\" &&\n \"payload\" in value &&\n typeof value.payload === \"string\" &&\n \"timestamp\" in value &&\n typeof value.timestamp === \"string\"\n );\n}\n\ntype EventLogFilters = {\n dataset: string;\n origin: string;\n status: string;\n};\n\nconst PAGE_SIZE = 50;\n\nfunction sqlStringLiteral(value: string): string {\n return `'${value.replaceAll(\"'\", \"''\")}'`;\n}\n\nfunction eventLogWhereClause(filters: EventLogFilters, afterSyncId: number | null): string {\n const conditions: string[] = [];\n\n if (filters.dataset) conditions.push(`dataset = ${sqlStringLiteral(filters.dataset)}`);\n if (filters.origin) conditions.push(`origin = ${sqlStringLiteral(filters.origin)}`);\n if (filters.status) conditions.push(`status = ${sqlStringLiteral(filters.status)}`);\n if (afterSyncId !== null) conditions.push(`sync_id < ${afterSyncId}`);\n\n return conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n}\n\nfunction buildEventLogQuery(filters: EventLogFilters, afterSyncId: number | null): string {\n return `SELECT * FROM \"worker\".\"crdt_events\" ${eventLogWhereClause(filters, afterSyncId)} ORDER BY sync_id DESC LIMIT ${PAGE_SIZE + 1}`;\n}\n\nfunction buildEventLogCountQuery(filters: EventLogFilters): string {\n return `SELECT COUNT(*) AS count FROM \"worker\".\"crdt_events\" ${eventLogWhereClause(filters, null)}`;\n}\n\nfunction EventLogTab({ selectedInstance }: { selectedInstance: SQLiteSyncDevtoolsInstance | null }) {\n const baseTableNames = useMemo(\n () => selectedInstance?.instance._internal.crdtTablesConfig.map((table) => table.baseTableName) ?? [],\n [selectedInstance],\n );\n\n const [filters, setFilters] = useState<EventLogFilters>({ dataset: \"\", origin: \"\", status: \"\" });\n const [events, setEvents] = useState<PersistedCrdtEvent[]>([]);\n const [totalCount, setTotalCount] = useState<number | null>(null);\n const [hasMore, setHasMore] = useState(false);\n const [isLoading, setIsLoading] = useState(false);\n const [expandedId, setExpandedId] = useState<number | null>(null);\n const afterSyncIdRef = useRef<number | null>(null);\n const isLoadingRef = useRef(false);\n\n const executeRows = useCallback(\n async (sql: string): Promise<unknown[]> => {\n if (!selectedInstance) return [];\n const result = await selectedInstance.instance._internal.executeAsync({ sql, parameters: [] });\n return result.rows;\n },\n [selectedInstance],\n );\n\n const load = useCallback(\n async (reset: boolean, currentFilters: EventLogFilters) => {\n if (!selectedInstance || isLoadingRef.current) return;\n isLoadingRef.current = true;\n setIsLoading(true);\n try {\n const afterSyncId = reset ? null : afterSyncIdRef.current;\n const sql = buildEventLogQuery(currentFilters, afterSyncId);\n const rowsPromise = executeRows(sql);\n const countPromise = reset ? executeRows(buildEventLogCountQuery(currentFilters)) : Promise.resolve(null);\n const [rows, countRows] = await Promise.all([rowsPromise, countPromise]);\n const page = rows.filter(isPersistedCrdtEvent).slice(0, PAGE_SIZE);\n setHasMore(rows.length > PAGE_SIZE);\n if (reset) {\n setEvents(page);\n setTotalCount(countRows ? readCount(countRows) : null);\n } else {\n setEvents((prev) => [...prev, ...page]);\n }\n afterSyncIdRef.current = page.at(-1)?.sync_id ?? null;\n } finally {\n isLoadingRef.current = false;\n setIsLoading(false);\n }\n },\n [selectedInstance, executeRows],\n );\n\n // Initial load and reload on instance or filter change\n useEffect(() => {\n afterSyncIdRef.current = null;\n setEvents([]);\n setTotalCount(null);\n void load(true, filters);\n }, [filters, load]);\n\n const applyFilters = (next: EventLogFilters) => {\n setFilters(next);\n };\n\n if (!selectedInstance) return null;\n\n return (\n <div className=\"eventLogLayout\">\n {/* Toolbar */}\n <div className=\"eventLogToolbar\">\n <select\n value={filters.dataset}\n onChange={(e) => applyFilters({ ...filters, dataset: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All datasets</option>\n {baseTableNames.map((name) => (\n <option key={name} value={name}>\n {name}\n </option>\n ))}\n </select>\n <select\n value={filters.origin}\n onChange={(e) => applyFilters({ ...filters, origin: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All origins</option>\n <option value=\"own\">own</option>\n <option value=\"remote\">remote</option>\n <option value=\"local\">local</option>\n </select>\n <select\n value={filters.status}\n onChange={(e) => applyFilters({ ...filters, status: e.target.value })}\n className=\"eventLogFilterSelect\"\n >\n <option value=\"\">All statuses</option>\n <option value=\"applied\">applied</option>\n <option value=\"pending\">pending</option>\n <option value=\"failed\">failed</option>\n <option value=\"deduped\">deduped</option>\n </select>\n <button type=\"button\" className=\"refreshButton\" disabled={isLoading} onClick={() => void load(true, filters)}>\n {isLoading ? \"…\" : \"↻\"} Refresh\n </button>\n {totalCount !== null && (\n <span className=\"eventLogCount\">\n {events.length === totalCount\n ? `${totalCount} event${totalCount === 1 ? \"\" : \"s\"}`\n : `${events.length} of ${totalCount}`}\n </span>\n )}\n </div>\n\n {/* Event list */}\n {events.length === 0 && !isLoading ? (\n <div className=\"eventLogEmpty\">No events match the current filters.</div>\n ) : (\n <div className=\"eventLogList\">\n {events.map((event) => {\n const isExpanded = expandedId === event.sync_id;\n return (\n <div key={event.sync_id} className=\"eventRow\" data-expanded={isExpanded ? \"true\" : undefined}>\n <button\n type=\"button\"\n className=\"eventRowHeader\"\n onClick={() => setExpandedId(isExpanded ? null : event.sync_id)}\n >\n <span className=\"eventSyncId\">#{event.sync_id}</span>\n <EventTypeBadge type={event.type} />\n <EventOriginBadge origin={event.origin} />\n <EventStatusBadge status={event.status} />\n <span className=\"eventDataset\">{event.dataset}</span>\n <span className=\"eventItemId\">{event.item_id}</span>\n <span className=\"eventTimestamp\">{formatHlcTimestamp(event.timestamp)}</span>\n <span className=\"eventChevron\">{isExpanded ? \"▲\" : \"▼\"}</span>\n </button>\n\n {isExpanded && (\n <div className=\"eventPayload\">\n <div className=\"eventPayloadMeta\">\n <span className=\"eventMetaItem\">schema v{event.schema_version}</span>\n <span className=\"eventMetaItem\">node: {event.source_node_id || \"—\"}</span>\n <span className=\"eventMetaItem\">ts: {event.timestamp}</span>\n </div>\n <pre className=\"eventPayloadPre\">{formatPayload(event.payload)}</pre>\n </div>\n )}\n </div>\n );\n })}\n\n {hasMore && (\n <button\n type=\"button\"\n className=\"loadMoreButton\"\n disabled={isLoading}\n onClick={() => void load(false, filters)}\n >\n {isLoading ? \"Loading…\" : `Load ${PAGE_SIZE} more`}\n </button>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction EventTypeBadge({ type }: { type: string }) {\n const { variant, label } =\n type === \"item-created\"\n ? { variant: \"create\", label: \"create\" }\n : type === \"item-deleted\"\n ? { variant: \"delete\", label: \"delete\" }\n : { variant: \"update\", label: \"update\" };\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {label}\n </span>\n );\n}\n\nfunction EventOriginBadge({ origin }: { origin: string }) {\n const variant = origin === \"own\" ? \"own\" : origin === \"remote\" ? \"remote\" : \"local\";\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {origin}\n </span>\n );\n}\n\nfunction EventStatusBadge({ status }: { status: string }) {\n const variant =\n status === \"applied\" ? \"applied\" : status === \"pending\" ? \"pending\" : status === \"failed\" ? \"failed\" : \"skipped\";\n return (\n <span className=\"eventBadge\" data-variant={variant}>\n {status}\n </span>\n );\n}\n\nfunction formatHlcTimestamp(ts: string): string {\n // HLC format: \"<unix_ms>-<counter>-<node>\" or just an ISO string\n const ms = Number(ts.split(\"-\")[0]);\n if (!Number.isNaN(ms) && ms > 1e12) {\n return new Date(ms).toLocaleTimeString();\n }\n return ts.slice(0, 19).replace(\"T\", \" \");\n}\n\nfunction formatPayload(raw: string): string {\n try {\n return JSON.stringify(JSON.parse(raw), null, 2);\n } catch {\n return raw;\n }\n}\n\nfunction QueryRunnerTab({\n selectedInstance,\n queryTarget,\n setQueryTarget,\n query,\n setQuery,\n queryState,\n canRunQuery,\n runQuery,\n}: {\n selectedInstance: unknown;\n queryTarget: QueryTarget;\n setQueryTarget: (t: QueryTarget) => void;\n query: string;\n setQuery: (q: string) => void;\n queryState: QueryState;\n canRunQuery: boolean;\n runQuery: () => Promise<void>;\n}) {\n return (\n <div className=\"queryRunnerLayout\">\n {/* Top toolbar */}\n <div className=\"queryToolbar\">\n <div className=\"targetToggle\">\n <button\n type=\"button\"\n className=\"targetButton\"\n data-active={queryTarget === \"memory\" ? \"true\" : undefined}\n onClick={() => setQueryTarget(\"memory\")}\n >\n Memory DB\n </button>\n <button\n type=\"button\"\n className=\"targetButton\"\n data-active={queryTarget === \"worker\" ? \"true\" : undefined}\n onClick={() => setQueryTarget(\"worker\")}\n >\n Worker DB\n </button>\n </div>\n\n <div className=\"queryToolbarRight\">\n {!selectedInstance && <span className=\"noInstanceWarning\">No instance selected</span>}\n <span className=\"shortcutHint\">⌘↵ to run</span>\n <button\n type=\"button\"\n className=\"runButton\"\n data-enabled={canRunQuery ? \"true\" : undefined}\n data-running={queryState.status === \"running\" ? \"true\" : undefined}\n disabled={!canRunQuery}\n onClick={() => void runQuery()}\n >\n {queryState.status === \"running\" ? (\n <>\n <span className=\"runningDot\" />\n Running…\n </>\n ) : (\n <>▶ Run</>\n )}\n </button>\n </div>\n </div>\n\n {/* SQL textarea */}\n <div className=\"editorWrapper\">\n <textarea\n value={query}\n onChange={(event) => setQuery(event.target.value)}\n onKeyDown={(event) => {\n if ((event.metaKey || event.ctrlKey) && event.key === \"Enter\" && canRunQuery) {\n event.preventDefault();\n void runQuery();\n }\n }}\n className=\"textarea\"\n placeholder=\"SELECT * FROM your_table LIMIT 100\"\n spellCheck={false}\n />\n </div>\n\n {/* Constraint hint */}\n <div className=\"helperText\">\n {queryTarget === \"worker\"\n ? \"Worker DB is read-only — only SELECT, PRAGMA, and EXPLAIN are allowed.\"\n : \"Memory DB allows writes only to CRDT tables.\"}\n </div>\n\n {/* Results */}\n {queryState.status === \"error\" && (\n <div className=\"errorPanel\">\n <div className=\"resultHeader\">\n <span className=\"errorBadge\">Error</span>\n <span className=\"resultMeta\">\n {queryState.error.target} · {queryState.error.sql}\n </span>\n </div>\n <pre className=\"errorMessage\">{queryState.error.message}</pre>\n </div>\n )}\n\n {queryState.status === \"success\" && (\n <div className=\"resultPanel\">\n <div className=\"resultHeader\">\n <span className=\"successBadge\">\n {queryState.output.rowCount} row{queryState.output.rowCount !== 1 ? \"s\" : \"\"}\n </span>\n <span className=\"resultMeta\">\n {queryState.output.target} · {queryState.output.durationMs}ms\n </span>\n </div>\n <ResultTable rows={queryState.output.rows} />\n </div>\n )}\n </div>\n );\n}\n\nfunction ResultTable({ rows }: { rows: unknown[] }) {\n if (rows.length === 0) {\n return <div className=\"resultEmpty\">Query returned 0 rows.</div>;\n }\n\n const firstRow = rows[0];\n if (typeof firstRow !== \"object\" || firstRow === null) {\n return <pre className=\"resultRaw\">{JSON.stringify(rows, null, 2)}</pre>;\n }\n\n const columns = Object.keys(firstRow as object);\n\n return (\n <div className=\"tableWrapper\">\n <table className=\"table\">\n <thead>\n <tr>\n <th className=\"thRowNum\">#</th>\n {columns.map((col) => (\n <th key={col} className=\"th\">\n {col}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {rows.map((row, rowIdx) => (\n <tr key={rowIdx}>\n <td className=\"tdRowNum\">{rowIdx + 1}</td>\n {columns.map((col) => {\n const val = (row as Record<string, unknown>)[col];\n return (\n <td key={col} className=\"td\">\n {val === null ? (\n <span className=\"nullValue\">NULL</span>\n ) : typeof val === \"object\" ? (\n <span className=\"jsonValue\">{JSON.stringify(val)}</span>\n ) : (\n String(val)\n )}\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────────\n\nfunction formatInstanceLabel(dbId: string, instanceId: string, duplicateCount: number): string {\n if (duplicateCount < 2) {\n return dbId;\n }\n\n return `${dbId} (${instanceId.slice(0, 6)})`;\n}\n\nfunction normalizeSingleStatement(query: string): string {\n const trimmed = query.trim();\n if (!trimmed) {\n throw new Error(\"Enter a SQL statement.\");\n }\n\n const withoutTrailingSemicolons = trimmed.replace(/;+\\s*$/u, \"\");\n if (withoutTrailingSemicolons.includes(\";\")) {\n throw new Error(\"Devtools only supports a single SQL statement.\");\n }\n\n return withoutTrailingSemicolons;\n}\n\nfunction getStatementKind(query: string): string {\n const match = query.trimStart().match(/^([a-z]+)/iu);\n return match?.[1]?.toLowerCase() ?? \"\";\n}\n\nfunction isWorkerReadOnlyStatement(statementKind: string): boolean {\n return statementKind === \"select\" || statementKind === \"pragma\";\n}\n\nfunction getEmptySnapshot(): SQLiteSyncDevtoolsSnapshot {\n return emptySnapshot;\n}\n\nconst emptySnapshot: SQLiteSyncDevtoolsSnapshot = {\n instances: [],\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sqlite-sync/devtools",
3
- "version": "0.12.3",
3
+ "version": "0.13.1",
4
4
  "description": "Embeddable devtools for @sqlite-sync",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -30,7 +30,7 @@
30
30
  "dist"
31
31
  ],
32
32
  "peerDependencies": {
33
- "@sqlite-sync/core": "^0.12.3",
33
+ "@sqlite-sync/core": "^0.13.1",
34
34
  "react": "^18.0.0 || ^19.0.0",
35
35
  "react-dom": "^18.0.0 || ^19.0.0"
36
36
  },
@@ -42,7 +42,7 @@
42
42
  "react-dom": "^19.2.7",
43
43
  "tsdown": "0.22.14",
44
44
  "typescript": "npm:@typescript/typescript6@6.0.2",
45
- "@sqlite-sync/core": "0.12.3"
45
+ "@sqlite-sync/core": "0.13.1"
46
46
  },
47
47
  "scripts": {
48
48
  "build": "tsdown",