@pantheon-systems/puck-css 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (433) hide show
  1. package/dist/agent/useAgentEdit.d.ts.map +1 -1
  2. package/dist/agent/useAgentEdit.js.map +1 -1
  3. package/dist/agent/useAgentTrigger.d.ts.map +1 -1
  4. package/dist/agent/useAgentTrigger.js.map +1 -1
  5. package/dist/auth/AuthGate.d.ts +1 -1
  6. package/dist/auth/AuthGate.d.ts.map +1 -1
  7. package/dist/collaboration/utils/avatarColor.d.ts +2 -8
  8. package/dist/collaboration/utils/avatarColor.d.ts.map +1 -1
  9. package/dist/collaboration/utils/avatarColor.js +4 -31
  10. package/dist/collaboration/utils/avatarColor.js.map +1 -1
  11. package/dist/collaboration/utils/focusHighlightConfig.d.ts.map +1 -1
  12. package/dist/collaboration/utils/focusHighlightConfig.js.map +1 -1
  13. package/dist/collaboration/utils/initials.d.ts +2 -0
  14. package/dist/collaboration/utils/initials.d.ts.map +1 -0
  15. package/dist/collaboration/utils/initials.js +27 -0
  16. package/dist/collaboration/utils/initials.js.map +1 -0
  17. package/dist/collaboration/utils/presenceIdentity.d.ts +29 -0
  18. package/dist/collaboration/utils/presenceIdentity.d.ts.map +1 -0
  19. package/dist/collaboration/utils/presenceIdentity.js +42 -0
  20. package/dist/collaboration/utils/presenceIdentity.js.map +1 -0
  21. package/dist/core/config.d.ts +2 -2
  22. package/dist/core/config.d.ts.map +1 -1
  23. package/dist/core/config.js +1 -1
  24. package/dist/core/config.js.map +1 -1
  25. package/dist/core/types.d.ts +21 -4
  26. package/dist/core/types.d.ts.map +1 -1
  27. package/dist/data/css-queries/css-query-registry.d.ts +11 -0
  28. package/dist/data/css-queries/css-query-registry.d.ts.map +1 -0
  29. package/dist/data/css-queries/css-query-registry.js +28 -0
  30. package/dist/data/css-queries/css-query-registry.js.map +1 -0
  31. package/dist/data/dal/index.d.ts +1 -1
  32. package/dist/data/dal/index.d.ts.map +1 -1
  33. package/dist/data/dal/init.d.ts +5 -0
  34. package/dist/data/dal/init.d.ts.map +1 -1
  35. package/dist/data/dal/init.js +31 -4
  36. package/dist/data/dal/init.js.map +1 -1
  37. package/dist/data/dal/p1-store.d.ts +23 -0
  38. package/dist/data/dal/p1-store.d.ts.map +1 -1
  39. package/dist/data/dal/p1-store.js +14 -1
  40. package/dist/data/dal/p1-store.js.map +1 -1
  41. package/dist/data/page-editor-meta.d.ts.map +1 -1
  42. package/dist/data/page-editor-meta.js +0 -1
  43. package/dist/data/page-editor-meta.js.map +1 -1
  44. package/dist/data/query-provider.d.ts +1 -1
  45. package/dist/data/query-provider.d.ts.map +1 -1
  46. package/dist/data/remote-datasources/fetch-http-json.d.ts.map +1 -1
  47. package/dist/data/remote-datasources/fetch-http-json.js.map +1 -1
  48. package/dist/data/remote-datasources/loader.js +1 -1
  49. package/dist/data/remote-datasources/loader.js.map +1 -1
  50. package/dist/data/resolve-data-templates.d.ts.map +1 -1
  51. package/dist/data/resolve-data-templates.js +26 -4
  52. package/dist/data/resolve-data-templates.js.map +1 -1
  53. package/dist/editor/P1App.d.ts.map +1 -1
  54. package/dist/editor/P1App.js +1 -1
  55. package/dist/editor/P1App.js.map +1 -1
  56. package/dist/editor/P1PuckProvider.d.ts.map +1 -1
  57. package/dist/editor/P1PuckProvider.js +174 -57
  58. package/dist/editor/P1PuckProvider.js.map +1 -1
  59. package/dist/editor/aiPanelStore.d.ts +15 -0
  60. package/dist/editor/aiPanelStore.d.ts.map +1 -0
  61. package/dist/editor/aiPanelStore.js +43 -0
  62. package/dist/editor/aiPanelStore.js.map +1 -0
  63. package/dist/editor/components/CollapsibleFieldSection.d.ts +10 -0
  64. package/dist/editor/components/CollapsibleFieldSection.d.ts.map +1 -0
  65. package/dist/editor/components/CollapsibleFieldSection.js +9 -0
  66. package/dist/editor/components/CollapsibleFieldSection.js.map +1 -0
  67. package/dist/editor/components/CollapsibleSection.module.css +70 -0
  68. package/dist/editor/components/CollapsibleSectionHeader.d.ts +20 -0
  69. package/dist/editor/components/CollapsibleSectionHeader.d.ts.map +1 -0
  70. package/dist/editor/components/CollapsibleSectionHeader.js +10 -0
  71. package/dist/editor/components/CollapsibleSectionHeader.js.map +1 -0
  72. package/dist/editor/components/DraggableRow.d.ts +13 -0
  73. package/dist/editor/components/DraggableRow.d.ts.map +1 -0
  74. package/dist/editor/components/DraggableRow.js +20 -0
  75. package/dist/editor/components/DraggableRow.js.map +1 -0
  76. package/dist/editor/components/FieldHelpText.d.ts +6 -0
  77. package/dist/editor/components/FieldHelpText.d.ts.map +1 -0
  78. package/dist/editor/components/FieldHelpText.js +6 -0
  79. package/dist/editor/components/FieldHelpText.js.map +1 -0
  80. package/dist/editor/components/FieldHelpText.module.css +13 -0
  81. package/dist/editor/components/InspectorTabHeader.d.ts +18 -0
  82. package/dist/editor/components/InspectorTabHeader.d.ts.map +1 -0
  83. package/dist/editor/components/InspectorTabHeader.js +16 -0
  84. package/dist/editor/components/InspectorTabHeader.js.map +1 -0
  85. package/dist/editor/components/OutlinePanel.d.ts +10 -0
  86. package/dist/editor/components/OutlinePanel.d.ts.map +1 -0
  87. package/dist/editor/components/OutlinePanel.js +64 -0
  88. package/dist/editor/components/OutlinePanel.js.map +1 -0
  89. package/dist/editor/components/OutlinePanel.module.css +111 -0
  90. package/dist/editor/components/P1InspectorFields.d.ts +16 -0
  91. package/dist/editor/components/P1InspectorFields.d.ts.map +1 -0
  92. package/dist/editor/components/P1InspectorFields.js +61 -0
  93. package/dist/editor/components/P1InspectorFields.js.map +1 -0
  94. package/dist/editor/components/P1TemplateFields.d.ts +11 -0
  95. package/dist/editor/components/P1TemplateFields.d.ts.map +1 -0
  96. package/dist/editor/components/P1TemplateFields.js +52 -0
  97. package/dist/editor/components/P1TemplateFields.js.map +1 -0
  98. package/dist/editor/components/PanelHeader.d.ts +25 -0
  99. package/dist/editor/components/PanelHeader.d.ts.map +1 -0
  100. package/dist/editor/components/PanelHeader.js +12 -0
  101. package/dist/editor/components/PanelHeader.js.map +1 -0
  102. package/dist/editor/components/PanelHeader.module.css +34 -0
  103. package/dist/editor/components/PanelShell.d.ts +10 -0
  104. package/dist/editor/components/PanelShell.d.ts.map +1 -0
  105. package/dist/editor/components/PanelShell.js +7 -0
  106. package/dist/editor/components/PanelShell.js.map +1 -0
  107. package/dist/editor/components/PanelShell.module.css +15 -0
  108. package/dist/editor/components/PreviewPanelOverlay.d.ts +12 -0
  109. package/dist/editor/components/PreviewPanelOverlay.d.ts.map +1 -0
  110. package/dist/editor/components/PreviewPanelOverlay.js +7 -0
  111. package/dist/editor/components/PreviewPanelOverlay.js.map +1 -0
  112. package/dist/editor/components/PublishedStatusBadge.d.ts +1 -1
  113. package/dist/editor/components/PublishedStatusBadge.d.ts.map +1 -1
  114. package/dist/editor/components/VersionBannerOverride.d.ts +5 -1
  115. package/dist/editor/components/VersionBannerOverride.d.ts.map +1 -1
  116. package/dist/editor/components/VersionBannerOverride.js +24 -7
  117. package/dist/editor/components/VersionBannerOverride.js.map +1 -1
  118. package/dist/editor/components/VersionTimeline.d.ts +20 -0
  119. package/dist/editor/components/VersionTimeline.d.ts.map +1 -0
  120. package/dist/editor/components/VersionTimeline.js +42 -0
  121. package/dist/editor/components/VersionTimeline.js.map +1 -0
  122. package/dist/editor/components/collapsibleSectionContext.d.ts +17 -0
  123. package/dist/editor/components/collapsibleSectionContext.d.ts.map +1 -0
  124. package/dist/editor/components/collapsibleSectionContext.js +13 -0
  125. package/dist/editor/components/collapsibleSectionContext.js.map +1 -0
  126. package/dist/editor/components/componentIconName.d.ts +15 -0
  127. package/dist/editor/components/componentIconName.d.ts.map +1 -0
  128. package/dist/editor/components/componentIconName.js +68 -0
  129. package/dist/editor/components/componentIconName.js.map +1 -0
  130. package/dist/editor/components/connectable.d.ts +1 -1
  131. package/dist/editor/components/connectable.d.ts.map +1 -1
  132. package/dist/editor/components/merge-preview/MergePreviewPanel.d.ts.map +1 -1
  133. package/dist/editor/components/merge-preview/MergePreviewPanel.js.map +1 -1
  134. package/dist/editor/components/merge-preview/MergePreviewRenderer.js +3 -15
  135. package/dist/editor/components/merge-preview/MergePreviewRenderer.js.map +1 -1
  136. package/dist/editor/components/outlineTree.d.ts +68 -0
  137. package/dist/editor/components/outlineTree.d.ts.map +1 -0
  138. package/dist/editor/components/outlineTree.js +72 -0
  139. package/dist/editor/components/outlineTree.js.map +1 -0
  140. package/dist/editor/components/useDragReorder.d.ts +16 -0
  141. package/dist/editor/components/useDragReorder.d.ts.map +1 -0
  142. package/dist/editor/components/useDragReorder.js +35 -0
  143. package/dist/editor/components/useDragReorder.js.map +1 -0
  144. package/dist/editor/index.d.ts +13 -0
  145. package/dist/editor/index.d.ts.map +1 -1
  146. package/dist/editor/index.js +8 -0
  147. package/dist/editor/index.js.map +1 -1
  148. package/dist/editor/plugin/P1Plugin.d.ts +25 -2
  149. package/dist/editor/plugin/P1Plugin.d.ts.map +1 -1
  150. package/dist/editor/plugin/P1Plugin.js +147 -63
  151. package/dist/editor/plugin/P1Plugin.js.map +1 -1
  152. package/dist/editor/plugin/context-sync-key.d.ts +30 -0
  153. package/dist/editor/plugin/context-sync-key.d.ts.map +1 -0
  154. package/dist/editor/plugin/context-sync-key.js +36 -0
  155. package/dist/editor/plugin/context-sync-key.js.map +1 -0
  156. package/dist/editor/plugin/createP1Overrides.d.ts +33 -50
  157. package/dist/editor/plugin/createP1Overrides.d.ts.map +1 -1
  158. package/dist/editor/plugin/createP1Overrides.js +54 -112
  159. package/dist/editor/plugin/createP1Overrides.js.map +1 -1
  160. package/dist/editor/plugin/document-sync-plugin.d.ts +35 -0
  161. package/dist/editor/plugin/document-sync-plugin.d.ts.map +1 -0
  162. package/dist/editor/plugin/document-sync-plugin.js +130 -0
  163. package/dist/editor/plugin/document-sync-plugin.js.map +1 -0
  164. package/dist/editor/plugin/fieldGuidance.d.ts +45 -0
  165. package/dist/editor/plugin/fieldGuidance.d.ts.map +1 -0
  166. package/dist/editor/plugin/fieldGuidance.js +24 -0
  167. package/dist/editor/plugin/fieldGuidance.js.map +1 -0
  168. package/dist/editor/plugin/mergePreviewPlugin.d.ts.map +1 -1
  169. package/dist/editor/plugin/mergePreviewPlugin.js.map +1 -1
  170. package/dist/editor/plugin/selectHeaderCollaborators.d.ts +12 -0
  171. package/dist/editor/plugin/selectHeaderCollaborators.d.ts.map +1 -0
  172. package/dist/editor/plugin/selectHeaderCollaborators.js +15 -0
  173. package/dist/editor/plugin/selectHeaderCollaborators.js.map +1 -0
  174. package/dist/editor/thumbnails/LiveThumbnail.d.ts +47 -0
  175. package/dist/editor/thumbnails/LiveThumbnail.d.ts.map +1 -0
  176. package/dist/editor/thumbnails/LiveThumbnail.js +120 -0
  177. package/dist/editor/thumbnails/LiveThumbnail.js.map +1 -0
  178. package/dist/editor/thumbnails/ThumbnailCard.d.ts +37 -0
  179. package/dist/editor/thumbnails/ThumbnailCard.d.ts.map +1 -0
  180. package/dist/editor/thumbnails/ThumbnailCard.js +91 -0
  181. package/dist/editor/thumbnails/ThumbnailCard.js.map +1 -0
  182. package/dist/editor/thumbnails/buildLiveThumbnailDrawer.d.ts +33 -0
  183. package/dist/editor/thumbnails/buildLiveThumbnailDrawer.d.ts.map +1 -0
  184. package/dist/editor/thumbnails/buildLiveThumbnailDrawer.js +79 -0
  185. package/dist/editor/thumbnails/buildLiveThumbnailDrawer.js.map +1 -0
  186. package/dist/editor/thumbnails/humanizeComponentName.d.ts +18 -0
  187. package/dist/editor/thumbnails/humanizeComponentName.d.ts.map +1 -0
  188. package/dist/editor/thumbnails/humanizeComponentName.js +32 -0
  189. package/dist/editor/thumbnails/humanizeComponentName.js.map +1 -0
  190. package/dist/editor/thumbnails/resolveLiveThumbnailDrawer.d.ts +15 -0
  191. package/dist/editor/thumbnails/resolveLiveThumbnailDrawer.d.ts.map +1 -0
  192. package/dist/editor/thumbnails/resolveLiveThumbnailDrawer.js +19 -0
  193. package/dist/editor/thumbnails/resolveLiveThumbnailDrawer.js.map +1 -0
  194. package/dist/editor/thumbnails/thumbnailCache.d.ts +39 -0
  195. package/dist/editor/thumbnails/thumbnailCache.d.ts.map +1 -0
  196. package/dist/editor/thumbnails/thumbnailCache.js +97 -0
  197. package/dist/editor/thumbnails/thumbnailCache.js.map +1 -0
  198. package/dist/editor/useDocuments.d.ts.map +1 -1
  199. package/dist/editor/useDocuments.js +27 -15
  200. package/dist/editor/useDocuments.js.map +1 -1
  201. package/dist/editor/useP1Editor.d.ts +15 -13
  202. package/dist/editor/useP1Editor.d.ts.map +1 -1
  203. package/dist/editor/useP1Editor.js +97 -20
  204. package/dist/editor/useP1Editor.js.map +1 -1
  205. package/dist/editor/useP1Overrides.d.ts +1 -1
  206. package/dist/editor/useP1Overrides.d.ts.map +1 -1
  207. package/dist/editor/useP1Overrides.js.map +1 -1
  208. package/dist/editor/useP1Plugin.d.ts +20 -2
  209. package/dist/editor/useP1Plugin.d.ts.map +1 -1
  210. package/dist/editor/useP1Plugin.js +5 -0
  211. package/dist/editor/useP1Plugin.js.map +1 -1
  212. package/dist/editor/useRealtime.d.ts +2 -2
  213. package/dist/editor/useRealtime.d.ts.map +1 -1
  214. package/dist/editor/useRealtime.js.map +1 -1
  215. package/dist/editor/utils/componentRegistry.d.ts +4 -4
  216. package/dist/editor/utils/componentRegistry.d.ts.map +1 -1
  217. package/dist/editor/utils/componentRegistry.js +0 -1
  218. package/dist/editor/utils/componentRegistry.js.map +1 -1
  219. package/dist/editor/utils/puckYjsBinding.d.ts.map +1 -1
  220. package/dist/editor/utils/puckYjsBinding.js +6 -4
  221. package/dist/editor/utils/puckYjsBinding.js.map +1 -1
  222. package/dist/editor/utils/restoreDocumentVersion.d.ts +18 -0
  223. package/dist/editor/utils/restoreDocumentVersion.d.ts.map +1 -0
  224. package/dist/editor/utils/restoreDocumentVersion.js +49 -0
  225. package/dist/editor/utils/restoreDocumentVersion.js.map +1 -0
  226. package/dist/editor/utils/sanitizeRichtextDefaults.d.ts +22 -0
  227. package/dist/editor/utils/sanitizeRichtextDefaults.d.ts.map +1 -0
  228. package/dist/editor/utils/sanitizeRichtextDefaults.js +98 -0
  229. package/dist/editor/utils/sanitizeRichtextDefaults.js.map +1 -0
  230. package/dist/editor/utils/snapshotToPuckData.d.ts +11 -0
  231. package/dist/editor/utils/snapshotToPuckData.d.ts.map +1 -0
  232. package/dist/editor/utils/snapshotToPuckData.js +27 -0
  233. package/dist/editor/utils/snapshotToPuckData.js.map +1 -0
  234. package/dist/editor/utils/syncComponentRegistry.d.ts.map +1 -1
  235. package/dist/editor/utils/syncComponentRegistry.js +32 -6
  236. package/dist/editor/utils/syncComponentRegistry.js.map +1 -1
  237. package/dist/editor/utils/templatePath.d.ts +8 -0
  238. package/dist/editor/utils/templatePath.d.ts.map +1 -0
  239. package/dist/editor/utils/templatePath.js +14 -0
  240. package/dist/editor/utils/templatePath.js.map +1 -0
  241. package/dist/features/content-type-templates/permissions/createPuckPermissions.d.ts +10 -7
  242. package/dist/features/content-type-templates/permissions/createPuckPermissions.d.ts.map +1 -1
  243. package/dist/features/content-type-templates/permissions/createPuckPermissions.js +27 -8
  244. package/dist/features/content-type-templates/permissions/createPuckPermissions.js.map +1 -1
  245. package/dist/features/content-type-templates/stores/template-store-api.d.ts.map +1 -1
  246. package/dist/features/content-type-templates/ui/ActionBarPinButton.d.ts.map +1 -1
  247. package/dist/features/content-type-templates/ui/ActionBarPinButton.js +1 -1
  248. package/dist/features/content-type-templates/ui/ActionBarPinButton.js.map +1 -1
  249. package/dist/features/content-type-templates/validation/structural-validation.d.ts +4 -4
  250. package/dist/features/content-type-templates/validation/structural-validation.d.ts.map +1 -1
  251. package/dist/features/content-type-templates/validation/structural-validation.js +123 -50
  252. package/dist/features/content-type-templates/validation/structural-validation.js.map +1 -1
  253. package/dist/index.d.ts +10 -2
  254. package/dist/index.d.ts.map +1 -1
  255. package/dist/index.js +10 -2
  256. package/dist/index.js.map +1 -1
  257. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js +1 -3
  258. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js.map +1 -1
  259. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js +2 -2
  260. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js.map +1 -1
  261. package/dist/p1/editor/client.d.ts +1 -1
  262. package/dist/p1/editor/client.d.ts.map +1 -1
  263. package/dist/p1/editor/client.js +3 -3
  264. package/dist/p1/editor/client.js.map +1 -1
  265. package/dist/p1/editor/connect/connect-field-modal.d.ts +1 -1
  266. package/dist/p1/editor/connect/connect-field-modal.d.ts.map +1 -1
  267. package/dist/p1/editor/connect/connect-field-modal.js +2 -2
  268. package/dist/p1/editor/connect/connect-field-modal.js.map +1 -1
  269. package/dist/p1/editor/connect/connect-preview-config.d.ts +1 -1
  270. package/dist/p1/editor/connect/connect-preview-config.d.ts.map +1 -1
  271. package/dist/p1/editor/connect/field-connect-plugin.js +1 -1
  272. package/dist/p1/editor/connect/field-connect-plugin.js.map +1 -1
  273. package/dist/p1/editor/editor-preview-resolve.d.ts +7 -1
  274. package/dist/p1/editor/editor-preview-resolve.d.ts.map +1 -1
  275. package/dist/p1/editor/editor-preview-resolve.js +9 -2
  276. package/dist/p1/editor/editor-preview-resolve.js.map +1 -1
  277. package/dist/p1/editor/{hooks.d.ts → hooks/api-hooks.d.ts} +9 -20
  278. package/dist/p1/editor/hooks/api-hooks.d.ts.map +1 -0
  279. package/dist/p1/editor/{hooks.js → hooks/api-hooks.js} +72 -57
  280. package/dist/p1/editor/hooks/api-hooks.js.map +1 -0
  281. package/dist/p1/editor/hooks/index.d.ts +4 -0
  282. package/dist/p1/editor/hooks/index.d.ts.map +1 -0
  283. package/dist/p1/editor/hooks/index.js +4 -0
  284. package/dist/p1/editor/hooks/index.js.map +1 -0
  285. package/dist/p1/editor/hooks/useEditorContext.d.ts +13 -0
  286. package/dist/p1/editor/hooks/useEditorContext.d.ts.map +1 -0
  287. package/dist/p1/editor/hooks/useEditorContext.js +25 -0
  288. package/dist/p1/editor/hooks/useEditorContext.js.map +1 -0
  289. package/dist/p1/editor/hooks/useP1Plugins.d.ts +3 -0
  290. package/dist/p1/editor/hooks/useP1Plugins.d.ts.map +1 -0
  291. package/dist/p1/editor/hooks/useP1Plugins.js +33 -0
  292. package/dist/p1/editor/hooks/useP1Plugins.js.map +1 -0
  293. package/dist/p1/editor/icons/button-block-icon.d.ts +1 -1
  294. package/dist/p1/editor/icons/button-block-icon.d.ts.map +1 -1
  295. package/dist/p1/editor/icons/default-block-icon.d.ts +1 -1
  296. package/dist/p1/editor/icons/default-block-icon.d.ts.map +1 -1
  297. package/dist/p1/editor/icons/divider-block-icon.d.ts +1 -1
  298. package/dist/p1/editor/icons/divider-block-icon.d.ts.map +1 -1
  299. package/dist/p1/editor/icons/grid-block-icon.d.ts +1 -1
  300. package/dist/p1/editor/icons/grid-block-icon.d.ts.map +1 -1
  301. package/dist/p1/editor/icons/heading-block-icon.d.ts +1 -1
  302. package/dist/p1/editor/icons/heading-block-icon.d.ts.map +1 -1
  303. package/dist/p1/editor/icons/image-block-icon.d.ts +1 -1
  304. package/dist/p1/editor/icons/image-block-icon.d.ts.map +1 -1
  305. package/dist/p1/editor/icons/list-block-icon.d.ts +1 -1
  306. package/dist/p1/editor/icons/list-block-icon.d.ts.map +1 -1
  307. package/dist/p1/editor/icons/paragraph-block-icon.d.ts +1 -1
  308. package/dist/p1/editor/icons/paragraph-block-icon.d.ts.map +1 -1
  309. package/dist/p1/editor/icons/quote-block-icon.d.ts +1 -1
  310. package/dist/p1/editor/icons/quote-block-icon.d.ts.map +1 -1
  311. package/dist/p1/editor/icons/spacer-block-icon.d.ts +1 -1
  312. package/dist/p1/editor/icons/spacer-block-icon.d.ts.map +1 -1
  313. package/dist/p1/editor/index.d.ts +2 -2
  314. package/dist/p1/editor/index.d.ts.map +1 -1
  315. package/dist/p1/editor/index.js +2 -2
  316. package/dist/p1/editor/index.js.map +1 -1
  317. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js +65 -67
  318. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js.map +1 -1
  319. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts +4 -4
  320. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts.map +1 -1
  321. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.js.map +1 -1
  322. package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts +1 -1
  323. package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts.map +1 -1
  324. package/dist/p1/editor/remote-datasources/remote-datasource-manager.js +2 -2
  325. package/dist/p1/editor/remote-datasources/remote-datasource-manager.js.map +1 -1
  326. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts +1 -1
  327. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts.map +1 -1
  328. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js +2 -2
  329. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js.map +1 -1
  330. package/dist/p1/editor/template-autocomplete-layer.d.ts +2 -2
  331. package/dist/p1/editor/template-autocomplete-layer.d.ts.map +1 -1
  332. package/dist/p1/editor/template-autocomplete-layer.js +23 -3
  333. package/dist/p1/editor/template-autocomplete-layer.js.map +1 -1
  334. package/dist/p1/pages/render-client.d.ts +1 -1
  335. package/dist/p1/pages/render-client.d.ts.map +1 -1
  336. package/dist/pds/components/AgentChip.d.ts.map +1 -1
  337. package/dist/pds/components/AgentChip.js +1 -2
  338. package/dist/pds/components/AgentChip.js.map +1 -1
  339. package/dist/pds/components/CreatePageModal.d.ts +10 -1
  340. package/dist/pds/components/CreatePageModal.d.ts.map +1 -1
  341. package/dist/pds/components/CreatePageModal.js +29 -9
  342. package/dist/pds/components/CreatePageModal.js.map +1 -1
  343. package/dist/pds/components/CreatePageModal.module.css +34 -0
  344. package/dist/pds/components/DocStateBadge.d.ts +1 -1
  345. package/dist/pds/components/DocStateBadge.d.ts.map +1 -1
  346. package/dist/pds/components/DocStateBadge.js +1 -1
  347. package/dist/pds/components/DocStateBadge.js.map +1 -1
  348. package/dist/pds/components/LoadingMessage.d.ts +16 -0
  349. package/dist/pds/components/LoadingMessage.d.ts.map +1 -0
  350. package/dist/pds/components/LoadingMessage.js +6 -0
  351. package/dist/pds/components/LoadingMessage.js.map +1 -0
  352. package/dist/pds/components/LoadingMessage.module.css +44 -0
  353. package/dist/pds/components/NavIcon.js +1 -1
  354. package/dist/pds/components/NavIcon.js.map +1 -1
  355. package/dist/pds/components/P1EditorHeader.d.ts +10 -2
  356. package/dist/pds/components/P1EditorHeader.d.ts.map +1 -1
  357. package/dist/pds/components/P1EditorHeader.js +16 -7
  358. package/dist/pds/components/P1EditorHeader.js.map +1 -1
  359. package/dist/pds/components/P1EditorHeader.module.css +113 -35
  360. package/dist/pds/components/P1EditorSubheader.d.ts +1 -2
  361. package/dist/pds/components/P1EditorSubheader.d.ts.map +1 -1
  362. package/dist/pds/components/P1EditorSubheader.js +10 -21
  363. package/dist/pds/components/P1EditorSubheader.js.map +1 -1
  364. package/dist/pds/components/P1EditorSubheader.module.css +7 -1
  365. package/dist/pds/components/PageNavigator.d.ts.map +1 -1
  366. package/dist/pds/components/PageNavigator.js.map +1 -1
  367. package/dist/pds/components/PresenceStack.d.ts +6 -5
  368. package/dist/pds/components/PresenceStack.d.ts.map +1 -1
  369. package/dist/pds/components/PresenceStack.js +43 -4
  370. package/dist/pds/components/PresenceStack.js.map +1 -1
  371. package/dist/pds/components/PresenceStack.module.css +52 -7
  372. package/dist/pds/components/PublishControl.js +2 -2
  373. package/dist/pds/components/PublishControl.js.map +1 -1
  374. package/dist/pds/components/WorkstreamSwitcher.d.ts +7 -2
  375. package/dist/pds/components/WorkstreamSwitcher.d.ts.map +1 -1
  376. package/dist/pds/components/WorkstreamSwitcher.js +5 -3
  377. package/dist/pds/components/WorkstreamSwitcher.js.map +1 -1
  378. package/dist/pds/index.d.ts +2 -0
  379. package/dist/pds/index.d.ts.map +1 -1
  380. package/dist/pds/index.js +1 -0
  381. package/dist/pds/index.js.map +1 -1
  382. package/dist/pds/theme/pds-core-content.d.ts +1 -1
  383. package/dist/pds/theme/pds-core-content.d.ts.map +1 -1
  384. package/dist/pds/theme/pds-core-content.js +1 -1
  385. package/dist/pds/theme/pds-core-content.js.map +1 -1
  386. package/dist/server.d.ts +4 -1
  387. package/dist/server.d.ts.map +1 -1
  388. package/dist/server.js +4 -1
  389. package/dist/server.js.map +1 -1
  390. package/dist/versioning/components/HistoricalVersionBanner.d.ts +19 -21
  391. package/dist/versioning/components/HistoricalVersionBanner.d.ts.map +1 -1
  392. package/dist/versioning/components/HistoricalVersionBanner.js +7 -19
  393. package/dist/versioning/components/HistoricalVersionBanner.js.map +1 -1
  394. package/dist/versioning/components/ReadOnlyFieldsGuard.d.ts +14 -0
  395. package/dist/versioning/components/ReadOnlyFieldsGuard.d.ts.map +1 -0
  396. package/dist/versioning/components/ReadOnlyFieldsGuard.js +8 -0
  397. package/dist/versioning/components/ReadOnlyFieldsGuard.js.map +1 -0
  398. package/dist/versioning/components/VersionBannerActions.d.ts +15 -0
  399. package/dist/versioning/components/VersionBannerActions.d.ts.map +1 -0
  400. package/dist/versioning/components/VersionBannerActions.js +30 -0
  401. package/dist/versioning/components/VersionBannerActions.js.map +1 -0
  402. package/dist/versioning/components/VersionPublishedBadge.d.ts +1 -1
  403. package/dist/versioning/components/VersionPublishedBadge.d.ts.map +1 -1
  404. package/dist/versioning/components/VersionReadOnlyBanner.d.ts +12 -0
  405. package/dist/versioning/components/VersionReadOnlyBanner.d.ts.map +1 -0
  406. package/dist/versioning/components/VersionReadOnlyBanner.js +5 -0
  407. package/dist/versioning/components/VersionReadOnlyBanner.js.map +1 -0
  408. package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts +2 -2
  409. package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts.map +1 -1
  410. package/dist/versioning/index.d.ts +4 -0
  411. package/dist/versioning/index.d.ts.map +1 -1
  412. package/dist/versioning/index.js +2 -0
  413. package/dist/versioning/index.js.map +1 -1
  414. package/dist/versioning/utils/formatVersionDate.d.ts +15 -0
  415. package/dist/versioning/utils/formatVersionDate.d.ts.map +1 -0
  416. package/dist/versioning/utils/formatVersionDate.js +41 -0
  417. package/dist/versioning/utils/formatVersionDate.js.map +1 -0
  418. package/dist/versioning/utils/versionKind.d.ts +19 -0
  419. package/dist/versioning/utils/versionKind.d.ts.map +1 -0
  420. package/dist/versioning/utils/versionKind.js +30 -0
  421. package/dist/versioning/utils/versionKind.js.map +1 -0
  422. package/package.json +16 -8
  423. package/src/pds/theme/PuckEditorTheme.css +81 -0
  424. package/src/pds/theme/PuckEditorTheme.test.ts +50 -1
  425. package/src/pds/theme/pds-core-content.ts +1 -1
  426. package/src/pds/theme/pds-core.css +1 -1
  427. package/src/styles.css +693 -29
  428. package/dist/features/content-type-templates/editor/useTemplateScaffold.d.ts +0 -15
  429. package/dist/features/content-type-templates/editor/useTemplateScaffold.d.ts.map +0 -1
  430. package/dist/features/content-type-templates/editor/useTemplateScaffold.js +0 -29
  431. package/dist/features/content-type-templates/editor/useTemplateScaffold.js.map +0 -1
  432. package/dist/p1/editor/hooks.d.ts.map +0 -1
  433. package/dist/p1/editor/hooks.js.map +0 -1
@@ -5,19 +5,21 @@ import { jsx as _jsx } from "react/jsx-runtime";
5
5
  * React context provider for P1 Puck integration.
6
6
  */
7
7
  import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
8
+ import isEqual from 'lodash.isequal';
8
9
  import { P1PuckContext } from '../core/P1PuckContext.js';
9
10
  import { NotificationProvider, useNotifications } from '../core/NotificationContext.js';
10
11
  import { PresenceContext } from '../core/PresenceContext.js';
11
- import isEqual from 'lodash.isequal';
12
12
  import { debounce } from '../core/utils/debounce.js';
13
13
  import { withRetry } from '../core/utils/retry.js';
14
- import { useRealtime } from './useRealtime.js';
15
- import { useDocuments } from './useDocuments.js';
16
14
  import { resolveFeatureConfig } from '../core/featureConfig.js';
17
- import { resolveActivePlugins, composeProviders } from './composePlugins.js';
18
- import { DEFAULT_CSS_FEATURE_PLUGINS } from './defaultPlugins.js';
19
15
  import { createPuckPermissions } from '../features/content-type-templates/permissions/createPuckPermissions.js';
20
16
  import { useTemplateList } from '../features/content-type-templates/hooks/useTemplateList.js';
17
+ import { presenceIdentityKey } from '../collaboration/utils/presenceIdentity.js';
18
+ import { DEFAULT_CSS_FEATURE_PLUGINS } from './defaultPlugins.js';
19
+ import { resolveActivePlugins, composeProviders } from './composePlugins.js';
20
+ import { snapshotToPuckData } from './utils/snapshotToPuckData.js';
21
+ import { useDocuments } from './useDocuments.js';
22
+ import { useRealtime } from './useRealtime.js';
21
23
  /**
22
24
  * Provider component for P1 Puck integration.
23
25
  *
@@ -126,6 +128,10 @@ userRole = 'editor', children, }) {
126
128
  // Document state
127
129
  const [currentDocument, setCurrentDocument] = useState(null);
128
130
  const [currentData, setCurrentData] = useState(null);
131
+ // True while loadDocument is in flight. Consumers use it to distinguish
132
+ // "no document while switching" (keep showing the old canvas) from
133
+ // "genuinely no document" (show the empty state).
134
+ const [documentLoading, setDocumentLoading] = useState(false);
129
135
  // Template state (PROPOSAL-010)
130
136
  const [currentTemplate, setCurrentTemplate] = useState(null);
131
137
  // Save state
@@ -192,6 +198,10 @@ userRole = 'editor', children, }) {
192
198
  const REMOTE_SYNC_DEBOUNCE_DELAY = 50;
193
199
  // Ref to track viewingVersion for use in callbacks (avoids stale closure)
194
200
  const viewingVersionRef = useRef(null);
201
+ // Tracks the latest data seen by saveData when NOT viewing historical.
202
+ // Used by returnToLatest to restore unsaved edits that were in Puck's
203
+ // memory when the user navigated to a historical version.
204
+ const latestLocalDataRef = useRef(null);
195
205
  // Helper to cancel any pending remote sync - used when loading documents/versions
196
206
  // This prevents race conditions where a pending remote update overrides loaded data
197
207
  const cancelPendingRemoteSync = useCallback(() => {
@@ -394,14 +404,14 @@ userRole = 'editor', children, }) {
394
404
  // The list endpoint carries no layout content; fetch the full template.
395
405
  const fullTemplate = await userClient.templates.get(siteId, branchIdRef.current, template.id);
396
406
  // A template without a content array has no stored layout snapshot;
397
- // scaffolding from it would silently create a blank page. An empty
407
+ // creating a page from it would silently produce a blank page. An empty
398
408
  // array is a legitimate empty layout and passes.
399
409
  if (!fullTemplate.content) {
400
410
  throw new Error(`Template "${template.label || template.name}" has no layout yet. Open it in the editor and add components before creating pages from it.`);
401
411
  }
402
- const { scaffoldFromTemplate } = await import('../features/content-type-templates/editor/useTemplateScaffold.js');
403
- const initialData = scaffoldFromTemplate(fullTemplate);
404
- await createDocumentRawRef.current(path, initialData, {
412
+ // The backend builds the initial version from the template, preserving
413
+ // each component's durable slot id; no client snapshot is sent.
414
+ await createDocumentRawRef.current(path, undefined, {
405
415
  templateId: fullTemplate.id,
406
416
  templateVersion: fullTemplate.version,
407
417
  title,
@@ -642,6 +652,11 @@ userRole = 'editor', children, }) {
642
652
  return;
643
653
  }
644
654
  }
655
+ // Only genuine user edits reach here — load/restore echoes arm
656
+ // suppressNextSaveRef before they fire and are returned early above.
657
+ if (!viewingVersionRef.current) {
658
+ latestLocalDataRef.current = data;
659
+ }
645
660
  // When realtime is enabled, detect whether this onChange came from a remote
646
661
  // sync (Yjs update from another client) vs. a local user edit.
647
662
  // Remote updates should NOT trigger a REST save — the DO handles persistence.
@@ -698,6 +713,12 @@ userRole = 'editor', children, }) {
698
713
  return;
699
714
  }
700
715
  }
716
+ // Mirror the realtime guard: don't save when previewing a historical version.
717
+ // Without this, the PuckDataSynchronizer echo from loadVersion resumes the
718
+ // debounce and writes historical data to the server.
719
+ if (viewingVersionRef.current !== null) {
720
+ return;
721
+ }
701
722
  pendingDataRef.current = data;
702
723
  if (debouncedSave.isPaused()) {
703
724
  debouncedSave.resume();
@@ -725,6 +746,34 @@ userRole = 'editor', children, }) {
725
746
  }
726
747
  await performSave();
727
748
  }, [debouncedSave, performSave, enableRealtime]);
749
+ // Persist current in-memory edits as a REST version before a destructive operation.
750
+ // Realtime: confirms WebSocket delivery then snapshots latestLocalDataRef as a version.
751
+ // Non-realtime: delegates to performSave which creates a version from pendingDataRef.
752
+ const persistCurrentEdits = useCallback(async () => {
753
+ if (!enableRealtime || !realtimeConnectedRef.current) {
754
+ await performSave();
755
+ return;
756
+ }
757
+ await realtime.waitForDelivery();
758
+ const latestData = latestLocalDataRef.current;
759
+ const doc = currentDocumentRef.current;
760
+ if (latestData && doc && currentDataDocumentPathRef.current === doc.path) {
761
+ setSaveStatus('saving');
762
+ try {
763
+ await userClient.versions.create(siteId, {
764
+ documentId: doc.id,
765
+ branchId,
766
+ snapshot: latestData,
767
+ });
768
+ setSaveStatus('saved');
769
+ setLastSaved(new Date());
770
+ }
771
+ catch (err) {
772
+ setSaveStatus('error');
773
+ throw err;
774
+ }
775
+ }
776
+ }, [enableRealtime, realtime, performSave, userClient, siteId, branchId]);
728
777
  // Load document by path
729
778
  const loadDocument = useCallback(async (path) => {
730
779
  // Flush any pending debounced save while the outgoing document's
@@ -741,6 +790,8 @@ userRole = 'editor', children, }) {
741
790
  }
742
791
  debouncedSave.cancel();
743
792
  pendingDataRef.current = null;
793
+ // Invalidate cached local edit so returnToLatest() doesn't treat it as unsaved.
794
+ latestLocalDataRef.current = null;
744
795
  // Cancel any pending remote sync to prevent race conditions
745
796
  // where a stale remote update overrides the document we're loading
746
797
  cancelPendingRemoteSync();
@@ -750,29 +801,28 @@ userRole = 'editor', children, }) {
750
801
  // will no longer match — signaling that our response is stale.
751
802
  loadRequestIdRef.current += 1;
752
803
  const thisRequestId = loadRequestIdRef.current;
753
- // Pre-clear the current document immediately so the preview shows the
754
- // empty state right away rather than stale content during the fetch.
804
+ setDocumentLoading(true);
805
+ // Pre-clear the current document so nothing can save against the old
806
+ // one while the fetch is in flight. The canvas keeps showing the
807
+ // previous document — documentLoading suppresses the empty state.
755
808
  currentDataDocumentPathRef.current = null;
756
809
  setCurrentData(null);
757
- setCurrentDocument(null);
758
810
  try {
759
- // Normalize path: strip leading slash if present
760
- const normalizedPath = path.startsWith('/') ? path.slice(1) : path;
761
- // Get document by path
762
- const doc = await userClient.documents.getByPath(siteId, normalizedPath);
811
+ const doc = await userClient.documents.getByPath(siteId, path.startsWith('/') ? path.slice(1) : path);
763
812
  // Staleness check: a newer loadDocument call has started
764
813
  if (thisRequestId !== loadRequestIdRef.current) {
765
814
  console.debug('[P1PuckProvider] Stale loadDocument — skipping (after getByPath)');
766
815
  return;
767
816
  }
768
- // Clear stale data BEFORE updating the document identity so that
769
- // useRealtime's new useEffect sees initialData=null when it creates
770
- // the fresh Y.Doc. Without this, currentData still holds the previous
771
- // document's content when setCurrentDocument triggers the re-render,
772
- // causing the new Y.Doc to be seeded with the wrong document's Yjs
773
- // state — which the DO then commits as the first realtime version.
817
+ // Use ID not path paths may differ by normalization, causing a false disconnect.
818
+ // Same-doc keeps Yjs alive; cross-doc nulls out so useRealtime seeds a fresh Y.Doc.
819
+ const isSameDocument = doc.id === currentDocumentRef.current?.id;
820
+ // Null data before identity update so useRealtime sees initialData=null.
774
821
  currentDataDocumentPathRef.current = null;
775
822
  setCurrentData(null);
823
+ if (!isSameDocument) {
824
+ setCurrentDocument(null);
825
+ }
776
826
  setCurrentDocument(doc);
777
827
  // Fetch template if document is bound to one (PROPOSAL-010)
778
828
  if (doc.templateId) {
@@ -793,7 +843,7 @@ userRole = 'editor', children, }) {
793
843
  }
794
844
  // Get latest version
795
845
  const version = await userClient.versions.getLatest(siteId, branchId, doc.id);
796
- const puckData = version.snapshot;
846
+ const puckData = snapshotToPuckData(version.snapshot);
797
847
  // Staleness check: a newer loadDocument call has started
798
848
  if (thisRequestId !== loadRequestIdRef.current) {
799
849
  console.debug('[P1PuckProvider] Stale loadDocument — skipping (after getLatest)');
@@ -851,6 +901,13 @@ userRole = 'editor', children, }) {
851
901
  setCurrentDocument(null);
852
902
  throw error;
853
903
  }
904
+ finally {
905
+ // Guarded so a stale call's completion can't clear the flag while a
906
+ // newer load is still in flight.
907
+ if (thisRequestId === loadRequestIdRef.current) {
908
+ setDocumentLoading(false);
909
+ }
910
+ }
854
911
  }, [userClient, siteId, branchId, cancelPendingRemoteSync, enableRealtime, debouncedSave, performSave]);
855
912
  // Load a specific version into the editor
856
913
  const loadVersion = useCallback(async (version) => {
@@ -873,12 +930,9 @@ userRole = 'editor', children, }) {
873
930
  console.warn('Could not fetch full version data, using version from list:', fetchError);
874
931
  }
875
932
  }
876
- let puckData = versionToUse.snapshot;
877
- // If snapshot is empty or invalid, use blank Puck data
878
- // This is expected for version 1 which represents the initial blank state
879
- if (!puckData || (!puckData.content && !puckData.root)) {
880
- puckData = { content: [], root: { props: {} } };
881
- }
933
+ // Parses a JSON-string snapshot and falls back to blank Puck data for
934
+ // an empty/invalid snapshot (e.g. version 1's initial blank state).
935
+ const puckData = snapshotToPuckData(versionToUse.snapshot);
882
936
  // IMPORTANT: Update the ref BEFORE state updates to block any incoming remote updates
883
937
  // The effect that syncs viewingVersionRef runs AFTER render, which is too late
884
938
  // Remote updates check this ref, so we need it set synchronously
@@ -913,6 +967,10 @@ userRole = 'editor', children, }) {
913
967
  dataToRestore = currentYjsData;
914
968
  }
915
969
  }
970
+ // 1. Edits typed inside the debounce window — cleared from pendingDataRef by loadVersion but still live here.
971
+ const hadLocalEdits = !!latestLocalDataRef.current;
972
+ dataToRestore ??= latestLocalDataRef.current;
973
+ latestLocalDataRef.current = null; // consume — prevents stale ref short-circuiting server fetch on next history visit
916
974
  // Re-fetch the true latest from the server when no live Yjs snapshot is
917
975
  // available. The cached latestVersionDataRef is only a last-resort fallback
918
976
  // (e.g. no current document); it is NOT used on fetch failure — silently
@@ -922,8 +980,7 @@ userRole = 'editor', children, }) {
922
980
  if (!dataToRestore) {
923
981
  const doc = currentDocumentRef.current;
924
982
  if (doc) {
925
- // Surface a loading state for the round trip the editor is otherwise
926
- // frozen on the historical snapshot with no indication.
983
+ // 2. Authoritative server state the only source that reflects saves from other tabs, users, or agents.
927
984
  setIsReturningToLatest(true);
928
985
  try {
929
986
  const version = await userClient.versions.getLatest(siteId, branchId, doc.id);
@@ -941,16 +998,16 @@ userRole = 'editor', children, }) {
941
998
  setIsReturningToLatest(false);
942
999
  }
943
1000
  }
944
- }
945
- if (!dataToRestore) {
946
- dataToRestore = latestVersionDataRef.current;
1001
+ // 3. No document context — can't fetch; use last value written by performSave.
1002
+ dataToRestore ??= latestVersionDataRef.current;
947
1003
  }
948
1004
  if (dataToRestore) {
949
1005
  // IMPORTANT: Update the ref BEFORE state updates
950
1006
  // Setting to null allows remote updates to resume
951
1007
  viewingVersionRef.current = null;
952
- // Suppress the echo save so returning to latest does not itself create a
953
- // duplicate version from the data we just loaded back in.
1008
+ // Suppress the PuckDataSynchronizer echo: setCurrentData triggers a setData
1009
+ // dispatch and Puck fires onChange saveData. Arm the ref so saveData drops
1010
+ // that echo; we control the save explicitly below.
954
1011
  suppressNextSaveRef.current = dataToRestore;
955
1012
  if (enableRealtime) {
956
1013
  pendingRemoteUpdatesRef.current += 1;
@@ -967,7 +1024,13 @@ userRole = 'editor', children, }) {
967
1024
  // Resume auto-save
968
1025
  debouncedSave.resume();
969
1026
  setAutoSavePaused(false);
970
- pendingDataRef.current = null;
1027
+ // Only queue a save when restoring from local in-memory edits — those were
1028
+ // never persisted. Data from the server fetch is already the latest saved
1029
+ // version; queuing a save would create a spurious identical version.
1030
+ if (hadLocalEdits) {
1031
+ pendingDataRef.current = dataToRestore;
1032
+ debouncedSave();
1033
+ }
971
1034
  setSaveStatus('idle');
972
1035
  }
973
1036
  }, [debouncedSave, cancelPendingRemoteSync, enableRealtime, realtime, userClient, siteId, branchId, showErrorNotifications, notificationContext]);
@@ -1132,6 +1195,8 @@ userRole = 'editor', children, }) {
1132
1195
  // but shouldn't cause PuckDataSynchronizer or plugin re-renders.
1133
1196
  const presenceStateRef = useRef(presenceState);
1134
1197
  presenceStateRef.current = presenceState;
1198
+ const humanPresenceKey = presenceIdentityKey(presenceState?.humans);
1199
+ const agentPresenceKey = presenceIdentityKey(presenceState?.agents);
1135
1200
  // =========================================================================
1136
1201
  // Phase 9: Agent Edit Capabilities (when this client IS an agent)
1137
1202
  // =========================================================================
@@ -1381,31 +1446,72 @@ userRole = 'editor', children, }) {
1381
1446
  const result = await userClient.documents.publish(siteId, branchId, doc.id);
1382
1447
  return result.checkpoint;
1383
1448
  }, [userClient, siteId, branchId, debouncedSave, performSave, enableRealtime, realtime]);
1449
+ // Tracks the currently in-flight switchBranch flush (everything after the
1450
+ // synchronous branch-selection commit), so a rapid re-selection can await
1451
+ // the prior call instead of racing it. See switchBranch below.
1452
+ const switchBranchInFlightRef = useRef(null);
1384
1453
  // Switch branch
1385
1454
  const switchBranch = useCallback(async (newBranchId) => {
1386
- // Cancel any pending remote sync - we're switching to a different branch
1387
- cancelPendingRemoteSync();
1388
- // Save any pending changes first
1389
- if (pendingDataRef.current) {
1390
- debouncedSave.cancel();
1391
- await performSave();
1392
- }
1393
- // IMPORTANT: Update the ref BEFORE state updates
1394
- viewingVersionRef.current = null;
1455
+ // Commit the new workstream selection FIRST, synchronously, before the
1456
+ // async save-flush below. The UI (WorkstreamSwitcher) fires this inside
1457
+ // startTransition without awaiting it, so its "Switching..." busy state
1458
+ // clears as soon as this function's synchronous portion returns — well
1459
+ // before a save-flush of the outgoing document would resolve. If the
1460
+ // user navigates to a different document in that window, this provider
1461
+ // can remount (the editor route has no layout.tsx to shield it across
1462
+ // param changes), and its branchId initializer re-reads sessionStorage.
1463
+ // Persisting here — before the flush, not after — guarantees that read
1464
+ // always sees the newly selected branch instead of a stale one,
1465
+ // preventing the workstream selector from snapping back to Live/main.
1395
1466
  setBranchId(newBranchId);
1396
1467
  persistBranchId(newBranchId);
1397
- setCurrentDocument(null);
1398
- currentDataDocumentPathRef.current = null;
1399
- setCurrentData(null);
1400
- setViewingVersion(null);
1401
- // Clear remoteSyncKey so new branch document sync takes priority
1402
- setRemoteSyncKey(null);
1403
- pendingDataRef.current = null;
1404
- setSaveStatus('idle');
1405
- setSaveError(null);
1406
- // Update current branch
1407
1468
  const branch = branches.find((b) => b.id === newBranchId);
1408
1469
  setCurrentBranch(branch ?? null);
1470
+ // Serialize the flush portion below against any switchBranch call
1471
+ // still in flight. Because the branch commit above is synchronous but
1472
+ // the flush is not, a rapid second call (the switcher fires onSwitch
1473
+ // fire-and-forget, so its busy state clears well before the flush
1474
+ // resolves) can otherwise start its own flush while pendingDataRef
1475
+ // still holds the first call's outgoing edit — grabbing a performSave
1476
+ // closure already pointed at the intermediate branch and saving that
1477
+ // same edit a second time, to the wrong branch. Awaiting the prior
1478
+ // in-flight flush first guarantees only one flush ever reads/clears
1479
+ // pendingDataRef at a time, and that each flush's performSave targets
1480
+ // the branch that was current when that flush actually started.
1481
+ const previousSwitch = switchBranchInFlightRef.current;
1482
+ const thisSwitch = (async () => {
1483
+ if (previousSwitch) {
1484
+ // A prior switch's flush failure shouldn't block this one.
1485
+ await previousSwitch.catch(() => undefined);
1486
+ }
1487
+ // Cancel any pending remote sync - we're switching to a different branch
1488
+ cancelPendingRemoteSync();
1489
+ // Save any pending changes on the outgoing document/branch first
1490
+ if (pendingDataRef.current) {
1491
+ debouncedSave.cancel();
1492
+ await performSave();
1493
+ }
1494
+ // IMPORTANT: Update the ref BEFORE state updates
1495
+ viewingVersionRef.current = null;
1496
+ setCurrentDocument(null);
1497
+ currentDataDocumentPathRef.current = null;
1498
+ setCurrentData(null);
1499
+ setViewingVersion(null);
1500
+ // Clear remoteSyncKey so new branch document sync takes priority
1501
+ setRemoteSyncKey(null);
1502
+ pendingDataRef.current = null;
1503
+ setSaveStatus('idle');
1504
+ setSaveError(null);
1505
+ })();
1506
+ switchBranchInFlightRef.current = thisSwitch;
1507
+ try {
1508
+ await thisSwitch;
1509
+ }
1510
+ finally {
1511
+ if (switchBranchInFlightRef.current === thisSwitch) {
1512
+ switchBranchInFlightRef.current = null;
1513
+ }
1514
+ }
1409
1515
  }, [branches, debouncedSave, performSave, cancelPendingRemoteSync, persistBranchId]);
1410
1516
  // Presence context value (for hooks like useFocusRegionReporting)
1411
1517
  const presenceContextValue = useMemo(() => {
@@ -1458,6 +1564,9 @@ userRole = 'editor', children, }) {
1458
1564
  const saveNowRef = useRef(saveNow);
1459
1565
  saveNowRef.current = saveNow;
1460
1566
  const stableSaveNow = useCallback(() => saveNowRef.current(), []);
1567
+ const persistCurrentEditsRef = useRef(persistCurrentEdits);
1568
+ persistCurrentEditsRef.current = persistCurrentEdits;
1569
+ const stablePersistCurrentEdits = useCallback(() => persistCurrentEditsRef.current(), []);
1461
1570
  const createCheckpointRef = useRef(createCheckpoint);
1462
1571
  createCheckpointRef.current = createCheckpoint;
1463
1572
  const stableCreateCheckpoint = useCallback((name) => createCheckpointRef.current(name), []);
@@ -1568,12 +1677,14 @@ userRole = 'editor', children, }) {
1568
1677
  userId,
1569
1678
  currentDocument,
1570
1679
  currentData,
1680
+ documentLoading,
1571
1681
  saveStatus,
1572
1682
  lastSaved,
1573
1683
  saveError,
1574
1684
  loadDocument: stableLoadDocument,
1575
1685
  saveData: stableSaveData,
1576
1686
  saveNow: stableSaveNow,
1687
+ persistCurrentEdits: stablePersistCurrentEdits,
1577
1688
  createCheckpoint: stableCreateCheckpoint,
1578
1689
  publishDocument: stablePublishDocument,
1579
1690
  switchBranch: stableSwitchBranch,
@@ -1654,12 +1765,14 @@ userRole = 'editor', children, }) {
1654
1765
  userId,
1655
1766
  currentDocument,
1656
1767
  currentData,
1768
+ documentLoading,
1657
1769
  saveStatus,
1658
1770
  lastSaved,
1659
1771
  saveError,
1660
1772
  stableLoadDocument,
1661
1773
  stableSaveData,
1662
1774
  stableSaveNow,
1775
+ stablePersistCurrentEdits,
1663
1776
  stableCreateCheckpoint,
1664
1777
  stablePublishDocument,
1665
1778
  stableSwitchBranch,
@@ -1697,7 +1810,11 @@ userRole = 'editor', children, }) {
1697
1810
  handleRealtimeDataCapture,
1698
1811
  // Phase 9 dependencies (full presenceState excluded — accessed via getter/ref,
1699
1812
  // but humanPresenceCount/hasActiveHumans/hasActiveAgents are direct values so every
1700
- // join/leave triggers re-renders regardless of how many actors are present)
1813
+ // join/leave triggers re-renders regardless of how many actors are present).
1814
+ // The roster keys cover the changes a count cannot see: a same-frame join/leave of
1815
+ // two humans would keep the count the same but change the roster.
1816
+ humanPresenceKey,
1817
+ agentPresenceKey,
1701
1818
  presenceState?.humans.length,
1702
1819
  presenceState?.hasActiveHumans,
1703
1820
  presenceState?.hasActiveAgents,