@vielzeug/vault 2.5.0 → 3.0.1
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 +25 -32
- package/dist/adapter-core.cjs +1 -1
- package/dist/adapter-core.cjs.map +1 -1
- package/dist/adapter-core.d.ts +32 -7
- package/dist/adapter-core.d.ts.map +1 -1
- package/dist/adapter-core.js +204 -120
- package/dist/adapter-core.js.map +1 -1
- package/dist/adapters/indexeddb.cjs +1 -1
- package/dist/adapters/indexeddb.cjs.map +1 -1
- package/dist/adapters/indexeddb.d.ts +7 -4
- package/dist/adapters/indexeddb.d.ts.map +1 -1
- package/dist/adapters/indexeddb.js +204 -172
- package/dist/adapters/indexeddb.js.map +1 -1
- package/dist/adapters/memory.cjs +1 -1
- package/dist/adapters/memory.cjs.map +1 -1
- package/dist/adapters/memory.d.ts +2 -4
- package/dist/adapters/memory.d.ts.map +1 -1
- package/dist/adapters/memory.js +30 -52
- package/dist/adapters/memory.js.map +1 -1
- package/dist/adapters/sqlite.cjs +21 -21
- package/dist/adapters/sqlite.cjs.map +1 -1
- package/dist/adapters/sqlite.d.ts +4 -4
- package/dist/adapters/sqlite.d.ts.map +1 -1
- package/dist/adapters/sqlite.js +246 -248
- package/dist/adapters/sqlite.js.map +1 -1
- package/dist/adapters/webstorage.cjs +1 -1
- package/dist/adapters/webstorage.cjs.map +1 -1
- package/dist/adapters/webstorage.d.ts +4 -4
- package/dist/adapters/webstorage.d.ts.map +1 -1
- package/dist/adapters/webstorage.js +100 -119
- package/dist/adapters/webstorage.js.map +1 -1
- package/dist/codec.cjs +2 -0
- package/dist/codec.cjs.map +1 -0
- package/dist/codec.d.ts +5 -0
- package/dist/codec.d.ts.map +1 -0
- package/dist/codec.js +6 -0
- package/dist/codec.js.map +1 -0
- package/dist/errors.cjs +1 -1
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.d.ts +5 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +10 -2
- package/dist/errors.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/internal.cjs +1 -1
- package/dist/internal.cjs.map +1 -1
- package/dist/internal.d.ts.map +1 -1
- package/dist/internal.js +16 -13
- package/dist/internal.js.map +1 -1
- package/dist/query.cjs +1 -1
- package/dist/query.cjs.map +1 -1
- package/dist/query.d.ts +8 -24
- package/dist/query.d.ts.map +1 -1
- package/dist/query.js +23 -35
- package/dist/query.js.map +1 -1
- package/dist/ttl.cjs +1 -1
- package/dist/ttl.cjs.map +1 -1
- package/dist/ttl.js +1 -1
- package/dist/ttl.js.map +1 -1
- package/dist/types.cjs +1 -1
- package/dist/types.cjs.map +1 -1
- package/dist/types.d.ts +46 -33
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +8 -2
- package/dist/types.js.map +1 -1
- package/dist/vault.cjs +1 -1
- package/dist/vault.cjs.map +1 -1
- package/dist/vault.iife.js +1 -1
- package/dist/vault.iife.js.map +1 -1
- package/dist/vault.js +1 -1
- package/dist/vault.js.map +1 -1
- package/package.json +11 -9
package/dist/adapter-core.js
CHANGED
|
@@ -1,53 +1,53 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { validateRecord as e } from "./codec.js";
|
|
2
|
+
import { VaultDisposedError as t, VaultError as n, VaultScopeError as r } from "./errors.js";
|
|
3
3
|
import { createObserverHub as i, getRecordKey as a } from "./internal.js";
|
|
4
4
|
import { createQueryBuilder as o } from "./query.js";
|
|
5
|
+
import { assertPositiveFinite as s } from "./ttl.js";
|
|
5
6
|
//#region src/adapter-core.ts
|
|
6
|
-
function
|
|
7
|
-
if (e.length === 0) throw new
|
|
7
|
+
function c(e) {
|
|
8
|
+
if (e.length === 0) throw new n("batch: declare at least one table");
|
|
8
9
|
}
|
|
9
|
-
function
|
|
10
|
-
return n !== void 0 &&
|
|
10
|
+
function l(e, t, n) {
|
|
11
|
+
return n !== void 0 && s(n, "put/putAll"), n ?? e[t].defaultTtl;
|
|
11
12
|
}
|
|
12
|
-
function
|
|
13
|
-
let s = a(e,
|
|
14
|
-
if (s !== r) throw new
|
|
13
|
+
function u(e, t, r, i, o) {
|
|
14
|
+
let s = a(e, t, i);
|
|
15
|
+
if (s !== r) throw new n(`${o}: key field "${e[t].key}" must be "${String(r)}" but got "${String(s)}" in table "${t}"`);
|
|
15
16
|
}
|
|
16
|
-
function
|
|
17
|
-
return
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
},
|
|
26
|
-
source: () => t.getAll(e)
|
|
17
|
+
function d(t) {
|
|
18
|
+
return (r, i) => {
|
|
19
|
+
let a = t?.[r];
|
|
20
|
+
if (!a) return i;
|
|
21
|
+
try {
|
|
22
|
+
return e(a, i);
|
|
23
|
+
} catch (e) {
|
|
24
|
+
throw new n(`validation failed for table "${r}"`, { cause: e });
|
|
25
|
+
}
|
|
27
26
|
};
|
|
28
27
|
}
|
|
29
|
-
function f(e, t,
|
|
30
|
-
let
|
|
31
|
-
if (!
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
function f(e, t, n, i, s, c = () => !0) {
|
|
29
|
+
let d = i ?? ((e, t) => t), f = (e) => {
|
|
30
|
+
if (!c()) throw new r("transaction context is no longer active");
|
|
31
|
+
if (s && !s.has(e)) throw new r(`table "${e}" is not part of this batch scope`);
|
|
32
|
+
}, p = {
|
|
34
33
|
async clear(e) {
|
|
35
|
-
f(e);
|
|
36
|
-
let n = await t.count(e);
|
|
37
|
-
await t.clear(e), n > 0 && r(e);
|
|
34
|
+
f(e), await t.clear(e), n(e);
|
|
38
35
|
},
|
|
39
36
|
async count(e) {
|
|
40
|
-
return f(e), t.count(e);
|
|
37
|
+
return f(e), t.count ? t.count(e) : (await t.getAll(e)).length;
|
|
41
38
|
},
|
|
42
|
-
async delete(e,
|
|
39
|
+
async delete(e, r) {
|
|
43
40
|
f(e);
|
|
44
|
-
let i = await t.delete(e,
|
|
45
|
-
return i &&
|
|
41
|
+
let i = await t.delete(e, r);
|
|
42
|
+
return i && n(e), i;
|
|
46
43
|
},
|
|
47
|
-
async deleteMany(e,
|
|
48
|
-
f(e)
|
|
49
|
-
|
|
50
|
-
|
|
44
|
+
async deleteMany(e, r) {
|
|
45
|
+
if (f(e), !t.deleteMany) {
|
|
46
|
+
let i = (await Promise.all(r.map((n) => t.delete(e, n)))).filter(Boolean).length;
|
|
47
|
+
return i > 0 && n(e), i;
|
|
48
|
+
}
|
|
49
|
+
let i = await t.deleteMany(e, r);
|
|
50
|
+
return i > 0 && n(e), i;
|
|
51
51
|
},
|
|
52
52
|
async get(e, n) {
|
|
53
53
|
return f(e), t.get(e, n);
|
|
@@ -56,144 +56,228 @@ function f(e, t, r, i, a) {
|
|
|
56
56
|
return f(e), t.getAll(e);
|
|
57
57
|
},
|
|
58
58
|
async getMany(e, n) {
|
|
59
|
-
return f(e),
|
|
59
|
+
return f(e), t.getMany ? t.getMany(e, n) : Promise.all(n.map((n) => t.get(e, n)));
|
|
60
60
|
},
|
|
61
61
|
async has(e, n) {
|
|
62
|
-
return f(e), t.has(e, n);
|
|
62
|
+
return f(e), t.has ? t.has(e, n) : await t.get(e, n) !== void 0;
|
|
63
63
|
},
|
|
64
64
|
async isEmpty(e) {
|
|
65
|
-
return
|
|
66
|
-
},
|
|
67
|
-
async keys(n, r) {
|
|
68
|
-
if (f(n), r) {
|
|
69
|
-
let i = await t.getAll(n), a = e[n].key;
|
|
70
|
-
return i.filter(r).map((e) => e[a]);
|
|
71
|
-
}
|
|
72
|
-
if (t.getAllKeys) return t.getAllKeys(n);
|
|
73
|
-
let i = await t.getAll(n), a = e[n].key;
|
|
74
|
-
return i.map((e) => e[a]);
|
|
75
|
-
},
|
|
76
|
-
async put(n, i, a) {
|
|
77
|
-
f(n), await t.put(n, s(n, i), c(e, n, a)), r(n);
|
|
65
|
+
return await p.count(e) === 0;
|
|
78
66
|
},
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
67
|
+
iterate(e) {
|
|
68
|
+
return f(e), t.iterate ? t.iterate(e) : (async function* () {
|
|
69
|
+
let n = await t.getAll(e);
|
|
70
|
+
for (let e of n) yield e;
|
|
71
|
+
})();
|
|
83
72
|
},
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
|
|
73
|
+
async keys(n, r) {
|
|
74
|
+
if (f(n), !r && t.getAllKeys) return t.getAllKeys(n);
|
|
75
|
+
let i = await t.getAll(n), a = r ? i.filter(r) : i, o = e[n].key;
|
|
76
|
+
return a.map((e) => e[o]);
|
|
77
|
+
},
|
|
78
|
+
async put(r, i, a) {
|
|
79
|
+
f(r);
|
|
80
|
+
let o = d(r, i);
|
|
81
|
+
return await t.put(r, o, l(e, r, a)), n(r), o;
|
|
82
|
+
},
|
|
83
|
+
async putAll(r, i, a) {
|
|
84
|
+
if (f(r), i.length === 0) return;
|
|
85
|
+
let o = i.map((e) => d(r, e));
|
|
86
|
+
await t.putAll(r, o, l(e, r, a)), n(r);
|
|
87
|
+
},
|
|
88
|
+
query(t) {
|
|
89
|
+
return f(t), o({
|
|
90
|
+
deleteMany: async (n) => {
|
|
91
|
+
let r = n.map((n) => a(e, t, n));
|
|
92
|
+
return p.deleteMany(t, r);
|
|
93
|
+
},
|
|
94
|
+
source: () => p.getAll(t)
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
async update(t, n, r, i) {
|
|
98
|
+
let a = await p.get(t, n);
|
|
99
|
+
if (a === void 0) return;
|
|
100
|
+
let o = {
|
|
101
|
+
...a,
|
|
102
|
+
...r
|
|
94
103
|
};
|
|
95
|
-
return
|
|
104
|
+
return u(e, t, n, o, "update"), p.put(t, o, i);
|
|
96
105
|
},
|
|
97
|
-
async upsert(
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
return l(e, n, i, u, "upsert: fn()"), await t.put(n, s(n, u), c(e, n, o)), r(n), u;
|
|
106
|
+
async upsert(t, n, r, i) {
|
|
107
|
+
let a = r(await p.get(t, n));
|
|
108
|
+
return u(e, t, n, a, "upsert: update()"), p.put(t, a, i);
|
|
101
109
|
}
|
|
102
110
|
};
|
|
111
|
+
return p;
|
|
103
112
|
}
|
|
104
|
-
function p(n, r
|
|
105
|
-
let {
|
|
106
|
-
c.notify(e),
|
|
107
|
-
},
|
|
113
|
+
function p(e, n, r) {
|
|
114
|
+
let { codecs: s } = r ?? {}, c = i((e) => n.getAll(e)), f = (e) => {
|
|
115
|
+
c.notify(e), r?.onMutation?.(e);
|
|
116
|
+
}, p = (e) => {
|
|
108
117
|
c.notify(e);
|
|
109
|
-
},
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
return r.parse(n);
|
|
114
|
-
} catch (n) {
|
|
115
|
-
throw new t(`validation failed for table "${e}"`, { cause: n });
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
a?.onTransactions?.({
|
|
119
|
-
notifyMutation: l,
|
|
120
|
-
validate: h
|
|
118
|
+
}, m = n.pruneAllExpired?.bind(n), h = r?.onCrossTabMessage?.(p) ?? void 0, g = d(s);
|
|
119
|
+
r?.onTransactions?.({
|
|
120
|
+
notifyMutation: f,
|
|
121
|
+
validate: g
|
|
121
122
|
});
|
|
122
|
-
let
|
|
123
|
-
if (v) throw new
|
|
123
|
+
let _ = new AbortController(), v = !1, y = () => {
|
|
124
|
+
if (v) throw new t();
|
|
124
125
|
}, b = {
|
|
125
126
|
async clear(e) {
|
|
126
|
-
y(), await
|
|
127
|
+
y(), await n.clear(e), f(e);
|
|
127
128
|
},
|
|
128
129
|
async count(e) {
|
|
129
|
-
return y(),
|
|
130
|
+
return y(), n.count ? n.count(e) : (await n.getAll(e)).length;
|
|
130
131
|
},
|
|
131
132
|
async delete(e, t) {
|
|
132
|
-
|
|
133
|
+
y();
|
|
134
|
+
let r = await n.delete(e, t);
|
|
135
|
+
return r && f(e), r;
|
|
133
136
|
},
|
|
134
137
|
async deleteMany(e, t) {
|
|
135
|
-
|
|
138
|
+
y();
|
|
139
|
+
let r = n.deleteMany ? await n.deleteMany(e, t) : (await Promise.all(t.map((t) => n.delete(e, t)))).filter(Boolean).length;
|
|
140
|
+
return r > 0 && f(e), r;
|
|
136
141
|
},
|
|
137
142
|
get disposalSignal() {
|
|
138
143
|
return _.signal;
|
|
139
144
|
},
|
|
140
145
|
async dispose() {
|
|
141
|
-
v || (v = !0, _.abort(),
|
|
146
|
+
v || (v = !0, _.abort(), h?.(), c.dispose(), await n.dispose?.());
|
|
142
147
|
},
|
|
143
148
|
get disposed() {
|
|
144
149
|
return v;
|
|
145
150
|
},
|
|
146
151
|
async get(e, t) {
|
|
147
|
-
return y(),
|
|
152
|
+
return y(), n.get(e, t);
|
|
148
153
|
},
|
|
149
154
|
async getAll(e) {
|
|
150
|
-
return y(),
|
|
155
|
+
return y(), n.getAll(e);
|
|
151
156
|
},
|
|
152
157
|
async getMany(e, t) {
|
|
153
|
-
return y(),
|
|
158
|
+
return y(), n.getMany ? n.getMany(e, t) : Promise.all(t.map((t) => n.get(e, t)));
|
|
154
159
|
},
|
|
155
160
|
async has(e, t) {
|
|
156
|
-
return y(),
|
|
161
|
+
return y(), n.has ? n.has(e, t) : await n.get(e, t) !== void 0;
|
|
157
162
|
},
|
|
158
163
|
async isEmpty(e) {
|
|
159
|
-
return
|
|
164
|
+
return await b.count(e) === 0;
|
|
160
165
|
},
|
|
161
|
-
async keys(
|
|
162
|
-
|
|
166
|
+
async keys(t, r) {
|
|
167
|
+
if (y(), !r && n.getAllKeys) return n.getAllKeys(t);
|
|
168
|
+
let i = await n.getAll(t), a = r ? i.filter(r) : i, o = e[t].key;
|
|
169
|
+
return a.map((e) => e[o]);
|
|
163
170
|
},
|
|
164
171
|
observe(e, t, n) {
|
|
165
172
|
return y(), c.observe(e, t, n);
|
|
166
173
|
},
|
|
167
174
|
async pruneExpired() {
|
|
168
|
-
if (y(),
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
if (y(), m) {
|
|
176
|
+
let e = await m();
|
|
177
|
+
for (let [t, n] of Object.entries(e)) n > 0 && f(t);
|
|
178
|
+
return e;
|
|
179
|
+
}
|
|
180
|
+
let t = Object.keys(e), r = await Promise.all(t.map(async (e) => [e, await n.pruneExpiredInTable(e)]));
|
|
181
|
+
for (let [e, t] of r) t > 0 && f(e);
|
|
182
|
+
return Object.fromEntries(r);
|
|
183
|
+
},
|
|
184
|
+
async put(t, r, i) {
|
|
185
|
+
y();
|
|
186
|
+
let a = g(t, r);
|
|
187
|
+
return await n.put(t, a, l(e, t, i)), f(t), a;
|
|
188
|
+
},
|
|
189
|
+
async putAll(t, r, i) {
|
|
190
|
+
if (y(), r.length === 0) return;
|
|
191
|
+
let a = r.map((e) => g(t, e));
|
|
192
|
+
await n.putAll(t, a, l(e, t, i)), f(t);
|
|
193
|
+
},
|
|
194
|
+
query(t) {
|
|
195
|
+
return y(), o({
|
|
196
|
+
deleteMany: async (n) => {
|
|
197
|
+
let r = n.map((n) => a(e, t, n));
|
|
198
|
+
return b.deleteMany(t, r);
|
|
199
|
+
},
|
|
200
|
+
source: () => b.getAll(t)
|
|
201
|
+
});
|
|
202
|
+
},
|
|
203
|
+
async update(t, n, r, i) {
|
|
204
|
+
let a = await b.get(t, n);
|
|
205
|
+
if (a === void 0) return;
|
|
206
|
+
let o = {
|
|
207
|
+
...a,
|
|
208
|
+
...r
|
|
209
|
+
};
|
|
210
|
+
return u(e, t, n, o, "update"), b.put(t, o, i);
|
|
177
211
|
},
|
|
178
|
-
|
|
179
|
-
|
|
212
|
+
async upsert(t, n, r, i) {
|
|
213
|
+
let a = r(await b.get(t, n));
|
|
214
|
+
return u(e, t, n, a, "upsert: apply()"), b.put(t, a, i);
|
|
180
215
|
},
|
|
181
216
|
async [Symbol.asyncDispose]() {
|
|
182
217
|
await b.dispose();
|
|
183
|
-
},
|
|
184
|
-
async update(e, t, n, r) {
|
|
185
|
-
return y(), g.update(e, t, n, r);
|
|
186
|
-
},
|
|
187
|
-
async upsert(e, t, n, r) {
|
|
188
|
-
return y(), g.upsert(e, t, n, r);
|
|
189
218
|
}
|
|
190
219
|
};
|
|
191
220
|
return b;
|
|
192
221
|
}
|
|
193
|
-
function m(e,
|
|
194
|
-
|
|
222
|
+
function m(e, n, r) {
|
|
223
|
+
let i = p(e, n, r);
|
|
224
|
+
return Object.assign(i, { iterate(e) {
|
|
225
|
+
if (i.disposed) throw new t();
|
|
226
|
+
return n.iterate ? n.iterate(e) : (async function* () {
|
|
227
|
+
for (let t of await i.getAll(e)) yield t;
|
|
228
|
+
})();
|
|
229
|
+
} });
|
|
230
|
+
}
|
|
231
|
+
function h(e, n, r) {
|
|
232
|
+
let i = (r, i) => e.disposed ? Promise.reject(new t()) : n(r, i);
|
|
233
|
+
return Object.assign(e, {
|
|
234
|
+
batch: i,
|
|
235
|
+
deleteMany(e, t) {
|
|
236
|
+
return i([e], (n) => n.deleteMany(e, t));
|
|
237
|
+
},
|
|
238
|
+
query(n) {
|
|
239
|
+
if (e.disposed) throw new t();
|
|
240
|
+
return o({
|
|
241
|
+
deleteMany: async (e) => {
|
|
242
|
+
let t = e.map((e) => a(r, n, e));
|
|
243
|
+
return i([n], (e) => e.deleteMany(n, t));
|
|
244
|
+
},
|
|
245
|
+
source: () => e.getAll(n)
|
|
246
|
+
});
|
|
247
|
+
},
|
|
248
|
+
update(e, t, n, r) {
|
|
249
|
+
return i([e], (i) => i.update(e, t, n, r));
|
|
250
|
+
},
|
|
251
|
+
upsert(e, t, n, r) {
|
|
252
|
+
return i([e], (i) => i.upsert(e, t, n, r));
|
|
253
|
+
}
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
async function g(e, t, n) {
|
|
257
|
+
return e.has(t, n);
|
|
258
|
+
}
|
|
259
|
+
async function _(e, t) {
|
|
260
|
+
return e.count(t);
|
|
261
|
+
}
|
|
262
|
+
async function v(e, t) {
|
|
263
|
+
return e.isEmpty(t);
|
|
264
|
+
}
|
|
265
|
+
async function y(e, t, n) {
|
|
266
|
+
return e.getMany(t, n);
|
|
267
|
+
}
|
|
268
|
+
async function b(e, t, n) {
|
|
269
|
+
return e.keys(t, n);
|
|
270
|
+
}
|
|
271
|
+
async function x(e, t, n) {
|
|
272
|
+
return e.deleteMany(t, n);
|
|
273
|
+
}
|
|
274
|
+
async function S(e, t, n, r, i) {
|
|
275
|
+
return e.update(t, n, r, i);
|
|
276
|
+
}
|
|
277
|
+
async function C(e, t, n, r, i) {
|
|
278
|
+
return e.upsert(t, n, r, i);
|
|
195
279
|
}
|
|
196
280
|
//#endregion
|
|
197
|
-
export {
|
|
281
|
+
export { c as assertBatchTables, m as buildDocumentStore, p as buildKeyValueStore, f as buildTxContext, _ as count, x as deleteMany, y as getMany, g as has, v as isEmpty, b as keys, d as makeValidator, S as update, C as upsert, h as withBatch };
|
|
198
282
|
|
|
199
283
|
//# sourceMappingURL=adapter-core.js.map
|
package/dist/adapter-core.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-core.js","names":[],"sources":["../src/adapter-core.ts"],"sourcesContent":["import { VaultDisposedError, VaultError, VaultScopeError } from './errors';\nimport { createObserverHub, getRecordKey } from './internal';\nimport { createQueryBuilder, type QueryContext } from './query';\nimport { assertPositiveFinite } from './ttl';\nimport type {\n AnySchema,\n BaseAdapterOptions,\n KeyOf,\n RecordOf,\n TransactionalVaultStore,\n TransactionContext,\n VaultStore,\n} from './types';\n\n/* -------------------- Internal backend protocol -------------------- */\n\n/** @internal Full backend protocol implemented by each adapter. A single flat interface — no StorageCore/StorageBackend split. */\nexport type StorageBackend<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n clear<T extends K>(table: T): Promise<void>;\n /** Returns live (non-expired) record count for the table. */\n count<T extends K>(table: T): Promise<number>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n deleteMany<T extends K>(table: T, keys: KeyOf<S, T>[]): Promise<number>;\n dispose?(): Promise<void>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n /**\n * Optional: fetch all live primary keys without materialising full records.\n * When present, `keys()` uses this instead of `getAll()` + key extraction.\n * For tables with TTL, implementations may still fall back to `getAll()` to\n * filter expired keys accurately.\n */\n getAllKeys?<T extends K>(table: T): Promise<KeyOf<S, T>[]>;\n /**\n * Optional: fetch multiple records by key in a single operation. Preserves key order; missing keys yield\n * `undefined`. Falls back to N individual `get` calls when absent.\n */\n getMany?<T extends K>(table: T, keys: KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n /**\n * Optional: prune all expired records across all tables in a single atomic operation.\n * When present, `pruneExpired()` delegates here instead of calling `pruneExpiredInTable` N times.\n */\n pruneAllExpired?(): Promise<Record<string, number>>;\n pruneExpiredInTable<T extends K>(table: T): Promise<number>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<void>;\n putAll<T extends K>(table: T, values: RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** @internal */\nexport type BatchDeps<S extends AnySchema> = {\n notifyMutation: (table: keyof S & string) => void;\n validate: <K extends keyof S & string>(table: K, value: RecordOf<S, K>) => RecordOf<S, K>;\n};\n\n/** @internal */\nexport type BatchImpl<S extends AnySchema> = <K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n) => Promise<R>;\n\n/* -------------------- Helpers -------------------- */\n\nexport function assertBatchTables(tables: readonly string[]): void {\n if (tables.length === 0) throw new VaultError('batch: declare at least one table');\n}\n\nfunction resolveTtl<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n ttl?: number,\n): number | undefined {\n if (ttl !== undefined) assertPositiveFinite(ttl, 'put/putAll');\n\n return ttl ?? schema[table].defaultTtl;\n}\n\nfunction verifyKey<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n expected: KeyOf<S, K>,\n value: RecordOf<S, K>,\n op: string,\n): void {\n const actual = getRecordKey(schema, table, value);\n\n if (actual !== expected) {\n throw new VaultError(\n `${op}: key field \"${schema[table].key}\" must be \"${String(expected)}\" but got \"${String(actual)}\" in table \"${table}\"`,\n );\n }\n}\n\nfunction getManyWithFallback<S extends AnySchema, K extends keyof S & string>(\n core: Pick<StorageBackend<S, K>, 'get' | 'getMany'>,\n table: K,\n keys: KeyOf<S, K>[],\n): Promise<Array<RecordOf<S, K> | undefined>> {\n if (core.getMany) return core.getMany(table, keys);\n\n return Promise.all(keys.map((k) => core.get(table, k)));\n}\n\nfunction buildQueryCtx<S extends AnySchema, K extends keyof S & string>(\n table: K,\n core: Pick<StorageBackend<S, K>, 'deleteMany' | 'getAll'>,\n schema: S,\n onMutate: (t: K) => void,\n): QueryContext<RecordOf<S, K>> {\n const deleteManyFn = async (records: RecordOf<S, K>[]): Promise<number> => {\n if (records.length === 0) return 0;\n\n const keys = records.map((r) => getRecordKey(schema, table, r));\n const deleted = await core.deleteMany(table, keys);\n\n if (deleted > 0) onMutate(table);\n\n return deleted;\n };\n\n return {\n deleteMany: deleteManyFn,\n source: () => core.getAll(table),\n };\n}\n\n/* -------------------- buildTxContext -------------------- */\n\nexport function buildTxContext<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n core: StorageBackend<S, K>,\n onMutate: (table: K) => void,\n validate?: <T extends K>(table: T, value: RecordOf<S, T>) => RecordOf<S, T>,\n scope?: ReadonlySet<string>,\n): TransactionContext<S, K> {\n const applyValidation = validate ?? ((_: K, v: RecordOf<S, K>) => v);\n\n const checkScope = scope\n ? (t: K): void => {\n if (!scope.has(t)) {\n throw new VaultScopeError(`table \"${t}\" is not part of this batch scope`);\n }\n }\n : (_t: K): void => {};\n\n return {\n async clear(table) {\n checkScope(table);\n\n const live = await core.count(table);\n\n await core.clear(table);\n\n if (live > 0) onMutate(table);\n },\n async count(table) {\n checkScope(table);\n\n return core.count(table);\n },\n async delete(table, key) {\n checkScope(table);\n\n const deleted = await core.delete(table, key);\n\n if (deleted) onMutate(table);\n\n return deleted;\n },\n async deleteMany(table, keys) {\n checkScope(table);\n\n const deleted = await core.deleteMany(table, keys);\n\n if (deleted > 0) onMutate(table);\n\n return deleted;\n },\n async get(table, key) {\n checkScope(table);\n\n return core.get(table, key);\n },\n async getAll(table) {\n checkScope(table);\n\n return core.getAll(table);\n },\n async getMany(table, keys) {\n checkScope(table);\n\n return getManyWithFallback(core, table, keys);\n },\n async has(table, key) {\n checkScope(table);\n\n return core.has(table, key);\n },\n async isEmpty(table) {\n checkScope(table);\n\n return (await core.count(table)) === 0;\n },\n async keys(table, filter) {\n checkScope(table);\n\n if (filter) {\n const records = await core.getAll(table);\n const keyField = schema[table].key;\n\n return records.filter(filter).map((r) => (r as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n }\n\n // R1: prefer native getAllKeys when the backend supports it (e.g. IDB store.getAllKeys).\n if (core.getAllKeys) {\n return core.getAllKeys(table);\n }\n\n const records = await core.getAll(table);\n const keyField = schema[table].key;\n\n return records.map((r) => (r as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n },\n async put(table, value, ttl) {\n checkScope(table);\n\n await core.put(table, applyValidation(table, value), resolveTtl(schema, table, ttl));\n onMutate(table);\n },\n async putAll(table, values, ttl) {\n checkScope(table);\n\n if (values.length === 0) return;\n\n const toWrite = values.map((v) => applyValidation(table, v));\n\n await core.putAll(table, toWrite, resolveTtl(schema, table, ttl));\n onMutate(table);\n },\n query(table) {\n checkScope(table);\n\n return createQueryBuilder(buildQueryCtx(table, core, schema, onMutate));\n },\n async update(table, key, changes, ttl) {\n checkScope(table);\n\n const current = await core.get(table, key);\n\n if (!current) return undefined;\n\n const merged = { ...current, ...changes } as RecordOf<S, typeof table>;\n\n verifyKey(schema, table, key, merged, 'update');\n await core.put(table, applyValidation(table, merged), resolveTtl(schema, table, ttl));\n onMutate(table);\n\n return merged;\n },\n async upsert(table, key, fn, ttl) {\n checkScope(table);\n\n const existing = await core.get(table, key);\n const value = fn(existing);\n\n verifyKey(schema, table, key, value, 'upsert: fn()');\n await core.put(table, applyValidation(table, value), resolveTtl(schema, table, ttl));\n onMutate(table);\n\n return value;\n },\n };\n}\n\n/* -------------------- buildAdapterOps -------------------- */\n\n/** Builds the portable surface first; IndexedDB opts into transactions at its factory boundary. */\nexport function buildAdapterOps<S extends AnySchema>(\n schema: S,\n core: StorageBackend<S>,\n options?: BaseAdapterOptions<S> & {\n onCrossTabMessage?: (notify: (table: keyof S & string) => void) => (() => void) | undefined;\n onMutation?: (table: keyof S & string) => void;\n onTransactions?: (deps: BatchDeps<S>) => void;\n },\n): VaultStore<S> {\n const { validators } = options ?? {};\n\n const observers = createObserverHub<S>((table) => core.getAll(table));\n\n const notifyMutation = (table: keyof S & string): void => {\n observers.notify(table);\n options?.onMutation?.(table);\n };\n\n // Cross-tab notifications must NOT call onMutation (which would re-publish to BroadcastChannel,\n // creating an infinite loop). They only notify local observers.\n const notifyExternal = (table: keyof S & string): void => {\n observers.notify(table);\n };\n\n // R6: Resolve optional backend capabilities once at construction — no per-call checks.\n const pruneAll = core.pruneAllExpired?.bind(core);\n\n const disconnectExternal = options?.onCrossTabMessage?.(notifyExternal) ?? undefined;\n\n const validate = <K extends keyof S & string>(table: K, value: RecordOf<S, K>): RecordOf<S, K> => {\n const validator = validators?.[table];\n\n if (!validator) return value;\n\n try {\n return validator.parse(value) as RecordOf<S, K>;\n } catch (err) {\n throw new VaultError(`validation failed for table \"${table}\"`, { cause: err });\n }\n };\n\n options?.onTransactions?.({ notifyMutation, validate });\n\n const txCtx = buildTxContext<S, keyof S & string>(schema, core, notifyMutation, validate);\n\n const disposeController = new AbortController();\n let disposed = false;\n\n const checkDisposed = (): void => {\n if (disposed) throw new VaultDisposedError();\n };\n\n const adapter: VaultStore<S> = {\n async clear(table) {\n checkDisposed();\n await txCtx.clear(table);\n },\n\n async count(table) {\n checkDisposed();\n\n return core.count(table);\n },\n\n async delete(table, key) {\n checkDisposed();\n\n return txCtx.delete(table, key);\n },\n\n async deleteMany(table, keys) {\n checkDisposed();\n\n return txCtx.deleteMany(table, keys);\n },\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n async dispose() {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n disconnectExternal?.();\n observers.dispose();\n await core.dispose?.();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n async get(table, key) {\n checkDisposed();\n\n return txCtx.get(table, key);\n },\n\n async getAll(table) {\n checkDisposed();\n\n return txCtx.getAll(table);\n },\n\n async getMany(table, keys) {\n checkDisposed();\n\n return txCtx.getMany(table, keys);\n },\n\n async has(table, key) {\n checkDisposed();\n\n return txCtx.has(table, key);\n },\n\n async isEmpty(table) {\n checkDisposed();\n\n return (await core.count(table)) === 0;\n },\n\n async keys(table, filter) {\n checkDisposed();\n\n return txCtx.keys(table, filter);\n },\n\n observe(table, listener, opts) {\n checkDisposed();\n\n return observers.observe(table, listener, opts);\n },\n\n async pruneExpired() {\n checkDisposed();\n\n if (pruneAll) {\n const result = await pruneAll();\n\n return result as { [K in keyof S & string]: number };\n }\n\n const tableNames = Object.keys(schema) as Array<keyof S & string>;\n const pairs = await Promise.all(\n tableNames.map(async (name) => {\n const pruned = await core.pruneExpiredInTable(name);\n\n return [name, pruned] as const;\n }),\n );\n\n return Object.fromEntries(pairs) as { [K in keyof S & string]: number };\n },\n\n async put(table, value, ttl) {\n checkDisposed();\n await txCtx.put(table, value, ttl);\n },\n\n async putAll(table, values, ttl) {\n checkDisposed();\n await txCtx.putAll(table, values, ttl);\n },\n\n query(table) {\n checkDisposed();\n\n return createQueryBuilder(buildQueryCtx(table, core, schema, notifyMutation));\n },\n\n async [Symbol.asyncDispose]() {\n await adapter.dispose();\n },\n\n async update(table, key, changes, ttl) {\n checkDisposed();\n\n return txCtx.update(table, key, changes, ttl);\n },\n\n async upsert(table, key, fn, ttl) {\n checkDisposed();\n\n return txCtx.upsert(table, key, fn, ttl);\n },\n };\n\n return adapter;\n}\n\n/** IndexedDB is the only backend that can bind this callback to one native transaction. */\nexport function withIndexedDbTransactions<S extends AnySchema>(\n store: VaultStore<S>,\n batch: BatchImpl<S>,\n): TransactionalVaultStore<S> {\n return Object.assign(store, { batch }) as TransactionalVaultStore<S>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"adapter-core.js","names":[],"sources":["../src/adapter-core.ts"],"sourcesContent":["import { validateRecord } from './codec';\nimport { VaultDisposedError, VaultError, VaultScopeError } from './errors';\nimport { createObserverHub, getRecordKey } from './internal';\nimport { createQueryBuilder } from './query';\nimport { assertPositiveFinite } from './ttl';\nimport type {\n AnySchema,\n DocumentVaultStore,\n DurableStoreOptions,\n KeyOf,\n KeyValueVaultStore,\n MemoryStoreOptions,\n RecordOf,\n TableCodecs,\n TransactionContext,\n} from './types';\n\n/* -------------------- Internal backend protocol -------------------- */\n\n/** @internal Full backend protocol implemented by each adapter. */\nexport type StorageBackend<S extends AnySchema, K extends keyof S & string = keyof S & string> = {\n clear<T extends K>(table: T): Promise<void>;\n count?<T extends K>(table: T): Promise<number>;\n delete<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n deleteMany?<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<number>;\n dispose?(): Promise<void>;\n get<T extends K>(table: T, key: KeyOf<S, T>): Promise<RecordOf<S, T> | undefined>;\n getAll<T extends K>(table: T): Promise<RecordOf<S, T>[]>;\n getAllKeys?<T extends K>(table: T): Promise<KeyOf<S, T>[]>;\n getMany?<T extends K>(table: T, keys: readonly KeyOf<S, T>[]): Promise<Array<RecordOf<S, T> | undefined>>;\n has?<T extends K>(table: T, key: KeyOf<S, T>): Promise<boolean>;\n /**\n * Optional: lazy iteration over live records. Document stores implement this natively\n * (IDB cursor, SQLite keyset pagination). Key-value stores fall back to getAll().\n */\n iterate?<T extends K>(table: T): AsyncIterable<RecordOf<S, T>>;\n /**\n * Optional: prune all expired records across all tables in a single atomic operation.\n * When present, `pruneExpired()` delegates here instead of calling `pruneExpiredInTable` N times.\n */\n pruneAllExpired?(): Promise<Record<string, number>>;\n pruneExpiredInTable<T extends K>(table: T): Promise<number>;\n put<T extends K>(table: T, value: RecordOf<S, T>, ttl?: number): Promise<void>;\n putAll<T extends K>(table: T, values: readonly RecordOf<S, T>[], ttl?: number): Promise<void>;\n};\n\n/** @internal */\nexport type BatchDeps<S extends AnySchema> = {\n notifyMutation: (table: keyof S & string) => void;\n validate: <K extends keyof S & string>(table: K, value: RecordOf<S, K>) => RecordOf<S, K>;\n};\n\n/** @internal */\nexport type BatchImpl<S extends AnySchema> = <K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n) => Promise<R>;\n\n/* -------------------- Helpers -------------------- */\n\nexport function assertBatchTables(tables: readonly string[]): void {\n if (tables.length === 0) throw new VaultError('batch: declare at least one table');\n}\n\nfunction resolveTtl<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n ttl?: number,\n): number | undefined {\n if (ttl !== undefined) assertPositiveFinite(ttl, 'put/putAll');\n\n return ttl ?? schema[table].defaultTtl;\n}\n\nfunction verifyKey<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n table: K,\n expected: KeyOf<S, K>,\n value: RecordOf<S, K>,\n op: string,\n): void {\n const actual = getRecordKey(schema, table, value);\n\n if (actual !== expected) {\n throw new VaultError(\n `${op}: key field \"${schema[table].key}\" must be \"${String(expected)}\" but got \"${String(actual)}\" in table \"${table}\"`,\n );\n }\n}\n\n/* -------------------- Codec helpers -------------------- */\n\nexport function makeValidator<S extends AnySchema>(\n codecs: TableCodecs<S> | undefined,\n): <K extends keyof S & string>(table: K, value: RecordOf<S, K>) => RecordOf<S, K> {\n return <K extends keyof S & string>(table: K, value: RecordOf<S, K>): RecordOf<S, K> => {\n const codec = codecs?.[table];\n\n if (!codec) return value;\n\n try {\n return validateRecord(codec, value);\n } catch (err) {\n throw new VaultError(`validation failed for table \"${table}\"`, { cause: err });\n }\n };\n}\n\n/* -------------------- buildTxContext -------------------- */\n\nexport function buildTxContext<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n core: StorageBackend<S, K>,\n onMutate: (table: K) => void,\n validate?: <T extends K>(table: T, value: RecordOf<S, T>) => RecordOf<S, T>,\n scope?: ReadonlySet<string>,\n isActive: () => boolean = () => true,\n): TransactionContext<S, K> {\n const applyValidation = validate ?? ((_: K, v: RecordOf<S, K>) => v);\n\n const checkScope = (table: K): void => {\n if (!isActive()) throw new VaultScopeError('transaction context is no longer active');\n if (scope && !scope.has(table)) throw new VaultScopeError(`table \"${table}\" is not part of this batch scope`);\n };\n\n const context: TransactionContext<S, K> = {\n async clear(table) {\n checkScope(table);\n await core.clear(table);\n onMutate(table);\n },\n async count(table) {\n checkScope(table);\n return core.count ? core.count(table) : (await core.getAll(table)).length;\n },\n async delete(table, key) {\n checkScope(table);\n\n const deleted = await core.delete(table, key);\n\n if (deleted) onMutate(table);\n\n return deleted;\n },\n async deleteMany(table, keys) {\n checkScope(table);\n if (!core.deleteMany) {\n const results = await Promise.all(keys.map((key) => core.delete(table, key)));\n const deleted = results.filter(Boolean).length;\n if (deleted > 0) onMutate(table);\n return deleted;\n }\n const deleted = await core.deleteMany(table, keys);\n if (deleted > 0) onMutate(table);\n return deleted;\n },\n async get(table, key) {\n checkScope(table);\n\n return core.get(table, key);\n },\n async getAll(table) {\n checkScope(table);\n\n return core.getAll(table);\n },\n async getMany(table, keys) {\n checkScope(table);\n return core.getMany ? core.getMany(table, keys) : Promise.all(keys.map((key) => core.get(table, key)));\n },\n async has(table, key) {\n checkScope(table);\n return core.has ? core.has(table, key) : (await core.get(table, key)) !== undefined;\n },\n async isEmpty(table) {\n return (await context.count(table)) === 0;\n },\n iterate(table) {\n checkScope(table);\n\n if (core.iterate) return core.iterate(table);\n\n // Fallback: iterate over getAll() materialized records.\n return (async function* (): AsyncIterable<RecordOf<S, typeof table>> {\n const records = await core.getAll(table);\n\n for (const record of records) yield record;\n })();\n },\n async keys(table, filter) {\n checkScope(table);\n if (!filter && core.getAllKeys) return core.getAllKeys(table);\n const records = await core.getAll(table);\n const selected = filter ? records.filter(filter) : records;\n const keyField = schema[table].key;\n return selected.map((record) => (record as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n },\n async put(table, value, ttl) {\n checkScope(table);\n const canonical = applyValidation(table, value);\n await core.put(table, canonical, resolveTtl(schema, table, ttl));\n onMutate(table);\n return canonical;\n },\n async putAll(table, values, ttl) {\n checkScope(table);\n\n if (values.length === 0) return;\n\n const toWrite = values.map((v) => applyValidation(table, v));\n\n await core.putAll(table, toWrite, resolveTtl(schema, table, ttl));\n onMutate(table);\n },\n query(table) {\n checkScope(table);\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return context.deleteMany(table, keys);\n },\n source: () => context.getAll(table),\n });\n },\n async update(table, key, changes, ttl) {\n const current = await context.get(table, key);\n if (current === undefined) return undefined;\n const merged = { ...current, ...changes } as RecordOf<S, typeof table>;\n verifyKey(schema, table, key, merged, 'update');\n return context.put(table, merged, ttl);\n },\n async upsert(table, key, update, ttl) {\n const value = update(await context.get(table, key));\n verifyKey(schema, table, key, value, 'upsert: update()');\n return context.put(table, value, ttl);\n },\n };\n\n return context;\n}\n\n/* -------------------- buildKeyValueStore -------------------- */\n\n/** Builds a KeyValueVaultStore from a backend and options. */\nexport function buildKeyValueStore<S extends AnySchema>(\n schema: S,\n core: StorageBackend<S>,\n options?: MemoryStoreOptions<S> & {\n onCrossTabMessage?: (notify: (table: keyof S & string) => void) => (() => void) | undefined;\n onMutation?: (table: keyof S & string) => void;\n onTransactions?: (deps: BatchDeps<S>) => void;\n },\n): KeyValueVaultStore<S> {\n const { codecs } = options ?? {};\n\n const observers = createObserverHub<S>((table) => core.getAll(table));\n\n const notifyMutation = (table: keyof S & string): void => {\n observers.notify(table);\n options?.onMutation?.(table);\n };\n\n // Cross-tab notifications must NOT call onMutation (which would re-publish to BroadcastChannel,\n // creating an infinite loop). They only notify local observers.\n const notifyExternal = (table: keyof S & string): void => {\n observers.notify(table);\n };\n\n const pruneAll = core.pruneAllExpired?.bind(core);\n\n const disconnectExternal = options?.onCrossTabMessage?.(notifyExternal) ?? undefined;\n\n const validate = makeValidator(codecs);\n\n options?.onTransactions?.({ notifyMutation, validate });\n\n const disposeController = new AbortController();\n let disposed = false;\n\n const checkDisposed = (): void => {\n if (disposed) throw new VaultDisposedError();\n };\n\n const adapter: KeyValueVaultStore<S> = {\n async clear(table) {\n checkDisposed();\n await core.clear(table);\n notifyMutation(table);\n },\n async count(table) {\n checkDisposed();\n return core.count ? core.count(table) : (await core.getAll(table)).length;\n },\n\n async delete(table, key) {\n checkDisposed();\n\n const deleted = await core.delete(table, key);\n\n if (deleted) notifyMutation(table);\n\n return deleted;\n },\n async deleteMany(table, keys) {\n checkDisposed();\n const deleted = core.deleteMany\n ? await core.deleteMany(table, keys)\n : (await Promise.all(keys.map((key) => core.delete(table, key)))).filter(Boolean).length;\n if (deleted > 0) notifyMutation(table);\n return deleted;\n },\n\n get disposalSignal(): AbortSignal {\n return disposeController.signal;\n },\n\n async dispose() {\n if (disposed) return;\n\n disposed = true;\n disposeController.abort();\n disconnectExternal?.();\n observers.dispose();\n await core.dispose?.();\n },\n\n get disposed(): boolean {\n return disposed;\n },\n\n async get(table, key) {\n checkDisposed();\n\n return core.get(table, key);\n },\n\n async getAll(table) {\n checkDisposed();\n\n return core.getAll(table);\n },\n async getMany(table, keys) {\n checkDisposed();\n return core.getMany ? core.getMany(table, keys) : Promise.all(keys.map((key) => core.get(table, key)));\n },\n async has(table, key) {\n checkDisposed();\n return core.has ? core.has(table, key) : (await core.get(table, key)) !== undefined;\n },\n async isEmpty(table) {\n return (await adapter.count(table)) === 0;\n },\n async keys(table, filter) {\n checkDisposed();\n if (!filter && core.getAllKeys) return core.getAllKeys(table);\n const records = await core.getAll(table);\n const selected = filter ? records.filter(filter) : records;\n const keyField = schema[table].key;\n return selected.map((record) => (record as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n },\n\n observe(table, listener, opts) {\n checkDisposed();\n\n return observers.observe(table, listener, opts);\n },\n\n async pruneExpired() {\n checkDisposed();\n\n if (pruneAll) {\n const result = await pruneAll();\n\n for (const [table, pruned] of Object.entries(result)) {\n if (pruned > 0) notifyMutation(table as keyof S & string);\n }\n\n return result as { [K in keyof S & string]: number };\n }\n\n const tableNames = Object.keys(schema) as Array<keyof S & string>;\n const pairs = await Promise.all(\n tableNames.map(async (name) => {\n const pruned = await core.pruneExpiredInTable(name);\n\n return [name, pruned] as const;\n }),\n );\n\n for (const [table, pruned] of pairs) {\n if (pruned > 0) notifyMutation(table);\n }\n\n return Object.fromEntries(pairs) as { [K in keyof S & string]: number };\n },\n\n async put(table, value, ttl) {\n checkDisposed();\n const canonical = validate(table, value);\n await core.put(table, canonical, resolveTtl(schema, table, ttl));\n notifyMutation(table);\n return canonical;\n },\n\n async putAll(table, values, ttl) {\n checkDisposed();\n\n if (values.length === 0) return;\n\n const toWrite = values.map((v) => validate(table, v));\n\n await core.putAll(table, toWrite, resolveTtl(schema, table, ttl));\n notifyMutation(table);\n },\n query(table) {\n checkDisposed();\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return adapter.deleteMany(table, keys);\n },\n source: () => adapter.getAll(table),\n });\n },\n async update(table, key, changes, ttl) {\n const current = await adapter.get(table, key);\n if (current === undefined) return undefined;\n const merged = { ...current, ...changes } as RecordOf<S, typeof table>;\n verifyKey(schema, table, key, merged, 'update');\n return adapter.put(table, merged, ttl);\n },\n async upsert(table, key, apply, ttl) {\n const value = apply(await adapter.get(table, key));\n verifyKey(schema, table, key, value, 'upsert: apply()');\n return adapter.put(table, value, ttl);\n },\n\n async [Symbol.asyncDispose]() {\n await adapter.dispose();\n },\n };\n\n return adapter;\n}\n\n/* -------------------- buildDocumentStore -------------------- */\n\n/** A document store before batch() is attached. */\nexport type DocumentVaultStoreWithoutBatch<S extends AnySchema> = Omit<DocumentVaultStore<S>, 'batch'>;\n\n/** Builds a DocumentVaultStore (without batch) from a backend, codecs, and options. */\nexport function buildDocumentStore<S extends AnySchema>(\n schema: S,\n core: StorageBackend<S>,\n options: DurableStoreOptions<S> & {\n onCrossTabMessage?: (notify: (table: keyof S & string) => void) => (() => void) | undefined;\n onMutation?: (table: keyof S & string) => void;\n onTransactions?: (deps: BatchDeps<S>) => void;\n },\n): DocumentVaultStoreWithoutBatch<S> {\n const store = buildKeyValueStore(schema, core, options);\n\n return Object.assign(store, {\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (store.disposed) throw new VaultDisposedError();\n if (core.iterate) return core.iterate(table);\n return (async function* (): AsyncIterable<RecordOf<S, K>> {\n for (const record of await store.getAll(table)) yield record;\n })();\n },\n });\n}\n\n/** Attaches a batch() implementation to a document store. */\nexport function withBatch<S extends AnySchema>(\n store: DocumentVaultStoreWithoutBatch<S>,\n batch: BatchImpl<S>,\n schema: S,\n): DocumentVaultStore<S> {\n const runBatch: BatchImpl<S> = (tables, fn) => {\n if (store.disposed) return Promise.reject(new VaultDisposedError());\n return batch(tables, fn);\n };\n\n return Object.assign(store, {\n batch: runBatch,\n deleteMany<K extends keyof S & string>(table: K, keys: readonly KeyOf<S, K>[]) {\n return runBatch([table], (tx) => tx.deleteMany(table, keys));\n },\n query<K extends keyof S & string>(table: K) {\n if (store.disposed) throw new VaultDisposedError();\n return createQueryBuilder({\n deleteMany: async (records) => {\n const keys = records.map((record) => getRecordKey(schema, table, record));\n return runBatch([table], (tx) => tx.deleteMany(table, keys));\n },\n source: () => store.getAll(table),\n });\n },\n update<K extends keyof S & string>(table: K, key: KeyOf<S, K>, changes: Partial<RecordOf<S, K>>, ttl?: number) {\n return runBatch([table], (tx) => tx.update(table, key, changes, ttl));\n },\n upsert<K extends keyof S & string>(\n table: K,\n key: KeyOf<S, K>,\n apply: (existing: RecordOf<S, K> | undefined) => RecordOf<S, K>,\n ttl?: number,\n ) {\n return runBatch([table], (tx) => tx.upsert(table, key, apply, ttl));\n },\n }) as DocumentVaultStore<S>;\n}\n\n/* -------------------- Derived convenience helpers -------------------- */\n\n/** Check whether a record exists for the given key. */\nexport async function has<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n): Promise<boolean> {\n return store.has(table, key);\n}\n\n/** Count live records in a table. */\nexport async function count<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n): Promise<number> {\n return store.count(table);\n}\n\n/** Check whether a table has no live records. */\nexport async function isEmpty<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n): Promise<boolean> {\n return store.isEmpty(table);\n}\n\n/** Fetch multiple records by key. Preserves key order; missing keys yield `undefined`. */\nexport async function getMany<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n keys: readonly KeyOf<S, K>[],\n): Promise<Array<RecordOf<S, K> | undefined>> {\n return store.getMany(table, keys);\n}\n\n/** Fetch all live primary keys for a table. */\nexport async function keys<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n filter?: (record: RecordOf<S, K>) => boolean,\n): Promise<KeyOf<S, K>[]> {\n return store.keys(table, filter);\n}\n\n/** Delete multiple records by key. Returns the count of records that were actually deleted. */\nexport async function deleteMany<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n keys: readonly KeyOf<S, K>[],\n): Promise<number> {\n return store.deleteMany(table, keys);\n}\n\n/** Partially update an existing record. Returns `undefined` when the key does not exist. */\nexport async function update<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n changes: Partial<RecordOf<S, K>>,\n ttl?: number,\n): Promise<RecordOf<S, K> | undefined> {\n return store.update(table, key, changes, ttl);\n}\n\n/** Read-modify-write: the callback receives the current record (or `undefined`) and returns the value to store. */\nexport async function upsert<S extends AnySchema, K extends keyof S & string>(\n store: KeyValueVaultStore<S>,\n table: K,\n key: KeyOf<S, K>,\n apply: (existing: RecordOf<S, K> | undefined) => RecordOf<S, K>,\n ttl?: number,\n): Promise<RecordOf<S, K>> {\n return store.upsert(table, key, apply, ttl);\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../
|
|
1
|
+
const e=require("../codec.cjs"),t=require("../errors.cjs"),n=require("../internal.cjs"),r=require("../ttl.cjs"),i=require("../adapter-core.cjs");function a(e){return({db:t,tx:n})=>{for(let r of e)switch(r.type){case`addIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)||e.createIndex(r.field,`value.${r.field}`);break}case`addTable`:t.objectStoreNames.contains(r.name)||t.createObjectStore(r.name);break;case`removeIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)&&e.deleteIndex(r.field);break}case`removeTable`:t.objectStoreNames.contains(r.name)&&t.deleteObjectStore(r.name)}}}function o(e){return new Promise((n,r)=>{e.onsuccess=()=>n(e.result),e.onerror=()=>r(e.error??new t.VaultError(`IndexedDB request failed`))})}function s(e,n,r){let i=r instanceof Error&&r.message?`: ${r.message}`:``;return new t.VaultError(`${n} on "${e}"${i}`,{cause:r})}function c(e,t,n){return new Promise((r,i)=>{let a,o;Promise.resolve().then(n).then(e=>{a=e}).catch(t=>{o=t;try{e.abort()}catch{}});let c=(e,n=`transaction failed`)=>{o instanceof Error?i(o):i(s(t,n,o??e))};e.oncomplete=()=>{if(o){c(void 0);return}r(a)},e.onerror=()=>i(s(t,`transaction error`,e.error)),e.onabort=()=>c(e.error,`transaction aborted`)})}async function l(e,t,n){let r=await o(e.getAll(n)),i=[];for(let e of r){let n=t(e);n!==void 0&&i.push(n)}return i}async function u(e,t,n){let r=await o(e.get(t));if(r!=null)return n(r)}async function d(e,t,n){let r=await u(e,t,n)!==void 0;return await o(e.delete(t)),r}async function f(e,t,n){return(await Promise.all(t.map(t=>d(e,t,n)))).filter(Boolean).length}function p(e){return new Promise((n,i)=>{let a=0,o=e.openCursor();o.onerror=()=>i(o.error??new t.VaultError(`IndexedDB cursor failed during prune`)),o.onsuccess=()=>{let e=o.result;if(!e){n(a);return}let t=r.parseStored(e.value);(!t||r.isExpired(t.expiresAt))&&(e.delete(),a+=1),e.continue()}})}function m(e,n){return{[Symbol.asyncIterator](){let r=e.openCursor(),i={type:`idle`},a=e=>{if(i.type===`waiting`){let{resolve:t}=i;i=e.done?{type:`done`}:{type:`idle`},t(e)}else i.type===`buffered`?i.results.push(e):i={results:[e],type:`buffered`}};return r.onerror=()=>{let e=r.error??new t.VaultError(`IndexedDB cursor iteration failed`);if(i.type===`waiting`){let{reject:t}=i;i={type:`done`},t(e)}else i={error:e,type:`error`}},r.onsuccess=()=>{if(i.type===`done`)return;let e=r.result;if(!e){a({done:!0,value:void 0});return}let t;try{t=n(e.value)}catch(e){if(i.type===`waiting`){let{reject:t}=i;i={type:`done`},t(e)}else i={error:e,type:`error`};return}e.continue(),t!==void 0&&a({done:!1,value:t})},{next(){if(i.type===`error`){let{error:e}=i;return i={type:`done`},Promise.reject(e)}if(i.type===`buffered`){let[e,...t]=i.results;return i=e.done?{type:`done`}:t.length>0?{results:t,type:`buffered`}:{type:`idle`},Promise.resolve(e)}return i.type===`done`?Promise.resolve({done:!0,value:void 0}):new Promise((e,t)=>{i={reject:t,resolve:e,type:`waiting`}})},return(e){return i.type===`waiting`&&i.resolve({done:!0,value:void 0}),i={type:`done`},Promise.resolve({done:!0,value:e})},throw(e){return i.type===`waiting`&&i.reject(e),i={type:`done`},Promise.reject(e)}}}}}function h(a){let{migrate:s,name:h,schema:g,codecs:_,version:v=1}=a;if(!_)throw new t.VaultError(`createIndexedDB: codecs are required for durable persistence`);if(!Number.isInteger(v)||v<1)throw new t.VaultError(`createIndexedDB: version must be a positive integer, got ${String(v)}`);let y=typeof BroadcastChannel<`u`?new BroadcastChannel(`vault:${h}`):void 0,b=null,x=null,S=!1,C=(e,t)=>{for(let[n,r]of Object.entries(g)){let i;i=e.objectStoreNames.contains(n)?t.objectStore(n):e.createObjectStore(n);let a=r.indexes??[];for(let e of a)i.indexNames.contains(e)||i.createIndex(e,`value.${e}`)}},w=async()=>(x||=new Promise((e,n)=>{let r=indexedDB.open(h,v);r.onupgradeneeded=e=>{let i=r.result,a=r.transaction;if(s)try{s({db:i,newVersion:e.newVersion??null,oldVersion:e.oldVersion,tx:a})}catch(e){try{a.abort()}catch{}n(new t.VaultMigrationError(`migration failed for "${h}"`,{cause:e}));return}C(i,a)},r.onsuccess=()=>{if(S){r.result.close(),e();return}let t=r.result;t.onversionchange=()=>{t.close(),b=null,x=null},b=t,e()},r.onerror=()=>{x=null,n(new t.VaultError(`failed to open "${h}"`,{cause:r.error}))}}),x),T=async(e,n,r)=>{if(S||(b||await w(),!b))throw new t.VaultDisposedError(`"${h}" is disposed`);let i=String(e),a=b.transaction(i,n);return c(a,`${h}/${i}`,()=>r(a.objectStore(i)))},E=async()=>{if(S||(b||await w(),!b))throw new t.VaultDisposedError(`"${h}" is disposed`);return b},D=e=>{y?.postMessage({table:String(e)})},O=(n,i)=>{let a=r.parseStored(i);if(a&&!r.isExpired(a.expiresAt))try{return e.decodeRecord(_[n],a.value)}catch(e){throw new t.VaultError(`validation failed for table "${String(n)}"`,{cause:e})}},k=(n,r,i)=>{let a=r,o=e.encodeRecord(_[n],a);for(let e of g[n].indexes??[]){let r=a[e];if(r!==void 0&&(typeof o!=`object`||!o||!Object.hasOwn(o,e)||!Object.is(o[e],r)))throw new t.VaultError(`codec output for table "${String(n)}" must preserve indexed field "${e}"`)}return i===void 0?{value:o}:{expiresAt:Date.now()+i,value:o}},A={clear:e=>T(e,`readwrite`,e=>o(e.clear()).then(()=>void 0)),delete:(e,t)=>T(e,`readwrite`,r=>d(r,n.encodeVaultKey(t),t=>O(e,t))),deleteMany:(e,t)=>T(e,`readwrite`,r=>f(r,t.map(n.encodeVaultKey),t=>O(e,t))),async dispose(){S=!0,y?.close(),x&&await x.catch(()=>{}),b?.close(),b=null,x=null},get:(e,t)=>T(e,`readonly`,r=>u(r,n.encodeVaultKey(t),t=>O(e,t))),getAll:e=>T(e,`readonly`,t=>l(t,t=>O(e,t))),getMany:(e,t)=>T(e,`readonly`,r=>{let i=t=>O(e,t);return Promise.all(t.map(e=>u(r,n.encodeVaultKey(e),i)))}),iterate:e=>{let n=async()=>{if(S||(b||await w(),!b||S))throw new t.VaultDisposedError(`"${h}" is disposed`);return m(b.transaction(String(e),`readonly`).objectStore(String(e)),t=>O(e,t))},r,i=()=>n().then(e=>(r=e[Symbol.asyncIterator](),r));return{[Symbol.asyncIterator](){return{next(){return r?r.next():i().then(e=>e.next())},return(e){return r?r.return?.(e)??Promise.resolve({done:!0,value:e}):Promise.resolve({done:!0,value:e})},throw(e){return r?r.throw?.(e)??Promise.reject(e):Promise.reject(e)}}}}},async pruneAllExpired(){let e=await E(),t=Object.keys(g),n=e.transaction(t,`readwrite`),r=await c(n,`${h}/pruneAll`,()=>Promise.all(t.map(async e=>[e,await p(n.objectStore(e))])));return Object.fromEntries(r)},pruneExpiredInTable:e=>T(e,`readwrite`,e=>p(e)),put(e,t,r){let i=n.encodeVaultKey(n.getRecordKey(g,e,t)),a=k(e,t,r);return T(e,`readwrite`,e=>o(e.put(a,i)).then(()=>void 0))},putAll(e,t,r){let i=t.map(t=>{let i=n.encodeVaultKey(n.getRecordKey(g,e,t));return{encoded:k(e,t,r),key:i}});return T(e,`readwrite`,e=>Promise.all(i.map(({encoded:t,key:n})=>o(e.put(t,n)))).then(()=>void 0))}},j=async(e,t,r,a)=>{i.assertBatchTables(e);let s=(await E()).transaction([...e],`readwrite`),_=new Set,v=e=>s.objectStore(e),y={clear:async e=>{await o(v(e).clear())},delete:(e,t)=>d(v(e),n.encodeVaultKey(t),t=>O(e,t)),deleteMany:(e,t)=>f(v(e),t.map(n.encodeVaultKey),t=>O(e,t)),get:(e,t)=>u(v(e),n.encodeVaultKey(t),t=>O(e,t)),getAll:e=>l(v(e),t=>O(e,t)),getMany:(e,t)=>{let r=t=>O(e,t),i=v(e);return Promise.all(t.map(e=>u(i,n.encodeVaultKey(e),r)))},iterate(e){return m(v(e),t=>O(e,t))},pruneExpiredInTable:e=>p(v(e)),put(e,t,r){let i=n.encodeVaultKey(n.getRecordKey(g,e,t)),a=k(e,t,r);return o(v(e).put(a,i)).then(()=>void 0)},putAll(e,t,r){return Promise.all(t.map(t=>{let i=n.encodeVaultKey(n.getRecordKey(g,e,t)),a=k(e,t,r);return o(v(e).put(a,i))})).then(()=>void 0)}},b=new Set(e),x=!0,S=i.buildTxContext(g,y,e=>_.add(e),a,b,()=>x);try{let e=await c(s,h,()=>t(S));for(let e of _)r(e);return e}finally{x=!1}},M,N=i.buildDocumentStore(g,A,{codecs:_,onCrossTabMessage(e){if(y)return y.onmessage=t=>{let n=t.data?.table;n&&Object.hasOwn(g,n)&&e(n)},()=>{y.onmessage=null}},onMutation:D,onTransactions:e=>{M=(t,n)=>j(t,n,e.notifyMutation,e.validate)},schema:g});if(!M)throw new t.VaultError(`IndexedDB transaction capability was not initialized`);return Object.assign(i.withBatch(N,M,g),{getAllByIndex(e,n,r){return T(e,`readonly`,i=>{if(!i.indexNames.contains(n))throw new t.VaultError(`Table "${e}" has no index "${n}"`);return l(i.index(n),t=>O(e,t),r)})}})}exports.createIndexedDB=h,exports.defineMigration=a;
|
|
2
2
|
//# sourceMappingURL=indexeddb.cjs.map
|