@docmentis/udoc-server 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.
Files changed (53) hide show
  1. package/LICENSE-APACHE +202 -0
  2. package/LICENSE-MIT +21 -0
  3. package/README.md +41 -2
  4. package/config.example.toml +26 -0
  5. package/dist/collaboration.d.ts +25 -0
  6. package/dist/collaboration.d.ts.map +1 -0
  7. package/dist/collaboration.js +348 -0
  8. package/dist/collaboration.js.map +1 -0
  9. package/dist/config.d.ts +30 -0
  10. package/dist/config.d.ts.map +1 -0
  11. package/dist/config.js +87 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/document.d.ts +29 -0
  14. package/dist/document.d.ts.map +1 -0
  15. package/dist/document.js +308 -0
  16. package/dist/document.js.map +1 -0
  17. package/dist/http.d.ts +44 -0
  18. package/dist/http.d.ts.map +1 -0
  19. package/dist/http.js +96 -0
  20. package/dist/http.js.map +1 -0
  21. package/dist/index.d.ts +5 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +3 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/main.d.ts +3 -0
  26. package/dist/main.d.ts.map +1 -0
  27. package/dist/main.js +105 -0
  28. package/dist/main.js.map +1 -0
  29. package/dist/package.d.ts +5 -0
  30. package/dist/package.d.ts.map +1 -0
  31. package/dist/package.js +116 -0
  32. package/dist/package.js.map +1 -0
  33. package/dist/route.d.ts +56 -0
  34. package/dist/route.d.ts.map +1 -0
  35. package/dist/route.js +126 -0
  36. package/dist/route.js.map +1 -0
  37. package/dist/server.d.ts +45 -0
  38. package/dist/server.d.ts.map +1 -0
  39. package/dist/server.js +103 -0
  40. package/dist/server.js.map +1 -0
  41. package/dist/session-pool.d.ts +19 -0
  42. package/dist/session-pool.d.ts.map +1 -0
  43. package/dist/session-pool.js +95 -0
  44. package/dist/session-pool.js.map +1 -0
  45. package/dist/store.d.ts +115 -0
  46. package/dist/store.d.ts.map +1 -0
  47. package/dist/store.js +441 -0
  48. package/dist/store.js.map +1 -0
  49. package/dist/version.d.ts +2 -0
  50. package/dist/version.d.ts.map +1 -0
  51. package/dist/version.js +10 -0
  52. package/dist/version.js.map +1 -0
  53. package/package.json +76 -5
package/dist/store.js ADDED
@@ -0,0 +1,441 @@
1
+ // Where udoc-server keeps each document between sessions.
2
+ //
3
+ // A document is kept as its original — the upload, byte for byte, in the
4
+ // format it was imported as — and its checkpoints, each the udoc package one
5
+ // checkpoint saved: `v0`, the baseline its import produced with every id
6
+ // already minted, then one more each time it is checkpointed
7
+ // (docs/design/core-save.md). Every later session reopens the latest.
8
+ //
9
+ // The latest checkpoint is also read an entry at a time, for streaming: its
10
+ // description, a part, a blob, each addressed by its route — the server API's
11
+ // own terms (see docs/design/node-streaming.md), which a store maps to
12
+ // wherever it keeps them. A part or a blob is read deflated, the form it is
13
+ // sent in.
14
+ //
15
+ // Once the document is edited, it also has an edit log: every edit made, which
16
+ // is a package's own `crdt` entity — opening applies it — but kept apart from
17
+ // the checkpoints, because it is written on every edit and a checkpoint only
18
+ // once. It holds every edit since the import, so it replays over any
19
+ // checkpoint, and a checkpoint leaves it as it is.
20
+ //
21
+ // An edit that inserts a picture also brings the picture's image: an opaque
22
+ // part, whose id the edit log carries but not its content
23
+ // (docs/design/core-editor-opaque-part.md). Each such part, and each blob it
24
+ // carries, is kept beside the checkpoints by its route — written once, since
25
+ // an opaque part never changes and a blob's key is its content — until a
26
+ // checkpoint holds it.
27
+ import { randomUUID } from "node:crypto";
28
+ import { link, mkdir, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
29
+ import { dirname, join } from "node:path";
30
+ import { buffer } from "node:stream/consumers";
31
+ import { promisify } from "node:util";
32
+ import { deflateRaw } from "node:zlib";
33
+ import { UDocError, isFileFormat } from "@docmentis/udoc-node";
34
+ import { fromBufferPromise, openPromise } from "yauzl";
35
+ /**
36
+ * A route's segments under `…/package` (docs/design/node-streaming.md): a
37
+ * part's kind in kebab-case and plural, its id's key — `replica-counter` in
38
+ * hex — and a blob's key. A route is held to them before it reaches a store,
39
+ * so none names a path outside.
40
+ */
41
+ export const KINDS = /[a-z0-9]+(?:-[a-z0-9]+)*/;
42
+ export const PART_ID = /[0-9a-f]+-[0-9a-f]+/;
43
+ export const BLOB_KEY = /[0-9a-f]+/;
44
+ /** An id that is safe as a file name. No dot, so no id can name a staged write. */
45
+ const FILE_SAFE_ID = /^[A-Za-z0-9_-]+$/;
46
+ /**
47
+ * A document's original is `original.<format>`; its checkpoints are
48
+ * `checkpoints/v<version>.udoc`, the latest the highest; its edit log, once it
49
+ * has one, is `crdt.loro`, the name a package's own entry for it has.
50
+ */
51
+ const ORIGINAL = "original";
52
+ const CHECKPOINTS_DIR = "checkpoints";
53
+ const CHECKPOINT_FILE = /^v(\d+)\.udoc$/;
54
+ const LOG_FILE = "crdt.loro";
55
+ /**
56
+ * Where the opaque parts edits brought are kept, each deflated at
57
+ * `opaque-parts/<kinds>/<partId>`; the blobs they carry are at `blobs/<key>`.
58
+ */
59
+ const OPAQUE_PARTS_DIR = "opaque-parts";
60
+ const BLOBS_DIR = "blobs";
61
+ /**
62
+ * A part's entry in a package, `parts/<snake_kind>_<id-key>.json`, and a
63
+ * blob's, `blobs/<key>` with whatever extension it was written with. The key
64
+ * holds no `_`, so the kind is everything before the last one.
65
+ */
66
+ const PART_ENTRY = new RegExp(`^parts/([a-z0-9]+(?:_[a-z0-9]+)*)_(${PART_ID.source})\\.json$`);
67
+ const BLOB_ENTRY = new RegExp(`^blobs/(${BLOB_KEY.source})(?:\\.[^/]*)?$`);
68
+ /** The compression method of a zip entry kept deflated. */
69
+ const DEFLATE = 8;
70
+ const deflate = promisify(deflateRaw);
71
+ /**
72
+ * A {@link DocumentStore} over a directory: one directory per document, named
73
+ * by its id, holding its original, its checkpoints and its edit log.
74
+ */
75
+ export class DirectoryDocumentStore {
76
+ #directory;
77
+ constructor(directory) {
78
+ this.#directory = directory;
79
+ }
80
+ async put(id, document) {
81
+ const path = this.#path(id);
82
+ await mkdir(this.#directory, { recursive: true });
83
+ // Both are written into a directory aside and renamed into place
84
+ // together, so a reader never meets half a document, and a crash
85
+ // mid-write leaves none. A directory can't be renamed over one that
86
+ // holds files, so an id already kept stays as it was.
87
+ const staged = `${path}.${randomUUID()}.partial`;
88
+ try {
89
+ await mkdir(staged);
90
+ await writeFile(join(staged, `${ORIGINAL}.${document.original.format}`), document.original.bytes);
91
+ await mkdir(join(staged, CHECKPOINTS_DIR));
92
+ await writeFile(join(staged, CHECKPOINTS_DIR, "v0.udoc"), document.checkpoint);
93
+ await rename(staged, path);
94
+ }
95
+ catch (error) {
96
+ await rm(staged, { recursive: true, force: true });
97
+ throw error;
98
+ }
99
+ }
100
+ async getOriginal(id) {
101
+ const path = this.#path(id);
102
+ let names;
103
+ try {
104
+ names = await readdir(path);
105
+ }
106
+ catch (error) {
107
+ if (isNotFound(error))
108
+ return undefined;
109
+ throw error;
110
+ }
111
+ for (const name of names) {
112
+ const format = name.startsWith(`${ORIGINAL}.`) ? name.slice(ORIGINAL.length + 1) : undefined;
113
+ if (format !== undefined && isFileFormat(format)) {
114
+ return { bytes: await readFile(join(path, name)), format };
115
+ }
116
+ }
117
+ throw new Error(`document ${id} is kept without its original`);
118
+ }
119
+ async getCheckpoint(id) {
120
+ const [latest] = await this.#checkpoints(id);
121
+ return latest === undefined ? undefined : readFile(latest);
122
+ }
123
+ async putCheckpoint(id, version, checkpoint) {
124
+ const path = this.#path(id);
125
+ const kept = join(path, CHECKPOINTS_DIR, `v${version}.udoc`);
126
+ // Written aside, then linked into place, which refuses a version kept
127
+ // already: once there, it is the latest, whole.
128
+ const staged = `${kept}.${randomUUID()}.partial`;
129
+ try {
130
+ await writeFile(staged, checkpoint, { flag: "wx" });
131
+ await link(staged, kept);
132
+ }
133
+ catch (error) {
134
+ if (isNotFound(error))
135
+ throw new Error(`no document ${JSON.stringify(id)} with checkpoints is kept`);
136
+ if (isAlreadyKept(error))
137
+ throw new Error(`document ${JSON.stringify(id)} keeps checkpoint v${version} already`);
138
+ throw error;
139
+ }
140
+ finally {
141
+ await rm(staged, { force: true });
142
+ }
143
+ // What it holds is served from it now. Forgotten only after it is in
144
+ // place, so a crash between leaves an opaque part kept twice, never
145
+ // one kept nowhere.
146
+ const zip = await fromBufferPromise(Buffer.from(checkpoint.buffer, checkpoint.byteOffset, checkpoint.byteLength), {
147
+ lazyEntries: true,
148
+ });
149
+ try {
150
+ for await (const entry of zip.eachEntry()) {
151
+ const route = keptRouteOf(entry.fileName);
152
+ if (route !== undefined)
153
+ await rm(join(path, route), { force: true });
154
+ }
155
+ }
156
+ finally {
157
+ zip.close();
158
+ }
159
+ }
160
+ async getDescription(id) {
161
+ const metadata = await this.#readCheckpointEntry(id, "");
162
+ if (!metadata)
163
+ return undefined;
164
+ // The checkpoint's own envelope, written by the engine this server runs.
165
+ // Every number is read whole, as a `bigint`, so a frontier's peers
166
+ // keep every bit.
167
+ const { documentType, sourceFormat, sourceDelimiter, baselineVersion, baselineFrontier } = JSON.parse(new TextDecoder().decode(metadata), (_key, value, context) => typeof value === "number" && context?.source !== undefined ? BigInt(context.source) : value);
168
+ const frontier = baselineFrontier ?? ((await this.#hasLog(id)) ? [] : undefined);
169
+ return {
170
+ docType: documentType,
171
+ ...(sourceFormat !== undefined ? { sourceFormat } : {}),
172
+ ...(sourceDelimiter !== undefined ? { sourceDelimiter } : {}),
173
+ baselineVersion: Number(baselineVersion),
174
+ ...(frontier !== undefined ? { baselineFrontier: frontier } : {}),
175
+ };
176
+ }
177
+ async getPart(id, kinds, partId) {
178
+ return this.#readPart(id, `${kinds}/${partId}`, join(OPAQUE_PARTS_DIR, kinds, partId));
179
+ }
180
+ async getBlob(id, key) {
181
+ return this.#readPart(id, `blobs/${key}`, join(BLOBS_DIR, key));
182
+ }
183
+ /**
184
+ * Document `id`'s part or blob at `route`, deflated: its latest
185
+ * checkpoint's; else the one kept beside the checkpoints at `kept`; else
186
+ * the newest earlier checkpoint's that has it. Once a checkpoint holds an
187
+ * opaque part, it is kept beside them no longer, and a later checkpoint
188
+ * holds it only if something showed it then — yet an undo can show it
189
+ * again.
190
+ */
191
+ async #readPart(id, route, kept) {
192
+ const [latest, ...earlier] = await this.#checkpoints(id);
193
+ if (latest !== undefined) {
194
+ const entry = await this.#readEntry(latest, route, true);
195
+ if (entry)
196
+ return entry;
197
+ }
198
+ const keptBeside = await this.#readKept(id, kept);
199
+ if (keptBeside)
200
+ return keptBeside;
201
+ for (const checkpoint of earlier) {
202
+ const entry = await this.#readEntry(checkpoint, route, true);
203
+ if (entry)
204
+ return entry;
205
+ }
206
+ return undefined;
207
+ }
208
+ async putOpaqueParts(id, parts) {
209
+ const path = this.#path(id);
210
+ // Nothing here creates the document's directory, so a document
211
+ // forgotten meanwhile stays forgotten.
212
+ try {
213
+ await stat(path);
214
+ }
215
+ catch (error) {
216
+ if (isNotFound(error))
217
+ throw new UDocError("notFound", `no document ${JSON.stringify(id)} is kept`);
218
+ throw error;
219
+ }
220
+ // Sent by a client: bytes that aren't a zip are its to answer for.
221
+ const zip = await fromBufferPromise(Buffer.from(parts.buffer, parts.byteOffset, parts.byteLength), {
222
+ lazyEntries: true,
223
+ }).catch((error) => {
224
+ const reason = error instanceof Error ? error.message : String(error);
225
+ throw new UDocError("malformed", `the opaque parts aren't a zip: ${reason}`, undefined, { cause: error });
226
+ });
227
+ try {
228
+ for await (const entry of zip.eachEntry()) {
229
+ const route = keptRouteOf(entry.fileName);
230
+ if (route === undefined)
231
+ continue;
232
+ const kept = join(path, route);
233
+ await mkdir(dirname(kept), { recursive: true });
234
+ // Written aside and renamed into place, so a reader meets the
235
+ // whole entry or none. A route names its content, so one kept
236
+ // already is the same bytes, renamed over.
237
+ const staged = `${kept}.${randomUUID()}.partial`;
238
+ try {
239
+ await writeFile(staged, await deflatedEntry(zip, entry), { flag: "wx" });
240
+ await rename(staged, kept);
241
+ }
242
+ catch (error) {
243
+ await rm(staged, { force: true });
244
+ throw error;
245
+ }
246
+ }
247
+ }
248
+ finally {
249
+ zip.close();
250
+ }
251
+ }
252
+ /** The file kept at `route` beside document `id`'s checkpoints, or `undefined` when there is none. */
253
+ async #readKept(id, route) {
254
+ try {
255
+ return await readFile(join(this.#path(id), route));
256
+ }
257
+ catch (error) {
258
+ if (isNotFound(error))
259
+ return undefined;
260
+ throw error;
261
+ }
262
+ }
263
+ /** The paths of document `id`'s checkpoints, the latest first; none when it has none. */
264
+ async #checkpoints(id) {
265
+ const directory = join(this.#path(id), CHECKPOINTS_DIR);
266
+ let names;
267
+ try {
268
+ names = await readdir(directory);
269
+ }
270
+ catch (error) {
271
+ if (isNotFound(error))
272
+ return [];
273
+ throw error;
274
+ }
275
+ return names
276
+ .flatMap((name) => {
277
+ const version = CHECKPOINT_FILE.exec(name)?.[1];
278
+ return version === undefined ? [] : [{ version: Number(version), path: join(directory, name) }];
279
+ })
280
+ .sort((a, b) => b.version - a.version)
281
+ .map(({ path }) => path);
282
+ }
283
+ /**
284
+ * The entry of document `id`'s latest checkpoint at `route`, read as
285
+ * `#readEntry` reads one, or `undefined` when it has none or there is no
286
+ * checkpoint.
287
+ */
288
+ async #readCheckpointEntry(id, route, deflated = false) {
289
+ const [latest] = await this.#checkpoints(id);
290
+ return latest === undefined ? undefined : this.#readEntry(latest, route, deflated);
291
+ }
292
+ /**
293
+ * The entry of the checkpoint at `checkpoint` at `route` (see
294
+ * {@link routeOf}), or `undefined` when it has none. Reads the zip's
295
+ * central directory and that one entry: inflated, or — `deflated` — as the
296
+ * zip keeps it, deflated, so nothing is compressed again; one kept stored
297
+ * is deflated now.
298
+ */
299
+ async #readEntry(checkpoint, route, deflated = false) {
300
+ let zip;
301
+ try {
302
+ zip = await openPromise(checkpoint, { lazyEntries: true, autoClose: false });
303
+ }
304
+ catch (error) {
305
+ if (isNotFound(error))
306
+ return undefined;
307
+ throw error;
308
+ }
309
+ try {
310
+ for await (const entry of zip.eachEntry()) {
311
+ if (routeOf(entry.fileName) !== route)
312
+ continue;
313
+ if (deflated && entry.compressionMethod === DEFLATE) {
314
+ return await buffer(await zip.openReadStreamPromise(entry, { decodeFileData: false }));
315
+ }
316
+ const bytes = await buffer(await zip.openReadStreamPromise(entry));
317
+ return deflated ? await deflate(bytes) : bytes;
318
+ }
319
+ return undefined;
320
+ }
321
+ finally {
322
+ zip.close();
323
+ }
324
+ }
325
+ async getLog(id) {
326
+ try {
327
+ return await readFile(join(this.#path(id), LOG_FILE));
328
+ }
329
+ catch (error) {
330
+ if (!isNotFound(error))
331
+ throw error;
332
+ }
333
+ return this.#readCheckpointEntry(id, LOG_FILE);
334
+ }
335
+ async putLog(id, log) {
336
+ const path = join(this.#path(id), LOG_FILE);
337
+ // Written aside and renamed over the one kept, so a reader meets the old
338
+ // log or the new, never part of one. Neither creates the document's
339
+ // directory, so a document forgotten meanwhile stays forgotten.
340
+ const staged = `${path}.${randomUUID()}.partial`;
341
+ try {
342
+ await writeFile(staged, log, { flag: "wx" });
343
+ await rename(staged, path);
344
+ }
345
+ catch (error) {
346
+ await rm(staged, { force: true });
347
+ if (isNotFound(error))
348
+ throw new Error(`no document ${JSON.stringify(id)} is kept`);
349
+ throw error;
350
+ }
351
+ }
352
+ async #hasLog(id) {
353
+ try {
354
+ await stat(join(this.#path(id), LOG_FILE));
355
+ return true;
356
+ }
357
+ catch (error) {
358
+ if (isNotFound(error))
359
+ return false;
360
+ throw error;
361
+ }
362
+ }
363
+ async delete(id) {
364
+ try {
365
+ await rm(this.#path(id), { recursive: true });
366
+ return true;
367
+ }
368
+ catch (error) {
369
+ if (isNotFound(error))
370
+ return false;
371
+ throw error;
372
+ }
373
+ }
374
+ #path(id) {
375
+ if (!FILE_SAFE_ID.test(id))
376
+ throw new Error(`not a document id: ${JSON.stringify(id)}`);
377
+ return join(this.#directory, id);
378
+ }
379
+ }
380
+ /**
381
+ * The route a package entry is served at, relative to the package: `""` for
382
+ * `metadata.json`, `<kinds>/<partId>` for a part, `blobs/<key>` for a blob,
383
+ * `crdt.loro` for the edit log, and `undefined` for anything not served.
384
+ */
385
+ function routeOf(entry) {
386
+ if (entry === "metadata.json")
387
+ return "";
388
+ if (entry === LOG_FILE)
389
+ return LOG_FILE;
390
+ const part = PART_ENTRY.exec(entry);
391
+ if (part)
392
+ return `${pluralKebab(part[1])}/${part[2]}`;
393
+ const blob = BLOB_ENTRY.exec(entry);
394
+ if (blob)
395
+ return `blobs/${blob[1]}`;
396
+ return undefined;
397
+ }
398
+ /**
399
+ * Where an entry of an `opaque parts` zip is kept, relative to the document's
400
+ * directory: a part's entry at `opaque-parts/<kinds>/<partId>`, and a blob at
401
+ * `blobs/<key>`. Anything else — the zip's own list of what it carries — is not
402
+ * kept. Every segment is checked against its pattern, so no entry names a path
403
+ * outside.
404
+ */
405
+ function keptRouteOf(entry) {
406
+ const part = PART_ENTRY.exec(entry);
407
+ if (part)
408
+ return join(OPAQUE_PARTS_DIR, pluralKebab(part[1]), part[2]);
409
+ const blob = BLOB_ENTRY.exec(entry);
410
+ if (blob)
411
+ return join(BLOBS_DIR, blob[1]);
412
+ return undefined;
413
+ }
414
+ /** `entry` of `zip`, deflated: as the zip keeps it when it keeps it deflated, else deflated now. */
415
+ async function deflatedEntry(zip, entry) {
416
+ if (entry.compressionMethod === DEFLATE) {
417
+ return buffer(await zip.openReadStreamPromise(entry, { decodeFileData: false }));
418
+ }
419
+ return deflate(await buffer(await zip.openReadStreamPromise(entry)));
420
+ }
421
+ /**
422
+ * A kind's route segment from its snake_case entry name: kebab-case, plural. A
423
+ * kind already plural stays as it is, and so does a `…data` kind, whose noun is
424
+ * uncounted — the rule the engine's `RemotePackageLoader` applies to the same
425
+ * kind (docs/design/node-streaming.md).
426
+ */
427
+ function pluralKebab(snakeKind) {
428
+ const kebab = snakeKind.replaceAll("_", "-");
429
+ const uncounted = kebab.endsWith("s") || kebab.split("-").at(-1) === "data";
430
+ return uncounted ? kebab : `${kebab}s`;
431
+ }
432
+ function isNotFound(error) {
433
+ return codeOf(error) === "ENOENT";
434
+ }
435
+ function isAlreadyKept(error) {
436
+ return codeOf(error) === "EEXIST";
437
+ }
438
+ function codeOf(error) {
439
+ return typeof error === "object" && error !== null ? error.code : undefined;
440
+ }
441
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.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"}
package/package.json CHANGED
@@ -1,6 +1,77 @@
1
1
  {
2
- "name": "@docmentis/udoc-server",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
2
+ "name": "@docmentis/udoc-server",
3
+ "version": "0.8.0",
4
+ "description": "Self-hosted document server for remote access, rendering, and collaboration.",
5
+ "keywords": [
6
+ "document-server",
7
+ "server",
8
+ "http",
9
+ "websocket",
10
+ "collaboration",
11
+ "real-time",
12
+ "document",
13
+ "pdf",
14
+ "docx",
15
+ "pptx",
16
+ "xlsx",
17
+ "word",
18
+ "powerpoint",
19
+ "excel",
20
+ "office",
21
+ "render",
22
+ "docmentis",
23
+ "udoc",
24
+ "webassembly",
25
+ "wasm"
26
+ ],
27
+ "homepage": "https://www.docmentis.com/docs",
28
+ "license": "MIT OR Apache-2.0",
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "git+https://github.com/docMentis/docmentis-udoc.git",
32
+ "directory": "packages/udoc-server"
33
+ },
34
+ "type": "module",
35
+ "files": [
36
+ "dist",
37
+ "config.example.toml",
38
+ "LICENSE-MIT",
39
+ "LICENSE-APACHE"
40
+ ],
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "main": "./dist/index.js",
45
+ "types": "./dist/index.d.ts",
46
+ "exports": {
47
+ ".": {
48
+ "types": "./dist/index.d.ts",
49
+ "import": "./dist/index.js"
50
+ }
51
+ },
52
+ "bin": {
53
+ "udoc-server": "dist/main.js"
54
+ },
55
+ "engines": {
56
+ "node": ">=22.18"
57
+ },
58
+ "scripts": {
59
+ "dev": "tsc -p tsconfig.json --watch",
60
+ "build": "npm run clean && node scripts/check-version.mjs && tsc -p tsconfig.json && chmod +x dist/main.js",
61
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
62
+ "test": "node --test \"test/**/*.test.ts\"",
63
+ "clean": "rm -rf dist"
64
+ },
65
+ "dependencies": {
66
+ "@docmentis/udoc-node": "0.8.0",
67
+ "smol-toml": "^1.9.0",
68
+ "ws": "^8.21.3",
69
+ "yauzl": "^3.4.0"
70
+ },
71
+ "devDependencies": {
72
+ "@types/ws": "^8.18.1",
73
+ "@types/yauzl": "^3.4.0",
74
+ "@types/yazl": "^3.3.1",
75
+ "yazl": "^3.3.1"
76
+ }
77
+ }