@signaldb/opfs 1.0.0 → 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 CHANGED
@@ -1,5 +1,5 @@
1
1
  # @signaldb/opfs
2
2
 
3
- This is the OPFS persistence adapter for [SignalDB](https://github.com/maxnowack/signaldb). SignalDB is a local-first JavaScript database with real-time sync, enabling optimistic UI with signal-based reactivity across multiple frameworks.
3
+ This is the OPFS storage adapter for [SignalDB](https://github.com/maxnowack/signaldb). SignalDB is a local-first JavaScript database with real-time sync, enabling optimistic UI with signal-based reactivity across multiple frameworks.
4
4
 
5
5
  See https://signaldb.js.org/reference/opfs/ for more information.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  * and deserialization.
6
6
  * @template T - The type of the items in the collection.
7
7
  * @template I - The type of the unique identifier for the items.
8
- * @param filename - The name of the file in OPFS where data will be stored.
8
+ * @param folderName - The name of the file in OPFS where data will be stored.
9
9
  * @param options - Optional configuration for serialization and deserialization.
10
10
  * @param options.serialize - A function to serialize items to a string (default: `JSON.stringify`).
11
11
  * @param options.deserialize - A function to deserialize a string into items (default: `JSON.parse`).
@@ -27,7 +27,7 @@
27
27
  */
28
28
  export default function createOPFSAdapter<T extends {
29
29
  id: I;
30
- } & Record<string, any>, I>(filename: string, options?: {
31
- serialize?: (items: T[]) => string;
32
- deserialize?: (itemsString: string) => T[];
33
- }): import("@signaldb/core").PersistenceAdapter<T, I>;
30
+ } & Record<string, any>, I>(folderName: string, options?: {
31
+ serialize?: (data: any) => string;
32
+ deserialize?: (input: string) => any;
33
+ }): import("@signaldb/core").StorageAdapter<T, I>;
package/dist/index.mjs CHANGED
@@ -1,53 +1,270 @@
1
- import { createPersistenceAdapter as p } from "@signaldb/core";
2
- function F(l, u) {
3
- const { serialize: g = JSON.stringify, deserialize: h = JSON.parse } = u || {};
4
- let e = null;
5
- async function f() {
6
- const s = await (await (await navigator.storage.getDirectory()).getFileHandle(l, { create: !0 })).getFile().then((c) => c.text());
7
- return h(s || "[]");
8
- }
9
- return p({
10
- async register(r) {
11
- await (await navigator.storage.getDirectory()).getFileHandle(l, { create: !0 }), r();
12
- },
13
- async load() {
14
- return e && await e, { items: await f() };
15
- },
16
- async save(r, { added: o, modified: s, removed: c }) {
17
- e && await e;
18
- const d = await (await navigator.storage.getDirectory()).getFileHandle(l, { create: !0 });
19
- if (o.length === 0 && s.length === 0 && c.length === 0) {
20
- const i = await d.createWritable();
21
- await i.write(g(r)), await i.close(), await e;
1
+ import { createStorageAdapter as $, get as b, serializeValue as M } from "@signaldb/core";
2
+ function H(e, P) {
3
+ const m = e.joinPath(P, "items"), v = e.joinPath(P, "index"), x = async () => {
4
+ if (!await e.fileExists(await m).catch(() => !1))
5
+ return [];
6
+ const r = await e.listFilesRecursive(await m), i = [];
7
+ return await Promise.all(r.map(async (n) => {
8
+ const a = await e.joinPath(await m, n), c = await e.readObject(a);
9
+ Array.isArray(c) && i.push(...c);
10
+ })), i;
11
+ }, S = async (r, i = x()) => {
12
+ const n = await i, a = await e.joinPath(await v, await e.fileNameForIndexKey(r));
13
+ await e.removeEntry(a, { recursive: !0 }).catch(() => {
14
+ }), await e.ensureDir(a);
15
+ const c = /* @__PURE__ */ new Map();
16
+ for (const l of n) {
17
+ const d = b(l, r);
18
+ d != null && (c.has(d) || c.set(d, /* @__PURE__ */ new Set()), c.get(d)?.add(l.id));
19
+ }
20
+ const w = {};
21
+ for (const [l, d] of c) {
22
+ const u = String(l), I = await e.fileNameForIndexKey(u);
23
+ w[I] || (w[I] = []), w[I].push({ [u]: [...d] });
24
+ }
25
+ await Promise.all(Object.entries(w).map(async ([l, d]) => {
26
+ const u = await e.joinPath(a, l);
27
+ await e.writeIndexObject(u, d);
28
+ }));
29
+ }, D = async (r) => {
30
+ const i = await e.joinPath(await v, await e.fileNameForIndexKey(r));
31
+ if (!await e.fileExists(i).catch(() => !1))
32
+ throw new Error(`Index on field "${r}" does not exist`);
33
+ const n = await e.listFilesRecursive(i), a = /* @__PURE__ */ new Map();
34
+ return await Promise.all(n.map(async (c) => {
35
+ const w = await e.joinPath(i, c), l = await e.readIndexObject(w);
36
+ if (Array.isArray(l))
37
+ for (const d of l)
38
+ for (const [u, I] of Object.entries(d)) {
39
+ a.has(u) || a.set(u, /* @__PURE__ */ new Set());
40
+ for (const j of I)
41
+ a.get(u)?.add(j);
42
+ }
43
+ })), a;
44
+ }, t = [], o = (r, i, n, a, c) => {
45
+ r.has(i) || r.set(i, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });
46
+ const w = r.get(i);
47
+ if (!w)
48
+ return;
49
+ const l = n === "add" ? w.adds : w.removes;
50
+ l.has(a) || l.set(a, /* @__PURE__ */ new Set()), l.get(a)?.add(c);
51
+ }, y = (r, i, n, a, c) => {
52
+ const w = n == null ? void 0 : String(n), l = a == null ? void 0 : String(a);
53
+ w !== l && (w != null && o(r, i, "remove", w, c), l != null && o(r, i, "add", l, c));
54
+ }, f = (r, i, n) => {
55
+ if (i)
56
+ for (const a of t)
57
+ y(r, a, b(i, a), b(n, a), n.id);
58
+ else
59
+ for (const a of t) {
60
+ const c = b(n, a);
61
+ c != null && o(r, a, "add", String(c), n.id);
62
+ }
63
+ }, s = (r, i) => {
64
+ for (const n of t) {
65
+ const a = b(i, n);
66
+ a != null && o(r, n, "remove", String(a), i.id);
67
+ }
68
+ }, h = async (r) => {
69
+ await Promise.all([...r.entries()].map(async ([i, n]) => {
70
+ const a = await e.joinPath(await v, await e.fileNameForIndexKey(i));
71
+ if (!await e.fileExists(a).catch(() => !1))
22
72
  return;
73
+ await e.ensureDir(a);
74
+ const c = /* @__PURE__ */ new Set([
75
+ ...n.adds.keys(),
76
+ ...n.removes.keys()
77
+ ]), w = /* @__PURE__ */ new Map();
78
+ await Promise.all([...c].map(async (d) => {
79
+ w.set(d, await e.fileNameForIndexKey(d));
80
+ }));
81
+ const l = new Set(w.values());
82
+ await Promise.all([...l].map(async (d) => {
83
+ const u = await e.joinPath(a, d), I = await e.readIndexObject(u), j = /* @__PURE__ */ new Map();
84
+ if (Array.isArray(I))
85
+ for (const E of I)
86
+ for (const [p, g] of Object.entries(E))
87
+ j.set(p, new Set(g));
88
+ if (n.removes.forEach((E, p) => {
89
+ if (w.get(p) !== d)
90
+ return;
91
+ const g = j.get(p);
92
+ g && (E.forEach((A) => g.delete(A)), g.size === 0 && j.delete(p));
93
+ }), n.adds.forEach((E, p) => {
94
+ if (w.get(p) !== d)
95
+ return;
96
+ let g = j.get(p);
97
+ g || (g = /* @__PURE__ */ new Set(), j.set(p, g)), E.forEach((A) => g.add(A));
98
+ }), j.size === 0) {
99
+ await e.fileExists(u).catch(() => !1) && await e.removeEntry(u).catch(() => {
100
+ });
101
+ return;
102
+ }
103
+ const N = [];
104
+ j.forEach((E, p) => {
105
+ N.push({ [p]: [...E] });
106
+ }), await e.writeIndexObject(u, N);
107
+ }));
108
+ }));
109
+ }, O = async (r, i) => {
110
+ const n = /* @__PURE__ */ new Map();
111
+ await Promise.all(r.map(async (a) => {
112
+ const c = await e.joinPath(await m, await e.fileNameForId(a.id)), w = await e.readObject(c), l = Array.isArray(w) ? w : [], d = l.findIndex((u) => u.id === a.id);
113
+ if (i === "insert") {
114
+ if (d !== -1)
115
+ throw new Error(`Item with id "${String(a.id)}" already exists`);
116
+ f(n, void 0, a), await e.writeObject(c, [...l, a]);
117
+ } else {
118
+ if (d === -1)
119
+ throw new Error(`Item with id "${String(a.id)}" does not exist`);
120
+ f(n, l[d], a);
121
+ const u = [...l];
122
+ u[d] = a, await e.writeObject(c, u);
23
123
  }
24
- e = f().then((i) => {
25
- const t = i.slice();
26
- return o.forEach((a) => {
27
- t.push(a);
28
- }), s.forEach((a) => {
29
- const n = t.findIndex(({ id: w }) => w === a.id);
30
- /* istanbul ignore if -- @preserve */
31
- if (n === -1)
32
- throw new Error(`Item with ID ${a.id} not found`);
33
- t[n] = a;
34
- }), c.forEach((a) => {
35
- const n = t.findIndex(({ id: w }) => w === a.id);
36
- /* istanbul ignore if -- @preserve */
37
- if (n === -1)
38
- throw new Error(`Item with ID ${a.id} not found`);
39
- t.splice(n, 1);
40
- }), t;
41
- }).then(async (i) => {
42
- const t = await d.createWritable();
43
- await t.write(g(i)), await t.close();
44
- }).then(() => {
45
- e = null;
46
- }), await e;
124
+ })), await h(n);
125
+ };
126
+ return $({
127
+ setup: async () => {
128
+ await e.ensureDir(P);
129
+ },
130
+ teardown: async () => {
131
+ },
132
+ readAll: x,
133
+ readIds: async (r) => (await Promise.all(r.map(async (i) => {
134
+ const n = await e.joinPath(await m, await e.fileNameForId(i)), a = await e.readObject(n);
135
+ return Array.isArray(a) ? a.find((c) => c.id === i) ?? null : null;
136
+ }))).filter((i) => i != null),
137
+ createIndex: async (r) => {
138
+ t.push(r), await S(r);
139
+ },
140
+ dropIndex: async (r) => {
141
+ const i = await e.joinPath(await v, await e.fileNameForIndexKey(r));
142
+ if (!await e.fileExists(i).catch(() => !1))
143
+ throw new Error(`Index on field "${r}" does not exist`);
144
+ await e.removeEntry(i, { recursive: !0 });
145
+ },
146
+ readIndex: D,
147
+ insert: async (r) => {
148
+ await O(r, "insert");
149
+ },
150
+ replace: async (r) => {
151
+ await O(r, "replace");
152
+ },
153
+ remove: async (r) => {
154
+ const i = /* @__PURE__ */ new Map();
155
+ await Promise.all(r.map(async (n) => {
156
+ const a = await e.joinPath(await m, await e.fileNameForId(n.id)), c = await e.readObject(a), w = Array.isArray(c) ? c : [], l = w.findIndex((u) => u.id === n.id);
157
+ if (l === -1)
158
+ throw new Error(`Item with id "${String(n.id)}" does not exist`);
159
+ s(i, w[l]);
160
+ const d = [...w];
161
+ d.splice(l, 1), await (d.length === 0 ? e.removeEntry(a) : e.writeObject(a, d));
162
+ })), await h(i);
163
+ },
164
+ removeAll: async () => {
165
+ await e.fileExists(P).catch(() => !1) && await e.removeEntry(P, { recursive: !0 });
47
166
  }
48
167
  });
49
168
  }
169
+ function F(e) {
170
+ let m = e.normalize("NFC");
171
+ const v = (x) => x.replaceAll(/[-/\\^$*+?.()|[\]{}]/g, String.raw`\$&`);
172
+ return m = m.replaceAll("/", "_"), m = m.replaceAll(new RegExp(`${v("_")}{2,}`, "g"), "_"), m || (m = "unnamed"), m;
173
+ }
174
+ function R(e, P) {
175
+ const { serialize: m = JSON.stringify, deserialize: v = JSON.parse } = P || {}, x = async (t, o, y) => {
176
+ const f = o.split("/").filter(Boolean);
177
+ let s = t;
178
+ for (const h of f)
179
+ s = await s.getDirectoryHandle(h, { create: y });
180
+ return s;
181
+ }, S = async (t, o, y) => {
182
+ const f = o.split("/").filter(Boolean), s = f.pop();
183
+ return (await x(t, f.join("/"), y)).getFileHandle(s, { create: y });
184
+ }, D = {
185
+ fileNameForId: (t) => {
186
+ if (typeof t != "string" && typeof t != "number")
187
+ return Promise.resolve(F(M(t)));
188
+ const o = typeof t == "string" ? t : t.toString(16).padStart(4, "0"), y = F(o.slice(0, 2) || "00"), f = F(o.slice(2, 4) || "00");
189
+ return Promise.resolve(`${y}/${f}/${F(o)}`);
190
+ },
191
+ fileNameForIndexKey: (t) => Promise.resolve(F(t)),
192
+ joinPath: (...t) => Promise.resolve(t.join("/")),
193
+ ensureDir: async (t) => {
194
+ const o = await navigator.storage.getDirectory();
195
+ await x(o, t, !0);
196
+ },
197
+ fileExists: async (t) => {
198
+ const o = await navigator.storage.getDirectory();
199
+ try {
200
+ return await S(o, t, !1), !0;
201
+ } catch {
202
+ const y = t.split("/").filter(Boolean);
203
+ let f = o;
204
+ for (const s of y)
205
+ try {
206
+ f = await f.getDirectoryHandle(s);
207
+ } catch {
208
+ return !1;
209
+ }
210
+ return !0;
211
+ }
212
+ },
213
+ readObject: async (t) => {
214
+ const o = await navigator.storage.getDirectory();
215
+ try {
216
+ const s = await (await (await S(o, t, !1)).getFile()).text();
217
+ return v(s);
218
+ } catch {
219
+ return null;
220
+ }
221
+ },
222
+ writeObject: async (t, o) => {
223
+ const y = await navigator.storage.getDirectory(), s = await (await S(y, t, !0)).createWritable(), h = m(o);
224
+ await s.write(h), await s.close();
225
+ },
226
+ readIndexObject: async (t) => {
227
+ const o = await navigator.storage.getDirectory();
228
+ try {
229
+ const s = await (await (await S(o, t, !1)).getFile()).text();
230
+ return v(s);
231
+ } catch {
232
+ return null;
233
+ }
234
+ },
235
+ writeIndexObject: async (t, o) => {
236
+ const y = await navigator.storage.getDirectory(), s = await (await S(y, t, !0)).createWritable(), h = m(o);
237
+ await s.write(h), await s.close();
238
+ },
239
+ listFilesRecursive: async (t) => {
240
+ const o = await navigator.storage.getDirectory();
241
+ let y;
242
+ try {
243
+ y = await x(o, t, !1);
244
+ } catch {
245
+ /* istanbul ignore next -- @preserve */
246
+ return [];
247
+ }
248
+ const f = [];
249
+ for await (const s of y.values())
250
+ if (s.kind === "file")
251
+ f.push(s.name);
252
+ else if (s.kind === "directory") {
253
+ const h = await D.listFilesRecursive(`${t}/${s.name}`);
254
+ f.push(...h.map((O) => `${s.name}/${O}`));
255
+ }
256
+ return f;
257
+ },
258
+ removeEntry: async (t, o) => {
259
+ const y = await navigator.storage.getDirectory(), f = t.split("/").filter(Boolean), s = f.pop();
260
+ if (!s)
261
+ throw new Error("Invalid path");
262
+ await (f.length > 0 ? await x(y, f.join("/"), !1) : y).removeEntry(s, { recursive: !!o?.recursive });
263
+ }
264
+ };
265
+ return H(D, e);
266
+ }
50
267
  export {
51
- F as default
268
+ R as default
52
269
  };
53
270
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { createPersistenceAdapter } from '@signaldb/core';\n/**\n * Creates a persistence adapter for managing a SignalDB collection using the\n * Origin Private File System (OPFS). This adapter allows data to be stored and managed\n * directly in the browser's file system with support for customizable serialization\n * and deserialization.\n * @template T - The type of the items in the collection.\n * @template I - The type of the unique identifier for the items.\n * @param filename - The name of the file in OPFS where data will be stored.\n * @param options - Optional configuration for serialization and deserialization.\n * @param options.serialize - A function to serialize items to a string (default: `JSON.stringify`).\n * @param options.deserialize - A function to deserialize a string into items (default: `JSON.parse`).\n * @returns A SignalDB persistence adapter for managing data in OPFS.\n * @example\n * import createOPFSAdapter from './createOPFSAdapter';\n * import { Collection } from '@signaldb/core';\n *\n * const adapter = createOPFSAdapter('myCollection.json', {\n * serialize: (items) => JSON.stringify(items, null, 2), // Pretty-print JSON\n * deserialize: (itemsString) => JSON.parse(itemsString), // Default JSON parse\n * });\n *\n * const collection = new Collection({\n * persistence: adapter,\n * });\n *\n * // Perform operations on the collection, and changes will be reflected in the OPFS file.\n */\nexport default function createOPFSAdapter(filename, options) {\n const { serialize = JSON.stringify, deserialize = JSON.parse } = options || {};\n let savePromise = null;\n async function getItems() {\n const opfsRoot = await navigator.storage.getDirectory();\n const existingFileHandle = await opfsRoot.getFileHandle(filename, { create: true });\n const contents = await existingFileHandle.getFile().then(val => val.text());\n return deserialize(contents || '[]');\n }\n return createPersistenceAdapter({\n async register(onChange) {\n const opfsRoot = await navigator.storage.getDirectory();\n await opfsRoot.getFileHandle(filename, { create: true });\n void onChange();\n },\n async load() {\n if (savePromise)\n await savePromise;\n const items = await getItems();\n return { items };\n },\n async save(_items, { added, modified, removed }) {\n if (savePromise)\n await savePromise;\n const opfsRoot = await navigator.storage.getDirectory();\n const existingFileHandle = await opfsRoot.getFileHandle(filename, { create: true });\n if (added.length === 0 && modified.length === 0 && removed.length === 0) {\n const writeStream = await existingFileHandle.createWritable();\n await writeStream.write(serialize(_items));\n await writeStream.close();\n await savePromise;\n return;\n }\n savePromise = getItems()\n .then((currentItems) => {\n const items = currentItems.slice();\n added.forEach((item) => {\n items.push(item);\n });\n modified.forEach((item) => {\n const index = items.findIndex(({ id }) => id === item.id);\n /* istanbul ignore if -- @preserve */\n if (index === -1)\n throw new Error(`Item with ID ${item.id} not found`);\n items[index] = item;\n });\n removed.forEach((item) => {\n const index = items.findIndex(({ id }) => id === item.id);\n /* istanbul ignore if -- @preserve */\n if (index === -1)\n throw new Error(`Item with ID ${item.id} not found`);\n items.splice(index, 1);\n });\n return items;\n })\n .then(async (items) => {\n const writeStream = await existingFileHandle.createWritable();\n await writeStream.write(serialize(items));\n await writeStream.close();\n })\n .then(() => {\n savePromise = null;\n });\n await savePromise;\n },\n });\n}\n"],"names":["createOPFSAdapter","filename","options","serialize","deserialize","savePromise","getItems","contents","val","createPersistenceAdapter","onChange","_items","added","modified","removed","existingFileHandle","writeStream","currentItems","items","item","index","id"],"mappings":";AA4BwB,SAAAA,EAAkBC,GAAUC,GAAS;AACnD,QAAA,EAAE,WAAAC,IAAY,KAAK,WAAW,aAAAC,IAAc,KAAK,UAAUF,KAAW,CAAC;AAC7E,MAAIG,IAAc;AAClB,iBAAeC,IAAW;AAGhB,UAAAC,IAAW,OADU,OADV,MAAM,UAAU,QAAQ,aAAa,GACZ,cAAcN,GAAU,EAAE,QAAQ,IAAM,GACxC,UAAU,KAAK,CAAAO,MAAOA,EAAI,MAAM;AACnE,WAAAJ,EAAYG,KAAY,IAAI;AAAA,EAAA;AAEvC,SAAOE,EAAyB;AAAA,IAC5B,MAAM,SAASC,GAAU;AAErB,aADiB,MAAM,UAAU,QAAQ,aAAa,GACvC,cAAcT,GAAU,EAAE,QAAQ,IAAM,GAClDS,EAAS;AAAA,IAClB;AAAA,IACA,MAAM,OAAO;AACL,aAAAL,KACM,MAAAA,GAEH,EAAE,OADK,MAAMC,EAAS,EACd;AAAA,IACnB;AAAA,IACA,MAAM,KAAKK,GAAQ,EAAE,OAAAC,GAAO,UAAAC,GAAU,SAAAC,KAAW;AACzC,MAAAT,KACM,MAAAA;AAEJ,YAAAU,IAAqB,OADV,MAAM,UAAU,QAAQ,aAAa,GACZ,cAAcd,GAAU,EAAE,QAAQ,IAAM;AAC9E,UAAAW,EAAM,WAAW,KAAKC,EAAS,WAAW,KAAKC,EAAQ,WAAW,GAAG;AAC/D,cAAAE,IAAc,MAAMD,EAAmB,eAAe;AAC5D,cAAMC,EAAY,MAAMb,EAAUQ,CAAM,CAAC,GACzC,MAAMK,EAAY,MAAM,GAClB,MAAAX;AACN;AAAA,MAAA;AAEJ,MAAAA,IAAcC,EAAS,EAClB,KAAK,CAACW,MAAiB;AAClB,cAAAC,IAAQD,EAAa,MAAM;AAC3B,eAAAL,EAAA,QAAQ,CAACO,MAAS;AACpB,UAAAD,EAAM,KAAKC,CAAI;AAAA,QAAA,CAClB,GACQN,EAAA,QAAQ,CAACM,MAAS;AACjB,gBAAAC,IAAQF,EAAM,UAAU,CAAC,EAAE,IAAAG,QAASA,MAAOF,EAAK,EAAE;AAAA,UAAA;AAExD,cAAIC,MAAU;AACV,kBAAM,IAAI,MAAM,gBAAgBD,EAAK,EAAE,YAAY;AACvD,UAAAD,EAAME,CAAK,IAAID;AAAA,QAAA,CAClB,GACOL,EAAA,QAAQ,CAACK,MAAS;AAChB,gBAAAC,IAAQF,EAAM,UAAU,CAAC,EAAE,IAAAG,QAASA,MAAOF,EAAK,EAAE;AAAA,UAAA;AAExD,cAAIC,MAAU;AACV,kBAAM,IAAI,MAAM,gBAAgBD,EAAK,EAAE,YAAY;AACjD,UAAAD,EAAA,OAAOE,GAAO,CAAC;AAAA,QAAA,CACxB,GACMF;AAAA,MAAA,CACV,EACI,KAAK,OAAOA,MAAU;AACjB,cAAAF,IAAc,MAAMD,EAAmB,eAAe;AAC5D,cAAMC,EAAY,MAAMb,EAAUe,CAAK,CAAC,GACxC,MAAMF,EAAY,MAAM;AAAA,MAAA,CAC3B,EACI,KAAK,MAAM;AACE,QAAAX,IAAA;AAAA,MAAA,CACjB,GACK,MAAAA;AAAA,IAAA;AAAA,EACV,CACH;AACL;"}
1
+ {"version":3,"file":"index.mjs","sources":["../../generic-fs/dist/index.mjs","../src/index.ts"],"sourcesContent":["import { createStorageAdapter as K, get as m } from \"@signaldb/core\";\nfunction R(t, x) {\n const h = t.joinPath(x, \"items\"), p = t.joinPath(x, \"index\"), g = async () => {\n if (!await t.fileExists(await h).catch(() => !1))\n return [];\n const n = await t.listFilesRecursive(await h), s = [];\n return await Promise.all(n.map(async (a) => {\n const i = await t.joinPath(await h, a), c = await t.readObject(i);\n Array.isArray(c) && s.push(...c);\n })), s;\n }, O = async (e, n = g()) => {\n const s = await n, a = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n await t.removeEntry(a, { recursive: !0 }).catch(() => {\n }), await t.ensureDir(a);\n const i = /* @__PURE__ */ new Map();\n for (const o of s) {\n const r = m(o, e);\n r != null && (i.has(r) || i.set(r, /* @__PURE__ */ new Set()), i.get(r)?.add(o.id));\n }\n const c = {};\n for (const [o, r] of i) {\n const w = String(o), l = await t.fileNameForIndexKey(w);\n c[l] || (c[l] = []), c[l].push({ [w]: [...r] });\n }\n await Promise.all(Object.entries(c).map(async ([o, r]) => {\n const w = await t.joinPath(a, o);\n await t.writeIndexObject(w, r);\n }));\n }, D = async (e) => {\n const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n if (!await t.fileExists(n).catch(() => !1))\n throw new Error(`Index on field \"${e}\" does not exist`);\n const a = await t.listFilesRecursive(n), i = /* @__PURE__ */ new Map();\n return await Promise.all(a.map(async (c) => {\n const o = await t.joinPath(n, c), r = await t.readIndexObject(o);\n if (Array.isArray(r))\n for (const w of r)\n for (const [l, j] of Object.entries(w)) {\n i.has(l) || i.set(l, /* @__PURE__ */ new Set());\n for (const d of j)\n i.get(l)?.add(d);\n }\n })), i;\n }, I = [], P = (e, n, s, a, i) => {\n e.has(n) || e.set(n, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });\n const c = e.get(n);\n if (!c)\n return;\n const o = s === \"add\" ? c.adds : c.removes;\n o.has(a) || o.set(a, /* @__PURE__ */ new Set()), o.get(a)?.add(i);\n }, M = (e, n, s, a, i) => {\n const c = s == null ? void 0 : String(s), o = a == null ? void 0 : String(a);\n c !== o && (c != null && P(e, n, \"remove\", c, i), o != null && P(e, n, \"add\", o, i));\n }, S = (e, n, s) => {\n if (n)\n for (const a of I)\n M(e, a, m(n, a), m(s, a), s.id);\n else\n for (const a of I) {\n const i = m(s, a);\n i != null && P(e, a, \"add\", String(i), s.id);\n }\n }, k = (e, n) => {\n for (const s of I) {\n const a = m(n, s);\n a != null && P(e, s, \"remove\", String(a), n.id);\n }\n }, F = async (e) => {\n await Promise.all([...e.entries()].map(async ([n, s]) => {\n const a = await t.joinPath(await p, await t.fileNameForIndexKey(n));\n if (!await t.fileExists(a).catch(() => !1))\n return;\n await t.ensureDir(a);\n const c = /* @__PURE__ */ new Set([\n ...s.adds.keys(),\n ...s.removes.keys()\n ]), o = /* @__PURE__ */ new Map();\n await Promise.all([...c].map(async (w) => {\n o.set(w, await t.fileNameForIndexKey(w));\n }));\n const r = new Set(o.values());\n await Promise.all([...r].map(async (w) => {\n const l = await t.joinPath(a, w), j = await t.readIndexObject(l), d = /* @__PURE__ */ new Map();\n if (Array.isArray(j))\n for (const y of j)\n for (const [f, u] of Object.entries(y))\n d.set(f, new Set(u));\n if (s.removes.forEach((y, f) => {\n if (o.get(f) !== w)\n return;\n const u = d.get(f);\n u && (y.forEach((E) => u.delete(E)), u.size === 0 && d.delete(f));\n }), s.adds.forEach((y, f) => {\n if (o.get(f) !== w)\n return;\n let u = d.get(f);\n u || (u = /* @__PURE__ */ new Set(), d.set(f, u)), y.forEach((E) => u.add(E));\n }), d.size === 0) {\n await t.fileExists(l).catch(() => !1) && await t.removeEntry(l).catch(() => {\n });\n return;\n }\n const b = [];\n d.forEach((y, f) => {\n b.push({ [f]: [...y] });\n }), await t.writeIndexObject(l, b);\n }));\n }));\n }, A = async (e, n) => {\n const s = /* @__PURE__ */ new Map();\n await Promise.all(e.map(async (a) => {\n 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);\n if (n === \"insert\") {\n if (r !== -1)\n throw new Error(`Item with id \"${String(a.id)}\" already exists`);\n S(s, void 0, a), await t.writeObject(i, [...o, a]);\n } else {\n if (r === -1)\n throw new Error(`Item with id \"${String(a.id)}\" does not exist`);\n S(s, o[r], a);\n const w = [...o];\n w[r] = a, await t.writeObject(i, w);\n }\n })), await F(s);\n };\n return K({\n setup: async () => {\n await t.ensureDir(x);\n },\n teardown: async () => {\n },\n readAll: g,\n readIds: async (e) => (await Promise.all(e.map(async (s) => {\n const a = await t.joinPath(await h, await t.fileNameForId(s)), i = await t.readObject(a);\n return Array.isArray(i) ? i.find((c) => c.id === s) ?? null : null;\n }))).filter((s) => s != null),\n createIndex: async (e) => {\n I.push(e), await O(e);\n },\n dropIndex: async (e) => {\n const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n if (!await t.fileExists(n).catch(() => !1))\n throw new Error(`Index on field \"${e}\" does not exist`);\n await t.removeEntry(n, { recursive: !0 });\n },\n readIndex: D,\n insert: async (e) => {\n await A(e, \"insert\");\n },\n replace: async (e) => {\n await A(e, \"replace\");\n },\n remove: async (e) => {\n const n = /* @__PURE__ */ new Map();\n await Promise.all(e.map(async (s) => {\n 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);\n if (o === -1)\n throw new Error(`Item with id \"${String(s.id)}\" does not exist`);\n k(n, c[o]);\n const r = [...c];\n r.splice(o, 1), await (r.length === 0 ? t.removeEntry(a) : t.writeObject(a, r));\n })), await F(n);\n },\n removeAll: async () => {\n await t.fileExists(x).catch(() => !1) && await t.removeEntry(x, { recursive: !0 });\n }\n });\n}\nexport {\n R as default\n};\n//# sourceMappingURL=index.mjs.map\n","import createGenericFSAdapter from '@signaldb/generic-fs';\nimport { serializeValue } from '@signaldb/core';\n/**\n * Convert an arbitrary filename into a OPFS safe filename.\n * @param input - The input filename to sanitize.\n * @returns A safe filename.\n */\nfunction toSafeFilename(input) {\n const replacement = '_';\n let name = input.normalize('NFC');\n const escapeRegex = (s) => s.replaceAll(/[-/\\\\^$*+?.()|[\\]{}]/g, String.raw `\\$&`);\n name = name.replaceAll('/', replacement);\n name = name.replaceAll(new RegExp(`${escapeRegex(replacement)}{2,}`, 'g'), replacement);\n if (!name)\n name = 'unnamed';\n return name;\n}\n/**\n * Creates a persistence adapter for managing a SignalDB collection using the\n * Origin Private File System (OPFS). This adapter allows data to be stored and managed\n * directly in the browser's file system with support for customizable serialization\n * and deserialization.\n * @template T - The type of the items in the collection.\n * @template I - The type of the unique identifier for the items.\n * @param folderName - The name of the file in OPFS where data will be stored.\n * @param options - Optional configuration for serialization and deserialization.\n * @param options.serialize - A function to serialize items to a string (default: `JSON.stringify`).\n * @param options.deserialize - A function to deserialize a string into items (default: `JSON.parse`).\n * @returns A SignalDB persistence adapter for managing data in OPFS.\n * @example\n * import createOPFSAdapter from './createOPFSAdapter';\n * import { Collection } from '@signaldb/core';\n *\n * const adapter = createOPFSAdapter('myCollection.json', {\n * serialize: (items) => JSON.stringify(items, null, 2), // Pretty-print JSON\n * deserialize: (itemsString) => JSON.parse(itemsString), // Default JSON parse\n * });\n *\n * const collection = new Collection({\n * persistence: adapter,\n * });\n *\n * // Perform operations on the collection, and changes will be reflected in the OPFS file.\n */\nexport default function createOPFSAdapter(folderName, options) {\n const { serialize = JSON.stringify, deserialize = JSON.parse } = options || {};\n const ensureDirectoryExists = async (rootDirectory, directoryPath, createIfMissing) => {\n const parts = directoryPath.split('/').filter(Boolean);\n let current = rootDirectory;\n for (const part of parts) {\n current = await current.getDirectoryHandle(part, { create: createIfMissing });\n }\n return current;\n };\n const getFileHandleForPath = async (rootDirectory, fullPath, createIfMissing) => {\n const parts = fullPath.split('/').filter(Boolean);\n const fileName = parts.pop();\n const directoryHandle = await ensureDirectoryExists(rootDirectory, parts.join('/'), createIfMissing);\n return directoryHandle.getFileHandle(fileName, { create: createIfMissing });\n };\n const driver = {\n fileNameForId: (id) => {\n if (typeof id !== 'string' && typeof id !== 'number') {\n return Promise.resolve(toSafeFilename(serializeValue(id)));\n }\n const idString = typeof id === 'string' ? id : id.toString(16).padStart(4, '0');\n const firstShard = toSafeFilename(idString.slice(0, 2) || '00');\n const secondShard = toSafeFilename(idString.slice(2, 4) || '00');\n return Promise.resolve(`${firstShard}/${secondShard}/${toSafeFilename(idString)}`);\n },\n fileNameForIndexKey: key => Promise.resolve(toSafeFilename(key)),\n joinPath: (...parts) => Promise.resolve(parts.join('/')),\n ensureDir: async (directoryPath) => {\n const rootDirectory = await navigator.storage.getDirectory();\n await ensureDirectoryExists(rootDirectory, directoryPath, true);\n },\n fileExists: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n await getFileHandleForPath(rootDirectory, path, false);\n return true;\n }\n catch {\n const parts = path.split('/').filter(Boolean);\n let directory = rootDirectory;\n for (const part of parts) {\n try {\n directory = await directory.getDirectoryHandle(part);\n }\n catch {\n return false;\n }\n }\n return true;\n }\n },\n readObject: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n const handle = await getFileHandleForPath(rootDirectory, path, false);\n const file = await handle.getFile();\n const text = await file.text();\n return deserialize(text);\n }\n catch {\n return null;\n }\n },\n writeObject: async (path, value) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const handle = await getFileHandleForPath(rootDirectory, path, true);\n const writableStream = await handle.createWritable();\n const text = serialize(value);\n await writableStream.write(text);\n await writableStream.close();\n },\n readIndexObject: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n const handle = await getFileHandleForPath(rootDirectory, path, false);\n const file = await handle.getFile();\n const text = await file.text();\n return deserialize(text);\n }\n catch {\n return null;\n }\n },\n writeIndexObject: async (path, value) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const handle = await getFileHandleForPath(rootDirectory, path, true);\n const writableStream = await handle.createWritable();\n const text = serialize(value);\n await writableStream.write(text);\n await writableStream.close();\n },\n listFilesRecursive: async (directoryPath) => {\n const rootDirectory = await navigator.storage.getDirectory();\n let directoryHandle;\n try {\n directoryHandle = await ensureDirectoryExists(rootDirectory, directoryPath, false);\n }\n catch {\n /* istanbul ignore next -- @preserve */\n return [];\n }\n const files = [];\n // @ts-expect-error -- for-await-of on FileSystemDirectoryHandle is not in types yet\n for await (const entry of directoryHandle.values()) {\n if (entry.kind === 'file') {\n files.push(entry.name);\n }\n else if (entry.kind === 'directory') {\n const subFiles = await driver.listFilesRecursive(`${directoryPath}/${entry.name}`);\n files.push(...subFiles.map(f => `${entry.name}/${f}`));\n }\n }\n return files;\n },\n removeEntry: async (path, removeOptions) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const pathParts = path.split('/').filter(Boolean);\n const name = pathParts.pop();\n if (!name)\n throw new Error('Invalid path');\n const parent = pathParts.length > 0\n ? await ensureDirectoryExists(rootDirectory, pathParts.join('/'), false)\n : rootDirectory;\n await parent.removeEntry(name, { recursive: Boolean(removeOptions?.recursive) });\n },\n };\n return createGenericFSAdapter(driver, folderName);\n}\n"],"names":["R","t","x","h","p","g","n","s","a","i","O","e","o","r","m","c","w","l","j","d","I","P","M","S","k","F","y","f","u","E","b","A","K","toSafeFilename","input","name","escapeRegex","createOPFSAdapter","folderName","options","serialize","deserialize","ensureDirectoryExists","rootDirectory","directoryPath","createIfMissing","parts","current","part","getFileHandleForPath","fullPath","fileName","driver","id","serializeValue","idString","firstShard","secondShard","key","path","directory","text","value","writableStream","directoryHandle","files","entry","subFiles","removeOptions","pathParts","createGenericFSAdapter"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(n,o){typeof exports=="object"&&typeof module<"u"?module.exports=o(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],o):(n=typeof globalThis<"u"?globalThis:n||self,n.SignalDB=o(n.core))})(this,function(n){"use strict";function o(f,p){const{serialize:u=JSON.stringify,deserialize:y=JSON.parse}=p||{};let e=null;async function g(){const l=await(await(await navigator.storage.getDirectory()).getFileHandle(f,{create:!0})).getFile().then(d=>d.text());return y(l||"[]")}return n.createPersistenceAdapter({async register(r){await(await navigator.storage.getDirectory()).getFileHandle(f,{create:!0}),r()},async load(){return e&&await e,{items:await g()}},async save(r,{added:c,modified:l,removed:d}){e&&await e;const h=await(await navigator.storage.getDirectory()).getFileHandle(f,{create:!0});if(c.length===0&&l.length===0&&d.length===0){const a=await h.createWritable();await a.write(u(r)),await a.close(),await e;return}e=g().then(a=>{const t=a.slice();return c.forEach(i=>{t.push(i)}),l.forEach(i=>{const s=t.findIndex(({id:w})=>w===i.id);/* istanbul ignore if -- @preserve */if(s===-1)throw new Error(`Item with ID ${i.id} not found`);t[s]=i}),d.forEach(i=>{const s=t.findIndex(({id:w})=>w===i.id);/* istanbul ignore if -- @preserve */if(s===-1)throw new Error(`Item with ID ${i.id} not found`);t.splice(s,1)}),t}).then(async a=>{const t=await h.createWritable();await t.write(u(a)),await t.close()}).then(()=>{e=null}),await e}})}return o});
1
+ (function(h,D){typeof exports=="object"&&typeof module<"u"?module.exports=D(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],D):(h=typeof globalThis<"u"?globalThis:h||self,h.SignalDB=D(h.core))})(this,(function(h){"use strict";function D(e,S){const m=e.joinPath(S,"items"),x=e.joinPath(S,"index"),j=async()=>{if(!await e.fileExists(await m).catch(()=>!1))return[];const r=await e.listFilesRecursive(await m),i=[];return await Promise.all(r.map(async n=>{const t=await e.joinPath(await m,n),c=await e.readObject(t);Array.isArray(c)&&i.push(...c)})),i},b=async(r,i=j())=>{const n=await i,t=await e.joinPath(await x,await e.fileNameForIndexKey(r));await e.removeEntry(t,{recursive:!0}).catch(()=>{}),await e.ensureDir(t);const c=new Map;for(const l of n){const d=h.get(l,r);d!=null&&(c.has(d)||c.set(d,new Set),c.get(d)?.add(l.id))}const w={};for(const[l,d]of c){const u=String(l),I=await e.fileNameForIndexKey(u);w[I]||(w[I]=[]),w[I].push({[u]:[...d]})}await Promise.all(Object.entries(w).map(async([l,d])=>{const u=await e.joinPath(t,l);await e.writeIndexObject(u,d)}))},O=async r=>{const i=await e.joinPath(await x,await e.fileNameForIndexKey(r));if(!await e.fileExists(i).catch(()=>!1))throw new Error(`Index on field "${r}" does not exist`);const n=await e.listFilesRecursive(i),t=new Map;return await Promise.all(n.map(async c=>{const w=await e.joinPath(i,c),l=await e.readIndexObject(w);if(Array.isArray(l))for(const d of l)for(const[u,I]of Object.entries(d)){t.has(u)||t.set(u,new Set);for(const P of I)t.get(u)?.add(P)}})),t},a=[],o=(r,i,n,t,c)=>{r.has(i)||r.set(i,{adds:new Map,removes:new Map});const w=r.get(i);if(!w)return;const l=n==="add"?w.adds:w.removes;l.has(t)||l.set(t,new Set),l.get(t)?.add(c)},y=(r,i,n,t,c)=>{const w=n==null?void 0:String(n),l=t==null?void 0:String(t);w!==l&&(w!=null&&o(r,i,"remove",w,c),l!=null&&o(r,i,"add",l,c))},f=(r,i,n)=>{if(i)for(const t of a)y(r,t,h.get(i,t),h.get(n,t),n.id);else for(const t of a){const c=h.get(n,t);c!=null&&o(r,t,"add",String(c),n.id)}},s=(r,i)=>{for(const n of a){const t=h.get(i,n);t!=null&&o(r,n,"remove",String(t),i.id)}},p=async r=>{await Promise.all([...r.entries()].map(async([i,n])=>{const t=await e.joinPath(await x,await e.fileNameForIndexKey(i));if(!await e.fileExists(t).catch(()=>!1))return;await e.ensureDir(t);const c=new Set([...n.adds.keys(),...n.removes.keys()]),w=new Map;await Promise.all([...c].map(async d=>{w.set(d,await e.fileNameForIndexKey(d))}));const l=new Set(w.values());await Promise.all([...l].map(async d=>{const u=await e.joinPath(t,d),I=await e.readIndexObject(u),P=new Map;if(Array.isArray(I))for(const E of I)for(const[g,v]of Object.entries(E))P.set(g,new Set(v));if(n.removes.forEach((E,g)=>{if(w.get(g)!==d)return;const v=P.get(g);v&&(E.forEach(N=>v.delete(N)),v.size===0&&P.delete(g))}),n.adds.forEach((E,g)=>{if(w.get(g)!==d)return;let v=P.get(g);v||(v=new Set,P.set(g,v)),E.forEach(N=>v.add(N))}),P.size===0){await e.fileExists(u).catch(()=>!1)&&await e.removeEntry(u).catch(()=>{});return}const $=[];P.forEach((E,g)=>{$.push({[g]:[...E]})}),await e.writeIndexObject(u,$)}))}))},A=async(r,i)=>{const n=new Map;await Promise.all(r.map(async t=>{const c=await e.joinPath(await m,await e.fileNameForId(t.id)),w=await e.readObject(c),l=Array.isArray(w)?w:[],d=l.findIndex(u=>u.id===t.id);if(i==="insert"){if(d!==-1)throw new Error(`Item with id "${String(t.id)}" already exists`);f(n,void 0,t),await e.writeObject(c,[...l,t])}else{if(d===-1)throw new Error(`Item with id "${String(t.id)}" does not exist`);f(n,l[d],t);const u=[...l];u[d]=t,await e.writeObject(c,u)}})),await p(n)};return h.createStorageAdapter({setup:async()=>{await e.ensureDir(S)},teardown:async()=>{},readAll:j,readIds:async r=>(await Promise.all(r.map(async i=>{const n=await e.joinPath(await m,await e.fileNameForId(i)),t=await e.readObject(n);return Array.isArray(t)?t.find(c=>c.id===i)??null:null}))).filter(i=>i!=null),createIndex:async r=>{a.push(r),await b(r)},dropIndex:async r=>{const i=await e.joinPath(await x,await e.fileNameForIndexKey(r));if(!await e.fileExists(i).catch(()=>!1))throw new Error(`Index on field "${r}" does not exist`);await e.removeEntry(i,{recursive:!0})},readIndex:O,insert:async r=>{await A(r,"insert")},replace:async r=>{await A(r,"replace")},remove:async r=>{const i=new Map;await Promise.all(r.map(async n=>{const t=await e.joinPath(await m,await e.fileNameForId(n.id)),c=await e.readObject(t),w=Array.isArray(c)?c:[],l=w.findIndex(u=>u.id===n.id);if(l===-1)throw new Error(`Item with id "${String(n.id)}" does not exist`);s(i,w[l]);const d=[...w];d.splice(l,1),await(d.length===0?e.removeEntry(t):e.writeObject(t,d))})),await p(i)},removeAll:async()=>{await e.fileExists(S).catch(()=>!1)&&await e.removeEntry(S,{recursive:!0})}})}function F(e){let m=e.normalize("NFC");const x=j=>j.replaceAll(/[-/\\^$*+?.()|[\]{}]/g,String.raw`\$&`);return m=m.replaceAll("/","_"),m=m.replaceAll(new RegExp(`${x("_")}{2,}`,"g"),"_"),m||(m="unnamed"),m}function M(e,S){const{serialize:m=JSON.stringify,deserialize:x=JSON.parse}=S||{},j=async(a,o,y)=>{const f=o.split("/").filter(Boolean);let s=a;for(const p of f)s=await s.getDirectoryHandle(p,{create:y});return s},b=async(a,o,y)=>{const f=o.split("/").filter(Boolean),s=f.pop();return(await j(a,f.join("/"),y)).getFileHandle(s,{create:y})},O={fileNameForId:a=>{if(typeof a!="string"&&typeof a!="number")return Promise.resolve(F(h.serializeValue(a)));const o=typeof a=="string"?a:a.toString(16).padStart(4,"0"),y=F(o.slice(0,2)||"00"),f=F(o.slice(2,4)||"00");return Promise.resolve(`${y}/${f}/${F(o)}`)},fileNameForIndexKey:a=>Promise.resolve(F(a)),joinPath:(...a)=>Promise.resolve(a.join("/")),ensureDir:async a=>{const o=await navigator.storage.getDirectory();await j(o,a,!0)},fileExists:async a=>{const o=await navigator.storage.getDirectory();try{return await b(o,a,!1),!0}catch{const y=a.split("/").filter(Boolean);let f=o;for(const s of y)try{f=await f.getDirectoryHandle(s)}catch{return!1}return!0}},readObject:async a=>{const o=await navigator.storage.getDirectory();try{const s=await(await(await b(o,a,!1)).getFile()).text();return x(s)}catch{return null}},writeObject:async(a,o)=>{const y=await navigator.storage.getDirectory(),s=await(await b(y,a,!0)).createWritable(),p=m(o);await s.write(p),await s.close()},readIndexObject:async a=>{const o=await navigator.storage.getDirectory();try{const s=await(await(await b(o,a,!1)).getFile()).text();return x(s)}catch{return null}},writeIndexObject:async(a,o)=>{const y=await navigator.storage.getDirectory(),s=await(await b(y,a,!0)).createWritable(),p=m(o);await s.write(p),await s.close()},listFilesRecursive:async a=>{const o=await navigator.storage.getDirectory();let y;try{y=await j(o,a,!1)}catch{/* istanbul ignore next -- @preserve */return[]}const f=[];for await(const s of y.values())if(s.kind==="file")f.push(s.name);else if(s.kind==="directory"){const p=await O.listFilesRecursive(`${a}/${s.name}`);f.push(...p.map(A=>`${s.name}/${A}`))}return f},removeEntry:async(a,o)=>{const y=await navigator.storage.getDirectory(),f=a.split("/").filter(Boolean),s=f.pop();if(!s)throw new Error("Invalid path");await(f.length>0?await j(y,f.join("/"),!1):y).removeEntry(s,{recursive:!!o?.recursive})}};return D(O,e)}return M}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { createPersistenceAdapter } from '@signaldb/core';\n/**\n * Creates a persistence adapter for managing a SignalDB collection using the\n * Origin Private File System (OPFS). This adapter allows data to be stored and managed\n * directly in the browser's file system with support for customizable serialization\n * and deserialization.\n * @template T - The type of the items in the collection.\n * @template I - The type of the unique identifier for the items.\n * @param filename - The name of the file in OPFS where data will be stored.\n * @param options - Optional configuration for serialization and deserialization.\n * @param options.serialize - A function to serialize items to a string (default: `JSON.stringify`).\n * @param options.deserialize - A function to deserialize a string into items (default: `JSON.parse`).\n * @returns A SignalDB persistence adapter for managing data in OPFS.\n * @example\n * import createOPFSAdapter from './createOPFSAdapter';\n * import { Collection } from '@signaldb/core';\n *\n * const adapter = createOPFSAdapter('myCollection.json', {\n * serialize: (items) => JSON.stringify(items, null, 2), // Pretty-print JSON\n * deserialize: (itemsString) => JSON.parse(itemsString), // Default JSON parse\n * });\n *\n * const collection = new Collection({\n * persistence: adapter,\n * });\n *\n * // Perform operations on the collection, and changes will be reflected in the OPFS file.\n */\nexport default function createOPFSAdapter(filename, options) {\n const { serialize = JSON.stringify, deserialize = JSON.parse } = options || {};\n let savePromise = null;\n async function getItems() {\n const opfsRoot = await navigator.storage.getDirectory();\n const existingFileHandle = await opfsRoot.getFileHandle(filename, { create: true });\n const contents = await existingFileHandle.getFile().then(val => val.text());\n return deserialize(contents || '[]');\n }\n return createPersistenceAdapter({\n async register(onChange) {\n const opfsRoot = await navigator.storage.getDirectory();\n await opfsRoot.getFileHandle(filename, { create: true });\n void onChange();\n },\n async load() {\n if (savePromise)\n await savePromise;\n const items = await getItems();\n return { items };\n },\n async save(_items, { added, modified, removed }) {\n if (savePromise)\n await savePromise;\n const opfsRoot = await navigator.storage.getDirectory();\n const existingFileHandle = await opfsRoot.getFileHandle(filename, { create: true });\n if (added.length === 0 && modified.length === 0 && removed.length === 0) {\n const writeStream = await existingFileHandle.createWritable();\n await writeStream.write(serialize(_items));\n await writeStream.close();\n await savePromise;\n return;\n }\n savePromise = getItems()\n .then((currentItems) => {\n const items = currentItems.slice();\n added.forEach((item) => {\n items.push(item);\n });\n modified.forEach((item) => {\n const index = items.findIndex(({ id }) => id === item.id);\n /* istanbul ignore if -- @preserve */\n if (index === -1)\n throw new Error(`Item with ID ${item.id} not found`);\n items[index] = item;\n });\n removed.forEach((item) => {\n const index = items.findIndex(({ id }) => id === item.id);\n /* istanbul ignore if -- @preserve */\n if (index === -1)\n throw new Error(`Item with ID ${item.id} not found`);\n items.splice(index, 1);\n });\n return items;\n })\n .then(async (items) => {\n const writeStream = await existingFileHandle.createWritable();\n await writeStream.write(serialize(items));\n await writeStream.close();\n })\n .then(() => {\n savePromise = null;\n });\n await savePromise;\n },\n });\n}\n"],"names":["createOPFSAdapter","filename","options","serialize","deserialize","savePromise","getItems","contents","val","createPersistenceAdapter","onChange","_items","added","modified","removed","existingFileHandle","writeStream","currentItems","items","item","index","id"],"mappings":"4QA4BwB,SAAAA,EAAkBC,EAAUC,EAAS,CACnD,KAAA,CAAE,UAAAC,EAAY,KAAK,UAAW,YAAAC,EAAc,KAAK,OAAUF,GAAW,CAAC,EAC7E,IAAIG,EAAc,KAClB,eAAeC,GAAW,CAGhB,MAAAC,EAAW,MADU,MADV,MAAM,UAAU,QAAQ,aAAa,GACZ,cAAcN,EAAU,CAAE,OAAQ,GAAM,GACxC,UAAU,KAAKO,GAAOA,EAAI,MAAM,EACnE,OAAAJ,EAAYG,GAAY,IAAI,CAAA,CAEvC,OAAOE,2BAAyB,CAC5B,MAAM,SAASC,EAAU,CAErB,MADiB,MAAM,UAAU,QAAQ,aAAa,GACvC,cAAcT,EAAU,CAAE,OAAQ,GAAM,EAClDS,EAAS,CAClB,EACA,MAAM,MAAO,CACL,OAAAL,GACM,MAAAA,EAEH,CAAE,MADK,MAAMC,EAAS,CACd,CACnB,EACA,MAAM,KAAKK,EAAQ,CAAE,MAAAC,EAAO,SAAAC,EAAU,QAAAC,GAAW,CACzCT,GACM,MAAAA,EAEJ,MAAAU,EAAqB,MADV,MAAM,UAAU,QAAQ,aAAa,GACZ,cAAcd,EAAU,CAAE,OAAQ,GAAM,EAC9E,GAAAW,EAAM,SAAW,GAAKC,EAAS,SAAW,GAAKC,EAAQ,SAAW,EAAG,CAC/D,MAAAE,EAAc,MAAMD,EAAmB,eAAe,EAC5D,MAAMC,EAAY,MAAMb,EAAUQ,CAAM,CAAC,EACzC,MAAMK,EAAY,MAAM,EAClB,MAAAX,EACN,MAAA,CAEJA,EAAcC,EAAS,EAClB,KAAMW,GAAiB,CAClB,MAAAC,EAAQD,EAAa,MAAM,EAC3B,OAAAL,EAAA,QAASO,GAAS,CACpBD,EAAM,KAAKC,CAAI,CAAA,CAClB,EACQN,EAAA,QAASM,GAAS,CACjB,MAAAC,EAAQF,EAAM,UAAU,CAAC,CAAE,GAAAG,KAASA,IAAOF,EAAK,EAAE,EAAA,qCAExD,GAAIC,IAAU,GACV,MAAM,IAAI,MAAM,gBAAgBD,EAAK,EAAE,YAAY,EACvDD,EAAME,CAAK,EAAID,CAAA,CAClB,EACOL,EAAA,QAASK,GAAS,CAChB,MAAAC,EAAQF,EAAM,UAAU,CAAC,CAAE,GAAAG,KAASA,IAAOF,EAAK,EAAE,EAAA,qCAExD,GAAIC,IAAU,GACV,MAAM,IAAI,MAAM,gBAAgBD,EAAK,EAAE,YAAY,EACjDD,EAAA,OAAOE,EAAO,CAAC,CAAA,CACxB,EACMF,CAAA,CACV,EACI,KAAK,MAAOA,GAAU,CACjB,MAAAF,EAAc,MAAMD,EAAmB,eAAe,EAC5D,MAAMC,EAAY,MAAMb,EAAUe,CAAK,CAAC,EACxC,MAAMF,EAAY,MAAM,CAAA,CAC3B,EACI,KAAK,IAAM,CACEX,EAAA,IAAA,CACjB,EACK,MAAAA,CAAA,CACV,CACH,CACL"}
1
+ {"version":3,"file":"index.umd.js","sources":["../../generic-fs/dist/index.mjs","../src/index.ts"],"sourcesContent":["import { createStorageAdapter as K, get as m } from \"@signaldb/core\";\nfunction R(t, x) {\n const h = t.joinPath(x, \"items\"), p = t.joinPath(x, \"index\"), g = async () => {\n if (!await t.fileExists(await h).catch(() => !1))\n return [];\n const n = await t.listFilesRecursive(await h), s = [];\n return await Promise.all(n.map(async (a) => {\n const i = await t.joinPath(await h, a), c = await t.readObject(i);\n Array.isArray(c) && s.push(...c);\n })), s;\n }, O = async (e, n = g()) => {\n const s = await n, a = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n await t.removeEntry(a, { recursive: !0 }).catch(() => {\n }), await t.ensureDir(a);\n const i = /* @__PURE__ */ new Map();\n for (const o of s) {\n const r = m(o, e);\n r != null && (i.has(r) || i.set(r, /* @__PURE__ */ new Set()), i.get(r)?.add(o.id));\n }\n const c = {};\n for (const [o, r] of i) {\n const w = String(o), l = await t.fileNameForIndexKey(w);\n c[l] || (c[l] = []), c[l].push({ [w]: [...r] });\n }\n await Promise.all(Object.entries(c).map(async ([o, r]) => {\n const w = await t.joinPath(a, o);\n await t.writeIndexObject(w, r);\n }));\n }, D = async (e) => {\n const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n if (!await t.fileExists(n).catch(() => !1))\n throw new Error(`Index on field \"${e}\" does not exist`);\n const a = await t.listFilesRecursive(n), i = /* @__PURE__ */ new Map();\n return await Promise.all(a.map(async (c) => {\n const o = await t.joinPath(n, c), r = await t.readIndexObject(o);\n if (Array.isArray(r))\n for (const w of r)\n for (const [l, j] of Object.entries(w)) {\n i.has(l) || i.set(l, /* @__PURE__ */ new Set());\n for (const d of j)\n i.get(l)?.add(d);\n }\n })), i;\n }, I = [], P = (e, n, s, a, i) => {\n e.has(n) || e.set(n, { adds: /* @__PURE__ */ new Map(), removes: /* @__PURE__ */ new Map() });\n const c = e.get(n);\n if (!c)\n return;\n const o = s === \"add\" ? c.adds : c.removes;\n o.has(a) || o.set(a, /* @__PURE__ */ new Set()), o.get(a)?.add(i);\n }, M = (e, n, s, a, i) => {\n const c = s == null ? void 0 : String(s), o = a == null ? void 0 : String(a);\n c !== o && (c != null && P(e, n, \"remove\", c, i), o != null && P(e, n, \"add\", o, i));\n }, S = (e, n, s) => {\n if (n)\n for (const a of I)\n M(e, a, m(n, a), m(s, a), s.id);\n else\n for (const a of I) {\n const i = m(s, a);\n i != null && P(e, a, \"add\", String(i), s.id);\n }\n }, k = (e, n) => {\n for (const s of I) {\n const a = m(n, s);\n a != null && P(e, s, \"remove\", String(a), n.id);\n }\n }, F = async (e) => {\n await Promise.all([...e.entries()].map(async ([n, s]) => {\n const a = await t.joinPath(await p, await t.fileNameForIndexKey(n));\n if (!await t.fileExists(a).catch(() => !1))\n return;\n await t.ensureDir(a);\n const c = /* @__PURE__ */ new Set([\n ...s.adds.keys(),\n ...s.removes.keys()\n ]), o = /* @__PURE__ */ new Map();\n await Promise.all([...c].map(async (w) => {\n o.set(w, await t.fileNameForIndexKey(w));\n }));\n const r = new Set(o.values());\n await Promise.all([...r].map(async (w) => {\n const l = await t.joinPath(a, w), j = await t.readIndexObject(l), d = /* @__PURE__ */ new Map();\n if (Array.isArray(j))\n for (const y of j)\n for (const [f, u] of Object.entries(y))\n d.set(f, new Set(u));\n if (s.removes.forEach((y, f) => {\n if (o.get(f) !== w)\n return;\n const u = d.get(f);\n u && (y.forEach((E) => u.delete(E)), u.size === 0 && d.delete(f));\n }), s.adds.forEach((y, f) => {\n if (o.get(f) !== w)\n return;\n let u = d.get(f);\n u || (u = /* @__PURE__ */ new Set(), d.set(f, u)), y.forEach((E) => u.add(E));\n }), d.size === 0) {\n await t.fileExists(l).catch(() => !1) && await t.removeEntry(l).catch(() => {\n });\n return;\n }\n const b = [];\n d.forEach((y, f) => {\n b.push({ [f]: [...y] });\n }), await t.writeIndexObject(l, b);\n }));\n }));\n }, A = async (e, n) => {\n const s = /* @__PURE__ */ new Map();\n await Promise.all(e.map(async (a) => {\n 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);\n if (n === \"insert\") {\n if (r !== -1)\n throw new Error(`Item with id \"${String(a.id)}\" already exists`);\n S(s, void 0, a), await t.writeObject(i, [...o, a]);\n } else {\n if (r === -1)\n throw new Error(`Item with id \"${String(a.id)}\" does not exist`);\n S(s, o[r], a);\n const w = [...o];\n w[r] = a, await t.writeObject(i, w);\n }\n })), await F(s);\n };\n return K({\n setup: async () => {\n await t.ensureDir(x);\n },\n teardown: async () => {\n },\n readAll: g,\n readIds: async (e) => (await Promise.all(e.map(async (s) => {\n const a = await t.joinPath(await h, await t.fileNameForId(s)), i = await t.readObject(a);\n return Array.isArray(i) ? i.find((c) => c.id === s) ?? null : null;\n }))).filter((s) => s != null),\n createIndex: async (e) => {\n I.push(e), await O(e);\n },\n dropIndex: async (e) => {\n const n = await t.joinPath(await p, await t.fileNameForIndexKey(e));\n if (!await t.fileExists(n).catch(() => !1))\n throw new Error(`Index on field \"${e}\" does not exist`);\n await t.removeEntry(n, { recursive: !0 });\n },\n readIndex: D,\n insert: async (e) => {\n await A(e, \"insert\");\n },\n replace: async (e) => {\n await A(e, \"replace\");\n },\n remove: async (e) => {\n const n = /* @__PURE__ */ new Map();\n await Promise.all(e.map(async (s) => {\n 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);\n if (o === -1)\n throw new Error(`Item with id \"${String(s.id)}\" does not exist`);\n k(n, c[o]);\n const r = [...c];\n r.splice(o, 1), await (r.length === 0 ? t.removeEntry(a) : t.writeObject(a, r));\n })), await F(n);\n },\n removeAll: async () => {\n await t.fileExists(x).catch(() => !1) && await t.removeEntry(x, { recursive: !0 });\n }\n });\n}\nexport {\n R as default\n};\n//# sourceMappingURL=index.mjs.map\n","import createGenericFSAdapter from '@signaldb/generic-fs';\nimport { serializeValue } from '@signaldb/core';\n/**\n * Convert an arbitrary filename into a OPFS safe filename.\n * @param input - The input filename to sanitize.\n * @returns A safe filename.\n */\nfunction toSafeFilename(input) {\n const replacement = '_';\n let name = input.normalize('NFC');\n const escapeRegex = (s) => s.replaceAll(/[-/\\\\^$*+?.()|[\\]{}]/g, String.raw `\\$&`);\n name = name.replaceAll('/', replacement);\n name = name.replaceAll(new RegExp(`${escapeRegex(replacement)}{2,}`, 'g'), replacement);\n if (!name)\n name = 'unnamed';\n return name;\n}\n/**\n * Creates a persistence adapter for managing a SignalDB collection using the\n * Origin Private File System (OPFS). This adapter allows data to be stored and managed\n * directly in the browser's file system with support for customizable serialization\n * and deserialization.\n * @template T - The type of the items in the collection.\n * @template I - The type of the unique identifier for the items.\n * @param folderName - The name of the file in OPFS where data will be stored.\n * @param options - Optional configuration for serialization and deserialization.\n * @param options.serialize - A function to serialize items to a string (default: `JSON.stringify`).\n * @param options.deserialize - A function to deserialize a string into items (default: `JSON.parse`).\n * @returns A SignalDB persistence adapter for managing data in OPFS.\n * @example\n * import createOPFSAdapter from './createOPFSAdapter';\n * import { Collection } from '@signaldb/core';\n *\n * const adapter = createOPFSAdapter('myCollection.json', {\n * serialize: (items) => JSON.stringify(items, null, 2), // Pretty-print JSON\n * deserialize: (itemsString) => JSON.parse(itemsString), // Default JSON parse\n * });\n *\n * const collection = new Collection({\n * persistence: adapter,\n * });\n *\n * // Perform operations on the collection, and changes will be reflected in the OPFS file.\n */\nexport default function createOPFSAdapter(folderName, options) {\n const { serialize = JSON.stringify, deserialize = JSON.parse } = options || {};\n const ensureDirectoryExists = async (rootDirectory, directoryPath, createIfMissing) => {\n const parts = directoryPath.split('/').filter(Boolean);\n let current = rootDirectory;\n for (const part of parts) {\n current = await current.getDirectoryHandle(part, { create: createIfMissing });\n }\n return current;\n };\n const getFileHandleForPath = async (rootDirectory, fullPath, createIfMissing) => {\n const parts = fullPath.split('/').filter(Boolean);\n const fileName = parts.pop();\n const directoryHandle = await ensureDirectoryExists(rootDirectory, parts.join('/'), createIfMissing);\n return directoryHandle.getFileHandle(fileName, { create: createIfMissing });\n };\n const driver = {\n fileNameForId: (id) => {\n if (typeof id !== 'string' && typeof id !== 'number') {\n return Promise.resolve(toSafeFilename(serializeValue(id)));\n }\n const idString = typeof id === 'string' ? id : id.toString(16).padStart(4, '0');\n const firstShard = toSafeFilename(idString.slice(0, 2) || '00');\n const secondShard = toSafeFilename(idString.slice(2, 4) || '00');\n return Promise.resolve(`${firstShard}/${secondShard}/${toSafeFilename(idString)}`);\n },\n fileNameForIndexKey: key => Promise.resolve(toSafeFilename(key)),\n joinPath: (...parts) => Promise.resolve(parts.join('/')),\n ensureDir: async (directoryPath) => {\n const rootDirectory = await navigator.storage.getDirectory();\n await ensureDirectoryExists(rootDirectory, directoryPath, true);\n },\n fileExists: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n await getFileHandleForPath(rootDirectory, path, false);\n return true;\n }\n catch {\n const parts = path.split('/').filter(Boolean);\n let directory = rootDirectory;\n for (const part of parts) {\n try {\n directory = await directory.getDirectoryHandle(part);\n }\n catch {\n return false;\n }\n }\n return true;\n }\n },\n readObject: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n const handle = await getFileHandleForPath(rootDirectory, path, false);\n const file = await handle.getFile();\n const text = await file.text();\n return deserialize(text);\n }\n catch {\n return null;\n }\n },\n writeObject: async (path, value) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const handle = await getFileHandleForPath(rootDirectory, path, true);\n const writableStream = await handle.createWritable();\n const text = serialize(value);\n await writableStream.write(text);\n await writableStream.close();\n },\n readIndexObject: async (path) => {\n const rootDirectory = await navigator.storage.getDirectory();\n try {\n const handle = await getFileHandleForPath(rootDirectory, path, false);\n const file = await handle.getFile();\n const text = await file.text();\n return deserialize(text);\n }\n catch {\n return null;\n }\n },\n writeIndexObject: async (path, value) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const handle = await getFileHandleForPath(rootDirectory, path, true);\n const writableStream = await handle.createWritable();\n const text = serialize(value);\n await writableStream.write(text);\n await writableStream.close();\n },\n listFilesRecursive: async (directoryPath) => {\n const rootDirectory = await navigator.storage.getDirectory();\n let directoryHandle;\n try {\n directoryHandle = await ensureDirectoryExists(rootDirectory, directoryPath, false);\n }\n catch {\n /* istanbul ignore next -- @preserve */\n return [];\n }\n const files = [];\n // @ts-expect-error -- for-await-of on FileSystemDirectoryHandle is not in types yet\n for await (const entry of directoryHandle.values()) {\n if (entry.kind === 'file') {\n files.push(entry.name);\n }\n else if (entry.kind === 'directory') {\n const subFiles = await driver.listFilesRecursive(`${directoryPath}/${entry.name}`);\n files.push(...subFiles.map(f => `${entry.name}/${f}`));\n }\n }\n return files;\n },\n removeEntry: async (path, removeOptions) => {\n const rootDirectory = await navigator.storage.getDirectory();\n const pathParts = path.split('/').filter(Boolean);\n const name = pathParts.pop();\n if (!name)\n throw new Error('Invalid path');\n const parent = pathParts.length > 0\n ? await ensureDirectoryExists(rootDirectory, pathParts.join('/'), false)\n : rootDirectory;\n await parent.removeEntry(name, { recursive: Boolean(removeOptions?.recursive) });\n },\n };\n return createGenericFSAdapter(driver, folderName);\n}\n"],"names":["R","t","x","h","p","g","n","s","a","i","O","e","o","r","m","c","w","l","D","j","d","I","P","M","S","k","F","y","f","u","E","b","K","toSafeFilename","input","name","escapeRegex","createOPFSAdapter","folderName","options","serialize","deserialize","ensureDirectoryExists","rootDirectory","directoryPath","createIfMissing","parts","current","part","getFileHandleForPath","fullPath","fileName","driver","id","serializeValue","idString","firstShard","secondShard","key","path","directory","text","value","writableStream","directoryHandle","files","entry","subFiles","removeOptions","pathParts","createGenericFSAdapter"],"mappings":"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"}
package/package.json CHANGED
@@ -1,9 +1,11 @@
1
1
  {
2
2
  "name": "@signaldb/opfs",
3
- "version": "1.0.0",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "",
5
5
  "scripts": {
6
- "build": "rimraf dist && vite build"
6
+ "build": "rimraf dist && vite build",
7
+ "analyze-bundle": "bundle-analyzer ./dist --upload-token=$BUNDLE_ANALYZER_UPLOAD_TOKEN --bundle-name=@signaldb/opfs",
8
+ "test": "vitest"
7
9
  },
8
10
  "repository": {
9
11
  "type": "git",
@@ -51,6 +53,9 @@
51
53
  "dist"
52
54
  ],
53
55
  "peerDependencies": {
54
- "@signaldb/core": "1.x"
56
+ "@signaldb/core": "2.0.0-beta.0"
57
+ },
58
+ "dependencies": {
59
+ "@signaldb/generic-fs": "^2.0.0-beta.0"
55
60
  }
56
61
  }