@net-vert/core
Version:
Dependency Inversion Network Library with Type-Safe Injection.
2 lines (1 loc) • 10.9 kB
JavaScript
(function(u,w){typeof exports=="object"&&typeof module<"u"?w(exports,require("id-queue")):typeof define=="function"&&define.amd?define(["exports","id-queue"],w):(u=typeof globalThis<"u"?globalThis:u||self,w(u.netVertCore={},u.idQueue))})(this,function(u,w){"use strict";var p=(r=>(r.GET="get",r.POST="post",r.PUT="put",r.DELETE="delete",r))(p||{}),y=(r=>(r.CACHE="cache",r.RETRY="retry",r.IDEMPOTENT="idempotent",r.CONCURRENT="concurrent",r.SYNC="sync",r))(y||{});const N="default",E={retries:3,delay:0,retryCondition:()=>!0},P=r=>{const e={...E,...r};return Object.assign(async({config:n,next:s})=>{let o=0,a;for(;o<=e.retries;)try{return await s()}catch(i){if(a=i,o===e.retries)throw i;const c={config:n,lastResponse:i,attempt:o};if(!e.retryCondition(c))throw i;o++;const l=typeof e.delay=="function"?e.delay(c):e.delay;l>0&&await new Promise(d=>setTimeout(d,l))}throw a},{__middlewareType:y.RETRY})},B=()=>{const r=new Map;return{getPromise:o=>r.get(o),setPromise:(o,a)=>{r.set(o,a),a.finally(()=>r.delete(o))},delPromise:o=>r.delete(o),clearCache:()=>r.clear()}},K={key:r=>{const{config:e}=r,{method:t,url:n,data:s}=e;return[t,n,JSON.stringify(s)].join("|")}},V=r=>{const e={...K,...r},t=B();return Object.assign(({config:s,next:o})=>{const a=e.key({config:s}),i=t.getPromise(a);if(i)return i;const c=o();return t.setPromise(a,c),c},{__middlewareType:y.IDEMPOTENT,promiseCache:t})};class _{parallelCount;tasks;runningCount;constructor(e=4){this.parallelCount=e,this.tasks=new w.TaskQueue,this.runningCount=0}add(e,t){return new Promise((n,s)=>{this.tasks.enqueue(e,{task:t,resolve:n,reject:s}),this._run()})}remove(e){this.tasks.remove(e)}execute(e){const{task:t,resolve:n,reject:s}=e;return t().then(n).catch(s).finally(()=>{this.runningCount--,this._run()})}_run(){for(;this.runningCount<this.parallelCount&&this.tasks.size>0;){const e=this.tasks.dequeue();this.runningCount++,this.execute(e)}}}let A=0;const J={parallelCount:4,createId:()=>A++},x=r=>{const{parallelCount:e,createId:t}={...J,...r},n=new _(e);return Object.assign(({config:o,next:a})=>{const i=t({config:o});return n.add(i,()=>a())},{__middlewareType:y.CONCURRENT,pool:n})},O=new Map,f=(r,e)=>{O.set(e,r)};function z(r){const e=O.get(r);if(!e)throw new Error(`Store实例 ${String(r)} 未注册`);return e}class G{store=new Map;getItem(e){return this.store.get(e)}setItem(e,t){return this.store.set(e,t),t}removeItem(e){this.store.delete(e)}clear(){this.store.clear()}length(){return this.store.size}key(e){return Array.from(this.store.keys())[e]}keys(){return Array.from(this.store.keys())}iterate(e){let t=0;for(const[n,s]of this.store.entries())e(s,n,t),t++}}const U=r=>!!r&&(typeof r=="object"||typeof r=="function")&&typeof r.then=="function",q=r=>typeof window<"u"?r():{getItem(){return null},setItem(){},removeItem(){},clear(){},key(){return null},get length(){return 0}},h=q(()=>window.localStorage);class M{constructor(){}getItem(e){const t=String(e),n=h.getItem(t);if(n!==null)try{return JSON.parse(n)}catch(s){console.error(`Failed to parse value for key: ${t}`,s);return}}setItem(e,t){const n=String(e);try{h.setItem(n,JSON.stringify(t))}catch(s){throw console.error(`Failed to set value for key: ${n}`,s),s}return t}removeItem(e){const t=String(e);h.removeItem(t)}clear(){h.clear()}length(){return h.length}key(e){return h.key(e)}keys(){const e=[];for(let t=0;t<h.length;t++){const n=h.key(t);n&&e.push(n)}return e}iterate(e){this.keys().forEach((t,n)=>{const s=this.getItem(t);s!==void 0&&e(s,t,n)})}}const m=q(()=>window.sessionStorage);class Y{constructor(){}getItem(e){const t=String(e),n=m.getItem(t);if(n!==null)try{return JSON.parse(n)}catch(s){console.error(`Failed to parse value for key: ${t}`,s);return}}setItem(e,t){const n=String(e);try{m.setItem(n,JSON.stringify(t))}catch(s){throw console.error(`Failed to set value for key: ${n}`,s),s}return t}removeItem(e){const t=String(e);m.removeItem(t)}clear(){m.clear()}length(){return m.length}key(e){return m.key(e)}keys(){const e=[];for(let t=0;t<m.length;t++){const n=m.key(t);n&&e.push(n)}return e}iterate(e){this.keys().forEach((t,n)=>{const s=this.getItem(t);s!==void 0&&e(s,t,n)})}}class X{dbName;storeName;dbPromise=null;DB_VERSION=1;constructor(e,t){this.dbName=e,this.storeName=t,this.initDB()}initDB(){if(typeof window>"u"||!window.indexedDB){console.warn("IndexedDB is not available");return}this.dbPromise=new Promise((e,t)=>{const n=indexedDB.open(this.dbName,this.DB_VERSION);n.onerror=()=>{t(new Error(`Failed to open database: ${this.dbName}`))},n.onsuccess=()=>{e(n.result)},n.onupgradeneeded=s=>{const o=s.target.result;o.objectStoreNames.contains(this.storeName)||o.createObjectStore(this.storeName)}})}async getDB(){if(!this.dbPromise)throw new Error("IndexedDB is not initialized");return this.dbPromise}async withStore(e,t){const n=await this.getDB();return new Promise((s,o)=>{const a=n.transaction([this.storeName],e).objectStore(this.storeName),i=t(a);i.onsuccess=()=>{s(i.result)},i.onerror=()=>{o(i.error)}})}async getItem(e){try{const t=await this.withStore("readonly",n=>n.get(String(e)));return t===void 0?void 0:t}catch(t){console.error(`Failed to get value for key: ${String(e)}`,t);return}}async setItem(e,t){try{return await this.withStore("readwrite",n=>n.put(t,String(e))),t}catch(n){throw console.error(`Failed to set value for key: ${String(e)}`,n),n}}async removeItem(e){try{await this.withStore("readwrite",t=>t.delete(String(e)))}catch(t){throw console.error(`Failed to remove value for key: ${String(e)}`,t),t}}async clear(){try{await this.withStore("readwrite",e=>e.clear())}catch(e){throw console.error("Failed to clear storage",e),e}}async length(){try{return await this.withStore("readonly",e=>e.count())}catch(e){return console.error("Failed to get storage length",e),0}}async key(e){try{return(await this.withStore("readonly",t=>t.getAllKeys()))[e]}catch(t){console.error("Failed to get key",t);return}}async keys(){try{return await this.withStore("readonly",e=>e.getAllKeys())}catch(e){return console.error("Failed to get all keys",e),[]}}async iterate(e){try{const t=(await this.getDB()).transaction([this.storeName],"readonly").objectStore(this.storeName).openCursor();return new Promise((n,s)=>{let o=0;t.onsuccess=a=>{const i=a.target.result;if(i){const c=i.key,l=i.value;e(l,c,o),o++,i.continue()}else n()},t.onerror=()=>{s(t.error)}})}catch(t){console.error("Failed to iterate storage",t)}}}const g={memory:"memory",local:"local",session:"session",indexeddb:"indexeddb"};function j(r,e){Object.assign(r,e)}function Z(r){return j(r,{async getItemOrDefault(e,t){const n=await this.getItem(e);return n!==null?n:t},async hasItem(e){return await this.getItem(e)!==null},async removeItems(e){await Promise.all(e.map(t=>this.removeItem(t)))},async getItems(e){return await Promise.all(e.map(t=>this.getItem(t)))}}),r}function H(r){return j(r,{getItemOrDefault(e,t){const n=this.getItem(e);return n!==null?n:t},hasItem(e){return this.getItem(e)!==null},removeItems(e){e.forEach(t=>this.removeItem(t))},getItems(e){return e.map(t=>this.getItem(t))}}),r}function L(r){const e=r.getItem("");return U(e)?Z(r):H(r)}function C(r,...e){const t=z(r);let n;try{n=new t(...e)}catch{n=t(...e)}return L(n)}f(G,g.memory),f(M,g.local),f(Y,g.session),f(X,g.indexeddb);function I(r,e){return{value:r,expireAt:Date.now()+e}}function k(r,e=Date.now()){return r.expireAt<=e}function R(r,e=Date.now()){return k(r,e)?void 0:r.value}const Q=r=>{const{config:e}=r,{method:t,url:n,data:s}=e;return[t,n,JSON.stringify(s)].join("|")},W=()=>!0,S=24*60*60*1e3,ee={key:Q,duration:S,isValid:W,store:g.memory},te=class{store;constructor(e){return typeof e=="string"?this.store=C(e):(f(e.factory,e.key),this.store=C(e.key)),new Proxy(this,{get(t,n){if(n in t)return t[n];const s=t.store[n];return typeof s=="function"?s.bind(t.store):s}})}setCache(e,t,n=S){const s=I(t,n);this.store.setItem(e,s)}async getCache(e){const t=await this.store.getItem(e);if(t)return R(t)}async hasValidCache(e){const t=await this.store.getItem(e);return t?!k(t):!1}},T=r=>{const e={...ee,...r},t=new te(e.store),n=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(async({config:o,next:a})=>{const i=e.key({config:o}),c=await t.getCache(i);if(c){if(await e.isValid({key:i,config:o,cachedData:c}))return c;t.removeItem(i)}const l=await a(),d=n({key:i,config:o,cachedData:c,response:l}),v=I(l,d);return t.setItem(i,v),l},{__middlewareType:y.CACHE,storage:t})};class re{store;constructor(e){return typeof e=="string"?this.store=C(e):(f(e.factory,e.key),this.store=C(e.key)),new Proxy(this,{get(t,n){if(n in t)return t[n];const s=t.store[n];return typeof s=="function"?s.bind(t.store):s}})}setCache(e,t,n=S){const s=I(t,n);this.store.setItem(e,s)}getCache(e){const t=this.store.getItem(e);if(t)return R(t)}hasValidCache(e){const t=this.store.getItem(e);return t?!k(t):!1}}const ne=re,se={suspense:!0,key:r=>{const{config:e}=r,{method:t,url:n}=e;return[t,n].join("|")},duration:24*60*60*1e3,isValid:()=>!0,store:g.memory};function oe(r){const e={...se,...r},t=new ne(e.store),n=o=>typeof e.duration=="function"?e.duration(o):e.duration;return Object.assign(({config:o,next:a})=>{const i=e.key({config:o}),c=t.getCache(i);if(c){if(e.isValid({key:i,config:o,cachedData:c}))return c;t.removeItem(i)}if(e.suspense)throw(e.wrapSuspense?e.wrapSuspense({key:i,config:o,p:a()}):a()).then(d=>{const v=n({key:i,config:o,cachedData:c,response:d});return t.setCache(i,d,v),d});return a().then(l=>{const d=n({key:i,config:o,cachedData:c,response:l});return t.setCache(i,l,d),l})},{__middlewareType:y.SYNC})}const D=new Map,ie=(r,e=N)=>{D.set(e,r)},F=(r=N)=>{const e=D.get(r);if(!e)throw new Error(`Requestor实例 ${String(r)} 未注册`);return e},$={get:(r,e)=>({url:r,method:p.GET,...e,params:e?.params}),post:(r,e,t)=>({url:r,method:p.POST,data:e,...t}),delete:(r,e)=>({url:r,method:p.DELETE,...e}),put:(r,e,t)=>({url:r,method:p.PUT,data:e,...t}),request:r=>r},ae=Object.keys($);function ce(r,e,t){const n={},s=o=>{if(o===e.length)return t(r);const a=e[o];return a({config:r,ctx:n,next:()=>s(o+1)})};return s(0)}function ue(r,e){const t={},n=e??[];return ae.forEach(s=>{t[s]=(...o)=>{const a=$[s](...o);return ce(a,n,r)}}),t}function b(r){const{extensions:e,instanceKey:t}=r??{},n=F(t);return ue(n,e)}function le(r){const{instanceKey:e,key:t,duration:n,isValid:s,store:o,...a}=r;return b({instanceKey:e,extensions:[V(a),T({key:t,duration:n,isValid:s,store:o})]})}function de(r){const{instanceKey:e,parallelCount:t,createId:n,retries:s,delay:o,retryCondition:a}=r;return b({instanceKey:e,extensions:[x({parallelCount:t,createId:n}),P({retries:s,delay:o,retryCondition:a})]})}u.cache=T,u.concurrent=x,u.createCachedIdempotentRequestor=le,u.createConcurrentRetryRequestor=de,u.createRequestor=b,u.idempotent=V,u.inject=ie,u.retry=P,u.sync=oe,u.useRequestor=F,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})});