mindoodb 0.0.89 → 0.0.91
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 +1 -0
- package/dist/browser/index.mjs +15 -0
- package/dist/core/BaseMindooDB.d.ts +18 -0
- package/dist/core/BaseMindooDB.d.ts.map +1 -1
- package/dist/core/BaseMindooDB.js +57 -0
- package/dist/core/BaseMindooDB.js.map +1 -1
- package/dist/core/BaseMindooTenant.d.ts +3 -0
- package/dist/core/BaseMindooTenant.d.ts.map +1 -1
- package/dist/core/BaseMindooTenant.js +28 -0
- package/dist/core/BaseMindooTenant.js.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts +2 -1
- package/dist/core/BaseMindooTenantDirectory.d.ts.map +1 -1
- package/dist/core/BaseMindooTenantDirectory.js +10 -2
- package/dist/core/BaseMindooTenantDirectory.js.map +1 -1
- package/dist/core/expressions/builder.d.ts +30 -0
- package/dist/core/expressions/builder.d.ts.map +1 -1
- package/dist/core/expressions/builder.js +42 -0
- package/dist/core/expressions/builder.js.map +1 -1
- package/dist/core/expressions/evaluateExpression.d.ts +10 -0
- package/dist/core/expressions/evaluateExpression.d.ts.map +1 -1
- package/dist/core/expressions/evaluateExpression.js +66 -1
- package/dist/core/expressions/evaluateExpression.js.map +1 -1
- package/dist/core/expressions/formulaSource.d.ts.map +1 -1
- package/dist/core/expressions/formulaSource.js +5 -0
- package/dist/core/expressions/formulaSource.js.map +1 -1
- package/dist/core/expressions/index.d.ts +1 -1
- package/dist/core/expressions/index.d.ts.map +1 -1
- package/dist/core/expressions/index.js +2 -1
- package/dist/core/expressions/index.js.map +1 -1
- package/dist/core/expressions/metadata.d.ts +2 -2
- package/dist/core/expressions/metadata.d.ts.map +1 -1
- package/dist/core/expressions/metadata.js +14 -0
- package/dist/core/expressions/metadata.js.map +1 -1
- package/dist/core/expressions/types.d.ts +1 -1
- package/dist/core/expressions/types.d.ts.map +1 -1
- package/dist/core/filing/FilingIndex.d.ts +209 -0
- package/dist/core/filing/FilingIndex.d.ts.map +1 -0
- package/dist/core/filing/FilingIndex.js +689 -0
- package/dist/core/filing/FilingIndex.js.map +1 -0
- package/dist/core/filing/MindooFilingStore.d.ts +200 -0
- package/dist/core/filing/MindooFilingStore.d.ts.map +1 -0
- package/dist/core/filing/MindooFilingStore.js +515 -0
- package/dist/core/filing/MindooFilingStore.js.map +1 -0
- package/dist/core/filing/index.d.ts +4 -0
- package/dist/core/filing/index.d.ts.map +1 -0
- package/dist/core/filing/index.js +22 -0
- package/dist/core/filing/index.js.map +1 -0
- package/dist/core/filing/refs.d.ts +56 -0
- package/dist/core/filing/refs.d.ts.map +1 -0
- package/dist/core/filing/refs.js +109 -0
- package/dist/core/filing/refs.js.map +1 -0
- package/dist/core/index.d.ts +2 -1
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +5 -2
- package/dist/core/index.js.map +1 -1
- package/dist/core/indexing/createViewDataProvider.d.ts +6 -0
- package/dist/core/indexing/createViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/createViewDataProvider.js +26 -1
- package/dist/core/indexing/createViewDataProvider.js.map +1 -1
- package/dist/core/indexing/summary/DocumentSummaryStore.d.ts +43 -1
- package/dist/core/indexing/summary/DocumentSummaryStore.d.ts.map +1 -1
- package/dist/core/indexing/summary/DocumentSummaryStore.js +302 -2
- package/dist/core/indexing/summary/DocumentSummaryStore.js.map +1 -1
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts +33 -2
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js +129 -26
- package/dist/core/indexing/summary/SummaryVirtualViewDataProvider.js.map +1 -1
- package/dist/core/indexing/summary/types.d.ts +40 -0
- package/dist/core/indexing/summary/types.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts +27 -2
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js +106 -1
- package/dist/core/indexing/virtualviews/MindooDBVirtualViewDataProvider.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.d.ts +70 -5
- package/dist/core/indexing/virtualviews/VirtualView.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualView.js +329 -28
- package/dist/core/indexing/virtualviews/VirtualView.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts +4 -22
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js +175 -129
- package/dist/core/indexing/virtualviews/VirtualViewEntryData.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts +28 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js +62 -0
- package/dist/core/indexing/virtualviews/VirtualViewFactory.js.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewFilingJoin.d.ts +75 -0
- package/dist/core/indexing/virtualviews/VirtualViewFilingJoin.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewFilingJoin.js +163 -0
- package/dist/core/indexing/virtualviews/VirtualViewFilingJoin.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewMergedNavigator.d.ts +112 -0
- package/dist/core/indexing/virtualviews/VirtualViewMergedNavigator.d.ts.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewMergedNavigator.js +296 -0
- package/dist/core/indexing/virtualviews/VirtualViewMergedNavigator.js.map +1 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts +2 -0
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js +10 -9
- package/dist/core/indexing/virtualviews/VirtualViewNavigator.js.map +1 -1
- package/dist/core/indexing/virtualviews/index.d.ts +2 -0
- package/dist/core/indexing/virtualviews/index.d.ts.map +1 -1
- package/dist/core/indexing/virtualviews/index.js +8 -1
- package/dist/core/indexing/virtualviews/index.js.map +1 -1
- package/dist/core/query/executeQuery.d.ts.map +1 -1
- package/dist/core/query/executeQuery.js +4 -0
- package/dist/core/query/executeQuery.js.map +1 -1
- package/dist/core/query/executeQueryInclude.d.ts.map +1 -1
- package/dist/core/query/executeQueryInclude.js +4 -0
- package/dist/core/query/executeQueryInclude.js.map +1 -1
- package/dist/core/query/queryView.d.ts.map +1 -1
- package/dist/core/query/queryView.js +4 -0
- package/dist/core/query/queryView.js.map +1 -1
- package/dist/core/types.d.ts +20 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MindooFilingStore = exports.DEFAULT_FILING_PRUNE_GRACE_MS = void 0;
|
|
4
|
+
const values_1 = require("../values");
|
|
5
|
+
const errors_1 = require("../errors");
|
|
6
|
+
const idGeneration_1 = require("../utils/idGeneration");
|
|
7
|
+
const FilingIndex_1 = require("./FilingIndex");
|
|
8
|
+
const refs_1 = require("./refs");
|
|
9
|
+
/** Default grace period before deleted documents leave their folders: 30 days. */
|
|
10
|
+
exports.DEFAULT_FILING_PRUNE_GRACE_MS = 30 * 24 * 60 * 60 * 1000;
|
|
11
|
+
/** Folder ids are category values: no backslash (category path separator), no control characters. */
|
|
12
|
+
const FOLDER_ID_REGEX = /^[^\\\u0000-\u001f]{1,200}$/;
|
|
13
|
+
function assertFolderId(folderId) {
|
|
14
|
+
if (typeof folderId !== "string" || !FOLDER_ID_REGEX.test(folderId)) {
|
|
15
|
+
throw new Error(`Invalid folder id ${JSON.stringify(folderId)}: 1-200 characters, no backslash and no control characters.`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function toFolderIdList(folderIds) {
|
|
19
|
+
const list = Array.isArray(folderIds) ? folderIds : [folderIds];
|
|
20
|
+
for (const folderId of list) {
|
|
21
|
+
assertFolderId(folderId);
|
|
22
|
+
}
|
|
23
|
+
return list;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* A filing store ("Ablage-Satz"): named set of folders in a database, with
|
|
27
|
+
* the documents filed into them. Obtain it via `db.filing(store)`.
|
|
28
|
+
*
|
|
29
|
+
* Filing never changes the filed document. Each filed document gets one
|
|
30
|
+
* small sidecar document in the filing database holding its folders as
|
|
31
|
+
* fields `f:<folderId> = filedAt` (see {@link FILING_FOLDER_FIELD_PREFIX});
|
|
32
|
+
* moving a document between folders is one small
|
|
33
|
+
* change of that sidecar. Hence filing only needs write access to the
|
|
34
|
+
* filing database — read access to the target suffices — and works across
|
|
35
|
+
* databases and tenants (see the reference format in `refs.ts`). The
|
|
36
|
+
* sidecar's id is a keyed hash of store + target (deterministic, so
|
|
37
|
+
* concurrent first filings on two replicas converge on one document, and
|
|
38
|
+
* opaque to anyone without the database key).
|
|
39
|
+
*
|
|
40
|
+
* Folder definitions are documents of the same store (`$folder`). Folder
|
|
41
|
+
* membership of sidecars whose folder was deleted is ignored.
|
|
42
|
+
*/
|
|
43
|
+
class MindooFilingStore {
|
|
44
|
+
/** @internal Use `db.filing(store)`. */
|
|
45
|
+
constructor(db, store, options, onIndexCreated) {
|
|
46
|
+
this.autoPruneRunning = null;
|
|
47
|
+
this.autoPrunePending = false;
|
|
48
|
+
this.idPrefix = null;
|
|
49
|
+
this.index = null;
|
|
50
|
+
this.initPromise = null;
|
|
51
|
+
if (typeof store !== "string" || !store) {
|
|
52
|
+
throw new Error("db.filing(store): store must be a non-empty string.");
|
|
53
|
+
}
|
|
54
|
+
this.db = db;
|
|
55
|
+
this.store = store;
|
|
56
|
+
this.decryptionKeyId = options?.decryptionKeyId ?? "default";
|
|
57
|
+
this.pruneGracePeriodMs = Math.max(0, options?.pruneGracePeriodMs ?? exports.DEFAULT_FILING_PRUNE_GRACE_MS);
|
|
58
|
+
this.autoPrune = options?.autoPrune !== false;
|
|
59
|
+
this.base = { tenantId: db.getTenant().getId(), dbId: db.getStore().getId() };
|
|
60
|
+
this.onIndexCreated = onIndexCreated;
|
|
61
|
+
}
|
|
62
|
+
/** Name of this filing store. */
|
|
63
|
+
getName() {
|
|
64
|
+
return this.store;
|
|
65
|
+
}
|
|
66
|
+
/** The filing database. */
|
|
67
|
+
getDatabase() {
|
|
68
|
+
return this.db;
|
|
69
|
+
}
|
|
70
|
+
/** Key id the store's documents are encrypted with. */
|
|
71
|
+
getDecryptionKeyId() {
|
|
72
|
+
return this.decryptionKeyId;
|
|
73
|
+
}
|
|
74
|
+
async hash(kind, data) {
|
|
75
|
+
const tenant = this.db.getTenant();
|
|
76
|
+
if (!tenant.computeKeyedHash) {
|
|
77
|
+
throw new Error("Filing needs a tenant implementation with computeKeyedHash().");
|
|
78
|
+
}
|
|
79
|
+
return tenant.computeKeyedHash(this.decryptionKeyId, `filing/${kind}`, data);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The membership index of this store (created and brought up to date
|
|
83
|
+
* lazily). Shared by every view joining the store.
|
|
84
|
+
*/
|
|
85
|
+
async getIndex() {
|
|
86
|
+
if (!this.initPromise) {
|
|
87
|
+
this.initPromise = (async () => {
|
|
88
|
+
const storeTag = (await this.hash("store", this.store)).slice(0, 16);
|
|
89
|
+
this.idPrefix = `fil_${storeTag}`;
|
|
90
|
+
this.index = new FilingIndex_1.FilingIndex(this.db, this.store, this.idPrefix);
|
|
91
|
+
this.onIndexCreated?.(this.index);
|
|
92
|
+
if (this.autoPrune) {
|
|
93
|
+
// Deleted documents of this database leave their folders once the
|
|
94
|
+
// grace period is over — checked whenever the index changes.
|
|
95
|
+
this.index.onDidChange(() => this.scheduleAutoPrune());
|
|
96
|
+
}
|
|
97
|
+
return this.index;
|
|
98
|
+
})();
|
|
99
|
+
this.initPromise.catch(() => {
|
|
100
|
+
this.initPromise = null;
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
return this.initPromise;
|
|
104
|
+
}
|
|
105
|
+
/** The index, brought up to date with the filing database. */
|
|
106
|
+
async currentIndex() {
|
|
107
|
+
const index = await this.getIndex();
|
|
108
|
+
await index.update();
|
|
109
|
+
return index;
|
|
110
|
+
}
|
|
111
|
+
/** Resolve a reference to the physical identity of the filed document. */
|
|
112
|
+
resolveRef(ref) {
|
|
113
|
+
return (0, refs_1.resolveFilingRef)(ref, this.base);
|
|
114
|
+
}
|
|
115
|
+
/** The reference string stored for `ref` (relative to the filing database). */
|
|
116
|
+
formatRef(ref) {
|
|
117
|
+
return (0, refs_1.formatFilingRef)(this.resolveRef(ref), this.base);
|
|
118
|
+
}
|
|
119
|
+
async sidecarIdFor(physRef) {
|
|
120
|
+
await this.getIndex();
|
|
121
|
+
return `${this.idPrefix}_r${(await this.hash("sidecar", `${this.store}\n${physRef}`)).slice(0, 32)}`;
|
|
122
|
+
}
|
|
123
|
+
async folderDocIdFor(folderId) {
|
|
124
|
+
await this.getIndex();
|
|
125
|
+
return `${this.idPrefix}_f${(await this.hash("folder", `${this.store}\n${folderId}`)).slice(0, 32)}`;
|
|
126
|
+
}
|
|
127
|
+
/** Every sidecar of a document: the deterministic one plus any the index knows. */
|
|
128
|
+
async sidecarIdsFor(index, physRef) {
|
|
129
|
+
const ids = new Set(index.sidecarIdsOf(physRef));
|
|
130
|
+
ids.add(await this.sidecarIdFor(physRef));
|
|
131
|
+
return Array.from(ids);
|
|
132
|
+
}
|
|
133
|
+
async openSidecar(sidecarId, target) {
|
|
134
|
+
// Idempotent create: returns the existing sidecar (reviving a deleted one).
|
|
135
|
+
const doc = await this.db.createDocument({ id: sidecarId, decryptionKeyId: this.decryptionKeyId });
|
|
136
|
+
const data = doc.getData();
|
|
137
|
+
if (data.type !== FilingIndex_1.FILING_SIDECAR_TYPE || data.store !== this.store || typeof data.ref !== "string") {
|
|
138
|
+
await this.db.changeDoc(doc, (d) => {
|
|
139
|
+
const values = d.getData();
|
|
140
|
+
values.type = values_1.MindooValue.atomic(FilingIndex_1.FILING_SIDECAR_TYPE);
|
|
141
|
+
values.store = values_1.MindooValue.atomic(this.store);
|
|
142
|
+
values.ref = values_1.MindooValue.atomic((0, refs_1.formatFilingRef)(target, this.base));
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
return doc;
|
|
146
|
+
}
|
|
147
|
+
async tryGetDocument(docId) {
|
|
148
|
+
try {
|
|
149
|
+
const doc = await this.db.getDocument(docId);
|
|
150
|
+
return doc.isDeleted() ? null : doc;
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* File a document into one or more folders. Already-present folders keep
|
|
158
|
+
* their original filed-at time.
|
|
159
|
+
*/
|
|
160
|
+
async add(ref, folderIds) {
|
|
161
|
+
const ids = toFolderIdList(folderIds);
|
|
162
|
+
const target = this.resolveRef(ref);
|
|
163
|
+
const physRef = (0, refs_1.physicalFilingRefKey)(target);
|
|
164
|
+
const sidecarId = await this.sidecarIdFor(physRef);
|
|
165
|
+
const doc = await this.openSidecar(sidecarId, target);
|
|
166
|
+
const now = Date.now();
|
|
167
|
+
const current = doc.getData();
|
|
168
|
+
const missing = ids.filter((folderId) => !Object.prototype.hasOwnProperty.call(current, FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId));
|
|
169
|
+
if (missing.length === 0) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
await this.db.changeDoc(doc, (d) => {
|
|
173
|
+
const values = d.getData();
|
|
174
|
+
for (const folderId of missing) {
|
|
175
|
+
if (!Object.prototype.hasOwnProperty.call(values, FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId)) {
|
|
176
|
+
values[FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId] = now;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Remove a document from one or more folders; without `folderIds` from
|
|
183
|
+
* every folder of this store. The sidecar stays (with an empty map) so a
|
|
184
|
+
* later re-filing changes the same document.
|
|
185
|
+
*/
|
|
186
|
+
async remove(ref, folderIds) {
|
|
187
|
+
const ids = folderIds === undefined ? null : toFolderIdList(folderIds);
|
|
188
|
+
const target = this.resolveRef(ref);
|
|
189
|
+
const index = await this.currentIndex();
|
|
190
|
+
await this.removeFromSidecars(index, (0, refs_1.physicalFilingRefKey)(target), ids);
|
|
191
|
+
}
|
|
192
|
+
async removeFromSidecars(index, physRef, ids) {
|
|
193
|
+
for (const sidecarId of await this.sidecarIdsFor(index, physRef)) {
|
|
194
|
+
const doc = await this.tryGetDocument(sidecarId);
|
|
195
|
+
if (!doc)
|
|
196
|
+
continue;
|
|
197
|
+
const present = Object.keys((0, FilingIndex_1.readFolderFields)(doc.getData()));
|
|
198
|
+
const toRemove = ids === null ? present : ids.filter((folderId) => present.includes(folderId));
|
|
199
|
+
if (toRemove.length === 0)
|
|
200
|
+
continue;
|
|
201
|
+
await this.db.changeDoc(doc, (d) => {
|
|
202
|
+
const values = d.getData();
|
|
203
|
+
for (const folderId of toRemove) {
|
|
204
|
+
delete values[FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId];
|
|
205
|
+
}
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Take deleted documents out of all their folders (their memberships are
|
|
211
|
+
* removed; the sidecar stays, so re-filing reuses it).
|
|
212
|
+
*
|
|
213
|
+
* Only documents that are really deleted, and deleted longer ago than the
|
|
214
|
+
* grace period: a document this device cannot read, or whose database is
|
|
215
|
+
* not given/open, is never touched — otherwise a device without the key
|
|
216
|
+
* would empty a shared filing store. Checked are the filing database's own
|
|
217
|
+
* documents and those of `options.databases`.
|
|
218
|
+
*/
|
|
219
|
+
async prune(options) {
|
|
220
|
+
const index = await this.currentIndex();
|
|
221
|
+
const now = options?.now ?? Date.now();
|
|
222
|
+
const grace = Math.max(0, options?.gracePeriodMs ?? this.pruneGracePeriodMs);
|
|
223
|
+
const databases = new Map();
|
|
224
|
+
for (const db of [this.db, ...(options?.databases ?? [])]) {
|
|
225
|
+
databases.set(`${db.getTenant().getId()}/${db.getStore().getId()}`, db);
|
|
226
|
+
}
|
|
227
|
+
const byDb = new Map();
|
|
228
|
+
for (const physRef of index.allSidecarRefs()) {
|
|
229
|
+
const target = (0, refs_1.parsePhysicalFilingRefKey)(physRef);
|
|
230
|
+
const dbKey = `${target.tenantId}/${target.dbId}`;
|
|
231
|
+
if (!databases.has(dbKey))
|
|
232
|
+
continue;
|
|
233
|
+
let docIds = byDb.get(dbKey);
|
|
234
|
+
if (!docIds) {
|
|
235
|
+
docIds = [];
|
|
236
|
+
byDb.set(dbKey, docIds);
|
|
237
|
+
}
|
|
238
|
+
docIds.push(target.docId);
|
|
239
|
+
}
|
|
240
|
+
let removed = 0;
|
|
241
|
+
let pending = 0;
|
|
242
|
+
for (const [dbKey, docIds] of byDb) {
|
|
243
|
+
const db = databases.get(dbKey);
|
|
244
|
+
const deletedAt = await deletionTimes(db, new Set(docIds));
|
|
245
|
+
for (const [docId, at] of deletedAt) {
|
|
246
|
+
if (now - at < grace) {
|
|
247
|
+
pending++;
|
|
248
|
+
continue;
|
|
249
|
+
}
|
|
250
|
+
if (!(await isReallyDeleted(db, docId)))
|
|
251
|
+
continue;
|
|
252
|
+
await this.removeFromSidecars(index, `${dbKey}/${docId}`, null);
|
|
253
|
+
removed++;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return { removed, pending };
|
|
257
|
+
}
|
|
258
|
+
/** Background cleanup for deleted documents of the filing database (single-flight). */
|
|
259
|
+
scheduleAutoPrune() {
|
|
260
|
+
if (this.autoPruneRunning) {
|
|
261
|
+
this.autoPrunePending = true;
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
const index = this.index;
|
|
265
|
+
if (!index || index.getDeletedTargets().size === 0)
|
|
266
|
+
return;
|
|
267
|
+
const holder = {};
|
|
268
|
+
holder.run = (async () => {
|
|
269
|
+
// Yield first: the run must be registered before it can finish.
|
|
270
|
+
await Promise.resolve();
|
|
271
|
+
try {
|
|
272
|
+
do {
|
|
273
|
+
this.autoPrunePending = false;
|
|
274
|
+
const now = Date.now();
|
|
275
|
+
const due = [...index.getDeletedTargets()].filter(([, at]) => now - at >= this.pruneGracePeriodMs);
|
|
276
|
+
for (const [physRef] of due) {
|
|
277
|
+
const target = (0, refs_1.parsePhysicalFilingRefKey)(physRef);
|
|
278
|
+
if (await isReallyDeleted(this.db, target.docId)) {
|
|
279
|
+
await this.removeFromSidecars(index, physRef, null);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
} while (this.autoPrunePending);
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// Best effort (e.g. no write access to the filing database).
|
|
286
|
+
}
|
|
287
|
+
finally {
|
|
288
|
+
if (this.autoPruneRunning === holder.run) {
|
|
289
|
+
this.autoPruneRunning = null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
})();
|
|
293
|
+
this.autoPruneRunning = holder.run;
|
|
294
|
+
}
|
|
295
|
+
/** Wait for a running background cleanup (tests). */
|
|
296
|
+
async whenIdle() {
|
|
297
|
+
while (this.autoPruneRunning) {
|
|
298
|
+
await this.autoPruneRunning;
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Move a document from one folder to another — one change of one small
|
|
303
|
+
* sidecar. Without `from` the document leaves every other folder of this
|
|
304
|
+
* store (a "move to" in the single-folder sense).
|
|
305
|
+
*/
|
|
306
|
+
async move(ref, options) {
|
|
307
|
+
const toIds = toFolderIdList(options.to);
|
|
308
|
+
const fromIds = options.from === undefined ? null : toFolderIdList(options.from);
|
|
309
|
+
const target = this.resolveRef(ref);
|
|
310
|
+
const physRef = (0, refs_1.physicalFilingRefKey)(target);
|
|
311
|
+
const index = await this.currentIndex();
|
|
312
|
+
const primaryId = await this.sidecarIdFor(physRef);
|
|
313
|
+
const now = Date.now();
|
|
314
|
+
// Primary sidecar: remove + add in ONE change, so a concurrent reader
|
|
315
|
+
// never sees the document in neither (or both) folders.
|
|
316
|
+
const primary = await this.openSidecar(primaryId, target);
|
|
317
|
+
await this.db.changeDoc(primary, (d) => {
|
|
318
|
+
const values = d.getData();
|
|
319
|
+
const present = Object.keys((0, FilingIndex_1.readFolderFields)(values));
|
|
320
|
+
const removeIds = fromIds ?? present;
|
|
321
|
+
for (const folderId of removeIds) {
|
|
322
|
+
if (!toIds.includes(folderId) && present.includes(folderId)) {
|
|
323
|
+
delete values[FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId];
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
for (const folderId of toIds) {
|
|
327
|
+
if (!present.includes(folderId)) {
|
|
328
|
+
values[FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId] = now;
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
});
|
|
332
|
+
// Secondary sidecars (rare): just drop the moved-from folders.
|
|
333
|
+
const secondary = index.sidecarIdsOf(physRef).filter((id) => id !== primaryId);
|
|
334
|
+
for (const sidecarId of secondary) {
|
|
335
|
+
const doc = await this.tryGetDocument(sidecarId);
|
|
336
|
+
if (!doc)
|
|
337
|
+
continue;
|
|
338
|
+
const present = Object.keys((0, FilingIndex_1.readFolderFields)(doc.getData()));
|
|
339
|
+
const removeIds = (fromIds ?? present).filter((folderId) => !toIds.includes(folderId) && present.includes(folderId));
|
|
340
|
+
if (removeIds.length === 0)
|
|
341
|
+
continue;
|
|
342
|
+
await this.db.changeDoc(doc, (d) => {
|
|
343
|
+
const values = d.getData();
|
|
344
|
+
for (const folderId of removeIds) {
|
|
345
|
+
delete values[FilingIndex_1.FILING_FOLDER_FIELD_PREFIX + folderId];
|
|
346
|
+
}
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
/** Folder ids a document is filed in (deleted folders left out), sorted. */
|
|
351
|
+
async foldersOf(ref) {
|
|
352
|
+
const index = await this.currentIndex();
|
|
353
|
+
return [...index.foldersOf((0, refs_1.physicalFilingRefKey)(this.resolveRef(ref)))];
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* The documents filed in a folder, read from the index — no view needed.
|
|
357
|
+
* Sorted by filed-at time (oldest first).
|
|
358
|
+
*/
|
|
359
|
+
async *contents(folderId) {
|
|
360
|
+
assertFolderId(folderId);
|
|
361
|
+
const index = await this.currentIndex();
|
|
362
|
+
const entries = index.membersOf(folderId).map((physRef) => {
|
|
363
|
+
const target = (0, refs_1.parsePhysicalFilingRefKey)(physRef);
|
|
364
|
+
return {
|
|
365
|
+
ref: (0, refs_1.formatFilingRef)(target, this.base),
|
|
366
|
+
target,
|
|
367
|
+
filedAt: index.filedAt(physRef, folderId) ?? 0,
|
|
368
|
+
};
|
|
369
|
+
});
|
|
370
|
+
entries.sort((a, b) => a.filedAt - b.filedAt || a.ref.localeCompare(b.ref));
|
|
371
|
+
for (const entry of entries) {
|
|
372
|
+
yield entry;
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
/** Number of documents in a folder. */
|
|
376
|
+
async count(folderId) {
|
|
377
|
+
assertFolderId(folderId);
|
|
378
|
+
return (await this.currentIndex()).membersOf(folderId).length;
|
|
379
|
+
}
|
|
380
|
+
// ---------------------------------------------------------------------------
|
|
381
|
+
// Folder definitions
|
|
382
|
+
// ---------------------------------------------------------------------------
|
|
383
|
+
/** Create a folder (or revive a deleted one with the same `folderId`). */
|
|
384
|
+
async createFolder(input) {
|
|
385
|
+
if (typeof input?.name !== "string" || !input.name.trim()) {
|
|
386
|
+
throw new Error("createFolder: name must be a non-empty string.");
|
|
387
|
+
}
|
|
388
|
+
const folderId = input.folderId ?? `fld_${(0, idGeneration_1.generateRandomUuid)().replace(/-/g, "").slice(0, 24)}`;
|
|
389
|
+
assertFolderId(folderId);
|
|
390
|
+
if (input.parentId)
|
|
391
|
+
assertFolderId(input.parentId);
|
|
392
|
+
const doc = await this.db.createDocument({
|
|
393
|
+
id: await this.folderDocIdFor(folderId),
|
|
394
|
+
decryptionKeyId: this.decryptionKeyId,
|
|
395
|
+
});
|
|
396
|
+
await this.db.changeDoc(doc, (d) => {
|
|
397
|
+
const values = d.getData();
|
|
398
|
+
values.type = values_1.MindooValue.atomic(FilingIndex_1.FILING_FOLDER_TYPE);
|
|
399
|
+
values.store = values_1.MindooValue.atomic(this.store);
|
|
400
|
+
values.folderId = values_1.MindooValue.atomic(folderId);
|
|
401
|
+
values.name = values_1.MindooValue.atomic(input.name);
|
|
402
|
+
setOptionalAtomic(values, "parentId", input.parentId);
|
|
403
|
+
setOptionalAtomic(values, "role", input.role);
|
|
404
|
+
setOptionalAtomic(values, "design", input.design);
|
|
405
|
+
values.deleted = false;
|
|
406
|
+
});
|
|
407
|
+
return {
|
|
408
|
+
folderId,
|
|
409
|
+
name: input.name,
|
|
410
|
+
parentId: input.parentId ?? null,
|
|
411
|
+
role: input.role ?? null,
|
|
412
|
+
design: input.design ?? null,
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
/** Change a folder's name, parent, role or design. */
|
|
416
|
+
async updateFolder(folderId, changes) {
|
|
417
|
+
assertFolderId(folderId);
|
|
418
|
+
const doc = await this.tryGetDocument(await this.folderDocIdFor(folderId));
|
|
419
|
+
if (!doc || doc.getData().type !== FilingIndex_1.FILING_FOLDER_TYPE) {
|
|
420
|
+
throw new Error(`Folder "${folderId}" does not exist in filing store "${this.store}".`);
|
|
421
|
+
}
|
|
422
|
+
if (changes.name !== undefined && (typeof changes.name !== "string" || !changes.name.trim())) {
|
|
423
|
+
throw new Error("updateFolder: name must be a non-empty string.");
|
|
424
|
+
}
|
|
425
|
+
if (changes.parentId)
|
|
426
|
+
assertFolderId(changes.parentId);
|
|
427
|
+
await this.db.changeDoc(doc, (d) => {
|
|
428
|
+
const values = d.getData();
|
|
429
|
+
if (changes.name !== undefined)
|
|
430
|
+
values.name = values_1.MindooValue.atomic(changes.name);
|
|
431
|
+
if (changes.parentId !== undefined)
|
|
432
|
+
setOptionalAtomic(values, "parentId", changes.parentId);
|
|
433
|
+
if (changes.role !== undefined)
|
|
434
|
+
setOptionalAtomic(values, "role", changes.role);
|
|
435
|
+
if (changes.design !== undefined)
|
|
436
|
+
setOptionalAtomic(values, "design", changes.design);
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
/** Rename a folder. Views categorize by folder id, so no filed row changes. */
|
|
440
|
+
async renameFolder(folderId, name) {
|
|
441
|
+
await this.updateFolder(folderId, { name });
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Delete a folder. The definition is marked deleted (so membership keys a
|
|
445
|
+
* concurrent replica still adds stay hidden) and — unless
|
|
446
|
+
* `keepFiling: true` — the folder is removed from every sidecar the
|
|
447
|
+
* local index knows.
|
|
448
|
+
*/
|
|
449
|
+
async deleteFolder(folderId, options) {
|
|
450
|
+
assertFolderId(folderId);
|
|
451
|
+
const doc = await this.tryGetDocument(await this.folderDocIdFor(folderId));
|
|
452
|
+
if (doc) {
|
|
453
|
+
await this.db.changeDoc(doc, (d) => {
|
|
454
|
+
d.getData().deleted = true;
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
if (options?.keepFiling) {
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
const index = await this.currentIndex();
|
|
461
|
+
// membersOf() hides deleted folders; read the raw members of the sidecars.
|
|
462
|
+
for (const physRef of index.allSidecarRefsInFolder(folderId)) {
|
|
463
|
+
await this.removeFromSidecars(index, physRef, [folderId]);
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
/** A folder definition, or `null` when unknown or deleted. */
|
|
467
|
+
async getFolder(folderId) {
|
|
468
|
+
const folder = (await this.currentIndex()).getFolder(folderId);
|
|
469
|
+
if (!folder || folder.deleted) {
|
|
470
|
+
return null;
|
|
471
|
+
}
|
|
472
|
+
const { deleted: _deleted, ...rest } = folder;
|
|
473
|
+
return rest;
|
|
474
|
+
}
|
|
475
|
+
/** All (not deleted) folders of this store. */
|
|
476
|
+
async listFolders() {
|
|
477
|
+
return (await this.currentIndex()).listFolders();
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
exports.MindooFilingStore = MindooFilingStore;
|
|
481
|
+
/** Deletion time (latest metadata entry) of those of `docIds` whose latest state is deleted. */
|
|
482
|
+
async function deletionTimes(db, docIds) {
|
|
483
|
+
const result = new Map();
|
|
484
|
+
for await (const { docId, isDeleted, lastModified } of db.iterateChangeMetadataSince(null)) {
|
|
485
|
+
if (!docIds.has(docId))
|
|
486
|
+
continue;
|
|
487
|
+
if (isDeleted)
|
|
488
|
+
result.set(docId, lastModified);
|
|
489
|
+
else
|
|
490
|
+
result.delete(docId);
|
|
491
|
+
}
|
|
492
|
+
return result;
|
|
493
|
+
}
|
|
494
|
+
/** Whether a document is deleted — not merely unreadable for this device. */
|
|
495
|
+
async function isReallyDeleted(db, docId) {
|
|
496
|
+
try {
|
|
497
|
+
const doc = await db.getDocument(docId);
|
|
498
|
+
return doc.isDeleted();
|
|
499
|
+
}
|
|
500
|
+
catch (error) {
|
|
501
|
+
return error instanceof errors_1.DocumentDeletedError || error?.name === "DocumentDeletedError";
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
function setOptionalAtomic(values, key, value) {
|
|
505
|
+
if (value === undefined) {
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
if (value === null || value === "") {
|
|
509
|
+
delete values[key];
|
|
510
|
+
}
|
|
511
|
+
else {
|
|
512
|
+
values[key] = values_1.MindooValue.atomic(value);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
//# sourceMappingURL=MindooFilingStore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MindooFilingStore.js","sourceRoot":"","sources":["../../../src/core/filing/MindooFilingStore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { MindooFilingStore, type FilingStoreOptions, type FilingPruneOptions, type FilingPruneResult, DEFAULT_FILING_PRUNE_GRACE_MS, type FilingEntry, type CreateFolderInput, type UpdateFolderInput, } from "./MindooFilingStore";
|
|
2
|
+
export { FilingIndex, FILING_SIDECAR_TYPE, FILING_FOLDER_TYPE, FILING_FOLDER_FIELD_PREFIX, readFolderFields, type FilingFolder, type FilingIndexChanges, } from "./FilingIndex";
|
|
3
|
+
export { resolveFilingRef, formatFilingRef, physicalFilingRefKey, parsePhysicalFilingRefKey, physicalDbKey, type FilingTarget, type FilingRefInput, type FilingRefBase, } from "./refs";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/filing/index.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,6BAA6B,EAC7B,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,mBAAmB,EACnB,kBAAkB,EAClB,0BAA0B,EAC1B,gBAAgB,EAChB,KAAK,YAAY,EACjB,KAAK,kBAAkB,GACxB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,gBAAgB,EAChB,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,aAAa,EACb,KAAK,YAAY,EACjB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,QAAQ,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Folders ("Ablage") for MindooDB: documents are filed into folders through
|
|
3
|
+
// small sidecar documents in a filing database, never by changing the filed
|
|
4
|
+
// document. See docs/folders.md.
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.physicalDbKey = exports.parsePhysicalFilingRefKey = exports.physicalFilingRefKey = exports.formatFilingRef = exports.resolveFilingRef = exports.readFolderFields = exports.FILING_FOLDER_FIELD_PREFIX = exports.FILING_FOLDER_TYPE = exports.FILING_SIDECAR_TYPE = exports.FilingIndex = exports.DEFAULT_FILING_PRUNE_GRACE_MS = exports.MindooFilingStore = void 0;
|
|
7
|
+
var MindooFilingStore_1 = require("./MindooFilingStore");
|
|
8
|
+
Object.defineProperty(exports, "MindooFilingStore", { enumerable: true, get: function () { return MindooFilingStore_1.MindooFilingStore; } });
|
|
9
|
+
Object.defineProperty(exports, "DEFAULT_FILING_PRUNE_GRACE_MS", { enumerable: true, get: function () { return MindooFilingStore_1.DEFAULT_FILING_PRUNE_GRACE_MS; } });
|
|
10
|
+
var FilingIndex_1 = require("./FilingIndex");
|
|
11
|
+
Object.defineProperty(exports, "FilingIndex", { enumerable: true, get: function () { return FilingIndex_1.FilingIndex; } });
|
|
12
|
+
Object.defineProperty(exports, "FILING_SIDECAR_TYPE", { enumerable: true, get: function () { return FilingIndex_1.FILING_SIDECAR_TYPE; } });
|
|
13
|
+
Object.defineProperty(exports, "FILING_FOLDER_TYPE", { enumerable: true, get: function () { return FilingIndex_1.FILING_FOLDER_TYPE; } });
|
|
14
|
+
Object.defineProperty(exports, "FILING_FOLDER_FIELD_PREFIX", { enumerable: true, get: function () { return FilingIndex_1.FILING_FOLDER_FIELD_PREFIX; } });
|
|
15
|
+
Object.defineProperty(exports, "readFolderFields", { enumerable: true, get: function () { return FilingIndex_1.readFolderFields; } });
|
|
16
|
+
var refs_1 = require("./refs");
|
|
17
|
+
Object.defineProperty(exports, "resolveFilingRef", { enumerable: true, get: function () { return refs_1.resolveFilingRef; } });
|
|
18
|
+
Object.defineProperty(exports, "formatFilingRef", { enumerable: true, get: function () { return refs_1.formatFilingRef; } });
|
|
19
|
+
Object.defineProperty(exports, "physicalFilingRefKey", { enumerable: true, get: function () { return refs_1.physicalFilingRefKey; } });
|
|
20
|
+
Object.defineProperty(exports, "parsePhysicalFilingRefKey", { enumerable: true, get: function () { return refs_1.parsePhysicalFilingRefKey; } });
|
|
21
|
+
Object.defineProperty(exports, "physicalDbKey", { enumerable: true, get: function () { return refs_1.physicalDbKey; } });
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/filing/index.ts"],"names":[],"mappings":";AAAA,4EAA4E;AAC5E,4EAA4E;AAC5E,iCAAiC;;;AAEjC,yDAS6B;AAR3B,sHAAA,iBAAiB,OAAA;AAIjB,kIAAA,6BAA6B,OAAA;AAK/B,6CAQuB;AAPrB,0GAAA,WAAW,OAAA;AACX,kHAAA,mBAAmB,OAAA;AACnB,iHAAA,kBAAkB,OAAA;AAClB,yHAAA,0BAA0B,OAAA;AAC1B,+GAAA,gBAAgB,OAAA;AAIlB,+BASgB;AARd,wGAAA,gBAAgB,OAAA;AAChB,uGAAA,eAAe,OAAA;AACf,4GAAA,oBAAoB,OAAA;AACpB,iHAAA,yBAAyB,OAAA;AACzB,qGAAA,aAAa,OAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference format of filed documents.
|
|
3
|
+
*
|
|
4
|
+
* A filing sidecar stores the document it files as a reference RELATIVE to
|
|
5
|
+
* the database the sidecar lives in (the filing database), so the common
|
|
6
|
+
* case stays short and a filing database can be copied between tenants
|
|
7
|
+
* without rewriting same-database references:
|
|
8
|
+
*
|
|
9
|
+
* - `"<docId>"` — a document in the filing database itself,
|
|
10
|
+
* - `"mdbref:/<dbId>/<docId>"` — a document in another database of the
|
|
11
|
+
* same tenant,
|
|
12
|
+
* - `"mdbref://<tenantId>/<dbId>/<docId>"` — a document in a database of
|
|
13
|
+
* another tenant.
|
|
14
|
+
*
|
|
15
|
+
* The reference always names the PHYSICAL identity (tenant id, database id)
|
|
16
|
+
* — never a view-local origin name or an app's logical database name.
|
|
17
|
+
* Views translate references into the canonical physical key
|
|
18
|
+
* `"<tenantId>/<dbId>/<docId>"` ({@link physicalFilingRefKey}) to match them
|
|
19
|
+
* against their data sources.
|
|
20
|
+
*/
|
|
21
|
+
/** A filed document, addressed by its physical identity. */
|
|
22
|
+
export interface FilingTarget {
|
|
23
|
+
tenantId: string;
|
|
24
|
+
dbId: string;
|
|
25
|
+
docId: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A filed document as accepted by the filing API: a reference string
|
|
29
|
+
* (`"<docId>"`, `"mdbref:/<dbId>/<docId>"`, `"mdbref://<tenantId>/<dbId>/<docId>"`)
|
|
30
|
+
* or an object whose missing `tenantId` / `dbId` default to the filing
|
|
31
|
+
* database's.
|
|
32
|
+
*/
|
|
33
|
+
export type FilingRefInput = string | {
|
|
34
|
+
tenantId?: string;
|
|
35
|
+
dbId?: string;
|
|
36
|
+
docId: string;
|
|
37
|
+
};
|
|
38
|
+
/** The database a reference is relative to (the filing database). */
|
|
39
|
+
export interface FilingRefBase {
|
|
40
|
+
tenantId: string;
|
|
41
|
+
dbId: string;
|
|
42
|
+
}
|
|
43
|
+
/** Resolve a reference (string or object) against the filing database. */
|
|
44
|
+
export declare function resolveFilingRef(ref: FilingRefInput, base: FilingRefBase): FilingTarget;
|
|
45
|
+
/**
|
|
46
|
+
* The shortest reference string for `target` relative to `base` — the form
|
|
47
|
+
* stored in sidecars.
|
|
48
|
+
*/
|
|
49
|
+
export declare function formatFilingRef(target: FilingTarget, base: FilingRefBase): string;
|
|
50
|
+
/** Canonical physical key `"<tenantId>/<dbId>/<docId>"` of a filed document. */
|
|
51
|
+
export declare function physicalFilingRefKey(target: FilingTarget): string;
|
|
52
|
+
/** Inverse of {@link physicalFilingRefKey}. */
|
|
53
|
+
export declare function parsePhysicalFilingRefKey(key: string): FilingTarget;
|
|
54
|
+
/** Physical key prefix `"<tenantId>/<dbId>/"` of a database. */
|
|
55
|
+
export declare function physicalDbKey(tenantId: string, dbId: string): string;
|
|
56
|
+
//# sourceMappingURL=refs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refs.d.ts","sourceRoot":"","sources":["../../../src/core/filing/refs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAE1F,qEAAqE;AACrE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd;AAUD,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,aAAa,GAAG,YAAY,CA0CvF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,aAAa,GAAG,MAAM,CAQjF;AAED,gFAAgF;AAChF,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEjE;AAED,+CAA+C;AAC/C,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,CAQnE;AAED,gEAAgE;AAChE,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEpE"}
|