@fireproof/core 0.19.121 → 0.20.0-dev-preview-06
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 +3 -2
- package/deno/index.d.ts +7 -0
- package/deno/index.js +66 -0
- package/deno/index.js.map +1 -0
- package/deno/metafile-esm.json +1 -0
- package/deno.json +2 -3
- package/index.cjs +1819 -1051
- package/index.cjs.map +1 -1
- package/index.d.cts +746 -333
- package/index.d.ts +746 -333
- package/index.js +1792 -1026
- package/index.js.map +1 -1
- package/metafile-cjs.json +1 -1
- package/metafile-esm.json +1 -1
- package/node/index.cjs +16 -293
- package/node/index.cjs.map +1 -1
- package/node/index.d.cts +4 -40
- package/node/index.d.ts +4 -40
- package/node/index.js +22 -237
- package/node/index.js.map +1 -1
- package/node/metafile-cjs.json +1 -1
- package/node/metafile-esm.json +1 -1
- package/package.json +12 -4
- package/react/index.cjs.map +1 -1
- package/react/index.js.map +1 -1
- package/react/metafile-cjs.json +1 -1
- package/react/metafile-esm.json +1 -1
- package/tests/blockstore/fp-envelope.test.ts-off +65 -0
- package/tests/blockstore/interceptor-gateway.test.ts +122 -0
- package/tests/blockstore/keyed-crypto-indexdb-file.test.ts +130 -0
- package/tests/blockstore/keyed-crypto.test.ts +73 -118
- package/tests/blockstore/loader.test.ts +18 -9
- package/tests/blockstore/store.test.ts +40 -31
- package/tests/blockstore/transaction.test.ts +14 -13
- package/tests/fireproof/all-gateway.test.ts +283 -213
- package/tests/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.ts +324 -316
- package/tests/fireproof/crdt.test.ts +78 -19
- package/tests/fireproof/database.test.ts +225 -29
- package/tests/fireproof/fireproof.test.ts +92 -73
- package/tests/fireproof/hello.test.ts +17 -13
- package/tests/fireproof/indexer.test.ts +67 -43
- package/tests/fireproof/utils.test.ts +47 -6
- package/tests/gateway/file/loader-config.test.ts +307 -0
- package/tests/gateway/fp-envelope-serialize.test.ts +256 -0
- package/tests/gateway/indexdb/loader-config.test.ts +79 -0
- package/tests/helpers.ts +44 -17
- package/tests/react/useFireproof.test.tsx +1 -1
- package/tests/www/todo.html +24 -3
- package/web/index.cjs +102 -116
- package/web/index.cjs.map +1 -1
- package/web/index.d.cts +15 -29
- package/web/index.d.ts +15 -29
- package/web/index.js +91 -105
- package/web/index.js.map +1 -1
- package/web/metafile-cjs.json +1 -1
- package/web/metafile-esm.json +1 -1
- package/node/chunk-4A4RAVNS.js +0 -17
- package/node/chunk-4A4RAVNS.js.map +0 -1
- package/node/mem-filesystem-LPPT7QV5.js +0 -40
- package/node/mem-filesystem-LPPT7QV5.js.map +0 -1
- package/tests/fireproof/config.test.ts +0 -163
- /package/tests/blockstore/{fragment-gateway.test.ts → fragment-gateway.test.ts-off} +0 -0
- /package/tests/fireproof/{multiple-ledger.test.ts → multiple-database.test.ts} +0 -0
package/index.cjs
CHANGED
@@ -31,15 +31,18 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
31
31
|
var index_exports = {};
|
32
32
|
__export(index_exports, {
|
33
33
|
CRDT: () => CRDT,
|
34
|
-
|
34
|
+
DatabaseFactory: () => DatabaseFactory,
|
35
|
+
DatabaseShell: () => DatabaseShell,
|
35
36
|
Index: () => Index,
|
36
37
|
NotFoundError: () => NotFoundError,
|
37
38
|
PACKAGE_VERSION: () => PACKAGE_VERSION,
|
38
|
-
|
39
|
+
PARAM: () => PARAM,
|
39
40
|
UInt8ArrayEqual: () => UInt8ArrayEqual,
|
40
41
|
blockstore: () => blockstore_exports,
|
41
42
|
bs: () => blockstore_exports,
|
42
|
-
|
43
|
+
coerceIntoUint8: () => coerceIntoUint8,
|
44
|
+
coercePromiseIntoUint8: () => coercePromiseIntoUint8,
|
45
|
+
defaultWriteQueueOpts: () => defaultWriteQueueOpts,
|
43
46
|
ensureLogger: () => ensureLogger,
|
44
47
|
ensureSuperLog: () => ensureSuperLog,
|
45
48
|
ensureSuperThis: () => ensureSuperThis,
|
@@ -50,248 +53,50 @@ __export(index_exports, {
|
|
50
53
|
getName: () => getName,
|
51
54
|
getStore: () => getStore,
|
52
55
|
index: () => index,
|
56
|
+
inplaceFilter: () => inplaceFilter,
|
57
|
+
isDatabase: () => isDatabase,
|
53
58
|
isFalsy: () => isFalsy,
|
54
59
|
isNotFoundError: () => isNotFoundError,
|
60
|
+
keyConfigOpts: () => keyConfigOpts,
|
55
61
|
onSuperThis: () => onSuperThis,
|
56
62
|
rt: () => runtime_exports,
|
57
63
|
runtime: () => runtime_exports,
|
58
|
-
throwFalsy: () => throwFalsy
|
64
|
+
throwFalsy: () => throwFalsy,
|
65
|
+
toSortedArray: () => toSortedArray,
|
66
|
+
toStoreURIRuntime: () => toStoreURIRuntime
|
59
67
|
});
|
60
68
|
module.exports = __toCommonJS(index_exports);
|
61
69
|
|
62
70
|
// src/database.ts
|
63
|
-
var
|
64
|
-
|
65
|
-
// src/write-queue.ts
|
66
|
-
function writeQueue(worker, payload = Infinity, unbounded = false) {
|
67
|
-
const queue = [];
|
68
|
-
let isProcessing = false;
|
69
|
-
async function process() {
|
70
|
-
if (isProcessing || queue.length === 0) return;
|
71
|
-
isProcessing = true;
|
72
|
-
const tasksToProcess = queue.splice(0, payload);
|
73
|
-
const updates = tasksToProcess.map((item) => item.task);
|
74
|
-
if (unbounded) {
|
75
|
-
const promises = updates.map(async (update, index2) => {
|
76
|
-
try {
|
77
|
-
const result = await worker([update]);
|
78
|
-
tasksToProcess[index2].resolve(result);
|
79
|
-
} catch (error) {
|
80
|
-
tasksToProcess[index2].reject(error);
|
81
|
-
}
|
82
|
-
});
|
83
|
-
await Promise.all(promises);
|
84
|
-
} else {
|
85
|
-
try {
|
86
|
-
const result = await worker(updates);
|
87
|
-
tasksToProcess.forEach((task) => task.resolve(result));
|
88
|
-
} catch (error) {
|
89
|
-
tasksToProcess.forEach((task) => task.reject(error));
|
90
|
-
}
|
91
|
-
}
|
92
|
-
isProcessing = false;
|
93
|
-
void process();
|
94
|
-
}
|
95
|
-
return {
|
96
|
-
push(task) {
|
97
|
-
return new Promise((resolve, reject) => {
|
98
|
-
queue.push({ task, resolve, reject });
|
99
|
-
void process();
|
100
|
-
});
|
101
|
-
}
|
102
|
-
};
|
103
|
-
}
|
104
|
-
|
105
|
-
// src/crdt.ts
|
106
|
-
var import_cement11 = require("@adviser/cement");
|
107
|
-
|
108
|
-
// src/runtime/wait-pr-multiformats/block.ts
|
109
|
-
var block_exports = {};
|
110
|
-
__export(block_exports, {
|
111
|
-
Block: () => Block,
|
112
|
-
create: () => create,
|
113
|
-
createUnsafe: () => createUnsafe,
|
114
|
-
decode: () => decode,
|
115
|
-
encode: () => encode
|
116
|
-
});
|
117
|
-
var import_multiformats = require("multiformats");
|
118
|
-
var import_block = require("multiformats/block");
|
119
|
-
var Block = import_block.Block;
|
120
|
-
async function decode({
|
121
|
-
bytes,
|
122
|
-
codec: codec3,
|
123
|
-
hasher: hasher7
|
124
|
-
}) {
|
125
|
-
if (bytes == null) throw new Error('Missing required argument "bytes"');
|
126
|
-
if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
|
127
|
-
const value = await Promise.resolve(codec3.decode(bytes));
|
128
|
-
const hash = await hasher7.digest(bytes);
|
129
|
-
const cid = import_multiformats.CID.create(1, codec3.code, hash);
|
130
|
-
return new import_block.Block({ value, bytes, cid });
|
131
|
-
}
|
132
|
-
async function encode({
|
133
|
-
value,
|
134
|
-
codec: codec3,
|
135
|
-
hasher: hasher7
|
136
|
-
}) {
|
137
|
-
if (typeof value === "undefined") throw new Error('Missing required argument "value"');
|
138
|
-
if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
|
139
|
-
const bytes = await Promise.resolve(codec3.encode(value));
|
140
|
-
const hash = await hasher7.digest(bytes);
|
141
|
-
const cid = import_multiformats.CID.create(1, codec3.code, hash);
|
142
|
-
return new import_block.Block({ value, bytes, cid });
|
143
|
-
}
|
144
|
-
async function create({
|
145
|
-
bytes,
|
146
|
-
cid,
|
147
|
-
hasher: hasher7,
|
148
|
-
codec: codec3
|
149
|
-
}) {
|
150
|
-
if (bytes == null) throw new Error('Missing required argument "bytes"');
|
151
|
-
if (hasher7 == null) throw new Error('Missing required argument "hasher"');
|
152
|
-
const value = await Promise.resolve(codec3.decode(bytes));
|
153
|
-
const hash = await hasher7.digest(bytes);
|
154
|
-
if (!import_multiformats.bytes.equals(cid.multihash.bytes, hash.bytes)) {
|
155
|
-
throw new Error("CID hash does not match bytes");
|
156
|
-
}
|
157
|
-
return createUnsafe({
|
158
|
-
bytes,
|
159
|
-
cid,
|
160
|
-
value,
|
161
|
-
codec: codec3
|
162
|
-
});
|
163
|
-
}
|
164
|
-
async function createUnsafe({
|
165
|
-
bytes,
|
166
|
-
cid,
|
167
|
-
value: maybeValue,
|
168
|
-
codec: codec3
|
169
|
-
}) {
|
170
|
-
const value = await Promise.resolve(maybeValue !== void 0 ? maybeValue : codec3?.decode(bytes));
|
171
|
-
if (value === void 0) throw new Error('Missing required argument, must either provide "value" or "codec"');
|
172
|
-
return new Block({
|
173
|
-
cid,
|
174
|
-
bytes,
|
175
|
-
value
|
176
|
-
});
|
177
|
-
}
|
178
|
-
|
179
|
-
// src/crdt-helpers.ts
|
180
|
-
var import_link = require("multiformats/link");
|
181
|
-
var import_sha25 = require("multiformats/hashes/sha2");
|
182
|
-
var codec = __toESM(require("@fireproof/vendor/@ipld/dag-cbor"), 1);
|
183
|
-
var import_crdt = require("@fireproof/vendor/@web3-storage/pail/crdt");
|
184
|
-
var import_clock2 = require("@fireproof/vendor/@web3-storage/pail/clock");
|
185
|
-
var Batch = __toESM(require("@fireproof/vendor/@web3-storage/pail/crdt/batch"), 1);
|
186
|
-
|
187
|
-
// src/blockstore/index.ts
|
188
|
-
var blockstore_exports = {};
|
189
|
-
__export(blockstore_exports, {
|
190
|
-
BaseBlockstore: () => BaseBlockstore,
|
191
|
-
CarTransaction: () => CarTransaction,
|
192
|
-
CompactionFetcher: () => CompactionFetcher,
|
193
|
-
ConnectionBase: () => ConnectionBase,
|
194
|
-
EncryptedBlockstore: () => EncryptedBlockstore,
|
195
|
-
FragmentGateway: () => FragmentGateway,
|
196
|
-
Loader: () => Loader,
|
197
|
-
addCryptoKeyToGatewayMetaPayload: () => addCryptoKeyToGatewayMetaPayload,
|
198
|
-
ensureStart: () => ensureStart,
|
199
|
-
getGatewayFromURL: () => getGatewayFromURL,
|
200
|
-
parseCarFile: () => parseCarFile,
|
201
|
-
registerStoreProtocol: () => registerStoreProtocol,
|
202
|
-
setCryptoKeyFromGatewayMetaPayload: () => setCryptoKeyFromGatewayMetaPayload,
|
203
|
-
testStoreFactory: () => testStoreFactory,
|
204
|
-
toCIDBlock: () => toCIDBlock,
|
205
|
-
toStoreRuntime: () => toStoreRuntime
|
206
|
-
});
|
207
|
-
|
208
|
-
// src/blockstore/types.ts
|
209
|
-
function toCIDBlock(block) {
|
210
|
-
return block;
|
211
|
-
}
|
212
|
-
|
213
|
-
// src/blockstore/store-factory.ts
|
214
|
-
var import_cement9 = require("@adviser/cement");
|
215
|
-
|
216
|
-
// src/runtime/files.ts
|
217
|
-
var files_exports = {};
|
218
|
-
__export(files_exports, {
|
219
|
-
decodeFile: () => decodeFile,
|
220
|
-
encodeFile: () => encodeFile
|
221
|
-
});
|
222
|
-
var UnixFS = __toESM(require("@ipld/unixfs"), 1);
|
223
|
-
var raw = __toESM(require("multiformats/codecs/raw"), 1);
|
224
|
-
var import_fixed = require("@ipld/unixfs/file/chunker/fixed");
|
225
|
-
var import_balanced = require("@ipld/unixfs/file/layout/balanced");
|
226
|
-
var import_ipfs_unixfs_exporter = require("@fireproof/vendor/ipfs-unixfs-exporter");
|
227
|
-
var queuingStrategy = UnixFS.withCapacity();
|
228
|
-
var settings = UnixFS.configure({
|
229
|
-
fileChunkEncoder: raw,
|
230
|
-
smallFileEncoder: raw,
|
231
|
-
chunker: (0, import_fixed.withMaxChunkSize)(1024 * 1024),
|
232
|
-
fileLayout: (0, import_balanced.withWidth)(1024)
|
233
|
-
});
|
234
|
-
async function collect(collectable) {
|
235
|
-
const chunks = [];
|
236
|
-
await collectable.pipeTo(
|
237
|
-
new WritableStream({
|
238
|
-
write(chunk) {
|
239
|
-
chunks.push(chunk);
|
240
|
-
}
|
241
|
-
})
|
242
|
-
);
|
243
|
-
return chunks;
|
244
|
-
}
|
245
|
-
async function encodeFile(blob) {
|
246
|
-
const readable = createFileEncoderStream(blob);
|
247
|
-
const blocks = await collect(readable);
|
248
|
-
return { cid: blocks.at(-1).cid, blocks };
|
249
|
-
}
|
250
|
-
async function decodeFile(blocks, cid, meta) {
|
251
|
-
const entry = await (0, import_ipfs_unixfs_exporter.exporter)(cid.toString(), blocks, { length: meta.size });
|
252
|
-
const chunks = [];
|
253
|
-
for await (const chunk of entry.content()) {
|
254
|
-
chunks.push(chunk);
|
255
|
-
}
|
256
|
-
return new File(chunks, entry.name, { type: meta.type, lastModified: 0 });
|
257
|
-
}
|
258
|
-
function createFileEncoderStream(blob) {
|
259
|
-
const { readable, writable } = new TransformStream({}, queuingStrategy);
|
260
|
-
const unixfsWriter = UnixFS.createWriter({ writable, settings });
|
261
|
-
const fileBuilder = new UnixFSFileBuilder("", blob);
|
262
|
-
void (async () => {
|
263
|
-
await fileBuilder.finalize(unixfsWriter);
|
264
|
-
await unixfsWriter.close();
|
265
|
-
})();
|
266
|
-
return readable;
|
267
|
-
}
|
268
|
-
var UnixFSFileBuilder = class {
|
269
|
-
#file;
|
270
|
-
constructor(name, file) {
|
271
|
-
this.name = name;
|
272
|
-
this.#file = file;
|
273
|
-
}
|
274
|
-
async finalize(writer) {
|
275
|
-
const unixfsFileWriter = UnixFS.createFileWriter(writer);
|
276
|
-
await this.#file.stream().pipeTo(
|
277
|
-
new WritableStream({
|
278
|
-
async write(chunk) {
|
279
|
-
await unixfsFileWriter.write(chunk);
|
280
|
-
}
|
281
|
-
})
|
282
|
-
);
|
283
|
-
return await unixfsFileWriter.close();
|
284
|
-
}
|
285
|
-
};
|
71
|
+
var import_cement20 = require("@adviser/cement");
|
286
72
|
|
287
|
-
// src/
|
288
|
-
var
|
289
|
-
var import_cement8 = require("@adviser/cement");
|
73
|
+
// src/utils.ts
|
74
|
+
var import_cement = require("@adviser/cement");
|
290
75
|
|
291
76
|
// src/types.ts
|
292
77
|
function isFalsy(value) {
|
293
78
|
return value === false && value === null && value === void 0;
|
294
79
|
}
|
80
|
+
var PARAM = /* @__PURE__ */ ((PARAM2) => {
|
81
|
+
PARAM2["SUFFIX"] = "suffix";
|
82
|
+
PARAM2["URL_GEN"] = "urlGen";
|
83
|
+
PARAM2["STORE_KEY"] = "storekey";
|
84
|
+
PARAM2["STORE"] = "store";
|
85
|
+
PARAM2["KEY"] = "key";
|
86
|
+
PARAM2["INDEX"] = "index";
|
87
|
+
PARAM2["NAME"] = "name";
|
88
|
+
PARAM2["VERSION"] = "version";
|
89
|
+
PARAM2["RUNTIME"] = "runtime";
|
90
|
+
PARAM2["FRAG_SIZE"] = "fragSize";
|
91
|
+
PARAM2["IV_VERIFY"] = "ivVerify";
|
92
|
+
PARAM2["IV_HASH"] = "ivHash";
|
93
|
+
PARAM2["FRAG_FID"] = "fid";
|
94
|
+
PARAM2["FRAG_OFS"] = "ofs";
|
95
|
+
PARAM2["FRAG_LEN"] = "len";
|
96
|
+
PARAM2["FRAG_HEAD"] = "headerSize";
|
97
|
+
PARAM2["EXTRACTKEY"] = "extractKey";
|
98
|
+
return PARAM2;
|
99
|
+
})(PARAM || {});
|
295
100
|
function throwFalsy(value) {
|
296
101
|
if (isFalsy(value)) {
|
297
102
|
throw new Error("value is Falsy");
|
@@ -306,7 +111,6 @@ function falsyToUndef(value) {
|
|
306
111
|
}
|
307
112
|
|
308
113
|
// src/utils.ts
|
309
|
-
var import_cement = require("@adviser/cement");
|
310
114
|
var import_base58 = require("multiformats/bases/base58");
|
311
115
|
var _globalLogger = new import_cement.ResolveOnce();
|
312
116
|
function globalLogger() {
|
@@ -374,17 +178,19 @@ var pathOpsImpl = class {
|
|
374
178
|
dirname(path) {
|
375
179
|
return path.split("/").slice(0, -1).join("/");
|
376
180
|
}
|
181
|
+
basename(path) {
|
182
|
+
return path.split("/").pop() || "";
|
183
|
+
}
|
377
184
|
// homedir() {
|
378
185
|
// throw new Error("SysContainer:homedir is not available in seeded state");
|
379
186
|
// }
|
380
187
|
};
|
381
188
|
var pathOps = new pathOpsImpl();
|
382
|
-
var txtOps = {
|
383
|
-
|
384
|
-
|
189
|
+
var txtOps = /* @__PURE__ */ ((txtEncoder, txtDecoder) => ({
|
190
|
+
encode: (input) => txtEncoder.encode(input),
|
191
|
+
decode: (input) => txtDecoder.decode(coerceIntoUint8(input).Ok())
|
385
192
|
// eslint-disable-next-line no-restricted-globals
|
386
|
-
|
387
|
-
};
|
193
|
+
}))(new TextEncoder(), new TextDecoder());
|
388
194
|
var _onSuperThis = /* @__PURE__ */ new Map();
|
389
195
|
function onSuperThis(fn) {
|
390
196
|
const key = `onSuperThis-${Math.random().toString(36).slice(2)}`;
|
@@ -416,9 +222,7 @@ function ensureSuperLog(sthis, componentName, ctx) {
|
|
416
222
|
}
|
417
223
|
function ensureLogger(sthis, componentName, ctx) {
|
418
224
|
let logger;
|
419
|
-
if ((0, import_cement.IsLogger)(sthis)) {
|
420
|
-
logger = sthis;
|
421
|
-
} else if (sthis && (0, import_cement.IsLogger)(sthis.logger)) {
|
225
|
+
if (sthis && (0, import_cement.IsLogger)(sthis.logger)) {
|
422
226
|
logger = sthis.logger;
|
423
227
|
} else {
|
424
228
|
logger = globalLogger();
|
@@ -439,6 +243,10 @@ function ensureLogger(sthis, componentName, ctx) {
|
|
439
243
|
exposeStack = true;
|
440
244
|
delete ctx.exposeStack;
|
441
245
|
}
|
246
|
+
if ("exposeStack" in ctx) {
|
247
|
+
exposeStack = true;
|
248
|
+
delete ctx.exposeStack;
|
249
|
+
}
|
442
250
|
if ("this" in ctx) {
|
443
251
|
cLogger.Str("this", sthis.nextId(4).str);
|
444
252
|
delete ctx.this;
|
@@ -505,10 +313,13 @@ function ensureLogger(sthis, componentName, ctx) {
|
|
505
313
|
logger.SetExposeStack(true);
|
506
314
|
}
|
507
315
|
const out = cLogger.Logger();
|
316
|
+
if (sthis.env.get("FP_CONSTRUCTOR_DEBUG")) {
|
317
|
+
out.Debug().Msg("constructor");
|
318
|
+
}
|
508
319
|
return out;
|
509
320
|
}
|
510
321
|
function getStore(url, sthis, joiner) {
|
511
|
-
const store = url.getParam("store");
|
322
|
+
const store = url.getParam("store" /* STORE */);
|
512
323
|
switch (store) {
|
513
324
|
case "data":
|
514
325
|
case "wal":
|
@@ -516,20 +327,21 @@ function getStore(url, sthis, joiner) {
|
|
516
327
|
break;
|
517
328
|
default:
|
518
329
|
throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
|
330
|
+
throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
|
519
331
|
}
|
520
332
|
let name = store;
|
521
333
|
if (url.hasParam("index")) {
|
522
|
-
name = joiner(url.getParam("index") || "idx", name);
|
334
|
+
name = joiner(url.getParam("index" /* INDEX */) || "idx", name);
|
523
335
|
}
|
524
336
|
return { store, name };
|
525
337
|
}
|
526
338
|
function getKey(url, logger) {
|
527
|
-
const result = url.getParam("key");
|
339
|
+
const result = url.getParam("key" /* KEY */);
|
528
340
|
if (!result) throw logger.Error().Str("url", url.toString()).Msg(`key not found`).AsError();
|
529
341
|
return result;
|
530
342
|
}
|
531
343
|
function getName(sthis, url) {
|
532
|
-
let result = url.getParam("name");
|
344
|
+
let result = url.getParam("name" /* NAME */);
|
533
345
|
if (!result) {
|
534
346
|
result = sthis.pathOps.dirname(url.pathname);
|
535
347
|
if (result.length === 0) {
|
@@ -538,50 +350,337 @@ function getName(sthis, url) {
|
|
538
350
|
}
|
539
351
|
return result;
|
540
352
|
}
|
541
|
-
async function exceptionWrapper(fn) {
|
542
|
-
return fn().catch((e) => import_cement.Result.Err(e));
|
353
|
+
async function exceptionWrapper(fn) {
|
354
|
+
return fn().catch((e) => import_cement.Result.Err(e));
|
355
|
+
}
|
356
|
+
var NotFoundError = class extends Error {
|
357
|
+
constructor() {
|
358
|
+
super(...arguments);
|
359
|
+
this.code = "ENOENT";
|
360
|
+
}
|
361
|
+
};
|
362
|
+
function isNotFoundError(e) {
|
363
|
+
if (import_cement.Result.Is(e)) {
|
364
|
+
if (e.isOk()) return false;
|
365
|
+
e = e.Err();
|
366
|
+
}
|
367
|
+
if (e.code === "ENOENT") return true;
|
368
|
+
return false;
|
369
|
+
}
|
370
|
+
function UInt8ArrayEqual(a, b) {
|
371
|
+
if (a.length !== b.length) {
|
372
|
+
return false;
|
373
|
+
}
|
374
|
+
for (let i = 0; i < a.length; i++) {
|
375
|
+
if (a[i] !== b[i]) {
|
376
|
+
return false;
|
377
|
+
}
|
378
|
+
}
|
379
|
+
return true;
|
380
|
+
}
|
381
|
+
function inplaceFilter(i, pred) {
|
382
|
+
const founds = [];
|
383
|
+
for (let j = 0; j < i.length; j++) {
|
384
|
+
if (!pred(i[j], j)) {
|
385
|
+
founds.push(j);
|
386
|
+
}
|
387
|
+
}
|
388
|
+
for (let j = founds.length - 1; j >= 0; j--) {
|
389
|
+
i.splice(founds[j], 1);
|
390
|
+
}
|
391
|
+
return i;
|
392
|
+
}
|
393
|
+
function toSortedArray(set) {
|
394
|
+
if (!set) return [];
|
395
|
+
return Object.entries(set).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => ({ [k]: v }));
|
396
|
+
}
|
397
|
+
function coerceIntoUint8(raw2) {
|
398
|
+
if (raw2 instanceof Uint8Array) {
|
399
|
+
return import_cement.Result.Ok(raw2);
|
400
|
+
}
|
401
|
+
if (import_cement.Result.Is(raw2)) {
|
402
|
+
return raw2;
|
403
|
+
}
|
404
|
+
return import_cement.Result.Err("Not a Uint8Array");
|
405
|
+
}
|
406
|
+
async function coercePromiseIntoUint8(raw2) {
|
407
|
+
if (raw2 instanceof Uint8Array) {
|
408
|
+
return import_cement.Result.Ok(raw2);
|
409
|
+
}
|
410
|
+
if (import_cement.Result.Is(raw2)) {
|
411
|
+
return raw2;
|
412
|
+
}
|
413
|
+
if (typeof raw2.then === "function") {
|
414
|
+
try {
|
415
|
+
return coercePromiseIntoUint8(await raw2);
|
416
|
+
} catch (e) {
|
417
|
+
return import_cement.Result.Err(e);
|
418
|
+
}
|
419
|
+
}
|
420
|
+
return import_cement.Result.Err("Not a Uint8Array");
|
421
|
+
}
|
422
|
+
|
423
|
+
// src/write-queue.ts
|
424
|
+
var import_cement2 = require("@adviser/cement");
|
425
|
+
function defaultWriteQueueOpts(opts = {}) {
|
426
|
+
return {
|
427
|
+
...opts,
|
428
|
+
chunkSize: opts.chunkSize && opts.chunkSize > 0 ? opts.chunkSize : 32
|
429
|
+
};
|
430
|
+
}
|
431
|
+
var WriteQueueImpl = class {
|
432
|
+
constructor(sthis, worker, opts) {
|
433
|
+
this.queue = [];
|
434
|
+
this.isProcessing = false;
|
435
|
+
this.logger = ensureLogger(sthis, "WriteQueueImpl");
|
436
|
+
this.worker = worker;
|
437
|
+
this.opts = defaultWriteQueueOpts(opts);
|
438
|
+
}
|
439
|
+
testEmptyQueue() {
|
440
|
+
if (this.waitForEmptyQueue && this.queue.length === 0) {
|
441
|
+
this.waitForEmptyQueue.resolve();
|
442
|
+
}
|
443
|
+
}
|
444
|
+
async process() {
|
445
|
+
if (this.isProcessing || this.queue.length === 0) {
|
446
|
+
this.testEmptyQueue();
|
447
|
+
return;
|
448
|
+
}
|
449
|
+
this.isProcessing = true;
|
450
|
+
try {
|
451
|
+
this.logger.Debug().Any("opts", this.opts).Len(this.queue).Msg("Processing tasks");
|
452
|
+
const tasksToProcess = this.queue.splice(0, this.opts.chunkSize);
|
453
|
+
const updates = tasksToProcess.map((item) => item.tasks).filter((item) => item);
|
454
|
+
const promises = updates.map(async (update, index2) => {
|
455
|
+
try {
|
456
|
+
const result = await this.worker(update);
|
457
|
+
tasksToProcess[index2].resolve(result);
|
458
|
+
} catch (error) {
|
459
|
+
tasksToProcess[index2].reject(this.logger.Error().Err(error).Msg("Error processing task").AsError());
|
460
|
+
}
|
461
|
+
});
|
462
|
+
await Promise.allSettled(promises);
|
463
|
+
this.logger.Debug().Any("opts", this.opts).Len(this.queue).Msg("Processed tasks");
|
464
|
+
} catch (error) {
|
465
|
+
this.logger.Error().Err(error).Msg("Error processing tasks");
|
466
|
+
} finally {
|
467
|
+
this.isProcessing = false;
|
468
|
+
setTimeout(() => this.process(), 0);
|
469
|
+
}
|
470
|
+
}
|
471
|
+
bulk(tasks) {
|
472
|
+
return new Promise((resolve, reject) => {
|
473
|
+
this.queue.push({ tasks, resolve, reject });
|
474
|
+
this.process();
|
475
|
+
});
|
476
|
+
}
|
477
|
+
push(task) {
|
478
|
+
return this.bulk([task]);
|
479
|
+
}
|
480
|
+
close() {
|
481
|
+
this.waitForEmptyQueue = new import_cement2.Future();
|
482
|
+
this.testEmptyQueue();
|
483
|
+
return this.waitForEmptyQueue.asPromise();
|
484
|
+
}
|
485
|
+
};
|
486
|
+
function writeQueue(sthis, worker, opts) {
|
487
|
+
return new WriteQueueImpl(sthis, worker, opts);
|
488
|
+
}
|
489
|
+
|
490
|
+
// src/crdt.ts
|
491
|
+
var import_cement19 = require("@adviser/cement");
|
492
|
+
|
493
|
+
// src/blockstore/index.ts
|
494
|
+
var blockstore_exports = {};
|
495
|
+
__export(blockstore_exports, {
|
496
|
+
BaseBlockstore: () => BaseBlockstore,
|
497
|
+
Car2FPMsg: () => Car2FPMsg,
|
498
|
+
CarTransaction: () => CarTransaction,
|
499
|
+
CompactionFetcher: () => CompactionFetcher,
|
500
|
+
ConnectionBase: () => ConnectionBase,
|
501
|
+
DbMetaEventEqual: () => DbMetaEventEqual,
|
502
|
+
DbMetaEventsEqual: () => DbMetaEventsEqual,
|
503
|
+
EncryptedBlockstore: () => EncryptedBlockstore,
|
504
|
+
FPEnvelopeType: () => FPEnvelopeType,
|
505
|
+
File2FPMsg: () => File2FPMsg,
|
506
|
+
InterceptorGateway: () => InterceptorGateway,
|
507
|
+
Loader: () => Loader,
|
508
|
+
PassThroughGateway: () => PassThroughGateway,
|
509
|
+
createDbMetaEvent: () => createDbMetaEvent,
|
510
|
+
defaultGatewayFactoryItem: () => defaultGatewayFactoryItem,
|
511
|
+
ensureStoreEnDeFile: () => ensureStoreEnDeFile,
|
512
|
+
getDefaultURI: () => getDefaultURI,
|
513
|
+
getGatewayFactoryItem: () => getGatewayFactoryItem,
|
514
|
+
getStartedGateway: () => getStartedGateway,
|
515
|
+
parseCarFile: () => parseCarFile,
|
516
|
+
registerStoreProtocol: () => registerStoreProtocol,
|
517
|
+
toCIDBlock: () => toCIDBlock,
|
518
|
+
toStoreRuntime: () => toStoreRuntime
|
519
|
+
});
|
520
|
+
|
521
|
+
// src/blockstore/types.ts
|
522
|
+
function toCIDBlock(block) {
|
523
|
+
return block;
|
524
|
+
}
|
525
|
+
function DbMetaEventEqual(a, b) {
|
526
|
+
return a.eventCid.equals(b.eventCid) && a.parents.length === b.parents.length && a.parents.every((p, i) => p.equals(b.parents[i])) && a.dbMeta.cars.length === b.dbMeta.cars.length && a.dbMeta.cars.every((c, i) => c.equals(b.dbMeta.cars[i]));
|
527
|
+
}
|
528
|
+
function DbMetaEventsEqual(a, b) {
|
529
|
+
return a.length === b.length && a.every((e, i) => DbMetaEventEqual(e, b[i]));
|
530
|
+
}
|
531
|
+
|
532
|
+
// src/blockstore/store-factory.ts
|
533
|
+
var import_cement17 = require("@adviser/cement");
|
534
|
+
|
535
|
+
// src/runtime/files.ts
|
536
|
+
var files_exports = {};
|
537
|
+
__export(files_exports, {
|
538
|
+
decodeFile: () => decodeFile,
|
539
|
+
encodeFile: () => encodeFile
|
540
|
+
});
|
541
|
+
var UnixFS = __toESM(require("@ipld/unixfs"), 1);
|
542
|
+
var raw = __toESM(require("multiformats/codecs/raw"), 1);
|
543
|
+
var import_fixed = require("@ipld/unixfs/file/chunker/fixed");
|
544
|
+
var import_balanced = require("@ipld/unixfs/file/layout/balanced");
|
545
|
+
var import_ipfs_unixfs_exporter = require("@fireproof/vendor/ipfs-unixfs-exporter");
|
546
|
+
var queuingStrategy = UnixFS.withCapacity();
|
547
|
+
var settings = UnixFS.configure({
|
548
|
+
fileChunkEncoder: raw,
|
549
|
+
smallFileEncoder: raw,
|
550
|
+
chunker: (0, import_fixed.withMaxChunkSize)(1024 * 1024),
|
551
|
+
fileLayout: (0, import_balanced.withWidth)(1024)
|
552
|
+
});
|
553
|
+
async function collect(collectable) {
|
554
|
+
const chunks = [];
|
555
|
+
await collectable.pipeTo(
|
556
|
+
new WritableStream({
|
557
|
+
write(chunk) {
|
558
|
+
chunks.push(chunk);
|
559
|
+
}
|
560
|
+
})
|
561
|
+
);
|
562
|
+
return chunks;
|
563
|
+
}
|
564
|
+
async function encodeFile(blob) {
|
565
|
+
const readable = createFileEncoderStream(blob);
|
566
|
+
const blocks = await collect(readable);
|
567
|
+
return { cid: blocks.at(-1).cid, blocks };
|
543
568
|
}
|
544
|
-
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
|
549
|
-
};
|
550
|
-
function isNotFoundError(e) {
|
551
|
-
if (import_cement.Result.Is(e)) {
|
552
|
-
if (e.isOk()) return false;
|
553
|
-
e = e.Err();
|
569
|
+
async function decodeFile(blocks, cid, meta) {
|
570
|
+
const entry = await (0, import_ipfs_unixfs_exporter.exporter)(cid.toString(), blocks, { length: meta.size });
|
571
|
+
const chunks = [];
|
572
|
+
for await (const chunk of entry.content()) {
|
573
|
+
chunks.push(chunk);
|
554
574
|
}
|
555
|
-
|
556
|
-
return false;
|
575
|
+
return new File(chunks, entry.name, { type: meta.type, lastModified: 0 });
|
557
576
|
}
|
558
|
-
function
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
567
|
-
return import_cement.URI.from(base.toString()).build().setParam("name", name || "").URI();
|
577
|
+
function createFileEncoderStream(blob) {
|
578
|
+
const { readable, writable } = new TransformStream({}, queuingStrategy);
|
579
|
+
const unixfsWriter = UnixFS.createWriter({ writable, settings });
|
580
|
+
const fileBuilder = new UnixFSFileBuilder("", blob);
|
581
|
+
void (async () => {
|
582
|
+
await fileBuilder.finalize(unixfsWriter);
|
583
|
+
await unixfsWriter.close();
|
584
|
+
})();
|
585
|
+
return readable;
|
568
586
|
}
|
569
|
-
|
570
|
-
|
571
|
-
|
587
|
+
var UnixFSFileBuilder = class {
|
588
|
+
#file;
|
589
|
+
constructor(name, file) {
|
590
|
+
this.name = name;
|
591
|
+
this.#file = file;
|
572
592
|
}
|
573
|
-
|
574
|
-
|
575
|
-
|
576
|
-
|
593
|
+
async finalize(writer) {
|
594
|
+
const unixfsFileWriter = UnixFS.createFileWriter(writer);
|
595
|
+
await this.#file.stream().pipeTo(
|
596
|
+
new WritableStream({
|
597
|
+
async write(chunk) {
|
598
|
+
await unixfsFileWriter.write(chunk);
|
599
|
+
}
|
600
|
+
})
|
601
|
+
);
|
602
|
+
return await unixfsFileWriter.close();
|
577
603
|
}
|
578
|
-
|
579
|
-
|
604
|
+
};
|
605
|
+
|
606
|
+
// src/blockstore/store.ts
|
607
|
+
var import_cement10 = require("@adviser/cement");
|
580
608
|
|
581
609
|
// src/blockstore/loader.ts
|
582
610
|
var import_p_limit = __toESM(require("p-limit"), 1);
|
583
611
|
var import_reader = require("@fireproof/vendor/@ipld/car/reader");
|
584
|
-
var
|
612
|
+
var import_cement7 = require("@adviser/cement");
|
613
|
+
|
614
|
+
// src/runtime/wait-pr-multiformats/block.ts
|
615
|
+
var block_exports = {};
|
616
|
+
__export(block_exports, {
|
617
|
+
Block: () => Block,
|
618
|
+
create: () => create,
|
619
|
+
createUnsafe: () => createUnsafe,
|
620
|
+
decode: () => decode,
|
621
|
+
encode: () => encode
|
622
|
+
});
|
623
|
+
var import_multiformats = require("multiformats");
|
624
|
+
var import_block = require("multiformats/block");
|
625
|
+
var Block = import_block.Block;
|
626
|
+
async function decode({
|
627
|
+
bytes,
|
628
|
+
codec: codec3,
|
629
|
+
hasher: hasher7
|
630
|
+
}) {
|
631
|
+
if (bytes == null) throw new Error('Missing required argument "bytes"');
|
632
|
+
if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
|
633
|
+
const value = await Promise.resolve(codec3.decode(bytes));
|
634
|
+
const hash = await hasher7.digest(bytes);
|
635
|
+
const cid = import_multiformats.CID.create(1, codec3.code, hash);
|
636
|
+
return new import_block.Block({ value, bytes, cid });
|
637
|
+
}
|
638
|
+
async function encode({
|
639
|
+
value,
|
640
|
+
codec: codec3,
|
641
|
+
hasher: hasher7
|
642
|
+
}) {
|
643
|
+
if (typeof value === "undefined") throw new Error('Missing required argument "value"');
|
644
|
+
if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
|
645
|
+
const bytes = await Promise.resolve(codec3.encode(value));
|
646
|
+
const hash = await hasher7.digest(bytes);
|
647
|
+
const cid = import_multiformats.CID.create(1, codec3.code, hash);
|
648
|
+
return new import_block.Block({ value, bytes, cid });
|
649
|
+
}
|
650
|
+
async function create({
|
651
|
+
bytes,
|
652
|
+
cid,
|
653
|
+
hasher: hasher7,
|
654
|
+
codec: codec3
|
655
|
+
}) {
|
656
|
+
if (bytes == null) throw new Error('Missing required argument "bytes"');
|
657
|
+
if (hasher7 == null) throw new Error('Missing required argument "hasher"');
|
658
|
+
const value = await Promise.resolve(codec3.decode(bytes));
|
659
|
+
const hash = await hasher7.digest(bytes);
|
660
|
+
if (!import_multiformats.bytes.equals(cid.multihash.bytes, hash.bytes)) {
|
661
|
+
throw new Error("CID hash does not match bytes");
|
662
|
+
}
|
663
|
+
return createUnsafe({
|
664
|
+
bytes,
|
665
|
+
cid,
|
666
|
+
value,
|
667
|
+
codec: codec3
|
668
|
+
});
|
669
|
+
}
|
670
|
+
async function createUnsafe({
|
671
|
+
bytes,
|
672
|
+
cid,
|
673
|
+
value: maybeValue,
|
674
|
+
codec: codec3
|
675
|
+
}) {
|
676
|
+
const value = await Promise.resolve(maybeValue !== void 0 ? maybeValue : codec3?.decode(bytes));
|
677
|
+
if (value === void 0) throw new Error('Missing required argument, must either provide "value" or "codec"');
|
678
|
+
return new Block({
|
679
|
+
cid,
|
680
|
+
bytes,
|
681
|
+
value
|
682
|
+
});
|
683
|
+
}
|
585
684
|
|
586
685
|
// src/blockstore/loader-helpers.ts
|
587
686
|
var import_sha2 = require("multiformats/hashes/sha2");
|
@@ -600,7 +699,7 @@ async function parseCarFile(reader, logger) {
|
|
600
699
|
|
601
700
|
// src/blockstore/transaction.ts
|
602
701
|
var import_block3 = require("@fireproof/vendor/@web3-storage/pail/block");
|
603
|
-
var
|
702
|
+
var import_cement3 = require("@adviser/cement");
|
604
703
|
var CarTransaction = class extends import_block3.MemoryBlockstore {
|
605
704
|
constructor(parent, opts = { add: true, noLoader: false }) {
|
606
705
|
super();
|
@@ -618,7 +717,6 @@ var CarTransaction = class extends import_block3.MemoryBlockstore {
|
|
618
717
|
};
|
619
718
|
function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
|
620
719
|
const logger = ensureLogger(sthis, component, ctx);
|
621
|
-
const store = opts.store || {};
|
622
720
|
return {
|
623
721
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
624
722
|
applyMeta: (meta, snap) => {
|
@@ -630,30 +728,27 @@ function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
|
|
630
728
|
},
|
631
729
|
autoCompact: 100,
|
632
730
|
public: false,
|
633
|
-
name:
|
731
|
+
// name: undefined,
|
634
732
|
threshold: 1e3 * 1e3,
|
635
733
|
...opts,
|
636
734
|
logger,
|
637
735
|
keyBag: opts.keyBag || {},
|
638
|
-
crypto: (0,
|
639
|
-
|
640
|
-
|
736
|
+
crypto: (0, import_cement3.toCryptoRuntime)(opts.crypto),
|
737
|
+
storeUrls: opts.storeUrls,
|
738
|
+
// storeEnDeFile: ensureStoreEnDeFile(opts.storeEnDeFile),
|
739
|
+
// store,
|
740
|
+
storeRuntime: toStoreRuntime(sthis, ensureStoreEnDeFile(opts.storeEnDeFile))
|
641
741
|
};
|
642
742
|
}
|
643
|
-
function blockstoreFactory(sthis, opts) {
|
644
|
-
if (opts.name) {
|
645
|
-
return new EncryptedBlockstore(sthis, opts);
|
646
|
-
} else {
|
647
|
-
return new BaseBlockstore(opts);
|
648
|
-
}
|
649
|
-
}
|
650
743
|
var BaseBlockstore = class {
|
651
|
-
constructor(ebOpts
|
744
|
+
constructor(ebOpts) {
|
652
745
|
this.transactions = /* @__PURE__ */ new Set();
|
653
746
|
this.sthis = ensureSuperThis(ebOpts);
|
654
747
|
this.ebOpts = defaultedBlockstoreRuntime(this.sthis, ebOpts, "BaseBlockstore");
|
655
748
|
this.logger = this.ebOpts.logger;
|
749
|
+
this.loader = new Loader(this.sthis, ebOpts);
|
656
750
|
}
|
751
|
+
// readonly name?: string;
|
657
752
|
// ready: Promise<void>;
|
658
753
|
ready() {
|
659
754
|
return Promise.resolve();
|
@@ -677,8 +772,11 @@ var BaseBlockstore = class {
|
|
677
772
|
}
|
678
773
|
// TransactionMeta
|
679
774
|
async transaction(fn, _opts) {
|
775
|
+
this.logger.Debug().Msg("enter transaction");
|
680
776
|
const t = new CarTransaction(this, _opts);
|
777
|
+
this.logger.Debug().Msg("post CarTransaction");
|
681
778
|
const done = await fn(t);
|
779
|
+
this.logger.Debug().Msg("post fn");
|
682
780
|
this.lastTxMeta = done;
|
683
781
|
return { t, meta: done };
|
684
782
|
}
|
@@ -687,7 +785,7 @@ var BaseBlockstore = class {
|
|
687
785
|
}
|
688
786
|
async commitTransaction(t, done, opts) {
|
689
787
|
if (!this.loader) throw this.logger.Error().Msg("loader required to commit").AsError();
|
690
|
-
const cars = await this.loader
|
788
|
+
const cars = await this.loader.commit(t, done, opts);
|
691
789
|
if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
|
692
790
|
setTimeout(() => void this.compact(), 10);
|
693
791
|
}
|
@@ -712,14 +810,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
|
|
712
810
|
constructor(sthis, ebOpts) {
|
713
811
|
super(ebOpts);
|
714
812
|
this.compacting = false;
|
715
|
-
this.logger = ensureLogger(this.sthis, "EncryptedBlockstore"
|
716
|
-
|
717
|
-
|
718
|
-
throw this.logger.Error().Msg("name required").AsError();
|
719
|
-
}
|
720
|
-
this.name = name;
|
721
|
-
this.loader = new Loader(this.name, ebOpts, sthis);
|
813
|
+
this.logger = ensureLogger(this.sthis, "EncryptedBlockstore", {
|
814
|
+
this: 1
|
815
|
+
});
|
722
816
|
}
|
817
|
+
// readonly name: string;
|
723
818
|
ready() {
|
724
819
|
return this.loader.ready();
|
725
820
|
}
|
@@ -738,8 +833,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
|
|
738
833
|
return falsyToUndef(await this.loader.getBlock(cid));
|
739
834
|
}
|
740
835
|
async transaction(fn, opts = { noLoader: false }) {
|
836
|
+
this.logger.Debug().Msg("enter transaction");
|
741
837
|
const { t, meta: done } = await super.transaction(fn);
|
838
|
+
this.logger.Debug().Msg("post super.transaction");
|
742
839
|
const cars = await this.loader.commit(t, done, opts);
|
840
|
+
this.logger.Debug().Msg("post this.loader.commit");
|
743
841
|
if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
|
744
842
|
setTimeout(() => void this.compact(), 10);
|
745
843
|
}
|
@@ -769,7 +867,7 @@ var EncryptedBlockstore = class extends BaseBlockstore {
|
|
769
867
|
const blockLog = new CompactionFetcher(this);
|
770
868
|
this.compacting = true;
|
771
869
|
const meta = await compactFn(blockLog);
|
772
|
-
await this.loader
|
870
|
+
await this.loader.commit(blockLog.loggedBlocks, meta, {
|
773
871
|
compact: true,
|
774
872
|
noLoader: true
|
775
873
|
});
|
@@ -811,7 +909,7 @@ var CompactionFetcher = class {
|
|
811
909
|
};
|
812
910
|
|
813
911
|
// src/blockstore/commit-queue.ts
|
814
|
-
var
|
912
|
+
var import_cement4 = require("@adviser/cement");
|
815
913
|
var CommitQueue = class {
|
816
914
|
constructor() {
|
817
915
|
this.queue = [];
|
@@ -822,7 +920,7 @@ var CommitQueue = class {
|
|
822
920
|
if (this.queue.length === 0 && !this.processing) {
|
823
921
|
return Promise.resolve();
|
824
922
|
}
|
825
|
-
const fn = new
|
923
|
+
const fn = new import_cement4.Future();
|
826
924
|
this._waitIdleItems.add(fn);
|
827
925
|
return fn.asPromise();
|
828
926
|
}
|
@@ -865,22 +963,103 @@ var CommitQueue = class {
|
|
865
963
|
var key_bag_exports = {};
|
866
964
|
__export(key_bag_exports, {
|
867
965
|
KeyBag: () => KeyBag,
|
966
|
+
defaultKeyBagOpts: () => defaultKeyBagOpts,
|
868
967
|
defaultKeyBagUrl: () => defaultKeyBagUrl,
|
869
968
|
getKeyBag: () => getKeyBag,
|
870
969
|
registerKeyBagProviderFactory: () => registerKeyBagProviderFactory
|
871
970
|
});
|
872
|
-
var
|
971
|
+
var import_cement6 = require("@adviser/cement");
|
873
972
|
var import_base582 = require("multiformats/bases/base58");
|
973
|
+
|
974
|
+
// src/runtime/gateways/file/sys-file-system-factory.ts
|
975
|
+
var import_cement5 = require("@adviser/cement");
|
976
|
+
function sysFileSystemFactory(uri) {
|
977
|
+
const rt = (0, import_cement5.runtimeFn)();
|
978
|
+
switch (true) {
|
979
|
+
case rt.isNodeIsh:
|
980
|
+
return import("@fireproof/core/node").then((m) => m.getSysFileSystem(uri));
|
981
|
+
case rt.isDeno:
|
982
|
+
return import("@fireproof/core/deno").then((m) => m.getSysFileSystem(uri));
|
983
|
+
default:
|
984
|
+
throw new Error(`unsupported runtime:${rt}`);
|
985
|
+
}
|
986
|
+
}
|
987
|
+
|
988
|
+
// src/runtime/gateways/file/key-bag-file.ts
|
989
|
+
var KeyBagProviderFile = class {
|
990
|
+
async _prepare(id) {
|
991
|
+
await this.sthis.start();
|
992
|
+
const sysFS = await sysFileSystemFactory(this.url);
|
993
|
+
const dirName = this.url.pathname;
|
994
|
+
await sysFS.mkdir(dirName, { recursive: true });
|
995
|
+
return {
|
996
|
+
dirName,
|
997
|
+
sysFS,
|
998
|
+
fName: this.sthis.pathOps.join(dirName, `${id.replace(/[^a-zA-Z0-9]/g, "_")}.json`)
|
999
|
+
};
|
1000
|
+
}
|
1001
|
+
constructor(url, sthis) {
|
1002
|
+
this.url = url;
|
1003
|
+
this.sthis = sthis;
|
1004
|
+
this.logger = sthis.logger;
|
1005
|
+
}
|
1006
|
+
async get(id) {
|
1007
|
+
const ctx = await this._prepare(id);
|
1008
|
+
try {
|
1009
|
+
const p = await ctx.sysFS.readfile(ctx.fName);
|
1010
|
+
const ki = JSON.parse(this.sthis.txt.decode(p));
|
1011
|
+
return ki;
|
1012
|
+
} catch (e) {
|
1013
|
+
if (isNotFoundError(e)) {
|
1014
|
+
return void 0;
|
1015
|
+
}
|
1016
|
+
throw this.logger.Error().Err(e).Str("file", ctx.dirName).Msg("read bag failed").AsError();
|
1017
|
+
}
|
1018
|
+
}
|
1019
|
+
async set(id, item) {
|
1020
|
+
const ctx = await this._prepare(id);
|
1021
|
+
const p = this.sthis.txt.encode(JSON.stringify(item, null, 2));
|
1022
|
+
await ctx.sysFS.writefile(ctx.fName, p);
|
1023
|
+
}
|
1024
|
+
};
|
1025
|
+
|
1026
|
+
// src/runtime/key-bag-memory.ts
|
1027
|
+
var memoryKeyBag = /* @__PURE__ */ new Map();
|
1028
|
+
var KeyBagProviderMemory = class {
|
1029
|
+
constructor(url, sthis) {
|
1030
|
+
this.url = url;
|
1031
|
+
this.sthis = sthis;
|
1032
|
+
}
|
1033
|
+
key(id) {
|
1034
|
+
return `${this.url.pathname}/${id}`;
|
1035
|
+
}
|
1036
|
+
async get(id) {
|
1037
|
+
const binKeyItem = memoryKeyBag.get(this.key(id));
|
1038
|
+
if (binKeyItem) {
|
1039
|
+
const ki = JSON.parse(this.sthis.txt.decode(binKeyItem));
|
1040
|
+
return ki;
|
1041
|
+
}
|
1042
|
+
return void 0;
|
1043
|
+
}
|
1044
|
+
async set(id, item) {
|
1045
|
+
const p = this.sthis.txt.encode(JSON.stringify(item, null, 2));
|
1046
|
+
memoryKeyBag.set(this.key(id), p);
|
1047
|
+
}
|
1048
|
+
};
|
1049
|
+
|
1050
|
+
// src/runtime/key-bag.ts
|
874
1051
|
var KeyBag = class {
|
875
1052
|
constructor(rt) {
|
876
1053
|
this.rt = rt;
|
877
|
-
this._warnOnce = new
|
878
|
-
this._seq = new
|
879
|
-
this.logger = ensureLogger(rt.sthis, "KeyBag"
|
1054
|
+
this._warnOnce = new import_cement6.ResolveOnce();
|
1055
|
+
this._seq = new import_cement6.ResolveSeq();
|
1056
|
+
this.logger = ensureLogger(rt.sthis, "KeyBag", {
|
1057
|
+
// id: rt.id(),
|
1058
|
+
});
|
880
1059
|
this.logger.Debug().Msg("KeyBag created");
|
881
1060
|
}
|
882
1061
|
async subtleKey(key) {
|
883
|
-
const extractable = this.rt.url.getParam("extractKey") === "_deprecated_internal_api";
|
1062
|
+
const extractable = this.rt.url.getParam("extractKey" /* EXTRACTKEY */) === "_deprecated_internal_api";
|
884
1063
|
if (extractable) {
|
885
1064
|
this._warnOnce.once(
|
886
1065
|
() => this.logger.Warn().Msg("extractKey is enabled via _deprecated_internal_api --- handle keys safely!!!")
|
@@ -897,9 +1076,9 @@ var KeyBag = class {
|
|
897
1076
|
);
|
898
1077
|
}
|
899
1078
|
async ensureKeyFromUrl(url, keyFactory) {
|
900
|
-
const storeKey = url.getParam("storekey");
|
1079
|
+
const storeKey = url.getParam("storekey" /* STORE_KEY */);
|
901
1080
|
if (storeKey === "insecure") {
|
902
|
-
return
|
1081
|
+
return import_cement6.Result.Ok(url);
|
903
1082
|
}
|
904
1083
|
if (!storeKey) {
|
905
1084
|
const keyName = `@${keyFactory()}@`;
|
@@ -907,8 +1086,8 @@ var KeyBag = class {
|
|
907
1086
|
if (ret.isErr()) {
|
908
1087
|
return ret;
|
909
1088
|
}
|
910
|
-
const urb = url.build().setParam("storekey"
|
911
|
-
return
|
1089
|
+
const urb = url.build().setParam("storekey" /* STORE_KEY */, keyName);
|
1090
|
+
return import_cement6.Result.Ok(urb.URI());
|
912
1091
|
}
|
913
1092
|
if (storeKey.startsWith("@") && storeKey.endsWith("@")) {
|
914
1093
|
const ret = await this.getNamedKey(storeKey);
|
@@ -916,13 +1095,13 @@ var KeyBag = class {
|
|
916
1095
|
return ret;
|
917
1096
|
}
|
918
1097
|
}
|
919
|
-
return
|
1098
|
+
return import_cement6.Result.Ok(url);
|
920
1099
|
}
|
921
1100
|
async toKeyWithFingerPrint(keyStr) {
|
922
1101
|
const material = import_base582.base58btc.decode(keyStr);
|
923
1102
|
const key = await this.subtleKey(keyStr);
|
924
1103
|
const fpr = await this.rt.crypto.digestSHA256(material);
|
925
|
-
return
|
1104
|
+
return import_cement6.Result.Ok({
|
926
1105
|
key,
|
927
1106
|
fingerPrint: import_base582.base58btc.encode(new Uint8Array(fpr))
|
928
1107
|
});
|
@@ -947,7 +1126,7 @@ var KeyBag = class {
|
|
947
1126
|
return ret;
|
948
1127
|
}
|
949
1128
|
const named = ret.Ok();
|
950
|
-
return
|
1129
|
+
return import_cement6.Result.Ok({
|
951
1130
|
...named,
|
952
1131
|
extract: async () => {
|
953
1132
|
const ext = new Uint8Array(await this.rt.crypto.exportKey("raw", named.key));
|
@@ -970,7 +1149,7 @@ var KeyBag = class {
|
|
970
1149
|
}
|
971
1150
|
if (failIfNotFound) {
|
972
1151
|
this.logger.Debug().Str("id", id).Str("name", name).Msg("failIfNotFound getNamedKey");
|
973
|
-
return
|
1152
|
+
return import_cement6.Result.Err(new Error(`Key not found: ${name}`));
|
974
1153
|
}
|
975
1154
|
const ret = await this._setNamedKey(name, import_base582.base58btc.encode(this.rt.crypto.randomBytes(this.rt.keyLength)));
|
976
1155
|
this.logger.Debug().Str("id", id).Str("name", name).Result("fpr", ret).Msg("createKey getNamedKey-post");
|
@@ -983,8 +1162,7 @@ var keyBagProviderFactories = new Map(
|
|
983
1162
|
{
|
984
1163
|
protocol: "file:",
|
985
1164
|
factory: async (url, sthis) => {
|
986
|
-
|
987
|
-
return new KeyBagProviderImpl(url, sthis);
|
1165
|
+
return new KeyBagProviderFile(url, sthis);
|
988
1166
|
}
|
989
1167
|
},
|
990
1168
|
{
|
@@ -993,6 +1171,12 @@ var keyBagProviderFactories = new Map(
|
|
993
1171
|
const { KeyBagProviderImpl } = await import("@fireproof/core/web");
|
994
1172
|
return new KeyBagProviderImpl(url, sthis);
|
995
1173
|
}
|
1174
|
+
},
|
1175
|
+
{
|
1176
|
+
protocol: "memory:",
|
1177
|
+
factory: async (url, sthis) => {
|
1178
|
+
return new KeyBagProviderMemory(url, sthis);
|
1179
|
+
}
|
996
1180
|
}
|
997
1181
|
].map((i) => [i.protocol, i])
|
998
1182
|
);
|
@@ -1006,15 +1190,15 @@ function registerKeyBagProviderFactory(item) {
|
|
1006
1190
|
function defaultKeyBagUrl(sthis) {
|
1007
1191
|
let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
|
1008
1192
|
let url;
|
1009
|
-
if ((0,
|
1010
|
-
url =
|
1193
|
+
if ((0, import_cement6.runtimeFn)().isBrowser) {
|
1194
|
+
url = import_cement6.URI.from(bagFnameOrUrl || "indexdb://fp-keybag");
|
1011
1195
|
} else {
|
1012
1196
|
if (!bagFnameOrUrl) {
|
1013
1197
|
const home = sthis.env.get("HOME");
|
1014
1198
|
bagFnameOrUrl = `${home}/.fireproof/keybag`;
|
1015
|
-
url =
|
1199
|
+
url = import_cement6.URI.from(`file://${bagFnameOrUrl}`);
|
1016
1200
|
} else {
|
1017
|
-
url =
|
1201
|
+
url = import_cement6.URI.from(bagFnameOrUrl);
|
1018
1202
|
}
|
1019
1203
|
}
|
1020
1204
|
const logger = ensureLogger(sthis, "defaultKeyBagUrl");
|
@@ -1022,38 +1206,50 @@ function defaultKeyBagUrl(sthis) {
|
|
1022
1206
|
return url;
|
1023
1207
|
}
|
1024
1208
|
function defaultKeyBagOpts(sthis, kbo) {
|
1209
|
+
kbo = kbo || {};
|
1025
1210
|
if (kbo.keyRuntime) {
|
1026
1211
|
return kbo.keyRuntime;
|
1027
1212
|
}
|
1028
1213
|
const logger = ensureLogger(sthis, "KeyBag");
|
1029
1214
|
let url;
|
1030
1215
|
if (kbo.url) {
|
1031
|
-
url =
|
1216
|
+
url = import_cement6.URI.from(kbo.url);
|
1032
1217
|
logger.Debug().Url(url).Msg("from opts");
|
1033
1218
|
} else {
|
1034
|
-
|
1219
|
+
let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
|
1220
|
+
if ((0, import_cement6.runtimeFn)().isBrowser) {
|
1221
|
+
url = import_cement6.URI.from(bagFnameOrUrl || "indexdb://fp-keybag");
|
1222
|
+
} else {
|
1223
|
+
if (!bagFnameOrUrl) {
|
1224
|
+
const home = sthis.env.get("HOME");
|
1225
|
+
bagFnameOrUrl = `${home}/.fireproof/keybag`;
|
1226
|
+
url = import_cement6.URI.from(`file://${bagFnameOrUrl}`);
|
1227
|
+
} else {
|
1228
|
+
url = import_cement6.URI.from(bagFnameOrUrl);
|
1229
|
+
}
|
1230
|
+
}
|
1231
|
+
logger.Debug().Url(url).Msg("from env");
|
1035
1232
|
}
|
1036
1233
|
const kitem = keyBagProviderFactories.get(url.protocol);
|
1037
1234
|
if (!kitem) {
|
1038
1235
|
throw logger.Error().Url(url).Msg("unsupported protocol").AsError();
|
1039
1236
|
}
|
1040
|
-
const getBag = async () => kitem.factory(url, sthis);
|
1041
1237
|
if (url.hasParam("masterkey")) {
|
1042
1238
|
throw logger.Error().Url(url).Msg("masterkey is not supported").AsError();
|
1043
1239
|
}
|
1044
1240
|
return {
|
1045
1241
|
url,
|
1046
|
-
crypto: kbo.crypto || (0,
|
1242
|
+
crypto: kbo.crypto || (0, import_cement6.toCryptoRuntime)({}),
|
1047
1243
|
sthis,
|
1048
1244
|
logger,
|
1049
1245
|
keyLength: kbo.keyLength || 16,
|
1050
|
-
getBag,
|
1246
|
+
getBag: () => kitem.factory(url, sthis),
|
1051
1247
|
id: () => {
|
1052
1248
|
return url.toString();
|
1053
1249
|
}
|
1054
1250
|
};
|
1055
1251
|
}
|
1056
|
-
var _keyBags = new
|
1252
|
+
var _keyBags = new import_cement6.KeyedResolvOnce();
|
1057
1253
|
async function getKeyBag(sthis, kbo = {}) {
|
1058
1254
|
await sthis.start();
|
1059
1255
|
const rt = defaultKeyBagOpts(sthis, kbo);
|
@@ -1072,7 +1268,7 @@ async function encodeCarFile(roots, t, codec3) {
|
|
1072
1268
|
size += CBW.blockLength({ cid, bytes });
|
1073
1269
|
}
|
1074
1270
|
const buffer = new Uint8Array(size);
|
1075
|
-
const writer = CBW.createWriter(buffer, { headerSize });
|
1271
|
+
const writer = CBW.createWriter(buffer.buffer, { headerSize });
|
1076
1272
|
for (const r of roots) {
|
1077
1273
|
writer.addRoot(r);
|
1078
1274
|
}
|
@@ -1227,7 +1423,7 @@ function uniqueCids(list, remove = /* @__PURE__ */ new Set()) {
|
|
1227
1423
|
return [...byString.values()];
|
1228
1424
|
}
|
1229
1425
|
var Loader = class {
|
1230
|
-
constructor(
|
1426
|
+
constructor(sthis, ebOpts) {
|
1231
1427
|
this.commitQueue = new CommitQueue();
|
1232
1428
|
this.isCompacting = false;
|
1233
1429
|
this.carReaders = /* @__PURE__ */ new Map();
|
@@ -1237,14 +1433,17 @@ var Loader = class {
|
|
1237
1433
|
this.getBlockCache = /* @__PURE__ */ new Map();
|
1238
1434
|
this.seenMeta = /* @__PURE__ */ new Set();
|
1239
1435
|
this.writeLimit = (0, import_p_limit.default)(1);
|
1240
|
-
this.
|
1241
|
-
this.
|
1436
|
+
this._carStore = new import_cement7.ResolveOnce();
|
1437
|
+
this._fileStore = new import_cement7.ResolveOnce();
|
1438
|
+
this._WALStore = new import_cement7.ResolveOnce();
|
1439
|
+
this._metaStore = new import_cement7.ResolveOnce();
|
1440
|
+
this.onceReady = new import_cement7.ResolveOnce();
|
1242
1441
|
this.sthis = sthis;
|
1243
1442
|
this.ebOpts = defaultedBlockstoreRuntime(
|
1244
1443
|
sthis,
|
1245
1444
|
{
|
1246
|
-
...ebOpts
|
1247
|
-
name
|
1445
|
+
...ebOpts
|
1446
|
+
// name,
|
1248
1447
|
},
|
1249
1448
|
"Loader"
|
1250
1449
|
);
|
@@ -1253,21 +1452,52 @@ var Loader = class {
|
|
1253
1452
|
await this.handleDbMetasFromStore([dbMeta]);
|
1254
1453
|
});
|
1255
1454
|
}
|
1256
|
-
// readonly id = uuidv4();
|
1257
|
-
async keyBag() {
|
1258
|
-
return getKeyBag(this.sthis, this.ebOpts.keyBag);
|
1259
|
-
}
|
1260
1455
|
async carStore() {
|
1261
|
-
return this.
|
1456
|
+
return this._carStore.once(
|
1457
|
+
async () => this.ebOpts.storeRuntime.makeDataStore({
|
1458
|
+
sthis: this.sthis,
|
1459
|
+
gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
1460
|
+
url: this.ebOpts.storeUrls.data,
|
1461
|
+
// keybag: await this.keyBag(),
|
1462
|
+
loader: this
|
1463
|
+
})
|
1464
|
+
);
|
1262
1465
|
}
|
1263
1466
|
async fileStore() {
|
1264
|
-
return this.
|
1467
|
+
return this._fileStore.once(
|
1468
|
+
async () => this.ebOpts.storeRuntime.makeDataStore({
|
1469
|
+
sthis: this.sthis,
|
1470
|
+
gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
1471
|
+
url: this.ebOpts.storeUrls.file,
|
1472
|
+
// keybag: await this.keyBag(),
|
1473
|
+
loader: this
|
1474
|
+
})
|
1475
|
+
);
|
1265
1476
|
}
|
1266
1477
|
async WALStore() {
|
1267
|
-
return this.
|
1478
|
+
return this._WALStore.once(
|
1479
|
+
async () => this.ebOpts.storeRuntime.makeWALStore({
|
1480
|
+
sthis: this.sthis,
|
1481
|
+
gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
1482
|
+
url: this.ebOpts.storeUrls.wal,
|
1483
|
+
// keybag: await this.keyBag(),
|
1484
|
+
loader: this
|
1485
|
+
})
|
1486
|
+
);
|
1268
1487
|
}
|
1269
1488
|
async metaStore() {
|
1270
|
-
return this.
|
1489
|
+
return this._metaStore.once(
|
1490
|
+
async () => this.ebOpts.storeRuntime.makeMetaStore({
|
1491
|
+
sthis: this.sthis,
|
1492
|
+
gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
1493
|
+
url: this.ebOpts.storeUrls.meta,
|
1494
|
+
// keybag: await this.keyBag(),
|
1495
|
+
loader: this
|
1496
|
+
})
|
1497
|
+
);
|
1498
|
+
}
|
1499
|
+
keyBag() {
|
1500
|
+
return getKeyBag(this.sthis, this.ebOpts.keyBag);
|
1271
1501
|
}
|
1272
1502
|
async ready() {
|
1273
1503
|
return this.onceReady.once(async () => {
|
@@ -1280,6 +1510,7 @@ var Loader = class {
|
|
1280
1510
|
});
|
1281
1511
|
}
|
1282
1512
|
async close() {
|
1513
|
+
await this.commitQueue.waitIdle();
|
1283
1514
|
const toClose = await Promise.all([this.carStore(), this.metaStore(), this.fileStore(), this.WALStore()]);
|
1284
1515
|
await Promise.all(toClose.map((store) => store.close()));
|
1285
1516
|
}
|
@@ -1349,11 +1580,11 @@ var Loader = class {
|
|
1349
1580
|
}
|
1350
1581
|
async commit(t, done, opts = { noLoader: false, compact: false }) {
|
1351
1582
|
await this.ready();
|
1352
|
-
const
|
1583
|
+
const carStore = await this.carStore();
|
1353
1584
|
const params = {
|
1354
|
-
encoder: (await
|
1585
|
+
encoder: (await carStore.keyedCrypto()).codec(),
|
1355
1586
|
carLog: this.carLog,
|
1356
|
-
carStore
|
1587
|
+
carStore,
|
1357
1588
|
WALStore: await this.WALStore(),
|
1358
1589
|
metaStore: await this.metaStore(),
|
1359
1590
|
threshold: this.ebOpts.threshold
|
@@ -1587,12 +1818,12 @@ var generateIV = {
|
|
1587
1818
|
return hashArray;
|
1588
1819
|
},
|
1589
1820
|
verify: async function(ko, crypto, iv, data) {
|
1590
|
-
return ko.url.getParam("
|
1821
|
+
return ko.url.getParam("ivVerify" /* IV_VERIFY */) !== "disable" && UInt8ArrayEqual(iv, await this.calc(ko, crypto, data));
|
1591
1822
|
}
|
1592
1823
|
}
|
1593
1824
|
};
|
1594
1825
|
function getGenerateIVFn(url, opts) {
|
1595
|
-
const ivhash = opts.ivCalc || url.getParam("
|
1826
|
+
const ivhash = opts.ivCalc || url.getParam("ivHash" /* IV_HASH */) || "hash";
|
1596
1827
|
return generateIV[ivhash] || generateIV["hash"];
|
1597
1828
|
}
|
1598
1829
|
var BlockIvKeyIdCodec = class {
|
@@ -1713,7 +1944,7 @@ var noCrypto = class {
|
|
1713
1944
|
}
|
1714
1945
|
};
|
1715
1946
|
async function keyedCryptoFactory(url, kb, sthis) {
|
1716
|
-
const storekey = url.getParam("storekey");
|
1947
|
+
const storekey = url.getParam("storekey" /* STORE_KEY */);
|
1717
1948
|
if (storekey && storekey !== "insecure") {
|
1718
1949
|
let rkey = await kb.getNamedKey(storekey, true);
|
1719
1950
|
if (rkey.isErr()) {
|
@@ -1728,294 +1959,189 @@ async function keyedCryptoFactory(url, kb, sthis) {
|
|
1728
1959
|
return new noCrypto(url, kb.rt.crypto, sthis);
|
1729
1960
|
}
|
1730
1961
|
|
1731
|
-
// src/blockstore/
|
1732
|
-
var
|
1733
|
-
var
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1737
|
-
|
1738
|
-
|
1739
|
-
|
1962
|
+
// src/blockstore/fp-envelope.ts
|
1963
|
+
var import_cement8 = require("@adviser/cement");
|
1964
|
+
var FPEnvelopeType = /* @__PURE__ */ ((FPEnvelopeType2) => {
|
1965
|
+
FPEnvelopeType2["CAR"] = "car";
|
1966
|
+
FPEnvelopeType2["FILE"] = "file";
|
1967
|
+
FPEnvelopeType2["META"] = "meta";
|
1968
|
+
FPEnvelopeType2["WAL"] = "wal";
|
1969
|
+
return FPEnvelopeType2;
|
1970
|
+
})(FPEnvelopeType || {});
|
1971
|
+
function Car2FPMsg(fpcar) {
|
1972
|
+
return import_cement8.Result.Ok({ type: "car" /* CAR */, payload: fpcar });
|
1973
|
+
}
|
1974
|
+
function File2FPMsg(fpfile) {
|
1975
|
+
return import_cement8.Result.Ok({ type: "file" /* FILE */, payload: fpfile });
|
1976
|
+
}
|
1977
|
+
|
1978
|
+
// src/blockstore/store.ts
|
1979
|
+
var import_clock = require("@fireproof/vendor/@web3-storage/pail/clock");
|
1980
|
+
var import_dag_json = require("@fireproof/vendor/@ipld/dag-json");
|
1981
|
+
var import_p_retry = __toESM(require("p-retry"), 1);
|
1982
|
+
var import_p_map = __toESM(require("p-map"), 1);
|
1983
|
+
|
1984
|
+
// src/blockstore/interceptor-gateway.ts
|
1985
|
+
var import_cement9 = require("@adviser/cement");
|
1986
|
+
var PassThroughGateway = class {
|
1987
|
+
async buildUrl(sthis, url, key) {
|
1988
|
+
const op = { url, key };
|
1989
|
+
return import_cement9.Result.Ok({ op });
|
1740
1990
|
}
|
1741
|
-
|
1742
|
-
|
1991
|
+
async start(sthis, url) {
|
1992
|
+
const op = { url };
|
1993
|
+
return import_cement9.Result.Ok({ op });
|
1743
1994
|
}
|
1744
|
-
|
1745
|
-
}
|
1746
|
-
|
1747
|
-
const fragSize = getFragSize(url);
|
1748
|
-
if (!fragSize) {
|
1749
|
-
const res = await innerGW.get(url);
|
1750
|
-
if (res.isErr()) {
|
1751
|
-
return [res];
|
1752
|
-
}
|
1753
|
-
const data = res.unwrap();
|
1754
|
-
return [
|
1755
|
-
import_cement6.Result.Ok({
|
1756
|
-
fid: new Uint8Array(0),
|
1757
|
-
ofs: 0,
|
1758
|
-
len: data.length,
|
1759
|
-
data
|
1760
|
-
})
|
1761
|
-
];
|
1762
|
-
}
|
1763
|
-
const firstRaw = await innerGW.get(url.build().setParam("ofs", "0").URI());
|
1764
|
-
if (firstRaw.isErr()) {
|
1765
|
-
return [firstRaw];
|
1766
|
-
}
|
1767
|
-
const firstFragment = (0, import_cborg.decode)(firstRaw.unwrap());
|
1768
|
-
const blockSize = firstFragment.data.length;
|
1769
|
-
const ops = [Promise.resolve(import_cement6.Result.Ok(firstFragment))];
|
1770
|
-
const fidStr = import_base584.base58btc.encode(firstFragment.fid);
|
1771
|
-
const fragUrl = url.build().setParam("fid", fidStr).setParam("len", firstFragment.len.toString()).setParam("headerSize", headerSize.toString());
|
1772
|
-
for (let ofs = blockSize; ofs < firstFragment.len; ofs += blockSize) {
|
1773
|
-
ops.push(
|
1774
|
-
(async (furl, ofs2) => {
|
1775
|
-
const raw2 = await innerGW.get(furl);
|
1776
|
-
if (raw2.isErr()) {
|
1777
|
-
return raw2;
|
1778
|
-
}
|
1779
|
-
const fragment = (0, import_cborg.decode)(raw2.unwrap());
|
1780
|
-
if (import_base584.base58btc.encode(fragment.fid) !== fidStr) {
|
1781
|
-
return import_cement6.Result.Err(logger.Error().Msg("Fragment fid mismatch").AsError());
|
1782
|
-
}
|
1783
|
-
if (fragment.ofs !== ofs2) {
|
1784
|
-
return import_cement6.Result.Err(logger.Error().Uint64("ofs", ofs2).Msg("Fragment ofs mismatch").AsError());
|
1785
|
-
}
|
1786
|
-
return import_cement6.Result.Ok(fragment);
|
1787
|
-
})(fragUrl.setParam("ofs", ofs.toString()).URI(), ofs)
|
1788
|
-
);
|
1995
|
+
async close(sthis, url) {
|
1996
|
+
const op = { url };
|
1997
|
+
return import_cement9.Result.Ok({ op });
|
1789
1998
|
}
|
1790
|
-
|
1791
|
-
}
|
1792
|
-
|
1793
|
-
|
1794
|
-
|
1795
|
-
|
1796
|
-
|
1797
|
-
|
1999
|
+
async delete(sthis, url) {
|
2000
|
+
const op = { url };
|
2001
|
+
return import_cement9.Result.Ok({ op });
|
2002
|
+
}
|
2003
|
+
async destroy(sthis, url) {
|
2004
|
+
const op = { url };
|
2005
|
+
return import_cement9.Result.Ok({ op });
|
2006
|
+
}
|
2007
|
+
async put(sthis, url, body) {
|
2008
|
+
const op = { url, body };
|
2009
|
+
return import_cement9.Result.Ok({ op });
|
2010
|
+
}
|
2011
|
+
async get(sthis, url) {
|
2012
|
+
const op = { url };
|
2013
|
+
return import_cement9.Result.Ok({ op });
|
2014
|
+
}
|
2015
|
+
async subscribe(sthis, url, callback) {
|
2016
|
+
const op = { url, callback };
|
2017
|
+
return import_cement9.Result.Ok({ op });
|
2018
|
+
}
|
2019
|
+
};
|
2020
|
+
var passThrougthGateway = new PassThroughGateway();
|
2021
|
+
var InterceptorGateway = class {
|
2022
|
+
constructor(sthis, innerGW, interceptor) {
|
1798
2023
|
this.innerGW = innerGW;
|
2024
|
+
this.interceptor = interceptor || passThrougthGateway;
|
1799
2025
|
}
|
1800
|
-
|
1801
|
-
const
|
1802
|
-
if (
|
1803
|
-
return
|
1804
|
-
}
|
1805
|
-
const
|
1806
|
-
if (
|
1807
|
-
|
1808
|
-
}
|
1809
|
-
|
1810
|
-
|
1811
|
-
|
1812
|
-
|
1813
|
-
|
1814
|
-
|
1815
|
-
|
1816
|
-
|
1817
|
-
|
1818
|
-
|
1819
|
-
|
1820
|
-
|
1821
|
-
|
1822
|
-
|
2026
|
+
async buildUrl(sthis, baseUrl, key, loader) {
|
2027
|
+
const rret = await this.interceptor.buildUrl(sthis, baseUrl, key, loader);
|
2028
|
+
if (rret.isErr()) {
|
2029
|
+
return import_cement9.Result.Err(rret.Err());
|
2030
|
+
}
|
2031
|
+
const ret = rret.unwrap();
|
2032
|
+
if (ret.stop && ret.value) {
|
2033
|
+
return ret.value;
|
2034
|
+
}
|
2035
|
+
return this.innerGW.buildUrl(sthis, ret.op.url, ret.op.key, loader);
|
2036
|
+
}
|
2037
|
+
async destroy(sthis, iurl, loader) {
|
2038
|
+
const rret = await this.interceptor.destroy(sthis, iurl, loader);
|
2039
|
+
if (rret.isErr()) {
|
2040
|
+
return import_cement9.Result.Err(rret.Err());
|
2041
|
+
}
|
2042
|
+
const ret = rret.unwrap();
|
2043
|
+
if (ret.stop && ret.value) {
|
2044
|
+
return ret.value;
|
2045
|
+
}
|
2046
|
+
return this.innerGW.destroy(sthis, ret.op.url, loader);
|
2047
|
+
}
|
2048
|
+
async start(sthis, url, loader) {
|
2049
|
+
const rret = await this.interceptor.start(sthis, url, loader);
|
2050
|
+
if (rret.isErr()) {
|
2051
|
+
return import_cement9.Result.Err(rret.Err());
|
2052
|
+
}
|
2053
|
+
const ret = rret.unwrap();
|
2054
|
+
if (ret.stop && ret.value) {
|
2055
|
+
return ret.value;
|
2056
|
+
}
|
2057
|
+
return await this.innerGW.start(sthis, ret.op.url, loader);
|
2058
|
+
}
|
2059
|
+
async close(sthis, url, loader) {
|
2060
|
+
const rret = await this.interceptor.close(sthis, url, loader);
|
2061
|
+
if (rret.isErr()) {
|
2062
|
+
return import_cement9.Result.Err(rret.Err());
|
2063
|
+
}
|
2064
|
+
const ret = rret.unwrap();
|
2065
|
+
if (ret.stop && ret.value) {
|
2066
|
+
return ret.value;
|
1823
2067
|
}
|
1824
|
-
return
|
2068
|
+
return await this.innerGW.close(sthis, ret.op.url, loader);
|
1825
2069
|
}
|
1826
|
-
|
1827
|
-
|
1828
|
-
|
1829
|
-
|
1830
|
-
return this.innerGW.destroy(iurl);
|
1831
|
-
}
|
1832
|
-
async start(url) {
|
1833
|
-
this.headerSize = (0, import_cborg.encode)({
|
1834
|
-
fid: this.sthis.nextId(this.fidLength).bin,
|
1835
|
-
ofs: 1024 * 1024,
|
1836
|
-
// 32bit
|
1837
|
-
len: 16 * 1024 * 1024,
|
1838
|
-
// 32bit
|
1839
|
-
data: new Uint8Array(1024)
|
1840
|
-
}).length - 1024;
|
1841
|
-
return this.innerGW.start(url);
|
1842
|
-
}
|
1843
|
-
async close(url) {
|
1844
|
-
return this.innerGW.close(url);
|
1845
|
-
}
|
1846
|
-
async put(url, body) {
|
1847
|
-
await Promise.all(this.slicer(url, body));
|
1848
|
-
return import_cement6.Result.Ok(void 0);
|
1849
|
-
}
|
1850
|
-
async get(url) {
|
1851
|
-
const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
|
1852
|
-
let buffer = void 0;
|
1853
|
-
for (const rfrag of rfrags) {
|
1854
|
-
if (rfrag.isErr()) {
|
1855
|
-
return import_cement6.Result.Err(rfrag.Err());
|
1856
|
-
}
|
1857
|
-
const frag = rfrag.Ok();
|
1858
|
-
buffer = buffer || new Uint8Array(frag.len);
|
1859
|
-
buffer.set(frag.data, frag.ofs);
|
1860
|
-
}
|
1861
|
-
return import_cement6.Result.Ok(buffer || new Uint8Array(0));
|
1862
|
-
}
|
1863
|
-
async subscribe(url, callback) {
|
1864
|
-
if (this.innerGW.subscribe) {
|
1865
|
-
return this.innerGW.subscribe(url, callback);
|
1866
|
-
} else {
|
1867
|
-
return import_cement6.Result.Err(this.logger.Error().Url(url).Msg("subscribe not supported").AsError());
|
2070
|
+
async put(sthis, url, fpEnv, loader) {
|
2071
|
+
const rret = await this.interceptor.put(sthis, url, fpEnv, loader);
|
2072
|
+
if (rret.isErr()) {
|
2073
|
+
return import_cement9.Result.Err(rret.Err());
|
1868
2074
|
}
|
2075
|
+
const ret = rret.unwrap();
|
2076
|
+
if (ret.stop && ret.value) {
|
2077
|
+
return ret.value;
|
2078
|
+
}
|
2079
|
+
return this.innerGW.put(sthis, ret.op.url, ret.op.body, loader);
|
1869
2080
|
}
|
1870
|
-
async
|
1871
|
-
const
|
1872
|
-
|
1873
|
-
|
1874
|
-
return import_cement6.Result.Err(rfrag.Err());
|
1875
|
-
}
|
1876
|
-
const frag = rfrag.Ok();
|
1877
|
-
const fidStr = import_base584.base58btc.encode(frag.fid);
|
1878
|
-
const fragUrl = url.build().setParam("fid", fidStr).setParam("len", frag.len.toString()).setParam("headerSize", this.headerSize.toString()).URI();
|
1879
|
-
await this.innerGW.delete(fragUrl);
|
2081
|
+
async get(sthis, url, loader) {
|
2082
|
+
const rret = await this.interceptor.get(sthis, url, loader);
|
2083
|
+
if (rret.isErr()) {
|
2084
|
+
return import_cement9.Result.Err(rret.Err());
|
1880
2085
|
}
|
1881
|
-
|
2086
|
+
const ret = rret.unwrap();
|
2087
|
+
if (ret.stop && ret.value) {
|
2088
|
+
return ret.value;
|
2089
|
+
}
|
2090
|
+
return this.innerGW.get(sthis, ret.op.url, loader);
|
1882
2091
|
}
|
1883
|
-
|
1884
|
-
|
1885
|
-
|
1886
|
-
|
1887
|
-
|
1888
|
-
|
1889
|
-
|
1890
|
-
var import_cement7 = require("@adviser/cement");
|
1891
|
-
async function decodeGatewayMetaBytesToDbMeta(sthis, byteHeads) {
|
1892
|
-
const crdtEntries = JSON.parse(sthis.txt.decode(byteHeads));
|
1893
|
-
if (!Array.isArray(crdtEntries)) {
|
1894
|
-
sthis.logger.Debug().Str("crdtEntries", JSON.stringify(crdtEntries)).Msg("No data in CRDT entries");
|
1895
|
-
return [];
|
1896
|
-
}
|
1897
|
-
if (!crdtEntries.length) {
|
1898
|
-
sthis.logger.Debug().Any("byteHeads", byteHeads).Msg("No CRDT entries found");
|
1899
|
-
return [];
|
1900
|
-
}
|
1901
|
-
const logger = ensureLogger(sthis, "decodeGatewayMetaBytesToDbMeta");
|
1902
|
-
return Promise.all(
|
1903
|
-
crdtEntries.map(async (crdtEntry) => {
|
1904
|
-
const eventBlock = await (0, import_clock.decodeEventBlock)(import_base64.base64pad.decode(crdtEntry.data));
|
1905
|
-
const dbMeta = (0, import_dag_json.parse)(sthis.txt.decode(eventBlock.value.data.dbMeta));
|
1906
|
-
logger.Debug().Any("crdtEntry", {
|
1907
|
-
crdtEntry,
|
1908
|
-
eventBlock,
|
1909
|
-
dbMeta,
|
1910
|
-
dbMetaStrings: dbMeta.cars.map((car) => car.toString())
|
1911
|
-
}).Msg("CRDT entry");
|
1912
|
-
return {
|
1913
|
-
eventCid: eventBlock.cid,
|
1914
|
-
parents: crdtEntry.parents,
|
1915
|
-
dbMeta
|
1916
|
-
};
|
1917
|
-
})
|
1918
|
-
);
|
1919
|
-
}
|
1920
|
-
async function setCryptoKeyFromGatewayMetaPayload(uri, sthis, data) {
|
1921
|
-
try {
|
1922
|
-
sthis.logger.Debug().Str("uri", uri.toString()).Msg("Setting crypto key from gateway meta payload");
|
1923
|
-
const keyInfo = await decodeGatewayMetaBytesToDbMeta(sthis, data);
|
1924
|
-
if (keyInfo.length) {
|
1925
|
-
const dbMeta = keyInfo[0].dbMeta;
|
1926
|
-
if (dbMeta.key) {
|
1927
|
-
const kb = await getKeyBag(sthis);
|
1928
|
-
const keyName = getStoreKeyName(uri);
|
1929
|
-
const res = await kb.setNamedKey(keyName, dbMeta.key);
|
1930
|
-
if (res.isErr()) {
|
1931
|
-
sthis.logger.Debug().Str("keyName", keyName).Str("dbMeta.key", dbMeta.key).Msg("Failed to set named key");
|
1932
|
-
throw res.Err();
|
1933
|
-
}
|
1934
|
-
}
|
1935
|
-
sthis.logger.Debug().Str("dbMeta.key", dbMeta.key).Str("uri", uri.toString()).Msg("Set crypto key from gateway meta payload");
|
1936
|
-
return import_cement7.Result.Ok(dbMeta);
|
2092
|
+
async subscribe(sthis, url, callback, loader) {
|
2093
|
+
if (!this.innerGW.subscribe) {
|
2094
|
+
return import_cement9.Result.Err(sthis.logger.Error().Url(url).Msg("subscribe not supported").AsError());
|
2095
|
+
}
|
2096
|
+
const rret = await this.interceptor.subscribe(sthis, url, callback, loader);
|
2097
|
+
if (rret.isErr()) {
|
2098
|
+
return import_cement9.Result.Err(rret.Err());
|
1937
2099
|
}
|
1938
|
-
|
1939
|
-
|
1940
|
-
|
1941
|
-
|
1942
|
-
return
|
2100
|
+
const ret = rret.unwrap();
|
2101
|
+
if (ret.stop && ret.value) {
|
2102
|
+
return ret.value;
|
2103
|
+
}
|
2104
|
+
return this.innerGW.subscribe(sthis, ret.op.url, ret.op.callback, loader);
|
1943
2105
|
}
|
1944
|
-
|
1945
|
-
|
1946
|
-
|
1947
|
-
|
1948
|
-
const keyName = getStoreKeyName(uri);
|
1949
|
-
const kb = await getKeyBag(sthis);
|
1950
|
-
const res = await kb.getNamedExtractableKey(keyName, true);
|
1951
|
-
if (res.isErr()) {
|
1952
|
-
sthis.logger.Error().Str("keyName", keyName).Msg("Failed to get named extractable key");
|
1953
|
-
throw res.Err();
|
2106
|
+
async delete(sthis, url, loader) {
|
2107
|
+
const rret = await this.interceptor.delete(sthis, url, loader);
|
2108
|
+
if (rret.isErr()) {
|
2109
|
+
return import_cement9.Result.Err(rret.Err());
|
1954
2110
|
}
|
1955
|
-
const
|
1956
|
-
|
1957
|
-
|
1958
|
-
|
1959
|
-
|
1960
|
-
|
1961
|
-
|
1962
|
-
|
1963
|
-
|
1964
|
-
|
1965
|
-
sthis.logger.Error().Err(error).Msg("Failed to add crypto key to gateway meta payload");
|
1966
|
-
return import_cement7.Result.Err(error);
|
1967
|
-
}
|
1968
|
-
}
|
1969
|
-
function getStoreKeyName(url) {
|
1970
|
-
const storeKeyName = [url.getParam("localName") || url.getParam("name")];
|
1971
|
-
const idx = url.getParam("index");
|
1972
|
-
if (idx) {
|
1973
|
-
storeKeyName.push(idx);
|
1974
|
-
}
|
1975
|
-
storeKeyName.push("data");
|
1976
|
-
return `@${storeKeyName.join(":")}@`;
|
1977
|
-
}
|
1978
|
-
async function createDbMetaEventBlock(sthis, dbMeta, parents) {
|
1979
|
-
const event = await import_clock.EventBlock.create(
|
1980
|
-
{
|
1981
|
-
dbMeta: sthis.txt.encode((0, import_dag_json.format)(dbMeta))
|
1982
|
-
},
|
1983
|
-
parents
|
1984
|
-
);
|
1985
|
-
return event;
|
1986
|
-
}
|
1987
|
-
async function encodeEventsWithParents(sthis, events, parents) {
|
1988
|
-
const crdtEntries = events.map((event) => {
|
1989
|
-
const base64String = import_base64.base64pad.encode(event.bytes);
|
1990
|
-
return {
|
1991
|
-
cid: event.cid.toString(),
|
1992
|
-
data: base64String,
|
1993
|
-
parents: parents.map((p) => p.toString())
|
1994
|
-
};
|
1995
|
-
});
|
1996
|
-
return sthis.txt.encode(JSON.stringify(crdtEntries));
|
1997
|
-
}
|
2111
|
+
const ret = rret.unwrap();
|
2112
|
+
if (ret.stop && ret.value) {
|
2113
|
+
return ret.value;
|
2114
|
+
}
|
2115
|
+
return this.innerGW.delete(sthis, url, loader);
|
2116
|
+
}
|
2117
|
+
async getPlain(sthis, url, key, loader) {
|
2118
|
+
return this.innerGW.getPlain(sthis, url, key, loader);
|
2119
|
+
}
|
2120
|
+
};
|
1998
2121
|
|
1999
2122
|
// src/blockstore/store.ts
|
2000
|
-
var import_p_retry = __toESM(require("p-retry"), 1);
|
2001
|
-
var import_p_map = __toESM(require("p-map"), 1);
|
2002
2123
|
function guardVersion(url) {
|
2003
2124
|
if (!url.hasParam("version")) {
|
2004
|
-
return
|
2125
|
+
return import_cement10.Result.Err(`missing version: ${url.toString()}`);
|
2005
2126
|
}
|
2006
|
-
return
|
2127
|
+
return import_cement10.Result.Ok(url);
|
2007
2128
|
}
|
2008
2129
|
var BaseStoreImpl = class {
|
2009
|
-
|
2130
|
+
// readonly loader: Loadable;
|
2131
|
+
constructor(sthis, url, opts, logger) {
|
2010
2132
|
this._onStarted = [];
|
2011
2133
|
this._onClosed = [];
|
2012
|
-
this.name = name;
|
2013
2134
|
this._url = url;
|
2014
|
-
this.
|
2015
|
-
this.sthis = sthis;
|
2016
|
-
this.logger = logger.With().Ref("url", () => this._url.toString()).Str("name", name).Logger();
|
2017
|
-
this.gateway = new FragmentGateway(this.sthis, opts.gateway);
|
2135
|
+
this.opts = opts;
|
2018
2136
|
this.loader = opts.loader;
|
2137
|
+
this.sthis = sthis;
|
2138
|
+
const name = this._url.getParam("name" /* NAME */);
|
2139
|
+
if (!name) {
|
2140
|
+
throw logger.Error().Url(this._url).Msg("missing name").AsError();
|
2141
|
+
}
|
2142
|
+
this.logger = logger.With().Str("this", this.sthis.nextId().str).Ref("url", () => this._url.toString()).Logger();
|
2143
|
+
this.realGateway = opts.gateway;
|
2144
|
+
this.gateway = new InterceptorGateway(this.sthis, opts.gateway, opts.gatewayInterceptor);
|
2019
2145
|
}
|
2020
2146
|
url() {
|
2021
2147
|
return this._url;
|
@@ -2030,21 +2156,21 @@ var BaseStoreImpl = class {
|
|
2030
2156
|
return;
|
2031
2157
|
}
|
2032
2158
|
async keyedCrypto() {
|
2033
|
-
return keyedCryptoFactory(this._url, await this.
|
2159
|
+
return keyedCryptoFactory(this._url, await this.loader.keyBag(), this.sthis);
|
2034
2160
|
}
|
2035
2161
|
async start() {
|
2036
2162
|
this.logger.Debug().Str("storeType", this.storeType).Msg("starting-gateway-pre");
|
2037
|
-
this._url = this._url.build().setParam("store"
|
2038
|
-
const res = await this.gateway.start(this._url);
|
2163
|
+
this._url = this._url.build().setParam("store" /* STORE */, this.storeType).URI();
|
2164
|
+
const res = await this.gateway.start(this.sthis, this._url, this.loader);
|
2039
2165
|
if (res.isErr()) {
|
2040
2166
|
this.logger.Error().Result("gw-start", res).Msg("started-gateway");
|
2041
2167
|
return res;
|
2042
2168
|
}
|
2043
2169
|
this._url = res.Ok();
|
2044
|
-
const kb = await this.
|
2170
|
+
const kb = await this.loader.keyBag();
|
2045
2171
|
const skRes = await kb.ensureKeyFromUrl(this._url, () => {
|
2046
|
-
const idx = this._url.getParam("index");
|
2047
|
-
const storeKeyName = [this.name];
|
2172
|
+
const idx = this._url.getParam("index" /* INDEX */);
|
2173
|
+
const storeKeyName = [this.url().getParam("name" /* NAME */)];
|
2048
2174
|
if (idx) {
|
2049
2175
|
storeKeyName.push(idx);
|
2050
2176
|
}
|
@@ -2063,7 +2189,7 @@ var BaseStoreImpl = class {
|
|
2063
2189
|
}
|
2064
2190
|
if (this.ready) {
|
2065
2191
|
const fn = this.ready.bind(this);
|
2066
|
-
const ready = await (0,
|
2192
|
+
const ready = await (0, import_cement10.exception2Result)(fn);
|
2067
2193
|
if (ready.isErr()) {
|
2068
2194
|
await this.close();
|
2069
2195
|
return ready;
|
@@ -2074,10 +2200,23 @@ var BaseStoreImpl = class {
|
|
2074
2200
|
return version;
|
2075
2201
|
}
|
2076
2202
|
};
|
2203
|
+
async function createDbMetaEvent(sthis, dbMeta, parents) {
|
2204
|
+
const event = await import_clock.EventBlock.create(
|
2205
|
+
{
|
2206
|
+
dbMeta: sthis.txt.encode((0, import_dag_json.format)(dbMeta))
|
2207
|
+
},
|
2208
|
+
parents
|
2209
|
+
);
|
2210
|
+
return {
|
2211
|
+
eventCid: event.cid,
|
2212
|
+
dbMeta,
|
2213
|
+
parents
|
2214
|
+
};
|
2215
|
+
}
|
2077
2216
|
var MetaStoreImpl = class extends BaseStoreImpl {
|
2078
2217
|
// remote: boolean;
|
2079
|
-
constructor(sthis,
|
2080
|
-
super(
|
2218
|
+
constructor(sthis, url, opts) {
|
2219
|
+
super(sthis, url, { ...opts }, ensureLogger(sthis, "MetaStoreImpl"));
|
2081
2220
|
this.storeType = "meta";
|
2082
2221
|
this.subscribers = /* @__PURE__ */ new Map();
|
2083
2222
|
this.parents = [];
|
@@ -2087,14 +2226,18 @@ var MetaStoreImpl = class extends BaseStoreImpl {
|
|
2087
2226
|
) {
|
2088
2227
|
this.onStarted(async () => {
|
2089
2228
|
this.logger.Debug().Str("url", this.url().toString()).Msg("Subscribing to the gateway");
|
2090
|
-
opts.gateway.subscribe?.(
|
2091
|
-
this.
|
2092
|
-
|
2093
|
-
|
2094
|
-
|
2095
|
-
|
2096
|
-
|
2097
|
-
|
2229
|
+
opts.gateway.subscribe?.(
|
2230
|
+
this.sthis,
|
2231
|
+
this.url(),
|
2232
|
+
async ({ payload: dbMetas }) => {
|
2233
|
+
this.logger.Debug().Msg("Received message from gateway");
|
2234
|
+
await Promise.all(
|
2235
|
+
dbMetas.map((dbMeta) => this.loader.taskManager?.handleEvent(dbMeta.eventCid, dbMeta.parents, dbMeta.dbMeta))
|
2236
|
+
);
|
2237
|
+
this.updateParentsFromDbMetas(dbMetas);
|
2238
|
+
},
|
2239
|
+
this.loader
|
2240
|
+
);
|
2098
2241
|
});
|
2099
2242
|
}
|
2100
2243
|
}
|
@@ -2105,129 +2248,165 @@ var MetaStoreImpl = class extends BaseStoreImpl {
|
|
2105
2248
|
const dbMetaParentsSet = new Set(dbMetaParents.map((p) => p.toString()));
|
2106
2249
|
this.parents = Array.from(uniqueParentsMap.values()).filter((p) => !dbMetaParentsSet.has(p.toString()));
|
2107
2250
|
}
|
2108
|
-
async handleByteHeads(byteHeads) {
|
2109
|
-
|
2110
|
-
|
2251
|
+
// async handleByteHeads(byteHeads: Uint8Array) {
|
2252
|
+
// // return await decodeGatewayMetaBytesToDbMeta(this.sthis, byteHeads);
|
2253
|
+
// const rDbMeta = await fpDeserialize(this.sthis, byteHeads, this.url());
|
2254
|
+
// if (rDbMeta.isErr()) {
|
2255
|
+
// throw this.logger.Error().Err(rDbMeta).Msg("error deserializing").AsError();
|
2256
|
+
// }
|
2257
|
+
// return (rDbMeta.Ok() as FPEnvelopeMeta).payload;
|
2258
|
+
// }
|
2111
2259
|
async load() {
|
2112
2260
|
const branch = "main";
|
2113
|
-
const url = await this.gateway.buildUrl(this.url(), branch);
|
2261
|
+
const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
|
2114
2262
|
if (url.isErr()) {
|
2115
2263
|
throw this.logger.Error().Result("buildUrl", url).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
|
2116
2264
|
}
|
2117
|
-
const
|
2118
|
-
if (
|
2119
|
-
if (isNotFoundError(
|
2265
|
+
const rfpEnv = await this.gateway.get(this.sthis, url.Ok(), this.loader);
|
2266
|
+
if (rfpEnv.isErr()) {
|
2267
|
+
if (isNotFoundError(rfpEnv)) {
|
2120
2268
|
return void 0;
|
2121
2269
|
}
|
2122
|
-
throw this.logger.Error().Url(url.Ok()).
|
2270
|
+
throw this.logger.Error().Url(url.Ok()).Err(rfpEnv).Msg("gateway get").AsError();
|
2123
2271
|
}
|
2124
|
-
const dbMetas =
|
2125
|
-
await this.loader
|
2272
|
+
const dbMetas = rfpEnv.Ok().payload;
|
2273
|
+
await this.loader.handleDbMetasFromStore(dbMetas.map((m) => m.dbMeta));
|
2126
2274
|
this.updateParentsFromDbMetas(dbMetas);
|
2127
2275
|
return dbMetas.map((m) => m.dbMeta);
|
2128
2276
|
}
|
2129
2277
|
async save(meta, branch) {
|
2130
2278
|
branch = branch || "main";
|
2131
2279
|
this.logger.Debug().Str("branch", branch).Any("meta", meta).Msg("saving meta");
|
2132
|
-
const
|
2133
|
-
const bytes = await encodeEventsWithParents(this.sthis, [event], this.parents);
|
2134
|
-
const url = await this.gateway.buildUrl(this.url(), branch);
|
2280
|
+
const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
|
2135
2281
|
if (url.isErr()) {
|
2136
2282
|
throw this.logger.Error().Err(url.Err()).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
|
2137
2283
|
}
|
2138
|
-
this.
|
2139
|
-
const res = await this.gateway.put(
|
2284
|
+
const dbMetaEvent = await createDbMetaEvent(this.sthis, meta, this.parents);
|
2285
|
+
const res = await this.gateway.put(
|
2286
|
+
this.sthis,
|
2287
|
+
url.Ok(),
|
2288
|
+
{
|
2289
|
+
type: "meta",
|
2290
|
+
payload: [dbMetaEvent]
|
2291
|
+
},
|
2292
|
+
this.loader
|
2293
|
+
);
|
2140
2294
|
if (res.isErr()) {
|
2141
2295
|
throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
|
2142
2296
|
}
|
2143
2297
|
return res;
|
2144
2298
|
}
|
2145
2299
|
async close() {
|
2146
|
-
await this.gateway.close(this.url());
|
2300
|
+
await this.gateway.close(this.sthis, this.url(), this.loader);
|
2147
2301
|
this._onClosed.forEach((fn) => fn());
|
2148
|
-
return
|
2302
|
+
return import_cement10.Result.Ok(void 0);
|
2149
2303
|
}
|
2150
2304
|
async destroy() {
|
2151
|
-
|
2305
|
+
this.logger.Debug().Msg("destroy");
|
2306
|
+
return this.gateway.destroy(this.sthis, this.url(), this.loader);
|
2152
2307
|
}
|
2153
2308
|
};
|
2154
2309
|
var DataStoreImpl = class extends BaseStoreImpl {
|
2155
|
-
|
2156
|
-
|
2157
|
-
super(name, url, { ...opts }, sthis, ensureLogger(sthis, "DataStoreImpl"));
|
2310
|
+
constructor(sthis, url, opts) {
|
2311
|
+
super(sthis, url, { ...opts }, ensureLogger(sthis, "DataStoreImpl"));
|
2158
2312
|
this.storeType = "data";
|
2159
2313
|
}
|
2160
2314
|
async load(cid) {
|
2161
2315
|
this.logger.Debug().Any("cid", cid).Msg("loading");
|
2162
|
-
const url = await this.gateway.buildUrl(this.url(), cid.toString());
|
2316
|
+
const url = await this.gateway.buildUrl(this.sthis, this.url(), cid.toString(), this.loader);
|
2163
2317
|
if (url.isErr()) {
|
2164
2318
|
throw this.logger.Error().Err(url.Err()).Str("cid", cid.toString()).Msg("got error from gateway.buildUrl").AsError();
|
2165
2319
|
}
|
2166
|
-
const res = await this.gateway.get(url.Ok());
|
2320
|
+
const res = await this.gateway.get(this.sthis, url.Ok(), this.loader);
|
2167
2321
|
if (res.isErr()) {
|
2168
2322
|
throw res.Err();
|
2169
2323
|
}
|
2170
|
-
|
2324
|
+
const fpenv = res.Ok();
|
2325
|
+
switch (fpenv.type) {
|
2326
|
+
case "car":
|
2327
|
+
return { cid, bytes: fpenv.payload };
|
2328
|
+
case "file":
|
2329
|
+
return { cid, bytes: fpenv.payload };
|
2330
|
+
default:
|
2331
|
+
throw this.logger.Error().Msg("unexpected type").AsError();
|
2332
|
+
}
|
2171
2333
|
}
|
2172
2334
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2173
2335
|
async save(car, opts) {
|
2174
2336
|
this.logger.Debug().Any("cid", car.cid.toString()).Msg("saving");
|
2175
|
-
const url = await this.gateway.buildUrl(this.url(), car.cid.toString());
|
2337
|
+
const url = await this.gateway.buildUrl(this.sthis, this.url(), car.cid.toString(), this.loader);
|
2176
2338
|
if (url.isErr()) {
|
2177
2339
|
throw this.logger.Error().Err(url.Err()).Ref("cid", car.cid).Msg("got error from gateway.buildUrl").AsError();
|
2178
2340
|
}
|
2179
|
-
|
2341
|
+
let fpMsg;
|
2342
|
+
switch (url.Ok().getParam("store" /* STORE */)) {
|
2343
|
+
case "data":
|
2344
|
+
if (url.Ok().getParam("suffix" /* SUFFIX */)) {
|
2345
|
+
fpMsg = Car2FPMsg(car.bytes);
|
2346
|
+
} else {
|
2347
|
+
fpMsg = File2FPMsg(car.bytes);
|
2348
|
+
}
|
2349
|
+
break;
|
2350
|
+
default:
|
2351
|
+
throw this.logger.Error().Str("store", url.Ok().getParam("store" /* STORE */)).Msg("unexpected store").AsError();
|
2352
|
+
}
|
2353
|
+
if (fpMsg.isErr()) {
|
2354
|
+
throw this.logger.Error().Err(fpMsg).Msg("got error from FPMsg2Car").AsError();
|
2355
|
+
}
|
2356
|
+
const res = await this.gateway.put(this.sthis, url.Ok(), fpMsg.Ok(), this.loader);
|
2180
2357
|
if (res.isErr()) {
|
2181
2358
|
throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
|
2182
2359
|
}
|
2183
2360
|
return res.Ok();
|
2184
2361
|
}
|
2185
2362
|
async remove(cid) {
|
2186
|
-
const url = await this.gateway.buildUrl(this.url(), cid.toString());
|
2363
|
+
const url = await this.gateway.buildUrl(this.sthis, this.url(), cid.toString(), this.loader);
|
2187
2364
|
if (url.isErr()) {
|
2188
2365
|
return url;
|
2189
2366
|
}
|
2190
|
-
return this.gateway.delete(url.Ok());
|
2367
|
+
return this.gateway.delete(this.sthis, url.Ok(), this.loader);
|
2191
2368
|
}
|
2192
2369
|
async close() {
|
2193
|
-
await this.gateway.close(this.url());
|
2370
|
+
await this.gateway.close(this.sthis, this.url(), this.loader);
|
2194
2371
|
this._onClosed.forEach((fn) => fn());
|
2195
|
-
return
|
2372
|
+
return import_cement10.Result.Ok(void 0);
|
2196
2373
|
}
|
2197
2374
|
destroy() {
|
2198
|
-
|
2375
|
+
this.logger.Debug().Msg("destroy");
|
2376
|
+
return this.gateway.destroy(this.sthis, this.url(), this.loader);
|
2199
2377
|
}
|
2200
2378
|
};
|
2201
2379
|
var WALStoreImpl = class extends BaseStoreImpl {
|
2202
|
-
constructor(
|
2203
|
-
super(
|
2380
|
+
constructor(sthis, url, opts) {
|
2381
|
+
super(sthis, url, { ...opts }, ensureLogger(sthis, "WALStoreImpl"));
|
2204
2382
|
this.storeType = "wal";
|
2205
|
-
|
2383
|
+
// readonly tag: string = "rwal-base";
|
2384
|
+
// readonly loader: Loadable;
|
2385
|
+
this._ready = new import_cement10.ResolveOnce();
|
2206
2386
|
this.walState = { operations: [], noLoaderOps: [], fileOperations: [] };
|
2207
2387
|
this.processing = void 0;
|
2208
2388
|
this.processQueue = new CommitQueue();
|
2209
|
-
this.loader = loader;
|
2210
2389
|
}
|
2211
2390
|
async ready() {
|
2212
2391
|
return this._ready.once(async () => {
|
2213
2392
|
const walState = await this.load().catch((e) => {
|
2214
|
-
this.logger.Error().
|
2393
|
+
this.logger.Error().Err(e).Msg("error loading wal");
|
2215
2394
|
return void 0;
|
2216
2395
|
});
|
2217
|
-
|
2218
|
-
|
2219
|
-
|
2220
|
-
|
2221
|
-
this.walState.
|
2222
|
-
this.walState.fileOperations = walState.fileOperations || [];
|
2396
|
+
this.walState.operations.splice(0, this.walState.operations.length);
|
2397
|
+
this.walState.fileOperations.splice(0, this.walState.fileOperations.length);
|
2398
|
+
if (walState) {
|
2399
|
+
this.walState.operations.push(...walState.operations);
|
2400
|
+
this.walState.fileOperations.push(...walState.fileOperations);
|
2223
2401
|
}
|
2224
2402
|
});
|
2225
2403
|
}
|
2226
2404
|
async enqueue(dbMeta, opts) {
|
2227
2405
|
await this.ready();
|
2228
2406
|
if (opts.compact) {
|
2229
|
-
this.walState.operations
|
2230
|
-
this.walState.noLoaderOps
|
2407
|
+
this.walState.operations.splice(0, this.walState.operations.length);
|
2408
|
+
this.walState.noLoaderOps.splice(0, this.walState.noLoaderOps.length);
|
2409
|
+
this.walState.noLoaderOps.push(dbMeta);
|
2231
2410
|
} else if (opts.noLoader) {
|
2232
2411
|
this.walState.noLoaderOps.push(dbMeta);
|
2233
2412
|
} else {
|
@@ -2257,6 +2436,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2257
2436
|
});
|
2258
2437
|
}
|
2259
2438
|
async _doProcess() {
|
2439
|
+
if (!this.loader) return;
|
2260
2440
|
if (!this.loader.remoteCarStore) return;
|
2261
2441
|
const operations = [...this.walState.operations];
|
2262
2442
|
const noLoaderOps = [...this.walState.noLoaderOps];
|
@@ -2274,6 +2454,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2274
2454
|
noLoaderOps,
|
2275
2455
|
async (dbMeta) => {
|
2276
2456
|
await retryableUpload(async () => {
|
2457
|
+
if (!this.loader) {
|
2458
|
+
return;
|
2459
|
+
}
|
2277
2460
|
for (const cid of dbMeta.cars) {
|
2278
2461
|
const car = await (await this.loader.carStore()).load(cid);
|
2279
2462
|
if (!car) {
|
@@ -2284,7 +2467,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2284
2467
|
await throwFalsy(this.loader.remoteCarStore).save(car);
|
2285
2468
|
}
|
2286
2469
|
}
|
2287
|
-
this.walState.noLoaderOps
|
2470
|
+
inplaceFilter(this.walState.noLoaderOps, (op) => op !== dbMeta);
|
2288
2471
|
}, `noLoaderOp with dbMeta.cars=${dbMeta.cars.toString()}`);
|
2289
2472
|
},
|
2290
2473
|
{ concurrency: concurrencyLimit }
|
@@ -2293,6 +2476,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2293
2476
|
operations,
|
2294
2477
|
async (dbMeta) => {
|
2295
2478
|
await retryableUpload(async () => {
|
2479
|
+
if (!this.loader) {
|
2480
|
+
return;
|
2481
|
+
}
|
2296
2482
|
for (const cid of dbMeta.cars) {
|
2297
2483
|
const car = await (await this.loader.carStore()).load(cid);
|
2298
2484
|
if (!car) {
|
@@ -2303,7 +2489,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2303
2489
|
await throwFalsy(this.loader.remoteCarStore).save(car);
|
2304
2490
|
}
|
2305
2491
|
}
|
2306
|
-
this.walState.operations
|
2492
|
+
inplaceFilter(this.walState.operations, (op) => op !== dbMeta);
|
2307
2493
|
}, `operation with dbMeta.cars=${dbMeta.cars.toString()}`);
|
2308
2494
|
},
|
2309
2495
|
{ concurrency: concurrencyLimit }
|
@@ -2312,12 +2498,15 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2312
2498
|
fileOperations,
|
2313
2499
|
async ({ cid: fileCid, public: publicFile }) => {
|
2314
2500
|
await retryableUpload(async () => {
|
2501
|
+
if (!this.loader) {
|
2502
|
+
return;
|
2503
|
+
}
|
2315
2504
|
const fileBlock = await (await this.loader.fileStore()).load(fileCid);
|
2316
2505
|
if (!fileBlock) {
|
2317
2506
|
throw this.logger.Error().Ref("cid", fileCid).Msg("missing file block").AsError();
|
2318
2507
|
}
|
2319
2508
|
await this.loader.remoteFileStore?.save(fileBlock, { public: publicFile });
|
2320
|
-
this.walState.fileOperations
|
2509
|
+
inplaceFilter(this.walState.fileOperations, (op) => op.cid !== fileCid);
|
2321
2510
|
}, `fileOperation with cid=${fileCid.toString()}`);
|
2322
2511
|
},
|
2323
2512
|
{ concurrency: concurrencyLimit }
|
@@ -2325,6 +2514,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2325
2514
|
if (operations.length) {
|
2326
2515
|
const lastOp = operations[operations.length - 1];
|
2327
2516
|
await retryableUpload(async () => {
|
2517
|
+
if (!this.loader) {
|
2518
|
+
return;
|
2519
|
+
}
|
2328
2520
|
await this.loader.remoteMetaStore?.save(lastOp);
|
2329
2521
|
}, `remoteMetaStore save with dbMeta.cars=${lastOp.cars.toString()}`);
|
2330
2522
|
}
|
@@ -2337,255 +2529,715 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
2337
2529
|
}
|
2338
2530
|
async load() {
|
2339
2531
|
this.logger.Debug().Msg("loading");
|
2340
|
-
const filepath = await this.gateway.buildUrl(this.url(), "main");
|
2532
|
+
const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
|
2341
2533
|
if (filepath.isErr()) {
|
2342
2534
|
throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
|
2343
2535
|
}
|
2344
|
-
const bytes = await this.gateway.get(filepath.Ok());
|
2536
|
+
const bytes = await this.gateway.get(this.sthis, filepath.Ok(), this.loader);
|
2345
2537
|
if (bytes.isErr()) {
|
2346
2538
|
if (isNotFoundError(bytes)) {
|
2347
2539
|
return void 0;
|
2348
2540
|
}
|
2349
2541
|
throw this.logger.Error().Err(bytes.Err()).Msg("error get").AsError();
|
2350
2542
|
}
|
2351
|
-
|
2352
|
-
|
2353
|
-
} catch (e) {
|
2354
|
-
throw this.logger.Error().Err(e).Msg("error parse").AsError();
|
2543
|
+
if (bytes.Ok().type !== "wal") {
|
2544
|
+
throw this.logger.Error().Str("type", bytes.Ok().type).Msg("unexpected type").AsError();
|
2355
2545
|
}
|
2546
|
+
return bytes.Ok().payload;
|
2356
2547
|
}
|
2357
2548
|
async save(state) {
|
2358
|
-
const filepath = await this.gateway.buildUrl(this.url(), "main");
|
2549
|
+
const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
|
2359
2550
|
if (filepath.isErr()) {
|
2360
2551
|
throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
|
2361
2552
|
}
|
2362
|
-
|
2363
|
-
|
2364
|
-
|
2365
|
-
|
2366
|
-
|
2367
|
-
|
2368
|
-
|
2553
|
+
const res = await this.gateway.put(
|
2554
|
+
this.sthis,
|
2555
|
+
filepath.Ok(),
|
2556
|
+
{
|
2557
|
+
type: "wal",
|
2558
|
+
payload: state
|
2559
|
+
},
|
2560
|
+
this.loader
|
2561
|
+
);
|
2369
2562
|
if (res.isErr()) {
|
2370
2563
|
throw this.logger.Error().Err(res.Err()).Str("filePath", filepath.Ok().toString()).Msg("error saving").AsError();
|
2371
2564
|
}
|
2372
2565
|
}
|
2373
2566
|
async close() {
|
2374
|
-
await this.gateway.close(this.url());
|
2567
|
+
await this.gateway.close(this.sthis, this.url(), this.loader);
|
2375
2568
|
this._onClosed.forEach((fn) => fn());
|
2376
|
-
return
|
2569
|
+
return import_cement10.Result.Ok(void 0);
|
2377
2570
|
}
|
2378
2571
|
destroy() {
|
2379
|
-
|
2572
|
+
this.logger.Debug().Msg("destroy");
|
2573
|
+
return this.gateway.destroy(this.sthis, this.url(), this.loader);
|
2380
2574
|
}
|
2381
2575
|
};
|
2382
2576
|
|
2383
|
-
// src/blockstore/store-
|
2384
|
-
|
2385
|
-
|
2386
|
-
|
2577
|
+
// src/blockstore/register-store-protocol.ts
|
2578
|
+
var import_cement16 = require("@adviser/cement");
|
2579
|
+
|
2580
|
+
// src/runtime/gateways/file/version.ts
|
2581
|
+
var FILESTORE_VERSION = "v0.19-file";
|
2582
|
+
|
2583
|
+
// src/runtime/gateways/memory/gateway.ts
|
2584
|
+
var import_cement11 = require("@adviser/cement");
|
2585
|
+
|
2586
|
+
// src/runtime/gateways/memory/version.ts
|
2587
|
+
var MEMORY_VERSION = "v0.19-memory";
|
2588
|
+
|
2589
|
+
// src/runtime/gateways/memory/gateway.ts
|
2590
|
+
var MemoryGateway = class {
|
2591
|
+
constructor(sthis, memorys) {
|
2592
|
+
this.memorys = memorys;
|
2593
|
+
this.sthis = sthis;
|
2594
|
+
}
|
2595
|
+
buildUrl(baseUrl, key) {
|
2596
|
+
return Promise.resolve(import_cement11.Result.Ok(baseUrl.build().setParam("key" /* KEY */, key).URI()));
|
2597
|
+
}
|
2598
|
+
start(baseUrl) {
|
2599
|
+
return Promise.resolve(import_cement11.Result.Ok(baseUrl.build().setParam("version" /* VERSION */, MEMORY_VERSION).URI()));
|
2600
|
+
}
|
2601
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2602
|
+
close(baseUrl) {
|
2603
|
+
return Promise.resolve(import_cement11.Result.Ok(void 0));
|
2604
|
+
}
|
2605
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
2606
|
+
destroy(baseUrl) {
|
2607
|
+
this.memorys.clear();
|
2608
|
+
return Promise.resolve(import_cement11.Result.Ok(void 0));
|
2609
|
+
}
|
2610
|
+
async put(url, bytes) {
|
2611
|
+
this.memorys.set(url.toString(), bytes);
|
2612
|
+
return import_cement11.Result.Ok(void 0);
|
2613
|
+
}
|
2614
|
+
// get could return a NotFoundError if the key is not found
|
2615
|
+
get(url) {
|
2616
|
+
const x = this.memorys.get(url.toString());
|
2617
|
+
if (!x) {
|
2618
|
+
return Promise.resolve(import_cement11.Result.Err(new NotFoundError("not found")));
|
2619
|
+
}
|
2620
|
+
return Promise.resolve(import_cement11.Result.Ok(x));
|
2621
|
+
}
|
2622
|
+
delete(url) {
|
2623
|
+
this.memorys.delete(url.toString());
|
2624
|
+
return Promise.resolve(import_cement11.Result.Ok(void 0));
|
2625
|
+
}
|
2626
|
+
async getPlain(url, key) {
|
2627
|
+
const x = this.memorys.get(url.build().setParam("key" /* KEY */, key).toString());
|
2628
|
+
if (!x) {
|
2629
|
+
return import_cement11.Result.Err(new NotFoundError("not found"));
|
2630
|
+
}
|
2631
|
+
return import_cement11.Result.Ok(x);
|
2632
|
+
}
|
2633
|
+
};
|
2634
|
+
|
2635
|
+
// src/runtime/index.ts
|
2636
|
+
var runtime_exports = {};
|
2637
|
+
__export(runtime_exports, {
|
2638
|
+
FILESTORE_VERSION: () => FILESTORE_VERSION,
|
2639
|
+
INDEXDB_VERSION: () => INDEXDB_VERSION,
|
2640
|
+
KeyBag: () => KeyBag,
|
2641
|
+
defaultKeyBagOpts: () => defaultKeyBagOpts,
|
2642
|
+
defaultKeyBagUrl: () => defaultKeyBagUrl,
|
2643
|
+
files: () => files_exports,
|
2644
|
+
getFileName: () => getFileName,
|
2645
|
+
getKeyBag: () => getKeyBag,
|
2646
|
+
getPath: () => getPath,
|
2647
|
+
gw: () => gateways_exports,
|
2648
|
+
kb: () => key_bag_exports,
|
2649
|
+
kc: () => keyed_crypto_exports,
|
2650
|
+
mf: () => wait_pr_multiformats_exports,
|
2651
|
+
registerKeyBagProviderFactory: () => registerKeyBagProviderFactory,
|
2652
|
+
runtimeFn: () => import_cement13.runtimeFn
|
2653
|
+
});
|
2654
|
+
|
2655
|
+
// src/runtime/gateways/file/utils.ts
|
2656
|
+
var import_core = require("@fireproof/core");
|
2657
|
+
function getPath(url, sthis) {
|
2658
|
+
const basePath = url.pathname;
|
2659
|
+
const name = url.getParam("name");
|
2660
|
+
if (name) {
|
2661
|
+
return sthis.pathOps.join(basePath, name);
|
2387
2662
|
}
|
2388
|
-
return
|
2663
|
+
return sthis.pathOps.join(basePath);
|
2389
2664
|
}
|
2390
|
-
function
|
2391
|
-
|
2392
|
-
|
2665
|
+
function getFileName(url, sthis) {
|
2666
|
+
const key = url.getParam("key");
|
2667
|
+
if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
|
2668
|
+
const res = (0, import_core.getStore)(url, sthis, (...a) => a.join("-"));
|
2669
|
+
switch (res.store) {
|
2670
|
+
case "data":
|
2671
|
+
return sthis.pathOps.join(res.name, key + ".car");
|
2672
|
+
case "wal":
|
2673
|
+
case "meta":
|
2674
|
+
return sthis.pathOps.join(res.name, key + ".json");
|
2675
|
+
default:
|
2676
|
+
throw sthis.logger.Error().Url(url).Msg(`unsupported store type`).AsError();
|
2393
2677
|
}
|
2394
|
-
return url;
|
2395
2678
|
}
|
2679
|
+
|
2680
|
+
// src/runtime/wait-pr-multiformats/index.ts
|
2681
|
+
var wait_pr_multiformats_exports = {};
|
2682
|
+
__export(wait_pr_multiformats_exports, {
|
2683
|
+
block: () => block_exports,
|
2684
|
+
codec: () => codec_interface_exports
|
2685
|
+
});
|
2686
|
+
|
2687
|
+
// src/runtime/wait-pr-multiformats/codec-interface.ts
|
2688
|
+
var codec_interface_exports = {};
|
2689
|
+
|
2690
|
+
// src/runtime/index.ts
|
2691
|
+
var import_cement13 = require("@adviser/cement");
|
2692
|
+
|
2693
|
+
// src/runtime/gateways/index.ts
|
2694
|
+
var gateways_exports = {};
|
2695
|
+
__export(gateways_exports, {
|
2696
|
+
file: () => file_exports,
|
2697
|
+
fpDeserialize: () => fpDeserialize,
|
2698
|
+
fpSerialize: () => fpSerialize
|
2699
|
+
});
|
2700
|
+
|
2701
|
+
// src/runtime/gateways/fp-envelope-serialize.ts
|
2702
|
+
var import_cement12 = require("@adviser/cement");
|
2703
|
+
var import_clock2 = require("@fireproof/vendor/@web3-storage/pail/clock");
|
2704
|
+
var import_base64 = require("multiformats/bases/base64");
|
2705
|
+
var import_multiformats2 = require("multiformats");
|
2706
|
+
var import_link = require("multiformats/link");
|
2707
|
+
var import_dag_json2 = require("@fireproof/vendor/@ipld/dag-json");
|
2708
|
+
async function dbMetaEvent2Serialized(sthis, dbEvents) {
|
2709
|
+
return await Promise.all(
|
2710
|
+
dbEvents.map(async (dbEvent) => {
|
2711
|
+
const event = await import_clock2.EventBlock.create(
|
2712
|
+
{
|
2713
|
+
dbMeta: sthis.txt.encode((0, import_dag_json2.format)(dbEvent.dbMeta))
|
2714
|
+
},
|
2715
|
+
dbEvent.parents
|
2716
|
+
);
|
2717
|
+
return {
|
2718
|
+
cid: event.cid.toString(),
|
2719
|
+
parents: dbEvent.parents.map((i) => i.toString()),
|
2720
|
+
data: import_base64.base64pad.encode(event.bytes)
|
2721
|
+
};
|
2722
|
+
})
|
2723
|
+
);
|
2724
|
+
}
|
2725
|
+
function WALState2Serialized(sthis, wal) {
|
2726
|
+
const serializedWAL = {
|
2727
|
+
fileOperations: wal.fileOperations.map((fop) => ({
|
2728
|
+
cid: fop.cid.toString(),
|
2729
|
+
public: fop.public
|
2730
|
+
})),
|
2731
|
+
noLoaderOps: wal.noLoaderOps.map((nop) => ({
|
2732
|
+
cars: nop.cars.map((i) => i.toString())
|
2733
|
+
})),
|
2734
|
+
operations: wal.operations.map((op) => ({
|
2735
|
+
cars: op.cars.map((i) => i.toString())
|
2736
|
+
}))
|
2737
|
+
};
|
2738
|
+
return serializedWAL;
|
2739
|
+
}
|
2740
|
+
var defaultEncoder = {
|
2741
|
+
car: async (sthis, payload) => import_cement12.Result.Ok(payload),
|
2742
|
+
file: async (sthis, payload) => import_cement12.Result.Ok(payload),
|
2743
|
+
meta: async (sthis, payload) => import_cement12.Result.Ok(sthis.txt.encode(JSON.stringify(payload))),
|
2744
|
+
wal: async (sthis, payload) => import_cement12.Result.Ok(sthis.txt.encode(JSON.stringify(payload)))
|
2745
|
+
};
|
2746
|
+
async function fpSerialize(sthis, env, pencoder) {
|
2747
|
+
const encoder = {
|
2748
|
+
...defaultEncoder,
|
2749
|
+
...pencoder
|
2750
|
+
};
|
2751
|
+
switch (env.type) {
|
2752
|
+
case "file" /* FILE */:
|
2753
|
+
return encoder.file(sthis, env.payload);
|
2754
|
+
case "car" /* CAR */:
|
2755
|
+
return encoder.car(sthis, env.payload);
|
2756
|
+
case "wal" /* WAL */:
|
2757
|
+
return encoder.wal(sthis, WALState2Serialized(sthis, env.payload));
|
2758
|
+
case "meta" /* META */:
|
2759
|
+
return encoder.meta(sthis, await dbMetaEvent2Serialized(sthis, env.payload));
|
2760
|
+
default:
|
2761
|
+
throw sthis.logger.Error().Str("type", env.type).Msg("unsupported store").AsError();
|
2762
|
+
}
|
2763
|
+
}
|
2764
|
+
async function decode2DbMetaEvents(sthis, rserializedMeta) {
|
2765
|
+
if (rserializedMeta.isErr()) {
|
2766
|
+
return import_cement12.Result.Err(rserializedMeta.Err());
|
2767
|
+
}
|
2768
|
+
const serializedMeta = rserializedMeta.unwrap();
|
2769
|
+
if (!Array.isArray(serializedMeta)) {
|
2770
|
+
return sthis.logger.Debug().Any("metaEntries", serializedMeta).Msg("No data in MetaEntries").ResultError();
|
2771
|
+
}
|
2772
|
+
if (!serializedMeta.length) {
|
2773
|
+
return sthis.logger.Debug().Msg("No MetaEntries found").ResultError();
|
2774
|
+
}
|
2775
|
+
return import_cement12.Result.Ok(
|
2776
|
+
await Promise.all(
|
2777
|
+
serializedMeta.map(async (metaEntry) => {
|
2778
|
+
const eventBlock = await (0, import_clock2.decodeEventBlock)(import_base64.base64pad.decode(metaEntry.data));
|
2779
|
+
const dbMeta = (0, import_dag_json2.parse)(sthis.txt.decode(eventBlock.value.data.dbMeta));
|
2780
|
+
return {
|
2781
|
+
eventCid: eventBlock.cid,
|
2782
|
+
parents: metaEntry.parents.map((i) => import_multiformats2.CID.parse(i)),
|
2783
|
+
dbMeta
|
2784
|
+
};
|
2785
|
+
})
|
2786
|
+
)
|
2787
|
+
);
|
2788
|
+
}
|
2789
|
+
function toCid(sthis, link) {
|
2790
|
+
if (typeof link === "string") {
|
2791
|
+
return import_multiformats2.CID.parse(link);
|
2792
|
+
}
|
2793
|
+
return (0, import_link.fromJSON)(link);
|
2794
|
+
}
|
2795
|
+
async function decode2WalState(sthis, rserializedWAL) {
|
2796
|
+
if (rserializedWAL.isErr()) {
|
2797
|
+
return import_cement12.Result.Err(rserializedWAL.Err());
|
2798
|
+
}
|
2799
|
+
const serializedWAL = rserializedWAL.unwrap();
|
2800
|
+
return import_cement12.Result.Ok({
|
2801
|
+
fileOperations: (serializedWAL.fileOperations || []).map((fop) => ({
|
2802
|
+
cid: toCid(sthis, fop.cid),
|
2803
|
+
public: !!fop.public
|
2804
|
+
})),
|
2805
|
+
noLoaderOps: (serializedWAL.noLoaderOps || []).map((nop) => ({
|
2806
|
+
cars: (nop.cars || []).map((i) => toCid(sthis, i))
|
2807
|
+
})),
|
2808
|
+
operations: (serializedWAL.operations || []).map((op) => ({
|
2809
|
+
cars: (op.cars || []).map((i) => toCid(sthis, i))
|
2810
|
+
}))
|
2811
|
+
});
|
2812
|
+
}
|
2813
|
+
var defaultDecoder = {
|
2814
|
+
car: async (sthis, payload) => import_cement12.Result.Ok(payload),
|
2815
|
+
file: async (sthis, payload) => import_cement12.Result.Ok(payload),
|
2816
|
+
meta: async (sthis, payload) => (0, import_cement12.exception2Result)(() => JSON.parse(sthis.txt.decode(payload))),
|
2817
|
+
wal: async (sthis, payload) => (0, import_cement12.exception2Result)(() => JSON.parse(sthis.txt.decode(payload)))
|
2818
|
+
};
|
2819
|
+
function makeFPEnvelope(type, payload) {
|
2820
|
+
if (payload.isErr()) {
|
2821
|
+
return import_cement12.Result.Err(payload.Err());
|
2822
|
+
}
|
2823
|
+
return import_cement12.Result.Ok({
|
2824
|
+
type,
|
2825
|
+
payload: payload.unwrap()
|
2826
|
+
});
|
2827
|
+
}
|
2828
|
+
async function fpDeserialize(sthis, url, intoRaw, pdecoder) {
|
2829
|
+
const rraw = await coercePromiseIntoUint8(intoRaw);
|
2830
|
+
if (rraw.isErr()) {
|
2831
|
+
return import_cement12.Result.Err(rraw.Err());
|
2832
|
+
}
|
2833
|
+
const raw2 = rraw.unwrap();
|
2834
|
+
const decoder = {
|
2835
|
+
...defaultDecoder,
|
2836
|
+
...pdecoder
|
2837
|
+
};
|
2838
|
+
switch (url.getParam("store" /* STORE */)) {
|
2839
|
+
case "data":
|
2840
|
+
if (url.getParam("suffix" /* SUFFIX */) === ".car") {
|
2841
|
+
return makeFPEnvelope("car" /* CAR */, await decoder.car(sthis, raw2));
|
2842
|
+
}
|
2843
|
+
return makeFPEnvelope("file" /* FILE */, await decoder.file(sthis, raw2));
|
2844
|
+
case "wal":
|
2845
|
+
return makeFPEnvelope("wal" /* WAL */, await decode2WalState(sthis, await decoder.wal(sthis, raw2)));
|
2846
|
+
case "meta":
|
2847
|
+
return makeFPEnvelope("meta" /* META */, await decode2DbMetaEvents(sthis, await decoder.meta(sthis, raw2)));
|
2848
|
+
default:
|
2849
|
+
return sthis.logger.Error().Str("store", url.getParam("store" /* STORE */)).Msg("unsupported store").ResultError();
|
2850
|
+
}
|
2851
|
+
}
|
2852
|
+
|
2853
|
+
// src/runtime/gateways/file/index.ts
|
2854
|
+
var file_exports = {};
|
2855
|
+
__export(file_exports, {
|
2856
|
+
KeyBagProviderFile: () => KeyBagProviderFile,
|
2857
|
+
sysFileSystemFactory: () => sysFileSystemFactory
|
2858
|
+
});
|
2859
|
+
|
2860
|
+
// src/runtime/gateways/indexdb/version.ts
|
2861
|
+
var INDEXDB_VERSION = "v0.19-indexdb";
|
2862
|
+
|
2863
|
+
// src/runtime/gateways/file/gateway-impl.ts
|
2864
|
+
var import_cement14 = require("@adviser/cement");
|
2865
|
+
var versionFiles = new import_cement14.KeyedResolvOnce();
|
2866
|
+
var FileGateway = class {
|
2867
|
+
constructor(sthis, fs) {
|
2868
|
+
this.fs = fs;
|
2869
|
+
}
|
2870
|
+
async getVersionFromFile(path, sthis) {
|
2871
|
+
return versionFiles.get(path).once(async () => {
|
2872
|
+
await this.fs.mkdir(path, { recursive: true });
|
2873
|
+
const vFile = sthis.pathOps.join(path, "version");
|
2874
|
+
const vFileStat = await this.fs.stat(vFile).catch(() => void 0);
|
2875
|
+
if (!vFileStat) {
|
2876
|
+
await this.fs.writefile(sthis.pathOps.join(path, "version"), FILESTORE_VERSION);
|
2877
|
+
return FILESTORE_VERSION;
|
2878
|
+
} else if (!vFileStat.isFile()) {
|
2879
|
+
throw sthis.logger.Error().Str("file", vFile).Msg(`version file is a directory`).AsError();
|
2880
|
+
}
|
2881
|
+
const v = await this.fs.readfile(vFile);
|
2882
|
+
const vStr = sthis.txt.decode(v);
|
2883
|
+
if (vStr !== FILESTORE_VERSION) {
|
2884
|
+
sthis.logger.Warn().Str("file", vFile).Str("from", vStr).Str("expected", FILESTORE_VERSION).Msg(`version mismatch`);
|
2885
|
+
}
|
2886
|
+
return vStr;
|
2887
|
+
});
|
2888
|
+
}
|
2889
|
+
start(baseURL, sthis) {
|
2890
|
+
return (0, import_cement14.exception2Result)(async () => {
|
2891
|
+
await this.fs.start();
|
2892
|
+
const url = baseURL.build();
|
2893
|
+
url.defParam("version" /* VERSION */, FILESTORE_VERSION);
|
2894
|
+
const dbUrl = await this.buildUrl(url.URI(), "dummy");
|
2895
|
+
const dbdirFile = this.getFilePath(dbUrl.Ok(), sthis);
|
2896
|
+
await this.fs.mkdir(sthis.pathOps.dirname(dbdirFile), { recursive: true });
|
2897
|
+
const dbroot = sthis.pathOps.dirname(dbdirFile);
|
2898
|
+
sthis.logger.Debug().Url(url.URI()).Str("dbroot", dbroot).Msg("start");
|
2899
|
+
url.setParam("version" /* VERSION */, await this.getVersionFromFile(dbroot, sthis));
|
2900
|
+
return url.URI();
|
2901
|
+
});
|
2902
|
+
}
|
2903
|
+
async buildUrl(baseUrl, key) {
|
2904
|
+
return import_cement14.Result.Ok(baseUrl.build().setParam("key" /* KEY */, key).URI());
|
2905
|
+
}
|
2906
|
+
async close() {
|
2907
|
+
return import_cement14.Result.Ok(void 0);
|
2908
|
+
}
|
2909
|
+
getFilePath(url, sthis) {
|
2910
|
+
const key = url.getParam("key" /* KEY */);
|
2911
|
+
if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
|
2912
|
+
return sthis.pathOps.join(getPath(url, sthis), getFileName(url, sthis));
|
2913
|
+
}
|
2914
|
+
async put(url, bytes, sthis) {
|
2915
|
+
return (0, import_cement14.exception2Result)(async () => {
|
2916
|
+
const file = await this.getFilePath(url, sthis);
|
2917
|
+
sthis.logger.Debug().Str("url", url.toString()).Str("file", file).Msg("put");
|
2918
|
+
await this.fs.writefile(file, bytes);
|
2919
|
+
});
|
2920
|
+
}
|
2921
|
+
async get(url, sthis) {
|
2922
|
+
return exceptionWrapper(async () => {
|
2923
|
+
const file = this.getFilePath(url, sthis);
|
2924
|
+
try {
|
2925
|
+
sthis.logger.Debug().Url(url).Str("file", file).Msg("get");
|
2926
|
+
const res = await this.fs.readfile(file);
|
2927
|
+
return import_cement14.Result.Ok(res);
|
2928
|
+
} catch (e) {
|
2929
|
+
if (isNotFoundError(e)) {
|
2930
|
+
return import_cement14.Result.Err(new NotFoundError(`file not found: ${file}`));
|
2931
|
+
}
|
2932
|
+
return import_cement14.Result.Err(e);
|
2933
|
+
}
|
2934
|
+
});
|
2935
|
+
}
|
2936
|
+
async delete(url, sthis) {
|
2937
|
+
return (0, import_cement14.exception2Result)(async () => {
|
2938
|
+
await this.fs.unlink(this.getFilePath(url, sthis));
|
2939
|
+
});
|
2940
|
+
}
|
2941
|
+
async destroy(baseURL, sthis) {
|
2942
|
+
const url = await this.buildUrl(baseURL, "x");
|
2943
|
+
if (url.isErr()) return url;
|
2944
|
+
const filepath = sthis.pathOps.dirname(this.getFilePath(url.Ok(), sthis));
|
2945
|
+
let files = [];
|
2946
|
+
try {
|
2947
|
+
files = await this.fs.readdir(filepath);
|
2948
|
+
} catch (e) {
|
2949
|
+
if (!isNotFoundError(e)) {
|
2950
|
+
throw sthis.logger.Error().Err(e).Str("dir", filepath).Msg("destroy:readdir").AsError();
|
2951
|
+
}
|
2952
|
+
}
|
2953
|
+
for (const file of files) {
|
2954
|
+
const pathed = sthis.pathOps.join(filepath, file);
|
2955
|
+
try {
|
2956
|
+
await this.fs.unlink(pathed);
|
2957
|
+
} catch (e) {
|
2958
|
+
if (!isNotFoundError(e)) {
|
2959
|
+
throw sthis.logger.Error().Err(e).Str("file", pathed).Msg("destroy:unlink").AsError();
|
2960
|
+
}
|
2961
|
+
}
|
2962
|
+
}
|
2963
|
+
return import_cement14.Result.Ok(void 0);
|
2964
|
+
}
|
2965
|
+
async getPlain(iurl, key, sthis) {
|
2966
|
+
const url = iurl.build().setParam("key" /* KEY */, key).URI();
|
2967
|
+
const dbFile = sthis.pathOps.join(getPath(url, sthis), getFileName(url, sthis));
|
2968
|
+
sthis.logger.Debug().Url(url).Str("dbFile", dbFile).Msg("get");
|
2969
|
+
const buffer = await this.fs.readfile(dbFile);
|
2970
|
+
sthis.logger.Debug().Url(url).Str("dbFile", dbFile).Len(buffer).Msg("got");
|
2971
|
+
return import_cement14.Result.Ok(buffer);
|
2972
|
+
}
|
2973
|
+
};
|
2974
|
+
|
2975
|
+
// src/runtime/gateways/def-serde-gateway.ts
|
2976
|
+
var import_cement15 = require("@adviser/cement");
|
2977
|
+
var DefSerdeGateway = class {
|
2978
|
+
constructor(gw) {
|
2979
|
+
this.gw = gw;
|
2980
|
+
}
|
2981
|
+
start(sthis, baseURL) {
|
2982
|
+
return this.gw.start(baseURL, sthis);
|
2983
|
+
}
|
2984
|
+
async buildUrl(sthis, baseUrl, key) {
|
2985
|
+
return this.gw.buildUrl(baseUrl, key, sthis);
|
2986
|
+
}
|
2987
|
+
async close(sthis, uri) {
|
2988
|
+
return this.gw.close(uri, sthis);
|
2989
|
+
}
|
2990
|
+
async put(sthis, url, env) {
|
2991
|
+
const rUint8 = await fpSerialize(sthis, env);
|
2992
|
+
if (rUint8.isErr()) return rUint8;
|
2993
|
+
return this.gw.put(url, rUint8.Ok(), sthis);
|
2994
|
+
}
|
2995
|
+
async get(sthis, url) {
|
2996
|
+
const res = await this.gw.get(url, sthis);
|
2997
|
+
if (res.isErr()) return import_cement15.Result.Err(res.Err());
|
2998
|
+
return fpDeserialize(sthis, url, res);
|
2999
|
+
}
|
3000
|
+
async delete(sthis, url) {
|
3001
|
+
return this.gw.delete(url, sthis);
|
3002
|
+
}
|
3003
|
+
async destroy(sthis, baseURL) {
|
3004
|
+
return this.gw.destroy(baseURL, sthis);
|
3005
|
+
}
|
3006
|
+
async getPlain(sthis, iurl, key) {
|
3007
|
+
return this.gw.getPlain(iurl, key, sthis);
|
3008
|
+
}
|
3009
|
+
};
|
3010
|
+
|
3011
|
+
// src/blockstore/register-store-protocol.ts
|
2396
3012
|
var storeFactory = /* @__PURE__ */ new Map();
|
2397
|
-
function
|
2398
|
-
|
2399
|
-
|
2400
|
-
|
2401
|
-
if (obuItem && obuItem.overrideBaseURL) {
|
2402
|
-
obuUrl = import_cement9.URI.from(obuItem.overrideBaseURL);
|
2403
|
-
}
|
2404
|
-
const ret = ensureIsIndex(
|
2405
|
-
import_cement9.URI.from(optURL || obuUrl || dataDir(loader.sthis, loader.name, storeOpts.stores?.base)),
|
2406
|
-
storeOpts.isIndex
|
2407
|
-
);
|
2408
|
-
return ret;
|
2409
|
-
}
|
2410
|
-
var onceGateway = new import_cement9.KeyedResolvOnce();
|
2411
|
-
async function getGatewayFromURL(url, sthis) {
|
2412
|
-
return onceGateway.get(url.toString()).once(async () => {
|
2413
|
-
const item = storeFactory.get(url.protocol);
|
2414
|
-
if (item) {
|
2415
|
-
const ret = {
|
2416
|
-
gateway: await item.gateway(sthis),
|
2417
|
-
test: await item.test(sthis)
|
2418
|
-
};
|
2419
|
-
const res = await ret.gateway.start(url);
|
2420
|
-
if (res.isErr()) {
|
2421
|
-
sthis.logger.Error().Result("start", res).Msg("start failed");
|
2422
|
-
return void 0;
|
2423
|
-
}
|
2424
|
-
return ret;
|
3013
|
+
function getDefaultURI(sthis, protocol) {
|
3014
|
+
if (protocol) {
|
3015
|
+
if (!protocol.endsWith(":")) {
|
3016
|
+
protocol += ":";
|
2425
3017
|
}
|
2426
|
-
|
2427
|
-
|
2428
|
-
|
3018
|
+
const gfi = storeFactory.get(protocol);
|
3019
|
+
if (gfi) {
|
3020
|
+
return gfi.defaultURI(sthis);
|
3021
|
+
}
|
3022
|
+
}
|
3023
|
+
const found = Array.from(storeFactory.values()).find((item) => item.isDefault);
|
3024
|
+
if (!found) {
|
3025
|
+
throw sthis.logger.Error().Msg("no default found").AsError();
|
3026
|
+
}
|
3027
|
+
return found.defaultURI(sthis);
|
2429
3028
|
}
|
2430
3029
|
function registerStoreProtocol(item) {
|
2431
3030
|
let protocol = item.protocol;
|
2432
3031
|
if (!protocol.endsWith(":")) {
|
2433
3032
|
protocol += ":";
|
2434
3033
|
}
|
2435
|
-
if (
|
2436
|
-
|
2437
|
-
throw new Error(`we need a logger here`);
|
2438
|
-
return () => {
|
2439
|
-
};
|
2440
|
-
}
|
3034
|
+
if (!item.serdegateway && !item.gateway) {
|
3035
|
+
throw new Error(`registerStoreProtocol needs a gateway or serdegateway`);
|
2441
3036
|
}
|
2442
|
-
|
3037
|
+
let serdegateway;
|
3038
|
+
if (item.gateway) {
|
3039
|
+
serdegateway = async (sthis) => {
|
3040
|
+
const m = await item.gateway(sthis);
|
3041
|
+
return new DefSerdeGateway(m);
|
3042
|
+
};
|
3043
|
+
} else {
|
3044
|
+
serdegateway = item.serdegateway;
|
3045
|
+
}
|
3046
|
+
if (item.isDefault) {
|
2443
3047
|
Array.from(storeFactory.values()).forEach((items) => {
|
2444
|
-
items.
|
3048
|
+
items.isDefault = false;
|
2445
3049
|
});
|
2446
3050
|
}
|
2447
|
-
storeFactory.set(protocol,
|
3051
|
+
storeFactory.set(protocol, {
|
3052
|
+
...item,
|
3053
|
+
serdegateway
|
3054
|
+
});
|
2448
3055
|
return () => {
|
2449
3056
|
storeFactory.delete(protocol);
|
2450
3057
|
};
|
2451
3058
|
}
|
2452
|
-
|
2453
|
-
|
2454
|
-
|
2455
|
-
|
2456
|
-
|
2457
|
-
|
2458
|
-
|
2459
|
-
|
3059
|
+
function getGatewayFactoryItem(protocol) {
|
3060
|
+
return storeFactory.get(protocol);
|
3061
|
+
}
|
3062
|
+
function defaultGatewayFactoryItem() {
|
3063
|
+
const found = Array.from(storeFactory.values()).find((item) => item.isDefault);
|
3064
|
+
if (!found) {
|
3065
|
+
throw new Error("no default found");
|
3066
|
+
}
|
3067
|
+
return found;
|
3068
|
+
}
|
3069
|
+
function defaultURI(sthis) {
|
3070
|
+
const rt = (0, import_cement16.runtimeFn)();
|
3071
|
+
return import_cement16.BuildURI.from("file://").pathname(`${sthis.env.get("HOME")}/.fireproof/${FILESTORE_VERSION.replace(/-.*$/, "")}`).setParam("version" /* VERSION */, FILESTORE_VERSION).setParam("urlGen" /* URL_GEN */, "default").setParam("runtime" /* RUNTIME */, rt.isNodeIsh ? "node" : rt.isDeno ? "deno" : "unknown").URI();
|
3072
|
+
}
|
3073
|
+
if ((0, import_cement16.runtimeFn)().isNodeIsh || (0, import_cement16.runtimeFn)().isDeno) {
|
3074
|
+
registerStoreProtocol({
|
3075
|
+
protocol: "file:",
|
3076
|
+
isDefault: true,
|
3077
|
+
defaultURI,
|
3078
|
+
gateway: async (sthis) => {
|
3079
|
+
return new FileGateway(sthis, await sysFileSystemFactory(defaultURI(sthis)));
|
3080
|
+
}
|
3081
|
+
});
|
3082
|
+
}
|
3083
|
+
if ((0, import_cement16.runtimeFn)().isBrowser) {
|
3084
|
+
registerStoreProtocol({
|
3085
|
+
protocol: "indexdb:",
|
3086
|
+
isDefault: true,
|
3087
|
+
defaultURI: () => {
|
3088
|
+
return import_cement16.BuildURI.from("indexdb://").pathname("fp").setParam("version" /* VERSION */, INDEXDB_VERSION).setParam("runtime" /* RUNTIME */, "browser").URI();
|
3089
|
+
},
|
3090
|
+
gateway: async () => {
|
3091
|
+
const { GatewayImpl } = await import("@fireproof/core/web");
|
3092
|
+
return new GatewayImpl();
|
2460
3093
|
}
|
2461
|
-
const store = new DataStoreImpl(sthis, loader.name, url, {
|
2462
|
-
gateway: gateway.gateway,
|
2463
|
-
keybag: () => getKeyBag(loader.sthis, {
|
2464
|
-
...loader.ebOpts.keyBag
|
2465
|
-
})
|
2466
|
-
});
|
2467
|
-
return store;
|
2468
3094
|
});
|
2469
3095
|
}
|
2470
|
-
var
|
2471
|
-
|
2472
|
-
|
2473
|
-
|
2474
|
-
|
2475
|
-
|
2476
|
-
|
2477
|
-
|
2478
|
-
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
|
2484
|
-
|
2485
|
-
|
2486
|
-
|
3096
|
+
var memory = /* @__PURE__ */ new Map();
|
3097
|
+
registerStoreProtocol({
|
3098
|
+
protocol: "memory:",
|
3099
|
+
isDefault: false,
|
3100
|
+
defaultURI: () => {
|
3101
|
+
return import_cement16.BuildURI.from("memory://").pathname("ram").URI();
|
3102
|
+
},
|
3103
|
+
gateway: async (sthis) => {
|
3104
|
+
return new MemoryGateway(sthis, memory);
|
3105
|
+
}
|
3106
|
+
});
|
3107
|
+
|
3108
|
+
// src/blockstore/store-factory.ts
|
3109
|
+
var onceGateway = new import_cement17.KeyedResolvOnce();
|
3110
|
+
var gatewayInstances = new import_cement17.KeyedResolvOnce();
|
3111
|
+
async function getStartedGateway(sthis, url) {
|
3112
|
+
return onceGateway.get(url.toString()).once(async () => {
|
3113
|
+
const item = getGatewayFactoryItem(url.protocol);
|
3114
|
+
if (item) {
|
3115
|
+
const ret = {
|
3116
|
+
url,
|
3117
|
+
...await gatewayInstances.get(url.protocol).once(async () => ({})),
|
3118
|
+
gateway: await item.serdegateway(sthis)
|
3119
|
+
};
|
3120
|
+
const res = await ret.gateway.start(sthis, url);
|
3121
|
+
if (res.isErr()) {
|
3122
|
+
return import_cement17.Result.Err(sthis.logger.Error().Result("start", res).Msg("start failed").AsError());
|
3123
|
+
}
|
3124
|
+
ret.url = res.Ok();
|
3125
|
+
return import_cement17.Result.Ok(ret);
|
3126
|
+
}
|
3127
|
+
return import_cement17.Result.Err(sthis.logger.Warn().Url(url).Msg("unsupported protocol").AsError());
|
2487
3128
|
});
|
2488
3129
|
}
|
2489
|
-
|
2490
|
-
|
2491
|
-
const
|
2492
|
-
|
2493
|
-
|
2494
|
-
|
2495
|
-
|
2496
|
-
|
2497
|
-
|
2498
|
-
|
2499
|
-
|
2500
|
-
gateway: gateway.gateway,
|
2501
|
-
keybag: () => getKeyBag(loader.sthis, {
|
2502
|
-
...loader.ebOpts.keyBag
|
2503
|
-
})
|
2504
|
-
});
|
2505
|
-
return store;
|
3130
|
+
async function dataStoreFactory(sfi) {
|
3131
|
+
const storeUrl = sfi.url.build().setParam("store" /* STORE */, "data").URI();
|
3132
|
+
const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
|
3133
|
+
if (rgateway.isErr()) {
|
3134
|
+
throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
|
3135
|
+
}
|
3136
|
+
const gateway = rgateway.Ok();
|
3137
|
+
const store = new DataStoreImpl(sfi.sthis, gateway.url, {
|
3138
|
+
gateway: gateway.gateway,
|
3139
|
+
gatewayInterceptor: sfi.gatewayInterceptor,
|
3140
|
+
loader: sfi.loader
|
2506
3141
|
});
|
3142
|
+
return store;
|
2507
3143
|
}
|
2508
|
-
async function
|
2509
|
-
|
2510
|
-
const
|
2511
|
-
if (
|
2512
|
-
throw sthis.logger.Error().Url(url).Msg("
|
2513
|
-
}
|
2514
|
-
|
3144
|
+
async function metaStoreFactory(sfi) {
|
3145
|
+
const storeUrl = sfi.url.build().setParam("store" /* STORE */, "meta").URI();
|
3146
|
+
const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
|
3147
|
+
if (rgateway.isErr()) {
|
3148
|
+
throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
|
3149
|
+
}
|
3150
|
+
const gateway = rgateway.Ok();
|
3151
|
+
const store = new MetaStoreImpl(sfi.sthis, gateway.url, {
|
3152
|
+
gateway: gateway.gateway,
|
3153
|
+
gatewayInterceptor: sfi.gatewayInterceptor,
|
3154
|
+
loader: sfi.loader
|
3155
|
+
});
|
3156
|
+
return store;
|
3157
|
+
}
|
3158
|
+
async function WALStoreFactory(sfi) {
|
3159
|
+
const storeUrl = sfi.url.build().setParam("store" /* STORE */, "wal").URI();
|
3160
|
+
const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
|
3161
|
+
if (rgateway.isErr()) {
|
3162
|
+
throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
|
3163
|
+
}
|
3164
|
+
const gateway = rgateway.Ok();
|
3165
|
+
const store = new WALStoreImpl(sfi.sthis, gateway.url, {
|
3166
|
+
gateway: gateway.gateway,
|
3167
|
+
gatewayInterceptor: sfi.gatewayInterceptor,
|
3168
|
+
loader: sfi.loader
|
3169
|
+
});
|
3170
|
+
return store;
|
2515
3171
|
}
|
2516
|
-
async function ensureStart(store
|
3172
|
+
async function ensureStart(store) {
|
2517
3173
|
const ret = await store.start();
|
2518
3174
|
if (ret.isErr()) {
|
2519
|
-
throw logger.Error().Result("start", ret).Msg("start failed").AsError();
|
3175
|
+
throw store.logger.Error().Result("start", ret).Msg("start failed").AsError();
|
2520
3176
|
}
|
2521
|
-
logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
|
3177
|
+
store.logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
|
2522
3178
|
return store;
|
2523
3179
|
}
|
2524
|
-
function
|
2525
|
-
|
3180
|
+
function ensureStoreEnDeFile(ende) {
|
3181
|
+
ende = ende || {};
|
2526
3182
|
return {
|
2527
|
-
|
2528
|
-
|
2529
|
-
return ensureStart(await (loader.ebOpts.store.makeMetaStore || metaStoreFactory)(loader), logger);
|
2530
|
-
},
|
2531
|
-
makeDataStore: async (loader) => {
|
2532
|
-
logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeDataStore).Msg("makeDataStore");
|
2533
|
-
return ensureStart(await (loader.ebOpts.store.makeDataStore || dataStoreFactory)(loader), logger);
|
2534
|
-
},
|
2535
|
-
makeWALStore: async (loader) => {
|
2536
|
-
logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeWALStore).Msg("makeRemoteWAL");
|
2537
|
-
return ensureStart(await (loader.ebOpts.store.makeWALStore || remoteWalFactory)(loader), logger);
|
2538
|
-
},
|
2539
|
-
encodeFile: opts.encodeFile || encodeFile,
|
2540
|
-
decodeFile: opts.decodeFile || decodeFile
|
3183
|
+
encodeFile: ende.encodeFile || encodeFile,
|
3184
|
+
decodeFile: ende.decodeFile || decodeFile
|
2541
3185
|
};
|
2542
3186
|
}
|
2543
|
-
|
2544
|
-
|
2545
|
-
|
2546
|
-
|
2547
|
-
|
2548
|
-
|
2549
|
-
|
2550
|
-
|
2551
|
-
|
2552
|
-
|
2553
|
-
|
2554
|
-
|
2555
|
-
|
2556
|
-
|
2557
|
-
|
2558
|
-
|
2559
|
-
|
2560
|
-
|
2561
|
-
|
2562
|
-
|
2563
|
-
|
2564
|
-
|
2565
|
-
|
2566
|
-
|
2567
|
-
|
3187
|
+
function toStoreRuntime(sthis, endeOpts = {}) {
|
3188
|
+
return {
|
3189
|
+
makeMetaStore: async (sfi) => ensureStart(await metaStoreFactory(sfi)),
|
3190
|
+
// async (loader: Loadable) => {
|
3191
|
+
// logger
|
3192
|
+
// .Debug()
|
3193
|
+
// .Str("fromOpts", "" + !!endeOpts.func?.makeMetaStore)
|
3194
|
+
// .Msg("makeMetaStore");
|
3195
|
+
// return ensureStart(await (endeOpts.func?.makeMetaStore || metaStoreFactory)(loader), logger);
|
3196
|
+
// },
|
3197
|
+
makeDataStore: async (sfi) => ensureStart(await dataStoreFactory(sfi)),
|
3198
|
+
// async (loader: Loadable) => {
|
3199
|
+
// logger
|
3200
|
+
// .Debug()
|
3201
|
+
// .Str("fromOpts", "" + !!endeOpts.func?.makeDataStore)
|
3202
|
+
// .Msg("makeDataStore");
|
3203
|
+
// return ensureStart(await (endeOpts.func?.makeDataStore || dataStoreFactory)(loader), logger);
|
3204
|
+
// },
|
3205
|
+
makeWALStore: async (sfi) => ensureStart(await WALStoreFactory(sfi)),
|
3206
|
+
// async (loader: Loadable) => {
|
3207
|
+
// logger
|
3208
|
+
// .Debug()
|
3209
|
+
// .Str("fromOpts", "" + !!endeOpts.func?.makeWALStore)
|
3210
|
+
// .Msg("makeRemoteWAL");
|
3211
|
+
// return ensureStart(await (endeOpts.func?.makeWALStore || remoteWalFactory)(loader), logger);
|
3212
|
+
// },
|
3213
|
+
...ensureStoreEnDeFile(endeOpts)
|
3214
|
+
};
|
2568
3215
|
}
|
2569
3216
|
|
2570
3217
|
// src/blockstore/store-remote.ts
|
2571
|
-
async function RemoteDataStore(sthis,
|
2572
|
-
const ds = new DataStoreImpl(sthis,
|
3218
|
+
async function RemoteDataStore(sthis, url, opts) {
|
3219
|
+
const ds = new DataStoreImpl(sthis, url, opts);
|
2573
3220
|
await ds.start();
|
2574
3221
|
return ds;
|
2575
3222
|
}
|
2576
|
-
async function RemoteMetaStore(sthis,
|
2577
|
-
const ms = new MetaStoreImpl(
|
2578
|
-
sthis,
|
2579
|
-
name,
|
2580
|
-
url,
|
2581
|
-
opts
|
2582
|
-
/* , true*/
|
2583
|
-
);
|
3223
|
+
async function RemoteMetaStore(sthis, url, opts) {
|
3224
|
+
const ms = new MetaStoreImpl(sthis, url, opts);
|
2584
3225
|
await ms.start();
|
2585
3226
|
return ms;
|
2586
3227
|
}
|
2587
3228
|
|
2588
3229
|
// src/blockstore/connection-base.ts
|
3230
|
+
function coerceLoader(ref) {
|
3231
|
+
const refl = ref;
|
3232
|
+
if (refl.loader) {
|
3233
|
+
return refl.loader;
|
3234
|
+
}
|
3235
|
+
const refb = ref;
|
3236
|
+
if (refb.blockstore) {
|
3237
|
+
return coerceLoader(refb.blockstore);
|
3238
|
+
}
|
3239
|
+
return void 0;
|
3240
|
+
}
|
2589
3241
|
var ConnectionBase = class {
|
2590
3242
|
constructor(url, logger) {
|
2591
3243
|
this.loaded = Promise.resolve();
|
@@ -2596,23 +3248,26 @@ var ConnectionBase = class {
|
|
2596
3248
|
await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load();
|
2597
3249
|
await (await throwFalsy(this.loader).WALStore()).process();
|
2598
3250
|
}
|
2599
|
-
async
|
2600
|
-
|
2601
|
-
await this.
|
2602
|
-
await this.connectStorage_X({ loader });
|
3251
|
+
async connect(refl) {
|
3252
|
+
await this.connectMeta(refl);
|
3253
|
+
await this.connectStorage(refl);
|
2603
3254
|
}
|
2604
|
-
async
|
2605
|
-
|
3255
|
+
async connectMeta(refl) {
|
3256
|
+
const loader = coerceLoader(refl);
|
3257
|
+
if (!loader) throw this.logger.Error().Msg("connectMeta: loader is required").AsError();
|
2606
3258
|
this.loader = loader;
|
2607
3259
|
await this.onConnect();
|
2608
|
-
const metaUrl = this.url.build().defParam("store"
|
2609
|
-
const
|
2610
|
-
if (
|
2611
|
-
|
2612
|
-
|
2613
|
-
|
3260
|
+
const metaUrl = this.url.build().defParam("store" /* STORE */, "meta").URI();
|
3261
|
+
const rgateway = await getStartedGateway(loader.sthis, metaUrl);
|
3262
|
+
if (rgateway.isErr())
|
3263
|
+
throw this.logger.Error().Result("err", rgateway).Url(metaUrl).Msg("connectMeta: gateway is required").AsError();
|
3264
|
+
const dbName = metaUrl.getParam("name" /* NAME */);
|
3265
|
+
if (!dbName) {
|
3266
|
+
throw this.logger.Error().Url(metaUrl).Msg("connectMeta: dbName is required").AsError();
|
3267
|
+
}
|
3268
|
+
const gateway = rgateway.Ok();
|
3269
|
+
const remote = await RemoteMetaStore(loader.sthis, metaUrl, {
|
2614
3270
|
gateway: gateway.gateway,
|
2615
|
-
keybag: () => getKeyBag(loader.sthis, loader.ebOpts.keyBag),
|
2616
3271
|
loader
|
2617
3272
|
});
|
2618
3273
|
this.loader.remoteMetaStore = remote;
|
@@ -2622,17 +3277,19 @@ var ConnectionBase = class {
|
|
2622
3277
|
});
|
2623
3278
|
});
|
2624
3279
|
}
|
2625
|
-
async
|
3280
|
+
async connectStorage(refl) {
|
3281
|
+
const loader = coerceLoader(refl);
|
2626
3282
|
if (!loader) throw this.logger.Error().Msg("connectStorage_X: loader is required").AsError();
|
2627
3283
|
this.loader = loader;
|
2628
|
-
const dataUrl = this.url.build().defParam("store"
|
2629
|
-
const
|
2630
|
-
if (
|
2631
|
-
|
3284
|
+
const dataUrl = this.url.build().defParam("store" /* STORE */, "data").URI();
|
3285
|
+
const rgateway = await getStartedGateway(loader.sthis, dataUrl);
|
3286
|
+
if (rgateway.isErr())
|
3287
|
+
throw this.logger.Error().Result("err", rgateway).Url(dataUrl).Msg("connectStorage_X: gateway is required").AsError();
|
3288
|
+
const name = dataUrl.getParam("name" /* NAME */);
|
2632
3289
|
if (!name) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: name is required").AsError;
|
2633
|
-
loader.remoteCarStore = await RemoteDataStore(loader.sthis,
|
2634
|
-
gateway:
|
2635
|
-
|
3290
|
+
loader.remoteCarStore = await RemoteDataStore(loader.sthis, this.url, {
|
3291
|
+
gateway: rgateway.Ok().gateway,
|
3292
|
+
loader
|
2636
3293
|
});
|
2637
3294
|
loader.remoteFileStore = loader.remoteCarStore;
|
2638
3295
|
}
|
@@ -2672,6 +3329,12 @@ var ConnectionBase = class {
|
|
2672
3329
|
};
|
2673
3330
|
|
2674
3331
|
// src/crdt-helpers.ts
|
3332
|
+
var import_link2 = require("multiformats/link");
|
3333
|
+
var import_sha25 = require("multiformats/hashes/sha2");
|
3334
|
+
var codec = __toESM(require("@fireproof/vendor/@ipld/dag-cbor"), 1);
|
3335
|
+
var import_crdt = require("@fireproof/vendor/@web3-storage/pail/crdt");
|
3336
|
+
var import_clock3 = require("@fireproof/vendor/@web3-storage/pail/clock");
|
3337
|
+
var Batch = __toESM(require("@fireproof/vendor/@web3-storage/pail/crdt/batch"), 1);
|
2675
3338
|
function time(tag) {
|
2676
3339
|
}
|
2677
3340
|
function timeEnd(tag) {
|
@@ -2818,7 +3481,7 @@ async function getValueFromLink(blocks, link, logger) {
|
|
2818
3481
|
readFiles(blocks, cvalue);
|
2819
3482
|
return cvalue;
|
2820
3483
|
}
|
2821
|
-
var DirtyEventFetcher = class extends
|
3484
|
+
var DirtyEventFetcher = class extends import_clock3.EventFetcher {
|
2822
3485
|
constructor(logger, blocks) {
|
2823
3486
|
super(blocks);
|
2824
3487
|
this.logger = logger;
|
@@ -2833,7 +3496,7 @@ var DirtyEventFetcher = class extends import_clock2.EventFetcher {
|
|
2833
3496
|
}
|
2834
3497
|
};
|
2835
3498
|
async function clockChangesSince(blocks, head, since, opts, logger) {
|
2836
|
-
const eventsFetcher = opts.dirty ? new DirtyEventFetcher(logger, blocks) : new
|
3499
|
+
const eventsFetcher = opts.dirty ? new DirtyEventFetcher(logger, blocks) : new import_clock3.EventFetcher(blocks);
|
2837
3500
|
const keys = /* @__PURE__ */ new Set();
|
2838
3501
|
const updates = await gatherUpdates(
|
2839
3502
|
blocks,
|
@@ -2890,7 +3553,7 @@ async function* getAllEntries(blocks, head, logger) {
|
|
2890
3553
|
}
|
2891
3554
|
}
|
2892
3555
|
async function* clockVis(blocks, head) {
|
2893
|
-
for await (const line of (0,
|
3556
|
+
for await (const line of (0, import_clock3.vis)(blocks, head)) {
|
2894
3557
|
yield line;
|
2895
3558
|
}
|
2896
3559
|
}
|
@@ -2912,7 +3575,7 @@ async function doCompact(blockLog, head, logger) {
|
|
2912
3575
|
}
|
2913
3576
|
timeEnd("compact all entries");
|
2914
3577
|
time("compact clock vis");
|
2915
|
-
for await (const _line of (0,
|
3578
|
+
for await (const _line of (0, import_clock3.vis)(blockLog, head)) {
|
2916
3579
|
}
|
2917
3580
|
timeEnd("compact clock vis");
|
2918
3581
|
time("compact root");
|
@@ -2929,7 +3592,7 @@ async function doCompact(blockLog, head, logger) {
|
|
2929
3592
|
isCompacting = false;
|
2930
3593
|
}
|
2931
3594
|
async function getBlock(blocks, cidString) {
|
2932
|
-
const block = await blocks.get((0,
|
3595
|
+
const block = await blocks.get((0, import_link2.parse)(cidString));
|
2933
3596
|
if (!block) throw new Error(`Missing block ${cidString}`);
|
2934
3597
|
const { cid, value } = await decode({ bytes: block.bytes, codec, hasher: import_sha25.sha256 });
|
2935
3598
|
return new Block({ cid, value, bytes: block.bytes });
|
@@ -2940,7 +3603,7 @@ var import_sha26 = require("multiformats/hashes/sha2");
|
|
2940
3603
|
var codec2 = __toESM(require("@fireproof/vendor/@ipld/dag-cbor"), 1);
|
2941
3604
|
var import_charwise = __toESM(require("charwise"), 1);
|
2942
3605
|
var DbIndex = __toESM(require("prolly-trees/db-index"), 1);
|
2943
|
-
var
|
3606
|
+
var import_utils12 = require("prolly-trees/utils");
|
2944
3607
|
var import_cache = require("prolly-trees/cache");
|
2945
3608
|
var IndexTree = class {
|
2946
3609
|
};
|
@@ -2948,17 +3611,17 @@ function refCompare(aRef, bRef) {
|
|
2948
3611
|
if (Number.isNaN(aRef)) return -1;
|
2949
3612
|
if (Number.isNaN(bRef)) throw new Error("ref may not be Infinity or NaN");
|
2950
3613
|
if (aRef === Infinity) return 1;
|
2951
|
-
return (0,
|
3614
|
+
return (0, import_utils12.simpleCompare)(aRef, bRef);
|
2952
3615
|
}
|
2953
3616
|
function compare(a, b) {
|
2954
3617
|
const [aKey, aRef] = a;
|
2955
3618
|
const [bKey, bRef] = b;
|
2956
|
-
const comp = (0,
|
3619
|
+
const comp = (0, import_utils12.simpleCompare)(aKey, bKey);
|
2957
3620
|
if (comp !== 0) return comp;
|
2958
3621
|
return refCompare(aRef, bRef);
|
2959
3622
|
}
|
2960
|
-
var byKeyOpts = { cache: import_cache.nocache, chunker: (0,
|
2961
|
-
var byIdOpts = { cache: import_cache.nocache, chunker: (0,
|
3623
|
+
var byKeyOpts = { cache: import_cache.nocache, chunker: (0, import_utils12.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare };
|
3624
|
+
var byIdOpts = { cache: import_cache.nocache, chunker: (0, import_utils12.bf)(30), codec: codec2, hasher: import_sha26.sha256, compare: import_utils12.simpleCompare };
|
2962
3625
|
function indexEntriesForChanges(changes, mapFn) {
|
2963
3626
|
const indexEntries = [];
|
2964
3627
|
changes.forEach(({ id: key, value, del }) => {
|
@@ -2989,7 +3652,8 @@ function makeProllyGetBlock(blocks) {
|
|
2989
3652
|
return create({ cid, bytes, hasher: import_sha26.sha256, codec: codec2 });
|
2990
3653
|
};
|
2991
3654
|
}
|
2992
|
-
async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
|
3655
|
+
async function bulkIndex(logger, tblocks, inIndex, indexEntries, opts) {
|
3656
|
+
logger.Debug().Msg("enter bulkIndex");
|
2993
3657
|
if (!indexEntries.length) return inIndex;
|
2994
3658
|
if (!inIndex.root) {
|
2995
3659
|
if (!inIndex.cid) {
|
@@ -3006,18 +3670,22 @@ async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
|
|
3006
3670
|
returnNode = node;
|
3007
3671
|
}
|
3008
3672
|
if (!returnNode || !returnRootBlock) throw new Error("failed to create index");
|
3673
|
+
logger.Debug().Msg("exit !root bulkIndex");
|
3009
3674
|
return { root: returnNode, cid: returnRootBlock.cid };
|
3010
3675
|
} else {
|
3011
3676
|
inIndex.root = await DbIndex.load({ cid: inIndex.cid, get: makeProllyGetBlock(tblocks), ...opts });
|
3012
3677
|
}
|
3013
3678
|
}
|
3679
|
+
logger.Debug().Msg("pre bulk bulkIndex");
|
3014
3680
|
const { root: root3, blocks: newBlocks } = await inIndex.root.bulk(indexEntries);
|
3015
3681
|
if (root3) {
|
3682
|
+
logger.Debug().Msg("pre root put bulkIndex");
|
3016
3683
|
for await (const block of newBlocks) {
|
3017
3684
|
await tblocks.put(block.cid, block.bytes);
|
3018
3685
|
}
|
3019
3686
|
return { root: root3, cid: (await root3.block).cid };
|
3020
3687
|
} else {
|
3688
|
+
logger.Debug().Msg("pre !root bulkIndex");
|
3021
3689
|
return { root: void 0, cid: void 0 };
|
3022
3690
|
}
|
3023
3691
|
}
|
@@ -3057,17 +3725,17 @@ function encodeKey(key) {
|
|
3057
3725
|
}
|
3058
3726
|
|
3059
3727
|
// src/indexer.ts
|
3060
|
-
function index(
|
3061
|
-
if (mapFn && meta) throw
|
3062
|
-
if (mapFn && mapFn.constructor.name !== "Function") throw
|
3063
|
-
if (
|
3064
|
-
const idx =
|
3728
|
+
function index(refDb, name, mapFn, meta) {
|
3729
|
+
if (mapFn && meta) throw refDb.crdt.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
|
3730
|
+
if (mapFn && mapFn.constructor.name !== "Function") throw refDb.crdt.logger.Error().Msg("mapFn must be a function").AsError();
|
3731
|
+
if (refDb.crdt.indexers.has(name)) {
|
3732
|
+
const idx = refDb.crdt.indexers.get(name);
|
3065
3733
|
idx.applyMapFn(name, mapFn, meta);
|
3066
3734
|
} else {
|
3067
|
-
const idx = new Index(sthis,
|
3068
|
-
|
3735
|
+
const idx = new Index(refDb.crdt.sthis, refDb.crdt, name, mapFn, meta);
|
3736
|
+
refDb.crdt.indexers.set(name, idx);
|
3069
3737
|
}
|
3070
|
-
return
|
3738
|
+
return refDb.crdt.indexers.get(name);
|
3071
3739
|
}
|
3072
3740
|
var Index = class {
|
3073
3741
|
constructor(sthis, crdt, name, mapFn, meta) {
|
@@ -3086,18 +3754,9 @@ var Index = class {
|
|
3086
3754
|
return Promise.all([this.blockstore.ready(), this.crdt.ready()]).then(() => {
|
3087
3755
|
});
|
3088
3756
|
}
|
3089
|
-
close() {
|
3090
|
-
return Promise.all([this.blockstore.close(), this.crdt.close()]).then(() => {
|
3091
|
-
});
|
3092
|
-
}
|
3093
|
-
destroy() {
|
3094
|
-
return Promise.all([this.blockstore.destroy(), this.crdt.destroy()]).then(() => {
|
3095
|
-
});
|
3096
|
-
}
|
3097
3757
|
applyMapFn(name, mapFn, meta) {
|
3098
3758
|
if (mapFn && meta) throw this.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
|
3099
3759
|
if (this.name && this.name !== name) throw this.logger.Error().Msg("cannot change name").AsError();
|
3100
|
-
this.name = name;
|
3101
3760
|
try {
|
3102
3761
|
if (meta) {
|
3103
3762
|
if (this.indexHead && this.indexHead.map((c) => c.toString()).join() !== meta.head.map((c) => c.toString()).join()) {
|
@@ -3145,9 +3804,13 @@ var Index = class {
|
|
3145
3804
|
}
|
3146
3805
|
}
|
3147
3806
|
async query(opts = {}) {
|
3807
|
+
this.logger.Debug().Msg("enter query");
|
3148
3808
|
await this.ready();
|
3809
|
+
this.logger.Debug().Msg("post ready query");
|
3149
3810
|
await this._updateIndex();
|
3811
|
+
this.logger.Debug().Msg("post _updateIndex query");
|
3150
3812
|
await this._hydrateIndex();
|
3813
|
+
this.logger.Debug().Msg("post _hydrateIndex query");
|
3151
3814
|
if (!this.byKey.root) {
|
3152
3815
|
return await applyQuery(this.crdt, { result: [] }, opts);
|
3153
3816
|
}
|
@@ -3203,13 +3866,16 @@ var Index = class {
|
|
3203
3866
|
}
|
3204
3867
|
async _updateIndex() {
|
3205
3868
|
await this.ready();
|
3869
|
+
this.logger.Debug().Msg("enter _updateIndex");
|
3206
3870
|
if (this.initError) throw this.initError;
|
3207
3871
|
if (!this.mapFn) throw this.logger.Error().Msg("No map function defined").AsError();
|
3208
3872
|
let result, head;
|
3209
3873
|
if (!this.indexHead || this.indexHead.length === 0) {
|
3210
3874
|
({ result, head } = await this.crdt.allDocs());
|
3875
|
+
this.logger.Debug().Msg("enter crdt.allDocs");
|
3211
3876
|
} else {
|
3212
3877
|
({ result, head } = await this.crdt.changes(this.indexHead));
|
3878
|
+
this.logger.Debug().Msg("enter crdt.changes");
|
3213
3879
|
}
|
3214
3880
|
if (result.length === 0) {
|
3215
3881
|
this.indexHead = head;
|
@@ -3242,9 +3908,22 @@ var Index = class {
|
|
3242
3908
|
if (result.length === 0) {
|
3243
3909
|
return indexerMeta;
|
3244
3910
|
}
|
3911
|
+
this.logger.Debug().Msg("pre this.blockstore.transaction");
|
3245
3912
|
const { meta } = await this.blockstore.transaction(async (tblocks) => {
|
3246
|
-
this.byId = await bulkIndex(
|
3247
|
-
|
3913
|
+
this.byId = await bulkIndex(
|
3914
|
+
this.logger,
|
3915
|
+
tblocks,
|
3916
|
+
this.byId,
|
3917
|
+
removeIdIndexEntries.concat(byIdIndexEntries),
|
3918
|
+
byIdOpts
|
3919
|
+
);
|
3920
|
+
this.byKey = await bulkIndex(
|
3921
|
+
this.logger,
|
3922
|
+
tblocks,
|
3923
|
+
this.byKey,
|
3924
|
+
staleKeyIndexEntries.concat(indexEntries),
|
3925
|
+
byKeyOpts
|
3926
|
+
);
|
3248
3927
|
this.indexHead = head;
|
3249
3928
|
if (this.byId.cid && this.byKey.cid) {
|
3250
3929
|
const idxMeta = {
|
@@ -3256,16 +3935,18 @@ var Index = class {
|
|
3256
3935
|
};
|
3257
3936
|
indexerMeta.indexes?.set(this.name, idxMeta);
|
3258
3937
|
}
|
3938
|
+
this.logger.Debug().Any("indexerMeta", new Array(indexerMeta.indexes?.entries())).Msg("exit this.blockstore.transaction fn");
|
3259
3939
|
return indexerMeta;
|
3260
3940
|
});
|
3941
|
+
this.logger.Debug().Msg("post this.blockstore.transaction");
|
3261
3942
|
return meta;
|
3262
3943
|
}
|
3263
3944
|
};
|
3264
3945
|
|
3265
3946
|
// src/crdt-clock.ts
|
3266
|
-
var
|
3947
|
+
var import_clock4 = require("@fireproof/vendor/@web3-storage/pail/clock");
|
3267
3948
|
var import_crdt2 = require("@fireproof/vendor/@web3-storage/pail/crdt");
|
3268
|
-
var
|
3949
|
+
var import_cement18 = require("@adviser/cement");
|
3269
3950
|
|
3270
3951
|
// src/apply-head-queue.ts
|
3271
3952
|
function applyHeadQueue(worker, logger) {
|
@@ -3322,7 +4003,7 @@ var CRDTClock = class {
|
|
3322
4003
|
this.zoomers = /* @__PURE__ */ new Set();
|
3323
4004
|
this.watchers = /* @__PURE__ */ new Set();
|
3324
4005
|
this.emptyWatchers = /* @__PURE__ */ new Set();
|
3325
|
-
this._ready = new
|
4006
|
+
this._ready = new import_cement18.ResolveOnce();
|
3326
4007
|
this.blockstore = blockstore;
|
3327
4008
|
this.logger = ensureLogger(blockstore.sthis, "CRDTClock");
|
3328
4009
|
this.applyHeadQueue = applyHeadQueue(this.int_applyHead.bind(this), this.logger);
|
@@ -3422,7 +4103,7 @@ function compareClockHeads(head1, head2) {
|
|
3422
4103
|
async function advanceBlocks(logger, newHead, tblocks, head) {
|
3423
4104
|
for (const cid of newHead) {
|
3424
4105
|
try {
|
3425
|
-
head = await (0,
|
4106
|
+
head = await (0, import_clock4.advance)(tblocks, head, cid);
|
3426
4107
|
} catch (e) {
|
3427
4108
|
logger.Debug().Err(e).Msg("failed to advance head");
|
3428
4109
|
continue;
|
@@ -3433,15 +4114,13 @@ async function advanceBlocks(logger, newHead, tblocks, head) {
|
|
3433
4114
|
|
3434
4115
|
// src/crdt.ts
|
3435
4116
|
var CRDT = class {
|
3436
|
-
constructor(sthis,
|
4117
|
+
constructor(sthis, opts) {
|
3437
4118
|
this.indexers = /* @__PURE__ */ new Map();
|
3438
|
-
this.onceReady = new
|
4119
|
+
this.onceReady = new import_cement19.ResolveOnce();
|
3439
4120
|
this.sthis = sthis;
|
3440
|
-
this.name = name;
|
3441
4121
|
this.logger = ensureLogger(sthis, "CRDT");
|
3442
4122
|
this.opts = opts;
|
3443
|
-
this.blockstore =
|
3444
|
-
name,
|
4123
|
+
this.blockstore = new EncryptedBlockstore(sthis, {
|
3445
4124
|
applyMeta: async (meta) => {
|
3446
4125
|
const crdtMeta = meta;
|
3447
4126
|
if (!crdtMeta.head) throw this.logger.Error().Msg("missing head").AsError();
|
@@ -3451,23 +4130,29 @@ var CRDT = class {
|
|
3451
4130
|
await doCompact(blocks, this.clock.head, this.logger);
|
3452
4131
|
return { head: this.clock.head };
|
3453
4132
|
},
|
3454
|
-
|
3455
|
-
|
3456
|
-
|
3457
|
-
|
3458
|
-
|
4133
|
+
gatewayInterceptor: opts.gatewayInterceptor,
|
4134
|
+
// autoCompact: this.opts.autoCompact || 100,
|
4135
|
+
storeRuntime: toStoreRuntime(this.sthis, this.opts.storeEnDe),
|
4136
|
+
storeUrls: this.opts.storeUrls.data,
|
4137
|
+
keyBag: this.opts.keyBag,
|
4138
|
+
// public: this.opts.public,
|
4139
|
+
meta: this.opts.meta
|
4140
|
+
// threshold: this.opts.threshold,
|
3459
4141
|
});
|
3460
|
-
this.indexBlockstore =
|
3461
|
-
name,
|
4142
|
+
this.indexBlockstore = new EncryptedBlockstore(sthis, {
|
4143
|
+
// name: opts.name,
|
3462
4144
|
applyMeta: async (meta) => {
|
3463
4145
|
const idxCarMeta = meta;
|
3464
4146
|
if (!idxCarMeta.indexes) throw this.logger.Error().Msg("missing indexes").AsError();
|
3465
|
-
for (const [
|
3466
|
-
index(
|
4147
|
+
for (const [name, idx] of Object.entries(idxCarMeta.indexes)) {
|
4148
|
+
index({ crdt: this }, name, void 0, idx);
|
3467
4149
|
}
|
3468
4150
|
},
|
3469
|
-
|
3470
|
-
|
4151
|
+
gatewayInterceptor: opts.gatewayInterceptor,
|
4152
|
+
storeRuntime: toStoreRuntime(this.sthis, this.opts.storeEnDe),
|
4153
|
+
storeUrls: this.opts.storeUrls.idx,
|
4154
|
+
keyBag: this.opts.keyBag
|
4155
|
+
// public: this.opts.public,
|
3471
4156
|
});
|
3472
4157
|
this.clock = new CRDTClock(this.blockstore);
|
3473
4158
|
this.clock.onZoom(() => {
|
@@ -3549,74 +4234,168 @@ var CRDT = class {
|
|
3549
4234
|
};
|
3550
4235
|
|
3551
4236
|
// src/database.ts
|
3552
|
-
var
|
3553
|
-
|
3554
|
-
|
4237
|
+
var databases = new import_cement20.KeyedResolvOnce();
|
4238
|
+
function keyConfigOpts(sthis, name, opts) {
|
4239
|
+
return JSON.stringify(
|
4240
|
+
toSortedArray({
|
4241
|
+
name,
|
4242
|
+
stores: toSortedArray(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, name, opts?.storeUrls))))
|
4243
|
+
})
|
4244
|
+
);
|
4245
|
+
}
|
4246
|
+
function isDatabase(db) {
|
4247
|
+
return db instanceof DatabaseImpl || db instanceof DatabaseShell;
|
4248
|
+
}
|
4249
|
+
function DatabaseFactory(name, opts) {
|
4250
|
+
const sthis = ensureSuperThis(opts);
|
4251
|
+
return new DatabaseShell(
|
4252
|
+
databases.get(keyConfigOpts(sthis, name, opts)).once((key) => {
|
4253
|
+
const db = new DatabaseImpl(sthis, {
|
4254
|
+
name,
|
4255
|
+
meta: opts?.meta,
|
4256
|
+
keyBag: defaultKeyBagOpts(sthis, opts?.keyBag),
|
4257
|
+
storeUrls: toStoreURIRuntime(sthis, name, opts?.storeUrls),
|
4258
|
+
gatewayInterceptor: opts?.gatewayInterceptor,
|
4259
|
+
writeQueue: defaultWriteQueueOpts(opts?.writeQueue),
|
4260
|
+
storeEnDe: {
|
4261
|
+
encodeFile,
|
4262
|
+
decodeFile,
|
4263
|
+
...opts?.storeEnDe
|
4264
|
+
}
|
4265
|
+
});
|
4266
|
+
db.onClosed(() => {
|
4267
|
+
databases.unget(key);
|
4268
|
+
});
|
4269
|
+
return db;
|
4270
|
+
})
|
4271
|
+
);
|
4272
|
+
}
|
4273
|
+
var DatabaseShell = class {
|
4274
|
+
constructor(ref) {
|
4275
|
+
this.ref = ref;
|
4276
|
+
ref.addShell(this);
|
4277
|
+
}
|
4278
|
+
get id() {
|
4279
|
+
return this.ref.id;
|
4280
|
+
}
|
4281
|
+
get logger() {
|
4282
|
+
return this.ref.logger;
|
4283
|
+
}
|
4284
|
+
get sthis() {
|
4285
|
+
return this.ref.sthis;
|
4286
|
+
}
|
4287
|
+
get crdt() {
|
4288
|
+
return this.ref.crdt;
|
4289
|
+
}
|
4290
|
+
get name() {
|
4291
|
+
return this.ref.name;
|
4292
|
+
}
|
4293
|
+
onClosed(fn) {
|
4294
|
+
return this.ref.onClosed(fn);
|
4295
|
+
}
|
4296
|
+
close() {
|
4297
|
+
return this.ref.shellClose(this);
|
4298
|
+
}
|
4299
|
+
destroy() {
|
4300
|
+
return this.ref.destroy();
|
4301
|
+
}
|
4302
|
+
ready() {
|
4303
|
+
return this.ref.ready();
|
4304
|
+
}
|
4305
|
+
get(id) {
|
4306
|
+
return this.ref.get(id);
|
4307
|
+
}
|
4308
|
+
put(doc) {
|
4309
|
+
return this.ref.put(doc);
|
4310
|
+
}
|
4311
|
+
bulk(docs) {
|
4312
|
+
return this.ref.bulk(docs);
|
4313
|
+
}
|
4314
|
+
del(id) {
|
4315
|
+
return this.ref.del(id);
|
4316
|
+
}
|
4317
|
+
changes(since, opts) {
|
4318
|
+
return this.ref.changes(since, opts);
|
4319
|
+
}
|
4320
|
+
allDocs(opts) {
|
4321
|
+
return this.ref.allDocs(opts);
|
4322
|
+
}
|
4323
|
+
allDocuments() {
|
4324
|
+
return this.ref.allDocuments();
|
4325
|
+
}
|
4326
|
+
subscribe(listener, updates) {
|
4327
|
+
return this.ref.subscribe(listener, updates);
|
4328
|
+
}
|
4329
|
+
query(field, opts) {
|
4330
|
+
return this.ref.query(field, opts);
|
4331
|
+
}
|
4332
|
+
compact() {
|
4333
|
+
return this.ref.compact();
|
4334
|
+
}
|
4335
|
+
};
|
4336
|
+
var DatabaseImpl = class {
|
4337
|
+
constructor(sthis, opts) {
|
3555
4338
|
this._listening = false;
|
3556
4339
|
this._listeners = /* @__PURE__ */ new Set();
|
3557
4340
|
this._noupdate_listeners = /* @__PURE__ */ new Set();
|
3558
|
-
|
3559
|
-
this.
|
3560
|
-
this.
|
3561
|
-
this.
|
4341
|
+
// readonly blockstore: BaseBlockstore;
|
4342
|
+
this.shells = /* @__PURE__ */ new Set();
|
4343
|
+
this._onClosedFns = /* @__PURE__ */ new Set();
|
4344
|
+
this._ready = new import_cement20.ResolveOnce();
|
4345
|
+
this.opts = opts;
|
4346
|
+
this.sthis = sthis;
|
4347
|
+
this.id = sthis.timeOrderedNextId().str;
|
3562
4348
|
this.logger = ensureLogger(this.sthis, "Database");
|
3563
|
-
this.
|
3564
|
-
this.
|
3565
|
-
this.
|
3566
|
-
return await this._crdt.bulk(updates);
|
3567
|
-
});
|
3568
|
-
this._crdt.clock.onTock(() => {
|
3569
|
-
this._no_update_notify();
|
3570
|
-
});
|
4349
|
+
this.crdt = new CRDT(this.sthis, this.opts);
|
4350
|
+
this._writeQueue = writeQueue(this.sthis, async (updates) => this.crdt.bulk(updates), this.opts.writeQueue);
|
4351
|
+
this.crdt.clock.onTock(() => this._no_update_notify());
|
3571
4352
|
}
|
3572
|
-
|
3573
|
-
this.
|
4353
|
+
addShell(shell) {
|
4354
|
+
this.shells.add(shell);
|
4355
|
+
}
|
4356
|
+
onClosed(fn) {
|
4357
|
+
this._onClosedFns.add(fn);
|
3574
4358
|
}
|
3575
|
-
/**
|
3576
|
-
* Close the database and release resources
|
3577
|
-
*/
|
3578
4359
|
async close() {
|
3579
|
-
|
3580
|
-
|
3581
|
-
|
4360
|
+
throw this.logger.Error().Str("db", this.name).Msg(`use shellClose`).AsError();
|
4361
|
+
}
|
4362
|
+
async shellClose(db) {
|
4363
|
+
if (!this.shells.has(db)) {
|
4364
|
+
throw this.logger.Error().Str("db", this.name).Msg(`DatabaseShell mismatch`).AsError();
|
4365
|
+
}
|
4366
|
+
this.shells.delete(db);
|
4367
|
+
if (this.shells.size === 0) {
|
4368
|
+
await this.ready();
|
4369
|
+
await this.crdt.close();
|
4370
|
+
await this._writeQueue.close();
|
4371
|
+
this._onClosedFns.forEach((fn) => fn());
|
4372
|
+
}
|
3582
4373
|
}
|
3583
|
-
/**
|
3584
|
-
* Destroy the database and release all resources
|
3585
|
-
*/
|
3586
4374
|
async destroy() {
|
3587
4375
|
await this.ready();
|
3588
|
-
await this.
|
3589
|
-
await this.blockstore.destroy();
|
4376
|
+
await this.crdt.destroy();
|
3590
4377
|
}
|
3591
4378
|
async ready() {
|
3592
|
-
|
4379
|
+
const ret = await this._ready.once(async () => {
|
3593
4380
|
await this.sthis.start();
|
3594
|
-
await this.
|
3595
|
-
await this.blockstore.ready();
|
4381
|
+
await this.crdt.ready();
|
3596
4382
|
});
|
4383
|
+
return ret;
|
4384
|
+
}
|
4385
|
+
get name() {
|
4386
|
+
return this.opts.storeUrls.data.data.getParam("name" /* NAME */) || "default";
|
3597
4387
|
}
|
3598
|
-
/**
|
3599
|
-
* Get a document from the database
|
3600
|
-
* @param id - the document id
|
3601
|
-
* @returns the document with the _id
|
3602
|
-
* @throws NotFoundError if the document is not found
|
3603
|
-
*/
|
3604
4388
|
async get(id) {
|
3605
4389
|
if (!id) throw this.logger.Error().Str("db", this.name).Msg(`Doc id is required`).AsError();
|
3606
4390
|
await this.ready();
|
3607
4391
|
this.logger.Debug().Str("id", id).Msg("get");
|
3608
|
-
const got = await this.
|
4392
|
+
const got = await this.crdt.get(id).catch((e) => {
|
3609
4393
|
throw new NotFoundError(`Not found: ${id} - ${e.message}`);
|
3610
4394
|
});
|
3611
4395
|
if (!got) throw new NotFoundError(`Not found: ${id}`);
|
3612
4396
|
const { doc } = got;
|
3613
4397
|
return { ...doc, _id: id };
|
3614
4398
|
}
|
3615
|
-
/**
|
3616
|
-
* Put a document from the database
|
3617
|
-
* @param doc - the document to put
|
3618
|
-
* @returns add DocResponse with the id and clock
|
3619
|
-
*/
|
3620
4399
|
async put(doc) {
|
3621
4400
|
await this.ready();
|
3622
4401
|
this.logger.Debug().Str("id", doc._id).Msg("put");
|
@@ -3631,11 +4410,21 @@ var Database = class {
|
|
3631
4410
|
});
|
3632
4411
|
return { id: docId, clock: result?.head, name: this.name };
|
3633
4412
|
}
|
3634
|
-
|
3635
|
-
|
3636
|
-
|
3637
|
-
|
3638
|
-
|
4413
|
+
async bulk(docs) {
|
4414
|
+
await this.ready();
|
4415
|
+
const updates = docs.map((doc) => {
|
4416
|
+
const id = doc._id || this.sthis.timeOrderedNextId().str;
|
4417
|
+
return {
|
4418
|
+
id,
|
4419
|
+
value: {
|
4420
|
+
...doc,
|
4421
|
+
_id: id
|
4422
|
+
}
|
4423
|
+
};
|
4424
|
+
});
|
4425
|
+
const result = await this._writeQueue.bulk(updates);
|
4426
|
+
return { ids: updates.map((u) => u.id), clock: result.head, name: this.name };
|
4427
|
+
}
|
3639
4428
|
async del(id) {
|
3640
4429
|
await this.ready();
|
3641
4430
|
this.logger.Debug().Str("id", id).Msg("del");
|
@@ -3645,7 +4434,7 @@ var Database = class {
|
|
3645
4434
|
async changes(since = [], opts = {}) {
|
3646
4435
|
await this.ready();
|
3647
4436
|
this.logger.Debug().Any("since", since).Any("opts", opts).Msg("changes");
|
3648
|
-
const { result, head } = await this.
|
4437
|
+
const { result, head } = await this.crdt.changes(since, opts);
|
3649
4438
|
const rows = result.map(({ id: key, value, del, clock }) => ({
|
3650
4439
|
key,
|
3651
4440
|
value: del ? { _id: key, _deleted: true } : { _id: key, ...value },
|
@@ -3656,7 +4445,7 @@ var Database = class {
|
|
3656
4445
|
async allDocs(opts = {}) {
|
3657
4446
|
await this.ready();
|
3658
4447
|
this.logger.Debug().Msg("allDocs");
|
3659
|
-
const { result, head } = await this.
|
4448
|
+
const { result, head } = await this.crdt.allDocs();
|
3660
4449
|
const rows = result.map(({ id: key, value, del }) => ({
|
3661
4450
|
key,
|
3662
4451
|
value: del ? { _id: key, _deleted: true } : { _id: key, ...value }
|
@@ -3671,7 +4460,7 @@ var Database = class {
|
|
3671
4460
|
if (updates) {
|
3672
4461
|
if (!this._listening) {
|
3673
4462
|
this._listening = true;
|
3674
|
-
this.
|
4463
|
+
this.crdt.clock.onTick((updates2) => {
|
3675
4464
|
void this._notify(updates2);
|
3676
4465
|
});
|
3677
4466
|
}
|
@@ -3690,13 +4479,13 @@ var Database = class {
|
|
3690
4479
|
async query(field, opts = {}) {
|
3691
4480
|
await this.ready();
|
3692
4481
|
this.logger.Debug().Any("field", field).Any("opts", opts).Msg("query");
|
3693
|
-
const _crdt = this.
|
3694
|
-
const idx = typeof field === "string" ? index(
|
4482
|
+
const _crdt = this.crdt;
|
4483
|
+
const idx = typeof field === "string" ? index({ crdt: _crdt }, field) : index({ crdt: _crdt }, makeName(field.toString()), field);
|
3695
4484
|
return await idx.query(opts);
|
3696
4485
|
}
|
3697
4486
|
async compact() {
|
3698
4487
|
await this.ready();
|
3699
|
-
await this.
|
4488
|
+
await this.crdt.compact();
|
3700
4489
|
}
|
3701
4490
|
async _notify(updates) {
|
3702
4491
|
await this.ready();
|
@@ -3720,23 +4509,62 @@ var Database = class {
|
|
3720
4509
|
}
|
3721
4510
|
}
|
3722
4511
|
};
|
3723
|
-
function
|
3724
|
-
|
3725
|
-
|
4512
|
+
function defaultURI2(sthis, curi, uri, store, ctx) {
|
4513
|
+
ctx = ctx || {};
|
4514
|
+
const ret = (curi ? import_cement20.URI.from(curi) : uri).build().setParam("store" /* STORE */, store);
|
4515
|
+
if (!ret.hasParam("name" /* NAME */)) {
|
4516
|
+
const name = sthis.pathOps.basename(ret.URI().pathname);
|
4517
|
+
if (!name) {
|
4518
|
+
throw sthis.logger.Error().Url(ret).Any("ctx", ctx).Msg("Database name is required").AsError();
|
4519
|
+
}
|
4520
|
+
ret.setParam("name" /* NAME */, name);
|
4521
|
+
}
|
4522
|
+
if (ctx.idx) {
|
4523
|
+
ret.defParam("index" /* INDEX */, "idx");
|
4524
|
+
ret.defParam("storekey" /* STORE_KEY */, `@${ret.getParam("name" /* NAME */)}-${store}-idx@`);
|
4525
|
+
} else {
|
4526
|
+
ret.defParam("storekey" /* STORE_KEY */, `@${ret.getParam("name" /* NAME */)}-${store}@`);
|
4527
|
+
}
|
4528
|
+
if (store === "data") {
|
4529
|
+
if (ctx.file) {
|
4530
|
+
} else {
|
4531
|
+
ret.defParam("suffix" /* SUFFIX */, ".car");
|
4532
|
+
}
|
4533
|
+
}
|
4534
|
+
return ret.URI();
|
3726
4535
|
}
|
3727
|
-
function
|
3728
|
-
|
3729
|
-
|
3730
|
-
|
3731
|
-
|
3732
|
-
|
3733
|
-
|
3734
|
-
|
3735
|
-
|
3736
|
-
db = new Database(name, opts);
|
3737
|
-
Database.databases.set(key, db);
|
4536
|
+
function toStoreURIRuntime(sthis, name, sopts) {
|
4537
|
+
sopts = sopts || {};
|
4538
|
+
if (!sopts.base) {
|
4539
|
+
const fp_env = sthis.env.get("FP_STORAGE_URL");
|
4540
|
+
if (fp_env) {
|
4541
|
+
sopts = { ...sopts, base: import_cement20.BuildURI.from(fp_env).setParam("urlGen" /* URL_GEN */, "fromEnv") };
|
4542
|
+
} else {
|
4543
|
+
sopts = { ...sopts, base: getDefaultURI(sthis).build().setParam("urlGen" /* URL_GEN */, "default") };
|
4544
|
+
}
|
3738
4545
|
}
|
3739
|
-
|
4546
|
+
const bbase = import_cement20.BuildURI.from(sopts.base);
|
4547
|
+
if (name) {
|
4548
|
+
bbase.setParam("name" /* NAME */, name);
|
4549
|
+
}
|
4550
|
+
const base = bbase.URI();
|
4551
|
+
return {
|
4552
|
+
idx: {
|
4553
|
+
data: defaultURI2(sthis, sopts.idx?.data, base, "data", { idx: true }),
|
4554
|
+
file: defaultURI2(sthis, sopts.idx?.data, base, "data", { file: true, idx: true }),
|
4555
|
+
meta: defaultURI2(sthis, sopts.idx?.meta, base, "meta", { idx: true }),
|
4556
|
+
wal: defaultURI2(sthis, sopts.idx?.wal, base, "wal", { idx: true })
|
4557
|
+
},
|
4558
|
+
data: {
|
4559
|
+
data: defaultURI2(sthis, sopts.data?.data, base, "data"),
|
4560
|
+
file: defaultURI2(sthis, sopts.data?.data, base, "data", { file: true }),
|
4561
|
+
meta: defaultURI2(sthis, sopts.data?.meta, base, "meta"),
|
4562
|
+
wal: defaultURI2(sthis, sopts.data?.wal, base, "wal")
|
4563
|
+
}
|
4564
|
+
};
|
4565
|
+
}
|
4566
|
+
function fireproof(name, opts) {
|
4567
|
+
return DatabaseFactory(name, opts);
|
3740
4568
|
}
|
3741
4569
|
function makeName(fnString) {
|
3742
4570
|
const regex = /\(([^,()]+,\s*[^,()]+|\[[^\]]+\],\s*[^,()]+)\)/g;
|
@@ -3755,68 +4583,8 @@ function makeName(fnString) {
|
|
3755
4583
|
}
|
3756
4584
|
}
|
3757
4585
|
|
3758
|
-
// src/runtime/index.ts
|
3759
|
-
var runtime_exports = {};
|
3760
|
-
__export(runtime_exports, {
|
3761
|
-
FILESTORE_VERSION: () => FILESTORE_VERSION,
|
3762
|
-
INDEXDB_VERSION: () => INDEXDB_VERSION,
|
3763
|
-
files: () => files_exports,
|
3764
|
-
getFileName: () => getFileName,
|
3765
|
-
getPath: () => getPath,
|
3766
|
-
kb: () => key_bag_exports,
|
3767
|
-
kc: () => keyed_crypto_exports,
|
3768
|
-
mf: () => wait_pr_multiformats_exports,
|
3769
|
-
runtimeFn: () => import_cement13.runtimeFn
|
3770
|
-
});
|
3771
|
-
|
3772
|
-
// src/runtime/gateways/file/node/utils.ts
|
3773
|
-
var import_core = require("@fireproof/core");
|
3774
|
-
function getPath(url, sthis) {
|
3775
|
-
const basePath = url.pathname;
|
3776
|
-
const name = url.getParam("name");
|
3777
|
-
if (name) {
|
3778
|
-
const version = url.getParam("version");
|
3779
|
-
if (!version) throw sthis.logger.Error().Url(url).Msg(`version not found`).AsError();
|
3780
|
-
return sthis.pathOps.join(basePath, version, name);
|
3781
|
-
}
|
3782
|
-
return sthis.pathOps.join(basePath);
|
3783
|
-
}
|
3784
|
-
function getFileName(url, sthis) {
|
3785
|
-
const key = url.getParam("key");
|
3786
|
-
if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
|
3787
|
-
const res = (0, import_core.getStore)(url, sthis, (...a) => a.join("-"));
|
3788
|
-
switch (res.store) {
|
3789
|
-
case "data":
|
3790
|
-
return sthis.pathOps.join(res.name, key + ".car");
|
3791
|
-
case "wal":
|
3792
|
-
case "meta":
|
3793
|
-
return sthis.pathOps.join(res.name, key + ".json");
|
3794
|
-
default:
|
3795
|
-
throw sthis.logger.Error().Url(url).Msg(`unsupported store type`).AsError();
|
3796
|
-
}
|
3797
|
-
}
|
3798
|
-
|
3799
|
-
// src/runtime/wait-pr-multiformats/index.ts
|
3800
|
-
var wait_pr_multiformats_exports = {};
|
3801
|
-
__export(wait_pr_multiformats_exports, {
|
3802
|
-
block: () => block_exports,
|
3803
|
-
codec: () => codec_interface_exports
|
3804
|
-
});
|
3805
|
-
|
3806
|
-
// src/runtime/wait-pr-multiformats/codec-interface.ts
|
3807
|
-
var codec_interface_exports = {};
|
3808
|
-
|
3809
|
-
// src/runtime/index.ts
|
3810
|
-
var import_cement13 = require("@adviser/cement");
|
3811
|
-
|
3812
|
-
// src/runtime/gateways/file/version.ts
|
3813
|
-
var FILESTORE_VERSION = "v0.19-file";
|
3814
|
-
|
3815
|
-
// src/runtime/gateways/indexdb/version.ts
|
3816
|
-
var INDEXDB_VERSION = "v0.19-indexdb";
|
3817
|
-
|
3818
4586
|
// src/version.ts
|
3819
4587
|
var PACKAGE_VERSION = Object.keys({
|
3820
|
-
"0.
|
4588
|
+
"0.20.0-dev-preview-06": "xxxx"
|
3821
4589
|
})[0];
|
3822
4590
|
//# sourceMappingURL=index.cjs.map
|