@fireproof/core 0.19.121 → 0.20.0-dev-preview-06

Sign up to get free protection for your applications and to get access to all the features.
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