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.
- package/dist/archives.cjs +316 -142
- package/dist/archives.cjs.map +1 -1
- package/dist/archives.js +326 -148
- package/dist/archives.js.map +1 -1
- package/dist/conversions.cjs +268 -99
- package/dist/conversions.cjs.map +1 -1
- package/dist/conversions.js +274 -103
- package/dist/conversions.js.map +1 -1
- package/dist/default-worker.cjs +258 -101
- package/dist/default-worker.cjs.map +1 -1
- package/dist/default-worker.js +264 -105
- package/dist/default-worker.js.map +1 -1
- package/dist/embedding.cjs +214 -54
- package/dist/embedding.cjs.map +1 -1
- package/dist/embedding.js +214 -54
- package/dist/embedding.js.map +1 -1
- package/dist/gc.cjs +214 -54
- package/dist/gc.cjs.map +1 -1
- package/dist/gc.js +214 -54
- package/dist/gc.js.map +1 -1
- package/dist/index.cjs +354 -174
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +369 -184
- package/dist/index.js.map +1 -1
- package/dist/local-config.cjs +214 -54
- package/dist/local-config.cjs.map +1 -1
- package/dist/local-config.js +214 -54
- package/dist/local-config.js.map +1 -1
- package/dist/maintenance.cjs +264 -97
- package/dist/maintenance.cjs.map +1 -1
- package/dist/maintenance.js +270 -101
- package/dist/maintenance.js.map +1 -1
- package/dist/node-platform.cjs +214 -54
- package/dist/node-platform.cjs.map +1 -1
- package/dist/node-platform.d.ts +2 -0
- package/dist/node-platform.js +214 -54
- package/dist/node-platform.js.map +1 -1
- package/dist/runtime-config.cjs +214 -54
- package/dist/runtime-config.cjs.map +1 -1
- package/dist/runtime-config.js +214 -54
- package/dist/runtime-config.js.map +1 -1
- package/dist/stage.cjs +214 -54
- package/dist/stage.cjs.map +1 -1
- package/dist/stage.js +214 -54
- package/dist/stage.js.map +1 -1
- package/dist/worker.cjs +257 -96
- package/dist/worker.cjs.map +1 -1
- package/dist/worker.js +263 -100
- package/dist/worker.js.map +1 -1
- package/package.json +2 -2
package/dist/archives.js
CHANGED
|
@@ -11,7 +11,9 @@ import { Readable as Readable2 } from "stream";
|
|
|
11
11
|
import {
|
|
12
12
|
addChapter,
|
|
13
13
|
applyChapterTree,
|
|
14
|
-
|
|
14
|
+
assertArchiveQueryReady,
|
|
15
|
+
resolveIndexedArchiveChapterScope,
|
|
16
|
+
ensureWikiGraphArchiveSchemaCurrent,
|
|
15
17
|
assertNoActiveBuildJobConflicts,
|
|
16
18
|
assertNoActiveBuildJobs,
|
|
17
19
|
deleteArchiveSearchSessions,
|
|
@@ -31,7 +33,7 @@ import {
|
|
|
31
33
|
moveChapter,
|
|
32
34
|
packArchiveContext,
|
|
33
35
|
parseLocatedWikiGraphUri as parseLocatedWikiGraphUri2,
|
|
34
|
-
|
|
36
|
+
prepareArchivePage,
|
|
35
37
|
readSearchIndexCapabilityStatus,
|
|
36
38
|
rebuildArchiveSearchIndex,
|
|
37
39
|
removeChapter,
|
|
@@ -162,6 +164,15 @@ var NodeFile = class {
|
|
|
162
164
|
this.name = name;
|
|
163
165
|
}
|
|
164
166
|
path;
|
|
167
|
+
async getPhysicalIdentity() {
|
|
168
|
+
const value = await fsPromises.stat(this.path).catch((error) => {
|
|
169
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
|
|
170
|
+
return void 0;
|
|
171
|
+
throw error;
|
|
172
|
+
});
|
|
173
|
+
if (value === void 0) return void 0;
|
|
174
|
+
return `${value.dev}:${value.ino}`;
|
|
175
|
+
}
|
|
165
176
|
kind = "file";
|
|
166
177
|
[NODE_RESOURCE_KIND] = "file";
|
|
167
178
|
identity;
|
|
@@ -286,6 +297,15 @@ var NodeDirectory = class _NodeDirectory {
|
|
|
286
297
|
this.name = pathModule.basename(path);
|
|
287
298
|
}
|
|
288
299
|
path;
|
|
300
|
+
async getPhysicalIdentity() {
|
|
301
|
+
const value = await fsPromises.stat(this.path).catch((error) => {
|
|
302
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT")
|
|
303
|
+
return void 0;
|
|
304
|
+
throw error;
|
|
305
|
+
});
|
|
306
|
+
if (value === void 0) return void 0;
|
|
307
|
+
return `${value.dev}:${value.ino}`;
|
|
308
|
+
}
|
|
289
309
|
kind = "directory";
|
|
290
310
|
[NODE_RESOURCE_KIND] = "directory";
|
|
291
311
|
identity;
|
|
@@ -295,8 +315,10 @@ var NodeDirectory = class _NodeDirectory {
|
|
|
295
315
|
const file = new NodeFile(pathModule.join(this.path, name));
|
|
296
316
|
try {
|
|
297
317
|
return (await fsPromises.stat(file.path)).isFile() ? file : void 0;
|
|
298
|
-
} catch {
|
|
299
|
-
|
|
318
|
+
} catch (error) {
|
|
319
|
+
if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
|
|
320
|
+
return void 0;
|
|
321
|
+
throw error;
|
|
300
322
|
}
|
|
301
323
|
}
|
|
302
324
|
async getLastModified() {
|
|
@@ -314,8 +336,10 @@ var NodeDirectory = class _NodeDirectory {
|
|
|
314
336
|
const directory = new _NodeDirectory(pathModule.join(this.path, name));
|
|
315
337
|
try {
|
|
316
338
|
return (await fsPromises.stat(directory.path)).isDirectory() ? directory : void 0;
|
|
317
|
-
} catch {
|
|
318
|
-
|
|
339
|
+
} catch (error) {
|
|
340
|
+
if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
|
|
341
|
+
return void 0;
|
|
342
|
+
throw error;
|
|
319
343
|
}
|
|
320
344
|
}
|
|
321
345
|
async list() {
|
|
@@ -439,14 +463,23 @@ async function openNativeNodeDatabase(file, flags) {
|
|
|
439
463
|
});
|
|
440
464
|
});
|
|
441
465
|
}
|
|
442
|
-
async function openNodeZip(file) {
|
|
466
|
+
async function openNodeZip(file, options = {}) {
|
|
443
467
|
const path = getBrandedNodeResourcePath(file, "file");
|
|
444
468
|
if (path === void 0) {
|
|
445
469
|
throw new TypeError("The Node ZIP adapter requires a NodeFile");
|
|
446
470
|
}
|
|
447
|
-
const
|
|
448
|
-
|
|
449
|
-
|
|
471
|
+
const handle = await fsPromises.open(path, "r");
|
|
472
|
+
let size;
|
|
473
|
+
try {
|
|
474
|
+
size = (await handle.stat()).size;
|
|
475
|
+
} catch (error) {
|
|
476
|
+
await handle.close();
|
|
477
|
+
throw error;
|
|
478
|
+
}
|
|
479
|
+
const open2 = () => new Promise((resolve4, reject) => {
|
|
480
|
+
yauzl.fromRandomAccessReader(
|
|
481
|
+
new NodeZipSource(handle),
|
|
482
|
+
size,
|
|
450
483
|
{ autoClose: false, lazyEntries: true },
|
|
451
484
|
(error, opened) => {
|
|
452
485
|
if (error || opened === void 0)
|
|
@@ -455,63 +488,192 @@ async function openNodeZip(file) {
|
|
|
455
488
|
}
|
|
456
489
|
);
|
|
457
490
|
});
|
|
458
|
-
|
|
459
|
-
(
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
error instanceof Error ? error : new Error("Cannot scan ZIP central directory")
|
|
465
|
-
);
|
|
466
|
-
};
|
|
467
|
-
const resolveEntries = () => {
|
|
468
|
-
zipFile.off("error", rejectAndClose);
|
|
469
|
-
resolve4(discovered);
|
|
470
|
-
};
|
|
471
|
-
zipFile.on("entry", (entry) => {
|
|
472
|
-
if (!entry.fileName.endsWith("/")) {
|
|
473
|
-
discovered.set(entry.fileName, entry);
|
|
474
|
-
}
|
|
475
|
-
zipFile.readEntry();
|
|
476
|
-
});
|
|
477
|
-
zipFile.once("error", rejectAndClose);
|
|
478
|
-
zipFile.once("end", resolveEntries);
|
|
479
|
-
zipFile.readEntry();
|
|
480
|
-
}
|
|
481
|
-
);
|
|
491
|
+
try {
|
|
492
|
+
(await open2()).close();
|
|
493
|
+
} catch (error) {
|
|
494
|
+
await handle.close();
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
482
497
|
let closed = false;
|
|
498
|
+
let pending = Promise.resolve();
|
|
499
|
+
let closing;
|
|
500
|
+
const run = (operation) => {
|
|
501
|
+
if (closed)
|
|
502
|
+
return Promise.reject(new Error("Cannot read a closed ZIP archive"));
|
|
503
|
+
const result = pending.then(async () => {
|
|
504
|
+
const zip = await open2();
|
|
505
|
+
try {
|
|
506
|
+
return await operation(zip);
|
|
507
|
+
} finally {
|
|
508
|
+
zip.close();
|
|
509
|
+
}
|
|
510
|
+
});
|
|
511
|
+
pending = result.then(
|
|
512
|
+
() => void 0,
|
|
513
|
+
() => void 0
|
|
514
|
+
);
|
|
515
|
+
return result;
|
|
516
|
+
};
|
|
517
|
+
const withEntry = (name, operation) => run(async (zip) => {
|
|
518
|
+
let exact;
|
|
519
|
+
let alias;
|
|
520
|
+
let aliasCollision = false;
|
|
521
|
+
await scanNodeZip(zip, (entry) => {
|
|
522
|
+
if (entry.fileName === name) exact = entry;
|
|
523
|
+
if (normalizeNodeZipName(entry.fileName) === name) {
|
|
524
|
+
if (alias !== void 0 && alias.fileName !== entry.fileName)
|
|
525
|
+
aliasCollision = true;
|
|
526
|
+
alias = entry;
|
|
527
|
+
}
|
|
528
|
+
});
|
|
529
|
+
if ((exact === void 0 || options.entryNameMode === "normalized") && aliasCollision) {
|
|
530
|
+
let bestPosition = -1;
|
|
531
|
+
const candidates = await open2();
|
|
532
|
+
try {
|
|
533
|
+
await scanNodeZip(candidates, async (entry) => {
|
|
534
|
+
if (normalizeNodeZipName(entry.fileName) !== name) return;
|
|
535
|
+
const probe = await open2();
|
|
536
|
+
let position = 0;
|
|
537
|
+
try {
|
|
538
|
+
await scanNodeZip(probe, (candidate) => {
|
|
539
|
+
if (candidate.fileName === entry.fileName) return false;
|
|
540
|
+
position++;
|
|
541
|
+
});
|
|
542
|
+
} finally {
|
|
543
|
+
probe.close();
|
|
544
|
+
}
|
|
545
|
+
if (position >= bestPosition) {
|
|
546
|
+
bestPosition = position;
|
|
547
|
+
alias = entry;
|
|
548
|
+
}
|
|
549
|
+
});
|
|
550
|
+
return await operation(candidates, alias);
|
|
551
|
+
} finally {
|
|
552
|
+
candidates.close();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
return await operation(
|
|
556
|
+
zip,
|
|
557
|
+
options.entryNameMode === "normalized" ? alias : exact ?? alias
|
|
558
|
+
);
|
|
559
|
+
});
|
|
483
560
|
return {
|
|
484
561
|
close: () => {
|
|
485
|
-
if (!closed) zipFile.close();
|
|
486
562
|
closed = true;
|
|
487
|
-
|
|
563
|
+
closing ??= pending.then(() => handle.close());
|
|
564
|
+
return closing;
|
|
488
565
|
},
|
|
489
|
-
copyEntry:
|
|
490
|
-
if (closed) throw new Error("Cannot read a closed ZIP archive");
|
|
491
|
-
const entry = entries.get(name);
|
|
566
|
+
copyEntry: (name, target) => withEntry(name, async (zip, entry) => {
|
|
492
567
|
if (entry === void 0) return false;
|
|
493
|
-
await copyNodeZipEntry(
|
|
568
|
+
await copyNodeZipEntry(zip, entry, target);
|
|
494
569
|
return true;
|
|
495
|
-
},
|
|
496
|
-
getEntrySize: (name) =>
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
listEntries: () =>
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
570
|
+
}),
|
|
571
|
+
getEntrySize: (name) => withEntry(
|
|
572
|
+
name,
|
|
573
|
+
(_zip, entry) => Promise.resolve(entry?.uncompressedSize)
|
|
574
|
+
),
|
|
575
|
+
listEntries: () => run(async (zip) => {
|
|
576
|
+
const names = /* @__PURE__ */ new Set();
|
|
577
|
+
await scanNodeZip(zip, (entry) => {
|
|
578
|
+
names.add(entry.fileName);
|
|
579
|
+
});
|
|
580
|
+
return [...names];
|
|
581
|
+
}),
|
|
582
|
+
readEntryRange: (name, offset, length) => withEntry(name, async (zip, entry) => {
|
|
504
583
|
if (entry === void 0) return void 0;
|
|
505
|
-
return await readNodeZipEntryRange(
|
|
506
|
-
},
|
|
507
|
-
readEntry: async (
|
|
508
|
-
if (closed) throw new Error("Cannot read a closed ZIP archive");
|
|
509
|
-
const entry = entries.get(name);
|
|
584
|
+
return await readNodeZipEntryRange(zip, entry, offset, length);
|
|
585
|
+
}),
|
|
586
|
+
readEntry: (name) => withEntry(name, async (zip, entry) => {
|
|
510
587
|
if (entry === void 0) return void 0;
|
|
511
|
-
return await readNodeZipEntry(
|
|
512
|
-
}
|
|
588
|
+
return await readNodeZipEntry(zip, entry);
|
|
589
|
+
})
|
|
513
590
|
};
|
|
514
591
|
}
|
|
592
|
+
var NodeZipSource = class extends yauzl.RandomAccessReader {
|
|
593
|
+
constructor(handle) {
|
|
594
|
+
super();
|
|
595
|
+
this.handle = handle;
|
|
596
|
+
}
|
|
597
|
+
handle;
|
|
598
|
+
read(buffer, offset, length, position, callback) {
|
|
599
|
+
const read2 = (written) => {
|
|
600
|
+
if (written === length) {
|
|
601
|
+
callback(null);
|
|
602
|
+
return;
|
|
603
|
+
}
|
|
604
|
+
fs.read(
|
|
605
|
+
this.handle.fd,
|
|
606
|
+
buffer,
|
|
607
|
+
offset + written,
|
|
608
|
+
length - written,
|
|
609
|
+
position + written,
|
|
610
|
+
(error, bytesRead) => {
|
|
611
|
+
if (error) callback(error);
|
|
612
|
+
else if (bytesRead === 0)
|
|
613
|
+
callback(new Error("Unexpected end of ZIP file"));
|
|
614
|
+
else read2(written + bytesRead);
|
|
615
|
+
}
|
|
616
|
+
);
|
|
617
|
+
};
|
|
618
|
+
read2(0);
|
|
619
|
+
}
|
|
620
|
+
_readStreamForRange(start, end) {
|
|
621
|
+
const handle = this.handle;
|
|
622
|
+
return Readable.from(
|
|
623
|
+
(async function* () {
|
|
624
|
+
for (let position = start; position < end; ) {
|
|
625
|
+
const buffer = Buffer.allocUnsafe(
|
|
626
|
+
Math.min(64 * 1024, end - position)
|
|
627
|
+
);
|
|
628
|
+
const { bytesRead } = await handle.read(
|
|
629
|
+
buffer,
|
|
630
|
+
0,
|
|
631
|
+
buffer.length,
|
|
632
|
+
position
|
|
633
|
+
);
|
|
634
|
+
if (bytesRead === 0) return;
|
|
635
|
+
position += bytesRead;
|
|
636
|
+
yield buffer.subarray(0, bytesRead);
|
|
637
|
+
}
|
|
638
|
+
})()
|
|
639
|
+
);
|
|
640
|
+
}
|
|
641
|
+
};
|
|
642
|
+
function normalizeNodeZipName(name) {
|
|
643
|
+
const normalized = name.replaceAll("\\", "/").trim().split("/").filter((part) => part !== "" && part !== ".").join("/");
|
|
644
|
+
return normalized.split("/").includes("..") ? void 0 : normalized;
|
|
645
|
+
}
|
|
646
|
+
async function scanNodeZip(zip, visit) {
|
|
647
|
+
await new Promise((resolve4, reject) => {
|
|
648
|
+
const cleanup = () => {
|
|
649
|
+
zip.off("entry", onEntry);
|
|
650
|
+
zip.off("end", onEnd);
|
|
651
|
+
zip.off("error", onError);
|
|
652
|
+
};
|
|
653
|
+
const onError = (error) => {
|
|
654
|
+
cleanup();
|
|
655
|
+
reject(error);
|
|
656
|
+
};
|
|
657
|
+
const onEnd = () => {
|
|
658
|
+
cleanup();
|
|
659
|
+
resolve4();
|
|
660
|
+
};
|
|
661
|
+
const onEntry = (entry) => {
|
|
662
|
+
void Promise.resolve().then(() => entry.fileName.endsWith("/") ? void 0 : visit(entry)).then((keepReading) => {
|
|
663
|
+
if (keepReading === false) onEnd();
|
|
664
|
+
else zip.readEntry();
|
|
665
|
+
}).catch(
|
|
666
|
+
(error) => onError(
|
|
667
|
+
error instanceof Error ? error : new Error("Cannot scan ZIP", { cause: error })
|
|
668
|
+
)
|
|
669
|
+
);
|
|
670
|
+
};
|
|
671
|
+
zip.on("entry", onEntry);
|
|
672
|
+
zip.once("end", onEnd);
|
|
673
|
+
zip.once("error", onError);
|
|
674
|
+
zip.readEntry();
|
|
675
|
+
});
|
|
676
|
+
}
|
|
515
677
|
async function copyNodeZipEntry(zipFile, entry, target) {
|
|
516
678
|
const writer = await target.openWriter();
|
|
517
679
|
try {
|
|
@@ -1282,17 +1444,29 @@ function resolveWikiGraphRuntimePath(path) {
|
|
|
1282
1444
|
|
|
1283
1445
|
// src/archive/target.ts
|
|
1284
1446
|
import { realpath, stat as stat2 } from "fs/promises";
|
|
1285
|
-
import { basename as basename2, dirname as dirname2,
|
|
1447
|
+
import { basename as basename2, dirname as dirname2, join as join3, resolve as resolve3 } from "path";
|
|
1286
1448
|
import {
|
|
1287
1449
|
formatLocatedWikiGraphUri,
|
|
1288
1450
|
formatWikiGraphLibraryUri,
|
|
1289
|
-
|
|
1290
|
-
|
|
1451
|
+
findWikiGraphLibraryByPhysicalIdentity,
|
|
1452
|
+
findWikiGraphLibraryArchivePhysicalAliases,
|
|
1291
1453
|
parseLocatedWikiGraphUri,
|
|
1292
1454
|
parseWikiGraphLibraryUri,
|
|
1293
1455
|
resolveWikiGraphLibrary,
|
|
1294
|
-
resolveWikiGraphLibraryArchiveFile
|
|
1456
|
+
resolveWikiGraphLibraryArchiveFile,
|
|
1457
|
+
isWikiGraphSchemaVersionError,
|
|
1458
|
+
WikiGraphSchemaVersionError
|
|
1295
1459
|
} from "wiki-graph-core";
|
|
1460
|
+
function rethrowArchiveSchemaError(error, target) {
|
|
1461
|
+
if (isWikiGraphSchemaVersionError(error) && error.target.kind === "archive") {
|
|
1462
|
+
throw new WikiGraphSchemaVersionError(
|
|
1463
|
+
target.kind === "standalone" ? { kind: "archive", path: resolveWikiGraphRuntimePath(target.path) } : { kind: "library", uri: target.uri.split("/arc/")[0] },
|
|
1464
|
+
error.actualVersion,
|
|
1465
|
+
error.supportedVersion
|
|
1466
|
+
);
|
|
1467
|
+
}
|
|
1468
|
+
throw error;
|
|
1469
|
+
}
|
|
1296
1470
|
function requireWikiGraphArchiveFile(location) {
|
|
1297
1471
|
return location.archiveFile;
|
|
1298
1472
|
}
|
|
@@ -1313,12 +1487,7 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
|
|
|
1313
1487
|
const path = resolveWikiGraphRuntimePath(inputPath);
|
|
1314
1488
|
const candidate = await canonicalPath(path);
|
|
1315
1489
|
const candidateIdentity = await readFileIdentity(path);
|
|
1316
|
-
const
|
|
1317
|
-
const matches = await findMatchingMembers(
|
|
1318
|
-
libraries,
|
|
1319
|
-
candidate,
|
|
1320
|
-
candidateIdentity
|
|
1321
|
-
);
|
|
1490
|
+
const matches = await findMatchingMembers(candidate, candidateIdentity);
|
|
1322
1491
|
if (matches.length > 0) {
|
|
1323
1492
|
const match = requireUnambiguousManagedMatch(path, matches);
|
|
1324
1493
|
throw new WikiGraphArchiveOwnershipError(
|
|
@@ -1327,15 +1496,26 @@ async function assertStandaloneWikiGraphArchivePath(inputPath) {
|
|
|
1327
1496
|
)}: ${path}. Use the library UUID URI ${match.archive.uri} instead.`
|
|
1328
1497
|
);
|
|
1329
1498
|
}
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1499
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
1500
|
+
for (const start of [candidate, resolve3(path)]) {
|
|
1501
|
+
for (let parent = dirname2(start); ; parent = dirname2(parent)) {
|
|
1502
|
+
ancestors.add(parent);
|
|
1503
|
+
if (dirname2(parent) === parent) break;
|
|
1504
|
+
}
|
|
1505
|
+
}
|
|
1506
|
+
for (const parent of ancestors) {
|
|
1507
|
+
const identity = await readFileIdentity(parent);
|
|
1508
|
+
const library = await findWikiGraphLibraryByPhysicalIdentity(
|
|
1509
|
+
identity,
|
|
1510
|
+
new NodeDirectory(parent).identity
|
|
1338
1511
|
);
|
|
1512
|
+
if (library !== void 0) {
|
|
1513
|
+
throw new WikiGraphArchiveOwnershipError(
|
|
1514
|
+
`Standalone archive path belongs to registered library ${formatWikiGraphLibraryUri(
|
|
1515
|
+
library.isDefault ? void 0 : library.publicId
|
|
1516
|
+
)}: ${path}. Scan the library, then address the archive by its library UUID URI.`
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1339
1519
|
}
|
|
1340
1520
|
return path;
|
|
1341
1521
|
}
|
|
@@ -1393,48 +1573,35 @@ async function resolveLibraryLocation(target) {
|
|
|
1393
1573
|
async function canonicalPath(path) {
|
|
1394
1574
|
try {
|
|
1395
1575
|
return await realpath(path);
|
|
1396
|
-
} catch {
|
|
1576
|
+
} catch (error) {
|
|
1577
|
+
if (!(typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR")))
|
|
1578
|
+
throw error;
|
|
1397
1579
|
const absolute = resolve3(path);
|
|
1398
1580
|
const parent = dirname2(absolute);
|
|
1399
1581
|
return parent === absolute ? absolute : join3(await canonicalPath(parent), basename2(absolute));
|
|
1400
1582
|
}
|
|
1401
1583
|
}
|
|
1402
|
-
function
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
}
|
|
1406
|
-
async function findMatchingMembers(libraries, candidate, candidateIdentity) {
|
|
1584
|
+
async function findMatchingMembers(candidate, candidateIdentity) {
|
|
1585
|
+
if (candidateIdentity === void 0) return [];
|
|
1586
|
+
const archives = await findWikiGraphLibraryArchivePhysicalAliases(candidateIdentity);
|
|
1407
1587
|
const members = [];
|
|
1408
|
-
for (const
|
|
1409
|
-
const
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
});
|
|
1414
|
-
for (const archive of archives) {
|
|
1415
|
-
const physical = archive.file ?? archive.directory;
|
|
1416
|
-
if (physical === void 0) continue;
|
|
1588
|
+
for (const archive of archives) {
|
|
1589
|
+
const parsed = parseWikiGraphLibraryUri(archive.libraryUri);
|
|
1590
|
+
const library = await resolveWikiGraphLibrary(parsed);
|
|
1591
|
+
const physical = archive.file ?? archive.directory;
|
|
1592
|
+
if (library !== void 0 && physical !== void 0)
|
|
1417
1593
|
members.push({
|
|
1418
1594
|
archive,
|
|
1419
1595
|
library,
|
|
1420
1596
|
memberPath: getNodeResourcePath(physical)
|
|
1421
1597
|
});
|
|
1422
|
-
}
|
|
1423
1598
|
}
|
|
1424
1599
|
const exact = [];
|
|
1425
1600
|
for (const member of members) {
|
|
1426
|
-
if (await canonicalPath(member.memberPath) === candidate)
|
|
1601
|
+
if (await canonicalPath(member.memberPath) === candidate)
|
|
1427
1602
|
exact.push(member);
|
|
1428
|
-
}
|
|
1429
1603
|
}
|
|
1430
|
-
|
|
1431
|
-
const identityMatches = [];
|
|
1432
|
-
for (const member of members) {
|
|
1433
|
-
if (await readFileIdentity(member.memberPath) === candidateIdentity) {
|
|
1434
|
-
identityMatches.push(member);
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
return identityMatches;
|
|
1604
|
+
return exact.length > 0 ? exact : members;
|
|
1438
1605
|
}
|
|
1439
1606
|
function requireUnambiguousManagedMatch(path, matches) {
|
|
1440
1607
|
if (matches.length === 1) return matches[0];
|
|
@@ -1446,8 +1613,10 @@ async function readFileIdentity(path) {
|
|
|
1446
1613
|
try {
|
|
1447
1614
|
const value = await stat2(path);
|
|
1448
1615
|
return `${value.dev}:${value.ino}`;
|
|
1449
|
-
} catch {
|
|
1450
|
-
|
|
1616
|
+
} catch (error) {
|
|
1617
|
+
if (typeof error === "object" && error !== null && "code" in error && (error.code === "ENOENT" || error.code === "ENOTDIR"))
|
|
1618
|
+
return void 0;
|
|
1619
|
+
throw error;
|
|
1451
1620
|
}
|
|
1452
1621
|
}
|
|
1453
1622
|
|
|
@@ -1509,11 +1678,15 @@ var WikiGraphConversionManager = class {
|
|
|
1509
1678
|
if (!("path" in options.input)) {
|
|
1510
1679
|
throw new Error("wikg input requires a file path.");
|
|
1511
1680
|
}
|
|
1681
|
+
const inputPath = options.input.path;
|
|
1512
1682
|
await app.openSession(
|
|
1513
|
-
new NodeFile(
|
|
1514
|
-
await assertStandaloneWikiGraphArchivePath(options.input.path)
|
|
1515
|
-
),
|
|
1683
|
+
new NodeFile(await assertStandaloneWikiGraphArchivePath(inputPath)),
|
|
1516
1684
|
write
|
|
1685
|
+
).catch(
|
|
1686
|
+
(error) => rethrowArchiveSchemaError(error, {
|
|
1687
|
+
kind: "standalone",
|
|
1688
|
+
path: inputPath
|
|
1689
|
+
})
|
|
1517
1690
|
);
|
|
1518
1691
|
} else if ("stream" in options.input) {
|
|
1519
1692
|
await app.digestTextStreamSession(
|
|
@@ -1913,6 +2086,12 @@ import {
|
|
|
1913
2086
|
async function writeWikiGraphArchiveLocation(location, operation, options = {}) {
|
|
1914
2087
|
const cacheOnly = options.searchIndexWritebackPolicy === "cache";
|
|
1915
2088
|
const write = async (archiveFile = location.archiveFile) => {
|
|
2089
|
+
if (cacheOnly) {
|
|
2090
|
+
return await new WikiGraphArchiveFile(archiveFile).readDocument(
|
|
2091
|
+
operation,
|
|
2092
|
+
{ searchIndexWritebackPolicy: "cache" }
|
|
2093
|
+
);
|
|
2094
|
+
}
|
|
1916
2095
|
const writeOptions = {
|
|
1917
2096
|
...cacheOnly ? {} : { derivedStateKeys: [location.archiveKey, location.archivePath] },
|
|
1918
2097
|
...options.invalidateContinuationCursors === void 0 ? {} : {
|
|
@@ -2230,10 +2409,15 @@ var WikiGraphArchiveManager = class {
|
|
|
2230
2409
|
}, options.signal);
|
|
2231
2410
|
}
|
|
2232
2411
|
async open(target, options = {}) {
|
|
2233
|
-
const location = await this.#runtime.run(
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2412
|
+
const location = await this.#runtime.run(async () => {
|
|
2413
|
+
const location2 = await resolveWikiGraphArchiveLocation(target);
|
|
2414
|
+
try {
|
|
2415
|
+
await ensureWikiGraphArchiveSchemaCurrent(location2.archiveFile);
|
|
2416
|
+
} catch (error) {
|
|
2417
|
+
rethrowArchiveSchemaError(error, target);
|
|
2418
|
+
}
|
|
2419
|
+
return location2;
|
|
2420
|
+
}, options.signal);
|
|
2237
2421
|
return new WikiGraphArchiveHandle(this.#runtime, location);
|
|
2238
2422
|
}
|
|
2239
2423
|
};
|
|
@@ -2284,15 +2468,11 @@ var WikiGraphArchiveHandle = class {
|
|
|
2284
2468
|
options.queryMode,
|
|
2285
2469
|
options.signal
|
|
2286
2470
|
);
|
|
2287
|
-
const result = await this.#
|
|
2471
|
+
const result = await this.#readDocument(
|
|
2288
2472
|
async (document) => {
|
|
2289
2473
|
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2290
2474
|
embeddingProvider
|
|
2291
2475
|
});
|
|
2292
|
-
await ensureArchiveSearchIndex(document, {
|
|
2293
|
-
...chapters === void 0 ? {} : { chapters },
|
|
2294
|
-
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2295
|
-
});
|
|
2296
2476
|
return await findArchiveObjects(document, query, {
|
|
2297
2477
|
...withoutOperationAndScope(options),
|
|
2298
2478
|
archiveKey: this.archiveKey,
|
|
@@ -2301,7 +2481,6 @@ var WikiGraphArchiveHandle = class {
|
|
|
2301
2481
|
});
|
|
2302
2482
|
},
|
|
2303
2483
|
{
|
|
2304
|
-
searchIndexWritebackPolicy: "cache",
|
|
2305
2484
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2306
2485
|
}
|
|
2307
2486
|
);
|
|
@@ -2406,6 +2585,7 @@ var WikiGraphArchiveHandle = class {
|
|
|
2406
2585
|
async (document) => {
|
|
2407
2586
|
const chapters = await this.#resolveScope(document, options);
|
|
2408
2587
|
await ensureArchiveSearchIndex(document, {
|
|
2588
|
+
rebuild: true,
|
|
2409
2589
|
...chapters === void 0 ? {} : { chapters },
|
|
2410
2590
|
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2411
2591
|
});
|
|
@@ -2656,13 +2836,16 @@ var WikiGraphArchiveHandle = class {
|
|
|
2656
2836
|
return await this.#runtime.run(
|
|
2657
2837
|
async () => await withConfiguredWikimediaResolver(
|
|
2658
2838
|
objectUri,
|
|
2659
|
-
async (wikimediaOptions) =>
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2839
|
+
async (wikimediaOptions) => {
|
|
2840
|
+
const read2 = await this.#readDocument(
|
|
2841
|
+
async (document) => await prepareArchivePage(document, objectUri, {
|
|
2842
|
+
...options,
|
|
2843
|
+
...wikimediaOptions
|
|
2844
|
+
}),
|
|
2845
|
+
options
|
|
2846
|
+
);
|
|
2847
|
+
return await read2();
|
|
2848
|
+
}
|
|
2666
2849
|
),
|
|
2667
2850
|
options.signal
|
|
2668
2851
|
);
|
|
@@ -2695,15 +2878,11 @@ var WikiGraphArchiveHandle = class {
|
|
|
2695
2878
|
options.queryMode,
|
|
2696
2879
|
options.signal
|
|
2697
2880
|
);
|
|
2698
|
-
const result = await this.#
|
|
2881
|
+
const result = await this.#readDocument(
|
|
2699
2882
|
async (document) => {
|
|
2700
2883
|
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2701
2884
|
embeddingProvider
|
|
2702
2885
|
});
|
|
2703
|
-
await ensureArchiveSearchIndex(document, {
|
|
2704
|
-
...chapters === void 0 ? {} : { chapters },
|
|
2705
|
-
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2706
|
-
});
|
|
2707
2886
|
return await listRelatedArchiveObjects(document, objectUri, {
|
|
2708
2887
|
...withoutOperation(options),
|
|
2709
2888
|
...embeddingProvider === void 0 ? {} : { embeddingProvider },
|
|
@@ -2711,7 +2890,6 @@ var WikiGraphArchiveHandle = class {
|
|
|
2711
2890
|
});
|
|
2712
2891
|
},
|
|
2713
2892
|
{
|
|
2714
|
-
searchIndexWritebackPolicy: "cache",
|
|
2715
2893
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2716
2894
|
}
|
|
2717
2895
|
);
|
|
@@ -2755,15 +2933,11 @@ var WikiGraphArchiveHandle = class {
|
|
|
2755
2933
|
options.queryMode,
|
|
2756
2934
|
options.signal
|
|
2757
2935
|
);
|
|
2758
|
-
const result = await this.#
|
|
2936
|
+
const result = await this.#readDocument(
|
|
2759
2937
|
async (document) => {
|
|
2760
2938
|
const chapters = await this.#resolveQueryChapters(document, options, {
|
|
2761
2939
|
embeddingProvider
|
|
2762
2940
|
});
|
|
2763
|
-
await ensureArchiveSearchIndex(document, {
|
|
2764
|
-
...chapters === void 0 ? {} : { chapters },
|
|
2765
|
-
...embeddingProvider === void 0 ? {} : { embeddingProvider }
|
|
2766
|
-
});
|
|
2767
2941
|
return await listArchiveEvidence(document, objectUri, {
|
|
2768
2942
|
...withoutOperation(options),
|
|
2769
2943
|
...embeddingProvider === void 0 ? {} : { embeddingProvider },
|
|
@@ -2771,7 +2945,6 @@ var WikiGraphArchiveHandle = class {
|
|
|
2771
2945
|
});
|
|
2772
2946
|
},
|
|
2773
2947
|
{
|
|
2774
|
-
searchIndexWritebackPolicy: "cache",
|
|
2775
2948
|
...options.signal === void 0 ? {} : { signal: options.signal }
|
|
2776
2949
|
}
|
|
2777
2950
|
);
|
|
@@ -2888,6 +3061,8 @@ var WikiGraphArchiveHandle = class {
|
|
|
2888
3061
|
this.#location.archiveFile
|
|
2889
3062
|
).readDocument(operation),
|
|
2890
3063
|
options.signal
|
|
3064
|
+
).catch(
|
|
3065
|
+
(error) => rethrowArchiveSchemaError(error, this.#location.target)
|
|
2891
3066
|
);
|
|
2892
3067
|
}
|
|
2893
3068
|
async #writeDocument(operation, options = {}) {
|
|
@@ -2899,33 +3074,32 @@ var WikiGraphArchiveHandle = class {
|
|
|
2899
3074
|
searchIndexWritebackPolicy: options.searchIndexWritebackPolicy
|
|
2900
3075
|
}
|
|
2901
3076
|
});
|
|
2902
|
-
}, options.signal)
|
|
3077
|
+
}, options.signal).catch(
|
|
3078
|
+
(error) => rethrowArchiveSchemaError(error, this.#location.target)
|
|
3079
|
+
);
|
|
2903
3080
|
}
|
|
2904
3081
|
async #resolveScope(document, options) {
|
|
2905
3082
|
if (options.chapters !== void 0) return options.chapters;
|
|
2906
3083
|
return (await resolveArchiveScope(document, this.objectUri, options.depth))?.chapterIds;
|
|
2907
3084
|
}
|
|
2908
3085
|
async #resolveQueryChapters(document, options, capabilities) {
|
|
2909
|
-
const
|
|
3086
|
+
const parsed = parseChapterScopePath(this.objectUri);
|
|
3087
|
+
const chapters = options.chapters ?? (parsed === void 0 || parsed.kind === "collection" && options.depth === void 0 ? void 0 : await resolveIndexedArchiveChapterScope(
|
|
3088
|
+
document,
|
|
3089
|
+
parsed.kind === "chapter" ? parsed.chapterPath : void 0,
|
|
3090
|
+
options.depth
|
|
3091
|
+
));
|
|
2910
3092
|
const coverageOptions = {
|
|
2911
3093
|
...chapters === void 0 ? {} : { chapters },
|
|
2912
3094
|
...capabilities.embeddingProvider === void 0 ? {} : { embeddingProvider: capabilities.embeddingProvider },
|
|
2913
3095
|
requireEmbeddingProvider: true,
|
|
2914
3096
|
...options.queryMode === void 0 ? {} : { queryMode: options.queryMode }
|
|
2915
3097
|
};
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
}
|
|
2920
|
-
const queryable = await listArchiveQueryableChapterIds(document, {
|
|
2921
|
-
...coverageOptions
|
|
3098
|
+
await assertArchiveQueryReady(document, {
|
|
3099
|
+
...coverageOptions,
|
|
3100
|
+
...options.skipUnindexed === void 0 ? {} : { skipUnindexed: options.skipUnindexed }
|
|
2922
3101
|
});
|
|
2923
|
-
|
|
2924
|
-
throw new Error(
|
|
2925
|
-
"Wiki Graph query is not ready. No chapters in this scope have a current FTS artifact or source embedding artifact."
|
|
2926
|
-
);
|
|
2927
|
-
}
|
|
2928
|
-
return queryable;
|
|
3102
|
+
return chapters;
|
|
2929
3103
|
}
|
|
2930
3104
|
async #resolveQueryEmbeddingProvider(queryMode, signal) {
|
|
2931
3105
|
if (queryMode === "fts") return void 0;
|
|
@@ -2944,6 +3118,10 @@ var WikiGraphArchiveHandle = class {
|
|
|
2944
3118
|
async function ensureArchiveSearchIndex(document, options = {}) {
|
|
2945
3119
|
const scope = options.chapters === void 0 ? {} : { chapters: options.chapters };
|
|
2946
3120
|
if (await isArchiveSearchIndexCurrent2(document, scope)) return;
|
|
3121
|
+
if (options.rebuild !== true)
|
|
3122
|
+
throw new Error(
|
|
3123
|
+
"Archive search index is missing or dirty. Run `wg <archive-uri>/index sync` explicitly before querying."
|
|
3124
|
+
);
|
|
2947
3125
|
await rebuildArchiveSearchIndex(document, void 0, {
|
|
2948
3126
|
...scope,
|
|
2949
3127
|
...options.embeddingProvider === void 0 ? {} : { embeddingProvider: options.embeddingProvider }
|