[{"data":1,"prerenderedAt":1333},["ShallowReactive",2],{"navigation":3,"-guide-functions":57,"-guide-functions-surround":1330},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":16},"Guide","\u002Fguide","1.guide\u002F1.index",[9,12,17,22,27,32,37,42,47,52],{"title":10,"path":6,"stem":7,"icon":11},"Getting Started","lucide:rocket",{"title":13,"path":14,"stem":15,"icon":16},"API Reference","\u002Fguide\u002Fapi","1.guide\u002F10.api","lucide:book-open",{"title":18,"path":19,"stem":20,"icon":21},"Caching Functions","\u002Fguide\u002Ffunctions","1.guide\u002F2.functions","lucide:square-function",{"title":23,"path":24,"stem":25,"icon":26},"Invalidation & Expiration","\u002Fguide\u002Finvalidation","1.guide\u002F3.invalidation","lucide:trash-2",{"title":28,"path":29,"stem":30,"icon":31},"Storage","\u002Fguide\u002Fstorage","1.guide\u002F4.storage","lucide:database",{"title":33,"path":34,"stem":35,"icon":36},"Caching HTTP Handlers","\u002Fguide\u002Fhandler","1.guide\u002F5.handler","lucide:server",{"title":38,"path":39,"stem":40,"icon":41},"Query Parameters","\u002Fguide\u002Fquery-params","1.guide\u002F6.query-params","lucide:link-2",{"title":43,"path":44,"stem":45,"icon":46},"Cookies","\u002Fguide\u002Fcookies","1.guide\u002F7.cookies","lucide:cookie",{"title":48,"path":49,"stem":50,"icon":51},"Cache-Control & Eligibility","\u002Fguide\u002Fcache-control","1.guide\u002F8.cache-control","lucide:sliders-horizontal",{"title":53,"path":54,"stem":55,"icon":56},"Incremental Static Regeneration","\u002Fguide\u002Fisr","1.guide\u002F9.isr","lucide:refresh-cw",{"id":58,"title":18,"body":59,"description":76,"extension":1325,"meta":1326,"navigation":1327,"path":19,"seo":1328,"stem":20,"__hash__":1329},"content\u002F1.guide\u002F2.functions.md",{"type":60,"value":61,"toc":1315,"icon":21},"minimark",[62,70,285,294,299,326,338,360,364,650,660,665,677,687,691,707,716,724,758,864,867,882,892,1035,1051,1055,1070,1075,1181,1185,1194,1220,1311],[63,64,65,69],"p",{},[66,67,68],"code",{},"defineCachedFunction"," wraps any async function with caching — TTL, stale-while-revalidate (SWR), integrity checks, and automatic deduplication of concurrent in-flight calls.",[71,72,77],"pre",{"className":73,"code":74,"language":75,"meta":76,"style":76},"language-ts shiki shiki-themes github-light github-dark github-dark","import { defineCachedFunction } from \"ocache\";\n\nconst getRepo = defineCachedFunction(\n  async (name: string) => {\n    const res = await fetch(`https:\u002F\u002Fapi.github.com\u002Frepos\u002F${name}`);\n    return res.json();\n  },\n  {\n    name: \"github-repo\",\n    maxAge: 60, \u002F\u002F cache each result for 60 seconds\n  },\n);\n\n\u002F\u002F First call fetches; calls within the next 60s return the cached value\nconst repo = await getRepo(\"unjs\u002Focache\");\n","ts","",[66,78,79,102,109,129,157,188,203,209,215,227,243,248,253,258,264],{"__ignoreMap":76},[80,81,84,88,92,95,99],"span",{"class":82,"line":83},"line",1,[80,85,87],{"class":86},"so5gQ","import",[80,89,91],{"class":90},"slsVL"," { defineCachedFunction } ",[80,93,94],{"class":86},"from",[80,96,98],{"class":97},"sfrk1"," \"ocache\"",[80,100,101],{"class":90},";\n",[80,103,105],{"class":82,"line":104},2,[80,106,108],{"emptyLinePlaceholder":107},true,"\n",[80,110,112,115,119,122,126],{"class":82,"line":111},3,[80,113,114],{"class":86},"const",[80,116,118],{"class":117},"suiK_"," getRepo",[80,120,121],{"class":86}," =",[80,123,125],{"class":124},"shcOC"," defineCachedFunction",[80,127,128],{"class":90},"(\n",[80,130,132,135,138,142,145,148,151,154],{"class":82,"line":131},4,[80,133,134],{"class":86},"  async",[80,136,137],{"class":90}," (",[80,139,141],{"class":140},"sQHwn","name",[80,143,144],{"class":86},":",[80,146,147],{"class":117}," string",[80,149,150],{"class":90},") ",[80,152,153],{"class":86},"=>",[80,155,156],{"class":90}," {\n",[80,158,160,163,166,168,171,174,177,180,182,185],{"class":82,"line":159},5,[80,161,162],{"class":86},"    const",[80,164,165],{"class":117}," res",[80,167,121],{"class":86},[80,169,170],{"class":86}," await",[80,172,173],{"class":124}," fetch",[80,175,176],{"class":90},"(",[80,178,179],{"class":97},"`https:\u002F\u002Fapi.github.com\u002Frepos\u002F${",[80,181,141],{"class":90},[80,183,184],{"class":97},"}`",[80,186,187],{"class":90},");\n",[80,189,191,194,197,200],{"class":82,"line":190},6,[80,192,193],{"class":86},"    return",[80,195,196],{"class":90}," res.",[80,198,199],{"class":124},"json",[80,201,202],{"class":90},"();\n",[80,204,206],{"class":82,"line":205},7,[80,207,208],{"class":90},"  },\n",[80,210,212],{"class":82,"line":211},8,[80,213,214],{"class":90},"  {\n",[80,216,218,221,224],{"class":82,"line":217},9,[80,219,220],{"class":90},"    name: ",[80,222,223],{"class":97},"\"github-repo\"",[80,225,226],{"class":90},",\n",[80,228,230,233,236,239],{"class":82,"line":229},10,[80,231,232],{"class":90},"    maxAge: ",[80,234,235],{"class":117},"60",[80,237,238],{"class":90},", ",[80,240,242],{"class":241},"sCsY4","\u002F\u002F cache each result for 60 seconds\n",[80,244,246],{"class":82,"line":245},11,[80,247,208],{"class":90},[80,249,251],{"class":82,"line":250},12,[80,252,187],{"class":90},[80,254,256],{"class":82,"line":255},13,[80,257,108],{"emptyLinePlaceholder":107},[80,259,261],{"class":82,"line":260},14,[80,262,263],{"class":241},"\u002F\u002F First call fetches; calls within the next 60s return the cached value\n",[80,265,267,269,272,274,276,278,280,283],{"class":82,"line":266},15,[80,268,114],{"class":86},[80,270,271],{"class":117}," repo",[80,273,121],{"class":86},[80,275,170],{"class":86},[80,277,118],{"class":124},[80,279,176],{"class":90},[80,281,282],{"class":97},"\"unjs\u002Focache\"",[80,284,187],{"class":90},[63,286,287,290,291,293],{},[66,288,289],{},"cachedFunction"," is an alias for ",[66,292,68],{},".",[295,296,298],"h2",{"id":297},"how-it-works","How it works",[300,301,302,314,320],"ul",{},[303,304,305,309,310,313],"li",{},[306,307,308],"strong",{},"TTL"," — a cached value is served until ",[66,311,312],{},"maxAge"," seconds pass, then it is re-resolved.",[303,315,316,319],{},[306,317,318],{},"Deduplication"," — concurrent calls for the same key share a single in-flight resolution, so the underlying function runs once even under a burst of requests.",[303,321,322,325],{},[306,323,324],{},"Integrity"," — entries are tied to a hash of the function and its options. Change the function body or options and stale entries are automatically ignored.",[327,328,329],"important",{},[63,330,331,333,334,337],{},[66,332,312],{}," defaults to ",[306,335,336],{},"1 second",". If you want meaningful caching, set it explicitly.",[339,340,341],"note",{},[63,342,343,344,347,348,351,352,357,358,293],{},"\nSWR is ",[306,345,346],{},"off by default",". Without it, an expired entry is re-resolved in the foreground (the caller waits for the fresh value). Enable ",[66,349,350],{},"swr: true"," to serve the stale value immediately and refresh in the background — see ",[353,354,356],"a",{"href":355},"#dynamic-ttl","Dynamic TTL"," and ",[353,359,23],{"href":24},[295,361,363],{"id":362},"options","Options",[71,365,367],{"className":73,"code":366,"language":75,"meta":76,"style":76},"const cached = defineCachedFunction(fn, {\n  name: \"my-fn\", \u002F\u002F cache key name (defaults to fn.name, then a source hash)\n  maxAge: 60, \u002F\u002F TTL in seconds (default: 1)\n  swr: false, \u002F\u002F serve stale while revalidating in background (default: false)\n  staleMaxAge: 300, \u002F\u002F max seconds a stale value may be served (SWR only)\n  getMaxAge: (entry) => entry.value?.expires_in, \u002F\u002F per-entry TTL from the value\n  base: \"\u002Fcache\", \u002F\u002F key prefix — string, or string[] for multi-tier caching\n  group: \"functions\", \u002F\u002F key group (default: \"functions\")\n  getKey: (...args) => args[0], \u002F\u002F custom cache key from the arguments\n  shouldBypassCache: (...args) => false, \u002F\u002F when true, skip cache and call fn directly\n  shouldInvalidateCache: (...args) => false, \u002F\u002F when true, force a fresh resolve\n  validate: (entry) => entry.value !== undefined, \u002F\u002F reject an entry to re-resolve\n  serialize: (entry) => entry.value, \u002F\u002F prepare the value for storage\n  transform: (entry) => entry.value, \u002F\u002F reshape the value before returning\n  onError: (error) => console.error(error), \u002F\u002F handle cache read\u002Fwrite\u002FSWR errors\n});\n",[66,368,369,383,396,408,421,434,455,468,481,510,533,555,582,601,619,644],{"__ignoreMap":76},[80,370,371,373,376,378,380],{"class":82,"line":83},[80,372,114],{"class":86},[80,374,375],{"class":117}," cached",[80,377,121],{"class":86},[80,379,125],{"class":124},[80,381,382],{"class":90},"(fn, {\n",[80,384,385,388,391,393],{"class":82,"line":104},[80,386,387],{"class":90},"  name: ",[80,389,390],{"class":97},"\"my-fn\"",[80,392,238],{"class":90},[80,394,395],{"class":241},"\u002F\u002F cache key name (defaults to fn.name, then a source hash)\n",[80,397,398,401,403,405],{"class":82,"line":111},[80,399,400],{"class":90},"  maxAge: ",[80,402,235],{"class":117},[80,404,238],{"class":90},[80,406,407],{"class":241},"\u002F\u002F TTL in seconds (default: 1)\n",[80,409,410,413,416,418],{"class":82,"line":131},[80,411,412],{"class":90},"  swr: ",[80,414,415],{"class":117},"false",[80,417,238],{"class":90},[80,419,420],{"class":241},"\u002F\u002F serve stale while revalidating in background (default: false)\n",[80,422,423,426,429,431],{"class":82,"line":159},[80,424,425],{"class":90},"  staleMaxAge: ",[80,427,428],{"class":117},"300",[80,430,238],{"class":90},[80,432,433],{"class":241},"\u002F\u002F max seconds a stale value may be served (SWR only)\n",[80,435,436,439,442,445,447,449,452],{"class":82,"line":190},[80,437,438],{"class":124},"  getMaxAge",[80,440,441],{"class":90},": (",[80,443,444],{"class":140},"entry",[80,446,150],{"class":90},[80,448,153],{"class":86},[80,450,451],{"class":90}," entry.value?.expires_in, ",[80,453,454],{"class":241},"\u002F\u002F per-entry TTL from the value\n",[80,456,457,460,463,465],{"class":82,"line":205},[80,458,459],{"class":90},"  base: ",[80,461,462],{"class":97},"\"\u002Fcache\"",[80,464,238],{"class":90},[80,466,467],{"class":241},"\u002F\u002F key prefix — string, or string[] for multi-tier caching\n",[80,469,470,473,476,478],{"class":82,"line":211},[80,471,472],{"class":90},"  group: ",[80,474,475],{"class":97},"\"functions\"",[80,477,238],{"class":90},[80,479,480],{"class":241},"\u002F\u002F key group (default: \"functions\")\n",[80,482,483,486,488,491,494,496,498,501,504,507],{"class":82,"line":217},[80,484,485],{"class":124},"  getKey",[80,487,441],{"class":90},[80,489,490],{"class":86},"...",[80,492,493],{"class":140},"args",[80,495,150],{"class":90},[80,497,153],{"class":86},[80,499,500],{"class":90}," args[",[80,502,503],{"class":117},"0",[80,505,506],{"class":90},"], ",[80,508,509],{"class":241},"\u002F\u002F custom cache key from the arguments\n",[80,511,512,515,517,519,521,523,525,528,530],{"class":82,"line":229},[80,513,514],{"class":124},"  shouldBypassCache",[80,516,441],{"class":90},[80,518,490],{"class":86},[80,520,493],{"class":140},[80,522,150],{"class":90},[80,524,153],{"class":86},[80,526,527],{"class":117}," false",[80,529,238],{"class":90},[80,531,532],{"class":241},"\u002F\u002F when true, skip cache and call fn directly\n",[80,534,535,538,540,542,544,546,548,550,552],{"class":82,"line":245},[80,536,537],{"class":124},"  shouldInvalidateCache",[80,539,441],{"class":90},[80,541,490],{"class":86},[80,543,493],{"class":140},[80,545,150],{"class":90},[80,547,153],{"class":86},[80,549,527],{"class":117},[80,551,238],{"class":90},[80,553,554],{"class":241},"\u002F\u002F when true, force a fresh resolve\n",[80,556,557,560,562,564,566,568,571,574,577,579],{"class":82,"line":250},[80,558,559],{"class":124},"  validate",[80,561,441],{"class":90},[80,563,444],{"class":140},[80,565,150],{"class":90},[80,567,153],{"class":86},[80,569,570],{"class":90}," entry.value ",[80,572,573],{"class":86},"!==",[80,575,576],{"class":117}," undefined",[80,578,238],{"class":90},[80,580,581],{"class":241},"\u002F\u002F reject an entry to re-resolve\n",[80,583,584,587,589,591,593,595,598],{"class":82,"line":255},[80,585,586],{"class":124},"  serialize",[80,588,441],{"class":90},[80,590,444],{"class":140},[80,592,150],{"class":90},[80,594,153],{"class":86},[80,596,597],{"class":90}," entry.value, ",[80,599,600],{"class":241},"\u002F\u002F prepare the value for storage\n",[80,602,603,606,608,610,612,614,616],{"class":82,"line":260},[80,604,605],{"class":124},"  transform",[80,607,441],{"class":90},[80,609,444],{"class":140},[80,611,150],{"class":90},[80,613,153],{"class":86},[80,615,597],{"class":90},[80,617,618],{"class":241},"\u002F\u002F reshape the value before returning\n",[80,620,621,624,626,629,631,633,636,638,641],{"class":82,"line":266},[80,622,623],{"class":124},"  onError",[80,625,441],{"class":90},[80,627,628],{"class":140},"error",[80,630,150],{"class":90},[80,632,153],{"class":86},[80,634,635],{"class":90}," console.",[80,637,628],{"class":124},[80,639,640],{"class":90},"(error), ",[80,642,643],{"class":241},"\u002F\u002F handle cache read\u002Fwrite\u002FSWR errors\n",[80,645,647],{"class":82,"line":646},16,[80,648,649],{"class":90},"});\n",[63,651,652,653,655,656,659],{},"By default, entries are stored in an in-memory store. See ",[353,654,28],{"href":29}," to plug in a persistent backend, and ",[353,657,658],{"href":34},"HTTP Handlers"," for caching full HTTP responses.",[661,662,664],"h3",{"id":663},"stalemaxage","staleMaxAge",[63,666,667,669,670,672,673,676],{},[66,668,664],{}," only takes effect with ",[66,671,350],{},". It caps how long a stale value may be served while a background refresh runs; after ",[66,674,675],{},"maxAge + staleMaxAge"," the entry is fully expired and the next call resolves in the foreground.",[63,678,679,682,683,686],{},[66,680,681],{},"staleMaxAge: 0"," means a stale value is ",[306,684,685],{},"never"," served — once expired, the request blocks on revalidation even with SWR on.",[295,688,690],{"id":689},"cache-keys","Cache keys",[63,692,693,694,238,697,238,700,702,703,706],{},"Each call resolves to a storage key built from ",[66,695,696],{},"base",[66,698,699],{},"group",[66,701,141],{},", and a key derived from the arguments (",[66,704,705],{},"getKey",", or a hash of all arguments by default).",[63,708,709,710,712,713,144],{},"The ",[66,711,141],{}," resolves as ",[66,714,715],{},"opts.name || fn.name || anon_\u003Chash(fn)>",[300,717,718,721],{},[303,719,720],{},"A named function (or one passed via a named binding) gets a stable, human-readable key.",[303,722,723],{},"An anonymous inline function falls back to a hash of its source, so two different inline functions don't collide on one key.",[327,725,726,735],{},[63,727,728,729,731,732,734],{},"\nA source hash can't tell apart two functions with identical source that differ only by closed-over variables — they will share a key and thrash each other. Pass an explicit ",[66,730,141],{}," (or ",[66,733,705],{},") for those.",[63,736,737,738,750,751,754,755,757],{},"When purging entries with the standalone ",[353,739,740,743,744,743,747],{"href":24},[66,741,742],{},"resolveCacheKeys"," \u002F ",[66,745,746],{},"invalidateCache",[66,748,749],{},"expireCache"," helpers (which never see ",[66,752,753],{},"fn","), always pass the same ",[66,756,141],{}," you cached with.",[71,759,761],{"className":73,"code":760,"language":75,"meta":76,"style":76},"\u002F\u002F Custom key derived from a single id argument\nconst getUser = defineCachedFunction(async (id: string) => db.users.find(id), {\n  name: \"getUser\",\n  maxAge: 60,\n  getKey: (id) => id,\n});\n\nawait getUser(\"user-123\"); \u002F\u002F key includes \"user-123\"\n",[66,762,763,768,806,815,823,838,842,846],{"__ignoreMap":76},[80,764,765],{"class":82,"line":83},[80,766,767],{"class":241},"\u002F\u002F Custom key derived from a single id argument\n",[80,769,770,772,775,777,779,781,784,786,789,791,793,795,797,800,803],{"class":82,"line":104},[80,771,114],{"class":86},[80,773,774],{"class":117}," getUser",[80,776,121],{"class":86},[80,778,125],{"class":124},[80,780,176],{"class":90},[80,782,783],{"class":86},"async",[80,785,137],{"class":90},[80,787,788],{"class":140},"id",[80,790,144],{"class":86},[80,792,147],{"class":117},[80,794,150],{"class":90},[80,796,153],{"class":86},[80,798,799],{"class":90}," db.users.",[80,801,802],{"class":124},"find",[80,804,805],{"class":90},"(id), {\n",[80,807,808,810,813],{"class":82,"line":111},[80,809,387],{"class":90},[80,811,812],{"class":97},"\"getUser\"",[80,814,226],{"class":90},[80,816,817,819,821],{"class":82,"line":131},[80,818,400],{"class":90},[80,820,235],{"class":117},[80,822,226],{"class":90},[80,824,825,827,829,831,833,835],{"class":82,"line":159},[80,826,485],{"class":124},[80,828,441],{"class":90},[80,830,788],{"class":140},[80,832,150],{"class":90},[80,834,153],{"class":86},[80,836,837],{"class":90}," id,\n",[80,839,840],{"class":82,"line":190},[80,841,649],{"class":90},[80,843,844],{"class":82,"line":205},[80,845,108],{"emptyLinePlaceholder":107},[80,847,848,851,853,855,858,861],{"class":82,"line":211},[80,849,850],{"class":86},"await",[80,852,774],{"class":124},[80,854,176],{"class":90},[80,856,857],{"class":97},"\"user-123\"",[80,859,860],{"class":90},"); ",[80,862,863],{"class":241},"\u002F\u002F key includes \"user-123\"\n",[295,865,356],{"id":866},"dynamic-ttl",[63,868,869,870,873,874,877,878,881],{},"Some values carry their own expiry — an OAuth token with ",[66,871,872],{},"expires_in",", an upstream response with a ",[66,875,876],{},"max-age",". Use ",[66,879,880],{},"getMaxAge"," to derive the lifetime from the resolved value instead of a fixed constant.",[63,883,884,885,887,888,891],{},"It runs after the resolver and returns either a number (seconds, shorthand for ",[66,886,312],{},") or ",[66,889,890],{},"{ maxAge?, staleMaxAge? }"," to also override the stale window. The returned values override the static options for that entry, driving both the freshness check and the storage TTL.",[71,893,895],{"className":73,"code":894,"language":75,"meta":76,"style":76},"const getToken = defineCachedFunction(\n  async () => {\n    const res = await fetch(\"https:\u002F\u002Fauth.example.com\u002Ftoken\", { method: \"POST\" });\n    return res.json(); \u002F\u002F { access_token, expires_in }\n  },\n  {\n    name: \"oauth-token\",\n    \u002F\u002F Cache each token for its own lifetime, minus a small safety margin\n    getMaxAge: (entry) => Math.max(1, (entry.value?.expires_in ?? 60) - 5),\n  },\n);\n",[66,896,897,910,921,947,961,965,969,978,983,1027,1031],{"__ignoreMap":76},[80,898,899,901,904,906,908],{"class":82,"line":83},[80,900,114],{"class":86},[80,902,903],{"class":117}," getToken",[80,905,121],{"class":86},[80,907,125],{"class":124},[80,909,128],{"class":90},[80,911,912,914,917,919],{"class":82,"line":104},[80,913,134],{"class":86},[80,915,916],{"class":90}," () ",[80,918,153],{"class":86},[80,920,156],{"class":90},[80,922,923,925,927,929,931,933,935,938,941,944],{"class":82,"line":111},[80,924,162],{"class":86},[80,926,165],{"class":117},[80,928,121],{"class":86},[80,930,170],{"class":86},[80,932,173],{"class":124},[80,934,176],{"class":90},[80,936,937],{"class":97},"\"https:\u002F\u002Fauth.example.com\u002Ftoken\"",[80,939,940],{"class":90},", { method: ",[80,942,943],{"class":97},"\"POST\"",[80,945,946],{"class":90}," });\n",[80,948,949,951,953,955,958],{"class":82,"line":131},[80,950,193],{"class":86},[80,952,196],{"class":90},[80,954,199],{"class":124},[80,956,957],{"class":90},"(); ",[80,959,960],{"class":241},"\u002F\u002F { access_token, expires_in }\n",[80,962,963],{"class":82,"line":159},[80,964,208],{"class":90},[80,966,967],{"class":82,"line":190},[80,968,214],{"class":90},[80,970,971,973,976],{"class":82,"line":205},[80,972,220],{"class":90},[80,974,975],{"class":97},"\"oauth-token\"",[80,977,226],{"class":90},[80,979,980],{"class":82,"line":211},[80,981,982],{"class":241},"    \u002F\u002F Cache each token for its own lifetime, minus a small safety margin\n",[80,984,985,988,990,992,994,996,999,1002,1004,1007,1010,1013,1016,1018,1021,1024],{"class":82,"line":217},[80,986,987],{"class":124},"    getMaxAge",[80,989,441],{"class":90},[80,991,444],{"class":140},[80,993,150],{"class":90},[80,995,153],{"class":86},[80,997,998],{"class":90}," Math.",[80,1000,1001],{"class":124},"max",[80,1003,176],{"class":90},[80,1005,1006],{"class":117},"1",[80,1008,1009],{"class":90},", (entry.value?.expires_in ",[80,1011,1012],{"class":86},"??",[80,1014,1015],{"class":117}," 60",[80,1017,150],{"class":90},[80,1019,1020],{"class":86},"-",[80,1022,1023],{"class":117}," 5",[80,1025,1026],{"class":90},"),\n",[80,1028,1029],{"class":82,"line":229},[80,1030,208],{"class":90},[80,1032,1033],{"class":82,"line":245},[80,1034,187],{"class":90},[339,1036,1037],{},[63,1038,1039,1040,1043,1044,1047,1048,1050],{},"\nReturn ",[66,1041,1042],{},"undefined"," (or omit a field) to fall back to the static option. A returned value ",[66,1045,1046],{},"\u003C= 0"," disables caching for that entry (it re-resolves on every access); negatives are clamped to ",[66,1049,503],{},", never treated as \"cache forever\".",[295,1052,1054],{"id":1053},"custom-serialization","Custom serialization",[63,1056,1057,1058,1061,1062,1065,1066,1069],{},"Some resolver outputs can't be persisted as-is — a ",[66,1059,1060],{},"ReadableStream",", a class instance. Use ",[66,1063,1064],{},"serialize"," to convert the value into a storable form on write, and ",[66,1067,1068],{},"transform"," to reconstruct the usable value on read.",[63,1071,1072,1074],{},[66,1073,1064],{}," runs exactly once per resolution, right after the resolver — even across concurrent deduplicated calls — so consuming a one-shot source such as a stream is safe.",[71,1076,1078],{"className":73,"code":1077,"language":75,"meta":76,"style":76},"const getReport = defineCachedFunction(\n  () => generateReportStream(), \u002F\u002F resolves a one-shot ReadableStream\n  {\n    name: \"report\",\n    maxAge: 300,\n    serialize: (entry) => streamToString(entry.value), \u002F\u002F store as a string\n    transform: (entry) => stringToStream(entry.value), \u002F\u002F rebuild a stream on read\n  },\n);\n",[66,1079,1080,1093,1109,1113,1122,1130,1152,1173,1177],{"__ignoreMap":76},[80,1081,1082,1084,1087,1089,1091],{"class":82,"line":83},[80,1083,114],{"class":86},[80,1085,1086],{"class":117}," getReport",[80,1088,121],{"class":86},[80,1090,125],{"class":124},[80,1092,128],{"class":90},[80,1094,1095,1098,1100,1103,1106],{"class":82,"line":104},[80,1096,1097],{"class":90},"  () ",[80,1099,153],{"class":86},[80,1101,1102],{"class":124}," generateReportStream",[80,1104,1105],{"class":90},"(), ",[80,1107,1108],{"class":241},"\u002F\u002F resolves a one-shot ReadableStream\n",[80,1110,1111],{"class":82,"line":111},[80,1112,214],{"class":90},[80,1114,1115,1117,1120],{"class":82,"line":131},[80,1116,220],{"class":90},[80,1118,1119],{"class":97},"\"report\"",[80,1121,226],{"class":90},[80,1123,1124,1126,1128],{"class":82,"line":159},[80,1125,232],{"class":90},[80,1127,428],{"class":117},[80,1129,226],{"class":90},[80,1131,1132,1135,1137,1139,1141,1143,1146,1149],{"class":82,"line":190},[80,1133,1134],{"class":124},"    serialize",[80,1136,441],{"class":90},[80,1138,444],{"class":140},[80,1140,150],{"class":90},[80,1142,153],{"class":86},[80,1144,1145],{"class":124}," streamToString",[80,1147,1148],{"class":90},"(entry.value), ",[80,1150,1151],{"class":241},"\u002F\u002F store as a string\n",[80,1153,1154,1157,1159,1161,1163,1165,1168,1170],{"class":82,"line":205},[80,1155,1156],{"class":124},"    transform",[80,1158,441],{"class":90},[80,1160,444],{"class":140},[80,1162,150],{"class":90},[80,1164,153],{"class":86},[80,1166,1167],{"class":124}," stringToStream",[80,1169,1148],{"class":90},[80,1171,1172],{"class":241},"\u002F\u002F rebuild a stream on read\n",[80,1174,1175],{"class":82,"line":211},[80,1176,208],{"class":90},[80,1178,1179],{"class":82,"line":217},[80,1180,187],{"class":90},[295,1182,1184],{"id":1183},"cache-status","Cache status",[63,1186,1187,1189,1190,1193],{},[66,1188,1068],{}," receives the entry with a ",[66,1191,1192],{},"status"," field describing how the value was served on this call — useful for metrics or observability. It is one of:",[300,1195,1196,1202,1208,1214],{},[303,1197,1198,1201],{},[66,1199,1200],{},"\"miss\""," — resolved fresh (nothing was cached)",[303,1203,1204,1207],{},[66,1205,1206],{},"\"hit\""," — a fresh cached value was returned",[303,1209,1210,1213],{},[66,1211,1212],{},"\"stale\""," — a stale value was served while a background SWR refresh runs",[303,1215,1216,1219],{},[66,1217,1218],{},"\"revalidated\""," — an expired value was re-resolved in the foreground before returning",[71,1221,1223],{"className":73,"code":1222,"language":75,"meta":76,"style":76},"const getData = defineCachedFunction(fetchData, {\n  name: \"data\",\n  maxAge: 60,\n  transform: (entry) => {\n    metrics.increment(`cache.${entry.status}`); \u002F\u002F \"hit\" \u002F \"miss\" \u002F ...\n    return entry.value;\n  },\n});\n",[66,1224,1225,1239,1248,1256,1270,1296,1303,1307],{"__ignoreMap":76},[80,1226,1227,1229,1232,1234,1236],{"class":82,"line":83},[80,1228,114],{"class":86},[80,1230,1231],{"class":117}," getData",[80,1233,121],{"class":86},[80,1235,125],{"class":124},[80,1237,1238],{"class":90},"(fetchData, {\n",[80,1240,1241,1243,1246],{"class":82,"line":104},[80,1242,387],{"class":90},[80,1244,1245],{"class":97},"\"data\"",[80,1247,226],{"class":90},[80,1249,1250,1252,1254],{"class":82,"line":111},[80,1251,400],{"class":90},[80,1253,235],{"class":117},[80,1255,226],{"class":90},[80,1257,1258,1260,1262,1264,1266,1268],{"class":82,"line":131},[80,1259,605],{"class":124},[80,1261,441],{"class":90},[80,1263,444],{"class":140},[80,1265,150],{"class":90},[80,1267,153],{"class":86},[80,1269,156],{"class":90},[80,1271,1272,1275,1278,1280,1283,1285,1287,1289,1291,1293],{"class":82,"line":159},[80,1273,1274],{"class":90},"    metrics.",[80,1276,1277],{"class":124},"increment",[80,1279,176],{"class":90},[80,1281,1282],{"class":97},"`cache.${",[80,1284,444],{"class":90},[80,1286,293],{"class":97},[80,1288,1192],{"class":90},[80,1290,184],{"class":97},[80,1292,860],{"class":90},[80,1294,1295],{"class":241},"\u002F\u002F \"hit\" \u002F \"miss\" \u002F ...\n",[80,1297,1298,1300],{"class":82,"line":190},[80,1299,193],{"class":86},[80,1301,1302],{"class":90}," entry.value;\n",[80,1304,1305],{"class":82,"line":205},[80,1306,208],{"class":90},[80,1308,1309],{"class":82,"line":211},[80,1310,649],{"class":90},[1312,1313,1314],"style",{},"html pre.shiki code .so5gQ, html code.shiki .so5gQ{--shiki-light:#D73A49;--shiki-default:#F97583;--shiki-dark:#F97583}html pre.shiki code .slsVL, html code.shiki .slsVL{--shiki-light:#24292E;--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8}html pre.shiki code .sfrk1, html code.shiki .sfrk1{--shiki-light:#032F62;--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF}html pre.shiki code .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}html pre.shiki code .shcOC, html code.shiki .shcOC{--shiki-light:#6F42C1;--shiki-default:#B392F0;--shiki-dark:#B392F0}html pre.shiki code .sQHwn, html code.shiki .sQHwn{--shiki-light:#E36209;--shiki-default:#FFAB70;--shiki-dark:#FFAB70}html pre.shiki code .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}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);}",{"title":76,"searchDepth":104,"depth":104,"links":1316},[1317,1318,1321,1322,1323,1324],{"id":297,"depth":104,"text":298},{"id":362,"depth":104,"text":363,"children":1319},[1320],{"id":663,"depth":111,"text":664},{"id":689,"depth":104,"text":690},{"id":866,"depth":104,"text":356},{"id":1053,"depth":104,"text":1054},{"id":1183,"depth":104,"text":1184},"md",{"icon":21},{"icon":21},{"title":18,"description":76},"0ovGghi3jHjPKfFwc6SBmmwGkJwTt8atoWCUIZfjr30",[1331,1332],{"title":13,"path":14,"stem":15,"description":76,"icon":16,"children":-1},{"title":23,"path":24,"stem":25,"description":76,"icon":26,"children":-1},1783601179224]