Skip to content

Document

An open PDF: read it, edit it with ops (atomic transactions with undo), save it.

await init();
const doc = Document.open(bytes);
doc.transact((tx) => tx.setInfo({ title: "Final" }));
const updated = doc.save({ mode: "incremental" });
doc.free();

get canExtractText(): boolean

Whether page(i).text() works on this document: it was opened or built while the extract or the text module was loaded. A document opened before the module loaded stays in the base module; save and reopen it to move it.

boolean


get hasUnsavedChanges(): boolean

Whether there are changes no save has written yet.

boolean


get info(): DocumentInfoJs

The Info dictionary’s text entries (document text).

LaminaError reading errors.

DocumentInfoJs


get pageCount(): number

The number of pages.

LaminaError reading errors.

number


get pages(): readonly PageInfoJs[]

Every page’s facts, in order (one page-tree walk).

LaminaError reading errors.

readonly PageInfoJs[]


get warnings(): readonly LaminaWarning[]

Every warning so far (build warnings first), each the ADR 0026 §1 object.

readonly LaminaWarning[]

[dispose](): void

Frees the document at the end of a using block.

void


apply(ops): EditedJs

Applies ops in order as one transaction: all of them, or none.

readonly OpJs[]

EditedJs

the pages the edit touched.

LaminaError unknown-option / invalid-argument for a value that isn’t an op; the first failing op’s error (unknown-page, …), with nothing applied.


applyLog(log): EditedJs

Applies an op log ({ v: 1, ops }, as JSON text or an object) as one transaction.

string | OpLog

EditedJs

LaminaError invalid-op-log, unsupported-version; as Document.apply.


ensure<T>(f, options?): Promise<T>

Runs a synchronous call on this document, fetching what it needs first: for a document from Document.openRange, a data-pending makes it fetch the ranges asked for and call f again. For other documents it just returns f().

T

() => T | Promise<T>

the call (it may run several times; keep it free of side effects). An async function works too: its data-pending rejections are caught the same way.

signal aborts this call’s fetches (the open’s signal applies to the open only).

AbortSignal

Promise<T>

what f returns.

const doc = await Document.openRange(httpRangeSource(url));
const pages = await doc.ensure(() => doc.pages);

what f throws, and as Document.openRange.


free(): void

Frees the document’s WASM memory now; without it, it is freed when garbage-collected. Calling it twice is harmless; using the document afterwards is not (L2b adds disposed).

void


page(index): PageRef

A handle on page index that follows the page by its ID.

number

PageRef

LaminaError page-index-out-of-range.


pageById(id): PageRef

A handle on the page with id (p12.0).

string

PageRef

LaminaError invalid-argument, unknown-page.


pageInfo(index): PageInfoJs

Page index’s facts.

number

PageInfoJs

LaminaError page-index-out-of-range.


rebase(bytes): void

Rebases onto bytes, the output of a save whose rebase failed (not-rebased).

Uint8Array

void

LaminaError no-pending-save; reading errors in bytes.


redo(): any

Redoes the newest undone transaction.

any

how it went, or undefined when there is nothing to redo.

LaminaError as Document.undo.


save(options?): Uint8Array

Saves and rebases onto the output (later edits and saves build on it).

any

mode (auto, incremental, fullRewrite), overrides, output form.

Uint8Array

the file’s bytes.

LaminaError would-invalidate-signatures, requires-rewrite, encrypted-base, …


saveJob(options?): SaveJob

A save as a job stepped by the caller (to keep a UI responsive).

any

SaveJob

LaminaError unknown-option / invalid-argument for bad options.


saveWithReport(options?): object

As Document.save, with the save’s report (mode used, bytes written, renumbering, …).

any

object

readonly bytes: Uint8Array

readonly report: SaveReportJs

LaminaError as Document.save.


transact<T>(edit): T

Runs edit with a transaction handle and applies what it collected as one transaction (ADR 0006 §2). When edit throws, nothing is applied and the error propagates. The ops are applied when edit returns: reads inside edit see the document before the transaction.

T

(tx) => T

collects ops on tx; synchronous only (a callback returning a promise is refused with invalid-argument and nothing is applied).

T

what edit returned.

LaminaError nested-transaction when called (or when apply, undo, redo, save… are called) inside a transact of the same document; invalid-argument for an async callback; as Document.apply.

doc.transact((tx) => {
tx.setInfo({ title: "Report" });
tx.rotatePage(doc.page(0).id, 90);
});

undo(): any

Undoes the newest transaction.

any

how it went, or undefined when there is nothing to undo.

LaminaError saved-not-rebased; reading errors.


static open(bytes, options?): Document

Opens a document from its bytes (the bytes are copied into the WASM memory).

The password is tried as given. When that fails with wrong-password and its NFKC form differs, the NFKC form is tried too: R5/R6 passwords are prepared with SASLprep, whose normalisation the WASM modules leave out (ADR 0016 §7), while R2–R4 passwords must reach the core unchanged.

ArrayBuffer | Uint8Array<ArrayBufferLike>

the PDF file.

OpenOptions

password, strict mode, limits.

Document

the document.

LaminaError not-pdf, password-required, wrong-password, limit-exceeded, strict, …; unknown-option / invalid-argument for bad options; not-initialized.


static openRange(source, options?): Promise<Document>

Opens a document whose bytes are fetched range by range (httpRangeSource, callbackSource): only what the open needs is fetched (the end of the file, the xref, the catalog). Calls on the document stay synchronous; one that needs bytes not fetched yet throws data-pending with ranges, so wrap later reads in Document.ensure.

RangeSource | Promise<RangeSource>

the file (or a promise of it, as httpRangeSource returns).

OpenOptions & RangeOptions = {}

open options (password, strict, limits) and fetch options.

Promise<Document>

the document, once open has everything it needs.

LaminaError as Document.open; data-pending when fetching made no progress or maxRounds ran out; source-budget-exceeded; the source’s own errors (fetch-failed, source-changed); the signal’s reason when aborted.