canopycms 0.0.61 → 0.0.63

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 (237) hide show
  1. package/dist/ai/index.d.ts +9 -0
  2. package/dist/ai/index.d.ts.map +1 -1
  3. package/dist/ai/index.js +9 -0
  4. package/dist/ai/index.js.map +1 -1
  5. package/dist/ai/json-to-markdown.js +1 -2
  6. package/dist/ai/json-to-markdown.js.map +1 -1
  7. package/dist/ai/to-plain-text.d.ts +57 -0
  8. package/dist/ai/to-plain-text.d.ts.map +1 -0
  9. package/dist/ai/to-plain-text.js +255 -0
  10. package/dist/ai/to-plain-text.js.map +1 -0
  11. package/dist/ai/transform-components.d.ts.map +1 -1
  12. package/dist/ai/transform-components.js +70 -5
  13. package/dist/ai/transform-components.js.map +1 -1
  14. package/dist/api/__test__/mock-client.d.ts +5 -1
  15. package/dist/api/__test__/mock-client.d.ts.map +1 -1
  16. package/dist/api/__test__/mock-client.js +9 -2
  17. package/dist/api/__test__/mock-client.js.map +1 -1
  18. package/dist/api/admin-branch-health.d.ts +36 -1
  19. package/dist/api/admin-branch-health.d.ts.map +1 -1
  20. package/dist/api/admin-branch-health.js +176 -2
  21. package/dist/api/admin-branch-health.js.map +1 -1
  22. package/dist/api/admin.d.ts +8 -1
  23. package/dist/api/admin.d.ts.map +1 -1
  24. package/dist/api/admin.js.map +1 -1
  25. package/dist/api/branch.d.ts.map +1 -1
  26. package/dist/api/branch.js +16 -2
  27. package/dist/api/branch.js.map +1 -1
  28. package/dist/api/client.d.ts +5 -1
  29. package/dist/api/client.d.ts.map +1 -1
  30. package/dist/api/client.js +6 -0
  31. package/dist/api/client.js.map +1 -1
  32. package/dist/api/content.d.ts +11 -5
  33. package/dist/api/content.d.ts.map +1 -1
  34. package/dist/api/content.js +79 -6
  35. package/dist/api/content.js.map +1 -1
  36. package/dist/api/entries.d.ts +10 -0
  37. package/dist/api/entries.d.ts.map +1 -1
  38. package/dist/api/entries.js +40 -15
  39. package/dist/api/entries.js.map +1 -1
  40. package/dist/api/schema.d.ts +4 -4
  41. package/dist/api/schema.d.ts.map +1 -1
  42. package/dist/api/schema.js +13 -13
  43. package/dist/api/schema.js.map +1 -1
  44. package/dist/assets/transform.d.ts.map +1 -1
  45. package/dist/assets/transform.js +19 -6
  46. package/dist/assets/transform.js.map +1 -1
  47. package/dist/authorization/branch.d.ts +55 -3
  48. package/dist/authorization/branch.d.ts.map +1 -1
  49. package/dist/authorization/branch.js +55 -9
  50. package/dist/authorization/branch.js.map +1 -1
  51. package/dist/authorization/types.d.ts +1 -1
  52. package/dist/authorization/types.d.ts.map +1 -1
  53. package/dist/branch-health.d.ts +13 -0
  54. package/dist/branch-health.d.ts.map +1 -1
  55. package/dist/branch-health.js +23 -0
  56. package/dist/branch-health.js.map +1 -1
  57. package/dist/build-canopy.d.ts +49 -0
  58. package/dist/build-canopy.d.ts.map +1 -0
  59. package/dist/build-canopy.js +51 -0
  60. package/dist/build-canopy.js.map +1 -0
  61. package/dist/cli/cli.js +935 -562
  62. package/dist/cli/generate-ai-content.js +837 -480
  63. package/dist/cli/init.js +25 -7
  64. package/dist/cli/template-files/Dockerfile.cms.template +19 -1
  65. package/dist/cli/template-files/canopycms.config.ts.template +25 -1
  66. package/dist/cli/template-files/cms-stack.ts.template +7 -1
  67. package/dist/client.d.ts +1 -0
  68. package/dist/client.d.ts.map +1 -1
  69. package/dist/client.js.map +1 -1
  70. package/dist/config/schemas/field.d.ts +15 -15
  71. package/dist/config/types.d.ts +2 -2
  72. package/dist/config/types.d.ts.map +1 -1
  73. package/dist/config/types.js +0 -1
  74. package/dist/config/types.js.map +1 -1
  75. package/dist/config/validation.d.ts +9 -0
  76. package/dist/config/validation.d.ts.map +1 -1
  77. package/dist/config/validation.js +14 -0
  78. package/dist/config/validation.js.map +1 -1
  79. package/dist/content-id-index.d.ts +97 -5
  80. package/dist/content-id-index.d.ts.map +1 -1
  81. package/dist/content-id-index.js +170 -18
  82. package/dist/content-id-index.js.map +1 -1
  83. package/dist/content-listing.d.ts +110 -5
  84. package/dist/content-listing.d.ts.map +1 -1
  85. package/dist/content-listing.js +164 -23
  86. package/dist/content-listing.js.map +1 -1
  87. package/dist/content-reader.d.ts +41 -4
  88. package/dist/content-reader.d.ts.map +1 -1
  89. package/dist/content-reader.js +17 -4
  90. package/dist/content-reader.js.map +1 -1
  91. package/dist/content-store.d.ts +91 -8
  92. package/dist/content-store.d.ts.map +1 -1
  93. package/dist/content-store.js +443 -258
  94. package/dist/content-store.js.map +1 -1
  95. package/dist/content-tree.d.ts +31 -2
  96. package/dist/content-tree.d.ts.map +1 -1
  97. package/dist/content-tree.js +22 -5
  98. package/dist/content-tree.js.map +1 -1
  99. package/dist/context.d.ts +30 -10
  100. package/dist/context.d.ts.map +1 -1
  101. package/dist/context.js +55 -4
  102. package/dist/context.js.map +1 -1
  103. package/dist/editor/BranchManager.d.ts.map +1 -1
  104. package/dist/editor/BranchManager.js +18 -6
  105. package/dist/editor/BranchManager.js.map +1 -1
  106. package/dist/editor/CanopyEditor.d.ts.map +1 -1
  107. package/dist/editor/CanopyEditor.js +2 -2
  108. package/dist/editor/CanopyEditor.js.map +1 -1
  109. package/dist/editor/CanopyEditorPage.d.ts +9 -1
  110. package/dist/editor/CanopyEditorPage.d.ts.map +1 -1
  111. package/dist/editor/CanopyEditorPage.js +9 -2
  112. package/dist/editor/CanopyEditorPage.js.map +1 -1
  113. package/dist/editor/Editor.d.ts +9 -1
  114. package/dist/editor/Editor.d.ts.map +1 -1
  115. package/dist/editor/Editor.js +58 -24
  116. package/dist/editor/Editor.js.map +1 -1
  117. package/dist/editor/FormRenderer.d.ts.map +1 -1
  118. package/dist/editor/FormRenderer.js +12 -0
  119. package/dist/editor/FormRenderer.js.map +1 -1
  120. package/dist/editor/admin/SystemHealthPanel.js +6 -2
  121. package/dist/editor/admin/SystemHealthPanel.js.map +1 -1
  122. package/dist/editor/components/EntryCreateModal.d.ts +9 -1
  123. package/dist/editor/components/EntryCreateModal.d.ts.map +1 -1
  124. package/dist/editor/components/EntryCreateModal.js +4 -1
  125. package/dist/editor/components/EntryCreateModal.js.map +1 -1
  126. package/dist/editor/fields/DateTimeField.d.ts +46 -0
  127. package/dist/editor/fields/DateTimeField.d.ts.map +1 -0
  128. package/dist/editor/fields/DateTimeField.js +66 -0
  129. package/dist/editor/fields/DateTimeField.js.map +1 -0
  130. package/dist/editor/fields/NumberField.d.ts +34 -0
  131. package/dist/editor/fields/NumberField.d.ts.map +1 -0
  132. package/dist/editor/fields/NumberField.js +53 -0
  133. package/dist/editor/fields/NumberField.js.map +1 -0
  134. package/dist/editor/fields/NumberListField.d.ts +25 -0
  135. package/dist/editor/fields/NumberListField.d.ts.map +1 -0
  136. package/dist/editor/fields/NumberListField.js +53 -0
  137. package/dist/editor/fields/NumberListField.js.map +1 -0
  138. package/dist/editor/hooks/useBranchManager.d.ts.map +1 -1
  139. package/dist/editor/hooks/useBranchManager.js +115 -26
  140. package/dist/editor/hooks/useBranchManager.js.map +1 -1
  141. package/dist/editor/hooks/useDraftManager.d.ts +8 -0
  142. package/dist/editor/hooks/useDraftManager.d.ts.map +1 -1
  143. package/dist/editor/hooks/useDraftManager.js +261 -21
  144. package/dist/editor/hooks/useDraftManager.js.map +1 -1
  145. package/dist/editor/hooks/useEntryManager.d.ts +21 -0
  146. package/dist/editor/hooks/useEntryManager.d.ts.map +1 -1
  147. package/dist/editor/hooks/useEntryManager.js +25 -2
  148. package/dist/editor/hooks/useEntryManager.js.map +1 -1
  149. package/dist/editor/theme.d.ts +8 -8
  150. package/dist/entry-schema.d.ts +228 -8
  151. package/dist/entry-schema.d.ts.map +1 -1
  152. package/dist/entry-schema.js +124 -0
  153. package/dist/entry-schema.js.map +1 -1
  154. package/dist/git-manager.d.ts +51 -7
  155. package/dist/git-manager.d.ts.map +1 -1
  156. package/dist/git-manager.js +105 -14
  157. package/dist/git-manager.js.map +1 -1
  158. package/dist/http/handler.d.ts.map +1 -1
  159. package/dist/http/handler.js +70 -27
  160. package/dist/http/handler.js.map +1 -1
  161. package/dist/http/router.d.ts.map +1 -1
  162. package/dist/http/router.js +40 -3
  163. package/dist/http/router.js.map +1 -1
  164. package/dist/index.d.ts +1 -0
  165. package/dist/index.d.ts.map +1 -1
  166. package/dist/index.js +7 -0
  167. package/dist/index.js.map +1 -1
  168. package/dist/operating-mode/deployment-name-fixtures.d.ts +29 -0
  169. package/dist/operating-mode/deployment-name-fixtures.d.ts.map +1 -0
  170. package/dist/operating-mode/deployment-name-fixtures.js +55 -0
  171. package/dist/operating-mode/deployment-name-fixtures.js.map +1 -0
  172. package/dist/operating-mode/deployment-name.d.ts +9 -0
  173. package/dist/operating-mode/deployment-name.d.ts.map +1 -1
  174. package/dist/operating-mode/deployment-name.js +9 -1
  175. package/dist/operating-mode/deployment-name.js.map +1 -1
  176. package/dist/operating-mode/index.d.ts +2 -1
  177. package/dist/operating-mode/index.d.ts.map +1 -1
  178. package/dist/operating-mode/index.js +4 -1
  179. package/dist/operating-mode/index.js.map +1 -1
  180. package/dist/operating-mode/mode-env.d.ts +58 -0
  181. package/dist/operating-mode/mode-env.d.ts.map +1 -0
  182. package/dist/operating-mode/mode-env.js +97 -0
  183. package/dist/operating-mode/mode-env.js.map +1 -0
  184. package/dist/resolve-canopy-user.d.ts +34 -0
  185. package/dist/resolve-canopy-user.d.ts.map +1 -0
  186. package/dist/resolve-canopy-user.js +55 -0
  187. package/dist/resolve-canopy-user.js.map +1 -0
  188. package/dist/schema/schema-store.d.ts +53 -2
  189. package/dist/schema/schema-store.d.ts.map +1 -1
  190. package/dist/schema/schema-store.js +92 -21
  191. package/dist/schema/schema-store.js.map +1 -1
  192. package/dist/server.d.ts +60 -0
  193. package/dist/server.d.ts.map +1 -1
  194. package/dist/server.js +58 -0
  195. package/dist/server.js.map +1 -1
  196. package/dist/services.d.ts +1 -2
  197. package/dist/services.d.ts.map +1 -1
  198. package/dist/services.js +42 -12
  199. package/dist/services.js.map +1 -1
  200. package/dist/settings-workspace.d.ts +40 -0
  201. package/dist/settings-workspace.d.ts.map +1 -1
  202. package/dist/settings-workspace.js +139 -151
  203. package/dist/settings-workspace.js.map +1 -1
  204. package/dist/static/index.d.ts +65 -5
  205. package/dist/static/index.d.ts.map +1 -1
  206. package/dist/static/index.js +65 -12
  207. package/dist/static/index.js.map +1 -1
  208. package/dist/static/seo.d.ts +150 -0
  209. package/dist/static/seo.d.ts.map +1 -0
  210. package/dist/static/seo.js +189 -0
  211. package/dist/static/seo.js.map +1 -0
  212. package/dist/types.d.ts +10 -0
  213. package/dist/types.d.ts.map +1 -1
  214. package/dist/utils/content-write-lock.d.ts +127 -0
  215. package/dist/utils/content-write-lock.d.ts.map +1 -0
  216. package/dist/utils/content-write-lock.js +170 -0
  217. package/dist/utils/content-write-lock.js.map +1 -0
  218. package/dist/utils/error.d.ts +1 -1
  219. package/dist/utils/error.js +1 -1
  220. package/dist/utils/git.d.ts +16 -0
  221. package/dist/utils/git.d.ts.map +1 -1
  222. package/dist/utils/git.js +22 -0
  223. package/dist/utils/git.js.map +1 -1
  224. package/dist/utils/sanitize-href.d.ts +74 -3
  225. package/dist/utils/sanitize-href.d.ts.map +1 -1
  226. package/dist/utils/sanitize-href.js +125 -6
  227. package/dist/utils/sanitize-href.js.map +1 -1
  228. package/dist/validation/entry-link-validator.d.ts +1 -1
  229. package/dist/validation/entry-link-validator.js +3 -3
  230. package/dist/validation/entry-link-validator.js.map +1 -1
  231. package/dist/validation/entry-validator.js +1 -1
  232. package/dist/validation/entry-validator.js.map +1 -1
  233. package/dist/worker/cms-worker.d.ts +13 -0
  234. package/dist/worker/cms-worker.d.ts.map +1 -1
  235. package/dist/worker/cms-worker.js +326 -264
  236. package/dist/worker/cms-worker.js.map +1 -1
  237. package/package.json +2 -2
@@ -12,30 +12,93 @@ import { BRANCHES_KEY, fetchBranches, useBranchesData } from './useBranchesData.
12
12
  // which breaks adopters' production `next build` of the editor bundle.
13
13
  // paths/branch-name.ts is the dependency-free home of sanitizeBranchName.
14
14
  import { sanitizeBranchName } from '../../paths/branch-name.js';
15
+ /**
16
+ * Wire a confirm modal's exits so exactly ONE of {confirmed, dismissed} runs,
17
+ * whichever happens first.
18
+ *
19
+ * Neither Mantine callback is the "user declined" signal on its own, in
20
+ * opposite directions: `onCancel` does NOT fire for an Escape or overlay
21
+ * dismissal (so a caller waiting on it alone waits forever), while `onClose`
22
+ * fires for EVERY exit including a confirm -- Mantine closes the modal right
23
+ * after calling `onConfirm`, and does not await it, so a bare `onClose`
24
+ * handler would settle the caller's promise before the confirmed work had
25
+ * even run. Claiming the first exit resolves both.
26
+ */
27
+ const confirmModalHandlers = (onConfirm, onDismiss) => {
28
+ let settled = false;
29
+ const claim = () => {
30
+ if (settled)
31
+ return false;
32
+ settled = true;
33
+ return true;
34
+ };
35
+ return {
36
+ onConfirm: () => {
37
+ // Not awaited by Mantine either way; the handlers below own their own
38
+ // error reporting, so nothing here can reject.
39
+ if (claim())
40
+ void onConfirm();
41
+ },
42
+ onCancel: () => {
43
+ if (claim())
44
+ onDismiss();
45
+ },
46
+ onClose: () => {
47
+ if (claim())
48
+ onDismiss();
49
+ },
50
+ };
51
+ };
15
52
  /**
16
53
  * Helper function to show confirmation modal for branch submit action.
17
54
  */
18
- const showSubmitConfirmation = (branchName, onConfirm, onCancel) => {
55
+ const showSubmitConfirmation = (branchName, onConfirm, onDismiss) => {
19
56
  modals.openConfirmModal({
20
57
  title: 'Submit Branch for Review',
21
58
  children: (_jsx(Text, { size: "sm", style: { whiteSpace: 'pre-line' }, children: `Are you sure you want to submit "${branchName}" for review?\n\nThis will:\n• Create a pull request for review\n• Change the branch status to "submitted"\n• Notify reviewers of pending changes` })),
22
59
  labels: { confirm: 'Submit Branch', cancel: 'Cancel' },
23
60
  confirmProps: { color: 'brand' },
24
- onCancel,
25
- onConfirm,
61
+ ...confirmModalHandlers(onConfirm, onDismiss),
26
62
  });
27
63
  };
28
64
  /**
29
65
  * Helper function to show confirmation modal for branch withdraw action.
30
66
  */
31
- const showWithdrawConfirmation = (branchName, onConfirm, onCancel) => {
67
+ const showWithdrawConfirmation = (branchName, onConfirm, onDismiss) => {
32
68
  modals.openConfirmModal({
33
69
  title: 'Withdraw Branch from Review',
34
70
  children: (_jsx(Text, { size: "sm", style: { whiteSpace: 'pre-line' }, children: `Are you sure you want to withdraw "${branchName}" from review?\n\nThis will:\n• Convert the pull request to a draft\n• Change the branch status back to "editing"\n• Remove from review queue` })),
35
71
  labels: { confirm: 'Withdraw Branch', cancel: 'Cancel' },
36
72
  confirmProps: { color: 'orange' },
37
- onCancel,
38
- onConfirm,
73
+ ...confirmModalHandlers(onConfirm, onDismiss),
74
+ });
75
+ };
76
+ /**
77
+ * Helper function to show confirmation modal for branch delete action.
78
+ *
79
+ * Unlike submit/withdraw (both reversible), delete is irreversible -- it
80
+ * unlinks branch.json, removes the clone, and removes the branch head from
81
+ * the local git mirror. Before this, `handleDelete` below called
82
+ * `apiClient.branches.delete` immediately on click with no confirmation
83
+ * anywhere in the chain (BranchManager.tsx's delete button calls `onDelete`
84
+ * directly), while submit and withdraw -- both reversible -- each went
85
+ * through this same `modals.openConfirmModal` pattern. This closes that gap;
86
+ * `color: 'red'` marks it as the destructive one, matching the button's own
87
+ * color in BranchManager.tsx.
88
+ */
89
+ const showDeleteConfirmation = (branchName, onConfirm, onDismiss) => {
90
+ modals.openConfirmModal({
91
+ title: 'Delete Branch',
92
+ children: (_jsx(Text, { size: "sm", style: { whiteSpace: 'pre-line' }, children: `Are you sure you want to delete "${branchName}"?\n\nThis will:\n• Permanently remove the branch and its clone\n• Discard any unsaved or unmerged changes\n\nThis cannot be undone.` })),
93
+ labels: { confirm: 'Delete Branch', cancel: 'Cancel' },
94
+ // data-testid is load-bearing, not decoration: the e2e helper
95
+ // (apps/test-app/e2e/fixtures/branch-page.ts's deleteBranch) already
96
+ // anticipated a delete confirmation and clicks
97
+ // [data-testid="confirm-delete-branch"] when it appears. Without this the
98
+ // modal opens, nothing dismisses it, and the branch never disappears --
99
+ // which is exactly how the e2e suite caught this confirmation being added.
100
+ confirmProps: { color: 'red', 'data-testid': 'confirm-delete-branch' },
101
+ ...confirmModalHandlers(onConfirm, onDismiss),
39
102
  });
40
103
  };
41
104
  /**
@@ -220,7 +283,13 @@ export function useBranchManager(options) {
220
283
  finally {
221
284
  options.setBusy(false);
222
285
  }
223
- }, () => reject(new Error('User cancelled submit')));
286
+ },
287
+ // Dismissal is not an error. Rejecting here meant clicking Cancel
288
+ // logged a console error at the only call site (Editor.tsx catches
289
+ // these into console.error), which is both noise and a trip hazard
290
+ // for the CI=1 stray-console gate. Settled once, by onCancel OR
291
+ // onClose, so an Escape/overlay dismissal can't leave this pending.
292
+ () => resolve());
224
293
  });
225
294
  };
226
295
  const handleWithdraw = async (branchNameToWithdraw) => {
@@ -246,7 +315,13 @@ export function useBranchManager(options) {
246
315
  finally {
247
316
  options.setBusy(false);
248
317
  }
249
- }, () => reject(new Error('User cancelled withdraw')));
318
+ },
319
+ // Dismissal is not an error. Rejecting here meant clicking Cancel
320
+ // logged a console error at the only call site (Editor.tsx catches
321
+ // these into console.error), which is both noise and a trip hazard
322
+ // for the CI=1 stray-console gate. Settled once, by onCancel OR
323
+ // onClose, so an Escape/overlay dismissal can't leave this pending.
324
+ () => resolve());
250
325
  });
251
326
  };
252
327
  const handleRequestChanges = async (branchNameForChanges) => {
@@ -268,24 +343,38 @@ export function useBranchManager(options) {
268
343
  }
269
344
  };
270
345
  const handleDelete = async (branchNameToDelete) => {
271
- options.setBusy(true);
272
- try {
273
- const result = await apiClient.branches.delete({
274
- branch: branchNameToDelete,
275
- });
276
- if (!result.ok) {
277
- throw new Error(result.error || 'Failed to delete branch');
278
- }
279
- notifications.show({ message: 'Branch deleted', color: 'green' });
280
- await loadBranches();
281
- }
282
- catch (err) {
283
- const message = err instanceof Error ? err.message : 'Failed to delete branch';
284
- notifications.show({ message, color: 'red' });
285
- }
286
- finally {
287
- options.setBusy(false);
288
- }
346
+ return new Promise((resolve) => {
347
+ showDeleteConfirmation(branchNameToDelete, async () => {
348
+ options.setBusy(true);
349
+ try {
350
+ const result = await apiClient.branches.delete({
351
+ branch: branchNameToDelete,
352
+ });
353
+ if (!result.ok) {
354
+ throw new Error(result.error || 'Failed to delete branch');
355
+ }
356
+ notifications.show({ message: 'Branch deleted', color: 'green' });
357
+ await loadBranches();
358
+ }
359
+ catch (err) {
360
+ const message = err instanceof Error ? err.message : 'Failed to delete branch';
361
+ notifications.show({ message, color: 'red' });
362
+ }
363
+ finally {
364
+ options.setBusy(false);
365
+ // Resolve regardless of API success/failure, matching the
366
+ // pre-confirmation behavior (errors were shown as a toast, not
367
+ // rethrown). Cancellation resolves too -- see below.
368
+ resolve();
369
+ }
370
+ },
371
+ // Dismissal is not an error. Rejecting here meant clicking Cancel
372
+ // logged a console error at the only call site (Editor.tsx catches
373
+ // these into console.error), which is both noise and a trip hazard
374
+ // for the CI=1 stray-console gate. Settled once, by onCancel OR
375
+ // onClose, so an Escape/overlay dismissal can't leave this pending.
376
+ () => resolve());
377
+ });
289
378
  };
290
379
  const handleReloadBranchData = async () => {
291
380
  await loadBranches();
@@ -1 +1 @@
1
- {"version":3,"file":"useBranchManager.js","sourceRoot":"","sources":["../../../src/editor/hooks/useBranchManager.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"useBranchManager.js","sourceRoot":"","sources":["../../../src/editor/hooks/useBranchManager.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,KAAK,CAAA;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AACpC,OAAO,EAAE,MAAM,EAAE,MAAM,iBAAiB,CAAA;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAKtD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAA;AAChF,0EAA0E;AAC1E,2EAA2E;AAC3E,uEAAuE;AACvE,0EAA0E;AAC1E,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAA;AAE5D;;;;;;;;;;;GAWG;AACH,MAAM,oBAAoB,GAAG,CAAC,SAA8B,EAAE,SAAqB,EAAE,EAAE;IACrF,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,MAAM,KAAK,GAAG,GAAY,EAAE;QAC1B,IAAI,OAAO;YAAE,OAAO,KAAK,CAAA;QACzB,OAAO,GAAG,IAAI,CAAA;QACd,OAAO,IAAI,CAAA;IACb,CAAC,CAAA;IACD,OAAO;QACL,SAAS,EAAE,GAAG,EAAE;YACd,sEAAsE;YACtE,+CAA+C;YAC/C,IAAI,KAAK,EAAE;gBAAE,KAAK,SAAS,EAAE,CAAA;QAC/B,CAAC;QACD,QAAQ,EAAE,GAAG,EAAE;YACb,IAAI,KAAK,EAAE;gBAAE,SAAS,EAAE,CAAA;QAC1B,CAAC;QACD,OAAO,EAAE,GAAG,EAAE;YACZ,IAAI,KAAK,EAAE;gBAAE,SAAS,EAAE,CAAA;QAC1B,CAAC;KACF,CAAA;AACH,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,sBAAsB,GAAG,CAC7B,UAAkB,EAClB,SAA8B,EAC9B,SAAqB,EACrB,EAAE;IACF,MAAM,CAAC,gBAAgB,CAAC;QACtB,KAAK,EAAE,0BAA0B;QACjC,QAAQ,EAAE,CACR,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,YAC9C,oCAAoC,UAAU,mJAAmJ,GAC7L,CACR;QACD,MAAM,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE;QACtD,YAAY,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE;QAChC,GAAG,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;GAEG;AACH,MAAM,wBAAwB,GAAG,CAC/B,UAAkB,EAClB,SAA8B,EAC9B,SAAqB,EACrB,EAAE;IACF,MAAM,CAAC,gBAAgB,CAAC;QACtB,KAAK,EAAE,6BAA6B;QACpC,QAAQ,EAAE,CACR,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,YAC9C,sCAAsC,UAAU,+IAA+I,GAC3L,CACR;QACD,MAAM,EAAE,EAAE,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,QAAQ,EAAE;QACxD,YAAY,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE;QACjC,GAAG,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,sBAAsB,GAAG,CAC7B,UAAkB,EAClB,SAA8B,EAC9B,SAAqB,EACrB,EAAE;IACF,MAAM,CAAC,gBAAgB,CAAC;QACtB,KAAK,EAAE,eAAe;QACtB,QAAQ,EAAE,CACR,KAAC,IAAI,IAAC,IAAI,EAAC,IAAI,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,UAAU,EAAE,YAC9C,oCAAoC,UAAU,sIAAsI,GAChL,CACR;QACD,MAAM,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,MAAM,EAAE,QAAQ,EAAE;QACtD,8DAA8D;QAC9D,qEAAqE;QACrE,+CAA+C;QAC/C,0EAA0E;QAC1E,wEAAwE;QACxE,2EAA2E;QAC3E,YAAY,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,aAAa,EAAE,uBAAuB,EAAE;QACtE,GAAG,oBAAoB,CAAC,SAAS,EAAE,SAAS,CAAC;KAC9C,CAAC,CAAA;AACJ,CAAC,CAAA;AAsFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAgC;IAC/D,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,EAAE,CAAA;IAC/C,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAS,OAAO,CAAC,aAAa,CAAC,CAAA;IAC3E,yEAAyE;IACzE,wEAAwE;IACxE,qEAAqE;IACrE,MAAM,EACJ,IAAI,EAAE,YAAY,EAClB,KAAK,EAAE,aAAa,EACpB,YAAY,EAAE,oBAAoB,GACnC,GAAG,eAAe,CAAC,SAAS,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC,YAAY,EAAE,QAAQ,IAAI,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAA;IAE5E,8EAA8E;IAC9E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,IAAI,YAAY,EAAE,aAAa,EAAE,CAAC;YAC/C,aAAa,CAAC,YAAY,CAAC,aAAa,CAAC,CAAA;QAC3C,CAAC;IACH,CAAC,EAAE,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAA;IAE9B,4EAA4E;IAC5E,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO,CAAC,KAAK,CAAC,aAAa,CAAC,CAAA;YAC5B,MAAM,OAAO,GACX,aAAa,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAA;YACpF,0EAA0E;YAC1E,8DAA8D;YAC9D,aAAa,CAAC,IAAI,CAAC;gBACjB,EAAE,EAAE,6BAA6B;gBACjC,OAAO;gBACP,KAAK,EAAE,KAAK;gBACZ,SAAS,EAAE,KAAK;aACjB,CAAC,CAAA;QACJ,CAAC;aAAM,IAAI,YAAY,EAAE,CAAC;YACxB,uEAAuE;YACvE,0EAA0E;YAC1E,aAAa,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAA;QACnD,CAAC;IACH,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;IAEjC,0EAA0E;IAC1E,4EAA4E;IAC5E,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAA;QACrC,yJAAyJ;IAC3J,CAAC,EAAE,CAAC,oBAAoB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAA;IAE3C,wEAAwE;IACxE,2EAA2E;IAC3E,mEAAmE;IACnE,2EAA2E;IAC3E,MAAM,aAAa,GACjB,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC;QAC3C,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,UAAU,CAAC,CAAC,CAAA;IAEjE,+CAA+C;IAC/C,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,OAAO,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;YACxB,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;YACpE,MAAM,eAAe,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAA;YACxE,OAAO;gBACL,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,MAAM,EAAE;oBACN,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY;oBAC5B,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,aAAa;iBAC/B;gBACD,cAAc,EAAE,CAAC,CAAC,cAAc;gBAChC,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;gBACtC,gBAAgB,EAAE,CAAC,CAAC,gBAAgB;gBACpC,QAAQ,EAAE,CAAC,CAAC,QAAQ;gBACpB,UAAU,EAAE,CAAC,CAAC,UAAU;gBACxB,iBAAiB,EAAE,CAAC,CAAC,iBAAiB;gBACtC,cAAc,EAAE,CAAC,CAAC,cAAc;gBAChC,aAAa,EAAE,CAAC,CAAC,aAAa;gBAC9B,YAAY,EAAE,eAAe;gBAC7B,qEAAqE;gBACrE,qEAAqE;gBACrE,sEAAsE;gBACtE,qEAAqE;gBACrE,uEAAuE;gBACvE,iEAAiE;gBACjE,oEAAoE;gBACpE,wEAAwE;gBACxE,6BAA6B;gBAC7B,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,IAAI;gBAClC,sEAAsE;gBACtE,oEAAoE;gBACpE,mEAAmE;gBACnE,uEAAuE;gBACvE,mEAAmE;gBACnE,oEAAoE;gBACpE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,KAAK;gBAC7B,YAAY,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI;gBACpC,aAAa,EAAE,CAAC,CAAC,aAAa,IAAI,IAAI;aACvC,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAA;IAE5C,2EAA2E;IAC3E,yEAAyE;IACzE,0EAA0E;IAC1E,uEAAuE;IACvE,mEAAmE;IACnE,0EAA0E;IAC1E,qEAAqE;IACrE,MAAM,YAAY,GAAG,KAAK,IAAI,EAAE;QAC9B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACrB,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,aAAa,CAAC,SAAS,CAAC,CAAA;YAC5C,MAAM,YAAY,CAAC,YAAY,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAA;QAChE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;YAClB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAA;YAC9E,0EAA0E;YAC1E,8DAA8D;YAC9D,aAAa,CAAC,IAAI,CAAC;gBACjB,EAAE,EAAE,6BAA6B;gBACjC,OAAO;gBACP,KAAK,EAAE,KAAK;gBACZ,SAAS,EAAE,KAAK;aACjB,CAAC,CAAA;QACJ,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,EAAE,kBAA0B,EAAE,EAAE;QACxD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,sBAAsB,CACpB,kBAAkB,EAClB,KAAK,IAAI,EAAE;gBACT,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBACrB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC7C,MAAM,EAAE,kBAAkB;qBAC3B,CAAC,CAAA;oBACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;wBACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,yBAAyB,CAAC,CAAA;oBAC5D,CAAC;oBACD,aAAa,CAAC,IAAI,CAAC;wBACjB,OAAO,EAAE,6BAA6B;wBACtC,KAAK,EAAE,OAAO;qBACf,CAAC,CAAA;oBACF,MAAM,YAAY,EAAE,CAAA;oBACpB,OAAO,EAAE,CAAA;gBACX,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAA;oBAC9E,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;oBAC7C,MAAM,CAAC,GAAG,CAAC,CAAA;gBACb,CAAC;wBAAS,CAAC;oBACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;gBACxB,CAAC;YACH,CAAC;YACD,kEAAkE;YAClE,mEAAmE;YACnE,mEAAmE;YACnE,gEAAgE;YAChE,oEAAoE;YACpE,GAAG,EAAE,CAAC,OAAO,EAAE,CAChB,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,cAAc,GAAG,KAAK,EAAE,oBAA4B,EAAE,EAAE;QAC5D,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC3C,wBAAwB,CACtB,oBAAoB,EACpB,KAAK,IAAI,EAAE;gBACT,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBACrB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC;wBAC/C,MAAM,EAAE,oBAAoB;qBAC7B,CAAC,CAAA;oBACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;wBACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAA;oBAC9D,CAAC;oBACD,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;oBAClE,MAAM,YAAY,EAAE,CAAA;oBACpB,OAAO,EAAE,CAAA;gBACX,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAA;oBAChF,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;oBAC7C,MAAM,CAAC,GAAG,CAAC,CAAA;gBACb,CAAC;wBAAS,CAAC;oBACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;gBACxB,CAAC;YACH,CAAC;YACD,kEAAkE;YAClE,mEAAmE;YACnE,mEAAmE;YACnE,gEAAgE;YAChE,oEAAoE;YACpE,GAAG,EAAE,CAAC,OAAO,EAAE,CAChB,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,oBAAoB,GAAG,KAAK,EAAE,oBAA4B,EAAE,EAAE;QAClE,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACrB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,EAAE,oBAAoB,EAAE,CAAC,CAAA;YACxF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;gBACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,2BAA2B,CAAC,CAAA;YAC9D,CAAC;YACD,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,mBAAmB,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAA;YACrE,MAAM,YAAY,EAAE,CAAA;QACtB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,2BAA2B,CAAA;YAChF,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;QAC/C,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;IACH,CAAC,CAAA;IAED,MAAM,YAAY,GAAG,KAAK,EAAE,kBAA0B,EAAE,EAAE;QACxD,OAAO,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE;YACnC,sBAAsB,CACpB,kBAAkB,EAClB,KAAK,IAAI,EAAE;gBACT,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;gBACrB,IAAI,CAAC;oBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC;wBAC7C,MAAM,EAAE,kBAAkB;qBAC3B,CAAC,CAAA;oBACF,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;wBACf,MAAM,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,IAAI,yBAAyB,CAAC,CAAA;oBAC5D,CAAC;oBACD,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,gBAAgB,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;oBACjE,MAAM,YAAY,EAAE,CAAA;gBACtB,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,yBAAyB,CAAA;oBAC9E,aAAa,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;gBAC/C,CAAC;wBAAS,CAAC;oBACT,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;oBACtB,0DAA0D;oBAC1D,+DAA+D;oBAC/D,qDAAqD;oBACrD,OAAO,EAAE,CAAA;gBACX,CAAC;YACH,CAAC;YACD,kEAAkE;YAClE,mEAAmE;YACnE,mEAAmE;YACnE,gEAAgE;YAChE,oEAAoE;YACpE,GAAG,EAAE,CAAC,OAAO,EAAE,CAChB,CAAA;QACH,CAAC,CAAC,CAAA;IACJ,CAAC,CAAA;IAED,MAAM,sBAAsB,GAAG,KAAK,IAAI,EAAE;QACxC,MAAM,YAAY,EAAE,CAAA;IACtB,CAAC,CAAA;IAED,+BAA+B;IAC/B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,OAAO,MAAM,KAAK,WAAW;YAAE,OAAM;QACzC,IAAI,CAAC,UAAU;YAAE,OAAM;QACvB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;QACzC,MAAM,OAAO,GAAG,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC9C,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;YAC3B,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAA;YAC1C,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAA;QACrD,CAAC;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,OAAO;QACL,UAAU;QACV,aAAa;QACb,QAAQ;QACR,eAAe;QACf,aAAa;QACb,YAAY;QACZ,cAAc;QACd,oBAAoB;QACpB,YAAY;QACZ,sBAAsB;QACtB,YAAY;KACb,CAAA;AACH,CAAC"}
@@ -16,6 +16,14 @@ export interface UseDraftManagerOptions {
16
16
  initialValues?: Record<string, FormValue>;
17
17
  loadEntry: (entry: EditorEntry) => Promise<FormValue>;
18
18
  saveEntry: (entry: EditorEntry, value: FormValue) => Promise<FormValue>;
19
+ /**
20
+ * The OCC version token currently held for an entry on the branch being
21
+ * shown (useEntryManager's `getEntryVersion`). Used to stamp each draft with
22
+ * the version it was based on, and to detect at save time that the token has
23
+ * since moved on. Optional: without it no base versions are recorded and
24
+ * conflict detection falls back entirely to the server's 409.
25
+ */
26
+ getEntryVersion?: (contentId: string) => number | undefined;
19
27
  setBusy: (busy: boolean) => void;
20
28
  /**
21
29
  * Fired (fire-and-forget) after a successful save. Lets callers refresh
@@ -1 +1 @@
1
- {"version":3,"file":"useDraftManager.d.ts","sourceRoot":"","sources":["../../../src/editor/hooks/useDraftManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAchD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACxB,OAQF,CAAA;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,WAAW,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACzC,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACrD,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACvE,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACjC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAC1E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAChF,aAAa,EAAE,SAAS,GAAG,SAAS,CAAA;IACpC,WAAW,EAAE,SAAS,GAAG,SAAS,CAAA;IAClC,cAAc,EAAE,SAAS,GAAG,SAAS,CAAA;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,mBAAmB,EAAE,MAAM,IAAI,CAAA;IAC/B,sBAAsB,EAAE,MAAM,IAAI,CAAA;IAClC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;IAC/C,eAAe,EAAE,MAAM,OAAO,CAAA;IAC9B,UAAU,EAAE,MAAM,OAAO,CAAA;IACzB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA6ZtF"}
1
+ {"version":3,"file":"useDraftManager.d.ts","sourceRoot":"","sources":["../../../src/editor/hooks/useDraftManager.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,KAAK,EAAa,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAchD;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,GAC7B,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACzB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KACxB,OAQF,CAAA;AA0DD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,WAAW,GAAG,SAAS,CAAA;IACrC,OAAO,EAAE,WAAW,EAAE,CAAA;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACzC,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACrD,SAAS,EAAE,CAAC,KAAK,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,KAAK,OAAO,CAAC,SAAS,CAAC,CAAA;IACvE;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,CAAA;IAC3D,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAA;IAChC;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,IAAI,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACjC,SAAS,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAC1E,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAA;IACvC,eAAe,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAA;IAChF,aAAa,EAAE,SAAS,GAAG,SAAS,CAAA;IACpC,WAAW,EAAE,SAAS,GAAG,SAAS,CAAA;IAClC,cAAc,EAAE,SAAS,GAAG,SAAS,CAAA;IACrC,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,WAAW,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IACxD,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/B,mBAAmB,EAAE,MAAM,IAAI,CAAA;IAC/B,sBAAsB,EAAE,MAAM,IAAI,CAAA;IAClC,YAAY,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IACjC,eAAe,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAA;IAC/C,eAAe,EAAE,MAAM,OAAO,CAAA;IAC9B,UAAU,EAAE,MAAM,OAAO,CAAA;IACzB;;;;;;OAMG;IACH,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,sBAAsB,GAAG,qBAAqB,CA0nBtF"}
@@ -31,6 +31,38 @@ export const shallowEqualRecord = (a, b) => {
31
31
  }
32
32
  return true;
33
33
  };
34
+ /** Storage-format tag for the persisted draft envelope (see `parsePersistedDrafts`). */
35
+ const DRAFTS_STORAGE_VERSION = 2;
36
+ /**
37
+ * Read the persisted draft store, tolerating the legacy pre-v2 shape.
38
+ *
39
+ * LEGACY DECISION: a pre-v2 payload carries no base versions at all, and we
40
+ * cannot reconstruct them -- the draft may predate any number of other
41
+ * people's saves. Every legacy draft is therefore restored with base version
42
+ * `null` ("unknown"), which surfaces a confirmation on save instead of
43
+ * trusting it. Trusting it is the bug being fixed; silently DISCARDING it is a
44
+ * quieter version of the same bug, so the draft is kept and the user gets the
45
+ * decision. Nothing here re-stamps `null` (the reconcile effect only fills ids
46
+ * NOT already present), so the ONLY thing that clears it is that confirmation
47
+ * -- which is why blocking on it unconditionally, as an earlier version did,
48
+ * made a legacy draft unsaveable by any sequence of actions, forever.
49
+ * This only affects drafts written before this change; everything written
50
+ * after carries a real base version.
51
+ */
52
+ const parsePersistedDrafts = (raw) => {
53
+ const parsed = JSON.parse(raw);
54
+ if (!parsed || typeof parsed !== 'object')
55
+ return { drafts: {}, baseVersions: {} };
56
+ if (parsed.v === DRAFTS_STORAGE_VERSION) {
57
+ const envelope = parsed;
58
+ return { drafts: envelope.drafts ?? {}, baseVersions: envelope.baseVersions ?? {} };
59
+ }
60
+ const drafts = parsed;
61
+ const baseVersions = {};
62
+ for (const id of Object.keys(drafts))
63
+ baseVersions[id] = null;
64
+ return { drafts, baseVersions };
65
+ };
34
66
  /**
35
67
  * Custom hook for managing draft state (localStorage persistence, save/discard).
36
68
  *
@@ -70,6 +102,26 @@ export function useDraftManager(options) {
70
102
  // entry structurally impossible: there is no render where `errorState`
71
103
  // exists but belongs to the wrong entry.
72
104
  const [errorState, setErrorState] = useState(null);
105
+ // contentId -> the server version the CURRENT draft for that entry is based
106
+ // on. A ref rather than state: nothing renders from it, and the persist
107
+ // effect below must be able to read the value stamped moments earlier in the
108
+ // same commit. Three distinguishable states, all load-bearing:
109
+ // number - known base version
110
+ // null - draft restored from storage with no recorded base ("unknown")
111
+ // absent - draft created this session before any version was known
112
+ // (adopter-supplied `initialValues`, or an edit that somehow
113
+ // preceded the entry's first load); treated as safe, matching
114
+ // the behavior before base versions existed.
115
+ const draftBaseVersionsRef = useRef({});
116
+ // The draft ids the reconcile effect below has already accounted for. It
117
+ // prunes on an observed present -> absent TRANSITION rather than on "not
118
+ // currently in drafts": the restore effect stamps base versions for ids
119
+ // whose `setDrafts` has only been QUEUED, so a prune keyed on the current
120
+ // `drafts` would delete every restored base version in the same commit that
121
+ // recorded it -- and the next pass would then re-stamp those drafts with the
122
+ // freshly loaded version, which is exactly the false "no conflict" this
123
+ // mechanism exists to prevent.
124
+ const reconciledDraftIdsRef = useRef(new Set());
73
125
  const storageKey = useMemo(() => `canopycms:drafts:${options.branchName}`, [options.branchName]);
74
126
  // Draft keys are now content IDs, not paths
75
127
  const currentId = options.currentEntry?.contentId;
@@ -111,6 +163,11 @@ export function useDraftManager(options) {
111
163
  if (prevBranchRef.current && prevBranchRef.current !== options.branchName) {
112
164
  setDrafts({});
113
165
  setLoadedValues({});
166
+ // Base versions are file mtimes, i.e. inherently per-branch -- carrying
167
+ // them across a switch would compare one branch's version against
168
+ // another's.
169
+ draftBaseVersionsRef.current = {};
170
+ reconciledDraftIdsRef.current = new Set();
114
171
  }
115
172
  prevBranchRef.current = options.branchName;
116
173
  }, [options.branchName]);
@@ -121,8 +178,15 @@ export function useDraftManager(options) {
121
178
  try {
122
179
  const raw = window.localStorage.getItem(storageKey);
123
180
  if (raw) {
124
- const parsed = JSON.parse(raw);
125
- setDrafts((prev) => ({ ...prev, ...parsed }));
181
+ const { drafts: restored, baseVersions } = parsePersistedDrafts(raw);
182
+ // Stamp the base versions BEFORE queueing the state update: the
183
+ // reconcile effect below only stamps ids it has never seen, so
184
+ // recording them here is what stops a restored draft from being
185
+ // (wrongly) stamped with the version of the load that happens next.
186
+ for (const id of Object.keys(restored)) {
187
+ draftBaseVersionsRef.current[id] = baseVersions[id] ?? null;
188
+ }
189
+ setDrafts((prev) => ({ ...prev, ...restored }));
126
190
  }
127
191
  }
128
192
  catch (err) {
@@ -138,7 +202,15 @@ export function useDraftManager(options) {
138
202
  if (event.key !== storageKey || !event.newValue)
139
203
  return;
140
204
  try {
141
- const parsed = JSON.parse(event.newValue);
205
+ const { drafts: parsed, baseVersions } = parsePersistedDrafts(event.newValue);
206
+ // Same "only fill what's missing" rule as the merge below: an id we
207
+ // already have a base version for is one this tab is already drafting,
208
+ // so the other tab's base version must not overwrite ours.
209
+ for (const id of Object.keys(parsed)) {
210
+ if (!(id in draftBaseVersionsRef.current)) {
211
+ draftBaseVersionsRef.current[id] = baseVersions[id] ?? null;
212
+ }
213
+ }
142
214
  setDrafts((prev) => {
143
215
  const missing = Object.keys(parsed).filter((id) => !(id in prev));
144
216
  if (missing.length === 0)
@@ -164,6 +236,39 @@ export function useDraftManager(options) {
164
236
  useEffect(() => {
165
237
  draftsStorageKeyRef.current = storageKey;
166
238
  }, [drafts]);
239
+ // Keep the per-draft base versions in step with `drafts`.
240
+ //
241
+ // A draft key appearing here for the first time was created by the user
242
+ // editing an entry they had already opened, so the version currently held
243
+ // for that entry IS the version their edit is based on. Keys that disappear
244
+ // (saved, discarded, reloaded) drop their base version with them, so the
245
+ // next edit re-stamps against whatever the server returned most recently.
246
+ //
247
+ // Declared BEFORE the persist effect so both run in the same commit, in this
248
+ // order -- the persist effect reads the ref this one just updated.
249
+ useEffect(() => {
250
+ const bases = draftBaseVersionsRef.current;
251
+ const draftIds = new Set(Object.keys(drafts));
252
+ for (const id of draftIds) {
253
+ if (id in bases)
254
+ continue;
255
+ const version = options.getEntryVersion?.(id);
256
+ // Only record a base we actually know. Leaving it absent (rather than
257
+ // writing `null`) keeps "never loaded, so nothing to compare" distinct
258
+ // from "restored with no recorded base", and lets a later edit stamp a
259
+ // real version once one is known.
260
+ if (version !== undefined)
261
+ bases[id] = version;
262
+ }
263
+ for (const id of reconciledDraftIdsRef.current) {
264
+ if (!draftIds.has(id))
265
+ delete bases[id];
266
+ }
267
+ reconciledDraftIdsRef.current = draftIds;
268
+ // Deliberately keyed on `drafts` alone: `options.getEntryVersion` is a
269
+ // fresh closure every render, and only a drafts change can add or remove
270
+ // the keys this effect reconciles.
271
+ }, [drafts]);
167
272
  // Persist drafts to localStorage whenever they change
168
273
  useEffect(() => {
169
274
  if (typeof window === 'undefined')
@@ -171,7 +276,12 @@ export function useDraftManager(options) {
171
276
  if (draftsStorageKeyRef.current !== storageKey)
172
277
  return;
173
278
  try {
174
- window.localStorage.setItem(storageKey, JSON.stringify(drafts));
279
+ const payload = {
280
+ v: DRAFTS_STORAGE_VERSION,
281
+ drafts,
282
+ baseVersions: draftBaseVersionsRef.current,
283
+ };
284
+ window.localStorage.setItem(storageKey, JSON.stringify(payload));
175
285
  }
176
286
  catch (err) {
177
287
  console.warn('Failed to persist drafts', err);
@@ -217,9 +327,98 @@ export function useDraftManager(options) {
217
327
  return shallowEqualRecord(prev.errors, next) ? prev : { entryId: prev.entryId, errors: next };
218
328
  });
219
329
  }, [effectiveValue, currentId, options.currentEntry?.schema, options.currentEntry?.format]);
330
+ /**
331
+ * The 409 presentation, in one place. The client-side stale-base check below
332
+ * and the server's own 409 response are the same situation from the user's
333
+ * point of view -- someone else's work is at risk -- so they must read
334
+ * identically, and "Reload" (now itself confirmed, see `handleReload`) is the
335
+ * recovery for both.
336
+ */
337
+ const showConflictNotification = () => {
338
+ notifications.show({
339
+ message: 'Content was modified by another editor. Reload to see the latest changes.',
340
+ color: 'yellow',
341
+ autoClose: getNotificationDuration(8000),
342
+ withCloseButton: true,
343
+ });
344
+ };
345
+ const draftBaseState = () => {
346
+ if (!currentId || drafts[currentId] === undefined)
347
+ return 'ok';
348
+ const currentVersion = options.getEntryVersion?.(currentId);
349
+ // No server version known for this entry at all -- nothing to compare
350
+ // against, so this check has no opinion (the server's 409 still applies).
351
+ if (currentVersion === undefined)
352
+ return 'ok';
353
+ const base = draftBaseVersionsRef.current[currentId];
354
+ if (base === undefined)
355
+ return 'ok';
356
+ if (base === null)
357
+ return 'unknown-base';
358
+ return base !== currentVersion ? 'stale' : 'ok';
359
+ };
360
+ /**
361
+ * One-time upgrade prompt for a draft carried across the pre-v2 -> v2
362
+ * storage change.
363
+ *
364
+ * `null` (unknown base) used to be treated exactly like a known-stale
365
+ * draft: blocked, with Reload and Discard the only exits -- both of which
366
+ * destroy the draft. And nothing ever re-stamped it, because the reconcile
367
+ * effect only fills ids NOT already in `bases` and `null` is present. So a
368
+ * legacy draft was visible, permanently unsaveable, and the only advice
369
+ * offered destroyed it: "kept" meant "kept and unusable".
370
+ *
371
+ * A bounded, one-time population deserves a decision, not a dead end. On
372
+ * confirm the base is re-stamped to the version currently held, so the
373
+ * draft rejoins the ordinary flow and this is never asked again -- and the
374
+ * server's own OCC check remains the backstop for the case where the
375
+ * answer was wrong.
376
+ */
377
+ const confirmUnknownBaseSave = () => new Promise((resolve) => {
378
+ let decided = false;
379
+ const settle = (value) => {
380
+ if (decided)
381
+ return;
382
+ decided = true;
383
+ resolve(value);
384
+ };
385
+ modals.openConfirmModal({
386
+ title: 'Unsaved draft from an older editor version',
387
+ children: 'This draft was saved by an earlier version of the editor, which did not record ' +
388
+ 'which version of the file it was based on. Saving it will overwrite the copy ' +
389
+ 'currently on the server, including any changes made by someone else since. ' +
390
+ 'Reload or Discard this file instead if you would rather not risk that.',
391
+ labels: { confirm: 'Save anyway', cancel: 'Cancel' },
392
+ confirmProps: { color: 'red' },
393
+ onConfirm: () => settle(true),
394
+ // onCancel alone is not enough: Mantine does not fire it when the
395
+ // modal is dismissed via Escape or the overlay, which would leave
396
+ // this promise pending forever. onClose fires for every dismissal.
397
+ onCancel: () => settle(false),
398
+ onClose: () => settle(false),
399
+ });
400
+ });
220
401
  const handleSave = async () => {
221
402
  if (!options.currentEntry || !effectiveValue || !currentId)
222
403
  return;
404
+ // Conflict check first: a stale-based draft must not be schema-validated
405
+ // into a green "Saved" -- and nagging about field errors is noise when the
406
+ // save is not going out at all.
407
+ const baseState = draftBaseState();
408
+ if (baseState === 'stale') {
409
+ showConflictNotification();
410
+ return;
411
+ }
412
+ if (baseState === 'unknown-base') {
413
+ if (!(await confirmUnknownBaseSave()))
414
+ return;
415
+ // Re-stamp so the draft rejoins the ordinary flow: from here on its base
416
+ // is a real version and the normal stale check applies. Done BEFORE the
417
+ // write so a failed save doesn't re-prompt on every retry.
418
+ const currentVersion = options.getEntryVersion?.(currentId);
419
+ if (currentVersion !== undefined)
420
+ draftBaseVersionsRef.current[currentId] = currentVersion;
421
+ }
223
422
  // Client-side pre-save validation (ED-H1): the same pure schema rules the
224
423
  // server enforces authoritatively at the write boundary. Blocks the save
225
424
  // and surfaces per-field errors in the form instead of a green "Saved".
@@ -289,18 +488,19 @@ export function useDraftManager(options) {
289
488
  err.fieldErrors.length > 0) {
290
489
  setErrorState({ entryId: currentId, errors: toFieldErrorMap(err.fieldErrors) });
291
490
  }
292
- notifications.show({
293
- ...(isValidation ? { title: 'Save rejected' } : {}),
294
- ...(isForbidden ? { title: 'Save not allowed' } : {}),
295
- message: isConflict
296
- ? 'Content was modified by another editor. Reload to see the latest changes.'
297
- : isValidation || isForbidden
298
- ? err.message
299
- : 'Save failed',
300
- color: isConflict ? 'yellow' : 'red',
301
- autoClose: getNotificationDuration(isConflict || isValidation || isForbidden ? 8000 : 6000),
302
- withCloseButton: true,
303
- });
491
+ if (isConflict) {
492
+ showConflictNotification();
493
+ }
494
+ else {
495
+ notifications.show({
496
+ ...(isValidation ? { title: 'Save rejected' } : {}),
497
+ ...(isForbidden ? { title: 'Save not allowed' } : {}),
498
+ message: isValidation || isForbidden ? err.message : 'Save failed',
499
+ color: 'red',
500
+ autoClose: getNotificationDuration(isValidation || isForbidden ? 8000 : 6000),
501
+ withCloseButton: true,
502
+ });
503
+ }
304
504
  }
305
505
  finally {
306
506
  options.setBusy(false);
@@ -354,9 +554,15 @@ export function useDraftManager(options) {
354
554
  if (typeof window !== 'undefined') {
355
555
  const raw = window.localStorage.getItem(storageKey);
356
556
  if (raw) {
357
- const parsed = JSON.parse(raw);
358
- delete parsed[currentId];
359
- window.localStorage.setItem(storageKey, JSON.stringify(parsed));
557
+ const { drafts: persisted, baseVersions } = parsePersistedDrafts(raw);
558
+ delete persisted[currentId];
559
+ delete baseVersions[currentId];
560
+ const payload = {
561
+ v: DRAFTS_STORAGE_VERSION,
562
+ drafts: persisted,
563
+ baseVersions,
564
+ };
565
+ window.localStorage.setItem(storageKey, JSON.stringify(payload));
360
566
  }
361
567
  }
362
568
  }
@@ -390,14 +596,25 @@ export function useDraftManager(options) {
390
596
  onConfirm: performDiscardFileDraft,
391
597
  });
392
598
  };
393
- const handleReload = async () => {
599
+ const performReload = async () => {
394
600
  if (!options.currentEntry || !currentId)
395
601
  return;
396
602
  options.setBusy(true);
397
603
  try {
398
604
  const loaded = await options.loadEntry(options.currentEntry);
399
605
  setLoadedValues((prev) => ({ ...prev, [currentId]: loaded }));
400
- setDrafts((prev) => ({ ...prev, [currentId]: loaded }));
606
+ // Drop the draft rather than seeding it with `loaded`. `effectiveValue`
607
+ // falls back to `loadedValues`, so the rendered value is identical --
608
+ // and a draft that merely mirrors the server value is exactly the
609
+ // phantom-dirty snapshot this hook works to avoid (same reasoning as
610
+ // handleSave's drop above).
611
+ setDrafts((prev) => {
612
+ if (!(currentId in prev))
613
+ return prev;
614
+ const next = { ...prev };
615
+ delete next[currentId];
616
+ return next;
617
+ });
401
618
  notifications.show({
402
619
  message: 'Reloaded',
403
620
  color: 'blue',
@@ -418,6 +635,29 @@ export function useDraftManager(options) {
418
635
  options.setBusy(false);
419
636
  }
420
637
  };
638
+ // Reloading replaces the working value with the server's copy, so over a
639
+ // real draft it is every bit as destructive as "Discard draft" -- and it is
640
+ // what the conflict notification tells the losing editor to do, i.e. the one
641
+ // moment their unsaved work matters most. Guarded exactly like
642
+ // handleDiscardFileDraft: the same `isSelectedDirty()` test (nothing to lose
643
+ // -> no prompt) and the same confirm-modal shape.
644
+ const handleReload = async () => {
645
+ if (!options.currentEntry || !currentId)
646
+ return;
647
+ if (!isSelectedDirty()) {
648
+ await performReload();
649
+ return;
650
+ }
651
+ modals.openConfirmModal({
652
+ title: 'Reload file',
653
+ children: 'Reload this file from the server? Unsaved changes for this file will be lost.',
654
+ labels: { confirm: 'Reload', cancel: 'Cancel' },
655
+ confirmProps: { color: 'red' },
656
+ onConfirm: () => {
657
+ void performReload();
658
+ },
659
+ });
660
+ };
421
661
  // Compute dirty state for a given entry
422
662
  const isDirtyForEntry = (entryPath) => {
423
663
  // Find entry by path to get its content ID