schema-idb 0.0.5 → 0.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 +19 -2
- package/dist/createSchemaDB.js +9 -1
- package/dist/schemaDetection.d.ts +0 -6
- package/dist/schemaDetection.js +3 -3
- package/package.json +1 -1
- package/dist/createDB.d.ts +0 -2
- package/dist/createDB.js +0 -1
- package/dist/defineStore.d.ts +0 -5
- package/dist/defineStore.js +0 -1
- package/dist/readChain.d.ts +0 -2
- package/dist/readChain.js +0 -1
- package/dist/writeChain.d.ts +0 -2
- package/dist/writeChain.js +0 -1
package/README.md
CHANGED
|
@@ -333,13 +333,30 @@ const db = openDB({
|
|
|
333
333
|
name: "MyApp",
|
|
334
334
|
versionStrategy: "auto",
|
|
335
335
|
// 'error' (default): Throws an error when stores are removed
|
|
336
|
-
// 'preserve': Renames removed stores to
|
|
336
|
+
// 'preserve': Renames removed stores to __storeName_deleted_v{version}__ as backup.
|
|
337
337
|
// Preserved stores are isolated from the typed API to avoid future name collisions.
|
|
338
338
|
removedStoreStrategy: "preserve",
|
|
339
339
|
stores: [usersStore] as const,
|
|
340
340
|
});
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
+
#### Behavior with explicit versioning
|
|
344
|
+
|
|
345
|
+
When `versionStrategy` is `"explicit"`:
|
|
346
|
+
|
|
347
|
+
- Schema changes are **detected** but **NOT applied** automatically
|
|
348
|
+
- `removedStoreStrategy` is evaluated for preview purposes only
|
|
349
|
+
- A warning is logged if schema changes are detected but version is not bumped
|
|
350
|
+
|
|
351
|
+
```
|
|
352
|
+
[schema-idb] Schema changes detected but version not bumped:
|
|
353
|
+
- Rename store "oldStore" to "__oldStore_deleted_v2__"
|
|
354
|
+
Current DB version: 1, Provided version: 1
|
|
355
|
+
Bump the version to apply these changes.
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
**Important:** `removedStoreStrategy` does not perform migrations in explicit mode. It only describes what _would_ happen after a version bump. To apply the changes, increment the `version` number.
|
|
359
|
+
|
|
343
360
|
To explicitly delete a store (including backups), use a migration:
|
|
344
361
|
|
|
345
362
|
```ts
|
|
@@ -347,7 +364,7 @@ const usersStore = defineStore("users", {
|
|
|
347
364
|
// ...
|
|
348
365
|
}).addMigration("003-delete-old-store", (db) => {
|
|
349
366
|
db.deleteObjectStore("oldStore");
|
|
350
|
-
db.deleteObjectStore("
|
|
367
|
+
db.deleteObjectStore("__oldStore_deleted_v2__"); // Remove backup too
|
|
351
368
|
});
|
|
352
369
|
```
|
|
353
370
|
|
package/dist/createSchemaDB.js
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var E=Object.defineProperty;var d=(e,r)=>E(e,"name",{value:r,configurable:!0});import{openDatabase as T}from"./utils.js";import{createStoreAccessor as D}from"./storeAccessor.js";import{createStartTransaction as A}from"./transaction.js";import{determineAutoVersion as k,applySafeChanges as R,openDatabaseForSchemaRead as $,readExistingSchema as M,toDesiredSchema as z,detectSchemaChanges as j}from"./schemaDetection.js";import{ensureSchemaHistoryStore as B,getAppliedMigrations as x,recordMigrationApplied as C,initializeSchemaHistory as q}from"./migrationHistory.js";function Y(e){return e}d(Y,"getKeyPathString");function U(e,r,a){const n=d(async()=>{if(await e.readyPromise,!e.idb)throw new Error("Database initialization failed");return D(e.idb,r,a)},"getAccessor");return new Proxy({},{get(t,o){return o==="query"?c=>c?n().then(u=>u.query(c)):F(e,r,a):async(...c)=>(await n())[o](...c)}})}d(U,"createLazyStoreAccessor");function F(e,r,a){const n=d(async()=>{if(await e.readyPromise,!e.idb)throw new Error("Database initialization failed");return D(e.idb,r,a).query()},"getQueryBuilder"),t=d(o=>new Proxy({},{get(c,u){return u==="findAll"||u==="find"||u==="count"?()=>o().then(s=>s[u]()):(...s)=>t(d(()=>o().then(l=>l[u](...s)),"newGetBuilder"))}}),"createBuilderProxy");return t(n)}d(F,"createLazyQueryBuilder");function K(e,r){const a={get name(){return e.idb?.name??r},get version(){return e.idb?.version??0},get raw(){if(!e.idb)throw new Error("Database not ready. Call waitForReady() first or check ready property.");return e.idb},get ready(){return e.ready},waitForReady(){return e.readyPromise},close(){e.idb?.close()},startTransaction(...n){if(!e.startTransaction){const[t,o]=n,c=Array.isArray(t)?t:[t];return L(e,c,o)}return e.startTransaction(...n)}};for(const n of e.stores)Object.defineProperty(a,n.name,{get(){return U(e,n.name,n.defaults)},enumerable:!0});return a}d(K,"buildSchemaDatabase");function L(e,r,a){const n={get raw(){throw new Error("Transaction raw is not available before ready state. Use await db.waitForReady() before starting transactions.")},async commit(){if(await e.readyPromise,!e.startTransaction)throw new Error("Database initialization failed");return e.startTransaction(r,a).commit()},abort(){}};for(const t of r)e.stores.find(c=>c.name===t)&&Object.defineProperty(n,t,{get(){throw new Error("Transaction operations before ready state are not yet supported. Use await db.waitForReady() before starting transactions.")},enumerable:!0});return n}d(L,"createLazyTransaction");function O(e){const r=[],a=new Set;for(const n of e)for(const t of n.migrations){if(a.has(t.name))throw new Error(`Duplicate migration name "${t.name}" found across stores`);a.add(t.name),r.push(t)}return r.sort((n,t)=>n.name.localeCompare(t.name))}d(O,"collectMigrations");function N(e,r){const a=new Set(r);return e.filter(n=>!a.has(n.name)).sort((n,t)=>n.name.localeCompare(t.name))}d(N,"filterPendingMigrations");function V(e,r,a,n,t,o,c){if(B(e),a===0){for(const s of n){const i=e.createObjectStore(s.name,{keyPath:s.keyPath});for(const l of s.indexes)i.createIndex(l.name,l.keyPath,{unique:l.unique??!1,multiEntry:l.multiEntry??!1})}q(r)}else c&&c.safe.length>0&&R(e,r,c.safe,n);let u=[...o];for(const s of t)try{const i=s.up(e,r);i instanceof Promise&&i.catch(l=>{console.error(`Migration "${s.name}" failed:`,l),r.abort()}),C(r,s.name,u),u=[...u,s.name].sort()}catch(i){throw console.error(`Migration "${s.name}" failed:`,i),r.abort(),i}}d(V,"handleUpgrade");export function openDB(e){const{name:r,version:a,versionStrategy:n="explicit",removedStoreStrategy:t="error",stores:o,onBlocked:c,onVersionChange:u}=e,s=new Set;for(const f of o){if(s.has(f.name))throw new Error(`Duplicate store name: "${f.name}"`);s.add(f.name)}const i=O(o);let l=d(()=>{},"readyResolve"),g=d(()=>{},"readyReject");const p={idb:null,ready:!1,error:null,readyPromise:new Promise((f,y)=>{l=f,g=y}),readyResolve:l,readyReject:g,stores:o,startTransaction:null},m=K(p,r);return G(p,r,a,n,t,o,i,c,u),m}d(openDB,"openDB");async function G(e,r,a,n,t,o,c,u,s){try{let i=[],l=null,g;if(n==="auto"){const m=await k(r,o,{removedStoreStrategy:t});if(g=m.version,l=m.changes,m.version>1){const y=await $(r);y&&(i=await x(y),y.close())}N(c,i).length>0&&!m.needsUpgrade&&(g=m.version+1)}else{if(a===void 0)throw new Error('Version is required when versionStrategy is "explicit"');g=a;const m=await $(r);if(m){const f=m.version;i=await x(m);const y=M(m),_=z(o);m.close();const b=j(y,_);if(b.hasChanges){const S=[];for(const w of b.dangerous)w.type==="store_delete"&&t==="preserve"?b.safe.push({type:"store_rename",oldName:w.storeName,newName:`__${w.storeName}_deleted_v${f}__`}):S.push(w);if(S.length>0){const h=`Dangerous schema changes detected:
|
|
2
|
+
${S.map(v=>{switch(v.type){case"store_delete":return`Store "${v.storeName}" would be deleted. Use removedStoreStrategy: 'preserve' to backup, or add a migration to explicitly delete it.`;case"keypath_change":return`Store "${v.storeName}" keyPath changed from "${v.oldKeyPath}" to "${v.newKeyPath}". This requires recreating the store with a manual migration.`;default:return"Unknown dangerous change"}}).join(`
|
|
3
|
+
`)}
|
|
4
|
+
|
|
5
|
+
Add explicit migrations to handle these changes safely.`;throw console.error("[schema-idb]",h),new Error(h)}if(b.dangerous=S,l=b,g<=f){const w=b.safe.map(h=>{switch(h.type){case"store_add":return`- Add store "${h.storeName}"`;case"store_rename":return`- Rename store "${h.oldName}" to "${h.newName}"`;case"index_add":return`- Add index "${h.indexName}" on "${h.storeName}"`;case"index_delete":return`- Delete index "${h.indexName}" from "${h.storeName}"`;default:return"- Schema change"}});console.warn(`[schema-idb] Schema changes detected but version not bumped:
|
|
6
|
+
${w.join(`
|
|
7
|
+
`)}
|
|
8
|
+
Current DB version: ${f}, Provided version: ${g}
|
|
9
|
+
Bump the version to apply these changes.`)}}}}const P=N(c,i),p=await T(r,g,(m,f,y)=>{V(m,f,y,o,P,i,l)},u);s&&(p.onversionchange=s),e.idb=p,e.startTransaction=A(p,o),e.ready=!0,e.readyResolve()}catch(i){e.error=i instanceof Error?i:new Error(String(i)),e.readyReject(e.error)}}d(G,"initializeDatabase");
|
|
@@ -65,12 +65,6 @@ export declare function applySafeChanges(db: IDBDatabase, tx: IDBTransaction, ch
|
|
|
65
65
|
keyPath: string | string[] | undefined;
|
|
66
66
|
indexes: IndexDefinition[];
|
|
67
67
|
}[]): void;
|
|
68
|
-
export declare function generateSchemaFingerprint(stores: readonly {
|
|
69
|
-
name: string;
|
|
70
|
-
keyPath: string | string[] | undefined;
|
|
71
|
-
indexes: IndexDefinition[];
|
|
72
|
-
}[]): string;
|
|
73
|
-
export declare function hashFingerprint(fingerprint: string): number;
|
|
74
68
|
export declare function getCurrentDatabaseVersion(dbName: string): Promise<number>;
|
|
75
69
|
export declare function openDatabaseForSchemaRead(dbName: string): Promise<IDBDatabase | null>;
|
|
76
70
|
export interface AutoVersionOptions {
|
package/dist/schemaDetection.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
"use strict";var g=Object.defineProperty;var
|
|
2
|
-
${
|
|
1
|
+
"use strict";var g=Object.defineProperty;var l=(r,t)=>g(r,"name",{value:t,configurable:!0});function p(r){return r.startsWith("__")}l(p,"isInternalStore");export function readExistingSchema(r){const t=new Map,n=Array.from({length:r.objectStoreNames.length},(a,o)=>r.objectStoreNames.item(o)).filter(a=>!p(a));for(const a of n){const o=r.transaction(a,"readonly"),u=o.objectStore(a),s=new Map,c=Array.from({length:u.indexNames.length},(e,i)=>u.indexNames.item(i));for(const e of c){const i=u.index(e);s.set(e,{keyPath:i.keyPath,unique:i.unique,multiEntry:i.multiEntry})}t.set(a,{name:a,keyPath:u.keyPath,indexes:s}),o.abort()}return t}l(readExistingSchema,"readExistingSchema");export function toDesiredSchema(r){const t=new Map;for(const n of r)t.set(n.name,{name:n.name,keyPath:n.keyPath,indexes:n.indexes});return t}l(toDesiredSchema,"toDesiredSchema");function x(r,t){return r===t||r==null&&t==null?!0:r==null||t==null?!1:Array.isArray(r)&&Array.isArray(t)?r.length!==t.length?!1:r.every((n,a)=>n===t[a]):r===t}l(x,"keyPathEquals");export function detectSchemaChanges(r,t){const n=[],a=[];for(const[o,u]of t){const s=r.get(o);if(!s){n.push({type:"store_add",storeName:o});continue}if(!x(s.keyPath,u.keyPath)){a.push({type:"keypath_change",storeName:o,oldKeyPath:s.keyPath,newKeyPath:u.keyPath});continue}for(const e of u.indexes){const i=s.indexes.get(e.name);if(!i)n.push({type:"index_add",storeName:o,indexName:e.name,index:e});else{const m=!x(i.keyPath,e.keyPath),h=i.unique!==(e.unique??!1),d=i.multiEntry!==(e.multiEntry??!1);(m||h||d)&&(n.push({type:"index_delete",storeName:o,indexName:e.name}),n.push({type:"index_add",storeName:o,indexName:e.name,index:e}))}}const c=new Set(u.indexes.map(e=>e.name));for(const e of s.indexes.keys())c.has(e)||n.push({type:"index_delete",storeName:o,indexName:e})}for(const o of r.keys())t.has(o)||a.push({type:"store_delete",storeName:o});return{safe:n,dangerous:a,hasChanges:n.length>0||a.length>0}}l(detectSchemaChanges,"detectSchemaChanges");export function applySafeChanges(r,t,n,a){const o=n.filter(s=>s.type==="store_rename"),u=new Map;for(const s of o){const c=t.objectStore(s.oldName),e=[],i=Array.from({length:c.indexNames.length},(h,d)=>c.indexNames.item(d));for(const h of i){const d=c.index(h);e.push({name:h,keyPath:d.keyPath,unique:d.unique,multiEntry:d.multiEntry})}u.set(s.oldName,{keyPath:c.keyPath,indexes:e,newName:s.newName});const m=c.getAll();m.onsuccess=()=>{const h=m.result,d=u.get(s.oldName),y=r.createObjectStore(d.newName,{keyPath:d.keyPath});for(const f of d.indexes)y.createIndex(f.name,f.keyPath,{unique:f.unique,multiEntry:f.multiEntry});for(const f of h)y.put(f)},r.deleteObjectStore(s.oldName)}for(const s of n)switch(s.type){case"store_add":{const c=a.find(e=>e.name===s.storeName);if(c){const e=r.createObjectStore(c.name,{keyPath:c.keyPath});for(const i of c.indexes)e.createIndex(i.name,i.keyPath,{unique:i.unique??!1,multiEntry:i.multiEntry??!1})}break}case"index_add":{t.objectStore(s.storeName).createIndex(s.indexName,s.index.keyPath,{unique:s.index.unique??!1,multiEntry:s.index.multiEntry??!1});break}case"index_delete":{t.objectStore(s.storeName).deleteIndex(s.indexName);break}}}l(applySafeChanges,"applySafeChanges");export async function getCurrentDatabaseVersion(r){return new Promise(t=>{const n=indexedDB.open(r);n.onsuccess=()=>{const a=n.result,o=a.version;a.close(),t(o)},n.onerror=()=>{t(0)}})}l(getCurrentDatabaseVersion,"getCurrentDatabaseVersion");export async function openDatabaseForSchemaRead(r){return new Promise(t=>{const n=indexedDB.open(r);n.onsuccess=()=>{t(n.result)},n.onerror=()=>{t(null)},n.onupgradeneeded=()=>{n.transaction?.abort(),t(null)}})}l(openDatabaseForSchemaRead,"openDatabaseForSchemaRead");export async function determineAutoVersion(r,t,n={}){const{removedStoreStrategy:a="error"}=n,o=await openDatabaseForSchemaRead(r);if(!o)return{version:1,changes:null,needsUpgrade:!0};const u=o.version,s=readExistingSchema(o),c=toDesiredSchema(t);o.close();const e=detectSchemaChanges(s,c);if(!e.hasChanges)return{version:u,changes:null,needsUpgrade:!1};const i=[];for(const m of e.dangerous)m.type==="store_delete"&&a==="preserve"?e.safe.push({type:"store_rename",oldName:m.storeName,newName:`__${m.storeName}_deleted_v${u}__`}):i.push(m);if(e.dangerous=i,e.dangerous.length>0){const h=`Dangerous schema changes detected:
|
|
2
|
+
${e.dangerous.map(d=>{switch(d.type){case"store_delete":return`Store "${d.storeName}" would be deleted. Use removedStoreStrategy: 'preserve' to backup, or add a migration to explicitly delete it.`;case"keypath_change":return`Store "${d.storeName}" keyPath changed from "${d.oldKeyPath}" to "${d.newKeyPath}". This requires recreating the store with a manual migration.`;default:return"Unknown dangerous change"}}).join(`
|
|
3
3
|
`)}
|
|
4
4
|
|
|
5
|
-
Add explicit migrations to handle these changes safely
|
|
5
|
+
Add explicit migrations to handle these changes safely.`;throw console.error("[schema-idb]",h),new Error(h)}return{version:u+1,changes:e,needsUpgrade:!0}}l(determineAutoVersion,"determineAutoVersion");
|
package/package.json
CHANGED
package/dist/createDB.d.ts
DELETED
package/dist/createDB.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var w=Object.defineProperty;var f=(n,t)=>w(n,"name",{value:t,configurable:!0});import{openDatabase as y,promisifyTransaction as b}from"./utils.js";import{createReadChain as S}from"./readChain.js";import{createWriteChain as v}from"./writeChain.js";import{createStoreAccessor as x}from"./storeAccessor.js";function D(n){const t=[],s=new Set;for(const r of n)for(const e of r.migrations){if(s.has(e.name))throw new Error(`Duplicate migration name "${e.name}" found across stores`);s.add(e.name),t.push(e)}return t.sort((r,e)=>r.name.localeCompare(e.name))}f(D,"collectMigrations");function E(n,t,s){const r={...n};for(const e of s)r[e.name]=x(t,e.name);return r}f(E,"buildDatabaseWithStores");function P(n,t,s,r,e){if(s===0)for(const a of r){const i=n.createObjectStore(a.name,{keyPath:a.keyPath,autoIncrement:a.autoIncrement});for(const c of a.indexes)i.createIndex(c.name,c.keyPath,{unique:c.unique??!1,multiEntry:c.multiEntry??!1})}for(const a of e)try{const i=a.up(n,t);i instanceof Promise&&i.catch(c=>{console.error(`Migration "${a.name}" failed:`,c),t.abort()})}catch(i){throw console.error(`Migration "${a.name}" failed:`,i),t.abort(),i}}f(P,"handleUpgrade");export async function openDB(n){const{name:t,version:s,versionStrategy:r="explicit",stores:e,onBlocked:a,onVersionChange:i}=n,c=new Set;for(const o of e){if(c.has(o.name))throw new Error(`Duplicate store name: "${o.name}"`);c.add(o.name)}let u;if(r==="auto")u=1;else{if(s===void 0)throw new Error('Version is required when versionStrategy is "explicit"');u=s}const p=D(e),m=await y(t,u,(o,l,d)=>{P(o,l,d,e,p)},a);return i&&(m.onversionchange=i),E({get name(){return m.name},get version(){return m.version},get raw(){return m},close(){m.close()},read(o){return S(m,o)},write(o){return v(m,o)},async transaction(o,l,d){const h=m.transaction(o,l),g=d(h);g instanceof Promise&&await g,await b(h)}},m,e)}f(openDB,"openDB");
|
package/dist/defineStore.d.ts
DELETED
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import type { StoreDefinition, StoreKeyPath, ExtractKeyType, StoreOptionsWithKeyPath, StoreOptionsWithoutKeyPath } from './types.js';
|
|
2
|
-
export declare function defineStore<T>(): {
|
|
3
|
-
<const TName extends string, const KP extends StoreKeyPath<T>>(name: TName, options: StoreOptionsWithKeyPath<T, KP>): StoreDefinition<T, ExtractKeyType<T, KP>, TName>;
|
|
4
|
-
<const TName extends string, K extends IDBValidKey = IDBValidKey>(name: TName, options?: StoreOptionsWithoutKeyPath<T, K>): StoreDefinition<T, K, TName>;
|
|
5
|
-
};
|
package/dist/defineStore.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var p=Object.defineProperty;var i=(t,e)=>p(t,"name",{value:e,configurable:!0});function g(t){if(!t)return[];const e=[];for(const[r,o]of Object.entries(t))o!==!1&&(o===!0?e.push({name:r,keyPath:r}):e.push({name:r,keyPath:r,unique:o.unique,multiEntry:o.multiEntry}));return e}i(g,"parseIndexConfig");export function defineStore(){function t(e,r={}){const{keyPath:o,autoIncrement:u=!1,indexes:m,migrations:a=[]}=r,f=g(m);if(!e||typeof e!="string")throw new Error("Store name is required and must be a string");const s=new Set;for(const n of a){if(!n.name||typeof n.name!="string")throw new Error(`Invalid migration name in store "${e}": must be a non-empty string`);if(s.has(n.name))throw new Error(`Duplicate migration name "${n.name}" in store "${e}"`);s.add(n.name)}return{name:e,keyPath:o,autoIncrement:u,indexes:f,migrations:[...a].sort((n,c)=>n.name.localeCompare(c.name)),_schema:{},_keyType:{}}}return i(t,"createStore"),t}i(defineStore,"defineStore");
|
package/dist/readChain.d.ts
DELETED
package/dist/readChain.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var l=Object.defineProperty;var i=(s,u)=>l(s,"name",{value:u,configurable:!0});import{promisifyTransaction as p}from"./utils.js";function g(s){return s}i(g,"toReadChain");export function createReadChain(s,u){const r=[],c={get(n,t){return r.push({type:"get",storeName:n,key:t}),c},getAll(n,t){return r.push({type:"getAll",storeName:n,query:t?.query,count:t?.count}),c},getAllByIndex(n,t,o){return r.push({type:"getAllByIndex",storeName:n,indexName:t,query:o}),c},count(n,t){return r.push({type:"count",storeName:n,query:t}),c},async execute(){if(r.length===0)return[];const n=[...new Set(r.map(e=>e.storeName))];for(const e of n)if(!u.includes(e))throw new Error(`Store "${e}" is not in the transaction scope. Available stores: ${u.join(", ")}`);const t=s.transaction(u,"readonly"),o=[];for(const e of r){const a=t.objectStore(e.storeName);switch(e.type){case"get":o.push(a.get(e.key));break;case"getAll":o.push(a.getAll(e.query,e.count));break;case"getAllByIndex":o.push(a.index(e.indexName).getAll(e.query));break;case"count":o.push(a.count(e.query));break}}return await p(t),o.map(e=>e.result)}};return c}i(createReadChain,"createReadChain");
|
package/dist/writeChain.d.ts
DELETED
package/dist/writeChain.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var i=(n,o)=>u(n,"name",{value:o,configurable:!0});import{promisifyTransaction as p}from"./utils.js";function h(n){return n}i(h,"toWriteChain");export function createWriteChain(n,o){const a=[],s={put(t,r,e){return a.push({type:"put",storeName:t,value:r,key:e}),s},add(t,r,e){return a.push({type:"add",storeName:t,value:r,key:e}),s},delete(t,r){return a.push({type:"delete",storeName:t,key:r}),s},clear(t){return a.push({type:"clear",storeName:t}),s},async execute(){if(a.length===0)return;const t=[...new Set(a.map(e=>e.storeName))];for(const e of t)if(!o.includes(e))throw new Error(`Store "${e}" is not in the transaction scope. Available stores: ${o.join(", ")}`);const r=n.transaction(o,"readwrite");for(const e of a){const c=r.objectStore(e.storeName);switch(e.type){case"put":c.put(e.value,e.key);break;case"add":c.add(e.value,e.key);break;case"delete":c.delete(e.key);break;case"clear":c.clear();break}}await p(r)}};return s}i(createWriteChain,"createWriteChain");
|