@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.
Files changed (63) hide show
  1. package/README.md +3 -2
  2. package/deno/index.d.ts +7 -0
  3. package/deno/index.js +66 -0
  4. package/deno/index.js.map +1 -0
  5. package/deno/metafile-esm.json +1 -0
  6. package/deno.json +2 -3
  7. package/index.cjs +1819 -1051
  8. package/index.cjs.map +1 -1
  9. package/index.d.cts +746 -333
  10. package/index.d.ts +746 -333
  11. package/index.js +1792 -1026
  12. package/index.js.map +1 -1
  13. package/metafile-cjs.json +1 -1
  14. package/metafile-esm.json +1 -1
  15. package/node/index.cjs +16 -293
  16. package/node/index.cjs.map +1 -1
  17. package/node/index.d.cts +4 -40
  18. package/node/index.d.ts +4 -40
  19. package/node/index.js +22 -237
  20. package/node/index.js.map +1 -1
  21. package/node/metafile-cjs.json +1 -1
  22. package/node/metafile-esm.json +1 -1
  23. package/package.json +12 -4
  24. package/react/index.cjs.map +1 -1
  25. package/react/index.js.map +1 -1
  26. package/react/metafile-cjs.json +1 -1
  27. package/react/metafile-esm.json +1 -1
  28. package/tests/blockstore/fp-envelope.test.ts-off +65 -0
  29. package/tests/blockstore/interceptor-gateway.test.ts +122 -0
  30. package/tests/blockstore/keyed-crypto-indexdb-file.test.ts +130 -0
  31. package/tests/blockstore/keyed-crypto.test.ts +73 -118
  32. package/tests/blockstore/loader.test.ts +18 -9
  33. package/tests/blockstore/store.test.ts +40 -31
  34. package/tests/blockstore/transaction.test.ts +14 -13
  35. package/tests/fireproof/all-gateway.test.ts +283 -213
  36. package/tests/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.ts +324 -316
  37. package/tests/fireproof/crdt.test.ts +78 -19
  38. package/tests/fireproof/database.test.ts +225 -29
  39. package/tests/fireproof/fireproof.test.ts +92 -73
  40. package/tests/fireproof/hello.test.ts +17 -13
  41. package/tests/fireproof/indexer.test.ts +67 -43
  42. package/tests/fireproof/utils.test.ts +47 -6
  43. package/tests/gateway/file/loader-config.test.ts +307 -0
  44. package/tests/gateway/fp-envelope-serialize.test.ts +256 -0
  45. package/tests/gateway/indexdb/loader-config.test.ts +79 -0
  46. package/tests/helpers.ts +44 -17
  47. package/tests/react/useFireproof.test.tsx +1 -1
  48. package/tests/www/todo.html +24 -3
  49. package/web/index.cjs +102 -116
  50. package/web/index.cjs.map +1 -1
  51. package/web/index.d.cts +15 -29
  52. package/web/index.d.ts +15 -29
  53. package/web/index.js +91 -105
  54. package/web/index.js.map +1 -1
  55. package/web/metafile-cjs.json +1 -1
  56. package/web/metafile-esm.json +1 -1
  57. package/node/chunk-4A4RAVNS.js +0 -17
  58. package/node/chunk-4A4RAVNS.js.map +0 -1
  59. package/node/mem-filesystem-LPPT7QV5.js +0 -40
  60. package/node/mem-filesystem-LPPT7QV5.js.map +0 -1
  61. package/tests/fireproof/config.test.ts +0 -163
  62. /package/tests/blockstore/{fragment-gateway.test.ts → fragment-gateway.test.ts-off} +0 -0
  63. /package/tests/fireproof/{multiple-ledger.test.ts → multiple-database.test.ts} +0 -0
package/index.js CHANGED
@@ -5,238 +5,45 @@ var __export = (target, all) => {
5
5
  };
6
6
 
7
7
  // src/database.ts
8
- import { ResolveOnce as ResolveOnce7 } from "@adviser/cement";
8
+ import { BuildURI as BuildURI2, KeyedResolvOnce as KeyedResolvOnce4, ResolveOnce as ResolveOnce7, URI as URI12 } from "@adviser/cement";
9
9
 
10
- // src/write-queue.ts
11
- function writeQueue(worker, payload = Infinity, unbounded = false) {
12
- const queue = [];
13
- let isProcessing = false;
14
- async function process() {
15
- if (isProcessing || queue.length === 0) return;
16
- isProcessing = true;
17
- const tasksToProcess = queue.splice(0, payload);
18
- const updates = tasksToProcess.map((item) => item.task);
19
- if (unbounded) {
20
- const promises = updates.map(async (update, index2) => {
21
- try {
22
- const result = await worker([update]);
23
- tasksToProcess[index2].resolve(result);
24
- } catch (error) {
25
- tasksToProcess[index2].reject(error);
26
- }
27
- });
28
- await Promise.all(promises);
29
- } else {
30
- try {
31
- const result = await worker(updates);
32
- tasksToProcess.forEach((task) => task.resolve(result));
33
- } catch (error) {
34
- tasksToProcess.forEach((task) => task.reject(error));
35
- }
36
- }
37
- isProcessing = false;
38
- void process();
39
- }
40
- return {
41
- push(task) {
42
- return new Promise((resolve, reject) => {
43
- queue.push({ task, resolve, reject });
44
- void process();
45
- });
46
- }
47
- };
48
- }
49
-
50
- // src/crdt.ts
51
- import { ResolveOnce as ResolveOnce6 } from "@adviser/cement";
52
-
53
- // src/runtime/wait-pr-multiformats/block.ts
54
- var block_exports = {};
55
- __export(block_exports, {
56
- Block: () => Block,
57
- create: () => create,
58
- createUnsafe: () => createUnsafe,
59
- decode: () => decode,
60
- encode: () => encode
61
- });
62
- import { bytes as binary, CID } from "multiformats";
63
- import { Block as mfBlock } from "multiformats/block";
64
- var Block = mfBlock;
65
- async function decode({
66
- bytes,
67
- codec: codec3,
68
- hasher: hasher7
69
- }) {
70
- if (bytes == null) throw new Error('Missing required argument "bytes"');
71
- if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
72
- const value = await Promise.resolve(codec3.decode(bytes));
73
- const hash = await hasher7.digest(bytes);
74
- const cid = CID.create(1, codec3.code, hash);
75
- return new mfBlock({ value, bytes, cid });
76
- }
77
- async function encode({
78
- value,
79
- codec: codec3,
80
- hasher: hasher7
81
- }) {
82
- if (typeof value === "undefined") throw new Error('Missing required argument "value"');
83
- if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
84
- const bytes = await Promise.resolve(codec3.encode(value));
85
- const hash = await hasher7.digest(bytes);
86
- const cid = CID.create(1, codec3.code, hash);
87
- return new mfBlock({ value, bytes, cid });
88
- }
89
- async function create({
90
- bytes,
91
- cid,
92
- hasher: hasher7,
93
- codec: codec3
94
- }) {
95
- if (bytes == null) throw new Error('Missing required argument "bytes"');
96
- if (hasher7 == null) throw new Error('Missing required argument "hasher"');
97
- const value = await Promise.resolve(codec3.decode(bytes));
98
- const hash = await hasher7.digest(bytes);
99
- if (!binary.equals(cid.multihash.bytes, hash.bytes)) {
100
- throw new Error("CID hash does not match bytes");
101
- }
102
- return createUnsafe({
103
- bytes,
104
- cid,
105
- value,
106
- codec: codec3
107
- });
108
- }
109
- async function createUnsafe({
110
- bytes,
111
- cid,
112
- value: maybeValue,
113
- codec: codec3
114
- }) {
115
- const value = await Promise.resolve(maybeValue !== void 0 ? maybeValue : codec3?.decode(bytes));
116
- if (value === void 0) throw new Error('Missing required argument, must either provide "value" or "codec"');
117
- return new Block({
118
- cid,
119
- bytes,
120
- value
121
- });
122
- }
123
-
124
- // src/crdt-helpers.ts
125
- import { parse as parse3 } from "multiformats/link";
126
- import { sha256 as hasher5 } from "multiformats/hashes/sha2";
127
- import * as codec from "@fireproof/vendor/@ipld/dag-cbor";
128
- import { put, get, entries, root } from "@fireproof/vendor/@web3-storage/pail/crdt";
129
- import { EventFetcher, vis } from "@fireproof/vendor/@web3-storage/pail/clock";
130
- import * as Batch from "@fireproof/vendor/@web3-storage/pail/crdt/batch";
131
-
132
- // src/blockstore/index.ts
133
- var blockstore_exports = {};
134
- __export(blockstore_exports, {
135
- BaseBlockstore: () => BaseBlockstore,
136
- CarTransaction: () => CarTransaction,
137
- CompactionFetcher: () => CompactionFetcher,
138
- ConnectionBase: () => ConnectionBase,
139
- EncryptedBlockstore: () => EncryptedBlockstore,
140
- FragmentGateway: () => FragmentGateway,
141
- Loader: () => Loader,
142
- addCryptoKeyToGatewayMetaPayload: () => addCryptoKeyToGatewayMetaPayload,
143
- ensureStart: () => ensureStart,
144
- getGatewayFromURL: () => getGatewayFromURL,
145
- parseCarFile: () => parseCarFile,
146
- registerStoreProtocol: () => registerStoreProtocol,
147
- setCryptoKeyFromGatewayMetaPayload: () => setCryptoKeyFromGatewayMetaPayload,
148
- testStoreFactory: () => testStoreFactory,
149
- toCIDBlock: () => toCIDBlock,
150
- toStoreRuntime: () => toStoreRuntime
151
- });
152
-
153
- // src/blockstore/types.ts
154
- function toCIDBlock(block) {
155
- return block;
156
- }
157
-
158
- // src/blockstore/store-factory.ts
159
- import { KeyedResolvOnce as KeyedResolvOnce2, URI as URI6, runtimeFn as runtimeFn3 } from "@adviser/cement";
160
-
161
- // src/runtime/files.ts
162
- var files_exports = {};
163
- __export(files_exports, {
164
- decodeFile: () => decodeFile,
165
- encodeFile: () => encodeFile
166
- });
167
- import * as UnixFS from "@ipld/unixfs";
168
- import * as raw from "multiformats/codecs/raw";
169
- import { withMaxChunkSize } from "@ipld/unixfs/file/chunker/fixed";
170
- import { withWidth } from "@ipld/unixfs/file/layout/balanced";
171
- import { exporter } from "@fireproof/vendor/ipfs-unixfs-exporter";
172
- var queuingStrategy = UnixFS.withCapacity();
173
- var settings = UnixFS.configure({
174
- fileChunkEncoder: raw,
175
- smallFileEncoder: raw,
176
- chunker: withMaxChunkSize(1024 * 1024),
177
- fileLayout: withWidth(1024)
178
- });
179
- async function collect(collectable) {
180
- const chunks = [];
181
- await collectable.pipeTo(
182
- new WritableStream({
183
- write(chunk) {
184
- chunks.push(chunk);
185
- }
186
- })
187
- );
188
- return chunks;
189
- }
190
- async function encodeFile(blob) {
191
- const readable = createFileEncoderStream(blob);
192
- const blocks = await collect(readable);
193
- return { cid: blocks.at(-1).cid, blocks };
194
- }
195
- async function decodeFile(blocks, cid, meta) {
196
- const entry = await exporter(cid.toString(), blocks, { length: meta.size });
197
- const chunks = [];
198
- for await (const chunk of entry.content()) {
199
- chunks.push(chunk);
200
- }
201
- return new File(chunks, entry.name, { type: meta.type, lastModified: 0 });
202
- }
203
- function createFileEncoderStream(blob) {
204
- const { readable, writable } = new TransformStream({}, queuingStrategy);
205
- const unixfsWriter = UnixFS.createWriter({ writable, settings });
206
- const fileBuilder = new UnixFSFileBuilder("", blob);
207
- void (async () => {
208
- await fileBuilder.finalize(unixfsWriter);
209
- await unixfsWriter.close();
210
- })();
211
- return readable;
212
- }
213
- var UnixFSFileBuilder = class {
214
- #file;
215
- constructor(name, file) {
216
- this.name = name;
217
- this.#file = file;
218
- }
219
- async finalize(writer) {
220
- const unixfsFileWriter = UnixFS.createFileWriter(writer);
221
- await this.#file.stream().pipeTo(
222
- new WritableStream({
223
- async write(chunk) {
224
- await unixfsFileWriter.write(chunk);
225
- }
226
- })
227
- );
228
- return await unixfsFileWriter.close();
229
- }
230
- };
231
-
232
- // src/blockstore/store.ts
233
- import { format as format2, parse as parse2 } from "@fireproof/vendor/@ipld/dag-json";
234
- import { exception2Result, ResolveOnce as ResolveOnce4, Result as Result5 } from "@adviser/cement";
10
+ // src/utils.ts
11
+ import {
12
+ LoggerImpl,
13
+ IsLogger,
14
+ Result,
15
+ ResolveOnce,
16
+ isURL,
17
+ envFactory,
18
+ toCryptoRuntime,
19
+ JSONFormatter,
20
+ YAMLFormatter
21
+ } from "@adviser/cement";
235
22
 
236
23
  // src/types.ts
237
24
  function isFalsy(value) {
238
25
  return value === false && value === null && value === void 0;
239
26
  }
27
+ var PARAM = /* @__PURE__ */ ((PARAM2) => {
28
+ PARAM2["SUFFIX"] = "suffix";
29
+ PARAM2["URL_GEN"] = "urlGen";
30
+ PARAM2["STORE_KEY"] = "storekey";
31
+ PARAM2["STORE"] = "store";
32
+ PARAM2["KEY"] = "key";
33
+ PARAM2["INDEX"] = "index";
34
+ PARAM2["NAME"] = "name";
35
+ PARAM2["VERSION"] = "version";
36
+ PARAM2["RUNTIME"] = "runtime";
37
+ PARAM2["FRAG_SIZE"] = "fragSize";
38
+ PARAM2["IV_VERIFY"] = "ivVerify";
39
+ PARAM2["IV_HASH"] = "ivHash";
40
+ PARAM2["FRAG_FID"] = "fid";
41
+ PARAM2["FRAG_OFS"] = "ofs";
42
+ PARAM2["FRAG_LEN"] = "len";
43
+ PARAM2["FRAG_HEAD"] = "headerSize";
44
+ PARAM2["EXTRACTKEY"] = "extractKey";
45
+ return PARAM2;
46
+ })(PARAM || {});
240
47
  function throwFalsy(value) {
241
48
  if (isFalsy(value)) {
242
49
  throw new Error("value is Falsy");
@@ -251,19 +58,6 @@ function falsyToUndef(value) {
251
58
  }
252
59
 
253
60
  // src/utils.ts
254
- import {
255
- LoggerImpl,
256
- IsLogger,
257
- Result,
258
- ResolveOnce,
259
- isURL,
260
- URI,
261
- runtimeFn,
262
- envFactory,
263
- toCryptoRuntime,
264
- JSONFormatter,
265
- YAMLFormatter
266
- } from "@adviser/cement";
267
61
  import { base58btc } from "multiformats/bases/base58";
268
62
  var _globalLogger = new ResolveOnce();
269
63
  function globalLogger() {
@@ -331,17 +125,19 @@ var pathOpsImpl = class {
331
125
  dirname(path) {
332
126
  return path.split("/").slice(0, -1).join("/");
333
127
  }
128
+ basename(path) {
129
+ return path.split("/").pop() || "";
130
+ }
334
131
  // homedir() {
335
132
  // throw new Error("SysContainer:homedir is not available in seeded state");
336
133
  // }
337
134
  };
338
135
  var pathOps = new pathOpsImpl();
339
- var txtOps = {
340
- // eslint-disable-next-line no-restricted-globals
341
- encode: (input) => new TextEncoder().encode(input),
136
+ var txtOps = /* @__PURE__ */ ((txtEncoder, txtDecoder) => ({
137
+ encode: (input) => txtEncoder.encode(input),
138
+ decode: (input) => txtDecoder.decode(coerceIntoUint8(input).Ok())
342
139
  // eslint-disable-next-line no-restricted-globals
343
- decode: (input) => new TextDecoder().decode(input)
344
- };
140
+ }))(new TextEncoder(), new TextDecoder());
345
141
  var _onSuperThis = /* @__PURE__ */ new Map();
346
142
  function onSuperThis(fn) {
347
143
  const key = `onSuperThis-${Math.random().toString(36).slice(2)}`;
@@ -373,9 +169,7 @@ function ensureSuperLog(sthis, componentName, ctx) {
373
169
  }
374
170
  function ensureLogger(sthis, componentName, ctx) {
375
171
  let logger;
376
- if (IsLogger(sthis)) {
377
- logger = sthis;
378
- } else if (sthis && IsLogger(sthis.logger)) {
172
+ if (sthis && IsLogger(sthis.logger)) {
379
173
  logger = sthis.logger;
380
174
  } else {
381
175
  logger = globalLogger();
@@ -396,6 +190,10 @@ function ensureLogger(sthis, componentName, ctx) {
396
190
  exposeStack = true;
397
191
  delete ctx.exposeStack;
398
192
  }
193
+ if ("exposeStack" in ctx) {
194
+ exposeStack = true;
195
+ delete ctx.exposeStack;
196
+ }
399
197
  if ("this" in ctx) {
400
198
  cLogger.Str("this", sthis.nextId(4).str);
401
199
  delete ctx.this;
@@ -462,10 +260,13 @@ function ensureLogger(sthis, componentName, ctx) {
462
260
  logger.SetExposeStack(true);
463
261
  }
464
262
  const out = cLogger.Logger();
263
+ if (sthis.env.get("FP_CONSTRUCTOR_DEBUG")) {
264
+ out.Debug().Msg("constructor");
265
+ }
465
266
  return out;
466
267
  }
467
268
  function getStore(url, sthis, joiner) {
468
- const store = url.getParam("store");
269
+ const store = url.getParam("store" /* STORE */);
469
270
  switch (store) {
470
271
  case "data":
471
272
  case "wal":
@@ -473,20 +274,21 @@ function getStore(url, sthis, joiner) {
473
274
  break;
474
275
  default:
475
276
  throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
277
+ throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
476
278
  }
477
279
  let name = store;
478
280
  if (url.hasParam("index")) {
479
- name = joiner(url.getParam("index") || "idx", name);
281
+ name = joiner(url.getParam("index" /* INDEX */) || "idx", name);
480
282
  }
481
283
  return { store, name };
482
284
  }
483
285
  function getKey(url, logger) {
484
- const result = url.getParam("key");
286
+ const result = url.getParam("key" /* KEY */);
485
287
  if (!result) throw logger.Error().Str("url", url.toString()).Msg(`key not found`).AsError();
486
288
  return result;
487
289
  }
488
290
  function getName(sthis, url) {
489
- let result = url.getParam("name");
291
+ let result = url.getParam("name" /* NAME */);
490
292
  if (!result) {
491
293
  result = sthis.pathOps.dirname(url.pathname);
492
294
  if (result.length === 0) {
@@ -495,51 +297,338 @@ function getName(sthis, url) {
495
297
  }
496
298
  return result;
497
299
  }
498
- async function exceptionWrapper(fn) {
499
- return fn().catch((e) => Result.Err(e));
300
+ async function exceptionWrapper(fn) {
301
+ return fn().catch((e) => Result.Err(e));
302
+ }
303
+ var NotFoundError = class extends Error {
304
+ constructor() {
305
+ super(...arguments);
306
+ this.code = "ENOENT";
307
+ }
308
+ };
309
+ function isNotFoundError(e) {
310
+ if (Result.Is(e)) {
311
+ if (e.isOk()) return false;
312
+ e = e.Err();
313
+ }
314
+ if (e.code === "ENOENT") return true;
315
+ return false;
316
+ }
317
+ function UInt8ArrayEqual(a, b) {
318
+ if (a.length !== b.length) {
319
+ return false;
320
+ }
321
+ for (let i = 0; i < a.length; i++) {
322
+ if (a[i] !== b[i]) {
323
+ return false;
324
+ }
325
+ }
326
+ return true;
327
+ }
328
+ function inplaceFilter(i, pred) {
329
+ const founds = [];
330
+ for (let j = 0; j < i.length; j++) {
331
+ if (!pred(i[j], j)) {
332
+ founds.push(j);
333
+ }
334
+ }
335
+ for (let j = founds.length - 1; j >= 0; j--) {
336
+ i.splice(founds[j], 1);
337
+ }
338
+ return i;
339
+ }
340
+ function toSortedArray(set) {
341
+ if (!set) return [];
342
+ return Object.entries(set).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => ({ [k]: v }));
343
+ }
344
+ function coerceIntoUint8(raw2) {
345
+ if (raw2 instanceof Uint8Array) {
346
+ return Result.Ok(raw2);
347
+ }
348
+ if (Result.Is(raw2)) {
349
+ return raw2;
350
+ }
351
+ return Result.Err("Not a Uint8Array");
352
+ }
353
+ async function coercePromiseIntoUint8(raw2) {
354
+ if (raw2 instanceof Uint8Array) {
355
+ return Result.Ok(raw2);
356
+ }
357
+ if (Result.Is(raw2)) {
358
+ return raw2;
359
+ }
360
+ if (typeof raw2.then === "function") {
361
+ try {
362
+ return coercePromiseIntoUint8(await raw2);
363
+ } catch (e) {
364
+ return Result.Err(e);
365
+ }
366
+ }
367
+ return Result.Err("Not a Uint8Array");
368
+ }
369
+
370
+ // src/write-queue.ts
371
+ import { Future } from "@adviser/cement";
372
+ function defaultWriteQueueOpts(opts = {}) {
373
+ return {
374
+ ...opts,
375
+ chunkSize: opts.chunkSize && opts.chunkSize > 0 ? opts.chunkSize : 32
376
+ };
377
+ }
378
+ var WriteQueueImpl = class {
379
+ constructor(sthis, worker, opts) {
380
+ this.queue = [];
381
+ this.isProcessing = false;
382
+ this.logger = ensureLogger(sthis, "WriteQueueImpl");
383
+ this.worker = worker;
384
+ this.opts = defaultWriteQueueOpts(opts);
385
+ }
386
+ testEmptyQueue() {
387
+ if (this.waitForEmptyQueue && this.queue.length === 0) {
388
+ this.waitForEmptyQueue.resolve();
389
+ }
390
+ }
391
+ async process() {
392
+ if (this.isProcessing || this.queue.length === 0) {
393
+ this.testEmptyQueue();
394
+ return;
395
+ }
396
+ this.isProcessing = true;
397
+ try {
398
+ this.logger.Debug().Any("opts", this.opts).Len(this.queue).Msg("Processing tasks");
399
+ const tasksToProcess = this.queue.splice(0, this.opts.chunkSize);
400
+ const updates = tasksToProcess.map((item) => item.tasks).filter((item) => item);
401
+ const promises = updates.map(async (update, index2) => {
402
+ try {
403
+ const result = await this.worker(update);
404
+ tasksToProcess[index2].resolve(result);
405
+ } catch (error) {
406
+ tasksToProcess[index2].reject(this.logger.Error().Err(error).Msg("Error processing task").AsError());
407
+ }
408
+ });
409
+ await Promise.allSettled(promises);
410
+ this.logger.Debug().Any("opts", this.opts).Len(this.queue).Msg("Processed tasks");
411
+ } catch (error) {
412
+ this.logger.Error().Err(error).Msg("Error processing tasks");
413
+ } finally {
414
+ this.isProcessing = false;
415
+ setTimeout(() => this.process(), 0);
416
+ }
417
+ }
418
+ bulk(tasks) {
419
+ return new Promise((resolve, reject) => {
420
+ this.queue.push({ tasks, resolve, reject });
421
+ this.process();
422
+ });
423
+ }
424
+ push(task) {
425
+ return this.bulk([task]);
426
+ }
427
+ close() {
428
+ this.waitForEmptyQueue = new Future();
429
+ this.testEmptyQueue();
430
+ return this.waitForEmptyQueue.asPromise();
431
+ }
432
+ };
433
+ function writeQueue(sthis, worker, opts) {
434
+ return new WriteQueueImpl(sthis, worker, opts);
435
+ }
436
+
437
+ // src/crdt.ts
438
+ import { ResolveOnce as ResolveOnce6 } from "@adviser/cement";
439
+
440
+ // src/blockstore/index.ts
441
+ var blockstore_exports = {};
442
+ __export(blockstore_exports, {
443
+ BaseBlockstore: () => BaseBlockstore,
444
+ Car2FPMsg: () => Car2FPMsg,
445
+ CarTransaction: () => CarTransaction,
446
+ CompactionFetcher: () => CompactionFetcher,
447
+ ConnectionBase: () => ConnectionBase,
448
+ DbMetaEventEqual: () => DbMetaEventEqual,
449
+ DbMetaEventsEqual: () => DbMetaEventsEqual,
450
+ EncryptedBlockstore: () => EncryptedBlockstore,
451
+ FPEnvelopeType: () => FPEnvelopeType,
452
+ File2FPMsg: () => File2FPMsg,
453
+ InterceptorGateway: () => InterceptorGateway,
454
+ Loader: () => Loader,
455
+ PassThroughGateway: () => PassThroughGateway,
456
+ createDbMetaEvent: () => createDbMetaEvent,
457
+ defaultGatewayFactoryItem: () => defaultGatewayFactoryItem,
458
+ ensureStoreEnDeFile: () => ensureStoreEnDeFile,
459
+ getDefaultURI: () => getDefaultURI,
460
+ getGatewayFactoryItem: () => getGatewayFactoryItem,
461
+ getStartedGateway: () => getStartedGateway,
462
+ parseCarFile: () => parseCarFile,
463
+ registerStoreProtocol: () => registerStoreProtocol,
464
+ toCIDBlock: () => toCIDBlock,
465
+ toStoreRuntime: () => toStoreRuntime
466
+ });
467
+
468
+ // src/blockstore/types.ts
469
+ function toCIDBlock(block) {
470
+ return block;
471
+ }
472
+ function DbMetaEventEqual(a, b) {
473
+ 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]));
474
+ }
475
+ function DbMetaEventsEqual(a, b) {
476
+ return a.length === b.length && a.every((e, i) => DbMetaEventEqual(e, b[i]));
477
+ }
478
+
479
+ // src/blockstore/store-factory.ts
480
+ import { KeyedResolvOnce as KeyedResolvOnce3, Result as Result10 } from "@adviser/cement";
481
+
482
+ // src/runtime/files.ts
483
+ var files_exports = {};
484
+ __export(files_exports, {
485
+ decodeFile: () => decodeFile,
486
+ encodeFile: () => encodeFile
487
+ });
488
+ import * as UnixFS from "@ipld/unixfs";
489
+ import * as raw from "multiformats/codecs/raw";
490
+ import { withMaxChunkSize } from "@ipld/unixfs/file/chunker/fixed";
491
+ import { withWidth } from "@ipld/unixfs/file/layout/balanced";
492
+ import { exporter } from "@fireproof/vendor/ipfs-unixfs-exporter";
493
+ var queuingStrategy = UnixFS.withCapacity();
494
+ var settings = UnixFS.configure({
495
+ fileChunkEncoder: raw,
496
+ smallFileEncoder: raw,
497
+ chunker: withMaxChunkSize(1024 * 1024),
498
+ fileLayout: withWidth(1024)
499
+ });
500
+ async function collect(collectable) {
501
+ const chunks = [];
502
+ await collectable.pipeTo(
503
+ new WritableStream({
504
+ write(chunk) {
505
+ chunks.push(chunk);
506
+ }
507
+ })
508
+ );
509
+ return chunks;
510
+ }
511
+ async function encodeFile(blob) {
512
+ const readable = createFileEncoderStream(blob);
513
+ const blocks = await collect(readable);
514
+ return { cid: blocks.at(-1).cid, blocks };
500
515
  }
501
- var NotFoundError = class extends Error {
502
- constructor() {
503
- super(...arguments);
504
- this.code = "ENOENT";
505
- }
506
- };
507
- function isNotFoundError(e) {
508
- if (Result.Is(e)) {
509
- if (e.isOk()) return false;
510
- e = e.Err();
516
+ async function decodeFile(blocks, cid, meta) {
517
+ const entry = await exporter(cid.toString(), blocks, { length: meta.size });
518
+ const chunks = [];
519
+ for await (const chunk of entry.content()) {
520
+ chunks.push(chunk);
511
521
  }
512
- if (e.code === "ENOENT") return true;
513
- return false;
522
+ return new File(chunks, entry.name, { type: meta.type, lastModified: 0 });
514
523
  }
515
- function dataDir(sthis, name, base) {
516
- if (!base) {
517
- if (!runtimeFn().isBrowser) {
518
- const home = sthis.env.get("HOME") || "./";
519
- base = sthis.env.get("FP_STORAGE_URL") || `file://${sthis.pathOps.join(home, ".fireproof")}`;
520
- } else {
521
- base = sthis.env.get("FP_STORAGE_URL") || `indexdb://fp`;
522
- }
523
- }
524
- return URI.from(base.toString()).build().setParam("name", name || "").URI();
524
+ function createFileEncoderStream(blob) {
525
+ const { readable, writable } = new TransformStream({}, queuingStrategy);
526
+ const unixfsWriter = UnixFS.createWriter({ writable, settings });
527
+ const fileBuilder = new UnixFSFileBuilder("", blob);
528
+ void (async () => {
529
+ await fileBuilder.finalize(unixfsWriter);
530
+ await unixfsWriter.close();
531
+ })();
532
+ return readable;
525
533
  }
526
- function UInt8ArrayEqual(a, b) {
527
- if (a.length !== b.length) {
528
- return false;
534
+ var UnixFSFileBuilder = class {
535
+ #file;
536
+ constructor(name, file) {
537
+ this.name = name;
538
+ this.#file = file;
529
539
  }
530
- for (let i = 0; i < a.length; i++) {
531
- if (a[i] !== b[i]) {
532
- return false;
533
- }
540
+ async finalize(writer) {
541
+ const unixfsFileWriter = UnixFS.createFileWriter(writer);
542
+ await this.#file.stream().pipeTo(
543
+ new WritableStream({
544
+ async write(chunk) {
545
+ await unixfsFileWriter.write(chunk);
546
+ }
547
+ })
548
+ );
549
+ return await unixfsFileWriter.close();
534
550
  }
535
- return true;
536
- }
551
+ };
552
+
553
+ // src/blockstore/store.ts
554
+ import { exception2Result, ResolveOnce as ResolveOnce4, Result as Result5 } from "@adviser/cement";
537
555
 
538
556
  // src/blockstore/loader.ts
539
557
  import pLimit from "p-limit";
540
558
  import { CarReader } from "@fireproof/vendor/@ipld/car/reader";
541
559
  import { ResolveOnce as ResolveOnce3 } from "@adviser/cement";
542
560
 
561
+ // src/runtime/wait-pr-multiformats/block.ts
562
+ var block_exports = {};
563
+ __export(block_exports, {
564
+ Block: () => Block,
565
+ create: () => create,
566
+ createUnsafe: () => createUnsafe,
567
+ decode: () => decode,
568
+ encode: () => encode
569
+ });
570
+ import { bytes as binary, CID } from "multiformats";
571
+ import { Block as mfBlock } from "multiformats/block";
572
+ var Block = mfBlock;
573
+ async function decode({
574
+ bytes,
575
+ codec: codec3,
576
+ hasher: hasher7
577
+ }) {
578
+ if (bytes == null) throw new Error('Missing required argument "bytes"');
579
+ if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
580
+ const value = await Promise.resolve(codec3.decode(bytes));
581
+ const hash = await hasher7.digest(bytes);
582
+ const cid = CID.create(1, codec3.code, hash);
583
+ return new mfBlock({ value, bytes, cid });
584
+ }
585
+ async function encode({
586
+ value,
587
+ codec: codec3,
588
+ hasher: hasher7
589
+ }) {
590
+ if (typeof value === "undefined") throw new Error('Missing required argument "value"');
591
+ if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
592
+ const bytes = await Promise.resolve(codec3.encode(value));
593
+ const hash = await hasher7.digest(bytes);
594
+ const cid = CID.create(1, codec3.code, hash);
595
+ return new mfBlock({ value, bytes, cid });
596
+ }
597
+ async function create({
598
+ bytes,
599
+ cid,
600
+ hasher: hasher7,
601
+ codec: codec3
602
+ }) {
603
+ if (bytes == null) throw new Error('Missing required argument "bytes"');
604
+ if (hasher7 == null) throw new Error('Missing required argument "hasher"');
605
+ const value = await Promise.resolve(codec3.decode(bytes));
606
+ const hash = await hasher7.digest(bytes);
607
+ if (!binary.equals(cid.multihash.bytes, hash.bytes)) {
608
+ throw new Error("CID hash does not match bytes");
609
+ }
610
+ return createUnsafe({
611
+ bytes,
612
+ cid,
613
+ value,
614
+ codec: codec3
615
+ });
616
+ }
617
+ async function createUnsafe({
618
+ bytes,
619
+ cid,
620
+ value: maybeValue,
621
+ codec: codec3
622
+ }) {
623
+ const value = await Promise.resolve(maybeValue !== void 0 ? maybeValue : codec3?.decode(bytes));
624
+ if (value === void 0) throw new Error('Missing required argument, must either provide "value" or "codec"');
625
+ return new Block({
626
+ cid,
627
+ bytes,
628
+ value
629
+ });
630
+ }
631
+
543
632
  // src/blockstore/loader-helpers.ts
544
633
  import { sha256 as hasher } from "multiformats/hashes/sha2";
545
634
  import * as dagCodec from "@fireproof/vendor/@ipld/dag-cbor";
@@ -575,7 +664,6 @@ var CarTransaction = class extends MemoryBlockstore {
575
664
  };
576
665
  function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
577
666
  const logger = ensureLogger(sthis, component, ctx);
578
- const store = opts.store || {};
579
667
  return {
580
668
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
581
669
  applyMeta: (meta, snap) => {
@@ -587,30 +675,27 @@ function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
587
675
  },
588
676
  autoCompact: 100,
589
677
  public: false,
590
- name: void 0,
678
+ // name: undefined,
591
679
  threshold: 1e3 * 1e3,
592
680
  ...opts,
593
681
  logger,
594
682
  keyBag: opts.keyBag || {},
595
683
  crypto: toCryptoRuntime2(opts.crypto),
596
- store,
597
- storeRuntime: toStoreRuntime(store, sthis)
684
+ storeUrls: opts.storeUrls,
685
+ // storeEnDeFile: ensureStoreEnDeFile(opts.storeEnDeFile),
686
+ // store,
687
+ storeRuntime: toStoreRuntime(sthis, ensureStoreEnDeFile(opts.storeEnDeFile))
598
688
  };
599
689
  }
600
- function blockstoreFactory(sthis, opts) {
601
- if (opts.name) {
602
- return new EncryptedBlockstore(sthis, opts);
603
- } else {
604
- return new BaseBlockstore(opts);
605
- }
606
- }
607
690
  var BaseBlockstore = class {
608
- constructor(ebOpts = {}) {
691
+ constructor(ebOpts) {
609
692
  this.transactions = /* @__PURE__ */ new Set();
610
693
  this.sthis = ensureSuperThis(ebOpts);
611
694
  this.ebOpts = defaultedBlockstoreRuntime(this.sthis, ebOpts, "BaseBlockstore");
612
695
  this.logger = this.ebOpts.logger;
696
+ this.loader = new Loader(this.sthis, ebOpts);
613
697
  }
698
+ // readonly name?: string;
614
699
  // ready: Promise<void>;
615
700
  ready() {
616
701
  return Promise.resolve();
@@ -634,8 +719,11 @@ var BaseBlockstore = class {
634
719
  }
635
720
  // TransactionMeta
636
721
  async transaction(fn, _opts) {
722
+ this.logger.Debug().Msg("enter transaction");
637
723
  const t = new CarTransaction(this, _opts);
724
+ this.logger.Debug().Msg("post CarTransaction");
638
725
  const done = await fn(t);
726
+ this.logger.Debug().Msg("post fn");
639
727
  this.lastTxMeta = done;
640
728
  return { t, meta: done };
641
729
  }
@@ -644,7 +732,7 @@ var BaseBlockstore = class {
644
732
  }
645
733
  async commitTransaction(t, done, opts) {
646
734
  if (!this.loader) throw this.logger.Error().Msg("loader required to commit").AsError();
647
- const cars = await this.loader?.commit(t, done, opts);
735
+ const cars = await this.loader.commit(t, done, opts);
648
736
  if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
649
737
  setTimeout(() => void this.compact(), 10);
650
738
  }
@@ -669,14 +757,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
669
757
  constructor(sthis, ebOpts) {
670
758
  super(ebOpts);
671
759
  this.compacting = false;
672
- this.logger = ensureLogger(this.sthis, "EncryptedBlockstore");
673
- const { name } = ebOpts;
674
- if (!name) {
675
- throw this.logger.Error().Msg("name required").AsError();
676
- }
677
- this.name = name;
678
- this.loader = new Loader(this.name, ebOpts, sthis);
760
+ this.logger = ensureLogger(this.sthis, "EncryptedBlockstore", {
761
+ this: 1
762
+ });
679
763
  }
764
+ // readonly name: string;
680
765
  ready() {
681
766
  return this.loader.ready();
682
767
  }
@@ -695,8 +780,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
695
780
  return falsyToUndef(await this.loader.getBlock(cid));
696
781
  }
697
782
  async transaction(fn, opts = { noLoader: false }) {
783
+ this.logger.Debug().Msg("enter transaction");
698
784
  const { t, meta: done } = await super.transaction(fn);
785
+ this.logger.Debug().Msg("post super.transaction");
699
786
  const cars = await this.loader.commit(t, done, opts);
787
+ this.logger.Debug().Msg("post this.loader.commit");
700
788
  if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
701
789
  setTimeout(() => void this.compact(), 10);
702
790
  }
@@ -726,7 +814,7 @@ var EncryptedBlockstore = class extends BaseBlockstore {
726
814
  const blockLog = new CompactionFetcher(this);
727
815
  this.compacting = true;
728
816
  const meta = await compactFn(blockLog);
729
- await this.loader?.commit(blockLog.loggedBlocks, meta, {
817
+ await this.loader.commit(blockLog.loggedBlocks, meta, {
730
818
  compact: true,
731
819
  noLoader: true
732
820
  });
@@ -768,7 +856,7 @@ var CompactionFetcher = class {
768
856
  };
769
857
 
770
858
  // src/blockstore/commit-queue.ts
771
- import { Future } from "@adviser/cement";
859
+ import { Future as Future2 } from "@adviser/cement";
772
860
  var CommitQueue = class {
773
861
  constructor() {
774
862
  this.queue = [];
@@ -779,7 +867,7 @@ var CommitQueue = class {
779
867
  if (this.queue.length === 0 && !this.processing) {
780
868
  return Promise.resolve();
781
869
  }
782
- const fn = new Future();
870
+ const fn = new Future2();
783
871
  this._waitIdleItems.add(fn);
784
872
  return fn.asPromise();
785
873
  }
@@ -822,6 +910,7 @@ var CommitQueue = class {
822
910
  var key_bag_exports = {};
823
911
  __export(key_bag_exports, {
824
912
  KeyBag: () => KeyBag,
913
+ defaultKeyBagOpts: () => defaultKeyBagOpts,
825
914
  defaultKeyBagUrl: () => defaultKeyBagUrl,
826
915
  getKeyBag: () => getKeyBag,
827
916
  registerKeyBagProviderFactory: () => registerKeyBagProviderFactory
@@ -833,19 +922,99 @@ import {
833
922
  Result as Result2,
834
923
  runtimeFn as runtimeFn2,
835
924
  toCryptoRuntime as toCryptoRuntime3,
836
- URI as URI2
925
+ URI as URI3
837
926
  } from "@adviser/cement";
838
927
  import { base58btc as base58btc2 } from "multiformats/bases/base58";
928
+
929
+ // src/runtime/gateways/file/sys-file-system-factory.ts
930
+ import { runtimeFn } from "@adviser/cement";
931
+ function sysFileSystemFactory(uri) {
932
+ const rt = runtimeFn();
933
+ switch (true) {
934
+ case rt.isNodeIsh:
935
+ return import("@fireproof/core/node").then((m) => m.getSysFileSystem(uri));
936
+ case rt.isDeno:
937
+ return import("@fireproof/core/deno").then((m) => m.getSysFileSystem(uri));
938
+ default:
939
+ throw new Error(`unsupported runtime:${rt}`);
940
+ }
941
+ }
942
+
943
+ // src/runtime/gateways/file/key-bag-file.ts
944
+ var KeyBagProviderFile = class {
945
+ async _prepare(id) {
946
+ await this.sthis.start();
947
+ const sysFS = await sysFileSystemFactory(this.url);
948
+ const dirName = this.url.pathname;
949
+ await sysFS.mkdir(dirName, { recursive: true });
950
+ return {
951
+ dirName,
952
+ sysFS,
953
+ fName: this.sthis.pathOps.join(dirName, `${id.replace(/[^a-zA-Z0-9]/g, "_")}.json`)
954
+ };
955
+ }
956
+ constructor(url, sthis) {
957
+ this.url = url;
958
+ this.sthis = sthis;
959
+ this.logger = sthis.logger;
960
+ }
961
+ async get(id) {
962
+ const ctx = await this._prepare(id);
963
+ try {
964
+ const p = await ctx.sysFS.readfile(ctx.fName);
965
+ const ki = JSON.parse(this.sthis.txt.decode(p));
966
+ return ki;
967
+ } catch (e) {
968
+ if (isNotFoundError(e)) {
969
+ return void 0;
970
+ }
971
+ throw this.logger.Error().Err(e).Str("file", ctx.dirName).Msg("read bag failed").AsError();
972
+ }
973
+ }
974
+ async set(id, item) {
975
+ const ctx = await this._prepare(id);
976
+ const p = this.sthis.txt.encode(JSON.stringify(item, null, 2));
977
+ await ctx.sysFS.writefile(ctx.fName, p);
978
+ }
979
+ };
980
+
981
+ // src/runtime/key-bag-memory.ts
982
+ var memoryKeyBag = /* @__PURE__ */ new Map();
983
+ var KeyBagProviderMemory = class {
984
+ constructor(url, sthis) {
985
+ this.url = url;
986
+ this.sthis = sthis;
987
+ }
988
+ key(id) {
989
+ return `${this.url.pathname}/${id}`;
990
+ }
991
+ async get(id) {
992
+ const binKeyItem = memoryKeyBag.get(this.key(id));
993
+ if (binKeyItem) {
994
+ const ki = JSON.parse(this.sthis.txt.decode(binKeyItem));
995
+ return ki;
996
+ }
997
+ return void 0;
998
+ }
999
+ async set(id, item) {
1000
+ const p = this.sthis.txt.encode(JSON.stringify(item, null, 2));
1001
+ memoryKeyBag.set(this.key(id), p);
1002
+ }
1003
+ };
1004
+
1005
+ // src/runtime/key-bag.ts
839
1006
  var KeyBag = class {
840
1007
  constructor(rt) {
841
1008
  this.rt = rt;
842
1009
  this._warnOnce = new ResolveOnce2();
843
1010
  this._seq = new ResolveSeq();
844
- this.logger = ensureLogger(rt.sthis, "KeyBag");
1011
+ this.logger = ensureLogger(rt.sthis, "KeyBag", {
1012
+ // id: rt.id(),
1013
+ });
845
1014
  this.logger.Debug().Msg("KeyBag created");
846
1015
  }
847
1016
  async subtleKey(key) {
848
- const extractable = this.rt.url.getParam("extractKey") === "_deprecated_internal_api";
1017
+ const extractable = this.rt.url.getParam("extractKey" /* EXTRACTKEY */) === "_deprecated_internal_api";
849
1018
  if (extractable) {
850
1019
  this._warnOnce.once(
851
1020
  () => this.logger.Warn().Msg("extractKey is enabled via _deprecated_internal_api --- handle keys safely!!!")
@@ -862,7 +1031,7 @@ var KeyBag = class {
862
1031
  );
863
1032
  }
864
1033
  async ensureKeyFromUrl(url, keyFactory) {
865
- const storeKey = url.getParam("storekey");
1034
+ const storeKey = url.getParam("storekey" /* STORE_KEY */);
866
1035
  if (storeKey === "insecure") {
867
1036
  return Result2.Ok(url);
868
1037
  }
@@ -872,7 +1041,7 @@ var KeyBag = class {
872
1041
  if (ret.isErr()) {
873
1042
  return ret;
874
1043
  }
875
- const urb = url.build().setParam("storekey", keyName);
1044
+ const urb = url.build().setParam("storekey" /* STORE_KEY */, keyName);
876
1045
  return Result2.Ok(urb.URI());
877
1046
  }
878
1047
  if (storeKey.startsWith("@") && storeKey.endsWith("@")) {
@@ -948,8 +1117,7 @@ var keyBagProviderFactories = new Map(
948
1117
  {
949
1118
  protocol: "file:",
950
1119
  factory: async (url, sthis) => {
951
- const { KeyBagProviderImpl } = await import("@fireproof/core/node");
952
- return new KeyBagProviderImpl(url, sthis);
1120
+ return new KeyBagProviderFile(url, sthis);
953
1121
  }
954
1122
  },
955
1123
  {
@@ -958,6 +1126,12 @@ var keyBagProviderFactories = new Map(
958
1126
  const { KeyBagProviderImpl } = await import("@fireproof/core/web");
959
1127
  return new KeyBagProviderImpl(url, sthis);
960
1128
  }
1129
+ },
1130
+ {
1131
+ protocol: "memory:",
1132
+ factory: async (url, sthis) => {
1133
+ return new KeyBagProviderMemory(url, sthis);
1134
+ }
961
1135
  }
962
1136
  ].map((i) => [i.protocol, i])
963
1137
  );
@@ -972,14 +1146,14 @@ function defaultKeyBagUrl(sthis) {
972
1146
  let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
973
1147
  let url;
974
1148
  if (runtimeFn2().isBrowser) {
975
- url = URI2.from(bagFnameOrUrl || "indexdb://fp-keybag");
1149
+ url = URI3.from(bagFnameOrUrl || "indexdb://fp-keybag");
976
1150
  } else {
977
1151
  if (!bagFnameOrUrl) {
978
1152
  const home = sthis.env.get("HOME");
979
1153
  bagFnameOrUrl = `${home}/.fireproof/keybag`;
980
- url = URI2.from(`file://${bagFnameOrUrl}`);
1154
+ url = URI3.from(`file://${bagFnameOrUrl}`);
981
1155
  } else {
982
- url = URI2.from(bagFnameOrUrl);
1156
+ url = URI3.from(bagFnameOrUrl);
983
1157
  }
984
1158
  }
985
1159
  const logger = ensureLogger(sthis, "defaultKeyBagUrl");
@@ -987,22 +1161,34 @@ function defaultKeyBagUrl(sthis) {
987
1161
  return url;
988
1162
  }
989
1163
  function defaultKeyBagOpts(sthis, kbo) {
1164
+ kbo = kbo || {};
990
1165
  if (kbo.keyRuntime) {
991
1166
  return kbo.keyRuntime;
992
1167
  }
993
1168
  const logger = ensureLogger(sthis, "KeyBag");
994
1169
  let url;
995
1170
  if (kbo.url) {
996
- url = URI2.from(kbo.url);
1171
+ url = URI3.from(kbo.url);
997
1172
  logger.Debug().Url(url).Msg("from opts");
998
1173
  } else {
999
- url = defaultKeyBagUrl(sthis);
1174
+ let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
1175
+ if (runtimeFn2().isBrowser) {
1176
+ url = URI3.from(bagFnameOrUrl || "indexdb://fp-keybag");
1177
+ } else {
1178
+ if (!bagFnameOrUrl) {
1179
+ const home = sthis.env.get("HOME");
1180
+ bagFnameOrUrl = `${home}/.fireproof/keybag`;
1181
+ url = URI3.from(`file://${bagFnameOrUrl}`);
1182
+ } else {
1183
+ url = URI3.from(bagFnameOrUrl);
1184
+ }
1185
+ }
1186
+ logger.Debug().Url(url).Msg("from env");
1000
1187
  }
1001
1188
  const kitem = keyBagProviderFactories.get(url.protocol);
1002
1189
  if (!kitem) {
1003
1190
  throw logger.Error().Url(url).Msg("unsupported protocol").AsError();
1004
1191
  }
1005
- const getBag = async () => kitem.factory(url, sthis);
1006
1192
  if (url.hasParam("masterkey")) {
1007
1193
  throw logger.Error().Url(url).Msg("masterkey is not supported").AsError();
1008
1194
  }
@@ -1012,7 +1198,7 @@ function defaultKeyBagOpts(sthis, kbo) {
1012
1198
  sthis,
1013
1199
  logger,
1014
1200
  keyLength: kbo.keyLength || 16,
1015
- getBag,
1201
+ getBag: () => kitem.factory(url, sthis),
1016
1202
  id: () => {
1017
1203
  return url.toString();
1018
1204
  }
@@ -1037,7 +1223,7 @@ async function encodeCarFile(roots, t, codec3) {
1037
1223
  size += CBW.blockLength({ cid, bytes });
1038
1224
  }
1039
1225
  const buffer = new Uint8Array(size);
1040
- const writer = CBW.createWriter(buffer, { headerSize });
1226
+ const writer = CBW.createWriter(buffer.buffer, { headerSize });
1041
1227
  for (const r of roots) {
1042
1228
  writer.addRoot(r);
1043
1229
  }
@@ -1192,7 +1378,7 @@ function uniqueCids(list, remove = /* @__PURE__ */ new Set()) {
1192
1378
  return [...byString.values()];
1193
1379
  }
1194
1380
  var Loader = class {
1195
- constructor(name, ebOpts, sthis) {
1381
+ constructor(sthis, ebOpts) {
1196
1382
  this.commitQueue = new CommitQueue();
1197
1383
  this.isCompacting = false;
1198
1384
  this.carReaders = /* @__PURE__ */ new Map();
@@ -1202,14 +1388,17 @@ var Loader = class {
1202
1388
  this.getBlockCache = /* @__PURE__ */ new Map();
1203
1389
  this.seenMeta = /* @__PURE__ */ new Set();
1204
1390
  this.writeLimit = pLimit(1);
1391
+ this._carStore = new ResolveOnce3();
1392
+ this._fileStore = new ResolveOnce3();
1393
+ this._WALStore = new ResolveOnce3();
1394
+ this._metaStore = new ResolveOnce3();
1205
1395
  this.onceReady = new ResolveOnce3();
1206
- this.name = name;
1207
1396
  this.sthis = sthis;
1208
1397
  this.ebOpts = defaultedBlockstoreRuntime(
1209
1398
  sthis,
1210
1399
  {
1211
- ...ebOpts,
1212
- name
1400
+ ...ebOpts
1401
+ // name,
1213
1402
  },
1214
1403
  "Loader"
1215
1404
  );
@@ -1218,21 +1407,52 @@ var Loader = class {
1218
1407
  await this.handleDbMetasFromStore([dbMeta]);
1219
1408
  });
1220
1409
  }
1221
- // readonly id = uuidv4();
1222
- async keyBag() {
1223
- return getKeyBag(this.sthis, this.ebOpts.keyBag);
1224
- }
1225
1410
  async carStore() {
1226
- return this.ebOpts.storeRuntime.makeDataStore(this);
1411
+ return this._carStore.once(
1412
+ async () => this.ebOpts.storeRuntime.makeDataStore({
1413
+ sthis: this.sthis,
1414
+ gatewayInterceptor: this.ebOpts.gatewayInterceptor,
1415
+ url: this.ebOpts.storeUrls.data,
1416
+ // keybag: await this.keyBag(),
1417
+ loader: this
1418
+ })
1419
+ );
1227
1420
  }
1228
1421
  async fileStore() {
1229
- return this.ebOpts.storeRuntime.makeDataStore(this);
1422
+ return this._fileStore.once(
1423
+ async () => this.ebOpts.storeRuntime.makeDataStore({
1424
+ sthis: this.sthis,
1425
+ gatewayInterceptor: this.ebOpts.gatewayInterceptor,
1426
+ url: this.ebOpts.storeUrls.file,
1427
+ // keybag: await this.keyBag(),
1428
+ loader: this
1429
+ })
1430
+ );
1230
1431
  }
1231
1432
  async WALStore() {
1232
- return this.ebOpts.storeRuntime.makeWALStore(this);
1433
+ return this._WALStore.once(
1434
+ async () => this.ebOpts.storeRuntime.makeWALStore({
1435
+ sthis: this.sthis,
1436
+ gatewayInterceptor: this.ebOpts.gatewayInterceptor,
1437
+ url: this.ebOpts.storeUrls.wal,
1438
+ // keybag: await this.keyBag(),
1439
+ loader: this
1440
+ })
1441
+ );
1233
1442
  }
1234
1443
  async metaStore() {
1235
- return this.ebOpts.storeRuntime.makeMetaStore(this);
1444
+ return this._metaStore.once(
1445
+ async () => this.ebOpts.storeRuntime.makeMetaStore({
1446
+ sthis: this.sthis,
1447
+ gatewayInterceptor: this.ebOpts.gatewayInterceptor,
1448
+ url: this.ebOpts.storeUrls.meta,
1449
+ // keybag: await this.keyBag(),
1450
+ loader: this
1451
+ })
1452
+ );
1453
+ }
1454
+ keyBag() {
1455
+ return getKeyBag(this.sthis, this.ebOpts.keyBag);
1236
1456
  }
1237
1457
  async ready() {
1238
1458
  return this.onceReady.once(async () => {
@@ -1245,6 +1465,7 @@ var Loader = class {
1245
1465
  });
1246
1466
  }
1247
1467
  async close() {
1468
+ await this.commitQueue.waitIdle();
1248
1469
  const toClose = await Promise.all([this.carStore(), this.metaStore(), this.fileStore(), this.WALStore()]);
1249
1470
  await Promise.all(toClose.map((store) => store.close()));
1250
1471
  }
@@ -1314,11 +1535,11 @@ var Loader = class {
1314
1535
  }
1315
1536
  async commit(t, done, opts = { noLoader: false, compact: false }) {
1316
1537
  await this.ready();
1317
- const fstore = await this.fileStore();
1538
+ const carStore = await this.carStore();
1318
1539
  const params = {
1319
- encoder: (await fstore.keyedCrypto()).codec(),
1540
+ encoder: (await carStore.keyedCrypto()).codec(),
1320
1541
  carLog: this.carLog,
1321
- carStore: fstore,
1542
+ carStore,
1322
1543
  WALStore: await this.WALStore(),
1323
1544
  metaStore: await this.metaStore(),
1324
1545
  threshold: this.ebOpts.threshold
@@ -1552,12 +1773,12 @@ var generateIV = {
1552
1773
  return hashArray;
1553
1774
  },
1554
1775
  verify: async function(ko, crypto, iv, data) {
1555
- return ko.url.getParam("ivverify") !== "disable" && UInt8ArrayEqual(iv, await this.calc(ko, crypto, data));
1776
+ return ko.url.getParam("ivVerify" /* IV_VERIFY */) !== "disable" && UInt8ArrayEqual(iv, await this.calc(ko, crypto, data));
1556
1777
  }
1557
1778
  }
1558
1779
  };
1559
1780
  function getGenerateIVFn(url, opts) {
1560
- const ivhash = opts.ivCalc || url.getParam("ivhash") || "hash";
1781
+ const ivhash = opts.ivCalc || url.getParam("ivHash" /* IV_HASH */) || "hash";
1561
1782
  return generateIV[ivhash] || generateIV["hash"];
1562
1783
  }
1563
1784
  var BlockIvKeyIdCodec = class {
@@ -1678,7 +1899,7 @@ var noCrypto = class {
1678
1899
  }
1679
1900
  };
1680
1901
  async function keyedCryptoFactory(url, kb, sthis) {
1681
- const storekey = url.getParam("storekey");
1902
+ const storekey = url.getParam("storekey" /* STORE_KEY */);
1682
1903
  if (storekey && storekey !== "insecure") {
1683
1904
  let rkey = await kb.getNamedKey(storekey, true);
1684
1905
  if (rkey.isErr()) {
@@ -1693,277 +1914,167 @@ async function keyedCryptoFactory(url, kb, sthis) {
1693
1914
  return new noCrypto(url, kb.rt.crypto, sthis);
1694
1915
  }
1695
1916
 
1696
- // src/blockstore/fragment-gateway.ts
1917
+ // src/blockstore/fp-envelope.ts
1697
1918
  import { Result as Result3 } from "@adviser/cement";
1698
- import { base58btc as base58btc4 } from "multiformats/bases/base58";
1699
- import { encode as encode3, decode as decode3 } from "@fireproof/vendor/cborg";
1700
- function getFragSize(url) {
1701
- const fragSize = url.getParam("fragSize");
1702
- let ret = 0;
1703
- if (fragSize) {
1704
- ret = parseInt(fragSize);
1919
+ var FPEnvelopeType = /* @__PURE__ */ ((FPEnvelopeType2) => {
1920
+ FPEnvelopeType2["CAR"] = "car";
1921
+ FPEnvelopeType2["FILE"] = "file";
1922
+ FPEnvelopeType2["META"] = "meta";
1923
+ FPEnvelopeType2["WAL"] = "wal";
1924
+ return FPEnvelopeType2;
1925
+ })(FPEnvelopeType || {});
1926
+ function Car2FPMsg(fpcar) {
1927
+ return Result3.Ok({ type: "car" /* CAR */, payload: fpcar });
1928
+ }
1929
+ function File2FPMsg(fpfile) {
1930
+ return Result3.Ok({ type: "file" /* FILE */, payload: fpfile });
1931
+ }
1932
+
1933
+ // src/blockstore/store.ts
1934
+ import { EventBlock } from "@fireproof/vendor/@web3-storage/pail/clock";
1935
+ import { format } from "@fireproof/vendor/@ipld/dag-json";
1936
+ import pRetry from "p-retry";
1937
+ import pMap from "p-map";
1938
+
1939
+ // src/blockstore/interceptor-gateway.ts
1940
+ import { Result as Result4 } from "@adviser/cement";
1941
+ var PassThroughGateway = class {
1942
+ async buildUrl(sthis, url, key) {
1943
+ const op = { url, key };
1944
+ return Result4.Ok({ op });
1705
1945
  }
1706
- if (isNaN(ret) || ret <= 0) {
1707
- ret = 0;
1946
+ async start(sthis, url) {
1947
+ const op = { url };
1948
+ return Result4.Ok({ op });
1708
1949
  }
1709
- return ret;
1710
- }
1711
- async function getFrags(url, innerGW, headerSize, logger) {
1712
- const fragSize = getFragSize(url);
1713
- if (!fragSize) {
1714
- const res = await innerGW.get(url);
1715
- if (res.isErr()) {
1716
- return [res];
1717
- }
1718
- const data = res.unwrap();
1719
- return [
1720
- Result3.Ok({
1721
- fid: new Uint8Array(0),
1722
- ofs: 0,
1723
- len: data.length,
1724
- data
1725
- })
1726
- ];
1727
- }
1728
- const firstRaw = await innerGW.get(url.build().setParam("ofs", "0").URI());
1729
- if (firstRaw.isErr()) {
1730
- return [firstRaw];
1731
- }
1732
- const firstFragment = decode3(firstRaw.unwrap());
1733
- const blockSize = firstFragment.data.length;
1734
- const ops = [Promise.resolve(Result3.Ok(firstFragment))];
1735
- const fidStr = base58btc4.encode(firstFragment.fid);
1736
- const fragUrl = url.build().setParam("fid", fidStr).setParam("len", firstFragment.len.toString()).setParam("headerSize", headerSize.toString());
1737
- for (let ofs = blockSize; ofs < firstFragment.len; ofs += blockSize) {
1738
- ops.push(
1739
- (async (furl, ofs2) => {
1740
- const raw2 = await innerGW.get(furl);
1741
- if (raw2.isErr()) {
1742
- return raw2;
1743
- }
1744
- const fragment = decode3(raw2.unwrap());
1745
- if (base58btc4.encode(fragment.fid) !== fidStr) {
1746
- return Result3.Err(logger.Error().Msg("Fragment fid mismatch").AsError());
1747
- }
1748
- if (fragment.ofs !== ofs2) {
1749
- return Result3.Err(logger.Error().Uint64("ofs", ofs2).Msg("Fragment ofs mismatch").AsError());
1750
- }
1751
- return Result3.Ok(fragment);
1752
- })(fragUrl.setParam("ofs", ofs.toString()).URI(), ofs)
1753
- );
1950
+ async close(sthis, url) {
1951
+ const op = { url };
1952
+ return Result4.Ok({ op });
1754
1953
  }
1755
- return Promise.all(ops);
1756
- }
1757
- var FragmentGateway = class {
1758
- constructor(sthis, innerGW) {
1759
- this.fidLength = 4;
1760
- this.headerSize = 32;
1761
- this.sthis = ensureSuperLog(sthis, "FragmentGateway");
1762
- this.logger = this.sthis.logger;
1954
+ async delete(sthis, url) {
1955
+ const op = { url };
1956
+ return Result4.Ok({ op });
1957
+ }
1958
+ async destroy(sthis, url) {
1959
+ const op = { url };
1960
+ return Result4.Ok({ op });
1961
+ }
1962
+ async put(sthis, url, body) {
1963
+ const op = { url, body };
1964
+ return Result4.Ok({ op });
1965
+ }
1966
+ async get(sthis, url) {
1967
+ const op = { url };
1968
+ return Result4.Ok({ op });
1969
+ }
1970
+ async subscribe(sthis, url, callback) {
1971
+ const op = { url, callback };
1972
+ return Result4.Ok({ op });
1973
+ }
1974
+ };
1975
+ var passThrougthGateway = new PassThroughGateway();
1976
+ var InterceptorGateway = class {
1977
+ constructor(sthis, innerGW, interceptor) {
1763
1978
  this.innerGW = innerGW;
1979
+ this.interceptor = interceptor || passThrougthGateway;
1764
1980
  }
1765
- slicer(url, body) {
1766
- const fragSize = getFragSize(url);
1767
- if (!fragSize) {
1768
- return [this.innerGW.put(url, body)];
1769
- }
1770
- const blocksize = fragSize - this.headerSize;
1771
- if (blocksize <= 0) {
1772
- throw this.logger.Error().Uint64("fragSize", fragSize).Uint64("headerSize", this.headerSize).Msg("Fragment size is too small").AsError();
1773
- }
1774
- const ops = [];
1775
- const fid = this.sthis.nextId(this.fidLength);
1776
- const fragUrl = url.build().setParam("fid", fid.str).setParam("len", body.length.toString()).setParam("headerSize", this.headerSize.toString());
1777
- for (let ofs = 0; ofs < body.length; ofs += blocksize) {
1778
- const block = encode3({
1779
- fid: fid.bin,
1780
- ofs,
1781
- len: body.length,
1782
- data: body.slice(ofs, ofs + blocksize)
1783
- });
1784
- if (block.length > fragSize) {
1785
- throw this.logger.Error().Uint64("block", block.length).Uint64("fragSize", fragSize).Msg("Block size to big").AsError();
1786
- }
1787
- ops.push(this.innerGW.put(fragUrl.setParam("ofs", ofs.toString()).URI(), block));
1981
+ async buildUrl(sthis, baseUrl, key, loader) {
1982
+ const rret = await this.interceptor.buildUrl(sthis, baseUrl, key, loader);
1983
+ if (rret.isErr()) {
1984
+ return Result4.Err(rret.Err());
1788
1985
  }
1789
- return ops;
1986
+ const ret = rret.unwrap();
1987
+ if (ret.stop && ret.value) {
1988
+ return ret.value;
1989
+ }
1990
+ return this.innerGW.buildUrl(sthis, ret.op.url, ret.op.key, loader);
1790
1991
  }
1791
- buildUrl(baseUrl, key) {
1792
- return this.innerGW.buildUrl(baseUrl, key);
1793
- }
1794
- async destroy(iurl) {
1795
- return this.innerGW.destroy(iurl);
1796
- }
1797
- async start(url) {
1798
- this.headerSize = encode3({
1799
- fid: this.sthis.nextId(this.fidLength).bin,
1800
- ofs: 1024 * 1024,
1801
- // 32bit
1802
- len: 16 * 1024 * 1024,
1803
- // 32bit
1804
- data: new Uint8Array(1024)
1805
- }).length - 1024;
1806
- return this.innerGW.start(url);
1807
- }
1808
- async close(url) {
1809
- return this.innerGW.close(url);
1810
- }
1811
- async put(url, body) {
1812
- await Promise.all(this.slicer(url, body));
1813
- return Result3.Ok(void 0);
1814
- }
1815
- async get(url) {
1816
- const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
1817
- let buffer = void 0;
1818
- for (const rfrag of rfrags) {
1819
- if (rfrag.isErr()) {
1820
- return Result3.Err(rfrag.Err());
1821
- }
1822
- const frag = rfrag.Ok();
1823
- buffer = buffer || new Uint8Array(frag.len);
1824
- buffer.set(frag.data, frag.ofs);
1825
- }
1826
- return Result3.Ok(buffer || new Uint8Array(0));
1827
- }
1828
- async subscribe(url, callback) {
1829
- if (this.innerGW.subscribe) {
1830
- return this.innerGW.subscribe(url, callback);
1831
- } else {
1832
- return Result3.Err(this.logger.Error().Url(url).Msg("subscribe not supported").AsError());
1992
+ async destroy(sthis, iurl, loader) {
1993
+ const rret = await this.interceptor.destroy(sthis, iurl, loader);
1994
+ if (rret.isErr()) {
1995
+ return Result4.Err(rret.Err());
1996
+ }
1997
+ const ret = rret.unwrap();
1998
+ if (ret.stop && ret.value) {
1999
+ return ret.value;
1833
2000
  }
2001
+ return this.innerGW.destroy(sthis, ret.op.url, loader);
1834
2002
  }
1835
- async delete(url) {
1836
- const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
1837
- for (const rfrag of rfrags) {
1838
- if (rfrag.isErr()) {
1839
- return Result3.Err(rfrag.Err());
1840
- }
1841
- const frag = rfrag.Ok();
1842
- const fidStr = base58btc4.encode(frag.fid);
1843
- const fragUrl = url.build().setParam("fid", fidStr).setParam("len", frag.len.toString()).setParam("headerSize", this.headerSize.toString()).URI();
1844
- await this.innerGW.delete(fragUrl);
2003
+ async start(sthis, url, loader) {
2004
+ const rret = await this.interceptor.start(sthis, url, loader);
2005
+ if (rret.isErr()) {
2006
+ return Result4.Err(rret.Err());
2007
+ }
2008
+ const ret = rret.unwrap();
2009
+ if (ret.stop && ret.value) {
2010
+ return ret.value;
1845
2011
  }
1846
- return Result3.Ok(void 0);
2012
+ return await this.innerGW.start(sthis, ret.op.url, loader);
1847
2013
  }
1848
- };
1849
-
1850
- // src/blockstore/meta-key-helper.ts
1851
- import { format, parse } from "@fireproof/vendor/@ipld/dag-json";
1852
- import { EventBlock, decodeEventBlock } from "@fireproof/vendor/@web3-storage/pail/clock";
1853
- import { CID as CID2 } from "multiformats";
1854
- import { base64pad } from "multiformats/bases/base64";
1855
- import { Result as Result4 } from "@adviser/cement";
1856
- async function decodeGatewayMetaBytesToDbMeta(sthis, byteHeads) {
1857
- const crdtEntries = JSON.parse(sthis.txt.decode(byteHeads));
1858
- if (!Array.isArray(crdtEntries)) {
1859
- sthis.logger.Debug().Str("crdtEntries", JSON.stringify(crdtEntries)).Msg("No data in CRDT entries");
1860
- return [];
1861
- }
1862
- if (!crdtEntries.length) {
1863
- sthis.logger.Debug().Any("byteHeads", byteHeads).Msg("No CRDT entries found");
1864
- return [];
1865
- }
1866
- const logger = ensureLogger(sthis, "decodeGatewayMetaBytesToDbMeta");
1867
- return Promise.all(
1868
- crdtEntries.map(async (crdtEntry) => {
1869
- const eventBlock = await decodeEventBlock(base64pad.decode(crdtEntry.data));
1870
- const dbMeta = parse(sthis.txt.decode(eventBlock.value.data.dbMeta));
1871
- logger.Debug().Any("crdtEntry", {
1872
- crdtEntry,
1873
- eventBlock,
1874
- dbMeta,
1875
- dbMetaStrings: dbMeta.cars.map((car) => car.toString())
1876
- }).Msg("CRDT entry");
1877
- return {
1878
- eventCid: eventBlock.cid,
1879
- parents: crdtEntry.parents,
1880
- dbMeta
1881
- };
1882
- })
1883
- );
1884
- }
1885
- async function setCryptoKeyFromGatewayMetaPayload(uri, sthis, data) {
1886
- try {
1887
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Setting crypto key from gateway meta payload");
1888
- const keyInfo = await decodeGatewayMetaBytesToDbMeta(sthis, data);
1889
- if (keyInfo.length) {
1890
- const dbMeta = keyInfo[0].dbMeta;
1891
- if (dbMeta.key) {
1892
- const kb = await getKeyBag(sthis);
1893
- const keyName = getStoreKeyName(uri);
1894
- const res = await kb.setNamedKey(keyName, dbMeta.key);
1895
- if (res.isErr()) {
1896
- sthis.logger.Debug().Str("keyName", keyName).Str("dbMeta.key", dbMeta.key).Msg("Failed to set named key");
1897
- throw res.Err();
1898
- }
1899
- }
1900
- sthis.logger.Debug().Str("dbMeta.key", dbMeta.key).Str("uri", uri.toString()).Msg("Set crypto key from gateway meta payload");
1901
- return Result4.Ok(dbMeta);
2014
+ async close(sthis, url, loader) {
2015
+ const rret = await this.interceptor.close(sthis, url, loader);
2016
+ if (rret.isErr()) {
2017
+ return Result4.Err(rret.Err());
1902
2018
  }
1903
- sthis.logger.Debug().Any("data", data).Msg("No crypto in gateway meta payload");
1904
- return Result4.Ok(void 0);
1905
- } catch (error) {
1906
- sthis.logger.Debug().Err(error).Msg("Failed to set crypto key from gateway meta payload");
1907
- return Result4.Err(error);
2019
+ const ret = rret.unwrap();
2020
+ if (ret.stop && ret.value) {
2021
+ return ret.value;
2022
+ }
2023
+ return await this.innerGW.close(sthis, ret.op.url, loader);
1908
2024
  }
1909
- }
1910
- async function addCryptoKeyToGatewayMetaPayload(uri, sthis, body) {
1911
- try {
1912
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Adding crypto key to gateway meta payload");
1913
- const keyName = getStoreKeyName(uri);
1914
- const kb = await getKeyBag(sthis);
1915
- const res = await kb.getNamedExtractableKey(keyName, true);
1916
- if (res.isErr()) {
1917
- sthis.logger.Error().Str("keyName", keyName).Msg("Failed to get named extractable key");
1918
- throw res.Err();
2025
+ async put(sthis, url, fpEnv, loader) {
2026
+ const rret = await this.interceptor.put(sthis, url, fpEnv, loader);
2027
+ if (rret.isErr()) {
2028
+ return Result4.Err(rret.Err());
1919
2029
  }
1920
- const keyData = await res.Ok().extract();
1921
- const dbMetas = await decodeGatewayMetaBytesToDbMeta(sthis, body);
1922
- const { dbMeta, parents } = dbMetas[0];
1923
- const parentLinks = parents.map((p) => CID2.parse(p));
1924
- dbMeta.key = keyData.keyStr;
1925
- const events = await Promise.all([dbMeta].map((dbMeta2) => createDbMetaEventBlock(sthis, dbMeta2, parentLinks)));
1926
- const encoded = await encodeEventsWithParents(sthis, events, parentLinks);
1927
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Added crypto key to gateway meta payload");
1928
- return Result4.Ok(encoded);
1929
- } catch (error) {
1930
- sthis.logger.Error().Err(error).Msg("Failed to add crypto key to gateway meta payload");
1931
- return Result4.Err(error);
1932
- }
1933
- }
1934
- function getStoreKeyName(url) {
1935
- const storeKeyName = [url.getParam("localName") || url.getParam("name")];
1936
- const idx = url.getParam("index");
1937
- if (idx) {
1938
- storeKeyName.push(idx);
1939
- }
1940
- storeKeyName.push("data");
1941
- return `@${storeKeyName.join(":")}@`;
1942
- }
1943
- async function createDbMetaEventBlock(sthis, dbMeta, parents) {
1944
- const event = await EventBlock.create(
1945
- {
1946
- dbMeta: sthis.txt.encode(format(dbMeta))
1947
- },
1948
- parents
1949
- );
1950
- return event;
1951
- }
1952
- async function encodeEventsWithParents(sthis, events, parents) {
1953
- const crdtEntries = events.map((event) => {
1954
- const base64String = base64pad.encode(event.bytes);
1955
- return {
1956
- cid: event.cid.toString(),
1957
- data: base64String,
1958
- parents: parents.map((p) => p.toString())
1959
- };
1960
- });
1961
- return sthis.txt.encode(JSON.stringify(crdtEntries));
1962
- }
2030
+ const ret = rret.unwrap();
2031
+ if (ret.stop && ret.value) {
2032
+ return ret.value;
2033
+ }
2034
+ return this.innerGW.put(sthis, ret.op.url, ret.op.body, loader);
2035
+ }
2036
+ async get(sthis, url, loader) {
2037
+ const rret = await this.interceptor.get(sthis, url, loader);
2038
+ if (rret.isErr()) {
2039
+ return Result4.Err(rret.Err());
2040
+ }
2041
+ const ret = rret.unwrap();
2042
+ if (ret.stop && ret.value) {
2043
+ return ret.value;
2044
+ }
2045
+ return this.innerGW.get(sthis, ret.op.url, loader);
2046
+ }
2047
+ async subscribe(sthis, url, callback, loader) {
2048
+ if (!this.innerGW.subscribe) {
2049
+ return Result4.Err(sthis.logger.Error().Url(url).Msg("subscribe not supported").AsError());
2050
+ }
2051
+ const rret = await this.interceptor.subscribe(sthis, url, callback, loader);
2052
+ if (rret.isErr()) {
2053
+ return Result4.Err(rret.Err());
2054
+ }
2055
+ const ret = rret.unwrap();
2056
+ if (ret.stop && ret.value) {
2057
+ return ret.value;
2058
+ }
2059
+ return this.innerGW.subscribe(sthis, ret.op.url, ret.op.callback, loader);
2060
+ }
2061
+ async delete(sthis, url, loader) {
2062
+ const rret = await this.interceptor.delete(sthis, url, loader);
2063
+ if (rret.isErr()) {
2064
+ return Result4.Err(rret.Err());
2065
+ }
2066
+ const ret = rret.unwrap();
2067
+ if (ret.stop && ret.value) {
2068
+ return ret.value;
2069
+ }
2070
+ return this.innerGW.delete(sthis, url, loader);
2071
+ }
2072
+ async getPlain(sthis, url, key, loader) {
2073
+ return this.innerGW.getPlain(sthis, url, key, loader);
2074
+ }
2075
+ };
1963
2076
 
1964
2077
  // src/blockstore/store.ts
1965
- import pRetry from "p-retry";
1966
- import pMap from "p-map";
1967
2078
  function guardVersion(url) {
1968
2079
  if (!url.hasParam("version")) {
1969
2080
  return Result5.Err(`missing version: ${url.toString()}`);
@@ -1971,16 +2082,21 @@ function guardVersion(url) {
1971
2082
  return Result5.Ok(url);
1972
2083
  }
1973
2084
  var BaseStoreImpl = class {
1974
- constructor(name, url, opts, sthis, logger) {
2085
+ // readonly loader: Loadable;
2086
+ constructor(sthis, url, opts, logger) {
1975
2087
  this._onStarted = [];
1976
2088
  this._onClosed = [];
1977
- this.name = name;
1978
2089
  this._url = url;
1979
- this.keybag = opts.keybag;
1980
- this.sthis = sthis;
1981
- this.logger = logger.With().Ref("url", () => this._url.toString()).Str("name", name).Logger();
1982
- this.gateway = new FragmentGateway(this.sthis, opts.gateway);
2090
+ this.opts = opts;
1983
2091
  this.loader = opts.loader;
2092
+ this.sthis = sthis;
2093
+ const name = this._url.getParam("name" /* NAME */);
2094
+ if (!name) {
2095
+ throw logger.Error().Url(this._url).Msg("missing name").AsError();
2096
+ }
2097
+ this.logger = logger.With().Str("this", this.sthis.nextId().str).Ref("url", () => this._url.toString()).Logger();
2098
+ this.realGateway = opts.gateway;
2099
+ this.gateway = new InterceptorGateway(this.sthis, opts.gateway, opts.gatewayInterceptor);
1984
2100
  }
1985
2101
  url() {
1986
2102
  return this._url;
@@ -1995,21 +2111,21 @@ var BaseStoreImpl = class {
1995
2111
  return;
1996
2112
  }
1997
2113
  async keyedCrypto() {
1998
- return keyedCryptoFactory(this._url, await this.keybag(), this.sthis);
2114
+ return keyedCryptoFactory(this._url, await this.loader.keyBag(), this.sthis);
1999
2115
  }
2000
2116
  async start() {
2001
2117
  this.logger.Debug().Str("storeType", this.storeType).Msg("starting-gateway-pre");
2002
- this._url = this._url.build().setParam("store", this.storeType).URI();
2003
- const res = await this.gateway.start(this._url);
2118
+ this._url = this._url.build().setParam("store" /* STORE */, this.storeType).URI();
2119
+ const res = await this.gateway.start(this.sthis, this._url, this.loader);
2004
2120
  if (res.isErr()) {
2005
2121
  this.logger.Error().Result("gw-start", res).Msg("started-gateway");
2006
2122
  return res;
2007
2123
  }
2008
2124
  this._url = res.Ok();
2009
- const kb = await this.keybag();
2125
+ const kb = await this.loader.keyBag();
2010
2126
  const skRes = await kb.ensureKeyFromUrl(this._url, () => {
2011
- const idx = this._url.getParam("index");
2012
- const storeKeyName = [this.name];
2127
+ const idx = this._url.getParam("index" /* INDEX */);
2128
+ const storeKeyName = [this.url().getParam("name" /* NAME */)];
2013
2129
  if (idx) {
2014
2130
  storeKeyName.push(idx);
2015
2131
  }
@@ -2039,10 +2155,23 @@ var BaseStoreImpl = class {
2039
2155
  return version;
2040
2156
  }
2041
2157
  };
2158
+ async function createDbMetaEvent(sthis, dbMeta, parents) {
2159
+ const event = await EventBlock.create(
2160
+ {
2161
+ dbMeta: sthis.txt.encode(format(dbMeta))
2162
+ },
2163
+ parents
2164
+ );
2165
+ return {
2166
+ eventCid: event.cid,
2167
+ dbMeta,
2168
+ parents
2169
+ };
2170
+ }
2042
2171
  var MetaStoreImpl = class extends BaseStoreImpl {
2043
2172
  // remote: boolean;
2044
- constructor(sthis, name, url, opts) {
2045
- super(name, url, { ...opts }, sthis, ensureLogger(sthis, "MetaStoreImpl"));
2173
+ constructor(sthis, url, opts) {
2174
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "MetaStoreImpl"));
2046
2175
  this.storeType = "meta";
2047
2176
  this.subscribers = /* @__PURE__ */ new Map();
2048
2177
  this.parents = [];
@@ -2052,14 +2181,18 @@ var MetaStoreImpl = class extends BaseStoreImpl {
2052
2181
  ) {
2053
2182
  this.onStarted(async () => {
2054
2183
  this.logger.Debug().Str("url", this.url().toString()).Msg("Subscribing to the gateway");
2055
- opts.gateway.subscribe?.(this.url(), async (message) => {
2056
- this.logger.Debug().Msg("Received message from gateway");
2057
- const dbMetas = await decodeGatewayMetaBytesToDbMeta(this.sthis, message);
2058
- await Promise.all(
2059
- dbMetas.map((dbMeta) => this.loader?.taskManager?.handleEvent(dbMeta.eventCid, dbMeta.parents, dbMeta.dbMeta))
2060
- );
2061
- this.updateParentsFromDbMetas(dbMetas);
2062
- });
2184
+ opts.gateway.subscribe?.(
2185
+ this.sthis,
2186
+ this.url(),
2187
+ async ({ payload: dbMetas }) => {
2188
+ this.logger.Debug().Msg("Received message from gateway");
2189
+ await Promise.all(
2190
+ dbMetas.map((dbMeta) => this.loader.taskManager?.handleEvent(dbMeta.eventCid, dbMeta.parents, dbMeta.dbMeta))
2191
+ );
2192
+ this.updateParentsFromDbMetas(dbMetas);
2193
+ },
2194
+ this.loader
2195
+ );
2063
2196
  });
2064
2197
  }
2065
2198
  }
@@ -2070,129 +2203,165 @@ var MetaStoreImpl = class extends BaseStoreImpl {
2070
2203
  const dbMetaParentsSet = new Set(dbMetaParents.map((p) => p.toString()));
2071
2204
  this.parents = Array.from(uniqueParentsMap.values()).filter((p) => !dbMetaParentsSet.has(p.toString()));
2072
2205
  }
2073
- async handleByteHeads(byteHeads) {
2074
- return await decodeGatewayMetaBytesToDbMeta(this.sthis, byteHeads);
2075
- }
2206
+ // async handleByteHeads(byteHeads: Uint8Array) {
2207
+ // // return await decodeGatewayMetaBytesToDbMeta(this.sthis, byteHeads);
2208
+ // const rDbMeta = await fpDeserialize(this.sthis, byteHeads, this.url());
2209
+ // if (rDbMeta.isErr()) {
2210
+ // throw this.logger.Error().Err(rDbMeta).Msg("error deserializing").AsError();
2211
+ // }
2212
+ // return (rDbMeta.Ok() as FPEnvelopeMeta).payload;
2213
+ // }
2076
2214
  async load() {
2077
2215
  const branch = "main";
2078
- const url = await this.gateway.buildUrl(this.url(), branch);
2216
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
2079
2217
  if (url.isErr()) {
2080
2218
  throw this.logger.Error().Result("buildUrl", url).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
2081
2219
  }
2082
- const bytes = await this.gateway.get(url.Ok());
2083
- if (bytes.isErr()) {
2084
- if (isNotFoundError(bytes)) {
2220
+ const rfpEnv = await this.gateway.get(this.sthis, url.Ok(), this.loader);
2221
+ if (rfpEnv.isErr()) {
2222
+ if (isNotFoundError(rfpEnv)) {
2085
2223
  return void 0;
2086
2224
  }
2087
- throw this.logger.Error().Url(url.Ok()).Result("bytes:", bytes).Msg("gateway get").AsError();
2225
+ throw this.logger.Error().Url(url.Ok()).Err(rfpEnv).Msg("gateway get").AsError();
2088
2226
  }
2089
- const dbMetas = await this.handleByteHeads(bytes.Ok());
2090
- await this.loader?.handleDbMetasFromStore(dbMetas.map((m) => m.dbMeta));
2227
+ const dbMetas = rfpEnv.Ok().payload;
2228
+ await this.loader.handleDbMetasFromStore(dbMetas.map((m) => m.dbMeta));
2091
2229
  this.updateParentsFromDbMetas(dbMetas);
2092
2230
  return dbMetas.map((m) => m.dbMeta);
2093
2231
  }
2094
2232
  async save(meta, branch) {
2095
2233
  branch = branch || "main";
2096
2234
  this.logger.Debug().Str("branch", branch).Any("meta", meta).Msg("saving meta");
2097
- const event = await createDbMetaEventBlock(this.sthis, meta, this.parents);
2098
- const bytes = await encodeEventsWithParents(this.sthis, [event], this.parents);
2099
- const url = await this.gateway.buildUrl(this.url(), branch);
2235
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
2100
2236
  if (url.isErr()) {
2101
2237
  throw this.logger.Error().Err(url.Err()).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
2102
2238
  }
2103
- this.parents = [event.cid];
2104
- const res = await this.gateway.put(url.Ok(), bytes);
2239
+ const dbMetaEvent = await createDbMetaEvent(this.sthis, meta, this.parents);
2240
+ const res = await this.gateway.put(
2241
+ this.sthis,
2242
+ url.Ok(),
2243
+ {
2244
+ type: "meta",
2245
+ payload: [dbMetaEvent]
2246
+ },
2247
+ this.loader
2248
+ );
2105
2249
  if (res.isErr()) {
2106
2250
  throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
2107
2251
  }
2108
2252
  return res;
2109
2253
  }
2110
2254
  async close() {
2111
- await this.gateway.close(this.url());
2255
+ await this.gateway.close(this.sthis, this.url(), this.loader);
2112
2256
  this._onClosed.forEach((fn) => fn());
2113
2257
  return Result5.Ok(void 0);
2114
2258
  }
2115
2259
  async destroy() {
2116
- return this.gateway.destroy(this.url());
2260
+ this.logger.Debug().Msg("destroy");
2261
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
2117
2262
  }
2118
2263
  };
2119
2264
  var DataStoreImpl = class extends BaseStoreImpl {
2120
- // readonly tag: string = "car-base";
2121
- constructor(sthis, name, url, opts) {
2122
- super(name, url, { ...opts }, sthis, ensureLogger(sthis, "DataStoreImpl"));
2265
+ constructor(sthis, url, opts) {
2266
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "DataStoreImpl"));
2123
2267
  this.storeType = "data";
2124
2268
  }
2125
2269
  async load(cid) {
2126
2270
  this.logger.Debug().Any("cid", cid).Msg("loading");
2127
- const url = await this.gateway.buildUrl(this.url(), cid.toString());
2271
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), cid.toString(), this.loader);
2128
2272
  if (url.isErr()) {
2129
2273
  throw this.logger.Error().Err(url.Err()).Str("cid", cid.toString()).Msg("got error from gateway.buildUrl").AsError();
2130
2274
  }
2131
- const res = await this.gateway.get(url.Ok());
2275
+ const res = await this.gateway.get(this.sthis, url.Ok(), this.loader);
2132
2276
  if (res.isErr()) {
2133
2277
  throw res.Err();
2134
2278
  }
2135
- return { cid, bytes: res.Ok() };
2279
+ const fpenv = res.Ok();
2280
+ switch (fpenv.type) {
2281
+ case "car":
2282
+ return { cid, bytes: fpenv.payload };
2283
+ case "file":
2284
+ return { cid, bytes: fpenv.payload };
2285
+ default:
2286
+ throw this.logger.Error().Msg("unexpected type").AsError();
2287
+ }
2136
2288
  }
2137
2289
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
2138
2290
  async save(car, opts) {
2139
2291
  this.logger.Debug().Any("cid", car.cid.toString()).Msg("saving");
2140
- const url = await this.gateway.buildUrl(this.url(), car.cid.toString());
2292
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), car.cid.toString(), this.loader);
2141
2293
  if (url.isErr()) {
2142
2294
  throw this.logger.Error().Err(url.Err()).Ref("cid", car.cid).Msg("got error from gateway.buildUrl").AsError();
2143
2295
  }
2144
- const res = await this.gateway.put(url.Ok(), car.bytes);
2296
+ let fpMsg;
2297
+ switch (url.Ok().getParam("store" /* STORE */)) {
2298
+ case "data":
2299
+ if (url.Ok().getParam("suffix" /* SUFFIX */)) {
2300
+ fpMsg = Car2FPMsg(car.bytes);
2301
+ } else {
2302
+ fpMsg = File2FPMsg(car.bytes);
2303
+ }
2304
+ break;
2305
+ default:
2306
+ throw this.logger.Error().Str("store", url.Ok().getParam("store" /* STORE */)).Msg("unexpected store").AsError();
2307
+ }
2308
+ if (fpMsg.isErr()) {
2309
+ throw this.logger.Error().Err(fpMsg).Msg("got error from FPMsg2Car").AsError();
2310
+ }
2311
+ const res = await this.gateway.put(this.sthis, url.Ok(), fpMsg.Ok(), this.loader);
2145
2312
  if (res.isErr()) {
2146
2313
  throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
2147
2314
  }
2148
2315
  return res.Ok();
2149
2316
  }
2150
2317
  async remove(cid) {
2151
- const url = await this.gateway.buildUrl(this.url(), cid.toString());
2318
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), cid.toString(), this.loader);
2152
2319
  if (url.isErr()) {
2153
2320
  return url;
2154
2321
  }
2155
- return this.gateway.delete(url.Ok());
2322
+ return this.gateway.delete(this.sthis, url.Ok(), this.loader);
2156
2323
  }
2157
2324
  async close() {
2158
- await this.gateway.close(this.url());
2325
+ await this.gateway.close(this.sthis, this.url(), this.loader);
2159
2326
  this._onClosed.forEach((fn) => fn());
2160
2327
  return Result5.Ok(void 0);
2161
2328
  }
2162
2329
  destroy() {
2163
- return this.gateway.destroy(this.url());
2330
+ this.logger.Debug().Msg("destroy");
2331
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
2164
2332
  }
2165
2333
  };
2166
2334
  var WALStoreImpl = class extends BaseStoreImpl {
2167
- constructor(loader, url, opts) {
2168
- super(loader.name, url, { ...opts }, loader.sthis, ensureLogger(loader.sthis, "WALStoreImpl"));
2335
+ constructor(sthis, url, opts) {
2336
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "WALStoreImpl"));
2169
2337
  this.storeType = "wal";
2338
+ // readonly tag: string = "rwal-base";
2339
+ // readonly loader: Loadable;
2170
2340
  this._ready = new ResolveOnce4();
2171
2341
  this.walState = { operations: [], noLoaderOps: [], fileOperations: [] };
2172
2342
  this.processing = void 0;
2173
2343
  this.processQueue = new CommitQueue();
2174
- this.loader = loader;
2175
2344
  }
2176
2345
  async ready() {
2177
2346
  return this._ready.once(async () => {
2178
2347
  const walState = await this.load().catch((e) => {
2179
- this.logger.Error().Any("error", e).Msg("error loading wal");
2348
+ this.logger.Error().Err(e).Msg("error loading wal");
2180
2349
  return void 0;
2181
2350
  });
2182
- if (!walState) {
2183
- this.walState.operations = [];
2184
- this.walState.fileOperations = [];
2185
- } else {
2186
- this.walState.operations = walState.operations || [];
2187
- this.walState.fileOperations = walState.fileOperations || [];
2351
+ this.walState.operations.splice(0, this.walState.operations.length);
2352
+ this.walState.fileOperations.splice(0, this.walState.fileOperations.length);
2353
+ if (walState) {
2354
+ this.walState.operations.push(...walState.operations);
2355
+ this.walState.fileOperations.push(...walState.fileOperations);
2188
2356
  }
2189
2357
  });
2190
2358
  }
2191
2359
  async enqueue(dbMeta, opts) {
2192
2360
  await this.ready();
2193
2361
  if (opts.compact) {
2194
- this.walState.operations = [];
2195
- this.walState.noLoaderOps = [dbMeta];
2362
+ this.walState.operations.splice(0, this.walState.operations.length);
2363
+ this.walState.noLoaderOps.splice(0, this.walState.noLoaderOps.length);
2364
+ this.walState.noLoaderOps.push(dbMeta);
2196
2365
  } else if (opts.noLoader) {
2197
2366
  this.walState.noLoaderOps.push(dbMeta);
2198
2367
  } else {
@@ -2222,6 +2391,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2222
2391
  });
2223
2392
  }
2224
2393
  async _doProcess() {
2394
+ if (!this.loader) return;
2225
2395
  if (!this.loader.remoteCarStore) return;
2226
2396
  const operations = [...this.walState.operations];
2227
2397
  const noLoaderOps = [...this.walState.noLoaderOps];
@@ -2239,6 +2409,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
2239
2409
  noLoaderOps,
2240
2410
  async (dbMeta) => {
2241
2411
  await retryableUpload(async () => {
2412
+ if (!this.loader) {
2413
+ return;
2414
+ }
2242
2415
  for (const cid of dbMeta.cars) {
2243
2416
  const car = await (await this.loader.carStore()).load(cid);
2244
2417
  if (!car) {
@@ -2249,7 +2422,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2249
2422
  await throwFalsy(this.loader.remoteCarStore).save(car);
2250
2423
  }
2251
2424
  }
2252
- this.walState.noLoaderOps = this.walState.noLoaderOps.filter((op) => op !== dbMeta);
2425
+ inplaceFilter(this.walState.noLoaderOps, (op) => op !== dbMeta);
2253
2426
  }, `noLoaderOp with dbMeta.cars=${dbMeta.cars.toString()}`);
2254
2427
  },
2255
2428
  { concurrency: concurrencyLimit }
@@ -2258,6 +2431,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
2258
2431
  operations,
2259
2432
  async (dbMeta) => {
2260
2433
  await retryableUpload(async () => {
2434
+ if (!this.loader) {
2435
+ return;
2436
+ }
2261
2437
  for (const cid of dbMeta.cars) {
2262
2438
  const car = await (await this.loader.carStore()).load(cid);
2263
2439
  if (!car) {
@@ -2268,7 +2444,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2268
2444
  await throwFalsy(this.loader.remoteCarStore).save(car);
2269
2445
  }
2270
2446
  }
2271
- this.walState.operations = this.walState.operations.filter((op) => op !== dbMeta);
2447
+ inplaceFilter(this.walState.operations, (op) => op !== dbMeta);
2272
2448
  }, `operation with dbMeta.cars=${dbMeta.cars.toString()}`);
2273
2449
  },
2274
2450
  { concurrency: concurrencyLimit }
@@ -2277,12 +2453,15 @@ var WALStoreImpl = class extends BaseStoreImpl {
2277
2453
  fileOperations,
2278
2454
  async ({ cid: fileCid, public: publicFile }) => {
2279
2455
  await retryableUpload(async () => {
2456
+ if (!this.loader) {
2457
+ return;
2458
+ }
2280
2459
  const fileBlock = await (await this.loader.fileStore()).load(fileCid);
2281
2460
  if (!fileBlock) {
2282
2461
  throw this.logger.Error().Ref("cid", fileCid).Msg("missing file block").AsError();
2283
2462
  }
2284
2463
  await this.loader.remoteFileStore?.save(fileBlock, { public: publicFile });
2285
- this.walState.fileOperations = this.walState.fileOperations.filter((op) => op.cid !== fileCid);
2464
+ inplaceFilter(this.walState.fileOperations, (op) => op.cid !== fileCid);
2286
2465
  }, `fileOperation with cid=${fileCid.toString()}`);
2287
2466
  },
2288
2467
  { concurrency: concurrencyLimit }
@@ -2290,6 +2469,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
2290
2469
  if (operations.length) {
2291
2470
  const lastOp = operations[operations.length - 1];
2292
2471
  await retryableUpload(async () => {
2472
+ if (!this.loader) {
2473
+ return;
2474
+ }
2293
2475
  await this.loader.remoteMetaStore?.save(lastOp);
2294
2476
  }, `remoteMetaStore save with dbMeta.cars=${lastOp.cars.toString()}`);
2295
2477
  }
@@ -2302,255 +2484,715 @@ var WALStoreImpl = class extends BaseStoreImpl {
2302
2484
  }
2303
2485
  async load() {
2304
2486
  this.logger.Debug().Msg("loading");
2305
- const filepath = await this.gateway.buildUrl(this.url(), "main");
2487
+ const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
2306
2488
  if (filepath.isErr()) {
2307
2489
  throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
2308
2490
  }
2309
- const bytes = await this.gateway.get(filepath.Ok());
2491
+ const bytes = await this.gateway.get(this.sthis, filepath.Ok(), this.loader);
2310
2492
  if (bytes.isErr()) {
2311
2493
  if (isNotFoundError(bytes)) {
2312
2494
  return void 0;
2313
2495
  }
2314
2496
  throw this.logger.Error().Err(bytes.Err()).Msg("error get").AsError();
2315
2497
  }
2316
- try {
2317
- return bytes && parse2(this.sthis.txt.decode(bytes.Ok()));
2318
- } catch (e) {
2319
- throw this.logger.Error().Err(e).Msg("error parse").AsError();
2498
+ if (bytes.Ok().type !== "wal") {
2499
+ throw this.logger.Error().Str("type", bytes.Ok().type).Msg("unexpected type").AsError();
2320
2500
  }
2501
+ return bytes.Ok().payload;
2321
2502
  }
2322
2503
  async save(state) {
2323
- const filepath = await this.gateway.buildUrl(this.url(), "main");
2504
+ const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
2324
2505
  if (filepath.isErr()) {
2325
2506
  throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
2326
2507
  }
2327
- let encoded;
2328
- try {
2329
- encoded = format2(state);
2330
- } catch (e) {
2331
- throw this.logger.Error().Err(e).Any("state", state).Msg("error format").AsError();
2332
- }
2333
- const res = await this.gateway.put(filepath.Ok(), this.sthis.txt.encode(encoded));
2508
+ const res = await this.gateway.put(
2509
+ this.sthis,
2510
+ filepath.Ok(),
2511
+ {
2512
+ type: "wal",
2513
+ payload: state
2514
+ },
2515
+ this.loader
2516
+ );
2334
2517
  if (res.isErr()) {
2335
2518
  throw this.logger.Error().Err(res.Err()).Str("filePath", filepath.Ok().toString()).Msg("error saving").AsError();
2336
2519
  }
2337
2520
  }
2338
2521
  async close() {
2339
- await this.gateway.close(this.url());
2522
+ await this.gateway.close(this.sthis, this.url(), this.loader);
2340
2523
  this._onClosed.forEach((fn) => fn());
2341
2524
  return Result5.Ok(void 0);
2342
2525
  }
2343
2526
  destroy() {
2344
- return this.gateway.destroy(this.url());
2527
+ this.logger.Debug().Msg("destroy");
2528
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
2345
2529
  }
2346
2530
  };
2347
2531
 
2348
- // src/blockstore/store-factory.ts
2349
- function ensureIsIndex(url, isIndex) {
2350
- if (isIndex) {
2351
- return url.build().setParam("index", isIndex).URI();
2532
+ // src/blockstore/register-store-protocol.ts
2533
+ import { BuildURI, runtimeFn as runtimeFn4 } from "@adviser/cement";
2534
+
2535
+ // src/runtime/gateways/file/version.ts
2536
+ var FILESTORE_VERSION = "v0.19-file";
2537
+
2538
+ // src/runtime/gateways/memory/gateway.ts
2539
+ import { Result as Result6 } from "@adviser/cement";
2540
+
2541
+ // src/runtime/gateways/memory/version.ts
2542
+ var MEMORY_VERSION = "v0.19-memory";
2543
+
2544
+ // src/runtime/gateways/memory/gateway.ts
2545
+ var MemoryGateway = class {
2546
+ constructor(sthis, memorys) {
2547
+ this.memorys = memorys;
2548
+ this.sthis = sthis;
2549
+ }
2550
+ buildUrl(baseUrl, key) {
2551
+ return Promise.resolve(Result6.Ok(baseUrl.build().setParam("key" /* KEY */, key).URI()));
2552
+ }
2553
+ start(baseUrl) {
2554
+ return Promise.resolve(Result6.Ok(baseUrl.build().setParam("version" /* VERSION */, MEMORY_VERSION).URI()));
2555
+ }
2556
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2557
+ close(baseUrl) {
2558
+ return Promise.resolve(Result6.Ok(void 0));
2559
+ }
2560
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
2561
+ destroy(baseUrl) {
2562
+ this.memorys.clear();
2563
+ return Promise.resolve(Result6.Ok(void 0));
2564
+ }
2565
+ async put(url, bytes) {
2566
+ this.memorys.set(url.toString(), bytes);
2567
+ return Result6.Ok(void 0);
2568
+ }
2569
+ // get could return a NotFoundError if the key is not found
2570
+ get(url) {
2571
+ const x = this.memorys.get(url.toString());
2572
+ if (!x) {
2573
+ return Promise.resolve(Result6.Err(new NotFoundError("not found")));
2574
+ }
2575
+ return Promise.resolve(Result6.Ok(x));
2576
+ }
2577
+ delete(url) {
2578
+ this.memorys.delete(url.toString());
2579
+ return Promise.resolve(Result6.Ok(void 0));
2580
+ }
2581
+ async getPlain(url, key) {
2582
+ const x = this.memorys.get(url.build().setParam("key" /* KEY */, key).toString());
2583
+ if (!x) {
2584
+ return Result6.Err(new NotFoundError("not found"));
2585
+ }
2586
+ return Result6.Ok(x);
2587
+ }
2588
+ };
2589
+
2590
+ // src/runtime/index.ts
2591
+ var runtime_exports = {};
2592
+ __export(runtime_exports, {
2593
+ FILESTORE_VERSION: () => FILESTORE_VERSION,
2594
+ INDEXDB_VERSION: () => INDEXDB_VERSION,
2595
+ KeyBag: () => KeyBag,
2596
+ defaultKeyBagOpts: () => defaultKeyBagOpts,
2597
+ defaultKeyBagUrl: () => defaultKeyBagUrl,
2598
+ files: () => files_exports,
2599
+ getFileName: () => getFileName,
2600
+ getKeyBag: () => getKeyBag,
2601
+ getPath: () => getPath,
2602
+ gw: () => gateways_exports,
2603
+ kb: () => key_bag_exports,
2604
+ kc: () => keyed_crypto_exports,
2605
+ mf: () => wait_pr_multiformats_exports,
2606
+ registerKeyBagProviderFactory: () => registerKeyBagProviderFactory,
2607
+ runtimeFn: () => runtimeFn3
2608
+ });
2609
+
2610
+ // src/runtime/gateways/file/utils.ts
2611
+ import { getStore as getStore2 } from "@fireproof/core";
2612
+ function getPath(url, sthis) {
2613
+ const basePath = url.pathname;
2614
+ const name = url.getParam("name");
2615
+ if (name) {
2616
+ return sthis.pathOps.join(basePath, name);
2617
+ }
2618
+ return sthis.pathOps.join(basePath);
2619
+ }
2620
+ function getFileName(url, sthis) {
2621
+ const key = url.getParam("key");
2622
+ if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
2623
+ const res = getStore2(url, sthis, (...a) => a.join("-"));
2624
+ switch (res.store) {
2625
+ case "data":
2626
+ return sthis.pathOps.join(res.name, key + ".car");
2627
+ case "wal":
2628
+ case "meta":
2629
+ return sthis.pathOps.join(res.name, key + ".json");
2630
+ default:
2631
+ throw sthis.logger.Error().Url(url).Msg(`unsupported store type`).AsError();
2632
+ }
2633
+ }
2634
+
2635
+ // src/runtime/wait-pr-multiformats/index.ts
2636
+ var wait_pr_multiformats_exports = {};
2637
+ __export(wait_pr_multiformats_exports, {
2638
+ block: () => block_exports,
2639
+ codec: () => codec_interface_exports
2640
+ });
2641
+
2642
+ // src/runtime/wait-pr-multiformats/codec-interface.ts
2643
+ var codec_interface_exports = {};
2644
+
2645
+ // src/runtime/index.ts
2646
+ import { runtimeFn as runtimeFn3 } from "@adviser/cement";
2647
+
2648
+ // src/runtime/gateways/index.ts
2649
+ var gateways_exports = {};
2650
+ __export(gateways_exports, {
2651
+ file: () => file_exports,
2652
+ fpDeserialize: () => fpDeserialize,
2653
+ fpSerialize: () => fpSerialize
2654
+ });
2655
+
2656
+ // src/runtime/gateways/fp-envelope-serialize.ts
2657
+ import { exception2Result as exception2Result2, Result as Result7 } from "@adviser/cement";
2658
+ import { decodeEventBlock, EventBlock as EventBlock2 } from "@fireproof/vendor/@web3-storage/pail/clock";
2659
+ import { base64pad } from "multiformats/bases/base64";
2660
+ import { CID as CID2 } from "multiformats";
2661
+ import { fromJSON } from "multiformats/link";
2662
+ import { format as format2, parse } from "@fireproof/vendor/@ipld/dag-json";
2663
+ async function dbMetaEvent2Serialized(sthis, dbEvents) {
2664
+ return await Promise.all(
2665
+ dbEvents.map(async (dbEvent) => {
2666
+ const event = await EventBlock2.create(
2667
+ {
2668
+ dbMeta: sthis.txt.encode(format2(dbEvent.dbMeta))
2669
+ },
2670
+ dbEvent.parents
2671
+ );
2672
+ return {
2673
+ cid: event.cid.toString(),
2674
+ parents: dbEvent.parents.map((i) => i.toString()),
2675
+ data: base64pad.encode(event.bytes)
2676
+ };
2677
+ })
2678
+ );
2679
+ }
2680
+ function WALState2Serialized(sthis, wal) {
2681
+ const serializedWAL = {
2682
+ fileOperations: wal.fileOperations.map((fop) => ({
2683
+ cid: fop.cid.toString(),
2684
+ public: fop.public
2685
+ })),
2686
+ noLoaderOps: wal.noLoaderOps.map((nop) => ({
2687
+ cars: nop.cars.map((i) => i.toString())
2688
+ })),
2689
+ operations: wal.operations.map((op) => ({
2690
+ cars: op.cars.map((i) => i.toString())
2691
+ }))
2692
+ };
2693
+ return serializedWAL;
2694
+ }
2695
+ var defaultEncoder = {
2696
+ car: async (sthis, payload) => Result7.Ok(payload),
2697
+ file: async (sthis, payload) => Result7.Ok(payload),
2698
+ meta: async (sthis, payload) => Result7.Ok(sthis.txt.encode(JSON.stringify(payload))),
2699
+ wal: async (sthis, payload) => Result7.Ok(sthis.txt.encode(JSON.stringify(payload)))
2700
+ };
2701
+ async function fpSerialize(sthis, env, pencoder) {
2702
+ const encoder = {
2703
+ ...defaultEncoder,
2704
+ ...pencoder
2705
+ };
2706
+ switch (env.type) {
2707
+ case "file" /* FILE */:
2708
+ return encoder.file(sthis, env.payload);
2709
+ case "car" /* CAR */:
2710
+ return encoder.car(sthis, env.payload);
2711
+ case "wal" /* WAL */:
2712
+ return encoder.wal(sthis, WALState2Serialized(sthis, env.payload));
2713
+ case "meta" /* META */:
2714
+ return encoder.meta(sthis, await dbMetaEvent2Serialized(sthis, env.payload));
2715
+ default:
2716
+ throw sthis.logger.Error().Str("type", env.type).Msg("unsupported store").AsError();
2717
+ }
2718
+ }
2719
+ async function decode2DbMetaEvents(sthis, rserializedMeta) {
2720
+ if (rserializedMeta.isErr()) {
2721
+ return Result7.Err(rserializedMeta.Err());
2722
+ }
2723
+ const serializedMeta = rserializedMeta.unwrap();
2724
+ if (!Array.isArray(serializedMeta)) {
2725
+ return sthis.logger.Debug().Any("metaEntries", serializedMeta).Msg("No data in MetaEntries").ResultError();
2726
+ }
2727
+ if (!serializedMeta.length) {
2728
+ return sthis.logger.Debug().Msg("No MetaEntries found").ResultError();
2729
+ }
2730
+ return Result7.Ok(
2731
+ await Promise.all(
2732
+ serializedMeta.map(async (metaEntry) => {
2733
+ const eventBlock = await decodeEventBlock(base64pad.decode(metaEntry.data));
2734
+ const dbMeta = parse(sthis.txt.decode(eventBlock.value.data.dbMeta));
2735
+ return {
2736
+ eventCid: eventBlock.cid,
2737
+ parents: metaEntry.parents.map((i) => CID2.parse(i)),
2738
+ dbMeta
2739
+ };
2740
+ })
2741
+ )
2742
+ );
2743
+ }
2744
+ function toCid(sthis, link) {
2745
+ if (typeof link === "string") {
2746
+ return CID2.parse(link);
2747
+ }
2748
+ return fromJSON(link);
2749
+ }
2750
+ async function decode2WalState(sthis, rserializedWAL) {
2751
+ if (rserializedWAL.isErr()) {
2752
+ return Result7.Err(rserializedWAL.Err());
2753
+ }
2754
+ const serializedWAL = rserializedWAL.unwrap();
2755
+ return Result7.Ok({
2756
+ fileOperations: (serializedWAL.fileOperations || []).map((fop) => ({
2757
+ cid: toCid(sthis, fop.cid),
2758
+ public: !!fop.public
2759
+ })),
2760
+ noLoaderOps: (serializedWAL.noLoaderOps || []).map((nop) => ({
2761
+ cars: (nop.cars || []).map((i) => toCid(sthis, i))
2762
+ })),
2763
+ operations: (serializedWAL.operations || []).map((op) => ({
2764
+ cars: (op.cars || []).map((i) => toCid(sthis, i))
2765
+ }))
2766
+ });
2767
+ }
2768
+ var defaultDecoder = {
2769
+ car: async (sthis, payload) => Result7.Ok(payload),
2770
+ file: async (sthis, payload) => Result7.Ok(payload),
2771
+ meta: async (sthis, payload) => exception2Result2(() => JSON.parse(sthis.txt.decode(payload))),
2772
+ wal: async (sthis, payload) => exception2Result2(() => JSON.parse(sthis.txt.decode(payload)))
2773
+ };
2774
+ function makeFPEnvelope(type, payload) {
2775
+ if (payload.isErr()) {
2776
+ return Result7.Err(payload.Err());
2777
+ }
2778
+ return Result7.Ok({
2779
+ type,
2780
+ payload: payload.unwrap()
2781
+ });
2782
+ }
2783
+ async function fpDeserialize(sthis, url, intoRaw, pdecoder) {
2784
+ const rraw = await coercePromiseIntoUint8(intoRaw);
2785
+ if (rraw.isErr()) {
2786
+ return Result7.Err(rraw.Err());
2787
+ }
2788
+ const raw2 = rraw.unwrap();
2789
+ const decoder = {
2790
+ ...defaultDecoder,
2791
+ ...pdecoder
2792
+ };
2793
+ switch (url.getParam("store" /* STORE */)) {
2794
+ case "data":
2795
+ if (url.getParam("suffix" /* SUFFIX */) === ".car") {
2796
+ return makeFPEnvelope("car" /* CAR */, await decoder.car(sthis, raw2));
2797
+ }
2798
+ return makeFPEnvelope("file" /* FILE */, await decoder.file(sthis, raw2));
2799
+ case "wal":
2800
+ return makeFPEnvelope("wal" /* WAL */, await decode2WalState(sthis, await decoder.wal(sthis, raw2)));
2801
+ case "meta":
2802
+ return makeFPEnvelope("meta" /* META */, await decode2DbMetaEvents(sthis, await decoder.meta(sthis, raw2)));
2803
+ default:
2804
+ return sthis.logger.Error().Str("store", url.getParam("store" /* STORE */)).Msg("unsupported store").ResultError();
2352
2805
  }
2353
- return url.build().delParam("index").URI();
2354
2806
  }
2355
- function ensureName(name, url) {
2356
- if (!url.hasParam("name")) {
2357
- return url.build().setParam("name", name).URI();
2807
+
2808
+ // src/runtime/gateways/file/index.ts
2809
+ var file_exports = {};
2810
+ __export(file_exports, {
2811
+ KeyBagProviderFile: () => KeyBagProviderFile,
2812
+ sysFileSystemFactory: () => sysFileSystemFactory
2813
+ });
2814
+
2815
+ // src/runtime/gateways/indexdb/version.ts
2816
+ var INDEXDB_VERSION = "v0.19-indexdb";
2817
+
2818
+ // src/runtime/gateways/file/gateway-impl.ts
2819
+ import { exception2Result as exception2Result3, KeyedResolvOnce as KeyedResolvOnce2, Result as Result8 } from "@adviser/cement";
2820
+ var versionFiles = new KeyedResolvOnce2();
2821
+ var FileGateway = class {
2822
+ constructor(sthis, fs) {
2823
+ this.fs = fs;
2824
+ }
2825
+ async getVersionFromFile(path, sthis) {
2826
+ return versionFiles.get(path).once(async () => {
2827
+ await this.fs.mkdir(path, { recursive: true });
2828
+ const vFile = sthis.pathOps.join(path, "version");
2829
+ const vFileStat = await this.fs.stat(vFile).catch(() => void 0);
2830
+ if (!vFileStat) {
2831
+ await this.fs.writefile(sthis.pathOps.join(path, "version"), FILESTORE_VERSION);
2832
+ return FILESTORE_VERSION;
2833
+ } else if (!vFileStat.isFile()) {
2834
+ throw sthis.logger.Error().Str("file", vFile).Msg(`version file is a directory`).AsError();
2835
+ }
2836
+ const v = await this.fs.readfile(vFile);
2837
+ const vStr = sthis.txt.decode(v);
2838
+ if (vStr !== FILESTORE_VERSION) {
2839
+ sthis.logger.Warn().Str("file", vFile).Str("from", vStr).Str("expected", FILESTORE_VERSION).Msg(`version mismatch`);
2840
+ }
2841
+ return vStr;
2842
+ });
2843
+ }
2844
+ start(baseURL, sthis) {
2845
+ return exception2Result3(async () => {
2846
+ await this.fs.start();
2847
+ const url = baseURL.build();
2848
+ url.defParam("version" /* VERSION */, FILESTORE_VERSION);
2849
+ const dbUrl = await this.buildUrl(url.URI(), "dummy");
2850
+ const dbdirFile = this.getFilePath(dbUrl.Ok(), sthis);
2851
+ await this.fs.mkdir(sthis.pathOps.dirname(dbdirFile), { recursive: true });
2852
+ const dbroot = sthis.pathOps.dirname(dbdirFile);
2853
+ sthis.logger.Debug().Url(url.URI()).Str("dbroot", dbroot).Msg("start");
2854
+ url.setParam("version" /* VERSION */, await this.getVersionFromFile(dbroot, sthis));
2855
+ return url.URI();
2856
+ });
2857
+ }
2858
+ async buildUrl(baseUrl, key) {
2859
+ return Result8.Ok(baseUrl.build().setParam("key" /* KEY */, key).URI());
2860
+ }
2861
+ async close() {
2862
+ return Result8.Ok(void 0);
2863
+ }
2864
+ getFilePath(url, sthis) {
2865
+ const key = url.getParam("key" /* KEY */);
2866
+ if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
2867
+ return sthis.pathOps.join(getPath(url, sthis), getFileName(url, sthis));
2868
+ }
2869
+ async put(url, bytes, sthis) {
2870
+ return exception2Result3(async () => {
2871
+ const file = await this.getFilePath(url, sthis);
2872
+ sthis.logger.Debug().Str("url", url.toString()).Str("file", file).Msg("put");
2873
+ await this.fs.writefile(file, bytes);
2874
+ });
2875
+ }
2876
+ async get(url, sthis) {
2877
+ return exceptionWrapper(async () => {
2878
+ const file = this.getFilePath(url, sthis);
2879
+ try {
2880
+ sthis.logger.Debug().Url(url).Str("file", file).Msg("get");
2881
+ const res = await this.fs.readfile(file);
2882
+ return Result8.Ok(res);
2883
+ } catch (e) {
2884
+ if (isNotFoundError(e)) {
2885
+ return Result8.Err(new NotFoundError(`file not found: ${file}`));
2886
+ }
2887
+ return Result8.Err(e);
2888
+ }
2889
+ });
2890
+ }
2891
+ async delete(url, sthis) {
2892
+ return exception2Result3(async () => {
2893
+ await this.fs.unlink(this.getFilePath(url, sthis));
2894
+ });
2895
+ }
2896
+ async destroy(baseURL, sthis) {
2897
+ const url = await this.buildUrl(baseURL, "x");
2898
+ if (url.isErr()) return url;
2899
+ const filepath = sthis.pathOps.dirname(this.getFilePath(url.Ok(), sthis));
2900
+ let files = [];
2901
+ try {
2902
+ files = await this.fs.readdir(filepath);
2903
+ } catch (e) {
2904
+ if (!isNotFoundError(e)) {
2905
+ throw sthis.logger.Error().Err(e).Str("dir", filepath).Msg("destroy:readdir").AsError();
2906
+ }
2907
+ }
2908
+ for (const file of files) {
2909
+ const pathed = sthis.pathOps.join(filepath, file);
2910
+ try {
2911
+ await this.fs.unlink(pathed);
2912
+ } catch (e) {
2913
+ if (!isNotFoundError(e)) {
2914
+ throw sthis.logger.Error().Err(e).Str("file", pathed).Msg("destroy:unlink").AsError();
2915
+ }
2916
+ }
2917
+ }
2918
+ return Result8.Ok(void 0);
2919
+ }
2920
+ async getPlain(iurl, key, sthis) {
2921
+ const url = iurl.build().setParam("key" /* KEY */, key).URI();
2922
+ const dbFile = sthis.pathOps.join(getPath(url, sthis), getFileName(url, sthis));
2923
+ sthis.logger.Debug().Url(url).Str("dbFile", dbFile).Msg("get");
2924
+ const buffer = await this.fs.readfile(dbFile);
2925
+ sthis.logger.Debug().Url(url).Str("dbFile", dbFile).Len(buffer).Msg("got");
2926
+ return Result8.Ok(buffer);
2927
+ }
2928
+ };
2929
+
2930
+ // src/runtime/gateways/def-serde-gateway.ts
2931
+ import { Result as Result9 } from "@adviser/cement";
2932
+ var DefSerdeGateway = class {
2933
+ constructor(gw) {
2934
+ this.gw = gw;
2935
+ }
2936
+ start(sthis, baseURL) {
2937
+ return this.gw.start(baseURL, sthis);
2938
+ }
2939
+ async buildUrl(sthis, baseUrl, key) {
2940
+ return this.gw.buildUrl(baseUrl, key, sthis);
2941
+ }
2942
+ async close(sthis, uri) {
2943
+ return this.gw.close(uri, sthis);
2944
+ }
2945
+ async put(sthis, url, env) {
2946
+ const rUint8 = await fpSerialize(sthis, env);
2947
+ if (rUint8.isErr()) return rUint8;
2948
+ return this.gw.put(url, rUint8.Ok(), sthis);
2949
+ }
2950
+ async get(sthis, url) {
2951
+ const res = await this.gw.get(url, sthis);
2952
+ if (res.isErr()) return Result9.Err(res.Err());
2953
+ return fpDeserialize(sthis, url, res);
2954
+ }
2955
+ async delete(sthis, url) {
2956
+ return this.gw.delete(url, sthis);
2957
+ }
2958
+ async destroy(sthis, baseURL) {
2959
+ return this.gw.destroy(baseURL, sthis);
2960
+ }
2961
+ async getPlain(sthis, iurl, key) {
2962
+ return this.gw.getPlain(iurl, key, sthis);
2358
2963
  }
2359
- return url;
2360
- }
2964
+ };
2965
+
2966
+ // src/blockstore/register-store-protocol.ts
2361
2967
  var storeFactory = /* @__PURE__ */ new Map();
2362
- function buildURL(optURL, loader) {
2363
- const storeOpts = loader.ebOpts.store;
2364
- const obuItem = Array.from(storeFactory.values()).find((items) => items.overrideBaseURL);
2365
- let obuUrl;
2366
- if (obuItem && obuItem.overrideBaseURL) {
2367
- obuUrl = URI6.from(obuItem.overrideBaseURL);
2368
- }
2369
- const ret = ensureIsIndex(
2370
- URI6.from(optURL || obuUrl || dataDir(loader.sthis, loader.name, storeOpts.stores?.base)),
2371
- storeOpts.isIndex
2372
- );
2373
- return ret;
2374
- }
2375
- var onceGateway = new KeyedResolvOnce2();
2376
- async function getGatewayFromURL(url, sthis) {
2377
- return onceGateway.get(url.toString()).once(async () => {
2378
- const item = storeFactory.get(url.protocol);
2379
- if (item) {
2380
- const ret = {
2381
- gateway: await item.gateway(sthis),
2382
- test: await item.test(sthis)
2383
- };
2384
- const res = await ret.gateway.start(url);
2385
- if (res.isErr()) {
2386
- sthis.logger.Error().Result("start", res).Msg("start failed");
2387
- return void 0;
2388
- }
2389
- return ret;
2968
+ function getDefaultURI(sthis, protocol) {
2969
+ if (protocol) {
2970
+ if (!protocol.endsWith(":")) {
2971
+ protocol += ":";
2390
2972
  }
2391
- sthis.logger.Warn().Url(url).Msg("unsupported protocol");
2392
- return void 0;
2393
- });
2973
+ const gfi = storeFactory.get(protocol);
2974
+ if (gfi) {
2975
+ return gfi.defaultURI(sthis);
2976
+ }
2977
+ }
2978
+ const found = Array.from(storeFactory.values()).find((item) => item.isDefault);
2979
+ if (!found) {
2980
+ throw sthis.logger.Error().Msg("no default found").AsError();
2981
+ }
2982
+ return found.defaultURI(sthis);
2394
2983
  }
2395
2984
  function registerStoreProtocol(item) {
2396
2985
  let protocol = item.protocol;
2397
2986
  if (!protocol.endsWith(":")) {
2398
2987
  protocol += ":";
2399
2988
  }
2400
- if (storeFactory.has(protocol)) {
2401
- if (!item.overrideBaseURL && storeFactory.get(protocol) !== item) {
2402
- throw new Error(`we need a logger here`);
2403
- return () => {
2404
- };
2405
- }
2989
+ if (!item.serdegateway && !item.gateway) {
2990
+ throw new Error(`registerStoreProtocol needs a gateway or serdegateway`);
2406
2991
  }
2407
- if (item.overrideBaseURL) {
2992
+ let serdegateway;
2993
+ if (item.gateway) {
2994
+ serdegateway = async (sthis) => {
2995
+ const m = await item.gateway(sthis);
2996
+ return new DefSerdeGateway(m);
2997
+ };
2998
+ } else {
2999
+ serdegateway = item.serdegateway;
3000
+ }
3001
+ if (item.isDefault) {
2408
3002
  Array.from(storeFactory.values()).forEach((items) => {
2409
- items.overrideBaseURL = void 0;
3003
+ items.isDefault = false;
2410
3004
  });
2411
3005
  }
2412
- storeFactory.set(protocol, item);
3006
+ storeFactory.set(protocol, {
3007
+ ...item,
3008
+ serdegateway
3009
+ });
2413
3010
  return () => {
2414
3011
  storeFactory.delete(protocol);
2415
3012
  };
2416
3013
  }
2417
- var onceDataStoreFactory = new KeyedResolvOnce2();
2418
- async function dataStoreFactory(loader) {
2419
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.data, loader)).build().setParam("store", "data").URI();
2420
- const sthis = ensureSuperLog(loader.sthis, "dataStoreFactory", { url: url.toString() });
2421
- return onceDataStoreFactory.get(url.toString()).once(async () => {
2422
- const gateway = await getGatewayFromURL(url, sthis);
2423
- if (!gateway) {
2424
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
3014
+ function getGatewayFactoryItem(protocol) {
3015
+ return storeFactory.get(protocol);
3016
+ }
3017
+ function defaultGatewayFactoryItem() {
3018
+ const found = Array.from(storeFactory.values()).find((item) => item.isDefault);
3019
+ if (!found) {
3020
+ throw new Error("no default found");
3021
+ }
3022
+ return found;
3023
+ }
3024
+ function defaultURI(sthis) {
3025
+ const rt = runtimeFn4();
3026
+ return 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();
3027
+ }
3028
+ if (runtimeFn4().isNodeIsh || runtimeFn4().isDeno) {
3029
+ registerStoreProtocol({
3030
+ protocol: "file:",
3031
+ isDefault: true,
3032
+ defaultURI,
3033
+ gateway: async (sthis) => {
3034
+ return new FileGateway(sthis, await sysFileSystemFactory(defaultURI(sthis)));
2425
3035
  }
2426
- const store = new DataStoreImpl(sthis, loader.name, url, {
2427
- gateway: gateway.gateway,
2428
- keybag: () => getKeyBag(loader.sthis, {
2429
- ...loader.ebOpts.keyBag
2430
- })
2431
- });
2432
- return store;
2433
3036
  });
2434
3037
  }
2435
- var onceMetaStoreFactory = new KeyedResolvOnce2();
2436
- async function metaStoreFactory(loader) {
2437
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.meta, loader)).build().setParam("store", "meta").URI();
2438
- const sthis = ensureSuperLog(loader.sthis, "metaStoreFactory", { url: () => url.toString() });
2439
- return onceMetaStoreFactory.get(url.toString()).once(async () => {
2440
- sthis.logger.Debug().Str("protocol", url.protocol).Msg("pre-protocol switch");
2441
- const gateway = await getGatewayFromURL(url, sthis);
2442
- if (!gateway) {
2443
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2444
- }
2445
- const store = new MetaStoreImpl(loader.sthis, loader.name, url, {
2446
- gateway: gateway.gateway,
2447
- keybag: () => getKeyBag(loader.sthis, {
2448
- ...loader.ebOpts.keyBag
2449
- })
2450
- });
2451
- return store;
3038
+ if (runtimeFn4().isBrowser) {
3039
+ registerStoreProtocol({
3040
+ protocol: "indexdb:",
3041
+ isDefault: true,
3042
+ defaultURI: () => {
3043
+ return BuildURI.from("indexdb://").pathname("fp").setParam("version" /* VERSION */, INDEXDB_VERSION).setParam("runtime" /* RUNTIME */, "browser").URI();
3044
+ },
3045
+ gateway: async () => {
3046
+ const { GatewayImpl } = await import("@fireproof/core/web");
3047
+ return new GatewayImpl();
3048
+ }
2452
3049
  });
2453
3050
  }
2454
- var onceRemoteWalFactory = new KeyedResolvOnce2();
2455
- async function remoteWalFactory(loader) {
2456
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.wal, loader)).build().setParam("store", "wal").URI();
2457
- const sthis = ensureSuperLog(loader.sthis, "remoteWalFactory", { url: url.toString() });
2458
- return onceRemoteWalFactory.get(url.toString()).once(async () => {
2459
- const gateway = await getGatewayFromURL(url, sthis);
2460
- if (!gateway) {
2461
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2462
- }
2463
- sthis.logger.Debug().Str("prepared", url.toString()).Msg("produced");
2464
- const store = new WALStoreImpl(loader, url, {
2465
- gateway: gateway.gateway,
2466
- keybag: () => getKeyBag(loader.sthis, {
2467
- ...loader.ebOpts.keyBag
2468
- })
2469
- });
2470
- return store;
3051
+ var memory = /* @__PURE__ */ new Map();
3052
+ registerStoreProtocol({
3053
+ protocol: "memory:",
3054
+ isDefault: false,
3055
+ defaultURI: () => {
3056
+ return BuildURI.from("memory://").pathname("ram").URI();
3057
+ },
3058
+ gateway: async (sthis) => {
3059
+ return new MemoryGateway(sthis, memory);
3060
+ }
3061
+ });
3062
+
3063
+ // src/blockstore/store-factory.ts
3064
+ var onceGateway = new KeyedResolvOnce3();
3065
+ var gatewayInstances = new KeyedResolvOnce3();
3066
+ async function getStartedGateway(sthis, url) {
3067
+ return onceGateway.get(url.toString()).once(async () => {
3068
+ const item = getGatewayFactoryItem(url.protocol);
3069
+ if (item) {
3070
+ const ret = {
3071
+ url,
3072
+ ...await gatewayInstances.get(url.protocol).once(async () => ({})),
3073
+ gateway: await item.serdegateway(sthis)
3074
+ };
3075
+ const res = await ret.gateway.start(sthis, url);
3076
+ if (res.isErr()) {
3077
+ return Result10.Err(sthis.logger.Error().Result("start", res).Msg("start failed").AsError());
3078
+ }
3079
+ ret.url = res.Ok();
3080
+ return Result10.Ok(ret);
3081
+ }
3082
+ return Result10.Err(sthis.logger.Warn().Url(url).Msg("unsupported protocol").AsError());
2471
3083
  });
2472
3084
  }
2473
- async function testStoreFactory(url, sthis) {
2474
- sthis = ensureSuperLog(sthis, "testStoreFactory");
2475
- const gateway = await getGatewayFromURL(url, sthis);
2476
- if (!gateway) {
2477
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2478
- }
2479
- return gateway.test;
3085
+ async function dataStoreFactory(sfi) {
3086
+ const storeUrl = sfi.url.build().setParam("store" /* STORE */, "data").URI();
3087
+ const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
3088
+ if (rgateway.isErr()) {
3089
+ throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
3090
+ }
3091
+ const gateway = rgateway.Ok();
3092
+ const store = new DataStoreImpl(sfi.sthis, gateway.url, {
3093
+ gateway: gateway.gateway,
3094
+ gatewayInterceptor: sfi.gatewayInterceptor,
3095
+ loader: sfi.loader
3096
+ });
3097
+ return store;
3098
+ }
3099
+ async function metaStoreFactory(sfi) {
3100
+ const storeUrl = sfi.url.build().setParam("store" /* STORE */, "meta").URI();
3101
+ const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
3102
+ if (rgateway.isErr()) {
3103
+ throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
3104
+ }
3105
+ const gateway = rgateway.Ok();
3106
+ const store = new MetaStoreImpl(sfi.sthis, gateway.url, {
3107
+ gateway: gateway.gateway,
3108
+ gatewayInterceptor: sfi.gatewayInterceptor,
3109
+ loader: sfi.loader
3110
+ });
3111
+ return store;
3112
+ }
3113
+ async function WALStoreFactory(sfi) {
3114
+ const storeUrl = sfi.url.build().setParam("store" /* STORE */, "wal").URI();
3115
+ const rgateway = await getStartedGateway(sfi.sthis, storeUrl);
3116
+ if (rgateway.isErr()) {
3117
+ throw sfi.sthis.logger.Error().Result("err", rgateway).Url(sfi.url).Msg("notfound").AsError();
3118
+ }
3119
+ const gateway = rgateway.Ok();
3120
+ const store = new WALStoreImpl(sfi.sthis, gateway.url, {
3121
+ gateway: gateway.gateway,
3122
+ gatewayInterceptor: sfi.gatewayInterceptor,
3123
+ loader: sfi.loader
3124
+ });
3125
+ return store;
2480
3126
  }
2481
- async function ensureStart(store, logger) {
3127
+ async function ensureStart(store) {
2482
3128
  const ret = await store.start();
2483
3129
  if (ret.isErr()) {
2484
- throw logger.Error().Result("start", ret).Msg("start failed").AsError();
3130
+ throw store.logger.Error().Result("start", ret).Msg("start failed").AsError();
2485
3131
  }
2486
- logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
3132
+ store.logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
2487
3133
  return store;
2488
3134
  }
2489
- function toStoreRuntime(opts, sthis) {
2490
- const logger = ensureLogger(sthis, "toStoreRuntime", {});
3135
+ function ensureStoreEnDeFile(ende) {
3136
+ ende = ende || {};
2491
3137
  return {
2492
- makeMetaStore: async (loader) => {
2493
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeMetaStore).Msg("makeMetaStore");
2494
- return ensureStart(await (loader.ebOpts.store.makeMetaStore || metaStoreFactory)(loader), logger);
2495
- },
2496
- makeDataStore: async (loader) => {
2497
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeDataStore).Msg("makeDataStore");
2498
- return ensureStart(await (loader.ebOpts.store.makeDataStore || dataStoreFactory)(loader), logger);
2499
- },
2500
- makeWALStore: async (loader) => {
2501
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeWALStore).Msg("makeRemoteWAL");
2502
- return ensureStart(await (loader.ebOpts.store.makeWALStore || remoteWalFactory)(loader), logger);
2503
- },
2504
- encodeFile: opts.encodeFile || encodeFile,
2505
- decodeFile: opts.decodeFile || decodeFile
3138
+ encodeFile: ende.encodeFile || encodeFile,
3139
+ decodeFile: ende.decodeFile || decodeFile
2506
3140
  };
2507
3141
  }
2508
- if (runtimeFn3().isNodeIsh || runtimeFn3().isDeno) {
2509
- registerStoreProtocol({
2510
- protocol: "file:",
2511
- gateway: async (sthis) => {
2512
- const { GatewayImpl } = await import("@fireproof/core/node");
2513
- return new GatewayImpl(sthis);
2514
- },
2515
- test: async (sthis) => {
2516
- const { GatewayTestImpl } = await import("@fireproof/core/node");
2517
- return new GatewayTestImpl(sthis);
2518
- }
2519
- });
2520
- }
2521
- if (runtimeFn3().isBrowser) {
2522
- registerStoreProtocol({
2523
- protocol: "indexdb:",
2524
- gateway: async (sthis) => {
2525
- const { GatewayImpl } = await import("@fireproof/core/web");
2526
- return new GatewayImpl(sthis);
2527
- },
2528
- test: async (sthis) => {
2529
- const { GatewayTestImpl } = await import("@fireproof/core/web");
2530
- return new GatewayTestImpl(sthis);
2531
- }
2532
- });
3142
+ function toStoreRuntime(sthis, endeOpts = {}) {
3143
+ return {
3144
+ makeMetaStore: async (sfi) => ensureStart(await metaStoreFactory(sfi)),
3145
+ // async (loader: Loadable) => {
3146
+ // logger
3147
+ // .Debug()
3148
+ // .Str("fromOpts", "" + !!endeOpts.func?.makeMetaStore)
3149
+ // .Msg("makeMetaStore");
3150
+ // return ensureStart(await (endeOpts.func?.makeMetaStore || metaStoreFactory)(loader), logger);
3151
+ // },
3152
+ makeDataStore: async (sfi) => ensureStart(await dataStoreFactory(sfi)),
3153
+ // async (loader: Loadable) => {
3154
+ // logger
3155
+ // .Debug()
3156
+ // .Str("fromOpts", "" + !!endeOpts.func?.makeDataStore)
3157
+ // .Msg("makeDataStore");
3158
+ // return ensureStart(await (endeOpts.func?.makeDataStore || dataStoreFactory)(loader), logger);
3159
+ // },
3160
+ makeWALStore: async (sfi) => ensureStart(await WALStoreFactory(sfi)),
3161
+ // async (loader: Loadable) => {
3162
+ // logger
3163
+ // .Debug()
3164
+ // .Str("fromOpts", "" + !!endeOpts.func?.makeWALStore)
3165
+ // .Msg("makeRemoteWAL");
3166
+ // return ensureStart(await (endeOpts.func?.makeWALStore || remoteWalFactory)(loader), logger);
3167
+ // },
3168
+ ...ensureStoreEnDeFile(endeOpts)
3169
+ };
2533
3170
  }
2534
3171
 
2535
3172
  // src/blockstore/store-remote.ts
2536
- async function RemoteDataStore(sthis, name, url, opts) {
2537
- const ds = new DataStoreImpl(sthis, name, url, opts);
3173
+ async function RemoteDataStore(sthis, url, opts) {
3174
+ const ds = new DataStoreImpl(sthis, url, opts);
2538
3175
  await ds.start();
2539
3176
  return ds;
2540
3177
  }
2541
- async function RemoteMetaStore(sthis, name, url, opts) {
2542
- const ms = new MetaStoreImpl(
2543
- sthis,
2544
- name,
2545
- url,
2546
- opts
2547
- /* , true*/
2548
- );
3178
+ async function RemoteMetaStore(sthis, url, opts) {
3179
+ const ms = new MetaStoreImpl(sthis, url, opts);
2549
3180
  await ms.start();
2550
3181
  return ms;
2551
3182
  }
2552
3183
 
2553
3184
  // src/blockstore/connection-base.ts
3185
+ function coerceLoader(ref) {
3186
+ const refl = ref;
3187
+ if (refl.loader) {
3188
+ return refl.loader;
3189
+ }
3190
+ const refb = ref;
3191
+ if (refb.blockstore) {
3192
+ return coerceLoader(refb.blockstore);
3193
+ }
3194
+ return void 0;
3195
+ }
2554
3196
  var ConnectionBase = class {
2555
3197
  constructor(url, logger) {
2556
3198
  this.loaded = Promise.resolve();
@@ -2561,23 +3203,26 @@ var ConnectionBase = class {
2561
3203
  await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load();
2562
3204
  await (await throwFalsy(this.loader).WALStore()).process();
2563
3205
  }
2564
- async connect_X({ loader }) {
2565
- if (!loader) throw this.logger.Error().Msg("loader is required").AsError();
2566
- await this.connectMeta_X({ loader });
2567
- await this.connectStorage_X({ loader });
3206
+ async connect(refl) {
3207
+ await this.connectMeta(refl);
3208
+ await this.connectStorage(refl);
2568
3209
  }
2569
- async connectMeta_X({ loader }) {
2570
- if (!loader) throw this.logger.Error().Msg("connectMeta_X: loader is required").AsError();
3210
+ async connectMeta(refl) {
3211
+ const loader = coerceLoader(refl);
3212
+ if (!loader) throw this.logger.Error().Msg("connectMeta: loader is required").AsError();
2571
3213
  this.loader = loader;
2572
3214
  await this.onConnect();
2573
- const metaUrl = this.url.build().defParam("store", "meta").URI();
2574
- const gateway = await getGatewayFromURL(metaUrl, this.loader.sthis);
2575
- if (!gateway) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: gateway is required").AsError();
2576
- const dbName = metaUrl.getParam("name");
2577
- if (!dbName) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: name is required").AsError();
2578
- const remote = await RemoteMetaStore(loader.sthis, dbName, metaUrl, {
3215
+ const metaUrl = this.url.build().defParam("store" /* STORE */, "meta").URI();
3216
+ const rgateway = await getStartedGateway(loader.sthis, metaUrl);
3217
+ if (rgateway.isErr())
3218
+ throw this.logger.Error().Result("err", rgateway).Url(metaUrl).Msg("connectMeta: gateway is required").AsError();
3219
+ const dbName = metaUrl.getParam("name" /* NAME */);
3220
+ if (!dbName) {
3221
+ throw this.logger.Error().Url(metaUrl).Msg("connectMeta: dbName is required").AsError();
3222
+ }
3223
+ const gateway = rgateway.Ok();
3224
+ const remote = await RemoteMetaStore(loader.sthis, metaUrl, {
2579
3225
  gateway: gateway.gateway,
2580
- keybag: () => getKeyBag(loader.sthis, loader.ebOpts.keyBag),
2581
3226
  loader
2582
3227
  });
2583
3228
  this.loader.remoteMetaStore = remote;
@@ -2587,17 +3232,19 @@ var ConnectionBase = class {
2587
3232
  });
2588
3233
  });
2589
3234
  }
2590
- async connectStorage_X({ loader }) {
3235
+ async connectStorage(refl) {
3236
+ const loader = coerceLoader(refl);
2591
3237
  if (!loader) throw this.logger.Error().Msg("connectStorage_X: loader is required").AsError();
2592
3238
  this.loader = loader;
2593
- const dataUrl = this.url.build().defParam("store", "data").URI();
2594
- const gateway = await getGatewayFromURL(dataUrl, this.loader.sthis);
2595
- if (!gateway) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: gateway is required").AsError();
2596
- const name = dataUrl.getParam("name");
3239
+ const dataUrl = this.url.build().defParam("store" /* STORE */, "data").URI();
3240
+ const rgateway = await getStartedGateway(loader.sthis, dataUrl);
3241
+ if (rgateway.isErr())
3242
+ throw this.logger.Error().Result("err", rgateway).Url(dataUrl).Msg("connectStorage_X: gateway is required").AsError();
3243
+ const name = dataUrl.getParam("name" /* NAME */);
2597
3244
  if (!name) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: name is required").AsError;
2598
- loader.remoteCarStore = await RemoteDataStore(loader.sthis, name, this.url, {
2599
- gateway: gateway.gateway,
2600
- keybag: () => getKeyBag(loader.sthis, this.loader?.ebOpts.keyBag)
3245
+ loader.remoteCarStore = await RemoteDataStore(loader.sthis, this.url, {
3246
+ gateway: rgateway.Ok().gateway,
3247
+ loader
2601
3248
  });
2602
3249
  loader.remoteFileStore = loader.remoteCarStore;
2603
3250
  }
@@ -2637,6 +3284,12 @@ var ConnectionBase = class {
2637
3284
  };
2638
3285
 
2639
3286
  // src/crdt-helpers.ts
3287
+ import { parse as parse2 } from "multiformats/link";
3288
+ import { sha256 as hasher5 } from "multiformats/hashes/sha2";
3289
+ import * as codec from "@fireproof/vendor/@ipld/dag-cbor";
3290
+ import { put, get, entries, root } from "@fireproof/vendor/@web3-storage/pail/crdt";
3291
+ import { EventFetcher, vis } from "@fireproof/vendor/@web3-storage/pail/clock";
3292
+ import * as Batch from "@fireproof/vendor/@web3-storage/pail/crdt/batch";
2640
3293
  function time(tag) {
2641
3294
  }
2642
3295
  function timeEnd(tag) {
@@ -2894,7 +3547,7 @@ async function doCompact(blockLog, head, logger) {
2894
3547
  isCompacting = false;
2895
3548
  }
2896
3549
  async function getBlock(blocks, cidString) {
2897
- const block = await blocks.get(parse3(cidString));
3550
+ const block = await blocks.get(parse2(cidString));
2898
3551
  if (!block) throw new Error(`Missing block ${cidString}`);
2899
3552
  const { cid, value } = await decode({ bytes: block.bytes, codec, hasher: hasher5 });
2900
3553
  return new Block({ cid, value, bytes: block.bytes });
@@ -2954,7 +3607,8 @@ function makeProllyGetBlock(blocks) {
2954
3607
  return create({ cid, bytes, hasher: hasher6, codec: codec2 });
2955
3608
  };
2956
3609
  }
2957
- async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
3610
+ async function bulkIndex(logger, tblocks, inIndex, indexEntries, opts) {
3611
+ logger.Debug().Msg("enter bulkIndex");
2958
3612
  if (!indexEntries.length) return inIndex;
2959
3613
  if (!inIndex.root) {
2960
3614
  if (!inIndex.cid) {
@@ -2971,18 +3625,22 @@ async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
2971
3625
  returnNode = node;
2972
3626
  }
2973
3627
  if (!returnNode || !returnRootBlock) throw new Error("failed to create index");
3628
+ logger.Debug().Msg("exit !root bulkIndex");
2974
3629
  return { root: returnNode, cid: returnRootBlock.cid };
2975
3630
  } else {
2976
3631
  inIndex.root = await DbIndex.load({ cid: inIndex.cid, get: makeProllyGetBlock(tblocks), ...opts });
2977
3632
  }
2978
3633
  }
3634
+ logger.Debug().Msg("pre bulk bulkIndex");
2979
3635
  const { root: root3, blocks: newBlocks } = await inIndex.root.bulk(indexEntries);
2980
3636
  if (root3) {
3637
+ logger.Debug().Msg("pre root put bulkIndex");
2981
3638
  for await (const block of newBlocks) {
2982
3639
  await tblocks.put(block.cid, block.bytes);
2983
3640
  }
2984
3641
  return { root: root3, cid: (await root3.block).cid };
2985
3642
  } else {
3643
+ logger.Debug().Msg("pre !root bulkIndex");
2986
3644
  return { root: void 0, cid: void 0 };
2987
3645
  }
2988
3646
  }
@@ -3022,17 +3680,17 @@ function encodeKey(key) {
3022
3680
  }
3023
3681
 
3024
3682
  // src/indexer.ts
3025
- function index(sthis, { _crdt }, name, mapFn, meta) {
3026
- if (mapFn && meta) throw _crdt.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
3027
- if (mapFn && mapFn.constructor.name !== "Function") throw _crdt.logger.Error().Msg("mapFn must be a function").AsError();
3028
- if (_crdt.indexers.has(name)) {
3029
- const idx = _crdt.indexers.get(name);
3683
+ function index(refDb, name, mapFn, meta) {
3684
+ if (mapFn && meta) throw refDb.crdt.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
3685
+ if (mapFn && mapFn.constructor.name !== "Function") throw refDb.crdt.logger.Error().Msg("mapFn must be a function").AsError();
3686
+ if (refDb.crdt.indexers.has(name)) {
3687
+ const idx = refDb.crdt.indexers.get(name);
3030
3688
  idx.applyMapFn(name, mapFn, meta);
3031
3689
  } else {
3032
- const idx = new Index(sthis, _crdt, name, mapFn, meta);
3033
- _crdt.indexers.set(name, idx);
3690
+ const idx = new Index(refDb.crdt.sthis, refDb.crdt, name, mapFn, meta);
3691
+ refDb.crdt.indexers.set(name, idx);
3034
3692
  }
3035
- return _crdt.indexers.get(name);
3693
+ return refDb.crdt.indexers.get(name);
3036
3694
  }
3037
3695
  var Index = class {
3038
3696
  constructor(sthis, crdt, name, mapFn, meta) {
@@ -3051,18 +3709,9 @@ var Index = class {
3051
3709
  return Promise.all([this.blockstore.ready(), this.crdt.ready()]).then(() => {
3052
3710
  });
3053
3711
  }
3054
- close() {
3055
- return Promise.all([this.blockstore.close(), this.crdt.close()]).then(() => {
3056
- });
3057
- }
3058
- destroy() {
3059
- return Promise.all([this.blockstore.destroy(), this.crdt.destroy()]).then(() => {
3060
- });
3061
- }
3062
3712
  applyMapFn(name, mapFn, meta) {
3063
3713
  if (mapFn && meta) throw this.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
3064
3714
  if (this.name && this.name !== name) throw this.logger.Error().Msg("cannot change name").AsError();
3065
- this.name = name;
3066
3715
  try {
3067
3716
  if (meta) {
3068
3717
  if (this.indexHead && this.indexHead.map((c) => c.toString()).join() !== meta.head.map((c) => c.toString()).join()) {
@@ -3110,9 +3759,13 @@ var Index = class {
3110
3759
  }
3111
3760
  }
3112
3761
  async query(opts = {}) {
3762
+ this.logger.Debug().Msg("enter query");
3113
3763
  await this.ready();
3764
+ this.logger.Debug().Msg("post ready query");
3114
3765
  await this._updateIndex();
3766
+ this.logger.Debug().Msg("post _updateIndex query");
3115
3767
  await this._hydrateIndex();
3768
+ this.logger.Debug().Msg("post _hydrateIndex query");
3116
3769
  if (!this.byKey.root) {
3117
3770
  return await applyQuery(this.crdt, { result: [] }, opts);
3118
3771
  }
@@ -3168,13 +3821,16 @@ var Index = class {
3168
3821
  }
3169
3822
  async _updateIndex() {
3170
3823
  await this.ready();
3824
+ this.logger.Debug().Msg("enter _updateIndex");
3171
3825
  if (this.initError) throw this.initError;
3172
3826
  if (!this.mapFn) throw this.logger.Error().Msg("No map function defined").AsError();
3173
3827
  let result, head;
3174
3828
  if (!this.indexHead || this.indexHead.length === 0) {
3175
3829
  ({ result, head } = await this.crdt.allDocs());
3830
+ this.logger.Debug().Msg("enter crdt.allDocs");
3176
3831
  } else {
3177
3832
  ({ result, head } = await this.crdt.changes(this.indexHead));
3833
+ this.logger.Debug().Msg("enter crdt.changes");
3178
3834
  }
3179
3835
  if (result.length === 0) {
3180
3836
  this.indexHead = head;
@@ -3207,9 +3863,22 @@ var Index = class {
3207
3863
  if (result.length === 0) {
3208
3864
  return indexerMeta;
3209
3865
  }
3866
+ this.logger.Debug().Msg("pre this.blockstore.transaction");
3210
3867
  const { meta } = await this.blockstore.transaction(async (tblocks) => {
3211
- this.byId = await bulkIndex(tblocks, this.byId, removeIdIndexEntries.concat(byIdIndexEntries), byIdOpts);
3212
- this.byKey = await bulkIndex(tblocks, this.byKey, staleKeyIndexEntries.concat(indexEntries), byKeyOpts);
3868
+ this.byId = await bulkIndex(
3869
+ this.logger,
3870
+ tblocks,
3871
+ this.byId,
3872
+ removeIdIndexEntries.concat(byIdIndexEntries),
3873
+ byIdOpts
3874
+ );
3875
+ this.byKey = await bulkIndex(
3876
+ this.logger,
3877
+ tblocks,
3878
+ this.byKey,
3879
+ staleKeyIndexEntries.concat(indexEntries),
3880
+ byKeyOpts
3881
+ );
3213
3882
  this.indexHead = head;
3214
3883
  if (this.byId.cid && this.byKey.cid) {
3215
3884
  const idxMeta = {
@@ -3221,8 +3890,10 @@ var Index = class {
3221
3890
  };
3222
3891
  indexerMeta.indexes?.set(this.name, idxMeta);
3223
3892
  }
3893
+ this.logger.Debug().Any("indexerMeta", new Array(indexerMeta.indexes?.entries())).Msg("exit this.blockstore.transaction fn");
3224
3894
  return indexerMeta;
3225
3895
  });
3896
+ this.logger.Debug().Msg("post this.blockstore.transaction");
3226
3897
  return meta;
3227
3898
  }
3228
3899
  };
@@ -3398,15 +4069,13 @@ async function advanceBlocks(logger, newHead, tblocks, head) {
3398
4069
 
3399
4070
  // src/crdt.ts
3400
4071
  var CRDT = class {
3401
- constructor(sthis, name, opts = {}) {
4072
+ constructor(sthis, opts) {
3402
4073
  this.indexers = /* @__PURE__ */ new Map();
3403
4074
  this.onceReady = new ResolveOnce6();
3404
4075
  this.sthis = sthis;
3405
- this.name = name;
3406
4076
  this.logger = ensureLogger(sthis, "CRDT");
3407
4077
  this.opts = opts;
3408
- this.blockstore = blockstoreFactory(sthis, {
3409
- name,
4078
+ this.blockstore = new EncryptedBlockstore(sthis, {
3410
4079
  applyMeta: async (meta) => {
3411
4080
  const crdtMeta = meta;
3412
4081
  if (!crdtMeta.head) throw this.logger.Error().Msg("missing head").AsError();
@@ -3416,23 +4085,29 @@ var CRDT = class {
3416
4085
  await doCompact(blocks, this.clock.head, this.logger);
3417
4086
  return { head: this.clock.head };
3418
4087
  },
3419
- autoCompact: this.opts.autoCompact || 100,
3420
- store: { ...this.opts.store, isIndex: void 0 },
3421
- public: this.opts.public,
3422
- meta: this.opts.meta,
3423
- threshold: this.opts.threshold
4088
+ gatewayInterceptor: opts.gatewayInterceptor,
4089
+ // autoCompact: this.opts.autoCompact || 100,
4090
+ storeRuntime: toStoreRuntime(this.sthis, this.opts.storeEnDe),
4091
+ storeUrls: this.opts.storeUrls.data,
4092
+ keyBag: this.opts.keyBag,
4093
+ // public: this.opts.public,
4094
+ meta: this.opts.meta
4095
+ // threshold: this.opts.threshold,
3424
4096
  });
3425
- this.indexBlockstore = blockstoreFactory(sthis, {
3426
- name,
4097
+ this.indexBlockstore = new EncryptedBlockstore(sthis, {
4098
+ // name: opts.name,
3427
4099
  applyMeta: async (meta) => {
3428
4100
  const idxCarMeta = meta;
3429
4101
  if (!idxCarMeta.indexes) throw this.logger.Error().Msg("missing indexes").AsError();
3430
- for (const [name2, idx] of Object.entries(idxCarMeta.indexes)) {
3431
- index(this.sthis, { _crdt: this }, name2, void 0, idx);
4102
+ for (const [name, idx] of Object.entries(idxCarMeta.indexes)) {
4103
+ index({ crdt: this }, name, void 0, idx);
3432
4104
  }
3433
4105
  },
3434
- store: { ...this.opts.store, isIndex: this.opts.store?.isIndex || "idx" },
3435
- public: this.opts.public
4106
+ gatewayInterceptor: opts.gatewayInterceptor,
4107
+ storeRuntime: toStoreRuntime(this.sthis, this.opts.storeEnDe),
4108
+ storeUrls: this.opts.storeUrls.idx,
4109
+ keyBag: this.opts.keyBag
4110
+ // public: this.opts.public,
3436
4111
  });
3437
4112
  this.clock = new CRDTClock(this.blockstore);
3438
4113
  this.clock.onZoom(() => {
@@ -3514,74 +4189,168 @@ var CRDT = class {
3514
4189
  };
3515
4190
 
3516
4191
  // src/database.ts
3517
- var Database = class {
3518
- constructor(name, opts) {
3519
- this.opts = {};
4192
+ var databases = new KeyedResolvOnce4();
4193
+ function keyConfigOpts(sthis, name, opts) {
4194
+ return JSON.stringify(
4195
+ toSortedArray({
4196
+ name,
4197
+ stores: toSortedArray(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, name, opts?.storeUrls))))
4198
+ })
4199
+ );
4200
+ }
4201
+ function isDatabase(db) {
4202
+ return db instanceof DatabaseImpl || db instanceof DatabaseShell;
4203
+ }
4204
+ function DatabaseFactory(name, opts) {
4205
+ const sthis = ensureSuperThis(opts);
4206
+ return new DatabaseShell(
4207
+ databases.get(keyConfigOpts(sthis, name, opts)).once((key) => {
4208
+ const db = new DatabaseImpl(sthis, {
4209
+ name,
4210
+ meta: opts?.meta,
4211
+ keyBag: defaultKeyBagOpts(sthis, opts?.keyBag),
4212
+ storeUrls: toStoreURIRuntime(sthis, name, opts?.storeUrls),
4213
+ gatewayInterceptor: opts?.gatewayInterceptor,
4214
+ writeQueue: defaultWriteQueueOpts(opts?.writeQueue),
4215
+ storeEnDe: {
4216
+ encodeFile,
4217
+ decodeFile,
4218
+ ...opts?.storeEnDe
4219
+ }
4220
+ });
4221
+ db.onClosed(() => {
4222
+ databases.unget(key);
4223
+ });
4224
+ return db;
4225
+ })
4226
+ );
4227
+ }
4228
+ var DatabaseShell = class {
4229
+ constructor(ref) {
4230
+ this.ref = ref;
4231
+ ref.addShell(this);
4232
+ }
4233
+ get id() {
4234
+ return this.ref.id;
4235
+ }
4236
+ get logger() {
4237
+ return this.ref.logger;
4238
+ }
4239
+ get sthis() {
4240
+ return this.ref.sthis;
4241
+ }
4242
+ get crdt() {
4243
+ return this.ref.crdt;
4244
+ }
4245
+ get name() {
4246
+ return this.ref.name;
4247
+ }
4248
+ onClosed(fn) {
4249
+ return this.ref.onClosed(fn);
4250
+ }
4251
+ close() {
4252
+ return this.ref.shellClose(this);
4253
+ }
4254
+ destroy() {
4255
+ return this.ref.destroy();
4256
+ }
4257
+ ready() {
4258
+ return this.ref.ready();
4259
+ }
4260
+ get(id) {
4261
+ return this.ref.get(id);
4262
+ }
4263
+ put(doc) {
4264
+ return this.ref.put(doc);
4265
+ }
4266
+ bulk(docs) {
4267
+ return this.ref.bulk(docs);
4268
+ }
4269
+ del(id) {
4270
+ return this.ref.del(id);
4271
+ }
4272
+ changes(since, opts) {
4273
+ return this.ref.changes(since, opts);
4274
+ }
4275
+ allDocs(opts) {
4276
+ return this.ref.allDocs(opts);
4277
+ }
4278
+ allDocuments() {
4279
+ return this.ref.allDocuments();
4280
+ }
4281
+ subscribe(listener, updates) {
4282
+ return this.ref.subscribe(listener, updates);
4283
+ }
4284
+ query(field, opts) {
4285
+ return this.ref.query(field, opts);
4286
+ }
4287
+ compact() {
4288
+ return this.ref.compact();
4289
+ }
4290
+ };
4291
+ var DatabaseImpl = class {
4292
+ constructor(sthis, opts) {
3520
4293
  this._listening = false;
3521
4294
  this._listeners = /* @__PURE__ */ new Set();
3522
4295
  this._noupdate_listeners = /* @__PURE__ */ new Set();
4296
+ // readonly blockstore: BaseBlockstore;
4297
+ this.shells = /* @__PURE__ */ new Set();
4298
+ this._onClosedFns = /* @__PURE__ */ new Set();
3523
4299
  this._ready = new ResolveOnce7();
3524
- this.name = name;
3525
- this.opts = opts || this.opts;
3526
- this.sthis = ensureSuperThis(this.opts);
4300
+ this.opts = opts;
4301
+ this.sthis = sthis;
4302
+ this.id = sthis.timeOrderedNextId().str;
3527
4303
  this.logger = ensureLogger(this.sthis, "Database");
3528
- this._crdt = new CRDT(this.sthis, name, this.opts);
3529
- this.blockstore = this._crdt.blockstore;
3530
- this._writeQueue = writeQueue(async (updates) => {
3531
- return await this._crdt.bulk(updates);
3532
- });
3533
- this._crdt.clock.onTock(() => {
3534
- this._no_update_notify();
3535
- });
4304
+ this.crdt = new CRDT(this.sthis, this.opts);
4305
+ this._writeQueue = writeQueue(this.sthis, async (updates) => this.crdt.bulk(updates), this.opts.writeQueue);
4306
+ this.crdt.clock.onTock(() => this._no_update_notify());
4307
+ }
4308
+ addShell(shell) {
4309
+ this.shells.add(shell);
3536
4310
  }
3537
- static {
3538
- this.databases = /* @__PURE__ */ new Map();
4311
+ onClosed(fn) {
4312
+ this._onClosedFns.add(fn);
3539
4313
  }
3540
- /**
3541
- * Close the database and release resources
3542
- */
3543
4314
  async close() {
3544
- await this.ready();
3545
- await this._crdt.close();
3546
- await this.blockstore.close();
4315
+ throw this.logger.Error().Str("db", this.name).Msg(`use shellClose`).AsError();
4316
+ }
4317
+ async shellClose(db) {
4318
+ if (!this.shells.has(db)) {
4319
+ throw this.logger.Error().Str("db", this.name).Msg(`DatabaseShell mismatch`).AsError();
4320
+ }
4321
+ this.shells.delete(db);
4322
+ if (this.shells.size === 0) {
4323
+ await this.ready();
4324
+ await this.crdt.close();
4325
+ await this._writeQueue.close();
4326
+ this._onClosedFns.forEach((fn) => fn());
4327
+ }
3547
4328
  }
3548
- /**
3549
- * Destroy the database and release all resources
3550
- */
3551
4329
  async destroy() {
3552
4330
  await this.ready();
3553
- await this._crdt.destroy();
3554
- await this.blockstore.destroy();
4331
+ await this.crdt.destroy();
3555
4332
  }
3556
4333
  async ready() {
3557
- return this._ready.once(async () => {
4334
+ const ret = await this._ready.once(async () => {
3558
4335
  await this.sthis.start();
3559
- await this._crdt.ready();
3560
- await this.blockstore.ready();
4336
+ await this.crdt.ready();
3561
4337
  });
4338
+ return ret;
4339
+ }
4340
+ get name() {
4341
+ return this.opts.storeUrls.data.data.getParam("name" /* NAME */) || "default";
3562
4342
  }
3563
- /**
3564
- * Get a document from the database
3565
- * @param id - the document id
3566
- * @returns the document with the _id
3567
- * @throws NotFoundError if the document is not found
3568
- */
3569
4343
  async get(id) {
3570
4344
  if (!id) throw this.logger.Error().Str("db", this.name).Msg(`Doc id is required`).AsError();
3571
4345
  await this.ready();
3572
4346
  this.logger.Debug().Str("id", id).Msg("get");
3573
- const got = await this._crdt.get(id).catch((e) => {
4347
+ const got = await this.crdt.get(id).catch((e) => {
3574
4348
  throw new NotFoundError(`Not found: ${id} - ${e.message}`);
3575
4349
  });
3576
4350
  if (!got) throw new NotFoundError(`Not found: ${id}`);
3577
4351
  const { doc } = got;
3578
4352
  return { ...doc, _id: id };
3579
4353
  }
3580
- /**
3581
- * Put a document from the database
3582
- * @param doc - the document to put
3583
- * @returns add DocResponse with the id and clock
3584
- */
3585
4354
  async put(doc) {
3586
4355
  await this.ready();
3587
4356
  this.logger.Debug().Str("id", doc._id).Msg("put");
@@ -3596,11 +4365,21 @@ var Database = class {
3596
4365
  });
3597
4366
  return { id: docId, clock: result?.head, name: this.name };
3598
4367
  }
3599
- /**
3600
- * delete a document from the database
3601
- * @param id Document id
3602
- * @returns DocResponse with the id and clock
3603
- */
4368
+ async bulk(docs) {
4369
+ await this.ready();
4370
+ const updates = docs.map((doc) => {
4371
+ const id = doc._id || this.sthis.timeOrderedNextId().str;
4372
+ return {
4373
+ id,
4374
+ value: {
4375
+ ...doc,
4376
+ _id: id
4377
+ }
4378
+ };
4379
+ });
4380
+ const result = await this._writeQueue.bulk(updates);
4381
+ return { ids: updates.map((u) => u.id), clock: result.head, name: this.name };
4382
+ }
3604
4383
  async del(id) {
3605
4384
  await this.ready();
3606
4385
  this.logger.Debug().Str("id", id).Msg("del");
@@ -3610,7 +4389,7 @@ var Database = class {
3610
4389
  async changes(since = [], opts = {}) {
3611
4390
  await this.ready();
3612
4391
  this.logger.Debug().Any("since", since).Any("opts", opts).Msg("changes");
3613
- const { result, head } = await this._crdt.changes(since, opts);
4392
+ const { result, head } = await this.crdt.changes(since, opts);
3614
4393
  const rows = result.map(({ id: key, value, del, clock }) => ({
3615
4394
  key,
3616
4395
  value: del ? { _id: key, _deleted: true } : { _id: key, ...value },
@@ -3621,7 +4400,7 @@ var Database = class {
3621
4400
  async allDocs(opts = {}) {
3622
4401
  await this.ready();
3623
4402
  this.logger.Debug().Msg("allDocs");
3624
- const { result, head } = await this._crdt.allDocs();
4403
+ const { result, head } = await this.crdt.allDocs();
3625
4404
  const rows = result.map(({ id: key, value, del }) => ({
3626
4405
  key,
3627
4406
  value: del ? { _id: key, _deleted: true } : { _id: key, ...value }
@@ -3636,7 +4415,7 @@ var Database = class {
3636
4415
  if (updates) {
3637
4416
  if (!this._listening) {
3638
4417
  this._listening = true;
3639
- this._crdt.clock.onTick((updates2) => {
4418
+ this.crdt.clock.onTick((updates2) => {
3640
4419
  void this._notify(updates2);
3641
4420
  });
3642
4421
  }
@@ -3655,13 +4434,13 @@ var Database = class {
3655
4434
  async query(field, opts = {}) {
3656
4435
  await this.ready();
3657
4436
  this.logger.Debug().Any("field", field).Any("opts", opts).Msg("query");
3658
- const _crdt = this._crdt;
3659
- const idx = typeof field === "string" ? index(this.sthis, { _crdt }, field) : index(this.sthis, { _crdt }, makeName(field.toString()), field);
4437
+ const _crdt = this.crdt;
4438
+ const idx = typeof field === "string" ? index({ crdt: _crdt }, field) : index({ crdt: _crdt }, makeName(field.toString()), field);
3660
4439
  return await idx.query(opts);
3661
4440
  }
3662
4441
  async compact() {
3663
4442
  await this.ready();
3664
- await this._crdt.compact();
4443
+ await this.crdt.compact();
3665
4444
  }
3666
4445
  async _notify(updates) {
3667
4446
  await this.ready();
@@ -3685,23 +4464,62 @@ var Database = class {
3685
4464
  }
3686
4465
  }
3687
4466
  };
3688
- function toSortedArray(set) {
3689
- if (!set) return [];
3690
- return Object.entries(set).sort(([a], [b]) => a.localeCompare(b)).map(([k, v]) => ({ [k]: v }));
4467
+ function defaultURI2(sthis, curi, uri, store, ctx) {
4468
+ ctx = ctx || {};
4469
+ const ret = (curi ? URI12.from(curi) : uri).build().setParam("store" /* STORE */, store);
4470
+ if (!ret.hasParam("name" /* NAME */)) {
4471
+ const name = sthis.pathOps.basename(ret.URI().pathname);
4472
+ if (!name) {
4473
+ throw sthis.logger.Error().Url(ret).Any("ctx", ctx).Msg("Database name is required").AsError();
4474
+ }
4475
+ ret.setParam("name" /* NAME */, name);
4476
+ }
4477
+ if (ctx.idx) {
4478
+ ret.defParam("index" /* INDEX */, "idx");
4479
+ ret.defParam("storekey" /* STORE_KEY */, `@${ret.getParam("name" /* NAME */)}-${store}-idx@`);
4480
+ } else {
4481
+ ret.defParam("storekey" /* STORE_KEY */, `@${ret.getParam("name" /* NAME */)}-${store}@`);
4482
+ }
4483
+ if (store === "data") {
4484
+ if (ctx.file) {
4485
+ } else {
4486
+ ret.defParam("suffix" /* SUFFIX */, ".car");
4487
+ }
4488
+ }
4489
+ return ret.URI();
3691
4490
  }
3692
- function fireproof(name, opts) {
3693
- const key = JSON.stringify(
3694
- toSortedArray({
3695
- name,
3696
- stores: toSortedArray(opts?.store?.stores)
3697
- })
3698
- );
3699
- let db = Database.databases.get(key);
3700
- if (!db) {
3701
- db = new Database(name, opts);
3702
- Database.databases.set(key, db);
4491
+ function toStoreURIRuntime(sthis, name, sopts) {
4492
+ sopts = sopts || {};
4493
+ if (!sopts.base) {
4494
+ const fp_env = sthis.env.get("FP_STORAGE_URL");
4495
+ if (fp_env) {
4496
+ sopts = { ...sopts, base: BuildURI2.from(fp_env).setParam("urlGen" /* URL_GEN */, "fromEnv") };
4497
+ } else {
4498
+ sopts = { ...sopts, base: getDefaultURI(sthis).build().setParam("urlGen" /* URL_GEN */, "default") };
4499
+ }
4500
+ }
4501
+ const bbase = BuildURI2.from(sopts.base);
4502
+ if (name) {
4503
+ bbase.setParam("name" /* NAME */, name);
3703
4504
  }
3704
- return db;
4505
+ const base = bbase.URI();
4506
+ return {
4507
+ idx: {
4508
+ data: defaultURI2(sthis, sopts.idx?.data, base, "data", { idx: true }),
4509
+ file: defaultURI2(sthis, sopts.idx?.data, base, "data", { file: true, idx: true }),
4510
+ meta: defaultURI2(sthis, sopts.idx?.meta, base, "meta", { idx: true }),
4511
+ wal: defaultURI2(sthis, sopts.idx?.wal, base, "wal", { idx: true })
4512
+ },
4513
+ data: {
4514
+ data: defaultURI2(sthis, sopts.data?.data, base, "data"),
4515
+ file: defaultURI2(sthis, sopts.data?.data, base, "data", { file: true }),
4516
+ meta: defaultURI2(sthis, sopts.data?.meta, base, "meta"),
4517
+ wal: defaultURI2(sthis, sopts.data?.wal, base, "wal")
4518
+ }
4519
+ };
4520
+ }
4521
+ function fireproof(name, opts) {
4522
+ return DatabaseFactory(name, opts);
3705
4523
  }
3706
4524
  function makeName(fnString) {
3707
4525
  const regex = /\(([^,()]+,\s*[^,()]+|\[[^\]]+\],\s*[^,()]+)\)/g;
@@ -3720,81 +4538,24 @@ function makeName(fnString) {
3720
4538
  }
3721
4539
  }
3722
4540
 
3723
- // src/runtime/index.ts
3724
- var runtime_exports = {};
3725
- __export(runtime_exports, {
3726
- FILESTORE_VERSION: () => FILESTORE_VERSION,
3727
- INDEXDB_VERSION: () => INDEXDB_VERSION,
3728
- files: () => files_exports,
3729
- getFileName: () => getFileName,
3730
- getPath: () => getPath,
3731
- kb: () => key_bag_exports,
3732
- kc: () => keyed_crypto_exports,
3733
- mf: () => wait_pr_multiformats_exports,
3734
- runtimeFn: () => runtimeFn4
3735
- });
3736
-
3737
- // src/runtime/gateways/file/node/utils.ts
3738
- import { getStore as getStore2 } from "@fireproof/core";
3739
- function getPath(url, sthis) {
3740
- const basePath = url.pathname;
3741
- const name = url.getParam("name");
3742
- if (name) {
3743
- const version = url.getParam("version");
3744
- if (!version) throw sthis.logger.Error().Url(url).Msg(`version not found`).AsError();
3745
- return sthis.pathOps.join(basePath, version, name);
3746
- }
3747
- return sthis.pathOps.join(basePath);
3748
- }
3749
- function getFileName(url, sthis) {
3750
- const key = url.getParam("key");
3751
- if (!key) throw sthis.logger.Error().Url(url).Msg(`key not found`).AsError();
3752
- const res = getStore2(url, sthis, (...a) => a.join("-"));
3753
- switch (res.store) {
3754
- case "data":
3755
- return sthis.pathOps.join(res.name, key + ".car");
3756
- case "wal":
3757
- case "meta":
3758
- return sthis.pathOps.join(res.name, key + ".json");
3759
- default:
3760
- throw sthis.logger.Error().Url(url).Msg(`unsupported store type`).AsError();
3761
- }
3762
- }
3763
-
3764
- // src/runtime/wait-pr-multiformats/index.ts
3765
- var wait_pr_multiformats_exports = {};
3766
- __export(wait_pr_multiformats_exports, {
3767
- block: () => block_exports,
3768
- codec: () => codec_interface_exports
3769
- });
3770
-
3771
- // src/runtime/wait-pr-multiformats/codec-interface.ts
3772
- var codec_interface_exports = {};
3773
-
3774
- // src/runtime/index.ts
3775
- import { runtimeFn as runtimeFn4 } from "@adviser/cement";
3776
-
3777
- // src/runtime/gateways/file/version.ts
3778
- var FILESTORE_VERSION = "v0.19-file";
3779
-
3780
- // src/runtime/gateways/indexdb/version.ts
3781
- var INDEXDB_VERSION = "v0.19-indexdb";
3782
-
3783
4541
  // src/version.ts
3784
4542
  var PACKAGE_VERSION = Object.keys({
3785
- "0.19.121": "xxxx"
4543
+ "0.20.0-dev-preview-06": "xxxx"
3786
4544
  })[0];
3787
4545
  export {
3788
4546
  CRDT,
3789
- Database,
4547
+ DatabaseFactory,
4548
+ DatabaseShell,
3790
4549
  Index,
3791
4550
  NotFoundError,
3792
4551
  PACKAGE_VERSION,
3793
- Result,
4552
+ PARAM,
3794
4553
  UInt8ArrayEqual,
3795
4554
  blockstore_exports as blockstore,
3796
4555
  blockstore_exports as bs,
3797
- dataDir,
4556
+ coerceIntoUint8,
4557
+ coercePromiseIntoUint8,
4558
+ defaultWriteQueueOpts,
3798
4559
  ensureLogger,
3799
4560
  ensureSuperLog,
3800
4561
  ensureSuperThis,
@@ -3805,11 +4566,16 @@ export {
3805
4566
  getName,
3806
4567
  getStore,
3807
4568
  index,
4569
+ inplaceFilter,
4570
+ isDatabase,
3808
4571
  isFalsy,
3809
4572
  isNotFoundError,
4573
+ keyConfigOpts,
3810
4574
  onSuperThis,
3811
4575
  runtime_exports as rt,
3812
4576
  runtime_exports as runtime,
3813
- throwFalsy
4577
+ throwFalsy,
4578
+ toSortedArray,
4579
+ toStoreURIRuntime
3814
4580
  };
3815
4581
  //# sourceMappingURL=index.js.map