@rightkit/document-workspace 0.0.0-stage → 0.1.1

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 (262) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/LICENSE-APACHE +201 -0
  3. package/LICENSE-MIT +21 -0
  4. package/README.md +74 -2
  5. package/dist/app/App.d.ts +1 -0
  6. package/dist/app/App.js +6 -0
  7. package/dist/app/AppDialogs.d.ts +52 -0
  8. package/dist/app/AppDialogs.js +23 -0
  9. package/dist/app/AppDialogsHost.d.ts +31 -0
  10. package/dist/app/AppDialogsHost.js +30 -0
  11. package/dist/app/AppLifecycle.d.ts +19 -0
  12. package/dist/app/AppLifecycle.js +87 -0
  13. package/dist/app/AppProvider.d.ts +317 -0
  14. package/dist/app/AppProvider.js +217 -0
  15. package/dist/app/AppRoot.d.ts +8 -0
  16. package/dist/app/AppRoot.js +159 -0
  17. package/dist/app/AppShell.d.ts +2 -0
  18. package/dist/app/AppShell.js +81 -0
  19. package/dist/app/CommandPalette.d.ts +13 -0
  20. package/dist/app/CommandPalette.js +47 -0
  21. package/dist/app/DocActionBar.d.ts +36 -0
  22. package/dist/app/DocActionBar.js +300 -0
  23. package/dist/app/DocumentContextMenu.d.ts +29 -0
  24. package/dist/app/DocumentContextMenu.js +122 -0
  25. package/dist/app/DocumentPane.d.ts +52 -0
  26. package/dist/app/DocumentPane.js +30 -0
  27. package/dist/app/DocumentRouterTable.d.ts +58 -0
  28. package/dist/app/DocumentRouterTable.js +143 -0
  29. package/dist/app/ErrorBoundary.d.ts +12 -0
  30. package/dist/app/ErrorBoundary.js +16 -0
  31. package/dist/app/FindBar.d.ts +12 -0
  32. package/dist/app/FindBar.js +199 -0
  33. package/dist/app/LiveTitle.d.ts +14 -0
  34. package/dist/app/LiveTitle.js +14 -0
  35. package/dist/app/OpeningProgress.d.ts +13 -0
  36. package/dist/app/OpeningProgress.js +21 -0
  37. package/dist/app/PrintPreviewWindow.d.ts +2 -0
  38. package/dist/app/PrintPreviewWindow.js +57 -0
  39. package/dist/app/ShortcutHelp.d.ts +3 -0
  40. package/dist/app/ShortcutHelp.js +99 -0
  41. package/dist/app/Sidebar.d.ts +36 -0
  42. package/dist/app/Sidebar.js +121 -0
  43. package/dist/app/ToastViewport.d.ts +1 -0
  44. package/dist/app/ToastViewport.js +31 -0
  45. package/dist/app/Toolbar.d.ts +26 -0
  46. package/dist/app/Toolbar.js +63 -0
  47. package/dist/app/activeFormatSavers.d.ts +7 -0
  48. package/dist/app/activeFormatSavers.js +4 -0
  49. package/dist/app/clipboardPaths.d.ts +1 -0
  50. package/dist/app/clipboardPaths.js +31 -0
  51. package/dist/app/documentDrafts.d.ts +17 -0
  52. package/dist/app/documentDrafts.js +104 -0
  53. package/dist/app/draftResolution.d.ts +5 -0
  54. package/dist/app/draftResolution.js +25 -0
  55. package/dist/app/markdownPaletteActions.d.ts +8 -0
  56. package/dist/app/markdownPaletteActions.js +107 -0
  57. package/dist/app/resourceCensusDev.d.ts +41 -0
  58. package/dist/app/resourceCensusDev.js +518 -0
  59. package/dist/app/setupRecovery.d.ts +34 -0
  60. package/dist/app/setupRecovery.js +70 -0
  61. package/dist/app/shell/DocStatsPill.d.ts +18 -0
  62. package/dist/app/shell/DocStatsPill.js +32 -0
  63. package/dist/app/shell/DocumentTools.d.ts +9 -0
  64. package/dist/app/shell/DocumentTools.js +73 -0
  65. package/dist/app/shell/InfoInspector.d.ts +9 -0
  66. package/dist/app/shell/InfoInspector.js +67 -0
  67. package/dist/app/shell/StartPage.d.ts +9 -0
  68. package/dist/app/shell/StartPage.js +49 -0
  69. package/dist/app/shell/readEdit.d.ts +6 -0
  70. package/dist/app/shell/readEdit.js +6 -0
  71. package/dist/app/sidebar/SidebarDocumentMenu.d.ts +20 -0
  72. package/dist/app/sidebar/SidebarDocumentMenu.js +56 -0
  73. package/dist/app/sidebar/SidebarExpandedPanel.d.ts +9 -0
  74. package/dist/app/sidebar/SidebarExpandedPanel.js +78 -0
  75. package/dist/app/sidebar/SidebarIcons.d.ts +3 -0
  76. package/dist/app/sidebar/SidebarIcons.js +18 -0
  77. package/dist/app/sidebar/SidebarMenus.d.ts +19 -0
  78. package/dist/app/sidebar/SidebarMenus.js +64 -0
  79. package/dist/app/sidebar/SidebarPathUtils.d.ts +10 -0
  80. package/dist/app/sidebar/SidebarPathUtils.js +55 -0
  81. package/dist/app/sidebar/SidebarPrimitives.d.ts +12 -0
  82. package/dist/app/sidebar/SidebarPrimitives.js +45 -0
  83. package/dist/app/sidebar/SidebarRail.d.ts +5 -0
  84. package/dist/app/sidebar/SidebarRail.js +37 -0
  85. package/dist/app/sidebar/explorer/ExplorerRowMenu.d.ts +21 -0
  86. package/dist/app/sidebar/explorer/ExplorerRowMenu.js +37 -0
  87. package/dist/app/sidebar/explorer/ExplorerSections.d.ts +16 -0
  88. package/dist/app/sidebar/explorer/ExplorerSections.js +259 -0
  89. package/dist/app/sidebar/explorer/ExplorerTree.d.ts +46 -0
  90. package/dist/app/sidebar/explorer/ExplorerTree.js +387 -0
  91. package/dist/app/sidebar/explorer/explorerState.d.ts +37 -0
  92. package/dist/app/sidebar/explorer/explorerState.js +135 -0
  93. package/dist/app/tabMountPolicy.d.ts +45 -0
  94. package/dist/app/tabMountPolicy.js +104 -0
  95. package/dist/app/tabWarmOrder.d.ts +7 -0
  96. package/dist/app/tabWarmOrder.js +48 -0
  97. package/dist/app/tabs/TabFuseCurves.d.ts +3 -0
  98. package/dist/app/tabs/TabFuseCurves.js +15 -0
  99. package/dist/app/tabs/TabOverview.d.ts +24 -0
  100. package/dist/app/tabs/TabOverview.js +121 -0
  101. package/dist/app/tabs/TabStrip.d.ts +42 -0
  102. package/dist/app/tabs/TabStrip.js +380 -0
  103. package/dist/app/tabs/tabIds.d.ts +5 -0
  104. package/dist/app/tabs/tabIds.js +7 -0
  105. package/dist/app/tabs/useTabDirty.d.ts +3 -0
  106. package/dist/app/tabs/useTabDirty.js +11 -0
  107. package/dist/app/useAppChromeState.d.ts +21 -0
  108. package/dist/app/useAppChromeState.js +48 -0
  109. package/dist/app/useAppCommands.d.ts +66 -0
  110. package/dist/app/useAppCommands.js +71 -0
  111. package/dist/app/useAppDocumentCore.d.ts +210 -0
  112. package/dist/app/useAppDocumentCore.js +40 -0
  113. package/dist/app/useAppEffects.d.ts +18 -0
  114. package/dist/app/useAppEffects.js +52 -0
  115. package/dist/app/useAppPaneSearch.d.ts +37 -0
  116. package/dist/app/useAppPaneSearch.js +74 -0
  117. package/dist/app/useAppShellSetup.d.ts +40 -0
  118. package/dist/app/useAppShellSetup.js +52 -0
  119. package/dist/app/useAppSlots.d.ts +28 -0
  120. package/dist/app/useAppSlots.js +40 -0
  121. package/dist/app/useAppTabChrome.d.ts +51 -0
  122. package/dist/app/useAppTabChrome.js +66 -0
  123. package/dist/app/useAutoSave.d.ts +34 -0
  124. package/dist/app/useAutoSave.js +116 -0
  125. package/dist/app/useCloseAll.d.ts +52 -0
  126. package/dist/app/useCloseAll.js +295 -0
  127. package/dist/app/useClosedTabEviction.d.ts +10 -0
  128. package/dist/app/useClosedTabEviction.js +38 -0
  129. package/dist/app/useCommandPalette.d.ts +44 -0
  130. package/dist/app/useCommandPalette.js +254 -0
  131. package/dist/app/useCrossDocSearch.d.ts +7 -0
  132. package/dist/app/useCrossDocSearch.js +94 -0
  133. package/dist/app/useDistractionFree.d.ts +21 -0
  134. package/dist/app/useDistractionFree.js +73 -0
  135. package/dist/app/useDocumentCreation.d.ts +18 -0
  136. package/dist/app/useDocumentCreation.js +63 -0
  137. package/dist/app/useDocumentDirty.d.ts +31 -0
  138. package/dist/app/useDocumentDirty.js +46 -0
  139. package/dist/app/useDocumentLoader.d.ts +55 -0
  140. package/dist/app/useDocumentLoader.js +267 -0
  141. package/dist/app/useDocumentOutputActions.d.ts +6 -0
  142. package/dist/app/useDocumentOutputActions.js +45 -0
  143. package/dist/app/useDocumentRuntimeEffects.d.ts +36 -0
  144. package/dist/app/useDocumentRuntimeEffects.js +458 -0
  145. package/dist/app/useDocumentSaver.d.ts +58 -0
  146. package/dist/app/useDocumentSaver.js +511 -0
  147. package/dist/app/useDocumentTabs.d.ts +41 -0
  148. package/dist/app/useDocumentTabs.js +207 -0
  149. package/dist/app/useDocumentWatcher.d.ts +83 -0
  150. package/dist/app/useDocumentWatcher.js +393 -0
  151. package/dist/app/useDocumentZoom.d.ts +24 -0
  152. package/dist/app/useDocumentZoom.js +104 -0
  153. package/dist/app/useDocuments.d.ts +169 -0
  154. package/dist/app/useDocuments.js +455 -0
  155. package/dist/app/useDraftConfirmGate.d.ts +27 -0
  156. package/dist/app/useDraftConfirmGate.js +47 -0
  157. package/dist/app/useFileDragOverlay.d.ts +12 -0
  158. package/dist/app/useFileDragOverlay.js +49 -0
  159. package/dist/app/useFormatApis.d.ts +13 -0
  160. package/dist/app/useFormatApis.js +62 -0
  161. package/dist/app/useFormatDirtyState.d.ts +29 -0
  162. package/dist/app/useFormatDirtyState.js +81 -0
  163. package/dist/app/useGlobalShortcuts.d.ts +47 -0
  164. package/dist/app/useGlobalShortcuts.js +359 -0
  165. package/dist/app/useHtmlSession.d.ts +68 -0
  166. package/dist/app/useHtmlSession.js +463 -0
  167. package/dist/app/useHtmlSessionProps.d.ts +33 -0
  168. package/dist/app/useHtmlSessionProps.js +57 -0
  169. package/dist/app/useLibrary.d.ts +21 -0
  170. package/dist/app/useLibrary.js +81 -0
  171. package/dist/app/useOpenFromClipboard.d.ts +7 -0
  172. package/dist/app/useOpenFromClipboard.js +44 -0
  173. package/dist/app/usePaneLiveness.d.ts +29 -0
  174. package/dist/app/usePaneLiveness.js +199 -0
  175. package/dist/app/usePendingSavePaths.d.ts +19 -0
  176. package/dist/app/usePendingSavePaths.js +67 -0
  177. package/dist/app/useReadyShow.d.ts +12 -0
  178. package/dist/app/useReadyShow.js +142 -0
  179. package/dist/app/useSearchController.d.ts +22 -0
  180. package/dist/app/useSearchController.js +114 -0
  181. package/dist/app/useSetupRecovery.d.ts +41 -0
  182. package/dist/app/useSetupRecovery.js +153 -0
  183. package/dist/app/useTabChrome.d.ts +40 -0
  184. package/dist/app/useTabChrome.js +115 -0
  185. package/dist/app/useViewState.d.ts +27 -0
  186. package/dist/app/useViewState.js +160 -0
  187. package/dist/appName.d.ts +2 -0
  188. package/dist/appName.js +8 -0
  189. package/dist/documents/DocumentRouter.d.ts +102 -0
  190. package/dist/documents/DocumentRouter.js +153 -0
  191. package/dist/documents/FileTypeIcon.d.ts +6 -0
  192. package/dist/documents/FileTypeIcon.js +93 -0
  193. package/dist/documents/ImageDocument.d.ts +14 -0
  194. package/dist/documents/ImageDocument.js +61 -0
  195. package/dist/documents/capabilities.d.ts +17 -0
  196. package/dist/documents/capabilities.js +18 -0
  197. package/dist/documents/html/HtmlDocument.d.ts +15 -0
  198. package/dist/documents/html/HtmlDocument.js +584 -0
  199. package/dist/documents/html/HtmlDocumentLayout.d.ts +87 -0
  200. package/dist/documents/html/HtmlDocumentLayout.js +25 -0
  201. package/dist/documents/html/HtmlDocumentProps.d.ts +60 -0
  202. package/dist/documents/html/HtmlDocumentProps.js +1 -0
  203. package/dist/documents/html/HtmlDocumentSource.d.ts +34 -0
  204. package/dist/documents/html/HtmlDocumentSource.js +28 -0
  205. package/dist/documents/markdown/MarkdownSplitPane.d.ts +115 -0
  206. package/dist/documents/markdown/MarkdownSplitPane.js +352 -0
  207. package/dist/documents/mdx/MdxSplitPane.d.ts +32 -0
  208. package/dist/documents/mdx/MdxSplitPane.js +60 -0
  209. package/dist/documents/txt/LinkDialog.d.ts +8 -0
  210. package/dist/documents/txt/LinkDialog.js +34 -0
  211. package/dist/documents/txt/MarkdownSourceToolbar.d.ts +8 -0
  212. package/dist/documents/txt/MarkdownSourceToolbar.js +25 -0
  213. package/dist/documents/txt/SourceEditorToolbar.d.ts +12 -0
  214. package/dist/documents/txt/SourceEditorToolbar.js +4 -0
  215. package/dist/documents/txt/TxtEditor.d.ts +39 -0
  216. package/dist/documents/txt/TxtEditor.js +186 -0
  217. package/dist/documents/txt/sourceEditorTypes.d.ts +49 -0
  218. package/dist/documents/txt/sourceEditorTypes.js +1 -0
  219. package/dist/documents/txt/sourceExtensions.d.ts +38 -0
  220. package/dist/documents/txt/sourceExtensions.js +444 -0
  221. package/dist/documents/txt/sourceFormatting.d.ts +18 -0
  222. package/dist/documents/txt/sourceFormatting.js +183 -0
  223. package/dist/documents/txt/sourceTheme.d.ts +5 -0
  224. package/dist/documents/txt/sourceTheme.js +220 -0
  225. package/dist/documents/txt/useCodeMirrorSourceEditor.d.ts +69 -0
  226. package/dist/documents/txt/useCodeMirrorSourceEditor.js +546 -0
  227. package/dist/documents/txt/useSourceSearch.d.ts +39 -0
  228. package/dist/documents/txt/useSourceSearch.js +122 -0
  229. package/dist/documents/txt/useTextEditorCommands.d.ts +26 -0
  230. package/dist/documents/txt/useTextEditorCommands.js +151 -0
  231. package/dist/documents/web/LivePreviewPane.d.ts +11 -0
  232. package/dist/documents/web/LivePreviewPane.js +58 -0
  233. package/dist/env.d.ts +66 -0
  234. package/dist/index.d.ts +121 -0
  235. package/dist/index.js +123 -0
  236. package/dist/settings/AppearanceMenu.d.ts +9 -0
  237. package/dist/settings/AppearanceMenu.js +54 -0
  238. package/dist/settings/SettingsPanel.d.ts +7 -0
  239. package/dist/settings/SettingsPanel.js +104 -0
  240. package/dist/settings/publishedSections.d.ts +22 -0
  241. package/dist/settings/publishedSections.js +79 -0
  242. package/dist/settings/sections/AboutSection.d.ts +1 -0
  243. package/dist/settings/sections/AboutSection.js +13 -0
  244. package/dist/settings/sections/DiagnosticsSection.d.ts +1 -0
  245. package/dist/settings/sections/DiagnosticsSection.js +42 -0
  246. package/dist/settings/sections/PrivacySection.d.ts +3 -0
  247. package/dist/settings/sections/PrivacySection.js +51 -0
  248. package/dist/settings/sections/UpdateLicenseBlock.d.ts +10 -0
  249. package/dist/settings/sections/UpdateLicenseBlock.js +158 -0
  250. package/dist/state/explorer.d.ts +32 -0
  251. package/dist/state/explorer.js +111 -0
  252. package/dist/state/legal.d.ts +51 -0
  253. package/dist/state/legal.js +130 -0
  254. package/dist/state/library.d.ts +33 -0
  255. package/dist/state/library.js +110 -0
  256. package/dist/state/updateLicense.d.ts +31 -0
  257. package/dist/state/updateLicense.js +340 -0
  258. package/dist/styles/explorer.css +219 -0
  259. package/dist/styles/index.css +1477 -0
  260. package/dist/styles/tabs.css +467 -0
  261. package/dist/styles.css +6 -0
  262. package/package.json +88 -3
@@ -0,0 +1,169 @@
1
+ import { type Dispatch, type MutableRefObject, type SetStateAction } from "react";
2
+ import { type LoadedDocument, type ViewMeta, type ViewMode } from "@rightkit/document-core/documents/types";
3
+ import type { DocumentTabs } from "./useDocumentTabs.js";
4
+ import { type HtmlConfirmState, type HtmlConflictState } from "./useHtmlSession.js";
5
+ import { pickNextActive } from "./useDocumentWatcher.js";
6
+ export { pickNextActive };
7
+ interface ViewStateDeps {
8
+ setViews: Dispatch<SetStateAction<Record<string, ViewMode>>>;
9
+ viewsRef: MutableRefObject<Record<string, ViewMode>>;
10
+ viewMetaRef: MutableRefObject<Record<string, ViewMeta>>;
11
+ dropViewState: (path: string) => void;
12
+ }
13
+ interface LibraryDeps {
14
+ refreshLibrary: () => Promise<void>;
15
+ syncPinned: (path: string) => Promise<void>;
16
+ }
17
+ /**
18
+ * The document lifecycle orchestrator: composes useDocumentLoader (open/read), useDocumentSaver
19
+ * (save/save-as), and useDocumentWatcher (close/teardown/reopen + external-change reload) around the
20
+ * shared `tabs` state and view-state/library setters (passed in to avoid a hook-ordering cycle).
21
+ * Bodies are unchanged from when everything lived in one 862-line hook — this file now just wires the
22
+ * pieces together and owns the state/refs genuinely shared across all three (fingerprints, the
23
+ * open-docs/activation-order mirrors, and the dialog state the HTML session drives).
24
+ */
25
+ export declare function useDocuments(deps: {
26
+ tabs: DocumentTabs;
27
+ viewState: ViewStateDeps;
28
+ library: LibraryDeps;
29
+ blockDrafts?: import("@rightkit/document-core/app/blockDrafts").BlockDraftRegistry;
30
+ }): {
31
+ ensureHtmlPage: (entryPath: string, pagePath: string) => Promise<void>;
32
+ setHtmlPageEdited: (entryPath: string, pagePath: string, edited: string) => void;
33
+ setHtmlActive: (entryPath: string, pagePath: string) => void;
34
+ discardHtmlPage: (entryPath: string, pagePath: string) => void;
35
+ saveHtmlPage: (entryPath: string, pagePath: string, options?: {
36
+ silent?: boolean;
37
+ }) => Promise<boolean>;
38
+ saveAllHtmlPages: (entryPath: string, options?: {
39
+ silent?: boolean;
40
+ }) => Promise<boolean>;
41
+ discardAllHtmlPages: (entryPath: string) => void;
42
+ onHtmlSaveShortcut: (entryPath: string) => void;
43
+ htmlDirtyPages: (entryPath: string) => {
44
+ path: string;
45
+ name: string;
46
+ isEntry: boolean;
47
+ }[];
48
+ htmlSaveCurrent: () => Promise<void>;
49
+ htmlSaveAll: () => Promise<void>;
50
+ htmlDiscardAll: () => void;
51
+ htmlConfirmCancel: () => void;
52
+ htmlConflictReload: () => Promise<void>;
53
+ htmlConflictKeep: () => Promise<void>;
54
+ reloadHtmlSubpage: (path: string) => void;
55
+ blockDrafts: import("@rightkit/document-core/app/blockDrafts").BlockDraftRegistry;
56
+ activate: (path: string) => Promise<void>;
57
+ open: (path: string, opts?: import("./useDocumentLoader.js").OpenDocumentOptions) => Promise<void>;
58
+ openLiveUrl: (input: string, opts?: {
59
+ background?: boolean;
60
+ }) => Promise<void>;
61
+ openRecent: (entry: import("../index.js").FileEntry) => Promise<void>;
62
+ onOpenDialog: () => Promise<void>;
63
+ newDocument: (format?: "txt" | "md" | "docx") => void;
64
+ duplicateAsDraft: (text: string, toastMsg?: string) => void;
65
+ requestClose: (path: string) => void;
66
+ closeAll: () => void;
67
+ closeMany: (paths: string[]) => void;
68
+ reopenLastClosed: () => void;
69
+ openImageSibling: (currentPath: string, targetPath: string) => Promise<void>;
70
+ onTxtChange: (path: string, content: string, text: string) => void;
71
+ onSave: (doc: LoadedDocument, options?: {
72
+ silent?: boolean;
73
+ }) => Promise<string | null>;
74
+ onSaveAs: (doc: LoadedDocument) => Promise<string | null>;
75
+ onDocxSaveAs: (doc: LoadedDocument, buffer?: ArrayBuffer) => Promise<string | null>;
76
+ onPrint: (doc: LoadedDocument | null) => void;
77
+ onDocxSave: (path: string, buffer: ArrayBuffer) => Promise<void>;
78
+ onDocxChange: (path: string) => void;
79
+ onPdfDirtyChange: (path: string, dirty: boolean) => void;
80
+ docxSaver: import("react").RefObject<(() => Promise<ArrayBuffer | null>) | null>;
81
+ docxSaversRef: import("react").RefObject<Map<string, () => Promise<ArrayBuffer | null>>>;
82
+ pdfSaversRef: import("react").RefObject<Map<string, import("@rightkit/document-core/documents/pdf/pdfEditor").PdfSaveFunction>>;
83
+ pdfSavePlansRef: import("react").RefObject<Map<string, () => Promise<import("@rightkit/document-core/documents/pdf/pdfEditModel").PdfSavePlan>>>;
84
+ onImageChange: (path: string) => void;
85
+ imageSaver: import("react").RefObject<import("@rightkit/media-ui").ImageSaveFunction | null>;
86
+ imageSaversRef: import("react").RefObject<Map<string, import("@rightkit/media-ui").ImageSaveFunction>>;
87
+ onEditImageExternal: (doc: LoadedDocument | null) => void;
88
+ isDirty: (doc: LoadedDocument) => boolean;
89
+ hasModifiedDraft: (path: string) => boolean;
90
+ snapshotModified: (path?: string) => Readonly<{
91
+ identity: import("@rightkit/document-core/app/blockDrafts").BlockDraftIdentity;
92
+ blockKind: string;
93
+ originalRevision: string | number;
94
+ sourceRange?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSourceRange;
95
+ sourceChecksum?: string;
96
+ originalText: string;
97
+ currentText: string;
98
+ targetTag?: string;
99
+ selectionBookmark?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSelectionBookmark;
100
+ status: import("@rightkit/document-core/app/blockDrafts").BlockDraftStatus;
101
+ reason?: string;
102
+ error?: string;
103
+ }>[];
104
+ snapshotAll: (path?: string) => Readonly<{
105
+ identity: import("@rightkit/document-core/app/blockDrafts").BlockDraftIdentity;
106
+ blockKind: string;
107
+ originalRevision: string | number;
108
+ sourceRange?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSourceRange;
109
+ sourceChecksum?: string;
110
+ originalText: string;
111
+ currentText: string;
112
+ targetTag?: string;
113
+ selectionBookmark?: import("@rightkit/document-core/app/blockDrafts").BlockDraftSelectionBookmark;
114
+ status: import("@rightkit/document-core/app/blockDrafts").BlockDraftStatus;
115
+ reason?: string;
116
+ error?: string;
117
+ }>[];
118
+ pendingSavePaths: Set<string>;
119
+ titleFor: (doc: LoadedDocument) => string;
120
+ error: string | null;
121
+ openingPath: string | null;
122
+ restoringSession: boolean;
123
+ setError: Dispatch<SetStateAction<string | null>>;
124
+ confirmClose: string | null;
125
+ setConfirmClose: Dispatch<SetStateAction<string | null>>;
126
+ confirmCloseAll: {
127
+ orderedPaths: string[];
128
+ affectedPaths: string[];
129
+ } | null;
130
+ setConfirmCloseAll: Dispatch<SetStateAction<{
131
+ orderedPaths: string[];
132
+ affectedPaths: string[];
133
+ } | null>>;
134
+ confirmCloseAllSaveAll: () => Promise<void>;
135
+ confirmCloseAllDontSave: () => Promise<void>;
136
+ confirmCloseAllCancel: () => void;
137
+ confirmQuit: boolean;
138
+ setConfirmQuit: Dispatch<SetStateAction<boolean>>;
139
+ conflict: string | null;
140
+ setConflict: Dispatch<SetStateAction<string | null>>;
141
+ keepConflict: (path: string) => Promise<void>;
142
+ reload: (path: string, options?: {
143
+ force?: boolean;
144
+ replayDeferred?: boolean;
145
+ }) => void;
146
+ confirmSave: () => Promise<void>;
147
+ confirmDontSave: () => Promise<void>;
148
+ applyReload: (path: string) => void;
149
+ quitNow: () => Promise<void>;
150
+ quitSaveAll: () => Promise<void>;
151
+ quitDiscardAll: () => Promise<void>;
152
+ draftConfirm: {
153
+ documentPath: string;
154
+ intent: import("@rightkit/document-core/app/blockDrafts").BlockDraftIntent;
155
+ onResolved: () => void;
156
+ } | null;
157
+ setDraftConfirm: Dispatch<SetStateAction<{
158
+ documentPath: string;
159
+ intent: import("@rightkit/document-core/app/blockDrafts").BlockDraftIntent;
160
+ onResolved: () => void;
161
+ } | null>>;
162
+ confirmDraftDone: () => Promise<void>;
163
+ confirmDraftDiscard: () => Promise<void>;
164
+ confirmDraftCancel: () => void;
165
+ requestDraftAwareViewChange: (path: string, proceed: () => void) => void;
166
+ htmlConfirm: HtmlConfirmState;
167
+ htmlConflict: HtmlConflictState;
168
+ trackMdxGrant: (entryPath: string, grantedPath: string) => void;
169
+ };
@@ -0,0 +1,455 @@
1
+ import { useCallback, useEffect, useRef, useState, } from "react";
2
+ import { isUntitled, } from "@rightkit/document-core/documents/types";
3
+ import { isWebTabKey } from "@rightkit/document-core/documents/web/webUrl";
4
+ import { readDocument, revokePath, } from "@rightkit/document-core/state/tauriBridge";
5
+ import { clearFileDraft, flushDraft, } from "./documentDrafts.js";
6
+ import { errorMessage } from "@rightkit/document-core/state/errors";
7
+ import { useDocumentRuntimeEffects } from "./useDocumentRuntimeEffects.js";
8
+ import { useFormatDirtyState } from "./useFormatDirtyState.js";
9
+ import { useHtmlSession } from "./useHtmlSession.js";
10
+ import { useDocumentLoader } from "./useDocumentLoader.js";
11
+ import { useDocumentSaver } from "./useDocumentSaver.js";
12
+ import { useDocumentWatcher, pickNextActive } from "./useDocumentWatcher.js";
13
+ import { useSettings } from "@rightkit/document-core/settings/settings";
14
+ import { createBlockDraftRegistry } from "@rightkit/document-core/app/blockDrafts";
15
+ import { useAutoSave } from "./useAutoSave.js";
16
+ import { useCloseAll } from "./useCloseAll.js";
17
+ import { useDraftConfirmGate } from "./useDraftConfirmGate.js";
18
+ import { usePendingSavePaths } from "./usePendingSavePaths.js";
19
+ import { useSetupRecovery } from "./useSetupRecovery.js";
20
+ import { useDocumentDirty } from "./useDocumentDirty.js";
21
+ import { useDocumentCreation } from "./useDocumentCreation.js";
22
+ import { useDocumentOutputActions } from "./useDocumentOutputActions.js";
23
+ const EMPTY_PENDING_SAVE_PATHS = new Set();
24
+ // Re-exported so the existing unit test (useDocuments.pickNextActive.test.ts) keeps importing this
25
+ // module without a signature change; the implementation now lives in useDocumentWatcher.ts.
26
+ export { pickNextActive };
27
+ /**
28
+ * The document lifecycle orchestrator: composes useDocumentLoader (open/read), useDocumentSaver
29
+ * (save/save-as), and useDocumentWatcher (close/teardown/reopen + external-change reload) around the
30
+ * shared `tabs` state and view-state/library setters (passed in to avoid a hook-ordering cycle).
31
+ * Bodies are unchanged from when everything lived in one 862-line hook — this file now just wires the
32
+ * pieces together and owns the state/refs genuinely shared across all three (fingerprints, the
33
+ * open-docs/activation-order mirrors, and the dialog state the HTML session drives).
34
+ */
35
+ export function useDocuments(deps) {
36
+ const [internalDrafts] = useState(() => createBlockDraftRegistry());
37
+ const blockDrafts = deps.blockDrafts ?? internalDrafts;
38
+ const { settings } = useSettings();
39
+ const { openDocs, setOpenDocs, activePath, setActivePath, editsRef, writeEdits, writeEditsLive, docxDirtyRef, setDocxDirty, pdfDirtyRef, setPdfDirty, imageDirtyRef, setImageDirty, htmlPagesRef, writeHtmlPages, htmlActivePage, setHtmlActivePage, mdxGrantsRef, trackMdxGrant, } = deps.tabs;
40
+ const { setViews, viewsRef, viewMetaRef } = deps.viewState;
41
+ const { refreshLibrary, syncPinned } = deps.library;
42
+ const [error, setError] = useState(null);
43
+ const [openingPath, setOpeningPath] = useState(null);
44
+ // True while the launch effect's session restore is in flight (file-backed tabs loading,
45
+ // active tab being chosen). App.tsx renders a small "Restoring session…" indicator in the
46
+ // active-pane slot while true so the user sees feedback instead of a blank pane that reads
47
+ // as "the app isn't loaded". Starts false so the first render shows the EmptyState (or the
48
+ // active doc) — the launch effect flips it true on entry, false in `finally` on exit.
49
+ const [restoringSession, setRestoringSession] = useState(false);
50
+ const untitledSeq = useRef(1);
51
+ const hydrated = useRef(false); // becomes true once the launch restore has read the saved session
52
+ const [confirmClose, setConfirmClose] = useState(null);
53
+ const [conflict, setConflict] = useState(null); // file changed on disk while dirty
54
+ // HTML session dialogs: the page-aware close/save chooser, and a sub-page on-disk conflict. State
55
+ // lives here (not in useHtmlSession) because requestClose opens the chooser before that hook runs.
56
+ const [htmlConfirm, setHtmlConfirm] = useState(null);
57
+ const [htmlConflict, setHtmlConflict] = useState(null);
58
+ // Last-seen on-disk fingerprint per open file, captured at read/save time and compared on
59
+ // activation to catch background-tab edits the active-file-only watcher can't see.
60
+ const fingerprints = useRef(new Map());
61
+ const tabSeq = useRef(1);
62
+ const openDocsRef = useRef(openDocs);
63
+ const activePathRef = useRef(activePath);
64
+ // queueAutoSave must exist before useAutoSave's deps (docxSaver/onSave/htmlSession) do — stable
65
+ // forwarder into the scheduler slot useAutoSave populates each render.
66
+ const autoSaveSchedulerRef = useRef(() => { });
67
+ const queueAutoSave = useCallback((path) => autoSaveSchedulerRef.current(path), []);
68
+ useEffect(() => {
69
+ openDocsRef.current = openDocs;
70
+ }, [openDocs]);
71
+ activePathRef.current = activePath;
72
+ // MRU activation history (most-recent LAST). Closing the active tab focuses the most-recently-used
73
+ // still-open tab — VS Code's `focusRecentEditorAfterClose` default — not nothing. `doClose` falls
74
+ // back to the spatial neighbour if there's no usable history (shouldn't happen once a tab has ever
75
+ // been active). Stale entries are harmless: `pickNextActive` filters against the remaining set.
76
+ const activationOrderRef = useRef([]);
77
+ useEffect(() => {
78
+ if (!activePath)
79
+ return;
80
+ const order = activationOrderRef.current;
81
+ const at = order.indexOf(activePath);
82
+ if (at !== -1)
83
+ order.splice(at, 1);
84
+ order.push(activePath);
85
+ }, [activePath]);
86
+ const withTabKey = useCallback((doc, existingKey) => ({
87
+ ...doc,
88
+ tabKey: existingKey ?? doc.tabKey ?? `tab:${tabSeq.current++}`,
89
+ }), []);
90
+ const releaseReplacedBackingPath = useCallback((oldPath, newPath) => {
91
+ if (oldPath === newPath || isUntitled(oldPath) || isWebTabKey(oldPath))
92
+ return;
93
+ fingerprints.current.delete(oldPath);
94
+ clearFileDraft(oldPath);
95
+ void revokePath(oldPath);
96
+ }, []);
97
+ // markSelfSaved/refreshFingerprint are owned by useDocumentSaver, constructed below — but
98
+ // useFormatDirtyState (docx/image dirty-set + onDocxSave/writeImagePayload) needs them and must be
99
+ // constructed BEFORE useDocumentSaver (the saver takes writeImagePayload as a dep). Break the cycle
100
+ // with a stable ref indirection: the ref is populated once the saver exists, and these thin
101
+ // forwarding callbacks never change identity, so downstream memoization is unaffected.
102
+ const saverHandlesRef = useRef({
103
+ markSelfSaved: () => { },
104
+ refreshFingerprint: () => { },
105
+ });
106
+ const markSelfSavedForward = useCallback((path) => saverHandlesRef.current.markSelfSaved(path), []);
107
+ const refreshFingerprintForward = useCallback((path) => saverHandlesRef.current.refreshFingerprint(path), []);
108
+ const { docxSaver, imageSaver, docxSaversRef, pdfSaversRef, pdfSavePlansRef, imageSaversRef, onDocxSave: persistDocx, onDocxChange, onPdfDirtyChange, onImageChange, clearImageDirty, restoreImageDirty, writeImagePayload, } = useFormatDirtyState({
109
+ setError,
110
+ setDocxDirty,
111
+ setPdfDirty,
112
+ setImageDirty,
113
+ markSelfSaved: markSelfSavedForward,
114
+ refreshFingerprint: refreshFingerprintForward,
115
+ onDirty: queueAutoSave,
116
+ });
117
+ const { hasModifiedDraft, snapshotModified, isDirty, titleFor } = useDocumentDirty({
118
+ blockDrafts,
119
+ pdfDirtyRef,
120
+ docxDirtyRef,
121
+ imageDirtyRef,
122
+ editsRef,
123
+ htmlPagesRef,
124
+ });
125
+ // Setup-replacement recovery (snapshot before window destroy + rehydrate on next launch) —
126
+ // extracted to useSetupRecovery; the pure (de)serialization stays in setupRecovery.ts.
127
+ const { prepareSetupRecovery, restoreSetupRecovery } = useSetupRecovery({
128
+ blockDrafts,
129
+ setError,
130
+ openDocsRef,
131
+ activePathRef,
132
+ viewsRef,
133
+ isDirty,
134
+ editsRef,
135
+ htmlPagesRef,
136
+ docxSaversRef,
137
+ imageSaversRef,
138
+ setOpenDocs,
139
+ writeEdits,
140
+ writeHtmlPages,
141
+ setViews,
142
+ setDocxDirty,
143
+ restoreImageDirty,
144
+ fingerprints,
145
+ withTabKey,
146
+ });
147
+ const loader = useDocumentLoader({
148
+ openDocs,
149
+ setOpenDocs,
150
+ setViews,
151
+ viewsRef,
152
+ viewMetaRef,
153
+ writeEdits,
154
+ setError,
155
+ setOpeningPath,
156
+ setActivePath,
157
+ fingerprints,
158
+ refreshLibrary,
159
+ syncPinned,
160
+ isDirty,
161
+ clearImageDirty,
162
+ withTabKey,
163
+ });
164
+ const { activate, open, openLiveUrl, openRecent, onOpenDialog, openImageSibling } = loader;
165
+ const saver = useDocumentSaver({
166
+ editsRef,
167
+ writeEdits,
168
+ setDocxDirty,
169
+ setOpenDocs,
170
+ setActivePath,
171
+ setViews,
172
+ setError,
173
+ setConflict,
174
+ fingerprints,
175
+ refreshLibrary,
176
+ imageSaver,
177
+ imageSaversRef,
178
+ docxSaver,
179
+ docxSaversRef,
180
+ pdfSaversRef,
181
+ pdfSavePlansRef,
182
+ setPdfDirty,
183
+ pdfDirtyRef,
184
+ clearImageDirty,
185
+ writeImagePayload,
186
+ releaseReplacedBackingPath,
187
+ withTabKey,
188
+ blockDrafts,
189
+ });
190
+ const { onSave, onSaveAs, onDocxSaveAs, markSelfSaved, refreshFingerprint, selfSaved, pendingSavePaths: saverPendingSavePaths = EMPTY_PENDING_SAVE_PATHS, pendingSavePathsRef: saverPendingSavePathsRef, } = saver;
191
+ // In-flight save paths across all three save surfaces (saver's own set + tracked docx writes +
192
+ // per-page HTML session writes) — extracted to usePendingSavePaths.
193
+ const { onDocxSave, onHtmlSaveActivity, pendingSavePaths, pendingSavePathsRef: formatPendingSavePathsRef, } = usePendingSavePaths({
194
+ persistDocx,
195
+ saverPendingSavePaths,
196
+ });
197
+ saverHandlesRef.current.markSelfSaved = markSelfSaved;
198
+ saverHandlesRef.current.refreshFingerprint = refreshFingerprint;
199
+ // T2-1 data-loss guard, explicit save path: flush any pending debounced draft write for this doc
200
+ // before saving. Save itself reads the live editsRef (always current, unaffected by the draft
201
+ // debounce), so this isn't required for save correctness — it just guarantees the recovery draft
202
+ // in localStorage can't hold text older than what's about to hit disk if something inspects it
203
+ // mid-save. clearDraft/clearFileDraft (called after a successful save) already cancel the pending
204
+ // write outright, so this and that together fully close the window.
205
+ const onSaveFlushed = useCallback((doc, options) => {
206
+ flushDraft(doc.path);
207
+ return onSave(doc, options);
208
+ }, [onSave]);
209
+ const onSaveAsFlushed = useCallback((doc) => {
210
+ flushDraft(doc.path);
211
+ return onSaveAs(doc);
212
+ }, [onSaveAs]);
213
+ const { newDocument, duplicateAsDraft, onTxtChange } = useDocumentCreation({
214
+ untitledSeq,
215
+ withTabKey,
216
+ setOpenDocs,
217
+ setActivePath,
218
+ setViews,
219
+ writeEdits,
220
+ writeEditsLive,
221
+ queueAutoSave,
222
+ });
223
+ // doClose (from useDocumentWatcher, constructed below) and reloadHtmlSubpage (from useHtmlSession,
224
+ // constructed here) are mutually dependent, exactly as in the original single-hook version — broken
225
+ // with the same stable-ref-forwarding pattern used above.
226
+ const doCloseRef = useRef(() => { });
227
+ const doCloseForward = useCallback((path) => doCloseRef.current(path), []);
228
+ // ── HTML site sessions ──────────────────────────────────────────────────────────────────────
229
+ // The navigated SUB-page buffers, their save/discard/dirty model, the page-aware close chooser, the
230
+ // sub-page conflict flow, and sub-page reload reconciliation all live in useHtmlSession. The ENTRY
231
+ // page still uses the shared text path above (edits + onSave). Dialog state stays here (above) so
232
+ // requestClose can open the chooser before this hook is constructed.
233
+ const htmlSession = useHtmlSession({
234
+ openDocs,
235
+ editsRef,
236
+ writeEdits,
237
+ htmlPagesRef,
238
+ writeHtmlPages,
239
+ htmlActivePage,
240
+ setHtmlActivePage,
241
+ htmlConfirm,
242
+ setHtmlConfirm,
243
+ htmlConflict,
244
+ setHtmlConflict,
245
+ onSave,
246
+ doClose: doCloseForward,
247
+ markSelfSaved,
248
+ setError,
249
+ onDirty: queueAutoSave,
250
+ onSaveActivity: onHtmlSaveActivity,
251
+ blockDrafts,
252
+ });
253
+ const { reloadHtmlSubpage } = htmlSession;
254
+ // Idle-delay autosave for file-backed tabs + the T2-1 draft-flush guards on unload/hide —
255
+ // extracted to useAutoSave. `autoSaveSchedulerRef` stays here: `queueAutoSave` (above, consumed by
256
+ // useFormatDirtyState/useHtmlSession/onTxtChange) must exist before this hook's deps do.
257
+ useAutoSave({
258
+ autoSave: settings.autoSave,
259
+ openDocs,
260
+ openDocsRef,
261
+ activePath,
262
+ activePathRef,
263
+ isDirty,
264
+ docxSaver,
265
+ onDocxSave,
266
+ onSave,
267
+ saveAllHtmlPages: htmlSession.saveAllHtmlPages,
268
+ autoSaveSchedulerRef,
269
+ });
270
+ const watcher = useDocumentWatcher({
271
+ openDocs,
272
+ openDocsRef,
273
+ activationOrderRef,
274
+ setOpenDocs,
275
+ setActivePath,
276
+ activePath,
277
+ writeEdits,
278
+ setDocxDirty,
279
+ setPdfDirty,
280
+ htmlPagesRef,
281
+ writeHtmlPages,
282
+ setHtmlActivePage,
283
+ mdxGrantsRef,
284
+ clearImageDirty,
285
+ isDirty,
286
+ openLiveUrl,
287
+ activate,
288
+ open,
289
+ fingerprints,
290
+ selfSaved,
291
+ pendingSavePaths,
292
+ reloadHtmlSubpage,
293
+ setHtmlConfirm,
294
+ setConfirmClose,
295
+ confirmClose,
296
+ setConflict,
297
+ onSave,
298
+ onDocxSave,
299
+ docxSaver,
300
+ docxSaversRef,
301
+ onDocxSaveAs,
302
+ withTabKey,
303
+ blockDrafts,
304
+ dropViewState: deps.viewState.dropViewState,
305
+ synchronousPendingSavePathsRef: saverPendingSavePathsRef,
306
+ synchronousPendingSavePathsRefs: [saverPendingSavePathsRef, formatPendingSavePathsRef],
307
+ });
308
+ const { doClose, reopenLastClosed, requestClose, confirmSave, confirmDontSave, applyReload, reload, teardownDoc, } = watcher;
309
+ doCloseRef.current = doClose;
310
+ // Keeping local edits after an external change must refresh the backend's expected source hash.
311
+ // The next save then overwrites only the exact bytes just acknowledged, while the backend guard
312
+ // still catches a second external write that races that save.
313
+ const keepConflict = useCallback(async (path) => {
314
+ const doc = openDocs.find((candidate) => candidate.path === path);
315
+ if (doc && !["txt", "md", "mdx", "html"].includes(doc.format)) {
316
+ // Binary/PDF saves have no source hash guard; preserve their existing Keep behavior.
317
+ setConflict(null);
318
+ return;
319
+ }
320
+ try {
321
+ const loaded = await readDocument(path);
322
+ if (!loaded.sourceSha256) {
323
+ setError("Couldn't refresh file identity before overwrite.");
324
+ return;
325
+ }
326
+ if (loaded.fingerprint)
327
+ fingerprints.current.set(path, loaded.fingerprint);
328
+ setOpenDocs((prev) => prev.map((doc) => doc.path === path
329
+ ? {
330
+ ...doc,
331
+ sourceSha256: loaded.sourceSha256,
332
+ fingerprint: loaded.fingerprint ?? doc.fingerprint,
333
+ }
334
+ : doc));
335
+ setConflict(null);
336
+ }
337
+ catch (error) {
338
+ setError(errorMessage(error));
339
+ }
340
+ }, [openDocs, setOpenDocs]);
341
+ // Bulk Close All + the Save-All/Discard-All quit flow — extracted to useCloseAll. The hook also
342
+ // owns the confirmQuit/confirmCloseAll dialog state (only consumed after requestClose exists, so
343
+ // unlike the other dialog state it doesn't need to stay at the top of this hook).
344
+ const { confirmQuit, setConfirmQuit, confirmCloseAll, setConfirmCloseAll, closeAll, closeMany, confirmCloseAllSaveAll, confirmCloseAllDontSave, confirmCloseAllCancel, quitNow, quitSaveAll, quitDiscardAll, } = useCloseAll({
345
+ openDocsRef,
346
+ isDirty,
347
+ setOpenDocs,
348
+ setActivePath,
349
+ teardownDoc,
350
+ blockDrafts,
351
+ htmlSession,
352
+ onSaveFlushed,
353
+ docxSaver,
354
+ docxSaversRef,
355
+ onDocxSave,
356
+ onDocxSaveAs,
357
+ });
358
+ const { onEditImageExternal, onPrint } = useDocumentOutputActions(setError);
359
+ useDocumentRuntimeEffects({
360
+ openDocs,
361
+ activePath,
362
+ hydrated,
363
+ untitledSeq,
364
+ refreshLibrary,
365
+ setOpenDocs,
366
+ writeEdits,
367
+ setViews,
368
+ activate,
369
+ open,
370
+ reload,
371
+ isDirty,
372
+ setConfirmQuit,
373
+ prepareSetupRecovery,
374
+ restoreSetupRecovery,
375
+ restoreSession: settings.restoreSession,
376
+ setRestoringSession,
377
+ blockDrafts,
378
+ });
379
+ // Draft-confirm dialog (view changes with a modified draft): Done commits, Discard drops,
380
+ // Cancel stays on the current view with the editor open — extracted to useDraftConfirmGate.
381
+ const { draftConfirm, setDraftConfirm, confirmDraftDone, confirmDraftDiscard, confirmDraftCancel, requestDraftAwareViewChange, } = useDraftConfirmGate({ blockDrafts });
382
+ return {
383
+ blockDrafts,
384
+ activate,
385
+ open,
386
+ openLiveUrl,
387
+ openRecent,
388
+ onOpenDialog,
389
+ newDocument,
390
+ duplicateAsDraft,
391
+ requestClose,
392
+ closeAll,
393
+ closeMany,
394
+ reopenLastClosed,
395
+ openImageSibling,
396
+ onTxtChange,
397
+ onSave: onSaveFlushed,
398
+ onSaveAs: onSaveAsFlushed,
399
+ onDocxSaveAs,
400
+ onPrint,
401
+ onDocxSave,
402
+ onDocxChange,
403
+ onPdfDirtyChange,
404
+ docxSaver,
405
+ docxSaversRef,
406
+ pdfSaversRef,
407
+ pdfSavePlansRef,
408
+ onImageChange,
409
+ imageSaver,
410
+ imageSaversRef,
411
+ onEditImageExternal,
412
+ isDirty,
413
+ hasModifiedDraft,
414
+ snapshotModified,
415
+ snapshotAll: (path) => blockDrafts.snapshotAll(path),
416
+ pendingSavePaths,
417
+ titleFor,
418
+ error,
419
+ openingPath,
420
+ restoringSession,
421
+ setError,
422
+ confirmClose,
423
+ setConfirmClose,
424
+ confirmCloseAll,
425
+ setConfirmCloseAll,
426
+ confirmCloseAllSaveAll,
427
+ confirmCloseAllDontSave,
428
+ confirmCloseAllCancel,
429
+ confirmQuit,
430
+ setConfirmQuit,
431
+ conflict,
432
+ setConflict,
433
+ keepConflict,
434
+ reload,
435
+ confirmSave,
436
+ confirmDontSave,
437
+ applyReload,
438
+ quitNow,
439
+ quitSaveAll,
440
+ quitDiscardAll,
441
+ draftConfirm,
442
+ setDraftConfirm,
443
+ confirmDraftDone,
444
+ confirmDraftDiscard,
445
+ confirmDraftCancel,
446
+ requestDraftAwareViewChange,
447
+ // HTML site sessions — dialog state owned here; behavior from useHtmlSession.
448
+ htmlConfirm,
449
+ htmlConflict,
450
+ ...htmlSession,
451
+ // MDX component-import grant tracking — reported by the resolver/preview frame, revoked in
452
+ // teardownDoc above.
453
+ trackMdxGrant,
454
+ };
455
+ }
@@ -0,0 +1,27 @@
1
+ import type { BlockDraftIntent, BlockDraftRegistry } from "@rightkit/document-core/app/blockDrafts";
2
+ interface DraftConfirmGateDeps {
3
+ blockDrafts: BlockDraftRegistry;
4
+ }
5
+ /**
6
+ * The draft-confirm chooser state + its gate. `requestDraftAwareViewChange` wraps a view change so
7
+ * a modified block draft first opens the Done/Discard/Cancel chooser (Done commits, Discard drops,
8
+ * Cancel stays on the current view with the editor open); a draft-free document proceeds
9
+ * immediately. Extracted verbatim from useDocuments; bodies are unchanged.
10
+ */
11
+ export declare function useDraftConfirmGate({ blockDrafts }: DraftConfirmGateDeps): {
12
+ draftConfirm: {
13
+ documentPath: string;
14
+ intent: BlockDraftIntent;
15
+ onResolved: () => void;
16
+ } | null;
17
+ setDraftConfirm: import("react").Dispatch<import("react").SetStateAction<{
18
+ documentPath: string;
19
+ intent: BlockDraftIntent;
20
+ onResolved: () => void;
21
+ } | null>>;
22
+ confirmDraftDone: () => Promise<void>;
23
+ confirmDraftDiscard: () => Promise<void>;
24
+ confirmDraftCancel: () => void;
25
+ requestDraftAwareViewChange: (path: string, proceed: () => void) => void;
26
+ };
27
+ export {};