[{"data":1,"prerenderedAt":3162},["ShallowReactive",2],{"navigation_docs":3,"-docs-essentials-client":493,"-docs-essentials-client-surround":3157},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":72,"body":495,"description":3150,"extension":3151,"links":3152,"meta":3153,"navigation":3154,"path":73,"seo":3155,"stem":74,"__hash__":3156},"docs\u002Fdocs\u002F02.essentials\u002F05.client.md",{"type":496,"value":497,"toc":3137},"minimark",[498,520,523,534,539,619,638,642,655,954,983,1005,1100,1107,1135,1142,1173,1410,1431,1435,1450,1668,1678,1682,1700,1938,1941,1945,1991,1994,2149,2155,2159,2174,2332,2349,2554,2558,2583,3051,3055,3063,3091,3095,3133],[499,500,501,502,506,507,511,512,515,516,519],"p",{},"Your backend already describes its API once, as a ",[503,504,505],"code",{},"Contract"," — and that same class ",[508,509,510],"strong",{},"is"," the client. Give\n",[503,513,514],{},"new SomeApi(transport)"," a transport and it hands you one typed caller per route under ",[503,517,518],{},".client",", each\nreturning the route's 2xx body inferred straight from the schemas (and throwing on a non-2xx).",[499,521,522],{},"Change the contract, and TypeScript lights up every call site that no longer matches. No code generation,\nno second source of truth, no drift between client and server.",[499,524,525,526,529,530,533],{},"The contract is frontend-safe: it imports only ",[503,527,528],{},"@standard-schema\u002Fspec"," (boundary validation) — no server\ncode, no compiler. The transports live in ",[503,531,532],{},"@heximon\u002Fclient",", also frontend-safe. You can ship both to\nthe browser.",[535,536,538],"h2",{"id":537},"install-the-package","Install the package",[540,541,542,570,587,603],"code-group",{},[543,544,550],"pre",{"className":545,"code":546,"filename":547,"language":548,"meta":549,"style":549},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @heximon\u002Fclient @heximon\u002Fcontract\n","pnpm","bash","",[503,551,552],{"__ignoreMap":549},[553,554,557,560,564,567],"span",{"class":555,"line":556},"line",1,[553,558,547],{"class":559},"sBMFI",[553,561,563],{"class":562},"sfazB"," add",[553,565,566],{"class":562}," @heximon\u002Fclient",[553,568,569],{"class":562}," @heximon\u002Fcontract\n",[543,571,574],{"className":545,"code":572,"filename":573,"language":548,"meta":549,"style":549},"npm install @heximon\u002Fclient @heximon\u002Fcontract\n","npm",[503,575,576],{"__ignoreMap":549},[553,577,578,580,583,585],{"class":555,"line":556},[553,579,573],{"class":559},[553,581,582],{"class":562}," install",[553,584,566],{"class":562},[553,586,569],{"class":562},[543,588,591],{"className":545,"code":589,"filename":590,"language":548,"meta":549,"style":549},"yarn add @heximon\u002Fclient @heximon\u002Fcontract\n","yarn",[503,592,593],{"__ignoreMap":549},[553,594,595,597,599,601],{"class":555,"line":556},[553,596,590],{"class":559},[553,598,563],{"class":562},[553,600,566],{"class":562},[553,602,569],{"class":562},[543,604,607],{"className":545,"code":605,"filename":606,"language":548,"meta":549,"style":549},"bun add @heximon\u002Fclient @heximon\u002Fcontract\n","bun",[503,608,609],{"__ignoreMap":549},[553,610,611,613,615,617],{"class":555,"line":556},[553,612,606],{"class":559},[553,614,563],{"class":562},[553,616,566],{"class":562},[553,618,569],{"class":562},[499,620,621,622,625,626,629,630,633,634,637],{},"The main entry has ",[508,623,624],{},"no peer dependencies",". The optional ",[503,627,628],{},".\u002Fvue-query"," subpath needs ",[503,631,632],{},"@tanstack\u002Fvue-query"," and\n",[503,635,636],{},"vue"," — install those only when you import the bindings.",[535,639,641],{"id":640},"build-a-client","Build a client",[499,643,644,645,647,648,650,651,654],{},"Construct the contract with a transport — the same ",[503,646,505],{}," class your controller binds to — and it folds\nthe prefix into each route, then assembles one caller per route key under ",[503,649,518],{},". Each caller's argument\nis that route's request payload; each result is its ",[508,652,653],{},"2xx body",".",[543,656,661],{"className":657,"code":658,"filename":659,"language":660,"meta":549,"style":549},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\"; \u002F\u002F a shared @heximon\u002Fcontract class\n\nconst api = new ProductsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\nconst product = await api.client.find({ params: { sku: \"abc-123\" } });\nconsole.log(product.name); \u002F\u002F body narrowed to the 2xx schema's output type — throws on a non-2xx\n\nawait api.client.create({ body: { sku: \"new-1\", name: \"Widget\", priceInCents: 999 } });\n\u002F\u002F mutation: JSON body + content-type set automatically\n","products.client.ts","ts",[503,662,663,694,722,729,783,788,846,870,875,948],{"__ignoreMap":549},[553,664,665,669,673,677,680,683,686,688,691],{"class":555,"line":556},[553,666,668],{"class":667},"s7zQu","import",[553,670,672],{"class":671},"sMK4o"," {",[553,674,676],{"class":675},"sTEyZ"," ClientTransport",[553,678,679],{"class":671}," }",[553,681,682],{"class":667}," from",[553,684,685],{"class":671}," \"",[553,687,532],{"class":562},[553,689,690],{"class":671},"\"",[553,692,693],{"class":671},";\n",[553,695,697,699,701,704,706,708,710,713,715,718],{"class":555,"line":696},2,[553,698,668],{"class":667},[553,700,672],{"class":671},[553,702,703],{"class":675}," ProductsApi",[553,705,679],{"class":671},[553,707,682],{"class":667},[553,709,685],{"class":671},[553,711,712],{"class":562},"..\u002Fserver\u002Fproducts\u002Fproduct.api",[553,714,690],{"class":671},[553,716,717],{"class":671},";",[553,719,721],{"class":720},"sHwdD"," \u002F\u002F a shared @heximon\u002Fcontract class\n",[553,723,725],{"class":555,"line":724},3,[553,726,728],{"emptyLinePlaceholder":727},true,"\n",[553,730,732,736,739,742,745,748,751,753,756,759,762,766,769,771,774,776,778,781],{"class":555,"line":731},4,[553,733,735],{"class":734},"spNyl","const",[553,737,738],{"class":675}," api ",[553,740,741],{"class":671},"=",[553,743,744],{"class":671}," new",[553,746,703],{"class":747},"s2Zo4",[553,749,750],{"class":675},"(ClientTransport",[553,752,654],{"class":671},[553,754,755],{"class":747},"fetch",[553,757,758],{"class":675},"(",[553,760,761],{"class":671},"{",[553,763,765],{"class":764},"swJcz"," baseUrl",[553,767,768],{"class":671},":",[553,770,685],{"class":671},[553,772,773],{"class":562},"https:\u002F\u002Fapi.example.com",[553,775,690],{"class":671},[553,777,679],{"class":671},[553,779,780],{"class":675},"))",[553,782,693],{"class":671},[553,784,786],{"class":555,"line":785},5,[553,787,728],{"emptyLinePlaceholder":727},[553,789,791,793,796,798,801,804,806,809,811,814,816,818,821,823,825,828,830,832,835,837,839,841,844],{"class":555,"line":790},6,[553,792,735],{"class":734},[553,794,795],{"class":675}," product ",[553,797,741],{"class":671},[553,799,800],{"class":667}," await",[553,802,803],{"class":675}," api",[553,805,654],{"class":671},[553,807,808],{"class":675},"client",[553,810,654],{"class":671},[553,812,813],{"class":747},"find",[553,815,758],{"class":675},[553,817,761],{"class":671},[553,819,820],{"class":764}," params",[553,822,768],{"class":671},[553,824,672],{"class":671},[553,826,827],{"class":764}," sku",[553,829,768],{"class":671},[553,831,685],{"class":671},[553,833,834],{"class":562},"abc-123",[553,836,690],{"class":671},[553,838,679],{"class":671},[553,840,679],{"class":671},[553,842,843],{"class":675},")",[553,845,693],{"class":671},[553,847,849,852,854,857,860,862,865,867],{"class":555,"line":848},7,[553,850,851],{"class":675},"console",[553,853,654],{"class":671},[553,855,856],{"class":747},"log",[553,858,859],{"class":675},"(product",[553,861,654],{"class":671},[553,863,864],{"class":675},"name)",[553,866,717],{"class":671},[553,868,869],{"class":720}," \u002F\u002F body narrowed to the 2xx schema's output type — throws on a non-2xx\n",[553,871,873],{"class":555,"line":872},8,[553,874,728],{"emptyLinePlaceholder":727},[553,876,878,881,883,885,887,889,892,894,896,899,901,903,905,907,909,912,914,917,920,922,924,927,929,931,934,936,940,942,944,946],{"class":555,"line":877},9,[553,879,880],{"class":667},"await",[553,882,803],{"class":675},[553,884,654],{"class":671},[553,886,808],{"class":675},[553,888,654],{"class":671},[553,890,891],{"class":747},"create",[553,893,758],{"class":675},[553,895,761],{"class":671},[553,897,898],{"class":764}," body",[553,900,768],{"class":671},[553,902,672],{"class":671},[553,904,827],{"class":764},[553,906,768],{"class":671},[553,908,685],{"class":671},[553,910,911],{"class":562},"new-1",[553,913,690],{"class":671},[553,915,916],{"class":671},",",[553,918,919],{"class":764}," name",[553,921,768],{"class":671},[553,923,685],{"class":671},[553,925,926],{"class":562},"Widget",[553,928,690],{"class":671},[553,930,916],{"class":671},[553,932,933],{"class":764}," priceInCents",[553,935,768],{"class":671},[553,937,939],{"class":938},"sbssI"," 999",[553,941,679],{"class":671},[553,943,679],{"class":671},[553,945,843],{"class":675},[553,947,693],{"class":671},[553,949,951],{"class":555,"line":950},10,[553,952,953],{"class":720},"\u002F\u002F mutation: JSON body + content-type set automatically\n",[499,955,956,957,960,961,967,968,971,972,971,975,978,979,982],{},"The caller ",[508,958,959],{},"returns the 2xx body"," and ",[508,962,963,964],{},"throws a ",[503,965,966],{},"ContractError"," on any non-2xx or network failure, so\nthe happy path reads straight. ",[503,969,970],{},"params"," \u002F ",[503,973,974],{},"query",[503,976,977],{},"body"," appear in the argument ",[508,980,981],{},"only"," when the route\ndeclares them — and the whole argument is optional when every field is. That's the contract paying off: the\nclient's surface is derived, not maintained.",[499,984,985,986,960,988,991,992,994,995,998,999,1001,1002,1004],{},"The path-parameters key accepts both ",[503,987,970],{},[503,989,990],{},"pathParams"," — they are aliases, and either name works.\n",[503,993,990],{}," aligns with the descriptor field name (",[503,996,997],{},"route.pathParams","); ",[503,1000,970],{}," is the shorter form. When\nboth are present, ",[503,1003,990],{}," takes precedence.",[543,1006,1008],{"className":657,"code":1007,"language":660,"meta":549,"style":549},"\u002F\u002F Both resolve to the same URL — choose whichever reads more clearly:\nawait api.client.find({ params: { sku: \"abc-123\" } });\nawait api.client.find({ pathParams: { sku: \"abc-123\" } });\n",[503,1009,1010,1015,1057],{"__ignoreMap":549},[553,1011,1012],{"class":555,"line":556},[553,1013,1014],{"class":720},"\u002F\u002F Both resolve to the same URL — choose whichever reads more clearly:\n",[553,1016,1017,1019,1021,1023,1025,1027,1029,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055],{"class":555,"line":696},[553,1018,880],{"class":667},[553,1020,803],{"class":675},[553,1022,654],{"class":671},[553,1024,808],{"class":675},[553,1026,654],{"class":671},[553,1028,813],{"class":747},[553,1030,758],{"class":675},[553,1032,761],{"class":671},[553,1034,820],{"class":764},[553,1036,768],{"class":671},[553,1038,672],{"class":671},[553,1040,827],{"class":764},[553,1042,768],{"class":671},[553,1044,685],{"class":671},[553,1046,834],{"class":562},[553,1048,690],{"class":671},[553,1050,679],{"class":671},[553,1052,679],{"class":671},[553,1054,843],{"class":675},[553,1056,693],{"class":671},[553,1058,1059,1061,1063,1065,1067,1069,1071,1073,1075,1078,1080,1082,1084,1086,1088,1090,1092,1094,1096,1098],{"class":555,"line":724},[553,1060,880],{"class":667},[553,1062,803],{"class":675},[553,1064,654],{"class":671},[553,1066,808],{"class":675},[553,1068,654],{"class":671},[553,1070,813],{"class":747},[553,1072,758],{"class":675},[553,1074,761],{"class":671},[553,1076,1077],{"class":764}," pathParams",[553,1079,768],{"class":671},[553,1081,672],{"class":671},[553,1083,827],{"class":764},[553,1085,768],{"class":671},[553,1087,685],{"class":671},[553,1089,834],{"class":562},[553,1091,690],{"class":671},[553,1093,679],{"class":671},[553,1095,679],{"class":671},[553,1097,843],{"class":675},[553,1099,693],{"class":671},[499,1101,1102,1103,1106],{},"When you need every status (not just the 2xx body), reach for ",[503,1104,1105],{},"api.raw(\"find\", …)"," — covered below.",[1108,1109,1111,1112,1115,1116,1119,1120,1123,1124,1126,1127,1130,1131,1134],"callout",{"type":1110},"info","Don't repeat the prefix in ",[503,1113,1114],{},"baseUrl",". The client folds ",[503,1117,1118],{},"contract.prefix"," into each route path ",[508,1121,1122],{},"once"," at\nassembly, then concatenates ",[503,1125,1114],{}," with a single de-duplicated slash. So a contract with\n",[503,1128,1129],{},"prefix: \"\u002Fapi\u002Fproducts\""," already produces ",[503,1132,1133],{},"https:\u002F\u002Fapi.example.com\u002Fapi\u002Fproducts\u002F:sku"," from a bare host.",[535,1136,1138,1139],{"id":1137},"handle-every-status-with-raw","Handle every status with ",[503,1140,1141],{},"raw()",[499,1143,1144,1145,1147,1148,1152,1153,1156,1157,1160,1161,1164,1165,1168,1169,1172],{},"The ",[503,1146,518],{}," callers return only the 2xx body and throw otherwise. When you need to branch on ",[1149,1150,1151],"em",{},"every","\nstatus the route declares — read a ",[503,1154,1155],{},"404"," body, inspect a ",[503,1158,1159],{},"409"," — call ",[503,1162,1163],{},"api.raw(key, args)",". It ",[508,1166,1167],{},"never\nthrows"," and returns the full ",[503,1170,1171],{},"{ status, body, headers }"," discriminated union, narrowed by status:",[543,1174,1176],{"className":657,"code":1175,"filename":659,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\nconst api = new ProductsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\nconst result = await api.raw(\"find\", { params: { sku: \"abc-123\" } });\nif (result.status === 200) {\n  console.log(result.body.name); \u002F\u002F body narrowed to the 200 schema's output type\n} else if (result.status === 404) {\n  \u002F\u002F result.body is the declared 404 shape — handle the miss without a try\u002Fcatch\n}\n",[503,1177,1178,1198,1218,1222,1260,1264,1318,1343,1373,1399,1404],{"__ignoreMap":549},[553,1179,1180,1182,1184,1186,1188,1190,1192,1194,1196],{"class":555,"line":556},[553,1181,668],{"class":667},[553,1183,672],{"class":671},[553,1185,676],{"class":675},[553,1187,679],{"class":671},[553,1189,682],{"class":667},[553,1191,685],{"class":671},[553,1193,532],{"class":562},[553,1195,690],{"class":671},[553,1197,693],{"class":671},[553,1199,1200,1202,1204,1206,1208,1210,1212,1214,1216],{"class":555,"line":696},[553,1201,668],{"class":667},[553,1203,672],{"class":671},[553,1205,703],{"class":675},[553,1207,679],{"class":671},[553,1209,682],{"class":667},[553,1211,685],{"class":671},[553,1213,712],{"class":562},[553,1215,690],{"class":671},[553,1217,693],{"class":671},[553,1219,1220],{"class":555,"line":724},[553,1221,728],{"emptyLinePlaceholder":727},[553,1223,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242,1244,1246,1248,1250,1252,1254,1256,1258],{"class":555,"line":731},[553,1225,735],{"class":734},[553,1227,738],{"class":675},[553,1229,741],{"class":671},[553,1231,744],{"class":671},[553,1233,703],{"class":747},[553,1235,750],{"class":675},[553,1237,654],{"class":671},[553,1239,755],{"class":747},[553,1241,758],{"class":675},[553,1243,761],{"class":671},[553,1245,765],{"class":764},[553,1247,768],{"class":671},[553,1249,685],{"class":671},[553,1251,773],{"class":562},[553,1253,690],{"class":671},[553,1255,679],{"class":671},[553,1257,780],{"class":675},[553,1259,693],{"class":671},[553,1261,1262],{"class":555,"line":785},[553,1263,728],{"emptyLinePlaceholder":727},[553,1265,1266,1268,1271,1273,1275,1277,1279,1282,1284,1286,1288,1290,1292,1294,1296,1298,1300,1302,1304,1306,1308,1310,1312,1314,1316],{"class":555,"line":790},[553,1267,735],{"class":734},[553,1269,1270],{"class":675}," result ",[553,1272,741],{"class":671},[553,1274,800],{"class":667},[553,1276,803],{"class":675},[553,1278,654],{"class":671},[553,1280,1281],{"class":747},"raw",[553,1283,758],{"class":675},[553,1285,690],{"class":671},[553,1287,813],{"class":562},[553,1289,690],{"class":671},[553,1291,916],{"class":671},[553,1293,672],{"class":671},[553,1295,820],{"class":764},[553,1297,768],{"class":671},[553,1299,672],{"class":671},[553,1301,827],{"class":764},[553,1303,768],{"class":671},[553,1305,685],{"class":671},[553,1307,834],{"class":562},[553,1309,690],{"class":671},[553,1311,679],{"class":671},[553,1313,679],{"class":671},[553,1315,843],{"class":675},[553,1317,693],{"class":671},[553,1319,1320,1323,1326,1328,1331,1334,1337,1340],{"class":555,"line":848},[553,1321,1322],{"class":667},"if",[553,1324,1325],{"class":675}," (result",[553,1327,654],{"class":671},[553,1329,1330],{"class":675},"status ",[553,1332,1333],{"class":671},"===",[553,1335,1336],{"class":938}," 200",[553,1338,1339],{"class":675},") ",[553,1341,1342],{"class":671},"{\n",[553,1344,1345,1348,1350,1352,1354,1357,1359,1361,1363,1366,1368,1370],{"class":555,"line":872},[553,1346,1347],{"class":675},"  console",[553,1349,654],{"class":671},[553,1351,856],{"class":747},[553,1353,758],{"class":764},[553,1355,1356],{"class":675},"result",[553,1358,654],{"class":671},[553,1360,977],{"class":675},[553,1362,654],{"class":671},[553,1364,1365],{"class":675},"name",[553,1367,843],{"class":764},[553,1369,717],{"class":671},[553,1371,1372],{"class":720}," \u002F\u002F body narrowed to the 200 schema's output type\n",[553,1374,1375,1378,1381,1384,1386,1388,1390,1392,1395,1397],{"class":555,"line":877},[553,1376,1377],{"class":671},"}",[553,1379,1380],{"class":667}," else",[553,1382,1383],{"class":667}," if",[553,1385,1325],{"class":675},[553,1387,654],{"class":671},[553,1389,1330],{"class":675},[553,1391,1333],{"class":671},[553,1393,1394],{"class":938}," 404",[553,1396,1339],{"class":675},[553,1398,1342],{"class":671},[553,1400,1401],{"class":555,"line":950},[553,1402,1403],{"class":720},"  \u002F\u002F result.body is the declared 404 shape — handle the miss without a try\u002Fcatch\n",[553,1405,1407],{"class":555,"line":1406},11,[553,1408,1409],{"class":671},"}\n",[499,1411,1412,1413,1416,1417,1420,1421,960,1424,1427,1428,1430],{},"A link is ",[503,1414,1415],{},"api.url(\"find\", { sku: \"abc-123\" })",", and ",[503,1418,1419],{},"api.scoped({ headers })"," returns a fresh instance\nwith merged options. ",[503,1422,1423],{},"api.url",[503,1425,1426],{},"api.raw"," share the same caller args as ",[503,1429,518],{},", so a contract drives\nits own routes three ways from one class.",[535,1432,1434],{"id":1433},"add-authentication","Add authentication",[499,1436,1437,1438,1441,1442,1445,1446,1449],{},"A ",[503,1439,1440],{},"request"," interceptor (registered with ",[503,1443,1444],{},"api.on(\"request\", …)",") sees the assembled request before it goes\nout — the natural place to attach a token. It may mutate the request in place or return a replacement. A\nstatic base header that's the same on every call can instead ride on the transport's ",[503,1447,1448],{},"headers"," option:",[543,1451,1454],{"className":657,"code":1452,"filename":1453,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\nconst api = new ProductsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }), {\n  headers: { \"x-app\": \"storefront\" }, \u002F\u002F base headers merged into every request\n});\n\napi.on(\"request\", (request) => {\n  request.headers[\"authorization\"] = \"Bearer token\";\n  return request;\n});\n","client.ts",[503,1455,1456,1476,1496,1500,1541,1572,1580,1584,1617,1650,1660],{"__ignoreMap":549},[553,1457,1458,1460,1462,1464,1466,1468,1470,1472,1474],{"class":555,"line":556},[553,1459,668],{"class":667},[553,1461,672],{"class":671},[553,1463,676],{"class":675},[553,1465,679],{"class":671},[553,1467,682],{"class":667},[553,1469,685],{"class":671},[553,1471,532],{"class":562},[553,1473,690],{"class":671},[553,1475,693],{"class":671},[553,1477,1478,1480,1482,1484,1486,1488,1490,1492,1494],{"class":555,"line":696},[553,1479,668],{"class":667},[553,1481,672],{"class":671},[553,1483,703],{"class":675},[553,1485,679],{"class":671},[553,1487,682],{"class":667},[553,1489,685],{"class":671},[553,1491,712],{"class":562},[553,1493,690],{"class":671},[553,1495,693],{"class":671},[553,1497,1498],{"class":555,"line":724},[553,1499,728],{"emptyLinePlaceholder":727},[553,1501,1502,1504,1506,1508,1510,1512,1514,1516,1518,1520,1522,1524,1526,1528,1530,1532,1534,1536,1538],{"class":555,"line":731},[553,1503,735],{"class":734},[553,1505,738],{"class":675},[553,1507,741],{"class":671},[553,1509,744],{"class":671},[553,1511,703],{"class":747},[553,1513,750],{"class":675},[553,1515,654],{"class":671},[553,1517,755],{"class":747},[553,1519,758],{"class":675},[553,1521,761],{"class":671},[553,1523,765],{"class":764},[553,1525,768],{"class":671},[553,1527,685],{"class":671},[553,1529,773],{"class":562},[553,1531,690],{"class":671},[553,1533,679],{"class":671},[553,1535,843],{"class":675},[553,1537,916],{"class":671},[553,1539,1540],{"class":671}," {\n",[553,1542,1543,1546,1548,1550,1552,1555,1557,1559,1561,1564,1566,1569],{"class":555,"line":785},[553,1544,1545],{"class":764},"  headers",[553,1547,768],{"class":671},[553,1549,672],{"class":671},[553,1551,685],{"class":671},[553,1553,1554],{"class":764},"x-app",[553,1556,690],{"class":671},[553,1558,768],{"class":671},[553,1560,685],{"class":671},[553,1562,1563],{"class":562},"storefront",[553,1565,690],{"class":671},[553,1567,1568],{"class":671}," },",[553,1570,1571],{"class":720}," \u002F\u002F base headers merged into every request\n",[553,1573,1574,1576,1578],{"class":555,"line":790},[553,1575,1377],{"class":671},[553,1577,843],{"class":675},[553,1579,693],{"class":671},[553,1581,1582],{"class":555,"line":848},[553,1583,728],{"emptyLinePlaceholder":727},[553,1585,1586,1589,1591,1594,1596,1598,1600,1602,1604,1607,1610,1612,1615],{"class":555,"line":872},[553,1587,1588],{"class":675},"api",[553,1590,654],{"class":671},[553,1592,1593],{"class":747},"on",[553,1595,758],{"class":675},[553,1597,690],{"class":671},[553,1599,1440],{"class":562},[553,1601,690],{"class":671},[553,1603,916],{"class":671},[553,1605,1606],{"class":671}," (",[553,1608,1440],{"class":1609},"sHdIc",[553,1611,843],{"class":671},[553,1613,1614],{"class":734}," =>",[553,1616,1540],{"class":671},[553,1618,1619,1622,1624,1626,1629,1631,1634,1636,1639,1641,1643,1646,1648],{"class":555,"line":877},[553,1620,1621],{"class":675},"  request",[553,1623,654],{"class":671},[553,1625,1448],{"class":675},[553,1627,1628],{"class":764},"[",[553,1630,690],{"class":671},[553,1632,1633],{"class":562},"authorization",[553,1635,690],{"class":671},[553,1637,1638],{"class":764},"] ",[553,1640,741],{"class":671},[553,1642,685],{"class":671},[553,1644,1645],{"class":562},"Bearer token",[553,1647,690],{"class":671},[553,1649,693],{"class":671},[553,1651,1652,1655,1658],{"class":555,"line":950},[553,1653,1654],{"class":667},"  return",[553,1656,1657],{"class":675}," request",[553,1659,693],{"class":671},[553,1661,1662,1664,1666],{"class":555,"line":1406},[553,1663,1377],{"class":671},[553,1665,843],{"class":675},[553,1667,693],{"class":671},[499,1669,1670,1673,1674,1677],{},[503,1671,1672],{},"api.on(...)"," returns the instance, so it chains; ",[503,1675,1676],{},"api.scoped({ headers: { ... } })"," returns a fresh\ninstance with the extra header merged in, carrying the interceptors over.",[535,1679,1681],{"id":1680},"validate-responses","Validate responses",[499,1683,1684,1685,1688,1689,1691,1692,1694,1695,960,1698,654],{},"Response validation is ",[508,1686,1687],{},"always on"," and runs for ",[1149,1690,1151],{}," transport: each JSON body is checked against the\nroute's response schema for the returned status, so a server that drifts from the contract is caught at the\nclient boundary, not three screens later in your UI. A mismatch throws a ",[503,1693,966],{}," carrying the\noffending ",[503,1696,1697],{},"status",[503,1699,977],{},[543,1701,1703],{"className":657,"code":1702,"filename":1453,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ContractError } from \"@heximon\u002Fcontract\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\nconst api = new ProductsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\ntry {\n  await api.client.find({ params: { sku: \"abc-123\" } });\n} catch (error) {\n  if (error instanceof ContractError) {\n    console.error(error.status, error.body); \u002F\u002F a non-2xx, or a body that doesn't match the contract\n  }\n}\n",[503,1704,1705,1725,1747,1767,1771,1809,1813,1820,1863,1875,1894,1927,1933],{"__ignoreMap":549},[553,1706,1707,1709,1711,1713,1715,1717,1719,1721,1723],{"class":555,"line":556},[553,1708,668],{"class":667},[553,1710,672],{"class":671},[553,1712,676],{"class":675},[553,1714,679],{"class":671},[553,1716,682],{"class":667},[553,1718,685],{"class":671},[553,1720,532],{"class":562},[553,1722,690],{"class":671},[553,1724,693],{"class":671},[553,1726,1727,1729,1731,1734,1736,1738,1740,1743,1745],{"class":555,"line":696},[553,1728,668],{"class":667},[553,1730,672],{"class":671},[553,1732,1733],{"class":675}," ContractError",[553,1735,679],{"class":671},[553,1737,682],{"class":667},[553,1739,685],{"class":671},[553,1741,1742],{"class":562},"@heximon\u002Fcontract",[553,1744,690],{"class":671},[553,1746,693],{"class":671},[553,1748,1749,1751,1753,1755,1757,1759,1761,1763,1765],{"class":555,"line":724},[553,1750,668],{"class":667},[553,1752,672],{"class":671},[553,1754,703],{"class":675},[553,1756,679],{"class":671},[553,1758,682],{"class":667},[553,1760,685],{"class":671},[553,1762,712],{"class":562},[553,1764,690],{"class":671},[553,1766,693],{"class":671},[553,1768,1769],{"class":555,"line":731},[553,1770,728],{"emptyLinePlaceholder":727},[553,1772,1773,1775,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807],{"class":555,"line":785},[553,1774,735],{"class":734},[553,1776,738],{"class":675},[553,1778,741],{"class":671},[553,1780,744],{"class":671},[553,1782,703],{"class":747},[553,1784,750],{"class":675},[553,1786,654],{"class":671},[553,1788,755],{"class":747},[553,1790,758],{"class":675},[553,1792,761],{"class":671},[553,1794,765],{"class":764},[553,1796,768],{"class":671},[553,1798,685],{"class":671},[553,1800,773],{"class":562},[553,1802,690],{"class":671},[553,1804,679],{"class":671},[553,1806,780],{"class":675},[553,1808,693],{"class":671},[553,1810,1811],{"class":555,"line":790},[553,1812,728],{"emptyLinePlaceholder":727},[553,1814,1815,1818],{"class":555,"line":848},[553,1816,1817],{"class":667},"try",[553,1819,1540],{"class":671},[553,1821,1822,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853,1855,1857,1859,1861],{"class":555,"line":872},[553,1823,1824],{"class":667},"  await",[553,1826,803],{"class":675},[553,1828,654],{"class":671},[553,1830,808],{"class":675},[553,1832,654],{"class":671},[553,1834,813],{"class":747},[553,1836,758],{"class":764},[553,1838,761],{"class":671},[553,1840,820],{"class":764},[553,1842,768],{"class":671},[553,1844,672],{"class":671},[553,1846,827],{"class":764},[553,1848,768],{"class":671},[553,1850,685],{"class":671},[553,1852,834],{"class":562},[553,1854,690],{"class":671},[553,1856,679],{"class":671},[553,1858,679],{"class":671},[553,1860,843],{"class":764},[553,1862,693],{"class":671},[553,1864,1865,1867,1870,1873],{"class":555,"line":877},[553,1866,1377],{"class":671},[553,1868,1869],{"class":667}," catch",[553,1871,1872],{"class":675}," (error) ",[553,1874,1342],{"class":671},[553,1876,1877,1880,1882,1885,1888,1890,1892],{"class":555,"line":950},[553,1878,1879],{"class":667},"  if",[553,1881,1606],{"class":764},[553,1883,1884],{"class":675},"error",[553,1886,1887],{"class":671}," instanceof",[553,1889,1733],{"class":559},[553,1891,1339],{"class":764},[553,1893,1342],{"class":671},[553,1895,1896,1899,1901,1903,1905,1907,1909,1911,1913,1916,1918,1920,1922,1924],{"class":555,"line":1406},[553,1897,1898],{"class":675},"    console",[553,1900,654],{"class":671},[553,1902,1884],{"class":747},[553,1904,758],{"class":764},[553,1906,1884],{"class":675},[553,1908,654],{"class":671},[553,1910,1697],{"class":675},[553,1912,916],{"class":671},[553,1914,1915],{"class":675}," error",[553,1917,654],{"class":671},[553,1919,977],{"class":675},[553,1921,843],{"class":764},[553,1923,717],{"class":671},[553,1925,1926],{"class":720}," \u002F\u002F a non-2xx, or a body that doesn't match the contract\n",[553,1928,1930],{"class":555,"line":1929},12,[553,1931,1932],{"class":671},"  }\n",[553,1934,1936],{"class":555,"line":1935},13,[553,1937,1409],{"class":671},[499,1939,1940],{},"Validation is synchronous, because a response schema is checked inline as the body decodes — an async\nresponse schema throws rather than silently skipping the check.",[535,1942,1944],{"id":1943},"download-and-text-responses","Download and text responses",[499,1946,1947,1948,1951,1952,1955,1956,1959,1960,1963,1964,1967,1968,1971,1972,1975,1976,1606,1979,1982,1983,1986,1987,1990],{},"A route whose ",[508,1949,1950],{},"2xx"," body is binary or text declares its wire type on the contract — ",[503,1953,1954],{},".download()"," (→\n",[503,1957,1958],{},"application\u002Foctet-stream","), ",[503,1961,1962],{},".html()"," (→ ",[503,1965,1966],{},"text\u002Fhtml","), or ",[503,1969,1970],{},".responseContentType(type)",". The client then\ndecodes the success body to a ",[503,1973,1974],{},"Blob"," (binary) or ",[503,1977,1978],{},"string",[503,1980,1981],{},"text\u002F*",") and ",[508,1984,1985],{},"skips"," response-schema validation\nfor it: a 2xx schema declared on such a route is informational only (",[1988,1989,199],"a",{"href":200},"), never\nrun.",[499,1992,1993],{},"(Declared error statuses are unaffected — they stay JSON and are still validated.)",[543,1995,1998],{"className":657,"code":1996,"filename":1997,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { UploadsApi } from \"..\u002Fserver\u002Fuploads\u002Fupload.api\"; \u002F\u002F download: Route.get(\"\u002F:key\").download()...\n\nconst api = new UploadsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\nconst file: Blob = await api.client.download({ params: { key: \"report-2026\" } });\n","download.ts",[503,1999,2000,2020,2045,2049,2087,2091],{"__ignoreMap":549},[553,2001,2002,2004,2006,2008,2010,2012,2014,2016,2018],{"class":555,"line":556},[553,2003,668],{"class":667},[553,2005,672],{"class":671},[553,2007,676],{"class":675},[553,2009,679],{"class":671},[553,2011,682],{"class":667},[553,2013,685],{"class":671},[553,2015,532],{"class":562},[553,2017,690],{"class":671},[553,2019,693],{"class":671},[553,2021,2022,2024,2026,2029,2031,2033,2035,2038,2040,2042],{"class":555,"line":696},[553,2023,668],{"class":667},[553,2025,672],{"class":671},[553,2027,2028],{"class":675}," UploadsApi",[553,2030,679],{"class":671},[553,2032,682],{"class":667},[553,2034,685],{"class":671},[553,2036,2037],{"class":562},"..\u002Fserver\u002Fuploads\u002Fupload.api",[553,2039,690],{"class":671},[553,2041,717],{"class":671},[553,2043,2044],{"class":720}," \u002F\u002F download: Route.get(\"\u002F:key\").download()...\n",[553,2046,2047],{"class":555,"line":724},[553,2048,728],{"emptyLinePlaceholder":727},[553,2050,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079,2081,2083,2085],{"class":555,"line":731},[553,2052,735],{"class":734},[553,2054,738],{"class":675},[553,2056,741],{"class":671},[553,2058,744],{"class":671},[553,2060,2028],{"class":747},[553,2062,750],{"class":675},[553,2064,654],{"class":671},[553,2066,755],{"class":747},[553,2068,758],{"class":675},[553,2070,761],{"class":671},[553,2072,765],{"class":764},[553,2074,768],{"class":671},[553,2076,685],{"class":671},[553,2078,773],{"class":562},[553,2080,690],{"class":671},[553,2082,679],{"class":671},[553,2084,780],{"class":675},[553,2086,693],{"class":671},[553,2088,2089],{"class":555,"line":785},[553,2090,728],{"emptyLinePlaceholder":727},[553,2092,2093,2095,2098,2100,2103,2106,2108,2110,2112,2114,2116,2119,2121,2123,2125,2127,2129,2132,2134,2136,2139,2141,2143,2145,2147],{"class":555,"line":790},[553,2094,735],{"class":734},[553,2096,2097],{"class":675}," file",[553,2099,768],{"class":671},[553,2101,2102],{"class":559}," Blob",[553,2104,2105],{"class":671}," =",[553,2107,800],{"class":667},[553,2109,803],{"class":675},[553,2111,654],{"class":671},[553,2113,808],{"class":675},[553,2115,654],{"class":671},[553,2117,2118],{"class":747},"download",[553,2120,758],{"class":675},[553,2122,761],{"class":671},[553,2124,820],{"class":764},[553,2126,768],{"class":671},[553,2128,672],{"class":671},[553,2130,2131],{"class":764}," key",[553,2133,768],{"class":671},[553,2135,685],{"class":671},[553,2137,2138],{"class":562},"report-2026",[553,2140,690],{"class":671},[553,2142,679],{"class":671},[553,2144,679],{"class":671},[553,2146,843],{"class":675},[553,2148,693],{"class":671},[499,2150,2151,2152,2154],{},"This fixes the old failure where validating a ",[503,2153,1974],{}," against a JSON response schema always threw on a\ndownload route.",[535,2156,2158],{"id":2157},"call-the-app-in-process","Call the app in-process",[499,2160,2161,2162,2165,2166,2169,2170,2173],{},"For tests and server-to-server calls, ",[503,2163,2164],{},"ClientTransport.internal"," dispatches through the live app with no network\nhop. The host (for example ",[503,2167,2168],{},"@heximon\u002Fnitro",") supplies a ",[503,2171,2172],{},"localFetch",", and the transport bridges it\ninto the contract client:",[543,2175,2178],{"className":657,"code":2176,"filename":2177,"language":660,"meta":549,"style":549},"import { ClientTransport, type LocalFetch } from \"@heximon\u002Fclient\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\ndeclare const localFetch: LocalFetch; \u002F\u002F host-supplied: (input, init) => Promise\u003CResponse>\n\nconst api = new ProductsApi(ClientTransport.internal(localFetch));\n\nconst product = await api.client.find({ params: { sku: \"abc-123\" } });\n","in-process.ts",[503,2179,2180,2208,2228,2232,2252,2256,2280,2284],{"__ignoreMap":549},[553,2181,2182,2184,2186,2188,2190,2193,2196,2198,2200,2202,2204,2206],{"class":555,"line":556},[553,2183,668],{"class":667},[553,2185,672],{"class":671},[553,2187,676],{"class":675},[553,2189,916],{"class":671},[553,2191,2192],{"class":667}," type",[553,2194,2195],{"class":675}," LocalFetch",[553,2197,679],{"class":671},[553,2199,682],{"class":667},[553,2201,685],{"class":671},[553,2203,532],{"class":562},[553,2205,690],{"class":671},[553,2207,693],{"class":671},[553,2209,2210,2212,2214,2216,2218,2220,2222,2224,2226],{"class":555,"line":696},[553,2211,668],{"class":667},[553,2213,672],{"class":671},[553,2215,703],{"class":675},[553,2217,679],{"class":671},[553,2219,682],{"class":667},[553,2221,685],{"class":671},[553,2223,712],{"class":562},[553,2225,690],{"class":671},[553,2227,693],{"class":671},[553,2229,2230],{"class":555,"line":724},[553,2231,728],{"emptyLinePlaceholder":727},[553,2233,2234,2237,2240,2243,2245,2247,2249],{"class":555,"line":731},[553,2235,2236],{"class":734},"declare",[553,2238,2239],{"class":734}," const",[553,2241,2242],{"class":675}," localFetch",[553,2244,768],{"class":671},[553,2246,2195],{"class":559},[553,2248,717],{"class":671},[553,2250,2251],{"class":720}," \u002F\u002F host-supplied: (input, init) => Promise\u003CResponse>\n",[553,2253,2254],{"class":555,"line":785},[553,2255,728],{"emptyLinePlaceholder":727},[553,2257,2258,2260,2262,2264,2266,2268,2270,2272,2275,2278],{"class":555,"line":790},[553,2259,735],{"class":734},[553,2261,738],{"class":675},[553,2263,741],{"class":671},[553,2265,744],{"class":671},[553,2267,703],{"class":747},[553,2269,750],{"class":675},[553,2271,654],{"class":671},[553,2273,2274],{"class":747},"internal",[553,2276,2277],{"class":675},"(localFetch))",[553,2279,693],{"class":671},[553,2281,2282],{"class":555,"line":848},[553,2283,728],{"emptyLinePlaceholder":727},[553,2285,2286,2288,2290,2292,2294,2296,2298,2300,2302,2304,2306,2308,2310,2312,2314,2316,2318,2320,2322,2324,2326,2328,2330],{"class":555,"line":872},[553,2287,735],{"class":734},[553,2289,795],{"class":675},[553,2291,741],{"class":671},[553,2293,800],{"class":667},[553,2295,803],{"class":675},[553,2297,654],{"class":671},[553,2299,808],{"class":675},[553,2301,654],{"class":671},[553,2303,813],{"class":747},[553,2305,758],{"class":675},[553,2307,761],{"class":671},[553,2309,820],{"class":764},[553,2311,768],{"class":671},[553,2313,672],{"class":671},[553,2315,827],{"class":764},[553,2317,768],{"class":671},[553,2319,685],{"class":671},[553,2321,834],{"class":562},[553,2323,690],{"class":671},[553,2325,679],{"class":671},[553,2327,679],{"class":671},[553,2329,843],{"class":675},[553,2331,693],{"class":671},[499,2333,2334,2335,2337,2338,2341,2342,2345,2346,768],{},"Because interceptors live in the contract client (not the transport), an ",[503,2336,1444],{}," hook runs\n",[508,2339,2340],{},"regardless of transport"," — your in-process and network calls share the same request decoration. For a\nunit test with no host at all, ",[503,2343,2344],{},"ClientTransport.mock"," returns canned responses keyed by ",[503,2347,2348],{},"\"METHOD \u002Fpath\"",[543,2350,2353],{"className":657,"code":2351,"filename":2352,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\nconst api = new ProductsApi(ClientTransport.mock({\n  \"GET \u002Fapi\u002Fproducts\u002Fabc-123\": { status: 200, headers: {}, body: { sku: \"abc-123\", name: \"Widget\", priceInCents: 999 } },\n}));\n\nconst product = await api.client.find({ params: { sku: \"abc-123\" } });\n","test.ts",[503,2354,2355,2375,2395,2399,2422,2494,2502,2506],{"__ignoreMap":549},[553,2356,2357,2359,2361,2363,2365,2367,2369,2371,2373],{"class":555,"line":556},[553,2358,668],{"class":667},[553,2360,672],{"class":671},[553,2362,676],{"class":675},[553,2364,679],{"class":671},[553,2366,682],{"class":667},[553,2368,685],{"class":671},[553,2370,532],{"class":562},[553,2372,690],{"class":671},[553,2374,693],{"class":671},[553,2376,2377,2379,2381,2383,2385,2387,2389,2391,2393],{"class":555,"line":696},[553,2378,668],{"class":667},[553,2380,672],{"class":671},[553,2382,703],{"class":675},[553,2384,679],{"class":671},[553,2386,682],{"class":667},[553,2388,685],{"class":671},[553,2390,712],{"class":562},[553,2392,690],{"class":671},[553,2394,693],{"class":671},[553,2396,2397],{"class":555,"line":724},[553,2398,728],{"emptyLinePlaceholder":727},[553,2400,2401,2403,2405,2407,2409,2411,2413,2415,2418,2420],{"class":555,"line":731},[553,2402,735],{"class":734},[553,2404,738],{"class":675},[553,2406,741],{"class":671},[553,2408,744],{"class":671},[553,2410,703],{"class":747},[553,2412,750],{"class":675},[553,2414,654],{"class":671},[553,2416,2417],{"class":747},"mock",[553,2419,758],{"class":675},[553,2421,1342],{"class":671},[553,2423,2424,2427,2430,2432,2434,2436,2439,2441,2443,2445,2448,2450,2453,2455,2457,2459,2461,2463,2465,2467,2469,2471,2473,2475,2477,2479,2481,2483,2485,2487,2489,2491],{"class":555,"line":785},[553,2425,2426],{"class":671},"  \"",[553,2428,2429],{"class":764},"GET \u002Fapi\u002Fproducts\u002Fabc-123",[553,2431,690],{"class":671},[553,2433,768],{"class":671},[553,2435,672],{"class":671},[553,2437,2438],{"class":764}," status",[553,2440,768],{"class":671},[553,2442,1336],{"class":938},[553,2444,916],{"class":671},[553,2446,2447],{"class":764}," headers",[553,2449,768],{"class":671},[553,2451,2452],{"class":671}," {},",[553,2454,898],{"class":764},[553,2456,768],{"class":671},[553,2458,672],{"class":671},[553,2460,827],{"class":764},[553,2462,768],{"class":671},[553,2464,685],{"class":671},[553,2466,834],{"class":562},[553,2468,690],{"class":671},[553,2470,916],{"class":671},[553,2472,919],{"class":764},[553,2474,768],{"class":671},[553,2476,685],{"class":671},[553,2478,926],{"class":562},[553,2480,690],{"class":671},[553,2482,916],{"class":671},[553,2484,933],{"class":764},[553,2486,768],{"class":671},[553,2488,939],{"class":938},[553,2490,679],{"class":671},[553,2492,2493],{"class":671}," },\n",[553,2495,2496,2498,2500],{"class":555,"line":790},[553,2497,1377],{"class":671},[553,2499,780],{"class":675},[553,2501,693],{"class":671},[553,2503,2504],{"class":555,"line":848},[553,2505,728],{"emptyLinePlaceholder":727},[553,2507,2508,2510,2512,2514,2516,2518,2520,2522,2524,2526,2528,2530,2532,2534,2536,2538,2540,2542,2544,2546,2548,2550,2552],{"class":555,"line":872},[553,2509,735],{"class":734},[553,2511,795],{"class":675},[553,2513,741],{"class":671},[553,2515,800],{"class":667},[553,2517,803],{"class":675},[553,2519,654],{"class":671},[553,2521,808],{"class":675},[553,2523,654],{"class":671},[553,2525,813],{"class":747},[553,2527,758],{"class":675},[553,2529,761],{"class":671},[553,2531,820],{"class":764},[553,2533,768],{"class":671},[553,2535,672],{"class":671},[553,2537,827],{"class":764},[553,2539,768],{"class":671},[553,2541,685],{"class":671},[553,2543,834],{"class":562},[553,2545,690],{"class":671},[553,2547,679],{"class":671},[553,2549,679],{"class":671},[553,2551,843],{"class":675},[553,2553,693],{"class":671},[535,2555,2557],{"id":2556},"use-it-with-vue-query","Use it with Vue Query",[499,2559,2560,2561,2563,2564,2567,2568,2571,2572,971,2575,2578,2579,2582],{},"The optional ",[503,2562,628],{}," subpath builds a per-route binding tree from the same contract: query routes (",[503,2565,2566],{},"GET"," \u002F\n",[503,2569,2570],{},"HEAD",") expose ",[503,2573,2574],{},"useQuery",[503,2576,2577],{},"useInfiniteQuery",", and mutation routes expose ",[503,2580,2581],{},"useMutation",". The query keys, fetch\nargs, and result shapes are all typed from the contract — you write Vue components against routes, not URLs.",[543,2584,2587],{"className":657,"code":2585,"filename":2586,"language":660,"meta":549,"style":549},"import { ClientTransport } from \"@heximon\u002Fclient\";\nimport { VueQuery } from \"@heximon\u002Fclient\u002Fvue-query\";\nimport { ProductsApi } from \"..\u002Fserver\u002Fproducts\u002Fproduct.api\";\n\n\u002F\u002F Pass the class + a transport (VueQuery.initClient constructs the instance):\nconst productsQuery = VueQuery.initClient(ProductsApi, ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\n\n\u002F\u002F Or pass an already-constructed instance:\nconst api = new ProductsApi(ClientTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }));\nconst productsQuery2 = VueQuery.initClient(api);\n\n\u002F\u002F a query route\nconst found = productsQuery.find.useQuery([\"product\", \"abc-123\"], () => ({ params: { sku: \"abc-123\" } }), {\n  enabled: true,\n});\nif (found.data.value?.status === 200) {\n  const name: string = found.data.value.body.name;\n}\n\n\u002F\u002F a mutation route\nconst create = productsQuery.create.useMutation();\ncreate.mutate({ body: { sku: \"new-1\", name: \"Widget\", priceInCents: 999 } });\n","products.vue-query.ts",[503,2588,2589,2609,2631,2651,2655,2660,2707,2711,2716,2754,2774,2778,2783,2861,2876,2885,2916,2952,2957,2962,2968,2993],{"__ignoreMap":549},[553,2590,2591,2593,2595,2597,2599,2601,2603,2605,2607],{"class":555,"line":556},[553,2592,668],{"class":667},[553,2594,672],{"class":671},[553,2596,676],{"class":675},[553,2598,679],{"class":671},[553,2600,682],{"class":667},[553,2602,685],{"class":671},[553,2604,532],{"class":562},[553,2606,690],{"class":671},[553,2608,693],{"class":671},[553,2610,2611,2613,2615,2618,2620,2622,2624,2627,2629],{"class":555,"line":696},[553,2612,668],{"class":667},[553,2614,672],{"class":671},[553,2616,2617],{"class":675}," VueQuery",[553,2619,679],{"class":671},[553,2621,682],{"class":667},[553,2623,685],{"class":671},[553,2625,2626],{"class":562},"@heximon\u002Fclient\u002Fvue-query",[553,2628,690],{"class":671},[553,2630,693],{"class":671},[553,2632,2633,2635,2637,2639,2641,2643,2645,2647,2649],{"class":555,"line":724},[553,2634,668],{"class":667},[553,2636,672],{"class":671},[553,2638,703],{"class":675},[553,2640,679],{"class":671},[553,2642,682],{"class":667},[553,2644,685],{"class":671},[553,2646,712],{"class":562},[553,2648,690],{"class":671},[553,2650,693],{"class":671},[553,2652,2653],{"class":555,"line":731},[553,2654,728],{"emptyLinePlaceholder":727},[553,2656,2657],{"class":555,"line":785},[553,2658,2659],{"class":720},"\u002F\u002F Pass the class + a transport (VueQuery.initClient constructs the instance):\n",[553,2661,2662,2664,2667,2669,2671,2673,2676,2679,2681,2683,2685,2687,2689,2691,2693,2695,2697,2699,2701,2703,2705],{"class":555,"line":790},[553,2663,735],{"class":734},[553,2665,2666],{"class":675}," productsQuery ",[553,2668,741],{"class":671},[553,2670,2617],{"class":675},[553,2672,654],{"class":671},[553,2674,2675],{"class":747},"initClient",[553,2677,2678],{"class":675},"(ProductsApi",[553,2680,916],{"class":671},[553,2682,676],{"class":675},[553,2684,654],{"class":671},[553,2686,755],{"class":747},[553,2688,758],{"class":675},[553,2690,761],{"class":671},[553,2692,765],{"class":764},[553,2694,768],{"class":671},[553,2696,685],{"class":671},[553,2698,773],{"class":562},[553,2700,690],{"class":671},[553,2702,679],{"class":671},[553,2704,780],{"class":675},[553,2706,693],{"class":671},[553,2708,2709],{"class":555,"line":848},[553,2710,728],{"emptyLinePlaceholder":727},[553,2712,2713],{"class":555,"line":872},[553,2714,2715],{"class":720},"\u002F\u002F Or pass an already-constructed instance:\n",[553,2717,2718,2720,2722,2724,2726,2728,2730,2732,2734,2736,2738,2740,2742,2744,2746,2748,2750,2752],{"class":555,"line":877},[553,2719,735],{"class":734},[553,2721,738],{"class":675},[553,2723,741],{"class":671},[553,2725,744],{"class":671},[553,2727,703],{"class":747},[553,2729,750],{"class":675},[553,2731,654],{"class":671},[553,2733,755],{"class":747},[553,2735,758],{"class":675},[553,2737,761],{"class":671},[553,2739,765],{"class":764},[553,2741,768],{"class":671},[553,2743,685],{"class":671},[553,2745,773],{"class":562},[553,2747,690],{"class":671},[553,2749,679],{"class":671},[553,2751,780],{"class":675},[553,2753,693],{"class":671},[553,2755,2756,2758,2761,2763,2765,2767,2769,2772],{"class":555,"line":950},[553,2757,735],{"class":734},[553,2759,2760],{"class":675}," productsQuery2 ",[553,2762,741],{"class":671},[553,2764,2617],{"class":675},[553,2766,654],{"class":671},[553,2768,2675],{"class":747},[553,2770,2771],{"class":675},"(api)",[553,2773,693],{"class":671},[553,2775,2776],{"class":555,"line":1406},[553,2777,728],{"emptyLinePlaceholder":727},[553,2779,2780],{"class":555,"line":1929},[553,2781,2782],{"class":720},"\u002F\u002F a query route\n",[553,2784,2785,2787,2790,2792,2795,2797,2799,2801,2803,2806,2808,2811,2813,2815,2817,2819,2821,2824,2826,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851,2853,2855,2857,2859],{"class":555,"line":1935},[553,2786,735],{"class":734},[553,2788,2789],{"class":675}," found ",[553,2791,741],{"class":671},[553,2793,2794],{"class":675}," productsQuery",[553,2796,654],{"class":671},[553,2798,813],{"class":675},[553,2800,654],{"class":671},[553,2802,2574],{"class":747},[553,2804,2805],{"class":675},"([",[553,2807,690],{"class":671},[553,2809,2810],{"class":562},"product",[553,2812,690],{"class":671},[553,2814,916],{"class":671},[553,2816,685],{"class":671},[553,2818,834],{"class":562},[553,2820,690],{"class":671},[553,2822,2823],{"class":675},"]",[553,2825,916],{"class":671},[553,2827,2828],{"class":671}," ()",[553,2830,1614],{"class":734},[553,2832,1606],{"class":675},[553,2834,761],{"class":671},[553,2836,820],{"class":764},[553,2838,768],{"class":671},[553,2840,672],{"class":671},[553,2842,827],{"class":764},[553,2844,768],{"class":671},[553,2846,685],{"class":671},[553,2848,834],{"class":562},[553,2850,690],{"class":671},[553,2852,679],{"class":671},[553,2854,679],{"class":671},[553,2856,843],{"class":675},[553,2858,916],{"class":671},[553,2860,1540],{"class":671},[553,2862,2864,2867,2869,2873],{"class":555,"line":2863},14,[553,2865,2866],{"class":764},"  enabled",[553,2868,768],{"class":671},[553,2870,2872],{"class":2871},"sfNiH"," true",[553,2874,2875],{"class":671},",\n",[553,2877,2879,2881,2883],{"class":555,"line":2878},15,[553,2880,1377],{"class":671},[553,2882,843],{"class":675},[553,2884,693],{"class":671},[553,2886,2888,2890,2893,2895,2898,2900,2903,2906,2908,2910,2912,2914],{"class":555,"line":2887},16,[553,2889,1322],{"class":667},[553,2891,2892],{"class":675}," (found",[553,2894,654],{"class":671},[553,2896,2897],{"class":675},"data",[553,2899,654],{"class":671},[553,2901,2902],{"class":675},"value",[553,2904,2905],{"class":671},"?.",[553,2907,1330],{"class":675},[553,2909,1333],{"class":671},[553,2911,1336],{"class":938},[553,2913,1339],{"class":675},[553,2915,1342],{"class":671},[553,2917,2919,2922,2924,2926,2929,2931,2934,2936,2938,2940,2942,2944,2946,2948,2950],{"class":555,"line":2918},17,[553,2920,2921],{"class":734},"  const",[553,2923,919],{"class":675},[553,2925,768],{"class":671},[553,2927,2928],{"class":559}," string",[553,2930,2105],{"class":671},[553,2932,2933],{"class":675}," found",[553,2935,654],{"class":671},[553,2937,2897],{"class":675},[553,2939,654],{"class":671},[553,2941,2902],{"class":675},[553,2943,654],{"class":671},[553,2945,977],{"class":675},[553,2947,654],{"class":671},[553,2949,1365],{"class":675},[553,2951,693],{"class":671},[553,2953,2955],{"class":555,"line":2954},18,[553,2956,1409],{"class":671},[553,2958,2960],{"class":555,"line":2959},19,[553,2961,728],{"emptyLinePlaceholder":727},[553,2963,2965],{"class":555,"line":2964},20,[553,2966,2967],{"class":720},"\u002F\u002F a mutation route\n",[553,2969,2971,2973,2976,2978,2980,2982,2984,2986,2988,2991],{"class":555,"line":2970},21,[553,2972,735],{"class":734},[553,2974,2975],{"class":675}," create ",[553,2977,741],{"class":671},[553,2979,2794],{"class":675},[553,2981,654],{"class":671},[553,2983,891],{"class":675},[553,2985,654],{"class":671},[553,2987,2581],{"class":747},[553,2989,2990],{"class":675},"()",[553,2992,693],{"class":671},[553,2994,2996,2998,3000,3003,3005,3007,3009,3011,3013,3015,3017,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043,3045,3047,3049],{"class":555,"line":2995},22,[553,2997,891],{"class":675},[553,2999,654],{"class":671},[553,3001,3002],{"class":747},"mutate",[553,3004,758],{"class":675},[553,3006,761],{"class":671},[553,3008,898],{"class":764},[553,3010,768],{"class":671},[553,3012,672],{"class":671},[553,3014,827],{"class":764},[553,3016,768],{"class":671},[553,3018,685],{"class":671},[553,3020,911],{"class":562},[553,3022,690],{"class":671},[553,3024,916],{"class":671},[553,3026,919],{"class":764},[553,3028,768],{"class":671},[553,3030,685],{"class":671},[553,3032,926],{"class":562},[553,3034,690],{"class":671},[553,3036,916],{"class":671},[553,3038,933],{"class":764},[553,3040,768],{"class":671},[553,3042,939],{"class":938},[553,3044,679],{"class":671},[553,3046,679],{"class":671},[553,3048,843],{"class":675},[553,3050,693],{"class":671},[535,3052,3054],{"id":3053},"real-time-typed-sse-and-websocket-clients","Real-time: typed SSE and WebSocket clients",[499,3056,3057,960,3060,3062],{},[503,3058,3059],{},"ClientTransport",[503,3061,518],{}," cover request\u002Fresponse REST calls.",[499,3064,1437,3065,3068,3069,3072,3073,3076,3077,633,3080,3076,3083,3086,3087,3090],{},[503,3066,3067],{},"ServerSentEvents"," broadcast feed or a ",[503,3070,3071],{},"WebSocketContract"," connection is a different shape — a long-lived\nstream instead of one call — so those get their own typed clients: ",[503,3074,3075],{},"@heximon\u002Fclient\u002Fsse","'s ",[503,3078,3079],{},"SseClient",[503,3081,3082],{},"@heximon\u002Fclient\u002Fws",[503,3084,3085],{},"WsClient",", each typed off the same contract\u002Fevent-map class your server declares.\nSee ",[1988,3088,3089],{"href":281},"Typed real-time clients"," for both.",[535,3092,3094],{"id":3093},"see-also","See also",[3096,3097,3098,3114,3123,3128],"ul",{},[3099,3100,3101,3103,3104,3106,3107,3110,3111,654],"li",{},[1988,3102,67],{"href":68}," — author the ",[503,3105,505],{}," class both the client and the server bind to, with\nthe ",[503,3108,3109],{},"Route"," builder and shared ",[503,3112,3113],{},"responses",[3099,3115,3116,3118,3119,3122],{},[1988,3117,57],{"href":58}," — serve that same contract from a controller that ",[503,3120,3121],{},"implements Controller\u003CSomeApi>"," on the backend, so request and response are typed end to end.",[3099,3124,3125,3127],{},[1988,3126,62],{"href":63}," — the response schemas the client checks on every call are your\nDTOs, any Standard Schema (valibot, Zod, …).",[3099,3129,3130,3132],{},[1988,3131,199],{"href":200}," — document the same contract as an OpenAPI 3.1 spec for consumers that aren't\non TypeScript.",[3134,3135,3136],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":549,"searchDepth":696,"depth":696,"links":3138},[3139,3140,3141,3143,3144,3145,3146,3147,3148,3149],{"id":537,"depth":696,"text":538},{"id":640,"depth":696,"text":641},{"id":1137,"depth":696,"text":3142},"Handle every status with raw()",{"id":1433,"depth":696,"text":1434},{"id":1680,"depth":696,"text":1681},{"id":1943,"depth":696,"text":1944},{"id":2157,"depth":696,"text":2158},{"id":2556,"depth":696,"text":2557},{"id":3053,"depth":696,"text":3054},{"id":3093,"depth":696,"text":3094},"Call a shared Contract from the frontend by constructing it with a transport — ClientTransport.fetch, ClientTransport.internal, and ClientTransport.mock, throwing 2xx-body callers, raw() for the full status union, request\u002Fresponse interceptors, and vue-query bindings.","md",null,{},{"icon":75},{"title":72,"description":3150},"eP8OYjxWnKpT-nikxZw6JEonAZRPCKxfrsegO_sreIk",[3158,3160],{"title":67,"path":68,"stem":69,"description":3159,"icon":70,"children":-1},"Describe an HTTP API once with the Contract class and Route builder, then bind the server, the REST client, and OpenAPI to the same route table — Route.get\u002Fpost, body, responses, pathParams, scopes, shared responses, contract-mode controllers.",{"title":77,"path":78,"stem":79,"description":3161,"icon":80,"children":-1},"Wire a real SQLite database into a CRUD API with no install and no compiler plugin — the unified DrizzleLibSQLConfig, a named database DI token, a repository over getOrm(), and boot-time table creation.",1783300761903]