[{"data":1,"prerenderedAt":2401},["ShallowReactive",2],{"navigation_docs":3,"-guide-zio":93,"-guide-zio-surround":2396},[4,71],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":70},"Guide","i-lucide-book-open","\u002Fguide","1.guide",[10,14,18,22,26,30,34,38,42,46,50,54,58,62,66],{"title":11,"path":12,"stem":13},"Getting started","\u002Fguide\u002Fgetting-started","1.guide\u002F01.getting-started",{"title":15,"path":16,"stem":17},"Adoption paths","\u002Fguide\u002Fadoption","1.guide\u002F02.adoption",{"title":19,"path":20,"stem":21},"Routes and typed $fetch","\u002Fguide\u002Froutes","1.guide\u002F02.routes",{"title":23,"path":24,"stem":25},"Kyo handlers","\u002Fguide\u002Fkyo","1.guide\u002F03.kyo",{"title":27,"path":28,"stem":29},"ZIO handlers","\u002Fguide\u002Fzio","1.guide\u002F04.zio",{"title":31,"path":32,"stem":33},"Configuration and secrets","\u002Fguide\u002Fconfiguration","1.guide\u002F05.configuration",{"title":35,"path":36,"stem":37},"Application and request lifetimes","\u002Fguide\u002Flifetimes","1.guide\u002F06.lifetimes",{"title":39,"path":40,"stem":41},"Schemas","\u002Fguide\u002Fschema","1.guide\u002F07.schema",{"title":43,"path":44,"stem":45},"PostgreSQL","\u002Fguide\u002Fdatabase","1.guide\u002F08.database",{"title":47,"path":48,"stem":49},"Streaming and cancellation","\u002Fguide\u002Fstreaming","1.guide\u002F09.streaming",{"title":51,"path":52,"stem":53},"Testing","\u002Fguide\u002Ftesting","1.guide\u002F10.testing",{"title":55,"path":56,"stem":57},"Nitro storage and NuxtHub KV","\u002Fguide\u002Fstorage","1.guide\u002F11.storage",{"title":59,"path":60,"stem":61},"Debug Scala handlers","\u002Fguide\u002Fdebugging","1.guide\u002F12.debugging",{"title":63,"path":64,"stem":65},"npm build tooling","\u002Fguide\u002Fnpm-tooling","1.guide\u002F13.npm-tooling",{"title":67,"path":68,"stem":69},"Set up h34s with a coding assistant","\u002Fguide\u002Fagent-setup","1.guide\u002F14.agent-setup",false,{"title":72,"icon":73,"path":74,"stem":75,"children":76,"page":70},"Reference","i-lucide-library","\u002Freference","2.reference",[77,81,85,89],{"title":78,"path":79,"stem":80},"Architecture","\u002Freference\u002Farchitecture","2.reference\u002F1.architecture",{"title":82,"path":83,"stem":84},"Releases","\u002Freference\u002Freleases","2.reference\u002F2.releases",{"title":86,"path":87,"stem":88},"Compatibility","\u002Freference\u002Fcompatibility","2.reference\u002F3.compatibility",{"title":90,"path":91,"stem":92},"Migration guide","\u002Freference\u002Fmigration","2.reference\u002F4.migration",{"id":94,"title":27,"body":95,"description":2390,"extension":2391,"links":2392,"meta":2393,"navigation":326,"path":28,"seo":2394,"stem":29,"__hash__":2395},"docs\u002F1.guide\u002F04.zio.md",{"type":96,"value":97,"toc":2374},"minimark",[98,127,134,154,159,182,203,207,214,515,546,550,557,882,900,918,922,932,1001,1005,1062,1091,1095,1152,1155,1176,1179,1183,1261,1308,1340,1344,1354,1389,1405,1409,1415,1658,1675,1707,1729,1742,1748,1759,1793,1971,1978,2212,2225,2229,2307,2311,2320,2331,2346,2350,2370],[99,100,101,102,106,107,110,111,114,115,118,119,122,123,126],"p",{},"The ZIO API is a first-class, hand-written adapter over the Kyo core. You write ordinary ZIO programs: ",[103,104,105],"code",{},"for"," comprehensions, ",[103,108,109],{},"ZIO.service",", typed errors, ",[103,112,113],{},"ZLayer"," and ",[103,116,117],{},"ZStream",". ",[103,120,121],{},"ZHandler.define"," runs them on a ZIO ",[103,124,125],{},"Runtime"," and hands the result to the core, which owns the request lifecycle, the wire format and the response.",[99,128,129,130,133],{},"Your application depends on ",[103,131,132],{},"zio-h3-ext",", which brings the Kyo core with it. You never write Kyo code in a ZIO application.",[99,135,136,140,141,144,145,148,149,153],{},[137,138,139],"strong",{},"Status."," This guide describes ",[103,142,143],{},"0.2.0-alpha.1",". The older ",[103,146,147],{},"0.1.0-alpha.1"," has a different ZIO API. The ",[150,151,152],"a",{"href":91},"migration guide"," maps every old call to its replacement.",[155,156,158],"h2",{"id":157},"prerequisites","Prerequisites",[160,161,162,166,169],"ul",{},[163,164,165],"li",{},"Scala 3.9.0, Scala.js 1.22.0, and JDK 25 to run sbt. The ZIO modules share the Kyo core's toolchain.",[163,167,168],{},"ZIO 2.1.26. kyo-zio 1.0.0-RC7 pins this version; keep your own ZIO dependencies on it.",[163,170,171,174,175,114,178,181],{},[103,172,173],{},"\"dev.yuri4n\" %%% \"zio-h3-ext\" % \"\u003Cversion>\"",", plus ",[103,176,177],{},"h3@1.15.4",[103,179,180],{},"@yuri4n\u002Fh34s-nuxt"," in your Nuxt app.",[99,183,184,185,188,189,192,193,192,196,192,199,202],{},"Import the API with ",[103,186,187],{},"import dev.yuri4n.exts.zioh3.*",". It re-exports the shared values (",[103,190,191],{},"Request",", ",[103,194,195],{},"ResponseHead",[103,197,198],{},"SafeError",[103,200,201],{},"Secret",", ...).",[155,204,206],{"id":205},"write-your-first-handler","Write your first handler",[99,208,209,210,213],{},"A handler is a function from the request snapshot to a ZIO program that returns the body. This is the demo's database-free route (",[103,211,212],{},"examples\u002Fnuxt\u002Fscala\u002Fzio\u002F...\u002FTestHandler.scala","), which streams three letters:",[215,216,221],"pre",{"className":217,"code":218,"language":219,"meta":220,"style":220},"language-scala shiki shiki-themes github-light github-light github-dark","import dev.yuri4n.exts.zioh3.{EventHandler, HandlerEnv, Request, Response, Route, Sent, ZHandler}\nimport zio.ZIO\nimport zio.stream.ZStream\n\nimport scala.scalajs.js.annotation.JSExportTopLevel\n\nobject TestHandler:\n    val letters: Request => ZIO[HandlerEnv, Throwable, Sent] = _ => Response.sendStream(ZStream(\"a\", \"b\", \"c\"))\n\n@JSExportTopLevel(\"default\", \"test\")\nval handler: EventHandler = ZHandler.define(TestHandler.letters).at(Route.any(\"\u002Fapi\u002Ftest\"))\n","scala","",[103,222,223,291,304,321,328,356,361,373,449,454,476],{"__ignoreMap":220},[224,225,228,232,236,240,243,245,248,250,253,256,259,261,264,266,268,270,273,275,278,280,283,285,288],"span",{"class":226,"line":227},"line",1,[224,229,231],{"class":230},"s8jYJ","import",[224,233,235],{"class":234},"snPdu"," dev",[224,237,239],{"class":238},"sxrX7",".",[224,241,242],{"class":234},"yuri4n",[224,244,239],{"class":238},[224,246,247],{"class":234},"exts",[224,249,239],{"class":238},[224,251,252],{"class":234},"zioh3",[224,254,255],{"class":238},".{",[224,257,258],{"class":234},"EventHandler",[224,260,192],{"class":238},[224,262,263],{"class":234},"HandlerEnv",[224,265,192],{"class":238},[224,267,191],{"class":234},[224,269,192],{"class":238},[224,271,272],{"class":234},"Response",[224,274,192],{"class":238},[224,276,277],{"class":234},"Route",[224,279,192],{"class":238},[224,281,282],{"class":234},"Sent",[224,284,192],{"class":238},[224,286,287],{"class":234},"ZHandler",[224,289,290],{"class":238},"}\n",[224,292,294,296,299,301],{"class":226,"line":293},2,[224,295,231],{"class":230},[224,297,298],{"class":234}," zio",[224,300,239],{"class":238},[224,302,303],{"class":234},"ZIO\n",[224,305,307,309,311,313,316,318],{"class":226,"line":306},3,[224,308,231],{"class":230},[224,310,298],{"class":234},[224,312,239],{"class":238},[224,314,315],{"class":234},"stream",[224,317,239],{"class":238},[224,319,320],{"class":234},"ZStream\n",[224,322,324],{"class":226,"line":323},4,[224,325,327],{"emptyLinePlaceholder":326},true,"\n",[224,329,331,333,336,338,341,343,346,348,351,353],{"class":226,"line":330},5,[224,332,231],{"class":230},[224,334,335],{"class":234}," scala",[224,337,239],{"class":238},[224,339,340],{"class":234},"scalajs",[224,342,239],{"class":238},[224,344,345],{"class":234},"js",[224,347,239],{"class":238},[224,349,350],{"class":234},"annotation",[224,352,239],{"class":238},[224,354,355],{"class":234},"JSExportTopLevel\n",[224,357,359],{"class":226,"line":358},6,[224,360,327],{"emptyLinePlaceholder":326},[224,362,364,367,370],{"class":226,"line":363},7,[224,365,366],{"class":230},"object",[224,368,369],{"class":234}," TestHandler",[224,371,372],{"class":230},":\n",[224,374,376,379,383,386,389,392,395,398,400,402,405,407,409,412,415,418,421,424,427,429,432,436,438,441,443,446],{"class":226,"line":375},8,[224,377,378],{"class":230},"    val",[224,380,382],{"class":381},"sP4rz"," letters",[224,384,385],{"class":230},":",[224,387,388],{"class":234}," Request",[224,390,391],{"class":230}," =>",[224,393,394],{"class":234}," ZIO",[224,396,397],{"class":238},"[",[224,399,263],{"class":234},[224,401,192],{"class":238},[224,403,404],{"class":234},"Throwable",[224,406,192],{"class":238},[224,408,282],{"class":234},[224,410,411],{"class":238},"] ",[224,413,414],{"class":230},"=",[224,416,417],{"class":238}," _ ",[224,419,420],{"class":230},"=>",[224,422,423],{"class":234}," Response",[224,425,426],{"class":238},".sendStream(",[224,428,117],{"class":234},[224,430,431],{"class":238},"(",[224,433,435],{"class":434},"sIIMD","\"a\"",[224,437,192],{"class":238},[224,439,440],{"class":434},"\"b\"",[224,442,192],{"class":238},[224,444,445],{"class":434},"\"c\"",[224,447,448],{"class":238},"))\n",[224,450,452],{"class":226,"line":451},9,[224,453,327],{"emptyLinePlaceholder":326},[224,455,457,460,463,465,468,470,473],{"class":226,"line":456},10,[224,458,459],{"class":230},"@",[224,461,462],{"class":234},"JSExportTopLevel",[224,464,431],{"class":238},[224,466,467],{"class":434},"\"default\"",[224,469,192],{"class":238},[224,471,472],{"class":434},"\"test\"",[224,474,475],{"class":238},")\n",[224,477,479,482,485,487,490,493,496,499,502,505,507,510,513],{"class":226,"line":478},11,[224,480,481],{"class":230},"val",[224,483,484],{"class":381}," handler",[224,486,385],{"class":230},[224,488,489],{"class":234}," EventHandler",[224,491,492],{"class":230}," =",[224,494,495],{"class":234}," ZHandler",[224,497,498],{"class":238},".define(",[224,500,501],{"class":234},"TestHandler",[224,503,504],{"class":238},".letters).at(",[224,506,277],{"class":234},[224,508,509],{"class":238},".any(",[224,511,512],{"class":434},"\"\u002Fapi\u002Ftest\"",[224,514,448],{"class":238},[99,516,517,518,118,521,524,525,527,528,531,532,535,536,539,540,239],{},"The response body is ",[103,519,520],{},"abc",[103,522,523],{},"Response.sendStream"," writes the head, then the stream, and gives ",[103,526,282],{},", which is the handler's body. ",[103,529,530],{},".at"," mounts the export at ",[103,533,534],{},"\u002Fapi\u002Ftest"," for every method: after ",[103,537,538],{},"h34s-scala"," links it, the Nuxt module registers the route, so you write no route file. See ",[150,541,542,543],{"href":20},"routes and typed ",[103,544,545],{},"$fetch",[155,547,549],{"id":548},"keep-handler-functions-small-and-testable","Keep handler functions small and testable",[99,551,552,553,556],{},"The demo keeps each handler as a plain value, so a test can call it with a fake request (",[103,554,555],{},"examples\u002Fnuxt\u002Fscala\u002Fzio\u002F...\u002FNotesHandler.scala","):",[215,558,560],{"className":217,"code":559,"language":219,"meta":220,"style":220},"object NotesHandler:\n    val list: Request => ZIO[Notes, Throwable, List[NoteView]] =\n      _ => ZIO.serviceWithZIO[Notes](_.list).map(_.map(NoteView.from))\n\n    \u002F** The schema validates and trims the input before any database work; the handler adds no\n      * validation code.\n      *\u002F\n    val create: Request => ZIO[HandlerEnv & Notes, Throwable, NoteView] = request =>\n      for\n        input \u003C- request.body.json[CreateNote]\n        note  \u003C- ZIO.serviceWithZIO[Notes](_.create(input.text))\n        _     \u003C- Response.status(Status.Created)\n      yield NoteView.from(note)\n\n@JSExportTopLevel(\"default\", \"notes-get\")\nval listNotes: EventHandler = AppHandler.define(NotesHandler.list).at(Route.get(\"\u002Fapi\u002Fnotes\"))\n\n@JSExportTopLevel(\"default\", \"notes-post\")\nval createNote: EventHandler = AppHandler.define(NotesHandler.create).at(Route.post(\"\u002Fapi\u002Fnotes\"))\n",[103,561,562,571,611,633,637,643,648,653,696,701,718,734,757,769,774,792,827,832,850],{"__ignoreMap":220},[224,563,564,566,569],{"class":226,"line":227},[224,565,366],{"class":230},[224,567,568],{"class":234}," NotesHandler",[224,570,372],{"class":230},[224,572,573,575,578,580,582,584,586,588,591,593,595,597,600,602,605,608],{"class":226,"line":293},[224,574,378],{"class":230},[224,576,577],{"class":381}," list",[224,579,385],{"class":230},[224,581,388],{"class":234},[224,583,391],{"class":230},[224,585,394],{"class":234},[224,587,397],{"class":238},[224,589,590],{"class":234},"Notes",[224,592,192],{"class":238},[224,594,404],{"class":234},[224,596,192],{"class":238},[224,598,599],{"class":234},"List",[224,601,397],{"class":238},[224,603,604],{"class":234},"NoteView",[224,606,607],{"class":238},"]] ",[224,609,610],{"class":230},"=\n",[224,612,613,616,618,620,623,625,628,630],{"class":226,"line":306},[224,614,615],{"class":238},"      _ ",[224,617,420],{"class":230},[224,619,394],{"class":234},[224,621,622],{"class":238},".serviceWithZIO[",[224,624,590],{"class":234},[224,626,627],{"class":238},"](_.list).map(_.map(",[224,629,604],{"class":234},[224,631,632],{"class":238},".from))\n",[224,634,635],{"class":226,"line":323},[224,636,327],{"emptyLinePlaceholder":326},[224,638,639],{"class":226,"line":330},[224,640,642],{"class":641},"sCsY4","    \u002F** The schema validates and trims the input before any database work; the handler adds no\n",[224,644,645],{"class":226,"line":358},[224,646,647],{"class":641},"      * validation code.\n",[224,649,650],{"class":226,"line":363},[224,651,652],{"class":641},"      *\u002F\n",[224,654,655,657,660,662,664,666,668,670,672,675,678,680,682,684,686,688,690,693],{"class":226,"line":375},[224,656,378],{"class":230},[224,658,659],{"class":381}," create",[224,661,385],{"class":230},[224,663,388],{"class":234},[224,665,391],{"class":230},[224,667,394],{"class":234},[224,669,397],{"class":238},[224,671,263],{"class":234},[224,673,674],{"class":230}," &",[224,676,677],{"class":234}," Notes",[224,679,192],{"class":238},[224,681,404],{"class":234},[224,683,192],{"class":238},[224,685,604],{"class":234},[224,687,411],{"class":238},[224,689,414],{"class":230},[224,691,692],{"class":238}," request ",[224,694,695],{"class":230},"=>\n",[224,697,698],{"class":226,"line":451},[224,699,700],{"class":230},"      for\n",[224,702,703,706,709,712,715],{"class":226,"line":456},[224,704,705],{"class":238},"        input ",[224,707,708],{"class":230},"\u003C-",[224,710,711],{"class":238}," request.body.json[",[224,713,714],{"class":234},"CreateNote",[224,716,717],{"class":238},"]\n",[224,719,720,723,725,727,729,731],{"class":226,"line":478},[224,721,722],{"class":238},"        note  ",[224,724,708],{"class":230},[224,726,394],{"class":234},[224,728,622],{"class":238},[224,730,590],{"class":234},[224,732,733],{"class":238},"](_.create(input.text))\n",[224,735,737,740,742,744,747,750,752,755],{"class":226,"line":736},12,[224,738,739],{"class":238},"        _     ",[224,741,708],{"class":230},[224,743,423],{"class":234},[224,745,746],{"class":238},".status(",[224,748,749],{"class":234},"Status",[224,751,239],{"class":238},[224,753,754],{"class":234},"Created",[224,756,475],{"class":238},[224,758,760,763,766],{"class":226,"line":759},13,[224,761,762],{"class":230},"      yield",[224,764,765],{"class":234}," NoteView",[224,767,768],{"class":238},".from(note)\n",[224,770,772],{"class":226,"line":771},14,[224,773,327],{"emptyLinePlaceholder":326},[224,775,777,779,781,783,785,787,790],{"class":226,"line":776},15,[224,778,459],{"class":230},[224,780,462],{"class":234},[224,782,431],{"class":238},[224,784,467],{"class":434},[224,786,192],{"class":238},[224,788,789],{"class":434},"\"notes-get\"",[224,791,475],{"class":238},[224,793,795,797,800,802,804,806,809,811,814,817,819,822,825],{"class":226,"line":794},16,[224,796,481],{"class":230},[224,798,799],{"class":381}," listNotes",[224,801,385],{"class":230},[224,803,489],{"class":234},[224,805,492],{"class":230},[224,807,808],{"class":234}," AppHandler",[224,810,498],{"class":238},[224,812,813],{"class":234},"NotesHandler",[224,815,816],{"class":238},".list).at(",[224,818,277],{"class":234},[224,820,821],{"class":238},".get(",[224,823,824],{"class":434},"\"\u002Fapi\u002Fnotes\"",[224,826,448],{"class":238},[224,828,830],{"class":226,"line":829},17,[224,831,327],{"emptyLinePlaceholder":326},[224,833,835,837,839,841,843,845,848],{"class":226,"line":834},18,[224,836,459],{"class":230},[224,838,462],{"class":234},[224,840,431],{"class":238},[224,842,467],{"class":434},[224,844,192],{"class":238},[224,846,847],{"class":434},"\"notes-post\"",[224,849,475],{"class":238},[224,851,853,855,858,860,862,864,866,868,870,873,875,878,880],{"class":226,"line":852},19,[224,854,481],{"class":230},[224,856,857],{"class":381}," createNote",[224,859,385],{"class":230},[224,861,489],{"class":234},[224,863,492],{"class":230},[224,865,808],{"class":234},[224,867,498],{"class":238},[224,869,813],{"class":234},[224,871,872],{"class":238},".create).at(",[224,874,277],{"class":234},[224,876,877],{"class":238},".post(",[224,879,824],{"class":434},[224,881,448],{"class":238},[99,883,884,885,888,889,892,893,895,896,899],{},"Nuxt types ",[103,886,887],{},"$fetch('\u002Fapi\u002Fnotes')"," as ",[103,890,891],{},"{ data: { id: number; text: string }[] }",": ",[103,894,604],{}," derives ",[103,897,898],{},"NativeSchema",", which describes the JSON it writes.",[99,901,902,192,904,907,908,910,911,913,914,917],{},[103,903,590],{},[103,905,906],{},"Note"," (the domain note), ",[103,909,604],{}," (the JSON it sends), ",[103,912,714],{}," (the JSON it reads) and ",[103,915,916],{},"AppHandler"," are demo code. Define your own.",[155,919,921],{"id":920},"read-the-request","Read the request",[99,923,924,925,927,928,931],{},"The ",[103,926,191],{}," snapshot is the same value the Kyo core uses; see ",[150,929,23],{"href":930},"\u002Fguide\u002Fkyo#read-the-request"," for every member and for the body status codes. The ZIO signatures:",[933,934,935,948],"table",{},[936,937,938],"thead",{},[939,940,941,945],"tr",{},[942,943,944],"th",{},"Call",[942,946,947],{},"Type",[949,950,951,964,977,989],"tbody",{},[939,952,953,959],{},[954,955,956],"td",{},[103,957,958],{},"request.body.json[A]",[954,960,961],{},[103,962,963],{},"IO[HttpError | InvalidInput, A]",[939,965,966,971],{},[954,967,968],{},[103,969,970],{},"request.body.json[A](limit)",[954,972,973,974],{},"the same, with an explicit ",[103,975,976],{},"BodyLimit",[939,978,979,984],{},[954,980,981],{},[103,982,983],{},"request.body.text()",[954,985,986],{},[103,987,988],{},"IO[HttpError, String]",[939,990,991,996],{},[954,992,993],{},[103,994,995],{},"request.param(name)",[954,997,998,1000],{},[103,999,988],{},"; 400 when absent",[155,1002,1004],{"id":1003},"return-a-body","Return a body",[933,1006,1007,1016],{},[936,1008,1009],{},[939,1010,1011,1014],{},[942,1012,1013],{},"Return type",[942,1015,272],{},[949,1017,1018,1036,1046],{},[939,1019,1020,1030],{},[954,1021,1022,1023,1026,1027],{},"Any ",[103,1024,1025],{},"A"," with a ",[103,1028,1029],{},"NativeConverter",[954,1031,1032,1033],{},"200 (or the status you set) with ",[103,1034,1035],{},"{\"data\": \u003Cvalue>}",[939,1037,1038,1043],{},[954,1039,1040],{},[103,1041,1042],{},"Unit",[954,1044,1045],{},"204 with no body, unless you set another status",[939,1047,1048,1056],{},[954,1049,1050,1052,1053],{},[103,1051,282],{},", from ",[103,1054,1055],{},"Response.sendStream(stream)",[954,1057,1058,1059],{},"The stream's strings, written as UTF-8 text as they come; see ",[150,1060,1061],{"href":48},"streaming",[99,1063,1064,1065,1067,1068,1070,1071,1074,1075,1078,1079,1081,1082,1084,1085,1088,1089,239],{},"A ",[103,1066,117],{}," is not a body. To stream, end your handler with ",[103,1069,1055],{},", where the stream is a ",[103,1072,1073],{},"ZStream[Any, E, String]"," with ",[103,1076,1077],{},"E \u003C: Throwable",", and return its ",[103,1080,282],{},". A handler that returns a ",[103,1083,117],{}," does not compile. ",[103,1086,1087],{},"ZHandler.sendStream"," is gone; see the ",[150,1090,152],{"href":91},[155,1092,1094],{"id":1093},"set-status-headers-and-cookies","Set status, headers and cookies",[99,1096,1097,1099,1100,892,1103,192,1106,192,1109,192,1112,192,1115,192,1118,1121,1122,1125,1126,1128,1129,118,1131,1134,1135,1138,1139,1142,1143,1147,1148,1151],{},[103,1098,272],{}," has the same operations as the Kyo API, as ",[103,1101,1102],{},"URIO[ZState[ResponseHead], Unit]",[103,1104,1105],{},"status",[103,1107,1108],{},"header",[103,1110,1111],{},"appendHeader",[103,1113,1114],{},"cookie",[103,1116,1117],{},"deleteCookie(name, path, domain, secure, onFailure)",[103,1119,1120],{},"redirect",", and ",[103,1123,1124],{},"head",". h34s writes the head once, after your program and its finalizers finish. ",[103,1127,1055],{}," is the one exception: it writes the head as it stands when it runs, then the stream, and gives ",[103,1130,282],{},[103,1132,1133],{},"Response.sendEvents(events)"," is ",[103,1136,1137],{},"sendStream"," for a ",[103,1140,1141],{},"ZStream[Any, E, ServerEvent]",": it sets the event-stream headers and writes one frame per event; see ",[150,1144,1146],{"href":1145},"\u002Fguide\u002Fstreaming#server-sent-events","server-sent events",". The failure rule is the same: on failure, the status comes from the error, and only handler defaults, ",[103,1149,1150],{},"OnFailure.Keep"," entries and the error's headers survive.",[99,1153,1154],{},"Two ZIO details:",[160,1156,1157,1170],{},[163,1158,1159,1162,1163,1166,1167,1169],{},[103,1160,1161],{},"ZState"," is backed by a ",[103,1164,1165],{},"FiberRef",". A forked fiber works on its own copy of the head; joining it copies the child's head back into the parent (ZIO's default ",[103,1168,1165],{}," join). Set response entries in the request fiber when you can.",[163,1171,1172,1175],{},[103,1173,1174],{},"catchAll"," and other recoveries do not roll back head changes.",[99,1177,1178],{},"An invalid header name or value, cookie name, or redirect status makes the effect die, and h34s answers with a 500.",[155,1180,1182],{"id":1181},"fail-safely","Fail safely",[933,1184,1185,1197],{},[936,1186,1187],{},[939,1188,1189,1192,1194],{},[942,1190,1191],{},"Failure",[942,1193,749],{},[942,1195,1196],{},"Body (default options)",[949,1198,1199,1216,1230,1248],{},[939,1200,1201,1206,1211],{},[954,1202,1203],{},[103,1204,1205],{},"ZIO.fail(safeError)",[954,1207,1208],{},[103,1209,1210],{},"safeError.status",[954,1212,1213],{},[103,1214,1215],{},"{\"errors\":[{\"message\":\"...\"}]}",[939,1217,1218,1223,1227],{},[954,1219,1220],{},[103,1221,1222],{},"ZHandler.failWith(status, msg, msgs*)",[954,1224,1225],{},[103,1226,1105],{},[954,1228,1229],{},"one entry per message",[939,1231,1232,1238,1241],{},[954,1233,1234,1237],{},[103,1235,1236],{},"InvalidInput"," from a body read",[954,1239,1240],{},"422",[954,1242,1243,1244,1247],{},"one entry per schema message, with ",[103,1245,1246],{},"path"," when known",[939,1249,1250,1253,1256],{},[954,1251,1252],{},"Any other typed failure, a defect, interruption, or several failures",[954,1254,1255],{},"500",[954,1257,1258],{},[103,1259,1260],{},"{\"errors\":[{\"message\":\"Internal server error\"}]}",[99,1262,1263,1266,1267,1270,1271,118,1273,1276,1277,1279,1280,1283,1284,1287,1288,1291,1292,1294,1295,1297,1298,1301,1302,1304,1305,1307],{},[103,1264,1265],{},"ZHandler.failWith"," fails with ",[103,1268,1269],{},"ErrorResponse(errors, status)",", as in ",[103,1272,147],{},[103,1274,1275],{},"ErrorResponse"," is not a ",[103,1278,198],{}," (its ",[103,1281,1282],{},"errors"," field is a ",[103,1285,1286],{},"NonEmptyList[String]","), so ",[103,1289,1290],{},"catchSome { case e: SafeError => ... }"," does not catch it; h34s approves both at the boundary. A ",[103,1293,198],{}," or ",[103,1296,1275],{}," stays approved even when sibling fibers were interrupted with it (for example in ",[103,1299,1300],{},"zipPar","). Any other ",[103,1303,404],{}," in the error channel is not approved: catching an exception and failing with it does not make it public. Map it to your own ",[103,1306,198],{}," instead.",[99,1309,1310,1311,1314,1315,1318,1319,1321,1322,1294,1325,1328,1329,1332,1333,1336,1337,1339],{},"A ZIO finalizer that dies does not change the response, as in Kyo: h34s logs ",[103,1312,1313],{},"h34s: a ZIO finalizer failed"," with ZIO's ",[103,1316,1317],{},"Cause.prettyPrint"," on the server, and the client gets the value, the ",[103,1320,1042],{}," response or the safe error that your program produced. Do work that must affect the response in the program, not in a finalizer. The rule applies to the request scope that h34s owns (finalizers your handler adds with ",[103,1323,1324],{},"ZIO.addFinalizer",[103,1326,1327],{},"ZIO.acquireRelease"," in its request ",[103,1330,1331],{},"Scope","). A release that dies inside your own ",[103,1334,1335],{},"ZIO.scoped"," block, or inside a scoped layer that you provide inside the handler, fails the program under ZIO's rules and answers 500, as before. In development or debug mode, the diagnostics of a failed program show ZIO's full ",[103,1338,1317],{},", with ZIO traces and Scala source lines.",[155,1341,1343],{"id":1342},"choose-the-wire-format","Choose the wire format",[99,1345,1346,1349,1350,1353],{},[103,1347,1348],{},"ZHandler.define(options)"," takes the same ",[103,1351,1352],{},"HandlerOptions"," as the Kyo core:",[215,1355,1357],{"className":217,"code":1356,"language":219,"meta":220,"style":220},"ZHandler.define(HandlerOptions(defaults = ResponseHead.noStore)): request =>\n  ...\n",[103,1358,1359,1384],{"__ignoreMap":220},[224,1360,1361,1363,1365,1367,1370,1372,1375,1378,1380,1382],{"class":226,"line":227},[224,1362,287],{"class":234},[224,1364,498],{"class":238},[224,1366,1352],{"class":234},[224,1368,1369],{"class":238},"(defaults ",[224,1371,414],{"class":230},[224,1373,1374],{"class":234}," ResponseHead",[224,1376,1377],{"class":238},".noStore))",[224,1379,385],{"class":230},[224,1381,692],{"class":238},[224,1383,695],{"class":230},[224,1385,1386],{"class":226,"line":293},[224,1387,1388],{"class":238},"  ...\n",[99,1390,1391,1392,1395,1396,1399,1400,1404],{},"See ",[150,1393,23],{"href":1394},"\u002Fguide\u002Fkyo#choose-the-wire-format"," for the envelopes, defaults, body limit and ",[103,1397,1398],{},"requireJsonContentType"," (see ",[150,1401,1403],{"href":1402},"\u002Fguide\u002Fkyo#cross-site-requests","cross-site requests",").",[155,1406,1408],{"id":1407},"compose-services-in-your-apphandler","Compose services in your AppHandler",[99,1410,1411,1412,556],{},"Write one wiring point that provides your layers. This is the demo's (",[103,1413,1414],{},"examples\u002Fnuxt\u002Fscala\u002Fzio\u002F...\u002FAppHandler.scala",[215,1416,1418],{"className":217,"code":1417,"language":219,"meta":220,"style":220},"object AppHandler:\n    \u002F** Every response is `Cache-Control: no-store`; bodies use the default `{ \"data\": ... }` envelope. *\u002F\n    private val options = HandlerOptions(defaults = ResponseHead.noStore)\n\n    \u002F** One Skunk pool for all requests: built when the first note needs a session, released when Nitro closes. *\u002F\n    private val database = ZShared.layer(SessionPool.layer)\n\n    \u002F** The greeting service, built from the startup runtime config on first use. It needs no database. *\u002F\n    private val greetings = ZShared.layer(Greetings.layer)\n\n    \u002F** `Notes` takes the pool only when a note operation runs, so a greeting never builds the pool. *\u002F\n    private val notes = NotesLive.lazily(database.get.map(_.get[SessionPool]))\n\n    def define[B: ZResponseBody](program: Request => ZIO[HandlerEnv & Notes & Greetings, Throwable, B]): EventHandler =\n      ZHandler.define(options): request =>\n          greetings.provide[HandlerEnv, Throwable, B](program(request).provideSomeLayer[HandlerEnv & Greetings](notes))\n",[103,1419,1420,1428,1433,1458,1462,1467,1490,1494,1499,1519,1523,1528,1550,1554,1617,1631],{"__ignoreMap":220},[224,1421,1422,1424,1426],{"class":226,"line":227},[224,1423,366],{"class":230},[224,1425,808],{"class":234},[224,1427,372],{"class":230},[224,1429,1430],{"class":226,"line":293},[224,1431,1432],{"class":641},"    \u002F** Every response is `Cache-Control: no-store`; bodies use the default `{ \"data\": ... }` envelope. *\u002F\n",[224,1434,1435,1438,1441,1444,1446,1449,1451,1453,1455],{"class":226,"line":306},[224,1436,1437],{"class":230},"    private",[224,1439,1440],{"class":230}," val",[224,1442,1443],{"class":381}," options",[224,1445,492],{"class":230},[224,1447,1448],{"class":234}," HandlerOptions",[224,1450,1369],{"class":238},[224,1452,414],{"class":230},[224,1454,1374],{"class":234},[224,1456,1457],{"class":238},".noStore)\n",[224,1459,1460],{"class":226,"line":323},[224,1461,327],{"emptyLinePlaceholder":326},[224,1463,1464],{"class":226,"line":330},[224,1465,1466],{"class":641},"    \u002F** One Skunk pool for all requests: built when the first note needs a session, released when Nitro closes. *\u002F\n",[224,1468,1469,1471,1473,1476,1478,1481,1484,1487],{"class":226,"line":358},[224,1470,1437],{"class":230},[224,1472,1440],{"class":230},[224,1474,1475],{"class":381}," database",[224,1477,492],{"class":230},[224,1479,1480],{"class":234}," ZShared",[224,1482,1483],{"class":238},".layer(",[224,1485,1486],{"class":234},"SessionPool",[224,1488,1489],{"class":238},".layer)\n",[224,1491,1492],{"class":226,"line":363},[224,1493,327],{"emptyLinePlaceholder":326},[224,1495,1496],{"class":226,"line":375},[224,1497,1498],{"class":641},"    \u002F** The greeting service, built from the startup runtime config on first use. It needs no database. *\u002F\n",[224,1500,1501,1503,1505,1508,1510,1512,1514,1517],{"class":226,"line":451},[224,1502,1437],{"class":230},[224,1504,1440],{"class":230},[224,1506,1507],{"class":381}," greetings",[224,1509,492],{"class":230},[224,1511,1480],{"class":234},[224,1513,1483],{"class":238},[224,1515,1516],{"class":234},"Greetings",[224,1518,1489],{"class":238},[224,1520,1521],{"class":226,"line":456},[224,1522,327],{"emptyLinePlaceholder":326},[224,1524,1525],{"class":226,"line":478},[224,1526,1527],{"class":641},"    \u002F** `Notes` takes the pool only when a note operation runs, so a greeting never builds the pool. *\u002F\n",[224,1529,1530,1532,1534,1537,1539,1542,1545,1547],{"class":226,"line":736},[224,1531,1437],{"class":230},[224,1533,1440],{"class":230},[224,1535,1536],{"class":381}," notes",[224,1538,492],{"class":230},[224,1540,1541],{"class":234}," NotesLive",[224,1543,1544],{"class":238},".lazily(database.get.map(_.get[",[224,1546,1486],{"class":234},[224,1548,1549],{"class":238},"]))\n",[224,1551,1552],{"class":226,"line":759},[224,1553,327],{"emptyLinePlaceholder":326},[224,1555,1556,1559,1562,1564,1567,1569,1572,1575,1578,1580,1582,1584,1586,1588,1590,1592,1594,1596,1599,1601,1603,1605,1607,1610,1612,1614],{"class":226,"line":771},[224,1557,1558],{"class":230},"    def",[224,1560,1561],{"class":234}," define",[224,1563,397],{"class":238},[224,1565,1566],{"class":234},"B",[224,1568,385],{"class":230},[224,1570,1571],{"class":234}," ZResponseBody",[224,1573,1574],{"class":238},"](",[224,1576,1577],{"class":381},"program",[224,1579,892],{"class":238},[224,1581,191],{"class":234},[224,1583,391],{"class":230},[224,1585,394],{"class":234},[224,1587,397],{"class":238},[224,1589,263],{"class":234},[224,1591,674],{"class":230},[224,1593,677],{"class":234},[224,1595,674],{"class":230},[224,1597,1598],{"class":234}," Greetings",[224,1600,192],{"class":238},[224,1602,404],{"class":234},[224,1604,192],{"class":238},[224,1606,1566],{"class":234},[224,1608,1609],{"class":238},"])",[224,1611,385],{"class":230},[224,1613,489],{"class":234},[224,1615,1616],{"class":230}," =\n",[224,1618,1619,1622,1625,1627,1629],{"class":226,"line":776},[224,1620,1621],{"class":234},"      ZHandler",[224,1623,1624],{"class":238},".define(options)",[224,1626,385],{"class":230},[224,1628,692],{"class":238},[224,1630,695],{"class":230},[224,1632,1633,1636,1638,1640,1642,1644,1646,1649,1651,1653,1655],{"class":226,"line":794},[224,1634,1635],{"class":238},"          greetings.provide[",[224,1637,263],{"class":234},[224,1639,192],{"class":238},[224,1641,404],{"class":234},[224,1643,192],{"class":238},[224,1645,1566],{"class":234},[224,1647,1648],{"class":238},"](program(request).provideSomeLayer[",[224,1650,263],{"class":234},[224,1652,674],{"class":230},[224,1654,1598],{"class":234},[224,1656,1657],{"class":238},"](notes))\n",[99,1659,1660,1663,1664,1667,1668,1671,1672,1674],{},[103,1661,1662],{},"NotesLive.lazily"," runs ",[103,1665,1666],{},"database.get"," only when a note operation first needs a session. So ",[103,1669,1670],{},"POST \u002Fapi\u002Fzio\u002Fgreeting",", which uses ",[103,1673,1516],{}," alone, never reads the database config and never builds the Skunk pool.",[99,1676,1677,1134,1679,1682,1683,1685,1686,1688,1689,1692,1693,1695,1696,1699,1700,1702,1703,1706],{},[103,1678,263],{},[103,1680,1681],{},"ZState[ResponseHead] & Scope & HandlerTransport & Fetch",": what h34s supplies to every ZIO handler. The ",[103,1684,1331],{}," is the request scope. It stays open while ",[103,1687,523],{}," sends a stream. ",[103,1690,1691],{},"HandlerTransport"," is the native response that ",[103,1694,523],{}," writes, and ",[103,1697,1698],{},"Fetch"," is the server-side ",[103,1701,545],{}," of the request. h34s provides both, and ",[103,1704,1705],{},"ZHandler.test"," provides them in a test, so you never build them.",[99,1708,1709,1710,192,1713,114,1716,1718,1719,1721,1722,1725,1726,239],{},"Use ordinary ",[103,1711,1712],{},"provide",[103,1714,1715],{},"provideSomeLayer",[103,1717,113],{}," composition. A ",[103,1720,113],{}," value is rebuilt each time you provide it. For a resource that all requests share, such as a pool, wrap the layer in ",[103,1723,1724],{},"ZShared","; see ",[150,1727,1728],{"href":36},"lifetimes",[99,1730,1731,1733,1734,1737,1738,1741],{},[103,1732,121],{}," runs on ",[103,1735,1736],{},"Runtime.default"," unless a ",[103,1739,1740],{},"given Runtime[Any]"," is in scope. You do not need to create one.",[155,1743,1745,1746],{"id":1744},"call-other-routes-with-fetch","Call other routes with ",[103,1747,545],{},[99,1749,1750,1751,1754,1755,1758],{},"A handler can call another route of your app, Scala or JavaScript, with ",[103,1752,1753],{},"ZHandler.$fetch",". It follows the rules of the Kyo core, which it runs at the boundary: Nitro answers a path that starts with ",[103,1756,1757],{},"\u002F"," in-process, without a socket, and your route rules, middleware and Nitro plugins run as they do for a browser request.",[99,1760,1761,1762,1765,1766,1121,1769,1772,1773,118,1775,1778,1779,1782,1783,1786,1787,1789,1790,385],{},"In this example, ",[103,1763,1764],{},"\u002Fapi\u002Fgreeting"," is an h34s route that returns ",[103,1767,1768],{},"Greeting(\"hi\")",[103,1770,1771],{},"\u002Fapi\u002Fevents"," sends NDJSON lines with ",[103,1774,523],{},[103,1776,1777],{},"GreetingData"," is the example's model of the ",[103,1780,1781],{},"{\"data\": ...}"," envelope: ",[103,1784,1785],{},"final case class GreetingData(data: Greeting) derives NativeConverter",". The code is the guide's ",[103,1788,545],{}," test of ",[103,1791,1792],{},"NitroLocalFetchSpec",[215,1794,1796],{"className":217,"code":1795,"language":219,"meta":220,"style":220},"val summary: Request => ZIO[HandlerEnv, FetchError, String] = _ =>\n  for\n    greeting \u003C- ZHandler.$fetch.get[GreetingData](\"\u002Fapi\u002Fgreeting\")\n    events   \u003C- ZHandler.$fetch.raw(\"\u002Fapi\u002Fevents\")\n    first    \u003C- events match\n      case FetchResponse.Streamed(_, _, body) => body.take(2).runCollect.map(_.mkString).orElseSucceed(\"the stream broke\")\n      case plain: FetchResponse.Plain         => ZIO.succeed(plain.text)\n  yield s\"${greeting.data.message}: $first\"\n",[103,1797,1798,1835,1840,1861,1878,1891,1924,1949],{"__ignoreMap":220},[224,1799,1800,1802,1805,1807,1809,1811,1813,1815,1817,1819,1822,1824,1827,1829,1831,1833],{"class":226,"line":227},[224,1801,481],{"class":230},[224,1803,1804],{"class":381}," summary",[224,1806,385],{"class":230},[224,1808,388],{"class":234},[224,1810,391],{"class":230},[224,1812,394],{"class":234},[224,1814,397],{"class":238},[224,1816,263],{"class":234},[224,1818,192],{"class":238},[224,1820,1821],{"class":234},"FetchError",[224,1823,192],{"class":238},[224,1825,1826],{"class":234},"String",[224,1828,411],{"class":238},[224,1830,414],{"class":230},[224,1832,417],{"class":238},[224,1834,695],{"class":230},[224,1836,1837],{"class":226,"line":293},[224,1838,1839],{"class":230},"  for\n",[224,1841,1842,1845,1847,1849,1852,1854,1856,1859],{"class":226,"line":306},[224,1843,1844],{"class":238},"    greeting ",[224,1846,708],{"class":230},[224,1848,495],{"class":234},[224,1850,1851],{"class":238},".$fetch.get[",[224,1853,1777],{"class":234},[224,1855,1574],{"class":238},[224,1857,1858],{"class":434},"\"\u002Fapi\u002Fgreeting\"",[224,1860,475],{"class":238},[224,1862,1863,1866,1868,1870,1873,1876],{"class":226,"line":323},[224,1864,1865],{"class":238},"    events   ",[224,1867,708],{"class":230},[224,1869,495],{"class":234},[224,1871,1872],{"class":238},".$fetch.raw(",[224,1874,1875],{"class":434},"\"\u002Fapi\u002Fevents\"",[224,1877,475],{"class":238},[224,1879,1880,1883,1885,1888],{"class":226,"line":330},[224,1881,1882],{"class":238},"    first    ",[224,1884,708],{"class":230},[224,1886,1887],{"class":238}," events ",[224,1889,1890],{"class":230},"match\n",[224,1892,1893,1896,1899,1901,1904,1907,1909,1912,1916,1919,1922],{"class":226,"line":358},[224,1894,1895],{"class":230},"      case",[224,1897,1898],{"class":234}," FetchResponse",[224,1900,239],{"class":238},[224,1902,1903],{"class":234},"Streamed",[224,1905,1906],{"class":238},"(_, _, body) ",[224,1908,420],{"class":230},[224,1910,1911],{"class":238}," body.take(",[224,1913,1915],{"class":1914},"sBjJW","2",[224,1917,1918],{"class":238},").runCollect.map(_.mkString).orElseSucceed(",[224,1920,1921],{"class":434},"\"the stream broke\"",[224,1923,475],{"class":238},[224,1925,1926,1928,1931,1933,1936,1938,1941,1944,1946],{"class":226,"line":363},[224,1927,1895],{"class":230},[224,1929,1930],{"class":381}," plain",[224,1932,892],{"class":238},[224,1934,1935],{"class":234},"FetchResponse",[224,1937,239],{"class":238},[224,1939,1940],{"class":234},"Plain",[224,1942,1943],{"class":230},"         =>",[224,1945,394],{"class":234},[224,1947,1948],{"class":238},".succeed(plain.text)\n",[224,1950,1951,1954,1957,1960,1963,1965,1968],{"class":226,"line":375},[224,1952,1953],{"class":230},"  yield",[224,1955,1956],{"class":230}," s",[224,1958,1959],{"class":434},"\"",[224,1961,1962],{"class":238},"${greeting.data.message}",[224,1964,892],{"class":434},[224,1966,1967],{"class":238},"$first",[224,1969,1970],{"class":434},"\"\n",[99,1972,1973,1974,1977],{},"The handler answers ",[103,1975,1976],{},"\"hi: 1\\n2\\n\"",". Keep these rules in mind:",[160,1979,1980,2009,2043,2061,2095,2116,2132,2156,2167,2187],{},[163,1981,1982,1985,1986,192,1989,114,1992,1995,1996,1998,1999,2001,2002,2008],{},[137,1983,1984],{},"Model the envelope."," ",[103,1987,1988],{},"get",[103,1990,1991],{},"post",[103,1993,1994],{},"as"," decode the JSON as it arrives. An h34s route with the default options answers ",[103,1997,1781],{},", so decode it with a model of the envelope, such as ",[103,2000,1777],{},". The typed route call (",[150,2003,2007],{"href":2004,"rel":2005},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Fh34s\u002Fissues\u002F46",[2006],"nofollow","#46",") will remove the envelope for you, because only the route knows its options.",[163,2010,2011,1985,2014,2017,2018,2021,2022,2025,2026,192,2029,2032,2033,2036,2037,2040,2041,239],{},[137,2012,2013],{},"Plain or streamed.",[103,2015,2016],{},"raw"," returns as soon as the head arrives. It gives ",[103,2019,2020],{},"FetchResponse.Streamed"," for a response with the ",[103,2023,2024],{},"x-h34s-stream"," marker or a stream content type (",[103,2027,2028],{},"text\u002Fevent-stream",[103,2030,2031],{},"application\u002Fx-ndjson","), and ",[103,2034,2035],{},"FetchResponse.Plain"," otherwise. ",[103,2038,2039],{},"Plain.as[A]"," decodes its text with the ",[103,2042,1029],{},[163,2044,2045,2048,2049,2052,2053,2056,2057,2060],{},[137,2046,2047],{},"Read a streamed body once."," It is a ",[103,2050,2051],{},"ZStream[Any, FetchError, String]",". When the callee's stream fails after its head, or the connection closes, the stream fails with ",[103,2054,2055],{},"FetchError.BodyFailed(status, reason)",". The ",[103,2058,2059],{},"reason"," is h34s' own text; it never quotes the callee's error.",[163,2062,2063,1985,2068,2070,2071,2074,2075,2077,2078,192,2081,192,2083,114,2085,2087,2088,2090,2091,239],{},[137,2064,2065,2066,239],{},"The body lives in your ",[103,2067,1331],{},[103,2069,2016],{}," needs ",[103,2072,2073],{},"Fetch & Scope",". In a handler, that is the request scope; use ",[103,2076,1335],{}," for a shorter one. When the scope closes, h34s cancels a body that you did not read to its end, and waits until the callee's stream and request finalizers have run. ",[103,2079,2080],{},"text",[103,2082,1994],{},[103,2084,1988],{},[103,2086,1991],{}," read the whole body in their own scope, so they need only ",[103,2089,1698],{},". See ",[150,2092,2094],{"href":2093},"\u002Fguide\u002Fstreaming#in-process-calls","in-process calls",[163,2096,2097,1985,2100,2102,2103,192,2105,192,2107,114,2109,2111,2112,2115],{},[137,2098,2099],{},"Statuses do not throw.",[103,2101,2016],{}," gives any status as a response. ",[103,2104,2080],{},[103,2106,1994],{},[103,2108,1988],{},[103,2110,1991],{}," fail with ",[103,2113,2114],{},"FetchError.Status(status, body)"," unless the status is 2xx. There is no retry.",[163,2117,2118,2121,2122,2125,2126,2128,2129,2131],{},[137,2119,2120],{},"The base URL is added."," h34s puts your app's ",[103,2123,2124],{},"app.baseURL"," in front of a path that starts with ",[103,2127,1757],{},", as Nuxt's ",[103,2130,545],{}," does. A path that already starts with the base stays as it is.",[163,2133,2134,2137,2138,2140,2141,2144,2145,114,2148,2151,2152,2155],{},[137,2135,2136],{},"Credentials stay in-process."," A path that starts with ",[103,2139,1757],{}," gets the incoming request's headers and cookies, as in Nuxt. An absolute URL gets only the headers that you pass, so the user's cookies and ",[103,2142,2143],{},"authorization"," never reach another host. The called route gets only the ",[103,2146,2147],{},"_platform",[103,2149,2150],{},"waitUntil"," entries of your request's ",[103,2153,2154],{},"event.context",", never the rest.",[163,2157,2158,2161,2162,1276,2164,2166],{},[137,2159,2160],{},"Errors are not public."," A ",[103,2163,1821],{},[103,2165,198],{},". If your handler does not handle it, the client gets the opaque 500.",[163,2168,2169,1985,2172,2175,2176,118,2179,2182,2183,2186],{},[137,2170,2171],{},"Repeated headers.",[103,2173,2174],{},"header(name)"," joins repeated values with ",[103,2177,2178],{},"\", \"",[103,2180,2181],{},"headerValues(name)"," gives each ",[103,2184,2185],{},"set-cookie"," value as its own entry.",[163,2188,2189,1985,2192,2195,2196,2198,2199,2202,2203,2206,2207,2090,2210,118],{},[137,2190,2191],{},"Server-sent events.",[103,2193,2194],{},"ZHandler.$fetch.events[E](url)"," reads a ",[103,2197,2028],{}," route as a ",[103,2200,2201],{},"ZStream[Any, FetchError, E]",", each event's ",[103,2204,2205],{},"data"," decoded as JSON for ",[103,2208,2209],{},"E",[150,2211,1146],{"href":1145},[99,2213,2214,2215,1725,2218,239],{},"Test such a handler with ",[103,2216,2217],{},"Fetch.fake",[150,2219,2221,2222,2224],{"href":2220},"\u002Fguide\u002Ftesting#answer-fetch-calls","answer ",[103,2223,545],{}," calls",[155,2226,2228],{"id":2227},"type-aliases","Type aliases",[933,2230,2231,2241],{},[936,2232,2233],{},[939,2234,2235,2238],{},[942,2236,2237],{},"Alias",[942,2239,2240],{},"Meaning",[949,2242,2243,2253,2265,2289],{},[939,2244,2245,2249],{},[954,2246,2247],{},[103,2248,263],{},[954,2250,2251],{},[103,2252,1681],{},[939,2254,2255,2260],{},[954,2256,2257],{},[103,2258,2259],{},"ZHandler[R, E, A]",[954,2261,2262],{},[103,2263,2264],{},"ZIO[HandlerEnv & R, E, A]",[939,2266,2267,2284],{},[954,2268,2269,192,2272,192,2275,192,2278,192,2281],{},[103,2270,2271],{},"Handler[E, A]",[103,2273,2274],{},"TaskHandler[A]",[103,2276,2277],{},"URHandler[R, A]",[103,2279,2280],{},"UHandler[A]",[103,2282,2283],{},"RHandler[R, A]",[954,2285,2286,2287],{},"The usual ZIO shapes over ",[103,2288,263],{},[939,2290,2291,2302],{},[954,2292,2293,192,2296,192,2299],{},[103,2294,2295],{},"TaskStream[A]",[103,2297,2298],{},"RStream[R, A]",[103,2300,2301],{},"URStream[R, A]",[954,2303,2304,2306],{},[103,2305,117],{}," shapes",[155,2308,2310],{"id":2309},"run-the-demos-zio-routes","Run the demo's ZIO routes",[99,2312,2313,2315,2316,2319],{},[103,2314,534],{}," needs no database. Run the demo as in ",[150,2317,23],{"href":2318},"\u002Fguide\u002Fkyo#run-the-demos-kyo-routes",", then:",[215,2321,2325],{"className":2322,"code":2323,"language":2324,"meta":220,"style":220},"language-sh shiki shiki-themes github-light github-light github-dark","curl http:\u002F\u002F127.0.0.1:3000\u002Fapi\u002Ftest\n","sh",[103,2326,2327],{"__ignoreMap":220},[224,2328,2329],{"class":226,"line":227},[224,2330,2323],{},[99,2332,2333,2334,2336,2337,2340,2341,239],{},"The body is ",[103,2335,520],{},". The Notes routes need PostgreSQL; see ",[150,2338,2339],{"href":44},"databases"," and the ",[150,2342,2345],{"href":2343,"rel":2344},"https:\u002F\u002Fgithub.com\u002Fyuri4n\u002Fh34s\u002Fblob\u002Fmain\u002Fdocs\u002Fdevelopment.md",[2006],"development guide",[155,2347,2349],{"id":2348},"next-steps","Next steps",[99,2351,2352,192,2355,192,2357,192,2360,192,2362,192,2364,1121,2367,239],{},[150,2353,2354],{"href":32},"Configuration",[150,2356,1728],{"href":36},[150,2358,2359],{"href":40},"schemas",[150,2361,2339],{"href":44},[150,2363,1061],{"href":48},[150,2365,2366],{"href":52},"testing",[150,2368,2369],{"href":60},"debugging",[2371,2372,2373],"style",{},"html pre.shiki code .s8jYJ, html code.shiki .s8jYJ{--shiki-light:#D73A49;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .snPdu, html code.shiki .snPdu{--shiki-light:#6F42C1;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sxrX7, html code.shiki .sxrX7{--shiki-light:#24292E;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP4rz, html code.shiki .sP4rz{--shiki-light:#E36209;--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sIIMD, html code.shiki .sIIMD{--shiki-light:#032F62;--shiki-default:#032F62;--shiki-dark:#9ECBFF}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 .sCsY4, html code.shiki .sCsY4{--shiki-light:#6A737D;--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .sBjJW, html code.shiki .sBjJW{--shiki-light:#005CC5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":220,"searchDepth":293,"depth":293,"links":2375},[2376,2377,2378,2379,2380,2381,2382,2383,2384,2385,2387,2388,2389],{"id":157,"depth":293,"text":158},{"id":205,"depth":293,"text":206},{"id":548,"depth":293,"text":549},{"id":920,"depth":293,"text":921},{"id":1003,"depth":293,"text":1004},{"id":1093,"depth":293,"text":1094},{"id":1181,"depth":293,"text":1182},{"id":1342,"depth":293,"text":1343},{"id":1407,"depth":293,"text":1408},{"id":1744,"depth":293,"text":2386},"Call other routes with $fetch",{"id":2227,"depth":293,"text":2228},{"id":2309,"depth":293,"text":2310},{"id":2348,"depth":293,"text":2349},"Write ordinary ZIO programs; the hand-written ZIO adapter runs them over the Kyo core.","md",null,{},{"title":27,"description":2390},"Cb2M5oxiN1QzLc9D2U8jGwfrPf0MR5y08uizPJyY2LE",[2397,2399],{"title":23,"path":24,"stem":25,"description":2398,"children":-1},"Write handlers as Kyo functions from the request to the body, set the response head, fail safely, and wire services in your AppHandler.",{"title":31,"path":32,"stem":33,"description":2400,"children":-1},"Decode Nuxt runtimeConfig into a Scala case class, override it with NUXT_* variables, and keep secrets out of logs.",1792533381917]