@replohq/sandbox-runtime 1.24.2 → 1.24.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.
- package/_vendor/schemas/commentsOverlayRpc.d.ts +4 -0
- package/_vendor/schemas/commentsOverlayRpc.mjs +4 -0
- package/buildMetadata.js +3 -3
- package/comments-overlay/bridge.js +3 -0
- package/comments-overlay/capture.d.ts +4 -1
- package/comments-overlay/capture.js +7 -1
- package/comments-overlay/overlay.d.ts +2 -0
- package/comments-overlay/overlay.js +40 -16
- package/package.json +4 -4
|
@@ -168,6 +168,10 @@ export declare const hostToCommentsOverlayMethodConfig: {
|
|
|
168
168
|
}, z.core.$strict>;
|
|
169
169
|
outputSchema: z.ZodVoid;
|
|
170
170
|
};
|
|
171
|
+
clearThreadFocus: {
|
|
172
|
+
inputSchema: z.ZodUndefined;
|
|
173
|
+
outputSchema: z.ZodVoid;
|
|
174
|
+
};
|
|
171
175
|
clearDraft: {
|
|
172
176
|
inputSchema: z.ZodUndefined;
|
|
173
177
|
outputSchema: z.ZodVoid;
|
|
@@ -40,6 +40,10 @@ var hostToCommentsOverlayMethodConfig = {
|
|
|
40
40
|
inputSchema: z.strictObject({ threadId: z.string() }),
|
|
41
41
|
outputSchema: z.void()
|
|
42
42
|
},
|
|
43
|
+
clearThreadFocus: {
|
|
44
|
+
inputSchema: z.undefined(),
|
|
45
|
+
outputSchema: z.void()
|
|
46
|
+
},
|
|
43
47
|
clearDraft: {
|
|
44
48
|
inputSchema: z.undefined(),
|
|
45
49
|
outputSchema: z.void()
|
package/buildMetadata.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export const BUILD_METADATA = {
|
|
2
2
|
"packageName": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.4",
|
|
4
4
|
"branch": "HEAD",
|
|
5
|
-
"commit": "
|
|
6
|
-
"builtAt": "2026-11-
|
|
5
|
+
"commit": "49a643c73e7608adcefebcd5c5e27c3e6d0c05a9",
|
|
6
|
+
"builtAt": "2026-11-04T22:05:21.699Z"
|
|
7
7
|
};
|
|
@@ -32,7 +32,10 @@ export declare function getElementSource(element: Element): ElementSource | null
|
|
|
32
32
|
* none. Inside a shadow root it includes nested shadow roots' text.
|
|
33
33
|
*/
|
|
34
34
|
export declare function getTextPreview(element: Element): string;
|
|
35
|
-
/**
|
|
35
|
+
/**
|
|
36
|
+
* The element an anchor for this click target or selection describes; null
|
|
37
|
+
* when a click lands in layout spacing or a selection isn't in an element.
|
|
38
|
+
*/
|
|
36
39
|
export declare function getAnchorElement(target: Element | Range): Element | null;
|
|
37
40
|
/**
|
|
38
41
|
* Builds an element anchor (D-13) for a clicked element or a text selection.
|
|
@@ -168,8 +168,14 @@ function createRootAnchorSelectors(element) {
|
|
|
168
168
|
selector: ownSemanticSelector ?? findUniqueSelector(element) ?? createNthChildSelector(element)
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
|
+
const LAYOUT_SELECTOR = "[data-comment-layout]";
|
|
171
172
|
function getAnchorElement(target) {
|
|
172
|
-
|
|
173
|
+
if (isElement(target)) {
|
|
174
|
+
const element = snapToAnchorElement(target);
|
|
175
|
+
const isLayout = element.matches(LAYOUT_SELECTOR) || element.querySelector(LAYOUT_SELECTOR) !== null;
|
|
176
|
+
return isLayout ? null : element;
|
|
177
|
+
}
|
|
178
|
+
const picked = rangeContainer(target);
|
|
173
179
|
return picked ? snapToAnchorElement(picked) : null;
|
|
174
180
|
}
|
|
175
181
|
function captureAnchor(target, point) {
|
|
@@ -20,6 +20,7 @@ export type CommentsOverlayCallbacks = {
|
|
|
20
20
|
onComposeFromSelection: (input: {
|
|
21
21
|
anchor: CommentAnchorElement;
|
|
22
22
|
}) => void;
|
|
23
|
+
/** Esc, or a click on empty page, closed the pending pick or open thread. */
|
|
23
24
|
onPickCancelled: () => void;
|
|
24
25
|
/** C or Esc pressed in the frame; the host owns the mode. */
|
|
25
26
|
onModeShortcut: (input: {
|
|
@@ -36,6 +37,7 @@ export type CommentsOverlay = {
|
|
|
36
37
|
setMode: (mode: DisplayMode) => void;
|
|
37
38
|
setPins: (pins: CommentOverlayPin[]) => void;
|
|
38
39
|
focusThread: (threadId: string) => void;
|
|
40
|
+
clearThreadFocus: () => void;
|
|
39
41
|
clearDraft: () => void;
|
|
40
42
|
setDraftAnchor: (anchor: CommentAnchor | null) => void;
|
|
41
43
|
/** Re-resolves every anchor now, e.g. after symbolication results arrive. */
|
|
@@ -12,6 +12,7 @@ const COMPACT_GUTTER_MAX_WIDTH_PX = 600;
|
|
|
12
12
|
const RERESOLVE_DEBOUNCE_MS = 250;
|
|
13
13
|
const SELECTION_PROMPT_DEBOUNCE_MS = 150;
|
|
14
14
|
const TEXT_PICK_CLICK_SUPPRESS_MS = 750;
|
|
15
|
+
const PENDING_SCROLL_MS = 1e4;
|
|
15
16
|
const HOVER_OUTLINE_STYLE = `position:absolute;pointer-events:none;box-sizing:border-box;border:${HIGHLIGHT_OUTLINE};background:transparent;border-radius:4px`;
|
|
16
17
|
const SVG_NAMESPACE = "http://www.w3.org/2000/svg";
|
|
17
18
|
const EDITABLE_SELECTOR = "input, textarea, select, [contenteditable]:not([contenteditable='false'])";
|
|
@@ -34,6 +35,7 @@ function createCommentsOverlay(options) {
|
|
|
34
35
|
const boundElements = /* @__PURE__ */ new Map();
|
|
35
36
|
let selection = null;
|
|
36
37
|
let hoveredBadgeThreadId = null;
|
|
38
|
+
let pendingScroll = null;
|
|
37
39
|
let statusesKey = "";
|
|
38
40
|
let hoveredElement = null;
|
|
39
41
|
let hoverOutline = null;
|
|
@@ -105,6 +107,19 @@ function createCommentsOverlay(options) {
|
|
|
105
107
|
return pin.anchor.type === "element" ? [{ pin, anchor: pin.anchor }] : [];
|
|
106
108
|
});
|
|
107
109
|
};
|
|
110
|
+
const scrollToThread = (threadId) => {
|
|
111
|
+
const resolution = resolutions.get(threadId);
|
|
112
|
+
if (!resolution || !isResolutionVisible(resolution)) {
|
|
113
|
+
return false;
|
|
114
|
+
}
|
|
115
|
+
const target = resolution.range?.startContainer.parentElement ?? resolution.element;
|
|
116
|
+
const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
|
|
117
|
+
target?.scrollIntoView?.({
|
|
118
|
+
block: "center",
|
|
119
|
+
behavior: reduceMotion ? "auto" : "smooth"
|
|
120
|
+
});
|
|
121
|
+
return true;
|
|
122
|
+
};
|
|
108
123
|
const resolveAll = () => {
|
|
109
124
|
resolveTimer = null;
|
|
110
125
|
observeShadowRoots(document);
|
|
@@ -130,6 +145,12 @@ function createCommentsOverlay(options) {
|
|
|
130
145
|
}
|
|
131
146
|
}
|
|
132
147
|
resolutions = next;
|
|
148
|
+
if (pendingScroll) {
|
|
149
|
+
const isStale = selection?.kind !== "thread" || selection.threadId !== pendingScroll.threadId || Date.now() > pendingScroll.until;
|
|
150
|
+
if (isStale || scrollToThread(pendingScroll.threadId)) {
|
|
151
|
+
pendingScroll = null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
133
154
|
if (selection?.kind === "draft") {
|
|
134
155
|
selection.resolution = resolveAnchor(selection.anchor, document, {
|
|
135
156
|
previous: selection.resolution?.element ?? null,
|
|
@@ -427,6 +448,15 @@ function createCommentsOverlay(options) {
|
|
|
427
448
|
selection = null;
|
|
428
449
|
}
|
|
429
450
|
};
|
|
451
|
+
const dismissSelection = () => {
|
|
452
|
+
if (!selection) {
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
selection = null;
|
|
456
|
+
options.onPickCancelled();
|
|
457
|
+
schedulePaint();
|
|
458
|
+
return true;
|
|
459
|
+
};
|
|
430
460
|
const refreshSelectionPrompt = () => {
|
|
431
461
|
selectionTimer = null;
|
|
432
462
|
const range = mode !== "comment" && !pointerIsDown ? getUsableSelectionRange() : null;
|
|
@@ -580,8 +610,8 @@ function createCommentsOverlay(options) {
|
|
|
580
610
|
if (window.getSelection()?.toString().trim()) {
|
|
581
611
|
return;
|
|
582
612
|
}
|
|
583
|
-
if (!isPageElement(target)) {
|
|
584
|
-
|
|
613
|
+
if (!isPageElement(target) || !getAnchorElement(target)) {
|
|
614
|
+
dismissSelection();
|
|
585
615
|
return;
|
|
586
616
|
}
|
|
587
617
|
pick(target, { x: event.clientX, y: event.clientY }, reportPicked);
|
|
@@ -602,11 +632,7 @@ function createCommentsOverlay(options) {
|
|
|
602
632
|
event.preventDefault();
|
|
603
633
|
event.stopImmediatePropagation();
|
|
604
634
|
}
|
|
605
|
-
if (
|
|
606
|
-
clearDraft();
|
|
607
|
-
options.onPickCancelled();
|
|
608
|
-
schedulePaint();
|
|
609
|
-
} else {
|
|
635
|
+
if (!dismissSelection()) {
|
|
610
636
|
options.onModeShortcut({ mode: "browse" });
|
|
611
637
|
}
|
|
612
638
|
return;
|
|
@@ -736,17 +762,15 @@ function createCommentsOverlay(options) {
|
|
|
736
762
|
},
|
|
737
763
|
focusThread: (threadId) => {
|
|
738
764
|
selection = { kind: "thread", threadId };
|
|
739
|
-
|
|
740
|
-
const target = resolution?.range?.startContainer.parentElement ?? resolution?.element ?? null;
|
|
741
|
-
if (resolution && isResolutionVisible(resolution)) {
|
|
742
|
-
const reduceMotion = window.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches ?? false;
|
|
743
|
-
target?.scrollIntoView?.({
|
|
744
|
-
block: "center",
|
|
745
|
-
behavior: reduceMotion ? "auto" : "smooth"
|
|
746
|
-
});
|
|
747
|
-
}
|
|
765
|
+
pendingScroll = scrollToThread(threadId) ? null : { threadId, until: Date.now() + PENDING_SCROLL_MS };
|
|
748
766
|
schedulePaint();
|
|
749
767
|
},
|
|
768
|
+
clearThreadFocus: () => {
|
|
769
|
+
if (selection?.kind === "thread") {
|
|
770
|
+
selection = null;
|
|
771
|
+
schedulePaint();
|
|
772
|
+
}
|
|
773
|
+
},
|
|
750
774
|
clearDraft: () => {
|
|
751
775
|
clearDraft();
|
|
752
776
|
schedulePaint();
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@replohq/sandbox-runtime",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.4",
|
|
4
4
|
"reploBuild": {
|
|
5
5
|
"packageName": "@replohq/sandbox-runtime",
|
|
6
|
-
"version": "1.24.
|
|
6
|
+
"version": "1.24.4",
|
|
7
7
|
"branch": "HEAD",
|
|
8
|
-
"commit": "
|
|
9
|
-
"builtAt": "2026-11-
|
|
8
|
+
"commit": "49a643c73e7608adcefebcd5c5e27c3e6d0c05a9",
|
|
9
|
+
"builtAt": "2026-11-04T22:05:21.699Z"
|
|
10
10
|
},
|
|
11
11
|
"description": "Replo sandbox runtime — editor integration for agent-built Next.js sites.",
|
|
12
12
|
"license": "SEE LICENSE IN LICENSE",
|