@embedpdf/core 3.0.0-next.15 → 3.0.0-next.16
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 +225 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +225 -7
- package/dist/index.js.map +1 -1
- package/dist/{settings-maKtf237.cjs → settings-BS97q3tq.cjs} +15 -7
- package/dist/settings-BS97q3tq.cjs.map +1 -0
- package/dist/{settings-CMWFRjmQ.js → settings-CHdHuZ3k.js} +12 -4
- package/dist/settings-CHdHuZ3k.js.map +1 -0
- package/dist/testing.cjs +56 -3
- package/dist/testing.cjs.map +1 -1
- package/dist/testing.d.cts +33 -3
- package/dist/testing.d.ts +33 -3
- package/dist/testing.js +56 -4
- package/dist/testing.js.map +1 -1
- package/dist/{types-t-DaU8VK.d.ts → types-CfnZ7go6.d.cts} +146 -4
- package/dist/{types-t-DaU8VK.d.cts → types-CfnZ7go6.d.ts} +146 -4
- package/package.json +2 -2
- package/dist/settings-CMWFRjmQ.js.map +0 -1
- package/dist/settings-maKtf237.cjs.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_settings = require("./settings-
|
|
2
|
+
const require_settings = require("./settings-BS97q3tq.cjs");
|
|
3
3
|
let _embedpdf_engine_core_runtime = require("@embedpdf/engine-core/runtime");
|
|
4
4
|
//#region src/order.ts
|
|
5
5
|
/**
|
|
@@ -97,7 +97,8 @@ function layoutFromEvent(event) {
|
|
|
97
97
|
case "pages.reordered":
|
|
98
98
|
case "pages.rotated":
|
|
99
99
|
case "pages.deleted":
|
|
100
|
-
case "pages.inserted":
|
|
100
|
+
case "pages.inserted":
|
|
101
|
+
case "pages.restored": return event.layout;
|
|
101
102
|
default: return null;
|
|
102
103
|
}
|
|
103
104
|
}
|
|
@@ -147,6 +148,16 @@ async function fetchUrlSource(source, signal) {
|
|
|
147
148
|
}
|
|
148
149
|
const isUrlSource = (source) => source.kind === "url";
|
|
149
150
|
const noLayer = () => new require_settings.PluginError("unsupported", "documents", "only the local engine gives a layer to download");
|
|
151
|
+
/** How a print comes out at each tier, one object each, so readers can compare them with `Object.is`. */
|
|
152
|
+
const PRINT_STANDARD = Object.freeze({
|
|
153
|
+
kind: "images",
|
|
154
|
+
dpi: 150
|
|
155
|
+
});
|
|
156
|
+
const PRINT_HIGH = Object.freeze({
|
|
157
|
+
kind: "images",
|
|
158
|
+
dpi: 300
|
|
159
|
+
});
|
|
160
|
+
const PRINT_PDF = Object.freeze({ kind: "pdf" });
|
|
150
161
|
/**
|
|
151
162
|
* The documents capability as seen from inside one document's scope: every call whose document
|
|
152
163
|
* is optional uses that document instead of the active one. The rest is the registry itself.
|
|
@@ -157,6 +168,9 @@ const documentsInScope = (documents, documentId) => ({
|
|
|
157
168
|
download: (id = documentId, options) => documents.download(id, options),
|
|
158
169
|
downloadLayer: (id = documentId, options) => documents.downloadLayer(id, options),
|
|
159
170
|
canDownload: (id = documentId) => documents.canDownload(id),
|
|
171
|
+
preparePrint: (id = documentId, options) => documents.preparePrint(id, options),
|
|
172
|
+
print: (id = documentId, options) => documents.print(id, options),
|
|
173
|
+
getPrintQuality: (id = documentId) => documents.getPrintQuality(id),
|
|
160
174
|
canPrint: (id = documentId) => documents.canPrint(id),
|
|
161
175
|
listPages: (id = documentId) => documents.listPages(id),
|
|
162
176
|
getPage: (page, id = documentId) => documents.getPage(page, id),
|
|
@@ -294,12 +308,14 @@ function createKernel(config) {
|
|
|
294
308
|
leases: /* @__PURE__ */ new Map(),
|
|
295
309
|
settleFlushes: /* @__PURE__ */ new Set(),
|
|
296
310
|
downloadWraps: [],
|
|
311
|
+
printWraps: [],
|
|
297
312
|
changes: require_settings.createDocumentChanges({
|
|
298
313
|
handle: () => session.handle,
|
|
299
314
|
notify: () => store.notify(),
|
|
300
315
|
report
|
|
301
316
|
}),
|
|
302
317
|
changeCount: 0,
|
|
318
|
+
changesSeen: 0,
|
|
303
319
|
close: () => closeSession(session)
|
|
304
320
|
};
|
|
305
321
|
session.settleFlushes.add(() => session.changes.settle());
|
|
@@ -518,13 +534,202 @@ function createKernel(config) {
|
|
|
518
534
|
readAt = session.changeCount;
|
|
519
535
|
return require_settings.cancellable("documents", signal, read(handle));
|
|
520
536
|
};
|
|
521
|
-
const bytes = await require_settings.
|
|
537
|
+
const bytes = await require_settings.runWrapped(session.downloadWraps, readFile);
|
|
522
538
|
if (readAt === session.changeCount) setUnsavedChanges(session, false);
|
|
523
539
|
return bytes;
|
|
524
540
|
} catch (error) {
|
|
525
541
|
throw require_settings.toPluginError("documents", error);
|
|
526
542
|
}
|
|
527
543
|
}
|
|
544
|
+
const printer = config.printer ?? null;
|
|
545
|
+
const canPrintOn = (documentId) => printer !== null && allowsOn(documentId, "doc.print");
|
|
546
|
+
/**
|
|
547
|
+
* How a print comes out: the PDF copy with `doc.print.high`, a right to keep the copy (every
|
|
548
|
+
* print dialog can save it as a file) and a printer that prints a PDF; else pictures, at the
|
|
549
|
+
* resolution `doc.print.high` or `doc.print` allows.
|
|
550
|
+
*/
|
|
551
|
+
const printQualityOf = (documentId) => {
|
|
552
|
+
if (!canPrintOn(documentId)) return null;
|
|
553
|
+
if (!allowsOn(documentId, "doc.print.high")) return PRINT_STANDARD;
|
|
554
|
+
return (allowsOn(documentId, "doc.download") || allowsOn(documentId, "doc.download.flattened")) && printer?.stagePdf ? PRINT_PDF : PRINT_HIGH;
|
|
555
|
+
};
|
|
556
|
+
/** The pages a print asks for, in its order: every page when it names none. */
|
|
557
|
+
function printPagesOf(session, pages) {
|
|
558
|
+
const all = metaOf(session.id)?.pages ?? EMPTY_PAGES;
|
|
559
|
+
if (pages === void 0) return all;
|
|
560
|
+
if (pages.length === 0) throw new require_settings.PluginError("invalid-input", "documents", "a print needs at least one page");
|
|
561
|
+
const found = pages.map((ref) => {
|
|
562
|
+
const page = require_settings.findPage(all, ref);
|
|
563
|
+
if (!page) throw new require_settings.PluginError("not-found", "documents", `page ${ref.objectNumber} is not in this document`);
|
|
564
|
+
return page;
|
|
565
|
+
});
|
|
566
|
+
if (new Set(found).size !== found.length) throw new require_settings.PluginError("invalid-input", "documents", "a print names a page twice");
|
|
567
|
+
return found;
|
|
568
|
+
}
|
|
569
|
+
/**
|
|
570
|
+
* What prints beside the page content: the annotations as the options ask, by default when
|
|
571
|
+
* the user may read them; the form fields whenever the user may read the form.
|
|
572
|
+
*/
|
|
573
|
+
const printLayersOf = (documentId, options) => ({
|
|
574
|
+
includeAnnotations: options.includeAnnotations ?? allowsOn(documentId, "doc.annotate.read"),
|
|
575
|
+
includeFormFields: allowsOn(documentId, "doc.forms.read")
|
|
576
|
+
});
|
|
577
|
+
/**
|
|
578
|
+
* Make the pages as they print and hand them to the printer, once the document settled: the
|
|
579
|
+
* PDF copy, or a picture of each page. The pages are looked up again each time, so one deleted
|
|
580
|
+
* meanwhile refuses `not-found`. Returns the staged print, how it came out, and the change it
|
|
581
|
+
* saw last, so a print can tell it went stale.
|
|
582
|
+
*/
|
|
583
|
+
async function stagePrint(session, activePrinter, quality, options) {
|
|
584
|
+
const { signal } = options;
|
|
585
|
+
await require_settings.settle(session.settleFlushes, [signal, session.signal], report);
|
|
586
|
+
const handle = documentHandle(session.id);
|
|
587
|
+
if (!handle) throw new require_settings.PluginError("not-ready", "documents", "no open document to print");
|
|
588
|
+
const changesSeen = session.changesSeen;
|
|
589
|
+
const job = {
|
|
590
|
+
handle,
|
|
591
|
+
pages: printPagesOf(session, options.pages),
|
|
592
|
+
layers: printLayersOf(session.id, options),
|
|
593
|
+
name: session.name ?? "document",
|
|
594
|
+
options
|
|
595
|
+
};
|
|
596
|
+
options.onProgress?.({
|
|
597
|
+
pagesRendered: 0,
|
|
598
|
+
pageCount: job.pages.length
|
|
599
|
+
});
|
|
600
|
+
if (quality.kind === "images") return {
|
|
601
|
+
staged: await stagePictures(job, activePrinter, quality.dpi),
|
|
602
|
+
quality,
|
|
603
|
+
changesSeen
|
|
604
|
+
};
|
|
605
|
+
try {
|
|
606
|
+
return {
|
|
607
|
+
staged: await stagePdfCopy(job, activePrinter),
|
|
608
|
+
quality,
|
|
609
|
+
changesSeen
|
|
610
|
+
};
|
|
611
|
+
} catch (error) {
|
|
612
|
+
if (signal?.aborted) throw error;
|
|
613
|
+
return {
|
|
614
|
+
staged: await stagePictures(job, activePrinter, PRINT_HIGH.dpi),
|
|
615
|
+
quality: PRINT_HIGH,
|
|
616
|
+
changesSeen
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/** The PDF copy of the pages as they print, staged with the printer. */
|
|
621
|
+
async function stagePdfCopy(job, activePrinter) {
|
|
622
|
+
const { handle, pages, layers, name, options } = job;
|
|
623
|
+
const { signal } = options;
|
|
624
|
+
if (!activePrinter.stagePdf) throw new require_settings.PluginError("unsupported", "documents", "this printer prints no PDF");
|
|
625
|
+
const pdf = await require_settings.cancellable("documents", signal, handle.pages.extract(pages.map((page) => page.ref), {
|
|
626
|
+
flatten: { usage: "print" },
|
|
627
|
+
...layers
|
|
628
|
+
}));
|
|
629
|
+
const staged = await activePrinter.stagePdf(pdf, {
|
|
630
|
+
name,
|
|
631
|
+
...signal ? { signal } : {}
|
|
632
|
+
});
|
|
633
|
+
options.onProgress?.({
|
|
634
|
+
pagesRendered: pages.length,
|
|
635
|
+
pageCount: pages.length
|
|
636
|
+
});
|
|
637
|
+
return staged;
|
|
638
|
+
}
|
|
639
|
+
/** A picture of each page, drawn by the print rules at `dpi`, staged with the printer. */
|
|
640
|
+
async function stagePictures(job, activePrinter, dpi) {
|
|
641
|
+
const { handle, pages, layers, name, options } = job;
|
|
642
|
+
const { signal } = options;
|
|
643
|
+
const sheets = [];
|
|
644
|
+
for (const page of pages) {
|
|
645
|
+
const blob = await require_settings.cancellable("documents", signal, (await require_settings.cancellable("documents", signal, handle.page(page.ref).render.image({
|
|
646
|
+
usage: "print",
|
|
647
|
+
viewport: {
|
|
648
|
+
kind: "dpi",
|
|
649
|
+
dpi
|
|
650
|
+
},
|
|
651
|
+
format: "png",
|
|
652
|
+
...layers
|
|
653
|
+
}))).blob());
|
|
654
|
+
sheets.push({
|
|
655
|
+
image: blob,
|
|
656
|
+
widthPt: page.size.width,
|
|
657
|
+
heightPt: page.size.height
|
|
658
|
+
});
|
|
659
|
+
options.onProgress?.({
|
|
660
|
+
pagesRendered: sheets.length,
|
|
661
|
+
pageCount: pages.length
|
|
662
|
+
});
|
|
663
|
+
}
|
|
664
|
+
return activePrinter.stage(sheets, {
|
|
665
|
+
name,
|
|
666
|
+
...signal ? { signal } : {}
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
/**
|
|
670
|
+
* Get a print ready. Refused before anything runs without `doc.print` or a printer, or for
|
|
671
|
+
* pages the document doesn't have. Its `print()` runs inside every `aroundPrint` wrap (the
|
|
672
|
+
* document's own print actions), and prepares again first when the document changed since:
|
|
673
|
+
* a will-print action that fills in a date is on the paper. When the printer turns the PDF
|
|
674
|
+
* copy down, preparing or printing, the same pages print as pictures, and `quality` says so.
|
|
675
|
+
*/
|
|
676
|
+
async function preparePrint(documentId, options = {}) {
|
|
677
|
+
const session = readySession(documentId, "preparePrint");
|
|
678
|
+
if (!allowsOn(session.id, "doc.print")) throw require_settings.permissionDenied("documents", "doc.print", "documents.preparePrint");
|
|
679
|
+
const quality = printQualityOf(session.id);
|
|
680
|
+
if (!printer || !quality) throw new require_settings.PluginError("unsupported", "documents", "no printer: pass one to createKernel({ printer }), such as browserPrinter() from @embedpdf/web");
|
|
681
|
+
const pageCount = printPagesOf(session, options.pages).length;
|
|
682
|
+
try {
|
|
683
|
+
let { staged, changesSeen, quality: printed } = await stagePrint(session, printer, quality, options);
|
|
684
|
+
let disposed = false;
|
|
685
|
+
const dispose = () => {
|
|
686
|
+
if (disposed) return;
|
|
687
|
+
disposed = true;
|
|
688
|
+
staged.dispose();
|
|
689
|
+
};
|
|
690
|
+
session.scope.defer(dispose);
|
|
691
|
+
/** Stage the print again, as `as`, in place of what was staged. */
|
|
692
|
+
const restage = async (as, signal) => {
|
|
693
|
+
const fresh = await stagePrint(session, printer, as, {
|
|
694
|
+
...options.pages ? { pages: options.pages } : {},
|
|
695
|
+
...options.includeAnnotations !== void 0 ? { includeAnnotations: options.includeAnnotations } : {},
|
|
696
|
+
...signal ? { signal } : {}
|
|
697
|
+
});
|
|
698
|
+
staged.dispose();
|
|
699
|
+
({staged, changesSeen, quality: printed} = fresh);
|
|
700
|
+
};
|
|
701
|
+
return {
|
|
702
|
+
get quality() {
|
|
703
|
+
return printed;
|
|
704
|
+
},
|
|
705
|
+
pageCount,
|
|
706
|
+
needsTap: printer.needsTap === true,
|
|
707
|
+
async print(printOptions) {
|
|
708
|
+
if (disposed) throw new require_settings.PluginError("invalid-input", "documents", "this print was disposed");
|
|
709
|
+
const signal = printOptions?.signal;
|
|
710
|
+
const run = async () => {
|
|
711
|
+
if (session.changesSeen !== changesSeen) await restage(quality, signal);
|
|
712
|
+
if (signal?.aborted) throw new require_settings.PluginError("operation-cancelled", "documents", "print cancelled", { cause: signal.reason });
|
|
713
|
+
try {
|
|
714
|
+
await staged.print();
|
|
715
|
+
} catch (error) {
|
|
716
|
+
if (printed.kind !== "pdf") throw error;
|
|
717
|
+
await restage(PRINT_HIGH, signal);
|
|
718
|
+
await staged.print();
|
|
719
|
+
}
|
|
720
|
+
};
|
|
721
|
+
try {
|
|
722
|
+
await require_settings.runWrapped(session.printWraps, run);
|
|
723
|
+
} catch (error) {
|
|
724
|
+
throw require_settings.toPluginError("documents", error);
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
dispose
|
|
728
|
+
};
|
|
729
|
+
} catch (error) {
|
|
730
|
+
throw require_settings.toPluginError("documents", error);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
528
733
|
/** Whether the plugin's `create()` is running for this document: it has no capability yet. */
|
|
529
734
|
const isBuilding = (plugin, session) => session.building.has(plugin) && !session.capabilities.has(plugin);
|
|
530
735
|
function buildDocumentCapability(plugin, session) {
|
|
@@ -666,9 +871,12 @@ function createKernel(config) {
|
|
|
666
871
|
session.scope.defer(bursts.close);
|
|
667
872
|
const unsubscribeEvents = session.handle.events.subscribe((event) => {
|
|
668
873
|
bursts.first(event);
|
|
669
|
-
if (
|
|
670
|
-
session.
|
|
671
|
-
|
|
874
|
+
if (changesDocument(event)) {
|
|
875
|
+
session.changesSeen += 1;
|
|
876
|
+
if (tracksChanges) {
|
|
877
|
+
session.changeCount += 1;
|
|
878
|
+
setUnsavedChanges(session, true);
|
|
879
|
+
}
|
|
672
880
|
}
|
|
673
881
|
const layout = layoutFromEvent(event);
|
|
674
882
|
if (!layout) return;
|
|
@@ -955,8 +1163,18 @@ function createKernel(config) {
|
|
|
955
1163
|
},
|
|
956
1164
|
download: (id, options) => downloadFile(id, options?.signal, "download", (handle) => handle.download(options?.mode !== void 0 ? { mode: options.mode } : void 0)),
|
|
957
1165
|
downloadLayer: (id, options) => downloadFile(id, options?.signal, "downloadLayer", (handle) => (0, _embedpdf_engine_core_runtime.isLocalDocument)(handle) ? handle.downloadLayer() : Promise.reject(noLayer()), (handle) => (0, _embedpdf_engine_core_runtime.isLocalDocument)(handle) ? null : noLayer()),
|
|
1166
|
+
preparePrint: (id, options) => preparePrint(id, options),
|
|
1167
|
+
async print(id, options = {}) {
|
|
1168
|
+
const prepared = await preparePrint(id, options);
|
|
1169
|
+
try {
|
|
1170
|
+
await prepared.print(options.signal ? { signal: options.signal } : void 0);
|
|
1171
|
+
} finally {
|
|
1172
|
+
prepared.dispose();
|
|
1173
|
+
}
|
|
1174
|
+
},
|
|
1175
|
+
getPrintQuality: (id) => printQualityOf(id),
|
|
958
1176
|
canDownload: (id) => allowsOn(id, "doc.download"),
|
|
959
|
-
canPrint: (id) =>
|
|
1177
|
+
canPrint: (id) => canPrintOn(id),
|
|
960
1178
|
listPages: (id) => metaOf(id)?.pages ?? EMPTY_PAGES,
|
|
961
1179
|
getPage: (page, id) => require_settings.findPage(metaOf(id)?.pages ?? EMPTY_PAGES, page),
|
|
962
1180
|
getPageIndex: (ref, id) => metaOf(id)?.pages.findIndex((pageInfo) => (0, _embedpdf_engine_core_runtime.pageRefsEqual)(pageInfo.ref, ref)) ?? -1,
|