[{"data":1,"prerenderedAt":3466},["ShallowReactive",2],{"navigation_docs":3,"-docs-realtime-asyncapi":493,"-docs-realtime-asyncapi-surround":3461},[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":285,"body":495,"description":3454,"extension":3455,"links":3456,"meta":3457,"navigation":3458,"path":286,"seo":3459,"stem":287,"__hash__":3460},"docs\u002Fdocs\u002F05.realtime\u002F06.asyncapi.md",{"type":496,"value":497,"toc":3440},"minimark",[498,519,531,536,607,626,630,656,945,992,997,1001,1022,1098,1114,1136,1141,1379,1532,1542,1575,1579,1753,1904,1910,1928,1932,1954,1958,1977,2035,2051,2055,2058,2203,2206,2303,2307,2317,3076,3082,3098,3102,3120,3346,3363,3367,3436],[499,500,501,502,506,507,510,511,518],"p",{},"You described your real-time API once — a ",[503,504,505],"code",{},"WebSocketContract"," carries the bidirectional schema for every\nmessage kind, and a ",[503,508,509],{},"ServerSentEvents"," class carries the broadcast event map for every SSE channel. Point a\ngenerator at them and you get a standards-compliant ",[512,513,517],"a",{"href":514,"rel":515},"https:\u002F\u002Fwww.asyncapi.com\u002Fdocs\u002Freference\u002Fspecification\u002Fv3.0.0",[516],"nofollow","AsyncAPI 3.1","\ndocument whose message schemas read the same Standard Schemas your server validates, so your docs can't\ndrift from what the wire actually accepts.",[499,520,521,522,526,527,530],{},"Generation happens at ",[523,524,525],"strong",{},"runtime",": ",[503,528,529],{},"AsyncApiGenerator"," is a plain class you construct and call from a\ncontroller — there's no plugin to register and no compiler step.",[532,533,535],"h2",{"id":534},"install-the-package","Install the package",[537,538,539,564,579,593],"code-group",{},[540,541,547],"pre",{"className":542,"code":543,"filename":544,"language":545,"meta":546,"style":546},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @heximon\u002Fasyncapi\n","pnpm","bash","",[503,548,549],{"__ignoreMap":546},[550,551,554,557,561],"span",{"class":552,"line":553},"line",1,[550,555,544],{"class":556},"sBMFI",[550,558,560],{"class":559},"sfazB"," add",[550,562,563],{"class":559}," @heximon\u002Fasyncapi\n",[540,565,568],{"className":542,"code":566,"filename":567,"language":545,"meta":546,"style":546},"npm install @heximon\u002Fasyncapi\n","npm",[503,569,570],{"__ignoreMap":546},[550,571,572,574,577],{"class":552,"line":553},[550,573,567],{"class":556},[550,575,576],{"class":559}," install",[550,578,563],{"class":559},[540,580,583],{"className":542,"code":581,"filename":582,"language":545,"meta":546,"style":546},"yarn add @heximon\u002Fasyncapi\n","yarn",[503,584,585],{"__ignoreMap":546},[550,586,587,589,591],{"class":552,"line":553},[550,588,582],{"class":556},[550,590,560],{"class":559},[550,592,563],{"class":559},[540,594,597],{"className":542,"code":595,"filename":596,"language":545,"meta":546,"style":546},"bun add @heximon\u002Fasyncapi\n","bun",[503,598,599],{"__ignoreMap":546},[550,600,601,603,605],{"class":552,"line":553},[550,602,596],{"class":556},[550,604,560],{"class":559},[550,606,563],{"class":559},[499,608,609,610,613,614,617,618,621,622,625],{},"There is nothing to add to ",[503,611,612],{},"vite.config.ts",". The generator depends on ",[503,615,616],{},"@heximon\u002Fopenapi"," for the\nStandard-Schema → JSON-Schema converter it shares; ",[503,619,620],{},"@heximon\u002Fwebsocket"," and ",[503,623,624],{},"@heximon\u002Fsse"," are optional peers\naccepted by structural duck-typing.",[532,627,629],{"id":628},"generate-the-document","Generate the document",[499,631,632,635,636,639,640,643,644,647,648,651,652,655],{},[503,633,634],{},"new AsyncApiGenerator(options)"," takes ",[503,637,638],{},"info"," (title + version, plus optional description), a ",[503,641,642],{},"channels","\narray of channel descriptors, and an optional custom ",[503,645,646],{},"converter",". Call ",[503,649,650],{},"generate()"," to build the document — it\nbuilds ",[523,653,654],{},"once"," and returns the same memoized object on every subsequent call.",[540,657,662],{"className":658,"code":659,"filename":660,"language":661,"meta":546,"style":546},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { AsyncApiGenerator } from \"@heximon\u002Fasyncapi\";\nimport { ChatContract } from \"..\u002Fchat\u002Fchat.contract\";\nimport { FeedEvents } from \"..\u002Ffeed\u002Ffeed.events\";\n\nexport const asyncApiGenerator = new AsyncApiGenerator({\n  info: {\n    title: \"Chat API\",\n    version: \"1.0.0\",\n    description: \"WebSocket chat and SSE feed, documented with AsyncAPI 3.1.\",\n  },\n  channels: [\n    \u002F\u002F No `address`: each channel's address defaults from the contract\u002Fevents value's own declared `path`.\n    { kind: \"websocket\", contract: ChatContract },\n    { kind: \"sse\",       events: FeedEvents },\n  ],\n});\n","src\u002Fdocs\u002Fasyncapi.ts","ts",[503,663,664,696,719,742,749,777,790,808,825,842,848,859,866,898,926,934],{"__ignoreMap":546},[550,665,666,670,674,678,681,684,687,690,693],{"class":552,"line":553},[550,667,669],{"class":668},"s7zQu","import",[550,671,673],{"class":672},"sMK4o"," {",[550,675,677],{"class":676},"sTEyZ"," AsyncApiGenerator",[550,679,680],{"class":672}," }",[550,682,683],{"class":668}," from",[550,685,686],{"class":672}," \"",[550,688,689],{"class":559},"@heximon\u002Fasyncapi",[550,691,692],{"class":672},"\"",[550,694,695],{"class":672},";\n",[550,697,699,701,703,706,708,710,712,715,717],{"class":552,"line":698},2,[550,700,669],{"class":668},[550,702,673],{"class":672},[550,704,705],{"class":676}," ChatContract",[550,707,680],{"class":672},[550,709,683],{"class":668},[550,711,686],{"class":672},[550,713,714],{"class":559},"..\u002Fchat\u002Fchat.contract",[550,716,692],{"class":672},[550,718,695],{"class":672},[550,720,722,724,726,729,731,733,735,738,740],{"class":552,"line":721},3,[550,723,669],{"class":668},[550,725,673],{"class":672},[550,727,728],{"class":676}," FeedEvents",[550,730,680],{"class":672},[550,732,683],{"class":668},[550,734,686],{"class":672},[550,736,737],{"class":559},"..\u002Ffeed\u002Ffeed.events",[550,739,692],{"class":672},[550,741,695],{"class":672},[550,743,745],{"class":552,"line":744},4,[550,746,748],{"emptyLinePlaceholder":747},true,"\n",[550,750,752,755,759,762,765,768,771,774],{"class":552,"line":751},5,[550,753,754],{"class":668},"export",[550,756,758],{"class":757},"spNyl"," const",[550,760,761],{"class":676}," asyncApiGenerator ",[550,763,764],{"class":672},"=",[550,766,767],{"class":672}," new",[550,769,677],{"class":770},"s2Zo4",[550,772,773],{"class":676},"(",[550,775,776],{"class":672},"{\n",[550,778,780,784,787],{"class":552,"line":779},6,[550,781,783],{"class":782},"swJcz","  info",[550,785,786],{"class":672},":",[550,788,789],{"class":672}," {\n",[550,791,793,796,798,800,803,805],{"class":552,"line":792},7,[550,794,795],{"class":782},"    title",[550,797,786],{"class":672},[550,799,686],{"class":672},[550,801,802],{"class":559},"Chat API",[550,804,692],{"class":672},[550,806,807],{"class":672},",\n",[550,809,811,814,816,818,821,823],{"class":552,"line":810},8,[550,812,813],{"class":782},"    version",[550,815,786],{"class":672},[550,817,686],{"class":672},[550,819,820],{"class":559},"1.0.0",[550,822,692],{"class":672},[550,824,807],{"class":672},[550,826,828,831,833,835,838,840],{"class":552,"line":827},9,[550,829,830],{"class":782},"    description",[550,832,786],{"class":672},[550,834,686],{"class":672},[550,836,837],{"class":559},"WebSocket chat and SSE feed, documented with AsyncAPI 3.1.",[550,839,692],{"class":672},[550,841,807],{"class":672},[550,843,845],{"class":552,"line":844},10,[550,846,847],{"class":672},"  },\n",[550,849,851,854,856],{"class":552,"line":850},11,[550,852,853],{"class":782},"  channels",[550,855,786],{"class":672},[550,857,858],{"class":676}," [\n",[550,860,862],{"class":552,"line":861},12,[550,863,865],{"class":864},"sHwdD","    \u002F\u002F No `address`: each channel's address defaults from the contract\u002Fevents value's own declared `path`.\n",[550,867,869,872,875,877,879,882,884,887,890,892,895],{"class":552,"line":868},13,[550,870,871],{"class":672},"    {",[550,873,874],{"class":782}," kind",[550,876,786],{"class":672},[550,878,686],{"class":672},[550,880,881],{"class":559},"websocket",[550,883,692],{"class":672},[550,885,886],{"class":672},",",[550,888,889],{"class":782}," contract",[550,891,786],{"class":672},[550,893,894],{"class":676}," ChatContract ",[550,896,897],{"class":672},"},\n",[550,899,901,903,905,907,909,912,914,916,919,921,924],{"class":552,"line":900},14,[550,902,871],{"class":672},[550,904,874],{"class":782},[550,906,786],{"class":672},[550,908,686],{"class":672},[550,910,911],{"class":559},"sse",[550,913,692],{"class":672},[550,915,886],{"class":672},[550,917,918],{"class":782},"       events",[550,920,786],{"class":672},[550,922,923],{"class":676}," FeedEvents ",[550,925,897],{"class":672},[550,927,929,932],{"class":552,"line":928},15,[550,930,931],{"class":676},"  ]",[550,933,807],{"class":672},[550,935,937,940,943],{"class":552,"line":936},16,[550,938,939],{"class":672},"}",[550,941,942],{"class":676},")",[550,944,695],{"class":672},[499,946,947,948,951,952,955,956,959,960,963,964,967,968,970,971,974,975,978,979,981,982,985,986,988,989,991],{},"A channel's ",[503,949,950],{},"address"," is ",[523,953,954],{},"optional"," when the ",[503,957,958],{},"contract","\u002F",[503,961,962],{},"events"," value declares its own ",[503,965,966],{},"path"," — the same\n",[503,969,966],{}," a ",[503,972,973],{},"WebSocketContract({ path, ... })"," or ",[503,976,977],{},"ServerSentEvents({ path, events })"," class declares for the\nserver and client to share becomes the channel's address, so the address lives in exactly one place. An\nexplicit channel ",[503,980,950],{}," still wins when both are supplied; a channel with ",[523,983,984],{},"neither"," an explicit\n",[503,987,950],{}," nor a declared ",[503,990,966],{}," throws at generation time.",[499,993,994,996],{},[503,995,650],{}," assembles one channel per descriptor and one or two operations per channel. A duplicate address\nacross descriptors produces an ambiguous key — keep channel addresses unique.",[532,998,1000],{"id":999},"supply-channel-descriptors","Supply channel descriptors",[499,1002,1003,1004,1006,1007,1010,1011,974,1013,1015,1016,1018,1019,1021],{},"Each entry in ",[503,1005,642],{}," is a discriminated union keyed by ",[503,1008,1009],{},"kind",". The ",[503,1012,958],{},[503,1014,962],{}," value is read\nby structural duck-typing — a ",[503,1017,505],{}," subclass or a ",[503,1020,509],{}," subclass both work\nwithout installing either optional peer:",[1023,1024,1025,1043],"table",{},[1026,1027,1028],"thead",{},[1029,1030,1031,1037,1040],"tr",{},[1032,1033,1035],"th",{"align":1034},"left",[503,1036,1009],{},[1032,1038,1039],{"align":1034},"Fields",[1032,1041,1042],{"align":1034},"What the generator reads",[1044,1045,1046,1076],"tbody",{},[1029,1047,1048,1054,1062],{},[1049,1050,1051],"td",{"align":1034},[503,1052,1053],{},"\"websocket\"",[1049,1055,1056,1058,1059],{"align":1034},[503,1057,958],{},", ",[503,1060,1061],{},"address?",[1049,1063,1064,1067,1068,1071,1072,1075],{"align":1034},[503,1065,1066],{},"contract.clientToServer"," (C2S schema map) and ",[503,1069,1070],{},"contract.serverToClient"," (S2C schema map); ",[503,1073,1074],{},"contract.path"," defaults the address",[1029,1077,1078,1083,1089],{},[1049,1079,1080],{"align":1034},[503,1081,1082],{},"\"sse\"",[1049,1084,1085,1058,1087],{"align":1034},[503,1086,962],{},[503,1088,1061],{},[1049,1090,1091,1094,1095,1075],{"align":1034},[503,1092,1093],{},"events.events"," (the broadcast event-schema map); ",[503,1096,1097],{},"events.path",[499,1099,1100,1102,1103,959,1105,963,1107,1109,1110,1113],{},[503,1101,950],{}," is optional on both — omit it when the ",[503,1104,958],{},[503,1106,962],{},[503,1108,966],{}," (see\n",[512,1111,629],{"href":1112},"#generate-the-document"," above).",[499,1115,1116,1117,1120,1121,1124,1125,1128,1129,1132,1133,1135],{},"A WebSocket channel produces ",[523,1118,1119],{},"two operations"," — ",[503,1122,1123],{},"${channelName}Send"," (client-to-server) and\n",[503,1126,1127],{},"${channelName}Receive"," (server-to-client). An SSE channel produces ",[523,1130,1131],{},"one operation"," —\n",[503,1134,1127],{}," — because SSE is server-to-client only.",[1137,1138,1140],"h3",{"id":1139},"websocket-channel","WebSocket channel",[540,1142,1145],{"className":658,"code":1143,"filename":1144,"language":661,"meta":546,"style":546},"import { object, string } from \"valibot\";\nimport { WebSocketContract } from \"@heximon\u002Fcontract\u002Fwebsocket\";\n\nexport class ChatContract extends WebSocketContract({\n  path: \"\u002Fchat\",\n  clientToServer: {\n    \"chat.message\": object({ text: string() }),\n  },\n  serverToClient: {\n    \"chat.joined\":  object({ userId: string() }),\n    \"chat.message\": object({ userId: string(), text: string() }),\n  },\n}) {}\n","src\u002Fchat\u002Fchat.contract.ts",[503,1146,1147,1174,1196,1200,1218,1234,1243,1278,1282,1291,1324,1365,1369],{"__ignoreMap":546},[550,1148,1149,1151,1153,1156,1158,1161,1163,1165,1167,1170,1172],{"class":552,"line":553},[550,1150,669],{"class":668},[550,1152,673],{"class":672},[550,1154,1155],{"class":676}," object",[550,1157,886],{"class":672},[550,1159,1160],{"class":676}," string",[550,1162,680],{"class":672},[550,1164,683],{"class":668},[550,1166,686],{"class":672},[550,1168,1169],{"class":559},"valibot",[550,1171,692],{"class":672},[550,1173,695],{"class":672},[550,1175,1176,1178,1180,1183,1185,1187,1189,1192,1194],{"class":552,"line":698},[550,1177,669],{"class":668},[550,1179,673],{"class":672},[550,1181,1182],{"class":676}," WebSocketContract",[550,1184,680],{"class":672},[550,1186,683],{"class":668},[550,1188,686],{"class":672},[550,1190,1191],{"class":559},"@heximon\u002Fcontract\u002Fwebsocket",[550,1193,692],{"class":672},[550,1195,695],{"class":672},[550,1197,1198],{"class":552,"line":721},[550,1199,748],{"emptyLinePlaceholder":747},[550,1201,1202,1204,1207,1209,1212,1214,1216],{"class":552,"line":744},[550,1203,754],{"class":668},[550,1205,1206],{"class":757}," class",[550,1208,705],{"class":556},[550,1210,1211],{"class":757}," extends",[550,1213,1182],{"class":770},[550,1215,773],{"class":676},[550,1217,776],{"class":672},[550,1219,1220,1223,1225,1227,1230,1232],{"class":552,"line":751},[550,1221,1222],{"class":782},"  path",[550,1224,786],{"class":672},[550,1226,686],{"class":672},[550,1228,1229],{"class":559},"\u002Fchat",[550,1231,692],{"class":672},[550,1233,807],{"class":672},[550,1235,1236,1239,1241],{"class":552,"line":779},[550,1237,1238],{"class":782},"  clientToServer",[550,1240,786],{"class":672},[550,1242,789],{"class":672},[550,1244,1245,1248,1251,1253,1255,1257,1259,1262,1265,1267,1269,1272,1274,1276],{"class":552,"line":792},[550,1246,1247],{"class":672},"    \"",[550,1249,1250],{"class":782},"chat.message",[550,1252,692],{"class":672},[550,1254,786],{"class":672},[550,1256,1155],{"class":770},[550,1258,773],{"class":676},[550,1260,1261],{"class":672},"{",[550,1263,1264],{"class":782}," text",[550,1266,786],{"class":672},[550,1268,1160],{"class":770},[550,1270,1271],{"class":676},"() ",[550,1273,939],{"class":672},[550,1275,942],{"class":676},[550,1277,807],{"class":672},[550,1279,1280],{"class":552,"line":810},[550,1281,847],{"class":672},[550,1283,1284,1287,1289],{"class":552,"line":827},[550,1285,1286],{"class":782},"  serverToClient",[550,1288,786],{"class":672},[550,1290,789],{"class":672},[550,1292,1293,1295,1298,1300,1302,1305,1307,1309,1312,1314,1316,1318,1320,1322],{"class":552,"line":844},[550,1294,1247],{"class":672},[550,1296,1297],{"class":782},"chat.joined",[550,1299,692],{"class":672},[550,1301,786],{"class":672},[550,1303,1304],{"class":770},"  object",[550,1306,773],{"class":676},[550,1308,1261],{"class":672},[550,1310,1311],{"class":782}," userId",[550,1313,786],{"class":672},[550,1315,1160],{"class":770},[550,1317,1271],{"class":676},[550,1319,939],{"class":672},[550,1321,942],{"class":676},[550,1323,807],{"class":672},[550,1325,1326,1328,1330,1332,1334,1336,1338,1340,1342,1344,1346,1349,1351,1353,1355,1357,1359,1361,1363],{"class":552,"line":850},[550,1327,1247],{"class":672},[550,1329,1250],{"class":782},[550,1331,692],{"class":672},[550,1333,786],{"class":672},[550,1335,1155],{"class":770},[550,1337,773],{"class":676},[550,1339,1261],{"class":672},[550,1341,1311],{"class":782},[550,1343,786],{"class":672},[550,1345,1160],{"class":770},[550,1347,1348],{"class":676},"()",[550,1350,886],{"class":672},[550,1352,1264],{"class":782},[550,1354,786],{"class":672},[550,1356,1160],{"class":770},[550,1358,1271],{"class":676},[550,1360,939],{"class":672},[550,1362,942],{"class":676},[550,1364,807],{"class":672},[550,1366,1367],{"class":552,"line":861},[550,1368,847],{"class":672},[550,1370,1371,1373,1376],{"class":552,"line":868},[550,1372,939],{"class":672},[550,1374,1375],{"class":676},") ",[550,1377,1378],{"class":672},"{}\n",[540,1380,1382],{"className":658,"code":1381,"filename":660,"language":661,"meta":546,"style":546},"import { AsyncApiGenerator } from \"@heximon\u002Fasyncapi\";\nimport { ChatContract } from \"..\u002Fchat\u002Fchat.contract\";\n\nexport const generator = new AsyncApiGenerator({\n  info: { title: \"Chat API\", version: \"1.0.0\" },\n  channels: [\n    { kind: \"websocket\", contract: ChatContract }, \u002F\u002F address defaults from ChatContract.path\n  ],\n});\n",[503,1383,1384,1404,1424,1428,1447,1482,1490,1518,1524],{"__ignoreMap":546},[550,1385,1386,1388,1390,1392,1394,1396,1398,1400,1402],{"class":552,"line":553},[550,1387,669],{"class":668},[550,1389,673],{"class":672},[550,1391,677],{"class":676},[550,1393,680],{"class":672},[550,1395,683],{"class":668},[550,1397,686],{"class":672},[550,1399,689],{"class":559},[550,1401,692],{"class":672},[550,1403,695],{"class":672},[550,1405,1406,1408,1410,1412,1414,1416,1418,1420,1422],{"class":552,"line":698},[550,1407,669],{"class":668},[550,1409,673],{"class":672},[550,1411,705],{"class":676},[550,1413,680],{"class":672},[550,1415,683],{"class":668},[550,1417,686],{"class":672},[550,1419,714],{"class":559},[550,1421,692],{"class":672},[550,1423,695],{"class":672},[550,1425,1426],{"class":552,"line":721},[550,1427,748],{"emptyLinePlaceholder":747},[550,1429,1430,1432,1434,1437,1439,1441,1443,1445],{"class":552,"line":744},[550,1431,754],{"class":668},[550,1433,758],{"class":757},[550,1435,1436],{"class":676}," generator ",[550,1438,764],{"class":672},[550,1440,767],{"class":672},[550,1442,677],{"class":770},[550,1444,773],{"class":676},[550,1446,776],{"class":672},[550,1448,1449,1451,1453,1455,1458,1460,1462,1464,1466,1468,1471,1473,1475,1477,1479],{"class":552,"line":751},[550,1450,783],{"class":782},[550,1452,786],{"class":672},[550,1454,673],{"class":672},[550,1456,1457],{"class":782}," title",[550,1459,786],{"class":672},[550,1461,686],{"class":672},[550,1463,802],{"class":559},[550,1465,692],{"class":672},[550,1467,886],{"class":672},[550,1469,1470],{"class":782}," version",[550,1472,786],{"class":672},[550,1474,686],{"class":672},[550,1476,820],{"class":559},[550,1478,692],{"class":672},[550,1480,1481],{"class":672}," },\n",[550,1483,1484,1486,1488],{"class":552,"line":779},[550,1485,853],{"class":782},[550,1487,786],{"class":672},[550,1489,858],{"class":676},[550,1491,1492,1494,1496,1498,1500,1502,1504,1506,1508,1510,1512,1515],{"class":552,"line":792},[550,1493,871],{"class":672},[550,1495,874],{"class":782},[550,1497,786],{"class":672},[550,1499,686],{"class":672},[550,1501,881],{"class":559},[550,1503,692],{"class":672},[550,1505,886],{"class":672},[550,1507,889],{"class":782},[550,1509,786],{"class":672},[550,1511,894],{"class":676},[550,1513,1514],{"class":672},"},",[550,1516,1517],{"class":864}," \u002F\u002F address defaults from ChatContract.path\n",[550,1519,1520,1522],{"class":552,"line":810},[550,1521,931],{"class":676},[550,1523,807],{"class":672},[550,1525,1526,1528,1530],{"class":552,"line":827},[550,1527,939],{"class":672},[550,1529,942],{"class":676},[550,1531,695],{"class":672},[499,1533,1534,1535,621,1538,1541],{},"The generator reads ",[503,1536,1537],{},"ChatContract.clientToServer",[503,1539,1540],{},"ChatContract.serverToClient"," (the statics) and emits:",[1543,1544,1545,1556,1566],"ul",{},[1546,1547,1548,1549,1552,1553,1555],"li",{},"Channel ",[503,1550,1551],{},"chat"," (address ",[503,1554,1229],{},") carrying all messages from both directions.",[1546,1557,1558,1559,1120,1562,1565],{},"Operation ",[503,1560,1561],{},"chatSend",[503,1563,1564],{},"action: \"send\"",", references the client-to-server messages.",[1546,1567,1558,1568,1120,1571,1574],{},[503,1569,1570],{},"chatReceive",[503,1572,1573],{},"action: \"receive\"",", references the server-to-client messages.",[1137,1576,1578],{"id":1577},"sse-channel","SSE channel",[540,1580,1583],{"className":658,"code":1581,"filename":1582,"language":661,"meta":546,"style":546},"import { object, string } from \"valibot\";\nimport { ServerSentEvents } from \"@heximon\u002Fsse\";\n\n\u002F\u002F The structured `{ path, events }` form lets the events class own the stream's address; the flat\n\u002F\u002F `ServerSentEvents({ name: schema })` form (no declared path) still works — pass an explicit `address` then.\nexport class FeedEvents extends ServerSentEvents({\n  path: \"\u002Ffeed\",\n  events: {\n    announce: object({ body: string() }),\n    ping:     object({ at: string() }),\n  },\n}) {}\n","src\u002Ffeed\u002Ffeed.events.ts",[503,1584,1585,1609,1630,1634,1639,1644,1660,1675,1684,1712,1741,1745],{"__ignoreMap":546},[550,1586,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607],{"class":552,"line":553},[550,1588,669],{"class":668},[550,1590,673],{"class":672},[550,1592,1155],{"class":676},[550,1594,886],{"class":672},[550,1596,1160],{"class":676},[550,1598,680],{"class":672},[550,1600,683],{"class":668},[550,1602,686],{"class":672},[550,1604,1169],{"class":559},[550,1606,692],{"class":672},[550,1608,695],{"class":672},[550,1610,1611,1613,1615,1618,1620,1622,1624,1626,1628],{"class":552,"line":698},[550,1612,669],{"class":668},[550,1614,673],{"class":672},[550,1616,1617],{"class":676}," ServerSentEvents",[550,1619,680],{"class":672},[550,1621,683],{"class":668},[550,1623,686],{"class":672},[550,1625,624],{"class":559},[550,1627,692],{"class":672},[550,1629,695],{"class":672},[550,1631,1632],{"class":552,"line":721},[550,1633,748],{"emptyLinePlaceholder":747},[550,1635,1636],{"class":552,"line":744},[550,1637,1638],{"class":864},"\u002F\u002F The structured `{ path, events }` form lets the events class own the stream's address; the flat\n",[550,1640,1641],{"class":552,"line":751},[550,1642,1643],{"class":864},"\u002F\u002F `ServerSentEvents({ name: schema })` form (no declared path) still works — pass an explicit `address` then.\n",[550,1645,1646,1648,1650,1652,1654,1656,1658],{"class":552,"line":779},[550,1647,754],{"class":668},[550,1649,1206],{"class":757},[550,1651,728],{"class":556},[550,1653,1211],{"class":757},[550,1655,1617],{"class":770},[550,1657,773],{"class":676},[550,1659,776],{"class":672},[550,1661,1662,1664,1666,1668,1671,1673],{"class":552,"line":792},[550,1663,1222],{"class":782},[550,1665,786],{"class":672},[550,1667,686],{"class":672},[550,1669,1670],{"class":559},"\u002Ffeed",[550,1672,692],{"class":672},[550,1674,807],{"class":672},[550,1676,1677,1680,1682],{"class":552,"line":810},[550,1678,1679],{"class":782},"  events",[550,1681,786],{"class":672},[550,1683,789],{"class":672},[550,1685,1686,1689,1691,1693,1695,1697,1700,1702,1704,1706,1708,1710],{"class":552,"line":827},[550,1687,1688],{"class":782},"    announce",[550,1690,786],{"class":672},[550,1692,1155],{"class":770},[550,1694,773],{"class":676},[550,1696,1261],{"class":672},[550,1698,1699],{"class":782}," body",[550,1701,786],{"class":672},[550,1703,1160],{"class":770},[550,1705,1271],{"class":676},[550,1707,939],{"class":672},[550,1709,942],{"class":676},[550,1711,807],{"class":672},[550,1713,1714,1717,1719,1722,1724,1726,1729,1731,1733,1735,1737,1739],{"class":552,"line":844},[550,1715,1716],{"class":782},"    ping",[550,1718,786],{"class":672},[550,1720,1721],{"class":770},"     object",[550,1723,773],{"class":676},[550,1725,1261],{"class":672},[550,1727,1728],{"class":782}," at",[550,1730,786],{"class":672},[550,1732,1160],{"class":770},[550,1734,1271],{"class":676},[550,1736,939],{"class":672},[550,1738,942],{"class":676},[550,1740,807],{"class":672},[550,1742,1743],{"class":552,"line":850},[550,1744,847],{"class":672},[550,1746,1747,1749,1751],{"class":552,"line":861},[550,1748,939],{"class":672},[550,1750,1375],{"class":676},[550,1752,1378],{"class":672},[540,1754,1756],{"className":658,"code":1755,"filename":660,"language":661,"meta":546,"style":546},"import { AsyncApiGenerator } from \"@heximon\u002Fasyncapi\";\nimport { FeedEvents } from \"..\u002Ffeed\u002Ffeed.events\";\n\nexport const generator = new AsyncApiGenerator({\n  info: { title: \"Feed API\", version: \"2.0.0\" },\n  channels: [\n    { kind: \"sse\", events: FeedEvents }, \u002F\u002F address defaults from FeedEvents.path\n  ],\n});\n",[503,1757,1758,1778,1798,1802,1820,1854,1862,1890,1896],{"__ignoreMap":546},[550,1759,1760,1762,1764,1766,1768,1770,1772,1774,1776],{"class":552,"line":553},[550,1761,669],{"class":668},[550,1763,673],{"class":672},[550,1765,677],{"class":676},[550,1767,680],{"class":672},[550,1769,683],{"class":668},[550,1771,686],{"class":672},[550,1773,689],{"class":559},[550,1775,692],{"class":672},[550,1777,695],{"class":672},[550,1779,1780,1782,1784,1786,1788,1790,1792,1794,1796],{"class":552,"line":698},[550,1781,669],{"class":668},[550,1783,673],{"class":672},[550,1785,728],{"class":676},[550,1787,680],{"class":672},[550,1789,683],{"class":668},[550,1791,686],{"class":672},[550,1793,737],{"class":559},[550,1795,692],{"class":672},[550,1797,695],{"class":672},[550,1799,1800],{"class":552,"line":721},[550,1801,748],{"emptyLinePlaceholder":747},[550,1803,1804,1806,1808,1810,1812,1814,1816,1818],{"class":552,"line":744},[550,1805,754],{"class":668},[550,1807,758],{"class":757},[550,1809,1436],{"class":676},[550,1811,764],{"class":672},[550,1813,767],{"class":672},[550,1815,677],{"class":770},[550,1817,773],{"class":676},[550,1819,776],{"class":672},[550,1821,1822,1824,1826,1828,1830,1832,1834,1837,1839,1841,1843,1845,1847,1850,1852],{"class":552,"line":751},[550,1823,783],{"class":782},[550,1825,786],{"class":672},[550,1827,673],{"class":672},[550,1829,1457],{"class":782},[550,1831,786],{"class":672},[550,1833,686],{"class":672},[550,1835,1836],{"class":559},"Feed API",[550,1838,692],{"class":672},[550,1840,886],{"class":672},[550,1842,1470],{"class":782},[550,1844,786],{"class":672},[550,1846,686],{"class":672},[550,1848,1849],{"class":559},"2.0.0",[550,1851,692],{"class":672},[550,1853,1481],{"class":672},[550,1855,1856,1858,1860],{"class":552,"line":779},[550,1857,853],{"class":782},[550,1859,786],{"class":672},[550,1861,858],{"class":676},[550,1863,1864,1866,1868,1870,1872,1874,1876,1878,1881,1883,1885,1887],{"class":552,"line":792},[550,1865,871],{"class":672},[550,1867,874],{"class":782},[550,1869,786],{"class":672},[550,1871,686],{"class":672},[550,1873,911],{"class":559},[550,1875,692],{"class":672},[550,1877,886],{"class":672},[550,1879,1880],{"class":782}," events",[550,1882,786],{"class":672},[550,1884,923],{"class":676},[550,1886,1514],{"class":672},[550,1888,1889],{"class":864}," \u002F\u002F address defaults from FeedEvents.path\n",[550,1891,1892,1894],{"class":552,"line":810},[550,1893,931],{"class":676},[550,1895,807],{"class":672},[550,1897,1898,1900,1902],{"class":552,"line":827},[550,1899,939],{"class":672},[550,1901,942],{"class":676},[550,1903,695],{"class":672},[499,1905,1534,1906,1909],{},[503,1907,1908],{},"FeedEvents.events"," (the static map) and emits:",[1543,1911,1912,1920],{},[1546,1913,1548,1914,1552,1917,1919],{},[503,1915,1916],{},"feed",[503,1918,1670],{},") carrying one message per event name.",[1546,1921,1558,1922,1120,1925,1927],{},[503,1923,1924],{},"feedReceive",[503,1926,1573],{}," (SSE emits no send operation).",[532,1929,1931],{"id":1930},"the-wire-envelope","The wire envelope",[499,1933,1934,1935,1938,1939,1942,1943,1945,1946,1949,1950,1953],{},"Every frame over a Heximon WebSocket or SSE channel carries the typed envelope\n",[503,1936,1937],{},"{\"v\":1,\"kind\":\"\u003Cname>\",\"data\":\u003Cpayload>}",". The generator documents this at the message level — each\nAsyncAPI ",[503,1940,1941],{},"message.name"," is the ",[503,1944,1009],{}," discriminator, and ",[503,1947,1948],{},"message.payload"," is the JSON Schema for the ",[503,1951,1952],{},"data","\nfield. The channel address and channel-level notes record the envelope structure so a consumer knows how to\ndecode each frame without consulting out-of-band documentation.",[532,1955,1957],{"id":1956},"channel-name-sanitization","Channel name sanitization",[499,1959,1960,1961,1963,1964,1966,1967,1058,1969,1972,1973,1976],{},"The generator derives each channel's key (used in ",[503,1962,642],{}," and as the operation-name prefix) from the\n",[503,1965,950],{}," by removing the leading slash, splitting on ",[503,1968,959],{},[503,1970,1971],{},"-",", and ",[503,1974,1975],{},"_",", and joining as camelCase:",[1023,1978,1979,1989],{},[1026,1980,1981],{},[1029,1982,1983,1986],{},[1032,1984,1985],{"align":1034},"Address",[1032,1987,1988],{"align":1034},"Channel key",[1044,1990,1991,2001,2011,2023],{},[1029,1992,1993,1997],{},[1049,1994,1995],{"align":1034},[503,1996,1229],{},[1049,1998,1999],{"align":1034},[503,2000,1551],{},[1029,2002,2003,2007],{},[1049,2004,2005],{"align":1034},[503,2006,1670],{},[1049,2008,2009],{"align":1034},[503,2010,1916],{},[1029,2012,2013,2018],{},[1049,2014,2015],{"align":1034},[503,2016,2017],{},"\u002Fapi\u002Fevents",[1049,2019,2020],{"align":1034},[503,2021,2022],{},"apiEvents",[1029,2024,2025,2030],{},[1049,2026,2027],{"align":1034},[503,2028,2029],{},"\u002Flive-feed",[1049,2031,2032],{"align":1034},[503,2033,2034],{},"liveFeed",[499,2036,2037,2038,2040,2041,621,2043,2045,2046,2040,2048,2050],{},"Operations follow: a WebSocket channel at ",[503,2039,1229],{}," produces ",[503,2042,1561],{},[503,2044,1570],{},"; an SSE channel at\n",[503,2047,1670],{},[503,2049,1924],{},".",[532,2052,2054],{"id":2053},"serve-the-document","Serve the document",[499,2056,2057],{},"The document is a plain serializable object, so a standard inline controller serves it:",[540,2059,2062],{"className":658,"code":2060,"filename":2061,"language":661,"meta":546,"style":546},"import type { Controller, Get } from \"@heximon\u002Fhttp\";\nimport { asyncApiGenerator } from \".\u002Fasyncapi\";\n\nexport class AsyncApiDocsController implements Controller {\n  \u002F\u002F GET \u002Fasyncapi.json — the AsyncAPI 3.1 document (built once, then memoized)\n  public async document(action: Get\u003C\"\u002Fasyncapi.json\">) {\n    return asyncApiGenerator.generate();\n  }\n}\n","src\u002Fdocs\u002Fdocs.controller.ts",[503,2063,2064,2094,2116,2120,2136,2141,2177,2193,2198],{"__ignoreMap":546},[550,2065,2066,2068,2071,2073,2076,2078,2081,2083,2085,2087,2090,2092],{"class":552,"line":553},[550,2067,669],{"class":668},[550,2069,2070],{"class":668}," type",[550,2072,673],{"class":672},[550,2074,2075],{"class":676}," Controller",[550,2077,886],{"class":672},[550,2079,2080],{"class":676}," Get",[550,2082,680],{"class":672},[550,2084,683],{"class":668},[550,2086,686],{"class":672},[550,2088,2089],{"class":559},"@heximon\u002Fhttp",[550,2091,692],{"class":672},[550,2093,695],{"class":672},[550,2095,2096,2098,2100,2103,2105,2107,2109,2112,2114],{"class":552,"line":698},[550,2097,669],{"class":668},[550,2099,673],{"class":672},[550,2101,2102],{"class":676}," asyncApiGenerator",[550,2104,680],{"class":672},[550,2106,683],{"class":668},[550,2108,686],{"class":672},[550,2110,2111],{"class":559},".\u002Fasyncapi",[550,2113,692],{"class":672},[550,2115,695],{"class":672},[550,2117,2118],{"class":552,"line":721},[550,2119,748],{"emptyLinePlaceholder":747},[550,2121,2122,2124,2126,2129,2132,2134],{"class":552,"line":744},[550,2123,754],{"class":668},[550,2125,1206],{"class":757},[550,2127,2128],{"class":556}," AsyncApiDocsController",[550,2130,2131],{"class":757}," implements",[550,2133,2075],{"class":556},[550,2135,789],{"class":672},[550,2137,2138],{"class":552,"line":751},[550,2139,2140],{"class":864},"  \u002F\u002F GET \u002Fasyncapi.json — the AsyncAPI 3.1 document (built once, then memoized)\n",[550,2142,2143,2146,2149,2152,2154,2158,2160,2162,2165,2167,2170,2172,2175],{"class":552,"line":779},[550,2144,2145],{"class":757},"  public",[550,2147,2148],{"class":757}," async",[550,2150,2151],{"class":782}," document",[550,2153,773],{"class":672},[550,2155,2157],{"class":2156},"sHdIc","action",[550,2159,786],{"class":672},[550,2161,2080],{"class":556},[550,2163,2164],{"class":672},"\u003C",[550,2166,692],{"class":672},[550,2168,2169],{"class":559},"\u002Fasyncapi.json",[550,2171,692],{"class":672},[550,2173,2174],{"class":672},">)",[550,2176,789],{"class":672},[550,2178,2179,2182,2184,2186,2189,2191],{"class":552,"line":792},[550,2180,2181],{"class":668},"    return",[550,2183,2102],{"class":676},[550,2185,2050],{"class":672},[550,2187,2188],{"class":770},"generate",[550,2190,1348],{"class":782},[550,2192,695],{"class":672},[550,2194,2195],{"class":552,"line":810},[550,2196,2197],{"class":672},"  }\n",[550,2199,2200],{"class":552,"line":827},[550,2201,2202],{"class":672},"}\n",[499,2204,2205],{},"The owning module declares only the controller — the generator is a module-level value, not a DI provider:",[540,2207,2210],{"className":658,"code":2208,"filename":2209,"language":661,"meta":546,"style":546},"import { Module } from \"@heximon\u002Fruntime\";\nimport { AsyncApiDocsController } from \".\u002Fdocs.controller\";\n\nexport class DocsModule extends Module({\n  http: { controllers: [AsyncApiDocsController] },\n}) {}\n","src\u002Fdocs\u002Fdocs.module.ts",[503,2211,2212,2234,2255,2259,2276,2295],{"__ignoreMap":546},[550,2213,2214,2216,2218,2221,2223,2225,2227,2230,2232],{"class":552,"line":553},[550,2215,669],{"class":668},[550,2217,673],{"class":672},[550,2219,2220],{"class":676}," Module",[550,2222,680],{"class":672},[550,2224,683],{"class":668},[550,2226,686],{"class":672},[550,2228,2229],{"class":559},"@heximon\u002Fruntime",[550,2231,692],{"class":672},[550,2233,695],{"class":672},[550,2235,2236,2238,2240,2242,2244,2246,2248,2251,2253],{"class":552,"line":698},[550,2237,669],{"class":668},[550,2239,673],{"class":672},[550,2241,2128],{"class":676},[550,2243,680],{"class":672},[550,2245,683],{"class":668},[550,2247,686],{"class":672},[550,2249,2250],{"class":559},".\u002Fdocs.controller",[550,2252,692],{"class":672},[550,2254,695],{"class":672},[550,2256,2257],{"class":552,"line":721},[550,2258,748],{"emptyLinePlaceholder":747},[550,2260,2261,2263,2265,2268,2270,2272,2274],{"class":552,"line":744},[550,2262,754],{"class":668},[550,2264,1206],{"class":757},[550,2266,2267],{"class":556}," DocsModule",[550,2269,1211],{"class":757},[550,2271,2220],{"class":770},[550,2273,773],{"class":676},[550,2275,776],{"class":672},[550,2277,2278,2281,2283,2285,2288,2290,2293],{"class":552,"line":751},[550,2279,2280],{"class":782},"  http",[550,2282,786],{"class":672},[550,2284,673],{"class":672},[550,2286,2287],{"class":782}," controllers",[550,2289,786],{"class":672},[550,2291,2292],{"class":676}," [AsyncApiDocsController] ",[550,2294,897],{"class":672},[550,2296,2297,2299,2301],{"class":552,"line":779},[550,2298,939],{"class":672},[550,2300,1375],{"class":676},[550,2302,1378],{"class":672},[532,2304,2306],{"id":2305},"document-shape","Document shape",[499,2308,2309,2310,2312,2313,2316],{},"A mixed WS + SSE app produces a document with this structure. The ",[503,2311,642],{}," map holds all address + message\ndeclarations; the ",[503,2314,2315],{},"operations"," map holds the intent (send vs. receive) pointing back at channel refs:",[540,2318,2322],{"className":2319,"code":2320,"language":2321,"meta":546,"style":546},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"asyncapi\": \"3.1.0\",\n  \"info\": { \"title\": \"Chat API\", \"version\": \"1.0.0\" },\n  \"channels\": {\n    \"chat\": {\n      \"address\": \"\u002Fchat\",\n      \"messages\": {\n        \"chatC2SChat.message\": { \"name\": \"chat.message\", \"payload\": { \"type\": \"object\" } },\n        \"chatS2CChat.joined\":  { \"name\": \"chat.joined\",  \"payload\": { \"type\": \"object\" } },\n        \"chatS2CChat.message\": { \"name\": \"chat.message\", \"payload\": { \"type\": \"object\" } }\n      }\n    },\n    \"feed\": {\n      \"address\": \"\u002Ffeed\",\n      \"messages\": {\n        \"feedAnnounce\": { \"name\": \"announce\", \"payload\": { \"type\": \"object\" } },\n        \"feedPing\":     { \"name\": \"ping\",     \"payload\": { \"type\": \"object\" } }\n      }\n    }\n  },\n  \"operations\": {\n    \"chatSend\":    { \"action\": \"send\",    \"channel\": { \"$ref\": \"#\u002Fchannels\u002Fchat\" }, \"messages\": [\"...\"] },\n    \"chatReceive\": { \"action\": \"receive\", \"channel\": { \"$ref\": \"#\u002Fchannels\u002Fchat\" }, \"messages\": [\"...\"] },\n    \"feedReceive\": { \"action\": \"receive\", \"channel\": { \"$ref\": \"#\u002Fchannels\u002Ffeed\" }, \"messages\": [\"...\"] }\n  }\n}\n","json",[503,2323,2324,2328,2349,2395,2407,2419,2439,2452,2515,2573,2631,2636,2641,2653,2671,2683,2741,2802,2807,2813,2818,2831,2914,2990,3066,3071],{"__ignoreMap":546},[550,2325,2326],{"class":552,"line":553},[550,2327,776],{"class":672},[550,2329,2330,2333,2336,2338,2340,2342,2345,2347],{"class":552,"line":698},[550,2331,2332],{"class":672},"  \"",[550,2334,2335],{"class":757},"asyncapi",[550,2337,692],{"class":672},[550,2339,786],{"class":672},[550,2341,686],{"class":672},[550,2343,2344],{"class":559},"3.1.0",[550,2346,692],{"class":672},[550,2348,807],{"class":672},[550,2350,2351,2353,2355,2357,2359,2361,2363,2366,2368,2370,2372,2374,2376,2378,2380,2383,2385,2387,2389,2391,2393],{"class":552,"line":721},[550,2352,2332],{"class":672},[550,2354,638],{"class":757},[550,2356,692],{"class":672},[550,2358,786],{"class":672},[550,2360,673],{"class":672},[550,2362,686],{"class":672},[550,2364,2365],{"class":556},"title",[550,2367,692],{"class":672},[550,2369,786],{"class":672},[550,2371,686],{"class":672},[550,2373,802],{"class":559},[550,2375,692],{"class":672},[550,2377,886],{"class":672},[550,2379,686],{"class":672},[550,2381,2382],{"class":556},"version",[550,2384,692],{"class":672},[550,2386,786],{"class":672},[550,2388,686],{"class":672},[550,2390,820],{"class":559},[550,2392,692],{"class":672},[550,2394,1481],{"class":672},[550,2396,2397,2399,2401,2403,2405],{"class":552,"line":744},[550,2398,2332],{"class":672},[550,2400,642],{"class":757},[550,2402,692],{"class":672},[550,2404,786],{"class":672},[550,2406,789],{"class":672},[550,2408,2409,2411,2413,2415,2417],{"class":552,"line":751},[550,2410,1247],{"class":672},[550,2412,1551],{"class":556},[550,2414,692],{"class":672},[550,2416,786],{"class":672},[550,2418,789],{"class":672},[550,2420,2421,2424,2427,2429,2431,2433,2435,2437],{"class":552,"line":779},[550,2422,2423],{"class":672},"      \"",[550,2425,950],{"class":2426},"sbssI",[550,2428,692],{"class":672},[550,2430,786],{"class":672},[550,2432,686],{"class":672},[550,2434,1229],{"class":559},[550,2436,692],{"class":672},[550,2438,807],{"class":672},[550,2440,2441,2443,2446,2448,2450],{"class":552,"line":792},[550,2442,2423],{"class":672},[550,2444,2445],{"class":2426},"messages",[550,2447,692],{"class":672},[550,2449,786],{"class":672},[550,2451,789],{"class":672},[550,2453,2454,2457,2460,2462,2464,2466,2468,2472,2474,2476,2478,2480,2482,2484,2486,2489,2491,2493,2495,2497,2500,2502,2504,2506,2509,2511,2513],{"class":552,"line":810},[550,2455,2456],{"class":672},"        \"",[550,2458,2459],{"class":782},"chatC2SChat.message",[550,2461,692],{"class":672},[550,2463,786],{"class":672},[550,2465,673],{"class":672},[550,2467,686],{"class":672},[550,2469,2471],{"class":2470},"su27w","name",[550,2473,692],{"class":672},[550,2475,786],{"class":672},[550,2477,686],{"class":672},[550,2479,1250],{"class":559},[550,2481,692],{"class":672},[550,2483,886],{"class":672},[550,2485,686],{"class":672},[550,2487,2488],{"class":2470},"payload",[550,2490,692],{"class":672},[550,2492,786],{"class":672},[550,2494,673],{"class":672},[550,2496,686],{"class":672},[550,2498,2499],{"class":770},"type",[550,2501,692],{"class":672},[550,2503,786],{"class":672},[550,2505,686],{"class":672},[550,2507,2508],{"class":559},"object",[550,2510,692],{"class":672},[550,2512,680],{"class":672},[550,2514,1481],{"class":672},[550,2516,2517,2519,2522,2524,2526,2529,2531,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551,2553,2555,2557,2559,2561,2563,2565,2567,2569,2571],{"class":552,"line":827},[550,2518,2456],{"class":672},[550,2520,2521],{"class":782},"chatS2CChat.joined",[550,2523,692],{"class":672},[550,2525,786],{"class":672},[550,2527,2528],{"class":672},"  {",[550,2530,686],{"class":672},[550,2532,2471],{"class":2470},[550,2534,692],{"class":672},[550,2536,786],{"class":672},[550,2538,686],{"class":672},[550,2540,1297],{"class":559},[550,2542,692],{"class":672},[550,2544,886],{"class":672},[550,2546,2332],{"class":672},[550,2548,2488],{"class":2470},[550,2550,692],{"class":672},[550,2552,786],{"class":672},[550,2554,673],{"class":672},[550,2556,686],{"class":672},[550,2558,2499],{"class":770},[550,2560,692],{"class":672},[550,2562,786],{"class":672},[550,2564,686],{"class":672},[550,2566,2508],{"class":559},[550,2568,692],{"class":672},[550,2570,680],{"class":672},[550,2572,1481],{"class":672},[550,2574,2575,2577,2580,2582,2584,2586,2588,2590,2592,2594,2596,2598,2600,2602,2604,2606,2608,2610,2612,2614,2616,2618,2620,2622,2624,2626,2628],{"class":552,"line":844},[550,2576,2456],{"class":672},[550,2578,2579],{"class":782},"chatS2CChat.message",[550,2581,692],{"class":672},[550,2583,786],{"class":672},[550,2585,673],{"class":672},[550,2587,686],{"class":672},[550,2589,2471],{"class":2470},[550,2591,692],{"class":672},[550,2593,786],{"class":672},[550,2595,686],{"class":672},[550,2597,1250],{"class":559},[550,2599,692],{"class":672},[550,2601,886],{"class":672},[550,2603,686],{"class":672},[550,2605,2488],{"class":2470},[550,2607,692],{"class":672},[550,2609,786],{"class":672},[550,2611,673],{"class":672},[550,2613,686],{"class":672},[550,2615,2499],{"class":770},[550,2617,692],{"class":672},[550,2619,786],{"class":672},[550,2621,686],{"class":672},[550,2623,2508],{"class":559},[550,2625,692],{"class":672},[550,2627,680],{"class":672},[550,2629,2630],{"class":672}," }\n",[550,2632,2633],{"class":552,"line":850},[550,2634,2635],{"class":672},"      }\n",[550,2637,2638],{"class":552,"line":861},[550,2639,2640],{"class":672},"    },\n",[550,2642,2643,2645,2647,2649,2651],{"class":552,"line":868},[550,2644,1247],{"class":672},[550,2646,1916],{"class":556},[550,2648,692],{"class":672},[550,2650,786],{"class":672},[550,2652,789],{"class":672},[550,2654,2655,2657,2659,2661,2663,2665,2667,2669],{"class":552,"line":900},[550,2656,2423],{"class":672},[550,2658,950],{"class":2426},[550,2660,692],{"class":672},[550,2662,786],{"class":672},[550,2664,686],{"class":672},[550,2666,1670],{"class":559},[550,2668,692],{"class":672},[550,2670,807],{"class":672},[550,2672,2673,2675,2677,2679,2681],{"class":552,"line":928},[550,2674,2423],{"class":672},[550,2676,2445],{"class":2426},[550,2678,692],{"class":672},[550,2680,786],{"class":672},[550,2682,789],{"class":672},[550,2684,2685,2687,2690,2692,2694,2696,2698,2700,2702,2704,2706,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729,2731,2733,2735,2737,2739],{"class":552,"line":936},[550,2686,2456],{"class":672},[550,2688,2689],{"class":782},"feedAnnounce",[550,2691,692],{"class":672},[550,2693,786],{"class":672},[550,2695,673],{"class":672},[550,2697,686],{"class":672},[550,2699,2471],{"class":2470},[550,2701,692],{"class":672},[550,2703,786],{"class":672},[550,2705,686],{"class":672},[550,2707,2708],{"class":559},"announce",[550,2710,692],{"class":672},[550,2712,886],{"class":672},[550,2714,686],{"class":672},[550,2716,2488],{"class":2470},[550,2718,692],{"class":672},[550,2720,786],{"class":672},[550,2722,673],{"class":672},[550,2724,686],{"class":672},[550,2726,2499],{"class":770},[550,2728,692],{"class":672},[550,2730,786],{"class":672},[550,2732,686],{"class":672},[550,2734,2508],{"class":559},[550,2736,692],{"class":672},[550,2738,680],{"class":672},[550,2740,1481],{"class":672},[550,2742,2744,2746,2749,2751,2753,2756,2758,2760,2762,2764,2766,2769,2771,2773,2776,2778,2780,2782,2784,2786,2788,2790,2792,2794,2796,2798,2800],{"class":552,"line":2743},17,[550,2745,2456],{"class":672},[550,2747,2748],{"class":782},"feedPing",[550,2750,692],{"class":672},[550,2752,786],{"class":672},[550,2754,2755],{"class":672},"     {",[550,2757,686],{"class":672},[550,2759,2471],{"class":2470},[550,2761,692],{"class":672},[550,2763,786],{"class":672},[550,2765,686],{"class":672},[550,2767,2768],{"class":559},"ping",[550,2770,692],{"class":672},[550,2772,886],{"class":672},[550,2774,2775],{"class":672},"     \"",[550,2777,2488],{"class":2470},[550,2779,692],{"class":672},[550,2781,786],{"class":672},[550,2783,673],{"class":672},[550,2785,686],{"class":672},[550,2787,2499],{"class":770},[550,2789,692],{"class":672},[550,2791,786],{"class":672},[550,2793,686],{"class":672},[550,2795,2508],{"class":559},[550,2797,692],{"class":672},[550,2799,680],{"class":672},[550,2801,2630],{"class":672},[550,2803,2805],{"class":552,"line":2804},18,[550,2806,2635],{"class":672},[550,2808,2810],{"class":552,"line":2809},19,[550,2811,2812],{"class":672},"    }\n",[550,2814,2816],{"class":552,"line":2815},20,[550,2817,847],{"class":672},[550,2819,2821,2823,2825,2827,2829],{"class":552,"line":2820},21,[550,2822,2332],{"class":672},[550,2824,2315],{"class":757},[550,2826,692],{"class":672},[550,2828,786],{"class":672},[550,2830,789],{"class":672},[550,2832,2834,2836,2838,2840,2842,2844,2846,2848,2850,2852,2854,2857,2859,2861,2863,2866,2868,2870,2872,2874,2877,2879,2881,2883,2886,2888,2891,2893,2895,2897,2899,2902,2904,2907,2909,2912],{"class":552,"line":2833},22,[550,2835,1247],{"class":672},[550,2837,1561],{"class":556},[550,2839,692],{"class":672},[550,2841,786],{"class":672},[550,2843,871],{"class":672},[550,2845,686],{"class":672},[550,2847,2157],{"class":2426},[550,2849,692],{"class":672},[550,2851,786],{"class":672},[550,2853,686],{"class":672},[550,2855,2856],{"class":559},"send",[550,2858,692],{"class":672},[550,2860,886],{"class":672},[550,2862,1247],{"class":672},[550,2864,2865],{"class":2426},"channel",[550,2867,692],{"class":672},[550,2869,786],{"class":672},[550,2871,673],{"class":672},[550,2873,686],{"class":672},[550,2875,2876],{"class":782},"$ref",[550,2878,692],{"class":672},[550,2880,786],{"class":672},[550,2882,686],{"class":672},[550,2884,2885],{"class":559},"#\u002Fchannels\u002Fchat",[550,2887,692],{"class":672},[550,2889,2890],{"class":672}," },",[550,2892,686],{"class":672},[550,2894,2445],{"class":2426},[550,2896,692],{"class":672},[550,2898,786],{"class":672},[550,2900,2901],{"class":672}," [",[550,2903,692],{"class":672},[550,2905,2906],{"class":559},"...",[550,2908,692],{"class":672},[550,2910,2911],{"class":672},"]",[550,2913,1481],{"class":672},[550,2915,2917,2919,2921,2923,2925,2927,2929,2931,2933,2935,2937,2940,2942,2944,2946,2948,2950,2952,2954,2956,2958,2960,2962,2964,2966,2968,2970,2972,2974,2976,2978,2980,2982,2984,2986,2988],{"class":552,"line":2916},23,[550,2918,1247],{"class":672},[550,2920,1570],{"class":556},[550,2922,692],{"class":672},[550,2924,786],{"class":672},[550,2926,673],{"class":672},[550,2928,686],{"class":672},[550,2930,2157],{"class":2426},[550,2932,692],{"class":672},[550,2934,786],{"class":672},[550,2936,686],{"class":672},[550,2938,2939],{"class":559},"receive",[550,2941,692],{"class":672},[550,2943,886],{"class":672},[550,2945,686],{"class":672},[550,2947,2865],{"class":2426},[550,2949,692],{"class":672},[550,2951,786],{"class":672},[550,2953,673],{"class":672},[550,2955,686],{"class":672},[550,2957,2876],{"class":782},[550,2959,692],{"class":672},[550,2961,786],{"class":672},[550,2963,686],{"class":672},[550,2965,2885],{"class":559},[550,2967,692],{"class":672},[550,2969,2890],{"class":672},[550,2971,686],{"class":672},[550,2973,2445],{"class":2426},[550,2975,692],{"class":672},[550,2977,786],{"class":672},[550,2979,2901],{"class":672},[550,2981,692],{"class":672},[550,2983,2906],{"class":559},[550,2985,692],{"class":672},[550,2987,2911],{"class":672},[550,2989,1481],{"class":672},[550,2991,2993,2995,2997,2999,3001,3003,3005,3007,3009,3011,3013,3015,3017,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3042,3044,3046,3048,3050,3052,3054,3056,3058,3060,3062,3064],{"class":552,"line":2992},24,[550,2994,1247],{"class":672},[550,2996,1924],{"class":556},[550,2998,692],{"class":672},[550,3000,786],{"class":672},[550,3002,673],{"class":672},[550,3004,686],{"class":672},[550,3006,2157],{"class":2426},[550,3008,692],{"class":672},[550,3010,786],{"class":672},[550,3012,686],{"class":672},[550,3014,2939],{"class":559},[550,3016,692],{"class":672},[550,3018,886],{"class":672},[550,3020,686],{"class":672},[550,3022,2865],{"class":2426},[550,3024,692],{"class":672},[550,3026,786],{"class":672},[550,3028,673],{"class":672},[550,3030,686],{"class":672},[550,3032,2876],{"class":782},[550,3034,692],{"class":672},[550,3036,786],{"class":672},[550,3038,686],{"class":672},[550,3040,3041],{"class":559},"#\u002Fchannels\u002Ffeed",[550,3043,692],{"class":672},[550,3045,2890],{"class":672},[550,3047,686],{"class":672},[550,3049,2445],{"class":2426},[550,3051,692],{"class":672},[550,3053,786],{"class":672},[550,3055,2901],{"class":672},[550,3057,692],{"class":672},[550,3059,2906],{"class":559},[550,3061,692],{"class":672},[550,3063,2911],{"class":672},[550,3065,2630],{"class":672},[550,3067,3069],{"class":552,"line":3068},25,[550,3070,2197],{"class":672},[550,3072,3074],{"class":552,"line":3073},26,[550,3075,2202],{"class":672},[499,3077,3078,3079,3081],{},"AsyncAPI 3.1 separates channels (the address, where messages flow) from operations (the intent: who sends what).\nThat's why there is no ",[503,3080,2315],{}," key inside a channel — channels describe the wire; operations describe the\napplication's behavior.",[499,3083,3084,3085,3087,3088,3090,3091,3093,3094,3097],{},"Message keys are assembled by uppercasing only the first character of the ",[503,3086,1009],{}," — a dotted kind like\n",[503,3089,1250],{}," keeps its dot (",[503,3092,2459],{},"), it isn't converted to camelCase. Keep kinds dot-free\n(",[503,3095,3096],{},"chatMessage",") if you want camelCase message keys.",[532,3099,3101],{"id":3100},"graceful-schema-degradation","Graceful schema degradation",[499,3103,3104,3105,3108,3109,3112,3113,3116,3117,786],{},"A schema that carries no ",[503,3106,3107],{},"~standard.jsonSchema"," converter degrades to an empty ",[503,3110,3111],{},"payload: {}"," rather than\nfailing the whole document — the channel and its operations are still emitted. For raw valibot schemas (which\ndo not carry the Standard Schema JSON Schema extension by default), supply a custom converter that chains\n",[503,3114,3115],{},"valibotJsonSchema"," from ",[503,3118,3119],{},"@heximon\u002Fschema\u002Fvalibot",[540,3121,3123],{"className":658,"code":3122,"filename":660,"language":661,"meta":546,"style":546},"import { valibotJsonSchema } from \"@heximon\u002Fschema\u002Fvalibot\";\nimport { AsyncApiGenerator, StandardSchemaConverter } from \"@heximon\u002Fasyncapi\";\nimport { ChatContract } from \"..\u002Fchat\u002Fchat.contract\";\n\nexport const generator = new AsyncApiGenerator({\n  info: { title: \"Chat API\", version: \"1.0.0\" },\n  channels: [\n    { kind: \"websocket\", contract: ChatContract },\n  ],\n  converter: (schema, direction) =>\n    valibotJsonSchema(schema, direction) ?? StandardSchemaConverter.convert(schema, direction),\n});\n",[503,3124,3125,3146,3171,3191,3195,3213,3245,3253,3277,3283,3306,3338],{"__ignoreMap":546},[550,3126,3127,3129,3131,3134,3136,3138,3140,3142,3144],{"class":552,"line":553},[550,3128,669],{"class":668},[550,3130,673],{"class":672},[550,3132,3133],{"class":676}," valibotJsonSchema",[550,3135,680],{"class":672},[550,3137,683],{"class":668},[550,3139,686],{"class":672},[550,3141,3119],{"class":559},[550,3143,692],{"class":672},[550,3145,695],{"class":672},[550,3147,3148,3150,3152,3154,3156,3159,3161,3163,3165,3167,3169],{"class":552,"line":698},[550,3149,669],{"class":668},[550,3151,673],{"class":672},[550,3153,677],{"class":676},[550,3155,886],{"class":672},[550,3157,3158],{"class":676}," StandardSchemaConverter",[550,3160,680],{"class":672},[550,3162,683],{"class":668},[550,3164,686],{"class":672},[550,3166,689],{"class":559},[550,3168,692],{"class":672},[550,3170,695],{"class":672},[550,3172,3173,3175,3177,3179,3181,3183,3185,3187,3189],{"class":552,"line":721},[550,3174,669],{"class":668},[550,3176,673],{"class":672},[550,3178,705],{"class":676},[550,3180,680],{"class":672},[550,3182,683],{"class":668},[550,3184,686],{"class":672},[550,3186,714],{"class":559},[550,3188,692],{"class":672},[550,3190,695],{"class":672},[550,3192,3193],{"class":552,"line":744},[550,3194,748],{"emptyLinePlaceholder":747},[550,3196,3197,3199,3201,3203,3205,3207,3209,3211],{"class":552,"line":751},[550,3198,754],{"class":668},[550,3200,758],{"class":757},[550,3202,1436],{"class":676},[550,3204,764],{"class":672},[550,3206,767],{"class":672},[550,3208,677],{"class":770},[550,3210,773],{"class":676},[550,3212,776],{"class":672},[550,3214,3215,3217,3219,3221,3223,3225,3227,3229,3231,3233,3235,3237,3239,3241,3243],{"class":552,"line":779},[550,3216,783],{"class":782},[550,3218,786],{"class":672},[550,3220,673],{"class":672},[550,3222,1457],{"class":782},[550,3224,786],{"class":672},[550,3226,686],{"class":672},[550,3228,802],{"class":559},[550,3230,692],{"class":672},[550,3232,886],{"class":672},[550,3234,1470],{"class":782},[550,3236,786],{"class":672},[550,3238,686],{"class":672},[550,3240,820],{"class":559},[550,3242,692],{"class":672},[550,3244,1481],{"class":672},[550,3246,3247,3249,3251],{"class":552,"line":792},[550,3248,853],{"class":782},[550,3250,786],{"class":672},[550,3252,858],{"class":676},[550,3254,3255,3257,3259,3261,3263,3265,3267,3269,3271,3273,3275],{"class":552,"line":810},[550,3256,871],{"class":672},[550,3258,874],{"class":782},[550,3260,786],{"class":672},[550,3262,686],{"class":672},[550,3264,881],{"class":559},[550,3266,692],{"class":672},[550,3268,886],{"class":672},[550,3270,889],{"class":782},[550,3272,786],{"class":672},[550,3274,894],{"class":676},[550,3276,897],{"class":672},[550,3278,3279,3281],{"class":552,"line":827},[550,3280,931],{"class":676},[550,3282,807],{"class":672},[550,3284,3285,3288,3290,3293,3296,3298,3301,3303],{"class":552,"line":844},[550,3286,3287],{"class":770},"  converter",[550,3289,786],{"class":672},[550,3291,3292],{"class":672}," (",[550,3294,3295],{"class":2156},"schema",[550,3297,886],{"class":672},[550,3299,3300],{"class":2156}," direction",[550,3302,942],{"class":672},[550,3304,3305],{"class":757}," =>\n",[550,3307,3308,3311,3314,3316,3319,3322,3324,3326,3329,3331,3333,3336],{"class":552,"line":850},[550,3309,3310],{"class":770},"    valibotJsonSchema",[550,3312,3313],{"class":676},"(schema",[550,3315,886],{"class":672},[550,3317,3318],{"class":676}," direction) ",[550,3320,3321],{"class":672},"??",[550,3323,3158],{"class":676},[550,3325,2050],{"class":672},[550,3327,3328],{"class":770},"convert",[550,3330,3313],{"class":676},[550,3332,886],{"class":672},[550,3334,3335],{"class":676}," direction)",[550,3337,807],{"class":672},[550,3339,3340,3342,3344],{"class":552,"line":861},[550,3341,939],{"class":672},[550,3343,942],{"class":676},[550,3345,695],{"class":672},[499,3347,3348,3350,3351,3354,3355,3358,3359,3362],{},[503,3349,3115],{}," guards on ",[503,3352,3353],{},"~standard.vendor === \"valibot\""," and returns ",[503,3356,3357],{},"undefined"," on any failure, so\nthe fallback to ",[503,3360,3361],{},"{}"," is preserved for schemas that cannot be represented in JSON Schema.",[532,3364,3366],{"id":3365},"see-also","See also",[1543,3368,3369,3378,3394,3408,3417],{},[1546,3370,3371,3373,3374,3377],{},[512,3372,267],{"href":268}," — the plain ",[503,3375,3376],{},"WebSocketHandler"," a WS channel descriptor can point at.",[1546,3379,3380,3382,3383,3385,3386,3389,3390,3393],{},[512,3381,271],{"href":272}," — the ",[503,3384,505],{}," class the WS channel\ndescriptor points at; the ",[503,3387,3388],{},"clientToServer"," \u002F ",[503,3391,3392],{},"serverToClient"," schema maps the generator reads.",[1546,3395,3396,3382,3398,3401,3402,3404,3405,3407],{},[512,3397,275],{"href":276},[503,3399,3400],{},"ServerSentEventsHandler"," and\n",[503,3403,509],{}," class the SSE channel descriptor points at; the ",[503,3406,962],{}," map the generator reads.",[1546,3409,3410,3412,3413,3416],{},[512,3411,199],{"href":200}," — the REST counterpart: generate an OpenAPI 3.1 document from a ",[503,3414,3415],{},"Contract","'s\nroute table, serve Scalar or Swagger UI.",[1546,3418,3419,3426,3427,3429,3430,3432,3433,3435],{},[512,3420,3423],{"href":3421,"rel":3422},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fflagship\u002Fapps\u002Fcloudflare",[516],[523,3424,3425],{},"The flagship Cloudflare app"," — a\n",[503,3428,505],{},"-backed seat-map channel and a ",[503,3431,509],{},"-backed feed channel, both documented in\none ",[503,3434,529],{},", served from a plain controller as an AsyncAPI 3.1 document.",[3437,3438,3439],"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 .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 .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 .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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .su27w, html code.shiki .su27w{--shiki-light:#916B53;--shiki-default:#916B53;--shiki-dark:#916B53}",{"title":546,"searchDepth":698,"depth":698,"links":3441},[3442,3443,3444,3448,3449,3450,3451,3452,3453],{"id":534,"depth":698,"text":535},{"id":628,"depth":698,"text":629},{"id":999,"depth":698,"text":1000,"children":3445},[3446,3447],{"id":1139,"depth":721,"text":1140},{"id":1577,"depth":721,"text":1578},{"id":1930,"depth":698,"text":1931},{"id":1956,"depth":698,"text":1957},{"id":2053,"depth":698,"text":2054},{"id":2305,"depth":698,"text":2306},{"id":3100,"depth":698,"text":3101},{"id":3365,"depth":698,"text":3366},"Generate an AsyncAPI 3.1 document from your WebSocket contracts and SSE event maps at runtime with AsyncApiGenerator, serving bidirectional WS send\u002Freceive operations and SSE receive-only operations, with the wire envelope documented at the message level.","md",null,{},{"icon":259},{"title":285,"description":3454},"I1e7nSyi-mxxtKcFZ3odtJe3qxcHAzFztfqknv5ULgw",[3462,3464],{"title":280,"path":281,"stem":282,"description":3463,"icon":283,"children":-1},"Browser and edge-safe clients for realtime transports — WsClient over a WebSocketContract and SseClient over a ServerSentEvents class, with WsTransport\u002FSseTransport native\u002Ffetch\u002FeventSource\u002Fmock modes, reconnect policies, and typed validation errors.",{"title":289,"path":290,"stem":291,"description":3465,"icon":80,"children":-1},"Author a single-threaded stateful actor at the edge with DurableObject and a DI-injected DurableFactory, address it by name, and reach storage through DurableContext.",1783300761903]