wiki-graph-sdk 0.8.4 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/dist/archives.cjs +345 -152
  2. package/dist/archives.cjs.map +1 -1
  3. package/dist/archives.js +356 -157
  4. package/dist/archives.js.map +1 -1
  5. package/dist/conversions.cjs +269 -99
  6. package/dist/conversions.cjs.map +1 -1
  7. package/dist/conversions.js +275 -103
  8. package/dist/conversions.js.map +1 -1
  9. package/dist/default-worker.cjs +278 -108
  10. package/dist/default-worker.cjs.map +1 -1
  11. package/dist/default-worker.js +285 -112
  12. package/dist/default-worker.js.map +1 -1
  13. package/dist/embedding.cjs +214 -54
  14. package/dist/embedding.cjs.map +1 -1
  15. package/dist/embedding.js +214 -54
  16. package/dist/embedding.js.map +1 -1
  17. package/dist/gc.cjs +214 -54
  18. package/dist/gc.cjs.map +1 -1
  19. package/dist/gc.js +214 -54
  20. package/dist/gc.js.map +1 -1
  21. package/dist/index.cjs +442 -226
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +461 -236
  25. package/dist/index.js.map +1 -1
  26. package/dist/local-config.cjs +214 -54
  27. package/dist/local-config.cjs.map +1 -1
  28. package/dist/local-config.js +214 -54
  29. package/dist/local-config.js.map +1 -1
  30. package/dist/maintenance.cjs +265 -97
  31. package/dist/maintenance.cjs.map +1 -1
  32. package/dist/maintenance.js +271 -101
  33. package/dist/maintenance.js.map +1 -1
  34. package/dist/node-platform.cjs +214 -54
  35. package/dist/node-platform.cjs.map +1 -1
  36. package/dist/node-platform.d.ts +2 -0
  37. package/dist/node-platform.js +214 -54
  38. package/dist/node-platform.js.map +1 -1
  39. package/dist/runtime-config.cjs +214 -54
  40. package/dist/runtime-config.cjs.map +1 -1
  41. package/dist/runtime-config.js +214 -54
  42. package/dist/runtime-config.js.map +1 -1
  43. package/dist/stage.cjs +214 -54
  44. package/dist/stage.cjs.map +1 -1
  45. package/dist/stage.js +214 -54
  46. package/dist/stage.js.map +1 -1
  47. package/dist/worker.cjs +277 -103
  48. package/dist/worker.cjs.map +1 -1
  49. package/dist/worker.js +284 -107
  50. package/dist/worker.js.map +1 -1
  51. package/package.json +2 -2
@@ -102,6 +102,15 @@ var NodeFile = class {
102
102
  this.name = name;
103
103
  }
104
104
  path;
105
+ async getPhysicalIdentity() {
106
+ const value = await fsPromises.stat(this.path).catch((error) => {
107
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
108
+ return void 0;
109
+ throw error;
110
+ });
111
+ if (value === void 0) return void 0;
112
+ return `${value.dev}:${value.ino}`;
113
+ }
105
114
  kind = "file";
106
115
  [NODE_RESOURCE_KIND] = "file";
107
116
  identity;
@@ -226,6 +235,15 @@ var NodeDirectory = class _NodeDirectory {
226
235
  this.name = pathModule.basename(path);
227
236
  }
228
237
  path;
238
+ async getPhysicalIdentity() {
239
+ const value = await fsPromises.stat(this.path).catch((error) => {
240
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
241
+ return void 0;
242
+ throw error;
243
+ });
244
+ if (value === void 0) return void 0;
245
+ return `${value.dev}:${value.ino}`;
246
+ }
229
247
  kind = "directory";
230
248
  [NODE_RESOURCE_KIND] = "directory";
231
249
  identity;
@@ -235,8 +253,10 @@ var NodeDirectory = class _NodeDirectory {
235
253
  const file = new NodeFile(pathModule.join(this.path, name));
236
254
  try {
237
255
  return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
238
- } catch {
239
- return void 0;
256
+ } catch (error) {
257
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
258
+ return void 0;
259
+ throw error;
240
260
  }
241
261
  }
242
262
  async getLastModified() {
@@ -254,8 +274,10 @@ var NodeDirectory = class _NodeDirectory {
254
274
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
255
275
  try {
256
276
  return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
257
- } catch {
258
- return void 0;
277
+ } catch (error) {
278
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
279
+ return void 0;
280
+ throw error;
259
281
  }
260
282
  }
261
283
  async list() {
@@ -371,14 +393,23 @@ async function openNativeNodeDatabase(file, flags) {
371
393
  });
372
394
  });
373
395
  }
374
- async function openNodeZip(file) {
396
+ async function openNodeZip(file, options = {}) {
375
397
  const path = getBrandedNodeResourcePath(file, "file");
376
398
  if (path === void 0) {
377
399
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
378
400
  }
379
- const zipFile = await new Promise((resolve2, reject) => {
380
- yauzl.open(
381
- path,
401
+ const handle = await fsPromises.open(path, "r");
402
+ let size;
403
+ try {
404
+ size = (await handle.stat()).size;
405
+ } catch (error) {
406
+ await handle.close();
407
+ throw error;
408
+ }
409
+ const open2 = () => new Promise((resolve2, reject) => {
410
+ yauzl.fromRandomAccessReader(
411
+ new NodeZipSource(handle),
412
+ size,
382
413
  { autoClose: false, lazyEntries: true },
383
414
  (error, opened) => {
384
415
  if (error || opened === void 0)
@@ -387,63 +418,192 @@ async function openNodeZip(file) {
387
418
  }
388
419
  );
389
420
  });
390
- const entries = await new Promise(
391
- (resolve2, reject) => {
392
- const discovered = /* @__PURE__ */ new Map();
393
- const rejectAndClose = (error) => {
394
- zipFile.close();
395
- reject(
396
- error instanceof Error ? error : new Error("Cannot scan ZIP central directory")
397
- );
398
- };
399
- const resolveEntries = () => {
400
- zipFile.off("error", rejectAndClose);
401
- resolve2(discovered);
402
- };
403
- zipFile.on("entry", (entry) => {
404
- if (!entry.fileName.endsWith("/")) {
405
- discovered.set(entry.fileName, entry);
406
- }
407
- zipFile.readEntry();
408
- });
409
- zipFile.once("error", rejectAndClose);
410
- zipFile.once("end", resolveEntries);
411
- zipFile.readEntry();
412
- }
413
- );
421
+ try {
422
+ (await open2()).close();
423
+ } catch (error) {
424
+ await handle.close();
425
+ throw error;
426
+ }
414
427
  let closed = false;
428
+ let pending = Promise.resolve();
429
+ let closing;
430
+ const run = (operation) => {
431
+ if (closed)
432
+ return Promise.reject(new Error("Cannot read a closed ZIP archive"));
433
+ const result = pending.then(async () => {
434
+ const zip = await open2();
435
+ try {
436
+ return await operation(zip);
437
+ } finally {
438
+ zip.close();
439
+ }
440
+ });
441
+ pending = result.then(
442
+ () => void 0,
443
+ () => void 0
444
+ );
445
+ return result;
446
+ };
447
+ const withEntry = (name, operation) => run(async (zip) => {
448
+ let exact;
449
+ let alias;
450
+ let aliasCollision = false;
451
+ await scanNodeZip(zip, (entry) => {
452
+ if (entry.fileName === name) exact = entry;
453
+ if (normalizeNodeZipName(entry.fileName) === name) {
454
+ if (alias !== void 0 && alias.fileName !== entry.fileName)
455
+ aliasCollision = true;
456
+ alias = entry;
457
+ }
458
+ });
459
+ if ((exact === void 0 || options.entryNameMode === "normalized") && aliasCollision) {
460
+ let bestPosition = -1;
461
+ const candidates = await open2();
462
+ try {
463
+ await scanNodeZip(candidates, async (entry) => {
464
+ if (normalizeNodeZipName(entry.fileName) !== name) return;
465
+ const probe = await open2();
466
+ let position = 0;
467
+ try {
468
+ await scanNodeZip(probe, (candidate) => {
469
+ if (candidate.fileName === entry.fileName) return false;
470
+ position++;
471
+ });
472
+ } finally {
473
+ probe.close();
474
+ }
475
+ if (position >= bestPosition) {
476
+ bestPosition = position;
477
+ alias = entry;
478
+ }
479
+ });
480
+ return await operation(candidates, alias);
481
+ } finally {
482
+ candidates.close();
483
+ }
484
+ }
485
+ return await operation(
486
+ zip,
487
+ options.entryNameMode === "normalized" ? alias : exact ?? alias
488
+ );
489
+ });
415
490
  return {
416
491
  close: () => {
417
- if (!closed) zipFile.close();
418
492
  closed = true;
419
- return Promise.resolve();
493
+ closing ??= pending.then(() => handle.close());
494
+ return closing;
420
495
  },
421
- copyEntry: async (name, target) => {
422
- if (closed) throw new Error("Cannot read a closed ZIP archive");
423
- const entry = entries.get(name);
496
+ copyEntry: (name, target) => withEntry(name, async (zip, entry) => {
424
497
  if (entry === void 0) return false;
425
- await copyNodeZipEntry(zipFile, entry, target);
498
+ await copyNodeZipEntry(zip, entry, target);
426
499
  return true;
427
- },
428
- getEntrySize: (name) => {
429
- if (closed) throw new Error("Cannot read a closed ZIP archive");
430
- return Promise.resolve(entries.get(name)?.uncompressedSize);
431
- },
432
- listEntries: () => Promise.resolve([...entries.keys()]),
433
- readEntryRange: async (name, offset, length) => {
434
- if (closed) throw new Error("Cannot read a closed ZIP archive");
435
- const entry = entries.get(name);
500
+ }),
501
+ getEntrySize: (name) => withEntry(
502
+ name,
503
+ (_zip, entry) => Promise.resolve(entry?.uncompressedSize)
504
+ ),
505
+ listEntries: () => run(async (zip) => {
506
+ const names = /* @__PURE__ */ new Set();
507
+ await scanNodeZip(zip, (entry) => {
508
+ names.add(entry.fileName);
509
+ });
510
+ return [...names];
511
+ }),
512
+ readEntryRange: (name, offset, length) => withEntry(name, async (zip, entry) => {
436
513
  if (entry === void 0) return void 0;
437
- return await readNodeZipEntryRange(zipFile, entry, offset, length);
438
- },
439
- readEntry: async (name) => {
440
- if (closed) throw new Error("Cannot read a closed ZIP archive");
441
- const entry = entries.get(name);
514
+ return await readNodeZipEntryRange(zip, entry, offset, length);
515
+ }),
516
+ readEntry: (name) => withEntry(name, async (zip, entry) => {
442
517
  if (entry === void 0) return void 0;
443
- return await readNodeZipEntry(zipFile, entry);
444
- }
518
+ return await readNodeZipEntry(zip, entry);
519
+ })
445
520
  };
446
521
  }
522
+ var NodeZipSource = class extends yauzl.RandomAccessReader {
523
+ constructor(handle) {
524
+ super();
525
+ this.handle = handle;
526
+ }
527
+ handle;
528
+ read(buffer, offset, length, position, callback) {
529
+ const read2 = (written) => {
530
+ if (written === length) {
531
+ callback(null);
532
+ return;
533
+ }
534
+ fs.read(
535
+ this.handle.fd,
536
+ buffer,
537
+ offset + written,
538
+ length - written,
539
+ position + written,
540
+ (error, bytesRead) => {
541
+ if (error) callback(error);
542
+ else if (bytesRead === 0)
543
+ callback(new Error("Unexpected end of ZIP file"));
544
+ else read2(written + bytesRead);
545
+ }
546
+ );
547
+ };
548
+ read2(0);
549
+ }
550
+ _readStreamForRange(start, end) {
551
+ const handle = this.handle;
552
+ return import_node_stream.Readable.from(
553
+ (async function* () {
554
+ for (let position = start; position < end; ) {
555
+ const buffer = Buffer.allocUnsafe(
556
+ Math.min(64 * 1024, end - position)
557
+ );
558
+ const { bytesRead } = await handle.read(
559
+ buffer,
560
+ 0,
561
+ buffer.length,
562
+ position
563
+ );
564
+ if (bytesRead === 0) return;
565
+ position += bytesRead;
566
+ yield buffer.subarray(0, bytesRead);
567
+ }
568
+ })()
569
+ );
570
+ }
571
+ };
572
+ function normalizeNodeZipName(name) {
573
+ const normalized = name.replaceAll("\\", "/").trim().split("/").filter((part) => part !== "" && part !== ".").join("/");
574
+ return normalized.split("/").includes("..") ? void 0 : normalized;
575
+ }
576
+ async function scanNodeZip(zip, visit) {
577
+ await new Promise((resolve2, reject) => {
578
+ const cleanup = () => {
579
+ zip.off("entry", onEntry);
580
+ zip.off("end", onEnd);
581
+ zip.off("error", onError);
582
+ };
583
+ const onError = (error) => {
584
+ cleanup();
585
+ reject(error);
586
+ };
587
+ const onEnd = () => {
588
+ cleanup();
589
+ resolve2();
590
+ };
591
+ const onEntry = (entry) => {
592
+ void Promise.resolve().then(() => entry.fileName.endsWith("/") ? void 0 : visit(entry)).then((keepReading) => {
593
+ if (keepReading === false) onEnd();
594
+ else zip.readEntry();
595
+ }).catch(
596
+ (error) => onError(
597
+ error instanceof Error ? error : new Error("Cannot scan ZIP", { cause: error })
598
+ )
599
+ );
600
+ };
601
+ zip.on("entry", onEntry);
602
+ zip.once("end", onEnd);
603
+ zip.once("error", onError);
604
+ zip.readEntry();
605
+ });
606
+ }
447
607
  async function copyNodeZipEntry(zipFile, entry, target) {
448
608
  const writer = await target.openWriter();
449
609
  try {