@cloudpdf/engine 3.0.0-next.8 → 3.0.0-next.9

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/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { AbortError, AbortablePromise, AbortablePromise as AbortablePromise$1, AnnotationAppearanceImageOptions, AnnotationAppearanceImagesResult, AnnotationAppearanceRenderOptions, AnnotationAppearancesResult, AnnotationCreateResult, AnnotationDeleteResult, AnnotationDraft, AnnotationListPageSnapshot, AnnotationListSnapshotAllPages, AnnotationMoveResult, AnnotationPatch, AnnotationRef, AnnotationUpdateResult, AttachmentContent, AttachmentsCache, DocumentAccessInfo, DocumentActionsService, DocumentAnnotationsService, DocumentAnnotationsService as DocumentAnnotationsService$1, DocumentAttachmentsService, DocumentCapabilities, DocumentEventStream, DocumentFormsService, DocumentHandle, DocumentHandle as DocumentHandle$1, DocumentIdentity, DocumentMetadata, DocumentPagesService, DocumentPagesService as DocumentPagesService$1, DocumentRedactionService, DocumentRenderService, DocumentSearchService, DocumentSecurityService, DocumentSecurityService as DocumentSecurityService$1, DocumentSecurityState, DocumentUnlockInput, DocumentUnlockResult, Engine, Engine as Engine$1, EngineError, EngineError as EngineError$1, EngineErrorCode, EngineFactory, MetadataCache, MetadataPatch, MetadataService, MetadataService as MetadataService$1, MetadataUpdateResult, MutationMeta, OpenInput, OpenInput as OpenInput$1, OpenInputShare, OpenOptions, OpenOptions as OpenOptions$1, PageAnnotationsService, PageAnnotationsService as PageAnnotationsService$1, PageDeleteResult, PageFlattenResult, PageFlattenUsage, PageGeometryService, PageGeometryService as PageGeometryService$1, PageGeometrySnapshot, PageHandle, PageHandle as PageHandle$1, PageImageHandle, PageImageOptions, PageListSnapshot, PageMoveResult, PageObjectNumber, PageRaster, PageRenderOptions, PageRenderService, PageRenderService as PageRenderService$1, PageRotateResult, PageRotation, PageStructureCache, PageTextService, PageTextService as PageTextService$1, PageTextSnapshot, PdfSaveMode, PdfSaveMode as PdfSaveMode$1, SearchRequest, SearchSlice, TokenSource, WeakAnnotationEditSession } from "@embedpdf/engine-core/runtime";
1
+ import { AbortError, AbortablePromise, AbortablePromise as AbortablePromise$1, AnnotationAppearanceImageOptions, AnnotationAppearanceImagesResult, AnnotationAppearanceRenderOptions, AnnotationAppearancesResult, AnnotationCreateResult, AnnotationDeleteResult, AnnotationDraft, AnnotationListPageSnapshot, AnnotationListSnapshotAllPages, AnnotationMoveResult, AnnotationPatch, AnnotationRef, AnnotationUpdateResult, AttachmentContent, AttachmentsCache, DocumentAccessInfo, DocumentActionsService, DocumentAnnotationsService, DocumentAnnotationsService as DocumentAnnotationsService$1, DocumentAttachmentsService, DocumentCapabilities, DocumentEventStream, DocumentFormsService, DocumentHandle, DocumentHandle as DocumentHandle$1, DocumentIdentity, DocumentMetadata, DocumentPagesService, DocumentPagesService as DocumentPagesService$1, DocumentRedactionService, DocumentRenderService, DocumentSearchService, DocumentSecurityService, DocumentSecurityService as DocumentSecurityService$1, DocumentSecurityState, DocumentUnlockInput, DocumentUnlockResult, Engine, Engine as Engine$1, EngineError, EngineError as EngineError$1, EngineErrorCode, EngineFactory, MetadataCache, MetadataPatch, MetadataService, MetadataService as MetadataService$1, MetadataUpdateResult, MutationMeta, OpenInput, OpenInput as OpenInput$1, OpenInputShare, OpenOptions, OpenOptions as OpenOptions$1, PageAnnotationsService, PageAnnotationsService as PageAnnotationsService$1, PageDeleteResult, PageFlattenResult, PageFlattenUsage, PageGeometryService, PageGeometryService as PageGeometryService$1, PageGeometrySnapshot, PageHandle, PageHandle as PageHandle$1, PageImageHandle, PageImageOptions, PageInsertBlankSpec, PageInsertResult, PageListSnapshot, PageMoveResult, PageObjectNumber, PageRaster, PageRenderOptions, PageRenderService, PageRenderService as PageRenderService$1, PageRotateResult, PageRotation, PageStructureCache, PageTextService, PageTextService as PageTextService$1, PageTextSnapshot, PdfSaveMode, PdfSaveMode as PdfSaveMode$1, SearchRequest, SearchSlice, TokenSource, WeakAnnotationEditSession } from "@embedpdf/engine-core/runtime";
2
2
  import { CdnAccessInfoForApply, DocumentHead, DocumentManifest, LayerScopePlane } from "@embedpdf/engine-core/wire";
3
3
  import { SessionEventPublisher } from "@embedpdf/engine-services";
4
4
  //#region src/transport/HttpClient.d.ts
@@ -22,12 +22,19 @@ interface HttpClientOptions {
22
22
  /** Replace the global fetch (e.g. in Node tests with undici). */
23
23
  fetch?: typeof globalThis.fetch;
24
24
  /**
25
- * Document affinity (opt-in; requires a server whose CORS
26
- * allowlist includes the header): send `X-CloudPDF-Doc` on
27
- * origin-bound doc requests so consistent-hash load balancers pin a
28
- * document's traffic to one warm replica. Derived from the request
29
- * path (`/v1/docs/:docId/…` — the same extraction the Helm chart's
30
- * uri-mode fallback uses); never sent on CDN-rewritten requests.
25
+ * Document affinity key: `X-CloudPDF-Doc` is sent BY DEFAULT on
26
+ * origin-bound doc requests so consistent-hash load balancers can pin
27
+ * a document's traffic to one warm replica. Routing hints are
28
+ * unconditional client behavior — whether they are USED is the
29
+ * operator's choice at the load balancer, never the app's. Derived
30
+ * from the request path (`/v1/docs/:docId/…` — the same extraction
31
+ * the Helm chart's uri-mode fallback uses); never sent on
32
+ * CDN-rewritten requests.
33
+ *
34
+ * `false` is an ESCAPE HATCH, not a feature toggle: use it only
35
+ * against a stale server whose CORS allowlist predates the header
36
+ * (browser preflights would fail) or behind a proxy that rejects
37
+ * unknown request headers.
31
38
  */
32
39
  docAffinityHeader?: boolean;
33
40
  /** Observability: fired once per transport-level retry (engine busy /
@@ -172,6 +179,8 @@ declare class HttpClient {
172
179
  /** PATCH counterpart of {@link postMultipartJson} (binary-carrying mutations). */
173
180
  patchMultipartJson<T>(path: string, body: FormData, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
174
181
  postJson<T>(path: string, body: unknown, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
182
+ /** POST a JSON body and return the raw binary response (pages.extract). */
183
+ postJsonBytes(path: string, body: unknown, signal: AbortSignal): Promise<Uint8Array>;
175
184
  /** POST a raw binary body (FDF/XFDF import) and parse the JSON response. */
176
185
  postBytesJson<T>(path: string, bytes: Uint8Array, contentType: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
177
186
  patchJson<T>(path: string, body: unknown, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
@@ -287,6 +296,10 @@ interface ManifestAccessor {
287
296
  /** Same advance for a page delete, additionally dropping the deleted
288
297
  * pages' manifest rows so per-page leaf URLs stop resolving locally. */
289
298
  applyPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void;
299
+ /** Page insert: the cached manifest has no rows for the fresh PONs (the
300
+ * result carries only their object numbers), so the absorb drops the
301
+ * cache for a lazy refetch instead of patching. */
302
+ applyPageInsert(cache: PageStructureCache): void;
290
303
  /** Advance the cached manifest's docVersion + metadataVersion after a metadata write. */
291
304
  applyMetadata(cache: MetadataCache): void;
292
305
  /** Advance the cached manifest's docVersion + attachmentsVersion after an
@@ -388,6 +401,18 @@ declare class CloudDocumentHandle implements DocumentHandle$1 {
388
401
  * 404 anyway — this keeps the failure local and instant).
389
402
  */
390
403
  private absorbPageDelete;
404
+ /**
405
+ * Patch bookkeeping after a page insert — the mirror of
406
+ * {@link absorbPageDelete}, with one asymmetry: delete can patch the
407
+ * cached manifest losslessly (it only REMOVES rows), but an insert needs
408
+ * manifest rows for the fresh PONs and the result doesn't carry them. So
409
+ * this absorb flips the planes (insert changes the page SET, so like
410
+ * delete it owns content + annotations alongside layout), raises the
411
+ * version floor, and DROPS the cache — the next read refetches a manifest
412
+ * that includes the new pages' rows. The UI never waits on that refetch:
413
+ * the mutation result / event already carries the full new layout.
414
+ */
415
+ private absorbPageInsert;
391
416
  /**
392
417
  * Patch the cached manifest after a metadata write. Symmetric with
393
418
  * {@link absorbPageMove}: a metadata edit advances `docVersion` (so leaf
@@ -471,6 +496,9 @@ declare class CloudDocumentPagesService implements DocumentPagesService$1 {
471
496
  move(pageObjectNumbers: PageObjectNumber[], destIndex: number): AbortablePromise$1<PageMoveResult>;
472
497
  rotate(pageObjectNumbers: PageObjectNumber[], rotation: PageRotation): AbortablePromise$1<PageRotateResult>;
473
498
  delete(pageObjectNumbers: PageObjectNumber[]): AbortablePromise$1<PageDeleteResult>;
499
+ insert(bytes: Uint8Array | ArrayBuffer, destIndex?: number): AbortablePromise$1<PageInsertResult>;
500
+ insertBlank(spec: PageInsertBlankSpec, destIndex?: number): AbortablePromise$1<PageInsertResult>;
501
+ extract(pageObjectNumbers: PageObjectNumber[]): AbortablePromise$1<Uint8Array>;
474
502
  flatten(pageObjectNumbers: PageObjectNumber[], usage?: PageFlattenUsage): AbortablePromise$1<PageFlattenResult>;
475
503
  }
476
504
  //#endregion
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AbortError, AbortablePromise, AbortablePromise as AbortablePromise$1, AnnotationAppearanceImageOptions, AnnotationAppearanceImagesResult, AnnotationAppearanceRenderOptions, AnnotationAppearancesResult, AnnotationCreateResult, AnnotationDeleteResult, AnnotationDraft, AnnotationListPageSnapshot, AnnotationListSnapshotAllPages, AnnotationMoveResult, AnnotationPatch, AnnotationRef, AnnotationUpdateResult, AttachmentContent, AttachmentsCache, DocumentAccessInfo, DocumentActionsService, DocumentAnnotationsService, DocumentAnnotationsService as DocumentAnnotationsService$1, DocumentAttachmentsService, DocumentCapabilities, DocumentEventStream, DocumentFormsService, DocumentHandle, DocumentHandle as DocumentHandle$1, DocumentIdentity, DocumentMetadata, DocumentPagesService, DocumentPagesService as DocumentPagesService$1, DocumentRedactionService, DocumentRenderService, DocumentSearchService, DocumentSecurityService, DocumentSecurityService as DocumentSecurityService$1, DocumentSecurityState, DocumentUnlockInput, DocumentUnlockResult, Engine, Engine as Engine$1, EngineError, EngineError as EngineError$1, EngineErrorCode, EngineFactory, MetadataCache, MetadataPatch, MetadataService, MetadataService as MetadataService$1, MetadataUpdateResult, MutationMeta, OpenInput, OpenInput as OpenInput$1, OpenInputShare, OpenOptions, OpenOptions as OpenOptions$1, PageAnnotationsService, PageAnnotationsService as PageAnnotationsService$1, PageDeleteResult, PageFlattenResult, PageFlattenUsage, PageGeometryService, PageGeometryService as PageGeometryService$1, PageGeometrySnapshot, PageHandle, PageHandle as PageHandle$1, PageImageHandle, PageImageOptions, PageListSnapshot, PageMoveResult, PageObjectNumber, PageRaster, PageRenderOptions, PageRenderService, PageRenderService as PageRenderService$1, PageRotateResult, PageRotation, PageStructureCache, PageTextService, PageTextService as PageTextService$1, PageTextSnapshot, PdfSaveMode, PdfSaveMode as PdfSaveMode$1, SearchRequest, SearchSlice, TokenSource, WeakAnnotationEditSession } from "@embedpdf/engine-core/runtime";
1
+ import { AbortError, AbortablePromise, AbortablePromise as AbortablePromise$1, AnnotationAppearanceImageOptions, AnnotationAppearanceImagesResult, AnnotationAppearanceRenderOptions, AnnotationAppearancesResult, AnnotationCreateResult, AnnotationDeleteResult, AnnotationDraft, AnnotationListPageSnapshot, AnnotationListSnapshotAllPages, AnnotationMoveResult, AnnotationPatch, AnnotationRef, AnnotationUpdateResult, AttachmentContent, AttachmentsCache, DocumentAccessInfo, DocumentActionsService, DocumentAnnotationsService, DocumentAnnotationsService as DocumentAnnotationsService$1, DocumentAttachmentsService, DocumentCapabilities, DocumentEventStream, DocumentFormsService, DocumentHandle, DocumentHandle as DocumentHandle$1, DocumentIdentity, DocumentMetadata, DocumentPagesService, DocumentPagesService as DocumentPagesService$1, DocumentRedactionService, DocumentRenderService, DocumentSearchService, DocumentSecurityService, DocumentSecurityService as DocumentSecurityService$1, DocumentSecurityState, DocumentUnlockInput, DocumentUnlockResult, Engine, Engine as Engine$1, EngineError, EngineError as EngineError$1, EngineErrorCode, EngineFactory, MetadataCache, MetadataPatch, MetadataService, MetadataService as MetadataService$1, MetadataUpdateResult, MutationMeta, OpenInput, OpenInput as OpenInput$1, OpenInputShare, OpenOptions, OpenOptions as OpenOptions$1, PageAnnotationsService, PageAnnotationsService as PageAnnotationsService$1, PageDeleteResult, PageFlattenResult, PageFlattenUsage, PageGeometryService, PageGeometryService as PageGeometryService$1, PageGeometrySnapshot, PageHandle, PageHandle as PageHandle$1, PageImageHandle, PageImageOptions, PageInsertBlankSpec, PageInsertResult, PageListSnapshot, PageMoveResult, PageObjectNumber, PageRaster, PageRenderOptions, PageRenderService, PageRenderService as PageRenderService$1, PageRotateResult, PageRotation, PageStructureCache, PageTextService, PageTextService as PageTextService$1, PageTextSnapshot, PdfSaveMode, PdfSaveMode as PdfSaveMode$1, SearchRequest, SearchSlice, TokenSource, WeakAnnotationEditSession } from "@embedpdf/engine-core/runtime";
2
2
  import { CdnAccessInfoForApply, DocumentHead, DocumentManifest, LayerScopePlane } from "@embedpdf/engine-core/wire";
3
3
  import { SessionEventPublisher } from "@embedpdf/engine-services";
4
4
  //#region src/transport/HttpClient.d.ts
@@ -22,12 +22,19 @@ interface HttpClientOptions {
22
22
  /** Replace the global fetch (e.g. in Node tests with undici). */
23
23
  fetch?: typeof globalThis.fetch;
24
24
  /**
25
- * Document affinity (opt-in; requires a server whose CORS
26
- * allowlist includes the header): send `X-CloudPDF-Doc` on
27
- * origin-bound doc requests so consistent-hash load balancers pin a
28
- * document's traffic to one warm replica. Derived from the request
29
- * path (`/v1/docs/:docId/…` — the same extraction the Helm chart's
30
- * uri-mode fallback uses); never sent on CDN-rewritten requests.
25
+ * Document affinity key: `X-CloudPDF-Doc` is sent BY DEFAULT on
26
+ * origin-bound doc requests so consistent-hash load balancers can pin
27
+ * a document's traffic to one warm replica. Routing hints are
28
+ * unconditional client behavior — whether they are USED is the
29
+ * operator's choice at the load balancer, never the app's. Derived
30
+ * from the request path (`/v1/docs/:docId/…` — the same extraction
31
+ * the Helm chart's uri-mode fallback uses); never sent on
32
+ * CDN-rewritten requests.
33
+ *
34
+ * `false` is an ESCAPE HATCH, not a feature toggle: use it only
35
+ * against a stale server whose CORS allowlist predates the header
36
+ * (browser preflights would fail) or behind a proxy that rejects
37
+ * unknown request headers.
31
38
  */
32
39
  docAffinityHeader?: boolean;
33
40
  /** Observability: fired once per transport-level retry (engine busy /
@@ -172,6 +179,8 @@ declare class HttpClient {
172
179
  /** PATCH counterpart of {@link postMultipartJson} (binary-carrying mutations). */
173
180
  patchMultipartJson<T>(path: string, body: FormData, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
174
181
  postJson<T>(path: string, body: unknown, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
182
+ /** POST a JSON body and return the raw binary response (pages.extract). */
183
+ postJsonBytes(path: string, body: unknown, signal: AbortSignal): Promise<Uint8Array>;
175
184
  /** POST a raw binary body (FDF/XFDF import) and parse the JSON response. */
176
185
  postBytesJson<T>(path: string, bytes: Uint8Array, contentType: string, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
177
186
  patchJson<T>(path: string, body: unknown, parser: (raw: unknown) => T, signal: AbortSignal): Promise<T>;
@@ -287,6 +296,10 @@ interface ManifestAccessor {
287
296
  /** Same advance for a page delete, additionally dropping the deleted
288
297
  * pages' manifest rows so per-page leaf URLs stop resolving locally. */
289
298
  applyPageDelete(cache: PageStructureCache, deletedPages: PageObjectNumber[]): void;
299
+ /** Page insert: the cached manifest has no rows for the fresh PONs (the
300
+ * result carries only their object numbers), so the absorb drops the
301
+ * cache for a lazy refetch instead of patching. */
302
+ applyPageInsert(cache: PageStructureCache): void;
290
303
  /** Advance the cached manifest's docVersion + metadataVersion after a metadata write. */
291
304
  applyMetadata(cache: MetadataCache): void;
292
305
  /** Advance the cached manifest's docVersion + attachmentsVersion after an
@@ -388,6 +401,18 @@ declare class CloudDocumentHandle implements DocumentHandle$1 {
388
401
  * 404 anyway — this keeps the failure local and instant).
389
402
  */
390
403
  private absorbPageDelete;
404
+ /**
405
+ * Patch bookkeeping after a page insert — the mirror of
406
+ * {@link absorbPageDelete}, with one asymmetry: delete can patch the
407
+ * cached manifest losslessly (it only REMOVES rows), but an insert needs
408
+ * manifest rows for the fresh PONs and the result doesn't carry them. So
409
+ * this absorb flips the planes (insert changes the page SET, so like
410
+ * delete it owns content + annotations alongside layout), raises the
411
+ * version floor, and DROPS the cache — the next read refetches a manifest
412
+ * that includes the new pages' rows. The UI never waits on that refetch:
413
+ * the mutation result / event already carries the full new layout.
414
+ */
415
+ private absorbPageInsert;
391
416
  /**
392
417
  * Patch the cached manifest after a metadata write. Symmetric with
393
418
  * {@link absorbPageMove}: a metadata edit advances `docVersion` (so leaf
@@ -471,6 +496,9 @@ declare class CloudDocumentPagesService implements DocumentPagesService$1 {
471
496
  move(pageObjectNumbers: PageObjectNumber[], destIndex: number): AbortablePromise$1<PageMoveResult>;
472
497
  rotate(pageObjectNumbers: PageObjectNumber[], rotation: PageRotation): AbortablePromise$1<PageRotateResult>;
473
498
  delete(pageObjectNumbers: PageObjectNumber[]): AbortablePromise$1<PageDeleteResult>;
499
+ insert(bytes: Uint8Array | ArrayBuffer, destIndex?: number): AbortablePromise$1<PageInsertResult>;
500
+ insertBlank(spec: PageInsertBlankSpec, destIndex?: number): AbortablePromise$1<PageInsertResult>;
501
+ extract(pageObjectNumbers: PageObjectNumber[]): AbortablePromise$1<Uint8Array>;
474
502
  flatten(pageObjectNumbers: PageObjectNumber[], usage?: PageFlattenUsage): AbortablePromise$1<PageFlattenResult>;
475
503
  }
476
504
  //#endregion
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { AbortError, AbortError as AbortError$1, AbortablePromise, AbortablePromise as AbortablePromise$1, CONTINUOUS_RENDER_POLICY, DEFAULT_PDF_SAVE_MODE, EngineError, EngineError as EngineError$1, EngineErrorCode, EngineErrorCode as EngineErrorCode$1, canonicalSearchQuery, checkCapability, createPageImageHandle, decodePdfBits, encodeFieldRefKey, encodeStableIdKey, expandRawScope, normalizeAnnotationDraft, normalizeAnnotationPatch, normalizeAttachmentFileSource, passwordPromptFromState, searchContentEpoch, securityStateFromHead } from "@embedpdf/engine-core/runtime";
2
- import { AccessResponseSchema, AnnotationAppearanceManifestSchema, AnnotationCreateResultSchema, AnnotationDeleteResultSchema, AnnotationListPageSnapshotSchema, AnnotationMoveResultSchema, AnnotationUpdateResultSchema, AttachmentCreateResultSchema, AttachmentDeleteResultSchema, DEFAULT_LAYER_NAME, DocumentActionsSnapshotSchema, DocumentHeadSchema, DocumentManifestSchema, DocumentMetadataSchema, EmbeddedFileItemSchema, EngineErrorPayloadSchema, FormEffectsResultSchema, FormFieldCreateResultSchema, FormFieldDTOSchema, FormFieldDeleteResultSchema, FormFieldUpdateResultSchema, FormImportResultSchema, FormRepairResultSchema, FormSetValueResultSchema, FormSnapshotSchema, FormWidgetLinkResultSchema, MetadataUpdateResultSchema, PageDeleteResultSchema, PageFlattenResultSchema, PageGeometrySnapshotSchema, PageListSnapshotSchema, PageMoveResultSchema, PageRotateResultSchema, PageTextSnapshotSchema, RedactionApplyResultSchema, SearchSliceSchema, WeakAnnotationSessionResponseSchema, annotationAppearancesImageOptionsToWire, applyCdnAccess, decodeSearchToken, decodeTokenText, encodeSearchToken, renderImageOptionsToWire, wirePaths } from "@embedpdf/engine-core/wire";
2
+ import { AccessResponseSchema, AnnotationAppearanceManifestSchema, AnnotationCreateResultSchema, AnnotationDeleteResultSchema, AnnotationListPageSnapshotSchema, AnnotationMoveResultSchema, AnnotationUpdateResultSchema, AttachmentCreateResultSchema, AttachmentDeleteResultSchema, DEFAULT_LAYER_NAME, DocumentActionsSnapshotSchema, DocumentHeadSchema, DocumentManifestSchema, DocumentMetadataSchema, EmbeddedFileItemSchema, EngineErrorPayloadSchema, FormEffectsResultSchema, FormFieldCreateResultSchema, FormFieldDTOSchema, FormFieldDeleteResultSchema, FormFieldUpdateResultSchema, FormImportResultSchema, FormRepairResultSchema, FormSetValueResultSchema, FormSnapshotSchema, FormWidgetLinkResultSchema, MetadataUpdateResultSchema, PageDeleteResultSchema, PageFlattenResultSchema, PageGeometrySnapshotSchema, PageInsertResultSchema, PageListSnapshotSchema, PageMoveResultSchema, PageRotateResultSchema, PageTextSnapshotSchema, RedactionApplyResultSchema, SearchSliceSchema, WeakAnnotationSessionResponseSchema, annotationAppearancesImageOptionsToWire, applyCdnAccess, decodeSearchToken, decodeTokenText, encodeSearchToken, renderImageOptionsToWire, wirePaths } from "@embedpdf/engine-core/wire";
3
3
  import { EventHub, SessionEventPublisher, generateUuid } from "@embedpdf/engine-services";
4
4
  //#region src/document/planes.ts
5
5
  /**
@@ -449,6 +449,13 @@ var CloudDocumentFormsService = class {
449
449
  };
450
450
  //#endregion
451
451
  //#region src/document/CloudDocumentPagesService.ts
452
+ /** Detach a Uint8Array view into a standalone ArrayBuffer (the resource-map
453
+ * shape) without disturbing a larger buffer the caller still owns. */
454
+ function copyToExactBuffer(view) {
455
+ const copy = new ArrayBuffer(view.byteLength);
456
+ new Uint8Array(copy).set(view);
457
+ return copy;
458
+ }
452
459
  /**
453
460
  * Cloud-side document pages service. Mirrors `LocalDocumentPagesService`
454
461
  * over HTTP: GET /pages for `list`, POST /pages/move for the reorder.
@@ -541,6 +548,46 @@ var CloudDocumentPagesService = class {
541
548
  return result;
542
549
  });
543
550
  }
551
+ insert(bytes, destIndex) {
552
+ if (this.isClosed()) return AbortablePromise$1.rejectReason(new EngineError$1(EngineErrorCode$1.DocNotOpen, `document ${this.docId} is closed`));
553
+ return AbortablePromise$1.run(async (signal) => {
554
+ const buffer = bytes instanceof ArrayBuffer ? bytes : copyToExactBuffer(bytes);
555
+ const form = buildMutationForm(destIndex !== void 0 ? { destIndex } : {}, { source: {
556
+ bytes: buffer,
557
+ mimeType: "application/pdf",
558
+ name: "source.pdf"
559
+ } });
560
+ const result = await this.http.postMultipartJson(wirePaths.layerPagesInsert(this.docId, this.layerName), form, (raw) => PageInsertResultSchema.parse(raw), signal);
561
+ if (result.cache) this.manifest.applyPageInsert(result.cache);
562
+ this.publisher.publishLocal({
563
+ type: "pages.inserted",
564
+ destIndex,
565
+ ...result
566
+ });
567
+ return result;
568
+ });
569
+ }
570
+ insertBlank(spec, destIndex) {
571
+ if (this.isClosed()) return AbortablePromise$1.rejectReason(new EngineError$1(EngineErrorCode$1.DocNotOpen, `document ${this.docId} is closed`));
572
+ return AbortablePromise$1.run(async (signal) => {
573
+ const result = await this.http.postJson(wirePaths.layerPagesInsertBlank(this.docId, this.layerName), {
574
+ size: spec.size,
575
+ ...spec.count !== void 0 ? { count: spec.count } : {},
576
+ ...destIndex !== void 0 ? { destIndex } : {}
577
+ }, (raw) => PageInsertResultSchema.parse(raw), signal);
578
+ if (result.cache) this.manifest.applyPageInsert(result.cache);
579
+ this.publisher.publishLocal({
580
+ type: "pages.inserted",
581
+ destIndex,
582
+ ...result
583
+ });
584
+ return result;
585
+ });
586
+ }
587
+ extract(pageObjectNumbers) {
588
+ if (this.isClosed()) return AbortablePromise$1.rejectReason(new EngineError$1(EngineErrorCode$1.DocNotOpen, `document ${this.docId} is closed`));
589
+ return AbortablePromise$1.run(async (signal) => this.http.postJsonBytes(wirePaths.layerPagesExtract(this.docId, this.layerName), { pageObjectNumbers }, signal));
590
+ }
544
591
  flatten(pageObjectNumbers, usage = "display") {
545
592
  if (this.isClosed()) return AbortablePromise$1.rejectReason(new EngineError$1(EngineErrorCode$1.DocNotOpen, `document ${this.docId} is closed`));
546
593
  return AbortablePromise$1.run(async (signal) => {
@@ -809,8 +856,7 @@ var CloudDocumentSecurityService = class {
809
856
  * and `applyCdnAccess` short-circuits to origin; safe to call always.
810
857
  */
811
858
  async postAccess(signal, body) {
812
- const response = await this.http.postJson(wirePaths.access(this.docId), {
813
- layerName: this.layerName,
859
+ const response = await this.http.postJson(wirePaths.access(this.docId, this.layerName), {
814
860
  ...body.password ? { password: body.password } : {},
815
861
  mode: body.mode
816
862
  }, (raw) => AccessResponseSchema.parse(raw), signal);
@@ -1340,6 +1386,12 @@ function auditRowToEvent(row, mySessionId) {
1340
1386
  origin,
1341
1387
  ...row.payload
1342
1388
  };
1389
+ case "pages.insert":
1390
+ case "pages.insertBlank": return {
1391
+ type: "pages.inserted",
1392
+ origin,
1393
+ ...row.payload
1394
+ };
1343
1395
  case "pages.flatten": return {
1344
1396
  type: "pages.flattened",
1345
1397
  origin,
@@ -1582,6 +1634,7 @@ var CloudDocumentHandle = class {
1582
1634
  apply: (meta, owns) => this.absorbMutation(meta, owns),
1583
1635
  applyPageStructure: (cache) => this.absorbPageStructure(cache),
1584
1636
  applyPageDelete: (cache, deletedPages) => this.absorbPageDelete(cache, deletedPages),
1637
+ applyPageInsert: (cache) => this.absorbPageInsert(cache),
1585
1638
  applyMetadata: (cache) => this.absorbMetadata(cache),
1586
1639
  applyAttachments: (cache) => this.absorbAttachments(cache)
1587
1640
  };
@@ -1747,6 +1800,27 @@ var CloudDocumentHandle = class {
1747
1800
  };
1748
1801
  }
1749
1802
  /**
1803
+ * Patch bookkeeping after a page insert — the mirror of
1804
+ * {@link absorbPageDelete}, with one asymmetry: delete can patch the
1805
+ * cached manifest losslessly (it only REMOVES rows), but an insert needs
1806
+ * manifest rows for the fresh PONs and the result doesn't carry them. So
1807
+ * this absorb flips the planes (insert changes the page SET, so like
1808
+ * delete it owns content + annotations alongside layout), raises the
1809
+ * version floor, and DROPS the cache — the next read refetches a manifest
1810
+ * that includes the new pages' rows. The UI never waits on that refetch:
1811
+ * the mutation result / event already carries the full new layout.
1812
+ */
1813
+ absorbPageInsert(cache) {
1814
+ this.flipScopes([
1815
+ "layout",
1816
+ "content",
1817
+ "annotations"
1818
+ ]);
1819
+ this.manifestFloorVersion = Math.max(this.manifestFloorVersion, cache.docVersion);
1820
+ this.inflightManifest = null;
1821
+ this.manifestCache = null;
1822
+ }
1823
+ /**
1750
1824
  * Patch the cached manifest after a metadata write. Symmetric with
1751
1825
  * {@link absorbPageMove}: a metadata edit advances `docVersion` (so leaf
1752
1826
  * URLs re-resolve) and `metadataVersion` (so the /metadata leaf re-fetches),
@@ -1882,6 +1956,9 @@ var CloudDocumentHandle = class {
1882
1956
  case "pages.deleted":
1883
1957
  if (event.cache) this.absorbPageDelete(event.cache, event.pageObjectNumbers);
1884
1958
  return;
1959
+ case "pages.inserted":
1960
+ if (event.cache) this.absorbPageInsert(event.cache);
1961
+ return;
1885
1962
  case "metadata.updated":
1886
1963
  if (event.cache) this.absorbMetadata(event.cache);
1887
1964
  return;
@@ -1933,7 +2010,7 @@ function fallbackUnknownHead(id) {
1933
2010
  access: {
1934
2011
  required: true,
1935
2012
  reasons: ["permissions-unknown"],
1936
- endpoint: wirePaths.access(id)
2013
+ endpoint: wirePaths.access(id, DEFAULT_LAYER_NAME)
1937
2014
  }
1938
2015
  };
1939
2016
  }
@@ -2050,7 +2127,7 @@ var HttpClient = class HttpClient {
2050
2127
  this.tokenFn = token === void 0 ? null : typeof token === "function" ? token : () => token;
2051
2128
  this.sessionId = opts.sessionId ?? null;
2052
2129
  this.fetchFn = opts.fetch ?? globalThis.fetch.bind(globalThis);
2053
- this.docAffinityHeader = opts.docAffinityHeader ?? false;
2130
+ this.docAffinityHeader = opts.docAffinityHeader ?? true;
2054
2131
  this.onRetry = opts.onRetry;
2055
2132
  }
2056
2133
  /** Normalized server base URL (no trailing slash). */
@@ -2282,6 +2359,12 @@ var HttpClient = class HttpClient {
2282
2359
  const res = await this.requestJson(path, "POST", body, signal);
2283
2360
  return await this.parseJsonResponse(res, parser);
2284
2361
  }
2362
+ /** POST a JSON body and return the raw binary response (pages.extract). */
2363
+ async postJsonBytes(path, body, signal) {
2364
+ const res = await this.requestJson(path, "POST", body, signal);
2365
+ if (!res.ok) await this.throwFromBody(res);
2366
+ return new Uint8Array(await res.arrayBuffer());
2367
+ }
2285
2368
  /** POST a raw binary body (FDF/XFDF import) and parse the JSON response. */
2286
2369
  async postBytesJson(path, bytes, contentType, parser, signal) {
2287
2370
  const headers = new Headers({ "Content-Type": contentType });