@docmentis/udoc-node 0.0.0-stage → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE-APACHE +202 -0
- package/LICENSE-MIT +21 -0
- package/README.md +50 -2
- package/dist/blocking-fetch.d.ts +8 -0
- package/dist/blocking-fetch.d.ts.map +1 -0
- package/dist/blocking-fetch.js +30 -0
- package/dist/blocking-fetch.js.map +1 -0
- package/dist/engine.d.ts +3 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +20 -0
- package/dist/engine.js.map +1 -0
- package/dist/font-cache.d.ts +16 -0
- package/dist/font-cache.d.ts.map +1 -0
- package/dist/font-cache.js +66 -0
- package/dist/font-cache.js.map +1 -0
- package/dist/format.d.ts +4 -0
- package/dist/format.d.ts.map +1 -0
- package/dist/format.js +30 -0
- package/dist/format.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/node.d.ts +101 -0
- package/dist/node.d.ts.map +1 -0
- package/dist/node.js +96 -0
- package/dist/node.js.map +1 -0
- package/dist/protocol.d.ts +151 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +3 -0
- package/dist/protocol.js.map +1 -0
- package/dist/session.d.ts +168 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +458 -0
- package/dist/session.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +10 -0
- package/dist/version.js.map +1 -0
- package/dist/worker.d.ts +2 -0
- package/dist/worker.d.ts.map +1 -0
- package/dist/worker.js +243 -0
- package/dist/worker.js.map +1 -0
- package/package.json +62 -5
package/dist/session.js
ADDED
|
@@ -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 @@
|
|
|
1
|
+
{"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,eAAe,QAAmB,CAAC"}
|
package/dist/version.js
ADDED
|
@@ -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"}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":""}
|