[{"data":1,"prerenderedAt":979},["ShallowReactive",2],{"navigation_docs":3,"-reference-architecture":93,"-reference-architecture-surround":974},[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":78,"body":95,"description":967,"extension":968,"links":969,"meta":970,"navigation":971,"path":79,"seo":972,"stem":80,"__hash__":973},"docs\u002F2.reference\u002F1.architecture.md",{"type":96,"value":97,"toc":957},"minimark",[98,111,131,136,139,464,467,477,484,487,522,526,591,606,610,613,709,720,724,738,772,776,803,807,920,926,930,949],[99,100,101,102,106,107,110],"p",{},"h34s is a toolbox for running Scala.js server code in your Nuxt\u002FNitro application. You add the modules you need, write your models and services, and mount your handlers as Nuxt routes. The repository also holds a runnable demo in ",[103,104,105],"code",{},"examples\u002Fnuxt\u002F"," and the guides and the documentation site in ",[103,108,109],{},"docs\u002F",". Neither is part of the toolbox.",[99,112,113,117,118,121,122,125,126,130],{},[114,115,116],"strong",{},"Status."," This page describes the design of ",[103,119,120],{},"0.2.0-alpha.1",". The older ",[103,123,124],{},"0.1.0-alpha.1"," release has a different module graph with two independent runtimes; the ",[127,128,129],"a",{"href":91},"migration guide"," lists every change.",[132,133,135],"h2",{"id":134},"layers","Layers",[99,137,138],{},"One runtime does the hard work. The h3 transport, the request lifecycle, cancellation, streaming, error rendering, configuration access and application-scoped resources are implemented once, in Kyo. The ZIO API is a hand-written adapter over that core.",[140,141,142,161],"table",{},[143,144,145],"thead",{},[146,147,148,152,155,158],"tr",{},[149,150,151],"th",{},"Layer",[149,153,154],{},"sbt project \u002F artifact",[149,156,157],{},"What it gives you",[149,159,160],{},"Depends on",[162,163,164,235,276,321,345,368,399,430,446],"tbody",{},[146,165,166,170,179,232],{},[167,168,169],"td",{},"Native layer",[167,171,172,175,176],{},[103,173,174],{},"h3Ext"," \u002F ",[103,177,178],{},"h3-ext",[167,180,181,182,185,186,185,189,185,192,185,195,185,198,185,201,185,204,185,207,185,210,185,213,185,216,185,219,185,222,185,225,185,228,231],{},"Pure values shared by every runtime: ",[103,183,184],{},"EventHandler",", ",[103,187,188],{},"Request",[103,190,191],{},"RequestBody",[103,193,194],{},"BodyLimit",[103,196,197],{},"ResponseHead",[103,199,200],{},"Status",[103,202,203],{},"SetCookie",[103,205,206],{},"OnFailure",[103,208,209],{},"HandlerOptions",[103,211,212],{},"SafeError",[103,214,215],{},"HttpError",[103,217,218],{},"InvalidInput",[103,220,221],{},"ErrorEntry",[103,223,224],{},"ConfigError",[103,226,227],{},"Secret",[103,229,230],{},"NativeConverter[Unit]",". The h3, Node and Nitro facades are internal.",[167,233,234],{},"native-converter. No effect library.",[146,236,237,240,248,271],{},[167,238,239],{},"Kyo core",[167,241,242,175,245],{},[103,243,244],{},"kyoH3Ext",[103,246,247],{},"kyo-h3-ext",[167,249,250,253,254,257,258,185,261,185,264,267,268],{},[103,251,252],{},"KHandler.define",", the request lifecycle, body reading with limits, ",[103,255,256],{},"Response",", error rendering, diagnostics, ",[103,259,260],{},"RuntimeConfig",[103,262,263],{},"Shared",[103,265,266],{},"Response.sendStream"," and ",[103,269,270],{},"sendEvents",[167,272,273,275],{},[103,274,178],{},", kyo-core 1.0.0-RC7",[146,277,278,281,289,313],{},[167,279,280],{},"ZIO adapter",[167,282,283,175,286],{},[103,284,285],{},"zioH3Ext",[103,287,288],{},"zio-h3-ext",[167,290,291,185,294,296,297,300,301,267,304,185,306,185,309,312],{},[103,292,293],{},"ZHandler.define",[103,295,256],{}," over ",[103,298,299],{},"ZState"," with ",[103,302,303],{},"sendStream",[103,305,270],{},[103,307,308],{},"ZRuntimeConfig",[103,310,311],{},"ZShared",", and the awaiting ZIO-to-Kyo bridge",[167,314,315,317,318],{},[103,316,247],{},", kyo-zio, ZIO 2.1.26, zio-prelude, zio-json, ",[103,319,320],{},"native-converter-zio-ext",[146,322,323,326,334,340],{},[167,324,325],{},"Kyo Schema bridge",[167,327,328,175,331],{},[103,329,330],{},"nativeConverterKyoSchemaExt",[103,332,333],{},"native-converter-kyo-schema-ext",[167,335,336,339],{},[103,337,338],{},"derives Schema, NativeSchema"," for Kyo Schema",[167,341,342,344],{},[103,343,178],{},", kyo-schema",[146,346,347,350,358,363],{},[167,348,349],{},"ZIO Schema bridge",[167,351,352,175,355],{},[103,353,354],{},"nativeConverterZIOSchemaExt",[103,356,357],{},"native-converter-zio-schema-ext",[167,359,360,362],{},[103,361,338],{}," for ZIO Schema",[167,364,365,367],{},[103,366,178],{},", zio-schema 1.7.5",[146,369,370,373,381,394],{},[167,371,372],{},"ZIO converters",[167,374,375,185,378],{},[103,376,377],{},"nativeConverterZIOExt",[103,379,380],{},"nativeConverterZIOJsonExt",[167,382,383,386,387,390,391],{},[103,384,385],{},"NonEmptyList"," and zio-json ",[103,388,389],{},"Json"," converters, ",[103,392,393],{},"eimap",[167,395,396,398],{},[103,397,178],{},", ZIO",[146,400,401,404,418,427],{},[167,402,403],{},"Storage",[167,405,406,175,409,185,412,175,415],{},[103,407,408],{},"kyoNuxtHubExt",[103,410,411],{},"kyo-nuxthub-ext",[103,413,414],{},"zioNuxtHubExt",[103,416,417],{},"zio-nuxthub-ext",[167,419,420,185,423,426],{},[103,421,422],{},"KHubKv.mount",[103,424,425],{},"ZHubKv.mount"," over Nitro storage",[167,428,429],{},"Kyo core; the ZIO one also needs the ZIO adapter",[146,431,432,435,440,443],{},[167,433,434],{},"npm tooling",[167,436,437],{},[103,438,439],{},"@yuri4n\u002Fh34s-nuxt",[167,441,442],{},"Build CLI, Nuxt module, development loading, source maps, and the Nitro plugin that supplies flags, runtime config, storage and the close hook",[167,444,445],{},"Node, Nuxt. No Scala dependency.",[146,447,448,451,454,461],{},[167,449,450],{},"Your application",[167,452,453],{},"your sbt project and Nuxt app",[167,455,456,457,460],{},"Models, services, ",[103,458,459],{},"AppHandler",", resources, route mounts, database and deployment",[167,462,463],{},"the modules you choose",[99,465,466],{},"Dependencies point one way. Kyo modules never depend on ZIO. ZIO modules get Kyo transitively.",[468,469,475],"pre",{"className":470,"code":472,"language":473,"meta":474},[471],"language-text","h3-ext                                 (no effect library)\n├── kyo-h3-ext                         (Kyo core)\n│   ├── kyo-nuxthub-ext\n│   └── zio-h3-ext                     (also uses native-converter-zio-ext, kyo-zio, ZIO)\n│       └── zio-nuxthub-ext            (also uses kyo-nuxthub-ext)\n├── native-converter-kyo-schema-ext    (also uses kyo-schema)\n├── native-converter-zio-schema-ext    (also uses zio-schema)\n└── native-converter-zio-ext           (also uses ZIO)\n    └── native-converter-zio-json-ext\n","text","",[103,476,472],{"__ignoreMap":474},[99,478,479,480,483],{},"Each module depends on its parent. A build check during the refactor found no ",[103,481,482],{},"dev.zio"," artifact on the Kyo core's compile classpath.",[99,485,486],{},"Pick the smallest set for your application:",[488,489,490,503,512],"ul",{},[491,492,493,494,496,497,499,500,502],"li",{},"A Kyo application adds ",[103,495,247],{},". Add ",[103,498,333],{}," for schemas and ",[103,501,411],{}," for storage.",[491,504,505,506,496,508,499,510,502],{},"A ZIO application adds ",[103,507,288],{},[103,509,357],{},[103,511,417],{},[491,513,514,515,517,518,521],{},"Every application adds the npm package ",[103,516,439],{}," and the runtime dependency ",[103,519,520],{},"h3@1.15.4",".",[132,523,525],{"id":524},"follow-one-request","Follow one request",[527,528,529,544,551,571,578,588],"ol",{},[491,530,531,532,535,536,539,540,543],{},"Nitro routes the request to a linked Scala.js module. The h34s Nuxt module registered that module for the route that your handler declares with ",[103,533,534],{},".at(Route...)","; ",[103,537,538],{},"h34s-scala"," read the route after linking and wrote it into the output's route manifest. A one-line route file in ",[103,541,542],{},"server\u002Fapi\u002F"," that re-exports the module works too.",[491,545,546,547,550],{},"The h34s Nitro plugin has attached a frozen record to ",[103,548,549],{},"event.context.h34s",": the development and debug flags, the request's runtime config, and Nitro storage. Requests cannot change this record.",[491,552,553,555,556,558,559,562,563,566,567,570],{},[103,554,252],{}," takes one immutable ",[103,557,188],{}," snapshot. It runs your function ",[103,560,561],{},"Request => B \u003C HandlerEffects"," once, on its own fiber, in a request ",[103,564,565],{},"Scope",", with a ",[103,568,569],{},"Var[ResponseHead]"," that starts empty.",[491,572,573,574,577],{},"Your program reads the body, calls your services, sets status, headers and cookies with ",[103,575,576],{},"Response.*",", and returns the body.",[491,579,580,581,585,586,521],{},"When the program and its finalizers have finished, the core writes the response once. On success it applies the handler defaults, then everything the program set. On failure it applies the ",[127,582,584],{"href":583},"\u002Fguide\u002Fkyo#fail-safely","failure rule",". It renders the body with the handler's ",[103,587,209],{},[491,589,590],{},"If the client disconnects first, the core interrupts the program, waits for its cleanup, and writes nothing.",[99,592,593,595,596,566,599,602,603,605],{},[103,594,293],{}," adds one step. It runs your ZIO program in one ZIO fiber per request, on the given ZIO ",[103,597,598],{},"Runtime",[103,600,601],{},"ZState[ResponseHead]"," and a ZIO ",[103,604,565],{},". It then hands the result and the head to the core, which does steps 5 and 6. Interrupting a request interrupts the ZIO fiber and waits for its finalizers.",[132,607,609],{"id":608},"where-your-code-goes","Where your code goes",[99,611,612],{},"The functional-design layers map to code like this:",[140,614,615,627],{},[143,616,617],{},[146,618,619,621,624],{},[149,620,151],{},[149,622,623],{},"What lives there",[149,625,626],{},"Who owns it",[162,628,629,644,669,683],{},[146,630,631,634,641],{},[167,632,633],{},"Business logic",[167,635,636,637,640],{},"Your services and programs, as Kyo ",[103,638,639],{},"A \u003C S"," or ZIO effects",[167,642,643],{},"You",[146,645,646,649,666],{},[167,647,648],{},"Interfaces",[167,650,651,652,185,655,658,659,185,661,185,663,665],{},"Your service traits (",[103,653,654],{},"Greetings",[103,656,657],{},"Notes",") and the h34s values (",[103,660,188],{},[103,662,212],{},[103,664,227],{},")",[167,667,668],{},"You and h34s",[146,670,671,674,680],{},[167,672,673],{},"Implementation",[167,675,676,677,665],{},"The h34s runtime, its internal facades, and your service interpreters (",[103,678,679],{},"NotesLive",[167,681,682],{},"h34s and you",[146,684,685,688,707],{},[167,686,687],{},"Application",[167,689,690,691,693,694,696,697,699,700,696,703,706],{},"Your ",[103,692,459],{},": configuration, then ",[103,695,263],{},"\u002F",[103,698,311],{}," resources, then ",[103,701,702],{},"Env",[103,704,705],{},"ZLayer"," wiring",[167,708,643],{},[99,710,711,713,714,716,717,719],{},[103,712,459],{}," is a name the demo uses for this one wiring point. It is your code, not an h34s export. Call ",[103,715,252],{}," or ",[103,718,293],{}," directly when you do not need a wrapper.",[132,721,723],{"id":722},"errors-and-diagnostics","Errors and diagnostics",[99,725,726,727,729,730,185,732,267,735,521],{},"A handler is an error boundary. Only a ",[103,728,212],{}," that your program fails with through the typed channel reaches the client, with its status and entries. Everything else becomes an opaque 500. Diagnostics appear only in Nuxt development mode or in debug mode. See ",[127,731,23],{"href":583},[127,733,27],{"href":734},"\u002Fguide\u002Fzio#fail-safely",[127,736,737],{"href":60},"debugging",[99,739,740,741,744,745,748,749,752,753,756,757,760,761,764,765,768,769,771],{},"A finalizer that fails behaves the same in both runtimes: the failure is logged on the server, and the response that the program computed does not change. The log messages differ. Kyo 1.0.0-RC7 logs ",[103,742,743],{},"Scope finalizer failed"," through its ",[103,746,747],{},"Log",". The ZIO adapter writes ",[103,750,751],{},"h34s: a ZIO finalizer failed",", with ",[103,754,755],{},"Cause.prettyPrint",", through ",[103,758,759],{},"console.error",", for value, ",[103,762,763],{},"Unit"," and streamed bodies and on a client disconnect. Since the next release (provisionally ",[103,766,767],{},"0.3.0-alpha.1","), a dying ZIO finalizer no longer turns a value or ",[103,770,763],{}," response into a 500.",[132,773,775],{"id":774},"what-h34s-does-not-do","What h34s does not do",[488,777,778,791,797,800],{},[491,779,780,781,784,785,521],{},"Infer TypeScript types from Scala classes. The generated declarations describe what each converter writes; a converter that does not describe itself gives ",[103,782,783],{},"unknown",". See ",[127,786,787,788],{"href":20},"routes and typed ",[103,789,790],{},"$fetch",[491,792,793,794,521],{},"Supply a database client, a connection pool or migrations. Use kyo-sql or Skunk directly; see ",[127,795,796],{"href":44},"database",[491,798,799],{},"Package or deploy your application. Nix and sbt-native-packager support are planned.",[491,801,802],{},"Run anywhere but Node. Streaming is tested over Node HTTP responses and over a copy of Nitro's in-process local fetch; other Nitro presets are untested. ",[132,804,806],{"id":805},"source-locations","Source locations",[140,808,809,819],{},[143,810,811],{},[146,812,813,816],{},[149,814,815],{},"Path",[149,817,818],{},"What to read",[162,820,821,831,841,851,864,876,888,898,911],{},[146,822,823,828],{},[167,824,825],{},[103,826,827],{},"scala-modules\u002Fh3",[167,829,830],{},"The native layer and its tests",[146,832,833,838],{},[167,834,835],{},[103,836,837],{},"scala-modules\u002Fkyo-h3",[167,839,840],{},"The Kyo core and its tests",[146,842,843,848],{},[167,844,845],{},[103,846,847],{},"scala-modules\u002Fzio-h3",[167,849,850],{},"The ZIO adapter and its tests",[146,852,853,861],{},[167,854,855,185,858],{},[103,856,857],{},"scala-modules\u002Fnative-converter-kyo-schema",[103,859,860],{},"native-converter-zio-schema",[167,862,863],{},"Schema bridges",[146,865,866,874],{},[167,867,868,185,871],{},[103,869,870],{},"scala-modules\u002Fnative-converter-zio",[103,872,873],{},"native-converter-zio-json",[167,875,372],{},[146,877,878,886],{},[167,879,880,185,883],{},[103,881,882],{},"scala-modules\u002Fkyo-nuxthub",[103,884,885],{},"zio-nuxthub",[167,887,403],{},[146,889,890,895],{},[167,891,892],{},[103,893,894],{},"packages\u002Fnuxt",[167,896,897],{},"CLI, Nuxt module, Nitro plugin",[146,899,900,908],{},[167,901,902,185,905],{},[103,903,904],{},"examples\u002Fnuxt\u002Fscala\u002Fkyo",[103,906,907],{},"examples\u002Fnuxt\u002Fscala\u002Fzio",[167,909,910],{},"The demo's Kyo and ZIO applications",[146,912,913,917],{},[167,914,915],{},[103,916,109],{},[167,918,919],{},"The guides and this documentation site",[99,921,922,925],{},[103,923,924],{},"examples\u002Fzio-migrations"," is an unpublished example that derives Skunk codecs and PostgreSQL DDL from ZIO Schema. It is not a supported API.",[132,927,929],{"id":928},"next-coherent-slices","Next coherent slices",[99,931,932,933,936,937,939,940,943,944,948],{},"Routes declared in Scala and the ",[103,934,935],{},".d.ts"," declarations for typed ",[103,938,790],{}," are on ",[103,941,942],{},"main"," and ship with the next release; see ",[127,945,787,946],{"href":20},[103,947,790],{},". The next slices are:",[527,950,951,954],{},[491,952,953],{},"The planned Nix and sbt-native-packager paths over the same build pipeline.",[491,955,956],{},"Interactive documentation: compiler-derived types, symbol links and runnable examples.",{"title":474,"searchDepth":958,"depth":958,"links":959},2,[960,961,962,963,964,965,966],{"id":134,"depth":958,"text":135},{"id":524,"depth":958,"text":525},{"id":608,"depth":958,"text":609},{"id":722,"depth":958,"text":723},{"id":774,"depth":958,"text":775},{"id":805,"depth":958,"text":806},{"id":928,"depth":958,"text":929},"An effect-free native layer, a Kyo core, a hand-written ZIO adapter, optional schema and storage bridges, and your application.","md",null,{},true,{"title":78,"description":967},"h5iGrkjhIkzhuLfbrtYqhzaMPxMKlQkVgJVell-_L1c",[975,977],{"title":67,"path":68,"stem":69,"description":976,"children":-1},"A prompt that a coding assistant follows to add h34s to a new project, an existing Nuxt app, or an existing Scala.js project.",{"title":82,"path":83,"stem":84,"description":978,"children":-1},"Published versions, registry access and installation, what 0.2.0-alpha.1 provides, and what was verified.",1792533381917]