wiki-graph-sdk 0.9.0 → 0.9.2

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 +316 -142
  2. package/dist/archives.cjs.map +1 -1
  3. package/dist/archives.js +326 -148
  4. package/dist/archives.js.map +1 -1
  5. package/dist/conversions.cjs +268 -99
  6. package/dist/conversions.cjs.map +1 -1
  7. package/dist/conversions.js +274 -103
  8. package/dist/conversions.js.map +1 -1
  9. package/dist/default-worker.cjs +258 -101
  10. package/dist/default-worker.cjs.map +1 -1
  11. package/dist/default-worker.js +264 -105
  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 +354 -174
  22. package/dist/index.cjs.map +1 -1
  23. package/dist/index.d.ts +1 -1
  24. package/dist/index.js +369 -184
  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 +264 -97
  31. package/dist/maintenance.cjs.map +1 -1
  32. package/dist/maintenance.js +270 -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 +257 -96
  48. package/dist/worker.cjs.map +1 -1
  49. package/dist/worker.js +263 -100
  50. package/dist/worker.js.map +1 -1
  51. package/package.json +2 -2
@@ -98,6 +98,15 @@ var NodeFile = class {
98
98
  this.name = name;
99
99
  }
100
100
  path;
101
+ async getPhysicalIdentity() {
102
+ const value = await fsPromises.stat(this.path).catch((error) => {
103
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
104
+ return void 0;
105
+ throw error;
106
+ });
107
+ if (value === void 0) return void 0;
108
+ return `${value.dev}:${value.ino}`;
109
+ }
101
110
  kind = "file";
102
111
  [NODE_RESOURCE_KIND] = "file";
103
112
  identity;
@@ -222,6 +231,15 @@ var NodeDirectory = class _NodeDirectory {
222
231
  this.name = pathModule.basename(path);
223
232
  }
224
233
  path;
234
+ async getPhysicalIdentity() {
235
+ const value = await fsPromises.stat(this.path).catch((error) => {
236
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
237
+ return void 0;
238
+ throw error;
239
+ });
240
+ if (value === void 0) return void 0;
241
+ return `${value.dev}:${value.ino}`;
242
+ }
225
243
  kind = "directory";
226
244
  [NODE_RESOURCE_KIND] = "directory";
227
245
  identity;
@@ -231,8 +249,10 @@ var NodeDirectory = class _NodeDirectory {
231
249
  const file = new NodeFile(pathModule.join(this.path, name));
232
250
  try {
233
251
  return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
234
- } catch {
235
- return void 0;
252
+ } catch (error) {
253
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
254
+ return void 0;
255
+ throw error;
236
256
  }
237
257
  }
238
258
  async getLastModified() {
@@ -250,8 +270,10 @@ var NodeDirectory = class _NodeDirectory {
250
270
  const directory = new _NodeDirectory(pathModule.join(this.path, name));
251
271
  try {
252
272
  return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
253
- } catch {
254
- return void 0;
273
+ } catch (error) {
274
+ if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
275
+ return void 0;
276
+ throw error;
255
277
  }
256
278
  }
257
279
  async list() {
@@ -367,14 +389,23 @@ async function openNativeNodeDatabase(file, flags) {
367
389
  });
368
390
  });
369
391
  }
370
- async function openNodeZip(file) {
392
+ async function openNodeZip(file, options = {}) {
371
393
  const path = getBrandedNodeResourcePath(file, "file");
372
394
  if (path === void 0) {
373
395
  throw new TypeError("The Node ZIP adapter requires a NodeFile");
374
396
  }
375
- const zipFile = await new Promise((resolve2, reject) => {
376
- yauzl.open(
377
- path,
397
+ const handle = await fsPromises.open(path, "r");
398
+ let size;
399
+ try {
400
+ size = (await handle.stat()).size;
401
+ } catch (error) {
402
+ await handle.close();
403
+ throw error;
404
+ }
405
+ const open2 = () => new Promise((resolve2, reject) => {
406
+ yauzl.fromRandomAccessReader(
407
+ new NodeZipSource(handle),
408
+ size,
378
409
  { autoClose: false, lazyEntries: true },
379
410
  (error, opened) => {
380
411
  if (error || opened === void 0)
@@ -383,63 +414,192 @@ async function openNodeZip(file) {
383
414
  }
384
415
  );
385
416
  });
386
- const entries = await new Promise(
387
- (resolve2, reject) => {
388
- const discovered = /* @__PURE__ */ new Map();
389
- const rejectAndClose = (error) => {
390
- zipFile.close();
391
- reject(
392
- error instanceof Error ? error : new Error("Cannot scan ZIP central directory")
393
- );
394
- };
395
- const resolveEntries = () => {
396
- zipFile.off("error", rejectAndClose);
397
- resolve2(discovered);
398
- };
399
- zipFile.on("entry", (entry) => {
400
- if (!entry.fileName.endsWith("/")) {
401
- discovered.set(entry.fileName, entry);
402
- }
403
- zipFile.readEntry();
404
- });
405
- zipFile.once("error", rejectAndClose);
406
- zipFile.once("end", resolveEntries);
407
- zipFile.readEntry();
408
- }
409
- );
417
+ try {
418
+ (await open2()).close();
419
+ } catch (error) {
420
+ await handle.close();
421
+ throw error;
422
+ }
410
423
  let closed = false;
424
+ let pending = Promise.resolve();
425
+ let closing;
426
+ const run = (operation) => {
427
+ if (closed)
428
+ return Promise.reject(new Error("Cannot read a closed ZIP archive"));
429
+ const result = pending.then(async () => {
430
+ const zip = await open2();
431
+ try {
432
+ return await operation(zip);
433
+ } finally {
434
+ zip.close();
435
+ }
436
+ });
437
+ pending = result.then(
438
+ () => void 0,
439
+ () => void 0
440
+ );
441
+ return result;
442
+ };
443
+ const withEntry = (name, operation) => run(async (zip) => {
444
+ let exact;
445
+ let alias;
446
+ let aliasCollision = false;
447
+ await scanNodeZip(zip, (entry) => {
448
+ if (entry.fileName === name) exact = entry;
449
+ if (normalizeNodeZipName(entry.fileName) === name) {
450
+ if (alias !== void 0 && alias.fileName !== entry.fileName)
451
+ aliasCollision = true;
452
+ alias = entry;
453
+ }
454
+ });
455
+ if ((exact === void 0 || options.entryNameMode === "normalized") && aliasCollision) {
456
+ let bestPosition = -1;
457
+ const candidates = await open2();
458
+ try {
459
+ await scanNodeZip(candidates, async (entry) => {
460
+ if (normalizeNodeZipName(entry.fileName) !== name) return;
461
+ const probe = await open2();
462
+ let position = 0;
463
+ try {
464
+ await scanNodeZip(probe, (candidate) => {
465
+ if (candidate.fileName === entry.fileName) return false;
466
+ position++;
467
+ });
468
+ } finally {
469
+ probe.close();
470
+ }
471
+ if (position >= bestPosition) {
472
+ bestPosition = position;
473
+ alias = entry;
474
+ }
475
+ });
476
+ return await operation(candidates, alias);
477
+ } finally {
478
+ candidates.close();
479
+ }
480
+ }
481
+ return await operation(
482
+ zip,
483
+ options.entryNameMode === "normalized" ? alias : exact ?? alias
484
+ );
485
+ });
411
486
  return {
412
487
  close: () => {
413
- if (!closed) zipFile.close();
414
488
  closed = true;
415
- return Promise.resolve();
489
+ closing ??= pending.then(() => handle.close());
490
+ return closing;
416
491
  },
417
- copyEntry: async (name, target) => {
418
- if (closed) throw new Error("Cannot read a closed ZIP archive");
419
- const entry = entries.get(name);
492
+ copyEntry: (name, target) => withEntry(name, async (zip, entry) => {
420
493
  if (entry === void 0) return false;
421
- await copyNodeZipEntry(zipFile, entry, target);
494
+ await copyNodeZipEntry(zip, entry, target);
422
495
  return true;
423
- },
424
- getEntrySize: (name) => {
425
- if (closed) throw new Error("Cannot read a closed ZIP archive");
426
- return Promise.resolve(entries.get(name)?.uncompressedSize);
427
- },
428
- listEntries: () => Promise.resolve([...entries.keys()]),
429
- readEntryRange: async (name, offset, length) => {
430
- if (closed) throw new Error("Cannot read a closed ZIP archive");
431
- const entry = entries.get(name);
496
+ }),
497
+ getEntrySize: (name) => withEntry(
498
+ name,
499
+ (_zip, entry) => Promise.resolve(entry?.uncompressedSize)
500
+ ),
501
+ listEntries: () => run(async (zip) => {
502
+ const names = /* @__PURE__ */ new Set();
503
+ await scanNodeZip(zip, (entry) => {
504
+ names.add(entry.fileName);
505
+ });
506
+ return [...names];
507
+ }),
508
+ readEntryRange: (name, offset, length) => withEntry(name, async (zip, entry) => {
432
509
  if (entry === void 0) return void 0;
433
- return await readNodeZipEntryRange(zipFile, entry, offset, length);
434
- },
435
- readEntry: async (name) => {
436
- if (closed) throw new Error("Cannot read a closed ZIP archive");
437
- const entry = entries.get(name);
510
+ return await readNodeZipEntryRange(zip, entry, offset, length);
511
+ }),
512
+ readEntry: (name) => withEntry(name, async (zip, entry) => {
438
513
  if (entry === void 0) return void 0;
439
- return await readNodeZipEntry(zipFile, entry);
440
- }
514
+ return await readNodeZipEntry(zip, entry);
515
+ })
441
516
  };
442
517
  }
518
+ var NodeZipSource = class extends yauzl.RandomAccessReader {
519
+ constructor(handle) {
520
+ super();
521
+ this.handle = handle;
522
+ }
523
+ handle;
524
+ read(buffer, offset, length, position, callback) {
525
+ const read2 = (written) => {
526
+ if (written === length) {
527
+ callback(null);
528
+ return;
529
+ }
530
+ fs.read(
531
+ this.handle.fd,
532
+ buffer,
533
+ offset + written,
534
+ length - written,
535
+ position + written,
536
+ (error, bytesRead) => {
537
+ if (error) callback(error);
538
+ else if (bytesRead === 0)
539
+ callback(new Error("Unexpected end of ZIP file"));
540
+ else read2(written + bytesRead);
541
+ }
542
+ );
543
+ };
544
+ read2(0);
545
+ }
546
+ _readStreamForRange(start, end) {
547
+ const handle = this.handle;
548
+ return import_node_stream.Readable.from(
549
+ (async function* () {
550
+ for (let position = start; position < end; ) {
551
+ const buffer = Buffer.allocUnsafe(
552
+ Math.min(64 * 1024, end - position)
553
+ );
554
+ const { bytesRead } = await handle.read(
555
+ buffer,
556
+ 0,
557
+ buffer.length,
558
+ position
559
+ );
560
+ if (bytesRead === 0) return;
561
+ position += bytesRead;
562
+ yield buffer.subarray(0, bytesRead);
563
+ }
564
+ })()
565
+ );
566
+ }
567
+ };
568
+ function normalizeNodeZipName(name) {
569
+ const normalized = name.replaceAll("\\", "/").trim().split("/").filter((part) => part !== "" && part !== ".").join("/");
570
+ return normalized.split("/").includes("..") ? void 0 : normalized;
571
+ }
572
+ async function scanNodeZip(zip, visit) {
573
+ await new Promise((resolve2, reject) => {
574
+ const cleanup = () => {
575
+ zip.off("entry", onEntry);
576
+ zip.off("end", onEnd);
577
+ zip.off("error", onError);
578
+ };
579
+ const onError = (error) => {
580
+ cleanup();
581
+ reject(error);
582
+ };
583
+ const onEnd = () => {
584
+ cleanup();
585
+ resolve2();
586
+ };
587
+ const onEntry = (entry) => {
588
+ void Promise.resolve().then(() => entry.fileName.endsWith("/") ? void 0 : visit(entry)).then((keepReading) => {
589
+ if (keepReading === false) onEnd();
590
+ else zip.readEntry();
591
+ }).catch(
592
+ (error) => onError(
593
+ error instanceof Error ? error : new Error("Cannot scan ZIP", { cause: error })
594
+ )
595
+ );
596
+ };
597
+ zip.on("entry", onEntry);
598
+ zip.once("end", onEnd);
599
+ zip.once("error", onError);
600
+ zip.readEntry();
601
+ });
602
+ }
443
603
  async function copyNodeZipEntry(zipFile, entry, target) {
444
604
  const writer = await target.openWriter();
445
605
  try {