@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,154 +0,0 @@
1
- /**
2
- * VR-P0-1 benchmark autopilot (dev-only, temporary instrumentation).
3
- *
4
- * The PDF loading benchmark has to run in the real WKWebView/WebView2 webview, whose DevTools
5
- * console is GUI-only — so driving it by hand does not scale to "3 repeats x 3 modes x N fixtures,
6
- * on two operating systems". This module runs the whole matrix unattended:
7
- *
8
- * 1. a plan (modes x repeats) is stored in localStorage;
9
- * 2. each app load runs whichever mode the plan currently points at;
10
- * 3. on completion the full result is appended to native PDF benchmark JSONL;
11
- * a content-free diagnostics breadcrumb remains for quick status checks;
12
- * 4. the plan advances and the app reloads, until the matrix is done.
13
- *
14
- * Repeats are INTERLEAVED (round-robin across modes) rather than grouped, so a thermal or
15
- * page-cache drift over the run cannot systematically favour whichever mode ran first.
16
- *
17
- * Delete this file together with the rest of the benchmark harness once the study is decided.
18
- */
19
- import { logEvent } from "../../state/diagnostics.js";
20
- const PLAN_KEY = "vr.pdf.bench.autopilot.v1";
21
- const ENABLED_KEY = "vr.pdf.bench.enabled";
22
- const MODE_KEY = "vr.pdf.bench.mode";
23
- const DEFAULT_MODES = ["buffer", "url-native", "custom-range"];
24
- const DEFAULT_REPEATS = 3;
25
- function dev() {
26
- // Vitest runs with MODE=test; retaining this explicit test-only gate keeps benchmark controls
27
- // unavailable in production builds while allowing orchestration behavior to stay covered.
28
- return (typeof window !== "undefined" &&
29
- (import.meta.env?.DEV ||
30
- import.meta.env?.MODE === "test" ||
31
- (typeof process !== "undefined" && process.env.NODE_ENV === "test")));
32
- }
33
- function loadPlan() {
34
- if (!dev())
35
- return null;
36
- try {
37
- const raw = localStorage.getItem(PLAN_KEY);
38
- if (!raw)
39
- return null;
40
- const parsed = JSON.parse(raw);
41
- if (!Array.isArray(parsed.modes) || parsed.modes.length === 0)
42
- return null;
43
- return parsed;
44
- }
45
- catch {
46
- return null;
47
- }
48
- }
49
- function savePlan(plan) {
50
- try {
51
- localStorage.setItem(PLAN_KEY, JSON.stringify(plan));
52
- }
53
- catch {
54
- // Dev-only; never an application correctness dependency.
55
- }
56
- }
57
- function totalRuns(plan) {
58
- return plan.modes.length * plan.repeats;
59
- }
60
- function modeForIndex(plan, index) {
61
- return plan.modes[index % plan.modes.length];
62
- }
63
- /** Point the benchmark at the mode this run should use, and make sure it is armed. */
64
- function armMode(mode) {
65
- try {
66
- localStorage.setItem(ENABLED_KEY, "1");
67
- localStorage.setItem(MODE_KEY, mode);
68
- }
69
- catch {
70
- // Dev-only.
71
- }
72
- }
73
- /** The mode the plan wants for the current load, or null when no plan is active. */
74
- export function autopilotCurrentMode() {
75
- const plan = loadPlan();
76
- if (!plan || plan.done)
77
- return null;
78
- return modeForIndex(plan, plan.index);
79
- }
80
- /**
81
- * Called from benchmark `finalize()`. Records a content-free diagnostics breadcrumb, advances plan,
82
- * & either reloads for next mode or reports matrix complete. Full result is native JSONL.
83
- */
84
- export function autopilotOnComplete() {
85
- const plan = loadPlan();
86
- if (!plan || plan.done)
87
- return;
88
- const of = totalRuns(plan);
89
- logEvent("pdf-bench-autopilot-result");
90
- plan.index += 1;
91
- if (plan.index >= of) {
92
- plan.done = true;
93
- savePlan(plan);
94
- logEvent("pdf-bench-autopilot-done");
95
- return;
96
- }
97
- savePlan(plan);
98
- armMode(modeForIndex(plan, plan.index));
99
- // finalize() has already awaited both settle sampling & durable native write. Reload now: WKWebView
100
- // can indefinitely throttle a timer once its benchmark window becomes occluded, stranding a
101
- // multi-mode plan after its first valid sample.
102
- if (import.meta.env?.MODE !== "test")
103
- location.reload();
104
- }
105
- /** Begin a matrix. Arms the first mode and reloads so the run starts from a clean document load. */
106
- export function startAutopilot(label = "unlabelled", modes = DEFAULT_MODES, repeats = DEFAULT_REPEATS, reload = true, runId = String(import.meta.env?.VITE_PDF_BENCH_RUN_ID ?? label)) {
107
- if (!dev())
108
- return;
109
- const plan = { runId, modes, repeats, index: 0, label, done: false };
110
- savePlan(plan);
111
- armMode(modeForIndex(plan, 0));
112
- logEvent("pdf-bench-autopilot-start");
113
- if (reload)
114
- location.reload();
115
- }
116
- export function stopAutopilot() {
117
- try {
118
- localStorage.removeItem(PLAN_KEY);
119
- localStorage.removeItem(ENABLED_KEY);
120
- }
121
- catch {
122
- // Dev-only.
123
- }
124
- }
125
- export function autopilotStatus() {
126
- return loadPlan();
127
- }
128
- /**
129
- * Auto-start from the environment so the matrix needs no console at all:
130
- * VITE_PDF_BENCH_AUTOPILOT=1 pnpm dev:tauri <file.pdf>
131
- *
132
- * Only fires when no plan exists yet, so the per-run reloads do not restart the matrix.
133
- */
134
- export function maybeAutoStartFromEnv() {
135
- if (!dev())
136
- return;
137
- if (import.meta.env?.VITE_PDF_BENCH_AUTOPILOT !== "1")
138
- return;
139
- const label = String(import.meta.env?.VITE_PDF_BENCH_LABEL ?? "auto");
140
- const runId = String(import.meta.env?.VITE_PDF_BENCH_RUN_ID ?? label);
141
- const modes = String(import.meta.env?.VITE_PDF_BENCH_MODES ?? "")
142
- .split(",")
143
- .map((mode) => mode.trim())
144
- .filter((mode) => DEFAULT_MODES.includes(mode));
145
- const existing = loadPlan();
146
- // A plan for THIS label that is still mid-matrix must never be restarted — that's the
147
- // per-run reload case. But localStorage survives across app launches (same webview profile),
148
- // so a plan left over from an earlier session/label (done, or for a different fixture) must
149
- // NOT silently block every future auto-start; start fresh for a new/changed label.
150
- if (existing && !existing.done && existing.runId === runId)
151
- return;
152
- const repeats = Number(import.meta.env?.VITE_PDF_BENCH_REPEATS ?? DEFAULT_REPEATS);
153
- startAutopilot(label, modes.length > 0 ? modes : DEFAULT_MODES, Number.isFinite(repeats) && repeats > 0 ? repeats : DEFAULT_REPEATS, false, runId);
154
- }
@@ -1,21 +0,0 @@
1
- import * as pdfjs from "pdfjs-dist";
2
- import type { PDFDocumentProxy } from "pdfjs-dist";
3
- import { type PdfBenchLoadMode } from "./pdfBench.js";
4
- /** Above this size the whole-file buffer fallback is skipped in favour of range loading. */
5
- export declare const MAX_BUFFERED_PDF_BYTES: number;
6
- export declare function shouldRangeLoadInsteadOfBuffer(contentLength: string | null): boolean;
7
- export interface PreparedPdfLoading {
8
- readonly task: ReturnType<typeof pdfjs.getDocument>;
9
- readonly promise: Promise<PDFDocumentProxy>;
10
- dispose(): void;
11
- }
12
- interface PreparePdfLoadingArgs {
13
- readonly url: string;
14
- readonly mode: PdfBenchLoadMode;
15
- readonly signal: AbortSignal;
16
- readonly wasmUrl: string;
17
- }
18
- export declare function formatPdfRangeHeader(begin: number, end: number): string;
19
- export declare function parseContentRangeTotal(value: string | null): number | null;
20
- export declare function preparePdfLoading({ url, mode, signal, wasmUrl, }: PreparePdfLoadingArgs): Promise<PreparedPdfLoading>;
21
- export {};
@@ -1,233 +0,0 @@
1
- import * as pdfjs from "pdfjs-dist";
2
- import { pdfDocumentInit } from "@rightkit/pdf-ui";
3
- import { isPdfBenchEnabled } from "./pdfBench.js";
4
- const RANGE_CHUNK_SIZE = 64 * 1024;
5
- /** Above this size the whole-file buffer fallback is skipped in favour of range loading. */
6
- export const MAX_BUFFERED_PDF_BYTES = 150 * 1024 * 1024;
7
- export function shouldRangeLoadInsteadOfBuffer(contentLength) {
8
- const n = Number(contentLength);
9
- return Number.isFinite(n) && n > MAX_BUFFERED_PDF_BYTES;
10
- }
11
- export function formatPdfRangeHeader(begin, end) {
12
- if (!Number.isInteger(begin) || !Number.isInteger(end) || begin < 0 || end <= begin) {
13
- throw new Error(`Invalid PDF byte range [${begin}, ${end})`);
14
- }
15
- return `bytes=${begin}-${end - 1}`;
16
- }
17
- export function parseContentRangeTotal(value) {
18
- return parseContentRange(value)?.total ?? null;
19
- }
20
- function parseContentRange(value) {
21
- if (!value)
22
- return null;
23
- const match = value.match(/^bytes\s+(\d+)-(\d+)\/(\d+)$/i);
24
- if (!match)
25
- return null;
26
- const begin = Number(match[1]);
27
- const end = Number(match[2]);
28
- const total = Number(match[3]);
29
- if (!Number.isSafeInteger(begin) ||
30
- !Number.isSafeInteger(end) ||
31
- !Number.isSafeInteger(total) ||
32
- begin < 0 ||
33
- end < begin ||
34
- total <= end) {
35
- return null;
36
- }
37
- return { begin, end, total };
38
- }
39
- function parseContentLength(value) {
40
- if (!value)
41
- return null;
42
- const length = Number(value);
43
- return Number.isSafeInteger(length) && length > 0 ? length : null;
44
- }
45
- async function probePdfLength(url, signal) {
46
- // HEAD is cheapest when the webview/custom protocol handles it correctly.
47
- try {
48
- const head = await fetch(url, { method: "HEAD", signal, cache: "no-store" });
49
- const length = head.ok ? parseContentLength(head.headers.get("content-length")) : null;
50
- if (length !== null)
51
- return { length, initialData: null };
52
- }
53
- catch (error) {
54
- if (error?.name === "AbortError")
55
- throw error;
56
- // Fall through to a 1-byte range probe. Benchmarking exists specifically because custom-scheme
57
- // behavior differs across webviews; HEAD support must not be assumed.
58
- }
59
- const probe = await fetch(url, {
60
- signal,
61
- cache: "no-store",
62
- headers: { Range: "bytes=0-0" },
63
- });
64
- if (probe.status !== 206) {
65
- throw new Error(`PDF range probe failed: expected 206, got ${probe.status}`);
66
- }
67
- const length = parseContentRangeTotal(probe.headers.get("content-range"));
68
- if (length === null)
69
- throw new Error("PDF range probe did not expose a valid total length");
70
- const initialData = new Uint8Array(await probe.arrayBuffer());
71
- const range = parseContentRange(probe.headers.get("content-range"));
72
- if (!range || range.begin !== 0 || range.end !== initialData.byteLength - 1) {
73
- throw new Error("PDF range probe returned bytes that do not match Content-Range");
74
- }
75
- return { length, initialData };
76
- }
77
- class HostPdfRangeTransport extends pdfjs.PDFDataRangeTransport {
78
- #url;
79
- #length;
80
- #controllers = new Set();
81
- #aborted = false;
82
- #failure = null;
83
- #onFailure = null;
84
- constructor(url, length, initialData) {
85
- // progressiveDone=true: this transport intentionally supplies explicit ranges only.
86
- super(length, initialData, true);
87
- this.#url = url;
88
- this.#length = length;
89
- }
90
- get failure() {
91
- return this.#failure;
92
- }
93
- setFailureHandler(handler) {
94
- this.#onFailure = handler;
95
- }
96
- requestDataRange(begin, end) {
97
- if (this.#aborted)
98
- return;
99
- const controller = new AbortController();
100
- this.#controllers.add(controller);
101
- void fetch(this.#url, {
102
- signal: controller.signal,
103
- cache: "no-store",
104
- headers: { Range: formatPdfRangeHeader(begin, end) },
105
- })
106
- .then(async (response) => {
107
- if (response.status !== 206) {
108
- throw new Error(`PDF custom range failed for [${begin}, ${end}): expected 206, got ${response.status}`);
109
- }
110
- const bytes = new Uint8Array(await response.arrayBuffer());
111
- const expected = end - begin;
112
- const range = parseContentRange(response.headers.get("content-range"));
113
- if (!range ||
114
- range.begin !== begin ||
115
- range.end !== end - 1 ||
116
- range.total !== this.#length) {
117
- throw new Error(`PDF custom range returned invalid Content-Range for [${begin}, ${end})`);
118
- }
119
- if (bytes.byteLength !== expected) {
120
- throw new Error(`PDF custom range returned ${bytes.byteLength} bytes for [${begin}, ${end}); expected ${expected}`);
121
- }
122
- if (!this.#aborted)
123
- this.onDataRange(begin, bytes);
124
- })
125
- .catch((error) => {
126
- if (this.#aborted || error?.name === "AbortError")
127
- return;
128
- const failure = error instanceof Error
129
- ? error
130
- : new Error(String(error?.message ?? error));
131
- this.#failure = failure;
132
- this.#onFailure?.(failure);
133
- })
134
- .finally(() => {
135
- this.#controllers.delete(controller);
136
- });
137
- }
138
- abort() {
139
- if (this.#aborted)
140
- return;
141
- this.#aborted = true;
142
- for (const controller of this.#controllers)
143
- controller.abort();
144
- this.#controllers.clear();
145
- }
146
- }
147
- function commonOptions(wasmUrl) {
148
- return {
149
- wasmUrl,
150
- useWorkerFetch: false,
151
- // Only the deterministic benchmark pins OffscreenCanvas off. This transport also serves every
152
- // ordinary PDF load, and pdf.js's save path REQUIRES OffscreenCanvas to encode Stamp (image)
153
- // annotations: with it forced off, `saveDocument()` hands the stamp writer a null image and
154
- // throws ("Cannot destructure property 'imageRef'"), so every image-stamp save failed with
155
- // "annotations could not be serialized". Let pdf.js detect support in the real app.
156
- isOffscreenCanvasSupported: isPdfBenchEnabled()
157
- ? false
158
- : typeof OffscreenCanvas !== "undefined",
159
- isImageDecoderSupported: false,
160
- };
161
- }
162
- export async function preparePdfLoading({ url, mode, signal, wasmUrl, }) {
163
- let bufferResponse = null;
164
- if (mode === "buffer") {
165
- const response = await fetch(url, { signal });
166
- if (!response.ok) {
167
- throw new Error(`PDF fetch failed: ${response.status} ${response.statusText}`.trim());
168
- }
169
- if (shouldRangeLoadInsteadOfBuffer(response.headers.get("content-length"))) {
170
- void response.body?.cancel().catch(() => { });
171
- }
172
- else {
173
- bufferResponse = response;
174
- }
175
- }
176
- if (bufferResponse) {
177
- const response = bufferResponse;
178
- const data = new Uint8Array(await response.arrayBuffer());
179
- const task = pdfjs.getDocument(pdfDocumentInit(data, commonOptions(wasmUrl)));
180
- let disposed = false;
181
- const dispose = () => {
182
- if (disposed)
183
- return;
184
- disposed = true;
185
- void task.destroy();
186
- };
187
- signal.addEventListener("abort", dispose, { once: true });
188
- return { task, promise: task.promise, dispose };
189
- }
190
- if (mode === "url-native") {
191
- // Deliberately use PDF.js's own Fetch/XHR network stream with default stream/range behavior.
192
- const task = pdfjs.getDocument(pdfDocumentInit(url, { rangeChunkSize: RANGE_CHUNK_SIZE, ...commonOptions(wasmUrl) }));
193
- let disposed = false;
194
- const dispose = () => {
195
- if (disposed)
196
- return;
197
- disposed = true;
198
- void task.destroy();
199
- };
200
- signal.addEventListener("abort", dispose, { once: true });
201
- return { task, promise: task.promise, dispose };
202
- }
203
- const probe = await probePdfLength(url, signal);
204
- const transport = new HostPdfRangeTransport(url, probe.length, probe.initialData);
205
- const task = pdfjs.getDocument({
206
- range: transport,
207
- rangeChunkSize: RANGE_CHUNK_SIZE,
208
- disableRange: false,
209
- disableStream: true,
210
- ...commonOptions(wasmUrl),
211
- });
212
- transport.setFailureHandler((error) => {
213
- console.error("[pdf-bench] custom range transport failed", error);
214
- void task.destroy();
215
- });
216
- const promise = task.promise.catch((error) => {
217
- throw transport.failure ?? error;
218
- });
219
- let disposed = false;
220
- const dispose = () => {
221
- if (disposed)
222
- return;
223
- disposed = true;
224
- transport.abort();
225
- void task.destroy();
226
- };
227
- signal.addEventListener("abort", dispose, { once: true });
228
- return {
229
- task,
230
- promise,
231
- dispose,
232
- };
233
- }