@ontos-ai/knowhere-sdk 2.1.1 → 2.1.3
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/README.md +7 -7
- package/dist/index.d.mts +219 -318
- package/dist/index.d.ts +219 -318
- package/dist/index.js +703 -731
- package/dist/index.mjs +703 -731
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1527,10 +1527,6 @@ import JSZip2 from "jszip";
|
|
|
1527
1527
|
var pageCitationAssetsMetadataKey = "pageAssets";
|
|
1528
1528
|
var defaultImageContentType = "application/octet-stream";
|
|
1529
1529
|
var tableContentType = "text/html; charset=utf-8";
|
|
1530
|
-
var snapshotManifestKey = "manifest/current.json";
|
|
1531
|
-
var snapshotIndexKey = "index.json";
|
|
1532
|
-
var defaultSnapshotChunkPageSize = 200;
|
|
1533
|
-
var snapshotJsonContentType = "application/json; charset=utf-8";
|
|
1534
1530
|
async function storeParseResultAssets(result, options) {
|
|
1535
1531
|
if (!options) {
|
|
1536
1532
|
return {
|
|
@@ -1548,148 +1544,11 @@ async function storeParseResultAssets(result, options) {
|
|
|
1548
1544
|
}
|
|
1549
1545
|
}
|
|
1550
1546
|
const normalizedResult = Object.keys(assetUrlsByFilePath).length === 0 ? result : rewriteResultAssetUrls(result, assetUrlsByFilePath);
|
|
1551
|
-
const snapshot = await storeParsedSnapshot({
|
|
1552
|
-
result: normalizedResult,
|
|
1553
|
-
assetUrlsByFilePath,
|
|
1554
|
-
keyPrefix: normalizedKeyPrefix,
|
|
1555
|
-
options
|
|
1556
|
-
});
|
|
1557
1547
|
return {
|
|
1558
1548
|
result: normalizedResult,
|
|
1559
|
-
assetUrlsByFilePath
|
|
1560
|
-
snapshot
|
|
1561
|
-
};
|
|
1562
|
-
}
|
|
1563
|
-
async function storeParsedSnapshot(input) {
|
|
1564
|
-
const pageSize = normalizeSnapshotChunkPageSize(input.options.chunkPageSize);
|
|
1565
|
-
const totalChunks = input.result.chunks.length;
|
|
1566
|
-
const totalPages = Math.max(1, Math.ceil(totalChunks / pageSize));
|
|
1567
|
-
const chunkPageReferences = [];
|
|
1568
|
-
const chunkPageUrlsByPage = {};
|
|
1569
|
-
for (let page = 1; page <= totalPages; page += 1) {
|
|
1570
|
-
const pageChunks = input.result.chunks.slice((page - 1) * pageSize, page * pageSize);
|
|
1571
|
-
const pageKey = `${input.keyPrefix}/chunks/page-${page}.json`;
|
|
1572
|
-
const chunkPage = {
|
|
1573
|
-
version: 1,
|
|
1574
|
-
jobId: input.result.jobId,
|
|
1575
|
-
revisionKey: input.options.revisionKey ?? input.result.jobId,
|
|
1576
|
-
documentId: input.result.documentId,
|
|
1577
|
-
namespace: input.result.namespace,
|
|
1578
|
-
sourceFileName: input.result.manifest.sourceFileName,
|
|
1579
|
-
page,
|
|
1580
|
-
pageSize,
|
|
1581
|
-
total: totalChunks,
|
|
1582
|
-
totalPages,
|
|
1583
|
-
chunks: pageChunks.map(
|
|
1584
|
-
(chunk, index) => toSnapshotChunk(chunk, (page - 1) * pageSize + index + 1)
|
|
1585
|
-
)
|
|
1586
|
-
};
|
|
1587
|
-
const pageUrl = await writeJsonObject({
|
|
1588
|
-
key: pageKey,
|
|
1589
|
-
value: chunkPage,
|
|
1590
|
-
adapter: input.options.adapter
|
|
1591
|
-
});
|
|
1592
|
-
if (pageUrl) chunkPageUrlsByPage[page] = pageUrl;
|
|
1593
|
-
chunkPageReferences.push({
|
|
1594
|
-
page,
|
|
1595
|
-
pageSize,
|
|
1596
|
-
chunkCount: pageChunks.length,
|
|
1597
|
-
key: pageKey,
|
|
1598
|
-
url: pageUrl
|
|
1599
|
-
});
|
|
1600
|
-
}
|
|
1601
|
-
const manifest = {
|
|
1602
|
-
version: 1,
|
|
1603
|
-
kind: "knowhere-parsed-result-snapshot",
|
|
1604
|
-
jobId: input.result.jobId,
|
|
1605
|
-
revisionKey: input.options.revisionKey ?? input.result.jobId,
|
|
1606
|
-
documentId: input.result.documentId,
|
|
1607
|
-
namespace: input.result.namespace,
|
|
1608
|
-
sourceFileName: input.result.manifest.sourceFileName,
|
|
1609
|
-
totalChunks,
|
|
1610
|
-
typeCounts: countSnapshotChunkTypes(input.result.chunks),
|
|
1611
|
-
chunkPageSize: pageSize,
|
|
1612
|
-
chunkPages: chunkPageReferences,
|
|
1613
|
-
assetUrlsByFilePath: input.assetUrlsByFilePath,
|
|
1614
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1615
|
-
};
|
|
1616
|
-
const manifestKey = `${input.keyPrefix}/${snapshotManifestKey}`;
|
|
1617
|
-
const indexKey = `${input.keyPrefix}/${snapshotIndexKey}`;
|
|
1618
|
-
const manifestUrl = await writeJsonObject({
|
|
1619
|
-
key: manifestKey,
|
|
1620
|
-
value: manifest,
|
|
1621
|
-
adapter: input.options.adapter
|
|
1622
|
-
});
|
|
1623
|
-
const indexUrl = await writeJsonObject({
|
|
1624
|
-
key: indexKey,
|
|
1625
|
-
value: manifest,
|
|
1626
|
-
adapter: input.options.adapter
|
|
1627
|
-
});
|
|
1628
|
-
return {
|
|
1629
|
-
manifest,
|
|
1630
|
-
manifestKey,
|
|
1631
|
-
manifestUrl,
|
|
1632
|
-
indexKey,
|
|
1633
|
-
indexUrl,
|
|
1634
|
-
chunkPageUrlsByPage
|
|
1635
|
-
};
|
|
1636
|
-
}
|
|
1637
|
-
function countSnapshotChunkTypes(chunks) {
|
|
1638
|
-
return chunks.reduce(
|
|
1639
|
-
(counts, chunk) => {
|
|
1640
|
-
counts[chunk.type] += 1;
|
|
1641
|
-
return counts;
|
|
1642
|
-
},
|
|
1643
|
-
{ text: 0, image: 0, table: 0, page: 0 }
|
|
1644
|
-
);
|
|
1645
|
-
}
|
|
1646
|
-
async function writeJsonObject(input) {
|
|
1647
|
-
const result = await input.adapter.writeObject({
|
|
1648
|
-
key: input.key,
|
|
1649
|
-
body: Buffer.from(JSON.stringify(input.value, null, 2), "utf8"),
|
|
1650
|
-
contentType: snapshotJsonContentType,
|
|
1651
|
-
metadata: {
|
|
1652
|
-
kind: "knowhere-parsed-result-snapshot"
|
|
1653
|
-
}
|
|
1654
|
-
});
|
|
1655
|
-
return result.url ?? await input.adapter.getObjectUrl?.(result.key) ?? void 0;
|
|
1656
|
-
}
|
|
1657
|
-
function normalizeSnapshotChunkPageSize(value) {
|
|
1658
|
-
if (!Number.isInteger(value) || value === void 0) return defaultSnapshotChunkPageSize;
|
|
1659
|
-
return Math.min(Math.max(value, 1), 1e3);
|
|
1660
|
-
}
|
|
1661
|
-
function toSnapshotChunk(chunk, position) {
|
|
1662
|
-
const filePath = getSnapshotChunkFilePath(chunk);
|
|
1663
|
-
return {
|
|
1664
|
-
id: chunk.chunkId,
|
|
1665
|
-
chunkId: chunk.chunkId,
|
|
1666
|
-
chunkType: chunk.type,
|
|
1667
|
-
contentSource: chunk.contentSource,
|
|
1668
|
-
content: chunk.content,
|
|
1669
|
-
sectionPath: normalizeSnapshotSectionPath(chunk.path),
|
|
1670
|
-
sourceChunkPath: chunk.path,
|
|
1671
|
-
filePath,
|
|
1672
|
-
sortOrder: position,
|
|
1673
|
-
metadata: cloneChunkMetadata(chunk.metadata),
|
|
1674
|
-
assetUrl: getSnapshotChunkAssetUrl(chunk)
|
|
1549
|
+
assetUrlsByFilePath
|
|
1675
1550
|
};
|
|
1676
1551
|
}
|
|
1677
|
-
function normalizeSnapshotSectionPath(path4) {
|
|
1678
|
-
return path4.length > 0 ? path4 : void 0;
|
|
1679
|
-
}
|
|
1680
|
-
function getSnapshotChunkFilePath(chunk) {
|
|
1681
|
-
if (chunk.type === "image" || chunk.type === "table") {
|
|
1682
|
-
return chunk.filePath;
|
|
1683
|
-
}
|
|
1684
|
-
const filePath = chunk.metadata.filePath;
|
|
1685
|
-
return typeof filePath === "string" ? filePath : void 0;
|
|
1686
|
-
}
|
|
1687
|
-
function getSnapshotChunkAssetUrl(chunk) {
|
|
1688
|
-
return chunk.type === "image" || chunk.type === "table" ? chunk.assetUrl : void 0;
|
|
1689
|
-
}
|
|
1690
|
-
function cloneChunkMetadata(metadata) {
|
|
1691
|
-
return { ...metadata };
|
|
1692
|
-
}
|
|
1693
1552
|
async function collectStorageAssets(result, keyPrefix) {
|
|
1694
1553
|
const resultZip = await loadResultZipForPageCitationAssets(result);
|
|
1695
1554
|
return [
|
|
@@ -1926,108 +1785,212 @@ function isRecord(value) {
|
|
|
1926
1785
|
}
|
|
1927
1786
|
|
|
1928
1787
|
// src/storage/parsed-document-storage.ts
|
|
1929
|
-
|
|
1930
|
-
var
|
|
1931
|
-
var
|
|
1932
|
-
var
|
|
1788
|
+
import JSZip3 from "jszip";
|
|
1789
|
+
var parsedDocumentCommitPath = ".knowhere-sdk/commit.json";
|
|
1790
|
+
var jsonContentType = "application/json; charset=utf-8";
|
|
1791
|
+
var markdownContentType = "text/markdown; charset=utf-8";
|
|
1792
|
+
var csvContentType = "text/csv; charset=utf-8";
|
|
1793
|
+
var htmlContentType = "text/html; charset=utf-8";
|
|
1794
|
+
var binaryContentType = "application/octet-stream";
|
|
1933
1795
|
async function syncParseResultToParsedDocumentStorage(params) {
|
|
1934
1796
|
const documentId = params.documentId ?? params.result.documentId ?? params.result.jobId;
|
|
1935
1797
|
const revisionKey = params.revisionKey ?? params.result.jobId;
|
|
1936
|
-
const
|
|
1937
|
-
|
|
1798
|
+
const objects = await collectResultLayoutObjects(params.result);
|
|
1799
|
+
for (const object of objects) {
|
|
1800
|
+
await params.storage.writeObject({
|
|
1801
|
+
documentId,
|
|
1802
|
+
revisionKey,
|
|
1803
|
+
...object
|
|
1804
|
+
});
|
|
1805
|
+
}
|
|
1806
|
+
const commit = {
|
|
1807
|
+
version: 1,
|
|
1938
1808
|
documentId,
|
|
1939
|
-
revisionKey
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
1944
|
-
|
|
1945
|
-
revisionKey
|
|
1809
|
+
revisionKey,
|
|
1810
|
+
source: params.source ?? "resultZip",
|
|
1811
|
+
committedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1812
|
+
};
|
|
1813
|
+
await writeParsedDocumentJsonObject(params.storage, {
|
|
1814
|
+
documentId,
|
|
1815
|
+
revisionKey,
|
|
1816
|
+
path: parsedDocumentCommitPath,
|
|
1817
|
+
value: commit
|
|
1946
1818
|
});
|
|
1947
1819
|
return {
|
|
1948
|
-
result:
|
|
1949
|
-
snapshot: stored.snapshot,
|
|
1820
|
+
result: params.result,
|
|
1950
1821
|
documentId,
|
|
1951
|
-
revisionKey
|
|
1822
|
+
revisionKey,
|
|
1823
|
+
commit
|
|
1952
1824
|
};
|
|
1953
1825
|
}
|
|
1954
|
-
function
|
|
1955
|
-
|
|
1956
|
-
|
|
1957
|
-
|
|
1958
|
-
|
|
1959
|
-
};
|
|
1826
|
+
async function readParsedDocumentCommit(params) {
|
|
1827
|
+
const object = await params.storage.readObject({
|
|
1828
|
+
documentId: params.documentId,
|
|
1829
|
+
revisionKey: params.revisionKey,
|
|
1830
|
+
path: parsedDocumentCommitPath
|
|
1831
|
+
});
|
|
1832
|
+
if (!object) {
|
|
1833
|
+
return null;
|
|
1834
|
+
}
|
|
1835
|
+
const commit = readJsonObject(object);
|
|
1836
|
+
return commit.revisionKey === params.revisionKey && commit.documentId === params.documentId ? commit : null;
|
|
1960
1837
|
}
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1838
|
+
function readJsonObject(object) {
|
|
1839
|
+
return JSON.parse(Buffer.from(object.body).toString("utf8"));
|
|
1840
|
+
}
|
|
1841
|
+
async function collectResultLayoutObjects(result) {
|
|
1842
|
+
const objectsByPath = /* @__PURE__ */ new Map();
|
|
1843
|
+
const rawZipObjects = await collectRawZipObjects(result.rawZip);
|
|
1844
|
+
for (const object of rawZipObjects) {
|
|
1845
|
+
objectsByPath.set(object.path, object);
|
|
1846
|
+
}
|
|
1847
|
+
for (const object of collectGeneratedResultObjects(result)) {
|
|
1848
|
+
if (!objectsByPath.has(object.path)) {
|
|
1849
|
+
objectsByPath.set(object.path, object);
|
|
1850
|
+
}
|
|
1851
|
+
}
|
|
1852
|
+
return [...objectsByPath.values()].filter((object) => !isSdkMetadataPath(object.path));
|
|
1853
|
+
}
|
|
1854
|
+
async function collectRawZipObjects(rawZip) {
|
|
1855
|
+
try {
|
|
1856
|
+
const zip = await JSZip3.loadAsync(rawZip);
|
|
1857
|
+
const objects = [];
|
|
1858
|
+
for (const entry of Object.values(zip.files)) {
|
|
1859
|
+
if (entry.dir || entry.name === "result.zip") {
|
|
1860
|
+
continue;
|
|
1861
|
+
}
|
|
1862
|
+
objects.push({
|
|
1863
|
+
path: normalizeResultPath(entry.name),
|
|
1864
|
+
body: new Uint8Array(await entry.async("nodebuffer")),
|
|
1865
|
+
contentType: inferContentTypeFromPath(entry.name)
|
|
1866
|
+
});
|
|
1867
|
+
}
|
|
1868
|
+
return objects;
|
|
1869
|
+
} catch {
|
|
1870
|
+
return [];
|
|
1973
1871
|
}
|
|
1974
|
-
|
|
1975
|
-
|
|
1872
|
+
}
|
|
1873
|
+
function collectGeneratedResultObjects(result) {
|
|
1874
|
+
const objects = [
|
|
1875
|
+
createJsonObject("manifest.json", result.manifest),
|
|
1876
|
+
createJsonObject("chunks.json", keysToSnake(serializeChunks2(result.chunks)))
|
|
1877
|
+
];
|
|
1878
|
+
if (result.docNav) {
|
|
1879
|
+
objects.push(createJsonObject("doc_nav.json", result.docNav));
|
|
1880
|
+
}
|
|
1881
|
+
if (result.fullMarkdown) {
|
|
1882
|
+
objects.push(createTextObject("full.md", result.fullMarkdown, markdownContentType));
|
|
1883
|
+
}
|
|
1884
|
+
if (result.chunksSlim) {
|
|
1885
|
+
objects.push(createJsonObject("chunks_slim.json", { chunks: result.chunksSlim }));
|
|
1886
|
+
}
|
|
1887
|
+
if (result.hierarchy) {
|
|
1888
|
+
objects.push(createJsonObject("hierarchy.json", result.hierarchy));
|
|
1889
|
+
}
|
|
1890
|
+
if (result.tocHierarchies) {
|
|
1891
|
+
objects.push(createJsonObject("toc_hierarchies.json", result.tocHierarchies));
|
|
1892
|
+
}
|
|
1893
|
+
if (result.kbCsv) {
|
|
1894
|
+
objects.push(createTextObject("kb.csv", result.kbCsv, csvContentType));
|
|
1976
1895
|
}
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
Buffer.from(input.body).toString("utf8")
|
|
1896
|
+
if (result.hierarchyViewHtml) {
|
|
1897
|
+
objects.push(
|
|
1898
|
+
createTextObject("hierarchy_view.html", result.hierarchyViewHtml, htmlContentType)
|
|
1981
1899
|
);
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1900
|
+
}
|
|
1901
|
+
for (const chunk of result.imageChunks) {
|
|
1902
|
+
objects.push({
|
|
1903
|
+
path: normalizeResultPath(chunk.filePath),
|
|
1904
|
+
body: new Uint8Array(chunk.data),
|
|
1905
|
+
contentType: inferContentTypeFromPath(chunk.filePath),
|
|
1906
|
+
metadata: {
|
|
1907
|
+
chunkId: chunk.chunkId,
|
|
1908
|
+
chunkType: chunk.type,
|
|
1909
|
+
sourcePath: chunk.filePath
|
|
1910
|
+
}
|
|
1986
1911
|
});
|
|
1987
|
-
return { key: input.key };
|
|
1988
1912
|
}
|
|
1989
|
-
const
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1913
|
+
for (const chunk of result.tableChunks) {
|
|
1914
|
+
objects.push({
|
|
1915
|
+
path: normalizeResultPath(chunk.filePath),
|
|
1916
|
+
body: Buffer.from(chunk.html, "utf8"),
|
|
1917
|
+
contentType: htmlContentType,
|
|
1918
|
+
metadata: {
|
|
1919
|
+
chunkId: chunk.chunkId,
|
|
1920
|
+
chunkType: chunk.type,
|
|
1921
|
+
sourcePath: chunk.filePath
|
|
1922
|
+
}
|
|
1923
|
+
});
|
|
1924
|
+
}
|
|
1925
|
+
return objects;
|
|
1926
|
+
}
|
|
1927
|
+
function serializeChunks2(chunks) {
|
|
1997
1928
|
return {
|
|
1998
|
-
|
|
1999
|
-
|
|
1929
|
+
chunks: chunks.map((chunk) => {
|
|
1930
|
+
const rawChunk = {
|
|
1931
|
+
chunkId: chunk.chunkId,
|
|
1932
|
+
type: chunk.type,
|
|
1933
|
+
contentSource: chunk.contentSource,
|
|
1934
|
+
content: chunk.content,
|
|
1935
|
+
path: chunk.path,
|
|
1936
|
+
metadata: chunk.metadata
|
|
1937
|
+
};
|
|
1938
|
+
if (chunk.type === "image" || chunk.type === "table") {
|
|
1939
|
+
return {
|
|
1940
|
+
...rawChunk,
|
|
1941
|
+
filePath: chunk.filePath,
|
|
1942
|
+
assetUrl: chunk.assetUrl
|
|
1943
|
+
};
|
|
1944
|
+
}
|
|
1945
|
+
return rawChunk;
|
|
1946
|
+
})
|
|
2000
1947
|
};
|
|
2001
1948
|
}
|
|
2002
|
-
async function
|
|
2003
|
-
|
|
2004
|
-
if (storagePath === manifestStoragePath || storagePath === indexStoragePath || chunkPagePathPattern.test(storagePath)) {
|
|
2005
|
-
return null;
|
|
2006
|
-
}
|
|
2007
|
-
const url = await params.storage.getAssetUrl({
|
|
1949
|
+
async function writeParsedDocumentJsonObject(storage, params) {
|
|
1950
|
+
await storage.writeObject({
|
|
2008
1951
|
documentId: params.documentId,
|
|
2009
1952
|
revisionKey: params.revisionKey,
|
|
2010
|
-
|
|
1953
|
+
path: params.path,
|
|
1954
|
+
body: Buffer.from(JSON.stringify(params.value, null, 2), "utf8"),
|
|
1955
|
+
contentType: jsonContentType
|
|
2011
1956
|
});
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
1957
|
+
}
|
|
1958
|
+
function createJsonObject(path4, value) {
|
|
1959
|
+
return {
|
|
1960
|
+
path: path4,
|
|
1961
|
+
body: Buffer.from(JSON.stringify(value, null, 2), "utf8"),
|
|
1962
|
+
contentType: jsonContentType
|
|
1963
|
+
};
|
|
1964
|
+
}
|
|
1965
|
+
function createTextObject(path4, value, contentType) {
|
|
1966
|
+
return {
|
|
1967
|
+
path: path4,
|
|
1968
|
+
body: Buffer.from(value, "utf8"),
|
|
1969
|
+
contentType
|
|
1970
|
+
};
|
|
1971
|
+
}
|
|
1972
|
+
function inferContentTypeFromPath(filePath) {
|
|
1973
|
+
const lower = filePath.toLowerCase();
|
|
1974
|
+
if (lower.endsWith(".json")) return jsonContentType;
|
|
1975
|
+
if (lower.endsWith(".md")) return markdownContentType;
|
|
1976
|
+
if (lower.endsWith(".csv")) return csvContentType;
|
|
1977
|
+
if (lower.endsWith(".html") || lower.endsWith(".htm")) return htmlContentType;
|
|
1978
|
+
if (lower.endsWith(".png")) return "image/png";
|
|
1979
|
+
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
1980
|
+
if (lower.endsWith(".gif")) return "image/gif";
|
|
1981
|
+
if (lower.endsWith(".webp")) return "image/webp";
|
|
1982
|
+
if (lower.endsWith(".svg")) return "image/svg+xml";
|
|
1983
|
+
return binaryContentType;
|
|
1984
|
+
}
|
|
1985
|
+
function normalizeResultPath(value) {
|
|
1986
|
+
const normalized = value.replaceAll("\\", "/").replace(/^\.\/+/, "");
|
|
1987
|
+
if (normalized.length === 0 || normalized.includes("\0") || normalized.startsWith("/") || normalized.split("/").some((part) => part.length === 0 || part === "." || part === "..")) {
|
|
1988
|
+
throw new Error(`Invalid parsed result path: ${value}`);
|
|
2021
1989
|
}
|
|
2022
|
-
return
|
|
2023
|
-
documentId: params.documentId,
|
|
2024
|
-
revisionKey: params.revisionKey,
|
|
2025
|
-
sourcePath: storagePath
|
|
2026
|
-
});
|
|
1990
|
+
return normalized;
|
|
2027
1991
|
}
|
|
2028
|
-
function
|
|
2029
|
-
|
|
2030
|
-
return key.startsWith(prefix) ? key.slice(prefix.length) : key;
|
|
1992
|
+
function isSdkMetadataPath(path4) {
|
|
1993
|
+
return path4 === ".knowhere-sdk" || path4.startsWith(".knowhere-sdk/");
|
|
2031
1994
|
}
|
|
2032
1995
|
|
|
2033
1996
|
// src/knowledge/local-store.ts
|
|
@@ -2262,7 +2225,6 @@ var MAX_GREP_LIMIT = 50;
|
|
|
2262
2225
|
var DEFAULT_CONTEXT_CHARS = 80;
|
|
2263
2226
|
var DEFAULT_REMOTE_SCAN_PAGE_SIZE = 100;
|
|
2264
2227
|
var DEFAULT_MAX_SYNC_PAGES = 10;
|
|
2265
|
-
var DEFAULT_MAX_SYNC_ASSETS = 20;
|
|
2266
2228
|
var DEFAULT_SYNC_DEADLINE_MS = 8e3;
|
|
2267
2229
|
var DEFAULT_GREP_MAX_PAGES = 50;
|
|
2268
2230
|
var DEFAULT_GREP_DEADLINE_MS = 8e3;
|
|
@@ -2270,6 +2232,7 @@ var DEFAULT_OUTLINE_MAX_PAGES = 50;
|
|
|
2270
2232
|
var DEFAULT_OUTLINE_DEADLINE_MS = 8e3;
|
|
2271
2233
|
var SAFE_LOCAL_DOCUMENT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
2272
2234
|
var REMOTE_DOCUMENT_ID_PATTERN = /^doc[_-]/;
|
|
2235
|
+
var remoteReconstructionPageDirectory = ".knowhere-sdk/remote-reconstruction/pages";
|
|
2273
2236
|
var Knowledge = class _Knowledge {
|
|
2274
2237
|
client;
|
|
2275
2238
|
store;
|
|
@@ -2304,8 +2267,7 @@ var Knowledge = class _Knowledge {
|
|
|
2304
2267
|
return {
|
|
2305
2268
|
document,
|
|
2306
2269
|
result,
|
|
2307
|
-
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2308
|
-
parsedSnapshot: storedAssets.snapshot
|
|
2270
|
+
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2309
2271
|
};
|
|
2310
2272
|
}
|
|
2311
2273
|
/** @deprecated Use parseToLocalCache for local cache imports or the top-level client.parse for server-safe parsing. */
|
|
@@ -2350,8 +2312,7 @@ var Knowledge = class _Knowledge {
|
|
|
2350
2312
|
const result = syncedStorage.result;
|
|
2351
2313
|
return {
|
|
2352
2314
|
result,
|
|
2353
|
-
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2354
|
-
parsedSnapshot: syncedStorage.snapshot ?? storedAssets.snapshot
|
|
2315
|
+
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2355
2316
|
};
|
|
2356
2317
|
}
|
|
2357
2318
|
async importJobResult(params) {
|
|
@@ -2363,8 +2324,7 @@ var Knowledge = class _Knowledge {
|
|
|
2363
2324
|
return {
|
|
2364
2325
|
document,
|
|
2365
2326
|
result,
|
|
2366
|
-
assetUrlsByFilePath: stored.assetUrlsByFilePath
|
|
2367
|
-
parsedSnapshot: stored.parsedSnapshot
|
|
2327
|
+
assetUrlsByFilePath: stored.assetUrlsByFilePath
|
|
2368
2328
|
};
|
|
2369
2329
|
}
|
|
2370
2330
|
/** @deprecated Use importJobResult for local cache imports or loadJobResult for server-safe loads. */
|
|
@@ -2387,14 +2347,13 @@ var Knowledge = class _Knowledge {
|
|
|
2387
2347
|
result: loadedResult,
|
|
2388
2348
|
storage: parsedStorageConfig.storage,
|
|
2389
2349
|
documentId: loadedResult.documentId ?? normalized.localDocumentId ?? normalized.jobId,
|
|
2390
|
-
revisionKey: params.revisionKey ?? normalized.jobId
|
|
2391
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2350
|
+
revisionKey: params.revisionKey ?? normalized.jobId
|
|
2392
2351
|
});
|
|
2393
2352
|
return {
|
|
2394
2353
|
documentId: synced2.documentId,
|
|
2395
2354
|
revisionKey: synced2.revisionKey,
|
|
2396
2355
|
completed: true,
|
|
2397
|
-
|
|
2356
|
+
commit: synced2.commit
|
|
2398
2357
|
};
|
|
2399
2358
|
}
|
|
2400
2359
|
if (!normalized.localDocumentId) {
|
|
@@ -2405,14 +2364,13 @@ var Knowledge = class _Knowledge {
|
|
|
2405
2364
|
result,
|
|
2406
2365
|
storage: parsedStorageConfig.storage,
|
|
2407
2366
|
documentId: result.documentId ?? normalized.localDocumentId,
|
|
2408
|
-
revisionKey: params.revisionKey ?? result.jobId
|
|
2409
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2367
|
+
revisionKey: params.revisionKey ?? result.jobId
|
|
2410
2368
|
});
|
|
2411
2369
|
return {
|
|
2412
2370
|
documentId: synced.documentId,
|
|
2413
2371
|
revisionKey: synced.revisionKey,
|
|
2414
2372
|
completed: true,
|
|
2415
|
-
|
|
2373
|
+
commit: synced.commit
|
|
2416
2374
|
};
|
|
2417
2375
|
}
|
|
2418
2376
|
async syncParseResultToConfiguredStorage(result) {
|
|
@@ -2422,12 +2380,11 @@ var Knowledge = class _Knowledge {
|
|
|
2422
2380
|
}
|
|
2423
2381
|
const synced = await syncParseResultToParsedDocumentStorage({
|
|
2424
2382
|
result,
|
|
2425
|
-
storage: parsedStorageConfig.storage
|
|
2426
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2383
|
+
storage: parsedStorageConfig.storage
|
|
2427
2384
|
});
|
|
2428
2385
|
return {
|
|
2429
2386
|
result: synced.result,
|
|
2430
|
-
|
|
2387
|
+
commit: synced.commit
|
|
2431
2388
|
};
|
|
2432
2389
|
}
|
|
2433
2390
|
async parseWithoutClientStorageAdapter(params) {
|
|
@@ -2678,10 +2635,7 @@ var Knowledge = class _Knowledge {
|
|
|
2678
2635
|
page: pageParams.page,
|
|
2679
2636
|
pageSize: pageParams.pageSize,
|
|
2680
2637
|
chunkType: params.chunkType,
|
|
2681
|
-
includeAssetUrls:
|
|
2682
|
-
params.assetUrlPolicy,
|
|
2683
|
-
this.parsedStorageConfig
|
|
2684
|
-
)
|
|
2638
|
+
includeAssetUrls: true
|
|
2685
2639
|
});
|
|
2686
2640
|
const revisionKey = getRemoteRevisionKey(remotePage);
|
|
2687
2641
|
const stored = await this.tryReadChunksFromParsedStorage({
|
|
@@ -2692,12 +2646,7 @@ var Knowledge = class _Knowledge {
|
|
|
2692
2646
|
if (stored) {
|
|
2693
2647
|
return stored;
|
|
2694
2648
|
}
|
|
2695
|
-
const chunks =
|
|
2696
|
-
documentId,
|
|
2697
|
-
revisionKey,
|
|
2698
|
-
chunks: remotePage.chunks,
|
|
2699
|
-
assetUrlPolicy: params.assetUrlPolicy
|
|
2700
|
-
});
|
|
2649
|
+
const chunks = remotePage.chunks.map((chunk) => toRemoteReadChunk(chunk));
|
|
2701
2650
|
this.scheduleParsedStorageSync(documentId, revisionKey);
|
|
2702
2651
|
return {
|
|
2703
2652
|
document: createRemoteKnowledgeDocument({
|
|
@@ -2730,10 +2679,7 @@ var Knowledge = class _Knowledge {
|
|
|
2730
2679
|
page: 1,
|
|
2731
2680
|
pageSize: limits.remotePageSize,
|
|
2732
2681
|
chunkType: params.chunkType,
|
|
2733
|
-
includeAssetUrls:
|
|
2734
|
-
params.assetUrlPolicy,
|
|
2735
|
-
this.parsedStorageConfig
|
|
2736
|
-
)
|
|
2682
|
+
includeAssetUrls: true
|
|
2737
2683
|
});
|
|
2738
2684
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2739
2685
|
const stored = await this.tryReadChunksFromParsedStorage({
|
|
@@ -2760,18 +2706,10 @@ var Knowledge = class _Knowledge {
|
|
|
2760
2706
|
page,
|
|
2761
2707
|
pageSize: limits.remotePageSize,
|
|
2762
2708
|
chunkType: params.chunkType,
|
|
2763
|
-
includeAssetUrls:
|
|
2764
|
-
params.assetUrlPolicy,
|
|
2765
|
-
this.parsedStorageConfig
|
|
2766
|
-
)
|
|
2709
|
+
includeAssetUrls: true
|
|
2767
2710
|
});
|
|
2768
2711
|
}
|
|
2769
|
-
const chunks =
|
|
2770
|
-
documentId,
|
|
2771
|
-
revisionKey,
|
|
2772
|
-
chunks: selected.slice(0, limit),
|
|
2773
|
-
assetUrlPolicy: params.assetUrlPolicy
|
|
2774
|
-
});
|
|
2712
|
+
const chunks = selected.slice(0, limit).map((chunk) => toRemoteReadChunk(chunk));
|
|
2775
2713
|
this.scheduleParsedStorageSync(documentId, revisionKey);
|
|
2776
2714
|
return {
|
|
2777
2715
|
document: createRemoteKnowledgeDocument({
|
|
@@ -2807,7 +2745,7 @@ var Knowledge = class _Knowledge {
|
|
|
2807
2745
|
page: startPage,
|
|
2808
2746
|
pageSize: limits.remotePageSize,
|
|
2809
2747
|
chunkType: params.chunkType,
|
|
2810
|
-
includeAssetUrls:
|
|
2748
|
+
includeAssetUrls: true
|
|
2811
2749
|
});
|
|
2812
2750
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2813
2751
|
const stored = startPage === 1 ? await this.tryGrepChunksFromParsedStorage({
|
|
@@ -2904,7 +2842,7 @@ var Knowledge = class _Knowledge {
|
|
|
2904
2842
|
page,
|
|
2905
2843
|
pageSize: limits.remotePageSize,
|
|
2906
2844
|
chunkType: params.chunkType,
|
|
2907
|
-
includeAssetUrls:
|
|
2845
|
+
includeAssetUrls: true
|
|
2908
2846
|
});
|
|
2909
2847
|
}
|
|
2910
2848
|
}
|
|
@@ -2919,7 +2857,7 @@ var Knowledge = class _Knowledge {
|
|
|
2919
2857
|
const firstPage = await this.client.documents.listChunks(documentId, {
|
|
2920
2858
|
page: 1,
|
|
2921
2859
|
pageSize: limits.remotePageSize,
|
|
2922
|
-
includeAssetUrls:
|
|
2860
|
+
includeAssetUrls: true
|
|
2923
2861
|
});
|
|
2924
2862
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2925
2863
|
const stored = await this.tryReadOutlineFromParsedStorage(documentId, revisionKey);
|
|
@@ -2941,7 +2879,7 @@ var Knowledge = class _Knowledge {
|
|
|
2941
2879
|
response = await this.client.documents.listChunks(documentId, {
|
|
2942
2880
|
page,
|
|
2943
2881
|
pageSize: limits.remotePageSize,
|
|
2944
|
-
includeAssetUrls:
|
|
2882
|
+
includeAssetUrls: true
|
|
2945
2883
|
});
|
|
2946
2884
|
}
|
|
2947
2885
|
const truncated = response.pagination.page < response.pagination.totalPages;
|
|
@@ -2967,28 +2905,13 @@ var Knowledge = class _Knowledge {
|
|
|
2967
2905
|
};
|
|
2968
2906
|
}
|
|
2969
2907
|
async tryReadChunksFromParsedStorage(params) {
|
|
2970
|
-
const
|
|
2971
|
-
if (!parsedStorageConfig) {
|
|
2972
|
-
return null;
|
|
2973
|
-
}
|
|
2974
|
-
const manifest = await this.readFreshParsedStorageManifest(
|
|
2908
|
+
const storedResult = await this.readCommittedParsedStorageResult(
|
|
2975
2909
|
params.documentId,
|
|
2976
2910
|
params.revisionKey
|
|
2977
2911
|
);
|
|
2978
|
-
if (!
|
|
2979
|
-
return null;
|
|
2980
|
-
}
|
|
2912
|
+
if (!storedResult) return null;
|
|
2981
2913
|
const pageParams = getReadPageParams(params.params);
|
|
2982
|
-
const
|
|
2983
|
-
documentId: params.documentId,
|
|
2984
|
-
revisionKey: params.revisionKey,
|
|
2985
|
-
manifest,
|
|
2986
|
-
chunkType: params.params.chunkType
|
|
2987
|
-
});
|
|
2988
|
-
if (!indexedChunks) {
|
|
2989
|
-
return null;
|
|
2990
|
-
}
|
|
2991
|
-
const scopedChunks = indexedChunks.filter((chunk) => matchesReadScope(chunk, params.params));
|
|
2914
|
+
const scopedChunks = storedResult.chunks.filter((chunk) => !params.params.chunkType || chunk.chunkType === params.params.chunkType).filter((chunk) => matchesReadScope(chunk, params.params));
|
|
2992
2915
|
const selected = hasScanReadFilters(params.params) ? selectReadWindow(
|
|
2993
2916
|
scopedChunks,
|
|
2994
2917
|
params.params,
|
|
@@ -2997,17 +2920,18 @@ var Knowledge = class _Knowledge {
|
|
|
2997
2920
|
(pageParams.page - 1) * pageParams.pageSize,
|
|
2998
2921
|
pageParams.page * pageParams.pageSize
|
|
2999
2922
|
);
|
|
3000
|
-
const visibleChunks =
|
|
3001
|
-
|
|
3002
|
-
params.
|
|
3003
|
-
|
|
2923
|
+
const visibleChunks = await applyStoredAssetUrlsToReadChunks({
|
|
2924
|
+
storageConfig: this.requireParsedStorageConfig(),
|
|
2925
|
+
documentId: params.documentId,
|
|
2926
|
+
revisionKey: params.revisionKey,
|
|
2927
|
+
chunks: selected.map(toReadChunk)
|
|
2928
|
+
});
|
|
3004
2929
|
const totalChunks = scopedChunks.length;
|
|
3005
2930
|
return {
|
|
3006
2931
|
document: createStoredKnowledgeDocument({
|
|
3007
2932
|
documentId: params.documentId,
|
|
3008
|
-
|
|
3009
|
-
revisionKey: params.revisionKey
|
|
3010
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
2933
|
+
storedResult,
|
|
2934
|
+
revisionKey: params.revisionKey
|
|
3011
2935
|
}),
|
|
3012
2936
|
chunks: visibleChunks,
|
|
3013
2937
|
page: hasScanReadFilters(params.params) ? void 0 : pageParams.page,
|
|
@@ -3018,30 +2942,15 @@ var Knowledge = class _Knowledge {
|
|
|
3018
2942
|
};
|
|
3019
2943
|
}
|
|
3020
2944
|
async tryGrepChunksFromParsedStorage(params) {
|
|
3021
|
-
const
|
|
3022
|
-
if (!parsedStorageConfig) {
|
|
3023
|
-
return null;
|
|
3024
|
-
}
|
|
3025
|
-
const manifest = await this.readFreshParsedStorageManifest(
|
|
2945
|
+
const storedResult = await this.readCommittedParsedStorageResult(
|
|
3026
2946
|
params.documentId,
|
|
3027
2947
|
params.revisionKey
|
|
3028
2948
|
);
|
|
3029
|
-
if (!
|
|
3030
|
-
return null;
|
|
3031
|
-
}
|
|
3032
|
-
const indexedChunks = await this.readStoredSnapshotChunks({
|
|
3033
|
-
documentId: params.documentId,
|
|
3034
|
-
revisionKey: params.revisionKey,
|
|
3035
|
-
manifest,
|
|
3036
|
-
chunkType: params.params.chunkType
|
|
3037
|
-
});
|
|
3038
|
-
if (!indexedChunks) {
|
|
3039
|
-
return null;
|
|
3040
|
-
}
|
|
2949
|
+
if (!storedResult) return null;
|
|
3041
2950
|
const maxResults = clampLimit(params.params.maxResults, DEFAULT_GREP_LIMIT, MAX_GREP_LIMIT);
|
|
3042
2951
|
const contextChars = params.params.contextChars ?? DEFAULT_CONTEXT_CHARS;
|
|
3043
2952
|
const matcher = createMatcher(params.params);
|
|
3044
|
-
const scopedChunks =
|
|
2953
|
+
const scopedChunks = storedResult.chunks.filter((chunk) => !params.params.chunkType || chunk.chunkType === params.params.chunkType).filter((chunk) => matchesGrepScope(chunk, params.params));
|
|
3045
2954
|
const matches = [];
|
|
3046
2955
|
let scannedChunks = 0;
|
|
3047
2956
|
for (const chunk of scopedChunks) {
|
|
@@ -3062,9 +2971,8 @@ var Knowledge = class _Knowledge {
|
|
|
3062
2971
|
return {
|
|
3063
2972
|
document: createStoredKnowledgeDocument({
|
|
3064
2973
|
documentId: params.documentId,
|
|
3065
|
-
|
|
3066
|
-
revisionKey: params.revisionKey
|
|
3067
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
2974
|
+
storedResult,
|
|
2975
|
+
revisionKey: params.revisionKey
|
|
3068
2976
|
}),
|
|
3069
2977
|
matches,
|
|
3070
2978
|
scannedChunks,
|
|
@@ -3076,9 +2984,8 @@ var Knowledge = class _Knowledge {
|
|
|
3076
2984
|
return {
|
|
3077
2985
|
document: createStoredKnowledgeDocument({
|
|
3078
2986
|
documentId: params.documentId,
|
|
3079
|
-
|
|
3080
|
-
revisionKey: params.revisionKey
|
|
3081
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
2987
|
+
storedResult,
|
|
2988
|
+
revisionKey: params.revisionKey
|
|
3082
2989
|
}),
|
|
3083
2990
|
matches,
|
|
3084
2991
|
scannedChunks,
|
|
@@ -3086,98 +2993,82 @@ var Knowledge = class _Knowledge {
|
|
|
3086
2993
|
};
|
|
3087
2994
|
}
|
|
3088
2995
|
async tryReadOutlineFromParsedStorage(documentId, revisionKey) {
|
|
3089
|
-
const
|
|
3090
|
-
if (!
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
}
|
|
3101
|
-
const sections = buildFlatSectionsFromIndexedChunks(indexedChunks);
|
|
3102
|
-
const typeCounts = countIndexedTypes(indexedChunks);
|
|
2996
|
+
const storedResult = await this.readCommittedParsedStorageResult(documentId, revisionKey);
|
|
2997
|
+
if (!storedResult) return null;
|
|
2998
|
+
const sections = storedResult.docNav?.sections && storedResult.docNav.sections.length > 0 ? flattenSections(
|
|
2999
|
+
storedResult.docNav.sections.map(
|
|
3000
|
+
(section) => toKnowledgeSection(
|
|
3001
|
+
section,
|
|
3002
|
+
storedResult.chunks,
|
|
3003
|
+
storedResult.manifest.sourceFileName
|
|
3004
|
+
)
|
|
3005
|
+
)
|
|
3006
|
+
) : buildFlatSectionsFromIndexedChunks(storedResult.chunks);
|
|
3103
3007
|
return {
|
|
3104
3008
|
document: createStoredKnowledgeDocument({
|
|
3105
3009
|
documentId,
|
|
3106
|
-
|
|
3107
|
-
revisionKey
|
|
3108
|
-
typeCounts
|
|
3010
|
+
storedResult,
|
|
3011
|
+
revisionKey
|
|
3109
3012
|
}),
|
|
3110
|
-
totalChunks:
|
|
3111
|
-
typeCounts,
|
|
3013
|
+
totalChunks: storedResult.chunks.length,
|
|
3014
|
+
typeCounts: storedResult.typeCounts,
|
|
3112
3015
|
sections,
|
|
3113
|
-
sectionTree:
|
|
3016
|
+
sectionTree: storedResult.docNav?.sections && storedResult.docNav.sections.length > 0 ? storedResult.docNav.sections.map(
|
|
3017
|
+
(section) => toKnowledgeSection(
|
|
3018
|
+
section,
|
|
3019
|
+
storedResult.chunks,
|
|
3020
|
+
storedResult.manifest.sourceFileName
|
|
3021
|
+
)
|
|
3022
|
+
) : nestSections(sections),
|
|
3114
3023
|
truncated: false
|
|
3115
3024
|
};
|
|
3116
3025
|
}
|
|
3117
|
-
async
|
|
3026
|
+
async readCommittedParsedStorageResult(documentId, revisionKey) {
|
|
3118
3027
|
const parsedStorageConfig = this.parsedStorageConfig;
|
|
3119
3028
|
if (!parsedStorageConfig) {
|
|
3120
3029
|
return null;
|
|
3121
3030
|
}
|
|
3122
|
-
const
|
|
3031
|
+
const commit = await readParsedDocumentCommit({
|
|
3032
|
+
storage: parsedStorageConfig.storage,
|
|
3123
3033
|
documentId,
|
|
3124
3034
|
revisionKey
|
|
3125
3035
|
});
|
|
3126
|
-
if (!
|
|
3036
|
+
if (!commit) {
|
|
3127
3037
|
return null;
|
|
3128
3038
|
}
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3039
|
+
const [manifestObject, chunksObject, docNavObject] = await Promise.all([
|
|
3040
|
+
parsedStorageConfig.storage.readObject({
|
|
3041
|
+
documentId,
|
|
3042
|
+
revisionKey,
|
|
3043
|
+
path: "manifest.json"
|
|
3044
|
+
}),
|
|
3045
|
+
parsedStorageConfig.storage.readObject({
|
|
3046
|
+
documentId,
|
|
3047
|
+
revisionKey,
|
|
3048
|
+
path: "chunks.json"
|
|
3049
|
+
}),
|
|
3050
|
+
parsedStorageConfig.storage.readObject({
|
|
3051
|
+
documentId,
|
|
3052
|
+
revisionKey,
|
|
3053
|
+
path: "doc_nav.json"
|
|
3054
|
+
})
|
|
3055
|
+
]);
|
|
3056
|
+
if (!manifestObject || !chunksObject) {
|
|
3134
3057
|
return null;
|
|
3135
3058
|
}
|
|
3136
|
-
const
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
}
|
|
3147
|
-
chunks
|
|
3148
|
-
|
|
3149
|
-
);
|
|
3150
|
-
}
|
|
3151
|
-
return chunks.sort((left, right) => left.position - right.position);
|
|
3152
|
-
}
|
|
3153
|
-
async toRemoteReadChunks(params) {
|
|
3154
|
-
const readChunks = params.chunks.map((chunk) => toRemoteReadChunk(chunk));
|
|
3155
|
-
if (params.assetUrlPolicy === "durable") {
|
|
3156
|
-
return this.hardenReadChunkAssetUrls({
|
|
3157
|
-
documentId: params.documentId,
|
|
3158
|
-
revisionKey: params.revisionKey,
|
|
3159
|
-
chunks: readChunks
|
|
3160
|
-
});
|
|
3161
|
-
}
|
|
3162
|
-
return applyAssetUrlPolicyToReadChunks(readChunks, params.assetUrlPolicy);
|
|
3163
|
-
}
|
|
3164
|
-
async hardenReadChunkAssetUrls(params) {
|
|
3165
|
-
const parsedStorageConfig = this.parsedStorageConfig;
|
|
3166
|
-
if (!parsedStorageConfig) {
|
|
3167
|
-
return applyAssetUrlPolicyToReadChunks(params.chunks, "none");
|
|
3168
|
-
}
|
|
3169
|
-
const hardenedChunks = [];
|
|
3170
|
-
for (const chunk of params.chunks) {
|
|
3171
|
-
hardenedChunks.push(
|
|
3172
|
-
await hardenReadChunkAssetUrls({
|
|
3173
|
-
storageConfig: parsedStorageConfig,
|
|
3174
|
-
documentId: params.documentId,
|
|
3175
|
-
revisionKey: params.revisionKey,
|
|
3176
|
-
chunk
|
|
3177
|
-
})
|
|
3178
|
-
);
|
|
3179
|
-
}
|
|
3180
|
-
return hardenedChunks;
|
|
3059
|
+
const manifest = readJsonObject(manifestObject);
|
|
3060
|
+
const chunks = parseStoredResultChunks({
|
|
3061
|
+
payload: readJsonObject(chunksObject),
|
|
3062
|
+
sourceFileName: manifest.sourceFileName
|
|
3063
|
+
});
|
|
3064
|
+
const docNav = docNavObject ? readJsonObject(docNavObject) : void 0;
|
|
3065
|
+
return {
|
|
3066
|
+
commit,
|
|
3067
|
+
manifest,
|
|
3068
|
+
chunks,
|
|
3069
|
+
docNav: docNav?.sections ? { sections: docNav.sections } : void 0,
|
|
3070
|
+
typeCounts: countIndexedTypes(chunks)
|
|
3071
|
+
};
|
|
3181
3072
|
}
|
|
3182
3073
|
scheduleParsedStorageSync(documentId, revisionKey) {
|
|
3183
3074
|
const parsedStorageConfig = this.parsedStorageConfig;
|
|
@@ -3197,7 +3088,6 @@ var Knowledge = class _Knowledge {
|
|
|
3197
3088
|
documentId,
|
|
3198
3089
|
revisionKey,
|
|
3199
3090
|
nextChunkPage: 1,
|
|
3200
|
-
nextAssetIndex: 0,
|
|
3201
3091
|
status: "failed",
|
|
3202
3092
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3203
3093
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -3207,28 +3097,63 @@ var Knowledge = class _Knowledge {
|
|
|
3207
3097
|
void Promise.resolve(scheduler.schedule(task)).catch(() => void 0);
|
|
3208
3098
|
}
|
|
3209
3099
|
async syncRemoteDocumentToParsedStorage(params) {
|
|
3210
|
-
const
|
|
3211
|
-
|
|
3212
|
-
|
|
3213
|
-
revisionKey: params.revisionKey
|
|
3214
|
-
}) : null;
|
|
3215
|
-
let nextPage = existingProgress?.status === "running" ? existingProgress.nextChunkPage : 1;
|
|
3216
|
-
let response = await this.client.documents.listChunks(params.documentId, {
|
|
3217
|
-
page: nextPage,
|
|
3218
|
-
pageSize: limits.remotePageSize,
|
|
3100
|
+
const firstPage = await this.client.documents.listChunks(params.documentId, {
|
|
3101
|
+
page: 1,
|
|
3102
|
+
pageSize: 1,
|
|
3219
3103
|
includeAssetUrls: true
|
|
3220
3104
|
});
|
|
3221
|
-
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(
|
|
3222
|
-
if (params.revisionKey && getRemoteRevisionKey(
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
includeAssetUrls: true
|
|
3105
|
+
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(firstPage);
|
|
3106
|
+
if (params.revisionKey && getRemoteRevisionKey(firstPage) !== params.revisionKey) {
|
|
3107
|
+
return this.syncRemoteDocumentToParsedStorage({
|
|
3108
|
+
documentId: params.documentId,
|
|
3109
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3227
3110
|
});
|
|
3228
|
-
nextPage = 1;
|
|
3229
3111
|
}
|
|
3230
|
-
|
|
3231
|
-
|
|
3112
|
+
if (firstPage.jobId) {
|
|
3113
|
+
try {
|
|
3114
|
+
const loadedResult = await this.client.jobs.load(firstPage.jobId);
|
|
3115
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3116
|
+
result: loadedResult,
|
|
3117
|
+
storage: params.parsedStorageConfig.storage,
|
|
3118
|
+
documentId: params.documentId,
|
|
3119
|
+
revisionKey,
|
|
3120
|
+
source: "resultZip"
|
|
3121
|
+
});
|
|
3122
|
+
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3123
|
+
documentId: params.documentId,
|
|
3124
|
+
revisionKey,
|
|
3125
|
+
status: "completed",
|
|
3126
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3127
|
+
});
|
|
3128
|
+
return {
|
|
3129
|
+
documentId: synced.documentId,
|
|
3130
|
+
revisionKey: synced.revisionKey,
|
|
3131
|
+
completed: true,
|
|
3132
|
+
commit: synced.commit
|
|
3133
|
+
};
|
|
3134
|
+
} catch {
|
|
3135
|
+
}
|
|
3136
|
+
}
|
|
3137
|
+
return this.syncRemoteDocumentChunksToParsedStorage({
|
|
3138
|
+
documentId: params.documentId,
|
|
3139
|
+
revisionKey,
|
|
3140
|
+
firstPage,
|
|
3141
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3142
|
+
});
|
|
3143
|
+
}
|
|
3144
|
+
async syncRemoteDocumentChunksToParsedStorage(params) {
|
|
3145
|
+
const limits = getParsedStorageLimits(params.parsedStorageConfig.limits);
|
|
3146
|
+
const existingProgress = await params.parsedStorageConfig.storage.readSyncProgress({
|
|
3147
|
+
documentId: params.documentId,
|
|
3148
|
+
revisionKey: params.revisionKey
|
|
3149
|
+
});
|
|
3150
|
+
let nextPage = existingProgress?.status === "running" ? existingProgress.nextChunkPage ?? 1 : 1;
|
|
3151
|
+
let response = nextPage === 1 && params.firstPage.pagination.pageSize === limits.remotePageSize ? params.firstPage : await this.client.documents.listChunks(params.documentId, {
|
|
3152
|
+
page: nextPage,
|
|
3153
|
+
pageSize: limits.remotePageSize,
|
|
3154
|
+
includeAssetUrls: true
|
|
3155
|
+
});
|
|
3156
|
+
const totalPages = response.pagination.totalPages;
|
|
3232
3157
|
let syncedPages = 0;
|
|
3233
3158
|
const startedAt = Date.now();
|
|
3234
3159
|
while (nextPage <= totalPages) {
|
|
@@ -3239,65 +3164,88 @@ var Knowledge = class _Knowledge {
|
|
|
3239
3164
|
includeAssetUrls: true
|
|
3240
3165
|
});
|
|
3241
3166
|
}
|
|
3242
|
-
|
|
3167
|
+
await params.parsedStorageConfig.storage.writeObject({
|
|
3243
3168
|
documentId: params.documentId,
|
|
3244
|
-
revisionKey,
|
|
3245
|
-
|
|
3246
|
-
|
|
3247
|
-
|
|
3248
|
-
response,
|
|
3249
|
-
revisionKey,
|
|
3250
|
-
chunks: readChunks
|
|
3251
|
-
});
|
|
3252
|
-
await params.parsedStorageConfig.storage.writeChunkPage({
|
|
3253
|
-
documentId: params.documentId,
|
|
3254
|
-
revisionKey,
|
|
3255
|
-
page
|
|
3169
|
+
revisionKey: params.revisionKey,
|
|
3170
|
+
path: getRemoteReconstructionPagePath(response.pagination.page),
|
|
3171
|
+
body: Buffer.from(JSON.stringify({ chunks: response.chunks }), "utf8"),
|
|
3172
|
+
contentType: "application/json; charset=utf-8"
|
|
3256
3173
|
});
|
|
3257
|
-
chunkPages.push(page);
|
|
3258
3174
|
nextPage += 1;
|
|
3259
3175
|
syncedPages += 1;
|
|
3260
3176
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3261
3177
|
documentId: params.documentId,
|
|
3262
|
-
revisionKey,
|
|
3178
|
+
revisionKey: params.revisionKey,
|
|
3263
3179
|
nextChunkPage: nextPage,
|
|
3264
|
-
nextAssetIndex: 0,
|
|
3265
3180
|
status: "running",
|
|
3266
3181
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3267
3182
|
});
|
|
3268
3183
|
if (syncedPages >= limits.maxPagesPerSync || Date.now() - startedAt >= limits.syncDeadlineMs) {
|
|
3269
3184
|
return {
|
|
3270
3185
|
documentId: params.documentId,
|
|
3271
|
-
revisionKey,
|
|
3186
|
+
revisionKey: params.revisionKey,
|
|
3272
3187
|
completed: false
|
|
3273
3188
|
};
|
|
3274
3189
|
}
|
|
3275
3190
|
}
|
|
3276
|
-
const
|
|
3277
|
-
|
|
3278
|
-
revisionKey,
|
|
3279
|
-
|
|
3191
|
+
const chunks = await this.readRemoteReconstructionChunks({
|
|
3192
|
+
documentId: params.documentId,
|
|
3193
|
+
revisionKey: params.revisionKey,
|
|
3194
|
+
totalPages,
|
|
3195
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3280
3196
|
});
|
|
3281
|
-
|
|
3197
|
+
if (!chunks) {
|
|
3198
|
+
return {
|
|
3199
|
+
documentId: params.documentId,
|
|
3200
|
+
revisionKey: params.revisionKey,
|
|
3201
|
+
completed: false
|
|
3202
|
+
};
|
|
3203
|
+
}
|
|
3204
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3205
|
+
result: createMinimalParseResultFromRemoteChunks({
|
|
3206
|
+
documentId: params.documentId,
|
|
3207
|
+
revisionKey: params.revisionKey,
|
|
3208
|
+
response,
|
|
3209
|
+
chunks
|
|
3210
|
+
}),
|
|
3211
|
+
storage: params.parsedStorageConfig.storage,
|
|
3282
3212
|
documentId: params.documentId,
|
|
3283
|
-
revisionKey,
|
|
3284
|
-
|
|
3213
|
+
revisionKey: params.revisionKey,
|
|
3214
|
+
source: "remoteReconstruction"
|
|
3285
3215
|
});
|
|
3286
3216
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3287
3217
|
documentId: params.documentId,
|
|
3288
|
-
revisionKey,
|
|
3218
|
+
revisionKey: params.revisionKey,
|
|
3289
3219
|
nextChunkPage: totalPages + 1,
|
|
3290
|
-
nextAssetIndex: 0,
|
|
3291
3220
|
status: "completed",
|
|
3292
3221
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3293
3222
|
});
|
|
3294
3223
|
return {
|
|
3295
3224
|
documentId: params.documentId,
|
|
3296
|
-
revisionKey,
|
|
3225
|
+
revisionKey: params.revisionKey,
|
|
3297
3226
|
completed: true,
|
|
3298
|
-
|
|
3227
|
+
commit: synced.commit
|
|
3299
3228
|
};
|
|
3300
3229
|
}
|
|
3230
|
+
async readRemoteReconstructionChunks(params) {
|
|
3231
|
+
const chunks = [];
|
|
3232
|
+
for (let page = 1; page <= params.totalPages; page += 1) {
|
|
3233
|
+
const object = await params.parsedStorageConfig.storage.readObject({
|
|
3234
|
+
documentId: params.documentId,
|
|
3235
|
+
revisionKey: params.revisionKey,
|
|
3236
|
+
path: getRemoteReconstructionPagePath(page)
|
|
3237
|
+
});
|
|
3238
|
+
if (!object) {
|
|
3239
|
+
return null;
|
|
3240
|
+
}
|
|
3241
|
+
const payload = readJsonObject(object);
|
|
3242
|
+
if (!isDocumentChunkArray(payload.chunks)) {
|
|
3243
|
+
return null;
|
|
3244
|
+
}
|
|
3245
|
+
chunks.push(...payload.chunks);
|
|
3246
|
+
}
|
|
3247
|
+
return chunks;
|
|
3248
|
+
}
|
|
3301
3249
|
requireParsedStorageConfig() {
|
|
3302
3250
|
if (!this.parsedStorageConfig) {
|
|
3303
3251
|
throw new ValidationError("parsed document storage is not configured");
|
|
@@ -3311,7 +3259,8 @@ var Knowledge = class _Knowledge {
|
|
|
3311
3259
|
async getPublishedDocumentJobId(documentId) {
|
|
3312
3260
|
const response = await this.client.documents.listChunks(documentId, {
|
|
3313
3261
|
page: 1,
|
|
3314
|
-
pageSize: 1
|
|
3262
|
+
pageSize: 1,
|
|
3263
|
+
includeAssetUrls: true
|
|
3315
3264
|
});
|
|
3316
3265
|
if (!response.jobId) {
|
|
3317
3266
|
throw new Error(
|
|
@@ -3344,14 +3293,12 @@ var defaultParsedStorageScheduler = {
|
|
|
3344
3293
|
};
|
|
3345
3294
|
function getParsedStorageLimits(limits) {
|
|
3346
3295
|
return {
|
|
3347
|
-
chunkPageSize: clampLimit(limits?.chunkPageSize, DEFAULT_REMOTE_SCAN_PAGE_SIZE, MAX_PAGE_SIZE),
|
|
3348
3296
|
remotePageSize: clampLimit(
|
|
3349
3297
|
limits?.remotePageSize,
|
|
3350
3298
|
DEFAULT_REMOTE_SCAN_PAGE_SIZE,
|
|
3351
3299
|
MAX_PAGE_SIZE
|
|
3352
3300
|
),
|
|
3353
3301
|
maxPagesPerSync: clampLimit(limits?.maxPagesPerSync, DEFAULT_MAX_SYNC_PAGES, 1e3),
|
|
3354
|
-
maxAssetsPerSync: clampLimit(limits?.maxAssetsPerSync, DEFAULT_MAX_SYNC_ASSETS, 1e3),
|
|
3355
3302
|
syncDeadlineMs: clampLimit(limits?.syncDeadlineMs, DEFAULT_SYNC_DEADLINE_MS, 6e4),
|
|
3356
3303
|
grepMaxPages: clampLimit(limits?.grepMaxPages, DEFAULT_GREP_MAX_PAGES, 1e3),
|
|
3357
3304
|
grepDeadlineMs: clampLimit(limits?.grepDeadlineMs, DEFAULT_GREP_DEADLINE_MS, 6e4),
|
|
@@ -3360,13 +3307,13 @@ function getParsedStorageLimits(limits) {
|
|
|
3360
3307
|
};
|
|
3361
3308
|
}
|
|
3362
3309
|
function validateReadParams(params) {
|
|
3363
|
-
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0
|
|
3310
|
+
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0;
|
|
3364
3311
|
if (!usesPagedDisplay) {
|
|
3365
3312
|
return;
|
|
3366
3313
|
}
|
|
3367
3314
|
if (params.sectionPath !== void 0 || params.startChunk !== void 0 || params.endChunk !== void 0 || params.chunkId !== void 0) {
|
|
3368
3315
|
throw new ValidationError(
|
|
3369
|
-
"page
|
|
3316
|
+
"page and pageSize cannot be combined with sectionPath, startChunk, endChunk, or chunkId"
|
|
3370
3317
|
);
|
|
3371
3318
|
}
|
|
3372
3319
|
}
|
|
@@ -3379,9 +3326,6 @@ function getReadPageParams(params) {
|
|
|
3379
3326
|
pageSize: clampLimit(params.pageSize ?? params.limit, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
|
|
3380
3327
|
};
|
|
3381
3328
|
}
|
|
3382
|
-
function shouldRequestRemoteAssetUrls(assetUrlPolicy, parsedStorageConfig) {
|
|
3383
|
-
return assetUrlPolicy === "durable" && parsedStorageConfig !== void 0;
|
|
3384
|
-
}
|
|
3385
3329
|
function getRemoteRevisionKey(response) {
|
|
3386
3330
|
const revisionKey = response.jobResultId ?? response.jobId;
|
|
3387
3331
|
if (!revisionKey) {
|
|
@@ -3391,6 +3335,9 @@ function getRemoteRevisionKey(response) {
|
|
|
3391
3335
|
}
|
|
3392
3336
|
return revisionKey;
|
|
3393
3337
|
}
|
|
3338
|
+
function getRemoteReconstructionPagePath(page) {
|
|
3339
|
+
return `${remoteReconstructionPageDirectory}/page-${page}.json`;
|
|
3340
|
+
}
|
|
3394
3341
|
function createRemoteKnowledgeDocument(params) {
|
|
3395
3342
|
return {
|
|
3396
3343
|
localDocumentId: params.documentId,
|
|
@@ -3405,23 +3352,103 @@ function createRemoteKnowledgeDocument(params) {
|
|
|
3405
3352
|
updatedAt: /* @__PURE__ */ new Date(0)
|
|
3406
3353
|
};
|
|
3407
3354
|
}
|
|
3355
|
+
function createMinimalParseResultFromRemoteChunks(params) {
|
|
3356
|
+
const chunks = params.chunks.map(toMinimalChunkFromRemoteChunk);
|
|
3357
|
+
const typeCounts = countRemoteChunkTypes(params.chunks);
|
|
3358
|
+
return {
|
|
3359
|
+
manifest: {
|
|
3360
|
+
version: "2.0",
|
|
3361
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3362
|
+
sourceFileName: params.documentId,
|
|
3363
|
+
statistics: {
|
|
3364
|
+
totalChunks: chunks.length,
|
|
3365
|
+
textChunks: typeCounts.text,
|
|
3366
|
+
imageChunks: typeCounts.image,
|
|
3367
|
+
tableChunks: typeCounts.table,
|
|
3368
|
+
pageChunks: typeCounts.page
|
|
3369
|
+
}
|
|
3370
|
+
},
|
|
3371
|
+
chunks,
|
|
3372
|
+
rawZip: Buffer.from(""),
|
|
3373
|
+
namespace: params.response.namespace,
|
|
3374
|
+
documentId: params.documentId,
|
|
3375
|
+
textChunks: chunks.filter(
|
|
3376
|
+
(chunk) => chunk.type === "text"
|
|
3377
|
+
),
|
|
3378
|
+
imageChunks: chunks.filter(
|
|
3379
|
+
(chunk) => chunk.type === "image"
|
|
3380
|
+
),
|
|
3381
|
+
tableChunks: chunks.filter(
|
|
3382
|
+
(chunk) => chunk.type === "table"
|
|
3383
|
+
),
|
|
3384
|
+
pageChunks: chunks.filter(
|
|
3385
|
+
(chunk) => chunk.type === "page"
|
|
3386
|
+
),
|
|
3387
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3388
|
+
statistics: {
|
|
3389
|
+
totalChunks: chunks.length,
|
|
3390
|
+
textChunks: typeCounts.text,
|
|
3391
|
+
imageChunks: typeCounts.image,
|
|
3392
|
+
tableChunks: typeCounts.table,
|
|
3393
|
+
pageChunks: typeCounts.page
|
|
3394
|
+
},
|
|
3395
|
+
getChunk: (chunkId) => chunks.find((chunk) => chunk.chunkId === chunkId),
|
|
3396
|
+
save: () => Promise.reject(new Error("Minimal remote reconstruction cannot be saved directly."))
|
|
3397
|
+
};
|
|
3398
|
+
}
|
|
3399
|
+
function toMinimalChunkFromRemoteChunk(chunk) {
|
|
3400
|
+
const baseChunk = {
|
|
3401
|
+
chunkId: chunk.chunkId,
|
|
3402
|
+
contentSource: chunk.contentSource ?? void 0,
|
|
3403
|
+
content: chunk.content ?? "",
|
|
3404
|
+
path: chunk.sourceChunkPath ?? chunk.sectionPath ?? "",
|
|
3405
|
+
metadata: cloneMetadata(chunk.metadata)
|
|
3406
|
+
};
|
|
3407
|
+
if (chunk.chunkType === "image") {
|
|
3408
|
+
return {
|
|
3409
|
+
...baseChunk,
|
|
3410
|
+
type: "image",
|
|
3411
|
+
filePath: chunk.filePath ?? "",
|
|
3412
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3413
|
+
data: Buffer.alloc(0),
|
|
3414
|
+
format: inferContentTypeFromPath2(chunk.filePath ?? "").replace("image/", ""),
|
|
3415
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3416
|
+
};
|
|
3417
|
+
}
|
|
3418
|
+
if (chunk.chunkType === "table") {
|
|
3419
|
+
return {
|
|
3420
|
+
...baseChunk,
|
|
3421
|
+
type: "table",
|
|
3422
|
+
filePath: chunk.filePath ?? "",
|
|
3423
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3424
|
+
html: chunk.content ?? "",
|
|
3425
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3426
|
+
};
|
|
3427
|
+
}
|
|
3428
|
+
if (chunk.chunkType === "page") {
|
|
3429
|
+
return {
|
|
3430
|
+
...baseChunk,
|
|
3431
|
+
type: "page"
|
|
3432
|
+
};
|
|
3433
|
+
}
|
|
3434
|
+
return {
|
|
3435
|
+
...baseChunk,
|
|
3436
|
+
type: "text"
|
|
3437
|
+
};
|
|
3438
|
+
}
|
|
3408
3439
|
function createStoredKnowledgeDocument(params) {
|
|
3409
3440
|
return {
|
|
3410
3441
|
localDocumentId: params.documentId,
|
|
3411
|
-
jobId: params.manifest.jobId || params.revisionKey,
|
|
3412
|
-
documentId: params.
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
typeCounts: params.typeCounts,
|
|
3442
|
+
jobId: params.storedResult.manifest.jobId || params.revisionKey,
|
|
3443
|
+
documentId: params.documentId,
|
|
3444
|
+
sourceFileName: params.storedResult.manifest.sourceFileName,
|
|
3445
|
+
chunkCount: params.storedResult.chunks.length,
|
|
3446
|
+
typeCounts: params.storedResult.typeCounts,
|
|
3417
3447
|
resultDirectoryPath: `parsed-storage:${params.documentId}`,
|
|
3418
|
-
createdAt: new Date(params.
|
|
3419
|
-
updatedAt: new Date(params.
|
|
3448
|
+
createdAt: new Date(params.storedResult.commit.committedAt),
|
|
3449
|
+
updatedAt: new Date(params.storedResult.commit.committedAt)
|
|
3420
3450
|
};
|
|
3421
3451
|
}
|
|
3422
|
-
function isFreshManifest(manifest, revisionKey) {
|
|
3423
|
-
return (manifest.revisionKey ?? manifest.jobId) === revisionKey;
|
|
3424
|
-
}
|
|
3425
3452
|
function toRemoteReadChunk(chunk) {
|
|
3426
3453
|
const metadata = cloneMetadata(chunk.metadata);
|
|
3427
3454
|
return {
|
|
@@ -3450,22 +3477,60 @@ function toIndexedRemoteChunk(chunk) {
|
|
|
3450
3477
|
const readChunk = toRemoteReadChunk(chunk);
|
|
3451
3478
|
return toIndexedReadChunk(readChunk);
|
|
3452
3479
|
}
|
|
3453
|
-
function
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
chunkType
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3480
|
+
function parseStoredResultChunks(params) {
|
|
3481
|
+
const rawChunks = extractStoredChunkRecords(params.payload);
|
|
3482
|
+
return rawChunks.map((record, index) => {
|
|
3483
|
+
const metadata = readRecordMetadata(record);
|
|
3484
|
+
const chunkType = readRecordString(record, "type", "chunkType", "chunk_type");
|
|
3485
|
+
const content = readRecordString(record, "content") ?? "";
|
|
3486
|
+
const sourceChunkPath = readRecordString(record, "path", "sourceChunkPath", "source_chunk_path") ?? "";
|
|
3487
|
+
const chunk = {
|
|
3488
|
+
position: index + 1,
|
|
3489
|
+
chunkId: readRecordString(record, "chunkId", "chunk_id") ?? "",
|
|
3490
|
+
chunkType: isKnowledgeChunkType(chunkType) ? chunkType : "text",
|
|
3491
|
+
contentSource: readRecordString(record, "contentSource", "content_source"),
|
|
3492
|
+
content,
|
|
3493
|
+
readableContent: chunkType === "page" && typeof metadata.summary === "string" && metadata.summary.trim().length > 0 ? metadata.summary : content,
|
|
3494
|
+
sectionPath: normalizeSectionPath(sourceChunkPath, params.sourceFileName),
|
|
3495
|
+
sourceChunkPath,
|
|
3496
|
+
filePath: readRecordString(record, "filePath", "file_path") ?? (typeof metadata.filePath === "string" ? metadata.filePath : void 0),
|
|
3497
|
+
assetUrl: readRecordString(record, "assetUrl", "asset_url"),
|
|
3498
|
+
pageNumbers: getChunkPageNumbers(metadata),
|
|
3499
|
+
metadata
|
|
3500
|
+
};
|
|
3501
|
+
return toIndexedReadChunk(chunk);
|
|
3467
3502
|
});
|
|
3468
3503
|
}
|
|
3504
|
+
function extractStoredChunkRecords(payload) {
|
|
3505
|
+
if (Array.isArray(payload)) {
|
|
3506
|
+
return payload.filter(isRecord2);
|
|
3507
|
+
}
|
|
3508
|
+
if (isRecord2(payload) && Array.isArray(payload.chunks)) {
|
|
3509
|
+
return payload.chunks.filter(isRecord2);
|
|
3510
|
+
}
|
|
3511
|
+
return [];
|
|
3512
|
+
}
|
|
3513
|
+
function readRecordString(record, ...keys) {
|
|
3514
|
+
for (const key of keys) {
|
|
3515
|
+
const value = record[key];
|
|
3516
|
+
if (typeof value === "string") return value;
|
|
3517
|
+
}
|
|
3518
|
+
return void 0;
|
|
3519
|
+
}
|
|
3520
|
+
function readRecordNumber(record, ...keys) {
|
|
3521
|
+
for (const key of keys) {
|
|
3522
|
+
const value = record[key];
|
|
3523
|
+
if (typeof value === "number") return value;
|
|
3524
|
+
}
|
|
3525
|
+
return void 0;
|
|
3526
|
+
}
|
|
3527
|
+
function readRecordMetadata(record) {
|
|
3528
|
+
const metadata = record.metadata;
|
|
3529
|
+
return isRecord2(metadata) ? keysToCamel(metadata) : {};
|
|
3530
|
+
}
|
|
3531
|
+
function isKnowledgeChunkType(value) {
|
|
3532
|
+
return value === "text" || value === "image" || value === "table" || value === "page";
|
|
3533
|
+
}
|
|
3469
3534
|
function toIndexedReadChunk(chunk) {
|
|
3470
3535
|
return {
|
|
3471
3536
|
source: createSyntheticChunk(chunk),
|
|
@@ -3519,204 +3584,105 @@ function getNextChunkPosition(chunks, selected) {
|
|
|
3519
3584
|
}
|
|
3520
3585
|
return chunks[chunks.indexOf(lastSelected) + 1]?.position;
|
|
3521
3586
|
}
|
|
3522
|
-
function
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
assetUrl: void 0,
|
|
3532
|
-
metadata: removeAssetUrlsFromMetadata(chunk.metadata)
|
|
3533
|
-
}));
|
|
3587
|
+
async function applyStoredAssetUrlsToReadChunks(params) {
|
|
3588
|
+
return Promise.all(
|
|
3589
|
+
params.chunks.map(
|
|
3590
|
+
(chunk) => applyStoredAssetUrlsToReadChunk({
|
|
3591
|
+
...params,
|
|
3592
|
+
chunk
|
|
3593
|
+
})
|
|
3594
|
+
)
|
|
3595
|
+
);
|
|
3534
3596
|
}
|
|
3535
|
-
async function
|
|
3597
|
+
async function applyStoredAssetUrlsToReadChunk(params) {
|
|
3536
3598
|
const metadata = cloneMetadata(params.chunk.metadata);
|
|
3537
|
-
const
|
|
3538
|
-
const pageAssets = await hardenPageAssetUrls(params, metadata);
|
|
3539
|
-
if (pageAssets) {
|
|
3540
|
-
metadata.pageAssets = pageAssets;
|
|
3541
|
-
}
|
|
3542
|
-
return {
|
|
3543
|
-
...params.chunk,
|
|
3544
|
-
assetUrl,
|
|
3545
|
-
metadata
|
|
3546
|
-
};
|
|
3547
|
-
}
|
|
3548
|
-
async function hardenPrimaryAssetUrl(params, metadata) {
|
|
3549
|
-
if (!params.chunk.assetUrl || !params.chunk.filePath) {
|
|
3550
|
-
return void 0;
|
|
3551
|
-
}
|
|
3552
|
-
return writeDurableAssetUrl({
|
|
3599
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3553
3600
|
storageConfig: params.storageConfig,
|
|
3554
3601
|
documentId: params.documentId,
|
|
3555
3602
|
revisionKey: params.revisionKey,
|
|
3556
|
-
|
|
3557
|
-
sourceUrl: params.chunk.assetUrl,
|
|
3558
|
-
fallbackContentType: inferContentTypeFromPath(params.chunk.filePath),
|
|
3559
|
-
metadata: {
|
|
3560
|
-
chunkId: params.chunk.chunkId,
|
|
3561
|
-
chunkType: params.chunk.chunkType,
|
|
3562
|
-
sourcePath: params.chunk.filePath,
|
|
3563
|
-
...stringifyFlatMetadata(metadata)
|
|
3564
|
-
}
|
|
3603
|
+
path: params.chunk.filePath
|
|
3565
3604
|
});
|
|
3566
|
-
|
|
3567
|
-
|
|
3568
|
-
const pageAssets = toUnknownArray(metadata.pageAssets);
|
|
3569
|
-
if (!pageAssets) {
|
|
3570
|
-
return void 0;
|
|
3571
|
-
}
|
|
3572
|
-
const hardenedAssets = [];
|
|
3573
|
-
for (const pageAsset of pageAssets) {
|
|
3574
|
-
if (!isRecord2(pageAsset)) {
|
|
3575
|
-
hardenedAssets.push(pageAsset);
|
|
3576
|
-
continue;
|
|
3577
|
-
}
|
|
3578
|
-
const artifactRef = pageAsset.artifactRef;
|
|
3579
|
-
const sourceUrl = pageAsset.assetUrl;
|
|
3580
|
-
if (typeof artifactRef !== "string" || typeof sourceUrl !== "string") {
|
|
3581
|
-
hardenedAssets.push(removeAssetUrlField(pageAsset));
|
|
3582
|
-
continue;
|
|
3583
|
-
}
|
|
3584
|
-
const durableUrl = await writeDurableAssetUrl({
|
|
3585
|
-
storageConfig: params.storageConfig,
|
|
3586
|
-
documentId: params.documentId,
|
|
3587
|
-
revisionKey: params.revisionKey,
|
|
3588
|
-
sourcePath: artifactRef,
|
|
3589
|
-
sourceUrl,
|
|
3590
|
-
fallbackContentType: typeof pageAsset.contentType === "string" ? pageAsset.contentType : inferContentTypeFromPath(artifactRef),
|
|
3591
|
-
metadata: {
|
|
3592
|
-
chunkId: params.chunk.chunkId,
|
|
3593
|
-
chunkType: params.chunk.chunkType,
|
|
3594
|
-
sourcePath: artifactRef
|
|
3595
|
-
}
|
|
3596
|
-
});
|
|
3597
|
-
const rest = removeAssetUrlField(pageAsset);
|
|
3598
|
-
hardenedAssets.push(durableUrl ? { ...rest, assetUrl: durableUrl } : rest);
|
|
3599
|
-
}
|
|
3600
|
-
return hardenedAssets;
|
|
3601
|
-
}
|
|
3602
|
-
async function writeDurableAssetUrl(params) {
|
|
3603
|
-
const existingUrl = await params.storageConfig.storage.getAssetUrl({
|
|
3605
|
+
const pageAssets = await applyStoredPageAssetUrls({
|
|
3606
|
+
storageConfig: params.storageConfig,
|
|
3604
3607
|
documentId: params.documentId,
|
|
3605
3608
|
revisionKey: params.revisionKey,
|
|
3606
|
-
|
|
3609
|
+
metadata
|
|
3607
3610
|
});
|
|
3608
|
-
if (
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
try {
|
|
3612
|
-
const fetched = await fetchAsset(params.sourceUrl, params.fallbackContentType);
|
|
3613
|
-
const written = await params.storageConfig.storage.writeAsset({
|
|
3614
|
-
documentId: params.documentId,
|
|
3615
|
-
revisionKey: params.revisionKey,
|
|
3616
|
-
sourcePath: params.sourcePath,
|
|
3617
|
-
body: fetched.body,
|
|
3618
|
-
contentType: fetched.contentType,
|
|
3619
|
-
metadata: params.metadata
|
|
3620
|
-
});
|
|
3621
|
-
return written.url ?? await params.storageConfig.storage.getAssetUrl({
|
|
3622
|
-
documentId: params.documentId,
|
|
3623
|
-
revisionKey: params.revisionKey,
|
|
3624
|
-
sourcePath: params.sourcePath
|
|
3625
|
-
}) ?? void 0;
|
|
3626
|
-
} catch {
|
|
3627
|
-
return void 0;
|
|
3628
|
-
}
|
|
3629
|
-
}
|
|
3630
|
-
async function fetchAsset(sourceUrl, fallbackContentType) {
|
|
3631
|
-
const response = await fetch(sourceUrl);
|
|
3632
|
-
if (!response.ok) {
|
|
3633
|
-
throw new Error(`Unable to fetch parsed asset: ${response.status}`);
|
|
3611
|
+
if (pageAssets) {
|
|
3612
|
+
metadata.pageAssets = pageAssets;
|
|
3613
|
+
delete metadata.page_assets;
|
|
3634
3614
|
}
|
|
3635
3615
|
return {
|
|
3636
|
-
|
|
3637
|
-
|
|
3616
|
+
...params.chunk,
|
|
3617
|
+
assetUrl: storedAssetUrl ?? params.chunk.assetUrl,
|
|
3618
|
+
metadata
|
|
3638
3619
|
};
|
|
3639
3620
|
}
|
|
3640
|
-
function
|
|
3641
|
-
const
|
|
3642
|
-
const pageAssets = toUnknownArray(cloned.pageAssets);
|
|
3621
|
+
async function applyStoredPageAssetUrls(params) {
|
|
3622
|
+
const pageAssets = getStoredPageAssets(params.metadata);
|
|
3643
3623
|
if (!pageAssets) {
|
|
3644
|
-
return
|
|
3624
|
+
return void 0;
|
|
3645
3625
|
}
|
|
3646
|
-
|
|
3647
|
-
|
|
3626
|
+
return Promise.all(
|
|
3627
|
+
pageAssets.map(async (pageAsset) => {
|
|
3628
|
+
if (!isRecord2(pageAsset)) {
|
|
3629
|
+
return pageAsset;
|
|
3630
|
+
}
|
|
3631
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3632
|
+
if (typeof artifactRef !== "string") {
|
|
3633
|
+
return pageAsset;
|
|
3634
|
+
}
|
|
3635
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3636
|
+
storageConfig: params.storageConfig,
|
|
3637
|
+
documentId: params.documentId,
|
|
3638
|
+
revisionKey: params.revisionKey,
|
|
3639
|
+
path: artifactRef
|
|
3640
|
+
});
|
|
3641
|
+
if (storedAssetUrl) {
|
|
3642
|
+
return {
|
|
3643
|
+
...pageAsset,
|
|
3644
|
+
artifactRef,
|
|
3645
|
+
assetUrl: storedAssetUrl
|
|
3646
|
+
};
|
|
3647
|
+
}
|
|
3648
3648
|
return pageAsset;
|
|
3649
|
-
}
|
|
3650
|
-
|
|
3651
|
-
});
|
|
3652
|
-
return cloned;
|
|
3653
|
-
}
|
|
3654
|
-
function removeAssetUrlField(value) {
|
|
3655
|
-
const cloned = { ...value };
|
|
3656
|
-
delete cloned.assetUrl;
|
|
3657
|
-
return cloned;
|
|
3658
|
-
}
|
|
3659
|
-
function toSnapshotChunkPageFromReadChunks(params) {
|
|
3660
|
-
return {
|
|
3661
|
-
version: 1,
|
|
3662
|
-
jobId: params.response.jobId ?? params.revisionKey,
|
|
3663
|
-
revisionKey: params.revisionKey,
|
|
3664
|
-
documentId: params.response.documentId,
|
|
3665
|
-
namespace: params.response.namespace,
|
|
3666
|
-
sourceFileName: params.response.documentId,
|
|
3667
|
-
page: params.response.pagination.page,
|
|
3668
|
-
pageSize: params.response.pagination.pageSize,
|
|
3669
|
-
total: params.response.pagination.total,
|
|
3670
|
-
totalPages: params.response.pagination.totalPages,
|
|
3671
|
-
chunks: params.chunks.map(toSnapshotChunkFromReadChunk)
|
|
3672
|
-
};
|
|
3649
|
+
})
|
|
3650
|
+
);
|
|
3673
3651
|
}
|
|
3674
|
-
function
|
|
3652
|
+
function getStoredPageAssets(metadata) {
|
|
3653
|
+
const pageAssets = toUnknownArray(metadata.pageAssets) ?? toUnknownArray(metadata.page_assets) ?? void 0;
|
|
3654
|
+
return pageAssets?.map(normalizeStoredPageAsset);
|
|
3655
|
+
}
|
|
3656
|
+
function normalizeStoredPageAsset(pageAsset) {
|
|
3657
|
+
if (!isRecord2(pageAsset)) {
|
|
3658
|
+
return pageAsset;
|
|
3659
|
+
}
|
|
3660
|
+
const normalizedPageAsset = { ...pageAsset };
|
|
3661
|
+
delete normalizedPageAsset.page_num;
|
|
3662
|
+
delete normalizedPageAsset.artifact_ref;
|
|
3663
|
+
delete normalizedPageAsset.asset_url;
|
|
3664
|
+
delete normalizedPageAsset.content_type;
|
|
3665
|
+
const pageNum = readRecordNumber(pageAsset, "pageNum", "page_num");
|
|
3666
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3667
|
+
const assetUrl = readRecordString(pageAsset, "assetUrl", "asset_url");
|
|
3668
|
+
const contentType = readRecordString(pageAsset, "contentType", "content_type");
|
|
3675
3669
|
return {
|
|
3676
|
-
|
|
3677
|
-
|
|
3678
|
-
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
sectionPath: chunk.sectionPath,
|
|
3682
|
-
sourceChunkPath: chunk.sourceChunkPath,
|
|
3683
|
-
filePath: chunk.filePath,
|
|
3684
|
-
sortOrder: chunk.position,
|
|
3685
|
-
metadata: cloneMetadata(chunk.metadata),
|
|
3686
|
-
assetUrl: chunk.assetUrl
|
|
3670
|
+
...normalizedPageAsset,
|
|
3671
|
+
...pageNum === void 0 ? {} : { pageNum },
|
|
3672
|
+
...artifactRef === void 0 ? {} : { artifactRef },
|
|
3673
|
+
...assetUrl === void 0 ? {} : { assetUrl },
|
|
3674
|
+
...contentType === void 0 ? {} : { contentType }
|
|
3687
3675
|
};
|
|
3688
3676
|
}
|
|
3689
|
-
function
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3677
|
+
async function getStoredObjectUrl(params) {
|
|
3678
|
+
if (!params.path) {
|
|
3679
|
+
return void 0;
|
|
3680
|
+
}
|
|
3681
|
+
return await params.storageConfig.storage.getObjectUrl?.({
|
|
3682
|
+
documentId: params.documentId,
|
|
3694
3683
|
revisionKey: params.revisionKey,
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
sourceFileName: params.response.documentId,
|
|
3698
|
-
totalChunks: params.response.pagination.total,
|
|
3699
|
-
typeCounts: countSnapshotPagesTypes(params.chunkPages),
|
|
3700
|
-
chunkPageSize: params.response.pagination.pageSize,
|
|
3701
|
-
chunkPages: Array.from({ length: params.response.pagination.totalPages }, (_, index) => ({
|
|
3702
|
-
page: index + 1,
|
|
3703
|
-
pageSize: params.response.pagination.pageSize,
|
|
3704
|
-
chunkCount: index + 1 === params.response.pagination.totalPages ? params.response.pagination.total - params.response.pagination.pageSize * (params.response.pagination.totalPages - 1) : params.response.pagination.pageSize,
|
|
3705
|
-
key: `parsed/chunks/page-${index + 1}.json`
|
|
3706
|
-
})),
|
|
3707
|
-
assetUrlsByFilePath: {},
|
|
3708
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3709
|
-
};
|
|
3710
|
-
}
|
|
3711
|
-
function countSnapshotPagesTypes(pages) {
|
|
3712
|
-
return pages.flatMap((page) => page.chunks).reduce(
|
|
3713
|
-
(counts, chunk) => {
|
|
3714
|
-
const chunkType = chunk.chunkType;
|
|
3715
|
-
counts[chunkType] += 1;
|
|
3716
|
-
return counts;
|
|
3717
|
-
},
|
|
3718
|
-
{ text: 0, image: 0, table: 0, page: 0 }
|
|
3719
|
-
);
|
|
3684
|
+
path: params.path
|
|
3685
|
+
}) ?? void 0;
|
|
3720
3686
|
}
|
|
3721
3687
|
function countRemoteChunkTypes(chunks) {
|
|
3722
3688
|
return chunks.reduce(
|
|
@@ -3794,22 +3760,10 @@ function isOptionalNonNegativeInteger(value) {
|
|
|
3794
3760
|
function cloneMetadata(metadata) {
|
|
3795
3761
|
return { ...metadata };
|
|
3796
3762
|
}
|
|
3797
|
-
function stringifyFlatMetadata(metadata) {
|
|
3798
|
-
const entries = Object.entries(metadata).flatMap(([key, value]) => {
|
|
3799
|
-
if (typeof value === "string") {
|
|
3800
|
-
return [[key, value]];
|
|
3801
|
-
}
|
|
3802
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
3803
|
-
return [[key, String(value)]];
|
|
3804
|
-
}
|
|
3805
|
-
return [];
|
|
3806
|
-
});
|
|
3807
|
-
return Object.fromEntries(entries);
|
|
3808
|
-
}
|
|
3809
3763
|
function toUnknownArray(value) {
|
|
3810
3764
|
return Array.isArray(value) ? value : null;
|
|
3811
3765
|
}
|
|
3812
|
-
function
|
|
3766
|
+
function inferContentTypeFromPath2(filePath) {
|
|
3813
3767
|
const extension = filePath.split(".").at(-1)?.toLowerCase();
|
|
3814
3768
|
if (extension === "png") return "image/png";
|
|
3815
3769
|
if (extension === "jpg" || extension === "jpeg") return "image/jpeg";
|
|
@@ -3819,6 +3773,9 @@ function inferContentTypeFromPath(filePath) {
|
|
|
3819
3773
|
function isRecord2(value) {
|
|
3820
3774
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3821
3775
|
}
|
|
3776
|
+
function isDocumentChunkArray(value) {
|
|
3777
|
+
return Array.isArray(value) && value.every(isRecord2);
|
|
3778
|
+
}
|
|
3822
3779
|
function indexChunks(result) {
|
|
3823
3780
|
return result.chunks.map((chunk, index) => {
|
|
3824
3781
|
const filePath = getChunkFilePath2(chunk);
|
|
@@ -4264,51 +4221,59 @@ var Knowhere = class {
|
|
|
4264
4221
|
import { createHash as createHash3 } from "crypto";
|
|
4265
4222
|
import { promises as fs4 } from "fs";
|
|
4266
4223
|
import path3 from "path";
|
|
4224
|
+
var syncProgressPath = ".knowhere-sdk/sync-progress.json";
|
|
4267
4225
|
var DiskParsedDocumentStorage = class {
|
|
4268
4226
|
rootDirectory;
|
|
4269
4227
|
constructor(rootDirectory) {
|
|
4270
4228
|
this.rootDirectory = rootDirectory;
|
|
4271
4229
|
}
|
|
4272
|
-
async
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
params.page
|
|
4292
|
-
);
|
|
4230
|
+
async readObject(params) {
|
|
4231
|
+
const objectPath = this.getObjectPath(params);
|
|
4232
|
+
try {
|
|
4233
|
+
const body = await fs4.readFile(objectPath);
|
|
4234
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4235
|
+
return {
|
|
4236
|
+
...params,
|
|
4237
|
+
body,
|
|
4238
|
+
contentType: metadata?.contentType,
|
|
4239
|
+
contentLength: body.byteLength,
|
|
4240
|
+
metadata: metadata?.metadata,
|
|
4241
|
+
url: toFileUrl(objectPath)
|
|
4242
|
+
};
|
|
4243
|
+
} catch (error) {
|
|
4244
|
+
if (isMissingFileError3(error)) {
|
|
4245
|
+
return null;
|
|
4246
|
+
}
|
|
4247
|
+
throw error;
|
|
4248
|
+
}
|
|
4293
4249
|
}
|
|
4294
|
-
async
|
|
4295
|
-
const
|
|
4296
|
-
await fs4.mkdir(path3.dirname(
|
|
4297
|
-
await fs4.writeFile(
|
|
4298
|
-
await this.
|
|
4250
|
+
async writeObject(params) {
|
|
4251
|
+
const objectPath = this.getObjectPath(params);
|
|
4252
|
+
await fs4.mkdir(path3.dirname(objectPath), { recursive: true });
|
|
4253
|
+
await fs4.writeFile(objectPath, params.body);
|
|
4254
|
+
await this.writeObjectMetadata(objectPath, {
|
|
4299
4255
|
contentType: params.contentType,
|
|
4300
|
-
metadata: params.metadata
|
|
4256
|
+
metadata: params.metadata
|
|
4301
4257
|
});
|
|
4302
4258
|
return {
|
|
4303
|
-
|
|
4304
|
-
|
|
4259
|
+
documentId: params.documentId,
|
|
4260
|
+
revisionKey: params.revisionKey,
|
|
4261
|
+
path: params.path,
|
|
4262
|
+
url: toFileUrl(objectPath)
|
|
4305
4263
|
};
|
|
4306
4264
|
}
|
|
4307
|
-
async
|
|
4308
|
-
const
|
|
4265
|
+
async headObject(params) {
|
|
4266
|
+
const objectPath = this.getObjectPath(params);
|
|
4309
4267
|
try {
|
|
4310
|
-
await fs4.
|
|
4311
|
-
|
|
4268
|
+
const stat = await fs4.stat(objectPath);
|
|
4269
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4270
|
+
return {
|
|
4271
|
+
...params,
|
|
4272
|
+
contentType: metadata?.contentType,
|
|
4273
|
+
contentLength: stat.size,
|
|
4274
|
+
metadata: metadata?.metadata,
|
|
4275
|
+
url: toFileUrl(objectPath)
|
|
4276
|
+
};
|
|
4312
4277
|
} catch (error) {
|
|
4313
4278
|
if (isMissingFileError3(error)) {
|
|
4314
4279
|
return null;
|
|
@@ -4316,53 +4281,54 @@ var DiskParsedDocumentStorage = class {
|
|
|
4316
4281
|
throw error;
|
|
4317
4282
|
}
|
|
4318
4283
|
}
|
|
4319
|
-
async
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
);
|
|
4323
|
-
}
|
|
4324
|
-
async writeSyncProgress(params) {
|
|
4325
|
-
await this.writeJson(this.getProgressPath(params.documentId, params.revisionKey), params);
|
|
4284
|
+
async getObjectUrl(params) {
|
|
4285
|
+
const head = await this.headObject(params);
|
|
4286
|
+
return head?.url ?? null;
|
|
4326
4287
|
}
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
);
|
|
4288
|
+
async deletePrefix(params) {
|
|
4289
|
+
await fs4.rm(this.getRevisionDirectory(params.documentId, params.revisionKey), {
|
|
4290
|
+
recursive: true,
|
|
4291
|
+
force: true
|
|
4292
|
+
});
|
|
4333
4293
|
}
|
|
4334
|
-
|
|
4335
|
-
return
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
);
|
|
4294
|
+
async readSyncProgress(params) {
|
|
4295
|
+
return this.readOptionalJson({
|
|
4296
|
+
...params,
|
|
4297
|
+
path: syncProgressPath
|
|
4298
|
+
});
|
|
4340
4299
|
}
|
|
4341
|
-
|
|
4342
|
-
|
|
4300
|
+
async writeSyncProgress(params) {
|
|
4301
|
+
await this.writeObject({
|
|
4302
|
+
documentId: params.documentId,
|
|
4303
|
+
revisionKey: params.revisionKey,
|
|
4304
|
+
path: syncProgressPath,
|
|
4305
|
+
body: Buffer.from(JSON.stringify(params, null, 2), "utf8"),
|
|
4306
|
+
contentType: "application/json; charset=utf-8"
|
|
4307
|
+
});
|
|
4343
4308
|
}
|
|
4344
|
-
|
|
4345
|
-
const
|
|
4346
|
-
const
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
normalizedSourcePath
|
|
4350
|
-
);
|
|
4351
|
-
const assetsDirectory = path3.resolve(
|
|
4352
|
-
this.getRevisionDirectory(documentId, revisionKey),
|
|
4353
|
-
"assets"
|
|
4354
|
-
);
|
|
4355
|
-
if (!isPathInsideDirectory2(assetPath, assetsDirectory)) {
|
|
4356
|
-
throw new Error(`Parsed asset path resolves outside storage: ${sourcePath}`);
|
|
4309
|
+
getObjectPath(params) {
|
|
4310
|
+
const revisionDirectory = this.getRevisionDirectory(params.documentId, params.revisionKey);
|
|
4311
|
+
const objectPath = path3.resolve(revisionDirectory, normalizeRelativeStoragePath(params.path));
|
|
4312
|
+
if (!isPathInsideDirectory2(objectPath, revisionDirectory)) {
|
|
4313
|
+
throw new Error(`Parsed document object path resolves outside storage: ${params.path}`);
|
|
4357
4314
|
}
|
|
4358
|
-
return
|
|
4315
|
+
return objectPath;
|
|
4359
4316
|
}
|
|
4360
4317
|
getRevisionDirectory(documentId, revisionKey) {
|
|
4361
4318
|
return path3.join(this.rootDirectory, hashPathPart(documentId), hashPathPart(revisionKey));
|
|
4362
4319
|
}
|
|
4363
|
-
async readOptionalJson(
|
|
4320
|
+
async readOptionalJson(params) {
|
|
4321
|
+
const object = await this.readObject(params);
|
|
4322
|
+
if (!object) {
|
|
4323
|
+
return null;
|
|
4324
|
+
}
|
|
4325
|
+
return JSON.parse(Buffer.from(object.body).toString("utf8"));
|
|
4326
|
+
}
|
|
4327
|
+
async readObjectMetadata(filePath) {
|
|
4364
4328
|
try {
|
|
4365
|
-
return JSON.parse(
|
|
4329
|
+
return JSON.parse(
|
|
4330
|
+
await fs4.readFile(getMetadataPath(filePath), "utf8")
|
|
4331
|
+
);
|
|
4366
4332
|
} catch (error) {
|
|
4367
4333
|
if (isMissingFileError3(error)) {
|
|
4368
4334
|
return null;
|
|
@@ -4370,16 +4336,22 @@ var DiskParsedDocumentStorage = class {
|
|
|
4370
4336
|
throw error;
|
|
4371
4337
|
}
|
|
4372
4338
|
}
|
|
4373
|
-
async
|
|
4374
|
-
await fs4.
|
|
4375
|
-
await fs4.writeFile(filePath, JSON.stringify(value, null, 2), {
|
|
4339
|
+
async writeObjectMetadata(filePath, metadata) {
|
|
4340
|
+
await fs4.writeFile(getMetadataPath(filePath), JSON.stringify(metadata, null, 2), {
|
|
4376
4341
|
encoding: "utf8",
|
|
4377
4342
|
flag: "w"
|
|
4378
4343
|
});
|
|
4379
4344
|
}
|
|
4380
4345
|
};
|
|
4346
|
+
function getMetadataPath(filePath) {
|
|
4347
|
+
return `${filePath}.metadata.json`;
|
|
4348
|
+
}
|
|
4381
4349
|
function hashPathPart(value) {
|
|
4382
|
-
|
|
4350
|
+
const normalized = value.trim();
|
|
4351
|
+
if (normalized.length === 0) {
|
|
4352
|
+
throw new Error("Parsed document storage path part must be a non-empty value.");
|
|
4353
|
+
}
|
|
4354
|
+
return createHash3("sha256").update(normalized).digest("hex").slice(0, 24);
|
|
4383
4355
|
}
|
|
4384
4356
|
function normalizeRelativeStoragePath(value) {
|
|
4385
4357
|
const normalized = value.replaceAll("\\", "/").replace(/^\.\/+/, "");
|