mvc-kit 2.12.4 → 2.13.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/agent-config/bin/postinstall.mjs +4 -3
- package/agent-config/bin/setup.mjs +5 -1
- package/agent-config/claude-code/agents/mvc-kit-architect.md +11 -8
- package/agent-config/claude-code/skills/guide/SKILL.md +20 -7
- package/agent-config/claude-code/skills/guide/patterns.md +12 -0
- package/agent-config/claude-code/skills/guide/recipes.md +510 -0
- package/agent-config/claude-code/skills/guide/testing.md +297 -0
- package/agent-config/claude-code/skills/review/SKILL.md +3 -13
- package/agent-config/claude-code/skills/review/checklist.md +30 -5
- package/agent-config/claude-code/skills/scaffold/SKILL.md +4 -13
- package/agent-config/lib/install-claude.mjs +84 -25
- package/dist/Channel.cjs +276 -300
- package/dist/Channel.cjs.map +1 -1
- package/dist/Channel.js +275 -299
- package/dist/Channel.js.map +1 -1
- package/dist/Collection.cjs +424 -504
- package/dist/Collection.cjs.map +1 -1
- package/dist/Collection.js +423 -503
- package/dist/Collection.js.map +1 -1
- package/dist/Controller.cjs +70 -67
- package/dist/Controller.cjs.map +1 -1
- package/dist/Controller.js +69 -66
- package/dist/Controller.js.map +1 -1
- package/dist/EventBus.cjs +77 -88
- package/dist/EventBus.cjs.map +1 -1
- package/dist/EventBus.js +76 -87
- package/dist/EventBus.js.map +1 -1
- package/dist/Feed.cjs +81 -77
- package/dist/Feed.cjs.map +1 -1
- package/dist/Feed.js +80 -76
- package/dist/Feed.js.map +1 -1
- package/dist/Model.cjs +181 -207
- package/dist/Model.cjs.map +1 -1
- package/dist/Model.js +179 -205
- package/dist/Model.js.map +1 -1
- package/dist/Pagination.cjs +75 -73
- package/dist/Pagination.cjs.map +1 -1
- package/dist/Pagination.js +74 -72
- package/dist/Pagination.js.map +1 -1
- package/dist/Pending.cjs +255 -287
- package/dist/Pending.cjs.map +1 -1
- package/dist/Pending.js +253 -285
- package/dist/Pending.js.map +1 -1
- package/dist/PersistentCollection.cjs +242 -285
- package/dist/PersistentCollection.cjs.map +1 -1
- package/dist/PersistentCollection.js +241 -284
- package/dist/PersistentCollection.js.map +1 -1
- package/dist/Resource.cjs +166 -174
- package/dist/Resource.cjs.map +1 -1
- package/dist/Resource.js +164 -172
- package/dist/Resource.js.map +1 -1
- package/dist/Selection.cjs +84 -94
- package/dist/Selection.cjs.map +1 -1
- package/dist/Selection.js +83 -93
- package/dist/Selection.js.map +1 -1
- package/dist/Service.cjs +54 -55
- package/dist/Service.cjs.map +1 -1
- package/dist/Service.js +53 -54
- package/dist/Service.js.map +1 -1
- package/dist/Sorting.cjs +102 -101
- package/dist/Sorting.cjs.map +1 -1
- package/dist/Sorting.js +102 -101
- package/dist/Sorting.js.map +1 -1
- package/dist/Trackable.cjs +112 -80
- package/dist/Trackable.cjs.map +1 -1
- package/dist/Trackable.js +111 -79
- package/dist/Trackable.js.map +1 -1
- package/dist/ViewModel.cjs +528 -576
- package/dist/ViewModel.cjs.map +1 -1
- package/dist/ViewModel.js +525 -573
- package/dist/ViewModel.js.map +1 -1
- package/dist/bindPublicMethods.cjs +43 -24
- package/dist/bindPublicMethods.cjs.map +1 -1
- package/dist/bindPublicMethods.js +43 -24
- package/dist/bindPublicMethods.js.map +1 -1
- package/dist/errors.cjs +67 -68
- package/dist/errors.cjs.map +1 -1
- package/dist/errors.js +68 -71
- package/dist/errors.js.map +1 -1
- package/dist/mvc-kit.cjs +44 -46
- package/dist/mvc-kit.js +5 -32
- package/dist/produceDraft.cjs +105 -95
- package/dist/produceDraft.cjs.map +1 -1
- package/dist/produceDraft.js +106 -97
- package/dist/produceDraft.js.map +1 -1
- package/dist/react/components/CardList.cjs +30 -40
- package/dist/react/components/CardList.cjs.map +1 -1
- package/dist/react/components/CardList.js +31 -41
- package/dist/react/components/CardList.js.map +1 -1
- package/dist/react/components/DataTable.cjs +146 -169
- package/dist/react/components/DataTable.cjs.map +1 -1
- package/dist/react/components/DataTable.js +147 -170
- package/dist/react/components/DataTable.js.map +1 -1
- package/dist/react/components/InfiniteScroll.cjs +51 -42
- package/dist/react/components/InfiniteScroll.cjs.map +1 -1
- package/dist/react/components/InfiniteScroll.js +52 -43
- package/dist/react/components/InfiniteScroll.js.map +1 -1
- package/dist/react/components/types.cjs +10 -6
- package/dist/react/components/types.cjs.map +1 -1
- package/dist/react/components/types.js +11 -9
- package/dist/react/components/types.js.map +1 -1
- package/dist/react/guards.cjs +10 -6
- package/dist/react/guards.cjs.map +1 -1
- package/dist/react/guards.js +11 -9
- package/dist/react/guards.js.map +1 -1
- package/dist/react/provider.cjs +23 -20
- package/dist/react/provider.cjs.map +1 -1
- package/dist/react/provider.js +23 -21
- package/dist/react/provider.js.map +1 -1
- package/dist/react/use-event-bus.cjs +24 -20
- package/dist/react/use-event-bus.cjs.map +1 -1
- package/dist/react/use-event-bus.js +24 -21
- package/dist/react/use-event-bus.js.map +1 -1
- package/dist/react/use-instance.cjs +43 -36
- package/dist/react/use-instance.cjs.map +1 -1
- package/dist/react/use-instance.js +43 -36
- package/dist/react/use-instance.js.map +1 -1
- package/dist/react/use-local.cjs +48 -64
- package/dist/react/use-local.cjs.map +1 -1
- package/dist/react/use-local.js +47 -63
- package/dist/react/use-local.js.map +1 -1
- package/dist/react/use-model.cjs +84 -98
- package/dist/react/use-model.cjs.map +1 -1
- package/dist/react/use-model.js +84 -100
- package/dist/react/use-model.js.map +1 -1
- package/dist/react/use-singleton.cjs +19 -23
- package/dist/react/use-singleton.cjs.map +1 -1
- package/dist/react/use-singleton.js +16 -20
- package/dist/react/use-singleton.js.map +1 -1
- package/dist/react/use-subscribe-only.cjs +28 -22
- package/dist/react/use-subscribe-only.cjs.map +1 -1
- package/dist/react/use-subscribe-only.js +28 -22
- package/dist/react/use-subscribe-only.js.map +1 -1
- package/dist/react/use-teardown.cjs +20 -19
- package/dist/react/use-teardown.cjs.map +1 -1
- package/dist/react/use-teardown.js +20 -19
- package/dist/react/use-teardown.js.map +1 -1
- package/dist/react-native/NativeCollection.cjs +98 -78
- package/dist/react-native/NativeCollection.cjs.map +1 -1
- package/dist/react-native/NativeCollection.js +97 -77
- package/dist/react-native/NativeCollection.js.map +1 -1
- package/dist/react-native.cjs +2 -4
- package/dist/react-native.js +1 -4
- package/dist/react.cjs +24 -26
- package/dist/react.js +1 -17
- package/dist/singleton.cjs +28 -22
- package/dist/singleton.cjs.map +1 -1
- package/dist/singleton.js +29 -26
- package/dist/singleton.js.map +1 -1
- package/dist/walkPrototypeChain.cjs +20 -12
- package/dist/walkPrototypeChain.cjs.map +1 -1
- package/dist/walkPrototypeChain.js +21 -13
- package/dist/walkPrototypeChain.js.map +1 -1
- package/dist/web/IndexedDBCollection.cjs +53 -36
- package/dist/web/IndexedDBCollection.cjs.map +1 -1
- package/dist/web/IndexedDBCollection.js +52 -35
- package/dist/web/IndexedDBCollection.js.map +1 -1
- package/dist/web/WebStorageCollection.cjs +82 -84
- package/dist/web/WebStorageCollection.cjs.map +1 -1
- package/dist/web/WebStorageCollection.js +81 -83
- package/dist/web/WebStorageCollection.js.map +1 -1
- package/dist/web/idb.cjs +107 -99
- package/dist/web/idb.cjs.map +1 -1
- package/dist/web/idb.js +108 -105
- package/dist/web/idb.js.map +1 -1
- package/dist/web.cjs +4 -6
- package/dist/web.js +1 -5
- package/dist/wrapAsyncMethods.cjs +141 -168
- package/dist/wrapAsyncMethods.cjs.map +1 -1
- package/dist/wrapAsyncMethods.js +141 -168
- package/dist/wrapAsyncMethods.js.map +1 -1
- package/package.json +8 -8
- package/src/Pending.test.ts +1 -2
- package/src/Sorting.test.ts +1 -1
- package/src/produceDraft.test.ts +3 -3
- package/src/react/components/CardList.test.tsx +1 -1
- package/src/react/components/DataTable.test.tsx +1 -1
- package/src/react/components/InfiniteScroll.test.tsx +5 -5
- package/dist/mvc-kit.cjs.map +0 -1
- package/dist/mvc-kit.js.map +0 -1
- package/dist/react-native.cjs.map +0 -1
- package/dist/react-native.js.map +0 -1
- package/dist/react.cjs.map +0 -1
- package/dist/react.js.map +0 -1
- package/dist/web.cjs.map +0 -1
- package/dist/web.js.map +0 -1
|
@@ -1,85 +1,83 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
this._storage.removeItem(this.storageKey);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
1
|
+
const require_PersistentCollection = require("../PersistentCollection.cjs");
|
|
2
|
+
//#region src/web/WebStorageCollection.ts
|
|
3
|
+
var __DEV__ = typeof __MVC_KIT_DEV__ !== "undefined" && __MVC_KIT_DEV__;
|
|
4
|
+
/**
|
|
5
|
+
* PersistentCollection backed by localStorage or sessionStorage.
|
|
6
|
+
* Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).
|
|
7
|
+
*
|
|
8
|
+
* Uses blob strategy: all items stored as a single JSON string under `storageKey`.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* class CartCollection extends WebStorageCollection<CartItem> {
|
|
12
|
+
* protected readonly storageKey = 'cart';
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
var WebStorageCollection = class extends require_PersistentCollection.PersistentCollection {
|
|
17
|
+
/** Which Web Storage backend to use. Override to 'session' for sessionStorage. */
|
|
18
|
+
static STORAGE = "local";
|
|
19
|
+
_autoHydrated = false;
|
|
20
|
+
get _storage() {
|
|
21
|
+
return this.constructor.STORAGE === "session" ? sessionStorage : localStorage;
|
|
22
|
+
}
|
|
23
|
+
_ensureHydrated() {
|
|
24
|
+
if (this._autoHydrated) return;
|
|
25
|
+
this._autoHydrated = true;
|
|
26
|
+
this._hydrateSync();
|
|
27
|
+
}
|
|
28
|
+
get items() {
|
|
29
|
+
this._ensureHydrated();
|
|
30
|
+
return super.items;
|
|
31
|
+
}
|
|
32
|
+
get state() {
|
|
33
|
+
return this.items;
|
|
34
|
+
}
|
|
35
|
+
get length() {
|
|
36
|
+
this._ensureHydrated();
|
|
37
|
+
return super.length;
|
|
38
|
+
}
|
|
39
|
+
get(id) {
|
|
40
|
+
this._ensureHydrated();
|
|
41
|
+
return super.get(id);
|
|
42
|
+
}
|
|
43
|
+
has(id) {
|
|
44
|
+
this._ensureHydrated();
|
|
45
|
+
return super.has(id);
|
|
46
|
+
}
|
|
47
|
+
persistGetAll() {
|
|
48
|
+
const raw = this._storage.getItem(this.storageKey);
|
|
49
|
+
if (!raw) return [];
|
|
50
|
+
try {
|
|
51
|
+
return this.deserialize(raw);
|
|
52
|
+
} catch {
|
|
53
|
+
if (__DEV__) console.warn(`[mvc-kit] Corrupted data in storage key "${this.storageKey}". Ignoring stored data.`);
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
persistGet(id) {
|
|
58
|
+
return this.persistGetAll().find((i) => i.id === id) ?? null;
|
|
59
|
+
}
|
|
60
|
+
persistSet(_items) {
|
|
61
|
+
try {
|
|
62
|
+
this._storage.setItem(this.storageKey, this.serialize([...this.items]));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (__DEV__ && err instanceof DOMException && err.name === "QuotaExceededError") console.warn(`[mvc-kit] QuotaExceededError writing to "${this.storageKey}". Consider using IndexedDBCollection for larger datasets.`);
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
persistRemove(_ids) {
|
|
69
|
+
try {
|
|
70
|
+
this._storage.setItem(this.storageKey, this.serialize([...this.items]));
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (__DEV__ && err instanceof DOMException && err.name === "QuotaExceededError") console.warn(`[mvc-kit] QuotaExceededError writing to "${this.storageKey}". Consider using IndexedDBCollection for larger datasets.`);
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
persistClear() {
|
|
77
|
+
this._storage.removeItem(this.storageKey);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
84
81
|
exports.WebStorageCollection = WebStorageCollection;
|
|
85
|
-
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=WebStorageCollection.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebStorageCollection.cjs","sources":["../../src/web/WebStorageCollection.ts"],"sourcesContent":["import { PersistentCollection } from '../PersistentCollection';\n\nconst __DEV__ = typeof __MVC_KIT_DEV__ !== 'undefined' && __MVC_KIT_DEV__;\n\n/**\n * PersistentCollection backed by localStorage or sessionStorage.\n * Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).\n *\n * Uses blob strategy: all items stored as a single JSON string under `storageKey`.\n *\n * ```ts\n * class CartCollection extends WebStorageCollection<CartItem> {\n * protected readonly storageKey = 'cart';\n * }\n * ```\n */\nexport abstract class WebStorageCollection<\n T extends { id: string | number },\n> extends PersistentCollection<T> {\n /** Which Web Storage backend to use. Override to 'session' for sessionStorage. */\n static STORAGE: 'local' | 'session' = 'local';\n\n private _autoHydrated = false;\n\n private get _storage(): Storage {\n return (this.constructor as typeof WebStorageCollection).STORAGE === 'session'\n ? sessionStorage\n : localStorage;\n }\n\n private _ensureHydrated(): void {\n if (this._autoHydrated) return;\n this._autoHydrated = true;\n this._hydrateSync();\n }\n\n // ── Override access points to trigger lazy hydration ──\n\n get items(): T[] {\n this._ensureHydrated();\n return super.items;\n }\n\n get state(): T[] {\n return this.items;\n }\n\n get length(): number {\n this._ensureHydrated();\n return super.length;\n }\n\n get(id: T['id']): T | undefined {\n this._ensureHydrated();\n return super.get(id);\n }\n\n has(id: T['id']): boolean {\n this._ensureHydrated();\n return super.has(id);\n }\n\n // ── Persist interface (blob strategy) ──\n\n protected persistGetAll(): T[] {\n const raw = this._storage.getItem(this.storageKey);\n if (!raw) return [];\n try {\n return this.deserialize(raw);\n } catch {\n if (__DEV__) {\n console.warn(\n `[mvc-kit] Corrupted data in storage key \"${this.storageKey}\". Ignoring stored data.`,\n );\n }\n return [];\n }\n }\n\n protected persistGet(id: T['id']): T | null {\n const all = this.persistGetAll();\n return all.find((i) => i.id === id) ?? null;\n }\n\n protected persistSet(_items: T[]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistRemove(_ids: T['id'][]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistClear(): void {\n this._storage.removeItem(this.storageKey);\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"WebStorageCollection.cjs","names":[],"sources":["../../src/web/WebStorageCollection.ts"],"sourcesContent":["import { PersistentCollection } from '../PersistentCollection';\n\nconst __DEV__ = typeof __MVC_KIT_DEV__ !== 'undefined' && __MVC_KIT_DEV__;\n\n/**\n * PersistentCollection backed by localStorage or sessionStorage.\n * Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).\n *\n * Uses blob strategy: all items stored as a single JSON string under `storageKey`.\n *\n * ```ts\n * class CartCollection extends WebStorageCollection<CartItem> {\n * protected readonly storageKey = 'cart';\n * }\n * ```\n */\nexport abstract class WebStorageCollection<\n T extends { id: string | number },\n> extends PersistentCollection<T> {\n /** Which Web Storage backend to use. Override to 'session' for sessionStorage. */\n static STORAGE: 'local' | 'session' = 'local';\n\n private _autoHydrated = false;\n\n private get _storage(): Storage {\n return (this.constructor as typeof WebStorageCollection).STORAGE === 'session'\n ? sessionStorage\n : localStorage;\n }\n\n private _ensureHydrated(): void {\n if (this._autoHydrated) return;\n this._autoHydrated = true;\n this._hydrateSync();\n }\n\n // ── Override access points to trigger lazy hydration ──\n\n get items(): T[] {\n this._ensureHydrated();\n return super.items;\n }\n\n get state(): T[] {\n return this.items;\n }\n\n get length(): number {\n this._ensureHydrated();\n return super.length;\n }\n\n get(id: T['id']): T | undefined {\n this._ensureHydrated();\n return super.get(id);\n }\n\n has(id: T['id']): boolean {\n this._ensureHydrated();\n return super.has(id);\n }\n\n // ── Persist interface (blob strategy) ──\n\n protected persistGetAll(): T[] {\n const raw = this._storage.getItem(this.storageKey);\n if (!raw) return [];\n try {\n return this.deserialize(raw);\n } catch {\n if (__DEV__) {\n console.warn(\n `[mvc-kit] Corrupted data in storage key \"${this.storageKey}\". Ignoring stored data.`,\n );\n }\n return [];\n }\n }\n\n protected persistGet(id: T['id']): T | null {\n const all = this.persistGetAll();\n return all.find((i) => i.id === id) ?? null;\n }\n\n protected persistSet(_items: T[]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistRemove(_ids: T['id'][]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistClear(): void {\n this._storage.removeItem(this.storageKey);\n }\n}\n"],"mappings":";;AAEA,IAAM,UAAU,OAAO,oBAAoB,eAAe;;;;;;;;;;;;;AAc1D,IAAsB,uBAAtB,cAEU,6BAAA,qBAAwB;;CAEhC,OAAO,UAA+B;CAEtC,gBAAwB;CAExB,IAAY,WAAoB;AAC9B,SAAQ,KAAK,YAA4C,YAAY,YACjE,iBACA;;CAGN,kBAAgC;AAC9B,MAAI,KAAK,cAAe;AACxB,OAAK,gBAAgB;AACrB,OAAK,cAAc;;CAKrB,IAAI,QAAa;AACf,OAAK,iBAAiB;AACtB,SAAO,MAAM;;CAGf,IAAI,QAAa;AACf,SAAO,KAAK;;CAGd,IAAI,SAAiB;AACnB,OAAK,iBAAiB;AACtB,SAAO,MAAM;;CAGf,IAAI,IAA4B;AAC9B,OAAK,iBAAiB;AACtB,SAAO,MAAM,IAAI,GAAG;;CAGtB,IAAI,IAAsB;AACxB,OAAK,iBAAiB;AACtB,SAAO,MAAM,IAAI,GAAG;;CAKtB,gBAA+B;EAC7B,MAAM,MAAM,KAAK,SAAS,QAAQ,KAAK,WAAW;AAClD,MAAI,CAAC,IAAK,QAAO,EAAE;AACnB,MAAI;AACF,UAAO,KAAK,YAAY,IAAI;UACtB;AACN,OAAI,QACF,SAAQ,KACN,4CAA4C,KAAK,WAAW,0BAC7D;AAEH,UAAO,EAAE;;;CAIb,WAAqB,IAAuB;AAE1C,SADY,KAAK,eAAe,CACrB,MAAM,MAAM,EAAE,OAAO,GAAG,IAAI;;CAGzC,WAAqB,QAAmB;AACtC,MAAI;AACF,QAAK,SAAS,QAAQ,KAAK,YAAY,KAAK,UAAU,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;WAChE,KAAK;AACZ,OAAI,WAAW,eAAe,gBAAgB,IAAI,SAAS,qBACzD,SAAQ,KACN,4CAA4C,KAAK,WAAW,4DAE7D;AAEH,SAAM;;;CAIV,cAAwB,MAAuB;AAC7C,MAAI;AACF,QAAK,SAAS,QAAQ,KAAK,YAAY,KAAK,UAAU,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;WAChE,KAAK;AACZ,OAAI,WAAW,eAAe,gBAAgB,IAAI,SAAS,qBACzD,SAAQ,KACN,4CAA4C,KAAK,WAAW,4DAE7D;AAEH,SAAM;;;CAIV,eAA+B;AAC7B,OAAK,SAAS,WAAW,KAAK,WAAW"}
|
|
@@ -1,85 +1,83 @@
|
|
|
1
1
|
import { PersistentCollection } from "../PersistentCollection.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
this._storage.removeItem(this.storageKey);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
export {
|
|
83
|
-
WebStorageCollection
|
|
2
|
+
//#region src/web/WebStorageCollection.ts
|
|
3
|
+
var __DEV__ = typeof __MVC_KIT_DEV__ !== "undefined" && __MVC_KIT_DEV__;
|
|
4
|
+
/**
|
|
5
|
+
* PersistentCollection backed by localStorage or sessionStorage.
|
|
6
|
+
* Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).
|
|
7
|
+
*
|
|
8
|
+
* Uses blob strategy: all items stored as a single JSON string under `storageKey`.
|
|
9
|
+
*
|
|
10
|
+
* ```ts
|
|
11
|
+
* class CartCollection extends WebStorageCollection<CartItem> {
|
|
12
|
+
* protected readonly storageKey = 'cart';
|
|
13
|
+
* }
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
var WebStorageCollection = class extends PersistentCollection {
|
|
17
|
+
/** Which Web Storage backend to use. Override to 'session' for sessionStorage. */
|
|
18
|
+
static STORAGE = "local";
|
|
19
|
+
_autoHydrated = false;
|
|
20
|
+
get _storage() {
|
|
21
|
+
return this.constructor.STORAGE === "session" ? sessionStorage : localStorage;
|
|
22
|
+
}
|
|
23
|
+
_ensureHydrated() {
|
|
24
|
+
if (this._autoHydrated) return;
|
|
25
|
+
this._autoHydrated = true;
|
|
26
|
+
this._hydrateSync();
|
|
27
|
+
}
|
|
28
|
+
get items() {
|
|
29
|
+
this._ensureHydrated();
|
|
30
|
+
return super.items;
|
|
31
|
+
}
|
|
32
|
+
get state() {
|
|
33
|
+
return this.items;
|
|
34
|
+
}
|
|
35
|
+
get length() {
|
|
36
|
+
this._ensureHydrated();
|
|
37
|
+
return super.length;
|
|
38
|
+
}
|
|
39
|
+
get(id) {
|
|
40
|
+
this._ensureHydrated();
|
|
41
|
+
return super.get(id);
|
|
42
|
+
}
|
|
43
|
+
has(id) {
|
|
44
|
+
this._ensureHydrated();
|
|
45
|
+
return super.has(id);
|
|
46
|
+
}
|
|
47
|
+
persistGetAll() {
|
|
48
|
+
const raw = this._storage.getItem(this.storageKey);
|
|
49
|
+
if (!raw) return [];
|
|
50
|
+
try {
|
|
51
|
+
return this.deserialize(raw);
|
|
52
|
+
} catch {
|
|
53
|
+
if (__DEV__) console.warn(`[mvc-kit] Corrupted data in storage key "${this.storageKey}". Ignoring stored data.`);
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
persistGet(id) {
|
|
58
|
+
return this.persistGetAll().find((i) => i.id === id) ?? null;
|
|
59
|
+
}
|
|
60
|
+
persistSet(_items) {
|
|
61
|
+
try {
|
|
62
|
+
this._storage.setItem(this.storageKey, this.serialize([...this.items]));
|
|
63
|
+
} catch (err) {
|
|
64
|
+
if (__DEV__ && err instanceof DOMException && err.name === "QuotaExceededError") console.warn(`[mvc-kit] QuotaExceededError writing to "${this.storageKey}". Consider using IndexedDBCollection for larger datasets.`);
|
|
65
|
+
throw err;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
persistRemove(_ids) {
|
|
69
|
+
try {
|
|
70
|
+
this._storage.setItem(this.storageKey, this.serialize([...this.items]));
|
|
71
|
+
} catch (err) {
|
|
72
|
+
if (__DEV__ && err instanceof DOMException && err.name === "QuotaExceededError") console.warn(`[mvc-kit] QuotaExceededError writing to "${this.storageKey}". Consider using IndexedDBCollection for larger datasets.`);
|
|
73
|
+
throw err;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
persistClear() {
|
|
77
|
+
this._storage.removeItem(this.storageKey);
|
|
78
|
+
}
|
|
84
79
|
};
|
|
85
|
-
//#
|
|
80
|
+
//#endregion
|
|
81
|
+
export { WebStorageCollection };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=WebStorageCollection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WebStorageCollection.js","sources":["../../src/web/WebStorageCollection.ts"],"sourcesContent":["import { PersistentCollection } from '../PersistentCollection';\n\nconst __DEV__ = typeof __MVC_KIT_DEV__ !== 'undefined' && __MVC_KIT_DEV__;\n\n/**\n * PersistentCollection backed by localStorage or sessionStorage.\n * Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).\n *\n * Uses blob strategy: all items stored as a single JSON string under `storageKey`.\n *\n * ```ts\n * class CartCollection extends WebStorageCollection<CartItem> {\n * protected readonly storageKey = 'cart';\n * }\n * ```\n */\nexport abstract class WebStorageCollection<\n T extends { id: string | number },\n> extends PersistentCollection<T> {\n /** Which Web Storage backend to use. Override to 'session' for sessionStorage. */\n static STORAGE: 'local' | 'session' = 'local';\n\n private _autoHydrated = false;\n\n private get _storage(): Storage {\n return (this.constructor as typeof WebStorageCollection).STORAGE === 'session'\n ? sessionStorage\n : localStorage;\n }\n\n private _ensureHydrated(): void {\n if (this._autoHydrated) return;\n this._autoHydrated = true;\n this._hydrateSync();\n }\n\n // ── Override access points to trigger lazy hydration ──\n\n get items(): T[] {\n this._ensureHydrated();\n return super.items;\n }\n\n get state(): T[] {\n return this.items;\n }\n\n get length(): number {\n this._ensureHydrated();\n return super.length;\n }\n\n get(id: T['id']): T | undefined {\n this._ensureHydrated();\n return super.get(id);\n }\n\n has(id: T['id']): boolean {\n this._ensureHydrated();\n return super.has(id);\n }\n\n // ── Persist interface (blob strategy) ──\n\n protected persistGetAll(): T[] {\n const raw = this._storage.getItem(this.storageKey);\n if (!raw) return [];\n try {\n return this.deserialize(raw);\n } catch {\n if (__DEV__) {\n console.warn(\n `[mvc-kit] Corrupted data in storage key \"${this.storageKey}\". Ignoring stored data.`,\n );\n }\n return [];\n }\n }\n\n protected persistGet(id: T['id']): T | null {\n const all = this.persistGetAll();\n return all.find((i) => i.id === id) ?? null;\n }\n\n protected persistSet(_items: T[]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistRemove(_ids: T['id'][]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistClear(): void {\n this._storage.removeItem(this.storageKey);\n }\n}\n"],"
|
|
1
|
+
{"version":3,"file":"WebStorageCollection.js","names":[],"sources":["../../src/web/WebStorageCollection.ts"],"sourcesContent":["import { PersistentCollection } from '../PersistentCollection';\n\nconst __DEV__ = typeof __MVC_KIT_DEV__ !== 'undefined' && __MVC_KIT_DEV__;\n\n/**\n * PersistentCollection backed by localStorage or sessionStorage.\n * Auto-hydrates on first access (sync storage — no need for manual `hydrate()` call).\n *\n * Uses blob strategy: all items stored as a single JSON string under `storageKey`.\n *\n * ```ts\n * class CartCollection extends WebStorageCollection<CartItem> {\n * protected readonly storageKey = 'cart';\n * }\n * ```\n */\nexport abstract class WebStorageCollection<\n T extends { id: string | number },\n> extends PersistentCollection<T> {\n /** Which Web Storage backend to use. Override to 'session' for sessionStorage. */\n static STORAGE: 'local' | 'session' = 'local';\n\n private _autoHydrated = false;\n\n private get _storage(): Storage {\n return (this.constructor as typeof WebStorageCollection).STORAGE === 'session'\n ? sessionStorage\n : localStorage;\n }\n\n private _ensureHydrated(): void {\n if (this._autoHydrated) return;\n this._autoHydrated = true;\n this._hydrateSync();\n }\n\n // ── Override access points to trigger lazy hydration ──\n\n get items(): T[] {\n this._ensureHydrated();\n return super.items;\n }\n\n get state(): T[] {\n return this.items;\n }\n\n get length(): number {\n this._ensureHydrated();\n return super.length;\n }\n\n get(id: T['id']): T | undefined {\n this._ensureHydrated();\n return super.get(id);\n }\n\n has(id: T['id']): boolean {\n this._ensureHydrated();\n return super.has(id);\n }\n\n // ── Persist interface (blob strategy) ──\n\n protected persistGetAll(): T[] {\n const raw = this._storage.getItem(this.storageKey);\n if (!raw) return [];\n try {\n return this.deserialize(raw);\n } catch {\n if (__DEV__) {\n console.warn(\n `[mvc-kit] Corrupted data in storage key \"${this.storageKey}\". Ignoring stored data.`,\n );\n }\n return [];\n }\n }\n\n protected persistGet(id: T['id']): T | null {\n const all = this.persistGetAll();\n return all.find((i) => i.id === id) ?? null;\n }\n\n protected persistSet(_items: T[]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistRemove(_ids: T['id'][]): void {\n try {\n this._storage.setItem(this.storageKey, this.serialize([...this.items]));\n } catch (err) {\n if (__DEV__ && err instanceof DOMException && err.name === 'QuotaExceededError') {\n console.warn(\n `[mvc-kit] QuotaExceededError writing to \"${this.storageKey}\". ` +\n `Consider using IndexedDBCollection for larger datasets.`,\n );\n }\n throw err;\n }\n }\n\n protected persistClear(): void {\n this._storage.removeItem(this.storageKey);\n }\n}\n"],"mappings":";;AAEA,IAAM,UAAU,OAAO,oBAAoB,eAAe;;;;;;;;;;;;;AAc1D,IAAsB,uBAAtB,cAEU,qBAAwB;;CAEhC,OAAO,UAA+B;CAEtC,gBAAwB;CAExB,IAAY,WAAoB;AAC9B,SAAQ,KAAK,YAA4C,YAAY,YACjE,iBACA;;CAGN,kBAAgC;AAC9B,MAAI,KAAK,cAAe;AACxB,OAAK,gBAAgB;AACrB,OAAK,cAAc;;CAKrB,IAAI,QAAa;AACf,OAAK,iBAAiB;AACtB,SAAO,MAAM;;CAGf,IAAI,QAAa;AACf,SAAO,KAAK;;CAGd,IAAI,SAAiB;AACnB,OAAK,iBAAiB;AACtB,SAAO,MAAM;;CAGf,IAAI,IAA4B;AAC9B,OAAK,iBAAiB;AACtB,SAAO,MAAM,IAAI,GAAG;;CAGtB,IAAI,IAAsB;AACxB,OAAK,iBAAiB;AACtB,SAAO,MAAM,IAAI,GAAG;;CAKtB,gBAA+B;EAC7B,MAAM,MAAM,KAAK,SAAS,QAAQ,KAAK,WAAW;AAClD,MAAI,CAAC,IAAK,QAAO,EAAE;AACnB,MAAI;AACF,UAAO,KAAK,YAAY,IAAI;UACtB;AACN,OAAI,QACF,SAAQ,KACN,4CAA4C,KAAK,WAAW,0BAC7D;AAEH,UAAO,EAAE;;;CAIb,WAAqB,IAAuB;AAE1C,SADY,KAAK,eAAe,CACrB,MAAM,MAAM,EAAE,OAAO,GAAG,IAAI;;CAGzC,WAAqB,QAAmB;AACtC,MAAI;AACF,QAAK,SAAS,QAAQ,KAAK,YAAY,KAAK,UAAU,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;WAChE,KAAK;AACZ,OAAI,WAAW,eAAe,gBAAgB,IAAI,SAAS,qBACzD,SAAQ,KACN,4CAA4C,KAAK,WAAW,4DAE7D;AAEH,SAAM;;;CAIV,cAAwB,MAAuB;AAC7C,MAAI;AACF,QAAK,SAAS,QAAQ,KAAK,YAAY,KAAK,UAAU,CAAC,GAAG,KAAK,MAAM,CAAC,CAAC;WAChE,KAAK;AACZ,OAAI,WAAW,eAAe,gBAAgB,IAAI,SAAS,qBACzD,SAAQ,KACN,4CAA4C,KAAK,WAAW,4DAE7D;AAEH,SAAM;;;CAIV,eAA+B;AAC7B,OAAK,SAAS,WAAW,KAAK,WAAW"}
|
package/dist/web/idb.cjs
CHANGED
|
@@ -1,121 +1,129 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
//#region src/web/idb.ts
|
|
2
|
+
/**
|
|
3
|
+
* Shared IndexedDB connection manager.
|
|
4
|
+
* Deduplicates indexedDB.open() calls and handles dynamic object store creation
|
|
5
|
+
* by bumping the DB version when a new storageKey is encountered.
|
|
6
|
+
*/
|
|
7
|
+
var _connections = /* @__PURE__ */ new Map();
|
|
8
|
+
var _stores = /* @__PURE__ */ new Map();
|
|
9
|
+
var _openQueue = Promise.resolve();
|
|
6
10
|
function openDB(dbName, storeName) {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
_openQueue = result.then(() => {
|
|
23
|
-
}, () => {
|
|
24
|
-
});
|
|
25
|
-
return result;
|
|
11
|
+
const existing = _connections.get(dbName);
|
|
12
|
+
if (existing) {
|
|
13
|
+
if (existing.objectStoreNames.contains(storeName)) return Promise.resolve(existing);
|
|
14
|
+
existing.close();
|
|
15
|
+
_connections.delete(dbName);
|
|
16
|
+
}
|
|
17
|
+
let stores = _stores.get(dbName);
|
|
18
|
+
if (!stores) {
|
|
19
|
+
stores = /* @__PURE__ */ new Set();
|
|
20
|
+
_stores.set(dbName, stores);
|
|
21
|
+
}
|
|
22
|
+
stores.add(storeName);
|
|
23
|
+
const result = _openQueue.then(() => doOpen(dbName, stores));
|
|
24
|
+
_openQueue = result.then(() => {}, () => {});
|
|
25
|
+
return result;
|
|
26
26
|
}
|
|
27
27
|
function doOpen(dbName, stores) {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
_connections.set(dbName, upgrade.result);
|
|
60
|
-
resolve(upgrade.result);
|
|
61
|
-
};
|
|
62
|
-
upgrade.onerror = () => reject(upgrade.error);
|
|
63
|
-
};
|
|
64
|
-
probe.onerror = () => reject(probe.error);
|
|
65
|
-
});
|
|
28
|
+
_connections.get(dbName)?.close();
|
|
29
|
+
_connections.delete(dbName);
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
const probe = indexedDB.open(dbName);
|
|
32
|
+
probe.onsuccess = () => {
|
|
33
|
+
const db = probe.result;
|
|
34
|
+
const version = db.version;
|
|
35
|
+
let needsUpgrade = false;
|
|
36
|
+
for (const name of stores) if (!db.objectStoreNames.contains(name)) {
|
|
37
|
+
needsUpgrade = true;
|
|
38
|
+
break;
|
|
39
|
+
}
|
|
40
|
+
if (!needsUpgrade) {
|
|
41
|
+
_connections.set(dbName, db);
|
|
42
|
+
resolve(db);
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
db.close();
|
|
46
|
+
const upgrade = indexedDB.open(dbName, version + 1);
|
|
47
|
+
upgrade.onupgradeneeded = () => {
|
|
48
|
+
const udb = upgrade.result;
|
|
49
|
+
for (const name of stores) if (!udb.objectStoreNames.contains(name)) udb.createObjectStore(name, { keyPath: "id" });
|
|
50
|
+
};
|
|
51
|
+
upgrade.onsuccess = () => {
|
|
52
|
+
_connections.set(dbName, upgrade.result);
|
|
53
|
+
resolve(upgrade.result);
|
|
54
|
+
};
|
|
55
|
+
upgrade.onerror = () => reject(upgrade.error);
|
|
56
|
+
};
|
|
57
|
+
probe.onerror = () => reject(probe.error);
|
|
58
|
+
});
|
|
66
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Open a transaction and return the object store for the given database and store name.
|
|
62
|
+
*/
|
|
67
63
|
function getStore(dbName, storeName, mode) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
64
|
+
return openDB(dbName, storeName).then((db) => {
|
|
65
|
+
return db.transaction(storeName, mode).objectStore(storeName);
|
|
66
|
+
});
|
|
72
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Retrieve all items from an IndexedDB object store.
|
|
70
|
+
*/
|
|
73
71
|
function idbGetAll(store) {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
72
|
+
return new Promise((resolve, reject) => {
|
|
73
|
+
const request = store.getAll();
|
|
74
|
+
request.onsuccess = () => resolve(request.result);
|
|
75
|
+
request.onerror = () => reject(request.error);
|
|
76
|
+
});
|
|
79
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Retrieve a single item by key from an IndexedDB object store.
|
|
80
|
+
*/
|
|
80
81
|
function idbGet(store, id) {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
82
|
+
return new Promise((resolve, reject) => {
|
|
83
|
+
const request = store.get(id);
|
|
84
|
+
request.onsuccess = () => resolve(request.result ?? null);
|
|
85
|
+
request.onerror = () => reject(request.error);
|
|
86
|
+
});
|
|
86
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Write (put) multiple items into an IndexedDB object store.
|
|
90
|
+
*/
|
|
87
91
|
function idbPut(store, items) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
tx.onerror = () => reject(tx.error);
|
|
95
|
-
});
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
const tx = store.transaction;
|
|
94
|
+
for (const item of items) store.put(item);
|
|
95
|
+
tx.oncomplete = () => resolve();
|
|
96
|
+
tx.onerror = () => reject(tx.error);
|
|
97
|
+
});
|
|
96
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Delete multiple items by key from an IndexedDB object store.
|
|
101
|
+
*/
|
|
97
102
|
function idbDelete(store, ids) {
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
tx.onerror = () => reject(tx.error);
|
|
105
|
-
});
|
|
103
|
+
return new Promise((resolve, reject) => {
|
|
104
|
+
const tx = store.transaction;
|
|
105
|
+
for (const id of ids) store.delete(id);
|
|
106
|
+
tx.oncomplete = () => resolve();
|
|
107
|
+
tx.onerror = () => reject(tx.error);
|
|
108
|
+
});
|
|
106
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* Clear all items from an IndexedDB object store.
|
|
112
|
+
*/
|
|
107
113
|
function idbClear(store) {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
+
return new Promise((resolve, reject) => {
|
|
115
|
+
const tx = store.transaction;
|
|
116
|
+
store.clear();
|
|
117
|
+
tx.oncomplete = () => resolve();
|
|
118
|
+
tx.onerror = () => reject(tx.error);
|
|
119
|
+
});
|
|
114
120
|
}
|
|
121
|
+
//#endregion
|
|
115
122
|
exports.getStore = getStore;
|
|
116
123
|
exports.idbClear = idbClear;
|
|
117
124
|
exports.idbDelete = idbDelete;
|
|
118
125
|
exports.idbGet = idbGet;
|
|
119
126
|
exports.idbGetAll = idbGetAll;
|
|
120
127
|
exports.idbPut = idbPut;
|
|
121
|
-
|
|
128
|
+
|
|
129
|
+
//# sourceMappingURL=idb.cjs.map
|