[{"data":1,"prerenderedAt":2884},["ShallowReactive",2],{"navigation_docs":3,"-docs-recipes-reliable-integration-events":493,"-docs-recipes-reliable-integration-events-surround":2879},[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":480,"body":495,"description":2872,"extension":2873,"links":2874,"meta":2875,"navigation":2876,"path":481,"seo":2877,"stem":482,"__hash__":2878},"docs\u002Fdocs\u002F09.recipes\u002F13.reliable-integration-events.md",{"type":496,"value":497,"toc":2854},"minimark",[498,502,507,596,614,618,626,731,746,750,762,907,921,925,947,954,967,1132,1138,1245,1262,1279,1285,1297,1560,1582,1701,1707,1769,1788,1809,1819,1888,1894,1906,2187,2209,2230,2530,2537,2547,2555,2565,2625,2629,2641,2670,2673,2686,2690,2697,2766,2794,2798,2850],[499,500,501],"p",{},"Fire-and-forget integration events work fine until the process crashes between committing an aggregate write\nand dispatching the event. When that happens, the write lands but the downstream handler never runs — a ghost\nrecord that never triggers its consequences. The transactional outbox closes that gap: the event persists in\nthe same transaction as the aggregate, so either both commit or neither does.",[503,504,506],"h2",{"id":505},"the-problem-with-fire-and-forget","The problem with fire-and-forget",[508,509,514],"pre",{"className":510,"code":511,"language":512,"meta":513,"style":513},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","await this.repository.save(order);\nawait this.orderPlaced.publish({ orderId: order.id }); \u002F\u002F lost on crash here\n","ts","",[515,516,517,547],"code",{"__ignoreMap":513},[518,519,522,526,530,534,537,541,544],"span",{"class":520,"line":521},"line",1,[518,523,525],{"class":524},"s7zQu","await",[518,527,529],{"class":528},"sMK4o"," this.",[518,531,533],{"class":532},"sTEyZ","repository",[518,535,536],{"class":528},".",[518,538,540],{"class":539},"s2Zo4","save",[518,542,543],{"class":532},"(order)",[518,545,546],{"class":528},";\n",[518,548,550,552,554,557,559,562,565,568,572,575,578,580,583,586,589,592],{"class":520,"line":549},2,[518,551,525],{"class":524},[518,553,529],{"class":528},[518,555,556],{"class":532},"orderPlaced",[518,558,536],{"class":528},[518,560,561],{"class":539},"publish",[518,563,564],{"class":532},"(",[518,566,567],{"class":528},"{",[518,569,571],{"class":570},"swJcz"," orderId",[518,573,574],{"class":528},":",[518,576,577],{"class":532}," order",[518,579,536],{"class":528},[518,581,582],{"class":532},"id ",[518,584,585],{"class":528},"}",[518,587,588],{"class":532},")",[518,590,591],{"class":528},";",[518,593,595],{"class":594},"sHwdD"," \u002F\u002F lost on crash here\n",[499,597,598,599,602,603,606,607,610,611,613],{},"The producer is a typed ",[515,600,601],{},"IntegrationEvent"," class injected by identity (",[515,604,605],{},"this.orderPlaced","), and\n",[515,608,609],{},"publish(data)"," routes through the bound transport. If the process terminates after ",[515,612,540],{}," returns but before\nthe transport delivers the event, the order exists in the database but the event is gone. The downstream\ncontext never learns the order was placed, and no error is visible anywhere.",[503,615,617],{"id":616},"the-outbox-pattern","The outbox pattern",[499,619,620,621,625],{},"Instead of emitting directly to the queue, the event is written to an ",[622,623,624],"strong",{},"outbox table"," in the same database\ntransaction as the aggregate write. After the commit, a relay picks up pending rows and dispatches them. A\ncrash after the commit leaves the outbox row durable — the relay replays it on the next boot:",[508,627,629],{"className":510,"code":628,"language":512,"meta":513,"style":513},"await this.repository.runInTransaction(async () => {\n  await this.repository.save(order);\n  await this.orderPlaced.publish({ orderId: order.id }); \u002F\u002F buffered, not yet delivered\n}); \u002F\u002F onBeforeCommit: outbox row written atomically; onCommit: relay scheduled\n",[515,630,631,659,681,719],{"__ignoreMap":513},[518,632,633,635,637,639,641,644,646,650,653,656],{"class":520,"line":521},[518,634,525],{"class":524},[518,636,529],{"class":528},[518,638,533],{"class":532},[518,640,536],{"class":528},[518,642,643],{"class":539},"runInTransaction",[518,645,564],{"class":532},[518,647,649],{"class":648},"spNyl","async",[518,651,652],{"class":528}," ()",[518,654,655],{"class":648}," =>",[518,657,658],{"class":528}," {\n",[518,660,661,664,666,668,670,672,674,677,679],{"class":520,"line":549},[518,662,663],{"class":524},"  await",[518,665,529],{"class":528},[518,667,533],{"class":532},[518,669,536],{"class":528},[518,671,540],{"class":539},[518,673,564],{"class":570},[518,675,676],{"class":532},"order",[518,678,588],{"class":570},[518,680,546],{"class":528},[518,682,684,686,688,690,692,694,696,698,700,702,704,706,709,712,714,716],{"class":520,"line":683},3,[518,685,663],{"class":524},[518,687,529],{"class":528},[518,689,556],{"class":532},[518,691,536],{"class":528},[518,693,561],{"class":539},[518,695,564],{"class":570},[518,697,567],{"class":528},[518,699,571],{"class":570},[518,701,574],{"class":528},[518,703,577],{"class":532},[518,705,536],{"class":528},[518,707,708],{"class":532},"id",[518,710,711],{"class":528}," }",[518,713,588],{"class":570},[518,715,591],{"class":528},[518,717,718],{"class":594}," \u002F\u002F buffered, not yet delivered\n",[518,720,722,724,726,728],{"class":520,"line":721},4,[518,723,585],{"class":528},[518,725,588],{"class":532},[518,727,591],{"class":528},[518,729,730],{"class":594}," \u002F\u002F onBeforeCommit: outbox row written atomically; onCommit: relay scheduled\n",[499,732,733,734,737,738,741,742,745],{},"The producer call is unchanged from the in-process default — the same ",[515,735,736],{},"await this.orderPlaced.publish(...)",".\nThe difference is entirely in which ",[515,739,740],{},"IntegrationEventTransport"," the event publishes through. The relay\ndelivers ",[622,743,744],{},"after"," the commit, so the downstream handler receives the event if and only if the aggregate\nwrite committed.",[503,747,749],{"id":748},"the-producer-event","The producer event",[499,751,598,752,754,755,757,758,761],{},[515,753,601],{}," class — one class per cross-context event, carrying a plain-interface\npayload. The orders controller injects it by class identity and calls ",[515,756,609],{},"; the compiler bakes the\nprefixed channel from the ",[515,759,760],{},"\"order.placed\""," type argument and wires the publisher over the bound transport:",[508,763,766],{"className":510,"code":764,"filename":765,"language":512,"meta":513,"style":513},"import { IntegrationEvent } from \"@heximon\u002Fintegration\";\n\nexport interface OrderPlacedPayload {\n  readonly orderId: string;\n  readonly customer: string;\n  readonly totalCents: number;\n}\n\nexport class OrderPlaced extends IntegrationEvent\u003C\"order.placed\", OrderPlacedPayload> {}\n","src\u002Forders\u002Fevents.ts",[515,767,768,796,802,816,830,844,859,865,870],{"__ignoreMap":513},[518,769,770,773,776,779,781,784,787,791,794],{"class":520,"line":521},[518,771,772],{"class":524},"import",[518,774,775],{"class":528}," {",[518,777,778],{"class":532}," IntegrationEvent",[518,780,711],{"class":528},[518,782,783],{"class":524}," from",[518,785,786],{"class":528}," \"",[518,788,790],{"class":789},"sfazB","@heximon\u002Fintegration",[518,792,793],{"class":528},"\"",[518,795,546],{"class":528},[518,797,798],{"class":520,"line":549},[518,799,801],{"emptyLinePlaceholder":800},true,"\n",[518,803,804,807,810,814],{"class":520,"line":683},[518,805,806],{"class":524},"export",[518,808,809],{"class":648}," interface",[518,811,813],{"class":812},"sBMFI"," OrderPlacedPayload",[518,815,658],{"class":528},[518,817,818,821,823,825,828],{"class":520,"line":721},[518,819,820],{"class":648},"  readonly",[518,822,571],{"class":570},[518,824,574],{"class":528},[518,826,827],{"class":812}," string",[518,829,546],{"class":528},[518,831,833,835,838,840,842],{"class":520,"line":832},5,[518,834,820],{"class":648},[518,836,837],{"class":570}," customer",[518,839,574],{"class":528},[518,841,827],{"class":812},[518,843,546],{"class":528},[518,845,847,849,852,854,857],{"class":520,"line":846},6,[518,848,820],{"class":648},[518,850,851],{"class":570}," totalCents",[518,853,574],{"class":528},[518,855,856],{"class":812}," number",[518,858,546],{"class":528},[518,860,862],{"class":520,"line":861},7,[518,863,864],{"class":528},"}\n",[518,866,868],{"class":520,"line":867},8,[518,869,801],{"emptyLinePlaceholder":800},[518,871,873,875,878,881,884,886,889,891,894,896,899,901,904],{"class":520,"line":872},9,[518,874,806],{"class":524},[518,876,877],{"class":648}," class",[518,879,880],{"class":812}," OrderPlaced",[518,882,883],{"class":648}," extends",[518,885,778],{"class":812},[518,887,888],{"class":528},"\u003C",[518,890,793],{"class":528},[518,892,893],{"class":789},"order.placed",[518,895,793],{"class":528},[518,897,898],{"class":528},",",[518,900,813],{"class":812},[518,902,903],{"class":528},">",[518,905,906],{"class":528}," {}\n",[499,908,909,910,913,914,917,918,536],{},"List it under ",[515,911,912],{},"integration: { events }"," in the producing module (alongside the outbox bindings below). The\nmatching consumer is an unchanged ",[515,915,916],{},"IntegrationEventHandler\u003C\"order.placed\", OrderPlacedPayload>"," in the\ndownstream context (name-first type argument), listed under ",[515,919,920],{},"integration: { eventHandlers }",[503,922,924],{"id":923},"the-outbox-wiring","The outbox wiring",[499,926,927,928,930,931,934,935,938,939,942,943,946],{},"The transactional outbox tier ships in ",[515,929,790],{}," as the ",[515,932,933],{},"OutboxStore"," \u002F ",[515,936,937],{},"OutboxRelay"," \u002F\n",[515,940,941],{},"OutboxIntegrationEventTransport"," classes (plus the relay's in-process delivery terminal). Because the compiler\nreads constructor signatures from ",[622,944,945],{},"app source",", you bind them by authoring thin nominal-satisfier subclasses in\nyour own module:",[948,949,951,953],"h3",{"id":950},"outboxstore-persistence",[515,952,933],{}," — persistence",[499,955,956,958,959,962,963,966],{},[515,957,933],{}," is the abstract DI token. Implement it (or extend ",[515,960,961],{},"DrizzleOutboxStore"," from\n",[515,964,965],{},"@heximon\u002Fdrizzle\u002Fcore",") with a concrete subclass that exposes its own constructor:",[508,968,971],{"className":510,"code":969,"filename":970,"language":512,"meta":513,"style":513},"import { OutboxStore } from \"@heximon\u002Fintegration\";\nimport { DrizzleOutboxStore } from \"@heximon\u002Fdrizzle\u002Fcore\";\nimport { Database } from \"..\u002Fdatabase\u002Fdatabase\";\nimport { outbox } from \".\u002Fschema\";\n\nexport class AppOutboxStore extends DrizzleOutboxStore implements OutboxStore {\n  public constructor(database: Database) {\n    super(database, outbox);\n  }\n}\n","src\u002Foutbox\u002Foutbox-store.ts",[515,972,973,994,1015,1037,1059,1063,1083,1105,1122,1127],{"__ignoreMap":513},[518,974,975,977,979,982,984,986,988,990,992],{"class":520,"line":521},[518,976,772],{"class":524},[518,978,775],{"class":528},[518,980,981],{"class":532}," OutboxStore",[518,983,711],{"class":528},[518,985,783],{"class":524},[518,987,786],{"class":528},[518,989,790],{"class":789},[518,991,793],{"class":528},[518,993,546],{"class":528},[518,995,996,998,1000,1003,1005,1007,1009,1011,1013],{"class":520,"line":549},[518,997,772],{"class":524},[518,999,775],{"class":528},[518,1001,1002],{"class":532}," DrizzleOutboxStore",[518,1004,711],{"class":528},[518,1006,783],{"class":524},[518,1008,786],{"class":528},[518,1010,965],{"class":789},[518,1012,793],{"class":528},[518,1014,546],{"class":528},[518,1016,1017,1019,1021,1024,1026,1028,1030,1033,1035],{"class":520,"line":683},[518,1018,772],{"class":524},[518,1020,775],{"class":528},[518,1022,1023],{"class":532}," Database",[518,1025,711],{"class":528},[518,1027,783],{"class":524},[518,1029,786],{"class":528},[518,1031,1032],{"class":789},"..\u002Fdatabase\u002Fdatabase",[518,1034,793],{"class":528},[518,1036,546],{"class":528},[518,1038,1039,1041,1043,1046,1048,1050,1052,1055,1057],{"class":520,"line":721},[518,1040,772],{"class":524},[518,1042,775],{"class":528},[518,1044,1045],{"class":532}," outbox",[518,1047,711],{"class":528},[518,1049,783],{"class":524},[518,1051,786],{"class":528},[518,1053,1054],{"class":789},".\u002Fschema",[518,1056,793],{"class":528},[518,1058,546],{"class":528},[518,1060,1061],{"class":520,"line":832},[518,1062,801],{"emptyLinePlaceholder":800},[518,1064,1065,1067,1069,1072,1074,1076,1079,1081],{"class":520,"line":846},[518,1066,806],{"class":524},[518,1068,877],{"class":648},[518,1070,1071],{"class":812}," AppOutboxStore",[518,1073,883],{"class":648},[518,1075,1002],{"class":812},[518,1077,1078],{"class":648}," implements",[518,1080,981],{"class":812},[518,1082,658],{"class":528},[518,1084,1085,1088,1091,1093,1097,1099,1101,1103],{"class":520,"line":861},[518,1086,1087],{"class":648},"  public",[518,1089,1090],{"class":648}," constructor",[518,1092,564],{"class":528},[518,1094,1096],{"class":1095},"sHdIc","database",[518,1098,574],{"class":528},[518,1100,1023],{"class":812},[518,1102,588],{"class":528},[518,1104,658],{"class":528},[518,1106,1107,1110,1112,1114,1116,1118,1120],{"class":520,"line":867},[518,1108,1109],{"class":532},"    super",[518,1111,564],{"class":570},[518,1113,1096],{"class":532},[518,1115,898],{"class":528},[518,1117,1045],{"class":532},[518,1119,588],{"class":570},[518,1121,546],{"class":528},[518,1123,1124],{"class":520,"line":872},[518,1125,1126],{"class":528},"  }\n",[518,1128,1130],{"class":520,"line":1129},10,[518,1131,864],{"class":528},[499,1133,1134,1135,574],{},"Add the outbox columns to your Drizzle schema by spreading ",[515,1136,1137],{},"outboxColumns()",[508,1139,1142],{"className":510,"code":1140,"filename":1141,"language":512,"meta":513,"style":513},"import { outboxColumns } from \"@heximon\u002Fdrizzle\u002Fsqlite-core\"; \u002F\u002F or pg-core \u002F mysql-core\nimport { sqliteTable } from \"drizzle-orm\u002Fsqlite-core\";\n\nexport const outbox = sqliteTable(\"outbox\", {\n  ...outboxColumns(),\n});\n","src\u002Fdatabase\u002Fschema.ts",[515,1143,1144,1169,1191,1195,1223,1237],{"__ignoreMap":513},[518,1145,1146,1148,1150,1153,1155,1157,1159,1162,1164,1166],{"class":520,"line":521},[518,1147,772],{"class":524},[518,1149,775],{"class":528},[518,1151,1152],{"class":532}," outboxColumns",[518,1154,711],{"class":528},[518,1156,783],{"class":524},[518,1158,786],{"class":528},[518,1160,1161],{"class":789},"@heximon\u002Fdrizzle\u002Fsqlite-core",[518,1163,793],{"class":528},[518,1165,591],{"class":528},[518,1167,1168],{"class":594}," \u002F\u002F or pg-core \u002F mysql-core\n",[518,1170,1171,1173,1175,1178,1180,1182,1184,1187,1189],{"class":520,"line":549},[518,1172,772],{"class":524},[518,1174,775],{"class":528},[518,1176,1177],{"class":532}," sqliteTable",[518,1179,711],{"class":528},[518,1181,783],{"class":524},[518,1183,786],{"class":528},[518,1185,1186],{"class":789},"drizzle-orm\u002Fsqlite-core",[518,1188,793],{"class":528},[518,1190,546],{"class":528},[518,1192,1193],{"class":520,"line":683},[518,1194,801],{"emptyLinePlaceholder":800},[518,1196,1197,1199,1202,1205,1208,1210,1212,1214,1217,1219,1221],{"class":520,"line":721},[518,1198,806],{"class":524},[518,1200,1201],{"class":648}," const",[518,1203,1204],{"class":532}," outbox ",[518,1206,1207],{"class":528},"=",[518,1209,1177],{"class":539},[518,1211,564],{"class":532},[518,1213,793],{"class":528},[518,1215,1216],{"class":789},"outbox",[518,1218,793],{"class":528},[518,1220,898],{"class":528},[518,1222,658],{"class":528},[518,1224,1225,1228,1231,1234],{"class":520,"line":832},[518,1226,1227],{"class":528},"  ...",[518,1229,1230],{"class":539},"outboxColumns",[518,1232,1233],{"class":532},"()",[518,1235,1236],{"class":528},",\n",[518,1238,1239,1241,1243],{"class":520,"line":846},[518,1240,585],{"class":528},[518,1242,588],{"class":532},[518,1244,546],{"class":528},[499,1246,1247,1249,1250,1253,1254,1257,1258,1261],{},[515,1248,1137],{}," includes ",[515,1251,1252],{},"correlationId"," and ",[515,1255,1256],{},"causationId"," as nullable columns (new rows carry the\nambient tracing ids; pre-existing rows read back as ",[515,1259,1260],{},"null","). For an existing outbox table, add a\nmigration:",[508,1263,1267],{"className":1264,"code":1265,"language":1266,"meta":513,"style":513},"language-sql shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","ALTER TABLE outbox ADD COLUMN correlation_id TEXT;\nALTER TABLE outbox ADD COLUMN causation_id TEXT;\n","sql",[515,1268,1269,1274],{"__ignoreMap":513},[518,1270,1271],{"class":520,"line":521},[518,1272,1273],{},"ALTER TABLE outbox ADD COLUMN correlation_id TEXT;\n",[518,1275,1276],{"class":520,"line":549},[518,1277,1278],{},"ALTER TABLE outbox ADD COLUMN causation_id TEXT;\n",[948,1280,1282,1284],{"id":1281},"outboxrelay-and-its-in-process-terminal",[515,1283,937],{}," and its in-process terminal",[499,1286,1287,1289,1290,1292,1293,1296],{},[515,1288,937],{}," drains pending rows after each commit and replays rows left pending on boot, delivering each\nclaimed row through an ",[515,1291,740],{}," terminal. That terminal is the relay's own in-process\ndelivery target — a concrete ",[515,1294,1295],{},"MemoryIntegrationEventTransport"," subclass bound separately from the producer's\ntransport (the producer publishes through the outbox transport; the relay fans each drained row out through the\nin-process channel table):",[508,1298,1301],{"className":510,"code":1299,"filename":1300,"language":512,"meta":513,"style":513},"import { Context } from \"@heximon\u002Fruntime\";\nimport { OutboxRelay } from \"@heximon\u002Fintegration\";\nimport { QueueChannelDispatcher } from \"@heximon\u002Fqueue\";\nimport { MemoryIntegrationEventTransport } from \"@heximon\u002Fqueue\u002Fmemory\";\nimport { AppOutboxStore } from \".\u002Foutbox-store\";\n\nexport class AppRelayTransport extends MemoryIntegrationEventTransport {\n  public constructor(dispatcher: QueueChannelDispatcher) {\n    super(dispatcher);\n  }\n}\n\nexport class AppOutboxRelay extends OutboxRelay {\n  public constructor(store: AppOutboxStore, target: AppRelayTransport, context: Context) {\n    super(store, target, context);\n  }\n}\n","src\u002Foutbox\u002Foutbox-relay.ts",[515,1302,1303,1325,1346,1368,1390,1411,1415,1430,1449,1461,1465,1470,1475,1491,1529,1550,1555],{"__ignoreMap":513},[518,1304,1305,1307,1309,1312,1314,1316,1318,1321,1323],{"class":520,"line":521},[518,1306,772],{"class":524},[518,1308,775],{"class":528},[518,1310,1311],{"class":532}," Context",[518,1313,711],{"class":528},[518,1315,783],{"class":524},[518,1317,786],{"class":528},[518,1319,1320],{"class":789},"@heximon\u002Fruntime",[518,1322,793],{"class":528},[518,1324,546],{"class":528},[518,1326,1327,1329,1331,1334,1336,1338,1340,1342,1344],{"class":520,"line":549},[518,1328,772],{"class":524},[518,1330,775],{"class":528},[518,1332,1333],{"class":532}," OutboxRelay",[518,1335,711],{"class":528},[518,1337,783],{"class":524},[518,1339,786],{"class":528},[518,1341,790],{"class":789},[518,1343,793],{"class":528},[518,1345,546],{"class":528},[518,1347,1348,1350,1352,1355,1357,1359,1361,1364,1366],{"class":520,"line":683},[518,1349,772],{"class":524},[518,1351,775],{"class":528},[518,1353,1354],{"class":532}," QueueChannelDispatcher",[518,1356,711],{"class":528},[518,1358,783],{"class":524},[518,1360,786],{"class":528},[518,1362,1363],{"class":789},"@heximon\u002Fqueue",[518,1365,793],{"class":528},[518,1367,546],{"class":528},[518,1369,1370,1372,1374,1377,1379,1381,1383,1386,1388],{"class":520,"line":721},[518,1371,772],{"class":524},[518,1373,775],{"class":528},[518,1375,1376],{"class":532}," MemoryIntegrationEventTransport",[518,1378,711],{"class":528},[518,1380,783],{"class":524},[518,1382,786],{"class":528},[518,1384,1385],{"class":789},"@heximon\u002Fqueue\u002Fmemory",[518,1387,793],{"class":528},[518,1389,546],{"class":528},[518,1391,1392,1394,1396,1398,1400,1402,1404,1407,1409],{"class":520,"line":832},[518,1393,772],{"class":524},[518,1395,775],{"class":528},[518,1397,1071],{"class":532},[518,1399,711],{"class":528},[518,1401,783],{"class":524},[518,1403,786],{"class":528},[518,1405,1406],{"class":789},".\u002Foutbox-store",[518,1408,793],{"class":528},[518,1410,546],{"class":528},[518,1412,1413],{"class":520,"line":846},[518,1414,801],{"emptyLinePlaceholder":800},[518,1416,1417,1419,1421,1424,1426,1428],{"class":520,"line":861},[518,1418,806],{"class":524},[518,1420,877],{"class":648},[518,1422,1423],{"class":812}," AppRelayTransport",[518,1425,883],{"class":648},[518,1427,1376],{"class":812},[518,1429,658],{"class":528},[518,1431,1432,1434,1436,1438,1441,1443,1445,1447],{"class":520,"line":867},[518,1433,1087],{"class":648},[518,1435,1090],{"class":648},[518,1437,564],{"class":528},[518,1439,1440],{"class":1095},"dispatcher",[518,1442,574],{"class":528},[518,1444,1354],{"class":812},[518,1446,588],{"class":528},[518,1448,658],{"class":528},[518,1450,1451,1453,1455,1457,1459],{"class":520,"line":872},[518,1452,1109],{"class":532},[518,1454,564],{"class":570},[518,1456,1440],{"class":532},[518,1458,588],{"class":570},[518,1460,546],{"class":528},[518,1462,1463],{"class":520,"line":1129},[518,1464,1126],{"class":528},[518,1466,1468],{"class":520,"line":1467},11,[518,1469,864],{"class":528},[518,1471,1473],{"class":520,"line":1472},12,[518,1474,801],{"emptyLinePlaceholder":800},[518,1476,1478,1480,1482,1485,1487,1489],{"class":520,"line":1477},13,[518,1479,806],{"class":524},[518,1481,877],{"class":648},[518,1483,1484],{"class":812}," AppOutboxRelay",[518,1486,883],{"class":648},[518,1488,1333],{"class":812},[518,1490,658],{"class":528},[518,1492,1494,1496,1498,1500,1503,1505,1507,1509,1512,1514,1516,1518,1521,1523,1525,1527],{"class":520,"line":1493},14,[518,1495,1087],{"class":648},[518,1497,1090],{"class":648},[518,1499,564],{"class":528},[518,1501,1502],{"class":1095},"store",[518,1504,574],{"class":528},[518,1506,1071],{"class":812},[518,1508,898],{"class":528},[518,1510,1511],{"class":1095}," target",[518,1513,574],{"class":528},[518,1515,1423],{"class":812},[518,1517,898],{"class":528},[518,1519,1520],{"class":1095}," context",[518,1522,574],{"class":528},[518,1524,1311],{"class":812},[518,1526,588],{"class":528},[518,1528,658],{"class":528},[518,1530,1532,1534,1536,1538,1540,1542,1544,1546,1548],{"class":520,"line":1531},15,[518,1533,1109],{"class":532},[518,1535,564],{"class":570},[518,1537,1502],{"class":532},[518,1539,898],{"class":528},[518,1541,1511],{"class":532},[518,1543,898],{"class":528},[518,1545,1520],{"class":532},[518,1547,588],{"class":570},[518,1549,546],{"class":528},[518,1551,1553],{"class":520,"line":1552},16,[518,1554,1126],{"class":528},[518,1556,1558],{"class":520,"line":1557},17,[518,1559,864],{"class":528},[499,1561,1562,1563,1566,1567,1570,1571,1573,1574,1577,1578,1581],{},"On Cloudflare Workers, bind ",[515,1564,1565],{},"CloudflareQueueIntegrationEventTransport"," (",[515,1568,1569],{},"@heximon\u002Fqueue\u002Fcloudflare",") as the\nrelay's terminal instead — the durable counterpart of ",[515,1572,1295],{},". Rather than running the\nhandlers inline on the producing isolate, it ",[515,1575,1576],{},"send","s each drained row onto the app's own Cloudflare Queue, and\nthat same worker's ",[515,1579,1580],{},"queue(batch, env, ctx)"," export drains it later, decoupled from the producing request and\ncovered by the platform's own retry \u002F backoff \u002F DLQ:",[508,1583,1586],{"className":510,"code":1584,"filename":1585,"language":512,"meta":513,"style":513},"import { Platform } from \"@heximon\u002Fruntime\";\nimport { CloudflareQueueIntegrationEventTransport } from \"@heximon\u002Fqueue\u002Fcloudflare\";\n\n{\n  provide: CloudflareQueueIntegrationEventTransport,\n  useFactory: (): CloudflareQueueIntegrationEventTransport =>\n    new CloudflareQueueIntegrationEventTransport(Platform.binding(\"OUTBOX_QUEUE\")),\n},\n","src\u002Fdatabase\u002Fdatabase.module.ts",[515,1587,1588,1609,1630,1634,1639,1650,1665,1696],{"__ignoreMap":513},[518,1589,1590,1592,1594,1597,1599,1601,1603,1605,1607],{"class":520,"line":521},[518,1591,772],{"class":524},[518,1593,775],{"class":528},[518,1595,1596],{"class":532}," Platform",[518,1598,711],{"class":528},[518,1600,783],{"class":524},[518,1602,786],{"class":528},[518,1604,1320],{"class":789},[518,1606,793],{"class":528},[518,1608,546],{"class":528},[518,1610,1611,1613,1615,1618,1620,1622,1624,1626,1628],{"class":520,"line":549},[518,1612,772],{"class":524},[518,1614,775],{"class":528},[518,1616,1617],{"class":532}," CloudflareQueueIntegrationEventTransport",[518,1619,711],{"class":528},[518,1621,783],{"class":524},[518,1623,786],{"class":528},[518,1625,1569],{"class":789},[518,1627,793],{"class":528},[518,1629,546],{"class":528},[518,1631,1632],{"class":520,"line":683},[518,1633,801],{"emptyLinePlaceholder":800},[518,1635,1636],{"class":520,"line":721},[518,1637,1638],{"class":528},"{\n",[518,1640,1641,1644,1646,1648],{"class":520,"line":832},[518,1642,1643],{"class":812},"  provide",[518,1645,574],{"class":528},[518,1647,1617],{"class":532},[518,1649,1236],{"class":528},[518,1651,1652,1655,1657,1660,1662],{"class":520,"line":846},[518,1653,1654],{"class":812},"  useFactory",[518,1656,574],{"class":528},[518,1658,1659],{"class":528}," ():",[518,1661,1617],{"class":812},[518,1663,1664],{"class":648}," =>\n",[518,1666,1667,1670,1672,1674,1677,1679,1682,1684,1686,1689,1691,1694],{"class":520,"line":861},[518,1668,1669],{"class":528},"    new",[518,1671,1617],{"class":539},[518,1673,564],{"class":570},[518,1675,1676],{"class":532},"Platform",[518,1678,536],{"class":528},[518,1680,1681],{"class":539},"binding",[518,1683,564],{"class":570},[518,1685,793],{"class":528},[518,1687,1688],{"class":789},"OUTBOX_QUEUE",[518,1690,793],{"class":528},[518,1692,1693],{"class":570},"))",[518,1695,1236],{"class":528},[518,1697,1698],{"class":520,"line":867},[518,1699,1700],{"class":528},"},\n",[499,1702,1703,1704,574],{},"Declare the queue once in ",[515,1705,1706],{},"heximon.config.ts",[508,1708,1710],{"className":510,"code":1709,"filename":1706,"language":512,"meta":513,"style":513},"cloudflare: {\n  queues: [{ queue: \"ticketing-outbox\", binding: \"OUTBOX_QUEUE\" }],\n},\n",[515,1711,1712,1721,1765],{"__ignoreMap":513},[518,1713,1714,1717,1719],{"class":520,"line":521},[518,1715,1716],{"class":812},"cloudflare",[518,1718,574],{"class":528},[518,1720,658],{"class":528},[518,1722,1723,1726,1728,1731,1733,1736,1738,1740,1743,1745,1747,1750,1752,1754,1756,1758,1760,1763],{"class":520,"line":549},[518,1724,1725],{"class":812},"  queues",[518,1727,574],{"class":528},[518,1729,1730],{"class":570}," [",[518,1732,567],{"class":528},[518,1734,1735],{"class":570}," queue",[518,1737,574],{"class":528},[518,1739,786],{"class":528},[518,1741,1742],{"class":789},"ticketing-outbox",[518,1744,793],{"class":528},[518,1746,898],{"class":528},[518,1748,1749],{"class":570}," binding",[518,1751,574],{"class":528},[518,1753,786],{"class":528},[518,1755,1688],{"class":789},[518,1757,793],{"class":528},[518,1759,711],{"class":528},[518,1761,1762],{"class":570},"]",[518,1764,1236],{"class":528},[518,1766,1767],{"class":520,"line":683},[518,1768,1700],{"class":528},[499,1770,1771,1772,1775,1776,1779,1780,1783,1784,1787],{},"The consume side needs no new code — the worker's generic ",[515,1773,1774],{},"queue()"," export already routes a drained message by\nits ",[515,1777,1778],{},"channel"," into the same ",[515,1781,1782],{},"IntegrationEventHandler","s, and ",[515,1785,1786],{},"vp dev"," provisions the consumer in Miniflare too, so\nthe round trip runs locally against real workerd.",[499,1789,1790,1791,1566,1794,1797,1798,1800,1801,1804,1805,1808],{},"On Vercel Functions, bind ",[515,1792,1793],{},"VercelQueueIntegrationEventTransport",[515,1795,1796],{},"@heximon\u002Fqueue\u002Fvercel",") as the terminal\ninstead — the same durable pattern for a freezing platform. It ",[515,1799,1576],{},"s each drained row onto the app's own Vercel\nQueue — always onto the one fixed ",[515,1802,1803],{},"heximon-integration-events"," topic (the dotted integration channel is not a\nvalid Vercel topic name; it rides the envelope, which the consumer dispatches by) — and the separate generated\n",[515,1806,1807],{},"functions\u002Fqueues\u002Fconsumer.func"," drains it later, decoupled from the frozen-between-invocations function that\nproduced it.",[499,1810,1811,1812,1814,1815,1818],{},"The build registers the topic's consumer trigger automatically whenever the app binds its own transport. The\n",[515,1813,1576],{}," is an optional constructor argument (omit it to lazily import the ",[515,1816,1817],{},"@vercel\u002Fqueue"," SDK on first publish;\npass one — the in-process platform simulator — in tests):",[508,1820,1822],{"className":510,"code":1821,"filename":1585,"language":512,"meta":513,"style":513},"import { VercelQueueIntegrationEventTransport } from \"@heximon\u002Fqueue\u002Fvercel\";\n\n{\n  provide: VercelQueueIntegrationEventTransport,\n  useFactory: (): VercelQueueIntegrationEventTransport => new VercelQueueIntegrationEventTransport(),\n},\n",[515,1823,1824,1845,1849,1853,1863,1884],{"__ignoreMap":513},[518,1825,1826,1828,1830,1833,1835,1837,1839,1841,1843],{"class":520,"line":521},[518,1827,772],{"class":524},[518,1829,775],{"class":528},[518,1831,1832],{"class":532}," VercelQueueIntegrationEventTransport",[518,1834,711],{"class":528},[518,1836,783],{"class":524},[518,1838,786],{"class":528},[518,1840,1796],{"class":789},[518,1842,793],{"class":528},[518,1844,546],{"class":528},[518,1846,1847],{"class":520,"line":549},[518,1848,801],{"emptyLinePlaceholder":800},[518,1850,1851],{"class":520,"line":683},[518,1852,1638],{"class":528},[518,1854,1855,1857,1859,1861],{"class":520,"line":721},[518,1856,1643],{"class":812},[518,1858,574],{"class":528},[518,1860,1832],{"class":532},[518,1862,1236],{"class":528},[518,1864,1865,1867,1869,1871,1873,1875,1878,1880,1882],{"class":520,"line":832},[518,1866,1654],{"class":812},[518,1868,574],{"class":528},[518,1870,1659],{"class":528},[518,1872,1832],{"class":812},[518,1874,655],{"class":648},[518,1876,1877],{"class":528}," new",[518,1879,1832],{"class":539},[518,1881,1233],{"class":570},[518,1883,1236],{"class":528},[518,1885,1886],{"class":520,"line":846},[518,1887,1700],{"class":528},[948,1889,1891,1893],{"id":1890},"outboxintegrationeventtransport-the-transactional-producer-transport",[515,1892,941],{}," — the transactional producer transport",[499,1895,1896,1898,1899,1901,1902,1905],{},[515,1897,941],{}," is an ",[515,1900,740],{}," satisfier that wraps the\nbuffer → flush → schedule lifecycle. Binding it replaces the in-process memory default, so every typed\n",[515,1903,1904],{},"IntegrationEvent.publish"," becomes reliable:",[508,1907,1910],{"className":510,"code":1908,"filename":1909,"language":512,"meta":513,"style":513},"import { Context, TransactionContext } from \"@heximon\u002Fruntime\";\nimport { OutboxIntegrationEventTransport } from \"@heximon\u002Fintegration\";\nimport { IntegrationEventTransport } from \"@heximon\u002Fqueue\";\nimport { Database } from \"..\u002Fdatabase\u002Fdatabase\";\nimport { AppOutboxRelay } from \".\u002Foutbox-relay\";\nimport { AppOutboxStore } from \".\u002Foutbox-store\";\n\nexport class AppOutboxTransport\n  extends OutboxIntegrationEventTransport\n  implements IntegrationEventTransport\n{\n  public constructor(\n    database: Database,\n    store: AppOutboxStore,\n    relay: AppOutboxRelay,\n    context: Context,\n    transactionContext: TransactionContext,\n  ) {\n    super(database, store, relay, context, transactionContext);\n  }\n}\n","src\u002Foutbox\u002Foutbox.ts",[515,1911,1912,1937,1958,1979,1999,2020,2040,2044,2053,2061,2069,2073,2082,2093,2104,2115,2126,2137,2145,2177,2182],{"__ignoreMap":513},[518,1913,1914,1916,1918,1920,1922,1925,1927,1929,1931,1933,1935],{"class":520,"line":521},[518,1915,772],{"class":524},[518,1917,775],{"class":528},[518,1919,1311],{"class":532},[518,1921,898],{"class":528},[518,1923,1924],{"class":532}," TransactionContext",[518,1926,711],{"class":528},[518,1928,783],{"class":524},[518,1930,786],{"class":528},[518,1932,1320],{"class":789},[518,1934,793],{"class":528},[518,1936,546],{"class":528},[518,1938,1939,1941,1943,1946,1948,1950,1952,1954,1956],{"class":520,"line":549},[518,1940,772],{"class":524},[518,1942,775],{"class":528},[518,1944,1945],{"class":532}," OutboxIntegrationEventTransport",[518,1947,711],{"class":528},[518,1949,783],{"class":524},[518,1951,786],{"class":528},[518,1953,790],{"class":789},[518,1955,793],{"class":528},[518,1957,546],{"class":528},[518,1959,1960,1962,1964,1967,1969,1971,1973,1975,1977],{"class":520,"line":683},[518,1961,772],{"class":524},[518,1963,775],{"class":528},[518,1965,1966],{"class":532}," IntegrationEventTransport",[518,1968,711],{"class":528},[518,1970,783],{"class":524},[518,1972,786],{"class":528},[518,1974,1363],{"class":789},[518,1976,793],{"class":528},[518,1978,546],{"class":528},[518,1980,1981,1983,1985,1987,1989,1991,1993,1995,1997],{"class":520,"line":721},[518,1982,772],{"class":524},[518,1984,775],{"class":528},[518,1986,1023],{"class":532},[518,1988,711],{"class":528},[518,1990,783],{"class":524},[518,1992,786],{"class":528},[518,1994,1032],{"class":789},[518,1996,793],{"class":528},[518,1998,546],{"class":528},[518,2000,2001,2003,2005,2007,2009,2011,2013,2016,2018],{"class":520,"line":832},[518,2002,772],{"class":524},[518,2004,775],{"class":528},[518,2006,1484],{"class":532},[518,2008,711],{"class":528},[518,2010,783],{"class":524},[518,2012,786],{"class":528},[518,2014,2015],{"class":789},".\u002Foutbox-relay",[518,2017,793],{"class":528},[518,2019,546],{"class":528},[518,2021,2022,2024,2026,2028,2030,2032,2034,2036,2038],{"class":520,"line":846},[518,2023,772],{"class":524},[518,2025,775],{"class":528},[518,2027,1071],{"class":532},[518,2029,711],{"class":528},[518,2031,783],{"class":524},[518,2033,786],{"class":528},[518,2035,1406],{"class":789},[518,2037,793],{"class":528},[518,2039,546],{"class":528},[518,2041,2042],{"class":520,"line":861},[518,2043,801],{"emptyLinePlaceholder":800},[518,2045,2046,2048,2050],{"class":520,"line":867},[518,2047,806],{"class":524},[518,2049,877],{"class":648},[518,2051,2052],{"class":812}," AppOutboxTransport\n",[518,2054,2055,2058],{"class":520,"line":872},[518,2056,2057],{"class":648},"  extends",[518,2059,2060],{"class":812}," OutboxIntegrationEventTransport\n",[518,2062,2063,2066],{"class":520,"line":1129},[518,2064,2065],{"class":648},"  implements",[518,2067,2068],{"class":812}," IntegrationEventTransport\n",[518,2070,2071],{"class":520,"line":1467},[518,2072,1638],{"class":528},[518,2074,2075,2077,2079],{"class":520,"line":1472},[518,2076,1087],{"class":648},[518,2078,1090],{"class":648},[518,2080,2081],{"class":528},"(\n",[518,2083,2084,2087,2089,2091],{"class":520,"line":1477},[518,2085,2086],{"class":1095},"    database",[518,2088,574],{"class":528},[518,2090,1023],{"class":812},[518,2092,1236],{"class":528},[518,2094,2095,2098,2100,2102],{"class":520,"line":1493},[518,2096,2097],{"class":1095},"    store",[518,2099,574],{"class":528},[518,2101,1071],{"class":812},[518,2103,1236],{"class":528},[518,2105,2106,2109,2111,2113],{"class":520,"line":1531},[518,2107,2108],{"class":1095},"    relay",[518,2110,574],{"class":528},[518,2112,1484],{"class":812},[518,2114,1236],{"class":528},[518,2116,2117,2120,2122,2124],{"class":520,"line":1552},[518,2118,2119],{"class":1095},"    context",[518,2121,574],{"class":528},[518,2123,1311],{"class":812},[518,2125,1236],{"class":528},[518,2127,2128,2131,2133,2135],{"class":520,"line":1557},[518,2129,2130],{"class":1095},"    transactionContext",[518,2132,574],{"class":528},[518,2134,1924],{"class":812},[518,2136,1236],{"class":528},[518,2138,2140,2143],{"class":520,"line":2139},18,[518,2141,2142],{"class":528},"  )",[518,2144,658],{"class":528},[518,2146,2148,2150,2152,2154,2156,2159,2161,2164,2166,2168,2170,2173,2175],{"class":520,"line":2147},19,[518,2149,1109],{"class":532},[518,2151,564],{"class":570},[518,2153,1096],{"class":532},[518,2155,898],{"class":528},[518,2157,2158],{"class":532}," store",[518,2160,898],{"class":528},[518,2162,2163],{"class":532}," relay",[518,2165,898],{"class":528},[518,2167,1520],{"class":532},[518,2169,898],{"class":528},[518,2171,2172],{"class":532}," transactionContext",[518,2174,588],{"class":570},[518,2176,546],{"class":528},[518,2178,2180],{"class":520,"line":2179},20,[518,2181,1126],{"class":528},[518,2183,2185],{"class":520,"line":2184},21,[518,2186,864],{"class":528},[499,2188,2189,2190,2193,2194,2197,2198,2201,2202,2204,2205,2208],{},"Declare all four in your module's ",[515,2191,2192],{},"providers"," — bare, no ",[515,2195,2196],{},"useFactory",", since every constructor above is\nauthored in app source and the compiler reads its parameter types directly. That includes ",[515,2199,2200],{},"AppOutboxRelay",":\n",[515,2203,937],{},"'s ",[515,2206,2207],{},"OnBootstrap"," hook (the crash-recovery boot replay) is inherited, not redeclared, and still\nfires automatically at boot.",[499,2210,2211,2212,2215,2216,2219,2220,2222,2223,2226,2227,2229],{},"Because both ",[515,2213,2214],{},"AppOutboxTransport"," (the producer transport) and ",[515,2217,2218],{},"AppRelayTransport"," (the relay's terminal)\nsatisfy the abstract ",[515,2221,740],{},", disambiguate the producer's binding explicitly with\n",[515,2224,2225],{},"{ provide: IntegrationEventTransport, useExisting: AppOutboxTransport }"," — the typed event publishes\nthrough the outbox transport. The relay's own constructor sidesteps the same ambiguity from the other side:\nit asks for ",[515,2228,2218],{}," by its concrete class, not the abstract token the alias above resolves, so\nthe two terminals never collide:",[508,2231,2234],{"className":510,"code":2232,"filename":2233,"language":512,"meta":513,"style":513},"import { Module, TransactionContext } from \"@heximon\u002Fruntime\";\nimport { IntegrationEventTransport } from \"@heximon\u002Fqueue\";\nimport { DatabaseModule } from \"..\u002Fdatabase\u002Fdatabase.module\";\nimport { AppOutboxRelay, AppRelayTransport } from \".\u002Foutbox-relay\";\nimport { AppOutboxStore } from \".\u002Foutbox-store\";\nimport { AppOutboxTransport } from \".\u002Foutbox\";\n\nexport class OutboxModule extends Module({\n  imports: [DatabaseModule],\n  providers: [\n    AppOutboxStore,\n    AppRelayTransport,\n    AppOutboxRelay,\n    AppOutboxTransport,\n    \u002F\u002F Both AppOutboxTransport and AppRelayTransport satisfy IntegrationEventTransport, so disambiguate:\n    \u002F\u002F the typed event publishes through the outbox transport; the relay injects its concrete terminal.\n    { provide: IntegrationEventTransport, useExisting: AppOutboxTransport },\n    TransactionContext, \u002F\u002F bare: its constructor is already a plain DI token (just the app Context)\n  ],\n  exports: [AppOutboxStore, AppRelayTransport, AppOutboxRelay, AppOutboxTransport, IntegrationEventTransport],\n}) {}\n","src\u002Foutbox\u002Foutbox.module.ts",[515,2235,2236,2261,2281,2303,2327,2347,2369,2373,2390,2402,2412,2419,2426,2433,2440,2445,2450,2474,2484,2491,2520],{"__ignoreMap":513},[518,2237,2238,2240,2242,2245,2247,2249,2251,2253,2255,2257,2259],{"class":520,"line":521},[518,2239,772],{"class":524},[518,2241,775],{"class":528},[518,2243,2244],{"class":532}," Module",[518,2246,898],{"class":528},[518,2248,1924],{"class":532},[518,2250,711],{"class":528},[518,2252,783],{"class":524},[518,2254,786],{"class":528},[518,2256,1320],{"class":789},[518,2258,793],{"class":528},[518,2260,546],{"class":528},[518,2262,2263,2265,2267,2269,2271,2273,2275,2277,2279],{"class":520,"line":549},[518,2264,772],{"class":524},[518,2266,775],{"class":528},[518,2268,1966],{"class":532},[518,2270,711],{"class":528},[518,2272,783],{"class":524},[518,2274,786],{"class":528},[518,2276,1363],{"class":789},[518,2278,793],{"class":528},[518,2280,546],{"class":528},[518,2282,2283,2285,2287,2290,2292,2294,2296,2299,2301],{"class":520,"line":683},[518,2284,772],{"class":524},[518,2286,775],{"class":528},[518,2288,2289],{"class":532}," DatabaseModule",[518,2291,711],{"class":528},[518,2293,783],{"class":524},[518,2295,786],{"class":528},[518,2297,2298],{"class":789},"..\u002Fdatabase\u002Fdatabase.module",[518,2300,793],{"class":528},[518,2302,546],{"class":528},[518,2304,2305,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325],{"class":520,"line":721},[518,2306,772],{"class":524},[518,2308,775],{"class":528},[518,2310,1484],{"class":532},[518,2312,898],{"class":528},[518,2314,1423],{"class":532},[518,2316,711],{"class":528},[518,2318,783],{"class":524},[518,2320,786],{"class":528},[518,2322,2015],{"class":789},[518,2324,793],{"class":528},[518,2326,546],{"class":528},[518,2328,2329,2331,2333,2335,2337,2339,2341,2343,2345],{"class":520,"line":832},[518,2330,772],{"class":524},[518,2332,775],{"class":528},[518,2334,1071],{"class":532},[518,2336,711],{"class":528},[518,2338,783],{"class":524},[518,2340,786],{"class":528},[518,2342,1406],{"class":789},[518,2344,793],{"class":528},[518,2346,546],{"class":528},[518,2348,2349,2351,2353,2356,2358,2360,2362,2365,2367],{"class":520,"line":846},[518,2350,772],{"class":524},[518,2352,775],{"class":528},[518,2354,2355],{"class":532}," AppOutboxTransport",[518,2357,711],{"class":528},[518,2359,783],{"class":524},[518,2361,786],{"class":528},[518,2363,2364],{"class":789},".\u002Foutbox",[518,2366,793],{"class":528},[518,2368,546],{"class":528},[518,2370,2371],{"class":520,"line":861},[518,2372,801],{"emptyLinePlaceholder":800},[518,2374,2375,2377,2379,2382,2384,2386,2388],{"class":520,"line":867},[518,2376,806],{"class":524},[518,2378,877],{"class":648},[518,2380,2381],{"class":812}," OutboxModule",[518,2383,883],{"class":648},[518,2385,2244],{"class":539},[518,2387,564],{"class":532},[518,2389,1638],{"class":528},[518,2391,2392,2395,2397,2400],{"class":520,"line":872},[518,2393,2394],{"class":570},"  imports",[518,2396,574],{"class":528},[518,2398,2399],{"class":532}," [DatabaseModule]",[518,2401,1236],{"class":528},[518,2403,2404,2407,2409],{"class":520,"line":1129},[518,2405,2406],{"class":570},"  providers",[518,2408,574],{"class":528},[518,2410,2411],{"class":532}," [\n",[518,2413,2414,2417],{"class":520,"line":1467},[518,2415,2416],{"class":532},"    AppOutboxStore",[518,2418,1236],{"class":528},[518,2420,2421,2424],{"class":520,"line":1472},[518,2422,2423],{"class":532},"    AppRelayTransport",[518,2425,1236],{"class":528},[518,2427,2428,2431],{"class":520,"line":1477},[518,2429,2430],{"class":532},"    AppOutboxRelay",[518,2432,1236],{"class":528},[518,2434,2435,2438],{"class":520,"line":1493},[518,2436,2437],{"class":532},"    AppOutboxTransport",[518,2439,1236],{"class":528},[518,2441,2442],{"class":520,"line":1531},[518,2443,2444],{"class":594},"    \u002F\u002F Both AppOutboxTransport and AppRelayTransport satisfy IntegrationEventTransport, so disambiguate:\n",[518,2446,2447],{"class":520,"line":1552},[518,2448,2449],{"class":594},"    \u002F\u002F the typed event publishes through the outbox transport; the relay injects its concrete terminal.\n",[518,2451,2452,2455,2458,2460,2462,2464,2467,2469,2472],{"class":520,"line":1557},[518,2453,2454],{"class":528},"    {",[518,2456,2457],{"class":570}," provide",[518,2459,574],{"class":528},[518,2461,1966],{"class":532},[518,2463,898],{"class":528},[518,2465,2466],{"class":570}," useExisting",[518,2468,574],{"class":528},[518,2470,2471],{"class":532}," AppOutboxTransport ",[518,2473,1700],{"class":528},[518,2475,2476,2479,2481],{"class":520,"line":2139},[518,2477,2478],{"class":532},"    TransactionContext",[518,2480,898],{"class":528},[518,2482,2483],{"class":594}," \u002F\u002F bare: its constructor is already a plain DI token (just the app Context)\n",[518,2485,2486,2489],{"class":520,"line":2147},[518,2487,2488],{"class":532},"  ]",[518,2490,1236],{"class":528},[518,2492,2493,2496,2498,2501,2503,2505,2507,2509,2511,2513,2515,2518],{"class":520,"line":2179},[518,2494,2495],{"class":570},"  exports",[518,2497,574],{"class":528},[518,2499,2500],{"class":532}," [AppOutboxStore",[518,2502,898],{"class":528},[518,2504,1423],{"class":532},[518,2506,898],{"class":528},[518,2508,1484],{"class":532},[518,2510,898],{"class":528},[518,2512,2355],{"class":532},[518,2514,898],{"class":528},[518,2516,2517],{"class":532}," IntegrationEventTransport]",[518,2519,1236],{"class":528},[518,2521,2522,2524,2527],{"class":520,"line":2184},[518,2523,585],{"class":528},[518,2525,2526],{"class":532},") ",[518,2528,2529],{"class":528},"{}\n",[503,2531,2533,2534],{"id":2532},"the-compiler-warning-integrationfire-and-forget","The compiler warning — ",[515,2535,2536],{},"integration.fire-and-forget",[499,2538,2539,2540,2542,2543,2546],{},"When the compiler discovers ",[515,2541,1782],{}," classes but no durable transport is bound, it emits a\n",[515,2544,2545],{},"warning","-severity diagnostic:",[508,2548,2553],{"className":2549,"code":2551,"language":2552,"meta":513},[2550],"language-text","warning [integration\u002Ffire-and-forget]  OrderPlacedHandler: 1 IntegrationEventHandler discovered, but\nfire-and-forget delivery is not explicitly opted into. Integration events dispatched without a\ntransactional outbox are fire-and-forget: a process crash between the aggregate write and the dispatch\nloses the event silently. Bind the transactional outbox pattern (OutboxIntegrationEventTransport +\nOutboxRelay) for at-least-once delivery — see the \"reliable integration events\" recipe in the docs.\n","text",[515,2554,2551],{"__ignoreMap":513},[499,2556,2557,2558,2561,2562,574],{},"The build always completes — the warning never becomes an error. If fire-and-forget is deliberately\nacceptable for a given app (tests, development, a throwaway prototype), suppress it by listing the code in\n",[515,2559,2560],{},"suppressDiagnostics"," — the silence-direction mirror of ",[515,2563,2564],{},"strictDiagnostics",[508,2566,2569],{"className":510,"code":2567,"filename":2568,"language":512,"meta":513,"style":513},"import { DiagnosticCode } from \"@heximon\u002Fbuild\";\n\nheximon({ suppressDiagnostics: [DiagnosticCode.FireAndForgetIntegrationEvents] });\n","vite.config.ts",[515,2570,2571,2593,2597],{"__ignoreMap":513},[518,2572,2573,2575,2577,2580,2582,2584,2586,2589,2591],{"class":520,"line":521},[518,2574,772],{"class":524},[518,2576,775],{"class":528},[518,2578,2579],{"class":532}," DiagnosticCode",[518,2581,711],{"class":528},[518,2583,783],{"class":524},[518,2585,786],{"class":528},[518,2587,2588],{"class":789},"@heximon\u002Fbuild",[518,2590,793],{"class":528},[518,2592,546],{"class":528},[518,2594,2595],{"class":520,"line":549},[518,2596,801],{"emptyLinePlaceholder":800},[518,2598,2599,2602,2604,2606,2609,2611,2614,2616,2619,2621,2623],{"class":520,"line":683},[518,2600,2601],{"class":539},"heximon",[518,2603,564],{"class":532},[518,2605,567],{"class":528},[518,2607,2608],{"class":570}," suppressDiagnostics",[518,2610,574],{"class":528},[518,2612,2613],{"class":532}," [DiagnosticCode",[518,2615,536],{"class":528},[518,2617,2618],{"class":532},"FireAndForgetIntegrationEvents] ",[518,2620,585],{"class":528},[518,2622,588],{"class":532},[518,2624,546],{"class":528},[503,2626,2628],{"id":2627},"correlation-and-causation-across-the-outbox-boundary","Correlation and causation across the outbox boundary",[499,2630,2631,2632,1253,2634,2636,2637,2640],{},"The ",[515,2633,1252],{},[515,2635,1256],{}," are captured from the ambient context at emit time and persisted on\nthe outbox row. The relay reads them from the stored row — not from the (empty) context at drain time —\nand seeds them into the consumer's context via ",[515,2638,2639],{},"QueueChannelDispatcher.dispatch",". This means:",[2642,2643,2644,2651],"ul",{},[2645,2646,2647,2650],"li",{},[622,2648,2649],{},"A boot-time replay"," (rows left pending across a process restart) threads the same tracing ids into the\nhandler as the original dispatch would have.",[2645,2652,2653,2660,2661,2663,2664,2666,2667,2669],{},[622,2654,2655,2656,2659],{},"The handler's own ",[515,2657,2658],{},"DomainEvents.emit"," calls"," inherit the correct ",[515,2662,1252],{}," (the originating\nrequest) and ",[515,2665,1256],{}," (the integration event's stable row ",[515,2668,708],{},").",[499,2671,2672],{},"No extra wiring is needed — the three-class setup above handles it automatically.",[499,2674,2675,2676,2678,2679,2681,2682,2685],{},"The columns are nullable in the outbox table. Rows written before this feature existed read back as ",[515,2677,1260],{},";\nthe relay converts ",[515,2680,1260],{}," to ",[515,2683,2684],{},"undefined"," before passing to the dispatcher, so a legacy row causes no ids\nto be seeded (the same as if the event had been emitted outside an active context).",[503,2687,2689],{"id":2688},"at-least-once-delivery","At-least-once delivery",[499,2691,2692,2693,2696],{},"The outbox guarantees ",[622,2694,2695],{},"at-least-once"," delivery — not exactly-once. A crash after the relay dispatches the\nevent but before it deletes the outbox row will cause re-delivery. Every handler that writes state should\nguard against double-processing:",[508,2698,2700],{"className":510,"code":2699,"language":512,"meta":513,"style":513},"const existing = await this.repository.getByOrderId(payload.orderId);\nif (existing !== undefined) {\n  return; \u002F\u002F already processed — skip the duplicate\n}\n",[515,2701,2702,2734,2752,2762],{"__ignoreMap":513},[518,2703,2704,2707,2710,2712,2715,2717,2719,2721,2724,2727,2729,2732],{"class":520,"line":521},[518,2705,2706],{"class":648},"const",[518,2708,2709],{"class":532}," existing ",[518,2711,1207],{"class":528},[518,2713,2714],{"class":524}," await",[518,2716,529],{"class":528},[518,2718,533],{"class":532},[518,2720,536],{"class":528},[518,2722,2723],{"class":539},"getByOrderId",[518,2725,2726],{"class":532},"(payload",[518,2728,536],{"class":528},[518,2730,2731],{"class":532},"orderId)",[518,2733,546],{"class":528},[518,2735,2736,2739,2742,2745,2748,2750],{"class":520,"line":549},[518,2737,2738],{"class":524},"if",[518,2740,2741],{"class":532}," (existing ",[518,2743,2744],{"class":528},"!==",[518,2746,2747],{"class":528}," undefined",[518,2749,2526],{"class":532},[518,2751,1638],{"class":528},[518,2753,2754,2757,2759],{"class":520,"line":683},[518,2755,2756],{"class":524},"  return",[518,2758,591],{"class":528},[518,2760,2761],{"class":594}," \u002F\u002F already processed — skip the duplicate\n",[518,2763,2764],{"class":520,"line":721},[518,2765,864],{"class":528},[499,2767,2631,2768,2771,2772,2775,2776,2778,2779,2771,2782,2785,2786,2789,2790,2793],{},[515,2769,2770],{},"QueueIdempotencyInterceptor"," from ",[515,2773,2774],{},"@heximon\u002Fqueue\u002Fidempotency"," provides a framework-level guard on top of\nthe handler's own check — it dedups queue and integration-event dispatch on the envelope's stable ",[515,2777,708],{},", so a\nrelay redelivery is a no-op the second time. (",[515,2780,2781],{},"EventIdempotencyInterceptor",[515,2783,2784],{},"@heximon\u002Fevents\u002Fidempotency","\nis the sibling for the serial in-process ",[515,2787,2788],{},"EventHandler"," tier, keyed on ",[515,2791,2792],{},"DomainEvent.eventId"," — a different\ndispatch path from the relay.)",[503,2795,2797],{"id":2796},"see-also","See also",[2642,2799,2800,2806,2811,2819,2830],{},[2645,2801,2802,2805],{},[2803,2804,243],"a",{"href":244}," — the full integration-event tier and how it differs from domain events.",[2645,2807,2808,2810],{},[2803,2809,485],{"href":486}," — multi-step compensation chains over the durable outbox.",[2645,2812,2813,2815,2816,2818],{},[2803,2814,185],{"href":186}," — the ",[515,2817,2770],{}," that deduplicates relay redeliveries.",[2645,2820,2821,2829],{},[2803,2822,2826],{"href":2823,"rel":2824},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fgap\u002Fcross-service-transports\u002Freliable",[2825],"nofollow",[622,2827,2828],{},"the gap's reliable cross-service example","\n— a complete, tested outbox wiring: a place-order endpoint that commits the outbox row atomically with the\norder, a relay drain that fans to both a local handler and a remote subscriber, and a test that proves a\nrolled-back order delivers nothing.",[2645,2831,2832,2839,2840,934,2843,934,2845,2847,2848,536],{},[2803,2833,2836],{"href":2834,"rel":2835},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fgap\u002Fworkflow-compensation",[2825],[622,2837,2838],{},"the gap's workflow compensation example","\n— the same three-class outbox tier (",[515,2841,2842],{},"AppOutboxStore",[515,2844,2200],{},[515,2846,2214],{},") shared by\nthree bounded contexts, backing the choreography in ",[2803,2849,485],{"href":486},[2851,2852,2853],"style",{},"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 .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 .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}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}",{"title":513,"searchDepth":549,"depth":549,"links":2855},[2856,2857,2858,2859,2867,2869,2870,2871],{"id":505,"depth":549,"text":506},{"id":616,"depth":549,"text":617},{"id":748,"depth":549,"text":749},{"id":923,"depth":549,"text":924,"children":2860},[2861,2863,2865],{"id":950,"depth":683,"text":2862},"OutboxStore — persistence",{"id":1281,"depth":683,"text":2864},"OutboxRelay and its in-process terminal",{"id":1890,"depth":683,"text":2866},"OutboxIntegrationEventTransport — the transactional producer transport",{"id":2532,"depth":549,"text":2868},"The compiler warning — integration.fire-and-forget",{"id":2627,"depth":549,"text":2628},{"id":2688,"depth":549,"text":2689},{"id":2796,"depth":549,"text":2797},"Transactional outbox pattern for at-least-once integration event delivery — OutboxStore, OutboxIntegrationEventTransport, OutboxRelay, fire-and-forget tradeoff, the fire-and-forget compiler warning and its suppressDiagnostics opt-out.","md",null,{},{"icon":483},{"title":480,"description":2872},"jGiRqq5fuXbhnjWfD-zFzgLaQ8-3PRhUBuaq9EnkOEw",[2880,2882],{"title":475,"path":476,"stem":477,"description":2881,"icon":478,"children":-1},"Ship a feature as a precompiled, publishable Heximon module — build the factory and manifest with heximonLibrary(), require host tokens, then consume it in one import.",{"title":485,"path":486,"stem":487,"description":2883,"icon":95,"children":-1},"A multi-step saga that compensates itself, with no central coordinator — each bounded context reacts to integration events over the transactional outbox and emits the next, with at-least-once delivery and per-handler idempotency.",1783300761903]