@docmentis/udoc-node 0.0.1 → 0.8.1

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.
@@ -0,0 +1,458 @@
1
+ // A session — one open document: the handle an embedder holds, over the worker
2
+ // thread that runs it.
3
+ //
4
+ // The one sibling it imports at runtime is `@docmentis/udoc-wasm/error`, which
5
+ // loads no engine, so the tests can load it straight from `src` (see
6
+ // `tsconfig.test.json`).
7
+ import { MessageChannel, Worker } from "node:worker_threads";
8
+ import { UDocError } from "@docmentis/udoc-wasm/error";
9
+ /** The largest page index the engine takes: it indexes with a wasm32 `usize`,
10
+ * and a larger number would wrap on the way in. */
11
+ const MAX_PAGE_INDEX = 2 ** 32 - 1;
12
+ /** The largest baseline version the engine takes: a `u32`, for the same reason. */
13
+ const MAX_VERSION = 2 ** 32 - 1;
14
+ /** How long one part of a remote document, or one font file, may take to
15
+ * arrive before its load fails — so a server that stops answering fails the
16
+ * call that needed it, rather than leaving the worker waiting for good. */
17
+ const FETCH_TIMEOUT_MS = 60_000;
18
+ /**
19
+ * A session: one open document, driven on a worker thread of its own, so every
20
+ * call is asynchronous and none blocks the caller's event loop while the engine
21
+ * composes or rasterizes. As in the engine, the session is its document —
22
+ * opening one is the open, closing it is the close.
23
+ *
24
+ * The thread is held until {@link close}. An idle session does not keep the
25
+ * process alive; a call in flight does.
26
+ */
27
+ export class UDocSession {
28
+ /**
29
+ * Settles once the session can take no more calls, with why: it was
30
+ * {@link close}d, or its engine crashed or its thread exited on its own —
31
+ * `crashed`. A host holding sessions watches this to let go of one that
32
+ * died.
33
+ */
34
+ closed;
35
+ #worker;
36
+ #pending = new Map();
37
+ #nextId = 1;
38
+ /** Why no further call can succeed, once none can. */
39
+ #ended = null;
40
+ #settleClosed;
41
+ /** What the document opened as; set once it has opened. */
42
+ #opened = null;
43
+ /** The package resource {@link UDocNode.openRemote} opened the document from; `undefined` for any other open. */
44
+ #remotePackage;
45
+ /**
46
+ * Start a worker on the compiled engine and open `bytes` in it, answering
47
+ * each font file it asks for from `fontCache`. `UDocNode.open` is the way
48
+ * in; this is what it runs.
49
+ *
50
+ * @internal
51
+ */
52
+ static open(init, fontCache, bytes, format, delimiter) {
53
+ const fontFiles = new MessageChannel();
54
+ answerFontFiles(fontFiles.port1, fontCache);
55
+ return UDocSession.#start(init, (id) => ({
56
+ id,
57
+ type: "open",
58
+ bytes,
59
+ ...(format !== undefined ? { format } : {}),
60
+ ...(delimiter !== undefined ? { delimiter } : {}),
61
+ fontFiles: fontFiles.port2,
62
+ }), [fontFiles.port2]);
63
+ }
64
+ /**
65
+ * Start a worker on the compiled engine and open the package a server keeps
66
+ * at `url` in it, answering each part its engine asks for from here, and
67
+ * each font file from `fontCache`. `UDocNode.openRemote` is the way in;
68
+ * this is what it runs.
69
+ *
70
+ * @internal
71
+ */
72
+ static openRemote(init, fontCache, url, fetch = fetchWhole) {
73
+ // Refused before a thread starts or a permit is spent: a Node host has
74
+ // no page to resolve a relative URL against.
75
+ if (!URL.canParse(url)) {
76
+ return Promise.reject(new UDocError("invalidRequest", `a remote document's URL must be absolute, got ${JSON.stringify(url)}`));
77
+ }
78
+ const { port1, port2 } = new MessageChannel();
79
+ const answered = new Int32Array(new SharedArrayBuffer(Int32Array.BYTES_PER_ELEMENT));
80
+ answerFetches(port1, answered, fetch);
81
+ const fontFiles = new MessageChannel();
82
+ answerFontFiles(fontFiles.port1, fontCache);
83
+ return UDocSession.#start(init, (id) => ({ id, type: "openRemote", url, fetches: { port: port2, answered }, fontFiles: fontFiles.port2 }), [port2, fontFiles.port2]).then((session) => {
84
+ session.#remotePackage = url;
85
+ return session;
86
+ });
87
+ }
88
+ /** Start a worker on the compiled engine and send it `request`, the open. */
89
+ static async #start(init, request, transfer = []) {
90
+ const worker = new Worker(new URL("./worker.js", import.meta.url), { workerData: init });
91
+ const session = new UDocSession(worker);
92
+ try {
93
+ session.#opened = await session.#call(request, transfer);
94
+ }
95
+ catch (error) {
96
+ // A session that failed to open has spent its permit on nothing it
97
+ // can use again, so the thread goes with it.
98
+ await session.close();
99
+ throw error;
100
+ }
101
+ return session;
102
+ }
103
+ /** Drive `worker`, which runs `worker.ts`. See {@link UDocSession.open}. */
104
+ constructor(worker) {
105
+ this.closed = new Promise((resolve) => (this.#settleClosed = resolve));
106
+ this.#worker = worker;
107
+ worker.unref();
108
+ worker.on("message", (reply) => this.#settle(reply));
109
+ worker.on("error", (error) => this.#end(new UDocError("crashed", `the session's engine thread failed: ${error.message}`, undefined, {
110
+ cause: error,
111
+ })));
112
+ worker.on("exit", (code) => this.#end(new UDocError("crashed", `the session's engine thread exited (code ${code})`)));
113
+ }
114
+ /** The open document's doc type (`"portable"`, `"presentation"`, …). */
115
+ get docType() {
116
+ return this.#opened?.docType;
117
+ }
118
+ /**
119
+ * The file format the document came from (`"pdf"`, `"pptx"`, …) — what
120
+ * saving it back means — or `undefined` for a package that recorded none.
121
+ */
122
+ get sourceFormat() {
123
+ return this.#opened?.sourceFormat;
124
+ }
125
+ /**
126
+ * Whether the document was opened from a udoc package rather than
127
+ * imported from a file — which {@link sourceFormat} alone can't tell,
128
+ * since a package reports the format it recorded.
129
+ */
130
+ get fromPackage() {
131
+ return this.#opened?.fromPackage ?? false;
132
+ }
133
+ /**
134
+ * Whether the document needs a password before it can be read — a PDF
135
+ * encrypted with a user password. Until {@link authenticate} unlocks it,
136
+ * every other call rejects; {@link docType} and {@link sourceFormat} are
137
+ * already known.
138
+ */
139
+ get needsPassword() {
140
+ return this.#opened?.needsPassword ?? false;
141
+ }
142
+ /**
143
+ * What the license, or with none the permit, entitled the session to — the
144
+ * `features` a host checks before a call that needs one (the sync calls
145
+ * need `collaboration`). Advisory: the engine enforces each at the call it
146
+ * guards, rejecting with a `notEntitled` {@link UDocError}.
147
+ */
148
+ get entitlements() {
149
+ return this.#opened?.entitlements;
150
+ }
151
+ /**
152
+ * Unlock the document, which {@link needsPassword needs a password}, with
153
+ * `password` — its user or its owner password. Resolves `true` once it is
154
+ * open, and `false` when `password` is refused, the document waiting for
155
+ * another: try as often as it takes. Not a second open — no further permit
156
+ * is spent.
157
+ */
158
+ async authenticate(password) {
159
+ const unlocked = await this.#call((id) => ({ id, type: "authenticate", password }));
160
+ if (unlocked && this.#opened)
161
+ this.#opened.needsPassword = false;
162
+ return unlocked;
163
+ }
164
+ /**
165
+ * How many pages the document's primary plane has.
166
+ *
167
+ * A page is known only once it is composed, so this composes the whole
168
+ * plane — for a long flowing document, the cost of laying out all of it.
169
+ * Once paid it is not paid again: asking twice, or rendering any page
170
+ * after, reuses the composed pages. Rejects when a page fails to compose,
171
+ * since the count is then unknown.
172
+ */
173
+ pageCount() {
174
+ return this.#call((id) => ({ id, type: "pageCount" }));
175
+ }
176
+ /**
177
+ * Save the document as `format`, faithfully — the bytes reopen as the same
178
+ * document. `format` is one of its doc type's own (a PDF saves to `"pdf"`, a
179
+ * presentation to `"pptx"`); {@link sourceFormat} is what saving it back
180
+ * means. `strategy` is how much of the file it was opened from, the
181
+ * original, the saved bytes keep: a `"delta"` or `"incremental"` save
182
+ * writes over it, which a session opened with `UDocNode.openRemote` doesn't
183
+ * hold; without it, the one keeping the most of it that `format` saves by
184
+ * (`"incremental"` for a PDF, `"rewrite"` for a CSV, a TSV, a PSV or an
185
+ * image, else `"delta"`). `delimiter` is the character a CSV's fields are
186
+ * split by; without it, the one the document was opened with, else a comma.
187
+ * Rejects for a format its doc type doesn't save to, a format that never
188
+ * saves by `strategy`, a delimiter for a format that takes none, no
189
+ * original to write over, or a save that isn't built yet.
190
+ */
191
+ saveToBytes(format, strategy, delimiter) {
192
+ return this.#call((id) => ({
193
+ id,
194
+ type: "saveToBytes",
195
+ format,
196
+ ...(strategy !== undefined ? { strategy } : {}),
197
+ ...(delimiter !== undefined ? { delimiter } : {}),
198
+ }));
199
+ }
200
+ /**
201
+ * Save the document as a udoc package — the bytes of a `.udoc` zip, which
202
+ * `UDocNode.open` reopens. It records the source format, so a reopened package
203
+ * can still be saved back to it. `version` makes it a checkpoint, baseline
204
+ * `v<version>`, which keeps the edit log a reopen replays; without it the
205
+ * package is a flat baseline — the whole document and no log.
206
+ */
207
+ saveToPackage(version) {
208
+ if (version !== undefined && (!Number.isInteger(version) || version < 0 || version > MAX_VERSION)) {
209
+ return Promise.reject(new UDocError("invalidRequest", `version must be a whole number from 0 to ${MAX_VERSION}, got ${version}`));
210
+ }
211
+ return this.#call((id) => ({ id, type: "saveToPackage", ...(version !== undefined ? { version } : {}) }));
212
+ }
213
+ /**
214
+ * Ask the udoc server the document was opened from (`UDocNode.openRemote`)
215
+ * for a copy of it, saved as its {@link sourceFormat} by `strategy`, else
216
+ * by the engine's for it — a `"delta"` or `"incremental"` copy is the
217
+ * server's to save, since only it holds the original. Resolves with the
218
+ * copy's bytes. Asked with the global
219
+ * `fetch`, not the one the open was given, which only reads. Rejects for a
220
+ * document not opened with `UDocNode.openRemote`, or one that records no source
221
+ * format, and with the server's message for what it refuses.
222
+ */
223
+ async requestRemoteCopy(strategy) {
224
+ const format = this.sourceFormat;
225
+ if (format === undefined) {
226
+ throw new UDocError("invalidRequest", "requestRemoteCopy: the document records no source format to copy as");
227
+ }
228
+ const query = strategy === undefined ? "" : `?strategy=${encodeURIComponent(strategy)}`;
229
+ const response = await fetch(this.#remote("requestRemoteCopy", `file.${format}${query}`));
230
+ if (!response.ok)
231
+ throw await refusalOf(response);
232
+ return new Uint8Array(await response.arrayBuffer());
233
+ }
234
+ /**
235
+ * Ask the udoc server the document was opened from (`UDocNode.openRemote`) to
236
+ * checkpoint it: save its document as a new baseline. Resolves with that
237
+ * baseline's version. Nothing reopens: this session goes on as it was.
238
+ * Asked with the global `fetch`, as {@link requestRemoteCopy} is. Rejects
239
+ * for a document not opened with `UDocNode.openRemote`, and with the server's
240
+ * message for what it refuses.
241
+ */
242
+ async requestRemoteCheckpoint() {
243
+ const response = await fetch(this.#remote("requestRemoteCheckpoint", "checkpoints"), { method: "POST" });
244
+ if (!response.ok)
245
+ throw await refusalOf(response);
246
+ return (await response.json());
247
+ }
248
+ /**
249
+ * `route`, a resource of the document a server keeps, for `call`, which
250
+ * asks it: resolved against the package resource the document was opened
251
+ * from, `…/documents/{id}/package`, so beside it.
252
+ */
253
+ #remote(call, route) {
254
+ if (this.#remotePackage === undefined) {
255
+ throw new UDocError("invalidRequest", `${call}: the document wasn't opened from a server`);
256
+ }
257
+ return new URL(route, this.#remotePackage);
258
+ }
259
+ /**
260
+ * Export the whole document as `format` — a rendering of its laid-out
261
+ * pages, fixed and one-way. Rejects until PDF export is built.
262
+ */
263
+ exportToBytes(format) {
264
+ return this.#call((id) => ({ id, type: "exportToBytes", format }));
265
+ }
266
+ /**
267
+ * Export page `index` (0-based) of the document's primary plane as
268
+ * `format` — `{ png: { scale } }`, where `scale` is output pixels per
269
+ * document point (`1` is 72 DPI).
270
+ *
271
+ * Composes the document through that page first — not past it. Rejects
272
+ * `notFound` when the document turns out to have fewer pages; its message
273
+ * is the page count.
274
+ */
275
+ exportPageToBytes(index, format) {
276
+ if (!Number.isInteger(index) || index < 0 || index > MAX_PAGE_INDEX) {
277
+ return Promise.reject(new UDocError("invalidRequest", `page index must be a whole number from 0 to ${MAX_PAGE_INDEX}, got ${index}`));
278
+ }
279
+ if (format !== "svg" && (!Number.isFinite(format.png.scale) || format.png.scale <= 0)) {
280
+ return Promise.reject(new UDocError("invalidRequest", `scale must be a positive number, got ${format.png.scale}`));
281
+ }
282
+ return this.#call((id) => ({ id, type: "exportPageToBytes", index, format }));
283
+ }
284
+ /**
285
+ * The document's whole editing state — every edit since its baseline — for
286
+ * a peer that has none of it, to {@link merge}. For a peer that has some,
287
+ * {@link patchSince} sends only the rest.
288
+ */
289
+ snapshot() {
290
+ return this.#call((id) => ({ id, type: "snapshot" }));
291
+ }
292
+ /**
293
+ * Which edits this session holds, as the token a peer's {@link patchSince}
294
+ * takes to answer with only the ones this session lacks.
295
+ */
296
+ versionVector() {
297
+ return this.#call((id) => ({ id, type: "versionVector" }));
298
+ }
299
+ /**
300
+ * The edits this session holds that a peer — named by its
301
+ * {@link versionVector} — lacks, for that peer's {@link merge}.
302
+ */
303
+ patchSince(peer) {
304
+ return this.#call((id) => ({ id, type: "patchSince", peer }));
305
+ }
306
+ /**
307
+ * Apply a peer's edits — its {@link snapshot} or {@link patchSince} — to the
308
+ * document. Edits this session already holds are skipped, so merging the
309
+ * same patch twice changes nothing the second time. Rejects when the bytes
310
+ * aren't a patch.
311
+ */
312
+ merge(patch) {
313
+ return this.#call((id) => ({ id, type: "merge", patch }));
314
+ }
315
+ /**
316
+ * Every peer's presence this session knows of — each one's selection and
317
+ * name — for a peer's {@link mergePresence}. Transient: no history, never
318
+ * part of a save.
319
+ */
320
+ presence() {
321
+ return this.#call((id) => ({ id, type: "presence" }));
322
+ }
323
+ /** Take in a peer's {@link UDocSession.presence}, each peer's latest winning. */
324
+ mergePresence(presence) {
325
+ return this.#call((id) => ({ id, type: "mergePresence", presence }));
326
+ }
327
+ /** Release the document and its thread. Calls still in flight reject. */
328
+ async close() {
329
+ this.#end(new UDocError("invalidRequest", "the session is closed"));
330
+ await this.#worker.terminate();
331
+ }
332
+ /**
333
+ * Send `request`, handing over `transfer` with it, and answer with what the
334
+ * worker replies to its type.
335
+ */
336
+ #call(request, transfer = []) {
337
+ if (this.#ended)
338
+ return Promise.reject(this.#ended);
339
+ const id = this.#nextId++;
340
+ return new Promise((resolve, reject) => {
341
+ if (this.#pending.size === 0)
342
+ this.#worker.ref();
343
+ // The worker answers each request with its own type's result, which
344
+ // the reply's shape cannot say for itself.
345
+ this.#pending.set(id, { resolve: resolve, reject });
346
+ this.#worker.postMessage(request(id), transfer);
347
+ });
348
+ }
349
+ #settle(reply) {
350
+ const pending = this.#pending.get(reply.id);
351
+ if (!pending)
352
+ return;
353
+ this.#pending.delete(reply.id);
354
+ if (this.#pending.size === 0)
355
+ this.#worker.unref();
356
+ if (reply.ok) {
357
+ pending.resolve(reply.result);
358
+ return;
359
+ }
360
+ const error = errorOf(reply.failure);
361
+ if (error.code === "crashed") {
362
+ this.#end(error);
363
+ void this.#worker.terminate();
364
+ }
365
+ pending.reject(error);
366
+ }
367
+ #end(error) {
368
+ if (this.#ended)
369
+ return;
370
+ this.#ended = error;
371
+ for (const pending of this.#pending.values())
372
+ pending.reject(error);
373
+ this.#pending.clear();
374
+ this.#worker.unref();
375
+ this.#settleClosed(error);
376
+ }
377
+ }
378
+ /**
379
+ * Fetch each URL a worker posts on `port` — a part of the remote document its
380
+ * engine is blocked waiting for — through `fetch`, the global one unless an
381
+ * embedder answers the URLs itself, and post the answer back, counting it in
382
+ * `answered[0]` to wake the worker. The fetch happens here, on the embedder's
383
+ * thread, because the worker's own event loop is stopped while it waits; here
384
+ * it is asynchronous and blocks nothing.
385
+ *
386
+ * Nothing closes `port`: it closes with the worker's end, when the session's
387
+ * thread goes.
388
+ *
389
+ * @internal Exported for the tests.
390
+ */
391
+ export function answerFetches(port, answered, fetch = fetchWhole) {
392
+ port.on("message", (url) => {
393
+ void fetch(url)
394
+ .then(
395
+ // Its own buffer, whole, so it can be transferred.
396
+ (bytes) => ({ ok: true, body: bytes.slice().buffer }), (error) => ({ ok: false, message: reasonOf(error) }))
397
+ .then((answer) => {
398
+ port.postMessage(answer, answer.ok ? [answer.body] : []);
399
+ Atomics.add(answered, 0, 1);
400
+ Atomics.notify(answered, 0);
401
+ });
402
+ });
403
+ // As with the thread: an idle session does not keep the process alive, and
404
+ // a fetch in flight does.
405
+ port.unref();
406
+ }
407
+ /**
408
+ * Answer each font file a worker asks for on `port` from `cache`, which keeps
409
+ * it for every session of the same `UDocNode` and fetches it only on a miss.
410
+ * Unlike {@link answerFetches}, the worker is not blocked: it awaits the
411
+ * answer, so nothing needs waking.
412
+ *
413
+ * Nothing closes `port`: it closes with the worker's end, when the session's
414
+ * thread goes.
415
+ */
416
+ function answerFontFiles(port, cache) {
417
+ port.on("message", ({ id, url }) => {
418
+ void cache
419
+ .get(url)
420
+ .then(
421
+ // A copy: the cache keeps its own, and this one is transferred.
422
+ (bytes) => ({ id, ok: true, body: bytes.slice().buffer }), (error) => ({ id, ok: false, message: reasonOf(error) }))
423
+ .then((answer) => port.postMessage(answer, answer.ok ? [answer.body] : []));
424
+ });
425
+ port.unref();
426
+ }
427
+ /** The whole body `url` answers with, or a throw saying why it didn't come. */
428
+ export async function fetchWhole(url) {
429
+ const response = await fetch(url, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
430
+ if (!response.ok)
431
+ throw new Error(`HTTP ${response.status}`);
432
+ return new Uint8Array(await response.arrayBuffer());
433
+ }
434
+ /**
435
+ * What a server's failed answer says: its `{ error, message }` body, the code
436
+ * its `error` — or, for a body that isn't one, its status, as `io`. The codes
437
+ * udoc-server keeps of its own answer requests this side never makes, so what
438
+ * comes back is one of the engine's.
439
+ */
440
+ async function refusalOf(response) {
441
+ const body = (await response.json().catch(() => undefined));
442
+ const message = typeof body?.message === "string" ? `: ${body.message}` : "";
443
+ const code = typeof body?.error === "string" ? body.error : "io";
444
+ return new UDocError(code, `HTTP ${response.status}${message}`);
445
+ }
446
+ /** What a failed fetch says. Node's own says only "fetch failed", and why beside it. */
447
+ function reasonOf(error) {
448
+ if (!(error instanceof Error))
449
+ return String(error);
450
+ return error.cause instanceof Error ? `${error.message}: ${error.cause.message}` : error.message;
451
+ }
452
+ /** The {@link UDocError} `failure` crossed the thread boundary as. */
453
+ function errorOf({ code, message, detail }) {
454
+ if (code === "crashed")
455
+ return new UDocError(code, `the engine crashed, and the session is closed: ${message}`);
456
+ return new UDocError(code, message, detail);
457
+ }
458
+ //# sourceMappingURL=session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session.js","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const WRAPPER_VERSION: string;
2
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe,QAAmB,CAAC"}
@@ -0,0 +1,10 @@
1
+ // This package's version, reported to the engine as the wrapper version so a
2
+ // permit request and a usage event can name what produced them.
3
+ //
4
+ // Read from the `package.json` npm ships beside `dist` — the one place a
5
+ // release bumps — so it is always the version actually running. `../` is the
6
+ // package root from `src` and from `dist` alike.
7
+ import { readFileSync } from "node:fs";
8
+ const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
9
+ export const WRAPPER_VERSION = manifest.version;
10
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,gEAAgE;AAChE,EAAE;AACF,yEAAyE;AACzE,6EAA6E;AAC7E,iDAAiD;AAEjD,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;AAEtH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=worker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":""}