@ontos-ai/knowhere-sdk 2.1.1 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -7
- package/dist/index.d.mts +219 -318
- package/dist/index.d.ts +219 -318
- package/dist/index.js +700 -730
- package/dist/index.mjs +700 -730
- 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,80 @@ 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 = await parsedStorageConfig.storage.readObject({
|
|
3040
|
+
documentId,
|
|
3041
|
+
revisionKey,
|
|
3042
|
+
path: "manifest.json"
|
|
3043
|
+
});
|
|
3044
|
+
const chunksObject = await parsedStorageConfig.storage.readObject({
|
|
3045
|
+
documentId,
|
|
3046
|
+
revisionKey,
|
|
3047
|
+
path: "chunks.json"
|
|
3048
|
+
});
|
|
3049
|
+
if (!manifestObject || !chunksObject) {
|
|
3134
3050
|
return null;
|
|
3135
3051
|
}
|
|
3136
|
-
const
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3144
|
-
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
|
|
3150
|
-
|
|
3151
|
-
|
|
3152
|
-
|
|
3153
|
-
|
|
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;
|
|
3052
|
+
const manifest = readJsonObject(manifestObject);
|
|
3053
|
+
const chunks = parseStoredResultChunks({
|
|
3054
|
+
payload: readJsonObject(chunksObject),
|
|
3055
|
+
sourceFileName: manifest.sourceFileName
|
|
3056
|
+
});
|
|
3057
|
+
const docNavObject = await parsedStorageConfig.storage.readObject({
|
|
3058
|
+
documentId,
|
|
3059
|
+
revisionKey,
|
|
3060
|
+
path: "doc_nav.json"
|
|
3061
|
+
});
|
|
3062
|
+
const docNav = docNavObject ? readJsonObject(docNavObject) : void 0;
|
|
3063
|
+
return {
|
|
3064
|
+
commit,
|
|
3065
|
+
manifest,
|
|
3066
|
+
chunks,
|
|
3067
|
+
docNav: docNav?.sections ? { sections: docNav.sections } : void 0,
|
|
3068
|
+
typeCounts: countIndexedTypes(chunks)
|
|
3069
|
+
};
|
|
3181
3070
|
}
|
|
3182
3071
|
scheduleParsedStorageSync(documentId, revisionKey) {
|
|
3183
3072
|
const parsedStorageConfig = this.parsedStorageConfig;
|
|
@@ -3197,7 +3086,6 @@ var Knowledge = class _Knowledge {
|
|
|
3197
3086
|
documentId,
|
|
3198
3087
|
revisionKey,
|
|
3199
3088
|
nextChunkPage: 1,
|
|
3200
|
-
nextAssetIndex: 0,
|
|
3201
3089
|
status: "failed",
|
|
3202
3090
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3203
3091
|
error: error instanceof Error ? error.message : String(error)
|
|
@@ -3207,28 +3095,63 @@ var Knowledge = class _Knowledge {
|
|
|
3207
3095
|
void Promise.resolve(scheduler.schedule(task)).catch(() => void 0);
|
|
3208
3096
|
}
|
|
3209
3097
|
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,
|
|
3098
|
+
const firstPage = await this.client.documents.listChunks(params.documentId, {
|
|
3099
|
+
page: 1,
|
|
3100
|
+
pageSize: 1,
|
|
3219
3101
|
includeAssetUrls: true
|
|
3220
3102
|
});
|
|
3221
|
-
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(
|
|
3222
|
-
if (params.revisionKey && getRemoteRevisionKey(
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
includeAssetUrls: true
|
|
3103
|
+
const revisionKey = params.revisionKey ?? getRemoteRevisionKey(firstPage);
|
|
3104
|
+
if (params.revisionKey && getRemoteRevisionKey(firstPage) !== params.revisionKey) {
|
|
3105
|
+
return this.syncRemoteDocumentToParsedStorage({
|
|
3106
|
+
documentId: params.documentId,
|
|
3107
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3227
3108
|
});
|
|
3228
|
-
nextPage = 1;
|
|
3229
3109
|
}
|
|
3110
|
+
if (firstPage.jobId) {
|
|
3111
|
+
try {
|
|
3112
|
+
const loadedResult = await this.client.jobs.load(firstPage.jobId);
|
|
3113
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3114
|
+
result: loadedResult,
|
|
3115
|
+
storage: params.parsedStorageConfig.storage,
|
|
3116
|
+
documentId: params.documentId,
|
|
3117
|
+
revisionKey,
|
|
3118
|
+
source: "resultZip"
|
|
3119
|
+
});
|
|
3120
|
+
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3121
|
+
documentId: params.documentId,
|
|
3122
|
+
revisionKey,
|
|
3123
|
+
status: "completed",
|
|
3124
|
+
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3125
|
+
});
|
|
3126
|
+
return {
|
|
3127
|
+
documentId: synced.documentId,
|
|
3128
|
+
revisionKey: synced.revisionKey,
|
|
3129
|
+
completed: true,
|
|
3130
|
+
commit: synced.commit
|
|
3131
|
+
};
|
|
3132
|
+
} catch {
|
|
3133
|
+
}
|
|
3134
|
+
}
|
|
3135
|
+
return this.syncRemoteDocumentChunksToParsedStorage({
|
|
3136
|
+
documentId: params.documentId,
|
|
3137
|
+
revisionKey,
|
|
3138
|
+
firstPage,
|
|
3139
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3140
|
+
});
|
|
3141
|
+
}
|
|
3142
|
+
async syncRemoteDocumentChunksToParsedStorage(params) {
|
|
3143
|
+
const limits = getParsedStorageLimits(params.parsedStorageConfig.limits);
|
|
3144
|
+
const existingProgress = await params.parsedStorageConfig.storage.readSyncProgress({
|
|
3145
|
+
documentId: params.documentId,
|
|
3146
|
+
revisionKey: params.revisionKey
|
|
3147
|
+
});
|
|
3148
|
+
let nextPage = existingProgress?.status === "running" ? existingProgress.nextChunkPage ?? 1 : 1;
|
|
3149
|
+
let response = nextPage === 1 && params.firstPage.pagination.pageSize === limits.remotePageSize ? params.firstPage : await this.client.documents.listChunks(params.documentId, {
|
|
3150
|
+
page: nextPage,
|
|
3151
|
+
pageSize: limits.remotePageSize,
|
|
3152
|
+
includeAssetUrls: true
|
|
3153
|
+
});
|
|
3230
3154
|
const totalPages = response.pagination.totalPages;
|
|
3231
|
-
const chunkPages = [];
|
|
3232
3155
|
let syncedPages = 0;
|
|
3233
3156
|
const startedAt = Date.now();
|
|
3234
3157
|
while (nextPage <= totalPages) {
|
|
@@ -3239,65 +3162,88 @@ var Knowledge = class _Knowledge {
|
|
|
3239
3162
|
includeAssetUrls: true
|
|
3240
3163
|
});
|
|
3241
3164
|
}
|
|
3242
|
-
|
|
3243
|
-
documentId: params.documentId,
|
|
3244
|
-
revisionKey,
|
|
3245
|
-
chunks: response.chunks.map(toRemoteReadChunk)
|
|
3246
|
-
});
|
|
3247
|
-
const page = toSnapshotChunkPageFromReadChunks({
|
|
3248
|
-
response,
|
|
3249
|
-
revisionKey,
|
|
3250
|
-
chunks: readChunks
|
|
3251
|
-
});
|
|
3252
|
-
await params.parsedStorageConfig.storage.writeChunkPage({
|
|
3165
|
+
await params.parsedStorageConfig.storage.writeObject({
|
|
3253
3166
|
documentId: params.documentId,
|
|
3254
|
-
revisionKey,
|
|
3255
|
-
page
|
|
3167
|
+
revisionKey: params.revisionKey,
|
|
3168
|
+
path: getRemoteReconstructionPagePath(response.pagination.page),
|
|
3169
|
+
body: Buffer.from(JSON.stringify({ chunks: response.chunks }), "utf8"),
|
|
3170
|
+
contentType: "application/json; charset=utf-8"
|
|
3256
3171
|
});
|
|
3257
|
-
chunkPages.push(page);
|
|
3258
3172
|
nextPage += 1;
|
|
3259
3173
|
syncedPages += 1;
|
|
3260
3174
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3261
3175
|
documentId: params.documentId,
|
|
3262
|
-
revisionKey,
|
|
3176
|
+
revisionKey: params.revisionKey,
|
|
3263
3177
|
nextChunkPage: nextPage,
|
|
3264
|
-
nextAssetIndex: 0,
|
|
3265
3178
|
status: "running",
|
|
3266
3179
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3267
3180
|
});
|
|
3268
3181
|
if (syncedPages >= limits.maxPagesPerSync || Date.now() - startedAt >= limits.syncDeadlineMs) {
|
|
3269
3182
|
return {
|
|
3270
3183
|
documentId: params.documentId,
|
|
3271
|
-
revisionKey,
|
|
3184
|
+
revisionKey: params.revisionKey,
|
|
3272
3185
|
completed: false
|
|
3273
3186
|
};
|
|
3274
3187
|
}
|
|
3275
3188
|
}
|
|
3276
|
-
const
|
|
3277
|
-
|
|
3278
|
-
revisionKey,
|
|
3279
|
-
|
|
3189
|
+
const chunks = await this.readRemoteReconstructionChunks({
|
|
3190
|
+
documentId: params.documentId,
|
|
3191
|
+
revisionKey: params.revisionKey,
|
|
3192
|
+
totalPages,
|
|
3193
|
+
parsedStorageConfig: params.parsedStorageConfig
|
|
3280
3194
|
});
|
|
3281
|
-
|
|
3195
|
+
if (!chunks) {
|
|
3196
|
+
return {
|
|
3197
|
+
documentId: params.documentId,
|
|
3198
|
+
revisionKey: params.revisionKey,
|
|
3199
|
+
completed: false
|
|
3200
|
+
};
|
|
3201
|
+
}
|
|
3202
|
+
const synced = await syncParseResultToParsedDocumentStorage({
|
|
3203
|
+
result: createMinimalParseResultFromRemoteChunks({
|
|
3204
|
+
documentId: params.documentId,
|
|
3205
|
+
revisionKey: params.revisionKey,
|
|
3206
|
+
response,
|
|
3207
|
+
chunks
|
|
3208
|
+
}),
|
|
3209
|
+
storage: params.parsedStorageConfig.storage,
|
|
3282
3210
|
documentId: params.documentId,
|
|
3283
|
-
revisionKey,
|
|
3284
|
-
|
|
3211
|
+
revisionKey: params.revisionKey,
|
|
3212
|
+
source: "remoteReconstruction"
|
|
3285
3213
|
});
|
|
3286
3214
|
await params.parsedStorageConfig.storage.writeSyncProgress({
|
|
3287
3215
|
documentId: params.documentId,
|
|
3288
|
-
revisionKey,
|
|
3216
|
+
revisionKey: params.revisionKey,
|
|
3289
3217
|
nextChunkPage: totalPages + 1,
|
|
3290
|
-
nextAssetIndex: 0,
|
|
3291
3218
|
status: "completed",
|
|
3292
3219
|
updatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
3293
3220
|
});
|
|
3294
3221
|
return {
|
|
3295
3222
|
documentId: params.documentId,
|
|
3296
|
-
revisionKey,
|
|
3223
|
+
revisionKey: params.revisionKey,
|
|
3297
3224
|
completed: true,
|
|
3298
|
-
|
|
3225
|
+
commit: synced.commit
|
|
3299
3226
|
};
|
|
3300
3227
|
}
|
|
3228
|
+
async readRemoteReconstructionChunks(params) {
|
|
3229
|
+
const chunks = [];
|
|
3230
|
+
for (let page = 1; page <= params.totalPages; page += 1) {
|
|
3231
|
+
const object = await params.parsedStorageConfig.storage.readObject({
|
|
3232
|
+
documentId: params.documentId,
|
|
3233
|
+
revisionKey: params.revisionKey,
|
|
3234
|
+
path: getRemoteReconstructionPagePath(page)
|
|
3235
|
+
});
|
|
3236
|
+
if (!object) {
|
|
3237
|
+
return null;
|
|
3238
|
+
}
|
|
3239
|
+
const payload = readJsonObject(object);
|
|
3240
|
+
if (!isDocumentChunkArray(payload.chunks)) {
|
|
3241
|
+
return null;
|
|
3242
|
+
}
|
|
3243
|
+
chunks.push(...payload.chunks);
|
|
3244
|
+
}
|
|
3245
|
+
return chunks;
|
|
3246
|
+
}
|
|
3301
3247
|
requireParsedStorageConfig() {
|
|
3302
3248
|
if (!this.parsedStorageConfig) {
|
|
3303
3249
|
throw new ValidationError("parsed document storage is not configured");
|
|
@@ -3311,7 +3257,8 @@ var Knowledge = class _Knowledge {
|
|
|
3311
3257
|
async getPublishedDocumentJobId(documentId) {
|
|
3312
3258
|
const response = await this.client.documents.listChunks(documentId, {
|
|
3313
3259
|
page: 1,
|
|
3314
|
-
pageSize: 1
|
|
3260
|
+
pageSize: 1,
|
|
3261
|
+
includeAssetUrls: true
|
|
3315
3262
|
});
|
|
3316
3263
|
if (!response.jobId) {
|
|
3317
3264
|
throw new Error(
|
|
@@ -3344,14 +3291,12 @@ var defaultParsedStorageScheduler = {
|
|
|
3344
3291
|
};
|
|
3345
3292
|
function getParsedStorageLimits(limits) {
|
|
3346
3293
|
return {
|
|
3347
|
-
chunkPageSize: clampLimit(limits?.chunkPageSize, DEFAULT_REMOTE_SCAN_PAGE_SIZE, MAX_PAGE_SIZE),
|
|
3348
3294
|
remotePageSize: clampLimit(
|
|
3349
3295
|
limits?.remotePageSize,
|
|
3350
3296
|
DEFAULT_REMOTE_SCAN_PAGE_SIZE,
|
|
3351
3297
|
MAX_PAGE_SIZE
|
|
3352
3298
|
),
|
|
3353
3299
|
maxPagesPerSync: clampLimit(limits?.maxPagesPerSync, DEFAULT_MAX_SYNC_PAGES, 1e3),
|
|
3354
|
-
maxAssetsPerSync: clampLimit(limits?.maxAssetsPerSync, DEFAULT_MAX_SYNC_ASSETS, 1e3),
|
|
3355
3300
|
syncDeadlineMs: clampLimit(limits?.syncDeadlineMs, DEFAULT_SYNC_DEADLINE_MS, 6e4),
|
|
3356
3301
|
grepMaxPages: clampLimit(limits?.grepMaxPages, DEFAULT_GREP_MAX_PAGES, 1e3),
|
|
3357
3302
|
grepDeadlineMs: clampLimit(limits?.grepDeadlineMs, DEFAULT_GREP_DEADLINE_MS, 6e4),
|
|
@@ -3360,13 +3305,13 @@ function getParsedStorageLimits(limits) {
|
|
|
3360
3305
|
};
|
|
3361
3306
|
}
|
|
3362
3307
|
function validateReadParams(params) {
|
|
3363
|
-
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0
|
|
3308
|
+
const usesPagedDisplay = params.page !== void 0 || params.pageSize !== void 0;
|
|
3364
3309
|
if (!usesPagedDisplay) {
|
|
3365
3310
|
return;
|
|
3366
3311
|
}
|
|
3367
3312
|
if (params.sectionPath !== void 0 || params.startChunk !== void 0 || params.endChunk !== void 0 || params.chunkId !== void 0) {
|
|
3368
3313
|
throw new ValidationError(
|
|
3369
|
-
"page
|
|
3314
|
+
"page and pageSize cannot be combined with sectionPath, startChunk, endChunk, or chunkId"
|
|
3370
3315
|
);
|
|
3371
3316
|
}
|
|
3372
3317
|
}
|
|
@@ -3379,9 +3324,6 @@ function getReadPageParams(params) {
|
|
|
3379
3324
|
pageSize: clampLimit(params.pageSize ?? params.limit, DEFAULT_PAGE_SIZE, MAX_PAGE_SIZE)
|
|
3380
3325
|
};
|
|
3381
3326
|
}
|
|
3382
|
-
function shouldRequestRemoteAssetUrls(assetUrlPolicy, parsedStorageConfig) {
|
|
3383
|
-
return assetUrlPolicy === "durable" && parsedStorageConfig !== void 0;
|
|
3384
|
-
}
|
|
3385
3327
|
function getRemoteRevisionKey(response) {
|
|
3386
3328
|
const revisionKey = response.jobResultId ?? response.jobId;
|
|
3387
3329
|
if (!revisionKey) {
|
|
@@ -3391,6 +3333,9 @@ function getRemoteRevisionKey(response) {
|
|
|
3391
3333
|
}
|
|
3392
3334
|
return revisionKey;
|
|
3393
3335
|
}
|
|
3336
|
+
function getRemoteReconstructionPagePath(page) {
|
|
3337
|
+
return `${remoteReconstructionPageDirectory}/page-${page}.json`;
|
|
3338
|
+
}
|
|
3394
3339
|
function createRemoteKnowledgeDocument(params) {
|
|
3395
3340
|
return {
|
|
3396
3341
|
localDocumentId: params.documentId,
|
|
@@ -3405,23 +3350,103 @@ function createRemoteKnowledgeDocument(params) {
|
|
|
3405
3350
|
updatedAt: /* @__PURE__ */ new Date(0)
|
|
3406
3351
|
};
|
|
3407
3352
|
}
|
|
3353
|
+
function createMinimalParseResultFromRemoteChunks(params) {
|
|
3354
|
+
const chunks = params.chunks.map(toMinimalChunkFromRemoteChunk);
|
|
3355
|
+
const typeCounts = countRemoteChunkTypes(params.chunks);
|
|
3356
|
+
return {
|
|
3357
|
+
manifest: {
|
|
3358
|
+
version: "2.0",
|
|
3359
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3360
|
+
sourceFileName: params.documentId,
|
|
3361
|
+
statistics: {
|
|
3362
|
+
totalChunks: chunks.length,
|
|
3363
|
+
textChunks: typeCounts.text,
|
|
3364
|
+
imageChunks: typeCounts.image,
|
|
3365
|
+
tableChunks: typeCounts.table,
|
|
3366
|
+
pageChunks: typeCounts.page
|
|
3367
|
+
}
|
|
3368
|
+
},
|
|
3369
|
+
chunks,
|
|
3370
|
+
rawZip: Buffer.from(""),
|
|
3371
|
+
namespace: params.response.namespace,
|
|
3372
|
+
documentId: params.documentId,
|
|
3373
|
+
textChunks: chunks.filter(
|
|
3374
|
+
(chunk) => chunk.type === "text"
|
|
3375
|
+
),
|
|
3376
|
+
imageChunks: chunks.filter(
|
|
3377
|
+
(chunk) => chunk.type === "image"
|
|
3378
|
+
),
|
|
3379
|
+
tableChunks: chunks.filter(
|
|
3380
|
+
(chunk) => chunk.type === "table"
|
|
3381
|
+
),
|
|
3382
|
+
pageChunks: chunks.filter(
|
|
3383
|
+
(chunk) => chunk.type === "page"
|
|
3384
|
+
),
|
|
3385
|
+
jobId: params.response.jobId ?? params.revisionKey,
|
|
3386
|
+
statistics: {
|
|
3387
|
+
totalChunks: chunks.length,
|
|
3388
|
+
textChunks: typeCounts.text,
|
|
3389
|
+
imageChunks: typeCounts.image,
|
|
3390
|
+
tableChunks: typeCounts.table,
|
|
3391
|
+
pageChunks: typeCounts.page
|
|
3392
|
+
},
|
|
3393
|
+
getChunk: (chunkId) => chunks.find((chunk) => chunk.chunkId === chunkId),
|
|
3394
|
+
save: () => Promise.reject(new Error("Minimal remote reconstruction cannot be saved directly."))
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
function toMinimalChunkFromRemoteChunk(chunk) {
|
|
3398
|
+
const baseChunk = {
|
|
3399
|
+
chunkId: chunk.chunkId,
|
|
3400
|
+
contentSource: chunk.contentSource ?? void 0,
|
|
3401
|
+
content: chunk.content ?? "",
|
|
3402
|
+
path: chunk.sourceChunkPath ?? chunk.sectionPath ?? "",
|
|
3403
|
+
metadata: cloneMetadata(chunk.metadata)
|
|
3404
|
+
};
|
|
3405
|
+
if (chunk.chunkType === "image") {
|
|
3406
|
+
return {
|
|
3407
|
+
...baseChunk,
|
|
3408
|
+
type: "image",
|
|
3409
|
+
filePath: chunk.filePath ?? "",
|
|
3410
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3411
|
+
data: Buffer.alloc(0),
|
|
3412
|
+
format: inferContentTypeFromPath2(chunk.filePath ?? "").replace("image/", ""),
|
|
3413
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3414
|
+
};
|
|
3415
|
+
}
|
|
3416
|
+
if (chunk.chunkType === "table") {
|
|
3417
|
+
return {
|
|
3418
|
+
...baseChunk,
|
|
3419
|
+
type: "table",
|
|
3420
|
+
filePath: chunk.filePath ?? "",
|
|
3421
|
+
assetUrl: chunk.assetUrl ?? void 0,
|
|
3422
|
+
html: chunk.content ?? "",
|
|
3423
|
+
save: () => Promise.resolve(chunk.filePath ?? "")
|
|
3424
|
+
};
|
|
3425
|
+
}
|
|
3426
|
+
if (chunk.chunkType === "page") {
|
|
3427
|
+
return {
|
|
3428
|
+
...baseChunk,
|
|
3429
|
+
type: "page"
|
|
3430
|
+
};
|
|
3431
|
+
}
|
|
3432
|
+
return {
|
|
3433
|
+
...baseChunk,
|
|
3434
|
+
type: "text"
|
|
3435
|
+
};
|
|
3436
|
+
}
|
|
3408
3437
|
function createStoredKnowledgeDocument(params) {
|
|
3409
3438
|
return {
|
|
3410
3439
|
localDocumentId: params.documentId,
|
|
3411
|
-
jobId: params.manifest.jobId || params.revisionKey,
|
|
3412
|
-
documentId: params.
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
typeCounts: params.typeCounts,
|
|
3440
|
+
jobId: params.storedResult.manifest.jobId || params.revisionKey,
|
|
3441
|
+
documentId: params.documentId,
|
|
3442
|
+
sourceFileName: params.storedResult.manifest.sourceFileName,
|
|
3443
|
+
chunkCount: params.storedResult.chunks.length,
|
|
3444
|
+
typeCounts: params.storedResult.typeCounts,
|
|
3417
3445
|
resultDirectoryPath: `parsed-storage:${params.documentId}`,
|
|
3418
|
-
createdAt: new Date(params.
|
|
3419
|
-
updatedAt: new Date(params.
|
|
3446
|
+
createdAt: new Date(params.storedResult.commit.committedAt),
|
|
3447
|
+
updatedAt: new Date(params.storedResult.commit.committedAt)
|
|
3420
3448
|
};
|
|
3421
3449
|
}
|
|
3422
|
-
function isFreshManifest(manifest, revisionKey) {
|
|
3423
|
-
return (manifest.revisionKey ?? manifest.jobId) === revisionKey;
|
|
3424
|
-
}
|
|
3425
3450
|
function toRemoteReadChunk(chunk) {
|
|
3426
3451
|
const metadata = cloneMetadata(chunk.metadata);
|
|
3427
3452
|
return {
|
|
@@ -3450,22 +3475,60 @@ function toIndexedRemoteChunk(chunk) {
|
|
|
3450
3475
|
const readChunk = toRemoteReadChunk(chunk);
|
|
3451
3476
|
return toIndexedReadChunk(readChunk);
|
|
3452
3477
|
}
|
|
3453
|
-
function
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
chunkType
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3478
|
+
function parseStoredResultChunks(params) {
|
|
3479
|
+
const rawChunks = extractStoredChunkRecords(params.payload);
|
|
3480
|
+
return rawChunks.map((record, index) => {
|
|
3481
|
+
const metadata = readRecordMetadata(record);
|
|
3482
|
+
const chunkType = readRecordString(record, "type", "chunkType", "chunk_type");
|
|
3483
|
+
const content = readRecordString(record, "content") ?? "";
|
|
3484
|
+
const sourceChunkPath = readRecordString(record, "path", "sourceChunkPath", "source_chunk_path") ?? "";
|
|
3485
|
+
const chunk = {
|
|
3486
|
+
position: index + 1,
|
|
3487
|
+
chunkId: readRecordString(record, "chunkId", "chunk_id") ?? "",
|
|
3488
|
+
chunkType: isKnowledgeChunkType(chunkType) ? chunkType : "text",
|
|
3489
|
+
contentSource: readRecordString(record, "contentSource", "content_source"),
|
|
3490
|
+
content,
|
|
3491
|
+
readableContent: chunkType === "page" && typeof metadata.summary === "string" && metadata.summary.trim().length > 0 ? metadata.summary : content,
|
|
3492
|
+
sectionPath: normalizeSectionPath(sourceChunkPath, params.sourceFileName),
|
|
3493
|
+
sourceChunkPath,
|
|
3494
|
+
filePath: readRecordString(record, "filePath", "file_path") ?? (typeof metadata.filePath === "string" ? metadata.filePath : void 0),
|
|
3495
|
+
assetUrl: readRecordString(record, "assetUrl", "asset_url"),
|
|
3496
|
+
pageNumbers: getChunkPageNumbers(metadata),
|
|
3497
|
+
metadata
|
|
3498
|
+
};
|
|
3499
|
+
return toIndexedReadChunk(chunk);
|
|
3467
3500
|
});
|
|
3468
3501
|
}
|
|
3502
|
+
function extractStoredChunkRecords(payload) {
|
|
3503
|
+
if (Array.isArray(payload)) {
|
|
3504
|
+
return payload.filter(isRecord2);
|
|
3505
|
+
}
|
|
3506
|
+
if (isRecord2(payload) && Array.isArray(payload.chunks)) {
|
|
3507
|
+
return payload.chunks.filter(isRecord2);
|
|
3508
|
+
}
|
|
3509
|
+
return [];
|
|
3510
|
+
}
|
|
3511
|
+
function readRecordString(record, ...keys) {
|
|
3512
|
+
for (const key of keys) {
|
|
3513
|
+
const value = record[key];
|
|
3514
|
+
if (typeof value === "string") return value;
|
|
3515
|
+
}
|
|
3516
|
+
return void 0;
|
|
3517
|
+
}
|
|
3518
|
+
function readRecordNumber(record, ...keys) {
|
|
3519
|
+
for (const key of keys) {
|
|
3520
|
+
const value = record[key];
|
|
3521
|
+
if (typeof value === "number") return value;
|
|
3522
|
+
}
|
|
3523
|
+
return void 0;
|
|
3524
|
+
}
|
|
3525
|
+
function readRecordMetadata(record) {
|
|
3526
|
+
const metadata = record.metadata;
|
|
3527
|
+
return isRecord2(metadata) ? keysToCamel(metadata) : {};
|
|
3528
|
+
}
|
|
3529
|
+
function isKnowledgeChunkType(value) {
|
|
3530
|
+
return value === "text" || value === "image" || value === "table" || value === "page";
|
|
3531
|
+
}
|
|
3469
3532
|
function toIndexedReadChunk(chunk) {
|
|
3470
3533
|
return {
|
|
3471
3534
|
source: createSyntheticChunk(chunk),
|
|
@@ -3519,204 +3582,105 @@ function getNextChunkPosition(chunks, selected) {
|
|
|
3519
3582
|
}
|
|
3520
3583
|
return chunks[chunks.indexOf(lastSelected) + 1]?.position;
|
|
3521
3584
|
}
|
|
3522
|
-
function
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
|
|
3527
|
-
|
|
3528
|
-
|
|
3529
|
-
|
|
3530
|
-
|
|
3531
|
-
assetUrl: void 0,
|
|
3532
|
-
metadata: removeAssetUrlsFromMetadata(chunk.metadata)
|
|
3533
|
-
}));
|
|
3585
|
+
async function applyStoredAssetUrlsToReadChunks(params) {
|
|
3586
|
+
return Promise.all(
|
|
3587
|
+
params.chunks.map(
|
|
3588
|
+
(chunk) => applyStoredAssetUrlsToReadChunk({
|
|
3589
|
+
...params,
|
|
3590
|
+
chunk
|
|
3591
|
+
})
|
|
3592
|
+
)
|
|
3593
|
+
);
|
|
3534
3594
|
}
|
|
3535
|
-
async function
|
|
3595
|
+
async function applyStoredAssetUrlsToReadChunk(params) {
|
|
3536
3596
|
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({
|
|
3597
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3553
3598
|
storageConfig: params.storageConfig,
|
|
3554
3599
|
documentId: params.documentId,
|
|
3555
3600
|
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
|
-
}
|
|
3601
|
+
path: params.chunk.filePath
|
|
3565
3602
|
});
|
|
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({
|
|
3603
|
+
const pageAssets = await applyStoredPageAssetUrls({
|
|
3604
|
+
storageConfig: params.storageConfig,
|
|
3604
3605
|
documentId: params.documentId,
|
|
3605
3606
|
revisionKey: params.revisionKey,
|
|
3606
|
-
|
|
3607
|
+
metadata
|
|
3607
3608
|
});
|
|
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}`);
|
|
3609
|
+
if (pageAssets) {
|
|
3610
|
+
metadata.pageAssets = pageAssets;
|
|
3611
|
+
delete metadata.page_assets;
|
|
3634
3612
|
}
|
|
3635
3613
|
return {
|
|
3636
|
-
|
|
3637
|
-
|
|
3614
|
+
...params.chunk,
|
|
3615
|
+
assetUrl: storedAssetUrl ?? params.chunk.assetUrl,
|
|
3616
|
+
metadata
|
|
3638
3617
|
};
|
|
3639
3618
|
}
|
|
3640
|
-
function
|
|
3641
|
-
const
|
|
3642
|
-
const pageAssets = toUnknownArray(cloned.pageAssets);
|
|
3619
|
+
async function applyStoredPageAssetUrls(params) {
|
|
3620
|
+
const pageAssets = getStoredPageAssets(params.metadata);
|
|
3643
3621
|
if (!pageAssets) {
|
|
3644
|
-
return
|
|
3622
|
+
return void 0;
|
|
3645
3623
|
}
|
|
3646
|
-
|
|
3647
|
-
|
|
3624
|
+
return Promise.all(
|
|
3625
|
+
pageAssets.map(async (pageAsset) => {
|
|
3626
|
+
if (!isRecord2(pageAsset)) {
|
|
3627
|
+
return pageAsset;
|
|
3628
|
+
}
|
|
3629
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3630
|
+
if (typeof artifactRef !== "string") {
|
|
3631
|
+
return pageAsset;
|
|
3632
|
+
}
|
|
3633
|
+
const storedAssetUrl = await getStoredObjectUrl({
|
|
3634
|
+
storageConfig: params.storageConfig,
|
|
3635
|
+
documentId: params.documentId,
|
|
3636
|
+
revisionKey: params.revisionKey,
|
|
3637
|
+
path: artifactRef
|
|
3638
|
+
});
|
|
3639
|
+
if (storedAssetUrl) {
|
|
3640
|
+
return {
|
|
3641
|
+
...pageAsset,
|
|
3642
|
+
artifactRef,
|
|
3643
|
+
assetUrl: storedAssetUrl
|
|
3644
|
+
};
|
|
3645
|
+
}
|
|
3648
3646
|
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
|
-
};
|
|
3647
|
+
})
|
|
3648
|
+
);
|
|
3673
3649
|
}
|
|
3674
|
-
function
|
|
3650
|
+
function getStoredPageAssets(metadata) {
|
|
3651
|
+
const pageAssets = toUnknownArray(metadata.pageAssets) ?? toUnknownArray(metadata.page_assets) ?? void 0;
|
|
3652
|
+
return pageAssets?.map(normalizeStoredPageAsset);
|
|
3653
|
+
}
|
|
3654
|
+
function normalizeStoredPageAsset(pageAsset) {
|
|
3655
|
+
if (!isRecord2(pageAsset)) {
|
|
3656
|
+
return pageAsset;
|
|
3657
|
+
}
|
|
3658
|
+
const normalizedPageAsset = { ...pageAsset };
|
|
3659
|
+
delete normalizedPageAsset.page_num;
|
|
3660
|
+
delete normalizedPageAsset.artifact_ref;
|
|
3661
|
+
delete normalizedPageAsset.asset_url;
|
|
3662
|
+
delete normalizedPageAsset.content_type;
|
|
3663
|
+
const pageNum = readRecordNumber(pageAsset, "pageNum", "page_num");
|
|
3664
|
+
const artifactRef = readRecordString(pageAsset, "artifactRef", "artifact_ref");
|
|
3665
|
+
const assetUrl = readRecordString(pageAsset, "assetUrl", "asset_url");
|
|
3666
|
+
const contentType = readRecordString(pageAsset, "contentType", "content_type");
|
|
3675
3667
|
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
|
|
3668
|
+
...normalizedPageAsset,
|
|
3669
|
+
...pageNum === void 0 ? {} : { pageNum },
|
|
3670
|
+
...artifactRef === void 0 ? {} : { artifactRef },
|
|
3671
|
+
...assetUrl === void 0 ? {} : { assetUrl },
|
|
3672
|
+
...contentType === void 0 ? {} : { contentType }
|
|
3687
3673
|
};
|
|
3688
3674
|
}
|
|
3689
|
-
function
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3675
|
+
async function getStoredObjectUrl(params) {
|
|
3676
|
+
if (!params.path) {
|
|
3677
|
+
return void 0;
|
|
3678
|
+
}
|
|
3679
|
+
return await params.storageConfig.storage.getObjectUrl?.({
|
|
3680
|
+
documentId: params.documentId,
|
|
3694
3681
|
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
|
-
);
|
|
3682
|
+
path: params.path
|
|
3683
|
+
}) ?? void 0;
|
|
3720
3684
|
}
|
|
3721
3685
|
function countRemoteChunkTypes(chunks) {
|
|
3722
3686
|
return chunks.reduce(
|
|
@@ -3794,22 +3758,10 @@ function isOptionalNonNegativeInteger(value) {
|
|
|
3794
3758
|
function cloneMetadata(metadata) {
|
|
3795
3759
|
return { ...metadata };
|
|
3796
3760
|
}
|
|
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
3761
|
function toUnknownArray(value) {
|
|
3810
3762
|
return Array.isArray(value) ? value : null;
|
|
3811
3763
|
}
|
|
3812
|
-
function
|
|
3764
|
+
function inferContentTypeFromPath2(filePath) {
|
|
3813
3765
|
const extension = filePath.split(".").at(-1)?.toLowerCase();
|
|
3814
3766
|
if (extension === "png") return "image/png";
|
|
3815
3767
|
if (extension === "jpg" || extension === "jpeg") return "image/jpeg";
|
|
@@ -3819,6 +3771,9 @@ function inferContentTypeFromPath(filePath) {
|
|
|
3819
3771
|
function isRecord2(value) {
|
|
3820
3772
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3821
3773
|
}
|
|
3774
|
+
function isDocumentChunkArray(value) {
|
|
3775
|
+
return Array.isArray(value) && value.every(isRecord2);
|
|
3776
|
+
}
|
|
3822
3777
|
function indexChunks(result) {
|
|
3823
3778
|
return result.chunks.map((chunk, index) => {
|
|
3824
3779
|
const filePath = getChunkFilePath2(chunk);
|
|
@@ -4264,51 +4219,59 @@ var Knowhere = class {
|
|
|
4264
4219
|
import { createHash as createHash3 } from "crypto";
|
|
4265
4220
|
import { promises as fs4 } from "fs";
|
|
4266
4221
|
import path3 from "path";
|
|
4222
|
+
var syncProgressPath = ".knowhere-sdk/sync-progress.json";
|
|
4267
4223
|
var DiskParsedDocumentStorage = class {
|
|
4268
4224
|
rootDirectory;
|
|
4269
4225
|
constructor(rootDirectory) {
|
|
4270
4226
|
this.rootDirectory = rootDirectory;
|
|
4271
4227
|
}
|
|
4272
|
-
async
|
|
4273
|
-
|
|
4274
|
-
|
|
4275
|
-
|
|
4276
|
-
|
|
4277
|
-
|
|
4278
|
-
|
|
4279
|
-
|
|
4280
|
-
|
|
4281
|
-
|
|
4282
|
-
|
|
4283
|
-
|
|
4284
|
-
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4291
|
-
params.page
|
|
4292
|
-
);
|
|
4228
|
+
async readObject(params) {
|
|
4229
|
+
const objectPath = this.getObjectPath(params);
|
|
4230
|
+
try {
|
|
4231
|
+
const body = await fs4.readFile(objectPath);
|
|
4232
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4233
|
+
return {
|
|
4234
|
+
...params,
|
|
4235
|
+
body,
|
|
4236
|
+
contentType: metadata?.contentType,
|
|
4237
|
+
contentLength: body.byteLength,
|
|
4238
|
+
metadata: metadata?.metadata,
|
|
4239
|
+
url: toFileUrl(objectPath)
|
|
4240
|
+
};
|
|
4241
|
+
} catch (error) {
|
|
4242
|
+
if (isMissingFileError3(error)) {
|
|
4243
|
+
return null;
|
|
4244
|
+
}
|
|
4245
|
+
throw error;
|
|
4246
|
+
}
|
|
4293
4247
|
}
|
|
4294
|
-
async
|
|
4295
|
-
const
|
|
4296
|
-
await fs4.mkdir(path3.dirname(
|
|
4297
|
-
await fs4.writeFile(
|
|
4298
|
-
await this.
|
|
4248
|
+
async writeObject(params) {
|
|
4249
|
+
const objectPath = this.getObjectPath(params);
|
|
4250
|
+
await fs4.mkdir(path3.dirname(objectPath), { recursive: true });
|
|
4251
|
+
await fs4.writeFile(objectPath, params.body);
|
|
4252
|
+
await this.writeObjectMetadata(objectPath, {
|
|
4299
4253
|
contentType: params.contentType,
|
|
4300
|
-
metadata: params.metadata
|
|
4254
|
+
metadata: params.metadata
|
|
4301
4255
|
});
|
|
4302
4256
|
return {
|
|
4303
|
-
|
|
4304
|
-
|
|
4257
|
+
documentId: params.documentId,
|
|
4258
|
+
revisionKey: params.revisionKey,
|
|
4259
|
+
path: params.path,
|
|
4260
|
+
url: toFileUrl(objectPath)
|
|
4305
4261
|
};
|
|
4306
4262
|
}
|
|
4307
|
-
async
|
|
4308
|
-
const
|
|
4263
|
+
async headObject(params) {
|
|
4264
|
+
const objectPath = this.getObjectPath(params);
|
|
4309
4265
|
try {
|
|
4310
|
-
await fs4.
|
|
4311
|
-
|
|
4266
|
+
const stat = await fs4.stat(objectPath);
|
|
4267
|
+
const metadata = await this.readObjectMetadata(objectPath);
|
|
4268
|
+
return {
|
|
4269
|
+
...params,
|
|
4270
|
+
contentType: metadata?.contentType,
|
|
4271
|
+
contentLength: stat.size,
|
|
4272
|
+
metadata: metadata?.metadata,
|
|
4273
|
+
url: toFileUrl(objectPath)
|
|
4274
|
+
};
|
|
4312
4275
|
} catch (error) {
|
|
4313
4276
|
if (isMissingFileError3(error)) {
|
|
4314
4277
|
return null;
|
|
@@ -4316,53 +4279,54 @@ var DiskParsedDocumentStorage = class {
|
|
|
4316
4279
|
throw error;
|
|
4317
4280
|
}
|
|
4318
4281
|
}
|
|
4319
|
-
async
|
|
4320
|
-
|
|
4321
|
-
|
|
4322
|
-
);
|
|
4323
|
-
}
|
|
4324
|
-
async writeSyncProgress(params) {
|
|
4325
|
-
await this.writeJson(this.getProgressPath(params.documentId, params.revisionKey), params);
|
|
4282
|
+
async getObjectUrl(params) {
|
|
4283
|
+
const head = await this.headObject(params);
|
|
4284
|
+
return head?.url ?? null;
|
|
4326
4285
|
}
|
|
4327
|
-
|
|
4328
|
-
|
|
4329
|
-
|
|
4330
|
-
|
|
4331
|
-
|
|
4332
|
-
);
|
|
4286
|
+
async deletePrefix(params) {
|
|
4287
|
+
await fs4.rm(this.getRevisionDirectory(params.documentId, params.revisionKey), {
|
|
4288
|
+
recursive: true,
|
|
4289
|
+
force: true
|
|
4290
|
+
});
|
|
4333
4291
|
}
|
|
4334
|
-
|
|
4335
|
-
return
|
|
4336
|
-
|
|
4337
|
-
|
|
4338
|
-
|
|
4339
|
-
);
|
|
4292
|
+
async readSyncProgress(params) {
|
|
4293
|
+
return this.readOptionalJson({
|
|
4294
|
+
...params,
|
|
4295
|
+
path: syncProgressPath
|
|
4296
|
+
});
|
|
4340
4297
|
}
|
|
4341
|
-
|
|
4342
|
-
|
|
4298
|
+
async writeSyncProgress(params) {
|
|
4299
|
+
await this.writeObject({
|
|
4300
|
+
documentId: params.documentId,
|
|
4301
|
+
revisionKey: params.revisionKey,
|
|
4302
|
+
path: syncProgressPath,
|
|
4303
|
+
body: Buffer.from(JSON.stringify(params, null, 2), "utf8"),
|
|
4304
|
+
contentType: "application/json; charset=utf-8"
|
|
4305
|
+
});
|
|
4343
4306
|
}
|
|
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}`);
|
|
4307
|
+
getObjectPath(params) {
|
|
4308
|
+
const revisionDirectory = this.getRevisionDirectory(params.documentId, params.revisionKey);
|
|
4309
|
+
const objectPath = path3.resolve(revisionDirectory, normalizeRelativeStoragePath(params.path));
|
|
4310
|
+
if (!isPathInsideDirectory2(objectPath, revisionDirectory)) {
|
|
4311
|
+
throw new Error(`Parsed document object path resolves outside storage: ${params.path}`);
|
|
4357
4312
|
}
|
|
4358
|
-
return
|
|
4313
|
+
return objectPath;
|
|
4359
4314
|
}
|
|
4360
4315
|
getRevisionDirectory(documentId, revisionKey) {
|
|
4361
4316
|
return path3.join(this.rootDirectory, hashPathPart(documentId), hashPathPart(revisionKey));
|
|
4362
4317
|
}
|
|
4363
|
-
async readOptionalJson(
|
|
4318
|
+
async readOptionalJson(params) {
|
|
4319
|
+
const object = await this.readObject(params);
|
|
4320
|
+
if (!object) {
|
|
4321
|
+
return null;
|
|
4322
|
+
}
|
|
4323
|
+
return JSON.parse(Buffer.from(object.body).toString("utf8"));
|
|
4324
|
+
}
|
|
4325
|
+
async readObjectMetadata(filePath) {
|
|
4364
4326
|
try {
|
|
4365
|
-
return JSON.parse(
|
|
4327
|
+
return JSON.parse(
|
|
4328
|
+
await fs4.readFile(getMetadataPath(filePath), "utf8")
|
|
4329
|
+
);
|
|
4366
4330
|
} catch (error) {
|
|
4367
4331
|
if (isMissingFileError3(error)) {
|
|
4368
4332
|
return null;
|
|
@@ -4370,16 +4334,22 @@ var DiskParsedDocumentStorage = class {
|
|
|
4370
4334
|
throw error;
|
|
4371
4335
|
}
|
|
4372
4336
|
}
|
|
4373
|
-
async
|
|
4374
|
-
await fs4.
|
|
4375
|
-
await fs4.writeFile(filePath, JSON.stringify(value, null, 2), {
|
|
4337
|
+
async writeObjectMetadata(filePath, metadata) {
|
|
4338
|
+
await fs4.writeFile(getMetadataPath(filePath), JSON.stringify(metadata, null, 2), {
|
|
4376
4339
|
encoding: "utf8",
|
|
4377
4340
|
flag: "w"
|
|
4378
4341
|
});
|
|
4379
4342
|
}
|
|
4380
4343
|
};
|
|
4344
|
+
function getMetadataPath(filePath) {
|
|
4345
|
+
return `${filePath}.metadata.json`;
|
|
4346
|
+
}
|
|
4381
4347
|
function hashPathPart(value) {
|
|
4382
|
-
|
|
4348
|
+
const normalized = value.trim();
|
|
4349
|
+
if (normalized.length === 0) {
|
|
4350
|
+
throw new Error("Parsed document storage path part must be a non-empty value.");
|
|
4351
|
+
}
|
|
4352
|
+
return createHash3("sha256").update(normalized).digest("hex").slice(0, 24);
|
|
4383
4353
|
}
|
|
4384
4354
|
function normalizeRelativeStoragePath(value) {
|
|
4385
4355
|
const normalized = value.replaceAll("\\", "/").replace(/^\.\/+/, "");
|