wiki-graph-sdk 0.9.4 → 0.9.5

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 (52) hide show
  1. package/dist/archives.cjs +237 -28
  2. package/dist/archives.cjs.map +1 -1
  3. package/dist/archives.d.ts +1 -1
  4. package/dist/archives.js +240 -28
  5. package/dist/archives.js.map +1 -1
  6. package/dist/conversions.cjs +64 -28
  7. package/dist/conversions.cjs.map +1 -1
  8. package/dist/conversions.js +64 -28
  9. package/dist/conversions.js.map +1 -1
  10. package/dist/default-worker.cjs +64 -28
  11. package/dist/default-worker.cjs.map +1 -1
  12. package/dist/default-worker.js +64 -28
  13. package/dist/default-worker.js.map +1 -1
  14. package/dist/embedding.cjs +64 -28
  15. package/dist/embedding.cjs.map +1 -1
  16. package/dist/embedding.js +64 -28
  17. package/dist/embedding.js.map +1 -1
  18. package/dist/gc.cjs +64 -28
  19. package/dist/gc.cjs.map +1 -1
  20. package/dist/gc.js +64 -28
  21. package/dist/gc.js.map +1 -1
  22. package/dist/{index-DQzLAnjf.d.ts → index-4YX4dv6Y.d.ts} +38 -2
  23. package/dist/index.cjs +240 -31
  24. package/dist/index.cjs.map +1 -1
  25. package/dist/index.d.ts +3 -3
  26. package/dist/index.js +243 -31
  27. package/dist/index.js.map +1 -1
  28. package/dist/local-config.cjs +64 -28
  29. package/dist/local-config.cjs.map +1 -1
  30. package/dist/local-config.js +64 -28
  31. package/dist/local-config.js.map +1 -1
  32. package/dist/maintenance.cjs +64 -28
  33. package/dist/maintenance.cjs.map +1 -1
  34. package/dist/maintenance.js +64 -28
  35. package/dist/maintenance.js.map +1 -1
  36. package/dist/node-platform.cjs +64 -28
  37. package/dist/node-platform.cjs.map +1 -1
  38. package/dist/node-platform.js +64 -28
  39. package/dist/node-platform.js.map +1 -1
  40. package/dist/runtime-config.cjs +64 -28
  41. package/dist/runtime-config.cjs.map +1 -1
  42. package/dist/runtime-config.js +64 -28
  43. package/dist/runtime-config.js.map +1 -1
  44. package/dist/stage.cjs +64 -28
  45. package/dist/stage.cjs.map +1 -1
  46. package/dist/stage.js +64 -28
  47. package/dist/stage.js.map +1 -1
  48. package/dist/worker.cjs +64 -28
  49. package/dist/worker.cjs.map +1 -1
  50. package/dist/worker.js +64 -28
  51. package/dist/worker.js.map +1 -1
  52. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -152,6 +152,7 @@ var import_os3 = require("os");
152
152
  var import_path5 = require("path");
153
153
  var import_stream = require("stream");
154
154
  var import_wiki_graph_core7 = require("wiki-graph-core");
155
+ var import_platform2 = require("wiki-graph-core/platform");
155
156
 
156
157
  // src/conversions.ts
157
158
  var import_crypto = require("crypto");
@@ -258,7 +259,7 @@ var NodeFile = class {
258
259
  }
259
260
  path;
260
261
  async getPhysicalIdentity() {
261
- const value = await fsPromises.stat(this.path).catch((error) => {
262
+ const value = await fsPromises.stat(toNodeFilesystemPath(this.path)).catch((error) => {
262
263
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
263
264
  return void 0;
264
265
  throw error;
@@ -271,7 +272,7 @@ var NodeFile = class {
271
272
  identity;
272
273
  name;
273
274
  async openReader() {
274
- const handle = await fsPromises.open(this.path, "r");
275
+ const handle = await fsPromises.open(toNodeFilesystemPath(this.path), "r");
275
276
  let closed = false;
276
277
  try {
277
278
  const stats = await handle.stat();
@@ -311,7 +312,7 @@ var NodeFile = class {
311
312
  }
312
313
  async getLastModified() {
313
314
  try {
314
- return (await fsPromises.stat(this.path)).mtimeMs;
315
+ return (await fsPromises.stat(toNodeFilesystemPath(this.path))).mtimeMs;
315
316
  } catch (error) {
316
317
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
317
318
  return void 0;
@@ -320,9 +321,14 @@ var NodeFile = class {
320
321
  }
321
322
  }
322
323
  async openWriter() {
323
- await fsPromises.mkdir(pathModule.dirname(this.path), { recursive: true });
324
+ await fsPromises.mkdir(
325
+ toNodeFilesystemPath(pathModule.dirname(this.path)),
326
+ {
327
+ recursive: true
328
+ }
329
+ );
324
330
  const temporary = `${this.path}.tmp-${crypto.randomUUID()}`;
325
- const handle = await fsPromises.open(temporary, "wx");
331
+ const handle = await fsPromises.open(toNodeFilesystemPath(temporary), "wx");
326
332
  let closed = false;
327
333
  return {
328
334
  write: async (data) => {
@@ -337,14 +343,17 @@ var NodeFile = class {
337
343
  commit: async () => {
338
344
  if (!closed) {
339
345
  await handle.close();
340
- await fsPromises.rename(temporary, this.path);
346
+ await fsPromises.rename(
347
+ toNodeFilesystemPath(temporary),
348
+ toNodeFilesystemPath(this.path)
349
+ );
341
350
  }
342
351
  closed = true;
343
352
  },
344
353
  abort: async () => {
345
354
  if (!closed) {
346
355
  await handle.close();
347
- await fsPromises.rm(temporary, { force: true });
356
+ await fsPromises.rm(toNodeFilesystemPath(temporary), { force: true });
348
357
  }
349
358
  closed = true;
350
359
  }
@@ -391,7 +400,7 @@ var NodeDirectory = class _NodeDirectory {
391
400
  }
392
401
  path;
393
402
  async getPhysicalIdentity() {
394
- const value = await fsPromises.stat(this.path).catch((error) => {
403
+ const value = await fsPromises.stat(toNodeFilesystemPath(this.path)).catch((error) => {
395
404
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
396
405
  return void 0;
397
406
  throw error;
@@ -407,7 +416,7 @@ var NodeDirectory = class _NodeDirectory {
407
416
  assertChildName(name);
408
417
  const file = new NodeFile(pathModule.join(this.path, name));
409
418
  try {
410
- return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
419
+ return (await fsPromises.stat(toNodeFilesystemPath(file.path))).isFile() ? file : void 0;
411
420
  } catch (error) {
412
421
  if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
413
422
  return void 0;
@@ -416,7 +425,7 @@ var NodeDirectory = class _NodeDirectory {
416
425
  }
417
426
  async getLastModified() {
418
427
  try {
419
- return (await fsPromises.stat(this.path)).mtimeMs;
428
+ return (await fsPromises.stat(toNodeFilesystemPath(this.path))).mtimeMs;
420
429
  } catch (error) {
421
430
  if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
422
431
  return void 0;
@@ -428,7 +437,7 @@ var NodeDirectory = class _NodeDirectory {
428
437
  assertChildName(name);
429
438
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
430
439
  try {
431
- return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
440
+ return (await fsPromises.stat(toNodeFilesystemPath(directory.path))).isDirectory() ? directory : void 0;
432
441
  } catch (error) {
433
442
  if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
434
443
  return void 0;
@@ -436,7 +445,7 @@ var NodeDirectory = class _NodeDirectory {
436
445
  }
437
446
  }
438
447
  async list() {
439
- const entries = await fsPromises.readdir(this.path, {
448
+ const entries = await fsPromises.readdir(toNodeFilesystemPath(this.path), {
440
449
  withFileTypes: true
441
450
  });
442
451
  return entries.map(
@@ -445,26 +454,45 @@ var NodeDirectory = class _NodeDirectory {
445
454
  }
446
455
  async createFile(name) {
447
456
  assertChildName(name);
448
- await fsPromises.mkdir(this.path, { recursive: true });
457
+ await fsPromises.mkdir(toNodeFilesystemPath(this.path), {
458
+ recursive: true
459
+ });
449
460
  const file = new NodeFile(pathModule.join(this.path, name));
450
- await fsPromises.writeFile(file.path, "", { flag: "wx" });
461
+ await fsPromises.writeFile(toNodeFilesystemPath(file.path), "", {
462
+ flag: "wx"
463
+ });
451
464
  return file;
452
465
  }
453
466
  async createDirectory(name) {
454
467
  assertChildName(name);
455
- await fsPromises.mkdir(this.path, { recursive: true });
468
+ await fsPromises.mkdir(toNodeFilesystemPath(this.path), {
469
+ recursive: true
470
+ });
456
471
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
457
- await fsPromises.mkdir(directory.path);
472
+ await fsPromises.mkdir(toNodeFilesystemPath(directory.path));
458
473
  return directory;
459
474
  }
460
475
  async remove(name, options) {
461
476
  assertChildName(name);
462
- await fsPromises.rm(pathModule.join(this.path, name), {
463
- force: true,
464
- recursive: options?.recursive === true
465
- });
477
+ await fsPromises.rm(
478
+ toNodeFilesystemPath(pathModule.join(this.path, name)),
479
+ {
480
+ force: true,
481
+ recursive: options?.recursive === true
482
+ }
483
+ );
466
484
  }
467
485
  };
486
+ function toNodeFilesystemPath(path) {
487
+ if (nodeProcess.platform !== "win32" || path.startsWith("\\\\?\\")) {
488
+ return path;
489
+ }
490
+ const absolute = pathModule.resolve(path);
491
+ if (absolute.startsWith("\\\\")) {
492
+ return `\\\\?\\UNC\\${absolute.slice(2)}`;
493
+ }
494
+ return `\\\\?\\${absolute}`;
495
+ }
468
496
  function encodeNodeResourceIdentity(kind, path) {
469
497
  return `node-${kind}:${Buffer.from(pathModule.resolve(path), "utf8").toString("base64url")}`;
470
498
  }
@@ -550,10 +578,14 @@ async function openNativeNodeDatabase(file, flags) {
550
578
  throw new TypeError("The Node database adapter requires a NodeFile");
551
579
  }
552
580
  return await new Promise((resolve4, reject) => {
553
- const database = new nodeSqlite3.Database(path, flags, (error) => {
554
- if (error) reject(error);
555
- else resolve4(database);
556
- });
581
+ const database = new nodeSqlite3.Database(
582
+ toNodeFilesystemPath(path),
583
+ flags,
584
+ (error) => {
585
+ if (error) reject(error);
586
+ else resolve4(database);
587
+ }
588
+ );
557
589
  });
558
590
  }
559
591
  async function openNodeZip(file, options = {}) {
@@ -561,7 +593,7 @@ async function openNodeZip(file, options = {}) {
561
593
  if (path === void 0) {
562
594
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
563
595
  }
564
- const handle = await fsPromises.open(path, "r");
596
+ const handle = await fsPromises.open(toNodeFilesystemPath(path), "r");
565
597
  let size;
566
598
  try {
567
599
  size = (await handle.stat()).size;
@@ -876,6 +908,11 @@ async function writeNodeZip(file, entries) {
876
908
  }
877
909
  }
878
910
  async function addNodeZipEntries(zipFile, iterator, state) {
911
+ const stableZipOptions = {
912
+ compress: false,
913
+ forceDosTimestamp: true,
914
+ mtime: new Date(1980, 0, 2)
915
+ };
879
916
  while (!state.cancelled) {
880
917
  const result = await iterator.next();
881
918
  if (state.cancelled) return;
@@ -887,17 +924,17 @@ async function addNodeZipEntries(zipFile, iterator, state) {
887
924
  zipFile.addReadStream(
888
925
  createNodeFileReadStream(result.value.file),
889
926
  result.value.name,
890
- { compress: false }
927
+ stableZipOptions
891
928
  );
892
929
  } else if ("data" in result.value) {
893
930
  zipFile.addBuffer(Buffer.from(result.value.data), result.value.name, {
894
- compress: false
931
+ ...stableZipOptions
895
932
  });
896
933
  } else {
897
934
  zipFile.addReadStream(
898
935
  createNodeRangeReadStream(result.value),
899
936
  result.value.name,
900
- { compress: false, size: result.value.size }
937
+ { ...stableZipOptions, size: result.value.size }
901
938
  );
902
939
  }
903
940
  }
@@ -2733,6 +2770,18 @@ var WikiGraphArchiveManager = class {
2733
2770
  }, options.signal);
2734
2771
  return new WikiGraphArchiveHandle(this.#runtime, location);
2735
2772
  }
2773
+ async inspectSchema(target, options = {}) {
2774
+ return await this.#runtime.run(
2775
+ async () => ({
2776
+ schemaVersion: await (0, import_wiki_graph_core7.readWikiGraphArchiveSchemaVersion)(
2777
+ await resolveWikiGraphArchiveLocation(target).then(
2778
+ (location) => location.archiveFile
2779
+ )
2780
+ )
2781
+ }),
2782
+ options.signal
2783
+ );
2784
+ }
2736
2785
  };
2737
2786
  var WikiGraphArchiveHandle = class {
2738
2787
  #runtime;
@@ -2759,6 +2808,19 @@ var WikiGraphArchiveHandle = class {
2759
2808
  get target() {
2760
2809
  return this.#location.target;
2761
2810
  }
2811
+ /** Export this archive through the SDK without exposing core file adapters. */
2812
+ async export(path) {
2813
+ return await this.#runtime.run(async () => {
2814
+ const outputPath = await assertStandaloneWikiGraphArchivePath(path);
2815
+ const output = new NodeFile(outputPath);
2816
+ if (this.#location.archiveFile.kind === "directory") {
2817
+ await (0, import_wiki_graph_core7.writeWikgArchive)(this.#location.archiveFile, output);
2818
+ } else {
2819
+ await (0, import_platform2.copyFileContent)(this.#location.archiveFile, output);
2820
+ }
2821
+ return { path: outputPath };
2822
+ });
2823
+ }
2762
2824
  async #persistCursor(cursor) {
2763
2825
  return await this.#runtime.run(
2764
2826
  async () => await (0, import_wiki_graph_core7.createContinuationCursor)(cursor)
@@ -3291,6 +3353,38 @@ var WikiGraphArchiveHandle = class {
3291
3353
  options
3292
3354
  );
3293
3355
  }
3356
+ /** Read archive-level data without exposing the underlying Core reader. */
3357
+ async readOverview(options = {}) {
3358
+ return await this.#readDocument(async (document) => {
3359
+ const [metadata, cover, toc] = await Promise.all([
3360
+ document.readBookMeta(),
3361
+ document.readCover(),
3362
+ document.readToc()
3363
+ ]);
3364
+ const serials = toc === void 0 ? [] : await collectArchiveSerials(document, toc.items);
3365
+ return {
3366
+ ...metadata === void 0 ? {} : { metadata },
3367
+ ...cover === void 0 ? {} : { cover },
3368
+ ...toc === void 0 ? {} : { toc },
3369
+ serials
3370
+ };
3371
+ }, options);
3372
+ }
3373
+ /** Read a chapter and expose its graph as the stable WikgObject stream. */
3374
+ async readChapterData(serialId, options = {}) {
3375
+ const result = await this.#readDocument(async (document) => {
3376
+ const [chapter, summary] = await Promise.all([
3377
+ (0, import_wiki_graph_core7.getChapterDetails)(document, serialId),
3378
+ document.readSummary(serialId)
3379
+ ]);
3380
+ return { chapter, summary };
3381
+ }, options);
3382
+ return {
3383
+ chapter: result.chapter,
3384
+ ...result.summary === void 0 ? {} : { summary: result.summary },
3385
+ objects: this.#readChapterObjects(serialId, options)
3386
+ };
3387
+ }
3294
3388
  async replaceBookMeta(meta, options = {}) {
3295
3389
  return await this.#writeDocument(async (document) => {
3296
3390
  await document.replaceBookMeta(meta);
@@ -3378,6 +3472,33 @@ var WikiGraphArchiveHandle = class {
3378
3472
  (error) => rethrowArchiveSchemaError(error, this.#location.target)
3379
3473
  );
3380
3474
  }
3475
+ async *#readChapterObjects(serialId, options) {
3476
+ const queue = createAsyncValueQueue();
3477
+ const producer = this.#readDocument(async (document) => {
3478
+ try {
3479
+ for await (const object of (0, import_wiki_graph_core7.createChapterReadingGraphObjectStream)({
3480
+ chapterId: serialId,
3481
+ document
3482
+ })) {
3483
+ if (!await queue.push(object)) break;
3484
+ }
3485
+ queue.end();
3486
+ } catch (error) {
3487
+ queue.fail(error);
3488
+ throw error;
3489
+ }
3490
+ }, options).catch((error) => {
3491
+ queue.fail(error);
3492
+ throw error;
3493
+ });
3494
+ try {
3495
+ for await (const object of queue) yield object;
3496
+ await producer;
3497
+ } finally {
3498
+ queue.cancel();
3499
+ await producer.catch(() => void 0);
3500
+ }
3501
+ }
3381
3502
  async #writeDocument(operation, options = {}) {
3382
3503
  return await this.#runtime.run(async () => {
3383
3504
  return await writeWikiGraphArchiveLocation(this.#location, operation, {
@@ -3572,6 +3693,94 @@ function requireChapter(chapters, chapterId) {
3572
3693
  function asTextStream(text) {
3573
3694
  return import_stream.Readable.from([text]);
3574
3695
  }
3696
+ async function collectArchiveSerials(document, items, ancestorTitles = []) {
3697
+ const entries = [];
3698
+ for (const item of items) {
3699
+ const title = item.title?.trim() || `Chapter ${item.serialId ?? "group"}`;
3700
+ const tocPath = [...ancestorTitles, title];
3701
+ if (item.serialId !== void 0) {
3702
+ entries.push({
3703
+ fragmentCount: (await document.getSerialFragments(item.serialId).listFragmentIds()).length,
3704
+ serialId: item.serialId,
3705
+ title,
3706
+ tocPath
3707
+ });
3708
+ }
3709
+ entries.push(
3710
+ ...await collectArchiveSerials(document, item.children, tocPath)
3711
+ );
3712
+ }
3713
+ return entries;
3714
+ }
3715
+ function createAsyncValueQueue() {
3716
+ const values = [];
3717
+ const readers = [];
3718
+ const writers = [];
3719
+ let cancelled = false;
3720
+ let ended = false;
3721
+ let failure;
3722
+ const settleReaders = () => {
3723
+ while (readers.length > 0) {
3724
+ const reader = readers.shift();
3725
+ if (failure !== void 0) reader.reject(failure);
3726
+ else if (values.length > 0) {
3727
+ reader.resolve({ done: false, value: values.shift() });
3728
+ writers.shift()?.();
3729
+ } else if (ended) reader.resolve({ done: true, value: void 0 });
3730
+ else {
3731
+ readers.unshift(reader);
3732
+ return;
3733
+ }
3734
+ }
3735
+ };
3736
+ return {
3737
+ [Symbol.asyncIterator]: () => ({
3738
+ next: async () => {
3739
+ if (failure !== void 0) throw failure;
3740
+ if (values.length > 0) {
3741
+ const value = values.shift();
3742
+ writers.shift()?.();
3743
+ return { done: false, value };
3744
+ }
3745
+ if (ended) return { done: true, value: void 0 };
3746
+ return await new Promise((resolve4, reject) => {
3747
+ readers.push({ reject, resolve: resolve4 });
3748
+ });
3749
+ }
3750
+ }),
3751
+ cancel: () => {
3752
+ cancelled = true;
3753
+ ended = true;
3754
+ values.length = 0;
3755
+ while (writers.length > 0) writers.shift()();
3756
+ settleReaders();
3757
+ },
3758
+ end: () => {
3759
+ ended = true;
3760
+ settleReaders();
3761
+ },
3762
+ fail: (error) => {
3763
+ failure = error instanceof Error ? error : new Error(String(error));
3764
+ ended = true;
3765
+ values.length = 0;
3766
+ while (writers.length > 0) writers.shift()();
3767
+ settleReaders();
3768
+ },
3769
+ push: async (value) => {
3770
+ if (cancelled || ended || failure !== void 0) return false;
3771
+ if (readers.length > 0) {
3772
+ readers.shift().resolve({ done: false, value });
3773
+ return true;
3774
+ }
3775
+ if (values.length > 0) {
3776
+ await new Promise((resolve4) => writers.push(resolve4));
3777
+ if (cancelled || ended || failure !== void 0) return false;
3778
+ }
3779
+ values.push(value);
3780
+ return true;
3781
+ }
3782
+ };
3783
+ }
3575
3784
  async function assertChapterResetAllowed(archive, chapterId, stage) {
3576
3785
  if (stage === "planned") {
3577
3786
  await (0, import_wiki_graph_core7.assertNoActiveBuildJobs)({
@@ -4262,13 +4471,13 @@ var import_worker = require("wiki-graph-core/worker");
4262
4471
  var import_wiki_graph_core13 = require("wiki-graph-core");
4263
4472
 
4264
4473
  // src/host.ts
4265
- var import_platform2 = require("wiki-graph-core/platform");
4474
+ var import_platform3 = require("wiki-graph-core/platform");
4266
4475
  function prepareWikiGraphSDKHost(host) {
4267
4476
  if (host?.platform === void 0) {
4268
4477
  ensureNodeWikiGraphPlatform();
4269
4478
  return;
4270
4479
  }
4271
- (0, import_platform2.installWikiGraphPlatform)(host.platform);
4480
+ (0, import_platform3.installWikiGraphPlatform)(host.platform);
4272
4481
  }
4273
4482
  function assertWikiGraphSDKHostOptions(options) {
4274
4483
  if (options.host?.storage !== void 0 && options.host.stateDir === void 0) {
@@ -4299,7 +4508,7 @@ async function withWikiGraphSDKHost(options, operation) {
4299
4508
  operation
4300
4509
  );
4301
4510
  if (effective.host?.storage !== void 0) {
4302
- return await (0, import_platform2.withWikiGraphStorage)(effective.host.storage, runWithContext);
4511
+ return await (0, import_platform3.withWikiGraphStorage)(effective.host.storage, runWithContext);
4303
4512
  }
4304
4513
  return await withNodeWikiGraphStorage(
4305
4514
  effective.host?.stateDir ?? effective.stateDir,