@embedpdf/engine-core 3.0.0-next.0 → 3.0.0-next.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{AbortError-CjSasIlL.js → AbortError-8-9JAX1Y.js} +2 -2
- package/dist/{AbortError-CjSasIlL.js.map → AbortError-8-9JAX1Y.js.map} +1 -1
- package/dist/{AbortError-ByBflvEl.cjs → AbortError-CRSooKsk.cjs} +2 -2
- package/dist/{AbortError-ByBflvEl.cjs.map → AbortError-CRSooKsk.cjs.map} +1 -1
- package/dist/{AnnotationListSnapshot-W0RCsyDE.d.cts → AnnotationListSnapshot-DDxHpJQU.d.cts} +538 -41
- package/dist/{AnnotationListSnapshot-W0RCsyDE.d.ts → AnnotationListSnapshot-DDxHpJQU.d.ts} +538 -41
- package/dist/{DocumentSecurityService-Df79fgpe.d.cts → DocumentSecurityService-BV4_YXkU.d.cts} +33 -2
- package/dist/{DocumentSecurityService-B-tULKNY.d.ts → DocumentSecurityService-o9aeTHwT.d.ts} +33 -2
- package/dist/{Engine-D9loFZc1.d.cts → Engine-D9je6GdU.d.cts} +50 -19
- package/dist/{Engine-B7Oe7f5i.d.ts → Engine-DOoVem7_.d.ts} +50 -19
- package/dist/{subtype-qejjVr6h.cjs → PageInsertBlankInput-CzShuSJI.cjs} +184 -1
- package/dist/PageInsertBlankInput-CzShuSJI.cjs.map +1 -0
- package/dist/{subtype-BvAzLCGC.js → PageInsertBlankInput-WKY0tr6S.js} +149 -2
- package/dist/PageInsertBlankInput-WKY0tr6S.js.map +1 -0
- package/dist/{builders-C548U47M.js → builders-B_KufGJ9.js} +547 -169
- package/dist/builders-B_KufGJ9.js.map +1 -0
- package/dist/{builders-BvikWRuO.cjs → builders-Cp_rlGob.cjs} +603 -225
- package/dist/builders-Cp_rlGob.cjs.map +1 -0
- package/dist/conformance.cjs +822 -198
- package/dist/conformance.cjs.map +1 -1
- package/dist/conformance.d.cts +124 -6
- package/dist/conformance.d.ts +124 -6
- package/dist/conformance.js +777 -157
- package/dist/conformance.js.map +1 -1
- package/dist/{fold-CB4fAOOy.js → fold-BfyxxwS6.js} +162 -3
- package/dist/fold-BfyxxwS6.js.map +1 -0
- package/dist/{fold-IaMph3CO.cjs → fold-C7I5GpBz.cjs} +235 -4
- package/dist/fold-C7I5GpBz.cjs.map +1 -0
- package/dist/index.cjs +36 -18
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/runtime.cjs +41 -23
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.d.cts +103 -5
- package/dist/runtime.d.ts +103 -5
- package/dist/runtime.js +5 -5
- package/dist/{schemas-B_1VyFsm.cjs → schemas-D1pxEv3t.cjs} +138 -32
- package/dist/schemas-D1pxEv3t.cjs.map +1 -0
- package/dist/{schemas-9OpSSeM6.js → schemas-DAnu8tuW.js} +95 -13
- package/dist/schemas-DAnu8tuW.js.map +1 -0
- package/dist/wire.cjs +118 -3
- package/dist/wire.cjs.map +1 -1
- package/dist/wire.d.cts +139 -27
- package/dist/wire.d.ts +139 -27
- package/dist/wire.js +111 -4
- package/dist/wire.js.map +1 -1
- package/package.json +1 -1
- package/dist/builders-BvikWRuO.cjs.map +0 -1
- package/dist/builders-C548U47M.js.map +0 -1
- package/dist/fold-CB4fAOOy.js.map +0 -1
- package/dist/fold-IaMph3CO.cjs.map +0 -1
- package/dist/schemas-9OpSSeM6.js.map +0 -1
- package/dist/schemas-B_1VyFsm.cjs.map +0 -1
- package/dist/subtype-BvAzLCGC.js.map +0 -1
- package/dist/subtype-qejjVr6h.cjs.map +0 -1
package/dist/{DocumentSecurityService-Df79fgpe.d.cts → DocumentSecurityService-BV4_YXkU.d.cts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cc as IdentityClaims, Sc as DocCapability, kc as PdfBits, rc as CollabTarget } from "./AnnotationListSnapshot-DDxHpJQU.cjs";
|
|
2
2
|
//#region src/promise/AbortablePromise.d.ts
|
|
3
3
|
type AbortableExecutor<T, P> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: unknown) => void, progress: (p: P) => void, signal: AbortSignal) => void;
|
|
4
4
|
/**
|
|
@@ -312,6 +312,37 @@ interface DocumentSecurityService {
|
|
|
312
312
|
* only to *display* the concrete grants.
|
|
313
313
|
*/
|
|
314
314
|
allows(capability: DocCapability): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Per-record annotation authorization mirrors — the SAME resolver the
|
|
317
|
+
* engine enforces with (`checkCollab`'s narrowing rule: an applicable
|
|
318
|
+
* `annotations:<action>:<filter>` grant SHADOWS the coarse
|
|
319
|
+
* `doc.annotate.modify` fallback for that action), over the same
|
|
320
|
+
* inputs (raw scope + identity claims + PDF bits). `allows()` cannot
|
|
321
|
+
* answer these: it enumerates capabilities, and a filtered collab
|
|
322
|
+
* grant is not a capability — whether "update" is allowed depends on
|
|
323
|
+
* WHOSE annotation you're touching.
|
|
324
|
+
*
|
|
325
|
+
* Three surfaces because the questions genuinely differ:
|
|
326
|
+
* - create derives its target from the caller's OWN identity
|
|
327
|
+
* (`:self` trivially passes; `:group=X` matches the caller's
|
|
328
|
+
* default group),
|
|
329
|
+
* - update/delete are asked about the TARGET record's stamped
|
|
330
|
+
* owner (`userId`/`groupId` from its EMBD metadata; pass `{}`
|
|
331
|
+
* when unstamped — matching the engine, which denies unstamped
|
|
332
|
+
* targets under any narrowed grant),
|
|
333
|
+
* - group assignment is asked about the DESTINATION group
|
|
334
|
+
* (`annotations:set-group:` ladder; the caller's own default
|
|
335
|
+
* group is always assignable).
|
|
336
|
+
*
|
|
337
|
+
* These are a courtesy for UI gating — the engine (and the server,
|
|
338
|
+
* on cloud) independently enforces every mutation with the same
|
|
339
|
+
* predicates, so a stale or bypassed answer here never widens
|
|
340
|
+
* access. Returns false when no scope context exists (legacy local
|
|
341
|
+
* open without `scope`, cloud open without a token before /access).
|
|
342
|
+
*/
|
|
343
|
+
allowsAnnotationCreate(): boolean;
|
|
344
|
+
allowsAnnotationMutation(action: 'update' | 'delete', target: CollabTarget): boolean;
|
|
345
|
+
allowsAnnotationGroupAssignment(groupId: string): boolean;
|
|
315
346
|
/**
|
|
316
347
|
* Identity of the current caller, or null when anonymous.
|
|
317
348
|
*/
|
|
@@ -329,4 +360,4 @@ interface DocumentSecurityService {
|
|
|
329
360
|
}
|
|
330
361
|
//#endregion
|
|
331
362
|
export { DocumentEncryptionState as a, DocumentSecurityState as c, PdfPermissionAdvisory as d, PdfPermissionInfo as f, AbortablePromise as g, AbortableExecutor as h, DocumentAccessReason as i, DocumentUnlockInput as l, passwordPromptFromState as m, CdnAdapter as n, DocumentOpenMode as o, PasswordPrompt as p, DocumentAccessInfo as r, DocumentSecurityService as s, CdnAccessInfo as t, DocumentUnlockResult as u };
|
|
332
|
-
//# sourceMappingURL=DocumentSecurityService-
|
|
363
|
+
//# sourceMappingURL=DocumentSecurityService-BV4_YXkU.d.cts.map
|
package/dist/{DocumentSecurityService-B-tULKNY.d.ts → DocumentSecurityService-o9aeTHwT.d.ts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Cc as IdentityClaims, Sc as DocCapability, kc as PdfBits, rc as CollabTarget } from "./AnnotationListSnapshot-DDxHpJQU.js";
|
|
2
2
|
//#region src/promise/AbortablePromise.d.ts
|
|
3
3
|
type AbortableExecutor<T, P> = (resolve: (value: T | PromiseLike<T>) => void, reject: (reason: unknown) => void, progress: (p: P) => void, signal: AbortSignal) => void;
|
|
4
4
|
/**
|
|
@@ -312,6 +312,37 @@ interface DocumentSecurityService {
|
|
|
312
312
|
* only to *display* the concrete grants.
|
|
313
313
|
*/
|
|
314
314
|
allows(capability: DocCapability): boolean;
|
|
315
|
+
/**
|
|
316
|
+
* Per-record annotation authorization mirrors — the SAME resolver the
|
|
317
|
+
* engine enforces with (`checkCollab`'s narrowing rule: an applicable
|
|
318
|
+
* `annotations:<action>:<filter>` grant SHADOWS the coarse
|
|
319
|
+
* `doc.annotate.modify` fallback for that action), over the same
|
|
320
|
+
* inputs (raw scope + identity claims + PDF bits). `allows()` cannot
|
|
321
|
+
* answer these: it enumerates capabilities, and a filtered collab
|
|
322
|
+
* grant is not a capability — whether "update" is allowed depends on
|
|
323
|
+
* WHOSE annotation you're touching.
|
|
324
|
+
*
|
|
325
|
+
* Three surfaces because the questions genuinely differ:
|
|
326
|
+
* - create derives its target from the caller's OWN identity
|
|
327
|
+
* (`:self` trivially passes; `:group=X` matches the caller's
|
|
328
|
+
* default group),
|
|
329
|
+
* - update/delete are asked about the TARGET record's stamped
|
|
330
|
+
* owner (`userId`/`groupId` from its EMBD metadata; pass `{}`
|
|
331
|
+
* when unstamped — matching the engine, which denies unstamped
|
|
332
|
+
* targets under any narrowed grant),
|
|
333
|
+
* - group assignment is asked about the DESTINATION group
|
|
334
|
+
* (`annotations:set-group:` ladder; the caller's own default
|
|
335
|
+
* group is always assignable).
|
|
336
|
+
*
|
|
337
|
+
* These are a courtesy for UI gating — the engine (and the server,
|
|
338
|
+
* on cloud) independently enforces every mutation with the same
|
|
339
|
+
* predicates, so a stale or bypassed answer here never widens
|
|
340
|
+
* access. Returns false when no scope context exists (legacy local
|
|
341
|
+
* open without `scope`, cloud open without a token before /access).
|
|
342
|
+
*/
|
|
343
|
+
allowsAnnotationCreate(): boolean;
|
|
344
|
+
allowsAnnotationMutation(action: 'update' | 'delete', target: CollabTarget): boolean;
|
|
345
|
+
allowsAnnotationGroupAssignment(groupId: string): boolean;
|
|
315
346
|
/**
|
|
316
347
|
* Identity of the current caller, or null when anonymous.
|
|
317
348
|
*/
|
|
@@ -329,4 +360,4 @@ interface DocumentSecurityService {
|
|
|
329
360
|
}
|
|
330
361
|
//#endregion
|
|
331
362
|
export { DocumentEncryptionState as a, DocumentSecurityState as c, PdfPermissionAdvisory as d, PdfPermissionInfo as f, AbortablePromise as g, AbortableExecutor as h, DocumentAccessReason as i, DocumentUnlockInput as l, passwordPromptFromState as m, CdnAdapter as n, DocumentOpenMode as o, PasswordPrompt as p, DocumentAccessInfo as r, DocumentSecurityService as s, CdnAccessInfo as t, DocumentUnlockResult as u };
|
|
332
|
-
//# sourceMappingURL=DocumentSecurityService-
|
|
363
|
+
//# sourceMappingURL=DocumentSecurityService-o9aeTHwT.d.ts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as AbortablePromise, s as DocumentSecurityService } from "./DocumentSecurityService-
|
|
1
|
+
import { $r as FormEffectsResult, Aa as AttachmentDeleteResult, Ao as FontKey, Bi as FormFieldRef, Di as FormFieldDTO, Dr as SearchRequest, Fn as RedactionApplyScope, Gi as AnnotationDeleteResult, Gn as PageDeleteResult, Gr as FormFieldUpdateResult, Ho as AnnotationAppearanceRenderOptions, Hr as FormDataExport, Io as AnnotationAppearanceImageOptions, Jr as FormSetValueResult, Ka as AttachmentContent, Ki as AnnotationMoveResult, Kr as FormImportResult, Lo as AnnotationAppearanceImagesResult, Mn as MetadataUpdateResult, No as PdfSaveMode, Or as SearchSlice, Pc as PageObjectNumber, Pn as RedactionApplyResult, Qo as PageImageOptions, Un as PageInsertBlankSpec, Ur as FormFieldCreateResult, Us as MetadataPatch, Vi as FormWidgetRef, Vn as PageFlattenUsage, Wi as AnnotationCreateResult, Wn as PageInsertResult, Wo as AnnotationAppearancesResult, Wr as FormFieldDeleteResult, Ws as OpenInput, Xa as EmbeddedFileItem, Xn as PageMoveResult, Xo as PageImageHandle, Xr as FormEffect, Ya as AttachmentFileSource, Yr as FormWidgetLinkResult, Za as EmbeddedFileRef, Zs as OpenOptions, ai as FormFieldPatch, bs as PageTextSnapshot, di as FormFieldDraft, fl as DocumentActionsSnapshot, jc as AnnotationRef, jo as FontSpec, ka as AttachmentCreateResult, ko as FontHandle, l as AnnotationPatch, ll as PdfRotation, ls as PageRenderViewport, n as AnnotationListSnapshotAllPages, ni as FormFieldValue, ns as PageRaster, o as AnnotationDraft, os as PageRenderOptions, ps as PageGeometrySnapshot, qi as AnnotationUpdateResult, qn as PageRotateResult, qr as FormRepairResult, t as AnnotationListPageSnapshot, ti as FormDataFormat, vi as FormSnapshot, xl as DocumentMetadata, zn as PageFlattenResult, zs as PageListSnapshot } from "./AnnotationListSnapshot-DDxHpJQU.cjs";
|
|
2
|
+
import { g as AbortablePromise, s as DocumentSecurityService } from "./DocumentSecurityService-BV4_YXkU.cjs";
|
|
3
3
|
//#region src/engine/DocumentActionsService.d.ts
|
|
4
4
|
/** Lazy, catalog-owned PDF action read. This API extracts; it never executes. */
|
|
5
5
|
interface DocumentActionsService {
|
|
@@ -262,27 +262,37 @@ interface DocumentPagesService {
|
|
|
262
262
|
* the source document is untouched — no revisions bump, no event is
|
|
263
263
|
* published. This is how a page becomes a portable asset (a vector
|
|
264
264
|
* stamp, a signature) that re-enters a document as a stamp draft's
|
|
265
|
-
* `source` bytes.
|
|
265
|
+
* `source` bytes. Gated by `doc.download` (it egresses content), not
|
|
266
|
+
* `doc.pages.assemble`.
|
|
266
267
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
* until the server exposes extraction. Feature-detect with
|
|
270
|
-
* `pages.extract !== undefined`.
|
|
268
|
+
* REQUIRED-parity, delivered: the local engine runs it in the worker,
|
|
269
|
+
* the cloud engine as POST /pages/extract.
|
|
271
270
|
*/
|
|
272
|
-
extract
|
|
271
|
+
extract(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<Uint8Array>;
|
|
273
272
|
/**
|
|
274
273
|
* Insert every page of a standalone PDF (`bytes`) at `destIndex`
|
|
275
274
|
* (omitted → append). The pages are COPIED in; the inserted copies get
|
|
276
275
|
* fresh object numbers, returned in insertion order. Bytes are a call
|
|
277
276
|
* ARGUMENT (the same law as annotation binaries): the local engine
|
|
278
|
-
* transfers them to its worker, the cloud engine
|
|
279
|
-
* multipart mutation.
|
|
277
|
+
* transfers them to its worker, the cloud engine ships them as a
|
|
278
|
+
* multipart mutation (POST /pages/insert).
|
|
280
279
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
280
|
+
* REQUIRED-parity, delivered — a cloud viewer must be able to add pages,
|
|
281
|
+
* so this is a mandatory member: any engine implements it or is not a
|
|
282
|
+
* conforming engine.
|
|
284
283
|
*/
|
|
285
|
-
insert
|
|
284
|
+
insert(bytes: Uint8Array | ArrayBuffer, destIndex?: number): AbortablePromise<PageInsertResult>;
|
|
285
|
+
/**
|
|
286
|
+
* Create `spec.count` (default 1) blank pages of `spec.size` (PDF points)
|
|
287
|
+
* at `destIndex` (omitted → append). The blank-page sibling of `insert`:
|
|
288
|
+
* same gate (`doc.pages.assemble`), same result shape, same
|
|
289
|
+
* `pages.inserted` event — it is a separate verb because its wire is pure
|
|
290
|
+
* parameters where `insert`'s is a binary payload (cloud: JSON
|
|
291
|
+
* POST /pages/insert-blank). The new pages get fresh, never-recycled
|
|
292
|
+
* object numbers; every pre-existing page keeps its identity and
|
|
293
|
+
* revisions. Mandatory, like `insert`.
|
|
294
|
+
*/
|
|
295
|
+
insertBlank(spec: PageInsertBlankSpec, destIndex?: number): AbortablePromise<PageInsertResult>;
|
|
286
296
|
}
|
|
287
297
|
//#endregion
|
|
288
298
|
//#region src/engine/DocumentRedactionService.d.ts
|
|
@@ -439,7 +449,7 @@ declare function snapTileScale(policy: EngineRenderPolicy, scale: number): numbe
|
|
|
439
449
|
* layer is unfindable, and a cursor issued before a content mutation is
|
|
440
450
|
* rejected rather than resumed over stale pages.
|
|
441
451
|
*
|
|
442
|
-
* Matches carry
|
|
452
|
+
* Matches carry canonical visual-line segments from the same layout as text
|
|
443
453
|
* selection (never per-glyph boxes) and text-page character offsets that
|
|
444
454
|
* join the selection/geometry subsystem directly.
|
|
445
455
|
*/
|
|
@@ -790,12 +800,33 @@ type DocumentEvent = ({
|
|
|
790
800
|
} & PageFlattenResult) | ({
|
|
791
801
|
type: 'redaction.applied';
|
|
792
802
|
origin: EventOrigin;
|
|
793
|
-
} & RedactionApplyResult)
|
|
803
|
+
} & RedactionApplyResult) | {
|
|
804
|
+
/**
|
|
805
|
+
* Cloud only: the live event stream fell too far behind to replay
|
|
806
|
+
* (the server's SSE `full-refresh`) — state derived from earlier
|
|
807
|
+
* events or snapshots may be stale, and the gap's mutations will
|
|
808
|
+
* NEVER arrive as events. Consumers must re-read the snapshots they
|
|
809
|
+
* keep fresh from this stream (`doc.annotations.listRawAll()`,
|
|
810
|
+
* `doc.forms.list()`, …).
|
|
811
|
+
*
|
|
812
|
+
* Carries no `EventOrigin`: it is a transport notice, not a
|
|
813
|
+
* document mutation — the exactly-once / results-ride-verbatim
|
|
814
|
+
* invariants above apply to mutation events only. The local engine
|
|
815
|
+
* never emits it.
|
|
816
|
+
*/
|
|
817
|
+
type: 'stream.desynced';
|
|
818
|
+
reason: 'backlog-overflow';
|
|
819
|
+
ts: number;
|
|
820
|
+
};
|
|
794
821
|
type DocumentEventType = DocumentEvent['type'];
|
|
795
822
|
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
796
823
|
/** A `DocumentEvent` before provenance is stamped — what mutation paths
|
|
797
|
-
* hand to their engine's publisher, which adds `origin`.
|
|
798
|
-
|
|
824
|
+
* hand to their engine's publisher, which adds `origin`. Transport
|
|
825
|
+
* notices (`stream.desynced`) are excluded: they are published directly
|
|
826
|
+
* by the remote channel, never through a mutation publisher. */
|
|
827
|
+
type DocumentEventInit = DistributiveOmit<Exclude<DocumentEvent, {
|
|
828
|
+
type: 'stream.desynced';
|
|
829
|
+
}>, 'origin'>;
|
|
799
830
|
//#endregion
|
|
800
831
|
//#region src/events/DocumentEventStream.d.ts
|
|
801
832
|
/**
|
|
@@ -1010,4 +1041,4 @@ interface Engine {
|
|
|
1010
1041
|
type EngineFactory = () => Engine;
|
|
1011
1042
|
//#endregion
|
|
1012
1043
|
export { DocumentPagesService as A, CONTINUOUS_RENDER_POLICY as C, snapFullPageViewport as D, snapAppearanceScale as E, WeakAnnotationEditSession as F, DocumentActionsService as I, FormRepairOptions as M, DocumentAttachmentsService as N, snapTileScale as O, DocumentAnnotationsService as P, DocumentSearchService as S, EngineRenderPolicy as T, PageTextService as _, DocumentHandle as a, PageAnnotationsService as b, DocumentEventInit as c, PageHandle as d, PieceInfoService as f, PieceInfoSnapshot as g, PieceInfoPatchValue as h, DocumentCapabilities as i, DocumentFormsService as j, DocumentRedactionService as k, DocumentEventType as l, PieceInfoPatch as m, EngineFactory as n, DocumentEventStream as o, PieceInfoEntry as p, FontService as r, DocumentEvent as s, Engine as t, EventOrigin as u, PageRenderService as v, DocumentRenderService as w, MetadataService as x, PageGeometryService as y };
|
|
1013
|
-
//# sourceMappingURL=Engine-
|
|
1044
|
+
//# sourceMappingURL=Engine-D9je6GdU.d.cts.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { g as AbortablePromise, s as DocumentSecurityService } from "./DocumentSecurityService-
|
|
1
|
+
import { $r as FormEffectsResult, Aa as AttachmentDeleteResult, Ao as FontKey, Bi as FormFieldRef, Di as FormFieldDTO, Dr as SearchRequest, Fn as RedactionApplyScope, Gi as AnnotationDeleteResult, Gn as PageDeleteResult, Gr as FormFieldUpdateResult, Ho as AnnotationAppearanceRenderOptions, Hr as FormDataExport, Io as AnnotationAppearanceImageOptions, Jr as FormSetValueResult, Ka as AttachmentContent, Ki as AnnotationMoveResult, Kr as FormImportResult, Lo as AnnotationAppearanceImagesResult, Mn as MetadataUpdateResult, No as PdfSaveMode, Or as SearchSlice, Pc as PageObjectNumber, Pn as RedactionApplyResult, Qo as PageImageOptions, Un as PageInsertBlankSpec, Ur as FormFieldCreateResult, Us as MetadataPatch, Vi as FormWidgetRef, Vn as PageFlattenUsage, Wi as AnnotationCreateResult, Wn as PageInsertResult, Wo as AnnotationAppearancesResult, Wr as FormFieldDeleteResult, Ws as OpenInput, Xa as EmbeddedFileItem, Xn as PageMoveResult, Xo as PageImageHandle, Xr as FormEffect, Ya as AttachmentFileSource, Yr as FormWidgetLinkResult, Za as EmbeddedFileRef, Zs as OpenOptions, ai as FormFieldPatch, bs as PageTextSnapshot, di as FormFieldDraft, fl as DocumentActionsSnapshot, jc as AnnotationRef, jo as FontSpec, ka as AttachmentCreateResult, ko as FontHandle, l as AnnotationPatch, ll as PdfRotation, ls as PageRenderViewport, n as AnnotationListSnapshotAllPages, ni as FormFieldValue, ns as PageRaster, o as AnnotationDraft, os as PageRenderOptions, ps as PageGeometrySnapshot, qi as AnnotationUpdateResult, qn as PageRotateResult, qr as FormRepairResult, t as AnnotationListPageSnapshot, ti as FormDataFormat, vi as FormSnapshot, xl as DocumentMetadata, zn as PageFlattenResult, zs as PageListSnapshot } from "./AnnotationListSnapshot-DDxHpJQU.js";
|
|
2
|
+
import { g as AbortablePromise, s as DocumentSecurityService } from "./DocumentSecurityService-o9aeTHwT.js";
|
|
3
3
|
//#region src/engine/DocumentActionsService.d.ts
|
|
4
4
|
/** Lazy, catalog-owned PDF action read. This API extracts; it never executes. */
|
|
5
5
|
interface DocumentActionsService {
|
|
@@ -262,27 +262,37 @@ interface DocumentPagesService {
|
|
|
262
262
|
* the source document is untouched — no revisions bump, no event is
|
|
263
263
|
* published. This is how a page becomes a portable asset (a vector
|
|
264
264
|
* stamp, a signature) that re-enters a document as a stamp draft's
|
|
265
|
-
* `source` bytes.
|
|
265
|
+
* `source` bytes. Gated by `doc.download` (it egresses content), not
|
|
266
|
+
* `doc.pages.assemble`.
|
|
266
267
|
*
|
|
267
|
-
*
|
|
268
|
-
*
|
|
269
|
-
* until the server exposes extraction. Feature-detect with
|
|
270
|
-
* `pages.extract !== undefined`.
|
|
268
|
+
* REQUIRED-parity, delivered: the local engine runs it in the worker,
|
|
269
|
+
* the cloud engine as POST /pages/extract.
|
|
271
270
|
*/
|
|
272
|
-
extract
|
|
271
|
+
extract(pageObjectNumbers: PageObjectNumber[]): AbortablePromise<Uint8Array>;
|
|
273
272
|
/**
|
|
274
273
|
* Insert every page of a standalone PDF (`bytes`) at `destIndex`
|
|
275
274
|
* (omitted → append). The pages are COPIED in; the inserted copies get
|
|
276
275
|
* fresh object numbers, returned in insertion order. Bytes are a call
|
|
277
276
|
* ARGUMENT (the same law as annotation binaries): the local engine
|
|
278
|
-
* transfers them to its worker, the cloud engine
|
|
279
|
-
* multipart mutation.
|
|
277
|
+
* transfers them to its worker, the cloud engine ships them as a
|
|
278
|
+
* multipart mutation (POST /pages/insert).
|
|
280
279
|
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
280
|
+
* REQUIRED-parity, delivered — a cloud viewer must be able to add pages,
|
|
281
|
+
* so this is a mandatory member: any engine implements it or is not a
|
|
282
|
+
* conforming engine.
|
|
284
283
|
*/
|
|
285
|
-
insert
|
|
284
|
+
insert(bytes: Uint8Array | ArrayBuffer, destIndex?: number): AbortablePromise<PageInsertResult>;
|
|
285
|
+
/**
|
|
286
|
+
* Create `spec.count` (default 1) blank pages of `spec.size` (PDF points)
|
|
287
|
+
* at `destIndex` (omitted → append). The blank-page sibling of `insert`:
|
|
288
|
+
* same gate (`doc.pages.assemble`), same result shape, same
|
|
289
|
+
* `pages.inserted` event — it is a separate verb because its wire is pure
|
|
290
|
+
* parameters where `insert`'s is a binary payload (cloud: JSON
|
|
291
|
+
* POST /pages/insert-blank). The new pages get fresh, never-recycled
|
|
292
|
+
* object numbers; every pre-existing page keeps its identity and
|
|
293
|
+
* revisions. Mandatory, like `insert`.
|
|
294
|
+
*/
|
|
295
|
+
insertBlank(spec: PageInsertBlankSpec, destIndex?: number): AbortablePromise<PageInsertResult>;
|
|
286
296
|
}
|
|
287
297
|
//#endregion
|
|
288
298
|
//#region src/engine/DocumentRedactionService.d.ts
|
|
@@ -439,7 +449,7 @@ declare function snapTileScale(policy: EngineRenderPolicy, scale: number): numbe
|
|
|
439
449
|
* layer is unfindable, and a cursor issued before a content mutation is
|
|
440
450
|
* rejected rather than resumed over stale pages.
|
|
441
451
|
*
|
|
442
|
-
* Matches carry
|
|
452
|
+
* Matches carry canonical visual-line segments from the same layout as text
|
|
443
453
|
* selection (never per-glyph boxes) and text-page character offsets that
|
|
444
454
|
* join the selection/geometry subsystem directly.
|
|
445
455
|
*/
|
|
@@ -790,12 +800,33 @@ type DocumentEvent = ({
|
|
|
790
800
|
} & PageFlattenResult) | ({
|
|
791
801
|
type: 'redaction.applied';
|
|
792
802
|
origin: EventOrigin;
|
|
793
|
-
} & RedactionApplyResult)
|
|
803
|
+
} & RedactionApplyResult) | {
|
|
804
|
+
/**
|
|
805
|
+
* Cloud only: the live event stream fell too far behind to replay
|
|
806
|
+
* (the server's SSE `full-refresh`) — state derived from earlier
|
|
807
|
+
* events or snapshots may be stale, and the gap's mutations will
|
|
808
|
+
* NEVER arrive as events. Consumers must re-read the snapshots they
|
|
809
|
+
* keep fresh from this stream (`doc.annotations.listRawAll()`,
|
|
810
|
+
* `doc.forms.list()`, …).
|
|
811
|
+
*
|
|
812
|
+
* Carries no `EventOrigin`: it is a transport notice, not a
|
|
813
|
+
* document mutation — the exactly-once / results-ride-verbatim
|
|
814
|
+
* invariants above apply to mutation events only. The local engine
|
|
815
|
+
* never emits it.
|
|
816
|
+
*/
|
|
817
|
+
type: 'stream.desynced';
|
|
818
|
+
reason: 'backlog-overflow';
|
|
819
|
+
ts: number;
|
|
820
|
+
};
|
|
794
821
|
type DocumentEventType = DocumentEvent['type'];
|
|
795
822
|
type DistributiveOmit<T, K extends PropertyKey> = T extends unknown ? Omit<T, K> : never;
|
|
796
823
|
/** A `DocumentEvent` before provenance is stamped — what mutation paths
|
|
797
|
-
* hand to their engine's publisher, which adds `origin`.
|
|
798
|
-
|
|
824
|
+
* hand to their engine's publisher, which adds `origin`. Transport
|
|
825
|
+
* notices (`stream.desynced`) are excluded: they are published directly
|
|
826
|
+
* by the remote channel, never through a mutation publisher. */
|
|
827
|
+
type DocumentEventInit = DistributiveOmit<Exclude<DocumentEvent, {
|
|
828
|
+
type: 'stream.desynced';
|
|
829
|
+
}>, 'origin'>;
|
|
799
830
|
//#endregion
|
|
800
831
|
//#region src/events/DocumentEventStream.d.ts
|
|
801
832
|
/**
|
|
@@ -1010,4 +1041,4 @@ interface Engine {
|
|
|
1010
1041
|
type EngineFactory = () => Engine;
|
|
1011
1042
|
//#endregion
|
|
1012
1043
|
export { DocumentPagesService as A, CONTINUOUS_RENDER_POLICY as C, snapFullPageViewport as D, snapAppearanceScale as E, WeakAnnotationEditSession as F, DocumentActionsService as I, FormRepairOptions as M, DocumentAttachmentsService as N, snapTileScale as O, DocumentAnnotationsService as P, DocumentSearchService as S, EngineRenderPolicy as T, PageTextService as _, DocumentHandle as a, PageAnnotationsService as b, DocumentEventInit as c, PageHandle as d, PieceInfoService as f, PieceInfoSnapshot as g, PieceInfoPatchValue as h, DocumentCapabilities as i, DocumentFormsService as j, DocumentRedactionService as k, DocumentEventType as l, PieceInfoPatch as m, EngineFactory as n, DocumentEventStream as o, PieceInfoEntry as p, FontService as r, DocumentEvent as s, Engine as t, EventOrigin as u, PageRenderService as v, DocumentRenderService as w, MetadataService as x, PageGeometryService as y };
|
|
1013
|
-
//# sourceMappingURL=Engine-
|
|
1044
|
+
//# sourceMappingURL=Engine-DOoVem7_.d.ts.map
|
|
@@ -6,6 +6,14 @@ const EngineErrorCode = {
|
|
|
6
6
|
DocOpenFailed: "DocOpenFailed",
|
|
7
7
|
DocPasswordRequired: "DocPasswordRequired",
|
|
8
8
|
DocPasswordIncorrect: "DocPasswordIncorrect",
|
|
9
|
+
/**
|
|
10
|
+
* A share-token exchange (`open({ kind: 'share' })`) needs the grant's
|
|
11
|
+
* passphrase: none was supplied, or the supplied one was rejected —
|
|
12
|
+
* indistinguishable by design, mirroring the server. Prompt and retry
|
|
13
|
+
* with `sharePassword`. Distinct from `DocPasswordRequired`, which is
|
|
14
|
+
* about the PDF's own encryption password.
|
|
15
|
+
*/
|
|
16
|
+
SharePasswordRequired: "SharePasswordRequired",
|
|
9
17
|
Aborted: "Aborted",
|
|
10
18
|
Network: "Network",
|
|
11
19
|
Unauthenticated: "Unauthenticated",
|
|
@@ -191,6 +199,145 @@ function subtypeFromCode(code) {
|
|
|
191
199
|
return PDF_CODE_TO_SUBTYPE[code] ?? "unsupported";
|
|
192
200
|
}
|
|
193
201
|
//#endregion
|
|
202
|
+
//#region src/text/charmap.ts
|
|
203
|
+
const clampInt = (value, lo, hi) => Math.min(Math.max(Math.floor(value), lo), hi);
|
|
204
|
+
/** The greatest anchor with `anchor.char <= boundary` (implicit head [0,0]). */
|
|
205
|
+
function anchorAtOrBefore(map, boundary) {
|
|
206
|
+
let lo = 0;
|
|
207
|
+
let hi = map.length - 1;
|
|
208
|
+
let best = null;
|
|
209
|
+
while (lo <= hi) {
|
|
210
|
+
const mid = lo + hi >> 1;
|
|
211
|
+
if (map[mid][0] <= boundary) {
|
|
212
|
+
best = map[mid];
|
|
213
|
+
lo = mid + 1;
|
|
214
|
+
} else hi = mid - 1;
|
|
215
|
+
}
|
|
216
|
+
return best ?? [0, 0];
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Text offset of character boundary `boundary` (clamped into
|
|
220
|
+
* [0, charCount]). For a dropped character this is the offset of the next
|
|
221
|
+
* real text unit — exactly what half-open slicing needs at either end.
|
|
222
|
+
*/
|
|
223
|
+
function boundaryTextOffset(snapshot, boundary) {
|
|
224
|
+
const b = clampInt(boundary, 0, snapshot.charCount);
|
|
225
|
+
const map = snapshot.charMap;
|
|
226
|
+
if (!map || map.length === 0) return Math.min(b, snapshot.text.length);
|
|
227
|
+
const [char, text] = anchorAtOrBefore(map, b);
|
|
228
|
+
return text + (b - char);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* The character boundary for a text offset, with explicit plateau bias:
|
|
232
|
+
*
|
|
233
|
+
* - `'start'`: the GREATEST boundary whose text offset is <= `offset` —
|
|
234
|
+
* scans forward past zero-width characters, so a range start never
|
|
235
|
+
* includes a dropped character that precedes its first real unit.
|
|
236
|
+
* - `'end'`: the SMALLEST boundary whose text offset is >= `offset` —
|
|
237
|
+
* stops before zero-width characters, so a range end never swallows a
|
|
238
|
+
* dropped character that follows its last real unit.
|
|
239
|
+
*
|
|
240
|
+
* An offset inside a surrogate pair resolves outward under both biases
|
|
241
|
+
* (start → the pair's character, end → past it), so a clipped astral
|
|
242
|
+
* character is always covered whole. Prefer {@link charRangeForTextOffsets}
|
|
243
|
+
* — the two biases exist to be used as a PAIR.
|
|
244
|
+
*/
|
|
245
|
+
function charBoundaryAtTextOffset(snapshot, offset, bias) {
|
|
246
|
+
const target = clampInt(offset, 0, snapshot.text.length);
|
|
247
|
+
let lo = 0;
|
|
248
|
+
let hi = snapshot.charCount;
|
|
249
|
+
if (bias === "start") {
|
|
250
|
+
while (lo < hi) {
|
|
251
|
+
const mid = lo + Math.ceil((hi - lo) / 2);
|
|
252
|
+
if (boundaryTextOffset(snapshot, mid) <= target) lo = mid;
|
|
253
|
+
else hi = mid - 1;
|
|
254
|
+
}
|
|
255
|
+
return lo;
|
|
256
|
+
}
|
|
257
|
+
while (lo < hi) {
|
|
258
|
+
const mid = lo + hi >> 1;
|
|
259
|
+
if (boundaryTextOffset(snapshot, mid) >= target) hi = mid;
|
|
260
|
+
else lo = mid + 1;
|
|
261
|
+
}
|
|
262
|
+
return lo;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* The character range whose text projection is exactly
|
|
266
|
+
* `text.slice(startOffset, endOffset)` — THE inverse used by search-hit
|
|
267
|
+
* conversion and select-by-text. Start is right-biased and end left-biased
|
|
268
|
+
* (see {@link charBoundaryAtTextOffset}), so zero-width characters adjacent
|
|
269
|
+
* to the range fall OUTSIDE it on both sides.
|
|
270
|
+
*
|
|
271
|
+
* A non-empty text range can never invert: `end > start` implies
|
|
272
|
+
* `B(end) >= endOffset > startOffset >= B(start)`, which forces
|
|
273
|
+
* `end > start` by monotonicity. Empty input (`endOffset <= startOffset`)
|
|
274
|
+
* normalizes to the end-rule boundary of `startOffset` on both sides.
|
|
275
|
+
*/
|
|
276
|
+
function charRangeForTextOffsets(snapshot, startOffset, endOffset) {
|
|
277
|
+
if (endOffset <= startOffset) {
|
|
278
|
+
const b = charBoundaryAtTextOffset(snapshot, startOffset, "end");
|
|
279
|
+
return {
|
|
280
|
+
start: b,
|
|
281
|
+
end: b
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return {
|
|
285
|
+
start: charBoundaryAtTextOffset(snapshot, startOffset, "start"),
|
|
286
|
+
end: charBoundaryAtTextOffset(snapshot, endOffset, "end")
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/**
|
|
290
|
+
* THE copy primitive: the text projection of the half-open character range
|
|
291
|
+
* `[charStart, charEnd)`. Dropped characters inside the range contribute
|
|
292
|
+
* nothing; a supplementary character contributes its full surrogate pair.
|
|
293
|
+
* `sliceTextByChars(s, 0, s.charCount) === s.text` always.
|
|
294
|
+
*/
|
|
295
|
+
function sliceTextByChars(snapshot, charStart, charEnd) {
|
|
296
|
+
if (charEnd <= charStart) return "";
|
|
297
|
+
return snapshot.text.slice(boundaryTextOffset(snapshot, charStart), boundaryTextOffset(snapshot, charEnd));
|
|
298
|
+
}
|
|
299
|
+
/**
|
|
300
|
+
* First invariant violation of a snapshot's char map, or null when valid.
|
|
301
|
+
* Shared by the wire schema (rejects malformed bodies) and engine builders
|
|
302
|
+
* (dev-mode assertion). The invariants:
|
|
303
|
+
*
|
|
304
|
+
* 1. absent/empty map ⇒ identity, so `charCount === text.length`;
|
|
305
|
+
* 2. anchor chars strictly increasing, each in [1, charCount];
|
|
306
|
+
* 3. step rule: against the previous anchor (implicit head [0, 0]), the
|
|
307
|
+
* character just before each anchor contributed exactly 0 units
|
|
308
|
+
* (dropped) or 2 (surrogate pair):
|
|
309
|
+
* `t₂ - (t₁ + (c₂ - c₁ - 1)) ∈ {0, 2}`;
|
|
310
|
+
* 4. tail: `lastText + (charCount - lastChar) === text.length`
|
|
311
|
+
* (equivalently `boundaryTextOffset(s, charCount) === text.length`).
|
|
312
|
+
*/
|
|
313
|
+
function charMapViolation(charCount, textLength, charMap) {
|
|
314
|
+
if (!charMap || charMap.length === 0) return charCount === textLength ? null : `identity map requires charCount (${charCount}) === text length (${textLength})`;
|
|
315
|
+
let prevChar = 0;
|
|
316
|
+
let prevText = 0;
|
|
317
|
+
for (let i = 0; i < charMap.length; i++) {
|
|
318
|
+
const [char, text] = charMap[i];
|
|
319
|
+
if (!Number.isInteger(char) || !Number.isInteger(text)) return `anchor ${i} is not integer-valued`;
|
|
320
|
+
if (char <= prevChar) return `anchor ${i} char ${char} not strictly after ${prevChar}`;
|
|
321
|
+
if (char > charCount) return `anchor ${i} char ${char} outside [1, ${charCount}]`;
|
|
322
|
+
const step = text - (prevText + (char - prevChar - 1));
|
|
323
|
+
if (step !== 0 && step !== 2) return `anchor ${i} implies a character contributing ${step} text units (expected 0 or 2)`;
|
|
324
|
+
prevChar = char;
|
|
325
|
+
prevText = text;
|
|
326
|
+
}
|
|
327
|
+
const tail = prevText + (charCount - prevChar);
|
|
328
|
+
if (tail !== textLength) return `map projects charCount to ${tail}, but text length is ${textLength}`;
|
|
329
|
+
return null;
|
|
330
|
+
}
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/mutation/PageInsertBlankInput.ts
|
|
333
|
+
/**
|
|
334
|
+
* Upper bound on `count` for a single `pages.insertBlank()` call. A CONTRACT
|
|
335
|
+
* cap, enforced identically by every engine (the cloud input schema carries
|
|
336
|
+
* the same number), so a UI never discovers a lower server limit by surprise.
|
|
337
|
+
* Larger batches are a loop at the call site.
|
|
338
|
+
*/
|
|
339
|
+
const PAGE_INSERT_BLANK_MAX_COUNT = 100;
|
|
340
|
+
//#endregion
|
|
194
341
|
Object.defineProperty(exports, "ANNOTATION_SUBTYPES", {
|
|
195
342
|
enumerable: true,
|
|
196
343
|
get: function() {
|
|
@@ -203,6 +350,12 @@ Object.defineProperty(exports, "EngineErrorCode", {
|
|
|
203
350
|
return EngineErrorCode;
|
|
204
351
|
}
|
|
205
352
|
});
|
|
353
|
+
Object.defineProperty(exports, "PAGE_INSERT_BLANK_MAX_COUNT", {
|
|
354
|
+
enumerable: true,
|
|
355
|
+
get: function() {
|
|
356
|
+
return PAGE_INSERT_BLANK_MAX_COUNT;
|
|
357
|
+
}
|
|
358
|
+
});
|
|
206
359
|
Object.defineProperty(exports, "PDF_CODE_TO_SUBTYPE", {
|
|
207
360
|
enumerable: true,
|
|
208
361
|
get: function() {
|
|
@@ -221,6 +374,36 @@ Object.defineProperty(exports, "PdfAnnotationSubtypeCode", {
|
|
|
221
374
|
return PdfAnnotationSubtypeCode;
|
|
222
375
|
}
|
|
223
376
|
});
|
|
377
|
+
Object.defineProperty(exports, "boundaryTextOffset", {
|
|
378
|
+
enumerable: true,
|
|
379
|
+
get: function() {
|
|
380
|
+
return boundaryTextOffset;
|
|
381
|
+
}
|
|
382
|
+
});
|
|
383
|
+
Object.defineProperty(exports, "charBoundaryAtTextOffset", {
|
|
384
|
+
enumerable: true,
|
|
385
|
+
get: function() {
|
|
386
|
+
return charBoundaryAtTextOffset;
|
|
387
|
+
}
|
|
388
|
+
});
|
|
389
|
+
Object.defineProperty(exports, "charMapViolation", {
|
|
390
|
+
enumerable: true,
|
|
391
|
+
get: function() {
|
|
392
|
+
return charMapViolation;
|
|
393
|
+
}
|
|
394
|
+
});
|
|
395
|
+
Object.defineProperty(exports, "charRangeForTextOffsets", {
|
|
396
|
+
enumerable: true,
|
|
397
|
+
get: function() {
|
|
398
|
+
return charRangeForTextOffsets;
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
Object.defineProperty(exports, "sliceTextByChars", {
|
|
402
|
+
enumerable: true,
|
|
403
|
+
get: function() {
|
|
404
|
+
return sliceTextByChars;
|
|
405
|
+
}
|
|
406
|
+
});
|
|
224
407
|
Object.defineProperty(exports, "subtypeFromCode", {
|
|
225
408
|
enumerable: true,
|
|
226
409
|
get: function() {
|
|
@@ -228,4 +411,4 @@ Object.defineProperty(exports, "subtypeFromCode", {
|
|
|
228
411
|
}
|
|
229
412
|
});
|
|
230
413
|
|
|
231
|
-
//# sourceMappingURL=
|
|
414
|
+
//# sourceMappingURL=PageInsertBlankInput-CzShuSJI.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageInsertBlankInput-CzShuSJI.cjs","names":[],"sources":["../src/errors/EngineErrorCode.ts","../src/annotation/subtype.ts","../src/text/charmap.ts","../src/mutation/PageInsertBlankInput.ts"],"sourcesContent":["export const EngineErrorCode = {\n Unknown: 'Unknown',\n InvalidArg: 'InvalidArg',\n DocNotOpen: 'DocNotOpen',\n DocOpenFailed: 'DocOpenFailed',\n DocPasswordRequired: 'DocPasswordRequired',\n DocPasswordIncorrect: 'DocPasswordIncorrect',\n /**\n * A share-token exchange (`open({ kind: 'share' })`) needs the grant's\n * passphrase: none was supplied, or the supplied one was rejected —\n * indistinguishable by design, mirroring the server. Prompt and retry\n * with `sharePassword`. Distinct from `DocPasswordRequired`, which is\n * about the PDF's own encryption password.\n */\n SharePasswordRequired: 'SharePasswordRequired',\n Aborted: 'Aborted',\n Network: 'Network',\n Unauthenticated: 'Unauthenticated',\n Forbidden: 'Forbidden',\n NotFound: 'NotFound',\n WireFormat: 'WireFormat',\n RuntimeUnavailable: 'RuntimeUnavailable',\n /**\n * Annotation/page reference could not be resolved. Surfaced when:\n * - `AnnotationRef.kind === 'objectNumber'` but the document has no\n * annotation with that indirect object number on the addressed page\n * - `AnnotationRef.kind === 'nm'` but no annotation on the page has\n * that `/NM`\n * - `AnnotationRef.kind === 'index'` but the supplied `RevisionToken`\n * does not match the current per-page generation\n * - `AnnotationRef.kind === 'index'` but `index` is out of range for\n * the page's current annotation count\n */\n InvalidReference: 'InvalidReference',\n /**\n * A weak-annotation structural edit (delete/move) was attempted while the\n * caller does not have sole active edit presence for that page. This is a\n * collaboration guard for index-addressed annotations; stable pages and\n * non-shifting annotation updates do not use it.\n */\n WeakAnnotationSessionConflict: 'WeakAnnotationSessionConflict',\n /**\n * A layer write lost its optimistic-concurrency check: the layer's\n * durable version advanced (another writer — typically another server\n * replica — committed) between the operation's prepare and its commit,\n * and the server exhausted its rebase-and-retry budget. Retryable: the\n * operation was NOT applied; re-issue it against the new state.\n */\n LayerVersionConflict: 'LayerVersionConflict',\n /**\n * The requested operation is typed but not yet wired in this engine\n * version. The wire shape stays valid; clients can detect this with\n * `EngineError.is(err, EngineErrorCode.NotImplemented)` and degrade\n * gracefully.\n */\n NotImplemented: 'NotImplemented',\n /**\n * The PDF was loadable enough for PDFium to parse, but violates a\n * structural invariant the engine relies on. Surfaced for the rare\n * spec-violating PDF that ships a direct (non-indirect) page\n * dictionary in the /Pages tree — see `EPDFPage_GetObjectNumber`\n * returning `0`. PDFium creation paths (`FPDFPage_New`,\n * `EPDFPage_CreateAnnot`) always produce indirect objects, so this\n * error code is intentionally not used for engine-produced state;\n * it specifically signals \"this input file is broken in a way we\n * cannot work around without compromising stable identity\".\n *\n * Distinct from `DocOpenFailed` (PDFium refused to load the bytes\n * at all) and `NotFound` (a well-formed page/annotation/etc. simply\n * doesn't exist).\n */\n MalformedPdf: 'MalformedPdf',\n} as const;\n\nexport type EngineErrorCode = (typeof EngineErrorCode)[keyof typeof EngineErrorCode];\n","/**\n * Closed-world string catalog of annotation subtypes the v3 wire format knows\n * about. The TypeScript discriminated union `AnnotationDTO` is keyed on this\n * literal type. PDFium's integer subtype code is mapped onto these strings\n * by the reader registry.\n *\n * `unsupported` is the forward-compat fallback for any PDF subtype that\n * the engine has not implemented a reader for yet. Unknown subtypes never\n * silently disappear from the wire — they round-trip as\n * `{ subtype: 'unsupported', rawSubtypeCode }`.\n */\nexport const ANNOTATION_SUBTYPES = [\n 'text',\n 'link',\n 'free-text',\n 'line',\n 'square',\n 'circle',\n 'polygon',\n 'polyline',\n 'highlight',\n 'underline',\n 'squiggly',\n 'strikeout',\n 'stamp',\n 'caret',\n 'ink',\n 'popup',\n 'file-attachment',\n 'redact',\n 'widget',\n 'unsupported',\n] as const;\n\nexport type AnnotationSubtype = (typeof ANNOTATION_SUBTYPES)[number];\n\n/**\n * PDFium subtype codes from `FPDFAnnot_GetSubtype`. Mirrors\n * `FPDF_ANNOTATION_SUBTYPE` in `public/fpdf_annot.h`. We keep this here\n * (rather than importing from @embedpdf/engine-runtime) so the engine-core\n * package has zero PDFium dependency.\n */\nexport const PdfAnnotationSubtypeCode = {\n UNKNOWN: 0,\n TEXT: 1,\n LINK: 2,\n FREETEXT: 3,\n LINE: 4,\n SQUARE: 5,\n CIRCLE: 6,\n POLYGON: 7,\n POLYLINE: 8,\n HIGHLIGHT: 9,\n UNDERLINE: 10,\n SQUIGGLY: 11,\n STRIKEOUT: 12,\n STAMP: 13,\n CARET: 14,\n INK: 15,\n POPUP: 16,\n FILEATTACHMENT: 17,\n SOUND: 18,\n MOVIE: 19,\n WIDGET: 20,\n SCREEN: 21,\n PRINTERMARK: 22,\n TRAPNET: 23,\n WATERMARK: 24,\n THREED: 25,\n RICHMEDIA: 26,\n XFAWIDGET: 27,\n REDACT: 28,\n} as const;\n\nexport type PdfAnnotationSubtypeCode =\n (typeof PdfAnnotationSubtypeCode)[keyof typeof PdfAnnotationSubtypeCode];\n\n/**\n * Map from PDFium codes to wire-stable string subtypes. Codes the engine\n * recognises as a v3 subtype (or maps to 'unsupported' if not yet wired).\n */\nexport const PDF_CODE_TO_SUBTYPE: Readonly<Record<number, AnnotationSubtype>> = Object.freeze({\n [PdfAnnotationSubtypeCode.TEXT]: 'text',\n [PdfAnnotationSubtypeCode.LINK]: 'link',\n [PdfAnnotationSubtypeCode.FREETEXT]: 'free-text',\n [PdfAnnotationSubtypeCode.LINE]: 'line',\n [PdfAnnotationSubtypeCode.SQUARE]: 'square',\n [PdfAnnotationSubtypeCode.CIRCLE]: 'circle',\n [PdfAnnotationSubtypeCode.POLYGON]: 'polygon',\n [PdfAnnotationSubtypeCode.POLYLINE]: 'polyline',\n [PdfAnnotationSubtypeCode.HIGHLIGHT]: 'highlight',\n [PdfAnnotationSubtypeCode.UNDERLINE]: 'underline',\n [PdfAnnotationSubtypeCode.SQUIGGLY]: 'squiggly',\n [PdfAnnotationSubtypeCode.STRIKEOUT]: 'strikeout',\n [PdfAnnotationSubtypeCode.STAMP]: 'stamp',\n [PdfAnnotationSubtypeCode.CARET]: 'caret',\n [PdfAnnotationSubtypeCode.INK]: 'ink',\n [PdfAnnotationSubtypeCode.POPUP]: 'popup',\n [PdfAnnotationSubtypeCode.FILEATTACHMENT]: 'file-attachment',\n [PdfAnnotationSubtypeCode.WIDGET]: 'widget',\n [PdfAnnotationSubtypeCode.REDACT]: 'redact',\n});\n\n/**\n * Reverse map for write paths that need to turn a wire subtype back into the\n * PDFium integer code without importing the zod-backed annotation registry.\n */\nexport const PDF_SUBTYPE_TO_CODE: Readonly<Record<AnnotationSubtype, PdfAnnotationSubtypeCode>> =\n Object.freeze({\n text: PdfAnnotationSubtypeCode.TEXT,\n link: PdfAnnotationSubtypeCode.LINK,\n 'free-text': PdfAnnotationSubtypeCode.FREETEXT,\n line: PdfAnnotationSubtypeCode.LINE,\n square: PdfAnnotationSubtypeCode.SQUARE,\n circle: PdfAnnotationSubtypeCode.CIRCLE,\n polygon: PdfAnnotationSubtypeCode.POLYGON,\n polyline: PdfAnnotationSubtypeCode.POLYLINE,\n highlight: PdfAnnotationSubtypeCode.HIGHLIGHT,\n underline: PdfAnnotationSubtypeCode.UNDERLINE,\n squiggly: PdfAnnotationSubtypeCode.SQUIGGLY,\n strikeout: PdfAnnotationSubtypeCode.STRIKEOUT,\n stamp: PdfAnnotationSubtypeCode.STAMP,\n caret: PdfAnnotationSubtypeCode.CARET,\n ink: PdfAnnotationSubtypeCode.INK,\n popup: PdfAnnotationSubtypeCode.POPUP,\n 'file-attachment': PdfAnnotationSubtypeCode.FILEATTACHMENT,\n redact: PdfAnnotationSubtypeCode.REDACT,\n widget: PdfAnnotationSubtypeCode.WIDGET,\n unsupported: PdfAnnotationSubtypeCode.UNKNOWN,\n });\n\nexport function subtypeFromCode(code: number): AnnotationSubtype {\n return PDF_CODE_TO_SUBTYPE[code] ?? 'unsupported';\n}\n","import type { PageTextSnapshot } from '../dto/PageTextSnapshot';\n\n/**\n * Character↔text index translation — the ONE place the two text index\n * spaces of a page meet.\n *\n * A page has two index spaces:\n *\n * - CHARACTER space: PDFium's internal character list, the space geometry\n * runs tile (`PageGeometryRun.charStart`), hit-testing addresses, and\n * selection ranges live in. Size: `PageTextSnapshot.charCount`.\n * - TEXT space: UTF-16 code-unit offsets into the extracted string\n * `PageTextSnapshot.text` — what search matching and slicing operate on.\n *\n * They diverge in exactly two ways, both encoded by `charMap` anchors:\n * - a non-printing character occupies a character slot but contributes\n * ZERO text units (PDFium's `char_indices_` skip list);\n * - a supplementary-plane character contributes TWO text units (a\n * surrogate pair) once extraction is UTF-16-faithful.\n *\n * `charMap` semantics (see {@link CharMapAnchor}): an implicit head anchor\n * `[0, 0]`; between anchors every character advances the text by exactly one\n * unit; an anchor sits at `i + 1` whenever character `i` contributed\n * something other than one unit. Absent/empty map = identity\n * (`charCount === text.length`). `charMapViolation` is the validator both\n * the wire schema and engine builders share — malformed maps are rejected,\n * never silently repaired.\n *\n * Boundary model: a \"character boundary\" `c` ∈ [0, charCount] sits BEFORE\n * character `c`; `boundaryTextOffset(s, charCount) === text.length` always.\n * All ranges are half-open in both spaces.\n */\n\n/**\n * One anchor of the character→text mapping: from character index `char`\n * onward (until the next anchor), boundary `c` maps to text offset\n * `text + (c - char)`.\n */\nexport type CharMapAnchor = readonly [char: number, text: number];\n\n/** Direction to resolve a text offset that falls on a zero-width plateau —\n * see {@link charBoundaryAtTextOffset}. */\nexport type CharBoundaryBias = 'start' | 'end';\n\nconst clampInt = (value: number, lo: number, hi: number): number =>\n Math.min(Math.max(Math.floor(value), lo), hi);\n\n/** The greatest anchor with `anchor.char <= boundary` (implicit head [0,0]). */\nfunction anchorAtOrBefore(map: ReadonlyArray<CharMapAnchor>, boundary: number): CharMapAnchor {\n let lo = 0;\n let hi = map.length - 1;\n let best: CharMapAnchor | null = null;\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n if (map[mid][0] <= boundary) {\n best = map[mid];\n lo = mid + 1;\n } else {\n hi = mid - 1;\n }\n }\n return best ?? [0, 0];\n}\n\n/**\n * Text offset of character boundary `boundary` (clamped into\n * [0, charCount]). For a dropped character this is the offset of the next\n * real text unit — exactly what half-open slicing needs at either end.\n */\nexport function boundaryTextOffset(snapshot: PageTextSnapshot, boundary: number): number {\n const b = clampInt(boundary, 0, snapshot.charCount);\n const map = snapshot.charMap;\n if (!map || map.length === 0) return Math.min(b, snapshot.text.length);\n const [char, text] = anchorAtOrBefore(map, b);\n return text + (b - char);\n}\n\n/**\n * The character boundary for a text offset, with explicit plateau bias:\n *\n * - `'start'`: the GREATEST boundary whose text offset is <= `offset` —\n * scans forward past zero-width characters, so a range start never\n * includes a dropped character that precedes its first real unit.\n * - `'end'`: the SMALLEST boundary whose text offset is >= `offset` —\n * stops before zero-width characters, so a range end never swallows a\n * dropped character that follows its last real unit.\n *\n * An offset inside a surrogate pair resolves outward under both biases\n * (start → the pair's character, end → past it), so a clipped astral\n * character is always covered whole. Prefer {@link charRangeForTextOffsets}\n * — the two biases exist to be used as a PAIR.\n */\nexport function charBoundaryAtTextOffset(\n snapshot: PageTextSnapshot,\n offset: number,\n bias: CharBoundaryBias,\n): number {\n const target = clampInt(offset, 0, snapshot.text.length);\n let lo = 0;\n let hi = snapshot.charCount;\n if (bias === 'start') {\n // Greatest boundary with B(boundary) <= target. B(0) = 0 <= target always.\n while (lo < hi) {\n const mid = lo + Math.ceil((hi - lo) / 2);\n if (boundaryTextOffset(snapshot, mid) <= target) lo = mid;\n else hi = mid - 1;\n }\n return lo;\n }\n // Smallest boundary with B(boundary) >= target. B(charCount) = text.length\n // >= target always (offset is clamped).\n while (lo < hi) {\n const mid = (lo + hi) >> 1;\n if (boundaryTextOffset(snapshot, mid) >= target) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n}\n\n/**\n * The character range whose text projection is exactly\n * `text.slice(startOffset, endOffset)` — THE inverse used by search-hit\n * conversion and select-by-text. Start is right-biased and end left-biased\n * (see {@link charBoundaryAtTextOffset}), so zero-width characters adjacent\n * to the range fall OUTSIDE it on both sides.\n *\n * A non-empty text range can never invert: `end > start` implies\n * `B(end) >= endOffset > startOffset >= B(start)`, which forces\n * `end > start` by monotonicity. Empty input (`endOffset <= startOffset`)\n * normalizes to the end-rule boundary of `startOffset` on both sides.\n */\nexport function charRangeForTextOffsets(\n snapshot: PageTextSnapshot,\n startOffset: number,\n endOffset: number,\n): { start: number; end: number } {\n if (endOffset <= startOffset) {\n const b = charBoundaryAtTextOffset(snapshot, startOffset, 'end');\n return { start: b, end: b };\n }\n return {\n start: charBoundaryAtTextOffset(snapshot, startOffset, 'start'),\n end: charBoundaryAtTextOffset(snapshot, endOffset, 'end'),\n };\n}\n\n/**\n * THE copy primitive: the text projection of the half-open character range\n * `[charStart, charEnd)`. Dropped characters inside the range contribute\n * nothing; a supplementary character contributes its full surrogate pair.\n * `sliceTextByChars(s, 0, s.charCount) === s.text` always.\n */\nexport function sliceTextByChars(\n snapshot: PageTextSnapshot,\n charStart: number,\n charEnd: number,\n): string {\n if (charEnd <= charStart) return '';\n return snapshot.text.slice(\n boundaryTextOffset(snapshot, charStart),\n boundaryTextOffset(snapshot, charEnd),\n );\n}\n\n/**\n * First invariant violation of a snapshot's char map, or null when valid.\n * Shared by the wire schema (rejects malformed bodies) and engine builders\n * (dev-mode assertion). The invariants:\n *\n * 1. absent/empty map ⇒ identity, so `charCount === text.length`;\n * 2. anchor chars strictly increasing, each in [1, charCount];\n * 3. step rule: against the previous anchor (implicit head [0, 0]), the\n * character just before each anchor contributed exactly 0 units\n * (dropped) or 2 (surrogate pair):\n * `t₂ - (t₁ + (c₂ - c₁ - 1)) ∈ {0, 2}`;\n * 4. tail: `lastText + (charCount - lastChar) === text.length`\n * (equivalently `boundaryTextOffset(s, charCount) === text.length`).\n */\nexport function charMapViolation(\n charCount: number,\n textLength: number,\n charMap: ReadonlyArray<CharMapAnchor> | undefined,\n): string | null {\n if (!charMap || charMap.length === 0) {\n return charCount === textLength\n ? null\n : `identity map requires charCount (${charCount}) === text length (${textLength})`;\n }\n let prevChar = 0;\n let prevText = 0;\n for (let i = 0; i < charMap.length; i++) {\n const [char, text] = charMap[i];\n if (!Number.isInteger(char) || !Number.isInteger(text)) {\n return `anchor ${i} is not integer-valued`;\n }\n if (char <= prevChar) {\n return `anchor ${i} char ${char} not strictly after ${prevChar}`;\n }\n if (char > charCount) {\n return `anchor ${i} char ${char} outside [1, ${charCount}]`;\n }\n const step = text - (prevText + (char - prevChar - 1));\n if (step !== 0 && step !== 2) {\n return `anchor ${i} implies a character contributing ${step} text units (expected 0 or 2)`;\n }\n prevChar = char;\n prevText = text;\n }\n const tail = prevText + (charCount - prevChar);\n if (tail !== textLength) {\n return `map projects charCount to ${tail}, but text length is ${textLength}`;\n }\n return null;\n}\n","import type { PdfSize } from '../geometry/primitives';\n\n/**\n * Upper bound on `count` for a single `pages.insertBlank()` call. A CONTRACT\n * cap, enforced identically by every engine (the cloud input schema carries\n * the same number), so a UI never discovers a lower server limit by surprise.\n * Larger batches are a loop at the call site.\n */\nexport const PAGE_INSERT_BLANK_MAX_COUNT = 100;\n\n/**\n * Spec for `pages.insertBlank()`: create `count` blank pages of `size`.\n *\n * `size` is explicit and in PDF points, un-rotated — the same convention as\n * `PageLayout.size`. The \"match my neighbour\" default developers expect is a\n * registry read, so it lives in the page-edit capability, not here: the\n * engine wire never guesses (the `rotateBy` law).\n */\nexport interface PageInsertBlankSpec {\n /** Page size in PDF points. Both dimensions must be finite and > 0. */\n size: PdfSize;\n /** Pages to create, in `[1, PAGE_INSERT_BLANK_MAX_COUNT]`. Default 1. */\n count?: number;\n}\n"],"mappings":"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"}
|