@concavejs/devtools 0.0.1-alpha.4

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.

Potentially problematic release.


This version of @concavejs/devtools might be problematic. Click here for more details.

@@ -0,0 +1,7 @@
1
+ /**
2
+ * Client entry point for DevTools
3
+ * This is injected into the browser by the Vite plugin
4
+ */
5
+ export declare function initDevTools(options?: {
6
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
7
+ }): void;
package/dist/client.js ADDED
@@ -0,0 +1,5 @@
1
+ import "react/jsx-runtime";
2
+ import { i as t } from "./client-D6NyDOCN.js";
3
+ export {
4
+ t as initDevTools
5
+ };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Page Agent — Thin IIFE injected into the page context.
3
+ *
4
+ * Intercepts WebSocket traffic using the same WebSocketInterceptor,
5
+ * but instead of a full EventStore it posts events to the content script
6
+ * via window.postMessage. Buffers the last 500 events for late-opening panels.
7
+ */
8
+ export {};
@@ -0,0 +1,14 @@
1
+ /**
2
+ * DevTools Panel Entry — React app rendered inside the Chrome DevTools "Concave" tab.
3
+ *
4
+ * Uses chrome.devtools.inspectedWindow.reload({ injectedScript }) to install a
5
+ * WebSocket interceptor BEFORE any page scripts run. This guarantees full
6
+ * interception without any permissions beyond the devtools_page manifest key.
7
+ *
8
+ * Flow:
9
+ * 1. Panel opens → try eval() injection (catches new WS connections)
10
+ * 2. If page already has a connection → show "Reload" button
11
+ * 3. Reload uses inspectedWindow.reload({ injectedScript }) — runs before page JS
12
+ * 4. On navigation → re-inject via eval()
13
+ */
14
+ import "../devtools.css";
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Concave DevTools
3
+ *
4
+ * Client-side development tools for Convex/Concave applications
5
+ */
6
+ export type { DevToolsEvent, QueryEvent, MutationEvent, ActionEvent, SubscriptionEvent, LogEvent, AuthEvent, ActiveSubscription, PerformanceMetrics, EventType, EventStatus, SubscriptionStatus, } from "./types";
7
+ export { EventStore, getGlobalEventStore } from "./store/event-store";
8
+ export type { EventListener, StoreSnapshot, ExportedSession } from "./store/event-store";
9
+ export { WebSocketInterceptor } from "./interceptor/websocket-interceptor";
10
+ export { DevToolbar } from "./overlay/DevToolbar";
11
+ export { SubscriptionsPanel } from "./overlay/SubscriptionsPanel";
12
+ export { PerformancePanel } from "./overlay/PerformancePanel";
13
+ export { LogsPanel } from "./overlay/LogsPanel";
14
+ export { SettingsPanel } from "./overlay/SettingsPanel";
15
+ export { DataInspector } from "./overlay/DataInspector";
16
+ export { initDevTools } from "./client";
17
+ export { default as concaveDevTools } from "./vite-plugin/index";
18
+ export type { DevToolsOptions } from "./vite-plugin/index";
package/dist/index.js ADDED
@@ -0,0 +1,380 @@
1
+ var m = Object.defineProperty;
2
+ var v = (c, e, t) => e in c ? m(c, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : c[e] = t;
3
+ var d = (c, e, t) => v(c, typeof e != "symbol" ? e + "" : e, t);
4
+ import { b as w, D as P, E, L as S, P as A, a as L, S as M, g as D, i as $ } from "./client-D6NyDOCN.js";
5
+ import { concaveDevTools as R } from "./vite-plugin.js";
6
+ function T(c) {
7
+ const e = c.split(".");
8
+ if (e.length < 2) return null;
9
+ try {
10
+ const t = e[1].replace(/-/g, "+").replace(/_/g, "/"), n = t + "=".repeat((4 - t.length % 4) % 4), s = JSON.parse(atob(n)), o = ["iss", "sub", "aud", "exp", "iat", "nbf"], i = {};
11
+ for (const a of o) {
12
+ const u = s[a];
13
+ u !== void 0 && (i[a] = u);
14
+ }
15
+ return typeof i.exp == "number" && (i.expIso = new Date(i.exp * 1e3).toISOString()), typeof i.iat == "number" && (i.iatIso = new Date(i.iat * 1e3).toISOString()), Object.keys(i).length > 0 ? i : null;
16
+ } catch {
17
+ return null;
18
+ }
19
+ }
20
+ class I {
21
+ constructor(e) {
22
+ d(this, "eventStore");
23
+ d(this, "originalWebSocket");
24
+ d(this, "pendingQueries", /* @__PURE__ */ new Map());
25
+ d(this, "pendingMutations", /* @__PURE__ */ new Map());
26
+ d(this, "pendingActions", /* @__PURE__ */ new Map());
27
+ d(this, "pendingAuthTokenType", null);
28
+ /** Tracks the most recent mutation event ID for causality linking */
29
+ d(this, "lastMutationEventId", null);
30
+ d(this, "lastMutationTimestamp", 0);
31
+ this.eventStore = e, this.originalWebSocket = window.WebSocket;
32
+ }
33
+ /**
34
+ * Install the WebSocket interceptor
35
+ */
36
+ install() {
37
+ const e = this, t = this.originalWebSocket;
38
+ class n extends t {
39
+ constructor(o, i) {
40
+ super(o, i);
41
+ const a = this.addEventListener.bind(this);
42
+ this.addEventListener = (r, l, h) => {
43
+ r === "message" && typeof l == "function" ? a("message", (p) => {
44
+ try {
45
+ e.handleServerMessage(p.data);
46
+ } catch (f) {
47
+ console.warn("[DevTools] Error parsing server message:", f);
48
+ }
49
+ l(p);
50
+ }, h) : a(r, l, h);
51
+ };
52
+ let u = null;
53
+ Object.defineProperty(this, "onmessage", {
54
+ get: () => u,
55
+ set: (r) => {
56
+ u = r, r && a("message", (h) => {
57
+ try {
58
+ e.handleServerMessage(h.data);
59
+ } catch (g) {
60
+ console.warn("[DevTools] Error parsing server message:", g);
61
+ }
62
+ r.call(this, h);
63
+ });
64
+ },
65
+ configurable: !0,
66
+ enumerable: !0
67
+ });
68
+ const y = this.send.bind(this);
69
+ this.send = (r) => {
70
+ try {
71
+ typeof r == "string" && e.handleClientMessage(r);
72
+ } catch (l) {
73
+ console.warn("[DevTools] Error parsing client message:", l);
74
+ }
75
+ y(r);
76
+ };
77
+ }
78
+ }
79
+ window.WebSocket = n, console.log("[DevTools] WebSocket interceptor installed");
80
+ }
81
+ /**
82
+ * Uninstall the interceptor
83
+ */
84
+ uninstall() {
85
+ window.WebSocket = this.originalWebSocket;
86
+ }
87
+ /**
88
+ * Handle client → server messages
89
+ */
90
+ handleClientMessage(e) {
91
+ try {
92
+ const t = JSON.parse(e);
93
+ switch (console.log("[DevTools] Client message:", t.type, t), t.type) {
94
+ case "ModifyQuerySet":
95
+ this.handleModifyQuerySet(t.modifications);
96
+ break;
97
+ case "Mutation":
98
+ this.handleMutationRequest(t);
99
+ break;
100
+ case "Action":
101
+ this.handleActionRequest(t);
102
+ break;
103
+ case "Connect":
104
+ this.handleConnectMessage(t);
105
+ break;
106
+ case "Authenticate":
107
+ this.handleAuthenticateMessage(t);
108
+ break;
109
+ }
110
+ } catch (t) {
111
+ console.warn("[DevTools] Failed to parse client message:", t);
112
+ }
113
+ }
114
+ /**
115
+ * Handle server → client messages
116
+ */
117
+ handleServerMessage(e) {
118
+ try {
119
+ const t = JSON.parse(e);
120
+ switch (console.log("[DevTools] Server message:", t.type, t), t.type) {
121
+ case "Transition":
122
+ this.handleTransition(t);
123
+ break;
124
+ case "MutationResponse":
125
+ this.handleMutationResponse(t);
126
+ break;
127
+ case "ActionResponse":
128
+ this.handleActionResponse(t);
129
+ break;
130
+ case "AuthError":
131
+ this.handleAuthErrorResponse(t);
132
+ break;
133
+ }
134
+ } catch (t) {
135
+ console.warn("[DevTools] Failed to parse server message:", t);
136
+ }
137
+ }
138
+ /**
139
+ * Handle query set modifications (subscriptions)
140
+ */
141
+ handleModifyQuerySet(e) {
142
+ const t = Date.now();
143
+ for (const n of e)
144
+ if (n.type === "Add") {
145
+ this.pendingQueries.set(n.queryId, {
146
+ queryId: n.queryId,
147
+ udfPath: n.udfPath,
148
+ args: n.args,
149
+ componentPath: n.componentPath,
150
+ startTime: t
151
+ });
152
+ const s = {
153
+ id: `sub-${n.queryId}-${t}`,
154
+ timestamp: t,
155
+ type: "subscription",
156
+ queryId: n.queryId,
157
+ udfPath: n.udfPath,
158
+ args: n.args,
159
+ componentPath: n.componentPath,
160
+ status: "added"
161
+ };
162
+ this.eventStore.addEvent(s);
163
+ } else if (n.type === "Remove") {
164
+ const s = this.pendingQueries.get(n.queryId);
165
+ if (this.pendingQueries.delete(n.queryId), s) {
166
+ const o = {
167
+ id: `sub-${n.queryId}-${t}`,
168
+ timestamp: t,
169
+ type: "subscription",
170
+ queryId: n.queryId,
171
+ udfPath: s.udfPath,
172
+ args: s.args,
173
+ componentPath: s.componentPath,
174
+ status: "removed"
175
+ };
176
+ this.eventStore.addEvent(o);
177
+ }
178
+ }
179
+ }
180
+ /**
181
+ * Handle mutation requests
182
+ */
183
+ handleMutationRequest(e) {
184
+ const t = Date.now();
185
+ this.pendingMutations.set(e.requestId, {
186
+ requestId: e.requestId,
187
+ udfPath: e.udfPath,
188
+ args: e.args,
189
+ componentPath: e.componentPath,
190
+ startTime: t
191
+ });
192
+ }
193
+ /**
194
+ * Handle action requests
195
+ */
196
+ handleActionRequest(e) {
197
+ const t = Date.now();
198
+ this.pendingActions.set(e.requestId, {
199
+ requestId: e.requestId,
200
+ udfPath: e.udfPath,
201
+ args: e.args,
202
+ componentPath: e.componentPath,
203
+ startTime: t
204
+ });
205
+ }
206
+ handleConnectMessage(e) {
207
+ const t = {};
208
+ typeof e.connectionCount == "number" && (t.connectionCount = e.connectionCount), typeof e.lastCloseReason == "string" && (t.lastCloseReason = e.lastCloseReason), typeof e.clientTs == "number" && (t.clientTs = e.clientTs), typeof e.sessionId == "string" && (t.sessionId = e.sessionId), this.emitAuthEvent({
209
+ direction: "client",
210
+ messageType: "Connect",
211
+ status: "success",
212
+ details: t
213
+ });
214
+ }
215
+ handleAuthenticateMessage(e) {
216
+ const t = {};
217
+ if (typeof e.baseVersion == "number" && (t.baseVersion = e.baseVersion), typeof e.tokenType == "string" && (t.tokenType = e.tokenType), typeof e.value == "string" && e.value.length > 0) {
218
+ const n = e.value;
219
+ t.tokenLength = n.length, t.tokenPreview = n.length > 24 ? `${n.slice(0, 12)}…${n.slice(-10)}` : n;
220
+ const s = T(n);
221
+ s && (t.jwtClaims = s);
222
+ }
223
+ this.pendingAuthTokenType = e.tokenType ?? "Unknown", this.emitAuthEvent({
224
+ direction: "client",
225
+ messageType: "Authenticate",
226
+ status: "success",
227
+ tokenType: e.tokenType,
228
+ details: t
229
+ });
230
+ }
231
+ /**
232
+ * Handle state transitions (query updates)
233
+ */
234
+ handleTransition(e) {
235
+ const t = Date.now();
236
+ this.pendingAuthTokenType && (this.emitAuthEvent({
237
+ direction: "server",
238
+ messageType: "Authenticated",
239
+ status: "success",
240
+ tokenType: this.pendingAuthTokenType,
241
+ details: { modificationCount: e.modifications.length }
242
+ }), this.pendingAuthTokenType = null);
243
+ for (const n of e.modifications)
244
+ if (n.type === "QueryUpdated") {
245
+ const s = this.pendingQueries.get(n.queryId);
246
+ if (!s) continue;
247
+ const o = t - s.startTime, i = this.lastMutationEventId && t - this.lastMutationTimestamp < 2e3 ? this.lastMutationEventId : void 0, a = {
248
+ id: `query-${n.queryId}-${t}`,
249
+ timestamp: t,
250
+ type: "query",
251
+ queryId: n.queryId,
252
+ udfPath: s.udfPath,
253
+ args: s.args,
254
+ componentPath: s.componentPath,
255
+ status: "success",
256
+ result: n.value,
257
+ logLines: n.logLines,
258
+ duration: o,
259
+ triggeredBy: i
260
+ };
261
+ this.eventStore.addEvent(a), Array.isArray(n.logLines) && n.logLines.length > 0 && this.emitLogEvents(n.logLines, a.id);
262
+ } else if (n.type === "QueryFailed") {
263
+ const s = this.pendingQueries.get(n.queryId);
264
+ if (!s) continue;
265
+ const o = t - s.startTime, i = {
266
+ id: `query-${n.queryId}-${t}`,
267
+ timestamp: t,
268
+ type: "query",
269
+ queryId: n.queryId,
270
+ udfPath: s.udfPath,
271
+ args: s.args,
272
+ componentPath: s.componentPath,
273
+ status: "error",
274
+ error: n.errorMessage,
275
+ logLines: n.logLines,
276
+ duration: o
277
+ };
278
+ this.eventStore.addEvent(i), Array.isArray(n.logLines) && n.logLines.length > 0 && this.emitLogEvents(n.logLines, i.id);
279
+ }
280
+ }
281
+ /**
282
+ * Handle mutation responses
283
+ */
284
+ handleMutationResponse(e) {
285
+ const t = this.pendingMutations.get(e.requestId);
286
+ if (!t) return;
287
+ const n = Date.now(), s = n - t.startTime, o = {
288
+ id: `mutation-${e.requestId}-${n}`,
289
+ timestamp: n,
290
+ type: "mutation",
291
+ requestId: e.requestId,
292
+ udfPath: t.udfPath,
293
+ args: t.args,
294
+ componentPath: t.componentPath,
295
+ status: e.success ? "success" : "error",
296
+ result: e.success ? e.result : void 0,
297
+ error: e.success ? void 0 : e.result,
298
+ logLines: e.logLines,
299
+ duration: s
300
+ };
301
+ this.eventStore.addEvent(o), this.lastMutationEventId = o.id, this.lastMutationTimestamp = n, e.logLines && e.logLines.length > 0 && this.emitLogEvents(e.logLines, o.id), this.pendingMutations.delete(e.requestId);
302
+ }
303
+ /**
304
+ * Handle action responses
305
+ */
306
+ handleActionResponse(e) {
307
+ const t = this.pendingActions.get(e.requestId);
308
+ if (!t) return;
309
+ const n = Date.now(), s = n - t.startTime, o = {
310
+ id: `action-${e.requestId}-${n}`,
311
+ timestamp: n,
312
+ type: "action",
313
+ requestId: e.requestId,
314
+ udfPath: t.udfPath,
315
+ args: t.args,
316
+ componentPath: t.componentPath,
317
+ status: e.success ? "success" : "error",
318
+ result: e.success ? e.result : void 0,
319
+ error: e.success ? void 0 : e.result,
320
+ logLines: e.logLines,
321
+ duration: s
322
+ };
323
+ this.eventStore.addEvent(o), e.logLines && e.logLines.length > 0 && this.emitLogEvents(e.logLines, o.id), this.pendingActions.delete(e.requestId);
324
+ }
325
+ handleAuthErrorResponse(e) {
326
+ const t = {};
327
+ typeof e.baseVersion == "number" && (t.baseVersion = e.baseVersion), typeof e.authUpdateAttempted == "boolean" && (t.authUpdateAttempted = e.authUpdateAttempted), this.emitAuthEvent({
328
+ direction: "server",
329
+ messageType: "AuthError",
330
+ status: "error",
331
+ tokenType: this.pendingAuthTokenType ?? void 0,
332
+ error: e.error ?? "Authentication failed",
333
+ details: t
334
+ }), this.pendingAuthTokenType = null;
335
+ }
336
+ emitAuthEvent(e) {
337
+ const t = Date.now(), n = {
338
+ id: `auth-${e.direction}-${e.messageType}-${t}-${Math.random().toString(36).slice(2, 8)}`,
339
+ timestamp: t,
340
+ type: "auth",
341
+ direction: e.direction,
342
+ messageType: e.messageType,
343
+ status: e.status,
344
+ tokenType: e.tokenType,
345
+ error: e.error,
346
+ details: e.details
347
+ };
348
+ this.eventStore.addEvent(n);
349
+ }
350
+ /**
351
+ * Extract and emit log events from logLines
352
+ */
353
+ emitLogEvents(e, t) {
354
+ const n = Date.now();
355
+ for (const s of e) {
356
+ const o = s.match(/^\[(log|info|warn|error)\]\s+(.+)$/i), i = o ? o[1].toLowerCase() : "log", a = o ? o[2] : s, u = {
357
+ id: `log-${n}-${Math.random()}`,
358
+ timestamp: n,
359
+ type: "log",
360
+ level: i,
361
+ message: a,
362
+ relatedEventId: t
363
+ };
364
+ this.eventStore.addEvent(u);
365
+ }
366
+ }
367
+ }
368
+ export {
369
+ w as DataInspector,
370
+ P as DevToolbar,
371
+ E as EventStore,
372
+ S as LogsPanel,
373
+ A as PerformancePanel,
374
+ L as SettingsPanel,
375
+ M as SubscriptionsPanel,
376
+ I as WebSocketInterceptor,
377
+ R as concaveDevTools,
378
+ D as getGlobalEventStore,
379
+ $ as initDevTools
380
+ };
@@ -0,0 +1,5 @@
1
+ /**
2
+ * WebSocket Interceptor exports
3
+ */
4
+ export { WebSocketInterceptor } from "./websocket-interceptor";
5
+ export { getGlobalEventStore } from "../store/event-store";
@@ -0,0 +1,67 @@
1
+ /**
2
+ * WebSocket Interceptor for Convex Sync Protocol
3
+ *
4
+ * Intercepts WebSocket messages to capture queries, mutations, actions, subscriptions,
5
+ * and authentication protocol events.
6
+ */
7
+ import type { EventStore } from "../store/event-store";
8
+ export declare class WebSocketInterceptor {
9
+ private eventStore;
10
+ private originalWebSocket;
11
+ private pendingQueries;
12
+ private pendingMutations;
13
+ private pendingActions;
14
+ private pendingAuthTokenType;
15
+ /** Tracks the most recent mutation event ID for causality linking */
16
+ private lastMutationEventId;
17
+ private lastMutationTimestamp;
18
+ constructor(eventStore: EventStore);
19
+ /**
20
+ * Install the WebSocket interceptor
21
+ */
22
+ install(): void;
23
+ /**
24
+ * Uninstall the interceptor
25
+ */
26
+ uninstall(): void;
27
+ /**
28
+ * Handle client → server messages
29
+ */
30
+ private handleClientMessage;
31
+ /**
32
+ * Handle server → client messages
33
+ */
34
+ private handleServerMessage;
35
+ /**
36
+ * Handle query set modifications (subscriptions)
37
+ */
38
+ private handleModifyQuerySet;
39
+ /**
40
+ * Handle mutation requests
41
+ */
42
+ private handleMutationRequest;
43
+ /**
44
+ * Handle action requests
45
+ */
46
+ private handleActionRequest;
47
+ private handleConnectMessage;
48
+ private handleAuthenticateMessage;
49
+ /**
50
+ * Handle state transitions (query updates)
51
+ */
52
+ private handleTransition;
53
+ /**
54
+ * Handle mutation responses
55
+ */
56
+ private handleMutationResponse;
57
+ /**
58
+ * Handle action responses
59
+ */
60
+ private handleActionResponse;
61
+ private handleAuthErrorResponse;
62
+ private emitAuthEvent;
63
+ /**
64
+ * Extract and emit log events from logLines
65
+ */
66
+ private emitLogEvents;
67
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Activity Panel - Unified view of queries, mutations, and actions
3
+ * with focused list-first debugging UX
4
+ */
5
+ import type { EventStore } from "../store/event-store";
6
+ interface ActivityPanelProps {
7
+ eventStore: EventStore;
8
+ }
9
+ export declare function ActivityPanel({ eventStore }: ActivityPanelProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,23 @@
1
+ /**
2
+ * ContextMenu - Native-style right-click context menu for DevTools panels
3
+ */
4
+ export interface MenuItem {
5
+ label: string;
6
+ action: () => void;
7
+ shortcut?: string;
8
+ disabled?: boolean;
9
+ separator?: boolean;
10
+ }
11
+ export interface ContextMenuProps {
12
+ x: number;
13
+ y: number;
14
+ items: MenuItem[];
15
+ onClose: () => void;
16
+ }
17
+ export declare function ContextMenu({ x, y, items, onClose }: ContextMenuProps): import("react/jsx-runtime").JSX.Element;
18
+ /** State type for panels using context menus */
19
+ export interface ContextMenuState {
20
+ x: number;
21
+ y: number;
22
+ items: MenuItem[];
23
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Data Inspector - Advanced JSON viewer with syntax highlighting, search, and diff
3
+ */
4
+ import type { JSONValue } from "../types";
5
+ interface DataInspectorProps {
6
+ data: JSONValue;
7
+ label?: string;
8
+ onCopy?: () => void;
9
+ maxHeight?: number;
10
+ }
11
+ export declare function DataInspector({ data, label, onCopy, maxHeight, }: DataInspectorProps): import("react/jsx-runtime").JSX.Element;
12
+ export {};
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Main DevTools Overlay Component
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface DevToolbarProps {
6
+ eventStore: EventStore;
7
+ position?: "bottom-right" | "bottom-left" | "top-right" | "top-left";
8
+ mode?: "overlay" | "panel";
9
+ }
10
+ export declare function DevToolbar({ eventStore, position, mode }: DevToolbarProps): import("react/jsx-runtime").JSX.Element;
11
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Logs Panel - Shows console logs from function executions
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface LogsPanelProps {
6
+ eventStore: EventStore;
7
+ onNavigate?: (tab: "activity" | "subscriptions" | "performance" | "logs" | "settings") => void;
8
+ }
9
+ export declare function LogsPanel({ eventStore, onNavigate }: LogsPanelProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Network Panel - Shows all client-server communication
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface NetworkPanelProps {
6
+ eventStore: EventStore;
7
+ }
8
+ export declare function NetworkPanel({ eventStore }: NetworkPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Performance Panel - Shows performance metrics with sparkline trends
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface PerformancePanelProps {
6
+ eventStore: EventStore;
7
+ onNavigate?: (tab: "activity" | "subscriptions" | "performance" | "logs" | "settings") => void;
8
+ }
9
+ export declare function PerformancePanel({ eventStore, onNavigate }: PerformancePanelProps): import("react/jsx-runtime").JSX.Element;
10
+ export {};
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface SearchFieldProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange"> {
3
+ value: string;
4
+ onValueChange: (value: string) => void;
5
+ onClear?: () => void;
6
+ className?: string;
7
+ }
8
+ export declare const SearchField: React.ForwardRefExoticComponent<SearchFieldProps & React.RefAttributes<HTMLInputElement>>;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Settings Panel - Configure devtools behavior
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface SettingsPanelProps {
6
+ eventStore: EventStore;
7
+ }
8
+ export declare function SettingsPanel({ eventStore }: SettingsPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Subscriptions Panel - Shows active query subscriptions
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface SubscriptionsPanelProps {
6
+ eventStore: EventStore;
7
+ }
8
+ export declare function SubscriptionsPanel({ eventStore }: SubscriptionsPanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Timeline Panel - Visual timeline of all events
3
+ */
4
+ import type { EventStore } from "../store/event-store";
5
+ interface TimelinePanelProps {
6
+ eventStore: EventStore;
7
+ }
8
+ export declare function TimelinePanel({ eventStore }: TimelinePanelProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Copy text to clipboard with fallback for restricted contexts (e.g. Chrome
3
+ * DevTools panels where the Clipboard API is blocked by permissions policy).
4
+ * Shows a brief "Copied!" toast on success.
5
+ */
6
+ export declare function copyToClipboard(text: string): void;
7
+ export declare function unwrapArgs<T>(args: T): T;
8
+ export type InlinePreviewOptions = {
9
+ maxStringLength?: number;
10
+ stringTailLength?: number;
11
+ maxArrayItems?: number;
12
+ maxObjectEntries?: number;
13
+ maxDepth?: number;
14
+ };
15
+ export declare function formatInlinePreview(value: any, options?: InlinePreviewOptions, depth?: number): string;
16
+ export declare function formatJsonSnippet(value: any, maxLength?: number): string;
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Standalone DevTools Entry Point
3
+ *
4
+ * Self-contained bundle that can be loaded via <script> on any page.
5
+ * Renders inside a Shadow DOM for complete CSS/DOM isolation from the host page.
6
+ *
7
+ * When the Chrome extension's page-agent is already intercepting WebSockets,
8
+ * this skips installing its own interceptor and instead consumes events from
9
+ * page-agent via postMessage. This enables overlay + panel coexistence.
10
+ */
11
+ export {};