postext-pdf 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +67 -0
  3. package/dist/__bench__/render.bench.test.d.ts +2 -0
  4. package/dist/__bench__/render.bench.test.d.ts.map +1 -0
  5. package/dist/__bench__/render.bench.test.js +86 -0
  6. package/dist/__bench__/render.bench.test.js.map +1 -0
  7. package/dist/__tests__/accessibility.test.d.ts +2 -0
  8. package/dist/__tests__/accessibility.test.d.ts.map +1 -0
  9. package/dist/__tests__/accessibility.test.js +364 -0
  10. package/dist/__tests__/accessibility.test.js.map +1 -0
  11. package/dist/__tests__/contentsLinks.test.d.ts +2 -0
  12. package/dist/__tests__/contentsLinks.test.d.ts.map +1 -0
  13. package/dist/__tests__/contentsLinks.test.js +131 -0
  14. package/dist/__tests__/contentsLinks.test.js.map +1 -0
  15. package/dist/__tests__/fontCache.test.d.ts +2 -0
  16. package/dist/__tests__/fontCache.test.d.ts.map +1 -0
  17. package/dist/__tests__/fontCache.test.js +42 -0
  18. package/dist/__tests__/fontCache.test.js.map +1 -0
  19. package/dist/__tests__/headerFooter.test.d.ts +2 -0
  20. package/dist/__tests__/headerFooter.test.d.ts.map +1 -0
  21. package/dist/__tests__/headerFooter.test.js +68 -0
  22. package/dist/__tests__/headerFooter.test.js.map +1 -0
  23. package/dist/__tests__/rotatedTable.test.d.ts +2 -0
  24. package/dist/__tests__/rotatedTable.test.d.ts.map +1 -0
  25. package/dist/__tests__/rotatedTable.test.js +112 -0
  26. package/dist/__tests__/rotatedTable.test.js.map +1 -0
  27. package/dist/__tests__/svgVector.test.d.ts +2 -0
  28. package/dist/__tests__/svgVector.test.d.ts.map +1 -0
  29. package/dist/__tests__/svgVector.test.js +322 -0
  30. package/dist/__tests__/svgVector.test.js.map +1 -0
  31. package/dist/__tests__/toUnicode.test.d.ts +2 -0
  32. package/dist/__tests__/toUnicode.test.d.ts.map +1 -0
  33. package/dist/__tests__/toUnicode.test.js +57 -0
  34. package/dist/__tests__/toUnicode.test.js.map +1 -0
  35. package/dist/colors.d.ts +23 -0
  36. package/dist/colors.d.ts.map +1 -0
  37. package/dist/colors.js +47 -0
  38. package/dist/colors.js.map +1 -0
  39. package/dist/fontCache.d.ts +41 -0
  40. package/dist/fontCache.d.ts.map +1 -0
  41. package/dist/fontCache.js +154 -0
  42. package/dist/fontCache.js.map +1 -0
  43. package/dist/fontString.d.ts +14 -0
  44. package/dist/fontString.d.ts.map +1 -0
  45. package/dist/fontString.js +43 -0
  46. package/dist/fontString.js.map +1 -0
  47. package/dist/index.d.ts +6 -0
  48. package/dist/index.d.ts.map +1 -0
  49. package/dist/index.js +5 -0
  50. package/dist/index.js.map +1 -0
  51. package/dist/pdf-backend/blockRender.d.ts +15 -0
  52. package/dist/pdf-backend/blockRender.d.ts.map +1 -0
  53. package/dist/pdf-backend/blockRender.js +244 -0
  54. package/dist/pdf-backend/blockRender.js.map +1 -0
  55. package/dist/pdf-backend/fontHelpers.d.ts +6 -0
  56. package/dist/pdf-backend/fontHelpers.d.ts.map +1 -0
  57. package/dist/pdf-backend/fontHelpers.js +81 -0
  58. package/dist/pdf-backend/fontHelpers.js.map +1 -0
  59. package/dist/pdf-backend/headerFooter.d.ts +15 -0
  60. package/dist/pdf-backend/headerFooter.d.ts.map +1 -0
  61. package/dist/pdf-backend/headerFooter.js +145 -0
  62. package/dist/pdf-backend/headerFooter.js.map +1 -0
  63. package/dist/pdf-backend/index.d.ts +47 -0
  64. package/dist/pdf-backend/index.d.ts.map +1 -0
  65. package/dist/pdf-backend/index.js +227 -0
  66. package/dist/pdf-backend/index.js.map +1 -0
  67. package/dist/pdf-backend/links.d.ts +44 -0
  68. package/dist/pdf-backend/links.d.ts.map +1 -0
  69. package/dist/pdf-backend/links.js +110 -0
  70. package/dist/pdf-backend/links.js.map +1 -0
  71. package/dist/pdf-backend/outlines.d.ts +8 -0
  72. package/dist/pdf-backend/outlines.d.ts.map +1 -0
  73. package/dist/pdf-backend/outlines.js +145 -0
  74. package/dist/pdf-backend/outlines.js.map +1 -0
  75. package/dist/pdf-backend/pageDecorations.d.ts +13 -0
  76. package/dist/pdf-backend/pageDecorations.d.ts.map +1 -0
  77. package/dist/pdf-backend/pageDecorations.js +88 -0
  78. package/dist/pdf-backend/pageDecorations.js.map +1 -0
  79. package/dist/pdf-backend/pageLabels.d.ts +8 -0
  80. package/dist/pdf-backend/pageLabels.d.ts.map +1 -0
  81. package/dist/pdf-backend/pageLabels.js +61 -0
  82. package/dist/pdf-backend/pageLabels.js.map +1 -0
  83. package/dist/pdf-backend/primitives.d.ts +46 -0
  84. package/dist/pdf-backend/primitives.d.ts.map +1 -0
  85. package/dist/pdf-backend/primitives.js +162 -0
  86. package/dist/pdf-backend/primitives.js.map +1 -0
  87. package/dist/pdf-backend/renderResourceBlock.d.ts +87 -0
  88. package/dist/pdf-backend/renderResourceBlock.d.ts.map +1 -0
  89. package/dist/pdf-backend/renderResourceBlock.js +753 -0
  90. package/dist/pdf-backend/renderResourceBlock.js.map +1 -0
  91. package/dist/pdf-backend/structureFlow.d.ts +55 -0
  92. package/dist/pdf-backend/structureFlow.d.ts.map +1 -0
  93. package/dist/pdf-backend/structureFlow.js +180 -0
  94. package/dist/pdf-backend/structureFlow.js.map +1 -0
  95. package/dist/pdf-backend/svgVector.d.ts +144 -0
  96. package/dist/pdf-backend/svgVector.d.ts.map +1 -0
  97. package/dist/pdf-backend/svgVector.js +1455 -0
  98. package/dist/pdf-backend/svgVector.js.map +1 -0
  99. package/dist/pdf-backend/tagging.d.ts +136 -0
  100. package/dist/pdf-backend/tagging.d.ts.map +1 -0
  101. package/dist/pdf-backend/tagging.js +296 -0
  102. package/dist/pdf-backend/tagging.js.map +1 -0
  103. package/dist/woff2.d.ts +11 -0
  104. package/dist/woff2.d.ts.map +1 -0
  105. package/dist/woff2.js +47 -0
  106. package/dist/woff2.js.map +1 -0
  107. package/dist/worker/client.d.ts +30 -0
  108. package/dist/worker/client.d.ts.map +1 -0
  109. package/dist/worker/client.js +112 -0
  110. package/dist/worker/client.js.map +1 -0
  111. package/dist/worker/pdf.worker.d.ts +2 -0
  112. package/dist/worker/pdf.worker.d.ts.map +1 -0
  113. package/dist/worker/pdf.worker.js +67 -0
  114. package/dist/worker/pdf.worker.js.map +1 -0
  115. package/dist/worker/protocol.d.ts +49 -0
  116. package/dist/worker/protocol.d.ts.map +1 -0
  117. package/dist/worker/protocol.js +2 -0
  118. package/dist/worker/protocol.js.map +1 -0
  119. package/package.json +67 -0
package/dist/woff2.js ADDED
@@ -0,0 +1,47 @@
1
+ let wawoff2Promise = null;
2
+ function loadWawoff2() {
3
+ if (!wawoff2Promise) {
4
+ wawoff2Promise = (async () => {
5
+ const mod = await import('wawoff2');
6
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
7
+ const anyMod = mod;
8
+ const fn = typeof anyMod === 'function'
9
+ ? anyMod
10
+ : typeof anyMod.decompress === 'function'
11
+ ? anyMod.decompress
12
+ : typeof anyMod.default === 'function'
13
+ ? anyMod.default
14
+ : typeof anyMod.default?.decompress === 'function'
15
+ ? anyMod.default.decompress
16
+ : undefined;
17
+ if (!fn)
18
+ throw new Error('wawoff2: no decompress export');
19
+ return fn;
20
+ })();
21
+ }
22
+ return wawoff2Promise;
23
+ }
24
+ let queue = Promise.resolve();
25
+ /**
26
+ * Decompress a WOFF2 (RFC 8844) binary to raw TTF/OTF bytes. The WASM
27
+ * decoder weighs ~200 KB and is loaded lazily on first use.
28
+ *
29
+ * Calls are serialized and the output is copied out of WASM memory: the
30
+ * emscripten-generated module keeps a single shared heap, so concurrent
31
+ * invocations corrupt each other, and the returned Uint8Array is a live
32
+ * view that a subsequent call would overwrite.
33
+ */
34
+ export async function decompressWoff2(input) {
35
+ const run = async () => {
36
+ const decompress = await loadWawoff2();
37
+ const out = await decompress(input);
38
+ const view = out instanceof Uint8Array ? out : new Uint8Array(out);
39
+ const copy = new Uint8Array(view.byteLength);
40
+ copy.set(view);
41
+ return copy;
42
+ };
43
+ const next = queue.then(run, run);
44
+ queue = next.catch(() => undefined);
45
+ return next;
46
+ }
47
+ //# sourceMappingURL=woff2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"woff2.js","sourceRoot":"","sources":["../src/woff2.ts"],"names":[],"mappings":"AAEA,IAAI,cAAc,GAAiC,IAAI,CAAC;AAExD,SAAS,WAAW;IAClB,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,cAAc,GAAG,CAAC,KAAK,IAAI,EAAE;YAC3B,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,CAAC;YACpC,8DAA8D;YAC9D,MAAM,MAAM,GAAG,GAAU,CAAC;YAC1B,MAAM,EAAE,GACN,OAAO,MAAM,KAAK,UAAU;gBAC1B,CAAC,CAAC,MAAM;gBACR,CAAC,CAAC,OAAO,MAAM,CAAC,UAAU,KAAK,UAAU;oBACvC,CAAC,CAAC,MAAM,CAAC,UAAU;oBACnB,CAAC,CAAC,OAAO,MAAM,CAAC,OAAO,KAAK,UAAU;wBACpC,CAAC,CAAC,MAAM,CAAC,OAAO;wBAChB,CAAC,CAAC,OAAO,MAAM,CAAC,OAAO,EAAE,UAAU,KAAK,UAAU;4BAChD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,UAAU;4BAC3B,CAAC,CAAC,SAAS,CAAC;YACtB,IAAI,CAAC,EAAE;gBAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;YAC1D,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;IACD,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,IAAI,KAAK,GAAqB,OAAO,CAAC,OAAO,EAAE,CAAC;AAEhD;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,KAAiB;IACrD,MAAM,GAAG,GAAG,KAAK,IAAyB,EAAE;QAC1C,MAAM,UAAU,GAAG,MAAM,WAAW,EAAE,CAAC;QACvC,MAAM,GAAG,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,YAAY,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,UAAU,CAAC,GAAG,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACf,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;IACF,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IAClC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IACpC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,30 @@
1
+ import type { VDTDocument } from 'postext';
2
+ import type { PdfFontProvider } from '../fontCache';
3
+ import type { RenderToPdfOptions } from '../pdf-backend';
4
+ import { type SvgRasterizer } from '../pdf-backend/renderResourceBlock';
5
+ export type { RenderProgress } from '../pdf-backend';
6
+ export interface PdfWorkerRenderOptions extends Omit<RenderToPdfOptions, 'resourceBytes' | 'rasterizeSvg'> {
7
+ /** Resource bytes by file id. Their buffers are transferred: pass copies
8
+ * if the caller keeps them. */
9
+ resourceBytes?: Map<string, Uint8Array>;
10
+ /** How the host rasterises an SVG for the worker; the document's `Image`
11
+ * by default. */
12
+ rasterizeSvg?: SvgRasterizer;
13
+ /** Called with the finished document's font provider results too. */
14
+ fontProvider: PdfFontProvider;
15
+ }
16
+ export interface PdfWorkerHandle {
17
+ /** Render on the worker. Fonts and SVG rasters are fetched on this
18
+ * thread when the worker asks (it cannot reach the document's fonts or
19
+ * decode SVG); everything else — text, vector figures, the structure
20
+ * tree, the file itself — is written off the main thread. */
21
+ render(docs: VDTDocument | VDTDocument[], options: PdfWorkerRenderOptions): Promise<Uint8Array>;
22
+ dispose(): void;
23
+ }
24
+ export interface CreatePdfWorkerOptions {
25
+ /** A Worker of the caller's own, for build tooling that controls the
26
+ * worker URL. */
27
+ worker?: Worker;
28
+ }
29
+ export declare function createPdfWorker(options?: CreatePdfWorkerOptions): PdfWorkerHandle;
30
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/worker/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EAAuB,KAAK,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAG7F,YAAY,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAErD,MAAM,WAAW,sBAAuB,SAAQ,IAAI,CAAC,kBAAkB,EAAE,eAAe,GAAG,cAAc,CAAC;IACxG;oCACgC;IAChC,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACxC;sBACkB;IAClB,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,qEAAqE;IACrE,YAAY,EAAE,eAAe,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B;;;kEAG8D;IAC9D,MAAM,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE,EAAE,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IAChG,OAAO,IAAI,IAAI,CAAC;CACjB;AAED,MAAM,WAAW,sBAAsB;IACrC;sBACkB;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAQD,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,sBAAsB,GAAG,eAAe,CAoGjF"}
@@ -0,0 +1,112 @@
1
+ import { rasterizeSvgWithDom } from '../pdf-backend/renderResourceBlock';
2
+ export function createPdfWorker(options) {
3
+ const worker = options?.worker
4
+ ?? new Worker(new URL('./pdf.worker.js', import.meta.url), { type: 'module' });
5
+ let nextId = 1;
6
+ let disposed = false;
7
+ const pending = new Map();
8
+ // One render at a time: the worker's questions go to the render in flight.
9
+ let current = null;
10
+ const send = (msg, transfer) => {
11
+ if (disposed)
12
+ throw new Error('PDF worker has been disposed');
13
+ if (transfer && transfer.length > 0)
14
+ worker.postMessage(msg, transfer);
15
+ else
16
+ worker.postMessage(msg);
17
+ };
18
+ const answer = async (askId, job) => {
19
+ try {
20
+ const bytes = await job();
21
+ // A copy: the provider may keep the original in a cache.
22
+ const copy = bytes ? bytes.slice() : null;
23
+ send({ kind: 'answer', askId, bytes: copy }, copy ? [copy.buffer] : undefined);
24
+ }
25
+ catch (err) {
26
+ send({ kind: 'answer', askId, bytes: null, error: err instanceof Error ? err.message : String(err) });
27
+ }
28
+ };
29
+ worker.addEventListener('message', (event) => {
30
+ const msg = event.data;
31
+ switch (msg.kind) {
32
+ case 'font': {
33
+ const job = current;
34
+ void answer(msg.askId, () => (job ? job.options.fontProvider(msg.family, msg.weight, msg.style) : Promise.resolve(null)));
35
+ return;
36
+ }
37
+ case 'rasterize': {
38
+ const job = current;
39
+ const rasterize = job?.options.rasterizeSvg ?? rasterizeSvgWithDom;
40
+ void answer(msg.askId, () => rasterize(msg.svg, msg.widthPx, msg.heightPx));
41
+ return;
42
+ }
43
+ case 'progress': {
44
+ pending.get(msg.id)?.options.onProgress?.(msg.progress);
45
+ return;
46
+ }
47
+ case 'rendered': {
48
+ const entry = pending.get(msg.id);
49
+ pending.delete(msg.id);
50
+ if (current === entry)
51
+ current = null;
52
+ entry?.resolve(msg.bytes);
53
+ return;
54
+ }
55
+ case 'error': {
56
+ const entry = pending.get(msg.id);
57
+ pending.delete(msg.id);
58
+ if (current === entry)
59
+ current = null;
60
+ entry?.reject(Object.assign(new Error(msg.message), msg.stack ? { stack: msg.stack } : {}));
61
+ return;
62
+ }
63
+ }
64
+ });
65
+ worker.addEventListener('error', (event) => {
66
+ for (const entry of pending.values())
67
+ entry.reject(new Error(event.message || 'PDF worker error'));
68
+ pending.clear();
69
+ current = null;
70
+ });
71
+ return {
72
+ render(input, renderOptions) {
73
+ const docs = Array.isArray(input) ? input : [input];
74
+ const id = nextId++;
75
+ return new Promise((resolve, reject) => {
76
+ const entry = { resolve, reject, options: renderOptions };
77
+ pending.set(id, entry);
78
+ current = entry;
79
+ const resourceBytes = [...(renderOptions.resourceBytes ?? new Map())];
80
+ const buffers = new Set();
81
+ for (const [, bytes] of resourceBytes) {
82
+ if (bytes.buffer instanceof ArrayBuffer)
83
+ buffers.add(bytes.buffer);
84
+ }
85
+ const { pageNegative, outlines, colorSpace, accessible } = renderOptions;
86
+ try {
87
+ send({ kind: 'render', id, docs, settings: { pageNegative, outlines, colorSpace, accessible }, resourceBytes }, [...buffers]);
88
+ }
89
+ catch (err) {
90
+ pending.delete(id);
91
+ current = null;
92
+ reject(err);
93
+ }
94
+ });
95
+ },
96
+ dispose() {
97
+ if (disposed)
98
+ return;
99
+ disposed = true;
100
+ try {
101
+ worker.postMessage({ kind: 'dispose' });
102
+ }
103
+ catch { /* ignore */ }
104
+ worker.terminate();
105
+ for (const entry of pending.values())
106
+ entry.reject(new DOMException('Worker disposed', 'AbortError'));
107
+ pending.clear();
108
+ current = null;
109
+ },
110
+ };
111
+ }
112
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/worker/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pdf.worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.worker.d.ts","sourceRoot":"","sources":["../../src/worker/pdf.worker.ts"],"names":[],"mappings":""}
@@ -0,0 +1,67 @@
1
+ /// <reference lib="webworker" />
2
+ import { renderToPdf } from '../pdf-backend';
3
+ const ctx = self;
4
+ function post(msg, transfer) {
5
+ if (transfer && transfer.length > 0)
6
+ ctx.postMessage(msg, transfer);
7
+ else
8
+ ctx.postMessage(msg);
9
+ }
10
+ let nextAskId = 1;
11
+ const asks = new Map();
12
+ /** Ask the host for something only it can do; resolves with its answer. */
13
+ function ask(question) {
14
+ const askId = nextAskId++;
15
+ return new Promise((resolve, reject) => {
16
+ asks.set(askId, { resolve, reject });
17
+ post({ ...question, askId });
18
+ });
19
+ }
20
+ ctx.addEventListener('message', async (event) => {
21
+ const msg = event.data;
22
+ switch (msg.kind) {
23
+ case 'answer': {
24
+ const pending = asks.get(msg.askId);
25
+ if (!pending)
26
+ return;
27
+ asks.delete(msg.askId);
28
+ if (msg.error)
29
+ pending.reject(new Error(msg.error));
30
+ else
31
+ pending.resolve(msg.bytes);
32
+ return;
33
+ }
34
+ case 'render': {
35
+ const bytesById = new Map(msg.resourceBytes);
36
+ try {
37
+ const bytes = await renderToPdf(msg.docs, {
38
+ ...msg.settings,
39
+ fontProvider: async (family, weight, style) => {
40
+ const answer = await ask({ kind: 'font', family, weight, style });
41
+ if (!answer)
42
+ throw new Error(`postext-pdf: no bytes for font ${family} ${weight} ${style}`);
43
+ return answer;
44
+ },
45
+ rasterizeSvg: (svg, widthPx, heightPx) => ask({ kind: 'rasterize', svg, widthPx, heightPx }).catch(() => null),
46
+ resourceBytes: (fileId) => bytesById.get(fileId),
47
+ onProgress: (progress) => post({ kind: 'progress', id: msg.id, progress }),
48
+ });
49
+ post({ kind: 'rendered', id: msg.id, bytes }, [bytes.buffer]);
50
+ }
51
+ catch (err) {
52
+ post({
53
+ kind: 'error',
54
+ id: msg.id,
55
+ message: err instanceof Error ? err.message : String(err),
56
+ ...(err instanceof Error && err.stack ? { stack: err.stack } : {}),
57
+ });
58
+ }
59
+ return;
60
+ }
61
+ case 'dispose': {
62
+ ctx.close();
63
+ return;
64
+ }
65
+ }
66
+ });
67
+ //# sourceMappingURL=pdf.worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.worker.js","sourceRoot":"","sources":["../../src/worker/pdf.worker.ts"],"names":[],"mappings":"AAAA,iCAAiC;AAEjC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,MAAM,GAAG,GAA+B,IAA6C,CAAC;AAEtF,SAAS,IAAI,CAAC,GAAuB,EAAE,QAAyB;IAC9D,IAAI,QAAQ,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC;QAAE,GAAG,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;;QAC/D,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,IAAI,SAAS,GAAG,CAAC,CAAC;AAClB,MAAM,IAAI,GAAG,IAAI,GAAG,EAAyF,CAAC;AAM9G,2EAA2E;AAC3E,SAAS,GAAG,CAAC,QAAkB;IAC7B,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,GAAG,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IAC/B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,GAAG,CAAC,gBAAgB,CAAC,SAAS,EAAE,KAAK,EAAE,KAAsC,EAAE,EAAE;IAC/E,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC;IACvB,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;QACjB,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACpC,IAAI,CAAC,OAAO;gBAAE,OAAO;YACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YACvB,IAAI,GAAG,CAAC,KAAK;gBAAE,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;;gBAC/C,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;YAChC,OAAO;QACT,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE;oBACxC,GAAG,GAAG,CAAC,QAAQ;oBACf,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE;wBAC5C,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;wBAClE,IAAI,CAAC,MAAM;4BAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC;wBAC5F,OAAO,MAAM,CAAC;oBAChB,CAAC;oBACD,YAAY,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC;oBAC9G,aAAa,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC;oBAChD,UAAU,EAAE,CAAC,QAAQ,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC;iBAC3E,CAAC,CAAC;gBACH,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;YAChE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC;oBACH,IAAI,EAAE,OAAO;oBACb,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,OAAO,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;oBACzD,GAAG,CAAC,GAAG,YAAY,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACnE,CAAC,CAAC;YACL,CAAC;YACD,OAAO;QACT,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,GAAG,CAAC,KAAK,EAAE,CAAC;YACZ,OAAO;QACT,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,49 @@
1
+ import type { VDTDocument } from 'postext';
2
+ import type { RenderProgress, RenderToPdfOptions } from '../pdf-backend';
3
+ /** The render options that travel to the worker as data. */
4
+ export type PdfRenderSettings = Pick<RenderToPdfOptions, 'pageNegative' | 'outlines' | 'colorSpace' | 'accessible'>;
5
+ export type PdfRequestMessage = {
6
+ kind: 'render';
7
+ id: number;
8
+ docs: VDTDocument[];
9
+ settings: PdfRenderSettings;
10
+ /** Resource bytes by file id (transferred). */
11
+ resourceBytes: [string, Uint8Array][];
12
+ } | {
13
+ /** The host's answer to a `font` or `rasterize` question. */
14
+ kind: 'answer';
15
+ askId: number;
16
+ bytes: Uint8Array | null;
17
+ error?: string;
18
+ } | {
19
+ kind: 'dispose';
20
+ };
21
+ export type PdfResponseMessage = {
22
+ kind: 'progress';
23
+ id: number;
24
+ progress: RenderProgress;
25
+ } | {
26
+ kind: 'rendered';
27
+ id: number;
28
+ bytes: Uint8Array;
29
+ } | {
30
+ kind: 'error';
31
+ id: number;
32
+ message: string;
33
+ stack?: string;
34
+ }
35
+ /** The worker cannot reach fonts or decode SVG itself: it asks the host. */
36
+ | {
37
+ kind: 'font';
38
+ askId: number;
39
+ family: string;
40
+ weight: number;
41
+ style: 'normal' | 'italic';
42
+ } | {
43
+ kind: 'rasterize';
44
+ askId: number;
45
+ svg: string;
46
+ widthPx: number;
47
+ heightPx: number;
48
+ };
49
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/worker/protocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAEzE,4DAA4D;AAC5D,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,EAAE,cAAc,GAAG,UAAU,GAAG,YAAY,GAAG,YAAY,CAAC,CAAC;AAEpH,MAAM,MAAM,iBAAiB,GACzB;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,WAAW,EAAE,CAAC;IACpB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,+CAA+C;IAC/C,aAAa,EAAE,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;CACvC,GACD;IACE,6DAA6D;IAC7D,IAAI,EAAE,QAAQ,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,GACD;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,cAAc,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE;AAChE,4EAA4E;GAC1E;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAA;CAAE,GAC3F;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/worker/protocol.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "postext-pdf",
3
+ "version": "0.1.0",
4
+ "description": "Browser-native PDF renderer for Postext documents. Consumes the same VDT as the canvas/HTML backends and produces a physical PDF with faithful glyph positioning, justification, crop marks, and baseline grid.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "homepage": "https://postext.dev/",
8
+ "keywords": [
9
+ "postext",
10
+ "pdf",
11
+ "typesetting",
12
+ "layout",
13
+ "pdf-lib",
14
+ "woff2",
15
+ "fonts",
16
+ "print",
17
+ "typography"
18
+ ],
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "https://github.com/drnachio/postext.git",
22
+ "directory": "packages/postext-pdf"
23
+ },
24
+ "files": [
25
+ "dist"
26
+ ],
27
+ "exports": {
28
+ ".": {
29
+ "types": "./dist/index.d.ts",
30
+ "default": "./dist/index.js"
31
+ },
32
+ "./worker": {
33
+ "types": "./dist/worker/client.d.ts",
34
+ "default": "./dist/worker/client.js"
35
+ },
36
+ "./worker/entry": {
37
+ "types": "./dist/worker/pdf.worker.d.ts",
38
+ "default": "./dist/worker/pdf.worker.js"
39
+ },
40
+ "./package.json": "./package.json"
41
+ },
42
+ "peerDependencies": {
43
+ "postext": ">=0.1.0"
44
+ },
45
+ "dependencies": {
46
+ "@pdf-lib/fontkit": "^1.1.1",
47
+ "pdf-lib": "^1.17.1",
48
+ "wawoff2": "^2.0.1"
49
+ },
50
+ "devDependencies": {
51
+ "@postext/typescript-config": "0.0.0",
52
+ "@types/node": "^26.5.0",
53
+ "eslint": "^9.39.4",
54
+ "postext": "0.3.48",
55
+ "typescript": "^6.0.3",
56
+ "typescript-eslint": "^8.70.0",
57
+ "vitest": "^5.0.0"
58
+ },
59
+ "scripts": {
60
+ "build": "rm -rf dist && tsc",
61
+ "dev": "tsc --watch",
62
+ "check-types": "tsc --noEmit",
63
+ "lint": "eslint .",
64
+ "test": "vitest run",
65
+ "bench": "BENCH=1 vitest run __bench__"
66
+ }
67
+ }