@laminapdf/wasm 0.2.0-alpha.6 → 0.2.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/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # `@laminapdf/wasm`
2
2
 
3
- Lamina PDF's WebAssembly modules and their [wasm-bindgen](https://github.com/wasm-bindgen/wasm-bindgen) glue. The package is private: use [`@laminapdf/sdk`](../sdk/README.md), which is built on it. This package is its raw layer.
3
+ Lamina PDF's WebAssembly modules and their [wasm-bindgen](https://github.com/wasm-bindgen/wasm-bindgen) glue. Use [`@laminapdf/sdk`](../sdk/README.md), which is built on it and gives the modules a typed API: create, read, edit and save PDFs and extract their text. This package is its raw layer.
4
4
 
5
5
  | Export | File | What it has |
6
6
  | --- | --- | --- |
@@ -14,11 +14,117 @@ export interface Diagnostic {
14
14
  }
15
15
 
16
16
 
17
+ /**
18
+ * A change a signature's restriction forbids.
19
+ */
20
+ export interface ViolationJs {
21
+ /**
22
+ * The kind of change.
23
+ */
24
+ class: ModificationClass;
25
+ /**
26
+ * `docMdp`, `fieldMdp`, `usageRights`, `signedBytes` or `signedWidget`.
27
+ */
28
+ restriction: string;
29
+ /**
30
+ * The certification's `/P` (1, 2 or 3), for a `docMdp` restriction.
31
+ */
32
+ permission?: number;
33
+ /**
34
+ * The signature that carries the restriction.
35
+ */
36
+ signature: SignatureJs;
37
+ /**
38
+ * The form field whose widget a page edit deletes or reshows (its ID), for a
39
+ * `signedWidget` restriction or a `fieldMdp` one that a page edit breaks.
40
+ */
41
+ field?: string;
42
+ }
43
+
44
+ /**
45
+ * A conformance claim the document's metadata no longer meets.
46
+ *
47
+ * Added in 0.2.0.
48
+ */
49
+ export type ConformanceWarning = { code: "pdfa-one-author"; authors: number } | { code: "pdfua-title-missing" } | { code: "pdfa-info-mismatch"; keys: MetadataKey[] };
50
+
17
51
  /**
18
52
  * A conformance profile.
19
53
  */
20
54
  export type ProfileInit = "PDF/UA-1" | "PDF/A-2b" | "PDF/A-2u" | "PDF/A-3b";
21
55
 
56
+ /**
57
+ * A document's metadata as one record, read from the Info dictionary and the XMP packet.
58
+ *
59
+ * When the two disagree, the values come from the XMP packet in a PDF 2.0 file (ISO 32000-2
60
+ * §14.3.3 deprecates the Info entries) or a file that claims PDF/A (whose packet is
61
+ * authoritative, ISO 19005-2 §6.6.2.3.1), and otherwise from the side whose modification date
62
+ * is newer, Info winning a tie. A field the winning side lacks is taken from the other.
63
+ * [`disagreements`](DocumentMetadata::disagreements) names the fields where the two differ, so
64
+ * a properties view can say so.
65
+ *
66
+ * Added in 0.2.0.
67
+ */
68
+ export interface DocumentMetadata {
69
+ /**
70
+ * The title.
71
+ */
72
+ title?: string;
73
+ /**
74
+ * The authors, in order (Info's `/Author` split at `;`).
75
+ */
76
+ authors: string[];
77
+ /**
78
+ * The subject.
79
+ */
80
+ subject?: string;
81
+ /**
82
+ * The keywords.
83
+ */
84
+ keywords?: string;
85
+ /**
86
+ * The application the content came from.
87
+ */
88
+ creator?: string;
89
+ /**
90
+ * The application that wrote the PDF.
91
+ */
92
+ producer?: string;
93
+ /**
94
+ * The creation date (a PDF date string on the wire).
95
+ */
96
+ created?: string;
97
+ /**
98
+ * The modification date.
99
+ */
100
+ modified?: string;
101
+ /**
102
+ * Which side the values come from.
103
+ */
104
+ source: MetadataSource;
105
+ /**
106
+ * The fields where Info and XMP hold different values.
107
+ */
108
+ disagreements: MetadataKey[];
109
+ /**
110
+ * What `/Metadata` holds.
111
+ */
112
+ packet: PacketStatus;
113
+ /**
114
+ * The PDF/A part and conformance the packet claims (`pdfaid:`), e.g. `"2B"`.
115
+ */
116
+ pdfa?: string;
117
+ /**
118
+ * The PDF/UA part the packet claims (`pdfuaid:part`).
119
+ */
120
+ pdfua?: number;
121
+ /**
122
+ * In a PDF 2.0 file, the Info entries besides the two dates: deprecated, kept as they
123
+ * were for older readers, and never written by an edit.
124
+ */
125
+ keptInfoKeys: MetadataKey[];
126
+ }
127
+
22
128
  /**
23
129
  * A job's progress (`laminapdf::Step::Progress`).
24
130
  */
@@ -52,17 +158,56 @@ export interface ProgressJs {
52
158
  * ```
53
159
  *
54
160
  * [ADR 0006]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0006-op-log-and-undo.md
161
+ *
162
+ * Added in 0.2.0.
55
163
  */
56
164
  export interface OpLog {
57
165
  v: 1;
58
166
  ops: Op[];
59
167
  }
60
168
 
169
+ /**
170
+ * A metadata field Lamina PDF keeps in step in the Info dictionary and the XMP packet: what
171
+ * [`RemoveMetadata`] removes and [`DocumentMetadata::disagreements`] names.
172
+ *
173
+ * | Key | Info | XMP |
174
+ * | --- | --- | --- |
175
+ * | `title` | `/Title` | `dc:title` |
176
+ * | `authors` | `/Author` (joined with `; `) | `dc:creator` |
177
+ * | `subject` | `/Subject` | `dc:description` |
178
+ * | `keywords` | `/Keywords` | `pdf:Keywords` |
179
+ * | `creator` | `/Creator` | `xmp:CreatorTool` |
180
+ * | `producer` | `/Producer` | `pdf:Producer` |
181
+ * | `created` | `/CreationDate` | `xmp:CreateDate` |
182
+ * | `modified` | `/ModDate` | `xmp:ModifyDate` |
183
+ *
184
+ * Added in 0.2.0.
185
+ */
186
+ export type MetadataKey = "title" | "authors" | "subject" | "keywords" | "creator" | "producer" | "created" | "modified";
187
+
61
188
  /**
62
189
  * A page-label numbering style.
63
190
  */
64
191
  export type LabelStyleInit = "decimal" | "upperRoman" | "lowerRoman" | "upperLetters" | "lowerLetters";
65
192
 
193
+ /**
194
+ * A signature the planner found.
195
+ */
196
+ export interface SignatureJs {
197
+ /**
198
+ * `approval`, `certification`, `docTimeStamp` or `usageRights`.
199
+ */
200
+ kind: string;
201
+ /**
202
+ * The signature field's ID, when a field holds it.
203
+ */
204
+ field?: string;
205
+ /**
206
+ * The 1-based revision the signature closes, when known.
207
+ */
208
+ revision?: number;
209
+ }
210
+
66
211
  /**
67
212
  * An attached file's options.
68
213
  */
@@ -101,8 +246,10 @@ export interface AttachmentInit {
101
246
  * ```
102
247
  *
103
248
  * [ADR 0006]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0006-op-log-and-undo.md
249
+ *
250
+ * Added in 0.2.0.
104
251
  */
105
- export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: RotatePage };
252
+ export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: RotatePage } | { op: "setMetadata"; args: SetMetadata } | { op: "removeMetadata"; args: RemoveMetadata };
106
253
 
107
254
  /**
108
255
  * Changes to the Info dictionary's text entries. For each field, `None` leaves the entry
@@ -111,6 +258,8 @@ export type Op = { op: "setInfo"; args: SetInfo } | { op: "rotatePage"; args: Ro
111
258
  *
112
259
  * On the wire an absent field is left alone and `null` clears: `{ "title": "Report",
113
260
  * "author": null }`.
261
+ *
262
+ * Added in 0.2.0.
114
263
  */
115
264
  export interface InfoPatch {
116
265
  /**
@@ -139,13 +288,75 @@ export interface InfoPatch {
139
288
  producer?: string | null;
140
289
  }
141
290
 
291
+ /**
292
+ * Changes to the document's metadata. For each field, `None` leaves it alone, `Some(None)`
293
+ * removes it and `Some(Some(value))` sets it, in Info and XMP alike.
294
+ *
295
+ * On the wire an absent field is left alone and `null` removes: `{ "title": "Report",
296
+ * "authors": ["Ada Lovelace", "Charles Babbage"], "keywords": null }`; dates are PDF date
297
+ * strings (`"D:20261110093000+01'00'"`).
298
+ *
299
+ * ```
300
+ * use laminapdf_ops::MetadataPatch;
301
+ *
302
+ * let patch = MetadataPatch::new().title(Some("Quarterly figures")).authors(&["Ada Lovelace", "Charles Babbage"]);
303
+ * assert_eq!(patch.authors, Some(Some(vec!["Ada Lovelace".to_owned(), "Charles Babbage".to_owned()])));
304
+ * assert_eq!(serde_json::to_string(&patch)?, r#"{"title":"Quarterly figures","authors":["Ada Lovelace","Charles Babbage"]}"#);
305
+ * # Ok::<(), serde_json::Error>(())
306
+ * ```
307
+ *
308
+ * Added in 0.2.0.
309
+ */
310
+ export interface MetadataPatch {
311
+ /**
312
+ * `/Title`, `dc:title`.
313
+ */
314
+ title?: string | null;
315
+ /**
316
+ * `/Author` (joined with `; `), `dc:creator` (in order). An empty list removes them.
317
+ */
318
+ authors?: string[] | null;
319
+ /**
320
+ * `/Subject`, `dc:description`.
321
+ */
322
+ subject?: string | null;
323
+ /**
324
+ * `/Keywords`, `pdf:Keywords`.
325
+ */
326
+ keywords?: string | null;
327
+ /**
328
+ * `/Creator`, `xmp:CreatorTool`: the application the content came from.
329
+ */
330
+ creator?: string | null;
331
+ /**
332
+ * `/Producer`, `pdf:Producer`: the application that wrote the PDF.
333
+ */
334
+ producer?: string | null;
335
+ /**
336
+ * `/CreationDate`, `xmp:CreateDate`.
337
+ */
338
+ created?: string | null;
339
+ /**
340
+ * `/ModDate`, `xmp:ModifyDate`.
341
+ */
342
+ modified?: string | null;
343
+ }
344
+
142
345
  /**
143
346
  * Edits the Info dictionary: applies `patch` and, when `at` is given, sets `/ModDate` to it.
347
+ *
348
+ * **Deprecated:** use [`SetMetadata`](crate::SetMetadata), which writes authors as a list and
349
+ * the dates, and edits files whose metadata is in XMP alone. `SetInfo` stays, with its v1 wire
350
+ * form (`setInfo`) and meaning, so op logs already written still apply (ADR 0006 §6). It now
351
+ * goes through the same writer, so a document's XMP packet, when it has one, changes with it.
352
+ * It adds a packet only to a PDF 2.0 file, where the fields other than the dates belong in XMP.
144
353
  * The date is part of the op, never read from a clock, so the same op gives the same bytes
145
354
  * everywhere (ADR 0006 §1).
146
355
  *
147
356
  * An Info dictionary written directly in the trailer, or missing, becomes a new indirect
148
357
  * object that the trailer's `/Info` points to (the first time the op changes something).
358
+ *
359
+ * Added in 0.2.0.
149
360
  */
150
361
  export interface SetInfo {
151
362
  /**
@@ -158,11 +369,106 @@ export interface SetInfo {
158
369
  at?: string;
159
370
  }
160
371
 
372
+ /**
373
+ * Edits the document's metadata: applies `patch` to the Info dictionary and the XMP packet
374
+ * together and, when `at` is given, records it as the modification date (`/ModDate`,
375
+ * `xmp:ModifyDate`) and as `xmp:MetadataDate`, unless the patch sets the modification date
376
+ * itself. The date is part of the op, never read from a clock (ADR 0006 §1).
377
+ *
378
+ * ```
379
+ * use laminapdf_ops::{MetadataPatch, Op, SetMetadata};
380
+ *
381
+ * let op = Op::from(SetMetadata::new(MetadataPatch::new().title(Some("Minutes")), Some("D:20261110093000Z".parse()?)));
382
+ * assert_eq!(
383
+ * serde_json::to_string(&op)?,
384
+ * r#"{"op":"setMetadata","args":{"patch":{"title":"Minutes"},"at":"D:20261110093000Z"}}"#
385
+ * );
386
+ * # Ok::<(), Box<dyn std::error::Error>>(())
387
+ * ```
388
+ *
389
+ * Added in 0.2.0.
390
+ */
391
+ export interface SetMetadata {
392
+ /**
393
+ * The fields to set or remove.
394
+ */
395
+ patch?: MetadataPatch;
396
+ /**
397
+ * The modification date the edit writes.
398
+ */
399
+ at?: string;
400
+ /**
401
+ * Replace an XMP packet that can't be read with a new one, losing whatever it held.
402
+ * Without it, such a packet makes the op fail with `malformed-xmp`, so nothing is lost
403
+ * without the user saying so.
404
+ */
405
+ replaceMalformed?: boolean;
406
+ }
407
+
161
408
  /**
162
409
  * How a destination shows its page (§12.3.2.2).
163
410
  */
164
411
  export type FitInit = { type: "page" } | { type: "width"; top?: number } | { type: "height"; left?: number } | { type: "xyz"; left?: number; top?: number; zoom?: number } | { type: "rect"; x: number; y: number; width: number; height: number } | { type: "bounds" };
165
412
 
413
+ /**
414
+ * How a save would go (`laminapdf::PlannedSave`).
415
+ */
416
+ export interface PlannedSaveJs {
417
+ /**
418
+ * The mode the save resolves to; absent when it would be refused.
419
+ */
420
+ mode?: SaveModeJs;
421
+ /**
422
+ * The code the save would be refused with.
423
+ */
424
+ refusal?: string;
425
+ /**
426
+ * `free`, `appendOnly`, `requiresRewrite` or `conflict`.
427
+ */
428
+ constraint: string;
429
+ /**
430
+ * Every signature, in the order found.
431
+ */
432
+ signatures: SignatureJs[];
433
+ /**
434
+ * The certification's `/P` (1, 2 or 3), when the document is certified.
435
+ */
436
+ docMdp?: number;
437
+ /**
438
+ * Why only a full rewrite is safe: `repairedBase`, `encryptedBase`, `noBase`,
439
+ * `opRequiresRewrite`.
440
+ */
441
+ rewriteReasons: string[];
442
+ /**
443
+ * The pending changes a signature's restriction forbids.
444
+ */
445
+ violations: ViolationJs[];
446
+ /**
447
+ * The signatures the save would invalidate (only with `invalidateSignatures`).
448
+ */
449
+ wouldInvalidate: SignatureJs[];
450
+ /**
451
+ * Whether the save writes an encrypted document as plaintext.
452
+ */
453
+ removesEncryption: boolean;
454
+ /**
455
+ * What the save does with the save-time metadata: `none`, `stamp` or `skipped`.
456
+ */
457
+ metadata: string;
458
+ /**
459
+ * Whether an edit to save rewrote the XMP packet whole.
460
+ */
461
+ packetRewritten: boolean;
462
+ /**
463
+ * The PDF/A and PDF/UA claims the edited metadata breaks (warnings that never block).
464
+ */
465
+ conformanceWarnings: Diagnostic[];
466
+ /**
467
+ * The document has no changes.
468
+ */
469
+ unchanged: boolean;
470
+ }
471
+
166
472
  /**
167
473
  * How a viewer lays pages out.
168
474
  */
@@ -370,6 +676,48 @@ export interface SaveOptionsInit {
370
676
  * The cross-reference form.
371
677
  */
372
678
  xref?: XrefJs;
679
+ /**
680
+ * When the save happens, as the app's clock reads it: a PDF date (`D:20261110093000Z`)
681
+ * or an ISO 8601 date-time. A save that writes changes stamps it as the modification and
682
+ * metadata dates and gives the XMP packet a new instance ID.
683
+ */
684
+ metadataDate?: string;
685
+ /**
686
+ * The XMP instance ID the save writes, a UUID (`uuid:` optional); without it, one is
687
+ * derived from the content.
688
+ */
689
+ instanceId?: string;
690
+ }
691
+
692
+ /**
693
+ * Removes metadata fields from the Info dictionary and the XMP packet; the packet's other
694
+ * properties stay (J.10).
695
+ *
696
+ * The values stay in the file's earlier revisions until a full rewrite: an incremental save
697
+ * appends the change and keeps the original bytes. When it removed anything, the op's result
698
+ * says so ([`Applied::still_in_earlier_revisions`](crate::Applied::still_in_earlier_revisions)),
699
+ * so the caller can offer a full rewrite (on a signed file, the override that removes the
700
+ * signatures).
701
+ *
702
+ * ```
703
+ * use laminapdf_ops::{MetadataKey, Op, RemoveMetadata};
704
+ *
705
+ * let op = Op::from(RemoveMetadata::new(vec![MetadataKey::Authors, MetadataKey::Creator]));
706
+ * assert_eq!(serde_json::to_string(&op)?, r#"{"op":"removeMetadata","args":{"keys":["authors","creator"]}}"#);
707
+ * # Ok::<(), serde_json::Error>(())
708
+ * ```
709
+ *
710
+ * Added in 0.2.0.
711
+ */
712
+ export interface RemoveMetadata {
713
+ /**
714
+ * The fields to remove.
715
+ */
716
+ keys: MetadataKey[];
717
+ /**
718
+ * As [`SetMetadata::replace_malformed`].
719
+ */
720
+ replaceMalformed?: boolean;
373
721
  }
374
722
 
375
723
  /**
@@ -384,6 +732,8 @@ export interface SaveOptionsInit {
384
732
  * On the wire: `{ "op": "rotatePage", "args": { "page": "p12.0", "rotate": 90 } }`.
385
733
  *
386
734
  * [ADR 0005]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0005-document-model.md
735
+ *
736
+ * Added in 0.2.0.
387
737
  */
388
738
  export interface RotatePage {
389
739
  /**
@@ -479,6 +829,8 @@ export interface MetadataInit {
479
829
  * permissions and the document's `SaveConstraint` ([ADR 0007]).
480
830
  *
481
831
  * [ADR 0007]: https://github.com/laudebugs/laminapdf/blob/main/docs/decisions/0007-save-planner.md
832
+ *
833
+ * Added in 0.2.0.
482
834
  */
483
835
  export type ModificationClass = "metadata" | "formFill" | "annotation" | "signature" | "pageStructure" | "content" | "document";
484
836
 
@@ -490,6 +842,15 @@ export interface EditedJs {
490
842
  * IDs of the pages whose content or attributes changed.
491
843
  */
492
844
  touchedPages: string[];
845
+ /**
846
+ * A metadata edit rewrote the XMP packet whole (UTF-16, or marked read-only).
847
+ */
848
+ packetRewritten: boolean;
849
+ /**
850
+ * A metadata edit removed values the file's earlier revisions still hold, which only a
851
+ * full rewrite drops.
852
+ */
853
+ stillInEarlierRevisions: boolean;
493
854
  /**
494
855
  * Whether the edit changed the document: one that only set values they already had leaves
495
856
  * no step to undo.
@@ -535,6 +896,24 @@ export interface SaveReportJs {
535
896
  * Whether encryption was removed.
536
897
  */
537
898
  encryptionRemoved: boolean;
899
+ /**
900
+ * Whether the save stamped the save-time metadata (`metadataDate`, `instanceId`).
901
+ */
902
+ metadataUpdated: boolean;
903
+ /**
904
+ * Whether the options asked for the stamp and the save left it out, because it would have
905
+ * broken a signature's restriction the saved changes keep.
906
+ */
907
+ metadataNotUpdated: boolean;
908
+ /**
909
+ * Whether an edit saved here rewrote the XMP packet whole.
910
+ */
911
+ packetRewritten: boolean;
912
+ /**
913
+ * Whether the save emptied the undo history (a full rewrite, or an incremental save that
914
+ * freed objects); for a copy, whether adopting it would.
915
+ */
916
+ historyCleared: boolean;
538
917
  }
539
918
 
540
919
  /**
@@ -556,11 +935,25 @@ export interface RevertedJs {
556
935
  touchedPages: string[];
557
936
  }
558
937
 
938
+ /**
939
+ * What the document's `/Metadata` holds.
940
+ *
941
+ * Added in 0.2.0.
942
+ */
943
+ export type PacketStatus = "absent" | "parsed" | "malformed";
944
+
559
945
  /**
560
946
  * Where a link or outline item goes.
561
947
  */
562
948
  export type LinkTargetInit = { type: "uri"; uri: string } | { type: "page"; index: number; fit?: FitInit } | { type: "named"; name: string };
563
949
 
950
+ /**
951
+ * Which side [`DocumentMetadata`]'s values come from.
952
+ *
953
+ * Added in 0.2.0.
954
+ */
955
+ export type MetadataSource = "info" | "xmp";
956
+
564
957
  /**
565
958
  * `Limits` with every field optional (ADR 0003 §3; names as in Rust, camelCase).
566
959
  */
@@ -715,6 +1108,15 @@ export class WasmDocument {
715
1108
  private constructor();
716
1109
  free(): void;
717
1110
  [Symbol.dispose](): void;
1111
+ /**
1112
+ * Makes `bytes`, the whole output of `saveCopy`, the document's saved file (it rebases onto
1113
+ * them), once they are written where the document lives; `historyCleared` is the copy's
1114
+ * report's.
1115
+ *
1116
+ * # Errors
1117
+ * `nested-transaction`, `saved-not-rebased`; `not-rebased` when `bytes` can't be read.
1118
+ */
1119
+ adoptCopy(bytes: Uint8Array, historyCleared: boolean): void;
718
1120
  /**
719
1121
  * Applies an op log (`{ "v": 1, "ops": [ … ] }`) as one transaction.
720
1122
  *
@@ -745,6 +1147,14 @@ export class WasmDocument {
745
1147
  * Whether the file is encrypted (it opened with its password, or the empty one).
746
1148
  */
747
1149
  isEncrypted(): boolean;
1150
+ /**
1151
+ * The document's metadata, read from Info and XMP together, with the fields where they
1152
+ * disagree.
1153
+ *
1154
+ * # Errors
1155
+ * Reading errors.
1156
+ */
1157
+ metadata(): DocumentMetadata;
748
1158
  /**
749
1159
  * Opens a document from its bytes.
750
1160
  *
@@ -797,6 +1207,13 @@ export class WasmDocument {
797
1207
  * `page-index-out-of-range`; reading errors.
798
1208
  */
799
1209
  page(index: number): WasmPage;
1210
+ /**
1211
+ * How a save with `options` would go, without saving.
1212
+ *
1213
+ * # Errors
1214
+ * `invalid-argument` / `unknown-option` for bad options; reading errors.
1215
+ */
1216
+ plan(options: SaveOptionsInit | undefined): PlannedSaveJs;
800
1217
  /**
801
1218
  * Rebases onto `bytes`, the output of a save whose rebase failed (`not-rebased`).
802
1219
  *
@@ -812,6 +1229,14 @@ export class WasmDocument {
812
1229
  * As [`WasmDocument::undo`].
813
1230
  */
814
1231
  redo(): RevertedJs | undefined;
1232
+ /**
1233
+ * Writes what `save` would and leaves the document as it was: not rebased, its changes
1234
+ * still unsaved, the save-time stamp in the copy only (Save a copy).
1235
+ *
1236
+ * # Errors
1237
+ * As `save`; the document is unchanged either way.
1238
+ */
1239
+ saveCopy(options: SaveOptionsInit | undefined): { bytes: Uint8Array<ArrayBuffer>; report: SaveReportJs };
815
1240
  /**
816
1241
  * A save as a job, stepped with a budget of work units (ADR 0028 §3, §4).
817
1242
  *
@@ -838,6 +1263,13 @@ export class WasmDocument {
838
1263
  * A cursor over the warnings so far (build warnings first), each as the §1 object.
839
1264
  */
840
1265
  warnings(): WasmWarningCursor;
1266
+ /**
1267
+ * The signature restrictions `op` would break if it were applied and saved.
1268
+ *
1269
+ * # Errors
1270
+ * `invalid-argument` for a value that isn't an op; reading errors.
1271
+ */
1272
+ wouldViolate(op: Op): ViolationJs[];
841
1273
  }
842
1274
 
843
1275
  /**
@@ -1205,11 +1637,13 @@ export interface InitOutput {
1205
1637
  readonly wasmbuilder_page: (a: number, b: number, c: number) => number;
1206
1638
  readonly wasmbuilder_pageLabels: (a: number, b: any) => [number, number];
1207
1639
  readonly wasmbuilder_viewerPreferences: (a: number, b: any) => [number, number];
1640
+ readonly wasmdocument_adoptCopy: (a: number, b: number, c: number, d: number) => [number, number];
1208
1641
  readonly wasmdocument_apply: (a: number, b: any) => [number, number, number];
1209
1642
  readonly wasmdocument_applyLog: (a: number, b: number, c: number) => [number, number, number];
1210
1643
  readonly wasmdocument_hasUnsavedChanges: (a: number) => number;
1211
1644
  readonly wasmdocument_info: (a: number) => [number, number, number];
1212
1645
  readonly wasmdocument_isEncrypted: (a: number) => number;
1646
+ readonly wasmdocument_metadata: (a: number) => [number, number, number];
1213
1647
  readonly wasmdocument_openBytes: (a: number, b: number, c: any) => [number, number, number];
1214
1648
  readonly wasmdocument_openSource: (a: number, b: any) => [number, number, number];
1215
1649
  readonly wasmdocument_page: (a: number, b: number) => [number, number, number];
@@ -1217,12 +1651,15 @@ export interface InitOutput {
1217
1651
  readonly wasmdocument_pageCount: (a: number) => [number, number, number];
1218
1652
  readonly wasmdocument_pageInfo: (a: number, b: number) => [number, number, number];
1219
1653
  readonly wasmdocument_pageInfos: (a: number) => [number, number, number];
1654
+ readonly wasmdocument_plan: (a: number, b: any) => [number, number, number];
1220
1655
  readonly wasmdocument_rebase: (a: number, b: number, c: number) => [number, number];
1221
1656
  readonly wasmdocument_redo: (a: number) => [number, number, number];
1222
1657
  readonly wasmdocument_save: (a: number, b: any) => [number, number, number];
1658
+ readonly wasmdocument_saveCopy: (a: number, b: any) => [number, number, number];
1223
1659
  readonly wasmdocument_saveJob: (a: number, b: any) => [number, number, number];
1224
1660
  readonly wasmdocument_undo: (a: number) => [number, number, number];
1225
1661
  readonly wasmdocument_warnings: (a: number) => number;
1662
+ readonly wasmdocument_wouldViolate: (a: number, b: any) => [number, number, number];
1226
1663
  readonly wasmimage_height: (a: number) => number;
1227
1664
  readonly wasmimage_jpeg: (a: number, b: number) => [number, number, number];
1228
1665
  readonly wasmimage_png: (a: number, b: number) => [number, number, number];