@abbox/inspector 0.4.8 → 0.4.10

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.
@@ -1 +1 @@
1
- {"version":3,"file":"client-bridge.d.ts","sourceRoot":"","sources":["../../src/host/client-bridge.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAyEjB"}
1
+ {"version":3,"file":"client-bridge.d.ts","sourceRoot":"","sources":["../../src/host/client-bridge.ts"],"names":[],"mappings":"AAmBA,MAAM,MAAM,sBAAsB,GAAG;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,6EAA6E;IAC7E,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;CAClB,CAAC;AAEF,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,sBAAsB,GAC9B,eAAe,CAqHjB"}
@@ -2,15 +2,51 @@ import { ABBBOX_INSPECTOR_CHANNEL, PROTOCOL_VERSION, } from "../protocol.js";
2
2
  import { createInspectorRuntime } from "../runtime/inspector.js";
3
3
  import { withLocalhostAliases } from "./origin-aliases.js";
4
4
  import { validateIncomingMessage } from "./validate.js";
5
+ // Only available in browser context
6
+ let addDebugLog = () => { };
7
+ if (typeof window !== "undefined") {
8
+ import("../runtime/overlay.js").then((m) => {
9
+ addDebugLog = m.addDebugLog;
10
+ });
11
+ }
5
12
  export function createInspectorClient(options) {
6
13
  const win = options.window ?? globalThis.window;
7
14
  const doc = options.document ?? win.document;
8
15
  const allowedOrigins = withLocalhostAliases(options.allowedHostOrigins);
16
+ addDebugLog(`Client init: sessionId=${options.sessionId}`);
17
+ addDebugLog(`Allowed origins: ${allowedOrigins.join(", ")}`);
18
+ addDebugLog(`Window href: ${win.location.href}`);
19
+ addDebugLog(`Parent href: ${win.parent?.location?.href ?? "N/A"}`);
9
20
  const send = (message) => {
10
- if (!win.parent || win.parent === win)
21
+ if (!win.parent || win.parent === win) {
22
+ addDebugLog(`send() skipped: parent=${!!win.parent}`);
11
23
  return;
24
+ }
25
+ let sent = false;
26
+ // Try each allowed origin
12
27
  for (const targetOrigin of allowedOrigins) {
13
- win.parent.postMessage(message, targetOrigin);
28
+ try {
29
+ addDebugLog(`→ ${message.type} on ${targetOrigin}`);
30
+ win.parent.postMessage(message, targetOrigin);
31
+ sent = true;
32
+ addDebugLog(`✓ ${message.type} sent`);
33
+ break;
34
+ }
35
+ catch (err) {
36
+ addDebugLog(`✗ ${targetOrigin}: ${String(err).slice(0, 40)}`);
37
+ }
38
+ }
39
+ // If all allowed origins failed, try wildcard
40
+ if (!sent) {
41
+ try {
42
+ addDebugLog(`→ ${message.type} on wildcard`);
43
+ win.parent.postMessage(message, "*");
44
+ sent = true;
45
+ addDebugLog(`✓ ${message.type} sent via *`);
46
+ }
47
+ catch (err) {
48
+ addDebugLog(`✗ Wildcard: ${String(err).slice(0, 40)}`);
49
+ }
14
50
  }
15
51
  };
16
52
  const base = () => ({
@@ -47,15 +83,25 @@ export function createInspectorClient(options) {
47
83
  sessionId: options.sessionId,
48
84
  allowedOrigins,
49
85
  });
50
- if (!msg)
86
+ if (!msg) {
87
+ addDebugLog(`Message rejected from ${event.origin}`);
51
88
  return;
52
- if (msg.type === "INSPECTOR_HOST_HELLO")
89
+ }
90
+ addDebugLog(`← Received: ${msg.type}`);
91
+ if (msg.type === "INSPECTOR_HOST_HELLO") {
92
+ addDebugLog(` Sending INSPECTOR_READY`);
53
93
  sendReady();
54
- if (msg.type === "INSPECTOR_ENABLE")
94
+ }
95
+ if (msg.type === "INSPECTOR_ENABLE") {
96
+ addDebugLog(` Enabling inspector runtime`);
55
97
  runtime.enable();
56
- if (msg.type === "INSPECTOR_DISABLE")
98
+ }
99
+ if (msg.type === "INSPECTOR_DISABLE") {
100
+ addDebugLog(` Disabling inspector runtime`);
57
101
  runtime.disable();
102
+ }
58
103
  if (msg.type === "APPLY_CHANGE_MARKERS") {
104
+ addDebugLog(` Applying ${msg.markers.length} change markers`);
59
105
  runtime.setChangeMarkers(msg.markers);
60
106
  }
61
107
  };
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/host/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,gBAAgB,GAAG,IAAI,CAKzB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,IAAI,CAEN"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/host/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,gBAAgB,EAAsB,MAAM,gBAAgB,CAAC;AAE3E,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC,CAAC;AAEF,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,OAAO,EACb,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,GACvB,gBAAgB,GAAG,IAAI,CAKzB;AAED,wBAAgB,YAAY,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,gBAAgB,EACzB,YAAY,EAAE,MAAM,GACnB,IAAI,CAoBN"}
@@ -9,5 +9,25 @@ export function validateIncomingMessage(data, origin, options) {
9
9
  return data;
10
10
  }
11
11
  export function postToTarget(target, message, targetOrigin) {
12
- target.postMessage(message, targetOrigin);
12
+ try {
13
+ target.postMessage(message, targetOrigin);
14
+ }
15
+ catch (err) {
16
+ // If postMessage fails (e.g., origin mismatch with localhost vs 127.0.0.1),
17
+ // try common alternative origins
18
+ const fallbackOrigins = [
19
+ targetOrigin.replace("://localhost", "://127.0.0.1"),
20
+ targetOrigin.replace("://127.0.0.1", "://localhost"),
21
+ "*",
22
+ ];
23
+ for (const origin of fallbackOrigins) {
24
+ try {
25
+ target.postMessage(message, origin);
26
+ return;
27
+ }
28
+ catch {
29
+ // Continue to next fallback
30
+ }
31
+ }
32
+ }
13
33
  }
@@ -1,3 +1,12 @@
1
- /** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`. */
2
- export declare function AbboxInspectorBoot(): null;
1
+ export type AbboxInspectorBootProps = {
2
+ /** Search params from Next.js useSearchParams (for RSC environments).
3
+ * Required in Next.js 13+ RSC where window.location.search may be empty.
4
+ * Pass Object.fromEntries(useSearchParams()) from your layout.
5
+ */
6
+ searchParams?: Record<string, string | string[]>;
7
+ };
8
+ /** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`.
9
+ * In Next.js 13+ RSC, pass searchParams prop from useSearchParams() in your layout.
10
+ */
11
+ export declare function AbboxInspectorBoot(props?: AbboxInspectorBootProps): null;
3
12
  //# sourceMappingURL=AbboxInspectorBoot.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"AbboxInspectorBoot.d.ts","sourceRoot":"","sources":["../../src/react/AbboxInspectorBoot.tsx"],"names":[],"mappings":"AAKA,yFAAyF;AACzF,wBAAgB,kBAAkB,SAKjC"}
1
+ {"version":3,"file":"AbboxInspectorBoot.d.ts","sourceRoot":"","sources":["../../src/react/AbboxInspectorBoot.tsx"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAAG;IACpC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;CAClD,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,CAAC,EAAE,uBAAuB,QAiBjE"}
@@ -1,10 +1,20 @@
1
1
  "use client";
2
2
  import { useEffect } from "react";
3
3
  import { bootstrapInspectorPreview } from "../runtime/bootstrap.js";
4
- /** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`. */
5
- export function AbboxInspectorBoot() {
4
+ /** Mount once in the root layout so the Viewer iframe can connect via `abboxSession`.
5
+ * In Next.js 13+ RSC, pass searchParams prop from useSearchParams() in your layout.
6
+ */
7
+ export function AbboxInspectorBoot(props) {
6
8
  useEffect(() => {
7
- bootstrapInspectorPreview();
8
- }, []);
9
+ // Convert searchParams to URLSearchParams if provided
10
+ let searchParams;
11
+ if (props?.searchParams) {
12
+ searchParams = new URLSearchParams(Object.entries(props.searchParams).map(([k, v]) => [
13
+ k,
14
+ Array.isArray(v) ? v[0] : v,
15
+ ]));
16
+ }
17
+ bootstrapInspectorPreview({ searchParams });
18
+ }, [props?.searchParams]);
9
19
  return null;
10
20
  }
@@ -1,6 +1,7 @@
1
1
  export type BootstrapOptions = {
2
2
  sessionId?: string;
3
3
  allowedHostOrigins?: string[];
4
+ searchParams?: URLSearchParams | Record<string, string>;
4
5
  };
5
6
  /**
6
7
  * Entry for instrumented apps. Activates when the build baked an authorized
@@ -1 +1 @@
1
- {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B,CAAC;AA8CF;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAyCN;AAED,4CAA4C;AAC5C,wBAAgB,+BAA+B,IAAI,IAAI,CAMtD"}
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/runtime/bootstrap.ts"],"names":[],"mappings":"AAuCA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,YAAY,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACzD,CAAC;AA8CF;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,gBAAqB,GAC7B,IAAI,CAiDN;AAED,4CAA4C;AAC5C,wBAAgB,+BAA+B,IAAI,IAAI,CAMtD"}
@@ -72,7 +72,16 @@ export function bootstrapInspectorPreview(options = {}) {
72
72
  if (!isAbboxInspectorRuntimeEnabled())
73
73
  return;
74
74
  const win = window;
75
- const params = new URLSearchParams(win.location.search);
75
+ // In Next.js 13+ RSC, window.location.search may be empty. Fallback to passed searchParams.
76
+ let params;
77
+ if (options.searchParams) {
78
+ params = options.searchParams instanceof URLSearchParams
79
+ ? options.searchParams
80
+ : new URLSearchParams(options.searchParams);
81
+ }
82
+ else {
83
+ params = new URLSearchParams(win.location.search);
84
+ }
76
85
  const sessionFromUrl = params.get("abboxSession");
77
86
  const hostParam = params.get("abboxHostOrigin");
78
87
  if (!sessionFromUrl) {
@@ -1 +1 @@
1
- {"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../src/runtime/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAgBxE,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA8NlB"}
1
+ {"version":3,"file":"inspector.d.ts","sourceRoot":"","sources":["../../src/runtime/inspector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAkBxE,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,mBAAmB,KAAK,IAAI,CAAC;IAClD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,sBAAsB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACrD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB,gBAAgB,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IACpD,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,CAAC;IACrD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,uBAAuB,GAC/B,gBAAgB,CA0OlB"}
@@ -1,11 +1,12 @@
1
1
  import { runtimeElementRefFor } from "./element-ref.js";
2
2
  import { extractMetadata, findSourceLocation, sourceKeyFor, sourceMappingStatus, } from "./metadata.js";
3
- import { createOverlay, hideHighlight, positionHighlight, rectForElement, renderChangeMarkers, } from "./overlay.js";
3
+ import { createOverlay, hideHighlight, hideSelectedHighlight, positionHighlight, positionSelectedHighlight, rectForElement, renderChangeMarkers, } from "./overlay.js";
4
4
  export function createInspectorRuntime(options) {
5
5
  const { document: doc, window: win } = options;
6
6
  const overlay = createOverlay(doc);
7
7
  let enabled = false;
8
8
  let hovered = null;
9
+ let selected = null;
9
10
  const refIdToElement = new Map();
10
11
  let markers = [];
11
12
  let focusedMarkerId = null;
@@ -49,8 +50,12 @@ export function createInspectorRuntime(options) {
49
50
  select(target);
50
51
  };
51
52
  const onScrollOrResize = () => {
52
- if (hovered)
53
+ if (selected) {
54
+ positionSelectedHighlight(overlay.selectedHighlight, rectForElement(selected));
55
+ }
56
+ if (hovered) {
53
57
  positionHighlight(overlay.highlight, rectForElement(hovered));
58
+ }
54
59
  if (markers.length) {
55
60
  renderChangeMarkers(overlay.markerLayer, markers, (id) => refIdToElement.get(id) ?? null, options.onChangeMarkerSelected);
56
61
  }
@@ -76,7 +81,10 @@ export function createInspectorRuntime(options) {
76
81
  options.onHover?.(payloadFor(el));
77
82
  }
78
83
  function select(el) {
84
+ console.log("[inspector] element selected", el.tagName);
85
+ selected = el;
79
86
  hovered = el;
87
+ positionSelectedHighlight(overlay.selectedHighlight, rectForElement(el));
80
88
  positionHighlight(overlay.highlight, rectForElement(el));
81
89
  options.onSelect?.(payloadFor(el));
82
90
  }
@@ -125,7 +133,9 @@ export function createInspectorRuntime(options) {
125
133
  }
126
134
  function clearSelection() {
127
135
  hovered = null;
136
+ selected = null;
128
137
  hideHighlight(overlay.highlight);
138
+ hideSelectedHighlight(overlay.selectedHighlight);
129
139
  options.onClear?.();
130
140
  }
131
141
  win.addEventListener("scroll", onScrollOrResize, true);
@@ -145,6 +155,7 @@ export function createInspectorRuntime(options) {
145
155
  teardownListeners();
146
156
  hovered = null;
147
157
  hideHighlight(overlay.highlight);
158
+ hideSelectedHighlight(overlay.selectedHighlight);
148
159
  clearSelection();
149
160
  },
150
161
  isEnabled: () => enabled,
@@ -1,12 +1,16 @@
1
1
  import type { ChangeMarker, ElementRect } from "../protocol.js";
2
+ export declare function addDebugLog(message: string): void;
2
3
  export type OverlayHandles = {
3
4
  highlight: HTMLDivElement;
5
+ selectedHighlight: HTMLDivElement;
4
6
  markerLayer: HTMLDivElement;
5
7
  destroy: () => void;
6
8
  };
7
9
  export declare function createOverlay(root: Document): OverlayHandles;
8
10
  export declare function positionHighlight(highlight: HTMLDivElement, rect: ElementRect): void;
11
+ export declare function positionSelectedHighlight(selectedHighlight: HTMLDivElement, rect: ElementRect): void;
9
12
  export declare function hideHighlight(highlight: HTMLDivElement): void;
13
+ export declare function hideSelectedHighlight(selectedHighlight: HTMLDivElement): void;
10
14
  export declare function rectForElement(el: Element): ElementRect;
11
15
  export declare function renderChangeMarkers(layer: HTMLDivElement, markers: ChangeMarker[], resolveElement: (refId: string) => Element | null, onSelect?: (changeId: string) => void): void;
12
16
  //# sourceMappingURL=overlay.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAKhE,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAiC5D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAQvD;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,EACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,CA+DN"}
1
+ {"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../src/runtime/overlay.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAUhE,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,QAM1C;AAiCD,MAAM,MAAM,cAAc,GAAG;IAC3B,SAAS,EAAE,cAAc,CAAC;IAC1B,iBAAiB,EAAE,cAAc,CAAC;IAClC,WAAW,EAAE,cAAc,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,cAAc,CAiD5D;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,cAAc,EACzB,IAAI,EAAE,WAAW,GAChB,IAAI,CAQN;AAED,wBAAgB,yBAAyB,CACvC,iBAAiB,EAAE,cAAc,EACjC,IAAI,EAAE,WAAW,GAChB,IAAI,CASN;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,cAAc,GAAG,IAAI,CAE7D;AAED,wBAAgB,qBAAqB,CAAC,iBAAiB,EAAE,cAAc,GAAG,IAAI,CAE7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,OAAO,GAAG,WAAW,CAQvD;AAOD,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,cAAc,EACrB,OAAO,EAAE,YAAY,EAAE,EACvB,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,GAAG,IAAI,EACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,GACpC,IAAI,CA+DN"}
@@ -1,12 +1,68 @@
1
1
  const HIGHLIGHT_Z = 2147483646;
2
+ const SELECTED_HIGHLIGHT_Z = 2147483643;
2
3
  const MARKER_Z = 2147483645;
4
+ // Debug panel for on-screen logging
5
+ let debugPanel = null;
6
+ let debugLogs = [];
7
+ export function addDebugLog(message) {
8
+ const timestamp = new Date().toLocaleTimeString();
9
+ const log = `[${timestamp}] ${message}`;
10
+ debugLogs.push(log);
11
+ if (debugLogs.length > 20)
12
+ debugLogs.shift(); // Keep last 20 logs
13
+ updateDebugPanel();
14
+ }
15
+ function updateDebugPanel() {
16
+ if (!debugPanel)
17
+ createDebugPanel();
18
+ if (debugPanel) {
19
+ debugPanel.textContent = debugLogs.join("\n");
20
+ }
21
+ }
22
+ function createDebugPanel() {
23
+ if (debugPanel)
24
+ return;
25
+ debugPanel = document.createElement("div");
26
+ debugPanel.setAttribute("data-abbox-debug-panel", "true");
27
+ Object.assign(debugPanel.style, {
28
+ position: "fixed",
29
+ bottom: "10px",
30
+ right: "10px",
31
+ background: "rgba(0, 0, 0, 0.9)",
32
+ color: "#0f0",
33
+ padding: "10px",
34
+ borderRadius: "4px",
35
+ fontFamily: "monospace",
36
+ fontSize: "11px",
37
+ maxWidth: "400px",
38
+ maxHeight: "300px",
39
+ overflowY: "auto",
40
+ zIndex: "2147483647",
41
+ whiteSpace: "pre-wrap",
42
+ wordBreak: "break-word",
43
+ });
44
+ document.body.appendChild(debugPanel);
45
+ }
3
46
  export function createOverlay(root) {
47
+ addDebugLog("Creating overlay elements");
48
+ const selectedHighlight = root.createElement("div");
49
+ selectedHighlight.setAttribute("data-abbox-inspector", "selected-highlight");
50
+ Object.assign(selectedHighlight.style, {
51
+ position: "fixed",
52
+ pointerEvents: "none",
53
+ border: "40px dashed #2563eb",
54
+ background: "rgba(37, 99, 235, 0.06)",
55
+ borderRadius: "2px",
56
+ zIndex: String(SELECTED_HIGHLIGHT_Z),
57
+ display: "none",
58
+ boxSizing: "border-box",
59
+ });
4
60
  const highlight = root.createElement("div");
5
61
  highlight.setAttribute("data-abbox-inspector", "highlight");
6
62
  Object.assign(highlight.style, {
7
63
  position: "fixed",
8
64
  pointerEvents: "none",
9
- border: "2px solid #2563eb",
65
+ border: "20px solid #2563eb",
10
66
  background: "rgba(37, 99, 235, 0.12)",
11
67
  borderRadius: "2px",
12
68
  zIndex: String(HIGHLIGHT_Z),
@@ -21,11 +77,13 @@ export function createOverlay(root) {
21
77
  pointerEvents: "none",
22
78
  zIndex: String(MARKER_Z),
23
79
  });
24
- root.body.append(highlight, markerLayer);
80
+ root.body.append(selectedHighlight, highlight, markerLayer);
25
81
  return {
26
82
  highlight,
83
+ selectedHighlight,
27
84
  markerLayer,
28
85
  destroy: () => {
86
+ selectedHighlight.remove();
29
87
  highlight.remove();
30
88
  markerLayer.remove();
31
89
  },
@@ -40,9 +98,22 @@ export function positionHighlight(highlight, rect) {
40
98
  height: `${rect.height}px`,
41
99
  });
42
100
  }
101
+ export function positionSelectedHighlight(selectedHighlight, rect) {
102
+ addDebugLog(`Selected: ${rect.width}×${rect.height} at ${Math.round(rect.x)},${Math.round(rect.y)}`);
103
+ Object.assign(selectedHighlight.style, {
104
+ display: "block",
105
+ left: `${rect.x}px`,
106
+ top: `${rect.y}px`,
107
+ width: `${rect.width}px`,
108
+ height: `${rect.height}px`,
109
+ });
110
+ }
43
111
  export function hideHighlight(highlight) {
44
112
  highlight.style.display = "none";
45
113
  }
114
+ export function hideSelectedHighlight(selectedHighlight) {
115
+ selectedHighlight.style.display = "none";
116
+ }
46
117
  export function rectForElement(el) {
47
118
  const r = el.getBoundingClientRect();
48
119
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abbox/inspector",
3
- "version": "0.4.8",
3
+ "version": "0.4.10",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -82,12 +82,13 @@
82
82
  }
83
83
  },
84
84
  "devDependencies": {
85
- "@types/react": "^19.3.0",
86
- "react": "^19.3.0",
87
85
  "@biomejs/biome": "2.5.15",
88
86
  "@types/babel__core": "^7.20.5",
89
87
  "@types/node": "^22.20.5",
88
+ "@types/react": "^19.3.0",
90
89
  "happy-dom": "^20.0.10",
90
+ "next": "^16.4.3",
91
+ "react": "^19.3.0",
91
92
  "typescript": "^5.7.3",
92
93
  "vitest": "^5.0.4"
93
94
  }