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

Sign up to get free protection for your applications and to get access to all the features.
Files changed (103) hide show
  1. package/README.md +13 -12
  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 +3 -4
  7. package/index.cjs +1797 -1431
  8. package/index.cjs.map +1 -1
  9. package/index.d.cts +760 -381
  10. package/index.d.ts +760 -381
  11. package/index.js +1976 -913
  12. package/index.js.map +1 -1
  13. package/metafile-cjs.json +1 -1
  14. package/metafile-esm.json +1 -1
  15. package/node/{node-filesystem.cjs → index.cjs} +17 -6
  16. package/node/index.cjs.map +1 -0
  17. package/node/index.d.cts +7 -0
  18. package/node/index.d.ts +7 -0
  19. package/node/{node-filesystem.js → index.js} +25 -5
  20. package/node/index.js.map +1 -0
  21. package/node/metafile-cjs.json +1 -1
  22. package/node/metafile-esm.json +1 -1
  23. package/package.json +27 -17
  24. package/react/index.cjs +22 -22
  25. package/react/index.cjs.map +1 -1
  26. package/react/index.d.cts +7 -7
  27. package/react/index.d.ts +7 -7
  28. package/react/index.js +22 -22
  29. package/react/index.js.map +1 -1
  30. package/react/metafile-cjs.json +1 -1
  31. package/react/metafile-esm.json +1 -1
  32. package/tests/blockstore/fp-envelope.test.ts-off +65 -0
  33. package/tests/blockstore/interceptor-gateway.test.ts +122 -0
  34. package/tests/blockstore/keyed-crypto-indexdb-file.test.ts +130 -0
  35. package/tests/blockstore/keyed-crypto.test.ts +75 -118
  36. package/tests/blockstore/loader.test.ts +18 -9
  37. package/tests/blockstore/store.test.ts +40 -31
  38. package/tests/blockstore/transaction.test.ts +14 -13
  39. package/tests/fireproof/all-gateway.test.ts +286 -216
  40. package/tests/fireproof/cars/bafkreidxwt2nhvbl4fnqfw3ctlt6zbrir4kqwmjo5im6rf4q5si27kgo2i.ts +324 -316
  41. package/tests/fireproof/crdt.test.ts +78 -19
  42. package/tests/fireproof/fireproof.test.ts +111 -92
  43. package/tests/fireproof/hello.test.ts +21 -17
  44. package/tests/fireproof/indexer.test.ts +74 -50
  45. package/tests/fireproof/{database.test.ts → ledger.test.ts} +241 -45
  46. package/tests/fireproof/multiple-ledger.test.ts +2 -2
  47. package/tests/fireproof/utils.test.ts +47 -6
  48. package/tests/gateway/file/loader-config.test.ts +307 -0
  49. package/tests/gateway/fp-envelope-serialize.test.ts +256 -0
  50. package/tests/gateway/indexdb/loader-config.test.ts +79 -0
  51. package/tests/helpers.ts +44 -17
  52. package/tests/react/useFireproof.test.tsx +2 -2
  53. package/tests/www/gallery.html +2 -2
  54. package/tests/www/todo-aws.html +1 -1
  55. package/tests/www/todo-ipfs.html +1 -1
  56. package/tests/www/todo-local.html +1 -1
  57. package/tests/www/todo.html +25 -4
  58. package/web/index.cjs +218 -0
  59. package/web/index.cjs.map +1 -0
  60. package/web/index.d.cts +30 -0
  61. package/web/index.d.ts +30 -0
  62. package/web/index.js +195 -0
  63. package/web/index.js.map +1 -0
  64. package/web/metafile-cjs.json +1 -1
  65. package/web/metafile-esm.json +1 -1
  66. package/chunk-7EWIAXTM.js +0 -7
  67. package/chunk-7EWIAXTM.js.map +0 -1
  68. package/chunk-F4FC6B2T.js +0 -63
  69. package/chunk-F4FC6B2T.js.map +0 -1
  70. package/chunk-PZ5AY32C.js +0 -10
  71. package/chunk-PZ5AY32C.js.map +0 -1
  72. package/chunk-RXC4JGJT.js +0 -301
  73. package/chunk-RXC4JGJT.js.map +0 -1
  74. package/gateway-C62S56GY.js +0 -66
  75. package/gateway-C62S56GY.js.map +0 -1
  76. package/gateway-VVS4QWDA.js +0 -145
  77. package/gateway-VVS4QWDA.js.map +0 -1
  78. package/key-bag-file-PWZ3QE7B.js +0 -55
  79. package/key-bag-file-PWZ3QE7B.js.map +0 -1
  80. package/key-bag-indexdb-SYG3YD4D.js +0 -51
  81. package/key-bag-indexdb-SYG3YD4D.js.map +0 -1
  82. package/node/chunk-4A4RAVNS.js +0 -17
  83. package/node/chunk-4A4RAVNS.js.map +0 -1
  84. package/node/mem-filesystem.cjs +0 -72
  85. package/node/mem-filesystem.cjs.map +0 -1
  86. package/node/mem-filesystem.d.cts +0 -25
  87. package/node/mem-filesystem.d.ts +0 -25
  88. package/node/mem-filesystem.js +0 -40
  89. package/node/mem-filesystem.js.map +0 -1
  90. package/node/node-filesystem.cjs.map +0 -1
  91. package/node/node-filesystem.d.cts +0 -35
  92. package/node/node-filesystem.d.ts +0 -35
  93. package/node/node-filesystem.js.map +0 -1
  94. package/tests/fireproof/config.test.ts +0 -172
  95. package/utils-ZVVGAXFE.js +0 -13
  96. package/utils-ZVVGAXFE.js.map +0 -1
  97. package/web/gateway-impl.cjs +0 -183
  98. package/web/gateway-impl.cjs.map +0 -1
  99. package/web/gateway-impl.d.cts +0 -31
  100. package/web/gateway-impl.d.ts +0 -31
  101. package/web/gateway-impl.js +0 -162
  102. package/web/gateway-impl.js.map +0 -1
  103. /package/tests/blockstore/{fragment-gateway.test.ts → fragment-gateway.test.ts-off} +0 -0
package/index.js CHANGED
@@ -1,172 +1,466 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ // src/ledger.ts
8
+ import { BuildURI as BuildURI2, KeyedResolvOnce as KeyedResolvOnce4, ResolveOnce as ResolveOnce7, URI as URI12 } from "@adviser/cement";
9
+
10
+ // src/utils.ts
1
11
  import {
2
- FILESTORE_VERSION
3
- } from "./chunk-7EWIAXTM.js";
4
- import {
5
- getFileName,
6
- getFileSystem,
7
- getPath
8
- } from "./chunk-F4FC6B2T.js";
9
- import {
10
- NotFoundError,
12
+ LoggerImpl,
13
+ IsLogger,
11
14
  Result,
12
- UInt8ArrayEqual,
13
- dataDir,
14
- ensureLogger,
15
- ensureSuperLog,
16
- ensureSuperThis,
17
- exceptionWrapper,
18
- getKey,
19
- getName,
20
- getStore,
21
- isNotFoundError,
22
- onSuperThis
23
- } from "./chunk-RXC4JGJT.js";
24
- import {
25
- __export
26
- } from "./chunk-PZ5AY32C.js";
15
+ ResolveOnce,
16
+ isURL,
17
+ envFactory,
18
+ toCryptoRuntime,
19
+ JSONFormatter,
20
+ YAMLFormatter
21
+ } from "@adviser/cement";
27
22
 
28
- // src/database.ts
29
- import { ResolveOnce as ResolveOnce6 } from "@adviser/cement";
23
+ // src/types.ts
24
+ function isFalsy(value) {
25
+ return value === false && value === null && value === void 0;
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 || {});
47
+ function throwFalsy(value) {
48
+ if (isFalsy(value)) {
49
+ throw new Error("value is Falsy");
50
+ }
51
+ return value;
52
+ }
53
+ function falsyToUndef(value) {
54
+ if (isFalsy(value)) {
55
+ return void 0;
56
+ }
57
+ return value;
58
+ }
59
+
60
+ // src/utils.ts
61
+ import { base58btc } from "multiformats/bases/base58";
62
+ var _globalLogger = new ResolveOnce();
63
+ function globalLogger() {
64
+ return _globalLogger.once(() => new LoggerImpl());
65
+ }
66
+ var registerFP_DEBUG = new ResolveOnce();
67
+ var SuperThisImpl = class _SuperThisImpl {
68
+ constructor(opts) {
69
+ this.logger = opts.logger;
70
+ this.env = opts.env;
71
+ this.crypto = opts.crypto;
72
+ this.pathOps = opts.pathOps;
73
+ this.txt = opts.txt;
74
+ this.ctx = { ...opts.ctx };
75
+ }
76
+ nextId(bytes = 6) {
77
+ const bin = this.crypto.randomBytes(bytes);
78
+ return {
79
+ str: base58btc.encode(bin),
80
+ bin
81
+ };
82
+ }
83
+ timeOrderedNextId(now) {
84
+ now = typeof now === "number" ? now : (/* @__PURE__ */ new Date()).getTime();
85
+ const t = (281474976710656 + now).toString(16).replace(/^1/, "");
86
+ const bin = this.crypto.randomBytes(10);
87
+ bin[1] = bin[1] & 240 | (bin[1] | 8 && 11);
88
+ const hex = Array.from(bin).map((i) => i.toString(16).padStart(2, "0")).join("");
89
+ return {
90
+ str: `${t.slice(0, 8)}-${t.slice(8)}-7${hex.slice(0, 3)}-${hex.slice(3, 7)}-${hex.slice(7, 19)}`
91
+ };
92
+ }
93
+ start() {
94
+ return Promise.resolve();
95
+ }
96
+ clone(override) {
97
+ return new _SuperThisImpl({
98
+ logger: override.logger || this.logger,
99
+ env: envFactory(override.env) || this.env,
100
+ crypto: override.crypto || this.crypto,
101
+ pathOps: override.pathOps || this.pathOps,
102
+ txt: override.txt || this.txt,
103
+ ctx: { ...this.ctx, ...override.ctx }
104
+ });
105
+ }
106
+ };
107
+ function presetEnv() {
108
+ const penv = new Map([
109
+ // ["FP_DEBUG", "xxx"],
110
+ // ["FP_ENV", "development"],
111
+ ...Array.from(
112
+ Object.entries(
113
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
114
+ globalThis[Symbol.for("FP_PRESET_ENV")] || {}
115
+ )
116
+ )
117
+ // .map(([k, v]) => [k, v as string])
118
+ ]);
119
+ return penv;
120
+ }
121
+ var pathOpsImpl = class {
122
+ join(...paths) {
123
+ return paths.map((i) => i.replace(/\/+$/, "")).join("/");
124
+ }
125
+ dirname(path) {
126
+ return path.split("/").slice(0, -1).join("/");
127
+ }
128
+ basename(path) {
129
+ return path.split("/").pop() || "";
130
+ }
131
+ // homedir() {
132
+ // throw new Error("SysContainer:homedir is not available in seeded state");
133
+ // }
134
+ };
135
+ var pathOps = new pathOpsImpl();
136
+ var txtOps = /* @__PURE__ */ ((txtEncoder, txtDecoder) => ({
137
+ encode: (input) => txtEncoder.encode(input),
138
+ decode: (input) => txtDecoder.decode(coerceIntoUint8(input).Ok())
139
+ // eslint-disable-next-line no-restricted-globals
140
+ }))(new TextEncoder(), new TextDecoder());
141
+ var _onSuperThis = /* @__PURE__ */ new Map();
142
+ function onSuperThis(fn) {
143
+ const key = `onSuperThis-${Math.random().toString(36).slice(2)}`;
144
+ _onSuperThis.set(key, fn);
145
+ return () => {
146
+ _onSuperThis.delete(key);
147
+ };
148
+ }
149
+ function ensureSuperThis(osthis) {
150
+ const env = envFactory({
151
+ symbol: osthis?.env?.symbol || "FP_ENV",
152
+ presetEnv: osthis?.env?.presetEnv || presetEnv()
153
+ });
154
+ const ret = new SuperThisImpl({
155
+ logger: osthis?.logger || globalLogger(),
156
+ env,
157
+ crypto: osthis?.crypto || toCryptoRuntime(),
158
+ ctx: osthis?.ctx || {},
159
+ pathOps,
160
+ txt: osthis?.txt || txtOps
161
+ });
162
+ _onSuperThis.forEach((fn) => fn(ret));
163
+ return ret;
164
+ }
165
+ function ensureSuperLog(sthis, componentName, ctx) {
166
+ return sthis.clone({
167
+ logger: ensureLogger(sthis, componentName, ctx)
168
+ });
169
+ }
170
+ function ensureLogger(sthis, componentName, ctx) {
171
+ let logger;
172
+ if (sthis && IsLogger(sthis.logger)) {
173
+ logger = sthis.logger;
174
+ } else {
175
+ logger = globalLogger();
176
+ }
177
+ const cLogger = logger.With().Module(componentName);
178
+ const debug = [];
179
+ let exposeStack = false;
180
+ if (ctx) {
181
+ if ("debug" in ctx) {
182
+ if (typeof ctx.debug === "string" && ctx.debug.length > 0) {
183
+ debug.push(ctx.debug);
184
+ } else {
185
+ debug.push(componentName);
186
+ }
187
+ delete ctx.debug;
188
+ }
189
+ if ("exposeStack" in ctx) {
190
+ exposeStack = true;
191
+ delete ctx.exposeStack;
192
+ }
193
+ if ("exposeStack" in ctx) {
194
+ exposeStack = true;
195
+ delete ctx.exposeStack;
196
+ }
197
+ if ("this" in ctx) {
198
+ cLogger.Str("this", sthis.nextId(4).str);
199
+ delete ctx.this;
200
+ }
201
+ for (const [key, value] of Object.entries(ctx)) {
202
+ switch (typeof value) {
203
+ case "string":
204
+ cLogger.Str(key, value);
205
+ break;
206
+ case "number":
207
+ cLogger.Uint64(key, value);
208
+ break;
209
+ default:
210
+ if (value instanceof Date) {
211
+ cLogger.Str(key, value.toISOString());
212
+ } else if (isURL(value)) {
213
+ cLogger.Str(key, value.toString());
214
+ } else if (typeof value === "function") {
215
+ cLogger.Ref(key, value);
216
+ } else {
217
+ cLogger.Any(key, value);
218
+ }
219
+ break;
220
+ }
221
+ }
222
+ }
223
+ registerFP_DEBUG.once(async () => {
224
+ sthis.env.onSet(
225
+ (key, value) => {
226
+ switch (key) {
227
+ case "FP_FORMAT": {
228
+ switch (value) {
229
+ case "jsonice":
230
+ logger.SetFormatter(new JSONFormatter(logger.TxtEnDe(), 2));
231
+ break;
232
+ case "yaml":
233
+ logger.SetFormatter(new YAMLFormatter(logger.TxtEnDe(), 2));
234
+ break;
235
+ case "json":
236
+ default:
237
+ logger.SetFormatter(new JSONFormatter(logger.TxtEnDe()));
238
+ break;
239
+ }
240
+ break;
241
+ }
242
+ case "FP_DEBUG":
243
+ logger.SetDebug(value || []);
244
+ break;
245
+ case "FP_STACK":
246
+ logger.SetExposeStack(!!value);
247
+ break;
248
+ }
249
+ },
250
+ "FP_FORMAT",
251
+ "FP_DEBUG",
252
+ "FP_STACK"
253
+ );
254
+ }).finally(() => {
255
+ });
256
+ if (debug.length > 0) {
257
+ logger.SetDebug(debug);
258
+ }
259
+ if (exposeStack) {
260
+ logger.SetExposeStack(true);
261
+ }
262
+ const out = cLogger.Logger();
263
+ if (sthis.env.get("FP_CONSTRUCTOR_DEBUG")) {
264
+ out.Debug().Msg("constructor");
265
+ }
266
+ return out;
267
+ }
268
+ function getStore(url, sthis, joiner) {
269
+ const store = url.getParam("store" /* STORE */);
270
+ switch (store) {
271
+ case "data":
272
+ case "wal":
273
+ case "meta":
274
+ break;
275
+ default:
276
+ throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
277
+ throw sthis.logger.Error().Url(url).Msg(`store not found`).AsError();
278
+ }
279
+ let name = store;
280
+ if (url.hasParam("index")) {
281
+ name = joiner(url.getParam("index" /* INDEX */) || "idx", name);
282
+ }
283
+ return { store, name };
284
+ }
285
+ function getKey(url, logger) {
286
+ const result = url.getParam("key" /* KEY */);
287
+ if (!result) throw logger.Error().Str("url", url.toString()).Msg(`key not found`).AsError();
288
+ return result;
289
+ }
290
+ function getName(sthis, url) {
291
+ let result = url.getParam("name" /* NAME */);
292
+ if (!result) {
293
+ result = sthis.pathOps.dirname(url.pathname);
294
+ if (result.length === 0) {
295
+ throw sthis.logger.Error().Str("url", url.toString()).Msg(`name not found`).AsError();
296
+ }
297
+ }
298
+ return result;
299
+ }
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
+ }
30
369
 
31
370
  // src/write-queue.ts
32
- function writeQueue(worker, payload = Infinity, unbounded = false) {
33
- const queue = [];
34
- let isProcessing = false;
35
- async function process() {
36
- if (isProcessing || queue.length === 0) return;
37
- isProcessing = true;
38
- const tasksToProcess = queue.splice(0, payload);
39
- const updates = tasksToProcess.map((item) => item.task);
40
- if (unbounded) {
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);
41
401
  const promises = updates.map(async (update, index2) => {
42
402
  try {
43
- const result = await worker([update]);
403
+ const result = await this.worker(update);
44
404
  tasksToProcess[index2].resolve(result);
45
405
  } catch (error) {
46
- tasksToProcess[index2].reject(error);
406
+ tasksToProcess[index2].reject(this.logger.Error().Err(error).Msg("Error processing task").AsError());
47
407
  }
48
408
  });
49
- await Promise.all(promises);
50
- } else {
51
- try {
52
- const result = await worker(updates);
53
- tasksToProcess.forEach((task) => task.resolve(result));
54
- } catch (error) {
55
- tasksToProcess.forEach((task) => task.reject(error));
56
- }
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);
57
416
  }
58
- isProcessing = false;
59
- void process();
60
417
  }
61
- return {
62
- push(task) {
63
- return new Promise((resolve, reject) => {
64
- queue.push({ task, resolve, reject });
65
- void process();
66
- });
67
- }
68
- };
69
- }
70
-
71
- // src/crdt.ts
72
- import { ResolveOnce as ResolveOnce5 } from "@adviser/cement";
73
-
74
- // src/runtime/wait-pr-multiformats/block.ts
75
- var block_exports = {};
76
- __export(block_exports, {
77
- Block: () => Block,
78
- create: () => create,
79
- createUnsafe: () => createUnsafe,
80
- decode: () => decode,
81
- encode: () => encode
82
- });
83
- import { bytes as binary, CID } from "multiformats";
84
- import { Block as mfBlock } from "multiformats/block";
85
- var Block = mfBlock;
86
- async function decode({
87
- bytes,
88
- codec: codec3,
89
- hasher: hasher7
90
- }) {
91
- if (bytes == null) throw new Error('Missing required argument "bytes"');
92
- if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
93
- const value = await Promise.resolve(codec3.decode(bytes));
94
- const hash = await hasher7.digest(bytes);
95
- const cid = CID.create(1, codec3.code, hash);
96
- return new mfBlock({ value, bytes, cid });
97
- }
98
- async function encode({
99
- value,
100
- codec: codec3,
101
- hasher: hasher7
102
- }) {
103
- if (typeof value === "undefined") throw new Error('Missing required argument "value"');
104
- if (codec3 == null || hasher7 == null) throw new Error("Missing required argument: codec or hasher");
105
- const bytes = await Promise.resolve(codec3.encode(value));
106
- const hash = await hasher7.digest(bytes);
107
- const cid = CID.create(1, codec3.code, hash);
108
- return new mfBlock({ value, bytes, cid });
109
- }
110
- async function create({
111
- bytes,
112
- cid,
113
- hasher: hasher7,
114
- codec: codec3
115
- }) {
116
- if (bytes == null) throw new Error('Missing required argument "bytes"');
117
- if (hasher7 == null) throw new Error('Missing required argument "hasher"');
118
- const value = await Promise.resolve(codec3.decode(bytes));
119
- const hash = await hasher7.digest(bytes);
120
- if (!binary.equals(cid.multihash.bytes, hash.bytes)) {
121
- throw new Error("CID hash does not match bytes");
418
+ bulk(tasks) {
419
+ return new Promise((resolve, reject) => {
420
+ this.queue.push({ tasks, resolve, reject });
421
+ this.process();
422
+ });
122
423
  }
123
- return createUnsafe({
124
- bytes,
125
- cid,
126
- value,
127
- codec: codec3
128
- });
129
- }
130
- async function createUnsafe({
131
- bytes,
132
- cid,
133
- value: maybeValue,
134
- codec: codec3
135
- }) {
136
- const value = await Promise.resolve(maybeValue !== void 0 ? maybeValue : codec3?.decode(bytes));
137
- if (value === void 0) throw new Error('Missing required argument, must either provide "value" or "codec"');
138
- return new Block({
139
- cid,
140
- bytes,
141
- value
142
- });
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);
143
435
  }
144
436
 
145
- // src/crdt-helpers.ts
146
- import { parse as parse3 } from "multiformats/link";
147
- import { sha256 as hasher5 } from "multiformats/hashes/sha2";
148
- import * as codec from "@fireproof/vendor/@ipld/dag-cbor";
149
- import { put, get, entries, root } from "@fireproof/vendor/@web3-storage/pail/crdt";
150
- import { EventFetcher, vis } from "@fireproof/vendor/@web3-storage/pail/clock";
151
- import * as Batch from "@fireproof/vendor/@web3-storage/pail/crdt/batch";
437
+ // src/crdt.ts
438
+ import { ResolveOnce as ResolveOnce6 } from "@adviser/cement";
152
439
 
153
440
  // src/blockstore/index.ts
154
441
  var blockstore_exports = {};
155
442
  __export(blockstore_exports, {
156
443
  BaseBlockstore: () => BaseBlockstore,
444
+ Car2FPMsg: () => Car2FPMsg,
157
445
  CarTransaction: () => CarTransaction,
158
446
  CompactionFetcher: () => CompactionFetcher,
159
447
  ConnectionBase: () => ConnectionBase,
448
+ DbMetaEventEqual: () => DbMetaEventEqual,
449
+ DbMetaEventsEqual: () => DbMetaEventsEqual,
160
450
  EncryptedBlockstore: () => EncryptedBlockstore,
161
- FragmentGateway: () => FragmentGateway,
451
+ FPEnvelopeType: () => FPEnvelopeType,
452
+ File2FPMsg: () => File2FPMsg,
453
+ InterceptorGateway: () => InterceptorGateway,
162
454
  Loader: () => Loader,
163
- addCryptoKeyToGatewayMetaPayload: () => addCryptoKeyToGatewayMetaPayload,
164
- ensureStart: () => ensureStart,
165
- getGatewayFromURL: () => getGatewayFromURL,
455
+ PassThroughGateway: () => PassThroughGateway,
456
+ createDbMetaEvent: () => createDbMetaEvent,
457
+ defaultGatewayFactoryItem: () => defaultGatewayFactoryItem,
458
+ ensureStoreEnDeFile: () => ensureStoreEnDeFile,
459
+ getDefaultURI: () => getDefaultURI,
460
+ getGatewayFactoryItem: () => getGatewayFactoryItem,
461
+ getStartedGateway: () => getStartedGateway,
166
462
  parseCarFile: () => parseCarFile,
167
463
  registerStoreProtocol: () => registerStoreProtocol,
168
- setCryptoKeyFromGatewayMetaPayload: () => setCryptoKeyFromGatewayMetaPayload,
169
- testStoreFactory: () => testStoreFactory,
170
464
  toCIDBlock: () => toCIDBlock,
171
465
  toStoreRuntime: () => toStoreRuntime
172
466
  });
@@ -175,9 +469,15 @@ __export(blockstore_exports, {
175
469
  function toCIDBlock(block) {
176
470
  return block;
177
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
+ }
178
478
 
179
479
  // src/blockstore/store-factory.ts
180
- import { KeyedResolvOnce as KeyedResolvOnce2, URI as URI5 } from "@adviser/cement";
480
+ import { KeyedResolvOnce as KeyedResolvOnce3, Result as Result10 } from "@adviser/cement";
181
481
 
182
482
  // src/runtime/files.ts
183
483
  var files_exports = {};
@@ -251,30 +551,83 @@ var UnixFSFileBuilder = class {
251
551
  };
252
552
 
253
553
  // src/blockstore/store.ts
254
- import { format as format2, parse as parse2 } from "@fireproof/vendor/@ipld/dag-json";
255
- import { exception2Result, ResolveOnce as ResolveOnce3, Result as Result5 } from "@adviser/cement";
554
+ import { exception2Result, ResolveOnce as ResolveOnce4, Result as Result5 } from "@adviser/cement";
256
555
 
257
- // src/types.ts
258
- function isFalsy(value) {
259
- return value === false && value === null && value === void 0;
556
+ // src/blockstore/loader.ts
557
+ import pLimit from "p-limit";
558
+ import { CarReader } from "@fireproof/vendor/@ipld/car/reader";
559
+ import { ResolveOnce as ResolveOnce3 } from "@adviser/cement";
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 });
260
584
  }
261
- function throwFalsy(value) {
262
- if (isFalsy(value)) {
263
- throw new Error("value is Falsy");
264
- }
265
- return value;
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 });
266
596
  }
267
- function falsyToUndef(value) {
268
- if (isFalsy(value)) {
269
- return void 0;
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");
270
609
  }
271
- return value;
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
+ });
272
630
  }
273
-
274
- // src/blockstore/loader.ts
275
- import pLimit from "p-limit";
276
- import { CarReader } from "@fireproof/vendor/@ipld/car/reader";
277
- import { ResolveOnce as ResolveOnce2 } from "@adviser/cement";
278
631
 
279
632
  // src/blockstore/loader-helpers.ts
280
633
  import { sha256 as hasher } from "multiformats/hashes/sha2";
@@ -293,7 +646,7 @@ async function parseCarFile(reader, logger) {
293
646
 
294
647
  // src/blockstore/transaction.ts
295
648
  import { MemoryBlockstore } from "@fireproof/vendor/@web3-storage/pail/block";
296
- import { toCryptoRuntime } from "@adviser/cement";
649
+ import { toCryptoRuntime as toCryptoRuntime2 } from "@adviser/cement";
297
650
  var CarTransaction = class extends MemoryBlockstore {
298
651
  constructor(parent, opts = { add: true, noLoader: false }) {
299
652
  super();
@@ -311,7 +664,6 @@ var CarTransaction = class extends MemoryBlockstore {
311
664
  };
312
665
  function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
313
666
  const logger = ensureLogger(sthis, component, ctx);
314
- const store = opts.store || {};
315
667
  return {
316
668
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
317
669
  applyMeta: (meta, snap) => {
@@ -323,30 +675,27 @@ function defaultedBlockstoreRuntime(sthis, opts, component, ctx) {
323
675
  },
324
676
  autoCompact: 100,
325
677
  public: false,
326
- name: void 0,
678
+ // name: undefined,
327
679
  threshold: 1e3 * 1e3,
328
680
  ...opts,
329
681
  logger,
330
682
  keyBag: opts.keyBag || {},
331
- crypto: toCryptoRuntime(opts.crypto),
332
- store,
333
- storeRuntime: toStoreRuntime(store, sthis)
683
+ crypto: toCryptoRuntime2(opts.crypto),
684
+ storeUrls: opts.storeUrls,
685
+ // storeEnDeFile: ensureStoreEnDeFile(opts.storeEnDeFile),
686
+ // store,
687
+ storeRuntime: toStoreRuntime(sthis, ensureStoreEnDeFile(opts.storeEnDeFile))
334
688
  };
335
689
  }
336
- function blockstoreFactory(sthis, opts) {
337
- if (opts.name) {
338
- return new EncryptedBlockstore(sthis, opts);
339
- } else {
340
- return new BaseBlockstore(opts);
341
- }
342
- }
343
690
  var BaseBlockstore = class {
344
- constructor(ebOpts = {}) {
691
+ constructor(ebOpts) {
345
692
  this.transactions = /* @__PURE__ */ new Set();
346
693
  this.sthis = ensureSuperThis(ebOpts);
347
694
  this.ebOpts = defaultedBlockstoreRuntime(this.sthis, ebOpts, "BaseBlockstore");
348
695
  this.logger = this.ebOpts.logger;
696
+ this.loader = new Loader(this.sthis, ebOpts);
349
697
  }
698
+ // readonly name?: string;
350
699
  // ready: Promise<void>;
351
700
  ready() {
352
701
  return Promise.resolve();
@@ -370,8 +719,11 @@ var BaseBlockstore = class {
370
719
  }
371
720
  // TransactionMeta
372
721
  async transaction(fn, _opts) {
722
+ this.logger.Debug().Msg("enter transaction");
373
723
  const t = new CarTransaction(this, _opts);
724
+ this.logger.Debug().Msg("post CarTransaction");
374
725
  const done = await fn(t);
726
+ this.logger.Debug().Msg("post fn");
375
727
  this.lastTxMeta = done;
376
728
  return { t, meta: done };
377
729
  }
@@ -380,7 +732,7 @@ var BaseBlockstore = class {
380
732
  }
381
733
  async commitTransaction(t, done, opts) {
382
734
  if (!this.loader) throw this.logger.Error().Msg("loader required to commit").AsError();
383
- const cars = await this.loader?.commit(t, done, opts);
735
+ const cars = await this.loader.commit(t, done, opts);
384
736
  if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
385
737
  setTimeout(() => void this.compact(), 10);
386
738
  }
@@ -405,14 +757,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
405
757
  constructor(sthis, ebOpts) {
406
758
  super(ebOpts);
407
759
  this.compacting = false;
408
- this.logger = ensureLogger(this.sthis, "EncryptedBlockstore");
409
- const { name } = ebOpts;
410
- if (!name) {
411
- throw this.logger.Error().Msg("name required").AsError();
412
- }
413
- this.name = name;
414
- this.loader = new Loader(this.name, ebOpts, sthis);
760
+ this.logger = ensureLogger(this.sthis, "EncryptedBlockstore", {
761
+ this: 1
762
+ });
415
763
  }
764
+ // readonly name: string;
416
765
  ready() {
417
766
  return this.loader.ready();
418
767
  }
@@ -431,8 +780,11 @@ var EncryptedBlockstore = class extends BaseBlockstore {
431
780
  return falsyToUndef(await this.loader.getBlock(cid));
432
781
  }
433
782
  async transaction(fn, opts = { noLoader: false }) {
783
+ this.logger.Debug().Msg("enter transaction");
434
784
  const { t, meta: done } = await super.transaction(fn);
785
+ this.logger.Debug().Msg("post super.transaction");
435
786
  const cars = await this.loader.commit(t, done, opts);
787
+ this.logger.Debug().Msg("post this.loader.commit");
436
788
  if (this.ebOpts.autoCompact && this.loader.carLog.length > this.ebOpts.autoCompact) {
437
789
  setTimeout(() => void this.compact(), 10);
438
790
  }
@@ -444,7 +796,7 @@ var EncryptedBlockstore = class extends BaseBlockstore {
444
796
  }
445
797
  async getFile(car, cid) {
446
798
  await this.ready();
447
- if (!this.loader) throw this.logger.Error().Msg("loader required to get file, database must be named").AsError();
799
+ if (!this.loader) throw this.logger.Error().Msg("loader required to get file, ledger must be named").AsError();
448
800
  const reader = await this.loader.loadFileCar(
449
801
  car
450
802
  /*, isPublic */
@@ -462,7 +814,7 @@ var EncryptedBlockstore = class extends BaseBlockstore {
462
814
  const blockLog = new CompactionFetcher(this);
463
815
  this.compacting = true;
464
816
  const meta = await compactFn(blockLog);
465
- await this.loader?.commit(blockLog.loggedBlocks, meta, {
817
+ await this.loader.commit(blockLog.loggedBlocks, meta, {
466
818
  compact: true,
467
819
  noLoader: true
468
820
  });
@@ -504,7 +856,7 @@ var CompactionFetcher = class {
504
856
  };
505
857
 
506
858
  // src/blockstore/commit-queue.ts
507
- import { Future } from "@adviser/cement";
859
+ import { Future as Future2 } from "@adviser/cement";
508
860
  var CommitQueue = class {
509
861
  constructor() {
510
862
  this.queue = [];
@@ -515,7 +867,7 @@ var CommitQueue = class {
515
867
  if (this.queue.length === 0 && !this.processing) {
516
868
  return Promise.resolve();
517
869
  }
518
- const fn = new Future();
870
+ const fn = new Future2();
519
871
  this._waitIdleItems.add(fn);
520
872
  return fn.asPromise();
521
873
  }
@@ -558,30 +910,111 @@ var CommitQueue = class {
558
910
  var key_bag_exports = {};
559
911
  __export(key_bag_exports, {
560
912
  KeyBag: () => KeyBag,
913
+ defaultKeyBagOpts: () => defaultKeyBagOpts,
561
914
  defaultKeyBagUrl: () => defaultKeyBagUrl,
562
915
  getKeyBag: () => getKeyBag,
563
916
  registerKeyBagProviderFactory: () => registerKeyBagProviderFactory
564
917
  });
565
918
  import {
566
919
  KeyedResolvOnce,
567
- ResolveOnce,
920
+ ResolveOnce as ResolveOnce2,
568
921
  ResolveSeq,
569
922
  Result as Result2,
570
- runtimeFn,
571
- toCryptoRuntime as toCryptoRuntime2,
572
- URI
923
+ runtimeFn as runtimeFn2,
924
+ toCryptoRuntime as toCryptoRuntime3,
925
+ URI as URI3
573
926
  } from "@adviser/cement";
574
- import { base58btc } from "multiformats/bases/base58";
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
575
1006
  var KeyBag = class {
576
1007
  constructor(rt) {
577
1008
  this.rt = rt;
578
- this._warnOnce = new ResolveOnce();
1009
+ this._warnOnce = new ResolveOnce2();
579
1010
  this._seq = new ResolveSeq();
580
- this.logger = ensureLogger(rt.sthis, "KeyBag");
1011
+ this.logger = ensureLogger(rt.sthis, "KeyBag", {
1012
+ // id: rt.id(),
1013
+ });
581
1014
  this.logger.Debug().Msg("KeyBag created");
582
1015
  }
583
1016
  async subtleKey(key) {
584
- const extractable = this.rt.url.getParam("extractKey") === "_deprecated_internal_api";
1017
+ const extractable = this.rt.url.getParam("extractKey" /* EXTRACTKEY */) === "_deprecated_internal_api";
585
1018
  if (extractable) {
586
1019
  this._warnOnce.once(
587
1020
  () => this.logger.Warn().Msg("extractKey is enabled via _deprecated_internal_api --- handle keys safely!!!")
@@ -590,7 +1023,7 @@ var KeyBag = class {
590
1023
  return await this.rt.crypto.importKey(
591
1024
  "raw",
592
1025
  // raw or jwk
593
- base58btc.decode(key),
1026
+ base58btc2.decode(key),
594
1027
  // hexStringToUint8Array(key), // raw data
595
1028
  "AES-GCM",
596
1029
  extractable,
@@ -598,7 +1031,7 @@ var KeyBag = class {
598
1031
  );
599
1032
  }
600
1033
  async ensureKeyFromUrl(url, keyFactory) {
601
- const storeKey = url.getParam("storekey");
1034
+ const storeKey = url.getParam("storekey" /* STORE_KEY */);
602
1035
  if (storeKey === "insecure") {
603
1036
  return Result2.Ok(url);
604
1037
  }
@@ -608,7 +1041,7 @@ var KeyBag = class {
608
1041
  if (ret.isErr()) {
609
1042
  return ret;
610
1043
  }
611
- const urb = url.build().setParam("storekey", keyName);
1044
+ const urb = url.build().setParam("storekey" /* STORE_KEY */, keyName);
612
1045
  return Result2.Ok(urb.URI());
613
1046
  }
614
1047
  if (storeKey.startsWith("@") && storeKey.endsWith("@")) {
@@ -620,12 +1053,12 @@ var KeyBag = class {
620
1053
  return Result2.Ok(url);
621
1054
  }
622
1055
  async toKeyWithFingerPrint(keyStr) {
623
- const material = base58btc.decode(keyStr);
1056
+ const material = base58btc2.decode(keyStr);
624
1057
  const key = await this.subtleKey(keyStr);
625
1058
  const fpr = await this.rt.crypto.digestSHA256(material);
626
1059
  return Result2.Ok({
627
1060
  key,
628
- fingerPrint: base58btc.encode(new Uint8Array(fpr))
1061
+ fingerPrint: base58btc2.encode(new Uint8Array(fpr))
629
1062
  });
630
1063
  }
631
1064
  async setNamedKey(name, key) {
@@ -654,7 +1087,7 @@ var KeyBag = class {
654
1087
  const ext = new Uint8Array(await this.rt.crypto.exportKey("raw", named.key));
655
1088
  return {
656
1089
  key: ext,
657
- keyStr: base58btc.encode(ext)
1090
+ keyStr: base58btc2.encode(ext)
658
1091
  };
659
1092
  }
660
1093
  });
@@ -673,7 +1106,7 @@ var KeyBag = class {
673
1106
  this.logger.Debug().Str("id", id).Str("name", name).Msg("failIfNotFound getNamedKey");
674
1107
  return Result2.Err(new Error(`Key not found: ${name}`));
675
1108
  }
676
- const ret = await this._setNamedKey(name, base58btc.encode(this.rt.crypto.randomBytes(this.rt.keyLength)));
1109
+ const ret = await this._setNamedKey(name, base58btc2.encode(this.rt.crypto.randomBytes(this.rt.keyLength)));
677
1110
  this.logger.Debug().Str("id", id).Str("name", name).Result("fpr", ret).Msg("createKey getNamedKey-post");
678
1111
  return ret;
679
1112
  });
@@ -684,15 +1117,20 @@ var keyBagProviderFactories = new Map(
684
1117
  {
685
1118
  protocol: "file:",
686
1119
  factory: async (url, sthis) => {
687
- const { KeyBagProviderFile } = await import("./key-bag-file-PWZ3QE7B.js");
688
1120
  return new KeyBagProviderFile(url, sthis);
689
1121
  }
690
1122
  },
691
1123
  {
692
1124
  protocol: "indexdb:",
693
1125
  factory: async (url, sthis) => {
694
- const { KeyBagProviderIndexDB } = await import("./key-bag-indexdb-SYG3YD4D.js");
695
- return new KeyBagProviderIndexDB(url, sthis);
1126
+ const { KeyBagProviderImpl } = await import("@fireproof/core/web");
1127
+ return new KeyBagProviderImpl(url, sthis);
1128
+ }
1129
+ },
1130
+ {
1131
+ protocol: "memory:",
1132
+ factory: async (url, sthis) => {
1133
+ return new KeyBagProviderMemory(url, sthis);
696
1134
  }
697
1135
  }
698
1136
  ].map((i) => [i.protocol, i])
@@ -707,15 +1145,15 @@ function registerKeyBagProviderFactory(item) {
707
1145
  function defaultKeyBagUrl(sthis) {
708
1146
  let bagFnameOrUrl = sthis.env.get("FP_KEYBAG_URL");
709
1147
  let url;
710
- if (runtimeFn().isBrowser) {
711
- url = URI.from(bagFnameOrUrl || "indexdb://fp-keybag");
1148
+ if (runtimeFn2().isBrowser) {
1149
+ url = URI3.from(bagFnameOrUrl || "indexdb://fp-keybag");
712
1150
  } else {
713
1151
  if (!bagFnameOrUrl) {
714
1152
  const home = sthis.env.get("HOME");
715
1153
  bagFnameOrUrl = `${home}/.fireproof/keybag`;
716
- url = URI.from(`file://${bagFnameOrUrl}`);
1154
+ url = URI3.from(`file://${bagFnameOrUrl}`);
717
1155
  } else {
718
- url = URI.from(bagFnameOrUrl);
1156
+ url = URI3.from(bagFnameOrUrl);
719
1157
  }
720
1158
  }
721
1159
  const logger = ensureLogger(sthis, "defaultKeyBagUrl");
@@ -723,32 +1161,44 @@ function defaultKeyBagUrl(sthis) {
723
1161
  return url;
724
1162
  }
725
1163
  function defaultKeyBagOpts(sthis, kbo) {
1164
+ kbo = kbo || {};
726
1165
  if (kbo.keyRuntime) {
727
1166
  return kbo.keyRuntime;
728
1167
  }
729
1168
  const logger = ensureLogger(sthis, "KeyBag");
730
1169
  let url;
731
1170
  if (kbo.url) {
732
- url = URI.from(kbo.url);
1171
+ url = URI3.from(kbo.url);
733
1172
  logger.Debug().Url(url).Msg("from opts");
734
1173
  } else {
735
- 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");
736
1187
  }
737
1188
  const kitem = keyBagProviderFactories.get(url.protocol);
738
1189
  if (!kitem) {
739
1190
  throw logger.Error().Url(url).Msg("unsupported protocol").AsError();
740
1191
  }
741
- const getBag = async () => kitem.factory(url, sthis);
742
1192
  if (url.hasParam("masterkey")) {
743
1193
  throw logger.Error().Url(url).Msg("masterkey is not supported").AsError();
744
1194
  }
745
1195
  return {
746
1196
  url,
747
- crypto: kbo.crypto || toCryptoRuntime2({}),
1197
+ crypto: kbo.crypto || toCryptoRuntime3({}),
748
1198
  sthis,
749
1199
  logger,
750
1200
  keyLength: kbo.keyLength || 16,
751
- getBag,
1201
+ getBag: () => kitem.factory(url, sthis),
752
1202
  id: () => {
753
1203
  return url.toString();
754
1204
  }
@@ -773,7 +1223,7 @@ async function encodeCarFile(roots, t, codec3) {
773
1223
  size += CBW.blockLength({ cid, bytes });
774
1224
  }
775
1225
  const buffer = new Uint8Array(size);
776
- const writer = CBW.createWriter(buffer, { headerSize });
1226
+ const writer = CBW.createWriter(buffer.buffer, { headerSize });
777
1227
  for (const r of roots) {
778
1228
  writer.addRoot(r);
779
1229
  }
@@ -928,7 +1378,7 @@ function uniqueCids(list, remove = /* @__PURE__ */ new Set()) {
928
1378
  return [...byString.values()];
929
1379
  }
930
1380
  var Loader = class {
931
- constructor(name, ebOpts, sthis) {
1381
+ constructor(sthis, ebOpts) {
932
1382
  this.commitQueue = new CommitQueue();
933
1383
  this.isCompacting = false;
934
1384
  this.carReaders = /* @__PURE__ */ new Map();
@@ -938,14 +1388,17 @@ var Loader = class {
938
1388
  this.getBlockCache = /* @__PURE__ */ new Map();
939
1389
  this.seenMeta = /* @__PURE__ */ new Set();
940
1390
  this.writeLimit = pLimit(1);
941
- this.onceReady = new ResolveOnce2();
942
- this.name = name;
1391
+ this._carStore = new ResolveOnce3();
1392
+ this._fileStore = new ResolveOnce3();
1393
+ this._WALStore = new ResolveOnce3();
1394
+ this._metaStore = new ResolveOnce3();
1395
+ this.onceReady = new ResolveOnce3();
943
1396
  this.sthis = sthis;
944
1397
  this.ebOpts = defaultedBlockstoreRuntime(
945
1398
  sthis,
946
1399
  {
947
- ...ebOpts,
948
- name
1400
+ ...ebOpts
1401
+ // name,
949
1402
  },
950
1403
  "Loader"
951
1404
  );
@@ -954,21 +1407,52 @@ var Loader = class {
954
1407
  await this.handleDbMetasFromStore([dbMeta]);
955
1408
  });
956
1409
  }
957
- // readonly id = uuidv4();
958
- async keyBag() {
959
- return getKeyBag(this.sthis, this.ebOpts.keyBag);
960
- }
961
1410
  async carStore() {
962
- 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
+ );
963
1420
  }
964
1421
  async fileStore() {
965
- 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
+ );
966
1431
  }
967
1432
  async WALStore() {
968
- 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
+ );
969
1442
  }
970
1443
  async metaStore() {
971
- 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);
972
1456
  }
973
1457
  async ready() {
974
1458
  return this.onceReady.once(async () => {
@@ -981,6 +1465,7 @@ var Loader = class {
981
1465
  });
982
1466
  }
983
1467
  async close() {
1468
+ await this.commitQueue.waitIdle();
984
1469
  const toClose = await Promise.all([this.carStore(), this.metaStore(), this.fileStore(), this.WALStore()]);
985
1470
  await Promise.all(toClose.map((store) => store.close()));
986
1471
  }
@@ -1050,11 +1535,11 @@ var Loader = class {
1050
1535
  }
1051
1536
  async commit(t, done, opts = { noLoader: false, compact: false }) {
1052
1537
  await this.ready();
1053
- const fstore = await this.fileStore();
1538
+ const carStore = await this.carStore();
1054
1539
  const params = {
1055
- encoder: (await fstore.keyedCrypto()).codec(),
1540
+ encoder: (await carStore.keyedCrypto()).codec(),
1056
1541
  carLog: this.carLog,
1057
- carStore: fstore,
1542
+ carStore,
1058
1543
  WALStore: await this.WALStore(),
1059
1544
  metaStore: await this.metaStore(),
1060
1545
  threshold: this.ebOpts.threshold
@@ -1263,7 +1748,7 @@ __export(keyed_crypto_exports, {
1263
1748
  BlockIvKeyIdCodec: () => BlockIvKeyIdCodec,
1264
1749
  keyedCryptoFactory: () => keyedCryptoFactory
1265
1750
  });
1266
- import { base58btc as base58btc2 } from "multiformats/bases/base58";
1751
+ import { base58btc as base58btc3 } from "multiformats/bases/base58";
1267
1752
  import { sha256 as hasher4 } from "multiformats/hashes/sha2";
1268
1753
  import * as CBOR from "@fireproof/vendor/cborg";
1269
1754
  var generateIV = {
@@ -1288,12 +1773,12 @@ var generateIV = {
1288
1773
  return hashArray;
1289
1774
  },
1290
1775
  verify: async function(ko, crypto, iv, data) {
1291
- 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));
1292
1777
  }
1293
1778
  }
1294
1779
  };
1295
1780
  function getGenerateIVFn(url, opts) {
1296
- const ivhash = opts.ivCalc || url.getParam("ivhash") || "hash";
1781
+ const ivhash = opts.ivCalc || url.getParam("ivHash" /* IV_HASH */) || "hash";
1297
1782
  return generateIV[ivhash] || generateIV["hash"];
1298
1783
  }
1299
1784
  var BlockIvKeyIdCodec = class {
@@ -1308,7 +1793,7 @@ var BlockIvKeyIdCodec = class {
1308
1793
  const calcIv = this.iv || await getGenerateIVFn(this.ko.url, this.opts).calc(this.ko, this.ko.crypto, data);
1309
1794
  const { iv } = this.ko.algo(calcIv);
1310
1795
  const fprt = await this.ko.fingerPrint();
1311
- const keyId = base58btc2.decode(fprt);
1796
+ const keyId = base58btc3.decode(fprt);
1312
1797
  this.ko.logger.Debug().Str("fp", fprt).Msg("encode");
1313
1798
  return CBOR.encode({
1314
1799
  iv,
@@ -1325,9 +1810,9 @@ var BlockIvKeyIdCodec = class {
1325
1810
  }
1326
1811
  const { iv, keyId, data } = CBOR.decode(bytes);
1327
1812
  const fprt = await this.ko.fingerPrint();
1328
- this.ko.logger.Debug().Str("fp", base58btc2.encode(keyId)).Msg("decode");
1329
- if (base58btc2.encode(keyId) !== fprt) {
1330
- throw this.ko.logger.Error().Str("fp", fprt).Str("keyId", base58btc2.encode(keyId)).Msg("keyId mismatch").AsError();
1813
+ this.ko.logger.Debug().Str("fp", base58btc3.encode(keyId)).Msg("decode");
1814
+ if (base58btc3.encode(keyId) !== fprt) {
1815
+ throw this.ko.logger.Error().Str("fp", fprt).Str("keyId", base58btc3.encode(keyId)).Msg("keyId mismatch").AsError();
1331
1816
  }
1332
1817
  const result = await this.ko._decrypt({ iv, bytes: data });
1333
1818
  if (!this.opts?.noIVVerify && !await getGenerateIVFn(this.ko.url, this.opts).verify(this.ko, this.ko.crypto, iv, result)) {
@@ -1414,7 +1899,7 @@ var noCrypto = class {
1414
1899
  }
1415
1900
  };
1416
1901
  async function keyedCryptoFactory(url, kb, sthis) {
1417
- const storekey = url.getParam("storekey");
1902
+ const storekey = url.getParam("storekey" /* STORE_KEY */);
1418
1903
  if (storekey && storekey !== "insecure") {
1419
1904
  let rkey = await kb.getNamedKey(storekey, true);
1420
1905
  if (rkey.isErr()) {
@@ -1429,277 +1914,167 @@ async function keyedCryptoFactory(url, kb, sthis) {
1429
1914
  return new noCrypto(url, kb.rt.crypto, sthis);
1430
1915
  }
1431
1916
 
1432
- // src/blockstore/fragment-gateway.ts
1917
+ // src/blockstore/fp-envelope.ts
1433
1918
  import { Result as Result3 } from "@adviser/cement";
1434
- import { base58btc as base58btc3 } from "multiformats/bases/base58";
1435
- import { encode as encode3, decode as decode3 } from "@fireproof/vendor/cborg";
1436
- function getFragSize(url) {
1437
- const fragSize = url.getParam("fragSize");
1438
- let ret = 0;
1439
- if (fragSize) {
1440
- 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 });
1441
1945
  }
1442
- if (isNaN(ret) || ret <= 0) {
1443
- ret = 0;
1946
+ async start(sthis, url) {
1947
+ const op = { url };
1948
+ return Result4.Ok({ op });
1444
1949
  }
1445
- return ret;
1446
- }
1447
- async function getFrags(url, innerGW, headerSize, logger) {
1448
- const fragSize = getFragSize(url);
1449
- if (!fragSize) {
1450
- const res = await innerGW.get(url);
1451
- if (res.isErr()) {
1452
- return [res];
1453
- }
1454
- const data = res.unwrap();
1455
- return [
1456
- Result3.Ok({
1457
- fid: new Uint8Array(0),
1458
- ofs: 0,
1459
- len: data.length,
1460
- data
1461
- })
1462
- ];
1463
- }
1464
- const firstRaw = await innerGW.get(url.build().setParam("ofs", "0").URI());
1465
- if (firstRaw.isErr()) {
1466
- return [firstRaw];
1467
- }
1468
- const firstFragment = decode3(firstRaw.unwrap());
1469
- const blockSize = firstFragment.data.length;
1470
- const ops = [Promise.resolve(Result3.Ok(firstFragment))];
1471
- const fidStr = base58btc3.encode(firstFragment.fid);
1472
- const fragUrl = url.build().setParam("fid", fidStr).setParam("len", firstFragment.len.toString()).setParam("headerSize", headerSize.toString());
1473
- for (let ofs = blockSize; ofs < firstFragment.len; ofs += blockSize) {
1474
- ops.push(
1475
- (async (furl, ofs2) => {
1476
- const raw2 = await innerGW.get(furl);
1477
- if (raw2.isErr()) {
1478
- return raw2;
1479
- }
1480
- const fragment = decode3(raw2.unwrap());
1481
- if (base58btc3.encode(fragment.fid) !== fidStr) {
1482
- return Result3.Err(logger.Error().Msg("Fragment fid mismatch").AsError());
1483
- }
1484
- if (fragment.ofs !== ofs2) {
1485
- return Result3.Err(logger.Error().Uint64("ofs", ofs2).Msg("Fragment ofs mismatch").AsError());
1486
- }
1487
- return Result3.Ok(fragment);
1488
- })(fragUrl.setParam("ofs", ofs.toString()).URI(), ofs)
1489
- );
1950
+ async close(sthis, url) {
1951
+ const op = { url };
1952
+ return Result4.Ok({ op });
1490
1953
  }
1491
- return Promise.all(ops);
1492
- }
1493
- var FragmentGateway = class {
1494
- constructor(sthis, innerGW) {
1495
- this.fidLength = 4;
1496
- this.headerSize = 32;
1497
- this.sthis = ensureSuperLog(sthis, "FragmentGateway");
1498
- 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) {
1499
1978
  this.innerGW = innerGW;
1979
+ this.interceptor = interceptor || passThrougthGateway;
1500
1980
  }
1501
- slicer(url, body) {
1502
- const fragSize = getFragSize(url);
1503
- if (!fragSize) {
1504
- return [this.innerGW.put(url, body)];
1505
- }
1506
- const blocksize = fragSize - this.headerSize;
1507
- if (blocksize <= 0) {
1508
- throw this.logger.Error().Uint64("fragSize", fragSize).Uint64("headerSize", this.headerSize).Msg("Fragment size is too small").AsError();
1509
- }
1510
- const ops = [];
1511
- const fid = this.sthis.nextId(this.fidLength);
1512
- const fragUrl = url.build().setParam("fid", fid.str).setParam("len", body.length.toString()).setParam("headerSize", this.headerSize.toString());
1513
- for (let ofs = 0; ofs < body.length; ofs += blocksize) {
1514
- const block = encode3({
1515
- fid: fid.bin,
1516
- ofs,
1517
- len: body.length,
1518
- data: body.slice(ofs, ofs + blocksize)
1519
- });
1520
- if (block.length > fragSize) {
1521
- throw this.logger.Error().Uint64("block", block.length).Uint64("fragSize", fragSize).Msg("Block size to big").AsError();
1522
- }
1523
- 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());
1985
+ }
1986
+ const ret = rret.unwrap();
1987
+ if (ret.stop && ret.value) {
1988
+ return ret.value;
1524
1989
  }
1525
- return ops;
1990
+ return this.innerGW.buildUrl(sthis, ret.op.url, ret.op.key, loader);
1526
1991
  }
1527
- buildUrl(baseUrl, key) {
1528
- return this.innerGW.buildUrl(baseUrl, key);
1529
- }
1530
- async destroy(iurl) {
1531
- return this.innerGW.destroy(iurl);
1532
- }
1533
- async start(url) {
1534
- this.headerSize = encode3({
1535
- fid: this.sthis.nextId(this.fidLength).bin,
1536
- ofs: 1024 * 1024,
1537
- // 32bit
1538
- len: 16 * 1024 * 1024,
1539
- // 32bit
1540
- data: new Uint8Array(1024)
1541
- }).length - 1024;
1542
- return this.innerGW.start(url);
1543
- }
1544
- async close(url) {
1545
- return this.innerGW.close(url);
1546
- }
1547
- async put(url, body) {
1548
- await Promise.all(this.slicer(url, body));
1549
- return Result3.Ok(void 0);
1550
- }
1551
- async get(url) {
1552
- const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
1553
- let buffer = void 0;
1554
- for (const rfrag of rfrags) {
1555
- if (rfrag.isErr()) {
1556
- return Result3.Err(rfrag.Err());
1557
- }
1558
- const frag = rfrag.Ok();
1559
- buffer = buffer || new Uint8Array(frag.len);
1560
- buffer.set(frag.data, frag.ofs);
1561
- }
1562
- return Result3.Ok(buffer || new Uint8Array(0));
1563
- }
1564
- async subscribe(url, callback) {
1565
- if (this.innerGW.subscribe) {
1566
- return this.innerGW.subscribe(url, callback);
1567
- } else {
1568
- 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());
1569
1996
  }
1997
+ const ret = rret.unwrap();
1998
+ if (ret.stop && ret.value) {
1999
+ return ret.value;
2000
+ }
2001
+ return this.innerGW.destroy(sthis, ret.op.url, loader);
1570
2002
  }
1571
- async delete(url) {
1572
- const rfrags = await getFrags(url, this.innerGW, this.headerSize, this.logger);
1573
- for (const rfrag of rfrags) {
1574
- if (rfrag.isErr()) {
1575
- return Result3.Err(rfrag.Err());
1576
- }
1577
- const frag = rfrag.Ok();
1578
- const fidStr = base58btc3.encode(frag.fid);
1579
- const fragUrl = url.build().setParam("fid", fidStr).setParam("len", frag.len.toString()).setParam("headerSize", this.headerSize.toString()).URI();
1580
- 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());
1581
2007
  }
1582
- return Result3.Ok(void 0);
2008
+ const ret = rret.unwrap();
2009
+ if (ret.stop && ret.value) {
2010
+ return ret.value;
2011
+ }
2012
+ return await this.innerGW.start(sthis, ret.op.url, loader);
1583
2013
  }
1584
- };
1585
-
1586
- // src/blockstore/meta-key-helper.ts
1587
- import { format, parse } from "@fireproof/vendor/@ipld/dag-json";
1588
- import { EventBlock, decodeEventBlock } from "@fireproof/vendor/@web3-storage/pail/clock";
1589
- import { CID as CID2 } from "multiformats";
1590
- import { base64pad } from "multiformats/bases/base64";
1591
- import { Result as Result4 } from "@adviser/cement";
1592
- async function decodeGatewayMetaBytesToDbMeta(sthis, byteHeads) {
1593
- const crdtEntries = JSON.parse(sthis.txt.decode(byteHeads));
1594
- if (!Array.isArray(crdtEntries)) {
1595
- sthis.logger.Debug().Str("crdtEntries", JSON.stringify(crdtEntries)).Msg("No data in CRDT entries");
1596
- return [];
1597
- }
1598
- if (!crdtEntries.length) {
1599
- sthis.logger.Debug().Any("byteHeads", byteHeads).Msg("No CRDT entries found");
1600
- return [];
1601
- }
1602
- const logger = ensureLogger(sthis, "decodeGatewayMetaBytesToDbMeta");
1603
- return Promise.all(
1604
- crdtEntries.map(async (crdtEntry) => {
1605
- const eventBlock = await decodeEventBlock(base64pad.decode(crdtEntry.data));
1606
- const dbMeta = parse(sthis.txt.decode(eventBlock.value.data.dbMeta));
1607
- logger.Debug().Any("crdtEntry", {
1608
- crdtEntry,
1609
- eventBlock,
1610
- dbMeta,
1611
- dbMetaStrings: dbMeta.cars.map((car) => car.toString())
1612
- }).Msg("CRDT entry");
1613
- return {
1614
- eventCid: eventBlock.cid,
1615
- parents: crdtEntry.parents,
1616
- dbMeta
1617
- };
1618
- })
1619
- );
1620
- }
1621
- async function setCryptoKeyFromGatewayMetaPayload(uri, sthis, data) {
1622
- try {
1623
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Setting crypto key from gateway meta payload");
1624
- const keyInfo = await decodeGatewayMetaBytesToDbMeta(sthis, data);
1625
- if (keyInfo.length) {
1626
- const dbMeta = keyInfo[0].dbMeta;
1627
- if (dbMeta.key) {
1628
- const kb = await getKeyBag(sthis);
1629
- const keyName = getStoreKeyName(uri);
1630
- const res = await kb.setNamedKey(keyName, dbMeta.key);
1631
- if (res.isErr()) {
1632
- sthis.logger.Debug().Str("keyName", keyName).Str("dbMeta.key", dbMeta.key).Msg("Failed to set named key");
1633
- throw res.Err();
1634
- }
1635
- }
1636
- sthis.logger.Debug().Str("dbMeta.key", dbMeta.key).Str("uri", uri.toString()).Msg("Set crypto key from gateway meta payload");
1637
- 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());
2018
+ }
2019
+ const ret = rret.unwrap();
2020
+ if (ret.stop && ret.value) {
2021
+ return ret.value;
1638
2022
  }
1639
- sthis.logger.Debug().Any("data", data).Msg("No crypto in gateway meta payload");
1640
- return Result4.Ok(void 0);
1641
- } catch (error) {
1642
- sthis.logger.Debug().Err(error).Msg("Failed to set crypto key from gateway meta payload");
1643
- return Result4.Err(error);
2023
+ return await this.innerGW.close(sthis, ret.op.url, loader);
1644
2024
  }
1645
- }
1646
- async function addCryptoKeyToGatewayMetaPayload(uri, sthis, body) {
1647
- try {
1648
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Adding crypto key to gateway meta payload");
1649
- const keyName = getStoreKeyName(uri);
1650
- const kb = await getKeyBag(sthis);
1651
- const res = await kb.getNamedExtractableKey(keyName, true);
1652
- if (res.isErr()) {
1653
- sthis.logger.Error().Str("keyName", keyName).Msg("Failed to get named extractable key");
1654
- 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());
1655
2029
  }
1656
- const keyData = await res.Ok().extract();
1657
- const dbMetas = await decodeGatewayMetaBytesToDbMeta(sthis, body);
1658
- const { dbMeta, parents } = dbMetas[0];
1659
- const parentLinks = parents.map((p) => CID2.parse(p));
1660
- dbMeta.key = keyData.keyStr;
1661
- const events = await Promise.all([dbMeta].map((dbMeta2) => createDbMetaEventBlock(sthis, dbMeta2, parentLinks)));
1662
- const encoded = await encodeEventsWithParents(sthis, events, parentLinks);
1663
- sthis.logger.Debug().Str("uri", uri.toString()).Msg("Added crypto key to gateway meta payload");
1664
- return Result4.Ok(encoded);
1665
- } catch (error) {
1666
- sthis.logger.Error().Err(error).Msg("Failed to add crypto key to gateway meta payload");
1667
- return Result4.Err(error);
1668
- }
1669
- }
1670
- function getStoreKeyName(url) {
1671
- const storeKeyName = [url.getParam("localName") || url.getParam("name")];
1672
- const idx = url.getParam("index");
1673
- if (idx) {
1674
- storeKeyName.push(idx);
1675
- }
1676
- storeKeyName.push("data");
1677
- return `@${storeKeyName.join(":")}@`;
1678
- }
1679
- async function createDbMetaEventBlock(sthis, dbMeta, parents) {
1680
- const event = await EventBlock.create(
1681
- {
1682
- dbMeta: sthis.txt.encode(format(dbMeta))
1683
- },
1684
- parents
1685
- );
1686
- return event;
1687
- }
1688
- async function encodeEventsWithParents(sthis, events, parents) {
1689
- const crdtEntries = events.map((event) => {
1690
- const base64String = base64pad.encode(event.bytes);
1691
- return {
1692
- cid: event.cid.toString(),
1693
- data: base64String,
1694
- parents: parents.map((p) => p.toString())
1695
- };
1696
- });
1697
- return sthis.txt.encode(JSON.stringify(crdtEntries));
1698
- }
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
+ };
1699
2076
 
1700
2077
  // src/blockstore/store.ts
1701
- import pRetry from "p-retry";
1702
- import pMap from "p-map";
1703
2078
  function guardVersion(url) {
1704
2079
  if (!url.hasParam("version")) {
1705
2080
  return Result5.Err(`missing version: ${url.toString()}`);
@@ -1707,16 +2082,21 @@ function guardVersion(url) {
1707
2082
  return Result5.Ok(url);
1708
2083
  }
1709
2084
  var BaseStoreImpl = class {
1710
- constructor(name, url, opts, sthis, logger) {
2085
+ // readonly loader: Loadable;
2086
+ constructor(sthis, url, opts, logger) {
1711
2087
  this._onStarted = [];
1712
2088
  this._onClosed = [];
1713
- this.name = name;
1714
2089
  this._url = url;
1715
- this.keybag = opts.keybag;
1716
- this.sthis = sthis;
1717
- this.logger = logger.With().Ref("url", () => this._url.toString()).Str("name", name).Logger();
1718
- this.gateway = new FragmentGateway(this.sthis, opts.gateway);
2090
+ this.opts = opts;
1719
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);
1720
2100
  }
1721
2101
  url() {
1722
2102
  return this._url;
@@ -1731,21 +2111,21 @@ var BaseStoreImpl = class {
1731
2111
  return;
1732
2112
  }
1733
2113
  async keyedCrypto() {
1734
- return keyedCryptoFactory(this._url, await this.keybag(), this.sthis);
2114
+ return keyedCryptoFactory(this._url, await this.loader.keyBag(), this.sthis);
1735
2115
  }
1736
2116
  async start() {
1737
2117
  this.logger.Debug().Str("storeType", this.storeType).Msg("starting-gateway-pre");
1738
- this._url = this._url.build().setParam("store", this.storeType).URI();
1739
- 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);
1740
2120
  if (res.isErr()) {
1741
2121
  this.logger.Error().Result("gw-start", res).Msg("started-gateway");
1742
2122
  return res;
1743
2123
  }
1744
2124
  this._url = res.Ok();
1745
- const kb = await this.keybag();
2125
+ const kb = await this.loader.keyBag();
1746
2126
  const skRes = await kb.ensureKeyFromUrl(this._url, () => {
1747
- const idx = this._url.getParam("index");
1748
- const storeKeyName = [this.name];
2127
+ const idx = this._url.getParam("index" /* INDEX */);
2128
+ const storeKeyName = [this.url().getParam("name" /* NAME */)];
1749
2129
  if (idx) {
1750
2130
  storeKeyName.push(idx);
1751
2131
  }
@@ -1775,10 +2155,23 @@ var BaseStoreImpl = class {
1775
2155
  return version;
1776
2156
  }
1777
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
+ }
1778
2171
  var MetaStoreImpl = class extends BaseStoreImpl {
1779
2172
  // remote: boolean;
1780
- constructor(sthis, name, url, opts) {
1781
- super(name, url, { ...opts }, sthis, ensureLogger(sthis, "MetaStoreImpl"));
2173
+ constructor(sthis, url, opts) {
2174
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "MetaStoreImpl"));
1782
2175
  this.storeType = "meta";
1783
2176
  this.subscribers = /* @__PURE__ */ new Map();
1784
2177
  this.parents = [];
@@ -1788,14 +2181,18 @@ var MetaStoreImpl = class extends BaseStoreImpl {
1788
2181
  ) {
1789
2182
  this.onStarted(async () => {
1790
2183
  this.logger.Debug().Str("url", this.url().toString()).Msg("Subscribing to the gateway");
1791
- opts.gateway.subscribe?.(this.url(), async (message) => {
1792
- this.logger.Debug().Msg("Received message from gateway");
1793
- const dbMetas = await decodeGatewayMetaBytesToDbMeta(this.sthis, message);
1794
- await Promise.all(
1795
- dbMetas.map((dbMeta) => this.loader?.taskManager?.handleEvent(dbMeta.eventCid, dbMeta.parents, dbMeta.dbMeta))
1796
- );
1797
- this.updateParentsFromDbMetas(dbMetas);
1798
- });
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
+ );
1799
2196
  });
1800
2197
  }
1801
2198
  }
@@ -1806,129 +2203,165 @@ var MetaStoreImpl = class extends BaseStoreImpl {
1806
2203
  const dbMetaParentsSet = new Set(dbMetaParents.map((p) => p.toString()));
1807
2204
  this.parents = Array.from(uniqueParentsMap.values()).filter((p) => !dbMetaParentsSet.has(p.toString()));
1808
2205
  }
1809
- async handleByteHeads(byteHeads) {
1810
- return await decodeGatewayMetaBytesToDbMeta(this.sthis, byteHeads);
1811
- }
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
+ // }
1812
2214
  async load() {
1813
2215
  const branch = "main";
1814
- const url = await this.gateway.buildUrl(this.url(), branch);
2216
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
1815
2217
  if (url.isErr()) {
1816
2218
  throw this.logger.Error().Result("buildUrl", url).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
1817
2219
  }
1818
- const bytes = await this.gateway.get(url.Ok());
1819
- if (bytes.isErr()) {
1820
- if (isNotFoundError(bytes)) {
2220
+ const rfpEnv = await this.gateway.get(this.sthis, url.Ok(), this.loader);
2221
+ if (rfpEnv.isErr()) {
2222
+ if (isNotFoundError(rfpEnv)) {
1821
2223
  return void 0;
1822
2224
  }
1823
- 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();
1824
2226
  }
1825
- const dbMetas = await this.handleByteHeads(bytes.Ok());
1826
- 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));
1827
2229
  this.updateParentsFromDbMetas(dbMetas);
1828
2230
  return dbMetas.map((m) => m.dbMeta);
1829
2231
  }
1830
2232
  async save(meta, branch) {
1831
2233
  branch = branch || "main";
1832
2234
  this.logger.Debug().Str("branch", branch).Any("meta", meta).Msg("saving meta");
1833
- const event = await createDbMetaEventBlock(this.sthis, meta, this.parents);
1834
- const bytes = await encodeEventsWithParents(this.sthis, [event], this.parents);
1835
- const url = await this.gateway.buildUrl(this.url(), branch);
2235
+ const url = await this.gateway.buildUrl(this.sthis, this.url(), branch, this.loader);
1836
2236
  if (url.isErr()) {
1837
2237
  throw this.logger.Error().Err(url.Err()).Str("branch", branch).Msg("got error from gateway.buildUrl").AsError();
1838
2238
  }
1839
- this.parents = [event.cid];
1840
- 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
+ );
1841
2249
  if (res.isErr()) {
1842
2250
  throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
1843
2251
  }
1844
2252
  return res;
1845
2253
  }
1846
2254
  async close() {
1847
- await this.gateway.close(this.url());
2255
+ await this.gateway.close(this.sthis, this.url(), this.loader);
1848
2256
  this._onClosed.forEach((fn) => fn());
1849
2257
  return Result5.Ok(void 0);
1850
2258
  }
1851
2259
  async destroy() {
1852
- return this.gateway.destroy(this.url());
2260
+ this.logger.Debug().Msg("destroy");
2261
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
1853
2262
  }
1854
2263
  };
1855
2264
  var DataStoreImpl = class extends BaseStoreImpl {
1856
- // readonly tag: string = "car-base";
1857
- constructor(sthis, name, url, opts) {
1858
- super(name, url, { ...opts }, sthis, ensureLogger(sthis, "DataStoreImpl"));
2265
+ constructor(sthis, url, opts) {
2266
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "DataStoreImpl"));
1859
2267
  this.storeType = "data";
1860
2268
  }
1861
2269
  async load(cid) {
1862
2270
  this.logger.Debug().Any("cid", cid).Msg("loading");
1863
- 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);
1864
2272
  if (url.isErr()) {
1865
2273
  throw this.logger.Error().Err(url.Err()).Str("cid", cid.toString()).Msg("got error from gateway.buildUrl").AsError();
1866
2274
  }
1867
- const res = await this.gateway.get(url.Ok());
2275
+ const res = await this.gateway.get(this.sthis, url.Ok(), this.loader);
1868
2276
  if (res.isErr()) {
1869
2277
  throw res.Err();
1870
2278
  }
1871
- 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
+ }
1872
2288
  }
1873
2289
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
1874
2290
  async save(car, opts) {
1875
2291
  this.logger.Debug().Any("cid", car.cid.toString()).Msg("saving");
1876
- 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);
1877
2293
  if (url.isErr()) {
1878
2294
  throw this.logger.Error().Err(url.Err()).Ref("cid", car.cid).Msg("got error from gateway.buildUrl").AsError();
1879
2295
  }
1880
- 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);
1881
2312
  if (res.isErr()) {
1882
2313
  throw this.logger.Error().Err(res.Err()).Msg("got error from gateway.put").AsError();
1883
2314
  }
1884
2315
  return res.Ok();
1885
2316
  }
1886
2317
  async remove(cid) {
1887
- 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);
1888
2319
  if (url.isErr()) {
1889
2320
  return url;
1890
2321
  }
1891
- return this.gateway.delete(url.Ok());
2322
+ return this.gateway.delete(this.sthis, url.Ok(), this.loader);
1892
2323
  }
1893
2324
  async close() {
1894
- await this.gateway.close(this.url());
2325
+ await this.gateway.close(this.sthis, this.url(), this.loader);
1895
2326
  this._onClosed.forEach((fn) => fn());
1896
2327
  return Result5.Ok(void 0);
1897
2328
  }
1898
2329
  destroy() {
1899
- return this.gateway.destroy(this.url());
2330
+ this.logger.Debug().Msg("destroy");
2331
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
1900
2332
  }
1901
2333
  };
1902
2334
  var WALStoreImpl = class extends BaseStoreImpl {
1903
- constructor(loader, url, opts) {
1904
- super(loader.name, url, { ...opts }, loader.sthis, ensureLogger(loader.sthis, "WALStoreImpl"));
2335
+ constructor(sthis, url, opts) {
2336
+ super(sthis, url, { ...opts }, ensureLogger(sthis, "WALStoreImpl"));
1905
2337
  this.storeType = "wal";
1906
- this._ready = new ResolveOnce3();
2338
+ // readonly tag: string = "rwal-base";
2339
+ // readonly loader: Loadable;
2340
+ this._ready = new ResolveOnce4();
1907
2341
  this.walState = { operations: [], noLoaderOps: [], fileOperations: [] };
1908
2342
  this.processing = void 0;
1909
2343
  this.processQueue = new CommitQueue();
1910
- this.loader = loader;
1911
2344
  }
1912
2345
  async ready() {
1913
2346
  return this._ready.once(async () => {
1914
2347
  const walState = await this.load().catch((e) => {
1915
- this.logger.Error().Any("error", e).Msg("error loading wal");
2348
+ this.logger.Error().Err(e).Msg("error loading wal");
1916
2349
  return void 0;
1917
2350
  });
1918
- if (!walState) {
1919
- this.walState.operations = [];
1920
- this.walState.fileOperations = [];
1921
- } else {
1922
- this.walState.operations = walState.operations || [];
1923
- 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);
1924
2356
  }
1925
2357
  });
1926
2358
  }
1927
2359
  async enqueue(dbMeta, opts) {
1928
2360
  await this.ready();
1929
2361
  if (opts.compact) {
1930
- this.walState.operations = [];
1931
- 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);
1932
2365
  } else if (opts.noLoader) {
1933
2366
  this.walState.noLoaderOps.push(dbMeta);
1934
2367
  } else {
@@ -1958,6 +2391,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
1958
2391
  });
1959
2392
  }
1960
2393
  async _doProcess() {
2394
+ if (!this.loader) return;
1961
2395
  if (!this.loader.remoteCarStore) return;
1962
2396
  const operations = [...this.walState.operations];
1963
2397
  const noLoaderOps = [...this.walState.noLoaderOps];
@@ -1975,6 +2409,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
1975
2409
  noLoaderOps,
1976
2410
  async (dbMeta) => {
1977
2411
  await retryableUpload(async () => {
2412
+ if (!this.loader) {
2413
+ return;
2414
+ }
1978
2415
  for (const cid of dbMeta.cars) {
1979
2416
  const car = await (await this.loader.carStore()).load(cid);
1980
2417
  if (!car) {
@@ -1985,7 +2422,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
1985
2422
  await throwFalsy(this.loader.remoteCarStore).save(car);
1986
2423
  }
1987
2424
  }
1988
- this.walState.noLoaderOps = this.walState.noLoaderOps.filter((op) => op !== dbMeta);
2425
+ inplaceFilter(this.walState.noLoaderOps, (op) => op !== dbMeta);
1989
2426
  }, `noLoaderOp with dbMeta.cars=${dbMeta.cars.toString()}`);
1990
2427
  },
1991
2428
  { concurrency: concurrencyLimit }
@@ -1994,6 +2431,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
1994
2431
  operations,
1995
2432
  async (dbMeta) => {
1996
2433
  await retryableUpload(async () => {
2434
+ if (!this.loader) {
2435
+ return;
2436
+ }
1997
2437
  for (const cid of dbMeta.cars) {
1998
2438
  const car = await (await this.loader.carStore()).load(cid);
1999
2439
  if (!car) {
@@ -2004,7 +2444,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
2004
2444
  await throwFalsy(this.loader.remoteCarStore).save(car);
2005
2445
  }
2006
2446
  }
2007
- this.walState.operations = this.walState.operations.filter((op) => op !== dbMeta);
2447
+ inplaceFilter(this.walState.operations, (op) => op !== dbMeta);
2008
2448
  }, `operation with dbMeta.cars=${dbMeta.cars.toString()}`);
2009
2449
  },
2010
2450
  { concurrency: concurrencyLimit }
@@ -2013,12 +2453,15 @@ var WALStoreImpl = class extends BaseStoreImpl {
2013
2453
  fileOperations,
2014
2454
  async ({ cid: fileCid, public: publicFile }) => {
2015
2455
  await retryableUpload(async () => {
2456
+ if (!this.loader) {
2457
+ return;
2458
+ }
2016
2459
  const fileBlock = await (await this.loader.fileStore()).load(fileCid);
2017
2460
  if (!fileBlock) {
2018
2461
  throw this.logger.Error().Ref("cid", fileCid).Msg("missing file block").AsError();
2019
2462
  }
2020
2463
  await this.loader.remoteFileStore?.save(fileBlock, { public: publicFile });
2021
- this.walState.fileOperations = this.walState.fileOperations.filter((op) => op.cid !== fileCid);
2464
+ inplaceFilter(this.walState.fileOperations, (op) => op.cid !== fileCid);
2022
2465
  }, `fileOperation with cid=${fileCid.toString()}`);
2023
2466
  },
2024
2467
  { concurrency: concurrencyLimit }
@@ -2026,6 +2469,9 @@ var WALStoreImpl = class extends BaseStoreImpl {
2026
2469
  if (operations.length) {
2027
2470
  const lastOp = operations[operations.length - 1];
2028
2471
  await retryableUpload(async () => {
2472
+ if (!this.loader) {
2473
+ return;
2474
+ }
2029
2475
  await this.loader.remoteMetaStore?.save(lastOp);
2030
2476
  }, `remoteMetaStore save with dbMeta.cars=${lastOp.cars.toString()}`);
2031
2477
  }
@@ -2038,251 +2484,715 @@ var WALStoreImpl = class extends BaseStoreImpl {
2038
2484
  }
2039
2485
  async load() {
2040
2486
  this.logger.Debug().Msg("loading");
2041
- const filepath = await this.gateway.buildUrl(this.url(), "main");
2487
+ const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
2042
2488
  if (filepath.isErr()) {
2043
2489
  throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
2044
2490
  }
2045
- const bytes = await this.gateway.get(filepath.Ok());
2491
+ const bytes = await this.gateway.get(this.sthis, filepath.Ok(), this.loader);
2046
2492
  if (bytes.isErr()) {
2047
2493
  if (isNotFoundError(bytes)) {
2048
2494
  return void 0;
2049
2495
  }
2050
2496
  throw this.logger.Error().Err(bytes.Err()).Msg("error get").AsError();
2051
2497
  }
2052
- try {
2053
- return bytes && parse2(this.sthis.txt.decode(bytes.Ok()));
2054
- } catch (e) {
2055
- 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();
2500
+ }
2501
+ return bytes.Ok().payload;
2502
+ }
2503
+ async save(state) {
2504
+ const filepath = await this.gateway.buildUrl(this.sthis, this.url(), "main", this.loader);
2505
+ if (filepath.isErr()) {
2506
+ throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
2507
+ }
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
+ );
2517
+ if (res.isErr()) {
2518
+ throw this.logger.Error().Err(res.Err()).Str("filePath", filepath.Ok().toString()).Msg("error saving").AsError();
2519
+ }
2520
+ }
2521
+ async close() {
2522
+ await this.gateway.close(this.sthis, this.url(), this.loader);
2523
+ this._onClosed.forEach((fn) => fn());
2524
+ return Result5.Ok(void 0);
2525
+ }
2526
+ destroy() {
2527
+ this.logger.Debug().Msg("destroy");
2528
+ return this.gateway.destroy(this.sthis, this.url(), this.loader);
2529
+ }
2530
+ };
2531
+
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"));
2056
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();
2805
+ }
2806
+ }
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
+ });
2057
2890
  }
2058
- async save(state) {
2059
- const filepath = await this.gateway.buildUrl(this.url(), "main");
2060
- if (filepath.isErr()) {
2061
- throw this.logger.Error().Err(filepath.Err()).Url(this.url()).Msg("error building url").AsError();
2062
- }
2063
- let encoded;
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 = [];
2064
2901
  try {
2065
- encoded = format2(state);
2902
+ files = await this.fs.readdir(filepath);
2066
2903
  } catch (e) {
2067
- throw this.logger.Error().Err(e).Any("state", state).Msg("error format").AsError();
2904
+ if (!isNotFoundError(e)) {
2905
+ throw sthis.logger.Error().Err(e).Str("dir", filepath).Msg("destroy:readdir").AsError();
2906
+ }
2068
2907
  }
2069
- const res = await this.gateway.put(filepath.Ok(), this.sthis.txt.encode(encoded));
2070
- if (res.isErr()) {
2071
- throw this.logger.Error().Err(res.Err()).Str("filePath", filepath.Ok().toString()).Msg("error saving").AsError();
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
+ }
2072
2917
  }
2918
+ return Result8.Ok(void 0);
2073
2919
  }
2074
- async close() {
2075
- await this.gateway.close(this.url());
2076
- this._onClosed.forEach((fn) => fn());
2077
- return Result5.Ok(void 0);
2078
- }
2079
- destroy() {
2080
- return this.gateway.destroy(this.url());
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);
2081
2927
  }
2082
2928
  };
2083
2929
 
2084
- // src/blockstore/store-factory.ts
2085
- function ensureIsIndex(url, isIndex) {
2086
- if (isIndex) {
2087
- return url.build().setParam("index", isIndex).URI();
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;
2088
2935
  }
2089
- return url.build().delParam("index").URI();
2090
- }
2091
- function ensureName(name, url) {
2092
- if (!url.hasParam("name")) {
2093
- return url.build().setParam("name", name).URI();
2936
+ start(sthis, baseURL) {
2937
+ return this.gw.start(baseURL, sthis);
2094
2938
  }
2095
- return url;
2096
- }
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);
2963
+ }
2964
+ };
2965
+
2966
+ // src/blockstore/register-store-protocol.ts
2097
2967
  var storeFactory = /* @__PURE__ */ new Map();
2098
- function buildURL(optURL, loader) {
2099
- const storeOpts = loader.ebOpts.store;
2100
- const obuItem = Array.from(storeFactory.values()).find((items) => items.overrideBaseURL);
2101
- let obuUrl;
2102
- if (obuItem && obuItem.overrideBaseURL) {
2103
- obuUrl = URI5.from(obuItem.overrideBaseURL);
2104
- }
2105
- const ret = ensureIsIndex(
2106
- URI5.from(optURL || obuUrl || dataDir(loader.sthis, loader.name, storeOpts.stores?.base)),
2107
- storeOpts.isIndex
2108
- );
2109
- return ret;
2110
- }
2111
- var onceGateway = new KeyedResolvOnce2();
2112
- async function getGatewayFromURL(url, sthis) {
2113
- return onceGateway.get(url.toString()).once(async () => {
2114
- const item = storeFactory.get(url.protocol);
2115
- if (item) {
2116
- const ret = {
2117
- gateway: await item.gateway(sthis),
2118
- test: await item.test(sthis)
2119
- };
2120
- const res = await ret.gateway.start(url);
2121
- if (res.isErr()) {
2122
- sthis.logger.Error().Result("start", res).Msg("start failed");
2123
- return void 0;
2124
- }
2125
- return ret;
2968
+ function getDefaultURI(sthis, protocol) {
2969
+ if (protocol) {
2970
+ if (!protocol.endsWith(":")) {
2971
+ protocol += ":";
2126
2972
  }
2127
- sthis.logger.Warn().Url(url).Msg("unsupported protocol");
2128
- return void 0;
2129
- });
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);
2130
2983
  }
2131
2984
  function registerStoreProtocol(item) {
2132
2985
  let protocol = item.protocol;
2133
2986
  if (!protocol.endsWith(":")) {
2134
2987
  protocol += ":";
2135
2988
  }
2136
- if (storeFactory.has(protocol)) {
2137
- if (!item.overrideBaseURL && storeFactory.get(protocol) !== item) {
2138
- throw new Error(`we need a logger here`);
2139
- return () => {
2140
- };
2141
- }
2989
+ if (!item.serdegateway && !item.gateway) {
2990
+ throw new Error(`registerStoreProtocol needs a gateway or serdegateway`);
2142
2991
  }
2143
- 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) {
2144
3002
  Array.from(storeFactory.values()).forEach((items) => {
2145
- items.overrideBaseURL = void 0;
3003
+ items.isDefault = false;
2146
3004
  });
2147
3005
  }
2148
- storeFactory.set(protocol, item);
3006
+ storeFactory.set(protocol, {
3007
+ ...item,
3008
+ serdegateway
3009
+ });
2149
3010
  return () => {
2150
3011
  storeFactory.delete(protocol);
2151
3012
  };
2152
3013
  }
2153
- var onceDataStoreFactory = new KeyedResolvOnce2();
2154
- async function dataStoreFactory(loader) {
2155
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.data, loader)).build().setParam("store", "data").URI();
2156
- const sthis = ensureSuperLog(loader.sthis, "dataStoreFactory", { url: url.toString() });
2157
- return onceDataStoreFactory.get(url.toString()).once(async () => {
2158
- const gateway = await getGatewayFromURL(url, sthis);
2159
- if (!gateway) {
2160
- 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)));
2161
3035
  }
2162
- const store = new DataStoreImpl(sthis, loader.name, url, {
2163
- gateway: gateway.gateway,
2164
- keybag: () => getKeyBag(loader.sthis, {
2165
- ...loader.ebOpts.keyBag
2166
- })
2167
- });
2168
- return store;
2169
3036
  });
2170
3037
  }
2171
- var onceMetaStoreFactory = new KeyedResolvOnce2();
2172
- async function metaStoreFactory(loader) {
2173
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.meta, loader)).build().setParam("store", "meta").URI();
2174
- const sthis = ensureSuperLog(loader.sthis, "metaStoreFactory", { url: () => url.toString() });
2175
- return onceMetaStoreFactory.get(url.toString()).once(async () => {
2176
- sthis.logger.Debug().Str("protocol", url.protocol).Msg("pre-protocol switch");
2177
- const gateway = await getGatewayFromURL(url, sthis);
2178
- if (!gateway) {
2179
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2180
- }
2181
- const store = new MetaStoreImpl(loader.sthis, loader.name, url, {
2182
- gateway: gateway.gateway,
2183
- keybag: () => getKeyBag(loader.sthis, {
2184
- ...loader.ebOpts.keyBag
2185
- })
2186
- });
2187
- 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
+ }
2188
3049
  });
2189
3050
  }
2190
- var onceRemoteWalFactory = new KeyedResolvOnce2();
2191
- async function remoteWalFactory(loader) {
2192
- const url = ensureName(loader.name, buildURL(loader.ebOpts.store.stores?.wal, loader)).build().setParam("store", "wal").URI();
2193
- const sthis = ensureSuperLog(loader.sthis, "remoteWalFactory", { url: url.toString() });
2194
- return onceRemoteWalFactory.get(url.toString()).once(async () => {
2195
- const gateway = await getGatewayFromURL(url, sthis);
2196
- if (!gateway) {
2197
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2198
- }
2199
- sthis.logger.Debug().Str("prepared", url.toString()).Msg("produced");
2200
- const store = new WALStoreImpl(loader, url, {
2201
- gateway: gateway.gateway,
2202
- keybag: () => getKeyBag(loader.sthis, {
2203
- ...loader.ebOpts.keyBag
2204
- })
2205
- });
2206
- 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());
2207
3083
  });
2208
3084
  }
2209
- async function testStoreFactory(url, sthis) {
2210
- sthis = ensureSuperLog(sthis, "testStoreFactory");
2211
- const gateway = await getGatewayFromURL(url, sthis);
2212
- if (!gateway) {
2213
- throw sthis.logger.Error().Url(url).Msg("gateway not found").AsError();
2214
- }
2215
- 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;
2216
3126
  }
2217
- async function ensureStart(store, logger) {
3127
+ async function ensureStart(store) {
2218
3128
  const ret = await store.start();
2219
3129
  if (ret.isErr()) {
2220
- throw logger.Error().Result("start", ret).Msg("start failed").AsError();
3130
+ throw store.logger.Error().Result("start", ret).Msg("start failed").AsError();
2221
3131
  }
2222
- logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
3132
+ store.logger.Debug().Url(ret.Ok(), "prepared").Msg("produced");
2223
3133
  return store;
2224
3134
  }
2225
- function toStoreRuntime(opts, sthis) {
2226
- const logger = ensureLogger(sthis, "toStoreRuntime", {});
3135
+ function ensureStoreEnDeFile(ende) {
3136
+ ende = ende || {};
2227
3137
  return {
2228
- makeMetaStore: async (loader) => {
2229
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeMetaStore).Msg("makeMetaStore");
2230
- return ensureStart(await (loader.ebOpts.store.makeMetaStore || metaStoreFactory)(loader), logger);
2231
- },
2232
- makeDataStore: async (loader) => {
2233
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeDataStore).Msg("makeDataStore");
2234
- return ensureStart(await (loader.ebOpts.store.makeDataStore || dataStoreFactory)(loader), logger);
2235
- },
2236
- makeWALStore: async (loader) => {
2237
- logger.Debug().Str("fromOpts", "" + !!loader.ebOpts.store.makeWALStore).Msg("makeRemoteWAL");
2238
- return ensureStart(await (loader.ebOpts.store.makeWALStore || remoteWalFactory)(loader), logger);
2239
- },
2240
- encodeFile: opts.encodeFile || encodeFile,
2241
- decodeFile: opts.decodeFile || decodeFile
3138
+ encodeFile: ende.encodeFile || encodeFile,
3139
+ decodeFile: ende.decodeFile || decodeFile
3140
+ };
3141
+ }
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)
2242
3169
  };
2243
3170
  }
2244
- registerStoreProtocol({
2245
- protocol: "file:",
2246
- gateway: async (sthis) => {
2247
- const { FileGateway } = await import("./gateway-VVS4QWDA.js");
2248
- return new FileGateway(sthis);
2249
- },
2250
- test: async (sthis) => {
2251
- const { FileTestStore } = await import("./gateway-VVS4QWDA.js");
2252
- return new FileTestStore(sthis);
2253
- }
2254
- });
2255
- registerStoreProtocol({
2256
- protocol: "indexdb:",
2257
- gateway: async (sthis) => {
2258
- const { IndexDBGateway } = await import("./gateway-C62S56GY.js");
2259
- return new IndexDBGateway(sthis);
2260
- },
2261
- test: async (sthis) => {
2262
- const { IndexDBTestStore } = await import("./gateway-C62S56GY.js");
2263
- return new IndexDBTestStore(sthis);
2264
- }
2265
- });
2266
3171
 
2267
3172
  // src/blockstore/store-remote.ts
2268
- async function RemoteDataStore(sthis, name, url, opts) {
2269
- const ds = new DataStoreImpl(sthis, name, url, opts);
3173
+ async function RemoteDataStore(sthis, url, opts) {
3174
+ const ds = new DataStoreImpl(sthis, url, opts);
2270
3175
  await ds.start();
2271
3176
  return ds;
2272
3177
  }
2273
- async function RemoteMetaStore(sthis, name, url, opts) {
2274
- const ms = new MetaStoreImpl(
2275
- sthis,
2276
- name,
2277
- url,
2278
- opts
2279
- /* , true*/
2280
- );
3178
+ async function RemoteMetaStore(sthis, url, opts) {
3179
+ const ms = new MetaStoreImpl(sthis, url, opts);
2281
3180
  await ms.start();
2282
3181
  return ms;
2283
3182
  }
2284
3183
 
2285
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
+ }
2286
3196
  var ConnectionBase = class {
2287
3197
  constructor(url, logger) {
2288
3198
  this.loaded = Promise.resolve();
@@ -2293,23 +3203,26 @@ var ConnectionBase = class {
2293
3203
  await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load();
2294
3204
  await (await throwFalsy(this.loader).WALStore()).process();
2295
3205
  }
2296
- async connect_X({ loader }) {
2297
- if (!loader) throw this.logger.Error().Msg("loader is required").AsError();
2298
- await this.connectMeta_X({ loader });
2299
- await this.connectStorage_X({ loader });
3206
+ async connect(refl) {
3207
+ await this.connectMeta(refl);
3208
+ await this.connectStorage(refl);
2300
3209
  }
2301
- async connectMeta_X({ loader }) {
2302
- 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();
2303
3213
  this.loader = loader;
2304
3214
  await this.onConnect();
2305
- const metaUrl = this.url.build().defParam("store", "meta").URI();
2306
- const gateway = await getGatewayFromURL(metaUrl, this.loader.sthis);
2307
- if (!gateway) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: gateway is required").AsError();
2308
- const dbName = metaUrl.getParam("name");
2309
- if (!dbName) throw this.logger.Error().Url(metaUrl).Msg("connectMeta_X: name is required").AsError();
2310
- 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, {
2311
3225
  gateway: gateway.gateway,
2312
- keybag: () => getKeyBag(loader.sthis, loader.ebOpts.keyBag),
2313
3226
  loader
2314
3227
  });
2315
3228
  this.loader.remoteMetaStore = remote;
@@ -2319,17 +3232,19 @@ var ConnectionBase = class {
2319
3232
  });
2320
3233
  });
2321
3234
  }
2322
- async connectStorage_X({ loader }) {
3235
+ async connectStorage(refl) {
3236
+ const loader = coerceLoader(refl);
2323
3237
  if (!loader) throw this.logger.Error().Msg("connectStorage_X: loader is required").AsError();
2324
3238
  this.loader = loader;
2325
- const dataUrl = this.url.build().defParam("store", "data").URI();
2326
- const gateway = await getGatewayFromURL(dataUrl, this.loader.sthis);
2327
- if (!gateway) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: gateway is required").AsError();
2328
- 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 */);
2329
3244
  if (!name) throw this.logger.Error().Url(dataUrl).Msg("connectStorage_X: name is required").AsError;
2330
- loader.remoteCarStore = await RemoteDataStore(loader.sthis, name, this.url, {
2331
- gateway: gateway.gateway,
2332
- keybag: () => getKeyBag(loader.sthis, this.loader?.ebOpts.keyBag)
3245
+ loader.remoteCarStore = await RemoteDataStore(loader.sthis, this.url, {
3246
+ gateway: rgateway.Ok().gateway,
3247
+ loader
2333
3248
  });
2334
3249
  loader.remoteFileStore = loader.remoteCarStore;
2335
3250
  }
@@ -2341,9 +3256,9 @@ var ConnectionBase = class {
2341
3256
  // // await this.compact()
2342
3257
  // // }
2343
3258
  // const currents = await this.loader?.metaStore?.load()
2344
- // if (!currents) throw new Error("Can't sync empty database: save data first")
3259
+ // if (!currents) throw new Error("Can't sync empty ledger: save data first")
2345
3260
  // if (currents.length > 1)
2346
- // throw new Error("Can't sync database with split heads: make an update first")
3261
+ // throw new Error("Can't sync ledger with split heads: make an update first")
2347
3262
  // const current = currents[0]
2348
3263
  // const params = {
2349
3264
  // car: current.car.toString()
@@ -2369,6 +3284,12 @@ var ConnectionBase = class {
2369
3284
  };
2370
3285
 
2371
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";
2372
3293
  function time(tag) {
2373
3294
  }
2374
3295
  function timeEnd(tag) {
@@ -2436,7 +3357,7 @@ async function processFiles(store, blocks, doc, logger) {
2436
3357
  }
2437
3358
  async function processFileset(logger, store, blocks, files) {
2438
3359
  const dbBlockstore = blocks.parent;
2439
- if (!dbBlockstore.loader) throw logger.Error().Msg("Missing loader, database name is required").AsError();
3360
+ if (!dbBlockstore.loader) throw logger.Error().Msg("Missing loader, ledger name is required").AsError();
2440
3361
  const t = new CarTransaction(dbBlockstore);
2441
3362
  const didPut = [];
2442
3363
  for (const filename in files) {
@@ -2468,7 +3389,7 @@ async function processFileset(logger, store, blocks, files) {
2468
3389
  }
2469
3390
  }
2470
3391
  async function getValueFromCrdt(blocks, head, key, logger) {
2471
- if (!head.length) throw logger.Debug().Msg("Getting from an empty database").AsError();
3392
+ if (!head.length) throw logger.Debug().Msg("Getting from an empty ledger").AsError();
2472
3393
  const link = await get(blocks, head, key);
2473
3394
  if (!link) throw logger.Error().Str("key", key).Msg(`Missing key`).AsError();
2474
3395
  return await getValueFromLink(blocks, link, logger);
@@ -2626,7 +3547,7 @@ async function doCompact(blockLog, head, logger) {
2626
3547
  isCompacting = false;
2627
3548
  }
2628
3549
  async function getBlock(blocks, cidString) {
2629
- const block = await blocks.get(parse3(cidString));
3550
+ const block = await blocks.get(parse2(cidString));
2630
3551
  if (!block) throw new Error(`Missing block ${cidString}`);
2631
3552
  const { cid, value } = await decode({ bytes: block.bytes, codec, hasher: hasher5 });
2632
3553
  return new Block({ cid, value, bytes: block.bytes });
@@ -2686,7 +3607,8 @@ function makeProllyGetBlock(blocks) {
2686
3607
  return create({ cid, bytes, hasher: hasher6, codec: codec2 });
2687
3608
  };
2688
3609
  }
2689
- async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
3610
+ async function bulkIndex(logger, tblocks, inIndex, indexEntries, opts) {
3611
+ logger.Debug().Msg("enter bulkIndex");
2690
3612
  if (!indexEntries.length) return inIndex;
2691
3613
  if (!inIndex.root) {
2692
3614
  if (!inIndex.cid) {
@@ -2703,18 +3625,22 @@ async function bulkIndex(tblocks, inIndex, indexEntries, opts) {
2703
3625
  returnNode = node;
2704
3626
  }
2705
3627
  if (!returnNode || !returnRootBlock) throw new Error("failed to create index");
3628
+ logger.Debug().Msg("exit !root bulkIndex");
2706
3629
  return { root: returnNode, cid: returnRootBlock.cid };
2707
3630
  } else {
2708
3631
  inIndex.root = await DbIndex.load({ cid: inIndex.cid, get: makeProllyGetBlock(tblocks), ...opts });
2709
3632
  }
2710
3633
  }
3634
+ logger.Debug().Msg("pre bulk bulkIndex");
2711
3635
  const { root: root3, blocks: newBlocks } = await inIndex.root.bulk(indexEntries);
2712
3636
  if (root3) {
3637
+ logger.Debug().Msg("pre root put bulkIndex");
2713
3638
  for await (const block of newBlocks) {
2714
3639
  await tblocks.put(block.cid, block.bytes);
2715
3640
  }
2716
3641
  return { root: root3, cid: (await root3.block).cid };
2717
3642
  } else {
3643
+ logger.Debug().Msg("pre !root bulkIndex");
2718
3644
  return { root: void 0, cid: void 0 };
2719
3645
  }
2720
3646
  }
@@ -2754,17 +3680,17 @@ function encodeKey(key) {
2754
3680
  }
2755
3681
 
2756
3682
  // src/indexer.ts
2757
- function index(sthis, { _crdt }, name, mapFn, meta) {
2758
- if (mapFn && meta) throw _crdt.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
2759
- if (mapFn && mapFn.constructor.name !== "Function") throw _crdt.logger.Error().Msg("mapFn must be a function").AsError();
2760
- if (_crdt.indexers.has(name)) {
2761
- 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);
2762
3688
  idx.applyMapFn(name, mapFn, meta);
2763
3689
  } else {
2764
- const idx = new Index(sthis, _crdt, name, mapFn, meta);
2765
- _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);
2766
3692
  }
2767
- return _crdt.indexers.get(name);
3693
+ return refDb.crdt.indexers.get(name);
2768
3694
  }
2769
3695
  var Index = class {
2770
3696
  constructor(sthis, crdt, name, mapFn, meta) {
@@ -2783,18 +3709,9 @@ var Index = class {
2783
3709
  return Promise.all([this.blockstore.ready(), this.crdt.ready()]).then(() => {
2784
3710
  });
2785
3711
  }
2786
- close() {
2787
- return Promise.all([this.blockstore.close(), this.crdt.close()]).then(() => {
2788
- });
2789
- }
2790
- destroy() {
2791
- return Promise.all([this.blockstore.destroy(), this.crdt.destroy()]).then(() => {
2792
- });
2793
- }
2794
3712
  applyMapFn(name, mapFn, meta) {
2795
3713
  if (mapFn && meta) throw this.logger.Error().Msg("cannot provide both mapFn and meta").AsError();
2796
3714
  if (this.name && this.name !== name) throw this.logger.Error().Msg("cannot change name").AsError();
2797
- this.name = name;
2798
3715
  try {
2799
3716
  if (meta) {
2800
3717
  if (this.indexHead && this.indexHead.map((c) => c.toString()).join() !== meta.head.map((c) => c.toString()).join()) {
@@ -2842,9 +3759,13 @@ var Index = class {
2842
3759
  }
2843
3760
  }
2844
3761
  async query(opts = {}) {
3762
+ this.logger.Debug().Msg("enter query");
2845
3763
  await this.ready();
3764
+ this.logger.Debug().Msg("post ready query");
2846
3765
  await this._updateIndex();
3766
+ this.logger.Debug().Msg("post _updateIndex query");
2847
3767
  await this._hydrateIndex();
3768
+ this.logger.Debug().Msg("post _hydrateIndex query");
2848
3769
  if (!this.byKey.root) {
2849
3770
  return await applyQuery(this.crdt, { result: [] }, opts);
2850
3771
  }
@@ -2900,13 +3821,16 @@ var Index = class {
2900
3821
  }
2901
3822
  async _updateIndex() {
2902
3823
  await this.ready();
3824
+ this.logger.Debug().Msg("enter _updateIndex");
2903
3825
  if (this.initError) throw this.initError;
2904
3826
  if (!this.mapFn) throw this.logger.Error().Msg("No map function defined").AsError();
2905
3827
  let result, head;
2906
3828
  if (!this.indexHead || this.indexHead.length === 0) {
2907
3829
  ({ result, head } = await this.crdt.allDocs());
3830
+ this.logger.Debug().Msg("enter crdt.allDocs");
2908
3831
  } else {
2909
3832
  ({ result, head } = await this.crdt.changes(this.indexHead));
3833
+ this.logger.Debug().Msg("enter crdt.changes");
2910
3834
  }
2911
3835
  if (result.length === 0) {
2912
3836
  this.indexHead = head;
@@ -2939,9 +3863,22 @@ var Index = class {
2939
3863
  if (result.length === 0) {
2940
3864
  return indexerMeta;
2941
3865
  }
3866
+ this.logger.Debug().Msg("pre this.blockstore.transaction");
2942
3867
  const { meta } = await this.blockstore.transaction(async (tblocks) => {
2943
- this.byId = await bulkIndex(tblocks, this.byId, removeIdIndexEntries.concat(byIdIndexEntries), byIdOpts);
2944
- 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
+ );
2945
3882
  this.indexHead = head;
2946
3883
  if (this.byId.cid && this.byKey.cid) {
2947
3884
  const idxMeta = {
@@ -2953,8 +3890,10 @@ var Index = class {
2953
3890
  };
2954
3891
  indexerMeta.indexes?.set(this.name, idxMeta);
2955
3892
  }
3893
+ this.logger.Debug().Any("indexerMeta", new Array(indexerMeta.indexes?.entries())).Msg("exit this.blockstore.transaction fn");
2956
3894
  return indexerMeta;
2957
3895
  });
3896
+ this.logger.Debug().Msg("post this.blockstore.transaction");
2958
3897
  return meta;
2959
3898
  }
2960
3899
  };
@@ -2962,7 +3901,7 @@ var Index = class {
2962
3901
  // src/crdt-clock.ts
2963
3902
  import { advance } from "@fireproof/vendor/@web3-storage/pail/clock";
2964
3903
  import { root as root2 } from "@fireproof/vendor/@web3-storage/pail/crdt";
2965
- import { ResolveOnce as ResolveOnce4 } from "@adviser/cement";
3904
+ import { ResolveOnce as ResolveOnce5 } from "@adviser/cement";
2966
3905
 
2967
3906
  // src/apply-head-queue.ts
2968
3907
  function applyHeadQueue(worker, logger) {
@@ -3019,7 +3958,7 @@ var CRDTClock = class {
3019
3958
  this.zoomers = /* @__PURE__ */ new Set();
3020
3959
  this.watchers = /* @__PURE__ */ new Set();
3021
3960
  this.emptyWatchers = /* @__PURE__ */ new Set();
3022
- this._ready = new ResolveOnce4();
3961
+ this._ready = new ResolveOnce5();
3023
3962
  this.blockstore = blockstore;
3024
3963
  this.logger = ensureLogger(blockstore.sthis, "CRDTClock");
3025
3964
  this.applyHeadQueue = applyHeadQueue(this.int_applyHead.bind(this), this.logger);
@@ -3130,15 +4069,13 @@ async function advanceBlocks(logger, newHead, tblocks, head) {
3130
4069
 
3131
4070
  // src/crdt.ts
3132
4071
  var CRDT = class {
3133
- constructor(sthis, name, opts = {}) {
4072
+ constructor(sthis, opts) {
3134
4073
  this.indexers = /* @__PURE__ */ new Map();
3135
- this.onceReady = new ResolveOnce5();
4074
+ this.onceReady = new ResolveOnce6();
3136
4075
  this.sthis = sthis;
3137
- this.name = name;
3138
4076
  this.logger = ensureLogger(sthis, "CRDT");
3139
4077
  this.opts = opts;
3140
- this.blockstore = blockstoreFactory(sthis, {
3141
- name,
4078
+ this.blockstore = new EncryptedBlockstore(sthis, {
3142
4079
  applyMeta: async (meta) => {
3143
4080
  const crdtMeta = meta;
3144
4081
  if (!crdtMeta.head) throw this.logger.Error().Msg("missing head").AsError();
@@ -3148,23 +4085,29 @@ var CRDT = class {
3148
4085
  await doCompact(blocks, this.clock.head, this.logger);
3149
4086
  return { head: this.clock.head };
3150
4087
  },
3151
- autoCompact: this.opts.autoCompact || 100,
3152
- store: { ...this.opts.store, isIndex: void 0 },
3153
- public: this.opts.public,
3154
- meta: this.opts.meta,
3155
- 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,
3156
4096
  });
3157
- this.indexBlockstore = blockstoreFactory(sthis, {
3158
- name,
4097
+ this.indexBlockstore = new EncryptedBlockstore(sthis, {
4098
+ // name: opts.name,
3159
4099
  applyMeta: async (meta) => {
3160
4100
  const idxCarMeta = meta;
3161
4101
  if (!idxCarMeta.indexes) throw this.logger.Error().Msg("missing indexes").AsError();
3162
- for (const [name2, idx] of Object.entries(idxCarMeta.indexes)) {
3163
- 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);
3164
4104
  }
3165
4105
  },
3166
- store: { ...this.opts.store, isIndex: this.opts.store?.isIndex || "idx" },
3167
- 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,
3168
4111
  });
3169
4112
  this.clock = new CRDTClock(this.blockstore);
3170
4113
  this.clock.onZoom(() => {
@@ -3245,75 +4188,169 @@ var CRDT = class {
3245
4188
  }
3246
4189
  };
3247
4190
 
3248
- // src/database.ts
3249
- var Database = class {
3250
- constructor(name, opts) {
3251
- this.opts = {};
4191
+ // src/ledger.ts
4192
+ var ledgers = 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 isLedger(db) {
4202
+ return db instanceof LedgerImpl || db instanceof LedgerShell;
4203
+ }
4204
+ function LedgerFactory(name, opts) {
4205
+ const sthis = ensureSuperThis(opts);
4206
+ return new LedgerShell(
4207
+ ledgers.get(keyConfigOpts(sthis, name, opts)).once((key) => {
4208
+ const db = new LedgerImpl(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
+ ledgers.unget(key);
4223
+ });
4224
+ return db;
4225
+ })
4226
+ );
4227
+ }
4228
+ var LedgerShell = 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 LedgerImpl = class {
4292
+ constructor(sthis, opts) {
3252
4293
  this._listening = false;
3253
4294
  this._listeners = /* @__PURE__ */ new Set();
3254
4295
  this._noupdate_listeners = /* @__PURE__ */ new Set();
3255
- this._ready = new ResolveOnce6();
3256
- this.name = name;
3257
- this.opts = opts || this.opts;
3258
- this.sthis = ensureSuperThis(this.opts);
3259
- this.logger = ensureLogger(this.sthis, "Database");
3260
- this._crdt = new CRDT(this.sthis, name, this.opts);
3261
- this.blockstore = this._crdt.blockstore;
3262
- this._writeQueue = writeQueue(async (updates) => {
3263
- return await this._crdt.bulk(updates);
3264
- });
3265
- this._crdt.clock.onTock(() => {
3266
- this._no_update_notify();
3267
- });
4296
+ // readonly blockstore: BaseBlockstore;
4297
+ this.shells = /* @__PURE__ */ new Set();
4298
+ this._onClosedFns = /* @__PURE__ */ new Set();
4299
+ this._ready = new ResolveOnce7();
4300
+ this.opts = opts;
4301
+ this.sthis = sthis;
4302
+ this.id = sthis.timeOrderedNextId().str;
4303
+ this.logger = ensureLogger(this.sthis, "Ledger");
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());
3268
4307
  }
3269
- static {
3270
- this.databases = /* @__PURE__ */ new Map();
4308
+ addShell(shell) {
4309
+ this.shells.add(shell);
4310
+ }
4311
+ onClosed(fn) {
4312
+ this._onClosedFns.add(fn);
3271
4313
  }
3272
- /**
3273
- * Close the database and release resources
3274
- */
3275
4314
  async close() {
3276
- await this.ready();
3277
- await this._crdt.close();
3278
- 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(`LedgerShell 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
+ }
3279
4328
  }
3280
- /**
3281
- * Destroy the database and release all resources
3282
- */
3283
4329
  async destroy() {
3284
4330
  await this.ready();
3285
- await this._crdt.destroy();
3286
- await this.blockstore.destroy();
4331
+ await this.crdt.destroy();
3287
4332
  }
3288
4333
  async ready() {
3289
- return this._ready.once(async () => {
4334
+ const ret = await this._ready.once(async () => {
3290
4335
  await this.sthis.start();
3291
- await this._crdt.ready();
3292
- await this.blockstore.ready();
4336
+ await this.crdt.ready();
3293
4337
  });
4338
+ return ret;
4339
+ }
4340
+ get name() {
4341
+ return this.opts.storeUrls.data.data.getParam("name" /* NAME */) || "default";
3294
4342
  }
3295
- /**
3296
- * Get a document from the database
3297
- * @param id - the document id
3298
- * @returns the document with the _id
3299
- * @throws NotFoundError if the document is not found
3300
- */
3301
4343
  async get(id) {
3302
4344
  if (!id) throw this.logger.Error().Str("db", this.name).Msg(`Doc id is required`).AsError();
3303
4345
  await this.ready();
3304
4346
  this.logger.Debug().Str("id", id).Msg("get");
3305
- const got = await this._crdt.get(id).catch((e) => {
4347
+ const got = await this.crdt.get(id).catch((e) => {
3306
4348
  throw new NotFoundError(`Not found: ${id} - ${e.message}`);
3307
4349
  });
3308
4350
  if (!got) throw new NotFoundError(`Not found: ${id}`);
3309
4351
  const { doc } = got;
3310
4352
  return { ...doc, _id: id };
3311
4353
  }
3312
- /**
3313
- * Put a document from the database
3314
- * @param doc - the document to put
3315
- * @returns add DocResponse with the id and clock
3316
- */
3317
4354
  async put(doc) {
3318
4355
  await this.ready();
3319
4356
  this.logger.Debug().Str("id", doc._id).Msg("put");
@@ -3328,11 +4365,21 @@ var Database = class {
3328
4365
  });
3329
4366
  return { id: docId, clock: result?.head, name: this.name };
3330
4367
  }
3331
- /**
3332
- * delete a document from the database
3333
- * @param id Document id
3334
- * @returns DocResponse with the id and clock
3335
- */
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
+ }
3336
4383
  async del(id) {
3337
4384
  await this.ready();
3338
4385
  this.logger.Debug().Str("id", id).Msg("del");
@@ -3342,7 +4389,7 @@ var Database = class {
3342
4389
  async changes(since = [], opts = {}) {
3343
4390
  await this.ready();
3344
4391
  this.logger.Debug().Any("since", since).Any("opts", opts).Msg("changes");
3345
- const { result, head } = await this._crdt.changes(since, opts);
4392
+ const { result, head } = await this.crdt.changes(since, opts);
3346
4393
  const rows = result.map(({ id: key, value, del, clock }) => ({
3347
4394
  key,
3348
4395
  value: del ? { _id: key, _deleted: true } : { _id: key, ...value },
@@ -3353,7 +4400,7 @@ var Database = class {
3353
4400
  async allDocs(opts = {}) {
3354
4401
  await this.ready();
3355
4402
  this.logger.Debug().Msg("allDocs");
3356
- const { result, head } = await this._crdt.allDocs();
4403
+ const { result, head } = await this.crdt.allDocs();
3357
4404
  const rows = result.map(({ id: key, value, del }) => ({
3358
4405
  key,
3359
4406
  value: del ? { _id: key, _deleted: true } : { _id: key, ...value }
@@ -3368,7 +4415,7 @@ var Database = class {
3368
4415
  if (updates) {
3369
4416
  if (!this._listening) {
3370
4417
  this._listening = true;
3371
- this._crdt.clock.onTick((updates2) => {
4418
+ this.crdt.clock.onTick((updates2) => {
3372
4419
  void this._notify(updates2);
3373
4420
  });
3374
4421
  }
@@ -3387,13 +4434,13 @@ var Database = class {
3387
4434
  async query(field, opts = {}) {
3388
4435
  await this.ready();
3389
4436
  this.logger.Debug().Any("field", field).Any("opts", opts).Msg("query");
3390
- const _crdt = this._crdt;
3391
- 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);
3392
4439
  return await idx.query(opts);
3393
4440
  }
3394
4441
  async compact() {
3395
4442
  await this.ready();
3396
- await this._crdt.compact();
4443
+ await this.crdt.compact();
3397
4444
  }
3398
4445
  async _notify(updates) {
3399
4446
  await this.ready();
@@ -3417,23 +4464,62 @@ var Database = class {
3417
4464
  }
3418
4465
  }
3419
4466
  };
3420
- function toSortedArray(set) {
3421
- if (!set) return [];
3422
- 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("Ledger 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();
3423
4490
  }
3424
- function fireproof(name, opts) {
3425
- const key = JSON.stringify(
3426
- toSortedArray({
3427
- name,
3428
- stores: toSortedArray(opts?.store?.stores)
3429
- })
3430
- );
3431
- let db = Database.databases.get(key);
3432
- if (!db) {
3433
- db = new Database(name, opts);
3434
- 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
+ }
3435
4500
  }
3436
- return db;
4501
+ const bbase = BuildURI2.from(sopts.base);
4502
+ if (name) {
4503
+ bbase.setParam("name" /* NAME */, name);
4504
+ }
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 LedgerFactory(name, opts);
3437
4523
  }
3438
4524
  function makeName(fnString) {
3439
4525
  const regex = /\(([^,()]+,\s*[^,()]+|\[[^\]]+\],\s*[^,()]+)\)/g;
@@ -3452,52 +4538,24 @@ function makeName(fnString) {
3452
4538
  }
3453
4539
  }
3454
4540
 
3455
- // src/runtime/index.ts
3456
- var runtime_exports = {};
3457
- __export(runtime_exports, {
3458
- FILESTORE_VERSION: () => FILESTORE_VERSION,
3459
- INDEXDB_VERSION: () => INDEXDB_VERSION,
3460
- files: () => files_exports,
3461
- getFileName: () => getFileName,
3462
- getFileSystem: () => getFileSystem,
3463
- getPath: () => getPath,
3464
- kb: () => key_bag_exports,
3465
- kc: () => keyed_crypto_exports,
3466
- mf: () => wait_pr_multiformats_exports,
3467
- runtimeFn: () => runtimeFn2
3468
- });
3469
-
3470
- // src/runtime/wait-pr-multiformats/index.ts
3471
- var wait_pr_multiformats_exports = {};
3472
- __export(wait_pr_multiformats_exports, {
3473
- block: () => block_exports,
3474
- codec: () => codec_interface_exports
3475
- });
3476
-
3477
- // src/runtime/wait-pr-multiformats/codec-interface.ts
3478
- var codec_interface_exports = {};
3479
-
3480
- // src/runtime/index.ts
3481
- import { runtimeFn as runtimeFn2 } from "@adviser/cement";
3482
-
3483
- // src/runtime/gateways/indexdb/version.ts
3484
- var INDEXDB_VERSION = "v0.19-indexdb";
3485
-
3486
4541
  // src/version.ts
3487
4542
  var PACKAGE_VERSION = Object.keys({
3488
- "0.19.121-dev": "xxxx"
4543
+ "0.20.0-dev-preview-05": "xxxx"
3489
4544
  })[0];
3490
4545
  export {
3491
4546
  CRDT,
3492
- Database,
3493
4547
  Index,
4548
+ LedgerFactory,
4549
+ LedgerShell,
3494
4550
  NotFoundError,
3495
4551
  PACKAGE_VERSION,
3496
- Result,
4552
+ PARAM,
3497
4553
  UInt8ArrayEqual,
3498
4554
  blockstore_exports as blockstore,
3499
4555
  blockstore_exports as bs,
3500
- dataDir,
4556
+ coerceIntoUint8,
4557
+ coercePromiseIntoUint8,
4558
+ defaultWriteQueueOpts,
3501
4559
  ensureLogger,
3502
4560
  ensureSuperLog,
3503
4561
  ensureSuperThis,
@@ -3508,11 +4566,16 @@ export {
3508
4566
  getName,
3509
4567
  getStore,
3510
4568
  index,
4569
+ inplaceFilter,
3511
4570
  isFalsy,
4571
+ isLedger,
3512
4572
  isNotFoundError,
4573
+ keyConfigOpts,
3513
4574
  onSuperThis,
3514
4575
  runtime_exports as rt,
3515
4576
  runtime_exports as runtime,
3516
- throwFalsy
4577
+ throwFalsy,
4578
+ toSortedArray,
4579
+ toStoreURIRuntime
3517
4580
  };
3518
4581
  //# sourceMappingURL=index.js.map