@sqlite-sync/devtools 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1939 @@
1
+ // src/devtools.tsx
2
+ import { useCallback, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
+
4
+ // src/devtools-registry.ts
5
+ var devtoolsRegistrySymbol = Symbol.for("@sqlite-sync/devtools");
6
+ function createSQLiteSyncDevtoolsRegistry() {
7
+ const instances = /* @__PURE__ */ new Map();
8
+ const listeners = /* @__PURE__ */ new Set();
9
+ let snapshot = {
10
+ instances: []
11
+ };
12
+ const notify = () => {
13
+ for (const listener of listeners) {
14
+ listener();
15
+ }
16
+ };
17
+ const updateSnapshot = () => {
18
+ snapshot = {
19
+ instances: Array.from(instances.values())
20
+ };
21
+ notify();
22
+ };
23
+ return {
24
+ version: 1,
25
+ instances,
26
+ subscribe(listener) {
27
+ listeners.add(listener);
28
+ return () => {
29
+ listeners.delete(listener);
30
+ };
31
+ },
32
+ getSnapshot() {
33
+ return snapshot;
34
+ },
35
+ register(instance) {
36
+ instances.set(instance.instanceId, instance);
37
+ updateSnapshot();
38
+ let isUnregistered = false;
39
+ return () => {
40
+ if (isUnregistered) return;
41
+ isUnregistered = true;
42
+ if (!instances.delete(instance.instanceId)) return;
43
+ updateSnapshot();
44
+ };
45
+ }
46
+ };
47
+ }
48
+ function getOrCreateSQLiteSyncDevtoolsRegistry() {
49
+ const registryGlobal = globalThis;
50
+ registryGlobal[devtoolsRegistrySymbol] ??= createSQLiteSyncDevtoolsRegistry();
51
+ return registryGlobal[devtoolsRegistrySymbol];
52
+ }
53
+
54
+ // src/devtools.tsx
55
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
56
+ function SQLiteSyncDevtools({ className }) {
57
+ const registry = getOrCreateSQLiteSyncDevtoolsRegistry();
58
+ const snapshot = useSyncExternalStore(registry.subscribe, registry.getSnapshot, getEmptySnapshot);
59
+ const instances = snapshot.instances;
60
+ const [isOpen, setIsOpen] = useState(false);
61
+ const [activeTab, setActiveTab] = useState("overview");
62
+ const [selectedInstanceId, setSelectedInstanceId] = useState("");
63
+ const [queryTarget, setQueryTarget] = useState("memory");
64
+ const [query, setQuery] = useState("");
65
+ const [queryState, setQueryState] = useState({
66
+ status: "idle"
67
+ });
68
+ useEffect(() => {
69
+ if (!isOpen) return;
70
+ const onKeyDown = (event) => {
71
+ if (event.key === "Escape") {
72
+ setIsOpen(false);
73
+ }
74
+ };
75
+ window.addEventListener("keydown", onKeyDown);
76
+ return () => {
77
+ window.removeEventListener("keydown", onKeyDown);
78
+ };
79
+ }, [isOpen]);
80
+ useEffect(() => {
81
+ if (instances.length === 0) {
82
+ setSelectedInstanceId("");
83
+ return;
84
+ }
85
+ if (instances.some((instance) => instance.instanceId === selectedInstanceId)) {
86
+ return;
87
+ }
88
+ setSelectedInstanceId(instances[0]?.instanceId ?? "");
89
+ }, [instances, selectedInstanceId]);
90
+ const dbIdCounts = useMemo(() => {
91
+ const counts = /* @__PURE__ */ new Map();
92
+ for (const instance of instances) {
93
+ counts.set(instance.dbId, (counts.get(instance.dbId) ?? 0) + 1);
94
+ }
95
+ return counts;
96
+ }, [instances]);
97
+ const selectedInstance = useMemo(() => {
98
+ return instances.find((instance) => instance.instanceId === selectedInstanceId) ?? null;
99
+ }, [instances, selectedInstanceId]);
100
+ const canRunQuery = selectedInstance !== null && query.trim().length > 0 && queryState.status !== "running";
101
+ const runQuery = async () => {
102
+ if (!selectedInstance) return;
103
+ let normalizedQuery = query.trim();
104
+ try {
105
+ normalizedQuery = normalizeSingleStatement(query);
106
+ const statementKind = getStatementKind(normalizedQuery);
107
+ if (queryTarget === "worker") {
108
+ if (!isWorkerReadOnlyStatement(statementKind)) {
109
+ throw new Error("Worker DB devtools only allows read-only SQL: SELECT, PRAGMA.");
110
+ }
111
+ } else {
112
+ const touchedTables = selectedInstance.instance._internal.getMemoryQueryTables(normalizedQuery);
113
+ const writtenTables = touchedTables.filter((table) => table.isWrite).map((table) => table.name);
114
+ const allowedTables = new Set(selectedInstance.instance._internal.crdtTableNames);
115
+ const invalidTables = writtenTables.filter((table) => !allowedTables.has(table));
116
+ if (invalidTables.length > 0) {
117
+ throw new Error(
118
+ `Memory DB writes are only allowed for CRDT tables. Rejected tables: ${invalidTables.join(", ")}`
119
+ );
120
+ }
121
+ }
122
+ setQueryState({ status: "running" });
123
+ const startedAt = performance.now();
124
+ const result = queryTarget === "memory" ? selectedInstance.instance.db.execute(normalizedQuery) : await selectedInstance.instance._internal.executeAsync({
125
+ sql: normalizedQuery,
126
+ parameters: []
127
+ });
128
+ setQueryState({
129
+ status: "success",
130
+ output: {
131
+ target: queryTarget,
132
+ sql: normalizedQuery,
133
+ rowCount: result.rows.length,
134
+ durationMs: Number((performance.now() - startedAt).toFixed(2)),
135
+ rows: result.rows
136
+ }
137
+ });
138
+ } catch (error) {
139
+ setQueryState({
140
+ status: "error",
141
+ error: {
142
+ target: queryTarget,
143
+ sql: normalizedQuery,
144
+ message: error instanceof Error ? error.message : String(error)
145
+ }
146
+ });
147
+ }
148
+ };
149
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
150
+ /* @__PURE__ */ jsx("div", { style: floatingRootStyles, children: /* @__PURE__ */ jsxs("button", { type: "button", style: triggerButtonStyles, onClick: () => setIsOpen(true), title: "SQLite Sync Devtools", children: [
151
+ /* @__PURE__ */ jsx("span", { style: triggerIconStyles, children: "\u25C8" }),
152
+ /* @__PURE__ */ jsx("span", { style: triggerCountStyles, children: instances.length })
153
+ ] }) }),
154
+ isOpen ? /* @__PURE__ */ jsx("div", { style: overlayStyles, onClick: () => setIsOpen(false), children: /* @__PURE__ */ jsxs(
155
+ "section",
156
+ {
157
+ className,
158
+ role: "dialog",
159
+ "aria-modal": "true",
160
+ "aria-label": "SQLite Sync devtools",
161
+ style: dialogStyles,
162
+ onClick: (event) => event.stopPropagation(),
163
+ children: [
164
+ /* @__PURE__ */ jsxs("div", { style: headerStyles, children: [
165
+ /* @__PURE__ */ jsxs("div", { style: headerLeftStyles, children: [
166
+ /* @__PURE__ */ jsx("span", { style: headerLogoStyles, children: "\u25C8" }),
167
+ /* @__PURE__ */ jsxs("div", { children: [
168
+ /* @__PURE__ */ jsx("div", { style: eyebrowStyles, children: "sqlite-sync" }),
169
+ /* @__PURE__ */ jsx("h2", { style: titleStyles, children: "Devtools" })
170
+ ] })
171
+ ] }),
172
+ /* @__PURE__ */ jsxs("div", { style: headerRightStyles, children: [
173
+ instances.length > 0 && /* @__PURE__ */ jsxs("label", { style: instancePickerLabelStyles, children: [
174
+ /* @__PURE__ */ jsx("span", { style: instancePickerTextStyles, children: "DB" }),
175
+ /* @__PURE__ */ jsx(
176
+ "select",
177
+ {
178
+ value: selectedInstanceId,
179
+ onChange: (event) => setSelectedInstanceId(event.target.value),
180
+ style: instancePickerSelectStyles,
181
+ children: instances.map((instance) => /* @__PURE__ */ jsx("option", { value: instance.instanceId, children: formatInstanceLabel(instance.dbId, instance.instanceId, dbIdCounts.get(instance.dbId) ?? 0) }, instance.instanceId))
182
+ }
183
+ )
184
+ ] }),
185
+ /* @__PURE__ */ jsxs("span", { style: instanceCountBadgeStyles, children: [
186
+ instances.length,
187
+ " instance",
188
+ instances.length !== 1 ? "s" : ""
189
+ ] }),
190
+ /* @__PURE__ */ jsx("button", { type: "button", style: closeButtonStyles, onClick: () => setIsOpen(false), "aria-label": "Close", children: "\u2715" })
191
+ ] })
192
+ ] }),
193
+ instances.length === 0 ? /* @__PURE__ */ jsxs("div", { style: emptyStateStyles, children: [
194
+ /* @__PURE__ */ jsx("div", { style: emptyStateIconStyles, children: "\u25C8" }),
195
+ /* @__PURE__ */ jsx("p", { style: emptyStateTextStyles, children: "No SQLite Sync database instances registered." }),
196
+ /* @__PURE__ */ jsxs("p", { style: emptyStateSubtextStyles, children: [
197
+ "Call ",
198
+ /* @__PURE__ */ jsx("code", { style: inlineCodeStyles, children: "registerDevtools(db)" }),
199
+ " in your app to get started."
200
+ ] })
201
+ ] }) : /* @__PURE__ */ jsxs("div", { style: contentLayoutStyles, children: [
202
+ /* @__PURE__ */ jsxs("aside", { style: sidebarStyles, children: [
203
+ /* @__PURE__ */ jsxs("nav", { style: navStyles, children: [
204
+ /* @__PURE__ */ jsxs(
205
+ "button",
206
+ {
207
+ type: "button",
208
+ style: getTabButtonStyles(activeTab === "overview"),
209
+ onClick: () => setActiveTab("overview"),
210
+ children: [
211
+ /* @__PURE__ */ jsx("span", { style: navIconStyles, children: "\u25A6" }),
212
+ "Overview"
213
+ ]
214
+ }
215
+ ),
216
+ /* @__PURE__ */ jsxs(
217
+ "button",
218
+ {
219
+ type: "button",
220
+ style: getTabButtonStyles(activeTab === "schema"),
221
+ onClick: () => setActiveTab("schema"),
222
+ children: [
223
+ /* @__PURE__ */ jsx("span", { style: navIconStyles, children: "\u2B21" }),
224
+ "Schema"
225
+ ]
226
+ }
227
+ ),
228
+ /* @__PURE__ */ jsxs(
229
+ "button",
230
+ {
231
+ type: "button",
232
+ style: getTabButtonStyles(activeTab === "event-log"),
233
+ onClick: () => setActiveTab("event-log"),
234
+ children: [
235
+ /* @__PURE__ */ jsx("span", { style: navIconStyles, children: "\u2261" }),
236
+ "Event Log"
237
+ ]
238
+ }
239
+ ),
240
+ /* @__PURE__ */ jsxs(
241
+ "button",
242
+ {
243
+ type: "button",
244
+ style: getTabButtonStyles(activeTab === "query-runner"),
245
+ onClick: () => setActiveTab("query-runner"),
246
+ children: [
247
+ /* @__PURE__ */ jsx("span", { style: navIconStyles, children: "\u25B6" }),
248
+ "Query Runner"
249
+ ]
250
+ }
251
+ )
252
+ ] }),
253
+ selectedInstance && /* @__PURE__ */ jsxs("div", { style: sidebarInfoStyles, children: [
254
+ /* @__PURE__ */ jsx("div", { style: sidebarInfoLabelStyles, children: "Active instance" }),
255
+ /* @__PURE__ */ jsx("div", { style: sidebarInfoValueStyles, children: formatInstanceLabel(
256
+ selectedInstance.dbId,
257
+ selectedInstance.instanceId,
258
+ dbIdCounts.get(selectedInstance.dbId) ?? 0
259
+ ) }),
260
+ /* @__PURE__ */ jsxs("div", { style: sidebarInfoSubStyles, children: [
261
+ "id: ",
262
+ selectedInstance.instanceId.slice(0, 12),
263
+ "\u2026"
264
+ ] })
265
+ ] })
266
+ ] }),
267
+ /* @__PURE__ */ jsx("div", { style: mainPaneStyles, children: activeTab === "overview" ? /* @__PURE__ */ jsx(OverviewTab, { selectedInstance, dbIdCounts }) : activeTab === "schema" ? /* @__PURE__ */ jsx(SchemaTab, { selectedInstance }) : activeTab === "event-log" ? /* @__PURE__ */ jsx(EventLogTab, { selectedInstance }) : /* @__PURE__ */ jsx(
268
+ QueryRunnerTab,
269
+ {
270
+ selectedInstance,
271
+ queryTarget,
272
+ setQueryTarget,
273
+ query,
274
+ setQuery,
275
+ queryState,
276
+ canRunQuery,
277
+ runQuery
278
+ }
279
+ ) })
280
+ ] })
281
+ ]
282
+ }
283
+ ) }) : null
284
+ ] });
285
+ }
286
+ var EVENT_HLC_ACCUMULATOR_KV_KEY = "crdt.consistency.event_hlc_sum.v2";
287
+ var EVENT_HLC_ACCUMULATOR_QUERY = `SELECT value FROM "worker"."kv" WHERE key = '${EVENT_HLC_ACCUMULATOR_KV_KEY}'`;
288
+ function OverviewTab({
289
+ selectedInstance,
290
+ dbIdCounts
291
+ }) {
292
+ const [eventHlcAccumulator, setEventHlcAccumulator] = useState(null);
293
+ const [accumulatorError, setAccumulatorError] = useState(null);
294
+ const [isAccumulatorLoading, setIsAccumulatorLoading] = useState(false);
295
+ const refreshEventHlcAccumulator = useCallback(async () => {
296
+ if (!selectedInstance) return;
297
+ setIsAccumulatorLoading(true);
298
+ setAccumulatorError(null);
299
+ try {
300
+ const result = await selectedInstance.instance._internal.executeAsync({
301
+ sql: EVENT_HLC_ACCUMULATOR_QUERY,
302
+ parameters: []
303
+ });
304
+ const row = result.rows[0];
305
+ setEventHlcAccumulator(row?.value ?? "");
306
+ } catch (error) {
307
+ setAccumulatorError(error instanceof Error ? error.message : String(error));
308
+ setEventHlcAccumulator(null);
309
+ } finally {
310
+ setIsAccumulatorLoading(false);
311
+ }
312
+ }, [selectedInstance]);
313
+ useEffect(() => {
314
+ setEventHlcAccumulator(null);
315
+ setAccumulatorError(null);
316
+ void refreshEventHlcAccumulator();
317
+ }, [refreshEventHlcAccumulator]);
318
+ if (!selectedInstance) return null;
319
+ const label = formatInstanceLabel(
320
+ selectedInstance.dbId,
321
+ selectedInstance.instanceId,
322
+ dbIdCounts.get(selectedInstance.dbId) ?? 0
323
+ );
324
+ const crdtTables = selectedInstance.instance._internal.crdtTableNames;
325
+ return /* @__PURE__ */ jsxs("div", { style: overviewLayoutStyles, children: [
326
+ /* @__PURE__ */ jsxs("div", { style: overviewCardsRowStyles, children: [
327
+ /* @__PURE__ */ jsxs("div", { style: overviewCardStyles, children: [
328
+ /* @__PURE__ */ jsx("div", { style: overviewCardLabelStyles, children: "Database" }),
329
+ /* @__PURE__ */ jsx("div", { style: overviewCardValueStyles, children: label })
330
+ ] }),
331
+ /* @__PURE__ */ jsxs("div", { style: overviewCardStyles, children: [
332
+ /* @__PURE__ */ jsx("div", { style: overviewCardLabelStyles, children: "Instance ID" }),
333
+ /* @__PURE__ */ jsxs("div", { style: { ...overviewCardValueStyles, fontFamily: "ui-monospace, monospace", fontSize: "0.78rem" }, children: [
334
+ selectedInstance.instanceId.slice(0, 16),
335
+ "\u2026"
336
+ ] })
337
+ ] }),
338
+ /* @__PURE__ */ jsxs("div", { style: overviewCardStyles, children: [
339
+ /* @__PURE__ */ jsx("div", { style: overviewCardLabelStyles, children: "CRDT Tables" }),
340
+ /* @__PURE__ */ jsx("div", { style: overviewCardValueStyles, children: crdtTables.length })
341
+ ] })
342
+ ] }),
343
+ /* @__PURE__ */ jsxs("div", { style: overviewSectionStyles, children: [
344
+ /* @__PURE__ */ jsx("div", { style: overviewSectionTitleStyles, children: "CRDT Tables" }),
345
+ crdtTables.length === 0 ? /* @__PURE__ */ jsx("div", { style: overviewEmptyStyles, children: "No CRDT tables registered." }) : /* @__PURE__ */ jsx("div", { style: crdtTableListStyles, children: [...crdtTables].map((name) => /* @__PURE__ */ jsxs("div", { style: crdtTableRowStyles, children: [
346
+ /* @__PURE__ */ jsx("span", { style: crdtTableIconStyles, children: "\u25A6" }),
347
+ /* @__PURE__ */ jsx("span", { style: crdtTableNameStyles, children: name })
348
+ ] }, name)) })
349
+ ] }),
350
+ /* @__PURE__ */ jsxs("div", { style: overviewSectionStyles, children: [
351
+ /* @__PURE__ */ jsxs("div", { style: overviewSectionHeaderStyles, children: [
352
+ /* @__PURE__ */ jsx("div", { style: overviewSectionTitleStyles, children: "Event HLC accumulator" }),
353
+ /* @__PURE__ */ jsxs(
354
+ "button",
355
+ {
356
+ type: "button",
357
+ style: overviewRefreshButtonStyles,
358
+ disabled: isAccumulatorLoading,
359
+ onClick: () => void refreshEventHlcAccumulator(),
360
+ children: [
361
+ isAccumulatorLoading ? "\u2026" : "\u21BB",
362
+ " Refresh"
363
+ ]
364
+ }
365
+ )
366
+ ] }),
367
+ /* @__PURE__ */ jsx("div", { style: overviewAccumulatorValueStyles, children: accumulatorError ? /* @__PURE__ */ jsx("span", { style: overviewAccumulatorErrorStyles, children: accumulatorError }) : isAccumulatorLoading && eventHlcAccumulator === null ? "Loading\u2026" : eventHlcAccumulator === "" ? /* @__PURE__ */ jsx("span", { style: overviewAccumulatorEmptyStyles, children: "(empty)" }) : eventHlcAccumulator })
368
+ ] }),
369
+ /* @__PURE__ */ jsxs("div", { style: overviewSectionStyles, children: [
370
+ /* @__PURE__ */ jsx("div", { style: overviewSectionTitleStyles, children: "Write Permissions" }),
371
+ /* @__PURE__ */ jsxs("div", { style: permissionRowStyles, children: [
372
+ /* @__PURE__ */ jsx("span", { style: permissionIconStyles, children: "\u2713" }),
373
+ /* @__PURE__ */ jsx("span", { style: permissionTextStyles, children: "Memory DB \u2014 CRDT tables only" })
374
+ ] }),
375
+ /* @__PURE__ */ jsxs("div", { style: permissionRowStyles, children: [
376
+ /* @__PURE__ */ jsx("span", { style: { ...permissionIconStyles, color: "#f59e0b" }, children: "\u2298" }),
377
+ /* @__PURE__ */ jsx("span", { style: permissionTextStyles, children: "Worker DB \u2014 read-only (SELECT, PRAGMA, EXPLAIN)" })
378
+ ] })
379
+ ] }),
380
+ /* @__PURE__ */ jsx(ResetSection, { dbId: selectedInstance.dbId, instance: selectedInstance.instance })
381
+ ] });
382
+ }
383
+ function ResetSection({ dbId, instance }) {
384
+ const [confirming, setConfirming] = useState(false);
385
+ const [isResetting, setIsResetting] = useState(false);
386
+ const handleReset = () => {
387
+ setIsResetting(true);
388
+ void instance.requestReload({ clean: true });
389
+ };
390
+ return /* @__PURE__ */ jsxs("div", { style: dangerZoneStyles, children: [
391
+ /* @__PURE__ */ jsx("div", { style: dangerZoneTitleStyles, children: "Danger Zone" }),
392
+ /* @__PURE__ */ jsxs("div", { style: dangerZoneRowStyles, children: [
393
+ /* @__PURE__ */ jsxs("div", { style: dangerZoneDescStyles, children: [
394
+ "Requests a clean reload, so ",
395
+ /* @__PURE__ */ jsx("code", { style: inlineCodeStyles, children: dbId }),
396
+ " is wiped on next load via",
397
+ " ",
398
+ /* @__PURE__ */ jsx("code", { style: inlineCodeStyles, children: "clearOnInit" }),
399
+ ", then reloads all tabs."
400
+ ] }),
401
+ confirming ? /* @__PURE__ */ jsxs("div", { style: dangerZoneActionsStyles, children: [
402
+ /* @__PURE__ */ jsx(
403
+ "button",
404
+ {
405
+ type: "button",
406
+ style: resetCancelButtonStyles,
407
+ disabled: isResetting,
408
+ onClick: () => setConfirming(false),
409
+ children: "Cancel"
410
+ }
411
+ ),
412
+ /* @__PURE__ */ jsx("button", { type: "button", style: resetConfirmButtonStyles, disabled: isResetting, onClick: handleReset, children: isResetting ? "Resetting\u2026" : "Confirm reset" })
413
+ ] }) : /* @__PURE__ */ jsx("button", { type: "button", style: resetButtonStyles, onClick: () => setConfirming(true), children: "Reset DB" })
414
+ ] })
415
+ ] });
416
+ }
417
+ function SchemaTab({
418
+ selectedInstance
419
+ }) {
420
+ if (!selectedInstance) return null;
421
+ const { crdtTablesConfig, schemaVersion, migrationVersions } = selectedInstance.instance._internal;
422
+ const latestVersion = migrationVersions.at(-1) ?? 0;
423
+ return /* @__PURE__ */ jsxs("div", { style: schemaLayoutStyles, children: [
424
+ /* @__PURE__ */ jsxs("div", { style: schemaSectionStyles, children: [
425
+ /* @__PURE__ */ jsxs("div", { style: schemaSectionHeaderStyles, children: [
426
+ /* @__PURE__ */ jsx("div", { style: schemaSectionTitleStyles, children: "CRDT Tables" }),
427
+ /* @__PURE__ */ jsx("span", { style: schemaBadgeStyles, children: crdtTablesConfig.length })
428
+ ] }),
429
+ /* @__PURE__ */ jsxs("div", { style: schemaTableGridStyles, children: [
430
+ /* @__PURE__ */ jsxs("div", { style: schemaTableHeaderRowStyles, children: [
431
+ /* @__PURE__ */ jsx("div", { style: schemaColHeaderStyles, children: "Base Table" }),
432
+ /* @__PURE__ */ jsx("div", { style: schemaColHeaderStyles, children: "CRDT Table" }),
433
+ /* @__PURE__ */ jsx("div", { style: { ...schemaColHeaderStyles, textAlign: "center" }, children: "Status" })
434
+ ] }),
435
+ crdtTablesConfig.map((table) => /* @__PURE__ */ jsxs("div", { style: schemaTableRowStyles, children: [
436
+ /* @__PURE__ */ jsxs("div", { style: schemaTableNameStyles, children: [
437
+ /* @__PURE__ */ jsx("span", { style: schemaTableIconStyles, children: "\u25A6" }),
438
+ table.baseTableName
439
+ ] }),
440
+ /* @__PURE__ */ jsx("div", { style: schemaCrdtNameStyles, children: table.crdtTableName }),
441
+ /* @__PURE__ */ jsx("div", { style: schemaStatusCellStyles, children: /* @__PURE__ */ jsx("span", { style: schemaActiveTagStyles, children: "active" }) })
442
+ ] }, table.crdtTableName))
443
+ ] })
444
+ ] }),
445
+ /* @__PURE__ */ jsxs("div", { style: schemaSectionStyles, children: [
446
+ /* @__PURE__ */ jsxs("div", { style: schemaSectionHeaderStyles, children: [
447
+ /* @__PURE__ */ jsx("div", { style: schemaSectionTitleStyles, children: "Migrations" }),
448
+ /* @__PURE__ */ jsxs("div", { style: schemaMigrationsMetaStyles, children: [
449
+ /* @__PURE__ */ jsxs("span", { style: schemaBadgeStyles, children: [
450
+ migrationVersions.length,
451
+ " total"
452
+ ] }),
453
+ /* @__PURE__ */ jsxs("span", { style: schemaVersionChipStyles, children: [
454
+ "current: v",
455
+ schemaVersion,
456
+ " / latest: v",
457
+ latestVersion
458
+ ] })
459
+ ] })
460
+ ] }),
461
+ migrationVersions.length === 0 ? /* @__PURE__ */ jsx("div", { style: schemaEmptyStyles, children: "No migrations defined." }) : /* @__PURE__ */ jsx("div", { style: migrationListStyles, children: migrationVersions.map((version) => {
462
+ const applied = version <= schemaVersion;
463
+ const isCurrent = version === schemaVersion;
464
+ return /* @__PURE__ */ jsxs("div", { style: getMigrationRowStyles(applied), children: [
465
+ /* @__PURE__ */ jsxs("div", { style: migrationVersionStyles, children: [
466
+ "v",
467
+ version
468
+ ] }),
469
+ /* @__PURE__ */ jsx("div", { style: migrationBarTrackStyles, children: /* @__PURE__ */ jsx("div", { style: getMigrationBarFillStyles(applied) }) }),
470
+ /* @__PURE__ */ jsx("div", { style: getMigrationTagStyles(applied, isCurrent), children: isCurrent ? "current" : applied ? "applied" : "pending" })
471
+ ] }, version);
472
+ }) })
473
+ ] })
474
+ ] });
475
+ }
476
+ var PAGE_SIZE = 50;
477
+ function buildEventLogQuery(filters, afterSyncId) {
478
+ const conditions = [];
479
+ if (filters.dataset) conditions.push(`dataset = '${filters.dataset}'`);
480
+ if (filters.origin) conditions.push(`origin = '${filters.origin}'`);
481
+ if (filters.status) conditions.push(`status = '${filters.status}'`);
482
+ if (afterSyncId !== null) conditions.push(`sync_id < ${afterSyncId}`);
483
+ const where = conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";
484
+ return `SELECT * FROM "worker"."crdt_events" ${where} ORDER BY sync_id DESC LIMIT ${PAGE_SIZE + 1}`;
485
+ }
486
+ function EventLogTab({
487
+ selectedInstance
488
+ }) {
489
+ const baseTableNames = useMemo(
490
+ () => selectedInstance?.instance._internal.crdtTablesConfig.map((table) => table.baseTableName) ?? [],
491
+ [selectedInstance]
492
+ );
493
+ const [filters, setFilters] = useState({ dataset: "", origin: "", status: "" });
494
+ const [events, setEvents] = useState([]);
495
+ const [hasMore, setHasMore] = useState(false);
496
+ const [isLoading, setIsLoading] = useState(false);
497
+ const [expandedId, setExpandedId] = useState(null);
498
+ const afterSyncIdRef = useRef(null);
499
+ const isLoadingRef = useRef(false);
500
+ const executeQuery = useCallback(
501
+ async (sql) => {
502
+ if (!selectedInstance) return [];
503
+ const result = await selectedInstance.instance._internal.executeAsync({ sql, parameters: [] });
504
+ return result.rows;
505
+ },
506
+ [selectedInstance]
507
+ );
508
+ const load = useCallback(
509
+ async (reset, currentFilters) => {
510
+ if (!selectedInstance || isLoadingRef.current) return;
511
+ isLoadingRef.current = true;
512
+ setIsLoading(true);
513
+ try {
514
+ const afterSyncId = reset ? null : afterSyncIdRef.current;
515
+ const sql = buildEventLogQuery(currentFilters, afterSyncId);
516
+ const rows = await executeQuery(sql);
517
+ const page = rows.slice(0, PAGE_SIZE);
518
+ setHasMore(rows.length > PAGE_SIZE);
519
+ if (reset) {
520
+ setEvents(page);
521
+ } else {
522
+ setEvents((prev) => [...prev, ...page]);
523
+ }
524
+ afterSyncIdRef.current = page.at(-1)?.sync_id ?? null;
525
+ } finally {
526
+ isLoadingRef.current = false;
527
+ setIsLoading(false);
528
+ }
529
+ },
530
+ [selectedInstance, executeQuery]
531
+ );
532
+ useEffect(() => {
533
+ afterSyncIdRef.current = null;
534
+ setEvents([]);
535
+ void load(true, filters);
536
+ }, [filters, load]);
537
+ const applyFilters = (next) => {
538
+ setFilters(next);
539
+ };
540
+ if (!selectedInstance) return null;
541
+ return /* @__PURE__ */ jsxs("div", { style: eventLogLayoutStyles, children: [
542
+ /* @__PURE__ */ jsxs("div", { style: eventLogToolbarStyles, children: [
543
+ /* @__PURE__ */ jsxs(
544
+ "select",
545
+ {
546
+ value: filters.dataset,
547
+ onChange: (e) => applyFilters({ ...filters, dataset: e.target.value }),
548
+ style: eventLogFilterSelectStyles,
549
+ children: [
550
+ /* @__PURE__ */ jsx("option", { value: "", children: "All datasets" }),
551
+ baseTableNames.map((name) => /* @__PURE__ */ jsx("option", { value: name, children: name }, name))
552
+ ]
553
+ }
554
+ ),
555
+ /* @__PURE__ */ jsxs(
556
+ "select",
557
+ {
558
+ value: filters.origin,
559
+ onChange: (e) => applyFilters({ ...filters, origin: e.target.value }),
560
+ style: eventLogFilterSelectStyles,
561
+ children: [
562
+ /* @__PURE__ */ jsx("option", { value: "", children: "All origins" }),
563
+ /* @__PURE__ */ jsx("option", { value: "own", children: "own" }),
564
+ /* @__PURE__ */ jsx("option", { value: "remote", children: "remote" }),
565
+ /* @__PURE__ */ jsx("option", { value: "local", children: "local" })
566
+ ]
567
+ }
568
+ ),
569
+ /* @__PURE__ */ jsxs(
570
+ "select",
571
+ {
572
+ value: filters.status,
573
+ onChange: (e) => applyFilters({ ...filters, status: e.target.value }),
574
+ style: eventLogFilterSelectStyles,
575
+ children: [
576
+ /* @__PURE__ */ jsx("option", { value: "", children: "All statuses" }),
577
+ /* @__PURE__ */ jsx("option", { value: "applied", children: "applied" }),
578
+ /* @__PURE__ */ jsx("option", { value: "pending", children: "pending" }),
579
+ /* @__PURE__ */ jsx("option", { value: "failed", children: "failed" }),
580
+ /* @__PURE__ */ jsx("option", { value: "deduped", children: "deduped" })
581
+ ]
582
+ }
583
+ ),
584
+ /* @__PURE__ */ jsxs(
585
+ "button",
586
+ {
587
+ type: "button",
588
+ style: eventLogRefreshButtonStyles,
589
+ disabled: isLoading,
590
+ onClick: () => void load(true, filters),
591
+ children: [
592
+ isLoading ? "\u2026" : "\u21BB",
593
+ " Refresh"
594
+ ]
595
+ }
596
+ ),
597
+ events.length > 0 && /* @__PURE__ */ jsxs("span", { style: eventLogCountStyles, children: [
598
+ events.length,
599
+ hasMore ? "+" : "",
600
+ " events"
601
+ ] })
602
+ ] }),
603
+ events.length === 0 && !isLoading ? /* @__PURE__ */ jsx("div", { style: eventLogEmptyStyles, children: "No events match the current filters." }) : /* @__PURE__ */ jsxs("div", { style: eventLogListStyles, children: [
604
+ events.map((event) => {
605
+ const isExpanded = expandedId === event.sync_id;
606
+ return /* @__PURE__ */ jsxs("div", { style: getEventRowStyles(isExpanded), children: [
607
+ /* @__PURE__ */ jsxs(
608
+ "button",
609
+ {
610
+ type: "button",
611
+ style: eventRowHeaderStyles,
612
+ onClick: () => setExpandedId(isExpanded ? null : event.sync_id),
613
+ children: [
614
+ /* @__PURE__ */ jsxs("span", { style: eventSyncIdStyles, children: [
615
+ "#",
616
+ event.sync_id
617
+ ] }),
618
+ /* @__PURE__ */ jsx(EventTypeBadge, { type: event.type }),
619
+ /* @__PURE__ */ jsx(EventOriginBadge, { origin: event.origin }),
620
+ /* @__PURE__ */ jsx(EventStatusBadge, { status: event.status }),
621
+ /* @__PURE__ */ jsx("span", { style: eventDatasetStyles, children: event.dataset }),
622
+ /* @__PURE__ */ jsx("span", { style: eventItemIdStyles, children: event.item_id }),
623
+ /* @__PURE__ */ jsx("span", { style: eventTimestampStyles, children: formatHlcTimestamp(event.timestamp) }),
624
+ /* @__PURE__ */ jsx("span", { style: eventChevronStyles, children: isExpanded ? "\u25B2" : "\u25BC" })
625
+ ]
626
+ }
627
+ ),
628
+ isExpanded && /* @__PURE__ */ jsxs("div", { style: eventPayloadStyles, children: [
629
+ /* @__PURE__ */ jsxs("div", { style: eventPayloadMetaStyles, children: [
630
+ /* @__PURE__ */ jsxs("span", { style: eventMetaItemStyles, children: [
631
+ "schema v",
632
+ event.schema_version
633
+ ] }),
634
+ /* @__PURE__ */ jsxs("span", { style: eventMetaItemStyles, children: [
635
+ "node: ",
636
+ event.source_node_id || "\u2014"
637
+ ] }),
638
+ /* @__PURE__ */ jsxs("span", { style: eventMetaItemStyles, children: [
639
+ "ts: ",
640
+ event.timestamp
641
+ ] })
642
+ ] }),
643
+ /* @__PURE__ */ jsx("pre", { style: eventPayloadPreStyles, children: formatPayload(event.payload) })
644
+ ] })
645
+ ] }, event.sync_id);
646
+ }),
647
+ hasMore && /* @__PURE__ */ jsx(
648
+ "button",
649
+ {
650
+ type: "button",
651
+ style: loadMoreButtonStyles,
652
+ disabled: isLoading,
653
+ onClick: () => void load(false, filters),
654
+ children: isLoading ? "Loading\u2026" : `Load ${PAGE_SIZE} more`
655
+ }
656
+ )
657
+ ] })
658
+ ] });
659
+ }
660
+ function EventTypeBadge({ type }) {
661
+ const isCreate = type === "item-created";
662
+ return /* @__PURE__ */ jsx("span", { style: isCreate ? eventTypeCreateStyles : eventTypeUpdateStyles, children: isCreate ? "create" : "update" });
663
+ }
664
+ function EventOriginBadge({ origin }) {
665
+ const style = origin === "own" ? eventOriginOwnStyles : origin === "remote" ? eventOriginRemoteStyles : eventOriginLocalStyles;
666
+ return /* @__PURE__ */ jsx("span", { style, children: origin });
667
+ }
668
+ function EventStatusBadge({ status }) {
669
+ const style = status === "applied" ? eventStatusAppliedStyles : status === "pending" ? eventStatusPendingStyles : status === "failed" ? eventStatusFailedStyles : eventStatusSkippedStyles;
670
+ return /* @__PURE__ */ jsx("span", { style, children: status });
671
+ }
672
+ function formatHlcTimestamp(ts) {
673
+ const ms = Number(ts.split("-")[0]);
674
+ if (!Number.isNaN(ms) && ms > 1e12) {
675
+ return new Date(ms).toLocaleTimeString();
676
+ }
677
+ return ts.slice(0, 19).replace("T", " ");
678
+ }
679
+ function formatPayload(raw) {
680
+ try {
681
+ return JSON.stringify(JSON.parse(raw), null, 2);
682
+ } catch {
683
+ return raw;
684
+ }
685
+ }
686
+ function QueryRunnerTab({
687
+ selectedInstance,
688
+ queryTarget,
689
+ setQueryTarget,
690
+ query,
691
+ setQuery,
692
+ queryState,
693
+ canRunQuery,
694
+ runQuery
695
+ }) {
696
+ return /* @__PURE__ */ jsxs("div", { style: queryRunnerLayoutStyles, children: [
697
+ /* @__PURE__ */ jsxs("div", { style: queryToolbarStyles, children: [
698
+ /* @__PURE__ */ jsxs("div", { style: targetToggleStyles, children: [
699
+ /* @__PURE__ */ jsx(
700
+ "button",
701
+ {
702
+ type: "button",
703
+ style: getTargetButtonStyles(queryTarget === "memory"),
704
+ onClick: () => setQueryTarget("memory"),
705
+ children: "Memory DB"
706
+ }
707
+ ),
708
+ /* @__PURE__ */ jsx(
709
+ "button",
710
+ {
711
+ type: "button",
712
+ style: getTargetButtonStyles(queryTarget === "worker"),
713
+ onClick: () => setQueryTarget("worker"),
714
+ children: "Worker DB"
715
+ }
716
+ )
717
+ ] }),
718
+ /* @__PURE__ */ jsxs("div", { style: queryToolbarRightStyles, children: [
719
+ !selectedInstance && /* @__PURE__ */ jsx("span", { style: noInstanceWarningStyles, children: "No instance selected" }),
720
+ /* @__PURE__ */ jsx("span", { style: shortcutHintStyles, children: "\u2318\u21B5 to run" }),
721
+ /* @__PURE__ */ jsx(
722
+ "button",
723
+ {
724
+ type: "button",
725
+ style: runButtonStyles(canRunQuery, queryState.status === "running"),
726
+ disabled: !canRunQuery,
727
+ onClick: () => void runQuery(),
728
+ children: queryState.status === "running" ? /* @__PURE__ */ jsxs(Fragment, { children: [
729
+ /* @__PURE__ */ jsx("span", { style: runningDotStyles }),
730
+ "Running\u2026"
731
+ ] }) : /* @__PURE__ */ jsx(Fragment, { children: "\u25B6 Run" })
732
+ }
733
+ )
734
+ ] })
735
+ ] }),
736
+ /* @__PURE__ */ jsx("div", { style: editorWrapperStyles, children: /* @__PURE__ */ jsx(
737
+ "textarea",
738
+ {
739
+ value: query,
740
+ onChange: (event) => setQuery(event.target.value),
741
+ onKeyDown: (event) => {
742
+ if ((event.metaKey || event.ctrlKey) && event.key === "Enter" && canRunQuery) {
743
+ event.preventDefault();
744
+ void runQuery();
745
+ }
746
+ },
747
+ style: textareaStyles,
748
+ placeholder: "SELECT * FROM your_table LIMIT 100",
749
+ spellCheck: false
750
+ }
751
+ ) }),
752
+ /* @__PURE__ */ jsx("div", { style: helperTextStyles, children: queryTarget === "worker" ? "Worker DB is read-only \u2014 only SELECT, PRAGMA, and EXPLAIN are allowed." : "Memory DB allows writes only to CRDT tables." }),
753
+ queryState.status === "error" && /* @__PURE__ */ jsxs("div", { style: errorPanelStyles, children: [
754
+ /* @__PURE__ */ jsxs("div", { style: resultHeaderStyles, children: [
755
+ /* @__PURE__ */ jsx("span", { style: errorBadgeStyles, children: "Error" }),
756
+ /* @__PURE__ */ jsxs("span", { style: resultMetaStyles, children: [
757
+ queryState.error.target,
758
+ " \xB7 ",
759
+ queryState.error.sql
760
+ ] })
761
+ ] }),
762
+ /* @__PURE__ */ jsx("pre", { style: errorMessageStyles, children: queryState.error.message })
763
+ ] }),
764
+ queryState.status === "success" && /* @__PURE__ */ jsxs("div", { style: resultPanelStyles, children: [
765
+ /* @__PURE__ */ jsxs("div", { style: resultHeaderStyles, children: [
766
+ /* @__PURE__ */ jsxs("span", { style: successBadgeStyles, children: [
767
+ queryState.output.rowCount,
768
+ " row",
769
+ queryState.output.rowCount !== 1 ? "s" : ""
770
+ ] }),
771
+ /* @__PURE__ */ jsxs("span", { style: resultMetaStyles, children: [
772
+ queryState.output.target,
773
+ " \xB7 ",
774
+ queryState.output.durationMs,
775
+ "ms"
776
+ ] })
777
+ ] }),
778
+ /* @__PURE__ */ jsx(ResultTable, { rows: queryState.output.rows })
779
+ ] })
780
+ ] });
781
+ }
782
+ function ResultTable({ rows }) {
783
+ if (rows.length === 0) {
784
+ return /* @__PURE__ */ jsx("div", { style: resultEmptyStyles, children: "Query returned 0 rows." });
785
+ }
786
+ const firstRow = rows[0];
787
+ if (typeof firstRow !== "object" || firstRow === null) {
788
+ return /* @__PURE__ */ jsx("pre", { style: resultRawStyles, children: JSON.stringify(rows, null, 2) });
789
+ }
790
+ const columns = Object.keys(firstRow);
791
+ return /* @__PURE__ */ jsx("div", { style: tableWrapperStyles, children: /* @__PURE__ */ jsxs("table", { style: tableStyles, children: [
792
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
793
+ /* @__PURE__ */ jsx("th", { style: thRowNumStyles, children: "#" }),
794
+ columns.map((col) => /* @__PURE__ */ jsx("th", { style: thStyles, children: col }, col))
795
+ ] }) }),
796
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((row, rowIdx) => /* @__PURE__ */ jsxs("tr", { style: rowIdx % 2 === 0 ? trStyles : trAltStyles, children: [
797
+ /* @__PURE__ */ jsx("td", { style: tdRowNumStyles, children: rowIdx + 1 }),
798
+ columns.map((col) => {
799
+ const val = row[col];
800
+ return /* @__PURE__ */ jsx("td", { style: tdStyles, children: val === null ? /* @__PURE__ */ jsx("span", { style: nullValueStyles, children: "NULL" }) : typeof val === "object" ? /* @__PURE__ */ jsx("span", { style: jsonValueStyles, children: JSON.stringify(val) }) : String(val) }, col);
801
+ })
802
+ ] }, rowIdx)) })
803
+ ] }) });
804
+ }
805
+ function formatInstanceLabel(dbId, instanceId, duplicateCount) {
806
+ if (duplicateCount < 2) {
807
+ return dbId;
808
+ }
809
+ return `${dbId} (${instanceId.slice(0, 6)})`;
810
+ }
811
+ function normalizeSingleStatement(query) {
812
+ const trimmed = query.trim();
813
+ if (!trimmed) {
814
+ throw new Error("Enter a SQL statement.");
815
+ }
816
+ const withoutTrailingSemicolons = trimmed.replace(/;+\s*$/u, "");
817
+ if (withoutTrailingSemicolons.includes(";")) {
818
+ throw new Error("Devtools only supports a single SQL statement.");
819
+ }
820
+ return withoutTrailingSemicolons;
821
+ }
822
+ function getStatementKind(query) {
823
+ const match = query.trimStart().match(/^([a-z]+)/iu);
824
+ return match?.[1]?.toLowerCase() ?? "";
825
+ }
826
+ function isWorkerReadOnlyStatement(statementKind) {
827
+ return statementKind === "select" || statementKind === "pragma";
828
+ }
829
+ function getEmptySnapshot() {
830
+ return emptySnapshot;
831
+ }
832
+ var emptySnapshot = {
833
+ instances: []
834
+ };
835
+ var C = {
836
+ bg: "#0e1015",
837
+ bgPanel: "#161921",
838
+ bgCard: "#1c2030",
839
+ bgInput: "#111318",
840
+ border: "#2a2f3e",
841
+ borderLight: "#343a4f",
842
+ text: "#e2e8f0",
843
+ textMuted: "#6b7280",
844
+ textDim: "#9ca3af",
845
+ teal: "#2dd4bf",
846
+ tealDim: "rgba(45,212,191,0.12)",
847
+ tealGlow: "rgba(45,212,191,0.06)",
848
+ error: "#f87171",
849
+ errorBg: "rgba(248,113,113,0.08)",
850
+ errorBorder: "rgba(248,113,113,0.25)",
851
+ success: "#34d399",
852
+ successBg: "rgba(52,211,153,0.08)",
853
+ amber: "#fbbf24"
854
+ };
855
+ var floatingRootStyles = {
856
+ position: "fixed",
857
+ inset: 0,
858
+ pointerEvents: "none",
859
+ zIndex: 9998
860
+ };
861
+ var triggerButtonStyles = {
862
+ position: "absolute",
863
+ right: "16px",
864
+ bottom: "16px",
865
+ display: "inline-flex",
866
+ alignItems: "center",
867
+ gap: "0.3rem",
868
+ border: `1px solid ${C.border}`,
869
+ borderRadius: "8px",
870
+ padding: "0.3rem 0.45rem",
871
+ background: C.bgPanel,
872
+ color: C.text,
873
+ boxShadow: `0 0 0 1px ${C.border}, 0 4px 16px rgba(0,0,0,0.5)`,
874
+ cursor: "pointer",
875
+ pointerEvents: "auto"
876
+ };
877
+ var triggerIconStyles = {
878
+ color: C.teal,
879
+ fontSize: "0.9rem",
880
+ lineHeight: 1
881
+ };
882
+ var triggerCountStyles = {
883
+ minWidth: "1.1rem",
884
+ borderRadius: "4px",
885
+ padding: "0.05rem 0.25rem",
886
+ backgroundColor: C.tealDim,
887
+ color: C.teal,
888
+ fontSize: "0.65rem",
889
+ fontWeight: 700,
890
+ textAlign: "center",
891
+ fontFamily: "ui-monospace, monospace"
892
+ };
893
+ var overlayStyles = {
894
+ position: "fixed",
895
+ inset: 0,
896
+ zIndex: 9999,
897
+ display: "flex",
898
+ alignItems: "center",
899
+ justifyContent: "center",
900
+ padding: "1.5rem",
901
+ backgroundColor: "rgba(0,0,0,0.72)",
902
+ backdropFilter: "blur(8px)"
903
+ };
904
+ var dialogStyles = {
905
+ width: "min(72rem, 100%)",
906
+ height: "min(90vh, 860px)",
907
+ display: "flex",
908
+ flexDirection: "column",
909
+ border: `1px solid ${C.border}`,
910
+ borderRadius: "16px",
911
+ background: C.bg,
912
+ boxShadow: `0 0 0 1px ${C.border}, 0 40px 80px rgba(0,0,0,0.8), 0 0 60px rgba(45,212,191,0.04)`,
913
+ overflow: "hidden",
914
+ fontFamily: "ui-sans-serif, system-ui, sans-serif",
915
+ color: C.text,
916
+ fontSize: "0.88rem"
917
+ };
918
+ var headerStyles = {
919
+ display: "flex",
920
+ justifyContent: "space-between",
921
+ alignItems: "center",
922
+ gap: "1rem",
923
+ padding: "0.85rem 1.1rem",
924
+ borderBottom: `1px solid ${C.border}`,
925
+ background: C.bgPanel,
926
+ flexShrink: 0
927
+ };
928
+ var headerLeftStyles = {
929
+ display: "flex",
930
+ alignItems: "center",
931
+ gap: "0.75rem"
932
+ };
933
+ var headerLogoStyles = {
934
+ fontSize: "1.3rem",
935
+ color: C.teal,
936
+ lineHeight: 1
937
+ };
938
+ var eyebrowStyles = {
939
+ fontSize: "0.65rem",
940
+ fontWeight: 600,
941
+ letterSpacing: "0.1em",
942
+ textTransform: "uppercase",
943
+ color: C.textMuted,
944
+ fontFamily: "ui-monospace, monospace"
945
+ };
946
+ var titleStyles = {
947
+ margin: "0.05rem 0 0",
948
+ fontSize: "0.95rem",
949
+ fontWeight: 700,
950
+ color: C.text,
951
+ letterSpacing: "-0.01em"
952
+ };
953
+ var headerRightStyles = {
954
+ display: "flex",
955
+ alignItems: "center",
956
+ gap: "0.6rem"
957
+ };
958
+ var instancePickerLabelStyles = {
959
+ display: "flex",
960
+ alignItems: "center",
961
+ gap: "0.5rem"
962
+ };
963
+ var instancePickerTextStyles = {
964
+ fontSize: "0.72rem",
965
+ fontWeight: 600,
966
+ color: C.textMuted,
967
+ textTransform: "uppercase",
968
+ letterSpacing: "0.06em"
969
+ };
970
+ var instancePickerSelectStyles = {
971
+ borderRadius: "7px",
972
+ border: `1px solid ${C.border}`,
973
+ padding: "0.35rem 0.6rem",
974
+ backgroundColor: C.bgCard,
975
+ color: C.text,
976
+ fontSize: "0.82rem",
977
+ fontFamily: "ui-monospace, monospace",
978
+ cursor: "pointer"
979
+ };
980
+ var instanceCountBadgeStyles = {
981
+ fontSize: "0.72rem",
982
+ fontWeight: 600,
983
+ color: C.teal,
984
+ backgroundColor: C.tealDim,
985
+ borderRadius: "5px",
986
+ padding: "0.2rem 0.5rem",
987
+ fontFamily: "ui-monospace, monospace"
988
+ };
989
+ var closeButtonStyles = {
990
+ border: `1px solid ${C.border}`,
991
+ borderRadius: "7px",
992
+ width: "28px",
993
+ height: "28px",
994
+ display: "flex",
995
+ alignItems: "center",
996
+ justifyContent: "center",
997
+ backgroundColor: "transparent",
998
+ color: C.textMuted,
999
+ fontSize: "0.82rem",
1000
+ fontWeight: 600,
1001
+ cursor: "pointer"
1002
+ };
1003
+ var emptyStateStyles = {
1004
+ display: "flex",
1005
+ flexDirection: "column",
1006
+ alignItems: "center",
1007
+ justifyContent: "center",
1008
+ padding: "4rem 2rem",
1009
+ gap: "0.75rem",
1010
+ flex: 1
1011
+ };
1012
+ var emptyStateIconStyles = {
1013
+ fontSize: "2.5rem",
1014
+ color: C.textMuted,
1015
+ opacity: 0.4
1016
+ };
1017
+ var emptyStateTextStyles = {
1018
+ margin: 0,
1019
+ fontSize: "0.95rem",
1020
+ fontWeight: 600,
1021
+ color: C.textDim
1022
+ };
1023
+ var emptyStateSubtextStyles = {
1024
+ margin: 0,
1025
+ fontSize: "0.82rem",
1026
+ color: C.textMuted,
1027
+ textAlign: "center"
1028
+ };
1029
+ var inlineCodeStyles = {
1030
+ fontFamily: "ui-monospace, monospace",
1031
+ backgroundColor: C.bgCard,
1032
+ border: `1px solid ${C.border}`,
1033
+ borderRadius: "4px",
1034
+ padding: "0.1em 0.4em",
1035
+ fontSize: "0.88em",
1036
+ color: C.teal
1037
+ };
1038
+ var contentLayoutStyles = {
1039
+ display: "grid",
1040
+ gridTemplateColumns: "200px minmax(0, 1fr)",
1041
+ flex: 1,
1042
+ minHeight: 0,
1043
+ overflow: "hidden"
1044
+ };
1045
+ var sidebarStyles = {
1046
+ display: "flex",
1047
+ flexDirection: "column",
1048
+ gap: "0",
1049
+ padding: "0.75rem",
1050
+ borderRight: `1px solid ${C.border}`,
1051
+ background: C.bgPanel,
1052
+ overflowY: "auto"
1053
+ };
1054
+ var navStyles = {
1055
+ display: "flex",
1056
+ flexDirection: "column",
1057
+ gap: "0.25rem",
1058
+ marginBottom: "1rem"
1059
+ };
1060
+ var navIconStyles = {
1061
+ fontSize: "0.7rem",
1062
+ opacity: 0.7
1063
+ };
1064
+ var sidebarInfoStyles = {
1065
+ marginTop: "auto",
1066
+ padding: "0.75rem",
1067
+ borderRadius: "8px",
1068
+ background: C.bgCard,
1069
+ border: `1px solid ${C.border}`
1070
+ };
1071
+ var sidebarInfoLabelStyles = {
1072
+ fontSize: "0.65rem",
1073
+ fontWeight: 600,
1074
+ letterSpacing: "0.08em",
1075
+ textTransform: "uppercase",
1076
+ color: C.textMuted,
1077
+ marginBottom: "0.3rem"
1078
+ };
1079
+ var sidebarInfoValueStyles = {
1080
+ fontSize: "0.88rem",
1081
+ fontWeight: 600,
1082
+ color: C.text,
1083
+ wordBreak: "break-word",
1084
+ fontFamily: "ui-monospace, monospace"
1085
+ };
1086
+ var sidebarInfoSubStyles = {
1087
+ fontSize: "0.72rem",
1088
+ color: C.textMuted,
1089
+ fontFamily: "ui-monospace, monospace",
1090
+ marginTop: "0.25rem"
1091
+ };
1092
+ var mainPaneStyles = {
1093
+ minWidth: 0,
1094
+ overflowY: "auto",
1095
+ padding: "1rem"
1096
+ };
1097
+ var overviewLayoutStyles = {
1098
+ display: "flex",
1099
+ flexDirection: "column",
1100
+ gap: "1.25rem"
1101
+ };
1102
+ var overviewCardsRowStyles = {
1103
+ display: "grid",
1104
+ gridTemplateColumns: "repeat(auto-fit, minmax(11rem, 1fr))",
1105
+ gap: "0.75rem"
1106
+ };
1107
+ var overviewCardStyles = {
1108
+ padding: "0.9rem 1rem",
1109
+ borderRadius: "10px",
1110
+ border: `1px solid ${C.border}`,
1111
+ background: C.bgCard
1112
+ };
1113
+ var overviewCardLabelStyles = {
1114
+ fontSize: "0.68rem",
1115
+ fontWeight: 600,
1116
+ letterSpacing: "0.08em",
1117
+ textTransform: "uppercase",
1118
+ color: C.textMuted,
1119
+ marginBottom: "0.4rem"
1120
+ };
1121
+ var overviewCardValueStyles = {
1122
+ fontSize: "1rem",
1123
+ fontWeight: 700,
1124
+ color: C.text,
1125
+ wordBreak: "break-word"
1126
+ };
1127
+ var overviewSectionStyles = {
1128
+ display: "flex",
1129
+ flexDirection: "column",
1130
+ gap: "0.5rem"
1131
+ };
1132
+ var overviewSectionTitleStyles = {
1133
+ fontSize: "0.72rem",
1134
+ fontWeight: 600,
1135
+ letterSpacing: "0.08em",
1136
+ textTransform: "uppercase",
1137
+ color: C.textMuted
1138
+ };
1139
+ var overviewSectionHeaderStyles = {
1140
+ display: "flex",
1141
+ alignItems: "center",
1142
+ justifyContent: "space-between",
1143
+ gap: "0.75rem"
1144
+ };
1145
+ var overviewRefreshButtonStyles = {
1146
+ border: `1px solid ${C.border}`,
1147
+ borderRadius: "7px",
1148
+ padding: "0.35rem 0.7rem",
1149
+ backgroundColor: "transparent",
1150
+ color: C.textDim,
1151
+ fontSize: "0.78rem",
1152
+ fontFamily: "ui-monospace, monospace",
1153
+ cursor: "pointer",
1154
+ flexShrink: 0
1155
+ };
1156
+ var overviewAccumulatorValueStyles = {
1157
+ padding: "0.75rem",
1158
+ borderRadius: "8px",
1159
+ border: `1px solid ${C.border}`,
1160
+ background: C.bgCard,
1161
+ fontFamily: "ui-monospace, monospace",
1162
+ fontSize: "0.78rem",
1163
+ color: C.text,
1164
+ lineHeight: 1.5,
1165
+ wordBreak: "break-all"
1166
+ };
1167
+ var overviewAccumulatorEmptyStyles = {
1168
+ color: C.textMuted,
1169
+ fontStyle: "italic"
1170
+ };
1171
+ var overviewAccumulatorErrorStyles = {
1172
+ color: C.error
1173
+ };
1174
+ var overviewEmptyStyles = {
1175
+ fontSize: "0.82rem",
1176
+ color: C.textMuted,
1177
+ fontStyle: "italic"
1178
+ };
1179
+ var crdtTableListStyles = {
1180
+ display: "flex",
1181
+ flexDirection: "column",
1182
+ gap: "0.25rem"
1183
+ };
1184
+ var crdtTableRowStyles = {
1185
+ display: "flex",
1186
+ alignItems: "center",
1187
+ gap: "0.6rem",
1188
+ padding: "0.5rem 0.75rem",
1189
+ borderRadius: "7px",
1190
+ background: C.bgCard,
1191
+ border: `1px solid ${C.border}`
1192
+ };
1193
+ var crdtTableIconStyles = {
1194
+ color: C.teal,
1195
+ fontSize: "0.72rem"
1196
+ };
1197
+ var crdtTableNameStyles = {
1198
+ fontFamily: "ui-monospace, monospace",
1199
+ fontSize: "0.85rem",
1200
+ color: C.text
1201
+ };
1202
+ var permissionRowStyles = {
1203
+ display: "flex",
1204
+ alignItems: "center",
1205
+ gap: "0.6rem",
1206
+ fontSize: "0.82rem",
1207
+ color: C.textDim
1208
+ };
1209
+ var permissionIconStyles = {
1210
+ color: C.success,
1211
+ fontWeight: 700,
1212
+ fontSize: "0.85rem",
1213
+ lineHeight: 1
1214
+ };
1215
+ var permissionTextStyles = {
1216
+ color: C.textDim
1217
+ };
1218
+ var dangerZoneStyles = {
1219
+ marginTop: "auto",
1220
+ borderRadius: "10px",
1221
+ border: `1px solid ${C.errorBorder}`,
1222
+ padding: "0.75rem 1rem",
1223
+ background: C.errorBg
1224
+ };
1225
+ var dangerZoneTitleStyles = {
1226
+ fontSize: "0.65rem",
1227
+ fontWeight: 700,
1228
+ letterSpacing: "0.08em",
1229
+ textTransform: "uppercase",
1230
+ color: C.error,
1231
+ marginBottom: "0.5rem"
1232
+ };
1233
+ var dangerZoneRowStyles = {
1234
+ display: "flex",
1235
+ alignItems: "center",
1236
+ justifyContent: "space-between",
1237
+ gap: "1rem"
1238
+ };
1239
+ var dangerZoneDescStyles = {
1240
+ fontSize: "0.75rem",
1241
+ color: C.textMuted,
1242
+ lineHeight: 1.5
1243
+ };
1244
+ var dangerZoneActionsStyles = {
1245
+ display: "flex",
1246
+ gap: "0.4rem",
1247
+ flexShrink: 0
1248
+ };
1249
+ var resetButtonStyles = {
1250
+ flexShrink: 0,
1251
+ border: `1px solid ${C.errorBorder}`,
1252
+ borderRadius: "7px",
1253
+ padding: "0.35rem 0.75rem",
1254
+ backgroundColor: "transparent",
1255
+ color: C.error,
1256
+ fontSize: "0.78rem",
1257
+ fontWeight: 600,
1258
+ cursor: "pointer",
1259
+ whiteSpace: "nowrap"
1260
+ };
1261
+ var resetCancelButtonStyles = {
1262
+ border: `1px solid ${C.border}`,
1263
+ borderRadius: "7px",
1264
+ padding: "0.35rem 0.65rem",
1265
+ backgroundColor: "transparent",
1266
+ color: C.textDim,
1267
+ fontSize: "0.78rem",
1268
+ fontWeight: 600,
1269
+ cursor: "pointer",
1270
+ whiteSpace: "nowrap"
1271
+ };
1272
+ var resetConfirmButtonStyles = {
1273
+ border: "none",
1274
+ borderRadius: "7px",
1275
+ padding: "0.35rem 0.75rem",
1276
+ backgroundColor: C.error,
1277
+ color: "#0e1015",
1278
+ fontSize: "0.78rem",
1279
+ fontWeight: 700,
1280
+ cursor: "pointer",
1281
+ whiteSpace: "nowrap"
1282
+ };
1283
+ var queryRunnerLayoutStyles = {
1284
+ display: "flex",
1285
+ flexDirection: "column",
1286
+ gap: "0.75rem",
1287
+ height: "100%"
1288
+ };
1289
+ var queryToolbarStyles = {
1290
+ display: "flex",
1291
+ alignItems: "center",
1292
+ justifyContent: "space-between",
1293
+ gap: "0.75rem",
1294
+ flexWrap: "wrap"
1295
+ };
1296
+ var targetToggleStyles = {
1297
+ display: "flex",
1298
+ gap: "0",
1299
+ borderRadius: "8px",
1300
+ border: `1px solid ${C.border}`,
1301
+ overflow: "hidden",
1302
+ background: C.bgCard
1303
+ };
1304
+ var queryToolbarRightStyles = {
1305
+ display: "flex",
1306
+ alignItems: "center",
1307
+ gap: "0.6rem"
1308
+ };
1309
+ var noInstanceWarningStyles = {
1310
+ fontSize: "0.75rem",
1311
+ color: C.amber,
1312
+ fontWeight: 500
1313
+ };
1314
+ var shortcutHintStyles = {
1315
+ fontSize: "0.72rem",
1316
+ color: C.textMuted,
1317
+ fontFamily: "ui-monospace, monospace",
1318
+ padding: "0.2rem 0.5rem",
1319
+ borderRadius: "5px",
1320
+ border: `1px solid ${C.border}`,
1321
+ background: C.bgCard
1322
+ };
1323
+ var editorWrapperStyles = {
1324
+ borderRadius: "10px",
1325
+ border: `1px solid ${C.border}`,
1326
+ overflow: "hidden",
1327
+ background: C.bgInput
1328
+ };
1329
+ var textareaStyles = {
1330
+ width: "100%",
1331
+ minHeight: "9rem",
1332
+ resize: "vertical",
1333
+ border: "none",
1334
+ padding: "0.85rem 1rem",
1335
+ backgroundColor: "transparent",
1336
+ color: C.text,
1337
+ fontSize: "0.875rem",
1338
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
1339
+ lineHeight: 1.6,
1340
+ outline: "none",
1341
+ boxSizing: "border-box"
1342
+ };
1343
+ var helperTextStyles = {
1344
+ fontSize: "0.75rem",
1345
+ lineHeight: 1.5,
1346
+ color: C.textMuted
1347
+ };
1348
+ var resultPanelStyles = {
1349
+ display: "flex",
1350
+ flexDirection: "column",
1351
+ gap: "0.6rem",
1352
+ borderRadius: "10px",
1353
+ border: `1px solid ${C.border}`,
1354
+ overflow: "hidden",
1355
+ background: C.bgPanel
1356
+ };
1357
+ var errorPanelStyles = {
1358
+ display: "flex",
1359
+ flexDirection: "column",
1360
+ gap: "0.6rem",
1361
+ padding: "0.85rem 1rem",
1362
+ borderRadius: "10px",
1363
+ border: `1px solid ${C.errorBorder}`,
1364
+ background: C.errorBg
1365
+ };
1366
+ var resultHeaderStyles = {
1367
+ display: "flex",
1368
+ alignItems: "center",
1369
+ gap: "0.6rem",
1370
+ padding: "0.6rem 0.85rem",
1371
+ borderBottom: `1px solid ${C.border}`,
1372
+ background: C.bgCard
1373
+ };
1374
+ var successBadgeStyles = {
1375
+ fontSize: "0.72rem",
1376
+ fontWeight: 700,
1377
+ color: C.success,
1378
+ backgroundColor: C.successBg,
1379
+ borderRadius: "5px",
1380
+ padding: "0.15rem 0.5rem",
1381
+ fontFamily: "ui-monospace, monospace"
1382
+ };
1383
+ var errorBadgeStyles = {
1384
+ fontSize: "0.72rem",
1385
+ fontWeight: 700,
1386
+ color: C.error,
1387
+ backgroundColor: C.errorBg,
1388
+ borderRadius: "5px",
1389
+ padding: "0.15rem 0.5rem",
1390
+ fontFamily: "ui-monospace, monospace"
1391
+ };
1392
+ var resultMetaStyles = {
1393
+ fontSize: "0.72rem",
1394
+ color: C.textMuted,
1395
+ fontFamily: "ui-monospace, monospace"
1396
+ };
1397
+ var resultEmptyStyles = {
1398
+ padding: "1.5rem",
1399
+ fontSize: "0.82rem",
1400
+ color: C.textMuted,
1401
+ fontStyle: "italic",
1402
+ textAlign: "center"
1403
+ };
1404
+ var resultRawStyles = {
1405
+ margin: 0,
1406
+ padding: "0.85rem 1rem",
1407
+ overflowX: "auto",
1408
+ whiteSpace: "pre-wrap",
1409
+ wordBreak: "break-word",
1410
+ fontSize: "0.8rem",
1411
+ lineHeight: 1.5,
1412
+ color: C.text,
1413
+ fontFamily: "ui-monospace, monospace"
1414
+ };
1415
+ var errorMessageStyles = {
1416
+ margin: 0,
1417
+ fontSize: "0.82rem",
1418
+ lineHeight: 1.6,
1419
+ color: C.error,
1420
+ fontFamily: "ui-monospace, monospace",
1421
+ whiteSpace: "pre-wrap",
1422
+ wordBreak: "break-word"
1423
+ };
1424
+ var tableWrapperStyles = {
1425
+ overflowX: "auto",
1426
+ maxHeight: "320px",
1427
+ overflowY: "auto"
1428
+ };
1429
+ var tableStyles = {
1430
+ width: "100%",
1431
+ borderCollapse: "collapse",
1432
+ fontSize: "0.8rem",
1433
+ fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace"
1434
+ };
1435
+ var thStyles = {
1436
+ padding: "0.5rem 0.85rem",
1437
+ textAlign: "left",
1438
+ fontWeight: 600,
1439
+ fontSize: "0.7rem",
1440
+ letterSpacing: "0.05em",
1441
+ textTransform: "uppercase",
1442
+ color: C.textMuted,
1443
+ borderBottom: `1px solid ${C.border}`,
1444
+ borderRight: `1px solid ${C.border}`,
1445
+ background: C.bgCard,
1446
+ whiteSpace: "nowrap",
1447
+ position: "sticky",
1448
+ top: 0
1449
+ };
1450
+ var thRowNumStyles = {
1451
+ ...thStyles,
1452
+ color: C.textMuted,
1453
+ opacity: 0.5,
1454
+ width: "2.5rem",
1455
+ textAlign: "right"
1456
+ };
1457
+ var trStyles = {
1458
+ background: "transparent"
1459
+ };
1460
+ var trAltStyles = {
1461
+ background: C.tealGlow
1462
+ };
1463
+ var tdStyles = {
1464
+ padding: "0.45rem 0.85rem",
1465
+ borderBottom: `1px solid ${C.border}`,
1466
+ borderRight: `1px solid ${C.border}`,
1467
+ color: C.text,
1468
+ whiteSpace: "nowrap",
1469
+ maxWidth: "300px",
1470
+ overflow: "hidden",
1471
+ textOverflow: "ellipsis"
1472
+ };
1473
+ var tdRowNumStyles = {
1474
+ ...tdStyles,
1475
+ color: C.textMuted,
1476
+ opacity: 0.5,
1477
+ textAlign: "right",
1478
+ userSelect: "none"
1479
+ };
1480
+ var nullValueStyles = {
1481
+ color: C.textMuted,
1482
+ fontStyle: "italic",
1483
+ opacity: 0.6
1484
+ };
1485
+ var jsonValueStyles = {
1486
+ color: C.textDim
1487
+ };
1488
+ function getTabButtonStyles(isActive) {
1489
+ return {
1490
+ display: "flex",
1491
+ alignItems: "center",
1492
+ gap: "0.5rem",
1493
+ width: "100%",
1494
+ border: "none",
1495
+ borderRadius: "7px",
1496
+ padding: "0.6rem 0.75rem",
1497
+ background: isActive ? C.tealDim : "transparent",
1498
+ color: isActive ? C.teal : C.textDim,
1499
+ fontSize: "0.82rem",
1500
+ fontWeight: isActive ? 700 : 500,
1501
+ textAlign: "left",
1502
+ cursor: "pointer",
1503
+ transition: "background 0.15s",
1504
+ borderLeft: isActive ? `2px solid ${C.teal}` : "2px solid transparent"
1505
+ };
1506
+ }
1507
+ function getTargetButtonStyles(isActive) {
1508
+ return {
1509
+ border: "none",
1510
+ borderRight: `1px solid ${C.border}`,
1511
+ padding: "0.45rem 0.85rem",
1512
+ background: isActive ? C.tealDim : "transparent",
1513
+ color: isActive ? C.teal : C.textMuted,
1514
+ fontSize: "0.78rem",
1515
+ fontWeight: isActive ? 700 : 500,
1516
+ cursor: "pointer",
1517
+ fontFamily: "ui-monospace, monospace",
1518
+ transition: "background 0.1s",
1519
+ whiteSpace: "nowrap"
1520
+ };
1521
+ }
1522
+ function runButtonStyles(enabled, running) {
1523
+ return {
1524
+ display: "inline-flex",
1525
+ alignItems: "center",
1526
+ gap: "0.4rem",
1527
+ border: "none",
1528
+ borderRadius: "7px",
1529
+ padding: "0.45rem 0.9rem",
1530
+ background: enabled ? C.teal : C.bgCard,
1531
+ color: enabled ? "#0e1015" : C.textMuted,
1532
+ fontSize: "0.82rem",
1533
+ fontWeight: 700,
1534
+ fontFamily: "ui-monospace, monospace",
1535
+ cursor: enabled ? "pointer" : "not-allowed",
1536
+ opacity: running ? 0.75 : 1,
1537
+ transition: "background 0.15s",
1538
+ whiteSpace: "nowrap"
1539
+ };
1540
+ }
1541
+ var runningDotStyles = {
1542
+ width: "6px",
1543
+ height: "6px",
1544
+ borderRadius: "50%",
1545
+ backgroundColor: "currentColor",
1546
+ animation: "pulse 1s infinite"
1547
+ };
1548
+ var schemaLayoutStyles = {
1549
+ display: "flex",
1550
+ flexDirection: "column",
1551
+ gap: "1.5rem"
1552
+ };
1553
+ var schemaSectionStyles = {
1554
+ display: "flex",
1555
+ flexDirection: "column",
1556
+ gap: "0.65rem"
1557
+ };
1558
+ var schemaSectionHeaderStyles = {
1559
+ display: "flex",
1560
+ alignItems: "center",
1561
+ gap: "0.6rem"
1562
+ };
1563
+ var schemaSectionTitleStyles = {
1564
+ fontSize: "0.72rem",
1565
+ fontWeight: 700,
1566
+ letterSpacing: "0.08em",
1567
+ textTransform: "uppercase",
1568
+ color: C.textMuted
1569
+ };
1570
+ var schemaBadgeStyles = {
1571
+ fontSize: "0.68rem",
1572
+ fontWeight: 700,
1573
+ color: C.teal,
1574
+ backgroundColor: C.tealDim,
1575
+ borderRadius: "4px",
1576
+ padding: "0.1rem 0.4rem",
1577
+ fontFamily: "ui-monospace, monospace"
1578
+ };
1579
+ var schemaMigrationsMetaStyles = {
1580
+ display: "flex",
1581
+ alignItems: "center",
1582
+ gap: "0.5rem",
1583
+ marginLeft: "auto"
1584
+ };
1585
+ var schemaVersionChipStyles = {
1586
+ fontSize: "0.68rem",
1587
+ fontFamily: "ui-monospace, monospace",
1588
+ color: C.textMuted,
1589
+ backgroundColor: C.bgCard,
1590
+ border: `1px solid ${C.border}`,
1591
+ borderRadius: "4px",
1592
+ padding: "0.1rem 0.5rem"
1593
+ };
1594
+ var schemaTableGridStyles = {
1595
+ borderRadius: "10px",
1596
+ border: `1px solid ${C.border}`,
1597
+ overflow: "hidden"
1598
+ };
1599
+ var schemaTableHeaderRowStyles = {
1600
+ display: "grid",
1601
+ gridTemplateColumns: "1fr 1fr 90px",
1602
+ gap: 0,
1603
+ backgroundColor: C.bgCard,
1604
+ borderBottom: `1px solid ${C.border}`
1605
+ };
1606
+ var schemaColHeaderStyles = {
1607
+ padding: "0.5rem 0.85rem",
1608
+ fontSize: "0.68rem",
1609
+ fontWeight: 700,
1610
+ letterSpacing: "0.07em",
1611
+ textTransform: "uppercase",
1612
+ color: C.textMuted,
1613
+ borderRight: `1px solid ${C.border}`
1614
+ };
1615
+ var schemaTableRowStyles = {
1616
+ display: "grid",
1617
+ gridTemplateColumns: "1fr 1fr 90px",
1618
+ gap: 0,
1619
+ borderBottom: `1px solid ${C.border}`
1620
+ };
1621
+ var schemaTableNameStyles = {
1622
+ display: "flex",
1623
+ alignItems: "center",
1624
+ gap: "0.5rem",
1625
+ padding: "0.6rem 0.85rem",
1626
+ fontSize: "0.82rem",
1627
+ fontFamily: "ui-monospace, monospace",
1628
+ color: C.text,
1629
+ borderRight: `1px solid ${C.border}`
1630
+ };
1631
+ var schemaTableIconStyles = {
1632
+ color: C.teal,
1633
+ fontSize: "0.68rem",
1634
+ opacity: 0.8
1635
+ };
1636
+ var schemaCrdtNameStyles = {
1637
+ display: "flex",
1638
+ alignItems: "center",
1639
+ padding: "0.6rem 0.85rem",
1640
+ fontSize: "0.82rem",
1641
+ fontFamily: "ui-monospace, monospace",
1642
+ color: C.textDim,
1643
+ borderRight: `1px solid ${C.border}`
1644
+ };
1645
+ var schemaStatusCellStyles = {
1646
+ display: "flex",
1647
+ alignItems: "center",
1648
+ justifyContent: "center",
1649
+ padding: "0.6rem 0.5rem"
1650
+ };
1651
+ var schemaActiveTagStyles = {
1652
+ fontSize: "0.68rem",
1653
+ fontWeight: 700,
1654
+ color: C.success,
1655
+ backgroundColor: C.successBg,
1656
+ borderRadius: "4px",
1657
+ padding: "0.15rem 0.45rem",
1658
+ fontFamily: "ui-monospace, monospace"
1659
+ };
1660
+ var schemaEmptyStyles = {
1661
+ fontSize: "0.82rem",
1662
+ color: C.textMuted,
1663
+ fontStyle: "italic"
1664
+ };
1665
+ var migrationListStyles = {
1666
+ display: "flex",
1667
+ flexDirection: "column",
1668
+ gap: "0.35rem"
1669
+ };
1670
+ function getMigrationRowStyles(applied) {
1671
+ return {
1672
+ display: "grid",
1673
+ gridTemplateColumns: "3.5rem 1fr 70px",
1674
+ alignItems: "center",
1675
+ gap: "0.75rem",
1676
+ padding: "0.55rem 0.85rem",
1677
+ borderRadius: "8px",
1678
+ background: applied ? C.bgCard : "transparent",
1679
+ border: `1px solid ${applied ? C.border : C.borderLight}`,
1680
+ opacity: applied ? 1 : 0.55
1681
+ };
1682
+ }
1683
+ var migrationVersionStyles = {
1684
+ fontSize: "0.78rem",
1685
+ fontWeight: 700,
1686
+ fontFamily: "ui-monospace, monospace",
1687
+ color: C.textDim
1688
+ };
1689
+ var migrationBarTrackStyles = {
1690
+ height: "4px",
1691
+ borderRadius: "2px",
1692
+ backgroundColor: C.border,
1693
+ overflow: "hidden"
1694
+ };
1695
+ function getMigrationBarFillStyles(applied) {
1696
+ return {
1697
+ height: "100%",
1698
+ width: applied ? "100%" : "0%",
1699
+ borderRadius: "2px",
1700
+ backgroundColor: C.teal,
1701
+ transition: "width 0.3s ease"
1702
+ };
1703
+ }
1704
+ function getMigrationTagStyles(applied, isCurrent) {
1705
+ if (isCurrent) {
1706
+ return {
1707
+ fontSize: "0.68rem",
1708
+ fontWeight: 700,
1709
+ color: C.teal,
1710
+ backgroundColor: C.tealDim,
1711
+ borderRadius: "4px",
1712
+ padding: "0.15rem 0.45rem",
1713
+ fontFamily: "ui-monospace, monospace",
1714
+ textAlign: "center"
1715
+ };
1716
+ }
1717
+ if (applied) {
1718
+ return {
1719
+ fontSize: "0.68rem",
1720
+ fontWeight: 600,
1721
+ color: C.success,
1722
+ backgroundColor: C.successBg,
1723
+ borderRadius: "4px",
1724
+ padding: "0.15rem 0.45rem",
1725
+ fontFamily: "ui-monospace, monospace",
1726
+ textAlign: "center"
1727
+ };
1728
+ }
1729
+ return {
1730
+ fontSize: "0.68rem",
1731
+ fontWeight: 600,
1732
+ color: C.amber,
1733
+ backgroundColor: "rgba(251,191,36,0.08)",
1734
+ borderRadius: "4px",
1735
+ padding: "0.15rem 0.45rem",
1736
+ fontFamily: "ui-monospace, monospace",
1737
+ textAlign: "center"
1738
+ };
1739
+ }
1740
+ var eventLogLayoutStyles = {
1741
+ display: "flex",
1742
+ flexDirection: "column",
1743
+ gap: "0.75rem",
1744
+ height: "100%"
1745
+ };
1746
+ var eventLogToolbarStyles = {
1747
+ display: "flex",
1748
+ alignItems: "center",
1749
+ gap: "0.5rem",
1750
+ flexWrap: "wrap",
1751
+ flexShrink: 0
1752
+ };
1753
+ var eventLogFilterSelectStyles = {
1754
+ borderRadius: "7px",
1755
+ border: `1px solid ${C.border}`,
1756
+ padding: "0.35rem 0.6rem",
1757
+ backgroundColor: C.bgCard,
1758
+ color: C.text,
1759
+ fontSize: "0.78rem",
1760
+ fontFamily: "ui-monospace, monospace",
1761
+ cursor: "pointer"
1762
+ };
1763
+ var eventLogRefreshButtonStyles = {
1764
+ border: `1px solid ${C.border}`,
1765
+ borderRadius: "7px",
1766
+ padding: "0.35rem 0.7rem",
1767
+ backgroundColor: "transparent",
1768
+ color: C.textDim,
1769
+ fontSize: "0.78rem",
1770
+ fontFamily: "ui-monospace, monospace",
1771
+ cursor: "pointer"
1772
+ };
1773
+ var eventLogCountStyles = {
1774
+ marginLeft: "auto",
1775
+ fontSize: "0.72rem",
1776
+ fontFamily: "ui-monospace, monospace",
1777
+ color: C.textMuted
1778
+ };
1779
+ var eventLogEmptyStyles = {
1780
+ padding: "2rem",
1781
+ textAlign: "center",
1782
+ fontSize: "0.82rem",
1783
+ color: C.textMuted,
1784
+ fontStyle: "italic"
1785
+ };
1786
+ var eventLogListStyles = {
1787
+ display: "flex",
1788
+ flexDirection: "column",
1789
+ gap: "0.25rem",
1790
+ overflowY: "auto",
1791
+ flex: 1
1792
+ };
1793
+ function getEventRowStyles(isExpanded) {
1794
+ return {
1795
+ borderRadius: "8px",
1796
+ border: `1px solid ${isExpanded ? `${C.teal}40` : C.border}`,
1797
+ background: isExpanded ? C.tealGlow : C.bgCard,
1798
+ overflow: "hidden",
1799
+ flexShrink: 0
1800
+ };
1801
+ }
1802
+ var eventRowHeaderStyles = {
1803
+ display: "flex",
1804
+ alignItems: "center",
1805
+ gap: "0.5rem",
1806
+ width: "100%",
1807
+ padding: "0.5rem 0.75rem",
1808
+ background: "transparent",
1809
+ border: "none",
1810
+ cursor: "pointer",
1811
+ textAlign: "left",
1812
+ flexWrap: "wrap"
1813
+ };
1814
+ var eventSyncIdStyles = {
1815
+ fontSize: "0.7rem",
1816
+ fontFamily: "ui-monospace, monospace",
1817
+ color: C.textMuted,
1818
+ minWidth: "3.5rem"
1819
+ };
1820
+ var eventDatasetStyles = {
1821
+ fontSize: "0.8rem",
1822
+ fontFamily: "ui-monospace, monospace",
1823
+ color: C.text,
1824
+ fontWeight: 600
1825
+ };
1826
+ var eventItemIdStyles = {
1827
+ fontSize: "0.75rem",
1828
+ fontFamily: "ui-monospace, monospace",
1829
+ color: C.textMuted,
1830
+ flex: 1,
1831
+ overflow: "hidden",
1832
+ textOverflow: "ellipsis",
1833
+ whiteSpace: "nowrap",
1834
+ minWidth: 0
1835
+ };
1836
+ var eventTimestampStyles = {
1837
+ fontSize: "0.7rem",
1838
+ fontFamily: "ui-monospace, monospace",
1839
+ color: C.textMuted,
1840
+ marginLeft: "auto"
1841
+ };
1842
+ var eventChevronStyles = {
1843
+ fontSize: "0.6rem",
1844
+ color: C.textMuted,
1845
+ marginLeft: "0.25rem"
1846
+ };
1847
+ var eventPayloadStyles = {
1848
+ borderTop: `1px solid ${C.border}`,
1849
+ padding: "0.6rem 0.75rem"
1850
+ };
1851
+ var eventPayloadMetaStyles = {
1852
+ display: "flex",
1853
+ gap: "0.75rem",
1854
+ marginBottom: "0.5rem"
1855
+ };
1856
+ var eventMetaItemStyles = {
1857
+ fontSize: "0.68rem",
1858
+ fontFamily: "ui-monospace, monospace",
1859
+ color: C.textMuted
1860
+ };
1861
+ var eventPayloadPreStyles = {
1862
+ margin: 0,
1863
+ fontSize: "0.78rem",
1864
+ fontFamily: "ui-monospace, monospace",
1865
+ color: C.text,
1866
+ lineHeight: 1.5,
1867
+ whiteSpace: "pre-wrap",
1868
+ wordBreak: "break-word"
1869
+ };
1870
+ var loadMoreButtonStyles = {
1871
+ width: "100%",
1872
+ border: `1px solid ${C.border}`,
1873
+ borderRadius: "8px",
1874
+ padding: "0.6rem",
1875
+ backgroundColor: "transparent",
1876
+ color: C.textDim,
1877
+ fontSize: "0.78rem",
1878
+ fontFamily: "ui-monospace, monospace",
1879
+ cursor: "pointer",
1880
+ flexShrink: 0
1881
+ };
1882
+ var eventTypeBadgeBase = {
1883
+ fontSize: "0.65rem",
1884
+ fontWeight: 700,
1885
+ borderRadius: "4px",
1886
+ padding: "0.1rem 0.4rem",
1887
+ fontFamily: "ui-monospace, monospace",
1888
+ whiteSpace: "nowrap"
1889
+ };
1890
+ var eventTypeCreateStyles = {
1891
+ ...eventTypeBadgeBase,
1892
+ color: C.teal,
1893
+ backgroundColor: C.tealDim
1894
+ };
1895
+ var eventTypeUpdateStyles = {
1896
+ ...eventTypeBadgeBase,
1897
+ color: "#a78bfa",
1898
+ backgroundColor: "rgba(167,139,250,0.12)"
1899
+ };
1900
+ var eventOriginOwnStyles = {
1901
+ ...eventTypeBadgeBase,
1902
+ color: C.success,
1903
+ backgroundColor: C.successBg
1904
+ };
1905
+ var eventOriginRemoteStyles = {
1906
+ ...eventTypeBadgeBase,
1907
+ color: C.amber,
1908
+ backgroundColor: "rgba(251,191,36,0.1)"
1909
+ };
1910
+ var eventOriginLocalStyles = {
1911
+ ...eventTypeBadgeBase,
1912
+ color: C.textDim,
1913
+ backgroundColor: C.bgCard,
1914
+ border: `1px solid ${C.border}`
1915
+ };
1916
+ var eventStatusAppliedStyles = {
1917
+ ...eventTypeBadgeBase,
1918
+ color: C.success,
1919
+ backgroundColor: C.successBg
1920
+ };
1921
+ var eventStatusPendingStyles = {
1922
+ ...eventTypeBadgeBase,
1923
+ color: C.amber,
1924
+ backgroundColor: "rgba(251,191,36,0.1)"
1925
+ };
1926
+ var eventStatusFailedStyles = {
1927
+ ...eventTypeBadgeBase,
1928
+ color: C.error,
1929
+ backgroundColor: C.errorBg
1930
+ };
1931
+ var eventStatusSkippedStyles = {
1932
+ ...eventTypeBadgeBase,
1933
+ color: C.textMuted,
1934
+ backgroundColor: C.bgCard
1935
+ };
1936
+ export {
1937
+ SQLiteSyncDevtools
1938
+ };
1939
+ //# sourceMappingURL=index.js.map