@replohq/sandbox-runtime 1.10.1 → 1.10.3

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.
Files changed (33) hide show
  1. package/_vendor/replo-utils/lib/fonts.d.ts +12 -1
  2. package/_vendor/replo-utils/lib/fonts.mjs +41 -3
  3. package/_vendor/replo-utils/lib/miniappPreview.d.ts +13 -0
  4. package/_vendor/replo-utils/lib/miniappPreview.mjs +48 -0
  5. package/_vendor/replo-utils/lib/misc.d.ts +4 -0
  6. package/_vendor/replo-utils/lib/misc.mjs +1 -1
  7. package/_vendor/schemas/componentPreview.d.ts +0 -55
  8. package/_vendor/schemas/componentPreview.mjs +1 -45
  9. package/_vendor/schemas/designLibrary.d.ts +23 -0
  10. package/_vendor/schemas/designLibrary.mjs +8 -1
  11. package/_vendor/schemas/generated/componentPreview.d.ts +0 -34
  12. package/_vendor/schemas/generated/selectMode.d.ts +8 -0
  13. package/_vendor/schemas/iframeRpcChannel.mjs +1 -1
  14. package/_vendor/schemas/selectMode.d.ts +25 -1
  15. package/_vendor/schemas/selectMode.mjs +2 -2
  16. package/_vendor/schemas/selectModeIframeRpc.d.ts +45 -5
  17. package/_vendor/schemas/selectModeIframeRpc.mjs +2 -2
  18. package/annotations/bridgeGate.d.ts +0 -5
  19. package/annotations/bridgeGate.js +2 -1
  20. package/buildMetadata.js +3 -3
  21. package/capturePage.d.ts +6 -0
  22. package/capturePage.js +118 -6
  23. package/{chunk-NBVMONRN.mjs → chunk-KFJZ2OLV.mjs} +10 -2
  24. package/{chunk-JUKCUPQ6.mjs → chunk-PH3S6LJI.mjs} +21 -1
  25. package/package.json +4 -4
  26. package/select-mode/descriptor/elementDescriptor.js +10 -2
  27. package/select-mode/descriptor/styleExtraction.d.ts +4 -0
  28. package/select-mode/descriptor/styleExtraction.js +134 -19
  29. package/select-mode/hooks/useOptimisticOverrides.js +7 -0
  30. package/select-mode/hooks/useSelectionInteractions.js +7 -5
  31. package/select-mode/iframeRpcChannel.d.ts +16 -1
  32. package/select-mode/selectModeStore.d.ts +1 -0
  33. package/select-mode/selectModeStore.js +8 -2
@@ -10,7 +10,15 @@ const CONTROL_STYLE_PROPERTIES = [
10
10
  "font-weight",
11
11
  "line-height",
12
12
  "letter-spacing",
13
- "text-align"
13
+ "text-align",
14
+ "padding-top",
15
+ "padding-right",
16
+ "padding-bottom",
17
+ "padding-left",
18
+ "margin-top",
19
+ "margin-right",
20
+ "margin-bottom",
21
+ "margin-left"
14
22
  ];
15
23
  const CONTROL_STYLE_PROPERTY_SET = new Set(CONTROL_STYLE_PROPERTIES);
16
24
  function isControlStyleProperty(propertyName) {
@@ -88,6 +96,57 @@ function getDefinedStyleKey({
88
96
  }) {
89
97
  return `${property}:${getStyleVariantKey(variant)}`;
90
98
  }
99
+ function getVariantApplicability(variant) {
100
+ if (!variant) {
101
+ return "applies";
102
+ }
103
+ if (variant.pseudo) {
104
+ return "skipped";
105
+ }
106
+ let applicability = "applies";
107
+ for (const atRule of variant.atRules) {
108
+ if (atRule.type === "@media") {
109
+ if (!window.matchMedia(atRule.text).matches) {
110
+ return "skipped";
111
+ }
112
+ } else if (atRule.type === "@supports") {
113
+ if (!CSS.supports(atRule.text)) {
114
+ return "skipped";
115
+ }
116
+ } else {
117
+ applicability = "unknown";
118
+ }
119
+ }
120
+ return applicability;
121
+ }
122
+ function setAuthoredDeclaration({
123
+ collector,
124
+ property,
125
+ declaration
126
+ }) {
127
+ const current = collector.authoredByProperty.get(property);
128
+ if (current?.isImportant && !declaration.isImportant) {
129
+ return;
130
+ }
131
+ collector.authoredByProperty.set(property, declaration);
132
+ }
133
+ const CUSTOM_PROPERTY_PATTERN = /^var\(\s*(--[\w-]+)\s*(?:,\s*(.+))?\)$/u;
134
+ const MAX_CUSTOM_PROPERTY_DEPTH = 5;
135
+ function expandCustomProperties({
136
+ element,
137
+ value
138
+ }) {
139
+ const computedStyle = window.getComputedStyle(element);
140
+ let expanded = value;
141
+ for (let depth = 0; depth < MAX_CUSTOM_PROPERTY_DEPTH; depth += 1) {
142
+ const match = expanded.match(CUSTOM_PROPERTY_PATTERN);
143
+ if (!match?.[1]) {
144
+ return expanded;
145
+ }
146
+ expanded = computedStyle.getPropertyValue(match[1]).trim() || match[2]?.trim() || "";
147
+ }
148
+ return expanded;
149
+ }
91
150
  function getResolvedClassStyleValue({
92
151
  className,
93
152
  property,
@@ -105,7 +164,7 @@ function getResolvedClassStyleValue({
105
164
  return resolved.trim() || raw;
106
165
  }
107
166
  function setDefinedStyle({
108
- definedStylesByKey,
167
+ collector: { definedStylesByKey },
109
168
  property,
110
169
  variant,
111
170
  className,
@@ -124,7 +183,7 @@ function addRuleDefinedStyles({
124
183
  rule,
125
184
  activeAtRules,
126
185
  classNames,
127
- definedStylesByKey
186
+ collector
128
187
  }) {
129
188
  const selectorMatches = getClassSelectorMatches({
130
189
  selectorText: rule.selectorText ?? "",
@@ -138,6 +197,7 @@ function addRuleDefinedStyles({
138
197
  atRules: activeAtRules,
139
198
  pseudo: selectorMatch.pseudo
140
199
  });
200
+ const applicability = getVariantApplicability(variant);
141
201
  for (let styleIndex = 0; styleIndex < rule.style.length; styleIndex += 1) {
142
202
  const property = rule.style.item(styleIndex);
143
203
  if (!property || !isControlStyleProperty(property)) {
@@ -148,7 +208,7 @@ function addRuleDefinedStyles({
148
208
  continue;
149
209
  }
150
210
  setDefinedStyle({
151
- definedStylesByKey,
211
+ collector,
152
212
  property,
153
213
  variant,
154
214
  className: selectorMatch.className,
@@ -160,6 +220,16 @@ function addRuleDefinedStyles({
160
220
  variant
161
221
  })
162
222
  });
223
+ if (applicability !== "skipped") {
224
+ setAuthoredDeclaration({
225
+ collector,
226
+ property,
227
+ declaration: {
228
+ value: applicability === "applies" ? raw : null,
229
+ isImportant: rule.style.getPropertyPriority(property) === "important"
230
+ }
231
+ });
232
+ }
163
233
  }
164
234
  }
165
235
  }
@@ -167,7 +237,7 @@ function addStyleRulesRecursively({
167
237
  ruleList,
168
238
  activeAtRules,
169
239
  classNames,
170
- definedStylesByKey
240
+ collector
171
241
  }) {
172
242
  for (const rule of Array.from(ruleList)) {
173
243
  const nestedRuleList = getNestedRuleList(rule);
@@ -176,7 +246,7 @@ function addStyleRulesRecursively({
176
246
  ruleList: nestedRuleList,
177
247
  activeAtRules: getNestedAtRules({ rule, activeAtRules }),
178
248
  classNames,
179
- definedStylesByKey
249
+ collector
180
250
  });
181
251
  }
182
252
  if (rule instanceof CSSStyleRule) {
@@ -184,14 +254,14 @@ function addStyleRulesRecursively({
184
254
  rule,
185
255
  activeAtRules,
186
256
  classNames,
187
- definedStylesByKey
257
+ collector
188
258
  });
189
259
  }
190
260
  }
191
261
  }
192
262
  function addClassDefinedStyles({
193
263
  element,
194
- definedStylesByKey
264
+ collector
195
265
  }) {
196
266
  const classNames = Array.from(
197
267
  new Set([...element.classList].filter(Boolean))
@@ -218,7 +288,7 @@ function addClassDefinedStyles({
218
288
  ruleList: sheet.cssRules,
219
289
  activeAtRules: [],
220
290
  classNames,
221
- definedStylesByKey
291
+ collector
222
292
  });
223
293
  } catch (error) {
224
294
  if (error instanceof DOMException && error.name === "SecurityError") {
@@ -230,7 +300,7 @@ function addClassDefinedStyles({
230
300
  }
231
301
  function addInlineDefinedStyles({
232
302
  element,
233
- definedStylesByKey
303
+ collector
234
304
  }) {
235
305
  if (!(element instanceof HTMLElement)) {
236
306
  return;
@@ -245,13 +315,21 @@ function addInlineDefinedStyles({
245
315
  continue;
246
316
  }
247
317
  setDefinedStyle({
248
- definedStylesByKey,
318
+ collector,
249
319
  property,
250
320
  variant: null,
251
321
  className: null,
252
322
  raw,
253
323
  resolved: raw
254
324
  });
325
+ setAuthoredDeclaration({
326
+ collector,
327
+ property,
328
+ declaration: {
329
+ value: raw,
330
+ isImportant: element.style.getPropertyPriority(property) === "important"
331
+ }
332
+ });
255
333
  }
256
334
  }
257
335
  function getOverrideStyleDeclarations(styleElement) {
@@ -279,7 +357,7 @@ function getOverrideStyleDeclarations(styleElement) {
279
357
  }
280
358
  function addOptimisticDefinedStyles({
281
359
  element,
282
- definedStylesByKey
360
+ collector
283
361
  }) {
284
362
  const tokens = (element.getAttribute(SELECT_MODE_OVERRIDE_ATTRIBUTE) ?? "").split(/\s+/).filter(Boolean);
285
363
  if (tokens.length === 0) {
@@ -300,13 +378,23 @@ function addOptimisticDefinedStyles({
300
378
  continue;
301
379
  }
302
380
  if (raw.toLowerCase() === "revert") {
303
- definedStylesByKey.delete(
381
+ collector.definedStylesByKey.delete(
304
382
  getDefinedStyleKey({ property, variant: null })
305
383
  );
384
+ setAuthoredDeclaration({
385
+ collector,
386
+ property,
387
+ declaration: { value: null, isImportant: true }
388
+ });
306
389
  continue;
307
390
  }
391
+ setAuthoredDeclaration({
392
+ collector,
393
+ property,
394
+ declaration: { value: raw, isImportant: true }
395
+ });
308
396
  setDefinedStyle({
309
- definedStylesByKey,
397
+ collector,
310
398
  property,
311
399
  variant: null,
312
400
  className: null,
@@ -316,12 +404,38 @@ function addOptimisticDefinedStyles({
316
404
  }
317
405
  }
318
406
  }
407
+ function collectStyles(element) {
408
+ const collector = {
409
+ definedStylesByKey: /* @__PURE__ */ new Map(),
410
+ authoredByProperty: /* @__PURE__ */ new Map()
411
+ };
412
+ addClassDefinedStyles({ element, collector });
413
+ addInlineDefinedStyles({ element, collector });
414
+ addOptimisticDefinedStyles({ element, collector });
415
+ return collector;
416
+ }
417
+ function getAuthoredStyles({
418
+ element,
419
+ collector
420
+ }) {
421
+ const authoredStyles = {};
422
+ for (const [property, declaration] of collector.authoredByProperty) {
423
+ const value = declaration.value && expandCustomProperties({ element, value: declaration.value });
424
+ if (value) {
425
+ authoredStyles[property] = value;
426
+ }
427
+ }
428
+ return authoredStyles;
429
+ }
430
+ function getElementStyles(element) {
431
+ const collector = collectStyles(element);
432
+ return {
433
+ definedStyles: Array.from(collector.definedStylesByKey.values()),
434
+ authoredStyles: getAuthoredStyles({ element, collector })
435
+ };
436
+ }
319
437
  function getDefinedStyles(element) {
320
- const definedStylesByKey = /* @__PURE__ */ new Map();
321
- addClassDefinedStyles({ element, definedStylesByKey });
322
- addInlineDefinedStyles({ element, definedStylesByKey });
323
- addOptimisticDefinedStyles({ element, definedStylesByKey });
324
- return Array.from(definedStylesByKey.values());
438
+ return getElementStyles(element).definedStyles;
325
439
  }
326
440
  function getInheritedStyles(element) {
327
441
  const computedStyle = window.getComputedStyle(element);
@@ -333,5 +447,6 @@ function getInheritedStyles(element) {
333
447
  }
334
448
  export {
335
449
  getDefinedStyles,
450
+ getElementStyles,
336
451
  getInheritedStyles
337
452
  };
@@ -1,5 +1,6 @@
1
1
  import { useCallback } from "react";
2
2
  import { buildGoogleFontsCssUrl, quoteFontFamily } from "../../_vendor/replo-utils/lib/fonts.mjs";
3
+ import { z } from "zod";
3
4
  import { buildSelector } from "../descriptor/elementDescriptor";
4
5
  import { createImagePreview } from "../imageOverridePreview";
5
6
  import {
@@ -115,6 +116,12 @@ function restoreOriginalState({
115
116
  } else {
116
117
  element.setAttribute(name, value);
117
118
  }
119
+ if (name === "src" && value === null) {
120
+ const video = z.instanceof(HTMLVideoElement).safeParse(element);
121
+ if (video.success) {
122
+ video.data.load();
123
+ }
124
+ }
118
125
  }
119
126
  return;
120
127
  }
@@ -88,16 +88,14 @@ function useSelectionInteractions() {
88
88
  cancelAnimationFrame(dragAnimationFrameId);
89
89
  actions().setDragAnimationFrameId(null);
90
90
  };
91
- const resetDragState = ({
92
- notifyParentDragCleared = true
93
- } = {}) => {
91
+ const resetDragState = () => {
94
92
  const currentSession = interactionSessionRef.current;
95
93
  stopDragAnimation();
96
94
  if (currentSession.type !== "drag") {
97
95
  actions().setDragCandidates([]);
98
96
  return;
99
97
  }
100
- if (notifyParentDragCleared && currentSession.hasExceededThreshold) {
98
+ if (currentSession.hasExceededThreshold) {
101
99
  getWebsiteBuilderRpc()?.dragRectUpdated({
102
100
  dragRect: null,
103
101
  selectionRects: []
@@ -214,6 +212,10 @@ function useSelectionInteractions() {
214
212
  if (session.type !== "drag") {
215
213
  return;
216
214
  }
215
+ if ((event.buttons & 1) === 0) {
216
+ resetDragState();
217
+ return;
218
+ }
217
219
  interactionSessionRef.current = {
218
220
  ...session,
219
221
  dragCurrent: getDragPositionFromClient({
@@ -375,7 +377,7 @@ function useSelectionInteractions() {
375
377
  const dragCurrent = snapshot.type === "drag" ? snapshot.dragCurrent : null;
376
378
  const scrollOffset = snapshot.type === "drag" ? snapshot.scrollOffset : getDocumentScrollOffset();
377
379
  const candidates = store().dragCandidates;
378
- resetDragState({ notifyParentDragCleared: false });
380
+ resetDragState();
379
381
  if (snapshot.type !== "drag" || !dragStart) {
380
382
  return;
381
383
  }
@@ -50,6 +50,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
50
50
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
51
51
  }, import("zod/v4/core").$strip>>;
52
52
  }, import("zod/v4/core").$strip>>;
53
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
54
+ src: import("zod").ZodString;
55
+ currentSrc: import("zod").ZodString;
56
+ }, import("zod/v4/core").$strip>>;
53
57
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
54
58
  property: import("zod").ZodString;
55
59
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -63,6 +67,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
63
67
  raw: import("zod").ZodString;
64
68
  resolved: import("zod").ZodString;
65
69
  }, import("zod/v4/core").$strip>>>;
70
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
66
71
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
67
72
  clickPosition: import("zod").ZodObject<{
68
73
  x: import("zod").ZodNumber;
@@ -145,6 +150,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
145
150
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
146
151
  }, import("zod/v4/core").$strip>>;
147
152
  }, import("zod/v4/core").$strip>>;
153
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
154
+ src: import("zod").ZodString;
155
+ currentSrc: import("zod").ZodString;
156
+ }, import("zod/v4/core").$strip>>;
148
157
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
149
158
  property: import("zod").ZodString;
150
159
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -158,6 +167,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
158
167
  raw: import("zod").ZodString;
159
168
  resolved: import("zod").ZodString;
160
169
  }, import("zod/v4/core").$strip>>>;
170
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
161
171
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
162
172
  clickPosition: import("zod").ZodObject<{
163
173
  x: import("zod").ZodNumber;
@@ -329,6 +339,10 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
329
339
  previewUrl: import("zod").ZodNullable<import("zod").ZodString>;
330
340
  }, import("zod/v4/core").$strip>>;
331
341
  }, import("zod/v4/core").$strip>>;
342
+ video: import("zod").ZodOptional<import("zod").ZodObject<{
343
+ src: import("zod").ZodString;
344
+ currentSrc: import("zod").ZodString;
345
+ }, import("zod/v4/core").$strip>>;
332
346
  definedStyles: import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodObject<{
333
347
  property: import("zod").ZodString;
334
348
  variant: import("zod").ZodNullable<import("zod").ZodObject<{
@@ -342,6 +356,7 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
342
356
  raw: import("zod").ZodString;
343
357
  resolved: import("zod").ZodString;
344
358
  }, import("zod/v4/core").$strip>>>;
359
+ authoredStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
345
360
  inheritedStyles: import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodString>>;
346
361
  clickPosition: import("zod").ZodObject<{
347
362
  x: import("zod").ZodNumber;
@@ -396,8 +411,8 @@ export declare function getSelectModeIframeRpcChannel(): import("../_vendor/sche
396
411
  inputSchema: import("zod").ZodObject<{
397
412
  feedback: import("zod").ZodNullable<import("zod").ZodObject<{
398
413
  status: import("zod").ZodEnum<{
399
- unavailable: "unavailable";
400
414
  pending: "pending";
415
+ unavailable: "unavailable";
401
416
  failed: "failed";
402
417
  }>;
403
418
  rect: import("zod").ZodObject<{
@@ -5,6 +5,7 @@ import type { SelectionFrameSpec } from "./selectionFrame";
5
5
  import type { SelectModeInteractionSession } from "./selectModeSession";
6
6
  import type { InlineTiptapEditor } from "./tiptapInlineEditor";
7
7
  export declare const EMPTY_ACTIVE_MARKS: SelectModeTiptapActiveMarks;
8
+ export declare const INLINE_EDIT_PREPARE_TIMEOUT_MS = 10000;
8
9
  type InlineEditDraft = {
9
10
  status: "pending";
10
11
  editId: string;
@@ -29,6 +29,7 @@ const EMPTY_ACTIVE_MARKS = {
29
29
  strike: false
30
30
  };
31
31
  const FOCUS_STEAL_GUARD_MS = 1500;
32
+ const INLINE_EDIT_PREPARE_TIMEOUT_MS = 1e4;
32
33
  function isPendingEdit({
33
34
  editId,
34
35
  request
@@ -579,7 +580,7 @@ const selectModeStore = createShallowStore(
579
580
  const editId = crypto.randomUUID();
580
581
  const timeout = window.setTimeout(
581
582
  () => finishPendingEdit({ editId, status: "failed" }),
582
- 5e3
583
+ INLINE_EDIT_PREPARE_TIMEOUT_MS
583
584
  );
584
585
  setInlineEditRequest({
585
586
  activeMarks: EMPTY_ACTIVE_MARKS,
@@ -629,7 +630,11 @@ const selectModeStore = createShallowStore(
629
630
  element: symbolicated
630
631
  });
631
632
  resolveEditRequest({ editId, allowed });
632
- }).catch(() => {
633
+ }).catch((error) => {
634
+ console.error(
635
+ "[selectMode] inline text edit prepare failed",
636
+ error
637
+ );
633
638
  if (get().editId === editId) {
634
639
  revertInlineEdit();
635
640
  } else {
@@ -693,6 +698,7 @@ const useInteractionSession = () => {
693
698
  };
694
699
  export {
695
700
  EMPTY_ACTIVE_MARKS,
701
+ INLINE_EDIT_PREPARE_TIMEOUT_MS,
696
702
  selectModeStore,
697
703
  useDisplayMode,
698
704
  useEditingElement,