@fireproof/core-base 0.0.0-smoke-1b31059-1752074105
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/LICENSE.md +232 -0
- package/apply-head-queue.d.ts +17 -0
- package/apply-head-queue.js +47 -0
- package/apply-head-queue.js.map +1 -0
- package/apply-head-queue.ts +72 -0
- package/bundle-not-impl.d.ts +1 -0
- package/bundle-not-impl.js +4 -0
- package/bundle-not-impl.js.map +1 -0
- package/bundle-not-impl.ts +4 -0
- package/crdt-clock.d.ts +25 -0
- package/crdt-clock.js +138 -0
- package/crdt-clock.js.map +1 -0
- package/crdt-clock.ts +192 -0
- package/crdt-helpers.d.ts +18 -0
- package/crdt-helpers.js +331 -0
- package/crdt-helpers.js.map +1 -0
- package/crdt-helpers.ts +484 -0
- package/crdt.d.ts +40 -0
- package/crdt.js +172 -0
- package/crdt.js.map +1 -0
- package/crdt.ts +268 -0
- package/database.d.ts +32 -0
- package/database.js +136 -0
- package/database.js.map +1 -0
- package/database.ts +200 -0
- package/index.d.ts +6 -0
- package/index.js +7 -0
- package/index.js.map +1 -0
- package/index.ts +9 -0
- package/indexer-helpers.d.ts +25 -0
- package/indexer-helpers.js +155 -0
- package/indexer-helpers.js.map +1 -0
- package/indexer-helpers.ts +263 -0
- package/indexer.d.ts +22 -0
- package/indexer.js +246 -0
- package/indexer.js.map +1 -0
- package/indexer.ts +360 -0
- package/ledger.d.ts +55 -0
- package/ledger.js +245 -0
- package/ledger.js.map +1 -0
- package/ledger.ts +344 -0
- package/package.json +54 -0
- package/tsconfig.json +18 -0
- package/version.d.ts +1 -0
- package/version.js +4 -0
- package/version.js.map +1 -0
- package/version.ts +3 -0
- package/write-queue.d.ts +4 -0
- package/write-queue.js +69 -0
- package/write-queue.js.map +1 -0
- package/write-queue.ts +93 -0
package/ledger.js
ADDED
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
import { BuildURI, KeyedResolvOnce, ResolveOnce, URI, AppContext } from "@adviser/cement";
|
|
2
|
+
import { writeQueue } from "./write-queue.js";
|
|
3
|
+
import { defaultWriteQueueOpts, PARAM, } from "@fireproof/core-types-base";
|
|
4
|
+
import { decodeFile, encodeFile, ensureLogger, ensureSuperThis, ensureURIDefaults, hashObject } from "@fireproof/core-runtime";
|
|
5
|
+
import { DatabaseImpl } from "./database.js";
|
|
6
|
+
import { CRDTImpl } from "./crdt.js";
|
|
7
|
+
import { toSortedArray } from "@adviser/cement/utils";
|
|
8
|
+
import { getDefaultURI } from "@fireproof/core-blockstore";
|
|
9
|
+
import { defaultKeyBagOpts } from "@fireproof/core-keybag";
|
|
10
|
+
const ledgers = new KeyedResolvOnce();
|
|
11
|
+
export function keyConfigOpts(sthis, name, opts) {
|
|
12
|
+
return JSON.stringify(toSortedArray({
|
|
13
|
+
name,
|
|
14
|
+
stores: toSortedArray(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, name, opts?.storeUrls)))),
|
|
15
|
+
}));
|
|
16
|
+
}
|
|
17
|
+
export function isLedger(db) {
|
|
18
|
+
return db instanceof LedgerImpl || db instanceof LedgerShell;
|
|
19
|
+
}
|
|
20
|
+
export function LedgerFactory(name, opts) {
|
|
21
|
+
const sthis = ensureSuperThis(opts);
|
|
22
|
+
const key = keyConfigOpts(sthis, name, opts);
|
|
23
|
+
const item = ledgers.get(key);
|
|
24
|
+
return new LedgerShell(item.once((key) => {
|
|
25
|
+
const db = new LedgerImpl(sthis, {
|
|
26
|
+
name,
|
|
27
|
+
meta: opts?.meta,
|
|
28
|
+
keyBag: defaultKeyBagOpts(sthis, opts?.keyBag),
|
|
29
|
+
storeUrls: toStoreURIRuntime(sthis, name, opts?.storeUrls),
|
|
30
|
+
gatewayInterceptor: opts?.gatewayInterceptor,
|
|
31
|
+
writeQueue: defaultWriteQueueOpts(opts?.writeQueue),
|
|
32
|
+
ctx: opts?.ctx ?? new AppContext(),
|
|
33
|
+
storeEnDe: {
|
|
34
|
+
encodeFile,
|
|
35
|
+
decodeFile,
|
|
36
|
+
...opts?.storeEnDe,
|
|
37
|
+
},
|
|
38
|
+
tracer: opts?.tracer ??
|
|
39
|
+
(() => {
|
|
40
|
+
}),
|
|
41
|
+
});
|
|
42
|
+
db.onClosed(() => {
|
|
43
|
+
ledgers.unget(key);
|
|
44
|
+
});
|
|
45
|
+
return db;
|
|
46
|
+
}));
|
|
47
|
+
}
|
|
48
|
+
export class LedgerShell {
|
|
49
|
+
ref;
|
|
50
|
+
writeQueue;
|
|
51
|
+
name;
|
|
52
|
+
constructor(ref) {
|
|
53
|
+
this.ref = ref;
|
|
54
|
+
this.writeQueue = ref.writeQueue;
|
|
55
|
+
this.name = ref.name;
|
|
56
|
+
ref.addShell(this);
|
|
57
|
+
}
|
|
58
|
+
attach(a) {
|
|
59
|
+
return this.ref.attach(a);
|
|
60
|
+
}
|
|
61
|
+
get opts() {
|
|
62
|
+
return this.ref.opts;
|
|
63
|
+
}
|
|
64
|
+
get ctx() {
|
|
65
|
+
return this.ref.ctx;
|
|
66
|
+
}
|
|
67
|
+
refId() {
|
|
68
|
+
return this.ref.refId();
|
|
69
|
+
}
|
|
70
|
+
get logger() {
|
|
71
|
+
return this.ref.logger;
|
|
72
|
+
}
|
|
73
|
+
get sthis() {
|
|
74
|
+
return this.ref.sthis;
|
|
75
|
+
}
|
|
76
|
+
get crdt() {
|
|
77
|
+
return this.ref.crdt;
|
|
78
|
+
}
|
|
79
|
+
onClosed(fn) {
|
|
80
|
+
return this.ref.onClosed(fn);
|
|
81
|
+
}
|
|
82
|
+
close() {
|
|
83
|
+
return this.ref.shellClose(this);
|
|
84
|
+
}
|
|
85
|
+
destroy() {
|
|
86
|
+
return this.ref.destroy();
|
|
87
|
+
}
|
|
88
|
+
ready() {
|
|
89
|
+
return this.ref.ready();
|
|
90
|
+
}
|
|
91
|
+
subscribe(listener, updates) {
|
|
92
|
+
return this.ref.subscribe(listener, updates);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
class LedgerImpl {
|
|
96
|
+
opts;
|
|
97
|
+
_listening = false;
|
|
98
|
+
_listeners = new Set();
|
|
99
|
+
_noupdate_listeners = new Set();
|
|
100
|
+
crdt;
|
|
101
|
+
writeQueue;
|
|
102
|
+
shells = new Set();
|
|
103
|
+
ctx;
|
|
104
|
+
get name() {
|
|
105
|
+
return this.opts.name;
|
|
106
|
+
}
|
|
107
|
+
addShell(shell) {
|
|
108
|
+
this.shells.add(shell);
|
|
109
|
+
}
|
|
110
|
+
_refid = new ResolveOnce();
|
|
111
|
+
refId() {
|
|
112
|
+
return this._refid.once(() => hashObject(this.opts.storeUrls));
|
|
113
|
+
}
|
|
114
|
+
_onClosedFns = new Map();
|
|
115
|
+
onClosed(fn) {
|
|
116
|
+
const id = this.sthis.nextId().str;
|
|
117
|
+
this._onClosedFns.set(id, fn);
|
|
118
|
+
return () => {
|
|
119
|
+
this._onClosedFns.delete(id);
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
async close() {
|
|
123
|
+
throw this.logger.Error().Str("db", this.name).Msg(`use shellClose`).AsError();
|
|
124
|
+
}
|
|
125
|
+
async shellClose(db) {
|
|
126
|
+
if (!this.shells.has(db)) {
|
|
127
|
+
throw this.logger.Error().Str("db", this.name).Msg(`LedgerShell mismatch`).AsError();
|
|
128
|
+
}
|
|
129
|
+
this.shells.delete(db);
|
|
130
|
+
if (this.shells.size === 0) {
|
|
131
|
+
await this.ready();
|
|
132
|
+
await this.crdt.close();
|
|
133
|
+
await this.writeQueue.close();
|
|
134
|
+
this._onClosedFns.forEach((fn) => fn());
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
async destroy() {
|
|
138
|
+
await this.ready();
|
|
139
|
+
await this.crdt.destroy();
|
|
140
|
+
}
|
|
141
|
+
_ready = new ResolveOnce();
|
|
142
|
+
async ready() {
|
|
143
|
+
const ret = await this._ready.once(async () => {
|
|
144
|
+
await this.sthis.start();
|
|
145
|
+
await this.crdt.ready();
|
|
146
|
+
});
|
|
147
|
+
return ret;
|
|
148
|
+
}
|
|
149
|
+
logger;
|
|
150
|
+
sthis;
|
|
151
|
+
constructor(sthis, opts) {
|
|
152
|
+
this.opts = {
|
|
153
|
+
tracer: () => {
|
|
154
|
+
},
|
|
155
|
+
...opts,
|
|
156
|
+
};
|
|
157
|
+
this.sthis = sthis;
|
|
158
|
+
this.ctx = opts.ctx;
|
|
159
|
+
this.logger = ensureLogger(this.sthis, "Ledger");
|
|
160
|
+
this.crdt = new CRDTImpl(this.sthis, this.opts, this);
|
|
161
|
+
this.writeQueue = writeQueue(this.sthis, async (updates) => this.crdt.bulk(updates), this.opts.writeQueue);
|
|
162
|
+
this.crdt.clock.onTock(() => this._no_update_notify());
|
|
163
|
+
}
|
|
164
|
+
async attach(a) {
|
|
165
|
+
await this.ready();
|
|
166
|
+
return this.crdt.blockstore.loader.attach(a);
|
|
167
|
+
}
|
|
168
|
+
subscribe(listener, updates) {
|
|
169
|
+
this.ready();
|
|
170
|
+
this.logger.Debug().Bool("updates", updates).Msg("subscribe");
|
|
171
|
+
if (updates) {
|
|
172
|
+
if (!this._listening) {
|
|
173
|
+
this._listening = true;
|
|
174
|
+
this.crdt.clock.onTick((updates) => {
|
|
175
|
+
void this._notify(updates);
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
this._listeners.add(listener);
|
|
179
|
+
return () => {
|
|
180
|
+
this._listeners.delete(listener);
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
else {
|
|
184
|
+
this._noupdate_listeners.add(listener);
|
|
185
|
+
return () => {
|
|
186
|
+
this._noupdate_listeners.delete(listener);
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
async _notify(updates) {
|
|
191
|
+
await this.ready();
|
|
192
|
+
if (this._listeners.size) {
|
|
193
|
+
const docs = updates.map(({ id, value }) => ({ ...value, _id: id }));
|
|
194
|
+
for (const listener of this._listeners) {
|
|
195
|
+
await (async () => await listener(docs))().catch((e) => {
|
|
196
|
+
this.logger.Error().Err(e).Msg("subscriber error");
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
async _no_update_notify() {
|
|
202
|
+
await this.ready();
|
|
203
|
+
if (this._noupdate_listeners.size) {
|
|
204
|
+
for (const listener of this._noupdate_listeners) {
|
|
205
|
+
await (async () => await listener([]))().catch((e) => {
|
|
206
|
+
this.logger.Error().Err(e).Msg("subscriber error");
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
export function toStoreURIRuntime(sthis, name, sopts) {
|
|
213
|
+
sopts = sopts || {};
|
|
214
|
+
if (!sopts.base) {
|
|
215
|
+
const fp_env = sthis.env.get("FP_STORAGE_URL");
|
|
216
|
+
if (fp_env) {
|
|
217
|
+
sopts = { ...sopts, base: BuildURI.from(fp_env).setParam(PARAM.URL_GEN, "fromEnv") };
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
sopts = { ...sopts, base: getDefaultURI(sthis).build().setParam(PARAM.URL_GEN, "default") };
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
const base = URI.from(sopts.base);
|
|
224
|
+
return {
|
|
225
|
+
idx: {
|
|
226
|
+
car: ensureURIDefaults(sthis, { name }, sopts.idx?.car ?? sopts.data?.car, base, "car", { idx: true }),
|
|
227
|
+
file: ensureURIDefaults(sthis, { name }, sopts.idx?.file ?? sopts.idx?.car ?? sopts.data?.file ?? sopts.data?.car, base, "file", {
|
|
228
|
+
file: true,
|
|
229
|
+
idx: true,
|
|
230
|
+
}),
|
|
231
|
+
meta: ensureURIDefaults(sthis, { name }, sopts.idx?.meta ?? sopts.data?.meta, base, "meta", { idx: true }),
|
|
232
|
+
wal: ensureURIDefaults(sthis, { name }, sopts.idx?.wal ?? sopts.data?.wal, base, "wal", { idx: true }),
|
|
233
|
+
},
|
|
234
|
+
data: {
|
|
235
|
+
car: ensureURIDefaults(sthis, { name }, sopts.data?.car, base, "car"),
|
|
236
|
+
file: ensureURIDefaults(sthis, { name }, sopts.data?.file ?? sopts.data?.car, base, "file", { file: true }),
|
|
237
|
+
meta: ensureURIDefaults(sthis, { name }, sopts.data?.meta, base, "meta"),
|
|
238
|
+
wal: ensureURIDefaults(sthis, { name }, sopts.data?.wal, base, "wal"),
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
export function fireproof(name, opts) {
|
|
243
|
+
return new DatabaseImpl(LedgerFactory(name, opts));
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=ledger.js.map
|
package/ledger.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ledger.js","sourceRoot":"","sources":["ledger.ts"],"names":[],"mappings":"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"}
|
package/ledger.ts
ADDED
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import { BuildURI, KeyedResolvOnce, Logger, ResolveOnce, URI, AppContext } from "@adviser/cement";
|
|
2
|
+
|
|
3
|
+
import { writeQueue } from "./write-queue.js";
|
|
4
|
+
import {
|
|
5
|
+
DocUpdate,
|
|
6
|
+
ConfigOpts,
|
|
7
|
+
defaultWriteQueueOpts,
|
|
8
|
+
DocWithId,
|
|
9
|
+
ListenerFn,
|
|
10
|
+
DocTypes,
|
|
11
|
+
SuperThis,
|
|
12
|
+
Database,
|
|
13
|
+
Ledger,
|
|
14
|
+
WriteQueue,
|
|
15
|
+
CRDT,
|
|
16
|
+
LedgerOpts,
|
|
17
|
+
Attachable,
|
|
18
|
+
Attached,
|
|
19
|
+
LedgerOptsOptionalTracer,
|
|
20
|
+
PARAM,
|
|
21
|
+
} from "@fireproof/core-types-base";
|
|
22
|
+
import { StoreURIRuntime, StoreUrlsOpts } from "@fireproof/core-types-blockstore";
|
|
23
|
+
import { decodeFile, encodeFile, ensureLogger, ensureSuperThis, ensureURIDefaults, hashObject } from "@fireproof/core-runtime";
|
|
24
|
+
|
|
25
|
+
import { DatabaseImpl } from "./database.js";
|
|
26
|
+
import { CRDTImpl } from "./crdt.js";
|
|
27
|
+
import { toSortedArray } from "@adviser/cement/utils";
|
|
28
|
+
import { getDefaultURI } from "@fireproof/core-blockstore";
|
|
29
|
+
import { defaultKeyBagOpts } from "@fireproof/core-keybag";
|
|
30
|
+
|
|
31
|
+
const ledgers = new KeyedResolvOnce<Ledger>();
|
|
32
|
+
|
|
33
|
+
export function keyConfigOpts(sthis: SuperThis, name: string, opts?: ConfigOpts): string {
|
|
34
|
+
return JSON.stringify(
|
|
35
|
+
toSortedArray({
|
|
36
|
+
name,
|
|
37
|
+
stores: toSortedArray(JSON.parse(JSON.stringify(toStoreURIRuntime(sthis, name, opts?.storeUrls)))),
|
|
38
|
+
}),
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function isLedger(db: unknown): db is Ledger {
|
|
43
|
+
return db instanceof LedgerImpl || db instanceof LedgerShell;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function LedgerFactory(name: string, opts?: ConfigOpts): Ledger {
|
|
47
|
+
const sthis = ensureSuperThis(opts);
|
|
48
|
+
const key = keyConfigOpts(sthis, name, opts);
|
|
49
|
+
const item = ledgers.get(key);
|
|
50
|
+
// if (!item.ready) {
|
|
51
|
+
// console.log("LedgerFactory", key);
|
|
52
|
+
// }
|
|
53
|
+
return new LedgerShell(
|
|
54
|
+
item.once((key) => {
|
|
55
|
+
// console.log("once-LedgerFactory", key);
|
|
56
|
+
|
|
57
|
+
const db = new LedgerImpl(sthis, {
|
|
58
|
+
name,
|
|
59
|
+
meta: opts?.meta,
|
|
60
|
+
keyBag: defaultKeyBagOpts(sthis, opts?.keyBag),
|
|
61
|
+
storeUrls: toStoreURIRuntime(sthis, name, opts?.storeUrls),
|
|
62
|
+
gatewayInterceptor: opts?.gatewayInterceptor,
|
|
63
|
+
writeQueue: defaultWriteQueueOpts(opts?.writeQueue),
|
|
64
|
+
ctx: opts?.ctx ?? new AppContext(),
|
|
65
|
+
storeEnDe: {
|
|
66
|
+
encodeFile,
|
|
67
|
+
decodeFile,
|
|
68
|
+
...opts?.storeEnDe,
|
|
69
|
+
},
|
|
70
|
+
tracer:
|
|
71
|
+
opts?.tracer ??
|
|
72
|
+
(() => {
|
|
73
|
+
/* noop */
|
|
74
|
+
}),
|
|
75
|
+
});
|
|
76
|
+
db.onClosed(() => {
|
|
77
|
+
ledgers.unget(key);
|
|
78
|
+
});
|
|
79
|
+
return db;
|
|
80
|
+
}),
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export class LedgerShell implements Ledger {
|
|
85
|
+
readonly ref: LedgerImpl;
|
|
86
|
+
readonly writeQueue: WriteQueue<DocUpdate<DocTypes>>;
|
|
87
|
+
readonly name: string;
|
|
88
|
+
|
|
89
|
+
constructor(ref: LedgerImpl) {
|
|
90
|
+
this.ref = ref;
|
|
91
|
+
this.writeQueue = ref.writeQueue;
|
|
92
|
+
this.name = ref.name;
|
|
93
|
+
ref.addShell(this);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
attach(a: Attachable): Promise<Attached> {
|
|
97
|
+
return this.ref.attach(a);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
get opts(): LedgerOpts {
|
|
101
|
+
return this.ref.opts;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
get ctx(): AppContext {
|
|
105
|
+
return this.ref.ctx;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
refId(): Promise<string> {
|
|
109
|
+
return this.ref.refId();
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// get id(): string {
|
|
113
|
+
// return this.ref.id;
|
|
114
|
+
// }
|
|
115
|
+
get logger(): Logger {
|
|
116
|
+
return this.ref.logger;
|
|
117
|
+
}
|
|
118
|
+
get sthis(): SuperThis {
|
|
119
|
+
return this.ref.sthis;
|
|
120
|
+
}
|
|
121
|
+
get crdt(): CRDT {
|
|
122
|
+
return this.ref.crdt;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
onClosed(fn: () => void): () => void {
|
|
126
|
+
return this.ref.onClosed(fn);
|
|
127
|
+
}
|
|
128
|
+
close(): Promise<void> {
|
|
129
|
+
return this.ref.shellClose(this);
|
|
130
|
+
}
|
|
131
|
+
destroy(): Promise<void> {
|
|
132
|
+
return this.ref.destroy();
|
|
133
|
+
}
|
|
134
|
+
ready(): Promise<void> {
|
|
135
|
+
return this.ref.ready();
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// asDB(): Database {
|
|
139
|
+
// return this.ref.asDB();
|
|
140
|
+
// }
|
|
141
|
+
|
|
142
|
+
subscribe<T extends DocTypes>(listener: ListenerFn<T>, updates?: boolean): () => void {
|
|
143
|
+
return this.ref.subscribe(listener, updates);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
class LedgerImpl implements Ledger {
|
|
148
|
+
// readonly name: string;
|
|
149
|
+
readonly opts: LedgerOpts;
|
|
150
|
+
|
|
151
|
+
_listening = false;
|
|
152
|
+
readonly _listeners = new Set<ListenerFn<DocTypes>>();
|
|
153
|
+
readonly _noupdate_listeners = new Set<ListenerFn<DocTypes>>();
|
|
154
|
+
readonly crdt: CRDT;
|
|
155
|
+
readonly writeQueue: WriteQueue<DocUpdate<DocTypes>>;
|
|
156
|
+
// readonly blockstore: BaseBlockstore;
|
|
157
|
+
|
|
158
|
+
readonly shells: Set<LedgerShell> = new Set<LedgerShell>();
|
|
159
|
+
|
|
160
|
+
readonly ctx: AppContext;
|
|
161
|
+
|
|
162
|
+
get name(): string {
|
|
163
|
+
return this.opts.name;
|
|
164
|
+
// this.opts.storeUrls.data.data.getParam(PARAM.NAME) ?? "default";
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
addShell(shell: LedgerShell) {
|
|
168
|
+
this.shells.add(shell);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
readonly _refid = new ResolveOnce<string>();
|
|
172
|
+
refId(): Promise<string> {
|
|
173
|
+
return this._refid.once(() => hashObject(this.opts.storeUrls));
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
readonly _onClosedFns = new Map<string, () => void>();
|
|
177
|
+
onClosed(fn: () => void): () => void {
|
|
178
|
+
const id = this.sthis.nextId().str;
|
|
179
|
+
this._onClosedFns.set(id, fn);
|
|
180
|
+
return () => {
|
|
181
|
+
this._onClosedFns.delete(id);
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async close() {
|
|
185
|
+
throw this.logger.Error().Str("db", this.name).Msg(`use shellClose`).AsError();
|
|
186
|
+
}
|
|
187
|
+
async shellClose(db: LedgerShell) {
|
|
188
|
+
if (!this.shells.has(db)) {
|
|
189
|
+
throw this.logger.Error().Str("db", this.name).Msg(`LedgerShell mismatch`).AsError();
|
|
190
|
+
}
|
|
191
|
+
this.shells.delete(db);
|
|
192
|
+
if (this.shells.size === 0) {
|
|
193
|
+
await this.ready();
|
|
194
|
+
await this.crdt.close();
|
|
195
|
+
await this.writeQueue.close();
|
|
196
|
+
this._onClosedFns.forEach((fn) => fn());
|
|
197
|
+
}
|
|
198
|
+
// await this.blockstore.close();
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async destroy() {
|
|
202
|
+
await this.ready();
|
|
203
|
+
await this.crdt.destroy();
|
|
204
|
+
// await this.blockstore.destroy();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
readonly _ready: ResolveOnce<void> = new ResolveOnce<void>();
|
|
208
|
+
async ready(): Promise<void> {
|
|
209
|
+
const ret = await this._ready.once(async () => {
|
|
210
|
+
await this.sthis.start();
|
|
211
|
+
await this.crdt.ready();
|
|
212
|
+
// await this.blockstore.ready();
|
|
213
|
+
});
|
|
214
|
+
return ret;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
readonly logger: Logger;
|
|
218
|
+
readonly sthis: SuperThis;
|
|
219
|
+
// readonly id: string;
|
|
220
|
+
|
|
221
|
+
constructor(sthis: SuperThis, opts: LedgerOptsOptionalTracer) {
|
|
222
|
+
this.opts = {
|
|
223
|
+
tracer: () => {
|
|
224
|
+
/* noop */
|
|
225
|
+
},
|
|
226
|
+
...opts,
|
|
227
|
+
}; // || this.opts;
|
|
228
|
+
// this.name = opts.storeUrls.data.data.getParam(PARAM.NAME) || "default";
|
|
229
|
+
this.sthis = sthis;
|
|
230
|
+
this.ctx = opts.ctx;
|
|
231
|
+
// this.id = sthis.timeOrderedNextId().str;
|
|
232
|
+
this.logger = ensureLogger(this.sthis, "Ledger");
|
|
233
|
+
this.crdt = new CRDTImpl(this.sthis, this.opts, this);
|
|
234
|
+
this.writeQueue = writeQueue(
|
|
235
|
+
this.sthis,
|
|
236
|
+
async (updates: DocUpdate<DocTypes>[]) => this.crdt.bulk(updates),
|
|
237
|
+
this.opts.writeQueue,
|
|
238
|
+
);
|
|
239
|
+
this.crdt.clock.onTock(() => this._no_update_notify());
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async attach(a: Attachable): Promise<Attached> {
|
|
243
|
+
await this.ready();
|
|
244
|
+
return this.crdt.blockstore.loader.attach(a);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// readonly _asDb = new ResolveOnce<Database>();
|
|
248
|
+
// asDB(): Database {
|
|
249
|
+
// return this._asDb.once(() => new DatabaseImpl(this));
|
|
250
|
+
// }
|
|
251
|
+
|
|
252
|
+
subscribe<T extends DocTypes>(listener: ListenerFn<T>, updates?: boolean): () => void {
|
|
253
|
+
this.ready();
|
|
254
|
+
this.logger.Debug().Bool("updates", updates).Msg("subscribe");
|
|
255
|
+
if (updates) {
|
|
256
|
+
if (!this._listening) {
|
|
257
|
+
this._listening = true;
|
|
258
|
+
this.crdt.clock.onTick((updates: DocUpdate<NonNullable<unknown>>[]) => {
|
|
259
|
+
void this._notify(updates);
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
this._listeners.add(listener as ListenerFn<NonNullable<unknown>>);
|
|
263
|
+
return () => {
|
|
264
|
+
this._listeners.delete(listener as ListenerFn<NonNullable<unknown>>);
|
|
265
|
+
};
|
|
266
|
+
} else {
|
|
267
|
+
this._noupdate_listeners.add(listener as ListenerFn<NonNullable<unknown>>);
|
|
268
|
+
return () => {
|
|
269
|
+
this._noupdate_listeners.delete(listener as ListenerFn<NonNullable<unknown>>);
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
private async _notify(updates: DocUpdate<DocTypes>[]) {
|
|
275
|
+
await this.ready();
|
|
276
|
+
if (this._listeners.size) {
|
|
277
|
+
const docs: DocWithId<DocTypes>[] = updates.map(({ id, value }) => ({ ...value, _id: id }));
|
|
278
|
+
for (const listener of this._listeners) {
|
|
279
|
+
await (async () => await listener(docs as DocWithId<DocTypes>[]))().catch((e: Error) => {
|
|
280
|
+
this.logger.Error().Err(e).Msg("subscriber error");
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
private async _no_update_notify() {
|
|
287
|
+
await this.ready();
|
|
288
|
+
if (this._noupdate_listeners.size) {
|
|
289
|
+
for (const listener of this._noupdate_listeners) {
|
|
290
|
+
await (async () => await listener([]))().catch((e: Error) => {
|
|
291
|
+
this.logger.Error().Err(e).Msg("subscriber error");
|
|
292
|
+
});
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
export function toStoreURIRuntime(sthis: SuperThis, name: string, sopts?: StoreUrlsOpts): StoreURIRuntime {
|
|
299
|
+
sopts = sopts || {};
|
|
300
|
+
if (!sopts.base) {
|
|
301
|
+
const fp_env = sthis.env.get("FP_STORAGE_URL");
|
|
302
|
+
if (fp_env) {
|
|
303
|
+
sopts = { ...sopts, base: BuildURI.from(fp_env).setParam(PARAM.URL_GEN, "fromEnv") };
|
|
304
|
+
} else {
|
|
305
|
+
sopts = { ...sopts, base: getDefaultURI(sthis).build().setParam(PARAM.URL_GEN, "default") };
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
const base = URI.from(sopts.base);
|
|
309
|
+
// bbase.setParam(PARAM.NAME, name);
|
|
310
|
+
// const base = bbase.URI();
|
|
311
|
+
// readonly public?: boolean;
|
|
312
|
+
// readonly meta?: DbMeta;
|
|
313
|
+
// readonly persistIndexes?: boolean;
|
|
314
|
+
// readonly autoCompact?: number;
|
|
315
|
+
// readonly threshold?: number;
|
|
316
|
+
return {
|
|
317
|
+
idx: {
|
|
318
|
+
car: ensureURIDefaults(sthis, { name }, sopts.idx?.car ?? sopts.data?.car, base, "car", { idx: true }),
|
|
319
|
+
file: ensureURIDefaults(
|
|
320
|
+
sthis,
|
|
321
|
+
{ name },
|
|
322
|
+
sopts.idx?.file ?? sopts.idx?.car ?? sopts.data?.file ?? sopts.data?.car,
|
|
323
|
+
base,
|
|
324
|
+
"file",
|
|
325
|
+
{
|
|
326
|
+
file: true,
|
|
327
|
+
idx: true,
|
|
328
|
+
},
|
|
329
|
+
),
|
|
330
|
+
meta: ensureURIDefaults(sthis, { name }, sopts.idx?.meta ?? sopts.data?.meta, base, "meta", { idx: true }),
|
|
331
|
+
wal: ensureURIDefaults(sthis, { name }, sopts.idx?.wal ?? sopts.data?.wal, base, "wal", { idx: true }),
|
|
332
|
+
},
|
|
333
|
+
data: {
|
|
334
|
+
car: ensureURIDefaults(sthis, { name }, sopts.data?.car, base, "car"),
|
|
335
|
+
file: ensureURIDefaults(sthis, { name }, sopts.data?.file ?? sopts.data?.car, base, "file", { file: true }),
|
|
336
|
+
meta: ensureURIDefaults(sthis, { name }, sopts.data?.meta, base, "meta"),
|
|
337
|
+
wal: ensureURIDefaults(sthis, { name }, sopts.data?.wal, base, "wal"),
|
|
338
|
+
},
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
export function fireproof(name: string, opts?: ConfigOpts): Database {
|
|
343
|
+
return new DatabaseImpl(LedgerFactory(name, opts));
|
|
344
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@fireproof/core-base",
|
|
3
|
+
"version": "0.0.0-smoke-1b31059-1752074105",
|
|
4
|
+
"description": "Live ledger for the web.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./index.js",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ledger",
|
|
9
|
+
"JSON",
|
|
10
|
+
"document",
|
|
11
|
+
"IPLD",
|
|
12
|
+
"CID",
|
|
13
|
+
"IPFS"
|
|
14
|
+
],
|
|
15
|
+
"contributors": [
|
|
16
|
+
"J Chris Anderson",
|
|
17
|
+
"Alan Shaw",
|
|
18
|
+
"Travis Vachon",
|
|
19
|
+
"Mikeal Rogers",
|
|
20
|
+
"Meno Abels"
|
|
21
|
+
],
|
|
22
|
+
"author": "J Chris Anderson",
|
|
23
|
+
"license": "Apache-2.0 OR MIT",
|
|
24
|
+
"homepage": "https://use-fireproof.com",
|
|
25
|
+
"gptdoc": "import { fireproof } from 'use-fireproof'; const db = fireproof('app-db-name'); const ok = await db.put({ anyField: ['any','json'] }); const doc = await db.get(ok.id); await db.del(doc._id); db.subscribe(myRedrawFn); const result = await db.query('anyField', {range : ['a', 'z']}); result.rows.map(({ key }) => key);",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/fireproof-storage/fireproof.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/fireproof-storage/fireproof/issues"
|
|
32
|
+
},
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@adviser/cement": "^0.4.20",
|
|
35
|
+
"@fireproof/core-blockstore": "0.0.0-smoke-1b31059-1752074105",
|
|
36
|
+
"@fireproof/core-keybag": "0.0.0-smoke-1b31059-1752074105",
|
|
37
|
+
"@fireproof/core-runtime": "0.0.0-smoke-1b31059-1752074105",
|
|
38
|
+
"@fireproof/core-types-base": "0.0.0-smoke-1b31059-1752074105",
|
|
39
|
+
"@fireproof/core-types-blockstore": "0.0.0-smoke-1b31059-1752074105",
|
|
40
|
+
"@fireproof/core-types-protocols-cloud": "0.0.0-smoke-1b31059-1752074105",
|
|
41
|
+
"@fireproof/vendor": "^3.0.0",
|
|
42
|
+
"@ipld/dag-cbor": "^9.2.4",
|
|
43
|
+
"@web3-storage/pail": "^0.6.2",
|
|
44
|
+
"charwise": "^3.0.1",
|
|
45
|
+
"prolly-trees": "^1.0.4"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@fireproof/core-cli": "0.0.0-smoke-1b31059-1752074105",
|
|
49
|
+
"@types/node": "^24.0.10"
|
|
50
|
+
},
|
|
51
|
+
"scripts": {
|
|
52
|
+
"build": "tsc"
|
|
53
|
+
}
|
|
54
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": [
|
|
3
|
+
"/home/runner/work/fireproof/fireproof/tsconfig.dist.json"
|
|
4
|
+
],
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"noEmit": false,
|
|
7
|
+
"outDir": "./"
|
|
8
|
+
},
|
|
9
|
+
"include": [
|
|
10
|
+
"**/*"
|
|
11
|
+
],
|
|
12
|
+
"exclude": [
|
|
13
|
+
"node_modules",
|
|
14
|
+
"dist",
|
|
15
|
+
".git",
|
|
16
|
+
".vscode"
|
|
17
|
+
]
|
|
18
|
+
}
|
package/version.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const PACKAGE_VERSION: string;
|
package/version.js
ADDED
package/version.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["version.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,MAAM,CAAC,IAAI,CAAC;IACzC,kBAAkB,EAAE,MAAM;CAC3B,CAAC,CAAC,CAAC,CAAW,CAAC"}
|