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.
- package/dist/components/AuthGate.js +0 -6
- package/dist/components/DeviceSelector.js +96 -0
- package/dist/components/PlatformLabel.js +20 -24
- package/dist/core/components/lexical/HighlightNode.js +1 -1
- package/dist/core/components/lexical/InlineContentEditable.js +15 -19
- package/dist/core/components/lexical/InlineLexicalEditor.js +54 -74
- package/dist/core/components/lexical/InlineStylesPlugin.js +53 -53
- package/dist/core/components/lexical/MaxLengthPlugin.js +59 -0
- package/dist/core/components/lexical/SelectionBroadcaster.js +53 -54
- package/dist/core/components/lexical/SidebarLexicalEditor.js +322 -229
- package/dist/core/components/lexical/SummaryToggleGuard.js +42 -0
- package/dist/core/components/lexical/TextLinkPopover.js +169 -180
- package/dist/core/createApp.d.ts +241 -312
- package/dist/core/createApp.js +123 -29
- package/dist/core/createBlock.d.ts +5 -5
- package/dist/core/createBlock.js +385 -152
- package/dist/core/createCollection.d.ts +55 -0
- package/dist/core/createCollection.js +93 -0
- package/dist/core/createLayout.d.ts +197 -61
- package/dist/core/createLayout.js +114 -56
- package/dist/core/defineDocument.d.ts +3 -5
- package/dist/core/derivedRoutes.js +49 -1
- package/dist/core/dom.d.ts +13 -4
- package/dist/core/dom.js +44 -1
- package/dist/core/editing/BlockEditingRuntime.d.ts +16 -0
- package/dist/core/editing/BlockEditingRuntime.js +6 -15
- package/dist/core/editing/CompleteBlockEditingRuntime.js +28 -23
- package/dist/core/editing/createEditableBlock.d.ts +754 -633
- package/dist/core/editing/createEditableBlock.js +2113 -1066
- package/dist/core/editing/referenceWrites.js +51 -0
- package/dist/core/editing/useLatestRecord.js +90 -0
- package/dist/core/hooks/useArtifactHost.js +139 -0
- package/dist/core/hooks/useFieldSelection.js +43 -18
- package/dist/core/hooks/useIsEditable.js +12 -10
- package/dist/core/hooks/useOverlayMessage.js +15 -19
- package/dist/core/lib/artifact.d.ts +21 -0
- package/dist/core/lib/artifact.js +154 -0
- package/dist/core/lib/artifactColors.js +123 -0
- package/dist/core/lib/artifactData.d.ts +1 -0
- package/dist/core/lib/artifactData.js +131 -0
- package/dist/core/lib/artifactHost.js +205 -0
- package/dist/core/lib/artifactRuntime.js +36 -0
- package/dist/core/lib/artifactTheme.js +57 -0
- package/dist/core/lib/contentType.d.ts +302 -106
- package/dist/core/lib/contentType.js +201 -173
- package/dist/core/lib/fieldTypes.js +3 -0
- package/dist/core/lib/iconTypes.d.ts +3 -3
- package/dist/core/lib/icons.d.ts +4 -4
- package/dist/core/lib/icons.js +40 -44
- package/dist/core/lib/imagePlaceholder.js +177 -0
- package/dist/core/lib/imageTransform.js +1 -1
- package/dist/core/lib/lexicalReact.d.ts +3 -1
- package/dist/core/lib/lexicalState.js +1 -1
- package/dist/core/lib/previewPaused.js +9 -0
- package/dist/core/lib/recordScope.js +316 -0
- package/dist/core/lib/reference.d.ts +81 -0
- package/dist/core/lib/reference.js +29 -0
- package/dist/core/lib/textLinks.js +7 -5
- package/dist/core/lib/textStyles.d.ts +5 -7
- package/dist/core/lib/textStyles.js +2 -2
- package/dist/core/notFound.d.ts +7 -0
- package/dist/core/notFound.js +11 -0
- package/dist/core/pageDestinations.js +6 -3
- package/dist/core/recordItem.js +34 -0
- package/dist/core/requestContext.d.ts +26 -0
- package/dist/core/requestContext.js +20 -0
- package/dist/features/canvas/CamoxCanvas.js +1401 -0
- package/dist/features/canvas/CanvasLoadingScreen.js +35 -0
- package/dist/features/canvas/CanvasOverlays.js +254 -0
- package/dist/features/canvas/CanvasPageEdge.js +87 -0
- package/dist/features/canvas/CanvasPageFrame.js +333 -0
- package/dist/features/canvas/CanvasPageHeader.js +125 -0
- package/dist/features/canvas/CanvasPreviewPageSlot.js +123 -0
- package/dist/features/canvas/DerivedPagePathInput.js +238 -0
- package/dist/features/canvas/canvasCamera.js +229 -0
- package/dist/features/canvas/canvasFlight.js +104 -0
- package/dist/features/canvas/canvasFrameCapture.js +364 -0
- package/dist/features/canvas/canvasFrameDocument.js +302 -0
- package/dist/features/canvas/canvasFrameMode.js +53 -0
- package/dist/features/canvas/canvasInsertionSeams.js +44 -0
- package/dist/features/canvas/canvasItems.js +30 -0
- package/dist/features/canvas/canvasOverlayGeometry.js +240 -0
- package/dist/features/canvas/canvasPages.js +79 -0
- package/dist/features/canvas/canvasScreenSpace.js +26 -0
- package/dist/features/canvas/canvasSelection.js +18 -0
- package/dist/features/canvas/canvasStore.js +60 -0
- package/dist/features/canvas/canvasThumbnails.js +304 -0
- package/dist/features/canvas/canvasZoom.js +10 -0
- package/dist/features/canvas/sidebar/CanvasInspector.js +202 -0
- package/dist/features/canvas/sidebar/CanvasNavigator.js +124 -0
- package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -0
- package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +48 -0
- package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +39 -0
- package/dist/features/canvas/sidebar/CuratedPageInspector.js +69 -0
- package/dist/features/canvas/sidebar/DerivedPageInspector.js +37 -0
- package/dist/features/canvas/sidebar/LayoutPageBlocks.js +78 -0
- package/dist/features/canvas/sidebar/LayoutPageOverview.js +71 -0
- package/dist/features/canvas/sidebar/PageInspector.js +157 -0
- package/dist/features/canvas/sidebar/PageInspectorSkeleton.js +90 -0
- package/dist/features/canvas/sidebar/PageOverview.js +27 -0
- package/dist/features/canvas/sidebar/SingletonPageInspector.js +31 -0
- package/dist/features/canvas/useCanvasCamera.js +783 -0
- package/dist/features/canvas/useCanvasFrame.js +148 -0
- package/dist/features/canvas/useCanvasFrameInput.js +97 -0
- package/dist/features/canvas/useCanvasNearness.js +57 -0
- package/dist/features/canvas/useDiscoveredPreviewPaths.js +62 -0
- package/dist/features/content/CamoxContent.d.ts +2 -5
- package/dist/features/content/CamoxContent.js +174 -271
- package/dist/features/content/CollectionItemSheetContext.js +106 -0
- package/dist/features/content/ContentAssets.js +315 -0
- package/dist/features/content/ContentCollection.js +663 -0
- package/dist/features/content/collection-form.js +58 -0
- package/dist/features/content/components/AssetCard.js +80 -84
- package/dist/features/content/components/AssetCardSkeleton.js +4 -8
- package/dist/features/content/components/ContentSidebar.js +129 -18
- package/dist/features/content/components/ContentSidebarGroup.js +37 -0
- package/dist/features/content/components/DeleteCollectionItemButton.js +202 -0
- package/dist/features/content/components/MissingFromLocale.js +282 -0
- package/dist/features/content/components/UploadDropZone.js +27 -31
- package/dist/features/content/components/UploadProgressDrawer.js +90 -98
- package/dist/features/navigation/navigation.d.ts +66 -20
- package/dist/features/navigation/navigation.js +257 -90
- package/dist/features/og/defaultFonts.js +8 -8
- package/dist/features/og/geist-variable-ttf-base64.js +1 -1
- package/dist/features/og/imageResponse.d.ts +8 -0
- package/dist/features/og/imageResponse.js +26 -0
- package/dist/features/page/CuratedPageContent.js +167 -0
- package/dist/features/page/DerivedPageContent.js +26 -30
- package/dist/features/page/SharedLayoutContent.js +25 -27
- package/dist/features/preview/CamoxPreview.d.ts +23 -61
- package/dist/features/preview/CamoxPreview.js +816 -537
- package/dist/features/preview/EditablePageContent.js +1 -1
- package/dist/features/preview/EditablePageExperience.js +16 -22
- package/dist/features/preview/components/AddBlockSheet.js +273 -0
- package/dist/features/preview/components/AssetFieldEditor.js +173 -154
- package/dist/features/preview/components/AssetLightbox.js +181 -134
- package/dist/features/preview/components/AssetPickerModal.js +153 -170
- package/dist/features/preview/components/BlockActionsPopover.js +150 -149
- package/dist/features/preview/components/BlockErrorBoundary.js +8 -12
- package/dist/features/preview/components/BlockThumbnail.js +172 -98
- package/dist/features/preview/components/CanvasPreview.js +243 -0
- package/dist/features/preview/components/CreatePageModal.js +128 -137
- package/dist/features/preview/components/DebouncedFieldEditor.js +29 -33
- package/dist/features/preview/components/DerivedLayoutDialog.js +21 -19
- package/dist/features/preview/components/DrillRow.js +150 -0
- package/dist/features/preview/components/FieldOverlayStyles.js +11 -8
- package/dist/features/preview/components/FieldToolbar.js +160 -110
- package/dist/features/preview/components/Frame.js +108 -20
- package/dist/features/preview/components/IconFieldEditor.js +62 -66
- package/dist/features/preview/components/ItemFieldsEditor.js +231 -205
- package/dist/features/preview/components/LinkFieldEditor.js +135 -139
- package/dist/features/preview/components/Metadata.js +22 -30
- package/dist/features/preview/components/MobilePreviewDrawer.js +89 -108
- package/dist/features/preview/components/MultipleAssetFieldEditor.js +334 -246
- package/dist/features/preview/components/OverlayTracker.js +9 -41
- package/dist/features/preview/components/Overlays.js +81 -69
- package/dist/features/preview/components/PageInfo.js +1748 -0
- package/dist/features/preview/components/PageInfoSkeleton.js +51 -0
- package/dist/features/preview/components/PageLocationFieldset.js +112 -116
- package/dist/features/preview/components/PageNavigatorHeader.js +24 -0
- package/dist/features/preview/components/PageNicknameField.js +22 -26
- package/dist/features/preview/components/PagePicker.js +128 -130
- package/dist/features/preview/components/PageTree.js +525 -532
- package/dist/features/preview/components/PreviewActivation.js +28 -32
- package/dist/features/preview/components/PreviewPanel.js +620 -319
- package/dist/features/preview/components/PreviewToolbar.js +105 -333
- package/dist/features/preview/components/RecordCard.js +80 -0
- package/dist/features/preview/components/RecordCombobox.js +178 -0
- package/dist/features/preview/components/ReferenceFieldEditor.js +149 -0
- package/dist/features/preview/components/ReferenceListFieldEditor.js +432 -0
- package/dist/features/preview/components/RemovedBlockPlaceholder.js +95 -0
- package/dist/features/preview/components/RepeatableItemsList.js +125 -138
- package/dist/features/preview/components/SelectionEditor.js +993 -0
- package/dist/features/preview/components/ShikiMarkdown.js +14 -18
- package/dist/features/preview/components/SidebarSection.js +52 -64
- package/dist/features/preview/components/StudioEditingFallback.js +56 -0
- package/dist/features/preview/components/UnlinkAssetButton.js +104 -107
- package/dist/features/preview/components/blockGridNavigation.js +15 -0
- package/dist/features/preview/components/contentFieldSchema.js +8 -0
- package/dist/features/preview/components/useFieldWriter.js +200 -0
- package/dist/features/preview/components/useRecordView.js +383 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +35 -37
- package/dist/features/preview/components/useUpdateBlockPosition.js +37 -37
- package/dist/features/preview/editingFrame.js +197 -0
- package/dist/features/preview/overlayHighlights.js +17 -44
- package/dist/features/preview/overlayMessages.js +72 -1
- package/dist/features/preview/pageRecord.js +189 -0
- package/dist/features/preview/previewConstants.js +6 -2
- package/dist/features/preview/previewPageFrame.js +95 -0
- package/dist/features/preview/previewPreparation.js +7 -0
- package/dist/features/preview/previewSelection.js +32 -63
- package/dist/features/preview/previewStore.js +225 -123
- package/dist/features/preview/referencePickerFocus.js +29 -0
- package/dist/features/preview/repeatableItemTargets.js +56 -0
- package/dist/features/preview/selectionReveal.js +21 -0
- package/dist/features/preview/usePreviewViewportActions.js +114 -0
- package/dist/features/preview/viewportContinuity.js +109 -0
- package/dist/features/provider/AuthenticatedCamoxProvider.js +69 -44
- package/dist/features/provider/CamoxProvider.d.ts +3 -6
- package/dist/features/provider/CamoxProvider.js +38 -50
- package/dist/features/provider/CoreCamoxProvider.js +69 -50
- package/dist/features/provider/LocalhostPreviewProvider.js +78 -114
- package/dist/features/provider/PreviewSignInPage.js +54 -0
- package/dist/features/provider/components/CamoxAppContext.js +11 -11
- package/dist/features/provider/components/CommandPalette.js +75 -82
- package/dist/features/provider/useAdminShortcuts.js +7 -11
- package/dist/features/routes/pageRuntime.d.ts +44 -4
- package/dist/features/routes/pageRuntime.js +244 -137
- package/dist/features/runtime/RuntimeChrome.js +117 -115
- package/dist/features/runtime/alternates.js +64 -0
- package/dist/features/runtime/analytics.d.ts +7 -0
- package/dist/features/runtime/analytics.js +66 -0
- package/dist/features/runtime/artifactSources.js +87 -0
- package/dist/features/runtime/editingFallback.js +20 -0
- package/dist/features/runtime/linkPrefetch.js +97 -0
- package/dist/features/runtime/livePages.js +62 -0
- package/dist/features/runtime/llmsTxt.js +40 -0
- package/dist/features/runtime/loopbackFetch.js +18 -0
- package/dist/features/runtime/navigationAccessibility.js +51 -0
- package/dist/features/runtime/navigationTarget.js +23 -2
- package/dist/features/runtime/pageApp.js +229 -158
- package/dist/features/runtime/pageBlockTypes.js +20 -0
- package/dist/features/runtime/pageClient.d.ts +2 -4
- package/dist/features/runtime/pageClient.js +18 -3
- package/dist/features/runtime/pageNavigation.js +254 -32
- package/dist/features/runtime/pageServer.d.ts +2 -4
- package/dist/features/runtime/pageServer.js +6 -2
- package/dist/features/runtime/pageViewport.js +7 -0
- package/dist/features/runtime/runtime.d.ts +54 -24
- package/dist/features/runtime/runtime.js +766 -191
- package/dist/features/runtime/runtimeChromeLoader.js +58 -0
- package/dist/features/runtime/runtimeRoutes.d.ts +19 -0
- package/dist/features/runtime/runtimeRoutes.js +25 -0
- package/dist/features/runtime/scrollRestoration.js +133 -0
- package/dist/features/runtime/studioApp.d.ts +4 -3
- package/dist/features/runtime/studioApp.js +5 -9
- package/dist/features/runtime/studioClient.d.ts +2 -4
- package/dist/features/runtime/studioClient.js +12 -3
- package/dist/features/runtime/studioServer.d.ts +2 -4
- package/dist/features/runtime/studioServer.js +6 -1
- package/dist/features/runtime/worker.d.ts +6 -0
- package/dist/features/runtime/worker.js +23 -0
- package/dist/features/runtime/workerRequest.js +44 -0
- package/dist/features/studio/CamoxStudio.d.ts +2 -6
- package/dist/features/studio/CamoxStudio.js +34 -49
- package/dist/features/studio/FollowAgentProvider.js +327 -0
- package/dist/features/studio/components/ChatSidebar.js +356 -0
- package/dist/features/studio/components/DraftsControl.js +676 -0
- package/dist/features/studio/components/FaviconDialog.js +318 -0
- package/dist/features/studio/components/LocalePicker.js +785 -0
- package/dist/features/studio/components/Navbar.js +123 -103
- package/dist/features/studio/components/ProjectMenu.js +239 -260
- package/dist/features/studio/components/RenameDraftDialog.js +206 -0
- package/dist/features/studio/components/ReviewDraftSheet.js +1472 -0
- package/dist/features/studio/components/ThreadComposer.js +157 -0
- package/dist/features/studio/components/ThreadMarkdown.js +113 -0
- package/dist/features/studio/components/ThreadMessages.js +270 -0
- package/dist/features/studio/components/UserButton.js +34 -23
- package/dist/features/studio/draftLabel.js +33 -0
- package/dist/features/studio/draftNotice.js +13 -0
- package/dist/features/studio/followAgent.js +241 -0
- package/dist/features/studio/followAgentContext.js +7 -0
- package/dist/features/studio/localeOptions.js +118 -0
- package/dist/features/studio/localeSwitch.js +19 -0
- package/dist/features/studio/routes.js +26 -1
- package/dist/features/studio/studioStore.js +64 -1
- package/dist/features/studio/useTheme.js +24 -27
- package/dist/features/vite/artifactRuntimeMinification.js +36 -0
- package/dist/features/vite/blockBoilerplate.js +6 -5
- package/dist/features/vite/blockChunks.js +31 -0
- package/dist/features/vite/bundlerLogs.js +17 -0
- package/dist/features/vite/definitionsSync.js +158 -226
- package/dist/features/vite/devAuthentication.js +4 -16
- package/dist/features/vite/devSignIn.js +87 -0
- package/dist/features/vite/iconGeneration.js +1 -1
- package/dist/features/vite/layoutGeneration.js +11 -1
- package/dist/features/vite/publishSeededContent.js +30 -0
- package/dist/features/vite/routeGeneration.js +6 -7
- package/dist/features/vite/runtimeDev.js +80 -99
- package/dist/features/vite/vite.d.ts +51 -31
- package/dist/features/vite/vite.js +224 -127
- package/dist/features/vite/workerBuild.js +39 -0
- package/dist/hooks/use-debounced-field.js +116 -47
- package/dist/hooks/use-file-upload.js +114 -67
- package/dist/hooks/use-marquee-selection.js +32 -36
- package/dist/hooks/use-page-destinations.js +69 -37
- package/dist/lib/api-client-server.d.ts +5 -0
- package/dist/lib/api-client-server.js +10 -4
- package/dist/lib/api-client.d.ts +6 -0
- package/dist/lib/api-client.js +51 -16
- package/dist/lib/api-socket.js +17 -0
- package/dist/lib/auth-page-styles.js +39 -0
- package/dist/lib/auth.js +129 -61
- package/dist/lib/collection-cache.js +23 -0
- package/dist/lib/draft-scope.d.ts +4 -0
- package/dist/lib/draft-scope.js +222 -0
- package/dist/lib/html.js +12 -0
- package/dist/lib/link-pages.js +154 -0
- package/dist/lib/locale-path.d.ts +22 -0
- package/dist/lib/locale-path.js +57 -0
- package/dist/lib/normalized-data.js +252 -152
- package/dist/lib/preview-handoff.js +2 -2
- package/dist/lib/queries.d.ts +11 -0
- package/dist/lib/queries.js +70 -141
- package/dist/lib/studio-reads.d.ts +14 -0
- package/dist/lib/studio-reads.js +554 -0
- package/dist/lib/use-project-room.js +50 -50
- package/dist/lib/use-thread.js +310 -0
- package/dist/lib/utils.js +25 -29
- package/dist/lib/view-locale-context.js +22 -0
- package/dist/lib/view-locale.js +46 -0
- package/dist/package.js +5 -0
- package/dist/studio-overlays.css +41 -151
- package/dist/studio.css +2 -2
- package/package.json +70 -73
- package/skills/camox/SKILL.md +16 -11
- package/skills/camox/references/artifacts.md +179 -0
- package/skills/camox/references/block-definitions.md +75 -59
- package/skills/camox/references/cli-common.md +9 -11
- package/skills/camox/references/cli-content.md +92 -69
- package/skills/camox/references/cli-publishing.md +26 -0
- package/skills/camox/references/dom-integrations.md +27 -0
- package/skills/camox/references/field-styling.md +4 -4
- package/skills/camox/references/layout-definitions.md +16 -14
- package/skills/camox/references/localization.md +56 -0
- package/skills/camox/references/routed-layouts.md +133 -15
- package/skills/camox-expand/SKILL.md +70 -0
- package/skills/camox-expand/references/jobs.md +39 -0
- package/skills/camoxify/SKILL.md +29 -7
- package/dist/core/components/AddBlockControlBar.js +0 -78
- package/dist/core/hooks/useRequireDraftSource.js +0 -23
- package/dist/features/metadata/sitemap.d.ts +0 -8
- package/dist/features/metadata/sitemap.js +0 -17
- package/dist/features/og/imageResponse.node.d.ts +0 -12
- package/dist/features/og/imageResponse.node.js +0 -49
- package/dist/features/og/imageResponse.workerd.d.ts +0 -12
- package/dist/features/og/imageResponse.workerd.js +0 -40
- package/dist/features/page/PublishedPageContent.js +0 -205
- package/dist/features/page/PublishedPageExperience.js +0 -23
- package/dist/features/preview/DerivedPreview.js +0 -134
- package/dist/features/preview/commentsEnabled.js +0 -8
- package/dist/features/preview/components/AddBlockSidebar.js +0 -381
- package/dist/features/preview/components/AttachedComments.js +0 -331
- package/dist/features/preview/components/CommentHeader.js +0 -122
- package/dist/features/preview/components/CommentSidebar.js +0 -29
- package/dist/features/preview/components/CommentTargetQuote.js +0 -167
- package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +0 -5
- package/dist/features/preview/components/DerivedLayoutSidebar.js +0 -179
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +0 -69
- package/dist/features/preview/components/LeftSidebar.js +0 -68
- package/dist/features/preview/components/PageEditorSidebar.js +0 -563
- package/dist/features/preview/components/PageInfoSidebar.js +0 -1551
- package/dist/features/preview/components/PageNavigatorSidebar.js +0 -78
- package/dist/features/preview/components/PageStatusBadge.js +0 -97
- package/dist/features/preview/components/PeekedBlock.js +0 -217
- package/dist/features/preview/components/PreviewComments.js +0 -56
- package/dist/features/preview/components/PreviewToolbarSpacer.js +0 -43
- package/dist/features/preview/components/PublicationRow.js +0 -422
- package/dist/features/preview/components/PublishDialog.js +0 -194
- package/dist/features/preview/components/RightSidebar.js +0 -59
- package/dist/features/preview/components/SendFeedbackDialog.js +0 -83
- package/dist/features/preview/previewCommentsStore.js +0 -135
- package/dist/features/preview/publication.js +0 -81
- package/dist/features/preview/usePageComments.js +0 -39
- package/dist/features/runtime/SharedChromeContext.js +0 -7
- package/dist/features/studio/components/EnvironmentMenu.js +0 -425
- package/dist/features/vite/appGeneration.js +0 -89
- package/dist/lib/view-queries.js +0 -28
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/Matches.d.ts +0 -114
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/RouterProvider.d.ts +0 -25
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/config.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/defer.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/fileRoute.d.ts +0 -20
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/global.d.ts +0 -8
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/hash-scroll.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/index.d.ts +0 -18
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/link.d.ts +0 -161
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/load-matches.d.ts +0 -6
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/location.d.ts +0 -54
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/lru-cache.d.ts +0 -8
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/manifest.d.ts +0 -32
- 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
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/not-found.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/redirect.d.ts +0 -49
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/rewrite.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/root.d.ts +0 -6
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/route.d.ts +0 -343
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/routeInfo.d.ts +0 -48
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/router.d.ts +0 -695
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/scroll-restoration.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchMiddleware.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/searchParams.d.ts +0 -5
- 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
- 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
- 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
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/stores.d.ts +0 -69
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/structuralSharing.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/typePrimitives.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderData.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useLoaderDeps.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useNavigate.d.ts +0 -10
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useParams.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useRouteContext.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/useSearch.d.ts +0 -1
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/utils.d.ts +0 -28
- package/dist/node_modules/.pnpm/@tanstack_router-core@1.168.14/node_modules/@tanstack/router-core/dist/esm/validators.d.ts +0 -49
- 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
|
|
11
|
+
* Matches when the selection points to this exact field (type + name + optional repeatable item).
|
|
10
12
|
*/
|
|
11
|
-
function useFieldSelection(blockId, fieldName, fieldType,
|
|
13
|
+
function useFieldSelection(blockId, fieldName, fieldType, repeatableItemId) {
|
|
12
14
|
const $ = c(6);
|
|
13
|
-
|
|
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 ($[
|
|
17
|
+
if ($[0] !== blockId || $[1] !== fieldName || $[2] !== fieldType || $[3] !== owner || $[4] !== repeatableItemId) {
|
|
19
18
|
t0 = (state) => {
|
|
20
|
-
const sel = state.context
|
|
21
|
-
if (!sel || sel
|
|
19
|
+
const sel = selectionForOwner(state.context, owner);
|
|
20
|
+
if (!sel || selectionBlockId(sel) !== blockId) return false;
|
|
22
21
|
if (sel.type === "block-field") {
|
|
23
|
-
if (
|
|
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 (!
|
|
28
|
-
return sel.itemId ===
|
|
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
|
-
$[
|
|
33
|
-
$[
|
|
34
|
-
$[
|
|
35
|
-
$[
|
|
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,
|
|
3
|
-
import
|
|
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
|
|
15
|
-
|
|
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(
|
|
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 ($[
|
|
17
|
+
if ($[0] !== match) {
|
|
22
18
|
t0 = JSON.stringify(match);
|
|
23
|
-
$[
|
|
24
|
-
$[
|
|
25
|
-
} else t0 = $[
|
|
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 ($[
|
|
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
|
-
$[
|
|
55
|
-
$[
|
|
56
|
-
$[
|
|
57
|
-
$[
|
|
58
|
-
$[
|
|
59
|
-
$[
|
|
60
|
-
$[
|
|
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 = $[
|
|
63
|
-
t2 = $[
|
|
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 };
|