@signaldb/generic-fs 2.0.0-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,5 @@
1
+ # @signaldb/generic-fs
2
+
3
+ This is the generic filesystem storage adapter for [SignalDB](https://github.com/maxnowack/signaldb). It's a abstract wrapper that makes it easier to develop file system adapters for SignalDB. SignalDB is a local-first JavaScript database with real-time sync, enabling optimistic UI with signal-based reactivity across multiple frameworks.
4
+
5
+ See https://signaldb.js.org/reference/generic-fs/ for more information.
@@ -0,0 +1,8 @@
1
+ {
2
+ "src/index.ts": {
3
+ "file": "index.umd.js",
4
+ "name": "index",
5
+ "src": "src/index.ts",
6
+ "isEntry": true
7
+ }
8
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * A driver interface that abstracts low-level filesystem operations.
3
+ * Implementations can back this with Node.js fs/promises, browser FS APIs, or other storage mechanisms.
4
+ */
5
+ export interface Driver<T extends {
6
+ id: I;
7
+ } & Record<string, unknown>, I> {
8
+ fileNameForId(id: I): Promise<string>;
9
+ fileNameForIndexKey(key: string): Promise<string>;
10
+ joinPath(...parts: string[]): Promise<string>;
11
+ ensureDir(path: string): Promise<void>;
12
+ fileExists(path: string): Promise<boolean>;
13
+ readObject(path: string): Promise<T[] | null>;
14
+ writeObject(path: string, value: T[]): Promise<void>;
15
+ readIndexObject(path: string): Promise<Record<string, I[]>[] | null>;
16
+ writeIndexObject(path: string, value: Record<string, I[]>[]): Promise<void>;
17
+ listFilesRecursive(directoryPath: string): Promise<string[]>;
18
+ removeEntry(path: string, options?: {
19
+ recursive?: boolean;
20
+ }): Promise<void>;
21
+ }
22
+ /**
23
+ * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.
24
+ * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.
25
+ * @param driver - The driver that handles low-level file operations.
26
+ * @param folderName - The root folder path for storing the collection data.
27
+ * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.
28
+ */
29
+ export default function createGenericFSAdapter<T extends {
30
+ id: I;
31
+ } & Record<string, unknown>, I>(driver: Driver<T, I>, folderName: string): import("@signaldb/core").StorageAdapter<T, I>;
package/dist/index.mjs ADDED
@@ -0,0 +1,172 @@
1
+ import { createStorageAdapter as K, get as m } from "@signaldb/core";
2
+ function R(t, x) {
3
+ const h = t.joinPath(x, "items"), p = t.joinPath(x, "index"), g = async () => {
4
+ if (!await t.fileExists(await h).catch(() => !1))
5
+ return [];
6
+ const n = await t.listFilesRecursive(await h), s = [];
7
+ return await Promise.all(n.map(async (a) => {
8
+ const i = await t.joinPath(await h, a), c = await t.readObject(i);
9
+ Array.isArray(c) && s.push(...c);
10
+ })), s;
11
+ }, O = async (e, n = g()) => {
12
+ const s = await n, a = await t.joinPath(await p, await t.fileNameForIndexKey(e));
13
+ await t.removeEntry(a, { recursive: !0 }).catch(() => {
14
+ }), await t.ensureDir(a);
15
+ const i = /* @__PURE__ */ new Map();
16
+ for (const o of s) {
17
+ const r = m(o, e);
18
+ r != null && (i.has(r) || i.set(r, /* @__PURE__ */ new Set()), i.get(r)?.add(o.id));
19
+ }
20
+ const c = {};
21
+ for (const [o, r] of i) {
22
+ const w = String(o), l = await t.fileNameForIndexKey(w);
23
+ c[l] || (c[l] = []), c[l].push({ [w]: [...r] });
24
+ }
25
+ await Promise.all(Object.entries(c).map(async ([o, r]) => {
26
+ const w = await t.joinPath(a, o);
27
+ await t.writeIndexObject(w, r);
28
+ }));
29
+ }, D = async (e) => {
30
+ const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));
31
+ if (!await t.fileExists(n).catch(() => !1))
32
+ throw new Error(`Index on field "${e}" does not exist`);
33
+ const a = await t.listFilesRecursive(n), i = /* @__PURE__ */ new Map();
34
+ return await Promise.all(a.map(async (c) => {
35
+ const o = await t.joinPath(n, c), r = await t.readIndexObject(o);
36
+ if (Array.isArray(r))
37
+ for (const w of r)
38
+ for (const [l, j] of Object.entries(w)) {
39
+ i.has(l) || i.set(l, /* @__PURE__ */ new Set());
40
+ for (const d of j)
41
+ i.get(l)?.add(d);
42
+ }
43
+ })), i;
44
+ }, I = [], P = (e, n, s, a, i) => {
45
+ e.has(n) || e.set(n, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });
46
+ const c = e.get(n);
47
+ if (!c)
48
+ return;
49
+ const o = s === "add" ? c.adds : c.removes;
50
+ o.has(a) || o.set(a, /* @__PURE__ */ new Set()), o.get(a)?.add(i);
51
+ }, M = (e, n, s, a, i) => {
52
+ const c = s == null ? void 0 : String(s), o = a == null ? void 0 : String(a);
53
+ c !== o && (c != null && P(e, n, "remove", c, i), o != null && P(e, n, "add", o, i));
54
+ }, S = (e, n, s) => {
55
+ if (n)
56
+ for (const a of I)
57
+ M(e, a, m(n, a), m(s, a), s.id);
58
+ else
59
+ for (const a of I) {
60
+ const i = m(s, a);
61
+ i != null && P(e, a, "add", String(i), s.id);
62
+ }
63
+ }, k = (e, n) => {
64
+ for (const s of I) {
65
+ const a = m(n, s);
66
+ a != null && P(e, s, "remove", String(a), n.id);
67
+ }
68
+ }, F = async (e) => {
69
+ await Promise.all([...e.entries()].map(async ([n, s]) => {
70
+ const a = await t.joinPath(await p, await t.fileNameForIndexKey(n));
71
+ if (!await t.fileExists(a).catch(() => !1))
72
+ return;
73
+ await t.ensureDir(a);
74
+ const c = /* @__PURE__ */ new Set([
75
+ ...s.adds.keys(),
76
+ ...s.removes.keys()
77
+ ]), o = /* @__PURE__ */ new Map();
78
+ await Promise.all([...c].map(async (w) => {
79
+ o.set(w, await t.fileNameForIndexKey(w));
80
+ }));
81
+ const r = new Set(o.values());
82
+ await Promise.all([...r].map(async (w) => {
83
+ const l = await t.joinPath(a, w), j = await t.readIndexObject(l), d = /* @__PURE__ */ new Map();
84
+ if (Array.isArray(j))
85
+ for (const y of j)
86
+ for (const [f, u] of Object.entries(y))
87
+ d.set(f, new Set(u));
88
+ if (s.removes.forEach((y, f) => {
89
+ if (o.get(f) !== w)
90
+ return;
91
+ const u = d.get(f);
92
+ u && (y.forEach((E) => u.delete(E)), u.size === 0 && d.delete(f));
93
+ }), s.adds.forEach((y, f) => {
94
+ if (o.get(f) !== w)
95
+ return;
96
+ let u = d.get(f);
97
+ u || (u = /* @__PURE__ */ new Set(), d.set(f, u)), y.forEach((E) => u.add(E));
98
+ }), d.size === 0) {
99
+ await t.fileExists(l).catch(() => !1) && await t.removeEntry(l).catch(() => {
100
+ });
101
+ return;
102
+ }
103
+ const b = [];
104
+ d.forEach((y, f) => {
105
+ b.push({ [f]: [...y] });
106
+ }), await t.writeIndexObject(l, b);
107
+ }));
108
+ }));
109
+ }, A = async (e, n) => {
110
+ const s = /* @__PURE__ */ new Map();
111
+ await Promise.all(e.map(async (a) => {
112
+ const i = await t.joinPath(await h, await t.fileNameForId(a.id)), c = await t.readObject(i), o = Array.isArray(c) ? c : [], r = o.findIndex((w) => w.id === a.id);
113
+ if (n === "insert") {
114
+ if (r !== -1)
115
+ throw new Error(`Item with id "${String(a.id)}" already exists`);
116
+ S(s, void 0, a), await t.writeObject(i, [...o, a]);
117
+ } else {
118
+ if (r === -1)
119
+ throw new Error(`Item with id "${String(a.id)}" does not exist`);
120
+ S(s, o[r], a);
121
+ const w = [...o];
122
+ w[r] = a, await t.writeObject(i, w);
123
+ }
124
+ })), await F(s);
125
+ };
126
+ return K({
127
+ setup: async () => {
128
+ await t.ensureDir(x);
129
+ },
130
+ teardown: async () => {
131
+ },
132
+ readAll: g,
133
+ readIds: async (e) => (await Promise.all(e.map(async (s) => {
134
+ const a = await t.joinPath(await h, await t.fileNameForId(s)), i = await t.readObject(a);
135
+ return Array.isArray(i) ? i.find((c) => c.id === s) ?? null : null;
136
+ }))).filter((s) => s != null),
137
+ createIndex: async (e) => {
138
+ I.push(e), await O(e);
139
+ },
140
+ dropIndex: async (e) => {
141
+ const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));
142
+ if (!await t.fileExists(n).catch(() => !1))
143
+ throw new Error(`Index on field "${e}" does not exist`);
144
+ await t.removeEntry(n, { recursive: !0 });
145
+ },
146
+ readIndex: D,
147
+ insert: async (e) => {
148
+ await A(e, "insert");
149
+ },
150
+ replace: async (e) => {
151
+ await A(e, "replace");
152
+ },
153
+ remove: async (e) => {
154
+ const n = /* @__PURE__ */ new Map();
155
+ await Promise.all(e.map(async (s) => {
156
+ const a = await t.joinPath(await h, await t.fileNameForId(s.id)), i = await t.readObject(a), c = Array.isArray(i) ? i : [], o = c.findIndex((w) => w.id === s.id);
157
+ if (o === -1)
158
+ throw new Error(`Item with id "${String(s.id)}" does not exist`);
159
+ k(n, c[o]);
160
+ const r = [...c];
161
+ r.splice(o, 1), await (r.length === 0 ? t.removeEntry(a) : t.writeObject(a, r));
162
+ })), await F(n);
163
+ },
164
+ removeAll: async () => {
165
+ await t.fileExists(x).catch(() => !1) && await t.removeEntry(x, { recursive: !0 });
166
+ }
167
+ });
168
+ }
169
+ export {
170
+ R as default
171
+ };
172
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter, get } from '@signaldb/core';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const readAll = async () => {\n const directoryExists = await driver.fileExists(await itemsDirectoryPathPromise)\n .catch(() => false);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(await itemsDirectoryPathPromise);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(await itemsDirectoryPathPromise, relativePath);\n const itemsInFile = await driver.readObject(fullPath);\n if (!Array.isArray(itemsInFile))\n return;\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n await driver.removeEntry(indexPath, { recursive: true }).catch(() => { });\n await driver.ensureDir(indexPath);\n // Map<fieldValue, Set<identifier>>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n if (!indexMap.has(fieldValue))\n indexMap.set(fieldValue, new Set());\n indexMap.get(fieldValue)?.add(item.id);\n }\n // Persist as files keyed by safe value; keep original value stringified for lookup parity.\n const buckets = {};\n for (const [rawKey, identifiers] of indexMap) {\n const rawKeyString = String(rawKey);\n const key = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[key])\n buckets[key] = [];\n buckets[key].push({ [rawKeyString]: [...identifiers] });\n }\n await Promise.all(Object.entries(buckets).map(async ([key, maps]) => {\n const filePath = await driver.joinPath(indexPath, key);\n await driver.writeIndexObject(filePath, maps);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [key, identifiers] of Object.entries(entry)) {\n if (!resultIndex.has(key))\n resultIndex.set(key, new Set());\n for (const identifier of identifiers) {\n resultIndex.get(key)?.add(identifier);\n }\n }\n }\n }));\n return resultIndex;\n };\n const indicesToMaintain = [];\n const addToDelta = (deltas, field, kind, rawKey, id) => {\n if (!deltas.has(field))\n deltas.set(field, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(field);\n if (!delta)\n return;\n const target = kind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(id);\n };\n const addDeltaForChange = (deltas, field, oldValue, newValue, id) => {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, field, 'remove', oldKey, id);\n if (newKey != null)\n addToDelta(deltas, field, 'add', newKey, id);\n };\n const accumulateUpsertDelta = (deltas, existing, next) => {\n if (existing) {\n for (const field of indicesToMaintain) {\n addDeltaForChange(deltas, field, get(existing, field), get(next, field), next.id);\n }\n }\n else {\n for (const field of indicesToMaintain) {\n const value = get(next, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'add', String(value), next.id);\n }\n }\n };\n const accumulateRemoveDelta = (deltas, existing) => {\n for (const field of indicesToMaintain) {\n const value = get(existing, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'remove', String(value), existing.id);\n }\n };\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucket = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucket.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBuckets = new Set(rawKeyToBucket.values());\n await Promise.all([...touchedBuckets].map(async (bucket) => {\n const filePath = await driver.joinPath(indexPath, bucket);\n const data = await driver.readIndexObject(filePath);\n // Rehydrate only this bucket into a map of rawKey -> Set<I>\n const bucketIndex = new Map();\n if (Array.isArray(data)) {\n for (const entry of data) {\n for (const [rawKey, ids] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(ids));\n }\n }\n }\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n const set = bucketIndex.get(rawKey);\n if (!set)\n return;\n ids.forEach(id => set.delete(id));\n if (set.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n let set = bucketIndex.get(rawKey);\n if (!set) {\n set = new Set();\n bucketIndex.set(rawKey, set);\n }\n ids.forEach(id => set.add(id));\n });\n if (bucketIndex.size === 0) {\n const exists = await driver.fileExists(filePath).catch(() => false);\n if (exists)\n await driver.removeEntry(filePath).catch(() => { });\n return;\n }\n // Persist this bucket only\n const out = [];\n bucketIndex.forEach((set, rawKey) => {\n out.push({ [rawKey]: [...set] });\n });\n await driver.writeIndexObject(filePath, out);\n }));\n }));\n };\n // Shared item operations using the delta helpers\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (mode === 'insert') {\n if (index !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, undefined, item);\n await driver.writeObject(filePath, [...array, item]);\n }\n else {\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateUpsertDelta(deltas, array[index], item);\n const updated = [...array];\n updated[index] = item;\n await driver.writeObject(filePath, updated);\n }\n }));\n await applyIndexDeltas(deltas);\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const itemsInFile = await driver.readObject(filePath);\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const exists = await driver.fileExists(pathToDrop).catch(() => false);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, array[index]);\n const updated = [...array];\n updated.splice(index, 1);\n await (updated.length === 0\n ? driver.removeEntry(filePath)\n : driver.writeObject(filePath, updated));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await driver.fileExists(folderName).catch(() => false);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","readAll","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","fieldPath","itemsPromise","allItems","indexPath","indexMap","item","fieldValue","get","buckets","rawKey","identifiers","rawKeyString","key","maps","filePath","readIndex","resultIndex","entry","identifier","indicesToMaintain","addToDelta","deltas","field","kind","id","delta","target","addDeltaForChange","oldValue","newValue","oldKey","newKey","accumulateUpsertDelta","existing","next","value","accumulateRemoveDelta","applyIndexDeltas","touchedRawKeys","rawKeyToBucket","touchedBuckets","bucket","data","bucketIndex","ids","set","out","upsertItems","items","mode","array","index","x","updated","createStorageAdapter","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":";AAQA,SAAwBA,EAAuBC,GAAQC,GAAY;AAC/D,QAAMC,IAA4BF,EAAO,SAASC,GAAY,OAAO,GAC/DE,IAAuBH,EAAO,SAASC,GAAY,OAAO,GAC1DG,IAAU,YAAY;AAGxB,QAAI,CAFoB,MAAMJ,EAAO,WAAW,MAAME,CAAyB,EAC1E,MAAM,MAAM,EAAK;AAElB,aAAO,CAAA;AACX,UAAMG,IAAgB,MAAML,EAAO,mBAAmB,MAAME,CAAyB,GAC/EI,IAAkB,CAAA;AACxB,iBAAM,QAAQ,IAAID,EAAc,IAAI,OAAOE,MAAiB;AACxD,YAAMC,IAAW,MAAMR,EAAO,SAAS,MAAME,GAA2BK,CAAY,GAC9EE,IAAc,MAAMT,EAAO,WAAWQ,CAAQ;AACpD,MAAK,MAAM,QAAQC,CAAW,KAE9BH,EAAgB,KAAK,GAAGG,CAAW;AAAA,IACvC,CAAC,CAAC,GACKH;AAAA,EACX,GACMI,IAAc,OAAOC,GAAWC,IAAeR,QAAc;AAC/D,UAAMS,IAAW,MAAMD,GACjBE,IAAY,MAAMd,EAAO,SAAS,MAAMG,GAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC;AAC/G,UAAMX,EAAO,YAAYc,GAAW,EAAE,WAAW,GAAA,CAAM,EAAE,MAAM,MAAM;AAAA,IAAE,CAAC,GACxE,MAAMd,EAAO,UAAUc,CAAS;AAEhC,UAAMC,wBAAe,IAAA;AACrB,eAAWC,KAAQH,GAAU;AACzB,YAAMI,IAAaC,EAAIF,GAAML,CAAS;AACtC,MAAIM,KAAc,SAEbF,EAAS,IAAIE,CAAU,KACxBF,EAAS,IAAIE,GAAY,oBAAI,IAAA,CAAK,GACtCF,EAAS,IAAIE,CAAU,GAAG,IAAID,EAAK,EAAE;AAAA,IACzC;AAEA,UAAMG,IAAU,CAAA;AAChB,eAAW,CAACC,GAAQC,CAAW,KAAKN,GAAU;AAC1C,YAAMO,IAAe,OAAOF,CAAM,GAC5BG,IAAM,MAAMvB,EAAO,oBAAoBsB,CAAY;AACzD,MAAKH,EAAQI,CAAG,MACZJ,EAAQI,CAAG,IAAI,CAAA,IACnBJ,EAAQI,CAAG,EAAE,KAAK,EAAE,CAACD,CAAY,GAAG,CAAC,GAAGD,CAAW,GAAG;AAAA,IAC1D;AACA,UAAM,QAAQ,IAAI,OAAO,QAAQF,CAAO,EAAE,IAAI,OAAO,CAACI,GAAKC,CAAI,MAAM;AACjE,YAAMC,IAAW,MAAMzB,EAAO,SAASc,GAAWS,CAAG;AACrD,YAAMvB,EAAO,iBAAiByB,GAAUD,CAAI;AAAA,IAChD,CAAC,CAAC;AAAA,EACN,GACME,IAAY,OAAOf,MAAc;AACnC,UAAMG,IAAY,MAAMd,EAAO,SAAS,MAAMG,GAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC;AAE/G,QAAI,CADgB,MAAMX,EAAO,WAAWc,CAAS,EAAE,MAAM,MAAM,EAAK;AAEpE,YAAM,IAAI,MAAM,mBAAmBH,CAAS,kBAAkB;AAClE,UAAMN,IAAgB,MAAML,EAAO,mBAAmBc,CAAS,GACzDa,wBAAkB,IAAA;AACxB,iBAAM,QAAQ,IAAItB,EAAc,IAAI,OAAOE,MAAiB;AACxD,YAAMC,IAAW,MAAMR,EAAO,SAASc,GAAWP,CAAY,GACxDiB,IAAO,MAAMxB,EAAO,gBAAgBQ,CAAQ;AAClD,UAAK,MAAM,QAAQgB,CAAI;AAEvB,mBAAWI,KAASJ;AAChB,qBAAW,CAACD,GAAKF,CAAW,KAAK,OAAO,QAAQO,CAAK,GAAG;AACpD,YAAKD,EAAY,IAAIJ,CAAG,KACpBI,EAAY,IAAIJ,GAAK,oBAAI,IAAA,CAAK;AAClC,uBAAWM,KAAcR;AACrB,cAAAM,EAAY,IAAIJ,CAAG,GAAG,IAAIM,CAAU;AAAA,UAE5C;AAAA,IAER,CAAC,CAAC,GACKF;AAAA,EACX,GACMG,IAAoB,CAAA,GACpBC,IAAa,CAACC,GAAQC,GAAOC,GAAMd,GAAQe,MAAO;AACpD,IAAKH,EAAO,IAAIC,CAAK,KACjBD,EAAO,IAAIC,GAAO,EAAE,MAAM,oBAAI,IAAA,GAAO,SAAS,oBAAI,IAAA,GAAO;AAC7D,UAAMG,IAAQJ,EAAO,IAAIC,CAAK;AAC9B,QAAI,CAACG;AACD;AACJ,UAAMC,IAASH,MAAS,QAAQE,EAAM,OAAOA,EAAM;AACnD,IAAKC,EAAO,IAAIjB,CAAM,KAClBiB,EAAO,IAAIjB,GAAQ,oBAAI,IAAA,CAAK,GAChCiB,EAAO,IAAIjB,CAAM,GAAG,IAAIe,CAAE;AAAA,EAC9B,GACMG,IAAoB,CAACN,GAAQC,GAAOM,GAAUC,GAAUL,MAAO;AACjE,UAAMM,IAASF,KAAY,OAAO,SAAY,OAAOA,CAAQ,GACvDG,IAASF,KAAY,OAAO,SAAY,OAAOA,CAAQ;AAC7D,IAAIC,MAAWC,MAEXD,KAAU,QACVV,EAAWC,GAAQC,GAAO,UAAUQ,GAAQN,CAAE,GAC9CO,KAAU,QACVX,EAAWC,GAAQC,GAAO,OAAOS,GAAQP,CAAE;AAAA,EACnD,GACMQ,IAAwB,CAACX,GAAQY,GAAUC,MAAS;AACtD,QAAID;AACA,iBAAWX,KAASH;AAChB,QAAAQ,EAAkBN,GAAQC,GAAOf,EAAI0B,GAAUX,CAAK,GAAGf,EAAI2B,GAAMZ,CAAK,GAAGY,EAAK,EAAE;AAAA;AAIpF,iBAAWZ,KAASH,GAAmB;AACnC,cAAMgB,IAAQ5B,EAAI2B,GAAMZ,CAAK;AAC7B,QAAIa,KAAS,QAEbf,EAAWC,GAAQC,GAAO,OAAO,OAAOa,CAAK,GAAGD,EAAK,EAAE;AAAA,MAC3D;AAAA,EAER,GACME,IAAwB,CAACf,GAAQY,MAAa;AAChD,eAAWX,KAASH,GAAmB;AACnC,YAAMgB,IAAQ5B,EAAI0B,GAAUX,CAAK;AACjC,MAAIa,KAAS,QAEbf,EAAWC,GAAQC,GAAO,UAAU,OAAOa,CAAK,GAAGF,EAAS,EAAE;AAAA,IAClE;AAAA,EACJ,GACMI,IAAmB,OAAOhB,MAAW;AAEvC,UAAM,QAAQ,IAAI,CAAC,GAAGA,EAAO,SAAS,EAAE,IAAI,OAAO,CAACrB,GAAWyB,CAAK,MAAM;AACtE,YAAMtB,IAAY,MAAMd,EAAO,SAAS,MAAMG,GAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC;AAE/G,UAAI,CADgB,MAAMX,EAAO,WAAWc,CAAS,EAAE,MAAM,MAAM,EAAK;AAEpE;AACJ,YAAMd,EAAO,UAAUc,CAAS;AAEhC,YAAMmC,wBAAqB,IAAI;AAAA,QAC3B,GAAGb,EAAM,KAAK,KAAA;AAAA,QACd,GAAGA,EAAM,QAAQ,KAAA;AAAA,MAAK,CACzB,GACKc,wBAAqB,IAAA;AAC3B,YAAM,QAAQ,IAAI,CAAC,GAAGD,CAAc,EAAE,IAAI,OAAO7B,MAAW;AACxD,QAAA8B,EAAe,IAAI9B,GAAQ,MAAMpB,EAAO,oBAAoBoB,CAAM,CAAC;AAAA,MACvE,CAAC,CAAC;AACF,YAAM+B,IAAiB,IAAI,IAAID,EAAe,QAAQ;AACtD,YAAM,QAAQ,IAAI,CAAC,GAAGC,CAAc,EAAE,IAAI,OAAOC,MAAW;AACxD,cAAM3B,IAAW,MAAMzB,EAAO,SAASc,GAAWsC,CAAM,GAClDC,IAAO,MAAMrD,EAAO,gBAAgByB,CAAQ,GAE5C6B,wBAAkB,IAAA;AACxB,YAAI,MAAM,QAAQD,CAAI;AAClB,qBAAWzB,KAASyB;AAChB,uBAAW,CAACjC,GAAQmC,CAAG,KAAK,OAAO,QAAQ3B,CAAK;AAC5C,cAAA0B,EAAY,IAAIlC,GAAQ,IAAI,IAAImC,CAAG,CAAC;AA0BhD,YArBAnB,EAAM,QAAQ,QAAQ,CAACmB,GAAKnC,MAAW;AACnC,cAAI8B,EAAe,IAAI9B,CAAM,MAAMgC;AAC/B;AACJ,gBAAMI,IAAMF,EAAY,IAAIlC,CAAM;AAClC,UAAKoC,MAELD,EAAI,QAAQ,CAAApB,MAAMqB,EAAI,OAAOrB,CAAE,CAAC,GAC5BqB,EAAI,SAAS,KACbF,EAAY,OAAOlC,CAAM;AAAA,QACjC,CAAC,GAEDgB,EAAM,KAAK,QAAQ,CAACmB,GAAKnC,MAAW;AAChC,cAAI8B,EAAe,IAAI9B,CAAM,MAAMgC;AAC/B;AACJ,cAAII,IAAMF,EAAY,IAAIlC,CAAM;AAChC,UAAKoC,MACDA,wBAAU,IAAA,GACVF,EAAY,IAAIlC,GAAQoC,CAAG,IAE/BD,EAAI,QAAQ,CAAApB,MAAMqB,EAAI,IAAIrB,CAAE,CAAC;AAAA,QACjC,CAAC,GACGmB,EAAY,SAAS,GAAG;AAExB,UADe,MAAMtD,EAAO,WAAWyB,CAAQ,EAAE,MAAM,MAAM,EAAK,KAE9D,MAAMzB,EAAO,YAAYyB,CAAQ,EAAE,MAAM,MAAM;AAAA,UAAE,CAAC;AACtD;AAAA,QACJ;AAEA,cAAMgC,IAAM,CAAA;AACZ,QAAAH,EAAY,QAAQ,CAACE,GAAKpC,MAAW;AACjC,UAAAqC,EAAI,KAAK,EAAE,CAACrC,CAAM,GAAG,CAAC,GAAGoC,CAAG,GAAG;AAAA,QACnC,CAAC,GACD,MAAMxD,EAAO,iBAAiByB,GAAUgC,CAAG;AAAA,MAC/C,CAAC,CAAC;AAAA,IACN,CAAC,CAAC;AAAA,EACN,GAEMC,IAAc,OAAOC,GAAOC,MAAS;AACvC,UAAM5B,wBAAa,IAAA;AACnB,UAAM,QAAQ,IAAI2B,EAAM,IAAI,OAAO3C,MAAS;AACxC,YAAMS,IAAW,MAAMzB,EAAO,SAAS,MAAME,GAA2B,MAAMF,EAAO,cAAcgB,EAAK,EAAE,CAAC,GACrG4B,IAAW,MAAM5C,EAAO,WAAWyB,CAAQ,GAC3CoC,IAAQ,MAAM,QAAQjB,CAAQ,IAAIA,IAAW,CAAA,GAC7CkB,IAAQD,EAAM,UAAU,OAAKE,EAAE,OAAO/C,EAAK,EAAE;AACnD,UAAI4C,MAAS,UAAU;AACnB,YAAIE,MAAU;AACV,gBAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB;AACtE,QAAA2B,EAAsBX,GAAQ,QAAWhB,CAAI,GAC7C,MAAMhB,EAAO,YAAYyB,GAAU,CAAC,GAAGoC,GAAO7C,CAAI,CAAC;AAAA,MACvD,OACK;AACD,YAAI8C,MAAU;AACV,gBAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB;AACtE,QAAA2B,EAAsBX,GAAQ6B,EAAMC,CAAK,GAAG9C,CAAI;AAChD,cAAMgD,IAAU,CAAC,GAAGH,CAAK;AACzB,QAAAG,EAAQF,CAAK,IAAI9C,GACjB,MAAMhB,EAAO,YAAYyB,GAAUuC,CAAO;AAAA,MAC9C;AAAA,IACJ,CAAC,CAAC,GACF,MAAMhB,EAAiBhB,CAAM;AAAA,EACjC;AACA,SAAOiC,EAAqB;AAAA,IACxB,OAAO,YAAY;AACf,YAAMjE,EAAO,UAAUC,CAAU;AAAA,IACrC;AAAA,IACA,UAAU,YAAY;AAAA,IAEtB;AAAA,IACA,SAAAG;AAAA,IACA,SAAS,OAAOiB,OACI,MAAM,QAAQ,IAAIA,EAAY,IAAI,OAAOQ,MAAe;AACpE,YAAMJ,IAAW,MAAMzB,EAAO,SAAS,MAAME,GAA2B,MAAMF,EAAO,cAAc6B,CAAU,CAAC,GACxGpB,IAAc,MAAMT,EAAO,WAAWyB,CAAQ;AACpD,aAAK,MAAM,QAAQhB,CAAW,IAEvBA,EAAY,KAAK,CAAAO,MAAQA,EAAK,OAAOa,CAAU,KAAK,OADhD;AAAA,IAEf,CAAC,CAAC,GACa,OAAO,CAACiB,MAAUA,KAAS,IAAI;AAAA,IAElD,aAAa,OAAOnC,MAAc;AAC9B,MAAAmB,EAAkB,KAAKnB,CAAS,GAChC,MAAMD,EAAYC,CAAS;AAAA,IAC/B;AAAA,IACA,WAAW,OAAOA,MAAc;AAC5B,YAAMuD,IAAa,MAAMlE,EAAO,SAAS,MAAMG,GAAsB,MAAMH,EAAO,oBAAoBW,CAAS,CAAC;AAEhH,UAAI,CADW,MAAMX,EAAO,WAAWkE,CAAU,EAAE,MAAM,MAAM,EAAK;AAEhE,cAAM,IAAI,MAAM,mBAAmBvD,CAAS,kBAAkB;AAClE,YAAMX,EAAO,YAAYkE,GAAY,EAAE,WAAW,IAAM;AAAA,IAC5D;AAAA,IACA,WAAAxC;AAAA,IACA,QAAQ,OAAOyC,MAAkB;AAC7B,YAAMT,EAAYS,GAAe,QAAQ;AAAA,IAC7C;AAAA,IACA,SAAS,OAAOC,MAAmB;AAC/B,YAAMV,EAAYU,GAAgB,SAAS;AAAA,IAC/C;AAAA,IACA,QAAQ,OAAOC,MAAkB;AAC7B,YAAMrC,wBAAa,IAAA;AACnB,YAAM,QAAQ,IAAIqC,EAAc,IAAI,OAAOrD,MAAS;AAChD,cAAMS,IAAW,MAAMzB,EAAO,SAAS,MAAME,GAA2B,MAAMF,EAAO,cAAcgB,EAAK,EAAE,CAAC,GACrG4B,IAAW,MAAM5C,EAAO,WAAWyB,CAAQ,GAC3CoC,IAAQ,MAAM,QAAQjB,CAAQ,IAAIA,IAAW,CAAA,GAC7CkB,IAAQD,EAAM,UAAU,OAAKE,EAAE,OAAO/C,EAAK,EAAE;AACnD,YAAI8C,MAAU;AACV,gBAAM,IAAI,MAAM,iBAAiB,OAAO9C,EAAK,EAAE,CAAC,kBAAkB;AACtE,QAAA+B,EAAsBf,GAAQ6B,EAAMC,CAAK,CAAC;AAC1C,cAAME,IAAU,CAAC,GAAGH,CAAK;AACzB,QAAAG,EAAQ,OAAOF,GAAO,CAAC,GACvB,OAAOE,EAAQ,WAAW,IACpBhE,EAAO,YAAYyB,CAAQ,IAC3BzB,EAAO,YAAYyB,GAAUuC,CAAO;AAAA,MAC9C,CAAC,CAAC,GACF,MAAMhB,EAAiBhB,CAAM;AAAA,IACjC;AAAA,IACA,WAAW,YAAY;AAEnB,MADe,MAAMhC,EAAO,WAAWC,CAAU,EAAE,MAAM,MAAM,EAAK,KAGpE,MAAMD,EAAO,YAAYC,GAAY,EAAE,WAAW,IAAM;AAAA,IAC5D;AAAA,EAAA,CACH;AACL;"}
@@ -0,0 +1,2 @@
1
+ (function(f,m){typeof exports=="object"&&typeof module<"u"?module.exports=m(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],m):(f=typeof globalThis<"u"?globalThis:f||self,f.SignalDB=m(f.core))})(this,(function(f){"use strict";function m(t,p){const x=t.joinPath(p,"items"),I=t.joinPath(p,"index"),S=async()=>{if(!await t.fileExists(await x).catch(()=>!1))return[];const s=await t.listFilesRecursive(await x),n=[];return await Promise.all(s.map(async a=>{const i=await t.joinPath(await x,a),c=await t.readObject(i);Array.isArray(c)&&n.push(...c)})),n},D=async(e,s=S())=>{const n=await s,a=await t.joinPath(await I,await t.fileNameForIndexKey(e));await t.removeEntry(a,{recursive:!0}).catch(()=>{}),await t.ensureDir(a);const i=new Map;for(const o of n){const r=f.get(o,e);r!=null&&(i.has(r)||i.set(r,new Set),i.get(r)?.add(o.id))}const c={};for(const[o,r]of i){const l=String(o),w=await t.fileNameForIndexKey(l);c[w]||(c[w]=[]),c[w].push({[l]:[...r]})}await Promise.all(Object.entries(c).map(async([o,r])=>{const l=await t.joinPath(a,o);await t.writeIndexObject(l,r)}))},M=async e=>{const s=await t.joinPath(await I,await t.fileNameForIndexKey(e));if(!await t.fileExists(s).catch(()=>!1))throw new Error(`Index on field "${e}" does not exist`);const a=await t.listFilesRecursive(s),i=new Map;return await Promise.all(a.map(async c=>{const o=await t.joinPath(s,c),r=await t.readIndexObject(o);if(Array.isArray(r))for(const l of r)for(const[w,j]of Object.entries(l)){i.has(w)||i.set(w,new Set);for(const y of j)i.get(w)?.add(y)}})),i},P=[],g=(e,s,n,a,i)=>{e.has(s)||e.set(s,{adds:new Map,removes:new Map});const c=e.get(s);if(!c)return;const o=n==="add"?c.adds:c.removes;o.has(a)||o.set(a,new Set),o.get(a)?.add(i)},k=(e,s,n,a,i)=>{const c=n==null?void 0:String(n),o=a==null?void 0:String(a);c!==o&&(c!=null&&g(e,s,"remove",c,i),o!=null&&g(e,s,"add",o,i))},F=(e,s,n)=>{if(s)for(const a of P)k(e,a,f.get(s,a),f.get(n,a),n.id);else for(const a of P){const i=f.get(n,a);i!=null&&g(e,a,"add",String(i),n.id)}},K=(e,s)=>{for(const n of P){const a=f.get(s,n);a!=null&&g(e,n,"remove",String(a),s.id)}},b=async e=>{await Promise.all([...e.entries()].map(async([s,n])=>{const a=await t.joinPath(await I,await t.fileNameForIndexKey(s));if(!await t.fileExists(a).catch(()=>!1))return;await t.ensureDir(a);const c=new Set([...n.adds.keys(),...n.removes.keys()]),o=new Map;await Promise.all([...c].map(async l=>{o.set(l,await t.fileNameForIndexKey(l))}));const r=new Set(o.values());await Promise.all([...r].map(async l=>{const w=await t.joinPath(a,l),j=await t.readIndexObject(w),y=new Map;if(Array.isArray(j))for(const h of j)for(const[u,d]of Object.entries(h))y.set(u,new Set(d));if(n.removes.forEach((h,u)=>{if(o.get(u)!==l)return;const d=y.get(u);d&&(h.forEach(E=>d.delete(E)),d.size===0&&y.delete(u))}),n.adds.forEach((h,u)=>{if(o.get(u)!==l)return;let d=y.get(u);d||(d=new Set,y.set(u,d)),h.forEach(E=>d.add(E))}),y.size===0){await t.fileExists(w).catch(()=>!1)&&await t.removeEntry(w).catch(()=>{});return}const O=[];y.forEach((h,u)=>{O.push({[u]:[...h]})}),await t.writeIndexObject(w,O)}))}))},A=async(e,s)=>{const n=new Map;await Promise.all(e.map(async a=>{const i=await t.joinPath(await x,await t.fileNameForId(a.id)),c=await t.readObject(i),o=Array.isArray(c)?c:[],r=o.findIndex(l=>l.id===a.id);if(s==="insert"){if(r!==-1)throw new Error(`Item with id "${String(a.id)}" already exists`);F(n,void 0,a),await t.writeObject(i,[...o,a])}else{if(r===-1)throw new Error(`Item with id "${String(a.id)}" does not exist`);F(n,o[r],a);const l=[...o];l[r]=a,await t.writeObject(i,l)}})),await b(n)};return f.createStorageAdapter({setup:async()=>{await t.ensureDir(p)},teardown:async()=>{},readAll:S,readIds:async e=>(await Promise.all(e.map(async n=>{const a=await t.joinPath(await x,await t.fileNameForId(n)),i=await t.readObject(a);return Array.isArray(i)?i.find(c=>c.id===n)??null:null}))).filter(n=>n!=null),createIndex:async e=>{P.push(e),await D(e)},dropIndex:async e=>{const s=await t.joinPath(await I,await t.fileNameForIndexKey(e));if(!await t.fileExists(s).catch(()=>!1))throw new Error(`Index on field "${e}" does not exist`);await t.removeEntry(s,{recursive:!0})},readIndex:M,insert:async e=>{await A(e,"insert")},replace:async e=>{await A(e,"replace")},remove:async e=>{const s=new Map;await Promise.all(e.map(async n=>{const a=await t.joinPath(await x,await t.fileNameForId(n.id)),i=await t.readObject(a),c=Array.isArray(i)?i:[],o=c.findIndex(l=>l.id===n.id);if(o===-1)throw new Error(`Item with id "${String(n.id)}" does not exist`);K(s,c[o]);const r=[...c];r.splice(o,1),await(r.length===0?t.removeEntry(a):t.writeObject(a,r))})),await b(s)},removeAll:async()=>{await t.fileExists(p).catch(()=>!1)&&await t.removeEntry(p,{recursive:!0})}})}return m}));
2
+ //# sourceMappingURL=index.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter, get } from '@signaldb/core';\n/**\n * Creates a storage adapter for managing a SignalDB collection using a generic filesystem-like driver.\n * Data is sharded into subdirectories based on item identifiers, and indices are maintained as files.\n * @param driver - The driver that handles low-level file operations.\n * @param folderName - The root folder path for storing the collection data.\n * @returns A SignalDB storage adapter for managing data in a filesystem-like storage.\n */\nexport default function createGenericFSAdapter(driver, folderName) {\n const itemsDirectoryPathPromise = driver.joinPath(folderName, 'items');\n const indexRootPathPromise = driver.joinPath(folderName, 'index');\n const readAll = async () => {\n const directoryExists = await driver.fileExists(await itemsDirectoryPathPromise)\n .catch(() => false);\n if (!directoryExists)\n return [];\n const relativeFiles = await driver.listFilesRecursive(await itemsDirectoryPathPromise);\n const aggregatedItems = [];\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(await itemsDirectoryPathPromise, relativePath);\n const itemsInFile = await driver.readObject(fullPath);\n if (!Array.isArray(itemsInFile))\n return;\n aggregatedItems.push(...itemsInFile);\n }));\n return aggregatedItems;\n };\n const ensureIndex = async (fieldPath, itemsPromise = readAll()) => {\n const allItems = await itemsPromise;\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n await driver.removeEntry(indexPath, { recursive: true }).catch(() => { });\n await driver.ensureDir(indexPath);\n // Map<fieldValue, Set<identifier>>\n const indexMap = new Map();\n for (const item of allItems) {\n const fieldValue = get(item, fieldPath);\n if (fieldValue == null)\n continue;\n if (!indexMap.has(fieldValue))\n indexMap.set(fieldValue, new Set());\n indexMap.get(fieldValue)?.add(item.id);\n }\n // Persist as files keyed by safe value; keep original value stringified for lookup parity.\n const buckets = {};\n for (const [rawKey, identifiers] of indexMap) {\n const rawKeyString = String(rawKey);\n const key = await driver.fileNameForIndexKey(rawKeyString);\n if (!buckets[key])\n buckets[key] = [];\n buckets[key].push({ [rawKeyString]: [...identifiers] });\n }\n await Promise.all(Object.entries(buckets).map(async ([key, maps]) => {\n const filePath = await driver.joinPath(indexPath, key);\n await driver.writeIndexObject(filePath, maps);\n }));\n };\n const readIndex = async (fieldPath) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n const relativeFiles = await driver.listFilesRecursive(indexPath);\n const resultIndex = new Map();\n await Promise.all(relativeFiles.map(async (relativePath) => {\n const fullPath = await driver.joinPath(indexPath, relativePath);\n const maps = await driver.readIndexObject(fullPath);\n if (!Array.isArray(maps))\n return;\n for (const entry of maps) {\n for (const [key, identifiers] of Object.entries(entry)) {\n if (!resultIndex.has(key))\n resultIndex.set(key, new Set());\n for (const identifier of identifiers) {\n resultIndex.get(key)?.add(identifier);\n }\n }\n }\n }));\n return resultIndex;\n };\n const indicesToMaintain = [];\n const addToDelta = (deltas, field, kind, rawKey, id) => {\n if (!deltas.has(field))\n deltas.set(field, { adds: new Map(), removes: new Map() });\n const delta = deltas.get(field);\n if (!delta)\n return;\n const target = kind === 'add' ? delta.adds : delta.removes;\n if (!target.has(rawKey))\n target.set(rawKey, new Set());\n target.get(rawKey)?.add(id);\n };\n const addDeltaForChange = (deltas, field, oldValue, newValue, id) => {\n const oldKey = oldValue == null ? undefined : String(oldValue);\n const newKey = newValue == null ? undefined : String(newValue);\n if (oldKey === newKey)\n return;\n if (oldKey != null)\n addToDelta(deltas, field, 'remove', oldKey, id);\n if (newKey != null)\n addToDelta(deltas, field, 'add', newKey, id);\n };\n const accumulateUpsertDelta = (deltas, existing, next) => {\n if (existing) {\n for (const field of indicesToMaintain) {\n addDeltaForChange(deltas, field, get(existing, field), get(next, field), next.id);\n }\n }\n else {\n for (const field of indicesToMaintain) {\n const value = get(next, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'add', String(value), next.id);\n }\n }\n };\n const accumulateRemoveDelta = (deltas, existing) => {\n for (const field of indicesToMaintain) {\n const value = get(existing, field);\n if (value == null)\n continue;\n addToDelta(deltas, field, 'remove', String(value), existing.id);\n }\n };\n const applyIndexDeltas = async (deltas) => {\n // For each indexed field with changes, touch only the affected bucket files\n await Promise.all([...deltas.entries()].map(async ([fieldPath, delta]) => {\n const indexPath = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const indexExists = await driver.fileExists(indexPath).catch(() => false);\n if (!indexExists)\n return; // Only update indices that exist\n await driver.ensureDir(indexPath);\n // Compute impacted bucket filenames\n const touchedRawKeys = new Set([\n ...delta.adds.keys(),\n ...delta.removes.keys(),\n ]);\n const rawKeyToBucket = new Map();\n await Promise.all([...touchedRawKeys].map(async (rawKey) => {\n rawKeyToBucket.set(rawKey, await driver.fileNameForIndexKey(rawKey));\n }));\n const touchedBuckets = new Set(rawKeyToBucket.values());\n await Promise.all([...touchedBuckets].map(async (bucket) => {\n const filePath = await driver.joinPath(indexPath, bucket);\n const data = await driver.readIndexObject(filePath);\n // Rehydrate only this bucket into a map of rawKey -> Set<I>\n const bucketIndex = new Map();\n if (Array.isArray(data)) {\n for (const entry of data) {\n for (const [rawKey, ids] of Object.entries(entry)) {\n bucketIndex.set(rawKey, new Set(ids));\n }\n }\n }\n // Apply removals for keys that map to this bucket\n delta.removes.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n const set = bucketIndex.get(rawKey);\n if (!set)\n return;\n ids.forEach(id => set.delete(id));\n if (set.size === 0)\n bucketIndex.delete(rawKey);\n });\n // Apply additions\n delta.adds.forEach((ids, rawKey) => {\n if (rawKeyToBucket.get(rawKey) !== bucket)\n return;\n let set = bucketIndex.get(rawKey);\n if (!set) {\n set = new Set();\n bucketIndex.set(rawKey, set);\n }\n ids.forEach(id => set.add(id));\n });\n if (bucketIndex.size === 0) {\n const exists = await driver.fileExists(filePath).catch(() => false);\n if (exists)\n await driver.removeEntry(filePath).catch(() => { });\n return;\n }\n // Persist this bucket only\n const out = [];\n bucketIndex.forEach((set, rawKey) => {\n out.push({ [rawKey]: [...set] });\n });\n await driver.writeIndexObject(filePath, out);\n }));\n }));\n };\n // Shared item operations using the delta helpers\n const upsertItems = async (items, mode) => {\n const deltas = new Map();\n await Promise.all(items.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (mode === 'insert') {\n if (index !== -1)\n throw new Error(`Item with id \"${String(item.id)}\" already exists`);\n accumulateUpsertDelta(deltas, undefined, item);\n await driver.writeObject(filePath, [...array, item]);\n }\n else {\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateUpsertDelta(deltas, array[index], item);\n const updated = [...array];\n updated[index] = item;\n await driver.writeObject(filePath, updated);\n }\n }));\n await applyIndexDeltas(deltas);\n };\n return createStorageAdapter({\n setup: async () => {\n await driver.ensureDir(folderName);\n },\n teardown: async () => {\n // no-op\n },\n readAll,\n readIds: async (identifiers) => {\n const results = await Promise.all(identifiers.map(async (identifier) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(identifier));\n const itemsInFile = await driver.readObject(filePath);\n if (!Array.isArray(itemsInFile))\n return null;\n return itemsInFile.find(item => item.id === identifier) ?? null;\n }));\n return results.filter((value) => value != null);\n },\n createIndex: async (fieldPath) => {\n indicesToMaintain.push(fieldPath);\n await ensureIndex(fieldPath);\n },\n dropIndex: async (fieldPath) => {\n const pathToDrop = await driver.joinPath(await indexRootPathPromise, await driver.fileNameForIndexKey(fieldPath));\n const exists = await driver.fileExists(pathToDrop).catch(() => false);\n if (!exists)\n throw new Error(`Index on field \"${fieldPath}\" does not exist`);\n await driver.removeEntry(pathToDrop, { recursive: true });\n },\n readIndex,\n insert: async (itemsToInsert) => {\n await upsertItems(itemsToInsert, 'insert');\n },\n replace: async (itemsToReplace) => {\n await upsertItems(itemsToReplace, 'replace');\n },\n remove: async (itemsToRemove) => {\n const deltas = new Map();\n await Promise.all(itemsToRemove.map(async (item) => {\n const filePath = await driver.joinPath(await itemsDirectoryPathPromise, await driver.fileNameForId(item.id));\n const existing = await driver.readObject(filePath);\n const array = Array.isArray(existing) ? existing : [];\n const index = array.findIndex(x => x.id === item.id);\n if (index === -1)\n throw new Error(`Item with id \"${String(item.id)}\" does not exist`);\n accumulateRemoveDelta(deltas, array[index]);\n const updated = [...array];\n updated.splice(index, 1);\n await (updated.length === 0\n ? driver.removeEntry(filePath)\n : driver.writeObject(filePath, updated));\n }));\n await applyIndexDeltas(deltas);\n },\n removeAll: async () => {\n const exists = await driver.fileExists(folderName).catch(() => false);\n if (!exists)\n return;\n await driver.removeEntry(folderName, { recursive: true });\n },\n });\n}\n"],"names":["createGenericFSAdapter","driver","folderName","itemsDirectoryPathPromise","indexRootPathPromise","readAll","relativeFiles","aggregatedItems","relativePath","fullPath","itemsInFile","ensureIndex","fieldPath","itemsPromise","allItems","indexPath","indexMap","item","fieldValue","get","buckets","rawKey","identifiers","rawKeyString","key","maps","filePath","readIndex","resultIndex","entry","identifier","indicesToMaintain","addToDelta","deltas","field","kind","id","delta","target","addDeltaForChange","oldValue","newValue","oldKey","newKey","accumulateUpsertDelta","existing","next","value","accumulateRemoveDelta","applyIndexDeltas","touchedRawKeys","rawKeyToBucket","touchedBuckets","bucket","data","bucketIndex","ids","set","out","upsertItems","items","mode","array","index","x","updated","createStorageAdapter","pathToDrop","itemsToInsert","itemsToReplace","itemsToRemove"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@signaldb/generic-fs",
3
+ "version": "2.0.0-beta.0",
4
+ "description": "",
5
+ "scripts": {
6
+ "build": "rimraf dist && vite build",
7
+ "analyze-bundle": "bundle-analyzer ./dist --upload-token=$BUNDLE_ANALYZER_UPLOAD_TOKEN --bundle-name=@signaldb/generic-fs",
8
+ "test": "vitest"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/maxnowack/signaldb.git"
13
+ },
14
+ "homepage": "https://signaldb.js.org",
15
+ "keywords": [
16
+ "filesystem",
17
+ "primitives",
18
+ "client-database",
19
+ "client",
20
+ "database",
21
+ "local-database",
22
+ "offline-first",
23
+ "optimistic-ui",
24
+ "plugin",
25
+ "reactive",
26
+ "reactivity",
27
+ "solid",
28
+ "synchronization",
29
+ "typescript"
30
+ ],
31
+ "author": "Max Nowack <max.nowack@gmail.com>",
32
+ "license": "MIT",
33
+ "sideEffects": false,
34
+ "exports": {
35
+ ".": {
36
+ "types": "./dist/index.d.ts",
37
+ "import": "./dist/index.mjs",
38
+ "require": "./dist/index.umd.js",
39
+ "default": "./dist/index.umd.js"
40
+ }
41
+ },
42
+ "main": "./dist/index.umd.js",
43
+ "module": "./dist/index.mjs",
44
+ "types": "./dist/index.d.ts",
45
+ "typesVersions": {
46
+ "*": {
47
+ "*": [
48
+ "./dist/*",
49
+ "./dist/index.d.ts"
50
+ ]
51
+ }
52
+ },
53
+ "files": [
54
+ "dist"
55
+ ],
56
+ "peerDependencies": {
57
+ "@signaldb/core": "2.0.0-beta.0"
58
+ }
59
+ }