@docmentis/udoc-node 0.0.1 → 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 +51 -0
- 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 +61 -5
package/dist/node.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// The embedder's entry point: who is running the engine, the fonts it offers,
|
|
2
|
+
// and the engine itself.
|
|
3
|
+
import { CSS2_ENDPOINT } from "@docmentis/udoc-wasm/font-fulfill";
|
|
4
|
+
import { compileEngine } from "./engine.js";
|
|
5
|
+
import { FontCache } from "./font-cache.js";
|
|
6
|
+
import { UDocSession, fetchWhole } from "./session.js";
|
|
7
|
+
import { WRAPPER_VERSION } from "./version.js";
|
|
8
|
+
/** The docMentis component this package is. */
|
|
9
|
+
const WRAPPER = "udoc-node";
|
|
10
|
+
/** The bytes of font files kept when {@link UDocNodeOptions.fontCacheSize} is absent. */
|
|
11
|
+
const FONT_CACHE_SIZE = 64 * 1024 * 1024;
|
|
12
|
+
/**
|
|
13
|
+
* The udoc engine in this process: the host's identity, and the compiled
|
|
14
|
+
* engine every session instantiates. Build one per host identity and open as
|
|
15
|
+
* many documents through it as needed — each is a session of its own, on a
|
|
16
|
+
* thread of its own.
|
|
17
|
+
*/
|
|
18
|
+
export class UDocNode {
|
|
19
|
+
#module;
|
|
20
|
+
#config;
|
|
21
|
+
#fonts;
|
|
22
|
+
/** `[]` with Google Fonts off; `undefined` keeps the catalog `startSession` offers. */
|
|
23
|
+
#googleFontFamilies;
|
|
24
|
+
#googleFontEndpoint;
|
|
25
|
+
/** The font files every session opened here shares. */
|
|
26
|
+
#fontCache;
|
|
27
|
+
constructor(module, options) {
|
|
28
|
+
this.#module = module;
|
|
29
|
+
this.#config = {
|
|
30
|
+
domain: options.domain ?? "unknown",
|
|
31
|
+
wrapper: options.wrapper?.name ?? WRAPPER,
|
|
32
|
+
wrapperVersion: options.wrapper?.version ?? WRAPPER_VERSION,
|
|
33
|
+
...(options.license !== undefined ? { license: options.license } : {}),
|
|
34
|
+
...(options.distinctId !== undefined ? { distinctId: options.distinctId } : {}),
|
|
35
|
+
disableTelemetry: options.disableTelemetry ?? false,
|
|
36
|
+
};
|
|
37
|
+
this.#fonts = [...(options.fonts ?? [])];
|
|
38
|
+
this.#googleFontFamilies = options.enableGoogleFonts === false ? [] : options.googleFontFamilies;
|
|
39
|
+
this.#googleFontEndpoint =
|
|
40
|
+
options.googleFontEndpoint === undefined ? CSS2_ENDPOINT : new URL(options.googleFontEndpoint).href;
|
|
41
|
+
this.#fontCache = new FontCache(options.fontCacheSize ?? FONT_CACHE_SIZE, fetchWhole);
|
|
42
|
+
}
|
|
43
|
+
/** Compile the bundled engine (once per process) and return a `UDocNode` for it. */
|
|
44
|
+
static async create(options = {}) {
|
|
45
|
+
return new UDocNode(await compileEngine(), options);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Open a document from its bytes in a session of its own — as `format` when
|
|
49
|
+
* given, which skips detection; otherwise the format is detected, and a
|
|
50
|
+
* `.udoc` zip opens as a package. `delimiter` is the character a CSV's
|
|
51
|
+
* fields are split by; without it, a comma, or a semicolon where the first
|
|
52
|
+
* record is split by more of them. No other format takes one.
|
|
53
|
+
*
|
|
54
|
+
* Starts the session first, so this is where a license is checked and,
|
|
55
|
+
* without one, where a permit is spent — on this document, whether or not
|
|
56
|
+
* it then parses. Rejects with a `UDocError`: a licensing code when the
|
|
57
|
+
* engine refuses, or the engine's own when the bytes don't open.
|
|
58
|
+
*
|
|
59
|
+
* A PDF that needs a password opens waiting for one: the session's
|
|
60
|
+
* `needsPassword` says so, and its `authenticate` takes the password.
|
|
61
|
+
*/
|
|
62
|
+
open(bytes, format, delimiter) {
|
|
63
|
+
return UDocSession.open(this.#init(), this.#fontCache, bytes, format, delimiter);
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Open the package a server keeps at `url` in a session of its own, without
|
|
67
|
+
* downloading it — `url` is its package resource, udoc-server's
|
|
68
|
+
* `…/documents/{id}/package`, and absolute. Each part is fetched the first
|
|
69
|
+
* time the document needs it: the open fetches the few it starts from, and a
|
|
70
|
+
* call that composes a page fetches that page's, rejecting if one can't be
|
|
71
|
+
* fetched.
|
|
72
|
+
*
|
|
73
|
+
* A remote open is an open: this is where a license is checked and, without
|
|
74
|
+
* one, where a permit is spent. Rejects with a `UDocError`: a licensing code
|
|
75
|
+
* when the engine refuses, or the engine's own when the package can't be
|
|
76
|
+
* fetched or read.
|
|
77
|
+
*
|
|
78
|
+
* Each URL is fetched with the global `fetch`, unless `fetch` answers it —
|
|
79
|
+
* the whole body, as the route serves it — which is how udoc-server opens
|
|
80
|
+
* a session over the store it keeps, with no request to itself.
|
|
81
|
+
*/
|
|
82
|
+
openRemote(url, fetch) {
|
|
83
|
+
return UDocSession.openRemote(this.#init(), this.#fontCache, url, fetch);
|
|
84
|
+
}
|
|
85
|
+
/** What a session's worker starts with. */
|
|
86
|
+
#init() {
|
|
87
|
+
return {
|
|
88
|
+
module: this.#module,
|
|
89
|
+
config: this.#config,
|
|
90
|
+
fonts: this.#fonts,
|
|
91
|
+
...(this.#googleFontFamilies !== undefined ? { googleFontFamilies: this.#googleFontFamilies } : {}),
|
|
92
|
+
googleFontEndpoint: this.#googleFontEndpoint,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=node.js.map
|
package/dist/node.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node.js","sourceRoot":"","sources":["../src/node.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import type { MessagePort } from "node:worker_threads";
|
|
2
|
+
import type { Entitlements, ExportFormat, FileFormat, PageExportFormat, SaveStrategy, UDocError, UDocType } from "@docmentis/udoc-wasm";
|
|
3
|
+
/**
|
|
4
|
+
* What a remote document's parts come to its worker over. The engine asks for a
|
|
5
|
+
* part the moment it needs one, and waits for it, and Node has no synchronous
|
|
6
|
+
* HTTP: so the worker posts the part's URL on `port` and blocks until the
|
|
7
|
+
* session's side has fetched it, posted a {@link FetchAnswer} back, and counted
|
|
8
|
+
* it in `answered[0]`.
|
|
9
|
+
*/
|
|
10
|
+
export interface FetchChannel {
|
|
11
|
+
port: MessagePort;
|
|
12
|
+
answered: Int32Array;
|
|
13
|
+
}
|
|
14
|
+
/** The session side's answer to one URL posted on a {@link FetchChannel}. */
|
|
15
|
+
export type FetchAnswer = {
|
|
16
|
+
ok: true;
|
|
17
|
+
body: ArrayBuffer;
|
|
18
|
+
} | {
|
|
19
|
+
ok: false;
|
|
20
|
+
message: string;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* A font file a worker asks its session's side for, on the port its open
|
|
24
|
+
* carried, from the cache every session of its `UDocNode` shares. `id` pairs it
|
|
25
|
+
* with its {@link FontFileAnswer}: the worker asks for several at once.
|
|
26
|
+
*/
|
|
27
|
+
export interface FontFileRequest {
|
|
28
|
+
id: number;
|
|
29
|
+
url: string;
|
|
30
|
+
}
|
|
31
|
+
/** The session side's answer to a {@link FontFileRequest}: the file, or why it didn't come. */
|
|
32
|
+
export type FontFileAnswer = {
|
|
33
|
+
id: number;
|
|
34
|
+
ok: true;
|
|
35
|
+
body: ArrayBuffer;
|
|
36
|
+
} | {
|
|
37
|
+
id: number;
|
|
38
|
+
ok: false;
|
|
39
|
+
message: string;
|
|
40
|
+
};
|
|
41
|
+
/** A request to the worker. `id` pairs it with its {@link WorkerReply}. */
|
|
42
|
+
export type WorkerRequest = {
|
|
43
|
+
id: number;
|
|
44
|
+
type: "open";
|
|
45
|
+
bytes: Uint8Array;
|
|
46
|
+
format?: FileFormat;
|
|
47
|
+
delimiter?: string;
|
|
48
|
+
fontFiles: MessagePort;
|
|
49
|
+
} | {
|
|
50
|
+
id: number;
|
|
51
|
+
type: "openRemote";
|
|
52
|
+
url: string;
|
|
53
|
+
fetches: FetchChannel;
|
|
54
|
+
fontFiles: MessagePort;
|
|
55
|
+
} | {
|
|
56
|
+
id: number;
|
|
57
|
+
type: "authenticate";
|
|
58
|
+
password: string;
|
|
59
|
+
} | {
|
|
60
|
+
id: number;
|
|
61
|
+
type: "pageCount";
|
|
62
|
+
} | {
|
|
63
|
+
id: number;
|
|
64
|
+
type: "saveToBytes";
|
|
65
|
+
format: FileFormat;
|
|
66
|
+
strategy?: SaveStrategy;
|
|
67
|
+
delimiter?: string;
|
|
68
|
+
} | {
|
|
69
|
+
id: number;
|
|
70
|
+
type: "saveToPackage";
|
|
71
|
+
version?: number;
|
|
72
|
+
} | {
|
|
73
|
+
id: number;
|
|
74
|
+
type: "exportToBytes";
|
|
75
|
+
format: ExportFormat;
|
|
76
|
+
} | {
|
|
77
|
+
id: number;
|
|
78
|
+
type: "exportPageToBytes";
|
|
79
|
+
index: number;
|
|
80
|
+
format: PageExportFormat;
|
|
81
|
+
} | {
|
|
82
|
+
id: number;
|
|
83
|
+
type: "snapshot";
|
|
84
|
+
} | {
|
|
85
|
+
id: number;
|
|
86
|
+
type: "versionVector";
|
|
87
|
+
} | {
|
|
88
|
+
id: number;
|
|
89
|
+
type: "patchSince";
|
|
90
|
+
peer: Uint8Array;
|
|
91
|
+
} | {
|
|
92
|
+
id: number;
|
|
93
|
+
type: "merge";
|
|
94
|
+
patch: Uint8Array;
|
|
95
|
+
} | {
|
|
96
|
+
id: number;
|
|
97
|
+
type: "presence";
|
|
98
|
+
} | {
|
|
99
|
+
id: number;
|
|
100
|
+
type: "mergePresence";
|
|
101
|
+
presence: Uint8Array;
|
|
102
|
+
};
|
|
103
|
+
/**
|
|
104
|
+
* What the document opened as: its doc type, the format it came from, whether
|
|
105
|
+
* it came as a package, and whether it needs a password before it can be read.
|
|
106
|
+
*/
|
|
107
|
+
export interface Opened {
|
|
108
|
+
docType: UDocType;
|
|
109
|
+
/** Absent for a package that recorded none. */
|
|
110
|
+
sourceFormat?: FileFormat;
|
|
111
|
+
fromPackage: boolean;
|
|
112
|
+
needsPassword: boolean;
|
|
113
|
+
/** What the license, or with none the permit, entitled the session to. */
|
|
114
|
+
entitlements: Entitlements;
|
|
115
|
+
}
|
|
116
|
+
/** What each request's reply carries when it succeeds. */
|
|
117
|
+
export interface WorkerResult {
|
|
118
|
+
open: Opened;
|
|
119
|
+
openRemote: Opened;
|
|
120
|
+
authenticate: boolean;
|
|
121
|
+
pageCount: number;
|
|
122
|
+
saveToBytes: Uint8Array;
|
|
123
|
+
saveToPackage: Uint8Array;
|
|
124
|
+
exportToBytes: Uint8Array;
|
|
125
|
+
exportPageToBytes: Uint8Array;
|
|
126
|
+
snapshot: Uint8Array;
|
|
127
|
+
versionVector: Uint8Array;
|
|
128
|
+
patchSince: Uint8Array;
|
|
129
|
+
merge: undefined;
|
|
130
|
+
presence: Uint8Array;
|
|
131
|
+
mergePresence: undefined;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* A failure, as it crosses the thread boundary: an `Error` loses its class on
|
|
135
|
+
* the way, so the {@link UDocError} the session side rebuilds travels as its
|
|
136
|
+
* fields. A `crashed` one finishes the session — a wasm instance is not usable
|
|
137
|
+
* after a trap, since a panic aborts mid-call and can leave a session borrowed
|
|
138
|
+
* for good; after any other, the session is still good.
|
|
139
|
+
*/
|
|
140
|
+
export type WorkerFailure = Pick<UDocError, "code" | "message" | "detail">;
|
|
141
|
+
/** The worker's answer to a {@link WorkerRequest}. */
|
|
142
|
+
export type WorkerReply = {
|
|
143
|
+
id: number;
|
|
144
|
+
ok: true;
|
|
145
|
+
result: WorkerResult[keyof WorkerResult];
|
|
146
|
+
} | {
|
|
147
|
+
id: number;
|
|
148
|
+
ok: false;
|
|
149
|
+
failure: WorkerFailure;
|
|
150
|
+
};
|
|
151
|
+
//# sourceMappingURL=protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
|
package/dist/protocol.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AAAA,iEAAiE"}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import { Worker } from "node:worker_threads";
|
|
2
|
+
import type { Entitlements, ExportFormat, FileFormat, PageExportFormat, SaveStrategy, UDocType } from "@docmentis/udoc-wasm";
|
|
3
|
+
import { UDocError } from "@docmentis/udoc-wasm/error";
|
|
4
|
+
/** A server's answer to {@link UDocSession.requestRemoteCheckpoint}: the version of the baseline it wrote. */
|
|
5
|
+
export interface RemoteCheckpointResponse {
|
|
6
|
+
version: number;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* A session: one open document, driven on a worker thread of its own, so every
|
|
10
|
+
* call is asynchronous and none blocks the caller's event loop while the engine
|
|
11
|
+
* composes or rasterizes. As in the engine, the session is its document —
|
|
12
|
+
* opening one is the open, closing it is the close.
|
|
13
|
+
*
|
|
14
|
+
* The thread is held until {@link close}. An idle session does not keep the
|
|
15
|
+
* process alive; a call in flight does.
|
|
16
|
+
*/
|
|
17
|
+
export declare class UDocSession {
|
|
18
|
+
#private;
|
|
19
|
+
/**
|
|
20
|
+
* Settles once the session can take no more calls, with why: it was
|
|
21
|
+
* {@link close}d, or its engine crashed or its thread exited on its own —
|
|
22
|
+
* `crashed`. A host holding sessions watches this to let go of one that
|
|
23
|
+
* died.
|
|
24
|
+
*/
|
|
25
|
+
readonly closed: Promise<UDocError>;
|
|
26
|
+
/** Drive `worker`, which runs `worker.ts`. See {@link UDocSession.open}. */
|
|
27
|
+
constructor(worker: Worker);
|
|
28
|
+
/** The open document's doc type (`"portable"`, `"presentation"`, …). */
|
|
29
|
+
get docType(): UDocType | undefined;
|
|
30
|
+
/**
|
|
31
|
+
* The file format the document came from (`"pdf"`, `"pptx"`, …) — what
|
|
32
|
+
* saving it back means — or `undefined` for a package that recorded none.
|
|
33
|
+
*/
|
|
34
|
+
get sourceFormat(): FileFormat | undefined;
|
|
35
|
+
/**
|
|
36
|
+
* Whether the document was opened from a udoc package rather than
|
|
37
|
+
* imported from a file — which {@link sourceFormat} alone can't tell,
|
|
38
|
+
* since a package reports the format it recorded.
|
|
39
|
+
*/
|
|
40
|
+
get fromPackage(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Whether the document needs a password before it can be read — a PDF
|
|
43
|
+
* encrypted with a user password. Until {@link authenticate} unlocks it,
|
|
44
|
+
* every other call rejects; {@link docType} and {@link sourceFormat} are
|
|
45
|
+
* already known.
|
|
46
|
+
*/
|
|
47
|
+
get needsPassword(): boolean;
|
|
48
|
+
/**
|
|
49
|
+
* What the license, or with none the permit, entitled the session to — the
|
|
50
|
+
* `features` a host checks before a call that needs one (the sync calls
|
|
51
|
+
* need `collaboration`). Advisory: the engine enforces each at the call it
|
|
52
|
+
* guards, rejecting with a `notEntitled` {@link UDocError}.
|
|
53
|
+
*/
|
|
54
|
+
get entitlements(): Entitlements | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Unlock the document, which {@link needsPassword needs a password}, with
|
|
57
|
+
* `password` — its user or its owner password. Resolves `true` once it is
|
|
58
|
+
* open, and `false` when `password` is refused, the document waiting for
|
|
59
|
+
* another: try as often as it takes. Not a second open — no further permit
|
|
60
|
+
* is spent.
|
|
61
|
+
*/
|
|
62
|
+
authenticate(password: string): Promise<boolean>;
|
|
63
|
+
/**
|
|
64
|
+
* How many pages the document's primary plane has.
|
|
65
|
+
*
|
|
66
|
+
* A page is known only once it is composed, so this composes the whole
|
|
67
|
+
* plane — for a long flowing document, the cost of laying out all of it.
|
|
68
|
+
* Once paid it is not paid again: asking twice, or rendering any page
|
|
69
|
+
* after, reuses the composed pages. Rejects when a page fails to compose,
|
|
70
|
+
* since the count is then unknown.
|
|
71
|
+
*/
|
|
72
|
+
pageCount(): Promise<number>;
|
|
73
|
+
/**
|
|
74
|
+
* Save the document as `format`, faithfully — the bytes reopen as the same
|
|
75
|
+
* document. `format` is one of its doc type's own (a PDF saves to `"pdf"`, a
|
|
76
|
+
* presentation to `"pptx"`); {@link sourceFormat} is what saving it back
|
|
77
|
+
* means. `strategy` is how much of the file it was opened from, the
|
|
78
|
+
* original, the saved bytes keep: a `"delta"` or `"incremental"` save
|
|
79
|
+
* writes over it, which a session opened with `UDocNode.openRemote` doesn't
|
|
80
|
+
* hold; without it, the one keeping the most of it that `format` saves by
|
|
81
|
+
* (`"incremental"` for a PDF, `"rewrite"` for a CSV, a TSV, a PSV or an
|
|
82
|
+
* image, else `"delta"`). `delimiter` is the character a CSV's fields are
|
|
83
|
+
* split by; without it, the one the document was opened with, else a comma.
|
|
84
|
+
* Rejects for a format its doc type doesn't save to, a format that never
|
|
85
|
+
* saves by `strategy`, a delimiter for a format that takes none, no
|
|
86
|
+
* original to write over, or a save that isn't built yet.
|
|
87
|
+
*/
|
|
88
|
+
saveToBytes(format: FileFormat, strategy?: SaveStrategy, delimiter?: string): Promise<Uint8Array>;
|
|
89
|
+
/**
|
|
90
|
+
* Save the document as a udoc package — the bytes of a `.udoc` zip, which
|
|
91
|
+
* `UDocNode.open` reopens. It records the source format, so a reopened package
|
|
92
|
+
* can still be saved back to it. `version` makes it a checkpoint, baseline
|
|
93
|
+
* `v<version>`, which keeps the edit log a reopen replays; without it the
|
|
94
|
+
* package is a flat baseline — the whole document and no log.
|
|
95
|
+
*/
|
|
96
|
+
saveToPackage(version?: number): Promise<Uint8Array>;
|
|
97
|
+
/**
|
|
98
|
+
* Ask the udoc server the document was opened from (`UDocNode.openRemote`)
|
|
99
|
+
* for a copy of it, saved as its {@link sourceFormat} by `strategy`, else
|
|
100
|
+
* by the engine's for it — a `"delta"` or `"incremental"` copy is the
|
|
101
|
+
* server's to save, since only it holds the original. Resolves with the
|
|
102
|
+
* copy's bytes. Asked with the global
|
|
103
|
+
* `fetch`, not the one the open was given, which only reads. Rejects for a
|
|
104
|
+
* document not opened with `UDocNode.openRemote`, or one that records no source
|
|
105
|
+
* format, and with the server's message for what it refuses.
|
|
106
|
+
*/
|
|
107
|
+
requestRemoteCopy(strategy?: SaveStrategy): Promise<Uint8Array>;
|
|
108
|
+
/**
|
|
109
|
+
* Ask the udoc server the document was opened from (`UDocNode.openRemote`) to
|
|
110
|
+
* checkpoint it: save its document as a new baseline. Resolves with that
|
|
111
|
+
* baseline's version. Nothing reopens: this session goes on as it was.
|
|
112
|
+
* Asked with the global `fetch`, as {@link requestRemoteCopy} is. Rejects
|
|
113
|
+
* for a document not opened with `UDocNode.openRemote`, and with the server's
|
|
114
|
+
* message for what it refuses.
|
|
115
|
+
*/
|
|
116
|
+
requestRemoteCheckpoint(): Promise<RemoteCheckpointResponse>;
|
|
117
|
+
/**
|
|
118
|
+
* Export the whole document as `format` — a rendering of its laid-out
|
|
119
|
+
* pages, fixed and one-way. Rejects until PDF export is built.
|
|
120
|
+
*/
|
|
121
|
+
exportToBytes(format: ExportFormat): Promise<Uint8Array>;
|
|
122
|
+
/**
|
|
123
|
+
* Export page `index` (0-based) of the document's primary plane as
|
|
124
|
+
* `format` — `{ png: { scale } }`, where `scale` is output pixels per
|
|
125
|
+
* document point (`1` is 72 DPI).
|
|
126
|
+
*
|
|
127
|
+
* Composes the document through that page first — not past it. Rejects
|
|
128
|
+
* `notFound` when the document turns out to have fewer pages; its message
|
|
129
|
+
* is the page count.
|
|
130
|
+
*/
|
|
131
|
+
exportPageToBytes(index: number, format: PageExportFormat): Promise<Uint8Array>;
|
|
132
|
+
/**
|
|
133
|
+
* The document's whole editing state — every edit since its baseline — for
|
|
134
|
+
* a peer that has none of it, to {@link merge}. For a peer that has some,
|
|
135
|
+
* {@link patchSince} sends only the rest.
|
|
136
|
+
*/
|
|
137
|
+
snapshot(): Promise<Uint8Array>;
|
|
138
|
+
/**
|
|
139
|
+
* Which edits this session holds, as the token a peer's {@link patchSince}
|
|
140
|
+
* takes to answer with only the ones this session lacks.
|
|
141
|
+
*/
|
|
142
|
+
versionVector(): Promise<Uint8Array>;
|
|
143
|
+
/**
|
|
144
|
+
* The edits this session holds that a peer — named by its
|
|
145
|
+
* {@link versionVector} — lacks, for that peer's {@link merge}.
|
|
146
|
+
*/
|
|
147
|
+
patchSince(peer: Uint8Array): Promise<Uint8Array>;
|
|
148
|
+
/**
|
|
149
|
+
* Apply a peer's edits — its {@link snapshot} or {@link patchSince} — to the
|
|
150
|
+
* document. Edits this session already holds are skipped, so merging the
|
|
151
|
+
* same patch twice changes nothing the second time. Rejects when the bytes
|
|
152
|
+
* aren't a patch.
|
|
153
|
+
*/
|
|
154
|
+
merge(patch: Uint8Array): Promise<void>;
|
|
155
|
+
/**
|
|
156
|
+
* Every peer's presence this session knows of — each one's selection and
|
|
157
|
+
* name — for a peer's {@link mergePresence}. Transient: no history, never
|
|
158
|
+
* part of a save.
|
|
159
|
+
*/
|
|
160
|
+
presence(): Promise<Uint8Array>;
|
|
161
|
+
/** Take in a peer's {@link UDocSession.presence}, each peer's latest winning. */
|
|
162
|
+
mergePresence(presence: Uint8Array): Promise<void>;
|
|
163
|
+
/** Release the document and its thread. Calls still in flight reject. */
|
|
164
|
+
close(): Promise<void>;
|
|
165
|
+
}
|
|
166
|
+
/** The whole body `url` answers with, or a throw saying why it didn't come. */
|
|
167
|
+
export declare function fetchWhole(url: string): Promise<Uint8Array>;
|
|
168
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../src/session.ts"],"names":[],"mappings":"AAOA,OAAO,EAAkB,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAG7D,OAAO,KAAK,EACR,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,YAAY,EACZ,QAAQ,EACX,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAiCvD,8GAA8G;AAC9G,MAAM,WAAW,wBAAwB;IACrC,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,qBAAa,WAAW;;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC;IAkGpC,4EAA4E;gBAChE,MAAM,EAAE,MAAM;IAiB1B,wEAAwE;IACxE,IAAI,OAAO,IAAI,QAAQ,GAAG,SAAS,CAElC;IAED;;;OAGG;IACH,IAAI,YAAY,IAAI,UAAU,GAAG,SAAS,CAEzC;IAED;;;;OAIG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;;;;OAKG;IACH,IAAI,aAAa,IAAI,OAAO,CAE3B;IAED;;;;;OAKG;IACH,IAAI,YAAY,IAAI,YAAY,GAAG,SAAS,CAE3C;IAED;;;;;;OAMG;IACG,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAMtD;;;;;;;;OAQG;IACH,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC;IAI5B;;;;;;;;;;;;;;OAcG;IACH,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAUjG;;;;;;OAMG;IACH,aAAa,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAYpD;;;;;;;;;OASG;IACG,iBAAiB,CAAC,QAAQ,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAcrE;;;;;;;OAOG;IACG,uBAAuB,IAAI,OAAO,CAAC,wBAAwB,CAAC;IAkBlE;;;OAGG;IACH,aAAa,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAIxD;;;;;;;;OAQG;IACH,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,UAAU,CAAC;IAiB/E;;;;OAIG;IACH,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAI/B;;;OAGG;IACH,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC;IAIpC;;;OAGG;IACH,UAAU,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IAIjD;;;;;OAKG;IACH,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC;;;;OAIG;IACH,QAAQ,IAAI,OAAO,CAAC,UAAU,CAAC;IAI/B,iFAAiF;IACjF,aAAa,CAAC,QAAQ,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,yEAAyE;IACnE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAiD/B;AA6DD,+EAA+E;AAC/E,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAIjE"}
|