@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.
Files changed (805) hide show
  1. package/dist/agent/agentPlugin.d.ts +3 -0
  2. package/dist/agent/agentPlugin.d.ts.map +1 -0
  3. package/dist/agent/agentPlugin.js +6 -0
  4. package/dist/agent/agentPlugin.js.map +1 -0
  5. package/dist/agent/components/AgentActionButton.d.ts +38 -0
  6. package/dist/agent/components/AgentActionButton.d.ts.map +1 -0
  7. package/dist/agent/components/AgentActionButton.js +76 -0
  8. package/dist/agent/components/AgentActionButton.js.map +1 -0
  9. package/dist/agent/components/AgentActionModal.d.ts +28 -0
  10. package/dist/agent/components/AgentActionModal.d.ts.map +1 -0
  11. package/dist/agent/components/AgentActionModal.js +85 -0
  12. package/dist/agent/components/AgentActionModal.js.map +1 -0
  13. package/dist/agent/components/AgentStatusPanel.d.ts +27 -0
  14. package/dist/agent/components/AgentStatusPanel.d.ts.map +1 -0
  15. package/dist/agent/components/AgentStatusPanel.js +51 -0
  16. package/dist/agent/components/AgentStatusPanel.js.map +1 -0
  17. package/dist/agent/components/index.d.ts +12 -0
  18. package/dist/agent/components/index.d.ts.map +1 -0
  19. package/dist/agent/components/index.js +9 -0
  20. package/dist/agent/components/index.js.map +1 -0
  21. package/dist/agent/index.d.ts +6 -0
  22. package/dist/agent/index.d.ts.map +1 -0
  23. package/dist/agent/index.js +4 -0
  24. package/dist/agent/index.js.map +1 -0
  25. package/dist/agent/useAgentEdit.d.ts +68 -0
  26. package/dist/agent/useAgentEdit.d.ts.map +1 -0
  27. package/dist/agent/useAgentEdit.js +125 -0
  28. package/dist/agent/useAgentEdit.js.map +1 -0
  29. package/dist/agent/useAgentTrigger.d.ts +69 -0
  30. package/dist/agent/useAgentTrigger.d.ts.map +1 -0
  31. package/dist/agent/useAgentTrigger.js +131 -0
  32. package/dist/agent/useAgentTrigger.js.map +1 -0
  33. package/dist/auth/AuthGate.d.ts +5 -0
  34. package/dist/auth/AuthGate.d.ts.map +1 -0
  35. package/dist/auth/AuthGate.js +17 -0
  36. package/dist/auth/AuthGate.js.map +1 -0
  37. package/dist/auth/P1AuthProvider.d.ts +59 -0
  38. package/dist/auth/P1AuthProvider.d.ts.map +1 -0
  39. package/dist/auth/P1AuthProvider.js +254 -0
  40. package/dist/auth/P1AuthProvider.js.map +1 -0
  41. package/dist/auth/P1LoginPage.d.ts +26 -0
  42. package/dist/auth/P1LoginPage.d.ts.map +1 -0
  43. package/dist/auth/P1LoginPage.js +105 -0
  44. package/dist/auth/P1LoginPage.js.map +1 -0
  45. package/dist/auth/index.d.ts +14 -0
  46. package/dist/auth/index.d.ts.map +1 -0
  47. package/dist/auth/index.js +12 -0
  48. package/dist/auth/index.js.map +1 -0
  49. package/dist/collaboration/collaborationPlugin.d.ts +3 -0
  50. package/dist/collaboration/collaborationPlugin.d.ts.map +1 -0
  51. package/dist/collaboration/collaborationPlugin.js +6 -0
  52. package/dist/collaboration/collaborationPlugin.js.map +1 -0
  53. package/dist/collaboration/components/AgentActivityBanner.d.ts +26 -0
  54. package/dist/collaboration/components/AgentActivityBanner.d.ts.map +1 -0
  55. package/dist/collaboration/components/AgentActivityBanner.js +50 -0
  56. package/dist/collaboration/components/AgentActivityBanner.js.map +1 -0
  57. package/dist/collaboration/components/CollaboratorAvatars.d.ts +25 -0
  58. package/dist/collaboration/components/CollaboratorAvatars.d.ts.map +1 -0
  59. package/dist/collaboration/components/CollaboratorAvatars.js +75 -0
  60. package/dist/collaboration/components/CollaboratorAvatars.js.map +1 -0
  61. package/dist/collaboration/components/FocusRegionHighlight.d.ts +20 -0
  62. package/dist/collaboration/components/FocusRegionHighlight.d.ts.map +1 -0
  63. package/dist/collaboration/components/FocusRegionHighlight.js +35 -0
  64. package/dist/collaboration/components/FocusRegionHighlight.js.map +1 -0
  65. package/dist/collaboration/components/PresenceIndicator.d.ts +23 -0
  66. package/dist/collaboration/components/PresenceIndicator.d.ts.map +1 -0
  67. package/dist/collaboration/components/PresenceIndicator.js +25 -0
  68. package/dist/collaboration/components/PresenceIndicator.js.map +1 -0
  69. package/dist/collaboration/index.d.ts +21 -0
  70. package/dist/collaboration/index.d.ts.map +1 -0
  71. package/dist/collaboration/index.js +12 -0
  72. package/dist/collaboration/index.js.map +1 -0
  73. package/dist/collaboration/useBranchPresence.d.ts +54 -0
  74. package/dist/collaboration/useBranchPresence.d.ts.map +1 -0
  75. package/dist/collaboration/useBranchPresence.js +94 -0
  76. package/dist/collaboration/useBranchPresence.js.map +1 -0
  77. package/dist/collaboration/useFocusRegionReporting.d.ts +69 -0
  78. package/dist/collaboration/useFocusRegionReporting.d.ts.map +1 -0
  79. package/dist/collaboration/useFocusRegionReporting.js +199 -0
  80. package/dist/collaboration/useFocusRegionReporting.js.map +1 -0
  81. package/dist/collaboration/usePresence.d.ts +62 -0
  82. package/dist/collaboration/usePresence.d.ts.map +1 -0
  83. package/dist/collaboration/usePresence.js +105 -0
  84. package/dist/collaboration/usePresence.js.map +1 -0
  85. package/dist/collaboration/useSitePresence.d.ts +54 -0
  86. package/dist/collaboration/useSitePresence.d.ts.map +1 -0
  87. package/dist/collaboration/useSitePresence.js +94 -0
  88. package/dist/collaboration/useSitePresence.js.map +1 -0
  89. package/dist/collaboration/utils/avatarColor.d.ts +11 -0
  90. package/dist/collaboration/utils/avatarColor.d.ts.map +1 -0
  91. package/dist/collaboration/utils/avatarColor.js +42 -0
  92. package/dist/collaboration/utils/avatarColor.js.map +1 -0
  93. package/dist/collaboration/utils/focusHighlightConfig.d.ts +54 -0
  94. package/dist/collaboration/utils/focusHighlightConfig.d.ts.map +1 -0
  95. package/dist/collaboration/utils/focusHighlightConfig.js +98 -0
  96. package/dist/collaboration/utils/focusHighlightConfig.js.map +1 -0
  97. package/dist/collaboration/utils/focusRegionMap.d.ts +82 -0
  98. package/dist/collaboration/utils/focusRegionMap.d.ts.map +1 -0
  99. package/dist/collaboration/utils/focusRegionMap.js +188 -0
  100. package/dist/collaboration/utils/focusRegionMap.js.map +1 -0
  101. package/dist/core/FocusHighlightContext.d.ts +54 -0
  102. package/dist/core/FocusHighlightContext.d.ts.map +1 -0
  103. package/dist/core/FocusHighlightContext.js +46 -0
  104. package/dist/core/FocusHighlightContext.js.map +1 -0
  105. package/dist/core/NotificationContext.d.ts +63 -0
  106. package/dist/core/NotificationContext.d.ts.map +1 -0
  107. package/dist/core/NotificationContext.js +194 -0
  108. package/dist/core/NotificationContext.js.map +1 -0
  109. package/dist/core/P1PuckContext.d.ts +36 -0
  110. package/dist/core/P1PuckContext.d.ts.map +1 -0
  111. package/dist/core/P1PuckContext.js +44 -0
  112. package/dist/core/P1PuckContext.js.map +1 -0
  113. package/dist/core/PresenceContext.d.ts +70 -0
  114. package/dist/core/PresenceContext.d.ts.map +1 -0
  115. package/dist/core/PresenceContext.js +31 -0
  116. package/dist/core/PresenceContext.js.map +1 -0
  117. package/dist/core/config.d.ts +26 -0
  118. package/dist/core/config.d.ts.map +1 -0
  119. package/dist/core/config.js +78 -0
  120. package/dist/core/config.js.map +1 -0
  121. package/dist/core/featureConfig.d.ts +56 -0
  122. package/dist/core/featureConfig.d.ts.map +1 -0
  123. package/dist/core/featureConfig.js +77 -0
  124. package/dist/core/featureConfig.js.map +1 -0
  125. package/dist/core/index.d.ts +17 -0
  126. package/dist/core/index.d.ts.map +1 -0
  127. package/dist/core/index.js +11 -0
  128. package/dist/core/index.js.map +1 -0
  129. package/dist/core/plugin-types.d.ts +30 -0
  130. package/dist/core/plugin-types.d.ts.map +1 -0
  131. package/dist/core/plugin-types.js +2 -0
  132. package/dist/core/plugin-types.js.map +1 -0
  133. package/dist/core/types.d.ts +710 -0
  134. package/dist/core/types.d.ts.map +1 -0
  135. package/dist/core/types.js +5 -0
  136. package/dist/core/types.js.map +1 -0
  137. package/dist/core/utils/debounce.d.ts +27 -0
  138. package/dist/core/utils/debounce.d.ts.map +1 -0
  139. package/dist/core/utils/debounce.js +77 -0
  140. package/dist/core/utils/debounce.js.map +1 -0
  141. package/dist/core/utils/retry.d.ts +57 -0
  142. package/dist/core/utils/retry.d.ts.map +1 -0
  143. package/dist/core/utils/retry.js +70 -0
  144. package/dist/core/utils/retry.js.map +1 -0
  145. package/dist/core/utils/throttle.d.ts +29 -0
  146. package/dist/core/utils/throttle.d.ts.map +1 -0
  147. package/dist/core/utils/throttle.js +66 -0
  148. package/dist/core/utils/throttle.js.map +1 -0
  149. package/dist/data/cross-reference-resolve.d.ts +6 -0
  150. package/dist/data/cross-reference-resolve.d.ts.map +1 -0
  151. package/dist/data/cross-reference-resolve.js +58 -0
  152. package/dist/data/cross-reference-resolve.js.map +1 -0
  153. package/dist/data/cross-reference.d.ts +32 -0
  154. package/dist/data/cross-reference.d.ts.map +1 -0
  155. package/dist/data/cross-reference.js +188 -0
  156. package/dist/data/cross-reference.js.map +1 -0
  157. package/dist/data/dal/index.d.ts +32 -0
  158. package/dist/data/dal/index.d.ts.map +1 -0
  159. package/dist/data/dal/index.js +72 -0
  160. package/dist/data/dal/index.js.map +1 -0
  161. package/dist/data/dal/init.d.ts +28 -0
  162. package/dist/data/dal/init.d.ts.map +1 -0
  163. package/dist/data/dal/init.js +76 -0
  164. package/dist/data/dal/init.js.map +1 -0
  165. package/dist/data/dal/p1-store.d.ts +52 -0
  166. package/dist/data/dal/p1-store.d.ts.map +1 -0
  167. package/dist/data/dal/p1-store.js +121 -0
  168. package/dist/data/dal/p1-store.js.map +1 -0
  169. package/dist/data/dal/request-auth.d.ts +3 -0
  170. package/dist/data/dal/request-auth.d.ts.map +1 -0
  171. package/dist/data/dal/request-auth.js +9 -0
  172. package/dist/data/dal/request-auth.js.map +1 -0
  173. package/dist/data/dal/types.d.ts +31 -0
  174. package/dist/data/dal/types.d.ts.map +1 -0
  175. package/dist/data/dal/types.js +2 -0
  176. package/dist/data/dal/types.js.map +1 -0
  177. package/dist/data/get-page.d.ts +5 -0
  178. package/dist/data/get-page.d.ts.map +1 -0
  179. package/dist/data/get-page.js +5 -0
  180. package/dist/data/get-page.js.map +1 -0
  181. package/dist/data/page-editor-meta.d.ts +16 -0
  182. package/dist/data/page-editor-meta.d.ts.map +1 -0
  183. package/dist/data/page-editor-meta.js +99 -0
  184. package/dist/data/page-editor-meta.js.map +1 -0
  185. package/dist/data/page-store.d.ts +65 -0
  186. package/dist/data/page-store.d.ts.map +1 -0
  187. package/dist/data/page-store.js +302 -0
  188. package/dist/data/page-store.js.map +1 -0
  189. package/dist/data/page-structure.d.ts +13 -0
  190. package/dist/data/page-structure.d.ts.map +1 -0
  191. package/dist/data/page-structure.js +95 -0
  192. package/dist/data/page-structure.js.map +1 -0
  193. package/dist/data/paths.d.ts +16 -0
  194. package/dist/data/paths.d.ts.map +1 -0
  195. package/dist/data/paths.js +36 -0
  196. package/dist/data/paths.js.map +1 -0
  197. package/dist/data/query-provider.d.ts +5 -0
  198. package/dist/data/query-provider.d.ts.map +1 -0
  199. package/dist/data/query-provider.js +16 -0
  200. package/dist/data/query-provider.js.map +1 -0
  201. package/dist/data/remote-datasources/fetch-http-json.d.ts +8 -0
  202. package/dist/data/remote-datasources/fetch-http-json.d.ts.map +1 -0
  203. package/dist/data/remote-datasources/fetch-http-json.js +89 -0
  204. package/dist/data/remote-datasources/fetch-http-json.js.map +1 -0
  205. package/dist/data/remote-datasources/index.d.ts +5 -0
  206. package/dist/data/remote-datasources/index.d.ts.map +1 -0
  207. package/dist/data/remote-datasources/index.js +3 -0
  208. package/dist/data/remote-datasources/index.js.map +1 -0
  209. package/dist/data/remote-datasources/loader.d.ts +44 -0
  210. package/dist/data/remote-datasources/loader.d.ts.map +1 -0
  211. package/dist/data/remote-datasources/loader.js +126 -0
  212. package/dist/data/remote-datasources/loader.js.map +1 -0
  213. package/dist/data/remote-datasources/remote-datasource-registry.d.ts +21 -0
  214. package/dist/data/remote-datasources/remote-datasource-registry.d.ts.map +1 -0
  215. package/dist/data/remote-datasources/remote-datasource-registry.js +15 -0
  216. package/dist/data/remote-datasources/remote-datasource-registry.js.map +1 -0
  217. package/dist/data/remote-datasources/user-remote-datasource-store.d.ts +14 -0
  218. package/dist/data/remote-datasources/user-remote-datasource-store.d.ts.map +1 -0
  219. package/dist/data/remote-datasources/user-remote-datasource-store.js +125 -0
  220. package/dist/data/remote-datasources/user-remote-datasource-store.js.map +1 -0
  221. package/dist/data/remote-datasources/user-remote-datasource-types.d.ts +15 -0
  222. package/dist/data/remote-datasources/user-remote-datasource-types.d.ts.map +1 -0
  223. package/dist/data/remote-datasources/user-remote-datasource-types.js +2 -0
  224. package/dist/data/remote-datasources/user-remote-datasource-types.js.map +1 -0
  225. package/dist/data/resolve-data-templates.d.ts +12 -0
  226. package/dist/data/resolve-data-templates.d.ts.map +1 -0
  227. package/dist/data/resolve-data-templates.js +286 -0
  228. package/dist/data/resolve-data-templates.js.map +1 -0
  229. package/dist/data/route-templates.d.ts +43 -0
  230. package/dist/data/route-templates.d.ts.map +1 -0
  231. package/dist/data/route-templates.js +146 -0
  232. package/dist/data/route-templates.js.map +1 -0
  233. package/dist/data/semantic-ops.d.ts +47 -0
  234. package/dist/data/semantic-ops.d.ts.map +1 -0
  235. package/dist/data/semantic-ops.js +335 -0
  236. package/dist/data/semantic-ops.js.map +1 -0
  237. package/dist/data/styles.d.ts +87 -0
  238. package/dist/data/styles.d.ts.map +1 -0
  239. package/dist/data/styles.js +87 -0
  240. package/dist/data/styles.js.map +1 -0
  241. package/dist/data/template-autocomplete.d.ts +22 -0
  242. package/dist/data/template-autocomplete.d.ts.map +1 -0
  243. package/dist/data/template-autocomplete.js +71 -0
  244. package/dist/data/template-autocomplete.js.map +1 -0
  245. package/dist/data/template-functions.d.ts +5 -0
  246. package/dist/data/template-functions.d.ts.map +1 -0
  247. package/dist/data/template-functions.js +90 -0
  248. package/dist/data/template-functions.js.map +1 -0
  249. package/dist/data/utils.d.ts +3 -0
  250. package/dist/data/utils.d.ts.map +1 -0
  251. package/dist/data/utils.js +11 -0
  252. package/dist/data/utils.js.map +1 -0
  253. package/dist/editor/P1App.d.ts +14 -0
  254. package/dist/editor/P1App.d.ts.map +1 -0
  255. package/dist/editor/P1App.js +138 -0
  256. package/dist/editor/P1App.js.map +1 -0
  257. package/dist/editor/P1PuckProvider.d.ts +69 -0
  258. package/dist/editor/P1PuckProvider.d.ts.map +1 -0
  259. package/dist/editor/P1PuckProvider.js +1473 -0
  260. package/dist/editor/P1PuckProvider.js.map +1 -0
  261. package/dist/editor/components/BranchSelector.d.ts +49 -0
  262. package/dist/editor/components/BranchSelector.d.ts.map +1 -0
  263. package/dist/editor/components/BranchSelector.js +55 -0
  264. package/dist/editor/components/BranchSelector.js.map +1 -0
  265. package/dist/editor/components/NotificationContainer.d.ts +41 -0
  266. package/dist/editor/components/NotificationContainer.d.ts.map +1 -0
  267. package/dist/editor/components/NotificationContainer.js +32 -0
  268. package/dist/editor/components/NotificationContainer.js.map +1 -0
  269. package/dist/editor/components/PublishButton.d.ts +52 -0
  270. package/dist/editor/components/PublishButton.d.ts.map +1 -0
  271. package/dist/editor/components/PublishButton.js +58 -0
  272. package/dist/editor/components/PublishButton.js.map +1 -0
  273. package/dist/editor/components/PublishedStatusBadge.d.ts +6 -0
  274. package/dist/editor/components/PublishedStatusBadge.d.ts.map +1 -0
  275. package/dist/editor/components/PublishedStatusBadge.js +25 -0
  276. package/dist/editor/components/PublishedStatusBadge.js.map +1 -0
  277. package/dist/editor/components/PuckDataCapture.d.ts +22 -0
  278. package/dist/editor/components/PuckDataCapture.d.ts.map +1 -0
  279. package/dist/editor/components/PuckDataCapture.js +30 -0
  280. package/dist/editor/components/PuckDataCapture.js.map +1 -0
  281. package/dist/editor/components/PuckDataSynchronizer.d.ts +49 -0
  282. package/dist/editor/components/PuckDataSynchronizer.d.ts.map +1 -0
  283. package/dist/editor/components/PuckDataSynchronizer.js +126 -0
  284. package/dist/editor/components/PuckDataSynchronizer.js.map +1 -0
  285. package/dist/editor/components/PuckSelectionTracker.d.ts +47 -0
  286. package/dist/editor/components/PuckSelectionTracker.d.ts.map +1 -0
  287. package/dist/editor/components/PuckSelectionTracker.js +93 -0
  288. package/dist/editor/components/PuckSelectionTracker.js.map +1 -0
  289. package/dist/editor/components/SaveIndicator.d.ts +77 -0
  290. package/dist/editor/components/SaveIndicator.d.ts.map +1 -0
  291. package/dist/editor/components/SaveIndicator.js +114 -0
  292. package/dist/editor/components/SaveIndicator.js.map +1 -0
  293. package/dist/editor/components/Toast.d.ts +40 -0
  294. package/dist/editor/components/Toast.d.ts.map +1 -0
  295. package/dist/editor/components/Toast.js +92 -0
  296. package/dist/editor/components/Toast.js.map +1 -0
  297. package/dist/editor/components/VersionBannerOverride.d.ts +10 -0
  298. package/dist/editor/components/VersionBannerOverride.d.ts.map +1 -0
  299. package/dist/editor/components/VersionBannerOverride.js +22 -0
  300. package/dist/editor/components/VersionBannerOverride.js.map +1 -0
  301. package/dist/editor/components/connectable.d.ts +22 -0
  302. package/dist/editor/components/connectable.d.ts.map +1 -0
  303. package/dist/editor/components/connectable.js +84 -0
  304. package/dist/editor/components/connectable.js.map +1 -0
  305. package/dist/editor/components/merge-preview/MergePreviewPanel.d.ts +13 -0
  306. package/dist/editor/components/merge-preview/MergePreviewPanel.d.ts.map +1 -0
  307. package/dist/editor/components/merge-preview/MergePreviewPanel.js +32 -0
  308. package/dist/editor/components/merge-preview/MergePreviewPanel.js.map +1 -0
  309. package/dist/editor/components/merge-preview/MergePreviewRenderer.d.ts +58 -0
  310. package/dist/editor/components/merge-preview/MergePreviewRenderer.d.ts.map +1 -0
  311. package/dist/editor/components/merge-preview/MergePreviewRenderer.js +150 -0
  312. package/dist/editor/components/merge-preview/MergePreviewRenderer.js.map +1 -0
  313. package/dist/editor/components/merge-preview/ScaledContent.d.ts +11 -0
  314. package/dist/editor/components/merge-preview/ScaledContent.d.ts.map +1 -0
  315. package/dist/editor/components/merge-preview/ScaledContent.js +31 -0
  316. package/dist/editor/components/merge-preview/ScaledContent.js.map +1 -0
  317. package/dist/editor/components/merge-preview/ViewModeSelector.d.ts +8 -0
  318. package/dist/editor/components/merge-preview/ViewModeSelector.d.ts.map +1 -0
  319. package/dist/editor/components/merge-preview/ViewModeSelector.js +11 -0
  320. package/dist/editor/components/merge-preview/ViewModeSelector.js.map +1 -0
  321. package/dist/editor/components/merge-preview/index.d.ts +12 -0
  322. package/dist/editor/components/merge-preview/index.d.ts.map +1 -0
  323. package/dist/editor/components/merge-preview/index.js +9 -0
  324. package/dist/editor/components/merge-preview/index.js.map +1 -0
  325. package/dist/editor/composePlugins.d.ts +10 -0
  326. package/dist/editor/composePlugins.d.ts.map +1 -0
  327. package/dist/editor/composePlugins.js +47 -0
  328. package/dist/editor/composePlugins.js.map +1 -0
  329. package/dist/editor/defaultPlugins.d.ts +3 -0
  330. package/dist/editor/defaultPlugins.d.ts.map +1 -0
  331. package/dist/editor/defaultPlugins.js +7 -0
  332. package/dist/editor/defaultPlugins.js.map +1 -0
  333. package/dist/editor/icons/GenericThumbnailIcon.d.ts +3 -0
  334. package/dist/editor/icons/GenericThumbnailIcon.d.ts.map +1 -0
  335. package/dist/editor/icons/GenericThumbnailIcon.js +5 -0
  336. package/dist/editor/icons/GenericThumbnailIcon.js.map +1 -0
  337. package/dist/editor/icons/GripHandleIcon.d.ts +3 -0
  338. package/dist/editor/icons/GripHandleIcon.d.ts.map +1 -0
  339. package/dist/editor/icons/GripHandleIcon.js +5 -0
  340. package/dist/editor/icons/GripHandleIcon.js.map +1 -0
  341. package/dist/editor/icons/MergePreviewIcon.d.ts +3 -0
  342. package/dist/editor/icons/MergePreviewIcon.d.ts.map +1 -0
  343. package/dist/editor/icons/MergePreviewIcon.js +5 -0
  344. package/dist/editor/icons/MergePreviewIcon.js.map +1 -0
  345. package/dist/editor/icons/WarningTriangleIcon.d.ts +3 -0
  346. package/dist/editor/icons/WarningTriangleIcon.d.ts.map +1 -0
  347. package/dist/editor/icons/WarningTriangleIcon.js +5 -0
  348. package/dist/editor/icons/WarningTriangleIcon.js.map +1 -0
  349. package/dist/editor/icons/index.d.ts +5 -0
  350. package/dist/editor/icons/index.d.ts.map +1 -0
  351. package/dist/editor/icons/index.js +5 -0
  352. package/dist/editor/icons/index.js.map +1 -0
  353. package/dist/editor/index.d.ts +43 -0
  354. package/dist/editor/index.d.ts.map +1 -0
  355. package/dist/editor/index.js +30 -0
  356. package/dist/editor/index.js.map +1 -0
  357. package/dist/editor/plugin/P1Plugin.d.ts +161 -0
  358. package/dist/editor/plugin/P1Plugin.d.ts.map +1 -0
  359. package/dist/editor/plugin/P1Plugin.js +358 -0
  360. package/dist/editor/plugin/P1Plugin.js.map +1 -0
  361. package/dist/editor/plugin/createP1Overrides.d.ts +161 -0
  362. package/dist/editor/plugin/createP1Overrides.d.ts.map +1 -0
  363. package/dist/editor/plugin/createP1Overrides.js +103 -0
  364. package/dist/editor/plugin/createP1Overrides.js.map +1 -0
  365. package/dist/editor/plugin/index.d.ts +13 -0
  366. package/dist/editor/plugin/index.d.ts.map +1 -0
  367. package/dist/editor/plugin/index.js +10 -0
  368. package/dist/editor/plugin/index.js.map +1 -0
  369. package/dist/editor/plugin/mergePreviewPlugin.d.ts +9 -0
  370. package/dist/editor/plugin/mergePreviewPlugin.d.ts.map +1 -0
  371. package/dist/editor/plugin/mergePreviewPlugin.js +26 -0
  372. package/dist/editor/plugin/mergePreviewPlugin.js.map +1 -0
  373. package/dist/editor/presets.d.ts +8 -0
  374. package/dist/editor/presets.d.ts.map +1 -0
  375. package/dist/editor/presets.js +24 -0
  376. package/dist/editor/presets.js.map +1 -0
  377. package/dist/editor/useAutoSave.d.ts +37 -0
  378. package/dist/editor/useAutoSave.d.ts.map +1 -0
  379. package/dist/editor/useAutoSave.js +118 -0
  380. package/dist/editor/useAutoSave.js.map +1 -0
  381. package/dist/editor/useBranches.d.ts +67 -0
  382. package/dist/editor/useBranches.d.ts.map +1 -0
  383. package/dist/editor/useBranches.js +78 -0
  384. package/dist/editor/useBranches.js.map +1 -0
  385. package/dist/editor/useComponentRegistry.d.ts +31 -0
  386. package/dist/editor/useComponentRegistry.d.ts.map +1 -0
  387. package/dist/editor/useComponentRegistry.js +237 -0
  388. package/dist/editor/useComponentRegistry.js.map +1 -0
  389. package/dist/editor/useDocuments.d.ts +66 -0
  390. package/dist/editor/useDocuments.d.ts.map +1 -0
  391. package/dist/editor/useDocuments.js +112 -0
  392. package/dist/editor/useDocuments.js.map +1 -0
  393. package/dist/editor/useMergePreview.d.ts +15 -0
  394. package/dist/editor/useMergePreview.d.ts.map +1 -0
  395. package/dist/editor/useMergePreview.js +56 -0
  396. package/dist/editor/useMergePreview.js.map +1 -0
  397. package/dist/editor/useP1Editor.d.ts +125 -0
  398. package/dist/editor/useP1Editor.d.ts.map +1 -0
  399. package/dist/editor/useP1Editor.js +339 -0
  400. package/dist/editor/useP1Editor.js.map +1 -0
  401. package/dist/editor/useP1Overrides.d.ts +52 -0
  402. package/dist/editor/useP1Overrides.d.ts.map +1 -0
  403. package/dist/editor/useP1Overrides.js +74 -0
  404. package/dist/editor/useP1Overrides.js.map +1 -0
  405. package/dist/editor/useP1Plugin.d.ts +95 -0
  406. package/dist/editor/useP1Plugin.d.ts.map +1 -0
  407. package/dist/editor/useP1Plugin.js +112 -0
  408. package/dist/editor/useP1Plugin.js.map +1 -0
  409. package/dist/editor/useRealtime.d.ts +148 -0
  410. package/dist/editor/useRealtime.d.ts.map +1 -0
  411. package/dist/editor/useRealtime.js +244 -0
  412. package/dist/editor/useRealtime.js.map +1 -0
  413. package/dist/editor/utils/buildThumbnailOverride.d.ts +28 -0
  414. package/dist/editor/utils/buildThumbnailOverride.d.ts.map +1 -0
  415. package/dist/editor/utils/buildThumbnailOverride.js +39 -0
  416. package/dist/editor/utils/buildThumbnailOverride.js.map +1 -0
  417. package/dist/editor/utils/componentRegistry.d.ts +141 -0
  418. package/dist/editor/utils/componentRegistry.d.ts.map +1 -0
  419. package/dist/editor/utils/componentRegistry.js +238 -0
  420. package/dist/editor/utils/componentRegistry.js.map +1 -0
  421. package/dist/editor/utils/createStablePluginArray.d.ts +27 -0
  422. package/dist/editor/utils/createStablePluginArray.d.ts.map +1 -0
  423. package/dist/editor/utils/createStablePluginArray.js +40 -0
  424. package/dist/editor/utils/createStablePluginArray.js.map +1 -0
  425. package/dist/editor/utils/path.d.ts +2 -0
  426. package/dist/editor/utils/path.d.ts.map +1 -0
  427. package/dist/editor/utils/path.js +20 -0
  428. package/dist/editor/utils/path.js.map +1 -0
  429. package/dist/editor/utils/puckYjsBinding.d.ts +66 -0
  430. package/dist/editor/utils/puckYjsBinding.d.ts.map +1 -0
  431. package/dist/editor/utils/puckYjsBinding.js +272 -0
  432. package/dist/editor/utils/puckYjsBinding.js.map +1 -0
  433. package/dist/index.d.ts +121 -0
  434. package/dist/index.d.ts.map +1 -0
  435. package/dist/index.js +109 -0
  436. package/dist/index.js.map +1 -0
  437. package/dist/merge/components/conflict-notifications/ConflictNotificationToast.d.ts +35 -0
  438. package/dist/merge/components/conflict-notifications/ConflictNotificationToast.d.ts.map +1 -0
  439. package/dist/merge/components/conflict-notifications/ConflictNotificationToast.js +59 -0
  440. package/dist/merge/components/conflict-notifications/ConflictNotificationToast.js.map +1 -0
  441. package/dist/merge/components/conflict-notifications/index.d.ts +10 -0
  442. package/dist/merge/components/conflict-notifications/index.d.ts.map +1 -0
  443. package/dist/merge/components/conflict-notifications/index.js +8 -0
  444. package/dist/merge/components/conflict-notifications/index.js.map +1 -0
  445. package/dist/merge/components/conflict-notifications/useConflictNotifications.d.ts +69 -0
  446. package/dist/merge/components/conflict-notifications/useConflictNotifications.d.ts.map +1 -0
  447. package/dist/merge/components/conflict-notifications/useConflictNotifications.js +151 -0
  448. package/dist/merge/components/conflict-notifications/useConflictNotifications.js.map +1 -0
  449. package/dist/merge/components/conflict-resolution/ComponentConflictGroup.d.ts +55 -0
  450. package/dist/merge/components/conflict-resolution/ComponentConflictGroup.d.ts.map +1 -0
  451. package/dist/merge/components/conflict-resolution/ComponentConflictGroup.js +112 -0
  452. package/dist/merge/components/conflict-resolution/ComponentConflictGroup.js.map +1 -0
  453. package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.d.ts +51 -0
  454. package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.d.ts.map +1 -0
  455. package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.js +75 -0
  456. package/dist/merge/components/conflict-resolution/PuckFieldResolutionPanel.js.map +1 -0
  457. package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.d.ts +37 -0
  458. package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.d.ts.map +1 -0
  459. package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.js +42 -0
  460. package/dist/merge/components/conflict-resolution/RenderedResolutionPreview.js.map +1 -0
  461. package/dist/merge/components/conflict-resolution/index.d.ts +12 -0
  462. package/dist/merge/components/conflict-resolution/index.d.ts.map +1 -0
  463. package/dist/merge/components/conflict-resolution/index.js +9 -0
  464. package/dist/merge/components/conflict-resolution/index.js.map +1 -0
  465. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.d.ts +44 -0
  466. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.d.ts.map +1 -0
  467. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js +186 -0
  468. package/dist/merge/components/merge-resolution/CherryPickVisualPanel.js.map +1 -0
  469. package/dist/merge/components/merge-resolution/ComponentClickOverlay.d.ts +34 -0
  470. package/dist/merge/components/merge-resolution/ComponentClickOverlay.d.ts.map +1 -0
  471. package/dist/merge/components/merge-resolution/ComponentClickOverlay.js +141 -0
  472. package/dist/merge/components/merge-resolution/ComponentClickOverlay.js.map +1 -0
  473. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.d.ts +26 -0
  474. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.d.ts.map +1 -0
  475. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js +167 -0
  476. package/dist/merge/components/merge-resolution/DocumentResolutionDetail.js.map +1 -0
  477. package/dist/merge/components/merge-resolution/DocumentResolutionList.d.ts +21 -0
  478. package/dist/merge/components/merge-resolution/DocumentResolutionList.d.ts.map +1 -0
  479. package/dist/merge/components/merge-resolution/DocumentResolutionList.js +106 -0
  480. package/dist/merge/components/merge-resolution/DocumentResolutionList.js.map +1 -0
  481. package/dist/merge/components/merge-resolution/MergeResolutionPage.d.ts +15 -0
  482. package/dist/merge/components/merge-resolution/MergeResolutionPage.d.ts.map +1 -0
  483. package/dist/merge/components/merge-resolution/MergeResolutionPage.js +90 -0
  484. package/dist/merge/components/merge-resolution/MergeResolutionPage.js.map +1 -0
  485. package/dist/merge/components/merge-resolution/MergeResolutionToolbar.d.ts +26 -0
  486. package/dist/merge/components/merge-resolution/MergeResolutionToolbar.d.ts.map +1 -0
  487. package/dist/merge/components/merge-resolution/MergeResolutionToolbar.js +23 -0
  488. package/dist/merge/components/merge-resolution/MergeResolutionToolbar.js.map +1 -0
  489. package/dist/merge/components/merge-resolution/MergeReviewPage.d.ts +11 -0
  490. package/dist/merge/components/merge-resolution/MergeReviewPage.d.ts.map +1 -0
  491. package/dist/merge/components/merge-resolution/MergeReviewPage.js +26 -0
  492. package/dist/merge/components/merge-resolution/MergeReviewPage.js.map +1 -0
  493. package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.d.ts +16 -0
  494. package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.d.ts.map +1 -0
  495. package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.js +15 -0
  496. package/dist/merge/components/merge-resolution/ResolutionStrategyPicker.js.map +1 -0
  497. package/dist/merge/components/merge-resolution/index.d.ts +20 -0
  498. package/dist/merge/components/merge-resolution/index.d.ts.map +1 -0
  499. package/dist/merge/components/merge-resolution/index.js +12 -0
  500. package/dist/merge/components/merge-resolution/index.js.map +1 -0
  501. package/dist/merge/index.d.ts +8 -0
  502. package/dist/merge/index.d.ts.map +1 -0
  503. package/dist/merge/index.js +6 -0
  504. package/dist/merge/index.js.map +1 -0
  505. package/dist/merge/useMergeResolution.d.ts +65 -0
  506. package/dist/merge/useMergeResolution.d.ts.map +1 -0
  507. package/dist/merge/useMergeResolution.js +444 -0
  508. package/dist/merge/useMergeResolution.js.map +1 -0
  509. package/dist/merge/utils/puckFieldClassifier.d.ts +151 -0
  510. package/dist/merge/utils/puckFieldClassifier.d.ts.map +1 -0
  511. package/dist/merge/utils/puckFieldClassifier.js +427 -0
  512. package/dist/merge/utils/puckFieldClassifier.js.map +1 -0
  513. package/dist/p1/editor/client.d.ts +17 -0
  514. package/dist/p1/editor/client.d.ts.map +1 -0
  515. package/dist/p1/editor/client.js +79 -0
  516. package/dist/p1/editor/client.js.map +1 -0
  517. package/dist/p1/editor/connect/connect-field-modal.d.ts +11 -0
  518. package/dist/p1/editor/connect/connect-field-modal.d.ts.map +1 -0
  519. package/dist/p1/editor/connect/connect-field-modal.js +127 -0
  520. package/dist/p1/editor/connect/connect-field-modal.js.map +1 -0
  521. package/dist/p1/editor/connect/connect-preview-config.d.ts +7 -0
  522. package/dist/p1/editor/connect/connect-preview-config.d.ts.map +1 -0
  523. package/dist/p1/editor/connect/connect-preview-config.js +76 -0
  524. package/dist/p1/editor/connect/connect-preview-config.js.map +1 -0
  525. package/dist/p1/editor/connect/field-connect-plugin.d.ts +10 -0
  526. package/dist/p1/editor/connect/field-connect-plugin.d.ts.map +1 -0
  527. package/dist/p1/editor/connect/field-connect-plugin.js +46 -0
  528. package/dist/p1/editor/connect/field-connect-plugin.js.map +1 -0
  529. package/dist/p1/editor/editor-preview-resolve.d.ts +11 -0
  530. package/dist/p1/editor/editor-preview-resolve.d.ts.map +1 -0
  531. package/dist/p1/editor/editor-preview-resolve.js +115 -0
  532. package/dist/p1/editor/editor-preview-resolve.js.map +1 -0
  533. package/dist/p1/editor/hooks.d.ts +42 -0
  534. package/dist/p1/editor/hooks.d.ts.map +1 -0
  535. package/dist/p1/editor/hooks.js +219 -0
  536. package/dist/p1/editor/hooks.js.map +1 -0
  537. package/dist/p1/editor/icons/button-block-icon.d.ts +2 -0
  538. package/dist/p1/editor/icons/button-block-icon.d.ts.map +1 -0
  539. package/dist/p1/editor/icons/button-block-icon.js +5 -0
  540. package/dist/p1/editor/icons/button-block-icon.js.map +1 -0
  541. package/dist/p1/editor/icons/default-block-icon.d.ts +2 -0
  542. package/dist/p1/editor/icons/default-block-icon.d.ts.map +1 -0
  543. package/dist/p1/editor/icons/default-block-icon.js +5 -0
  544. package/dist/p1/editor/icons/default-block-icon.js.map +1 -0
  545. package/dist/p1/editor/icons/divider-block-icon.d.ts +2 -0
  546. package/dist/p1/editor/icons/divider-block-icon.d.ts.map +1 -0
  547. package/dist/p1/editor/icons/divider-block-icon.js +5 -0
  548. package/dist/p1/editor/icons/divider-block-icon.js.map +1 -0
  549. package/dist/p1/editor/icons/grid-block-icon.d.ts +2 -0
  550. package/dist/p1/editor/icons/grid-block-icon.d.ts.map +1 -0
  551. package/dist/p1/editor/icons/grid-block-icon.js +5 -0
  552. package/dist/p1/editor/icons/grid-block-icon.js.map +1 -0
  553. package/dist/p1/editor/icons/heading-block-icon.d.ts +2 -0
  554. package/dist/p1/editor/icons/heading-block-icon.d.ts.map +1 -0
  555. package/dist/p1/editor/icons/heading-block-icon.js +5 -0
  556. package/dist/p1/editor/icons/heading-block-icon.js.map +1 -0
  557. package/dist/p1/editor/icons/image-block-icon.d.ts +2 -0
  558. package/dist/p1/editor/icons/image-block-icon.d.ts.map +1 -0
  559. package/dist/p1/editor/icons/image-block-icon.js +5 -0
  560. package/dist/p1/editor/icons/image-block-icon.js.map +1 -0
  561. package/dist/p1/editor/icons/list-block-icon.d.ts +2 -0
  562. package/dist/p1/editor/icons/list-block-icon.d.ts.map +1 -0
  563. package/dist/p1/editor/icons/list-block-icon.js +5 -0
  564. package/dist/p1/editor/icons/list-block-icon.js.map +1 -0
  565. package/dist/p1/editor/icons/paragraph-block-icon.d.ts +2 -0
  566. package/dist/p1/editor/icons/paragraph-block-icon.d.ts.map +1 -0
  567. package/dist/p1/editor/icons/paragraph-block-icon.js +5 -0
  568. package/dist/p1/editor/icons/paragraph-block-icon.js.map +1 -0
  569. package/dist/p1/editor/icons/quote-block-icon.d.ts +2 -0
  570. package/dist/p1/editor/icons/quote-block-icon.d.ts.map +1 -0
  571. package/dist/p1/editor/icons/quote-block-icon.js +5 -0
  572. package/dist/p1/editor/icons/quote-block-icon.js.map +1 -0
  573. package/dist/p1/editor/icons/spacer-block-icon.d.ts +2 -0
  574. package/dist/p1/editor/icons/spacer-block-icon.d.ts.map +1 -0
  575. package/dist/p1/editor/icons/spacer-block-icon.js +5 -0
  576. package/dist/p1/editor/icons/spacer-block-icon.js.map +1 -0
  577. package/dist/p1/editor/index.d.ts +9 -0
  578. package/dist/p1/editor/index.d.ts.map +1 -0
  579. package/dist/p1/editor/index.js +9 -0
  580. package/dist/p1/editor/index.js.map +1 -0
  581. package/dist/p1/editor/json-tree.d.ts +6 -0
  582. package/dist/p1/editor/json-tree.d.ts.map +1 -0
  583. package/dist/p1/editor/json-tree.js +64 -0
  584. package/dist/p1/editor/json-tree.js.map +1 -0
  585. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.d.ts +11 -0
  586. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.d.ts.map +1 -0
  587. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js +62 -0
  588. package/dist/p1/editor/remote-datasources/remote-datasource-explorer-plugin.js.map +1 -0
  589. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts +23 -0
  590. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.d.ts.map +1 -0
  591. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.js +39 -0
  592. package/dist/p1/editor/remote-datasources/remote-datasource-form-helpers.js.map +1 -0
  593. package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts +4 -0
  594. package/dist/p1/editor/remote-datasources/remote-datasource-manager.d.ts.map +1 -0
  595. package/dist/p1/editor/remote-datasources/remote-datasource-manager.js +72 -0
  596. package/dist/p1/editor/remote-datasources/remote-datasource-manager.js.map +1 -0
  597. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts +6 -0
  598. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.d.ts.map +1 -0
  599. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js +67 -0
  600. package/dist/p1/editor/remote-datasources/template-preview-params-toolbar.js.map +1 -0
  601. package/dist/p1/editor/template-autocomplete-layer.d.ts +11 -0
  602. package/dist/p1/editor/template-autocomplete-layer.d.ts.map +1 -0
  603. package/dist/p1/editor/template-autocomplete-layer.js +386 -0
  604. package/dist/p1/editor/template-autocomplete-layer.js.map +1 -0
  605. package/dist/p1/pages/add-override-for-template.d.ts +4 -0
  606. package/dist/p1/pages/add-override-for-template.d.ts.map +1 -0
  607. package/dist/p1/pages/add-override-for-template.js +47 -0
  608. package/dist/p1/pages/add-override-for-template.js.map +1 -0
  609. package/dist/p1/pages/create-page-form.d.ts +2 -0
  610. package/dist/p1/pages/create-page-form.d.ts.map +1 -0
  611. package/dist/p1/pages/create-page-form.js +28 -0
  612. package/dist/p1/pages/create-page-form.js.map +1 -0
  613. package/dist/p1/pages/create-template-form.d.ts +2 -0
  614. package/dist/p1/pages/create-template-form.d.ts.map +1 -0
  615. package/dist/p1/pages/create-template-form.js +36 -0
  616. package/dist/p1/pages/create-template-form.js.map +1 -0
  617. package/dist/p1/pages/delete-row-button.d.ts +7 -0
  618. package/dist/p1/pages/delete-row-button.d.ts.map +1 -0
  619. package/dist/p1/pages/delete-row-button.js +23 -0
  620. package/dist/p1/pages/delete-row-button.js.map +1 -0
  621. package/dist/p1/pages/hooks.d.ts +5 -0
  622. package/dist/p1/pages/hooks.d.ts.map +1 -0
  623. package/dist/p1/pages/hooks.js +55 -0
  624. package/dist/p1/pages/hooks.js.map +1 -0
  625. package/dist/p1/pages/index.d.ts +7 -0
  626. package/dist/p1/pages/index.d.ts.map +1 -0
  627. package/dist/p1/pages/index.js +7 -0
  628. package/dist/p1/pages/index.js.map +1 -0
  629. package/dist/p1/pages/render-client.d.ts +6 -0
  630. package/dist/p1/pages/render-client.d.ts.map +1 -0
  631. package/dist/p1/pages/render-client.js +7 -0
  632. package/dist/p1/pages/render-client.js.map +1 -0
  633. package/dist/p1/pages/structure-page.d.ts +2 -0
  634. package/dist/p1/pages/structure-page.d.ts.map +1 -0
  635. package/dist/p1/pages/structure-page.js +46 -0
  636. package/dist/p1/pages/structure-page.js.map +1 -0
  637. package/dist/p1/router-context.d.ts +11 -0
  638. package/dist/p1/router-context.d.ts.map +1 -0
  639. package/dist/p1/router-context.js +11 -0
  640. package/dist/p1/router-context.js.map +1 -0
  641. package/dist/pds/components/AgentChip.d.ts +26 -0
  642. package/dist/pds/components/AgentChip.d.ts.map +1 -0
  643. package/dist/pds/components/AgentChip.js +15 -0
  644. package/dist/pds/components/AgentChip.js.map +1 -0
  645. package/dist/pds/components/AgentChip.module.css +141 -0
  646. package/dist/pds/components/DocStateBadge.d.ts +7 -0
  647. package/dist/pds/components/DocStateBadge.d.ts.map +1 -0
  648. package/dist/pds/components/DocStateBadge.js +24 -0
  649. package/dist/pds/components/DocStateBadge.js.map +1 -0
  650. package/dist/pds/components/NavIcon.d.ts +7 -0
  651. package/dist/pds/components/NavIcon.d.ts.map +1 -0
  652. package/dist/pds/components/NavIcon.js +6 -0
  653. package/dist/pds/components/NavIcon.js.map +1 -0
  654. package/dist/pds/components/P1EditorHeader.d.ts +41 -0
  655. package/dist/pds/components/P1EditorHeader.d.ts.map +1 -0
  656. package/dist/pds/components/P1EditorHeader.js +138 -0
  657. package/dist/pds/components/P1EditorHeader.js.map +1 -0
  658. package/dist/pds/components/P1EditorHeader.module.css +253 -0
  659. package/dist/pds/components/P1EditorSubheader.d.ts +42 -0
  660. package/dist/pds/components/P1EditorSubheader.d.ts.map +1 -0
  661. package/dist/pds/components/P1EditorSubheader.js +27 -0
  662. package/dist/pds/components/P1EditorSubheader.js.map +1 -0
  663. package/dist/pds/components/P1EditorSubheader.module.css +81 -0
  664. package/dist/pds/components/PageNavigator.d.ts +38 -0
  665. package/dist/pds/components/PageNavigator.d.ts.map +1 -0
  666. package/dist/pds/components/PageNavigator.js +60 -0
  667. package/dist/pds/components/PageNavigator.js.map +1 -0
  668. package/dist/pds/components/PageNavigator.module.css +276 -0
  669. package/dist/pds/components/PresenceStack.d.ts +17 -0
  670. package/dist/pds/components/PresenceStack.d.ts.map +1 -0
  671. package/dist/pds/components/PresenceStack.js +14 -0
  672. package/dist/pds/components/PresenceStack.js.map +1 -0
  673. package/dist/pds/components/PresenceStack.module.css +48 -0
  674. package/dist/pds/components/PublishControl.d.ts +15 -0
  675. package/dist/pds/components/PublishControl.d.ts.map +1 -0
  676. package/dist/pds/components/PublishControl.js +46 -0
  677. package/dist/pds/components/PublishControl.js.map +1 -0
  678. package/dist/pds/components/PublishControl.module.css +36 -0
  679. package/dist/pds/components/WorkstreamSwitcher.d.ts +26 -0
  680. package/dist/pds/components/WorkstreamSwitcher.d.ts.map +1 -0
  681. package/dist/pds/components/WorkstreamSwitcher.js +134 -0
  682. package/dist/pds/components/WorkstreamSwitcher.js.map +1 -0
  683. package/dist/pds/components/WorkstreamSwitcher.module.css +320 -0
  684. package/dist/pds/index.d.ts +33 -0
  685. package/dist/pds/index.d.ts.map +1 -0
  686. package/dist/pds/index.js +46 -0
  687. package/dist/pds/index.js.map +1 -0
  688. package/dist/pds/theme/pds-core-content.d.ts +2 -0
  689. package/dist/pds/theme/pds-core-content.d.ts.map +1 -0
  690. package/dist/pds/theme/pds-core-content.js +8 -0
  691. package/dist/pds/theme/pds-core-content.js.map +1 -0
  692. package/dist/pds/types.d.ts +7 -0
  693. package/dist/pds/types.d.ts.map +1 -0
  694. package/dist/pds/types.js +2 -0
  695. package/dist/pds/types.js.map +1 -0
  696. package/dist/pds/utils/deriveDocState.d.ts +8 -0
  697. package/dist/pds/utils/deriveDocState.d.ts.map +1 -0
  698. package/dist/pds/utils/deriveDocState.js +14 -0
  699. package/dist/pds/utils/deriveDocState.js.map +1 -0
  700. package/dist/server.d.ts +23 -0
  701. package/dist/server.d.ts.map +1 -0
  702. package/dist/server.js +24 -0
  703. package/dist/server.js.map +1 -0
  704. package/dist/versioning/components/HistoricalVersionBanner.d.ts +28 -0
  705. package/dist/versioning/components/HistoricalVersionBanner.d.ts.map +1 -0
  706. package/dist/versioning/components/HistoricalVersionBanner.js +23 -0
  707. package/dist/versioning/components/HistoricalVersionBanner.js.map +1 -0
  708. package/dist/versioning/components/VersionPublishedBadge.d.ts +5 -0
  709. package/dist/versioning/components/VersionPublishedBadge.d.ts.map +1 -0
  710. package/dist/versioning/components/VersionPublishedBadge.js +8 -0
  711. package/dist/versioning/components/VersionPublishedBadge.js.map +1 -0
  712. package/dist/versioning/components/version-compare/BranchDiffHeader.d.ts +53 -0
  713. package/dist/versioning/components/version-compare/BranchDiffHeader.d.ts.map +1 -0
  714. package/dist/versioning/components/version-compare/BranchDiffHeader.js +15 -0
  715. package/dist/versioning/components/version-compare/BranchDiffHeader.js.map +1 -0
  716. package/dist/versioning/components/version-compare/BranchMergeCompare.d.ts +43 -0
  717. package/dist/versioning/components/version-compare/BranchMergeCompare.d.ts.map +1 -0
  718. package/dist/versioning/components/version-compare/BranchMergeCompare.js +70 -0
  719. package/dist/versioning/components/version-compare/BranchMergeCompare.js.map +1 -0
  720. package/dist/versioning/components/version-compare/ComponentNode.d.ts +34 -0
  721. package/dist/versioning/components/version-compare/ComponentNode.d.ts.map +1 -0
  722. package/dist/versioning/components/version-compare/ComponentNode.js +40 -0
  723. package/dist/versioning/components/version-compare/ComponentNode.js.map +1 -0
  724. package/dist/versioning/components/version-compare/ComponentTree.d.ts +34 -0
  725. package/dist/versioning/components/version-compare/ComponentTree.d.ts.map +1 -0
  726. package/dist/versioning/components/version-compare/ComponentTree.js +35 -0
  727. package/dist/versioning/components/version-compare/ComponentTree.js.map +1 -0
  728. package/dist/versioning/components/version-compare/DiffHeader.d.ts +45 -0
  729. package/dist/versioning/components/version-compare/DiffHeader.d.ts.map +1 -0
  730. package/dist/versioning/components/version-compare/DiffHeader.js +11 -0
  731. package/dist/versioning/components/version-compare/DiffHeader.js.map +1 -0
  732. package/dist/versioning/components/version-compare/DocumentDiffList.d.ts +39 -0
  733. package/dist/versioning/components/version-compare/DocumentDiffList.d.ts.map +1 -0
  734. package/dist/versioning/components/version-compare/DocumentDiffList.js +32 -0
  735. package/dist/versioning/components/version-compare/DocumentDiffList.js.map +1 -0
  736. package/dist/versioning/components/version-compare/PropDiffPanel.d.ts +30 -0
  737. package/dist/versioning/components/version-compare/PropDiffPanel.d.ts.map +1 -0
  738. package/dist/versioning/components/version-compare/PropDiffPanel.js +34 -0
  739. package/dist/versioning/components/version-compare/PropDiffPanel.js.map +1 -0
  740. package/dist/versioning/components/version-compare/PropDiffRow.d.ts +22 -0
  741. package/dist/versioning/components/version-compare/PropDiffRow.d.ts.map +1 -0
  742. package/dist/versioning/components/version-compare/PropDiffRow.js +12 -0
  743. package/dist/versioning/components/version-compare/PropDiffRow.js.map +1 -0
  744. package/dist/versioning/components/version-compare/PropValueDisplay.d.ts +36 -0
  745. package/dist/versioning/components/version-compare/PropValueDisplay.d.ts.map +1 -0
  746. package/dist/versioning/components/version-compare/PropValueDisplay.js +79 -0
  747. package/dist/versioning/components/version-compare/PropValueDisplay.js.map +1 -0
  748. package/dist/versioning/components/version-compare/VersionComparePage.d.ts +34 -0
  749. package/dist/versioning/components/version-compare/VersionComparePage.d.ts.map +1 -0
  750. package/dist/versioning/components/version-compare/VersionComparePage.js +61 -0
  751. package/dist/versioning/components/version-compare/VersionComparePage.js.map +1 -0
  752. package/dist/versioning/components/version-compare/VisualBranchCompare.d.ts +41 -0
  753. package/dist/versioning/components/version-compare/VisualBranchCompare.d.ts.map +1 -0
  754. package/dist/versioning/components/version-compare/VisualBranchCompare.js +84 -0
  755. package/dist/versioning/components/version-compare/VisualBranchCompare.js.map +1 -0
  756. package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts +67 -0
  757. package/dist/versioning/components/version-compare/VisualVersionCompare.d.ts.map +1 -0
  758. package/dist/versioning/components/version-compare/VisualVersionCompare.js +84 -0
  759. package/dist/versioning/components/version-compare/VisualVersionCompare.js.map +1 -0
  760. package/dist/versioning/components/version-compare/index.d.ts +30 -0
  761. package/dist/versioning/components/version-compare/index.d.ts.map +1 -0
  762. package/dist/versioning/components/version-compare/index.js +18 -0
  763. package/dist/versioning/components/version-compare/index.js.map +1 -0
  764. package/dist/versioning/components/version-history/AgentCheckpointBadge.d.ts +22 -0
  765. package/dist/versioning/components/version-history/AgentCheckpointBadge.d.ts.map +1 -0
  766. package/dist/versioning/components/version-history/AgentCheckpointBadge.js +55 -0
  767. package/dist/versioning/components/version-history/AgentCheckpointBadge.js.map +1 -0
  768. package/dist/versioning/components/version-history/VersionItem.d.ts +30 -0
  769. package/dist/versioning/components/version-history/VersionItem.d.ts.map +1 -0
  770. package/dist/versioning/components/version-history/VersionItem.js +39 -0
  771. package/dist/versioning/components/version-history/VersionItem.js.map +1 -0
  772. package/dist/versioning/components/version-history/index.d.ts +10 -0
  773. package/dist/versioning/components/version-history/index.d.ts.map +1 -0
  774. package/dist/versioning/components/version-history/index.js +8 -0
  775. package/dist/versioning/components/version-history/index.js.map +1 -0
  776. package/dist/versioning/index.d.ts +17 -0
  777. package/dist/versioning/index.d.ts.map +1 -0
  778. package/dist/versioning/index.js +10 -0
  779. package/dist/versioning/index.js.map +1 -0
  780. package/dist/versioning/useCheckpoints.d.ts +66 -0
  781. package/dist/versioning/useCheckpoints.d.ts.map +1 -0
  782. package/dist/versioning/useCheckpoints.js +100 -0
  783. package/dist/versioning/useCheckpoints.js.map +1 -0
  784. package/dist/versioning/useVersions.d.ts +81 -0
  785. package/dist/versioning/useVersions.d.ts.map +1 -0
  786. package/dist/versioning/useVersions.js +110 -0
  787. package/dist/versioning/useVersions.js.map +1 -0
  788. package/dist/versioning/utils/branchDiff.d.ts +136 -0
  789. package/dist/versioning/utils/branchDiff.d.ts.map +1 -0
  790. package/dist/versioning/utils/branchDiff.js +172 -0
  791. package/dist/versioning/utils/branchDiff.js.map +1 -0
  792. package/dist/versioning/utils/diff.d.ts +63 -0
  793. package/dist/versioning/utils/diff.d.ts.map +1 -0
  794. package/dist/versioning/utils/diff.js +318 -0
  795. package/dist/versioning/utils/diff.js.map +1 -0
  796. package/dist/versioning/utils/highlightConfig.d.ts +41 -0
  797. package/dist/versioning/utils/highlightConfig.d.ts.map +1 -0
  798. package/dist/versioning/utils/highlightConfig.js +130 -0
  799. package/dist/versioning/utils/highlightConfig.js.map +1 -0
  800. package/package.json +113 -0
  801. package/src/pds/theme/PuckEditorTheme.css +277 -0
  802. package/src/pds/theme/PuckEditorTheme.test.ts +136 -0
  803. package/src/pds/theme/pds-core-content.ts +7 -0
  804. package/src/pds/theme/pds-core.css +2 -0
  805. 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