@elytracms/studio 0.0.91 → 0.0.93

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 (353) hide show
  1. package/convex/asset-alt-migration.test.ts +127 -0
  2. package/convex/asset-replace.test.ts +168 -0
  3. package/convex/asset-revalidate.test.ts +6 -6
  4. package/convex/assets.ts +41 -5
  5. package/convex/cms.ts +537 -177
  6. package/convex/contract-parity.test.ts +173 -19
  7. package/convex/delivery.ts +26 -13
  8. package/convex/document-revalidate.test.ts +17 -16
  9. package/convex/orphan-hydration.test.ts +116 -0
  10. package/convex/presence-cost.test.ts +89 -0
  11. package/convex/rail-write-parity.test.ts +17 -14
  12. package/convex/referenceMaintenance.ts +15 -15
  13. package/convex/schema.ts +70 -5
  14. package/convex/triggers.ts +21 -8
  15. package/convex/write-limits.ts +1 -1
  16. package/dist/components/ai/ai-chat-panel.js +33 -22
  17. package/dist/components/ai/ai-chat-panel.js.map +1 -1
  18. package/dist/components/ai/proposal-card.js +2 -1
  19. package/dist/components/ai/proposal-card.js.map +1 -1
  20. package/dist/components/ai/translate-document-action.d.ts +8 -2
  21. package/dist/components/ai/translate-document-action.js.map +1 -1
  22. package/dist/components/ai/translate-document-dialog.d.ts +1 -1
  23. package/dist/components/ai/translate-document-dialog.js +14 -8
  24. package/dist/components/ai/translate-document-dialog.js.map +1 -1
  25. package/dist/components/ai/translate-skipped.d.ts +19 -0
  26. package/dist/components/ai/translate-skipped.js +46 -0
  27. package/dist/components/ai/translate-skipped.js.map +1 -0
  28. package/dist/components/app-views/default-modules.d.ts +23 -6
  29. package/dist/components/app-views/default-modules.js +33 -14
  30. package/dist/components/app-views/default-modules.js.map +1 -1
  31. package/dist/components/assets/asset-detail.js +18 -8
  32. package/dist/components/assets/asset-detail.js.map +1 -1
  33. package/dist/components/assets/asset-metadata.d.ts +15 -4
  34. package/dist/components/assets/asset-metadata.js +15 -2
  35. package/dist/components/assets/asset-metadata.js.map +1 -1
  36. package/dist/components/assets/asset-search.js +4 -1
  37. package/dist/components/assets/asset-search.js.map +1 -1
  38. package/dist/components/assets/asset-selection.d.ts +0 -8
  39. package/dist/components/assets/asset-selection.js +4 -23
  40. package/dist/components/assets/asset-selection.js.map +1 -1
  41. package/dist/components/assets/asset-thumb.js +3 -2
  42. package/dist/components/assets/asset-thumb.js.map +1 -1
  43. package/dist/components/assets/assets-collection-view-source.d.ts +3 -3
  44. package/dist/components/assets/assets-collection-view-source.js +9 -5
  45. package/dist/components/assets/assets-collection-view-source.js.map +1 -1
  46. package/dist/components/assets/assets-store.d.ts +14 -0
  47. package/dist/components/assets/assets-store.js +23 -1
  48. package/dist/components/assets/assets-store.js.map +1 -1
  49. package/dist/components/assets/replace-file.d.ts +22 -0
  50. package/dist/components/assets/replace-file.js +59 -0
  51. package/dist/components/assets/replace-file.js.map +1 -0
  52. package/dist/components/builder/blocks-model.d.ts +14 -26
  53. package/dist/components/builder/blocks-model.js +35 -41
  54. package/dist/components/builder/blocks-model.js.map +1 -1
  55. package/dist/components/builder/blocks-panel.d.ts +7 -3
  56. package/dist/components/builder/blocks-panel.js +6 -5
  57. package/dist/components/builder/blocks-panel.js.map +1 -1
  58. package/dist/components/builder/builder-store.d.ts +126 -30
  59. package/dist/components/builder/builder-store.js +169 -67
  60. package/dist/components/builder/builder-store.js.map +1 -1
  61. package/dist/components/builder/canvas-body.d.ts +30 -0
  62. package/dist/components/builder/canvas-body.js +38 -0
  63. package/dist/components/builder/canvas-body.js.map +1 -0
  64. package/dist/components/builder/canvas-chrome-css.js +7 -0
  65. package/dist/components/builder/canvas-chrome-css.js.map +1 -1
  66. package/dist/components/builder/canvas-dnd.d.ts +7 -7
  67. package/dist/components/builder/canvas-dnd.js +5 -5
  68. package/dist/components/builder/canvas-dnd.js.map +1 -1
  69. package/dist/components/builder/canvas-render-context.d.ts +30 -22
  70. package/dist/components/builder/canvas-render-context.js +44 -44
  71. package/dist/components/builder/canvas-render-context.js.map +1 -1
  72. package/dist/components/builder/canvas-runs.d.ts +45 -0
  73. package/dist/components/builder/canvas-runs.js +51 -0
  74. package/dist/components/builder/canvas-runs.js.map +1 -0
  75. package/dist/components/builder/canvas.d.ts +5 -4
  76. package/dist/components/builder/canvas.js +34 -6
  77. package/dist/components/builder/canvas.js.map +1 -1
  78. package/dist/components/builder/clipboard-actions.d.ts +15 -0
  79. package/dist/components/builder/clipboard-actions.js +50 -13
  80. package/dist/components/builder/clipboard-actions.js.map +1 -1
  81. package/dist/components/builder/composition-field-editor.d.ts +10 -16
  82. package/dist/components/builder/composition-field-editor.js +30 -40
  83. package/dist/components/builder/composition-field-editor.js.map +1 -1
  84. package/dist/components/builder/composition-patches.d.ts +7 -0
  85. package/dist/components/builder/composition-patches.js +256 -0
  86. package/dist/components/builder/composition-patches.js.map +1 -0
  87. package/dist/components/builder/delete-key.d.ts +5 -0
  88. package/dist/components/builder/delete-key.js +4 -0
  89. package/dist/components/builder/delete-key.js.map +1 -1
  90. package/dist/components/builder/insert-context.d.ts +17 -25
  91. package/dist/components/builder/insert-context.js +45 -92
  92. package/dist/components/builder/insert-context.js.map +1 -1
  93. package/dist/components/builder/page-tree.d.ts +3 -3
  94. package/dist/components/builder/page-tree.js +3 -3
  95. package/dist/components/builder/page-tree.js.map +1 -1
  96. package/dist/components/builder/placement-refusal.d.ts +18 -0
  97. package/dist/components/builder/placement-refusal.js +46 -0
  98. package/dist/components/builder/placement-refusal.js.map +1 -0
  99. package/dist/components/builder/property-inspector.js +4 -0
  100. package/dist/components/builder/property-inspector.js.map +1 -1
  101. package/dist/components/builder/reuse-context.js +65 -26
  102. package/dist/components/builder/reuse-context.js.map +1 -1
  103. package/dist/components/builder/reuse.d.ts +79 -8
  104. package/dist/components/builder/reuse.js +71 -23
  105. package/dist/components/builder/reuse.js.map +1 -1
  106. package/dist/components/builder/run-inspector.d.ts +11 -0
  107. package/dist/components/builder/run-inspector.js +33 -0
  108. package/dist/components/builder/run-inspector.js.map +1 -0
  109. package/dist/components/cms/asset-field.d.ts +38 -1
  110. package/dist/components/cms/asset-field.js +182 -58
  111. package/dist/components/cms/asset-field.js.map +1 -1
  112. package/dist/components/cms/asset-picker-core.d.ts +16 -0
  113. package/dist/components/cms/asset-picker-core.js +20 -0
  114. package/dist/components/cms/asset-picker-core.js.map +1 -1
  115. package/dist/components/cms/asset-picker.js +12 -18
  116. package/dist/components/cms/asset-picker.js.map +1 -1
  117. package/dist/components/cms/bulk-actions.d.ts +4 -20
  118. package/dist/components/cms/bulk-actions.js +3 -24
  119. package/dist/components/cms/bulk-actions.js.map +1 -1
  120. package/dist/components/cms/cell-edit.d.ts +5 -5
  121. package/dist/components/cms/cell-edit.js.map +1 -1
  122. package/dist/components/cms/cell.js.map +1 -1
  123. package/dist/components/cms/cms-store.d.ts +87 -45
  124. package/dist/components/cms/cms-store.js +347 -203
  125. package/dist/components/cms/cms-store.js.map +1 -1
  126. package/dist/components/cms/collection-table.js +7 -2
  127. package/dist/components/cms/collection-table.js.map +1 -1
  128. package/dist/components/cms/commit-policy.d.ts +24 -0
  129. package/dist/components/cms/commit-policy.js +37 -0
  130. package/dist/components/cms/commit-policy.js.map +1 -0
  131. package/dist/components/cms/detail-editor.js +83 -137
  132. package/dist/components/cms/detail-editor.js.map +1 -1
  133. package/dist/components/cms/document-diff-view.d.ts +3 -1
  134. package/dist/components/cms/document-diff-view.js +12 -7
  135. package/dist/components/cms/document-diff-view.js.map +1 -1
  136. package/dist/components/cms/draft-commit.d.ts +70 -0
  137. package/dist/components/cms/draft-commit.js +82 -0
  138. package/dist/components/cms/draft-commit.js.map +1 -0
  139. package/dist/components/cms/duplicate-document.d.ts +11 -13
  140. package/dist/components/cms/duplicate-document.js +26 -34
  141. package/dist/components/cms/duplicate-document.js.map +1 -1
  142. package/dist/components/cms/field-anchors.d.ts +7 -4
  143. package/dist/components/cms/field-anchors.js +9 -7
  144. package/dist/components/cms/field-anchors.js.map +1 -1
  145. package/dist/components/cms/field-collaboration.d.ts +47 -0
  146. package/dist/components/cms/field-collaboration.js +87 -0
  147. package/dist/components/cms/field-collaboration.js.map +1 -0
  148. package/dist/components/cms/field-control-lib.d.ts +22 -1
  149. package/dist/components/cms/field-control-lib.js +33 -4
  150. package/dist/components/cms/field-control-lib.js.map +1 -1
  151. package/dist/components/cms/field-control.js +17 -14
  152. package/dist/components/cms/field-control.js.map +1 -1
  153. package/dist/components/cms/gate-validation.d.ts +21 -30
  154. package/dist/components/cms/gate-validation.js +11 -22
  155. package/dist/components/cms/gate-validation.js.map +1 -1
  156. package/dist/components/cms/object-array-field.js +4 -4
  157. package/dist/components/cms/object-array-field.js.map +1 -1
  158. package/dist/components/cms/prop-fields.d.ts +7 -2
  159. package/dist/components/cms/prop-fields.js +13 -6
  160. package/dist/components/cms/prop-fields.js.map +1 -1
  161. package/dist/components/cms/reference-confirm.js +10 -4
  162. package/dist/components/cms/reference-confirm.js.map +1 -1
  163. package/dist/components/cms/rich-text/embed-picker.d.ts +1 -1
  164. package/dist/components/cms/rich-text/embed-picker.js.map +1 -1
  165. package/dist/components/cms/rich-text/insert.d.ts +20 -9
  166. package/dist/components/cms/rich-text/insert.js +25 -17
  167. package/dist/components/cms/rich-text/insert.js.map +1 -1
  168. package/dist/components/cms/use-document-draft.d.ts +96 -0
  169. package/dist/components/cms/use-document-draft.js +283 -0
  170. package/dist/components/cms/use-document-draft.js.map +1 -0
  171. package/dist/components/cms/use-document-versions.js +2 -2
  172. package/dist/components/cms/use-document-versions.js.map +1 -1
  173. package/dist/components/cms/use-live-url.d.ts +6 -12
  174. package/dist/components/cms/use-live-url.js +16 -15
  175. package/dist/components/cms/use-live-url.js.map +1 -1
  176. package/dist/components/cms/use-publish-controller.d.ts +13 -18
  177. package/dist/components/cms/use-publish-controller.js +24 -41
  178. package/dist/components/cms/use-publish-controller.js.map +1 -1
  179. package/dist/components/cms/use-published-perspective.d.ts +2 -3
  180. package/dist/components/cms/use-published-perspective.js +4 -3
  181. package/dist/components/cms/use-published-perspective.js.map +1 -1
  182. package/dist/components/cms/versions-pane.js +8 -1
  183. package/dist/components/cms/versions-pane.js.map +1 -1
  184. package/dist/components/collection-view/cms-collection-view-source.js +24 -7
  185. package/dist/components/collection-view/cms-collection-view-source.js.map +1 -1
  186. package/dist/components/components/transfer-dialog.js +28 -23
  187. package/dist/components/components/transfer-dialog.js.map +1 -1
  188. package/dist/components/components/transfer.d.ts +31 -21
  189. package/dist/components/components/transfer.js +49 -35
  190. package/dist/components/components/transfer.js.map +1 -1
  191. package/dist/components/project-list.js.map +1 -1
  192. package/dist/components/project-session.d.ts +6 -3
  193. package/dist/components/project-session.js +14 -8
  194. package/dist/components/project-session.js.map +1 -1
  195. package/dist/components/project-switcher.js.map +1 -1
  196. package/dist/components/rail-view-source.js +2 -1
  197. package/dist/components/rail-view-source.js.map +1 -1
  198. package/dist/components/section-nav.js +1 -1
  199. package/dist/components/section-nav.js.map +1 -1
  200. package/dist/lib/ai/apply-content.js +56 -116
  201. package/dist/lib/ai/apply-content.js.map +1 -1
  202. package/dist/lib/ai/chat-context.d.ts +8 -0
  203. package/dist/lib/ai/chat-context.js +37 -6
  204. package/dist/lib/ai/chat-context.js.map +1 -1
  205. package/dist/lib/ai/chat-state.d.ts +14 -1
  206. package/dist/lib/ai/chat-state.js.map +1 -1
  207. package/dist/lib/ai/constraints.d.ts +20 -5
  208. package/dist/lib/ai/constraints.js +125 -33
  209. package/dist/lib/ai/constraints.js.map +1 -1
  210. package/dist/lib/ai/fake-provider.d.ts +16 -3
  211. package/dist/lib/ai/fake-provider.js +22 -6
  212. package/dist/lib/ai/fake-provider.js.map +1 -1
  213. package/dist/lib/ai/index.d.ts +2 -0
  214. package/dist/lib/ai/index.js +2 -0
  215. package/dist/lib/ai/index.js.map +1 -1
  216. package/dist/lib/ai/leash.d.ts +34 -0
  217. package/dist/lib/ai/leash.js +28 -0
  218. package/dist/lib/ai/leash.js.map +1 -0
  219. package/dist/lib/ai/provenance.d.ts +1 -1
  220. package/dist/lib/ai/provenance.js.map +1 -1
  221. package/dist/lib/ai/rich-text-input.d.ts +8 -8
  222. package/dist/lib/ai/rich-text-input.js +2 -1
  223. package/dist/lib/ai/rich-text-input.js.map +1 -1
  224. package/dist/lib/ai/rich-text-translate.d.ts +27 -4
  225. package/dist/lib/ai/rich-text-translate.js +28 -10
  226. package/dist/lib/ai/rich-text-translate.js.map +1 -1
  227. package/dist/lib/ai/shape.d.ts +13 -13
  228. package/dist/lib/ai/shape.js +69 -93
  229. package/dist/lib/ai/shape.js.map +1 -1
  230. package/dist/lib/ai/tools.d.ts +36 -41
  231. package/dist/lib/ai/tools.js +85 -87
  232. package/dist/lib/ai/tools.js.map +1 -1
  233. package/dist/lib/ai/translate-document.d.ts +39 -5
  234. package/dist/lib/ai/translate-document.js +160 -51
  235. package/dist/lib/ai/translate-document.js.map +1 -1
  236. package/dist/lib/ai/types.d.ts +34 -23
  237. package/dist/lib/ai/types.js.map +1 -1
  238. package/dist/lib/ai/update-fields.d.ts +21 -12
  239. package/dist/lib/ai/update-fields.js +118 -177
  240. package/dist/lib/ai/update-fields.js.map +1 -1
  241. package/dist/lib/ai/writer-form.d.ts +116 -0
  242. package/dist/lib/ai/writer-form.js +429 -0
  243. package/dist/lib/ai/writer-form.js.map +1 -0
  244. package/dist/lib/ai-current-document.d.ts +11 -11
  245. package/dist/lib/ai-current-document.js +4 -4
  246. package/dist/lib/ai-current-document.js.map +1 -1
  247. package/dist/lib/assets/upload.d.ts +31 -2
  248. package/dist/lib/assets/upload.js +61 -6
  249. package/dist/lib/assets/upload.js.map +1 -1
  250. package/dist/lib/clipboard/os-clipboard.d.ts +10 -2
  251. package/dist/lib/clipboard/os-clipboard.js +8 -4
  252. package/dist/lib/clipboard/os-clipboard.js.map +1 -1
  253. package/dist/lib/clipboard/paste-target.d.ts +18 -9
  254. package/dist/lib/clipboard/paste-target.js +8 -7
  255. package/dist/lib/clipboard/paste-target.js.map +1 -1
  256. package/dist/lib/cms/field-patch.d.ts +15 -0
  257. package/dist/lib/cms/field-patch.js +25 -0
  258. package/dist/lib/cms/field-patch.js.map +1 -0
  259. package/dist/lib/cms/published-documents.d.ts +1 -1
  260. package/dist/lib/cms/published-documents.js +1 -1
  261. package/dist/lib/cms/published-documents.js.map +1 -1
  262. package/dist/lib/cms-views/view-model.d.ts +3 -3
  263. package/dist/lib/collection-view/__fixtures__/document-writes.d.ts +6 -0
  264. package/dist/lib/collection-view/__fixtures__/document-writes.js +23 -0
  265. package/dist/lib/collection-view/__fixtures__/document-writes.js.map +1 -0
  266. package/dist/lib/collection-view/collection-view-source.d.ts +69 -6
  267. package/dist/lib/collection-view/collection-view-source.js.map +1 -1
  268. package/dist/lib/data/collection-content.d.ts +4 -13
  269. package/dist/lib/data/collection-content.js +11 -5
  270. package/dist/lib/data/collection-content.js.map +1 -1
  271. package/dist/lib/dnd/drop-rules.d.ts +25 -31
  272. package/dist/lib/dnd/drop-rules.js +53 -59
  273. package/dist/lib/dnd/drop-rules.js.map +1 -1
  274. package/dist/lib/engine-version.d.ts +1 -1
  275. package/dist/lib/engine-version.js +1 -1
  276. package/dist/lib/engine-version.js.map +1 -1
  277. package/dist/lib/i18n/messages.de.js +72 -15
  278. package/dist/lib/i18n/messages.de.js.map +1 -1
  279. package/dist/lib/i18n/messages.en.d.ts +61 -12
  280. package/dist/lib/i18n/messages.en.js +76 -16
  281. package/dist/lib/i18n/messages.en.js.map +1 -1
  282. package/dist/lib/operations/__fixtures__/write-document.d.ts +30 -0
  283. package/dist/lib/operations/__fixtures__/write-document.js +16 -0
  284. package/dist/lib/operations/__fixtures__/write-document.js.map +1 -0
  285. package/dist/lib/operations/cms-persistence.d.ts +124 -31
  286. package/dist/lib/operations/cms-persistence.js +447 -68
  287. package/dist/lib/operations/cms-persistence.js.map +1 -1
  288. package/dist/lib/operations/config-manifest-lookup.d.ts +35 -0
  289. package/dist/lib/operations/config-manifest-lookup.js +56 -0
  290. package/dist/lib/operations/config-manifest-lookup.js.map +1 -0
  291. package/dist/lib/operations/project-runtime-config.d.ts +39 -0
  292. package/dist/lib/operations/project-runtime-config.js +54 -0
  293. package/dist/lib/operations/project-runtime-config.js.map +1 -0
  294. package/dist/lib/operations/publish-with-revision.d.ts +64 -0
  295. package/dist/lib/operations/publish-with-revision.js +66 -0
  296. package/dist/lib/operations/publish-with-revision.js.map +1 -0
  297. package/dist/lib/operations/runtime-validator.d.ts +32 -0
  298. package/dist/lib/operations/runtime-validator.js +18 -0
  299. package/dist/lib/operations/runtime-validator.js.map +1 -0
  300. package/dist/lib/operations/session-hydration.d.ts +31 -14
  301. package/dist/lib/operations/session-hydration.js +12 -16
  302. package/dist/lib/operations/session-hydration.js.map +1 -1
  303. package/dist/lib/operations/studio-operations.d.ts +59 -2
  304. package/dist/lib/operations/studio-operations.js +76 -14
  305. package/dist/lib/operations/studio-operations.js.map +1 -1
  306. package/dist/lib/persistence/convex-adapter.d.ts +13 -5
  307. package/dist/lib/persistence/convex-adapter.js +189 -74
  308. package/dist/lib/persistence/convex-adapter.js.map +1 -1
  309. package/dist/lib/persistence/convex-client.d.ts +65 -5
  310. package/dist/lib/persistence/convex-client.js +106 -3
  311. package/dist/lib/persistence/convex-client.js.map +1 -1
  312. package/dist/lib/persistence/index.js +17 -18
  313. package/dist/lib/persistence/index.js.map +1 -1
  314. package/dist/lib/persona/labels.js +4 -1
  315. package/dist/lib/persona/labels.js.map +1 -1
  316. package/dist/lib/query/operations-query.d.ts +1 -1
  317. package/dist/lib/query/operations-query.js +1 -1
  318. package/dist/lib/query/operations-query.js.map +1 -1
  319. package/dist/lib/references/impact.d.ts +21 -15
  320. package/dist/lib/references/impact.js +13 -26
  321. package/dist/lib/references/impact.js.map +1 -1
  322. package/dist/lib/references/references-store.d.ts +9 -0
  323. package/dist/lib/references/references-store.js +24 -4
  324. package/dist/lib/references/references-store.js.map +1 -1
  325. package/dist/lib/routes/route-issues.d.ts +6 -6
  326. package/dist/lib/routes/route-issues.js +26 -80
  327. package/dist/lib/routes/route-issues.js.map +1 -1
  328. package/dist/lib/workspace/config-issues.js +2 -1
  329. package/dist/lib/workspace/config-issues.js.map +1 -1
  330. package/dist/lib/workspace/index.d.ts +31 -1
  331. package/dist/lib/workspace/index.js +64 -17
  332. package/dist/lib/workspace/index.js.map +1 -1
  333. package/dist/lib/workspace/switcher-source.d.ts +3 -3
  334. package/dist/lib/workspace/switcher-source.js.map +1 -1
  335. package/dist/lib/workspace/workspace-source.d.ts +2 -2
  336. package/dist/lib/workspace/workspace-source.js +2 -1
  337. package/dist/lib/workspace/workspace-source.js.map +1 -1
  338. package/package.json +3 -3
  339. package/dist/components/cms/cms-composition-validators.d.ts +0 -16
  340. package/dist/components/cms/cms-composition-validators.js +0 -133
  341. package/dist/components/cms/cms-composition-validators.js.map +0 -1
  342. package/dist/components/cms/publish-clean.d.ts +0 -28
  343. package/dist/components/cms/publish-clean.js +0 -38
  344. package/dist/components/cms/publish-clean.js.map +0 -1
  345. package/dist/components/cms/use-save-mode.d.ts +0 -35
  346. package/dist/components/cms/use-save-mode.js +0 -54
  347. package/dist/components/cms/use-save-mode.js.map +0 -1
  348. package/dist/lib/assets/asset-placements.d.ts +0 -28
  349. package/dist/lib/assets/asset-placements.js +0 -83
  350. package/dist/lib/assets/asset-placements.js.map +0 -1
  351. package/dist/lib/cms/document-gate.d.ts +0 -47
  352. package/dist/lib/cms/document-gate.js +0 -61
  353. package/dist/lib/cms/document-gate.js.map +0 -1
@@ -0,0 +1,30 @@
1
+ import type { CmsDocument } from '@elytracms/core/cms-core';
2
+ import type { DocumentOperations } from '../operations-package.js';
3
+ /**
4
+ * EC-595 A2 — a TEST helper: write a whole document through the revisioned verbs,
5
+ * `documents.replace` at the stored revision (or insert-if-absent when there is none).
6
+ * Studio tests that only need "this document now holds these values" (seeding, a later
7
+ * edit) use it in place of the deleted whole-document upsert; a test about concurrency
8
+ * passes its own precondition to `documents.replace` / `documents.patch` instead.
9
+ */
10
+ export declare function writeDocument(ops: {
11
+ readonly documents: Pick<DocumentOperations, 'get' | 'replace'>;
12
+ }, projectId: string, document: Omit<CmsDocument, 'values'> & {
13
+ readonly values?: CmsDocument['values'];
14
+ }): Promise<import("@elytracms/core/operations").OperationResult<{
15
+ createdAt: string;
16
+ updatedAt: string;
17
+ projectId: string;
18
+ document: {
19
+ collection: string;
20
+ id: string;
21
+ values: Record<string, unknown>;
22
+ alias?: string | undefined;
23
+ localized?: Record<string, Record<string, unknown>> | undefined;
24
+ };
25
+ variant: string;
26
+ revision: number;
27
+ publishedVersion?: number | undefined;
28
+ publishedAt?: string | undefined;
29
+ hasUnpublishedChanges?: boolean | undefined;
30
+ }>>;
@@ -0,0 +1,16 @@
1
+ /**
2
+ * EC-595 A2 — a TEST helper: write a whole document through the revisioned verbs,
3
+ * `documents.replace` at the stored revision (or insert-if-absent when there is none).
4
+ * Studio tests that only need "this document now holds these values" (seeding, a later
5
+ * edit) use it in place of the deleted whole-document upsert; a test about concurrency
6
+ * passes its own precondition to `documents.replace` / `documents.patch` instead.
7
+ */
8
+ export async function writeDocument(ops, projectId, document) {
9
+ const current = await ops.documents.get({ projectId, ref: { collection: document.collection, id: document.id } });
10
+ return ops.documents.replace({
11
+ projectId,
12
+ document: { ...document, values: document.values ?? {} },
13
+ precondition: current.ok ? { revision: current.value.revision } : { ifAbsent: true },
14
+ });
15
+ }
16
+ //# sourceMappingURL=write-document.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"write-document.js","sourceRoot":"","sources":["../../../../src/lib/operations/__fixtures__/write-document.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,GAAwE,EACxE,SAAiB,EACjB,QAAmF;IAEnF,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,GAAG,EAAE,EAAE,UAAU,EAAE,QAAQ,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAA;IACjH,OAAO,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC;QAC3B,SAAS;QACT,QAAQ,EAAE,EAAE,GAAG,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,MAAM,IAAI,EAAE,EAAE;QACxD,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;KACrF,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import type { CmsDocument } from '@elytracms/core/cms-core'\nimport type { DocumentOperations } from '../operations-package'\n\n/**\n * EC-595 A2 — a TEST helper: write a whole document through the revisioned verbs,\n * `documents.replace` at the stored revision (or insert-if-absent when there is none).\n * Studio tests that only need \"this document now holds these values\" (seeding, a later\n * edit) use it in place of the deleted whole-document upsert; a test about concurrency\n * passes its own precondition to `documents.replace` / `documents.patch` instead.\n */\nexport async function writeDocument(\n ops: { readonly documents: Pick<DocumentOperations, 'get' | 'replace'> },\n projectId: string,\n document: Omit<CmsDocument, 'values'> & { readonly values?: CmsDocument['values'] },\n) {\n const current = await ops.documents.get({ projectId, ref: { collection: document.collection, id: document.id } })\n return ops.documents.replace({\n projectId,\n document: { ...document, values: document.values ?? {} },\n precondition: current.ok ? { revision: current.value.revision } : { ifAbsent: true },\n })\n}\n"]}
@@ -1,50 +1,143 @@
1
- import type { CmsDocument, CollectionDef, DocumentRef, PropFieldLookup } from '@elytracms/core/cms-core';
1
+ import type { CmsDocument, CollectionDef, DocumentPatch, DocumentRef, PropFieldLookup, RefusedPatch, ValuePath } from '@elytracms/core/cms-core';
2
2
  import type { CmsDocumentRecord } from '@elytracms/core/persistence';
3
3
  import type { OperationError, OperationsClient } from './operations-package.js';
4
4
  /**
5
- * CMS session → operations persistence (EC-141). The CMS store keeps documents
6
- * and collections as optimistic session state (synchronous editing, validation
7
- * feedback while typing); every mutation is mirrored onto the operations layer
8
- * through `documents.*` / `schema.*` commands in dispatch order.
5
+ * CMS session → operations persistence (EC-141 → EC-595 part A2): the PATCH QUEUE.
9
6
  *
10
- * Baseline: the persisted seed only covers the sample project. Before the
11
- * first mirrored command, the persister ensures the project has a persisted
12
- * schema + documents matching the session's starting state (kit imports,
13
- * sample fixtures), so deletes/updates address records that exist.
7
+ * The CMS session keeps documents as optimistic, synchronous state; every write is
8
+ * mirrored onto the operations layer through the revisioned aggregate's two verbs
9
+ * (EC-595, ratified 2026-10-24): `documents.patch` for editing, `documents.replace`
10
+ * for whole-document writers (create, import). There is no document diffing anywhere:
11
+ * every writer EMITS the patches it made at its source (the form's field path, the
12
+ * canvas's node patches, the AI proposal's field changes, bulk set-field, transfer) and
13
+ * hands them to {@link CmsPersister.commit}.
14
+ *
15
+ * **Per document, the persister keeps** the server row it last adopted (`base` — its
16
+ * revision is what a patch is made against), the committed-but-unacknowledged patches
17
+ * (each with the revision the user's view was at when it was made), and the refused
18
+ * paths awaiting a decision. It derives the session's view of the document from them:
19
+ *
20
+ * display = base.document ⊕ unresolved conflicts (mine) ⊕ in-flight ⊕ queued
21
+ *
22
+ * by re-applying the patches with THE merge (`applyDocumentPatches`, `since: []`) — the
23
+ * same pure function both stores run. So local edits win on their paths until they are
24
+ * flushed (EC-595 point 7), and a server row adopted underneath them (a write result,
25
+ * a subscription push, a conflict's `current`) shows everywhere else at once.
26
+ *
27
+ * **Base revisions are per patch** (not per call): a patch is checked against the
28
+ * changes in `(its base, current]`, so a colleague's change that arrived (by subscribe)
29
+ * AFTER the user started typing in a field is still detected on that field. A patch
30
+ * whose path our own successful write just covered moves its base to that write's
31
+ * revision — the server guarantees no other session touched the path in between, so
32
+ * a second edit of a field during the first one's flight never conflicts with itself.
33
+ * Consecutive runs of equal base are sent in commit order, one `documents.patch` call
34
+ * per run.
35
+ *
36
+ * **A refused path is a conflict ON THAT FIELD** ({@link DocumentConflict}): the
37
+ * session shows "changed by X — take theirs / keep mine"; until the user decides, the
38
+ * field keeps showing mine (and further edits of it replace mine without being sent);
39
+ * keep-mine re-sends at the current base, take-theirs drops mine. Never a
40
+ * whole-document dialog, never a silent overwrite.
14
41
  */
42
+ /** One refused patch awaiting the user's decision (EC-595 binding point 5). */
43
+ export interface DocumentConflict {
44
+ /** Stable id for the UI (`<key>|<path>`); one conflict per path. */
45
+ readonly id: string;
46
+ readonly ref: DocumentRef;
47
+ /** The refused patch — "mine". */
48
+ readonly patch: DocumentPatch;
49
+ /** The submitted target path. */
50
+ readonly path: ValuePath;
51
+ /** The value at that path on the server NOW — "theirs" (`undefined` = absent). */
52
+ readonly theirs: unknown;
53
+ /** `conflict` — changed since the base; `invalid` — never resolved (e.g. its node is gone). */
54
+ readonly reason: RefusedPatch['reason'];
55
+ /** The server revision the refusal was made at. */
56
+ readonly revision: number;
57
+ /** Who changed the path (the patch log's actor), once resolved; `undefined` while unknown. */
58
+ readonly actor?: string;
59
+ }
60
+ /** How one {@link CmsPersister.commit} ended once its patches were acknowledged. */
61
+ export type CommitOutcome = {
62
+ readonly status: 'applied';
63
+ readonly record: CmsDocumentRecord;
64
+ }
65
+ /** Refused per field — the conflicts stay open on the document for the user to resolve. */
66
+ | {
67
+ readonly status: 'refused';
68
+ readonly conflicts: readonly DocumentConflict[];
69
+ }
70
+ /** A transport / authorization failure (also reported through `onError`). */
71
+ | {
72
+ readonly status: 'failed';
73
+ readonly error: OperationError;
74
+ };
15
75
  export interface CmsPersister {
16
- upsertDocument(doc: CmsDocument): void;
76
+ /** Adopt a server row as this session's base for its document (hydration, a create result). */
77
+ track(row: TrackedRow): void;
78
+ /** The revision the session's view of a document is at (`undefined` = untracked). */
79
+ revisionOf(ref: DocumentRef): number | undefined;
80
+ /** The session's view of a tracked document (base ⊕ local), or `undefined`. */
81
+ documentOf(ref: DocumentRef): CmsDocument | undefined;
82
+ /**
83
+ * Commit patches a writer made (at the session's current view) and flush them. The
84
+ * session's view updates synchronously (via `onDocument`); the patches persist in
85
+ * order through `documents.patch`. `view` — the session's current document, the
86
+ * provisional base of a document this session holds no revision for (a staged
87
+ * transfer); its revision is read before the first send. `bases` — per patch, the
88
+ * revision the user's view was at when they STARTED that edit (an editor field typed
89
+ * across a colleague's change); absent → the revision the view is at now.
90
+ */
91
+ commit(ref: DocumentRef, patches: readonly DocumentPatch[], view?: CmsDocument, bases?: readonly (number | undefined)[]): Promise<CommitOutcome>;
92
+ /** Adopt a server row one of the session's OWN direct writes returned (publish, restore). */
93
+ adoptRecord(record: CmsDocumentRecord): void;
94
+ /** Create a document (insert-if-absent: `documents.replace` `{ ifAbsent: true }`). */
95
+ create(document: CmsDocument): void;
96
+ /**
97
+ * Write a whole document at the session's tracked revision (or insert-if-absent when
98
+ * untracked): an import. A move since then is refused as a conflict, never overwritten.
99
+ */
100
+ replace(document: CmsDocument): void;
17
101
  deleteDocument(ref: DocumentRef): void;
18
- /** Publish (EC-224): snapshot the current draft as a new version and pin it live. */
19
- publishDocument(ref: DocumentRef): void;
20
- /** Unpublish (EC-224): clear the live version pin + any legacy published marker. */
21
102
  unpublishDocument(ref: DocumentRef): void;
22
- upsertCollection(collection: CollectionDef): void;
23
- /** Run the baseline seed now (e.g. before applying an AI changeset). */
24
- ensureBaseline(): Promise<void>;
25
- /** Await every queued command. */
26
- flush(): Promise<void>;
103
+ /**
104
+ * Adopt a server row pushed by the document subscription (EC-595 point 7): applied
105
+ * under the local patches (local wins until flushed); held while a write is in flight
106
+ * and applied after it, so an echo of our own write never races its result.
107
+ * `undefined` = the document is gone.
108
+ */
109
+ adoptSnapshot(ref: DocumentRef, record: CmsDocumentRecord | undefined): void;
110
+ /** The unresolved conflicts on a document. */
111
+ conflicts(ref: DocumentRef): readonly DocumentConflict[];
112
+ /** Resolve a conflict: `theirs` adopts the server value; `mine` re-sends at the current base. */
113
+ resolveConflict(ref: DocumentRef, conflictId: string, choice: 'theirs' | 'mine'): void;
114
+ /** Await every queued write (of one document, or all). The FORCED FLUSH's persistence half. */
115
+ flush(ref?: DocumentRef): Promise<void>;
27
116
  }
28
117
  export interface CmsPersisterOptions {
29
118
  projectId: string;
30
119
  getOperations: () => Promise<OperationsClient>;
31
- /** Session collections/documents at baseline time (read lazily via refs). */
120
+ /** The session's collections (read lazily via a ref) — the create/import canonicaliser's lens. */
32
121
  getCollections: () => readonly CollectionDef[];
33
- getDocuments: () => readonly CmsDocument[];
34
- /**
35
- * Component-prop field-defs by component id (EC-277): the manifest half of the
36
- * write-time self-typing lens, so a composition's static relation/asset props are
37
- * self-typed too ("schema leads, component adopts"). Omit → document fields are
38
- * still self-typed; composition static props pass through.
39
- */
122
+ /** Component-prop field-defs (EC-277), so a created document's composition props are canonical too. */
40
123
  lookupManifest?: PropFieldLookup;
124
+ /** A failed / denied write that is not a per-field conflict — rendered by the session, never silent. */
41
125
  onError: (error: OperationError) => void;
42
126
  /**
43
- * Called with the AUTHORITATIVE saved record after each queued upsert lands
44
- * (EC-449). The session adopts server-computed record state from it — today the
45
- * write-chokepoint `hasUnpublishedChanges` verdict behind the amber "changed"
46
- * list dot. Optional: omitting it changes nothing.
127
+ * The session's view of a document changed (an optimistic commit, an adopted server
128
+ * row, a resolved conflict) — `undefined` when the document is gone. Synchronous.
129
+ */
130
+ onDocument?: (ref: DocumentRef, document: CmsDocument | undefined) => void;
131
+ /**
132
+ * A server row was adopted (EC-449 and friends): the session stamps the chokepoint's
133
+ * `hasUnpublishedChanges`, `updatedAt`, `publishedAt` from it — and, since the row
134
+ * carries the CANONICAL saved values, the session adopts those too (EC-586
135
+ * found-but-left: the studio never adopted the saved canonical document).
47
136
  */
48
- onDocumentSaved?: (record: CmsDocumentRecord) => void;
137
+ onRecord?: (record: CmsDocumentRecord) => void;
138
+ /** A document's conflict list changed. */
139
+ onConflicts?: (ref: DocumentRef, conflicts: readonly DocumentConflict[]) => void;
49
140
  }
141
+ /** What the session hydrated for a document: its value and the revision it is at. */
142
+ export type TrackedRow = Pick<CmsDocumentRecord, 'document' | 'revision'>;
50
143
  export declare function createCmsPersister(options: CmsPersisterOptions): CmsPersister;