@embedpdf/engine-core 3.0.0-next.14 → 3.0.0-next.15

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 (134) hide show
  1. package/dist/AnnotationList-CkijRHet.d.cts +27163 -0
  2. package/dist/AnnotationList-CkijRHet.d.ts +27163 -0
  3. package/dist/Change-CKoxfTNY.js +889 -0
  4. package/dist/Change-CKoxfTNY.js.map +1 -0
  5. package/dist/Change-CjImsrN0.cjs +1020 -0
  6. package/dist/Change-CjImsrN0.cjs.map +1 -0
  7. package/dist/DocumentRenderService-BfFdFSwI.cjs +120 -0
  8. package/dist/DocumentRenderService-BfFdFSwI.cjs.map +1 -0
  9. package/dist/DocumentRenderService-DV3J9lMz.js +85 -0
  10. package/dist/DocumentRenderService-DV3J9lMz.js.map +1 -0
  11. package/dist/{DocumentSecurityService-Ca6EK3-3.d.ts → DocumentSecurityService-CU1M6Q7m.d.ts} +100 -112
  12. package/dist/{DocumentSecurityService-CIx1MT0T.d.cts → DocumentSecurityService-e6vp2de8.d.cts} +100 -112
  13. package/dist/LocalDocumentHandle-D02FMm-Z.cjs +53 -0
  14. package/dist/LocalDocumentHandle-D02FMm-Z.cjs.map +1 -0
  15. package/dist/LocalDocumentHandle-DAPdaOt_.js +30 -0
  16. package/dist/LocalDocumentHandle-DAPdaOt_.js.map +1 -0
  17. package/dist/LocalEngine-DFoBm4B3.d.cts +1565 -0
  18. package/dist/LocalEngine-DPriFujS.d.ts +1565 -0
  19. package/dist/PageInsertBlankInput-CXHAM7l6.cjs +17 -0
  20. package/dist/PageInsertBlankInput-CXHAM7l6.cjs.map +1 -0
  21. package/dist/PageInsertBlankInput-DhVYVJ_S.js +12 -0
  22. package/dist/PageInsertBlankInput-DhVYVJ_S.js.map +1 -0
  23. package/dist/authority-B3BklsB4.js +2239 -0
  24. package/dist/authority-B3BklsB4.js.map +1 -0
  25. package/dist/{viewport-BWeNHZmb.cjs → authority-DLMNR7ff.cjs} +820 -1647
  26. package/dist/authority-DLMNR7ff.cjs.map +1 -0
  27. package/dist/builders-CNj0POeY.js +161 -0
  28. package/dist/builders-CNj0POeY.js.map +1 -0
  29. package/dist/builders-Cgdp_YCn.cjs +184 -0
  30. package/dist/builders-Cgdp_YCn.cjs.map +1 -0
  31. package/dist/calibrate-7T3fnP8-.js +2404 -0
  32. package/dist/calibrate-7T3fnP8-.js.map +1 -0
  33. package/dist/calibrate-DJBXnhLE.cjs +2919 -0
  34. package/dist/calibrate-DJBXnhLE.cjs.map +1 -0
  35. package/dist/charmap-Cprti1ta.js +239 -0
  36. package/dist/charmap-Cprti1ta.js.map +1 -0
  37. package/dist/charmap-aYlefQP9.cjs +304 -0
  38. package/dist/charmap-aYlefQP9.cjs.map +1 -0
  39. package/dist/conformance.cjs +16466 -5247
  40. package/dist/conformance.cjs.map +1 -1
  41. package/dist/conformance.d.cts +924 -165
  42. package/dist/conformance.d.ts +924 -165
  43. package/dist/conformance.js +16429 -5252
  44. package/dist/conformance.js.map +1 -1
  45. package/dist/format-Bp3QFSH1.cjs +574 -0
  46. package/dist/format-Bp3QFSH1.cjs.map +1 -0
  47. package/dist/format-Dgg428Kb.js +461 -0
  48. package/dist/format-Dgg428Kb.js.map +1 -0
  49. package/dist/index.cjs +323 -116
  50. package/dist/index.d.cts +2 -2
  51. package/dist/index.d.ts +2 -2
  52. package/dist/index.js +14 -5
  53. package/dist/pageRefs-B3ur7Ckm.cjs +51 -0
  54. package/dist/pageRefs-B3ur7Ckm.cjs.map +1 -0
  55. package/dist/pageRefs-DkbuxSCV.js +40 -0
  56. package/dist/pageRefs-DkbuxSCV.js.map +1 -0
  57. package/dist/public.cjs +57 -0
  58. package/dist/public.d.cts +5 -0
  59. package/dist/public.d.ts +5 -0
  60. package/dist/public.js +9 -0
  61. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs +3646 -0
  62. package/dist/resolveAnnotationDraft-7Ke4nV7F.cjs.map +1 -0
  63. package/dist/resolveAnnotationDraft-CUpf0SMh.js +3167 -0
  64. package/dist/resolveAnnotationDraft-CUpf0SMh.js.map +1 -0
  65. package/dist/{resolver-inAVzsWt.js → resolver-CzxmD9Ck.js} +294 -144
  66. package/dist/resolver-CzxmD9Ck.js.map +1 -0
  67. package/dist/{resolver-CYVNV4hn.cjs → resolver-D2OCtE8F.cjs} +347 -143
  68. package/dist/resolver-D2OCtE8F.cjs.map +1 -0
  69. package/dist/runtime-Cl0v56mm.d.ts +2032 -0
  70. package/dist/runtime-p1WDzDo4.d.cts +2032 -0
  71. package/dist/runtime.cjs +726 -297
  72. package/dist/runtime.cjs.map +1 -1
  73. package/dist/runtime.d.cts +5 -1372
  74. package/dist/runtime.d.ts +5 -1372
  75. package/dist/runtime.js +396 -179
  76. package/dist/runtime.js.map +1 -1
  77. package/dist/schema-C-gU4vj7.cjs +3034 -0
  78. package/dist/schema-C-gU4vj7.cjs.map +1 -0
  79. package/dist/schema-DzlUNk38.js +2081 -0
  80. package/dist/schema-DzlUNk38.js.map +1 -0
  81. package/dist/schemas-Berf1swF.cjs +2481 -0
  82. package/dist/schemas-Berf1swF.cjs.map +1 -0
  83. package/dist/schemas-D6xOGjqg.js +1654 -0
  84. package/dist/schemas-D6xOGjqg.js.map +1 -0
  85. package/dist/subtype-CG4WpIRj.js +129 -0
  86. package/dist/subtype-CG4WpIRj.js.map +1 -0
  87. package/dist/subtype-aDt5TFmK.cjs +158 -0
  88. package/dist/subtype-aDt5TFmK.cjs.map +1 -0
  89. package/dist/validation.cjs +578 -0
  90. package/dist/validation.cjs.map +1 -0
  91. package/dist/validation.d.cts +174 -0
  92. package/dist/validation.d.ts +174 -0
  93. package/dist/validation.js +571 -0
  94. package/dist/validation.js.map +1 -0
  95. package/dist/value-BFS1R8ek.cjs +435 -0
  96. package/dist/value-BFS1R8ek.cjs.map +1 -0
  97. package/dist/value-Dhc8eYcx.js +340 -0
  98. package/dist/value-Dhc8eYcx.js.map +1 -0
  99. package/dist/viewport-BJW13EGZ.js +540 -0
  100. package/dist/viewport-BJW13EGZ.js.map +1 -0
  101. package/dist/viewport-DlL5Bxbg.cjs +671 -0
  102. package/dist/viewport-DlL5Bxbg.cjs.map +1 -0
  103. package/dist/wire.cjs +1051 -397
  104. package/dist/wire.cjs.map +1 -1
  105. package/dist/wire.d.cts +12403 -790
  106. package/dist/wire.d.ts +12403 -790
  107. package/dist/wire.js +821 -242
  108. package/dist/wire.js.map +1 -1
  109. package/package.json +10 -1
  110. package/dist/AbortError-DwuHPK_I.js +0 -27
  111. package/dist/AbortError-DwuHPK_I.js.map +0 -1
  112. package/dist/AbortError-P0RU0Mgg.cjs +0 -38
  113. package/dist/AbortError-P0RU0Mgg.cjs.map +0 -1
  114. package/dist/AnnotationListSnapshot-D9R5n2Kf.d.cts +0 -7101
  115. package/dist/AnnotationListSnapshot-D9R5n2Kf.d.ts +0 -7101
  116. package/dist/Engine-EWWHhEIi.d.ts +0 -1277
  117. package/dist/Engine-FNaAEjfb.d.cts +0 -1277
  118. package/dist/derive-BbsDk_Kz.cjs +0 -880
  119. package/dist/derive-BbsDk_Kz.cjs.map +0 -1
  120. package/dist/derive-DAFJolWu.js +0 -647
  121. package/dist/derive-DAFJolWu.js.map +0 -1
  122. package/dist/format-Bbphf4zR.js +0 -435
  123. package/dist/format-Bbphf4zR.js.map +0 -1
  124. package/dist/format-D_epWlob.cjs +0 -518
  125. package/dist/format-D_epWlob.cjs.map +0 -1
  126. package/dist/resolver-CYVNV4hn.cjs.map +0 -1
  127. package/dist/resolver-inAVzsWt.js.map +0 -1
  128. package/dist/schemas-CFQGvWiu.js +0 -3243
  129. package/dist/schemas-CFQGvWiu.js.map +0 -1
  130. package/dist/schemas-D0g6tKa9.cjs +0 -4694
  131. package/dist/schemas-D0g6tKa9.cjs.map +0 -1
  132. package/dist/viewport-BWeNHZmb.cjs.map +0 -1
  133. package/dist/viewport-CvMcadfQ.js +0 -3072
  134. package/dist/viewport-CvMcadfQ.js.map +0 -1
@@ -1,1277 +0,0 @@
1
- import { $a as FormFieldPatch, Au as SignaturePrepared, Bc as AnnotationAppearanceImagesResult, Bi as FormFieldDeleteResult, Ca as ChangeAnalysis, Ci as SearchRequest, Cr as RedactionApplyResult, Cu as SignatureAppearanceInput, Dr as PageInsertBlankSpec, Fo as AnnotationDeleteResult, Ga as FormSubmissionReceipt, Gc as AnnotationAppearanceRenderOptions, Gi as FormWidgetLinkResult, Gl as OpenInput, Hi as FormImportResult, Hr as PageNameResult, Io as AnnotationMoveResult, Ir as AnnotationFlattenResult, Is as AttachmentFileSource, Kd as DocumentActionsSnapshot, Kr as PageMoveResult, Lc as PdfSaveMode, Lo as AnnotationUpdateResult, Ls as EmbeddedFileItem, Nc as FontKey, Ns as AttachmentContent, Nu as SignatureSnapshot, Or as PageInsertResult, Pc as FontSpec, Po as AnnotationCreateResult, Ql as OpenOptions, Ra as FormEffect, Ri as FormDataExport, Rl as PageListSnapshot, Rs as EmbeddedFileRef, Su as SignatureAbortResult, Tu as SignatureCompleteResult, Ud as PdfRotation, Ui as FormRepairResult, Ur as PageNameInput, Uu as FormFieldRef, Va as FormEffectsResult, Vi as FormFieldUpdateResult, Vr as PageFlattenUsage, Wi as FormSetValueResult, Wl as MetadataPatch, Wr as PageRemoveNameInput, Wu as FormWidgetRef, Xa as FormFieldValue, Ya as FormDataFormat, Yc as PageImageHandle, Zc as PageImageOptions, _s as AttachmentDeleteResult, al as PageRenderOptions, ao as FormFieldDraft, cf as DocumentMetadata, cl as PageRenderViewport, fl as PageGeometrySnapshot, fo as FormSnapshot, fr as PdfMeasure, fu as BaseVersionInfo, gs as AttachmentCreateResult, jc as FontHandle, jn as PageScaleResult, jr as PageRotateResult, kr as PageDeleteResult, ku as SignaturePrepareInput, l as AnnotationPatch, n as AnnotationListSnapshotAllPages, o as AnnotationDraft, of as PageObjectNumber, pd as AnnotationRef, pu as DigestAlgorithm, qa as FormSubmissionRequest, qc as AnnotationAppearancesResult, t as AnnotationListPageSnapshot, tl as PageRaster, ur as PageMeasurementViewport, wi as SearchSlice, wr as RedactionApplyScope, wu as SignatureCompleteInput, xa as AnalyzeInput, xo as FormFieldDTO, xr as MetadataUpdateResult, yl as PageTextSnapshot, zc as AnnotationAppearanceImageOptions, zi as FormFieldCreateResult, zr as PageFlattenResult } from "./AnnotationListSnapshot-D9R5n2Kf.js";
2
- import { g as AbortablePromise, s as DocumentSecurityService } from "./DocumentSecurityService-Ca6EK3-3.js";
3
- //#region src/engine/DocumentActionsService.d.ts
4
- /** Lazy, catalog-owned PDF action read. This API extracts; it never executes. */
5
- interface DocumentActionsService {
6
- read(): AbortablePromise<DocumentActionsSnapshot>;
7
- }
8
- //#endregion
9
- //#region src/engine/DocumentAnnotationsService.d.ts
10
- interface WeakAnnotationEditSession {
11
- readonly id: string;
12
- readonly expiresAt: number;
13
- readonly heartbeatIntervalMs: number;
14
- readonly pageObjectNumbers: readonly PageObjectNumber[];
15
- covers(pageObjectNumber: PageObjectNumber): boolean;
16
- updatePages(pageObjectNumbers: readonly PageObjectNumber[]): AbortablePromise<void>;
17
- heartbeat(): AbortablePromise<void>;
18
- release(): AbortablePromise<void>;
19
- }
20
- /**
21
- * Document-scoped annotation service exposed via
22
- * `DocumentHandle.annotations`. The two read paths matter:
23
- *
24
- * `listRawAll()` - whole-doc raw read. No `pagePtr` is acquired; uses
25
- * `EPDFPage_GetAnnotCountRaw` + `EPDFPage_GetAnnotRaw`.
26
- * Cheapest possible path; ideal for "do anything with
27
- * a document" UX where the caller wants to know what's
28
- * where but does not need full per-subtype fields yet.
29
- *
30
- * `listRaw(p)` - single-page raw read. Same fast path scoped to one
31
- * page, by PDF object number.
32
- *
33
- * The slow per-subtype `pagePtr`-driven read lives on
34
- * `PageAnnotationsService.list()`.
35
- */
36
- interface DocumentAnnotationsService {
37
- listRawAll(): AbortablePromise<AnnotationListSnapshotAllPages>;
38
- listRaw(pageObjectNumber: PageObjectNumber): AbortablePromise<AnnotationListPageSnapshot>;
39
- beginWeakEdit(pageObjectNumbers: readonly PageObjectNumber[]): AbortablePromise<WeakAnnotationEditSession>;
40
- }
41
- //#endregion
42
- //#region src/engine/DocumentAttachmentsService.d.ts
43
- /**
44
- * Document-level attachments: the catalog's `/EmbeddedFiles` name tree
45
- * (ISO 32000 §7.11.4). Exposed via `DocumentHandle.attachments`.
46
- *
47
- * Addressing is by name-tree KEY (`EmbeddedFileRef`) — unique by
48
- * construction, so there is no weak/index tier and no revision to
49
- * validate (see the ref's doc comment). `list()` returns metadata only;
50
- * bytes leave the engine exclusively through {@link download}. The
51
- * annotation-level counterpart is
52
- * `PageAnnotationsService.downloadFile(ref)`.
53
- *
54
- * `create`/`delete` are optional (the `downloadLayer?` pattern) while
55
- * transports ship — feature-detect with `attachments.create !== undefined`.
56
- */
57
- interface DocumentAttachmentsService {
58
- /** Snapshot of the `/EmbeddedFiles` name tree, in tree (key-sorted) order. */
59
- list(): AbortablePromise<EmbeddedFileItem[]>;
60
- /**
61
- * Decode and return one embedded file's bytes plus the metadata needed
62
- * to hand it to a user (name, mime type). Throws
63
- * `EngineError(NotFound)` when no entry has the ref's key and
64
- * `EngineError(InvalidArg)` when the entry has no embedded file stream.
65
- */
66
- download(ref: EmbeddedFileRef): AbortablePromise<AttachmentContent>;
67
- /**
68
- * Create an embedded file in the name tree. The file's `name` becomes
69
- * the tree key (`/UF` = `/F` = key); a duplicate key rejects with
70
- * `EngineError(InvalidArg)` — rename and retry. A MUTATION: layer
71
- * sessions persist an artifact and an `attachment.created` event is
72
- * published. Note the tree is key-sorted, so other entries' indices
73
- * may shift; keys never move.
74
- */
75
- create?(file: AttachmentFileSource): AbortablePromise<AttachmentCreateResult>;
76
- /**
77
- * Delete an embedded file from the name tree. Unlinks the entry only —
78
- * the stream bytes remain in the document until a full rewrite (the
79
- * immutable-base/layer model). Throws `EngineError(NotFound)` for an
80
- * unknown key. A MUTATION: layer sessions persist an artifact and an
81
- * `attachment.deleted` event is published.
82
- */
83
- delete?(ref: EmbeddedFileRef): AbortablePromise<AttachmentDeleteResult>;
84
- }
85
- //#endregion
86
- //#region src/engine/DocumentFontSettings.d.ts
87
- /**
88
- * How much of a registered font's program the appearances authored in this
89
- * document carry. `default` subsets annotation text (FreeText, redaction
90
- * labels) and embeds form-field text whole; `subset` and `full` apply to
91
- * both. A font whose licence forbids subsetting is embedded whole under
92
- * every policy; programs already in the document are never re-embedded.
93
- */
94
- type FontEmbeddingPolicy = 'default' | 'subset' | 'full';
95
- /**
96
- * Per-document font and text-layout settings: session state of this
97
- * document handle, never written to the file, applied to appearances
98
- * generated after the call. Local engine only (`doc.fonts` is undefined on
99
- * engines that do not lay text out in-process).
100
- */
101
- interface DocumentFontSettings {
102
- setEmbeddingPolicy(policy: FontEmbeddingPolicy): AbortablePromise<void>;
103
- /**
104
- * Latin typographic features (kerning, ligatures) when shaping rich text.
105
- * Off by default: Acrobat's appearances show plain advance widths and no
106
- * ligatures, and parity with what Acrobat draws wins.
107
- */
108
- setTypographicFeatures(enabled: boolean): AbortablePromise<void>;
109
- }
110
- //#endregion
111
- //#region src/engine/DocumentFormsService.d.ts
112
- /** Options for {@link DocumentFormsService.repair}. */
113
- interface FormRepairOptions {
114
- /**
115
- * Also regenerate widget appearance streams: widgets with no /AP get
116
- * one, and when the /AcroForm sets /NeedAppearances every widget is
117
- * re-baked and the flag cleared, making rendering deterministic across
118
- * viewers.
119
- */
120
- bakeAppearances?: boolean;
121
- }
122
- /**
123
- * The document's interactive form: a document-scoped record system where
124
- * fields hold the values and widget annotations are their page-scoped
125
- * views. Filling mutates the field plane; rendering only ever reads the
126
- * widget plane (through the annotation subsystem — join widgets to
127
- * annotations via `FormFieldWidget.annotObjectNumber`).
128
- *
129
- * Reads are gated by `doc.forms.read`, value writes and imports by
130
- * `doc.forms.fill`, and repair by `doc.forms.modify`. On layer documents
131
- * every write lands as a minimal delta over the shared immutable base — a
132
- * filled form layer is semantically an FDF diff.
133
- */
134
- interface DocumentFormsService {
135
- /**
136
- * The complete reconciled form state: every terminal field with its
137
- * effective value, options, and widgets. Fields broken producers left
138
- * out of /AcroForm /Fields are included with `origin: 'recovered'`.
139
- */
140
- list(): AbortablePromise<FormSnapshot>;
141
- /**
142
- * One field by ref. Prefer `objectNumber` refs (durable); `fqn` refs
143
- * resolve against the current field tree. Fails with `NotFound` when
144
- * the ref matches nothing.
145
- */
146
- get(ref: FormFieldRef): AbortablePromise<FormFieldDTO>;
147
- /**
148
- * Write one field's value. The value's `type` must match the field
149
- * family (see {@link FormFieldValue}). Validation happens before any
150
- * write — a failed call leaves the document untouched. Appearance
151
- * streams regenerate for text/choice widgets; toggles flip their
152
- * appearance state. Emits `form.valueChanged`.
153
- */
154
- setValue(ref: FormFieldRef, value: FormFieldValue): AbortablePromise<FormSetValueResult>;
155
- /**
156
- * Restore a field to its default value (/DV), or clear it when no
157
- * default exists. Emits `form.valueChanged`.
158
- */
159
- reset(ref: FormFieldRef): AbortablePromise<FormSetValueResult>;
160
- /**
161
- * Apply one script run's ordered effects as one worker/cloud job. The batch
162
- * is not rollback-atomic. All references are preflighted before writes;
163
- * after a post-preflight internal failure the remaining effects are marked
164
- * skipped and any landed state is finalized as one artifact/event/version.
165
- */
166
- applyEffects?(effects: FormEffect[]): AbortablePromise<FormEffectsResult>;
167
- /**
168
- * Deliver a resolved form submission to the document's HOME. Present only
169
- * where the document HAS a home that accepts submissions — the cloud
170
- * engine when the deployment advertises the capability; the local engine
171
- * truthfully lacks it (an in-process document has no home, and this
172
- * contract is never a callback trampoline). Gated by `doc.forms.submit`
173
- * (grant-minted; no PDF permission bit exists for submission), asserted
174
- * at the home's boundary where enforcement is real. The home stores the
175
- * dataset with the declared intent as metadata and derives WHO submitted
176
- * from its own verified session — it never fetches the PDF's URL.
177
- */
178
- submit?(request: FormSubmissionRequest): AbortablePromise<FormSubmissionReceipt>;
179
- /**
180
- * Serialize the form data for interchange. Defaults to `'xfdf'` (the
181
- * XML sibling; UTF-8, friendliest to web pipelines) — pass `'fdf'` for
182
- * the PDF-native container. Exports read the same reconciled view as
183
- * `list()`, so recovered fields are included and, on layer documents,
184
- * filled values win over the base.
185
- */
186
- exportData(format?: FormDataFormat): AbortablePromise<FormDataExport>;
187
- /**
188
- * Apply an FDF or XFDF payload. The format is sniffed from the bytes
189
- * when `format` is omitted. Each entry replays through the same typed,
190
- * validated write path as `setValue` — one bad entry is skipped and
191
- * counted, never fatal. Emits `form.imported`.
192
- */
193
- importData(data: Uint8Array | ArrayBuffer, format?: FormDataFormat): AbortablePromise<FormImportResult>;
194
- /**
195
- * Create a logical form field, optionally with styled widgets, in one
196
- * atomic job. Widgets are born through the annotation plane and adopted
197
- * (see {@link attachWidget}); the inline `widget(s)` config is sugar for
198
- * exactly that composition. Gated by `doc.forms.modify`. Emits
199
- * `form.fieldCreated`.
200
- */
201
- createField(draft: FormFieldDraft): AbortablePromise<FormFieldCreateResult>;
202
- /**
203
- * Update field-plane properties (name, universal and family flags,
204
- * options, default value, names). The patch's `family` must match the
205
- * target field. Validate-then-apply per property. Emits
206
- * `form.fieldUpdated`.
207
- */
208
- updateField(ref: FormFieldRef, patch: FormFieldPatch): AbortablePromise<FormFieldUpdateResult>;
209
- /**
210
- * Draw a PDF page into every widget of an UNSIGNED signature field — the
211
- * visual "sign" of a viewer that has no signer. The field's value stays
212
- * empty and nothing is sealed; a signed field is refused. Gated by
213
- * `doc.forms.fill`. Emits `form.fieldUpdated`. Absent on engines that
214
- * cannot draw appearances.
215
- */
216
- setSignatureAppearance?(ref: FormFieldRef, appearance: SignatureAppearanceInput): AbortablePromise<FormFieldUpdateResult>;
217
- /**
218
- * Delete a terminal field and cascade: every widget is removed from its
219
- * page, the field leaves the tree, and empty ancestors are pruned.
220
- * Emits `form.fieldDeleted`.
221
- */
222
- deleteField(ref: FormFieldRef): AbortablePromise<FormFieldDeleteResult>;
223
- /**
224
- * Adopt an existing, unattached widget annotation as a view of the
225
- * field. `onState` names the checked appearance state and is required
226
- * for radio groups (checkboxes default to "Yes"). Attaching into a
227
- * legacy merged field splits it — the FIELD object number never
228
- * changes; widget identity may. Emits `form.widgetAttached`.
229
- */
230
- attachWidget(ref: FormFieldRef, widget: FormWidgetRef, options?: {
231
- onState?: string;
232
- }): AbortablePromise<FormWidgetLinkResult>;
233
- /**
234
- * The inverse of {@link attachWidget}: the widget keeps its page
235
- * placement and last appearance but becomes an ordinary, inert
236
- * annotation (deletable through the annotation APIs). The field
237
- * survives, "unplaced" when this was its last widget. Emits
238
- * `form.widgetDetached`.
239
- */
240
- detachWidget(ref: FormFieldRef, widget: FormWidgetRef): AbortablePromise<FormWidgetLinkResult>;
241
- /**
242
- * Make the engine's read-time reconciliation durable in the document
243
- * ("form doctor"): bootstrap a missing /AcroForm, link recovered field
244
- * roots into /Fields, re-attach stray widgets to their parent's /Kids,
245
- * and optionally bake appearances. Validate-then-apply and idempotent —
246
- * a second call reports zero fixes. Emits `form.repaired`.
247
- */
248
- repair(options?: FormRepairOptions): AbortablePromise<FormRepairResult>;
249
- }
250
- //#endregion
251
- //#region src/engine/DocumentPagesService.d.ts
252
- /**
253
- * Document-scoped page service exposed via `DocumentHandle.pages`.
254
- *
255
- * Mirrors the shape of `DocumentAnnotationsService` so that anything
256
- * touching "many things at the document level" lives in one place. The
257
- * structure verbs are `move`, `rotate`, and `delete`; the surface is
258
- * designed for `insert` to slot in without API churn.
259
- *
260
- * Identity rule: pages are addressed by indirect `pageObjectNumber`
261
- * everywhere except `list()`, which exposes display order through
262
- * `PageState.pageIndex`. There is no "weak page ref" model — structure
263
- * verbs therefore do not bump per-page revisions and do not invalidate
264
- * any in-flight annotation refs on surviving pages.
265
- */
266
- interface DocumentPagesService {
267
- /**
268
- * Snapshot of every page in display order. Cheap; never acquires a
269
- * `pagePtr`.
270
- */
271
- list(): AbortablePromise<PageListSnapshot>;
272
- /**
273
- * Reorder pages. The supplied pages are detached and re-inserted as
274
- * a contiguous block starting at `destIndex` in the post-removal
275
- * index space, preserving caller order. Per-page `RevisionToken`s
276
- * survive — index-based annotation refs the caller is holding remain
277
- * valid across a page reorder.
278
- *
279
- * @param pageObjectNumbers Pages to move, in the order they should
280
- * appear after the move.
281
- * @param destIndex Insertion point in `[0, pageCount - len]`.
282
- */
283
- move(pageObjectNumbers: PageObjectNumber[], destIndex: number): AbortablePromise<PageMoveResult>;
284
- /**
285
- * Set the ABSOLUTE display rotation of the supplied pages (one value
286
- * for all — the multi-select thumbnail gesture). Pure presentation
287
- * metadata: content coordinates are normalized, so cached renders,
288
- * annotation refs, and `RevisionToken`s all survive untouched. See
289
- * `PageRotateInput` for why the wire is absolute, never relative.
290
- */
291
- rotate(pageObjectNumbers: PageObjectNumber[], rotation: PdfRotation): AbortablePromise<PageRotateResult>;
292
- /**
293
- * Delete pages. Deleting every page is rejected (`InvalidArg`) — a
294
- * document must keep at least one. Deleted PONs are retired, never
295
- * recycled; surviving pages keep their identity and revisions.
296
- */
297
- delete(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<PageDeleteResult>;
298
- /**
299
- * Register `name` → page in the catalog's `/Names /Pages` tree (create,
300
- * or replace what an existing key points at); with `replace`, drop that
301
- * other key in the same job (rename). Named pages are LAYOUT — read them
302
- * back from `list().namedPages` — so this is a page-structure mutation:
303
- * `docVersion` + `layoutVersion` advance, per-page pins do not. Gated like
304
- * `move` (`doc.pages.assemble`). Optional while transports ship;
305
- * feature-detect with `pages.setName !== undefined`.
306
- *
307
- * Rejects with `InvalidArg` for an empty name and `NotFound` for a page
308
- * that is not in the page tree (hidden templates included).
309
- */
310
- setName?(input: PageNameInput): AbortablePromise<PageNameResult>;
311
- /**
312
- * Remove one `/Names /Pages` registration; the page itself is untouched.
313
- * `NotFound` when no registration has that decoded key. Page DELETION
314
- * removes registrations by itself — callers never need to pair the two.
315
- */
316
- removeName?(input: PageRemoveNameInput): AbortablePromise<PageNameResult>;
317
- /**
318
- * Paint eligible annotation appearances into page content and remove only
319
- * those annotations that were painted. This changes content and annotation
320
- * liveness, not layout. The default usage is normal display.
321
- */
322
- flatten?(pageObjectNumbers: PageObjectNumber[], usage?: PageFlattenUsage): AbortablePromise<PageFlattenResult>;
323
- /**
324
- * Export the given pages, in the supplied order, as a standalone PDF
325
- * (bytes of a new document containing copies of those pages). A READ:
326
- * the source document is untouched — no revisions bump, no event is
327
- * published. This is how a page becomes a portable asset (a vector
328
- * stamp, a signature) that re-enters a document as a stamp draft's
329
- * `source` bytes. Gated by `doc.download` (it egresses content), not
330
- * `doc.pages.assemble`.
331
- *
332
- * REQUIRED-parity, delivered: the local engine runs it in the worker,
333
- * the cloud engine as POST /pages/extract.
334
- */
335
- extract(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<Uint8Array>;
336
- /**
337
- * Insert every page of a standalone PDF (`bytes`) at `destIndex`
338
- * (omitted → append). The pages are COPIED in; the inserted copies get
339
- * fresh object numbers, returned in insertion order. Bytes are a call
340
- * ARGUMENT (the same law as annotation binaries): the local engine
341
- * transfers them to its worker, the cloud engine ships them as a
342
- * multipart mutation (POST /pages/insert).
343
- *
344
- * REQUIRED-parity, delivered — a cloud viewer must be able to add pages,
345
- * so this is a mandatory member: any engine implements it or is not a
346
- * conforming engine.
347
- */
348
- insert(bytes: Uint8Array | ArrayBuffer, destIndex?: number): AbortablePromise<PageInsertResult>;
349
- /**
350
- * Create `spec.count` (default 1) blank pages of `spec.size` (PDF points)
351
- * at `destIndex` (omitted → append). The blank-page sibling of `insert`:
352
- * same gate (`doc.pages.assemble`), same result shape, same
353
- * `pages.inserted` event — it is a separate verb because its wire is pure
354
- * parameters where `insert`'s is a binary payload (cloud: JSON
355
- * POST /pages/insert-blank). The new pages get fresh, never-recycled
356
- * object numbers; every pre-existing page keeps its identity and
357
- * revisions. Mandatory, like `insert`.
358
- */
359
- insertBlank(spec: PageInsertBlankSpec, destIndex?: number): AbortablePromise<PageInsertResult>;
360
- }
361
- //#endregion
362
- //#region src/engine/DocumentRedactionService.d.ts
363
- /**
364
- * The destructive half of the two-stage redaction model (ISO 32000-2
365
- * 12.5.6.23). MARKING is annotation-plane work: a `redact` annotation rides
366
- * the normal create/update/delete verbs and destroys nothing. APPLYING —
367
- * this service — permanently removes the content under each marked region,
368
- * paints the configured overlay in its place, and removes the consumed
369
- * REDACT annotations along with any annotation intersecting the region.
370
- *
371
- * Trust boundary (deliberate, documented): on a layered document, apply
372
- * rewrites THIS LAYER's bytes only. The immutable base document still
373
- * contains the original content — byte-perfect original recovery is a
374
- * feature of the storage model, not a leak. Redacted content becomes truly
375
- * unrecoverable only in a full-rewrite export after apply. Callers MUST select
376
- * `download({ mode: 'rewrite' })` (or the corresponding file/cloud save mode)
377
- * before sharing the redacted PDF. The default incremental download preserves
378
- * the original content in prior revisions; apply does not change that default.
379
- * Surfaces that promise "permanent removal" must scope that promise to the
380
- * full-rewrite exported artifact.
381
- *
382
- * Applying is irreversible within the layer (no undo). Emits a
383
- * `redaction.applied` document event; content-scope raster invalidation and
384
- * search-corpus refresh ride the normal content-version machinery.
385
- */
386
- interface DocumentRedactionService {
387
- /**
388
- * Apply redactions in `scope`. Ordered batch verb: pages are processed
389
- * independently and a failed page is recorded in its item result rather
390
- * than throwing after the first native write; `unchanged` means the page
391
- * had no matching REDACT annotation. Returns no `meta` only when nothing
392
- * changed.
393
- */
394
- apply(scope: RedactionApplyScope): AbortablePromise<RedactionApplyResult>;
395
- }
396
- //#endregion
397
- //#region src/engine/DocumentRenderService.d.ts
398
- /**
399
- * The engine's render-parameter policy.
400
- *
401
- * - `continuous` — any viewport renders exactly as requested. The LOCAL
402
- * engine always answers this: rendering is in-process, there is no
403
- * shared cache to protect, and exactness is the local product promise.
404
- * - `lattice` — the deployment treats a finite set of render points as
405
- * durable, CDN-shared artifacts. The bounded quantity
406
- * is OUTPUT PIXELS, never zoom:
407
- *
408
- * - `fullPage.widths` — full-page renders quantize on `viewport.width`
409
- * (a scale lattice bounds artifact COUNT but not SIZE: PDF page space
410
- * is effectively unbounded, so scale 1 of a poster page is a memory
411
- * bomb while width caps the dominant dimension by construction).
412
- * - `tiles` — RESERVED for the deep-zoom vertical: a scale-based
413
- * pyramid × fixed tile size, where per-job cost is constant. Absent
414
- * until the tiling plugin ships; reserving the shape keeps the SDK
415
- * contract from churning twice.
416
- * - `maxRenderPixels` — the worker-side output budget for degenerate
417
- * geometry (width bounds width, not height).
418
- *
419
- * The SDK never conforms a request implicitly — the same `render.image`
420
- * call must not return different pixels on local vs cloud. Conformance is
421
- * the caller's visible choice via {@link snapFullPageViewport}.
422
- */
423
- type EngineRenderPolicy = {
424
- readonly kind: 'continuous';
425
- } | {
426
- readonly kind: 'lattice';
427
- readonly fullPage: {
428
- readonly widths: readonly number[];
429
- };
430
- readonly tiles?: {
431
- readonly tileSizes: readonly number[];
432
- readonly scales: readonly number[];
433
- };
434
- /**
435
- * Annotation-appearance lattice — SCALE-based, unlike full pages:
436
- * an appearance is sized by `annotation.rect × scale`, rects span
437
- * orders of magnitude (a 4pt caret vs a page-sized stamp), and the
438
- * composite must track the PAGE's effective render scale or
439
- * annotations sit blurry on a crisp raster. Small images → the
440
- * ladder affords finer, taller steps than pages ever could.
441
- */
442
- readonly appearances?: {
443
- readonly scales: readonly number[];
444
- };
445
- readonly maxRenderPixels?: number;
446
- readonly formats: readonly ('webp' | 'png')[];
447
- readonly background: 'white';
448
- readonly enforced: boolean;
449
- };
450
- declare const CONTINUOUS_RENDER_POLICY: EngineRenderPolicy;
451
- /**
452
- * Document-scoped render policy surface (`doc.render`). Async because the
453
- * cloud engine learns its policy from `/v1/access`; the local engine
454
- * resolves immediately with `continuous`.
455
- *
456
- * Per-page rendering itself stays on `page(pon).render` — this service
457
- * carries POLICY, not pixels.
458
- */
459
- interface DocumentRenderService {
460
- policy(): Promise<EngineRenderPolicy>;
461
- }
462
- /**
463
- * Conform a FULL-PAGE viewport to a render policy — the ONE snap
464
- * implementation, shared by every engine and plugin. Pure and explicit
465
- * by design:
466
- *
467
- * - `continuous` → identity (local/cloud plugin code stays byte-identical).
468
- * - `lattice` → returns a `width`-kind viewport at the smallest ladder
469
- * width ≥ the requested detail (snap UP: always crisp, CSS downscales
470
- * for free), capped at the largest width — detail beyond the cap is the
471
- * tile pyramid's job, by design.
472
- * - `scale`-kind requests convert through the page's width in PDF user
473
- * units — pass `opts.pageWidth` (the caller has it from the layout);
474
- * omitting it for a scale viewport under a lattice policy is a
475
- * programmer error and throws `InvalidArg`.
476
- */
477
- declare function snapFullPageViewport(policy: EngineRenderPolicy, viewport: PageRenderViewport, opts?: {
478
- pageWidth?: number;
479
- }): PageRenderViewport;
480
- /**
481
- * Conform an annotation-appearance scale to the policy's appearance
482
- * lattice. Same discipline as {@link snapFullPageViewport}: identity on
483
- * continuous (and when the policy carries no appearance block), snap UP,
484
- * cap at the largest point. Callers derive `scale` from the page's
485
- * effective render scale (`snappedWidth / pageWidth`, × devicePixelRatio
486
- * as needed) so composites stay crisp against the page raster.
487
- */
488
- declare function snapAppearanceScale(policy: EngineRenderPolicy, scale: number): number;
489
- /**
490
- * Conform a tile-pyramid scale to the policy's tile lattice — the third
491
- * member of the `snap<PolicyBlock><Quantity>` family. Identity on
492
- * continuous and while the deployment doesn't advertise a `tiles` block
493
- * (the block is reserved until the deep-zoom vertical ships server-side;
494
- * the tiling client uses its own default pyramid then — see
495
- * plugin-render). Snap UP, cap at the largest scale: per-tile cost is
496
- * constant by construction (`tileSize²` pixels regardless of level), so
497
- * the cap bounds artifact COUNT, not memory.
498
- */
499
- declare function snapTileScale(policy: EngineRenderPolicy, scale: number): number;
500
- //#endregion
501
- //#region src/engine/DocumentSearchService.d.ts
502
- /**
503
- * Document-scoped text search, exposed via `DocumentHandle.search`.
504
- *
505
- * The contract is a client-driven cursor loop over bounded slices: each
506
- * `query()` call scans at most a budgeted amount of work (pages/matches)
507
- * and returns what it found plus a resume cursor. There is no job to
508
- * start or cancel — a 40K-page document is searched by asking for slices
509
- * until `nextCursor` is null or the user stops caring. Engines clamp the
510
- * requested budget to their own ceilings, so no single call can hold a
511
- * worker (or the server) for minutes.
512
- *
513
- * Reads are gated by `doc.text.search`; `mode: 'full'` (snippets) also
514
- * requires `doc.text.copy` — see {@link SearchMode}. Results always
515
- * reflect the CURRENT layer view: text removed by redaction in this
516
- * layer is unfindable, and a cursor issued before a content mutation is
517
- * rejected rather than resumed over stale pages.
518
- *
519
- * Matches carry canonical visual-line segments from the same layout as text
520
- * selection (never per-glyph boxes) and text-page character offsets that
521
- * join the selection/geometry subsystem directly.
522
- */
523
- interface DocumentSearchService {
524
- query(request: SearchRequest): AbortablePromise<SearchSlice>;
525
- }
526
- //#endregion
527
- //#region src/engine/DocumentSignaturesService.d.ts
528
- /**
529
- * Digital signatures on the document: the read side (what is signed, what
530
- * it seals, what it forbids) and the two-phase signing protocol. The
531
- * engine does the PDF job — candidate file, digest, sealing — and never
532
- * holds a key; the CMS comes from the caller (`@embedpdf/core-signature`
533
- * builds one from a raw signer, or a signing service returns it).
534
- *
535
- * Every read here describes the bytes the document was loaded from
536
- * (for a layer document: base + the delta it was opened with). Unsaved
537
- * edits are not part of any revision until `prepare` snapshots them.
538
- *
539
- * Reads ride `doc.forms.read`; `revisionBytes` rides `doc.download`;
540
- * `prepare`/`complete`/`abort` ride `doc.sign`, a certification
541
- * additionally `doc.sign.certify`.
542
- */
543
- interface DocumentSignaturesService {
544
- /** Revisions, every signature field with its signed state, and the protection in force. */
545
- list(): AbortablePromise<SignatureSnapshot>;
546
- /** The DER `/Contents` of a signed field (exactly `contentsSize` bytes, padding stripped). `NotFound` for an unsigned field. */
547
- contents(field: FormFieldRef): AbortablePromise<Uint8Array>;
548
- /**
549
- * Hash the signed field's `/ByteRange` with `algorithm`, straight from
550
- * the loaded bytes. What a CMS verifier compares its message digest to.
551
- */
552
- digest(field: FormFieldRef, algorithm: DigestAlgorithm): AbortablePromise<Uint8Array>;
553
- /** The exact bytes of revision `revisionIndex` (`[0, end)`): what a signature over it signed. */
554
- revisionBytes(revisionIndex: number): AbortablePromise<Uint8Array>;
555
- /**
556
- * What changed after a signature (or after any revision), judged
557
- * revision by revision against the restrictions in force: every object
558
- * whose cross-reference mapping moved, with its value and every
559
- * reference to it in both revisions, and the rule that explains each —
560
- * or the reference no rule explains. `until: 'working-copy'` snapshots
561
- * unsaved edits as one more revision first. A truncated value is never
562
- * permitted; a broken chain is `indeterminate`.
563
- */
564
- analyze(input: AnalyzeInput): AbortablePromise<ChangeAnalysis>;
565
- /**
566
- * Build the candidate (unsaved edits become their own revision, the
567
- * signature lands in a fresh update over it), seal it, and return the
568
- * digest to sign. The live document is untouched and read-only until
569
- * `complete` or `abort` (`SigningPending`). Refusals are
570
- * `SignatureRefused` with the reason in the message.
571
- */
572
- prepare(input: SignaturePrepareInput): AbortablePromise<SignaturePrepared>;
573
- /**
574
- * Write the CMS into the candidate and install the sealed bytes as the
575
- * document's new version. `expectedVersion` must be what `prepare`
576
- * returned (`SigningVersionMismatch` otherwise). Idempotent: a replay
577
- * with the same CMS answers `already-completed`. Emits
578
- * `signature.completed` and `document.versioned`.
579
- */
580
- complete(input: SignatureCompleteInput): AbortablePromise<SignatureCompleteResult>;
581
- /** Discard a pending candidate. */
582
- abort(signingId: string): AbortablePromise<SignatureAbortResult>;
583
- }
584
- //#endregion
585
- //#region src/engine/MetadataService.d.ts
586
- interface MetadataService {
587
- read(): AbortablePromise<DocumentMetadata>;
588
- /**
589
- * Rewrite the document Info dict via a three-state {@link MetadataPatch}
590
- * (undefined=leave, null=clear, value=set). Returns the re-read metadata
591
- * plus cloud coherence pins (`null` for local engines). Gated by
592
- * `doc.metadata.modify` on the cloud.
593
- */
594
- update(patch: MetadataPatch): AbortablePromise<MetadataUpdateResult>;
595
- }
596
- //#endregion
597
- //#region src/engine/PageAnnotationsService.d.ts
598
- /**
599
- * Per-page annotation service exposed via `PageHandle.annotations`.
600
- *
601
- * `list()` is the slow path: the engine acquires a `pagePtr` from the
602
- * `PagePtrPool`, dispatches per-subtype readers, and returns
603
- * fully-typed annotations. Mutations all funnel through this service
604
- * because they need a `pagePtr` anyway.
605
- *
606
- * Mutation methods are typed in this slice but throw
607
- * `EngineError(NotImplemented)` until the next slice. The signatures are
608
- * stable so client code can be written against them today.
609
- */
610
- interface PageAnnotationsService {
611
- list(): AbortablePromise<AnnotationListPageSnapshot>;
612
- /**
613
- * Batch-render every annotation appearance (`/AP`) stream on the page into
614
- * its own raw RGBA raster, sized to the annotation's `/Rect`. Read-only and
615
- * gated by `doc.annotate.read` — reading an annotation implies you may see
616
- * its rendered appearance (the Adobe boundary).
617
- *
618
- * Cloud engines do not expose the raw rasters (the HTTP surface ships
619
- * encoded images); use {@link renderAppearanceImages} there instead.
620
- */
621
- renderAppearances(options?: AnnotationAppearanceRenderOptions): AbortablePromise<AnnotationAppearancesResult>;
622
- /**
623
- * Encoded counterpart of {@link renderAppearances}: each raster is run
624
- * through the engine's image encoder (local) or fetched as a
625
- * `multipart/form-data` body (cloud) and returned as a lazily-resolved
626
- * `PageImageHandle`. This is the cross-engine portable surface.
627
- */
628
- renderAppearanceImages(options?: AnnotationAppearanceImageOptions): AbortablePromise<AnnotationAppearanceImagesResult>;
629
- /**
630
- * Decode and return the file embedded in a FileAttachment annotation
631
- * (its `/FS` filespec). A read — listings carry the file's metadata
632
- * (`FileAttachmentAnnotationDTO.file`); this is the explicit bytes-out
633
- * call. Optional while the cloud endpoint ships (the `extract?`
634
- * pattern); feature-detect with `annotations.downloadFile !== undefined`.
635
- * Throws `EngineError(InvalidArg)` when the annotation is not a
636
- * file-attachment or has no embedded file stream.
637
- */
638
- downloadFile?(ref: AnnotationRef): AbortablePromise<AttachmentContent>;
639
- create(draft: AnnotationDraft): AbortablePromise<AnnotationCreateResult>;
640
- update(ref: AnnotationRef, patch: AnnotationPatch): AbortablePromise<AnnotationUpdateResult>;
641
- delete(ref: AnnotationRef): AbortablePromise<AnnotationDeleteResult>;
642
- /**
643
- * Batch move (contiguous-block; `refs.length === 1` is the
644
- * single-annotation case). Refs may mix stable ids and weak `index`
645
- * refs; weak refs are opportunistically upgraded to durable `/NM`
646
- * before the move (same rule as `update()`). Atomic — one revision
647
- * bump and one impact computation per batch.
648
- *
649
- * @param refs Annotations to move, in the order they should appear
650
- * after the move.
651
- * @param toIndex Insertion point in the post-removal /Annots index
652
- * space, in `[0, count - refs.length]`.
653
- */
654
- move(refs: AnnotationRef[], toIndex: number): AbortablePromise<AnnotationMoveResult>;
655
- /**
656
- * Flatten the given annotations of THIS page into its content —
657
- * `pages.flatten` for a chosen set. Painted annotations are removed from
658
- * the page; ones that are ineligible (hidden for `usage`, Popups, no
659
- * usable appearance) stay and report `skipped`, so a caller can say
660
- * "2 of 3 flattened". A content + annotation MUTATION of this page: its
661
- * content and annotation pins advance, layout does not; a
662
- * `annotations.flattened` event is published when anything was applied.
663
- * Gated like `pages.flatten` (`doc.pages.modify` + `doc.annotate.modify`).
664
- * `InvalidArg` for a ref on another page; `NotFound` for an unknown ref.
665
- * Optional while transports ship — feature-detect.
666
- */
667
- flatten?(refs: AnnotationRef[], usage?: PageFlattenUsage): AbortablePromise<AnnotationFlattenResult>;
668
- /**
669
- * Flatten the normal appearances of the given annotations of this page
670
- * into a NEW single-page PDF sized to their union `/Rect` — vector,
671
- * positions preserved, exactly as this page shows them. The same plan as
672
- * `flatten` aimed at a fresh page; the source document is untouched. A
673
- * derived READ that egresses content, so it is gated by `doc.download`
674
- * like `pages.extract`. All-or-nothing: `InvalidArg` when any ref is not
675
- * on this page, hidden, or has no appearance (a stamp silently missing a
676
- * part would be worse than an error). Optional — feature-detect.
677
- */
678
- exportAppearance?(refs: AnnotationRef[]): AbortablePromise<Uint8Array>;
679
- }
680
- //#endregion
681
- //#region src/engine/PageGeometryService.d.ts
682
- interface PageGeometryService {
683
- read(): AbortablePromise<PageGeometrySnapshot>;
684
- }
685
- //#endregion
686
- //#region src/engine/PageRenderService.d.ts
687
- interface PageRenderService {
688
- image(options?: PageImageOptions): AbortablePromise<PageImageHandle>;
689
- raw(options?: PageRenderOptions): AbortablePromise<PageRaster>;
690
- }
691
- //#endregion
692
- //#region src/engine/PageTextService.d.ts
693
- /**
694
- * Per-page text service exposed via `PageHandle.text`.
695
- *
696
- * `read()` acquires a `pagePtr` on the worker, runs PDFium's
697
- * `FPDFText_LoadPage` → `FPDFText_GetText` chain, and returns the
698
- * full plain-text extraction together with the current `PageState`.
699
- *
700
- * The single-method shape is intentional: future per-character
701
- * features (bounding boxes, font runs, search) land on this service
702
- * as additional methods without changing the existing URL or DTO.
703
- */
704
- interface PageTextService {
705
- read(): AbortablePromise<PageTextSnapshot>;
706
- }
707
- //#endregion
708
- //#region src/dto/PieceInfo.d.ts
709
- /**
710
- * Page-piece metadata (ISO 32000 §14.5): private, application-scoped data
711
- * under `/PieceInfo` on a page or on the document catalog. The engine
712
- * round-trips a constrained, wire-safe value vocabulary; anything else in
713
- * the file is PRESERVED untouched and surfaced as `{ type: 'unknown' }`.
714
- *
715
- * Reads are lossless-tagged (a PDF name and a PDF string both arrive as
716
- * JS strings, so the tag is what keeps them distinguishable); writes take
717
- * plain JS values, with `{ name: '...' }` as the one wrapper needed to
718
- * request a PDF name. `/LastModified` bookkeeping (application dict, page
719
- * dict, doc /Info /ModDate) is engine-managed on every write.
720
- */
721
- /** One `/Private` value as read from the file. */
722
- type PieceInfoEntry = {
723
- type: 'string';
724
- value: string;
725
- } | {
726
- type: 'name';
727
- value: string;
728
- } | {
729
- type: 'number';
730
- value: number;
731
- } | {
732
- type: 'boolean';
733
- value: boolean;
734
- } | {
735
- type: 'string-array';
736
- value: string[];
737
- } |
738
- /** Present in the file but outside the supported vocabulary — preserved
739
- * by writes to sibling keys, not readable through this API. */
740
- {
741
- type: 'unknown';
742
- };
743
- /** A write value: plain JS, `{ name }` requests a PDF name, `null` deletes. */
744
- type PieceInfoPatchValue = string | number | boolean | readonly string[] | {
745
- name: string;
746
- };
747
- type PieceInfoPatch = Record<string, PieceInfoPatchValue | null>;
748
- interface PieceInfoSnapshot {
749
- /** The application's `/Private` entries, keyed by PDF key name. */
750
- entries: Record<string, PieceInfoEntry>;
751
- /** The application data dict's `/LastModified`, as ISO 8601 (null if absent). */
752
- lastModified: string | null;
753
- }
754
- //#endregion
755
- //#region src/engine/PieceInfoService.d.ts
756
- /**
757
- * Access to `/PieceInfo` private application data (ISO 32000 §14.5). The
758
- * SAME interface serves both levels — `DocumentHandle.pieceInfo?` reads and
759
- * writes the catalog's `/PieceInfo`, `PageHandle.pieceInfo?` the page's —
760
- * mirroring the native API's doc/page symmetry.
761
- *
762
- * Optional on the contract while the cloud endpoints ship (the
763
- * `downloadLayer?` pattern): the local engine implements it; the cloud
764
- * engine omits it until a cloud consumer exists (writes there also need an
765
- * authorization-scope decision — currently they ride `doc.metadata.modify`
766
- * locally). Feature-detect with `handle.pieceInfo !== undefined`.
767
- *
768
- * Writes are engine-managed for spec bookkeeping: every update refreshes
769
- * the application dict's `/LastModified`, the page's `/LastModified`
770
- * (required once `/PieceInfo` is present), and — for catalog writes — the
771
- * document `/Info` `/ModDate`. No document event is published: piece data
772
- * is private app state, not rendered document state.
773
- */
774
- interface PieceInfoService {
775
- /**
776
- * The application's data, or null when the holder has no well-formed
777
- * entry for it. Unknown value types arrive as `{ type: 'unknown' }` and
778
- * survive sibling writes untouched.
779
- */
780
- read(application: string): AbortablePromise<PieceInfoSnapshot | null>;
781
- /**
782
- * Merge-write entries into the application's `/Private` dictionary:
783
- * strings/numbers/booleans/string-arrays write as the corresponding PDF
784
- * types, `{ name }` writes a PDF name, `null` deletes the key. One call
785
- * is one worker job — atomic with respect to every other engine
786
- * operation on this document.
787
- */
788
- update(application: string, patch: PieceInfoPatch): AbortablePromise<void>;
789
- /** Application names present under this holder's `/PieceInfo`. */
790
- applications(): AbortablePromise<string[]>;
791
- /** Remove the application's entire entry (sibling applications survive). */
792
- clear(application: string): AbortablePromise<void>;
793
- }
794
- //#endregion
795
- //#region src/engine/PageMeasureService.d.ts
796
- interface PageMeasureService {
797
- /** Viewports in drawing order. Last containing viewport wins, including foreign ones. */
798
- viewports(): AbortablePromise<PageMeasurementViewport[]>;
799
- /** Upsert/remove EmbedPDF's full-page calibration. Other producers' entries survive.
800
- * Existing annotations retain their own scale snapshots. */
801
- setScale(measure: PdfMeasure | null): AbortablePromise<void>;
802
- }
803
- //#endregion
804
- //#region src/engine/PageHandle.d.ts
805
- /**
806
- * Page-scoped handle returned by `DocumentHandle.page(pageObjectNumber)`.
807
- * The handle is keyed on the PDF indirect object number, never the page
808
- * index, so it survives page-list mutations.
809
- */
810
- interface PageHandle {
811
- readonly pageObjectNumber: PageObjectNumber;
812
- /**
813
- * Display index at the time this handle was minted. The engine refreshes
814
- * this on every annotation/list call against the live `PageRecord`, but
815
- * callers should treat it as advisory metadata only.
816
- */
817
- readonly pageIndex: number;
818
- readonly annotations: PageAnnotationsService;
819
- readonly text: PageTextService;
820
- readonly geometry: PageGeometryService;
821
- readonly render: PageRenderService;
822
- /**
823
- * PAGE-level `/PieceInfo` private application data (ISO 32000 §14.5) —
824
- * e.g. a stamp page's name/subject. Optional: local implements it; cloud
825
- * omits it until a cloud consumer ships (the `downloadLayer?` pattern).
826
- */
827
- readonly pieceInfo?: PieceInfoService;
828
- readonly measure?: PageMeasureService;
829
- }
830
- //#endregion
831
- //#region src/events/DocumentEvent.d.ts
832
- /**
833
- * Provenance of a `DocumentEvent` — WHOSE HAND caused the mutation, never
834
- * which transport delivered it (transport is invisible by design).
835
- *
836
- * `kind: 'local'` means caused by THIS ENGINE INSTANCE — not "this user".
837
- * The same user in two tabs is two sessions: tab A's mutation arrives in
838
- * tab B as `'remote'` (with the same `sub`). Rule of thumb for consumers:
839
- * "is this MY ACTION" → check `kind` / `sessionId` (undo stacks, optimism
840
- * reconciliation); "is this MY USER" → check `sub` (attribution).
841
- */
842
- interface EventOrigin {
843
- /** 'local' = caused by this engine instance; 'remote' = another session. */
844
- kind: 'local' | 'remote';
845
- /** Identifies the engine instance that caused the mutation. */
846
- sessionId: string;
847
- /** Authenticated subject of the originator (cloud); `null` locally. */
848
- sub: string | null;
849
- /** Mutation timestamp (server ts for remote, client ts for local). */
850
- ts: number;
851
- /** Server audit-log row id — monotonic per document, the resume cursor.
852
- * `null` until the mutation has a server identity (local engines; cloud
853
- * own-mutation events before the server echoes the id). */
854
- serverId: number | null;
855
- }
856
- /**
857
- * The one event stream both engines speak — the model is the contract, the
858
- * transport differs (local: in-process after the worker confirms; cloud:
859
- * in-process for your own mutations, SSE for everyone else's).
860
- *
861
- * Invariants (locked — the collaboration design rests on these):
862
- *
863
- * - EXACTLY ONCE: every mutation that touches your document appears in
864
- * your stream exactly once. The engine that performs a mutation emits
865
- * the event itself at confirmation time; the remote channel exists to
866
- * tell everyone ELSE (own echoes are dropped by `sessionId`).
867
- * - GROUND TRUTH ONLY: events fire after the mutation is confirmed —
868
- * never optimistically. Optimism is a plugin concern.
869
- * - RESULTS RIDE VERBATIM: each event embeds the mutation result the
870
- * caller received, unmodified — which (cloud) is byte-identical to the
871
- * audit-log payload. A handler sees the same fact whether it performed
872
- * the mutation, watched it locally, or received it over the wire.
873
- *
874
- * Handlers updating UI/document state should be ORIGIN-AGNOSTIC ("a page
875
- * was removed → update the registry"); `origin` is metadata for the few
876
- * provenance-aware features (undo, attribution toasts, camera etiquette).
877
- */
878
- type DocumentEvent = ({
879
- type: 'page.viewportsChanged';
880
- origin: EventOrigin;
881
- } & PageScaleResult) | ({
882
- type: 'annotation.created';
883
- pageObjectNumber: PageObjectNumber;
884
- origin: EventOrigin;
885
- } & AnnotationCreateResult) | ({
886
- type: 'annotation.updated';
887
- pageObjectNumber: PageObjectNumber;
888
- origin: EventOrigin;
889
- } & AnnotationUpdateResult) | ({
890
- type: 'annotation.deleted';
891
- pageObjectNumber: PageObjectNumber;
892
- origin: EventOrigin;
893
- } & AnnotationDeleteResult) | ({
894
- type: 'annotation.moved';
895
- pageObjectNumber: PageObjectNumber;
896
- origin: EventOrigin;
897
- } & AnnotationMoveResult) | ({
898
- type: 'annotations.flattened';
899
- origin: EventOrigin;
900
- } & AnnotationFlattenResult) | ({
901
- type: 'pages.moved';
902
- /** Locally: the moved block. Remotely the audit row only records the
903
- * outcome, so this is the full new order — consumers should read
904
- * `layout` for positions, never reconstruct the gesture. */
905
- pageObjectNumbers: PageObjectNumber[];
906
- /** The originator's insertion point; absent on remote events. */
907
- destIndex?: number;
908
- origin: EventOrigin;
909
- } & PageMoveResult) | ({
910
- type: 'pages.rotated';
911
- pageObjectNumbers: PageObjectNumber[];
912
- rotation: PdfRotation;
913
- origin: EventOrigin;
914
- } & PageRotateResult) | ({
915
- type: 'pages.deleted';
916
- /** The RETIRED pons — not derivable from the surviving `layout`. */
917
- pageObjectNumbers: PageObjectNumber[];
918
- origin: EventOrigin;
919
- } & PageDeleteResult) | ({
920
- type: 'pages.inserted';
921
- /** The originator's insertion point; absent on remote events. */
922
- destIndex?: number;
923
- origin: EventOrigin;
924
- } & PageInsertResult) | ({
925
- type: 'pages.named';
926
- /** The decoded key that was registered, renamed, or removed. */
927
- name: string;
928
- /** The page it now points at; `null` when the registration was removed. */
929
- pageObjectNumber: PageObjectNumber | null;
930
- origin: EventOrigin;
931
- } & PageNameResult) | ({
932
- type: 'attachment.created';
933
- origin: EventOrigin;
934
- } & AttachmentCreateResult) | ({
935
- type: 'attachment.deleted';
936
- origin: EventOrigin;
937
- } & AttachmentDeleteResult) | ({
938
- type: 'metadata.updated';
939
- origin: EventOrigin;
940
- } & MetadataUpdateResult) | ({
941
- type: 'form.valueChanged';
942
- origin: EventOrigin;
943
- } & FormSetValueResult) | ({
944
- type: 'form.imported';
945
- origin: EventOrigin;
946
- } & FormImportResult) | ({
947
- type: 'form.repaired';
948
- origin: EventOrigin;
949
- } & FormRepairResult) | ({
950
- type: 'form.fieldCreated';
951
- origin: EventOrigin;
952
- } & FormFieldCreateResult) | ({
953
- type: 'form.fieldUpdated';
954
- origin: EventOrigin;
955
- } & FormFieldUpdateResult) | ({
956
- type: 'form.fieldDeleted';
957
- origin: EventOrigin;
958
- } & FormFieldDeleteResult) | ({
959
- type: 'form.widgetAttached';
960
- origin: EventOrigin;
961
- } & FormWidgetLinkResult) | ({
962
- type: 'form.widgetDetached';
963
- origin: EventOrigin;
964
- } & FormWidgetLinkResult) | ({
965
- type: 'form.effectsApplied';
966
- origin: EventOrigin;
967
- } & FormEffectsResult) | ({
968
- type: 'pages.flattened';
969
- pageObjectNumbers: PageObjectNumber[];
970
- usage: PageFlattenUsage;
971
- origin: EventOrigin;
972
- } & PageFlattenResult) | ({
973
- type: 'redaction.applied';
974
- origin: EventOrigin;
975
- } & RedactionApplyResult) | {
976
- /** A signing candidate was parked: the document is read-only until it completes or aborts. */
977
- type: 'signature.prepared';
978
- signingId: string;
979
- field: FormFieldRef;
980
- origin: EventOrigin;
981
- } | ({
982
- /** The sealed bytes are installed; `version` is what they became. */
983
- type: 'signature.completed';
984
- signingId: string;
985
- origin: EventOrigin;
986
- } & SignatureCompleteResult) | {
987
- type: 'signature.aborted';
988
- signingId: string;
989
- origin: EventOrigin;
990
- } | {
991
- /**
992
- * The session moved to a new saved version (a completed signature,
993
- * here or in another session). Byte-level facts — revisions,
994
- * coverage, digests, verdicts — must be re-read.
995
- */
996
- type: 'document.versioned';
997
- version: BaseVersionInfo;
998
- origin: EventOrigin;
999
- } | {
1000
- /**
1001
- * Cloud only: the live event stream fell too far behind to replay
1002
- * (the server's SSE `full-refresh`) — state derived from earlier
1003
- * events or snapshots may be stale, and the gap's mutations will
1004
- * NEVER arrive as events. Consumers must re-read the snapshots they
1005
- * keep fresh from this stream (`doc.annotations.listRawAll()`,
1006
- * `doc.forms.list()`, …).
1007
- *
1008
- * Carries no `EventOrigin`: it is a transport notice, not a
1009
- * document mutation — the exactly-once / results-ride-verbatim
1010
- * invariants above apply to mutation events only. The local engine
1011
- * never emits it.
1012
- */
1013
- type: 'stream.desynced';
1014
- reason: 'backlog-overflow';
1015
- ts: number;
1016
- };
1017
- type DocumentEventType = DocumentEvent['type'];
1018
- type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
1019
- /** A `DocumentEvent` before provenance is stamped — what mutation paths
1020
- * hand to their engine's publisher, which adds `origin`. Transport
1021
- * notices (`stream.desynced`) are excluded: they are published directly
1022
- * by the remote channel, never through a mutation publisher. */
1023
- type DocumentEventInit = DistributiveOmit<Exclude<DocumentEvent, {
1024
- type: 'stream.desynced';
1025
- }>, 'origin'>;
1026
- //#endregion
1027
- //#region src/events/DocumentEventStream.d.ts
1028
- /**
1029
- * The subscription surface on `DocumentHandle.events`. Intentionally
1030
- * minimal — no filtering, no replay-from-id: plugins build their own
1031
- * filter wrappers (per-page, per-type, …). One subscription, one stream.
1032
- *
1033
- * Delivery is synchronous fan-out with error isolation: a throwing
1034
- * listener never blocks other listeners, and never fails the mutation
1035
- * whose confirmation produced the event.
1036
- */
1037
- interface DocumentEventStream {
1038
- /** Subscribe to every event for this document. Returns the unsubscriber. */
1039
- subscribe(listener: (event: DocumentEvent) => void): () => void;
1040
- /**
1041
- * Highest `origin.serverId` observed so far — the reconnect/backfill
1042
- * cursor for the remote channel. `null` until a remote-identified event
1043
- * has been seen (always `null` on purely-local engines).
1044
- */
1045
- lastServerId(): number | null;
1046
- }
1047
- //#endregion
1048
- //#region src/engine/DocumentHandle.d.ts
1049
- interface DocumentCapabilities {
1050
- readonly weakAnnotationEditSessions: 'not-needed' | 'required';
1051
- readonly pageEditSessions: 'unsupported' | 'supported';
1052
- }
1053
- interface DocumentHandle {
1054
- readonly id: string;
1055
- readonly capabilities: DocumentCapabilities;
1056
- readonly security: DocumentSecurityService;
1057
- readonly metadata: MetadataService;
1058
- readonly annotations: DocumentAnnotationsService;
1059
- /** Lazy catalog-owned action extraction. The engine never executes scripts. */
1060
- readonly actions?: DocumentActionsService;
1061
- /**
1062
- * Document-level attachments (the catalog's `/EmbeddedFiles` name tree).
1063
- * Optional while transports ship (the `downloadLayer?` pattern) —
1064
- * feature-detect with `doc.attachments !== undefined`. Files attached to
1065
- * annotations are downloaded via `page(pon).annotations.downloadFile`.
1066
- */
1067
- readonly attachments?: DocumentAttachmentsService;
1068
- /** The document's interactive form (AcroForm): fields, values, interchange. */
1069
- readonly forms: DocumentFormsService;
1070
- /**
1071
- * Font embedding and text layout settings of this document (session
1072
- * state). Optional: the local engine implements it; engines that do not
1073
- * lay text out in-process omit it — feature-detect with
1074
- * `doc.fonts !== undefined`.
1075
- */
1076
- readonly fonts?: DocumentFontSettings;
1077
- /**
1078
- * CATALOG-level `/PieceInfo` private application data (ISO 32000 §14.5)
1079
- * — e.g. a stamp library's display name. Optional: the local engine
1080
- * implements it; the cloud engine omits it until a cloud consumer ships
1081
- * (the `downloadLayer?` pattern). Per-page piece data lives on
1082
- * `page(pon).pieceInfo`.
1083
- */
1084
- readonly pieceInfo?: PieceInfoService;
1085
- /** Document text search: budgeted, cursor-resumable slices. */
1086
- readonly search: DocumentSearchService;
1087
- /**
1088
- * Render POLICY surface (`doc.render.policy()`): the engine's render
1089
- * lattice, or `continuous` on engines that render any viewport exactly
1090
- * (the local engine). Pixels stay on `page(pon).render` — this carries
1091
- * policy only. Conformance is explicit via `snapFullPageViewport`; no
1092
- * engine ever snaps a render call implicitly. Optional while engines
1093
- * ship it — feature-detect with `doc.render !== undefined`.
1094
- */
1095
- readonly render?: DocumentRenderService;
1096
- /**
1097
- * Document-scoped page service. Use for cross-page operations:
1098
- * - `pages.list()` for the current display order.
1099
- * - `pages.move(pons, destIndex)` for reorder.
1100
- *
1101
- * Per-page reads/writes still live on `page(pon).annotations`.
1102
- */
1103
- readonly pages: DocumentPagesService;
1104
- /**
1105
- * Destructive redaction apply (the second stage of the two-stage model;
1106
- * marking rides the normal annotation verbs). Optional while engines
1107
- * ship it — feature-detect with `doc.redaction !== undefined`.
1108
- */
1109
- readonly redaction?: DocumentRedactionService;
1110
- /**
1111
- * Digital signatures: the read side (revisions, signed fields, the
1112
- * protection they impose) and the two-phase signing protocol. Optional
1113
- * while engines ship it — feature-detect with
1114
- * `doc.signatures !== undefined`.
1115
- */
1116
- readonly signatures?: DocumentSignaturesService;
1117
- /**
1118
- * The document's event stream — every confirmed mutation, exactly once,
1119
- * identical shape on local and cloud engines (see `DocumentEvent`). The
1120
- * engine-instance identity lives on each event's `origin.sessionId`.
1121
- */
1122
- readonly events: DocumentEventStream;
1123
- /**
1124
- * Returns a handle scoped to a page by PDF indirect object number.
1125
- * Throws `EngineError(NotFound)` if the document has no such page.
1126
- * Synchronous because page records are cached on `DocumentSession`.
1127
- */
1128
- page(pageObjectNumber: PageObjectNumber): PageHandle;
1129
- download(opts?: {
1130
- mode?: PdfSaveMode;
1131
- }): AbortablePromise<Uint8Array>;
1132
- /**
1133
- * Local Node engines only: write the document to a local file without
1134
- * moving its bytes through JS. An untouched session (no unsaved edits,
1135
- * incremental mode) is streamed out verbatim — for a signed document,
1136
- * exactly as sealed. Absent on engines that cannot reach a filesystem.
1137
- */
1138
- downloadToFile?(path: string, opts?: {
1139
- mode?: PdfSaveMode;
1140
- }): AbortablePromise<void>;
1141
- /**
1142
- * The saved version this session is on: SHA-256 and length of the
1143
- * loaded bytes (for a layer session, of its base). Changes only when
1144
- * a signature completes. Optional while engines ship it.
1145
- */
1146
- version?(): AbortablePromise<BaseVersionInfo>;
1147
- /**
1148
- * Export JUST this document's LAYER as a self-contained artifact (the small
1149
- * overlay diff over the immutable base) — re-openable later via
1150
- * `OpenInputLayerBytes` with `{ kind: 'artifact', bytes }`. Optional: the
1151
- * local engine supports it for every session it opens as a layer (the
1152
- * default `sessionKind`, and any `layerBytes` open); the cloud engine
1153
- * manages layers server-side and omits it. Rejects on a session opened
1154
- * with `sessionKind: 'plain'`.
1155
- */
1156
- downloadLayer?(): AbortablePromise<Uint8Array>;
1157
- close(): AbortablePromise<void>;
1158
- }
1159
- //#endregion
1160
- //#region src/engine/FontService.d.ts
1161
- /**
1162
- * Engine-level service for registering runtime fonts and configuring the
1163
- * ordered glyph-fallback chain. Runtime-global, not document-scoped: a
1164
- * registered font is shared by every page render and annotation-authoring
1165
- * call on the engine's PDFium thread, and survives document open/close.
1166
- *
1167
- * Availability is the deliberate local-vs-cloud split:
1168
- * - `@embedpdf/engine` (local/WASM) implements it: the developer embedding
1169
- * the viewer decides what fonts ship to the client runtime.
1170
- * - `@cloudpdf/engine` (cloud) does NOT expose it (`Engine.fonts` is
1171
- * undefined). Fallback fonts are a server policy decision, loaded once on
1172
- * the server runtime; clients cannot influence them.
1173
- *
1174
- * `register` and `addFallback` are intentionally separate calls: registering a
1175
- * font makes it available for explicit annotation authoring
1176
- * (`FreeTextDraft.registeredFontKey`); adding it to the fallback chain *also*
1177
- * makes it eligible for automatic missing-glyph substitution during page
1178
- * rendering and appearance generation. Many fonts want one without the other.
1179
- */
1180
- interface FontService {
1181
- /**
1182
- * Register a single font. Idempotent: registering a font whose `key` (or, if
1183
- * `key` is omitted, whose content hash) is already known resolves to the
1184
- * existing handle without re-uploading bytes to the runtime.
1185
- *
1186
- * Rejects with `EngineErrorCode.InvalidArg` when the runtime cannot load the
1187
- * font (corrupt file, unsupported format, no glyphs).
1188
- */
1189
- register(spec: FontSpec): AbortablePromise<FontHandle>;
1190
- /** Register several fonts, preserving order. */
1191
- registerAll(specs: FontSpec[]): AbortablePromise<FontHandle[]>;
1192
- /**
1193
- * Append a registered font to the ordered fallback chain. Order is
1194
- * precedence: the first registered font that covers a missing glyph wins,
1195
- * with style (weight/italic) used as a tie-breaker by the runtime.
1196
- */
1197
- addFallback(font: FontHandle | FontKey): AbortablePromise<void>;
1198
- /** Clear the fallback chain without unregistering the fonts themselves. */
1199
- clearFallbacks(): AbortablePromise<void>;
1200
- /** Unregister every font and reset the fallback chain. */
1201
- clear(): AbortablePromise<void>;
1202
- /**
1203
- * Assert that the application holds a licence permitting editing with a
1204
- * preview-and-print font, so FreeText authoring and missing-glyph fallback
1205
- * may use it. Resolves to the updated handle (`editingAuthorized: true`).
1206
- * Rejects with `InvalidArg` for an unregistered key.
1207
- */
1208
- authorizeEditing(font: FontHandle | FontKey): AbortablePromise<FontHandle>;
1209
- /** Currently registered fonts, in registration order. */
1210
- list(): readonly FontHandle[];
1211
- }
1212
- //#endregion
1213
- //#region src/engine/Engine.d.ts
1214
- /**
1215
- * Engine contract shared by `@embedpdf/engine` and
1216
- * `@cloudpdf/engine`. Both implementations expose the same
1217
- * `open()` surface and return the same {@link DocumentHandle} shape;
1218
- * the only observable difference is transport — local goes through a
1219
- * Worker + WASM PDFium, cloud goes through HTTPS to a remote server.
1220
- *
1221
- * Authorization parity:
1222
- * - Cloud reads scope + identity from the doc-scoped JWT it gets at
1223
- * transport setup time. `OpenOptions.scope` / `OpenOptions.identity`
1224
- * are silently ignored by cloud (the JWT is the authority).
1225
- * - Local reads scope + identity from `OpenOptions.scope` /
1226
- * `OpenOptions.identity` (no JWT involved). Defaults to `['*']`
1227
- * wildcard with a one-time console warning.
1228
- *
1229
- * Both engines run the same resolver against the same `pdf.permissions`
1230
- * expansion → identical allow/deny decisions for the same
1231
- * scope+identity+PDF-bits inputs. The parity test at
1232
- * `engine-core/test/scope-parity.test.ts` (commit 17) locks this in.
1233
- */
1234
- interface Engine {
1235
- open(input: OpenInput, options?: OpenOptions): AbortablePromise<DocumentHandle>;
1236
- destroy(): AbortablePromise<void>;
1237
- /**
1238
- * Start booting the engine's backing resources (Worker spawn, WASM compile,
1239
- * transport connect) without performing any work. Optional because some
1240
- * engines have nothing to warm (cloud). Idempotent and non-blocking:
1241
- * engines that boot lazily do so on first use anyway — calling `warmup()`
1242
- * just overlaps that boot with app/plugin initialization instead of paying
1243
- * for it on the first `open()`.
1244
- */
1245
- warmup?(): void;
1246
- /**
1247
- * Runtime font registration + fallback configuration. Present on the local
1248
- * (WASM) engine only; `undefined` on the cloud engine, where fallback fonts
1249
- * are a server-side policy decision and cannot be configured from the
1250
- * client. See {@link FontService}.
1251
- */
1252
- readonly fonts?: FontService;
1253
- }
1254
- /**
1255
- * A thunk that constructs a fresh {@link Engine}. Construction is synchronous
1256
- * and cheap — engines allocate no live resources (no Worker, no WASM, no
1257
- * socket) until first use — so the thunk exists purely to express OWNERSHIP:
1258
- *
1259
- * - Pass an `Engine` INSTANCE to an adapter (`<Viewer>`, `provideEmbedPdf`)
1260
- * and it is BORROWED: the adapter never destroys it. You own the
1261
- * lifetime — the module-scope singleton case.
1262
- * - Pass a THUNK (`() => localEngine()`) and the adapter OWNS the result:
1263
- * it calls the thunk on mount and destroys the engine on unmount. Use
1264
- * this for per-mount isolation (StrictMode/HMR-clean teardown,
1265
- * multi-viewer independence).
1266
- *
1267
- * DELIBERATELY synchronous — an async thunk would reintroduce a "maybe
1268
- * engine" that every consumer must await (the deferredEngine problem this
1269
- * design removed). Async acquisition (dynamic `import()`, remote config)
1270
- * belongs OUTSIDE the thunk: await it, then hand over the instance. Code
1271
- * that genuinely needs a lazily-resolved engine models that itself with
1272
- * `Engine | Promise<Engine>` (see the stamp plugin's `assetEngine`).
1273
- */
1274
- type EngineFactory = () => Engine;
1275
- //#endregion
1276
- export { snapTileScale as A, DocumentActionsService as B, DocumentSignaturesService as C, EngineRenderPolicy as D, DocumentRenderService as E, DocumentFontSettings as F, FontEmbeddingPolicy as I, DocumentAttachmentsService as L, DocumentPagesService as M, DocumentFormsService as N, snapAppearanceScale as O, FormRepairOptions as P, DocumentAnnotationsService as R, MetadataService as S, CONTINUOUS_RENDER_POLICY as T, PieceInfoSnapshot as _, DocumentHandle as a, PageGeometryService as b, DocumentEventInit as c, PageHandle as d, PageMeasureService as f, PieceInfoPatchValue as g, PieceInfoPatch as h, DocumentCapabilities as i, DocumentRedactionService as j, snapFullPageViewport as k, DocumentEventType as l, PieceInfoEntry as m, EngineFactory as n, DocumentEventStream as o, PieceInfoService as p, FontService as r, DocumentEvent as s, Engine as t, EventOrigin as u, PageTextService as v, DocumentSearchService as w, PageAnnotationsService as x, PageRenderService as y, WeakAnnotationEditSession as z };
1277
- //# sourceMappingURL=Engine-EWWHhEIi.d.ts.map