@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.js
CHANGED
|
@@ -1590,10 +1590,6 @@ var import_jszip2 = __toESM(require("jszip"));
|
|
|
1590
1590
|
var pageCitationAssetsMetadataKey = "pageAssets";
|
|
1591
1591
|
var defaultImageContentType = "application/octet-stream";
|
|
1592
1592
|
var tableContentType = "text/html; charset=utf-8";
|
|
1593
|
-
var snapshotManifestKey = "manifest/current.json";
|
|
1594
|
-
var snapshotIndexKey = "index.json";
|
|
1595
|
-
var defaultSnapshotChunkPageSize = 200;
|
|
1596
|
-
var snapshotJsonContentType = "application/json; charset=utf-8";
|
|
1597
1593
|
async function storeParseResultAssets(result, options) {
|
|
1598
1594
|
if (!options) {
|
|
1599
1595
|
return {
|
|
@@ -1611,148 +1607,11 @@ async function storeParseResultAssets(result, options) {
|
|
|
1611
1607
|
}
|
|
1612
1608
|
}
|
|
1613
1609
|
const normalizedResult = Object.keys(assetUrlsByFilePath).length === 0 ? result : rewriteResultAssetUrls(result, assetUrlsByFilePath);
|
|
1614
|
-
const snapshot = await storeParsedSnapshot({
|
|
1615
|
-
result: normalizedResult,
|
|
1616
|
-
assetUrlsByFilePath,
|
|
1617
|
-
keyPrefix: normalizedKeyPrefix,
|
|
1618
|
-
options
|
|
1619
|
-
});
|
|
1620
1610
|
return {
|
|
1621
1611
|
result: normalizedResult,
|
|
1622
|
-
assetUrlsByFilePath
|
|
1623
|
-
snapshot
|
|
1624
|
-
};
|
|
1625
|
-
}
|
|
1626
|
-
async function storeParsedSnapshot(input) {
|
|
1627
|
-
const pageSize = normalizeSnapshotChunkPageSize(input.options.chunkPageSize);
|
|
1628
|
-
const totalChunks = input.result.chunks.length;
|
|
1629
|
-
const totalPages = Math.max(1, Math.ceil(totalChunks / pageSize));
|
|
1630
|
-
const chunkPageReferences = [];
|
|
1631
|
-
const chunkPageUrlsByPage = {};
|
|
1632
|
-
for (let page = 1; page <= totalPages; page += 1) {
|
|
1633
|
-
const pageChunks = input.result.chunks.slice((page - 1) * pageSize, page * pageSize);
|
|
1634
|
-
const pageKey = `${input.keyPrefix}/chunks/page-${page}.json`;
|
|
1635
|
-
const chunkPage = {
|
|
1636
|
-
version: 1,
|
|
1637
|
-
jobId: input.result.jobId,
|
|
1638
|
-
revisionKey: input.options.revisionKey ?? input.result.jobId,
|
|
1639
|
-
documentId: input.result.documentId,
|
|
1640
|
-
namespace: input.result.namespace,
|
|
1641
|
-
sourceFileName: input.result.manifest.sourceFileName,
|
|
1642
|
-
page,
|
|
1643
|
-
pageSize,
|
|
1644
|
-
total: totalChunks,
|
|
1645
|
-
totalPages,
|
|
1646
|
-
chunks: pageChunks.map(
|
|
1647
|
-
(chunk, index) => toSnapshotChunk(chunk, (page - 1) * pageSize + index + 1)
|
|
1648
|
-
)
|
|
1649
|
-
};
|
|
1650
|
-
const pageUrl = await writeJsonObject({
|
|
1651
|
-
key: pageKey,
|
|
1652
|
-
value: chunkPage,
|
|
1653
|
-
adapter: input.options.adapter
|
|
1654
|
-
});
|
|
1655
|
-
if (pageUrl) chunkPageUrlsByPage[page] = pageUrl;
|
|
1656
|
-
chunkPageReferences.push({
|
|
1657
|
-
page,
|
|
1658
|
-
pageSize,
|
|
1659
|
-
chunkCount: pageChunks.length,
|
|
1660
|
-
key: pageKey,
|
|
1661
|
-
url: pageUrl
|
|
1662
|
-
});
|
|
1663
|
-
}
|
|
1664
|
-
const manifest = {
|
|
1665
|
-
version: 1,
|
|
1666
|
-
kind: "knowhere-parsed-result-snapshot",
|
|
1667
|
-
jobId: input.result.jobId,
|
|
1668
|
-
revisionKey: input.options.revisionKey ?? input.result.jobId,
|
|
1669
|
-
documentId: input.result.documentId,
|
|
1670
|
-
namespace: input.result.namespace,
|
|
1671
|
-
sourceFileName: input.result.manifest.sourceFileName,
|
|
1672
|
-
totalChunks,
|
|
1673
|
-
typeCounts: countSnapshotChunkTypes(input.result.chunks),
|
|
1674
|
-
chunkPageSize: pageSize,
|
|
1675
|
-
chunkPages: chunkPageReferences,
|
|
1676
|
-
assetUrlsByFilePath: input.assetUrlsByFilePath,
|
|
1677
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1678
|
-
};
|
|
1679
|
-
const manifestKey = `${input.keyPrefix}/${snapshotManifestKey}`;
|
|
1680
|
-
const indexKey = `${input.keyPrefix}/${snapshotIndexKey}`;
|
|
1681
|
-
const manifestUrl = await writeJsonObject({
|
|
1682
|
-
key: manifestKey,
|
|
1683
|
-
value: manifest,
|
|
1684
|
-
adapter: input.options.adapter
|
|
1685
|
-
});
|
|
1686
|
-
const indexUrl = await writeJsonObject({
|
|
1687
|
-
key: indexKey,
|
|
1688
|
-
value: manifest,
|
|
1689
|
-
adapter: input.options.adapter
|
|
1690
|
-
});
|
|
1691
|
-
return {
|
|
1692
|
-
manifest,
|
|
1693
|
-
manifestKey,
|
|
1694
|
-
manifestUrl,
|
|
1695
|
-
indexKey,
|
|
1696
|
-
indexUrl,
|
|
1697
|
-
chunkPageUrlsByPage
|
|
1698
|
-
};
|
|
1699
|
-
}
|
|
1700
|
-
function countSnapshotChunkTypes(chunks) {
|
|
1701
|
-
return chunks.reduce(
|
|
1702
|
-
(counts, chunk) => {
|
|
1703
|
-
counts[chunk.type] += 1;
|
|
1704
|
-
return counts;
|
|
1705
|
-
},
|
|
1706
|
-
{ text: 0, image: 0, table: 0, page: 0 }
|
|
1707
|
-
);
|
|
1708
|
-
}
|
|
1709
|
-
async function writeJsonObject(input) {
|
|
1710
|
-
const result = await input.adapter.writeObject({
|
|
1711
|
-
key: input.key,
|
|
1712
|
-
body: Buffer.from(JSON.stringify(input.value, null, 2), "utf8"),
|
|
1713
|
-
contentType: snapshotJsonContentType,
|
|
1714
|
-
metadata: {
|
|
1715
|
-
kind: "knowhere-parsed-result-snapshot"
|
|
1716
|
-
}
|
|
1717
|
-
});
|
|
1718
|
-
return result.url ?? await input.adapter.getObjectUrl?.(result.key) ?? void 0;
|
|
1719
|
-
}
|
|
1720
|
-
function normalizeSnapshotChunkPageSize(value) {
|
|
1721
|
-
if (!Number.isInteger(value) || value === void 0) return defaultSnapshotChunkPageSize;
|
|
1722
|
-
return Math.min(Math.max(value, 1), 1e3);
|
|
1723
|
-
}
|
|
1724
|
-
function toSnapshotChunk(chunk, position) {
|
|
1725
|
-
const filePath = getSnapshotChunkFilePath(chunk);
|
|
1726
|
-
return {
|
|
1727
|
-
id: chunk.chunkId,
|
|
1728
|
-
chunkId: chunk.chunkId,
|
|
1729
|
-
chunkType: chunk.type,
|
|
1730
|
-
contentSource: chunk.contentSource,
|
|
1731
|
-
content: chunk.content,
|
|
1732
|
-
sectionPath: normalizeSnapshotSectionPath(chunk.path),
|
|
1733
|
-
sourceChunkPath: chunk.path,
|
|
1734
|
-
filePath,
|
|
1735
|
-
sortOrder: position,
|
|
1736
|
-
metadata: cloneChunkMetadata(chunk.metadata),
|
|
1737
|
-
assetUrl: getSnapshotChunkAssetUrl(chunk)
|
|
1612
|
+
assetUrlsByFilePath
|
|
1738
1613
|
};
|
|
1739
1614
|
}
|
|
1740
|
-
function normalizeSnapshotSectionPath(path4) {
|
|
1741
|
-
return path4.length > 0 ? path4 : void 0;
|
|
1742
|
-
}
|
|
1743
|
-
function getSnapshotChunkFilePath(chunk) {
|
|
1744
|
-
if (chunk.type === "image" || chunk.type === "table") {
|
|
1745
|
-
return chunk.filePath;
|
|
1746
|
-
}
|
|
1747
|
-
const filePath = chunk.metadata.filePath;
|
|
1748
|
-
return typeof filePath === "string" ? filePath : void 0;
|
|
1749
|
-
}
|
|
1750
|
-
function getSnapshotChunkAssetUrl(chunk) {
|
|
1751
|
-
return chunk.type === "image" || chunk.type === "table" ? chunk.assetUrl : void 0;
|
|
1752
|
-
}
|
|
1753
|
-
function cloneChunkMetadata(metadata) {
|
|
1754
|
-
return { ...metadata };
|
|
1755
|
-
}
|
|
1756
1615
|
async function collectStorageAssets(result, keyPrefix) {
|
|
1757
1616
|
const resultZip = await loadResultZipForPageCitationAssets(result);
|
|
1758
1617
|
return [
|
|
@@ -1989,108 +1848,212 @@ function isRecord(value) {
|
|
|
1989
1848
|
}
|
|
1990
1849
|
|
|
1991
1850
|
// src/storage/parsed-document-storage.ts
|
|
1992
|
-
var
|
|
1993
|
-
var
|
|
1994
|
-
var
|
|
1995
|
-
var
|
|
1851
|
+
var import_jszip3 = __toESM(require("jszip"));
|
|
1852
|
+
var parsedDocumentCommitPath = ".knowhere-sdk/commit.json";
|
|
1853
|
+
var jsonContentType = "application/json; charset=utf-8";
|
|
1854
|
+
var markdownContentType = "text/markdown; charset=utf-8";
|
|
1855
|
+
var csvContentType = "text/csv; charset=utf-8";
|
|
1856
|
+
var htmlContentType = "text/html; charset=utf-8";
|
|
1857
|
+
var binaryContentType = "application/octet-stream";
|
|
1996
1858
|
async function syncParseResultToParsedDocumentStorage(params) {
|
|
1997
1859
|
const documentId = params.documentId ?? params.result.documentId ?? params.result.jobId;
|
|
1998
1860
|
const revisionKey = params.revisionKey ?? params.result.jobId;
|
|
1999
|
-
const
|
|
2000
|
-
|
|
1861
|
+
const objects = await collectResultLayoutObjects(params.result);
|
|
1862
|
+
for (const object of objects) {
|
|
1863
|
+
await params.storage.writeObject({
|
|
1864
|
+
documentId,
|
|
1865
|
+
revisionKey,
|
|
1866
|
+
...object
|
|
1867
|
+
});
|
|
1868
|
+
}
|
|
1869
|
+
const commit = {
|
|
1870
|
+
version: 1,
|
|
2001
1871
|
documentId,
|
|
2002
|
-
revisionKey
|
|
2003
|
-
|
|
2004
|
-
|
|
2005
|
-
|
|
2006
|
-
|
|
2007
|
-
|
|
2008
|
-
revisionKey
|
|
1872
|
+
revisionKey,
|
|
1873
|
+
source: params.source ?? "resultZip",
|
|
1874
|
+
committedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1875
|
+
};
|
|
1876
|
+
await writeParsedDocumentJsonObject(params.storage, {
|
|
1877
|
+
documentId,
|
|
1878
|
+
revisionKey,
|
|
1879
|
+
path: parsedDocumentCommitPath,
|
|
1880
|
+
value: commit
|
|
2009
1881
|
});
|
|
2010
1882
|
return {
|
|
2011
|
-
result:
|
|
2012
|
-
snapshot: stored.snapshot,
|
|
1883
|
+
result: params.result,
|
|
2013
1884
|
documentId,
|
|
2014
|
-
revisionKey
|
|
1885
|
+
revisionKey,
|
|
1886
|
+
commit
|
|
2015
1887
|
};
|
|
2016
1888
|
}
|
|
2017
|
-
function
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
};
|
|
1889
|
+
async function readParsedDocumentCommit(params) {
|
|
1890
|
+
const object = await params.storage.readObject({
|
|
1891
|
+
documentId: params.documentId,
|
|
1892
|
+
revisionKey: params.revisionKey,
|
|
1893
|
+
path: parsedDocumentCommitPath
|
|
1894
|
+
});
|
|
1895
|
+
if (!object) {
|
|
1896
|
+
return null;
|
|
1897
|
+
}
|
|
1898
|
+
const commit = readJsonObject(object);
|
|
1899
|
+
return commit.revisionKey === params.revisionKey && commit.documentId === params.documentId ? commit : null;
|
|
2023
1900
|
}
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
1901
|
+
function readJsonObject(object) {
|
|
1902
|
+
return JSON.parse(Buffer.from(object.body).toString("utf8"));
|
|
1903
|
+
}
|
|
1904
|
+
async function collectResultLayoutObjects(result) {
|
|
1905
|
+
const objectsByPath = /* @__PURE__ */ new Map();
|
|
1906
|
+
const rawZipObjects = await collectRawZipObjects(result.rawZip);
|
|
1907
|
+
for (const object of rawZipObjects) {
|
|
1908
|
+
objectsByPath.set(object.path, object);
|
|
1909
|
+
}
|
|
1910
|
+
for (const object of collectGeneratedResultObjects(result)) {
|
|
1911
|
+
if (!objectsByPath.has(object.path)) {
|
|
1912
|
+
objectsByPath.set(object.path, object);
|
|
1913
|
+
}
|
|
1914
|
+
}
|
|
1915
|
+
return [...objectsByPath.values()].filter((object) => !isSdkMetadataPath(object.path));
|
|
1916
|
+
}
|
|
1917
|
+
async function collectRawZipObjects(rawZip) {
|
|
1918
|
+
try {
|
|
1919
|
+
const zip = await import_jszip3.default.loadAsync(rawZip);
|
|
1920
|
+
const objects = [];
|
|
1921
|
+
for (const entry of Object.values(zip.files)) {
|
|
1922
|
+
if (entry.dir || entry.name === "result.zip") {
|
|
1923
|
+
continue;
|
|
1924
|
+
}
|
|
1925
|
+
objects.push({
|
|
1926
|
+
path: normalizeResultPath(entry.name),
|
|
1927
|
+
body: new Uint8Array(await entry.async("nodebuffer")),
|
|
1928
|
+
contentType: inferContentTypeFromPath(entry.name)
|
|
1929
|
+
});
|
|
1930
|
+
}
|
|
1931
|
+
return objects;
|
|
1932
|
+
} catch {
|
|
1933
|
+
return [];
|
|
2036
1934
|
}
|
|
2037
|
-
|
|
2038
|
-
|
|
1935
|
+
}
|
|
1936
|
+
function collectGeneratedResultObjects(result) {
|
|
1937
|
+
const objects = [
|
|
1938
|
+
createJsonObject("manifest.json", result.manifest),
|
|
1939
|
+
createJsonObject("chunks.json", keysToSnake(serializeChunks2(result.chunks)))
|
|
1940
|
+
];
|
|
1941
|
+
if (result.docNav) {
|
|
1942
|
+
objects.push(createJsonObject("doc_nav.json", result.docNav));
|
|
1943
|
+
}
|
|
1944
|
+
if (result.fullMarkdown) {
|
|
1945
|
+
objects.push(createTextObject("full.md", result.fullMarkdown, markdownContentType));
|
|
1946
|
+
}
|
|
1947
|
+
if (result.chunksSlim) {
|
|
1948
|
+
objects.push(createJsonObject("chunks_slim.json", { chunks: result.chunksSlim }));
|
|
1949
|
+
}
|
|
1950
|
+
if (result.hierarchy) {
|
|
1951
|
+
objects.push(createJsonObject("hierarchy.json", result.hierarchy));
|
|
1952
|
+
}
|
|
1953
|
+
if (result.tocHierarchies) {
|
|
1954
|
+
objects.push(createJsonObject("toc_hierarchies.json", result.tocHierarchies));
|
|
1955
|
+
}
|
|
1956
|
+
if (result.kbCsv) {
|
|
1957
|
+
objects.push(createTextObject("kb.csv", result.kbCsv, csvContentType));
|
|
2039
1958
|
}
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
Buffer.from(input.body).toString("utf8")
|
|
1959
|
+
if (result.hierarchyViewHtml) {
|
|
1960
|
+
objects.push(
|
|
1961
|
+
createTextObject("hierarchy_view.html", result.hierarchyViewHtml, htmlContentType)
|
|
2044
1962
|
);
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
1963
|
+
}
|
|
1964
|
+
for (const chunk of result.imageChunks) {
|
|
1965
|
+
objects.push({
|
|
1966
|
+
path: normalizeResultPath(chunk.filePath),
|
|
1967
|
+
body: new Uint8Array(chunk.data),
|
|
1968
|
+
contentType: inferContentTypeFromPath(chunk.filePath),
|
|
1969
|
+
metadata: {
|
|
1970
|
+
chunkId: chunk.chunkId,
|
|
1971
|
+
chunkType: chunk.type,
|
|
1972
|
+
sourcePath: chunk.filePath
|
|
1973
|
+
}
|
|
2049
1974
|
});
|
|
2050
|
-
return { key: input.key };
|
|
2051
1975
|
}
|
|
2052
|
-
const
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
1976
|
+
for (const chunk of result.tableChunks) {
|
|
1977
|
+
objects.push({
|
|
1978
|
+
path: normalizeResultPath(chunk.filePath),
|
|
1979
|
+
body: Buffer.from(chunk.html, "utf8"),
|
|
1980
|
+
contentType: htmlContentType,
|
|
1981
|
+
metadata: {
|
|
1982
|
+
chunkId: chunk.chunkId,
|
|
1983
|
+
chunkType: chunk.type,
|
|
1984
|
+
sourcePath: chunk.filePath
|
|
1985
|
+
}
|
|
1986
|
+
});
|
|
1987
|
+
}
|
|
1988
|
+
return objects;
|
|
1989
|
+
}
|
|
1990
|
+
function serializeChunks2(chunks) {
|
|
2060
1991
|
return {
|
|
2061
|
-
|
|
2062
|
-
|
|
1992
|
+
chunks: chunks.map((chunk) => {
|
|
1993
|
+
const rawChunk = {
|
|
1994
|
+
chunkId: chunk.chunkId,
|
|
1995
|
+
type: chunk.type,
|
|
1996
|
+
contentSource: chunk.contentSource,
|
|
1997
|
+
content: chunk.content,
|
|
1998
|
+
path: chunk.path,
|
|
1999
|
+
metadata: chunk.metadata
|
|
2000
|
+
};
|
|
2001
|
+
if (chunk.type === "image" || chunk.type === "table") {
|
|
2002
|
+
return {
|
|
2003
|
+
...rawChunk,
|
|
2004
|
+
filePath: chunk.filePath,
|
|
2005
|
+
assetUrl: chunk.assetUrl
|
|
2006
|
+
};
|
|
2007
|
+
}
|
|
2008
|
+
return rawChunk;
|
|
2009
|
+
})
|
|
2063
2010
|
};
|
|
2064
2011
|
}
|
|
2065
|
-
async function
|
|
2066
|
-
|
|
2067
|
-
if (storagePath === manifestStoragePath || storagePath === indexStoragePath || chunkPagePathPattern.test(storagePath)) {
|
|
2068
|
-
return null;
|
|
2069
|
-
}
|
|
2070
|
-
const url = await params.storage.getAssetUrl({
|
|
2012
|
+
async function writeParsedDocumentJsonObject(storage, params) {
|
|
2013
|
+
await storage.writeObject({
|
|
2071
2014
|
documentId: params.documentId,
|
|
2072
2015
|
revisionKey: params.revisionKey,
|
|
2073
|
-
|
|
2016
|
+
path: params.path,
|
|
2017
|
+
body: Buffer.from(JSON.stringify(params.value, null, 2), "utf8"),
|
|
2018
|
+
contentType: jsonContentType
|
|
2074
2019
|
});
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2020
|
+
}
|
|
2021
|
+
function createJsonObject(path4, value) {
|
|
2022
|
+
return {
|
|
2023
|
+
path: path4,
|
|
2024
|
+
body: Buffer.from(JSON.stringify(value, null, 2), "utf8"),
|
|
2025
|
+
contentType: jsonContentType
|
|
2026
|
+
};
|
|
2027
|
+
}
|
|
2028
|
+
function createTextObject(path4, value, contentType) {
|
|
2029
|
+
return {
|
|
2030
|
+
path: path4,
|
|
2031
|
+
body: Buffer.from(value, "utf8"),
|
|
2032
|
+
contentType
|
|
2033
|
+
};
|
|
2034
|
+
}
|
|
2035
|
+
function inferContentTypeFromPath(filePath) {
|
|
2036
|
+
const lower = filePath.toLowerCase();
|
|
2037
|
+
if (lower.endsWith(".json")) return jsonContentType;
|
|
2038
|
+
if (lower.endsWith(".md")) return markdownContentType;
|
|
2039
|
+
if (lower.endsWith(".csv")) return csvContentType;
|
|
2040
|
+
if (lower.endsWith(".html") || lower.endsWith(".htm")) return htmlContentType;
|
|
2041
|
+
if (lower.endsWith(".png")) return "image/png";
|
|
2042
|
+
if (lower.endsWith(".jpg") || lower.endsWith(".jpeg")) return "image/jpeg";
|
|
2043
|
+
if (lower.endsWith(".gif")) return "image/gif";
|
|
2044
|
+
if (lower.endsWith(".webp")) return "image/webp";
|
|
2045
|
+
if (lower.endsWith(".svg")) return "image/svg+xml";
|
|
2046
|
+
return binaryContentType;
|
|
2047
|
+
}
|
|
2048
|
+
function normalizeResultPath(value) {
|
|
2049
|
+
const normalized = value.replaceAll("\\", "/").replace(/^\.\/+/, "");
|
|
2050
|
+
if (normalized.length === 0 || normalized.includes("\0") || normalized.startsWith("/") || normalized.split("/").some((part) => part.length === 0 || part === "." || part === "..")) {
|
|
2051
|
+
throw new Error(`Invalid parsed result path: ${value}`);
|
|
2084
2052
|
}
|
|
2085
|
-
return
|
|
2086
|
-
documentId: params.documentId,
|
|
2087
|
-
revisionKey: params.revisionKey,
|
|
2088
|
-
sourcePath: storagePath
|
|
2089
|
-
});
|
|
2053
|
+
return normalized;
|
|
2090
2054
|
}
|
|
2091
|
-
function
|
|
2092
|
-
|
|
2093
|
-
return key.startsWith(prefix) ? key.slice(prefix.length) : key;
|
|
2055
|
+
function isSdkMetadataPath(path4) {
|
|
2056
|
+
return path4 === ".knowhere-sdk" || path4.startsWith(".knowhere-sdk/");
|
|
2094
2057
|
}
|
|
2095
2058
|
|
|
2096
2059
|
// src/knowledge/local-store.ts
|
|
@@ -2325,7 +2288,6 @@ var MAX_GREP_LIMIT = 50;
|
|
|
2325
2288
|
var DEFAULT_CONTEXT_CHARS = 80;
|
|
2326
2289
|
var DEFAULT_REMOTE_SCAN_PAGE_SIZE = 100;
|
|
2327
2290
|
var DEFAULT_MAX_SYNC_PAGES = 10;
|
|
2328
|
-
var DEFAULT_MAX_SYNC_ASSETS = 20;
|
|
2329
2291
|
var DEFAULT_SYNC_DEADLINE_MS = 8e3;
|
|
2330
2292
|
var DEFAULT_GREP_MAX_PAGES = 50;
|
|
2331
2293
|
var DEFAULT_GREP_DEADLINE_MS = 8e3;
|
|
@@ -2333,6 +2295,7 @@ var DEFAULT_OUTLINE_MAX_PAGES = 50;
|
|
|
2333
2295
|
var DEFAULT_OUTLINE_DEADLINE_MS = 8e3;
|
|
2334
2296
|
var SAFE_LOCAL_DOCUMENT_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
2335
2297
|
var REMOTE_DOCUMENT_ID_PATTERN = /^doc[_-]/;
|
|
2298
|
+
var remoteReconstructionPageDirectory = ".knowhere-sdk/remote-reconstruction/pages";
|
|
2336
2299
|
var Knowledge = class _Knowledge {
|
|
2337
2300
|
client;
|
|
2338
2301
|
store;
|
|
@@ -2367,8 +2330,7 @@ var Knowledge = class _Knowledge {
|
|
|
2367
2330
|
return {
|
|
2368
2331
|
document,
|
|
2369
2332
|
result,
|
|
2370
|
-
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2371
|
-
parsedSnapshot: storedAssets.snapshot
|
|
2333
|
+
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2372
2334
|
};
|
|
2373
2335
|
}
|
|
2374
2336
|
/** @deprecated Use parseToLocalCache for local cache imports or the top-level client.parse for server-safe parsing. */
|
|
@@ -2413,8 +2375,7 @@ var Knowledge = class _Knowledge {
|
|
|
2413
2375
|
const result = syncedStorage.result;
|
|
2414
2376
|
return {
|
|
2415
2377
|
result,
|
|
2416
|
-
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2417
|
-
parsedSnapshot: syncedStorage.snapshot ?? storedAssets.snapshot
|
|
2378
|
+
assetUrlsByFilePath: storedAssets.assetUrlsByFilePath
|
|
2418
2379
|
};
|
|
2419
2380
|
}
|
|
2420
2381
|
async importJobResult(params) {
|
|
@@ -2426,8 +2387,7 @@ var Knowledge = class _Knowledge {
|
|
|
2426
2387
|
return {
|
|
2427
2388
|
document,
|
|
2428
2389
|
result,
|
|
2429
|
-
assetUrlsByFilePath: stored.assetUrlsByFilePath
|
|
2430
|
-
parsedSnapshot: stored.parsedSnapshot
|
|
2390
|
+
assetUrlsByFilePath: stored.assetUrlsByFilePath
|
|
2431
2391
|
};
|
|
2432
2392
|
}
|
|
2433
2393
|
/** @deprecated Use importJobResult for local cache imports or loadJobResult for server-safe loads. */
|
|
@@ -2450,14 +2410,13 @@ var Knowledge = class _Knowledge {
|
|
|
2450
2410
|
result: loadedResult,
|
|
2451
2411
|
storage: parsedStorageConfig.storage,
|
|
2452
2412
|
documentId: loadedResult.documentId ?? normalized.localDocumentId ?? normalized.jobId,
|
|
2453
|
-
revisionKey: params.revisionKey ?? normalized.jobId
|
|
2454
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2413
|
+
revisionKey: params.revisionKey ?? normalized.jobId
|
|
2455
2414
|
});
|
|
2456
2415
|
return {
|
|
2457
2416
|
documentId: synced2.documentId,
|
|
2458
2417
|
revisionKey: synced2.revisionKey,
|
|
2459
2418
|
completed: true,
|
|
2460
|
-
|
|
2419
|
+
commit: synced2.commit
|
|
2461
2420
|
};
|
|
2462
2421
|
}
|
|
2463
2422
|
if (!normalized.localDocumentId) {
|
|
@@ -2468,14 +2427,13 @@ var Knowledge = class _Knowledge {
|
|
|
2468
2427
|
result,
|
|
2469
2428
|
storage: parsedStorageConfig.storage,
|
|
2470
2429
|
documentId: result.documentId ?? normalized.localDocumentId,
|
|
2471
|
-
revisionKey: params.revisionKey ?? result.jobId
|
|
2472
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2430
|
+
revisionKey: params.revisionKey ?? result.jobId
|
|
2473
2431
|
});
|
|
2474
2432
|
return {
|
|
2475
2433
|
documentId: synced.documentId,
|
|
2476
2434
|
revisionKey: synced.revisionKey,
|
|
2477
2435
|
completed: true,
|
|
2478
|
-
|
|
2436
|
+
commit: synced.commit
|
|
2479
2437
|
};
|
|
2480
2438
|
}
|
|
2481
2439
|
async syncParseResultToConfiguredStorage(result) {
|
|
@@ -2485,12 +2443,11 @@ var Knowledge = class _Knowledge {
|
|
|
2485
2443
|
}
|
|
2486
2444
|
const synced = await syncParseResultToParsedDocumentStorage({
|
|
2487
2445
|
result,
|
|
2488
|
-
storage: parsedStorageConfig.storage
|
|
2489
|
-
chunkPageSize: parsedStorageConfig.limits?.chunkPageSize
|
|
2446
|
+
storage: parsedStorageConfig.storage
|
|
2490
2447
|
});
|
|
2491
2448
|
return {
|
|
2492
2449
|
result: synced.result,
|
|
2493
|
-
|
|
2450
|
+
commit: synced.commit
|
|
2494
2451
|
};
|
|
2495
2452
|
}
|
|
2496
2453
|
async parseWithoutClientStorageAdapter(params) {
|
|
@@ -2741,10 +2698,7 @@ var Knowledge = class _Knowledge {
|
|
|
2741
2698
|
page: pageParams.page,
|
|
2742
2699
|
pageSize: pageParams.pageSize,
|
|
2743
2700
|
chunkType: params.chunkType,
|
|
2744
|
-
includeAssetUrls:
|
|
2745
|
-
params.assetUrlPolicy,
|
|
2746
|
-
this.parsedStorageConfig
|
|
2747
|
-
)
|
|
2701
|
+
includeAssetUrls: true
|
|
2748
2702
|
});
|
|
2749
2703
|
const revisionKey = getRemoteRevisionKey(remotePage);
|
|
2750
2704
|
const stored = await this.tryReadChunksFromParsedStorage({
|
|
@@ -2755,12 +2709,7 @@ var Knowledge = class _Knowledge {
|
|
|
2755
2709
|
if (stored) {
|
|
2756
2710
|
return stored;
|
|
2757
2711
|
}
|
|
2758
|
-
const chunks =
|
|
2759
|
-
documentId,
|
|
2760
|
-
revisionKey,
|
|
2761
|
-
chunks: remotePage.chunks,
|
|
2762
|
-
assetUrlPolicy: params.assetUrlPolicy
|
|
2763
|
-
});
|
|
2712
|
+
const chunks = remotePage.chunks.map((chunk) => toRemoteReadChunk(chunk));
|
|
2764
2713
|
this.scheduleParsedStorageSync(documentId, revisionKey);
|
|
2765
2714
|
return {
|
|
2766
2715
|
document: createRemoteKnowledgeDocument({
|
|
@@ -2793,10 +2742,7 @@ var Knowledge = class _Knowledge {
|
|
|
2793
2742
|
page: 1,
|
|
2794
2743
|
pageSize: limits.remotePageSize,
|
|
2795
2744
|
chunkType: params.chunkType,
|
|
2796
|
-
includeAssetUrls:
|
|
2797
|
-
params.assetUrlPolicy,
|
|
2798
|
-
this.parsedStorageConfig
|
|
2799
|
-
)
|
|
2745
|
+
includeAssetUrls: true
|
|
2800
2746
|
});
|
|
2801
2747
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2802
2748
|
const stored = await this.tryReadChunksFromParsedStorage({
|
|
@@ -2823,18 +2769,10 @@ var Knowledge = class _Knowledge {
|
|
|
2823
2769
|
page,
|
|
2824
2770
|
pageSize: limits.remotePageSize,
|
|
2825
2771
|
chunkType: params.chunkType,
|
|
2826
|
-
includeAssetUrls:
|
|
2827
|
-
params.assetUrlPolicy,
|
|
2828
|
-
this.parsedStorageConfig
|
|
2829
|
-
)
|
|
2772
|
+
includeAssetUrls: true
|
|
2830
2773
|
});
|
|
2831
2774
|
}
|
|
2832
|
-
const chunks =
|
|
2833
|
-
documentId,
|
|
2834
|
-
revisionKey,
|
|
2835
|
-
chunks: selected.slice(0, limit),
|
|
2836
|
-
assetUrlPolicy: params.assetUrlPolicy
|
|
2837
|
-
});
|
|
2775
|
+
const chunks = selected.slice(0, limit).map((chunk) => toRemoteReadChunk(chunk));
|
|
2838
2776
|
this.scheduleParsedStorageSync(documentId, revisionKey);
|
|
2839
2777
|
return {
|
|
2840
2778
|
document: createRemoteKnowledgeDocument({
|
|
@@ -2870,7 +2808,7 @@ var Knowledge = class _Knowledge {
|
|
|
2870
2808
|
page: startPage,
|
|
2871
2809
|
pageSize: limits.remotePageSize,
|
|
2872
2810
|
chunkType: params.chunkType,
|
|
2873
|
-
includeAssetUrls:
|
|
2811
|
+
includeAssetUrls: true
|
|
2874
2812
|
});
|
|
2875
2813
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2876
2814
|
const stored = startPage === 1 ? await this.tryGrepChunksFromParsedStorage({
|
|
@@ -2967,7 +2905,7 @@ var Knowledge = class _Knowledge {
|
|
|
2967
2905
|
page,
|
|
2968
2906
|
pageSize: limits.remotePageSize,
|
|
2969
2907
|
chunkType: params.chunkType,
|
|
2970
|
-
includeAssetUrls:
|
|
2908
|
+
includeAssetUrls: true
|
|
2971
2909
|
});
|
|
2972
2910
|
}
|
|
2973
2911
|
}
|
|
@@ -2982,7 +2920,7 @@ var Knowledge = class _Knowledge {
|
|
|
2982
2920
|
const firstPage = await this.client.documents.listChunks(documentId, {
|
|
2983
2921
|
page: 1,
|
|
2984
2922
|
pageSize: limits.remotePageSize,
|
|
2985
|
-
includeAssetUrls:
|
|
2923
|
+
includeAssetUrls: true
|
|
2986
2924
|
});
|
|
2987
2925
|
const revisionKey = getRemoteRevisionKey(firstPage);
|
|
2988
2926
|
const stored = await this.tryReadOutlineFromParsedStorage(documentId, revisionKey);
|
|
@@ -3004,7 +2942,7 @@ var Knowledge = class _Knowledge {
|
|
|
3004
2942
|
response = await this.client.documents.listChunks(documentId, {
|
|
3005
2943
|
page,
|
|
3006
2944
|
pageSize: limits.remotePageSize,
|
|
3007
|
-
includeAssetUrls:
|
|
2945
|
+
includeAssetUrls: true
|
|
3008
2946
|
});
|
|
3009
2947
|
}
|
|
3010
2948
|
const truncated = response.pagination.page < response.pagination.totalPages;
|
|
@@ -3030,28 +2968,13 @@ var Knowledge = class _Knowledge {
|
|
|
3030
2968
|
};
|
|
3031
2969
|
}
|
|
3032
2970
|
async tryReadChunksFromParsedStorage(params) {
|
|
3033
|
-
const
|
|
3034
|
-
if (!parsedStorageConfig) {
|
|
3035
|
-
return null;
|
|
3036
|
-
}
|
|
3037
|
-
const manifest = await this.readFreshParsedStorageManifest(
|
|
2971
|
+
const storedResult = await this.readCommittedParsedStorageResult(
|
|
3038
2972
|
params.documentId,
|
|
3039
2973
|
params.revisionKey
|
|
3040
2974
|
);
|
|
3041
|
-
if (!
|
|
3042
|
-
return null;
|
|
3043
|
-
}
|
|
2975
|
+
if (!storedResult) return null;
|
|
3044
2976
|
const pageParams = getReadPageParams(params.params);
|
|
3045
|
-
const
|
|
3046
|
-
documentId: params.documentId,
|
|
3047
|
-
revisionKey: params.revisionKey,
|
|
3048
|
-
manifest,
|
|
3049
|
-
chunkType: params.params.chunkType
|
|
3050
|
-
});
|
|
3051
|
-
if (!indexedChunks) {
|
|
3052
|
-
return null;
|
|
3053
|
-
}
|
|
3054
|
-
const scopedChunks = indexedChunks.filter((chunk) => matchesReadScope(chunk, params.params));
|
|
2977
|
+
const scopedChunks = storedResult.chunks.filter((chunk) => !params.params.chunkType || chunk.chunkType === params.params.chunkType).filter((chunk) => matchesReadScope(chunk, params.params));
|
|
3055
2978
|
const selected = hasScanReadFilters(params.params) ? selectReadWindow(
|
|
3056
2979
|
scopedChunks,
|
|
3057
2980
|
params.params,
|
|
@@ -3060,17 +2983,18 @@ var Knowledge = class _Knowledge {
|
|
|
3060
2983
|
(pageParams.page - 1) * pageParams.pageSize,
|
|
3061
2984
|
pageParams.page * pageParams.pageSize
|
|
3062
2985
|
);
|
|
3063
|
-
const visibleChunks =
|
|
3064
|
-
|
|
3065
|
-
params.
|
|
3066
|
-
|
|
2986
|
+
const visibleChunks = await applyStoredAssetUrlsToReadChunks({
|
|
2987
|
+
storageConfig: this.requireParsedStorageConfig(),
|
|
2988
|
+
documentId: params.documentId,
|
|
2989
|
+
revisionKey: params.revisionKey,
|
|
2990
|
+
chunks: selected.map(toReadChunk)
|
|
2991
|
+
});
|
|
3067
2992
|
const totalChunks = scopedChunks.length;
|
|
3068
2993
|
return {
|
|
3069
2994
|
document: createStoredKnowledgeDocument({
|
|
3070
2995
|
documentId: params.documentId,
|
|
3071
|
-
|
|
3072
|
-
revisionKey: params.revisionKey
|
|
3073
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
2996
|
+
storedResult,
|
|
2997
|
+
revisionKey: params.revisionKey
|
|
3074
2998
|
}),
|
|
3075
2999
|
chunks: visibleChunks,
|
|
3076
3000
|
page: hasScanReadFilters(params.params) ? void 0 : pageParams.page,
|
|
@@ -3081,30 +3005,15 @@ var Knowledge = class _Knowledge {
|
|
|
3081
3005
|
};
|
|
3082
3006
|
}
|
|
3083
3007
|
async tryGrepChunksFromParsedStorage(params) {
|
|
3084
|
-
const
|
|
3085
|
-
if (!parsedStorageConfig) {
|
|
3086
|
-
return null;
|
|
3087
|
-
}
|
|
3088
|
-
const manifest = await this.readFreshParsedStorageManifest(
|
|
3008
|
+
const storedResult = await this.readCommittedParsedStorageResult(
|
|
3089
3009
|
params.documentId,
|
|
3090
3010
|
params.revisionKey
|
|
3091
3011
|
);
|
|
3092
|
-
if (!
|
|
3093
|
-
return null;
|
|
3094
|
-
}
|
|
3095
|
-
const indexedChunks = await this.readStoredSnapshotChunks({
|
|
3096
|
-
documentId: params.documentId,
|
|
3097
|
-
revisionKey: params.revisionKey,
|
|
3098
|
-
manifest,
|
|
3099
|
-
chunkType: params.params.chunkType
|
|
3100
|
-
});
|
|
3101
|
-
if (!indexedChunks) {
|
|
3102
|
-
return null;
|
|
3103
|
-
}
|
|
3012
|
+
if (!storedResult) return null;
|
|
3104
3013
|
const maxResults = clampLimit(params.params.maxResults, DEFAULT_GREP_LIMIT, MAX_GREP_LIMIT);
|
|
3105
3014
|
const contextChars = params.params.contextChars ?? DEFAULT_CONTEXT_CHARS;
|
|
3106
3015
|
const matcher = createMatcher(params.params);
|
|
3107
|
-
const scopedChunks =
|
|
3016
|
+
const scopedChunks = storedResult.chunks.filter((chunk) => !params.params.chunkType || chunk.chunkType === params.params.chunkType).filter((chunk) => matchesGrepScope(chunk, params.params));
|
|
3108
3017
|
const matches = [];
|
|
3109
3018
|
let scannedChunks = 0;
|
|
3110
3019
|
for (const chunk of scopedChunks) {
|
|
@@ -3125,9 +3034,8 @@ var Knowledge = class _Knowledge {
|
|
|
3125
3034
|
return {
|
|
3126
3035
|
document: createStoredKnowledgeDocument({
|
|
3127
3036
|
documentId: params.documentId,
|
|
3128
|
-
|
|
3129
|
-
revisionKey: params.revisionKey
|
|
3130
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
3037
|
+
storedResult,
|
|
3038
|
+
revisionKey: params.revisionKey
|
|
3131
3039
|
}),
|
|
3132
3040
|
matches,
|
|
3133
3041
|
scannedChunks,
|
|
@@ -3139,9 +3047,8 @@ var Knowledge = class _Knowledge {
|
|
|
3139
3047
|
return {
|
|
3140
3048
|
document: createStoredKnowledgeDocument({
|
|
3141
3049
|
documentId: params.documentId,
|
|
3142
|
-
|
|
3143
|
-
revisionKey: params.revisionKey
|
|
3144
|
-
typeCounts: countIndexedTypes(indexedChunks)
|
|
3050
|
+
storedResult,
|
|
3051
|
+
revisionKey: params.revisionKey
|
|
3145
3052
|
}),
|
|
3146
3053
|
matches,
|
|
3147
3054
|
scannedChunks,
|
|
@@ -3149,98 +3056,82 @@ var Knowledge = class _Knowledge {
|
|
|
3149
3056
|
};
|
|
3150
3057
|
}
|
|
3151
3058
|
async tryReadOutlineFromParsedStorage(documentId, revisionKey) {
|
|
3152
|
-
const
|
|
3153
|
-
if (!
|
|
3154
|
-
|
|
3155
|
-
|
|
3156
|
-
|
|
3157
|
-
|
|
3158
|
-
|
|
3159
|
-
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
}
|
|
3164
|
-
const sections = buildFlatSectionsFromIndexedChunks(indexedChunks);
|
|
3165
|
-
const typeCounts = countIndexedTypes(indexedChunks);
|
|
3059
|
+
const storedResult = await this.readCommittedParsedStorageResult(documentId, revisionKey);
|
|
3060
|
+
if (!storedResult) return null;
|
|
3061
|
+
const sections = storedResult.docNav?.sections && storedResult.docNav.sections.length > 0 ? flattenSections(
|
|
3062
|
+
storedResult.docNav.sections.map(
|
|
3063
|
+
(section) => toKnowledgeSection(
|
|
3064
|
+
section,
|
|
3065
|
+
storedResult.chunks,
|
|
3066
|
+
storedResult.manifest.sourceFileName
|
|
3067
|
+
)
|
|
3068
|
+
)
|
|
3069
|
+
) : buildFlatSectionsFromIndexedChunks(storedResult.chunks);
|
|
3166
3070
|
return {
|
|
3167
3071
|
document: createStoredKnowledgeDocument({
|
|
3168
3072
|
documentId,
|
|
3169
|
-
|
|
3170
|
-
revisionKey
|
|
3171
|
-
typeCounts
|
|
3073
|
+
storedResult,
|
|
3074
|
+
revisionKey
|
|
3172
3075
|
}),
|
|
3173
|
-
totalChunks:
|
|
3174
|
-
typeCounts,
|
|
3076
|
+
totalChunks: storedResult.chunks.length,
|
|
3077
|
+
typeCounts: storedResult.typeCounts,
|
|
3175
3078
|
sections,
|
|
3176
|
-
sectionTree:
|
|
3079
|
+
sectionTree: storedResult.docNav?.sections && storedResult.docNav.sections.length > 0 ? storedResult.docNav.sections.map(
|
|
3080
|
+
(section) => toKnowledgeSection(
|
|
3081
|
+
section,
|
|
3082
|
+
storedResult.chunks,
|
|
3083
|
+
storedResult.manifest.sourceFileName
|
|
3084
|
+
)
|
|
3085
|
+
) : nestSections(sections),
|
|
3177
3086
|
truncated: false
|
|
3178
3087
|
};
|
|
3179
3088
|
}
|
|
3180
|
-
async
|
|
3089
|
+
async readCommittedParsedStorageResult(documentId, revisionKey) {
|
|
3181
3090
|
const parsedStorageConfig = this.parsedStorageConfig;
|
|
3182
3091
|
if (!parsedStorageConfig) {
|
|
3183
3092
|
return null;
|
|
3184
3093
|
}
|
|
3185
|
-
const
|
|
3094
|
+
const commit = await readParsedDocumentCommit({
|
|
3095
|
+
storage: parsedStorageConfig.storage,
|
|
3186
3096
|
documentId,
|
|
3187
3097
|
revisionKey
|
|
3188
3098
|
});
|
|
3189
|
-
if (!
|
|
3099
|
+
if (!commit) {
|
|
3190
3100
|
return null;
|
|
3191
3101
|
}
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
3102
|
+
const [manifestObject, chunksObject, docNavObject] = await Promise.all([
|
|
3103
|
+
parsedStorageConfig.storage.readObject({
|
|
3104
|
+
documentId,
|
|
3105
|
+
revisionKey,
|
|
3106
|
+
path: "manifest.json"
|
|
3107
|
+
}),
|
|
3108
|
+
parsedStorageConfig.storage.readObject({
|
|
3109
|
+
documentId,
|
|
3110
|
+
revisionKey,
|
|
3111
|
+
path: "chunks.json"
|
|
3112
|
+
}),
|
|
3113
|
+
parsedStorageConfig.storage.readObject({
|
|
3114
|
+
documentId,
|
|
3115
|
+
revisionKey,
|
|
3116
|
+
path: "doc_nav.json"
|
|
3117
|
+
})
|
|
3118
|
+
]);
|
|
3119
|
+
if (!manifestObject || !chunksObject) {
|
|
3197
3120
|
return null;
|
|
3198
3121
|
}
|
|
3199
|
-
const
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
}
|
|
3210
|
-
chunks
|
|
3211
|
-
|
|
3212
|
-
);
|
|
3213
|
-
}
|
|
3214
|
-
return chunks.sort((left, right) => left.position - right.position);
|
|
3215
|
-
}
|
|
3216
|
-
async toRemoteReadChunks(params) {
|
|
3217
|
-
const readChunks = params.chunks.map((chunk) => toRemoteReadChunk(chunk));
|
|
3218
|
-
if (params.assetUrlPolicy === "durable") {
|
|
3219
|
-
return this.hardenReadChunkAssetUrls({
|
|
3220
|
-
documentId: params.documentId,
|
|
3221
|
-
revisionKey: params.revisionKey,
|
|
3222
|
-
chunks: readChunks
|
|
3223
|
-
});
|
|
3224
|
-
}
|
|
3225
|
-
return applyAssetUrlPolicyToReadChunks(readChunks, params.assetUrlPolicy);
|
|
3226
|
-
}
|
|
3227
|
-
async hardenReadChunkAssetUrls(params) {
|
|
3228
|
-
const parsedStorageConfig = this.parsedStorageConfig;
|
|
3229
|
-
if (!parsedStorageConfig) {
|
|
3230
|
-
return applyAssetUrlPolicyToReadChunks(params.chunks, "none");
|
|
3231
|
-
}
|
|
3232
|
-
const hardenedChunks = [];
|
|
3233
|
-
for (const chunk of params.chunks) {
|
|
3234
|
-
hardenedChunks.push(
|
|
3235
|
-
await hardenReadChunkAssetUrls({
|
|
3236
|
-
storageConfig: parsedStorageConfig,
|
|
3237
|
-
documentId: params.documentId,
|
|
3238
|
-
revisionKey: params.revisionKey,
|
|
3239
|
-
chunk
|
|
3240
|
-
})
|
|
3241
|
-
);
|
|
3242
|
-
}
|
|
3243
|
-
return hardenedChunks;
|
|
3122
|
+
const manifest = readJsonObject(manifestObject);
|
|
3123
|
+
const chunks = parseStoredResultChunks({
|
|
3124
|
+
payload: readJsonObject(chunksObject),
|
|
3125
|
+
sourceFileName: manifest.sourceFileName
|
|
3126
|
+
});
|
|
3127
|
+
const docNav = docNavObject ? readJsonObject(docNavObject) : void 0;
|
|
3128
|
+
return {
|
|
3129
|
+
commit,
|
|
3130
|
+
manifest,
|
|
3131
|
+
chunks,
|
|
3132
|
+
docNav: docNav?.sections ? { sections: docNav.sections } : void 0,
|
|
3133
|
+
typeCounts: countIndexedTypes(chunks)
|
|
3134
|
+
};
|
|
3244
3135
|
}
|
|
3245
3136
|
scheduleParsedStorageSync(documentId, revisionKey) {
|
|
3246
3137
|
const parsedStorageConfig = this.parsedStorageConfig;
|
|
@@ -3260,7 +3151,6 @@ var Knowledge = class _Knowledge {
|
|
|
3260
3151
|
documentId,
|
|
3261
3152
|
revisionKey,
|
|
3262
3153
|
nextChunkPage: 1,
|
|
3263
|
-
nextAssetIndex: 0,
|
|
3264
3154
|
status: "failed",
|
|
3265
3155
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3266
3156
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -3270,28 +3160,63 @@ var Knowledge = class _Knowledge {
|
|
|
3270
3160
|
void Promise.resolve(scheduler.schedule(task)).catch(() => void 0);
|
|
3271
3161
|
}
|
|
3272
3162
|
async syncRemoteDocumentToParsedStorage(params) {
|
|
3273
|
-
const
|
|
3274
|
-
|
|
3275
|
-
|
|
3276
|
-
revisionKey: params.revisionKey
|
|
3277
|
-
}) : null;
|
|
3278
|
-
let nextPage = existingProgress?.status === "running" ? existingProgress.nextChunkPage : 1;
|
|
3279
|
-
let response = await this.client.documents.listChunks(params.documentId, {
|
|
3280
|
-
page: nextPage,
|
|
3281
|
-
pageSize: limits.remotePageSize,
|
|
3163
|
+
const firstPage = await this.client.documents.listChunks(params.documentId, {
|
|
3164
|
+
page: 1,
|
|
3165
|
+
pageSize: 1,
|
|
3282
3166
|
includeAssetUrls: true
|
|
3283
3167
|
});
|
|
3284
|
-
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(
|
|
3285
|
-
if (params.revisionKey && getRemoteRevisionKey(
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
includeAssetUrls: true
|
|
3168
|
+
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(firstPage);
|
|
3169
|
+
if (params.revisionKey && getRemoteRevisionKey(firstPage) !== params.revisionKey) {
|
|
3170
|
+
return this.syncRemoteDocumentToParsedStorage({
|
|
3171
|
+
documentId: params.documentId,
|
|
3172
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3290
3173
|
});
|
|
3291
|
-
nextPage = 1;
|
|
3292
3174
|
}
|
|
3293
|
-
|
|
3294
|
-
|
|
3175
|
+
if (firstPage.jobId) {
|
|
3176
|
+
try {
|
|
3177
|
+
const loadedResult = await this.client.jobs.load(firstPage.jobId);
|
|
3178
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3179
|
+
result: loadedResult,
|
|
3180
|
+
storage: params.parsedStorageConfig.storage,
|
|
3181
|
+
documentId: params.documentId,
|
|
3182
|
+
revisionKey,
|
|
3183
|
+
source: "resultZip"
|
|
3184
|
+
});
|
|
3185
|
+
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3186
|
+
documentId: params.documentId,
|
|
3187
|
+
revisionKey,
|
|
3188
|
+
status: "completed",
|
|
3189
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3190
|
+
});
|
|
3191
|
+
return {
|
|
3192
|
+
documentId: synced.documentId,
|
|
3193
|
+
revisionKey: synced.revisionKey,
|
|
3194
|
+
completed: true,
|
|
3195
|
+
commit: synced.commit
|
|
3196
|
+
};
|
|
3197
|
+
} catch {
|
|
3198
|
+
}
|
|
3199
|
+
}
|
|
3200
|
+
return this.syncRemoteDocumentChunksToParsedStorage({
|
|
3201
|
+
documentId: params.documentId,
|
|
3202
|
+
revisionKey,
|
|
3203
|
+
firstPage,
|
|
3204
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3205
|
+
});
|
|
3206
|
+
}
|
|
3207
|
+
async syncRemoteDocumentChunksToParsedStorage(params) {
|
|
3208
|
+
const limits = getParsedStorageLimits(params.parsedStorageConfig.limits);
|
|
3209
|
+
const existingProgress = await params.parsedStorageConfig.storage.readSyncProgress({
|
|
3210
|
+
documentId: params.documentId,
|
|
3211
|
+
revisionKey: params.revisionKey
|
|
3212
|
+
});
|
|
3213
|
+
let nextPage = existingProgress?.status === "running" ? existingProgress.nextChunkPage ?? 1 : 1;
|
|
3214
|
+
let response = nextPage === 1 && params.firstPage.pagination.pageSize === limits.remotePageSize ? params.firstPage : await this.client.documents.listChunks(params.documentId, {
|
|
3215
|
+
page: nextPage,
|
|
3216
|
+
pageSize: limits.remotePageSize,
|
|
3217
|
+
includeAssetUrls: true
|
|
3218
|
+
});
|
|
3219
|
+
const totalPages = response.pagination.totalPages;
|
|
3295
3220
|
let syncedPages = 0;
|
|
3296
3221
|
const startedAt = Date.now();
|
|
3297
3222
|
while (nextPage <= totalPages) {
|
|
@@ -3302,65 +3227,88 @@ var Knowledge = class _Knowledge {
|
|
|
3302
3227
|
includeAssetUrls: true
|
|
3303
3228
|
});
|
|
3304
3229
|
}
|
|
3305
|
-
|
|
3230
|
+
await params.parsedStorageConfig.storage.writeObject({
|
|
3306
3231
|
documentId: params.documentId,
|
|
3307
|
-
revisionKey,
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
response,
|
|
3312
|
-
revisionKey,
|
|
3313
|
-
chunks: readChunks
|
|
3314
|
-
});
|
|
3315
|
-
await params.parsedStorageConfig.storage.writeChunkPage({
|
|
3316
|
-
documentId: params.documentId,
|
|
3317
|
-
revisionKey,
|
|
3318
|
-
page
|
|
3232
|
+
revisionKey: params.revisionKey,
|
|
3233
|
+
path: getRemoteReconstructionPagePath(response.pagination.page),
|
|
3234
|
+
body: Buffer.from(JSON.stringify({ chunks: response.chunks }), "utf8"),
|
|
3235
|
+
contentType: "application/json; charset=utf-8"
|
|
3319
3236
|
});
|
|
3320
|
-
chunkPages.push(page);
|
|
3321
3237
|
nextPage += 1;
|
|
3322
3238
|
syncedPages += 1;
|
|
3323
3239
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3324
3240
|
documentId: params.documentId,
|
|
3325
|
-
revisionKey,
|
|
3241
|
+
revisionKey: params.revisionKey,
|
|
3326
3242
|
nextChunkPage: nextPage,
|
|
3327
|
-
nextAssetIndex: 0,
|
|
3328
3243
|
status: "running",
|
|
3329
3244
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3330
3245
|
});
|
|
3331
3246
|
if (syncedPages >= limits.maxPagesPerSync || Date.now() - startedAt >= limits.syncDeadlineMs) {
|
|
3332
3247
|
return {
|
|
3333
3248
|
documentId: params.documentId,
|
|
3334
|
-
revisionKey,
|
|
3249
|
+
revisionKey: params.revisionKey,
|
|
3335
3250
|
completed: false
|
|
3336
3251
|
};
|
|
3337
3252
|
}
|
|
3338
3253
|
}
|
|
3339
|
-
const
|
|
3340
|
-
|
|
3341
|
-
revisionKey,
|
|
3342
|
-
|
|
3254
|
+
const chunks = await this.readRemoteReconstructionChunks({
|
|
3255
|
+
documentId: params.documentId,
|
|
3256
|
+
revisionKey: params.revisionKey,
|
|
3257
|
+
totalPages,
|
|
3258
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3343
3259
|
});
|
|
3344
|
-
|
|
3260
|
+
if (!chunks) {
|
|
3261
|
+
return {
|
|
3262
|
+
documentId: params.documentId,
|
|
3263
|
+
revisionKey: params.revisionKey,
|
|
3264
|
+
completed: false
|
|
3265
|
+
};
|
|
3266
|
+
}
|
|
3267
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3268
|
+
result: createMinimalParseResultFromRemoteChunks({
|
|
3269
|
+
documentId: params.documentId,
|
|
3270
|
+
revisionKey: params.revisionKey,
|
|
3271
|
+
response,
|
|
3272
|
+
chunks
|
|
3273
|
+
}),
|
|
3274
|
+
storage: params.parsedStorageConfig.storage,
|
|
3345
3275
|
documentId: params.documentId,
|
|
3346
|
-
revisionKey,
|
|
3347
|
-
|
|
3276
|
+
revisionKey: params.revisionKey,
|
|
3277
|
+
source: "remoteReconstruction"
|
|
3348
3278
|
});
|
|
3349
3279
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3350
3280
|
documentId: params.documentId,
|
|
3351
|
-
revisionKey,
|
|
3281
|
+
revisionKey: params.revisionKey,
|
|
3352
3282
|
nextChunkPage: totalPages + 1,
|
|
3353
|
-
nextAssetIndex: 0,
|
|
3354
3283
|
status: "completed",
|
|
3355
3284
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3356
3285
|
});
|
|
3357
3286
|
return {
|
|
3358
3287
|
documentId: params.documentId,
|
|
3359
|
-
revisionKey,
|
|
3288
|
+
revisionKey: params.revisionKey,
|
|
3360
3289
|
completed: true,
|
|
3361
|
-
|
|
3290
|
+
commit: synced.commit
|
|
3362
3291
|
};
|
|
3363
3292
|
}
|
|
3293
|
+
async readRemoteReconstructionChunks(params) {
|
|
3294
|
+
const chunks = [];
|
|
3295
|
+
for (let page = 1; page <= params.totalPages; page += 1) {
|
|
3296
|
+
const object = await params.parsedStorageConfig.storage.readObject({
|
|
3297
|
+
documentId: params.documentId,
|
|
3298
|
+
revisionKey: params.revisionKey,
|
|
3299
|
+
path: getRemoteReconstructionPagePath(page)
|
|
3300
|
+
});
|
|
3301
|
+
if (!object) {
|
|
3302
|
+
return null;
|
|
3303
|
+
}
|
|
3304
|
+
const payload = readJsonObject(object);
|
|
3305
|
+
if (!isDocumentChunkArray(payload.chunks)) {
|
|
3306
|
+
return null;
|
|
3307
|
+
}
|
|
3308
|
+
chunks.push(...payload.chunks);
|
|
3309
|
+
}
|
|
3310
|
+
return chunks;
|
|
3311
|
+
}
|
|
3364
3312
|
requireParsedStorageConfig() {
|
|
3365
3313
|
if (!this.parsedStorageConfig) {
|
|
3366
3314
|
throw new ValidationError("parsed document storage is not configured");
|
|
@@ -3374,7 +3322,8 @@ var Knowledge = class _Knowledge {
|
|
|
3374
3322
|
async getPublishedDocumentJobId(documentId) {
|
|
3375
3323
|
const response = await this.client.documents.listChunks(documentId, {
|
|
3376
3324
|
page: 1,
|
|
3377
|
-
pageSize: 1
|
|
3325
|
+
pageSize: 1,
|
|
3326
|
+
includeAssetUrls: true
|
|
3378
3327
|
});
|
|
3379
3328
|
if (!response.jobId) {
|
|
3380
3329
|
throw new Error(
|
|
@@ -3407,14 +3356,12 @@ var defaultParsedStorageScheduler = {
|
|
|
3407
3356
|
};
|
|
3408
3357
|
function getParsedStorageLimits(limits) {
|
|
3409
3358
|
return {
|
|
3410
|
-
chunkPageSize: clampLimit(limits?.chunkPageSize, DEFAULT_REMOTE_SCAN_PAGE_SIZE, MAX_PAGE_SIZE),
|
|
3411
3359
|
remotePageSize: clampLimit(
|
|
3412
3360
|
limits?.remotePageSize,
|
|
3413
3361
|
DEFAULT_REMOTE_SCAN_PAGE_SIZE,
|
|
3414
3362
|
MAX_PAGE_SIZE
|
|
3415
3363
|
),
|
|
3416
3364
|
maxPagesPerSync: clampLimit(limits?.maxPagesPerSync, DEFAULT_MAX_SYNC_PAGES, 1e3),
|
|
3417
|
-
maxAssetsPerSync: clampLimit(limits?.maxAssetsPerSync, DEFAULT_MAX_SYNC_ASSETS, 1e3),
|
|
3418
3365
|
syncDeadlineMs: clampLimit(limits?.syncDeadlineMs, DEFAULT_SYNC_DEADLINE_MS, 6e4),
|
|
3419
3366
|
grepMaxPages: clampLimit(limits?.grepMaxPages, DEFAULT_GREP_MAX_PAGES, 1e3),
|
|
3420
3367
|
grepDeadlineMs: clampLimit(limits?.grepDeadlineMs, DEFAULT_GREP_DEADLINE_MS, 6e4),
|
|
@@ -3423,13 +3370,13 @@ function getParsedStorageLimits(limits) {
|
|
|
3423
3370
|
};
|
|
3424
3371
|
}
|
|
3425
3372
|
function validateReadParams(params) {
|
|
3426
|
-
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0
|
|
3373
|
+
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0;
|
|
3427
3374
|
if (!usesPagedDisplay) {
|
|
3428
3375
|
return;
|
|
3429
3376
|
}
|
|
3430
3377
|
if (params.sectionPath !== void 0 || params.startChunk !== void 0 || params.endChunk !== void 0 || params.chunkId !== void 0) {
|
|
3431
3378
|
throw new ValidationError(
|
|
3432
|
-
"page
|
|
3379
|
+
"page and pageSize cannot be combined with sectionPath, startChunk, endChunk, or chunkId"
|
|
3433
3380
|
);
|
|
3434
3381
|
}
|
|
3435
3382
|
}
|
|
@@ -3442,9 +3389,6 @@ function getReadPageParams(params) {
|
|
|
3442
3389
|
pageSize: clampLimit(params.pageSize ?? params.limit, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
|
|
3443
3390
|
};
|
|
3444
3391
|
}
|
|
3445
|
-
function shouldRequestRemoteAssetUrls(assetUrlPolicy, parsedStorageConfig) {
|
|
3446
|
-
return assetUrlPolicy === "durable" && parsedStorageConfig !== void 0;
|
|
3447
|
-
}
|
|
3448
3392
|
function getRemoteRevisionKey(response) {
|
|
3449
3393
|
const revisionKey = response.jobResultId ?? response.jobId;
|
|
3450
3394
|
if (!revisionKey) {
|
|
@@ -3454,6 +3398,9 @@ function getRemoteRevisionKey(response) {
|
|
|
3454
3398
|
}
|
|
3455
3399
|
return revisionKey;
|
|
3456
3400
|
}
|
|
3401
|
+
function getRemoteReconstructionPagePath(page) {
|
|
3402
|
+
return `${remoteReconstructionPageDirectory}/page-${page}.json`;
|
|
3403
|
+
}
|
|
3457
3404
|
function createRemoteKnowledgeDocument(params) {
|
|
3458
3405
|
return {
|
|
3459
3406
|
localDocumentId: params.documentId,
|
|
@@ -3468,23 +3415,103 @@ function createRemoteKnowledgeDocument(params) {
|
|
|
3468
3415
|
updatedAt: /* @__PURE__ */ new Date(0)
|
|
3469
3416
|
};
|
|
3470
3417
|
}
|
|
3418
|
+
function createMinimalParseResultFromRemoteChunks(params) {
|
|
3419
|
+
const chunks = params.chunks.map(toMinimalChunkFromRemoteChunk);
|
|
3420
|
+
const typeCounts = countRemoteChunkTypes(params.chunks);
|
|
3421
|
+
return {
|
|
3422
|
+
manifest: {
|
|
3423
|
+
version: "2.0",
|
|
3424
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3425
|
+
sourceFileName: params.documentId,
|
|
3426
|
+
statistics: {
|
|
3427
|
+
totalChunks: chunks.length,
|
|
3428
|
+
textChunks: typeCounts.text,
|
|
3429
|
+
imageChunks: typeCounts.image,
|
|
3430
|
+
tableChunks: typeCounts.table,
|
|
3431
|
+
pageChunks: typeCounts.page
|
|
3432
|
+
}
|
|
3433
|
+
},
|
|
3434
|
+
chunks,
|
|
3435
|
+
rawZip: Buffer.from(""),
|
|
3436
|
+
namespace: params.response.namespace,
|
|
3437
|
+
documentId: params.documentId,
|
|
3438
|
+
textChunks: chunks.filter(
|
|
3439
|
+
(chunk) => chunk.type === "text"
|
|
3440
|
+
),
|
|
3441
|
+
imageChunks: chunks.filter(
|
|
3442
|
+
(chunk) => chunk.type === "image"
|
|
3443
|
+
),
|
|
3444
|
+
tableChunks: chunks.filter(
|
|
3445
|
+
(chunk) => chunk.type === "table"
|
|
3446
|
+
),
|
|
3447
|
+
pageChunks: chunks.filter(
|
|
3448
|
+
(chunk) => chunk.type === "page"
|
|
3449
|
+
),
|
|
3450
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3451
|
+
statistics: {
|
|
3452
|
+
totalChunks: chunks.length,
|
|
3453
|
+
textChunks: typeCounts.text,
|
|
3454
|
+
imageChunks: typeCounts.image,
|
|
3455
|
+
tableChunks: typeCounts.table,
|
|
3456
|
+
pageChunks: typeCounts.page
|
|
3457
|
+
},
|
|
3458
|
+
getChunk: (chunkId) => chunks.find((chunk) => chunk.chunkId === chunkId),
|
|
3459
|
+
save: () => Promise.reject(new Error("Minimal remote reconstruction cannot be saved directly."))
|
|
3460
|
+
};
|
|
3461
|
+
}
|
|
3462
|
+
function toMinimalChunkFromRemoteChunk(chunk) {
|
|
3463
|
+
const baseChunk = {
|
|
3464
|
+
chunkId: chunk.chunkId,
|
|
3465
|
+
contentSource: chunk.contentSource ?? void 0,
|
|
3466
|
+
content: chunk.content ?? "",
|
|
3467
|
+
path: chunk.sourceChunkPath ?? chunk.sectionPath ?? "",
|
|
3468
|
+
metadata: cloneMetadata(chunk.metadata)
|
|
3469
|
+
};
|
|
3470
|
+
if (chunk.chunkType === "image") {
|
|
3471
|
+
return {
|
|
3472
|
+
...baseChunk,
|
|
3473
|
+
type: "image",
|
|
3474
|
+
filePath: chunk.filePath ?? "",
|
|
3475
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3476
|
+
data: Buffer.alloc(0),
|
|
3477
|
+
format: inferContentTypeFromPath2(chunk.filePath ?? "").replace("image/", ""),
|
|
3478
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3479
|
+
};
|
|
3480
|
+
}
|
|
3481
|
+
if (chunk.chunkType === "table") {
|
|
3482
|
+
return {
|
|
3483
|
+
...baseChunk,
|
|
3484
|
+
type: "table",
|
|
3485
|
+
filePath: chunk.filePath ?? "",
|
|
3486
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3487
|
+
html: chunk.content ?? "",
|
|
3488
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3489
|
+
};
|
|
3490
|
+
}
|
|
3491
|
+
if (chunk.chunkType === "page") {
|
|
3492
|
+
return {
|
|
3493
|
+
...baseChunk,
|
|
3494
|
+
type: "page"
|
|
3495
|
+
};
|
|
3496
|
+
}
|
|
3497
|
+
return {
|
|
3498
|
+
...baseChunk,
|
|
3499
|
+
type: "text"
|
|
3500
|
+
};
|
|
3501
|
+
}
|
|
3471
3502
|
function createStoredKnowledgeDocument(params) {
|
|
3472
3503
|
return {
|
|
3473
3504
|
localDocumentId: params.documentId,
|
|
3474
|
-
jobId: params.manifest.jobId || params.revisionKey,
|
|
3475
|
-
documentId: params.
|
|
3476
|
-
|
|
3477
|
-
|
|
3478
|
-
|
|
3479
|
-
typeCounts: params.typeCounts,
|
|
3505
|
+
jobId: params.storedResult.manifest.jobId || params.revisionKey,
|
|
3506
|
+
documentId: params.documentId,
|
|
3507
|
+
sourceFileName: params.storedResult.manifest.sourceFileName,
|
|
3508
|
+
chunkCount: params.storedResult.chunks.length,
|
|
3509
|
+
typeCounts: params.storedResult.typeCounts,
|
|
3480
3510
|
resultDirectoryPath: `parsed-storage:${params.documentId}`,
|
|
3481
|
-
createdAt: new Date(params.
|
|
3482
|
-
updatedAt: new Date(params.
|
|
3511
|
+
createdAt: new Date(params.storedResult.commit.committedAt),
|
|
3512
|
+
updatedAt: new Date(params.storedResult.commit.committedAt)
|
|
3483
3513
|
};
|
|
3484
3514
|
}
|
|
3485
|
-
function isFreshManifest(manifest, revisionKey) {
|
|
3486
|
-
return (manifest.revisionKey ?? manifest.jobId) === revisionKey;
|
|
3487
|
-
}
|
|
3488
3515
|
function toRemoteReadChunk(chunk) {
|
|
3489
3516
|
const metadata = cloneMetadata(chunk.metadata);
|
|
3490
3517
|
return {
|
|
@@ -3513,22 +3540,60 @@ function toIndexedRemoteChunk(chunk) {
|
|
|
3513
3540
|
const readChunk = toRemoteReadChunk(chunk);
|
|
3514
3541
|
return toIndexedReadChunk(readChunk);
|
|
3515
3542
|
}
|
|
3516
|
-
function
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
chunkType
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3543
|
+
function parseStoredResultChunks(params) {
|
|
3544
|
+
const rawChunks = extractStoredChunkRecords(params.payload);
|
|
3545
|
+
return rawChunks.map((record, index) => {
|
|
3546
|
+
const metadata = readRecordMetadata(record);
|
|
3547
|
+
const chunkType = readRecordString(record, "type", "chunkType", "chunk_type");
|
|
3548
|
+
const content = readRecordString(record, "content") ?? "";
|
|
3549
|
+
const sourceChunkPath = readRecordString(record, "path", "sourceChunkPath", "source_chunk_path") ?? "";
|
|
3550
|
+
const chunk = {
|
|
3551
|
+
position: index + 1,
|
|
3552
|
+
chunkId: readRecordString(record, "chunkId", "chunk_id") ?? "",
|
|
3553
|
+
chunkType: isKnowledgeChunkType(chunkType) ? chunkType : "text",
|
|
3554
|
+
contentSource: readRecordString(record, "contentSource", "content_source"),
|
|
3555
|
+
content,
|
|
3556
|
+
readableContent: chunkType === "page" && typeof metadata.summary === "string" && metadata.summary.trim().length > 0 ? metadata.summary : content,
|
|
3557
|
+
sectionPath: normalizeSectionPath(sourceChunkPath, params.sourceFileName),
|
|
3558
|
+
sourceChunkPath,
|
|
3559
|
+
filePath: readRecordString(record, "filePath", "file_path") ?? (typeof metadata.filePath === "string" ? metadata.filePath : void 0),
|
|
3560
|
+
assetUrl: readRecordString(record, "assetUrl", "asset_url"),
|
|
3561
|
+
pageNumbers: getChunkPageNumbers(metadata),
|
|
3562
|
+
metadata
|
|
3563
|
+
};
|
|
3564
|
+
return toIndexedReadChunk(chunk);
|
|
3530
3565
|
});
|
|
3531
3566
|
}
|
|
3567
|
+
function extractStoredChunkRecords(payload) {
|
|
3568
|
+
if (Array.isArray(payload)) {
|
|
3569
|
+
return payload.filter(isRecord2);
|
|
3570
|
+
}
|
|
3571
|
+
if (isRecord2(payload) && Array.isArray(payload.chunks)) {
|
|
3572
|
+
return payload.chunks.filter(isRecord2);
|
|
3573
|
+
}
|
|
3574
|
+
return [];
|
|
3575
|
+
}
|
|
3576
|
+
function readRecordString(record, ...keys) {
|
|
3577
|
+
for (const key of keys) {
|
|
3578
|
+
const value = record[key];
|
|
3579
|
+
if (typeof value === "string") return value;
|
|
3580
|
+
}
|
|
3581
|
+
return void 0;
|
|
3582
|
+
}
|
|
3583
|
+
function readRecordNumber(record, ...keys) {
|
|
3584
|
+
for (const key of keys) {
|
|
3585
|
+
const value = record[key];
|
|
3586
|
+
if (typeof value === "number") return value;
|
|
3587
|
+
}
|
|
3588
|
+
return void 0;
|
|
3589
|
+
}
|
|
3590
|
+
function readRecordMetadata(record) {
|
|
3591
|
+
const metadata = record.metadata;
|
|
3592
|
+
return isRecord2(metadata) ? keysToCamel(metadata) : {};
|
|
3593
|
+
}
|
|
3594
|
+
function isKnowledgeChunkType(value) {
|
|
3595
|
+
return value === "text" || value === "image" || value === "table" || value === "page";
|
|
3596
|
+
}
|
|
3532
3597
|
function toIndexedReadChunk(chunk) {
|
|
3533
3598
|
return {
|
|
3534
3599
|
source: createSyntheticChunk(chunk),
|
|
@@ -3582,204 +3647,105 @@ function getNextChunkPosition(chunks, selected) {
|
|
|
3582
3647
|
}
|
|
3583
3648
|
return chunks[chunks.indexOf(lastSelected) + 1]?.position;
|
|
3584
3649
|
}
|
|
3585
|
-
function
|
|
3586
|
-
|
|
3587
|
-
|
|
3588
|
-
|
|
3589
|
-
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
|
|
3593
|
-
|
|
3594
|
-
assetUrl: void 0,
|
|
3595
|
-
metadata: removeAssetUrlsFromMetadata(chunk.metadata)
|
|
3596
|
-
}));
|
|
3650
|
+
async function applyStoredAssetUrlsToReadChunks(params) {
|
|
3651
|
+
return Promise.all(
|
|
3652
|
+
params.chunks.map(
|
|
3653
|
+
(chunk) => applyStoredAssetUrlsToReadChunk({
|
|
3654
|
+
...params,
|
|
3655
|
+
chunk
|
|
3656
|
+
})
|
|
3657
|
+
)
|
|
3658
|
+
);
|
|
3597
3659
|
}
|
|
3598
|
-
async function
|
|
3660
|
+
async function applyStoredAssetUrlsToReadChunk(params) {
|
|
3599
3661
|
const metadata = cloneMetadata(params.chunk.metadata);
|
|
3600
|
-
const
|
|
3601
|
-
const pageAssets = await hardenPageAssetUrls(params, metadata);
|
|
3602
|
-
if (pageAssets) {
|
|
3603
|
-
metadata.pageAssets = pageAssets;
|
|
3604
|
-
}
|
|
3605
|
-
return {
|
|
3606
|
-
...params.chunk,
|
|
3607
|
-
assetUrl,
|
|
3608
|
-
metadata
|
|
3609
|
-
};
|
|
3610
|
-
}
|
|
3611
|
-
async function hardenPrimaryAssetUrl(params, metadata) {
|
|
3612
|
-
if (!params.chunk.assetUrl || !params.chunk.filePath) {
|
|
3613
|
-
return void 0;
|
|
3614
|
-
}
|
|
3615
|
-
return writeDurableAssetUrl({
|
|
3662
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3616
3663
|
storageConfig: params.storageConfig,
|
|
3617
3664
|
documentId: params.documentId,
|
|
3618
3665
|
revisionKey: params.revisionKey,
|
|
3619
|
-
|
|
3620
|
-
sourceUrl: params.chunk.assetUrl,
|
|
3621
|
-
fallbackContentType: inferContentTypeFromPath(params.chunk.filePath),
|
|
3622
|
-
metadata: {
|
|
3623
|
-
chunkId: params.chunk.chunkId,
|
|
3624
|
-
chunkType: params.chunk.chunkType,
|
|
3625
|
-
sourcePath: params.chunk.filePath,
|
|
3626
|
-
...stringifyFlatMetadata(metadata)
|
|
3627
|
-
}
|
|
3666
|
+
path: params.chunk.filePath
|
|
3628
3667
|
});
|
|
3629
|
-
|
|
3630
|
-
|
|
3631
|
-
const pageAssets = toUnknownArray(metadata.pageAssets);
|
|
3632
|
-
if (!pageAssets) {
|
|
3633
|
-
return void 0;
|
|
3634
|
-
}
|
|
3635
|
-
const hardenedAssets = [];
|
|
3636
|
-
for (const pageAsset of pageAssets) {
|
|
3637
|
-
if (!isRecord2(pageAsset)) {
|
|
3638
|
-
hardenedAssets.push(pageAsset);
|
|
3639
|
-
continue;
|
|
3640
|
-
}
|
|
3641
|
-
const artifactRef = pageAsset.artifactRef;
|
|
3642
|
-
const sourceUrl = pageAsset.assetUrl;
|
|
3643
|
-
if (typeof artifactRef !== "string" || typeof sourceUrl !== "string") {
|
|
3644
|
-
hardenedAssets.push(removeAssetUrlField(pageAsset));
|
|
3645
|
-
continue;
|
|
3646
|
-
}
|
|
3647
|
-
const durableUrl = await writeDurableAssetUrl({
|
|
3648
|
-
storageConfig: params.storageConfig,
|
|
3649
|
-
documentId: params.documentId,
|
|
3650
|
-
revisionKey: params.revisionKey,
|
|
3651
|
-
sourcePath: artifactRef,
|
|
3652
|
-
sourceUrl,
|
|
3653
|
-
fallbackContentType: typeof pageAsset.contentType === "string" ? pageAsset.contentType : inferContentTypeFromPath(artifactRef),
|
|
3654
|
-
metadata: {
|
|
3655
|
-
chunkId: params.chunk.chunkId,
|
|
3656
|
-
chunkType: params.chunk.chunkType,
|
|
3657
|
-
sourcePath: artifactRef
|
|
3658
|
-
}
|
|
3659
|
-
});
|
|
3660
|
-
const rest = removeAssetUrlField(pageAsset);
|
|
3661
|
-
hardenedAssets.push(durableUrl ? { ...rest, assetUrl: durableUrl } : rest);
|
|
3662
|
-
}
|
|
3663
|
-
return hardenedAssets;
|
|
3664
|
-
}
|
|
3665
|
-
async function writeDurableAssetUrl(params) {
|
|
3666
|
-
const existingUrl = await params.storageConfig.storage.getAssetUrl({
|
|
3668
|
+
const pageAssets = await applyStoredPageAssetUrls({
|
|
3669
|
+
storageConfig: params.storageConfig,
|
|
3667
3670
|
documentId: params.documentId,
|
|
3668
3671
|
revisionKey: params.revisionKey,
|
|
3669
|
-
|
|
3672
|
+
metadata
|
|
3670
3673
|
});
|
|
3671
|
-
if (
|
|
3672
|
-
|
|
3673
|
-
|
|
3674
|
-
try {
|
|
3675
|
-
const fetched = await fetchAsset(params.sourceUrl, params.fallbackContentType);
|
|
3676
|
-
const written = await params.storageConfig.storage.writeAsset({
|
|
3677
|
-
documentId: params.documentId,
|
|
3678
|
-
revisionKey: params.revisionKey,
|
|
3679
|
-
sourcePath: params.sourcePath,
|
|
3680
|
-
body: fetched.body,
|
|
3681
|
-
contentType: fetched.contentType,
|
|
3682
|
-
metadata: params.metadata
|
|
3683
|
-
});
|
|
3684
|
-
return written.url ?? await params.storageConfig.storage.getAssetUrl({
|
|
3685
|
-
documentId: params.documentId,
|
|
3686
|
-
revisionKey: params.revisionKey,
|
|
3687
|
-
sourcePath: params.sourcePath
|
|
3688
|
-
}) ?? void 0;
|
|
3689
|
-
} catch {
|
|
3690
|
-
return void 0;
|
|
3691
|
-
}
|
|
3692
|
-
}
|
|
3693
|
-
async function fetchAsset(sourceUrl, fallbackContentType) {
|
|
3694
|
-
const response = await fetch(sourceUrl);
|
|
3695
|
-
if (!response.ok) {
|
|
3696
|
-
throw new Error(`Unable to fetch parsed asset: ${response.status}`);
|
|
3674
|
+
if (pageAssets) {
|
|
3675
|
+
metadata.pageAssets = pageAssets;
|
|
3676
|
+
delete metadata.page_assets;
|
|
3697
3677
|
}
|
|
3698
3678
|
return {
|
|
3699
|
-
|
|
3700
|
-
|
|
3679
|
+
...params.chunk,
|
|
3680
|
+
assetUrl: storedAssetUrl ?? params.chunk.assetUrl,
|
|
3681
|
+
metadata
|
|
3701
3682
|
};
|
|
3702
3683
|
}
|
|
3703
|
-
function
|
|
3704
|
-
const
|
|
3705
|
-
const pageAssets = toUnknownArray(cloned.pageAssets);
|
|
3684
|
+
async function applyStoredPageAssetUrls(params) {
|
|
3685
|
+
const pageAssets = getStoredPageAssets(params.metadata);
|
|
3706
3686
|
if (!pageAssets) {
|
|
3707
|
-
return
|
|
3687
|
+
return void 0;
|
|
3708
3688
|
}
|
|
3709
|
-
|
|
3710
|
-
|
|
3689
|
+
return Promise.all(
|
|
3690
|
+
pageAssets.map(async (pageAsset) => {
|
|
3691
|
+
if (!isRecord2(pageAsset)) {
|
|
3692
|
+
return pageAsset;
|
|
3693
|
+
}
|
|
3694
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3695
|
+
if (typeof artifactRef !== "string") {
|
|
3696
|
+
return pageAsset;
|
|
3697
|
+
}
|
|
3698
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3699
|
+
storageConfig: params.storageConfig,
|
|
3700
|
+
documentId: params.documentId,
|
|
3701
|
+
revisionKey: params.revisionKey,
|
|
3702
|
+
path: artifactRef
|
|
3703
|
+
});
|
|
3704
|
+
if (storedAssetUrl) {
|
|
3705
|
+
return {
|
|
3706
|
+
...pageAsset,
|
|
3707
|
+
artifactRef,
|
|
3708
|
+
assetUrl: storedAssetUrl
|
|
3709
|
+
};
|
|
3710
|
+
}
|
|
3711
3711
|
return pageAsset;
|
|
3712
|
-
}
|
|
3713
|
-
|
|
3714
|
-
});
|
|
3715
|
-
return cloned;
|
|
3716
|
-
}
|
|
3717
|
-
function removeAssetUrlField(value) {
|
|
3718
|
-
const cloned = { ...value };
|
|
3719
|
-
delete cloned.assetUrl;
|
|
3720
|
-
return cloned;
|
|
3721
|
-
}
|
|
3722
|
-
function toSnapshotChunkPageFromReadChunks(params) {
|
|
3723
|
-
return {
|
|
3724
|
-
version: 1,
|
|
3725
|
-
jobId: params.response.jobId ?? params.revisionKey,
|
|
3726
|
-
revisionKey: params.revisionKey,
|
|
3727
|
-
documentId: params.response.documentId,
|
|
3728
|
-
namespace: params.response.namespace,
|
|
3729
|
-
sourceFileName: params.response.documentId,
|
|
3730
|
-
page: params.response.pagination.page,
|
|
3731
|
-
pageSize: params.response.pagination.pageSize,
|
|
3732
|
-
total: params.response.pagination.total,
|
|
3733
|
-
totalPages: params.response.pagination.totalPages,
|
|
3734
|
-
chunks: params.chunks.map(toSnapshotChunkFromReadChunk)
|
|
3735
|
-
};
|
|
3712
|
+
})
|
|
3713
|
+
);
|
|
3736
3714
|
}
|
|
3737
|
-
function
|
|
3715
|
+
function getStoredPageAssets(metadata) {
|
|
3716
|
+
const pageAssets = toUnknownArray(metadata.pageAssets) ?? toUnknownArray(metadata.page_assets) ?? void 0;
|
|
3717
|
+
return pageAssets?.map(normalizeStoredPageAsset);
|
|
3718
|
+
}
|
|
3719
|
+
function normalizeStoredPageAsset(pageAsset) {
|
|
3720
|
+
if (!isRecord2(pageAsset)) {
|
|
3721
|
+
return pageAsset;
|
|
3722
|
+
}
|
|
3723
|
+
const normalizedPageAsset = { ...pageAsset };
|
|
3724
|
+
delete normalizedPageAsset.page_num;
|
|
3725
|
+
delete normalizedPageAsset.artifact_ref;
|
|
3726
|
+
delete normalizedPageAsset.asset_url;
|
|
3727
|
+
delete normalizedPageAsset.content_type;
|
|
3728
|
+
const pageNum = readRecordNumber(pageAsset, "pageNum", "page_num");
|
|
3729
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3730
|
+
const assetUrl = readRecordString(pageAsset, "assetUrl", "asset_url");
|
|
3731
|
+
const contentType = readRecordString(pageAsset, "contentType", "content_type");
|
|
3738
3732
|
return {
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
sectionPath: chunk.sectionPath,
|
|
3745
|
-
sourceChunkPath: chunk.sourceChunkPath,
|
|
3746
|
-
filePath: chunk.filePath,
|
|
3747
|
-
sortOrder: chunk.position,
|
|
3748
|
-
metadata: cloneMetadata(chunk.metadata),
|
|
3749
|
-
assetUrl: chunk.assetUrl
|
|
3733
|
+
...normalizedPageAsset,
|
|
3734
|
+
...pageNum === void 0 ? {} : { pageNum },
|
|
3735
|
+
...artifactRef === void 0 ? {} : { artifactRef },
|
|
3736
|
+
...assetUrl === void 0 ? {} : { assetUrl },
|
|
3737
|
+
...contentType === void 0 ? {} : { contentType }
|
|
3750
3738
|
};
|
|
3751
3739
|
}
|
|
3752
|
-
function
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3740
|
+
async function getStoredObjectUrl(params) {
|
|
3741
|
+
if (!params.path) {
|
|
3742
|
+
return void 0;
|
|
3743
|
+
}
|
|
3744
|
+
return await params.storageConfig.storage.getObjectUrl?.({
|
|
3745
|
+
documentId: params.documentId,
|
|
3757
3746
|
revisionKey: params.revisionKey,
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
sourceFileName: params.response.documentId,
|
|
3761
|
-
totalChunks: params.response.pagination.total,
|
|
3762
|
-
typeCounts: countSnapshotPagesTypes(params.chunkPages),
|
|
3763
|
-
chunkPageSize: params.response.pagination.pageSize,
|
|
3764
|
-
chunkPages: Array.from({ length: params.response.pagination.totalPages }, (_, index) => ({
|
|
3765
|
-
page: index + 1,
|
|
3766
|
-
pageSize: params.response.pagination.pageSize,
|
|
3767
|
-
chunkCount: index + 1 === params.response.pagination.totalPages ? params.response.pagination.total - params.response.pagination.pageSize * (params.response.pagination.totalPages - 1) : params.response.pagination.pageSize,
|
|
3768
|
-
key: `parsed/chunks/page-${index + 1}.json`
|
|
3769
|
-
})),
|
|
3770
|
-
assetUrlsByFilePath: {},
|
|
3771
|
-
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3772
|
-
};
|
|
3773
|
-
}
|
|
3774
|
-
function countSnapshotPagesTypes(pages) {
|
|
3775
|
-
return pages.flatMap((page) => page.chunks).reduce(
|
|
3776
|
-
(counts, chunk) => {
|
|
3777
|
-
const chunkType = chunk.chunkType;
|
|
3778
|
-
counts[chunkType] += 1;
|
|
3779
|
-
return counts;
|
|
3780
|
-
},
|
|
3781
|
-
{ text: 0, image: 0, table: 0, page: 0 }
|
|
3782
|
-
);
|
|
3747
|
+
path: params.path
|
|
3748
|
+
}) ?? void 0;
|
|
3783
3749
|
}
|
|
3784
3750
|
function countRemoteChunkTypes(chunks) {
|
|
3785
3751
|
return chunks.reduce(
|
|
@@ -3857,22 +3823,10 @@ function isOptionalNonNegativeInteger(value) {
|
|
|
3857
3823
|
function cloneMetadata(metadata) {
|
|
3858
3824
|
return { ...metadata };
|
|
3859
3825
|
}
|
|
3860
|
-
function stringifyFlatMetadata(metadata) {
|
|
3861
|
-
const entries = Object.entries(metadata).flatMap(([key, value]) => {
|
|
3862
|
-
if (typeof value === "string") {
|
|
3863
|
-
return [[key, value]];
|
|
3864
|
-
}
|
|
3865
|
-
if (typeof value === "number" || typeof value === "boolean") {
|
|
3866
|
-
return [[key, String(value)]];
|
|
3867
|
-
}
|
|
3868
|
-
return [];
|
|
3869
|
-
});
|
|
3870
|
-
return Object.fromEntries(entries);
|
|
3871
|
-
}
|
|
3872
3826
|
function toUnknownArray(value) {
|
|
3873
3827
|
return Array.isArray(value) ? value : null;
|
|
3874
3828
|
}
|
|
3875
|
-
function
|
|
3829
|
+
function inferContentTypeFromPath2(filePath) {
|
|
3876
3830
|
const extension = filePath.split(".").at(-1)?.toLowerCase();
|
|
3877
3831
|
if (extension === "png") return "image/png";
|
|
3878
3832
|
if (extension === "jpg" || extension === "jpeg") return "image/jpeg";
|
|
@@ -3882,6 +3836,9 @@ function inferContentTypeFromPath(filePath) {
|
|
|
3882
3836
|
function isRecord2(value) {
|
|
3883
3837
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3884
3838
|
}
|
|
3839
|
+
function isDocumentChunkArray(value) {
|
|
3840
|
+
return Array.isArray(value) && value.every(isRecord2);
|
|
3841
|
+
}
|
|
3885
3842
|
function indexChunks(result) {
|
|
3886
3843
|
return result.chunks.map((chunk, index) => {
|
|
3887
3844
|
const filePath = getChunkFilePath2(chunk);
|
|
@@ -4327,51 +4284,59 @@ var Knowhere = class {
|
|
|
4327
4284
|
var import_crypto3 = require("crypto");
|
|
4328
4285
|
var import_fs4 = require("fs");
|
|
4329
4286
|
var import_path4 = __toESM(require("path"));
|
|
4287
|
+
var syncProgressPath = ".knowhere-sdk/sync-progress.json";
|
|
4330
4288
|
var DiskParsedDocumentStorage = class {
|
|
4331
4289
|
rootDirectory;
|
|
4332
4290
|
constructor(rootDirectory) {
|
|
4333
4291
|
this.rootDirectory = rootDirectory;
|
|
4334
4292
|
}
|
|
4335
|
-
async
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
|
|
4349
|
-
|
|
4350
|
-
|
|
4351
|
-
|
|
4352
|
-
|
|
4353
|
-
|
|
4354
|
-
params.page
|
|
4355
|
-
);
|
|
4293
|
+
async readObject(params) {
|
|
4294
|
+
const objectPath = this.getObjectPath(params);
|
|
4295
|
+
try {
|
|
4296
|
+
const body = await import_fs4.promises.readFile(objectPath);
|
|
4297
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4298
|
+
return {
|
|
4299
|
+
...params,
|
|
4300
|
+
body,
|
|
4301
|
+
contentType: metadata?.contentType,
|
|
4302
|
+
contentLength: body.byteLength,
|
|
4303
|
+
metadata: metadata?.metadata,
|
|
4304
|
+
url: toFileUrl(objectPath)
|
|
4305
|
+
};
|
|
4306
|
+
} catch (error) {
|
|
4307
|
+
if (isMissingFileError3(error)) {
|
|
4308
|
+
return null;
|
|
4309
|
+
}
|
|
4310
|
+
throw error;
|
|
4311
|
+
}
|
|
4356
4312
|
}
|
|
4357
|
-
async
|
|
4358
|
-
const
|
|
4359
|
-
await import_fs4.promises.mkdir(import_path4.default.dirname(
|
|
4360
|
-
await import_fs4.promises.writeFile(
|
|
4361
|
-
await this.
|
|
4313
|
+
async writeObject(params) {
|
|
4314
|
+
const objectPath = this.getObjectPath(params);
|
|
4315
|
+
await import_fs4.promises.mkdir(import_path4.default.dirname(objectPath), { recursive: true });
|
|
4316
|
+
await import_fs4.promises.writeFile(objectPath, params.body);
|
|
4317
|
+
await this.writeObjectMetadata(objectPath, {
|
|
4362
4318
|
contentType: params.contentType,
|
|
4363
|
-
metadata: params.metadata
|
|
4319
|
+
metadata: params.metadata
|
|
4364
4320
|
});
|
|
4365
4321
|
return {
|
|
4366
|
-
|
|
4367
|
-
|
|
4322
|
+
documentId: params.documentId,
|
|
4323
|
+
revisionKey: params.revisionKey,
|
|
4324
|
+
path: params.path,
|
|
4325
|
+
url: toFileUrl(objectPath)
|
|
4368
4326
|
};
|
|
4369
4327
|
}
|
|
4370
|
-
async
|
|
4371
|
-
const
|
|
4328
|
+
async headObject(params) {
|
|
4329
|
+
const objectPath = this.getObjectPath(params);
|
|
4372
4330
|
try {
|
|
4373
|
-
await import_fs4.promises.
|
|
4374
|
-
|
|
4331
|
+
const stat = await import_fs4.promises.stat(objectPath);
|
|
4332
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4333
|
+
return {
|
|
4334
|
+
...params,
|
|
4335
|
+
contentType: metadata?.contentType,
|
|
4336
|
+
contentLength: stat.size,
|
|
4337
|
+
metadata: metadata?.metadata,
|
|
4338
|
+
url: toFileUrl(objectPath)
|
|
4339
|
+
};
|
|
4375
4340
|
} catch (error) {
|
|
4376
4341
|
if (isMissingFileError3(error)) {
|
|
4377
4342
|
return null;
|
|
@@ -4379,53 +4344,54 @@ var DiskParsedDocumentStorage = class {
|
|
|
4379
4344
|
throw error;
|
|
4380
4345
|
}
|
|
4381
4346
|
}
|
|
4382
|
-
async
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
);
|
|
4386
|
-
}
|
|
4387
|
-
async writeSyncProgress(params) {
|
|
4388
|
-
await this.writeJson(this.getProgressPath(params.documentId, params.revisionKey), params);
|
|
4347
|
+
async getObjectUrl(params) {
|
|
4348
|
+
const head = await this.headObject(params);
|
|
4349
|
+
return head?.url ?? null;
|
|
4389
4350
|
}
|
|
4390
|
-
|
|
4391
|
-
|
|
4392
|
-
|
|
4393
|
-
|
|
4394
|
-
|
|
4395
|
-
);
|
|
4351
|
+
async deletePrefix(params) {
|
|
4352
|
+
await import_fs4.promises.rm(this.getRevisionDirectory(params.documentId, params.revisionKey), {
|
|
4353
|
+
recursive: true,
|
|
4354
|
+
force: true
|
|
4355
|
+
});
|
|
4396
4356
|
}
|
|
4397
|
-
|
|
4398
|
-
return
|
|
4399
|
-
|
|
4400
|
-
|
|
4401
|
-
|
|
4402
|
-
);
|
|
4357
|
+
async readSyncProgress(params) {
|
|
4358
|
+
return this.readOptionalJson({
|
|
4359
|
+
...params,
|
|
4360
|
+
path: syncProgressPath
|
|
4361
|
+
});
|
|
4403
4362
|
}
|
|
4404
|
-
|
|
4405
|
-
|
|
4363
|
+
async writeSyncProgress(params) {
|
|
4364
|
+
await this.writeObject({
|
|
4365
|
+
documentId: params.documentId,
|
|
4366
|
+
revisionKey: params.revisionKey,
|
|
4367
|
+
path: syncProgressPath,
|
|
4368
|
+
body: Buffer.from(JSON.stringify(params, null, 2), "utf8"),
|
|
4369
|
+
contentType: "application/json; charset=utf-8"
|
|
4370
|
+
});
|
|
4406
4371
|
}
|
|
4407
|
-
|
|
4408
|
-
const
|
|
4409
|
-
const
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
normalizedSourcePath
|
|
4413
|
-
);
|
|
4414
|
-
const assetsDirectory = import_path4.default.resolve(
|
|
4415
|
-
this.getRevisionDirectory(documentId, revisionKey),
|
|
4416
|
-
"assets"
|
|
4417
|
-
);
|
|
4418
|
-
if (!isPathInsideDirectory2(assetPath, assetsDirectory)) {
|
|
4419
|
-
throw new Error(`Parsed asset path resolves outside storage: ${sourcePath}`);
|
|
4372
|
+
getObjectPath(params) {
|
|
4373
|
+
const revisionDirectory = this.getRevisionDirectory(params.documentId, params.revisionKey);
|
|
4374
|
+
const objectPath = import_path4.default.resolve(revisionDirectory, normalizeRelativeStoragePath(params.path));
|
|
4375
|
+
if (!isPathInsideDirectory2(objectPath, revisionDirectory)) {
|
|
4376
|
+
throw new Error(`Parsed document object path resolves outside storage: ${params.path}`);
|
|
4420
4377
|
}
|
|
4421
|
-
return
|
|
4378
|
+
return objectPath;
|
|
4422
4379
|
}
|
|
4423
4380
|
getRevisionDirectory(documentId, revisionKey) {
|
|
4424
4381
|
return import_path4.default.join(this.rootDirectory, hashPathPart(documentId), hashPathPart(revisionKey));
|
|
4425
4382
|
}
|
|
4426
|
-
async readOptionalJson(
|
|
4383
|
+
async readOptionalJson(params) {
|
|
4384
|
+
const object = await this.readObject(params);
|
|
4385
|
+
if (!object) {
|
|
4386
|
+
return null;
|
|
4387
|
+
}
|
|
4388
|
+
return JSON.parse(Buffer.from(object.body).toString("utf8"));
|
|
4389
|
+
}
|
|
4390
|
+
async readObjectMetadata(filePath) {
|
|
4427
4391
|
try {
|
|
4428
|
-
return JSON.parse(
|
|
4392
|
+
return JSON.parse(
|
|
4393
|
+
await import_fs4.promises.readFile(getMetadataPath(filePath), "utf8")
|
|
4394
|
+
);
|
|
4429
4395
|
} catch (error) {
|
|
4430
4396
|
if (isMissingFileError3(error)) {
|
|
4431
4397
|
return null;
|
|
@@ -4433,16 +4399,22 @@ var DiskParsedDocumentStorage = class {
|
|
|
4433
4399
|
throw error;
|
|
4434
4400
|
}
|
|
4435
4401
|
}
|
|
4436
|
-
async
|
|
4437
|
-
await import_fs4.promises.
|
|
4438
|
-
await import_fs4.promises.writeFile(filePath, JSON.stringify(value, null, 2), {
|
|
4402
|
+
async writeObjectMetadata(filePath, metadata) {
|
|
4403
|
+
await import_fs4.promises.writeFile(getMetadataPath(filePath), JSON.stringify(metadata, null, 2), {
|
|
4439
4404
|
encoding: "utf8",
|
|
4440
4405
|
flag: "w"
|
|
4441
4406
|
});
|
|
4442
4407
|
}
|
|
4443
4408
|
};
|
|
4409
|
+
function getMetadataPath(filePath) {
|
|
4410
|
+
return `${filePath}.metadata.json`;
|
|
4411
|
+
}
|
|
4444
4412
|
function hashPathPart(value) {
|
|
4445
|
-
|
|
4413
|
+
const normalized = value.trim();
|
|
4414
|
+
if (normalized.length === 0) {
|
|
4415
|
+
throw new Error("Parsed document storage path part must be a non-empty value.");
|
|
4416
|
+
}
|
|
4417
|
+
return (0, import_crypto3.createHash)("sha256").update(normalized).digest("hex").slice(0, 24);
|
|
4446
4418
|
}
|
|
4447
4419
|
function normalizeRelativeStoragePath(value) {
|
|
4448
4420
|
const normalized = value.replaceAll("\\", "/").replace(/^\.\/+/, "");
|