[{"data":1,"prerenderedAt":3821},["ShallowReactive",2],{"navigation_docs":3,"-docs-realtime-typed-clients":493,"-docs-realtime-typed-clients-surround":3816},[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":280,"body":495,"description":3809,"extension":3810,"links":3811,"meta":3812,"navigation":3813,"path":281,"seo":3814,"stem":282,"__hash__":3815},"docs\u002Fdocs\u002F05.realtime\u002F05.typed-clients.md",{"type":496,"value":497,"toc":3788},"minimark",[498,511,537,560,668,676,681,702,1104,1121,1147,1333,1337,1408,1421,1425,1439,1531,1535,1542,1615,1618,1622,1781,1791,1797,1801,1814,1980,1991,2202,2206,2223,2511,2515,2520,2662,2665,2669,2698,2832,2836,2846,2909,2918,2973,2976,3102,3106,3113,3180,3395,3399,3408,3706,3710,3784],[499,500,501,502,506,507,510],"p",{},"A ",[503,504,505],"code",{},"WebSocketContract"," or a ",[503,508,509],{},"ServerSentEvents({...})"," class isn't only a server-side declaration — it's a\nschema map, and a schema map is exactly what a client needs to validate what it sends and receives.",[499,512,513,514,517,518,521,522,525,526,529,530,525,533,536],{},"The ",[503,515,516],{},"@heximon\u002Fclient\u002Fws"," and ",[503,519,520],{},"@heximon\u002Fclient\u002Fsse"," subpaths give you clients that type themselves off the same\nclass your server binds to: connect, get a fully typed ",[503,523,524],{},"send","\u002F",[503,527,528],{},"on"," or ",[503,531,532],{},"subscribe",[503,534,535],{},"stream"," surface, and catch\na schema mismatch at the call site instead of in production.",[499,538,539,540,543,544,547,548,551,552,555,556,559],{},"Both clients are frontend-safe: no ",[503,541,542],{},"node:"," imports, and no runtime dependency on ",[503,545,546],{},"@heximon\u002Fruntime",",\n",[503,549,550],{},"@heximon\u002Fwebsocket",", or ",[503,553,554],{},"@heximon\u002Fsse"," — the contract's schema types are ",[503,557,558],{},"import type"," only and erase at\nbuild time, so shipping the client to the browser never pulls the server package along.",[561,562,563,601,624,646],"code-group",{},[564,565,571],"pre",{"className":566,"code":567,"filename":568,"language":569,"meta":570,"style":570},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @heximon\u002Fclient\n# @heximon\u002Fwebsocket \u002F @heximon\u002Fsse are optional peers — install them only if you pass\n# a WebSocketContract \u002F ServerSentEvents class (rather than a raw schema map) as the type source\n","pnpm","bash","",[503,572,573,588,595],{"__ignoreMap":570},[574,575,578,581,585],"span",{"class":576,"line":577},"line",1,[574,579,568],{"class":580},"sBMFI",[574,582,584],{"class":583},"sfazB"," add",[574,586,587],{"class":583}," @heximon\u002Fclient\n",[574,589,591],{"class":576,"line":590},2,[574,592,594],{"class":593},"sHwdD","# @heximon\u002Fwebsocket \u002F @heximon\u002Fsse are optional peers — install them only if you pass\n",[574,596,598],{"class":576,"line":597},3,[574,599,600],{"class":593},"# a WebSocketContract \u002F ServerSentEvents class (rather than a raw schema map) as the type source\n",[564,602,605],{"className":566,"code":603,"filename":604,"language":569,"meta":570,"style":570},"npm install @heximon\u002Fclient\n# @heximon\u002Fwebsocket \u002F @heximon\u002Fsse are optional peers — install them only if you pass\n# a WebSocketContract \u002F ServerSentEvents class (rather than a raw schema map) as the type source\n","npm",[503,606,607,616,620],{"__ignoreMap":570},[574,608,609,611,614],{"class":576,"line":577},[574,610,604],{"class":580},[574,612,613],{"class":583}," install",[574,615,587],{"class":583},[574,617,618],{"class":576,"line":590},[574,619,594],{"class":593},[574,621,622],{"class":576,"line":597},[574,623,600],{"class":593},[564,625,628],{"className":566,"code":626,"filename":627,"language":569,"meta":570,"style":570},"yarn add @heximon\u002Fclient\n# @heximon\u002Fwebsocket \u002F @heximon\u002Fsse are optional peers — install them only if you pass\n# a WebSocketContract \u002F ServerSentEvents class (rather than a raw schema map) as the type source\n","yarn",[503,629,630,638,642],{"__ignoreMap":570},[574,631,632,634,636],{"class":576,"line":577},[574,633,627],{"class":580},[574,635,584],{"class":583},[574,637,587],{"class":583},[574,639,640],{"class":576,"line":590},[574,641,594],{"class":593},[574,643,644],{"class":576,"line":597},[574,645,600],{"class":593},[564,647,650],{"className":566,"code":648,"filename":649,"language":569,"meta":570,"style":570},"bun add @heximon\u002Fclient\n# @heximon\u002Fwebsocket \u002F @heximon\u002Fsse are optional peers — install them only if you pass\n# a WebSocketContract \u002F ServerSentEvents class (rather than a raw schema map) as the type source\n","bun",[503,651,652,660,664],{"__ignoreMap":570},[574,653,654,656,658],{"class":576,"line":577},[574,655,649],{"class":580},[574,657,584],{"class":583},[574,659,587],{"class":583},[574,661,662],{"class":576,"line":590},[574,663,594],{"class":593},[574,665,666],{"class":576,"line":597},[574,667,600],{"class":593},[669,670,672,673,675],"h2",{"id":671},"typed-websocket-client-heximonclientws","Typed WebSocket client (",[503,674,516],{},")",[677,678,680],"h3",{"id":679},"connect-and-exchange-messages","Connect and exchange messages",[499,682,683,686,687,689,690,693,694,697,698,701],{},[503,684,685],{},"WsClient\u003CContract>"," is generic over a ",[503,688,505],{}," subclass (or a raw ",[503,691,692],{},"WebSocketContractLike"," pair).\nConstruct it with a transport and the contract, then ",[503,695,696],{},"connect"," to get a live ",[503,699,700],{},"WsConnection",".",[564,703,708],{"className":704,"code":705,"filename":706,"language":707,"meta":570,"style":570},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { WsClient, WsTransport } from \"@heximon\u002Fclient\u002Fws\";\nimport { ChatContract } from \"@my-org\u002Fapi-contract\"; \u002F\u002F the shared contract package\n\nconst client = new WsClient(\n  WsTransport.native({ baseUrl: \"wss:\u002F\u002Fapi.example.com\" }),\n  new ChatContract(),\n);\n\nconst conn = client.connect(\"\u002Fws\u002Fchat\u002Froom-42\");\n\nconn.onOpen(() => console.log(\"connected\"));\n\nconn.on(\"broadcast\", (data) => {\n  \u002F\u002F data is typed: { id: string; text: string }\n  console.log(`${data.id}: ${data.text}`);\n});\n\nconn.send(\"message\", { text: \"hello\" }); \u002F\u002F validated against clientToServer[\"message\"]\n\nconn.close();\n","src\u002Fchat-client.ts","ts",[503,709,710,747,773,779,801,838,851,858,863,893,898,938,943,977,983,1028,1037,1042,1085,1090],{"__ignoreMap":570},[574,711,712,716,720,724,727,730,733,736,739,741,744],{"class":576,"line":577},[574,713,715],{"class":714},"s7zQu","import",[574,717,719],{"class":718},"sMK4o"," {",[574,721,723],{"class":722},"sTEyZ"," WsClient",[574,725,726],{"class":718},",",[574,728,729],{"class":722}," WsTransport",[574,731,732],{"class":718}," }",[574,734,735],{"class":714}," from",[574,737,738],{"class":718}," \"",[574,740,516],{"class":583},[574,742,743],{"class":718},"\"",[574,745,746],{"class":718},";\n",[574,748,749,751,753,756,758,760,762,765,767,770],{"class":576,"line":590},[574,750,715],{"class":714},[574,752,719],{"class":718},[574,754,755],{"class":722}," ChatContract",[574,757,732],{"class":718},[574,759,735],{"class":714},[574,761,738],{"class":718},[574,763,764],{"class":583},"@my-org\u002Fapi-contract",[574,766,743],{"class":718},[574,768,769],{"class":718},";",[574,771,772],{"class":593}," \u002F\u002F the shared contract package\n",[574,774,775],{"class":576,"line":597},[574,776,778],{"emptyLinePlaceholder":777},true,"\n",[574,780,782,786,789,792,795,798],{"class":576,"line":781},4,[574,783,785],{"class":784},"spNyl","const",[574,787,788],{"class":722}," client ",[574,790,791],{"class":718},"=",[574,793,794],{"class":718}," new",[574,796,723],{"class":797},"s2Zo4",[574,799,800],{"class":722},"(\n",[574,802,804,807,809,812,815,818,822,825,827,830,832,834,836],{"class":576,"line":803},5,[574,805,806],{"class":722},"  WsTransport",[574,808,701],{"class":718},[574,810,811],{"class":797},"native",[574,813,814],{"class":722},"(",[574,816,817],{"class":718},"{",[574,819,821],{"class":820},"swJcz"," baseUrl",[574,823,824],{"class":718},":",[574,826,738],{"class":718},[574,828,829],{"class":583},"wss:\u002F\u002Fapi.example.com",[574,831,743],{"class":718},[574,833,732],{"class":718},[574,835,675],{"class":722},[574,837,547],{"class":718},[574,839,841,844,846,849],{"class":576,"line":840},6,[574,842,843],{"class":718},"  new",[574,845,755],{"class":797},[574,847,848],{"class":722},"()",[574,850,547],{"class":718},[574,852,854,856],{"class":576,"line":853},7,[574,855,675],{"class":722},[574,857,746],{"class":718},[574,859,861],{"class":576,"line":860},8,[574,862,778],{"emptyLinePlaceholder":777},[574,864,866,868,871,873,876,878,880,882,884,887,889,891],{"class":576,"line":865},9,[574,867,785],{"class":784},[574,869,870],{"class":722}," conn ",[574,872,791],{"class":718},[574,874,875],{"class":722}," client",[574,877,701],{"class":718},[574,879,696],{"class":797},[574,881,814],{"class":722},[574,883,743],{"class":718},[574,885,886],{"class":583},"\u002Fws\u002Fchat\u002Froom-42",[574,888,743],{"class":718},[574,890,675],{"class":722},[574,892,746],{"class":718},[574,894,896],{"class":576,"line":895},10,[574,897,778],{"emptyLinePlaceholder":777},[574,899,901,904,906,909,911,913,916,919,921,924,926,928,931,933,936],{"class":576,"line":900},11,[574,902,903],{"class":722},"conn",[574,905,701],{"class":718},[574,907,908],{"class":797},"onOpen",[574,910,814],{"class":722},[574,912,848],{"class":718},[574,914,915],{"class":784}," =>",[574,917,918],{"class":722}," console",[574,920,701],{"class":718},[574,922,923],{"class":797},"log",[574,925,814],{"class":722},[574,927,743],{"class":718},[574,929,930],{"class":583},"connected",[574,932,743],{"class":718},[574,934,935],{"class":722},"))",[574,937,746],{"class":718},[574,939,941],{"class":576,"line":940},12,[574,942,778],{"emptyLinePlaceholder":777},[574,944,946,948,950,952,954,956,959,961,963,966,970,972,974],{"class":576,"line":945},13,[574,947,903],{"class":722},[574,949,701],{"class":718},[574,951,528],{"class":797},[574,953,814],{"class":722},[574,955,743],{"class":718},[574,957,958],{"class":583},"broadcast",[574,960,743],{"class":718},[574,962,726],{"class":718},[574,964,965],{"class":718}," (",[574,967,969],{"class":968},"sHdIc","data",[574,971,675],{"class":718},[574,973,915],{"class":784},[574,975,976],{"class":718}," {\n",[574,978,980],{"class":576,"line":979},14,[574,981,982],{"class":593},"  \u002F\u002F data is typed: { id: string; text: string }\n",[574,984,986,989,991,993,995,998,1000,1002,1005,1008,1011,1014,1016,1018,1021,1024,1026],{"class":576,"line":985},15,[574,987,988],{"class":722},"  console",[574,990,701],{"class":718},[574,992,923],{"class":797},[574,994,814],{"class":820},[574,996,997],{"class":718},"`${",[574,999,969],{"class":722},[574,1001,701],{"class":718},[574,1003,1004],{"class":722},"id",[574,1006,1007],{"class":718},"}",[574,1009,1010],{"class":583},": ",[574,1012,1013],{"class":718},"${",[574,1015,969],{"class":722},[574,1017,701],{"class":718},[574,1019,1020],{"class":722},"text",[574,1022,1023],{"class":718},"}`",[574,1025,675],{"class":820},[574,1027,746],{"class":718},[574,1029,1031,1033,1035],{"class":576,"line":1030},16,[574,1032,1007],{"class":718},[574,1034,675],{"class":722},[574,1036,746],{"class":718},[574,1038,1040],{"class":576,"line":1039},17,[574,1041,778],{"emptyLinePlaceholder":777},[574,1043,1045,1047,1049,1051,1053,1055,1058,1060,1062,1064,1067,1069,1071,1074,1076,1078,1080,1082],{"class":576,"line":1044},18,[574,1046,903],{"class":722},[574,1048,701],{"class":718},[574,1050,524],{"class":797},[574,1052,814],{"class":722},[574,1054,743],{"class":718},[574,1056,1057],{"class":583},"message",[574,1059,743],{"class":718},[574,1061,726],{"class":718},[574,1063,719],{"class":718},[574,1065,1066],{"class":820}," text",[574,1068,824],{"class":718},[574,1070,738],{"class":718},[574,1072,1073],{"class":583},"hello",[574,1075,743],{"class":718},[574,1077,732],{"class":718},[574,1079,675],{"class":722},[574,1081,769],{"class":718},[574,1083,1084],{"class":593}," \u002F\u002F validated against clientToServer[\"message\"]\n",[574,1086,1088],{"class":576,"line":1087},19,[574,1089,778],{"emptyLinePlaceholder":777},[574,1091,1093,1095,1097,1100,1102],{"class":576,"line":1092},20,[574,1094,903],{"class":722},[574,1096,701],{"class":718},[574,1098,1099],{"class":797},"close",[574,1101,848],{"class":722},[574,1103,746],{"class":718},[499,1105,1106,1109,1110,1113,1114,1117,1118,1120],{},[503,1107,1108],{},"connect(path)"," returns a ",[503,1111,1112],{},"WsConnection\u003CContract>"," immediately in ",[503,1115,1116],{},"\"connecting\""," state — register ",[503,1119,908],{}," to\nknow when the handshake completes.",[499,1122,1123,1126,1127,1130,1131,1133,1134,1138,1139,1142,1143,1146],{},[503,1124,1125],{},"ChatContract"," above declares no ",[503,1128,1129],{},"path",", so ",[503,1132,696],{}," takes the concrete path string. A contract that ",[1135,1136,1137],"em",{},"does","\nown a path (declared with ",[503,1140,1141],{},"WebSocketContract({ path, ... })",") takes different arguments, shaped by what it\ndeclared: no argument at all for a static path, or a typed parameter record for a parameterised one —\n",[503,1144,1145],{},"connect()","'s signature is generated from the contract, so a typo in a parameter name is a compile error, not\na runtime 404.",[1148,1149,1151,1161,1231,1245,1325],"callout",{"type":1150},"tip",[499,1152,1153,1157,1158,824],{},[1154,1155,1156],"strong",{},"Shorthand:"," the contract instance is itself the client hub when constructed over a client transport, so you\ncan skip the explicit ",[503,1159,1160],{},"WsClient",[564,1162,1164],{"className":704,"code":1163,"language":707,"meta":570,"style":570},"const conn = new ChatContract(WsTransport.native({ baseUrl: \"wss:\u002F\u002Fapi.example.com\" })).connect(\n  \"\u002Fws\u002Fchat\u002Froom-42\",\n);\n\u002F\u002F conn.on(\"broadcast\", …) \u002F conn.send(\"message\", …) — identical to the WsClient form above.\n",[503,1165,1166,1209,1220,1226],{"__ignoreMap":570},[574,1167,1168,1170,1172,1174,1176,1178,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201,1203,1205,1207],{"class":576,"line":577},[574,1169,785],{"class":784},[574,1171,870],{"class":722},[574,1173,791],{"class":718},[574,1175,794],{"class":718},[574,1177,755],{"class":797},[574,1179,1180],{"class":722},"(WsTransport",[574,1182,701],{"class":718},[574,1184,811],{"class":797},[574,1186,814],{"class":722},[574,1188,817],{"class":718},[574,1190,821],{"class":820},[574,1192,824],{"class":718},[574,1194,738],{"class":718},[574,1196,829],{"class":583},[574,1198,743],{"class":718},[574,1200,732],{"class":718},[574,1202,935],{"class":722},[574,1204,701],{"class":718},[574,1206,696],{"class":797},[574,1208,800],{"class":722},[574,1210,1211,1214,1216,1218],{"class":576,"line":590},[574,1212,1213],{"class":718},"  \"",[574,1215,886],{"class":583},[574,1217,743],{"class":718},[574,1219,547],{"class":718},[574,1221,1222,1224],{"class":576,"line":597},[574,1223,675],{"class":722},[574,1225,746],{"class":718},[574,1227,1228],{"class":576,"line":781},[574,1229,1230],{"class":593},"\u002F\u002F conn.on(\"broadcast\", …) \u002F conn.send(\"message\", …) — identical to the WsClient form above.\n",[499,1232,1233,1234,1237,1238,1241,1242,1244],{},"For a contract that owns a parameterised path (like the flagship ",[503,1235,1236],{},"SeatMapContract",", declared with\n",[503,1239,1240],{},"path: \"\u002Fws\u002Fevents\u002F:eventId\u002Fseats\"","), the same shorthand takes the typed parameter record instead of a path\nstring — ",[503,1243,696],{}," interpolates it into the declared template:",[564,1246,1248],{"className":704,"code":1247,"language":707,"meta":570,"style":570},"const conn = new SeatMapContract(WsTransport.native({ baseUrl: \"wss:\u002F\u002Fapi.example.com\" })).connect({\n  eventId: \"evt-42\",\n});\n\u002F\u002F → connects to wss:\u002F\u002Fapi.example.com\u002Fws\u002Fevents\u002Fevt-42\u002Fseats\n",[503,1249,1250,1296,1312,1320],{"__ignoreMap":570},[574,1251,1252,1254,1256,1258,1260,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293],{"class":576,"line":577},[574,1253,785],{"class":784},[574,1255,870],{"class":722},[574,1257,791],{"class":718},[574,1259,794],{"class":718},[574,1261,1262],{"class":797}," SeatMapContract",[574,1264,1180],{"class":722},[574,1266,701],{"class":718},[574,1268,811],{"class":797},[574,1270,814],{"class":722},[574,1272,817],{"class":718},[574,1274,821],{"class":820},[574,1276,824],{"class":718},[574,1278,738],{"class":718},[574,1280,829],{"class":583},[574,1282,743],{"class":718},[574,1284,732],{"class":718},[574,1286,935],{"class":722},[574,1288,701],{"class":718},[574,1290,696],{"class":797},[574,1292,814],{"class":722},[574,1294,1295],{"class":718},"{\n",[574,1297,1298,1301,1303,1305,1308,1310],{"class":576,"line":590},[574,1299,1300],{"class":820},"  eventId",[574,1302,824],{"class":718},[574,1304,738],{"class":718},[574,1306,1307],{"class":583},"evt-42",[574,1309,743],{"class":718},[574,1311,547],{"class":718},[574,1313,1314,1316,1318],{"class":576,"line":597},[574,1315,1007],{"class":718},[574,1317,675],{"class":722},[574,1319,746],{"class":718},[574,1321,1322],{"class":576,"line":781},[574,1323,1324],{"class":593},"\u002F\u002F → connects to wss:\u002F\u002Fapi.example.com\u002Fws\u002Fevents\u002Fevt-42\u002Fseats\n",[499,1326,1327,1330,1331,701],{},[503,1328,1329],{},"new WsClient(port, contract)"," stays as the explicit low-level form; both build the same ",[503,1332,700],{},[677,1334,1336],{"id":1335},"validation-and-errors","Validation and errors",[1338,1339,1340,1354],"table",{},[1341,1342,1343],"thead",{},[1344,1345,1346,1351],"tr",{},[1347,1348,1350],"th",{"align":1349},"left","Path",[1347,1352,1353],{"align":1349},"On failure",[1355,1356,1357,1373,1388,1398],"tbody",{},[1344,1358,1359,1366],{},[1360,1361,1362,1365],"td",{"align":1349},[503,1363,1364],{},"conn.send(kind, data)"," — outbound",[1360,1367,1368,1369,1372],{"align":1349},"throws ",[503,1370,1371],{},"WsValidationError","; nothing sent",[1344,1374,1375,1382],{},[1360,1376,1377,1378,1381],{"align":1349},"inbound ",[503,1379,1380],{},"on(kind)"," dispatch",[1360,1383,1384,1387],{"align":1349},[503,1385,1386],{},"onError(WsValidationError)","; frame dropped; connection stays open",[1344,1389,1390,1393],{},[1360,1391,1392],{"align":1349},"inbound unknown kind",[1360,1394,1395,1387],{"align":1349},[503,1396,1397],{},"onError(WsUnknownKindError)",[1344,1399,1400,1403],{},[1360,1401,1402],{"align":1349},"non-JSON or malformed envelope",[1360,1404,1405,1387],{"align":1349},[503,1406,1407],{},"onError(WsClientError)",[499,1409,1410,1412,1413,1416,1417,1420],{},[503,1411,524],{}," validates synchronously and throws rather than returning a promise: there's no backpressure signal to\nawait on a raw ",[503,1414,1415],{},"WebSocket.send",", so a failure has to surface at the call site instead of silently vanishing\ninto an unresolved promise. The connection never closes on a validation error — only on a manual\n",[503,1418,1419],{},"conn.close()"," or after the reconnect budget is exhausted.",[677,1422,1424],{"id":1423},"reconnect","Reconnect",[499,1426,1427,1428,1430,1431,1434,1435,1438],{},"The client reconnects automatically per the port's ",[503,1429,1423],{}," policy. The default is exponential back-off\ncapped at 30 s (",[503,1432,1433],{},"WsReconnect.exponential","). Use ",[503,1436,1437],{},"WsReconnect.none"," for a single attempt:",[564,1440,1442],{"className":704,"code":1441,"language":707,"meta":570,"style":570},"import { WsTransport, WsReconnect } from \"@heximon\u002Fclient\u002Fws\";\n\nconst port = WsTransport.native({\n  baseUrl: \"wss:\u002F\u002Fapi.example.com\",\n  reconnect: WsReconnect.none,\n});\n",[503,1443,1444,1469,1473,1492,1507,1523],{"__ignoreMap":570},[574,1445,1446,1448,1450,1452,1454,1457,1459,1461,1463,1465,1467],{"class":576,"line":577},[574,1447,715],{"class":714},[574,1449,719],{"class":718},[574,1451,729],{"class":722},[574,1453,726],{"class":718},[574,1455,1456],{"class":722}," WsReconnect",[574,1458,732],{"class":718},[574,1460,735],{"class":714},[574,1462,738],{"class":718},[574,1464,516],{"class":583},[574,1466,743],{"class":718},[574,1468,746],{"class":718},[574,1470,1471],{"class":576,"line":590},[574,1472,778],{"emptyLinePlaceholder":777},[574,1474,1475,1477,1480,1482,1484,1486,1488,1490],{"class":576,"line":597},[574,1476,785],{"class":784},[574,1478,1479],{"class":722}," port ",[574,1481,791],{"class":718},[574,1483,729],{"class":722},[574,1485,701],{"class":718},[574,1487,811],{"class":797},[574,1489,814],{"class":722},[574,1491,1295],{"class":718},[574,1493,1494,1497,1499,1501,1503,1505],{"class":576,"line":781},[574,1495,1496],{"class":820},"  baseUrl",[574,1498,824],{"class":718},[574,1500,738],{"class":718},[574,1502,829],{"class":583},[574,1504,743],{"class":718},[574,1506,547],{"class":718},[574,1508,1509,1512,1514,1516,1518,1521],{"class":576,"line":803},[574,1510,1511],{"class":820},"  reconnect",[574,1513,824],{"class":718},[574,1515,1456],{"class":722},[574,1517,701],{"class":718},[574,1519,1520],{"class":722},"none",[574,1522,547],{"class":718},[574,1524,1525,1527,1529],{"class":576,"line":840},[574,1526,1007],{"class":718},[574,1528,675],{"class":722},[574,1530,746],{"class":718},[677,1532,1534],{"id":1533},"query-parameters","Query parameters",[499,1536,1537,1538,1541],{},"Pass a ",[503,1539,1540],{},"query"," factory on the port to inject auth tickets or other per-connection parameters. It is re-evaluated\non every connection attempt, so a rotating token is always fresh:",[564,1543,1545],{"className":704,"code":1544,"language":707,"meta":570,"style":570},"WsTransport.native({\n  baseUrl: \"wss:\u002F\u002Fapi.example.com\",\n  query: () => ({ ticket: getTicket() }),\n});\n",[503,1546,1547,1560,1574,1607],{"__ignoreMap":570},[574,1548,1549,1552,1554,1556,1558],{"class":576,"line":577},[574,1550,1551],{"class":722},"WsTransport",[574,1553,701],{"class":718},[574,1555,811],{"class":797},[574,1557,814],{"class":722},[574,1559,1295],{"class":718},[574,1561,1562,1564,1566,1568,1570,1572],{"class":576,"line":590},[574,1563,1496],{"class":820},[574,1565,824],{"class":718},[574,1567,738],{"class":718},[574,1569,829],{"class":583},[574,1571,743],{"class":718},[574,1573,547],{"class":718},[574,1575,1576,1579,1581,1584,1586,1588,1590,1593,1595,1598,1601,1603,1605],{"class":576,"line":597},[574,1577,1578],{"class":797},"  query",[574,1580,824],{"class":718},[574,1582,1583],{"class":718}," ()",[574,1585,915],{"class":784},[574,1587,965],{"class":722},[574,1589,817],{"class":718},[574,1591,1592],{"class":820}," ticket",[574,1594,824],{"class":718},[574,1596,1597],{"class":797}," getTicket",[574,1599,1600],{"class":722},"() ",[574,1602,1007],{"class":718},[574,1604,675],{"class":722},[574,1606,547],{"class":718},[574,1608,1609,1611,1613],{"class":576,"line":781},[574,1610,1007],{"class":718},[574,1612,675],{"class":722},[574,1614,746],{"class":718},[499,1616,1617],{},"Browser WebSockets cannot set arbitrary headers at connect time, so a query param is the cross-origin auth\npattern (mint a short-lived ticket with a normal authenticated HTTP call, then pass it here).",[677,1619,1621],{"id":1620},"testing-with-a-mock-transport","Testing with a mock transport",[564,1623,1625],{"className":704,"code":1624,"language":707,"meta":570,"style":570},"import { WsClient, WsTransport } from \"@heximon\u002Fclient\u002Fws\";\n\nconst port = WsTransport.mock((url, protocols) => {\n  \u002F\u002F return a WebSocket-compatible mock object; no real network I\u002FO\n  return new MockWebSocket(url, protocols) as unknown as WebSocket;\n});\n\nconst conn = new WsClient(port, new ChatContract()).connect(\"\u002Fws\u002Fchat\u002Ftest\");\n",[503,1626,1627,1651,1655,1688,1693,1728,1736,1740],{"__ignoreMap":570},[574,1628,1629,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649],{"class":576,"line":577},[574,1630,715],{"class":714},[574,1632,719],{"class":718},[574,1634,723],{"class":722},[574,1636,726],{"class":718},[574,1638,729],{"class":722},[574,1640,732],{"class":718},[574,1642,735],{"class":714},[574,1644,738],{"class":718},[574,1646,516],{"class":583},[574,1648,743],{"class":718},[574,1650,746],{"class":718},[574,1652,1653],{"class":576,"line":590},[574,1654,778],{"emptyLinePlaceholder":777},[574,1656,1657,1659,1661,1663,1665,1667,1670,1672,1674,1677,1679,1682,1684,1686],{"class":576,"line":597},[574,1658,785],{"class":784},[574,1660,1479],{"class":722},[574,1662,791],{"class":718},[574,1664,729],{"class":722},[574,1666,701],{"class":718},[574,1668,1669],{"class":797},"mock",[574,1671,814],{"class":722},[574,1673,814],{"class":718},[574,1675,1676],{"class":968},"url",[574,1678,726],{"class":718},[574,1680,1681],{"class":968}," protocols",[574,1683,675],{"class":718},[574,1685,915],{"class":784},[574,1687,976],{"class":718},[574,1689,1690],{"class":576,"line":781},[574,1691,1692],{"class":593},"  \u002F\u002F return a WebSocket-compatible mock object; no real network I\u002FO\n",[574,1694,1695,1698,1700,1703,1705,1707,1709,1711,1714,1717,1720,1723,1726],{"class":576,"line":803},[574,1696,1697],{"class":714},"  return",[574,1699,794],{"class":718},[574,1701,1702],{"class":797}," MockWebSocket",[574,1704,814],{"class":820},[574,1706,1676],{"class":722},[574,1708,726],{"class":718},[574,1710,1681],{"class":722},[574,1712,1713],{"class":820},") ",[574,1715,1716],{"class":714},"as",[574,1718,1719],{"class":580}," unknown",[574,1721,1722],{"class":714}," as",[574,1724,1725],{"class":580}," WebSocket",[574,1727,746],{"class":718},[574,1729,1730,1732,1734],{"class":576,"line":840},[574,1731,1007],{"class":718},[574,1733,675],{"class":722},[574,1735,746],{"class":718},[574,1737,1738],{"class":576,"line":853},[574,1739,778],{"emptyLinePlaceholder":777},[574,1741,1742,1744,1746,1748,1750,1752,1755,1757,1759,1761,1764,1766,1768,1770,1772,1775,1777,1779],{"class":576,"line":860},[574,1743,785],{"class":784},[574,1745,870],{"class":722},[574,1747,791],{"class":718},[574,1749,794],{"class":718},[574,1751,723],{"class":797},[574,1753,1754],{"class":722},"(port",[574,1756,726],{"class":718},[574,1758,794],{"class":718},[574,1760,755],{"class":797},[574,1762,1763],{"class":722},"())",[574,1765,701],{"class":718},[574,1767,696],{"class":797},[574,1769,814],{"class":722},[574,1771,743],{"class":718},[574,1773,1774],{"class":583},"\u002Fws\u002Fchat\u002Ftest",[574,1776,743],{"class":718},[574,1778,675],{"class":722},[574,1780,746],{"class":718},[499,1782,1783,1786,1787,1790],{},[503,1784,1785],{},"WsTransport.mock(factory)"," injects any ",[503,1788,1789],{},"WebSocket","-compatible object so unit tests can assert typed dispatch,\nvalidation errors, and reconnect behavior without a running server.",[669,1792,1794,1795,675],{"id":1793},"typed-sse-client-heximonclientsse","Typed SSE client (",[503,1796,520],{},[677,1798,1800],{"id":1799},"build-a-port-and-construct-the-client","Build a port and construct the client",[499,1802,1803,1806,1807,1810,1811,701],{},[503,1804,1805],{},"SseTransport.fetch"," is the recommended default — it can attach auth headers cross-origin, and it surfaces\na non-2xx status as a typed ",[503,1808,1809],{},"SseConnectionError"," rather than silently retrying like the native ",[503,1812,1813],{},"EventSource",[564,1815,1817],{"className":704,"code":1816,"language":707,"meta":570,"style":570},"import { SseClient, SseTransport } from \"@heximon\u002Fclient\u002Fsse\";\nimport { FeedEvents } from \"@my-org\u002Fapi-contract\"; \u002F\u002F a ServerSentEvents({...}) class\n\nconst client = new SseClient(\n  SseTransport.fetch({\n    baseUrl: \"https:\u002F\u002Fapi.example.com\",\n    headers: () => ({ authorization: `Bearer ${getToken()}` }),\n  }),\n  FeedEvents,\n);\n",[503,1818,1819,1845,1869,1873,1887,1901,1917,1958,1967,1974],{"__ignoreMap":570},[574,1820,1821,1823,1825,1828,1830,1833,1835,1837,1839,1841,1843],{"class":576,"line":577},[574,1822,715],{"class":714},[574,1824,719],{"class":718},[574,1826,1827],{"class":722}," SseClient",[574,1829,726],{"class":718},[574,1831,1832],{"class":722}," SseTransport",[574,1834,732],{"class":718},[574,1836,735],{"class":714},[574,1838,738],{"class":718},[574,1840,520],{"class":583},[574,1842,743],{"class":718},[574,1844,746],{"class":718},[574,1846,1847,1849,1851,1854,1856,1858,1860,1862,1864,1866],{"class":576,"line":590},[574,1848,715],{"class":714},[574,1850,719],{"class":718},[574,1852,1853],{"class":722}," FeedEvents",[574,1855,732],{"class":718},[574,1857,735],{"class":714},[574,1859,738],{"class":718},[574,1861,764],{"class":583},[574,1863,743],{"class":718},[574,1865,769],{"class":718},[574,1867,1868],{"class":593}," \u002F\u002F a ServerSentEvents({...}) class\n",[574,1870,1871],{"class":576,"line":597},[574,1872,778],{"emptyLinePlaceholder":777},[574,1874,1875,1877,1879,1881,1883,1885],{"class":576,"line":781},[574,1876,785],{"class":784},[574,1878,788],{"class":722},[574,1880,791],{"class":718},[574,1882,794],{"class":718},[574,1884,1827],{"class":797},[574,1886,800],{"class":722},[574,1888,1889,1892,1894,1897,1899],{"class":576,"line":803},[574,1890,1891],{"class":722},"  SseTransport",[574,1893,701],{"class":718},[574,1895,1896],{"class":797},"fetch",[574,1898,814],{"class":722},[574,1900,1295],{"class":718},[574,1902,1903,1906,1908,1910,1913,1915],{"class":576,"line":840},[574,1904,1905],{"class":820},"    baseUrl",[574,1907,824],{"class":718},[574,1909,738],{"class":718},[574,1911,1912],{"class":583},"https:\u002F\u002Fapi.example.com",[574,1914,743],{"class":718},[574,1916,547],{"class":718},[574,1918,1919,1922,1924,1926,1928,1930,1932,1935,1937,1940,1943,1945,1948,1950,1952,1954,1956],{"class":576,"line":853},[574,1920,1921],{"class":797},"    headers",[574,1923,824],{"class":718},[574,1925,1583],{"class":718},[574,1927,915],{"class":784},[574,1929,965],{"class":722},[574,1931,817],{"class":718},[574,1933,1934],{"class":820}," authorization",[574,1936,824],{"class":718},[574,1938,1939],{"class":718}," `",[574,1941,1942],{"class":583},"Bearer ",[574,1944,1013],{"class":718},[574,1946,1947],{"class":797},"getToken",[574,1949,848],{"class":722},[574,1951,1023],{"class":718},[574,1953,732],{"class":718},[574,1955,675],{"class":722},[574,1957,547],{"class":718},[574,1959,1960,1963,1965],{"class":576,"line":860},[574,1961,1962],{"class":718},"  }",[574,1964,675],{"class":722},[574,1966,547],{"class":718},[574,1968,1969,1972],{"class":576,"line":865},[574,1970,1971],{"class":722},"  FeedEvents",[574,1973,547],{"class":718},[574,1975,1976,1978],{"class":576,"line":895},[574,1977,675],{"class":722},[574,1979,746],{"class":718},[499,1981,1982,1983,1986,1987,1990],{},"Pass a raw ",[503,1984,1985],{},"EventSchemaMap"," instead of a ",[503,1988,1989],{},"ServerSentEvents"," class when you have no shared contract package:",[564,1992,1994],{"className":704,"code":1993,"language":707,"meta":570,"style":570},"import * as v from \"valibot\";\n\nconst client = new SseClient(\n  SseTransport.fetch({ baseUrl: \"https:\u002F\u002Fapi.example.com\" }),\n  {\n    \"order.placed\": v.object({ orderId: v.string(), amount: v.number() }),\n    \"order.shipped\": v.object({ orderId: v.string(), carrier: v.string() }),\n  } as const,\n);\n",[503,1995,1996,2020,2024,2038,2066,2071,2131,2185,2196],{"__ignoreMap":570},[574,1997,1998,2000,2003,2005,2008,2011,2013,2016,2018],{"class":576,"line":577},[574,1999,715],{"class":714},[574,2001,2002],{"class":718}," *",[574,2004,1722],{"class":714},[574,2006,2007],{"class":722}," v ",[574,2009,2010],{"class":714},"from",[574,2012,738],{"class":718},[574,2014,2015],{"class":583},"valibot",[574,2017,743],{"class":718},[574,2019,746],{"class":718},[574,2021,2022],{"class":576,"line":590},[574,2023,778],{"emptyLinePlaceholder":777},[574,2025,2026,2028,2030,2032,2034,2036],{"class":576,"line":597},[574,2027,785],{"class":784},[574,2029,788],{"class":722},[574,2031,791],{"class":718},[574,2033,794],{"class":718},[574,2035,1827],{"class":797},[574,2037,800],{"class":722},[574,2039,2040,2042,2044,2046,2048,2050,2052,2054,2056,2058,2060,2062,2064],{"class":576,"line":781},[574,2041,1891],{"class":722},[574,2043,701],{"class":718},[574,2045,1896],{"class":797},[574,2047,814],{"class":722},[574,2049,817],{"class":718},[574,2051,821],{"class":820},[574,2053,824],{"class":718},[574,2055,738],{"class":718},[574,2057,1912],{"class":583},[574,2059,743],{"class":718},[574,2061,732],{"class":718},[574,2063,675],{"class":722},[574,2065,547],{"class":718},[574,2067,2068],{"class":576,"line":803},[574,2069,2070],{"class":718},"  {\n",[574,2072,2073,2076,2079,2081,2083,2086,2088,2091,2093,2095,2098,2100,2102,2104,2107,2109,2111,2114,2116,2118,2120,2123,2125,2127,2129],{"class":576,"line":840},[574,2074,2075],{"class":718},"    \"",[574,2077,2078],{"class":820},"order.placed",[574,2080,743],{"class":718},[574,2082,824],{"class":718},[574,2084,2085],{"class":722}," v",[574,2087,701],{"class":718},[574,2089,2090],{"class":797},"object",[574,2092,814],{"class":722},[574,2094,817],{"class":718},[574,2096,2097],{"class":820}," orderId",[574,2099,824],{"class":718},[574,2101,2085],{"class":722},[574,2103,701],{"class":718},[574,2105,2106],{"class":797},"string",[574,2108,848],{"class":722},[574,2110,726],{"class":718},[574,2112,2113],{"class":820}," amount",[574,2115,824],{"class":718},[574,2117,2085],{"class":722},[574,2119,701],{"class":718},[574,2121,2122],{"class":797},"number",[574,2124,1600],{"class":722},[574,2126,1007],{"class":718},[574,2128,675],{"class":722},[574,2130,547],{"class":718},[574,2132,2133,2135,2138,2140,2142,2144,2146,2148,2150,2152,2154,2156,2158,2160,2162,2164,2166,2169,2171,2173,2175,2177,2179,2181,2183],{"class":576,"line":853},[574,2134,2075],{"class":718},[574,2136,2137],{"class":820},"order.shipped",[574,2139,743],{"class":718},[574,2141,824],{"class":718},[574,2143,2085],{"class":722},[574,2145,701],{"class":718},[574,2147,2090],{"class":797},[574,2149,814],{"class":722},[574,2151,817],{"class":718},[574,2153,2097],{"class":820},[574,2155,824],{"class":718},[574,2157,2085],{"class":722},[574,2159,701],{"class":718},[574,2161,2106],{"class":797},[574,2163,848],{"class":722},[574,2165,726],{"class":718},[574,2167,2168],{"class":820}," carrier",[574,2170,824],{"class":718},[574,2172,2085],{"class":722},[574,2174,701],{"class":718},[574,2176,2106],{"class":797},[574,2178,1600],{"class":722},[574,2180,1007],{"class":718},[574,2182,675],{"class":722},[574,2184,547],{"class":718},[574,2186,2187,2189,2191,2194],{"class":576,"line":860},[574,2188,1962],{"class":718},[574,2190,1722],{"class":714},[574,2192,2193],{"class":784}," const",[574,2195,547],{"class":718},[574,2197,2198,2200],{"class":576,"line":865},[574,2199,675],{"class":722},[574,2201,746],{"class":718},[677,2203,2205],{"id":2204},"subscribe-with-a-callback","Subscribe with a callback",[499,2207,2208,2210,2211,2214,2215,2218,2219,2222],{},[503,2209,532],{}," opens the connection, validates each frame, and delivers events to ",[503,2212,2213],{},"onEvent",". It returns an\n",[503,2216,2217],{},"SseSubscription"," — call ",[503,2220,2221],{},"unsubscribe()"," to close at any time.",[564,2224,2226],{"className":704,"code":2225,"language":707,"meta":570,"style":570},"const sub = client.subscribe(\"\u002Forders\u002Ffeed\", {\n  onEvent(e) {\n    if (e.event === \"order.placed\") {\n      console.log(e.data.orderId); \u002F\u002F typed from the schema\n    }\n    if (e.event === \"order.shipped\") {\n      console.log(e.data.carrier);\n    }\n  },\n  onError(err) {\n    \u002F\u002F SseValidationError, SseUnknownEventError, SseConnectionError\n    \u002F\u002F Each leaves the connection open — only a SseConnectionError after all\n    \u002F\u002F reconnect attempts have been exhausted causes the stream to close.\n    console.error(err.message);\n  },\n  onClose() {\n    console.log(\"stream closed\");\n  },\n});\n\n\u002F\u002F later:\nsub.unsubscribe();\n",[503,2227,2228,2256,2270,2297,2326,2331,2355,2380,2384,2389,2403,2408,2413,2418,2440,2444,2453,2474,2478,2486,2490,2496],{"__ignoreMap":570},[574,2229,2230,2232,2235,2237,2239,2241,2243,2245,2247,2250,2252,2254],{"class":576,"line":577},[574,2231,785],{"class":784},[574,2233,2234],{"class":722}," sub ",[574,2236,791],{"class":718},[574,2238,875],{"class":722},[574,2240,701],{"class":718},[574,2242,532],{"class":797},[574,2244,814],{"class":722},[574,2246,743],{"class":718},[574,2248,2249],{"class":583},"\u002Forders\u002Ffeed",[574,2251,743],{"class":718},[574,2253,726],{"class":718},[574,2255,976],{"class":718},[574,2257,2258,2261,2263,2266,2268],{"class":576,"line":590},[574,2259,2260],{"class":820},"  onEvent",[574,2262,814],{"class":718},[574,2264,2265],{"class":968},"e",[574,2267,675],{"class":718},[574,2269,976],{"class":718},[574,2271,2272,2275,2277,2279,2281,2284,2287,2289,2291,2293,2295],{"class":576,"line":597},[574,2273,2274],{"class":714},"    if",[574,2276,965],{"class":820},[574,2278,2265],{"class":722},[574,2280,701],{"class":718},[574,2282,2283],{"class":722},"event",[574,2285,2286],{"class":718}," ===",[574,2288,738],{"class":718},[574,2290,2078],{"class":583},[574,2292,743],{"class":718},[574,2294,1713],{"class":820},[574,2296,1295],{"class":718},[574,2298,2299,2302,2304,2306,2308,2310,2312,2314,2316,2319,2321,2323],{"class":576,"line":781},[574,2300,2301],{"class":722},"      console",[574,2303,701],{"class":718},[574,2305,923],{"class":797},[574,2307,814],{"class":820},[574,2309,2265],{"class":722},[574,2311,701],{"class":718},[574,2313,969],{"class":722},[574,2315,701],{"class":718},[574,2317,2318],{"class":722},"orderId",[574,2320,675],{"class":820},[574,2322,769],{"class":718},[574,2324,2325],{"class":593}," \u002F\u002F typed from the schema\n",[574,2327,2328],{"class":576,"line":803},[574,2329,2330],{"class":718},"    }\n",[574,2332,2333,2335,2337,2339,2341,2343,2345,2347,2349,2351,2353],{"class":576,"line":840},[574,2334,2274],{"class":714},[574,2336,965],{"class":820},[574,2338,2265],{"class":722},[574,2340,701],{"class":718},[574,2342,2283],{"class":722},[574,2344,2286],{"class":718},[574,2346,738],{"class":718},[574,2348,2137],{"class":583},[574,2350,743],{"class":718},[574,2352,1713],{"class":820},[574,2354,1295],{"class":718},[574,2356,2357,2359,2361,2363,2365,2367,2369,2371,2373,2376,2378],{"class":576,"line":853},[574,2358,2301],{"class":722},[574,2360,701],{"class":718},[574,2362,923],{"class":797},[574,2364,814],{"class":820},[574,2366,2265],{"class":722},[574,2368,701],{"class":718},[574,2370,969],{"class":722},[574,2372,701],{"class":718},[574,2374,2375],{"class":722},"carrier",[574,2377,675],{"class":820},[574,2379,746],{"class":718},[574,2381,2382],{"class":576,"line":860},[574,2383,2330],{"class":718},[574,2385,2386],{"class":576,"line":865},[574,2387,2388],{"class":718},"  },\n",[574,2390,2391,2394,2396,2399,2401],{"class":576,"line":895},[574,2392,2393],{"class":820},"  onError",[574,2395,814],{"class":718},[574,2397,2398],{"class":968},"err",[574,2400,675],{"class":718},[574,2402,976],{"class":718},[574,2404,2405],{"class":576,"line":900},[574,2406,2407],{"class":593},"    \u002F\u002F SseValidationError, SseUnknownEventError, SseConnectionError\n",[574,2409,2410],{"class":576,"line":940},[574,2411,2412],{"class":593},"    \u002F\u002F Each leaves the connection open — only a SseConnectionError after all\n",[574,2414,2415],{"class":576,"line":945},[574,2416,2417],{"class":593},"    \u002F\u002F reconnect attempts have been exhausted causes the stream to close.\n",[574,2419,2420,2423,2425,2428,2430,2432,2434,2436,2438],{"class":576,"line":979},[574,2421,2422],{"class":722},"    console",[574,2424,701],{"class":718},[574,2426,2427],{"class":797},"error",[574,2429,814],{"class":820},[574,2431,2398],{"class":722},[574,2433,701],{"class":718},[574,2435,1057],{"class":722},[574,2437,675],{"class":820},[574,2439,746],{"class":718},[574,2441,2442],{"class":576,"line":985},[574,2443,2388],{"class":718},[574,2445,2446,2449,2451],{"class":576,"line":1030},[574,2447,2448],{"class":820},"  onClose",[574,2450,848],{"class":718},[574,2452,976],{"class":718},[574,2454,2455,2457,2459,2461,2463,2465,2468,2470,2472],{"class":576,"line":1039},[574,2456,2422],{"class":722},[574,2458,701],{"class":718},[574,2460,923],{"class":797},[574,2462,814],{"class":820},[574,2464,743],{"class":718},[574,2466,2467],{"class":583},"stream closed",[574,2469,743],{"class":718},[574,2471,675],{"class":820},[574,2473,746],{"class":718},[574,2475,2476],{"class":576,"line":1044},[574,2477,2388],{"class":718},[574,2479,2480,2482,2484],{"class":576,"line":1087},[574,2481,1007],{"class":718},[574,2483,675],{"class":722},[574,2485,746],{"class":718},[574,2487,2488],{"class":576,"line":1092},[574,2489,778],{"emptyLinePlaceholder":777},[574,2491,2493],{"class":576,"line":2492},21,[574,2494,2495],{"class":593},"\u002F\u002F later:\n",[574,2497,2499,2502,2504,2507,2509],{"class":576,"line":2498},22,[574,2500,2501],{"class":722},"sub",[574,2503,701],{"class":718},[574,2505,2506],{"class":797},"unsubscribe",[574,2508,848],{"class":722},[574,2510,746],{"class":718},[677,2512,2514],{"id":2513},"stream-with-an-async-generator","Stream with an async generator",[499,2516,2517,2519],{},[503,2518,535],{}," yields one typed event per iteration. Terminate by returning from the loop, or by aborting a signal.",[564,2521,2523],{"className":704,"code":2522,"language":707,"meta":570,"style":570},"const controller = new AbortController();\n\nfor await (const event of client.stream(\"\u002Forders\u002Ffeed\", { signal: controller.signal })) {\n  if (event.event === \"order.placed\") {\n    console.log(event.data.orderId);\n  }\n}\n",[503,2524,2525,2543,2547,2603,2628,2652,2657],{"__ignoreMap":570},[574,2526,2527,2529,2532,2534,2536,2539,2541],{"class":576,"line":577},[574,2528,785],{"class":784},[574,2530,2531],{"class":722}," controller ",[574,2533,791],{"class":718},[574,2535,794],{"class":718},[574,2537,2538],{"class":797}," AbortController",[574,2540,848],{"class":722},[574,2542,746],{"class":718},[574,2544,2545],{"class":576,"line":590},[574,2546,778],{"emptyLinePlaceholder":777},[574,2548,2549,2552,2555,2557,2559,2562,2565,2567,2569,2571,2573,2575,2577,2579,2581,2583,2586,2588,2591,2593,2596,2598,2601],{"class":576,"line":597},[574,2550,2551],{"class":714},"for",[574,2553,2554],{"class":714}," await",[574,2556,965],{"class":722},[574,2558,785],{"class":784},[574,2560,2561],{"class":722}," event ",[574,2563,2564],{"class":718},"of",[574,2566,875],{"class":722},[574,2568,701],{"class":718},[574,2570,535],{"class":797},[574,2572,814],{"class":722},[574,2574,743],{"class":718},[574,2576,2249],{"class":583},[574,2578,743],{"class":718},[574,2580,726],{"class":718},[574,2582,719],{"class":718},[574,2584,2585],{"class":820}," signal",[574,2587,824],{"class":718},[574,2589,2590],{"class":722}," controller",[574,2592,701],{"class":718},[574,2594,2595],{"class":722},"signal ",[574,2597,1007],{"class":718},[574,2599,2600],{"class":722},")) ",[574,2602,1295],{"class":718},[574,2604,2605,2608,2610,2612,2614,2616,2618,2620,2622,2624,2626],{"class":576,"line":781},[574,2606,2607],{"class":714},"  if",[574,2609,965],{"class":820},[574,2611,2283],{"class":722},[574,2613,701],{"class":718},[574,2615,2283],{"class":722},[574,2617,2286],{"class":718},[574,2619,738],{"class":718},[574,2621,2078],{"class":583},[574,2623,743],{"class":718},[574,2625,1713],{"class":820},[574,2627,1295],{"class":718},[574,2629,2630,2632,2634,2636,2638,2640,2642,2644,2646,2648,2650],{"class":576,"line":803},[574,2631,2422],{"class":722},[574,2633,701],{"class":718},[574,2635,923],{"class":797},[574,2637,814],{"class":820},[574,2639,2283],{"class":722},[574,2641,701],{"class":718},[574,2643,969],{"class":722},[574,2645,701],{"class":718},[574,2647,2318],{"class":722},[574,2649,675],{"class":820},[574,2651,746],{"class":718},[574,2653,2654],{"class":576,"line":840},[574,2655,2656],{"class":718},"  }\n",[574,2658,2659],{"class":576,"line":853},[574,2660,2661],{"class":718},"}\n",[499,2663,2664],{},"Validation errors drop the individual frame but do not terminate the generator — only a connection failure that\nexhausts all reconnect attempts ends the loop.",[677,2666,2668],{"id":2667},"resume-from-a-last-event-id","Resume from a last event id",[499,2670,2671,2672,2675,2676,2679,2680,2682,2683,2686,2687,2690,2691,2694,2695,2697],{},"Pass ",[503,2673,2674],{},"lastEventId"," to resume from a known position after a reload or a dropped connection. The client sends it as\nthe ",[503,2677,2678],{},"Last-Event-ID"," header in ",[503,2681,1896],{}," mode (the server's ",[503,2684,2685],{},"resumeFrom"," receives it), or as\n",[503,2688,2689],{},"?lastEventId=\u003Cid>"," in ",[503,2692,2693],{},"eventSource"," mode (the ",[503,2696,1813],{}," API cannot set custom headers).",[564,2699,2701],{"className":704,"code":2700,"language":707,"meta":570,"style":570},"const sub = client.subscribe(\"\u002Forders\u002Ffeed\", {\n  lastEventId: localStorage.getItem(\"lastEventId\") ?? undefined,\n  onEvent(e) {\n    if (e.id) localStorage.setItem(\"lastEventId\", e.id);\n    \u002F\u002F handle e ...\n  },\n});\n",[503,2702,2703,2729,2760,2772,2815,2820,2824],{"__ignoreMap":570},[574,2704,2705,2707,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727],{"class":576,"line":577},[574,2706,785],{"class":784},[574,2708,2234],{"class":722},[574,2710,791],{"class":718},[574,2712,875],{"class":722},[574,2714,701],{"class":718},[574,2716,532],{"class":797},[574,2718,814],{"class":722},[574,2720,743],{"class":718},[574,2722,2249],{"class":583},[574,2724,743],{"class":718},[574,2726,726],{"class":718},[574,2728,976],{"class":718},[574,2730,2731,2734,2736,2739,2741,2744,2746,2748,2750,2752,2754,2757],{"class":576,"line":590},[574,2732,2733],{"class":820},"  lastEventId",[574,2735,824],{"class":718},[574,2737,2738],{"class":722}," localStorage",[574,2740,701],{"class":718},[574,2742,2743],{"class":797},"getItem",[574,2745,814],{"class":722},[574,2747,743],{"class":718},[574,2749,2674],{"class":583},[574,2751,743],{"class":718},[574,2753,1713],{"class":722},[574,2755,2756],{"class":718},"??",[574,2758,2759],{"class":718}," undefined,\n",[574,2761,2762,2764,2766,2768,2770],{"class":576,"line":597},[574,2763,2260],{"class":820},[574,2765,814],{"class":718},[574,2767,2265],{"class":968},[574,2769,675],{"class":718},[574,2771,976],{"class":718},[574,2773,2774,2776,2778,2780,2782,2784,2786,2789,2791,2794,2796,2798,2800,2802,2804,2807,2809,2811,2813],{"class":576,"line":781},[574,2775,2274],{"class":714},[574,2777,965],{"class":820},[574,2779,2265],{"class":722},[574,2781,701],{"class":718},[574,2783,1004],{"class":722},[574,2785,1713],{"class":820},[574,2787,2788],{"class":722},"localStorage",[574,2790,701],{"class":718},[574,2792,2793],{"class":797},"setItem",[574,2795,814],{"class":820},[574,2797,743],{"class":718},[574,2799,2674],{"class":583},[574,2801,743],{"class":718},[574,2803,726],{"class":718},[574,2805,2806],{"class":722}," e",[574,2808,701],{"class":718},[574,2810,1004],{"class":722},[574,2812,675],{"class":820},[574,2814,746],{"class":718},[574,2816,2817],{"class":576,"line":803},[574,2818,2819],{"class":593},"    \u002F\u002F handle e ...\n",[574,2821,2822],{"class":576,"line":840},[574,2823,2388],{"class":718},[574,2825,2826,2828,2830],{"class":576,"line":853},[574,2827,1007],{"class":718},[574,2829,675],{"class":722},[574,2831,746],{"class":718},[677,2833,2835],{"id":2834},"transport-modes-and-reconnect","Transport modes and reconnect",[499,2837,2838,2841,2842,2845],{},[503,2839,2840],{},"SseTransport"," builds three modes. The mode is fixed per ",[503,2843,2844],{},"SsePort"," — one port per client construction.",[1338,2847,2848,2861],{},[1341,2849,2850],{},[1344,2851,2852,2855,2858],{},[1347,2853,2854],{"align":1349},"Mode",[1347,2856,2857],{"align":1349},"Factory",[1347,2859,2860],{"align":1349},"When to use",[1355,2862,2863,2879,2894],{},[1344,2864,2865,2871,2876],{},[1360,2866,2867,2870],{"align":1349},[503,2868,2869],{},"\"fetch\""," (default)",[1360,2872,2873],{"align":1349},[503,2874,2875],{},"SseTransport.fetch({ baseUrl, headers?, credentials?, reconnect? })",[1360,2877,2878],{"align":1349},"Any cross-origin stream that needs auth headers.",[1344,2880,2881,2886,2891],{},[1360,2882,2883],{"align":1349},[503,2884,2885],{},"\"eventSource\"",[1360,2887,2888],{"align":1349},[503,2889,2890],{},"SseTransport.eventSource({ baseUrl, reconnect? })",[1360,2892,2893],{"align":1349},"Same-origin streams relying on cookies; the browser manages reconnect natively.",[1344,2895,2896,2901,2906],{},[1360,2897,2898],{"align":1349},[503,2899,2900],{},"\"mock\"",[1360,2902,2903],{"align":1349},[503,2904,2905],{},"SseTransport.mock(frames)",[1360,2907,2908],{"align":1349},"Tests — drive the parser with a pre-encoded iterable of frame strings, no network I\u002FO.",[499,2910,513,2911,2913,2914,2917],{},[503,2912,1423],{}," field takes an ",[503,2915,2916],{},"SseReconnectPolicy",". Two presets cover most needs:",[564,2919,2921],{"className":704,"code":2920,"language":707,"meta":570,"style":570},"import { SseReconnect } from \"@heximon\u002Fclient\u002Fsse\";\n\nSseReconnect.forever \u002F\u002F indefinite, exponential back-off capped at 30 s (or the server's retry: hint)\nSseReconnect.none    \u002F\u002F a single attempt, no retries\n",[503,2922,2923,2944,2948,2961],{"__ignoreMap":570},[574,2924,2925,2927,2929,2932,2934,2936,2938,2940,2942],{"class":576,"line":577},[574,2926,715],{"class":714},[574,2928,719],{"class":718},[574,2930,2931],{"class":722}," SseReconnect",[574,2933,732],{"class":718},[574,2935,735],{"class":714},[574,2937,738],{"class":718},[574,2939,520],{"class":583},[574,2941,743],{"class":718},[574,2943,746],{"class":718},[574,2945,2946],{"class":576,"line":590},[574,2947,778],{"emptyLinePlaceholder":777},[574,2949,2950,2953,2955,2958],{"class":576,"line":597},[574,2951,2952],{"class":722},"SseReconnect",[574,2954,701],{"class":718},[574,2956,2957],{"class":722},"forever ",[574,2959,2960],{"class":593},"\u002F\u002F indefinite, exponential back-off capped at 30 s (or the server's retry: hint)\n",[574,2962,2963,2965,2967,2970],{"class":576,"line":781},[574,2964,2952],{"class":722},[574,2966,701],{"class":718},[574,2968,2969],{"class":722},"none    ",[574,2971,2972],{"class":593},"\u002F\u002F a single attempt, no retries\n",[499,2974,2975],{},"Supply a custom policy when you need a bounded retry count or a fixed delay:",[564,2977,2979],{"className":704,"code":2978,"language":707,"meta":570,"style":570},"const port = SseTransport.fetch({\n  baseUrl: \"https:\u002F\u002Fapi.example.com\",\n  reconnect: {\n    enabled: true,\n    maxAttempts: 5,\n    delay: (attempt) => Math.min(1_000 * attempt, 10_000),\n  },\n});\n",[503,2980,2981,2999,3013,3021,3034,3047,3090,3094],{"__ignoreMap":570},[574,2982,2983,2985,2987,2989,2991,2993,2995,2997],{"class":576,"line":577},[574,2984,785],{"class":784},[574,2986,1479],{"class":722},[574,2988,791],{"class":718},[574,2990,1832],{"class":722},[574,2992,701],{"class":718},[574,2994,1896],{"class":797},[574,2996,814],{"class":722},[574,2998,1295],{"class":718},[574,3000,3001,3003,3005,3007,3009,3011],{"class":576,"line":590},[574,3002,1496],{"class":820},[574,3004,824],{"class":718},[574,3006,738],{"class":718},[574,3008,1912],{"class":583},[574,3010,743],{"class":718},[574,3012,547],{"class":718},[574,3014,3015,3017,3019],{"class":576,"line":597},[574,3016,1511],{"class":820},[574,3018,824],{"class":718},[574,3020,976],{"class":718},[574,3022,3023,3026,3028,3032],{"class":576,"line":781},[574,3024,3025],{"class":820},"    enabled",[574,3027,824],{"class":718},[574,3029,3031],{"class":3030},"sfNiH"," true",[574,3033,547],{"class":718},[574,3035,3036,3039,3041,3045],{"class":576,"line":803},[574,3037,3038],{"class":820},"    maxAttempts",[574,3040,824],{"class":718},[574,3042,3044],{"class":3043},"sbssI"," 5",[574,3046,547],{"class":718},[574,3048,3049,3052,3054,3056,3059,3061,3063,3066,3068,3071,3073,3076,3078,3081,3083,3086,3088],{"class":576,"line":840},[574,3050,3051],{"class":797},"    delay",[574,3053,824],{"class":718},[574,3055,965],{"class":718},[574,3057,3058],{"class":968},"attempt",[574,3060,675],{"class":718},[574,3062,915],{"class":784},[574,3064,3065],{"class":722}," Math",[574,3067,701],{"class":718},[574,3069,3070],{"class":797},"min",[574,3072,814],{"class":722},[574,3074,3075],{"class":3043},"1_000",[574,3077,2002],{"class":718},[574,3079,3080],{"class":722}," attempt",[574,3082,726],{"class":718},[574,3084,3085],{"class":3043}," 10_000",[574,3087,675],{"class":722},[574,3089,547],{"class":718},[574,3091,3092],{"class":576,"line":853},[574,3093,2388],{"class":718},[574,3095,3096,3098,3100],{"class":576,"line":860},[574,3097,1007],{"class":718},[574,3099,675],{"class":722},[574,3101,746],{"class":718},[677,3103,3105],{"id":3104},"error-types","Error types",[499,3107,3108,3109,3112],{},"Three typed errors surface through ",[503,3110,3111],{},"onError"," — none of them close the connection on their own:",[1338,3114,3115,3128],{},[1341,3116,3117],{},[1344,3118,3119,3122,3125],{},[1347,3120,3121],{"align":1349},"Error",[1347,3123,3124],{"align":1349},"Cause",[1347,3126,3127],{"align":1349},"Stream stays open",[1355,3129,3130,3151,3165],{},[1344,3131,3132,3137,3148],{},[1360,3133,3134],{"align":1349},[503,3135,3136],{},"SseValidationError",[1360,3138,3139,3140,3143,3144,3147],{"align":1349},"The frame's JSON payload failed its schema. Carries ",[503,3141,3142],{},"eventName"," + the Standard Schema ",[503,3145,3146],{},"issues"," array.",[1360,3149,3150],{"align":1349},"Yes",[1344,3152,3153,3158,3163],{},[1360,3154,3155],{"align":1349},[503,3156,3157],{},"SseUnknownEventError",[1360,3159,3160,3161,701],{"align":1349},"The server sent an event name not in the declared schema map. Carries ",[503,3162,3142],{},[1360,3164,3150],{"align":1349},[1344,3166,3167,3171,3177],{},[1360,3168,3169],{"align":1349},[503,3170,1809],{},[1360,3172,3173,3174,701],{"align":1349},"A network failure, a non-2xx status, or a transport-level abort. Carries an optional ",[503,3175,3176],{},"cause",[1360,3178,3179],{"align":1349},"Until reconnect budget is exhausted",[564,3181,3183],{"className":704,"code":3182,"language":707,"meta":570,"style":570},"import { SseValidationError, SseUnknownEventError, SseConnectionError } from \"@heximon\u002Fclient\u002Fsse\";\n\nonError(err) {\n  if (err instanceof SseValidationError) {\n    console.warn(`bad payload for ${err.eventName}`, err.issues);\n  } else if (err instanceof SseUnknownEventError) {\n    console.warn(`unknown event: ${err.eventName}`);\n  } else if (err instanceof SseConnectionError) {\n    console.error(\"connection failed\", err.cause);\n  }\n},\n",[503,3184,3185,3216,3220,3229,3246,3286,3308,3337,3357,3386,3390],{"__ignoreMap":570},[574,3186,3187,3189,3191,3194,3196,3199,3201,3204,3206,3208,3210,3212,3214],{"class":576,"line":577},[574,3188,715],{"class":714},[574,3190,719],{"class":718},[574,3192,3193],{"class":722}," SseValidationError",[574,3195,726],{"class":718},[574,3197,3198],{"class":722}," SseUnknownEventError",[574,3200,726],{"class":718},[574,3202,3203],{"class":722}," SseConnectionError",[574,3205,732],{"class":718},[574,3207,735],{"class":714},[574,3209,738],{"class":718},[574,3211,520],{"class":583},[574,3213,743],{"class":718},[574,3215,746],{"class":718},[574,3217,3218],{"class":576,"line":590},[574,3219,778],{"emptyLinePlaceholder":777},[574,3221,3222,3224,3227],{"class":576,"line":597},[574,3223,3111],{"class":797},[574,3225,3226],{"class":722},"(err) ",[574,3228,1295],{"class":718},[574,3230,3231,3233,3235,3237,3240,3242,3244],{"class":576,"line":781},[574,3232,2607],{"class":714},[574,3234,965],{"class":820},[574,3236,2398],{"class":722},[574,3238,3239],{"class":718}," instanceof",[574,3241,3193],{"class":580},[574,3243,1713],{"class":820},[574,3245,1295],{"class":718},[574,3247,3248,3250,3252,3255,3257,3260,3263,3265,3267,3269,3271,3273,3275,3278,3280,3282,3284],{"class":576,"line":803},[574,3249,2422],{"class":722},[574,3251,701],{"class":718},[574,3253,3254],{"class":797},"warn",[574,3256,814],{"class":820},[574,3258,3259],{"class":718},"`",[574,3261,3262],{"class":583},"bad payload for ",[574,3264,1013],{"class":718},[574,3266,2398],{"class":722},[574,3268,701],{"class":718},[574,3270,3142],{"class":722},[574,3272,1023],{"class":718},[574,3274,726],{"class":718},[574,3276,3277],{"class":722}," err",[574,3279,701],{"class":718},[574,3281,3146],{"class":722},[574,3283,675],{"class":820},[574,3285,746],{"class":718},[574,3287,3288,3290,3293,3296,3298,3300,3302,3304,3306],{"class":576,"line":840},[574,3289,1962],{"class":718},[574,3291,3292],{"class":714}," else",[574,3294,3295],{"class":714}," if",[574,3297,965],{"class":820},[574,3299,2398],{"class":722},[574,3301,3239],{"class":718},[574,3303,3198],{"class":580},[574,3305,1713],{"class":820},[574,3307,1295],{"class":718},[574,3309,3310,3312,3314,3316,3318,3320,3323,3325,3327,3329,3331,3333,3335],{"class":576,"line":853},[574,3311,2422],{"class":722},[574,3313,701],{"class":718},[574,3315,3254],{"class":797},[574,3317,814],{"class":820},[574,3319,3259],{"class":718},[574,3321,3322],{"class":583},"unknown event: ",[574,3324,1013],{"class":718},[574,3326,2398],{"class":722},[574,3328,701],{"class":718},[574,3330,3142],{"class":722},[574,3332,1023],{"class":718},[574,3334,675],{"class":820},[574,3336,746],{"class":718},[574,3338,3339,3341,3343,3345,3347,3349,3351,3353,3355],{"class":576,"line":860},[574,3340,1962],{"class":718},[574,3342,3292],{"class":714},[574,3344,3295],{"class":714},[574,3346,965],{"class":820},[574,3348,2398],{"class":722},[574,3350,3239],{"class":718},[574,3352,3203],{"class":580},[574,3354,1713],{"class":820},[574,3356,1295],{"class":718},[574,3358,3359,3361,3363,3365,3367,3369,3372,3374,3376,3378,3380,3382,3384],{"class":576,"line":865},[574,3360,2422],{"class":722},[574,3362,701],{"class":718},[574,3364,2427],{"class":797},[574,3366,814],{"class":820},[574,3368,743],{"class":718},[574,3370,3371],{"class":583},"connection failed",[574,3373,743],{"class":718},[574,3375,726],{"class":718},[574,3377,3277],{"class":722},[574,3379,701],{"class":718},[574,3381,3176],{"class":722},[574,3383,675],{"class":820},[574,3385,746],{"class":718},[574,3387,3388],{"class":576,"line":895},[574,3389,2656],{"class":718},[574,3391,3392],{"class":576,"line":900},[574,3393,3394],{"class":718},"},\n",[677,3396,3398],{"id":3397},"testing-with-the-mock-transport","Testing with the mock transport",[499,3400,3401,3403,3404,3407],{},[503,3402,2905],{}," drives the full parser + validation path with a pre-encoded iterable of SSE frame\nstrings — identical to the fetch path, no network. Use ",[503,3405,3406],{},"SseReconnect.none"," so the generator terminates\nwhen the frames are exhausted.",[564,3409,3411],{"className":704,"code":3410,"language":707,"meta":570,"style":570},"import { SseClient, SseTransport, SseReconnect } from \"@heximon\u002Fclient\u002Fsse\";\n\nconst frames = [\n  \"id: 1\\nevent: order.placed\\ndata: {\\\"orderId\\\":\\\"abc\\\",\\\"amount\\\":42}\\n\\n\",\n  \"id: 2\\nevent: order.shipped\\ndata: {\\\"orderId\\\":\\\"abc\\\",\\\"carrier\\\":\\\"DHL\\\"}\\n\\n\",\n];\n\nconst port = { ...SseTransport.mock(frames), reconnect: SseReconnect.none };\nconst client = new SseClient(port, testEvents);\n\nfor await (const event of client.stream(\"\u002Ffeed\")) {\n  console.log(event.event, event.data);\n}\n",[503,3412,3413,3441,3445,3457,3510,3565,3572,3576,3615,3636,3640,3673,3702],{"__ignoreMap":570},[574,3414,3415,3417,3419,3421,3423,3425,3427,3429,3431,3433,3435,3437,3439],{"class":576,"line":577},[574,3416,715],{"class":714},[574,3418,719],{"class":718},[574,3420,1827],{"class":722},[574,3422,726],{"class":718},[574,3424,1832],{"class":722},[574,3426,726],{"class":718},[574,3428,2931],{"class":722},[574,3430,732],{"class":718},[574,3432,735],{"class":714},[574,3434,738],{"class":718},[574,3436,520],{"class":583},[574,3438,743],{"class":718},[574,3440,746],{"class":718},[574,3442,3443],{"class":576,"line":590},[574,3444,778],{"emptyLinePlaceholder":777},[574,3446,3447,3449,3452,3454],{"class":576,"line":597},[574,3448,785],{"class":784},[574,3450,3451],{"class":722}," frames ",[574,3453,791],{"class":718},[574,3455,3456],{"class":722}," [\n",[574,3458,3459,3461,3464,3467,3470,3472,3475,3478,3480,3482,3484,3486,3489,3491,3493,3495,3498,3500,3503,3506,3508],{"class":576,"line":781},[574,3460,1213],{"class":718},[574,3462,3463],{"class":583},"id: 1",[574,3465,3466],{"class":722},"\\n",[574,3468,3469],{"class":583},"event: order.placed",[574,3471,3466],{"class":722},[574,3473,3474],{"class":583},"data: {",[574,3476,3477],{"class":722},"\\\"",[574,3479,2318],{"class":583},[574,3481,3477],{"class":722},[574,3483,824],{"class":583},[574,3485,3477],{"class":722},[574,3487,3488],{"class":583},"abc",[574,3490,3477],{"class":722},[574,3492,726],{"class":583},[574,3494,3477],{"class":722},[574,3496,3497],{"class":583},"amount",[574,3499,3477],{"class":722},[574,3501,3502],{"class":583},":42}",[574,3504,3505],{"class":722},"\\n\\n",[574,3507,743],{"class":718},[574,3509,547],{"class":718},[574,3511,3512,3514,3517,3519,3522,3524,3526,3528,3530,3532,3534,3536,3538,3540,3542,3544,3546,3548,3550,3552,3555,3557,3559,3561,3563],{"class":576,"line":803},[574,3513,1213],{"class":718},[574,3515,3516],{"class":583},"id: 2",[574,3518,3466],{"class":722},[574,3520,3521],{"class":583},"event: order.shipped",[574,3523,3466],{"class":722},[574,3525,3474],{"class":583},[574,3527,3477],{"class":722},[574,3529,2318],{"class":583},[574,3531,3477],{"class":722},[574,3533,824],{"class":583},[574,3535,3477],{"class":722},[574,3537,3488],{"class":583},[574,3539,3477],{"class":722},[574,3541,726],{"class":583},[574,3543,3477],{"class":722},[574,3545,2375],{"class":583},[574,3547,3477],{"class":722},[574,3549,824],{"class":583},[574,3551,3477],{"class":722},[574,3553,3554],{"class":583},"DHL",[574,3556,3477],{"class":722},[574,3558,1007],{"class":583},[574,3560,3505],{"class":722},[574,3562,743],{"class":718},[574,3564,547],{"class":718},[574,3566,3567,3570],{"class":576,"line":840},[574,3568,3569],{"class":722},"]",[574,3571,746],{"class":718},[574,3573,3574],{"class":576,"line":853},[574,3575,778],{"emptyLinePlaceholder":777},[574,3577,3578,3580,3582,3584,3586,3589,3591,3593,3595,3598,3600,3603,3605,3607,3609,3612],{"class":576,"line":860},[574,3579,785],{"class":784},[574,3581,1479],{"class":722},[574,3583,791],{"class":718},[574,3585,719],{"class":718},[574,3587,3588],{"class":718}," ...",[574,3590,2840],{"class":722},[574,3592,701],{"class":718},[574,3594,1669],{"class":797},[574,3596,3597],{"class":722},"(frames)",[574,3599,726],{"class":718},[574,3601,3602],{"class":820}," reconnect",[574,3604,824],{"class":718},[574,3606,2931],{"class":722},[574,3608,701],{"class":718},[574,3610,3611],{"class":722},"none ",[574,3613,3614],{"class":718},"};\n",[574,3616,3617,3619,3621,3623,3625,3627,3629,3631,3634],{"class":576,"line":865},[574,3618,785],{"class":784},[574,3620,788],{"class":722},[574,3622,791],{"class":718},[574,3624,794],{"class":718},[574,3626,1827],{"class":797},[574,3628,1754],{"class":722},[574,3630,726],{"class":718},[574,3632,3633],{"class":722}," testEvents)",[574,3635,746],{"class":718},[574,3637,3638],{"class":576,"line":895},[574,3639,778],{"emptyLinePlaceholder":777},[574,3641,3642,3644,3646,3648,3650,3652,3654,3656,3658,3660,3662,3664,3667,3669,3671],{"class":576,"line":900},[574,3643,2551],{"class":714},[574,3645,2554],{"class":714},[574,3647,965],{"class":722},[574,3649,785],{"class":784},[574,3651,2561],{"class":722},[574,3653,2564],{"class":718},[574,3655,875],{"class":722},[574,3657,701],{"class":718},[574,3659,535],{"class":797},[574,3661,814],{"class":722},[574,3663,743],{"class":718},[574,3665,3666],{"class":583},"\u002Ffeed",[574,3668,743],{"class":718},[574,3670,2600],{"class":722},[574,3672,1295],{"class":718},[574,3674,3675,3677,3679,3681,3683,3685,3687,3689,3691,3694,3696,3698,3700],{"class":576,"line":940},[574,3676,988],{"class":722},[574,3678,701],{"class":718},[574,3680,923],{"class":797},[574,3682,814],{"class":820},[574,3684,2283],{"class":722},[574,3686,701],{"class":718},[574,3688,2283],{"class":722},[574,3690,726],{"class":718},[574,3692,3693],{"class":722}," event",[574,3695,701],{"class":718},[574,3697,969],{"class":722},[574,3699,675],{"class":820},[574,3701,746],{"class":718},[574,3703,3704],{"class":576,"line":945},[574,3705,2661],{"class":718},[669,3707,3709],{"id":3708},"see-also","See also",[3711,3712,3713,3730,3741,3755],"ul",{},[3714,3715,3716,3719,3720,3722,3723,3725,3726,3729],"li",{},[3717,3718,271],"a",{"href":272}," — declare the ",[503,3721,505],{}," this page's\n",[503,3724,1160],{}," types itself off, including the per-kind ",[503,3727,3728],{},"WebSocketMessage\u003CC, \"kind\">"," method binding on the\nserver side.",[3714,3731,3732,3719,3734,3736,3737,3740],{},[3717,3733,275],{"href":276},[503,3735,509],{}," class this page's\n",[503,3738,3739],{},"SseClient"," validates against, including the durable cross-isolate broadcast tier.",[3714,3742,3743,3746,3747,3750,3751,3754],{},[3717,3744,3745],{"href":73},"REST client"," — the ",[503,3748,3749],{},"Contract"," self-client (",[503,3752,3753],{},"new SomeApi(transport)",") for request\u002Fresponse\nroutes, the non-realtime sibling of the two clients here.",[3714,3756,3757,3765,3766,3768,3769,3772,3773,3776,3777,3779,3780,3783],{},[3717,3758,3762],{"href":3759,"rel":3760},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fflagship\u002Fapps\u002Fcloudflare",[3761],"nofollow",[1154,3763,3764],{},"The flagship Cloudflare app","\n— a real end-to-end test where both clients parse actual server-produced wire frames: a ",[503,3767,1160],{}," (mock\ntransport) decoding a real ",[503,3770,3771],{},"seat.map"," frame off the ",[503,3774,3775],{},"WebSocketDispatcher",", and an ",[503,3778,3739],{}," (mock\ntransport) decoding real ",[503,3781,3782],{},"seats.remaining"," frames off a live SSE response.",[3785,3786,3787],"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 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 .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 .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}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":570,"searchDepth":590,"depth":590,"links":3789},[3790,3798,3808],{"id":671,"depth":590,"text":3791,"children":3792},"Typed WebSocket client (@heximon\u002Fclient\u002Fws)",[3793,3794,3795,3796,3797],{"id":679,"depth":597,"text":680},{"id":1335,"depth":597,"text":1336},{"id":1423,"depth":597,"text":1424},{"id":1533,"depth":597,"text":1534},{"id":1620,"depth":597,"text":1621},{"id":1793,"depth":590,"text":3799,"children":3800},"Typed SSE client (@heximon\u002Fclient\u002Fsse)",[3801,3802,3803,3804,3805,3806,3807],{"id":1799,"depth":597,"text":1800},{"id":2204,"depth":597,"text":2205},{"id":2513,"depth":597,"text":2514},{"id":2667,"depth":597,"text":2668},{"id":2834,"depth":597,"text":2835},{"id":3104,"depth":597,"text":3105},{"id":3397,"depth":597,"text":3398},{"id":3708,"depth":590,"text":3709},"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.","md",null,{},{"icon":283},{"title":280,"description":3809},"hQbj9C2-F8-B8Ad16196NFWv1fGUqpFpsoDdJ1SnV9Y",[3817,3819],{"title":275,"path":276,"stem":277,"description":3818,"icon":278,"children":-1},"Stream typed events server-to-client over plain HTTP with EventStream, EventChannel, heartbeats and Last-Event-ID resume, plus a durable-backed ServerSentEventsHandler for cross-isolate broadcast.",{"title":285,"path":286,"stem":287,"description":3820,"icon":259,"children":-1},"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.",1783300761903]