[{"data":1,"prerenderedAt":2151},["ShallowReactive",2],{"navigation":3,"docs-path-index":230,"-docs-modules-cache-overview":302,"-docs-modules-cache-overview-surround":2146},[4],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":52},"Docs","i-lucide-book-marked","\u002Fdocs","docs",[10,26,53,191,212],{"title":11,"path":12,"stem":13,"children":14,"icon":25},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started\u002F1.index",[15,17,21],{"title":16,"path":12,"stem":13},"Introduction",{"title":18,"path":19,"stem":20},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F1.getting-started\u002F2.installation",{"title":22,"path":23,"stem":24},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F1.getting-started\u002F3.examples","i-lucide-rocket",{"title":27,"icon":28,"path":29,"stem":30,"children":31,"page":52},"Core features","i-lucide-square-function","\u002Fdocs\u002Fcore-features","docs\u002F2.core-features",[32,36,40,44,48],{"title":33,"path":34,"stem":35},"Configuration","\u002Fdocs\u002Fcore-features\u002Fconfiguration","docs\u002F2.core-features\u002F0.configuration",{"title":37,"path":38,"stem":39},"Dependency Injection","\u002Fdocs\u002Fcore-features\u002Fcontainer","docs\u002F2.core-features\u002F1.container",{"title":41,"path":42,"stem":43},"Controllers","\u002Fdocs\u002Fcore-features\u002Fcontrollers","docs\u002F2.core-features\u002F2.controllers",{"title":45,"path":46,"stem":47},"Middlewares","\u002Fdocs\u002Fcore-features\u002Fmiddlewares","docs\u002F2.core-features\u002F3.middlewares",{"title":49,"path":50,"stem":51},"Validation","\u002Fdocs\u002Fcore-features\u002Fvalidation","docs\u002F2.core-features\u002F4.validation",false,{"title":54,"icon":55,"defaultOpen":56,"path":57,"stem":58,"children":59,"page":52},"Modules","i-lucide-boxes",true,"\u002Fdocs\u002Fmodules","docs\u002F3.modules",[60,77,88,104,112,127,138,153,172,180],{"title":61,"icon":52,"defaultOpen":52,"path":62,"stem":63,"children":64,"page":52},"Auth","\u002Fdocs\u002Fmodules\u002Fauth","docs\u002F3.modules\u002F1.auth",[65,69,73],{"title":66,"path":67,"stem":68},"Overview","\u002Fdocs\u002Fmodules\u002Fauth\u002Foverview","docs\u002F3.modules\u002F1.auth\u002F0.overview",{"title":70,"path":71,"stem":72},"Decorators","\u002Fdocs\u002Fmodules\u002Fauth\u002Fdecorators","docs\u002F3.modules\u002F1.auth\u002F1.decorators",{"title":74,"path":75,"stem":76},"API Reference","\u002Fdocs\u002Fmodules\u002Fauth\u002Fapi","docs\u002F3.modules\u002F1.auth\u002F2.api",{"title":78,"icon":52,"defaultOpen":52,"path":79,"stem":80,"children":81,"page":52},"Devtools","\u002Fdocs\u002Fmodules\u002Fdevtools","docs\u002F3.modules\u002F10.devtools",[82,85],{"title":66,"path":83,"stem":84},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Foverview","docs\u002F3.modules\u002F10.devtools\u002F0.overview",{"title":33,"path":86,"stem":87},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002Fconfiguration","docs\u002F3.modules\u002F10.devtools\u002F1.configuration",{"title":89,"icon":52,"defaultOpen":52,"path":90,"stem":91,"children":92,"page":52},"Logger","\u002Fdocs\u002Fmodules\u002Flogger","docs\u002F3.modules\u002F2.logger",[93,96,100],{"title":66,"path":94,"stem":95},"\u002Fdocs\u002Fmodules\u002Flogger\u002Foverview","docs\u002F3.modules\u002F2.logger\u002F0.overview",{"title":97,"path":98,"stem":99},"Drains & Adapters","\u002Fdocs\u002Fmodules\u002Flogger\u002Fdrivers","docs\u002F3.modules\u002F2.logger\u002F1.drivers",{"title":101,"path":102,"stem":103},"API","\u002Fdocs\u002Fmodules\u002Flogger\u002Fapi","docs\u002F3.modules\u002F2.logger\u002F2.api",{"title":105,"icon":52,"defaultOpen":52,"path":106,"stem":107,"children":108,"page":52},"Serverless","\u002Fdocs\u002Fmodules\u002Fserverless","docs\u002F3.modules\u002F3.serverless",[109],{"title":66,"path":110,"stem":111},"\u002Fdocs\u002Fmodules\u002Fserverless\u002Foverview","docs\u002F3.modules\u002F3.serverless\u002F0.overview",{"title":113,"icon":52,"defaultOpen":52,"path":114,"stem":115,"children":116,"page":52},"Storage","\u002Fdocs\u002Fmodules\u002Fstorage","docs\u002F3.modules\u002F4.storage",[117,120,124],{"title":66,"path":118,"stem":119},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Foverview","docs\u002F3.modules\u002F4.storage\u002F0.overview",{"title":121,"path":122,"stem":123},"Drivers","\u002Fdocs\u002Fmodules\u002Fstorage\u002Fdrivers","docs\u002F3.modules\u002F4.storage\u002F1.drivers",{"title":101,"path":125,"stem":126},"\u002Fdocs\u002Fmodules\u002Fstorage\u002Fapi","docs\u002F3.modules\u002F4.storage\u002F2.api",{"title":128,"icon":52,"defaultOpen":52,"path":129,"stem":130,"children":131,"page":52},"Web Sockets","\u002Fdocs\u002Fmodules\u002Fweb-sockets","docs\u002F3.modules\u002F5.web-sockets",[132,135],{"title":66,"path":133,"stem":134},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Foverview","docs\u002F3.modules\u002F5.web-sockets\u002F0.overview",{"title":101,"path":136,"stem":137},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002Fapi","docs\u002F3.modules\u002F5.web-sockets\u002F1.api",{"title":139,"icon":52,"defaultOpen":52,"path":140,"stem":141,"children":142,"page":52},"Schema","\u002Fdocs\u002Fmodules\u002Fschema","docs\u002F3.modules\u002F6.schema",[143,146,149],{"title":66,"path":144,"stem":145},"\u002Fdocs\u002Fmodules\u002Fschema\u002Foverview","docs\u002F3.modules\u002F6.schema\u002F0.overview",{"title":70,"path":147,"stem":148},"\u002Fdocs\u002Fmodules\u002Fschema\u002Fdecorators","docs\u002F3.modules\u002F6.schema\u002F1.decorators",{"title":150,"path":151,"stem":152},"Scalar","\u002Fdocs\u002Fmodules\u002Fschema\u002Fscalar","docs\u002F3.modules\u002F6.schema\u002F2.scalar",{"title":154,"icon":52,"defaultOpen":52,"path":155,"stem":156,"children":157,"page":52},"Nitro","\u002Fdocs\u002Fmodules\u002Fnitro","docs\u002F3.modules\u002F7.nitro",[158,161,164,168],{"title":66,"path":159,"stem":160},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Foverview","docs\u002F3.modules\u002F7.nitro\u002F0.overview",{"title":113,"path":162,"stem":163},"\u002Fdocs\u002Fmodules\u002Fnitro\u002Fstorage","docs\u002F3.modules\u002F7.nitro\u002F1.storage",{"title":165,"path":166,"stem":167},"File-Based Routes","\u002Fdocs\u002Fmodules\u002Fnitro\u002Ffile-based-routes","docs\u002F3.modules\u002F7.nitro\u002F2.file-based-routes",{"title":169,"path":170,"stem":171},"Middleware","\u002Fdocs\u002Fmodules\u002Fnitro\u002Fmiddleware","docs\u002F3.modules\u002F7.nitro\u002F3.middleware",{"title":173,"icon":52,"defaultOpen":52,"path":174,"stem":175,"children":176,"page":52},"Vite","\u002Fdocs\u002Fmodules\u002Fvite","docs\u002F3.modules\u002F8.vite",[177],{"title":66,"path":178,"stem":179},"\u002Fdocs\u002Fmodules\u002Fvite\u002Foverview","docs\u002F3.modules\u002F8.vite\u002F0.overview",{"title":181,"icon":52,"defaultOpen":52,"path":182,"stem":183,"children":184,"page":52},"Cache","\u002Fdocs\u002Fmodules\u002Fcache","docs\u002F3.modules\u002F9.cache",[185,188],{"title":66,"path":186,"stem":187},"\u002Fdocs\u002Fmodules\u002Fcache\u002Foverview","docs\u002F3.modules\u002F9.cache\u002F0.overview",{"title":101,"path":189,"stem":190},"\u002Fdocs\u002Fmodules\u002Fcache\u002Fapi","docs\u002F3.modules\u002F9.cache\u002F1.api",{"title":192,"icon":193,"path":194,"stem":195,"children":196,"page":52},"Deployment","i-lucide-cloud-upload","\u002Fdocs\u002Fdeployment","docs\u002F4.deployment",[197,200,204,208],{"title":66,"path":198,"stem":199},"\u002Fdocs\u002Fdeployment\u002Foverview","docs\u002F4.deployment\u002F0.overview",{"title":201,"path":202,"stem":203},"Vercel","\u002Fdocs\u002Fdeployment\u002Fvercel","docs\u002F4.deployment\u002F1.vercel",{"title":205,"path":206,"stem":207},"AWS Lambda","\u002Fdocs\u002Fdeployment\u002Faws-lambda","docs\u002F4.deployment\u002F2.aws-lambda",{"title":209,"path":210,"stem":211},"Azure Functions","\u002Fdocs\u002Fdeployment\u002Fazure-functions","docs\u002F4.deployment\u002F3.azure-functions",{"title":213,"icon":214,"path":215,"stem":216,"children":217,"page":52},"Advanced","i-lucide-brain","\u002Fdocs\u002Fadvanced","docs\u002F99.advanced",[218,222,226],{"title":219,"path":220,"stem":221},"Custom Decorator","\u002Fdocs\u002Fadvanced\u002Fcustom-decorator","docs\u002F99.advanced\u002F1.custom-decorator",{"title":223,"path":224,"stem":225},"Plugins","\u002Fdocs\u002Fadvanced\u002Fcustom-plugin","docs\u002F99.advanced\u002F2.custom-plugin",{"title":227,"path":228,"stem":229},"Custom CLI Command","\u002Fdocs\u002Fadvanced\u002Fcustom-cli-command","docs\u002F99.advanced\u002F3.custom-cli-command",[231,233,235,236,237,238,240,241,242,243,244,245,247,249,250,251,252,254,255,256,258,259,260,261,263,264,266,267,268,269,271,272,273,275,276,277,278,280,281,282,283,284,286,287,289,290,291,293,294,295,296,297,299,300,301],{"path":232},"\u002Fdocs\u002F.navigation",{"path":234},"\u002Fdocs\u002Fgetting-started\u002F.navigation",{"path":12},{"path":19},{"path":23},{"path":239},"\u002Fdocs\u002Fcore-features\u002F.navigation",{"path":34},{"path":38},{"path":42},{"path":46},{"path":50},{"path":246},"\u002Fdocs\u002Fmodules\u002F.navigation",{"path":248},"\u002Fdocs\u002Fmodules\u002Fauth\u002F.navigation",{"path":67},{"path":71},{"path":75},{"path":253},"\u002Fdocs\u002Fmodules\u002Fdevtools\u002F.navigation",{"path":83},{"path":86},{"path":257},"\u002Fdocs\u002Fmodules\u002Flogger\u002F.navigation",{"path":94},{"path":98},{"path":102},{"path":262},"\u002Fdocs\u002Fmodules\u002Fserverless\u002F.navigation",{"path":110},{"path":265},"\u002Fdocs\u002Fmodules\u002Fstorage\u002F.navigation",{"path":118},{"path":122},{"path":125},{"path":270},"\u002Fdocs\u002Fmodules\u002Fweb-sockets\u002F.navigation",{"path":133},{"path":136},{"path":274},"\u002Fdocs\u002Fmodules\u002Fschema\u002F.navigation",{"path":144},{"path":147},{"path":151},{"path":279},"\u002Fdocs\u002Fmodules\u002Fnitro\u002F.navigation",{"path":159},{"path":162},{"path":166},{"path":170},{"path":285},"\u002Fdocs\u002Fmodules\u002Fvite\u002F.navigation",{"path":178},{"path":288},"\u002Fdocs\u002Fmodules\u002Fcache\u002F.navigation",{"path":186},{"path":189},{"path":292},"\u002Fdocs\u002Fdeployment\u002F.navigation",{"path":198},{"path":202},{"path":206},{"path":210},{"path":298},"\u002Fdocs\u002Fadvanced\u002F.navigation",{"path":220},{"path":224},{"path":228},{"id":303,"title":66,"body":304,"description":2140,"extension":2141,"links":2142,"meta":2143,"navigation":56,"path":186,"seo":2144,"stem":187,"__hash__":2145},"docs\u002Fdocs\u002F3.modules\u002F9.cache\u002F0.overview.md",{"type":305,"value":306,"toc":2130},"minimark",[307,315,319,394,398,1246,1250,1253,1261,1282,1288,1291,1295,1361,1499,1503,1510,1672,1675,1679,1682,1905,1911,1915,1918,2031,2040,2044,2126],[308,309,310,311,314],"p",{},"The Cache module turns any method into a cached one with a single decorator. It handles time-based expiration, stale-while-revalidate refreshes, concurrent call deduplication and automatic invalidation when your code changes - while keeping every entry inside a regular ",[312,313,113],"a",{"href":114}," instance, so memory, S3 or any other driver backs your cache without a line of glue code.",[316,317,18],"h2",{"id":318},"installation",[320,321,322,355,375],"code-group",{},[323,324,330],"pre",{"className":325,"code":326,"filename":327,"language":328,"meta":329,"style":329},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","$ pnpm add @vercube\u002Fcache @vercube\u002Fstorage\n","pnpm","bash","",[331,332,333],"code",{"__ignoreMap":329},[334,335,338,342,346,349,352],"span",{"class":336,"line":337},"line",1,[334,339,341],{"class":340},"sBMFI","$",[334,343,345],{"class":344},"sfazB"," pnpm",[334,347,348],{"class":344}," add",[334,350,351],{"class":344}," @vercube\u002Fcache",[334,353,354],{"class":344}," @vercube\u002Fstorage\n",[323,356,359],{"className":325,"code":357,"filename":358,"language":328,"meta":329,"style":329},"$ npm install @vercube\u002Fcache @vercube\u002Fstorage\n","npm",[331,360,361],{"__ignoreMap":329},[334,362,363,365,368,371,373],{"class":336,"line":337},[334,364,341],{"class":340},[334,366,367],{"class":344}," npm",[334,369,370],{"class":344}," install",[334,372,351],{"class":344},[334,374,354],{"class":344},[323,376,379],{"className":325,"code":377,"filename":378,"language":328,"meta":329,"style":329},"$ bun install @vercube\u002Fcache @vercube\u002Fstorage\n","bun",[331,380,381],{"__ignoreMap":329},[334,382,383,385,388,390,392],{"class":336,"line":337},[334,384,341],{"class":340},[334,386,387],{"class":344}," bun",[334,389,370],{"class":344},[334,391,351],{"class":344},[334,393,354],{"class":344},[316,395,397],{"id":396},"quick-start","Quick Start",[399,400,401,406,413,778,782,785,918,924,928,943],"steps",{},[402,403,405],"h3",{"id":404},"register-the-cache-in-your-container","Register the cache in your container",[308,407,408,409,412],{},"The Cache module stores everything through the Storage module, so bind both. Mounting a storage named ",[331,410,411],{},"cache"," keeps cached entries away from the rest of your data.",[323,414,419],{"className":415,"code":416,"filename":417,"language":418,"meta":329,"style":329},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { Container } from '@vercube\u002Fdi';\nimport { CacheManager } from '@vercube\u002Fcache';\nimport { StorageManager } from '@vercube\u002Fstorage';\nimport { MemoryStorage } from '@vercube\u002Fstorage\u002Fdrivers\u002FMemoryStorage';\n\nexport async function setupContainer(container: Container): Promise\u003Cvoid> {\n  container.bind(StorageManager);\n  container.bind(CacheManager);\n\n  const storageManager = container.get(StorageManager);\n  await storageManager.mount({ name: 'cache', storage: MemoryStorage });\n\n  \u002F\u002F application wide defaults, every cached function can override them\n  container.get(CacheManager).configure({\n    storage: 'cache',\n    maxAge: 60,\n  });\n}\n","src\u002Fcontainer.ts","ts",[331,420,421,453,476,499,522,528,575,598,616,621,649,694,699,706,731,748,762,772],{"__ignoreMap":329},[334,422,423,427,431,435,438,441,444,447,450],{"class":336,"line":337},[334,424,426],{"class":425},"s7zQu","import",[334,428,430],{"class":429},"sMK4o"," {",[334,432,434],{"class":433},"sTEyZ"," Container",[334,436,437],{"class":429}," }",[334,439,440],{"class":425}," from",[334,442,443],{"class":429}," '",[334,445,446],{"class":344},"@vercube\u002Fdi",[334,448,449],{"class":429},"'",[334,451,452],{"class":429},";\n",[334,454,456,458,460,463,465,467,469,472,474],{"class":336,"line":455},2,[334,457,426],{"class":425},[334,459,430],{"class":429},[334,461,462],{"class":433}," CacheManager",[334,464,437],{"class":429},[334,466,440],{"class":425},[334,468,443],{"class":429},[334,470,471],{"class":344},"@vercube\u002Fcache",[334,473,449],{"class":429},[334,475,452],{"class":429},[334,477,479,481,483,486,488,490,492,495,497],{"class":336,"line":478},3,[334,480,426],{"class":425},[334,482,430],{"class":429},[334,484,485],{"class":433}," StorageManager",[334,487,437],{"class":429},[334,489,440],{"class":425},[334,491,443],{"class":429},[334,493,494],{"class":344},"@vercube\u002Fstorage",[334,496,449],{"class":429},[334,498,452],{"class":429},[334,500,502,504,506,509,511,513,515,518,520],{"class":336,"line":501},4,[334,503,426],{"class":425},[334,505,430],{"class":429},[334,507,508],{"class":433}," MemoryStorage",[334,510,437],{"class":429},[334,512,440],{"class":425},[334,514,443],{"class":429},[334,516,517],{"class":344},"@vercube\u002Fstorage\u002Fdrivers\u002FMemoryStorage",[334,519,449],{"class":429},[334,521,452],{"class":429},[334,523,525],{"class":336,"line":524},5,[334,526,527],{"emptyLinePlaceholder":56},"\n",[334,529,531,534,538,541,545,548,552,555,557,560,563,566,569,572],{"class":336,"line":530},6,[334,532,533],{"class":425},"export",[334,535,537],{"class":536},"spNyl"," async",[334,539,540],{"class":536}," function",[334,542,544],{"class":543},"s2Zo4"," setupContainer",[334,546,547],{"class":429},"(",[334,549,551],{"class":550},"sHdIc","container",[334,553,554],{"class":429},":",[334,556,434],{"class":340},[334,558,559],{"class":429},"):",[334,561,562],{"class":340}," Promise",[334,564,565],{"class":429},"\u003C",[334,567,568],{"class":340},"void",[334,570,571],{"class":429},">",[334,573,574],{"class":429}," {\n",[334,576,578,581,584,587,590,593,596],{"class":336,"line":577},7,[334,579,580],{"class":433},"  container",[334,582,583],{"class":429},".",[334,585,586],{"class":543},"bind",[334,588,547],{"class":589},"swJcz",[334,591,592],{"class":433},"StorageManager",[334,594,595],{"class":589},")",[334,597,452],{"class":429},[334,599,601,603,605,607,609,612,614],{"class":336,"line":600},8,[334,602,580],{"class":433},[334,604,583],{"class":429},[334,606,586],{"class":543},[334,608,547],{"class":589},[334,610,611],{"class":433},"CacheManager",[334,613,595],{"class":589},[334,615,452],{"class":429},[334,617,619],{"class":336,"line":618},9,[334,620,527],{"emptyLinePlaceholder":56},[334,622,624,627,630,633,636,638,641,643,645,647],{"class":336,"line":623},10,[334,625,626],{"class":536},"  const",[334,628,629],{"class":433}," storageManager",[334,631,632],{"class":429}," =",[334,634,635],{"class":433}," container",[334,637,583],{"class":429},[334,639,640],{"class":543},"get",[334,642,547],{"class":589},[334,644,592],{"class":433},[334,646,595],{"class":589},[334,648,452],{"class":429},[334,650,652,655,657,659,662,664,667,670,672,674,676,678,681,684,686,688,690,692],{"class":336,"line":651},11,[334,653,654],{"class":425},"  await",[334,656,629],{"class":433},[334,658,583],{"class":429},[334,660,661],{"class":543},"mount",[334,663,547],{"class":589},[334,665,666],{"class":429},"{",[334,668,669],{"class":589}," name",[334,671,554],{"class":429},[334,673,443],{"class":429},[334,675,411],{"class":344},[334,677,449],{"class":429},[334,679,680],{"class":429},",",[334,682,683],{"class":589}," storage",[334,685,554],{"class":429},[334,687,508],{"class":433},[334,689,437],{"class":429},[334,691,595],{"class":589},[334,693,452],{"class":429},[334,695,697],{"class":336,"line":696},12,[334,698,527],{"emptyLinePlaceholder":56},[334,700,702],{"class":336,"line":701},13,[334,703,705],{"class":704},"sHwdD","  \u002F\u002F application wide defaults, every cached function can override them\n",[334,707,709,711,713,715,717,719,721,723,726,728],{"class":336,"line":708},14,[334,710,580],{"class":433},[334,712,583],{"class":429},[334,714,640],{"class":543},[334,716,547],{"class":589},[334,718,611],{"class":433},[334,720,595],{"class":589},[334,722,583],{"class":429},[334,724,725],{"class":543},"configure",[334,727,547],{"class":589},[334,729,730],{"class":429},"{\n",[334,732,734,737,739,741,743,745],{"class":336,"line":733},15,[334,735,736],{"class":589},"    storage",[334,738,554],{"class":429},[334,740,443],{"class":429},[334,742,411],{"class":344},[334,744,449],{"class":429},[334,746,747],{"class":429},",\n",[334,749,751,754,756,760],{"class":336,"line":750},16,[334,752,753],{"class":589},"    maxAge",[334,755,554],{"class":429},[334,757,759],{"class":758},"sbssI"," 60",[334,761,747],{"class":429},[334,763,765,768,770],{"class":336,"line":764},17,[334,766,767],{"class":429},"  }",[334,769,595],{"class":589},[334,771,452],{"class":429},[334,773,775],{"class":336,"line":774},18,[334,776,777],{"class":429},"}\n",[402,779,781],{"id":780},"cache-a-method","Cache a method",[308,783,784],{},"Decorate any method of a class registered in the container. The cache key is derived from the method's arguments, so every distinct set of arguments gets its own entry.",[323,786,789],{"className":415,"code":787,"filename":788,"language":418,"meta":329,"style":329},"import { Cache } from '@vercube\u002Fcache';\n\nexport class UsersService {\n  @Cache({ maxAge: 300 })\n  public async getUser(id: string): Promise\u003CUser> {\n    return this.database.findUser(id);\n  }\n}\n","src\u002Fservices\u002FUsersService.ts",[331,790,791,812,816,828,852,885,909,914],{"__ignoreMap":329},[334,792,793,795,797,800,802,804,806,808,810],{"class":336,"line":337},[334,794,426],{"class":425},[334,796,430],{"class":429},[334,798,799],{"class":433}," Cache",[334,801,437],{"class":429},[334,803,440],{"class":425},[334,805,443],{"class":429},[334,807,471],{"class":344},[334,809,449],{"class":429},[334,811,452],{"class":429},[334,813,814],{"class":336,"line":455},[334,815,527],{"emptyLinePlaceholder":56},[334,817,818,820,823,826],{"class":336,"line":478},[334,819,533],{"class":425},[334,821,822],{"class":536}," class",[334,824,825],{"class":340}," UsersService",[334,827,574],{"class":429},[334,829,830,833,835,837,839,842,844,847,849],{"class":336,"line":501},[334,831,832],{"class":429},"  @",[334,834,181],{"class":543},[334,836,547],{"class":433},[334,838,666],{"class":429},[334,840,841],{"class":589}," maxAge",[334,843,554],{"class":429},[334,845,846],{"class":758}," 300",[334,848,437],{"class":429},[334,850,851],{"class":433},")\n",[334,853,854,857,859,862,864,867,869,872,874,876,878,881,883],{"class":336,"line":524},[334,855,856],{"class":536},"  public",[334,858,537],{"class":536},[334,860,861],{"class":589}," getUser",[334,863,547],{"class":429},[334,865,866],{"class":550},"id",[334,868,554],{"class":429},[334,870,871],{"class":340}," string",[334,873,559],{"class":429},[334,875,562],{"class":340},[334,877,565],{"class":429},[334,879,880],{"class":340},"User",[334,882,571],{"class":429},[334,884,574],{"class":429},[334,886,887,890,893,896,898,901,903,905,907],{"class":336,"line":530},[334,888,889],{"class":425},"    return",[334,891,892],{"class":429}," this.",[334,894,895],{"class":433},"database",[334,897,583],{"class":429},[334,899,900],{"class":543},"findUser",[334,902,547],{"class":589},[334,904,866],{"class":433},[334,906,595],{"class":589},[334,908,452],{"class":429},[334,910,911],{"class":336,"line":577},[334,912,913],{"class":429},"  }\n",[334,915,916],{"class":336,"line":600},[334,917,777],{"class":429},[308,919,920,921,923],{},"That is the whole setup. The first call hits the database, every call within the next 5 minutes is served from the storage, and simultaneous calls for the same ",[331,922,866],{}," share a single database round trip.",[402,925,927],{"id":926},"invalidate-when-data-changes","Invalidate when data changes",[308,929,930,931,934,935,938,939,942],{},"Every decorated method gains ",[331,932,933],{},"invalidate()",", ",[331,936,937],{},"expire()"," and ",[331,940,941],{},"resolveKeys()"," helpers, keyed exactly like the cached calls - you never rebuild a cache key by hand.",[323,944,946],{"className":415,"code":945,"filename":788,"language":418,"meta":329,"style":329},"import { Cache } from '@vercube\u002Fcache';\nimport type { CacheTypes } from '@vercube\u002Fcache';\n\nexport class UsersService {\n  @Cache({ maxAge: 300 })\n  public async getUser(id: string): Promise\u003CUser> {\n    return this.database.findUser(id);\n  }\n\n  public async updateUser(id: string, patch: Partial\u003CUser>): Promise\u003CUser> {\n    const user = await this.database.updateUser(id, patch);\n\n    \u002F\u002F drop the cached entry for this user only\n    await (this.getUser as CacheTypes.CachedMethod\u003C[string], User>).invalidate(id);\n\n    return user;\n  }\n}\n",[331,947,948,968,992,996,1006,1026,1054,1074,1078,1082,1126,1160,1164,1169,1226,1230,1238,1242],{"__ignoreMap":329},[334,949,950,952,954,956,958,960,962,964,966],{"class":336,"line":337},[334,951,426],{"class":425},[334,953,430],{"class":429},[334,955,799],{"class":433},[334,957,437],{"class":429},[334,959,440],{"class":425},[334,961,443],{"class":429},[334,963,471],{"class":344},[334,965,449],{"class":429},[334,967,452],{"class":429},[334,969,970,972,975,977,980,982,984,986,988,990],{"class":336,"line":455},[334,971,426],{"class":425},[334,973,974],{"class":425}," type",[334,976,430],{"class":429},[334,978,979],{"class":433}," CacheTypes",[334,981,437],{"class":429},[334,983,440],{"class":425},[334,985,443],{"class":429},[334,987,471],{"class":344},[334,989,449],{"class":429},[334,991,452],{"class":429},[334,993,994],{"class":336,"line":478},[334,995,527],{"emptyLinePlaceholder":56},[334,997,998,1000,1002,1004],{"class":336,"line":501},[334,999,533],{"class":425},[334,1001,822],{"class":536},[334,1003,825],{"class":340},[334,1005,574],{"class":429},[334,1007,1008,1010,1012,1014,1016,1018,1020,1022,1024],{"class":336,"line":524},[334,1009,832],{"class":429},[334,1011,181],{"class":543},[334,1013,547],{"class":433},[334,1015,666],{"class":429},[334,1017,841],{"class":589},[334,1019,554],{"class":429},[334,1021,846],{"class":758},[334,1023,437],{"class":429},[334,1025,851],{"class":433},[334,1027,1028,1030,1032,1034,1036,1038,1040,1042,1044,1046,1048,1050,1052],{"class":336,"line":530},[334,1029,856],{"class":536},[334,1031,537],{"class":536},[334,1033,861],{"class":589},[334,1035,547],{"class":429},[334,1037,866],{"class":550},[334,1039,554],{"class":429},[334,1041,871],{"class":340},[334,1043,559],{"class":429},[334,1045,562],{"class":340},[334,1047,565],{"class":429},[334,1049,880],{"class":340},[334,1051,571],{"class":429},[334,1053,574],{"class":429},[334,1055,1056,1058,1060,1062,1064,1066,1068,1070,1072],{"class":336,"line":577},[334,1057,889],{"class":425},[334,1059,892],{"class":429},[334,1061,895],{"class":433},[334,1063,583],{"class":429},[334,1065,900],{"class":543},[334,1067,547],{"class":589},[334,1069,866],{"class":433},[334,1071,595],{"class":589},[334,1073,452],{"class":429},[334,1075,1076],{"class":336,"line":600},[334,1077,913],{"class":429},[334,1079,1080],{"class":336,"line":618},[334,1081,527],{"emptyLinePlaceholder":56},[334,1083,1084,1086,1088,1091,1093,1095,1097,1099,1101,1104,1106,1109,1111,1113,1116,1118,1120,1122,1124],{"class":336,"line":623},[334,1085,856],{"class":536},[334,1087,537],{"class":536},[334,1089,1090],{"class":589}," updateUser",[334,1092,547],{"class":429},[334,1094,866],{"class":550},[334,1096,554],{"class":429},[334,1098,871],{"class":340},[334,1100,680],{"class":429},[334,1102,1103],{"class":550}," patch",[334,1105,554],{"class":429},[334,1107,1108],{"class":340}," Partial",[334,1110,565],{"class":429},[334,1112,880],{"class":340},[334,1114,1115],{"class":429},">):",[334,1117,562],{"class":340},[334,1119,565],{"class":429},[334,1121,880],{"class":340},[334,1123,571],{"class":429},[334,1125,574],{"class":429},[334,1127,1128,1131,1134,1136,1139,1141,1143,1145,1148,1150,1152,1154,1156,1158],{"class":336,"line":651},[334,1129,1130],{"class":536},"    const",[334,1132,1133],{"class":433}," user",[334,1135,632],{"class":429},[334,1137,1138],{"class":425}," await",[334,1140,892],{"class":429},[334,1142,895],{"class":433},[334,1144,583],{"class":429},[334,1146,1147],{"class":543},"updateUser",[334,1149,547],{"class":589},[334,1151,866],{"class":433},[334,1153,680],{"class":429},[334,1155,1103],{"class":433},[334,1157,595],{"class":589},[334,1159,452],{"class":429},[334,1161,1162],{"class":336,"line":696},[334,1163,527],{"emptyLinePlaceholder":56},[334,1165,1166],{"class":336,"line":701},[334,1167,1168],{"class":704},"    \u002F\u002F drop the cached entry for this user only\n",[334,1170,1171,1174,1177,1180,1183,1186,1188,1190,1193,1195,1198,1201,1204,1206,1209,1211,1213,1215,1218,1220,1222,1224],{"class":336,"line":708},[334,1172,1173],{"class":425},"    await",[334,1175,1176],{"class":589}," (",[334,1178,1179],{"class":429},"this.",[334,1181,1182],{"class":433},"getUser",[334,1184,1185],{"class":425}," as",[334,1187,979],{"class":340},[334,1189,583],{"class":429},[334,1191,1192],{"class":340},"CachedMethod",[334,1194,565],{"class":429},[334,1196,1197],{"class":589},"[",[334,1199,1200],{"class":340},"string",[334,1202,1203],{"class":589},"]",[334,1205,680],{"class":429},[334,1207,1208],{"class":340}," User",[334,1210,571],{"class":429},[334,1212,595],{"class":589},[334,1214,583],{"class":429},[334,1216,1217],{"class":543},"invalidate",[334,1219,547],{"class":589},[334,1221,866],{"class":433},[334,1223,595],{"class":589},[334,1225,452],{"class":429},[334,1227,1228],{"class":336,"line":733},[334,1229,527],{"emptyLinePlaceholder":56},[334,1231,1232,1234,1236],{"class":336,"line":750},[334,1233,889],{"class":425},[334,1235,1133],{"class":433},[334,1237,452],{"class":429},[334,1239,1240],{"class":336,"line":764},[334,1241,913],{"class":429},[334,1243,1244],{"class":336,"line":774},[334,1245,777],{"class":429},[316,1247,1249],{"id":1248},"how-it-works","How it works",[308,1251,1252],{},"Cached entries are plain objects written into a mounted storage. Each cache key carries the storage it belongs to:",[323,1254,1259],{"className":1255,"code":1257,"language":1258},[1256],"language-text","\u002Fcache\u002F\u003Cstorage>:\u003Cgroup>:\u003Cname>:\u003Cargument-hash>.json   # a named storage\n\u002Fcache:\u003Cgroup>:\u003Cname>:\u003Cargument-hash>.json             # the default storage\n","text",[331,1260,1257],{"__ignoreMap":329},[308,1262,1263,1264,938,1267,1270,1271,1274,1275,1278,1279,583],{},"The ",[331,1265,1266],{},"\u003Cgroup>",[331,1268,1269],{},"\u003Cname>"," segments are sanitized: every character outside ",[331,1272,1273],{},"[A-Za-z0-9_]"," is dropped and a hash of the original is appended when that changes the value, so ",[331,1276,1277],{},"UsersService.getUser"," is stored as ",[331,1280,1281],{},"UsersServicegetUser.\u003Chash>",[308,1283,1284,1285,1287],{},"The Cache module resolves that prefix back to a mounted storage on every read and write, which means a single application can cache different things in different places - hot data in memory, shared data in a distributed storage - and inspect any of it through the regular ",[331,1286,592],{}," API.",[308,1289,1290],{},"If a cached function points at a storage nobody mounted, an in-memory one is mounted under that name on first use and a warning is logged. Caching therefore works with zero configuration, and mounting the name yourself is what swaps the backend for a real one.",[316,1292,1294],{"id":1293},"freshness","Freshness",[1296,1297,1298,1311],"table",{},[1299,1300,1301],"thead",{},[1302,1303,1304,1308],"tr",{},[1305,1306,1307],"th",{},"Option",[1305,1309,1310],{},"What it does",[1312,1313,1314,1328,1338,1348],"tbody",{},[1302,1315,1316,1322],{},[1317,1318,1319],"td",{},[331,1320,1321],{},"maxAge",[1317,1323,1324,1325,583],{},"Seconds an entry stays fresh. Defaults to ",[331,1326,1327],{},"1",[1302,1329,1330,1335],{},[1317,1331,1332],{},[331,1333,1334],{},"swr",[1317,1336,1337],{},"Serve a stale entry immediately and refresh it in the background.",[1302,1339,1340,1345],{},[1317,1341,1342],{},[331,1343,1344],{},"staleMaxAge",[1317,1346,1347],{},"How long a stale entry may still be served while revalidating.",[1302,1349,1350,1355],{},[1317,1351,1352],{},[331,1353,1354],{},"getMaxAge",[1317,1356,1357,1358,583],{},"Derive the lifetime from the resolved value, e.g. an OAuth token's ",[331,1359,1360],{},"expires_in",[323,1362,1364],{"className":415,"code":1363,"language":418,"meta":329,"style":329},"export class RatesService {\n  \u002F\u002F serve instantly for a minute, then keep serving the old value for up to\n  \u002F\u002F five more minutes while a fresh one is fetched in the background\n  @Cache({ maxAge: 60, swr: true, staleMaxAge: 300 })\n  public async getRates(currency: string): Promise\u003CRates> {\n    return this.http.get(`\u002Frates\u002F${currency}`);\n  }\n}\n",[331,1365,1366,1377,1382,1387,1427,1458,1491,1495],{"__ignoreMap":329},[334,1367,1368,1370,1372,1375],{"class":336,"line":337},[334,1369,533],{"class":425},[334,1371,822],{"class":536},[334,1373,1374],{"class":340}," RatesService",[334,1376,574],{"class":429},[334,1378,1379],{"class":336,"line":455},[334,1380,1381],{"class":704},"  \u002F\u002F serve instantly for a minute, then keep serving the old value for up to\n",[334,1383,1384],{"class":336,"line":478},[334,1385,1386],{"class":704},"  \u002F\u002F five more minutes while a fresh one is fetched in the background\n",[334,1388,1389,1391,1393,1395,1397,1399,1401,1403,1405,1408,1410,1414,1416,1419,1421,1423,1425],{"class":336,"line":501},[334,1390,832],{"class":429},[334,1392,181],{"class":543},[334,1394,547],{"class":433},[334,1396,666],{"class":429},[334,1398,841],{"class":589},[334,1400,554],{"class":429},[334,1402,759],{"class":758},[334,1404,680],{"class":429},[334,1406,1407],{"class":589}," swr",[334,1409,554],{"class":429},[334,1411,1413],{"class":1412},"sfNiH"," true",[334,1415,680],{"class":429},[334,1417,1418],{"class":589}," staleMaxAge",[334,1420,554],{"class":429},[334,1422,846],{"class":758},[334,1424,437],{"class":429},[334,1426,851],{"class":433},[334,1428,1429,1431,1433,1436,1438,1441,1443,1445,1447,1449,1451,1454,1456],{"class":336,"line":524},[334,1430,856],{"class":536},[334,1432,537],{"class":536},[334,1434,1435],{"class":589}," getRates",[334,1437,547],{"class":429},[334,1439,1440],{"class":550},"currency",[334,1442,554],{"class":429},[334,1444,871],{"class":340},[334,1446,559],{"class":429},[334,1448,562],{"class":340},[334,1450,565],{"class":429},[334,1452,1453],{"class":340},"Rates",[334,1455,571],{"class":429},[334,1457,574],{"class":429},[334,1459,1460,1462,1464,1467,1469,1471,1473,1476,1479,1482,1484,1487,1489],{"class":336,"line":530},[334,1461,889],{"class":425},[334,1463,892],{"class":429},[334,1465,1466],{"class":433},"http",[334,1468,583],{"class":429},[334,1470,640],{"class":543},[334,1472,547],{"class":589},[334,1474,1475],{"class":429},"`",[334,1477,1478],{"class":344},"\u002Frates\u002F",[334,1480,1481],{"class":429},"${",[334,1483,1440],{"class":433},[334,1485,1486],{"class":429},"}`",[334,1488,595],{"class":589},[334,1490,452],{"class":429},[334,1492,1493],{"class":336,"line":577},[334,1494,913],{"class":429},[334,1496,1497],{"class":336,"line":600},[334,1498,777],{"class":429},[316,1500,1502],{"id":1501},"cache-keys","Cache keys",[308,1504,1505,1506,1509],{},"By default the key is a hash of the method's arguments. That is the right behaviour for plain values (strings, numbers, POJOs), but arguments that are not stable to hash - a ",[331,1507,1508],{},"Request",", a stream, a class instance carrying a connection - should be projected into an explicit key:",[323,1511,1513],{"className":415,"code":1512,"language":418,"meta":329,"style":329},"export class ReportsController {\n  @Cache({\n    maxAge: 300,\n    getKey: (range: DateRange) => `${range.from}:${range.to}`,\n  })\n  public async report(range: DateRange, trace: TraceContext): Promise\u003CReport> {\n    return this.reports.build(range);\n  }\n}\n",[331,1514,1515,1526,1536,1546,1596,1602,1642,1664,1668],{"__ignoreMap":329},[334,1516,1517,1519,1521,1524],{"class":336,"line":337},[334,1518,533],{"class":425},[334,1520,822],{"class":536},[334,1522,1523],{"class":340}," ReportsController",[334,1525,574],{"class":429},[334,1527,1528,1530,1532,1534],{"class":336,"line":455},[334,1529,832],{"class":429},[334,1531,181],{"class":543},[334,1533,547],{"class":433},[334,1535,730],{"class":429},[334,1537,1538,1540,1542,1544],{"class":336,"line":478},[334,1539,753],{"class":589},[334,1541,554],{"class":429},[334,1543,846],{"class":758},[334,1545,747],{"class":429},[334,1547,1548,1551,1553,1555,1558,1560,1563,1565,1568,1571,1573,1575,1578,1581,1583,1585,1587,1589,1592,1594],{"class":336,"line":501},[334,1549,1550],{"class":543},"    getKey",[334,1552,554],{"class":429},[334,1554,1176],{"class":429},[334,1556,1557],{"class":550},"range",[334,1559,554],{"class":429},[334,1561,1562],{"class":340}," DateRange",[334,1564,595],{"class":429},[334,1566,1567],{"class":536}," =>",[334,1569,1570],{"class":429}," `${",[334,1572,1557],{"class":433},[334,1574,583],{"class":429},[334,1576,1577],{"class":433},"from",[334,1579,1580],{"class":429},"}",[334,1582,554],{"class":344},[334,1584,1481],{"class":429},[334,1586,1557],{"class":433},[334,1588,583],{"class":429},[334,1590,1591],{"class":433},"to",[334,1593,1486],{"class":429},[334,1595,747],{"class":429},[334,1597,1598,1600],{"class":336,"line":524},[334,1599,767],{"class":429},[334,1601,851],{"class":433},[334,1603,1604,1606,1608,1611,1613,1615,1617,1619,1621,1624,1626,1629,1631,1633,1635,1638,1640],{"class":336,"line":530},[334,1605,856],{"class":536},[334,1607,537],{"class":536},[334,1609,1610],{"class":589}," report",[334,1612,547],{"class":429},[334,1614,1557],{"class":550},[334,1616,554],{"class":429},[334,1618,1562],{"class":340},[334,1620,680],{"class":429},[334,1622,1623],{"class":550}," trace",[334,1625,554],{"class":429},[334,1627,1628],{"class":340}," TraceContext",[334,1630,559],{"class":429},[334,1632,562],{"class":340},[334,1634,565],{"class":429},[334,1636,1637],{"class":340},"Report",[334,1639,571],{"class":429},[334,1641,574],{"class":429},[334,1643,1644,1646,1648,1651,1653,1656,1658,1660,1662],{"class":336,"line":577},[334,1645,889],{"class":425},[334,1647,892],{"class":429},[334,1649,1650],{"class":433},"reports",[334,1652,583],{"class":429},[334,1654,1655],{"class":543},"build",[334,1657,547],{"class":589},[334,1659,1557],{"class":433},[334,1661,595],{"class":589},[334,1663,452],{"class":429},[334,1665,1666],{"class":336,"line":600},[334,1667,913],{"class":429},[334,1669,1670],{"class":336,"line":618},[334,1671,777],{"class":429},[308,1673,1674],{},"Entries also carry an integrity hash derived from the method body and its cache options. Changing either drops the old entries automatically, so a deploy never serves results produced by code that no longer exists.",[316,1676,1678],{"id":1677},"caching-controller-responses","Caching controller responses",[308,1680,1681],{},"A controller action is just a method, and by the time it runs its arguments are already the resolved route parameters. Decorating it caches the response keyed by those parameters:",[323,1683,1686],{"className":415,"code":1684,"filename":1685,"language":418,"meta":329,"style":329},"import { Cache } from '@vercube\u002Fcache';\nimport { Controller, Get, Param } from '@vercube\u002Fcore';\n\n@Controller('\u002Fproducts')\nexport class ProductsController {\n  @Get('\u002F:id')\n  @Cache({ maxAge: 120, swr: true, staleMaxAge: 600 })\n  public async getProduct(@Param('id') id: string): Promise\u003CProduct> {\n    return this.products.find(id);\n  }\n}\n","src\u002Fcontrollers\u002FProductsController.ts",[331,1687,1688,1708,1740,1744,1763,1774,1792,1830,1875,1897,1901],{"__ignoreMap":329},[334,1689,1690,1692,1694,1696,1698,1700,1702,1704,1706],{"class":336,"line":337},[334,1691,426],{"class":425},[334,1693,430],{"class":429},[334,1695,799],{"class":433},[334,1697,437],{"class":429},[334,1699,440],{"class":425},[334,1701,443],{"class":429},[334,1703,471],{"class":344},[334,1705,449],{"class":429},[334,1707,452],{"class":429},[334,1709,1710,1712,1714,1717,1719,1722,1724,1727,1729,1731,1733,1736,1738],{"class":336,"line":455},[334,1711,426],{"class":425},[334,1713,430],{"class":429},[334,1715,1716],{"class":433}," Controller",[334,1718,680],{"class":429},[334,1720,1721],{"class":433}," Get",[334,1723,680],{"class":429},[334,1725,1726],{"class":433}," Param",[334,1728,437],{"class":429},[334,1730,440],{"class":425},[334,1732,443],{"class":429},[334,1734,1735],{"class":344},"@vercube\u002Fcore",[334,1737,449],{"class":429},[334,1739,452],{"class":429},[334,1741,1742],{"class":336,"line":478},[334,1743,527],{"emptyLinePlaceholder":56},[334,1745,1746,1749,1752,1754,1756,1759,1761],{"class":336,"line":501},[334,1747,1748],{"class":429},"@",[334,1750,1751],{"class":543},"Controller",[334,1753,547],{"class":433},[334,1755,449],{"class":429},[334,1757,1758],{"class":344},"\u002Fproducts",[334,1760,449],{"class":429},[334,1762,851],{"class":433},[334,1764,1765,1767,1769,1772],{"class":336,"line":524},[334,1766,533],{"class":425},[334,1768,822],{"class":536},[334,1770,1771],{"class":340}," ProductsController",[334,1773,574],{"class":429},[334,1775,1776,1778,1781,1783,1785,1788,1790],{"class":336,"line":530},[334,1777,832],{"class":429},[334,1779,1780],{"class":543},"Get",[334,1782,547],{"class":433},[334,1784,449],{"class":429},[334,1786,1787],{"class":344},"\u002F:id",[334,1789,449],{"class":429},[334,1791,851],{"class":433},[334,1793,1794,1796,1798,1800,1802,1804,1806,1809,1811,1813,1815,1817,1819,1821,1823,1826,1828],{"class":336,"line":577},[334,1795,832],{"class":429},[334,1797,181],{"class":543},[334,1799,547],{"class":433},[334,1801,666],{"class":429},[334,1803,841],{"class":589},[334,1805,554],{"class":429},[334,1807,1808],{"class":758}," 120",[334,1810,680],{"class":429},[334,1812,1407],{"class":589},[334,1814,554],{"class":429},[334,1816,1413],{"class":1412},[334,1818,680],{"class":429},[334,1820,1418],{"class":589},[334,1822,554],{"class":429},[334,1824,1825],{"class":758}," 600",[334,1827,437],{"class":429},[334,1829,851],{"class":433},[334,1831,1832,1834,1836,1839,1842,1845,1847,1849,1851,1853,1856,1858,1860,1862,1864,1866,1868,1871,1873],{"class":336,"line":600},[334,1833,856],{"class":536},[334,1835,537],{"class":536},[334,1837,1838],{"class":589}," getProduct",[334,1840,1841],{"class":429},"(@",[334,1843,1844],{"class":543},"Param",[334,1846,547],{"class":433},[334,1848,449],{"class":429},[334,1850,866],{"class":344},[334,1852,449],{"class":429},[334,1854,1855],{"class":433},") ",[334,1857,866],{"class":550},[334,1859,554],{"class":429},[334,1861,871],{"class":340},[334,1863,559],{"class":429},[334,1865,562],{"class":340},[334,1867,565],{"class":429},[334,1869,1870],{"class":340},"Product",[334,1872,571],{"class":429},[334,1874,574],{"class":429},[334,1876,1877,1879,1881,1884,1886,1889,1891,1893,1895],{"class":336,"line":618},[334,1878,889],{"class":425},[334,1880,892],{"class":429},[334,1882,1883],{"class":433},"products",[334,1885,583],{"class":429},[334,1887,1888],{"class":543},"find",[334,1890,547],{"class":589},[334,1892,866],{"class":433},[334,1894,595],{"class":589},[334,1896,452],{"class":429},[334,1898,1899],{"class":336,"line":623},[334,1900,913],{"class":429},[334,1902,1903],{"class":336,"line":651},[334,1904,777],{"class":429},[1906,1907,1908],"warning",{},[308,1909,1910],{},"Only cache actions whose response depends purely on the arguments the method receives. An action that reads the authenticated user, a header or a cookie without taking it as an argument would serve one user's response to another - pass those values in as parameters so they become part of the key, or leave the action uncached.",[316,1912,1914],{"id":1913},"multi-tier-caching","Multi-tier caching",[308,1916,1917],{},"Passing several storages reads them in order and writes to all of them, which gives a fast local tier in front of a shared one:",[323,1919,1921],{"className":415,"code":1920,"language":418,"meta":329,"style":329},"export class CatalogService {\n  @Cache({ maxAge: 300, storage: ['memory', 'shared'] })\n  public async getCatalog(): Promise\u003CCatalog> {\n    return this.database.loadCatalog();\n  }\n}\n",[331,1922,1923,1934,1982,2005,2023,2027],{"__ignoreMap":329},[334,1924,1925,1927,1929,1932],{"class":336,"line":337},[334,1926,533],{"class":425},[334,1928,822],{"class":536},[334,1930,1931],{"class":340}," CatalogService",[334,1933,574],{"class":429},[334,1935,1936,1938,1940,1942,1944,1946,1948,1950,1952,1954,1956,1959,1961,1964,1966,1968,1970,1973,1975,1978,1980],{"class":336,"line":455},[334,1937,832],{"class":429},[334,1939,181],{"class":543},[334,1941,547],{"class":433},[334,1943,666],{"class":429},[334,1945,841],{"class":589},[334,1947,554],{"class":429},[334,1949,846],{"class":758},[334,1951,680],{"class":429},[334,1953,683],{"class":589},[334,1955,554],{"class":429},[334,1957,1958],{"class":433}," [",[334,1960,449],{"class":429},[334,1962,1963],{"class":344},"memory",[334,1965,449],{"class":429},[334,1967,680],{"class":429},[334,1969,443],{"class":429},[334,1971,1972],{"class":344},"shared",[334,1974,449],{"class":429},[334,1976,1977],{"class":433},"] ",[334,1979,1580],{"class":429},[334,1981,851],{"class":433},[334,1983,1984,1986,1988,1991,1994,1996,1998,2001,2003],{"class":336,"line":478},[334,1985,856],{"class":536},[334,1987,537],{"class":536},[334,1989,1990],{"class":589}," getCatalog",[334,1992,1993],{"class":429},"():",[334,1995,562],{"class":340},[334,1997,565],{"class":429},[334,1999,2000],{"class":340},"Catalog",[334,2002,571],{"class":429},[334,2004,574],{"class":429},[334,2006,2007,2009,2011,2013,2015,2018,2021],{"class":336,"line":501},[334,2008,889],{"class":425},[334,2010,892],{"class":429},[334,2012,895],{"class":433},[334,2014,583],{"class":429},[334,2016,2017],{"class":543},"loadCatalog",[334,2019,2020],{"class":589},"()",[334,2022,452],{"class":429},[334,2024,2025],{"class":336,"line":524},[334,2026,913],{"class":429},[334,2028,2029],{"class":336,"line":530},[334,2030,777],{"class":429},[308,2032,2033,2034,2036,2037,2039],{},"A read tries ",[331,2035,1963],{}," first and falls through to ",[331,2038,1972],{},". A resolved value is written to every tier.",[316,2041,2043],{"id":2042},"caveats","Caveats",[2045,2046,2047,2058,2069,2080,2091,2107],"ul",{},[2048,2049,2050,2053,2054,2057],"li",{},[331,2051,2052],{},"@Cache()"," works on classes registered in the container. Instances created with ",[331,2055,2056],{},"new"," by hand are not decorated.",[2048,2059,2060,2061,2064,2065,2068],{},"Cached entries are written to storage as-is, so the returned value must survive whatever serialization the driver applies. Use ",[331,2062,2063],{},"serialize"," \u002F ",[331,2066,2067],{},"transform"," for values that do not, such as streams or class instances.",[2048,2070,2071,2072,2075,2076,2079],{},"Expiration is enforced by the cache itself, so a driver that ignores the ",[331,2073,2074],{},"ttl"," hint (the built-in ",[331,2077,2078],{},"MemoryStorage"," does) still serves correct results - it just never evicts expired entries on its own.",[2048,2081,2082,2086,2087,2090],{},[2083,2084,2085],"strong",{},"Entries are shared between instances of the same class."," The key is built from the class name, the method name and the arguments - never from instance identity. If you register the same class twice with different constructor state (say two API clients pointing at different hosts), give each one an explicit ",[331,2088,2089],{},"name"," so they do not read each other's entries.",[2048,2092,2093,2096,2097,2099,2100,2103,2104,2106],{},[2083,2094,2095],{},"Minified builds mangle class names."," Since the default ",[331,2098,2089],{}," is ",[331,2101,2102],{},"ClassName.methodName",", two different classes can collapse onto the same name after minification and fight over one key. The integrity hash keeps you from being served the wrong data, but the hit rate collapses. Pass an explicit ",[331,2105,2089],{}," for anything shipped minified.",[2048,2108,2109,2112,2113,938,2116,2118,2119,2122,2123,2125],{},[2083,2110,2111],{},"A key built by hand will not match."," The ",[331,2114,2115],{},"group",[331,2117,2089],{}," segments are sanitized on the way into the key, so the stored key is not the one you would assemble from your own options. Ask ",[331,2120,2121],{},"CacheManager.resolveKeys()"," (or ",[331,2124,941],{}," on a cached function) for the real key.",[2127,2128,2129],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":329,"searchDepth":337,"depth":455,"links":2131},[2132,2133,2134,2135,2136,2137,2138,2139],{"id":318,"depth":455,"text":18},{"id":396,"depth":455,"text":397},{"id":1248,"depth":455,"text":1249},{"id":1293,"depth":455,"text":1294},{"id":1501,"depth":455,"text":1502},{"id":1677,"depth":455,"text":1678},{"id":1913,"depth":455,"text":1914},{"id":2042,"depth":455,"text":2043},"Decorator driven caching for Vercube applications, backed by the Storage module","md",null,{},{"title":66,"description":2140},"VJd6AS3AfJ9MGiOxuuQV6QoZHKU4RCG2flUrm-cCtIU",[2147,2149],{"title":66,"path":178,"stem":179,"description":2148,"children":-1},"Run Vercube as a Vite plugin using the Environment API",{"title":101,"path":189,"stem":190,"description":2150,"children":-1},"Complete API reference for Cache module",1787327654689]