mindoodb 0.0.3 → 0.0.5
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-server.md +1030 -0
- package/README.md +14 -26
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +27 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +270 -121
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.d.ts +15 -0
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +235 -10
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +5 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +40 -4
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +10 -3
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +138 -13
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -1
- package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts +21 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.d.ts.map +1 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.js +106 -0
- package/dist/browser/cache/IndexedDBLocalCacheStore.js.map +1 -0
- package/dist/browser/index.d.ts +3 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +9 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/core/BaseMindooDB.d.ts +108 -13
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +1268 -292
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +31 -1
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +212 -129
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +13 -10
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +134 -27
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts +5 -1
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +46 -69
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/MindooDBServerAdmin.d.ts +241 -0
- package/dist/core/MindooDBServerAdmin.d.ts.map +1 -0
- package/dist/core/MindooDBServerAdmin.js +401 -0
- package/dist/core/MindooDBServerAdmin.js.map +1 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.d.ts +22 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.d.ts.map +1 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.js +124 -0
- package/dist/core/appendonlystores/AttachmentReadPlanner.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +10 -4
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +44 -9
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/MaterializationPlanner.d.ts +84 -0
- package/dist/core/appendonlystores/MaterializationPlanner.d.ts.map +1 -0
- package/dist/core/appendonlystores/MaterializationPlanner.js +326 -0
- package/dist/core/appendonlystores/MaterializationPlanner.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +33 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.d.ts +35 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.js +2 -0
- package/dist/core/appendonlystores/network/types.js.map +1 -1
- package/dist/core/appendonlystores/types.d.ts +174 -3
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/cache/CacheManager.d.ts +75 -0
- package/dist/core/cache/CacheManager.d.ts.map +1 -0
- package/dist/core/cache/CacheManager.js +101 -0
- package/dist/core/cache/CacheManager.js.map +1 -0
- package/dist/core/cache/EncryptedLocalCacheStore.d.ts +41 -0
- package/dist/core/cache/EncryptedLocalCacheStore.d.ts.map +1 -0
- package/dist/core/cache/EncryptedLocalCacheStore.js +120 -0
- package/dist/core/cache/EncryptedLocalCacheStore.js.map +1 -0
- package/dist/core/cache/LocalCacheStore.d.ts +50 -0
- package/dist/core/cache/LocalCacheStore.d.ts.map +1 -0
- package/dist/core/cache/LocalCacheStore.js +39 -0
- package/dist/core/cache/LocalCacheStore.js.map +1 -0
- package/dist/core/crypto/privateKeyEncryption.d.ts +5 -0
- package/dist/core/crypto/privateKeyEncryption.d.ts.map +1 -0
- package/dist/core/crypto/privateKeyEncryption.js +87 -0
- package/dist/core/crypto/privateKeyEncryption.js.map +1 -0
- package/dist/core/index.d.ts +13 -6
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +13 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +4 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +39 -11
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts +1 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js +3 -0
- package/dist/core/indexing/virtualviews/ViewEntrySortKeyComparator.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +43 -0
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.js +173 -0
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +7 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +28 -0
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
- package/dist/core/keys/KeyBag.d.ts +38 -14
- package/dist/core/keys/KeyBag.d.ts.map +1 -1
- package/dist/core/keys/KeyBag.js +102 -76
- package/dist/core/keys/KeyBag.js.map +1 -1
- package/dist/core/keys/KeyContext.d.ts +3 -3
- package/dist/core/keys/KeyContext.d.ts.map +1 -1
- package/dist/core/keys/KeyContext.js +10 -4
- package/dist/core/keys/KeyContext.js.map +1 -1
- package/dist/core/types.d.ts +341 -22
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +7 -1
- package/dist/core/types.js.map +1 -1
- package/dist/core/utils/idGeneration.d.ts.map +1 -1
- package/dist/core/utils/idGeneration.js +37 -3
- package/dist/core/utils/idGeneration.js.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +31 -7
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +139 -17
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -1
- package/dist/node/attachments/writeAttachmentToFile.d.ts +15 -0
- package/dist/node/attachments/writeAttachmentToFile.d.ts.map +1 -0
- package/dist/node/attachments/writeAttachmentToFile.js +73 -0
- package/dist/node/attachments/writeAttachmentToFile.js.map +1 -0
- package/dist/node/cache/FileSystemLocalCacheStore.d.ts +17 -0
- package/dist/node/cache/FileSystemLocalCacheStore.d.ts.map +1 -0
- package/dist/node/cache/FileSystemLocalCacheStore.js +128 -0
- package/dist/node/cache/FileSystemLocalCacheStore.js.map +1 -0
- package/dist/node/cli/change-identity-password.d.ts +7 -0
- package/dist/node/cli/change-identity-password.d.ts.map +1 -0
- package/dist/node/cli/change-identity-password.js +67 -0
- package/dist/node/cli/change-identity-password.js.map +1 -0
- package/dist/node/cli/cli-utils.d.ts +16 -0
- package/dist/node/cli/cli-utils.d.ts.map +1 -0
- package/dist/node/cli/cli-utils.js +113 -0
- package/dist/node/cli/cli-utils.js.map +1 -0
- package/dist/node/cli/identity-export-public.d.ts +4 -0
- package/dist/node/cli/identity-export-public.d.ts.map +1 -0
- package/dist/node/cli/identity-export-public.js +55 -0
- package/dist/node/cli/identity-export-public.js.map +1 -0
- package/dist/node/cli/identity-info.d.ts +4 -0
- package/dist/node/cli/identity-info.d.ts.map +1 -0
- package/dist/node/cli/identity-info.js +57 -0
- package/dist/node/cli/identity-info.js.map +1 -0
- package/dist/node/index.d.ts +1 -0
- package/dist/node/index.d.ts.map +1 -1
- package/dist/node/index.js +4 -1
- package/dist/node/index.js.map +1 -1
- package/dist/node/server/CapabilityMatcher.d.ts +45 -0
- package/dist/node/server/CapabilityMatcher.d.ts.map +1 -0
- package/dist/node/server/CapabilityMatcher.js +117 -0
- package/dist/node/server/CapabilityMatcher.js.map +1 -0
- package/dist/node/server/MindooDBServer.d.ts +94 -0
- package/dist/node/server/MindooDBServer.d.ts.map +1 -0
- package/dist/node/server/MindooDBServer.js +1256 -0
- package/dist/node/server/MindooDBServer.js.map +1 -0
- package/dist/node/server/ServerSync.d.ts +41 -0
- package/dist/node/server/ServerSync.d.ts.map +1 -0
- package/dist/node/server/ServerSync.js +187 -0
- package/dist/node/server/ServerSync.js.map +1 -0
- package/dist/node/server/StoreFactory.d.ts +45 -0
- package/dist/node/server/StoreFactory.d.ts.map +1 -0
- package/dist/node/server/StoreFactory.js +89 -0
- package/dist/node/server/StoreFactory.js.map +1 -0
- package/dist/node/server/SystemAdminAuth.d.ts +65 -0
- package/dist/node/server/SystemAdminAuth.d.ts.map +1 -0
- package/dist/node/server/SystemAdminAuth.js +200 -0
- package/dist/node/server/SystemAdminAuth.js.map +1 -0
- package/dist/node/server/SystemIpAllowlist.d.ts +21 -0
- package/dist/node/server/SystemIpAllowlist.d.ts.map +1 -0
- package/dist/node/server/SystemIpAllowlist.js +210 -0
- package/dist/node/server/SystemIpAllowlist.js.map +1 -0
- package/dist/node/server/TenantManager.d.ts +100 -0
- package/dist/node/server/TenantManager.d.ts.map +1 -0
- package/dist/node/server/TenantManager.js +615 -0
- package/dist/node/server/TenantManager.js.map +1 -0
- package/dist/node/server/add-to-network.d.ts +20 -0
- package/dist/node/server/add-to-network.d.ts.map +1 -0
- package/dist/node/server/add-to-network.js +275 -0
- package/dist/node/server/add-to-network.js.map +1 -0
- package/dist/node/server/config.d.ts +51 -0
- package/dist/node/server/config.d.ts.map +1 -0
- package/dist/node/server/config.js +218 -0
- package/dist/node/server/config.js.map +1 -0
- package/dist/node/server/resolveServerPassword.d.ts +7 -0
- package/dist/node/server/resolveServerPassword.d.ts.map +1 -0
- package/dist/node/server/resolveServerPassword.js +25 -0
- package/dist/node/server/resolveServerPassword.js.map +1 -0
- package/dist/node/server/server.d.ts +22 -0
- package/dist/node/server/server.d.ts.map +1 -0
- package/dist/node/server/server.js +225 -0
- package/dist/node/server/server.js.map +1 -0
- package/dist/node/server/serverinit.d.ts +21 -0
- package/dist/node/server/serverinit.d.ts.map +1 -0
- package/dist/node/server/serverinit.js +317 -0
- package/dist/node/server/serverinit.js.map +1 -0
- package/dist/node/server/types.d.ts +167 -0
- package/dist/node/server/types.d.ts.map +1 -0
- package/dist/node/server/types.js +24 -0
- package/dist/node/server/types.js.map +1 -0
- package/dist/node/server/validation.d.ts +47 -0
- package/dist/node/server/validation.d.ts.map +1 -0
- package/dist/node/server/validation.js +114 -0
- package/dist/node/server/validation.js.map +1 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts +48 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.d.ts.map +1 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.js +113 -0
- package/dist/reactnative/cache/MMKVLocalCacheStore.js.map +1 -0
- package/dist/reactnative/index.d.ts +1 -0
- package/dist/reactnative/index.d.ts.map +1 -1
- package/dist/reactnative/index.js +4 -1
- package/dist/reactnative/index.js.map +1 -1
- package/package.json +15 -3
|
@@ -20,8 +20,43 @@ exports.isDocEntryId = isDocEntryId;
|
|
|
20
20
|
exports.isAttachmentChunkId = isAttachmentChunkId;
|
|
21
21
|
exports.extractDocIdFromEntryId = extractDocIdFromEntryId;
|
|
22
22
|
exports.computeContentHash = computeContentHash;
|
|
23
|
-
const uuid_base62_1 = require("@digitalmaas/uuid-base62");
|
|
24
23
|
const uuid_1 = require("uuid");
|
|
24
|
+
const BASE62_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
25
|
+
const UUID_NO_DASH_LENGTH = 32;
|
|
26
|
+
const BASE62_UUID_LENGTH = 22;
|
|
27
|
+
function trimLeft(target, length) {
|
|
28
|
+
let trim = 0;
|
|
29
|
+
while (target[trim] === "0" && target.length - trim > length) {
|
|
30
|
+
trim++;
|
|
31
|
+
}
|
|
32
|
+
return target.slice(trim);
|
|
33
|
+
}
|
|
34
|
+
function ensureLength(target, length) {
|
|
35
|
+
if (target.length < length) {
|
|
36
|
+
return target.padStart(length, "0");
|
|
37
|
+
}
|
|
38
|
+
if (target.length > length) {
|
|
39
|
+
return trimLeft(target, length);
|
|
40
|
+
}
|
|
41
|
+
return target;
|
|
42
|
+
}
|
|
43
|
+
function hexToBase62(uuid) {
|
|
44
|
+
const normalized = uuid.replace(/-/g, "");
|
|
45
|
+
if (!/^[0-9a-fA-F]{32}$/.test(normalized)) {
|
|
46
|
+
throw new TypeError(`Invalid UUID for base62 encoding: ${uuid}`);
|
|
47
|
+
}
|
|
48
|
+
let value = BigInt(`0x${normalized}`);
|
|
49
|
+
if (value === 0n) {
|
|
50
|
+
return "0".repeat(BASE62_UUID_LENGTH);
|
|
51
|
+
}
|
|
52
|
+
let encoded = "";
|
|
53
|
+
while (value > 0n) {
|
|
54
|
+
const digit = Number(value % 62n);
|
|
55
|
+
encoded = BASE62_ALPHABET[digit] + encoded;
|
|
56
|
+
value /= 62n;
|
|
57
|
+
}
|
|
58
|
+
return ensureLength(encoded, BASE62_UUID_LENGTH);
|
|
59
|
+
}
|
|
25
60
|
/**
|
|
26
61
|
* Generate a document entry ID with blockchain-like chaining.
|
|
27
62
|
* Format: <docId>_d_<depsFingerprint>_<automergeHash>
|
|
@@ -71,8 +106,7 @@ async function generateDepsFingerprint(dependencyAutomergeHashes, subtle) {
|
|
|
71
106
|
*/
|
|
72
107
|
function generateAttachmentChunkId(docId, fileUuid7, chunkUuid7) {
|
|
73
108
|
const chunkId = chunkUuid7 || (0, uuid_1.v7)();
|
|
74
|
-
|
|
75
|
-
const base62Chunk = (0, uuid_base62_1.encode)(chunkId);
|
|
109
|
+
const base62Chunk = hexToBase62(chunkId);
|
|
76
110
|
return `${docId}_a_${fileUuid7}_${base62Chunk}`;
|
|
77
111
|
}
|
|
78
112
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"idGeneration.js","sourceRoot":"","sources":["../../../src/core/utils/idGeneration.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;
|
|
1
|
+
{"version":3,"file":"idGeneration.js","sourceRoot":"","sources":["../../../src/core/utils/idGeneration.ts"],"names":[],"mappings":"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"}
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
*
|
|
39
39
|
* @module BasicOnDiskContentAddressedStore
|
|
40
40
|
*/
|
|
41
|
-
import { ContentAddressedStore, ContentAddressedStoreFactory, CreateStoreResult, OpenStoreOptions, StoreIndexBuildStatus, StoreCompactionStatus, AwaitIndexReadyOptions, StoreScanCursor, StoreScanFilters, StoreScanResult, StoreIdBloomSummary } from "../../core/appendonlystores/types";
|
|
41
|
+
import { AttachmentReadPlan, AttachmentReadPlanOptions, ContentAddressedStore, ContentAddressedStoreFactory, CreateStoreResult, DocumentMaterializationBatchPlan, DocumentMaterializationPlan, MaterializationPlanOptions, OpenStoreOptions, StoreIndexBuildStatus, StoreCompactionStatus, AwaitIndexReadyOptions, StoreScanCursor, StoreScanFilters, StoreScanResult, StoreIdBloomSummary } from "../../core/appendonlystores/types";
|
|
42
42
|
import type { StoreEntry, StoreEntryMetadata, StoreEntryType } from "../../core/types";
|
|
43
43
|
import { Logger } from "../../core/logging";
|
|
44
44
|
/**
|
|
@@ -111,11 +111,13 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
111
111
|
*/
|
|
112
112
|
private contentRefCount;
|
|
113
113
|
/**
|
|
114
|
-
* All metadata sorted by `(
|
|
114
|
+
* All metadata sorted by `(receiptOrder ASC, id ASC)`.
|
|
115
115
|
* Supports O(log N) lower-bound binary search for cursor-based scans
|
|
116
116
|
* in {@link scanEntriesSince}.
|
|
117
117
|
*/
|
|
118
118
|
private orderedMetadata;
|
|
119
|
+
/** Next monotonic local receipt order assigned on insert. */
|
|
120
|
+
private nextReceiptOrder;
|
|
119
121
|
/** Current phase and progress of the index build (building / ready). */
|
|
120
122
|
private indexStatus;
|
|
121
123
|
/**
|
|
@@ -159,7 +161,7 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
159
161
|
*
|
|
160
162
|
* Clears all in-memory structures, reads every `entries/*.json` file,
|
|
161
163
|
* populates the primary, secondary, and ref-count indexes, and finally
|
|
162
|
-
* sorts `orderedMetadata` by `(
|
|
164
|
+
* sorts `orderedMetadata` by `(receiptOrder, id)`.
|
|
163
165
|
*
|
|
164
166
|
* This is the slowest startup path (O(N) filesystem reads) and is only
|
|
165
167
|
* used when the persisted snapshot + segments cannot be validated.
|
|
@@ -265,13 +267,13 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
265
267
|
*/
|
|
266
268
|
private computeSegmentFilesTotalBytes;
|
|
267
269
|
/**
|
|
268
|
-
* Compare two metadata entries by the canonical sort key `(
|
|
270
|
+
* Compare two metadata entries by the canonical sort key `(receiptOrder, id)`.
|
|
269
271
|
* Used to maintain and query the `orderedMetadata` sorted array.
|
|
270
272
|
*/
|
|
271
273
|
private compareMetadata;
|
|
272
274
|
/**
|
|
273
275
|
* Binary search for the first index in `orderedMetadata` that is strictly
|
|
274
|
-
* greater than the given cursor position `(
|
|
276
|
+
* greater than the given cursor position `(receiptOrder, id)`.
|
|
275
277
|
*
|
|
276
278
|
* Returns 0 when cursor is `null` (start from the beginning).
|
|
277
279
|
* Runs in O(log N) time.
|
|
@@ -310,6 +312,23 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
310
312
|
* Updates `entries`, `docIndex`, `orderedMetadata`, and `contentRefCount`.
|
|
311
313
|
*/
|
|
312
314
|
private applyMetadataUpsert;
|
|
315
|
+
private recomputeNextReceiptOrder;
|
|
316
|
+
private compareLegacyCreatedAtId;
|
|
317
|
+
/**
|
|
318
|
+
* Ensure every persisted metadata file has a `receiptOrder`.
|
|
319
|
+
*
|
|
320
|
+
* Older on-disk stores predate receipt-order discovery and therefore only
|
|
321
|
+
* persist `createdAt`. On startup we detect that legacy shape, assign a
|
|
322
|
+
* deterministic synthetic `receiptOrder` by sorting existing entries using
|
|
323
|
+
* the old `(createdAt, id)` rule, and rewrite the metadata files in that
|
|
324
|
+
* order. This preserves a stable forward cursor contract after migration,
|
|
325
|
+
* even though the exact historic arrival order is unknowable for preexisting
|
|
326
|
+
* rows.
|
|
327
|
+
*
|
|
328
|
+
* @returns `true` when a backfill rewrite was performed, `false` when the
|
|
329
|
+
* store already had receipt-order metadata (or was empty).
|
|
330
|
+
*/
|
|
331
|
+
private ensurePersistedReceiptOrder;
|
|
313
332
|
/** List all `.json` files in the `entries/` directory. */
|
|
314
333
|
private listEntryFiles;
|
|
315
334
|
/** Resolve the absolute path to the metadata file for a given entry id. */
|
|
@@ -366,6 +385,7 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
366
385
|
private listAllMetadata;
|
|
367
386
|
/** Return the database id this store was created for. */
|
|
368
387
|
getId(): string;
|
|
388
|
+
getCacheIdentity(): string;
|
|
369
389
|
/**
|
|
370
390
|
* Persist one or more entries to disk.
|
|
371
391
|
*
|
|
@@ -388,6 +408,8 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
388
408
|
* is O(1); the content read is always a disk I/O.
|
|
389
409
|
*/
|
|
390
410
|
getEntries(ids: string[]): Promise<StoreEntry[]>;
|
|
411
|
+
getEntryMetadata(id: string): Promise<StoreEntryMetadata | null>;
|
|
412
|
+
planAttachmentReadByWalkingMetadata(lastChunkId: string, attachmentSize: number, options: AttachmentReadPlanOptions): Promise<AttachmentReadPlan>;
|
|
391
413
|
/**
|
|
392
414
|
* Check which of the given ids exist in the store.
|
|
393
415
|
*
|
|
@@ -424,7 +446,7 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
424
446
|
/**
|
|
425
447
|
* Return all entry ids in the store.
|
|
426
448
|
*
|
|
427
|
-
* When indexing is enabled, returns ids in `(
|
|
449
|
+
* When indexing is enabled, returns ids in `(receiptOrder, id)` order.
|
|
428
450
|
* Without indexing, order depends on the filesystem directory listing.
|
|
429
451
|
*/
|
|
430
452
|
getAllIds(): Promise<string[]>;
|
|
@@ -433,7 +455,7 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
433
455
|
*
|
|
434
456
|
* Designed for high-volume synchronization: the caller repeatedly advances
|
|
435
457
|
* a cursor to stream through all entries in deterministic
|
|
436
|
-
* `(
|
|
458
|
+
* `(receiptOrder ASC, id ASC)` order, optionally applying filters.
|
|
437
459
|
*
|
|
438
460
|
* **Indexed path** (default):
|
|
439
461
|
* - O(log N) binary search for the cursor position.
|
|
@@ -463,6 +485,8 @@ export declare class BasicOnDiskContentAddressedStore implements ContentAddresse
|
|
|
463
485
|
* bitset, suitable for transmission over the network.
|
|
464
486
|
*/
|
|
465
487
|
getIdBloomSummary(): Promise<StoreIdBloomSummary>;
|
|
488
|
+
planDocumentMaterialization(docId: string, options?: MaterializationPlanOptions): Promise<DocumentMaterializationPlan>;
|
|
489
|
+
planDocumentMaterializationBatch(docIds: string[], options?: MaterializationPlanOptions): Promise<DocumentMaterializationBatchPlan>;
|
|
466
490
|
/**
|
|
467
491
|
* Traverse the dependency graph starting from a given entry id.
|
|
468
492
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BasicOnDiskContentAddressedStore.d.ts","sourceRoot":"","sources":["../../../src/node/appendonlystores/BasicOnDiskContentAddressedStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAKH,OAAO,EACL,qBAAqB,EACrB,4BAA4B,EAC5B,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,qBAAqB,EACrB,sBAAsB,EACtB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,mBAAmB,EACpB,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"BasicOnDiskContentAddressedStore.d.ts","sourceRoot":"","sources":["../../../src/node/appendonlystores/BasicOnDiskContentAddressedStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -77,7 +77,9 @@ exports.BasicOnDiskContentAddressedStoreFactory = exports.BasicOnDiskContentAddr
|
|
|
77
77
|
const promises_1 = require("fs/promises");
|
|
78
78
|
const fs_1 = require("fs");
|
|
79
79
|
const path = __importStar(require("path"));
|
|
80
|
+
const AttachmentReadPlanner_1 = require("../../core/appendonlystores/AttachmentReadPlanner");
|
|
80
81
|
const bloom_1 = require("../../core/appendonlystores/bloom");
|
|
82
|
+
const MaterializationPlanner_1 = require("../../core/appendonlystores/MaterializationPlanner");
|
|
81
83
|
const logging_1 = require("../../core/logging");
|
|
82
84
|
/**
|
|
83
85
|
* When the number of uncompacted segment files reaches this threshold,
|
|
@@ -198,11 +200,13 @@ class BasicOnDiskContentAddressedStore {
|
|
|
198
200
|
*/
|
|
199
201
|
this.contentRefCount = new Map();
|
|
200
202
|
/**
|
|
201
|
-
* All metadata sorted by `(
|
|
203
|
+
* All metadata sorted by `(receiptOrder ASC, id ASC)`.
|
|
202
204
|
* Supports O(log N) lower-bound binary search for cursor-based scans
|
|
203
205
|
* in {@link scanEntriesSince}.
|
|
204
206
|
*/
|
|
205
207
|
this.orderedMetadata = [];
|
|
208
|
+
/** Next monotonic local receipt order assigned on insert. */
|
|
209
|
+
this.nextReceiptOrder = 1;
|
|
206
210
|
this.dbId = dbId;
|
|
207
211
|
this.logger =
|
|
208
212
|
logger ||
|
|
@@ -265,6 +269,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
265
269
|
await (0, promises_1.mkdir)(this.entriesDir, { recursive: true });
|
|
266
270
|
await (0, promises_1.mkdir)(this.contentDir, { recursive: true });
|
|
267
271
|
await (0, promises_1.mkdir)(this.metadataSegmentsDir, { recursive: true });
|
|
272
|
+
const migratedReceiptOrder = await this.ensurePersistedReceiptOrder();
|
|
268
273
|
if (!this.indexingEnabled) {
|
|
269
274
|
this.indexStatus = {
|
|
270
275
|
phase: "ready",
|
|
@@ -273,6 +278,17 @@ class BasicOnDiskContentAddressedStore {
|
|
|
273
278
|
};
|
|
274
279
|
return;
|
|
275
280
|
}
|
|
281
|
+
if (migratedReceiptOrder) {
|
|
282
|
+
await this.rebuildInMemoryIndexes();
|
|
283
|
+
await this.persistMetadataIndex();
|
|
284
|
+
await this.clearMetadataSegments(Array.from(this.appliedMetadataSegmentFiles));
|
|
285
|
+
this.indexStatus = {
|
|
286
|
+
phase: "ready",
|
|
287
|
+
indexingEnabled: true,
|
|
288
|
+
progress01: 1,
|
|
289
|
+
};
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
276
292
|
// Startup path:
|
|
277
293
|
// 1) load snapshot (fast path)
|
|
278
294
|
// 2) replay append-only segments (apply recent mutations)
|
|
@@ -286,6 +302,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
286
302
|
await this.persistMetadataIndex();
|
|
287
303
|
await this.clearMetadataSegments(Array.from(this.appliedMetadataSegmentFiles));
|
|
288
304
|
}
|
|
305
|
+
this.recomputeNextReceiptOrder();
|
|
289
306
|
this.indexStatus = {
|
|
290
307
|
phase: "ready",
|
|
291
308
|
indexingEnabled: true,
|
|
@@ -308,13 +325,14 @@ class BasicOnDiskContentAddressedStore {
|
|
|
308
325
|
this.contentRefCount.clear();
|
|
309
326
|
this.orderedMetadata = [];
|
|
310
327
|
this.appliedMetadataSegmentFiles.clear();
|
|
328
|
+
this.nextReceiptOrder = 1;
|
|
311
329
|
}
|
|
312
330
|
/**
|
|
313
331
|
* Full index rebuild from the authoritative entry files on disk.
|
|
314
332
|
*
|
|
315
333
|
* Clears all in-memory structures, reads every `entries/*.json` file,
|
|
316
334
|
* populates the primary, secondary, and ref-count indexes, and finally
|
|
317
|
-
* sorts `orderedMetadata` by `(
|
|
335
|
+
* sorts `orderedMetadata` by `(receiptOrder, id)`.
|
|
318
336
|
*
|
|
319
337
|
* This is the slowest startup path (O(N) filesystem reads) and is only
|
|
320
338
|
* used when the persisted snapshot + segments cannot be validated.
|
|
@@ -338,7 +356,8 @@ class BasicOnDiskContentAddressedStore {
|
|
|
338
356
|
this.contentRefCount.set(metadata.contentHash, (this.contentRefCount.get(metadata.contentHash) || 0) + 1);
|
|
339
357
|
this.orderedMetadata.push(metadata);
|
|
340
358
|
}
|
|
341
|
-
this.orderedMetadata.sort((a, b) =>
|
|
359
|
+
this.orderedMetadata.sort((a, b) => this.compareMetadata(a, b));
|
|
360
|
+
this.recomputeNextReceiptOrder();
|
|
342
361
|
}
|
|
343
362
|
/**
|
|
344
363
|
* Attempt to hydrate the in-memory index from the persisted
|
|
@@ -372,6 +391,8 @@ class BasicOnDiskContentAddressedStore {
|
|
|
372
391
|
this.contentRefCount.set(metadata.contentHash, (this.contentRefCount.get(metadata.contentHash) || 0) + 1);
|
|
373
392
|
this.orderedMetadata.push(metadata);
|
|
374
393
|
}
|
|
394
|
+
this.orderedMetadata.sort((a, b) => this.compareMetadata(a, b));
|
|
395
|
+
this.recomputeNextReceiptOrder();
|
|
375
396
|
return true;
|
|
376
397
|
}
|
|
377
398
|
catch (err) {
|
|
@@ -594,18 +615,20 @@ class BasicOnDiskContentAddressedStore {
|
|
|
594
615
|
// In-memory index helpers
|
|
595
616
|
// ---------------------------------------------------------------------------
|
|
596
617
|
/**
|
|
597
|
-
* Compare two metadata entries by the canonical sort key `(
|
|
618
|
+
* Compare two metadata entries by the canonical sort key `(receiptOrder, id)`.
|
|
598
619
|
* Used to maintain and query the `orderedMetadata` sorted array.
|
|
599
620
|
*/
|
|
600
621
|
compareMetadata(a, b) {
|
|
601
|
-
|
|
602
|
-
|
|
622
|
+
const leftReceiptOrder = a.receiptOrder ?? 0;
|
|
623
|
+
const rightReceiptOrder = b.receiptOrder ?? 0;
|
|
624
|
+
if (leftReceiptOrder !== rightReceiptOrder) {
|
|
625
|
+
return leftReceiptOrder - rightReceiptOrder;
|
|
603
626
|
}
|
|
604
627
|
return a.id.localeCompare(b.id);
|
|
605
628
|
}
|
|
606
629
|
/**
|
|
607
630
|
* Binary search for the first index in `orderedMetadata` that is strictly
|
|
608
|
-
* greater than the given cursor position `(
|
|
631
|
+
* greater than the given cursor position `(receiptOrder, id)`.
|
|
609
632
|
*
|
|
610
633
|
* Returns 0 when cursor is `null` (start from the beginning).
|
|
611
634
|
* Runs in O(log N) time.
|
|
@@ -619,8 +642,8 @@ class BasicOnDiskContentAddressedStore {
|
|
|
619
642
|
while (left < right) {
|
|
620
643
|
const mid = Math.floor((left + right) / 2);
|
|
621
644
|
const candidate = this.orderedMetadata[mid];
|
|
622
|
-
const greater = candidate.
|
|
623
|
-
(candidate.
|
|
645
|
+
const greater = (candidate.receiptOrder ?? 0) > cursor.receiptOrder ||
|
|
646
|
+
((candidate.receiptOrder ?? 0) === cursor.receiptOrder && candidate.id > cursor.id);
|
|
624
647
|
if (greater) {
|
|
625
648
|
right = mid;
|
|
626
649
|
}
|
|
@@ -724,6 +747,70 @@ class BasicOnDiskContentAddressedStore {
|
|
|
724
747
|
this.docIndex.get(metadata.docId).add(metadata.id);
|
|
725
748
|
this.contentRefCount.set(metadata.contentHash, (this.contentRefCount.get(metadata.contentHash) || 0) + 1);
|
|
726
749
|
this.insertOrderedMetadata(metadata);
|
|
750
|
+
this.nextReceiptOrder = Math.max(this.nextReceiptOrder, (metadata.receiptOrder ?? 0) + 1);
|
|
751
|
+
}
|
|
752
|
+
recomputeNextReceiptOrder() {
|
|
753
|
+
const maxReceiptOrder = this.orderedMetadata.reduce((max, metadata) => Math.max(max, metadata.receiptOrder ?? 0), 0);
|
|
754
|
+
this.nextReceiptOrder = maxReceiptOrder + 1;
|
|
755
|
+
}
|
|
756
|
+
compareLegacyCreatedAtId(a, b) {
|
|
757
|
+
if (a.createdAt !== b.createdAt) {
|
|
758
|
+
return a.createdAt - b.createdAt;
|
|
759
|
+
}
|
|
760
|
+
return a.id.localeCompare(b.id);
|
|
761
|
+
}
|
|
762
|
+
/**
|
|
763
|
+
* Ensure every persisted metadata file has a `receiptOrder`.
|
|
764
|
+
*
|
|
765
|
+
* Older on-disk stores predate receipt-order discovery and therefore only
|
|
766
|
+
* persist `createdAt`. On startup we detect that legacy shape, assign a
|
|
767
|
+
* deterministic synthetic `receiptOrder` by sorting existing entries using
|
|
768
|
+
* the old `(createdAt, id)` rule, and rewrite the metadata files in that
|
|
769
|
+
* order. This preserves a stable forward cursor contract after migration,
|
|
770
|
+
* even though the exact historic arrival order is unknowable for preexisting
|
|
771
|
+
* rows.
|
|
772
|
+
*
|
|
773
|
+
* @returns `true` when a backfill rewrite was performed, `false` when the
|
|
774
|
+
* store already had receipt-order metadata (or was empty).
|
|
775
|
+
*/
|
|
776
|
+
async ensurePersistedReceiptOrder() {
|
|
777
|
+
const files = await this.listEntryFiles();
|
|
778
|
+
if (files.length === 0) {
|
|
779
|
+
this.nextReceiptOrder = 1;
|
|
780
|
+
return false;
|
|
781
|
+
}
|
|
782
|
+
const metadataList = [];
|
|
783
|
+
let missingReceiptOrder = false;
|
|
784
|
+
let maxReceiptOrder = 0;
|
|
785
|
+
for (const fileName of files) {
|
|
786
|
+
const metadata = await this.readMetadataByFileName(fileName);
|
|
787
|
+
if (!metadata) {
|
|
788
|
+
continue;
|
|
789
|
+
}
|
|
790
|
+
metadataList.push({ fileName, metadata });
|
|
791
|
+
if (typeof metadata.receiptOrder !== "number") {
|
|
792
|
+
missingReceiptOrder = true;
|
|
793
|
+
}
|
|
794
|
+
else {
|
|
795
|
+
maxReceiptOrder = Math.max(maxReceiptOrder, metadata.receiptOrder);
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
if (!missingReceiptOrder) {
|
|
799
|
+
this.nextReceiptOrder = maxReceiptOrder + 1;
|
|
800
|
+
return false;
|
|
801
|
+
}
|
|
802
|
+
metadataList.sort((left, right) => this.compareLegacyCreatedAtId(left.metadata, right.metadata));
|
|
803
|
+
let nextReceiptOrder = 1;
|
|
804
|
+
for (const { fileName, metadata } of metadataList) {
|
|
805
|
+
const migrated = {
|
|
806
|
+
...metadata,
|
|
807
|
+
receiptOrder: nextReceiptOrder++,
|
|
808
|
+
};
|
|
809
|
+
const filePath = path.join(this.entriesDir, fileName);
|
|
810
|
+
await this.writeFileAtomic(filePath, JSON.stringify(serializeMetadata(migrated)));
|
|
811
|
+
}
|
|
812
|
+
this.nextReceiptOrder = nextReceiptOrder;
|
|
813
|
+
return true;
|
|
727
814
|
}
|
|
728
815
|
// ---------------------------------------------------------------------------
|
|
729
816
|
// Filesystem I/O helpers
|
|
@@ -874,6 +961,9 @@ class BasicOnDiskContentAddressedStore {
|
|
|
874
961
|
getId() {
|
|
875
962
|
return this.dbId;
|
|
876
963
|
}
|
|
964
|
+
getCacheIdentity() {
|
|
965
|
+
return `disk:${this.storeRoot}`;
|
|
966
|
+
}
|
|
877
967
|
/**
|
|
878
968
|
* Persist one or more entries to disk.
|
|
879
969
|
*
|
|
@@ -904,7 +994,11 @@ class BasicOnDiskContentAddressedStore {
|
|
|
904
994
|
if (!(await this.fileExists(contentPath))) {
|
|
905
995
|
await this.writeFileAtomic(contentPath, entry.encryptedData);
|
|
906
996
|
}
|
|
907
|
-
const { encryptedData, ...
|
|
997
|
+
const { encryptedData, receiptOrder: _ignoredReceiptOrder, ...rest } = entry;
|
|
998
|
+
const metadata = {
|
|
999
|
+
...rest,
|
|
1000
|
+
receiptOrder: this.nextReceiptOrder++,
|
|
1001
|
+
};
|
|
908
1002
|
const serialized = JSON.stringify(serializeMetadata(metadata));
|
|
909
1003
|
await this.writeFileAtomic(metadataPath, serialized);
|
|
910
1004
|
hasMutation = true;
|
|
@@ -945,6 +1039,14 @@ class BasicOnDiskContentAddressedStore {
|
|
|
945
1039
|
}
|
|
946
1040
|
return result;
|
|
947
1041
|
}
|
|
1042
|
+
async getEntryMetadata(id) {
|
|
1043
|
+
await this.ensureInitialized();
|
|
1044
|
+
return this.readMetadataById(id);
|
|
1045
|
+
}
|
|
1046
|
+
async planAttachmentReadByWalkingMetadata(lastChunkId, attachmentSize, options) {
|
|
1047
|
+
await this.ensureInitialized();
|
|
1048
|
+
return (0, AttachmentReadPlanner_1.planAttachmentReadByWalkingMetadata)(this, lastChunkId, attachmentSize, options);
|
|
1049
|
+
}
|
|
948
1050
|
/**
|
|
949
1051
|
* Check which of the given ids exist in the store.
|
|
950
1052
|
*
|
|
@@ -1036,7 +1138,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1036
1138
|
/**
|
|
1037
1139
|
* Return all entry ids in the store.
|
|
1038
1140
|
*
|
|
1039
|
-
* When indexing is enabled, returns ids in `(
|
|
1141
|
+
* When indexing is enabled, returns ids in `(receiptOrder, id)` order.
|
|
1040
1142
|
* Without indexing, order depends on the filesystem directory listing.
|
|
1041
1143
|
*/
|
|
1042
1144
|
async getAllIds() {
|
|
@@ -1052,7 +1154,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1052
1154
|
*
|
|
1053
1155
|
* Designed for high-volume synchronization: the caller repeatedly advances
|
|
1054
1156
|
* a cursor to stream through all entries in deterministic
|
|
1055
|
-
* `(
|
|
1157
|
+
* `(receiptOrder ASC, id ASC)` order, optionally applying filters.
|
|
1056
1158
|
*
|
|
1057
1159
|
* **Indexed path** (default):
|
|
1058
1160
|
* - O(log N) binary search for the cursor position.
|
|
@@ -1078,7 +1180,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1078
1180
|
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
1079
1181
|
return {
|
|
1080
1182
|
entries: page,
|
|
1081
|
-
nextCursor: last ? {
|
|
1183
|
+
nextCursor: last ? { receiptOrder: last.receiptOrder ?? 0, id: last.id } : cursor,
|
|
1082
1184
|
hasMore: startIndex + page.length < this.orderedMetadata.length,
|
|
1083
1185
|
};
|
|
1084
1186
|
}
|
|
@@ -1102,7 +1204,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1102
1204
|
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
1103
1205
|
return {
|
|
1104
1206
|
entries: page,
|
|
1105
|
-
nextCursor: last ? {
|
|
1207
|
+
nextCursor: last ? { receiptOrder: last.receiptOrder ?? 0, id: last.id } : cursor,
|
|
1106
1208
|
hasMore,
|
|
1107
1209
|
};
|
|
1108
1210
|
}
|
|
@@ -1123,10 +1225,10 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1123
1225
|
}
|
|
1124
1226
|
return true;
|
|
1125
1227
|
})
|
|
1126
|
-
.sort((a, b) =>
|
|
1228
|
+
.sort((a, b) => this.compareMetadata(a, b));
|
|
1127
1229
|
const startIndex = cursor === null
|
|
1128
1230
|
? 0
|
|
1129
|
-
: all.findIndex((meta) => meta.
|
|
1231
|
+
: all.findIndex((meta) => (meta.receiptOrder ?? 0) > cursor.receiptOrder || ((meta.receiptOrder ?? 0) === cursor.receiptOrder && meta.id > cursor.id));
|
|
1130
1232
|
if (startIndex === -1) {
|
|
1131
1233
|
return { entries: [], nextCursor: cursor, hasMore: false };
|
|
1132
1234
|
}
|
|
@@ -1134,7 +1236,7 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1134
1236
|
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
1135
1237
|
return {
|
|
1136
1238
|
entries: page,
|
|
1137
|
-
nextCursor: last ? {
|
|
1239
|
+
nextCursor: last ? { receiptOrder: last.receiptOrder ?? 0, id: last.id } : cursor,
|
|
1138
1240
|
hasMore: startIndex + page.length < all.length,
|
|
1139
1241
|
};
|
|
1140
1242
|
}
|
|
@@ -1155,6 +1257,26 @@ class BasicOnDiskContentAddressedStore {
|
|
|
1155
1257
|
const ids = await this.getAllIds();
|
|
1156
1258
|
return (0, bloom_1.createIdBloomSummary)(ids);
|
|
1157
1259
|
}
|
|
1260
|
+
async planDocumentMaterialization(docId, options) {
|
|
1261
|
+
await this.ensureInitialized();
|
|
1262
|
+
let entries = [];
|
|
1263
|
+
if (this.indexingEnabled) {
|
|
1264
|
+
const ids = this.docIndex.get(docId) || new Set();
|
|
1265
|
+
entries = Array.from(ids)
|
|
1266
|
+
.map((id) => this.entries.get(id))
|
|
1267
|
+
.filter((m) => m !== undefined);
|
|
1268
|
+
}
|
|
1269
|
+
else {
|
|
1270
|
+
const all = await this.listAllMetadata();
|
|
1271
|
+
entries = all.filter((m) => m.docId === docId);
|
|
1272
|
+
}
|
|
1273
|
+
return (0, MaterializationPlanner_1.computeDocumentMaterializationPlan)(docId, entries, options);
|
|
1274
|
+
}
|
|
1275
|
+
async planDocumentMaterializationBatch(docIds, options) {
|
|
1276
|
+
await this.ensureInitialized();
|
|
1277
|
+
const all = await this.listAllMetadata();
|
|
1278
|
+
return (0, MaterializationPlanner_1.computeBatchMaterializationPlan)(all, docIds, options);
|
|
1279
|
+
}
|
|
1158
1280
|
/**
|
|
1159
1281
|
* Traverse the dependency graph starting from a given entry id.
|
|
1160
1282
|
*
|