mindoodb 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -19
- package/dist/__mocks__/expo-standard-web-crypto.d.ts +10 -0
- package/dist/__mocks__/expo-standard-web-crypto.d.ts.map +1 -0
- package/dist/__mocks__/expo-standard-web-crypto.js +22 -0
- package/dist/__mocks__/expo-standard-web-crypto.js.map +1 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts +8 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js +16 -0
- package/dist/appendonlystores/BasicOnDiskContentAddressedStoreFactory.js.map +1 -0
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts +1 -1
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.d.ts.map +1 -1
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js +2 -2
- package/dist/appendonlystores/InMemoryContentAddressedStoreFactory.js.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts +11 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js +94 -0
- package/dist/appendonlystores/network/ClientNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.d.ts +13 -2
- package/dist/appendonlystores/network/HttpTransport.d.ts.map +1 -1
- package/dist/appendonlystores/network/HttpTransport.js +86 -0
- package/dist/appendonlystores/network/HttpTransport.js.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts +19 -2
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.d.ts.map +1 -1
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js +96 -0
- package/dist/appendonlystores/network/ServerNetworkContentAddressedStore.js.map +1 -1
- package/dist/appendonlystores/network/index.d.ts +1 -1
- package/dist/appendonlystores/network/index.d.ts.map +1 -1
- package/dist/appendonlystores/network/index.js.map +1 -1
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts +61 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.d.ts.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js +685 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStore.js.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts +25 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.d.ts.map +1 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js +41 -0
- package/dist/browser/appendonlystores/IndexedDBContentAddressedStoreFactory.js.map +1 -0
- package/dist/browser/index.d.ts +5 -0
- package/dist/browser/index.d.ts.map +1 -1
- package/dist/browser/index.js +13 -1
- package/dist/browser/index.js.map +1 -1
- package/dist/core/BaseMindooDB.d.ts +12 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +210 -108
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +40 -6
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +179 -21
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +10 -0
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/BaseMindooTenantFactory.d.ts +22 -28
- package/dist/core/BaseMindooTenantFactory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantFactory.js +161 -65
- package/dist/core/BaseMindooTenantFactory.js.map +1 -1
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +68 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js +659 -0
- package/dist/core/appendonlystores/BasicOnDiskContentAddressedStore.js.map +1 -0
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts +43 -3
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.d.ts.map +1 -1
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js +162 -23
- package/dist/core/appendonlystores/InMemoryContentAddressedStore.js.map +1 -1
- package/dist/core/appendonlystores/bloom.d.ts +85 -0
- package/dist/core/appendonlystores/bloom.d.ts.map +1 -0
- package/dist/core/appendonlystores/bloom.js +228 -0
- package/dist/core/appendonlystores/bloom.js.map +1 -0
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts +22 -2
- package/dist/core/appendonlystores/network/NetworkTransport.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.d.ts +10 -0
- package/dist/core/appendonlystores/network/types.d.ts.map +1 -1
- package/dist/core/appendonlystores/network/types.js.map +1 -1
- package/dist/core/appendonlystores/types.d.ts +123 -0
- package/dist/core/appendonlystores/types.d.ts.map +1 -1
- package/dist/core/automerge-adapter.d.ts +15 -0
- package/dist/core/automerge-adapter.d.ts.map +1 -0
- package/dist/core/automerge-adapter.js +73 -0
- package/dist/core/automerge-adapter.js.map +1 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts +12 -0
- package/dist/core/crypto/pbkdf2Iterations.d.ts.map +1 -0
- package/dist/core/crypto/pbkdf2Iterations.js +55 -0
- package/dist/core/crypto/pbkdf2Iterations.js.map +1 -0
- package/dist/core/index.d.ts +7 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +30 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/keys/KeyBag.d.ts +32 -12
- package/dist/core/keys/KeyBag.d.ts.map +1 -1
- package/dist/core/keys/KeyBag.js +86 -26
- package/dist/core/keys/KeyBag.js.map +1 -1
- package/dist/core/keys/KeyContext.d.ts +4 -0
- package/dist/core/keys/KeyContext.d.ts.map +1 -0
- package/dist/core/keys/KeyContext.js +11 -0
- package/dist/core/keys/KeyContext.js.map +1 -0
- package/dist/core/types.d.ts +218 -50
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -1
- package/dist/core/uri/MindooURI.d.ts +58 -0
- package/dist/core/uri/MindooURI.d.ts.map +1 -0
- package/dist/core/uri/MindooURI.js +169 -0
- package/dist/core/uri/MindooURI.js.map +1 -0
- package/dist/core/userid/index.d.ts +0 -10
- package/dist/core/userid/index.d.ts.map +1 -1
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts +541 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.d.ts.map +1 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.js +1334 -0
- package/dist/node/appendonlystores/BasicOnDiskContentAddressedStore.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 +5 -1
- package/dist/node/index.js.map +1 -1
- package/dist/reactnative/crypto/AESAdapter.d.ts +18 -0
- package/dist/reactnative/crypto/AESAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/AESAdapter.js +112 -0
- package/dist/reactnative/crypto/AESAdapter.js.map +1 -0
- package/dist/reactnative/crypto/Ed25519Adapter.d.ts +34 -0
- package/dist/reactnative/crypto/Ed25519Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/Ed25519Adapter.js +386 -0
- package/dist/reactnative/crypto/Ed25519Adapter.js.map +1 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts +23 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js +51 -0
- package/dist/reactnative/crypto/ExpoGoCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/HMACAdapter.d.ts +13 -0
- package/dist/reactnative/crypto/HMACAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/HMACAdapter.js +50 -0
- package/dist/reactnative/crypto/HMACAdapter.js.map +1 -0
- package/dist/reactnative/crypto/KeyFormatConverter.d.ts +21 -0
- package/dist/reactnative/crypto/KeyFormatConverter.d.ts.map +1 -0
- package/dist/reactnative/crypto/KeyFormatConverter.js +72 -0
- package/dist/reactnative/crypto/KeyFormatConverter.js.map +1 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.d.ts +19 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.js +67 -0
- package/dist/reactnative/crypto/PBKDF2Adapter.js.map +1 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts +37 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.js +72 -0
- package/dist/reactnative/crypto/QuickCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/RSAAdapter.d.ts +38 -0
- package/dist/reactnative/crypto/RSAAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/RSAAdapter.js +184 -0
- package/dist/reactnative/crypto/RSAAdapter.js.map +1 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts +33 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js +61 -0
- package/dist/reactnative/crypto/ReactNativeCryptoAdapter.js.map +1 -0
- package/dist/reactnative/crypto/SHA256Adapter.d.ts +9 -0
- package/dist/reactnative/crypto/SHA256Adapter.d.ts.map +1 -0
- package/dist/reactnative/crypto/SHA256Adapter.js +29 -0
- package/dist/reactnative/crypto/SHA256Adapter.js.map +1 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts +63 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.d.ts.map +1 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.js +350 -0
- package/dist/reactnative/crypto/SubtleCryptoPolyfill.js.map +1 -0
- package/dist/reactnative/index.d.ts +8 -0
- package/dist/reactnative/index.d.ts.map +1 -0
- package/dist/reactnative/index.js +38 -0
- package/dist/reactnative/index.js.map +1 -0
- package/package.json +51 -6
- package/patches/PATCHES.md +111 -0
- package/patches/react-native+0.76.9.patch +34 -0
- package/patches/react-native-quick-crypto+1.0.7.patch +42 -0
- package/scripts/cli.js +21 -0
- package/scripts/setup-react-native.js +228 -0
- package/templates/reactnative/App.js +252 -0
- package/templates/reactnative/app.json +29 -0
- package/templates/reactnative/babel.config.js +6 -0
- package/templates/reactnative/index.js +26 -0
- package/templates/reactnative/metro.config.snippet.js +39 -0
- package/templates/reactnative/mindoodb-polyfills.js +116 -0
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.BasicOnDiskContentAddressedStoreFactory = exports.BasicOnDiskContentAddressedStore = void 0;
|
|
37
|
+
const promises_1 = require("fs/promises");
|
|
38
|
+
const fs_1 = require("fs");
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const bloom_1 = require("./bloom");
|
|
41
|
+
const logging_1 = require("../logging");
|
|
42
|
+
function serializeMetadata(metadata) {
|
|
43
|
+
return {
|
|
44
|
+
...metadata,
|
|
45
|
+
signature: Buffer.from(metadata.signature).toString("base64"),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function deserializeMetadata(serialized) {
|
|
49
|
+
return {
|
|
50
|
+
...serialized,
|
|
51
|
+
signature: new Uint8Array(Buffer.from(serialized.signature, "base64")),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function toEntryFileName(id) {
|
|
55
|
+
return `${encodeURIComponent(id)}.json`;
|
|
56
|
+
}
|
|
57
|
+
function fromEntryFileName(fileName) {
|
|
58
|
+
const withoutExt = fileName.endsWith(".json") ? fileName.slice(0, -5) : fileName;
|
|
59
|
+
return decodeURIComponent(withoutExt);
|
|
60
|
+
}
|
|
61
|
+
function tempPathFor(finalPath) {
|
|
62
|
+
return `${finalPath}.tmp-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Simple persistent on-disk ContentAddressedStore implementation.
|
|
66
|
+
* Uses metadata files by id and binary content files by contentHash.
|
|
67
|
+
* Supports reset-on-start and optional in-memory indexing.
|
|
68
|
+
*/
|
|
69
|
+
class BasicOnDiskContentAddressedStore {
|
|
70
|
+
constructor(dbId, logger, options) {
|
|
71
|
+
// In-memory indexes (only used when indexingEnabled=true)
|
|
72
|
+
this.entries = new Map();
|
|
73
|
+
this.docIndex = new Map();
|
|
74
|
+
this.contentRefCount = new Map();
|
|
75
|
+
this.orderedMetadata = [];
|
|
76
|
+
this.dbId = dbId;
|
|
77
|
+
this.logger =
|
|
78
|
+
logger ||
|
|
79
|
+
new logging_1.MindooLogger((0, logging_1.getDefaultLogLevel)(), `BasicOnDiskStore:${dbId}`, true);
|
|
80
|
+
this.storeRoot = path.join(options?.basePath?.toString() || ".mindoodb-store", dbId);
|
|
81
|
+
this.entriesDir = path.join(this.storeRoot, "entries");
|
|
82
|
+
this.contentDir = path.join(this.storeRoot, "content");
|
|
83
|
+
this.metadataIndexPath = path.join(this.storeRoot, "metadata-index.json");
|
|
84
|
+
this.indexingEnabled = options?.indexingEnabled !== false;
|
|
85
|
+
this.indexStatus = {
|
|
86
|
+
phase: this.indexingEnabled ? "building" : "ready",
|
|
87
|
+
indexingEnabled: this.indexingEnabled,
|
|
88
|
+
progress01: this.indexingEnabled ? 0 : 1,
|
|
89
|
+
};
|
|
90
|
+
this.initPromise = this.initialize(options);
|
|
91
|
+
}
|
|
92
|
+
async initialize(options) {
|
|
93
|
+
if (options?.clearLocalDataOnStartup) {
|
|
94
|
+
await this.clearAllLocalDataInternal();
|
|
95
|
+
}
|
|
96
|
+
await (0, promises_1.mkdir)(this.entriesDir, { recursive: true });
|
|
97
|
+
await (0, promises_1.mkdir)(this.contentDir, { recursive: true });
|
|
98
|
+
if (!this.indexingEnabled) {
|
|
99
|
+
this.indexStatus = {
|
|
100
|
+
phase: "ready",
|
|
101
|
+
indexingEnabled: false,
|
|
102
|
+
progress01: 1,
|
|
103
|
+
};
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const loaded = await this.tryLoadPersistedIndex();
|
|
107
|
+
const indexCoverageOk = loaded ? await this.validatePersistedIndexCoverage() : false;
|
|
108
|
+
if (!loaded || !indexCoverageOk) {
|
|
109
|
+
await this.rebuildInMemoryIndexes();
|
|
110
|
+
await this.persistMetadataIndex();
|
|
111
|
+
}
|
|
112
|
+
this.indexStatus = {
|
|
113
|
+
phase: "ready",
|
|
114
|
+
indexingEnabled: true,
|
|
115
|
+
progress01: 1,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async ensureInitialized() {
|
|
119
|
+
await this.initPromise;
|
|
120
|
+
}
|
|
121
|
+
async clearAllLocalDataInternal() {
|
|
122
|
+
await (0, promises_1.rm)(this.storeRoot, { recursive: true, force: true });
|
|
123
|
+
this.entries.clear();
|
|
124
|
+
this.docIndex.clear();
|
|
125
|
+
this.contentRefCount.clear();
|
|
126
|
+
this.orderedMetadata = [];
|
|
127
|
+
}
|
|
128
|
+
async rebuildInMemoryIndexes() {
|
|
129
|
+
this.entries.clear();
|
|
130
|
+
this.docIndex.clear();
|
|
131
|
+
this.contentRefCount.clear();
|
|
132
|
+
this.orderedMetadata = [];
|
|
133
|
+
const files = await this.listEntryFiles();
|
|
134
|
+
for (const fileName of files) {
|
|
135
|
+
const metadata = await this.readMetadataByFileName(fileName);
|
|
136
|
+
if (!metadata) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
this.entries.set(metadata.id, metadata);
|
|
140
|
+
if (!this.docIndex.has(metadata.docId)) {
|
|
141
|
+
this.docIndex.set(metadata.docId, new Set());
|
|
142
|
+
}
|
|
143
|
+
this.docIndex.get(metadata.docId).add(metadata.id);
|
|
144
|
+
this.contentRefCount.set(metadata.contentHash, (this.contentRefCount.get(metadata.contentHash) || 0) + 1);
|
|
145
|
+
this.orderedMetadata.push(metadata);
|
|
146
|
+
}
|
|
147
|
+
this.orderedMetadata.sort((a, b) => (a.createdAt === b.createdAt ? a.id.localeCompare(b.id) : a.createdAt - b.createdAt));
|
|
148
|
+
}
|
|
149
|
+
async tryLoadPersistedIndex() {
|
|
150
|
+
if (!(await this.fileExists(this.metadataIndexPath))) {
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
try {
|
|
154
|
+
const raw = await (0, promises_1.readFile)(this.metadataIndexPath, "utf-8");
|
|
155
|
+
const serialized = JSON.parse(raw);
|
|
156
|
+
const loaded = serialized.map((s) => deserializeMetadata(s));
|
|
157
|
+
this.entries.clear();
|
|
158
|
+
this.docIndex.clear();
|
|
159
|
+
this.contentRefCount.clear();
|
|
160
|
+
this.orderedMetadata = [];
|
|
161
|
+
for (const metadata of loaded) {
|
|
162
|
+
this.entries.set(metadata.id, metadata);
|
|
163
|
+
if (!this.docIndex.has(metadata.docId)) {
|
|
164
|
+
this.docIndex.set(metadata.docId, new Set());
|
|
165
|
+
}
|
|
166
|
+
this.docIndex.get(metadata.docId).add(metadata.id);
|
|
167
|
+
this.contentRefCount.set(metadata.contentHash, (this.contentRefCount.get(metadata.contentHash) || 0) + 1);
|
|
168
|
+
this.orderedMetadata.push(metadata);
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
}
|
|
172
|
+
catch (err) {
|
|
173
|
+
this.logger.warn(`Failed to load metadata index, rebuilding from entry files: ${String(err)}`);
|
|
174
|
+
return false;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
async validatePersistedIndexCoverage() {
|
|
178
|
+
if (!this.indexingEnabled) {
|
|
179
|
+
return true;
|
|
180
|
+
}
|
|
181
|
+
const files = await this.listEntryFiles();
|
|
182
|
+
if (files.length !== this.entries.size) {
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
for (const fileName of files) {
|
|
186
|
+
const entryId = fromEntryFileName(fileName);
|
|
187
|
+
if (!this.entries.has(entryId)) {
|
|
188
|
+
return false;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
async persistMetadataIndex() {
|
|
194
|
+
if (!this.indexingEnabled) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const serialized = JSON.stringify(this.orderedMetadata.map((m) => serializeMetadata(m)));
|
|
198
|
+
await this.writeFileAtomic(this.metadataIndexPath, serialized);
|
|
199
|
+
}
|
|
200
|
+
compareMetadata(a, b) {
|
|
201
|
+
if (a.createdAt !== b.createdAt) {
|
|
202
|
+
return a.createdAt - b.createdAt;
|
|
203
|
+
}
|
|
204
|
+
return a.id.localeCompare(b.id);
|
|
205
|
+
}
|
|
206
|
+
lowerBoundForCursor(cursor) {
|
|
207
|
+
if (cursor === null) {
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
let left = 0;
|
|
211
|
+
let right = this.orderedMetadata.length;
|
|
212
|
+
while (left < right) {
|
|
213
|
+
const mid = Math.floor((left + right) / 2);
|
|
214
|
+
const candidate = this.orderedMetadata[mid];
|
|
215
|
+
const greater = candidate.createdAt > cursor.createdAt ||
|
|
216
|
+
(candidate.createdAt === cursor.createdAt && candidate.id > cursor.id);
|
|
217
|
+
if (greater) {
|
|
218
|
+
right = mid;
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
left = mid + 1;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return left;
|
|
225
|
+
}
|
|
226
|
+
metadataMatchesFilters(meta, filters) {
|
|
227
|
+
if (filters?.docId && meta.docId !== filters.docId) {
|
|
228
|
+
return false;
|
|
229
|
+
}
|
|
230
|
+
if (filters?.entryTypes && filters.entryTypes.length > 0 && !filters.entryTypes.includes(meta.entryType)) {
|
|
231
|
+
return false;
|
|
232
|
+
}
|
|
233
|
+
if (filters?.creationDateFrom !== undefined && filters.creationDateFrom !== null && meta.createdAt < filters.creationDateFrom) {
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
if (filters?.creationDateUntil !== undefined && filters.creationDateUntil !== null && meta.createdAt >= filters.creationDateUntil) {
|
|
237
|
+
return false;
|
|
238
|
+
}
|
|
239
|
+
return true;
|
|
240
|
+
}
|
|
241
|
+
insertOrderedMetadata(meta) {
|
|
242
|
+
let left = 0;
|
|
243
|
+
let right = this.orderedMetadata.length;
|
|
244
|
+
while (left < right) {
|
|
245
|
+
const mid = Math.floor((left + right) / 2);
|
|
246
|
+
if (this.compareMetadata(this.orderedMetadata[mid], meta) < 0) {
|
|
247
|
+
left = mid + 1;
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
right = mid;
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
this.orderedMetadata.splice(left, 0, meta);
|
|
254
|
+
}
|
|
255
|
+
removeOrderedMetadataById(id) {
|
|
256
|
+
const idx = this.orderedMetadata.findIndex((m) => m.id === id);
|
|
257
|
+
if (idx >= 0) {
|
|
258
|
+
this.orderedMetadata.splice(idx, 1);
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
async listEntryFiles() {
|
|
262
|
+
try {
|
|
263
|
+
const files = await (0, promises_1.readdir)(this.entriesDir);
|
|
264
|
+
return files.filter((f) => f.endsWith(".json"));
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return [];
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
metadataPathForId(id) {
|
|
271
|
+
return path.join(this.entriesDir, toEntryFileName(id));
|
|
272
|
+
}
|
|
273
|
+
contentPathForHash(contentHash) {
|
|
274
|
+
return path.join(this.contentDir, `${contentHash}.bin`);
|
|
275
|
+
}
|
|
276
|
+
async fileExists(filePath) {
|
|
277
|
+
try {
|
|
278
|
+
await (0, promises_1.access)(filePath, fs_1.constants.F_OK);
|
|
279
|
+
return true;
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
async writeFileAtomic(filePath, data) {
|
|
286
|
+
const tmpPath = tempPathFor(filePath);
|
|
287
|
+
const tmpHandle = await (0, promises_1.open)(tmpPath, "w");
|
|
288
|
+
try {
|
|
289
|
+
await tmpHandle.writeFile(data);
|
|
290
|
+
await tmpHandle.sync();
|
|
291
|
+
}
|
|
292
|
+
finally {
|
|
293
|
+
await tmpHandle.close();
|
|
294
|
+
}
|
|
295
|
+
await (0, promises_1.rename)(tmpPath, filePath);
|
|
296
|
+
await this.syncParentDirectory(filePath);
|
|
297
|
+
}
|
|
298
|
+
async syncParentDirectory(filePath) {
|
|
299
|
+
const dirPath = path.dirname(filePath);
|
|
300
|
+
try {
|
|
301
|
+
const dirHandle = await (0, promises_1.open)(dirPath, "r");
|
|
302
|
+
try {
|
|
303
|
+
await dirHandle.sync();
|
|
304
|
+
}
|
|
305
|
+
finally {
|
|
306
|
+
await dirHandle.close();
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
catch (err) {
|
|
310
|
+
this.logger.debug(`Directory fsync skipped for ${dirPath}: ${String(err)}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
async readMetadataById(id) {
|
|
314
|
+
if (this.indexingEnabled) {
|
|
315
|
+
return this.entries.get(id) || null;
|
|
316
|
+
}
|
|
317
|
+
const filePath = this.metadataPathForId(id);
|
|
318
|
+
if (!(await this.fileExists(filePath))) {
|
|
319
|
+
return null;
|
|
320
|
+
}
|
|
321
|
+
const raw = await (0, promises_1.readFile)(filePath, "utf-8");
|
|
322
|
+
return deserializeMetadata(JSON.parse(raw));
|
|
323
|
+
}
|
|
324
|
+
async readMetadataByFileName(fileName) {
|
|
325
|
+
const filePath = path.join(this.entriesDir, fileName);
|
|
326
|
+
try {
|
|
327
|
+
const raw = await (0, promises_1.readFile)(filePath, "utf-8");
|
|
328
|
+
const metadata = deserializeMetadata(JSON.parse(raw));
|
|
329
|
+
return metadata;
|
|
330
|
+
}
|
|
331
|
+
catch (err) {
|
|
332
|
+
this.logger.warn(`Failed to read metadata file ${fileName}: ${String(err)}`);
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
async listAllMetadata() {
|
|
337
|
+
if (this.indexingEnabled) {
|
|
338
|
+
return [...this.orderedMetadata];
|
|
339
|
+
}
|
|
340
|
+
const files = await this.listEntryFiles();
|
|
341
|
+
const result = [];
|
|
342
|
+
for (const fileName of files) {
|
|
343
|
+
const metadata = await this.readMetadataByFileName(fileName);
|
|
344
|
+
if (metadata) {
|
|
345
|
+
result.push(metadata);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
return result;
|
|
349
|
+
}
|
|
350
|
+
getId() {
|
|
351
|
+
return this.dbId;
|
|
352
|
+
}
|
|
353
|
+
async putEntries(entries) {
|
|
354
|
+
await this.ensureInitialized();
|
|
355
|
+
let hasMutation = false;
|
|
356
|
+
for (const entry of entries) {
|
|
357
|
+
const metadataPath = this.metadataPathForId(entry.id);
|
|
358
|
+
if (await this.fileExists(metadataPath)) {
|
|
359
|
+
continue;
|
|
360
|
+
}
|
|
361
|
+
const contentPath = this.contentPathForHash(entry.contentHash);
|
|
362
|
+
if (!(await this.fileExists(contentPath))) {
|
|
363
|
+
await this.writeFileAtomic(contentPath, entry.encryptedData);
|
|
364
|
+
}
|
|
365
|
+
const { encryptedData, ...metadata } = entry;
|
|
366
|
+
const serialized = JSON.stringify(serializeMetadata(metadata));
|
|
367
|
+
await this.writeFileAtomic(metadataPath, serialized);
|
|
368
|
+
hasMutation = true;
|
|
369
|
+
if (this.indexingEnabled) {
|
|
370
|
+
this.entries.set(entry.id, metadata);
|
|
371
|
+
if (!this.docIndex.has(entry.docId)) {
|
|
372
|
+
this.docIndex.set(entry.docId, new Set());
|
|
373
|
+
}
|
|
374
|
+
this.docIndex.get(entry.docId).add(entry.id);
|
|
375
|
+
this.contentRefCount.set(entry.contentHash, (this.contentRefCount.get(entry.contentHash) || 0) + 1);
|
|
376
|
+
this.insertOrderedMetadata(metadata);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
if (hasMutation && this.indexingEnabled) {
|
|
380
|
+
await this.persistMetadataIndex();
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
async getEntries(ids) {
|
|
384
|
+
await this.ensureInitialized();
|
|
385
|
+
const result = [];
|
|
386
|
+
for (const id of ids) {
|
|
387
|
+
const metadata = await this.readMetadataById(id);
|
|
388
|
+
if (!metadata) {
|
|
389
|
+
continue;
|
|
390
|
+
}
|
|
391
|
+
const contentPath = this.contentPathForHash(metadata.contentHash);
|
|
392
|
+
if (!(await this.fileExists(contentPath))) {
|
|
393
|
+
this.logger.warn(`Content ${metadata.contentHash} not found for entry ${id}`);
|
|
394
|
+
continue;
|
|
395
|
+
}
|
|
396
|
+
const encryptedData = new Uint8Array(await (0, promises_1.readFile)(contentPath));
|
|
397
|
+
result.push({ ...metadata, encryptedData });
|
|
398
|
+
}
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
async hasEntries(ids) {
|
|
402
|
+
await this.ensureInitialized();
|
|
403
|
+
const existing = [];
|
|
404
|
+
for (const id of ids) {
|
|
405
|
+
if (this.indexingEnabled) {
|
|
406
|
+
if (this.entries.has(id)) {
|
|
407
|
+
existing.push(id);
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
else {
|
|
411
|
+
if (await this.fileExists(this.metadataPathForId(id))) {
|
|
412
|
+
existing.push(id);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return existing;
|
|
417
|
+
}
|
|
418
|
+
async findNewEntries(knownIds) {
|
|
419
|
+
await this.ensureInitialized();
|
|
420
|
+
const known = new Set(knownIds);
|
|
421
|
+
const all = await this.listAllMetadata();
|
|
422
|
+
return all.filter((meta) => !known.has(meta.id));
|
|
423
|
+
}
|
|
424
|
+
async findNewEntriesForDoc(knownIds, docId) {
|
|
425
|
+
await this.ensureInitialized();
|
|
426
|
+
const known = new Set(knownIds);
|
|
427
|
+
if (this.indexingEnabled) {
|
|
428
|
+
const ids = this.docIndex.get(docId) || new Set();
|
|
429
|
+
const result = [];
|
|
430
|
+
for (const id of ids) {
|
|
431
|
+
if (known.has(id)) {
|
|
432
|
+
continue;
|
|
433
|
+
}
|
|
434
|
+
const metadata = this.entries.get(id);
|
|
435
|
+
if (metadata) {
|
|
436
|
+
result.push(metadata);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return result;
|
|
440
|
+
}
|
|
441
|
+
const all = await this.listAllMetadata();
|
|
442
|
+
return all.filter((meta) => meta.docId === docId && !known.has(meta.id));
|
|
443
|
+
}
|
|
444
|
+
async findEntries(type, creationDateFrom, creationDateUntil) {
|
|
445
|
+
await this.ensureInitialized();
|
|
446
|
+
const all = await this.listAllMetadata();
|
|
447
|
+
return all.filter((meta) => {
|
|
448
|
+
if (meta.entryType !== type) {
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
if (creationDateFrom !== null && meta.createdAt < creationDateFrom) {
|
|
452
|
+
return false;
|
|
453
|
+
}
|
|
454
|
+
if (creationDateUntil !== null && meta.createdAt >= creationDateUntil) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
return true;
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
async getAllIds() {
|
|
461
|
+
await this.ensureInitialized();
|
|
462
|
+
if (this.indexingEnabled) {
|
|
463
|
+
return this.orderedMetadata.map((m) => m.id);
|
|
464
|
+
}
|
|
465
|
+
const files = await this.listEntryFiles();
|
|
466
|
+
return files.map(fromEntryFileName);
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Cursor-based metadata scan for high-volume synchronization.
|
|
470
|
+
* Ordering: createdAt ASC, id ASC.
|
|
471
|
+
*/
|
|
472
|
+
async scanEntriesSince(cursor, limit = Number.MAX_SAFE_INTEGER, filters) {
|
|
473
|
+
await this.ensureInitialized();
|
|
474
|
+
if (this.indexingEnabled) {
|
|
475
|
+
const startIndex = this.lowerBoundForCursor(cursor);
|
|
476
|
+
if (!filters || Object.keys(filters).length === 0) {
|
|
477
|
+
const page = this.orderedMetadata.slice(startIndex, startIndex + limit);
|
|
478
|
+
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
479
|
+
return {
|
|
480
|
+
entries: page,
|
|
481
|
+
nextCursor: last ? { createdAt: last.createdAt, id: last.id } : cursor,
|
|
482
|
+
hasMore: startIndex + page.length < this.orderedMetadata.length,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
const page = [];
|
|
486
|
+
let idx = startIndex;
|
|
487
|
+
while (idx < this.orderedMetadata.length && page.length < limit) {
|
|
488
|
+
const meta = this.orderedMetadata[idx];
|
|
489
|
+
if (this.metadataMatchesFilters(meta, filters)) {
|
|
490
|
+
page.push(meta);
|
|
491
|
+
}
|
|
492
|
+
idx++;
|
|
493
|
+
}
|
|
494
|
+
let hasMore = false;
|
|
495
|
+
while (idx < this.orderedMetadata.length) {
|
|
496
|
+
if (this.metadataMatchesFilters(this.orderedMetadata[idx], filters)) {
|
|
497
|
+
hasMore = true;
|
|
498
|
+
break;
|
|
499
|
+
}
|
|
500
|
+
idx++;
|
|
501
|
+
}
|
|
502
|
+
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
503
|
+
return {
|
|
504
|
+
entries: page,
|
|
505
|
+
nextCursor: last ? { createdAt: last.createdAt, id: last.id } : cursor,
|
|
506
|
+
hasMore,
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
const all = (await this.listAllMetadata())
|
|
510
|
+
.filter((meta) => {
|
|
511
|
+
if (filters?.docId && meta.docId !== filters.docId) {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
if (filters?.entryTypes && filters.entryTypes.length > 0 && !filters.entryTypes.includes(meta.entryType)) {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
if (filters?.creationDateFrom !== undefined && filters.creationDateFrom !== null && meta.createdAt < filters.creationDateFrom) {
|
|
518
|
+
return false;
|
|
519
|
+
}
|
|
520
|
+
if (filters?.creationDateUntil !== undefined && filters.creationDateUntil !== null && meta.createdAt >= filters.creationDateUntil) {
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
return true;
|
|
524
|
+
})
|
|
525
|
+
.sort((a, b) => (a.createdAt === b.createdAt ? a.id.localeCompare(b.id) : a.createdAt - b.createdAt));
|
|
526
|
+
const startIndex = cursor === null
|
|
527
|
+
? 0
|
|
528
|
+
: all.findIndex((meta) => meta.createdAt > cursor.createdAt || (meta.createdAt === cursor.createdAt && meta.id > cursor.id));
|
|
529
|
+
if (startIndex === -1) {
|
|
530
|
+
return { entries: [], nextCursor: cursor, hasMore: false };
|
|
531
|
+
}
|
|
532
|
+
const page = all.slice(startIndex, startIndex + limit);
|
|
533
|
+
const last = page.length > 0 ? page[page.length - 1] : null;
|
|
534
|
+
return {
|
|
535
|
+
entries: page,
|
|
536
|
+
nextCursor: last ? { createdAt: last.createdAt, id: last.id } : cursor,
|
|
537
|
+
hasMore: startIndex + page.length < all.length,
|
|
538
|
+
};
|
|
539
|
+
}
|
|
540
|
+
async getIdBloomSummary() {
|
|
541
|
+
await this.ensureInitialized();
|
|
542
|
+
const ids = await this.getAllIds();
|
|
543
|
+
return (0, bloom_1.createIdBloomSummary)(ids);
|
|
544
|
+
}
|
|
545
|
+
async resolveDependencies(startId, options) {
|
|
546
|
+
await this.ensureInitialized();
|
|
547
|
+
const stopAtEntryType = options?.stopAtEntryType;
|
|
548
|
+
const maxDepth = options?.maxDepth;
|
|
549
|
+
const includeStart = options?.includeStart !== false;
|
|
550
|
+
const result = [];
|
|
551
|
+
const visited = new Set();
|
|
552
|
+
const queue = [{ id: startId, depth: 0 }];
|
|
553
|
+
while (queue.length > 0) {
|
|
554
|
+
const { id, depth } = queue.shift();
|
|
555
|
+
if (visited.has(id)) {
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
visited.add(id);
|
|
559
|
+
if (maxDepth !== undefined && depth > maxDepth) {
|
|
560
|
+
continue;
|
|
561
|
+
}
|
|
562
|
+
const entry = await this.readMetadataById(id);
|
|
563
|
+
if (!entry) {
|
|
564
|
+
continue;
|
|
565
|
+
}
|
|
566
|
+
if (stopAtEntryType && entry.entryType === stopAtEntryType && id !== startId) {
|
|
567
|
+
result.push(id);
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
if (id !== startId || includeStart) {
|
|
571
|
+
result.push(id);
|
|
572
|
+
}
|
|
573
|
+
for (const depId of entry.dependencyIds) {
|
|
574
|
+
if (!visited.has(depId)) {
|
|
575
|
+
queue.push({ id: depId, depth: depth + 1 });
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
result.reverse();
|
|
580
|
+
return result;
|
|
581
|
+
}
|
|
582
|
+
async purgeDocHistory(docId) {
|
|
583
|
+
await this.ensureInitialized();
|
|
584
|
+
const all = await this.listAllMetadata();
|
|
585
|
+
const toDelete = all.filter((meta) => meta.docId === docId);
|
|
586
|
+
if (toDelete.length === 0) {
|
|
587
|
+
return;
|
|
588
|
+
}
|
|
589
|
+
const deletedHashes = new Set();
|
|
590
|
+
for (const meta of toDelete) {
|
|
591
|
+
deletedHashes.add(meta.contentHash);
|
|
592
|
+
const metadataPath = this.metadataPathForId(meta.id);
|
|
593
|
+
await (0, promises_1.unlink)(metadataPath).catch(() => {
|
|
594
|
+
// Ignore races or already-deleted files.
|
|
595
|
+
});
|
|
596
|
+
await this.syncParentDirectory(metadataPath);
|
|
597
|
+
if (this.indexingEnabled) {
|
|
598
|
+
this.entries.delete(meta.id);
|
|
599
|
+
this.docIndex.get(docId)?.delete(meta.id);
|
|
600
|
+
this.removeOrderedMetadataById(meta.id);
|
|
601
|
+
const nextRef = (this.contentRefCount.get(meta.contentHash) || 1) - 1;
|
|
602
|
+
if (nextRef <= 0) {
|
|
603
|
+
this.contentRefCount.delete(meta.contentHash);
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
this.contentRefCount.set(meta.contentHash, nextRef);
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
if (this.indexingEnabled && (this.docIndex.get(docId)?.size || 0) === 0) {
|
|
611
|
+
this.docIndex.delete(docId);
|
|
612
|
+
}
|
|
613
|
+
const remaining = await this.listAllMetadata();
|
|
614
|
+
const remainingHashes = new Set(remaining.map((m) => m.contentHash));
|
|
615
|
+
for (const hash of deletedHashes) {
|
|
616
|
+
if (!remainingHashes.has(hash)) {
|
|
617
|
+
const contentPath = this.contentPathForHash(hash);
|
|
618
|
+
await (0, promises_1.unlink)(contentPath).catch(() => {
|
|
619
|
+
// Ignore races or already-deleted files.
|
|
620
|
+
});
|
|
621
|
+
await this.syncParentDirectory(contentPath);
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
if (this.indexingEnabled) {
|
|
625
|
+
await this.persistMetadataIndex();
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
async clearAllLocalData() {
|
|
629
|
+
await this.ensureInitialized();
|
|
630
|
+
this.indexStatus = {
|
|
631
|
+
phase: this.indexingEnabled ? "building" : "ready",
|
|
632
|
+
indexingEnabled: this.indexingEnabled,
|
|
633
|
+
progress01: this.indexingEnabled ? 0 : 1,
|
|
634
|
+
};
|
|
635
|
+
await this.clearAllLocalDataInternal();
|
|
636
|
+
await (0, promises_1.mkdir)(this.entriesDir, { recursive: true });
|
|
637
|
+
await (0, promises_1.mkdir)(this.contentDir, { recursive: true });
|
|
638
|
+
if (this.indexingEnabled) {
|
|
639
|
+
this.indexStatus = { phase: "ready", indexingEnabled: true, progress01: 1 };
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
async awaitIndexReady(_options) {
|
|
643
|
+
await this.ensureInitialized();
|
|
644
|
+
return this.indexStatus;
|
|
645
|
+
}
|
|
646
|
+
getIndexBuildStatus() {
|
|
647
|
+
return this.indexStatus;
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
exports.BasicOnDiskContentAddressedStore = BasicOnDiskContentAddressedStore;
|
|
651
|
+
class BasicOnDiskContentAddressedStoreFactory {
|
|
652
|
+
createStore(dbId, options) {
|
|
653
|
+
return {
|
|
654
|
+
docStore: new BasicOnDiskContentAddressedStore(dbId, undefined, options),
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
exports.BasicOnDiskContentAddressedStoreFactory = BasicOnDiskContentAddressedStoreFactory;
|
|
659
|
+
//# sourceMappingURL=BasicOnDiskContentAddressedStore.js.map
|