@fireproof/core 0.20.0-dev-preview-39 → 0.20.0-dev-preview-41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -4
- package/deno/index.js +2 -2
- package/deno/index.js.map +1 -1
- package/index.cjs +499 -370
- package/index.cjs.map +1 -1
- package/index.d.cts +162 -64
- package/index.d.ts +162 -64
- package/index.js +473 -344
- package/index.js.map +1 -1
- package/metafile-cjs.json +1 -1
- package/metafile-esm.json +1 -1
- package/package.json +3 -3
- package/react/index.cjs +28 -11
- package/react/index.cjs.map +1 -1
- package/react/index.d.cts +2 -1
- package/react/index.d.ts +2 -1
- package/react/index.js +29 -12
- package/react/index.js.map +1 -1
- package/react/metafile-cjs.json +1 -1
- package/react/metafile-esm.json +1 -1
- package/tests/blockstore/interceptor-gateway.test.ts +5 -1
- package/tests/blockstore/keyed-crypto-indexeddb-file.test.ts +8 -18
- package/tests/blockstore/keyed-crypto.test.ts +7 -30
- package/tests/blockstore/loader.test.ts +19 -17
- package/tests/blockstore/store.test.ts +48 -51
- package/tests/blockstore/transaction.test.ts +13 -11
- package/tests/fireproof/all-gateway.test.ts +49 -46
- package/tests/fireproof/attachable.test.ts +82 -0
- package/tests/fireproof/crdt.test.ts +49 -48
- package/tests/fireproof/database.test.ts +40 -40
- package/tests/fireproof/fireproof.test.ts +43 -42
- package/tests/fireproof/hello.test.ts +4 -4
- package/tests/fireproof/indexer.test.ts +44 -44
- package/tests/fireproof/utils.test.ts +4 -3
- package/tests/gateway/file/loader-config.test.ts +17 -17
- package/tests/gateway/indexeddb/loader-config.test.ts +4 -4
- package/tests/helpers.ts +80 -2
- package/tests/react/useFireproof.test.tsx +79 -4
package/index.js
CHANGED
@@ -5,7 +5,7 @@ var __export = (target, all) => {
|
|
5
5
|
};
|
6
6
|
|
7
7
|
// src/ledger.ts
|
8
|
-
import { BuildURI as
|
8
|
+
import { BuildURI as BuildURI3, KeyedResolvOnce as KeyedResolvOnce5, ResolveOnce as ResolveOnce7, URI as URI12 } from "@adviser/cement";
|
9
9
|
|
10
10
|
// src/utils.ts
|
11
11
|
import {
|
@@ -60,6 +60,18 @@ function falsyToUndef(value) {
|
|
60
60
|
}
|
61
61
|
return value;
|
62
62
|
}
|
63
|
+
var DataAndMetaAndWalAndBaseStore = class {
|
64
|
+
constructor(dam) {
|
65
|
+
this.wal = dam.wal;
|
66
|
+
this.file = dam.file;
|
67
|
+
this.car = dam.car;
|
68
|
+
this.meta = dam.meta;
|
69
|
+
this.baseStores = [this.file, this.car, this.meta];
|
70
|
+
if (this.wal) {
|
71
|
+
this.baseStores.push(this.wal);
|
72
|
+
}
|
73
|
+
}
|
74
|
+
};
|
63
75
|
|
64
76
|
// src/utils.ts
|
65
77
|
import { base58btc } from "multiformats/bases/base58";
|
@@ -1237,7 +1249,7 @@ var MemoryGateway = class {
|
|
1237
1249
|
get(url) {
|
1238
1250
|
const x = this.memorys.get(url.toString());
|
1239
1251
|
if (!x) {
|
1240
|
-
return Promise.resolve(Result4.Err(new NotFoundError(
|
1252
|
+
return Promise.resolve(Result4.Err(new NotFoundError(`not found: ${url.getParam(PARAM.STORE)}`)));
|
1241
1253
|
}
|
1242
1254
|
return Promise.resolve(Result4.Ok(x));
|
1243
1255
|
}
|
@@ -1343,9 +1355,6 @@ async function decode2DbMetaEvents(sthis, rserializedMeta) {
|
|
1343
1355
|
if (!Array.isArray(serializedMeta)) {
|
1344
1356
|
return sthis.logger.Debug().Any("metaEntries", serializedMeta).Msg("No data in MetaEntries").ResultError();
|
1345
1357
|
}
|
1346
|
-
if (!serializedMeta.length) {
|
1347
|
-
return sthis.logger.Debug().Msg("No MetaEntries found").ResultError();
|
1348
|
-
}
|
1349
1358
|
return Result6.Ok(
|
1350
1359
|
await Promise.all(
|
1351
1360
|
serializedMeta.map(async (metaEntry) => {
|
@@ -2032,6 +2041,9 @@ var DatabaseImpl = class {
|
|
2032
2041
|
this.id = ledger.id;
|
2033
2042
|
this.logger = ensureLogger(this.sthis, "Database");
|
2034
2043
|
}
|
2044
|
+
attach(a) {
|
2045
|
+
return this.ledger.attach(a);
|
2046
|
+
}
|
2035
2047
|
get name() {
|
2036
2048
|
return this.ledger.name;
|
2037
2049
|
}
|
@@ -2127,11 +2139,11 @@ import { ResolveOnce as ResolveOnce6 } from "@adviser/cement";
|
|
2127
2139
|
// src/blockstore/index.ts
|
2128
2140
|
var blockstore_exports = {};
|
2129
2141
|
__export(blockstore_exports, {
|
2142
|
+
AttachedRemotesImpl: () => AttachedRemotesImpl,
|
2130
2143
|
BaseBlockstoreImpl: () => BaseBlockstoreImpl,
|
2131
2144
|
Car2FPMsg: () => Car2FPMsg,
|
2132
2145
|
CarTransactionImpl: () => CarTransactionImpl,
|
2133
2146
|
CompactionFetcher: () => CompactionFetcher,
|
2134
|
-
ConnectionBase: () => ConnectionBase,
|
2135
2147
|
DbMetaEventEqual: () => DbMetaEventEqual,
|
2136
2148
|
DbMetaEventsEqual: () => DbMetaEventsEqual,
|
2137
2149
|
EncryptedBlockstore: () => EncryptedBlockstore,
|
@@ -2140,6 +2152,7 @@ __export(blockstore_exports, {
|
|
2140
2152
|
InterceptorGateway: () => InterceptorGateway,
|
2141
2153
|
Loader: () => Loader,
|
2142
2154
|
PassThroughGateway: () => PassThroughGateway,
|
2155
|
+
createAttachedStores: () => createAttachedStores,
|
2143
2156
|
createDbMetaEvent: () => createDbMetaEvent,
|
2144
2157
|
defaultGatewayFactoryItem: () => defaultGatewayFactoryItem,
|
2145
2158
|
ensureStoreEnDeFile: () => ensureStoreEnDeFile,
|
@@ -2164,7 +2177,7 @@ function DbMetaEventsEqual(a, b) {
|
|
2164
2177
|
}
|
2165
2178
|
|
2166
2179
|
// src/blockstore/store-factory.ts
|
2167
|
-
import { KeyedResolvOnce as
|
2180
|
+
import { KeyedResolvOnce as KeyedResolvOnce4, Result as Result10 } from "@adviser/cement";
|
2168
2181
|
|
2169
2182
|
// src/blockstore/store.ts
|
2170
2183
|
import { exception2Result as exception2Result3, ResolveOnce as ResolveOnce4, Result as Result9 } from "@adviser/cement";
|
@@ -2333,7 +2346,7 @@ var EncryptedBlockstore = class extends BaseBlockstoreImpl {
|
|
2333
2346
|
if (!this.loader) {
|
2334
2347
|
return;
|
2335
2348
|
}
|
2336
|
-
return falsyToUndef(await this.loader.getBlock(cid));
|
2349
|
+
return falsyToUndef(await this.loader.getBlock(cid, this.loader.attachedStores.local()));
|
2337
2350
|
}
|
2338
2351
|
async transaction(fn, opts = { noLoader: false }) {
|
2339
2352
|
this.logger.Debug().Msg("enter transaction");
|
@@ -2353,10 +2366,7 @@ var EncryptedBlockstore = class extends BaseBlockstoreImpl {
|
|
2353
2366
|
async getFile(car, cid) {
|
2354
2367
|
await this.ready();
|
2355
2368
|
if (!this.loader) throw this.logger.Error().Msg("loader required to get file, ledger must be named").AsError();
|
2356
|
-
const reader = await this.loader.loadFileCar(
|
2357
|
-
car
|
2358
|
-
/*, isPublic */
|
2359
|
-
);
|
2369
|
+
const reader = await this.loader.loadFileCar(car, this.loader.attachedStores.local());
|
2360
2370
|
const block = await reader.get(cid);
|
2361
2371
|
if (!block) throw this.logger.Error().Str("cid", cid.toString()).Msg(`Missing block`).AsError();
|
2362
2372
|
return block.bytes;
|
@@ -2577,11 +2587,11 @@ var TaskManager = class {
|
|
2577
2587
|
this.logger = ensureLogger(sthis, "TaskManager");
|
2578
2588
|
this.callback = callback;
|
2579
2589
|
}
|
2580
|
-
async handleEvent(cid, parents, dbMeta) {
|
2590
|
+
async handleEvent(cid, parents, dbMeta, store) {
|
2581
2591
|
for (const parent of parents) {
|
2582
2592
|
this.eventsWeHandled.add(parent.toString());
|
2583
2593
|
}
|
2584
|
-
this.queue.push({ cid: cid.toString(), dbMeta, retries: 0 });
|
2594
|
+
this.queue.push({ cid: cid.toString(), dbMeta, retries: 0, store });
|
2585
2595
|
this.queue = this.queue.filter(({ cid: cid2 }) => !this.eventsWeHandled.has(cid2));
|
2586
2596
|
void this.processQueue();
|
2587
2597
|
}
|
@@ -2595,7 +2605,7 @@ var TaskManager = class {
|
|
2595
2605
|
return;
|
2596
2606
|
}
|
2597
2607
|
try {
|
2598
|
-
await this.callback(first.dbMeta);
|
2608
|
+
await this.callback(first.dbMeta, first.store);
|
2599
2609
|
this.eventsWeHandled.add(first.cid);
|
2600
2610
|
this.queue = this.queue.filter(({ cid }) => !this.eventsWeHandled.has(cid));
|
2601
2611
|
} catch (err) {
|
@@ -2614,6 +2624,237 @@ var TaskManager = class {
|
|
2614
2624
|
}
|
2615
2625
|
};
|
2616
2626
|
|
2627
|
+
// src/blockstore/attachable-store.ts
|
2628
|
+
import { KeyedResolvOnce as KeyedResolvOnce3, BuildURI as BuildURI2, isCoerceURI } from "@adviser/cement";
|
2629
|
+
var AttachedImpl = class {
|
2630
|
+
constructor(gws, stores, unreg) {
|
2631
|
+
this.gatewayUrls = gws;
|
2632
|
+
this.stores = new DataAndMetaAndWalAndBaseStore(stores);
|
2633
|
+
this.unreg = unreg;
|
2634
|
+
}
|
2635
|
+
async detach() {
|
2636
|
+
const toClose = [this.stores.car.close(), this.stores.file.close(), this.stores.meta.close()];
|
2637
|
+
if (this.stores.wal) {
|
2638
|
+
toClose.push(this.stores.wal.close());
|
2639
|
+
}
|
2640
|
+
await Promise.all(toClose);
|
2641
|
+
this.unreg();
|
2642
|
+
}
|
2643
|
+
status() {
|
2644
|
+
return "attached";
|
2645
|
+
}
|
2646
|
+
};
|
2647
|
+
var DataActiveStoreImpl = class {
|
2648
|
+
constructor(ref, active, attached) {
|
2649
|
+
this.ref = ref;
|
2650
|
+
this.active = active;
|
2651
|
+
this.attached = attached;
|
2652
|
+
}
|
2653
|
+
};
|
2654
|
+
var CarAttachedStoresImpl = class {
|
2655
|
+
constructor(attached) {
|
2656
|
+
this.attached = attached;
|
2657
|
+
}
|
2658
|
+
local() {
|
2659
|
+
return this.attached.local().active.car;
|
2660
|
+
}
|
2661
|
+
remotes() {
|
2662
|
+
return this.attached.remotes().map(({ active }) => active.car);
|
2663
|
+
}
|
2664
|
+
};
|
2665
|
+
var FileAttachedStoresImpl = class {
|
2666
|
+
constructor(attached) {
|
2667
|
+
this.attached = attached;
|
2668
|
+
}
|
2669
|
+
local() {
|
2670
|
+
return this.attached.local().active.file;
|
2671
|
+
}
|
2672
|
+
remotes() {
|
2673
|
+
return this.attached.remotes().map(({ active }) => active.file);
|
2674
|
+
}
|
2675
|
+
};
|
2676
|
+
var MetaActiveStoreImpl = class {
|
2677
|
+
constructor(ref, active, attached) {
|
2678
|
+
this.ref = ref;
|
2679
|
+
this.active = active;
|
2680
|
+
this.attached = attached;
|
2681
|
+
}
|
2682
|
+
};
|
2683
|
+
var MetaAttachedStoresImpl = class {
|
2684
|
+
constructor(attached) {
|
2685
|
+
this.attached = attached;
|
2686
|
+
}
|
2687
|
+
local() {
|
2688
|
+
return this.attached.local().active.meta;
|
2689
|
+
}
|
2690
|
+
remotes() {
|
2691
|
+
return this.attached.remotes().map(({ active }) => active.meta);
|
2692
|
+
}
|
2693
|
+
};
|
2694
|
+
var WALActiveStoreImpl = class {
|
2695
|
+
constructor(ref, active, attached) {
|
2696
|
+
this.ref = ref;
|
2697
|
+
this.active = active;
|
2698
|
+
this.attached = attached;
|
2699
|
+
}
|
2700
|
+
};
|
2701
|
+
var WALAttachedStoresImpl = class {
|
2702
|
+
constructor(attached) {
|
2703
|
+
this.attached = attached;
|
2704
|
+
}
|
2705
|
+
local() {
|
2706
|
+
return this.attached.local().active.wal;
|
2707
|
+
}
|
2708
|
+
remotes() {
|
2709
|
+
return this.attached.remotes().filter(({ active }) => active.wal).map(({ active }) => active.wal);
|
2710
|
+
}
|
2711
|
+
};
|
2712
|
+
var ActiveStoreImpl = class {
|
2713
|
+
constructor(active, attached) {
|
2714
|
+
this.active = active;
|
2715
|
+
this.attached = attached;
|
2716
|
+
}
|
2717
|
+
baseStores() {
|
2718
|
+
const bs = [this.active.car, this.active.file, this.active.meta];
|
2719
|
+
if (this.active.wal) {
|
2720
|
+
bs.push(this.active.wal);
|
2721
|
+
}
|
2722
|
+
return bs;
|
2723
|
+
}
|
2724
|
+
carStore() {
|
2725
|
+
return new DataActiveStoreImpl(this, this.active.car, new CarAttachedStoresImpl(this.attached));
|
2726
|
+
}
|
2727
|
+
fileStore() {
|
2728
|
+
return new DataActiveStoreImpl(this, this.active.file, new FileAttachedStoresImpl(this.attached));
|
2729
|
+
}
|
2730
|
+
metaStore() {
|
2731
|
+
return new MetaActiveStoreImpl(this, this.active.meta, new MetaAttachedStoresImpl(this.attached));
|
2732
|
+
}
|
2733
|
+
walStore() {
|
2734
|
+
if (!this.active.wal) {
|
2735
|
+
throw this.attached.loadable.sthis.logger.Error().Msg("wal store not set").AsError();
|
2736
|
+
}
|
2737
|
+
return new WALActiveStoreImpl(this, this.active.wal, new WALAttachedStoresImpl(this.attached));
|
2738
|
+
}
|
2739
|
+
};
|
2740
|
+
function isLoadable(unknown) {
|
2741
|
+
return !!unknown.sthis && !!unknown.attachedStores;
|
2742
|
+
}
|
2743
|
+
async function createAttachedStores(urlOrGup, arOrLoadable, name = "local") {
|
2744
|
+
let ar;
|
2745
|
+
if (!isLoadable(arOrLoadable)) {
|
2746
|
+
ar = arOrLoadable;
|
2747
|
+
} else {
|
2748
|
+
ar = arOrLoadable.attachedStores;
|
2749
|
+
}
|
2750
|
+
let gup;
|
2751
|
+
if (!urlOrGup) {
|
2752
|
+
throw new Error("urlOrGup is required");
|
2753
|
+
}
|
2754
|
+
if (isCoerceURI(urlOrGup)) {
|
2755
|
+
const url = urlOrGup;
|
2756
|
+
gup = {
|
2757
|
+
car: { url },
|
2758
|
+
file: { url },
|
2759
|
+
meta: { url },
|
2760
|
+
wal: { url }
|
2761
|
+
};
|
2762
|
+
} else {
|
2763
|
+
gup = urlOrGup;
|
2764
|
+
}
|
2765
|
+
return await ar.attach({
|
2766
|
+
name,
|
2767
|
+
prepare: async () => gup
|
2768
|
+
});
|
2769
|
+
}
|
2770
|
+
var AttachedRemotesImpl = class {
|
2771
|
+
constructor(loadable) {
|
2772
|
+
this._remotes = new KeyedResolvOnce3();
|
2773
|
+
this.loadable = loadable;
|
2774
|
+
}
|
2775
|
+
forRemotes(action) {
|
2776
|
+
return Promise.all(this.remotes().map((i) => action(i))).then(() => void 0);
|
2777
|
+
}
|
2778
|
+
remotes() {
|
2779
|
+
return this._remotes.values().filter(({ value }) => value.isOk() && !value.Ok().stores.wal).map(({ value }) => value.Ok().stores).map((i) => this.activate(i));
|
2780
|
+
}
|
2781
|
+
local() {
|
2782
|
+
if (!this._local) {
|
2783
|
+
throw this.loadable.sthis.logger.Error().Msg("local store not set").AsError();
|
2784
|
+
}
|
2785
|
+
return new ActiveStoreImpl(this._local.stores, this);
|
2786
|
+
}
|
2787
|
+
activate(store) {
|
2788
|
+
if (isCoerceURI(store)) {
|
2789
|
+
throw this.loadable.sthis.logger.Error().Msg("store must be an object").AsError();
|
2790
|
+
}
|
2791
|
+
return new ActiveStoreImpl(store, this);
|
2792
|
+
}
|
2793
|
+
async detach() {
|
2794
|
+
await Promise.all(
|
2795
|
+
this._remotes.values().map(async ({ value: rvalue }) => {
|
2796
|
+
if (rvalue.isOk()) {
|
2797
|
+
await rvalue.Ok().detach();
|
2798
|
+
}
|
2799
|
+
})
|
2800
|
+
);
|
2801
|
+
}
|
2802
|
+
async attach(attached) {
|
2803
|
+
const gwp = await attached.prepare();
|
2804
|
+
const gws = {
|
2805
|
+
car: {
|
2806
|
+
...gwp.car,
|
2807
|
+
url: BuildURI2.from(gwp.car.url).defParam("name", attached.name).URI()
|
2808
|
+
},
|
2809
|
+
file: {
|
2810
|
+
...gwp.file,
|
2811
|
+
url: BuildURI2.from(gwp.file.url).defParam("name", attached.name).URI()
|
2812
|
+
},
|
2813
|
+
meta: {
|
2814
|
+
...gwp.meta,
|
2815
|
+
url: BuildURI2.from(gwp.meta.url).defParam("name", attached.name).URI()
|
2816
|
+
},
|
2817
|
+
wal: gwp.wal ? {
|
2818
|
+
...gwp.wal,
|
2819
|
+
url: BuildURI2.from(gwp.wal.url).defParam("name", attached.name).URI()
|
2820
|
+
} : void 0
|
2821
|
+
};
|
2822
|
+
const key = JSON.stringify(
|
2823
|
+
toSortedArray({
|
2824
|
+
carUrl: gws.car.url.toString(),
|
2825
|
+
filesUrl: gws.file.url.toString(),
|
2826
|
+
metaUrl: gws.meta.url.toString(),
|
2827
|
+
walUrl: gws.wal?.url.toString()
|
2828
|
+
})
|
2829
|
+
);
|
2830
|
+
return this._remotes.get(key).once(async () => {
|
2831
|
+
const rt = toStoreRuntime(this.loadable.sthis);
|
2832
|
+
const result = new AttachedImpl(
|
2833
|
+
gws,
|
2834
|
+
await rt.makeStores({
|
2835
|
+
byStore: gws,
|
2836
|
+
loader: this.loadable
|
2837
|
+
}),
|
2838
|
+
// {
|
2839
|
+
// car: await rt.makeDataStore({ url: gws.carUrl, loader: this.loadable }),
|
2840
|
+
// file: await rt.makeDataStore({ url: gws.filesUrl, loader: this.loadable }),
|
2841
|
+
// meta: await rt.makeMetaStore({ url: gws.metaUrl, loader: this.loadable }),
|
2842
|
+
// },
|
2843
|
+
() => {
|
2844
|
+
this._remotes.unget(key);
|
2845
|
+
}
|
2846
|
+
);
|
2847
|
+
if (result.stores.wal) {
|
2848
|
+
if (this._local) {
|
2849
|
+
throw this.loadable.sthis.logger.Error().Msg("local store could only set once").AsError();
|
2850
|
+
}
|
2851
|
+
this._local = result;
|
2852
|
+
}
|
2853
|
+
return result;
|
2854
|
+
});
|
2855
|
+
}
|
2856
|
+
};
|
2857
|
+
|
2617
2858
|
// src/blockstore/loader.ts
|
2618
2859
|
function carLogIncludesGroup(list, cids) {
|
2619
2860
|
return list.some((arr) => {
|
@@ -2639,10 +2880,6 @@ var Loader = class {
|
|
2639
2880
|
this.getBlockCache = /* @__PURE__ */ new Map();
|
2640
2881
|
this.seenMeta = /* @__PURE__ */ new Set();
|
2641
2882
|
this.writeLimit = pLimit(1);
|
2642
|
-
this._carStore = new ResolveOnce3();
|
2643
|
-
this._fileStore = new ResolveOnce3();
|
2644
|
-
this._WALStore = new ResolveOnce3();
|
2645
|
-
this._metaStore = new ResolveOnce3();
|
2646
2883
|
this.onceReady = new ResolveOnce3();
|
2647
2884
|
this.sthis = sthis;
|
2648
2885
|
this.ebOpts = defaultedBlockstoreRuntime(
|
@@ -2654,75 +2891,93 @@ var Loader = class {
|
|
2654
2891
|
"Loader"
|
2655
2892
|
);
|
2656
2893
|
this.logger = this.ebOpts.logger;
|
2657
|
-
this.taskManager = new TaskManager(sthis, async (dbMeta) => {
|
2658
|
-
await this.handleDbMetasFromStore([dbMeta]);
|
2894
|
+
this.taskManager = new TaskManager(sthis, async (dbMeta, activeStore) => {
|
2895
|
+
await this.handleDbMetasFromStore([dbMeta], activeStore);
|
2659
2896
|
});
|
2660
|
-
|
2661
|
-
|
2662
|
-
|
2663
|
-
|
2664
|
-
|
2665
|
-
|
2666
|
-
|
2667
|
-
|
2668
|
-
|
2669
|
-
|
2670
|
-
|
2671
|
-
|
2672
|
-
|
2673
|
-
|
2674
|
-
|
2675
|
-
|
2676
|
-
|
2677
|
-
|
2678
|
-
|
2679
|
-
|
2680
|
-
|
2681
|
-
|
2682
|
-
|
2683
|
-
|
2684
|
-
|
2685
|
-
|
2686
|
-
|
2687
|
-
|
2688
|
-
|
2689
|
-
|
2690
|
-
|
2691
|
-
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2698
|
-
|
2699
|
-
|
2700
|
-
|
2701
|
-
|
2702
|
-
|
2703
|
-
|
2704
|
-
|
2897
|
+
this.attachedStores = new AttachedRemotesImpl(this);
|
2898
|
+
}
|
2899
|
+
attach(attached) {
|
2900
|
+
return this.attachedStores.attach(attached);
|
2901
|
+
}
|
2902
|
+
// private readonly _carStore = new ResolveOnce<DataStore>();
|
2903
|
+
// async carStore(): Promise<DataStore> {
|
2904
|
+
// return this._carStore.once(async () =>
|
2905
|
+
// this.ebOpts.storeRuntime.makeDataStore({
|
2906
|
+
// // sthis: this.sthis,
|
2907
|
+
// gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
2908
|
+
// url: this.ebOpts.storeUrls.data,
|
2909
|
+
// // keybag: await this.keyBag(),
|
2910
|
+
// loader: this,
|
2911
|
+
// }),
|
2912
|
+
// );
|
2913
|
+
// }
|
2914
|
+
// private readonly _fileStore = new ResolveOnce<DataStore>();
|
2915
|
+
// async fileStore(): Promise<DataStore> {
|
2916
|
+
// return this._fileStore.once(async () =>
|
2917
|
+
// this.ebOpts.storeRuntime.makeDataStore({
|
2918
|
+
// // sthis: this.sthis,
|
2919
|
+
// gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
2920
|
+
// url: this.ebOpts.storeUrls.file,
|
2921
|
+
// // keybag: await this.keyBag(),
|
2922
|
+
// loader: this,
|
2923
|
+
// }),
|
2924
|
+
// );
|
2925
|
+
// }
|
2926
|
+
// private readonly _WALStore = new ResolveOnce<WALStore>();
|
2927
|
+
// async WALStore(): Promise<WALStore> {
|
2928
|
+
// return this._WALStore.once(async () =>
|
2929
|
+
// this.ebOpts.storeRuntime.makeWALStore({
|
2930
|
+
// // sthis: this.sthis,
|
2931
|
+
// gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
2932
|
+
// url: this.ebOpts.storeUrls.wal,
|
2933
|
+
// // keybag: await this.keyBag(),
|
2934
|
+
// loader: this,
|
2935
|
+
// }),
|
2936
|
+
// );
|
2937
|
+
// }
|
2938
|
+
// private readonly _metaStore = new ResolveOnce<MetaStore>();
|
2939
|
+
// async metaStore(): Promise<MetaStore> {
|
2940
|
+
// return this._metaStore.once(async () =>
|
2941
|
+
// this.ebOpts.storeRuntime.makeMetaStore({
|
2942
|
+
// // sthis: this.sthis,
|
2943
|
+
// gatewayInterceptor: this.ebOpts.gatewayInterceptor,
|
2944
|
+
// url: this.ebOpts.storeUrls.meta,
|
2945
|
+
// // keybag: await this.keyBag(),
|
2946
|
+
// loader: this,
|
2947
|
+
// }),
|
2948
|
+
// );
|
2949
|
+
// }
|
2705
2950
|
keyBag() {
|
2706
2951
|
return getKeyBag(this.sthis, this.ebOpts.keyBag);
|
2707
2952
|
}
|
2708
2953
|
async ready() {
|
2709
2954
|
return this.onceReady.once(async () => {
|
2710
|
-
|
2955
|
+
await createAttachedStores(
|
2956
|
+
{
|
2957
|
+
car: { url: this.ebOpts.storeUrls.car, gatewayInterceptor: this.ebOpts.gatewayInterceptor },
|
2958
|
+
file: { url: this.ebOpts.storeUrls.file, gatewayInterceptor: this.ebOpts.gatewayInterceptor },
|
2959
|
+
meta: { url: this.ebOpts.storeUrls.meta, gatewayInterceptor: this.ebOpts.gatewayInterceptor },
|
2960
|
+
wal: { url: this.ebOpts.storeUrls.wal, gatewayInterceptor: this.ebOpts.gatewayInterceptor }
|
2961
|
+
},
|
2962
|
+
this.attachedStores
|
2963
|
+
);
|
2964
|
+
const local = this.attachedStores.local();
|
2965
|
+
const metas = await local.active.meta.load();
|
2711
2966
|
if (this.ebOpts.meta) {
|
2712
|
-
await this.handleDbMetasFromStore([this.ebOpts.meta]);
|
2967
|
+
await this.handleDbMetasFromStore([this.ebOpts.meta, ...metas || []], local);
|
2713
2968
|
} else if (metas) {
|
2714
|
-
await this.handleDbMetasFromStore(metas);
|
2969
|
+
await this.handleDbMetasFromStore(metas, local);
|
2715
2970
|
}
|
2716
2971
|
});
|
2717
2972
|
}
|
2718
2973
|
async close() {
|
2719
2974
|
await this.commitQueue.waitIdle();
|
2720
|
-
|
2721
|
-
await Promise.all(toClose.map((store) => store.close()));
|
2975
|
+
await this.attachedStores.detach();
|
2722
2976
|
}
|
2723
2977
|
async destroy() {
|
2724
|
-
|
2725
|
-
|
2978
|
+
await Promise.all(
|
2979
|
+
this.attachedStores.local().baseStores().map((store) => store.destroy())
|
2980
|
+
);
|
2726
2981
|
}
|
2727
2982
|
// async snapToCar(carCid: AnyLink | string) {
|
2728
2983
|
// await this.ready
|
@@ -2734,15 +2989,15 @@ var Loader = class {
|
|
2734
2989
|
// await this.getMoreReaders(carHeader.cars)
|
2735
2990
|
// await this._applyCarHeader(carHeader, true)
|
2736
2991
|
// }
|
2737
|
-
async handleDbMetasFromStore(metas) {
|
2992
|
+
async handleDbMetasFromStore(metas, activeStore) {
|
2738
2993
|
this.logger.Debug().Any("metas", metas).Msg("handleDbMetasFromStore");
|
2739
2994
|
for (const meta of metas) {
|
2740
2995
|
await this.writeLimit(async () => {
|
2741
|
-
await this.mergeDbMetaIntoClock(meta);
|
2996
|
+
await this.mergeDbMetaIntoClock(meta, activeStore);
|
2742
2997
|
});
|
2743
2998
|
}
|
2744
2999
|
}
|
2745
|
-
async mergeDbMetaIntoClock(meta) {
|
3000
|
+
async mergeDbMetaIntoClock(meta, activeStore) {
|
2746
3001
|
if (this.isCompacting) {
|
2747
3002
|
throw this.logger.Error().Msg("cannot merge while compacting").AsError();
|
2748
3003
|
}
|
@@ -2751,9 +3006,9 @@ var Loader = class {
|
|
2751
3006
|
if (carLogIncludesGroup(this.carLog, meta.cars)) {
|
2752
3007
|
return;
|
2753
3008
|
}
|
2754
|
-
const carHeader = await this.loadCarHeaderFromMeta(meta);
|
3009
|
+
const carHeader = await this.loadCarHeaderFromMeta(meta, activeStore);
|
2755
3010
|
carHeader.compact.map((c) => c.toString()).forEach(this.seenCompacted.add, this.seenCompacted);
|
2756
|
-
await this.getMoreReaders(carHeader.cars.flat());
|
3011
|
+
await this.getMoreReaders(carHeader.cars.flat(), activeStore);
|
2757
3012
|
this.carLog = [...uniqueCids([meta.cars, ...this.carLog, ...carHeader.cars], this.seenCompacted)];
|
2758
3013
|
await this.ebOpts.applyMeta?.(carHeader.meta);
|
2759
3014
|
}
|
@@ -2763,8 +3018,8 @@ var Loader = class {
|
|
2763
3018
|
// await this.setKey(key);
|
2764
3019
|
// }
|
2765
3020
|
// }
|
2766
|
-
async loadCarHeaderFromMeta(
|
2767
|
-
const reader = await this.loadCar(
|
3021
|
+
async loadCarHeaderFromMeta(dbm, astore) {
|
3022
|
+
const reader = await this.loadCar(dbm.cars[0], astore);
|
2768
3023
|
return await parseCarFile(reader, this.logger);
|
2769
3024
|
}
|
2770
3025
|
// async _getKey(): Promise<string | undefined> {
|
@@ -2777,22 +3032,22 @@ var Loader = class {
|
|
2777
3032
|
// }
|
2778
3033
|
async commitFiles(t, done) {
|
2779
3034
|
await this.ready();
|
2780
|
-
const fstore =
|
2781
|
-
const wstore =
|
3035
|
+
const fstore = this.attachedStores.local().active.file;
|
3036
|
+
const wstore = this.attachedStores.local().active.wal;
|
2782
3037
|
return this.commitQueue.enqueue(() => commitFiles(fstore, wstore, t, done));
|
2783
3038
|
}
|
2784
|
-
async loadFileCar(cid) {
|
2785
|
-
return await this.storesLoadCar(cid,
|
3039
|
+
async loadFileCar(cid, store) {
|
3040
|
+
return await this.storesLoadCar(cid, store.fileStore());
|
2786
3041
|
}
|
2787
3042
|
async commit(t, done, opts = { noLoader: false, compact: false }) {
|
2788
3043
|
await this.ready();
|
2789
|
-
const carStore = await this.
|
3044
|
+
const carStore = await this.attachedStores.local().active.car;
|
2790
3045
|
const params = {
|
2791
3046
|
encoder: (await carStore.keyedCrypto()).codec(),
|
2792
3047
|
carLog: this.carLog,
|
2793
3048
|
carStore,
|
2794
|
-
WALStore: await this.
|
2795
|
-
metaStore: await this.
|
3049
|
+
WALStore: await this.attachedStores.local().active.wal,
|
3050
|
+
metaStore: await this.attachedStores.local().active.meta,
|
2796
3051
|
threshold: this.ebOpts.threshold
|
2797
3052
|
};
|
2798
3053
|
return this.commitQueue.enqueue(async () => {
|
@@ -2807,7 +3062,7 @@ var Loader = class {
|
|
2807
3062
|
const previousCompactCid = fp.compact[fp.compact.length - 1];
|
2808
3063
|
fp.compact.map((c) => c.toString()).forEach(this.seenCompacted.add, this.seenCompacted);
|
2809
3064
|
this.carLog = [...uniqueCids([...this.carLog, ...fp.cars, cids], this.seenCompacted)];
|
2810
|
-
await this.removeCidsForCompact(previousCompactCid[0]).catch((e) => e);
|
3065
|
+
await this.removeCidsForCompact(previousCompactCid[0], this.attachedStores.local()).catch((e) => e);
|
2811
3066
|
} else {
|
2812
3067
|
this.carLog.unshift(cids);
|
2813
3068
|
}
|
@@ -2830,13 +3085,16 @@ var Loader = class {
|
|
2830
3085
|
}
|
2831
3086
|
}
|
2832
3087
|
}
|
2833
|
-
async removeCidsForCompact(cid) {
|
2834
|
-
const carHeader = await this.loadCarHeaderFromMeta(
|
2835
|
-
|
2836
|
-
|
3088
|
+
async removeCidsForCompact(cid, store) {
|
3089
|
+
const carHeader = await this.loadCarHeaderFromMeta(
|
3090
|
+
{
|
3091
|
+
cars: [cid]
|
3092
|
+
},
|
3093
|
+
store
|
3094
|
+
);
|
2837
3095
|
for (const cids of carHeader.compact) {
|
2838
3096
|
for (const cid2 of cids) {
|
2839
|
-
await
|
3097
|
+
await this.attachedStores.local().active.car.remove(cid2);
|
2840
3098
|
}
|
2841
3099
|
}
|
2842
3100
|
}
|
@@ -2860,7 +3118,7 @@ var Loader = class {
|
|
2860
3118
|
}
|
2861
3119
|
for (const cids of this.carLog) {
|
2862
3120
|
for (const cid of cids) {
|
2863
|
-
const reader = await this.loadCar(cid);
|
3121
|
+
const reader = await this.loadCar(cid, this.attachedStores.local());
|
2864
3122
|
if (!reader) throw this.logger.Error().Ref("cid", cid).Msg("missing car reader").AsError();
|
2865
3123
|
for await (const block of reader.blocks()) {
|
2866
3124
|
const sCid = block.cid.toString();
|
@@ -2872,13 +3130,13 @@ var Loader = class {
|
|
2872
3130
|
}
|
2873
3131
|
}
|
2874
3132
|
}
|
2875
|
-
async getBlock(cid) {
|
3133
|
+
async getBlock(cid, store) {
|
2876
3134
|
await this.ready();
|
2877
3135
|
const sCid = cid.toString();
|
2878
3136
|
if (this.getBlockCache.has(sCid)) return this.getBlockCache.get(sCid);
|
2879
3137
|
const getCarCid = async (carCid) => {
|
2880
3138
|
if (this.getBlockCache.has(sCid)) return this.getBlockCache.get(sCid);
|
2881
|
-
const reader = await this.loadCar(carCid);
|
3139
|
+
const reader = await this.loadCar(carCid, store);
|
2882
3140
|
if (!reader) {
|
2883
3141
|
throw this.logger.Error().Ref("cid", carCid).Msg("missing car reader").AsError();
|
2884
3142
|
}
|
@@ -2889,7 +3147,7 @@ var Loader = class {
|
|
2889
3147
|
throw this.logger.Error().Str("cid", sCid).Msg("block not in reader").AsError();
|
2890
3148
|
};
|
2891
3149
|
const getCompactCarCids = async (carCid) => {
|
2892
|
-
const reader = await this.loadCar(carCid);
|
3150
|
+
const reader = await this.loadCar(carCid, store);
|
2893
3151
|
if (!reader) {
|
2894
3152
|
throw this.logger.Error().Str("cid", carCid.toString()).Msg("missing car reader").AsError();
|
2895
3153
|
}
|
@@ -2932,36 +3190,37 @@ var Loader = class {
|
|
2932
3190
|
}
|
2933
3191
|
return got;
|
2934
3192
|
}
|
2935
|
-
async loadCar(cid) {
|
2936
|
-
|
2937
|
-
throw this.logger.Error().Msg("car store not initialized").AsError();
|
2938
|
-
}
|
2939
|
-
const loaded = await this.storesLoadCar(cid, await this.carStore(), this.remoteCarStore);
|
3193
|
+
async loadCar(cid, store) {
|
3194
|
+
const loaded = await this.storesLoadCar(cid, store.carStore());
|
2940
3195
|
return loaded;
|
2941
3196
|
}
|
2942
|
-
async makeDecoderAndCarReader(cid,
|
3197
|
+
async makeDecoderAndCarReader(cid, store) {
|
2943
3198
|
const cidsString = cid.toString();
|
2944
3199
|
let loadedCar = void 0;
|
2945
|
-
let activeStore = local;
|
3200
|
+
let activeStore = store.attached.local();
|
2946
3201
|
try {
|
2947
3202
|
this.logger.Debug().Any("cid", cidsString).Msg("loading car");
|
2948
|
-
loadedCar = await local.load(cid);
|
3203
|
+
loadedCar = await store.attached.local().load(cid);
|
2949
3204
|
this.logger.Debug().Bool("loadedCar", loadedCar).Msg("loaded");
|
2950
3205
|
} catch (e) {
|
2951
|
-
if (
|
3206
|
+
if (!isNotFoundError(e)) {
|
3207
|
+
throw this.logger.Error().Str("cid", cidsString).Err(e).Msg("loading car");
|
3208
|
+
}
|
3209
|
+
for (const remote of store.attached.remotes()) {
|
2952
3210
|
const remoteCar = await remote.load(cid);
|
2953
3211
|
if (remoteCar) {
|
2954
3212
|
this.logger.Debug().Ref("cid", remoteCar.cid).Msg("saving remote car locally");
|
2955
|
-
await local.save(remoteCar);
|
3213
|
+
await store.attached.local().save(remoteCar);
|
2956
3214
|
loadedCar = remoteCar;
|
2957
3215
|
activeStore = remote;
|
3216
|
+
break;
|
3217
|
+
} else {
|
3218
|
+
this.logger.Error().Str("cid", cidsString).Err(e).Msg("loading car");
|
2958
3219
|
}
|
2959
|
-
} else {
|
2960
|
-
this.logger.Error().Str("cid", cidsString).Err(e).Msg("loading car");
|
2961
3220
|
}
|
2962
3221
|
}
|
2963
3222
|
if (!loadedCar) {
|
2964
|
-
throw this.logger.Error().Url(local.url()).Str("cid", cidsString).Msg("missing car files").AsError();
|
3223
|
+
throw this.logger.Error().Url(store.attached.local().url()).Str("cid", cidsString).Msg("missing car files").AsError();
|
2965
3224
|
}
|
2966
3225
|
const bytes = await decode({ bytes: loadedCar.bytes, hasher: hasher4, codec: (await activeStore.keyedCrypto()).codec() });
|
2967
3226
|
const rawReader = await CarReader.fromBytes(bytes.value);
|
@@ -2977,19 +3236,19 @@ var Loader = class {
|
|
2977
3236
|
return readerP;
|
2978
3237
|
}
|
2979
3238
|
//What if instead it returns an Array of CarHeader
|
2980
|
-
async storesLoadCar(cid,
|
3239
|
+
async storesLoadCar(cid, store) {
|
2981
3240
|
const cidsString = cid.toString();
|
2982
3241
|
let dacr = this.carReaders.get(cidsString);
|
2983
3242
|
if (!dacr) {
|
2984
|
-
dacr = this.makeDecoderAndCarReader(cid,
|
3243
|
+
dacr = this.makeDecoderAndCarReader(cid, store);
|
2985
3244
|
this.carReaders.set(cidsString, dacr);
|
2986
3245
|
}
|
2987
3246
|
return dacr;
|
2988
3247
|
}
|
2989
|
-
async getMoreReaders(cids) {
|
3248
|
+
async getMoreReaders(cids, store) {
|
2990
3249
|
const limit = pLimit(5);
|
2991
3250
|
const missing = cids.filter((cid) => !this.carReaders.has(cid.toString()));
|
2992
|
-
await Promise.all(missing.map((cid) => limit(() => this.loadCar(cid))));
|
3251
|
+
await Promise.all(missing.map((cid) => limit(() => this.loadCar(cid, store))));
|
2993
3252
|
}
|
2994
3253
|
};
|
2995
3254
|
|
@@ -3360,7 +3619,7 @@ var BaseStoreImpl = class {
|
|
3360
3619
|
async keyedCrypto() {
|
3361
3620
|
return keyedCryptoFactory(this._url, await this.loader.keyBag(), this.sthis);
|
3362
3621
|
}
|
3363
|
-
async start() {
|
3622
|
+
async start(dam) {
|
3364
3623
|
this.logger.Debug().Str("storeType", this.storeType).Msg("starting-gateway-pre");
|
3365
3624
|
this._url = this._url.build().setParam(PARAM.STORE, this.storeType).URI();
|
3366
3625
|
const res = await this.gateway.start({ loader: this.loader }, this._url);
|
@@ -3397,7 +3656,7 @@ var BaseStoreImpl = class {
|
|
3397
3656
|
return ready;
|
3398
3657
|
}
|
3399
3658
|
}
|
3400
|
-
this._onStarted.forEach((fn) => fn());
|
3659
|
+
this._onStarted.forEach((fn) => fn(dam));
|
3401
3660
|
this.logger.Debug().Msg("started");
|
3402
3661
|
return version;
|
3403
3662
|
}
|
@@ -3426,12 +3685,19 @@ var MetaStoreImpl = class extends BaseStoreImpl {
|
|
3426
3685
|
/*this.remote && */
|
3427
3686
|
opts.gateway.subscribe
|
3428
3687
|
) {
|
3429
|
-
this.onStarted(async () => {
|
3688
|
+
this.onStarted(async (dam) => {
|
3430
3689
|
this.logger.Debug().Str("url", this.url().toString()).Msg("Subscribing to the gateway");
|
3431
3690
|
opts.gateway.subscribe({ loader: this.loader }, this.url(), async ({ payload: dbMetas }) => {
|
3432
3691
|
this.logger.Debug().Msg("Received message from gateway");
|
3433
3692
|
await Promise.all(
|
3434
|
-
dbMetas.map(
|
3693
|
+
dbMetas.map(
|
3694
|
+
(dbMetaEv) => this.loader.taskManager?.handleEvent(
|
3695
|
+
dbMetaEv.eventCid,
|
3696
|
+
dbMetaEv.parents,
|
3697
|
+
dbMetaEv.dbMeta,
|
3698
|
+
this.loader.attachedStores.activate(dam)
|
3699
|
+
)
|
3700
|
+
)
|
3435
3701
|
);
|
3436
3702
|
this.updateParentsFromDbMetas(dbMetas);
|
3437
3703
|
});
|
@@ -3466,10 +3732,11 @@ var MetaStoreImpl = class extends BaseStoreImpl {
|
|
3466
3732
|
}
|
3467
3733
|
throw this.logger.Error().Url(url.Ok()).Err(rfpEnv).Msg("gateway get").AsError();
|
3468
3734
|
}
|
3469
|
-
const
|
3470
|
-
|
3471
|
-
this.
|
3472
|
-
|
3735
|
+
const fpMeta = rfpEnv.Ok().payload;
|
3736
|
+
const dbMetas = fpMeta.map((m) => m.dbMeta);
|
3737
|
+
await this.loader.handleDbMetasFromStore(dbMetas, this.loader.attachedStores.local());
|
3738
|
+
this.updateParentsFromDbMetas(fpMeta);
|
3739
|
+
return dbMetas;
|
3473
3740
|
}
|
3474
3741
|
async save(meta, branch) {
|
3475
3742
|
branch = branch || "main";
|
@@ -3615,7 +3882,6 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3615
3882
|
}
|
3616
3883
|
async process() {
|
3617
3884
|
await this.ready();
|
3618
|
-
if (!this.loader.remoteCarStore) return;
|
3619
3885
|
await this.processQueue.enqueue(async () => {
|
3620
3886
|
try {
|
3621
3887
|
await this._doProcess();
|
@@ -3629,7 +3895,6 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3629
3895
|
}
|
3630
3896
|
async _doProcess() {
|
3631
3897
|
if (!this.loader) return;
|
3632
|
-
if (!this.loader.remoteCarStore) return;
|
3633
3898
|
const operations = [...this.walState.operations];
|
3634
3899
|
const noLoaderOps = [...this.walState.noLoaderOps];
|
3635
3900
|
const fileOperations = [...this.walState.fileOperations];
|
@@ -3650,13 +3915,13 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3650
3915
|
return;
|
3651
3916
|
}
|
3652
3917
|
for (const cid of dbMeta.cars) {
|
3653
|
-
const car = await
|
3918
|
+
const car = await this.loader.attachedStores.local().active.car.load(cid);
|
3654
3919
|
if (!car) {
|
3655
3920
|
if (carLogIncludesGroup(this.loader.carLog, dbMeta.cars)) {
|
3656
3921
|
throw this.logger.Error().Ref("cid", cid).Msg("missing local car").AsError();
|
3657
3922
|
}
|
3658
3923
|
} else {
|
3659
|
-
await
|
3924
|
+
await this.loader.attachedStores.forRemotes((x) => x.active.car.save(car));
|
3660
3925
|
}
|
3661
3926
|
}
|
3662
3927
|
inplaceFilter(this.walState.noLoaderOps, (op) => op !== dbMeta);
|
@@ -3672,13 +3937,13 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3672
3937
|
return;
|
3673
3938
|
}
|
3674
3939
|
for (const cid of dbMeta.cars) {
|
3675
|
-
const car = await
|
3940
|
+
const car = await this.loader.attachedStores.local().active.car.load(cid);
|
3676
3941
|
if (!car) {
|
3677
3942
|
if (carLogIncludesGroup(this.loader.carLog, dbMeta.cars)) {
|
3678
3943
|
throw this.logger.Error().Ref("cid", cid).Msg(`missing local car`).AsError();
|
3679
3944
|
}
|
3680
3945
|
} else {
|
3681
|
-
await
|
3946
|
+
await this.loader.attachedStores.forRemotes((x) => x.active.car.save(car));
|
3682
3947
|
}
|
3683
3948
|
}
|
3684
3949
|
inplaceFilter(this.walState.operations, (op) => op !== dbMeta);
|
@@ -3693,11 +3958,11 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3693
3958
|
if (!this.loader) {
|
3694
3959
|
return;
|
3695
3960
|
}
|
3696
|
-
const fileBlock = await
|
3961
|
+
const fileBlock = await this.loader.attachedStores.local().active.file.load(fileCid);
|
3697
3962
|
if (!fileBlock) {
|
3698
3963
|
throw this.logger.Error().Ref("cid", fileCid).Msg("missing file block").AsError();
|
3699
3964
|
}
|
3700
|
-
await this.loader.
|
3965
|
+
await this.loader.attachedStores.forRemotes((x) => x.active.file.save(fileBlock, { public: publicFile }));
|
3701
3966
|
inplaceFilter(this.walState.fileOperations, (op) => op.cid !== fileCid);
|
3702
3967
|
}, `fileOperation with cid=${fileCid.toString()}`);
|
3703
3968
|
},
|
@@ -3709,7 +3974,7 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3709
3974
|
if (!this.loader) {
|
3710
3975
|
return;
|
3711
3976
|
}
|
3712
|
-
await this.loader.
|
3977
|
+
await this.loader.attachedStores.forRemotes((x) => x.active.meta.save(lastOp));
|
3713
3978
|
}, `remoteMetaStore save with dbMeta.cars=${lastOp.cars.toString()}`);
|
3714
3979
|
}
|
3715
3980
|
} catch (error) {
|
@@ -3762,8 +4027,8 @@ var WALStoreImpl = class extends BaseStoreImpl {
|
|
3762
4027
|
};
|
3763
4028
|
|
3764
4029
|
// src/blockstore/store-factory.ts
|
3765
|
-
var onceGateway = new
|
3766
|
-
var gatewayInstances = new
|
4030
|
+
var onceGateway = new KeyedResolvOnce4();
|
4031
|
+
var gatewayInstances = new KeyedResolvOnce4();
|
3767
4032
|
async function getStartedGateway(ctx, url) {
|
3768
4033
|
return onceGateway.get(url.toString()).once(async () => {
|
3769
4034
|
const item = getGatewayFactoryItem(url.protocol);
|
@@ -3783,50 +4048,50 @@ async function getStartedGateway(ctx, url) {
|
|
3783
4048
|
return Result10.Err(ctx.loader.sthis.logger.Warn().Url(url).Msg("unsupported protocol").AsError());
|
3784
4049
|
});
|
3785
4050
|
}
|
3786
|
-
async function dataStoreFactory(
|
3787
|
-
const storeUrl =
|
3788
|
-
const rgateway = await getStartedGateway(
|
4051
|
+
async function dataStoreFactory(ctx, uai) {
|
4052
|
+
const storeUrl = uai.url.build().setParam(PARAM.STORE, "data").URI();
|
4053
|
+
const rgateway = await getStartedGateway(ctx, storeUrl);
|
3789
4054
|
if (rgateway.isErr()) {
|
3790
|
-
throw
|
4055
|
+
throw ctx.loader.sthis.logger.Error().Result("err", rgateway).Url(uai.url).Msg("notfound").AsError();
|
3791
4056
|
}
|
3792
4057
|
const gateway = rgateway.Ok();
|
3793
|
-
const store = new DataStoreImpl(
|
4058
|
+
const store = new DataStoreImpl(ctx.loader.sthis, gateway.url, {
|
3794
4059
|
gateway: gateway.gateway,
|
3795
|
-
gatewayInterceptor:
|
3796
|
-
loader:
|
4060
|
+
gatewayInterceptor: uai.gatewayInterceptor,
|
4061
|
+
loader: ctx.loader
|
3797
4062
|
});
|
3798
4063
|
return store;
|
3799
4064
|
}
|
3800
|
-
async function metaStoreFactory(
|
3801
|
-
const storeUrl =
|
3802
|
-
const rgateway = await getStartedGateway(
|
4065
|
+
async function metaStoreFactory(ctx, uai) {
|
4066
|
+
const storeUrl = uai.url.build().setParam(PARAM.STORE, "meta").URI();
|
4067
|
+
const rgateway = await getStartedGateway(ctx, storeUrl);
|
3803
4068
|
if (rgateway.isErr()) {
|
3804
|
-
throw
|
4069
|
+
throw ctx.loader.sthis.logger.Error().Result("err", rgateway).Url(uai.url).Msg("notfound").AsError();
|
3805
4070
|
}
|
3806
4071
|
const gateway = rgateway.Ok();
|
3807
|
-
const store = new MetaStoreImpl(
|
4072
|
+
const store = new MetaStoreImpl(ctx.loader.sthis, gateway.url, {
|
3808
4073
|
gateway: gateway.gateway,
|
3809
|
-
gatewayInterceptor:
|
3810
|
-
loader:
|
4074
|
+
gatewayInterceptor: uai.gatewayInterceptor,
|
4075
|
+
loader: ctx.loader
|
3811
4076
|
});
|
3812
4077
|
return store;
|
3813
4078
|
}
|
3814
|
-
async function WALStoreFactory(
|
3815
|
-
const storeUrl =
|
3816
|
-
const rgateway = await getStartedGateway(
|
4079
|
+
async function WALStoreFactory(ctx, uai) {
|
4080
|
+
const storeUrl = uai.url.build().setParam(PARAM.STORE, "wal").URI();
|
4081
|
+
const rgateway = await getStartedGateway(ctx, storeUrl);
|
3817
4082
|
if (rgateway.isErr()) {
|
3818
|
-
throw
|
4083
|
+
throw ctx.loader.sthis.logger.Error().Result("err", rgateway).Url(uai.url).Msg("notfound").AsError();
|
3819
4084
|
}
|
3820
4085
|
const gateway = rgateway.Ok();
|
3821
|
-
const store = new WALStoreImpl(
|
4086
|
+
const store = new WALStoreImpl(ctx.loader.sthis, gateway.url, {
|
3822
4087
|
gateway: gateway.gateway,
|
3823
|
-
gatewayInterceptor:
|
3824
|
-
loader:
|
4088
|
+
gatewayInterceptor: uai.gatewayInterceptor,
|
4089
|
+
loader: ctx.loader
|
3825
4090
|
});
|
3826
4091
|
return store;
|
3827
4092
|
}
|
3828
|
-
async function ensureStart(store) {
|
3829
|
-
const ret = await store.start();
|
4093
|
+
async function ensureStart(store, damaw) {
|
4094
|
+
const ret = await store.start(damaw);
|
3830
4095
|
if (ret.isErr()) {
|
3831
4096
|
throw store.logger.Error().Result("start", ret).Msg("start failed").AsError();
|
3832
4097
|
}
|
@@ -3842,191 +4107,32 @@ function ensureStoreEnDeFile(ende) {
|
|
3842
4107
|
}
|
3843
4108
|
function toStoreRuntime(sthis, endeOpts = {}) {
|
3844
4109
|
return {
|
3845
|
-
|
3846
|
-
|
3847
|
-
|
3848
|
-
|
3849
|
-
|
3850
|
-
|
3851
|
-
|
3852
|
-
|
3853
|
-
|
3854
|
-
|
3855
|
-
|
3856
|
-
|
3857
|
-
|
3858
|
-
|
3859
|
-
|
3860
|
-
|
3861
|
-
|
3862
|
-
|
3863
|
-
|
3864
|
-
//
|
3865
|
-
//
|
3866
|
-
//
|
3867
|
-
// return ensureStart(await (endeOpts.func?.makeWALStore || remoteWalFactory)(loader), logger);
|
3868
|
-
// },
|
4110
|
+
makeStores: async (sfi) => {
|
4111
|
+
const ctx = {
|
4112
|
+
loader: sfi.loader
|
4113
|
+
};
|
4114
|
+
const storeSet = {};
|
4115
|
+
storeSet.meta = await metaStoreFactory(ctx, sfi.byStore.meta);
|
4116
|
+
storeSet.car = await dataStoreFactory(ctx, sfi.byStore.car);
|
4117
|
+
storeSet.file = await dataStoreFactory(ctx, sfi.byStore.file);
|
4118
|
+
if (sfi.byStore.wal) {
|
4119
|
+
storeSet.wal = await WALStoreFactory(ctx, sfi.byStore.wal);
|
4120
|
+
}
|
4121
|
+
await ensureStart(storeSet.meta, storeSet);
|
4122
|
+
await ensureStart(storeSet.car, storeSet);
|
4123
|
+
await ensureStart(storeSet.file, storeSet);
|
4124
|
+
if (storeSet.wal) {
|
4125
|
+
await ensureStart(storeSet.wal, storeSet);
|
4126
|
+
}
|
4127
|
+
return storeSet;
|
4128
|
+
},
|
4129
|
+
// makeMetaStore: async (sfi: StoreFactoryItem) => ensureStart(await metaStoreFactory(sfi)),
|
4130
|
+
// makeDataStore: async (sfi: StoreFactoryItem) => ensureStart(await dataStoreFactory(sfi)),
|
4131
|
+
// makeWALStore: async (sfi: StoreFactoryItem) => ensureStart(await WALStoreFactory(sfi)),
|
3869
4132
|
...ensureStoreEnDeFile(endeOpts)
|
3870
4133
|
};
|
3871
4134
|
}
|
3872
4135
|
|
3873
|
-
// src/blockstore/connection-base.ts
|
3874
|
-
import { exception2Result as exception2Result4, Future as Future3 } from "@adviser/cement";
|
3875
|
-
|
3876
|
-
// src/blockstore/store-remote.ts
|
3877
|
-
async function RemoteDataStore(sthis, url, opts) {
|
3878
|
-
const ds = new DataStoreImpl(sthis, url, opts);
|
3879
|
-
await ds.start();
|
3880
|
-
return ds;
|
3881
|
-
}
|
3882
|
-
async function RemoteMetaStore(sthis, url, opts) {
|
3883
|
-
const ms = new MetaStoreImpl(sthis, url, opts);
|
3884
|
-
await ms.start();
|
3885
|
-
return ms;
|
3886
|
-
}
|
3887
|
-
|
3888
|
-
// src/context.ts
|
3889
|
-
var Context = class {
|
3890
|
-
constructor() {
|
3891
|
-
this.ctx = /* @__PURE__ */ new Map();
|
3892
|
-
}
|
3893
|
-
set(key, value) {
|
3894
|
-
this.ctx.set(key, value);
|
3895
|
-
}
|
3896
|
-
get(key) {
|
3897
|
-
return this.ctx.get(key);
|
3898
|
-
}
|
3899
|
-
delete(key) {
|
3900
|
-
this.ctx.delete(key);
|
3901
|
-
}
|
3902
|
-
};
|
3903
|
-
|
3904
|
-
// src/blockstore/connection-base.ts
|
3905
|
-
function coerceLoader(ref) {
|
3906
|
-
const refl = ref;
|
3907
|
-
if (refl.loader) {
|
3908
|
-
return refl.loader;
|
3909
|
-
}
|
3910
|
-
const refb = ref;
|
3911
|
-
if (refb.blockstore) {
|
3912
|
-
return coerceLoader(refb.blockstore);
|
3913
|
-
}
|
3914
|
-
return void 0;
|
3915
|
-
}
|
3916
|
-
var ConnectionBase = class {
|
3917
|
-
constructor(url, logger) {
|
3918
|
-
// loaded: Promise<void> = Promise.resolve();
|
3919
|
-
this.context = new Context();
|
3920
|
-
this._loaded = /* @__PURE__ */ new Set();
|
3921
|
-
this._metaIsLoading = false;
|
3922
|
-
this.logger = logger;
|
3923
|
-
this.url = url;
|
3924
|
-
}
|
3925
|
-
loaded() {
|
3926
|
-
const f = new Future3();
|
3927
|
-
if (!this._metaIsLoading) {
|
3928
|
-
f.resolve();
|
3929
|
-
} else {
|
3930
|
-
this._loaded.add(f);
|
3931
|
-
}
|
3932
|
-
return f;
|
3933
|
-
}
|
3934
|
-
async refresh() {
|
3935
|
-
await throwFalsy(throwFalsy(this.loader).remoteMetaStore).load();
|
3936
|
-
await (await throwFalsy(this.loader).WALStore()).process();
|
3937
|
-
}
|
3938
|
-
async connect(refl) {
|
3939
|
-
await this.connectMeta(refl);
|
3940
|
-
await this.connectStorage(refl);
|
3941
|
-
}
|
3942
|
-
async connectMeta(refl) {
|
3943
|
-
const loader = coerceLoader(refl);
|
3944
|
-
if (!loader) throw this.logger.Error().Msg("connectMeta: loader is required").AsError();
|
3945
|
-
this.loader = loader;
|
3946
|
-
await this.onConnect();
|
3947
|
-
const metaUrl = this.url.build().defParam(PARAM.STORE, "meta").URI();
|
3948
|
-
const rgateway = await getStartedGateway({ loader }, metaUrl);
|
3949
|
-
if (rgateway.isErr())
|
3950
|
-
throw this.logger.Error().Result("err", rgateway).Url(metaUrl).Msg("connectMeta: gateway is required").AsError();
|
3951
|
-
const dbName = metaUrl.getParam(PARAM.NAME);
|
3952
|
-
if (!dbName) {
|
3953
|
-
throw this.logger.Error().Url(metaUrl).Msg("connectMeta: dbName is required").AsError();
|
3954
|
-
}
|
3955
|
-
const gateway = rgateway.Ok();
|
3956
|
-
const remote = await RemoteMetaStore(loader.sthis, metaUrl, {
|
3957
|
-
gateway: gateway.gateway,
|
3958
|
-
loader
|
3959
|
-
});
|
3960
|
-
this.loader.remoteMetaStore = remote;
|
3961
|
-
this._metaIsLoading = true;
|
3962
|
-
this.loader.ready().then(async () => {
|
3963
|
-
return remote.load().then(async () => {
|
3964
|
-
const res = await exception2Result4(async () => {
|
3965
|
-
return await (await throwFalsy(this.loader).WALStore()).process();
|
3966
|
-
});
|
3967
|
-
this._metaIsLoading = false;
|
3968
|
-
for (const f of this._loaded) {
|
3969
|
-
if (res.isErr()) {
|
3970
|
-
f.reject(res.Err());
|
3971
|
-
} else {
|
3972
|
-
f.resolve();
|
3973
|
-
}
|
3974
|
-
}
|
3975
|
-
this._loaded.clear();
|
3976
|
-
});
|
3977
|
-
});
|
3978
|
-
}
|
3979
|
-
async connectStorage(refl) {
|
3980
|
-
const loader = coerceLoader(refl);
|
3981
|
-
if (!loader) throw this.logger.Error().Msg("connectStorage: loader is required").AsError();
|
3982
|
-
this.loader = loader;
|
3983
|
-
const dataUrl = this.url.build().defParam(PARAM.STORE, "data").URI();
|
3984
|
-
const rgateway = await getStartedGateway({ loader }, dataUrl);
|
3985
|
-
if (rgateway.isErr())
|
3986
|
-
throw this.logger.Error().Result("err", rgateway).Url(dataUrl).Msg("connectStorage: gateway is required").AsError();
|
3987
|
-
const name = dataUrl.getParam(PARAM.NAME);
|
3988
|
-
if (!name) throw this.logger.Error().Url(dataUrl).Msg("connectStorage: name is required").AsError;
|
3989
|
-
loader.remoteCarStore = await RemoteDataStore(loader.sthis, this.url, {
|
3990
|
-
gateway: rgateway.Ok().gateway,
|
3991
|
-
loader
|
3992
|
-
});
|
3993
|
-
loader.remoteFileStore = loader.remoteCarStore;
|
3994
|
-
}
|
3995
|
-
// move this stuff to connect
|
3996
|
-
// async getDashboardURL(compact = true) {
|
3997
|
-
// const baseUrl = 'https://dashboard.fireproof.storage/'
|
3998
|
-
// if (!this.loader?.remoteCarStore) return new URL('/howto', baseUrl)
|
3999
|
-
// // if (compact) {
|
4000
|
-
// // await this.compact()
|
4001
|
-
// // }
|
4002
|
-
// const currents = await this.loader?.metaStore?.load()
|
4003
|
-
// if (!currents) throw new Error("Can't sync empty ledger: save data first")
|
4004
|
-
// if (currents.length > 1)
|
4005
|
-
// throw new Error("Can't sync ledger with split heads: make an update first")
|
4006
|
-
// const current = currents[0]
|
4007
|
-
// const params = {
|
4008
|
-
// car: current.car.toString()
|
4009
|
-
// }
|
4010
|
-
// if (current.key) {
|
4011
|
-
// // @ts-ignore
|
4012
|
-
// params.key = current.key.toString()
|
4013
|
-
// }
|
4014
|
-
// // @ts-ignore
|
4015
|
-
// if (this.name) {
|
4016
|
-
// // @ts-ignore
|
4017
|
-
// params.name = this.name
|
4018
|
-
// }
|
4019
|
-
// const url = new URL('/import#' + new URLSearchParams(params).toString(), baseUrl)
|
4020
|
-
// console.log('Import to dashboard: ' + url.toString())
|
4021
|
-
// return url
|
4022
|
-
// }
|
4023
|
-
// openDashboard() {
|
4024
|
-
// void this.getDashboardURL().then(url => {
|
4025
|
-
// if (url) window.open(url.toString(), '_blank')
|
4026
|
-
// })
|
4027
|
-
// }
|
4028
|
-
};
|
4029
|
-
|
4030
4136
|
// src/crdt-helpers.ts
|
4031
4137
|
import { parse as parse2 } from "multiformats/link";
|
4032
4138
|
import { sha256 as hasher6 } from "multiformats/hashes/sha2";
|
@@ -4601,8 +4707,24 @@ var CRDTImpl = class {
|
|
4601
4707
|
}
|
4602
4708
|
};
|
4603
4709
|
|
4710
|
+
// src/context.ts
|
4711
|
+
var Context = class {
|
4712
|
+
constructor() {
|
4713
|
+
this.ctx = /* @__PURE__ */ new Map();
|
4714
|
+
}
|
4715
|
+
set(key, value) {
|
4716
|
+
this.ctx.set(key, value);
|
4717
|
+
}
|
4718
|
+
get(key) {
|
4719
|
+
return this.ctx.get(key);
|
4720
|
+
}
|
4721
|
+
delete(key) {
|
4722
|
+
this.ctx.delete(key);
|
4723
|
+
}
|
4724
|
+
};
|
4725
|
+
|
4604
4726
|
// src/ledger.ts
|
4605
|
-
var ledgers = new
|
4727
|
+
var ledgers = new KeyedResolvOnce5();
|
4606
4728
|
function keyConfigOpts(sthis, name, opts) {
|
4607
4729
|
return JSON.stringify(
|
4608
4730
|
toSortedArray({
|
@@ -4645,6 +4767,9 @@ var LedgerShell = class {
|
|
4645
4767
|
this.name = ref.name;
|
4646
4768
|
ref.addShell(this);
|
4647
4769
|
}
|
4770
|
+
attach(a) {
|
4771
|
+
return this.ref.attach(a);
|
4772
|
+
}
|
4648
4773
|
get opts() {
|
4649
4774
|
return this.ref.opts;
|
4650
4775
|
}
|
@@ -4743,6 +4868,9 @@ var LedgerImpl = class {
|
|
4743
4868
|
});
|
4744
4869
|
return ret;
|
4745
4870
|
}
|
4871
|
+
attach(a) {
|
4872
|
+
return this.crdt.blockstore.loader.attach(a);
|
4873
|
+
}
|
4746
4874
|
// readonly _asDb = new ResolveOnce<Database>();
|
4747
4875
|
// asDB(): Database {
|
4748
4876
|
// return this._asDb.once(() => new DatabaseImpl(this));
|
@@ -4791,7 +4919,7 @@ var LedgerImpl = class {
|
|
4791
4919
|
};
|
4792
4920
|
function defaultURI2(sthis, name, curi, uri, store, ctx) {
|
4793
4921
|
ctx = ctx || {};
|
4794
|
-
const ret = (curi ?
|
4922
|
+
const ret = (curi ? URI12.from(curi) : uri).build().setParam(PARAM.STORE, store).defParam(PARAM.NAME, name);
|
4795
4923
|
if (!ret.hasParam(PARAM.NAME)) {
|
4796
4924
|
throw sthis.logger.Error().Url(ret).Any("ctx", ctx).Msg("Ledger name is required").AsError();
|
4797
4925
|
}
|
@@ -4814,21 +4942,21 @@ function toStoreURIRuntime(sthis, name, sopts) {
|
|
4814
4942
|
if (!sopts.base) {
|
4815
4943
|
const fp_env = sthis.env.get("FP_STORAGE_URL");
|
4816
4944
|
if (fp_env) {
|
4817
|
-
sopts = { ...sopts, base:
|
4945
|
+
sopts = { ...sopts, base: BuildURI3.from(fp_env).setParam(PARAM.URL_GEN, "fromEnv") };
|
4818
4946
|
} else {
|
4819
4947
|
sopts = { ...sopts, base: getDefaultURI(sthis).build().setParam(PARAM.URL_GEN, "default") };
|
4820
4948
|
}
|
4821
4949
|
}
|
4822
|
-
const base =
|
4950
|
+
const base = URI12.from(sopts.base);
|
4823
4951
|
return {
|
4824
4952
|
idx: {
|
4825
|
-
|
4953
|
+
car: defaultURI2(sthis, name, sopts.idx?.data, base, "data", { idx: true }),
|
4826
4954
|
file: defaultURI2(sthis, name, sopts.idx?.data, base, "data", { file: true, idx: true }),
|
4827
4955
|
meta: defaultURI2(sthis, name, sopts.idx?.meta, base, "meta", { idx: true }),
|
4828
4956
|
wal: defaultURI2(sthis, name, sopts.idx?.wal, base, "wal", { idx: true })
|
4829
4957
|
},
|
4830
4958
|
data: {
|
4831
|
-
|
4959
|
+
car: defaultURI2(sthis, name, sopts.data?.data, base, "data"),
|
4832
4960
|
file: defaultURI2(sthis, name, sopts.data?.data, base, "data", { file: true }),
|
4833
4961
|
meta: defaultURI2(sthis, name, sopts.data?.meta, base, "meta"),
|
4834
4962
|
wal: defaultURI2(sthis, name, sopts.data?.wal, base, "wal")
|
@@ -4895,10 +5023,11 @@ __export(file_exports, {
|
|
4895
5023
|
|
4896
5024
|
// src/version.ts
|
4897
5025
|
var PACKAGE_VERSION = Object.keys({
|
4898
|
-
"0.20.0-dev-preview-
|
5026
|
+
"0.20.0-dev-preview-41": "xxxx"
|
4899
5027
|
})[0];
|
4900
5028
|
export {
|
4901
5029
|
CRDTImpl,
|
5030
|
+
DataAndMetaAndWalAndBaseStore,
|
4902
5031
|
DatabaseImpl,
|
4903
5032
|
Index,
|
4904
5033
|
LedgerFactory,
|