@silurus/ooxml 0.74.6 → 0.75.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 (47) hide show
  1. package/README.md +105 -6
  2. package/dist/bounded-raw-part-cache-BTfZD_Sz.js +1248 -0
  3. package/dist/{docx-DftZMp7R.js → document-pull-client-H80_E10V.js} +11165 -11517
  4. package/dist/docx-BX0mJqS1.js +1274 -0
  5. package/dist/docx.mjs +6 -3
  6. package/dist/docx_parser_bg.wasm +0 -0
  7. package/dist/duotone-bitmap-by-path-Dv5Ikbzl.js +28 -0
  8. package/dist/find-cursor-Dc5iM6s7.js +815 -0
  9. package/dist/highlight-rect-cCvVU-MW.js +48 -0
  10. package/dist/hyperlink-D85FexTa.js +27 -0
  11. package/dist/index.mjs +4 -4
  12. package/dist/{highlight-rect-IjFkGg4X.js → line-distribute-DkLgIa7B.js} +37 -84
  13. package/dist/{find-cursor-DtgyGs5V.js → line-metrics-qwIyTk7Q.js} +1169 -3641
  14. package/dist/math.mjs +1 -1
  15. package/dist/node.mjs +998 -0
  16. package/dist/pptx-BEYjiTnZ.js +822 -0
  17. package/dist/pptx-CXgyi7wu.js +1705 -0
  18. package/dist/pptx.mjs +7 -3
  19. package/dist/pptx_parser_bg.wasm +0 -0
  20. package/dist/preload-BEouWnlI.js +132 -0
  21. package/dist/render-C0wMf5eT.js +71 -0
  22. package/dist/render-worker-host-CLdOlxFu.js +27 -0
  23. package/dist/render-worker-host-DZ4u0RFs.js +27 -0
  24. package/dist/render-worker-host-s3J-mWBP.js +27 -0
  25. package/dist/renderer-CwzTv9hH.js +5225 -0
  26. package/dist/resource-measurement-6aReN3K0.js +93 -0
  27. package/dist/slide-pull-client-D_T0AIoX.js +175 -0
  28. package/dist/svg-image-by-path-C1M3N2pT.js +1623 -0
  29. package/dist/transfer-3QEJrsJa.js +6 -0
  30. package/dist/types/docx.d.ts +290 -105
  31. package/dist/types/index.d.ts +399 -142
  32. package/dist/types/math.d.ts +1 -1
  33. package/dist/types/node.d.ts +4855 -0
  34. package/dist/types/pptx.d.ts +431 -245
  35. package/dist/types/xlsx.d.ts +320 -120
  36. package/dist/visible-index-CKvgpUrf.js +17 -0
  37. package/dist/worksheet-pull-worker-DCei8u-4.js +347 -0
  38. package/dist/{xlsx-BqMHvfsE.js → xlsx-DJyPlzjB.js} +1499 -1284
  39. package/dist/xlsx.mjs +7 -3
  40. package/dist/xlsx_parser_bg.wasm +0 -0
  41. package/package.json +12 -2
  42. package/dist/pptx-qbadwIv4.js +0 -6761
  43. package/dist/render-worker-host-Bcm9j4-H.js +0 -27
  44. package/dist/render-worker-host-BqSTDaYt.js +0 -27
  45. package/dist/render-worker-host-C523QxVw.js +0 -27
  46. package/dist/visible-index-C3_3gBg-.js +0 -50
  47. /package/dist/{mathjax-BPjQ2C_j.js → mathjax-Dqo857oC.js} +0 -0
@@ -1,4 +1,4 @@
1
- //#region dist/.types-work/mathjax-6BV6bQWa.d.ts
1
+ //#region dist/.types-work/mathjax-BO1uUSCW.d.ts
2
2
  //#region packages/core/src/math/mathjax.d.ts
3
3
  interface MathSvg {
4
4
  /** standalone `<svg>…</svg>` markup. */
@@ -29,7 +29,7 @@ interface MathRenderer {
29
29
  mathMLToSvg(mathml: string): Promise<MathSvg>;
30
30
  }
31
31
  //#endregion
32
- //#region dist/.types-work/find-highlight-B8ft6Y0g.d.ts
32
+ //#region dist/.types-work/hyperlink-CHHEOeCL.d.ts
33
33
  //#region packages/core/src/types/math.d.ts
34
34
  type MathStyle = 'roman' | 'italic' | 'bold' | 'boldItalic';
35
35
  interface MathRun {
@@ -963,7 +963,157 @@ interface LegendManualLayout {
963
963
  h: number;
964
964
  }
965
965
  //#endregion
966
+ //#region packages/core/src/errors/ooxml-error.d.ts
967
+ /**
968
+ * Machine-readable code for a typed load-time failure.
969
+ *
970
+ * The container-level failures the `load()` factories detect on the main thread
971
+ * before handing bytes to the parser worker (see `sniffCfb` / `decryptOoxml`).
972
+ * This is the seed of the broader typed-error surface tracked as PD4 (OoxmlError
973
+ * typed errors). Add codes here rather than throwing bare `Error(string)`, so
974
+ * callers can `switch` on `err.code` instead of matching message text.
975
+ *
976
+ * - `'encrypted'` — password-protected, but no `password` was
977
+ * supplied (pass `LoadOptions.password` to decrypt).
978
+ * - `'invalid-password'` — a `password` was supplied but did not match.
979
+ * - `'unsupported-encryption'`— encrypted with a scheme other than Agile
980
+ * (Standard / Extensible / a legacy binary encryptor), which this library
981
+ * cannot decrypt (PD8 implements Agile only).
982
+ * - `'legacy-binary-format'` — a raw .doc / .xls / .ppt (not OOXML).
983
+ * - `'not-ooxml'` — a CFB of an unrecognised kind, or otherwise
984
+ * not an OOXML ZIP.
985
+ */
986
+ type OoxmlErrorCode = 'encrypted' | 'invalid-password' | 'unsupported-encryption' | 'legacy-binary-format' | 'not-ooxml';
987
+ type OoxmlErrorStage = 'container' | 'decompression' | 'parsing' | 'serialization' | 'layout' | 'rendering' | 'worker';
988
+ /**
989
+ * @deprecated Use {@link OoxmlErrorStage}. Retained as a compatibility alias
990
+ * for the short-lived resource-governance API that exposed this vocabulary;
991
+ * scheduled for removal in a future breaking release.
992
+ */
993
+ type OoxmlErrorSource = 'container' | 'zip-part' | 'parser' | 'serializer' | 'layout' | 'renderer' | 'worker';
994
+ /**
995
+ * Typed error thrown by the docx / pptx / xlsx `load()` factories for failures
996
+ * that carry a stable, programmatic {@link OoxmlErrorCode} (e.g. a
997
+ * password-protected or legacy-binary file detected from its container magic).
998
+ *
999
+ * Note on workers: `instanceof OoxmlError` does not survive a structured-clone
1000
+ * across the worker boundary. Detection that needs a typed error is therefore
1001
+ * done on the main thread (before the worker is involved) so a genuine
1002
+ * `OoxmlError` instance is thrown to the caller. Errors that must cross the
1003
+ * worker boundary should carry the `code` string and be reconstructed on the
1004
+ * main side.
1005
+ */
1006
+ declare class OoxmlError extends Error {
1007
+ readonly code: OoxmlErrorCode;
1008
+ constructor(code: OoxmlErrorCode, message: string);
1009
+ }
1010
+ type OoxmlFormat = 'docx' | 'xlsx' | 'pptx';
1011
+ interface OoxmlResourceUsageSnapshot {
1012
+ readonly archiveEntryCount: number;
1013
+ readonly declaredInflatedBytes: number;
1014
+ /** Largest actual decompressed size observed for one ZIP entry. */
1015
+ readonly largestInflatedEntryBytes?: number;
1016
+ readonly distinctInflatedBytes: number;
1017
+ readonly operationInflatedBytes: number;
1018
+ }
1019
+ type ExtensibleLiteral<Known extends string> = Known | (string & Record<never, never>);
1020
+ /**
1021
+ * Resource family reported by a policy or hard-quota violation.
1022
+ *
1023
+ * The known literals provide editor completion. The string tail is deliberate:
1024
+ * adding a future format-owned unit must not break exhaustive switches compiled
1025
+ * against an older host while a newer worker is already able to report it.
1026
+ */
1027
+ type OoxmlResourceName = ExtensibleLiteral<'archive' | 'archive-entry' | 'xml-event' | 'xml-context' | 'xml-tree' | 'worksheet-row' | 'worksheet-shell'>;
1028
+ /** Measurement axis used by an OOXML resource violation. Extensible by design. */
1029
+ type OoxmlResourceMetric = ExtensibleLiteral<'declared-inflated-bytes' | 'actual-inflated-bytes' | 'entry-count' | 'central-directory-bytes' | 'distinct-inflated-bytes' | 'bytes' | 'depth' | 'projected-bytes'>;
1030
+ /** Stable public violation record. Valid resource/metric pairings are enforced
1031
+ * by the emitting parser and the worker decoder rather than by a closed public
1032
+ * union that would require a breaking expansion for every new hard quota. */
1033
+ interface OoxmlResourceViolation {
1034
+ readonly format: OoxmlFormat;
1035
+ readonly operation: string;
1036
+ readonly resource: OoxmlResourceName;
1037
+ readonly metric: OoxmlResourceMetric;
1038
+ readonly part?: string;
1039
+ readonly limit: number;
1040
+ readonly observed: number;
1041
+ readonly configurable: boolean;
1042
+ readonly usage: OoxmlResourceUsageSnapshot;
1043
+ }
1044
+ interface OoxmlResourceLimitErrorDetails {
1045
+ readonly stage: OoxmlErrorStage;
1046
+ readonly violation: OoxmlResourceViolation;
1047
+ }
1048
+ /** Deterministic rejection caused by a measured OOXML resource-policy breach. */
1049
+ declare class OoxmlResourceLimitError extends Error {
1050
+ readonly code: "ooxml-resource-limit";
1051
+ readonly details: OoxmlResourceLimitErrorDetails;
1052
+ constructor(message: string, details: OoxmlResourceLimitErrorDetails);
1053
+ }
1054
+ //#endregion
1055
+ //#region packages/core/src/types/resource-metrics.d.ts
1056
+ /** Configured public admission policy used for one measured operation. */
1057
+ interface OoxmlResourcePolicySnapshot {
1058
+ readonly maxArchiveEntryBytes: number | null;
1059
+ readonly maxTotalInflatedBytes: number | null;
1060
+ }
1061
+ interface OoxmlResourceMetricsCheckpoint {
1062
+ readonly name: string;
1063
+ readonly elapsedMs: number;
1064
+ readonly usage?: OoxmlResourceUsageSnapshot;
1065
+ }
1066
+ /**
1067
+ * Content-free, machine-readable resource report for an OOXML load or bounded
1068
+ * Node session. Byte counters describe measured package work, not the JavaScript
1069
+ * heap, WASM allocator overhead, decoded images, canvas, or GPU. Browser engines
1070
+ * and Viewers can return a newer snapshot after lazy package access.
1071
+ *
1072
+ * No source URL, filename, OOXML part name, document text, password, or raw
1073
+ * error message is included. Sizes, counts, and timings are still
1074
+ * document-derived metadata; applications apply their own consent, retention,
1075
+ * and telemetry policy.
1076
+ */
1077
+ interface OoxmlResourceMetrics {
1078
+ /** Version of this metrics payload, independent of the package version. */
1079
+ readonly schemaVersion: 1;
1080
+ /**
1081
+ * Browser factories report `load`; bounded Node sessions report `session`.
1082
+ */
1083
+ readonly scope: 'load' | 'session';
1084
+ readonly format: OoxmlFormat;
1085
+ readonly mode: 'main' | 'worker' | 'node';
1086
+ /** Outcome of this measured load/session, not of later render operations. */
1087
+ readonly status: 'ok' | 'error';
1088
+ /** Compressed or decrypted OOXML container bytes supplied to the parser. */
1089
+ readonly sourceBytes?: number;
1090
+ readonly elapsedMs: number;
1091
+ readonly policy: Readonly<OoxmlResourcePolicySnapshot>;
1092
+ /** Last complete observed package-usage checkpoint. */
1093
+ readonly usage?: OoxmlResourceUsageSnapshot;
1094
+ readonly checkpoints: readonly OoxmlResourceMetricsCheckpoint[];
1095
+ readonly outcome?: Readonly<Record<string, number>>;
1096
+ readonly error?: Readonly<{
1097
+ readonly code?: string;
1098
+ readonly stage?: string;
1099
+ readonly resource?: string;
1100
+ readonly metric?: string;
1101
+ }>;
1102
+ }
1103
+ //#endregion
966
1104
  //#region packages/core/src/types/load-options.d.ts
1105
+ /** A positive safe-integer byte count, or `null` to disable one public limit. */
1106
+ type OoxmlResourceLimit = number | null;
1107
+ /** Admission limits for the inflated contents of one OOXML package session. */
1108
+ interface OoxmlResourceLimits {
1109
+ /**
1110
+ * Maximum permitted inflated size for any one archive entry, including
1111
+ * media. Enforced against both the ZIP declaration and actual output.
1112
+ */
1113
+ maxArchiveEntryBytes?: OoxmlResourceLimit;
1114
+ /** Maximum actual inflated bytes across distinct entries in the session. */
1115
+ maxTotalInflatedBytes?: OoxmlResourceLimit;
1116
+ }
967
1117
  /**
968
1118
  * Common load-time options shared by the docx / pptx / xlsx
969
1119
  * `Document.load` / `Presentation.load` / `Workbook.load` factories and their
@@ -1030,12 +1180,44 @@ interface LoadOptions$1 {
1030
1180
  */
1031
1181
  wasmUrl?: string | URL;
1032
1182
  /**
1033
- * Override the per-entry ZIP decompression cap (bytes) used by the zip-bomb
1034
- * guard in the Rust parser. Defaults to 512 MiB. Raise it to load documents
1035
- * with very large embedded media, or lower it to tighten the budget for
1036
- * untrusted input. Zero / negative values fall back to the default.
1183
+ * @deprecated Use `resourceLimits.maxArchiveEntryBytes`. Scheduled for
1184
+ * removal in a future breaking release.
1185
+ *
1186
+ * Existing positive safe-integer values remain an all-entry inflated-byte
1187
+ * limit. Zero, negative, and NaN values retain their historical fallback
1188
+ * behavior; other invalid positive values reject during `load()`.
1037
1189
  */
1038
1190
  maxZipEntryBytes?: number;
1191
+ /**
1192
+ * Inflated archive admission limits for one document session. Omitted fields
1193
+ * use the library defaults. A positive safe integer overrides a default;
1194
+ * `null` disables that configurable limit only. Limits are admission policy,
1195
+ * not guarantees of exact browser-process memory use.
1196
+ */
1197
+ resourceLimits?: OoxmlResourceLimits;
1198
+ /**
1199
+ * Emit one content-free resource-usage card after load succeeds or fails.
1200
+ * Includes observed archive counters and configured limits, but never source
1201
+ * URLs, part names, document text, passwords, or error messages.
1202
+ */
1203
+ debug?: boolean;
1204
+ /**
1205
+ * Receive the initial content-free, machine-readable report that powers the
1206
+ * debug card, without enabling console output. After resource options validate,
1207
+ * the callback runs once when the current load settles, including failed loads
1208
+ * for which no renderer instance is returned. The callback is not awaited;
1209
+ * synchronous exceptions and rejected promises are ignored and never change
1210
+ * load results.
1211
+ *
1212
+ * A browser report covers the underlying document/workbook/presentation
1213
+ * factory. It does not wait for a Viewer's first canvas paint; that paint and
1214
+ * later lazy worksheet, slide, image, or media access may increase counters or
1215
+ * surface a separate render error. Successfully opened packages include the
1216
+ * declared package total and source byte size in the report. On a successful
1217
+ * load, call `getResourceMetrics()` on the returned engine or Viewer for a fresh
1218
+ * snapshot that includes subsequently observed lazy package work.
1219
+ */
1220
+ onResourceMetrics?: (metrics: OoxmlResourceMetrics) => void;
1039
1221
  /**
1040
1222
  * Reject the parse request if the parser worker does not answer within this
1041
1223
  * many milliseconds. Opt-in safety net for a wedged or crashed worker that
@@ -1058,155 +1240,17 @@ interface LoadOptions$1 {
1058
1240
  math?: MathRenderer;
1059
1241
  }
1060
1242
  //#endregion
1061
- //#region packages/core/src/errors/ooxml-error.d.ts
1062
- /**
1063
- * Machine-readable code for a typed load-time failure.
1064
- *
1065
- * The container-level failures the `load()` factories detect on the main thread
1066
- * before handing bytes to the parser worker (see `sniffCfb` / `decryptOoxml`).
1067
- * This is the seed of the broader typed-error surface tracked as PD4 (OoxmlError
1068
- * typed errors). Add codes here rather than throwing bare `Error(string)`, so
1069
- * callers can `switch` on `err.code` instead of matching message text.
1070
- *
1071
- * - `'encrypted'` — password-protected, but no `password` was
1072
- * supplied (pass `LoadOptions.password` to decrypt).
1073
- * - `'invalid-password'` — a `password` was supplied but did not match.
1074
- * - `'unsupported-encryption'`— encrypted with a scheme other than Agile
1075
- * (Standard / Extensible / a legacy binary encryptor), which this library
1076
- * cannot decrypt (PD8 implements Agile only).
1077
- * - `'legacy-binary-format'` — a raw .doc / .xls / .ppt (not OOXML).
1078
- * - `'not-ooxml'` — a CFB of an unrecognised kind, or otherwise
1079
- * not an OOXML ZIP.
1080
- */
1081
- type OoxmlErrorCode = 'encrypted' | 'invalid-password' | 'unsupported-encryption' | 'legacy-binary-format' | 'not-ooxml';
1082
- /**
1083
- * Typed error thrown by the docx / pptx / xlsx `load()` factories for failures
1084
- * that carry a stable, programmatic {@link OoxmlErrorCode} (e.g. a
1085
- * password-protected or legacy-binary file detected from its container magic).
1086
- *
1087
- * Note on workers: `instanceof OoxmlError` does not survive a structured-clone
1088
- * across the worker boundary. Detection that needs a typed error is therefore
1089
- * done on the main thread (before the worker is involved) so a genuine
1090
- * `OoxmlError` instance is thrown to the caller. Errors that must cross the
1091
- * worker boundary should carry the `code` string and be reconstructed on the
1092
- * main side.
1093
- */
1094
- declare class OoxmlError extends Error {
1095
- readonly code: OoxmlErrorCode;
1096
- constructor(code: OoxmlErrorCode, message: string);
1097
- }
1098
- //#endregion
1099
- //#region packages/core/src/autoResize.d.ts
1100
- interface AutoResizeOptions {
1101
- /**
1102
- * Skip rendering while `document.hidden` is true and fire once with the latest
1103
- * observed size when the tab becomes visible again. Default: true.
1104
- */
1105
- pauseWhenHidden?: boolean;
1106
- }
1107
- /**
1108
- * Observe an element's size and invoke a render callback, coalescing bursts to
1109
- * one call per animation frame and serializing overlapping async renders.
1110
- *
1111
- * Framework-agnostic: call from any mount/setup hook and invoke the returned
1112
- * disposer in the corresponding teardown hook.
1113
- *
1114
- * @example
1115
- * const detach = autoResize(
1116
- * (width) => pres.renderSlide(canvas, 0, { width }),
1117
- * canvas,
1118
- * );
1119
- * // later
1120
- * detach();
1121
- */
1122
- declare function autoResize(render: (width: number, height: number) => void | Promise<void>, element: Element, opts?: AutoResizeOptions): () => void;
1123
- //#endregion
1124
- //#region packages/core/src/interaction/zoomable.d.ts
1125
- /**
1126
- * IX9 — the shared zoom API contract for every viewer (DocxViewer, PptxViewer,
1127
- * DocxScrollViewer, PptxScrollViewer, XlsxViewer).
1128
- *
1129
- * This module owns ONLY the pure, DOM-free pieces of the contract: the type
1130
- * ({@link ZoomableViewer}), the discrete zoom-step ladder ({@link nextZoomStep} /
1131
- * {@link prevZoomStep}), the fit-to-content scale math ({@link fitScale}), and the
1132
- * range clamp ({@link clampScale}). Each viewer implements the interface with its
1133
- * own scale field and re-render path; this keeps ONE definition of "what a zoom
1134
- * factor means" and "what the +/- steps are" across all five, so a host can drive
1135
- * any viewer through the same six calls without special-casing the format.
1136
- *
1137
- * SCALE SEMANTICS (the contract): a scale of `1` means 100% — the content at its
1138
- * natural size (a docx page at `widthPt × PT_TO_PX`, a pptx slide at
1139
- * `slideWidth / EMU_PER_PX`, an xlsx grid at `cellScale` 1). `getScale()` and
1140
- * `setScale(n)` speak this user-facing factor for EVERY viewer.
1141
- *
1142
- * KNOWN FAMILY DIFFERENCE — the INITIAL scale right after load (deliberate,
1143
- * documented rather than papered over): the single-canvas viewers (DocxViewer /
1144
- * PptxViewer) and XlsxViewer start at `1` (or the effective factor implied by an
1145
- * explicit `width` option); the continuous-scroll viewers (DocxScrollViewer /
1146
- * PptxScrollViewer) AUTO-FIT to the container on first layout, so their
1147
- * `getScale()` right after load reports the fit-to-width BASE factor (≠ 1 unless
1148
- * the container happens to match the natural width). The unit is identical — only
1149
- * the starting point differs, because fit-to-width is the natural resting state
1150
- * of a continuous document viewer.
1151
- *
1152
- * PRE-LOAD `setScale` (family-unified, IX9 F1): a `setScale` called before the
1153
- * content is loaded / before the layout is established is LATCHED — never
1154
- * silently dropped — and applied once the viewer establishes its scale (the
1155
- * single-canvas viewers honour it on the first render; the scroll viewers apply
1156
- * it right after the base fit establishes, firing `onScaleChange` at application
1157
- * time). `getScale()` reports the latched factor while it is pending.
1158
- *
1159
- * API SHAPE (idiomatic default — the integrator MAY veto; see the IX9 PR): a
1160
- * six-method surface plus one change notification (`onScaleChange`). Deliberately
1161
- * NO new UI here — the contract is API only (design decision IX9 §4). Touch-pinch
1162
- * (IX8) is out of scope.
1163
- */
1164
- /**
1165
- * The zoom contract every viewer satisfies. All scales are the user-facing factor
1166
- * where `1` = 100% (see the module note). `fitWidth`/`fitPage` are async because a
1167
- * fit re-renders at the new scale; the getters/steppers resolve synchronously.
1168
- */
1169
- interface ZoomableViewer {
1170
- /** The current zoom factor (`1` = 100%). Never throws — returns the default
1171
- * (`1`) before anything is loaded, or the latched pending factor when a
1172
- * pre-load `setScale` is waiting to be applied (see the module note). */
1173
- getScale(): number;
1174
- /** Set the absolute zoom factor (`1` = 100%), clamped to the viewer's
1175
- * `[zoomMin, zoomMax]`. Re-renders at the new scale and fires `onScaleChange`
1176
- * when the clamped value actually changes. Called BEFORE the content is
1177
- * loaded / the layout is established, the (clamped) factor is LATCHED and
1178
- * applied once the viewer establishes its scale — family-unified semantics
1179
- * (IX9 F1): never silently dropped by any viewer. */
1180
- setScale(scale: number): void | Promise<void>;
1181
- /** Step up to the next larger rung of the shared zoom ladder (25 %→400 %),
1182
- * clamped to `zoomMax`. Equivalent to `setScale(nextZoomStep(getScale()))`. */
1183
- zoomIn(): void | Promise<void>;
1184
- /** Step down to the next smaller ladder rung, clamped to `zoomMin`. */
1185
- zoomOut(): void | Promise<void>;
1186
- /** Fit the content's WIDTH to the container (the common "fit width" / "fit
1187
- * page width" verb). Sets the scale so one page/slide/sheet-column-run spans
1188
- * the available width, then re-renders. Resolves once the fit render settles.
1189
- *
1190
- * PERSISTENCE is viewer-implementation-dependent (deliberate, by family): the
1191
- * single-canvas viewers (DocxViewer / PptxViewer) and XlsxViewer apply the fit
1192
- * ONE-SHOT — they observe no container resizes, so a later resize does NOT
1193
- * re-fit (call `fitWidth()` again after a layout change). The continuous-
1194
- * scroll viewers (DocxScrollViewer / PptxScrollViewer) re-fit their width-fit
1195
- * base on every container resize, so a `fitWidth()` there effectively
1196
- * PERSISTS across resizes (the resize re-fit preserves the width-fit state). */
1197
- fitWidth(): void | Promise<void>;
1198
- /** Fit the WHOLE content (width AND height) inside the container, so an entire
1199
- * page/slide is visible without scrolling. Sets the scale to the smaller of the
1200
- * width- and height-fit factors, then re-renders.
1201
- *
1202
- * PERSISTENCE is viewer-implementation-dependent, and — unlike `fitWidth` —
1203
- * a page fit does NOT persist across container resizes on ANY viewer: the
1204
- * single-canvas viewers and XlsxViewer observe no resizes at all (one-shot),
1205
- * and the continuous-scroll viewers' resize handler re-applies the WIDTH fit
1206
- * (preserving the zoom multiplier), not the page fit. Re-invoke `fitPage()`
1207
- * after a layout change to re-fit. */
1208
- fitPage(): void | Promise<void>;
1209
- }
1243
+ //#region packages/core/src/image/pixel-budget.d.ts
1244
+ type OoxmlDecodedImageLimitMetric = 'image-pixels' | 'active-decoded-bytes';
1245
+ /** Catchable hard-quota crossing for decoded image surfaces. */
1246
+ declare class OoxmlDecodedImageLimitError extends RangeError {
1247
+ readonly metric: OoxmlDecodedImageLimitMetric;
1248
+ readonly limit: number;
1249
+ readonly observed: number;
1250
+ readonly code: "ooxml-decoded-image-limit";
1251
+ constructor(metric: OoxmlDecodedImageLimitMetric, limit: number, observed: number);
1252
+ }
1253
+ declare function isOoxmlDecodedImageLimitError(error: unknown): error is OoxmlDecodedImageLimitError;
1210
1254
  //#endregion
1211
1255
  //#region packages/core/src/interaction/hyperlink.d.ts
1212
1256
  /**
@@ -1270,81 +1314,7 @@ type HyperlinkTarget = {
1270
1314
  */
1271
1315
  declare function openExternalHyperlink(url: string, allowed?: readonly string[], win?: Pick<Window, 'open'> | undefined): boolean;
1272
1316
  //#endregion
1273
- //#region packages/core/src/search/text-index.d.ts
1274
- /**
1275
- * The slice of one run a match covers: the run's index in the original `runs[]`
1276
- * and the `[start, end)` character range within that run's own `text`. A match
1277
- * that straddles N runs yields N of these (the first sliced from its start
1278
- * offset to the run end, the last from 0 to its end offset, any middle run
1279
- * whole). The viewer measures each slice against that run's font to get a pixel
1280
- * rectangle.
1281
- */
1282
- interface MatchRunSlice {
1283
- /** Index into the original `runs[]` handed to {@link buildTextIndex}. */
1284
- runIndex: number;
1285
- /** Start offset within `runs[runIndex].text` (inclusive). */
1286
- start: number;
1287
- /** End offset within `runs[runIndex].text` (exclusive). */
1288
- end: number;
1289
- }
1290
- /** Options for {@link findMatches}. */
1291
- interface FindMatchesOptions {
1292
- /**
1293
- * Match case exactly. Default `false` (case-insensitive, like a browser's
1294
- * find-in-page). IX2 default — an integrator can pass `true`.
1295
- */
1296
- caseSensitive?: boolean;
1297
- }
1298
- //#endregion
1299
- //#region packages/core/src/search/find-match.d.ts
1300
- /**
1301
- * IX2 public find-result shape, shared by all three viewers.
1302
- *
1303
- * `findText` returns an ordered list of {@link FindMatch}. Every match carries
1304
- * its ordinal position (`matchIndex`, 0-based, document order — the same index
1305
- * `findNext` / `findPrev` cycle through), the matched `text`, and a
1306
- * format-specific `location`. The location is where the three formats
1307
- * legitimately differ — a docx match lives on a page, a pptx match on a slide,
1308
- * an xlsx match in a sheet cell — so `FindMatch` is generic over it rather than
1309
- * forcing an artificial common shape. Each viewer instantiates it with its own
1310
- * location type:
1311
- *
1312
- * - `DocxViewer.findText` → `FindMatch<DocxMatchLocation>` ({ page })
1313
- * - `PptxViewer.findText` → `FindMatch<PptxMatchLocation>` ({ slide })
1314
- * - `XlsxViewer.findText` → `FindMatch<XlsxMatchLocation>` ({ sheet, ref, … })
1315
- *
1316
- * The generic default is `unknown` so `FindMatch` can be referenced without a
1317
- * type argument (e.g. in generic UI code) while each viewer's return type stays
1318
- * precise.
1319
- */
1320
- interface FindMatch<Loc = unknown> {
1321
- /** 0-based ordinal among all matches, in document order. This is the index
1322
- * `findNext`/`findPrev` make active, so a caller can correlate the array it
1323
- * got from `findText` with the active-match reported by navigation. */
1324
- matchIndex: number;
1325
- /** The text that matched (the query as it appears in the document — its
1326
- * original case, not the folded form used for case-insensitive matching). */
1327
- text: string;
1328
- /** Where the match is, in the format's own coordinates. */
1329
- location: Loc;
1330
- }
1331
- //#endregion
1332
- //#region packages/core/src/search/find-highlight.d.ts
1333
- /**
1334
- * CSS colours used by in-document search overlays.
1335
- *
1336
- * The values are applied as the overlay backgrounds verbatim. Use an alpha
1337
- * colour (`rgba(...)`, 8-digit hex, or `color-mix(...)`) when the rendered text
1338
- * should remain visible through the highlight.
1339
- */
1340
- interface FindHighlightColors {
1341
- /** Background for every match except the active one. */
1342
- match?: string;
1343
- /** Background for the match selected by findNext/findPrev. */
1344
- active?: string;
1345
- }
1346
- //#endregion
1347
- //#region dist/.types-work/common-Bva7_XCn.d.ts
1317
+ //#region dist/.types-work/common-Bgczc_Eb.d.ts
1348
1318
  //#region packages/core/src/types/common.d.ts
1349
1319
  type PathCmd = {
1350
1320
  cmd: 'moveTo';
@@ -1816,7 +1786,194 @@ interface RenderOptions {
1816
1786
  skipMediaControls?: boolean;
1817
1787
  }
1818
1788
  //#endregion
1819
- //#region dist/.types-work/pptx-lmtZXJAj.d.ts
1789
+ //#region dist/.types-work/find-highlight-gMP3FAnW.d.ts
1790
+ //#region packages/core/src/autoResize.d.ts
1791
+ interface AutoResizeOptions {
1792
+ /**
1793
+ * Skip rendering while `document.hidden` is true and fire once with the latest
1794
+ * observed size when the tab becomes visible again. Default: true.
1795
+ */
1796
+ pauseWhenHidden?: boolean;
1797
+ }
1798
+ /**
1799
+ * Observe an element's size and invoke a render callback, coalescing bursts to
1800
+ * one call per animation frame and serializing overlapping async renders.
1801
+ *
1802
+ * Framework-agnostic: call from any mount/setup hook and invoke the returned
1803
+ * disposer in the corresponding teardown hook.
1804
+ *
1805
+ * @example
1806
+ * const detach = autoResize(
1807
+ * (width) => pres.renderSlide(canvas, 0, { width }),
1808
+ * canvas,
1809
+ * );
1810
+ * // later
1811
+ * detach();
1812
+ */
1813
+ declare function autoResize(render: (width: number, height: number) => void | Promise<void>, element: Element, opts?: AutoResizeOptions): () => void;
1814
+ //#endregion
1815
+ //#region packages/core/src/interaction/zoomable.d.ts
1816
+ /**
1817
+ * IX9 — the shared zoom API contract for every viewer (DocxViewer, PptxViewer,
1818
+ * DocxScrollViewer, PptxScrollViewer, XlsxViewer).
1819
+ *
1820
+ * This module owns ONLY the pure, DOM-free pieces of the contract: the type
1821
+ * ({@link ZoomableViewer}), the discrete zoom-step ladder ({@link nextZoomStep} /
1822
+ * {@link prevZoomStep}), the fit-to-content scale math ({@link fitScale}), and the
1823
+ * range clamp ({@link clampScale}). Each viewer implements the interface with its
1824
+ * own scale field and re-render path; this keeps ONE definition of "what a zoom
1825
+ * factor means" and "what the +/- steps are" across all five, so a host can drive
1826
+ * any viewer through the same six calls without special-casing the format.
1827
+ *
1828
+ * SCALE SEMANTICS (the contract): a scale of `1` means 100% — the content at its
1829
+ * natural size (a docx page at `widthPt × PT_TO_PX`, a pptx slide at
1830
+ * `slideWidth / EMU_PER_PX`, an xlsx grid at `cellScale` 1). `getScale()` and
1831
+ * `setScale(n)` speak this user-facing factor for EVERY viewer.
1832
+ *
1833
+ * KNOWN FAMILY DIFFERENCE — the INITIAL scale right after load (deliberate,
1834
+ * documented rather than papered over): the single-canvas viewers (DocxViewer /
1835
+ * PptxViewer) and XlsxViewer start at `1` (or the effective factor implied by an
1836
+ * explicit `width` option); the continuous-scroll viewers (DocxScrollViewer /
1837
+ * PptxScrollViewer) AUTO-FIT to the container on first layout, so their
1838
+ * `getScale()` right after load reports the fit-to-width BASE factor (≠ 1 unless
1839
+ * the container happens to match the natural width). The unit is identical — only
1840
+ * the starting point differs, because fit-to-width is the natural resting state
1841
+ * of a continuous document viewer.
1842
+ *
1843
+ * PRE-LOAD `setScale` (family-unified, IX9 F1): a `setScale` called before the
1844
+ * content is loaded / before the layout is established is LATCHED — never
1845
+ * silently dropped — and applied once the viewer establishes its scale (the
1846
+ * single-canvas viewers honour it on the first render; the scroll viewers apply
1847
+ * it right after the base fit establishes, firing `onScaleChange` at application
1848
+ * time). `getScale()` reports the latched factor while it is pending.
1849
+ *
1850
+ * API SHAPE (idiomatic default — the integrator MAY veto; see the IX9 PR): a
1851
+ * six-method surface plus one change notification (`onScaleChange`). Deliberately
1852
+ * NO new UI here — the contract is API only (design decision IX9 §4). Touch-pinch
1853
+ * (IX8) is out of scope.
1854
+ */
1855
+ /**
1856
+ * The zoom contract every viewer satisfies. All scales are the user-facing factor
1857
+ * where `1` = 100% (see the module note). `fitWidth`/`fitPage` are async because a
1858
+ * fit re-renders at the new scale; the getters/steppers resolve synchronously.
1859
+ */
1860
+ interface ZoomableViewer {
1861
+ /** The current zoom factor (`1` = 100%). Never throws — returns the default
1862
+ * (`1`) before anything is loaded, or the latched pending factor when a
1863
+ * pre-load `setScale` is waiting to be applied (see the module note). */
1864
+ getScale(): number;
1865
+ /** Set the absolute zoom factor (`1` = 100%), clamped to the viewer's
1866
+ * `[zoomMin, zoomMax]`. Re-renders at the new scale and fires `onScaleChange`
1867
+ * when the clamped value actually changes. Called BEFORE the content is
1868
+ * loaded / the layout is established, the (clamped) factor is LATCHED and
1869
+ * applied once the viewer establishes its scale — family-unified semantics
1870
+ * (IX9 F1): never silently dropped by any viewer. */
1871
+ setScale(scale: number): void | Promise<void>;
1872
+ /** Step up to the next larger rung of the shared zoom ladder (25 %→400 %),
1873
+ * clamped to `zoomMax`. Equivalent to `setScale(nextZoomStep(getScale()))`. */
1874
+ zoomIn(): void | Promise<void>;
1875
+ /** Step down to the next smaller ladder rung, clamped to `zoomMin`. */
1876
+ zoomOut(): void | Promise<void>;
1877
+ /** Fit the content's WIDTH to the container (the common "fit width" / "fit
1878
+ * page width" verb). Sets the scale so one page/slide/sheet-column-run spans
1879
+ * the available width, then re-renders. Resolves once the fit render settles.
1880
+ *
1881
+ * PERSISTENCE is viewer-implementation-dependent (deliberate, by family): the
1882
+ * single-canvas viewers (DocxViewer / PptxViewer) and XlsxViewer apply the fit
1883
+ * ONE-SHOT — they observe no container resizes, so a later resize does NOT
1884
+ * re-fit (call `fitWidth()` again after a layout change). The continuous-
1885
+ * scroll viewers (DocxScrollViewer / PptxScrollViewer) re-fit their width-fit
1886
+ * base on every container resize, so a `fitWidth()` there effectively
1887
+ * PERSISTS across resizes (the resize re-fit preserves the width-fit state). */
1888
+ fitWidth(): void | Promise<void>;
1889
+ /** Fit the WHOLE content (width AND height) inside the container, so an entire
1890
+ * page/slide is visible without scrolling. Sets the scale to the smaller of the
1891
+ * width- and height-fit factors, then re-renders.
1892
+ *
1893
+ * PERSISTENCE is viewer-implementation-dependent, and — unlike `fitWidth` —
1894
+ * a page fit does NOT persist across container resizes on ANY viewer: the
1895
+ * single-canvas viewers and XlsxViewer observe no resizes at all (one-shot),
1896
+ * and the continuous-scroll viewers' resize handler re-applies the WIDTH fit
1897
+ * (preserving the zoom multiplier), not the page fit. Re-invoke `fitPage()`
1898
+ * after a layout change to re-fit. */
1899
+ fitPage(): void | Promise<void>;
1900
+ }
1901
+ //#endregion
1902
+ //#region packages/core/src/search/text-index.d.ts
1903
+ /**
1904
+ * The slice of one run a match covers: the run's index in the original `runs[]`
1905
+ * and the `[start, end)` character range within that run's own `text`. A match
1906
+ * that straddles N runs yields N of these (the first sliced from its start
1907
+ * offset to the run end, the last from 0 to its end offset, any middle run
1908
+ * whole). The viewer measures each slice against that run's font to get a pixel
1909
+ * rectangle.
1910
+ */
1911
+ interface MatchRunSlice {
1912
+ /** Index into the original `runs[]` handed to {@link buildTextIndex}. */
1913
+ runIndex: number;
1914
+ /** Start offset within `runs[runIndex].text` (inclusive). */
1915
+ start: number;
1916
+ /** End offset within `runs[runIndex].text` (exclusive). */
1917
+ end: number;
1918
+ }
1919
+ /** Options for {@link findMatches}. */
1920
+ interface FindMatchesOptions {
1921
+ /**
1922
+ * Match case exactly. Default `false` (case-insensitive, like a browser's
1923
+ * find-in-page). IX2 default — an integrator can pass `true`.
1924
+ */
1925
+ caseSensitive?: boolean;
1926
+ }
1927
+ //#endregion
1928
+ //#region packages/core/src/search/find-match.d.ts
1929
+ /**
1930
+ * IX2 public find-result shape, shared by all three viewers.
1931
+ *
1932
+ * `findText` returns an ordered list of {@link FindMatch}. Every match carries
1933
+ * its ordinal position (`matchIndex`, 0-based, document order — the same index
1934
+ * `findNext` / `findPrev` cycle through), the matched `text`, and a
1935
+ * format-specific `location`. The location is where the three formats
1936
+ * legitimately differ — a docx match lives on a page, a pptx match on a slide,
1937
+ * an xlsx match in a sheet cell — so `FindMatch` is generic over it rather than
1938
+ * forcing an artificial common shape. Each viewer instantiates it with its own
1939
+ * location type:
1940
+ *
1941
+ * - `DocxViewer.findText` → `FindMatch<DocxMatchLocation>` ({ page })
1942
+ * - `PptxViewer.findText` → `FindMatch<PptxMatchLocation>` ({ slide })
1943
+ * - `XlsxViewer.findText` → `FindMatch<XlsxMatchLocation>` ({ sheet, ref, … })
1944
+ *
1945
+ * The generic default is `unknown` so `FindMatch` can be referenced without a
1946
+ * type argument (e.g. in generic UI code) while each viewer's return type stays
1947
+ * precise.
1948
+ */
1949
+ interface FindMatch<Loc = unknown> {
1950
+ /** 0-based ordinal among all matches, in document order. This is the index
1951
+ * `findNext`/`findPrev` make active, so a caller can correlate the array it
1952
+ * got from `findText` with the active-match reported by navigation. */
1953
+ matchIndex: number;
1954
+ /** The text that matched (the query as it appears in the document — its
1955
+ * original case, not the folded form used for case-insensitive matching). */
1956
+ text: string;
1957
+ /** Where the match is, in the format's own coordinates. */
1958
+ location: Loc;
1959
+ }
1960
+ //#endregion
1961
+ //#region packages/core/src/search/find-highlight.d.ts
1962
+ /**
1963
+ * CSS colours used by in-document search overlays.
1964
+ *
1965
+ * The values are applied as the overlay backgrounds verbatim. Use an alpha
1966
+ * colour (`rgba(...)`, 8-digit hex, or `color-mix(...)`) when the rendered text
1967
+ * should remain visible through the highlight.
1968
+ */
1969
+ interface FindHighlightColors {
1970
+ /** Background for every match except the active one. */
1971
+ match?: string;
1972
+ /** Background for the match selected by findNext/findPrev. */
1973
+ active?: string;
1974
+ }
1975
+ //#endregion
1976
+ //#region dist/.types-work/pptx-B9ExAlcU.d.ts
1820
1977
  //#region packages/pptx/src/types.d.ts
1821
1978
  /**
1822
1979
  * Picture bullet — ECMA-376 §21.1.2.4.2 `<a:buBlip><a:blip r:embed>`. The
@@ -2515,18 +2672,22 @@ interface RenderSlideOptions {
2515
2672
  * await pres.renderSlide(canvas, 0, { width: 960 });
2516
2673
  */
2517
2674
  declare class PptxPresentation {
2675
+ private _metrics;
2518
2676
  private readonly _worker;
2519
2677
  private readonly _bridge;
2520
2678
  private _mode;
2521
- private _presentation;
2522
- private _meta;
2679
+ private _preflight;
2680
+ private _slides;
2681
+ private _slidePullClient;
2682
+ /** First fatal package/model violation for this presentation generation. */
2683
+ private _resourceFailure;
2523
2684
  /** Lazily-built `partName → slide index` map for internal hyperlink slide
2524
2685
  * jumps (IX-nav). Cleared on {@link destroy}; built on first
2525
- * {@link getSlideIndexByPartName}/{@link resolveInternalTarget} from either
2526
- * the parsed slides (main) or the worker meta's `partNames` (worker). */
2686
+ * {@link getSlideIndexByPartName}/{@link resolveInternalTarget} from the
2687
+ * common compact preflight in either render mode. */
2527
2688
  private _slidePartIndex;
2528
- private _mediaCache;
2529
- private _imageCache;
2689
+ /** One bounded retained-byte owner shared by images and media. */
2690
+ private readonly _rawParts;
2530
2691
  /** Google-Fonts `FontFace` objects this deck preloaded into `document.fonts`
2531
2692
  * (main mode only — in worker mode the worker owns them and terminates with
2532
2693
  * its own FontFaceSet). Released in {@link destroy} so they do not leak into
@@ -2538,11 +2699,14 @@ declare class PptxPresentation {
2538
2699
  * images for a shared zip path like ppt/media/image1.png). Reusing the same
2539
2700
  * reference across every render also lets those caches hit across slides. */
2540
2701
  private readonly _fetchImage;
2702
+ private readonly _fetchMedia;
2541
2703
  /** Opt-in OMML equation engine, injected once at {@link load}. Every
2542
2704
  * `renderSlide` / `presentSlide` reuses it — equations render when present,
2543
2705
  * and are skipped (engine tree-shaken) when omitted. */
2544
2706
  private _math;
2545
2707
  private constructor();
2708
+ private _assertResourceHealthy;
2709
+ private _rethrowWithResourceFailure;
2546
2710
  /** Parse a PPTX from URL or ArrayBuffer. */
2547
2711
  static load(source: string | ArrayBuffer, opts?: LoadOptions): Promise<PptxPresentation>;
2548
2712
  private _parse;
@@ -2585,8 +2749,7 @@ declare class PptxPresentation {
2585
2749
  * caller's policy (see {@link PptxViewer}'s `hiddenSlideMode` modes).
2586
2750
  */
2587
2751
  isHidden(slideIndex: number): boolean;
2588
- /** The per-slide `partName` array (`sldIdLst` order) from either the parsed
2589
- * model (main) or the worker meta (worker). Backs the lazy part-index map. */
2752
+ /** The compact preflight's per-slide `partName` array (`sldIdLst` order). */
2590
2753
  private _partNames;
2591
2754
  /** Lazily build (and cache) the `partName → index` map. Nulled by
2592
2755
  * {@link destroy} so a reused reference never serves a stale deck's indices. */
@@ -2598,7 +2761,7 @@ declare class PptxPresentation {
2598
2761
  * (`<a:hlinkClick action="ppaction://hlinksldjump" r:id>`, ECMA-376
2599
2762
  * §21.1.2.3.5) resolves against: the click's rel Target names a slide part, and
2600
2763
  * this turns it into the index a viewer can navigate to. Works in both `main`
2601
- * and `worker` mode (the part names ride along in the worker meta).
2764
+ * and `worker` mode through the same compact preflight contract.
2602
2765
  */
2603
2766
  getSlideIndexByPartName(partName: string): number | undefined;
2604
2767
  /**
@@ -2647,7 +2810,7 @@ declare class PptxPresentation {
2647
2810
  collectSlideRuns(slideIndex: number, width?: number): Promise<PptxTextRunInfo[]>;
2648
2811
  /**
2649
2812
  * Extract raw media bytes for a zip path referenced by {@link MediaElement}.
2650
- * Results are cached by path for the lifetime of this instance.
2813
+ * Results share a count- and byte-bounded cache with embedded images.
2651
2814
  */
2652
2815
  getMedia(mediaPath: string): Promise<Blob>;
2653
2816
  private _findMimeTypeForPath;
@@ -2655,10 +2818,13 @@ declare class PptxPresentation {
2655
2818
  * Extract raw bytes for an embedded image by zip path (e.g.
2656
2819
  * "ppt/media/image1.png"), wrapped in a Blob of the given MIME type. Mirrors
2657
2820
  * {@link getMedia}; results are cached by path for the lifetime of this
2658
- * instance. The renderer routes its `fetchImage` option here so images are
2821
+ * instance within a common count and byte budget. The renderer routes its `fetchImage` option here so images are
2659
2822
  * decoded lazily rather than inlined as base64 at parse time.
2660
2823
  */
2661
2824
  getImage(imagePath: string, mimeType: string): Promise<Blob>;
2825
+ /** Return a fresh content-free metrics snapshot, including lazy slide and
2826
+ * media work completed since load. */
2827
+ getResourceMetrics(): Promise<OoxmlResourceMetrics>;
2662
2828
  /**
2663
2829
  * Project the presentation to GitHub-flavoured markdown: title slides become
2664
2830
  * `#` headings, body shapes become nested bullets at each paragraph's `lvl`,
@@ -2693,7 +2859,19 @@ type HiddenSlideMode = 'show' | 'skip' | 'dim';
2693
2859
  interface PptxViewerOptions extends RenderOptions, LoadOptions {
2694
2860
  /** Called when a slide finishes rendering */
2695
2861
  onSlideChange?: (index: number, total: number) => void;
2696
- /** Called on parse, render, or embedded-media playback errors. */
2862
+ /**
2863
+ * Receives load failures plus asynchronous render or embedded-media failures
2864
+ * handled by the Viewer. Supplying this callback changes load-failure
2865
+ * delivery: `load()` invokes it and resolves; without it, the same load/parse
2866
+ * failure rejects `load()`. Viewer-managed failures invoke it, or fall back
2867
+ * to `console.error` when omitted.
2868
+ *
2869
+ * Stable cases can be narrowed with `OoxmlError`,
2870
+ * `OoxmlResourceLimitError`, or `OoxmlDecodedImageLimitError` re-exported by
2871
+ * this package. Other failures remain `Error` values; do not parse message
2872
+ * text as an API. A `code` of `parser-crashed` identifies a recognized WASM
2873
+ * trap, not a reliably classified OOM.
2874
+ */
2697
2875
  onError?: (err: Error) => void;
2698
2876
  /** IX9 zoom contract ({@link ZoomableViewer}) — the clamp range for
2699
2877
  * {@link PptxViewer.setScale} / `zoomIn` / `zoomOut` / `fitWidth` / `fitPage`,
@@ -2991,6 +3169,8 @@ declare class PptxViewer implements ZoomableViewer {
2991
3169
  * teardown. Mirrors the scroll viewers' `_reportRenderError` so all three
2992
3170
  * single-canvas viewers agree. */
2993
3171
  private _reportRenderError;
3172
+ /** Latest content-free resource metrics for the loaded presentation. */
3173
+ getResourceMetrics(): Promise<OoxmlResourceMetrics>;
2994
3174
  /**
2995
3175
  * Clean up the viewer and terminate the background worker.
2996
3176
  *
@@ -3131,7 +3311,11 @@ interface PptxScrollViewerOptions extends Omit<RenderSlideOptions, 'onTextRun'>,
3131
3311
  * `renderSlideToBitmap` rejections) and embedded-media fetch/decode/playback
3132
3312
  * failures. A failed slide is left blank rather than crashing the loop.
3133
3313
  * Without an `onError`, failures are logged via `console.error` so they are
3134
- * never fully silent. */
3314
+ * never fully silent. Stable cases can be narrowed with `OoxmlError`,
3315
+ * `OoxmlResourceLimitError`, or `OoxmlDecodedImageLimitError` re-exported by
3316
+ * this package. Other failures remain `Error` values; a `code` of
3317
+ * `parser-crashed` identifies a recognized WASM trap, not a reliably
3318
+ * classified OOM. */
3135
3319
  onError?: (err: Error) => void;
3136
3320
  /**
3137
3321
  * IX1 (design decision — NOT user-confirmed, integrator may veto). Fires on a
@@ -3645,6 +3829,8 @@ declare class PptxScrollViewer implements ZoomableViewer {
3645
3829
  */
3646
3830
  private _onResize;
3647
3831
  get topVisibleSlide(): number;
3832
+ /** Return the owning engine's latest content-free package-usage snapshot. */
3833
+ getResourceMetrics(): Promise<OoxmlResourceMetrics>;
3648
3834
  /**
3649
3835
  * Tear down the viewer: remove the DOM subtree and (only for a self-loaded
3650
3836
  * engine) destroy the engine. An injected engine is left intact — the caller
@@ -3719,4 +3905,4 @@ type PptxHighlightColors = FindHighlightColors;
3719
3905
  */
3720
3906
  declare function buildPptxHighlightLayer(layer: HTMLDivElement, runs: PptxTextRunInfo[], matches: PptxHighlightMatch[], cssWidth: number, cssHeight: number, measureForFont: (font: string) => (s: string) => number, colors?: PptxHighlightColors): void;
3721
3907
  //#endregion
3722
- export { type AutoResizeOptions, type Bevel3d, type BlipBullet, type Bullet, type Camera3d, type ChartElement, type ChartModel, type ChartSeries, type DimOptions, type Fill, type FillRect, type FindHighlightColors, type FindMatch, type FindMatchesOptions, type Glow, type GradientFill, type GradientStop, type HiddenSlideMode, type HyperlinkTarget, type ImageFill, type LightRig, type LineBreak, type LoadOptions, type MediaElement, type NoFill, OoxmlError, type OoxmlErrorCode, type Paragraph, type PathCmd, type PictureElement, type PptxComment, type PptxHighlightColors, type PptxHighlightMatch, type PptxMatchLocation, PptxPresentation, PptxScrollViewer, type PptxScrollViewerOptions, type PptxTextRunInfo, PptxViewer, type PptxViewerOptions, type Presentation, type PresentationHandle, type Reflection, type RenderOptions, type RenderSlideOptions, type RenderSlideToBitmapOptions, type Rot3d, type Scene3d, type Shadow, type ShapeElement, type Slide, type SlideElement, type SoftEdge, type SolidFill, type Sp3d, type SpaceLine, type Stroke, type TabStop, type TableCell, type TableElement, type TableRow, type TextBody, type TextRect, type TextRun, type TextRunCallback, type TextRunData, type TileInfo, autoResize, buildPptxHighlightLayer, buildPptxTextLayer, openExternalHyperlink, renderSlide };
3908
+ export { type AutoResizeOptions, type Bevel3d, type BlipBullet, type Bullet, type Camera3d, type ChartElement, type ChartModel, type ChartSeries, type DimOptions, type Fill, type FillRect, type FindHighlightColors, type FindMatch, type FindMatchesOptions, type Glow, type GradientFill, type GradientStop, type HiddenSlideMode, type HyperlinkTarget, type ImageFill, type LightRig, type LineBreak, type LoadOptions, type MediaElement, type NoFill, OoxmlDecodedImageLimitError, type OoxmlDecodedImageLimitMetric, OoxmlError, type OoxmlErrorCode, type OoxmlErrorSource, type OoxmlErrorStage, type OoxmlFormat, type OoxmlResourceLimit, OoxmlResourceLimitError, type OoxmlResourceLimitErrorDetails, type OoxmlResourceLimits, type OoxmlResourceMetric, type OoxmlResourceMetrics, type OoxmlResourceMetricsCheckpoint, type OoxmlResourceName, type OoxmlResourcePolicySnapshot, type OoxmlResourceUsageSnapshot, type OoxmlResourceViolation, type Paragraph, type PathCmd, type PictureElement, type PptxComment, type PptxHighlightColors, type PptxHighlightMatch, type PptxMatchLocation, PptxPresentation, PptxScrollViewer, type PptxScrollViewerOptions, type PptxTextRunInfo, PptxViewer, type PptxViewerOptions, type Presentation, type PresentationHandle, type Reflection, type RenderOptions, type RenderSlideOptions, type RenderSlideToBitmapOptions, type Rot3d, type Scene3d, type Shadow, type ShapeElement, type Slide, type SlideElement, type SoftEdge, type SolidFill, type Sp3d, type SpaceLine, type Stroke, type TabStop, type TableCell, type TableElement, type TableRow, type TextBody, type TextRect, type TextRun, type TextRunCallback, type TextRunData, type TileInfo, autoResize, buildPptxHighlightLayer, buildPptxTextLayer, isOoxmlDecodedImageLimitError, openExternalHyperlink, renderSlide };