@vielzeug/vault 2.3.0 → 2.4.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.
Files changed (68) hide show
  1. package/dist/adapter-core.cjs +1 -1
  2. package/dist/adapter-core.cjs.map +1 -1
  3. package/dist/adapter-core.d.ts +2 -2
  4. package/dist/adapter-core.d.ts.map +1 -1
  5. package/dist/adapter-core.js +66 -116
  6. package/dist/adapter-core.js.map +1 -1
  7. package/dist/adapters/indexeddb.cjs +1 -1
  8. package/dist/adapters/indexeddb.cjs.map +1 -1
  9. package/dist/adapters/indexeddb.d.ts +3 -3
  10. package/dist/adapters/indexeddb.d.ts.map +1 -1
  11. package/dist/adapters/indexeddb.js +93 -102
  12. package/dist/adapters/indexeddb.js.map +1 -1
  13. package/dist/adapters/memory.cjs +1 -1
  14. package/dist/adapters/memory.cjs.map +1 -1
  15. package/dist/adapters/memory.d.ts +1 -3
  16. package/dist/adapters/memory.d.ts.map +1 -1
  17. package/dist/adapters/memory.js +24 -105
  18. package/dist/adapters/memory.js.map +1 -1
  19. package/dist/adapters/sqlite.cjs +16 -4
  20. package/dist/adapters/sqlite.cjs.map +1 -1
  21. package/dist/adapters/sqlite.d.ts +2 -3
  22. package/dist/adapters/sqlite.d.ts.map +1 -1
  23. package/dist/adapters/sqlite.js +122 -90
  24. package/dist/adapters/sqlite.js.map +1 -1
  25. package/dist/adapters/webstorage.cjs +1 -1
  26. package/dist/adapters/webstorage.cjs.map +1 -1
  27. package/dist/adapters/webstorage.d.ts.map +1 -1
  28. package/dist/adapters/webstorage.js +59 -66
  29. package/dist/adapters/webstorage.js.map +1 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +1 -2
  32. package/dist/index.d.ts.map +1 -1
  33. package/dist/index.js +2 -3
  34. package/dist/internal.cjs +1 -1
  35. package/dist/internal.cjs.map +1 -1
  36. package/dist/internal.d.ts +1 -1
  37. package/dist/internal.d.ts.map +1 -1
  38. package/dist/internal.js +18 -23
  39. package/dist/internal.js.map +1 -1
  40. package/dist/query.cjs +1 -1
  41. package/dist/query.cjs.map +1 -1
  42. package/dist/query.d.ts +11 -79
  43. package/dist/query.d.ts.map +1 -1
  44. package/dist/query.js +14 -71
  45. package/dist/query.js.map +1 -1
  46. package/dist/types.cjs.map +1 -1
  47. package/dist/types.d.ts +4 -34
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/types.js.map +1 -1
  50. package/dist/vault.cjs +1 -1
  51. package/dist/vault.cjs.map +1 -1
  52. package/dist/vault.iife.js +1 -1
  53. package/dist/vault.iife.js.map +1 -1
  54. package/dist/vault.js +1 -1
  55. package/dist/vault.js.map +1 -1
  56. package/package.json +2 -1
  57. package/dist/_dev.cjs +0 -2
  58. package/dist/_dev.cjs.map +0 -1
  59. package/dist/_dev.d.ts +0 -2
  60. package/dist/_dev.d.ts.map +0 -1
  61. package/dist/_dev.js +0 -6
  62. package/dist/_dev.js.map +0 -1
  63. package/dist/prune.cjs +0 -2
  64. package/dist/prune.cjs.map +0 -1
  65. package/dist/prune.d.ts +0 -21
  66. package/dist/prune.d.ts.map +0 -1
  67. package/dist/prune.js +0 -16
  68. package/dist/prune.js.map +0 -1
@@ -1,2 +1,2 @@
1
- const e=require("../errors.cjs"),t=require("../ttl.cjs"),n=require("../internal.cjs"),r=require("../adapter-core.cjs");function i(e){return({db:t,tx:n})=>{for(let r of e)switch(r.type){case`addIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)||e.createIndex(r.field,`value.${r.field}`);break}case`addTable`:t.objectStoreNames.contains(r.name)||t.createObjectStore(r.name);break;case`removeIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)&&e.deleteIndex(r.field);break}case`removeTable`:t.objectStoreNames.contains(r.name)&&t.deleteObjectStore(r.name)}}}function a(t){return new Promise((n,r)=>{t.onsuccess=()=>n(t.result),t.onerror=()=>r(t.error??new e.VaultError(`IndexedDB request failed`))})}function o(t,n,r){let i=r instanceof Error&&r.message?`: ${r.message}`:``;return new e.VaultError(`${n} on "${t}"${i}`,{cause:r})}function s(e,t,n){return new Promise((r,i)=>{let a,s;Promise.resolve().then(n).then(e=>{a=e}).catch(t=>{s=t;try{e.abort()}catch{}});let c=(e,n=`transaction failed`)=>{s instanceof Error?i(s):i(o(t,n,s??e))};e.oncomplete=()=>{if(s){c(void 0);return}r(a)},e.onerror=()=>i(o(t,`transaction error`,e.error)),e.onabort=()=>c(e.error,`transaction aborted`)})}async function c(e,t){let n=await a(e.getAll()),r=[];for(let e of n){let n=t(e);n!==void 0&&r.push(n)}return r}async function l(e,t,n,r){let i=e.index(t),o=n.type===`eq`?IDBKeyRange.only(n.value):n.type===`between`?IDBKeyRange.bound(n.lower,n.upper):IDBKeyRange.bound(n.prefix,`${n.prefix}\uffff`),s=await a(i.getAll(o)),c=[];for(let e of s){let t=r(e);t!==void 0&&c.push(t)}return c}async function u(e,t,n){let r=await a(e.get(t));if(r!=null)return n(r)}async function d(e,t,n){return await u(e,t,n)!==void 0}async function f(e,t,n){let r=await d(e,t,n);return await a(e.delete(t)),r}async function p(e,t,n){return t.length===0?0:(await Promise.all(t.map(t=>f(e,t,n)))).filter(Boolean).length}async function m(e,t,n,r,i){await a(e.put(r(n,i),t))}function h(n){return new Promise((r,i)=>{let a=0,o=n.openCursor();o.onerror=()=>i(o.error??new e.VaultError(`IndexedDB cursor failed during prune`)),o.onsuccess=()=>{let e=o.result;if(!e){r(a);return}let n=t.parseStored(e.value);(!n||t.isExpired(n.expiresAt))&&(e.delete(),a+=1),e.continue()}})}function g(t,n){return{[Symbol.asyncIterator](){let r=t.openCursor(),i={type:`idle`},a=e=>{if(i.type===`waiting`){let{resolve:t}=i;i=e.done?{type:`done`}:{type:`idle`},t(e)}else i={result:e,type:`buffered`}};return r.onerror=()=>{let t=r.error??new e.VaultError(`IndexedDB cursor iteration failed`);if(i.type===`waiting`){let{reject:e}=i;i={type:`done`},e(t)}else i={error:t,type:`error`}},r.onsuccess=()=>{let e=r.result;if(!e){a({done:!0,value:void 0});return}let t=n(e.value);e.continue(),t!==void 0&&a({done:!1,value:t})},{next(){if(i.type===`error`){let{error:e}=i;return i={type:`done`},Promise.reject(e)}if(i.type===`buffered`){let{result:e}=i;return i=e.done?{type:`done`}:{type:`idle`},Promise.resolve(e)}return i.type===`done`?Promise.resolve({done:!0,value:void 0}):new Promise((e,t)=>{i={reject:t,resolve:e,type:`waiting`}})},return(e){return i.type===`waiting`&&i.resolve({done:!0,value:void 0}),i={type:`done`},Promise.resolve({done:!0,value:e})},throw(e){return i.type===`waiting`&&i.reject(e),i={type:`done`},Promise.reject(e)}}}}}function _(e,t,r,i){let o=e=>t.objectStore(e);return{clear:async e=>{await a(o(e).clear())},count:async e=>(await a(o(e).getAll())).filter(e=>r(e)!==void 0).length,delete:(e,t)=>f(o(e),n.encodeVaultKey(t),r),deleteMany:(e,t)=>p(o(e),t.map(n.encodeVaultKey),r),get:(e,t)=>u(o(e),n.encodeVaultKey(t),r),getAll:e=>c(o(e),r),getByIndexRange:(e,t,n)=>l(o(e),t,n,r),getMany:(e,t)=>Promise.all(t.map(t=>u(o(e),n.encodeVaultKey(t),r))),has:(e,t)=>d(o(e),n.encodeVaultKey(t),r),pruneExpiredInTable:e=>h(o(e)),put(t,r,a){return m(o(t),n.encodeVaultKey(n.getRecordKey(e,t,r)),r,i,a)},putAll(t,r,a){return Promise.all(r.map(r=>m(o(t),n.encodeVaultKey(n.getRecordKey(e,t,r)),r,i,a))).then(()=>void 0)}}}function v(i){let{logger:o,migrate:v,name:y,onMetrics:b,schema:x,validators:S,version:C=1}=i;if(!Number.isInteger(C)||C<1)throw new e.VaultError(`createIndexedDB: version must be a positive integer, got ${String(C)}`);let w=e=>{let n=t.parseStored(e);return!n||t.isExpired(n.expiresAt)?void 0:n.value},T=(e,t)=>t===void 0?{value:e}:{expiresAt:Date.now()+t,value:e},E=typeof BroadcastChannel<`u`?new BroadcastChannel(`vault:${y}`):void 0;!E&&o&&o.error(`[vault] BroadcastChannel unavailable — cross-tab sync disabled for "${y}"`);let D=null,O=null,k=!1,A=(e,t)=>{for(let[n,r]of Object.entries(x)){let i;i=e.objectStoreNames.contains(n)?t.objectStore(n):e.createObjectStore(n);let a=r.indexes??[];for(let e of a)i.indexNames.contains(e)||i.createIndex(e,`value.${e}`)}},j=async()=>(O||=new Promise((t,n)=>{let r=indexedDB.open(y,C);r.onupgradeneeded=t=>{let i=r.result,a=r.transaction;if(v)try{v({db:i,newVersion:t.newVersion??null,oldVersion:t.oldVersion,tx:a})}catch(t){try{a.abort()}catch{}n(new e.VaultMigrationError(`migration failed for "${y}"`,{cause:t}));return}A(i,a)},r.onsuccess=()=>{if(k){r.result.close(),t();return}let e=r.result;e.onversionchange=()=>{e.close(),D=null,O=null},D=e,t()},r.onerror=()=>{O=null,n(new e.VaultError(`failed to open "${y}"`,{cause:r.error}))}}),O),M=async(t,n,r)=>{if(k||(D||await j(),!D))throw new e.VaultDisposedError(`"${y}" is disposed`);let i=String(t),a=D.transaction(i,n);return s(a,`${y}/${i}`,()=>r(a.objectStore(i)))},N=async()=>{if(k||(D||await j(),!D))throw new e.VaultDisposedError(`"${y}" is disposed`);return D},P=e=>{E?.postMessage({table:String(e)})},F={clear:e=>M(e,`readwrite`,e=>a(e.clear()).then(()=>void 0)),count:e=>M(e,`readonly`,async e=>(await a(e.getAll())).filter(e=>w(e)!==void 0).length),delete:(e,t)=>M(e,`readwrite`,e=>f(e,n.encodeVaultKey(t),w)),deleteMany:(e,t)=>t.length===0?Promise.resolve(0):M(e,`readwrite`,e=>p(e,t.map(n.encodeVaultKey),w)),async dispose(){k=!0,E?.close(),O&&await O.catch(()=>{}),D?.close(),D=null,O=null},get:(e,t)=>M(e,`readonly`,e=>u(e,n.encodeVaultKey(t),w)),getAll:e=>M(e,`readonly`,e=>c(e,w)),getAllKeys:e=>M(e,`readonly`,async t=>{let n=await c(t,w),r=x[e].key;return n.map(e=>e[r])}),getByIndexRange:(e,t,n)=>M(e,`readonly`,e=>l(e,t,n,w)),getMany:(e,t)=>t.length===0?Promise.resolve([]):M(e,`readonly`,e=>Promise.all(t.map(t=>u(e,n.encodeVaultKey(t),w)))),getRawCount:e=>M(e,`readonly`,e=>a(e.count())),has:(e,t)=>M(e,`readonly`,e=>d(e,n.encodeVaultKey(t),w)),async pruneAllExpired(){let e=await N(),t=Object.keys(x),n=e.transaction(t,`readwrite`),r=await s(n,`${y}/pruneAll`,()=>Promise.all(t.map(async e=>[e,await h(n.objectStore(e))])));return Object.fromEntries(r)},pruneExpiredInTable:e=>M(e,`readwrite`,e=>h(e)),put(e,t,r){let i=n.encodeVaultKey(n.getRecordKey(x,e,t));return M(e,`readwrite`,e=>m(e,i,t,T,r))},putAll(e,t,r){return M(e,`readwrite`,i=>Promise.all(t.map(t=>m(i,n.encodeVaultKey(n.getRecordKey(x,e,t)),t,T,r))).then(()=>void 0))}},I=async(e,t,n,i)=>{r.assertBatchTables(e);let a=(await N()).transaction([...e],`readwrite`),o=new Set,c=_(x,a,w,T),l=new Set(e),u=r.buildTxContext(x,c,e=>o.add(e),i,l),d=await s(a,y,()=>t(u));for(let e of o)n(e);return d},L,R={...r.buildAdapterOps(x,F,{logger:o,onCrossTabMessage(e){if(E)return E.onmessage=t=>{let n=t.data?.table;!n||!Object.hasOwn(x,n)||e(n)},()=>{E.onmessage=null}},onMetrics:b,onMutation:P,onTransactions:e=>{L=(t,n)=>I(t,n,e.notifyMutation,e.validate)},schema:x,validators:S}),iterate(t){if(k)throw new e.VaultDisposedError(`"${y}" is disposed`);let n=async()=>{if(D||await j(),!D||k)throw new e.VaultDisposedError(`"${y}" is disposed`);return g(D.transaction(String(t),`readonly`).objectStore(String(t)),w)},r,i=()=>n().then(e=>(r=e[Symbol.asyncIterator](),r));return{[Symbol.asyncIterator](){return{next(){return r?r.next():i().then(e=>e.next())},return(e){return r?r.return?.(e)??Promise.resolve({done:!0,value:e}):Promise.resolve({done:!0,value:e})},throw(e){return r?r.throw?.(e)??Promise.reject(e):Promise.reject(e)}}}}}};if(!L)throw new e.VaultError(`IndexedDB transaction capability was not initialized`);return r.withIndexedDbTransactions(R,L)}exports.createIndexedDB=v,exports.defineMigration=i;
1
+ const e=require("../errors.cjs"),t=require("../ttl.cjs"),n=require("../internal.cjs"),r=require("../adapter-core.cjs");function i(e){return({db:t,tx:n})=>{for(let r of e)switch(r.type){case`addIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)||e.createIndex(r.field,`value.${r.field}`);break}case`addTable`:t.objectStoreNames.contains(r.name)||t.createObjectStore(r.name);break;case`removeIndex`:{let e=n.objectStore(r.table);e.indexNames.contains(r.field)&&e.deleteIndex(r.field);break}case`removeTable`:t.objectStoreNames.contains(r.name)&&t.deleteObjectStore(r.name)}}}function a(t){return new Promise((n,r)=>{t.onsuccess=()=>n(t.result),t.onerror=()=>r(t.error??new e.VaultError(`IndexedDB request failed`))})}function o(t,n,r){let i=r instanceof Error&&r.message?`: ${r.message}`:``;return new e.VaultError(`${n} on "${t}"${i}`,{cause:r})}function s(e,t,n){return new Promise((r,i)=>{let a,s;Promise.resolve().then(n).then(e=>{a=e}).catch(t=>{s=t;try{e.abort()}catch{}});let c=(e,n=`transaction failed`)=>{s instanceof Error?i(s):i(o(t,n,s??e))};e.oncomplete=()=>{if(s){c(void 0);return}r(a)},e.onerror=()=>i(o(t,`transaction error`,e.error)),e.onabort=()=>c(e.error,`transaction aborted`)})}async function c(e,t){let n=await a(e.getAll()),r=[];for(let e of n){let n=t(e);n!==void 0&&r.push(n)}return r}async function l(e,t,n){let r=await a(e.get(t));if(r!=null)return n(r)}async function u(e,t,n){return await l(e,t,n)!==void 0}async function d(e,t,n){let r=await u(e,t,n);return await a(e.delete(t)),r}async function f(e,t,n){return t.length===0?0:(await Promise.all(t.map(t=>d(e,t,n)))).filter(Boolean).length}async function p(e,t,n,r,i){await a(e.put(r(n,i),t))}function m(n){return new Promise((r,i)=>{let a=0,o=n.openCursor();o.onerror=()=>i(o.error??new e.VaultError(`IndexedDB cursor failed during prune`)),o.onsuccess=()=>{let e=o.result;if(!e){r(a);return}let n=t.parseStored(e.value);(!n||t.isExpired(n.expiresAt))&&(e.delete(),a+=1),e.continue()}})}function h(t,n){return{[Symbol.asyncIterator](){let r=t.openCursor(),i={type:`idle`},a=e=>{if(i.type===`waiting`){let{resolve:t}=i;i=e.done?{type:`done`}:{type:`idle`},t(e)}else i={result:e,type:`buffered`}};return r.onerror=()=>{let t=r.error??new e.VaultError(`IndexedDB cursor iteration failed`);if(i.type===`waiting`){let{reject:e}=i;i={type:`done`},e(t)}else i={error:t,type:`error`}},r.onsuccess=()=>{let e=r.result;if(!e){a({done:!0,value:void 0});return}let t=n(e.value);e.continue(),t!==void 0&&a({done:!1,value:t})},{next(){if(i.type===`error`){let{error:e}=i;return i={type:`done`},Promise.reject(e)}if(i.type===`buffered`){let{result:e}=i;return i=e.done?{type:`done`}:{type:`idle`},Promise.resolve(e)}return i.type===`done`?Promise.resolve({done:!0,value:void 0}):new Promise((e,t)=>{i={reject:t,resolve:e,type:`waiting`}})},return(e){return i.type===`waiting`&&i.resolve({done:!0,value:void 0}),i={type:`done`},Promise.resolve({done:!0,value:e})},throw(e){return i.type===`waiting`&&i.reject(e),i={type:`done`},Promise.reject(e)}}}}}function g(e,t,r,i){let o=e=>t.objectStore(e);return{clear:async e=>{await a(o(e).clear())},count:async e=>(await a(o(e).getAll())).filter(e=>r(e)!==void 0).length,delete:(e,t)=>d(o(e),n.encodeVaultKey(t),r),deleteMany:(e,t)=>f(o(e),t.map(n.encodeVaultKey),r),get:(e,t)=>l(o(e),n.encodeVaultKey(t),r),getAll:e=>c(o(e),r),getMany:(e,t)=>Promise.all(t.map(t=>l(o(e),n.encodeVaultKey(t),r))),has:(e,t)=>u(o(e),n.encodeVaultKey(t),r),pruneExpiredInTable:e=>m(o(e)),put(t,r,a){return p(o(t),n.encodeVaultKey(n.getRecordKey(e,t,r)),r,i,a)},putAll(t,r,a){return Promise.all(r.map(r=>p(o(t),n.encodeVaultKey(n.getRecordKey(e,t,r)),r,i,a))).then(()=>void 0)}}}function _(i){let{migrate:o,name:_,schema:v,validators:y,version:b=1}=i;if(!Number.isInteger(b)||b<1)throw new e.VaultError(`createIndexedDB: version must be a positive integer, got ${String(b)}`);let x=e=>{let n=t.parseStored(e);return!n||t.isExpired(n.expiresAt)?void 0:n.value},S=(e,t)=>t===void 0?{value:e}:{expiresAt:Date.now()+t,value:e},C=typeof BroadcastChannel<`u`?new BroadcastChannel(`vault:${_}`):void 0,w=null,T=null,E=!1,D=(e,t)=>{for(let[n,r]of Object.entries(v)){let i;i=e.objectStoreNames.contains(n)?t.objectStore(n):e.createObjectStore(n);let a=r.indexes??[];for(let e of a)i.indexNames.contains(e)||i.createIndex(e,`value.${e}`)}},O=async()=>(T||=new Promise((t,n)=>{let r=indexedDB.open(_,b);r.onupgradeneeded=t=>{let i=r.result,a=r.transaction;if(o)try{o({db:i,newVersion:t.newVersion??null,oldVersion:t.oldVersion,tx:a})}catch(t){try{a.abort()}catch{}n(new e.VaultMigrationError(`migration failed for "${_}"`,{cause:t}));return}D(i,a)},r.onsuccess=()=>{if(E){r.result.close(),t();return}let e=r.result;e.onversionchange=()=>{e.close(),w=null,T=null},w=e,t()},r.onerror=()=>{T=null,n(new e.VaultError(`failed to open "${_}"`,{cause:r.error}))}}),T),k=async(t,n,r)=>{if(E||(w||await O(),!w))throw new e.VaultDisposedError(`"${_}" is disposed`);let i=String(t),a=w.transaction(i,n);return s(a,`${_}/${i}`,()=>r(a.objectStore(i)))},A=async()=>{if(E||(w||await O(),!w))throw new e.VaultDisposedError(`"${_}" is disposed`);return w},j=e=>{C?.postMessage({table:String(e)})},M={clear:e=>k(e,`readwrite`,e=>a(e.clear()).then(()=>void 0)),count:e=>k(e,`readonly`,async e=>(await a(e.getAll())).filter(e=>x(e)!==void 0).length),delete:(e,t)=>k(e,`readwrite`,e=>d(e,n.encodeVaultKey(t),x)),deleteMany:(e,t)=>t.length===0?Promise.resolve(0):k(e,`readwrite`,e=>f(e,t.map(n.encodeVaultKey),x)),async dispose(){E=!0,C?.close(),T&&await T.catch(()=>{}),w?.close(),w=null,T=null},get:(e,t)=>k(e,`readonly`,e=>l(e,n.encodeVaultKey(t),x)),getAll:e=>k(e,`readonly`,e=>c(e,x)),getAllKeys:e=>k(e,`readonly`,async t=>{let n=await c(t,x),r=v[e].key;return n.map(e=>e[r])}),getMany:(e,t)=>t.length===0?Promise.resolve([]):k(e,`readonly`,e=>Promise.all(t.map(t=>l(e,n.encodeVaultKey(t),x)))),has:(e,t)=>k(e,`readonly`,e=>u(e,n.encodeVaultKey(t),x)),async pruneAllExpired(){let e=await A(),t=Object.keys(v),n=e.transaction(t,`readwrite`),r=await s(n,`${_}/pruneAll`,()=>Promise.all(t.map(async e=>[e,await m(n.objectStore(e))])));return Object.fromEntries(r)},pruneExpiredInTable:e=>k(e,`readwrite`,e=>m(e)),put(e,t,r){let i=n.encodeVaultKey(n.getRecordKey(v,e,t));return k(e,`readwrite`,e=>p(e,i,t,S,r))},putAll(e,t,r){return k(e,`readwrite`,i=>Promise.all(t.map(t=>p(i,n.encodeVaultKey(n.getRecordKey(v,e,t)),t,S,r))).then(()=>void 0))}},N=async(e,t,n,i)=>{r.assertBatchTables(e);let a=(await A()).transaction([...e],`readwrite`),o=new Set,c=g(v,a,x,S),l=new Set(e),u=r.buildTxContext(v,c,e=>o.add(e),i,l),d=await s(a,_,()=>t(u));for(let e of o)n(e);return d},P,F=r.buildAdapterOps(v,M,{onCrossTabMessage(e){if(C)return C.onmessage=t=>{let n=t.data?.table;!n||!Object.hasOwn(v,n)||e(n)},()=>{C.onmessage=null}},onMutation:j,onTransactions:e=>{P=(t,n)=>N(t,n,e.notifyMutation,e.validate)},schema:v,validators:y}),I={...F,get disposalSignal(){return F.disposalSignal},get disposed(){return F.disposed},iterate(t){if(E)throw new e.VaultDisposedError(`"${_}" is disposed`);let n=async()=>{if(w||await O(),!w||E)throw new e.VaultDisposedError(`"${_}" is disposed`);return h(w.transaction(String(t),`readonly`).objectStore(String(t)),x)},r,i=()=>n().then(e=>(r=e[Symbol.asyncIterator](),r));return{[Symbol.asyncIterator](){return{next(){return r?r.next():i().then(e=>e.next())},return(e){return r?r.return?.(e)??Promise.resolve({done:!0,value:e}):Promise.resolve({done:!0,value:e})},throw(e){return r?r.throw?.(e)??Promise.reject(e):Promise.reject(e)}}}}}};if(!P)throw new e.VaultError(`IndexedDB transaction capability was not initialized`);return r.withIndexedDbTransactions(I,P)}exports.createIndexedDB=_,exports.defineMigration=i;
2
2
  //# sourceMappingURL=indexeddb.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexeddb.cjs","names":[],"sources":["../../src/adapters/indexeddb.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport {\n assertBatchTables,\n type BatchImpl,\n buildAdapterOps,\n buildTxContext,\n type StorageBackend,\n withIndexedDbTransactions,\n} from '../adapter-core';\nimport { VaultDisposedError, VaultError, VaultMigrationError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport type { NativeRange } from '../query';\nimport { isExpired, parseStored, type StoredRecord } from '../ttl';\nimport type { AnySchema, BaseAdapterOptions, IndexedDbVaultStore, KeyOf, RecordOf, TransactionContext } from '../types';\n\nexport type { IndexedDbVaultStore };\n\n/** IndexedDB-only migration context supplied to `MigrationFn` during `onupgradeneeded`. */\nexport type MigrationContext = {\n db: IDBDatabase;\n newVersion: number | null;\n oldVersion: number;\n tx: IDBTransaction;\n};\n\n/** Synchronous IndexedDB schema upgrade callback. */\nexport type MigrationFn = (ctx: MigrationContext) => void;\n\n/**\n * A single step in a typed migration definition.\n * Compose multiple steps to describe the full schema change between two versions.\n */\nexport type MigrationStep =\n | { field: string; table: string; type: 'addIndex' }\n | { field: string; table: string; type: 'removeIndex' }\n | { name: string; type: 'addTable' }\n | { name: string; type: 'removeTable' };\n\n/**\n * Builds a typed `MigrationFn` from a declarative list of schema change steps.\n * Each step is applied in order and is idempotent (safe to run when the target\n * already exists or has already been removed).\n *\n * ```ts\n * const migrate = defineMigration([\n * { type: 'addTable', name: 'sessions' },\n * { type: 'addIndex', table: 'users', field: 'email' },\n * { type: 'removeTable', name: 'legacyTokens' },\n * ]);\n *\n * const db = createIndexedDB({ name: 'app', version: 2, schema, migrate });\n * ```\n */\nexport function defineMigration(steps: MigrationStep[]): MigrationFn {\n return ({ db, tx }) => {\n for (const step of steps) {\n switch (step.type) {\n case 'addIndex': {\n const store = tx.objectStore(step.table);\n\n // keyPath mirrors the vault storage envelope: { value: T, expiresAt?: number }\n if (!store.indexNames.contains(step.field)) {\n store.createIndex(step.field, `value.${step.field}`);\n }\n\n break;\n }\n case 'addTable':\n if (!db.objectStoreNames.contains(step.name)) {\n db.createObjectStore(step.name);\n }\n\n break;\n case 'removeIndex': {\n const store = tx.objectStore(step.table);\n\n if (store.indexNames.contains(step.field)) {\n store.deleteIndex(step.field);\n }\n\n break;\n }\n case 'removeTable':\n if (db.objectStoreNames.contains(step.name)) {\n db.deleteObjectStore(step.name);\n }\n\n break;\n }\n }\n };\n}\n\nfunction idbReq<R>(request: IDBRequest<R>): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new VaultError('IndexedDB request failed'));\n });\n}\n\nfunction wrapTxError(scope: string, message: string, cause: unknown): VaultError {\n const causeMessage = cause instanceof Error && cause.message ? `: ${cause.message}` : '';\n\n return new VaultError(`${message} on \"${scope}\"${causeMessage}`, { cause });\n}\n\nfunction runIdbTx<T>(tx: IDBTransaction, scope: string, work: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let result: T | undefined;\n let callbackError: unknown;\n\n Promise.resolve()\n .then(work)\n .then((value) => {\n result = value;\n })\n .catch((error) => {\n callbackError = error;\n\n try {\n tx.abort();\n } catch {\n /* ignore */\n }\n });\n\n const rejectWithCallbackError = (fallbackCause: unknown, message = 'transaction failed'): void => {\n if (callbackError instanceof Error) {\n reject(callbackError);\n } else {\n reject(wrapTxError(scope, message, callbackError ?? fallbackCause));\n }\n };\n\n tx.oncomplete = () => {\n if (callbackError) {\n rejectWithCallbackError(undefined);\n\n return;\n }\n\n resolve(result as T);\n };\n tx.onerror = () => reject(wrapTxError(scope, 'transaction error', tx.error));\n tx.onabort = () => rejectWithCallbackError(tx.error, 'transaction aborted');\n });\n}\n\nasync function getAllFromStore<T extends object>(\n store: IDBObjectStore,\n decode: (raw: unknown) => T | undefined,\n): Promise<T[]> {\n const rawRecords = await idbReq<unknown[]>(store.getAll());\n const records: T[] = [];\n\n for (const raw of rawRecords) {\n const value = decode(raw);\n\n if (value !== undefined) records.push(value);\n }\n\n return records;\n}\n\nasync function getAllFromStoreByIndex<T extends object>(\n store: IDBObjectStore,\n indexName: string,\n range: NativeRange,\n decode: (raw: unknown) => T | undefined,\n): Promise<T[]> {\n const index = store.index(indexName);\n const idbRange =\n range.type === 'eq'\n ? IDBKeyRange.only(range.value as IDBValidKey)\n : range.type === 'between'\n ? IDBKeyRange.bound(range.lower as IDBValidKey, range.upper as IDBValidKey)\n : IDBKeyRange.bound(range.prefix, `${range.prefix}\\uffff`);\n const rawRecords = await idbReq<unknown[]>(index.getAll(idbRange));\n const records: T[] = [];\n\n for (const raw of rawRecords) {\n const value = decode(raw);\n\n if (value !== undefined) records.push(value);\n }\n\n return records;\n}\n\nasync function storeGet<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<T | undefined> {\n const raw = await idbReq<unknown>(store.get(key));\n\n if (raw == null) return undefined;\n\n return decode(raw);\n}\n\nasync function storeHas<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<boolean> {\n return (await storeGet<T>(store, key, decode)) !== undefined;\n}\n\nasync function storeDelete<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<boolean> {\n const live = await storeHas<T>(store, key, decode);\n\n await idbReq(store.delete(key));\n\n return live;\n}\n\nasync function storeDeleteMany<T extends object>(\n store: IDBObjectStore,\n keys: IDBValidKey[],\n decode: (raw: unknown) => T | undefined,\n): Promise<number> {\n if (keys.length === 0) return 0;\n\n const results = await Promise.all(keys.map((k) => storeDelete<T>(store, k, decode)));\n\n return results.filter(Boolean).length;\n}\n\nasync function storePutAt<T>(\n store: IDBObjectStore,\n key: IDBValidKey,\n value: T,\n encode: (v: T, ttl?: number) => unknown,\n ttl?: number,\n): Promise<void> {\n await idbReq(store.put(encode(value, ttl), key));\n}\n\nfunction pruneExpiredInStore(store: IDBObjectStore): Promise<number> {\n return new Promise<number>((resolve, reject) => {\n let deleted = 0;\n const request = store.openCursor();\n\n request.onerror = () => reject(request.error ?? new VaultError('IndexedDB cursor failed during prune'));\n request.onsuccess = () => {\n const cursor = request.result;\n\n if (!cursor) {\n resolve(deleted);\n\n return;\n }\n\n const stored = parseStored(cursor.value as unknown);\n\n if (!stored || isExpired(stored.expiresAt)) {\n cursor.delete();\n deleted += 1;\n }\n\n cursor.continue();\n };\n });\n}\n\n/**\n * Cursor state machine — a single discriminated union replaces five boolean/nullable variables.\n * Transitions: idle → waiting (next() before cursor fires) | buffered (cursor fires first) | done | error\n */\ntype CursorState<T> =\n | { type: 'idle' }\n | { reject: (e: unknown) => void; resolve: (r: IteratorResult<T>) => void; type: 'waiting' }\n | { result: IteratorResult<T>; type: 'buffered' }\n | { error: unknown; type: 'error' }\n | { type: 'done' };\n\n/**\n * F1: True cursor-based iteration for IndexedDB.\n * Yields live records one-by-one using an IDB cursor, avoiding materializing the full table.\n * This is memory-efficient for large tables — the cursor walks the store incrementally.\n *\n * Design: the cursor is opened *synchronously* in [Symbol.asyncIterator]() so that event\n * handlers are wired immediately (no queueMicrotask races). The cursor is advanced *eagerly*\n * before yielding — this keeps the IDB readonly transaction alive between consumer awaits,\n * because IDB auto-commits when there are no pending requests.\n */\nfunction iterateStoreWithCursor<T extends object>(\n store: IDBObjectStore,\n decode: (raw: unknown) => T | undefined,\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n const cursorRequest = store.openCursor();\n let state: CursorState<T> = { type: 'idle' };\n\n const deliver = (result: IteratorResult<T>): void => {\n if (state.type === 'waiting') {\n const { resolve } = state;\n\n state = result.done ? { type: 'done' } : { type: 'idle' };\n resolve(result);\n } else {\n state = { result, type: 'buffered' };\n }\n };\n\n cursorRequest.onerror = () => {\n const err = cursorRequest.error ?? new VaultError('IndexedDB cursor iteration failed');\n\n if (state.type === 'waiting') {\n const { reject } = state;\n\n state = { type: 'done' };\n reject(err);\n } else {\n state = { error: err, type: 'error' };\n }\n };\n\n cursorRequest.onsuccess = () => {\n const cursor = cursorRequest.result;\n\n if (!cursor) {\n deliver({ done: true, value: undefined });\n\n return;\n }\n\n const value = decode(cursor.value as unknown);\n\n // Advance eagerly BEFORE yielding to keep the IDB transaction alive.\n cursor.continue();\n\n if (value !== undefined) deliver({ done: false, value });\n };\n\n return {\n next(): Promise<IteratorResult<T>> {\n if (state.type === 'error') {\n const { error } = state;\n\n state = { type: 'done' };\n\n return Promise.reject(error);\n }\n\n if (state.type === 'buffered') {\n const { result } = state;\n\n state = result.done ? { type: 'done' } : { type: 'idle' };\n\n return Promise.resolve(result);\n }\n\n if (state.type === 'done') return Promise.resolve({ done: true, value: undefined });\n\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n state = { reject, resolve, type: 'waiting' };\n });\n },\n\n return(value?: unknown): Promise<IteratorResult<T>> {\n if (state.type === 'waiting') state.resolve({ done: true, value: undefined });\n\n state = { type: 'done' };\n\n return Promise.resolve({ done: true, value });\n },\n\n throw(err?: unknown): Promise<IteratorResult<T>> {\n if (state.type === 'waiting') state.reject(err);\n\n state = { type: 'done' };\n\n return Promise.reject(err);\n },\n };\n },\n };\n}\n\n/**\n * R3: Extracted IDB batch core — builds a StorageBackend that operates within\n * an existing IDBTransaction, shared by all tables in the batch.\n * Eliminates the duplicated `txCore` block that was previously inlined in `idbBatch`.\n */\nfunction buildIdbBatchCore<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n idbTx: IDBTransaction,\n decode: <T extends object>(raw: unknown) => T | undefined,\n encode: <T>(value: T, ttl?: number) => unknown,\n): StorageBackend<S, K> {\n const storeOf = (table: K): IDBObjectStore => idbTx.objectStore(table);\n\n return {\n clear: async (table) => {\n await idbReq(storeOf(table).clear());\n },\n count: async (table) => {\n // Must inspect each stored record to exclude TTL-expired entries.\n // Individual put() calls can attach a TTL even when the schema has no defaultTtl,\n // so schema[table].defaultTtl being absent does not guarantee a clean count.\n // This matches the top-level core.count() behaviour in the IDB adapter.\n const all = await idbReq<unknown[]>(storeOf(table).getAll());\n\n return all.filter((r) => decode(r) !== undefined).length;\n },\n delete: (table, key) => storeDelete<RecordOf<S, K>>(storeOf(table), encodeVaultKey(key), decode),\n deleteMany: (table, keys) => storeDeleteMany<RecordOf<S, K>>(storeOf(table), keys.map(encodeVaultKey), decode),\n get: (table, key) => storeGet<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode),\n getAll: (table) => getAllFromStore<RecordOf<S, typeof table>>(storeOf(table), decode),\n getByIndexRange: (table, field, range) =>\n getAllFromStoreByIndex<RecordOf<S, typeof table>>(storeOf(table), field, range, decode),\n getMany: (table, keys) =>\n Promise.all(keys.map((key) => storeGet<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode))),\n has: (table, key) => storeHas<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode),\n pruneExpiredInTable: (table) => pruneExpiredInStore(storeOf(table)),\n put(table, value, ttl) {\n return storePutAt(storeOf(table), encodeVaultKey(getRecordKey(schema, table, value)), value, encode, ttl);\n },\n putAll(table, values, ttl) {\n return Promise.all(\n values.map((v) => storePutAt(storeOf(table), encodeVaultKey(getRecordKey(schema, table, v)), v, encode, ttl)),\n ).then(() => undefined);\n },\n };\n}\n\ntype IndexedDbOptions<S extends AnySchema> = BaseAdapterOptions<S> & {\n migrate?: MigrationFn;\n name: string;\n /** Schema version. Must be a positive integer. Increment when adding tables or changing the schema, then provide `migrate`. Defaults to 1. */\n version?: number;\n};\n\nexport function createIndexedDB<S extends AnySchema>(options: IndexedDbOptions<S>): IndexedDbVaultStore<S> {\n const { logger, migrate, name, onMetrics, schema, validators, version = 1 } = options;\n\n if (!Number.isInteger(version) || version < 1) {\n throw new VaultError(`createIndexedDB: version must be a positive integer, got ${String(version)}`);\n }\n\n // Fixed envelopes keep IndexedDB records and `value.<field>` indexes portable across adapters.\n const decode = <T extends object>(raw: unknown): T | undefined => {\n const stored = parseStored<T>(raw);\n\n return !stored || isExpired(stored.expiresAt) ? undefined : stored.value;\n };\n\n const encode = <T>(value: T, ttl?: number): StoredRecord<T> => {\n return ttl === undefined ? { value } : { expiresAt: Date.now() + ttl, value };\n };\n\n const channel = typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(`vault:${name}`) : undefined;\n\n if (!channel && logger) {\n logger.error(`[vault] BroadcastChannel unavailable — cross-tab sync disabled for \"${name}\"`);\n }\n\n let db: IDBDatabase | null = null;\n let connectPromise: Promise<void> | null = null;\n let disposed = false;\n\n const createObjectStores = (target: IDBDatabase, tx: IDBTransaction): void => {\n for (const [tableName, entry] of Object.entries(schema)) {\n let store: IDBObjectStore;\n\n if (!target.objectStoreNames.contains(tableName)) {\n store = target.createObjectStore(tableName);\n } else {\n store = tx.objectStore(tableName);\n }\n\n // F5: Create secondary indexes for fields declared via .index() on the table() builder.\n // Stored format is { value: T, expiresAt?: number } so IDB keyPath is `value.<field>`.\n const indexes = (entry as { indexes?: readonly string[] }).indexes ?? [];\n\n for (const field of indexes) {\n if (!store.indexNames.contains(field)) {\n store.createIndex(field, `value.${field}`);\n }\n }\n }\n };\n\n const connect = async (): Promise<void> => {\n if (!connectPromise) {\n connectPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onupgradeneeded = (event) => {\n const target = request.result;\n const tx = request.transaction!;\n\n if (migrate) {\n try {\n migrate({\n db: target,\n newVersion: (event as IDBVersionChangeEvent).newVersion ?? null,\n oldVersion: event.oldVersion,\n tx,\n });\n } catch (error) {\n try {\n tx.abort();\n } catch {\n /* ignore */\n }\n\n reject(new VaultMigrationError(`migration failed for \"${name}\"`, { cause: error }));\n\n return;\n }\n }\n\n createObjectStores(target, tx);\n };\n\n request.onsuccess = () => {\n if (disposed) {\n request.result.close();\n resolve();\n\n return;\n }\n\n const connection = request.result;\n\n connection.onversionchange = () => {\n connection.close();\n db = null;\n connectPromise = null;\n };\n\n db = connection;\n resolve();\n };\n request.onerror = () => {\n connectPromise = null;\n reject(new VaultError(`failed to open \"${name}\"`, { cause: request.error }));\n };\n });\n }\n\n return connectPromise;\n };\n\n const withStore = async <T>(\n table: keyof S,\n mode: 'readonly' | 'readwrite',\n fn: (store: IDBObjectStore) => Promise<T>,\n ): Promise<T> => {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (!db) await connect();\n\n if (!db) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n const tableName = String(table);\n const tx = db.transaction(tableName, mode);\n\n return runIdbTx(tx, `${name}/${tableName}`, () => fn(tx.objectStore(tableName)));\n };\n\n const requireDb = async (): Promise<IDBDatabase> => {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (!db) await connect();\n\n if (!db) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return db;\n };\n\n const publish = <K extends keyof S>(table: K): void => {\n channel?.postMessage({ table: String(table) });\n };\n\n const core: StorageBackend<S> = {\n clear: (table) => withStore(table, 'readwrite', (s) => idbReq(s.clear()).then(() => undefined)),\n\n count: (table) =>\n withStore(table, 'readonly', async (s) => {\n // Must inspect each stored record to exclude TTL-expired entries.\n // Individual put() calls can attach a TTL even when the schema has no defaultTtl,\n // so schema[table].defaultTtl being absent does not guarantee a clean count.\n const all = await idbReq<unknown[]>(s.getAll());\n\n return all.filter((r) => decode(r) !== undefined).length;\n }),\n\n delete: (table, key) =>\n withStore(table, 'readwrite', (s) => storeDelete<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n deleteMany: (table, keys) =>\n keys.length === 0\n ? Promise.resolve(0)\n : withStore(table, 'readwrite', (s) =>\n storeDeleteMany<RecordOf<S, typeof table>>(s, keys.map(encodeVaultKey), decode),\n ),\n\n async dispose(): Promise<void> {\n disposed = true;\n channel?.close();\n\n // F7: Wait for any in-progress connect before closing the DB to avoid\n // \"database connection is closing\" errors on in-flight requests.\n if (connectPromise) await connectPromise.catch(() => {});\n\n db?.close();\n db = null;\n connectPromise = null;\n },\n\n get: (table, key) =>\n withStore(table, 'readonly', (s) => storeGet<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n getAll: (table) => withStore(table, 'readonly', (s) => getAllFromStore<RecordOf<S, typeof table>>(s, decode)),\n\n // Ad-hoc per-put TTLs can be attached regardless of schema-level defaultTtl (same caveat as\n // count()), so we cannot take the O(1) store.getAllKeys() shortcut unconditionally — every\n // record must be decoded to exclude TTL-expired entries correctly.\n getAllKeys: (table) =>\n withStore(table, 'readonly', async (s) => {\n const records = await getAllFromStore<RecordOf<S, typeof table>>(s, decode);\n const keyField = schema[table].key;\n\n return records.map((r) => (r as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n }),\n\n getByIndexRange: (table, field, range) =>\n withStore(table, 'readonly', (s) => getAllFromStoreByIndex<RecordOf<S, typeof table>>(s, field, range, decode)),\n\n getMany: (table, keys) =>\n keys.length === 0\n ? Promise.resolve([])\n : withStore(table, 'readonly', (s) =>\n Promise.all(keys.map((key) => storeGet<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode))),\n ),\n\n getRawCount: (table) => withStore(table, 'readonly', (s) => idbReq(s.count())),\n\n has: (table, key) =>\n withStore(table, 'readonly', (s) => storeHas<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n async pruneAllExpired() {\n const idb = await requireDb();\n const tableNames = Object.keys(schema);\n const tx = idb.transaction(tableNames, 'readwrite');\n const results = await runIdbTx(tx, `${name}/pruneAll`, () =>\n Promise.all(tableNames.map(async (t) => [t, await pruneExpiredInStore(tx.objectStore(t))] as const)),\n );\n\n return Object.fromEntries(results);\n },\n\n pruneExpiredInTable: (table) => withStore(table, 'readwrite', (s) => pruneExpiredInStore(s)),\n\n put(table, value, ttl) {\n const key = encodeVaultKey(getRecordKey(schema, table, value));\n\n return withStore(table, 'readwrite', (s) => storePutAt(s, key, value, encode, ttl));\n },\n\n putAll(table, values, ttl) {\n return withStore(table, 'readwrite', (s) =>\n Promise.all(\n values.map((v) => storePutAt(s, encodeVaultKey(getRecordKey(schema, table, v)), v, encode, ttl)),\n ).then(() => undefined),\n );\n },\n };\n\n const idbBatch = async <K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n notifyMutation: (table: K) => void,\n validateFn: <T extends K>(table: T, value: RecordOf<S, T>) => RecordOf<S, T>,\n ): Promise<R> => {\n assertBatchTables(tables);\n\n const idb = await requireDb();\n const idbTx = idb.transaction([...tables] as string[], 'readwrite');\n const dirtyTables = new Set<K>();\n\n const txCore = buildIdbBatchCore<S, K>(schema, idbTx, decode, encode);\n const scope = new Set<string>(tables);\n const tx = buildTxContext<S, K>(schema, txCore, (t) => dirtyTables.add(t), validateFn, scope);\n const result = await runIdbTx(idbTx, name, () => fn(tx));\n\n for (const table of dirtyTables) {\n notifyMutation(table);\n }\n\n return result;\n };\n\n let batch: BatchImpl<S> | undefined;\n const adapter = buildAdapterOps(schema, core, {\n logger,\n onCrossTabMessage(notify) {\n if (!channel) {\n return undefined;\n }\n\n channel.onmessage = (event: MessageEvent<{ table?: string }>) => {\n const tableName = event.data?.table;\n\n if (!tableName || !Object.hasOwn(schema, tableName)) return;\n\n notify(tableName as keyof S & string);\n };\n\n return () => {\n channel.onmessage = null;\n };\n },\n onMetrics,\n onMutation: publish,\n onTransactions: (deps) => {\n batch = (tables, fn) => idbBatch(tables, fn, deps.notifyMutation, deps.validate);\n },\n schema,\n validators,\n });\n\n /**\n * F1: Attach cursor-based `iterate()` on top of the adapter.\n * Opens a dedicated readonly transaction per call and streams records via IDB cursor —\n * genuinely memory-efficient for large tables unlike the getAll()-then-yield pattern.\n */\n const store = {\n ...adapter,\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n // Each call opens a fresh transaction so iteration doesn't hold locks across awaits.\n // We need to ensure the DB is connected before opening the transaction.\n const getIterable = async (): Promise<AsyncIterable<RecordOf<S, K>>> => {\n if (!db) await connect();\n\n if (!db || disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n const idb = db;\n const tx = idb.transaction(String(table), 'readonly');\n const store = tx.objectStore(String(table));\n\n return iterateStoreWithCursor<RecordOf<S, K>>(store, decode as (raw: unknown) => RecordOf<S, K> | undefined);\n };\n\n let inner: AsyncIterator<RecordOf<S, K>> | undefined;\n\n const initInner = (): Promise<AsyncIterator<RecordOf<S, K>>> =>\n getIterable().then((iterable) => {\n inner = iterable[Symbol.asyncIterator]();\n\n return inner;\n });\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n return {\n next(): Promise<IteratorResult<RecordOf<S, K>>> {\n // Sync check avoids an extra Promise allocation on every iteration after the first.\n if (inner) return inner.next();\n\n return initInner().then((it) => it.next());\n },\n return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n if (inner) return inner.return?.(value) ?? Promise.resolve({ done: true, value });\n\n return Promise.resolve({ done: true, value });\n },\n throw(err?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n if (inner) return inner.throw?.(err) ?? Promise.reject(err);\n\n return Promise.reject(err);\n },\n };\n },\n };\n },\n };\n\n if (!batch) throw new VaultError('IndexedDB transaction capability was not initialized');\n\n return withIndexedDbTransactions(store, batch);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"indexeddb.cjs","names":[],"sources":["../../src/adapters/indexeddb.ts"],"sourcesContent":["/// <reference lib=\"dom\" />\n\nimport {\n assertBatchTables,\n type BatchImpl,\n buildAdapterOps,\n buildTxContext,\n type StorageBackend,\n withIndexedDbTransactions,\n} from '../adapter-core';\nimport { VaultDisposedError, VaultError, VaultMigrationError } from '../errors';\nimport { encodeVaultKey, getRecordKey } from '../internal';\nimport { isExpired, parseStored, type StoredRecord } from '../ttl';\nimport type {\n AnySchema,\n BaseAdapterOptions,\n KeyOf,\n RecordOf,\n TransactionalVaultStore,\n TransactionContext,\n} from '../types';\n\nexport type { TransactionalVaultStore as IndexedDbVaultStore };\n\n/** IndexedDB-only migration context supplied to `MigrationFn` during `onupgradeneeded`. */\nexport type MigrationContext = {\n db: IDBDatabase;\n newVersion: number | null;\n oldVersion: number;\n tx: IDBTransaction;\n};\n\n/** Synchronous IndexedDB schema upgrade callback. */\nexport type MigrationFn = (ctx: MigrationContext) => void;\n\n/**\n * A single step in a typed migration definition.\n * Compose multiple steps to describe the full schema change between two versions.\n */\nexport type MigrationStep =\n | { field: string; table: string; type: 'addIndex' }\n | { field: string; table: string; type: 'removeIndex' }\n | { name: string; type: 'addTable' }\n | { name: string; type: 'removeTable' };\n\n/**\n * Builds a typed `MigrationFn` from a declarative list of schema change steps.\n * Each step is applied in order and is idempotent (safe to run when the target\n * already exists or has already been removed).\n *\n * ```ts\n * const migrate = defineMigration([\n * { type: 'addTable', name: 'sessions' },\n * { type: 'addIndex', table: 'users', field: 'email' },\n * { type: 'removeTable', name: 'legacyTokens' },\n * ]);\n *\n * const db = createIndexedDB({ name: 'app', version: 2, schema, migrate });\n * ```\n */\nexport function defineMigration(steps: MigrationStep[]): MigrationFn {\n return ({ db, tx }) => {\n for (const step of steps) {\n switch (step.type) {\n case 'addIndex': {\n const store = tx.objectStore(step.table);\n\n // keyPath mirrors the vault storage envelope: { value: T, expiresAt?: number }\n if (!store.indexNames.contains(step.field)) {\n store.createIndex(step.field, `value.${step.field}`);\n }\n\n break;\n }\n case 'addTable':\n if (!db.objectStoreNames.contains(step.name)) {\n db.createObjectStore(step.name);\n }\n\n break;\n case 'removeIndex': {\n const store = tx.objectStore(step.table);\n\n if (store.indexNames.contains(step.field)) {\n store.deleteIndex(step.field);\n }\n\n break;\n }\n case 'removeTable':\n if (db.objectStoreNames.contains(step.name)) {\n db.deleteObjectStore(step.name);\n }\n\n break;\n }\n }\n };\n}\n\nfunction idbReq<R>(request: IDBRequest<R>): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error ?? new VaultError('IndexedDB request failed'));\n });\n}\n\nfunction wrapTxError(scope: string, message: string, cause: unknown): VaultError {\n const causeMessage = cause instanceof Error && cause.message ? `: ${cause.message}` : '';\n\n return new VaultError(`${message} on \"${scope}\"${causeMessage}`, { cause });\n}\n\nfunction runIdbTx<T>(tx: IDBTransaction, scope: string, work: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n let result: T | undefined;\n let callbackError: unknown;\n\n Promise.resolve()\n .then(work)\n .then((value) => {\n result = value;\n })\n .catch((error) => {\n callbackError = error;\n\n try {\n tx.abort();\n } catch {\n /* ignore */\n }\n });\n\n const rejectWithCallbackError = (fallbackCause: unknown, message = 'transaction failed'): void => {\n if (callbackError instanceof Error) {\n reject(callbackError);\n } else {\n reject(wrapTxError(scope, message, callbackError ?? fallbackCause));\n }\n };\n\n tx.oncomplete = () => {\n if (callbackError) {\n rejectWithCallbackError(undefined);\n\n return;\n }\n\n resolve(result as T);\n };\n tx.onerror = () => reject(wrapTxError(scope, 'transaction error', tx.error));\n tx.onabort = () => rejectWithCallbackError(tx.error, 'transaction aborted');\n });\n}\n\nasync function getAllFromStore<T extends object>(\n store: IDBObjectStore,\n decode: (raw: unknown) => T | undefined,\n): Promise<T[]> {\n const rawRecords = await idbReq<unknown[]>(store.getAll());\n const records: T[] = [];\n\n for (const raw of rawRecords) {\n const value = decode(raw);\n\n if (value !== undefined) records.push(value);\n }\n\n return records;\n}\n\nasync function storeGet<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<T | undefined> {\n const raw = await idbReq<unknown>(store.get(key));\n\n if (raw == null) return undefined;\n\n return decode(raw);\n}\n\nasync function storeHas<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<boolean> {\n return (await storeGet<T>(store, key, decode)) !== undefined;\n}\n\nasync function storeDelete<T extends object>(\n store: IDBObjectStore,\n key: IDBValidKey,\n decode: (raw: unknown) => T | undefined,\n): Promise<boolean> {\n const live = await storeHas<T>(store, key, decode);\n\n await idbReq(store.delete(key));\n\n return live;\n}\n\nasync function storeDeleteMany<T extends object>(\n store: IDBObjectStore,\n keys: IDBValidKey[],\n decode: (raw: unknown) => T | undefined,\n): Promise<number> {\n if (keys.length === 0) return 0;\n\n const results = await Promise.all(keys.map((k) => storeDelete<T>(store, k, decode)));\n\n return results.filter(Boolean).length;\n}\n\nasync function storePutAt<T>(\n store: IDBObjectStore,\n key: IDBValidKey,\n value: T,\n encode: (v: T, ttl?: number) => unknown,\n ttl?: number,\n): Promise<void> {\n await idbReq(store.put(encode(value, ttl), key));\n}\n\nfunction pruneExpiredInStore(store: IDBObjectStore): Promise<number> {\n return new Promise<number>((resolve, reject) => {\n let deleted = 0;\n const request = store.openCursor();\n\n request.onerror = () => reject(request.error ?? new VaultError('IndexedDB cursor failed during prune'));\n request.onsuccess = () => {\n const cursor = request.result;\n\n if (!cursor) {\n resolve(deleted);\n\n return;\n }\n\n const stored = parseStored(cursor.value as unknown);\n\n if (!stored || isExpired(stored.expiresAt)) {\n cursor.delete();\n deleted += 1;\n }\n\n cursor.continue();\n };\n });\n}\n\n/**\n * Cursor state machine — a single discriminated union replaces five boolean/nullable variables.\n * Transitions: idle → waiting (next() before cursor fires) | buffered (cursor fires first) | done | error\n */\ntype CursorState<T> =\n | { type: 'idle' }\n | { reject: (e: unknown) => void; resolve: (r: IteratorResult<T>) => void; type: 'waiting' }\n | { result: IteratorResult<T>; type: 'buffered' }\n | { error: unknown; type: 'error' }\n | { type: 'done' };\n\n/**\n * F1: True cursor-based iteration for IndexedDB.\n * Yields live records one-by-one using an IDB cursor, avoiding materializing the full table.\n * This is memory-efficient for large tables — the cursor walks the store incrementally.\n *\n * Design: the cursor is opened *synchronously* in [Symbol.asyncIterator]() so that event\n * handlers are wired immediately (no queueMicrotask races). The cursor is advanced *eagerly*\n * before yielding — this keeps the IDB readonly transaction alive between consumer awaits,\n * because IDB auto-commits when there are no pending requests.\n */\nfunction iterateStoreWithCursor<T extends object>(\n store: IDBObjectStore,\n decode: (raw: unknown) => T | undefined,\n): AsyncIterable<T> {\n return {\n [Symbol.asyncIterator](): AsyncIterator<T> {\n const cursorRequest = store.openCursor();\n let state: CursorState<T> = { type: 'idle' };\n\n const deliver = (result: IteratorResult<T>): void => {\n if (state.type === 'waiting') {\n const { resolve } = state;\n\n state = result.done ? { type: 'done' } : { type: 'idle' };\n resolve(result);\n } else {\n state = { result, type: 'buffered' };\n }\n };\n\n cursorRequest.onerror = () => {\n const err = cursorRequest.error ?? new VaultError('IndexedDB cursor iteration failed');\n\n if (state.type === 'waiting') {\n const { reject } = state;\n\n state = { type: 'done' };\n reject(err);\n } else {\n state = { error: err, type: 'error' };\n }\n };\n\n cursorRequest.onsuccess = () => {\n const cursor = cursorRequest.result;\n\n if (!cursor) {\n deliver({ done: true, value: undefined });\n\n return;\n }\n\n const value = decode(cursor.value as unknown);\n\n // Advance eagerly BEFORE yielding to keep the IDB transaction alive.\n cursor.continue();\n\n if (value !== undefined) deliver({ done: false, value });\n };\n\n return {\n next(): Promise<IteratorResult<T>> {\n if (state.type === 'error') {\n const { error } = state;\n\n state = { type: 'done' };\n\n return Promise.reject(error);\n }\n\n if (state.type === 'buffered') {\n const { result } = state;\n\n state = result.done ? { type: 'done' } : { type: 'idle' };\n\n return Promise.resolve(result);\n }\n\n if (state.type === 'done') return Promise.resolve({ done: true, value: undefined });\n\n return new Promise<IteratorResult<T>>((resolve, reject) => {\n state = { reject, resolve, type: 'waiting' };\n });\n },\n\n return(value?: unknown): Promise<IteratorResult<T>> {\n if (state.type === 'waiting') state.resolve({ done: true, value: undefined });\n\n state = { type: 'done' };\n\n return Promise.resolve({ done: true, value });\n },\n\n throw(err?: unknown): Promise<IteratorResult<T>> {\n if (state.type === 'waiting') state.reject(err);\n\n state = { type: 'done' };\n\n return Promise.reject(err);\n },\n };\n },\n };\n}\n\n/**\n * R3: Extracted IDB batch core — builds a StorageBackend that operates within\n * an existing IDBTransaction, shared by all tables in the batch.\n * Eliminates the duplicated `txCore` block that was previously inlined in `idbBatch`.\n */\nfunction buildIdbBatchCore<S extends AnySchema, K extends keyof S & string>(\n schema: S,\n idbTx: IDBTransaction,\n decode: <T extends object>(raw: unknown) => T | undefined,\n encode: <T>(value: T, ttl?: number) => unknown,\n): StorageBackend<S, K> {\n const storeOf = (table: K): IDBObjectStore => idbTx.objectStore(table);\n\n return {\n clear: async (table) => {\n await idbReq(storeOf(table).clear());\n },\n count: async (table) => {\n // Must inspect each stored record to exclude TTL-expired entries.\n // Individual put() calls can attach a TTL even when the schema has no defaultTtl,\n // so schema[table].defaultTtl being absent does not guarantee a clean count.\n // This matches the top-level core.count() behaviour in the IDB adapter.\n const all = await idbReq<unknown[]>(storeOf(table).getAll());\n\n return all.filter((r) => decode(r) !== undefined).length;\n },\n delete: (table, key) => storeDelete<RecordOf<S, K>>(storeOf(table), encodeVaultKey(key), decode),\n deleteMany: (table, keys) => storeDeleteMany<RecordOf<S, K>>(storeOf(table), keys.map(encodeVaultKey), decode),\n get: (table, key) => storeGet<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode),\n getAll: (table) => getAllFromStore<RecordOf<S, typeof table>>(storeOf(table), decode),\n getMany: (table, keys) =>\n Promise.all(keys.map((key) => storeGet<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode))),\n has: (table, key) => storeHas<RecordOf<S, typeof table>>(storeOf(table), encodeVaultKey(key), decode),\n pruneExpiredInTable: (table) => pruneExpiredInStore(storeOf(table)),\n put(table, value, ttl) {\n return storePutAt(storeOf(table), encodeVaultKey(getRecordKey(schema, table, value)), value, encode, ttl);\n },\n putAll(table, values, ttl) {\n return Promise.all(\n values.map((v) => storePutAt(storeOf(table), encodeVaultKey(getRecordKey(schema, table, v)), v, encode, ttl)),\n ).then(() => undefined);\n },\n };\n}\n\ntype IndexedDbOptions<S extends AnySchema> = BaseAdapterOptions<S> & {\n migrate?: MigrationFn;\n name: string;\n /** Schema version. Must be a positive integer. Increment when adding tables or changing the schema, then provide `migrate`. Defaults to 1. */\n version?: number;\n};\n\nexport function createIndexedDB<S extends AnySchema>(options: IndexedDbOptions<S>): TransactionalVaultStore<S> {\n const { migrate, name, schema, validators, version = 1 } = options;\n\n if (!Number.isInteger(version) || version < 1) {\n throw new VaultError(`createIndexedDB: version must be a positive integer, got ${String(version)}`);\n }\n\n // Fixed envelopes keep IndexedDB records and `value.<field>` indexes portable across adapters.\n const decode = <T extends object>(raw: unknown): T | undefined => {\n const stored = parseStored<T>(raw);\n\n return !stored || isExpired(stored.expiresAt) ? undefined : stored.value;\n };\n\n const encode = <T>(value: T, ttl?: number): StoredRecord<T> => {\n return ttl === undefined ? { value } : { expiresAt: Date.now() + ttl, value };\n };\n\n const channel = typeof BroadcastChannel !== 'undefined' ? new BroadcastChannel(`vault:${name}`) : undefined;\n\n let db: IDBDatabase | null = null;\n let connectPromise: Promise<void> | null = null;\n let disposed = false;\n\n const createObjectStores = (target: IDBDatabase, tx: IDBTransaction): void => {\n for (const [tableName, entry] of Object.entries(schema)) {\n let store: IDBObjectStore;\n\n if (!target.objectStoreNames.contains(tableName)) {\n store = target.createObjectStore(tableName);\n } else {\n store = tx.objectStore(tableName);\n }\n\n // F5: Create secondary indexes for fields declared via .index() on the table() builder.\n // Stored format is { value: T, expiresAt?: number } so IDB keyPath is `value.<field>`.\n const indexes = (entry as { indexes?: readonly string[] }).indexes ?? [];\n\n for (const field of indexes) {\n if (!store.indexNames.contains(field)) {\n store.createIndex(field, `value.${field}`);\n }\n }\n }\n };\n\n const connect = async (): Promise<void> => {\n if (!connectPromise) {\n connectPromise = new Promise((resolve, reject) => {\n const request = indexedDB.open(name, version);\n\n request.onupgradeneeded = (event) => {\n const target = request.result;\n const tx = request.transaction!;\n\n if (migrate) {\n try {\n migrate({\n db: target,\n newVersion: (event as IDBVersionChangeEvent).newVersion ?? null,\n oldVersion: event.oldVersion,\n tx,\n });\n } catch (error) {\n try {\n tx.abort();\n } catch {\n /* ignore */\n }\n\n reject(new VaultMigrationError(`migration failed for \"${name}\"`, { cause: error }));\n\n return;\n }\n }\n\n createObjectStores(target, tx);\n };\n\n request.onsuccess = () => {\n if (disposed) {\n request.result.close();\n resolve();\n\n return;\n }\n\n const connection = request.result;\n\n connection.onversionchange = () => {\n connection.close();\n db = null;\n connectPromise = null;\n };\n\n db = connection;\n resolve();\n };\n request.onerror = () => {\n connectPromise = null;\n reject(new VaultError(`failed to open \"${name}\"`, { cause: request.error }));\n };\n });\n }\n\n return connectPromise;\n };\n\n const withStore = async <T>(\n table: keyof S,\n mode: 'readonly' | 'readwrite',\n fn: (store: IDBObjectStore) => Promise<T>,\n ): Promise<T> => {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (!db) await connect();\n\n if (!db) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n const tableName = String(table);\n const tx = db.transaction(tableName, mode);\n\n return runIdbTx(tx, `${name}/${tableName}`, () => fn(tx.objectStore(tableName)));\n };\n\n const requireDb = async (): Promise<IDBDatabase> => {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n if (!db) await connect();\n\n if (!db) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n return db;\n };\n\n const publish = <K extends keyof S>(table: K): void => {\n channel?.postMessage({ table: String(table) });\n };\n\n const core: StorageBackend<S> = {\n clear: (table) => withStore(table, 'readwrite', (s) => idbReq(s.clear()).then(() => undefined)),\n\n count: (table) =>\n withStore(table, 'readonly', async (s) => {\n // Must inspect each stored record to exclude TTL-expired entries.\n // Individual put() calls can attach a TTL even when the schema has no defaultTtl,\n // so schema[table].defaultTtl being absent does not guarantee a clean count.\n const all = await idbReq<unknown[]>(s.getAll());\n\n return all.filter((r) => decode(r) !== undefined).length;\n }),\n\n delete: (table, key) =>\n withStore(table, 'readwrite', (s) => storeDelete<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n deleteMany: (table, keys) =>\n keys.length === 0\n ? Promise.resolve(0)\n : withStore(table, 'readwrite', (s) =>\n storeDeleteMany<RecordOf<S, typeof table>>(s, keys.map(encodeVaultKey), decode),\n ),\n\n async dispose(): Promise<void> {\n disposed = true;\n channel?.close();\n\n // F7: Wait for any in-progress connect before closing the DB to avoid\n // \"database connection is closing\" errors on in-flight requests.\n if (connectPromise) await connectPromise.catch(() => {});\n\n db?.close();\n db = null;\n connectPromise = null;\n },\n\n get: (table, key) =>\n withStore(table, 'readonly', (s) => storeGet<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n getAll: (table) => withStore(table, 'readonly', (s) => getAllFromStore<RecordOf<S, typeof table>>(s, decode)),\n\n // Ad-hoc per-put TTLs can be attached regardless of schema-level defaultTtl (same caveat as\n // count()), so we cannot take the O(1) store.getAllKeys() shortcut unconditionally — every\n // record must be decoded to exclude TTL-expired entries correctly.\n getAllKeys: (table) =>\n withStore(table, 'readonly', async (s) => {\n const records = await getAllFromStore<RecordOf<S, typeof table>>(s, decode);\n const keyField = schema[table].key;\n\n return records.map((r) => (r as Record<string, unknown>)[keyField] as KeyOf<S, typeof table>);\n }),\n\n getMany: (table, keys) =>\n keys.length === 0\n ? Promise.resolve([])\n : withStore(table, 'readonly', (s) =>\n Promise.all(keys.map((key) => storeGet<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode))),\n ),\n\n has: (table, key) =>\n withStore(table, 'readonly', (s) => storeHas<RecordOf<S, typeof table>>(s, encodeVaultKey(key), decode)),\n\n async pruneAllExpired() {\n const idb = await requireDb();\n const tableNames = Object.keys(schema);\n const tx = idb.transaction(tableNames, 'readwrite');\n const results = await runIdbTx(tx, `${name}/pruneAll`, () =>\n Promise.all(tableNames.map(async (t) => [t, await pruneExpiredInStore(tx.objectStore(t))] as const)),\n );\n\n return Object.fromEntries(results);\n },\n\n pruneExpiredInTable: (table) => withStore(table, 'readwrite', (s) => pruneExpiredInStore(s)),\n\n put(table, value, ttl) {\n const key = encodeVaultKey(getRecordKey(schema, table, value));\n\n return withStore(table, 'readwrite', (s) => storePutAt(s, key, value, encode, ttl));\n },\n\n putAll(table, values, ttl) {\n return withStore(table, 'readwrite', (s) =>\n Promise.all(\n values.map((v) => storePutAt(s, encodeVaultKey(getRecordKey(schema, table, v)), v, encode, ttl)),\n ).then(() => undefined),\n );\n },\n };\n\n const idbBatch = async <K extends keyof S & string, R>(\n tables: readonly K[],\n fn: (tx: TransactionContext<S, K>) => Promise<R>,\n notifyMutation: (table: K) => void,\n validateFn: <T extends K>(table: T, value: RecordOf<S, T>) => RecordOf<S, T>,\n ): Promise<R> => {\n assertBatchTables(tables);\n\n const idb = await requireDb();\n const idbTx = idb.transaction([...tables] as string[], 'readwrite');\n const dirtyTables = new Set<K>();\n\n const txCore = buildIdbBatchCore<S, K>(schema, idbTx, decode, encode);\n const scope = new Set<string>(tables);\n const tx = buildTxContext<S, K>(schema, txCore, (t) => dirtyTables.add(t), validateFn, scope);\n const result = await runIdbTx(idbTx, name, () => fn(tx));\n\n for (const table of dirtyTables) {\n notifyMutation(table);\n }\n\n return result;\n };\n\n let batch: BatchImpl<S> | undefined;\n const adapter = buildAdapterOps(schema, core, {\n onCrossTabMessage(notify) {\n if (!channel) {\n return undefined;\n }\n\n channel.onmessage = (event: MessageEvent<{ table?: string }>) => {\n const tableName = event.data?.table;\n\n if (!tableName || !Object.hasOwn(schema, tableName)) return;\n\n notify(tableName as keyof S & string);\n };\n\n return () => {\n channel.onmessage = null;\n };\n },\n onMutation: publish,\n onTransactions: (deps) => {\n batch = (tables, fn) => idbBatch(tables, fn, deps.notifyMutation, deps.validate);\n },\n schema,\n validators,\n });\n\n /**\n * F1: Attach cursor-based `iterate()` on top of the adapter.\n * Opens a dedicated readonly transaction per call and streams records via IDB cursor —\n * genuinely memory-efficient for large tables unlike the getAll()-then-yield pattern.\n */\n const store = {\n ...adapter,\n get disposalSignal(): AbortSignal {\n return adapter.disposalSignal;\n },\n // Spread copies getters as static values; re-expose live disposal state.\n get disposed(): boolean {\n return adapter.disposed;\n },\n iterate<K extends keyof S & string>(table: K): AsyncIterable<RecordOf<S, K>> {\n if (disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n // Each call opens a fresh transaction so iteration doesn't hold locks across awaits.\n // We need to ensure the DB is connected before opening the transaction.\n const getIterable = async (): Promise<AsyncIterable<RecordOf<S, K>>> => {\n if (!db) await connect();\n\n if (!db || disposed) throw new VaultDisposedError(`\"${name}\" is disposed`);\n\n const idb = db;\n const tx = idb.transaction(String(table), 'readonly');\n const store = tx.objectStore(String(table));\n\n return iterateStoreWithCursor<RecordOf<S, K>>(store, decode as (raw: unknown) => RecordOf<S, K> | undefined);\n };\n\n let inner: AsyncIterator<RecordOf<S, K>> | undefined;\n\n const initInner = (): Promise<AsyncIterator<RecordOf<S, K>>> =>\n getIterable().then((iterable) => {\n inner = iterable[Symbol.asyncIterator]();\n\n return inner;\n });\n\n return {\n [Symbol.asyncIterator](): AsyncIterator<RecordOf<S, K>> {\n return {\n next(): Promise<IteratorResult<RecordOf<S, K>>> {\n // Sync check avoids an extra Promise allocation on every iteration after the first.\n if (inner) return inner.next();\n\n return initInner().then((it) => it.next());\n },\n return(value?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n if (inner) return inner.return?.(value) ?? Promise.resolve({ done: true, value });\n\n return Promise.resolve({ done: true, value });\n },\n throw(err?: unknown): Promise<IteratorResult<RecordOf<S, K>>> {\n if (inner) return inner.throw?.(err) ?? Promise.reject(err);\n\n return Promise.reject(err);\n },\n };\n },\n };\n },\n };\n\n if (!batch) throw new VaultError('IndexedDB transaction capability was not initialized');\n\n return withIndexedDbTransactions(store, batch);\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import type { AnySchema, BaseAdapterOptions, IndexedDbVaultStore } from '../types';
2
- export type { IndexedDbVaultStore };
1
+ import type { AnySchema, BaseAdapterOptions, TransactionalVaultStore } from '../types';
2
+ export type { TransactionalVaultStore as IndexedDbVaultStore };
3
3
  /** IndexedDB-only migration context supplied to `MigrationFn` during `onupgradeneeded`. */
4
4
  export type MigrationContext = {
5
5
  db: IDBDatabase;
@@ -50,5 +50,5 @@ type IndexedDbOptions<S extends AnySchema> = BaseAdapterOptions<S> & {
50
50
  /** Schema version. Must be a positive integer. Increment when adding tables or changing the schema, then provide `migrate`. Defaults to 1. */
51
51
  version?: number;
52
52
  };
53
- export declare function createIndexedDB<S extends AnySchema>(options: IndexedDbOptions<S>): IndexedDbVaultStore<S>;
53
+ export declare function createIndexedDB<S extends AnySchema>(options: IndexedDbOptions<S>): TransactionalVaultStore<S>;
54
54
  //# sourceMappingURL=indexeddb.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/adapters/indexeddb.ts"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,mBAAmB,EAAuC,MAAM,UAAU,CAAC;AAExH,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAEpC,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,WAAW,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,cAAc,CAAC;CACpB,CAAC;AAEF,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAClD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE1C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,WAAW,CAsCnE;AAsVD,KAAK,gBAAgB,CAAC,CAAC,SAAS,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,8IAA8I;IAC9I,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,mBAAmB,CAAC,CAAC,CAAC,CAgWzG"}
1
+ {"version":3,"file":"indexeddb.d.ts","sourceRoot":"","sources":["../../src/adapters/indexeddb.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,SAAS,EACT,kBAAkB,EAGlB,uBAAuB,EAExB,MAAM,UAAU,CAAC;AAElB,YAAY,EAAE,uBAAuB,IAAI,mBAAmB,EAAE,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,WAAW,CAAC;IAChB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,EAAE,EAAE,cAAc,CAAC;CACpB,CAAC;AAEF,qDAAqD;AACrD,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAE1D;;;GAGG;AACH,MAAM,MAAM,aAAa,GACrB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAClD;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,aAAa,CAAA;CAAE,CAAC;AAE1C;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,aAAa,EAAE,GAAG,WAAW,CAsCnE;AA2TD,KAAK,gBAAgB,CAAC,CAAC,SAAS,SAAS,IAAI,kBAAkB,CAAC,CAAC,CAAC,GAAG;IACnE,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,8IAA8I;IAC9I,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,wBAAgB,eAAe,CAAC,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,uBAAuB,CAAC,CAAC,CAAC,CA4V7G"}
@@ -63,32 +63,24 @@ async function h(e, t) {
63
63
  }
64
64
  return r;
65
65
  }
66
- async function g(e, t, n, r) {
67
- let i = e.index(t), a = n.type === "eq" ? IDBKeyRange.only(n.value) : n.type === "between" ? IDBKeyRange.bound(n.lower, n.upper) : IDBKeyRange.bound(n.prefix, `${n.prefix}\uffff`), o = await f(i.getAll(a)), s = [];
68
- for (let e of o) {
69
- let t = r(e);
70
- t !== void 0 && s.push(t);
71
- }
72
- return s;
73
- }
74
- async function _(e, t, n) {
66
+ async function g(e, t, n) {
75
67
  let r = await f(e.get(t));
76
68
  if (r != null) return n(r);
77
69
  }
78
- async function v(e, t, n) {
79
- return await _(e, t, n) !== void 0;
70
+ async function _(e, t, n) {
71
+ return await g(e, t, n) !== void 0;
80
72
  }
81
- async function y(e, t, n) {
82
- let r = await v(e, t, n);
73
+ async function v(e, t, n) {
74
+ let r = await _(e, t, n);
83
75
  return await f(e.delete(t)), r;
84
76
  }
85
- async function b(e, t, n) {
86
- return t.length === 0 ? 0 : (await Promise.all(t.map((t) => y(e, t, n)))).filter(Boolean).length;
77
+ async function y(e, t, n) {
78
+ return t.length === 0 ? 0 : (await Promise.all(t.map((t) => v(e, t, n)))).filter(Boolean).length;
87
79
  }
88
- async function x(e, t, n, r, i) {
80
+ async function b(e, t, n, r, i) {
89
81
  await f(e.put(r(n, i), t));
90
82
  }
91
- function S(e) {
83
+ function x(e) {
92
84
  return new Promise((n, a) => {
93
85
  let o = 0, s = e.openCursor();
94
86
  s.onerror = () => a(s.error ?? new t("IndexedDB cursor failed during prune")), s.onsuccess = () => {
@@ -102,7 +94,7 @@ function S(e) {
102
94
  };
103
95
  });
104
96
  }
105
- function C(e, n) {
97
+ function S(e, n) {
106
98
  return { [Symbol.asyncIterator]() {
107
99
  let r = e.openCursor(), i = { type: "idle" }, a = (e) => {
108
100
  if (i.type === "waiting") {
@@ -172,53 +164,50 @@ function C(e, n) {
172
164
  };
173
165
  } };
174
166
  }
175
- function w(e, t, n, r) {
167
+ function C(e, t, n, r) {
176
168
  let i = (e) => t.objectStore(e);
177
169
  return {
178
170
  clear: async (e) => {
179
171
  await f(i(e).clear());
180
172
  },
181
173
  count: async (e) => (await f(i(e).getAll())).filter((e) => n(e) !== void 0).length,
182
- delete: (e, t) => y(i(e), a(t), n),
183
- deleteMany: (e, t) => b(i(e), t.map(a), n),
184
- get: (e, t) => _(i(e), a(t), n),
174
+ delete: (e, t) => v(i(e), a(t), n),
175
+ deleteMany: (e, t) => y(i(e), t.map(a), n),
176
+ get: (e, t) => g(i(e), a(t), n),
185
177
  getAll: (e) => h(i(e), n),
186
- getByIndexRange: (e, t, r) => g(i(e), t, r, n),
187
- getMany: (e, t) => Promise.all(t.map((t) => _(i(e), a(t), n))),
188
- has: (e, t) => v(i(e), a(t), n),
189
- pruneExpiredInTable: (e) => S(i(e)),
178
+ getMany: (e, t) => Promise.all(t.map((t) => g(i(e), a(t), n))),
179
+ has: (e, t) => _(i(e), a(t), n),
180
+ pruneExpiredInTable: (e) => x(i(e)),
190
181
  put(t, n, s) {
191
- return x(i(t), a(o(e, t, n)), n, r, s);
182
+ return b(i(t), a(o(e, t, n)), n, r, s);
192
183
  },
193
184
  putAll(t, n, s) {
194
- return Promise.all(n.map((n) => x(i(t), a(o(e, t, n)), n, r, s))).then(() => void 0);
185
+ return Promise.all(n.map((n) => b(i(t), a(o(e, t, n)), n, r, s))).then(() => void 0);
195
186
  }
196
187
  };
197
188
  }
198
- function T(d) {
199
- let { logger: p, migrate: T, name: E, onMetrics: D, schema: O, validators: k, version: A = 1 } = d;
200
- if (!Number.isInteger(A) || A < 1) throw new t(`createIndexedDB: version must be a positive integer, got ${String(A)}`);
201
- let j = (e) => {
189
+ function w(d) {
190
+ let { migrate: p, name: w, schema: T, validators: E, version: D = 1 } = d;
191
+ if (!Number.isInteger(D) || D < 1) throw new t(`createIndexedDB: version must be a positive integer, got ${String(D)}`);
192
+ let O = (e) => {
202
193
  let t = i(e);
203
194
  return !t || r(t.expiresAt) ? void 0 : t.value;
204
- }, M = (e, t) => t === void 0 ? { value: e } : {
195
+ }, k = (e, t) => t === void 0 ? { value: e } : {
205
196
  expiresAt: Date.now() + t,
206
197
  value: e
207
- }, N = typeof BroadcastChannel < "u" ? new BroadcastChannel(`vault:${E}`) : void 0;
208
- !N && p && p.error(`[vault] BroadcastChannel unavailable — cross-tab sync disabled for "${E}"`);
209
- let P = null, F = null, I = !1, L = (e, t) => {
210
- for (let [n, r] of Object.entries(O)) {
198
+ }, A = typeof BroadcastChannel < "u" ? new BroadcastChannel(`vault:${w}`) : void 0, j = null, M = null, N = !1, P = (e, t) => {
199
+ for (let [n, r] of Object.entries(T)) {
211
200
  let i;
212
201
  i = e.objectStoreNames.contains(n) ? t.objectStore(n) : e.createObjectStore(n);
213
202
  let a = r.indexes ?? [];
214
203
  for (let e of a) i.indexNames.contains(e) || i.createIndex(e, `value.${e}`);
215
204
  }
216
- }, R = async () => (F ||= new Promise((e, r) => {
217
- let i = indexedDB.open(E, A);
205
+ }, F = async () => (M ||= new Promise((e, r) => {
206
+ let i = indexedDB.open(w, D);
218
207
  i.onupgradeneeded = (e) => {
219
208
  let t = i.result, a = i.transaction;
220
- if (T) try {
221
- T({
209
+ if (p) try {
210
+ p({
222
211
  db: t,
223
212
  newVersion: e.newVersion ?? null,
224
213
  oldVersion: e.oldVersion,
@@ -228,90 +217,92 @@ function T(d) {
228
217
  try {
229
218
  a.abort();
230
219
  } catch {}
231
- r(new n(`migration failed for "${E}"`, { cause: e }));
220
+ r(new n(`migration failed for "${w}"`, { cause: e }));
232
221
  return;
233
222
  }
234
- L(t, a);
223
+ P(t, a);
235
224
  }, i.onsuccess = () => {
236
- if (I) {
225
+ if (N) {
237
226
  i.result.close(), e();
238
227
  return;
239
228
  }
240
229
  let t = i.result;
241
230
  t.onversionchange = () => {
242
- t.close(), P = null, F = null;
243
- }, P = t, e();
231
+ t.close(), j = null, M = null;
232
+ }, j = t, e();
244
233
  }, i.onerror = () => {
245
- F = null, r(new t(`failed to open "${E}"`, { cause: i.error }));
234
+ M = null, r(new t(`failed to open "${w}"`, { cause: i.error }));
246
235
  };
247
- }), F), z = async (t, n, r) => {
248
- if (I || (P || await R(), !P)) throw new e(`"${E}" is disposed`);
249
- let i = String(t), a = P.transaction(i, n);
250
- return m(a, `${E}/${i}`, () => r(a.objectStore(i)));
251
- }, B = async () => {
252
- if (I || (P || await R(), !P)) throw new e(`"${E}" is disposed`);
253
- return P;
254
- }, V = (e) => {
255
- N?.postMessage({ table: String(e) });
256
- }, H = {
257
- clear: (e) => z(e, "readwrite", (e) => f(e.clear()).then(() => void 0)),
258
- count: (e) => z(e, "readonly", async (e) => (await f(e.getAll())).filter((e) => j(e) !== void 0).length),
259
- delete: (e, t) => z(e, "readwrite", (e) => y(e, a(t), j)),
260
- deleteMany: (e, t) => t.length === 0 ? Promise.resolve(0) : z(e, "readwrite", (e) => b(e, t.map(a), j)),
236
+ }), M), I = async (t, n, r) => {
237
+ if (N || (j || await F(), !j)) throw new e(`"${w}" is disposed`);
238
+ let i = String(t), a = j.transaction(i, n);
239
+ return m(a, `${w}/${i}`, () => r(a.objectStore(i)));
240
+ }, L = async () => {
241
+ if (N || (j || await F(), !j)) throw new e(`"${w}" is disposed`);
242
+ return j;
243
+ }, R = (e) => {
244
+ A?.postMessage({ table: String(e) });
245
+ }, z = {
246
+ clear: (e) => I(e, "readwrite", (e) => f(e.clear()).then(() => void 0)),
247
+ count: (e) => I(e, "readonly", async (e) => (await f(e.getAll())).filter((e) => O(e) !== void 0).length),
248
+ delete: (e, t) => I(e, "readwrite", (e) => v(e, a(t), O)),
249
+ deleteMany: (e, t) => t.length === 0 ? Promise.resolve(0) : I(e, "readwrite", (e) => y(e, t.map(a), O)),
261
250
  async dispose() {
262
- I = !0, N?.close(), F && await F.catch(() => {}), P?.close(), P = null, F = null;
251
+ N = !0, A?.close(), M && await M.catch(() => {}), j?.close(), j = null, M = null;
263
252
  },
264
- get: (e, t) => z(e, "readonly", (e) => _(e, a(t), j)),
265
- getAll: (e) => z(e, "readonly", (e) => h(e, j)),
266
- getAllKeys: (e) => z(e, "readonly", async (t) => {
267
- let n = await h(t, j), r = O[e].key;
253
+ get: (e, t) => I(e, "readonly", (e) => g(e, a(t), O)),
254
+ getAll: (e) => I(e, "readonly", (e) => h(e, O)),
255
+ getAllKeys: (e) => I(e, "readonly", async (t) => {
256
+ let n = await h(t, O), r = T[e].key;
268
257
  return n.map((e) => e[r]);
269
258
  }),
270
- getByIndexRange: (e, t, n) => z(e, "readonly", (e) => g(e, t, n, j)),
271
- getMany: (e, t) => t.length === 0 ? Promise.resolve([]) : z(e, "readonly", (e) => Promise.all(t.map((t) => _(e, a(t), j)))),
272
- getRawCount: (e) => z(e, "readonly", (e) => f(e.count())),
273
- has: (e, t) => z(e, "readonly", (e) => v(e, a(t), j)),
259
+ getMany: (e, t) => t.length === 0 ? Promise.resolve([]) : I(e, "readonly", (e) => Promise.all(t.map((t) => g(e, a(t), O)))),
260
+ has: (e, t) => I(e, "readonly", (e) => _(e, a(t), O)),
274
261
  async pruneAllExpired() {
275
- let e = await B(), t = Object.keys(O), n = e.transaction(t, "readwrite"), r = await m(n, `${E}/pruneAll`, () => Promise.all(t.map(async (e) => [e, await S(n.objectStore(e))])));
262
+ let e = await L(), t = Object.keys(T), n = e.transaction(t, "readwrite"), r = await m(n, `${w}/pruneAll`, () => Promise.all(t.map(async (e) => [e, await x(n.objectStore(e))])));
276
263
  return Object.fromEntries(r);
277
264
  },
278
- pruneExpiredInTable: (e) => z(e, "readwrite", (e) => S(e)),
265
+ pruneExpiredInTable: (e) => I(e, "readwrite", (e) => x(e)),
279
266
  put(e, t, n) {
280
- let r = a(o(O, e, t));
281
- return z(e, "readwrite", (e) => x(e, r, t, M, n));
267
+ let r = a(o(T, e, t));
268
+ return I(e, "readwrite", (e) => b(e, r, t, k, n));
282
269
  },
283
270
  putAll(e, t, n) {
284
- return z(e, "readwrite", (r) => Promise.all(t.map((t) => x(r, a(o(O, e, t)), t, M, n))).then(() => void 0));
271
+ return I(e, "readwrite", (r) => Promise.all(t.map((t) => b(r, a(o(T, e, t)), t, k, n))).then(() => void 0));
285
272
  }
286
- }, U = async (e, t, n, r) => {
273
+ }, B = async (e, t, n, r) => {
287
274
  s(e);
288
- let i = (await B()).transaction([...e], "readwrite"), a = /* @__PURE__ */ new Set(), o = w(O, i, j, M), c = new Set(e), u = l(O, o, (e) => a.add(e), r, c), d = await m(i, E, () => t(u));
275
+ let i = (await L()).transaction([...e], "readwrite"), a = /* @__PURE__ */ new Set(), o = C(T, i, O, k), c = new Set(e), u = l(T, o, (e) => a.add(e), r, c), d = await m(i, w, () => t(u));
289
276
  for (let e of a) n(e);
290
277
  return d;
291
- }, W, G = {
292
- ...c(O, H, {
293
- logger: p,
294
- onCrossTabMessage(e) {
295
- if (N) return N.onmessage = (t) => {
296
- let n = t.data?.table;
297
- !n || !Object.hasOwn(O, n) || e(n);
298
- }, () => {
299
- N.onmessage = null;
300
- };
301
- },
302
- onMetrics: D,
303
- onMutation: V,
304
- onTransactions: (e) => {
305
- W = (t, n) => U(t, n, e.notifyMutation, e.validate);
306
- },
307
- schema: O,
308
- validators: k
309
- }),
278
+ }, V, H = c(T, z, {
279
+ onCrossTabMessage(e) {
280
+ if (A) return A.onmessage = (t) => {
281
+ let n = t.data?.table;
282
+ !n || !Object.hasOwn(T, n) || e(n);
283
+ }, () => {
284
+ A.onmessage = null;
285
+ };
286
+ },
287
+ onMutation: R,
288
+ onTransactions: (e) => {
289
+ V = (t, n) => B(t, n, e.notifyMutation, e.validate);
290
+ },
291
+ schema: T,
292
+ validators: E
293
+ }), U = {
294
+ ...H,
295
+ get disposalSignal() {
296
+ return H.disposalSignal;
297
+ },
298
+ get disposed() {
299
+ return H.disposed;
300
+ },
310
301
  iterate(t) {
311
- if (I) throw new e(`"${E}" is disposed`);
302
+ if (N) throw new e(`"${w}" is disposed`);
312
303
  let n = async () => {
313
- if (P || await R(), !P || I) throw new e(`"${E}" is disposed`);
314
- return C(P.transaction(String(t), "readonly").objectStore(String(t)), j);
304
+ if (j || await F(), !j || N) throw new e(`"${w}" is disposed`);
305
+ return S(j.transaction(String(t), "readonly").objectStore(String(t)), O);
315
306
  }, r, i = () => n().then((e) => (r = e[Symbol.asyncIterator](), r));
316
307
  return { [Symbol.asyncIterator]() {
317
308
  return {
@@ -334,10 +325,10 @@ function T(d) {
334
325
  } };
335
326
  }
336
327
  };
337
- if (!W) throw new t("IndexedDB transaction capability was not initialized");
338
- return u(G, W);
328
+ if (!V) throw new t("IndexedDB transaction capability was not initialized");
329
+ return u(U, V);
339
330
  }
340
331
  //#endregion
341
- export { T as createIndexedDB, d as defineMigration };
332
+ export { w as createIndexedDB, d as defineMigration };
342
333
 
343
334
  //# sourceMappingURL=indexeddb.js.map