@signaldb/indexeddb 2.0.0-beta.4 → 2.0.0-beta.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,141 +1,135 @@
1
- import { createStorageAdapter as E } from "@signaldb/core";
2
- async function f(c, m, d) {
3
- const o = indexedDB.open(c, m), t = new Promise((r, e) => {
4
- o.addEventListener("success", () => r()), o.addEventListener("error", () => e(new Error(o.error?.message || "Database error"))), o.addEventListener("upgradeneeded", (i) => {
5
- const s = o.result, a = o.transaction;
6
- if (d) {
7
- d(s, a, i.oldVersion, i.newVersion ?? null).then(() => r()).catch(
1
+ import { createStorageAdapter as g } from "@signaldb/core";
2
+ async function v(i, l, c) {
3
+ const s = indexedDB.open(i, l), d = new Promise((e, r) => {
4
+ s.addEventListener("success", () => e()), s.addEventListener("error", () => r(new Error(s.error?.message || "Database error"))), s.addEventListener("upgradeneeded", (t) => {
5
+ const a = s.result, n = s.transaction;
6
+ if (c) {
7
+ c(a, n, t.oldVersion, t.newVersion ?? null).then(() => e()).catch(
8
8
  /* istanbul ignore next -- @preserve */
9
- (u) => {
10
- e(u);
9
+ (o) => {
10
+ r(o);
11
11
  }
12
12
  );
13
13
  return;
14
14
  }
15
- r();
15
+ e();
16
16
  });
17
- }), n = new Promise((r, e) => {
18
- o.addEventListener("success", () => r(o.result)), o.addEventListener("error", () => e(new Error(o.error?.message || "Database error")));
17
+ }), u = new Promise((e, r) => {
18
+ s.addEventListener("success", () => e(s.result)), s.addEventListener("error", () => r(new Error(s.error?.message || "Database error")));
19
19
  });
20
20
  return await Promise.all([
21
- n,
22
- t
23
- ]), n;
21
+ u,
22
+ d
23
+ ]), u;
24
24
  }
25
- function x(c) {
26
- const m = c.databaseName || "signaldb", d = f(m, c.version, async (o, t) => {
27
- c.onUpgrade && await c.onUpgrade(o, t, o.version, c.version);
28
- const n = /* @__PURE__ */ new Set();
29
- for (let r = 0; r < o.objectStoreNames.length; r += 1) {
30
- const e = o.objectStoreNames.item(r);
31
- !e || e in c.schema || n.add(e);
25
+ function y(i) {
26
+ const l = i.databaseName || "signaldb", c = v(l, i.version, async (s, d) => {
27
+ i.onUpgrade && await i.onUpgrade(s, d, s.version, i.version);
28
+ const u = /* @__PURE__ */ new Set();
29
+ for (let e = 0; e < s.objectStoreNames.length; e += 1) {
30
+ const r = s.objectStoreNames.item(e);
31
+ !r || r in i.schema || u.add(r);
32
32
  }
33
- n.forEach((r) => {
34
- o.objectStoreNames.contains(r) && o.deleteObjectStore(r);
33
+ u.forEach((e) => {
34
+ s.objectStoreNames.contains(e) && s.deleteObjectStore(e);
35
35
  });
36
- for (const [r, e] of Object.entries(c.schema)) {
37
- const i = o.objectStoreNames.contains(r) ? t.objectStore(r) : o.createObjectStore(r, {
36
+ for (const [e, r] of Object.entries(i.schema)) {
37
+ const t = s.objectStoreNames.contains(e) ? d.objectStore(e) : s.createObjectStore(e, {
38
38
  keyPath: "id"
39
- }), s = /* @__PURE__ */ new Set();
40
- for (let a = 0; a < i.indexNames.length; a += 1) {
41
- const u = i.indexNames.item(a);
42
- !u || e.includes(u) || s.add(u);
39
+ }), a = /* @__PURE__ */ new Set();
40
+ for (let n = 0; n < t.indexNames.length; n += 1) {
41
+ const o = t.indexNames.item(n);
42
+ !o || r.includes(o) || a.add(o);
43
43
  }
44
- s.forEach((a) => {
45
- i.indexNames.contains(a) && i.deleteIndex(a);
46
- }), e.forEach((a) => {
47
- a !== "id" && (i.indexNames.contains(a) || i.createIndex(a, a, { unique: !1 }));
44
+ a.forEach((n) => {
45
+ t.indexNames.contains(n) && t.deleteIndex(n);
46
+ }), r.forEach((n) => {
47
+ n !== "id" && (t.indexNames.contains(n) || t.createIndex(n, n, { unique: !1 }));
48
48
  });
49
49
  }
50
50
  });
51
- return function(t) {
52
- return g(t, d);
51
+ return function(d) {
52
+ return h(d, c);
53
53
  };
54
54
  }
55
- function g(c, m) {
56
- const d = async (t = !1) => {
57
- const n = await m;
58
- if (!n)
55
+ function h(i, l) {
56
+ const c = async (e = !1) => {
57
+ const r = await l;
58
+ if (!r)
59
59
  throw new Error("Database not initialized");
60
- return n.transaction(c, t ? "readwrite" : "readonly").objectStore(c);
60
+ return r.transaction(i, e ? "readwrite" : "readonly").objectStore(i);
61
+ }, s = async (e) => {
62
+ const r = await c();
63
+ if (!r.indexNames.contains(e))
64
+ throw new Error(`Index on field "${e}" does not exist`);
65
+ return new Promise((t, a) => {
66
+ const n = r.index(e), o = /* @__PURE__ */ new Map(), m = n.openCursor();
67
+ m.addEventListener("success", () => {
68
+ const w = m.result;
69
+ if (w) {
70
+ const E = w.key, f = w.value.id;
71
+ o.has(E) || o.set(E, /* @__PURE__ */ new Set()), o.get(E)?.add(f), w.continue();
72
+ } else
73
+ t(o);
74
+ }), m.addEventListener("error", () => a(new Error(m.error?.message || "Error reading index")));
75
+ });
76
+ }, d = async (e) => {
77
+ const r = await c(!0);
78
+ return new Promise((t, a) => {
79
+ const n = r.get(e);
80
+ n.addEventListener("success", () => t(n.result || null)), n.addEventListener("error", () => a(new Error(n.error?.message || "Error fetching item")));
81
+ });
82
+ }, u = async (e) => {
83
+ const r = await c(!0);
84
+ await Promise.all(e.map((t) => new Promise((a, n) => {
85
+ const o = r.put(t);
86
+ o.addEventListener("success", () => a()), o.addEventListener("error", () => n(new Error(o.error?.message || "Error inserting or replacing item")));
87
+ })));
61
88
  };
62
- return E({
89
+ return g({
63
90
  // lifecycle methods
64
91
  setup: async () => {
65
- if (!(await m).objectStoreNames.contains(c))
66
- throw new Error(`Object store "${c}" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);
92
+ if (!(await l).objectStoreNames.contains(i))
93
+ throw new Error(`Object store "${i}" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);
67
94
  },
68
95
  teardown: async () => {
69
- (await m).close();
96
+ (await l).close();
70
97
  },
71
98
  // data retrieval methods
72
99
  readAll: async () => {
73
- const t = await d();
74
- return new Promise((n, r) => {
75
- const e = t.getAll();
76
- e.addEventListener("success", () => n(e.result)), e.addEventListener("error", () => r(new Error(e.error?.message || "Error fetching items")));
100
+ const e = await c();
101
+ return new Promise((r, t) => {
102
+ const a = e.getAll();
103
+ a.addEventListener("success", () => r(a.result)), a.addEventListener("error", () => t(new Error(a.error?.message || "Error fetching items")));
77
104
  });
78
105
  },
79
- readIds: async (t) => {
80
- const n = await d();
81
- return (await Promise.all(t.map((e) => new Promise((i, s) => {
82
- const a = n.get(e);
83
- a.addEventListener("success", () => i(a.result || null)), a.addEventListener("error", () => s(new Error(a.error?.message || "Error fetching item")));
84
- })))).filter((e) => e !== null);
85
- },
106
+ readIds: async (e) => (await Promise.all(e.map((t) => d(t)))).filter((t) => t !== null),
86
107
  // index methods
87
108
  createIndex: async () => {
88
109
  },
89
110
  dropIndex: async () => {
90
111
  },
91
- readIndex: async (t) => {
92
- const n = await d();
93
- if (!n.indexNames.contains(t))
94
- throw new Error(`Index on field "${t}" does not exist`);
95
- return new Promise((r, e) => {
96
- const i = n.index(t), s = /* @__PURE__ */ new Map(), a = i.openCursor();
97
- a.addEventListener("success", () => {
98
- const u = a.result;
99
- if (u) {
100
- const l = u.key, w = u.value.id;
101
- s.has(l) || s.set(l, /* @__PURE__ */ new Set()), s.get(l)?.add(w), u.continue();
102
- } else
103
- r(s);
104
- }), a.addEventListener("error", () => e(new Error(a.error?.message || "Error reading index")));
105
- });
106
- },
112
+ readIndex: s,
107
113
  // data manipulation methods
108
- insert: async (t) => {
109
- const n = await d(!0);
110
- await Promise.all(t.map((r) => new Promise((e, i) => {
111
- const s = n.add(r);
112
- s.addEventListener("success", () => e()), s.addEventListener("error", () => i(new Error(s.error?.message || "Error inserting item")));
113
- })));
114
- },
115
- replace: async (t) => {
116
- const n = await d(!0);
117
- await Promise.all(t.map((r) => new Promise((e, i) => {
118
- const s = n.put(r);
119
- s.addEventListener("success", () => e()), s.addEventListener("error", () => i(new Error(s.error?.message || "Error replacing item")));
120
- })));
121
- },
122
- remove: async (t) => {
123
- const n = await d(!0);
124
- await Promise.all(t.map(async (r) => new Promise((e, i) => {
125
- const s = n.delete(r.id);
126
- s.addEventListener("success", () => e()), s.addEventListener("error", () => i(new Error(s.error?.message || "Error removing item")));
114
+ insert: (e) => u(e),
115
+ replace: (e) => u(e),
116
+ remove: async (e) => {
117
+ const r = await c(!0);
118
+ await Promise.all(e.map(async (t) => new Promise((a, n) => {
119
+ const o = r.delete(t.id);
120
+ o.addEventListener("success", () => a()), o.addEventListener("error", () => n(new Error(o.error?.message || "Error removing item")));
127
121
  })));
128
122
  },
129
123
  removeAll: async () => {
130
- const t = await d(!0);
131
- return new Promise((n, r) => {
132
- const e = t.clear();
133
- e.addEventListener("success", () => n()), e.addEventListener("error", () => r(new Error(e.error?.message || "Error clearing items")));
124
+ const e = await c(!0);
125
+ return new Promise((r, t) => {
126
+ const a = e.clear();
127
+ a.addEventListener("success", () => r()), a.addEventListener("error", () => t(new Error(a.error?.message || "Error clearing items")));
134
128
  });
135
129
  }
136
130
  });
137
131
  }
138
132
  export {
139
- x as default
133
+ y as default
140
134
  };
141
135
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter } from '@signaldb/core';\n/**\n * Opens the IndexedDB database and creates the object store if it doesn't exist.\n * @param databaseName - The name of the database.\n * @param version - The version of the database.\n * @param onUpgrade - Optional callback for handling database upgrades.\n * @returns A promise that resolves with the opened database.\n */\nasync function openDatabase(databaseName, version, onUpgrade) {\n const request = indexedDB.open(databaseName, version);\n const upgradePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n request.addEventListener('upgradeneeded', (event) => {\n const database = request.result;\n const tx = request.transaction;\n if (onUpgrade) {\n onUpgrade(database, tx, event.oldVersion, event.newVersion ?? null)\n .then(() => resolve())\n .catch(\n /* istanbul ignore next -- @preserve */\n (error) => {\n reject(error);\n });\n return;\n }\n // No custom upgrade logic provided, resolve immediately\n /* istanbul ignore next -- @preserve */\n resolve();\n });\n });\n const databasePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n });\n await Promise.all([\n databasePromise,\n upgradePromise,\n ]);\n return databasePromise;\n}\n/**\n * Prepares an IndexedDB storage adapter for SignalDB with the specified options.\n * @param options - Configuration options for the IndexedDB adapter.\n * @param options.databaseName - The name of the IndexedDB database. Defaults to 'signaldb'.\n * @param options.version - The version of the database schema.\n * @param options.schema - An object defining the schema of the database, where keys are store names and values are arrays of index names.\n * @param options.onUpgrade - Optional callback for handling database upgrades.\n * @returns A function that takes a store name and returns a SignalDB storage adapter for that store.\n */\nexport default function prepareIndexedDB(options) {\n const databaseName = options.databaseName || 'signaldb';\n const databasePromise = openDatabase(databaseName, options.version, async (database, tx) => {\n if (options.onUpgrade) {\n await options.onUpgrade(database, tx, database.version, options.version);\n }\n const storesToDelete = new Set();\n for (let i = 0; i < database.objectStoreNames.length; i += 1) {\n const storeName = database.objectStoreNames.item(i);\n if (!storeName || storeName in options.schema)\n continue;\n storesToDelete.add(storeName);\n }\n // Delete stores that are not in the new schema\n storesToDelete.forEach((storeName) => {\n if (!database.objectStoreNames.contains(storeName))\n return;\n database.deleteObjectStore(storeName);\n });\n // Create or update stores as per the new schema\n for (const [storeName, indexes] of Object.entries(options.schema)) {\n const store = database.objectStoreNames.contains(storeName)\n ? tx.objectStore(storeName)\n : database.createObjectStore(storeName, {\n keyPath: 'id',\n });\n const indexesToDrop = new Set();\n for (let i = 0; i < store.indexNames.length; i += 1) {\n const indexName = store.indexNames.item(i);\n if (!indexName || indexes.includes(indexName))\n continue;\n indexesToDrop.add(indexName);\n }\n // Drop indexes that are not in the new schema\n indexesToDrop.forEach((indexName) => {\n if (!store.indexNames.contains(indexName))\n return;\n store.deleteIndex(indexName);\n });\n // Create indexes as per the new schema\n indexes.forEach((index) => {\n if (index === 'id')\n return;\n if (store.indexNames.contains(index))\n return;\n store.createIndex(index, index, { unique: false });\n });\n }\n });\n return function indexedDBAdapter(storeName) {\n return createIndexedDBAdapter(storeName, databasePromise);\n };\n}\n/**\n * Creates a storage adapter for managing a SignalDB collection using IndexedDB.\n * This adapter reads and writes data to an IndexedDB object store, with customizable serialization 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 storeName - A unique name for the collection, used as the database name.\n * @param databasePromise - A promise that resolves to an opened IndexedDB database.\n * @returns A SignalDB storage adapter for managing data in IndexedDB.\n */\nfunction createIndexedDBAdapter(storeName, databasePromise) {\n const getStore = async (writeAccess = false) => {\n const database = await databasePromise;\n if (!database)\n throw new Error('Database not initialized');\n const transaction = database.transaction(storeName, writeAccess ? 'readwrite' : 'readonly');\n const store = transaction.objectStore(storeName);\n return store;\n };\n const readIndex = async (field) => {\n const store = await getStore();\n if (!store.indexNames.contains(field)) {\n throw new Error(`Index on field \"${field}\" does not exist`);\n }\n return new Promise((resolve, reject) => {\n const index = store.index(field);\n const result = new Map();\n const request = index.openCursor();\n request.addEventListener('success', () => {\n const cursor = request.result;\n if (cursor) {\n const key = cursor.key;\n const id = cursor.value.id;\n if (!result.has(key)) {\n result.set(key, new Set());\n }\n result.get(key)?.add(id);\n cursor.continue();\n }\n else {\n resolve(result);\n }\n });\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error reading index')));\n });\n };\n return createStorageAdapter({\n // lifecycle methods\n setup: async () => {\n const database = await databasePromise;\n if (database.objectStoreNames.contains(storeName))\n return;\n throw new Error(`Object store \"${storeName}\" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);\n },\n teardown: async () => {\n const database = await databasePromise;\n database.close();\n },\n // data retrieval methods\n readAll: async () => {\n const store = await getStore();\n return new Promise((resolve, reject) => {\n const request = store.getAll();\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching items')));\n });\n },\n readIds: async (ids) => {\n const store = await getStore();\n const results = await Promise.all(ids.map(id => new Promise((resolve, reject) => {\n const request = store.get(id);\n request.addEventListener('success', () => resolve(request.result || null));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching item')));\n })));\n return results.filter(item => item !== null);\n },\n // index methods\n createIndex: async () => {\n /* noop */\n },\n dropIndex: async () => {\n /* noop */\n },\n readIndex,\n // data manipulation methods\n insert: async (newItems) => {\n const store = await getStore(true);\n await Promise.all(newItems.map(item => new Promise((resolve, reject) => {\n const request = store.add(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error inserting item')));\n })));\n },\n replace: async (items) => {\n const store = await getStore(true);\n await Promise.all(items.map(item => new Promise((resolve, reject) => {\n const request = store.put(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error replacing item')));\n })));\n },\n remove: async (itemsToRemove) => {\n const store = await getStore(true);\n await Promise.all(itemsToRemove.map(async (item) => new Promise((resolve, reject) => {\n const request = store.delete(item.id);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error removing item')));\n })));\n },\n removeAll: async () => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.clear();\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error clearing items')));\n });\n },\n });\n}\n"],"names":["openDatabase","databaseName","version","onUpgrade","request","upgradePromise","resolve","reject","event","database","tx","error","databasePromise","prepareIndexedDB","options","storesToDelete","i","storeName","indexes","store","indexesToDrop","indexName","index","createIndexedDBAdapter","getStore","writeAccess","createStorageAdapter","ids","id","item","field","result","cursor","key","newItems","items","itemsToRemove"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter } from '@signaldb/core';\n/**\n * Opens the IndexedDB database and creates the object store if it doesn't exist.\n * @param databaseName - The name of the database.\n * @param version - The version of the database.\n * @param onUpgrade - Optional callback for handling database upgrades.\n * @returns A promise that resolves with the opened database.\n */\nasync function openDatabase(databaseName, version, onUpgrade) {\n const request = indexedDB.open(databaseName, version);\n const upgradePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n request.addEventListener('upgradeneeded', (event) => {\n const database = request.result;\n const tx = request.transaction;\n if (onUpgrade) {\n onUpgrade(database, tx, event.oldVersion, event.newVersion ?? null)\n .then(() => resolve())\n .catch(\n /* istanbul ignore next -- @preserve */\n (error) => {\n reject(error);\n });\n return;\n }\n // No custom upgrade logic provided, resolve immediately\n /* istanbul ignore next -- @preserve */\n resolve();\n });\n });\n const databasePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n });\n await Promise.all([\n databasePromise,\n upgradePromise,\n ]);\n return databasePromise;\n}\n/**\n * Prepares an IndexedDB storage adapter for SignalDB with the specified options.\n * @param options - Configuration options for the IndexedDB adapter.\n * @param options.databaseName - The name of the IndexedDB database. Defaults to 'signaldb'.\n * @param options.version - The version of the database schema.\n * @param options.schema - An object defining the schema of the database, where keys are store names and values are arrays of index names.\n * @param options.onUpgrade - Optional callback for handling database upgrades.\n * @returns A function that takes a store name and returns a SignalDB storage adapter for that store.\n */\nexport default function prepareIndexedDB(options) {\n const databaseName = options.databaseName || 'signaldb';\n const databasePromise = openDatabase(databaseName, options.version, async (database, tx) => {\n if (options.onUpgrade) {\n await options.onUpgrade(database, tx, database.version, options.version);\n }\n const storesToDelete = new Set();\n for (let i = 0; i < database.objectStoreNames.length; i += 1) {\n const storeName = database.objectStoreNames.item(i);\n if (!storeName || storeName in options.schema)\n continue;\n storesToDelete.add(storeName);\n }\n // Delete stores that are not in the new schema\n storesToDelete.forEach((storeName) => {\n if (!database.objectStoreNames.contains(storeName))\n return;\n database.deleteObjectStore(storeName);\n });\n // Create or update stores as per the new schema\n for (const [storeName, indexes] of Object.entries(options.schema)) {\n const store = database.objectStoreNames.contains(storeName)\n ? tx.objectStore(storeName)\n : database.createObjectStore(storeName, {\n keyPath: 'id',\n });\n const indexesToDrop = new Set();\n for (let i = 0; i < store.indexNames.length; i += 1) {\n const indexName = store.indexNames.item(i);\n if (!indexName || indexes.includes(indexName))\n continue;\n indexesToDrop.add(indexName);\n }\n // Drop indexes that are not in the new schema\n indexesToDrop.forEach((indexName) => {\n if (!store.indexNames.contains(indexName))\n return;\n store.deleteIndex(indexName);\n });\n // Create indexes as per the new schema\n indexes.forEach((index) => {\n if (index === 'id')\n return;\n if (store.indexNames.contains(index))\n return;\n store.createIndex(index, index, { unique: false });\n });\n }\n });\n return function indexedDBAdapter(storeName) {\n return createIndexedDBAdapter(storeName, databasePromise);\n };\n}\n/**\n * Creates a storage adapter for managing a SignalDB collection using IndexedDB.\n * This adapter reads and writes data to an IndexedDB object store, with customizable serialization 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 storeName - A unique name for the collection, used as the database name.\n * @param databasePromise - A promise that resolves to an opened IndexedDB database.\n * @returns A SignalDB storage adapter for managing data in IndexedDB.\n */\nfunction createIndexedDBAdapter(storeName, databasePromise) {\n const getStore = async (writeAccess = false) => {\n const database = await databasePromise;\n if (!database)\n throw new Error('Database not initialized');\n const transaction = database.transaction(storeName, writeAccess ? 'readwrite' : 'readonly');\n const store = transaction.objectStore(storeName);\n return store;\n };\n const readIndex = async (field) => {\n const store = await getStore();\n if (!store.indexNames.contains(field)) {\n throw new Error(`Index on field \"${field}\" does not exist`);\n }\n return new Promise((resolve, reject) => {\n const index = store.index(field);\n const result = new Map();\n const request = index.openCursor();\n request.addEventListener('success', () => {\n const cursor = request.result;\n if (cursor) {\n const key = cursor.key;\n const id = cursor.value.id;\n if (!result.has(key)) {\n result.set(key, new Set());\n }\n result.get(key)?.add(id);\n cursor.continue();\n }\n else {\n resolve(result);\n }\n });\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error reading index')));\n });\n };\n const getById = async (id) => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.get(id);\n request.addEventListener('success', () => resolve(request.result || null));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching item')));\n });\n };\n const insertOrReplace = async (items) => {\n const store = await getStore(true);\n await Promise.all(items.map(item => new Promise((resolve, reject) => {\n const request = store.put(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error inserting or replacing item')));\n })));\n };\n return createStorageAdapter({\n // lifecycle methods\n setup: async () => {\n const database = await databasePromise;\n if (database.objectStoreNames.contains(storeName))\n return;\n throw new Error(`Object store \"${storeName}\" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);\n },\n teardown: async () => {\n const database = await databasePromise;\n database.close();\n },\n // data retrieval methods\n readAll: async () => {\n const store = await getStore();\n return new Promise((resolve, reject) => {\n const request = store.getAll();\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching items')));\n });\n },\n readIds: async (ids) => {\n const results = await Promise.all(ids.map(id => getById(id)));\n return results.filter(item => item !== null);\n },\n // index methods\n createIndex: async () => {\n /* noop */\n },\n dropIndex: async () => {\n /* noop */\n },\n readIndex,\n // data manipulation methods\n insert: items => insertOrReplace(items),\n replace: items => insertOrReplace(items),\n remove: async (itemsToRemove) => {\n const store = await getStore(true);\n await Promise.all(itemsToRemove.map(async (item) => new Promise((resolve, reject) => {\n const request = store.delete(item.id);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error removing item')));\n })));\n },\n removeAll: async () => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.clear();\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error clearing items')));\n });\n },\n });\n}\n"],"names":["openDatabase","databaseName","version","onUpgrade","request","upgradePromise","resolve","reject","event","database","tx","error","databasePromise","prepareIndexedDB","options","storesToDelete","i","storeName","indexes","store","indexesToDrop","indexName","index","createIndexedDBAdapter","getStore","writeAccess","readIndex","field","result","cursor","key","id","getById","insertOrReplace","items","item","createStorageAdapter","ids","itemsToRemove"],"mappings":"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"}
package/dist/index.umd.js CHANGED
@@ -1,2 +1,2 @@
1
- (function(m,w){typeof exports=="object"&&typeof module<"u"?module.exports=w(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],w):(m=typeof globalThis<"u"?globalThis:m||self,m.SignalDB=w(m.core))})(this,(function(m){"use strict";async function w(c,l,d){const a=indexedDB.open(c,l),t=new Promise((r,e)=>{a.addEventListener("success",()=>r()),a.addEventListener("error",()=>e(new Error(a.error?.message||"Database error"))),a.addEventListener("upgradeneeded",i=>{const s=a.result,o=a.transaction;if(d){d(s,o,i.oldVersion,i.newVersion??null).then(()=>r()).catch(u=>{e(u)});return}r()})}),n=new Promise((r,e)=>{a.addEventListener("success",()=>r(a.result)),a.addEventListener("error",()=>e(new Error(a.error?.message||"Database error")))});return await Promise.all([n,t]),n}function f(c){const l=c.databaseName||"signaldb",d=w(l,c.version,async(a,t)=>{c.onUpgrade&&await c.onUpgrade(a,t,a.version,c.version);const n=new Set;for(let r=0;r<a.objectStoreNames.length;r+=1){const e=a.objectStoreNames.item(r);!e||e in c.schema||n.add(e)}n.forEach(r=>{a.objectStoreNames.contains(r)&&a.deleteObjectStore(r)});for(const[r,e]of Object.entries(c.schema)){const i=a.objectStoreNames.contains(r)?t.objectStore(r):a.createObjectStore(r,{keyPath:"id"}),s=new Set;for(let o=0;o<i.indexNames.length;o+=1){const u=i.indexNames.item(o);!u||e.includes(u)||s.add(u)}s.forEach(o=>{i.indexNames.contains(o)&&i.deleteIndex(o)}),e.forEach(o=>{o!=="id"&&(i.indexNames.contains(o)||i.createIndex(o,o,{unique:!1}))})}});return function(t){return g(t,d)}}function g(c,l){const d=async(t=!1)=>{const n=await l;if(!n)throw new Error("Database not initialized");return n.transaction(c,t?"readwrite":"readonly").objectStore(c)},a=async t=>{const n=await d();if(!n.indexNames.contains(t))throw new Error(`Index on field "${t}" does not exist`);return new Promise((r,e)=>{const i=n.index(t),s=new Map,o=i.openCursor();o.addEventListener("success",()=>{const u=o.result;if(u){const E=u.key,h=u.value.id;s.has(E)||s.set(E,new Set),s.get(E)?.add(h),u.continue()}else r(s)}),o.addEventListener("error",()=>e(new Error(o.error?.message||"Error reading index")))})};return m.createStorageAdapter({setup:async()=>{if(!(await l).objectStoreNames.contains(c))throw new Error(`Object store "${c}" does not exist in database. Make sure to define it in the schema when initializing the adapter.`)},teardown:async()=>{(await l).close()},readAll:async()=>{const t=await d();return new Promise((n,r)=>{const e=t.getAll();e.addEventListener("success",()=>n(e.result)),e.addEventListener("error",()=>r(new Error(e.error?.message||"Error fetching items")))})},readIds:async t=>{const n=await d();return(await Promise.all(t.map(e=>new Promise((i,s)=>{const o=n.get(e);o.addEventListener("success",()=>i(o.result||null)),o.addEventListener("error",()=>s(new Error(o.error?.message||"Error fetching item")))})))).filter(e=>e!==null)},createIndex:async()=>{},dropIndex:async()=>{},readIndex:a,insert:async t=>{const n=await d(!0);await Promise.all(t.map(r=>new Promise((e,i)=>{const s=n.add(r);s.addEventListener("success",()=>e()),s.addEventListener("error",()=>i(new Error(s.error?.message||"Error inserting item")))})))},replace:async t=>{const n=await d(!0);await Promise.all(t.map(r=>new Promise((e,i)=>{const s=n.put(r);s.addEventListener("success",()=>e()),s.addEventListener("error",()=>i(new Error(s.error?.message||"Error replacing item")))})))},remove:async t=>{const n=await d(!0);await Promise.all(t.map(async r=>new Promise((e,i)=>{const s=n.delete(r.id);s.addEventListener("success",()=>e()),s.addEventListener("error",()=>i(new Error(s.error?.message||"Error removing item")))})))},removeAll:async()=>{const t=await d(!0);return new Promise((n,r)=>{const e=t.clear();e.addEventListener("success",()=>n()),e.addEventListener("error",()=>r(new Error(e.error?.message||"Error clearing items")))})}})}return f}));
1
+ (function(m,w){typeof exports=="object"&&typeof module<"u"?module.exports=w(require("@signaldb/core")):typeof define=="function"&&define.amd?define(["@signaldb/core"],w):(m=typeof globalThis<"u"?globalThis:m||self,m.SignalDB=w(m.core))})(this,(function(m){"use strict";async function w(i,l,c){const s=indexedDB.open(i,l),d=new Promise((e,r)=>{s.addEventListener("success",()=>e()),s.addEventListener("error",()=>r(new Error(s.error?.message||"Database error"))),s.addEventListener("upgradeneeded",t=>{const o=s.result,n=s.transaction;if(c){c(o,n,t.oldVersion,t.newVersion??null).then(()=>e()).catch(a=>{r(a)});return}e()})}),u=new Promise((e,r)=>{s.addEventListener("success",()=>e(s.result)),s.addEventListener("error",()=>r(new Error(s.error?.message||"Database error")))});return await Promise.all([u,d]),u}function h(i){const l=i.databaseName||"signaldb",c=w(l,i.version,async(s,d)=>{i.onUpgrade&&await i.onUpgrade(s,d,s.version,i.version);const u=new Set;for(let e=0;e<s.objectStoreNames.length;e+=1){const r=s.objectStoreNames.item(e);!r||r in i.schema||u.add(r)}u.forEach(e=>{s.objectStoreNames.contains(e)&&s.deleteObjectStore(e)});for(const[e,r]of Object.entries(i.schema)){const t=s.objectStoreNames.contains(e)?d.objectStore(e):s.createObjectStore(e,{keyPath:"id"}),o=new Set;for(let n=0;n<t.indexNames.length;n+=1){const a=t.indexNames.item(n);!a||r.includes(a)||o.add(a)}o.forEach(n=>{t.indexNames.contains(n)&&t.deleteIndex(n)}),r.forEach(n=>{n!=="id"&&(t.indexNames.contains(n)||t.createIndex(n,n,{unique:!1}))})}});return function(d){return p(d,c)}}function p(i,l){const c=async(e=!1)=>{const r=await l;if(!r)throw new Error("Database not initialized");return r.transaction(i,e?"readwrite":"readonly").objectStore(i)},s=async e=>{const r=await c();if(!r.indexNames.contains(e))throw new Error(`Index on field "${e}" does not exist`);return new Promise((t,o)=>{const n=r.index(e),a=new Map,f=n.openCursor();f.addEventListener("success",()=>{const E=f.result;if(E){const g=E.key,y=E.value.id;a.has(g)||a.set(g,new Set),a.get(g)?.add(y),E.continue()}else t(a)}),f.addEventListener("error",()=>o(new Error(f.error?.message||"Error reading index")))})},d=async e=>{const r=await c(!0);return new Promise((t,o)=>{const n=r.get(e);n.addEventListener("success",()=>t(n.result||null)),n.addEventListener("error",()=>o(new Error(n.error?.message||"Error fetching item")))})},u=async e=>{const r=await c(!0);await Promise.all(e.map(t=>new Promise((o,n)=>{const a=r.put(t);a.addEventListener("success",()=>o()),a.addEventListener("error",()=>n(new Error(a.error?.message||"Error inserting or replacing item")))})))};return m.createStorageAdapter({setup:async()=>{if(!(await l).objectStoreNames.contains(i))throw new Error(`Object store "${i}" does not exist in database. Make sure to define it in the schema when initializing the adapter.`)},teardown:async()=>{(await l).close()},readAll:async()=>{const e=await c();return new Promise((r,t)=>{const o=e.getAll();o.addEventListener("success",()=>r(o.result)),o.addEventListener("error",()=>t(new Error(o.error?.message||"Error fetching items")))})},readIds:async e=>(await Promise.all(e.map(t=>d(t)))).filter(t=>t!==null),createIndex:async()=>{},dropIndex:async()=>{},readIndex:s,insert:e=>u(e),replace:e=>u(e),remove:async e=>{const r=await c(!0);await Promise.all(e.map(async t=>new Promise((o,n)=>{const a=r.delete(t.id);a.addEventListener("success",()=>o()),a.addEventListener("error",()=>n(new Error(a.error?.message||"Error removing item")))})))},removeAll:async()=>{const e=await c(!0);return new Promise((r,t)=>{const o=e.clear();o.addEventListener("success",()=>r()),o.addEventListener("error",()=>t(new Error(o.error?.message||"Error clearing items")))})}})}return h}));
2
2
  //# sourceMappingURL=index.umd.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter } from '@signaldb/core';\n/**\n * Opens the IndexedDB database and creates the object store if it doesn't exist.\n * @param databaseName - The name of the database.\n * @param version - The version of the database.\n * @param onUpgrade - Optional callback for handling database upgrades.\n * @returns A promise that resolves with the opened database.\n */\nasync function openDatabase(databaseName, version, onUpgrade) {\n const request = indexedDB.open(databaseName, version);\n const upgradePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n request.addEventListener('upgradeneeded', (event) => {\n const database = request.result;\n const tx = request.transaction;\n if (onUpgrade) {\n onUpgrade(database, tx, event.oldVersion, event.newVersion ?? null)\n .then(() => resolve())\n .catch(\n /* istanbul ignore next -- @preserve */\n (error) => {\n reject(error);\n });\n return;\n }\n // No custom upgrade logic provided, resolve immediately\n /* istanbul ignore next -- @preserve */\n resolve();\n });\n });\n const databasePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n });\n await Promise.all([\n databasePromise,\n upgradePromise,\n ]);\n return databasePromise;\n}\n/**\n * Prepares an IndexedDB storage adapter for SignalDB with the specified options.\n * @param options - Configuration options for the IndexedDB adapter.\n * @param options.databaseName - The name of the IndexedDB database. Defaults to 'signaldb'.\n * @param options.version - The version of the database schema.\n * @param options.schema - An object defining the schema of the database, where keys are store names and values are arrays of index names.\n * @param options.onUpgrade - Optional callback for handling database upgrades.\n * @returns A function that takes a store name and returns a SignalDB storage adapter for that store.\n */\nexport default function prepareIndexedDB(options) {\n const databaseName = options.databaseName || 'signaldb';\n const databasePromise = openDatabase(databaseName, options.version, async (database, tx) => {\n if (options.onUpgrade) {\n await options.onUpgrade(database, tx, database.version, options.version);\n }\n const storesToDelete = new Set();\n for (let i = 0; i < database.objectStoreNames.length; i += 1) {\n const storeName = database.objectStoreNames.item(i);\n if (!storeName || storeName in options.schema)\n continue;\n storesToDelete.add(storeName);\n }\n // Delete stores that are not in the new schema\n storesToDelete.forEach((storeName) => {\n if (!database.objectStoreNames.contains(storeName))\n return;\n database.deleteObjectStore(storeName);\n });\n // Create or update stores as per the new schema\n for (const [storeName, indexes] of Object.entries(options.schema)) {\n const store = database.objectStoreNames.contains(storeName)\n ? tx.objectStore(storeName)\n : database.createObjectStore(storeName, {\n keyPath: 'id',\n });\n const indexesToDrop = new Set();\n for (let i = 0; i < store.indexNames.length; i += 1) {\n const indexName = store.indexNames.item(i);\n if (!indexName || indexes.includes(indexName))\n continue;\n indexesToDrop.add(indexName);\n }\n // Drop indexes that are not in the new schema\n indexesToDrop.forEach((indexName) => {\n if (!store.indexNames.contains(indexName))\n return;\n store.deleteIndex(indexName);\n });\n // Create indexes as per the new schema\n indexes.forEach((index) => {\n if (index === 'id')\n return;\n if (store.indexNames.contains(index))\n return;\n store.createIndex(index, index, { unique: false });\n });\n }\n });\n return function indexedDBAdapter(storeName) {\n return createIndexedDBAdapter(storeName, databasePromise);\n };\n}\n/**\n * Creates a storage adapter for managing a SignalDB collection using IndexedDB.\n * This adapter reads and writes data to an IndexedDB object store, with customizable serialization 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 storeName - A unique name for the collection, used as the database name.\n * @param databasePromise - A promise that resolves to an opened IndexedDB database.\n * @returns A SignalDB storage adapter for managing data in IndexedDB.\n */\nfunction createIndexedDBAdapter(storeName, databasePromise) {\n const getStore = async (writeAccess = false) => {\n const database = await databasePromise;\n if (!database)\n throw new Error('Database not initialized');\n const transaction = database.transaction(storeName, writeAccess ? 'readwrite' : 'readonly');\n const store = transaction.objectStore(storeName);\n return store;\n };\n const readIndex = async (field) => {\n const store = await getStore();\n if (!store.indexNames.contains(field)) {\n throw new Error(`Index on field \"${field}\" does not exist`);\n }\n return new Promise((resolve, reject) => {\n const index = store.index(field);\n const result = new Map();\n const request = index.openCursor();\n request.addEventListener('success', () => {\n const cursor = request.result;\n if (cursor) {\n const key = cursor.key;\n const id = cursor.value.id;\n if (!result.has(key)) {\n result.set(key, new Set());\n }\n result.get(key)?.add(id);\n cursor.continue();\n }\n else {\n resolve(result);\n }\n });\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error reading index')));\n });\n };\n return createStorageAdapter({\n // lifecycle methods\n setup: async () => {\n const database = await databasePromise;\n if (database.objectStoreNames.contains(storeName))\n return;\n throw new Error(`Object store \"${storeName}\" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);\n },\n teardown: async () => {\n const database = await databasePromise;\n database.close();\n },\n // data retrieval methods\n readAll: async () => {\n const store = await getStore();\n return new Promise((resolve, reject) => {\n const request = store.getAll();\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching items')));\n });\n },\n readIds: async (ids) => {\n const store = await getStore();\n const results = await Promise.all(ids.map(id => new Promise((resolve, reject) => {\n const request = store.get(id);\n request.addEventListener('success', () => resolve(request.result || null));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching item')));\n })));\n return results.filter(item => item !== null);\n },\n // index methods\n createIndex: async () => {\n /* noop */\n },\n dropIndex: async () => {\n /* noop */\n },\n readIndex,\n // data manipulation methods\n insert: async (newItems) => {\n const store = await getStore(true);\n await Promise.all(newItems.map(item => new Promise((resolve, reject) => {\n const request = store.add(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error inserting item')));\n })));\n },\n replace: async (items) => {\n const store = await getStore(true);\n await Promise.all(items.map(item => new Promise((resolve, reject) => {\n const request = store.put(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error replacing item')));\n })));\n },\n remove: async (itemsToRemove) => {\n const store = await getStore(true);\n await Promise.all(itemsToRemove.map(async (item) => new Promise((resolve, reject) => {\n const request = store.delete(item.id);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error removing item')));\n })));\n },\n removeAll: async () => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.clear();\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error clearing items')));\n });\n },\n });\n}\n"],"names":["openDatabase","databaseName","version","onUpgrade","request","upgradePromise","resolve","reject","event","database","tx","error","databasePromise","prepareIndexedDB","options","storesToDelete","i","storeName","indexes","store","indexesToDrop","indexName","index","createIndexedDBAdapter","getStore","writeAccess","readIndex","field","result","cursor","key","id","createStorageAdapter","ids","item","newItems","items","itemsToRemove"],"mappings":"6QAQA,eAAeA,EAAaC,EAAcC,EAASC,EAAW,CAC1D,MAAMC,EAAU,UAAU,KAAKH,EAAcC,CAAO,EAC9CG,EAAiB,IAAI,QAAQ,CAACC,EAASC,IAAW,CACpDH,EAAQ,iBAAiB,UAAW,IAAME,EAAA,CAAS,EACnDF,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,gBAAgB,CAAC,CAAC,EACrGA,EAAQ,iBAAiB,gBAAkBI,GAAU,CACjD,MAAMC,EAAWL,EAAQ,OACnBM,EAAKN,EAAQ,YACnB,GAAID,EAAW,CACXA,EAAUM,EAAUC,EAAIF,EAAM,WAAYA,EAAM,YAAc,IAAI,EAC7D,KAAK,IAAMF,EAAA,CAAS,EACpB,MAEJK,GAAU,CACPJ,EAAOI,CAAK,CAChB,CAAA,EACA,MACJ,CAGAL,EAAA,CACJ,CAAC,CACL,CAAC,EACKM,EAAkB,IAAI,QAAQ,CAACN,EAASC,IAAW,CACrDH,EAAQ,iBAAiB,UAAW,IAAME,EAAQF,EAAQ,MAAM,CAAC,EACjEA,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,gBAAgB,CAAC,CAAC,CACzG,CAAC,EACD,aAAM,QAAQ,IAAI,CACdQ,EACAP,CAAA,CACH,EACMO,CACX,CAUA,SAAwBC,EAAiBC,EAAS,CAC9C,MAAMb,EAAea,EAAQ,cAAgB,WACvCF,EAAkBZ,EAAaC,EAAca,EAAQ,QAAS,MAAOL,EAAUC,IAAO,CACpFI,EAAQ,WACR,MAAMA,EAAQ,UAAUL,EAAUC,EAAID,EAAS,QAASK,EAAQ,OAAO,EAE3E,MAAMC,MAAqB,IAC3B,QAASC,EAAI,EAAGA,EAAIP,EAAS,iBAAiB,OAAQO,GAAK,EAAG,CAC1D,MAAMC,EAAYR,EAAS,iBAAiB,KAAKO,CAAC,EAC9C,CAACC,GAAaA,KAAaH,EAAQ,QAEvCC,EAAe,IAAIE,CAAS,CAChC,CAEAF,EAAe,QAASE,GAAc,CAC7BR,EAAS,iBAAiB,SAASQ,CAAS,GAEjDR,EAAS,kBAAkBQ,CAAS,CACxC,CAAC,EAED,SAAW,CAACA,EAAWC,CAAO,IAAK,OAAO,QAAQJ,EAAQ,MAAM,EAAG,CAC/D,MAAMK,EAAQV,EAAS,iBAAiB,SAASQ,CAAS,EACpDP,EAAG,YAAYO,CAAS,EACxBR,EAAS,kBAAkBQ,EAAW,CACpC,QAAS,IAAA,CACZ,EACCG,MAAoB,IAC1B,QAASJ,EAAI,EAAGA,EAAIG,EAAM,WAAW,OAAQH,GAAK,EAAG,CACjD,MAAMK,EAAYF,EAAM,WAAW,KAAKH,CAAC,EACrC,CAACK,GAAaH,EAAQ,SAASG,CAAS,GAE5CD,EAAc,IAAIC,CAAS,CAC/B,CAEAD,EAAc,QAASC,GAAc,CAC5BF,EAAM,WAAW,SAASE,CAAS,GAExCF,EAAM,YAAYE,CAAS,CAC/B,CAAC,EAEDH,EAAQ,QAASI,GAAU,CACnBA,IAAU,OAEVH,EAAM,WAAW,SAASG,CAAK,GAEnCH,EAAM,YAAYG,EAAOA,EAAO,CAAE,OAAQ,GAAO,EACrD,CAAC,CACL,CACJ,CAAC,EACD,OAAO,SAA0BL,EAAW,CACxC,OAAOM,EAAuBN,EAAWL,CAAe,CAC5D,CACJ,CAUA,SAASW,EAAuBN,EAAWL,EAAiB,CACxD,MAAMY,EAAW,MAAOC,EAAc,KAAU,CAC5C,MAAMhB,EAAW,MAAMG,EACvB,GAAI,CAACH,EACD,MAAM,IAAI,MAAM,0BAA0B,EAG9C,OAFoBA,EAAS,YAAYQ,EAAWQ,EAAc,YAAc,UAAU,EAChE,YAAYR,CAAS,CAEnD,EACMS,EAAY,MAAOC,GAAU,CAC/B,MAAMR,EAAQ,MAAMK,EAAA,EACpB,GAAI,CAACL,EAAM,WAAW,SAASQ,CAAK,EAChC,MAAM,IAAI,MAAM,mBAAmBA,CAAK,kBAAkB,EAE9D,OAAO,IAAI,QAAQ,CAACrB,EAASC,IAAW,CACpC,MAAMe,EAAQH,EAAM,MAAMQ,CAAK,EACzBC,MAAa,IACbxB,EAAUkB,EAAM,WAAA,EACtBlB,EAAQ,iBAAiB,UAAW,IAAM,CACtC,MAAMyB,EAASzB,EAAQ,OACvB,GAAIyB,EAAQ,CACR,MAAMC,EAAMD,EAAO,IACbE,EAAKF,EAAO,MAAM,GACnBD,EAAO,IAAIE,CAAG,GACfF,EAAO,IAAIE,EAAK,IAAI,GAAK,EAE7BF,EAAO,IAAIE,CAAG,GAAG,IAAIC,CAAE,EACvBF,EAAO,SAAA,CACX,MAEIvB,EAAQsB,CAAM,CAEtB,CAAC,EACDxB,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,qBAAqB,CAAC,CAAC,CAC9G,CAAC,CACL,EACA,OAAO4B,uBAAqB,CAExB,MAAO,SAAY,CAEf,GAAI,EADa,MAAMpB,GACV,iBAAiB,SAASK,CAAS,EAEhD,MAAM,IAAI,MAAM,iBAAiBA,CAAS,mGAAmG,CACjJ,EACA,SAAU,SAAY,EACD,MAAML,GACd,MAAA,CACb,EAEA,QAAS,SAAY,CACjB,MAAMO,EAAQ,MAAMK,EAAA,EACpB,OAAO,IAAI,QAAQ,CAAClB,EAASC,IAAW,CACpC,MAAMH,EAAUe,EAAM,OAAA,EACtBf,EAAQ,iBAAiB,UAAW,IAAME,EAAQF,EAAQ,MAAM,CAAC,EACjEA,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,sBAAsB,CAAC,CAAC,CAC/G,CAAC,CACL,EACA,QAAS,MAAO6B,GAAQ,CACpB,MAAMd,EAAQ,MAAMK,EAAA,EAMpB,OALgB,MAAM,QAAQ,IAAIS,EAAI,IAAIF,GAAM,IAAI,QAAQ,CAACzB,EAASC,IAAW,CAC7E,MAAMH,EAAUe,EAAM,IAAIY,CAAE,EAC5B3B,EAAQ,iBAAiB,UAAW,IAAME,EAAQF,EAAQ,QAAU,IAAI,CAAC,EACzEA,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,qBAAqB,CAAC,CAAC,CAC9G,CAAC,CAAC,CAAC,GACY,OAAO8B,GAAQA,IAAS,IAAI,CAC/C,EAEA,YAAa,SAAY,CAEzB,EACA,UAAW,SAAY,CAEvB,EACA,UAAAR,EAEA,OAAQ,MAAOS,GAAa,CACxB,MAAMhB,EAAQ,MAAMK,EAAS,EAAI,EACjC,MAAM,QAAQ,IAAIW,EAAS,OAAY,IAAI,QAAQ,CAAC7B,EAASC,IAAW,CACpE,MAAMH,EAAUe,EAAM,IAAIe,CAAI,EAC9B9B,EAAQ,iBAAiB,UAAW,IAAME,EAAA,CAAS,EACnDF,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,sBAAsB,CAAC,CAAC,CAC/G,CAAC,CAAC,CAAC,CACP,EACA,QAAS,MAAOgC,GAAU,CACtB,MAAMjB,EAAQ,MAAMK,EAAS,EAAI,EACjC,MAAM,QAAQ,IAAIY,EAAM,OAAY,IAAI,QAAQ,CAAC9B,EAASC,IAAW,CACjE,MAAMH,EAAUe,EAAM,IAAIe,CAAI,EAC9B9B,EAAQ,iBAAiB,UAAW,IAAME,EAAA,CAAS,EACnDF,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,sBAAsB,CAAC,CAAC,CAC/G,CAAC,CAAC,CAAC,CACP,EACA,OAAQ,MAAOiC,GAAkB,CAC7B,MAAMlB,EAAQ,MAAMK,EAAS,EAAI,EACjC,MAAM,QAAQ,IAAIa,EAAc,IAAI,MAAOH,GAAS,IAAI,QAAQ,CAAC5B,EAASC,IAAW,CACjF,MAAMH,EAAUe,EAAM,OAAOe,EAAK,EAAE,EACpC9B,EAAQ,iBAAiB,UAAW,IAAME,EAAA,CAAS,EACnDF,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,qBAAqB,CAAC,CAAC,CAC9G,CAAC,CAAC,CAAC,CACP,EACA,UAAW,SAAY,CACnB,MAAMe,EAAQ,MAAMK,EAAS,EAAI,EACjC,OAAO,IAAI,QAAQ,CAAClB,EAASC,IAAW,CACpC,MAAMH,EAAUe,EAAM,MAAA,EACtBf,EAAQ,iBAAiB,UAAW,IAAME,EAAA,CAAS,EACnDF,EAAQ,iBAAiB,QAAS,IAAMG,EAAO,IAAI,MAAMH,EAAQ,OAAO,SAAW,sBAAsB,CAAC,CAAC,CAC/G,CAAC,CACL,CAAA,CACH,CACL"}
1
+ {"version":3,"file":"index.umd.js","sources":["../src/index.ts"],"sourcesContent":["import { createStorageAdapter } from '@signaldb/core';\n/**\n * Opens the IndexedDB database and creates the object store if it doesn't exist.\n * @param databaseName - The name of the database.\n * @param version - The version of the database.\n * @param onUpgrade - Optional callback for handling database upgrades.\n * @returns A promise that resolves with the opened database.\n */\nasync function openDatabase(databaseName, version, onUpgrade) {\n const request = indexedDB.open(databaseName, version);\n const upgradePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n request.addEventListener('upgradeneeded', (event) => {\n const database = request.result;\n const tx = request.transaction;\n if (onUpgrade) {\n onUpgrade(database, tx, event.oldVersion, event.newVersion ?? null)\n .then(() => resolve())\n .catch(\n /* istanbul ignore next -- @preserve */\n (error) => {\n reject(error);\n });\n return;\n }\n // No custom upgrade logic provided, resolve immediately\n /* istanbul ignore next -- @preserve */\n resolve();\n });\n });\n const databasePromise = new Promise((resolve, reject) => {\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Database error')));\n });\n await Promise.all([\n databasePromise,\n upgradePromise,\n ]);\n return databasePromise;\n}\n/**\n * Prepares an IndexedDB storage adapter for SignalDB with the specified options.\n * @param options - Configuration options for the IndexedDB adapter.\n * @param options.databaseName - The name of the IndexedDB database. Defaults to 'signaldb'.\n * @param options.version - The version of the database schema.\n * @param options.schema - An object defining the schema of the database, where keys are store names and values are arrays of index names.\n * @param options.onUpgrade - Optional callback for handling database upgrades.\n * @returns A function that takes a store name and returns a SignalDB storage adapter for that store.\n */\nexport default function prepareIndexedDB(options) {\n const databaseName = options.databaseName || 'signaldb';\n const databasePromise = openDatabase(databaseName, options.version, async (database, tx) => {\n if (options.onUpgrade) {\n await options.onUpgrade(database, tx, database.version, options.version);\n }\n const storesToDelete = new Set();\n for (let i = 0; i < database.objectStoreNames.length; i += 1) {\n const storeName = database.objectStoreNames.item(i);\n if (!storeName || storeName in options.schema)\n continue;\n storesToDelete.add(storeName);\n }\n // Delete stores that are not in the new schema\n storesToDelete.forEach((storeName) => {\n if (!database.objectStoreNames.contains(storeName))\n return;\n database.deleteObjectStore(storeName);\n });\n // Create or update stores as per the new schema\n for (const [storeName, indexes] of Object.entries(options.schema)) {\n const store = database.objectStoreNames.contains(storeName)\n ? tx.objectStore(storeName)\n : database.createObjectStore(storeName, {\n keyPath: 'id',\n });\n const indexesToDrop = new Set();\n for (let i = 0; i < store.indexNames.length; i += 1) {\n const indexName = store.indexNames.item(i);\n if (!indexName || indexes.includes(indexName))\n continue;\n indexesToDrop.add(indexName);\n }\n // Drop indexes that are not in the new schema\n indexesToDrop.forEach((indexName) => {\n if (!store.indexNames.contains(indexName))\n return;\n store.deleteIndex(indexName);\n });\n // Create indexes as per the new schema\n indexes.forEach((index) => {\n if (index === 'id')\n return;\n if (store.indexNames.contains(index))\n return;\n store.createIndex(index, index, { unique: false });\n });\n }\n });\n return function indexedDBAdapter(storeName) {\n return createIndexedDBAdapter(storeName, databasePromise);\n };\n}\n/**\n * Creates a storage adapter for managing a SignalDB collection using IndexedDB.\n * This adapter reads and writes data to an IndexedDB object store, with customizable serialization 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 storeName - A unique name for the collection, used as the database name.\n * @param databasePromise - A promise that resolves to an opened IndexedDB database.\n * @returns A SignalDB storage adapter for managing data in IndexedDB.\n */\nfunction createIndexedDBAdapter(storeName, databasePromise) {\n const getStore = async (writeAccess = false) => {\n const database = await databasePromise;\n if (!database)\n throw new Error('Database not initialized');\n const transaction = database.transaction(storeName, writeAccess ? 'readwrite' : 'readonly');\n const store = transaction.objectStore(storeName);\n return store;\n };\n const readIndex = async (field) => {\n const store = await getStore();\n if (!store.indexNames.contains(field)) {\n throw new Error(`Index on field \"${field}\" does not exist`);\n }\n return new Promise((resolve, reject) => {\n const index = store.index(field);\n const result = new Map();\n const request = index.openCursor();\n request.addEventListener('success', () => {\n const cursor = request.result;\n if (cursor) {\n const key = cursor.key;\n const id = cursor.value.id;\n if (!result.has(key)) {\n result.set(key, new Set());\n }\n result.get(key)?.add(id);\n cursor.continue();\n }\n else {\n resolve(result);\n }\n });\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error reading index')));\n });\n };\n const getById = async (id) => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.get(id);\n request.addEventListener('success', () => resolve(request.result || null));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching item')));\n });\n };\n const insertOrReplace = async (items) => {\n const store = await getStore(true);\n await Promise.all(items.map(item => new Promise((resolve, reject) => {\n const request = store.put(item);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error inserting or replacing item')));\n })));\n };\n return createStorageAdapter({\n // lifecycle methods\n setup: async () => {\n const database = await databasePromise;\n if (database.objectStoreNames.contains(storeName))\n return;\n throw new Error(`Object store \"${storeName}\" does not exist in database. Make sure to define it in the schema when initializing the adapter.`);\n },\n teardown: async () => {\n const database = await databasePromise;\n database.close();\n },\n // data retrieval methods\n readAll: async () => {\n const store = await getStore();\n return new Promise((resolve, reject) => {\n const request = store.getAll();\n request.addEventListener('success', () => resolve(request.result));\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error fetching items')));\n });\n },\n readIds: async (ids) => {\n const results = await Promise.all(ids.map(id => getById(id)));\n return results.filter(item => item !== null);\n },\n // index methods\n createIndex: async () => {\n /* noop */\n },\n dropIndex: async () => {\n /* noop */\n },\n readIndex,\n // data manipulation methods\n insert: items => insertOrReplace(items),\n replace: items => insertOrReplace(items),\n remove: async (itemsToRemove) => {\n const store = await getStore(true);\n await Promise.all(itemsToRemove.map(async (item) => new Promise((resolve, reject) => {\n const request = store.delete(item.id);\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error removing item')));\n })));\n },\n removeAll: async () => {\n const store = await getStore(true);\n return new Promise((resolve, reject) => {\n const request = store.clear();\n request.addEventListener('success', () => resolve());\n request.addEventListener('error', () => reject(new Error(request.error?.message || 'Error clearing items')));\n });\n },\n });\n}\n"],"names":["openDatabase","databaseName","version","onUpgrade","request","upgradePromise","resolve","reject","event","database","tx","error","databasePromise","prepareIndexedDB","options","storesToDelete","i","storeName","indexes","store","indexesToDrop","indexName","index","createIndexedDBAdapter","getStore","writeAccess","readIndex","field","result","cursor","key","id","getById","insertOrReplace","items","item","createStorageAdapter","ids","itemsToRemove"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signaldb/indexeddb",
3
- "version": "2.0.0-beta.4",
3
+ "version": "2.0.0-beta.5",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "build": "rimraf dist && vite build",
@@ -56,6 +56,6 @@
56
56
  "fake-indexeddb": "6.2.5"
57
57
  },
58
58
  "peerDependencies": {
59
- "@signaldb/core": "2.0.0-beta.4"
59
+ "@signaldb/core": "2.0.0-beta.5"
60
60
  }
61
61
  }