offdex 1.0.4 → 1.0.6
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 +12 -5
- package/package.json +1 -1
- package/src/ObjectStore/index.js +221 -0
- package/src/ObservableObject/index.js +12 -0
- package/src/ObservableValue/index.js +58 -0
- package/src/StorageQuery/index.js +12 -0
- package/src/index.d.ts +45 -12
- package/src/index.js +7 -83
package/README.md
CHANGED
|
@@ -33,18 +33,25 @@ await storage.delete(profile.id);
|
|
|
33
33
|
|
|
34
34
|
## API
|
|
35
35
|
### `storage`
|
|
36
|
-
- Ready-to-use singleton instance shared across every import in the same origin.
|
|
37
|
-
- Uses the `offline` database and `objects` store under the hood.
|
|
36
|
+
- Ready-to-use singleton instance shared across every import in the same origin. Uses the `offdex` database and `objects` store under the hood.
|
|
38
37
|
|
|
39
|
-
### `class
|
|
40
|
-
- `constructor()` — opens (or creates) the `
|
|
38
|
+
### `class ObjectStore`
|
|
39
|
+
- `constructor()` — opens (or creates) the `offdex` database with the `objects` store. Use this only if you need a separate instance.
|
|
41
40
|
- `put(object: { id: UUIDv4 } & Record<string, unknown>): Promise<void>` — upserts an object keyed by `id`.
|
|
42
|
-
- `get(id: UUIDv4): Promise<{ id: UUIDv4 } & Record<string, unknown> | undefined>` — fetches by `id`, returning `undefined` when missing.
|
|
41
|
+
- `get(id: UUIDv4, onSet?, onDelete?): Promise<{ id: UUIDv4 } & Record<string, unknown> | undefined>` — fetches by `id`, returning `undefined` when missing. Optional callbacks run before a property change/delete; return `false` to block the change.
|
|
43
42
|
- `delete(id: UUIDv4): Promise<void>` — removes an object by `id`.
|
|
43
|
+
- `getAllMatches(queryOrFilter: StorageQuery | (object) => boolean, onSet?, onDelete?): Promise<object[]>` — returns objects that pass a query or predicate (with the same optional callbacks as `get`).
|
|
44
|
+
- `deleteAllMatches(queryOrFilter: StorageQuery | (object) => boolean): Promise<void>` — deletes objects that pass a query or predicate.
|
|
45
|
+
|
|
46
|
+
### Other exports
|
|
47
|
+
- `StorageQuery` — helper for simple equality-based queries.
|
|
48
|
+
- `ObservableValue` — observable wrapper around a single value.
|
|
49
|
+
- `ObservableObject` — wraps an object in observable values keyed by its properties.
|
|
44
50
|
|
|
45
51
|
### Types
|
|
46
52
|
- `UUIDv4` — template literal type for UUID strings.
|
|
47
53
|
- `StoredObject` — `{ id: UUIDv4 } & Record<string, unknown>`.
|
|
54
|
+
- `OnSetHandler`, `OnDeleteHandler` — callback shapes used by `get`/`getAllMatches`.
|
|
48
55
|
|
|
49
56
|
## Notes
|
|
50
57
|
- Runs in any environment that exposes `indexedDB` (secure contexts in modern browsers).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "offdex",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
4
|
"description": "ID-driven object storage wrapper for IndexedDB with zero schema/versioning overhead. Shared across all browser threads, offline-persistent, large capacity, simple API.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"indexeddb",
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
export class ObjectStore {
|
|
2
|
+
static #idb = "offdex";
|
|
3
|
+
static #store = "objects";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @returns {Promise<IDBDatabase>}
|
|
7
|
+
*/
|
|
8
|
+
static #open() {
|
|
9
|
+
return new Promise((resolve, reject) => {
|
|
10
|
+
const request = indexedDB.open(ObjectStore.#idb);
|
|
11
|
+
|
|
12
|
+
request.addEventListener("upgradeneeded", () => {
|
|
13
|
+
const db = request.result;
|
|
14
|
+
if (!db.objectStoreNames.contains(ObjectStore.#store)) {
|
|
15
|
+
db.createObjectStore(ObjectStore.#store, { keyPath: "id" });
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
request.addEventListener("success", () => {
|
|
20
|
+
resolve(request.result);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
request.addEventListener("error", () => {
|
|
24
|
+
reject(request.error);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
this.instance = ObjectStore.#open();
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* @param {import("../types").StoredObject} object
|
|
35
|
+
* @returns {Promise<void>}
|
|
36
|
+
*/
|
|
37
|
+
async put(object) {
|
|
38
|
+
const db = await this.instance;
|
|
39
|
+
return new Promise((resolve, reject) => {
|
|
40
|
+
const transaction = db.transaction(ObjectStore.#store, "readwrite");
|
|
41
|
+
const store = transaction.objectStore(ObjectStore.#store);
|
|
42
|
+
store.put(object);
|
|
43
|
+
|
|
44
|
+
transaction.oncomplete = () => resolve();
|
|
45
|
+
transaction.onerror = () =>
|
|
46
|
+
reject(new Error(`{offdex} ObjectStore: ${transaction.error}`));
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* @param {import("../types").UUIDv4} id
|
|
52
|
+
* @param {(propertyName: string, oldValue: any, newValue: any) => void | boolean} [onSetEvent]
|
|
53
|
+
* @param {(propertyName: string, deletedValue: any) => void | boolean} [onDeleteEvent]
|
|
54
|
+
* @returns {Promise<import("../types").StoredObject | undefined>}
|
|
55
|
+
*/
|
|
56
|
+
async get(id, onSetEvent, onDeleteEvent) {
|
|
57
|
+
const db = await this.instance;
|
|
58
|
+
const objectStoreInstance = this;
|
|
59
|
+
|
|
60
|
+
return new Promise((resolve, reject) => {
|
|
61
|
+
const transaction = db.transaction(ObjectStore.#store, "readonly");
|
|
62
|
+
const store = transaction.objectStore(ObjectStore.#store);
|
|
63
|
+
const request = store.get(id);
|
|
64
|
+
|
|
65
|
+
transaction.oncomplete = () => {
|
|
66
|
+
if (!request.result) {
|
|
67
|
+
resolve(undefined);
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const target = request.result;
|
|
72
|
+
|
|
73
|
+
const handler = {
|
|
74
|
+
set(targetObject, propertyName, newValue) {
|
|
75
|
+
const oldValue = targetObject[propertyName];
|
|
76
|
+
if (onSetEvent) {
|
|
77
|
+
const shouldUpdate = onSetEvent(propertyName, oldValue, newValue);
|
|
78
|
+
if (shouldUpdate === false) return true;
|
|
79
|
+
}
|
|
80
|
+
targetObject[propertyName] = newValue;
|
|
81
|
+
void objectStoreInstance.put(targetObject);
|
|
82
|
+
return true;
|
|
83
|
+
},
|
|
84
|
+
deleteProperty(targetObject, propertyName) {
|
|
85
|
+
const deletedValue = targetObject[propertyName];
|
|
86
|
+
if (onDeleteEvent) {
|
|
87
|
+
const shouldDelete = onDeleteEvent(propertyName, deletedValue);
|
|
88
|
+
if (shouldDelete === false) return true;
|
|
89
|
+
}
|
|
90
|
+
delete targetObject[propertyName];
|
|
91
|
+
void objectStoreInstance.put(targetObject);
|
|
92
|
+
return true;
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
resolve(new Proxy(target, handler));
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
transaction.onerror = () =>
|
|
100
|
+
reject(new Error(`{offdex} ObjectStore: ${transaction.error}`));
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @param {import("../types").UUIDv4} id
|
|
106
|
+
* @returns {Promise<void>}
|
|
107
|
+
*/
|
|
108
|
+
async delete(id) {
|
|
109
|
+
const db = await this.instance;
|
|
110
|
+
return new Promise((resolve, reject) => {
|
|
111
|
+
const transaction = db.transaction(ObjectStore.#store, "readwrite");
|
|
112
|
+
const store = transaction.objectStore(ObjectStore.#store);
|
|
113
|
+
store.delete(id);
|
|
114
|
+
transaction.oncomplete = () => resolve();
|
|
115
|
+
transaction.onerror = () =>
|
|
116
|
+
reject(new Error(`{offdex} ObjectStore: ${transaction.error}`));
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* @param {import("../StorageQuery/index.js").StorageQuery | ((object: import("../types").StoredObject) => boolean)} queryOrPredicate
|
|
122
|
+
* @param {(propertyName: string, oldValue: any, newValue: any) => void | boolean} [onSetEvent]
|
|
123
|
+
* @param {(propertyName: string, deletedValue: any) => void | boolean} [onDeleteEvent]
|
|
124
|
+
* @returns {Promise<import("../types").StoredObject[]>}
|
|
125
|
+
*/
|
|
126
|
+
async getAllMatches(queryOrPredicate, onSetEvent, onDeleteEvent) {
|
|
127
|
+
const db = await this.instance;
|
|
128
|
+
const objectStoreInstance = this;
|
|
129
|
+
|
|
130
|
+
const predicate =
|
|
131
|
+
typeof queryOrPredicate === "function"
|
|
132
|
+
? queryOrPredicate
|
|
133
|
+
: (object) => queryOrPredicate.matches(object);
|
|
134
|
+
|
|
135
|
+
return new Promise((resolve, reject) => {
|
|
136
|
+
const transaction = db.transaction(ObjectStore.#store, "readonly");
|
|
137
|
+
const store = transaction.objectStore(ObjectStore.#store);
|
|
138
|
+
const request = store.openCursor();
|
|
139
|
+
|
|
140
|
+
const results = [];
|
|
141
|
+
|
|
142
|
+
request.onsuccess = () => {
|
|
143
|
+
const cursor = request.result;
|
|
144
|
+
if (!cursor) return;
|
|
145
|
+
|
|
146
|
+
const value = cursor.value;
|
|
147
|
+
|
|
148
|
+
if (predicate(value)) {
|
|
149
|
+
const handler = {
|
|
150
|
+
set(targetObject, propertyName, newValue) {
|
|
151
|
+
const oldValue = targetObject[propertyName];
|
|
152
|
+
if (onSetEvent) {
|
|
153
|
+
const shouldUpdate = onSetEvent(
|
|
154
|
+
propertyName,
|
|
155
|
+
oldValue,
|
|
156
|
+
newValue
|
|
157
|
+
);
|
|
158
|
+
if (shouldUpdate === false) return true;
|
|
159
|
+
}
|
|
160
|
+
targetObject[propertyName] = newValue;
|
|
161
|
+
void objectStoreInstance.put(targetObject);
|
|
162
|
+
return true;
|
|
163
|
+
},
|
|
164
|
+
deleteProperty(targetObject, propertyName) {
|
|
165
|
+
const deletedValue = targetObject[propertyName];
|
|
166
|
+
if (onDeleteEvent) {
|
|
167
|
+
const shouldDelete = onDeleteEvent(propertyName, deletedValue);
|
|
168
|
+
if (shouldDelete === false) return true;
|
|
169
|
+
}
|
|
170
|
+
delete targetObject[propertyName];
|
|
171
|
+
void objectStoreInstance.put(targetObject);
|
|
172
|
+
return true;
|
|
173
|
+
},
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
results.push(new Proxy(value, handler));
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
cursor.continue();
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
transaction.oncomplete = () => resolve(results);
|
|
183
|
+
transaction.onerror = () =>
|
|
184
|
+
reject(new Error(`{offdex} ObjectStore: ${transaction.error}`));
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* @param {import("../StorageQuery/index.js").StorageQuery | ((object: import("../types").StoredObject) => boolean)} queryOrPredicate
|
|
190
|
+
* @returns {Promise<void>}
|
|
191
|
+
*/
|
|
192
|
+
async deleteAllMatches(queryOrPredicate) {
|
|
193
|
+
const db = await this.instance;
|
|
194
|
+
|
|
195
|
+
const predicate =
|
|
196
|
+
typeof queryOrPredicate === "function"
|
|
197
|
+
? queryOrPredicate
|
|
198
|
+
: (object) => queryOrPredicate.matches(object);
|
|
199
|
+
|
|
200
|
+
return new Promise((resolve, reject) => {
|
|
201
|
+
const transaction = db.transaction(ObjectStore.#store, "readwrite");
|
|
202
|
+
const store = transaction.objectStore(ObjectStore.#store);
|
|
203
|
+
const request = store.openCursor();
|
|
204
|
+
|
|
205
|
+
request.onsuccess = () => {
|
|
206
|
+
const cursor = request.result;
|
|
207
|
+
if (!cursor) return;
|
|
208
|
+
|
|
209
|
+
if (predicate(cursor.value)) {
|
|
210
|
+
cursor.delete();
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
cursor.continue();
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
transaction.oncomplete = () => resolve();
|
|
217
|
+
transaction.onerror = () =>
|
|
218
|
+
reject(new Error(`{offdex} ObjectStore: ${transaction.error}`));
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ObservableValue } from "../ObservableValue/index.js";
|
|
2
|
+
|
|
3
|
+
export class ObservableObject {
|
|
4
|
+
/**
|
|
5
|
+
* @param {import("../types").StoredObject} object
|
|
6
|
+
*/
|
|
7
|
+
constructor(object) {
|
|
8
|
+
for (const key in object) {
|
|
9
|
+
this[key] = new ObservableValue(object[key]);
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export class ObservableValue {
|
|
2
|
+
/**
|
|
3
|
+
* @param {any} value
|
|
4
|
+
* @param {any} [fallback]
|
|
5
|
+
*/
|
|
6
|
+
constructor(value, fallback = null) {
|
|
7
|
+
this.value = value;
|
|
8
|
+
this.fallback = fallback;
|
|
9
|
+
/** @type {Set<{ event: "set" | "reset"; callback: (value: any) => void }>} */
|
|
10
|
+
this.observers = new Set();
|
|
11
|
+
}
|
|
12
|
+
get() {
|
|
13
|
+
return this.value;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* @param {any} newValue
|
|
17
|
+
* @returns {void}
|
|
18
|
+
*/
|
|
19
|
+
set(newValue) {
|
|
20
|
+
if (newValue === this.value) return;
|
|
21
|
+
this.value = newValue;
|
|
22
|
+
const changeObservers = [...this.observers].filter(
|
|
23
|
+
(observer) => observer.event === "set"
|
|
24
|
+
);
|
|
25
|
+
for (const observer of changeObservers) {
|
|
26
|
+
observer.callback(newValue);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
reset() {
|
|
30
|
+
this.value = this.fallback;
|
|
31
|
+
const resetObservers = [...this.observers].filter(
|
|
32
|
+
(observer) => observer.event === "reset"
|
|
33
|
+
);
|
|
34
|
+
for (const observer of resetObservers) {
|
|
35
|
+
observer.callback(this.fallback);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* @param {"set" | "reset"} event
|
|
40
|
+
* @param {Function} callback
|
|
41
|
+
* @returns {() => void}
|
|
42
|
+
*/
|
|
43
|
+
observe(event, callback) {
|
|
44
|
+
if (event !== "set" && event !== "reset")
|
|
45
|
+
throw new Error(
|
|
46
|
+
"{offdex} ObservableValue: Supported `event` parameters are [set, reset]"
|
|
47
|
+
);
|
|
48
|
+
if (typeof callback !== "function")
|
|
49
|
+
throw new Error(
|
|
50
|
+
"{offdex} ObservableValue: Paramater `callback` must be of type function"
|
|
51
|
+
);
|
|
52
|
+
const observer = { event, callback };
|
|
53
|
+
this.observers.add(observer);
|
|
54
|
+
return () => {
|
|
55
|
+
this.observers.delete(observer);
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.d.ts
CHANGED
|
@@ -2,20 +2,53 @@ export type UUIDv4 = `${string}-${string}-${string}-${string}-${string}`;
|
|
|
2
2
|
|
|
3
3
|
export type StoredObject = { id: UUIDv4 } & Record<string, unknown>;
|
|
4
4
|
|
|
5
|
-
export
|
|
5
|
+
export type OnSetHandler = (
|
|
6
|
+
propertyName: string,
|
|
7
|
+
oldValue: unknown,
|
|
8
|
+
newValue: unknown
|
|
9
|
+
) => void | boolean;
|
|
10
|
+
|
|
11
|
+
export type OnDeleteHandler = (
|
|
12
|
+
propertyName: string,
|
|
13
|
+
deletedValue: unknown
|
|
14
|
+
) => void | boolean;
|
|
15
|
+
|
|
16
|
+
export class StorageQuery {
|
|
17
|
+
constructor(args?: Record<string, unknown>);
|
|
18
|
+
args: Record<string, unknown>;
|
|
19
|
+
matches(object: StoredObject): boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export class ObservableValue<T = unknown> {
|
|
23
|
+
constructor(value: T, fallback?: T);
|
|
24
|
+
get(): T;
|
|
25
|
+
set(newValue: T): void;
|
|
26
|
+
reset(): void;
|
|
27
|
+
observe(event: "set" | "reset", callback: (value: T) => void): () => void;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export class ObservableObject<T extends StoredObject = StoredObject> {
|
|
31
|
+
constructor(object: T);
|
|
32
|
+
[key: string]: ObservableValue<unknown>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export class ObjectStore {
|
|
6
36
|
constructor();
|
|
7
|
-
/**
|
|
8
|
-
* Persist or overwrite an object by id.
|
|
9
|
-
*/
|
|
10
37
|
put(object: StoredObject): Promise<void>;
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
* Remove an object by id.
|
|
17
|
-
*/
|
|
38
|
+
get(
|
|
39
|
+
id: UUIDv4,
|
|
40
|
+
onSetEvent?: OnSetHandler,
|
|
41
|
+
onDeleteEvent?: OnDeleteHandler
|
|
42
|
+
): Promise<StoredObject | undefined>;
|
|
18
43
|
delete(id: UUIDv4): Promise<void>;
|
|
44
|
+
getAllMatches(
|
|
45
|
+
queryOrFilter: StorageQuery | ((object: StoredObject) => boolean),
|
|
46
|
+
onSetEvent?: OnSetHandler,
|
|
47
|
+
onDeleteEvent?: OnDeleteHandler
|
|
48
|
+
): Promise<StoredObject[]>;
|
|
49
|
+
deleteAllMatches(
|
|
50
|
+
queryOrFilter: StorageQuery | ((object: StoredObject) => boolean)
|
|
51
|
+
): Promise<void>;
|
|
19
52
|
}
|
|
20
53
|
|
|
21
|
-
export const storage:
|
|
54
|
+
export const storage: ObjectStore;
|
package/src/index.js
CHANGED
|
@@ -1,83 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
static #open() {
|
|
9
|
-
return new Promise((resolve, reject) => {
|
|
10
|
-
const request = indexedDB.open(OfflineStorage.#idb);
|
|
11
|
-
|
|
12
|
-
request.addEventListener("upgradeneeded", () => {
|
|
13
|
-
const db = request.result;
|
|
14
|
-
if (!db.objectStoreNames.contains(OfflineStorage.#store)) {
|
|
15
|
-
db.createObjectStore(OfflineStorage.#store, { keyPath: "id" });
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
request.addEventListener("success", () => {
|
|
20
|
-
resolve(request.result);
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
request.addEventListener("error", () => {
|
|
24
|
-
reject(request.error);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
constructor() {
|
|
30
|
-
this.storage = OfflineStorage.#open();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* @param {import("./types").StoredObject} object
|
|
35
|
-
* @returns {Promise<void>}
|
|
36
|
-
*/
|
|
37
|
-
async put(object) {
|
|
38
|
-
const db = await this.storage;
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
const tx = db.transaction(OfflineStorage.#store, "readwrite");
|
|
41
|
-
const store = tx.objectStore(OfflineStorage.#store);
|
|
42
|
-
store.put(object);
|
|
43
|
-
|
|
44
|
-
tx.oncomplete = () => resolve();
|
|
45
|
-
tx.onerror = () => reject(new Error(`[OfflineStorage] ${tx.error}`));
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* @param {import("./types").UUIDv4} id
|
|
51
|
-
* @returns {Promise<import("./types").StoredObject | undefined>}
|
|
52
|
-
*/
|
|
53
|
-
async get(id) {
|
|
54
|
-
const db = await this.storage;
|
|
55
|
-
return new Promise((resolve, reject) => {
|
|
56
|
-
const tx = db.transaction(OfflineStorage.#store, "readonly");
|
|
57
|
-
const store = tx.objectStore(OfflineStorage.#store);
|
|
58
|
-
const request = store.get(id);
|
|
59
|
-
|
|
60
|
-
tx.oncomplete = () => {
|
|
61
|
-
resolve(request.result ? request.result : undefined);
|
|
62
|
-
};
|
|
63
|
-
tx.onerror = () => reject(new Error(`[OfflineStorage] ${tx.error}`));
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
*
|
|
68
|
-
* @param {import("./types").UUIDv4} id
|
|
69
|
-
* @returns {Promise<void>}
|
|
70
|
-
*/
|
|
71
|
-
async delete(id) {
|
|
72
|
-
const db = await this.storage;
|
|
73
|
-
return new Promise((resolve, reject) => {
|
|
74
|
-
const tx = db.transaction(OfflineStorage.#store, "readwrite");
|
|
75
|
-
const store = tx.objectStore(OfflineStorage.#store);
|
|
76
|
-
store.delete(id);
|
|
77
|
-
tx.oncomplete = () => resolve();
|
|
78
|
-
tx.onerror = () => reject(new Error(`[OfflineStorage] ${tx.error}`));
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export const storage = new OfflineStorage();
|
|
1
|
+
import { ObjectStore } from "./ObjectStore/index.js";
|
|
2
|
+
import { StorageQuery } from "./StorageQuery/index.js";
|
|
3
|
+
import { ObservableValue } from "./ObservableValue/index.js";
|
|
4
|
+
import { ObservableObject } from "./ObservableObject/index.js";
|
|
5
|
+
|
|
6
|
+
export { ObjectStore, StorageQuery, ObservableValue, ObservableObject };
|
|
7
|
+
export const storage = new ObjectStore();
|