@forgeroute/ui 0.3.11 → 0.3.13

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forgeroute/ui",
3
- "version": "0.3.11",
3
+ "version": "0.3.13",
4
4
  "peerDependencies": {
5
5
  "@angular/common": ">=22.0.0",
6
6
  "@angular/core": ">=22.0.0",
@@ -1,5 +1,5 @@
1
1
  import * as i0 from "@angular/core";
2
- import { InjectionToken } from "@angular/core";
2
+ import { EnvironmentProviders, InjectionToken } from "@angular/core";
3
3
  import { PDFDocumentProxy } from "pdfjs-dist";
4
4
  /** Where pdf.js finds its worker script. Provide it once in the app (`{ provide: PDF_VIEWER_WORKER_SRC, useValue: '/assets/pdf.worker.min.mjs' }`). */
5
5
  export declare const PDF_VIEWER_WORKER_SRC: InjectionToken<string>;
@@ -37,7 +37,7 @@ export interface PdfViewerRenderedEvent {
37
37
  pageWidths: number[];
38
38
  }
39
39
  type PdfJsModule = typeof import('pdfjs-dist');
40
- type Status = 'idle' | 'loading' | 'ready' | 'error';
40
+ type Status = 'idle' | 'loading' | 'ready' | 'error' | 'unsupported';
41
41
  interface PageView {
42
42
  number: number;
43
43
  cssWidth: number;
@@ -57,6 +57,33 @@ interface FieldView {
57
57
  height: number;
58
58
  fontPx: number;
59
59
  }
60
+ /**
61
+ * Language features the pdf.js modern build calls WITHOUT a polyfill or guard on the path every document takes, found by reading
62
+ * `pdfjs-dist/build/pdf.mjs` + `pdf.worker.mjs` of 5.7.284 (this library's dev copy) and 6.2.108 (the apps' copy). The `legacy/` build
63
+ * polyfills them; this component imports the modern one. Details and the evidence per feature: docs/pdf-viewer.md.
64
+ *
65
+ * - `Promise.withResolvers`, `Promise.try`: the main-thread API and the worker message handler (every message).
66
+ * - `Map.prototype.getOrInsertComputed`: per-page intent state and the object store on every render (6.x also in the message handler).
67
+ * - `Math.sumPrecise`: the worker, when it builds a font's name / glyf tables (every document with text).
68
+ * - `Iterator`: pdf.js 6.x touches `Iterator.prototype` while the module loads, so a browser without the global cannot even import it.
69
+ * - `URL.parse`: opening a document by URL (the stream choice and the worker origin check).
70
+ *
71
+ * Left out on purpose: `Worker` and `structuredClone` (pdf.js falls back to a main-thread worker that only needs one of them),
72
+ * `OffscreenCanvas` / `Float16Array` (feature-tested by pdf.js), `Uint8Array.fromBase64` / `toBase64` and `Iterator` helpers (XFA / editor / text-layer paths only).
73
+ */
74
+ export declare const PDF_VIEWER_REQUIRED_FEATURES: readonly ["Promise.withResolvers", "Promise.try", "Map.prototype.getOrInsertComputed", "Math.sumPrecise", "Iterator", "URL.parse"];
75
+ export type PdfViewerRequiredFeature = typeof PDF_VIEWER_REQUIRED_FEATURES[number];
76
+ /**
77
+ * Names of the required features `scope` (default: the global object) lacks; [] = pdf.js can run. Synchronous and
78
+ * side-effect free. `URL.parse` is only needed to open a URL, so it is skipped when `needsUrl` is false (bytes are given).
79
+ */
80
+ export declare function findMissingPdfFeatures(scope?: object, needsUrl?: boolean): PdfViewerRequiredFeature[];
81
+ /** Emitted by `loadFailed` when the browser lacks a feature pdf.js needs (nothing was loaded). */
82
+ export declare class PdfViewerUnsupportedError extends Error {
83
+ readonly missing: readonly PdfViewerRequiredFeature[];
84
+ readonly reason: "unsupported-browser";
85
+ constructor(missing: readonly PdfViewerRequiredFeature[]);
86
+ }
60
87
  /**
61
88
  * Renders every page of a PDF into a canvas (crisp on high-density screens), with optional labelled boxes overlaid in PDF coordinates.
62
89
  * Needs `pdfjs-dist` (loaded on first use, so it stays out of bundles that never show a PDF).
@@ -77,7 +104,11 @@ interface FieldView {
77
104
  * - `httpHeaders` and `withCredentials` apply to `src` only; they are not used when `data` is given.
78
105
  * - `fields[].id` is only a display / test hook; duplicates are tolerated. `httpHeaders` is compared by content, but a stable reference is still preferred.
79
106
  * - The worker-missing message is fixed text and ignores `errorText`, because it is a setup problem for the developer.
80
- * - Needs pdf.js 5 (`pdfjs-dist` >= 5), which needs Safari 17.4+; the legacy pdf.js build is not supported by this component.
107
+ * - Needs pdf.js 5 (`pdfjs-dist` >= 5); the legacy pdf.js build is not supported by this component.
108
+ * - Browser check: before pdf.js is imported, the viewer checks (once per load, synchronously) that the browser has the features
109
+ * `PDF_VIEWER_REQUIRED_FEATURES` lists. Without them it shows `unsupportedText` (role="status") and, when `src` is a URL, an
110
+ * "Open the document" link (new tab); `loadFailed` emits a `PdfViewerUnsupportedError` (`reason: 'unsupported-browser'`, `missing`).
111
+ * `[checkBrowserSupport]="false"` skips the check. See docs/pdf-viewer.md.
81
112
  * - The public typings reference `pdfjs-dist` types: apps that type-check the library without `pdfjs-dist` installed need `skipLibCheck` or the
82
113
  * package (the same trade-off as `@forgeroute/ui/charts` and chart.js).
83
114
  */
@@ -100,6 +131,12 @@ export declare class PdfViewerComponent {
100
131
  readonly ariaLabel: import("@angular/core").InputSignal<string>;
101
132
  readonly loadingText: import("@angular/core").InputSignal<string>;
102
133
  readonly errorText: import("@angular/core").InputSignal<string>;
134
+ /** Shown when the browser cannot run pdf.js (see `checkBrowserSupport`). */
135
+ readonly unsupportedText: import("@angular/core").InputSignal<string>;
136
+ /** Text of the link that opens `src` in a new tab on such a browser. */
137
+ readonly openText: import("@angular/core").InputSignal<string>;
138
+ /** Check for the browser features pdf.js needs before loading it; false = always try to load. */
139
+ readonly checkBrowserSupport: import("@angular/core").InputSignal<boolean>;
103
140
  readonly loaded: import("@angular/core").OutputEmitterRef<PdfViewerLoadedEvent>;
104
141
  readonly loadFailed: import("@angular/core").OutputEmitterRef<unknown>;
105
142
  readonly pagesRendered: import("@angular/core").OutputEmitterRef<PdfViewerRenderedEvent>;
@@ -107,7 +144,11 @@ export declare class PdfViewerComponent {
107
144
  private readonly pageSizes;
108
145
  private readonly containerWidth;
109
146
  private readonly customError;
147
+ /** The URL the "Open the document" link points at: `src` when no bytes are given. */
148
+ protected readonly openUrl: import("@angular/core").Signal<string>;
110
149
  protected readonly errorMessage: import("@angular/core").Signal<string>;
150
+ /** What the always-present live region announces: loading progress, or why no preview is shown (a live region that already exists is announced reliably; one inserted with its text is not). */
151
+ protected readonly liveText: import("@angular/core").Signal<string>;
111
152
  /** Changes exactly when some canvas bitmap changes size (and so is cleared). */
112
153
  private readonly drawKey;
113
154
  private readonly effectiveWidth;
@@ -131,6 +172,8 @@ export declare class PdfViewerComponent {
131
172
  constructor();
132
173
  /** Test seam: loads pdf.js on first use so apps that never show a PDF do not bundle or fetch it. */
133
174
  protected loadPdfJs(): Promise<PdfJsModule>;
175
+ /** Test seam: the required features this browser lacks. */
176
+ protected missingFeatures(needsUrl: boolean): readonly PdfViewerRequiredFeature[];
134
177
  private resolvedRatio;
135
178
  private widthFor;
136
179
  private startLoad;
@@ -198,9 +241,37 @@ export declare class PdfViewerComponent {
198
241
  "required": false;
199
242
  "isSignal": true;
200
243
  };
244
+ "unsupportedText": {
245
+ "alias": "unsupportedText";
246
+ "required": false;
247
+ "isSignal": true;
248
+ };
249
+ "openText": {
250
+ "alias": "openText";
251
+ "required": false;
252
+ "isSignal": true;
253
+ };
254
+ "checkBrowserSupport": {
255
+ "alias": "checkBrowserSupport";
256
+ "required": false;
257
+ "isSignal": true;
258
+ };
201
259
  }, {
202
260
  "loaded": "loaded";
203
261
  "loadFailed": "loadFailed";
204
262
  "pagesRendered": "pagesRendered";
205
263
  }, never, never, true, never>;
206
- }
264
+ }
265
+ export interface ForgeroutePdfOptions {
266
+ /** URL of the pdf.js worker script every `ui-pdf-viewer` in the app uses, e.g. `'/pdf.worker.min.mjs'`. Must not be blank. */
267
+ workerSrc: string;
268
+ }
269
+ /**
270
+ * Sets the pdf.js worker location once for the whole app (provides `PDF_VIEWER_WORKER_SRC`):
271
+ *
272
+ * providers: [provideForgeroutePdf({ workerSrc: '/pdf.worker.min.mjs' })]
273
+ *
274
+ * A `workerSrc` input on a viewer still wins over this value. Throws at provide time when `workerSrc` is blank, because a viewer
275
+ * without a worker can only show "PDF worker is not configured.".
276
+ */
277
+ export declare function provideForgeroutePdf(options: ForgeroutePdfOptions): EnvironmentProviders;