@laminapdf/sdk 0.0.0-stage → 0.2.0-alpha.2

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 (139) hide show
  1. package/README.md +208 -2
  2. package/dist/api.d.ts +23 -0
  3. package/dist/api.d.ts.map +1 -0
  4. package/dist/api.js +11 -0
  5. package/dist/api.js.map +1 -0
  6. package/dist/builder.d.ts +319 -0
  7. package/dist/builder.d.ts.map +1 -0
  8. package/dist/builder.js +540 -0
  9. package/dist/builder.js.map +1 -0
  10. package/dist/defined.d.ts +5 -0
  11. package/dist/defined.d.ts.map +1 -0
  12. package/dist/defined.js +7 -0
  13. package/dist/defined.js.map +1 -0
  14. package/dist/document.d.ts +241 -0
  15. package/dist/document.d.ts.map +1 -0
  16. package/dist/document.js +427 -0
  17. package/dist/document.js.map +1 -0
  18. package/dist/entry/node.d.ts +30 -0
  19. package/dist/entry/node.d.ts.map +1 -0
  20. package/dist/entry/node.js +37 -0
  21. package/dist/entry/node.js.map +1 -0
  22. package/dist/entry/workerd.d.ts +30 -0
  23. package/dist/entry/workerd.d.ts.map +1 -0
  24. package/dist/entry/workerd.js +37 -0
  25. package/dist/entry/workerd.js.map +1 -0
  26. package/dist/errors.d.ts +102 -0
  27. package/dist/errors.d.ts.map +1 -0
  28. package/dist/errors.js +137 -0
  29. package/dist/errors.js.map +1 -0
  30. package/dist/explain.d.ts +20 -0
  31. package/dist/explain.d.ts.map +1 -0
  32. package/dist/explain.js +14 -0
  33. package/dist/explain.js.map +1 -0
  34. package/dist/font.d.ts +66 -0
  35. package/dist/font.d.ts.map +1 -0
  36. package/dist/font.js +103 -0
  37. package/dist/font.js.map +1 -0
  38. package/dist/generated/builder-enums.d.ts +29 -0
  39. package/dist/generated/builder-enums.d.ts.map +1 -0
  40. package/dist/generated/builder-enums.js +80 -0
  41. package/dist/generated/builder-enums.js.map +1 -0
  42. package/dist/generated/codes.d.ts +97 -0
  43. package/dist/generated/codes.d.ts.map +1 -0
  44. package/dist/generated/codes.js +453 -0
  45. package/dist/generated/codes.js.map +1 -0
  46. package/dist/generated/explain.d.ts +6 -0
  47. package/dist/generated/explain.d.ts.map +1 -0
  48. package/dist/generated/explain.js +138 -0
  49. package/dist/generated/explain.js.map +1 -0
  50. package/dist/index.d.ts +30 -0
  51. package/dist/index.d.ts.map +1 -0
  52. package/dist/index.js +37 -0
  53. package/dist/index.js.map +1 -0
  54. package/dist/init.d.ts +80 -0
  55. package/dist/init.d.ts.map +1 -0
  56. package/dist/init.js +127 -0
  57. package/dist/init.js.map +1 -0
  58. package/dist/loader/fetch.d.ts +3 -0
  59. package/dist/loader/fetch.d.ts.map +1 -0
  60. package/dist/loader/fetch.js +2 -0
  61. package/dist/loader/fetch.js.map +1 -0
  62. package/dist/loader/node.d.ts +3 -0
  63. package/dist/loader/node.d.ts.map +1 -0
  64. package/dist/loader/node.js +9 -0
  65. package/dist/loader/node.js.map +1 -0
  66. package/dist/loader/workerd.d.ts +3 -0
  67. package/dist/loader/workerd.d.ts.map +1 -0
  68. package/dist/loader/workerd.js +15 -0
  69. package/dist/loader/workerd.js.map +1 -0
  70. package/dist/matrix.d.ts +16 -0
  71. package/dist/matrix.d.ts.map +1 -0
  72. package/dist/matrix.js +36 -0
  73. package/dist/matrix.js.map +1 -0
  74. package/dist/path.d.ts +34 -0
  75. package/dist/path.d.ts.map +1 -0
  76. package/dist/path.js +49 -0
  77. package/dist/path.js.map +1 -0
  78. package/dist/source/http.d.ts +36 -0
  79. package/dist/source/http.d.ts.map +1 -0
  80. package/dist/source/http.js +211 -0
  81. package/dist/source/http.js.map +1 -0
  82. package/dist/source/range.d.ts +70 -0
  83. package/dist/source/range.d.ts.map +1 -0
  84. package/dist/source/range.js +96 -0
  85. package/dist/source/range.js.map +1 -0
  86. package/dist/text.d.ts +90 -0
  87. package/dist/text.d.ts.map +1 -0
  88. package/dist/text.js +127 -0
  89. package/dist/text.js.map +1 -0
  90. package/dist/transaction.d.ts +36 -0
  91. package/dist/transaction.d.ts.map +1 -0
  92. package/dist/transaction.js +47 -0
  93. package/dist/transaction.js.map +1 -0
  94. package/dist/types.d.ts +79 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/dist/version.d.ts +3 -0
  99. package/dist/version.d.ts.map +1 -0
  100. package/dist/version.js +6 -0
  101. package/dist/version.js.map +1 -0
  102. package/dist/worker/client.d.ts +87 -0
  103. package/dist/worker/client.d.ts.map +1 -0
  104. package/dist/worker/client.js +405 -0
  105. package/dist/worker/client.js.map +1 -0
  106. package/dist/worker/emitter.d.ts +12 -0
  107. package/dist/worker/emitter.d.ts.map +1 -0
  108. package/dist/worker/emitter.js +34 -0
  109. package/dist/worker/emitter.js.map +1 -0
  110. package/dist/worker/entry.d.ts +2 -0
  111. package/dist/worker/entry.d.ts.map +1 -0
  112. package/dist/worker/entry.js +4 -0
  113. package/dist/worker/entry.js.map +1 -0
  114. package/dist/worker/index.d.ts +7 -0
  115. package/dist/worker/index.d.ts.map +1 -0
  116. package/dist/worker/index.js +4 -0
  117. package/dist/worker/index.js.map +1 -0
  118. package/dist/worker/protocol.d.ts +82 -0
  119. package/dist/worker/protocol.d.ts.map +1 -0
  120. package/dist/worker/protocol.js +11 -0
  121. package/dist/worker/protocol.js.map +1 -0
  122. package/dist/worker/server.d.ts +51 -0
  123. package/dist/worker/server.d.ts.map +1 -0
  124. package/dist/worker/server.js +460 -0
  125. package/dist/worker/server.js.map +1 -0
  126. package/dist/worker/support.d.ts +39 -0
  127. package/dist/worker/support.d.ts.map +1 -0
  128. package/dist/worker/support.js +25 -0
  129. package/dist/worker/support.js.map +1 -0
  130. package/dist/worker/transfer.d.ts +3 -0
  131. package/dist/worker/transfer.d.ts.map +1 -0
  132. package/dist/worker/transfer.js +13 -0
  133. package/dist/worker/transfer.js.map +1 -0
  134. package/dist/worker/types.d.ts +43 -0
  135. package/dist/worker/types.d.ts.map +1 -0
  136. package/dist/worker/types.js +2 -0
  137. package/dist/worker/types.js.map +1 -0
  138. package/package.json +91 -3
  139. package/schemas/error.schema.json +288 -0
@@ -0,0 +1,70 @@
1
+ import type { WasmSparseSource } from "@laminapdf/wasm/base";
2
+ /** A byte range of the input. */
3
+ export interface ByteRange {
4
+ /** First byte. */
5
+ readonly offset: number;
6
+ /** Number of bytes. */
7
+ readonly length: number;
8
+ }
9
+ /**
10
+ * Random access to a file whose bytes are fetched on demand (a remote file, a `Blob`, a file
11
+ * handle). Matches the viewer's source interface (C3a).
12
+ */
13
+ export interface RangeSource {
14
+ /** The file's size in bytes. */
15
+ readonly size: number;
16
+ /**
17
+ * The `length` bytes at `offset` (exactly that many: the file is at least `offset + length`
18
+ * long). Rejects when `signal` aborts.
19
+ */
20
+ read(offset: number, length: number, options?: {
21
+ readonly signal?: AbortSignal;
22
+ }): Promise<Uint8Array>;
23
+ /** The block size this source prefers fetches aligned to (HTTP: fewer, larger requests). */
24
+ readonly blockSize?: number;
25
+ }
26
+ /** How a range document fetches. */
27
+ export interface RangeOptions {
28
+ /** Aborts the open's fetches: it rejects with the signal's reason. Later calls take their own
29
+ * signal ({@link Document.ensure}). */
30
+ readonly signal?: AbortSignal;
31
+ /** Fetches are widened to whole blocks of this many bytes (default: the source's, else 4096). */
32
+ readonly blockSize?: number;
33
+ /** Extra bytes fetched after each range (default 0). */
34
+ readonly readahead?: number;
35
+ /** Rounds of fetches per call before giving up with the last `data-pending` (default 1024). */
36
+ readonly maxRounds?: number;
37
+ /** The most bytes the document may hold (default: no limit); more is `source-budget-exceeded`. */
38
+ readonly budget?: number;
39
+ }
40
+ /**
41
+ * A {@link RangeSource} over a caller's read function (a `Blob.slice`, a file handle, an IPC call).
42
+ *
43
+ * @param size - the file's size in bytes.
44
+ * @param read - returns the `length` bytes at `offset`.
45
+ */
46
+ export declare function callbackSource(size: number, read: (offset: number, length: number, signal?: AbortSignal) => Promise<Uint8Array>): RangeSource;
47
+ /** @internal Marks a source whose bytes are all in memory already (`httpRangeSource` after a `200`). */
48
+ export declare const WHOLE: unique symbol;
49
+ /** @internal The whole file, when `source` already has it in memory. */
50
+ export declare function wholeBytes(source: RangeSource): Uint8Array | undefined;
51
+ /** @internal What a range document keeps to fetch more: never the password or a signal. */
52
+ export interface RangeState {
53
+ readonly sparse: WasmSparseSource;
54
+ readonly source: RangeSource;
55
+ readonly blockSize: number;
56
+ readonly readahead: number;
57
+ readonly maxRounds: number;
58
+ }
59
+ /**
60
+ * Runs `call` until it stops throwing (or rejecting with) `data-pending`: fetches the ranges
61
+ * asked for (widened to blocks, minus what the source holds), supplies them and calls again.
62
+ * Gives up with the last `data-pending` after `maxRounds`, or when a round asks again for
63
+ * exactly what the round before asked (no progress). The fetches of a round share one abort
64
+ * controller: `signal` aborts them all, and the first failure aborts the others; the round waits
65
+ * for every fetch before it throws, so nothing is supplied after it returns.
66
+ *
67
+ * @internal
68
+ */
69
+ export declare function settle<T>(state: RangeState, call: () => T | Promise<T>, signal?: AbortSignal): Promise<T>;
70
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.d.ts","sourceRoot":"","sources":["../../src/source/range.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAG7D,iCAAiC;AACjC,MAAM,WAAW,SAAS;IACxB,kBAAkB;IAClB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,uBAAuB;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,gCAAgC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;KAAE,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACvG,4FAA4F;IAC5F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B;2CACuC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,iGAAiG;IACjG,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,wDAAwD;IACxD,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,+FAA+F;IAC/F,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,kGAAkG;IAClG,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,KAAK,OAAO,CAAC,UAAU,CAAC,GAClF,WAAW,CAEb;AAOD,wGAAwG;AACxG,eAAO,MAAM,KAAK,EAAE,OAAO,MAAoC,CAAC;AAEhE,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,GAAG,SAAS,CAGtE;AAED,2FAA2F;AAC3F,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAsB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,CAqB/G"}
@@ -0,0 +1,96 @@
1
+ import { guard, isLaminaPdfError, packageError } from "../errors.js";
2
+ /**
3
+ * A {@link RangeSource} over a caller's read function (a `Blob.slice`, a file handle, an IPC call).
4
+ *
5
+ * @param size - the file's size in bytes.
6
+ * @param read - returns the `length` bytes at `offset`.
7
+ */
8
+ export function callbackSource(size, read) {
9
+ return { size, read: (offset, length, options) => read(offset, length, options?.signal) };
10
+ }
11
+ /** The ranges of a `data-pending` error. */
12
+ function rangesOf(e) {
13
+ return e.ranges ?? [];
14
+ }
15
+ /** @internal Marks a source whose bytes are all in memory already (`httpRangeSource` after a `200`). */
16
+ export const WHOLE = Symbol("lamina.wholeBytes");
17
+ /** @internal The whole file, when `source` already has it in memory. */
18
+ export function wholeBytes(source) {
19
+ const bytes = source[WHOLE];
20
+ return bytes instanceof Uint8Array ? bytes : undefined;
21
+ }
22
+ /**
23
+ * Runs `call` until it stops throwing (or rejecting with) `data-pending`: fetches the ranges
24
+ * asked for (widened to blocks, minus what the source holds), supplies them and calls again.
25
+ * Gives up with the last `data-pending` after `maxRounds`, or when a round asks again for
26
+ * exactly what the round before asked (no progress). The fetches of a round share one abort
27
+ * controller: `signal` aborts them all, and the first failure aborts the others; the round waits
28
+ * for every fetch before it throws, so nothing is supplied after it returns.
29
+ *
30
+ * @internal
31
+ */
32
+ export async function settle(state, call, signal) {
33
+ const { sparse, blockSize, readahead, maxRounds } = state;
34
+ let previous;
35
+ for (let round = 0;; round++) {
36
+ let error;
37
+ try {
38
+ return await call();
39
+ }
40
+ catch (e) {
41
+ if (!isLaminaPdfError(e, "data-pending"))
42
+ throw e;
43
+ error = e;
44
+ }
45
+ const asked = rangesOf(error);
46
+ const key = JSON.stringify(asked);
47
+ const flat = new Float64Array(asked.flatMap((r) => [r.offset, r.offset + r.length]));
48
+ // The planning is laminapdf-source's (`SparseSource::to_fetch`), shared with the Rust loop.
49
+ const todo = guard(() => sparse.toFetch(flat, blockSize, readahead));
50
+ if (round >= maxRounds || todo.length === 0 || key === previous)
51
+ throw error;
52
+ signal?.throwIfAborted();
53
+ await fetchRound(state, todo, signal);
54
+ previous = key;
55
+ }
56
+ }
57
+ /** Fetches and supplies the flat `[start, end, …]` ranges of one round. */
58
+ async function fetchRound(state, todo, signal) {
59
+ const { sparse, source } = state;
60
+ const controller = new AbortController();
61
+ const onAbort = () => controller.abort(signal?.reason);
62
+ signal?.addEventListener("abort", onAbort, { once: true });
63
+ let failure;
64
+ const fetches = [];
65
+ for (let i = 0; i + 1 < todo.length; i += 2) {
66
+ const start = todo[i] ?? 0;
67
+ const end = todo[i + 1] ?? 0;
68
+ fetches.push(source
69
+ .read(start, end - start, { signal: controller.signal })
70
+ .then((bytes) => {
71
+ if (bytes.length !== end - start) {
72
+ throw packageError("fetch-failed", "a range source returned a different number of bytes than asked for", {
73
+ data: { reason: "length", expected: end - start, got: bytes.length },
74
+ });
75
+ }
76
+ if (!controller.signal.aborted)
77
+ guard(() => sparse.supply(start, bytes));
78
+ })
79
+ .catch((e) => {
80
+ // The first failure wins; the aborts it causes in the other fetches don't replace it.
81
+ failure ??= { reason: e };
82
+ controller.abort(e);
83
+ }));
84
+ }
85
+ try {
86
+ await Promise.all(fetches);
87
+ }
88
+ finally {
89
+ signal?.removeEventListener("abort", onAbort);
90
+ }
91
+ if (signal?.aborted)
92
+ throw signal.reason;
93
+ if (failure !== undefined)
94
+ throw failure.reason;
95
+ }
96
+ //# sourceMappingURL=range.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"range.js","sourceRoot":"","sources":["../../src/source/range.ts"],"names":[],"mappings":"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"}
package/dist/text.d.ts ADDED
@@ -0,0 +1,90 @@
1
+ import type { PageTextJs, TextRunJs } from "@laminapdf/wasm/extract";
2
+ /** Options for {@link PageRef.text}. */
3
+ export interface TextOptions {
4
+ /** Leave out text drawn invisibly (rendering modes 3 and 7: OCR layers, hidden text). */
5
+ readonly skipInvisible?: boolean;
6
+ }
7
+ /** A point in page space (ADR 0027: top-left of the displayed CropBox, y down, points). */
8
+ export interface QuadPoint {
9
+ readonly x: number;
10
+ readonly y: number;
11
+ }
12
+ /** A glyph's quad: its four corners, in drawing order (bottom-left, bottom-right, top-right, top-left of the glyph box). */
13
+ export type GlyphQuad = readonly [QuadPoint, QuadPoint, QuadPoint, QuadPoint];
14
+ /** One glyph of a run. */
15
+ export interface TextGlyph {
16
+ /** The glyph's text (document text; U+FFFD when its Unicode is unknown). */
17
+ readonly text: string;
18
+ /** Its quad in page space. */
19
+ readonly quad: GlyphQuad;
20
+ }
21
+ /** A run: glyphs of one font, size, direction and marked content on one baseline, in logical order. */
22
+ export declare class TextRun {
23
+ #private;
24
+ /** @internal */
25
+ constructor(page: PageText, run: TextRunJs);
26
+ /** The run's text in logical order (document text). */
27
+ get text(): string;
28
+ /** The font's `/BaseFont` (document text). */
29
+ get font(): string;
30
+ /** Font size, the text matrix applied. */
31
+ get size(): number;
32
+ /** Vertical writing. */
33
+ get vertical(): boolean;
34
+ /** The marked-content ID the run is in, if any (structure tree links). */
35
+ get mcid(): number | undefined;
36
+ /** The text comes from an `/ActualText` span. */
37
+ get actualText(): boolean;
38
+ /** Drawn invisibly (`Tr` 3 or 7: an OCR layer, hidden text). */
39
+ get invisible(): boolean;
40
+ /** The bounds of its glyph quads in page space: `{ x, y, width, height }`. */
41
+ get bounds(): {
42
+ readonly x: number;
43
+ readonly y: number;
44
+ readonly width: number;
45
+ readonly height: number;
46
+ };
47
+ /** The `[start, end)` range of its glyphs in the page's glyph arrays ({@link PageText.buffers}). */
48
+ get glyphRange(): readonly [number, number];
49
+ /** Its glyphs, with their quads (built on each call). */
50
+ glyphs(): TextGlyph[];
51
+ }
52
+ /** @internal The raw arrays of a PageText (the worker client sends them, L2a). */
53
+ export declare let rawOf: (text: PageText) => PageTextJs;
54
+ /** A page's extracted text: lines in reading order, and runs with their glyphs' quads. */
55
+ export declare class PageText {
56
+ #private;
57
+ /** @internal */
58
+ constructor(raw: PageTextJs);
59
+ /** The text by line (runs on one baseline joined, trimmed), in content order. */
60
+ get lines(): readonly string[];
61
+ /** The page's text: its lines joined with `\n`. */
62
+ text(): string;
63
+ /** The runs, in content order (made on first use). */
64
+ get runs(): readonly TextRun[];
65
+ /** Glyphs whose Unicode is unknown (shown as U+FFFD). */
66
+ get unmapped(): number;
67
+ /** The number of glyphs. */
68
+ readonly glyphCount: number;
69
+ /**
70
+ * Glyph `i`'s text and quad.
71
+ *
72
+ * @throws `RangeError` for an index outside `0 … glyphCount - 1`; `TypeError` once
73
+ * {@link PageText.buffers}' arrays were transferred to another thread.
74
+ */
75
+ glyph(i: number): TextGlyph;
76
+ /**
77
+ * The arrays as the WASM returned them: `quads` (8 numbers per glyph), `glyphText` and
78
+ * `glyphOffsets` (glyph i is `glyphText.slice(glyphOffsets[i], glyphOffsets[i + 1])`). Post
79
+ * `quads.buffer` and `glyphOffsets.buffer` as transferables to move them to another thread;
80
+ * that detaches them here, and this PageText's `glyph()` and `glyphs()` then throw (`lines`
81
+ * and `runs` keep working). They are this PageText's own arrays, not copies: writing to them
82
+ * changes what `glyph()` returns.
83
+ */
84
+ get buffers(): {
85
+ readonly quads: Float32Array;
86
+ readonly glyphText: string;
87
+ readonly glyphOffsets: Uint32Array;
88
+ };
89
+ }
90
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAErE,wCAAwC;AACxC,MAAM,WAAW,WAAW;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,aAAa,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,2FAA2F;AAC3F,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,4HAA4H;AAC5H,MAAM,MAAM,SAAS,GAAG,SAAS,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;AAE9E,0BAA0B;AAC1B,MAAM,WAAW,SAAS;IACxB,4EAA4E;IAC5E,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,8BAA8B;IAC9B,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;CAC1B;AAED,uGAAuG;AACvG,qBAAa,OAAO;;IAMlB,gBAAgB;IAChB,YAAY,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,SAAS,EAIzC;IAED,uDAAuD;IACvD,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,8CAA8C;IAC9C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,0CAA0C;IAC1C,IAAI,IAAI,IAAI,MAAM,CAEjB;IAED,wBAAwB;IACxB,IAAI,QAAQ,IAAI,OAAO,CAEtB;IAED,0EAA0E;IAC1E,IAAI,IAAI,IAAI,MAAM,GAAG,SAAS,CAE7B;IAED,iDAAiD;IACjD,IAAI,UAAU,IAAI,OAAO,CAExB;IAED,gEAAgE;IAChE,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED,8EAA8E;IAC9E,IAAI,MAAM,IAAI;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAGxG;IAED,oGAAoG;IACpG,IAAI,UAAU,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAE1C;IAED,yDAAyD;IACzD,MAAM,IAAI,SAAS,EAAE,CAKpB;CACF;AAED,kFAAkF;AAClF,eAAO,IAAI,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,CAAC;AAEjD,0FAA0F;AAC1F,qBAAa,QAAQ;;IAUnB,gBAAgB;IAChB,YAAY,GAAG,EAAE,UAAU,EAK1B;IAED,iFAAiF;IACjF,IAAI,KAAK,IAAI,SAAS,MAAM,EAAE,CAE7B;IAED,mDAAmD;IACnD,IAAI,IAAI,MAAM,CAEb;IAED,sDAAsD;IACtD,IAAI,IAAI,IAAI,SAAS,OAAO,EAAE,CAG7B;IAED,yDAAyD;IACzD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,4BAA4B;IAC5B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B;;;;;OAKG;IACH,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,SAAS,CAc1B;IAED;;;;;;;OAOG;IACH,IAAI,OAAO,IAAI;QAAE,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;QAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAA;KAAE,CAE9G;CACF"}
package/dist/text.js ADDED
@@ -0,0 +1,127 @@
1
+ /** A run: glyphs of one font, size, direction and marked content on one baseline, in logical order. */
2
+ export class TextRun {
3
+ #page;
4
+ #run;
5
+ #range;
6
+ /** @internal */
7
+ constructor(page, run) {
8
+ this.#page = page;
9
+ this.#run = run;
10
+ this.#range = Object.freeze([run.glyphs[0], run.glyphs[1]]);
11
+ }
12
+ /** The run's text in logical order (document text). */
13
+ get text() {
14
+ return this.#run.text;
15
+ }
16
+ /** The font's `/BaseFont` (document text). */
17
+ get font() {
18
+ return this.#run.font;
19
+ }
20
+ /** Font size, the text matrix applied. */
21
+ get size() {
22
+ return this.#run.size;
23
+ }
24
+ /** Vertical writing. */
25
+ get vertical() {
26
+ return this.#run.vertical;
27
+ }
28
+ /** The marked-content ID the run is in, if any (structure tree links). */
29
+ get mcid() {
30
+ return this.#run.mcid;
31
+ }
32
+ /** The text comes from an `/ActualText` span. */
33
+ get actualText() {
34
+ return this.#run.actualText;
35
+ }
36
+ /** Drawn invisibly (`Tr` 3 or 7: an OCR layer, hidden text). */
37
+ get invisible() {
38
+ return this.#run.invisible;
39
+ }
40
+ /** The bounds of its glyph quads in page space: `{ x, y, width, height }`. */
41
+ get bounds() {
42
+ const [x, y, width, height] = this.#run.bounds;
43
+ return { x, y, width, height };
44
+ }
45
+ /** The `[start, end)` range of its glyphs in the page's glyph arrays ({@link PageText.buffers}). */
46
+ get glyphRange() {
47
+ return this.#range;
48
+ }
49
+ /** Its glyphs, with their quads (built on each call). */
50
+ glyphs() {
51
+ const [start, end] = this.#run.glyphs;
52
+ const out = [];
53
+ for (let i = start; i < end; i++)
54
+ out.push(this.#page.glyph(i));
55
+ return out;
56
+ }
57
+ }
58
+ /** @internal The raw arrays of a PageText (the worker client sends them, L2a). */
59
+ export let rawOf;
60
+ /** A page's extracted text: lines in reading order, and runs with their glyphs' quads. */
61
+ export class PageText {
62
+ #raw;
63
+ #runs;
64
+ static {
65
+ rawOf = (text) => text.#raw;
66
+ }
67
+ #lines;
68
+ /** @internal */
69
+ constructor(raw) {
70
+ this.#raw = raw;
71
+ this.#lines = Object.freeze([...raw.lines]);
72
+ // Kept from the start: transferring the buffers detaches glyphOffsets.
73
+ this.glyphCount = Math.max(0, raw.glyphOffsets.length - 1);
74
+ }
75
+ /** The text by line (runs on one baseline joined, trimmed), in content order. */
76
+ get lines() {
77
+ return this.#lines;
78
+ }
79
+ /** The page's text: its lines joined with `\n`. */
80
+ text() {
81
+ return this.#lines.join("\n");
82
+ }
83
+ /** The runs, in content order (made on first use). */
84
+ get runs() {
85
+ this.#runs ??= this.#raw.runs.map((r) => new TextRun(this, r));
86
+ return this.#runs;
87
+ }
88
+ /** Glyphs whose Unicode is unknown (shown as U+FFFD). */
89
+ get unmapped() {
90
+ return this.#raw.unmapped;
91
+ }
92
+ /** The number of glyphs. */
93
+ glyphCount;
94
+ /**
95
+ * Glyph `i`'s text and quad.
96
+ *
97
+ * @throws `RangeError` for an index outside `0 … glyphCount - 1`; `TypeError` once
98
+ * {@link PageText.buffers}' arrays were transferred to another thread.
99
+ */
100
+ glyph(i) {
101
+ if (!Number.isInteger(i) || i < 0 || i >= this.glyphCount) {
102
+ throw new RangeError(`glyph index ${i} is outside 0..${this.glyphCount - 1}`);
103
+ }
104
+ const q = this.#raw.quads;
105
+ if (q.length < (i + 1) * 8 || this.#raw.glyphOffsets.length <= i + 1) {
106
+ throw new TypeError("the glyph arrays were transferred (buffers): this PageText no longer holds them");
107
+ }
108
+ const o = i * 8;
109
+ const point = (k) => ({ x: q[o + 2 * k] ?? 0, y: q[o + 2 * k + 1] ?? 0 });
110
+ return {
111
+ text: this.#raw.glyphText.slice(this.#raw.glyphOffsets[i] ?? 0, this.#raw.glyphOffsets[i + 1] ?? 0),
112
+ quad: [point(0), point(1), point(2), point(3)],
113
+ };
114
+ }
115
+ /**
116
+ * The arrays as the WASM returned them: `quads` (8 numbers per glyph), `glyphText` and
117
+ * `glyphOffsets` (glyph i is `glyphText.slice(glyphOffsets[i], glyphOffsets[i + 1])`). Post
118
+ * `quads.buffer` and `glyphOffsets.buffer` as transferables to move them to another thread;
119
+ * that detaches them here, and this PageText's `glyph()` and `glyphs()` then throw (`lines`
120
+ * and `runs` keep working). They are this PageText's own arrays, not copies: writing to them
121
+ * changes what `glyph()` returns.
122
+ */
123
+ get buffers() {
124
+ return { quads: this.#raw.quads, glyphText: this.#raw.glyphText, glyphOffsets: this.#raw.glyphOffsets };
125
+ }
126
+ }
127
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import type { DocumentInfo, Op } from "./types.js";
2
+ /** The rotations `/Rotate` allows. */
3
+ export type Rotation = 0 | 90 | 180 | 270;
4
+ /** An Info patch: a string sets the entry, `null` removes it, a missing key leaves it alone. */
5
+ export type InfoPatch = {
6
+ readonly [K in keyof DocumentInfo]?: string | null;
7
+ };
8
+ /** Collects the ops of one {@link Document.transact} call. */
9
+ export declare class Transaction {
10
+ #private;
11
+ /** The ops collected so far. */
12
+ get ops(): readonly Op[];
13
+ /** @internal Ends the transaction: the handle takes no more ops. */
14
+ close(): void;
15
+ /**
16
+ * Adds `op` to the transaction.
17
+ *
18
+ * @throws {@link LaminaPdfError} `no-transaction` after `transact` returned.
19
+ */
20
+ apply(op: Op): this;
21
+ /**
22
+ * Patches the Info dictionary (`setInfo`).
23
+ *
24
+ * @param patch - the entries to set (a string) or remove (`null`).
25
+ * @param at - the modification date to write (`D:20261030120000Z`); omitted, none is written.
26
+ */
27
+ setInfo(patch: InfoPatch, at?: string): this;
28
+ /**
29
+ * Sets a page's `/Rotate` (`rotatePage`).
30
+ *
31
+ * @param page - the page's ID (`doc.page(0).id`).
32
+ * @param rotate - 0, 90, 180 or 270 degrees.
33
+ */
34
+ rotatePage(page: string, rotate: Rotation): this;
35
+ }
36
+ //# sourceMappingURL=transaction.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAEnD,sCAAsC;AACtC,MAAM,MAAM,QAAQ,GAAG,CAAC,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;AAE1C,gGAAgG;AAChG,MAAM,MAAM,SAAS,GAAG;IAAE,QAAQ,EAAE,CAAC,IAAI,MAAM,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;CAAE,CAAC;AAE/E,8DAA8D;AAC9D,qBAAa,WAAW;;IAItB,gCAAgC;IAChC,IAAI,GAAG,IAAI,SAAS,EAAE,EAAE,CAEvB;IAED,oEAAoE;IACpE,KAAK,IAAI,IAAI,CAEZ;IAED;;;;OAIG;IACH,KAAK,CAAC,EAAE,EAAE,EAAE,GAAG,IAAI,CAMlB;IAED;;;;;OAKG;IACH,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAE3C;IAED;;;;;OAKG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,IAAI,CAE/C;CACF"}
@@ -0,0 +1,47 @@
1
+ // The handle `Document.transact` passes to its callback (ADR 0006 §2): a closure can't cross the
2
+ // WASM boundary, so the handle collects ops and the document applies them as one transaction.
3
+ import { packageError } from "./errors.js";
4
+ /** Collects the ops of one {@link Document.transact} call. */
5
+ export class Transaction {
6
+ #ops = [];
7
+ #open = true;
8
+ /** The ops collected so far. */
9
+ get ops() {
10
+ return this.#ops;
11
+ }
12
+ /** @internal Ends the transaction: the handle takes no more ops. */
13
+ close() {
14
+ this.#open = false;
15
+ }
16
+ /**
17
+ * Adds `op` to the transaction.
18
+ *
19
+ * @throws {@link LaminaPdfError} `no-transaction` after `transact` returned.
20
+ */
21
+ apply(op) {
22
+ if (!this.#open) {
23
+ throw packageError("no-transaction", "the transaction has ended");
24
+ }
25
+ this.#ops.push(op);
26
+ return this;
27
+ }
28
+ /**
29
+ * Patches the Info dictionary (`setInfo`).
30
+ *
31
+ * @param patch - the entries to set (a string) or remove (`null`).
32
+ * @param at - the modification date to write (`D:20261030120000Z`); omitted, none is written.
33
+ */
34
+ setInfo(patch, at) {
35
+ return this.apply({ op: "setInfo", args: at === undefined ? { patch } : { patch, at } });
36
+ }
37
+ /**
38
+ * Sets a page's `/Rotate` (`rotatePage`).
39
+ *
40
+ * @param page - the page's ID (`doc.page(0).id`).
41
+ * @param rotate - 0, 90, 180 or 270 degrees.
42
+ */
43
+ rotatePage(page, rotate) {
44
+ return this.apply({ op: "rotatePage", args: { page, rotate } });
45
+ }
46
+ }
47
+ //# sourceMappingURL=transaction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transaction.js","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,8FAA8F;AAC9F,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAS3C,8DAA8D;AAC9D,MAAM,OAAO,WAAW;IACb,IAAI,GAAS,EAAE,CAAC;IACzB,KAAK,GAAG,IAAI,CAAC;IAEb,gCAAgC;IAChC,IAAI,GAAG;QACL,OAAO,IAAI,CAAC,IAAI,CAAC;IACnB,CAAC;IAED,oEAAoE;IACpE,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,EAAM;QACV,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;YAChB,MAAM,YAAY,CAAC,gBAAgB,EAAE,2BAA2B,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACnB,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,KAAgB,EAAE,EAAW;QACnC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,EAAQ,CAAC,CAAC;IACjG,CAAC;IAED;;;;;OAKG;IACH,UAAU,CAAC,IAAY,EAAE,MAAgB;QACvC,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,EAAQ,CAAC,CAAC;IACxE,CAAC;CACF"}
@@ -0,0 +1,79 @@
1
+ import type { AfRelationshipInit, AlignInit, AttachmentInit, BuildOptionsInit, DirectionInit, DocumentInfoJs, EditedJs, FitInit, LimitsInit, LineBoxJs, LinkTargetInit, MetadataInit, Op as OpJs, OutlineEntryInit, OverflowInit, PageInfoJs, PageLabelInit, ProfileInit, ProgressJs, RectJs, RenderModeInit, SaveOptionsInit, SaveReportJs, TextLayoutJs, TextRunJs, UndoOutcomeJs, ViewerPreferencesInit } from "@laminapdf/wasm/text";
2
+ /** An edit (ADR 0006 §6: `{ op: "setInfo" | "rotatePage", args }`), as in `fixtures/ops/v1`. */
3
+ export type Op = OpJs;
4
+ /** An op log: `{ v: 1, ops }`. */
5
+ export interface OpLog {
6
+ readonly v: 1;
7
+ readonly ops: readonly Op[];
8
+ }
9
+ /** `Limits` (ADR 0003 §3); each one left out keeps its default. */
10
+ export type Limits = LimitsInit;
11
+ /** Options for {@link Document.open}. */
12
+ export interface OpenOptions {
13
+ /** The user or owner password of an encrypted document (normalised to NFKC, ADR 0016 §7). */
14
+ readonly password?: string;
15
+ /** Refuse files that need repair (`strict`). */
16
+ readonly strict?: boolean;
17
+ /** Resource limits. */
18
+ readonly limits?: Limits;
19
+ }
20
+ /** Options for saving. */
21
+ export type SaveOptions = SaveOptionsInit;
22
+ /** What a save wrote. */
23
+ export type SaveReport = SaveReportJs;
24
+ /** A page's facts: index, ID, displayed size in points, rotation, label. */
25
+ export type PageInfo = PageInfoJs;
26
+ /** The Info dictionary's text entries (document text). */
27
+ export type DocumentInfo = DocumentInfoJs;
28
+ /** The pages an edit touched. */
29
+ export type Edited = EditedJs;
30
+ /** How an undo or redo went. */
31
+ export type UndoOutcome = UndoOutcomeJs;
32
+ /** A save job's progress. */
33
+ export type Progress = ProgressJs;
34
+ /** Options for a new document: version, fixed file ID (32 hex digits), producer, creation date. */
35
+ export type BuildOptions = BuildOptionsInit;
36
+ /** A conformance profile: `PDF/UA-1` (accessible), `PDF/A-2b`, `PDF/A-2u` or `PDF/A-3b` (archival). */
37
+ export type Profile = ProfileInit;
38
+ /** How an attached file relates to the document (`/AFRelationship`). */
39
+ export type AfRelationship = AfRelationshipInit;
40
+ /** An attached file's relationship, description and modification date. */
41
+ export type AttachmentOptions = AttachmentInit;
42
+ /** Where a link or outline item goes. */
43
+ export type LinkTarget = LinkTargetInit;
44
+ /** How a destination shows its page. */
45
+ export type Fit = FitInit;
46
+ /** An outline (bookmarks) item with its children. */
47
+ export type OutlineEntry = OutlineEntryInit;
48
+ /** A page-label range, by its first page. */
49
+ export type PageLabel = PageLabelInit;
50
+ /** The document's metadata (Info and XMP). */
51
+ export type Metadata = MetadataInit;
52
+ /** How viewers present the document. */
53
+ export type ViewerPreferences = ViewerPreferencesInit;
54
+ /** A rectangle returned by the builder (page space). */
55
+ export type BoxRect = RectJs;
56
+ /** What a text run measures. */
57
+ export type TextRunInfo = TextRunJs;
58
+ /** How a text box laid its text out. */
59
+ export type TextLayout = TextLayoutJs;
60
+ /** A line of a text box. */
61
+ export type LineBox = LineBoxJs;
62
+ /** Text alignment in a text box. */
63
+ export type Align = AlignInit;
64
+ /** Paragraph direction. */
65
+ export type Direction = DirectionInit;
66
+ /** What happens to text that doesn't fit a text box. */
67
+ export type Overflow = OverflowInit;
68
+ /** Text rendering mode. */
69
+ export type RenderMode = RenderModeInit;
70
+ /**
71
+ * A colour: `[gray]`, `[r, g, b]` or `[c, m, y, k]` with components from 0 to 1, or `"#rrggbb"`
72
+ * / `"#rgb"` (DeviceRGB).
73
+ */
74
+ export type Color = string | readonly [number] | readonly [number, number, number] | readonly [number, number, number, number];
75
+ /** A point in page space (points from the top-left of the displayed page, y down; ADR 0027). */
76
+ export type Point = readonly [x: number, y: number];
77
+ /** A rectangle in page space: left, top, width, height. */
78
+ export type Rect = readonly [x: number, y: number, width: number, height: number];
79
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,3 @@
1
+ /** `@laminapdf/sdk`'s version. */
2
+ export declare const VERSION = "0.2.0-alpha.2";
3
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAIA,kCAAkC;AAClC,eAAO,MAAM,OAAO,kBAAkB,CAAC"}
@@ -0,0 +1,6 @@
1
+ // The package version the worker handshake compares (L2a): the client and the worker it starts
2
+ // must be one build. `cargo xtask version sync` writes it from package.json (ADR 0017), and
3
+ // test/version.test.ts checks the two agree.
4
+ /** `@laminapdf/sdk`'s version. */
5
+ export const VERSION = "0.2.0-alpha.2";
6
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,4FAA4F;AAC5F,6CAA6C;AAE7C,kCAAkC;AAClC,MAAM,CAAC,MAAM,OAAO,GAAG,eAAe,CAAC"}