@pantheon-systems/puck-css 0.4.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/agent/agentPlugin.d.ts +3 -0
- package/dist/agent/agentPlugin.d.ts.map +1 -0
- package/dist/agent/agentPlugin.js +6 -0
- package/dist/agent/agentPlugin.js.map +1 -0
- package/dist/agent/components/AgentActionButton.d.ts +38 -0
- package/dist/agent/components/AgentActionButton.d.ts.map +1 -0
- package/dist/agent/components/AgentActionButton.js +76 -0
- package/dist/agent/components/AgentActionButton.js.map +1 -0
- package/dist/agent/components/AgentActionModal.d.ts +28 -0
- package/dist/agent/components/AgentActionModal.d.ts.map +1 -0
- package/dist/agent/components/AgentActionModal.js +85 -0
- package/dist/agent/components/AgentActionModal.js.map +1 -0
- package/dist/agent/components/AgentStatusPanel.d.ts +27 -0
- package/dist/agent/components/AgentStatusPanel.d.ts.map +1 -0
- package/dist/agent/components/AgentStatusPanel.js +51 -0
- package/dist/agent/components/AgentStatusPanel.js.map +1 -0
- package/dist/agent/components/index.d.ts +12 -0
- package/dist/agent/components/index.d.ts.map +1 -0
- package/dist/agent/components/index.js +9 -0
- package/dist/agent/components/index.js.map +1 -0
- package/dist/agent/index.d.ts +6 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +4 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/useAgentEdit.d.ts +68 -0
- package/dist/agent/useAgentEdit.d.ts.map +1 -0
- package/dist/agent/useAgentEdit.js +125 -0
- package/dist/agent/useAgentEdit.js.map +1 -0
- package/dist/agent/useAgentTrigger.d.ts +69 -0
- package/dist/agent/useAgentTrigger.d.ts.map +1 -0
- package/dist/agent/useAgentTrigger.js +131 -0
- package/dist/agent/useAgentTrigger.js.map +1 -0
- package/dist/auth/AuthGate.d.ts +5 -0
- package/dist/auth/AuthGate.d.ts.map +1 -0
- package/dist/auth/AuthGate.js +17 -0
- package/dist/auth/AuthGate.js.map +1 -0
- package/dist/auth/P1AuthProvider.d.ts +59 -0
- package/dist/auth/P1AuthProvider.d.ts.map +1 -0
- package/dist/auth/P1AuthProvider.js +254 -0
- package/dist/auth/P1AuthProvider.js.map +1 -0
- package/dist/auth/P1LoginPage.d.ts +26 -0
- package/dist/auth/P1LoginPage.d.ts.map +1 -0
- package/dist/auth/P1LoginPage.js +105 -0
- package/dist/auth/P1LoginPage.js.map +1 -0
- package/dist/auth/index.d.ts +14 -0
- package/dist/auth/index.d.ts.map +1 -0
- package/dist/auth/index.js +12 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/collaboration/collaborationPlugin.d.ts +3 -0
- package/dist/collaboration/collaborationPlugin.d.ts.map +1 -0
- package/dist/collaboration/collaborationPlugin.js +6 -0
- package/dist/collaboration/collaborationPlugin.js.map +1 -0
- package/dist/collaboration/components/AgentActivityBanner.d.ts +26 -0
- package/dist/collaboration/components/AgentActivityBanner.d.ts.map +1 -0
- package/dist/collaboration/components/AgentActivityBanner.js +50 -0
- package/dist/collaboration/components/AgentActivityBanner.js.map +1 -0
- package/dist/collaboration/components/CollaboratorAvatars.d.ts +25 -0
- package/dist/collaboration/components/CollaboratorAvatars.d.ts.map +1 -0
- package/dist/collaboration/components/CollaboratorAvatars.js +75 -0
- package/dist/collaboration/components/CollaboratorAvatars.js.map +1 -0
- package/dist/collaboration/components/FocusRegionHighlight.d.ts +20 -0
- package/dist/collaboration/components/FocusRegionHighlight.d.ts.map +1 -0
- package/dist/collaboration/components/FocusRegionHighlight.js +35 -0
- package/dist/collaboration/components/FocusRegionHighlight.js.map +1 -0
- package/dist/collaboration/components/PresenceIndicator.d.ts +23 -0
- package/dist/collaboration/components/PresenceIndicator.d.ts.map +1 -0
- package/dist/collaboration/components/PresenceIndicator.js +25 -0
- package/dist/collaboration/components/PresenceIndicator.js.map +1 -0
- package/dist/collaboration/index.d.ts +21 -0
- package/dist/collaboration/index.d.ts.map +1 -0
- package/dist/collaboration/index.js +12 -0
- package/dist/collaboration/index.js.map +1 -0
- package/dist/collaboration/useBranchPresence.d.ts +54 -0
- package/dist/collaboration/useBranchPresence.d.ts.map +1 -0
- package/dist/collaboration/useBranchPresence.js +94 -0
- package/dist/collaboration/useBranchPresence.js.map +1 -0
- package/dist/collaboration/useFocusRegionReporting.d.ts +69 -0
- package/dist/collaboration/useFocusRegionReporting.d.ts.map +1 -0
- package/dist/collaboration/useFocusRegionReporting.js +199 -0
- package/dist/collaboration/useFocusRegionReporting.js.map +1 -0
- package/dist/collaboration/usePresence.d.ts +62 -0
- package/dist/collaboration/usePresence.d.ts.map +1 -0
- package/dist/collaboration/usePresence.js +105 -0
- package/dist/collaboration/usePresence.js.map +1 -0
- package/dist/collaboration/useSitePresence.d.ts +54 -0
- package/dist/collaboration/useSitePresence.d.ts.map +1 -0
- package/dist/collaboration/useSitePresence.js +94 -0
- package/dist/collaboration/useSitePresence.js.map +1 -0
- package/dist/collaboration/utils/avatarColor.d.ts +11 -0
- package/dist/collaboration/utils/avatarColor.d.ts.map +1 -0
- package/dist/collaboration/utils/avatarColor.js +42 -0
- package/dist/collaboration/utils/avatarColor.js.map +1 -0
- package/dist/collaboration/utils/focusHighlightConfig.d.ts +54 -0
- package/dist/collaboration/utils/focusHighlightConfig.d.ts.map +1 -0
- package/dist/collaboration/utils/focusHighlightConfig.js +98 -0
- package/dist/collaboration/utils/focusHighlightConfig.js.map +1 -0
- package/dist/collaboration/utils/focusRegionMap.d.ts +82 -0
- package/dist/collaboration/utils/focusRegionMap.d.ts.map +1 -0
- package/dist/collaboration/utils/focusRegionMap.js +188 -0
- package/dist/collaboration/utils/focusRegionMap.js.map +1 -0
- package/dist/core/FocusHighlightContext.d.ts +54 -0
- package/dist/core/FocusHighlightContext.d.ts.map +1 -0
- package/dist/core/FocusHighlightContext.js +46 -0
- package/dist/core/FocusHighlightContext.js.map +1 -0
- package/dist/core/NotificationContext.d.ts +63 -0
- package/dist/core/NotificationContext.d.ts.map +1 -0
- package/dist/core/NotificationContext.js +194 -0
- package/dist/core/NotificationContext.js.map +1 -0
- package/dist/core/P1PuckContext.d.ts +36 -0
- package/dist/core/P1PuckContext.d.ts.map +1 -0
- package/dist/core/P1PuckContext.js +44 -0
- package/dist/core/P1PuckContext.js.map +1 -0
- package/dist/core/PresenceContext.d.ts +70 -0
- package/dist/core/PresenceContext.d.ts.map +1 -0
- package/dist/core/PresenceContext.js +31 -0
- package/dist/core/PresenceContext.js.map +1 -0
- package/dist/core/config.d.ts +26 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +78 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/featureConfig.d.ts +56 -0
- package/dist/core/featureConfig.d.ts.map +1 -0
- package/dist/core/featureConfig.js +77 -0
- package/dist/core/featureConfig.js.map +1 -0
- package/dist/core/index.d.ts +17 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +11 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/plugin-types.d.ts +30 -0
- package/dist/core/plugin-types.d.ts.map +1 -0
- package/dist/core/plugin-types.js +2 -0
- package/dist/core/plugin-types.js.map +1 -0
- package/dist/core/types.d.ts +710 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +5 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/utils/debounce.d.ts +27 -0
- package/dist/core/utils/debounce.d.ts.map +1 -0
- package/dist/core/utils/debounce.js +77 -0
- package/dist/core/utils/debounce.js.map +1 -0
- package/dist/core/utils/retry.d.ts +57 -0
- package/dist/core/utils/retry.d.ts.map +1 -0
- package/dist/core/utils/retry.js +70 -0
- package/dist/core/utils/retry.js.map +1 -0
- package/dist/core/utils/throttle.d.ts +29 -0
- package/dist/core/utils/throttle.d.ts.map +1 -0
- package/dist/core/utils/throttle.js +66 -0
- package/dist/core/utils/throttle.js.map +1 -0
- package/dist/data/cross-reference-resolve.d.ts +6 -0
- package/dist/data/cross-reference-resolve.d.ts.map +1 -0
- package/dist/data/cross-reference-resolve.js +58 -0
- package/dist/data/cross-reference-resolve.js.map +1 -0
- package/dist/data/cross-reference.d.ts +32 -0
- package/dist/data/cross-reference.d.ts.map +1 -0
- package/dist/data/cross-reference.js +188 -0
- package/dist/data/cross-reference.js.map +1 -0
- package/dist/data/dal/index.d.ts +32 -0
- package/dist/data/dal/index.d.ts.map +1 -0
- package/dist/data/dal/index.js +72 -0
- package/dist/data/dal/index.js.map +1 -0
- package/dist/data/dal/init.d.ts +28 -0
- package/dist/data/dal/init.d.ts.map +1 -0
- package/dist/data/dal/init.js +76 -0
- package/dist/data/dal/init.js.map +1 -0
- package/dist/data/dal/p1-store.d.ts +52 -0
- package/dist/data/dal/p1-store.d.ts.map +1 -0
- package/dist/data/dal/p1-store.js +121 -0
- package/dist/data/dal/p1-store.js.map +1 -0
- package/dist/data/dal/request-auth.d.ts +3 -0
- package/dist/data/dal/request-auth.d.ts.map +1 -0
- package/dist/data/dal/request-auth.js +9 -0
- package/dist/data/dal/request-auth.js.map +1 -0
- package/dist/data/dal/types.d.ts +31 -0
- package/dist/data/dal/types.d.ts.map +1 -0
- package/dist/data/dal/types.js +2 -0
- package/dist/data/dal/types.js.map +1 -0
- package/dist/data/get-page.d.ts +5 -0
- package/dist/data/get-page.d.ts.map +1 -0
- package/dist/data/get-page.js +5 -0
- package/dist/data/get-page.js.map +1 -0
- package/dist/data/page-editor-meta.d.ts +16 -0
- package/dist/data/page-editor-meta.d.ts.map +1 -0
- package/dist/data/page-editor-meta.js +99 -0
- package/dist/data/page-editor-meta.js.map +1 -0
- package/dist/data/page-store.d.ts +65 -0
- package/dist/data/page-store.d.ts.map +1 -0
- package/dist/data/page-store.js +302 -0
- package/dist/data/page-store.js.map +1 -0
- package/dist/data/page-structure.d.ts +13 -0
- package/dist/data/page-structure.d.ts.map +1 -0
- package/dist/data/page-structure.js +95 -0
- package/dist/data/page-structure.js.map +1 -0
- package/dist/data/paths.d.ts +16 -0
- package/dist/data/paths.d.ts.map +1 -0
- package/dist/data/paths.js +36 -0
- package/dist/data/paths.js.map +1 -0
- package/dist/data/query-provider.d.ts +5 -0
- package/dist/data/query-provider.d.ts.map +1 -0
- package/dist/data/query-provider.js +16 -0
- package/dist/data/query-provider.js.map +1 -0
- package/dist/data/remote-datasources/fetch-http-json.d.ts +8 -0
- package/dist/data/remote-datasources/fetch-http-json.d.ts.map +1 -0
- package/dist/data/remote-datasources/fetch-http-json.js +89 -0
- package/dist/data/remote-datasources/fetch-http-json.js.map +1 -0
- package/dist/data/remote-datasources/index.d.ts +5 -0
- package/dist/data/remote-datasources/index.d.ts.map +1 -0
- package/dist/data/remote-datasources/index.js +3 -0
- package/dist/data/remote-datasources/index.js.map +1 -0
- package/dist/data/remote-datasources/loader.d.ts +44 -0
- package/dist/data/remote-datasources/loader.d.ts.map +1 -0
- package/dist/data/remote-datasources/loader.js +126 -0
- package/dist/data/remote-datasources/loader.js.map +1 -0
- package/dist/data/remote-datasources/remote-datasource-registry.d.ts +21 -0
- package/dist/data/remote-datasources/remote-datasource-registry.d.ts.map +1 -0
- package/dist/data/remote-datasources/remote-datasource-registry.js +15 -0
- package/dist/data/remote-datasources/remote-datasource-registry.js.map +1 -0
- package/dist/data/remote-datasources/user-remote-datasource-store.d.ts +14 -0
- package/dist/data/remote-datasources/user-remote-datasource-store.d.ts.map +1 -0
- package/dist/data/remote-datasources/user-remote-datasource-store.js +125 -0
- package/dist/data/remote-datasources/user-remote-datasource-store.js.map +1 -0
- package/dist/data/remote-datasources/user-remote-datasource-types.d.ts +15 -0
- package/dist/data/remote-datasources/user-remote-datasource-types.d.ts.map +1 -0
- package/dist/data/remote-datasources/user-remote-datasource-types.js +2 -0
- package/dist/data/remote-datasources/user-remote-datasource-types.js.map +1 -0
- package/dist/data/resolve-data-templates.d.ts +12 -0
- package/dist/data/resolve-data-templates.d.ts.map +1 -0
- package/dist/data/resolve-data-templates.js +286 -0
- package/dist/data/resolve-data-templates.js.map +1 -0
- package/dist/data/route-templates.d.ts +43 -0
- package/dist/data/route-templates.d.ts.map +1 -0
- package/dist/data/route-templates.js +146 -0
- package/dist/data/route-templates.js.map +1 -0
- package/dist/data/semantic-ops.d.ts +47 -0
- package/dist/data/semantic-ops.d.ts.map +1 -0
- package/dist/data/semantic-ops.js +335 -0
- package/dist/data/semantic-ops.js.map +1 -0
- package/dist/data/styles.d.ts +87 -0
- package/dist/data/styles.d.ts.map +1 -0
- package/dist/data/styles.js +87 -0
- package/dist/data/styles.js.map +1 -0
- package/dist/data/template-autocomplete.d.ts +22 -0
- package/dist/data/template-autocomplete.d.ts.map +1 -0
- package/dist/data/template-autocomplete.js +71 -0
- package/dist/data/template-autocomplete.js.map +1 -0
- package/dist/data/template-functions.d.ts +5 -0
- package/dist/data/template-functions.d.ts.map +1 -0
- package/dist/data/template-functions.js +90 -0
- package/dist/data/template-functions.js.map +1 -0
- package/dist/data/utils.d.ts +3 -0
- package/dist/data/utils.d.ts.map +1 -0
- package/dist/data/utils.js +11 -0
- package/dist/data/utils.js.map +1 -0
- package/dist/editor/P1App.d.ts +14 -0
- package/dist/editor/P1App.d.ts.map +1 -0
- package/dist/editor/P1App.js +138 -0
- package/dist/editor/P1App.js.map +1 -0
- package/dist/editor/P1PuckProvider.d.ts +69 -0
- package/dist/editor/P1PuckProvider.d.ts.map +1 -0
- package/dist/editor/P1PuckProvider.js +1473 -0
- package/dist/editor/P1PuckProvider.js.map +1 -0
- package/dist/editor/components/BranchSelector.d.ts +49 -0
- package/dist/editor/components/BranchSelector.d.ts.map +1 -0
- package/dist/editor/components/BranchSelector.js +55 -0
- package/dist/editor/components/BranchSelector.js.map +1 -0
- package/dist/editor/components/NotificationContainer.d.ts +41 -0
- package/dist/editor/components/NotificationContainer.d.ts.map +1 -0
- package/dist/editor/components/NotificationContainer.js +32 -0
- package/dist/editor/components/NotificationContainer.js.map +1 -0
- package/dist/editor/components/PublishButton.d.ts +52 -0
- package/dist/editor/components/PublishButton.d.ts.map +1 -0
- package/dist/editor/components/PublishButton.js +58 -0
- package/dist/editor/components/PublishButton.js.map +1 -0
- package/dist/editor/components/PublishedStatusBadge.d.ts +6 -0
- package/dist/editor/components/PublishedStatusBadge.d.ts.map +1 -0
- package/dist/editor/components/PublishedStatusBadge.js +25 -0
- package/dist/editor/components/PublishedStatusBadge.js.map +1 -0
- package/dist/editor/components/PuckDataCapture.d.ts +22 -0
- package/dist/editor/components/PuckDataCapture.d.ts.map +1 -0
- package/dist/editor/components/PuckDataCapture.js +30 -0
- package/dist/editor/components/PuckDataCapture.js.map +1 -0
- package/dist/editor/components/PuckDataSynchronizer.d.ts +49 -0
- package/dist/editor/components/PuckDataSynchronizer.d.ts.map +1 -0
- package/dist/editor/components/PuckDataSynchronizer.js +126 -0
- package/dist/editor/components/PuckDataSynchronizer.js.map +1 -0
- package/dist/editor/components/PuckSelectionTracker.d.ts +47 -0
- package/dist/editor/components/PuckSelectionTracker.d.ts.map +1 -0
- package/dist/editor/components/PuckSelectionTracker.js +93 -0
- package/dist/editor/components/PuckSelectionTracker.js.map +1 -0
- package/dist/editor/components/SaveIndicator.d.ts +77 -0
- package/dist/editor/components/SaveIndicator.d.ts.map +1 -0
- package/dist/editor/components/SaveIndicator.js +114 -0
- package/dist/editor/components/SaveIndicator.js.map +1 -0
- package/dist/editor/components/Toast.d.ts +40 -0
- package/dist/editor/components/Toast.d.ts.map +1 -0
- package/dist/editor/components/Toast.js +92 -0
- package/dist/editor/components/Toast.js.map +1 -0
- package/dist/editor/components/VersionBannerOverride.d.ts +10 -0
- package/dist/editor/components/VersionBannerOverride.d.ts.map +1 -0
- package/dist/editor/components/VersionBannerOverride.js +22 -0
- package/dist/editor/components/VersionBannerOverride.js.map +1 -0
- package/dist/editor/components/connectable.d.ts +22 -0
- package/dist/editor/components/connectable.d.ts.map +1 -0
- package/dist/editor/components/connectable.js +84 -0
- package/dist/editor/components/connectable.js.map +1 -0
- package/dist/editor/components/merge-preview/MergePreviewPanel.d.ts +13 -0
- package/dist/editor/components/merge-preview/MergePreviewPanel.d.ts.map +1 -0
- package/dist/editor/components/merge-preview/MergePreviewPanel.js +32 -0
- package/dist/editor/components/merge-preview/MergePreviewPanel.js.map +1 -0
- package/dist/editor/components/merge-preview/MergePreviewRenderer.d.ts +58 -0
- package/dist/editor/components/merge-preview/MergePreviewRenderer.d.ts.map +1 -0
- package/dist/editor/components/merge-preview/MergePreviewRenderer.js +150 -0
- package/dist/editor/components/merge-preview/MergePreviewRenderer.js.map +1 -0
- package/dist/editor/components/merge-preview/ScaledContent.d.ts +11 -0
- package/dist/editor/components/merge-preview/ScaledContent.d.ts.map +1 -0
- package/dist/editor/components/merge-preview/ScaledContent.js +31 -0
- package/dist/editor/components/merge-preview/ScaledContent.js.map +1 -0
- package/dist/editor/components/merge-preview/ViewModeSelector.d.ts +8 -0
- package/dist/editor/components/merge-preview/ViewModeSelector.d.ts.map +1 -0
- package/dist/editor/components/merge-preview/ViewModeSelector.js +11 -0
- package/dist/editor/components/merge-preview/ViewModeSelector.js.map +1 -0
- package/dist/editor/components/merge-preview/index.d.ts +12 -0
- package/dist/editor/components/merge-preview/index.d.ts.map +1 -0
- package/dist/editor/components/merge-preview/index.js +9 -0
- package/dist/editor/components/merge-preview/index.js.map +1 -0
- package/dist/editor/composePlugins.d.ts +10 -0
- package/dist/editor/composePlugins.d.ts.map +1 -0
- package/dist/editor/composePlugins.js +47 -0
- package/dist/editor/composePlugins.js.map +1 -0
- package/dist/editor/defaultPlugins.d.ts +3 -0
- package/dist/editor/defaultPlugins.d.ts.map +1 -0
- package/dist/editor/defaultPlugins.js +7 -0
- package/dist/editor/defaultPlugins.js.map +1 -0
- package/dist/editor/icons/GenericThumbnailIcon.d.ts +3 -0
- package/dist/editor/icons/GenericThumbnailIcon.d.ts.map +1 -0
- package/dist/editor/icons/GenericThumbnailIcon.js +5 -0
- package/dist/editor/icons/GenericThumbnailIcon.js.map +1 -0
- package/dist/editor/icons/GripHandleIcon.d.ts +3 -0
- package/dist/editor/icons/GripHandleIcon.d.ts.map +1 -0
- package/dist/editor/icons/GripHandleIcon.js +5 -0
- package/dist/editor/icons/GripHandleIcon.js.map +1 -0
- package/dist/editor/icons/MergePreviewIcon.d.ts +3 -0
- package/dist/editor/icons/MergePreviewIcon.d.ts.map +1 -0
- package/dist/editor/icons/MergePreviewIcon.js +5 -0
- package/dist/editor/icons/MergePreviewIcon.js.map +1 -0
- package/dist/editor/icons/WarningTriangleIcon.d.ts +3 -0
- package/dist/editor/icons/WarningTriangleIcon.d.ts.map +1 -0
- package/dist/editor/icons/WarningTriangleIcon.js +5 -0
- package/dist/editor/icons/WarningTriangleIcon.js.map +1 -0
- package/dist/editor/icons/index.d.ts +5 -0
- package/dist/editor/icons/index.d.ts.map +1 -0
- package/dist/editor/icons/index.js +5 -0
- package/dist/editor/icons/index.js.map +1 -0
- package/dist/editor/index.d.ts +43 -0
- package/dist/editor/index.d.ts.map +1 -0
- package/dist/editor/index.js +30 -0
- package/dist/editor/index.js.map +1 -0
- package/dist/editor/plugin/P1Plugin.d.ts +161 -0
- package/dist/editor/plugin/P1Plugin.d.ts.map +1 -0
- package/dist/editor/plugin/P1Plugin.js +358 -0
- package/dist/editor/plugin/P1Plugin.js.map +1 -0
- package/dist/editor/plugin/createP1Overrides.d.ts +161 -0
- package/dist/editor/plugin/createP1Overrides.d.ts.map +1 -0
- package/dist/editor/plugin/createP1Overrides.js +103 -0
- package/dist/editor/plugin/createP1Overrides.js.map +1 -0
- package/dist/editor/plugin/index.d.ts +13 -0
- package/dist/editor/plugin/index.d.ts.map +1 -0
- package/dist/editor/plugin/index.js +10 -0
- package/dist/editor/plugin/index.js.map +1 -0
- package/dist/editor/plugin/mergePreviewPlugin.d.ts +9 -0
- package/dist/editor/plugin/mergePreviewPlugin.d.ts.map +1 -0
- package/dist/editor/plugin/mergePreviewPlugin.js +26 -0
- package/dist/editor/plugin/mergePreviewPlugin.js.map +1 -0
- package/dist/editor/presets.d.ts +8 -0
- package/dist/editor/presets.d.ts.map +1 -0
- package/dist/editor/presets.js +24 -0
- package/dist/editor/presets.js.map +1 -0
- package/dist/editor/useAutoSave.d.ts +37 -0
- package/dist/editor/useAutoSave.d.ts.map +1 -0
- package/dist/editor/useAutoSave.js +118 -0
- package/dist/editor/useAutoSave.js.map +1 -0
- package/dist/editor/useBranches.d.ts +67 -0
- package/dist/editor/useBranches.d.ts.map +1 -0
- package/dist/editor/useBranches.js +78 -0
- package/dist/editor/useBranches.js.map +1 -0
- package/dist/editor/useComponentRegistry.d.ts +31 -0
- package/dist/editor/useComponentRegistry.d.ts.map +1 -0
- package/dist/editor/useComponentRegistry.js +237 -0
- package/dist/editor/useComponentRegistry.js.map +1 -0
- package/dist/editor/useDocuments.d.ts +66 -0
- package/dist/editor/useDocuments.d.ts.map +1 -0
- package/dist/editor/useDocuments.js +112 -0
- package/dist/editor/useDocuments.js.map +1 -0
- package/dist/editor/useMergePreview.d.ts +15 -0
- package/dist/editor/useMergePreview.d.ts.map +1 -0
- package/dist/editor/useMergePreview.js +56 -0
- package/dist/editor/useMergePreview.js.map +1 -0
- package/dist/editor/useP1Editor.d.ts +125 -0
- package/dist/editor/useP1Editor.d.ts.map +1 -0
- package/dist/editor/useP1Editor.js +339 -0
- package/dist/editor/useP1Editor.js.map +1 -0
- package/dist/editor/useP1Overrides.d.ts +52 -0
- package/dist/editor/useP1Overrides.d.ts.map +1 -0
- package/dist/editor/useP1Overrides.js +74 -0
- package/dist/editor/useP1Overrides.js.map +1 -0
- package/dist/editor/useP1Plugin.d.ts +95 -0
- package/dist/editor/useP1Plugin.d.ts.map +1 -0
- package/dist/editor/useP1Plugin.js +112 -0
- package/dist/editor/useP1Plugin.js.map +1 -0
- package/dist/editor/useRealtime.d.ts +148 -0
- package/dist/editor/useRealtime.d.ts.map +1 -0
- package/dist/editor/useRealtime.js +244 -0
- package/dist/editor/useRealtime.js.map +1 -0
- package/dist/editor/utils/buildThumbnailOverride.d.ts +28 -0
- package/dist/editor/utils/buildThumbnailOverride.d.ts.map +1 -0
- package/dist/editor/utils/buildThumbnailOverride.js +39 -0
- package/dist/editor/utils/buildThumbnailOverride.js.map +1 -0
- package/dist/editor/utils/componentRegistry.d.ts +141 -0
- package/dist/editor/utils/componentRegistry.d.ts.map +1 -0
- package/dist/editor/utils/componentRegistry.js +238 -0
- package/dist/editor/utils/componentRegistry.js.map +1 -0
- package/dist/editor/utils/createStablePluginArray.d.ts +27 -0
- package/dist/editor/utils/createStablePluginArray.d.ts.map +1 -0
- package/dist/editor/utils/createStablePluginArray.js +40 -0
- package/dist/editor/utils/createStablePluginArray.js.map +1 -0
- package/dist/editor/utils/path.d.ts +2 -0
- package/dist/editor/utils/path.d.ts.map +1 -0
- package/dist/editor/utils/path.js +20 -0
- package/dist/editor/utils/path.js.map +1 -0
- package/dist/editor/utils/puckYjsBinding.d.ts +66 -0
- package/dist/editor/utils/puckYjsBinding.d.ts.map +1 -0
- package/dist/editor/utils/puckYjsBinding.js +272 -0
- package/dist/editor/utils/puckYjsBinding.js.map +1 -0
- package/dist/index.d.ts +121 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/merge/components/conflict-notifications/ConflictNotificationToast.d.ts +35 -0
- package/dist/merge/components/conflict-notifications/ConflictNotificationToast.d.ts.map +1 -0
- package/dist/merge/components/conflict-notifications/ConflictNotificationToast.js +59 -0
- package/dist/merge/components/conflict-notifications/ConflictNotificationToast.js.map +1 -0
- package/dist/merge/components/conflict-notifications/index.d.ts +10 -0
- package/dist/merge/components/conflict-notifications/index.d.ts.map +1 -0
- package/dist/merge/components/conflict-notifications/index.js +8 -0
- package/dist/merge/components/conflict-notifications/index.js.map +1 -0
- package/dist/merge/components/conflict-notifications/useConflictNotifications.d.ts +69 -0
- package/dist/merge/components/conflict-notifications/useConflictNotifications.d.ts.map +1 -0
- package/dist/merge/components/conflict-notifications/useConflictNotifications.js +151 -0
- package/dist/merge/components/conflict-notifications/useConflictNotifications.js.map +1 -0
- package/dist/merge/components/conflict-resolution/ComponentConflictGroup.d.ts +55 -0
- package/dist/merge/components/conflict-resolution/ComponentConflictGroup.d.ts.map +1 -0
- package/dist/merge/components/conflict-resolution/ComponentConflictGroup.js +112 -0
- package/dist/merge/components/conflict-resolution/ComponentConflictGroup.js.map +1 -0
- package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.d.ts +51 -0
- package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.d.ts.map +1 -0
- package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.js +75 -0
- package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.js.map +1 -0
- package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.d.ts +37 -0
- package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.d.ts.map +1 -0
- package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.js +42 -0
- package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.js.map +1 -0
- package/dist/merge/components/conflict-resolution/index.d.ts +12 -0
- package/dist/merge/components/conflict-resolution/index.d.ts.map +1 -0
- package/dist/merge/components/conflict-resolution/index.js +9 -0
- package/dist/merge/components/conflict-resolution/index.js.map +1 -0
- package/dist/merge/components/merge-resolution/CherryPickVisualPanel.d.ts +44 -0
- package/dist/merge/components/merge-resolution/CherryPickVisualPanel.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js +186 -0
- package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js.map +1 -0
- package/dist/merge/components/merge-resolution/ComponentClickOverlay.d.ts +34 -0
- package/dist/merge/components/merge-resolution/ComponentClickOverlay.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/ComponentClickOverlay.js +141 -0
- package/dist/merge/components/merge-resolution/ComponentClickOverlay.js.map +1 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionDetail.d.ts +26 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionDetail.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js +167 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js.map +1 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionList.d.ts +21 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionList.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionList.js +106 -0
- package/dist/merge/components/merge-resolution/DocumentResolutionList.js.map +1 -0
- package/dist/merge/components/merge-resolution/MergeResolutionPage.d.ts +15 -0
- package/dist/merge/components/merge-resolution/MergeResolutionPage.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/MergeResolutionPage.js +90 -0
- package/dist/merge/components/merge-resolution/MergeResolutionPage.js.map +1 -0
- package/dist/merge/components/merge-resolution/MergeResolutionToolbar.d.ts +26 -0
- package/dist/merge/components/merge-resolution/MergeResolutionToolbar.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/MergeResolutionToolbar.js +23 -0
- package/dist/merge/components/merge-resolution/MergeResolutionToolbar.js.map +1 -0
- package/dist/merge/components/merge-resolution/MergeReviewPage.d.ts +11 -0
- package/dist/merge/components/merge-resolution/MergeReviewPage.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/MergeReviewPage.js +26 -0
- package/dist/merge/components/merge-resolution/MergeReviewPage.js.map +1 -0
- package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.d.ts +16 -0
- package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.js +15 -0
- package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.js.map +1 -0
- package/dist/merge/components/merge-resolution/index.d.ts +20 -0
- package/dist/merge/components/merge-resolution/index.d.ts.map +1 -0
- package/dist/merge/components/merge-resolution/index.js +12 -0
- package/dist/merge/components/merge-resolution/index.js.map +1 -0
- package/dist/merge/index.d.ts +8 -0
- package/dist/merge/index.d.ts.map +1 -0
- package/dist/merge/index.js +6 -0
- package/dist/merge/index.js.map +1 -0
- package/dist/merge/useMergeResolution.d.ts +65 -0
- package/dist/merge/useMergeResolution.d.ts.map +1 -0
- package/dist/merge/useMergeResolution.js +444 -0
- package/dist/merge/useMergeResolution.js.map +1 -0
- package/dist/merge/utils/puckFieldClassifier.d.ts +151 -0
- package/dist/merge/utils/puckFieldClassifier.d.ts.map +1 -0
- package/dist/merge/utils/puckFieldClassifier.js +427 -0
- package/dist/merge/utils/puckFieldClassifier.js.map +1 -0
- package/dist/p1/editor/client.d.ts +17 -0
- package/dist/p1/editor/client.d.ts.map +1 -0
- package/dist/p1/editor/client.js +79 -0
- package/dist/p1/editor/client.js.map +1 -0
- package/dist/p1/editor/connect/connect-field-modal.d.ts +11 -0
- package/dist/p1/editor/connect/connect-field-modal.d.ts.map +1 -0
- package/dist/p1/editor/connect/connect-field-modal.js +127 -0
- package/dist/p1/editor/connect/connect-field-modal.js.map +1 -0
- package/dist/p1/editor/connect/connect-preview-config.d.ts +7 -0
- package/dist/p1/editor/connect/connect-preview-config.d.ts.map +1 -0
- package/dist/p1/editor/connect/connect-preview-config.js +76 -0
- package/dist/p1/editor/connect/connect-preview-config.js.map +1 -0
- package/dist/p1/editor/connect/field-connect-plugin.d.ts +10 -0
- package/dist/p1/editor/connect/field-connect-plugin.d.ts.map +1 -0
- package/dist/p1/editor/connect/field-connect-plugin.js +46 -0
- package/dist/p1/editor/connect/field-connect-plugin.js.map +1 -0
- package/dist/p1/editor/editor-preview-resolve.d.ts +11 -0
- package/dist/p1/editor/editor-preview-resolve.d.ts.map +1 -0
- package/dist/p1/editor/editor-preview-resolve.js +115 -0
- package/dist/p1/editor/editor-preview-resolve.js.map +1 -0
- package/dist/p1/editor/hooks.d.ts +42 -0
- package/dist/p1/editor/hooks.d.ts.map +1 -0
- package/dist/p1/editor/hooks.js +219 -0
- package/dist/p1/editor/hooks.js.map +1 -0
- package/dist/p1/editor/icons/button-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/button-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/button-block-icon.js +5 -0
- package/dist/p1/editor/icons/button-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/default-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/default-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/default-block-icon.js +5 -0
- package/dist/p1/editor/icons/default-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/divider-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/divider-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/divider-block-icon.js +5 -0
- package/dist/p1/editor/icons/divider-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/grid-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/grid-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/grid-block-icon.js +5 -0
- package/dist/p1/editor/icons/grid-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/heading-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/heading-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/heading-block-icon.js +5 -0
- package/dist/p1/editor/icons/heading-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/image-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/image-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/image-block-icon.js +5 -0
- package/dist/p1/editor/icons/image-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/list-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/list-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/list-block-icon.js +5 -0
- package/dist/p1/editor/icons/list-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/paragraph-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/paragraph-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/paragraph-block-icon.js +5 -0
- package/dist/p1/editor/icons/paragraph-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/quote-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/quote-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/quote-block-icon.js +5 -0
- package/dist/p1/editor/icons/quote-block-icon.js.map +1 -0
- package/dist/p1/editor/icons/spacer-block-icon.d.ts +2 -0
- package/dist/p1/editor/icons/spacer-block-icon.d.ts.map +1 -0
- package/dist/p1/editor/icons/spacer-block-icon.js +5 -0
- package/dist/p1/editor/icons/spacer-block-icon.js.map +1 -0
- package/dist/p1/editor/index.d.ts +9 -0
- package/dist/p1/editor/index.d.ts.map +1 -0
- package/dist/p1/editor/index.js +9 -0
- package/dist/p1/editor/index.js.map +1 -0
- package/dist/p1/editor/json-tree.d.ts +6 -0
- package/dist/p1/editor/json-tree.d.ts.map +1 -0
- package/dist/p1/editor/json-tree.js +64 -0
- package/dist/p1/editor/json-tree.js.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.d.ts +11 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.d.ts.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js +62 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts +23 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.js +39 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.js.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts +4 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts.map +1 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-manager.js +72 -0
- package/dist/p1/editor/remote-datasources/remote-datasource-manager.js.map +1 -0
- package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts +6 -0
- package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts.map +1 -0
- package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js +67 -0
- package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js.map +1 -0
- package/dist/p1/editor/template-autocomplete-layer.d.ts +11 -0
- package/dist/p1/editor/template-autocomplete-layer.d.ts.map +1 -0
- package/dist/p1/editor/template-autocomplete-layer.js +386 -0
- package/dist/p1/editor/template-autocomplete-layer.js.map +1 -0
- package/dist/p1/pages/add-override-for-template.d.ts +4 -0
- package/dist/p1/pages/add-override-for-template.d.ts.map +1 -0
- package/dist/p1/pages/add-override-for-template.js +47 -0
- package/dist/p1/pages/add-override-for-template.js.map +1 -0
- package/dist/p1/pages/create-page-form.d.ts +2 -0
- package/dist/p1/pages/create-page-form.d.ts.map +1 -0
- package/dist/p1/pages/create-page-form.js +28 -0
- package/dist/p1/pages/create-page-form.js.map +1 -0
- package/dist/p1/pages/create-template-form.d.ts +2 -0
- package/dist/p1/pages/create-template-form.d.ts.map +1 -0
- package/dist/p1/pages/create-template-form.js +36 -0
- package/dist/p1/pages/create-template-form.js.map +1 -0
- package/dist/p1/pages/delete-row-button.d.ts +7 -0
- package/dist/p1/pages/delete-row-button.d.ts.map +1 -0
- package/dist/p1/pages/delete-row-button.js +23 -0
- package/dist/p1/pages/delete-row-button.js.map +1 -0
- package/dist/p1/pages/hooks.d.ts +5 -0
- package/dist/p1/pages/hooks.d.ts.map +1 -0
- package/dist/p1/pages/hooks.js +55 -0
- package/dist/p1/pages/hooks.js.map +1 -0
- package/dist/p1/pages/index.d.ts +7 -0
- package/dist/p1/pages/index.d.ts.map +1 -0
- package/dist/p1/pages/index.js +7 -0
- package/dist/p1/pages/index.js.map +1 -0
- package/dist/p1/pages/render-client.d.ts +6 -0
- package/dist/p1/pages/render-client.d.ts.map +1 -0
- package/dist/p1/pages/render-client.js +7 -0
- package/dist/p1/pages/render-client.js.map +1 -0
- package/dist/p1/pages/structure-page.d.ts +2 -0
- package/dist/p1/pages/structure-page.d.ts.map +1 -0
- package/dist/p1/pages/structure-page.js +46 -0
- package/dist/p1/pages/structure-page.js.map +1 -0
- package/dist/p1/router-context.d.ts +11 -0
- package/dist/p1/router-context.d.ts.map +1 -0
- package/dist/p1/router-context.js +11 -0
- package/dist/p1/router-context.js.map +1 -0
- package/dist/pds/components/AgentChip.d.ts +26 -0
- package/dist/pds/components/AgentChip.d.ts.map +1 -0
- package/dist/pds/components/AgentChip.js +15 -0
- package/dist/pds/components/AgentChip.js.map +1 -0
- package/dist/pds/components/AgentChip.module.css +141 -0
- package/dist/pds/components/DocStateBadge.d.ts +7 -0
- package/dist/pds/components/DocStateBadge.d.ts.map +1 -0
- package/dist/pds/components/DocStateBadge.js +24 -0
- package/dist/pds/components/DocStateBadge.js.map +1 -0
- package/dist/pds/components/NavIcon.d.ts +7 -0
- package/dist/pds/components/NavIcon.d.ts.map +1 -0
- package/dist/pds/components/NavIcon.js +6 -0
- package/dist/pds/components/NavIcon.js.map +1 -0
- package/dist/pds/components/P1EditorHeader.d.ts +41 -0
- package/dist/pds/components/P1EditorHeader.d.ts.map +1 -0
- package/dist/pds/components/P1EditorHeader.js +138 -0
- package/dist/pds/components/P1EditorHeader.js.map +1 -0
- package/dist/pds/components/P1EditorHeader.module.css +253 -0
- package/dist/pds/components/P1EditorSubheader.d.ts +42 -0
- package/dist/pds/components/P1EditorSubheader.d.ts.map +1 -0
- package/dist/pds/components/P1EditorSubheader.js +27 -0
- package/dist/pds/components/P1EditorSubheader.js.map +1 -0
- package/dist/pds/components/P1EditorSubheader.module.css +81 -0
- package/dist/pds/components/PageNavigator.d.ts +38 -0
- package/dist/pds/components/PageNavigator.d.ts.map +1 -0
- package/dist/pds/components/PageNavigator.js +60 -0
- package/dist/pds/components/PageNavigator.js.map +1 -0
- package/dist/pds/components/PageNavigator.module.css +276 -0
- package/dist/pds/components/PresenceStack.d.ts +17 -0
- package/dist/pds/components/PresenceStack.d.ts.map +1 -0
- package/dist/pds/components/PresenceStack.js +14 -0
- package/dist/pds/components/PresenceStack.js.map +1 -0
- package/dist/pds/components/PresenceStack.module.css +48 -0
- package/dist/pds/components/PublishControl.d.ts +15 -0
- package/dist/pds/components/PublishControl.d.ts.map +1 -0
- package/dist/pds/components/PublishControl.js +46 -0
- package/dist/pds/components/PublishControl.js.map +1 -0
- package/dist/pds/components/PublishControl.module.css +36 -0
- package/dist/pds/components/WorkstreamSwitcher.d.ts +26 -0
- package/dist/pds/components/WorkstreamSwitcher.d.ts.map +1 -0
- package/dist/pds/components/WorkstreamSwitcher.js +134 -0
- package/dist/pds/components/WorkstreamSwitcher.js.map +1 -0
- package/dist/pds/components/WorkstreamSwitcher.module.css +320 -0
- package/dist/pds/index.d.ts +33 -0
- package/dist/pds/index.d.ts.map +1 -0
- package/dist/pds/index.js +46 -0
- package/dist/pds/index.js.map +1 -0
- package/dist/pds/theme/pds-core-content.d.ts +2 -0
- package/dist/pds/theme/pds-core-content.d.ts.map +1 -0
- package/dist/pds/theme/pds-core-content.js +8 -0
- package/dist/pds/theme/pds-core-content.js.map +1 -0
- package/dist/pds/types.d.ts +7 -0
- package/dist/pds/types.d.ts.map +1 -0
- package/dist/pds/types.js +2 -0
- package/dist/pds/types.js.map +1 -0
- package/dist/pds/utils/deriveDocState.d.ts +8 -0
- package/dist/pds/utils/deriveDocState.d.ts.map +1 -0
- package/dist/pds/utils/deriveDocState.js +14 -0
- package/dist/pds/utils/deriveDocState.js.map +1 -0
- package/dist/server.d.ts +23 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +24 -0
- package/dist/server.js.map +1 -0
- package/dist/versioning/components/HistoricalVersionBanner.d.ts +28 -0
- package/dist/versioning/components/HistoricalVersionBanner.d.ts.map +1 -0
- package/dist/versioning/components/HistoricalVersionBanner.js +23 -0
- package/dist/versioning/components/HistoricalVersionBanner.js.map +1 -0
- package/dist/versioning/components/VersionPublishedBadge.d.ts +5 -0
- package/dist/versioning/components/VersionPublishedBadge.d.ts.map +1 -0
- package/dist/versioning/components/VersionPublishedBadge.js +8 -0
- package/dist/versioning/components/VersionPublishedBadge.js.map +1 -0
- package/dist/versioning/components/version-compare/BranchDiffHeader.d.ts +53 -0
- package/dist/versioning/components/version-compare/BranchDiffHeader.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/BranchDiffHeader.js +15 -0
- package/dist/versioning/components/version-compare/BranchDiffHeader.js.map +1 -0
- package/dist/versioning/components/version-compare/BranchMergeCompare.d.ts +43 -0
- package/dist/versioning/components/version-compare/BranchMergeCompare.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/BranchMergeCompare.js +70 -0
- package/dist/versioning/components/version-compare/BranchMergeCompare.js.map +1 -0
- package/dist/versioning/components/version-compare/ComponentNode.d.ts +34 -0
- package/dist/versioning/components/version-compare/ComponentNode.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/ComponentNode.js +40 -0
- package/dist/versioning/components/version-compare/ComponentNode.js.map +1 -0
- package/dist/versioning/components/version-compare/ComponentTree.d.ts +34 -0
- package/dist/versioning/components/version-compare/ComponentTree.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/ComponentTree.js +35 -0
- package/dist/versioning/components/version-compare/ComponentTree.js.map +1 -0
- package/dist/versioning/components/version-compare/DiffHeader.d.ts +45 -0
- package/dist/versioning/components/version-compare/DiffHeader.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/DiffHeader.js +11 -0
- package/dist/versioning/components/version-compare/DiffHeader.js.map +1 -0
- package/dist/versioning/components/version-compare/DocumentDiffList.d.ts +39 -0
- package/dist/versioning/components/version-compare/DocumentDiffList.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/DocumentDiffList.js +32 -0
- package/dist/versioning/components/version-compare/DocumentDiffList.js.map +1 -0
- package/dist/versioning/components/version-compare/PropDiffPanel.d.ts +30 -0
- package/dist/versioning/components/version-compare/PropDiffPanel.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/PropDiffPanel.js +34 -0
- package/dist/versioning/components/version-compare/PropDiffPanel.js.map +1 -0
- package/dist/versioning/components/version-compare/PropDiffRow.d.ts +22 -0
- package/dist/versioning/components/version-compare/PropDiffRow.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/PropDiffRow.js +12 -0
- package/dist/versioning/components/version-compare/PropDiffRow.js.map +1 -0
- package/dist/versioning/components/version-compare/PropValueDisplay.d.ts +36 -0
- package/dist/versioning/components/version-compare/PropValueDisplay.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/PropValueDisplay.js +79 -0
- package/dist/versioning/components/version-compare/PropValueDisplay.js.map +1 -0
- package/dist/versioning/components/version-compare/VersionComparePage.d.ts +34 -0
- package/dist/versioning/components/version-compare/VersionComparePage.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/VersionComparePage.js +61 -0
- package/dist/versioning/components/version-compare/VersionComparePage.js.map +1 -0
- package/dist/versioning/components/version-compare/VisualBranchCompare.d.ts +41 -0
- package/dist/versioning/components/version-compare/VisualBranchCompare.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/VisualBranchCompare.js +84 -0
- package/dist/versioning/components/version-compare/VisualBranchCompare.js.map +1 -0
- package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts +67 -0
- package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/VisualVersionCompare.js +84 -0
- package/dist/versioning/components/version-compare/VisualVersionCompare.js.map +1 -0
- package/dist/versioning/components/version-compare/index.d.ts +30 -0
- package/dist/versioning/components/version-compare/index.d.ts.map +1 -0
- package/dist/versioning/components/version-compare/index.js +18 -0
- package/dist/versioning/components/version-compare/index.js.map +1 -0
- package/dist/versioning/components/version-history/AgentCheckpointBadge.d.ts +22 -0
- package/dist/versioning/components/version-history/AgentCheckpointBadge.d.ts.map +1 -0
- package/dist/versioning/components/version-history/AgentCheckpointBadge.js +55 -0
- package/dist/versioning/components/version-history/AgentCheckpointBadge.js.map +1 -0
- package/dist/versioning/components/version-history/VersionItem.d.ts +30 -0
- package/dist/versioning/components/version-history/VersionItem.d.ts.map +1 -0
- package/dist/versioning/components/version-history/VersionItem.js +39 -0
- package/dist/versioning/components/version-history/VersionItem.js.map +1 -0
- package/dist/versioning/components/version-history/index.d.ts +10 -0
- package/dist/versioning/components/version-history/index.d.ts.map +1 -0
- package/dist/versioning/components/version-history/index.js +8 -0
- package/dist/versioning/components/version-history/index.js.map +1 -0
- package/dist/versioning/index.d.ts +17 -0
- package/dist/versioning/index.d.ts.map +1 -0
- package/dist/versioning/index.js +10 -0
- package/dist/versioning/index.js.map +1 -0
- package/dist/versioning/useCheckpoints.d.ts +66 -0
- package/dist/versioning/useCheckpoints.d.ts.map +1 -0
- package/dist/versioning/useCheckpoints.js +100 -0
- package/dist/versioning/useCheckpoints.js.map +1 -0
- package/dist/versioning/useVersions.d.ts +81 -0
- package/dist/versioning/useVersions.d.ts.map +1 -0
- package/dist/versioning/useVersions.js +110 -0
- package/dist/versioning/useVersions.js.map +1 -0
- package/dist/versioning/utils/branchDiff.d.ts +136 -0
- package/dist/versioning/utils/branchDiff.d.ts.map +1 -0
- package/dist/versioning/utils/branchDiff.js +172 -0
- package/dist/versioning/utils/branchDiff.js.map +1 -0
- package/dist/versioning/utils/diff.d.ts +63 -0
- package/dist/versioning/utils/diff.d.ts.map +1 -0
- package/dist/versioning/utils/diff.js +318 -0
- package/dist/versioning/utils/diff.js.map +1 -0
- package/dist/versioning/utils/highlightConfig.d.ts +41 -0
- package/dist/versioning/utils/highlightConfig.d.ts.map +1 -0
- package/dist/versioning/utils/highlightConfig.js +130 -0
- package/dist/versioning/utils/highlightConfig.js.map +1 -0
- package/package.json +113 -0
- package/src/pds/theme/PuckEditorTheme.css +277 -0
- package/src/pds/theme/PuckEditorTheme.test.ts +136 -0
- package/src/pds/theme/pds-core-content.ts +7 -0
- package/src/pds/theme/pds-core.css +2 -0
- package/src/styles.css +2366 -0
|
@@ -0,0 +1,1473 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* P1 Puck Provider
|
|
4
|
+
*
|
|
5
|
+
* React context provider for P1 Puck integration.
|
|
6
|
+
*/
|
|
7
|
+
import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
|
|
8
|
+
import { P1PuckContext } from '../core/P1PuckContext.js';
|
|
9
|
+
import { NotificationProvider, useNotifications } from '../core/NotificationContext.js';
|
|
10
|
+
import { PresenceContext } from '../core/PresenceContext.js';
|
|
11
|
+
import { debounce } from '../core/utils/debounce.js';
|
|
12
|
+
import { withRetry } from '../core/utils/retry.js';
|
|
13
|
+
import { useRealtime } from './useRealtime.js';
|
|
14
|
+
import { useDocuments } from './useDocuments.js';
|
|
15
|
+
import { resolveFeatureConfig } from '../core/featureConfig.js';
|
|
16
|
+
import { resolveActivePlugins, composeProviders } from './composePlugins.js';
|
|
17
|
+
import { DEFAULT_CSS_FEATURE_PLUGINS } from './defaultPlugins.js';
|
|
18
|
+
/**
|
|
19
|
+
* Provider component for P1 Puck integration.
|
|
20
|
+
*
|
|
21
|
+
* Wraps your Puck editor to provide P1 functionality including:
|
|
22
|
+
* - Auto-save with debouncing
|
|
23
|
+
* - Document loading
|
|
24
|
+
* - Checkpoint (publish) creation
|
|
25
|
+
* - Branch switching
|
|
26
|
+
* - Toast notifications for errors and success
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* ```tsx
|
|
30
|
+
* import { P1PuckProvider, P1PuckEditor } from '@pantheon-systems/puck-css';
|
|
31
|
+
* import { P1Client } from '@pantheon-systems/css-client';
|
|
32
|
+
*
|
|
33
|
+
* const client = new P1Client({
|
|
34
|
+
* baseUrl: 'http://localhost:8787',
|
|
35
|
+
* apiKey: 'your-api-key',
|
|
36
|
+
* });
|
|
37
|
+
*
|
|
38
|
+
* function App() {
|
|
39
|
+
* return (
|
|
40
|
+
* <P1PuckProvider
|
|
41
|
+
* client={client}
|
|
42
|
+
* siteId="site-123"
|
|
43
|
+
* branchId="branch-456"
|
|
44
|
+
* userId="user-789"
|
|
45
|
+
* >
|
|
46
|
+
* <P1PuckEditor config={puckConfig} documentPath="/home" />
|
|
47
|
+
* </P1PuckProvider>
|
|
48
|
+
* );
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export function P1PuckProvider(props) {
|
|
53
|
+
return (_jsx(NotificationProvider, { children: _jsx(P1PuckProviderInner, { ...props }) }));
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Inner provider component that has access to notification context.
|
|
57
|
+
*/
|
|
58
|
+
function P1PuckProviderInner({ client, siteId, branchId: initialBranchId, userId, autoSaveDelay = 3000, maxRetries = 3, showErrorNotifications = true, enableRealtime = true, wsBaseUrl, realtimeApiKey, realtimeSyncInterval: _realtimeSyncInterval = 250, realtimeTokenRefresher,
|
|
59
|
+
// Phase 9: Presence props
|
|
60
|
+
presenceEnabled = true, presencePollingInterval = 5000, userName: _userName, userAvatar: _userAvatar, userNameResolver,
|
|
61
|
+
// Phase 9: Agent mode props
|
|
62
|
+
agentModeEnabled = false, agentId, agentTrigger: _agentTrigger,
|
|
63
|
+
// Phase 9: Callbacks
|
|
64
|
+
onPresenceChange, onAgentConflict: _onAgentConflict,
|
|
65
|
+
// Plugin system props (B.4)
|
|
66
|
+
featurePlugins, featureConfig, children, }) {
|
|
67
|
+
// Access notification context
|
|
68
|
+
const notificationContext = useNotifications();
|
|
69
|
+
// Persist selected branch in sessionStorage so it survives provider remounts
|
|
70
|
+
// (e.g. when P1App is rendered per-page instead of in a shared layout).
|
|
71
|
+
const branchStorageKey = `css-branch-${siteId}`;
|
|
72
|
+
const getPersistedBranchId = useCallback(() => {
|
|
73
|
+
try {
|
|
74
|
+
return (typeof window !== 'undefined' && sessionStorage.getItem(branchStorageKey)) || '';
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
}, [branchStorageKey]);
|
|
80
|
+
const persistBranchId = useCallback((id) => {
|
|
81
|
+
try {
|
|
82
|
+
if (typeof window !== 'undefined') {
|
|
83
|
+
sessionStorage.setItem(branchStorageKey, id);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// sessionStorage may be unavailable (SSR, privacy mode)
|
|
88
|
+
}
|
|
89
|
+
}, [branchStorageKey]);
|
|
90
|
+
// Site name — fetched once on mount from the P1 API
|
|
91
|
+
const [siteName, setSiteName] = useState(null);
|
|
92
|
+
useEffect(() => {
|
|
93
|
+
client.sites?.get(siteId)
|
|
94
|
+
?.then((site) => setSiteName(site.name))
|
|
95
|
+
.catch(() => { });
|
|
96
|
+
}, [client, siteId]);
|
|
97
|
+
// Branch state - start with initialBranchId, persisted branch, or empty (will be set to main)
|
|
98
|
+
const [branchId, setBranchId] = useState(() => {
|
|
99
|
+
if (initialBranchId)
|
|
100
|
+
return initialBranchId;
|
|
101
|
+
try {
|
|
102
|
+
return (typeof window !== 'undefined' && sessionStorage.getItem(branchStorageKey)) || '';
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return '';
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
const [branches, setBranches] = useState([]);
|
|
109
|
+
const [currentBranch, setCurrentBranch] = useState(null);
|
|
110
|
+
const [branchesLoading, setBranchesLoading] = useState(() => {
|
|
111
|
+
if (initialBranchId)
|
|
112
|
+
return false;
|
|
113
|
+
try {
|
|
114
|
+
return !(typeof window !== 'undefined' && sessionStorage.getItem(branchStorageKey));
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
// Document state
|
|
121
|
+
const [currentDocument, setCurrentDocument] = useState(null);
|
|
122
|
+
const [currentData, setCurrentData] = useState(null);
|
|
123
|
+
// Save state
|
|
124
|
+
const [saveStatus, setSaveStatus] = useState('idle');
|
|
125
|
+
const [lastSaved, setLastSaved] = useState(null);
|
|
126
|
+
const [saveError, setSaveError] = useState(null);
|
|
127
|
+
// Pending data for debounced save - use ref to avoid recreating debounce
|
|
128
|
+
const pendingDataRef = useRef(null);
|
|
129
|
+
const currentDocumentRef = useRef(null);
|
|
130
|
+
const initializedRef = useRef(false);
|
|
131
|
+
// Track the latest Puck action metadata for inclusion in sync payloads.
|
|
132
|
+
// Set by handleAction (Puck's onAction callback), consumed by saveData
|
|
133
|
+
// when sending changes via realtime, then cleared.
|
|
134
|
+
const lastActionRef = useRef(null);
|
|
135
|
+
// Tracks the document path that the current data in state belongs to.
|
|
136
|
+
// Set alongside every setCurrentData call to record the data's origin.
|
|
137
|
+
// Checked before every write (realtime or REST) to prevent cross-document
|
|
138
|
+
// corruption during rapid document switching.
|
|
139
|
+
const currentDataDocumentPathRef = useRef(null);
|
|
140
|
+
// Suppresses the next saveData call after loadDocument completes.
|
|
141
|
+
// PuckDataSynchronizer dispatches setData into Puck, which fires onChange,
|
|
142
|
+
// which calls saveData — but this is just echoing the loaded data, not a
|
|
143
|
+
// user edit. This flag prevents that echo from triggering a false save.
|
|
144
|
+
const suppressNextSaveRef = useRef(false);
|
|
145
|
+
// Monotonically increasing counter for stale loadDocument response detection.
|
|
146
|
+
// Each loadDocument call increments this and captures the current value.
|
|
147
|
+
// After each async operation, the captured value is compared to the current
|
|
148
|
+
// value — if they differ, a newer loadDocument call has started and the
|
|
149
|
+
// current one should bail out.
|
|
150
|
+
const loadRequestIdRef = useRef(0);
|
|
151
|
+
// Track realtime connection state for use in performSave (avoids stale closure)
|
|
152
|
+
const realtimeConnectedRef = useRef(false);
|
|
153
|
+
// Auto-save pause state
|
|
154
|
+
const [autoSavePaused, setAutoSavePaused] = useState(false);
|
|
155
|
+
// Version viewing state
|
|
156
|
+
const [viewingVersion, setViewingVersion] = useState(null);
|
|
157
|
+
const [latestVersionData, setLatestVersionData] = useState(null);
|
|
158
|
+
// Remote sync key - changes when remote updates arrive to trigger Puck sync
|
|
159
|
+
const [remoteSyncKey, setRemoteSyncKey] = useState(null);
|
|
160
|
+
// Counter to track pending remote updates that will trigger onChange callbacks.
|
|
161
|
+
// When we receive a remote update and sync it to Puck via setData, Puck fires onChange.
|
|
162
|
+
// We need to skip the realtime send for that onChange to prevent bounce-back loops.
|
|
163
|
+
// Using a counter is more reliable than a timeout because it's synchronized with
|
|
164
|
+
// the actual number of remote updates received.
|
|
165
|
+
const pendingRemoteUpdatesRef = useRef(0);
|
|
166
|
+
// Flag to track if we're currently applying a remote sync.
|
|
167
|
+
// This is set before setCurrentData and cleared after a short delay to ensure
|
|
168
|
+
// all related onChange events are skipped (there may be multiple: one from data
|
|
169
|
+
// prop change and one from setData dispatch).
|
|
170
|
+
// Pending remote data ref - stores latest data during debounce period
|
|
171
|
+
const pendingRemoteDataRef = useRef(null);
|
|
172
|
+
// Debounce timer for remote sync - batches rapid updates to reduce flickering
|
|
173
|
+
const remoteSyncTimerRef = useRef(null);
|
|
174
|
+
// Delay for debouncing remote sync updates (ms)
|
|
175
|
+
const REMOTE_SYNC_DEBOUNCE_DELAY = 50;
|
|
176
|
+
// Ref to track viewingVersion for use in callbacks (avoids stale closure)
|
|
177
|
+
const viewingVersionRef = useRef(null);
|
|
178
|
+
// Helper to cancel any pending remote sync - used when loading documents/versions
|
|
179
|
+
// This prevents race conditions where a pending remote update overrides loaded data
|
|
180
|
+
const cancelPendingRemoteSync = useCallback(() => {
|
|
181
|
+
if (remoteSyncTimerRef.current) {
|
|
182
|
+
clearTimeout(remoteSyncTimerRef.current);
|
|
183
|
+
remoteSyncTimerRef.current = null;
|
|
184
|
+
}
|
|
185
|
+
pendingRemoteDataRef.current = null;
|
|
186
|
+
}, []);
|
|
187
|
+
// WebSocket presence state - used when realtime is connected for instant presence updates
|
|
188
|
+
const [wsPresenceActors, setWsPresenceActors] = useState([]);
|
|
189
|
+
const [wsPresenceActive, setWsPresenceActive] = useState(false);
|
|
190
|
+
// Helper to enrich actors with display names from the resolver
|
|
191
|
+
const enrichActorsWithNames = useCallback((actors) => {
|
|
192
|
+
if (!userNameResolver)
|
|
193
|
+
return actors;
|
|
194
|
+
return actors.map((actor) => {
|
|
195
|
+
const resolvedName = userNameResolver(actor.actorId);
|
|
196
|
+
return resolvedName ? { ...actor, name: resolvedName } : actor;
|
|
197
|
+
});
|
|
198
|
+
}, [userNameResolver]);
|
|
199
|
+
// Real-time collaboration hook
|
|
200
|
+
const realtime = useRealtime({
|
|
201
|
+
baseUrl: wsBaseUrl ?? '',
|
|
202
|
+
apiKey: realtimeApiKey,
|
|
203
|
+
tokenRefresher: realtimeTokenRefresher,
|
|
204
|
+
siteId,
|
|
205
|
+
branchId,
|
|
206
|
+
documentPath: currentDocument?.path ?? null,
|
|
207
|
+
actorId: userId,
|
|
208
|
+
actorType: 'user',
|
|
209
|
+
enabled: enableRealtime && !!wsBaseUrl,
|
|
210
|
+
initialData: currentData,
|
|
211
|
+
// WebSocket presence callbacks - receive instant presence updates
|
|
212
|
+
onPresenceUpdate: (actors) => {
|
|
213
|
+
// Mark WebSocket presence as active (first update received)
|
|
214
|
+
setWsPresenceActive(true);
|
|
215
|
+
// Filter out self, enrich with names, and update state
|
|
216
|
+
const filtered = actors.filter((a) => a.actorId !== userId);
|
|
217
|
+
const enriched = enrichActorsWithNames(filtered);
|
|
218
|
+
setWsPresenceActors(enriched);
|
|
219
|
+
},
|
|
220
|
+
onFocusRegionBroadcast: (actorId, focusRegions) => {
|
|
221
|
+
// Update focus regions for the specific actor
|
|
222
|
+
setWsPresenceActors((prev) => prev.map((a) => (a.actorId === actorId ? { ...a, focusRegions } : a)));
|
|
223
|
+
},
|
|
224
|
+
onRemoteUpdate: (data) => {
|
|
225
|
+
const componentCount = data.content?.length ?? 0;
|
|
226
|
+
const zoneCount = data.zones ? Object.keys(data.zones).length : 0;
|
|
227
|
+
console.log('[P1PuckProvider] onRemoteUpdate received:', `components=${componentCount}, zones=${zoneCount},`, `pendingRemoteUpdates=${pendingRemoteUpdatesRef.current},`, `viewingVersion=${viewingVersionRef.current !== null}`);
|
|
228
|
+
// Don't apply remote updates while viewing a historical version
|
|
229
|
+
// The user is viewing read-only historical data and shouldn't see live changes
|
|
230
|
+
if (viewingVersionRef.current !== null) {
|
|
231
|
+
console.log('[P1PuckProvider] onRemoteUpdate SKIPPED: viewing historical version');
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
// Reject empty data that would overwrite real editor content.
|
|
235
|
+
// During initial Yjs sync, the remote doc may be empty, producing
|
|
236
|
+
// { content: [], root: { props: {} } }. Applying this would clear
|
|
237
|
+
// the editor and trigger a save loop.
|
|
238
|
+
const rootProps = data.root.props;
|
|
239
|
+
if (data.content.length === 0 &&
|
|
240
|
+
(!rootProps || Object.keys(rootProps).length === 0) &&
|
|
241
|
+
!data.zones) {
|
|
242
|
+
console.log('[P1PuckProvider] onRemoteUpdate SKIPPED: empty data rejected');
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
// Store the latest data - will be used when debounce fires
|
|
246
|
+
pendingRemoteDataRef.current = data;
|
|
247
|
+
// Clear any pending debounce timer
|
|
248
|
+
if (remoteSyncTimerRef.current) {
|
|
249
|
+
clearTimeout(remoteSyncTimerRef.current);
|
|
250
|
+
}
|
|
251
|
+
// Debounce the sync to batch rapid successive updates
|
|
252
|
+
// This prevents plugin recreation and flickering on every update
|
|
253
|
+
remoteSyncTimerRef.current = setTimeout(() => {
|
|
254
|
+
// Double-check we're still not viewing a historical version
|
|
255
|
+
// (user might have switched while debounce was pending)
|
|
256
|
+
if (viewingVersionRef.current !== null) {
|
|
257
|
+
pendingRemoteDataRef.current = null;
|
|
258
|
+
remoteSyncTimerRef.current = null;
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
const dataToSync = pendingRemoteDataRef.current;
|
|
262
|
+
if (dataToSync) {
|
|
263
|
+
const syncComponentCount = dataToSync.content?.length ?? 0;
|
|
264
|
+
console.log('[P1PuckProvider] onRemoteUpdate APPLYING:', `components=${syncComponentCount},`, `pendingRemoteUpdates will be=${pendingRemoteUpdatesRef.current + 1}`);
|
|
265
|
+
// Increment counter to skip the onChange echo(es) that will fire
|
|
266
|
+
// when Puck processes the setCurrentData call below.
|
|
267
|
+
// The content-based guards in puckDataToYMap and RealtimeClient
|
|
268
|
+
// prevent actual echo loops at the Y.Doc/WebSocket layer.
|
|
269
|
+
pendingRemoteUpdatesRef.current += 1;
|
|
270
|
+
// Update current data when remote changes arrive
|
|
271
|
+
currentDataDocumentPathRef.current = currentDocumentRef.current?.path ?? null;
|
|
272
|
+
setCurrentData(dataToSync);
|
|
273
|
+
// Update sync key to trigger Puck re-sync
|
|
274
|
+
setRemoteSyncKey(`remote-${Date.now()}`);
|
|
275
|
+
pendingRemoteDataRef.current = null;
|
|
276
|
+
// Safety net: reset counter after React has processed the state updates.
|
|
277
|
+
// If the remote data is identical to current editor state, Puck won't
|
|
278
|
+
// fire onChange and the counter would never be decremented naturally.
|
|
279
|
+
// Leaving it > 0 would cause subsequent local edits to be dropped.
|
|
280
|
+
setTimeout(() => {
|
|
281
|
+
pendingRemoteUpdatesRef.current = 0;
|
|
282
|
+
}, 100);
|
|
283
|
+
}
|
|
284
|
+
remoteSyncTimerRef.current = null;
|
|
285
|
+
}, REMOTE_SYNC_DEBOUNCE_DELAY);
|
|
286
|
+
},
|
|
287
|
+
});
|
|
288
|
+
// Keep a stable ref to realtime for use in callbacks without dependency churn
|
|
289
|
+
const realtimeRef = useRef(realtime);
|
|
290
|
+
realtimeRef.current = realtime;
|
|
291
|
+
// Cleanup remote sync timer on unmount
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
return () => {
|
|
294
|
+
if (remoteSyncTimerRef.current) {
|
|
295
|
+
clearTimeout(remoteSyncTimerRef.current);
|
|
296
|
+
}
|
|
297
|
+
};
|
|
298
|
+
}, []);
|
|
299
|
+
// PuckDataCapture catch-up: detects data that Puck's onChange missed.
|
|
300
|
+
// Puck's onChange can miss the very last keystroke in a typing burst because
|
|
301
|
+
// createOnChange dispatches asynchronously (via resolveComponentData) and
|
|
302
|
+
// the Zustand subscriber may not fire for the final state update in time.
|
|
303
|
+
// PuckDataCapture subscribes to Puck's Zustand store independently via
|
|
304
|
+
// createUsePuck() and writes the true current data to this ref.
|
|
305
|
+
// The onDataChange callback debounces and compares with what saveData last
|
|
306
|
+
// sent — if they differ, it pushes the corrected data through realtime.
|
|
307
|
+
const realtimeDataCaptureRef = useRef(null);
|
|
308
|
+
const lastSentDataRef = useRef(null);
|
|
309
|
+
const captureTimerRef = useRef(null);
|
|
310
|
+
// Track the last data sent via saveData so we can detect missed updates.
|
|
311
|
+
// Updated in saveData's realtime branch (the happy path).
|
|
312
|
+
const trackSentData = useCallback((data) => {
|
|
313
|
+
lastSentDataRef.current = JSON.stringify(data);
|
|
314
|
+
}, []);
|
|
315
|
+
// Callback for PuckDataCapture.onDataChange — fires when Puck's store
|
|
316
|
+
// updates (may fire for changes that onChange misses).
|
|
317
|
+
const handleRealtimeDataCapture = useCallback((data) => {
|
|
318
|
+
if (!enableRealtime)
|
|
319
|
+
return;
|
|
320
|
+
// Store the latest data in the ref for comparison when the timer fires.
|
|
321
|
+
// The ref always holds the most recent Zustand store snapshot.
|
|
322
|
+
realtimeDataCaptureRef.current = data;
|
|
323
|
+
// Debounce: wait 800ms after the last store update to allow onChange
|
|
324
|
+
// to process normally. When the timer fires, compare the ref's current
|
|
325
|
+
// data (not the closure's stale copy) against what was last sent.
|
|
326
|
+
if (captureTimerRef.current)
|
|
327
|
+
clearTimeout(captureTimerRef.current);
|
|
328
|
+
captureTimerRef.current = setTimeout(() => {
|
|
329
|
+
if (!realtimeConnectedRef.current)
|
|
330
|
+
return;
|
|
331
|
+
if (viewingVersionRef.current !== null)
|
|
332
|
+
return;
|
|
333
|
+
const currentData = realtimeDataCaptureRef.current;
|
|
334
|
+
if (!currentData)
|
|
335
|
+
return;
|
|
336
|
+
const dataJson = JSON.stringify(currentData);
|
|
337
|
+
// If saveData already sent this exact data, no catch-up needed
|
|
338
|
+
if (dataJson === lastSentDataRef.current)
|
|
339
|
+
return;
|
|
340
|
+
// Data origin guard
|
|
341
|
+
const currentPath = currentDocumentRef.current?.path ?? null;
|
|
342
|
+
const dataOriginPath = currentDataDocumentPathRef.current;
|
|
343
|
+
if (dataOriginPath !== currentPath)
|
|
344
|
+
return;
|
|
345
|
+
console.log('[P1PuckProvider] PuckDataCapture catch-up: sending missed data,', `components=${currentData.content?.length ?? 0}`);
|
|
346
|
+
realtimeRef.current.applyLocalChange(currentData);
|
|
347
|
+
lastSentDataRef.current = dataJson;
|
|
348
|
+
}, 800);
|
|
349
|
+
}, [enableRealtime]);
|
|
350
|
+
// Cleanup capture timer on unmount
|
|
351
|
+
useEffect(() => {
|
|
352
|
+
return () => {
|
|
353
|
+
if (captureTimerRef.current)
|
|
354
|
+
clearTimeout(captureTimerRef.current);
|
|
355
|
+
};
|
|
356
|
+
}, []);
|
|
357
|
+
// Keep refs in sync with state
|
|
358
|
+
useEffect(() => {
|
|
359
|
+
currentDocumentRef.current = currentDocument;
|
|
360
|
+
}, [currentDocument]);
|
|
361
|
+
useEffect(() => {
|
|
362
|
+
viewingVersionRef.current = viewingVersion;
|
|
363
|
+
}, [viewingVersion]);
|
|
364
|
+
// Keep realtime connection ref in sync (used by performSave to avoid stale closure)
|
|
365
|
+
useEffect(() => {
|
|
366
|
+
realtimeConnectedRef.current = realtime.connected;
|
|
367
|
+
}, [realtime.connected]);
|
|
368
|
+
// Create client with user principal
|
|
369
|
+
const userClient = useMemo(() => client.withPrincipal({ id: userId, type: 'user' }), [client, userId]);
|
|
370
|
+
// Document list for current branch
|
|
371
|
+
const { documents: branchDocuments, loading: documentsLoading, create: createDocumentRaw, remove: removeDocumentRaw, } = useDocuments({ client: userClient, siteId, branchId });
|
|
372
|
+
// Stable document create/delete callbacks
|
|
373
|
+
const branchIdRef = useRef(branchId);
|
|
374
|
+
branchIdRef.current = branchId;
|
|
375
|
+
const createDocumentRawRef = useRef(createDocumentRaw);
|
|
376
|
+
createDocumentRawRef.current = createDocumentRaw;
|
|
377
|
+
const stableCreateDocument = useCallback(async (path) => {
|
|
378
|
+
if (!branchIdRef.current) {
|
|
379
|
+
throw new Error('Cannot create document: no branch selected');
|
|
380
|
+
}
|
|
381
|
+
await createDocumentRawRef.current(path);
|
|
382
|
+
}, []);
|
|
383
|
+
const removeDocumentRawRef = useRef(removeDocumentRaw);
|
|
384
|
+
removeDocumentRawRef.current = removeDocumentRaw;
|
|
385
|
+
const stableDeleteDocument = useCallback(async (documentId, _path) => {
|
|
386
|
+
if (!branchIdRef.current) {
|
|
387
|
+
throw new Error('Cannot delete document: no branch selected');
|
|
388
|
+
}
|
|
389
|
+
await removeDocumentRawRef.current(documentId);
|
|
390
|
+
}, []);
|
|
391
|
+
// Load branches
|
|
392
|
+
const refreshBranches = useCallback(async () => {
|
|
393
|
+
try {
|
|
394
|
+
setBranchesLoading(true);
|
|
395
|
+
const branchList = await userClient.branches.list(siteId);
|
|
396
|
+
setBranches(branchList);
|
|
397
|
+
// Update current branch from current branchId state
|
|
398
|
+
setBranchId((currentBranchId) => {
|
|
399
|
+
let effectiveBranchId = currentBranchId;
|
|
400
|
+
// If no branchId set, try persisted branch, then default to main
|
|
401
|
+
if (!effectiveBranchId) {
|
|
402
|
+
const persisted = getPersistedBranchId();
|
|
403
|
+
if (persisted && branchList.some((b) => b.id === persisted)) {
|
|
404
|
+
effectiveBranchId = persisted;
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
// Validate that the branch exists in the list; fall back to main if not
|
|
408
|
+
if (effectiveBranchId && !branchList.some((b) => b.id === effectiveBranchId)) {
|
|
409
|
+
const mainBranch = branchList.find((b) => b.isMain);
|
|
410
|
+
effectiveBranchId = mainBranch?.id ?? effectiveBranchId;
|
|
411
|
+
}
|
|
412
|
+
// Default to main if still empty
|
|
413
|
+
if (!effectiveBranchId) {
|
|
414
|
+
const mainBranch = branchList.find((b) => b.isMain);
|
|
415
|
+
if (mainBranch) {
|
|
416
|
+
effectiveBranchId = mainBranch.id;
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
persistBranchId(effectiveBranchId);
|
|
420
|
+
const current = branchList.find((b) => b.id === effectiveBranchId);
|
|
421
|
+
setCurrentBranch(current ?? null);
|
|
422
|
+
return effectiveBranchId;
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
catch (error) {
|
|
426
|
+
console.error('Failed to load branches:', error);
|
|
427
|
+
}
|
|
428
|
+
finally {
|
|
429
|
+
setBranchesLoading(false);
|
|
430
|
+
}
|
|
431
|
+
}, [userClient, siteId, getPersistedBranchId, persistBranchId]);
|
|
432
|
+
const createBranch = useCallback(async (name) => {
|
|
433
|
+
const branch = await userClient.branches.create({ siteId, name });
|
|
434
|
+
await refreshBranches();
|
|
435
|
+
return branch;
|
|
436
|
+
}, [userClient, siteId, refreshBranches]);
|
|
437
|
+
// Initial branch load - only once
|
|
438
|
+
useEffect(() => {
|
|
439
|
+
if (!initializedRef.current) {
|
|
440
|
+
initializedRef.current = true;
|
|
441
|
+
void refreshBranches();
|
|
442
|
+
}
|
|
443
|
+
}, [refreshBranches]);
|
|
444
|
+
// Perform save operation - uses refs to avoid dependency issues
|
|
445
|
+
const performSave = useCallback(async () => {
|
|
446
|
+
const dataToSave = pendingDataRef.current;
|
|
447
|
+
const doc = currentDocumentRef.current;
|
|
448
|
+
if (!dataToSave || !doc) {
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
// Data origin guard: reject writes if data doesn't belong to current document
|
|
452
|
+
if (currentDataDocumentPathRef.current !== doc.path) {
|
|
453
|
+
pendingDataRef.current = null;
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
// When realtime is connected, the DO handles persistence via WebSocket sync.
|
|
457
|
+
// Skip REST API save to avoid creating duplicate versions without CRDT state.
|
|
458
|
+
if (enableRealtime && realtimeConnectedRef.current) {
|
|
459
|
+
// The data is already being sent via realtime.applyLocalChange in saveData.
|
|
460
|
+
// Mark as saved since the DO will persist it.
|
|
461
|
+
pendingDataRef.current = null;
|
|
462
|
+
setSaveStatus('saved');
|
|
463
|
+
setLastSaved(new Date());
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
// Fallback: REST API save when realtime is disabled or disconnected
|
|
467
|
+
setSaveStatus('saving');
|
|
468
|
+
setSaveError(null);
|
|
469
|
+
try {
|
|
470
|
+
await withRetry(async () => {
|
|
471
|
+
await userClient.versions.create(siteId, {
|
|
472
|
+
documentId: doc.id,
|
|
473
|
+
branchId,
|
|
474
|
+
snapshot: dataToSave,
|
|
475
|
+
});
|
|
476
|
+
}, { maxAttempts: maxRetries });
|
|
477
|
+
// Note: We intentionally do NOT call setCurrentData(dataToSave) here.
|
|
478
|
+
// The data is already in Puck's internal state (it came from Puck's onChange).
|
|
479
|
+
// Updating currentData would trigger a re-render cascade that recreates the
|
|
480
|
+
// p1Plugin, causing Puck to potentially re-render and flicker.
|
|
481
|
+
// currentData should only be updated when loading a document or switching versions.
|
|
482
|
+
pendingDataRef.current = null;
|
|
483
|
+
setSaveStatus('saved');
|
|
484
|
+
setLastSaved(new Date());
|
|
485
|
+
}
|
|
486
|
+
catch (error) {
|
|
487
|
+
setSaveStatus('error');
|
|
488
|
+
const saveErr = error instanceof Error ? error : new Error(String(error));
|
|
489
|
+
setSaveError(saveErr);
|
|
490
|
+
// Show error notification with retry action
|
|
491
|
+
if (showErrorNotifications) {
|
|
492
|
+
notificationContext.addError(`Failed to save changes: ${saveErr.message}`, () => void performSave());
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}, [userClient, siteId, branchId, maxRetries, showErrorNotifications, notificationContext, enableRealtime]);
|
|
496
|
+
// Debounced save
|
|
497
|
+
const debouncedSave = useMemo(() => debounce(() => {
|
|
498
|
+
void performSave();
|
|
499
|
+
}, autoSaveDelay), [performSave, autoSaveDelay]);
|
|
500
|
+
// Cleanup debounce on unmount
|
|
501
|
+
useEffect(() => {
|
|
502
|
+
return () => {
|
|
503
|
+
debouncedSave.cancel();
|
|
504
|
+
};
|
|
505
|
+
}, [debouncedSave]);
|
|
506
|
+
// Pause auto-save
|
|
507
|
+
const pauseAutoSave = useCallback(() => {
|
|
508
|
+
debouncedSave.pause();
|
|
509
|
+
setAutoSavePaused(true);
|
|
510
|
+
}, [debouncedSave]);
|
|
511
|
+
// Resume auto-save
|
|
512
|
+
const resumeAutoSave = useCallback(() => {
|
|
513
|
+
debouncedSave.resume();
|
|
514
|
+
setAutoSavePaused(false);
|
|
515
|
+
}, [debouncedSave]);
|
|
516
|
+
// Capture Puck action metadata from the onAction callback.
|
|
517
|
+
// This captures the action type and relevant metadata fields so they
|
|
518
|
+
// can be included in the sync payload for backend version storage.
|
|
519
|
+
const handleAction = useCallback((action) => {
|
|
520
|
+
const actionMetadata = {};
|
|
521
|
+
if (action.componentType)
|
|
522
|
+
actionMetadata.componentType = action.componentType;
|
|
523
|
+
if (action.componentId)
|
|
524
|
+
actionMetadata.componentId = action.componentId;
|
|
525
|
+
if (action.zone)
|
|
526
|
+
actionMetadata.zone = action.zone;
|
|
527
|
+
if (action.sourceIndex !== undefined)
|
|
528
|
+
actionMetadata.sourceIndex = action.sourceIndex;
|
|
529
|
+
if (action.destinationIndex !== undefined)
|
|
530
|
+
actionMetadata.destinationIndex = action.destinationIndex;
|
|
531
|
+
lastActionRef.current = {
|
|
532
|
+
actionType: action.type || 'unknown',
|
|
533
|
+
actionMetadata,
|
|
534
|
+
};
|
|
535
|
+
}, []);
|
|
536
|
+
// Public save function (triggers debounce)
|
|
537
|
+
// Also resumes auto-save if paused, per user requirement
|
|
538
|
+
// Sends changes via WebSocket when realtime is enabled (but not for remote updates)
|
|
539
|
+
const saveData = useCallback((data) => {
|
|
540
|
+
const componentCount = data.content?.length ?? 0;
|
|
541
|
+
// Suppress the onChange echo from PuckDataSynchronizer after loadDocument.
|
|
542
|
+
if (suppressNextSaveRef.current) {
|
|
543
|
+
console.log(`[P1PuckProvider] saveData SKIPPED: suppressNextSave (components=${componentCount})`);
|
|
544
|
+
suppressNextSaveRef.current = false;
|
|
545
|
+
return;
|
|
546
|
+
}
|
|
547
|
+
// When realtime is enabled, detect whether this onChange came from a remote
|
|
548
|
+
// sync (Yjs update from another client) vs. a local user edit.
|
|
549
|
+
// Remote updates should NOT trigger a REST save — the DO handles persistence.
|
|
550
|
+
// Important: we must NOT set pendingDataRef for remote syncs, otherwise
|
|
551
|
+
// getHasUnsavedChanges() will incorrectly report unsaved changes.
|
|
552
|
+
if (enableRealtime && realtime.connected) {
|
|
553
|
+
if (pendingRemoteUpdatesRef.current > 0) {
|
|
554
|
+
// Counter indicates this onChange is from a remote update or data load
|
|
555
|
+
console.log(`[P1PuckProvider] saveData SKIPPED: pendingRemoteUpdates=${pendingRemoteUpdatesRef.current} (components=${componentCount})`);
|
|
556
|
+
pendingRemoteUpdatesRef.current -= 1;
|
|
557
|
+
return;
|
|
558
|
+
}
|
|
559
|
+
else if (viewingVersionRef.current !== null) {
|
|
560
|
+
// User is viewing historical version - don't broadcast or save
|
|
561
|
+
console.log(`[P1PuckProvider] saveData SKIPPED: viewing historical version (components=${componentCount})`);
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
else {
|
|
565
|
+
const currentPath = currentDocumentRef.current?.path ?? null;
|
|
566
|
+
// Data origin guard: verify the data in state belongs to the
|
|
567
|
+
// current document. During rapid document switching, a stale
|
|
568
|
+
// loadDocument call can resolve and set data from document Y
|
|
569
|
+
// into state after currentDocument has been updated to X.
|
|
570
|
+
const dataOriginPath = currentDataDocumentPathRef.current;
|
|
571
|
+
if (dataOriginPath !== currentPath) {
|
|
572
|
+
console.warn('[P1PuckProvider] saveData SKIPPED: data origin mismatch.', 'dataOrigin:', dataOriginPath, 'currentDoc:', currentPath, `components=${componentCount}`);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
// Connection identity guard: verify the realtime connection is
|
|
576
|
+
// bound to the same document we're currently editing.
|
|
577
|
+
const connectedPath = realtime.connectedDocumentPath;
|
|
578
|
+
if (currentPath !== connectedPath) {
|
|
579
|
+
console.warn('[P1PuckProvider] saveData SKIPPED: connection identity mismatch.', 'currentDoc:', currentPath, 'connectedDoc:', connectedPath, `components=${componentCount}`);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
// Local user edit — send via WebSocket (DO handles persistence)
|
|
583
|
+
// Echo prevention is handled at lower layers:
|
|
584
|
+
// - puckDataToYMap no-ops when Y.Doc already has identical data
|
|
585
|
+
// - RealtimeClient.lastSentSnapshot drops sends matching last sent/received
|
|
586
|
+
console.log(`[P1PuckProvider] saveData SENDING via realtime: components=${componentCount}, path=${currentPath}`);
|
|
587
|
+
realtime.applyLocalChange(data);
|
|
588
|
+
trackSentData(data);
|
|
589
|
+
lastActionRef.current = null;
|
|
590
|
+
// Data sent via WebSocket — DO handles persistence.
|
|
591
|
+
// Update save status directly (skip debouncedSave/performSave chain).
|
|
592
|
+
setSaveStatus('saved');
|
|
593
|
+
setLastSaved(new Date());
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
// Non-realtime path: mark data as pending and trigger debounced REST save
|
|
598
|
+
console.log(`[P1PuckProvider] saveData via REST (debounced): components=${componentCount}, realtimeEnabled=${enableRealtime}, connected=${realtime.connected}`);
|
|
599
|
+
pendingDataRef.current = data;
|
|
600
|
+
if (debouncedSave.isPaused()) {
|
|
601
|
+
debouncedSave.resume();
|
|
602
|
+
setAutoSavePaused(false);
|
|
603
|
+
}
|
|
604
|
+
debouncedSave();
|
|
605
|
+
}, [debouncedSave, enableRealtime, realtime.connected, trackSentData]);
|
|
606
|
+
// Force immediate save
|
|
607
|
+
const saveNow = useCallback(async () => {
|
|
608
|
+
debouncedSave.cancel();
|
|
609
|
+
// When realtime is connected, ensure the latest data is sent via WebSocket
|
|
610
|
+
if (enableRealtime && realtimeConnectedRef.current && pendingDataRef.current) {
|
|
611
|
+
const currentPath = currentDocumentRef.current?.path ?? null;
|
|
612
|
+
const dataOriginPath = currentDataDocumentPathRef.current;
|
|
613
|
+
const connectedPath = realtime.connectedDocumentPath;
|
|
614
|
+
// Data origin + connection identity guards
|
|
615
|
+
if (dataOriginPath === currentPath && currentPath === connectedPath) {
|
|
616
|
+
realtime.applyLocalChange(pendingDataRef.current);
|
|
617
|
+
pendingDataRef.current = null;
|
|
618
|
+
setSaveStatus('saved');
|
|
619
|
+
setLastSaved(new Date());
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
// Fall through to REST save if mismatch
|
|
623
|
+
}
|
|
624
|
+
await performSave();
|
|
625
|
+
}, [debouncedSave, performSave, enableRealtime]);
|
|
626
|
+
// Load document by path
|
|
627
|
+
const loadDocument = useCallback(async (path) => {
|
|
628
|
+
// Cancel any pending remote sync to prevent race conditions
|
|
629
|
+
// where a stale remote update overrides the document we're loading
|
|
630
|
+
cancelPendingRemoteSync();
|
|
631
|
+
// Increment load request counter and capture for staleness detection.
|
|
632
|
+
// If a newer loadDocument call starts before our awaits resolve, the
|
|
633
|
+
// counter will have been incremented again and our captured value
|
|
634
|
+
// will no longer match — signaling that our response is stale.
|
|
635
|
+
loadRequestIdRef.current += 1;
|
|
636
|
+
const thisRequestId = loadRequestIdRef.current;
|
|
637
|
+
// Pre-clear the current document immediately so the preview shows the
|
|
638
|
+
// empty state right away rather than stale content during the fetch.
|
|
639
|
+
currentDataDocumentPathRef.current = null;
|
|
640
|
+
setCurrentData(null);
|
|
641
|
+
setCurrentDocument(null);
|
|
642
|
+
try {
|
|
643
|
+
// Normalize path: strip leading slash if present
|
|
644
|
+
const normalizedPath = path.startsWith('/') ? path.slice(1) : path;
|
|
645
|
+
// Get document by path
|
|
646
|
+
const doc = await userClient.documents.getByPath(siteId, normalizedPath);
|
|
647
|
+
// Staleness check: a newer loadDocument call has started
|
|
648
|
+
if (thisRequestId !== loadRequestIdRef.current) {
|
|
649
|
+
console.debug('[P1PuckProvider] Stale loadDocument — skipping (after getByPath)');
|
|
650
|
+
return;
|
|
651
|
+
}
|
|
652
|
+
// Clear stale data BEFORE updating the document identity so that
|
|
653
|
+
// useRealtime's new useEffect sees initialData=null when it creates
|
|
654
|
+
// the fresh Y.Doc. Without this, currentData still holds the previous
|
|
655
|
+
// document's content when setCurrentDocument triggers the re-render,
|
|
656
|
+
// causing the new Y.Doc to be seeded with the wrong document's Yjs
|
|
657
|
+
// state — which the DO then commits as the first realtime version.
|
|
658
|
+
currentDataDocumentPathRef.current = null;
|
|
659
|
+
setCurrentData(null);
|
|
660
|
+
setCurrentDocument(doc);
|
|
661
|
+
// Get latest version
|
|
662
|
+
const version = await userClient.versions.getLatest(siteId, branchId, doc.id);
|
|
663
|
+
const puckData = version.snapshot;
|
|
664
|
+
// Staleness check: a newer loadDocument call has started
|
|
665
|
+
if (thisRequestId !== loadRequestIdRef.current) {
|
|
666
|
+
console.debug('[P1PuckProvider] Stale loadDocument — skipping (after getLatest)');
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
// Mark REST data as non-local to prevent the Puck onChange handler
|
|
670
|
+
// from echoing it back through the Y.Doc via applyLocalChange.
|
|
671
|
+
// This is critical after the Hibernatable WS migration because
|
|
672
|
+
// initializeIfNeeded() latency can invert the ordering of WebSocket
|
|
673
|
+
// initial state vs REST response, causing the remote-update guard
|
|
674
|
+
// (pendingRemoteUpdatesRef) to be bypassed.
|
|
675
|
+
if (enableRealtime) {
|
|
676
|
+
pendingRemoteUpdatesRef.current += 1;
|
|
677
|
+
// Safety net: reset after React has processed the state updates.
|
|
678
|
+
// If Puck's data is identical to current editor state, onChange
|
|
679
|
+
// won't fire and the counter would never be decremented naturally.
|
|
680
|
+
// Leaving it > 0 would cause subsequent local edits to be dropped.
|
|
681
|
+
setTimeout(() => {
|
|
682
|
+
pendingRemoteUpdatesRef.current = 0;
|
|
683
|
+
}, 100);
|
|
684
|
+
}
|
|
685
|
+
// IMPORTANT: Update the ref BEFORE state updates
|
|
686
|
+
// Setting to null allows remote updates after document loads
|
|
687
|
+
viewingVersionRef.current = null;
|
|
688
|
+
// Cancel any pending PuckDataCapture catch-up timer and reset its
|
|
689
|
+
// ref before arming the data-origin guard below. Without this, the
|
|
690
|
+
// timer can fire in the window between currentDataDocumentPathRef
|
|
691
|
+
// being set to doc.path and the new document's first remote update
|
|
692
|
+
// arriving — passing the origin check while still carrying the
|
|
693
|
+
// previous document's Puck state.
|
|
694
|
+
if (captureTimerRef.current) {
|
|
695
|
+
clearTimeout(captureTimerRef.current);
|
|
696
|
+
captureTimerRef.current = null;
|
|
697
|
+
}
|
|
698
|
+
realtimeDataCaptureRef.current = null;
|
|
699
|
+
currentDataDocumentPathRef.current = doc.path;
|
|
700
|
+
suppressNextSaveRef.current = true;
|
|
701
|
+
setCurrentData(puckData);
|
|
702
|
+
setLatestVersionData(puckData);
|
|
703
|
+
setViewingVersion(null);
|
|
704
|
+
// Clear remoteSyncKey so document sync takes priority
|
|
705
|
+
setRemoteSyncKey(null);
|
|
706
|
+
pendingDataRef.current = null;
|
|
707
|
+
setSaveStatus('idle');
|
|
708
|
+
setSaveError(null);
|
|
709
|
+
}
|
|
710
|
+
catch (error) {
|
|
711
|
+
// Use warn, not error: callers handle this and console.error triggers
|
|
712
|
+
// the Next.js dev overlay unnecessarily.
|
|
713
|
+
console.warn('[P1PuckProvider] loadDocument failed:', error);
|
|
714
|
+
// Unload the current document so VersionBannerOverride shows the empty
|
|
715
|
+
// state instead of the previous document's content.
|
|
716
|
+
currentDataDocumentPathRef.current = null;
|
|
717
|
+
setCurrentData(null);
|
|
718
|
+
setCurrentDocument(null);
|
|
719
|
+
throw error;
|
|
720
|
+
}
|
|
721
|
+
}, [userClient, siteId, branchId, cancelPendingRemoteSync, enableRealtime]);
|
|
722
|
+
// Load a specific version into the editor
|
|
723
|
+
const loadVersion = useCallback(async (version) => {
|
|
724
|
+
// Cancel any pending remote sync to prevent race conditions
|
|
725
|
+
// where a stale remote update overrides the version we're loading
|
|
726
|
+
cancelPendingRemoteSync();
|
|
727
|
+
try {
|
|
728
|
+
const doc = currentDocumentRef.current;
|
|
729
|
+
if (!doc) {
|
|
730
|
+
throw new Error('No document loaded');
|
|
731
|
+
}
|
|
732
|
+
let versionToUse = version;
|
|
733
|
+
// If the version doesn't have snapshot data, try fetching it from the API
|
|
734
|
+
if (!version.snapshot || Object.keys(version.snapshot).length === 0) {
|
|
735
|
+
try {
|
|
736
|
+
versionToUse = await userClient.versions.get(siteId, branchId, doc.id, version.id);
|
|
737
|
+
}
|
|
738
|
+
catch (fetchError) {
|
|
739
|
+
// If fetching fails, log a warning and use the version as-is
|
|
740
|
+
console.warn('Could not fetch full version data, using version from list:', fetchError);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
let puckData = versionToUse.snapshot;
|
|
744
|
+
// If snapshot is empty or invalid, use blank Puck data
|
|
745
|
+
// This is expected for version 1 which represents the initial blank state
|
|
746
|
+
if (!puckData || (!puckData.content && !puckData.root)) {
|
|
747
|
+
puckData = { content: [], root: { props: {} } };
|
|
748
|
+
}
|
|
749
|
+
// IMPORTANT: Update the ref BEFORE state updates to block any incoming remote updates
|
|
750
|
+
// The effect that syncs viewingVersionRef runs AFTER render, which is too late
|
|
751
|
+
// Remote updates check this ref, so we need it set synchronously
|
|
752
|
+
viewingVersionRef.current = versionToUse;
|
|
753
|
+
currentDataDocumentPathRef.current = currentDocumentRef.current?.path ?? null;
|
|
754
|
+
setCurrentData(puckData);
|
|
755
|
+
setViewingVersion(versionToUse);
|
|
756
|
+
// Clear remoteSyncKey so version sync takes priority
|
|
757
|
+
setRemoteSyncKey(null);
|
|
758
|
+
// Pause auto-save when viewing historical version
|
|
759
|
+
debouncedSave.pause();
|
|
760
|
+
setAutoSavePaused(true);
|
|
761
|
+
pendingDataRef.current = null;
|
|
762
|
+
setSaveStatus('idle');
|
|
763
|
+
}
|
|
764
|
+
catch (error) {
|
|
765
|
+
console.error('Failed to load version:', error);
|
|
766
|
+
throw error;
|
|
767
|
+
}
|
|
768
|
+
}, [userClient, siteId, branchId, debouncedSave, cancelPendingRemoteSync]);
|
|
769
|
+
// Return to the latest version
|
|
770
|
+
const returnToLatest = useCallback(async () => {
|
|
771
|
+
// Cancel any pending remote sync to prevent race conditions
|
|
772
|
+
// The latest data will be loaded fresh, then remote sync can resume
|
|
773
|
+
cancelPendingRemoteSync();
|
|
774
|
+
// Get current state from Yjs if realtime is connected
|
|
775
|
+
// This ensures we get any changes made by other users while viewing history
|
|
776
|
+
let dataToRestore = null;
|
|
777
|
+
if (enableRealtime && realtime.connected) {
|
|
778
|
+
const currentYjsData = realtime.getSnapshot();
|
|
779
|
+
if (currentYjsData) {
|
|
780
|
+
dataToRestore = currentYjsData;
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
// Fall back to latestVersionData if Yjs snapshot not available
|
|
784
|
+
if (!dataToRestore) {
|
|
785
|
+
dataToRestore = latestVersionData;
|
|
786
|
+
}
|
|
787
|
+
if (dataToRestore) {
|
|
788
|
+
// IMPORTANT: Update the ref BEFORE state updates
|
|
789
|
+
// Setting to null allows remote updates to resume
|
|
790
|
+
viewingVersionRef.current = null;
|
|
791
|
+
// Increment counter to skip onChange that will fire
|
|
792
|
+
pendingRemoteUpdatesRef.current += 1;
|
|
793
|
+
currentDataDocumentPathRef.current = currentDocumentRef.current?.path ?? null;
|
|
794
|
+
setCurrentData(dataToRestore);
|
|
795
|
+
setViewingVersion(null);
|
|
796
|
+
// Clear remoteSyncKey so latest version sync takes priority
|
|
797
|
+
setRemoteSyncKey(null);
|
|
798
|
+
// Resume auto-save
|
|
799
|
+
debouncedSave.resume();
|
|
800
|
+
setAutoSavePaused(false);
|
|
801
|
+
pendingDataRef.current = null;
|
|
802
|
+
setSaveStatus('idle');
|
|
803
|
+
}
|
|
804
|
+
}, [latestVersionData, debouncedSave, cancelPendingRemoteSync, enableRealtime, realtime]);
|
|
805
|
+
// Computed property for whether viewing historical version
|
|
806
|
+
const isViewingHistoricalVersion = viewingVersion !== null;
|
|
807
|
+
// =========================================================================
|
|
808
|
+
// Phase 9: Presence & Agent Mode State
|
|
809
|
+
// =========================================================================
|
|
810
|
+
// Presence state (when presenceEnabled)
|
|
811
|
+
const [presenceActors, setPresenceActors] = useState([]);
|
|
812
|
+
const presenceInitializedRef = useRef(false);
|
|
813
|
+
// Track previous actors for onPresenceChange callback comparison
|
|
814
|
+
const prevActorsRef = useRef([]);
|
|
815
|
+
// Conflict notifications state
|
|
816
|
+
const [conflicts, setConflicts] = useState([]);
|
|
817
|
+
// Agent edit session state (when agentModeEnabled && agentId)
|
|
818
|
+
const [agentSession, setAgentSession] = useState(null);
|
|
819
|
+
const [agentEditLoading, setAgentEditLoading] = useState(false);
|
|
820
|
+
const [agentEditError, setAgentEditError] = useState(null);
|
|
821
|
+
// Fetch presence data
|
|
822
|
+
const fetchPresence = useCallback(async () => {
|
|
823
|
+
if (!presenceEnabled || !branchId)
|
|
824
|
+
return;
|
|
825
|
+
try {
|
|
826
|
+
const branchPresence = await userClient.presence.getBranchPresence(siteId, branchId);
|
|
827
|
+
// Filter out self and enrich with names
|
|
828
|
+
const filteredActors = branchPresence.actors.filter((actor) => actor.actorId !== userId);
|
|
829
|
+
const enrichedActors = enrichActorsWithNames(filteredActors);
|
|
830
|
+
setPresenceActors(enrichedActors);
|
|
831
|
+
// Call onPresenceChange if actors changed
|
|
832
|
+
if (onPresenceChange) {
|
|
833
|
+
const actorsChanged = JSON.stringify(enrichedActors.map((a) => a.id).sort()) !==
|
|
834
|
+
JSON.stringify(prevActorsRef.current.map((a) => a.id).sort());
|
|
835
|
+
if (actorsChanged) {
|
|
836
|
+
onPresenceChange(enrichedActors);
|
|
837
|
+
prevActorsRef.current = enrichedActors;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
catch (error) {
|
|
842
|
+
console.error('Failed to fetch presence:', error);
|
|
843
|
+
}
|
|
844
|
+
}, [presenceEnabled, branchId, siteId, userId, userClient, onPresenceChange, enrichActorsWithNames]);
|
|
845
|
+
// Keep fetchPresence in a ref to avoid restarting the interval when callback changes
|
|
846
|
+
const fetchPresenceRef = useRef(fetchPresence);
|
|
847
|
+
useEffect(() => {
|
|
848
|
+
fetchPresenceRef.current = fetchPresence;
|
|
849
|
+
}, [fetchPresence]);
|
|
850
|
+
// Initial presence fetch and polling
|
|
851
|
+
// HTTP polling is skipped when WebSocket presence is active and connected
|
|
852
|
+
useEffect(() => {
|
|
853
|
+
if (!presenceEnabled)
|
|
854
|
+
return;
|
|
855
|
+
// Skip HTTP polling if WebSocket presence is handling updates
|
|
856
|
+
const shouldSkipPolling = wsPresenceActive && realtime.connected;
|
|
857
|
+
// Initial fetch (only if WS isn't active yet)
|
|
858
|
+
if (!presenceInitializedRef.current && !shouldSkipPolling) {
|
|
859
|
+
presenceInitializedRef.current = true;
|
|
860
|
+
void fetchPresenceRef.current();
|
|
861
|
+
}
|
|
862
|
+
// Set up polling - use ref to avoid restarting interval when callback changes
|
|
863
|
+
// Skip polling when WebSocket is handling presence
|
|
864
|
+
const intervalId = setInterval(() => {
|
|
865
|
+
// Check again at each interval - WS state may have changed
|
|
866
|
+
if (!wsPresenceActive || !realtime.connected) {
|
|
867
|
+
void fetchPresenceRef.current();
|
|
868
|
+
}
|
|
869
|
+
}, presencePollingInterval);
|
|
870
|
+
return () => {
|
|
871
|
+
clearInterval(intervalId);
|
|
872
|
+
};
|
|
873
|
+
}, [presenceEnabled, presencePollingInterval, realtime.connected]);
|
|
874
|
+
// Reset presence when disabled
|
|
875
|
+
useEffect(() => {
|
|
876
|
+
if (!presenceEnabled) {
|
|
877
|
+
setPresenceActors([]);
|
|
878
|
+
presenceInitializedRef.current = false;
|
|
879
|
+
}
|
|
880
|
+
}, [presenceEnabled]);
|
|
881
|
+
// Reset WebSocket presence state when disconnected so the UI falls back
|
|
882
|
+
// to HTTP-polled presence data. Without this, wsPresenceActive stays
|
|
883
|
+
// true after disconnect and the UI shows stale WebSocket presence
|
|
884
|
+
// (e.g. an agent that already completed its edit session still appears).
|
|
885
|
+
useEffect(() => {
|
|
886
|
+
if (!realtime.connected) {
|
|
887
|
+
setWsPresenceActive(false);
|
|
888
|
+
setWsPresenceActors([]);
|
|
889
|
+
}
|
|
890
|
+
}, [realtime.connected]);
|
|
891
|
+
// Compute derived presence values
|
|
892
|
+
// Prefer WebSocket presence when connected for instant updates
|
|
893
|
+
const presenceState = useMemo(() => {
|
|
894
|
+
if (!presenceEnabled)
|
|
895
|
+
return null;
|
|
896
|
+
// Use WebSocket presence when active and connected, otherwise fall back to HTTP polling data
|
|
897
|
+
const effectiveActors = wsPresenceActive && realtime.connected ? wsPresenceActors : presenceActors;
|
|
898
|
+
const humans = effectiveActors.filter((actor) => actor.role === 'human');
|
|
899
|
+
const agents = effectiveActors.filter((actor) => actor.role === 'agent');
|
|
900
|
+
const hasActiveHumans = humans.some((actor) => actor.state === 'active' || actor.state === 'editing');
|
|
901
|
+
const hasActiveAgents = agents.some((actor) => actor.state === 'active' || actor.state === 'editing');
|
|
902
|
+
return {
|
|
903
|
+
actors: effectiveActors,
|
|
904
|
+
humans,
|
|
905
|
+
agents,
|
|
906
|
+
hasActiveHumans,
|
|
907
|
+
hasActiveAgents,
|
|
908
|
+
refresh: fetchPresence,
|
|
909
|
+
};
|
|
910
|
+
}, [presenceEnabled, presenceActors, wsPresenceActors, wsPresenceActive, realtime.connected, fetchPresence]);
|
|
911
|
+
// Keep presence in a ref so it can be read via getter without triggering
|
|
912
|
+
// context recreation. Presence changes frequently (focus region broadcasts)
|
|
913
|
+
// but shouldn't cause PuckDataSynchronizer or plugin re-renders.
|
|
914
|
+
const presenceStateRef = useRef(presenceState);
|
|
915
|
+
presenceStateRef.current = presenceState;
|
|
916
|
+
// =========================================================================
|
|
917
|
+
// Phase 9: Agent Edit Capabilities (when this client IS an agent)
|
|
918
|
+
// =========================================================================
|
|
919
|
+
const agentEditCapabilities = useMemo(() => {
|
|
920
|
+
if (!agentModeEnabled || !agentId)
|
|
921
|
+
return null;
|
|
922
|
+
const documentPath = currentDocument?.path ?? null;
|
|
923
|
+
const canEdit = async (params) => {
|
|
924
|
+
if (!documentPath) {
|
|
925
|
+
throw new Error('No document loaded');
|
|
926
|
+
}
|
|
927
|
+
return userClient.agentEdit.canEdit(siteId, branchId, documentPath, {
|
|
928
|
+
agentId,
|
|
929
|
+
trigger: params.trigger,
|
|
930
|
+
intent: params.intent,
|
|
931
|
+
targetRegions: params.targetRegions,
|
|
932
|
+
requestedById: params.requestedById,
|
|
933
|
+
});
|
|
934
|
+
};
|
|
935
|
+
const startEdit = async (params) => {
|
|
936
|
+
if (!documentPath) {
|
|
937
|
+
throw new Error('No document loaded');
|
|
938
|
+
}
|
|
939
|
+
setAgentEditLoading(true);
|
|
940
|
+
setAgentEditError(null);
|
|
941
|
+
try {
|
|
942
|
+
const session = await userClient.agentEdit.startEdit(siteId, branchId, documentPath, {
|
|
943
|
+
agentId,
|
|
944
|
+
trigger: params.trigger,
|
|
945
|
+
intent: params.intent,
|
|
946
|
+
targetRegions: params.targetRegions,
|
|
947
|
+
requestedById: params.requestedById,
|
|
948
|
+
});
|
|
949
|
+
setAgentSession(session);
|
|
950
|
+
setAgentEditLoading(false);
|
|
951
|
+
return session;
|
|
952
|
+
}
|
|
953
|
+
catch (err) {
|
|
954
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
955
|
+
setAgentEditError(e);
|
|
956
|
+
setAgentEditLoading(false);
|
|
957
|
+
throw e;
|
|
958
|
+
}
|
|
959
|
+
};
|
|
960
|
+
const completeEdit = async () => {
|
|
961
|
+
if (!agentSession) {
|
|
962
|
+
throw new Error('No active edit session');
|
|
963
|
+
}
|
|
964
|
+
if (!documentPath) {
|
|
965
|
+
throw new Error('No document loaded');
|
|
966
|
+
}
|
|
967
|
+
setAgentEditLoading(true);
|
|
968
|
+
try {
|
|
969
|
+
await userClient.agentEdit.completeEdit(siteId, branchId, documentPath, agentId);
|
|
970
|
+
setAgentSession(null);
|
|
971
|
+
setAgentEditLoading(false);
|
|
972
|
+
}
|
|
973
|
+
catch (err) {
|
|
974
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
975
|
+
setAgentEditError(e);
|
|
976
|
+
setAgentEditLoading(false);
|
|
977
|
+
throw e;
|
|
978
|
+
}
|
|
979
|
+
};
|
|
980
|
+
const abortEdit = async () => {
|
|
981
|
+
if (!agentSession) {
|
|
982
|
+
throw new Error('No active edit session');
|
|
983
|
+
}
|
|
984
|
+
if (!documentPath) {
|
|
985
|
+
throw new Error('No document loaded');
|
|
986
|
+
}
|
|
987
|
+
if (!agentSession.checkpointId) {
|
|
988
|
+
throw new Error('No checkpoint ID in session');
|
|
989
|
+
}
|
|
990
|
+
setAgentEditLoading(true);
|
|
991
|
+
try {
|
|
992
|
+
await userClient.agentEdit.abortEdit(siteId, branchId, documentPath, agentId, agentSession.checkpointId);
|
|
993
|
+
setAgentSession(null);
|
|
994
|
+
setAgentEditLoading(false);
|
|
995
|
+
}
|
|
996
|
+
catch (err) {
|
|
997
|
+
const e = err instanceof Error ? err : new Error(String(err));
|
|
998
|
+
setAgentEditError(e);
|
|
999
|
+
setAgentEditLoading(false);
|
|
1000
|
+
throw e;
|
|
1001
|
+
}
|
|
1002
|
+
};
|
|
1003
|
+
return {
|
|
1004
|
+
canEdit,
|
|
1005
|
+
startEdit,
|
|
1006
|
+
completeEdit,
|
|
1007
|
+
abortEdit,
|
|
1008
|
+
session: agentSession,
|
|
1009
|
+
sessionId: agentSession?.sessionId ?? null,
|
|
1010
|
+
isEditing: agentSession !== null,
|
|
1011
|
+
isLoading: agentEditLoading,
|
|
1012
|
+
error: agentEditError,
|
|
1013
|
+
};
|
|
1014
|
+
}, [
|
|
1015
|
+
agentModeEnabled,
|
|
1016
|
+
agentId,
|
|
1017
|
+
currentDocument,
|
|
1018
|
+
siteId,
|
|
1019
|
+
branchId,
|
|
1020
|
+
userClient,
|
|
1021
|
+
agentSession,
|
|
1022
|
+
agentEditLoading,
|
|
1023
|
+
agentEditError,
|
|
1024
|
+
]);
|
|
1025
|
+
// =========================================================================
|
|
1026
|
+
// Phase 9: Agent Trigger (for human users to trigger agents)
|
|
1027
|
+
// =========================================================================
|
|
1028
|
+
const triggerAgentFn = useMemo(() => {
|
|
1029
|
+
// Only available when agentModeEnabled but no agentId (human user)
|
|
1030
|
+
if (!agentModeEnabled || agentId)
|
|
1031
|
+
return null;
|
|
1032
|
+
const documentPath = currentDocument?.path ?? null;
|
|
1033
|
+
return async (action) => {
|
|
1034
|
+
if (!documentPath) {
|
|
1035
|
+
return { success: false, error: 'No document loaded' };
|
|
1036
|
+
}
|
|
1037
|
+
try {
|
|
1038
|
+
// Check permission
|
|
1039
|
+
const permission = await userClient.agentEdit.canEdit(siteId, branchId, documentPath, {
|
|
1040
|
+
agentId: action.agentId,
|
|
1041
|
+
trigger: 'human_requested',
|
|
1042
|
+
intent: action.intent,
|
|
1043
|
+
targetRegions: action.targetRegions,
|
|
1044
|
+
requestedById: userId,
|
|
1045
|
+
});
|
|
1046
|
+
if (!permission.allowed) {
|
|
1047
|
+
return { success: false, error: permission.reason };
|
|
1048
|
+
}
|
|
1049
|
+
// Start edit session
|
|
1050
|
+
const session = await userClient.agentEdit.startEdit(siteId, branchId, documentPath, {
|
|
1051
|
+
agentId: action.agentId,
|
|
1052
|
+
trigger: 'human_requested',
|
|
1053
|
+
intent: action.intent,
|
|
1054
|
+
targetRegions: action.targetRegions,
|
|
1055
|
+
requestedById: userId,
|
|
1056
|
+
});
|
|
1057
|
+
return { success: true, checkpointId: session.checkpointId };
|
|
1058
|
+
}
|
|
1059
|
+
catch (err) {
|
|
1060
|
+
return {
|
|
1061
|
+
success: false,
|
|
1062
|
+
error: err instanceof Error ? err.message : String(err),
|
|
1063
|
+
};
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
}, [agentModeEnabled, agentId, currentDocument, siteId, branchId, userId, userClient]);
|
|
1067
|
+
// =========================================================================
|
|
1068
|
+
// Phase 9: Conflict Notifications
|
|
1069
|
+
// =========================================================================
|
|
1070
|
+
const dismissConflict = useCallback((id) => {
|
|
1071
|
+
setConflicts((prev) => prev.filter((c) => c.id !== id));
|
|
1072
|
+
}, []);
|
|
1073
|
+
// Stop an agent's edit session (human-initiated)
|
|
1074
|
+
const handleStopAgent = useCallback(async (agent) => {
|
|
1075
|
+
const documentPath = currentDocumentRef.current?.path;
|
|
1076
|
+
if (!documentPath) {
|
|
1077
|
+
notificationContext.addError('Cannot stop agent: no document loaded');
|
|
1078
|
+
return;
|
|
1079
|
+
}
|
|
1080
|
+
try {
|
|
1081
|
+
await userClient.agentEdit.stopAgent(siteId, branchId, documentPath, agent.actorId);
|
|
1082
|
+
notificationContext.addSuccess(`Agent "${agent.name}" has been stopped`);
|
|
1083
|
+
// Refresh presence to reflect the agent's removal
|
|
1084
|
+
if (presenceEnabled) {
|
|
1085
|
+
void fetchPresenceRef.current();
|
|
1086
|
+
}
|
|
1087
|
+
}
|
|
1088
|
+
catch (err) {
|
|
1089
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1090
|
+
notificationContext.addError(`Failed to stop agent: ${message}`);
|
|
1091
|
+
}
|
|
1092
|
+
}, [userClient, siteId, branchId, notificationContext, presenceEnabled]);
|
|
1093
|
+
// Create checkpoint
|
|
1094
|
+
const createCheckpoint = useCallback(async (name) => {
|
|
1095
|
+
// Save any pending changes first
|
|
1096
|
+
if (pendingDataRef.current) {
|
|
1097
|
+
if (enableRealtime && realtimeConnectedRef.current) {
|
|
1098
|
+
// Data origin guard: only send if data belongs to current document
|
|
1099
|
+
const currentPath = currentDocumentRef.current?.path ?? null;
|
|
1100
|
+
if (currentDataDocumentPathRef.current === currentPath) {
|
|
1101
|
+
realtime.applyLocalChange(pendingDataRef.current);
|
|
1102
|
+
}
|
|
1103
|
+
pendingDataRef.current = null;
|
|
1104
|
+
}
|
|
1105
|
+
else {
|
|
1106
|
+
debouncedSave.cancel();
|
|
1107
|
+
await performSave();
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1110
|
+
// When realtime is connected, wait for the DO to acknowledge receipt of
|
|
1111
|
+
// all preceding WebSocket messages before creating the checkpoint.
|
|
1112
|
+
if (enableRealtime && realtimeConnectedRef.current) {
|
|
1113
|
+
try {
|
|
1114
|
+
await realtime.waitForDelivery();
|
|
1115
|
+
}
|
|
1116
|
+
catch {
|
|
1117
|
+
console.warn('[P1PuckProvider] Delivery ack before checkpoint failed, proceeding anyway');
|
|
1118
|
+
}
|
|
1119
|
+
}
|
|
1120
|
+
const checkpoint = await userClient.checkpoints.create(siteId, {
|
|
1121
|
+
branchId,
|
|
1122
|
+
name,
|
|
1123
|
+
type: 'manual',
|
|
1124
|
+
});
|
|
1125
|
+
return checkpoint;
|
|
1126
|
+
}, [userClient, siteId, branchId, debouncedSave, performSave, enableRealtime, realtime]);
|
|
1127
|
+
// Publish current document
|
|
1128
|
+
const publishDocument = useCallback(async () => {
|
|
1129
|
+
const doc = currentDocumentRef.current;
|
|
1130
|
+
if (!doc) {
|
|
1131
|
+
throw new Error('No document loaded to publish');
|
|
1132
|
+
}
|
|
1133
|
+
// Send any pending changes before publish
|
|
1134
|
+
if (pendingDataRef.current) {
|
|
1135
|
+
if (enableRealtime && realtimeConnectedRef.current) {
|
|
1136
|
+
const currentPath = currentDocumentRef.current?.path ?? null;
|
|
1137
|
+
if (currentDataDocumentPathRef.current === currentPath) {
|
|
1138
|
+
realtime.applyLocalChange(pendingDataRef.current);
|
|
1139
|
+
}
|
|
1140
|
+
pendingDataRef.current = null;
|
|
1141
|
+
}
|
|
1142
|
+
else {
|
|
1143
|
+
debouncedSave.cancel();
|
|
1144
|
+
await performSave();
|
|
1145
|
+
}
|
|
1146
|
+
}
|
|
1147
|
+
// When realtime is connected, use WebSocket-driven publish.
|
|
1148
|
+
// The DO handles the entire flow: flush CRDT to Postgres, then
|
|
1149
|
+
// create the checkpoint. TCP ordering guarantees all preceding
|
|
1150
|
+
// binary CRDT updates are processed before the publish_request.
|
|
1151
|
+
if (enableRealtime && realtimeConnectedRef.current) {
|
|
1152
|
+
const publishResult = await realtime.requestPublish();
|
|
1153
|
+
if (!publishResult.success) {
|
|
1154
|
+
throw new Error(publishResult.error ?? 'Publish failed');
|
|
1155
|
+
}
|
|
1156
|
+
if (!publishResult.checkpoint) {
|
|
1157
|
+
throw new Error('Publish succeeded but no checkpoint returned');
|
|
1158
|
+
}
|
|
1159
|
+
return publishResult.checkpoint;
|
|
1160
|
+
}
|
|
1161
|
+
// Fallback: HTTP publish when realtime is not connected
|
|
1162
|
+
const result = await userClient.documents.publish(siteId, branchId, doc.id);
|
|
1163
|
+
return result.checkpoint;
|
|
1164
|
+
}, [userClient, siteId, branchId, debouncedSave, performSave, enableRealtime, realtime]);
|
|
1165
|
+
// Switch branch
|
|
1166
|
+
const switchBranch = useCallback(async (newBranchId) => {
|
|
1167
|
+
// Cancel any pending remote sync - we're switching to a different branch
|
|
1168
|
+
cancelPendingRemoteSync();
|
|
1169
|
+
// Save any pending changes first
|
|
1170
|
+
if (pendingDataRef.current) {
|
|
1171
|
+
debouncedSave.cancel();
|
|
1172
|
+
await performSave();
|
|
1173
|
+
}
|
|
1174
|
+
// IMPORTANT: Update the ref BEFORE state updates
|
|
1175
|
+
viewingVersionRef.current = null;
|
|
1176
|
+
setBranchId(newBranchId);
|
|
1177
|
+
persistBranchId(newBranchId);
|
|
1178
|
+
setCurrentDocument(null);
|
|
1179
|
+
currentDataDocumentPathRef.current = null;
|
|
1180
|
+
setCurrentData(null);
|
|
1181
|
+
setViewingVersion(null);
|
|
1182
|
+
// Clear remoteSyncKey so new branch document sync takes priority
|
|
1183
|
+
setRemoteSyncKey(null);
|
|
1184
|
+
pendingDataRef.current = null;
|
|
1185
|
+
setSaveStatus('idle');
|
|
1186
|
+
setSaveError(null);
|
|
1187
|
+
// Update current branch
|
|
1188
|
+
const branch = branches.find((b) => b.id === newBranchId);
|
|
1189
|
+
setCurrentBranch(branch ?? null);
|
|
1190
|
+
}, [branches, debouncedSave, performSave, cancelPendingRemoteSync, persistBranchId]);
|
|
1191
|
+
// Presence context value (for hooks like useFocusRegionReporting)
|
|
1192
|
+
const presenceContextValue = useMemo(() => {
|
|
1193
|
+
if (!presenceEnabled)
|
|
1194
|
+
return null;
|
|
1195
|
+
const actors = presenceState?.actors ?? [];
|
|
1196
|
+
return {
|
|
1197
|
+
client: userClient,
|
|
1198
|
+
siteId,
|
|
1199
|
+
branchId,
|
|
1200
|
+
documentPath: currentDocument?.path ?? null,
|
|
1201
|
+
userId,
|
|
1202
|
+
currentUserId: userId,
|
|
1203
|
+
isConnected: realtime.connected,
|
|
1204
|
+
presence: actors,
|
|
1205
|
+
actors,
|
|
1206
|
+
activeAgents: presenceState?.agents?.filter(a => a.state === 'editing') ?? [],
|
|
1207
|
+
agentEditingRegions: presenceState?.agents
|
|
1208
|
+
?.filter(a => a.state === 'editing')
|
|
1209
|
+
?.flatMap(a => a.focusRegions ?? []) ?? [],
|
|
1210
|
+
isAgentEditing: presenceState?.hasActiveAgents ?? false,
|
|
1211
|
+
// Agent edit functions - placeholder implementations
|
|
1212
|
+
// These are handled by agentEditCapabilities in the main context
|
|
1213
|
+
canEdit: async () => ({ allowed: true }),
|
|
1214
|
+
startEdit: async () => ({ sessionId: '' }),
|
|
1215
|
+
completeEdit: async () => ({ success: true }),
|
|
1216
|
+
abortEdit: async () => ({ success: true }),
|
|
1217
|
+
subscribe: () => () => { },
|
|
1218
|
+
};
|
|
1219
|
+
}, [
|
|
1220
|
+
presenceEnabled,
|
|
1221
|
+
userClient,
|
|
1222
|
+
siteId,
|
|
1223
|
+
branchId,
|
|
1224
|
+
currentDocument?.path,
|
|
1225
|
+
userId,
|
|
1226
|
+
realtime.connected,
|
|
1227
|
+
presenceState,
|
|
1228
|
+
]);
|
|
1229
|
+
// =========================================================================
|
|
1230
|
+
// Stable Callback Wrappers
|
|
1231
|
+
// =========================================================================
|
|
1232
|
+
// Wrap volatile callbacks in refs + stable wrappers so consumers don't need
|
|
1233
|
+
// to stabilize them manually. The ref is updated inline during render (safe
|
|
1234
|
+
// because it's a ref write, not a state write) and the stable wrapper
|
|
1235
|
+
// delegates to ref.current, ensuring the latest implementation is always used.
|
|
1236
|
+
const saveDataRef = useRef(saveData);
|
|
1237
|
+
saveDataRef.current = saveData;
|
|
1238
|
+
const stableSaveData = useCallback((data) => saveDataRef.current(data), []);
|
|
1239
|
+
const saveNowRef = useRef(saveNow);
|
|
1240
|
+
saveNowRef.current = saveNow;
|
|
1241
|
+
const stableSaveNow = useCallback(() => saveNowRef.current(), []);
|
|
1242
|
+
const createCheckpointRef = useRef(createCheckpoint);
|
|
1243
|
+
createCheckpointRef.current = createCheckpoint;
|
|
1244
|
+
const stableCreateCheckpoint = useCallback((name) => createCheckpointRef.current(name), []);
|
|
1245
|
+
const publishDocumentRef = useRef(publishDocument);
|
|
1246
|
+
publishDocumentRef.current = publishDocument;
|
|
1247
|
+
const stablePublishDocument = useCallback(() => publishDocumentRef.current(), []);
|
|
1248
|
+
const pauseAutoSaveRef = useRef(pauseAutoSave);
|
|
1249
|
+
pauseAutoSaveRef.current = pauseAutoSave;
|
|
1250
|
+
const stablePauseAutoSave = useCallback(() => pauseAutoSaveRef.current(), []);
|
|
1251
|
+
const resumeAutoSaveRef = useRef(resumeAutoSave);
|
|
1252
|
+
resumeAutoSaveRef.current = resumeAutoSave;
|
|
1253
|
+
const stableResumeAutoSave = useCallback(() => resumeAutoSaveRef.current(), []);
|
|
1254
|
+
const switchBranchRef = useRef(switchBranch);
|
|
1255
|
+
switchBranchRef.current = switchBranch;
|
|
1256
|
+
const stableSwitchBranch = useCallback((newBranchId) => switchBranchRef.current(newBranchId), []);
|
|
1257
|
+
const loadDocumentRef = useRef(loadDocument);
|
|
1258
|
+
loadDocumentRef.current = loadDocument;
|
|
1259
|
+
const stableLoadDocument = useCallback((path) => loadDocumentRef.current(path), []);
|
|
1260
|
+
const loadVersionRef = useRef(loadVersion);
|
|
1261
|
+
loadVersionRef.current = loadVersion;
|
|
1262
|
+
const stableLoadVersion = useCallback((version) => loadVersionRef.current(version), []);
|
|
1263
|
+
const returnToLatestRef = useRef(returnToLatest);
|
|
1264
|
+
returnToLatestRef.current = returnToLatest;
|
|
1265
|
+
const stableReturnToLatest = useCallback(() => returnToLatestRef.current(), []);
|
|
1266
|
+
const handleStopAgentRef = useRef(handleStopAgent);
|
|
1267
|
+
handleStopAgentRef.current = handleStopAgent;
|
|
1268
|
+
const stableStopAgent = useCallback((agent) => handleStopAgentRef.current(agent), []);
|
|
1269
|
+
// =========================================================================
|
|
1270
|
+
// Stable Getters (Items 2 & 3)
|
|
1271
|
+
// =========================================================================
|
|
1272
|
+
// Refs updated inline during render, exposed as stable getter callbacks.
|
|
1273
|
+
const saveStatusGetterRef = useRef(saveStatus);
|
|
1274
|
+
saveStatusGetterRef.current = saveStatus;
|
|
1275
|
+
const getSaveStatus = useCallback(() => saveStatusGetterRef.current, []);
|
|
1276
|
+
const lastSavedGetterRef = useRef(lastSaved);
|
|
1277
|
+
lastSavedGetterRef.current = lastSaved;
|
|
1278
|
+
const getLastSaved = useCallback(() => lastSavedGetterRef.current, []);
|
|
1279
|
+
const saveErrorGetterRef = useRef(saveError);
|
|
1280
|
+
saveErrorGetterRef.current = saveError;
|
|
1281
|
+
const getSaveError = useCallback(() => saveErrorGetterRef.current, []);
|
|
1282
|
+
const getHasUnsavedChanges = useCallback(() => pendingDataRef.current !== null, []);
|
|
1283
|
+
// Data sync getters (Item 3)
|
|
1284
|
+
const currentDataGetterRef = useRef(currentData);
|
|
1285
|
+
currentDataGetterRef.current = currentData;
|
|
1286
|
+
const remoteSyncKeyGetterRef = useRef(remoteSyncKey);
|
|
1287
|
+
remoteSyncKeyGetterRef.current = remoteSyncKey;
|
|
1288
|
+
const currentDocumentGetterRef = useRef(currentDocument);
|
|
1289
|
+
currentDocumentGetterRef.current = currentDocument;
|
|
1290
|
+
const viewingVersionGetterRef = useRef(viewingVersion);
|
|
1291
|
+
viewingVersionGetterRef.current = viewingVersion;
|
|
1292
|
+
const getSyncData = useCallback(() => currentDataGetterRef.current ?? undefined, []);
|
|
1293
|
+
const getDataSyncKey = useCallback(() => {
|
|
1294
|
+
const syncKey = remoteSyncKeyGetterRef.current;
|
|
1295
|
+
const doc = currentDocumentGetterRef.current;
|
|
1296
|
+
const version = viewingVersionGetterRef.current;
|
|
1297
|
+
if (syncKey)
|
|
1298
|
+
return syncKey;
|
|
1299
|
+
if (version)
|
|
1300
|
+
return `version-${version.id}`;
|
|
1301
|
+
if (doc)
|
|
1302
|
+
return `doc-${doc.id}-latest`;
|
|
1303
|
+
return undefined;
|
|
1304
|
+
}, []);
|
|
1305
|
+
// =========================================================================
|
|
1306
|
+
// Plugin Composition (B.4)
|
|
1307
|
+
// =========================================================================
|
|
1308
|
+
const resolvedFeatureConfig = useMemo(() => {
|
|
1309
|
+
if (featureConfig)
|
|
1310
|
+
return resolveFeatureConfig(featureConfig);
|
|
1311
|
+
return resolveFeatureConfig({
|
|
1312
|
+
enableRealtime,
|
|
1313
|
+
presenceEnabled,
|
|
1314
|
+
agentModeEnabled,
|
|
1315
|
+
});
|
|
1316
|
+
}, [featureConfig, enableRealtime, presenceEnabled, agentModeEnabled]);
|
|
1317
|
+
const activePlugins = useMemo(() => {
|
|
1318
|
+
const plugins = featurePlugins ?? DEFAULT_CSS_FEATURE_PLUGINS;
|
|
1319
|
+
return resolveActivePlugins(plugins, resolvedFeatureConfig);
|
|
1320
|
+
}, [featurePlugins, resolvedFeatureConfig]);
|
|
1321
|
+
const pluginDeps = useMemo(() => ({
|
|
1322
|
+
client: userClient,
|
|
1323
|
+
siteId,
|
|
1324
|
+
branchId,
|
|
1325
|
+
userId,
|
|
1326
|
+
config: resolvedFeatureConfig,
|
|
1327
|
+
}), [userClient, siteId, branchId, userId, resolvedFeatureConfig]);
|
|
1328
|
+
const ComposedPluginProviders = useMemo(() => composeProviders(activePlugins, resolvedFeatureConfig, pluginDeps), [activePlugins, resolvedFeatureConfig, pluginDeps]);
|
|
1329
|
+
// =========================================================================
|
|
1330
|
+
// safeData (Item 4) — never null
|
|
1331
|
+
// =========================================================================
|
|
1332
|
+
const EMPTY_PUCK_DATA = useMemo(() => ({ content: [], root: { props: {} } }), []);
|
|
1333
|
+
const lastGoodDataRef = useRef(EMPTY_PUCK_DATA);
|
|
1334
|
+
if (currentDocument && currentData) {
|
|
1335
|
+
lastGoodDataRef.current = currentData;
|
|
1336
|
+
}
|
|
1337
|
+
const safeData = lastGoodDataRef.current;
|
|
1338
|
+
// Context value
|
|
1339
|
+
const contextValue = useMemo(() => ({
|
|
1340
|
+
client: userClient,
|
|
1341
|
+
notifications: notificationContext,
|
|
1342
|
+
siteId,
|
|
1343
|
+
siteName,
|
|
1344
|
+
branchId,
|
|
1345
|
+
userId,
|
|
1346
|
+
currentDocument,
|
|
1347
|
+
currentData,
|
|
1348
|
+
saveStatus,
|
|
1349
|
+
lastSaved,
|
|
1350
|
+
saveError,
|
|
1351
|
+
loadDocument: stableLoadDocument,
|
|
1352
|
+
saveData: stableSaveData,
|
|
1353
|
+
saveNow: stableSaveNow,
|
|
1354
|
+
createCheckpoint: stableCreateCheckpoint,
|
|
1355
|
+
publishDocument: stablePublishDocument,
|
|
1356
|
+
switchBranch: stableSwitchBranch,
|
|
1357
|
+
// Stable getters (Items 2, 3)
|
|
1358
|
+
getSaveStatus,
|
|
1359
|
+
getLastSaved,
|
|
1360
|
+
getSaveError,
|
|
1361
|
+
getHasUnsavedChanges,
|
|
1362
|
+
getSyncData,
|
|
1363
|
+
getDataSyncKey,
|
|
1364
|
+
// safeData (Item 4)
|
|
1365
|
+
safeData,
|
|
1366
|
+
// Documents (Item 8)
|
|
1367
|
+
documents: branchDocuments,
|
|
1368
|
+
documentsLoading,
|
|
1369
|
+
createDocument: stableCreateDocument,
|
|
1370
|
+
deleteDocument: stableDeleteDocument,
|
|
1371
|
+
branches,
|
|
1372
|
+
currentBranch,
|
|
1373
|
+
refreshBranches,
|
|
1374
|
+
createBranch,
|
|
1375
|
+
branchesLoading,
|
|
1376
|
+
autoSavePaused,
|
|
1377
|
+
pauseAutoSave: stablePauseAutoSave,
|
|
1378
|
+
resumeAutoSave: stableResumeAutoSave,
|
|
1379
|
+
viewingVersion,
|
|
1380
|
+
latestVersionData,
|
|
1381
|
+
isViewingHistoricalVersion,
|
|
1382
|
+
loadVersion: stableLoadVersion,
|
|
1383
|
+
returnToLatest: stableReturnToLatest,
|
|
1384
|
+
realtimeEnabled: enableRealtime,
|
|
1385
|
+
realtimeConnected: realtime.connected,
|
|
1386
|
+
remoteSyncKey,
|
|
1387
|
+
// WebSocket presence - send focus regions via WebSocket when connected
|
|
1388
|
+
sendFocusRegions: realtime.sendFocusRegions,
|
|
1389
|
+
// Puck action metadata capture - pass as onAction to <Puck>
|
|
1390
|
+
handleAction,
|
|
1391
|
+
// Phase 9: Presence & Agent values
|
|
1392
|
+
// Use getter to avoid context recreation on every focus-region update.
|
|
1393
|
+
// Expose humanPresenceCount/hasActiveHumans/hasActiveAgents directly so every
|
|
1394
|
+
// join/leave triggers context re-renders and causes consumers to re-invoke the getter.
|
|
1395
|
+
get presence() { return presenceStateRef.current; },
|
|
1396
|
+
hasActiveHumans: presenceState?.hasActiveHumans ?? false,
|
|
1397
|
+
humanPresenceCount: presenceState?.humans.length ?? 0,
|
|
1398
|
+
hasActiveAgents: presenceState?.hasActiveAgents ?? false,
|
|
1399
|
+
agentEdit: agentEditCapabilities,
|
|
1400
|
+
triggerAgent: triggerAgentFn,
|
|
1401
|
+
stopAgent: stableStopAgent,
|
|
1402
|
+
conflicts,
|
|
1403
|
+
dismissConflict,
|
|
1404
|
+
// Feature configuration (Phase B.5)
|
|
1405
|
+
featureConfig: resolvedFeatureConfig,
|
|
1406
|
+
// Internal: realtime data capture for catch-up (sends missed keystrokes)
|
|
1407
|
+
_realtimeDataCaptureRef: enableRealtime ? realtimeDataCaptureRef : null,
|
|
1408
|
+
_onRealtimeDataCapture: enableRealtime ? handleRealtimeDataCapture : null,
|
|
1409
|
+
}), [
|
|
1410
|
+
userClient,
|
|
1411
|
+
notificationContext,
|
|
1412
|
+
siteId,
|
|
1413
|
+
branchId,
|
|
1414
|
+
userId,
|
|
1415
|
+
currentDocument,
|
|
1416
|
+
currentData,
|
|
1417
|
+
saveStatus,
|
|
1418
|
+
lastSaved,
|
|
1419
|
+
saveError,
|
|
1420
|
+
stableLoadDocument,
|
|
1421
|
+
stableSaveData,
|
|
1422
|
+
stableSaveNow,
|
|
1423
|
+
stableCreateCheckpoint,
|
|
1424
|
+
stablePublishDocument,
|
|
1425
|
+
stableSwitchBranch,
|
|
1426
|
+
getSaveStatus,
|
|
1427
|
+
getLastSaved,
|
|
1428
|
+
getSaveError,
|
|
1429
|
+
getHasUnsavedChanges,
|
|
1430
|
+
getSyncData,
|
|
1431
|
+
getDataSyncKey,
|
|
1432
|
+
safeData,
|
|
1433
|
+
branchDocuments,
|
|
1434
|
+
documentsLoading,
|
|
1435
|
+
stableCreateDocument,
|
|
1436
|
+
stableDeleteDocument,
|
|
1437
|
+
branches,
|
|
1438
|
+
currentBranch,
|
|
1439
|
+
refreshBranches,
|
|
1440
|
+
branchesLoading,
|
|
1441
|
+
autoSavePaused,
|
|
1442
|
+
stablePauseAutoSave,
|
|
1443
|
+
stableResumeAutoSave,
|
|
1444
|
+
viewingVersion,
|
|
1445
|
+
latestVersionData,
|
|
1446
|
+
isViewingHistoricalVersion,
|
|
1447
|
+
stableLoadVersion,
|
|
1448
|
+
stableReturnToLatest,
|
|
1449
|
+
enableRealtime,
|
|
1450
|
+
realtime.connected,
|
|
1451
|
+
remoteSyncKey,
|
|
1452
|
+
realtime.sendFocusRegions,
|
|
1453
|
+
handleAction,
|
|
1454
|
+
handleRealtimeDataCapture,
|
|
1455
|
+
// Phase 9 dependencies (full presenceState excluded — accessed via getter/ref,
|
|
1456
|
+
// but humanPresenceCount/hasActiveHumans/hasActiveAgents are direct values so every
|
|
1457
|
+
// join/leave triggers re-renders regardless of how many actors are present)
|
|
1458
|
+
presenceState?.humans.length,
|
|
1459
|
+
presenceState?.hasActiveHumans,
|
|
1460
|
+
presenceState?.hasActiveAgents,
|
|
1461
|
+
agentEditCapabilities,
|
|
1462
|
+
triggerAgentFn,
|
|
1463
|
+
stableStopAgent,
|
|
1464
|
+
conflicts,
|
|
1465
|
+
dismissConflict,
|
|
1466
|
+
enableRealtime,
|
|
1467
|
+
resolvedFeatureConfig,
|
|
1468
|
+
]);
|
|
1469
|
+
// Wrap with PresenceContext.Provider when presence is enabled
|
|
1470
|
+
const wrappedChildren = presenceContextValue ? (_jsx(PresenceContext.Provider, { value: presenceContextValue, children: children })) : (children);
|
|
1471
|
+
return (_jsx(P1PuckContext.Provider, { value: contextValue, children: _jsx(ComposedPluginProviders, { children: wrappedChildren }) }));
|
|
1472
|
+
}
|
|
1473
|
+
//# sourceMappingURL=P1PuckProvider.js.map
|