camox 0.44.0 → 0.46.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 (407) hide show
  1. package/dist/components/AuthGate.js +0 -6
  2. package/dist/components/DeviceSelector.js +96 -0
  3. package/dist/components/PlatformLabel.js +20 -24
  4. package/dist/core/components/lexical/HighlightNode.js +1 -1
  5. package/dist/core/components/lexical/InlineContentEditable.js +15 -19
  6. package/dist/core/components/lexical/InlineLexicalEditor.js +54 -74
  7. package/dist/core/components/lexical/InlineStylesPlugin.js +53 -53
  8. package/dist/core/components/lexical/MaxLengthPlugin.js +59 -0
  9. package/dist/core/components/lexical/SelectionBroadcaster.js +53 -54
  10. package/dist/core/components/lexical/SidebarLexicalEditor.js +322 -229
  11. package/dist/core/components/lexical/SummaryToggleGuard.js +42 -0
  12. package/dist/core/components/lexical/TextLinkPopover.js +169 -180
  13. package/dist/core/createApp.d.ts +241 -312
  14. package/dist/core/createApp.js +123 -29
  15. package/dist/core/createBlock.d.ts +5 -5
  16. package/dist/core/createBlock.js +385 -152
  17. package/dist/core/createCollection.d.ts +55 -0
  18. package/dist/core/createCollection.js +93 -0
  19. package/dist/core/createLayout.d.ts +197 -61
  20. package/dist/core/createLayout.js +114 -56
  21. package/dist/core/defineDocument.d.ts +3 -5
  22. package/dist/core/derivedRoutes.js +49 -1
  23. package/dist/core/dom.d.ts +13 -4
  24. package/dist/core/dom.js +44 -1
  25. package/dist/core/editing/BlockEditingRuntime.d.ts +16 -0
  26. package/dist/core/editing/BlockEditingRuntime.js +6 -15
  27. package/dist/core/editing/CompleteBlockEditingRuntime.js +28 -23
  28. package/dist/core/editing/createEditableBlock.d.ts +754 -633
  29. package/dist/core/editing/createEditableBlock.js +2113 -1066
  30. package/dist/core/editing/referenceWrites.js +51 -0
  31. package/dist/core/editing/useLatestRecord.js +90 -0
  32. package/dist/core/hooks/useArtifactHost.js +139 -0
  33. package/dist/core/hooks/useFieldSelection.js +43 -18
  34. package/dist/core/hooks/useIsEditable.js +12 -10
  35. package/dist/core/hooks/useOverlayMessage.js +15 -19
  36. package/dist/core/lib/artifact.d.ts +21 -0
  37. package/dist/core/lib/artifact.js +154 -0
  38. package/dist/core/lib/artifactColors.js +123 -0
  39. package/dist/core/lib/artifactData.d.ts +1 -0
  40. package/dist/core/lib/artifactData.js +131 -0
  41. package/dist/core/lib/artifactHost.js +205 -0
  42. package/dist/core/lib/artifactRuntime.js +36 -0
  43. package/dist/core/lib/artifactTheme.js +57 -0
  44. package/dist/core/lib/contentType.d.ts +302 -106
  45. package/dist/core/lib/contentType.js +201 -173
  46. package/dist/core/lib/fieldTypes.js +3 -0
  47. package/dist/core/lib/iconTypes.d.ts +3 -3
  48. package/dist/core/lib/icons.d.ts +4 -4
  49. package/dist/core/lib/icons.js +40 -44
  50. package/dist/core/lib/imagePlaceholder.js +177 -0
  51. package/dist/core/lib/imageTransform.js +1 -1
  52. package/dist/core/lib/lexicalReact.d.ts +3 -1
  53. package/dist/core/lib/lexicalState.js +1 -1
  54. package/dist/core/lib/previewPaused.js +9 -0
  55. package/dist/core/lib/recordScope.js +316 -0
  56. package/dist/core/lib/reference.d.ts +81 -0
  57. package/dist/core/lib/reference.js +29 -0
  58. package/dist/core/lib/textLinks.js +7 -5
  59. package/dist/core/lib/textStyles.d.ts +5 -7
  60. package/dist/core/lib/textStyles.js +2 -2
  61. package/dist/core/notFound.d.ts +7 -0
  62. package/dist/core/notFound.js +11 -0
  63. package/dist/core/pageDestinations.js +6 -3
  64. package/dist/core/recordItem.js +34 -0
  65. package/dist/core/requestContext.d.ts +26 -0
  66. package/dist/core/requestContext.js +20 -0
  67. package/dist/features/canvas/CamoxCanvas.js +1401 -0
  68. package/dist/features/canvas/CanvasLoadingScreen.js +35 -0
  69. package/dist/features/canvas/CanvasOverlays.js +254 -0
  70. package/dist/features/canvas/CanvasPageEdge.js +87 -0
  71. package/dist/features/canvas/CanvasPageFrame.js +333 -0
  72. package/dist/features/canvas/CanvasPageHeader.js +125 -0
  73. package/dist/features/canvas/CanvasPreviewPageSlot.js +123 -0
  74. package/dist/features/canvas/DerivedPagePathInput.js +238 -0
  75. package/dist/features/canvas/canvasCamera.js +229 -0
  76. package/dist/features/canvas/canvasFlight.js +104 -0
  77. package/dist/features/canvas/canvasFrameCapture.js +364 -0
  78. package/dist/features/canvas/canvasFrameDocument.js +302 -0
  79. package/dist/features/canvas/canvasFrameMode.js +53 -0
  80. package/dist/features/canvas/canvasInsertionSeams.js +44 -0
  81. package/dist/features/canvas/canvasItems.js +30 -0
  82. package/dist/features/canvas/canvasOverlayGeometry.js +240 -0
  83. package/dist/features/canvas/canvasPages.js +79 -0
  84. package/dist/features/canvas/canvasScreenSpace.js +26 -0
  85. package/dist/features/canvas/canvasSelection.js +18 -0
  86. package/dist/features/canvas/canvasStore.js +60 -0
  87. package/dist/features/canvas/canvasThumbnails.js +304 -0
  88. package/dist/features/canvas/canvasZoom.js +10 -0
  89. package/dist/features/canvas/sidebar/CanvasInspector.js +202 -0
  90. package/dist/features/canvas/sidebar/CanvasNavigator.js +124 -0
  91. package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -0
  92. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +48 -0
  93. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +39 -0
  94. package/dist/features/canvas/sidebar/CuratedPageInspector.js +69 -0
  95. package/dist/features/canvas/sidebar/DerivedPageInspector.js +37 -0
  96. package/dist/features/canvas/sidebar/LayoutPageBlocks.js +78 -0
  97. package/dist/features/canvas/sidebar/LayoutPageOverview.js +71 -0
  98. package/dist/features/canvas/sidebar/PageInspector.js +157 -0
  99. package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +90 -0
  100. package/dist/features/canvas/sidebar/PageOverview.js +27 -0
  101. package/dist/features/canvas/sidebar/SingletonPageInspector.js +31 -0
  102. package/dist/features/canvas/useCanvasCamera.js +783 -0
  103. package/dist/features/canvas/useCanvasFrame.js +148 -0
  104. package/dist/features/canvas/useCanvasFrameInput.js +97 -0
  105. package/dist/features/canvas/useCanvasNearness.js +57 -0
  106. package/dist/features/canvas/useDiscoveredPreviewPaths.js +62 -0
  107. package/dist/features/content/CamoxContent.d.ts +2 -5
  108. package/dist/features/content/CamoxContent.js +174 -271
  109. package/dist/features/content/CollectionItemSheetContext.js +106 -0
  110. package/dist/features/content/ContentAssets.js +315 -0
  111. package/dist/features/content/ContentCollection.js +663 -0
  112. package/dist/features/content/collection-form.js +58 -0
  113. package/dist/features/content/components/AssetCard.js +80 -84
  114. package/dist/features/content/components/AssetCardSkeleton.js +4 -8
  115. package/dist/features/content/components/ContentSidebar.js +129 -18
  116. package/dist/features/content/components/ContentSidebarGroup.js +37 -0
  117. package/dist/features/content/components/DeleteCollectionItemButton.js +202 -0
  118. package/dist/features/content/components/MissingFromLocale.js +282 -0
  119. package/dist/features/content/components/UploadDropZone.js +27 -31
  120. package/dist/features/content/components/UploadProgressDrawer.js +90 -98
  121. package/dist/features/navigation/navigation.d.ts +66 -20
  122. package/dist/features/navigation/navigation.js +257 -90
  123. package/dist/features/og/defaultFonts.js +8 -8
  124. package/dist/features/og/geist-variable-ttf-base64.js +1 -1
  125. package/dist/features/og/imageResponse.d.ts +8 -0
  126. package/dist/features/og/imageResponse.js +26 -0
  127. package/dist/features/page/CuratedPageContent.js +167 -0
  128. package/dist/features/page/DerivedPageContent.js +26 -30
  129. package/dist/features/page/SharedLayoutContent.js +25 -27
  130. package/dist/features/preview/CamoxPreview.d.ts +23 -61
  131. package/dist/features/preview/CamoxPreview.js +816 -537
  132. package/dist/features/preview/EditablePageContent.js +1 -1
  133. package/dist/features/preview/EditablePageExperience.js +16 -22
  134. package/dist/features/preview/components/AddBlockSheet.js +273 -0
  135. package/dist/features/preview/components/AssetFieldEditor.js +173 -154
  136. package/dist/features/preview/components/AssetLightbox.js +181 -134
  137. package/dist/features/preview/components/AssetPickerModal.js +153 -170
  138. package/dist/features/preview/components/BlockActionsPopover.js +150 -149
  139. package/dist/features/preview/components/BlockErrorBoundary.js +8 -12
  140. package/dist/features/preview/components/BlockThumbnail.js +172 -98
  141. package/dist/features/preview/components/CanvasPreview.js +243 -0
  142. package/dist/features/preview/components/CreatePageModal.js +128 -137
  143. package/dist/features/preview/components/DebouncedFieldEditor.js +29 -33
  144. package/dist/features/preview/components/DerivedLayoutDialog.js +21 -19
  145. package/dist/features/preview/components/DrillRow.js +150 -0
  146. package/dist/features/preview/components/FieldOverlayStyles.js +11 -8
  147. package/dist/features/preview/components/FieldToolbar.js +160 -110
  148. package/dist/features/preview/components/Frame.js +108 -20
  149. package/dist/features/preview/components/IconFieldEditor.js +62 -66
  150. package/dist/features/preview/components/ItemFieldsEditor.js +231 -205
  151. package/dist/features/preview/components/LinkFieldEditor.js +135 -139
  152. package/dist/features/preview/components/Metadata.js +22 -30
  153. package/dist/features/preview/components/MobilePreviewDrawer.js +89 -108
  154. package/dist/features/preview/components/MultipleAssetFieldEditor.js +334 -246
  155. package/dist/features/preview/components/OverlayTracker.js +9 -41
  156. package/dist/features/preview/components/Overlays.js +81 -69
  157. package/dist/features/preview/components/PageInfo.js +1748 -0
  158. package/dist/features/preview/components/PageInfoSkeleton.js +51 -0
  159. package/dist/features/preview/components/PageLocationFieldset.js +112 -116
  160. package/dist/features/preview/components/PageNavigatorHeader.js +24 -0
  161. package/dist/features/preview/components/PageNicknameField.js +22 -26
  162. package/dist/features/preview/components/PagePicker.js +128 -130
  163. package/dist/features/preview/components/PageTree.js +525 -532
  164. package/dist/features/preview/components/PreviewActivation.js +28 -32
  165. package/dist/features/preview/components/PreviewPanel.js +620 -319
  166. package/dist/features/preview/components/PreviewToolbar.js +105 -333
  167. package/dist/features/preview/components/RecordCard.js +80 -0
  168. package/dist/features/preview/components/RecordCombobox.js +178 -0
  169. package/dist/features/preview/components/ReferenceFieldEditor.js +149 -0
  170. package/dist/features/preview/components/ReferenceListFieldEditor.js +432 -0
  171. package/dist/features/preview/components/RemovedBlockPlaceholder.js +95 -0
  172. package/dist/features/preview/components/RepeatableItemsList.js +125 -138
  173. package/dist/features/preview/components/SelectionEditor.js +993 -0
  174. package/dist/features/preview/components/ShikiMarkdown.js +14 -18
  175. package/dist/features/preview/components/SidebarSection.js +52 -64
  176. package/dist/features/preview/components/StudioEditingFallback.js +56 -0
  177. package/dist/features/preview/components/UnlinkAssetButton.js +104 -107
  178. package/dist/features/preview/components/blockGridNavigation.js +15 -0
  179. package/dist/features/preview/components/contentFieldSchema.js +8 -0
  180. package/dist/features/preview/components/useFieldWriter.js +200 -0
  181. package/dist/features/preview/components/useRecordView.js +383 -0
  182. package/dist/features/preview/components/useRepeatableItemActions.js +35 -37
  183. package/dist/features/preview/components/useUpdateBlockPosition.js +37 -37
  184. package/dist/features/preview/editingFrame.js +197 -0
  185. package/dist/features/preview/overlayHighlights.js +17 -44
  186. package/dist/features/preview/overlayMessages.js +72 -1
  187. package/dist/features/preview/pageRecord.js +189 -0
  188. package/dist/features/preview/previewConstants.js +6 -2
  189. package/dist/features/preview/previewPageFrame.js +95 -0
  190. package/dist/features/preview/previewPreparation.js +7 -0
  191. package/dist/features/preview/previewSelection.js +32 -63
  192. package/dist/features/preview/previewStore.js +225 -123
  193. package/dist/features/preview/referencePickerFocus.js +29 -0
  194. package/dist/features/preview/repeatableItemTargets.js +56 -0
  195. package/dist/features/preview/selectionReveal.js +21 -0
  196. package/dist/features/preview/usePreviewViewportActions.js +114 -0
  197. package/dist/features/preview/viewportContinuity.js +109 -0
  198. package/dist/features/provider/AuthenticatedCamoxProvider.js +69 -44
  199. package/dist/features/provider/CamoxProvider.d.ts +3 -6
  200. package/dist/features/provider/CamoxProvider.js +38 -50
  201. package/dist/features/provider/CoreCamoxProvider.js +69 -50
  202. package/dist/features/provider/LocalhostPreviewProvider.js +78 -114
  203. package/dist/features/provider/PreviewSignInPage.js +54 -0
  204. package/dist/features/provider/components/CamoxAppContext.js +11 -11
  205. package/dist/features/provider/components/CommandPalette.js +75 -82
  206. package/dist/features/provider/useAdminShortcuts.js +7 -11
  207. package/dist/features/routes/pageRuntime.d.ts +44 -4
  208. package/dist/features/routes/pageRuntime.js +244 -137
  209. package/dist/features/runtime/RuntimeChrome.js +117 -115
  210. package/dist/features/runtime/alternates.js +64 -0
  211. package/dist/features/runtime/analytics.d.ts +7 -0
  212. package/dist/features/runtime/analytics.js +66 -0
  213. package/dist/features/runtime/artifactSources.js +87 -0
  214. package/dist/features/runtime/editingFallback.js +20 -0
  215. package/dist/features/runtime/linkPrefetch.js +97 -0
  216. package/dist/features/runtime/livePages.js +62 -0
  217. package/dist/features/runtime/llmsTxt.js +40 -0
  218. package/dist/features/runtime/loopbackFetch.js +18 -0
  219. package/dist/features/runtime/navigationAccessibility.js +51 -0
  220. package/dist/features/runtime/navigationTarget.js +23 -2
  221. package/dist/features/runtime/pageApp.js +229 -158
  222. package/dist/features/runtime/pageBlockTypes.js +20 -0
  223. package/dist/features/runtime/pageClient.d.ts +2 -4
  224. package/dist/features/runtime/pageClient.js +18 -3
  225. package/dist/features/runtime/pageNavigation.js +254 -32
  226. package/dist/features/runtime/pageServer.d.ts +2 -4
  227. package/dist/features/runtime/pageServer.js +6 -2
  228. package/dist/features/runtime/pageViewport.js +7 -0
  229. package/dist/features/runtime/runtime.d.ts +54 -24
  230. package/dist/features/runtime/runtime.js +766 -191
  231. package/dist/features/runtime/runtimeChromeLoader.js +58 -0
  232. package/dist/features/runtime/runtimeRoutes.d.ts +19 -0
  233. package/dist/features/runtime/runtimeRoutes.js +25 -0
  234. package/dist/features/runtime/scrollRestoration.js +133 -0
  235. package/dist/features/runtime/studioApp.d.ts +4 -3
  236. package/dist/features/runtime/studioApp.js +5 -9
  237. package/dist/features/runtime/studioClient.d.ts +2 -4
  238. package/dist/features/runtime/studioClient.js +12 -3
  239. package/dist/features/runtime/studioServer.d.ts +2 -4
  240. package/dist/features/runtime/studioServer.js +6 -1
  241. package/dist/features/runtime/worker.d.ts +6 -0
  242. package/dist/features/runtime/worker.js +23 -0
  243. package/dist/features/runtime/workerRequest.js +44 -0
  244. package/dist/features/studio/CamoxStudio.d.ts +2 -6
  245. package/dist/features/studio/CamoxStudio.js +34 -49
  246. package/dist/features/studio/FollowAgentProvider.js +327 -0
  247. package/dist/features/studio/components/ChatSidebar.js +356 -0
  248. package/dist/features/studio/components/DraftsControl.js +676 -0
  249. package/dist/features/studio/components/FaviconDialog.js +318 -0
  250. package/dist/features/studio/components/LocalePicker.js +785 -0
  251. package/dist/features/studio/components/Navbar.js +123 -103
  252. package/dist/features/studio/components/ProjectMenu.js +239 -260
  253. package/dist/features/studio/components/RenameDraftDialog.js +206 -0
  254. package/dist/features/studio/components/ReviewDraftSheet.js +1472 -0
  255. package/dist/features/studio/components/ThreadComposer.js +157 -0
  256. package/dist/features/studio/components/ThreadMarkdown.js +113 -0
  257. package/dist/features/studio/components/ThreadMessages.js +270 -0
  258. package/dist/features/studio/components/UserButton.js +34 -23
  259. package/dist/features/studio/draftLabel.js +33 -0
  260. package/dist/features/studio/draftNotice.js +13 -0
  261. package/dist/features/studio/followAgent.js +241 -0
  262. package/dist/features/studio/followAgentContext.js +7 -0
  263. package/dist/features/studio/localeOptions.js +118 -0
  264. package/dist/features/studio/localeSwitch.js +19 -0
  265. package/dist/features/studio/routes.js +26 -1
  266. package/dist/features/studio/studioStore.js +64 -1
  267. package/dist/features/studio/useTheme.js +24 -27
  268. package/dist/features/vite/artifactRuntimeMinification.js +36 -0
  269. package/dist/features/vite/blockBoilerplate.js +6 -5
  270. package/dist/features/vite/blockChunks.js +31 -0
  271. package/dist/features/vite/bundlerLogs.js +17 -0
  272. package/dist/features/vite/definitionsSync.js +158 -226
  273. package/dist/features/vite/devAuthentication.js +4 -16
  274. package/dist/features/vite/devSignIn.js +87 -0
  275. package/dist/features/vite/iconGeneration.js +1 -1
  276. package/dist/features/vite/layoutGeneration.js +11 -1
  277. package/dist/features/vite/publishSeededContent.js +30 -0
  278. package/dist/features/vite/routeGeneration.js +6 -7
  279. package/dist/features/vite/runtimeDev.js +80 -99
  280. package/dist/features/vite/vite.d.ts +51 -31
  281. package/dist/features/vite/vite.js +224 -127
  282. package/dist/features/vite/workerBuild.js +39 -0
  283. package/dist/hooks/use-debounced-field.js +116 -47
  284. package/dist/hooks/use-file-upload.js +114 -67
  285. package/dist/hooks/use-marquee-selection.js +32 -36
  286. package/dist/hooks/use-page-destinations.js +69 -37
  287. package/dist/lib/api-client-server.d.ts +5 -0
  288. package/dist/lib/api-client-server.js +10 -4
  289. package/dist/lib/api-client.d.ts +6 -0
  290. package/dist/lib/api-client.js +51 -16
  291. package/dist/lib/api-socket.js +17 -0
  292. package/dist/lib/auth-page-styles.js +39 -0
  293. package/dist/lib/auth.js +129 -61
  294. package/dist/lib/collection-cache.js +23 -0
  295. package/dist/lib/draft-scope.d.ts +4 -0
  296. package/dist/lib/draft-scope.js +222 -0
  297. package/dist/lib/html.js +12 -0
  298. package/dist/lib/link-pages.js +154 -0
  299. package/dist/lib/locale-path.d.ts +22 -0
  300. package/dist/lib/locale-path.js +57 -0
  301. package/dist/lib/normalized-data.js +252 -152
  302. package/dist/lib/preview-handoff.js +2 -2
  303. package/dist/lib/queries.d.ts +11 -0
  304. package/dist/lib/queries.js +70 -141
  305. package/dist/lib/studio-reads.d.ts +14 -0
  306. package/dist/lib/studio-reads.js +554 -0
  307. package/dist/lib/use-project-room.js +50 -50
  308. package/dist/lib/use-thread.js +310 -0
  309. package/dist/lib/utils.js +25 -29
  310. package/dist/lib/view-locale-context.js +22 -0
  311. package/dist/lib/view-locale.js +46 -0
  312. package/dist/package.js +5 -0
  313. package/dist/studio-overlays.css +41 -151
  314. package/dist/studio.css +2 -2
  315. package/package.json +70 -73
  316. package/skills/camox/SKILL.md +16 -11
  317. package/skills/camox/references/artifacts.md +179 -0
  318. package/skills/camox/references/block-definitions.md +75 -59
  319. package/skills/camox/references/cli-common.md +9 -11
  320. package/skills/camox/references/cli-content.md +92 -69
  321. package/skills/camox/references/cli-publishing.md +26 -0
  322. package/skills/camox/references/dom-integrations.md +27 -0
  323. package/skills/camox/references/field-styling.md +4 -4
  324. package/skills/camox/references/layout-definitions.md +16 -14
  325. package/skills/camox/references/localization.md +56 -0
  326. package/skills/camox/references/routed-layouts.md +133 -15
  327. package/skills/camox-expand/SKILL.md +70 -0
  328. package/skills/camox-expand/references/jobs.md +39 -0
  329. package/skills/camoxify/SKILL.md +29 -7
  330. package/dist/core/components/AddBlockControlBar.js +0 -78
  331. package/dist/core/hooks/useRequireDraftSource.js +0 -23
  332. package/dist/features/metadata/sitemap.d.ts +0 -8
  333. package/dist/features/metadata/sitemap.js +0 -17
  334. package/dist/features/og/imageResponse.node.d.ts +0 -12
  335. package/dist/features/og/imageResponse.node.js +0 -49
  336. package/dist/features/og/imageResponse.workerd.d.ts +0 -12
  337. package/dist/features/og/imageResponse.workerd.js +0 -40
  338. package/dist/features/page/PublishedPageContent.js +0 -205
  339. package/dist/features/page/PublishedPageExperience.js +0 -23
  340. package/dist/features/preview/DerivedPreview.js +0 -134
  341. package/dist/features/preview/commentsEnabled.js +0 -8
  342. package/dist/features/preview/components/AddBlockSidebar.js +0 -381
  343. package/dist/features/preview/components/AttachedComments.js +0 -331
  344. package/dist/features/preview/components/CommentHeader.js +0 -122
  345. package/dist/features/preview/components/CommentSidebar.js +0 -29
  346. package/dist/features/preview/components/CommentTargetQuote.js +0 -167
  347. package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +0 -5
  348. package/dist/features/preview/components/DerivedLayoutSidebar.js +0 -179
  349. package/dist/features/preview/components/DerivedPageInfoSidebar.js +0 -69
  350. package/dist/features/preview/components/LeftSidebar.js +0 -68
  351. package/dist/features/preview/components/PageEditorSidebar.js +0 -563
  352. package/dist/features/preview/components/PageInfoSidebar.js +0 -1551
  353. package/dist/features/preview/components/PageNavigatorSidebar.js +0 -78
  354. package/dist/features/preview/components/PageStatusBadge.js +0 -97
  355. package/dist/features/preview/components/PeekedBlock.js +0 -217
  356. package/dist/features/preview/components/PreviewComments.js +0 -56
  357. package/dist/features/preview/components/PreviewToolbarSpacer.js +0 -43
  358. package/dist/features/preview/components/PublicationRow.js +0 -422
  359. package/dist/features/preview/components/PublishDialog.js +0 -194
  360. package/dist/features/preview/components/RightSidebar.js +0 -59
  361. package/dist/features/preview/components/SendFeedbackDialog.js +0 -83
  362. package/dist/features/preview/previewCommentsStore.js +0 -135
  363. package/dist/features/preview/publication.js +0 -81
  364. package/dist/features/preview/usePageComments.js +0 -39
  365. package/dist/features/runtime/SharedChromeContext.js +0 -7
  366. package/dist/features/studio/components/EnvironmentMenu.js +0 -425
  367. package/dist/features/vite/appGeneration.js +0 -89
  368. package/dist/lib/view-queries.js +0 -28
  369. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +0 -114
  370. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +0 -25
  371. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +0 -1
  372. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +0 -1
  373. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +0 -20
  374. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +0 -8
  375. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +0 -1
  376. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +0 -18
  377. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +0 -161
  378. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +0 -6
  379. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +0 -54
  380. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +0 -8
  381. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +0 -32
  382. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/new-process-route-tree.d.ts +0 -115
  383. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +0 -1
  384. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +0 -49
  385. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +0 -1
  386. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +0 -6
  387. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +0 -343
  388. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +0 -48
  389. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +0 -695
  390. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +0 -1
  391. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +0 -1
  392. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +0 -5
  393. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/RawStream.d.ts +0 -38
  394. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/seroval-plugins.d.ts +0 -1
  395. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/ssr/serializer/transformer.d.ts +0 -65
  396. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +0 -69
  397. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +0 -1
  398. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +0 -1
  399. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +0 -1
  400. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +0 -1
  401. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +0 -10
  402. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +0 -1
  403. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +0 -1
  404. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +0 -1
  405. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +0 -28
  406. package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +0 -49
  407. package/skills/camox/references/cli-environments.md +0 -37
@@ -0,0 +1,51 @@
1
+ //#region src/core/editing/referenceWrites.ts
2
+ /**
3
+ * One queue per record and client. Two placements editing a shared record must
4
+ * not race each other or replace fields from a stale full-content snapshot:
5
+ * while saves are queued, each builds on the content the previous one saved.
6
+ */
7
+ var ReferenceWrites = class {
8
+ sources = /* @__PURE__ */ new Map();
9
+ save(record, field, value, write) {
10
+ const key = `${record.collectionId}/${record.id}`;
11
+ let source = this.sources.get(key);
12
+ if (!source?.pending) {
13
+ source = { record };
14
+ this.sources.set(key, source);
15
+ }
16
+ const state = source;
17
+ const operation = (state.pending ?? Promise.resolve()).then(async () => {
18
+ const saved = await write({
19
+ id: record.id,
20
+ collectionId: record.collectionId,
21
+ content: {
22
+ ...state.record.content,
23
+ [field]: value
24
+ }
25
+ });
26
+ state.record = {
27
+ ...state.record,
28
+ content: saved.content
29
+ };
30
+ });
31
+ state.pending = operation;
32
+ operation.then(() => {
33
+ if (state.pending === operation) state.pending = void 0;
34
+ }, () => {
35
+ if (state.pending === operation) state.pending = void 0;
36
+ });
37
+ return operation;
38
+ }
39
+ };
40
+ const writers = /* @__PURE__ */ new WeakMap();
41
+ function referenceWritesFor(client) {
42
+ let writer = writers.get(client);
43
+ if (!writer) {
44
+ writer = new ReferenceWrites();
45
+ writers.set(client, writer);
46
+ }
47
+ return writer;
48
+ }
49
+
50
+ //#endregion
51
+ export { ReferenceWrites, referenceWritesFor };
@@ -0,0 +1,90 @@
1
+ import { useProjectUuid } from "../../lib/auth.js";
2
+ import { reads, useReadQuery } from "../../lib/studio-reads.js";
3
+ import { latestContent } from "../lib/reference.js";
4
+ import { fieldPlainText } from "../recordItem.js";
5
+ import { c } from "react/compiler-runtime";
6
+
7
+ //#region src/core/editing/useLatestRecord.ts
8
+ /**
9
+ * A record page's record as the Studio shows it: as its loader returned it, or as a later save
10
+ * through any placement stored it in the shared record cache. Undefined without a record.
11
+ */
12
+ function useLatestRecord(t0) {
13
+ const $ = c(21);
14
+ const { collectionId, labelField, loaded } = t0;
15
+ const projectUuid = useProjectUuid();
16
+ let t1;
17
+ if ($[0] !== collectionId || $[1] !== loaded?.id || $[2] !== projectUuid) {
18
+ t1 = reads.record({
19
+ projectUuid,
20
+ collectionId,
21
+ id: loaded?.id ?? ""
22
+ });
23
+ $[0] = collectionId;
24
+ $[1] = loaded?.id;
25
+ $[2] = projectUuid;
26
+ $[3] = t1;
27
+ } else t1 = $[3];
28
+ let t2;
29
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
30
+ t2 = { enabled: false };
31
+ $[4] = t2;
32
+ } else t2 = $[4];
33
+ const { data: saved } = useReadQuery(t1, t2);
34
+ let t3;
35
+ bb0: {
36
+ if (!loaded) {
37
+ t3 = void 0;
38
+ break bb0;
39
+ }
40
+ let content;
41
+ let t4;
42
+ let t5;
43
+ let t6;
44
+ let updatedAt;
45
+ if ($[5] !== collectionId || $[6] !== labelField || $[7] !== loaded || $[8] !== saved) {
46
+ ({content, updatedAt} = latestContent(loaded, saved));
47
+ t4 = loaded.id;
48
+ t5 = collectionId;
49
+ t6 = fieldPlainText(content[labelField]);
50
+ $[5] = collectionId;
51
+ $[6] = labelField;
52
+ $[7] = loaded;
53
+ $[8] = saved;
54
+ $[9] = content;
55
+ $[10] = t4;
56
+ $[11] = t5;
57
+ $[12] = t6;
58
+ $[13] = updatedAt;
59
+ } else {
60
+ content = $[9];
61
+ t4 = $[10];
62
+ t5 = $[11];
63
+ t6 = $[12];
64
+ updatedAt = $[13];
65
+ }
66
+ let t7;
67
+ if ($[14] !== content || $[15] !== loaded.references || $[16] !== t4 || $[17] !== t5 || $[18] !== t6 || $[19] !== updatedAt) {
68
+ t7 = {
69
+ id: t4,
70
+ collectionId: t5,
71
+ label: t6,
72
+ content,
73
+ references: loaded.references,
74
+ updatedAt
75
+ };
76
+ $[14] = content;
77
+ $[15] = loaded.references;
78
+ $[16] = t4;
79
+ $[17] = t5;
80
+ $[18] = t6;
81
+ $[19] = updatedAt;
82
+ $[20] = t7;
83
+ } else t7 = $[20];
84
+ t3 = t7;
85
+ }
86
+ return t3;
87
+ }
88
+
89
+ //#endregion
90
+ export { useLatestRecord };
@@ -0,0 +1,139 @@
1
+ import { connectArtifactHost } from "../lib/artifactHost.js";
2
+ import { c } from "react/compiler-runtime";
3
+ import * as React from "react";
4
+
5
+ //#region src/core/hooks/useArtifactHost.ts
6
+ /**
7
+ * The studio context of artifacts rendered outside the editing runtime, such as the Preview's
8
+ * read-only page. Absent on the website, where artifacts see `camox.studio` as `null`.
9
+ */
10
+ const ArtifactStudioContext = React.createContext(null);
11
+ /**
12
+ * Whether artifacts run their source here, or show a still stand-in. On the Canvas, only the
13
+ * selected item's artifacts run: each running artifact gets a browser process of its own, which
14
+ * the Canvas waits on for every frame while the camera moves.
15
+ */
16
+ const ArtifactsRunContext = React.createContext(true);
17
+ /**
18
+ * Connects an artifact's `<iframe>` to the `camox` runtime inside it: keeps sharing `studio` and
19
+ * its Artifact Data as they change, sizes frames sized to their content, and routes the
20
+ * artifact's navigation.
21
+ */
22
+ function useArtifactHost(t0) {
23
+ const $ = c(18);
24
+ const { studio, data: t1, size, navigate } = t0;
25
+ let t2;
26
+ if ($[0] !== t1) {
27
+ t2 = t1 === void 0 ? {} : t1;
28
+ $[0] = t1;
29
+ $[1] = t2;
30
+ } else t2 = $[1];
31
+ const data = t2;
32
+ const host = React.useRef(null);
33
+ let t3;
34
+ if ($[2] !== data || $[3] !== studio) {
35
+ t3 = {
36
+ studio,
37
+ data
38
+ };
39
+ $[2] = data;
40
+ $[3] = studio;
41
+ $[4] = t3;
42
+ } else t3 = $[4];
43
+ const latest = React.useRef(t3);
44
+ const latestNavigate = React.useRef(navigate);
45
+ const [height, setHeight] = React.useState(null);
46
+ let t4;
47
+ if ($[5] !== data || $[6] !== navigate || $[7] !== studio) {
48
+ t4 = () => {
49
+ latest.current = {
50
+ studio,
51
+ data
52
+ };
53
+ latestNavigate.current = navigate;
54
+ host.current?.update({
55
+ studio,
56
+ data
57
+ });
58
+ };
59
+ $[5] = data;
60
+ $[6] = navigate;
61
+ $[7] = studio;
62
+ $[8] = t4;
63
+ } else t4 = $[8];
64
+ React.useEffect(t4);
65
+ let t5;
66
+ if ($[9] !== size) {
67
+ t5 = (frame) => {
68
+ if (!frame) return;
69
+ const options = {
70
+ size,
71
+ onHeight: setHeight,
72
+ navigate: (path) => void latestNavigate.current({ to: path })
73
+ };
74
+ const connected = connectArtifactHost(frame, latest.current, options);
75
+ host.current = connected;
76
+ return () => {
77
+ connected.disconnect();
78
+ if (host.current === connected) host.current = null;
79
+ };
80
+ };
81
+ $[9] = size;
82
+ $[10] = t5;
83
+ } else t5 = $[10];
84
+ const ref = t5;
85
+ if (size !== "content" || height === null) {
86
+ let t6;
87
+ if ($[11] !== ref) {
88
+ t6 = { ref };
89
+ $[11] = ref;
90
+ $[12] = t6;
91
+ } else t6 = $[12];
92
+ return t6;
93
+ }
94
+ let t6;
95
+ if ($[13] !== height) {
96
+ t6 = { height };
97
+ $[13] = height;
98
+ $[14] = t6;
99
+ } else t6 = $[14];
100
+ let t7;
101
+ if ($[15] !== ref || $[16] !== t6) {
102
+ t7 = {
103
+ ref,
104
+ style: t6
105
+ };
106
+ $[15] = ref;
107
+ $[16] = t6;
108
+ $[17] = t7;
109
+ } else t7 = $[17];
110
+ return t7;
111
+ }
112
+ /**
113
+ * The Artifact Data to inline in an artifact's `srcDoc`: the data its source first rendered
114
+ * with. Later changes reach the artifact through its host, so they never reload the frame; a new
115
+ * source starts again from the current data.
116
+ */
117
+ function useInitialArtifactData(source, data) {
118
+ const $ = c(3);
119
+ let t0;
120
+ if ($[0] !== data || $[1] !== source) {
121
+ t0 = {
122
+ source,
123
+ data
124
+ };
125
+ $[0] = data;
126
+ $[1] = source;
127
+ $[2] = t0;
128
+ } else t0 = $[2];
129
+ const [initial, setInitial] = React.useState(t0);
130
+ if (initial.source === source) return initial.data;
131
+ setInitial({
132
+ source,
133
+ data
134
+ });
135
+ return data;
136
+ }
137
+
138
+ //#endregion
139
+ export { ArtifactStudioContext, ArtifactsRunContext, useArtifactHost, useInitialArtifactData };
@@ -1,42 +1,67 @@
1
- import { previewStore } from "../../features/preview/previewStore.js";
1
+ import { previewStore, samePlacement, selectionBlockId, selectionForOwner } from "../../features/preview/previewStore.js";
2
+ import { PreviewEditingOwnerContext } from "../../features/preview/previewSelection.js";
2
3
  import { c } from "react/compiler-runtime";
4
+ import { useContext } from "react";
3
5
  import { useSelector } from "@xstate/store-react";
4
6
 
5
7
  //#region src/core/hooks/useFieldSelection.ts
6
8
  /**
7
9
  * Returns whether the given field is currently selected based on the normalized selection state.
8
10
  *
9
- * Matches when the selection points to this exact field (type + name + optional repeater item).
11
+ * Matches when the selection points to this exact field (type + name + optional repeatable item).
10
12
  */
11
- function useFieldSelection(blockId, fieldName, fieldType, repeaterItemId) {
13
+ function useFieldSelection(blockId, fieldName, fieldType, repeatableItemId) {
12
14
  const $ = c(6);
13
- if ($[0] !== "d38da1cfe1462f293f7a9f0ae3e6649ca277091bc93b0a6a0e1cbbe5ba4d1fef") {
14
- for (let $i = 0; $i < 6; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
15
- $[0] = "d38da1cfe1462f293f7a9f0ae3e6649ca277091bc93b0a6a0e1cbbe5ba4d1fef";
16
- }
15
+ const owner = useContext(PreviewEditingOwnerContext);
17
16
  let t0;
18
- if ($[1] !== blockId || $[2] !== fieldName || $[3] !== fieldType || $[4] !== repeaterItemId) {
17
+ if ($[0] !== blockId || $[1] !== fieldName || $[2] !== fieldType || $[3] !== owner || $[4] !== repeatableItemId) {
19
18
  t0 = (state) => {
20
- const sel = state.context.selection;
21
- if (!sel || sel.blockId !== blockId) return false;
19
+ const sel = selectionForOwner(state.context, owner);
20
+ if (!sel || selectionBlockId(sel) !== blockId) return false;
22
21
  if (sel.type === "block-field") {
23
- if (repeaterItemId) return false;
22
+ if (repeatableItemId) return false;
24
23
  return sel.fieldType === fieldType && sel.fieldName === fieldName;
25
24
  }
26
25
  if (sel.type === "item-field") {
27
- if (!repeaterItemId) return false;
28
- return sel.itemId === repeaterItemId && sel.fieldType === fieldType && sel.fieldName === fieldName;
26
+ if (!repeatableItemId) return false;
27
+ return sel.itemId === repeatableItemId && sel.fieldType === fieldType && sel.fieldName === fieldName;
29
28
  }
30
29
  return false;
31
30
  };
32
- $[1] = blockId;
33
- $[2] = fieldName;
34
- $[3] = fieldType;
35
- $[4] = repeaterItemId;
31
+ $[0] = blockId;
32
+ $[1] = fieldName;
33
+ $[2] = fieldType;
34
+ $[3] = owner;
35
+ $[4] = repeatableItemId;
36
36
  $[5] = t0;
37
37
  } else t0 = $[5];
38
38
  return useSelector(previewStore, t0);
39
39
  }
40
+ /**
41
+ * Returns whether the placed record, or one of its record fields when `recordFieldName` is
42
+ * given, is selected. Matches only this placement, so other placements of the same record
43
+ * stay unselected.
44
+ */
45
+ function useRecordSelection(placement, recordFieldName) {
46
+ const $ = c(4);
47
+ const owner = useContext(PreviewEditingOwnerContext);
48
+ let t0;
49
+ if ($[0] !== owner || $[1] !== placement || $[2] !== recordFieldName) {
50
+ t0 = (state) => {
51
+ const sel = selectionForOwner(state.context, owner);
52
+ if (!placement || !sel) return false;
53
+ if (sel.type !== "record" && sel.type !== "record-field") return false;
54
+ if (!samePlacement(sel, placement)) return false;
55
+ if (recordFieldName === void 0) return sel.type === "record";
56
+ return sel.type === "record-field" && sel.recordFieldName === recordFieldName;
57
+ };
58
+ $[0] = owner;
59
+ $[1] = placement;
60
+ $[2] = recordFieldName;
61
+ $[3] = t0;
62
+ } else t0 = $[3];
63
+ return useSelector(previewStore, t0);
64
+ }
40
65
 
41
66
  //#endregion
42
- export { useFieldSelection };
67
+ export { useFieldSelection, useRecordSelection };
@@ -1,19 +1,21 @@
1
1
  import { useIsAuthenticated } from "../../lib/auth.js";
2
- import { previewStore, selectIsEditMode } from "../../features/preview/previewStore.js";
3
- import { c } from "react/compiler-runtime";
2
+ import { previewStore, selectIsCanvasShown } from "../../features/preview/previewStore.js";
3
+ import * as React from "react";
4
4
  import { useSelector } from "@xstate/store-react";
5
5
 
6
6
  //#region src/core/hooks/useIsEditable.ts
7
+ /**
8
+ * Whether the surrounding frame offers editing while the Canvas shows. Only the selected
9
+ * Page's frame does: the others render as the site does, so a click on them only selects
10
+ * the Page. Frames keep the editing runtime either way, so toggling never remounts the page.
11
+ */
12
+ const EditableSurfaceContext = React.createContext(true);
7
13
  function useIsEditable(mode) {
8
- const $ = c(1);
9
- if ($[0] !== "baeaba7613c819c1f4460b64af1c246a057a26cf699e41daca4193d0ee512f1c") {
10
- for (let $i = 0; $i < 1; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
11
- $[0] = "baeaba7613c819c1f4460b64af1c246a057a26cf699e41daca4193d0ee512f1c";
12
- }
13
14
  const isAuthenticated = useIsAuthenticated();
14
- const isEditMode = useSelector(previewStore, selectIsEditMode);
15
- return isAuthenticated && (mode === "site" || mode === "layout") && isEditMode;
15
+ const isCanvasShown = useSelector(previewStore, selectIsCanvasShown);
16
+ const surface = React.use(EditableSurfaceContext);
17
+ return isAuthenticated && (mode === "site" || mode === "layout") && isCanvasShown && surface;
16
18
  }
17
19
 
18
20
  //#endregion
19
- export { useIsEditable };
21
+ export { EditableSurfaceContext, useIsEditable };
@@ -11,22 +11,18 @@ import * as React from "react";
11
11
  * `match` is undefined.
12
12
  */
13
13
  function useOverlayMessage(iframeWindow, enabled, startType, endType, match) {
14
- const $ = c(10);
15
- if ($[0] !== "054e151c2e2c2385d80749bd79af75fa91d1c017ccb12caf70e0f41df7360b1a") {
16
- for (let $i = 0; $i < 10; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
17
- $[0] = "054e151c2e2c2385d80749bd79af75fa91d1c017ccb12caf70e0f41df7360b1a";
18
- }
14
+ const $ = c(9);
19
15
  const [active, setActive] = React.useState(false);
20
16
  let t0;
21
- if ($[1] !== match) {
17
+ if ($[0] !== match) {
22
18
  t0 = JSON.stringify(match);
23
- $[1] = match;
24
- $[2] = t0;
25
- } else t0 = $[2];
19
+ $[0] = match;
20
+ $[1] = t0;
21
+ } else t0 = $[1];
26
22
  const matchJson = t0;
27
23
  let t1;
28
24
  let t2;
29
- if ($[3] !== enabled || $[4] !== endType || $[5] !== iframeWindow || $[6] !== matchJson || $[7] !== startType) {
25
+ if ($[2] !== enabled || $[3] !== endType || $[4] !== iframeWindow || $[5] !== matchJson || $[6] !== startType) {
30
26
  t1 = () => {
31
27
  if (!enabled || !iframeWindow) return;
32
28
  const matchEntries = Object.entries(JSON.parse(matchJson));
@@ -51,16 +47,16 @@ function useOverlayMessage(iframeWindow, enabled, startType, endType, match) {
51
47
  endType,
52
48
  matchJson
53
49
  ];
54
- $[3] = enabled;
55
- $[4] = endType;
56
- $[5] = iframeWindow;
57
- $[6] = matchJson;
58
- $[7] = startType;
59
- $[8] = t1;
60
- $[9] = t2;
50
+ $[2] = enabled;
51
+ $[3] = endType;
52
+ $[4] = iframeWindow;
53
+ $[5] = matchJson;
54
+ $[6] = startType;
55
+ $[7] = t1;
56
+ $[8] = t2;
61
57
  } else {
62
- t1 = $[8];
63
- t2 = $[9];
58
+ t1 = $[7];
59
+ t2 = $[8];
64
60
  }
65
61
  React.useEffect(t1, t2);
66
62
  return active;
@@ -0,0 +1,21 @@
1
+ import "../defineDocument.js";
2
+ import "./artifactData.js";
3
+ import * as React from "react";
4
+ import "@camox/api-contract";
5
+ //#region src/core/lib/artifact.d.ts
6
+ /** The frame attributes of an artifact source. */
7
+ export type ArtifactFrameProps = {
8
+ srcDoc: string;
9
+ sandbox: string;
10
+ allow: string;
11
+ title: string;
12
+ loading: "lazy";
13
+ };
14
+ /** What `block.Artifact` passes to its render prop, to spread onto an `<iframe>`. */
15
+ export type ArtifactRenderProps = ArtifactFrameProps & {
16
+ /** Connects the frame to the `camox` runtime inside it. */
17
+ ref: React.RefCallback<HTMLIFrameElement>;
18
+ /** For `size: "content"`, the height the artifact's content needs, once it reports it. */
19
+ style?: React.CSSProperties;
20
+ };
21
+ //#endregion
@@ -0,0 +1,154 @@
1
+ import { escapeAttribute } from "../../lib/html.js";
2
+ import { ARTIFACT_RUNTIME } from "./artifactRuntime.js";
3
+ import { artifactTitle } from "@camox/api-contract";
4
+
5
+ //#region src/core/lib/artifact.ts
6
+ const FONT_LINK_RELS = /* @__PURE__ */ new Set(["stylesheet", "preconnect"]);
7
+ const UNHEAD_TAG_OPTIONS = /* @__PURE__ */ new Set([
8
+ "key",
9
+ "tagPriority",
10
+ "tagPosition",
11
+ "tagDuplicateStrategy",
12
+ "processTemplateParams",
13
+ "innerHTML",
14
+ "textContent"
15
+ ]);
16
+ function renderLink(link) {
17
+ let attributes = "";
18
+ for (const [name, value] of Object.entries(link)) {
19
+ if (UNHEAD_TAG_OPTIONS.has(name) || !/^[a-z][a-z0-9-]*$/i.test(name)) continue;
20
+ if (value === true) attributes += ` ${name}`;
21
+ if (typeof value === "string" || typeof value === "number") attributes += ` ${name}="${escapeAttribute(String(value))}"`;
22
+ }
23
+ return `<link${attributes}>`;
24
+ }
25
+ const DATA_SCRIPT_OPEN = "<script type=\"application/json\" data-camox-data>";
26
+ /**
27
+ * The initial Artifact Data as an inert JSON script, which the runtime reads on first access.
28
+ * `<` is escaped so no value can close the script early.
29
+ */
30
+ function artifactDataScript(data) {
31
+ const json = JSON.stringify(data).replaceAll("<", "\\u003c");
32
+ return `${DATA_SCRIPT_OPEN}${json}<\/script>`;
33
+ }
34
+ /**
35
+ * The stylesheet and preconnect links of the project's document definition, as HTML, so artifacts
36
+ * use the website's fonts from their first render. Nothing else from the document's head: its
37
+ * title, meta, scripts and icons belong to the website, not to the artifact.
38
+ */
39
+ function artifactFontLinks(document) {
40
+ const links = document?.link;
41
+ if (!Array.isArray(links)) return "";
42
+ return links.filter((link) => {
43
+ if (typeof link !== "object" || link === null) return false;
44
+ const rel = link.rel;
45
+ if (typeof rel !== "string") return false;
46
+ return rel.split(/\s+/).some((token) => FONT_LINK_RELS.has(token.toLowerCase()));
47
+ }).map(renderLink).join("");
48
+ }
49
+ /**
50
+ * The document an artifact frame loads: the `camox` runtime, the website's font links, the initial
51
+ * Artifact Data, then the stored source. The doctype comes first so the runtime's script never
52
+ * puts the page in quirks mode; the source's own doctype, if any, is then ignored by the parser.
53
+ */
54
+ function artifactDocument(source, { fontLinks = "", data = {} }) {
55
+ return `<!doctype html>${`<script>${ARTIFACT_RUNTIME}<\/script>${fontLinks}${artifactDataScript(data)}`}${source}`;
56
+ }
57
+ /**
58
+ * The artifact source inside an artifact's document, the reverse of `artifactDocument`, or `null`
59
+ * for any other document. The font links can't hold `<` (their attributes escape it) and the data
60
+ * JSON escapes it too, so the first `<\/script>` after the data's opening tag ends the data.
61
+ */
62
+ function artifactSourceOf(document) {
63
+ const head = `<!doctype html><script>${ARTIFACT_RUNTIME}<\/script>`;
64
+ if (!document.startsWith(head)) return null;
65
+ const data = document.indexOf(DATA_SCRIPT_OPEN, head.length);
66
+ if (data < 0 || document.slice(head.length, data).includes("<script")) return null;
67
+ const end = document.indexOf("<\/script>", data + 48);
68
+ if (end < 0) return null;
69
+ return document.slice(end + 9);
70
+ }
71
+ /**
72
+ * The frame props for an artifact source, with its initial Artifact Data and the website's font
73
+ * links. This getter is the boundary that hides how the source reaches the frame (inline `srcdoc`
74
+ * today), so blocks never depend on it.
75
+ */
76
+ function artifactFrameProps(source, options = {}) {
77
+ return {
78
+ srcDoc: artifactDocument(source, options),
79
+ sandbox: "allow-scripts",
80
+ allow: "fullscreen; clipboard-write",
81
+ title: artifactTitle(source),
82
+ loading: "lazy"
83
+ };
84
+ }
85
+ const PLACEHOLDER_SOURCE = `<!doctype html>
86
+ <html>
87
+ <head>
88
+ <title>Empty artifact</title>
89
+ <style>
90
+ html, body { height: 100%; margin: 0; }
91
+ body {
92
+ display: grid;
93
+ place-items: center;
94
+ min-height: 8rem;
95
+ box-sizing: border-box;
96
+ border: 1px dashed #a1a1aa;
97
+ background: #f4f4f5;
98
+ color: #71717a;
99
+ font: 14px/1.4 system-ui, sans-serif;
100
+ text-align: center;
101
+ }
102
+ </style>
103
+ </head>
104
+ <body><p>Empty artifact<br />Ask an agent to create it</p></body>
105
+ </html>`;
106
+ /**
107
+ * The frame props of a still page: no script runs in it, so it can keep the website's origin,
108
+ * and render in the website's own browser process rather than one of its own.
109
+ */
110
+ function stillFrameProps(srcDoc, title) {
111
+ return {
112
+ srcDoc,
113
+ sandbox: "allow-same-origin",
114
+ allow: "",
115
+ title,
116
+ loading: "lazy"
117
+ };
118
+ }
119
+ /** The frame props of an empty artifact in the studio preview, so it takes the block's frame. */
120
+ function artifactPlaceholderProps() {
121
+ return stillFrameProps(PLACEHOLDER_SOURCE, "Empty artifact");
122
+ }
123
+ /**
124
+ * The frame props of an artifact that doesn't run, such as one on a Canvas Page that isn't
125
+ * selected: a still page with only the artifact's title, over whatever is behind the frame.
126
+ */
127
+ function artifactStandInProps(source) {
128
+ const title = artifactTitle(source);
129
+ const text = escapeAttribute(title);
130
+ return stillFrameProps(`<!doctype html>
131
+ <html>
132
+ <head>
133
+ <title>${text}</title>
134
+ <style>
135
+ html, body { height: 100%; margin: 0; }
136
+ body {
137
+ display: grid;
138
+ place-items: center;
139
+ color: #a1a1aa;
140
+ font: 14px/1.4 system-ui, sans-serif;
141
+ text-align: center;
142
+ }
143
+ </style>
144
+ </head>
145
+ <body><p>${text}</p></body>
146
+ </html>`, title);
147
+ }
148
+ /** Whether a stored artifact value holds a source to render. */
149
+ function isArtifactSource(value) {
150
+ return typeof value === "string" && value.trim() !== "";
151
+ }
152
+
153
+ //#endregion
154
+ export { artifactFontLinks, artifactFrameProps, artifactPlaceholderProps, artifactSourceOf, artifactStandInProps, artifactTitle, isArtifactSource };