@laminapdf/viewer 0.2.0-alpha.5 → 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 +48 -6
- package/dist/client.d.ts +60 -4
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +219 -22
- package/dist/client.js.map +1 -1
- package/dist/edit/session.d.ts +113 -0
- package/dist/edit/session.d.ts.map +1 -0
- package/dist/edit/session.js +232 -0
- package/dist/edit/session.js.map +1 -0
- package/dist/edit-log.d.ts +37 -0
- package/dist/edit-log.d.ts.map +1 -0
- package/dist/edit-log.js +98 -0
- package/dist/edit-log.js.map +1 -0
- package/dist/find/controller.d.ts +6 -0
- package/dist/find/controller.d.ts.map +1 -1
- package/dist/find/controller.js +69 -2
- package/dist/find/controller.js.map +1 -1
- package/dist/history/history.d.ts +9 -0
- package/dist/history/history.d.ts.map +1 -1
- package/dist/history/history.js.map +1 -1
- package/dist/index.d.ts +9 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/layers/link-layer.d.ts +33 -0
- package/dist/layers/link-layer.d.ts.map +1 -1
- package/dist/layers/link-layer.js +251 -3
- package/dist/layers/link-layer.js.map +1 -1
- package/dist/layers/link-preview.d.ts +77 -0
- package/dist/layers/link-preview.d.ts.map +1 -0
- package/dist/layers/link-preview.js +202 -0
- package/dist/layers/link-preview.js.map +1 -0
- package/dist/layers/text-layer.d.ts +7 -3
- package/dist/layers/text-layer.d.ts.map +1 -1
- package/dist/layers/text-layer.js +3 -5
- package/dist/layers/text-layer.js.map +1 -1
- package/dist/layout/page-layout.d.ts +7 -0
- package/dist/layout/page-layout.d.ts.map +1 -1
- package/dist/layout/page-layout.js +15 -0
- package/dist/layout/page-layout.js.map +1 -1
- package/dist/protocol.d.ts +145 -1
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +17 -2
- package/dist/protocol.js.map +1 -1
- package/dist/thumbnails/strip.d.ts.map +1 -1
- package/dist/thumbnails/strip.js +34 -1
- package/dist/thumbnails/strip.js.map +1 -1
- package/dist/view/previews.d.ts +47 -0
- package/dist/view/previews.d.ts.map +1 -0
- package/dist/view/previews.js +97 -0
- package/dist/view/previews.js.map +1 -0
- package/dist/view/viewer.d.ts +85 -7
- package/dist/view/viewer.d.ts.map +1 -1
- package/dist/view/viewer.js +347 -12
- package/dist/view/viewer.js.map +1 -1
- package/dist/worker/document.d.ts +56 -5
- package/dist/worker/document.d.ts.map +1 -1
- package/dist/worker/document.js +73 -2
- package/dist/worker/document.js.map +1 -1
- package/dist/worker/edit.d.ts +60 -0
- package/dist/worker/edit.d.ts.map +1 -0
- package/dist/worker/edit.js +383 -0
- package/dist/worker/edit.js.map +1 -0
- package/dist/worker/find.d.ts +2 -2
- package/dist/worker/find.d.ts.map +1 -1
- package/dist/worker/find.js +3 -3
- package/dist/worker/find.js.map +1 -1
- package/dist/worker/fingerprint.d.ts +10 -0
- package/dist/worker/fingerprint.d.ts.map +1 -0
- package/dist/worker/fingerprint.js +42 -0
- package/dist/worker/fingerprint.js.map +1 -0
- package/dist/worker/methods.d.ts.map +1 -1
- package/dist/worker/methods.js +34 -0
- package/dist/worker/methods.js.map +1 -1
- package/dist/worker/navigation.d.ts +2 -2
- package/dist/worker/navigation.d.ts.map +1 -1
- package/dist/worker/navigation.js +3 -3
- package/dist/worker/navigation.js.map +1 -1
- package/dist/worker/recent-pages.d.ts +2 -0
- package/dist/worker/recent-pages.d.ts.map +1 -1
- package/dist/worker/recent-pages.js +15 -0
- package/dist/worker/recent-pages.js.map +1 -1
- package/dist/worker/session.d.ts +61 -0
- package/dist/worker/session.d.ts.map +1 -0
- package/dist/worker/session.js +159 -0
- package/dist/worker/session.js.map +1 -0
- package/dist/worker/text.d.ts +2 -2
- package/dist/worker/text.d.ts.map +1 -1
- package/dist/worker/text.js +5 -4
- package/dist/worker/text.js.map +1 -1
- package/package.json +16 -10
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { DocumentMetadata, Op, PlannedSave, SaveOptions } from "@laminapdf/sdk";
|
|
2
|
+
import type { EditHistory, EditResult, ReplayedStep, SavedCopy } from "../protocol.js";
|
|
3
|
+
/** The edit session's history of document `id`. */
|
|
4
|
+
export declare function editHistory(id: number): EditHistory;
|
|
5
|
+
/**
|
|
6
|
+
* Applies `ops` to document `id`'s model as one transaction; when it touched pages, writes the
|
|
7
|
+
* edit and draws those pages from it from now on. The edit session records it as a step named
|
|
8
|
+
* `label`; an edit that changed nothing records none.
|
|
9
|
+
*
|
|
10
|
+
* @throws the op's error (nothing changed); a save or reopen error, after the transaction is
|
|
11
|
+
* undone, so the model again matches what is drawn; an error saying the document must be opened
|
|
12
|
+
* again when that undo failed too, and for every edit after it; an encrypted document's refusal.
|
|
13
|
+
*/
|
|
14
|
+
export declare function applyEdit(ops: readonly Op[], id: number, signal: AbortSignal, label?: string): Promise<EditResult>;
|
|
15
|
+
/**
|
|
16
|
+
* Undoes or redoes steps of document `id`'s edit session until `position` of them are done, then
|
|
17
|
+
* draws the pages they touched, once. A move that fails half way is taken back, so the document,
|
|
18
|
+
* the history and the pages drawn stay together.
|
|
19
|
+
*/
|
|
20
|
+
export declare function goToStep(position: number, id: number, signal: AbortSignal): Promise<EditResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Undoes (`delta` -1) or redoes (+1) one step of document `id`'s edit session, reading where it
|
|
23
|
+
* stands only once the calls before it are done.
|
|
24
|
+
*/
|
|
25
|
+
export declare function stepEdit(delta: -1 | 1, id: number, signal: AbortSignal): Promise<EditResult>;
|
|
26
|
+
/**
|
|
27
|
+
* Applies `steps` to document `id` again, one transaction each, then undoes the newest `undone`
|
|
28
|
+
* of them, and draws once: a restarted worker's document takes back the edits the old one had.
|
|
29
|
+
* The history keeps their labels and times.
|
|
30
|
+
*
|
|
31
|
+
* @throws an op's error, or a save or reopen error: the document is then marked diverged, since
|
|
32
|
+
* the edits applied so far can't all be taken back (the depth limit may have dropped some).
|
|
33
|
+
*/
|
|
34
|
+
export declare function restoreEdits(steps: readonly ReplayedStep[], undone: number, id: number, signal: AbortSignal): Promise<EditResult>;
|
|
35
|
+
/** How saving document `id` with `options` would go: its constraint, signatures, mode and warnings. */
|
|
36
|
+
export declare function planSave(options: SaveOptions, id: number, signal: AbortSignal): Promise<PlannedSave>;
|
|
37
|
+
/**
|
|
38
|
+
* Document `id`'s metadata as its edits leave it (Info and XMP read together), for the properties
|
|
39
|
+
* dialog's form. Read from the edited document, never the text copy, which has none of the edits.
|
|
40
|
+
*/
|
|
41
|
+
export declare function readMetadata(id: number, signal: AbortSignal): Promise<DocumentMetadata>;
|
|
42
|
+
/**
|
|
43
|
+
* Writes document `id` as a save with `options` would, for the page to write where the file
|
|
44
|
+
* lives; the document stays unsaved until `adoptEdits` takes the copy. `whole` copies are the
|
|
45
|
+
* file a save writes; Save a copy writes one too and never adopts it.
|
|
46
|
+
*
|
|
47
|
+
* @throws the save's refusals (`would-invalidate-signatures`, `requires-rewrite`, …); a diverged
|
|
48
|
+
* or encrypted document's.
|
|
49
|
+
*/
|
|
50
|
+
export declare function copyEdits(options: SaveOptions, id: number, signal: AbortSignal): Promise<SavedCopy>;
|
|
51
|
+
/**
|
|
52
|
+
* Makes the copy `token` names document `id`'s saved file, once the page has written it where
|
|
53
|
+
* the file lives: the model rebases onto it, the pages are drawn from it, and the history marks
|
|
54
|
+
* this point saved (or empties, when the save couldn't keep it).
|
|
55
|
+
*
|
|
56
|
+
* @throws when an edit, undo or redo since the copy made it stale: the copy written isn't the
|
|
57
|
+
* document any more, which stays unsaved.
|
|
58
|
+
*/
|
|
59
|
+
export declare function adoptEdits(token: number, id: number): Promise<EditHistory>;
|
|
60
|
+
//# sourceMappingURL=edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.d.ts","sourceRoot":"","sources":["../../src/worker/edit.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAY,gBAAgB,EAAE,EAAE,EAAY,WAAW,EAAY,WAAW,EAAE,MAAM,gBAAgB,CAAC;AACnH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAgB,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAyBrG,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,CAGnD;AAQD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,GAAG,EAAE,SAAS,EAAE,EAAE,EAClB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,EACnB,KAAK,SAAgB,GACpB,OAAO,CAAC,UAAU,CAAC,CAErB;AAmCD;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAE/F;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC,CAG5F;AAiED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,SAAS,YAAY,EAAE,EAC9B,MAAM,EAAE,MAAM,EACd,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,CAAC,CAErB;AA2HD,uGAAuG;AACvG,wBAAgB,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC,CAGpG;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAGvF;AAKD;;;;;;;GAOG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,WAAW,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,CAUnG;AAED;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAe1E"}
|
|
@@ -0,0 +1,383 @@
|
|
|
1
|
+
// Edits on screen (E1 plan §6) and saving them (§7). PDFium draws the pages from the bytes it
|
|
2
|
+
// opened, so an edit to Lamina PDF's model reaches the screen as bytes: after a transaction that
|
|
3
|
+
// touched pages, the model writes a copy of every edit since the last save, as one revision
|
|
4
|
+
// appended to the saved file (`saveCopy`: the model isn't rebased, so its plan still sees every
|
|
5
|
+
// change), and the backend opens the file with it. The new render document replaces the old one
|
|
6
|
+
// only once it is open, so a failure leaves the pages drawn as they were. The worker runs one call
|
|
7
|
+
// at a time, so no render runs while the documents are swapped: a render answered before this call
|
|
8
|
+
// drew the old file, one answered after it draws the new one.
|
|
9
|
+
//
|
|
10
|
+
// A save is a copy too (`copyEdits`), which the page writes where the file lives; only once that
|
|
11
|
+
// worked does the model adopt it as its saved file (`adoptEdits`), so a failed write leaves every
|
|
12
|
+
// edit unsaved.
|
|
13
|
+
import { current, currentBackend, filling, followEdit } from "./document.js";
|
|
14
|
+
import { forgetSearch } from "./find.js";
|
|
15
|
+
import { forgetLinks } from "./navigation.js";
|
|
16
|
+
import { clearHistory, clearRedo, historyOf, markSaved, record, removeStep, restore, snapshot, stepBack, walkTo, } from "./session.js";
|
|
17
|
+
import { forgetText } from "./text.js";
|
|
18
|
+
/** Why an edit that failed left the model and the pages drawn apart: the document must be opened again. */
|
|
19
|
+
const DIVERGED = "an edit failed and couldn't be undone: the document and the pages drawn may differ; open it again";
|
|
20
|
+
/** Why an encrypted document takes no edit: its edits can't be written into memory to be drawn. */
|
|
21
|
+
const ENCRYPTED = "an encrypted document can't be edited yet: its edits can't be saved (encrypted-base)";
|
|
22
|
+
/** The edit session's history of document `id`. */
|
|
23
|
+
export function editHistory(id) {
|
|
24
|
+
const { edit } = current(id);
|
|
25
|
+
return historyOf(edit.session, edit.diverged);
|
|
26
|
+
}
|
|
27
|
+
/** Throws why document `opened` can't take an edit, undo or redo now, if it can't. */
|
|
28
|
+
function editable(opened) {
|
|
29
|
+
if (opened.edit.diverged)
|
|
30
|
+
throw new Error(DIVERGED);
|
|
31
|
+
if (opened.model.isEncrypted)
|
|
32
|
+
throw new Error(ENCRYPTED);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Applies `ops` to document `id`'s model as one transaction; when it touched pages, writes the
|
|
36
|
+
* edit and draws those pages from it from now on. The edit session records it as a step named
|
|
37
|
+
* `label`; an edit that changed nothing records none.
|
|
38
|
+
*
|
|
39
|
+
* @throws the op's error (nothing changed); a save or reopen error, after the transaction is
|
|
40
|
+
* undone, so the model again matches what is drawn; an error saying the document must be opened
|
|
41
|
+
* again when that undo failed too, and for every edit after it; an encrypted document's refusal.
|
|
42
|
+
*/
|
|
43
|
+
export function applyEdit(ops, id, signal, label = describe(ops)) {
|
|
44
|
+
return serial(current(id), () => apply(ops, id, signal, label));
|
|
45
|
+
}
|
|
46
|
+
async function apply(ops, id, signal, label) {
|
|
47
|
+
const opened = current(id);
|
|
48
|
+
editable(opened);
|
|
49
|
+
const { model, edit } = opened;
|
|
50
|
+
const count = await model.ensure(() => model.pageCount, { signal });
|
|
51
|
+
const edited = await model.ensure(() => model.apply(ops), { signal });
|
|
52
|
+
if (!edited.changed)
|
|
53
|
+
return { pages: [], history: historyOf(edit.session, false) };
|
|
54
|
+
edit.copy = undefined;
|
|
55
|
+
// The transaction cleared the model's redo stack, whatever happens next.
|
|
56
|
+
clearRedo(edit.session);
|
|
57
|
+
if (edited.touchedPages.length > 0) {
|
|
58
|
+
try {
|
|
59
|
+
await samePages(model, count);
|
|
60
|
+
await redraw(opened);
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
// The edit never reached the screen: take it back out of the model, so the model matches
|
|
64
|
+
// what is drawn. The undone transaction is left on the model's redo stack, but the session
|
|
65
|
+
// has no step for it, so nothing redoes it, and the next edit clears it.
|
|
66
|
+
await revert(model, edit, "undo", e);
|
|
67
|
+
throw e;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
followEdit(opened, ops);
|
|
71
|
+
const pages = await touched(opened, edited.touchedPages);
|
|
72
|
+
record(edit.session, label, pages.map((page) => page.index), Date.now());
|
|
73
|
+
return { pages, history: historyOf(edit.session, false) };
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Undoes or redoes steps of document `id`'s edit session until `position` of them are done, then
|
|
77
|
+
* draws the pages they touched, once. A move that fails half way is taken back, so the document,
|
|
78
|
+
* the history and the pages drawn stay together.
|
|
79
|
+
*/
|
|
80
|
+
export function goToStep(position, id, signal) {
|
|
81
|
+
return serial(current(id), () => moveTo(() => position, id, signal));
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Undoes (`delta` -1) or redoes (+1) one step of document `id`'s edit session, reading where it
|
|
85
|
+
* stands only once the calls before it are done.
|
|
86
|
+
*/
|
|
87
|
+
export function stepEdit(delta, id, signal) {
|
|
88
|
+
const opened = current(id);
|
|
89
|
+
return serial(opened, () => moveTo(() => opened.edit.session.position + delta, id, signal));
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Runs `call` after document `opened`'s edit calls before it have settled: the worker serves
|
|
93
|
+
* calls as they come, and an edit's awaits would otherwise let another start against the history
|
|
94
|
+
* it is changing.
|
|
95
|
+
*/
|
|
96
|
+
function serial(opened, call) {
|
|
97
|
+
const run = opened.edit.queue.then(call);
|
|
98
|
+
opened.edit.queue = run.catch(() => undefined);
|
|
99
|
+
return run;
|
|
100
|
+
}
|
|
101
|
+
async function moveTo(position, id, signal) {
|
|
102
|
+
const opened = current(id);
|
|
103
|
+
editable(opened);
|
|
104
|
+
const { model, edit } = opened;
|
|
105
|
+
const { session } = edit;
|
|
106
|
+
const kept = snapshot(session);
|
|
107
|
+
edit.copy = undefined;
|
|
108
|
+
const done = [];
|
|
109
|
+
const ids = new Set();
|
|
110
|
+
try {
|
|
111
|
+
await walkTo(session, position(), async (way) => {
|
|
112
|
+
const reverted = await model.ensure(() => (way === "undo" ? model.undo() : model.redo()), { signal });
|
|
113
|
+
// The model has no entry where the session has a step: they disagree, which only a bug does.
|
|
114
|
+
if (reverted === undefined)
|
|
115
|
+
throw new Error(`the document has nothing to ${way}`);
|
|
116
|
+
for (const page of reverted.touchedPages)
|
|
117
|
+
ids.add(page);
|
|
118
|
+
followEdit(opened, way);
|
|
119
|
+
return reverted.outcome;
|
|
120
|
+
}, done);
|
|
121
|
+
if (ids.size > 0)
|
|
122
|
+
await redraw(opened);
|
|
123
|
+
}
|
|
124
|
+
catch (e) {
|
|
125
|
+
await takeBack(opened, kept, done, e);
|
|
126
|
+
throw e;
|
|
127
|
+
}
|
|
128
|
+
const pages = await touched(opened, [...ids]);
|
|
129
|
+
return { pages, history: historyOf(session, false), reverted: done };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Takes back the undos and redos in `done`, newest first, and puts the history back as `kept`
|
|
133
|
+
* was, less the steps the model dropped (a skipped undo or redo leaves it no entry).
|
|
134
|
+
*/
|
|
135
|
+
async function takeBack(opened, kept, done, failure) {
|
|
136
|
+
const { model, edit } = opened;
|
|
137
|
+
for (const step of [...done].reverse()) {
|
|
138
|
+
if (step.outcome === "skipped")
|
|
139
|
+
continue;
|
|
140
|
+
await revert(model, edit, step.way === "undo" ? "redo" : "undo", failure);
|
|
141
|
+
followEdit(opened, step.way === "undo" ? "redo" : "undo");
|
|
142
|
+
}
|
|
143
|
+
const { session } = edit;
|
|
144
|
+
restore(session, kept);
|
|
145
|
+
for (const step of done) {
|
|
146
|
+
if (step.outcome !== "skipped")
|
|
147
|
+
continue;
|
|
148
|
+
const index = session.steps.findIndex((s) => s.id === step.step.id);
|
|
149
|
+
if (index >= 0)
|
|
150
|
+
removeStep(session, index, step.way);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Applies `steps` to document `id` again, one transaction each, then undoes the newest `undone`
|
|
155
|
+
* of them, and draws once: a restarted worker's document takes back the edits the old one had.
|
|
156
|
+
* The history keeps their labels and times.
|
|
157
|
+
*
|
|
158
|
+
* @throws an op's error, or a save or reopen error: the document is then marked diverged, since
|
|
159
|
+
* the edits applied so far can't all be taken back (the depth limit may have dropped some).
|
|
160
|
+
*/
|
|
161
|
+
export function restoreEdits(steps, undone, id, signal) {
|
|
162
|
+
return serial(current(id), () => replay(steps, undone, id, signal));
|
|
163
|
+
}
|
|
164
|
+
async function replay(steps, undone, id, signal) {
|
|
165
|
+
const opened = current(id);
|
|
166
|
+
editable(opened);
|
|
167
|
+
const { model, edit } = opened;
|
|
168
|
+
const ids = new Set();
|
|
169
|
+
edit.copy = undefined;
|
|
170
|
+
try {
|
|
171
|
+
const count = await model.ensure(() => model.pageCount, { signal });
|
|
172
|
+
for (const step of steps) {
|
|
173
|
+
const edited = await model.ensure(() => model.apply(step.ops), { signal });
|
|
174
|
+
if (!edited.changed)
|
|
175
|
+
continue;
|
|
176
|
+
for (const page of edited.touchedPages)
|
|
177
|
+
ids.add(page);
|
|
178
|
+
followEdit(opened, step.ops);
|
|
179
|
+
const pages = await model.ensure(() => model.pages);
|
|
180
|
+
const wanted = new Set(edited.touchedPages);
|
|
181
|
+
const indices = pages.filter((page) => wanted.has(page.id)).map((page) => page.index);
|
|
182
|
+
record(edit.session, step.label, indices, step.at);
|
|
183
|
+
}
|
|
184
|
+
for (let i = 0; i < undone && edit.session.position > 0; i++) {
|
|
185
|
+
const reverted = await model.ensure(() => model.undo(), { signal });
|
|
186
|
+
if (reverted === undefined)
|
|
187
|
+
break;
|
|
188
|
+
stepBack(edit.session, reverted.outcome);
|
|
189
|
+
followEdit(opened, "undo");
|
|
190
|
+
}
|
|
191
|
+
await samePages(model, count);
|
|
192
|
+
if (ids.size > 0)
|
|
193
|
+
await redraw(opened);
|
|
194
|
+
}
|
|
195
|
+
catch (e) {
|
|
196
|
+
edit.diverged = true;
|
|
197
|
+
throw new Error(DIVERGED, { cause: e });
|
|
198
|
+
}
|
|
199
|
+
// The file reopened as it was: the saved document is the one opened.
|
|
200
|
+
edit.session.saved = 0;
|
|
201
|
+
return { pages: await touched(opened, [...ids]), history: historyOf(edit.session, false) };
|
|
202
|
+
}
|
|
203
|
+
/** A label for an edit whose caller gave none: its ops' names. */
|
|
204
|
+
function describe(ops) {
|
|
205
|
+
return ops.map((op) => op.op).join(", ");
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Refuses an edit that added, removed or moved pages: the view finds pages by index, and
|
|
209
|
+
* `EditResult` names pages by their indices after the edit.
|
|
210
|
+
*/
|
|
211
|
+
async function samePages(model, before) {
|
|
212
|
+
const after = await model.ensure(() => model.pageCount);
|
|
213
|
+
if (after !== before)
|
|
214
|
+
throw new Error(`an edit that changes the page count (${before} → ${after}) can't be shown yet`);
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Undoes (or redoes) the transaction just applied (or undone); when that fails too, marks the
|
|
218
|
+
* document diverged.
|
|
219
|
+
*/
|
|
220
|
+
async function revert(model, edit, way, failure) {
|
|
221
|
+
let reverted;
|
|
222
|
+
try {
|
|
223
|
+
reverted = await model.ensure(() => (way === "undo" ? model.undo() : model.redo()));
|
|
224
|
+
}
|
|
225
|
+
catch (e) {
|
|
226
|
+
edit.diverged = true;
|
|
227
|
+
throw new Error(DIVERGED, { cause: [failure, e] });
|
|
228
|
+
}
|
|
229
|
+
// A partial outcome still restored what it could; only nothing at all leaves them apart.
|
|
230
|
+
if (reverted === undefined || reverted.outcome === "skipped") {
|
|
231
|
+
edit.diverged = true;
|
|
232
|
+
throw new Error(DIVERGED, { cause: failure });
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/** The pages with these IDs, as they are now, in index order; what the worker kept of them is forgotten. */
|
|
236
|
+
async function touched(opened, ids) {
|
|
237
|
+
if (ids.length === 0)
|
|
238
|
+
return [];
|
|
239
|
+
const wanted = new Set(ids);
|
|
240
|
+
const { model } = opened;
|
|
241
|
+
const pages = (await model.ensure(() => model.pages)).filter((page) => wanted.has(page.id));
|
|
242
|
+
const indices = pages.map((page) => page.index);
|
|
243
|
+
forgetText(indices);
|
|
244
|
+
forgetSearch(indices);
|
|
245
|
+
forgetLinks(indices);
|
|
246
|
+
return pages;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Writes a copy of the model's changes since the last save and swaps in a render document opened
|
|
250
|
+
* from the saved file with it. The old one keeps drawing until the new one is open, and is closed
|
|
251
|
+
* after. The copy overrides signatures a change breaks (`invalidateSignatures`): the pages must
|
|
252
|
+
* show the edit, and only a save asks before it breaks one.
|
|
253
|
+
*/
|
|
254
|
+
async function redraw(opened) {
|
|
255
|
+
const { model, edit } = opened;
|
|
256
|
+
// Only the appended revision, unless the saved file must be rewritten (a repaired one).
|
|
257
|
+
const { bytes, report } = await model.ensure(() => model.saveCopy({ mode: "auto", output: "appendedOnly", invalidateSignatures: true }));
|
|
258
|
+
edit.drawn = { bytes, whole: report.mode === "fullRewrite" };
|
|
259
|
+
await reopen(opened);
|
|
260
|
+
}
|
|
261
|
+
/** Swaps in a render document opened from the saved file and the copy drawn after it. */
|
|
262
|
+
async function reopen(opened) {
|
|
263
|
+
const { edit } = opened;
|
|
264
|
+
const { drawn } = edit;
|
|
265
|
+
const source = drawn === undefined
|
|
266
|
+
? edit.source
|
|
267
|
+
: drawn.whole
|
|
268
|
+
? bytesSource(drawn.bytes)
|
|
269
|
+
: joined([edit.source, bytesSource(drawn.bytes)]);
|
|
270
|
+
const options = edit.renderLimits === undefined ? {} : { limits: edit.renderLimits };
|
|
271
|
+
// Not the caller's signal: the model has moved on, so the reopen finishes either way.
|
|
272
|
+
const next = await filling(opened.remote, () => currentBackend().open(source, options), new AbortController().signal);
|
|
273
|
+
const old = opened.render;
|
|
274
|
+
opened.render = next;
|
|
275
|
+
old.close();
|
|
276
|
+
}
|
|
277
|
+
/** How saving document `id` with `options` would go: its constraint, signatures, mode and warnings. */
|
|
278
|
+
export function planSave(options, id, signal) {
|
|
279
|
+
const opened = current(id);
|
|
280
|
+
return serial(opened, () => opened.model.ensure(() => opened.model.plan(options), { signal }));
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Document `id`'s metadata as its edits leave it (Info and XMP read together), for the properties
|
|
284
|
+
* dialog's form. Read from the edited document, never the text copy, which has none of the edits.
|
|
285
|
+
*/
|
|
286
|
+
export function readMetadata(id, signal) {
|
|
287
|
+
const opened = current(id);
|
|
288
|
+
return serial(opened, () => opened.model.ensure(() => opened.model.metadata(), { signal }));
|
|
289
|
+
}
|
|
290
|
+
/** The token of the next copy a save writes. */
|
|
291
|
+
let nextCopy = 1;
|
|
292
|
+
/**
|
|
293
|
+
* Writes document `id` as a save with `options` would, for the page to write where the file
|
|
294
|
+
* lives; the document stays unsaved until `adoptEdits` takes the copy. `whole` copies are the
|
|
295
|
+
* file a save writes; Save a copy writes one too and never adopts it.
|
|
296
|
+
*
|
|
297
|
+
* @throws the save's refusals (`would-invalidate-signatures`, `requires-rewrite`, …); a diverged
|
|
298
|
+
* or encrypted document's.
|
|
299
|
+
*/
|
|
300
|
+
export function copyEdits(options, id, signal) {
|
|
301
|
+
const opened = current(id);
|
|
302
|
+
return serial(opened, async () => {
|
|
303
|
+
editable(opened);
|
|
304
|
+
const { model, edit } = opened;
|
|
305
|
+
const { bytes, report } = await model.ensure(() => model.saveCopy({ ...options, output: "whole" }), { signal });
|
|
306
|
+
const token = nextCopy++;
|
|
307
|
+
edit.copy = { token, bytes, historyCleared: report.historyCleared };
|
|
308
|
+
return { token, bytes, report };
|
|
309
|
+
});
|
|
310
|
+
}
|
|
311
|
+
/**
|
|
312
|
+
* Makes the copy `token` names document `id`'s saved file, once the page has written it where
|
|
313
|
+
* the file lives: the model rebases onto it, the pages are drawn from it, and the history marks
|
|
314
|
+
* this point saved (or empties, when the save couldn't keep it).
|
|
315
|
+
*
|
|
316
|
+
* @throws when an edit, undo or redo since the copy made it stale: the copy written isn't the
|
|
317
|
+
* document any more, which stays unsaved.
|
|
318
|
+
*/
|
|
319
|
+
export function adoptEdits(token, id) {
|
|
320
|
+
const opened = current(id);
|
|
321
|
+
return serial(opened, async () => {
|
|
322
|
+
const { model, edit } = opened;
|
|
323
|
+
const { copy } = edit;
|
|
324
|
+
if (copy?.token !== token)
|
|
325
|
+
throw new Error("the document changed after this copy was written: it stays unsaved");
|
|
326
|
+
edit.copy = undefined;
|
|
327
|
+
await model.ensure(() => model.adoptCopy(copy.bytes, copy.historyCleared));
|
|
328
|
+
edit.source = bytesSource(copy.bytes);
|
|
329
|
+
edit.drawn = undefined;
|
|
330
|
+
if (copy.historyCleared)
|
|
331
|
+
clearHistory(edit.session);
|
|
332
|
+
else
|
|
333
|
+
markSaved(edit.session);
|
|
334
|
+
await reopen(opened);
|
|
335
|
+
return historyOf(edit.session, false);
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
function bytesSource(bytes) {
|
|
339
|
+
return { size: bytes.length, readSync: (offset, length) => bytes.subarray(offset, offset + length) };
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* `parts` one after another, read in place: the file and the revisions appended to it, never
|
|
343
|
+
* copied into one buffer. A part that answers `undefined` (a remote file's bytes not fetched yet)
|
|
344
|
+
* makes the read answer `undefined`, which `filling` fetches.
|
|
345
|
+
*/
|
|
346
|
+
function joined(parts) {
|
|
347
|
+
const starts = [];
|
|
348
|
+
let size = 0;
|
|
349
|
+
for (const part of parts) {
|
|
350
|
+
starts.push(size);
|
|
351
|
+
size += part.size;
|
|
352
|
+
}
|
|
353
|
+
return {
|
|
354
|
+
size,
|
|
355
|
+
readSync(offset, length) {
|
|
356
|
+
const end = Math.min(size, offset + length);
|
|
357
|
+
const pieces = [];
|
|
358
|
+
for (let i = 0; i < parts.length; i++) {
|
|
359
|
+
const start = starts[i];
|
|
360
|
+
const part = parts[i];
|
|
361
|
+
const from = Math.max(offset, start);
|
|
362
|
+
const to = Math.min(end, start + part.size);
|
|
363
|
+
if (from >= to)
|
|
364
|
+
continue;
|
|
365
|
+
const piece = part.readSync(from - start, to - from);
|
|
366
|
+
if (piece === undefined)
|
|
367
|
+
return undefined;
|
|
368
|
+
pieces.push(piece);
|
|
369
|
+
}
|
|
370
|
+
return pieces.length === 1 ? pieces[0] : concat(pieces);
|
|
371
|
+
},
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
function concat(pieces) {
|
|
375
|
+
const out = new Uint8Array(pieces.reduce((sum, piece) => sum + piece.length, 0));
|
|
376
|
+
let at = 0;
|
|
377
|
+
for (const piece of pieces) {
|
|
378
|
+
out.set(piece, at);
|
|
379
|
+
at += piece.length;
|
|
380
|
+
}
|
|
381
|
+
return out;
|
|
382
|
+
}
|
|
383
|
+
//# sourceMappingURL=edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edit.js","sourceRoot":"","sources":["../../src/worker/edit.ts"],"names":[],"mappings":"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"}
|
package/dist/worker/find.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import type { FindOptions } from "../find/fold.js";
|
|
|
2
2
|
import type { FindPageResult } from "../protocol.js";
|
|
3
3
|
/** The matches of `query` on each of `pages`, in that order. */
|
|
4
4
|
export declare function find(query: string, options: FindOptions, pages: readonly number[], signal: AbortSignal): Promise<FindPageResult[]>;
|
|
5
|
-
/** Forgets every page's
|
|
6
|
-
export declare function forgetSearch(): void;
|
|
5
|
+
/** Forgets `pages`' searchable text (an edit changed them), or every page's (the document closed). */
|
|
6
|
+
export declare function forgetSearch(pages?: Iterable<number>): void;
|
|
7
7
|
//# sourceMappingURL=find.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/worker/find.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAoBrD,gEAAgE;AAChE,wBAAsB,IAAI,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CAkB3B;AAED,
|
|
1
|
+
{"version":3,"file":"find.d.ts","sourceRoot":"","sources":["../../src/worker/find.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAoBrD,gEAAgE;AAChE,wBAAsB,IAAI,CACxB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,WAAW,EACpB,KAAK,EAAE,SAAS,MAAM,EAAE,EACxB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,cAAc,EAAE,CAAC,CAkB3B;AAED,sGAAsG;AACtG,wBAAgB,YAAY,CAAC,KAAK,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,GAAG,IAAI,CAE3D"}
|
package/dist/worker/find.js
CHANGED
|
@@ -39,8 +39,8 @@ export async function find(query, options, pages, signal) {
|
|
|
39
39
|
}
|
|
40
40
|
return out;
|
|
41
41
|
}
|
|
42
|
-
/** Forgets every page's
|
|
43
|
-
export function forgetSearch() {
|
|
44
|
-
cache.
|
|
42
|
+
/** Forgets `pages`' searchable text (an edit changed them), or every page's (the document closed). */
|
|
43
|
+
export function forgetSearch(pages) {
|
|
44
|
+
cache.forget(pages);
|
|
45
45
|
}
|
|
46
46
|
//# sourceMappingURL=find.js.map
|
package/dist/worker/find.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/worker/find.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,6FAA6F;AAC7F,+FAA+F;AAC/F,+FAA+F;AAC/F,iGAAiG;AACjG,wCAAwC;AAGxC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAmB,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtG,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;AAE9G,MAAM,KAAK,GAAG,IAAI,WAAW,CAAa,kBAAkB,EAAE,OAAO,CAAC,CAAC;AAEvE,mEAAmE;AACnE,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,MAAmB;IAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAClE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,KAAa,EACb,OAAoB,EACpB,KAAwB,EACxB,MAAmB;IAEnB,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QACxC,oFAAoF;QACpF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,KAAK,GACT,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3G,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,
|
|
1
|
+
{"version":3,"file":"find.js","sourceRoot":"","sources":["../../src/worker/find.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,6FAA6F;AAC7F,+FAA+F;AAC/F,+FAA+F;AAC/F,iGAAiG;AACjG,wCAAwC;AAGxC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAmB,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEtG,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAEvC,kEAAkE;AAClE,MAAM,kBAAkB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,OAAO,GAAG,CAAC,CAAa,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,UAAU,CAAC;AAE9G,MAAM,KAAK,GAAG,IAAI,WAAW,CAAa,kBAAkB,EAAE,OAAO,CAAC,CAAC;AAEvE,mEAAmE;AACnE,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,MAAmB;IAC1D,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAClC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;IAClE,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACzB,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,gEAAgE;AAChE,MAAM,CAAC,KAAK,UAAU,IAAI,CACxB,KAAa,EACb,OAAoB,EACpB,KAAwB,EACxB,MAAmB;IAEnB,MAAM,GAAG,GAAqB,EAAE,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;QACxC,oFAAoF;QACpF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;QAC/D,MAAM,KAAK,GACT,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,cAAc,CAAC,MAAM,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC3G,GAAG,CAAC,IAAI,CAAC;YACP,IAAI;YACJ,OAAO,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACjC,QAAQ,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC;YACzD,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACnC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,sGAAsG;AACtG,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** How much of the file's start is read: the first revision's end is looked for in it. */
|
|
2
|
+
export declare const HEAD_BYTES: number;
|
|
3
|
+
/** The bytes the fingerprint covers: `head` through the end of its first `%%EOF`, else all of it. */
|
|
4
|
+
export declare function fingerprintedBytes(head: Uint8Array): Uint8Array;
|
|
5
|
+
/**
|
|
6
|
+
* The fingerprint of a file whose first bytes are `head` (its first {@link HEAD_BYTES}, or the
|
|
7
|
+
* whole file when it is smaller): `"fp1:"` and a SHA-256 in hex.
|
|
8
|
+
*/
|
|
9
|
+
export declare function documentFingerprint(head: Uint8Array): Promise<string>;
|
|
10
|
+
//# sourceMappingURL=fingerprint.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/worker/fingerprint.ts"],"names":[],"mappings":"AAMA,0FAA0F;AAC1F,eAAO,MAAM,UAAU,QAAY,CAAC;AAWpC,qGAAqG;AACrG,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAG/D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAO3E"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
// A document's fingerprint, the key its reading position is kept under: a hash of the file's head,
|
|
2
|
+
// up to the end of its first revision. An incremental update appends to the file (ISO 32000-2
|
|
3
|
+
// §7.5.6) and leaves the head alone, so a file reopens at its place after someone adds a note or
|
|
4
|
+
// a signature; a full rewrite changes the head, so its output starts without one. `/ID[0]` stays
|
|
5
|
+
// out of it: a file without one gains one on its first save, which would change the key.
|
|
6
|
+
/** How much of the file's start is read: the first revision's end is looked for in it. */
|
|
7
|
+
export const HEAD_BYTES = 64 * 1024;
|
|
8
|
+
/** The fingerprint's version, so a later scheme can live beside this one. */
|
|
9
|
+
const PREFIX = "fp1:";
|
|
10
|
+
/** What the hash starts with: the scheme's name and a zero byte. */
|
|
11
|
+
const TAG = new TextEncoder().encode("laminapdf.fp/1\0");
|
|
12
|
+
/** `%%EOF`, the marker that ends a revision (§7.5.5). */
|
|
13
|
+
const EOF_MARKER = new TextEncoder().encode("%%EOF");
|
|
14
|
+
/** The bytes the fingerprint covers: `head` through the end of its first `%%EOF`, else all of it. */
|
|
15
|
+
export function fingerprintedBytes(head) {
|
|
16
|
+
const at = indexOf(head, EOF_MARKER);
|
|
17
|
+
return at < 0 ? head : head.subarray(0, at + EOF_MARKER.length);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* The fingerprint of a file whose first bytes are `head` (its first {@link HEAD_BYTES}, or the
|
|
21
|
+
* whole file when it is smaller): `"fp1:"` and a SHA-256 in hex.
|
|
22
|
+
*/
|
|
23
|
+
export async function documentFingerprint(head) {
|
|
24
|
+
const covered = fingerprintedBytes(head.subarray(0, HEAD_BYTES));
|
|
25
|
+
const input = new Uint8Array(TAG.length + covered.length);
|
|
26
|
+
input.set(TAG);
|
|
27
|
+
input.set(covered, TAG.length);
|
|
28
|
+
const digest = new Uint8Array(await crypto.subtle.digest("SHA-256", input));
|
|
29
|
+
return PREFIX + Array.from(digest, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
30
|
+
}
|
|
31
|
+
/** Where `needle` first starts in `bytes`, or −1. */
|
|
32
|
+
function indexOf(bytes, needle) {
|
|
33
|
+
for (let i = 0; i + needle.length <= bytes.length; i++) {
|
|
34
|
+
let j = 0;
|
|
35
|
+
while (j < needle.length && bytes[i + j] === needle[j])
|
|
36
|
+
j++;
|
|
37
|
+
if (j === needle.length)
|
|
38
|
+
return i;
|
|
39
|
+
}
|
|
40
|
+
return -1;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=fingerprint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/worker/fingerprint.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,8FAA8F;AAC9F,iGAAiG;AACjG,iGAAiG;AACjG,yFAAyF;AAEzF,0FAA0F;AAC1F,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,GAAG,IAAI,CAAC;AAEpC,6EAA6E;AAC7E,MAAM,MAAM,GAAG,MAAM,CAAC;AAEtB,oEAAoE;AACpE,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;AAEzD,yDAAyD;AACzD,MAAM,UAAU,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAErD,qGAAqG;AACrG,MAAM,UAAU,kBAAkB,CAAC,IAAgB;IACjD,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACrC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;AAClE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAgB;IACxD,MAAM,OAAO,GAAG,kBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC1D,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACf,KAAK,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,MAAM,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC,CAAC;IAC5E,OAAO,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,qDAAqD;AACrD,SAAS,OAAO,CAAC,KAAiB,EAAE,MAAkB;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC,GAAG,CAAC,CAAC;QACV,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;YAAE,CAAC,EAAE,CAAC;QAC5D,IAAI,CAAC,KAAK,MAAM,CAAC,MAAM;YAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IACD,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/worker/methods.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"methods.d.ts","sourceRoot":"","sources":["../../src/worker/methods.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AA8BpE,2EAA2E;AAC3E,eAAO,MAAM,aAAa,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAyFnE,CAAC"}
|
package/dist/worker/methods.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// The viewer's methods on the document worker: the extension `entry.ts` serves, and test
|
|
2
2
|
// workers too, which add their own hooks on top so none ships.
|
|
3
3
|
import { closeDocument, current, currentDocument, initBackend, openDocument, textModel, workerMemory, } from "./document.js";
|
|
4
|
+
import { adoptEdits, applyEdit, copyEdits, editHistory, goToStep, planSave, readMetadata, restoreEdits, stepEdit, } from "./edit.js";
|
|
4
5
|
import { find, forgetSearch } from "./find.js";
|
|
5
6
|
import { forgetLinks, namedDestination, outline, pageLinks } from "./navigation.js";
|
|
6
7
|
import { networkLog } from "./network.js";
|
|
@@ -22,6 +23,39 @@ export const viewerMethods = {
|
|
|
22
23
|
return closeDocument();
|
|
23
24
|
},
|
|
24
25
|
},
|
|
26
|
+
applyEdit: {
|
|
27
|
+
run: ([ops, id, label], { signal }) => applyEdit(ops, id, signal, label),
|
|
28
|
+
},
|
|
29
|
+
undoEdit: {
|
|
30
|
+
run: ([id], { signal }) => stepEdit(-1, id, signal),
|
|
31
|
+
},
|
|
32
|
+
redoEdit: {
|
|
33
|
+
run: ([id], { signal }) => stepEdit(1, id, signal),
|
|
34
|
+
},
|
|
35
|
+
goToStep: {
|
|
36
|
+
run: ([position, id], { signal }) => goToStep(position, id, signal),
|
|
37
|
+
},
|
|
38
|
+
editHistory: {
|
|
39
|
+
run: ([id]) => editHistory(id),
|
|
40
|
+
},
|
|
41
|
+
metadata: { run: ([id], { signal }) => readMetadata(id, signal) },
|
|
42
|
+
planSave: {
|
|
43
|
+
run: ([options, id], { signal }) => planSave(options, id, signal),
|
|
44
|
+
},
|
|
45
|
+
copyEdits: {
|
|
46
|
+
run: ([options, id], { signal }) => copyEdits(options, id, signal),
|
|
47
|
+
reply: (copy) => {
|
|
48
|
+
const { token, bytes, report } = copy;
|
|
49
|
+
const [own, transfer] = replyBytes(bytes);
|
|
50
|
+
return [{ token, bytes: own, report }, transfer];
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
adoptEdits: {
|
|
54
|
+
run: ([token, id]) => adoptEdits(token, id),
|
|
55
|
+
},
|
|
56
|
+
restoreEdits: {
|
|
57
|
+
run: ([steps, undone, id], { signal }) => restoreEdits(steps, undone, id, signal),
|
|
58
|
+
},
|
|
25
59
|
pageInfo: {
|
|
26
60
|
run: ([index], { signal }) => {
|
|
27
61
|
const { model } = current();
|