@embedpdf/engine-core 3.0.0-next.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.
- package/LICENSE +192 -0
- package/README.md +24 -0
- package/dist/AbortError-ByBflvEl.cjs +38 -0
- package/dist/AbortError-ByBflvEl.cjs.map +1 -0
- package/dist/AbortError-CjSasIlL.js +27 -0
- package/dist/AbortError-CjSasIlL.js.map +1 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE.d.cts +5043 -0
- package/dist/AnnotationListSnapshot-W0RCsyDE.d.ts +5043 -0
- package/dist/DocumentSecurityService-B-tULKNY.d.ts +332 -0
- package/dist/DocumentSecurityService-Df79fgpe.d.cts +332 -0
- package/dist/Engine-B7Oe7f5i.d.ts +1013 -0
- package/dist/Engine-D9loFZc1.d.cts +1013 -0
- package/dist/builders-BvikWRuO.cjs +1684 -0
- package/dist/builders-BvikWRuO.cjs.map +1 -0
- package/dist/builders-C548U47M.js +1367 -0
- package/dist/builders-C548U47M.js.map +1 -0
- package/dist/conformance.cjs +5414 -0
- package/dist/conformance.cjs.map +1 -0
- package/dist/conformance.d.cts +530 -0
- package/dist/conformance.d.ts +530 -0
- package/dist/conformance.js +5394 -0
- package/dist/conformance.js.map +1 -0
- package/dist/fold-CB4fAOOy.js +175 -0
- package/dist/fold-CB4fAOOy.js.map +1 -0
- package/dist/fold-IaMph3CO.cjs +216 -0
- package/dist/fold-IaMph3CO.cjs.map +1 -0
- package/dist/index.cjs +82 -0
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/resolver-DAZWVoJL.cjs +434 -0
- package/dist/resolver-DAZWVoJL.cjs.map +1 -0
- package/dist/resolver-DiPMTfcy.js +363 -0
- package/dist/resolver-DiPMTfcy.js.map +1 -0
- package/dist/runtime.cjs +453 -0
- package/dist/runtime.cjs.map +1 -0
- package/dist/runtime.d.cts +1002 -0
- package/dist/runtime.d.ts +1002 -0
- package/dist/runtime.js +361 -0
- package/dist/runtime.js.map +1 -0
- package/dist/schemas-9OpSSeM6.js +2493 -0
- package/dist/schemas-9OpSSeM6.js.map +1 -0
- package/dist/schemas-B_1VyFsm.cjs +3608 -0
- package/dist/schemas-B_1VyFsm.cjs.map +1 -0
- package/dist/subtype-BvAzLCGC.js +196 -0
- package/dist/subtype-BvAzLCGC.js.map +1 -0
- package/dist/subtype-qejjVr6h.cjs +231 -0
- package/dist/subtype-qejjVr6h.cjs.map +1 -0
- package/dist/wire.cjs +1516 -0
- package/dist/wire.cjs.map +1 -0
- package/dist/wire.d.cts +1546 -0
- package/dist/wire.d.ts +1546 -0
- package/dist/wire.js +1280 -0
- package/dist/wire.js.map +1 -0
- package/package.json +74 -0
|
@@ -0,0 +1,530 @@
|
|
|
1
|
+
import { An as HighlightDraft, Cc as InkList, Ec as PdfPoint, Oc as PdfRect, Tc as LinePoints, Vc as DocumentMetadata, n as AnnotationListSnapshotAllPages, t as AnnotationListPageSnapshot } from "./AnnotationListSnapshot-W0RCsyDE.js";
|
|
2
|
+
import { t as Engine } from "./Engine-B7Oe7f5i.js";
|
|
3
|
+
//#region src/conformance/runMetadataConformance.d.ts
|
|
4
|
+
interface ConformanceTestRunner {
|
|
5
|
+
describe(name: string, fn: () => void): void;
|
|
6
|
+
test(name: string, fn: () => void | Promise<void>): void;
|
|
7
|
+
beforeAll(fn: () => void | Promise<void>): void;
|
|
8
|
+
afterAll(fn: () => void | Promise<void>): void;
|
|
9
|
+
expect: ConformanceExpect;
|
|
10
|
+
}
|
|
11
|
+
interface ConformanceExpect {
|
|
12
|
+
(actual: unknown): {
|
|
13
|
+
toBe(expected: unknown): void;
|
|
14
|
+
toBeNull(): void;
|
|
15
|
+
toEqual(expected: unknown): void;
|
|
16
|
+
toHaveLength(expected: number): void;
|
|
17
|
+
toMatch(re: RegExp): void;
|
|
18
|
+
toMatchObject(shape: Record<string, unknown>): void;
|
|
19
|
+
toBeInstanceOf(ctor: Function): void;
|
|
20
|
+
toBeTruthy(): void;
|
|
21
|
+
rejects: {
|
|
22
|
+
toBeInstanceOf(ctor: Function): Promise<void>;
|
|
23
|
+
toMatchObject(shape: Record<string, unknown>): Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
resolves: {
|
|
26
|
+
toMatchObject(shape: Record<string, unknown>): Promise<void>;
|
|
27
|
+
toEqual(expected: unknown): Promise<void>;
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
interface ConformanceFixture {
|
|
32
|
+
/** Stable id used for the local engine; cloud uses its own id. */
|
|
33
|
+
id: string;
|
|
34
|
+
/** Bytes for the local engine. */
|
|
35
|
+
bytes: () => Uint8Array | Promise<Uint8Array>;
|
|
36
|
+
/** Override the cloud-side id. Defaults to `id`. */
|
|
37
|
+
cloudId?: string;
|
|
38
|
+
/** The expected document metadata. Used for parity assertions. */
|
|
39
|
+
expected: Partial<DocumentMetadata>;
|
|
40
|
+
}
|
|
41
|
+
interface ConformanceOptions {
|
|
42
|
+
label: string;
|
|
43
|
+
/** Build a fresh engine for this suite. Suite tears it down at the end. */
|
|
44
|
+
makeEngine: () => Promise<Engine> | Engine;
|
|
45
|
+
/** Sample fixture for the happy-path metadata read. */
|
|
46
|
+
fixture: ConformanceFixture;
|
|
47
|
+
/** Engine 'kind' for opening: 'bytes' for local, 'id' for cloud. */
|
|
48
|
+
openKind: 'bytes' | 'id';
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The conformance harness is transport-agnostic. It takes the test runner as
|
|
52
|
+
* a parameter so engine-core has no dependency on vitest/jest/node:test.
|
|
53
|
+
*/
|
|
54
|
+
declare function runMetadataConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/conformance/runAnnotationReadConformance.d.ts
|
|
57
|
+
/**
|
|
58
|
+
* Expected per-fixture annotation knowledge. The harness asserts against
|
|
59
|
+
* these without locking the exact wire content, so different fixtures can
|
|
60
|
+
* be added by suites without rewriting the harness.
|
|
61
|
+
*/
|
|
62
|
+
interface AnnotationReadConformanceFixture extends ConformanceFixture {
|
|
63
|
+
/** PDF object number of the page used by the annotation tests. */
|
|
64
|
+
pageObjectNumber: number;
|
|
65
|
+
/** The total annotation count expected on that page (across all subtypes). */
|
|
66
|
+
expectedAnnotationCount: number;
|
|
67
|
+
/** At least this many `'highlight'` annotations on the page. */
|
|
68
|
+
minHighlightCount: number;
|
|
69
|
+
/** At least this many `'unsupported'` annotations on the page. */
|
|
70
|
+
minUnsupportedCount: number;
|
|
71
|
+
/** At least this many `'circle'` annotations on the page. Defaults to 0. */
|
|
72
|
+
minCircleCount?: number;
|
|
73
|
+
/** At least this many `'square'` annotations on the page. Defaults to 0. */
|
|
74
|
+
minSquareCount?: number;
|
|
75
|
+
/** At least this many `'polygon'` annotations on the page. Defaults to 0. */
|
|
76
|
+
minPolygonCount?: number;
|
|
77
|
+
/** At least this many `'polyline'` annotations on the page. Defaults to 0. */
|
|
78
|
+
minPolylineCount?: number;
|
|
79
|
+
/** At least this many `'line'` annotations on the page. Defaults to 0. */
|
|
80
|
+
minLineCount?: number;
|
|
81
|
+
/** At least this many `'ink'` annotations on the page. Defaults to 0. */
|
|
82
|
+
minInkCount?: number;
|
|
83
|
+
/** At least this many `'free-text'` annotations on the page. Defaults to 0. */
|
|
84
|
+
minFreeTextCount?: number;
|
|
85
|
+
/** At least this many `'caret'` annotations on the page. Defaults to 0. */
|
|
86
|
+
minCaretCount?: number;
|
|
87
|
+
/**
|
|
88
|
+
* `true` if the fixture has at least one weak annotation (no /NM, direct
|
|
89
|
+
* object). Drives the weak-ref + revision tests.
|
|
90
|
+
*/
|
|
91
|
+
expectsWeakAnnotation: boolean;
|
|
92
|
+
}
|
|
93
|
+
interface AnnotationConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
94
|
+
fixture: AnnotationReadConformanceFixture;
|
|
95
|
+
}
|
|
96
|
+
declare function runAnnotationReadConformance(runner: ConformanceTestRunner, opts: AnnotationConformanceOptions): void;
|
|
97
|
+
//#endregion
|
|
98
|
+
//#region src/conformance/runActionsConformance.d.ts
|
|
99
|
+
interface ActionsConformanceFixtures {
|
|
100
|
+
document: ConformanceFixture;
|
|
101
|
+
page: ConformanceFixture;
|
|
102
|
+
annotation: ConformanceFixture;
|
|
103
|
+
field: ConformanceFixture;
|
|
104
|
+
/** A page whose only annotation is a Link with a `/S /JavaScript` action.
|
|
105
|
+
* Optional: the javascript-link classification test skips without it. */
|
|
106
|
+
javascriptLink?: ConformanceFixture;
|
|
107
|
+
}
|
|
108
|
+
interface ActionsConformanceOptions {
|
|
109
|
+
label: string;
|
|
110
|
+
makeEngine: () => Promise<Engine> | Engine;
|
|
111
|
+
fixtures: ActionsConformanceFixtures;
|
|
112
|
+
openKind: 'bytes' | 'id';
|
|
113
|
+
}
|
|
114
|
+
/** Action extraction parity. These tests assert data only; no script executes. */
|
|
115
|
+
declare function runActionsConformance(runner: ConformanceTestRunner, opts: ActionsConformanceOptions): void;
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/conformance/runAnnotationMutationConformance.d.ts
|
|
118
|
+
/**
|
|
119
|
+
* Per-fixture knowledge the mutation harness needs. The shared fixture
|
|
120
|
+
* fields (id, bytes, etc.) come from `ConformanceFixture`; the bits below
|
|
121
|
+
* pin the test page. The harness asserts behaviour, not exact wire
|
|
122
|
+
* content, so the same fixture can run against both local (WASM) and
|
|
123
|
+
* cloud (native via @cloudpdf/server) engines.
|
|
124
|
+
*/
|
|
125
|
+
interface AnnotationMutationConformanceFixture extends ConformanceFixture {
|
|
126
|
+
/** PDF object number of the page used by the mutation tests. */
|
|
127
|
+
pageObjectNumber: number;
|
|
128
|
+
/** Page already has at least one weak annotation (no /NM, direct object). */
|
|
129
|
+
expectsWeakAnnotation: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* QuadPoints to use for the create() smoke test. Coordinates are in
|
|
132
|
+
* PDF user space; pick a small rectangle that fits anywhere on the
|
|
133
|
+
* fixture page so we don't flake on different page sizes.
|
|
134
|
+
*/
|
|
135
|
+
createQuad?: HighlightDraft['quadPoints'];
|
|
136
|
+
/**
|
|
137
|
+
* `/Rect` to use for the shape (circle/square) create tests. PDF user
|
|
138
|
+
* space; pick a small box that fits anywhere on the fixture page.
|
|
139
|
+
*/
|
|
140
|
+
createShapeRect?: PdfRect;
|
|
141
|
+
/**
|
|
142
|
+
* `/Vertices` to use for the polygon/polyline create tests. PDF user
|
|
143
|
+
* space; must fit inside `createShapeRect` (the rect the engine bakes
|
|
144
|
+
* the appearance into). Defaults to a small triangle.
|
|
145
|
+
*/
|
|
146
|
+
createVertices?: PdfPoint[];
|
|
147
|
+
/**
|
|
148
|
+
* `/L` endpoints to use for the line create test. PDF user space; must
|
|
149
|
+
* fit inside `createShapeRect`. Defaults to the rect's diagonal.
|
|
150
|
+
*/
|
|
151
|
+
createLinePoints?: LinePoints;
|
|
152
|
+
/**
|
|
153
|
+
* `/InkList` strokes to use for the ink create test. PDF user space; must
|
|
154
|
+
* fit inside `createShapeRect`. Defaults to a single short stroke.
|
|
155
|
+
*/
|
|
156
|
+
createInkList?: InkList;
|
|
157
|
+
}
|
|
158
|
+
interface AnnotationMutationConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
159
|
+
fixture: AnnotationMutationConformanceFixture;
|
|
160
|
+
/**
|
|
161
|
+
* `true` for engines that expose the raw RGBA appearance rasters
|
|
162
|
+
* (`renderAppearances`). When set, the shape-create test additionally
|
|
163
|
+
* asserts that creating a shape produces a baked `/AP` the appearance
|
|
164
|
+
* reader can rasterize. The cloud engine ships encoded images instead
|
|
165
|
+
* and leaves this `false`.
|
|
166
|
+
*/
|
|
167
|
+
supportsAppearanceRasters?: boolean;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Mutation conformance suite. Mirrors the read suite: tests are written
|
|
171
|
+
* once and run against any engine that satisfies the public API
|
|
172
|
+
* surface. Both local (worker host + WASM) and cloud (HTTP +
|
|
173
|
+
* @cloudpdf/server) implementations must pass identically.
|
|
174
|
+
*
|
|
175
|
+
* The locked rules being verified here:
|
|
176
|
+
* - `create` is append-only: PDFium drops the new annotation at
|
|
177
|
+
* `index = previousCount`, so no existing index shifts. Treated
|
|
178
|
+
* as non-invalidating — revisions do NOT bump and weak refs
|
|
179
|
+
* captured before the create remain valid.
|
|
180
|
+
* - `update` is non-structural; revisions do NOT bump.
|
|
181
|
+
* - Opportunistic /NM stamp upgrades a weak annotation's ref to
|
|
182
|
+
* `kind: 'nm'` on update; an already-durable annotation's /NM is
|
|
183
|
+
* NEVER touched.
|
|
184
|
+
* - `delete` and `move` are the only index-shifting ops. They bump
|
|
185
|
+
* the per-page revision and, on a page that had weak refs before
|
|
186
|
+
* the mutation, surface `shouldRefetch: 'weakRefsInvalidated'`.
|
|
187
|
+
* - Abort propagates as `AbortError` even before the worker
|
|
188
|
+
* responds.
|
|
189
|
+
*/
|
|
190
|
+
declare function runAnnotationMutationConformance(runner: ConformanceTestRunner, opts: AnnotationMutationConformanceOptions): void;
|
|
191
|
+
//#endregion
|
|
192
|
+
//#region src/conformance/runFormConformance.d.ts
|
|
193
|
+
/**
|
|
194
|
+
* The three fixtures the forms suite needs. Shapes (names, object numbers,
|
|
195
|
+
* values) match the pdf-runtime fork's test resources:
|
|
196
|
+
*
|
|
197
|
+
* - `toggleFields` — toggle_fields.pdf: text field `maxlen_text`
|
|
198
|
+
* (/MaxLen 5, value "abc"), radio `ntto_radio` (NoToggleToOff, /DV x,
|
|
199
|
+
* widgets x/y), radio `unison_radio` (RadiosInUnison), checkbox
|
|
200
|
+
* `opt_check` (/Opt "Alpha", on-state "On"), hierarchical text field
|
|
201
|
+
* `billing.name`.
|
|
202
|
+
* - `orphanWidgets` — orphan_widgets.pdf: `linked_text` in /AcroForm
|
|
203
|
+
* /Fields plus RECOVERED `orphan_check` and `orphan_radio`.
|
|
204
|
+
* - `choiceFields` — listbox_form.pdf: `Listbox_MultiSelect` (options
|
|
205
|
+
* Apple..), `Listbox_SingleSelect`.
|
|
206
|
+
*/
|
|
207
|
+
interface FormConformanceFixtures {
|
|
208
|
+
/** toggle_fields.pdf; `pageObjectNumber` = its single page (object 3). */
|
|
209
|
+
toggleFields: ConformanceFixture & {
|
|
210
|
+
pageObjectNumber: number;
|
|
211
|
+
};
|
|
212
|
+
orphanWidgets: ConformanceFixture;
|
|
213
|
+
choiceFields: ConformanceFixture;
|
|
214
|
+
/**
|
|
215
|
+
* A second, independent copy of `toggleFields` used as the XFDF import
|
|
216
|
+
* target. Required for `openKind: 'id'` (cloud) — id-opened documents are
|
|
217
|
+
* server-side state, so the suite cannot mint a copy by re-opening the
|
|
218
|
+
* same bytes under a suffixed id the way the bytes transport does.
|
|
219
|
+
*/
|
|
220
|
+
importTarget?: ConformanceFixture;
|
|
221
|
+
}
|
|
222
|
+
interface FormConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
223
|
+
fixtures: FormConformanceFixtures;
|
|
224
|
+
}
|
|
225
|
+
declare function runFormConformance(runner: ConformanceTestRunner, opts: FormConformanceOptions): void;
|
|
226
|
+
//#endregion
|
|
227
|
+
//#region src/conformance/runAnnotationAppearanceConformance.d.ts
|
|
228
|
+
/**
|
|
229
|
+
* Per-fixture knowledge for the annotation appearance conformance suite. The
|
|
230
|
+
* harness asserts thresholds (not exact wire content) so the same suite runs
|
|
231
|
+
* unchanged against the local and cloud engines and proves they emit the same
|
|
232
|
+
* set of appearances — including weak (index-only) annotations.
|
|
233
|
+
*/
|
|
234
|
+
interface AnnotationAppearanceConformanceFixture extends ConformanceFixture {
|
|
235
|
+
/** PDF object number of the page whose appearances are rendered. */
|
|
236
|
+
pageObjectNumber: number;
|
|
237
|
+
/** At least this many `/AP` appearances are expected on that page. */
|
|
238
|
+
minAppearanceCount: number;
|
|
239
|
+
/**
|
|
240
|
+
* `true` when the page has at least one weak (index-only) annotation that
|
|
241
|
+
* carries an appearance stream. The whole point of this suite: that weak
|
|
242
|
+
* appearance must still be emitted (it used to be dropped on the wire).
|
|
243
|
+
*/
|
|
244
|
+
expectsWeakAppearance: boolean;
|
|
245
|
+
}
|
|
246
|
+
interface AnnotationAppearanceConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
247
|
+
fixture: AnnotationAppearanceConformanceFixture;
|
|
248
|
+
/**
|
|
249
|
+
* `true` for engines that expose the raw RGBA rasters (`renderAppearances`).
|
|
250
|
+
* The local engine's encoder needs a browser Canvas, so under node it can
|
|
251
|
+
* only be exercised via the raw rasters; the cloud engine ships encoded
|
|
252
|
+
* images (`renderAppearanceImages`) and leaves this `false`.
|
|
253
|
+
*/
|
|
254
|
+
supportsRawRasters?: boolean;
|
|
255
|
+
}
|
|
256
|
+
declare function runAnnotationAppearanceConformance(runner: ConformanceTestRunner, opts: AnnotationAppearanceConformanceOptions): void;
|
|
257
|
+
//#endregion
|
|
258
|
+
//#region src/conformance/runPageReorderConformance.d.ts
|
|
259
|
+
/**
|
|
260
|
+
* Per-fixture knowledge for the page-reorder suite. The test pages must
|
|
261
|
+
* be addressable by indirect `pageObjectNumber` (every page in our
|
|
262
|
+
* fixtures is). The fixture is expected to have at least 3 pages so the
|
|
263
|
+
* harness can exercise reorder permutations meaningfully.
|
|
264
|
+
*/
|
|
265
|
+
interface PageReorderConformanceFixture extends ConformanceFixture {
|
|
266
|
+
/** Stable, durable PONs of (at least) three distinct pages. Order
|
|
267
|
+
* here is the *intended caller-visible* order, not the on-disk
|
|
268
|
+
* order; the suite reads `pages.list()` first and works in document
|
|
269
|
+
* order. */
|
|
270
|
+
ponsForReorderTest?: number[];
|
|
271
|
+
/**
|
|
272
|
+
* Page used for the weak-ref-survival assertion. Defaults to the
|
|
273
|
+
* first PON in `ponsForReorderTest`. The fixture page must already
|
|
274
|
+
* have at least one weak annotation (no /NM, direct object) so the
|
|
275
|
+
* harness can capture an `index`-kind ref before the page move and
|
|
276
|
+
* re-use it after.
|
|
277
|
+
*/
|
|
278
|
+
weakRefHostPon?: number;
|
|
279
|
+
/** Quad to use for the `create()` step that produces a stable ref
|
|
280
|
+
* the suite uses. */
|
|
281
|
+
createQuad?: HighlightDraft['quadPoints'];
|
|
282
|
+
}
|
|
283
|
+
interface PageReorderConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
284
|
+
fixture: PageReorderConformanceFixture;
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Page reorder conformance suite. Verifies the architectural invariants
|
|
288
|
+
* locked with the user, do NOT loosen these without re-reading
|
|
289
|
+
* `PageMoveResult` and `DocumentPagesMutator`:
|
|
290
|
+
*
|
|
291
|
+
* 1. `pages.list()` returns every page in display order, addressed
|
|
292
|
+
* by indirect `pageObjectNumber`.
|
|
293
|
+
* 2. `pages.move()` returns the full new order + geometry via
|
|
294
|
+
* `result.layout` (the same shape `pages.list()` returns). There is
|
|
295
|
+
* no document-level revision; the wire never asks the caller for one.
|
|
296
|
+
* 3. Index-based annotation refs survive a page reorder. This is the
|
|
297
|
+
* whole reason per-page revisions stay put across a move: a user
|
|
298
|
+
* shuffling pages mid-edit must not lose a pending highlight. (The
|
|
299
|
+
* "move never bumps a RevisionToken" invariant is asserted directly
|
|
300
|
+
* in the annotation mutation suite, where revision liveness lives.)
|
|
301
|
+
* 4. Invalid inputs (duplicate PONs, unknown PONs, out-of-range
|
|
302
|
+
* `destIndex`) reject with `InvalidArg`.
|
|
303
|
+
* 5. Abort propagates as `AbortError`.
|
|
304
|
+
*
|
|
305
|
+
* Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
|
|
306
|
+
* implementations must pass identically.
|
|
307
|
+
*/
|
|
308
|
+
declare function runPageReorderConformance(runner: ConformanceTestRunner, opts: PageReorderConformanceOptions): void;
|
|
309
|
+
//#endregion
|
|
310
|
+
//#region src/conformance/runPageRotateConformance.d.ts
|
|
311
|
+
/**
|
|
312
|
+
* Page rotate conformance suite. Verifies the architectural invariants —
|
|
313
|
+
* do NOT loosen these without re-reading `PageRotateResult`:
|
|
314
|
+
*
|
|
315
|
+
* 1. Rotation is ABSOLUTE and idempotent: `rotate(pons, 90)` twice is
|
|
316
|
+
* `rotate(pons, 90)` once. The wire never speaks "turn by".
|
|
317
|
+
* 2. Rotation is presentation metadata over NORMALIZED content: the
|
|
318
|
+
* layout's `width`/`height` stay un-rotated, order and identity are
|
|
319
|
+
* untouched, and per-page `RevisionToken`s survive (an index-based
|
|
320
|
+
* annotation ref captured before the rotate works after it).
|
|
321
|
+
* 3. The result returns the full new `layout`; a subsequent `list()`
|
|
322
|
+
* agrees with it.
|
|
323
|
+
* 4. Invalid inputs (bad rotation value, duplicate PONs, unknown PONs)
|
|
324
|
+
* reject with `InvalidArg` / `NotFound`.
|
|
325
|
+
* 5. Abort propagates as `AbortError`.
|
|
326
|
+
*
|
|
327
|
+
* Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
|
|
328
|
+
* implementations must pass identically.
|
|
329
|
+
*/
|
|
330
|
+
declare function runPageRotateConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
331
|
+
//#endregion
|
|
332
|
+
//#region src/conformance/runPageDeleteConformance.d.ts
|
|
333
|
+
/**
|
|
334
|
+
* Page delete conformance suite. Verifies the architectural invariants —
|
|
335
|
+
* do NOT loosen these without re-reading `PageDeleteResult`:
|
|
336
|
+
*
|
|
337
|
+
* 1. `pages.delete()` removes exactly the listed pages and returns the
|
|
338
|
+
* full surviving layout; a subsequent `list()` agrees.
|
|
339
|
+
* 2. Deleted PONs are RETIRED: addressing a deleted page afterwards is a
|
|
340
|
+
* clean `NotFound` (an API-level error, never native-memory danger).
|
|
341
|
+
* 3. SURVIVING pages keep identity and `RevisionToken`s — an index-based
|
|
342
|
+
* annotation ref on an unrelated page survives a neighbour's deletion.
|
|
343
|
+
* 4. Deleting every page is rejected (`InvalidArg`) — a document keeps at
|
|
344
|
+
* least one page.
|
|
345
|
+
* 5. Duplicate / unknown PONs reject with `InvalidArg` / `NotFound`;
|
|
346
|
+
* abort propagates as `AbortError`.
|
|
347
|
+
*
|
|
348
|
+
* Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
|
|
349
|
+
* implementations must pass identically.
|
|
350
|
+
*/
|
|
351
|
+
declare function runPageDeleteConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
352
|
+
//#endregion
|
|
353
|
+
//#region src/conformance/runPageFlattenConformance.d.ts
|
|
354
|
+
/** Transport-neutral coverage for the content + annotation flatten rail. */
|
|
355
|
+
declare function runPageFlattenConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/conformance/runRedactionApplyConformance.d.ts
|
|
358
|
+
/**
|
|
359
|
+
* Transport-neutral coverage for the destructive redaction-apply rail.
|
|
360
|
+
* Runs against a fixture page with NO pre-existing annotations so the
|
|
361
|
+
* collateral counts are exact. Content-removal fidelity itself is pinned by
|
|
362
|
+
* the native embeddertests; this suite pins the transport contract: scopes,
|
|
363
|
+
* statuses, counts, revision bumps, events, and preflight rejection.
|
|
364
|
+
*/
|
|
365
|
+
declare function runRedactionApplyConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
366
|
+
//#endregion
|
|
367
|
+
//#region src/conformance/runPageExtractConformance.d.ts
|
|
368
|
+
/**
|
|
369
|
+
* Page extract conformance suite. `pages.extract?` is OPTIONAL on the
|
|
370
|
+
* contract (the `downloadLayer?` pattern) — the suite runs only when the
|
|
371
|
+
* implementation provides it, so a cloud engine that has not shipped the
|
|
372
|
+
* server endpoint yet skips cleanly instead of failing.
|
|
373
|
+
*
|
|
374
|
+
* Invariants:
|
|
375
|
+
* 1. `pages.extract([pon])` returns standalone PDF bytes (magic header).
|
|
376
|
+
* 2. The SOURCE document is untouched: identical layout before/after,
|
|
377
|
+
* and page revisions do not bump (extract is a read).
|
|
378
|
+
* 3. Caller order is preserved and page geometry survives the copy
|
|
379
|
+
* (asserted by re-opening the extracted bytes — bytes-open engines
|
|
380
|
+
* only, since a cloud engine cannot re-open loose bytes).
|
|
381
|
+
* 4. Empty / duplicate PONs reject `InvalidArg`; unknown PONs reject
|
|
382
|
+
* `NotFound` (or `InvalidArg`); abort propagates as `AbortError`.
|
|
383
|
+
*/
|
|
384
|
+
declare function runPageExtractConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
385
|
+
//#endregion
|
|
386
|
+
//#region src/conformance/runAttachmentConformance.d.ts
|
|
387
|
+
/**
|
|
388
|
+
* Attachment conformance suite. Fixture requirement: a document whose
|
|
389
|
+
* `/EmbeddedFiles` name tree contains AT LEAST ONE embedded file.
|
|
390
|
+
*
|
|
391
|
+
* Both attachment surfaces are OPTIONAL on the contract (the
|
|
392
|
+
* `downloadLayer?` pattern), probed independently and skipped cleanly:
|
|
393
|
+
* - `doc.attachments?` — document-level EmbeddedFiles (list/download)
|
|
394
|
+
* - `page.annotations.downloadFile?` — annotation-level file bytes
|
|
395
|
+
*
|
|
396
|
+
* Invariants:
|
|
397
|
+
* 1. `list()` reflects the name tree: positional indices, non-empty
|
|
398
|
+
* names, and repeated calls agree (a read).
|
|
399
|
+
* 2. `download(index)` round-trips the listed metadata and returns
|
|
400
|
+
* exactly `size` decoded bytes when the fixture declares one.
|
|
401
|
+
* 3. Unknown indices reject with an `EngineError`.
|
|
402
|
+
* 4. A created file-attachment annotation round-trips its file:
|
|
403
|
+
* metadata inline on the DTO (never bytes), bytes byte-identical
|
|
404
|
+
* through `downloadFile(ref)`.
|
|
405
|
+
* 5. A created text (sticky-note) annotation round-trips icon + color.
|
|
406
|
+
*/
|
|
407
|
+
declare function runAttachmentConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
408
|
+
//#endregion
|
|
409
|
+
//#region src/conformance/runPageInsertConformance.d.ts
|
|
410
|
+
/**
|
|
411
|
+
* Page insert conformance. `pages.insert?` is optional only until the cloud
|
|
412
|
+
* endpoint ships (it is slated REQUIRED-parity — a cloud viewer must be able
|
|
413
|
+
* to add pages); the suite runs wherever the implementation exists.
|
|
414
|
+
*
|
|
415
|
+
* Invariants:
|
|
416
|
+
* 1. Every page of the source bytes is COPIED in at `destIndex` (omitted →
|
|
417
|
+
* append), in source order; the result lists the fresh PONs in
|
|
418
|
+
* insertion order and they agree with the returned layout.
|
|
419
|
+
* 2. Pre-existing pages keep their identity: same PONs before and after,
|
|
420
|
+
* in the expected positions (an insert never invalidates neighbours).
|
|
421
|
+
* 3. The mutation persists through save → re-open (bytes engines only).
|
|
422
|
+
* 4. Empty bytes / malformed bytes / out-of-range destIndex reject with
|
|
423
|
+
* InvalidArg / MalformedPdf, leaving the document untouched.
|
|
424
|
+
*/
|
|
425
|
+
declare function runPageInsertConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
426
|
+
//#endregion
|
|
427
|
+
//#region src/conformance/runPieceInfoConformance.d.ts
|
|
428
|
+
/**
|
|
429
|
+
* `/PieceInfo` conformance (doc + page level). The service is OPTIONAL on
|
|
430
|
+
* the contract (`downloadLayer?` pattern) — the suite runs only where the
|
|
431
|
+
* implementation provides it, so an engine that has not shipped it yet
|
|
432
|
+
* skips cleanly.
|
|
433
|
+
*
|
|
434
|
+
* Invariants:
|
|
435
|
+
* 1. The full value vocabulary round-trips at both levels: string,
|
|
436
|
+
* number, boolean, name, string-array — read back with the same tags.
|
|
437
|
+
* 2. Writes PERSIST: download() → re-open → identical read (bytes-open
|
|
438
|
+
* engines only, since cloud cannot re-open loose bytes).
|
|
439
|
+
* 3. `null` deletes a key; sibling keys and sibling applications
|
|
440
|
+
* survive both key deletes and whole-entry clears.
|
|
441
|
+
* 4. An absent application reads as `null`; `applications()` enumerates
|
|
442
|
+
* what is present; every write refreshes `lastModified`.
|
|
443
|
+
*/
|
|
444
|
+
declare function runPieceInfoConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
445
|
+
//#endregion
|
|
446
|
+
//#region src/conformance/runDocumentEventsConformance.d.ts
|
|
447
|
+
/**
|
|
448
|
+
* Document event stream conformance suite. Verifies the invariants the
|
|
449
|
+
* collaboration design rests on — do NOT loosen these without re-reading
|
|
450
|
+
* `DocumentEvent`:
|
|
451
|
+
*
|
|
452
|
+
* 1. EXACTLY ONCE: every confirmed mutation produces exactly one event,
|
|
453
|
+
* in mutation order, regardless of engine (local worker or cloud HTTP).
|
|
454
|
+
* 2. GROUND TRUTH: a failed mutation publishes nothing; events fire only
|
|
455
|
+
* after confirmation.
|
|
456
|
+
* 3. RESULTS RIDE VERBATIM: each event embeds the result the caller
|
|
457
|
+
* received, deep-equal field for field.
|
|
458
|
+
* 4. PROVENANCE: own mutations are `origin.kind: 'local'` with a stable
|
|
459
|
+
* per-engine-instance `sessionId`.
|
|
460
|
+
* 5. Unsubscribe stops delivery.
|
|
461
|
+
*
|
|
462
|
+
* Both local (worker host + WASM) and cloud (HTTP + @cloudpdf/server)
|
|
463
|
+
* implementations must pass identically.
|
|
464
|
+
*/
|
|
465
|
+
declare function runDocumentEventsConformance(runner: ConformanceTestRunner, opts: ConformanceOptions): void;
|
|
466
|
+
//#endregion
|
|
467
|
+
//#region src/conformance/runPageTextConformance.d.ts
|
|
468
|
+
/**
|
|
469
|
+
* Per-fixture expectations for the text-extraction harness. Concrete
|
|
470
|
+
* suites supply the page identity + a substring the harness asserts
|
|
471
|
+
* exists in the extracted text. The harness deliberately avoids
|
|
472
|
+
* locking the exact string so different fixtures (or PDFium upgrades
|
|
473
|
+
* that change whitespace handling) don't require harness edits.
|
|
474
|
+
*/
|
|
475
|
+
interface PageTextConformanceFixture extends ConformanceFixture {
|
|
476
|
+
/** PDF indirect object number of the page used by the text tests. */
|
|
477
|
+
pageObjectNumber: number;
|
|
478
|
+
/**
|
|
479
|
+
* Substring guaranteed to appear in the extracted text. The harness
|
|
480
|
+
* uses `.includes(needle)`; suites should pick something distinctive
|
|
481
|
+
* but not whitespace-sensitive.
|
|
482
|
+
*/
|
|
483
|
+
expectedSubstring: string;
|
|
484
|
+
/** Minimum char count the harness expects (sanity floor). */
|
|
485
|
+
minCharCount: number;
|
|
486
|
+
}
|
|
487
|
+
interface PageTextConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
488
|
+
fixture: PageTextConformanceFixture;
|
|
489
|
+
}
|
|
490
|
+
declare function runPageTextConformance(runner: ConformanceTestRunner, opts: PageTextConformanceOptions): void;
|
|
491
|
+
//#endregion
|
|
492
|
+
//#region src/conformance/runSearchConformance.d.ts
|
|
493
|
+
/**
|
|
494
|
+
* Per-fixture expectations for the search harness. Suites supply a
|
|
495
|
+
* literal known to be on a specific page, one known to be nowhere, and a
|
|
496
|
+
* regex with a predictable hit — the harness asserts behavior (offsets,
|
|
497
|
+
* rects, snippets, cursor mechanics, dialect rejection), never exact
|
|
498
|
+
* match counts, so PDFium text-extraction tweaks don't require edits.
|
|
499
|
+
*/
|
|
500
|
+
interface SearchConformanceFixture extends ConformanceFixture {
|
|
501
|
+
/** Literal present in the document at least once. */
|
|
502
|
+
presentLiteral: string;
|
|
503
|
+
/** A page (pon) guaranteed to carry a `presentLiteral` match. */
|
|
504
|
+
presentPageObjectNumber: number;
|
|
505
|
+
/** Literal guaranteed to match nowhere. */
|
|
506
|
+
absentLiteral: string;
|
|
507
|
+
/** Dialect-valid regex with at least one match in the document. */
|
|
508
|
+
presentRegex: string;
|
|
509
|
+
}
|
|
510
|
+
interface SearchConformanceOptions extends Omit<ConformanceOptions, 'fixture'> {
|
|
511
|
+
fixture: SearchConformanceFixture;
|
|
512
|
+
}
|
|
513
|
+
declare function runSearchConformance(runner: ConformanceTestRunner, opts: SearchConformanceOptions): void;
|
|
514
|
+
//#endregion
|
|
515
|
+
//#region src/conformance/diffAnnotationListSnapshot.d.ts
|
|
516
|
+
/**
|
|
517
|
+
* Returns a list of human-readable difference strings between two
|
|
518
|
+
* snapshots. Empty array means parity. Used by `engine-node.ts` to assert
|
|
519
|
+
* that local and cloud emit identical annotations for the same fixture.
|
|
520
|
+
*
|
|
521
|
+
* `RevisionToken.docSessionId` is intentionally NOT compared — sessions
|
|
522
|
+
* are disjoint. We do compare `pageObjectNumber` and `generation` (which
|
|
523
|
+
* should be 0 for fresh reads on both sides). Page order is no longer part
|
|
524
|
+
* of `PageState`; it lives in `PageLayout.index` (see `pages.list()`).
|
|
525
|
+
*/
|
|
526
|
+
declare function diffAnnotationListSnapshot(a: AnnotationListPageSnapshot, b: AnnotationListPageSnapshot): string[];
|
|
527
|
+
declare function diffAnnotationListSnapshotAll(a: AnnotationListSnapshotAllPages, b: AnnotationListSnapshotAllPages): string[];
|
|
528
|
+
//#endregion
|
|
529
|
+
export { type ActionsConformanceFixtures, type ActionsConformanceOptions, type AnnotationAppearanceConformanceFixture, type AnnotationAppearanceConformanceOptions, type AnnotationConformanceOptions, type AnnotationMutationConformanceFixture, type AnnotationMutationConformanceOptions, type AnnotationReadConformanceFixture, type ConformanceExpect, type ConformanceFixture, type ConformanceOptions, type ConformanceTestRunner, type FormConformanceFixtures, type FormConformanceOptions, type PageReorderConformanceFixture, type PageReorderConformanceOptions, type PageTextConformanceFixture, type PageTextConformanceOptions, type SearchConformanceFixture, type SearchConformanceOptions, diffAnnotationListSnapshot, diffAnnotationListSnapshotAll, runActionsConformance, runAnnotationAppearanceConformance, runAnnotationMutationConformance, runAnnotationReadConformance, runAttachmentConformance, runDocumentEventsConformance, runFormConformance, runMetadataConformance, runPageDeleteConformance, runPageExtractConformance, runPageFlattenConformance, runPageInsertConformance, runPageReorderConformance, runPageRotateConformance, runPageTextConformance, runPieceInfoConformance, runRedactionApplyConformance, runSearchConformance };
|
|
530
|
+
//# sourceMappingURL=conformance.d.ts.map
|