omni-viewer-core 0.4.0 → 0.5.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.
- package/README.md +28 -0
- package/dist/host/index.d.ts +14 -2
- package/dist/i18n/catalog.en.js +8 -0
- package/dist/i18n/catalog.ja.js +9 -1
- package/dist/i18n/catalog.ko.js +8 -0
- package/dist/i18n/catalog.zh-cn.js +8 -1
- package/dist/parsers/yaml/index.js +14 -2
- package/dist/parsers/yaml/self-loading.js +26 -14
- package/dist/registry/index.js +1 -1
- package/dist/styles/pdf.css +26 -0
- package/dist/styles/toml.css +1 -1
- package/dist/styles/yaml.css +1 -1
- package/dist/viewers/json/controller.js +13 -24
- package/dist/viewers/json/index.js +5 -1
- package/dist/viewers/markdown/index.d.ts +3 -2
- package/dist/viewers/markdown/index.js +29 -14
- package/dist/viewers/pdf/controller.d.ts +14 -2
- package/dist/viewers/pdf/controller.js +28 -10
- package/dist/viewers/pdf/index.d.ts +79 -8
- package/dist/viewers/pdf/index.js +363 -81
- package/dist/viewers/pdf/self-loading.d.ts +3 -3
- package/dist/viewers/pdf/styles.d.ts +1 -1
- package/dist/viewers/pdf/styles.js +26 -0
- package/dist/viewers/structured-styles.d.ts +1 -1
- package/dist/viewers/structured-styles.js +1 -1
- package/dist/viewers/structured.d.ts +1 -0
- package/dist/viewers/structured.js +5 -3
- package/dist/viewers/yaml/controller.js +48 -5
- package/package.json +2 -1
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
export const PDF_ZOOM_LEVELS = [
|
|
1
|
+
export const PDF_ZOOM_LEVELS = [
|
|
2
|
+
50, 75, 100, 125, 150, 175, 200, 225, 250, 275, 300
|
|
3
|
+
];
|
|
4
|
+
export const PDF_MIN_ZOOM = 25;
|
|
5
|
+
export const PDF_MAX_ZOOM = 400;
|
|
2
6
|
/**
|
|
3
7
|
* PDF.js commonly returns one client rect per text span, even for a single
|
|
4
8
|
* continuous selection. Join neighbouring spans on the same text line so
|
|
@@ -41,8 +45,18 @@ export function mergeHighlightRects(rects) {
|
|
|
41
45
|
return merged;
|
|
42
46
|
});
|
|
43
47
|
}
|
|
44
|
-
function
|
|
45
|
-
|
|
48
|
+
function normalizedZoomOptions(options) {
|
|
49
|
+
const requestedMin = Number.isFinite(options.minZoom) ? Math.round(options.minZoom) : PDF_MIN_ZOOM;
|
|
50
|
+
const requestedMax = Number.isFinite(options.maxZoom) ? Math.round(options.maxZoom) : PDF_MAX_ZOOM;
|
|
51
|
+
const min = Math.max(1, Math.min(requestedMin, requestedMax));
|
|
52
|
+
const max = Math.max(min, Math.max(requestedMin, requestedMax));
|
|
53
|
+
const source = options.zoomLevels ?? PDF_ZOOM_LEVELS;
|
|
54
|
+
const levels = [...new Set(source
|
|
55
|
+
.filter(Number.isFinite)
|
|
56
|
+
.map((level) => Math.round(level))
|
|
57
|
+
.filter((level) => level >= min && level <= max))]
|
|
58
|
+
.sort((a, b) => a - b);
|
|
59
|
+
return { levels: levels.length > 0 ? levels : [min, max], min, max };
|
|
46
60
|
}
|
|
47
61
|
/** Highest `pdf-a<n>` suffix among seeded ids, so new ids never collide. */
|
|
48
62
|
function maxSequence(annotations) {
|
|
@@ -59,10 +73,11 @@ function copyAnnotations(annotations) {
|
|
|
59
73
|
? { ...annotation, rects: annotation.rects.map((rect) => ({ ...rect })) }
|
|
60
74
|
: { ...annotation });
|
|
61
75
|
}
|
|
62
|
-
export function createPdfController(pageCount, seed) {
|
|
76
|
+
export function createPdfController(pageCount, seed, options = {}) {
|
|
63
77
|
const original = Array.from({ length: Math.max(0, Math.floor(pageCount)) }, (_, i) => i + 1);
|
|
64
78
|
const listeners = new Set();
|
|
65
|
-
|
|
79
|
+
const zoomOptions = normalizedZoomOptions(options);
|
|
80
|
+
let zoom = Math.max(zoomOptions.min, Math.min(zoomOptions.max, 100));
|
|
66
81
|
// A seeded order may only reference pages that still exist; an empty result
|
|
67
82
|
// falls back to the natural order so the document is never left blank.
|
|
68
83
|
const seededOrder = seed?.pageOrder?.filter((page) => page >= 1 && page <= original.length) ?? [];
|
|
@@ -95,6 +110,9 @@ export function createPdfController(pageCount, seed) {
|
|
|
95
110
|
savedSignature = signature();
|
|
96
111
|
return {
|
|
97
112
|
get state() { return state(); },
|
|
113
|
+
zoomLevels: zoomOptions.levels,
|
|
114
|
+
minZoom: zoomOptions.min,
|
|
115
|
+
maxZoom: zoomOptions.max,
|
|
98
116
|
subscribe(listener) { listeners.add(listener); return () => listeners.delete(listener); },
|
|
99
117
|
dispatch(action) {
|
|
100
118
|
if (action.type === 'undo') {
|
|
@@ -125,19 +143,19 @@ export function createPdfController(pageCount, seed) {
|
|
|
125
143
|
const beforeSignature = tracksHistory ? signature() : undefined;
|
|
126
144
|
switch (action.type) {
|
|
127
145
|
case 'zoom-in': {
|
|
128
|
-
zoom =
|
|
129
|
-
??
|
|
146
|
+
zoom = zoomOptions.levels.find((level) => level > zoom)
|
|
147
|
+
?? zoomOptions.max;
|
|
130
148
|
break;
|
|
131
149
|
}
|
|
132
150
|
case 'zoom-out': {
|
|
133
|
-
zoom = [...
|
|
134
|
-
??
|
|
151
|
+
zoom = [...zoomOptions.levels].reverse().find((level) => level < zoom)
|
|
152
|
+
?? zoomOptions.min;
|
|
135
153
|
break;
|
|
136
154
|
}
|
|
137
155
|
case 'set-zoom': {
|
|
138
156
|
if (!Number.isFinite(action.zoom))
|
|
139
157
|
return;
|
|
140
|
-
zoom = Math.max(
|
|
158
|
+
zoom = Math.max(zoomOptions.min, Math.min(zoomOptions.max, Math.round(action.zoom)));
|
|
141
159
|
break;
|
|
142
160
|
}
|
|
143
161
|
case 'reorder-pages': {
|
|
@@ -1,12 +1,73 @@
|
|
|
1
|
-
import type { FilePickService, FileSaveService, FileWritebackService, HostContext } from '../../host/index.js';
|
|
1
|
+
import type { FilePickService, FileSaveResult, FileSaveService, FileWritebackService, HostContext } from '../../host/index.js';
|
|
2
2
|
import { type MountOptions, type ViewerHandle, type ViewerInput } from '../types.js';
|
|
3
|
-
import { type PdfController } from './controller.js';
|
|
3
|
+
import { type PdfController, type PdfControllerOptions, type PdfViewState } from './controller.js';
|
|
4
4
|
import { type PdfLibModule } from './editing.js';
|
|
5
|
-
export { createPdfController, PDF_ZOOM_LEVELS } from './controller.js';
|
|
6
|
-
export type { PdfController, PdfAction, PdfViewState, PdfAnnotation } from './controller.js';
|
|
5
|
+
export { createPdfController, PDF_MAX_ZOOM, PDF_MIN_ZOOM, PDF_ZOOM_LEVELS } from './controller.js';
|
|
6
|
+
export type { PdfController, PdfControllerOptions, PdfAction, PdfViewState, PdfAnnotation } from './controller.js';
|
|
7
7
|
export { pdfViewerCss } from './styles.js';
|
|
8
|
-
export { buildEditedPdf, mergePdfBytes, savedPdfName } from './editing.js';
|
|
9
|
-
export type { PdfLibModule } from './editing.js';
|
|
8
|
+
export { buildEditedPdf, buildSavedPdf, mergePdfBytes, parseLayer, savedPdfName, SIDECAR_BASE_NAME, SIDECAR_LAYER_NAME } from './editing.js';
|
|
9
|
+
export type { ParsedLayer, PdfLibModule } from './editing.js';
|
|
10
|
+
/** Asset key passed to `HostContext.assets.resolveAssetUrl` by default. */
|
|
11
|
+
export declare const PDF_WORKER_ASSET_KEY = "assets/pdfjs/pdf.worker.min.mjs";
|
|
12
|
+
export type PdfSaveMode = 'hybrid' | 'flattened';
|
|
13
|
+
export type PdfProcessingMode = 'auto' | 'host' | 'browser';
|
|
14
|
+
export interface PdfToolbarAction {
|
|
15
|
+
id: string;
|
|
16
|
+
label: string;
|
|
17
|
+
title?: string;
|
|
18
|
+
ariaLabel?: string;
|
|
19
|
+
disabled?: boolean | (() => boolean);
|
|
20
|
+
onClick(): void | Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
export interface PdfProcessingControl {
|
|
23
|
+
signal: AbortSignal;
|
|
24
|
+
onProgress(progress: number | undefined): void;
|
|
25
|
+
}
|
|
26
|
+
/** Optional host/Worker implementation for byte-heavy PDF operations. */
|
|
27
|
+
export interface PdfProcessingService {
|
|
28
|
+
/** Request byte arrays are borrowed: implementations must not mutate or
|
|
29
|
+
* detach their buffers. A Worker adapter may copy/transfer internally. */
|
|
30
|
+
buildPdf?(request: {
|
|
31
|
+
source: Uint8Array;
|
|
32
|
+
state: PdfViewState;
|
|
33
|
+
mode: PdfSaveMode;
|
|
34
|
+
}, control: PdfProcessingControl): Promise<Uint8Array>;
|
|
35
|
+
mergePdfs?(request: {
|
|
36
|
+
first: Uint8Array;
|
|
37
|
+
second: Uint8Array;
|
|
38
|
+
}, control: PdfProcessingControl): Promise<Uint8Array>;
|
|
39
|
+
}
|
|
40
|
+
export type PdfOperationState = {
|
|
41
|
+
status: 'idle';
|
|
42
|
+
} | {
|
|
43
|
+
status: 'running';
|
|
44
|
+
kind: 'save' | 'save-as' | 'merge';
|
|
45
|
+
progress?: number;
|
|
46
|
+
} | {
|
|
47
|
+
status: 'succeeded';
|
|
48
|
+
kind: 'save' | 'save-as' | 'merge';
|
|
49
|
+
} | {
|
|
50
|
+
status: 'failed';
|
|
51
|
+
kind: 'save' | 'save-as' | 'merge';
|
|
52
|
+
error: string;
|
|
53
|
+
} | {
|
|
54
|
+
status: 'cancelled';
|
|
55
|
+
kind: 'save' | 'save-as' | 'merge';
|
|
56
|
+
};
|
|
57
|
+
export interface PdfMountOptions extends MountOptions, PdfControllerOptions {
|
|
58
|
+
/** Defaults to `hybrid` for v0.4 compatibility. */
|
|
59
|
+
saveMode?: PdfSaveMode;
|
|
60
|
+
/** `auto` delegates when a service method exists, `browser` always uses pdf-lib. */
|
|
61
|
+
processingMode?: PdfProcessingMode;
|
|
62
|
+
/** Maximum merge input requested from FilePickService. */
|
|
63
|
+
maxMergeBytes?: number;
|
|
64
|
+
toolbarActions?: readonly PdfToolbarAction[];
|
|
65
|
+
/** Safe default for VS Code CSP is false. */
|
|
66
|
+
isEvalSupported?: boolean;
|
|
67
|
+
/** Host-provided worker URL. Omit to resolve {@link PDF_WORKER_ASSET_KEY}. */
|
|
68
|
+
workerSrc?: string;
|
|
69
|
+
onSaveAsComplete?(result: FileSaveResult | void): void | Promise<void>;
|
|
70
|
+
}
|
|
10
71
|
/** Viewer metadata — single source for the registry codegen (DESIGN.md §7). */
|
|
11
72
|
export declare const PDF_VIEWER_META: {
|
|
12
73
|
id: string;
|
|
@@ -58,12 +119,13 @@ export interface PdfJsDocument {
|
|
|
58
119
|
}
|
|
59
120
|
export interface PdfJsLoadingTask {
|
|
60
121
|
promise: Promise<PdfJsDocument>;
|
|
61
|
-
destroy(): void
|
|
122
|
+
destroy(): void | Promise<void>;
|
|
62
123
|
}
|
|
63
124
|
export interface PdfJsModule {
|
|
64
125
|
getDocument(options: {
|
|
65
126
|
data: Uint8Array;
|
|
66
127
|
password?: string;
|
|
128
|
+
isEvalSupported?: boolean;
|
|
67
129
|
}): PdfJsLoadingTask;
|
|
68
130
|
GlobalWorkerOptions: {
|
|
69
131
|
workerSrc: string;
|
|
@@ -80,9 +142,18 @@ export interface PdfViewerDeps {
|
|
|
80
142
|
/** Editing dependency (save / save-as / merge / annotation stamping).
|
|
81
143
|
* Absent -> editing controls disabled with a reason. */
|
|
82
144
|
loadPdfLib?(): Promise<PdfLibModule>;
|
|
145
|
+
/** Host/extension-host/Web Worker implementation for large byte operations. */
|
|
146
|
+
processing?: PdfProcessingService;
|
|
83
147
|
}
|
|
84
148
|
export interface PdfViewerHandle extends ViewerHandle {
|
|
85
149
|
readonly controller: PdfController;
|
|
150
|
+
readonly operation: PdfOperationState;
|
|
86
151
|
isDirty(): boolean;
|
|
152
|
+
cancelOperation(): void;
|
|
153
|
+
refreshToolbarActions(): void;
|
|
87
154
|
}
|
|
88
|
-
export declare function
|
|
155
|
+
export declare function containPdfSignatureSize(width: number, height: number, maxWidth?: number, maxHeight?: number): {
|
|
156
|
+
width: number;
|
|
157
|
+
height: number;
|
|
158
|
+
};
|
|
159
|
+
export declare function mountPdfViewer(input: ViewerInput, container: HTMLElement, ctx: PdfViewerContext, deps: PdfViewerDeps, options?: PdfMountOptions): Promise<PdfViewerHandle>;
|