@rightkit/document-core 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +31 -7
  3. package/dist/app/chrome.js +1 -1
  4. package/dist/app/documentPrinting.d.ts +0 -6
  5. package/dist/app/documentPrinting.js +0 -18
  6. package/dist/app/shell/nativeMenu.d.ts +3 -2
  7. package/dist/app/shell/nativeMenu.js +8 -5
  8. package/dist/documents/perfEventCounters.d.ts +0 -8
  9. package/dist/documents/perfEventCounters.js +2 -1
  10. package/dist/documents/preview/previewFrame.d.ts +2 -1
  11. package/dist/documents/preview/previewFrame.js +9 -7
  12. package/dist/documents/searchUtils.js +1 -1
  13. package/dist/host.d.ts +36 -0
  14. package/dist/host.js +54 -0
  15. package/dist/index.d.ts +1 -46
  16. package/dist/index.js +1 -46
  17. package/dist/settings/themes.js +1 -1
  18. package/dist/state/bridgeEvents.d.ts +1 -1
  19. package/dist/state/bridgeEvents.js +7 -4
  20. package/dist/state/recentUrls.js +4 -3
  21. package/dist/state/tauriBridge.d.ts +3 -47
  22. package/dist/state/tauriBridge.js +6 -162
  23. package/dist/styles.css +2 -2
  24. package/package.json +16 -87
  25. package/dist/app/shortcutChords.d.ts +0 -6
  26. package/dist/app/shortcutChords.js +0 -14
  27. package/dist/app/useCloseFindOnSurfaceChange.d.ts +0 -14
  28. package/dist/app/useCloseFindOnSurfaceChange.js +0 -23
  29. package/dist/app/useEditText.d.ts +0 -6
  30. package/dist/app/useEditText.js +0 -10
  31. package/dist/appName.d.ts +0 -2
  32. package/dist/appName.js +0 -8
  33. package/dist/documents/FullscreenIcon.d.ts +0 -4
  34. package/dist/documents/FullscreenIcon.js +0 -7
  35. package/dist/documents/mdx/mdxRuntimeScript.d.ts +0 -2
  36. package/dist/documents/mdx/mdxRuntimeScript.js +0 -3
  37. package/dist/documents/mdx/mdxRuntimeScript.txt +0 -584
  38. package/dist/documents/pdf/MacPdfReadPane.d.ts +0 -23
  39. package/dist/documents/pdf/MacPdfReadPane.js +0 -708
  40. package/dist/documents/pdf/NativePdfDocument.d.ts +0 -9
  41. package/dist/documents/pdf/NativePdfDocument.js +0 -41
  42. package/dist/documents/pdf/PdfInlineTextEditor.d.ts +0 -53
  43. package/dist/documents/pdf/PdfInlineTextEditor.js +0 -225
  44. package/dist/documents/pdf/PdfOcrLayer.d.ts +0 -4
  45. package/dist/documents/pdf/PdfOcrLayer.js +0 -30
  46. package/dist/documents/pdf/PdfOutline.d.ts +0 -6
  47. package/dist/documents/pdf/PdfOutline.js +0 -12
  48. package/dist/documents/pdf/PdfPasswordPrompt.d.ts +0 -5
  49. package/dist/documents/pdf/PdfPasswordPrompt.js +0 -24
  50. package/dist/documents/pdf/PdfThumbnails.d.ts +0 -8
  51. package/dist/documents/pdf/PdfThumbnails.js +0 -201
  52. package/dist/documents/pdf/PdfToolbar.d.ts +0 -47
  53. package/dist/documents/pdf/PdfToolbar.js +0 -76
  54. package/dist/documents/pdf/PdfViewer.d.ts +0 -36
  55. package/dist/documents/pdf/PdfViewer.js +0 -1522
  56. package/dist/documents/pdf/PdfViewerBody.d.ts +0 -22
  57. package/dist/documents/pdf/PdfViewerBody.js +0 -42
  58. package/dist/documents/pdf/macPdfNativeBridge.d.ts +0 -118
  59. package/dist/documents/pdf/macPdfNativeBridge.js +0 -134
  60. package/dist/documents/pdf/nearestVisiblePdfPage.d.ts +0 -2
  61. package/dist/documents/pdf/nearestVisiblePdfPage.js +0 -22
  62. package/dist/documents/pdf/pdfBench.d.ts +0 -88
  63. package/dist/documents/pdf/pdfBench.js +0 -535
  64. package/dist/documents/pdf/pdfBenchAutopilot.d.ts +0 -48
  65. package/dist/documents/pdf/pdfBenchAutopilot.js +0 -154
  66. package/dist/documents/pdf/pdfBenchTransport.d.ts +0 -21
  67. package/dist/documents/pdf/pdfBenchTransport.js +0 -233
  68. package/dist/documents/pdf/pdfEditModel.d.ts +0 -294
  69. package/dist/documents/pdf/pdfEditModel.js +0 -105
  70. package/dist/documents/pdf/pdfEditor.d.ts +0 -100
  71. package/dist/documents/pdf/pdfEditor.js +0 -68
  72. package/dist/documents/pdf/pdfOcr.d.ts +0 -36
  73. package/dist/documents/pdf/pdfOcr.js +0 -88
  74. package/dist/documents/pdf/pdfOcrEdit.d.ts +0 -32
  75. package/dist/documents/pdf/pdfOcrEdit.js +0 -138
  76. package/dist/documents/pdf/pdfPrinting.d.ts +0 -28
  77. package/dist/documents/pdf/pdfPrinting.js +0 -110
  78. package/dist/documents/pdf/pdfSave.d.ts +0 -87
  79. package/dist/documents/pdf/pdfSave.js +0 -250
  80. package/dist/documents/pdf/pdfShared.d.ts +0 -16
  81. package/dist/documents/pdf/pdfShared.js +0 -20
  82. package/dist/documents/pdf/pdfToMarkdown.d.ts +0 -11
  83. package/dist/documents/pdf/pdfToMarkdown.js +0 -67
  84. package/dist/documents/pdf/pdfjsLibGlobal.d.ts +0 -1
  85. package/dist/documents/pdf/pdfjsLibGlobal.js +0 -12
  86. package/dist/documents/pdf/toolbarIcons.d.ts +0 -18
  87. package/dist/documents/pdf/toolbarIcons.js +0 -31
  88. package/dist/documents/pdf/usePdfDocumentLoader.d.ts +0 -40
  89. package/dist/documents/pdf/usePdfDocumentLoader.js +0 -243
  90. package/dist/documents/pdf/usePdfEditSession.d.ts +0 -88
  91. package/dist/documents/pdf/usePdfEditSession.js +0 -341
  92. package/dist/documents/pdf/usePdfEditor.d.ts +0 -59
  93. package/dist/documents/pdf/usePdfEditor.js +0 -317
  94. package/dist/documents/pdf/usePdfFit.d.ts +0 -19
  95. package/dist/documents/pdf/usePdfFit.js +0 -55
  96. package/dist/documents/pdf/usePdfOcr.d.ts +0 -38
  97. package/dist/documents/pdf/usePdfOcr.js +0 -337
  98. package/dist/documents/pdf/usePdfPreviewRecompose.d.ts +0 -28
  99. package/dist/documents/pdf/usePdfPreviewRecompose.js +0 -256
  100. package/dist/documents/pdf/usePdfSavePlan.d.ts +0 -61
  101. package/dist/documents/pdf/usePdfSavePlan.js +0 -287
  102. package/dist/documents/pdf/usePdfSearch.d.ts +0 -31
  103. package/dist/documents/pdf/usePdfSearch.js +0 -367
  104. package/dist/documents/pdf/usePdfViewControls.d.ts +0 -72
  105. package/dist/documents/pdf/usePdfViewControls.js +0 -152
  106. package/dist/documents/scopedSelectAll.d.ts +0 -5
  107. package/dist/documents/scopedSelectAll.js +0 -77
  108. package/dist/documents/txt/cmScroll.d.ts +0 -11
  109. package/dist/documents/txt/cmScroll.js +0 -52
  110. package/dist/documents/useMirroredEditText.d.ts +0 -15
  111. package/dist/documents/useMirroredEditText.js +0 -29
  112. package/dist/documents/useSplitResize.d.ts +0 -7
  113. package/dist/documents/useSplitResize.js +0 -37
  114. package/dist/settings/rk-settings.css +0 -38
  115. package/dist/settings/sections/EditorSection.d.ts +0 -1
  116. package/dist/settings/sections/EditorSection.js +0 -18
  117. package/dist/settings/sections/FileAssociationsSection.d.ts +0 -1
  118. package/dist/settings/sections/FileAssociationsSection.js +0 -5
  119. package/dist/settings/sections/MacFileAssociationsBlock.d.ts +0 -33
  120. package/dist/settings/sections/MacFileAssociationsBlock.js +0 -151
  121. package/dist/settings/sections/ThemeSection.d.ts +0 -1
  122. package/dist/settings/sections/ThemeSection.js +0 -31
  123. package/dist/settings/sections/TypographySection.d.ts +0 -1
  124. package/dist/settings/sections/TypographySection.js +0 -19
  125. package/dist/settings/sections/onOff.d.ts +0 -11
  126. package/dist/settings/sections/onOff.js +0 -8
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0 (unpublished)
4
+
5
+ Shape review 2026-11-11 (`docs/audits/2026-11-11-shape-matrix/reports/family-documents.md`; design in `reports/documents-redraw-design.md`). Taken on the recommended option, pending the owner's confirmation.
6
+
7
+ The review judged this package the wrong shape: a catch-all holding ViewRight's whole PDF editor, its settings sections and workspace-only hooks beside the editor base, with five separate product-name stores across the document packages and names fixed to one app's prefix. It is dissolved as a catch-all: every part with an owner moved to it. What stays is the editor base that `@rightkit/html-editor`, `@rightkit/markdown-editor`, `@rightkit/docx-editor` and `@rightkit/document-workspace` all import; it cannot live in the workspace (the workspace imports the editors, so the editors importing the workspace would be a cycle), so it is not a re-export shim.
8
+
9
+ Moved out (breaking: the subpaths are gone from this package):
10
+ - To `@rightkit/document-workspace`: the PDF editor, `documents/pdf/*` (viewer, toolbar, thumbnails, outline, OCR, inline text editing, save plan, macOS native read pane, benchmark harness); the PDF-editor native commands of `state/tauriBridge` (`ocrPage`, `ocrAvailable`, `ocrBackendMissing`, `inspectPdfPage`, `listPdfFonts`, `composePdfPreview`, `preparePdfSave`, `commitPdfSave`, now `documents/pdf/pdfBridge`); `printPdf` and `printPdfDocument` of `app/documentPrinting` (now `documents/pdf/pdfPrinting`); `settings/sections/*` and `settings/rk-settings.css`; `app/useCloseFindOnSurfaceChange`, `app/useEditText`, `documents/FullscreenIcon`, `documents/txt/cmScroll`, `documents/useMirroredEditText`, `documents/useSplitResize`.
11
+ - To `@rightkit/html-editor`: `app/shortcutChords`.
12
+ - To `@rightkit/markdown-editor`: `documents/scopedSelectAll`, `documents/mdx/mdxRuntimeScript` (and its `.txt`).
13
+ - `styles.css` no longer imports pdf.js's `pdf_viewer.css` (the workspace's does). Dependencies `pdfjs-dist` and `@codemirror/view` removed.
14
+
15
+ Added:
16
+ - `host` (also on the root): `configureDocumentHost({ appName?, id? })`, the one host-identity store for every document package, read at use time. `hostAppName`, `setHostAppName` (now a shorthand), `hostId`, `documentEvent(name)` = `<id>:<name>`, `hostScheme(suffix)` = `<id>-<suffix>`, `hostHeader(suffix)` = `x-<id>-<suffix>`, `hostStorageKey(key)` = `<id>:<key>`, `hostQaGlobal(name)` = `__<camelId><Name>`. Default `id` is `"rk-document"`; a host whose native side uses `viewright:*` events and `viewright-*` schemes passes `id: "viewright"` and every name is as before.
17
+ - `state/tauriBridge` exports `byteArrayToBase64` (used by the PDF bridge).
18
+
19
+ Changed (breaking):
20
+ - `appName` module removed; import `hostAppName`/`setHostAppName` from the root or `host`.
21
+ - Names shared with the host's native side now come from `id`: the stream scheme (`<id>-stream`, was `viewright-stream`), the `write_document_base64` path header (`x-<id>-path-hex`), the native menu event (`menuCommandEvent()` replaces the constant `MENU_COMMAND_EVENT`), the Markdown format event (`markdownFormatEvent()` replaces `MARKDOWN_FORMAT_EVENT`), the Tauri events `<id>:open-url` (`onAppEvent("open-url")`, was `onAppEvent("viewright:open-url")`) and `<id>:context-*`, the preview scheme (`previewScheme()` replaces the constant `PREVIEW_SCHEME`), the recent-URL storage key `<id>:recent-urls` and the QA global `__<camelId>QaPerf`.
22
+ - The find-highlight style element id is `rk-document-search-highlight-styles` (was `viewright-search-highlight-styles`).
23
+
24
+ Not changed here, recorded for a later step: the theme ids `viewright-paper` and `viewright-night` and the settings key `vr.settings.v1` are stored user data, so renaming them needs a migration; the bridge still calls fixed native command names (the paired Rust command set in `rightkit-document-workspace` is the report's step 3).
25
+
3
26
  ## 0.1.2 (unpublished)
4
27
 
5
28
  - Removed (breaking, Adrian, 2026-11-03: "no dummy data, no fucking made up shit. real data."): the browser-QA fixture layer. `BROWSER_QA_BUILD`, `isBrowserQaMode()`, `qaReloadPdfBytes()`, every fixture branch of `state/tauriBridge` and the `state/browserQa`, `browserQaText`, `browserQaDocx` and `browserQaPdf` modules (and their `index` exports) are gone. Outside the Tauri webview the bridge keeps its plain no-op returns.
package/README.md CHANGED
@@ -1,11 +1,11 @@
1
1
  # @rightkit/document-core
2
2
 
3
- Shared base for the document editors: platform bridge, settings, state, PDF helpers and the format registry.
3
+ Shared base for the document editors and the document workspace: document types and the format registry, the host bridge, drafts, diagnostics, settings store, find, print and toolbar primitives, and the one host-identity store.
4
4
 
5
5
  | Item | Value |
6
6
  |---|---|
7
7
  | Where it runs | App webview UI (React) |
8
- | Version | 0.1.0 |
8
+ | Version | 0.2.0 |
9
9
  | License | MIT OR Apache-2.0 |
10
10
 
11
11
  ## Entry points
@@ -20,11 +20,35 @@ Shared base for the document editors: platform bridge, settings, state, PDF help
20
20
 
21
21
  `react`, `react-dom`
22
22
 
23
- ## Product name
23
+ ## Host identity
24
24
 
25
- User-facing copy reads the product name from `hostAppName()` (default `"App"`). Call
26
- `setHostAppName("Your App")` (exported from the root and from `appName`) once at startup, before
27
- rendering.
25
+ One store for every document package (`@rightkit/document-core/host`, also on the root). Call it once
26
+ at startup, before rendering; values are read where they are used, never at module load:
27
+
28
+ ```ts
29
+ configureDocumentHost({ appName: "Your App", id: "yourapp" });
30
+ ```
31
+
32
+ - `appName` (default `"App"`): product name in user-facing copy. `hostAppName()` reads it;
33
+ `setHostAppName(name)` is the same as passing only `appName`. The editors' and the workspace's
34
+ `appName` modules re-export this store.
35
+ - `id` (default `"rk-document"`): the prefix of every name shared with the host's native side or
36
+ between the document packages: events `<id>:<name>` (`documentEvent`), schemes `<id>-stream`,
37
+ `<id>-site`, `<id>-preview` (`hostScheme`), the raw-body path header `x-<id>-path-hex`
38
+ (`hostHeader`), storage keys `<id>:<key>` (`hostStorageKey`) and QA globals `__<camelId><Name>`
39
+ (`hostQaGlobal`). A host whose native side already uses its own prefix passes it here.
40
+
41
+ Not host-derived (fixed, with a later neutral rename recorded in the CHANGELOG): the theme ids
42
+ `viewright-paper` and `viewright-night` (stored in user settings) and the settings document key
43
+ `vr.settings.v1`.
44
+
45
+ ## What moved out in 0.2.0
46
+
47
+ The PDF editor (`documents/pdf/*`, its native commands from `state/tauriBridge` and the PDF print
48
+ path), the settings sections and their stylesheet, and the hooks only the workspace used moved to
49
+ `@rightkit/document-workspace`; `app/shortcutChords` moved to `@rightkit/html-editor`;
50
+ `documents/scopedSelectAll` and `documents/mdx/mdxRuntimeScript` moved to `@rightkit/markdown-editor`.
51
+ See the CHANGELOG for the full list.
28
52
 
29
53
  ## Host contract
30
54
 
@@ -38,4 +62,4 @@ pnpm --dir packages/document-core test
38
62
  ```
39
63
 
40
64
  Modules left out of the root barrel because an export name collides with an earlier module
41
- (import them by subpath): `documents/pdf/macPdfNativeBridge.ts`, `documents/pdf/pdfPrinting.ts`, `documents/previewViewport.tsx`, `state/tauriBridge.ts`
65
+ (import them by subpath): `documents/previewViewport.tsx`, `state/tauriBridge.ts`
@@ -9,7 +9,7 @@ function looksLikeLocalPath(input) {
9
9
  /^\/[^/]/.test(input));
10
10
  }
11
11
  import { ActionDialog, Button, IconButton, Input } from "@rightkit/react-shell/react";
12
- import { hostAppName } from "../appName.js";
12
+ import { hostAppName } from "../host.js";
13
13
  // Presentational shell chrome for App: confirmation dialogs and the Open-URL dialog. Pure leaf
14
14
  // components — no app state, no file semantics. Extracted from App.tsx so the shell composition
15
15
  // stays readable. (The Start page moved to src/app/shell/StartPage.tsx in Wave 3.)
@@ -16,12 +16,6 @@ export declare function printDocumentContent(input: PrintDocumentInput): Promise
16
16
  * document lets those selectors restyle the app behind macOS's print sheet. A shadow root keeps
17
17
  * both the document's authored CSS and print color settings inside this print-only subtree. */
18
18
  export declare function printIsolatedHtmlMarkup(markup: string): Promise<boolean>;
19
- /** Print the PDF a viewer pane already has open, WITHOUT re-fetching it. See
20
- * src/documents/pdf/pdfPrinting.ts. */
21
- export declare function printPdfDocument(doc: Parameters<typeof import("../documents/pdf/pdfPrinting.js").printPdfDocument>[0]): Promise<boolean>;
22
- /** Fallback PDF print path for when no viewer pane is registered: fetch the bytes from the stream URL
23
- * and rasterize them. See src/documents/pdf/pdfPrinting.ts. */
24
- export declare function printPdf(assetUrl: string): Promise<boolean>;
25
19
  /** Print a fully-baked image data: URI (crop/filters/text layers already rendered to a single canvas
26
20
  * by exportNativeImageEdit — the same pipeline Save/Save As uses). Deliberately NOT the on-screen
27
21
  * stage: that `<img>` loads through Tauri's custom asset:// scheme, which the native print
@@ -159,24 +159,6 @@ export async function printIsolatedHtmlMarkup(markup) {
159
159
  ${markup}`;
160
160
  });
161
161
  }
162
- /** Lazy bridge to the PDF print path. The pdf.js-dependent rasterizer lives in
163
- * src/documents/pdf/pdfPrinting.ts so the shell's entry chunk never pays for it; this module keeps
164
- * only the non-PDF printing helpers. The dynamic import resolves the SAME module the on-screen PDF
165
- * viewer already loaded (it shares the one worker-src setup), so the worker URL is never resolved
166
- * through a fresh chunk. See pdfPrinting.ts for the silent-hang trap this shape exists to avoid. */
167
- async function lazyPdfPrinting() {
168
- return import("../documents/pdf/pdfPrinting.js");
169
- }
170
- /** Print the PDF a viewer pane already has open, WITHOUT re-fetching it. See
171
- * src/documents/pdf/pdfPrinting.ts. */
172
- export async function printPdfDocument(doc) {
173
- return lazyPdfPrinting().then((m) => m.printPdfDocument(doc));
174
- }
175
- /** Fallback PDF print path for when no viewer pane is registered: fetch the bytes from the stream URL
176
- * and rasterize them. See src/documents/pdf/pdfPrinting.ts. */
177
- export async function printPdf(assetUrl) {
178
- return lazyPdfPrinting().then((m) => m.printPdf(assetUrl));
179
- }
180
162
  /** Print a fully-baked image data: URI (crop/filters/text layers already rendered to a single canvas
181
163
  * by exportNativeImageEdit — the same pipeline Save/Save As uses). Deliberately NOT the on-screen
182
164
  * stage: that `<img>` loads through Tauri's custom asset:// scheme, which the native print
@@ -3,10 +3,11 @@ export interface NativeMenuCommand {
3
3
  run: () => void;
4
4
  checked?: boolean;
5
5
  }
6
- export declare const MENU_COMMAND_EVENT = "viewright:menu-command";
6
+ /** Window event the native menu fires with the command id: `<host id>:menu-command`. */
7
+ export declare const menuCommandEvent: () => string;
7
8
  /** Menu-bar formatting commands for the active Markdown editor (event detail = command id).
8
9
  * Lives here (not in documents/markdown/) because the dispatcher is format-agnostic app chrome —
9
10
  * keeping it in the markdown tree would pull a markdown module into every format's closure. */
10
- export declare const MARKDOWN_FORMAT_EVENT = "viewright:markdown-format";
11
+ export declare const markdownFormatEvent: () => string;
11
12
  export declare function nativeMenuActive(): boolean;
12
13
  export declare function useNativeDocumentMenu(commands: NativeMenuCommand[] | null): void;
@@ -1,16 +1,18 @@
1
1
  // macOS native menu bridge. The document's File/View/Format/Insert commands live in the system
2
2
  // menu bar on Mac instead of in-window menus. Rust builds the menu once (every item disabled);
3
3
  // this hook tells it which `vr-cmd:` items apply to the active document (and which are checked),
4
- // and runs the matching command when the menu fires `viewright:menu-command`.
4
+ // and runs the matching command when the menu fires `<host id>:menu-command` (`documentEvent`).
5
5
  import { invoke } from "@tauri-apps/api/core";
6
6
  import { useEffect, useRef } from "react";
7
7
  import { isMac } from "../../platform.js";
8
8
  import { inTauri } from "../../state/tauriBridge.js";
9
- export const MENU_COMMAND_EVENT = "viewright:menu-command";
9
+ import { documentEvent } from "../../host.js";
10
+ /** Window event the native menu fires with the command id: `<host id>:menu-command`. */
11
+ export const menuCommandEvent = () => documentEvent("menu-command");
10
12
  /** Menu-bar formatting commands for the active Markdown editor (event detail = command id).
11
13
  * Lives here (not in documents/markdown/) because the dispatcher is format-agnostic app chrome —
12
14
  * keeping it in the markdown tree would pull a markdown module into every format's closure. */
13
- export const MARKDOWN_FORMAT_EVENT = "viewright:markdown-format";
15
+ export const markdownFormatEvent = () => documentEvent("markdown-format");
14
16
  export function nativeMenuActive() {
15
17
  return isMac() && inTauri();
16
18
  }
@@ -24,8 +26,9 @@ export function useNativeDocumentMenu(commands) {
24
26
  const id = event.detail;
25
27
  latest.current?.find((command) => command.id === id)?.run();
26
28
  };
27
- window.addEventListener(MENU_COMMAND_EVENT, onCommand);
28
- return () => window.removeEventListener(MENU_COMMAND_EVENT, onCommand);
29
+ const name = menuCommandEvent();
30
+ window.addEventListener(name, onCommand);
31
+ return () => window.removeEventListener(name, onCommand);
29
32
  }, [commands]);
30
33
  const enabled = commands?.map((command) => command.id) ?? [];
31
34
  const checked = commands?.filter((command) => command.checked).map((command) => command.id) ?? [];
@@ -44,13 +44,5 @@ export interface PerfQaFamily {
44
44
  read(): unknown;
45
45
  reset(): void;
46
46
  }
47
- declare global {
48
- interface Window {
49
- __viewrightQaPerf?: {
50
- read(): Record<string, unknown>;
51
- reset(): void;
52
- };
53
- }
54
- }
55
47
  /** Adds a named counter family (for example the Markdown resource lifecycle) to the QA readout. */
56
48
  export declare function exposePerfFamilyForQa(name: string, family: PerfQaFamily): void;
@@ -14,6 +14,7 @@
14
14
  * Cancel. Cache misses increment parse/projection counters;
15
15
  * cache hits are free.
16
16
  */
17
+ import { hostQaGlobal } from "../host.js";
17
18
  const counters = {
18
19
  sourceWrites: 0,
19
20
  parseCount: 0,
@@ -64,7 +65,7 @@ function qaReadoutEnabled() {
64
65
  function installQaReadout() {
65
66
  if (!qaReadoutEnabled())
66
67
  return;
67
- window.__viewrightQaPerf = {
68
+ window[hostQaGlobal("QaPerf")] = {
68
69
  read: () => ({
69
70
  perf: getPerfCounters(),
70
71
  ...Object.fromEntries([...qaFamilies].map(([name, family]) => [name, family.read()])),
@@ -1,6 +1,7 @@
1
1
  import { type PreviewHandle } from "@rightkit/tauri-shell";
2
2
  export type PreviewKind = "mdx" | "interactive";
3
- export declare const PREVIEW_SCHEME = "viewright-preview";
3
+ /** The host's preview scheme, `<host id>-preview` (`hostScheme`). */
4
+ export declare const previewScheme: () => string;
4
5
  export { isTauri as inTauriWebview } from "@rightkit/platform-ui";
5
6
  export declare function registerPreview(kind: PreviewKind, html: string): Promise<PreviewHandle>;
6
7
  export declare function revokePreview(token: string): Promise<void>;
@@ -1,15 +1,17 @@
1
- // Frame-source construction for documents served from the `viewright-preview` custom protocol
2
- // (the shell's preview store, configured in src-tauri/src/preview_protocol.rs). The protocol is
1
+ // Frame-source construction for documents served from the host's `<host id>-preview` custom
2
+ // protocol (the shell's preview store). The protocol is
3
3
  // registered by the Rust side; this file talks to the shell's register/revoke commands and takes the
4
4
  // iframe `src` from the URL the host builds. Content is keyed by an unguessable token, never by
5
5
  // file path.
6
6
  import { PREVIEW_COMMANDS } from "@rightkit/tauri-shell";
7
- export const PREVIEW_SCHEME = "viewright-preview";
8
- /** The origin a registered token is served from: `viewright-preview://localhost/<token>` on
9
- * macOS/Linux, `http://viewright-preview.localhost/<token>` on Windows/WebView2. */
7
+ import { hostScheme } from "../../host.js";
8
+ /** The host's preview scheme, `<host id>-preview` (`hostScheme`). */
9
+ export const previewScheme = () => hostScheme("preview");
10
+ /** The origin a registered token is served from: `<scheme>://localhost/<token>` on
11
+ * macOS/Linux, `http://<scheme>.localhost/<token>` on Windows/WebView2. */
10
12
  function isPreviewUrl(url, token) {
11
- return (url === `${PREVIEW_SCHEME}://localhost/${token}` ||
12
- url === `http://${PREVIEW_SCHEME}.localhost/${token}`);
13
+ const scheme = previewScheme();
14
+ return url === `${scheme}://localhost/${token}` || url === `http://${scheme}.localhost/${token}`;
13
15
  }
14
16
  export { isTauri as inTauriWebview } from "@rightkit/platform-ui";
15
17
  export async function registerPreview(kind, html) {
@@ -5,7 +5,7 @@ import { findLiteralMatches as findPlainMatches, findRegexMatches, regexPatternE
5
5
  export function isValidSearchRegex(pattern) {
6
6
  return regexPatternError(pattern) === null;
7
7
  }
8
- const SEARCH_HIGHLIGHT_STYLE_ID = "viewright-search-highlight-styles";
8
+ const SEARCH_HIGHLIGHT_STYLE_ID = "rk-document-search-highlight-styles";
9
9
  function ensureSearchHighlightStyles(win) {
10
10
  const doc = win.document;
11
11
  if (doc.getElementById(SEARCH_HIGHLIGHT_STYLE_ID))
package/dist/host.d.ts ADDED
@@ -0,0 +1,36 @@
1
+ export interface DocumentHostConfig {
2
+ /** Product name in user-facing copy (legal gate, settings, errors). Default `"App"`. */
3
+ appName?: string;
4
+ /**
5
+ * The host's native identifier. Every name the document packages share with the host's native
6
+ * side or with each other is derived from it:
7
+ *
8
+ * - window and Tauri event names: `<id>:<event>` (`documentEvent`);
9
+ * - custom URL schemes: `<id>-<suffix>`, e.g. `<id>-stream`, `<id>-site`, `<id>-preview` (`hostScheme`);
10
+ * - the raw-body path header: `x-<id>-path-hex` (`hostHeader`);
11
+ * - storage keys: `<id>:<key>` (`hostStorageKey`);
12
+ * - QA globals on `window`: `__<camelCaseId><Name>` (`hostQaGlobal`).
13
+ *
14
+ * Lower case letters, digits and single hyphens, starting with a letter. Default `"rk-document"`.
15
+ * A host whose native side already uses names with its own prefix passes that prefix here.
16
+ */
17
+ id?: string;
18
+ }
19
+ /** Set the host identity once at startup, before the first render. Absent fields keep their value. */
20
+ export declare function configureDocumentHost(config: DocumentHostConfig): void;
21
+ /** Product name for user-facing copy. Read it where the copy is built, not at module load. */
22
+ export declare function hostAppName(): string;
23
+ /** Same as `configureDocumentHost({ appName: name })`. */
24
+ export declare function setHostAppName(name: string): void;
25
+ /** The host's native identifier (see `DocumentHostConfig.id`). */
26
+ export declare function hostId(): string;
27
+ /** Name of a window or Tauri event shared by the document packages and the host: `<id>:<name>`. */
28
+ export declare function documentEvent(name: string): string;
29
+ /** Name of a host custom URL scheme: `<id>-<suffix>`. */
30
+ export declare function hostScheme(suffix: string): string;
31
+ /** Name of a host request header: `x-<id>-<suffix>`. */
32
+ export declare function hostHeader(suffix: string): string;
33
+ /** Key in web storage owned by the document packages: `<id>:<key>`. */
34
+ export declare function hostStorageKey(key: string): string;
35
+ /** Name of a QA global on `window`: `__<camelCaseId><Name>`. */
36
+ export declare function hostQaGlobal(name: string): string;
package/dist/host.js ADDED
@@ -0,0 +1,54 @@
1
+ // Host identity for every document package. One store, read at use time (never at module load), so
2
+ // a host's `configureDocumentHost()` call at startup reaches every module that was already imported.
3
+ // Before 0.2.0 each of the five document packages kept its own `appName` store, and the names the
4
+ // packages share with the host's native side (window and Tauri event names, the binary stream
5
+ // scheme, the path header, QA globals, storage keys) were fixed to one app's prefix.
6
+ const ID_PATTERN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/;
7
+ let appName = "App";
8
+ let id = "rk-document";
9
+ /** Set the host identity once at startup, before the first render. Absent fields keep their value. */
10
+ export function configureDocumentHost(config) {
11
+ if (config.appName !== undefined) {
12
+ if (!config.appName.trim())
13
+ throw new Error("configureDocumentHost: appName must not be empty");
14
+ appName = config.appName;
15
+ }
16
+ if (config.id !== undefined) {
17
+ if (!ID_PATTERN.test(config.id))
18
+ throw new Error(`configureDocumentHost: invalid id ${JSON.stringify(config.id)}`);
19
+ id = config.id;
20
+ }
21
+ }
22
+ /** Product name for user-facing copy. Read it where the copy is built, not at module load. */
23
+ export function hostAppName() {
24
+ return appName;
25
+ }
26
+ /** Same as `configureDocumentHost({ appName: name })`. */
27
+ export function setHostAppName(name) {
28
+ configureDocumentHost({ appName: name });
29
+ }
30
+ /** The host's native identifier (see `DocumentHostConfig.id`). */
31
+ export function hostId() {
32
+ return id;
33
+ }
34
+ /** Name of a window or Tauri event shared by the document packages and the host: `<id>:<name>`. */
35
+ export function documentEvent(name) {
36
+ return `${id}:${name}`;
37
+ }
38
+ /** Name of a host custom URL scheme: `<id>-<suffix>`. */
39
+ export function hostScheme(suffix) {
40
+ return `${id}-${suffix}`;
41
+ }
42
+ /** Name of a host request header: `x-<id>-<suffix>`. */
43
+ export function hostHeader(suffix) {
44
+ return `x-${id}-${suffix}`;
45
+ }
46
+ /** Key in web storage owned by the document packages: `<id>:<key>`. */
47
+ export function hostStorageKey(key) {
48
+ return `${id}:${key}`;
49
+ }
50
+ /** Name of a QA global on `window`: `__<camelCaseId><Name>`. */
51
+ export function hostQaGlobal(name) {
52
+ const camel = id.replace(/-([a-z0-9])/g, (_, c) => c.toUpperCase());
53
+ return `__${camel}${name}`;
54
+ }
package/dist/index.d.ts CHANGED
@@ -9,71 +9,26 @@ export * from "./app/printPipelineShared.js";
9
9
  export * from "./app/resourceCensus.js";
10
10
  export * from "./app/shell/docBar.js";
11
11
  export * from "./app/shell/nativeMenu.js";
12
- export * from "./app/shortcutChords.js";
13
- export * from "./app/useCloseFindOnSurfaceChange.js";
14
- export * from "./app/useEditText.js";
15
- export * from "./appName.js";
16
12
  export * from "./documents/BackToTopButton.js";
17
13
  export * from "./documents/ChromeButton.js";
18
14
  export * from "./documents/DocumentToolbarFind.js";
19
15
  export * from "./documents/DocumentToolbarShell.js";
20
- export * from "./documents/FullscreenIcon.js";
21
16
  export * from "./documents/PreviewChrome.js";
22
17
  export * from "./documents/PreviewMessage.js";
23
18
  export * from "./documents/base64.js";
24
19
  export * from "./documents/documentFormats.js";
25
- export * from "./documents/pdf/MacPdfReadPane.js";
26
- export * from "./documents/pdf/NativePdfDocument.js";
27
- export * from "./documents/pdf/PdfInlineTextEditor.js";
28
- export * from "./documents/pdf/PdfOcrLayer.js";
29
- export * from "./documents/pdf/PdfOutline.js";
30
- export * from "./documents/pdf/PdfPasswordPrompt.js";
31
- export * from "./documents/pdf/PdfThumbnails.js";
32
- export * from "./documents/pdf/PdfToolbar.js";
33
- export * from "./documents/pdf/PdfViewer.js";
34
- export * from "./documents/pdf/PdfViewerBody.js";
35
- export * from "./documents/pdf/nearestVisiblePdfPage.js";
36
- export * from "./documents/pdf/pdfBench.js";
37
- export * from "./documents/pdf/pdfBenchAutopilot.js";
38
- export * from "./documents/pdf/pdfBenchTransport.js";
39
- export * from "./documents/pdf/pdfEditModel.js";
40
- export * from "./documents/pdf/pdfEditor.js";
41
- export * from "./documents/pdf/pdfOcr.js";
42
- export * from "./documents/pdf/pdfOcrEdit.js";
43
- export * from "./documents/pdf/pdfSave.js";
44
- export * from "./documents/pdf/pdfShared.js";
45
- export * from "./documents/pdf/pdfToMarkdown.js";
46
- export * from "./documents/pdf/toolbarIcons.js";
47
- export * from "./documents/pdf/usePdfDocumentLoader.js";
48
- export * from "./documents/pdf/usePdfEditSession.js";
49
- export * from "./documents/pdf/usePdfEditor.js";
50
- export * from "./documents/pdf/usePdfFit.js";
51
- export * from "./documents/pdf/usePdfOcr.js";
52
- export * from "./documents/pdf/usePdfPreviewRecompose.js";
53
- export * from "./documents/pdf/usePdfSavePlan.js";
54
- export * from "./documents/pdf/usePdfSearch.js";
55
- export * from "./documents/pdf/usePdfViewControls.js";
56
20
  export * from "./documents/perfEventCounters.js";
57
21
  export * from "./documents/preview/previewFrame.js";
58
22
  export * from "./documents/preview/usePreviewFrameSrc.js";
59
- export * from "./documents/scopedSelectAll.js";
60
23
  export * from "./documents/searchUtils.js";
61
24
  export * from "./documents/splitResizeMath.js";
62
25
  export * from "./documents/toolbarPrimitives.js";
63
- export * from "./documents/txt/cmScroll.js";
64
26
  export * from "./documents/types.js";
65
- export * from "./documents/useMirroredEditText.js";
66
27
  export * from "./documents/usePreviewFind.js";
67
- export * from "./documents/useSplitResize.js";
68
28
  export * from "./documents/web/webUrl.js";
29
+ export * from "./host.js";
69
30
  export * from "./platform.js";
70
31
  export * from "./settings/fonts.js";
71
- export * from "./settings/sections/EditorSection.js";
72
- export * from "./settings/sections/FileAssociationsSection.js";
73
- export * from "./settings/sections/MacFileAssociationsBlock.js";
74
- export * from "./settings/sections/ThemeSection.js";
75
- export * from "./settings/sections/TypographySection.js";
76
- export * from "./settings/sections/onOff.js";
77
32
  export * from "./settings/settings.js";
78
33
  export * from "./settings/settingsBackend.js";
79
34
  export * from "./settings/themes.js";
package/dist/index.js CHANGED
@@ -11,71 +11,26 @@ export * from "./app/printPipelineShared.js";
11
11
  export * from "./app/resourceCensus.js";
12
12
  export * from "./app/shell/docBar.js";
13
13
  export * from "./app/shell/nativeMenu.js";
14
- export * from "./app/shortcutChords.js";
15
- export * from "./app/useCloseFindOnSurfaceChange.js";
16
- export * from "./app/useEditText.js";
17
- export * from "./appName.js";
18
14
  export * from "./documents/BackToTopButton.js";
19
15
  export * from "./documents/ChromeButton.js";
20
16
  export * from "./documents/DocumentToolbarFind.js";
21
17
  export * from "./documents/DocumentToolbarShell.js";
22
- export * from "./documents/FullscreenIcon.js";
23
18
  export * from "./documents/PreviewChrome.js";
24
19
  export * from "./documents/PreviewMessage.js";
25
20
  export * from "./documents/base64.js";
26
21
  export * from "./documents/documentFormats.js";
27
- export * from "./documents/pdf/MacPdfReadPane.js";
28
- export * from "./documents/pdf/NativePdfDocument.js";
29
- export * from "./documents/pdf/PdfInlineTextEditor.js";
30
- export * from "./documents/pdf/PdfOcrLayer.js";
31
- export * from "./documents/pdf/PdfOutline.js";
32
- export * from "./documents/pdf/PdfPasswordPrompt.js";
33
- export * from "./documents/pdf/PdfThumbnails.js";
34
- export * from "./documents/pdf/PdfToolbar.js";
35
- export * from "./documents/pdf/PdfViewer.js";
36
- export * from "./documents/pdf/PdfViewerBody.js";
37
- export * from "./documents/pdf/nearestVisiblePdfPage.js";
38
- export * from "./documents/pdf/pdfBench.js";
39
- export * from "./documents/pdf/pdfBenchAutopilot.js";
40
- export * from "./documents/pdf/pdfBenchTransport.js";
41
- export * from "./documents/pdf/pdfEditModel.js";
42
- export * from "./documents/pdf/pdfEditor.js";
43
- export * from "./documents/pdf/pdfOcr.js";
44
- export * from "./documents/pdf/pdfOcrEdit.js";
45
- export * from "./documents/pdf/pdfSave.js";
46
- export * from "./documents/pdf/pdfShared.js";
47
- export * from "./documents/pdf/pdfToMarkdown.js";
48
- export * from "./documents/pdf/toolbarIcons.js";
49
- export * from "./documents/pdf/usePdfDocumentLoader.js";
50
- export * from "./documents/pdf/usePdfEditSession.js";
51
- export * from "./documents/pdf/usePdfEditor.js";
52
- export * from "./documents/pdf/usePdfFit.js";
53
- export * from "./documents/pdf/usePdfOcr.js";
54
- export * from "./documents/pdf/usePdfPreviewRecompose.js";
55
- export * from "./documents/pdf/usePdfSavePlan.js";
56
- export * from "./documents/pdf/usePdfSearch.js";
57
- export * from "./documents/pdf/usePdfViewControls.js";
58
22
  export * from "./documents/perfEventCounters.js";
59
23
  export * from "./documents/preview/previewFrame.js";
60
24
  export * from "./documents/preview/usePreviewFrameSrc.js";
61
- export * from "./documents/scopedSelectAll.js";
62
25
  export * from "./documents/searchUtils.js";
63
26
  export * from "./documents/splitResizeMath.js";
64
27
  export * from "./documents/toolbarPrimitives.js";
65
- export * from "./documents/txt/cmScroll.js";
66
28
  export * from "./documents/types.js";
67
- export * from "./documents/useMirroredEditText.js";
68
29
  export * from "./documents/usePreviewFind.js";
69
- export * from "./documents/useSplitResize.js";
70
30
  export * from "./documents/web/webUrl.js";
31
+ export * from "./host.js";
71
32
  export * from "./platform.js";
72
33
  export * from "./settings/fonts.js";
73
- export * from "./settings/sections/EditorSection.js";
74
- export * from "./settings/sections/FileAssociationsSection.js";
75
- export * from "./settings/sections/MacFileAssociationsBlock.js";
76
- export * from "./settings/sections/ThemeSection.js";
77
- export * from "./settings/sections/TypographySection.js";
78
- export * from "./settings/sections/onOff.js";
79
34
  export * from "./settings/settings.js";
80
35
  export * from "./settings/settingsBackend.js";
81
36
  export * from "./settings/themes.js";
@@ -1,4 +1,4 @@
1
- import { hostAppName } from "../appName.js";
1
+ import { hostAppName } from "../host.js";
2
2
  export const THEMES = [
3
3
  {
4
4
  id: "viewright-paper",
@@ -1,5 +1,5 @@
1
1
  export type Unlisten = () => void | Promise<void>;
2
- export declare function onAppEvent(event: "open-file" | "file-changed" | "viewright:open-url" | "prepare-setup", cb: (path: string) => void): Promise<Unlisten>;
2
+ export declare function onAppEvent(event: "open-file" | "file-changed" | "open-url" | "prepare-setup", cb: (path: string) => void): Promise<Unlisten>;
3
3
  export declare function onContextViewSource(cb: () => void): Promise<Unlisten>;
4
4
  export declare function onContextOpenLinkTab(cb: () => void): Promise<Unlisten>;
5
5
  export declare function onContextOpenLinkExternal(cb: () => void): Promise<Unlisten>;
@@ -1,5 +1,6 @@
1
1
  import { isTauri as inTauri } from "@rightkit/platform-ui";
2
2
  import { EVENTS } from "@rightkit/tauri-shell";
3
+ import { documentEvent } from "../host.js";
3
4
  export async function onAppEvent(event, cb) {
4
5
  if (!inTauri())
5
6
  return () => { };
@@ -12,27 +13,29 @@ export async function onAppEvent(event, cb) {
12
13
  cb(path);
13
14
  });
14
15
  }
15
- const un = await listen(event, (e) => cb(e.payload));
16
+ // `open-url` is the host's own event, `<host id>:open-url`; the others are shell events.
17
+ const name = event === "open-url" ? documentEvent("open-url") : event;
18
+ const un = await listen(name, (e) => cb(e.payload));
16
19
  return un;
17
20
  }
18
21
  export async function onContextViewSource(cb) {
19
22
  if (!inTauri())
20
23
  return () => { };
21
24
  const { listen } = await import("@tauri-apps/api/event");
22
- const un = await listen("viewright:context-view-source", () => cb());
25
+ const un = await listen(documentEvent("context-view-source"), () => cb());
23
26
  return un;
24
27
  }
25
28
  export async function onContextOpenLinkTab(cb) {
26
29
  if (!inTauri())
27
30
  return () => { };
28
31
  const { listen } = await import("@tauri-apps/api/event");
29
- const un = await listen("viewright:context-open-link-tab", () => cb());
32
+ const un = await listen(documentEvent("context-open-link-tab"), () => cb());
30
33
  return un;
31
34
  }
32
35
  export async function onContextOpenLinkExternal(cb) {
33
36
  if (!inTauri())
34
37
  return () => { };
35
38
  const { listen } = await import("@tauri-apps/api/event");
36
- const un = await listen("viewright:context-open-link-external", () => cb());
39
+ const un = await listen(documentEvent("context-open-link-external"), () => cb());
37
40
  return un;
38
41
  }
@@ -2,11 +2,12 @@
2
2
  // PathBroker-token + on-disk based and don't fit URLs) and shown in the Open-URL dialog so a dev can
3
3
  // re-pick a server without retyping. localStorage-backed → persists across sessions via WebView2's
4
4
  // user-data folder. Best-effort: any storage failure degrades to "no history", never throws.
5
- const KEY = "viewright:recent-urls";
5
+ import { hostStorageKey } from "../host.js";
6
+ const key = () => hostStorageKey("recent-urls");
6
7
  const MAX = 8;
7
8
  export function getRecentUrls() {
8
9
  try {
9
- const raw = localStorage.getItem(KEY);
10
+ const raw = localStorage.getItem(key());
10
11
  const list = raw ? JSON.parse(raw) : [];
11
12
  return Array.isArray(list)
12
13
  ? list.filter((u) => typeof u === "string").slice(0, MAX)
@@ -22,7 +23,7 @@ export function addRecentUrl(url) {
22
23
  return;
23
24
  try {
24
25
  const next = [u, ...getRecentUrls().filter((existing) => existing !== u)].slice(0, MAX);
25
- localStorage.setItem(KEY, JSON.stringify(next));
26
+ localStorage.setItem(key(), JSON.stringify(next));
26
27
  }
27
28
  catch {
28
29
  /* storage unavailable — recents are a convenience, not load-bearing */