@rightkit/document-core 0.1.1 → 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 (136) hide show
  1. package/CHANGELOG.md +29 -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 -50
  16. package/dist/index.js +1 -50
  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 -61
  22. package/dist/state/tauriBridge.js +8 -297
  23. package/dist/styles.css +2 -2
  24. package/package.json +25 -98
  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 -303
  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
  127. package/dist/state/browserQa.d.ts +0 -21
  128. package/dist/state/browserQa.js +0 -303
  129. package/dist/state/browserQaDocx.d.ts +0 -3
  130. package/dist/state/browserQaDocx.js +0 -35
  131. package/dist/state/browserQaLicense.d.ts +0 -8
  132. package/dist/state/browserQaLicense.js +0 -7
  133. package/dist/state/browserQaPdf.d.ts +0 -60
  134. package/dist/state/browserQaPdf.js +0 -302
  135. package/dist/state/browserQaText.d.ts +0 -6
  136. package/dist/state/browserQaText.js +0 -48
@@ -1,303 +0,0 @@
1
- /**
2
- * Fixture documents + IPC-boundary fallbacks for browser QA mode (`VITE_RIGHTKIT_BROWSER_QA=1`,
3
- * `?qa=1&doc=<key>`) — the headless-Chrome harness `scripts/qa-browser-functional.mjs` drives, and
4
- * the manual escape hatch for poking the app in a plain browser tab outside Tauri. `qaOcrLines`
5
- * lives here; the PDF-edit-command mocks (`inspect_pdf_page`/`compose_pdf_preview`/
6
- * `prepare_pdf_save`/`commit_pdf_save`/`list_pdf_fonts`, plus the in-memory PDF "disk" and the
7
- * `window.__viewrightQa` assertion surface) live in the sibling `browserQaPdf.ts` instead, since
8
- * they need their own save-token/sha bookkeeping this file has no reason to carry.
9
- *
10
- * PDF coverage split: annotation editing (FreeText/Ink/Highlight/Stamp, via pdf.js's own
11
- * `AnnotationEditorLayer`/`saveDocument()`) + two-phase Save/Save As is fully exercised in browser
12
- * QA against `browserQaPdf.ts`'s mocks. Existing-text/add-text editing (`inspect_pdf_page`'s
13
- * `islands`) stays native-only — browser QA has no Rust content-stream walker, so that path is only
14
- * reachable/non-crashing here, never a real edit round trip.
15
- */
16
- import { baseName, formatFromPath } from "../documents/types.js";
17
- import { hostAppName } from "../appName.js";
18
- // 2-page PDF (generated by hand, ~1.4 KB): page 1 carries an external URI link annotation
19
- // (https://example.com/from-pdf) and an internal GoTo link to page 2. Exercises the viewer's
20
- // annotation/link layer in browser QA, where no Tauri stream token exists.
21
- const QA_LINK_PDF = "data:application/pdf;base64,JVBERi0xLjcKMSAwIG9iago8PCAvVHlwZSAvQ2F0YWxvZyAvUGFnZXMgMiAwIFIgPj4KZW5kb2JqCjIgMCBvYmoKPDwgL1R5cGUgL1BhZ2VzIC9LaWRzIFszIDAgUiA2IDAgUl0gL0NvdW50IDIgPj4KZW5kb2JqCjMgMCBvYmoKPDwgL1R5cGUgL1BhZ2UgL1BhcmVudCAyIDAgUiAvTWVkaWFCb3ggWzAgMCA2MTIgNzkyXSAvUmVzb3VyY2VzIDw8IC9Gb250IDw8IC9GMSA5IDAgUiA+PiA+PiAvQ29udGVudHMgNCAwIFIgL0Fubm90cyBbNyAwIFIgOCAwIFJdID4+CmVuZG9iago0IDAgb2JqCjw8IC9MZW5ndGggMTUxID4+CnN0cmVhbQpCVCAvRjEgMjQgVGYgNzIgNzAwIFRkIChQYWdlIDE6IGV4dGVybmFsIGxpbmsgYmVsb3cpIFRqIEVUCkJUIC9GMSAxOCBUZiA3MiA2NDAgVGQgKFZpc2l0IGV4YW1wbGUuY29tKSBUaiBFVApCVCAvRjEgMTggVGYgNzIgNTgwIFRkIChHbyB0byBwYWdlIDIpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKNSAwIG9iago8PCAvcGxhY2Vob2xkZXIgdHJ1ZSA+PgplbmRvYmoKNiAwIG9iago8PCAvVHlwZSAvUGFnZSAvUGFyZW50IDIgMCBSIC9NZWRpYUJveCBbMCAwIDYxMiA3OTJdIC9SZXNvdXJjZXMgPDwgL0ZvbnQgPDwgL0YxIDkgMCBSID4+ID4+IC9Db250ZW50cyAxMCAwIFIgPj4KZW5kb2JqCjcgMCBvYmoKPDwgL1R5cGUgL0Fubm90IC9TdWJ0eXBlIC9MaW5rIC9SZWN0IFs3MCA2MzAgMjYwIDY2NV0gL0JvcmRlciBbMCAwIDFdIC9BIDw8IC9TIC9VUkkgL1VSSSAoaHR0cHM6Ly9leGFtcGxlLmNvbS9mcm9tLXBkZikgPj4gPj4KZW5kb2JqCjggMCBvYmoKPDwgL1R5cGUgL0Fubm90IC9TdWJ0eXBlIC9MaW5rIC9SZWN0IFs3MCA1NzAgMjIwIDYwNV0gL0JvcmRlciBbMCAwIDFdIC9EZXN0IFs2IDAgUiAvWFlaIG51bGwgbnVsbCBudWxsXSA+PgplbmRvYmoKOSAwIG9iago8PCAvVHlwZSAvRm9udCAvU3VidHlwZSAvVHlwZTEgL0Jhc2VGb250IC9IZWx2ZXRpY2EgPj4KZW5kb2JqCjEwIDAgb2JqCjw8IC9MZW5ndGggNTkgPj4Kc3RyZWFtCkJUIC9GMSAyNCBUZiA3MiA3MDAgVGQgKFBhZ2UgMjogaW50ZXJuYWwgbGluayB0YXJnZXQpIFRqIEVUCmVuZHN0cmVhbQplbmRvYmoKeHJlZgowIDExCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDAwOSAwMDAwMCBuIAowMDAwMDAwMDU4IDAwMDAwIG4gCjAwMDAwMDAxMjEgMDAwMDAgbiAKMDAwMDAwMDI2OSAwMDAwMCBuIAowMDAwMDAwNDcxIDAwMDAwIG4gCjAwMDAwMDA1MTAgMDAwMDAgbiAKMDAwMDAwMDYzNyAwMDAwMCBuIAowMDAwMDAwNzc4IDAwMDAwIG4gCjAwMDAwMDA5MDAgMDAwMDAgbiAKMDAwMDAwMDk3MCAwMDAwMCBuIAp0cmFpbGVyCjw8IC9TaXplIDExIC9Sb290IDEgMCBSID4+CnN0YXJ0eHJlZgoxMDgwCiUlRU9GCg==";
22
- // Keep PDF xref offsets intact while exercising URL schemes accepted/rejected by pdf.js.
23
- function qaPdfUriAsset(uri) {
24
- const original = "https://example.com/from-pdf";
25
- if (uri.length > original.length)
26
- throw new Error("QA PDF URI must fit existing annotation");
27
- const bytes = atob(QA_LINK_PDF.split(",")[1]);
28
- return `data:application/pdf;base64,${btoa(bytes.replace(original, uri.padEnd(original.length, " ")))}`;
29
- }
30
- // Browser QA has no Rust OCR backend, so the IPC-boundary fixture keeps the scanned-page UI
31
- // deterministic while exercising the same positioned-line shape as native recognition.
32
- export function qaOcrLines() {
33
- return [
34
- {
35
- text: "Requerimento de licença",
36
- rect: { x: 0.12, y: 0.14, width: 0.42, height: 0.035 },
37
- confidence: 0.98,
38
- },
39
- {
40
- text: "Nome do requerente",
41
- rect: { x: 0.12, y: 0.22, width: 0.34, height: 0.035 },
42
- confidence: 0.96,
43
- },
44
- {
45
- text: "Data de nascimento",
46
- rect: { x: 0.12, y: 0.3, width: 0.31, height: 0.035 },
47
- confidence: null,
48
- },
49
- {
50
- text: "Assinatura do requerente",
51
- rect: { x: 0.12, y: 0.38, width: 0.39, height: 0.035 },
52
- confidence: 0.94,
53
- },
54
- ];
55
- }
56
- const qaDocs = {
57
- mdx: {
58
- path: `D:\\${hostAppName()} QA\\runtime.mdx`,
59
- lastView: "preview",
60
- content: `# MDX consolidation
61
-
62
- Needle one. Needle two.
63
-
64
- <button onClick={(event) => { event.currentTarget.textContent = "Clicked"; }}>Press</button>
65
- `,
66
- },
67
- md: {
68
- path: `D:\\${hostAppName()} QA\\source-notes.md`,
69
- lastView: "source",
70
- content: `# Source editor QA
71
-
72
- This markdown file exists only in browser QA mode.
73
-
74
- - The gutter should be subtle.
75
- - Markdown source should remain readable.
76
- - Find should navigate without leaving stale highlights.
77
-
78
- \`\`\`ts
79
- const product = "${hostAppName()}";
80
- console.log(product);
81
- \`\`\`
82
-
83
- | Very wide protected table with SupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidocious | Column two | Column three | Column four | Column five | Column six | Column seven | Column eight |
84
- | --- | --- | --- | --- | --- | --- | --- | --- |
85
- | This oversized fixture must remain inside its editor rail | Two | Three | Four | Five | Six | Seven | Eight |
86
-
87
- \`\`\`ts
88
- const oversizedCodeFixture = "SupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidociousSupercalifragilisticexpialidocious";
89
- \`\`\`
90
- ${Array.from({ length: 72 }, (_, index) => `\n\n## Outer scroll fixture ${index + 1}\nThis real Markdown line proves visible-line tracking & Back to top use document scroll owner.`).join("")}
91
- `,
92
- },
93
- mdMermaid: {
94
- path: `D:\\${hostAppName()} QA\\wide-mermaid.md`,
95
- lastView: "preview",
96
- content: `# Media Console Mermaid QA
97
-
98
- Visual Plan:
99
-
100
- \`\`\`mermaid
101
- flowchart LR
102
- ui["React/Vite UI"] --> shell["Tauri shell commands"]
103
- shell --> supervisor["Rust EngineSupervisor"]
104
- supervisor <--> protocol["media-console-protocol frames"]
105
- protocol <--> engine["media-console-engine sidecar"]
106
- engine --> core["media-console-core"]
107
- core --> store["manifest/job/artifact store"]
108
- engine --> runners["Rust-owned runner adapters"]
109
- runners --> providers["provider/runner boundaries"]
110
- \`\`\`
111
-
112
- The diagram above should scroll horizontally inside its card without clipping labels, nodes, or arrowheads.
113
- `,
114
- },
115
- html: {
116
- path: `D:\\${hostAppName()} QA\\local-preview.html`,
117
- lastView: "interactive",
118
- content: `<!doctype html>
119
- <html lang="en">
120
- <head>
121
- <meta charset="utf-8" />
122
- <title>${hostAppName()} HTML QA</title>
123
- <style>
124
- body { margin: 0; font-family: Inter, system-ui, sans-serif; color: #25221d; background: #faf7ef; }
125
- main { max-width: 760px; margin: 9vh auto; padding: 32px; border: 1px solid #ded4c2; background: white; }
126
- h1 { font-family: "Source Serif 4", Georgia, serif; font-size: 48px; margin: 0 0 12px; }
127
- code { color: #8f4d2e; }
128
- </style>
129
- </head>
130
- <body>
131
- <main>
132
- <h1>Local HTML preview</h1>
133
- <p>This page checks ${hostAppName()}'s rendered preview and source drawer.</p>
134
- <p><code>data-mode="qa"</code> should be easy to read in source.</p>
135
- <p>A <a href="https://example.com/">sample link</a> to click.</p>
136
- <table>
137
- <thead><tr><th>Name</th><th>Value</th></tr></thead>
138
- <tbody>
139
- <tr><td>alpha</td><td>one</td></tr>
140
- <tr><td>beta</td><td>two</td></tr>
141
- </tbody>
142
- </table>
143
- </main>
144
- </body>
145
- </html>
146
- `,
147
- },
148
- htmlSource: {
149
- path: `D:\\${hostAppName()} QA\\vite-source-shell.html`,
150
- lastView: "interactive",
151
- content: `<!doctype html>
152
- <html lang="en">
153
- <head><meta charset="utf-8" /><title>Vite source shell</title></head>
154
- <body>
155
- <div id="vr-boot">Loading…</div>
156
- <script src="/boot.js"></script>
157
- <script type="module" src="/src/main.tsx"></script>
158
- </body>
159
- </html>
160
- `,
161
- },
162
- txt: {
163
- path: `D:\\${hostAppName()} QA\\scratch.txt`,
164
- lastView: "preview",
165
- content: "Plain text QA\n\nThis surface should not show a source gutter.\nSpellcheck and find should still work.",
166
- },
167
- pdf: {
168
- path: `D:\\${hostAppName()} QA\\linked.pdf`,
169
- content: "",
170
- assetUrl: QA_LINK_PDF,
171
- },
172
- "pdf-malicious": {
173
- path: `D:\\${hostAppName()} QA\\malicious-link.pdf`,
174
- content: "",
175
- assetUrl: qaPdfUriAsset("ftp://evil.example/steal.pdf"),
176
- },
177
- "pdf-script": {
178
- path: `D:\\${hostAppName()} QA\\script-link.pdf`,
179
- content: "",
180
- assetUrl: qaPdfUriAsset("javascript:alert\\(1\\)"),
181
- },
182
- image: {
183
- path: `D:\\${hostAppName()} QA\\sample.svg`,
184
- content: `data:image/svg+xml,${encodeURIComponent(`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 360"><rect width="640" height="360" fill="#f7f3ec"/><circle cx="180" cy="180" r="96" fill="#1a6ed4"/><rect x="320" y="96" width="188" height="168" rx="18" fill="#16213f"/><text x="320" y="310" font-family="monospace" font-size="30" fill="#16213f">ViewRight image QA</text></svg>`)}`,
185
- },
186
- };
187
- function qaDocKey() {
188
- if (typeof window === "undefined")
189
- return null;
190
- const raw = new URLSearchParams(window.location.search).get("doc") ?? "";
191
- return raw in qaDocs ? raw : null;
192
- }
193
- /// Manual-QA-only escape hatch (not used by the automated `qa:functional:browser` suite): loads a
194
- /// real file straight off disk through Vite dev server's `/@fs/` route, keyed by `?doc=corpus&file=
195
- /// <name>` against `VR_CORPUS_DIR` (default `.qa-corpus/`, same env var the Rust corpus harness in
196
- /// `commands/corpus_qa.rs` uses). Lets a real-world PDF corpus be opened and observed (lazy-render,
197
- /// network panel, memory) via the ordinary QA-mode app shell without any native file dialog.
198
- function qaCorpusFileName() {
199
- if (typeof window === "undefined")
200
- return null;
201
- const params = new URLSearchParams(window.location.search);
202
- if (params.get("doc") !== "corpus")
203
- return null;
204
- return params.get("file");
205
- }
206
- function qaCorpusPath(file) {
207
- return `D:\\${hostAppName()} QA\\corpus\\${file}`;
208
- }
209
- function qaDocxCorpusFileName() {
210
- if (typeof window === "undefined")
211
- return null;
212
- const params = new URLSearchParams(window.location.search);
213
- const file = params.get("file");
214
- return params.get("doc") === "docx-corpus" && file && /^[^/\\]+\.docx$/.test(file) ? file : null;
215
- }
216
- const QA_DOCX_CORPUS_PREFIX = `D:\\${hostAppName()} QA\\docx-corpus\\`;
217
- export function qaDialogPath() {
218
- const docxCorpusFile = qaDocxCorpusFileName();
219
- if (docxCorpusFile)
220
- return QA_DOCX_CORPUS_PREFIX + docxCorpusFile;
221
- const corpusFile = qaCorpusFileName();
222
- if (corpusFile)
223
- return qaCorpusPath(corpusFile);
224
- return qaDocKey() === "md" ? qaDocs.mdMermaid.path : qaDocs[qaDocKey() ?? "md"].path;
225
- }
226
- export function qaInitialOpenPath() {
227
- const docxCorpusFile = qaDocxCorpusFileName();
228
- if (docxCorpusFile)
229
- return QA_DOCX_CORPUS_PREFIX + docxCorpusFile;
230
- const corpusFile = qaCorpusFileName();
231
- if (corpusFile)
232
- return qaCorpusPath(corpusFile);
233
- const key = qaDocKey();
234
- return key ? qaDocs[key].path : null;
235
- }
236
- async function bytesToBase64PdfUrl(bytes) {
237
- const blob = new Blob([bytes], { type: "application/pdf" });
238
- const reader = new FileReader();
239
- return new Promise((resolvePromise, reject) => {
240
- reader.onload = () => resolvePromise(reader.result);
241
- reader.onerror = () => reject(reader.error);
242
- reader.readAsDataURL(blob);
243
- });
244
- }
245
- export async function qaDocumentForPath(path) {
246
- if (path.startsWith(QA_DOCX_CORPUS_PREFIX)) {
247
- const file = path.slice(QA_DOCX_CORPUS_PREFIX.length);
248
- if (!/^[^/\\]+\.docx$/.test(file))
249
- return null;
250
- const res = await fetch(`/qa-docx-corpus/${encodeURIComponent(file)}`);
251
- if (!res.ok)
252
- return null;
253
- const bytes = await res.arrayBuffer();
254
- const content = await new Promise((resolvePromise, reject) => {
255
- const reader = new FileReader();
256
- reader.onload = () => resolvePromise(String(reader.result).split(",", 2)[1] ?? "");
257
- reader.onerror = () => reject(reader.error);
258
- reader.readAsDataURL(new Blob([bytes]));
259
- });
260
- return {
261
- path,
262
- displayName: baseName(path),
263
- format: "docx",
264
- content,
265
- encoding: "UTF-8",
266
- fingerprint: { mtimeMs: 1, size: bytes.byteLength },
267
- };
268
- }
269
- const corpusPrefix = `D:\\${hostAppName()} QA\\corpus\\`;
270
- if (path.startsWith(corpusPrefix)) {
271
- const file = path.slice(corpusPrefix.length);
272
- const dir = import.meta.env?.VITE_VR_CORPUS_DIR ?? "/Volumes/D/claude/viewright/.qa-corpus";
273
- const res = await fetch(`/@fs/${dir}/${encodeURIComponent(file)}`);
274
- if (!res.ok)
275
- return null;
276
- const bytes = await res.arrayBuffer();
277
- const format = formatFromPath(path);
278
- const assetUrl = format === "pdf" ? await bytesToBase64PdfUrl(bytes) : undefined;
279
- return {
280
- path,
281
- displayName: baseName(path),
282
- format,
283
- content: format === "pdf" ? "" : new TextDecoder().decode(bytes),
284
- assetUrl,
285
- encoding: "UTF-8",
286
- fingerprint: { mtimeMs: 1, size: bytes.byteLength },
287
- };
288
- }
289
- const doc = Object.values(qaDocs).find((entry) => entry.path === path);
290
- if (!doc)
291
- return null;
292
- return {
293
- path: doc.path,
294
- displayName: baseName(doc.path),
295
- format: formatFromPath(doc.path),
296
- content: doc.content,
297
- assetUrl: doc.assetUrl,
298
- lastView: doc.lastView,
299
- viewMeta: doc.viewMeta,
300
- encoding: "UTF-8",
301
- fingerprint: { mtimeMs: 1, size: doc.content.length },
302
- };
303
- }
@@ -1,3 +0,0 @@
1
- import type { LoadedDocument } from "../documents/types.js";
2
- export declare function readQaDocxDocument(doc: LoadedDocument): LoadedDocument | null;
3
- export declare function writeQaDocxDocument(path: string, bytes: ArrayBuffer, contentBase64: string): Promise<void>;
@@ -1,35 +0,0 @@
1
- // IPC-boundary DOCX disk, confined to disposable QA profile. Readback exposes only saved bytes.
2
- const PREFIX = "viewright.qa.docx-disk:";
3
- function read(path) {
4
- const raw = sessionStorage.getItem(PREFIX + path);
5
- return raw ? JSON.parse(raw) : null;
6
- }
7
- function publishReadback() {
8
- window.__viewrightQaDocx =
9
- Object.freeze({ read });
10
- }
11
- export function readQaDocxDocument(doc) {
12
- if (doc.format !== "docx")
13
- return null;
14
- const entry = read(doc.path);
15
- if (!entry)
16
- return null;
17
- publishReadback();
18
- return {
19
- ...doc,
20
- content: entry.contentBase64,
21
- assetUrl: undefined,
22
- fingerprint: { mtimeMs: entry.mtimeMs, size: entry.byteLength },
23
- };
24
- }
25
- export async function writeQaDocxDocument(path, bytes, contentBase64) {
26
- const hash = await crypto.subtle.digest("SHA-256", bytes);
27
- const sourceSha256 = Array.from(new Uint8Array(hash), (byte) => byte.toString(16).padStart(2, "0")).join("");
28
- sessionStorage.setItem(PREFIX + path, JSON.stringify({
29
- contentBase64,
30
- sourceSha256,
31
- byteLength: bytes.byteLength,
32
- mtimeMs: Date.now(),
33
- }));
34
- publishReadback();
35
- }
@@ -1,8 +0,0 @@
1
- export declare function qaLicenseClient(): {
2
- status: () => Promise<import("@rightkit/license").LicenseView>;
3
- activate: (key: string) => Promise<import("@rightkit/license").LicenseView>;
4
- refresh: () => Promise<import("@rightkit/license").RefreshView>;
5
- deactivate: () => Promise<import("@rightkit/license").LicenseView>;
6
- requestTrial: (email: string) => Promise<import("@rightkit/license").TrialView>;
7
- onChange(callback: (view: import("@rightkit/license").LicenseView) => void, onError?: (error: import("@rightkit/license").LicenseClientError) => void): Promise<import("@rightkit/license").LicenseUnlisten>;
8
- };
@@ -1,7 +0,0 @@
1
- import { createLicenseMock } from "@rightkit/license/testing";
2
- // Browser-QA only (loaded through `browserQaLicenseClient()` in tauriBridge, behind BROWSER_QA_BUILD).
3
- // The mock is in-memory: no persistence, credentials or network. The `testing` export resolves
4
- // only under the `development` condition, so a release build must never reach this module.
5
- export function qaLicenseClient() {
6
- return createLicenseMock().client;
7
- }
@@ -1,60 +0,0 @@
1
- /**
2
- * Deterministic PDF-edit-command mocks for browser QA mode (`VITE_RIGHTKIT_BROWSER_QA=1`,
3
- * `?qa=1&doc=pdf`). Never active in production builds — every export here is only ever reached
4
- * through `tauriBridge.ts`'s `isBrowserQaMode()` gate, exactly like `qaOcrLines` already is for
5
- * OCR (see `browserQa.ts`).
6
- *
7
- * Before this module, `requireTauriForPdfEdit` threw `unsupported_outside_tauri` for every
8
- * PDF-editor command (`inspect_pdf_page`, `compose_pdf_preview`, `prepare_pdf_save`,
9
- * `commit_pdf_save`, `list_pdf_fonts`), so Save and Edit-text had zero coverage in the automated
10
- * `qa:functional:browser` harness — every PDF save regression had to be found by hand in the
11
- * native app. This module gives the harness a real, in-memory PDF "disk" and mirrors the Rust
12
- * save-protocol rules (`src-tauri/crates/pdf/src/save.rs`'s `select_compose_base`, the stale-sha
13
- * check, single-use tokens) closely enough that ANNOTATION editing + save (stamp/ink/highlight, via
14
- * pdf.js's own `AnnotationEditorLayer`/`saveDocument()`) is now exercised end to end in the
15
- * headless browser harness. Source-TEXT editing (`inspect_pdf_page`'s `islands`) stays native-only:
16
- * browser QA has no Rust content-stream walker, so `qaInspectPdfPage` always reports zero editable
17
- * islands — good enough to keep the Edit-text UI reachable/non-crashing, not to exercise a real
18
- * text-replace round trip.
19
- */
20
- import type { ComposePdfPreviewRequest, ComposedPdfPreview, PdfCommitResult, PdfFontCatalogEntry, PdfPageGraph, PreparePdfSaveRequest, PreparedPdfSave } from "../documents/pdf/pdfEditModel.js";
21
- /** Matches `document_sha256` (`src-tauri/crates/pdf/src/model.rs`): plain SHA-256 of the whole
22
- * byte sequence, lowercase hex. */
23
- export declare function sha256Hex(bytes: Uint8Array): Promise<string>;
24
- /** Exported for PdfViewer.tsx's post-commit reload only (see its own call site's comment): the
25
- * `url` prop it otherwise reloads from is a static `data:` URL captured once at document-open
26
- * time — unlike a real Tauri stream token, it can never reflect a later commit on its own, so the
27
- * reload needs to ask this in-memory disk for the CURRENT bytes directly. Returns `null` outside
28
- * QA mode or for a path never touched through the PDF-edit bridge. */
29
- export declare function qaCurrentPdfBytes(path: string): Promise<Uint8Array | null>;
30
- export declare function qaCurrentPdfAssetUrl(path: string): Promise<string | null>;
31
- /** Test-only: clears the in-memory QA disk and save-token registry so each test starts from a
32
- * fresh fixture seed, independent of what earlier tests in the same file committed. Mirrors
33
- * `resourceCensus.ts`'s `resetResourceCensusForTests` convention. */
34
- export declare function resetQaPdfStateForTests(): void;
35
- export declare function qaInspectPdfPage(path: string, page: number): Promise<PdfPageGraph>;
36
- export declare function qaListPdfFonts(): Promise<PdfFontCatalogEntry[]>;
37
- export declare function qaComposePdfPreview(request: ComposePdfPreviewRequest): Promise<ComposedPdfPreview>;
38
- export declare function qaPreparePdfSave(request: PreparePdfSaveRequest): Promise<PreparedPdfSave>;
39
- export declare function qaCommitPdfSave(token: string, targetPath?: string): Promise<PdfCommitResult>;
40
- export interface ViewrightQaGlobal {
41
- pdfDiskBase64(path: string): string | null;
42
- pdfDiskLatin1(path: string): string | null;
43
- /** The PRISTINE fixture/corpus bytes for `path` (always freshly re-derived from
44
- * `qaDocumentForPath`, never from the mutable `qaDisk` — so this stays correct even after a
45
- * commit has already overwritten `qaDisk`'s entry). For asserting a save produced a real
46
- * incremental update ("committed bytes start with the ORIGINAL bytes"), since by the time a
47
- * script can read `pdfDiskLatin1` after a "Saved" toast, `qaDisk` already holds the new,
48
- * post-commit bytes. */
49
- originalPdfDiskLatin1(path: string): Promise<string | null>;
50
- }
51
- declare global {
52
- interface Window {
53
- __viewrightQa?: ViewrightQaGlobal;
54
- }
55
- }
56
- /** Registers `window.__viewrightQa` once. Callers (`tauriBridge.ts`) must gate this behind their
57
- * own `isBrowserQaMode()` check — kept unconditional here (idempotent via `registered`) rather
58
- * than duplicating that check locally, since importing `isBrowserQaMode` from `tauriBridge.ts`
59
- * would cycle back into this module's own `./browserQa` import. */
60
- export declare function registerViewrightQaGlobal(): void;