@embedpdf/engine-services 3.0.0-next.7 → 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.cjs CHANGED
@@ -1727,6 +1727,42 @@ var PagesInserter = class {
1727
1727
  cache: null
1728
1728
  };
1729
1729
  }
1730
+ /**
1731
+ * Create `count` blank pages of `size` at `destIndex`. Same mutation
1732
+ * contract as `insert`, but native creation (`FPDFPage_New`) instead of a
1733
+ * deep copy: no source document, so none of the retain-until-close
1734
+ * lifetime hazard above. Each page gets an empty content stream
1735
+ * (`FPDFPage_GenerateContent`) so the saved PDF renders identically in
1736
+ * third-party viewers.
1737
+ */
1738
+ insertBlank(spec, destIndex, signal) {
1739
+ throwIfAborted(signal);
1740
+ const { size } = spec;
1741
+ const count = spec.count ?? 1;
1742
+ if (!Number.isFinite(size?.width) || !Number.isFinite(size?.height) || size.width <= 0 || size.height <= 0) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `pages.insertBlank size must have positive finite dimensions, got ${size?.width}x${size?.height}`);
1743
+ if (!Number.isInteger(count) || count < 1 || count > _embedpdf_engine_core_runtime.PAGE_INSERT_BLANK_MAX_COUNT) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `pages.insertBlank count ${count} out of range [1, ${_embedpdf_engine_core_runtime.PAGE_INSERT_BLANK_MAX_COUNT}]`);
1744
+ const { fn } = this.runtime;
1745
+ const destPtr = this.session.requireDocPtr();
1746
+ const beforeCount = fn.FPDF_GetPageCount(destPtr);
1747
+ const at = destIndex ?? beforeCount;
1748
+ if (!Number.isInteger(at) || at < 0 || at > beforeCount) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.InvalidArg, `pages.insertBlank destIndex ${at} out of range [0, ${beforeCount}]`);
1749
+ for (let i = 0; i < count; i++) {
1750
+ const pagePtr = fn.FPDFPage_New(destPtr, at + i, size.width, size.height);
1751
+ if (!pagePtr) {
1752
+ for (let j = 0; j < i; j++) fn.FPDFPage_Delete(destPtr, at);
1753
+ throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Unknown, `FPDFPage_New rejected page ${i + 1}/${count} at index ${at + i}`);
1754
+ }
1755
+ fn.FPDFPage_GenerateContent(pagePtr);
1756
+ fn.FPDF_ClosePage(pagePtr);
1757
+ }
1758
+ this.session.refreshPageRegistry();
1759
+ const layout = new PagesReader(this.runtime, this.session).read(signal);
1760
+ return {
1761
+ insertedPageObjectNumbers: layout.pages.slice(at, at + count).map((page) => page.pageObjectNumber),
1762
+ layout,
1763
+ cache: null
1764
+ };
1765
+ }
1730
1766
  };
1731
1767
  //#endregion
1732
1768
  //#region src/features/annotations/internal/read/annotationReadContext.ts
@@ -9251,9 +9287,10 @@ function validatePatchValue(key, value) {
9251
9287
  * worker wire shape from @embedpdf/engine-core.
9252
9288
  */
9253
9289
  var WorkerHost = class {
9254
- constructor(runtime, post) {
9290
+ constructor(runtime, post, options = {}) {
9255
9291
  this.runtime = runtime;
9256
9292
  this.post = post;
9293
+ this.options = options;
9257
9294
  _defineProperty(this, "sessions", /* @__PURE__ */ new Map());
9258
9295
  _defineProperty(this, "baseDocuments", void 0);
9259
9296
  _defineProperty(this, "aborts", /* @__PURE__ */ new Map());
@@ -9279,6 +9316,10 @@ var WorkerHost = class {
9279
9316
  this.aborts.get(msg.jobId)?.abort();
9280
9317
  return;
9281
9318
  }
9319
+ if (msg.kind === "pages.renderEncoded" || msg.kind === "document.renderPageFileEncoded" || msg.kind === "annotations.renderAppearancesEncoded") {
9320
+ this.receiveEncoded(msg);
9321
+ return;
9322
+ }
9282
9323
  const ctrl = new AbortController();
9283
9324
  this.aborts.set(msg.jobId, ctrl);
9284
9325
  let resultPack;
@@ -9382,6 +9423,9 @@ var WorkerHost = class {
9382
9423
  case "pages.insert":
9383
9424
  resultPack = this.handlePagesInsert(msg, ctrl.signal);
9384
9425
  break;
9426
+ case "pages.insertBlank":
9427
+ resultPack = this.handlePagesInsertBlank(msg, ctrl.signal);
9428
+ break;
9385
9429
  case "attachments.list":
9386
9430
  resultPack = this.handleAttachmentsList(msg, ctrl.signal);
9387
9431
  break;
@@ -9674,6 +9718,17 @@ var WorkerHost = class {
9674
9718
  result
9675
9719
  }, req.artifactPath);
9676
9720
  }
9721
+ handlePagesInsertBlank(req, signal) {
9722
+ const session = this.requireSession(req);
9723
+ const result = new PagesInserter(this.runtime, session).insertBlank({
9724
+ size: req.size,
9725
+ count: req.count
9726
+ }, req.destIndex, signal);
9727
+ return this.finishMutation(session, {
9728
+ tag: "pages.insertBlank",
9729
+ result
9730
+ }, req.artifactPath);
9731
+ }
9677
9732
  handleAttachmentsList(req, signal) {
9678
9733
  const session = this.requireSession(req);
9679
9734
  return (0, _embedpdf_engine_core_runtime.wirePack)({
@@ -9766,6 +9821,105 @@ var WorkerHost = class {
9766
9821
  raster
9767
9822
  }, [raster.data]);
9768
9823
  }
9824
+ async receiveEncoded(msg) {
9825
+ if (!this.options.imageEncoder) {
9826
+ this.post((0, _embedpdf_engine_core_runtime.wirePack)({
9827
+ kind: "reject",
9828
+ jobId: msg.jobId,
9829
+ error: (0, _embedpdf_engine_core_runtime.serializeError)(new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "this engine has no image encoder (the *.renderEncoded kinds are cloud-server surface)"))
9830
+ }, _embedpdf_engine_core_runtime.EMPTY_TRANSFER));
9831
+ return;
9832
+ }
9833
+ const ctrl = new AbortController();
9834
+ this.aborts.set(msg.jobId, ctrl);
9835
+ try {
9836
+ let resultPack;
9837
+ switch (msg.kind) {
9838
+ case "pages.renderEncoded":
9839
+ resultPack = await this.handlePagesRenderEncoded(msg, ctrl.signal);
9840
+ break;
9841
+ case "document.renderPageFileEncoded":
9842
+ resultPack = await this.handleDocumentRenderPageFileEncoded(msg, ctrl.signal);
9843
+ break;
9844
+ case "annotations.renderAppearancesEncoded":
9845
+ resultPack = await this.handleAnnotationsRenderAppearancesEncoded(msg, ctrl.signal);
9846
+ break;
9847
+ }
9848
+ this.post((0, _embedpdf_engine_core_runtime.wirePack)({
9849
+ kind: "resolve",
9850
+ jobId: msg.jobId,
9851
+ result: resultPack.payload
9852
+ }, resultPack.transfer));
9853
+ } catch (err) {
9854
+ this.post((0, _embedpdf_engine_core_runtime.wirePack)({
9855
+ kind: "reject",
9856
+ jobId: msg.jobId,
9857
+ error: (0, _embedpdf_engine_core_runtime.serializeError)(err)
9858
+ }, _embedpdf_engine_core_runtime.EMPTY_TRANSFER));
9859
+ } finally {
9860
+ this.aborts.delete(msg.jobId);
9861
+ }
9862
+ }
9863
+ async encodeRaster(raster, encode, signal) {
9864
+ const encoder = this.options.imageEncoder;
9865
+ if (!encoder) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.NotImplemented, "this engine has no image encoder (the *.renderEncoded kinds are cloud-server surface)");
9866
+ const { bytes, contentType } = await encoder.encode(raster, encode);
9867
+ if (signal.aborted) throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.Aborted, "aborted during image encode");
9868
+ return {
9869
+ contentType,
9870
+ width: raster.width,
9871
+ height: raster.height,
9872
+ bytes
9873
+ };
9874
+ }
9875
+ async handlePagesRenderEncoded(req, signal) {
9876
+ const inner = this.handlePagesRender({
9877
+ ...req,
9878
+ kind: "pages.render"
9879
+ }, signal);
9880
+ if (inner.payload.tag !== "pages.render") throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.WireFormat, `unexpected ${inner.payload.tag}`);
9881
+ const image = await this.encodeRaster(inner.payload.raster, req.encode, signal);
9882
+ return (0, _embedpdf_engine_core_runtime.wirePack)({
9883
+ tag: "pages.renderEncoded",
9884
+ image
9885
+ }, [image.bytes.buffer]);
9886
+ }
9887
+ async handleDocumentRenderPageFileEncoded(req, signal) {
9888
+ const inner = this.handleDocumentRenderPageFile({
9889
+ ...req,
9890
+ kind: "document.renderPageFile"
9891
+ }, signal);
9892
+ if (inner.payload.tag !== "document.renderPageFile") throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.WireFormat, `unexpected ${inner.payload.tag}`);
9893
+ const image = await this.encodeRaster(inner.payload.raster, req.encode, signal);
9894
+ return (0, _embedpdf_engine_core_runtime.wirePack)({
9895
+ tag: "document.renderPageFileEncoded",
9896
+ pageObjectNumber: inner.payload.pageObjectNumber,
9897
+ pageCount: inner.payload.pageCount,
9898
+ image
9899
+ }, [image.bytes.buffer]);
9900
+ }
9901
+ async handleAnnotationsRenderAppearancesEncoded(req, signal) {
9902
+ const inner = this.handleAnnotationsRenderAppearances({
9903
+ ...req,
9904
+ kind: "annotations.renderAppearances"
9905
+ }, signal);
9906
+ if (inner.payload.tag !== "annotations.renderAppearances") throw new _embedpdf_engine_core_runtime.EngineError(_embedpdf_engine_core_runtime.EngineErrorCode.WireFormat, `unexpected ${inner.payload.tag}`);
9907
+ const { pageState, appearances } = inner.payload.result;
9908
+ const encoded = [];
9909
+ for (const a of appearances) encoded.push({
9910
+ ref: a.ref,
9911
+ mode: a.mode,
9912
+ rect: a.rect,
9913
+ image: await this.encodeRaster(a.raster, req.encode, signal)
9914
+ });
9915
+ return (0, _embedpdf_engine_core_runtime.wirePack)({
9916
+ tag: "annotations.renderAppearancesEncoded",
9917
+ result: {
9918
+ pageState,
9919
+ appearances: encoded
9920
+ }
9921
+ }, encoded.map((e) => e.image.bytes.buffer));
9922
+ }
9769
9923
  handleDocumentSaveBuffer(req) {
9770
9924
  const session = this.requireSession(req);
9771
9925
  const saved = new DocumentSaver(this.runtime, session).saveStandaloneToBuffer(req.mode);