@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,200 @@
1
+ import { isNullish } from "../_vendor/replo-utils/lib/misc.mjs";
2
+ const SYMBOLICATE_ENDPOINT = "/__nextjs_original-stack-frames";
3
+ function isLikelyCompiledLocation(location) {
4
+ if (!location) {
5
+ return false;
6
+ }
7
+ const filePath = location.filePath;
8
+ return filePath.includes(".next") || filePath.includes("/chunks/") || filePath.includes("webpack-internal:") || filePath.includes("turbopack:") || filePath.endsWith(".js") || filePath.startsWith("about:");
9
+ }
10
+ function isDependencyOrInternalPath(filePath) {
11
+ return filePath.includes("node_modules") || filePath.includes("/dist/compiled/") || filePath.startsWith("about:");
12
+ }
13
+ function isServerChunk(filePath) {
14
+ return filePath.startsWith("about://React/Server") || filePath.includes("/server/chunks/") || filePath.includes(".next-dev/dev/server/") || filePath.includes(".next/server/");
15
+ }
16
+ const NEXT_STATIC_PATH_PATTERN = /\/_next(\/static\/.+)/;
17
+ function getNextDistDir() {
18
+ try {
19
+ const distDir = process.env.__NEXT_DIST_DIR;
20
+ return typeof distDir === "string" && distDir.length > 0 ? distDir : null;
21
+ } catch {
22
+ return null;
23
+ }
24
+ }
25
+ function rewriteBrowserChunkUrlToDistPath(filePath) {
26
+ if (!/^https?:\/\//.test(filePath)) {
27
+ return filePath;
28
+ }
29
+ const distDir = getNextDistDir();
30
+ if (!distDir) {
31
+ return filePath;
32
+ }
33
+ let url;
34
+ try {
35
+ url = new URL(filePath);
36
+ } catch {
37
+ return filePath;
38
+ }
39
+ const staticPathMatch = NEXT_STATIC_PATH_PATTERN.exec(url.pathname);
40
+ if (!staticPathMatch?.[1]) {
41
+ return filePath;
42
+ }
43
+ const normalizedDistDir = distDir.replace(/\\/g, "/").replace(/\/$/, "");
44
+ return `file://${normalizedDistDir}${staticPathMatch[1]}${url.search}`;
45
+ }
46
+ function normalizeFilePathForSymbolicator(filePath) {
47
+ let normalized = filePath;
48
+ if (normalized.startsWith("about://React/Server/")) {
49
+ normalized = normalized.slice("about://React/Server/".length);
50
+ }
51
+ normalized = normalized.replace(/\?\d+$/, "");
52
+ return rewriteBrowserChunkUrlToDistPath(normalized);
53
+ }
54
+ function toNextStackFrame(location) {
55
+ return {
56
+ file: normalizeFilePathForSymbolicator(location.filePath),
57
+ methodName: location.componentName ?? null,
58
+ arguments: [],
59
+ line1: location.lineNumber,
60
+ column1: location.columnNumber ?? null
61
+ };
62
+ }
63
+ function extractResolvedFrame(entry) {
64
+ if (!entry || entry.status !== "fulfilled") {
65
+ return null;
66
+ }
67
+ return entry.value?.originalStackFrame ?? null;
68
+ }
69
+ async function postFrames({
70
+ frames,
71
+ isServer
72
+ }) {
73
+ if (frames.length === 0) {
74
+ return [];
75
+ }
76
+ try {
77
+ const response = await fetch(SYMBOLICATE_ENDPOINT, {
78
+ method: "POST",
79
+ headers: { "content-type": "application/json" },
80
+ body: JSON.stringify({
81
+ frames,
82
+ isServer,
83
+ isEdgeServer: false,
84
+ isAppDirectory: true
85
+ })
86
+ });
87
+ if (!response.ok) {
88
+ console.log("[selectMode] symbolicate: endpoint returned non-OK status", {
89
+ status: response.status,
90
+ isServer
91
+ });
92
+ return frames.map(() => null);
93
+ }
94
+ const parsed = await response.json();
95
+ if (Array.isArray(parsed)) {
96
+ return parsed;
97
+ }
98
+ return frames.map(() => null);
99
+ } catch (error) {
100
+ console.log("[selectMode] symbolicate: fetch failed", {
101
+ isServer,
102
+ error
103
+ });
104
+ return frames.map(() => null);
105
+ }
106
+ }
107
+ async function symbolicateFrames(frames) {
108
+ const serverIndices = [];
109
+ const clientIndices = [];
110
+ for (const [index, frame] of frames.entries()) {
111
+ if (frame.file && isServerChunk(frame.file)) {
112
+ serverIndices.push(index);
113
+ } else {
114
+ clientIndices.push(index);
115
+ }
116
+ }
117
+ const [serverResults, clientResults] = await Promise.all([
118
+ postFrames({
119
+ frames: serverIndices.map((index) => frames[index]),
120
+ isServer: true
121
+ }),
122
+ postFrames({
123
+ frames: clientIndices.map((index) => frames[index]),
124
+ isServer: false
125
+ })
126
+ ]);
127
+ const merged = frames.map(() => null);
128
+ for (const [position, index] of serverIndices.entries()) {
129
+ merged[index] = serverResults[position] ?? null;
130
+ }
131
+ for (const [position, index] of clientIndices.entries()) {
132
+ merged[index] = clientResults[position] ?? null;
133
+ }
134
+ return merged;
135
+ }
136
+ function applyResolved({
137
+ original,
138
+ frame
139
+ }) {
140
+ if (!frame || !frame.file || isNullish(frame.line1)) {
141
+ return original;
142
+ }
143
+ return {
144
+ filePath: frame.file,
145
+ lineNumber: frame.line1,
146
+ columnNumber: frame.column1 ?? void 0,
147
+ componentName: original.componentName
148
+ };
149
+ }
150
+ function findUserSourceLocation(fiberChain) {
151
+ return fiberChain.find((entry) => {
152
+ return !isLikelyCompiledLocation(entry.sourceLocation) && !isDependencyOrInternalPath(entry.sourceLocation.filePath);
153
+ })?.sourceLocation;
154
+ }
155
+ async function symbolicateSelectedElement(selectedElement) {
156
+ const targets = [];
157
+ const fiberChain = selectedElement.fiberChain.map((entry) => ({ ...entry }));
158
+ for (const entry of fiberChain) {
159
+ if (isLikelyCompiledLocation(entry.sourceLocation)) {
160
+ targets.push({
161
+ location: entry.sourceLocation,
162
+ apply: (next) => {
163
+ entry.sourceLocation = next;
164
+ }
165
+ });
166
+ }
167
+ }
168
+ let sourceLocation = selectedElement.sourceLocation;
169
+ if (fiberChain.length === 0 && sourceLocation && isLikelyCompiledLocation(sourceLocation)) {
170
+ const captured = sourceLocation;
171
+ targets.push({
172
+ location: captured,
173
+ apply: (next) => {
174
+ sourceLocation = next;
175
+ }
176
+ });
177
+ }
178
+ if (targets.length === 0) {
179
+ return selectedElement;
180
+ }
181
+ const resolved = await symbolicateFrames(
182
+ targets.map((target) => toNextStackFrame(target.location))
183
+ );
184
+ for (const [index, target] of targets.entries()) {
185
+ const frame = extractResolvedFrame(resolved[index] ?? null);
186
+ target.apply(applyResolved({ original: target.location, frame }));
187
+ }
188
+ if (fiberChain.length > 0) {
189
+ sourceLocation = findUserSourceLocation(fiberChain) ?? fiberChain[0].sourceLocation;
190
+ }
191
+ return {
192
+ ...selectedElement,
193
+ sourceLocation,
194
+ fiberChain
195
+ };
196
+ }
197
+ export {
198
+ symbolicateSelectedElement
199
+ };
200
+ //# sourceMappingURL=symbolicate.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../select-mode/symbolicate.ts"],
4
+ "sourcesContent": ["import type {\n SelectedElement,\n SelectModeFiberChainEntry,\n SelectModeSourceLocation,\n} from \"schemas/generated/selectMode\";\n\nimport { isNullish } from \"replo-utils/lib/misc\";\n\n/**\n * Runtime source-attribution for React 19 + Next.js Turbopack.\n *\n * React 19 removed `fiber._debugSource`; the only per-element source pointer\n * left is `fiber._debugStack`, whose `.stack` references compiled SSR/client\n * chunks. We POST those compiled frames to Next.js's dev-only\n * `/__nextjs_original-stack-frames` endpoint, which symbolicates them through\n * Turbopack's in-memory source maps \u2014 the same mechanism the Next error\n * overlay uses (see `next/dist/server/dev/middleware-turbopack.js`).\n */\n\ntype NextStackFrame = {\n file: string | null;\n methodName: string | null;\n arguments: string[];\n // Next.js's `/__nextjs_original-stack-frames` reads these as `line1`/`column1`\n // (1-based) in the request body \u2014 same field names it uses in the response.\n // Sending `lineNumber`/`column` is silently dropped on the server side.\n line1: number | null;\n column1: number | null;\n};\n\ntype ResolvedFrame = {\n file: string | null;\n line1?: number | null;\n column1?: number | null;\n methodName?: string | null;\n ignored?: boolean;\n arguments?: string[];\n};\n\ntype OriginalStackFrameResponse = {\n originalStackFrame: ResolvedFrame | null;\n originalCodeFrame: string | null;\n};\n\ntype SettledResponseEntry =\n | { status: \"fulfilled\"; value: OriginalStackFrameResponse }\n | { status: \"rejected\"; reason: string };\n\nconst SYMBOLICATE_ENDPOINT = \"/__nextjs_original-stack-frames\";\n\nfunction isLikelyCompiledLocation(\n location: SelectModeSourceLocation | undefined,\n): boolean {\n if (!location) {\n return false;\n }\n const filePath = location.filePath;\n return (\n filePath.includes(\".next\") ||\n filePath.includes(\"/chunks/\") ||\n filePath.includes(\"webpack-internal:\") ||\n filePath.includes(\"turbopack:\") ||\n filePath.endsWith(\".js\") ||\n filePath.startsWith(\"about:\")\n );\n}\n\n// A resolved source that lives in a dependency or framework internal is never\n// the user's own code. The canonical case is Next's `<Image>`, whose rendered\n// `<img>` symbolicates to\n// `.../node_modules/next/src/client/image-component.tsx` \u2014 useless as an edit\n// target. We skip these and keep walking the ownership chain toward the user's\n// call site. See (Noah, 2026-07-09, REPL-29098).\nfunction isDependencyOrInternalPath(filePath: string): boolean {\n return (\n filePath.includes(\"node_modules\") ||\n filePath.includes(\"/dist/compiled/\") ||\n filePath.startsWith(\"about:\")\n );\n}\n\n// React 19 fibers for server-rendered (RSC) elements carry a `_debugStack`\n// whose top frame points at an SSR chunk (e.g. `about://React/Server/file://\n// .../.next-dev/.../server/chunks/ssr/*.js`). The endpoint resolves those\n// against the server bundler context; client chunks go through the client\n// bundler context. Mis-routing returns the compiled chunk unchanged.\nfunction isServerChunk(filePath: string): boolean {\n return (\n filePath.startsWith(\"about://React/Server\") ||\n filePath.includes(\"/server/chunks/\") ||\n filePath.includes(\".next-dev/dev/server/\") ||\n filePath.includes(\".next/server/\")\n );\n}\n\n// Matches the `/_next/static/...` tail of a browser chunk URL's pathname.\n// Capture group 1 is the `/static/...` segment that lives under the dist dir\n// on disk. Mirrors `regexNextStatic` in\n// `next/dist/server/lib/parse-stack.js`.\nconst NEXT_STATIC_PATH_PATTERN = /\\/_next(\\/static\\/.+)/;\n\n// Absolute path to the dev dist dir (e.g.\n// `/workspace/dev/website/.next-dev/dev`). Next.js define-injects this into\n// dev client bundles (see the `__NEXT_DIST_DIR` define in\n// `next/dist/build/define-env.ts`); because the sandbox runtime is transpiled into the\n// host Next app, the replacement reaches this reference too. Outside a Next\n// dev client build the value is absent, so we bail and leave the URL as-is.\nfunction getNextDistDir(): string | null {\n try {\n const distDir = process.env.__NEXT_DIST_DIR;\n return typeof distDir === \"string\" && distDir.length > 0 ? distDir : null;\n } catch {\n return null;\n }\n}\n\n// Turbopack's `/__nextjs_original-stack-frames` backend only resolves source\n// maps for `file://` (or bare filesystem) paths \u2014 it rejects browser chunk\n// URLs (`https://host/_next/static/chunks/X.js`) with \"Unknown url scheme\",\n// which is why client-component frames never symbolicated in the sandbox\n// (everything is served over https) even though it worked for RSC frames that\n// already carry filesystem paths. Rewrite the URL to the on-disk dist path the\n// same way Next's own server-side stack parser does, so the endpoint can map\n// it back to the user's `.tsx`.\nfunction rewriteBrowserChunkUrlToDistPath(filePath: string): string {\n if (!/^https?:\\/\\//.test(filePath)) {\n return filePath;\n }\n const distDir = getNextDistDir();\n if (!distDir) {\n return filePath;\n }\n let url: URL;\n try {\n url = new URL(filePath);\n } catch {\n return filePath;\n }\n const staticPathMatch = NEXT_STATIC_PATH_PATTERN.exec(url.pathname);\n if (!staticPathMatch?.[1]) {\n return filePath;\n }\n const normalizedDistDir = distDir.replace(/\\\\/g, \"/\").replace(/\\/$/, \"\");\n return `file://${normalizedDistDir}${staticPathMatch[1]}${url.search}`;\n}\n\n// React 19's `_debugStack.stack` for RSC components wraps the SSR chunk URL\n// in an `about://React/Server/` prefix and appends a `?<digits>` cache-buster\n// (e.g. `about://React/Server/file:///.../[root-of-the-server]__abc._.js?21`).\n// Turbopack's source-map lookup matches against the bare chunk URL; with\n// either decoration in place it returns the compiled chunk unchanged. Client\n// components instead carry a plain browser chunk URL, which Turbopack rejects\n// outright unless rewritten to its on-disk `file://` path.\nfunction normalizeFilePathForSymbolicator(filePath: string): string {\n let normalized = filePath;\n if (normalized.startsWith(\"about://React/Server/\")) {\n normalized = normalized.slice(\"about://React/Server/\".length);\n }\n normalized = normalized.replace(/\\?\\d+$/, \"\");\n return rewriteBrowserChunkUrlToDistPath(normalized);\n}\n\nfunction toNextStackFrame(location: SelectModeSourceLocation): NextStackFrame {\n return {\n file: normalizeFilePathForSymbolicator(location.filePath),\n methodName: location.componentName ?? null,\n arguments: [],\n line1: location.lineNumber,\n column1: location.columnNumber ?? null,\n };\n}\n\nfunction extractResolvedFrame(\n entry: SettledResponseEntry | null,\n): ResolvedFrame | null {\n if (!entry || entry.status !== \"fulfilled\") {\n return null;\n }\n return entry.value?.originalStackFrame ?? null;\n}\n\nasync function postFrames({\n frames,\n isServer,\n}: {\n frames: NextStackFrame[];\n isServer: boolean;\n}): Promise<(SettledResponseEntry | null)[]> {\n if (frames.length === 0) {\n return [];\n }\n try {\n const response = await fetch(SYMBOLICATE_ENDPOINT, {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({\n frames,\n isServer,\n isEdgeServer: false,\n isAppDirectory: true,\n }),\n });\n if (!response.ok) {\n console.log(\"[selectMode] symbolicate: endpoint returned non-OK status\", {\n status: response.status,\n isServer,\n });\n return frames.map(() => null);\n }\n const parsed: unknown = await response.json();\n if (Array.isArray(parsed)) {\n // Promise.allSettled-shaped entries; see\n // node_modules/next/dist/server/dev/middleware-turbopack.js.\n // Legacy cast - the runtime shape isn't exported as a type.\n // eslint-disable-next-line replo/no-as-cast\n return parsed as (SettledResponseEntry | null)[];\n }\n return frames.map(() => null);\n } catch (error) {\n console.log(\"[selectMode] symbolicate: fetch failed\", {\n isServer,\n error,\n });\n return frames.map(() => null);\n }\n}\n\nasync function symbolicateFrames(\n frames: NextStackFrame[],\n): Promise<(SettledResponseEntry | null)[]> {\n const serverIndices: number[] = [];\n const clientIndices: number[] = [];\n for (const [index, frame] of frames.entries()) {\n if (frame.file && isServerChunk(frame.file)) {\n serverIndices.push(index);\n } else {\n clientIndices.push(index);\n }\n }\n\n const [serverResults, clientResults] = await Promise.all([\n postFrames({\n frames: serverIndices.map((index) => frames[index]!),\n isServer: true,\n }),\n postFrames({\n frames: clientIndices.map((index) => frames[index]!),\n isServer: false,\n }),\n ]);\n\n const merged: (SettledResponseEntry | null)[] = frames.map(() => null);\n for (const [position, index] of serverIndices.entries()) {\n merged[index] = serverResults[position] ?? null;\n }\n for (const [position, index] of clientIndices.entries()) {\n merged[index] = clientResults[position] ?? null;\n }\n return merged;\n}\n\nfunction applyResolved({\n original,\n frame,\n}: {\n original: SelectModeSourceLocation;\n frame: ResolvedFrame | null;\n}): SelectModeSourceLocation {\n if (!frame || !frame.file || isNullish(frame.line1)) {\n return original;\n }\n return {\n filePath: frame.file,\n lineNumber: frame.line1,\n columnNumber: frame.column1 ?? undefined,\n componentName: original.componentName,\n };\n}\n\n// The innermost chain entry that is a usable edit target: already-symbolicated\n// (still-compiled frames failed to resolve and are useless) and outside\n// dependency/framework code. See (Noah, 2026-07-09, REPL-29098).\nfunction findUserSourceLocation(\n fiberChain: SelectModeFiberChainEntry[],\n): SelectModeSourceLocation | undefined {\n return fiberChain.find((entry) => {\n return (\n !isLikelyCompiledLocation(entry.sourceLocation) &&\n !isDependencyOrInternalPath(entry.sourceLocation.filePath)\n );\n })?.sourceLocation;\n}\n\nexport async function symbolicateSelectedElement(\n selectedElement: SelectedElement,\n): Promise<SelectedElement> {\n const targets: {\n location: SelectModeSourceLocation;\n apply: (next: SelectModeSourceLocation) => void;\n }[] = [];\n\n const fiberChain: SelectModeFiberChainEntry[] =\n selectedElement.fiberChain.map((entry) => ({ ...entry }));\n for (const entry of fiberChain) {\n if (isLikelyCompiledLocation(entry.sourceLocation)) {\n targets.push({\n location: entry.sourceLocation,\n apply: (next) => {\n entry.sourceLocation = next;\n },\n });\n }\n }\n\n let sourceLocation = selectedElement.sourceLocation;\n // With a chain present `sourceLocation` is re-derived from it below, so\n // targeting it here would just duplicate the chain head's round trip.\n if (\n fiberChain.length === 0 &&\n sourceLocation &&\n isLikelyCompiledLocation(sourceLocation)\n ) {\n const captured = sourceLocation;\n targets.push({\n location: captured,\n apply: (next) => {\n sourceLocation = next;\n },\n });\n }\n\n if (targets.length === 0) {\n return selectedElement;\n }\n\n const resolved = await symbolicateFrames(\n targets.map((target) => toNextStackFrame(target.location)),\n );\n\n for (const [index, target] of targets.entries()) {\n const frame = extractResolvedFrame(resolved[index] ?? null);\n target.apply(applyResolved({ original: target.location, frame }));\n }\n\n if (fiberChain.length > 0) {\n // Fall back to the chain head so we never regress to attributing nothing.\n sourceLocation =\n findUserSourceLocation(fiberChain) ?? fiberChain[0]!.sourceLocation;\n }\n\n return {\n ...selectedElement,\n sourceLocation,\n fiberChain,\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,23 @@
1
+ import type { JSONContent } from "@tiptap/core";
2
+ import type { SelectModeFormatCommand } from "../_vendor/schemas/generated/selectMode";
3
+ export type InlineTiptapEditor = {
4
+ focus: () => void;
5
+ focusAndSelectAll: () => void;
6
+ destroy: () => void;
7
+ getHTML: () => string;
8
+ getJSON: () => JSONContent;
9
+ runFormatCommand: (command: SelectModeFormatCommand) => void;
10
+ };
11
+ export declare function createInlineTiptapEditor({ element, content, onCommit, onEscape, onBlur, onSelectionUpdate, }: {
12
+ element: HTMLElement;
13
+ content: string;
14
+ onCommit: () => void;
15
+ onEscape: () => void;
16
+ onBlur: () => void;
17
+ onSelectionUpdate: (activeMarks: {
18
+ bold: boolean;
19
+ italic: boolean;
20
+ underline: boolean;
21
+ strike: boolean;
22
+ }) => void;
23
+ }): InlineTiptapEditor;
@@ -0,0 +1,120 @@
1
+ import { Editor, Mark } from "@tiptap/core";
2
+ import Bold from "@tiptap/extension-bold";
3
+ import Document from "@tiptap/extension-document";
4
+ import Italic from "@tiptap/extension-italic";
5
+ import Strike from "@tiptap/extension-strike";
6
+ import Text from "@tiptap/extension-text";
7
+ import Underline from "@tiptap/extension-underline";
8
+ const InlineDocument = Document.extend({
9
+ content: "inline*"
10
+ });
11
+ const InlineLink = Mark.create({
12
+ name: "link",
13
+ inclusive: false,
14
+ addAttributes() {
15
+ return {
16
+ class: { default: null },
17
+ href: { default: null },
18
+ rel: { default: null },
19
+ target: { default: null }
20
+ };
21
+ },
22
+ parseHTML() {
23
+ return [{ tag: "a[href]" }];
24
+ },
25
+ renderHTML({ HTMLAttributes }) {
26
+ return ["a", HTMLAttributes, 0];
27
+ }
28
+ });
29
+ function createInlineTiptapEditor({
30
+ element,
31
+ content,
32
+ onCommit,
33
+ onEscape,
34
+ onBlur,
35
+ onSelectionUpdate
36
+ }) {
37
+ const originalAttributes = Array.from(
38
+ element.attributes,
39
+ ({ name, value }) => ({
40
+ name,
41
+ value
42
+ })
43
+ );
44
+ element.replaceChildren();
45
+ const mount = {
46
+ mount: element
47
+ };
48
+ const editor = new Editor({
49
+ element: mount,
50
+ content,
51
+ extensions: [
52
+ InlineDocument,
53
+ Text,
54
+ Bold,
55
+ Italic,
56
+ Underline,
57
+ Strike,
58
+ InlineLink
59
+ ],
60
+ editorProps: {
61
+ // Drop the browser's default focus ring on the contenteditable — the
62
+ // select-mode selection frame already indicates the edit target.
63
+ attributes: { style: "outline: none;" },
64
+ handleKeyDown: (_view, event) => {
65
+ if (event.key === "Enter" && (event.shiftKey || event.metaKey || event.ctrlKey)) {
66
+ event.preventDefault();
67
+ onCommit();
68
+ return true;
69
+ }
70
+ if (event.key === "Escape") {
71
+ event.preventDefault();
72
+ onEscape();
73
+ return true;
74
+ }
75
+ return false;
76
+ }
77
+ },
78
+ onSelectionUpdate: ({ editor: activeEditor }) => {
79
+ onSelectionUpdate({
80
+ bold: activeEditor.isActive("bold"),
81
+ italic: activeEditor.isActive("italic"),
82
+ underline: activeEditor.isActive("underline"),
83
+ strike: activeEditor.isActive("strike")
84
+ });
85
+ },
86
+ onBlur: () => {
87
+ onBlur();
88
+ }
89
+ });
90
+ return {
91
+ focus: () => editor.commands.focus(),
92
+ // Focus the editor with the full text block selected so the user can type
93
+ // to replace it immediately (or arrow/click to drop the selection).
94
+ focusAndSelectAll: () => editor.chain().focus().selectAll().run(),
95
+ destroy: () => {
96
+ editor.destroy();
97
+ for (const attribute of Array.from(element.attributes)) {
98
+ element.removeAttribute(attribute.name);
99
+ }
100
+ for (const { name, value } of originalAttributes) {
101
+ element.setAttribute(name, value);
102
+ }
103
+ },
104
+ getHTML: () => editor.getHTML(),
105
+ getJSON: () => editor.getJSON(),
106
+ runFormatCommand: (command) => {
107
+ const commandRunners = {
108
+ toggleBold: () => editor.chain().focus().toggleBold().run(),
109
+ toggleItalic: () => editor.chain().focus().toggleItalic().run(),
110
+ toggleUnderline: () => editor.chain().focus().toggleUnderline().run(),
111
+ toggleStrike: () => editor.chain().focus().toggleStrike().run()
112
+ };
113
+ commandRunners[command]();
114
+ }
115
+ };
116
+ }
117
+ export {
118
+ createInlineTiptapEditor
119
+ };
120
+ //# sourceMappingURL=tiptapInlineEditor.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../select-mode/tiptapInlineEditor.ts"],
4
+ "sourcesContent": ["import type { JSONContent } from \"@tiptap/core\";\nimport type { SelectModeFormatCommand } from \"schemas/generated/selectMode\";\n\nimport { Editor, Mark } from \"@tiptap/core\";\nimport Bold from \"@tiptap/extension-bold\";\nimport Document from \"@tiptap/extension-document\";\nimport Italic from \"@tiptap/extension-italic\";\nimport Strike from \"@tiptap/extension-strike\";\nimport Text from \"@tiptap/extension-text\";\nimport Underline from \"@tiptap/extension-underline\";\n\nconst InlineDocument = Document.extend({\n content: \"inline*\",\n});\n\nconst InlineLink = Mark.create({\n name: \"link\",\n inclusive: false,\n addAttributes() {\n return {\n class: { default: null },\n href: { default: null },\n rel: { default: null },\n target: { default: null },\n };\n },\n parseHTML() {\n return [{ tag: \"a[href]\" }];\n },\n renderHTML({ HTMLAttributes }) {\n return [\"a\", HTMLAttributes, 0];\n },\n});\n\nexport type InlineTiptapEditor = {\n focus: () => void;\n focusAndSelectAll: () => void;\n destroy: () => void;\n getHTML: () => string;\n getJSON: () => JSONContent;\n runFormatCommand: (command: SelectModeFormatCommand) => void;\n};\n\nexport function createInlineTiptapEditor({\n element,\n content,\n onCommit,\n onEscape,\n onBlur,\n onSelectionUpdate,\n}: {\n element: HTMLElement;\n content: string;\n onCommit: () => void;\n onEscape: () => void;\n onBlur: () => void;\n onSelectionUpdate: (activeMarks: {\n bold: boolean;\n italic: boolean;\n underline: boolean;\n strike: boolean;\n }) => void;\n}): InlineTiptapEditor {\n const originalAttributes = Array.from(\n element.attributes,\n ({ name, value }) => ({\n name,\n value,\n }),\n );\n // ProseMirror *appends* its contenteditable to the mount node rather than\n // replacing it, so the element's original text node would survive as a\n // sibling and render a duplicate copy. The editor's initial content comes\n // from the `content` option below (not the element's DOM), and the caller\n // keeps the original HTML for revert, so emptying the node here is safe.\n element.replaceChildren();\n const mount = {\n mount: element,\n } as unknown as Element; /* eslint-disable-line replo/no-as-cast -- NOTE (Noah Gilmore, 2026-07-16): ProseMirror accepts this documented direct-mount shape at runtime, but Tiptap v2's Editor option incorrectly narrows it to Element. */\n const editor = new Editor({\n element: mount,\n content,\n extensions: [\n InlineDocument,\n Text,\n Bold,\n Italic,\n Underline,\n Strike,\n InlineLink,\n ],\n editorProps: {\n // Drop the browser's default focus ring on the contenteditable \u2014 the\n // select-mode selection frame already indicates the edit target.\n attributes: { style: \"outline: none;\" },\n handleKeyDown: (_view, event) => {\n // Commit on Shift-Enter or Cmd/Ctrl-Enter; a bare Enter inserts a line\n // break as usual.\n if (\n event.key === \"Enter\" &&\n (event.shiftKey || event.metaKey || event.ctrlKey)\n ) {\n event.preventDefault();\n onCommit();\n return true;\n }\n if (event.key === \"Escape\") {\n event.preventDefault();\n onEscape();\n return true;\n }\n return false;\n },\n },\n onSelectionUpdate: ({ editor: activeEditor }) => {\n onSelectionUpdate({\n bold: activeEditor.isActive(\"bold\"),\n italic: activeEditor.isActive(\"italic\"),\n underline: activeEditor.isActive(\"underline\"),\n strike: activeEditor.isActive(\"strike\"),\n });\n },\n onBlur: () => {\n onBlur();\n },\n });\n\n return {\n focus: () => editor.commands.focus(),\n // Focus the editor with the full text block selected so the user can type\n // to replace it immediately (or arrow/click to drop the selection).\n focusAndSelectAll: () => editor.chain().focus().selectAll().run(),\n destroy: () => {\n editor.destroy();\n for (const attribute of Array.from(element.attributes)) {\n element.removeAttribute(attribute.name);\n }\n for (const { name, value } of originalAttributes) {\n element.setAttribute(name, value);\n }\n },\n getHTML: () => editor.getHTML(),\n getJSON: () => editor.getJSON(),\n runFormatCommand: (command) => {\n const commandRunners: Record<SelectModeFormatCommand, () => void> = {\n toggleBold: () => editor.chain().focus().toggleBold().run(),\n toggleItalic: () => editor.chain().focus().toggleItalic().run(),\n toggleUnderline: () => editor.chain().focus().toggleUnderline().run(),\n toggleStrike: () => editor.chain().focus().toggleStrike().run(),\n };\n commandRunners[command]();\n },\n };\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }