@signaldb/generic-fs 2.0.0-beta.0 → 2.0.0-beta.2
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/dist/deltaHelpers.d.ts +55 -0
- package/dist/index.mjs +188 -136
- package/dist/index.mjs.map +1 -1
- package/dist/index.umd.js +1 -1
- package/dist/index.umd.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export type IndexDelta<I> = {
|
|
2
|
+
adds: Map<string, Set<I>>;
|
|
3
|
+
removes: Map<string, Set<I>>;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Records a single index mutation into the delta map for a given indexed field.
|
|
7
|
+
*
|
|
8
|
+
* The delta map is grouped by `fieldPath`, and then by stringified key (`rawKey`).
|
|
9
|
+
* Each key maps to a set of identifiers to add/remove for that key.
|
|
10
|
+
* @param deltas - Accumulator of per-field index deltas.
|
|
11
|
+
* @param fieldPath - Dot-path of the indexed field (used as the delta bucket key).
|
|
12
|
+
* @param changeKind - Whether this identifier should be added to or removed from the index key.
|
|
13
|
+
* @param rawKey - The stringified index key value.
|
|
14
|
+
* @param identifier - The item identifier to add/remove for `rawKey`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function addToDelta<I>(deltas: Map<string, IndexDelta<I>>, fieldPath: string, changeKind: 'add' | 'remove', rawKey: string, identifier: I): void;
|
|
17
|
+
/**
|
|
18
|
+
* Computes the delta for a change in a single indexed field.
|
|
19
|
+
*
|
|
20
|
+
* Values are coerced to string keys (with `null`/`undefined` treated as "no key").
|
|
21
|
+
* If the derived keys are equal, no delta is recorded.
|
|
22
|
+
* @param deltas - Accumulator of per-field index deltas.
|
|
23
|
+
* @param fieldPath - Dot-path of the indexed field being tracked.
|
|
24
|
+
* @param oldValue - Previous value of the field.
|
|
25
|
+
* @param newValue - Next value of the field.
|
|
26
|
+
* @param identifier - The item identifier affected by the change.
|
|
27
|
+
*/
|
|
28
|
+
export declare function addDeltaForChange<I>(deltas: Map<string, IndexDelta<I>>, fieldPath: string, oldValue: any, newValue: any, identifier: I): void;
|
|
29
|
+
/**
|
|
30
|
+
* Accumulates index deltas for an upsert operation.
|
|
31
|
+
*
|
|
32
|
+
* - If `existingItem` is present, compares each maintained index field between the old and new item,
|
|
33
|
+
* recording removes/adds for key changes.
|
|
34
|
+
* - If `existingItem` is absent, treats the operation as an insert and records adds for each
|
|
35
|
+
* maintained index field that has a non-null value.
|
|
36
|
+
* @param deltas - Accumulator of per-field index deltas.
|
|
37
|
+
* @param indicesToMaintain - List of dot-paths for fields that are indexed.
|
|
38
|
+
* @param existingItem - Previous stored item (if any).
|
|
39
|
+
* @param nextItem - Incoming item to upsert.
|
|
40
|
+
*/
|
|
41
|
+
export declare const accumulateUpsertDelta: <T extends {
|
|
42
|
+
id: I;
|
|
43
|
+
}, I>(deltas: Map<string, IndexDelta<I>>, indicesToMaintain: string[], existingItem: T | undefined, nextItem: T) => void;
|
|
44
|
+
/**
|
|
45
|
+
* Accumulates index deltas for a remove/delete operation.
|
|
46
|
+
*
|
|
47
|
+
* For each maintained index field, records a removal of the item's identifier from the
|
|
48
|
+
* corresponding stringified key (skipping `null`/`undefined` values).
|
|
49
|
+
* @param deltas - Accumulator of per-field index deltas.
|
|
50
|
+
* @param indicesToMaintain - List of dot-paths for fields that are indexed.
|
|
51
|
+
* @param existingItem - The item being removed.
|
|
52
|
+
*/
|
|
53
|
+
export declare function accumulateRemoveDelta<T extends {
|
|
54
|
+
id: I;
|
|
55
|
+
}, I>(deltas: Map<string, IndexDelta<I>>, indicesToMaintain: string[], existingItem: T): void;
|
package/dist/index.mjs
CHANGED
|
@@ -1,172 +1,224 @@
|
|
|
1
|
-
import {
|
|
2
|
-
function
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { get as j, createStorageAdapter as N } from "@signaldb/core";
|
|
2
|
+
function M(e, d, p, f, l) {
|
|
3
|
+
e.has(d) || e.set(d, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });
|
|
4
|
+
const x = e.get(d);
|
|
5
|
+
if (!x)
|
|
6
|
+
return;
|
|
7
|
+
const I = p === "add" ? x.adds : x.removes;
|
|
8
|
+
I.has(f) || I.set(f, /* @__PURE__ */ new Set()), I.get(f)?.add(l);
|
|
9
|
+
}
|
|
10
|
+
const V = (e, d, p, f) => {
|
|
11
|
+
for (const l of d) {
|
|
12
|
+
const x = j(f, l);
|
|
13
|
+
x != null && M(e, l, "add", String(x), f.id);
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
function C(e, d, p) {
|
|
17
|
+
for (const f of d) {
|
|
18
|
+
const l = j(p, f);
|
|
19
|
+
l != null && M(e, f, "remove", String(l), p.id);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
function U(e, d) {
|
|
23
|
+
const p = e.joinPath(d, "items"), f = e.joinPath(d, "index"), l = async (t) => e.fileExists(t).catch(() => !1), x = async (t, n) => e.removeEntry(t, n).catch(() => {
|
|
24
|
+
}), I = async (t) => e.joinPath(await p, await e.fileNameForId(t)), g = async (t) => e.joinPath(await f, await e.fileNameForIndexKey(t)), R = async (t, n) => {
|
|
25
|
+
const a = await e.fileNameForIndexKey(n);
|
|
26
|
+
return e.joinPath(t, a);
|
|
27
|
+
}, S = async (t) => {
|
|
28
|
+
if (!await l(t))
|
|
29
|
+
return [];
|
|
30
|
+
const a = await e.readObject(t).catch(() => []);
|
|
31
|
+
return Array.isArray(a) ? a : [];
|
|
32
|
+
}, K = (t) => {
|
|
33
|
+
const n = /* @__PURE__ */ new Map();
|
|
34
|
+
if (!Array.isArray(t))
|
|
35
|
+
return n;
|
|
36
|
+
for (const a of t)
|
|
37
|
+
for (const [s, i] of Object.entries(a))
|
|
38
|
+
n.set(s, new Set(i));
|
|
39
|
+
return n;
|
|
40
|
+
}, A = async (t, n) => {
|
|
41
|
+
if (n.size === 0) {
|
|
42
|
+
await l(t) && await x(t);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const a = [];
|
|
46
|
+
n.forEach((s, i) => {
|
|
47
|
+
a.push({ [i]: [...s] });
|
|
48
|
+
}), await e.writeIndexObject(t, a);
|
|
49
|
+
}, b = async (t) => {
|
|
50
|
+
const n = await e.readIndexObject(t).catch(() => null);
|
|
51
|
+
return K(n);
|
|
52
|
+
}, O = async () => {
|
|
53
|
+
const t = await p;
|
|
54
|
+
if (!await l(t))
|
|
5
55
|
return [];
|
|
6
|
-
const
|
|
7
|
-
return await Promise.all(
|
|
8
|
-
const
|
|
9
|
-
Array.isArray(
|
|
56
|
+
const a = await e.listFilesRecursive(t), s = [];
|
|
57
|
+
return await Promise.all(a.map(async (i) => {
|
|
58
|
+
const w = await e.joinPath(t, i), o = await e.readObject(w).catch(() => null);
|
|
59
|
+
Array.isArray(o) && s.push(...o);
|
|
10
60
|
})), s;
|
|
11
|
-
},
|
|
12
|
-
const
|
|
13
|
-
await
|
|
14
|
-
}), await t.ensureDir(a);
|
|
61
|
+
}, z = async (t, n = O()) => {
|
|
62
|
+
const a = await n, s = await g(t);
|
|
63
|
+
await x(s, { recursive: !0 }), await e.ensureDir(s);
|
|
15
64
|
const i = /* @__PURE__ */ new Map();
|
|
16
|
-
for (const o of
|
|
17
|
-
const
|
|
18
|
-
|
|
65
|
+
for (const o of a) {
|
|
66
|
+
const c = j(o, t);
|
|
67
|
+
if (c == null)
|
|
68
|
+
continue;
|
|
69
|
+
const r = String(c);
|
|
70
|
+
i.has(r) || i.set(r, /* @__PURE__ */ new Set()), i.get(r)?.add(o.id);
|
|
19
71
|
}
|
|
20
|
-
const
|
|
21
|
-
for (const [o,
|
|
22
|
-
const
|
|
23
|
-
|
|
72
|
+
const w = {};
|
|
73
|
+
for (const [o, c] of i) {
|
|
74
|
+
const r = await e.fileNameForIndexKey(o);
|
|
75
|
+
w[r] || (w[r] = []), w[r].push({ [o]: [...c] });
|
|
24
76
|
}
|
|
25
|
-
await Promise.all(Object.entries(
|
|
26
|
-
const
|
|
27
|
-
await
|
|
77
|
+
await Promise.all(Object.entries(w).map(async ([o, c]) => {
|
|
78
|
+
const r = await e.joinPath(s, o);
|
|
79
|
+
await e.writeIndexObject(r, c);
|
|
28
80
|
}));
|
|
29
|
-
},
|
|
30
|
-
const n = await
|
|
31
|
-
if (!await
|
|
32
|
-
throw new Error(`Index on field "${
|
|
33
|
-
const
|
|
34
|
-
return await Promise.all(
|
|
35
|
-
const o = await
|
|
36
|
-
if (Array.isArray(
|
|
37
|
-
for (const
|
|
38
|
-
for (const [
|
|
39
|
-
i.has(
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
}, B = async (t) => {
|
|
82
|
+
const n = await g(t);
|
|
83
|
+
if (!await l(n))
|
|
84
|
+
throw new Error(`Index on field "${t}" does not exist`);
|
|
85
|
+
const s = await e.listFilesRecursive(n), i = /* @__PURE__ */ new Map();
|
|
86
|
+
return await Promise.all(s.map(async (w) => {
|
|
87
|
+
const o = await e.joinPath(n, w), c = await e.readIndexObject(o).catch(() => null);
|
|
88
|
+
if (Array.isArray(c))
|
|
89
|
+
for (const r of c)
|
|
90
|
+
for (const [h, m] of Object.entries(r)) {
|
|
91
|
+
i.has(h) || i.set(h, /* @__PURE__ */ new Set());
|
|
92
|
+
const P = i.get(h);
|
|
93
|
+
for (const y of m)
|
|
94
|
+
P?.add(y);
|
|
42
95
|
}
|
|
43
96
|
})), i;
|
|
44
|
-
},
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
return;
|
|
49
|
-
const o = s === "add" ? c.adds : c.removes;
|
|
50
|
-
o.has(a) || o.set(a, /* @__PURE__ */ new Set()), o.get(a)?.add(i);
|
|
51
|
-
}, M = (e, n, s, a, i) => {
|
|
52
|
-
const c = s == null ? void 0 : String(s), o = a == null ? void 0 : String(a);
|
|
53
|
-
c !== o && (c != null && P(e, n, "remove", c, i), o != null && P(e, n, "add", o, i));
|
|
54
|
-
}, S = (e, n, s) => {
|
|
55
|
-
if (n)
|
|
56
|
-
for (const a of I)
|
|
57
|
-
M(e, a, m(n, a), m(s, a), s.id);
|
|
58
|
-
else
|
|
59
|
-
for (const a of I) {
|
|
60
|
-
const i = m(s, a);
|
|
61
|
-
i != null && P(e, a, "add", String(i), s.id);
|
|
62
|
-
}
|
|
63
|
-
}, k = (e, n) => {
|
|
64
|
-
for (const s of I) {
|
|
65
|
-
const a = m(n, s);
|
|
66
|
-
a != null && P(e, s, "remove", String(a), n.id);
|
|
67
|
-
}
|
|
68
|
-
}, F = async (e) => {
|
|
69
|
-
await Promise.all([...e.entries()].map(async ([n, s]) => {
|
|
70
|
-
const a = await t.joinPath(await p, await t.fileNameForIndexKey(n));
|
|
71
|
-
if (!await t.fileExists(a).catch(() => !1))
|
|
97
|
+
}, F = [], k = async (t) => {
|
|
98
|
+
await Promise.all([...t.entries()].map(async ([n, a]) => {
|
|
99
|
+
const s = await g(n);
|
|
100
|
+
if (!await l(s))
|
|
72
101
|
return;
|
|
73
|
-
await
|
|
74
|
-
const
|
|
75
|
-
...
|
|
76
|
-
...
|
|
102
|
+
await e.ensureDir(s);
|
|
103
|
+
const w = /* @__PURE__ */ new Set([
|
|
104
|
+
...a.adds.keys(),
|
|
105
|
+
...a.removes.keys()
|
|
77
106
|
]), o = /* @__PURE__ */ new Map();
|
|
78
|
-
await Promise.all([...
|
|
79
|
-
o.set(
|
|
107
|
+
await Promise.all([...w].map(async (r) => {
|
|
108
|
+
o.set(r, await e.fileNameForIndexKey(r));
|
|
80
109
|
}));
|
|
81
|
-
const
|
|
82
|
-
await Promise.all([...
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
for (const [f, u] of Object.entries(y))
|
|
87
|
-
d.set(f, new Set(u));
|
|
88
|
-
if (s.removes.forEach((y, f) => {
|
|
89
|
-
if (o.get(f) !== w)
|
|
110
|
+
const c = new Set(o.values());
|
|
111
|
+
await Promise.all([...c].map(async (r) => {
|
|
112
|
+
const h = await e.joinPath(s, r), m = await b(h);
|
|
113
|
+
a.removes.forEach((P, y) => {
|
|
114
|
+
if (o.get(y) !== r)
|
|
90
115
|
return;
|
|
91
|
-
const u =
|
|
92
|
-
u && (
|
|
93
|
-
}),
|
|
94
|
-
if (o.get(
|
|
116
|
+
const u = m.get(y);
|
|
117
|
+
u && (P.forEach((E) => u.delete(E)), u.size === 0 && m.delete(y));
|
|
118
|
+
}), a.adds.forEach((P, y) => {
|
|
119
|
+
if (o.get(y) !== r)
|
|
95
120
|
return;
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
}),
|
|
99
|
-
await t.fileExists(l).catch(() => !1) && await t.removeEntry(l).catch(() => {
|
|
100
|
-
});
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const b = [];
|
|
104
|
-
d.forEach((y, f) => {
|
|
105
|
-
b.push({ [f]: [...y] });
|
|
106
|
-
}), await t.writeIndexObject(l, b);
|
|
121
|
+
const u = m.get(y) ?? /* @__PURE__ */ new Set();
|
|
122
|
+
P.forEach((E) => u.add(E)), m.set(y, u);
|
|
123
|
+
}), await A(h, m);
|
|
107
124
|
}));
|
|
108
125
|
}));
|
|
109
|
-
},
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
126
|
+
}, T = async (t, n) => {
|
|
127
|
+
const a = await g(t);
|
|
128
|
+
if (!await l(a))
|
|
129
|
+
return;
|
|
130
|
+
const i = await e.listFilesRecursive(a);
|
|
131
|
+
await Promise.all(i.map(async (w) => {
|
|
132
|
+
const o = await e.joinPath(a, w), c = await e.readIndexObject(o).catch(() => null);
|
|
133
|
+
if (!Array.isArray(c))
|
|
134
|
+
return;
|
|
135
|
+
let r = !1;
|
|
136
|
+
const h = /* @__PURE__ */ new Map();
|
|
137
|
+
for (const m of c)
|
|
138
|
+
for (const [P, y] of Object.entries(m)) {
|
|
139
|
+
const u = new Set(y), E = u.size;
|
|
140
|
+
u.delete(n), u.size !== E && (r = !0), u.size > 0 && h.set(P, u);
|
|
141
|
+
}
|
|
142
|
+
r && await A(o, h);
|
|
143
|
+
}));
|
|
144
|
+
}, $ = async (t, n, a) => {
|
|
145
|
+
if (n == null)
|
|
146
|
+
return;
|
|
147
|
+
const s = String(n), i = await g(t);
|
|
148
|
+
if (!await l(i))
|
|
149
|
+
return;
|
|
150
|
+
await e.ensureDir(i);
|
|
151
|
+
const o = await R(i, s), c = await b(o), r = c.get(s) ?? /* @__PURE__ */ new Set();
|
|
152
|
+
r.add(a), c.set(s, r), await A(o, c);
|
|
153
|
+
}, L = async (t, n) => {
|
|
154
|
+
await Promise.all(F.map(async (a) => {
|
|
155
|
+
await T(a, t.id);
|
|
156
|
+
const s = j(n, a);
|
|
157
|
+
await $(a, s, n.id);
|
|
158
|
+
}));
|
|
159
|
+
}, D = async (t, n) => {
|
|
160
|
+
const a = /* @__PURE__ */ new Map();
|
|
161
|
+
await Promise.all(t.map(async (s) => {
|
|
162
|
+
const i = await I(s.id), w = await S(i), o = w.findIndex((c) => c.id === s.id);
|
|
113
163
|
if (n === "insert") {
|
|
114
|
-
if (
|
|
115
|
-
throw new Error(`Item with id "${String(
|
|
116
|
-
|
|
164
|
+
if (o !== -1)
|
|
165
|
+
throw new Error(`Item with id "${String(s.id)}" already exists`);
|
|
166
|
+
V(a, F, void 0, s), await e.writeObject(i, [...w, s]);
|
|
117
167
|
} else {
|
|
118
|
-
if (
|
|
119
|
-
throw new Error(`Item with id "${String(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
w[r] = a, await t.writeObject(i, w);
|
|
168
|
+
if (o === -1)
|
|
169
|
+
throw new Error(`Item with id "${String(s.id)}" does not exist`);
|
|
170
|
+
const c = [...w], r = c[o];
|
|
171
|
+
c[o] = s, await e.writeObject(i, c), await L(r, s);
|
|
123
172
|
}
|
|
124
|
-
})), await
|
|
173
|
+
})), a.size > 0 && await k(a);
|
|
125
174
|
};
|
|
126
|
-
return
|
|
175
|
+
return N({
|
|
127
176
|
setup: async () => {
|
|
128
|
-
await
|
|
177
|
+
await e.ensureDir(d);
|
|
129
178
|
},
|
|
130
179
|
teardown: async () => {
|
|
131
180
|
},
|
|
132
|
-
readAll:
|
|
133
|
-
readIds: async (
|
|
134
|
-
const
|
|
135
|
-
return Array.isArray(i) ? i.find((
|
|
136
|
-
}))).filter((
|
|
137
|
-
createIndex: async (
|
|
138
|
-
|
|
181
|
+
readAll: O,
|
|
182
|
+
readIds: async (t) => (await Promise.all(t.map(async (a) => {
|
|
183
|
+
const s = await I(a), i = await e.readObject(s).catch(() => []) ?? [];
|
|
184
|
+
return Array.isArray(i) ? i.find((w) => w.id === a) ?? null : null;
|
|
185
|
+
}))).filter((a) => a != null),
|
|
186
|
+
createIndex: async (t) => {
|
|
187
|
+
if (t === "id")
|
|
188
|
+
throw new Error("Cannot create index on id field");
|
|
189
|
+
F.push(t), await z(t);
|
|
139
190
|
},
|
|
140
|
-
dropIndex: async (
|
|
141
|
-
const n = await
|
|
142
|
-
if (!await
|
|
143
|
-
throw new Error(`Index on field "${
|
|
144
|
-
await
|
|
191
|
+
dropIndex: async (t) => {
|
|
192
|
+
const n = await g(t);
|
|
193
|
+
if (!await l(n))
|
|
194
|
+
throw new Error(`Index on field "${t}" does not exist`);
|
|
195
|
+
await e.removeEntry(n, { recursive: !0 });
|
|
145
196
|
},
|
|
146
|
-
readIndex:
|
|
147
|
-
insert: async (
|
|
148
|
-
await
|
|
197
|
+
readIndex: B,
|
|
198
|
+
insert: async (t) => {
|
|
199
|
+
await D(t, "insert");
|
|
149
200
|
},
|
|
150
|
-
replace: async (
|
|
151
|
-
await
|
|
201
|
+
replace: async (t) => {
|
|
202
|
+
await D(t, "replace");
|
|
152
203
|
},
|
|
153
|
-
remove: async (
|
|
204
|
+
remove: async (t) => {
|
|
154
205
|
const n = /* @__PURE__ */ new Map();
|
|
155
|
-
await Promise.all(
|
|
156
|
-
const
|
|
157
|
-
if (
|
|
158
|
-
throw new Error(`Item with id "${String(
|
|
159
|
-
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
206
|
+
await Promise.all(t.map(async (a) => {
|
|
207
|
+
const s = await I(a.id), i = await S(s), w = i.findIndex((c) => c.id === a.id);
|
|
208
|
+
if (w === -1)
|
|
209
|
+
throw new Error(`Item with id "${String(a.id)}" does not exist`);
|
|
210
|
+
C(n, F, i[w]);
|
|
211
|
+
const o = [...i];
|
|
212
|
+
o.splice(w, 1), await (o.length === 0 ? e.removeEntry(s).catch(() => {
|
|
213
|
+
}) : e.writeObject(s, o));
|
|
214
|
+
})), await k(n);
|
|
163
215
|
},
|
|
164
216
|
removeAll: async () => {
|
|
165
|
-
await
|
|
217
|
+
await l(d) && await e.removeEntry(d, { recursive: !0 });
|
|
166
218
|
}
|
|
167
219
|
});
|
|
168
220
|
}
|
|
169
221
|
export {
|
|
170
|
-
|
|
222
|
+
U as default
|
|
171
223
|
};
|
|
172
224
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter, get } from '@signaldb/core';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const readAll = async () => {\n const directoryExists = await driver.fileExists(await itemsDirectoryPathPromise)\n .catch(() => false);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(await itemsDirectoryPathPromise);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(await itemsDirectoryPathPromise, relativePath);\n const itemsInFile = await driver.readObject(fullPath);\n if (!Array.isArray(itemsInFile))\n return;\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n await driver.removeEntry(indexPath, { recursive: true }).catch(() => { });\n await driver.ensureDir(indexPath);\n // Map<fieldValue, Set<identifier>>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n if (!indexMap.has(fieldValue))\n indexMap.set(fieldValue, new Set());\n indexMap.get(fieldValue)?.add(item.id);\n }\n // Persist as files keyed by safe value; keep original value stringified for lookup parity.\n const buckets = {};\n for (const [rawKey, identifiers] of indexMap) {\n const rawKeyString = String(rawKey);\n const key = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[key])\n buckets[key] = [];\n buckets[key].push({ [rawKeyString]: [...identifiers] });\n }\n await Promise.all(Object.entries(buckets).map(async ([key, maps]) => {\n const filePath = await driver.joinPath(indexPath, key);\n await driver.writeIndexObject(filePath, maps);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [key, identifiers] of Object.entries(entry)) {\n if (!resultIndex.has(key))\n resultIndex.set(key, new Set());\n for (const identifier of identifiers) {\n resultIndex.get(key)?.add(identifier);\n }\n }\n }\n }));\n return resultIndex;\n };\n const indicesToMaintain = [];\n const addToDelta = (deltas, field, kind, rawKey, id) => {\n if (!deltas.has(field))\n deltas.set(field, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(field);\n if (!delta)\n return;\n const target = kind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(id);\n };\n const addDeltaForChange = (deltas, field, oldValue, newValue, id) => {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, field, 'remove', oldKey, id);\n if (newKey != null)\n addToDelta(deltas, field, 'add', newKey, id);\n };\n const accumulateUpsertDelta = (deltas, existing, next) => {\n if (existing) {\n for (const field of indicesToMaintain) {\n addDeltaForChange(deltas, field, get(existing, field), get(next, field), next.id);\n }\n }\n else {\n for (const field of indicesToMaintain) {\n const value = get(next, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'add', String(value), next.id);\n }\n }\n };\n const accumulateRemoveDelta = (deltas, existing) => {\n for (const field of indicesToMaintain) {\n const value = get(existing, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'remove', String(value), existing.id);\n }\n };\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucket = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucket.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBuckets = new Set(rawKeyToBucket.values());\n await Promise.all([...touchedBuckets].map(async (bucket) => {\n const filePath = await driver.joinPath(indexPath, bucket);\n const data = await driver.readIndexObject(filePath);\n // Rehydrate only this bucket into a map of rawKey -> Set<I>\n const bucketIndex = new Map();\n if (Array.isArray(data)) {\n for (const entry of data) {\n for (const [rawKey, ids] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(ids));\n }\n }\n }\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n const set = bucketIndex.get(rawKey);\n if (!set)\n return;\n ids.forEach(id => set.delete(id));\n if (set.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n let set = bucketIndex.get(rawKey);\n if (!set) {\n set = new Set();\n bucketIndex.set(rawKey, set);\n }\n ids.forEach(id => set.add(id));\n });\n if (bucketIndex.size === 0) {\n const exists = await driver.fileExists(filePath).catch(() => false);\n if (exists)\n await driver.removeEntry(filePath).catch(() => { });\n return;\n }\n // Persist this bucket only\n const out = [];\n bucketIndex.forEach((set, rawKey) => {\n out.push({ [rawKey]: [...set] });\n });\n await driver.writeIndexObject(filePath, out);\n }));\n }));\n };\n // Shared item operations using the delta helpers\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (mode === 'insert') {\n if (index !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, undefined, item);\n await driver.writeObject(filePath, [...array, item]);\n }\n else {\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateUpsertDelta(deltas, array[index], item);\n const updated = [...array];\n updated[index] = item;\n await driver.writeObject(filePath, updated);\n }\n }));\n await applyIndexDeltas(deltas);\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const itemsInFile = await driver.readObject(filePath);\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const exists = await driver.fileExists(pathToDrop).catch(() => false);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, array[index]);\n const updated = [...array];\n updated.splice(index, 1);\n await (updated.length === 0\n ? driver.removeEntry(filePath)\n : driver.writeObject(filePath, updated));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await driver.fileExists(folderName).catch(() => false);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","readAll","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","fieldPath","itemsPromise","allItems","indexPath","indexMap","item","fieldValue","get","buckets","rawKey","identifiers","rawKeyString","key","maps","filePath","readIndex","resultIndex","entry","identifier","indicesToMaintain","addToDelta","deltas","field","kind","id","delta","target","addDeltaForChange","oldValue","newValue","oldKey","newKey","accumulateUpsertDelta","existing","next","value","accumulateRemoveDelta","applyIndexDeltas","touchedRawKeys","rawKeyToBucket","touchedBuckets","bucket","data","bucketIndex","ids","set","out","upsertItems","items","mode","array","index","x","updated","createStorageAdapter","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/deltaHelpers.ts","../src/index.ts"],"sourcesContent":["import { get } from '@signaldb/core';\n/**\n * Records a single index mutation into the delta map for a given indexed field.\n *\n * The delta map is grouped by `fieldPath`, and then by stringified key (`rawKey`).\n * Each key maps to a set of identifiers to add/remove for that key.\n * @param deltas - Accumulator of per-field index deltas.\n * @param fieldPath - Dot-path of the indexed field (used as the delta bucket key).\n * @param changeKind - Whether this identifier should be added to or removed from the index key.\n * @param rawKey - The stringified index key value.\n * @param identifier - The item identifier to add/remove for `rawKey`.\n */\nexport function addToDelta(deltas, fieldPath, changeKind, rawKey, identifier) {\n if (!deltas.has(fieldPath))\n deltas.set(fieldPath, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(fieldPath);\n if (!delta)\n return;\n const target = changeKind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(identifier);\n}\n/**\n * Computes the delta for a change in a single indexed field.\n *\n * Values are coerced to string keys (with `null`/`undefined` treated as \"no key\").\n * If the derived keys are equal, no delta is recorded.\n * @param deltas - Accumulator of per-field index deltas.\n * @param fieldPath - Dot-path of the indexed field being tracked.\n * @param oldValue - Previous value of the field.\n * @param newValue - Next value of the field.\n * @param identifier - The item identifier affected by the change.\n */\nexport function addDeltaForChange(deltas, fieldPath, oldValue, newValue, identifier) {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, fieldPath, 'remove', oldKey, identifier);\n if (newKey != null)\n addToDelta(deltas, fieldPath, 'add', newKey, identifier);\n}\n/**\n * Accumulates index deltas for an upsert operation.\n *\n * - If `existingItem` is present, compares each maintained index field between the old and new item,\n * recording removes/adds for key changes.\n * - If `existingItem` is absent, treats the operation as an insert and records adds for each\n * maintained index field that has a non-null value.\n * @param deltas - Accumulator of per-field index deltas.\n * @param indicesToMaintain - List of dot-paths for fields that are indexed.\n * @param existingItem - Previous stored item (if any).\n * @param nextItem - Incoming item to upsert.\n */\nexport const accumulateUpsertDelta = (deltas, indicesToMaintain, existingItem, nextItem) => {\n if (existingItem) {\n for (const fieldPath of indicesToMaintain) {\n addDeltaForChange(deltas, fieldPath, get(existingItem, fieldPath), get(nextItem, fieldPath), nextItem.id);\n }\n }\n else {\n for (const fieldPath of indicesToMaintain) {\n const value = get(nextItem, fieldPath);\n if (value == null)\n continue;\n addToDelta(deltas, fieldPath, 'add', String(value), nextItem.id);\n }\n }\n};\n/**\n * Accumulates index deltas for a remove/delete operation.\n *\n * For each maintained index field, records a removal of the item's identifier from the\n * corresponding stringified key (skipping `null`/`undefined` values).\n * @param deltas - Accumulator of per-field index deltas.\n * @param indicesToMaintain - List of dot-paths for fields that are indexed.\n * @param existingItem - The item being removed.\n */\nexport function accumulateRemoveDelta(deltas, indicesToMaintain, existingItem) {\n for (const fieldPath of indicesToMaintain) {\n const value = get(existingItem, fieldPath);\n if (value == null)\n continue;\n addToDelta(deltas, fieldPath, 'remove', String(value), existingItem.id);\n }\n}\n","import { createStorageAdapter, get } from '@signaldb/core';\nimport { accumulateUpsertDelta, accumulateRemoveDelta, } from './deltaHelpers';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const safeFileExists = async (path) => driver.fileExists(path).catch(() => false);\n const safeRemoveEntry = async (path, options) => driver.removeEntry(path, options).catch(() => { });\n const toItemsFilePath = async (identifier) => driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const toIndexPathForField = async (fieldPath) => driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const toIndexBucketFilePath = async (indexPath, rawKey) => {\n const bucketFileName = await driver.fileNameForIndexKey(rawKey);\n return driver.joinPath(indexPath, bucketFileName);\n };\n const readItemsArrayOrEmpty = async (filePath) => {\n const exists = await safeFileExists(filePath);\n if (!exists)\n return [];\n const data = await driver.readObject(filePath).catch(() => []);\n return Array.isArray(data) ? data : [];\n };\n const loadBucketIndexFromData = (data) => {\n const bucketIndex = new Map();\n if (!Array.isArray(data))\n return bucketIndex;\n for (const entry of data) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(identifierList));\n }\n }\n return bucketIndex;\n };\n const writeBucketIndex = async (filePath, bucketIndex) => {\n if (bucketIndex.size === 0) {\n const exists = await safeFileExists(filePath);\n if (exists)\n await safeRemoveEntry(filePath);\n return;\n }\n const output = [];\n bucketIndex.forEach((identifierSet, rawKey) => {\n output.push({ [rawKey]: [...identifierSet] });\n });\n await driver.writeIndexObject(filePath, output);\n };\n const readBucketIndex = async (filePath) => {\n const data = await driver.readIndexObject(filePath).catch(() => null);\n return loadBucketIndexFromData(data);\n };\n const readAll = async () => {\n const itemsDirectoryPath = await itemsDirectoryPathPromise;\n const directoryExists = await safeFileExists(itemsDirectoryPath);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(itemsDirectoryPath);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(itemsDirectoryPath, relativePath);\n const itemsInFile = await driver.readObject(fullPath).catch(() => null);\n if (Array.isArray(itemsInFile))\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await toIndexPathForField(fieldPath);\n await safeRemoveEntry(indexPath, { recursive: true });\n await driver.ensureDir(indexPath);\n // Build value -> Set<identifier>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n const keyString = String(fieldValue);\n if (!indexMap.has(keyString))\n indexMap.set(keyString, new Set());\n indexMap.get(keyString)?.add(item.id);\n }\n // Group entries by bucket file name, then persist each bucket\n const buckets = {};\n for (const [rawKeyString, identifierSet] of indexMap) {\n const bucketFileName = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[bucketFileName])\n buckets[bucketFileName] = [];\n buckets[bucketFileName].push({ [rawKeyString]: [...identifierSet] });\n }\n await Promise.all(Object.entries(buckets).map(async ([bucketFileName, records]) => {\n const filePath = await driver.joinPath(indexPath, bucketFileName);\n await driver.writeIndexObject(filePath, records);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath).catch(() => null);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n if (!resultIndex.has(rawKey))\n resultIndex.set(rawKey, new Set());\n const target = resultIndex.get(rawKey);\n for (const identifier of identifierList)\n target?.add(identifier);\n }\n }\n }));\n return resultIndex;\n };\n // Track which field paths should be kept up-to-date incrementally.\n const indicesToMaintain = [];\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucketFileName = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucketFileName.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBucketFileNames = new Set(rawKeyToBucketFileName.values());\n await Promise.all([...touchedBucketFileNames].map(async (bucketFileName) => {\n const filePath = await driver.joinPath(indexPath, bucketFileName);\n const bucketIndex = await readBucketIndex(filePath);\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((identifierSet, rawKey) => {\n if (rawKeyToBucketFileName.get(rawKey) !== bucketFileName)\n return;\n const setForKey = bucketIndex.get(rawKey);\n if (!setForKey)\n return;\n identifierSet.forEach(identifier => setForKey.delete(identifier));\n if (setForKey.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((identifierSet, rawKey) => {\n if (rawKeyToBucketFileName.get(rawKey) !== bucketFileName)\n return;\n const setForKey = bucketIndex.get(rawKey) ?? new Set();\n identifierSet.forEach(identifier => setForKey.add(identifier));\n bucketIndex.set(rawKey, setForKey);\n });\n await writeBucketIndex(filePath, bucketIndex);\n }));\n }));\n };\n const removeIdFromIndex = async (fieldPath, identifier) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return;\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const filePath = await driver.joinPath(indexPath, relativePath);\n const data = await driver.readIndexObject(filePath).catch(() => null);\n if (!Array.isArray(data))\n return;\n let changed = false;\n const bucketIndex = new Map();\n for (const entry of data) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n const set = new Set(identifierList);\n const before = set.size;\n set.delete(identifier);\n if (set.size !== before)\n changed = true;\n if (set.size > 0)\n bucketIndex.set(rawKey, set);\n }\n }\n if (!changed)\n return;\n await writeBucketIndex(filePath, bucketIndex);\n }));\n };\n const addIdToIndex = async (fieldPath, value, identifier) => {\n if (value == null)\n return;\n const rawKey = String(value);\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return;\n await driver.ensureDir(indexPath);\n const filePath = await toIndexBucketFilePath(indexPath, rawKey);\n const bucketIndex = await readBucketIndex(filePath);\n const setForKey = bucketIndex.get(rawKey) ?? new Set();\n setForKey.add(identifier);\n bucketIndex.set(rawKey, setForKey);\n await writeBucketIndex(filePath, bucketIndex);\n };\n const updateIndexForReplace = async (oldItem, nextItem) => {\n await Promise.all(indicesToMaintain.map(async (fieldPath) => {\n await removeIdFromIndex(fieldPath, oldItem.id);\n const newValue = get(nextItem, fieldPath);\n await addIdToIndex(fieldPath, newValue, nextItem.id);\n }));\n };\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await toItemsFilePath(item.id);\n const existingArray = await readItemsArrayOrEmpty(filePath);\n const indexOfItem = existingArray.findIndex(existing => existing.id === item.id);\n if (mode === 'insert') {\n if (indexOfItem !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, indicesToMaintain, undefined, item);\n await driver.writeObject(filePath, [...existingArray, item]);\n }\n else {\n if (indexOfItem === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n const updatedArray = [...existingArray];\n const oldItem = updatedArray[indexOfItem];\n updatedArray[indexOfItem] = item;\n await driver.writeObject(filePath, updatedArray);\n await updateIndexForReplace(oldItem, item);\n }\n }));\n // Only apply deltas for inserts (replace handled by direct purge+add)\n if (deltas.size > 0) {\n await applyIndexDeltas(deltas);\n }\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await toItemsFilePath(identifier);\n const itemsInFile = await driver.readObject(filePath).catch(() => []) ?? [];\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n if (fieldPath === 'id')\n throw new Error('Cannot create index on id field');\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await toIndexPathForField(fieldPath);\n const exists = await safeFileExists(pathToDrop);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await toItemsFilePath(item.id);\n const existingArray = await readItemsArrayOrEmpty(filePath);\n const indexOfItem = existingArray.findIndex(existing => existing.id === item.id);\n if (indexOfItem === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, indicesToMaintain, existingArray[indexOfItem]);\n const updatedArray = [...existingArray];\n updatedArray.splice(indexOfItem, 1);\n await (updatedArray.length === 0\n ? driver.removeEntry(filePath).catch(() => { })\n : driver.writeObject(filePath, updatedArray));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await safeFileExists(folderName);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["addToDelta","deltas","fieldPath","changeKind","rawKey","identifier","delta","target","accumulateUpsertDelta","indicesToMaintain","existingItem","nextItem","value","get","accumulateRemoveDelta","createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","safeFileExists","path","safeRemoveEntry","options","toItemsFilePath","toIndexPathForField","toIndexBucketFilePath","indexPath","bucketFileName","readItemsArrayOrEmpty","filePath","data","loadBucketIndexFromData","bucketIndex","entry","identifierList","writeBucketIndex","output","identifierSet","readBucketIndex","readAll","itemsDirectoryPath","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","itemsPromise","allItems","indexMap","item","fieldValue","keyString","buckets","rawKeyString","records","readIndex","resultIndex","maps","applyIndexDeltas","touchedRawKeys","rawKeyToBucketFileName","touchedBucketFileNames","setForKey","removeIdFromIndex","changed","set","before","addIdToIndex","updateIndexForReplace","oldItem","newValue","upsertItems","items","mode","existingArray","indexOfItem","existing","updatedArray","createStorageAdapter","identifiers","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":"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"}
|
package/dist/index.umd.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
(function(
|
|
1
|
+
(function(x,E){typeof exports=="object"&&typeof module<"u"?module.exports=E(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],E):(x=typeof globalThis<"u"?globalThis:x||self,x.SignalDB=E(x.core))})(this,(function(x){"use strict";function E(e,l,I,f,d){e.has(l)||e.set(l,{adds:new Map,removes:new Map});const h=e.get(l);if(!h)return;const g=I==="add"?h.adds:h.removes;g.has(f)||g.set(f,new Set),g.get(f)?.add(d)}const R=(e,l,I,f)=>{for(const d of l){const h=x.get(f,d);h!=null&&E(e,d,"add",String(h),f.id)}};function B(e,l,I){for(const f of l){const d=x.get(I,f);d!=null&&E(e,f,"remove",String(d),I.id)}}function K(e,l){const I=e.joinPath(l,"items"),f=e.joinPath(l,"index"),d=async t=>e.fileExists(t).catch(()=>!1),h=async(t,n)=>e.removeEntry(t,n).catch(()=>{}),g=async t=>e.joinPath(await I,await e.fileNameForId(t)),F=async t=>e.joinPath(await f,await e.fileNameForIndexKey(t)),T=async(t,n)=>{const a=await e.fileNameForIndexKey(n);return e.joinPath(t,a)},A=async t=>{if(!await d(t))return[];const a=await e.readObject(t).catch(()=>[]);return Array.isArray(a)?a:[]},z=t=>{const n=new Map;if(!Array.isArray(t))return n;for(const a of t)for(const[s,i]of Object.entries(a))n.set(s,new Set(i));return n},S=async(t,n)=>{if(n.size===0){await d(t)&&await h(t);return}const a=[];n.forEach((s,i)=>{a.push({[i]:[...s]})}),await e.writeIndexObject(t,a)},O=async t=>{const n=await e.readIndexObject(t).catch(()=>null);return z(n)},k=async()=>{const t=await I;if(!await d(t))return[];const a=await e.listFilesRecursive(t),s=[];return await Promise.all(a.map(async i=>{const w=await e.joinPath(t,i),o=await e.readObject(w).catch(()=>null);Array.isArray(o)&&s.push(...o)})),s},$=async(t,n=k())=>{const a=await n,s=await F(t);await h(s,{recursive:!0}),await e.ensureDir(s);const i=new Map;for(const o of a){const c=x.get(o,t);if(c==null)continue;const r=String(c);i.has(r)||i.set(r,new Set),i.get(r)?.add(o.id)}const w={};for(const[o,c]of i){const r=await e.fileNameForIndexKey(o);w[r]||(w[r]=[]),w[r].push({[o]:[...c]})}await Promise.all(Object.entries(w).map(async([o,c])=>{const r=await e.joinPath(s,o);await e.writeIndexObject(r,c)}))},L=async t=>{const n=await F(t);if(!await d(n))throw new Error(`Index on field "${t}" does not exist`);const s=await e.listFilesRecursive(n),i=new Map;return await Promise.all(s.map(async w=>{const o=await e.joinPath(n,w),c=await e.readIndexObject(o).catch(()=>null);if(Array.isArray(c))for(const r of c)for(const[m,p]of Object.entries(r)){i.has(m)||i.set(m,new Set);const P=i.get(m);for(const y of p)P?.add(y)}})),i},b=[],D=async t=>{await Promise.all([...t.entries()].map(async([n,a])=>{const s=await F(n);if(!await d(s))return;await e.ensureDir(s);const w=new Set([...a.adds.keys(),...a.removes.keys()]),o=new Map;await Promise.all([...w].map(async r=>{o.set(r,await e.fileNameForIndexKey(r))}));const c=new Set(o.values());await Promise.all([...c].map(async r=>{const m=await e.joinPath(s,r),p=await O(m);a.removes.forEach((P,y)=>{if(o.get(y)!==r)return;const u=p.get(y);u&&(P.forEach(j=>u.delete(j)),u.size===0&&p.delete(y))}),a.adds.forEach((P,y)=>{if(o.get(y)!==r)return;const u=p.get(y)??new Set;P.forEach(j=>u.add(j)),p.set(y,u)}),await S(m,p)}))}))},N=async(t,n)=>{const a=await F(t);if(!await d(a))return;const i=await e.listFilesRecursive(a);await Promise.all(i.map(async w=>{const o=await e.joinPath(a,w),c=await e.readIndexObject(o).catch(()=>null);if(!Array.isArray(c))return;let r=!1;const m=new Map;for(const p of c)for(const[P,y]of Object.entries(p)){const u=new Set(y),j=u.size;u.delete(n),u.size!==j&&(r=!0),u.size>0&&m.set(P,u)}r&&await S(o,m)}))},V=async(t,n,a)=>{if(n==null)return;const s=String(n),i=await F(t);if(!await d(i))return;await e.ensureDir(i);const o=await T(i,s),c=await O(o),r=c.get(s)??new Set;r.add(a),c.set(s,r),await S(o,c)},q=async(t,n)=>{await Promise.all(b.map(async a=>{await N(a,t.id);const s=x.get(n,a);await V(a,s,n.id)}))},M=async(t,n)=>{const a=new Map;await Promise.all(t.map(async s=>{const i=await g(s.id),w=await A(i),o=w.findIndex(c=>c.id===s.id);if(n==="insert"){if(o!==-1)throw new Error(`Item with id "${String(s.id)}" already exists`);R(a,b,void 0,s),await e.writeObject(i,[...w,s])}else{if(o===-1)throw new Error(`Item with id "${String(s.id)}" does not exist`);const c=[...w],r=c[o];c[o]=s,await e.writeObject(i,c),await q(r,s)}})),a.size>0&&await D(a)};return x.createStorageAdapter({setup:async()=>{await e.ensureDir(l)},teardown:async()=>{},readAll:k,readIds:async t=>(await Promise.all(t.map(async a=>{const s=await g(a),i=await e.readObject(s).catch(()=>[])??[];return Array.isArray(i)?i.find(w=>w.id===a)??null:null}))).filter(a=>a!=null),createIndex:async t=>{if(t==="id")throw new Error("Cannot create index on id field");b.push(t),await $(t)},dropIndex:async t=>{const n=await F(t);if(!await d(n))throw new Error(`Index on field "${t}" does not exist`);await e.removeEntry(n,{recursive:!0})},readIndex:L,insert:async t=>{await M(t,"insert")},replace:async t=>{await M(t,"replace")},remove:async t=>{const n=new Map;await Promise.all(t.map(async a=>{const s=await g(a.id),i=await A(s),w=i.findIndex(c=>c.id===a.id);if(w===-1)throw new Error(`Item with id "${String(a.id)}" does not exist`);B(n,b,i[w]);const o=[...i];o.splice(w,1),await(o.length===0?e.removeEntry(s).catch(()=>{}):e.writeObject(s,o))})),await D(n)},removeAll:async()=>{await d(l)&&await e.removeEntry(l,{recursive:!0})}})}return K}));
|
|
2
2
|
//# sourceMappingURL=index.umd.js.map
|
package/dist/index.umd.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter, get } from '@signaldb/core';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const readAll = async () => {\n const directoryExists = await driver.fileExists(await itemsDirectoryPathPromise)\n .catch(() => false);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(await itemsDirectoryPathPromise);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(await itemsDirectoryPathPromise, relativePath);\n const itemsInFile = await driver.readObject(fullPath);\n if (!Array.isArray(itemsInFile))\n return;\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n await driver.removeEntry(indexPath, { recursive: true }).catch(() => { });\n await driver.ensureDir(indexPath);\n // Map<fieldValue, Set<identifier>>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n if (!indexMap.has(fieldValue))\n indexMap.set(fieldValue, new Set());\n indexMap.get(fieldValue)?.add(item.id);\n }\n // Persist as files keyed by safe value; keep original value stringified for lookup parity.\n const buckets = {};\n for (const [rawKey, identifiers] of indexMap) {\n const rawKeyString = String(rawKey);\n const key = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[key])\n buckets[key] = [];\n buckets[key].push({ [rawKeyString]: [...identifiers] });\n }\n await Promise.all(Object.entries(buckets).map(async ([key, maps]) => {\n const filePath = await driver.joinPath(indexPath, key);\n await driver.writeIndexObject(filePath, maps);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [key, identifiers] of Object.entries(entry)) {\n if (!resultIndex.has(key))\n resultIndex.set(key, new Set());\n for (const identifier of identifiers) {\n resultIndex.get(key)?.add(identifier);\n }\n }\n }\n }));\n return resultIndex;\n };\n const indicesToMaintain = [];\n const addToDelta = (deltas, field, kind, rawKey, id) => {\n if (!deltas.has(field))\n deltas.set(field, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(field);\n if (!delta)\n return;\n const target = kind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(id);\n };\n const addDeltaForChange = (deltas, field, oldValue, newValue, id) => {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, field, 'remove', oldKey, id);\n if (newKey != null)\n addToDelta(deltas, field, 'add', newKey, id);\n };\n const accumulateUpsertDelta = (deltas, existing, next) => {\n if (existing) {\n for (const field of indicesToMaintain) {\n addDeltaForChange(deltas, field, get(existing, field), get(next, field), next.id);\n }\n }\n else {\n for (const field of indicesToMaintain) {\n const value = get(next, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'add', String(value), next.id);\n }\n }\n };\n const accumulateRemoveDelta = (deltas, existing) => {\n for (const field of indicesToMaintain) {\n const value = get(existing, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'remove', String(value), existing.id);\n }\n };\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucket = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucket.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBuckets = new Set(rawKeyToBucket.values());\n await Promise.all([...touchedBuckets].map(async (bucket) => {\n const filePath = await driver.joinPath(indexPath, bucket);\n const data = await driver.readIndexObject(filePath);\n // Rehydrate only this bucket into a map of rawKey -> Set<I>\n const bucketIndex = new Map();\n if (Array.isArray(data)) {\n for (const entry of data) {\n for (const [rawKey, ids] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(ids));\n }\n }\n }\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n const set = bucketIndex.get(rawKey);\n if (!set)\n return;\n ids.forEach(id => set.delete(id));\n if (set.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n let set = bucketIndex.get(rawKey);\n if (!set) {\n set = new Set();\n bucketIndex.set(rawKey, set);\n }\n ids.forEach(id => set.add(id));\n });\n if (bucketIndex.size === 0) {\n const exists = await driver.fileExists(filePath).catch(() => false);\n if (exists)\n await driver.removeEntry(filePath).catch(() => { });\n return;\n }\n // Persist this bucket only\n const out = [];\n bucketIndex.forEach((set, rawKey) => {\n out.push({ [rawKey]: [...set] });\n });\n await driver.writeIndexObject(filePath, out);\n }));\n }));\n };\n // Shared item operations using the delta helpers\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (mode === 'insert') {\n if (index !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, undefined, item);\n await driver.writeObject(filePath, [...array, item]);\n }\n else {\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateUpsertDelta(deltas, array[index], item);\n const updated = [...array];\n updated[index] = item;\n await driver.writeObject(filePath, updated);\n }\n }));\n await applyIndexDeltas(deltas);\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const itemsInFile = await driver.readObject(filePath);\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const exists = await driver.fileExists(pathToDrop).catch(() => false);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, array[index]);\n const updated = [...array];\n updated.splice(index, 1);\n await (updated.length === 0\n ? driver.removeEntry(filePath)\n : driver.writeObject(filePath, updated));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await driver.fileExists(folderName).catch(() => false);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","readAll","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","fieldPath","itemsPromise","allItems","indexPath","indexMap","item","fieldValue","get","buckets","rawKey","identifiers","rawKeyString","key","maps","filePath","readIndex","resultIndex","entry","identifier","indicesToMaintain","addToDelta","deltas","field","kind","id","delta","target","addDeltaForChange","oldValue","newValue","oldKey","newKey","accumulateUpsertDelta","existing","next","value","accumulateRemoveDelta","applyIndexDeltas","touchedRawKeys","rawKeyToBucket","touchedBuckets","bucket","data","bucketIndex","ids","set","out","upsertItems","items","mode","array","index","x","updated","createStorageAdapter","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":"6QAQA,SAAwBA,EAAuBC,EAAQC,EAAY,CAC/D,MAAMC,EAA4BF,EAAO,SAASC,EAAY,OAAO,EAC/DE,EAAuBH,EAAO,SAASC,EAAY,OAAO,EAC1DG,EAAU,SAAY,CAGxB,GAAI,CAFoB,MAAMJ,EAAO,WAAW,MAAME,CAAyB,EAC1E,MAAM,IAAM,EAAK,EAElB,MAAO,CAAA,EACX,MAAMG,EAAgB,MAAML,EAAO,mBAAmB,MAAME,CAAyB,EAC/EI,EAAkB,CAAA,EACxB,aAAM,QAAQ,IAAID,EAAc,IAAI,MAAOE,GAAiB,CACxD,MAAMC,EAAW,MAAMR,EAAO,SAAS,MAAME,EAA2BK,CAAY,EAC9EE,EAAc,MAAMT,EAAO,WAAWQ,CAAQ,EAC/C,MAAM,QAAQC,CAAW,GAE9BH,EAAgB,KAAK,GAAGG,CAAW,CACvC,CAAC,CAAC,EACKH,CACX,EACMI,EAAc,MAAOC,EAAWC,EAAeR,MAAc,CAC/D,MAAMS,EAAW,MAAMD,EACjBE,EAAY,MAAMd,EAAO,SAAS,MAAMG,EAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC,EAC/G,MAAMX,EAAO,YAAYc,EAAW,CAAE,UAAW,EAAA,CAAM,EAAE,MAAM,IAAM,CAAE,CAAC,EACxE,MAAMd,EAAO,UAAUc,CAAS,EAEhC,MAAMC,MAAe,IACrB,UAAWC,KAAQH,EAAU,CACzB,MAAMI,EAAaC,EAAAA,IAAIF,EAAML,CAAS,EAClCM,GAAc,OAEbF,EAAS,IAAIE,CAAU,GACxBF,EAAS,IAAIE,EAAY,IAAI,GAAK,EACtCF,EAAS,IAAIE,CAAU,GAAG,IAAID,EAAK,EAAE,EACzC,CAEA,MAAMG,EAAU,CAAA,EAChB,SAAW,CAACC,EAAQC,CAAW,IAAKN,EAAU,CAC1C,MAAMO,EAAe,OAAOF,CAAM,EAC5BG,EAAM,MAAMvB,EAAO,oBAAoBsB,CAAY,EACpDH,EAAQI,CAAG,IACZJ,EAAQI,CAAG,EAAI,CAAA,GACnBJ,EAAQI,CAAG,EAAE,KAAK,CAAE,CAACD,CAAY,EAAG,CAAC,GAAGD,CAAW,EAAG,CAC1D,CACA,MAAM,QAAQ,IAAI,OAAO,QAAQF,CAAO,EAAE,IAAI,MAAO,CAACI,EAAKC,CAAI,IAAM,CACjE,MAAMC,EAAW,MAAMzB,EAAO,SAASc,EAAWS,CAAG,EACrD,MAAMvB,EAAO,iBAAiByB,EAAUD,CAAI,CAChD,CAAC,CAAC,CACN,EACME,EAAY,MAAOf,GAAc,CACnC,MAAMG,EAAY,MAAMd,EAAO,SAAS,MAAMG,EAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC,EAE/G,GAAI,CADgB,MAAMX,EAAO,WAAWc,CAAS,EAAE,MAAM,IAAM,EAAK,EAEpE,MAAM,IAAI,MAAM,mBAAmBH,CAAS,kBAAkB,EAClE,MAAMN,EAAgB,MAAML,EAAO,mBAAmBc,CAAS,EACzDa,MAAkB,IACxB,aAAM,QAAQ,IAAItB,EAAc,IAAI,MAAOE,GAAiB,CACxD,MAAMC,EAAW,MAAMR,EAAO,SAASc,EAAWP,CAAY,EACxDiB,EAAO,MAAMxB,EAAO,gBAAgBQ,CAAQ,EAClD,GAAK,MAAM,QAAQgB,CAAI,EAEvB,UAAWI,KAASJ,EAChB,SAAW,CAACD,EAAKF,CAAW,IAAK,OAAO,QAAQO,CAAK,EAAG,CAC/CD,EAAY,IAAIJ,CAAG,GACpBI,EAAY,IAAIJ,EAAK,IAAI,GAAK,EAClC,UAAWM,KAAcR,EACrBM,EAAY,IAAIJ,CAAG,GAAG,IAAIM,CAAU,CAE5C,CAER,CAAC,CAAC,EACKF,CACX,EACMG,EAAoB,CAAA,EACpBC,EAAa,CAACC,EAAQC,EAAOC,EAAMd,EAAQe,IAAO,CAC/CH,EAAO,IAAIC,CAAK,GACjBD,EAAO,IAAIC,EAAO,CAAE,KAAM,IAAI,IAAO,QAAS,IAAI,IAAO,EAC7D,MAAMG,EAAQJ,EAAO,IAAIC,CAAK,EAC9B,GAAI,CAACG,EACD,OACJ,MAAMC,EAASH,IAAS,MAAQE,EAAM,KAAOA,EAAM,QAC9CC,EAAO,IAAIjB,CAAM,GAClBiB,EAAO,IAAIjB,EAAQ,IAAI,GAAK,EAChCiB,EAAO,IAAIjB,CAAM,GAAG,IAAIe,CAAE,CAC9B,EACMG,EAAoB,CAACN,EAAQC,EAAOM,EAAUC,EAAUL,IAAO,CACjE,MAAMM,EAASF,GAAY,KAAO,OAAY,OAAOA,CAAQ,EACvDG,EAASF,GAAY,KAAO,OAAY,OAAOA,CAAQ,EACzDC,IAAWC,IAEXD,GAAU,MACVV,EAAWC,EAAQC,EAAO,SAAUQ,EAAQN,CAAE,EAC9CO,GAAU,MACVX,EAAWC,EAAQC,EAAO,MAAOS,EAAQP,CAAE,EACnD,EACMQ,EAAwB,CAACX,EAAQY,EAAUC,IAAS,CACtD,GAAID,EACA,UAAWX,KAASH,EAChBQ,EAAkBN,EAAQC,EAAOf,EAAAA,IAAI0B,EAAUX,CAAK,EAAGf,EAAAA,IAAI2B,EAAMZ,CAAK,EAAGY,EAAK,EAAE,MAIpF,WAAWZ,KAASH,EAAmB,CACnC,MAAMgB,EAAQ5B,EAAAA,IAAI2B,EAAMZ,CAAK,EACzBa,GAAS,MAEbf,EAAWC,EAAQC,EAAO,MAAO,OAAOa,CAAK,EAAGD,EAAK,EAAE,CAC3D,CAER,EACME,EAAwB,CAACf,EAAQY,IAAa,CAChD,UAAWX,KAASH,EAAmB,CACnC,MAAMgB,EAAQ5B,EAAAA,IAAI0B,EAAUX,CAAK,EAC7Ba,GAAS,MAEbf,EAAWC,EAAQC,EAAO,SAAU,OAAOa,CAAK,EAAGF,EAAS,EAAE,CAClE,CACJ,EACMI,EAAmB,MAAOhB,GAAW,CAEvC,MAAM,QAAQ,IAAI,CAAC,GAAGA,EAAO,SAAS,EAAE,IAAI,MAAO,CAACrB,EAAWyB,CAAK,IAAM,CACtE,MAAMtB,EAAY,MAAMd,EAAO,SAAS,MAAMG,EAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC,EAE/G,GAAI,CADgB,MAAMX,EAAO,WAAWc,CAAS,EAAE,MAAM,IAAM,EAAK,EAEpE,OACJ,MAAMd,EAAO,UAAUc,CAAS,EAEhC,MAAMmC,MAAqB,IAAI,CAC3B,GAAGb,EAAM,KAAK,KAAA,EACd,GAAGA,EAAM,QAAQ,KAAA,CAAK,CACzB,EACKc,MAAqB,IAC3B,MAAM,QAAQ,IAAI,CAAC,GAAGD,CAAc,EAAE,IAAI,MAAO7B,GAAW,CACxD8B,EAAe,IAAI9B,EAAQ,MAAMpB,EAAO,oBAAoBoB,CAAM,CAAC,CACvE,CAAC,CAAC,EACF,MAAM+B,EAAiB,IAAI,IAAID,EAAe,QAAQ,EACtD,MAAM,QAAQ,IAAI,CAAC,GAAGC,CAAc,EAAE,IAAI,MAAOC,GAAW,CACxD,MAAM3B,EAAW,MAAMzB,EAAO,SAASc,EAAWsC,CAAM,EAClDC,EAAO,MAAMrD,EAAO,gBAAgByB,CAAQ,EAE5C6B,MAAkB,IACxB,GAAI,MAAM,QAAQD,CAAI,EAClB,UAAWzB,KAASyB,EAChB,SAAW,CAACjC,EAAQmC,CAAG,IAAK,OAAO,QAAQ3B,CAAK,EAC5C0B,EAAY,IAAIlC,EAAQ,IAAI,IAAImC,CAAG,CAAC,EA0BhD,GArBAnB,EAAM,QAAQ,QAAQ,CAACmB,EAAKnC,IAAW,CACnC,GAAI8B,EAAe,IAAI9B,CAAM,IAAMgC,EAC/B,OACJ,MAAMI,EAAMF,EAAY,IAAIlC,CAAM,EAC7BoC,IAELD,EAAI,QAAQpB,GAAMqB,EAAI,OAAOrB,CAAE,CAAC,EAC5BqB,EAAI,OAAS,GACbF,EAAY,OAAOlC,CAAM,EACjC,CAAC,EAEDgB,EAAM,KAAK,QAAQ,CAACmB,EAAKnC,IAAW,CAChC,GAAI8B,EAAe,IAAI9B,CAAM,IAAMgC,EAC/B,OACJ,IAAII,EAAMF,EAAY,IAAIlC,CAAM,EAC3BoC,IACDA,MAAU,IACVF,EAAY,IAAIlC,EAAQoC,CAAG,GAE/BD,EAAI,QAAQpB,GAAMqB,EAAI,IAAIrB,CAAE,CAAC,CACjC,CAAC,EACGmB,EAAY,OAAS,EAAG,CACT,MAAMtD,EAAO,WAAWyB,CAAQ,EAAE,MAAM,IAAM,EAAK,GAE9D,MAAMzB,EAAO,YAAYyB,CAAQ,EAAE,MAAM,IAAM,CAAE,CAAC,EACtD,MACJ,CAEA,MAAMgC,EAAM,CAAA,EACZH,EAAY,QAAQ,CAACE,EAAKpC,IAAW,CACjCqC,EAAI,KAAK,CAAE,CAACrC,CAAM,EAAG,CAAC,GAAGoC,CAAG,EAAG,CACnC,CAAC,EACD,MAAMxD,EAAO,iBAAiByB,EAAUgC,CAAG,CAC/C,CAAC,CAAC,CACN,CAAC,CAAC,CACN,EAEMC,EAAc,MAAOC,EAAOC,IAAS,CACvC,MAAM5B,MAAa,IACnB,MAAM,QAAQ,IAAI2B,EAAM,IAAI,MAAO3C,GAAS,CACxC,MAAMS,EAAW,MAAMzB,EAAO,SAAS,MAAME,EAA2B,MAAMF,EAAO,cAAcgB,EAAK,EAAE,CAAC,EACrG4B,EAAW,MAAM5C,EAAO,WAAWyB,CAAQ,EAC3CoC,EAAQ,MAAM,QAAQjB,CAAQ,EAAIA,EAAW,CAAA,EAC7CkB,EAAQD,EAAM,aAAeE,EAAE,KAAO/C,EAAK,EAAE,EACnD,GAAI4C,IAAS,SAAU,CACnB,GAAIE,IAAU,GACV,MAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB,EACtE2B,EAAsBX,EAAQ,OAAWhB,CAAI,EAC7C,MAAMhB,EAAO,YAAYyB,EAAU,CAAC,GAAGoC,EAAO7C,CAAI,CAAC,CACvD,KACK,CACD,GAAI8C,IAAU,GACV,MAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB,EACtE2B,EAAsBX,EAAQ6B,EAAMC,CAAK,EAAG9C,CAAI,EAChD,MAAMgD,EAAU,CAAC,GAAGH,CAAK,EACzBG,EAAQF,CAAK,EAAI9C,EACjB,MAAMhB,EAAO,YAAYyB,EAAUuC,CAAO,CAC9C,CACJ,CAAC,CAAC,EACF,MAAMhB,EAAiBhB,CAAM,CACjC,EACA,OAAOiC,uBAAqB,CACxB,MAAO,SAAY,CACf,MAAMjE,EAAO,UAAUC,CAAU,CACrC,EACA,SAAU,SAAY,CAEtB,EACA,QAAAG,EACA,QAAS,MAAOiB,IACI,MAAM,QAAQ,IAAIA,EAAY,IAAI,MAAOQ,GAAe,CACpE,MAAMJ,EAAW,MAAMzB,EAAO,SAAS,MAAME,EAA2B,MAAMF,EAAO,cAAc6B,CAAU,CAAC,EACxGpB,EAAc,MAAMT,EAAO,WAAWyB,CAAQ,EACpD,OAAK,MAAM,QAAQhB,CAAW,EAEvBA,EAAY,KAAKO,GAAQA,EAAK,KAAOa,CAAU,GAAK,KADhD,IAEf,CAAC,CAAC,GACa,OAAQiB,GAAUA,GAAS,IAAI,EAElD,YAAa,MAAOnC,GAAc,CAC9BmB,EAAkB,KAAKnB,CAAS,EAChC,MAAMD,EAAYC,CAAS,CAC/B,EACA,UAAW,MAAOA,GAAc,CAC5B,MAAMuD,EAAa,MAAMlE,EAAO,SAAS,MAAMG,EAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC,EAEhH,GAAI,CADW,MAAMX,EAAO,WAAWkE,CAAU,EAAE,MAAM,IAAM,EAAK,EAEhE,MAAM,IAAI,MAAM,mBAAmBvD,CAAS,kBAAkB,EAClE,MAAMX,EAAO,YAAYkE,EAAY,CAAE,UAAW,GAAM,CAC5D,EACA,UAAAxC,EACA,OAAQ,MAAOyC,GAAkB,CAC7B,MAAMT,EAAYS,EAAe,QAAQ,CAC7C,EACA,QAAS,MAAOC,GAAmB,CAC/B,MAAMV,EAAYU,EAAgB,SAAS,CAC/C,EACA,OAAQ,MAAOC,GAAkB,CAC7B,MAAMrC,MAAa,IACnB,MAAM,QAAQ,IAAIqC,EAAc,IAAI,MAAOrD,GAAS,CAChD,MAAMS,EAAW,MAAMzB,EAAO,SAAS,MAAME,EAA2B,MAAMF,EAAO,cAAcgB,EAAK,EAAE,CAAC,EACrG4B,EAAW,MAAM5C,EAAO,WAAWyB,CAAQ,EAC3CoC,EAAQ,MAAM,QAAQjB,CAAQ,EAAIA,EAAW,CAAA,EAC7CkB,EAAQD,EAAM,aAAeE,EAAE,KAAO/C,EAAK,EAAE,EACnD,GAAI8C,IAAU,GACV,MAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB,EACtE+B,EAAsBf,EAAQ6B,EAAMC,CAAK,CAAC,EAC1C,MAAME,EAAU,CAAC,GAAGH,CAAK,EACzBG,EAAQ,OAAOF,EAAO,CAAC,EACvB,MAAOE,EAAQ,SAAW,EACpBhE,EAAO,YAAYyB,CAAQ,EAC3BzB,EAAO,YAAYyB,EAAUuC,CAAO,EAC9C,CAAC,CAAC,EACF,MAAMhB,EAAiBhB,CAAM,CACjC,EACA,UAAW,SAAY,CACJ,MAAMhC,EAAO,WAAWC,CAAU,EAAE,MAAM,IAAM,EAAK,GAGpE,MAAMD,EAAO,YAAYC,EAAY,CAAE,UAAW,GAAM,CAC5D,CAAA,CACH,CACL"}
|
|
1
|
+
{"version":3,"file":"index.umd.js","sources":["../src/deltaHelpers.ts","../src/index.ts"],"sourcesContent":["import { get } from '@signaldb/core';\n/**\n * Records a single index mutation into the delta map for a given indexed field.\n *\n * The delta map is grouped by `fieldPath`, and then by stringified key (`rawKey`).\n * Each key maps to a set of identifiers to add/remove for that key.\n * @param deltas - Accumulator of per-field index deltas.\n * @param fieldPath - Dot-path of the indexed field (used as the delta bucket key).\n * @param changeKind - Whether this identifier should be added to or removed from the index key.\n * @param rawKey - The stringified index key value.\n * @param identifier - The item identifier to add/remove for `rawKey`.\n */\nexport function addToDelta(deltas, fieldPath, changeKind, rawKey, identifier) {\n if (!deltas.has(fieldPath))\n deltas.set(fieldPath, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(fieldPath);\n if (!delta)\n return;\n const target = changeKind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(identifier);\n}\n/**\n * Computes the delta for a change in a single indexed field.\n *\n * Values are coerced to string keys (with `null`/`undefined` treated as \"no key\").\n * If the derived keys are equal, no delta is recorded.\n * @param deltas - Accumulator of per-field index deltas.\n * @param fieldPath - Dot-path of the indexed field being tracked.\n * @param oldValue - Previous value of the field.\n * @param newValue - Next value of the field.\n * @param identifier - The item identifier affected by the change.\n */\nexport function addDeltaForChange(deltas, fieldPath, oldValue, newValue, identifier) {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, fieldPath, 'remove', oldKey, identifier);\n if (newKey != null)\n addToDelta(deltas, fieldPath, 'add', newKey, identifier);\n}\n/**\n * Accumulates index deltas for an upsert operation.\n *\n * - If `existingItem` is present, compares each maintained index field between the old and new item,\n * recording removes/adds for key changes.\n * - If `existingItem` is absent, treats the operation as an insert and records adds for each\n * maintained index field that has a non-null value.\n * @param deltas - Accumulator of per-field index deltas.\n * @param indicesToMaintain - List of dot-paths for fields that are indexed.\n * @param existingItem - Previous stored item (if any).\n * @param nextItem - Incoming item to upsert.\n */\nexport const accumulateUpsertDelta = (deltas, indicesToMaintain, existingItem, nextItem) => {\n if (existingItem) {\n for (const fieldPath of indicesToMaintain) {\n addDeltaForChange(deltas, fieldPath, get(existingItem, fieldPath), get(nextItem, fieldPath), nextItem.id);\n }\n }\n else {\n for (const fieldPath of indicesToMaintain) {\n const value = get(nextItem, fieldPath);\n if (value == null)\n continue;\n addToDelta(deltas, fieldPath, 'add', String(value), nextItem.id);\n }\n }\n};\n/**\n * Accumulates index deltas for a remove/delete operation.\n *\n * For each maintained index field, records a removal of the item's identifier from the\n * corresponding stringified key (skipping `null`/`undefined` values).\n * @param deltas - Accumulator of per-field index deltas.\n * @param indicesToMaintain - List of dot-paths for fields that are indexed.\n * @param existingItem - The item being removed.\n */\nexport function accumulateRemoveDelta(deltas, indicesToMaintain, existingItem) {\n for (const fieldPath of indicesToMaintain) {\n const value = get(existingItem, fieldPath);\n if (value == null)\n continue;\n addToDelta(deltas, fieldPath, 'remove', String(value), existingItem.id);\n }\n}\n","import { createStorageAdapter, get } from '@signaldb/core';\nimport { accumulateUpsertDelta, accumulateRemoveDelta, } from './deltaHelpers';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const safeFileExists = async (path) => driver.fileExists(path).catch(() => false);\n const safeRemoveEntry = async (path, options) => driver.removeEntry(path, options).catch(() => { });\n const toItemsFilePath = async (identifier) => driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const toIndexPathForField = async (fieldPath) => driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const toIndexBucketFilePath = async (indexPath, rawKey) => {\n const bucketFileName = await driver.fileNameForIndexKey(rawKey);\n return driver.joinPath(indexPath, bucketFileName);\n };\n const readItemsArrayOrEmpty = async (filePath) => {\n const exists = await safeFileExists(filePath);\n if (!exists)\n return [];\n const data = await driver.readObject(filePath).catch(() => []);\n return Array.isArray(data) ? data : [];\n };\n const loadBucketIndexFromData = (data) => {\n const bucketIndex = new Map();\n if (!Array.isArray(data))\n return bucketIndex;\n for (const entry of data) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(identifierList));\n }\n }\n return bucketIndex;\n };\n const writeBucketIndex = async (filePath, bucketIndex) => {\n if (bucketIndex.size === 0) {\n const exists = await safeFileExists(filePath);\n if (exists)\n await safeRemoveEntry(filePath);\n return;\n }\n const output = [];\n bucketIndex.forEach((identifierSet, rawKey) => {\n output.push({ [rawKey]: [...identifierSet] });\n });\n await driver.writeIndexObject(filePath, output);\n };\n const readBucketIndex = async (filePath) => {\n const data = await driver.readIndexObject(filePath).catch(() => null);\n return loadBucketIndexFromData(data);\n };\n const readAll = async () => {\n const itemsDirectoryPath = await itemsDirectoryPathPromise;\n const directoryExists = await safeFileExists(itemsDirectoryPath);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(itemsDirectoryPath);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(itemsDirectoryPath, relativePath);\n const itemsInFile = await driver.readObject(fullPath).catch(() => null);\n if (Array.isArray(itemsInFile))\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await toIndexPathForField(fieldPath);\n await safeRemoveEntry(indexPath, { recursive: true });\n await driver.ensureDir(indexPath);\n // Build value -> Set<identifier>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n const keyString = String(fieldValue);\n if (!indexMap.has(keyString))\n indexMap.set(keyString, new Set());\n indexMap.get(keyString)?.add(item.id);\n }\n // Group entries by bucket file name, then persist each bucket\n const buckets = {};\n for (const [rawKeyString, identifierSet] of indexMap) {\n const bucketFileName = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[bucketFileName])\n buckets[bucketFileName] = [];\n buckets[bucketFileName].push({ [rawKeyString]: [...identifierSet] });\n }\n await Promise.all(Object.entries(buckets).map(async ([bucketFileName, records]) => {\n const filePath = await driver.joinPath(indexPath, bucketFileName);\n await driver.writeIndexObject(filePath, records);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath).catch(() => null);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n if (!resultIndex.has(rawKey))\n resultIndex.set(rawKey, new Set());\n const target = resultIndex.get(rawKey);\n for (const identifier of identifierList)\n target?.add(identifier);\n }\n }\n }));\n return resultIndex;\n };\n // Track which field paths should be kept up-to-date incrementally.\n const indicesToMaintain = [];\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucketFileName = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucketFileName.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBucketFileNames = new Set(rawKeyToBucketFileName.values());\n await Promise.all([...touchedBucketFileNames].map(async (bucketFileName) => {\n const filePath = await driver.joinPath(indexPath, bucketFileName);\n const bucketIndex = await readBucketIndex(filePath);\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((identifierSet, rawKey) => {\n if (rawKeyToBucketFileName.get(rawKey) !== bucketFileName)\n return;\n const setForKey = bucketIndex.get(rawKey);\n if (!setForKey)\n return;\n identifierSet.forEach(identifier => setForKey.delete(identifier));\n if (setForKey.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((identifierSet, rawKey) => {\n if (rawKeyToBucketFileName.get(rawKey) !== bucketFileName)\n return;\n const setForKey = bucketIndex.get(rawKey) ?? new Set();\n identifierSet.forEach(identifier => setForKey.add(identifier));\n bucketIndex.set(rawKey, setForKey);\n });\n await writeBucketIndex(filePath, bucketIndex);\n }));\n }));\n };\n const removeIdFromIndex = async (fieldPath, identifier) => {\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return;\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const filePath = await driver.joinPath(indexPath, relativePath);\n const data = await driver.readIndexObject(filePath).catch(() => null);\n if (!Array.isArray(data))\n return;\n let changed = false;\n const bucketIndex = new Map();\n for (const entry of data) {\n for (const [rawKey, identifierList] of Object.entries(entry)) {\n const set = new Set(identifierList);\n const before = set.size;\n set.delete(identifier);\n if (set.size !== before)\n changed = true;\n if (set.size > 0)\n bucketIndex.set(rawKey, set);\n }\n }\n if (!changed)\n return;\n await writeBucketIndex(filePath, bucketIndex);\n }));\n };\n const addIdToIndex = async (fieldPath, value, identifier) => {\n if (value == null)\n return;\n const rawKey = String(value);\n const indexPath = await toIndexPathForField(fieldPath);\n const indexExists = await safeFileExists(indexPath);\n if (!indexExists)\n return;\n await driver.ensureDir(indexPath);\n const filePath = await toIndexBucketFilePath(indexPath, rawKey);\n const bucketIndex = await readBucketIndex(filePath);\n const setForKey = bucketIndex.get(rawKey) ?? new Set();\n setForKey.add(identifier);\n bucketIndex.set(rawKey, setForKey);\n await writeBucketIndex(filePath, bucketIndex);\n };\n const updateIndexForReplace = async (oldItem, nextItem) => {\n await Promise.all(indicesToMaintain.map(async (fieldPath) => {\n await removeIdFromIndex(fieldPath, oldItem.id);\n const newValue = get(nextItem, fieldPath);\n await addIdToIndex(fieldPath, newValue, nextItem.id);\n }));\n };\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await toItemsFilePath(item.id);\n const existingArray = await readItemsArrayOrEmpty(filePath);\n const indexOfItem = existingArray.findIndex(existing => existing.id === item.id);\n if (mode === 'insert') {\n if (indexOfItem !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, indicesToMaintain, undefined, item);\n await driver.writeObject(filePath, [...existingArray, item]);\n }\n else {\n if (indexOfItem === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n const updatedArray = [...existingArray];\n const oldItem = updatedArray[indexOfItem];\n updatedArray[indexOfItem] = item;\n await driver.writeObject(filePath, updatedArray);\n await updateIndexForReplace(oldItem, item);\n }\n }));\n // Only apply deltas for inserts (replace handled by direct purge+add)\n if (deltas.size > 0) {\n await applyIndexDeltas(deltas);\n }\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await toItemsFilePath(identifier);\n const itemsInFile = await driver.readObject(filePath).catch(() => []) ?? [];\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n if (fieldPath === 'id')\n throw new Error('Cannot create index on id field');\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await toIndexPathForField(fieldPath);\n const exists = await safeFileExists(pathToDrop);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await toItemsFilePath(item.id);\n const existingArray = await readItemsArrayOrEmpty(filePath);\n const indexOfItem = existingArray.findIndex(existing => existing.id === item.id);\n if (indexOfItem === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, indicesToMaintain, existingArray[indexOfItem]);\n const updatedArray = [...existingArray];\n updatedArray.splice(indexOfItem, 1);\n await (updatedArray.length === 0\n ? driver.removeEntry(filePath).catch(() => { })\n : driver.writeObject(filePath, updatedArray));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await safeFileExists(folderName);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["addToDelta","deltas","fieldPath","changeKind","rawKey","identifier","delta","target","accumulateUpsertDelta","indicesToMaintain","existingItem","nextItem","value","get","accumulateRemoveDelta","createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","safeFileExists","path","safeRemoveEntry","options","toItemsFilePath","toIndexPathForField","toIndexBucketFilePath","indexPath","bucketFileName","readItemsArrayOrEmpty","filePath","data","loadBucketIndexFromData","bucketIndex","entry","identifierList","writeBucketIndex","output","identifierSet","readBucketIndex","readAll","itemsDirectoryPath","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","itemsPromise","allItems","indexMap","item","fieldValue","keyString","buckets","rawKeyString","records","readIndex","resultIndex","maps","applyIndexDeltas","touchedRawKeys","rawKeyToBucketFileName","touchedBucketFileNames","setForKey","removeIdFromIndex","changed","set","before","addIdToIndex","updateIndexForReplace","oldItem","newValue","upsertItems","items","mode","existingArray","indexOfItem","existing","updatedArray","createStorageAdapter","identifiers","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signaldb/generic-fs",
|
|
3
|
-
"version": "2.0.0-beta.
|
|
3
|
+
"version": "2.0.0-beta.2",
|
|
4
4
|
"description": "",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "rimraf dist && vite build",
|
|
@@ -54,6 +54,6 @@
|
|
|
54
54
|
"dist"
|
|
55
55
|
],
|
|
56
56
|
"peerDependencies": {
|
|
57
|
-
"@signaldb/core": "2.0.0-beta.
|
|
57
|
+
"@signaldb/core": "2.0.0-beta.2"
|
|
58
58
|
}
|
|
59
59
|
}
|