@signaldb/generic-fs 2.0.0-beta.1 → 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.
@@ -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,195 +1,198 @@
1
- import { createStorageAdapter as C, get as P } from "@signaldb/core";
2
- function U(s, m) {
3
- const F = s.joinPath(m, "items"), M = s.joinPath(m, "index"), u = async (t) => s.fileExists(t).catch(() => !1), j = async (t, n) => s.removeEntry(t, n).catch(() => {
4
- }), g = async (t) => s.joinPath(await F, await s.fileNameForId(t)), h = async (t) => s.joinPath(await M, await s.fileNameForIndexKey(t)), R = async (t, n) => {
5
- const e = await s.fileNameForIndexKey(n);
6
- return s.joinPath(t, e);
7
- }, A = async (t) => {
8
- if (!await u(t))
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))
9
29
  return [];
10
- const e = await s.readObject(t).catch(() => []);
11
- return Array.isArray(e) ? e : [];
30
+ const a = await e.readObject(t).catch(() => []);
31
+ return Array.isArray(a) ? a : [];
12
32
  }, K = (t) => {
13
33
  const n = /* @__PURE__ */ new Map();
14
34
  if (!Array.isArray(t))
15
35
  return n;
16
- for (const e of t)
17
- for (const [a, i] of Object.entries(e))
18
- n.set(a, new Set(i));
36
+ for (const a of t)
37
+ for (const [s, i] of Object.entries(a))
38
+ n.set(s, new Set(i));
19
39
  return n;
20
- }, E = async (t, n) => {
40
+ }, A = async (t, n) => {
21
41
  if (n.size === 0) {
22
- await u(t) && await j(t);
42
+ await l(t) && await x(t);
23
43
  return;
24
44
  }
25
- const e = [];
26
- n.forEach((a, i) => {
27
- e.push({ [i]: [...a] });
28
- }), await s.writeIndexObject(t, e);
29
- }, S = async (t) => {
30
- const n = await s.readIndexObject(t).catch(() => null);
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);
31
51
  return K(n);
32
- }, b = async () => {
33
- const t = await F;
34
- if (!await u(t))
52
+ }, O = async () => {
53
+ const t = await p;
54
+ if (!await l(t))
35
55
  return [];
36
- const e = await s.listFilesRecursive(t), a = [];
37
- return await Promise.all(e.map(async (i) => {
38
- const c = await s.joinPath(t, i), o = await s.readObject(c).catch(() => null);
39
- Array.isArray(o) && a.push(...o);
40
- })), a;
41
- }, z = async (t, n = b()) => {
42
- const e = await n, a = await h(t);
43
- await j(a, { recursive: !0 }), await s.ensureDir(a);
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);
60
+ })), s;
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);
44
64
  const i = /* @__PURE__ */ new Map();
45
- for (const o of e) {
46
- const r = P(o, t);
47
- if (r == null)
65
+ for (const o of a) {
66
+ const c = j(o, t);
67
+ if (c == null)
48
68
  continue;
49
- const w = String(r);
50
- i.has(w) || i.set(w, /* @__PURE__ */ new Set()), i.get(w)?.add(o.id);
69
+ const r = String(c);
70
+ i.has(r) || i.set(r, /* @__PURE__ */ new Set()), i.get(r)?.add(o.id);
51
71
  }
52
- const c = {};
53
- for (const [o, r] of i) {
54
- const w = await s.fileNameForIndexKey(o);
55
- c[w] || (c[w] = []), c[w].push({ [o]: [...r] });
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] });
56
76
  }
57
- await Promise.all(Object.entries(c).map(async ([o, r]) => {
58
- const w = await s.joinPath(a, o);
59
- await s.writeIndexObject(w, r);
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);
60
80
  }));
61
81
  }, B = async (t) => {
62
- const n = await h(t);
63
- if (!await u(n))
82
+ const n = await g(t);
83
+ if (!await l(n))
64
84
  throw new Error(`Index on field "${t}" does not exist`);
65
- const a = await s.listFilesRecursive(n), i = /* @__PURE__ */ new Map();
66
- return await Promise.all(a.map(async (c) => {
67
- const o = await s.joinPath(n, c), r = await s.readIndexObject(o).catch(() => null);
68
- if (Array.isArray(r))
69
- for (const w of r)
70
- for (const [f, y] of Object.entries(w)) {
71
- i.has(f) || i.set(f, /* @__PURE__ */ new Set());
72
- const x = i.get(f);
73
- for (const d of y)
74
- x?.add(d);
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);
75
95
  }
76
96
  })), i;
77
- }, I = [], O = (t, n, e, a, i) => {
78
- t.has(n) || t.set(n, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });
79
- const c = t.get(n);
80
- if (!c)
81
- return;
82
- const o = e === "add" ? c.adds : c.removes;
83
- o.has(a) || o.set(a, /* @__PURE__ */ new Set()), o.get(a)?.add(i);
84
- }, T = (t, n, e) => {
85
- for (const a of I) {
86
- const i = P(e, a);
87
- i != null && O(t, a, "add", String(i), e.id);
88
- }
89
- }, $ = (t, n) => {
90
- for (const e of I) {
91
- const a = P(n, e);
92
- a != null && O(t, e, "remove", String(a), n.id);
93
- }
94
- }, k = async (t) => {
95
- await Promise.all([...t.entries()].map(async ([n, e]) => {
96
- const a = await h(n);
97
- if (!await u(a))
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))
98
101
  return;
99
- await s.ensureDir(a);
100
- const c = /* @__PURE__ */ new Set([
101
- ...e.adds.keys(),
102
- ...e.removes.keys()
102
+ await e.ensureDir(s);
103
+ const w = /* @__PURE__ */ new Set([
104
+ ...a.adds.keys(),
105
+ ...a.removes.keys()
103
106
  ]), o = /* @__PURE__ */ new Map();
104
- await Promise.all([...c].map(async (w) => {
105
- o.set(w, await s.fileNameForIndexKey(w));
107
+ await Promise.all([...w].map(async (r) => {
108
+ o.set(r, await e.fileNameForIndexKey(r));
106
109
  }));
107
- const r = new Set(o.values());
108
- await Promise.all([...r].map(async (w) => {
109
- const f = await s.joinPath(a, w), y = await S(f);
110
- e.removes.forEach((x, d) => {
111
- if (o.get(d) !== 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)
112
115
  return;
113
- const l = y.get(d);
114
- l && (x.forEach((p) => l.delete(p)), l.size === 0 && y.delete(d));
115
- }), e.adds.forEach((x, d) => {
116
- if (o.get(d) !== w)
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)
117
120
  return;
118
- const l = y.get(d) ?? /* @__PURE__ */ new Set();
119
- x.forEach((p) => l.add(p)), y.set(d, l);
120
- }), await E(f, y);
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);
121
124
  }));
122
125
  }));
123
- }, L = async (t, n) => {
124
- const e = await h(t);
125
- if (!await u(e))
126
+ }, T = async (t, n) => {
127
+ const a = await g(t);
128
+ if (!await l(a))
126
129
  return;
127
- const i = await s.listFilesRecursive(e);
128
- await Promise.all(i.map(async (c) => {
129
- const o = await s.joinPath(e, c), r = await s.readIndexObject(o).catch(() => null);
130
- if (!Array.isArray(r))
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))
131
134
  return;
132
- let w = !1;
133
- const f = /* @__PURE__ */ new Map();
134
- for (const y of r)
135
- for (const [x, d] of Object.entries(y)) {
136
- const l = new Set(d), p = l.size;
137
- l.delete(n), l.size !== p && (w = !0), l.size > 0 && f.set(x, l);
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);
138
141
  }
139
- w && await E(o, f);
142
+ r && await A(o, h);
140
143
  }));
141
- }, N = async (t, n, e) => {
144
+ }, $ = async (t, n, a) => {
142
145
  if (n == null)
143
146
  return;
144
- const a = String(n), i = await h(t);
145
- if (!await u(i))
147
+ const s = String(n), i = await g(t);
148
+ if (!await l(i))
146
149
  return;
147
- await s.ensureDir(i);
148
- const o = await R(i, a), r = await S(o), w = r.get(a) ?? /* @__PURE__ */ new Set();
149
- w.add(e), r.set(a, w), await E(o, r);
150
- }, V = async (t, n) => {
151
- await Promise.all(I.map(async (e) => {
152
- await L(e, t.id);
153
- const a = P(n, e);
154
- await N(e, a, n.id);
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);
155
158
  }));
156
159
  }, D = async (t, n) => {
157
- const e = /* @__PURE__ */ new Map();
158
- await Promise.all(t.map(async (a) => {
159
- const i = await g(a.id), c = await A(i), o = c.findIndex((r) => r.id === a.id);
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);
160
163
  if (n === "insert") {
161
164
  if (o !== -1)
162
- throw new Error(`Item with id "${String(a.id)}" already exists`);
163
- T(e, void 0, a), await s.writeObject(i, [...c, a]);
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]);
164
167
  } else {
165
168
  if (o === -1)
166
- throw new Error(`Item with id "${String(a.id)}" does not exist`);
167
- const r = [...c], w = r[o];
168
- r[o] = a, await s.writeObject(i, r), await V(w, a);
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);
169
172
  }
170
- })), e.size > 0 && await k(e);
173
+ })), a.size > 0 && await k(a);
171
174
  };
172
- return C({
175
+ return N({
173
176
  setup: async () => {
174
- await s.ensureDir(m);
177
+ await e.ensureDir(d);
175
178
  },
176
179
  teardown: async () => {
177
180
  },
178
- readAll: b,
179
- readIds: async (t) => (await Promise.all(t.map(async (e) => {
180
- const a = await g(e), i = await s.readObject(a).catch(() => []) ?? [];
181
- return Array.isArray(i) ? i.find((c) => c.id === e) ?? null : null;
182
- }))).filter((e) => e != null),
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),
183
186
  createIndex: async (t) => {
184
187
  if (t === "id")
185
188
  throw new Error("Cannot create index on id field");
186
- I.push(t), await z(t);
189
+ F.push(t), await z(t);
187
190
  },
188
191
  dropIndex: async (t) => {
189
- const n = await h(t);
190
- if (!await u(n))
192
+ const n = await g(t);
193
+ if (!await l(n))
191
194
  throw new Error(`Index on field "${t}" does not exist`);
192
- await s.removeEntry(n, { recursive: !0 });
195
+ await e.removeEntry(n, { recursive: !0 });
193
196
  },
194
197
  readIndex: B,
195
198
  insert: async (t) => {
@@ -200,18 +203,18 @@ function U(s, m) {
200
203
  },
201
204
  remove: async (t) => {
202
205
  const n = /* @__PURE__ */ new Map();
203
- await Promise.all(t.map(async (e) => {
204
- const a = await g(e.id), i = await A(a), c = i.findIndex((r) => r.id === e.id);
205
- if (c === -1)
206
- throw new Error(`Item with id "${String(e.id)}" does not exist`);
207
- $(n, i[c]);
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]);
208
211
  const o = [...i];
209
- o.splice(c, 1), await (o.length === 0 ? s.removeEntry(a).catch(() => {
210
- }) : s.writeObject(a, o));
212
+ o.splice(w, 1), await (o.length === 0 ? e.removeEntry(s).catch(() => {
213
+ }) : e.writeObject(s, o));
211
214
  })), await k(n);
212
215
  },
213
216
  removeAll: async () => {
214
- await u(m) && await s.removeEntry(m, { recursive: !0 });
217
+ await l(d) && await e.removeEntry(d, { recursive: !0 });
215
218
  }
216
219
  });
217
220
  }
@@ -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 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 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 const 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 const accumulateUpsertDelta = (deltas, 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 const accumulateRemoveDelta = (deltas, 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 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, 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, 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":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","safeFileExists","path","safeRemoveEntry","options","toItemsFilePath","identifier","toIndexPathForField","fieldPath","toIndexBucketFilePath","indexPath","rawKey","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","get","keyString","buckets","rawKeyString","records","readIndex","resultIndex","maps","target","indicesToMaintain","addToDelta","deltas","changeKind","delta","accumulateUpsertDelta","existingItem","nextItem","value","accumulateRemoveDelta","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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"}
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(u,p){typeof exports=="object"&&typeof module<"u"?module.exports=p(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],p):(u=typeof globalThis<"u"?globalThis:u||self,u.SignalDB=p(u.core))})(this,(function(u){"use strict";function p(s,I){const j=s.joinPath(I,"items"),R=s.joinPath(I,"index"),f=async t=>s.fileExists(t).catch(()=>!1),b=async(t,n)=>s.removeEntry(t,n).catch(()=>{}),E=async t=>s.joinPath(await j,await s.fileNameForId(t)),m=async t=>s.joinPath(await R,await s.fileNameForIndexKey(t)),B=async(t,n)=>{const e=await s.fileNameForIndexKey(n);return s.joinPath(t,e)},S=async t=>{if(!await f(t))return[];const e=await s.readObject(t).catch(()=>[]);return Array.isArray(e)?e:[]},K=t=>{const n=new Map;if(!Array.isArray(t))return n;for(const e of t)for(const[a,i]of Object.entries(e))n.set(a,new Set(i));return n},F=async(t,n)=>{if(n.size===0){await f(t)&&await b(t);return}const e=[];n.forEach((a,i)=>{e.push({[i]:[...a]})}),await s.writeIndexObject(t,e)},A=async t=>{const n=await s.readIndexObject(t).catch(()=>null);return K(n)},O=async()=>{const t=await j;if(!await f(t))return[];const e=await s.listFilesRecursive(t),a=[];return await Promise.all(e.map(async i=>{const c=await s.joinPath(t,i),o=await s.readObject(c).catch(()=>null);Array.isArray(o)&&a.push(...o)})),a},T=async(t,n=O())=>{const e=await n,a=await m(t);await b(a,{recursive:!0}),await s.ensureDir(a);const i=new Map;for(const o of e){const r=u.get(o,t);if(r==null)continue;const w=String(r);i.has(w)||i.set(w,new Set),i.get(w)?.add(o.id)}const c={};for(const[o,r]of i){const w=await s.fileNameForIndexKey(o);c[w]||(c[w]=[]),c[w].push({[o]:[...r]})}await Promise.all(Object.entries(c).map(async([o,r])=>{const w=await s.joinPath(a,o);await s.writeIndexObject(w,r)}))},z=async t=>{const n=await m(t);if(!await f(n))throw new Error(`Index on field "${t}" does not exist`);const a=await s.listFilesRecursive(n),i=new Map;return await Promise.all(a.map(async c=>{const o=await s.joinPath(n,c),r=await s.readIndexObject(o).catch(()=>null);if(Array.isArray(r))for(const w of r)for(const[y,x]of Object.entries(w)){i.has(y)||i.set(y,new Set);const h=i.get(y);for(const l of x)h?.add(l)}})),i},P=[],k=(t,n,e,a,i)=>{t.has(n)||t.set(n,{adds:new Map,removes:new Map});const c=t.get(n);if(!c)return;const o=e==="add"?c.adds:c.removes;o.has(a)||o.set(a,new Set),o.get(a)?.add(i)},$=(t,n,e)=>{for(const a of P){const i=u.get(e,a);i!=null&&k(t,a,"add",String(i),e.id)}},L=(t,n)=>{for(const e of P){const a=u.get(n,e);a!=null&&k(t,e,"remove",String(a),n.id)}},D=async t=>{await Promise.all([...t.entries()].map(async([n,e])=>{const a=await m(n);if(!await f(a))return;await s.ensureDir(a);const c=new Set([...e.adds.keys(),...e.removes.keys()]),o=new Map;await Promise.all([...c].map(async w=>{o.set(w,await s.fileNameForIndexKey(w))}));const r=new Set(o.values());await Promise.all([...r].map(async w=>{const y=await s.joinPath(a,w),x=await A(y);e.removes.forEach((h,l)=>{if(o.get(l)!==w)return;const d=x.get(l);d&&(h.forEach(g=>d.delete(g)),d.size===0&&x.delete(l))}),e.adds.forEach((h,l)=>{if(o.get(l)!==w)return;const d=x.get(l)??new Set;h.forEach(g=>d.add(g)),x.set(l,d)}),await F(y,x)}))}))},N=async(t,n)=>{const e=await m(t);if(!await f(e))return;const i=await s.listFilesRecursive(e);await Promise.all(i.map(async c=>{const o=await s.joinPath(e,c),r=await s.readIndexObject(o).catch(()=>null);if(!Array.isArray(r))return;let w=!1;const y=new Map;for(const x of r)for(const[h,l]of Object.entries(x)){const d=new Set(l),g=d.size;d.delete(n),d.size!==g&&(w=!0),d.size>0&&y.set(h,d)}w&&await F(o,y)}))},V=async(t,n,e)=>{if(n==null)return;const a=String(n),i=await m(t);if(!await f(i))return;await s.ensureDir(i);const o=await B(i,a),r=await A(o),w=r.get(a)??new Set;w.add(e),r.set(a,w),await F(o,r)},q=async(t,n)=>{await Promise.all(P.map(async e=>{await N(e,t.id);const a=u.get(n,e);await V(e,a,n.id)}))},M=async(t,n)=>{const e=new Map;await Promise.all(t.map(async a=>{const i=await E(a.id),c=await S(i),o=c.findIndex(r=>r.id===a.id);if(n==="insert"){if(o!==-1)throw new Error(`Item with id "${String(a.id)}" already exists`);$(e,void 0,a),await s.writeObject(i,[...c,a])}else{if(o===-1)throw new Error(`Item with id "${String(a.id)}" does not exist`);const r=[...c],w=r[o];r[o]=a,await s.writeObject(i,r),await q(w,a)}})),e.size>0&&await D(e)};return u.createStorageAdapter({setup:async()=>{await s.ensureDir(I)},teardown:async()=>{},readAll:O,readIds:async t=>(await Promise.all(t.map(async e=>{const a=await E(e),i=await s.readObject(a).catch(()=>[])??[];return Array.isArray(i)?i.find(c=>c.id===e)??null:null}))).filter(e=>e!=null),createIndex:async t=>{if(t==="id")throw new Error("Cannot create index on id field");P.push(t),await T(t)},dropIndex:async t=>{const n=await m(t);if(!await f(n))throw new Error(`Index on field "${t}" does not exist`);await s.removeEntry(n,{recursive:!0})},readIndex:z,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 e=>{const a=await E(e.id),i=await S(a),c=i.findIndex(r=>r.id===e.id);if(c===-1)throw new Error(`Item with id "${String(e.id)}" does not exist`);L(n,i[c]);const o=[...i];o.splice(c,1),await(o.length===0?s.removeEntry(a).catch(()=>{}):s.writeObject(a,o))})),await D(n)},removeAll:async()=>{await f(I)&&await s.removeEntry(I,{recursive:!0})}})}return p}));
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
@@ -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 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 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 const 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 const accumulateUpsertDelta = (deltas, 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 const accumulateRemoveDelta = (deltas, 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 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, 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, 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":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","safeFileExists","path","safeRemoveEntry","options","toItemsFilePath","identifier","toIndexPathForField","fieldPath","toIndexBucketFilePath","indexPath","rawKey","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","get","keyString","buckets","rawKeyString","records","readIndex","resultIndex","maps","target","indicesToMaintain","addToDelta","deltas","changeKind","delta","accumulateUpsertDelta","existingItem","nextItem","value","accumulateRemoveDelta","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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"}
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.1",
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.1"
57
+ "@signaldb/core": "2.0.0-beta.2"
58
58
  }
59
59
  }