[{"data":1,"prerenderedAt":1479},["ShallowReactive",2],{"navigation":3,"-guide-middleware":56,"-guide-middleware-surround":1474},[4],{"title":5,"path":6,"stem":7,"children":8,"icon":10},"Getting Started","/guide","1.guide/1.index",[9,11,16,21,26,31,36,41,46,51],{"title":5,"path":6,"stem":7,"icon":10},"ph:book-open-duotone",{"title":12,"path":13,"stem":14,"icon":15},"Using CLI","/guide/cli","1.guide/10.cli","garden:terminal-cli-stroke-12",{"title":17,"path":18,"stem":19,"icon":20},"Fetch Handler","/guide/handler","1.guide/2.handler","i-fluent:target-24-regular",{"title":22,"path":23,"stem":24,"icon":25},"Server Instance","/guide/server","1.guide/3.server","radix-icons:component-instance",{"title":27,"path":28,"stem":29,"icon":30},"Middleware","/guide/middleware","1.guide/4.middleware","clarity:plugin-line",{"title":32,"path":33,"stem":34,"icon":35},"Server Options","/guide/options","1.guide/5.options","ri:settings-3-line",{"title":37,"path":38,"stem":39,"icon":40},"TLS","/guide/tls","1.guide/6.tls","ri:lock-2-line",{"title":42,"path":43,"stem":44,"icon":45},"Bundler Usage","/guide/bundler","1.guide/7.bundler","clarity:bundle-line",{"title":47,"path":48,"stem":49,"icon":50},"Node.js Support","/guide/node","1.guide/8.node","akar-icons:node-fill",{"title":52,"path":53,"stem":54,"icon":55},"AWS Lambda","/guide/aws-lambda","1.guide/9.aws-lambda","clarity:cloud-traffic-line",{"id":57,"title":27,"body":58,"description":1468,"extension":1469,"meta":1470,"navigation":1471,"path":28,"seo":1472,"stem":29,"__hash__":1473},"content/1.guide/4.middleware.md",{"type":59,"value":60,"toc":1458,"icon":30},"minimark",[61,66,451,455,476,486,490,497,591,596,604,682,700,714,718,741,828,834,841,952,988,1023,1034,1051,1078,1085,1109,1125,1133,1137,1157,1161,1192,1409,1431,1444,1454],[62,63,65],"h2",{"id":64},"example","Example",[67,68,73],"pre",{"className":69,"code":70,"language":71,"meta":72,"style":72},"language-ts shiki shiki-themes github-light github-dark github-dark","import { serve, type ServerMiddleware, type ServerPlugin } from \"srvx\";\n\nconst xPoweredBy: ServerMiddleware = async (req, next) => {\n  const res = await next();\n  res.headers.set(\"X-Powered-By\", \"srvx\");\n  return res;\n};\n\nconst devLogs: ServerPlugin = (server) => {\n  if (process.env.NODE_ENV === \"production\") {\n    return;\n  }\n  console.log(`Logger plugin enabled!`);\n  server.options.middleware.push((req, next) => {\n    console.log(`[request] [${req.method}] ${req.url}`);\n    return next();\n  });\n};\n\nserve({\n  middleware: [xPoweredBy],\n  plugins: [devLogs],\n  fetch(request) {\n    return new Response(`👋 Hello there.`);\n  },\n});\n","ts","",[74,75,76,110,117,161,182,205,214,220,225,251,272,280,286,302,326,362,371,377,382,387,396,402,408,421,439,445],"code",{"__ignoreMap":72},[77,78,81,85,89,92,95,97,100,103,107],"span",{"class":79,"line":80},"line",1,[77,82,84],{"class":83},"so5gQ","import",[77,86,88],{"class":87},"slsVL"," { serve, ",[77,90,91],{"class":83},"type",[77,93,94],{"class":87}," ServerMiddleware, ",[77,96,91],{"class":83},[77,98,99],{"class":87}," ServerPlugin } ",[77,101,102],{"class":83},"from",[77,104,106],{"class":105},"sfrk1"," \"srvx\"",[77,108,109],{"class":87},";\n",[77,111,113],{"class":79,"line":112},2,[77,114,116],{"emptyLinePlaceholder":115},true,"\n",[77,118,120,123,127,130,133,136,139,142,146,149,152,155,158],{"class":79,"line":119},3,[77,121,122],{"class":83},"const",[77,124,126],{"class":125},"shcOC"," xPoweredBy",[77,128,129],{"class":83},":",[77,131,132],{"class":125}," ServerMiddleware",[77,134,135],{"class":83}," =",[77,137,138],{"class":83}," async",[77,140,141],{"class":87}," (",[77,143,145],{"class":144},"sQHwn","req",[77,147,148],{"class":87},", ",[77,150,151],{"class":144},"next",[77,153,154],{"class":87},") ",[77,156,157],{"class":83},"=>",[77,159,160],{"class":87}," {\n",[77,162,164,167,171,173,176,179],{"class":79,"line":163},4,[77,165,166],{"class":83},"  const",[77,168,170],{"class":169},"suiK_"," res",[77,172,135],{"class":83},[77,174,175],{"class":83}," await",[77,177,178],{"class":125}," next",[77,180,181],{"class":87},"();\n",[77,183,185,188,191,194,197,199,202],{"class":79,"line":184},5,[77,186,187],{"class":87},"  res.headers.",[77,189,190],{"class":125},"set",[77,192,193],{"class":87},"(",[77,195,196],{"class":105},"\"X-Powered-By\"",[77,198,148],{"class":87},[77,200,201],{"class":105},"\"srvx\"",[77,203,204],{"class":87},");\n",[77,206,208,211],{"class":79,"line":207},6,[77,209,210],{"class":83},"  return",[77,212,213],{"class":87}," res;\n",[77,215,217],{"class":79,"line":216},7,[77,218,219],{"class":87},"};\n",[77,221,223],{"class":79,"line":222},8,[77,224,116],{"emptyLinePlaceholder":115},[77,226,228,230,233,235,238,240,242,245,247,249],{"class":79,"line":227},9,[77,229,122],{"class":83},[77,231,232],{"class":125}," devLogs",[77,234,129],{"class":83},[77,236,237],{"class":125}," ServerPlugin",[77,239,135],{"class":83},[77,241,141],{"class":87},[77,243,244],{"class":144},"server",[77,246,154],{"class":87},[77,248,157],{"class":83},[77,250,160],{"class":87},[77,252,254,257,260,263,266,269],{"class":79,"line":253},10,[77,255,256],{"class":83},"  if",[77,258,259],{"class":87}," (process.env.",[77,261,262],{"class":169},"NODE_ENV",[77,264,265],{"class":83}," ===",[77,267,268],{"class":105}," \"production\"",[77,270,271],{"class":87},") {\n",[77,273,275,278],{"class":79,"line":274},11,[77,276,277],{"class":83},"    return",[77,279,109],{"class":87},[77,281,283],{"class":79,"line":282},12,[77,284,285],{"class":87},"  }\n",[77,287,289,292,295,297,300],{"class":79,"line":288},13,[77,290,291],{"class":87},"  console.",[77,293,294],{"class":125},"log",[77,296,193],{"class":87},[77,298,299],{"class":105},"`Logger plugin enabled!`",[77,301,204],{"class":87},[77,303,305,308,311,314,316,318,320,322,324],{"class":79,"line":304},14,[77,306,307],{"class":87},"  server.options.middleware.",[77,309,310],{"class":125},"push",[77,312,313],{"class":87},"((",[77,315,145],{"class":144},[77,317,148],{"class":87},[77,319,151],{"class":144},[77,321,154],{"class":87},[77,323,157],{"class":83},[77,325,160],{"class":87},[77,327,329,332,334,336,339,341,344,347,350,352,354,357,360],{"class":79,"line":328},15,[77,330,331],{"class":87},"    console.",[77,333,294],{"class":125},[77,335,193],{"class":87},[77,337,338],{"class":105},"`[request] [${",[77,340,145],{"class":87},[77,342,343],{"class":105},".",[77,345,346],{"class":87},"method",[77,348,349],{"class":105},"}] ${",[77,351,145],{"class":87},[77,353,343],{"class":105},[77,355,356],{"class":87},"url",[77,358,359],{"class":105},"}`",[77,361,204],{"class":87},[77,363,365,367,369],{"class":79,"line":364},16,[77,366,277],{"class":83},[77,368,178],{"class":125},[77,370,181],{"class":87},[77,372,374],{"class":79,"line":373},17,[77,375,376],{"class":87},"  });\n",[77,378,380],{"class":79,"line":379},18,[77,381,219],{"class":87},[77,383,385],{"class":79,"line":384},19,[77,386,116],{"emptyLinePlaceholder":115},[77,388,390,393],{"class":79,"line":389},20,[77,391,392],{"class":125},"serve",[77,394,395],{"class":87},"({\n",[77,397,399],{"class":79,"line":398},21,[77,400,401],{"class":87},"  middleware: [xPoweredBy],\n",[77,403,405],{"class":79,"line":404},22,[77,406,407],{"class":87},"  plugins: [devLogs],\n",[77,409,411,414,416,419],{"class":79,"line":410},23,[77,412,413],{"class":125},"  fetch",[77,415,193],{"class":87},[77,417,418],{"class":144},"request",[77,420,271],{"class":87},[77,422,424,426,429,432,434,437],{"class":79,"line":423},24,[77,425,277],{"class":83},[77,427,428],{"class":83}," new",[77,430,431],{"class":125}," Response",[77,433,193],{"class":87},[77,435,436],{"class":105},"`👋 Hello there.`",[77,438,204],{"class":87},[77,440,442],{"class":79,"line":441},25,[77,443,444],{"class":87},"  },\n",[77,446,448],{"class":79,"line":447},26,[77,449,450],{"class":87},"});\n",[62,452,454],{"id":453},"order-of-execution","Order of execution",[456,457,458,459,462,463,466,467,471,472,475],"p",{},"Middleware run in the order they appear in the ",[74,460,461],{},"middleware"," array, each wrapping the next, with your ",[74,464,465],{},"fetch"," handler at the center. A middleware that returns a response ",[468,469,470],"strong",{},"without"," calling ",[74,473,474],{},"next()"," short-circuits the rest of the chain — nothing after it runs.",[456,477,478,479,482,483,485],{},"Plugins are applied in ",[74,480,481],{},"plugins"," array order, before the server starts listening. A plugin that pushes middleware appends to the end of the array, so ",[74,484,461],{}," entries always run first.",[62,487,489],{"id":488},"built-in-middleware-and-plugins","Built-in middleware and plugins",[456,491,492,493,496],{},"srvx ships several optional extensions as separate subpath imports. All of them are opt-in — importing ",[74,494,495],{},"srvx"," alone pulls in none of them.",[498,499,500,519],"table",{},[501,502,503],"thead",{},[504,505,506,510,513,516],"tr",{},[507,508,509],"th",{},"Import",[507,511,512],{},"Export",[507,514,515],{},"Kind",[507,517,518],{},"Runtimes",[520,521,522,540,557,575],"tbody",{},[504,523,524,530,535,537],{},[525,526,527],"td",{},[74,528,529],{},"srvx/log",[525,531,532],{},[74,533,534],{},"log()",[525,536,27],{},[525,538,539],{},"All",[504,541,542,547,552,554],{},[525,543,544],{},[74,545,546],{},"srvx/static",[525,548,549],{},[74,550,551],{},"serveStatic()",[525,553,27],{},[525,555,556],{},"Node, Deno, Bun",[504,558,559,564,569,572],{},[525,560,561],{},[74,562,563],{},"srvx/mtls",[525,565,566],{},[74,567,568],{},"mtls()",[525,570,571],{},"Plugin",[525,573,574],{},"Node",[504,576,577,582,587,589],{},[525,578,579],{},[74,580,581],{},"srvx/tracing",[525,583,584],{},[74,585,586],{},"tracingPlugin()",[525,588,571],{},[525,590,556],{},[592,593,595],"h3",{"id":594},"request-logging","Request logging",[456,597,598,600,601,603],{},[74,599,534],{}," from ",[74,602,529],{}," prints one colored line per request with the method, URL, status, and duration.",[67,605,608],{"className":69,"code":606,"filename":607,"language":71,"meta":72,"style":72},"import { serve } from \"srvx\";\nimport { log } from \"srvx/log\";\n\nserve({\n  middleware: [log()],\n  fetch: () => new Response(\"👋 Hello there.\"),\n});\n","server.ts",[74,609,610,623,637,641,647,657,678],{"__ignoreMap":72},[77,611,612,614,617,619,621],{"class":79,"line":80},[77,613,84],{"class":83},[77,615,616],{"class":87}," { serve } ",[77,618,102],{"class":83},[77,620,106],{"class":105},[77,622,109],{"class":87},[77,624,625,627,630,632,635],{"class":79,"line":112},[77,626,84],{"class":83},[77,628,629],{"class":87}," { log } ",[77,631,102],{"class":83},[77,633,634],{"class":105}," \"srvx/log\"",[77,636,109],{"class":87},[77,638,639],{"class":79,"line":119},[77,640,116],{"emptyLinePlaceholder":115},[77,642,643,645],{"class":79,"line":163},[77,644,392],{"class":125},[77,646,395],{"class":87},[77,648,649,652,654],{"class":79,"line":184},[77,650,651],{"class":87},"  middleware: [",[77,653,294],{"class":125},[77,655,656],{"class":87},"()],\n",[77,658,659,661,664,666,668,670,672,675],{"class":79,"line":207},[77,660,413],{"class":125},[77,662,663],{"class":87},": () ",[77,665,157],{"class":83},[77,667,428],{"class":83},[77,669,431],{"class":125},[77,671,193],{"class":87},[77,673,674],{"class":105},"\"👋 Hello there.\"",[77,676,677],{"class":87},"),\n",[77,679,680],{"class":79,"line":216},[77,681,450],{"class":87},[67,683,687],{"className":684,"code":685,"language":686,"meta":72,"style":72},"language-sh shiki shiki-themes github-light github-dark github-dark","[10:32:03 AM] GET http://localhost:3000/ [200] (1.42ms)\n","sh",[74,688,689],{"__ignoreMap":72},[77,690,691,694,697],{"class":79,"line":80},[77,692,693],{"class":87},"[10:32:03 AM] GET http://localhost:3000/ [200] (",[77,695,696],{"class":125},"1.42ms",[77,698,699],{"class":87},")\n",[456,701,702,703,705,706,708,709,713],{},"The duration is measured around ",[74,704,474],{},", so place ",[74,707,534],{}," first in the array for it to cover the whole chain. The ",[710,711,712],"a",{"href":13},"CLI"," enables this middleware automatically.",[592,715,717],{"id":716},"static-files","Static files",[456,719,720,600,722,724,725,728,729,732,733,736,737,740],{},[74,721,551],{},[74,723,546],{}," serves files from a directory, with ",[74,726,727],{},"index.html"," resolution, ",[74,730,731],{},".html"," extension fallback (",[74,734,735],{},"/about"," → ",[74,738,739],{},"about.html","), common MIME types, gzip/Brotli compression, and path-traversal protection.",[67,742,744],{"className":69,"code":743,"filename":607,"language":71,"meta":72,"style":72},"import { serve } from \"srvx\";\nimport { serveStatic } from \"srvx/static\";\n\nserve({\n  middleware: [serveStatic({ dir: \"public\" })],\n  fetch: () => new Response(\"Not found\", { status: 404 }),\n});\n",[74,745,746,758,772,776,782,798,824],{"__ignoreMap":72},[77,747,748,750,752,754,756],{"class":79,"line":80},[77,749,84],{"class":83},[77,751,616],{"class":87},[77,753,102],{"class":83},[77,755,106],{"class":105},[77,757,109],{"class":87},[77,759,760,762,765,767,770],{"class":79,"line":112},[77,761,84],{"class":83},[77,763,764],{"class":87}," { serveStatic } ",[77,766,102],{"class":83},[77,768,769],{"class":105}," \"srvx/static\"",[77,771,109],{"class":87},[77,773,774],{"class":79,"line":119},[77,775,116],{"emptyLinePlaceholder":115},[77,777,778,780],{"class":79,"line":163},[77,779,392],{"class":125},[77,781,395],{"class":87},[77,783,784,786,789,792,795],{"class":79,"line":184},[77,785,651],{"class":87},[77,787,788],{"class":125},"serveStatic",[77,790,791],{"class":87},"({ dir: ",[77,793,794],{"class":105},"\"public\"",[77,796,797],{"class":87}," })],\n",[77,799,800,802,804,806,808,810,812,815,818,821],{"class":79,"line":207},[77,801,413],{"class":125},[77,803,663],{"class":87},[77,805,157],{"class":83},[77,807,428],{"class":83},[77,809,431],{"class":125},[77,811,193],{"class":87},[77,813,814],{"class":105},"\"Not found\"",[77,816,817],{"class":87},", { status: ",[77,819,820],{"class":169},"404",[77,822,823],{"class":87}," }),\n",[77,825,826],{"class":79,"line":216},[77,827,450],{"class":87},[456,829,830,831,833],{},"When no file matches the request, it calls ",[74,832,474],{}," — so your handler acts as the fallback for unmatched paths.",[456,835,836],{},[468,837,838,840],{},[74,839,551],{}," options:",[842,843,844,851,863,901,921,932],"ul",{},[845,846,847,850],"li",{},[74,848,849],{},"dir",": The directory to serve files from (required).",[845,852,853,856,857,860,861,343],{},[74,854,855],{},"methods",": HTTP methods to serve (default ",[74,858,859],{},"[\"GET\", \"HEAD\"]","). Other methods fall through to ",[74,862,474],{},[845,864,865,868,869,871,872,875,876,148,879,882,883,885,886,889,890,893,894,897,898,343],{},[74,866,867],{},"dotfiles",": Dot segments (path segments starting with ",[74,870,343],{},") that may be served (default ",[74,873,874],{},"[\".well-known\"]","). A path containing any other dot segment — ",[74,877,878],{},"/.env",[74,880,881],{},"/.git/config"," — falls through to ",[74,884,474],{},". Pass ",[74,887,888],{},"true"," to serve every dot segment, or ",[74,891,892],{},"false"," (or ",[74,895,896],{},"[]",") to serve none, including ",[74,899,900],{},"/.well-known/",[845,902,903,906,907,909,910,912,913,916,917,920],{},[74,904,905],{},"encodings",": Serve precompressed variants from disk (default ",[74,908,892],{},"). Pass ",[74,911,888],{}," for ",[74,914,915],{},"{ br: \".br\", gzip: \".gz\" }",", or a map setting the extension per encoding (keys tried in order, preferred first). Off by default because most deployments ship no precompressed files, so the lookup is a ",[74,918,919],{},"stat"," that always misses.",[845,922,923,926,927,909,929,931],{},[74,924,925],{},"compress",": Compress a response on the fly when no precompressed variant is served (default ",[74,928,888],{},[74,930,892],{}," to serve only what is already on disk.",[845,933,934,937,938,941,942,148,944,947,948,951],{},[74,935,936],{},"renderHTML",": A function receiving ",[74,939,940],{},"{ request, html, filename }"," for every HTML file (",[74,943,731],{},[74,945,946],{},".htm","), returning the ",[74,949,950],{},"Response"," to send. Use it to inject or template markup before serving.",[456,953,954,955,958,959,962,963,965,966,968,969,972,973,976,977,980,981,984,985,343],{},"A request resolves in order: the path itself, then ",[74,956,957],{},"\u003Cpath>.html",", then ",[74,960,961],{},"\u003Cpath>/index.html",". So ",[74,964,735],{}," serves ",[74,967,739],{},", while an extension-less file (",[74,970,971],{},"LICENSE",", an ACME challenge token) is served at its exact name. A trailing-slash request names a directory, so ",[74,974,975],{},"/sub/"," resolves only ",[74,978,979],{},"sub/index.html"," — never ",[74,982,983],{},"sub.html"," or a file named ",[74,986,987],{},"sub",[456,989,990,991,993,994,997,998,148,1001,1004,1005,1008,1009,1012,1013,1016,1017,1019,1020,1022],{},"By default a compressible response is compressed on the fly as it is sent. Enabling ",[74,992,905],{}," adds a disk lookup that takes precedence: for ",[74,995,996],{},"/app.js"," with ",[74,999,1000],{},"Accept-Encoding: br",[74,1002,1003],{},"app.js.br"," is served if it exists (with ",[74,1006,1007],{},"Content-Encoding: br","), and only a missing variant falls back to on-the-fly. A variant always wins because it costs no CPU, and a build can afford a better ratio than a per-request encode can justify — so ",[74,1010,1011],{},"encodings: true"," plus a build step is the cheapest way to serve maximum-quality compressed assets. The two switches are independent: ",[74,1014,1015],{},"compress: false"," serves only what is on disk, and ",[74,1018,905],{}," off with ",[74,1021,925],{}," on always compresses on the fly.",[456,1024,1025,1026,1029,1030,1033],{},"Brotli compresses at quality 4 rather than the ",[74,1027,1028],{},"node:zlib"," default of 11, which costs roughly 12x the CPU for a few percent of size. Only files between 1 KiB and 10 MiB are compressed on the fly: below that the encoded body can come out larger than the input, and above it the CPU spent per request outweighs the bandwidth saved — precompress large assets instead. On-the-fly responses are chunked, since the encoded length is not known until the bytes exist, while a variant declares the ",[74,1031,1032],{},"Content-Length"," it has on disk.",[456,1035,1036,1037,1040,1041,1044,1045,1047,1048,1050],{},"Compression applies to compressible types only, so a ",[74,1038,1039],{},".br"," next to an image or font is ignored, and those responses omit ",[74,1042,1043],{},"Vary: Accept-Encoding"," — which compressible ones always set, including uncompressed ones, as a shared cache must key on the header either way. ",[74,1046,936],{}," routes are never compressed and always read the source file: a variant on disk would not match the rendered output, and the ",[74,1049,950],{}," the hook returns is the caller's to encode.",[456,1052,1053,1055,1056,1062,1063,1066,1067,1069,1070,1073,1074,1077],{},[74,1054,900],{}," is served by default because ",[710,1057,1061],{"href":1058,"rel":1059},"https://www.rfc-editor.org/rfc/rfc8615",[1060],"nofollow","RFC 8615"," reserves it for public metadata: ACME HTTP-01 challenges and ",[74,1064,1065],{},"security.txt"," live there. Allow-listing is by exact segment name, so ",[74,1068,874],{}," serves neither a sibling sharing its prefix (",[74,1071,1072],{},".well-known-backup",") nor a dot segment nested under it (",[74,1075,1076],{},".well-known/.env",").",[456,1079,1080,1081,1084],{},"Text responses declare ",[74,1082,1083],{},"charset=utf-8","; without it a browser decodes them with a fallback of its own choosing, mangling any non-ASCII byte the file does not declare inline.",[1086,1087,1088],"note",{},[456,1089,1090,1091,1093,1094,1096,1097,1099,1100,736,1103,882,1106,1108],{},"\nFiles are only served from within ",[74,1092,849],{},", and both rules above are re-checked against the path a symlink actually resolves to. Symlinks are followed, but one resolving outside ",[74,1095,849],{}," — or onto a dot segment ",[74,1098,867],{}," hides, such as ",[74,1101,1102],{},"public.txt",[74,1104,1105],{},".env",[74,1107,474],{}," instead of being served.",[1086,1110,1111],{},[456,1112,1113,1114,1116,1117,1120,1121,1124],{},"\nDespite the runtime-neutral name, ",[74,1115,546],{}," is ",[468,1118,1119],{},"Node-API-only"," — it uses ",[74,1122,1123],{},"node:fs"," internally, so it works only on runtimes with Node.js compatibility (Node, Deno, Bun).",[456,1126,1127,1128,1132],{},"See ",[710,1129,1131],{"href":1130},"/guide/cli#serving-static-files","Serving static files"," for the equivalent CLI flag.",[592,1134,1136],{"id":1135},"mutual-tls","Mutual TLS",[456,1138,1139,600,1144,1146,1147,1153,1154,343],{},[710,1140,1142],{"href":1141},"/guide/tls#mutual-tls-mtls",[74,1143,568],{},[74,1145,563],{}," requests a client certificate during the TLS handshake and exposes it on ",[710,1148,1150],{"href":1149},"/guide/handler#requesttls",[74,1151,1152],{},"request.tls",". It requires the ",[710,1155,1156],{"href":48},"Node.js adapter",[592,1158,1160],{"id":1159},"tracing","Tracing",[456,1162,1163,600,1165,1167,1168,1170,1171,1178,1179,1182,1183,1186,1187,343],{},[74,1164,586],{},[74,1166,581],{}," wraps your ",[74,1169,465],{}," handler and each middleware with ",[710,1172,1175],{"href":1173,"rel":1174},"https://nodejs.org/api/diagnostics_channel.html",[1060],[74,1176,1177],{},"diagnostics_channel"," instrumentation, publishing to the ",[74,1180,1181],{},"srvx.request"," and ",[74,1184,1185],{},"srvx.middleware"," ",[710,1188,1191],{"href":1189,"rel":1190},"https://nodejs.org/api/diagnostics_channel.html#class-tracingchannel",[1060],"tracing channels",[67,1193,1195],{"className":69,"code":1194,"filename":607,"language":71,"meta":72,"style":72},"import { serve } from \"srvx\";\nimport { tracingPlugin } from \"srvx/tracing\";\nimport { tracingChannel } from \"node:diagnostics_channel\";\n\ntracingChannel(\"srvx.request\").subscribe({\n  start: ({ request }) => console.log(`[start] ${request.url}`),\n  asyncEnd: ({ request }) => console.log(`[end] ${request.url}`),\n  error: ({ request, error }) => console.error(`[error] ${request.url}`, error),\n});\n\nserve({\n  plugins: [tracingPlugin()],\n  fetch: () => new Response(\"👋 Hello there.\"),\n});\n",[74,1196,1197,1209,1223,1237,1241,1258,1293,1325,1363,1367,1371,1377,1387,1405],{"__ignoreMap":72},[77,1198,1199,1201,1203,1205,1207],{"class":79,"line":80},[77,1200,84],{"class":83},[77,1202,616],{"class":87},[77,1204,102],{"class":83},[77,1206,106],{"class":105},[77,1208,109],{"class":87},[77,1210,1211,1213,1216,1218,1221],{"class":79,"line":112},[77,1212,84],{"class":83},[77,1214,1215],{"class":87}," { tracingPlugin } ",[77,1217,102],{"class":83},[77,1219,1220],{"class":105}," \"srvx/tracing\"",[77,1222,109],{"class":87},[77,1224,1225,1227,1230,1232,1235],{"class":79,"line":119},[77,1226,84],{"class":83},[77,1228,1229],{"class":87}," { tracingChannel } ",[77,1231,102],{"class":83},[77,1233,1234],{"class":105}," \"node:diagnostics_channel\"",[77,1236,109],{"class":87},[77,1238,1239],{"class":79,"line":163},[77,1240,116],{"emptyLinePlaceholder":115},[77,1242,1243,1246,1248,1251,1253,1256],{"class":79,"line":184},[77,1244,1245],{"class":125},"tracingChannel",[77,1247,193],{"class":87},[77,1249,1250],{"class":105},"\"srvx.request\"",[77,1252,1077],{"class":87},[77,1254,1255],{"class":125},"subscribe",[77,1257,395],{"class":87},[77,1259,1260,1263,1266,1268,1271,1273,1276,1278,1280,1283,1285,1287,1289,1291],{"class":79,"line":207},[77,1261,1262],{"class":125},"  start",[77,1264,1265],{"class":87},": ({ ",[77,1267,418],{"class":144},[77,1269,1270],{"class":87}," }) ",[77,1272,157],{"class":83},[77,1274,1275],{"class":87}," console.",[77,1277,294],{"class":125},[77,1279,193],{"class":87},[77,1281,1282],{"class":105},"`[start] ${",[77,1284,418],{"class":87},[77,1286,343],{"class":105},[77,1288,356],{"class":87},[77,1290,359],{"class":105},[77,1292,677],{"class":87},[77,1294,1295,1298,1300,1302,1304,1306,1308,1310,1312,1315,1317,1319,1321,1323],{"class":79,"line":216},[77,1296,1297],{"class":125},"  asyncEnd",[77,1299,1265],{"class":87},[77,1301,418],{"class":144},[77,1303,1270],{"class":87},[77,1305,157],{"class":83},[77,1307,1275],{"class":87},[77,1309,294],{"class":125},[77,1311,193],{"class":87},[77,1313,1314],{"class":105},"`[end] ${",[77,1316,418],{"class":87},[77,1318,343],{"class":105},[77,1320,356],{"class":87},[77,1322,359],{"class":105},[77,1324,677],{"class":87},[77,1326,1327,1330,1332,1334,1336,1339,1341,1343,1345,1347,1349,1352,1354,1356,1358,1360],{"class":79,"line":222},[77,1328,1329],{"class":125},"  error",[77,1331,1265],{"class":87},[77,1333,418],{"class":144},[77,1335,148],{"class":87},[77,1337,1338],{"class":144},"error",[77,1340,1270],{"class":87},[77,1342,157],{"class":83},[77,1344,1275],{"class":87},[77,1346,1338],{"class":125},[77,1348,193],{"class":87},[77,1350,1351],{"class":105},"`[error] ${",[77,1353,418],{"class":87},[77,1355,343],{"class":105},[77,1357,356],{"class":87},[77,1359,359],{"class":105},[77,1361,1362],{"class":87},", error),\n",[77,1364,1365],{"class":79,"line":227},[77,1366,450],{"class":87},[77,1368,1369],{"class":79,"line":253},[77,1370,116],{"emptyLinePlaceholder":115},[77,1372,1373,1375],{"class":79,"line":274},[77,1374,392],{"class":125},[77,1376,395],{"class":87},[77,1378,1379,1382,1385],{"class":79,"line":282},[77,1380,1381],{"class":87},"  plugins: [",[77,1383,1384],{"class":125},"tracingPlugin",[77,1386,656],{"class":87},[77,1388,1389,1391,1393,1395,1397,1399,1401,1403],{"class":79,"line":288},[77,1390,413],{"class":125},[77,1392,663],{"class":87},[77,1394,157],{"class":83},[77,1396,428],{"class":83},[77,1398,431],{"class":125},[77,1400,193],{"class":87},[77,1402,674],{"class":105},[77,1404,677],{"class":87},[77,1406,1407],{"class":79,"line":304},[77,1408,450],{"class":87},[456,1410,1411,1412,1415,1416,1419,1420,1422,1423,1426,1427,1430],{},"Each event carries ",[74,1413,1414],{},"{ server, request }",", plus ",[74,1417,1418],{},"{ middleware: { index, handler } }"," on the ",[74,1421,1185],{}," channel. Pass ",[74,1424,1425],{},"{ fetch: false }"," or ",[74,1428,1429],{},"{ middleware: false }"," to instrument only one of the two.",[456,1432,1433,1434,1436,1437,1440,1441,1443],{},"Because plugins run in order, ",[74,1435,586],{}," only wraps middleware registered before it — keep it ",[468,1438,1439],{},"last"," in the ",[74,1442,481],{}," array so it covers middleware added by earlier plugins.",[1445,1446,1447],"important",{},[456,1448,1449,1116,1451,343],{},[74,1450,581],{},[468,1452,1453],{},"experimental",[1455,1456,1457],"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 .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 .suiK_, html code.shiki .suiK_{--shiki-light:#005CC5;--shiki-default:#79B8FF;--shiki-dark:#79B8FF}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":72,"searchDepth":112,"depth":112,"links":1459},[1460,1461,1462],{"id":64,"depth":112,"text":65},{"id":453,"depth":112,"text":454},{"id":488,"depth":112,"text":489,"children":1463},[1464,1465,1466,1467],{"id":594,"depth":119,"text":595},{"id":716,"depth":119,"text":717},{"id":1135,"depth":119,"text":1136},{"id":1159,"depth":119,"text":1160},"Plugins and middleware allow adding reusable server extensions.","md",{"icon":30},{"icon":30},{"title":27,"description":1468},"tM312JTI9jeu2l3wibtP5PNfMXKNcDEXVhtlPi1YBW0",[1475,1477],{"title":22,"path":23,"stem":24,"description":1476,"icon":25,"children":-1},"Control srvx server lifecycle.",{"title":32,"path":33,"stem":34,"description":1478,"icon":35,"children":-1},"Provide additional options to customize listening server.",1784302153565]