@replohq/sandbox-runtime 0.1.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.
Files changed (139) hide show
  1. package/ClientErrorBoundary.d.ts +10 -0
  2. package/ClientErrorBoundary.js +61 -0
  3. package/ClientErrorBoundary.js.map +7 -0
  4. package/DocumentReadyBeacon.d.ts +1 -0
  5. package/DocumentReadyBeacon.js +9 -0
  6. package/DocumentReadyBeacon.js.map +7 -0
  7. package/LICENSE +11 -0
  8. package/LinkInterceptor.d.ts +1 -0
  9. package/LinkInterceptor.js +128 -0
  10. package/LinkInterceptor.js.map +7 -0
  11. package/NextErrorReporter.d.ts +1 -0
  12. package/NextErrorReporter.js +92 -0
  13. package/NextErrorReporter.js.map +7 -0
  14. package/_vendor/replo-utils/lib/crypto.d.ts +30 -0
  15. package/_vendor/replo-utils/lib/errors.d.ts +83 -0
  16. package/_vendor/replo-utils/lib/fonts.d.ts +49 -0
  17. package/_vendor/replo-utils/lib/fonts.mjs +221 -0
  18. package/_vendor/replo-utils/lib/geometry.d.ts +18 -0
  19. package/_vendor/replo-utils/lib/geometry.mjs +9 -0
  20. package/_vendor/replo-utils/lib/json.d.ts +6 -0
  21. package/_vendor/replo-utils/lib/log.d.ts +11 -0
  22. package/_vendor/replo-utils/lib/misc.d.ts +145 -0
  23. package/_vendor/replo-utils/lib/misc.mjs +2 -0
  24. package/_vendor/replo-utils/lib/object.d.ts +31 -0
  25. package/_vendor/replo-utils/lib/parse.d.ts +15 -0
  26. package/_vendor/replo-utils/lib/posthogReplay.d.ts +43 -0
  27. package/_vendor/replo-utils/lib/posthogReplay.mjs +121 -0
  28. package/_vendor/replo-utils/react/use-iframe-rpc-channel.d.ts +14 -0
  29. package/_vendor/replo-utils/react/use-iframe-rpc-channel.mjs +14 -0
  30. package/_vendor/schemas/designLibrary.d.ts +361 -0
  31. package/_vendor/schemas/designLibrary.mjs +126 -0
  32. package/_vendor/schemas/errors.d.ts +459 -0
  33. package/_vendor/schemas/generated/errors.d.ts +61 -0
  34. package/_vendor/schemas/generated/pageAnnotations.d.ts +48 -0
  35. package/_vendor/schemas/generated/pageAnnotations.mjs +1 -0
  36. package/_vendor/schemas/generated/selectMode.d.ts +119 -0
  37. package/_vendor/schemas/generated/selectMode.mjs +1 -0
  38. package/_vendor/schemas/generated/selectModeIframeRpc.d.ts +100 -0
  39. package/_vendor/schemas/generated/selectModeIframeRpc.mjs +1 -0
  40. package/_vendor/schemas/iframeRpcChannel.d.ts +82 -0
  41. package/_vendor/schemas/iframeRpcChannel.mjs +520 -0
  42. package/_vendor/schemas/pageAnnotations.d.ts +134 -0
  43. package/_vendor/schemas/pageAnnotations.mjs +61 -0
  44. package/_vendor/schemas/savedStyles.d.ts +140 -0
  45. package/_vendor/schemas/selectMode.d.ts +522 -0
  46. package/_vendor/schemas/selectMode.mjs +3 -0
  47. package/_vendor/schemas/selectModeIframeRpc.d.ts +900 -0
  48. package/_vendor/schemas/selectModeIframeRpc.mjs +223 -0
  49. package/annotations/AnnotationLayerMount.d.ts +1 -0
  50. package/annotations/AnnotationLayerMount.js +13 -0
  51. package/annotations/AnnotationLayerMount.js.map +7 -0
  52. package/annotations/annotationController.d.ts +1 -0
  53. package/annotations/annotationController.js +384 -0
  54. package/annotations/annotationController.js.map +7 -0
  55. package/annotations/bridgeGate.d.ts +7 -0
  56. package/annotations/bridgeGate.js +22 -0
  57. package/annotations/bridgeGate.js.map +7 -0
  58. package/chunk-3UFG7XTQ.mjs +205 -0
  59. package/chunk-FNTGY7I5.mjs +68 -0
  60. package/chunk-N5EI2MOZ.mjs +1535 -0
  61. package/design-library-preview/DesignLibraryPreview.d.ts +1 -0
  62. package/design-library-preview/DesignLibraryPreview.js +93 -0
  63. package/design-library-preview/DesignLibraryPreview.js.map +7 -0
  64. package/package.json +41 -0
  65. package/posthog-relay.d.ts +11 -0
  66. package/posthog-relay.js +72 -0
  67. package/posthog-relay.js.map +7 -0
  68. package/sandbox-runtime.d.ts +1 -0
  69. package/sandbox-runtime.js +29 -0
  70. package/sandbox-runtime.js.map +7 -0
  71. package/select-mode/EditorSelection.d.ts +24 -0
  72. package/select-mode/EditorSelection.js +95 -0
  73. package/select-mode/EditorSelection.js.map +7 -0
  74. package/select-mode/annotationFrames.d.ts +33 -0
  75. package/select-mode/annotationFrames.js +119 -0
  76. package/select-mode/annotationFrames.js.map +7 -0
  77. package/select-mode/descriptor/elementDescriptor.d.ts +26 -0
  78. package/select-mode/descriptor/elementDescriptor.js +201 -0
  79. package/select-mode/descriptor/elementDescriptor.js.map +7 -0
  80. package/select-mode/descriptor/styleExtraction.d.ts +3 -0
  81. package/select-mode/descriptor/styleExtraction.js +271 -0
  82. package/select-mode/descriptor/styleExtraction.js.map +7 -0
  83. package/select-mode/displayModeStore.d.ts +10 -0
  84. package/select-mode/displayModeStore.js +47 -0
  85. package/select-mode/displayModeStore.js.map +7 -0
  86. package/select-mode/fast-refresh-relay.d.ts +3 -0
  87. package/select-mode/fast-refresh-relay.js +33 -0
  88. package/select-mode/fast-refresh-relay.js.map +7 -0
  89. package/select-mode/fiber.d.ts +49 -0
  90. package/select-mode/fiber.js +306 -0
  91. package/select-mode/fiber.js.map +7 -0
  92. package/select-mode/hooks/useCrosshairCursor.d.ts +12 -0
  93. package/select-mode/hooks/useCrosshairCursor.js +20 -0
  94. package/select-mode/hooks/useCrosshairCursor.js.map +7 -0
  95. package/select-mode/hooks/useEditModeStateMachine.d.ts +16 -0
  96. package/select-mode/hooks/useEditModeStateMachine.js +235 -0
  97. package/select-mode/hooks/useEditModeStateMachine.js.map +7 -0
  98. package/select-mode/hooks/useOptimisticOverrides.d.ts +17 -0
  99. package/select-mode/hooks/useOptimisticOverrides.js +283 -0
  100. package/select-mode/hooks/useOptimisticOverrides.js.map +7 -0
  101. package/select-mode/hooks/useParentMessaging.d.ts +36 -0
  102. package/select-mode/hooks/useParentMessaging.js +74 -0
  103. package/select-mode/hooks/useParentMessaging.js.map +7 -0
  104. package/select-mode/hooks/useSelectModeController.d.ts +8 -0
  105. package/select-mode/hooks/useSelectModeController.js +46 -0
  106. package/select-mode/hooks/useSelectModeController.js.map +7 -0
  107. package/select-mode/hooks/useSelectionHover.d.ts +22 -0
  108. package/select-mode/hooks/useSelectionHover.js +110 -0
  109. package/select-mode/hooks/useSelectionHover.js.map +7 -0
  110. package/select-mode/hooks/useSelectionInteractions.d.ts +37 -0
  111. package/select-mode/hooks/useSelectionInteractions.js +353 -0
  112. package/select-mode/hooks/useSelectionInteractions.js.map +7 -0
  113. package/select-mode/hooks/useSelectionScrollSync.d.ts +28 -0
  114. package/select-mode/hooks/useSelectionScrollSync.js +70 -0
  115. package/select-mode/hooks/useSelectionScrollSync.js.map +7 -0
  116. package/select-mode/hooks/useSiblingResolution.d.ts +6 -0
  117. package/select-mode/hooks/useSiblingResolution.js +59 -0
  118. package/select-mode/hooks/useSiblingResolution.js.map +7 -0
  119. package/select-mode/iframeRpcChannel.d.ts +356 -0
  120. package/select-mode/iframeRpcChannel.js +92 -0
  121. package/select-mode/iframeRpcChannel.js.map +7 -0
  122. package/select-mode/inlineTextMarks.d.ts +6 -0
  123. package/select-mode/inlineTextMarks.js +25 -0
  124. package/select-mode/inlineTextMarks.js.map +7 -0
  125. package/select-mode/interactions/selectionGeometry.d.ts +105 -0
  126. package/select-mode/interactions/selectionGeometry.js +192 -0
  127. package/select-mode/interactions/selectionGeometry.js.map +7 -0
  128. package/select-mode/selectModeSession.d.ts +21 -0
  129. package/select-mode/selectModeSession.js +7 -0
  130. package/select-mode/selectModeSession.js.map +7 -0
  131. package/select-mode/selectionFrame.d.ts +81 -0
  132. package/select-mode/selectionFrame.js +132 -0
  133. package/select-mode/selectionFrame.js.map +7 -0
  134. package/select-mode/symbolicate.d.ts +2 -0
  135. package/select-mode/symbolicate.js +200 -0
  136. package/select-mode/symbolicate.js.map +7 -0
  137. package/select-mode/tiptapInlineEditor.d.ts +23 -0
  138. package/select-mode/tiptapInlineEditor.js +120 -0
  139. package/select-mode/tiptapInlineEditor.js.map +7 -0
@@ -0,0 +1,33 @@
1
+ import { getWebsiteBuilderRpc } from "./iframeRpcChannel";
2
+ let hasInstalledFastRefreshRelay = false;
3
+ let onFastRefreshComplete = null;
4
+ function installFastRefreshRelay({
5
+ onComplete
6
+ } = {}) {
7
+ onFastRefreshComplete = onComplete ?? null;
8
+ if (hasInstalledFastRefreshRelay) {
9
+ return;
10
+ }
11
+ hasInstalledFastRefreshRelay = true;
12
+ const originalLog = console.log;
13
+ const originalInfo = console.info;
14
+ const relayIfFastRefreshComplete = (...args) => {
15
+ const message = args.join(" ");
16
+ if (message.includes("[Fast Refresh] done")) {
17
+ getWebsiteBuilderRpc()?.fastRefreshComplete(void 0);
18
+ onFastRefreshComplete?.();
19
+ }
20
+ };
21
+ console.log = (...args) => {
22
+ relayIfFastRefreshComplete(...args);
23
+ originalLog(...args);
24
+ };
25
+ console.info = (...args) => {
26
+ relayIfFastRefreshComplete(...args);
27
+ originalInfo(...args);
28
+ };
29
+ }
30
+ export {
31
+ installFastRefreshRelay
32
+ };
33
+ //# sourceMappingURL=fast-refresh-relay.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../select-mode/fast-refresh-relay.ts"],
4
+ "sourcesContent": ["import { getWebsiteBuilderRpc } from \"./iframeRpcChannel\";\n\nlet hasInstalledFastRefreshRelay = false;\nlet onFastRefreshComplete: (() => void) | null = null;\n\nexport function installFastRefreshRelay({\n onComplete,\n}: { onComplete?: () => void } = {}) {\n onFastRefreshComplete = onComplete ?? null;\n if (hasInstalledFastRefreshRelay) {\n return;\n }\n hasInstalledFastRefreshRelay = true;\n\n const originalLog = console.log;\n const originalInfo = console.info;\n const relayIfFastRefreshComplete = (...args: unknown[]) => {\n const message = args.join(\" \");\n if (message.includes(\"[Fast Refresh] done\")) {\n getWebsiteBuilderRpc()?.fastRefreshComplete(undefined);\n onFastRefreshComplete?.();\n }\n };\n\n console.log = (...args: unknown[]) => {\n relayIfFastRefreshComplete(...args);\n originalLog(...args);\n };\n console.info = (...args: unknown[]) => {\n relayIfFastRefreshComplete(...args);\n originalInfo(...args);\n };\n}\n"],
5
+ "mappings": "AAAA,SAAS,4BAA4B;AAErC,IAAI,+BAA+B;AACnC,IAAI,wBAA6C;AAE1C,SAAS,wBAAwB;AAAA,EACtC;AACF,IAAiC,CAAC,GAAG;AACnC,0BAAwB,cAAc;AACtC,MAAI,8BAA8B;AAChC;AAAA,EACF;AACA,iCAA+B;AAE/B,QAAM,cAAc,QAAQ;AAC5B,QAAM,eAAe,QAAQ;AAC7B,QAAM,6BAA6B,IAAI,SAAoB;AACzD,UAAM,UAAU,KAAK,KAAK,GAAG;AAC7B,QAAI,QAAQ,SAAS,qBAAqB,GAAG;AAC3C,2BAAqB,GAAG,oBAAoB,MAAS;AACrD,8BAAwB;AAAA,IAC1B;AAAA,EACF;AAEA,UAAQ,MAAM,IAAI,SAAoB;AACpC,+BAA2B,GAAG,IAAI;AAClC,gBAAY,GAAG,IAAI;AAAA,EACrB;AACA,UAAQ,OAAO,IAAI,SAAoB;AACrC,+BAA2B,GAAG,IAAI;AAClC,iBAAa,GAAG,IAAI;AAAA,EACtB;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,49 @@
1
+ export interface ReactFiber {
2
+ _debugSource?: {
3
+ fileName: string;
4
+ lineNumber: number;
5
+ columnNumber?: number;
6
+ };
7
+ _debugStack?: unknown;
8
+ _debugOwner?: ReactFiber;
9
+ type?: {
10
+ name?: string;
11
+ displayName?: string;
12
+ } | string | ((...args: unknown[]) => unknown) | null;
13
+ return?: ReactFiber | null;
14
+ memoizedProps?: Record<string, unknown>;
15
+ pendingProps?: Record<string, unknown>;
16
+ }
17
+ export declare function getFiberFromElement(element: HTMLElement): ReactFiber | null;
18
+ export declare function getComponentName(fiber: ReactFiber | null | undefined): string | undefined;
19
+ export declare function findDebugSource(fiber: ReactFiber, maxDepth?: number): {
20
+ source: ReactFiber["_debugSource"];
21
+ componentName?: string;
22
+ } | null;
23
+ export declare function findDebugSourceReact19(fiber: ReactFiber): {
24
+ source: ReactFiber["_debugSource"];
25
+ componentName?: string;
26
+ } | null;
27
+ export declare function getSourceLocation(element: HTMLElement): {
28
+ filePath: string;
29
+ lineNumber: number;
30
+ columnNumber: number | undefined;
31
+ componentName: string | undefined;
32
+ } | undefined;
33
+ export declare function getHostSourceIdentity(element: HTMLElement): {
34
+ filePath: string;
35
+ lineNumber: number;
36
+ columnNumber: number | undefined;
37
+ tagName: string;
38
+ } | null;
39
+ export declare function getFiberChain(element: HTMLElement): {
40
+ sourceLocation: {
41
+ filePath: string;
42
+ lineNumber: number;
43
+ columnNumber: number | undefined;
44
+ componentName: string | undefined;
45
+ };
46
+ tagName: string | undefined;
47
+ componentName: string | undefined;
48
+ props: Record<string, unknown> | undefined;
49
+ }[];
@@ -0,0 +1,306 @@
1
+ import { z } from "zod";
2
+ const MAX_FIBER_CHAIN_DEPTH = 80;
3
+ const MAX_SERIALIZED_PROP_COUNT = 24;
4
+ const MAX_SERIALIZED_STRING_LENGTH = 500;
5
+ const REACT_INTERNAL_FRAME_PATTERNS = [
6
+ /react.*jsx-dev-runtime/,
7
+ /react.*jsx-runtime/,
8
+ /react-dom\//,
9
+ /react\/cjs\/react\./,
10
+ /react-server-dom/,
11
+ /react_server_dom/,
12
+ /next[/_.]dist[/_.]compiled/,
13
+ /\/node_modules\/(next|react|react-dom)\//
14
+ ];
15
+ function isReactInternalFrame(fileName) {
16
+ return REACT_INTERNAL_FRAME_PATTERNS.some((pattern) => {
17
+ return pattern.test(fileName);
18
+ });
19
+ }
20
+ const REACT_INTERNAL_METHOD_PATTERNS = [
21
+ /(?:^|\.)jsxDEV(?:Impl)?$/,
22
+ /(?:^|\.)jsxs?$/,
23
+ /(?:^|\.)react_stack_bottom_frame$/,
24
+ /(?:^|\.)fakeJSXCallSite$/
25
+ ];
26
+ function isReactInternalMethod(methodName) {
27
+ if (!methodName) {
28
+ return false;
29
+ }
30
+ return REACT_INTERNAL_METHOD_PATTERNS.some((pattern) => {
31
+ return pattern.test(methodName);
32
+ });
33
+ }
34
+ function parseDebugStackSource(debugStack) {
35
+ let stackText = null;
36
+ if (typeof debugStack === "string") {
37
+ stackText = debugStack;
38
+ } else if (typeof debugStack === "object" && debugStack && "stack" in debugStack) {
39
+ const stack = debugStack.stack;
40
+ if (typeof stack === "string") {
41
+ stackText = stack;
42
+ }
43
+ }
44
+ if (!stackText) {
45
+ return null;
46
+ }
47
+ for (const rawLine of stackText.split("\n")) {
48
+ const line = rawLine.trim();
49
+ if (!line) {
50
+ continue;
51
+ }
52
+ const framedMatch = line.match(/^at\s+(.+?)\s+\((.*):(\d+):(\d+)\)$/);
53
+ const stackFrameMatch = framedMatch ?? line.match(/^at\s+(?:.*\()?(.*):(\d+):(\d+)\)?$/) ?? line.match(/^(.*):(\d+):(\d+)$/);
54
+ if (!stackFrameMatch) {
55
+ continue;
56
+ }
57
+ const methodName = framedMatch ? framedMatch[1].trim() : null;
58
+ const fileOffset = framedMatch ? 2 : 1;
59
+ const fileName = stackFrameMatch[fileOffset]?.trim();
60
+ const lineNumber = Number.parseInt(
61
+ stackFrameMatch[fileOffset + 1] ?? "",
62
+ 10
63
+ );
64
+ const columnNumber = Number.parseInt(
65
+ stackFrameMatch[fileOffset + 2] ?? "",
66
+ 10
67
+ );
68
+ if (!fileName || !Number.isFinite(lineNumber) || !Number.isFinite(columnNumber)) {
69
+ continue;
70
+ }
71
+ if (isReactInternalFrame(fileName) || isReactInternalMethod(methodName)) {
72
+ continue;
73
+ }
74
+ return {
75
+ fileName,
76
+ lineNumber,
77
+ columnNumber
78
+ };
79
+ }
80
+ return null;
81
+ }
82
+ function getFiberFromElement(element) {
83
+ if (!element || typeof element !== "object") {
84
+ return null;
85
+ }
86
+ const symbolKeys = Object.getOwnPropertySymbols(element);
87
+ const fiberSymbolKey = symbolKeys.find((symbolKey) => {
88
+ return symbolKey.toString().includes("reactFiber");
89
+ });
90
+ if (fiberSymbolKey) {
91
+ return (
92
+ // Legacy cast - may or may not be necessary
93
+ // eslint-disable-next-line replo/no-as-cast
94
+ element[fiberSymbolKey] ?? null
95
+ );
96
+ }
97
+ const keys = Object.keys(element);
98
+ const fiberKey = keys.find((key) => key.startsWith("__reactFiber$"));
99
+ if (fiberKey) {
100
+ return element[fiberKey] ?? null;
101
+ }
102
+ const instanceKey = keys.find((key) => {
103
+ return key.startsWith("__reactInternalInstance$");
104
+ });
105
+ if (instanceKey) {
106
+ return (
107
+ // Legacy cast - may or may not be necessary
108
+ // eslint-disable-next-line replo/no-as-cast
109
+ element[instanceKey] ?? null
110
+ );
111
+ }
112
+ const possibleFiberKey = keys.find((key) => {
113
+ if (!key.startsWith("__react")) {
114
+ return false;
115
+ }
116
+ const value = element[key];
117
+ return value && typeof value === "object" && "_debugSource" in value;
118
+ });
119
+ if (possibleFiberKey) {
120
+ return (
121
+ // Legacy cast - may or may not be necessary
122
+ // eslint-disable-next-line replo/no-as-cast
123
+ element[possibleFiberKey] ?? null
124
+ );
125
+ }
126
+ return null;
127
+ }
128
+ function getComponentName(fiber) {
129
+ if (!fiber?.type) {
130
+ return void 0;
131
+ }
132
+ if (typeof fiber.type === "string") {
133
+ return void 0;
134
+ }
135
+ if (typeof fiber.type === "function") {
136
+ return fiber.type.name || void 0;
137
+ }
138
+ if (typeof fiber.type === "object") {
139
+ return fiber.type.displayName ?? fiber.type.name ?? void 0;
140
+ }
141
+ return void 0;
142
+ }
143
+ function findDebugSource(fiber, maxDepth = 50) {
144
+ let current = fiber;
145
+ let depth = 0;
146
+ while (current && depth < maxDepth) {
147
+ if (current._debugSource) {
148
+ return {
149
+ source: current._debugSource,
150
+ componentName: getComponentName(current)
151
+ };
152
+ }
153
+ if (current._debugOwner?._debugSource) {
154
+ return {
155
+ source: current._debugOwner._debugSource,
156
+ componentName: getComponentName(current._debugOwner)
157
+ };
158
+ }
159
+ current = current.return;
160
+ depth++;
161
+ }
162
+ return null;
163
+ }
164
+ function findDebugSourceReact19(fiber) {
165
+ let current = fiber;
166
+ let depth = 0;
167
+ const maxDepth = 50;
168
+ while (current && depth < maxDepth) {
169
+ const debugStackSource = parseDebugStackSource(current._debugStack) ?? parseDebugStackSource(current._debugOwner?._debugStack);
170
+ if (debugStackSource) {
171
+ return {
172
+ source: debugStackSource,
173
+ componentName: getComponentName(current)
174
+ };
175
+ }
176
+ current = current.return;
177
+ depth++;
178
+ }
179
+ return null;
180
+ }
181
+ function getSourceLocation(element) {
182
+ let currentElement = element;
183
+ while (currentElement) {
184
+ const fiber = getFiberFromElement(currentElement);
185
+ if (fiber) {
186
+ const debugInfo = findDebugSource(fiber) ?? findDebugSourceReact19(fiber);
187
+ if (debugInfo?.source) {
188
+ return {
189
+ filePath: debugInfo.source.fileName,
190
+ lineNumber: debugInfo.source.lineNumber,
191
+ columnNumber: debugInfo.source.columnNumber,
192
+ componentName: debugInfo.componentName ?? void 0
193
+ };
194
+ }
195
+ }
196
+ currentElement = currentElement.parentElement;
197
+ }
198
+ return void 0;
199
+ }
200
+ function getDebugSource(fiber) {
201
+ const debugInfo = findDebugSource(fiber) ?? findDebugSourceReact19(fiber);
202
+ return debugInfo?.source;
203
+ }
204
+ function getTagName(fiber) {
205
+ return z.string().safeParse(fiber.type).data?.toLowerCase();
206
+ }
207
+ function getHostSourceIdentity(element) {
208
+ const fiber = getFiberFromElement(element);
209
+ if (!fiber) {
210
+ return null;
211
+ }
212
+ const source = getDebugSource(fiber);
213
+ if (!source) {
214
+ return null;
215
+ }
216
+ return {
217
+ filePath: source.fileName,
218
+ lineNumber: source.lineNumber,
219
+ columnNumber: source.columnNumber,
220
+ tagName: element.tagName.toLowerCase()
221
+ };
222
+ }
223
+ function getSerializablePropValue(value) {
224
+ if (value === null || typeof value === "number" || typeof value === "boolean") {
225
+ return value;
226
+ }
227
+ if (typeof value === "string") {
228
+ return value.length > MAX_SERIALIZED_STRING_LENGTH ? `${value.slice(0, MAX_SERIALIZED_STRING_LENGTH)}...` : value;
229
+ }
230
+ if (Array.isArray(value)) {
231
+ return value.slice(0, 20).map(getSerializablePropValue);
232
+ }
233
+ if (typeof value === "object") {
234
+ return "[object]";
235
+ }
236
+ return void 0;
237
+ }
238
+ function getSerializableProps(props) {
239
+ if (!props) {
240
+ return void 0;
241
+ }
242
+ const serializedProps = {};
243
+ for (const [key, value] of Object.entries(props).slice(
244
+ 0,
245
+ MAX_SERIALIZED_PROP_COUNT
246
+ )) {
247
+ if (key === "children" || key === "ref" || key.startsWith("on") || typeof value === "function" || typeof value === "symbol") {
248
+ continue;
249
+ }
250
+ const serializableValue = getSerializablePropValue(value);
251
+ if (serializableValue !== void 0) {
252
+ serializedProps[key] = serializableValue;
253
+ }
254
+ }
255
+ return Object.keys(serializedProps).length > 0 ? serializedProps : void 0;
256
+ }
257
+ function getFiberChain(element) {
258
+ const rootFiber = getFiberFromElement(element);
259
+ const fiberChain = [];
260
+ const seenKeys = /* @__PURE__ */ new Set();
261
+ let currentFiber = rootFiber;
262
+ let depth = 0;
263
+ while (currentFiber && depth < MAX_FIBER_CHAIN_DEPTH) {
264
+ const source = getDebugSource(currentFiber);
265
+ if (source) {
266
+ const tagName = getTagName(currentFiber);
267
+ const componentName = getComponentName(currentFiber);
268
+ const key = [
269
+ source.fileName,
270
+ source.lineNumber,
271
+ source.columnNumber ?? "",
272
+ tagName ?? "",
273
+ componentName ?? ""
274
+ ].join(":");
275
+ if (!seenKeys.has(key)) {
276
+ seenKeys.add(key);
277
+ fiberChain.push({
278
+ sourceLocation: {
279
+ filePath: source.fileName,
280
+ lineNumber: source.lineNumber,
281
+ columnNumber: source.columnNumber,
282
+ componentName
283
+ },
284
+ tagName,
285
+ componentName,
286
+ props: getSerializableProps(
287
+ currentFiber.memoizedProps ?? currentFiber.pendingProps
288
+ )
289
+ });
290
+ }
291
+ }
292
+ currentFiber = currentFiber.return;
293
+ depth += 1;
294
+ }
295
+ return fiberChain;
296
+ }
297
+ export {
298
+ findDebugSource,
299
+ findDebugSourceReact19,
300
+ getComponentName,
301
+ getFiberChain,
302
+ getFiberFromElement,
303
+ getHostSourceIdentity,
304
+ getSourceLocation
305
+ };
306
+ //# sourceMappingURL=fiber.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../select-mode/fiber.ts"],
4
+ "sourcesContent": ["// =============================================================================\n// React Fiber / Source Location Utilities\n// =============================================================================\n\nimport { z } from \"zod\";\n\nexport interface ReactFiber {\n _debugSource?: {\n fileName: string;\n lineNumber: number;\n columnNumber?: number;\n };\n _debugStack?: unknown;\n _debugOwner?: ReactFiber;\n type?:\n | { name?: string; displayName?: string }\n | string\n | ((...args: unknown[]) => unknown)\n | null;\n return?: ReactFiber | null;\n memoizedProps?: Record<string, unknown>;\n pendingProps?: Record<string, unknown>;\n}\n\nconst MAX_FIBER_CHAIN_DEPTH = 80;\nconst MAX_SERIALIZED_PROP_COUNT = 24;\nconst MAX_SERIALIZED_STRING_LENGTH = 500;\n\n// Frames produced by React's own JSX runtime \u2014 these come first in\n// `_debugStack.stack` because the `Error` is constructed inside `jsxDEV`. We\n// want the frame *above* them, which is the actual JSX call site.\n//\n// Turbopack rewrites `node_modules/next/dist/compiled/react-server-dom-*` and\n// friends into mangled chunk paths like\n// `_next/static/chunks/<hash>_next_dist_compiled_react-server-dom-turbopack_<hash>._.js`,\n// so we match both the human-readable module paths and the chunk-name forms.\n// Without this, `_debugStack`'s top frame inside React's RSC runtime gets\n// surfaced as the \"host\" source location for every text node on the page \u2014\n// which then symbolicates back to bundled React, not user code.\nconst REACT_INTERNAL_FRAME_PATTERNS = [\n /react.*jsx-dev-runtime/,\n /react.*jsx-runtime/,\n /react-dom\\//,\n /react\\/cjs\\/react\\./,\n /react-server-dom/,\n /react_server_dom/,\n /next[/_.]dist[/_.]compiled/,\n /\\/node_modules\\/(next|react|react-dom)\\//,\n];\n\nfunction isReactInternalFrame(fileName: string): boolean {\n return REACT_INTERNAL_FRAME_PATTERNS.some((pattern) => {\n return pattern.test(fileName);\n });\n}\n\n// React constructs the `_debugStack` Error inside its JSX runtime (`jsxDEV`,\n// `jsx`, `jsxs`), so those frames sit *above* the real JSX call site we want.\n// The file-based check above skips them when their path is recognizable, but\n// Turbopack mangles the client JSX-runtime chunk to an opaque name like\n// `node_modules__pnpm_<hash>._.js` (no \"react\"/\"jsx-dev-runtime\" substring),\n// so the top `jsxDEV` frame slips through and gets surfaced as the element's\n// source \u2014 which then symbolicates back to bundled React, not user code.\n// Matching by function name is stable across Turbopack's chunk hashing.\n// NOTE (Noah, 2026-07-27): Only bites client components; server-component\n// frames carry a recognizable `react-server-dom-*` path.\nconst REACT_INTERNAL_METHOD_PATTERNS = [\n /(?:^|\\.)jsxDEV(?:Impl)?$/,\n /(?:^|\\.)jsxs?$/,\n /(?:^|\\.)react_stack_bottom_frame$/,\n /(?:^|\\.)fakeJSXCallSite$/,\n];\n\nfunction isReactInternalMethod(methodName: string | null): boolean {\n if (!methodName) {\n return false;\n }\n return REACT_INTERNAL_METHOD_PATTERNS.some((pattern) => {\n return pattern.test(methodName);\n });\n}\n\nfunction parseDebugStackSource(\n debugStack: unknown,\n): ReactFiber[\"_debugSource\"] | null {\n let stackText: string | null = null;\n\n if (typeof debugStack === \"string\") {\n stackText = debugStack;\n } else if (\n typeof debugStack === \"object\" &&\n debugStack &&\n \"stack\" in debugStack\n ) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const stack = (debugStack as { stack?: unknown }).stack;\n if (typeof stack === \"string\") {\n stackText = stack;\n }\n }\n\n if (!stackText) {\n return null;\n }\n\n for (const rawLine of stackText.split(\"\\n\")) {\n const line = rawLine.trim();\n if (!line) {\n continue;\n }\n\n // Prefer the framed form `at <method> (<file>:<line>:<col>)` so we can\n // read the function name and skip React's JSX-runtime frames even when\n // Turbopack has mangled their chunk file name beyond recognition.\n const framedMatch = line.match(/^at\\s+(.+?)\\s+\\((.*):(\\d+):(\\d+)\\)$/);\n const stackFrameMatch =\n framedMatch ??\n line.match(/^at\\s+(?:.*\\()?(.*):(\\d+):(\\d+)\\)?$/) ??\n line.match(/^(.*):(\\d+):(\\d+)$/);\n\n if (!stackFrameMatch) {\n continue;\n }\n\n const methodName = framedMatch ? framedMatch[1]!.trim() : null;\n const fileOffset = framedMatch ? 2 : 1;\n const fileName = stackFrameMatch[fileOffset]?.trim();\n const lineNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 1] ?? \"\",\n 10,\n );\n const columnNumber = Number.parseInt(\n stackFrameMatch[fileOffset + 2] ?? \"\",\n 10,\n );\n\n if (\n !fileName ||\n !Number.isFinite(lineNumber) ||\n !Number.isFinite(columnNumber)\n ) {\n continue;\n }\n\n if (isReactInternalFrame(fileName) || isReactInternalMethod(methodName)) {\n continue;\n }\n\n return {\n fileName,\n lineNumber,\n columnNumber,\n };\n }\n\n return null;\n}\n\nexport function getFiberFromElement(element: HTMLElement): ReactFiber | null {\n if (!element || typeof element !== \"object\") {\n return null;\n }\n\n const symbolKeys = Object.getOwnPropertySymbols(element);\n const fiberSymbolKey = symbolKeys.find((symbolKey) => {\n return symbolKey.toString().includes(\"reactFiber\");\n });\n if (fiberSymbolKey) {\n return (\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n (element as unknown as Record<symbol, ReactFiber>)[fiberSymbolKey] ?? null\n );\n }\n\n const keys = Object.keys(element);\n const fiberKey = keys.find((key) => key.startsWith(\"__reactFiber$\"));\n if (fiberKey) {\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n return (element as unknown as Record<string, ReactFiber>)[fiberKey] ?? null;\n }\n const instanceKey = keys.find((key) => {\n return key.startsWith(\"__reactInternalInstance$\");\n });\n if (instanceKey) {\n return (\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n (element as unknown as Record<string, ReactFiber>)[instanceKey] ?? null\n );\n }\n\n const possibleFiberKey = keys.find((key) => {\n if (!key.startsWith(\"__react\")) {\n return false;\n }\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n const value = (element as unknown as Record<string, unknown>)[key];\n return value && typeof value === \"object\" && \"_debugSource\" in value;\n });\n\n if (possibleFiberKey) {\n return (\n // Legacy cast - may or may not be necessary\n // eslint-disable-next-line replo/no-as-cast\n (element as unknown as Record<string, ReactFiber>)[possibleFiberKey] ??\n null\n );\n }\n\n return null;\n}\n\nexport function getComponentName(\n fiber: ReactFiber | null | undefined,\n): string | undefined {\n if (!fiber?.type) {\n return undefined;\n }\n\n if (typeof fiber.type === \"string\") {\n return undefined;\n }\n\n if (typeof fiber.type === \"function\") {\n return fiber.type.name || undefined;\n }\n\n if (typeof fiber.type === \"object\") {\n return fiber.type.displayName ?? fiber.type.name ?? undefined;\n }\n\n return undefined;\n}\n\nexport function findDebugSource(\n fiber: ReactFiber,\n maxDepth = 50,\n): { source: ReactFiber[\"_debugSource\"]; componentName?: string } | null {\n let current: ReactFiber | null | undefined = fiber;\n let depth = 0;\n\n while (current && depth < maxDepth) {\n if (current._debugSource) {\n return {\n source: current._debugSource,\n componentName: getComponentName(current),\n };\n }\n\n if (current._debugOwner?._debugSource) {\n return {\n source: current._debugOwner._debugSource,\n componentName: getComponentName(current._debugOwner),\n };\n }\n\n current = current.return;\n depth++;\n }\n\n return null;\n}\n\n// React 19 removed `fiber._debugSource`. The only per-element source pointer\n// left is `fiber._debugStack`, an `Error` constructed inside `jsxDEV` at the\n// JSX call site. We pull the topmost non-React frame out of that stack; it\n// references a compiled SSR/client chunk (e.g. `.next-dev/.../ssr/*.js`).\n// `symbolicateSelectedElement` later resolves those compiled frames to\n// original `.tsx` locations via Next.js's `/__nextjs_original-stack-frames`\n// dev-server endpoint.\nexport function findDebugSourceReact19(\n fiber: ReactFiber,\n): { source: ReactFiber[\"_debugSource\"]; componentName?: string } | null {\n let current: ReactFiber | null | undefined = fiber;\n let depth = 0;\n const maxDepth = 50;\n\n while (current && depth < maxDepth) {\n const debugStackSource =\n parseDebugStackSource(current._debugStack) ??\n parseDebugStackSource(current._debugOwner?._debugStack);\n if (debugStackSource) {\n return {\n source: debugStackSource,\n componentName: getComponentName(current),\n };\n }\n\n current = current.return;\n depth++;\n }\n\n return null;\n}\n\nexport function getSourceLocation(element: HTMLElement) {\n let currentElement: HTMLElement | null = element;\n\n while (currentElement) {\n const fiber = getFiberFromElement(currentElement);\n if (fiber) {\n const debugInfo = findDebugSource(fiber) ?? findDebugSourceReact19(fiber);\n if (debugInfo?.source) {\n return {\n filePath: debugInfo.source.fileName,\n lineNumber: debugInfo.source.lineNumber,\n columnNumber: debugInfo.source.columnNumber,\n componentName: debugInfo.componentName ?? undefined,\n };\n }\n }\n\n currentElement = currentElement.parentElement;\n }\n\n return undefined;\n}\n\nfunction getDebugSource(\n fiber: ReactFiber,\n): ReactFiber[\"_debugSource\"] | undefined {\n const debugInfo = findDebugSource(fiber) ?? findDebugSourceReact19(fiber);\n return debugInfo?.source;\n}\n\nfunction getTagName(fiber: ReactFiber): string | undefined {\n return z.string().safeParse(fiber.type).data?.toLowerCase();\n}\n\nexport function getHostSourceIdentity(element: HTMLElement) {\n const fiber = getFiberFromElement(element);\n if (!fiber) {\n return null;\n }\n const source = getDebugSource(fiber);\n if (!source) {\n return null;\n }\n return {\n filePath: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n tagName: element.tagName.toLowerCase(),\n };\n}\n\nfunction getSerializablePropValue(value: unknown): unknown {\n if (\n value === null ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n ) {\n return value;\n }\n\n if (typeof value === \"string\") {\n return value.length > MAX_SERIALIZED_STRING_LENGTH\n ? `${value.slice(0, MAX_SERIALIZED_STRING_LENGTH)}...`\n : value;\n }\n\n if (Array.isArray(value)) {\n return value.slice(0, 20).map(getSerializablePropValue);\n }\n\n if (typeof value === \"object\") {\n return \"[object]\";\n }\n\n return undefined;\n}\n\nfunction getSerializableProps(\n props: Record<string, unknown> | undefined,\n): Record<string, unknown> | undefined {\n if (!props) {\n return undefined;\n }\n\n const serializedProps: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(props).slice(\n 0,\n MAX_SERIALIZED_PROP_COUNT,\n )) {\n if (\n key === \"children\" ||\n key === \"ref\" ||\n key.startsWith(\"on\") ||\n typeof value === \"function\" ||\n typeof value === \"symbol\"\n ) {\n continue;\n }\n\n const serializableValue = getSerializablePropValue(value);\n if (serializableValue !== undefined) {\n serializedProps[key] = serializableValue;\n }\n }\n\n return Object.keys(serializedProps).length > 0 ? serializedProps : undefined;\n}\n\nexport function getFiberChain(element: HTMLElement) {\n const rootFiber = getFiberFromElement(element);\n const fiberChain = [];\n const seenKeys = new Set<string>();\n let currentFiber: ReactFiber | null | undefined = rootFiber;\n let depth = 0;\n\n while (currentFiber && depth < MAX_FIBER_CHAIN_DEPTH) {\n const source = getDebugSource(currentFiber);\n if (source) {\n const tagName = getTagName(currentFiber);\n const componentName = getComponentName(currentFiber);\n const key = [\n source.fileName,\n source.lineNumber,\n source.columnNumber ?? \"\",\n tagName ?? \"\",\n componentName ?? \"\",\n ].join(\":\");\n\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n fiberChain.push({\n sourceLocation: {\n filePath: source.fileName,\n lineNumber: source.lineNumber,\n columnNumber: source.columnNumber,\n componentName,\n },\n tagName,\n componentName,\n props: getSerializableProps(\n currentFiber.memoizedProps ?? currentFiber.pendingProps,\n ),\n });\n }\n }\n\n currentFiber = currentFiber.return;\n depth += 1;\n }\n\n return fiberChain;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,12 @@
1
+ import type { DisplayMode } from "../../_vendor/schemas/generated/selectMode";
2
+ /**
3
+ * Forces a crosshair cursor + disables text selection / drag while the iframe
4
+ * is in `selection` mode. We inject a `<style>` tag into the iframe document
5
+ * (rather than toggling a class on `<html>`) so that the `!important` rule
6
+ * wins against any per-element cursor styling on the page being edited.
7
+ *
8
+ * @author Kevin O'Connell 2026-04-17
9
+ */
10
+ export declare function useCrosshairCursor({ displayMode, }: {
11
+ displayMode: DisplayMode;
12
+ }): void;
@@ -0,0 +1,20 @@
1
+ import { useEffect } from "react";
2
+ function useCrosshairCursor({
3
+ displayMode
4
+ }) {
5
+ useEffect(() => {
6
+ if (displayMode !== "selection") {
7
+ return;
8
+ }
9
+ const styleElement = document.createElement("style");
10
+ styleElement.textContent = "* { cursor: crosshair !important; user-select: none !important; -webkit-user-drag: none !important; }";
11
+ document.head.append(styleElement);
12
+ return () => {
13
+ styleElement.remove();
14
+ };
15
+ }, [displayMode]);
16
+ }
17
+ export {
18
+ useCrosshairCursor
19
+ };
20
+ //# sourceMappingURL=useCrosshairCursor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../select-mode/hooks/useCrosshairCursor.ts"],
4
+ "sourcesContent": ["import type { DisplayMode } from \"schemas/generated/selectMode\";\n\nimport { useEffect } from \"react\";\n\n/**\n * Forces a crosshair cursor + disables text selection / drag while the iframe\n * is in `selection` mode. We inject a `<style>` tag into the iframe document\n * (rather than toggling a class on `<html>`) so that the `!important` rule\n * wins against any per-element cursor styling on the page being edited.\n *\n * @author Kevin O'Connell 2026-04-17\n */\nexport function useCrosshairCursor({\n displayMode,\n}: {\n displayMode: DisplayMode;\n}) {\n // eslint-disable-next-line replo/no-use-effect -- Legacy effect - may or may not be necessary\n useEffect(() => {\n if (displayMode !== \"selection\") {\n return;\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.textContent =\n \"* { cursor: crosshair !important; user-select: none !important; -webkit-user-drag: none !important; }\";\n document.head.append(styleElement);\n\n return () => {\n styleElement.remove();\n };\n }, [displayMode]);\n}\n"],
5
+ "mappings": "AAEA,SAAS,iBAAiB;AAUnB,SAAS,mBAAmB;AAAA,EACjC;AACF,GAEG;AAED,YAAU,MAAM;AACd,QAAI,gBAAgB,aAAa;AAC/B;AAAA,IACF;AAEA,UAAM,eAAe,SAAS,cAAc,OAAO;AACnD,iBAAa,cACX;AACF,aAAS,KAAK,OAAO,YAAY;AAEjC,WAAO,MAAM;AACX,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF,GAAG,CAAC,WAAW,CAAC;AAClB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,16 @@
1
+ import type { MutableRefObject } from "react";
2
+ import type { DisplayMode, SelectableData, SelectModeFormatCommand } from "../../_vendor/schemas/generated/selectMode";
3
+ import type { SelectModeInteractionSession } from "../selectModeSession";
4
+ export declare function isTextEditableElement(element: Element): element is HTMLElement;
5
+ export declare function useEditModeStateMachine({ displayMode, interactionSessionRef, }: {
6
+ displayMode: DisplayMode;
7
+ interactionSessionRef: MutableRefObject<SelectModeInteractionSession>;
8
+ }): {
9
+ beginEditing: ({ element, descriptorPromise, }: {
10
+ element: Element;
11
+ descriptorPromise: Promise<SelectableData>;
12
+ }) => void;
13
+ editingElementRef: import("react").RefObject<HTMLElement | null>;
14
+ formatCommand: (command: SelectModeFormatCommand) => void;
15
+ revert: () => void;
16
+ };