@vielzeug/deposit 1.0.1

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 (154) hide show
  1. package/dist/deposit.cjs +2 -0
  2. package/dist/deposit.cjs.map +1 -0
  3. package/dist/deposit.js +503 -0
  4. package/dist/deposit.js.map +1 -0
  5. package/dist/index.cjs +2 -0
  6. package/dist/index.cjs.map +1 -0
  7. package/dist/index.d.ts +214 -0
  8. package/dist/index.js +9 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/logit/dist/logit.cjs +2 -0
  11. package/dist/logit/dist/logit.cjs.map +1 -0
  12. package/dist/logit/dist/logit.js +178 -0
  13. package/dist/logit/dist/logit.js.map +1 -0
  14. package/dist/toolkit/dist/array/filter.cjs +2 -0
  15. package/dist/toolkit/dist/array/filter.cjs.map +1 -0
  16. package/dist/toolkit/dist/array/filter.js +14 -0
  17. package/dist/toolkit/dist/array/filter.js.map +1 -0
  18. package/dist/toolkit/dist/array/group.cjs +2 -0
  19. package/dist/toolkit/dist/array/group.cjs.map +1 -0
  20. package/dist/toolkit/dist/array/group.js +16 -0
  21. package/dist/toolkit/dist/array/group.js.map +1 -0
  22. package/dist/toolkit/dist/array/search.cjs +2 -0
  23. package/dist/toolkit/dist/array/search.cjs.map +1 -0
  24. package/dist/toolkit/dist/array/search.js +14 -0
  25. package/dist/toolkit/dist/array/search.js.map +1 -0
  26. package/dist/toolkit/dist/array/sortBy.cjs +2 -0
  27. package/dist/toolkit/dist/array/sortBy.cjs.map +1 -0
  28. package/dist/toolkit/dist/array/sortBy.js +6 -0
  29. package/dist/toolkit/dist/array/sortBy.js.map +1 -0
  30. package/dist/toolkit/dist/function/assert.cjs +3 -0
  31. package/dist/toolkit/dist/function/assert.cjs.map +1 -0
  32. package/dist/toolkit/dist/function/assert.js +12 -0
  33. package/dist/toolkit/dist/function/assert.js.map +1 -0
  34. package/dist/toolkit/dist/function/compare.cjs +2 -0
  35. package/dist/toolkit/dist/function/compare.cjs.map +1 -0
  36. package/dist/toolkit/dist/function/compare.js +22 -0
  37. package/dist/toolkit/dist/function/compare.js.map +1 -0
  38. package/dist/toolkit/dist/function/compareBy.cjs +2 -0
  39. package/dist/toolkit/dist/function/compareBy.cjs.map +1 -0
  40. package/dist/toolkit/dist/function/compareBy.js +15 -0
  41. package/dist/toolkit/dist/function/compareBy.js.map +1 -0
  42. package/dist/toolkit/dist/logit/dist/logit.cjs +2 -0
  43. package/dist/toolkit/dist/logit/dist/logit.cjs.map +1 -0
  44. package/dist/toolkit/dist/logit/dist/logit.js +178 -0
  45. package/dist/toolkit/dist/logit/dist/logit.js.map +1 -0
  46. package/dist/toolkit/dist/math/boil.cjs +2 -0
  47. package/dist/toolkit/dist/math/boil.cjs.map +1 -0
  48. package/dist/toolkit/dist/math/boil.js +17 -0
  49. package/dist/toolkit/dist/math/boil.js.map +1 -0
  50. package/dist/toolkit/dist/math/max.cjs +2 -0
  51. package/dist/toolkit/dist/math/max.cjs.map +1 -0
  52. package/dist/toolkit/dist/math/max.js +12 -0
  53. package/dist/toolkit/dist/math/max.js.map +1 -0
  54. package/dist/toolkit/dist/math/min.cjs +2 -0
  55. package/dist/toolkit/dist/math/min.cjs.map +1 -0
  56. package/dist/toolkit/dist/math/min.js +12 -0
  57. package/dist/toolkit/dist/math/min.js.map +1 -0
  58. package/dist/toolkit/dist/object/seek.cjs +2 -0
  59. package/dist/toolkit/dist/object/seek.cjs.map +1 -0
  60. package/dist/toolkit/dist/object/seek.js +11 -0
  61. package/dist/toolkit/dist/object/seek.js.map +1 -0
  62. package/dist/toolkit/dist/string/similarity.cjs +2 -0
  63. package/dist/toolkit/dist/string/similarity.cjs.map +1 -0
  64. package/dist/toolkit/dist/string/similarity.js +34 -0
  65. package/dist/toolkit/dist/string/similarity.js.map +1 -0
  66. package/dist/toolkit/dist/typed/ge.cjs +2 -0
  67. package/dist/toolkit/dist/typed/ge.cjs.map +1 -0
  68. package/dist/toolkit/dist/typed/ge.js +7 -0
  69. package/dist/toolkit/dist/typed/ge.js.map +1 -0
  70. package/dist/toolkit/dist/typed/gt.cjs +2 -0
  71. package/dist/toolkit/dist/typed/gt.cjs.map +1 -0
  72. package/dist/toolkit/dist/typed/gt.js +7 -0
  73. package/dist/toolkit/dist/typed/gt.js.map +1 -0
  74. package/dist/toolkit/dist/typed/is.cjs +2 -0
  75. package/dist/toolkit/dist/typed/is.cjs.map +1 -0
  76. package/dist/toolkit/dist/typed/is.js +44 -0
  77. package/dist/toolkit/dist/typed/is.js.map +1 -0
  78. package/dist/toolkit/dist/typed/isArray.cjs +2 -0
  79. package/dist/toolkit/dist/typed/isArray.cjs.map +1 -0
  80. package/dist/toolkit/dist/typed/isArray.js +9 -0
  81. package/dist/toolkit/dist/typed/isArray.js.map +1 -0
  82. package/dist/toolkit/dist/typed/isDefined.cjs +2 -0
  83. package/dist/toolkit/dist/typed/isDefined.cjs.map +1 -0
  84. package/dist/toolkit/dist/typed/isDefined.js +7 -0
  85. package/dist/toolkit/dist/typed/isDefined.js.map +1 -0
  86. package/dist/toolkit/dist/typed/isEmpty.cjs +2 -0
  87. package/dist/toolkit/dist/typed/isEmpty.cjs.map +1 -0
  88. package/dist/toolkit/dist/typed/isEmpty.js +10 -0
  89. package/dist/toolkit/dist/typed/isEmpty.js.map +1 -0
  90. package/dist/toolkit/dist/typed/isEqual.cjs +2 -0
  91. package/dist/toolkit/dist/typed/isEqual.cjs.map +1 -0
  92. package/dist/toolkit/dist/typed/isEqual.js +23 -0
  93. package/dist/toolkit/dist/typed/isEqual.js.map +1 -0
  94. package/dist/toolkit/dist/typed/isEven.cjs +2 -0
  95. package/dist/toolkit/dist/typed/isEven.cjs.map +1 -0
  96. package/dist/toolkit/dist/typed/isEven.js +7 -0
  97. package/dist/toolkit/dist/typed/isEven.js.map +1 -0
  98. package/dist/toolkit/dist/typed/isMatch.cjs +2 -0
  99. package/dist/toolkit/dist/typed/isMatch.cjs.map +1 -0
  100. package/dist/toolkit/dist/typed/isMatch.js +19 -0
  101. package/dist/toolkit/dist/typed/isMatch.js.map +1 -0
  102. package/dist/toolkit/dist/typed/isNegative.cjs +2 -0
  103. package/dist/toolkit/dist/typed/isNegative.cjs.map +1 -0
  104. package/dist/toolkit/dist/typed/isNegative.js +7 -0
  105. package/dist/toolkit/dist/typed/isNegative.js.map +1 -0
  106. package/dist/toolkit/dist/typed/isNil.cjs +2 -0
  107. package/dist/toolkit/dist/typed/isNil.cjs.map +1 -0
  108. package/dist/toolkit/dist/typed/isNil.js +7 -0
  109. package/dist/toolkit/dist/typed/isNil.js.map +1 -0
  110. package/dist/toolkit/dist/typed/isNumber.cjs +2 -0
  111. package/dist/toolkit/dist/typed/isNumber.cjs.map +1 -0
  112. package/dist/toolkit/dist/typed/isNumber.js +7 -0
  113. package/dist/toolkit/dist/typed/isNumber.js.map +1 -0
  114. package/dist/toolkit/dist/typed/isObject.cjs +2 -0
  115. package/dist/toolkit/dist/typed/isObject.cjs.map +1 -0
  116. package/dist/toolkit/dist/typed/isObject.js +7 -0
  117. package/dist/toolkit/dist/typed/isObject.js.map +1 -0
  118. package/dist/toolkit/dist/typed/isOdd.cjs +2 -0
  119. package/dist/toolkit/dist/typed/isOdd.cjs.map +1 -0
  120. package/dist/toolkit/dist/typed/isOdd.js +7 -0
  121. package/dist/toolkit/dist/typed/isOdd.js.map +1 -0
  122. package/dist/toolkit/dist/typed/isPositive.cjs +2 -0
  123. package/dist/toolkit/dist/typed/isPositive.cjs.map +1 -0
  124. package/dist/toolkit/dist/typed/isPositive.js +7 -0
  125. package/dist/toolkit/dist/typed/isPositive.js.map +1 -0
  126. package/dist/toolkit/dist/typed/isRegex.cjs +2 -0
  127. package/dist/toolkit/dist/typed/isRegex.cjs.map +1 -0
  128. package/dist/toolkit/dist/typed/isRegex.js +7 -0
  129. package/dist/toolkit/dist/typed/isRegex.js.map +1 -0
  130. package/dist/toolkit/dist/typed/isString.cjs +2 -0
  131. package/dist/toolkit/dist/typed/isString.cjs.map +1 -0
  132. package/dist/toolkit/dist/typed/isString.js +9 -0
  133. package/dist/toolkit/dist/typed/isString.js.map +1 -0
  134. package/dist/toolkit/dist/typed/isWithin.cjs +2 -0
  135. package/dist/toolkit/dist/typed/isWithin.cjs.map +1 -0
  136. package/dist/toolkit/dist/typed/isWithin.js +10 -0
  137. package/dist/toolkit/dist/typed/isWithin.js.map +1 -0
  138. package/dist/toolkit/dist/typed/isZero.cjs +2 -0
  139. package/dist/toolkit/dist/typed/isZero.cjs.map +1 -0
  140. package/dist/toolkit/dist/typed/isZero.js +7 -0
  141. package/dist/toolkit/dist/typed/isZero.js.map +1 -0
  142. package/dist/toolkit/dist/typed/le.cjs +2 -0
  143. package/dist/toolkit/dist/typed/le.cjs.map +1 -0
  144. package/dist/toolkit/dist/typed/le.js +7 -0
  145. package/dist/toolkit/dist/typed/le.js.map +1 -0
  146. package/dist/toolkit/dist/typed/lt.cjs +2 -0
  147. package/dist/toolkit/dist/typed/lt.cjs.map +1 -0
  148. package/dist/toolkit/dist/typed/lt.js +7 -0
  149. package/dist/toolkit/dist/typed/lt.js.map +1 -0
  150. package/dist/toolkit/dist/typed/typeOf.cjs +2 -0
  151. package/dist/toolkit/dist/typed/typeOf.cjs.map +1 -0
  152. package/dist/toolkit/dist/typed/typeOf.js +14 -0
  153. package/dist/toolkit/dist/typed/typeOf.js.map +1 -0
  154. package/package.json +39 -0
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const w=require("./logit/dist/logit.cjs");require("./toolkit/dist/logit/dist/logit.cjs");require("./toolkit/dist/array/filter.cjs");const f=require("./toolkit/dist/array/group.cjs"),S=require("./toolkit/dist/array/search.cjs"),A=require("./toolkit/dist/array/sortBy.cjs"),E=require("./toolkit/dist/math/max.cjs"),T=require("./toolkit/dist/math/min.cjs");class b{adapter;constructor(t){this.adapter=this.createAdapter(t)}createAdapter(t){if(!("type"in t))return t;const{type:e,dbName:r,version:s,schema:a,migrationFn:i}=t;switch(e){case"localStorage":return new m(r,s,a);case"indexedDB":return new g(r,s,a,i);default:throw new Error(`Unknown adapter type: ${e}`)}}bulkDelete(t,e){return this.adapter.bulkDelete(t,e)}bulkPut(t,e,r){return this.adapter.bulkPut(t,e,r)}clear(t){return this.adapter.clear(t)}count(t){return this.adapter.count(t)}delete(t,e){return this.adapter.delete(t,e)}get(t,e,r){return this.adapter.get(t,e,r)}getAll(t){return this.adapter.getAll(t)}put(t,e,r){return this.adapter.put(t,e,r)}query(t){return new d(this.adapter,String(t))}async transaction(t,e,r){const s=await this.loadStores(t),a=this.createStoreProxy(s);try{await e(a),await this.commitStores(t,a,r)}catch(i){throw new Error("Transaction failed",{cause:i})}}async loadStores(t){const e={},r=t.map(async s=>{e[s]=await this.getAll(s)});return await Promise.all(r),e}createStoreProxy(t){return new Proxy(t,{get(e,r){return e[r]},set(e,r,s){return e[r]=s,!0}})}async commitStores(t,e,r){const s=t.map(async a=>{await this.clear(a),await this.bulkPut(a,e[a],r)});await Promise.all(s)}async patch(t,e){const r=e.map(s=>this.applyPatch(t,s));await Promise.all(r)}async applyPatch(t,e){switch(e.type){case"put":return this.put(t,e.value,e.ttl);case"delete":return this.delete(t,e.key);case"clear":return this.clear(t)}}}class d{operations=[];adapter;table;memoCache=new Map;dataVersion=0;hasMutatingOp=!1;cachedSignature=null;constructor(t,e){this.adapter=t,this.table=e}getOpSignature(){return this.cachedSignature===null&&(this.cachedSignature=this.operations.map(t=>`${t.name}:${JSON.stringify(t.args)}`).join("|")),this.cachedSignature}getMemoKey(){return`${this.getOpSignature()}|v${this.dataVersion}`}invalidateMemo(t){if(!t){this.memoCache.clear();return}const e=Array.from(this.memoCache.keys()).filter(t);for(const r of e)this.memoCache.delete(r)}pushOp(t,e="op",r=[]){this.operations.push({args:r,name:e,op:t}),this.cachedSignature=null;const s=this.getOpSignature();return this.invalidateMemo(a=>a.startsWith(s)),this}where(t,e){return this.pushOp(r=>r.filter(s=>e(s[t],s)),"where",[t,e])}equals(t,e){return this.pushOp(r=>r.filter(s=>s[t]===e),"equals",[t,e])}between(t,e,r){return this.pushOp(s=>s.filter(a=>{const i=a[t];return i>=e&&i<=r}),"between",[t,e,r])}startsWith(t,e,r=!1){const s=r?e.toLowerCase():e;return this.pushOp(a=>a.filter(i=>{const n=i[t];return typeof n!="string"?!1:(r?n.toLowerCase():n).startsWith(s)}),"startsWith",[t,e,r])}filter(t){return this.pushOp(e=>e.filter(t),"filter",[t])}not(t){return this.pushOp(e=>e.filter((r,s,a)=>!t(r,s,a)),"not",[t])}and(...t){return this.pushOp(e=>e.filter((r,s,a)=>t.every(i=>i(r,s,a))),"and",t)}or(...t){return this.pushOp(e=>e.filter((r,s,a)=>t.some(i=>i(r,s,a))),"or",t)}orderBy(t,e="asc"){return this.pushOp(r=>A.sortBy(r,{[t]:e}),"orderBy",[t,e])}limit(t){return this.pushOp(e=>e.slice(0,t),"limit",[t])}offset(t){return this.pushOp(e=>e.slice(t),"offset",[t])}page(t,e){return this.pushOp(r=>{const s=(t-1)*e,a=s+e;return r.slice(s,a)},"page",[t,e])}reverse(){return this.pushOp(t=>[...t].reverse(),"reverse",[])}async count(){return(await this.toArray()).length}async first(){return(await this.toArray())[0]}async last(){const t=await this.toArray();return t[t.length-1]}async average(t){const e=await this.toArray();return e.length===0?0:e.reduce((s,a)=>s+(Number(a[t])||0),0)/e.length}async min(t){return T.min(await this.toArray(),e=>e[t])}async max(t){return E.max(await this.toArray(),e=>e[t])}async sum(t){return(await this.toArray()).reduce((r,s)=>r+(Number(s[t])||0),0)}modify(t,e){return this.hasMutatingOp=!0,this.dataVersion++,this.invalidateModifyCache(e),this.pushOp(r=>r.map(s=>t(s)??s),"modify",[t])}invalidateModifyCache(t){if(!t?.field){this.invalidateMemo(r=>r.includes("modify"));return}const e=String(t.field);this.invalidateMemo(r=>r.includes(`"${e}"`)&&(t.value===void 0||r.includes(JSON.stringify(t.value))))}groupBy(t){return this.pushOp(e=>f.group(e,r=>r[t]))}search(t,e){return this.pushOp(r=>S.search(r,t,e))}reset(){return this.operations=[],this.hasMutatingOp=!1,this.cachedSignature=null,this.invalidateMemo(),this}async toArray(){const t=this.getMemoKey(),e=this.memoCache.get(t);if(e)return e;const r=this.executeOperations();return this.hasMutatingOp||this.memoCache.set(t,r),r}async executeOperations(){let e=(await this.adapter.getAll(this.table)).slice();for(const{op:r}of this.operations)e=r(e);return e}build(t){for(const e of t)this.applyCondition(e);return this}applyCondition(t){switch(t.type){case"equals":this.equals(t.field,t.value);break;case"between":this.between(t.field,t.lower,t.upper);break;case"startsWith":this.startsWith(t.field,t.value);break;case"where":this.where(t.field,t.fn);break;case"filter":this.filter(t.fn);break;case"orderBy":this.orderBy(t.field,t.value??"asc");break;case"limit":this.limit(t.value);break;case"offset":this.offset(t.value);break;case"page":this.page(t.pageNumber,t.pageSize);break;default:throw new Error(`Unknown query type: ${t.type}`)}}}class m{dbName;version;schema;constructor(t,e,r){this.dbName=t,this.version=e,this.schema=r}bulkDelete=o(async(t,e)=>{const r=e.map(s=>this.delete(t,s));await Promise.all(r)},"BULK_DELETE_FAILED");bulkPut=o(async(t,e,r)=>{const s=e.map(a=>this.put(t,a,r));await Promise.all(s)},"BULK_PUT_FAILED");clear=o(async t=>{const e=this.getStorageKey(t),r=this.getTableKeys(e);for(const s of r)localStorage.removeItem(s)},"CLEAR_FAILED");count=o(async t=>(await this.getAll(t)).length,"COUNT_FAILED");delete=o(async(t,e)=>{localStorage.removeItem(this.getStorageKey(t,String(e)))},"DELETE_FAILED");get=o(async(t,e,r)=>{const s=this.getStorageKey(t,String(e)),a=localStorage.getItem(s);if(!a)return r;try{const i=JSON.parse(a),n=Date.now();return u(i,n,async()=>await this.delete(t,e))??r}catch{return await this.delete(t,e),r}},"GET_FAILED");getAll=o(async t=>{const e=this.getStorageKey(t),r=Date.now(),s=this.getTableKeys(e),a=[];for(const i of s){const n=await this.parseStorageRecord(i,t,r);n&&a.push(n)}return a},"GET_ALL_FAILED");put=o(async(t,e,r)=>{const s=this.getRecordKey(e,t);if(s===void 0)throw new Error("Missing key for localStorage put");localStorage.setItem(this.getStorageKey(t,String(s)),JSON.stringify(p(e,r)))},"PUT_FAILED");getTableKeys(t){return Object.keys(localStorage).filter(e=>e.startsWith(t))}async parseStorageRecord(t,e,r){try{const s=JSON.parse(localStorage.getItem(t)??"{}");return u(s,r,async()=>{const a=this.extractKeyFromStorageKey(t);await this.delete(e,a)})}catch(s){const a=this.extractKeyFromStorageKey(t);throw await this.delete(e,a),new Error(`Corrupted JSON for key: ${t}`,{cause:s})}}extractKeyFromStorageKey(t){const e=t.split(":");return e[e.length-1]}getRecordKey(t,e){const r=String(this.schema[e].key);return t[r]}getStorageKey(t,e){const r=`${this.dbName}:${this.version}:${String(t)}:`;return e===void 0||e===""?r:`${r}${String(e)}`}}class g{db=null;dbName;schema;version;migrationFn;constructor(t,e,r,s){this.dbName=t,this.version=e,this.schema=r,this.migrationFn=s}bulkDelete=o(async(t,e)=>{await this.withTransaction(t,"readwrite",async r=>{const s=e.map(a=>this.requestToPromise(r.delete(a)));await Promise.all(s)})},"BULK_DELETE_FAILED");bulkPut=o(async(t,e,r)=>{await this.withTransaction(t,"readwrite",async s=>{const a=e.map(i=>this.requestToPromise(s.put(p(i,r))));await Promise.all(a)})},"BULK_PUT_FAILED");clear=o(async t=>{await this.withTransaction(t,"readwrite",async e=>{await this.requestToPromise(e.clear())})},"CLEAR_FAILED");async connect(){return new Promise((t,e)=>{const r=indexedDB.open(this.dbName,this.version);r.onupgradeneeded=s=>{const a=r.result,i=r.transaction;this.createObjectStores(a),this.executeMigration(a,s,i,e)},r.onsuccess=()=>{this.db=r.result,t()},r.onerror=()=>e(new Error("Failed to open IndexedDB"))})}createObjectStores(t){for(const[e,r]of Object.entries(this.schema)){if(t.objectStoreNames.contains(e))continue;const s=r.key,a=t.createObjectStore(e,{keyPath:s}),i=r.indexes;if(i)for(const n of i)a.createIndex(n,n)}}executeMigration(t,e,r,s){if(this.migrationFn)try{const a=this.migrationFn(t,e.oldVersion,e.newVersion??null,r,this.schema);a&&typeof a.then=="function"&&a.catch(i=>{this.abortTransaction(r),s(new Error("Migration failed",{cause:i}))})}catch(a){this.abortTransaction(r),s(new Error("Migration failed",{cause:a}))}}abortTransaction(t){o(()=>t.abort(),"TRANSACTION_ABORT_FAILED")()}count=o(async t=>(await this.getAll(t)).length,"COUNT_FAILED");delete=o(async(t,e)=>{await this.withTransaction(t,"readwrite",async r=>{await this.requestToPromise(r.delete(e))})},"DELETE_FAILED");get=o(async(t,e,r)=>await this.withTransaction(t,"readonly",async s=>{const a=await this.requestToPromise(s.get(e));if(!a)return r;const i=Date.now();return u(a,i,async()=>await this.delete(t,e))??r}),"GET_FAILED");getAll=o(async t=>await this.withTransaction(t,"readonly",async e=>{const r=await this.requestToPromise(e.getAll()),s=Date.now();return r.map(a=>u(a,s)).filter(a=>a!==void 0)}),"GET_ALL_FAILED");put=o(async(t,e,r)=>{await this.withTransaction(t,"readwrite",async s=>{await this.requestToPromise(s.put(p(e,r)))})},"PUT_FAILED");async withTransaction(t,e,r){return this.db||await this.connect(),new Promise((s,a)=>{const i=Array.isArray(t)?t.map(String):[String(t)],n=this.db.transaction(i,e),l=n.objectStore(i[0]);let y;r(l).then(h=>{y=h}).catch(h=>{this.abortTransaction(n),a(h)}),n.oncomplete=()=>s(y),n.onerror=h=>a(h),n.onabort=h=>a(h)})}requestToPromise(t){return new Promise((e,r)=>{t.onsuccess=()=>e(t.result),t.onerror=()=>r(t.error??new Error("IndexedDB request failed"))})}}function p(c,t){return t===void 0?c:{...c,expiresAt:Date.now()+t}}function u(c,t,e){if(c.expiresAt===void 0)return c;if(t>=c.expiresAt){e?.();return}return c}function o(c,t="runSafe"){return((...e)=>{try{return c(...e)}catch(r){w.Logit.error(t,r)}})}exports.Deposit=b;exports.IndexedDBAdapter=g;exports.LocalStorageAdapter=m;exports.QueryBuilder=d;exports.runSafe=o;
2
+ //# sourceMappingURL=deposit.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deposit.cjs","sources":["../src/deposit.ts"],"sourcesContent":["/** biome-ignore-all lint/suspicious/noExplicitAny: - */\nimport { Logit } from '@vielzeug/logit';\nimport { group, max, min, type Predicate, search, sortBy } from '@vielzeug/toolkit';\n\nexport type DepotDataRecord<T, K extends keyof T = keyof T> = {\n indexes?: K[];\n key: K;\n record: T;\n};\n\ntype DataSchemaDef = Record<string, Record<string, unknown>>;\n\nexport type DepositDataSchema<S = DataSchemaDef> = {\n [K in keyof S]: DepotDataRecord<S[K], keyof S[K]>;\n};\n\nexport type DepositMigrationFn<S extends DepositDataSchema> = (\n db: IDBDatabase,\n oldVersion: number,\n newVersion: number | null,\n transaction: IDBTransaction,\n schema: S,\n) => void | Promise<void>;\n\nexport type DepositStorageAdapter<S extends DepositDataSchema> = {\n bulkDelete<K extends keyof S>(table: K, keys: KeyType<S, K>[]): Promise<void>;\n bulkPut<K extends keyof S>(table: K, values: S[K]['record'][], ttl?: number): Promise<void>;\n clear<K extends keyof S>(table: K): Promise<void>;\n count<K extends keyof S>(table: K): Promise<number>;\n delete<K extends keyof S>(table: K, key: KeyType<S, K>): Promise<void>;\n get<K extends keyof S, T extends S[K]['record']>(\n table: K,\n key: KeyType<S, K>,\n defaultValue?: T,\n ): Promise<T | undefined>;\n getAll<K extends keyof S>(table: K): Promise<S[K]['record'][]>;\n put<K extends keyof S>(table: K, value: S[K]['record'], ttl?: number): Promise<void>;\n connect?(): Promise<void>;\n};\n\ntype QueryCondition<T, K extends keyof T = keyof T> =\n | { type: 'equals'; field: K; value: T[K] }\n | { type: 'between'; field: K; lower: T[K]; upper: T[K] }\n | { type: 'startsWith'; field: Extract<K, string & keyof T>; value: string }\n | { type: 'where'; field: K; fn: (value: T[K], record: T) => boolean }\n | { type: 'filter'; fn: (record: T) => boolean }\n | { type: 'orderBy'; field: K; value?: 'asc' | 'desc' }\n | { type: 'limit'; value: number }\n | { type: 'offset'; value: number }\n | { type: 'page'; pageNumber: number; pageSize: number };\n\ntype PatchOperation<T, K = any> =\n | { type: 'put'; value: T; ttl?: number }\n | { type: 'delete'; key: K }\n | { type: 'clear' };\n\ntype KeyType<S extends DepositDataSchema, K extends keyof S> = S[K]['record'][S[K]['key']];\n\ntype AdapterConfig<S extends DepositDataSchema> = {\n type: 'localStorage' | 'indexedDB';\n dbName: string;\n version: number;\n schema: S;\n migrationFn?: DepositMigrationFn<S>;\n};\n\nexport class Deposit<S extends DepositDataSchema> {\n private readonly adapter: DepositStorageAdapter<S>;\n\n constructor(adapterOrConfig: DepositStorageAdapter<S> | AdapterConfig<S>) {\n this.adapter = this.createAdapter(adapterOrConfig);\n }\n\n private createAdapter(adapterOrConfig: DepositStorageAdapter<S> | AdapterConfig<S>): DepositStorageAdapter<S> {\n if (!('type' in adapterOrConfig)) {\n return adapterOrConfig;\n }\n\n const { type, dbName, version, schema, migrationFn } = adapterOrConfig;\n\n switch (type) {\n case 'localStorage':\n return new LocalStorageAdapter(dbName, version, schema);\n case 'indexedDB':\n return new IndexedDBAdapter(dbName, version, schema, migrationFn);\n default:\n throw new Error(`Unknown adapter type: ${type}`);\n }\n }\n\n bulkDelete<K extends keyof S>(table: K, keys: KeyType<S, K>[]) {\n return this.adapter.bulkDelete(table, keys);\n }\n\n bulkPut<K extends keyof S>(table: K, values: S[K]['record'][], ttl?: number) {\n return this.adapter.bulkPut(table, values, ttl);\n }\n\n clear<K extends keyof S>(table: K) {\n return this.adapter.clear(table);\n }\n\n count<K extends keyof S>(table: K): Promise<number> {\n return this.adapter.count(table);\n }\n\n delete<K extends keyof S>(table: K, key: KeyType<S, K>) {\n return this.adapter.delete(table, key);\n }\n\n get<K extends keyof S, T extends S[K]['record']>(\n table: K,\n key: KeyType<S, K>,\n defaultValue?: T,\n ): Promise<T | undefined> {\n return this.adapter.get(table, key, defaultValue);\n }\n\n getAll<K extends keyof S>(table: K): Promise<S[K]['record'][]> {\n return this.adapter.getAll(table);\n }\n\n put<K extends keyof S>(table: K, value: S[K]['record'], ttl?: number) {\n return this.adapter.put(table, value, ttl);\n }\n\n query<K extends keyof S>(table: K): QueryBuilder<S[K]['record']> {\n return new QueryBuilder<S[K]['record']>(this.adapter, String(table));\n }\n\n async transaction<K extends keyof S, T extends { [P in K]: S[P]['record'][] }>(\n tables: K[],\n fn: (stores: T) => Promise<void>,\n ttl?: number,\n ) {\n const storeMap = await this.loadStores<K, T>(tables);\n const proxy = this.createStoreProxy(storeMap);\n\n try {\n await fn(proxy as T);\n await this.commitStores(tables, proxy, ttl);\n } catch (err) {\n throw new Error('Transaction failed', { cause: err });\n }\n }\n\n private async loadStores<K extends keyof S, T extends { [P in K]: S[P]['record'][] }>(tables: K[]): Promise<T> {\n const storeMap = {} as T;\n const promises = tables.map(async (table) => {\n (storeMap as any)[table] = await this.getAll(table);\n });\n await Promise.all(promises);\n return storeMap;\n }\n\n private createStoreProxy<T extends Record<string, any>>(storeMap: T): T {\n return new Proxy(storeMap, {\n get(target, prop) {\n return target[prop as keyof T];\n },\n set(target, prop, value) {\n target[prop as keyof T] = value;\n return true;\n },\n }) as T;\n }\n\n private async commitStores<K extends keyof S, T extends { [P in K]: S[P]['record'][] }>(\n tables: K[],\n stores: T,\n ttl?: number,\n ): Promise<void> {\n const commits = tables.map(async (table) => {\n await this.clear(table);\n await this.bulkPut(table, stores[table], ttl);\n });\n await Promise.all(commits);\n }\n\n async patch<K extends keyof S>(table: K, patches: PatchOperation<S[K]['record'], KeyType<S, K>>[]): Promise<void> {\n const operations = patches.map((patch) => this.applyPatch(table, patch));\n await Promise.all(operations);\n }\n\n private async applyPatch<K extends keyof S>(\n table: K,\n patch: PatchOperation<S[K]['record'], KeyType<S, K>>,\n ): Promise<void> {\n switch (patch.type) {\n case 'put':\n return this.put(table, patch.value, patch.ttl);\n case 'delete':\n return this.delete(table, patch.key);\n case 'clear':\n return this.clear(table);\n }\n }\n}\n\n/** -------------------- QueryBuilder -------------------- **/\n\nexport class QueryBuilder<T extends Record<string, unknown>> {\n private operations: Array<{ op: (data: T[]) => T[]; name: string; args: unknown[] }> = [];\n private readonly adapter: DepositStorageAdapter<any>;\n private readonly table: string;\n private memoCache: Map<string, Promise<T[]>> = new Map();\n private dataVersion = 0;\n private hasMutatingOp = false;\n private cachedSignature: string | null = null;\n\n constructor(adapter: DepositStorageAdapter<any>, table: string) {\n this.adapter = adapter;\n this.table = table;\n }\n\n private getOpSignature(): string {\n if (this.cachedSignature === null) {\n this.cachedSignature = this.operations.map((o) => `${o.name}:${JSON.stringify(o.args)}`).join('|');\n }\n return this.cachedSignature;\n }\n\n private getMemoKey(): string {\n return `${this.getOpSignature()}|v${this.dataVersion}`;\n }\n\n private invalidateMemo(predicate?: (key: string) => boolean): void {\n if (!predicate) {\n this.memoCache.clear();\n return;\n }\n const keysToDelete = Array.from(this.memoCache.keys()).filter(predicate);\n for (const key of keysToDelete) {\n this.memoCache.delete(key);\n }\n }\n\n private pushOp(op: (data: T[]) => T[], name = 'op', args: unknown[] = []): this {\n this.operations.push({ args, name, op });\n this.cachedSignature = null; // Invalidate cached signature\n const opSignature = this.getOpSignature();\n this.invalidateMemo((key: string) => key.startsWith(opSignature));\n return this;\n }\n\n /** ---- Core select/where operations (no implicit state) ---- */\n\n where<K extends keyof T>(field: K, predicate: (value: T[K], record: T) => boolean): this {\n return this.pushOp((data) => data.filter((r) => predicate(r[field], r)), 'where', [field, predicate]);\n }\n\n equals<K extends keyof T>(field: K, value: T[K]): this {\n return this.pushOp((data) => data.filter((r) => r[field] === value), 'equals', [field, value]);\n }\n\n between<K extends keyof T>(field: K, lower: number, upper: number): this {\n return this.pushOp(\n (data) =>\n data.filter((r) => {\n const val = r[field] as any;\n return val >= lower && val <= upper;\n }),\n 'between',\n [field, lower, upper],\n );\n }\n\n startsWith<K extends keyof T>(field: K, prefix: string, ignoreCase = false): this {\n const lowerPrefix = ignoreCase ? prefix.toLowerCase() : prefix;\n return this.pushOp(\n (data) =>\n data.filter((r) => {\n const value = r[field];\n if (typeof value !== 'string') return false;\n const str = ignoreCase ? value.toLowerCase() : value;\n return str.startsWith(lowerPrefix);\n }),\n 'startsWith',\n [field, prefix, ignoreCase],\n );\n }\n\n filter(fn: Predicate<T>): this {\n return this.pushOp((data) => data.filter(fn), 'filter', [fn]);\n }\n\n not(fn: Predicate<T>): this {\n return this.pushOp((data) => data.filter((item, idx, arr) => !fn(item, idx, arr)), 'not', [fn]);\n }\n\n and(...fns: Array<Predicate<T>>): this {\n return this.pushOp((data) => data.filter((item, idx, arr) => fns.every((fn) => fn(item, idx, arr))), 'and', fns);\n }\n\n or(...fns: Array<Predicate<T>>): this {\n return this.pushOp((data) => data.filter((item, idx, arr) => fns.some((fn) => fn(item, idx, arr))), 'or', fns);\n }\n\n /** ---- Ordering / slicing ---- */\n\n orderBy<K extends keyof T>(field: K, direction: 'asc' | 'desc' = 'asc'): this {\n return this.pushOp(\n (data) => sortBy(data, { [field]: direction } as Partial<Record<keyof T, 'asc' | 'desc'>>) as T[],\n 'orderBy',\n [field, direction],\n );\n }\n\n limit(n: number): this {\n return this.pushOp((data) => data.slice(0, n), 'limit', [n]);\n }\n\n offset(n: number): this {\n return this.pushOp((data) => data.slice(n), 'offset', [n]);\n }\n\n page(pageNumber: number, pageSize: number): this {\n return this.pushOp(\n (data) => {\n const start = (pageNumber - 1) * pageSize;\n const end = start + pageSize;\n return data.slice(start, end);\n },\n 'page',\n [pageNumber, pageSize],\n );\n }\n\n reverse(): this {\n return this.pushOp((data) => [...data].reverse(), 'reverse', []);\n }\n\n /** ---- Aggregations ---- */\n\n async count(): Promise<number> {\n return (await this.toArray()).length;\n }\n\n async first(): Promise<T | undefined> {\n return (await this.toArray())[0];\n }\n\n async last(): Promise<T | undefined> {\n const arr = await this.toArray();\n return arr[arr.length - 1];\n }\n\n async average<K extends keyof T>(field: K): Promise<number> {\n const arr = await this.toArray();\n if (arr.length === 0) return 0;\n const total = arr.reduce((acc, item) => acc + (Number(item[field]) || 0), 0);\n return total / arr.length;\n }\n\n async min<K extends keyof T>(field: K): Promise<T | undefined> {\n return min(await this.toArray(), (item) => item[field] as any);\n }\n\n async max<K extends keyof T>(field: K): Promise<T | undefined> {\n return max(await this.toArray(), (item) => item[field] as any);\n }\n\n async sum<K extends keyof T>(field: K): Promise<number> {\n const arr = await this.toArray();\n return arr.reduce((acc, item) => acc + (Number(item[field]) || 0), 0);\n }\n\n /** ---- Transformations ---- */\n\n modify(callback: (record: T) => T | undefined, context?: { field: keyof T; value: unknown }): this {\n this.hasMutatingOp = true;\n this.dataVersion++;\n this.invalidateModifyCache(context);\n\n return this.pushOp((data) => data.map((item) => callback(item) ?? item), 'modify', [callback]);\n }\n\n private invalidateModifyCache(context?: { field: keyof T; value: unknown }): void {\n if (!context?.field) {\n this.invalidateMemo((key: string) => key.includes('modify'));\n return;\n }\n\n const fieldStr = String(context.field);\n this.invalidateMemo(\n (key: string) =>\n key.includes(`\"${fieldStr}\"`) && (context.value === undefined || key.includes(JSON.stringify(context.value))),\n );\n }\n\n groupBy<K extends keyof T>(field: K): this {\n return this.pushOp((data) => group(data, (item) => item[field] as any) as unknown as T[]);\n }\n\n search(query: string, tone?: number): this {\n return this.pushOp((data) => search(data as unknown as any[], query, tone) as unknown as T[]);\n }\n\n /** ---- Execution / state ---- */\n\n reset(): this {\n this.operations = [];\n this.hasMutatingOp = false;\n this.cachedSignature = null;\n this.invalidateMemo();\n return this;\n }\n\n async toArray(): Promise<T[]> {\n const key = this.getMemoKey();\n const cached = this.memoCache.get(key);\n if (cached) return cached;\n\n const promise = this.executeOperations();\n if (!this.hasMutatingOp) {\n this.memoCache.set(key, promise);\n }\n return promise;\n }\n\n private async executeOperations(): Promise<T[]> {\n const originalData = (await this.adapter.getAll(this.table)) as T[];\n let data = originalData.slice(); // Create a shallow copy\n\n for (const { op } of this.operations) {\n data = op(data);\n }\n\n return data;\n }\n\n /** ---- Query builder DSL (typed) ---- */\n\n build(conditions: Array<QueryCondition<T>>): this {\n for (const cond of conditions) {\n this.applyCondition(cond);\n }\n return this;\n }\n\n private applyCondition(cond: QueryCondition<T>): void {\n switch (cond.type) {\n case 'equals':\n this.equals(cond.field as any, cond.value as any);\n break;\n case 'between':\n this.between(cond.field as any, cond.lower as any, cond.upper as any);\n break;\n case 'startsWith':\n this.startsWith(cond.field as any, cond.value);\n break;\n case 'where':\n this.where(cond.field as any, cond.fn as any);\n break;\n case 'filter':\n this.filter(cond.fn);\n break;\n case 'orderBy':\n this.orderBy(cond.field as any, cond.value ?? 'asc');\n break;\n case 'limit':\n this.limit(cond.value);\n break;\n case 'offset':\n this.offset(cond.value);\n break;\n case 'page':\n this.page(cond.pageNumber, cond.pageSize);\n break;\n default:\n throw new Error(`Unknown query type: ${(cond as any).type}`);\n }\n }\n}\n\n/** -------------------- LocalStorageAdapter -------------------- **/\n\nexport class LocalStorageAdapter<S extends DepositDataSchema> implements DepositStorageAdapter<S> {\n private readonly dbName: string;\n private readonly version: number;\n private schema: S;\n\n constructor(dbName: string, version: number, schema: S) {\n this.dbName = dbName;\n this.version = version;\n this.schema = schema;\n }\n\n bulkDelete = runSafe(async <K extends keyof S>(table: K, keys: KeyType<S, K>[]) => {\n const promises = keys.map((key) => this.delete(table, key));\n await Promise.all(promises);\n }, 'BULK_DELETE_FAILED');\n\n bulkPut = runSafe(async <K extends keyof S>(table: K, values: S[K]['record'][], ttl?: number) => {\n const promises = values.map((v) => this.put(table, v, ttl));\n await Promise.all(promises);\n }, 'BULK_PUT_FAILED');\n\n clear = runSafe(async <K extends keyof S>(table: K) => {\n const prefix = this.getStorageKey(table);\n const keysToRemove = this.getTableKeys(prefix);\n for (const k of keysToRemove) {\n localStorage.removeItem(k);\n }\n }, 'CLEAR_FAILED');\n\n count = runSafe(async <K extends keyof S>(table: K): Promise<number> => {\n return (await this.getAll(table)).length;\n }, 'COUNT_FAILED');\n\n delete = runSafe(async <K extends keyof S>(table: K, key: KeyType<S, K>) => {\n localStorage.removeItem(this.getStorageKey(table, String(key)));\n }, 'DELETE_FAILED');\n\n get = runSafe(\n async <K extends keyof S, T extends S[K]['record']>(\n table: K,\n key: KeyType<S, K>,\n defaultValue?: T,\n ): Promise<T | undefined> => {\n const storageKey = this.getStorageKey(table, String(key));\n const item = localStorage.getItem(storageKey);\n if (!item) return defaultValue;\n\n try {\n const raw = JSON.parse(item);\n const now = Date.now();\n const value = unwrapWithExpiry<T>(raw, now, async () => await this.delete(table, key));\n return value ?? defaultValue;\n } catch {\n await this.delete(table, key);\n return defaultValue;\n }\n },\n 'GET_FAILED',\n );\n\n getAll = runSafe(async <K extends keyof S>(table: K): Promise<S[K]['record'][]> => {\n const prefix = this.getStorageKey(table);\n const now = Date.now();\n const keys = this.getTableKeys(prefix);\n const records: S[K]['record'][] = [];\n\n for (const k of keys) {\n const record = await this.parseStorageRecord<K>(k, table, now);\n if (record) {\n records.push(record);\n }\n }\n\n return records;\n }, 'GET_ALL_FAILED');\n\n put = runSafe(async <K extends keyof S>(table: K, value: S[K]['record'], ttl?: number) => {\n const key = this.getRecordKey(value, table);\n if (key === undefined) throw new Error('Missing key for localStorage put');\n localStorage.setItem(this.getStorageKey(table, String(key)), JSON.stringify(wrapWithExpiry(value, ttl)));\n }, 'PUT_FAILED');\n\n private getTableKeys(prefix: string): string[] {\n return Object.keys(localStorage).filter((k) => k.startsWith(prefix));\n }\n\n private async parseStorageRecord<K extends keyof S>(\n storageKey: string,\n table: K,\n now: number,\n ): Promise<S[K]['record'] | undefined> {\n try {\n const raw = JSON.parse(localStorage.getItem(storageKey) ?? '{}');\n return unwrapWithExpiry<S[K]['record']>(raw, now, async () => {\n const idPart = this.extractKeyFromStorageKey(storageKey);\n await this.delete(table, idPart as KeyType<S, typeof table>);\n });\n } catch (err) {\n const idPart = this.extractKeyFromStorageKey(storageKey);\n await this.delete(table, idPart as KeyType<S, typeof table>);\n throw new Error(`Corrupted JSON for key: ${storageKey}`, { cause: err });\n }\n }\n\n private extractKeyFromStorageKey(storageKey: string): string {\n const parts = storageKey.split(':');\n return parts[parts.length - 1];\n }\n\n private getRecordKey<K extends keyof S>(value: Record<string, unknown>, table: K): string | number | undefined {\n const keyField = String((this.schema[table] as DepotDataRecord<any>).key);\n return value[keyField] as string | number | undefined;\n }\n\n private getStorageKey<K extends keyof S>(table: K, key?: string | number): string {\n const prefix = `${this.dbName}:${this.version}:${String(table)}:`;\n return key === undefined || key === '' ? prefix : `${prefix}${String(key)}`;\n }\n}\n\n/** -------------------- IndexedDBAdapter -------------------- **/\n\nexport class IndexedDBAdapter<S extends DepositDataSchema> implements DepositStorageAdapter<S> {\n private db: IDBDatabase | null = null;\n private readonly dbName: string;\n private readonly schema: S;\n private readonly version: number;\n private readonly migrationFn?: DepositMigrationFn<S>;\n\n constructor(dbName: string, version: number, schema: S, migrationFn?: DepositMigrationFn<S>) {\n this.dbName = dbName;\n this.version = version;\n this.schema = schema;\n this.migrationFn = migrationFn;\n }\n\n bulkDelete = runSafe(async <K extends keyof S>(table: K, keys: KeyType<S, K>[]): Promise<void> => {\n await this.withTransaction(table, 'readwrite', async (store) => {\n const promises = keys.map((key) => this.requestToPromise(store.delete(key as IDBKeyRange)));\n await Promise.all(promises);\n });\n }, 'BULK_DELETE_FAILED');\n\n bulkPut = runSafe(async <K extends keyof S>(table: K, values: S[K]['record'][], ttl?: number): Promise<void> => {\n await this.withTransaction(table, 'readwrite', async (store) => {\n const promises = values.map((value) => this.requestToPromise(store.put(wrapWithExpiry(value, ttl))));\n await Promise.all(promises);\n });\n }, 'BULK_PUT_FAILED');\n\n clear = runSafe(async <K extends keyof S>(table: K): Promise<void> => {\n await this.withTransaction(table, 'readwrite', async (store) => {\n await this.requestToPromise(store.clear());\n });\n }, 'CLEAR_FAILED');\n\n async connect(): Promise<void> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(this.dbName, this.version);\n\n request.onupgradeneeded = (event) => {\n const db = request.result;\n const tx = request.transaction!;\n\n this.createObjectStores(db);\n this.executeMigration(db, event, tx, reject);\n };\n\n request.onsuccess = () => {\n this.db = request.result;\n resolve();\n };\n\n request.onerror = () => reject(new Error('Failed to open IndexedDB'));\n });\n }\n\n private createObjectStores(db: IDBDatabase): void {\n for (const [name, def] of Object.entries(this.schema)) {\n if (db.objectStoreNames.contains(name)) continue;\n\n const keyPath = (def as DepotDataRecord<any>).key as string;\n const store = db.createObjectStore(name, { keyPath });\n\n const indexes = (def as DepotDataRecord<any>).indexes;\n if (indexes) {\n for (const index of indexes) {\n store.createIndex(index as string, index as string);\n }\n }\n }\n }\n\n private executeMigration(\n db: IDBDatabase,\n event: IDBVersionChangeEvent,\n tx: IDBTransaction,\n reject: (error: Error) => void,\n ): void {\n if (!this.migrationFn) return;\n\n try {\n const result = this.migrationFn(db, event.oldVersion, (event as any).newVersion ?? null, tx, this.schema);\n\n if (result && typeof (result as Promise<void>).then === 'function') {\n (result as Promise<void>).catch((err) => {\n this.abortTransaction(tx);\n reject(new Error('Migration failed', { cause: err }));\n });\n }\n } catch (err) {\n this.abortTransaction(tx);\n reject(new Error('Migration failed', { cause: err }));\n }\n }\n\n private abortTransaction(tx: IDBTransaction): void {\n runSafe(() => tx.abort(), 'TRANSACTION_ABORT_FAILED')();\n }\n\n count = runSafe(async <K extends keyof S>(table: K): Promise<number> => {\n const records = await this.getAll(table);\n return records.length;\n }, 'COUNT_FAILED');\n\n delete = runSafe(async <K extends keyof S>(table: K, key: KeyType<S, K>): Promise<void> => {\n await this.withTransaction(table, 'readwrite', async (store) => {\n await this.requestToPromise(store.delete(key as IDBKeyRange));\n });\n }, 'DELETE_FAILED');\n\n get = runSafe(\n async <K extends keyof S, T extends S[K]['record']>(\n table: K,\n key: KeyType<S, K>,\n defaultValue?: T,\n ): Promise<T | undefined> => {\n return await this.withTransaction(table, 'readonly', async (store) => {\n const result = (await this.requestToPromise(store.get(key as IDBKeyRange))) as any;\n if (!result) return defaultValue;\n\n const now = Date.now();\n const value = unwrapWithExpiry<T>(result, now, async () => await this.delete(table, key));\n return value ?? defaultValue;\n });\n },\n 'GET_FAILED',\n );\n\n getAll = runSafe(async <K extends keyof S>(table: K): Promise<S[K]['record'][]> => {\n return await this.withTransaction(table, 'readonly', async (store) => {\n const result = await this.requestToPromise(store.getAll());\n const now = Date.now();\n return result\n .map((rec) => unwrapWithExpiry<S[K]['record']>(rec, now))\n .filter((v): v is S[K]['record'] => v !== undefined);\n });\n }, 'GET_ALL_FAILED');\n\n put = runSafe(async <K extends keyof S>(table: K, value: S[K]['record'], ttl?: number): Promise<void> => {\n await this.withTransaction(table, 'readwrite', async (store) => {\n await this.requestToPromise(store.put(wrapWithExpiry(value, ttl)));\n });\n }, 'PUT_FAILED');\n\n private async withTransaction<T>(\n tables: keyof S | (keyof S)[],\n mode: 'readonly' | 'readwrite',\n fn: (store: IDBObjectStore) => Promise<T>,\n ): Promise<T> {\n if (!this.db) await this.connect();\n\n return new Promise<T>((resolve, reject) => {\n const tableNames = Array.isArray(tables) ? tables.map(String) : [String(tables)];\n const tx = this.db!.transaction(tableNames, mode);\n const store = tx.objectStore(tableNames[0]);\n\n let result: T | undefined;\n\n fn(store)\n .then((r) => {\n result = r;\n })\n .catch((e) => {\n this.abortTransaction(tx);\n reject(e);\n });\n\n tx.oncomplete = () => resolve(result as T);\n tx.onerror = (event) => reject(event);\n tx.onabort = (event) => reject(event);\n });\n }\n\n private requestToPromise<R>(req: IDBRequest<R>): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n req.onsuccess = () => resolve(req.result);\n req.onerror = () => reject(req.error ?? new Error('IndexedDB request failed'));\n });\n }\n}\n\n/**\n * Wraps a value with an expiry timestamp if TTL is provided.\n */\nfunction wrapWithExpiry<T extends Record<string, unknown>>(value: T, ttl?: number): T & { expiresAt?: number } {\n if (ttl === undefined) return value;\n return { ...value, expiresAt: Date.now() + ttl };\n}\n\n/**\n * Unwraps a value from an expiry wrapper, returns undefined if expired.\n */\nfunction unwrapWithExpiry<T extends Record<string, unknown>>(\n value: T & { expiresAt?: number },\n now: number,\n onExpire?: () => Promise<void>,\n): T | undefined {\n if (value.expiresAt === undefined) return value;\n\n if (now >= value.expiresAt) {\n onExpire?.();\n return undefined;\n }\n\n return value;\n}\n\n/** -------------------- runSafe -------------------- **/\n\n/**\n * Wraps a function to suppress errors and log them to the console.\n */\nexport function runSafe<T extends (...args: any[]) => any>(fn: T, label = 'runSafe'): T {\n return ((...args: any[]) => {\n try {\n return fn(...args);\n } catch (err) {\n Logit.error(label, err);\n }\n }) as unknown as T;\n}\n"],"names":["Deposit","adapterOrConfig","type","dbName","version","schema","migrationFn","LocalStorageAdapter","IndexedDBAdapter","table","keys","values","ttl","key","defaultValue","value","QueryBuilder","tables","fn","storeMap","proxy","err","promises","target","prop","stores","commits","patches","operations","patch","adapter","o","predicate","keysToDelete","op","name","args","opSignature","field","data","r","lower","upper","val","prefix","ignoreCase","lowerPrefix","item","idx","arr","fns","direction","sortBy","n","pageNumber","pageSize","start","end","acc","min","max","callback","context","fieldStr","group","query","tone","search","cached","promise","conditions","cond","runSafe","v","keysToRemove","k","storageKey","raw","now","unwrapWithExpiry","records","record","wrapWithExpiry","idPart","parts","keyField","store","resolve","reject","request","event","db","tx","def","keyPath","indexes","index","result","rec","mode","tableNames","e","req","onExpire","label","Logit"],"mappings":"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"}
@@ -0,0 +1,503 @@
1
+ import { Logit as y } from "./logit/dist/logit.js";
2
+ import "./toolkit/dist/logit/dist/logit.js";
3
+ import "./toolkit/dist/array/filter.js";
4
+ import { group as d } from "./toolkit/dist/array/group.js";
5
+ import { search as w } from "./toolkit/dist/array/search.js";
6
+ import { sortBy as g } from "./toolkit/dist/array/sortBy.js";
7
+ import { max as f } from "./toolkit/dist/math/max.js";
8
+ import { min as S } from "./toolkit/dist/math/min.js";
9
+ class F {
10
+ adapter;
11
+ constructor(t) {
12
+ this.adapter = this.createAdapter(t);
13
+ }
14
+ createAdapter(t) {
15
+ if (!("type" in t))
16
+ return t;
17
+ const { type: e, dbName: r, version: s, schema: a, migrationFn: i } = t;
18
+ switch (e) {
19
+ case "localStorage":
20
+ return new E(r, s, a);
21
+ case "indexedDB":
22
+ return new T(r, s, a, i);
23
+ default:
24
+ throw new Error(`Unknown adapter type: ${e}`);
25
+ }
26
+ }
27
+ bulkDelete(t, e) {
28
+ return this.adapter.bulkDelete(t, e);
29
+ }
30
+ bulkPut(t, e, r) {
31
+ return this.adapter.bulkPut(t, e, r);
32
+ }
33
+ clear(t) {
34
+ return this.adapter.clear(t);
35
+ }
36
+ count(t) {
37
+ return this.adapter.count(t);
38
+ }
39
+ delete(t, e) {
40
+ return this.adapter.delete(t, e);
41
+ }
42
+ get(t, e, r) {
43
+ return this.adapter.get(t, e, r);
44
+ }
45
+ getAll(t) {
46
+ return this.adapter.getAll(t);
47
+ }
48
+ put(t, e, r) {
49
+ return this.adapter.put(t, e, r);
50
+ }
51
+ query(t) {
52
+ return new A(this.adapter, String(t));
53
+ }
54
+ async transaction(t, e, r) {
55
+ const s = await this.loadStores(t), a = this.createStoreProxy(s);
56
+ try {
57
+ await e(a), await this.commitStores(t, a, r);
58
+ } catch (i) {
59
+ throw new Error("Transaction failed", { cause: i });
60
+ }
61
+ }
62
+ async loadStores(t) {
63
+ const e = {}, r = t.map(async (s) => {
64
+ e[s] = await this.getAll(s);
65
+ });
66
+ return await Promise.all(r), e;
67
+ }
68
+ createStoreProxy(t) {
69
+ return new Proxy(t, {
70
+ get(e, r) {
71
+ return e[r];
72
+ },
73
+ set(e, r, s) {
74
+ return e[r] = s, !0;
75
+ }
76
+ });
77
+ }
78
+ async commitStores(t, e, r) {
79
+ const s = t.map(async (a) => {
80
+ await this.clear(a), await this.bulkPut(a, e[a], r);
81
+ });
82
+ await Promise.all(s);
83
+ }
84
+ async patch(t, e) {
85
+ const r = e.map((s) => this.applyPatch(t, s));
86
+ await Promise.all(r);
87
+ }
88
+ async applyPatch(t, e) {
89
+ switch (e.type) {
90
+ case "put":
91
+ return this.put(t, e.value, e.ttl);
92
+ case "delete":
93
+ return this.delete(t, e.key);
94
+ case "clear":
95
+ return this.clear(t);
96
+ }
97
+ }
98
+ }
99
+ class A {
100
+ operations = [];
101
+ adapter;
102
+ table;
103
+ memoCache = /* @__PURE__ */ new Map();
104
+ dataVersion = 0;
105
+ hasMutatingOp = !1;
106
+ cachedSignature = null;
107
+ constructor(t, e) {
108
+ this.adapter = t, this.table = e;
109
+ }
110
+ getOpSignature() {
111
+ return this.cachedSignature === null && (this.cachedSignature = this.operations.map((t) => `${t.name}:${JSON.stringify(t.args)}`).join("|")), this.cachedSignature;
112
+ }
113
+ getMemoKey() {
114
+ return `${this.getOpSignature()}|v${this.dataVersion}`;
115
+ }
116
+ invalidateMemo(t) {
117
+ if (!t) {
118
+ this.memoCache.clear();
119
+ return;
120
+ }
121
+ const e = Array.from(this.memoCache.keys()).filter(t);
122
+ for (const r of e)
123
+ this.memoCache.delete(r);
124
+ }
125
+ pushOp(t, e = "op", r = []) {
126
+ this.operations.push({ args: r, name: e, op: t }), this.cachedSignature = null;
127
+ const s = this.getOpSignature();
128
+ return this.invalidateMemo((a) => a.startsWith(s)), this;
129
+ }
130
+ /** ---- Core select/where operations (no implicit state) ---- */
131
+ where(t, e) {
132
+ return this.pushOp((r) => r.filter((s) => e(s[t], s)), "where", [t, e]);
133
+ }
134
+ equals(t, e) {
135
+ return this.pushOp((r) => r.filter((s) => s[t] === e), "equals", [t, e]);
136
+ }
137
+ between(t, e, r) {
138
+ return this.pushOp(
139
+ (s) => s.filter((a) => {
140
+ const i = a[t];
141
+ return i >= e && i <= r;
142
+ }),
143
+ "between",
144
+ [t, e, r]
145
+ );
146
+ }
147
+ startsWith(t, e, r = !1) {
148
+ const s = r ? e.toLowerCase() : e;
149
+ return this.pushOp(
150
+ (a) => a.filter((i) => {
151
+ const n = i[t];
152
+ return typeof n != "string" ? !1 : (r ? n.toLowerCase() : n).startsWith(s);
153
+ }),
154
+ "startsWith",
155
+ [t, e, r]
156
+ );
157
+ }
158
+ filter(t) {
159
+ return this.pushOp((e) => e.filter(t), "filter", [t]);
160
+ }
161
+ not(t) {
162
+ return this.pushOp((e) => e.filter((r, s, a) => !t(r, s, a)), "not", [t]);
163
+ }
164
+ and(...t) {
165
+ return this.pushOp((e) => e.filter((r, s, a) => t.every((i) => i(r, s, a))), "and", t);
166
+ }
167
+ or(...t) {
168
+ return this.pushOp((e) => e.filter((r, s, a) => t.some((i) => i(r, s, a))), "or", t);
169
+ }
170
+ /** ---- Ordering / slicing ---- */
171
+ orderBy(t, e = "asc") {
172
+ return this.pushOp(
173
+ (r) => g(r, { [t]: e }),
174
+ "orderBy",
175
+ [t, e]
176
+ );
177
+ }
178
+ limit(t) {
179
+ return this.pushOp((e) => e.slice(0, t), "limit", [t]);
180
+ }
181
+ offset(t) {
182
+ return this.pushOp((e) => e.slice(t), "offset", [t]);
183
+ }
184
+ page(t, e) {
185
+ return this.pushOp(
186
+ (r) => {
187
+ const s = (t - 1) * e, a = s + e;
188
+ return r.slice(s, a);
189
+ },
190
+ "page",
191
+ [t, e]
192
+ );
193
+ }
194
+ reverse() {
195
+ return this.pushOp((t) => [...t].reverse(), "reverse", []);
196
+ }
197
+ /** ---- Aggregations ---- */
198
+ async count() {
199
+ return (await this.toArray()).length;
200
+ }
201
+ async first() {
202
+ return (await this.toArray())[0];
203
+ }
204
+ async last() {
205
+ const t = await this.toArray();
206
+ return t[t.length - 1];
207
+ }
208
+ async average(t) {
209
+ const e = await this.toArray();
210
+ return e.length === 0 ? 0 : e.reduce((s, a) => s + (Number(a[t]) || 0), 0) / e.length;
211
+ }
212
+ async min(t) {
213
+ return S(await this.toArray(), (e) => e[t]);
214
+ }
215
+ async max(t) {
216
+ return f(await this.toArray(), (e) => e[t]);
217
+ }
218
+ async sum(t) {
219
+ return (await this.toArray()).reduce((r, s) => r + (Number(s[t]) || 0), 0);
220
+ }
221
+ /** ---- Transformations ---- */
222
+ modify(t, e) {
223
+ return this.hasMutatingOp = !0, this.dataVersion++, this.invalidateModifyCache(e), this.pushOp((r) => r.map((s) => t(s) ?? s), "modify", [t]);
224
+ }
225
+ invalidateModifyCache(t) {
226
+ if (!t?.field) {
227
+ this.invalidateMemo((r) => r.includes("modify"));
228
+ return;
229
+ }
230
+ const e = String(t.field);
231
+ this.invalidateMemo(
232
+ (r) => r.includes(`"${e}"`) && (t.value === void 0 || r.includes(JSON.stringify(t.value)))
233
+ );
234
+ }
235
+ groupBy(t) {
236
+ return this.pushOp((e) => d(e, (r) => r[t]));
237
+ }
238
+ search(t, e) {
239
+ return this.pushOp((r) => w(r, t, e));
240
+ }
241
+ /** ---- Execution / state ---- */
242
+ reset() {
243
+ return this.operations = [], this.hasMutatingOp = !1, this.cachedSignature = null, this.invalidateMemo(), this;
244
+ }
245
+ async toArray() {
246
+ const t = this.getMemoKey(), e = this.memoCache.get(t);
247
+ if (e) return e;
248
+ const r = this.executeOperations();
249
+ return this.hasMutatingOp || this.memoCache.set(t, r), r;
250
+ }
251
+ async executeOperations() {
252
+ let e = (await this.adapter.getAll(this.table)).slice();
253
+ for (const { op: r } of this.operations)
254
+ e = r(e);
255
+ return e;
256
+ }
257
+ /** ---- Query builder DSL (typed) ---- */
258
+ build(t) {
259
+ for (const e of t)
260
+ this.applyCondition(e);
261
+ return this;
262
+ }
263
+ applyCondition(t) {
264
+ switch (t.type) {
265
+ case "equals":
266
+ this.equals(t.field, t.value);
267
+ break;
268
+ case "between":
269
+ this.between(t.field, t.lower, t.upper);
270
+ break;
271
+ case "startsWith":
272
+ this.startsWith(t.field, t.value);
273
+ break;
274
+ case "where":
275
+ this.where(t.field, t.fn);
276
+ break;
277
+ case "filter":
278
+ this.filter(t.fn);
279
+ break;
280
+ case "orderBy":
281
+ this.orderBy(t.field, t.value ?? "asc");
282
+ break;
283
+ case "limit":
284
+ this.limit(t.value);
285
+ break;
286
+ case "offset":
287
+ this.offset(t.value);
288
+ break;
289
+ case "page":
290
+ this.page(t.pageNumber, t.pageSize);
291
+ break;
292
+ default:
293
+ throw new Error(`Unknown query type: ${t.type}`);
294
+ }
295
+ }
296
+ }
297
+ class E {
298
+ dbName;
299
+ version;
300
+ schema;
301
+ constructor(t, e, r) {
302
+ this.dbName = t, this.version = e, this.schema = r;
303
+ }
304
+ bulkDelete = o(async (t, e) => {
305
+ const r = e.map((s) => this.delete(t, s));
306
+ await Promise.all(r);
307
+ }, "BULK_DELETE_FAILED");
308
+ bulkPut = o(async (t, e, r) => {
309
+ const s = e.map((a) => this.put(t, a, r));
310
+ await Promise.all(s);
311
+ }, "BULK_PUT_FAILED");
312
+ clear = o(async (t) => {
313
+ const e = this.getStorageKey(t), r = this.getTableKeys(e);
314
+ for (const s of r)
315
+ localStorage.removeItem(s);
316
+ }, "CLEAR_FAILED");
317
+ count = o(async (t) => (await this.getAll(t)).length, "COUNT_FAILED");
318
+ delete = o(async (t, e) => {
319
+ localStorage.removeItem(this.getStorageKey(t, String(e)));
320
+ }, "DELETE_FAILED");
321
+ get = o(
322
+ async (t, e, r) => {
323
+ const s = this.getStorageKey(t, String(e)), a = localStorage.getItem(s);
324
+ if (!a) return r;
325
+ try {
326
+ const i = JSON.parse(a), n = Date.now();
327
+ return u(i, n, async () => await this.delete(t, e)) ?? r;
328
+ } catch {
329
+ return await this.delete(t, e), r;
330
+ }
331
+ },
332
+ "GET_FAILED"
333
+ );
334
+ getAll = o(async (t) => {
335
+ const e = this.getStorageKey(t), r = Date.now(), s = this.getTableKeys(e), a = [];
336
+ for (const i of s) {
337
+ const n = await this.parseStorageRecord(i, t, r);
338
+ n && a.push(n);
339
+ }
340
+ return a;
341
+ }, "GET_ALL_FAILED");
342
+ put = o(async (t, e, r) => {
343
+ const s = this.getRecordKey(e, t);
344
+ if (s === void 0) throw new Error("Missing key for localStorage put");
345
+ localStorage.setItem(this.getStorageKey(t, String(s)), JSON.stringify(p(e, r)));
346
+ }, "PUT_FAILED");
347
+ getTableKeys(t) {
348
+ return Object.keys(localStorage).filter((e) => e.startsWith(t));
349
+ }
350
+ async parseStorageRecord(t, e, r) {
351
+ try {
352
+ const s = JSON.parse(localStorage.getItem(t) ?? "{}");
353
+ return u(s, r, async () => {
354
+ const a = this.extractKeyFromStorageKey(t);
355
+ await this.delete(e, a);
356
+ });
357
+ } catch (s) {
358
+ const a = this.extractKeyFromStorageKey(t);
359
+ throw await this.delete(e, a), new Error(`Corrupted JSON for key: ${t}`, { cause: s });
360
+ }
361
+ }
362
+ extractKeyFromStorageKey(t) {
363
+ const e = t.split(":");
364
+ return e[e.length - 1];
365
+ }
366
+ getRecordKey(t, e) {
367
+ const r = String(this.schema[e].key);
368
+ return t[r];
369
+ }
370
+ getStorageKey(t, e) {
371
+ const r = `${this.dbName}:${this.version}:${String(t)}:`;
372
+ return e === void 0 || e === "" ? r : `${r}${String(e)}`;
373
+ }
374
+ }
375
+ class T {
376
+ db = null;
377
+ dbName;
378
+ schema;
379
+ version;
380
+ migrationFn;
381
+ constructor(t, e, r, s) {
382
+ this.dbName = t, this.version = e, this.schema = r, this.migrationFn = s;
383
+ }
384
+ bulkDelete = o(async (t, e) => {
385
+ await this.withTransaction(t, "readwrite", async (r) => {
386
+ const s = e.map((a) => this.requestToPromise(r.delete(a)));
387
+ await Promise.all(s);
388
+ });
389
+ }, "BULK_DELETE_FAILED");
390
+ bulkPut = o(async (t, e, r) => {
391
+ await this.withTransaction(t, "readwrite", async (s) => {
392
+ const a = e.map((i) => this.requestToPromise(s.put(p(i, r))));
393
+ await Promise.all(a);
394
+ });
395
+ }, "BULK_PUT_FAILED");
396
+ clear = o(async (t) => {
397
+ await this.withTransaction(t, "readwrite", async (e) => {
398
+ await this.requestToPromise(e.clear());
399
+ });
400
+ }, "CLEAR_FAILED");
401
+ async connect() {
402
+ return new Promise((t, e) => {
403
+ const r = indexedDB.open(this.dbName, this.version);
404
+ r.onupgradeneeded = (s) => {
405
+ const a = r.result, i = r.transaction;
406
+ this.createObjectStores(a), this.executeMigration(a, s, i, e);
407
+ }, r.onsuccess = () => {
408
+ this.db = r.result, t();
409
+ }, r.onerror = () => e(new Error("Failed to open IndexedDB"));
410
+ });
411
+ }
412
+ createObjectStores(t) {
413
+ for (const [e, r] of Object.entries(this.schema)) {
414
+ if (t.objectStoreNames.contains(e)) continue;
415
+ const s = r.key, a = t.createObjectStore(e, { keyPath: s }), i = r.indexes;
416
+ if (i)
417
+ for (const n of i)
418
+ a.createIndex(n, n);
419
+ }
420
+ }
421
+ executeMigration(t, e, r, s) {
422
+ if (this.migrationFn)
423
+ try {
424
+ const a = this.migrationFn(t, e.oldVersion, e.newVersion ?? null, r, this.schema);
425
+ a && typeof a.then == "function" && a.catch((i) => {
426
+ this.abortTransaction(r), s(new Error("Migration failed", { cause: i }));
427
+ });
428
+ } catch (a) {
429
+ this.abortTransaction(r), s(new Error("Migration failed", { cause: a }));
430
+ }
431
+ }
432
+ abortTransaction(t) {
433
+ o(() => t.abort(), "TRANSACTION_ABORT_FAILED")();
434
+ }
435
+ count = o(async (t) => (await this.getAll(t)).length, "COUNT_FAILED");
436
+ delete = o(async (t, e) => {
437
+ await this.withTransaction(t, "readwrite", async (r) => {
438
+ await this.requestToPromise(r.delete(e));
439
+ });
440
+ }, "DELETE_FAILED");
441
+ get = o(
442
+ async (t, e, r) => await this.withTransaction(t, "readonly", async (s) => {
443
+ const a = await this.requestToPromise(s.get(e));
444
+ if (!a) return r;
445
+ const i = Date.now();
446
+ return u(a, i, async () => await this.delete(t, e)) ?? r;
447
+ }),
448
+ "GET_FAILED"
449
+ );
450
+ getAll = o(async (t) => await this.withTransaction(t, "readonly", async (e) => {
451
+ const r = await this.requestToPromise(e.getAll()), s = Date.now();
452
+ return r.map((a) => u(a, s)).filter((a) => a !== void 0);
453
+ }), "GET_ALL_FAILED");
454
+ put = o(async (t, e, r) => {
455
+ await this.withTransaction(t, "readwrite", async (s) => {
456
+ await this.requestToPromise(s.put(p(e, r)));
457
+ });
458
+ }, "PUT_FAILED");
459
+ async withTransaction(t, e, r) {
460
+ return this.db || await this.connect(), new Promise((s, a) => {
461
+ const i = Array.isArray(t) ? t.map(String) : [String(t)], n = this.db.transaction(i, e), l = n.objectStore(i[0]);
462
+ let m;
463
+ r(l).then((h) => {
464
+ m = h;
465
+ }).catch((h) => {
466
+ this.abortTransaction(n), a(h);
467
+ }), n.oncomplete = () => s(m), n.onerror = (h) => a(h), n.onabort = (h) => a(h);
468
+ });
469
+ }
470
+ requestToPromise(t) {
471
+ return new Promise((e, r) => {
472
+ t.onsuccess = () => e(t.result), t.onerror = () => r(t.error ?? new Error("IndexedDB request failed"));
473
+ });
474
+ }
475
+ }
476
+ function p(c, t) {
477
+ return t === void 0 ? c : { ...c, expiresAt: Date.now() + t };
478
+ }
479
+ function u(c, t, e) {
480
+ if (c.expiresAt === void 0) return c;
481
+ if (t >= c.expiresAt) {
482
+ e?.();
483
+ return;
484
+ }
485
+ return c;
486
+ }
487
+ function o(c, t = "runSafe") {
488
+ return ((...e) => {
489
+ try {
490
+ return c(...e);
491
+ } catch (r) {
492
+ y.error(t, r);
493
+ }
494
+ });
495
+ }
496
+ export {
497
+ F as Deposit,
498
+ T as IndexedDBAdapter,
499
+ E as LocalStorageAdapter,
500
+ A as QueryBuilder,
501
+ o as runSafe
502
+ };
503
+ //# sourceMappingURL=deposit.js.map