[{"data":1,"prerenderedAt":4036},["ShallowReactive",2],{"navigation_docs":3,"-docs-architecture-cqrs":493,"-docs-architecture-cqrs-surround":4031},[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":233,"body":495,"description":4024,"extension":4025,"links":4026,"meta":4027,"navigation":4028,"path":234,"seo":4029,"stem":235,"__hash__":4030},"docs\u002Fdocs\u002F04.architecture\u002F03.cqrs.md",{"type":496,"value":497,"toc":4011},"minimark",[498,511,516,519,591,748,752,767,931,944,948,958,969,1204,1208,1225,1490,1494,1512,2236,2250,2254,2269,2283,2560,2570,2577,2917,2920,2924,2943,3014,3030,3034,3044,3081,3094,3137,3141,3151,3168,3317,3330,3447,3495,3507,3550,3554,3571,3970,3974,4007],[499,500,501,502,506,507,510],"p",{},"CQRS — Command Query Responsibility Segregation — splits the two things your app does to data:\n",[503,504,505],"strong",{},"commands"," change state, ",[503,508,509],{},"queries"," read it. Heximon gives each its own typed bus and exactly one\nhandler per message, all wired at compile time. The payoff is a codebase where every write and every\nread is an explicit, named, individually testable unit.",[512,513,515],"h2",{"id":514},"setup","Setup",[499,517,518],{},"Install the package and register its compiler plugin alongside the HTTP plugin:",[520,521,522,548,563,577],"code-group",{},[523,524,530],"pre",{"className":525,"code":526,"filename":527,"language":528,"meta":529,"style":529},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pnpm add @heximon\u002Fcqrs\n","pnpm","bash","",[531,532,533],"code",{"__ignoreMap":529},[534,535,538,541,545],"span",{"class":536,"line":537},"line",1,[534,539,527],{"class":540},"sBMFI",[534,542,544],{"class":543},"sfazB"," add",[534,546,547],{"class":543}," @heximon\u002Fcqrs\n",[523,549,552],{"className":525,"code":550,"filename":551,"language":528,"meta":529,"style":529},"npm install @heximon\u002Fcqrs\n","npm",[531,553,554],{"__ignoreMap":529},[534,555,556,558,561],{"class":536,"line":537},[534,557,551],{"class":540},[534,559,560],{"class":543}," install",[534,562,547],{"class":543},[523,564,567],{"className":525,"code":565,"filename":566,"language":528,"meta":529,"style":529},"yarn add @heximon\u002Fcqrs\n","yarn",[531,568,569],{"__ignoreMap":529},[534,570,571,573,575],{"class":536,"line":537},[534,572,566],{"class":540},[534,574,544],{"class":543},[534,576,547],{"class":543},[523,578,581],{"className":525,"code":579,"filename":580,"language":528,"meta":529,"style":529},"bun add @heximon\u002Fcqrs\n","bun",[531,582,583],{"__ignoreMap":529},[534,584,585,587,589],{"class":536,"line":537},[534,586,580],{"class":540},[534,588,544],{"class":543},[534,590,547],{"class":543},[523,592,597],{"className":593,"code":594,"filename":595,"language":596,"meta":529,"style":529},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { defineHeximonConfig } from \"@heximon\u002Fbuild\";\nimport { CqrsPlugin } from \"@heximon\u002Fcqrs\u002Fcompiler\";\nimport { HttpPlugin } from \"@heximon\u002Fhttp\u002Fcompiler\";\n\nexport default defineHeximonConfig({\n  plugins: [new HttpPlugin(), new CqrsPlugin()],\n});\n","heximon.config.ts","ts",[531,598,599,631,654,677,684,702,737],{"__ignoreMap":529},[534,600,601,605,609,613,616,619,622,625,628],{"class":536,"line":537},[534,602,604],{"class":603},"s7zQu","import",[534,606,608],{"class":607},"sMK4o"," {",[534,610,612],{"class":611},"sTEyZ"," defineHeximonConfig",[534,614,615],{"class":607}," }",[534,617,618],{"class":603}," from",[534,620,621],{"class":607}," \"",[534,623,624],{"class":543},"@heximon\u002Fbuild",[534,626,627],{"class":607},"\"",[534,629,630],{"class":607},";\n",[534,632,634,636,638,641,643,645,647,650,652],{"class":536,"line":633},2,[534,635,604],{"class":603},[534,637,608],{"class":607},[534,639,640],{"class":611}," CqrsPlugin",[534,642,615],{"class":607},[534,644,618],{"class":603},[534,646,621],{"class":607},[534,648,649],{"class":543},"@heximon\u002Fcqrs\u002Fcompiler",[534,651,627],{"class":607},[534,653,630],{"class":607},[534,655,657,659,661,664,666,668,670,673,675],{"class":536,"line":656},3,[534,658,604],{"class":603},[534,660,608],{"class":607},[534,662,663],{"class":611}," HttpPlugin",[534,665,615],{"class":607},[534,667,618],{"class":603},[534,669,621],{"class":607},[534,671,672],{"class":543},"@heximon\u002Fhttp\u002Fcompiler",[534,674,627],{"class":607},[534,676,630],{"class":607},[534,678,680],{"class":536,"line":679},4,[534,681,683],{"emptyLinePlaceholder":682},true,"\n",[534,685,687,690,693,696,699],{"class":536,"line":686},5,[534,688,689],{"class":603},"export",[534,691,692],{"class":603}," default",[534,694,612],{"class":695},"s2Zo4",[534,697,698],{"class":611},"(",[534,700,701],{"class":607},"{\n",[534,703,705,709,712,715,718,720,723,726,729,731,734],{"class":536,"line":704},6,[534,706,708],{"class":707},"swJcz","  plugins",[534,710,711],{"class":607},":",[534,713,714],{"class":611}," [",[534,716,717],{"class":607},"new",[534,719,663],{"class":695},[534,721,722],{"class":611},"()",[534,724,725],{"class":607},",",[534,727,728],{"class":607}," new",[534,730,640],{"class":695},[534,732,733],{"class":611},"()]",[534,735,736],{"class":607},",\n",[534,738,740,743,746],{"class":536,"line":739},7,[534,741,742],{"class":607},"}",[534,744,745],{"class":611},")",[534,747,630],{"class":607},[512,749,751],{"id":750},"define-a-command","Define a command",[499,753,754,755,758,759,762,763,766],{},"A ",[531,756,757],{},"Command"," is a request to ",[503,760,761],{},"change state",". It states intent and returns nothing — its handler\nresolves to ",[531,764,765],{},"void",". The payload is just constructor parameters.",[523,768,771],{"className":593,"code":769,"filename":770,"language":596,"meta":529,"style":529},"import { Command } from \"@heximon\u002Fcqrs\";\nimport type { UserId } from \"..\u002Fuser\";\n\nexport class CreateUserCommand extends Command {\n  constructor(\n    public readonly id: UserId,\n    public readonly name: string,\n    public readonly email: string,\n  ) {\n    super();\n  }\n}\n","create-user.command.ts",[531,772,773,795,820,824,843,851,869,885,901,909,919,925],{"__ignoreMap":529},[534,774,775,777,779,782,784,786,788,791,793],{"class":536,"line":537},[534,776,604],{"class":603},[534,778,608],{"class":607},[534,780,781],{"class":611}," Command",[534,783,615],{"class":607},[534,785,618],{"class":603},[534,787,621],{"class":607},[534,789,790],{"class":543},"@heximon\u002Fcqrs",[534,792,627],{"class":607},[534,794,630],{"class":607},[534,796,797,799,802,804,807,809,811,813,816,818],{"class":536,"line":633},[534,798,604],{"class":603},[534,800,801],{"class":603}," type",[534,803,608],{"class":607},[534,805,806],{"class":611}," UserId",[534,808,615],{"class":607},[534,810,618],{"class":603},[534,812,621],{"class":607},[534,814,815],{"class":543},"..\u002Fuser",[534,817,627],{"class":607},[534,819,630],{"class":607},[534,821,822],{"class":536,"line":656},[534,823,683],{"emptyLinePlaceholder":682},[534,825,826,828,832,835,838,840],{"class":536,"line":679},[534,827,689],{"class":603},[534,829,831],{"class":830},"spNyl"," class",[534,833,834],{"class":540}," CreateUserCommand",[534,836,837],{"class":830}," extends",[534,839,781],{"class":540},[534,841,842],{"class":607}," {\n",[534,844,845,848],{"class":536,"line":686},[534,846,847],{"class":830},"  constructor",[534,849,850],{"class":607},"(\n",[534,852,853,856,859,863,865,867],{"class":536,"line":704},[534,854,855],{"class":830},"    public",[534,857,858],{"class":830}," readonly",[534,860,862],{"class":861},"sHdIc"," id",[534,864,711],{"class":607},[534,866,806],{"class":540},[534,868,736],{"class":607},[534,870,871,873,875,878,880,883],{"class":536,"line":739},[534,872,855],{"class":830},[534,874,858],{"class":830},[534,876,877],{"class":861}," name",[534,879,711],{"class":607},[534,881,882],{"class":540}," string",[534,884,736],{"class":607},[534,886,888,890,892,895,897,899],{"class":536,"line":887},8,[534,889,855],{"class":830},[534,891,858],{"class":830},[534,893,894],{"class":861}," email",[534,896,711],{"class":607},[534,898,882],{"class":540},[534,900,736],{"class":607},[534,902,904,907],{"class":536,"line":903},9,[534,905,906],{"class":607},"  )",[534,908,842],{"class":607},[534,910,912,915,917],{"class":536,"line":911},10,[534,913,914],{"class":611},"    super",[534,916,722],{"class":707},[534,918,630],{"class":607},[534,920,922],{"class":536,"line":921},11,[534,923,924],{"class":607},"  }\n",[534,926,928],{"class":536,"line":927},12,[534,929,930],{"class":607},"}\n",[932,933,935,936,939,940,943],"callout",{"type":934},"tip","A command returns nothing, so how do you get the new id? Mint it ",[503,937,938],{},"before"," you dispatch:\n",[531,941,942],{},"UserId.generate()",", pass it into the command, then read the new state back with a query. The command\nnever has to hand an id back — and the caller knew the id all along.",[512,945,947],{"id":946},"handle-a-command","Handle a command",[499,949,950,953,954,957],{},[531,951,952],{},"implements CommandHandler\u003CCreateUserCommand>"," is the link from message to handler — the compiler reads\nthe command from the type argument and routes it here. There is ",[503,955,956],{},"exactly one"," handler per command;\ndeclaring a second is a build error.",[499,959,960,961,964,965,968],{},"The constructor is the dependency declaration, so the kernel injects ",[531,962,963],{},"UserStore"," by class identity — no\ntoken to declare. (",[531,966,967],{},"extends CommandHandler\u003C...>"," binds identically — use it when you want your own\nbase-class hierarchy on top of a handler.)",[523,970,973],{"className":593,"code":971,"filename":972,"language":596,"meta":529,"style":529},"import type { CommandHandler } from \"@heximon\u002Fcqrs\";\nimport { UserStore } from \"..\u002Fuser.store\";\nimport { CreateUserCommand } from \".\u002Fcreate-user.command\";\n\nexport class CreateUserCommandHandler implements CommandHandler\u003CCreateUserCommand> {\n  constructor(private readonly userStore: UserStore) {}\n\n  public handle(command: CreateUserCommand): void {\n    this.userStore.save({ id: command.id, name: command.name, email: command.email, version: 1 });\n  }\n}\n","create-user.handler.ts",[531,974,975,998,1020,1041,1045,1070,1093,1097,1122,1196,1200],{"__ignoreMap":529},[534,976,977,979,981,983,986,988,990,992,994,996],{"class":536,"line":537},[534,978,604],{"class":603},[534,980,801],{"class":603},[534,982,608],{"class":607},[534,984,985],{"class":611}," CommandHandler",[534,987,615],{"class":607},[534,989,618],{"class":603},[534,991,621],{"class":607},[534,993,790],{"class":543},[534,995,627],{"class":607},[534,997,630],{"class":607},[534,999,1000,1002,1004,1007,1009,1011,1013,1016,1018],{"class":536,"line":633},[534,1001,604],{"class":603},[534,1003,608],{"class":607},[534,1005,1006],{"class":611}," UserStore",[534,1008,615],{"class":607},[534,1010,618],{"class":603},[534,1012,621],{"class":607},[534,1014,1015],{"class":543},"..\u002Fuser.store",[534,1017,627],{"class":607},[534,1019,630],{"class":607},[534,1021,1022,1024,1026,1028,1030,1032,1034,1037,1039],{"class":536,"line":656},[534,1023,604],{"class":603},[534,1025,608],{"class":607},[534,1027,834],{"class":611},[534,1029,615],{"class":607},[534,1031,618],{"class":603},[534,1033,621],{"class":607},[534,1035,1036],{"class":543},".\u002Fcreate-user.command",[534,1038,627],{"class":607},[534,1040,630],{"class":607},[534,1042,1043],{"class":536,"line":679},[534,1044,683],{"emptyLinePlaceholder":682},[534,1046,1047,1049,1051,1054,1057,1059,1062,1065,1068],{"class":536,"line":686},[534,1048,689],{"class":603},[534,1050,831],{"class":830},[534,1052,1053],{"class":540}," CreateUserCommandHandler",[534,1055,1056],{"class":830}," implements",[534,1058,985],{"class":540},[534,1060,1061],{"class":607},"\u003C",[534,1063,1064],{"class":540},"CreateUserCommand",[534,1066,1067],{"class":607},">",[534,1069,842],{"class":607},[534,1071,1072,1074,1076,1079,1081,1084,1086,1088,1090],{"class":536,"line":704},[534,1073,847],{"class":830},[534,1075,698],{"class":607},[534,1077,1078],{"class":830},"private",[534,1080,858],{"class":830},[534,1082,1083],{"class":861}," userStore",[534,1085,711],{"class":607},[534,1087,1006],{"class":540},[534,1089,745],{"class":607},[534,1091,1092],{"class":607}," {}\n",[534,1094,1095],{"class":536,"line":739},[534,1096,683],{"emptyLinePlaceholder":682},[534,1098,1099,1102,1105,1107,1110,1112,1114,1117,1120],{"class":536,"line":887},[534,1100,1101],{"class":830},"  public",[534,1103,1104],{"class":707}," handle",[534,1106,698],{"class":607},[534,1108,1109],{"class":861},"command",[534,1111,711],{"class":607},[534,1113,834],{"class":540},[534,1115,1116],{"class":607},"):",[534,1118,1119],{"class":540}," void",[534,1121,842],{"class":607},[534,1123,1124,1127,1130,1133,1136,1138,1141,1143,1145,1148,1150,1153,1155,1157,1159,1161,1163,1166,1168,1170,1172,1174,1176,1179,1181,1184,1186,1190,1192,1194],{"class":536,"line":903},[534,1125,1126],{"class":607},"    this.",[534,1128,1129],{"class":611},"userStore",[534,1131,1132],{"class":607},".",[534,1134,1135],{"class":695},"save",[534,1137,698],{"class":707},[534,1139,1140],{"class":607},"{",[534,1142,862],{"class":707},[534,1144,711],{"class":607},[534,1146,1147],{"class":611}," command",[534,1149,1132],{"class":607},[534,1151,1152],{"class":611},"id",[534,1154,725],{"class":607},[534,1156,877],{"class":707},[534,1158,711],{"class":607},[534,1160,1147],{"class":611},[534,1162,1132],{"class":607},[534,1164,1165],{"class":611},"name",[534,1167,725],{"class":607},[534,1169,894],{"class":707},[534,1171,711],{"class":607},[534,1173,1147],{"class":611},[534,1175,1132],{"class":607},[534,1177,1178],{"class":611},"email",[534,1180,725],{"class":607},[534,1182,1183],{"class":707}," version",[534,1185,711],{"class":607},[534,1187,1189],{"class":1188},"sbssI"," 1",[534,1191,615],{"class":607},[534,1193,745],{"class":707},[534,1195,630],{"class":607},[534,1197,1198],{"class":536,"line":911},[534,1199,924],{"class":607},[534,1201,1202],{"class":536,"line":921},[534,1203,930],{"class":607},[512,1205,1207],{"id":1206},"define-and-handle-a-query","Define and handle a query",[499,1209,754,1210,758,1213,1216,1217,1220,1221,1224],{},[531,1211,1212],{},"Query\u003CTResult>",[503,1214,1215],{},"read state"," that produces a typed result. The result type flows\nfrom the query's generic, through the bus, to the call site — so ",[531,1218,1219],{},"queryBus.execute(new GetUserQuery(id))","\nis typed ",[531,1222,1223],{},"User | undefined"," with nothing to annotate.",[523,1226,1229],{"className":593,"code":1227,"filename":1228,"language":596,"meta":529,"style":529},"import { Query, type QueryHandler } from \"@heximon\u002Fcqrs\";\nimport type { User, UserId } from \"..\u002Fuser\";\nimport { UserStore } from \"..\u002Fuser.store\";\n\nexport class GetUserQuery extends Query\u003CUser | undefined> {\n  constructor(public readonly id: UserId) {\n    super();\n  }\n}\n\nexport class GetUserQueryHandler implements QueryHandler\u003CGetUserQuery> {\n  constructor(private readonly userStore: UserStore) {}\n\n  public handle(query: GetUserQuery): User | undefined {\n    return this.userStore.findById(query.id);\n  }\n}\n","get-user.query.ts",[531,1230,1231,1259,1286,1306,1310,1338,1359,1367,1371,1375,1379,1401,1421,1426,1452,1480,1485],{"__ignoreMap":529},[534,1232,1233,1235,1237,1240,1242,1244,1247,1249,1251,1253,1255,1257],{"class":536,"line":537},[534,1234,604],{"class":603},[534,1236,608],{"class":607},[534,1238,1239],{"class":611}," Query",[534,1241,725],{"class":607},[534,1243,801],{"class":603},[534,1245,1246],{"class":611}," QueryHandler",[534,1248,615],{"class":607},[534,1250,618],{"class":603},[534,1252,621],{"class":607},[534,1254,790],{"class":543},[534,1256,627],{"class":607},[534,1258,630],{"class":607},[534,1260,1261,1263,1265,1267,1270,1272,1274,1276,1278,1280,1282,1284],{"class":536,"line":633},[534,1262,604],{"class":603},[534,1264,801],{"class":603},[534,1266,608],{"class":607},[534,1268,1269],{"class":611}," User",[534,1271,725],{"class":607},[534,1273,806],{"class":611},[534,1275,615],{"class":607},[534,1277,618],{"class":603},[534,1279,621],{"class":607},[534,1281,815],{"class":543},[534,1283,627],{"class":607},[534,1285,630],{"class":607},[534,1287,1288,1290,1292,1294,1296,1298,1300,1302,1304],{"class":536,"line":656},[534,1289,604],{"class":603},[534,1291,608],{"class":607},[534,1293,1006],{"class":611},[534,1295,615],{"class":607},[534,1297,618],{"class":603},[534,1299,621],{"class":607},[534,1301,1015],{"class":543},[534,1303,627],{"class":607},[534,1305,630],{"class":607},[534,1307,1308],{"class":536,"line":679},[534,1309,683],{"emptyLinePlaceholder":682},[534,1311,1312,1314,1316,1319,1321,1323,1325,1328,1331,1334,1336],{"class":536,"line":686},[534,1313,689],{"class":603},[534,1315,831],{"class":830},[534,1317,1318],{"class":540}," GetUserQuery",[534,1320,837],{"class":830},[534,1322,1239],{"class":540},[534,1324,1061],{"class":607},[534,1326,1327],{"class":540},"User",[534,1329,1330],{"class":607}," |",[534,1332,1333],{"class":540}," undefined",[534,1335,1067],{"class":607},[534,1337,842],{"class":607},[534,1339,1340,1342,1344,1347,1349,1351,1353,1355,1357],{"class":536,"line":704},[534,1341,847],{"class":830},[534,1343,698],{"class":607},[534,1345,1346],{"class":830},"public",[534,1348,858],{"class":830},[534,1350,862],{"class":861},[534,1352,711],{"class":607},[534,1354,806],{"class":540},[534,1356,745],{"class":607},[534,1358,842],{"class":607},[534,1360,1361,1363,1365],{"class":536,"line":739},[534,1362,914],{"class":611},[534,1364,722],{"class":707},[534,1366,630],{"class":607},[534,1368,1369],{"class":536,"line":887},[534,1370,924],{"class":607},[534,1372,1373],{"class":536,"line":903},[534,1374,930],{"class":607},[534,1376,1377],{"class":536,"line":911},[534,1378,683],{"emptyLinePlaceholder":682},[534,1380,1381,1383,1385,1388,1390,1392,1394,1397,1399],{"class":536,"line":921},[534,1382,689],{"class":603},[534,1384,831],{"class":830},[534,1386,1387],{"class":540}," GetUserQueryHandler",[534,1389,1056],{"class":830},[534,1391,1246],{"class":540},[534,1393,1061],{"class":607},[534,1395,1396],{"class":540},"GetUserQuery",[534,1398,1067],{"class":607},[534,1400,842],{"class":607},[534,1402,1403,1405,1407,1409,1411,1413,1415,1417,1419],{"class":536,"line":927},[534,1404,847],{"class":830},[534,1406,698],{"class":607},[534,1408,1078],{"class":830},[534,1410,858],{"class":830},[534,1412,1083],{"class":861},[534,1414,711],{"class":607},[534,1416,1006],{"class":540},[534,1418,745],{"class":607},[534,1420,1092],{"class":607},[534,1422,1424],{"class":536,"line":1423},13,[534,1425,683],{"emptyLinePlaceholder":682},[534,1427,1429,1431,1433,1435,1438,1440,1442,1444,1446,1448,1450],{"class":536,"line":1428},14,[534,1430,1101],{"class":830},[534,1432,1104],{"class":707},[534,1434,698],{"class":607},[534,1436,1437],{"class":861},"query",[534,1439,711],{"class":607},[534,1441,1318],{"class":540},[534,1443,1116],{"class":607},[534,1445,1269],{"class":540},[534,1447,1330],{"class":607},[534,1449,1333],{"class":540},[534,1451,842],{"class":607},[534,1453,1455,1458,1461,1463,1465,1468,1470,1472,1474,1476,1478],{"class":536,"line":1454},15,[534,1456,1457],{"class":603},"    return",[534,1459,1460],{"class":607}," this.",[534,1462,1129],{"class":611},[534,1464,1132],{"class":607},[534,1466,1467],{"class":695},"findById",[534,1469,698],{"class":707},[534,1471,1437],{"class":611},[534,1473,1132],{"class":607},[534,1475,1152],{"class":611},[534,1477,745],{"class":707},[534,1479,630],{"class":607},[534,1481,1483],{"class":536,"line":1482},16,[534,1484,924],{"class":607},[534,1486,1488],{"class":536,"line":1487},17,[534,1489,930],{"class":607},[512,1491,1493],{"id":1492},"dispatch-from-a-controller","Dispatch from a controller",[499,1495,1496,1499,1500,1503,1504,1507,1508,1511],{},[531,1497,1498],{},"CommandBus"," and ",[531,1501,1502],{},"QueryBus"," are provided for you, so a plain ",[531,1505,1506],{},"Controller"," injects them straight through\nits constructor — no base class, no tokens. The write\u002Fread split shows up at every endpoint: a write\n",[531,1509,1510],{},"execute","s a command (which returns nothing), then re-reads with a query.",[523,1513,1516],{"className":593,"code":1514,"filename":1515,"language":596,"meta":529,"style":529},"import { CommandBus, QueryBus } from \"@heximon\u002Fcqrs\";\nimport { NotFoundError } from \"@heximon\u002Fruntime\u002Ferrors\";\nimport type { Controller, Get, Post } from \"@heximon\u002Fhttp\";\nimport { CreateUserCommand } from \".\u002Fcommands\u002Fcreate-user.command\";\nimport { GetUserQuery } from \".\u002Fqueries\u002Fget-user.query\";\nimport { type User, UserId } from \".\u002Fuser\";\nimport { CreateUserBody } from \".\u002Fusers.schema\";\n\nexport class UsersController implements Controller\u003C\"\u002Fusers\"> {\n  constructor(\n    private readonly commandBus: CommandBus,\n    private readonly queryBus: QueryBus,\n  ) {}\n\n  public async get(action: Get\u003C\"\u002F:id\">): Promise\u003CUser> {\n    const id = UserId.from(action.request.pathParams.id);\n    const user = await this.queryBus.execute(new GetUserQuery(id));\n    if (!user) throw new NotFoundError(`User ${id} not found`);\n    return user;\n  }\n\n  public async create(action: Post\u003C\"\u002F\", { body: CreateUserBody }>): Promise\u003CUser> {\n    const body = await action.request.readValidatedBody();\n    const id = UserId.generate(); \u002F\u002F mint the id up front\n\n    await this.commandBus.execute(new CreateUserCommand(id, body.name, body.email));\n\n    \u002F\u002F The command returned nothing — read the new state back through the read side.\n    const user = await this.queryBus.execute(new GetUserQuery(id));\n    if (!user) throw new NotFoundError(`User ${id} not found`);\n\n    action.response.status = 201;\n    return user;\n  }\n}\n","users.controller.ts",[531,1517,1518,1544,1566,1600,1621,1642,1669,1691,1695,1721,1727,1743,1758,1764,1768,1810,1849,1885,1934,1943,1948,1953,2004,2031,2056,2061,2106,2111,2117,2150,2189,2194,2217,2226,2231],{"__ignoreMap":529},[534,1519,1520,1522,1524,1527,1529,1532,1534,1536,1538,1540,1542],{"class":536,"line":537},[534,1521,604],{"class":603},[534,1523,608],{"class":607},[534,1525,1526],{"class":611}," CommandBus",[534,1528,725],{"class":607},[534,1530,1531],{"class":611}," QueryBus",[534,1533,615],{"class":607},[534,1535,618],{"class":603},[534,1537,621],{"class":607},[534,1539,790],{"class":543},[534,1541,627],{"class":607},[534,1543,630],{"class":607},[534,1545,1546,1548,1550,1553,1555,1557,1559,1562,1564],{"class":536,"line":633},[534,1547,604],{"class":603},[534,1549,608],{"class":607},[534,1551,1552],{"class":611}," NotFoundError",[534,1554,615],{"class":607},[534,1556,618],{"class":603},[534,1558,621],{"class":607},[534,1560,1561],{"class":543},"@heximon\u002Fruntime\u002Ferrors",[534,1563,627],{"class":607},[534,1565,630],{"class":607},[534,1567,1568,1570,1572,1574,1577,1579,1582,1584,1587,1589,1591,1593,1596,1598],{"class":536,"line":656},[534,1569,604],{"class":603},[534,1571,801],{"class":603},[534,1573,608],{"class":607},[534,1575,1576],{"class":611}," Controller",[534,1578,725],{"class":607},[534,1580,1581],{"class":611}," Get",[534,1583,725],{"class":607},[534,1585,1586],{"class":611}," Post",[534,1588,615],{"class":607},[534,1590,618],{"class":603},[534,1592,621],{"class":607},[534,1594,1595],{"class":543},"@heximon\u002Fhttp",[534,1597,627],{"class":607},[534,1599,630],{"class":607},[534,1601,1602,1604,1606,1608,1610,1612,1614,1617,1619],{"class":536,"line":679},[534,1603,604],{"class":603},[534,1605,608],{"class":607},[534,1607,834],{"class":611},[534,1609,615],{"class":607},[534,1611,618],{"class":603},[534,1613,621],{"class":607},[534,1615,1616],{"class":543},".\u002Fcommands\u002Fcreate-user.command",[534,1618,627],{"class":607},[534,1620,630],{"class":607},[534,1622,1623,1625,1627,1629,1631,1633,1635,1638,1640],{"class":536,"line":686},[534,1624,604],{"class":603},[534,1626,608],{"class":607},[534,1628,1318],{"class":611},[534,1630,615],{"class":607},[534,1632,618],{"class":603},[534,1634,621],{"class":607},[534,1636,1637],{"class":543},".\u002Fqueries\u002Fget-user.query",[534,1639,627],{"class":607},[534,1641,630],{"class":607},[534,1643,1644,1646,1648,1650,1652,1654,1656,1658,1660,1662,1665,1667],{"class":536,"line":704},[534,1645,604],{"class":603},[534,1647,608],{"class":607},[534,1649,801],{"class":603},[534,1651,1269],{"class":611},[534,1653,725],{"class":607},[534,1655,806],{"class":611},[534,1657,615],{"class":607},[534,1659,618],{"class":603},[534,1661,621],{"class":607},[534,1663,1664],{"class":543},".\u002Fuser",[534,1666,627],{"class":607},[534,1668,630],{"class":607},[534,1670,1671,1673,1675,1678,1680,1682,1684,1687,1689],{"class":536,"line":739},[534,1672,604],{"class":603},[534,1674,608],{"class":607},[534,1676,1677],{"class":611}," CreateUserBody",[534,1679,615],{"class":607},[534,1681,618],{"class":603},[534,1683,621],{"class":607},[534,1685,1686],{"class":543},".\u002Fusers.schema",[534,1688,627],{"class":607},[534,1690,630],{"class":607},[534,1692,1693],{"class":536,"line":887},[534,1694,683],{"emptyLinePlaceholder":682},[534,1696,1697,1699,1701,1704,1706,1708,1710,1712,1715,1717,1719],{"class":536,"line":903},[534,1698,689],{"class":603},[534,1700,831],{"class":830},[534,1702,1703],{"class":540}," UsersController",[534,1705,1056],{"class":830},[534,1707,1576],{"class":540},[534,1709,1061],{"class":607},[534,1711,627],{"class":607},[534,1713,1714],{"class":543},"\u002Fusers",[534,1716,627],{"class":607},[534,1718,1067],{"class":607},[534,1720,842],{"class":607},[534,1722,1723,1725],{"class":536,"line":911},[534,1724,847],{"class":830},[534,1726,850],{"class":607},[534,1728,1729,1732,1734,1737,1739,1741],{"class":536,"line":921},[534,1730,1731],{"class":830},"    private",[534,1733,858],{"class":830},[534,1735,1736],{"class":861}," commandBus",[534,1738,711],{"class":607},[534,1740,1526],{"class":540},[534,1742,736],{"class":607},[534,1744,1745,1747,1749,1752,1754,1756],{"class":536,"line":927},[534,1746,1731],{"class":830},[534,1748,858],{"class":830},[534,1750,1751],{"class":861}," queryBus",[534,1753,711],{"class":607},[534,1755,1531],{"class":540},[534,1757,736],{"class":607},[534,1759,1760,1762],{"class":536,"line":1423},[534,1761,906],{"class":607},[534,1763,1092],{"class":607},[534,1765,1766],{"class":536,"line":1428},[534,1767,683],{"emptyLinePlaceholder":682},[534,1769,1770,1772,1775,1778,1780,1783,1785,1787,1789,1791,1794,1796,1799,1802,1804,1806,1808],{"class":536,"line":1454},[534,1771,1101],{"class":830},[534,1773,1774],{"class":830}," async",[534,1776,1777],{"class":707}," get",[534,1779,698],{"class":607},[534,1781,1782],{"class":861},"action",[534,1784,711],{"class":607},[534,1786,1581],{"class":540},[534,1788,1061],{"class":607},[534,1790,627],{"class":607},[534,1792,1793],{"class":543},"\u002F:id",[534,1795,627],{"class":607},[534,1797,1798],{"class":607},">):",[534,1800,1801],{"class":540}," Promise",[534,1803,1061],{"class":607},[534,1805,1327],{"class":540},[534,1807,1067],{"class":607},[534,1809,842],{"class":607},[534,1811,1812,1815,1817,1820,1822,1824,1827,1829,1831,1833,1836,1838,1841,1843,1845,1847],{"class":536,"line":1482},[534,1813,1814],{"class":830},"    const",[534,1816,862],{"class":611},[534,1818,1819],{"class":607}," =",[534,1821,806],{"class":611},[534,1823,1132],{"class":607},[534,1825,1826],{"class":695},"from",[534,1828,698],{"class":707},[534,1830,1782],{"class":611},[534,1832,1132],{"class":607},[534,1834,1835],{"class":611},"request",[534,1837,1132],{"class":607},[534,1839,1840],{"class":611},"pathParams",[534,1842,1132],{"class":607},[534,1844,1152],{"class":611},[534,1846,745],{"class":707},[534,1848,630],{"class":607},[534,1850,1851,1853,1856,1858,1861,1863,1866,1868,1870,1872,1874,1876,1878,1880,1883],{"class":536,"line":1487},[534,1852,1814],{"class":830},[534,1854,1855],{"class":611}," user",[534,1857,1819],{"class":607},[534,1859,1860],{"class":603}," await",[534,1862,1460],{"class":607},[534,1864,1865],{"class":611},"queryBus",[534,1867,1132],{"class":607},[534,1869,1510],{"class":695},[534,1871,698],{"class":707},[534,1873,717],{"class":607},[534,1875,1318],{"class":695},[534,1877,698],{"class":707},[534,1879,1152],{"class":611},[534,1881,1882],{"class":707},"))",[534,1884,630],{"class":607},[534,1886,1888,1891,1894,1897,1900,1903,1906,1908,1910,1912,1915,1918,1921,1923,1925,1928,1930,1932],{"class":536,"line":1887},18,[534,1889,1890],{"class":603},"    if",[534,1892,1893],{"class":707}," (",[534,1895,1896],{"class":607},"!",[534,1898,1899],{"class":611},"user",[534,1901,1902],{"class":707},") ",[534,1904,1905],{"class":603},"throw",[534,1907,728],{"class":607},[534,1909,1552],{"class":695},[534,1911,698],{"class":707},[534,1913,1914],{"class":607},"`",[534,1916,1917],{"class":543},"User ",[534,1919,1920],{"class":607},"${",[534,1922,1152],{"class":611},[534,1924,742],{"class":607},[534,1926,1927],{"class":543}," not found",[534,1929,1914],{"class":607},[534,1931,745],{"class":707},[534,1933,630],{"class":607},[534,1935,1937,1939,1941],{"class":536,"line":1936},19,[534,1938,1457],{"class":603},[534,1940,1855],{"class":611},[534,1942,630],{"class":607},[534,1944,1946],{"class":536,"line":1945},20,[534,1947,924],{"class":607},[534,1949,1951],{"class":536,"line":1950},21,[534,1952,683],{"emptyLinePlaceholder":682},[534,1954,1956,1958,1960,1963,1965,1967,1969,1971,1973,1975,1978,1980,1982,1984,1987,1989,1991,1994,1996,1998,2000,2002],{"class":536,"line":1955},22,[534,1957,1101],{"class":830},[534,1959,1774],{"class":830},[534,1961,1962],{"class":707}," create",[534,1964,698],{"class":607},[534,1966,1782],{"class":861},[534,1968,711],{"class":607},[534,1970,1586],{"class":540},[534,1972,1061],{"class":607},[534,1974,627],{"class":607},[534,1976,1977],{"class":543},"\u002F",[534,1979,627],{"class":607},[534,1981,725],{"class":607},[534,1983,608],{"class":607},[534,1985,1986],{"class":707}," body",[534,1988,711],{"class":607},[534,1990,1677],{"class":540},[534,1992,1993],{"class":607}," }>):",[534,1995,1801],{"class":540},[534,1997,1061],{"class":607},[534,1999,1327],{"class":540},[534,2001,1067],{"class":607},[534,2003,842],{"class":607},[534,2005,2007,2009,2011,2013,2015,2018,2020,2022,2024,2027,2029],{"class":536,"line":2006},23,[534,2008,1814],{"class":830},[534,2010,1986],{"class":611},[534,2012,1819],{"class":607},[534,2014,1860],{"class":603},[534,2016,2017],{"class":611}," action",[534,2019,1132],{"class":607},[534,2021,1835],{"class":611},[534,2023,1132],{"class":607},[534,2025,2026],{"class":695},"readValidatedBody",[534,2028,722],{"class":707},[534,2030,630],{"class":607},[534,2032,2034,2036,2038,2040,2042,2044,2047,2049,2052],{"class":536,"line":2033},24,[534,2035,1814],{"class":830},[534,2037,862],{"class":611},[534,2039,1819],{"class":607},[534,2041,806],{"class":611},[534,2043,1132],{"class":607},[534,2045,2046],{"class":695},"generate",[534,2048,722],{"class":707},[534,2050,2051],{"class":607},";",[534,2053,2055],{"class":2054},"sHwdD"," \u002F\u002F mint the id up front\n",[534,2057,2059],{"class":536,"line":2058},25,[534,2060,683],{"emptyLinePlaceholder":682},[534,2062,2064,2067,2069,2072,2074,2076,2078,2080,2082,2084,2086,2088,2090,2092,2094,2096,2098,2100,2102,2104],{"class":536,"line":2063},26,[534,2065,2066],{"class":603},"    await",[534,2068,1460],{"class":607},[534,2070,2071],{"class":611},"commandBus",[534,2073,1132],{"class":607},[534,2075,1510],{"class":695},[534,2077,698],{"class":707},[534,2079,717],{"class":607},[534,2081,834],{"class":695},[534,2083,698],{"class":707},[534,2085,1152],{"class":611},[534,2087,725],{"class":607},[534,2089,1986],{"class":611},[534,2091,1132],{"class":607},[534,2093,1165],{"class":611},[534,2095,725],{"class":607},[534,2097,1986],{"class":611},[534,2099,1132],{"class":607},[534,2101,1178],{"class":611},[534,2103,1882],{"class":707},[534,2105,630],{"class":607},[534,2107,2109],{"class":536,"line":2108},27,[534,2110,683],{"emptyLinePlaceholder":682},[534,2112,2114],{"class":536,"line":2113},28,[534,2115,2116],{"class":2054},"    \u002F\u002F The command returned nothing — read the new state back through the read side.\n",[534,2118,2120,2122,2124,2126,2128,2130,2132,2134,2136,2138,2140,2142,2144,2146,2148],{"class":536,"line":2119},29,[534,2121,1814],{"class":830},[534,2123,1855],{"class":611},[534,2125,1819],{"class":607},[534,2127,1860],{"class":603},[534,2129,1460],{"class":607},[534,2131,1865],{"class":611},[534,2133,1132],{"class":607},[534,2135,1510],{"class":695},[534,2137,698],{"class":707},[534,2139,717],{"class":607},[534,2141,1318],{"class":695},[534,2143,698],{"class":707},[534,2145,1152],{"class":611},[534,2147,1882],{"class":707},[534,2149,630],{"class":607},[534,2151,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181,2183,2185,2187],{"class":536,"line":2152},30,[534,2154,1890],{"class":603},[534,2156,1893],{"class":707},[534,2158,1896],{"class":607},[534,2160,1899],{"class":611},[534,2162,1902],{"class":707},[534,2164,1905],{"class":603},[534,2166,728],{"class":607},[534,2168,1552],{"class":695},[534,2170,698],{"class":707},[534,2172,1914],{"class":607},[534,2174,1917],{"class":543},[534,2176,1920],{"class":607},[534,2178,1152],{"class":611},[534,2180,742],{"class":607},[534,2182,1927],{"class":543},[534,2184,1914],{"class":607},[534,2186,745],{"class":707},[534,2188,630],{"class":607},[534,2190,2192],{"class":536,"line":2191},31,[534,2193,683],{"emptyLinePlaceholder":682},[534,2195,2197,2200,2202,2205,2207,2210,2212,2215],{"class":536,"line":2196},32,[534,2198,2199],{"class":611},"    action",[534,2201,1132],{"class":607},[534,2203,2204],{"class":611},"response",[534,2206,1132],{"class":607},[534,2208,2209],{"class":611},"status",[534,2211,1819],{"class":607},[534,2213,2214],{"class":1188}," 201",[534,2216,630],{"class":607},[534,2218,2220,2222,2224],{"class":536,"line":2219},33,[534,2221,1457],{"class":603},[534,2223,1855],{"class":611},[534,2225,630],{"class":607},[534,2227,2229],{"class":536,"line":2228},34,[534,2230,924],{"class":607},[534,2232,2234],{"class":536,"line":2233},35,[534,2235,930],{"class":607},[932,2237,2238,2239,2242,2243,2246,2247,2249],{"type":934},"Prefer a base class? ",[531,2240,2241],{},"CqrsController"," injects both buses for you and exposes them as\n",[531,2244,2245],{},"protected readonly",". It's optional — a plain ",[531,2248,1506],{}," listing the buses in its own constructor\nworks identically.",[512,2251,2253],{"id":2252},"customize-dispatch-with-interceptors","Customize dispatch with interceptors",[499,2255,2256,2257,2260,2261,2264,2265,2268],{},"Interceptors are the main place to add cross-cutting behavior — logging, metrics, auth, caching, or\nshort-circuiting a dispatch. ",[531,2258,2259],{},"intercept(message, next)"," is an onion: call ",[531,2262,2263],{},"next()"," to continue to the\nhandler, or return ",[503,2266,2267],{},"without"," calling it to short-circuit (a query interceptor can return a cached\nresult this way).",[499,2270,2271,2272,2275,2276,2279,2280,1132],{},"Scope one to a single message (",[531,2273,2274],{},"implements CommandInterceptor\u003CCreateUserCommand>",") or make it app-wide\n(",[531,2277,2278],{},"implements CommandInterceptor"," — no type argument). The same scoping applies to ",[531,2281,2282],{},"QueryInterceptor",[523,2284,2287],{"className":593,"code":2285,"filename":2286,"language":596,"meta":529,"style":529},"import { Command, type CommandInterceptor, MessageClassName } from \"@heximon\u002Fcqrs\";\nimport { AuditLog } from \"..\u002Faudit-log\";\n\nexport class AuditCommandInterceptor implements CommandInterceptor {  \u002F\u002F app-wide (no type arg)\n  constructor(private readonly auditLog: AuditLog) {}\n\n  public async intercept(command: Command, next: () => Promise\u003Cvoid>): Promise\u003Cvoid> {\n    this.auditLog.record({ command: MessageClassName.of(command), phase: \"before\" });\n    await next(); \u002F\u002F omit this call to short-circuit the dispatch\n    this.auditLog.record({ command: MessageClassName.of(command), phase: \"after\" });\n  }\n}\n","audit-command.interceptor.ts",[531,2288,2289,2321,2343,2347,2365,2386,2390,2438,2490,2503,2552,2556],{"__ignoreMap":529},[534,2290,2291,2293,2295,2297,2299,2301,2304,2306,2309,2311,2313,2315,2317,2319],{"class":536,"line":537},[534,2292,604],{"class":603},[534,2294,608],{"class":607},[534,2296,781],{"class":611},[534,2298,725],{"class":607},[534,2300,801],{"class":603},[534,2302,2303],{"class":611}," CommandInterceptor",[534,2305,725],{"class":607},[534,2307,2308],{"class":611}," MessageClassName",[534,2310,615],{"class":607},[534,2312,618],{"class":603},[534,2314,621],{"class":607},[534,2316,790],{"class":543},[534,2318,627],{"class":607},[534,2320,630],{"class":607},[534,2322,2323,2325,2327,2330,2332,2334,2336,2339,2341],{"class":536,"line":633},[534,2324,604],{"class":603},[534,2326,608],{"class":607},[534,2328,2329],{"class":611}," AuditLog",[534,2331,615],{"class":607},[534,2333,618],{"class":603},[534,2335,621],{"class":607},[534,2337,2338],{"class":543},"..\u002Faudit-log",[534,2340,627],{"class":607},[534,2342,630],{"class":607},[534,2344,2345],{"class":536,"line":656},[534,2346,683],{"emptyLinePlaceholder":682},[534,2348,2349,2351,2353,2356,2358,2360,2362],{"class":536,"line":679},[534,2350,689],{"class":603},[534,2352,831],{"class":830},[534,2354,2355],{"class":540}," AuditCommandInterceptor",[534,2357,1056],{"class":830},[534,2359,2303],{"class":540},[534,2361,608],{"class":607},[534,2363,2364],{"class":2054},"  \u002F\u002F app-wide (no type arg)\n",[534,2366,2367,2369,2371,2373,2375,2378,2380,2382,2384],{"class":536,"line":686},[534,2368,847],{"class":830},[534,2370,698],{"class":607},[534,2372,1078],{"class":830},[534,2374,858],{"class":830},[534,2376,2377],{"class":861}," auditLog",[534,2379,711],{"class":607},[534,2381,2329],{"class":540},[534,2383,745],{"class":607},[534,2385,1092],{"class":607},[534,2387,2388],{"class":536,"line":704},[534,2389,683],{"emptyLinePlaceholder":682},[534,2391,2392,2394,2396,2399,2401,2403,2405,2407,2409,2412,2414,2417,2420,2422,2424,2426,2428,2430,2432,2434,2436],{"class":536,"line":739},[534,2393,1101],{"class":830},[534,2395,1774],{"class":830},[534,2397,2398],{"class":707}," intercept",[534,2400,698],{"class":607},[534,2402,1109],{"class":861},[534,2404,711],{"class":607},[534,2406,781],{"class":540},[534,2408,725],{"class":607},[534,2410,2411],{"class":695}," next",[534,2413,711],{"class":607},[534,2415,2416],{"class":607}," ()",[534,2418,2419],{"class":830}," =>",[534,2421,1801],{"class":540},[534,2423,1061],{"class":607},[534,2425,765],{"class":540},[534,2427,1798],{"class":607},[534,2429,1801],{"class":540},[534,2431,1061],{"class":607},[534,2433,765],{"class":540},[534,2435,1067],{"class":607},[534,2437,842],{"class":607},[534,2439,2440,2442,2445,2447,2450,2452,2454,2456,2458,2460,2462,2465,2467,2469,2471,2473,2476,2478,2480,2482,2484,2486,2488],{"class":536,"line":887},[534,2441,1126],{"class":607},[534,2443,2444],{"class":611},"auditLog",[534,2446,1132],{"class":607},[534,2448,2449],{"class":695},"record",[534,2451,698],{"class":707},[534,2453,1140],{"class":607},[534,2455,1147],{"class":707},[534,2457,711],{"class":607},[534,2459,2308],{"class":611},[534,2461,1132],{"class":607},[534,2463,2464],{"class":695},"of",[534,2466,698],{"class":707},[534,2468,1109],{"class":611},[534,2470,745],{"class":707},[534,2472,725],{"class":607},[534,2474,2475],{"class":707}," phase",[534,2477,711],{"class":607},[534,2479,621],{"class":607},[534,2481,938],{"class":543},[534,2483,627],{"class":607},[534,2485,615],{"class":607},[534,2487,745],{"class":707},[534,2489,630],{"class":607},[534,2491,2492,2494,2496,2498,2500],{"class":536,"line":903},[534,2493,2066],{"class":603},[534,2495,2411],{"class":695},[534,2497,722],{"class":707},[534,2499,2051],{"class":607},[534,2501,2502],{"class":2054}," \u002F\u002F omit this call to short-circuit the dispatch\n",[534,2504,2505,2507,2509,2511,2513,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2544,2546,2548,2550],{"class":536,"line":911},[534,2506,1126],{"class":607},[534,2508,2444],{"class":611},[534,2510,1132],{"class":607},[534,2512,2449],{"class":695},[534,2514,698],{"class":707},[534,2516,1140],{"class":607},[534,2518,1147],{"class":707},[534,2520,711],{"class":607},[534,2522,2308],{"class":611},[534,2524,1132],{"class":607},[534,2526,2464],{"class":695},[534,2528,698],{"class":707},[534,2530,1109],{"class":611},[534,2532,745],{"class":707},[534,2534,725],{"class":607},[534,2536,2475],{"class":707},[534,2538,711],{"class":607},[534,2540,621],{"class":607},[534,2542,2543],{"class":543},"after",[534,2545,627],{"class":607},[534,2547,615],{"class":607},[534,2549,745],{"class":707},[534,2551,630],{"class":607},[534,2553,2554],{"class":536,"line":921},[534,2555,924],{"class":607},[534,2557,2558],{"class":536,"line":927},[534,2559,930],{"class":607},[499,2561,2562,2565,2566,2569],{},[531,2563,2564],{},"command.constructor.name"," mangles under production minification, so this interceptor logs\n",[531,2567,2568],{},"MessageClassName.of(command)"," instead — the compiler-stamped name that survives it.",[499,2571,2572,2573,2576],{},"A query interceptor short-circuits by returning a value without calling ",[531,2574,2575],{},"next"," — the right home for a\ncache gate:",[523,2578,2581],{"className":593,"code":2579,"filename":2580,"language":596,"meta":529,"style":529},"import type { QueryInterceptor } from \"@heximon\u002Fcqrs\";\nimport type { User } from \"..\u002Fuser\";\nimport { UserCache } from \"..\u002Fuser-cache\";\nimport type { GetUserQuery } from \"..\u002Fqueries\u002Fget-user.query\";\n\nexport class CacheGetUserInterceptor implements QueryInterceptor\u003CGetUserQuery, User | undefined> {\n  constructor(private readonly cache: UserCache) {}\n\n  public async intercept(\n    query: GetUserQuery,\n    next: () => Promise\u003CUser | undefined>,\n  ): Promise\u003CUser | undefined> {\n    const hit = this.cache.get(query.id);\n    if (hit) return hit; \u002F\u002F short-circuit — handler skipped\n    const result = await next();\n    if (result) this.cache.set(query.id, result);\n    return result;\n  }\n}\n","cache-get-user.interceptor.ts",[531,2582,2583,2606,2628,2650,2673,2677,2706,2727,2731,2741,2752,2776,2795,2826,2847,2864,2901,2909,2913],{"__ignoreMap":529},[534,2584,2585,2587,2589,2591,2594,2596,2598,2600,2602,2604],{"class":536,"line":537},[534,2586,604],{"class":603},[534,2588,801],{"class":603},[534,2590,608],{"class":607},[534,2592,2593],{"class":611}," QueryInterceptor",[534,2595,615],{"class":607},[534,2597,618],{"class":603},[534,2599,621],{"class":607},[534,2601,790],{"class":543},[534,2603,627],{"class":607},[534,2605,630],{"class":607},[534,2607,2608,2610,2612,2614,2616,2618,2620,2622,2624,2626],{"class":536,"line":633},[534,2609,604],{"class":603},[534,2611,801],{"class":603},[534,2613,608],{"class":607},[534,2615,1269],{"class":611},[534,2617,615],{"class":607},[534,2619,618],{"class":603},[534,2621,621],{"class":607},[534,2623,815],{"class":543},[534,2625,627],{"class":607},[534,2627,630],{"class":607},[534,2629,2630,2632,2634,2637,2639,2641,2643,2646,2648],{"class":536,"line":656},[534,2631,604],{"class":603},[534,2633,608],{"class":607},[534,2635,2636],{"class":611}," UserCache",[534,2638,615],{"class":607},[534,2640,618],{"class":603},[534,2642,621],{"class":607},[534,2644,2645],{"class":543},"..\u002Fuser-cache",[534,2647,627],{"class":607},[534,2649,630],{"class":607},[534,2651,2652,2654,2656,2658,2660,2662,2664,2666,2669,2671],{"class":536,"line":679},[534,2653,604],{"class":603},[534,2655,801],{"class":603},[534,2657,608],{"class":607},[534,2659,1318],{"class":611},[534,2661,615],{"class":607},[534,2663,618],{"class":603},[534,2665,621],{"class":607},[534,2667,2668],{"class":543},"..\u002Fqueries\u002Fget-user.query",[534,2670,627],{"class":607},[534,2672,630],{"class":607},[534,2674,2675],{"class":536,"line":686},[534,2676,683],{"emptyLinePlaceholder":682},[534,2678,2679,2681,2683,2686,2688,2690,2692,2694,2696,2698,2700,2702,2704],{"class":536,"line":704},[534,2680,689],{"class":603},[534,2682,831],{"class":830},[534,2684,2685],{"class":540}," CacheGetUserInterceptor",[534,2687,1056],{"class":830},[534,2689,2593],{"class":540},[534,2691,1061],{"class":607},[534,2693,1396],{"class":540},[534,2695,725],{"class":607},[534,2697,1269],{"class":540},[534,2699,1330],{"class":607},[534,2701,1333],{"class":540},[534,2703,1067],{"class":607},[534,2705,842],{"class":607},[534,2707,2708,2710,2712,2714,2716,2719,2721,2723,2725],{"class":536,"line":739},[534,2709,847],{"class":830},[534,2711,698],{"class":607},[534,2713,1078],{"class":830},[534,2715,858],{"class":830},[534,2717,2718],{"class":861}," cache",[534,2720,711],{"class":607},[534,2722,2636],{"class":540},[534,2724,745],{"class":607},[534,2726,1092],{"class":607},[534,2728,2729],{"class":536,"line":887},[534,2730,683],{"emptyLinePlaceholder":682},[534,2732,2733,2735,2737,2739],{"class":536,"line":903},[534,2734,1101],{"class":830},[534,2736,1774],{"class":830},[534,2738,2398],{"class":707},[534,2740,850],{"class":607},[534,2742,2743,2746,2748,2750],{"class":536,"line":911},[534,2744,2745],{"class":861},"    query",[534,2747,711],{"class":607},[534,2749,1318],{"class":540},[534,2751,736],{"class":607},[534,2753,2754,2757,2759,2761,2763,2765,2767,2769,2771,2773],{"class":536,"line":921},[534,2755,2756],{"class":695},"    next",[534,2758,711],{"class":607},[534,2760,2416],{"class":607},[534,2762,2419],{"class":830},[534,2764,1801],{"class":540},[534,2766,1061],{"class":607},[534,2768,1327],{"class":540},[534,2770,1330],{"class":607},[534,2772,1333],{"class":540},[534,2774,2775],{"class":607},">,\n",[534,2777,2778,2781,2783,2785,2787,2789,2791,2793],{"class":536,"line":927},[534,2779,2780],{"class":607},"  ):",[534,2782,1801],{"class":540},[534,2784,1061],{"class":607},[534,2786,1327],{"class":540},[534,2788,1330],{"class":607},[534,2790,1333],{"class":540},[534,2792,1067],{"class":607},[534,2794,842],{"class":607},[534,2796,2797,2799,2802,2804,2806,2809,2811,2814,2816,2818,2820,2822,2824],{"class":536,"line":1423},[534,2798,1814],{"class":830},[534,2800,2801],{"class":611}," hit",[534,2803,1819],{"class":607},[534,2805,1460],{"class":607},[534,2807,2808],{"class":611},"cache",[534,2810,1132],{"class":607},[534,2812,2813],{"class":695},"get",[534,2815,698],{"class":707},[534,2817,1437],{"class":611},[534,2819,1132],{"class":607},[534,2821,1152],{"class":611},[534,2823,745],{"class":707},[534,2825,630],{"class":607},[534,2827,2828,2830,2832,2835,2837,2840,2842,2844],{"class":536,"line":1428},[534,2829,1890],{"class":603},[534,2831,1893],{"class":707},[534,2833,2834],{"class":611},"hit",[534,2836,1902],{"class":707},[534,2838,2839],{"class":603},"return",[534,2841,2801],{"class":611},[534,2843,2051],{"class":607},[534,2845,2846],{"class":2054}," \u002F\u002F short-circuit — handler skipped\n",[534,2848,2849,2851,2854,2856,2858,2860,2862],{"class":536,"line":1454},[534,2850,1814],{"class":830},[534,2852,2853],{"class":611}," result",[534,2855,1819],{"class":607},[534,2857,1860],{"class":603},[534,2859,2411],{"class":695},[534,2861,722],{"class":707},[534,2863,630],{"class":607},[534,2865,2866,2868,2870,2873,2875,2878,2880,2882,2885,2887,2889,2891,2893,2895,2897,2899],{"class":536,"line":1482},[534,2867,1890],{"class":603},[534,2869,1893],{"class":707},[534,2871,2872],{"class":611},"result",[534,2874,1902],{"class":707},[534,2876,2877],{"class":607},"this.",[534,2879,2808],{"class":611},[534,2881,1132],{"class":607},[534,2883,2884],{"class":695},"set",[534,2886,698],{"class":707},[534,2888,1437],{"class":611},[534,2890,1132],{"class":607},[534,2892,1152],{"class":611},[534,2894,725],{"class":607},[534,2896,2853],{"class":611},[534,2898,745],{"class":707},[534,2900,630],{"class":607},[534,2902,2903,2905,2907],{"class":536,"line":1487},[534,2904,1457],{"class":603},[534,2906,2853],{"class":611},[534,2908,630],{"class":607},[534,2910,2911],{"class":536,"line":1887},[534,2912,924],{"class":607},[534,2914,2915],{"class":536,"line":1936},[534,2916,930],{"class":607},[499,2918,2919],{},"Interceptors are ordinary DI participants: their constructor declares dependencies, and the compiler\ncomposes them into the around-chain.",[512,2921,2923],{"id":2922},"per-handler-retry-policy","Per-handler retry policy",[499,2925,2926,2927,2930,2931,2934,2935,2938,2939,2942],{},"The default ",[531,2928,2929],{},"ConcurrencyError"," retry (3 attempts, 100 ms delay) applies to every command. Pass\n",[531,2932,2933],{},"{ retry }"," as a second ",[503,2936,2937],{},"type"," argument to ",[531,2940,2941],{},"CommandHandler"," to override it for a specific command:",[523,2944,2946],{"className":593,"code":2945,"filename":972,"language":596,"meta":529,"style":529},"export class CreateUserCommandHandler implements CommandHandler\u003CCreateUserCommand, {\n  retry: { attempts: 5; delay: 50 };\n}> {\n  \u002F\u002F ...\n}\n",[531,2947,2948,2968,2998,3005,3010],{"__ignoreMap":529},[534,2949,2950,2952,2954,2956,2958,2960,2962,2964,2966],{"class":536,"line":537},[534,2951,689],{"class":603},[534,2953,831],{"class":830},[534,2955,1053],{"class":540},[534,2957,1056],{"class":830},[534,2959,985],{"class":540},[534,2961,1061],{"class":607},[534,2963,1064],{"class":540},[534,2965,725],{"class":607},[534,2967,842],{"class":607},[534,2969,2970,2973,2975,2977,2980,2982,2985,2987,2990,2992,2995],{"class":536,"line":633},[534,2971,2972],{"class":707},"  retry",[534,2974,711],{"class":607},[534,2976,608],{"class":607},[534,2978,2979],{"class":707}," attempts",[534,2981,711],{"class":607},[534,2983,2984],{"class":1188}," 5",[534,2986,2051],{"class":607},[534,2988,2989],{"class":707}," delay",[534,2991,711],{"class":607},[534,2993,2994],{"class":1188}," 50",[534,2996,2997],{"class":607}," };\n",[534,2999,3000,3003],{"class":536,"line":656},[534,3001,3002],{"class":607},"}>",[534,3004,842],{"class":607},[534,3006,3007],{"class":536,"line":679},[534,3008,3009],{"class":2054},"  \u002F\u002F ...\n",[534,3011,3012],{"class":536,"line":686},[534,3013,930],{"class":607},[499,3015,3016,3019,3020,3023,3024,3026,3027,1132],{},[531,3017,3018],{},"retry.attempts"," is required; ",[531,3021,3022],{},"retry.delay"," is the millisecond gap between attempts. Queries are\nnever retried — the ",[531,3025,2933],{}," field is ignored for ",[531,3028,3029],{},"QueryHandler",[512,3031,3033],{"id":3032},"automatic-concurrencyerror-retry","Automatic ConcurrencyError retry",[499,3035,3036,3037,3039,3040,3043],{},"Commands automatically retry on ",[531,3038,2929],{}," — it's baked into the wiring, not your handler. Pair\nit with optimistic locking in your repositories (a ",[531,3041,3042],{},"version"," column): if two concurrent writes conflict,\nthe losing command re-runs with fresh state. Queries are never retried.",[3045,3046,3047,3061],"table",{},[3048,3049,3050],"thead",{},[3051,3052,3053,3058],"tr",{},[3054,3055,3057],"th",{"align":3056},"left","Setting",[3054,3059,3060],{"align":3056},"Default",[3062,3063,3064,3073],"tbody",{},[3051,3065,3066,3070],{},[3067,3068,3069],"td",{"align":3056},"Max attempts",[3067,3071,3072],{"align":3056},"3",[3051,3074,3075,3078],{},[3067,3076,3077],{"align":3056},"Delay between attempts",[3067,3079,3080],{"align":3056},"100 ms",[499,3082,3083,3084,3086,3087,3089,3090,3093],{},"Only ",[531,3085,2929],{}," triggers a retry — every other exception propagates immediately, which keeps\nretries scoped to real contention rather than application bugs. If all attempts are exhausted, the final\n",[531,3088,2929],{}," is rethrown for the caller to surface (usually as a ",[531,3091,3092],{},"409",").",[932,3095,3097,3111],{"type":3096},"info",[499,3098,3099,3101,3102,3104,3105,3107,3108,3110],{},[531,3100,2929],{}," is exported from ",[531,3103,1561],{},", not ",[531,3106,790],{},". Your\nrepositories throw it when the optimistic-concurrency check fails; ",[531,3109,1498],{}," catches and retries it.",[523,3112,3114],{"className":593,"code":3113,"language":596,"meta":529,"style":529},"import { ConcurrencyError } from \"@heximon\u002Fruntime\u002Ferrors\";\n",[531,3115,3116],{"__ignoreMap":529},[534,3117,3118,3120,3122,3125,3127,3129,3131,3133,3135],{"class":536,"line":537},[534,3119,604],{"class":603},[534,3121,608],{"class":607},[534,3123,3124],{"class":611}," ConcurrencyError",[534,3126,615],{"class":607},[534,3128,618],{"class":603},[534,3130,621],{"class":607},[534,3132,1561],{"class":543},[534,3134,627],{"class":607},[534,3136,630],{"class":607},[512,3138,3140],{"id":3139},"command-transaction-wrap","Command transaction wrap",[499,3142,3143,3144,3146,3147,3150],{},"When a command handler's owning module binds a ",[531,3145,77],{},", the compiler wraps that command's dispatch in\n",[531,3148,3149],{},"Database.runInTransaction"," automatically — so the handler's writes and the domain events it emits are atomic\n(a throw rolls the whole unit back). You do nothing: the wrap is derived from the module scope.",[499,3152,3153,3154,3156,3157,3160,3161,3164,3165,3167],{},"That automatic resolution needs exactly one ",[531,3155,77],{},". When a module binds ",[503,3158,3159],{},"more than one"," — a write\nprimary and a read replica, say — the wrap target is ambiguous, and the compiler errors rather than guessing.\nDisambiguate with the optional ",[531,3162,3163],{},"{ database }"," field on the second ",[503,3166,2937],{}," argument:",[523,3169,3172],{"className":593,"code":3170,"filename":3171,"language":596,"meta":529,"style":529},"import type { CommandHandler } from \"@heximon\u002Fcqrs\";\nimport { PlaceOrderCommand } from \".\u002Fplace-order.command\";\nimport type { WriteDatabase } from \".\u002Fdatabases\";\n\n\u002F\u002F Wrap on the named writing database (the module also binds a read replica).\nexport class PlaceOrderHandler implements CommandHandler\u003CPlaceOrderCommand, { database: WriteDatabase }> {\n  handle(command: PlaceOrderCommand): void {\n    \u002F\u002F ...\n  }\n}\n","place-order.handler.ts",[531,3173,3174,3196,3218,3242,3246,3251,3285,3304,3309,3313],{"__ignoreMap":529},[534,3175,3176,3178,3180,3182,3184,3186,3188,3190,3192,3194],{"class":536,"line":537},[534,3177,604],{"class":603},[534,3179,801],{"class":603},[534,3181,608],{"class":607},[534,3183,985],{"class":611},[534,3185,615],{"class":607},[534,3187,618],{"class":603},[534,3189,621],{"class":607},[534,3191,790],{"class":543},[534,3193,627],{"class":607},[534,3195,630],{"class":607},[534,3197,3198,3200,3202,3205,3207,3209,3211,3214,3216],{"class":536,"line":633},[534,3199,604],{"class":603},[534,3201,608],{"class":607},[534,3203,3204],{"class":611}," PlaceOrderCommand",[534,3206,615],{"class":607},[534,3208,618],{"class":603},[534,3210,621],{"class":607},[534,3212,3213],{"class":543},".\u002Fplace-order.command",[534,3215,627],{"class":607},[534,3217,630],{"class":607},[534,3219,3220,3222,3224,3226,3229,3231,3233,3235,3238,3240],{"class":536,"line":656},[534,3221,604],{"class":603},[534,3223,801],{"class":603},[534,3225,608],{"class":607},[534,3227,3228],{"class":611}," WriteDatabase",[534,3230,615],{"class":607},[534,3232,618],{"class":603},[534,3234,621],{"class":607},[534,3236,3237],{"class":543},".\u002Fdatabases",[534,3239,627],{"class":607},[534,3241,630],{"class":607},[534,3243,3244],{"class":536,"line":679},[534,3245,683],{"emptyLinePlaceholder":682},[534,3247,3248],{"class":536,"line":686},[534,3249,3250],{"class":2054},"\u002F\u002F Wrap on the named writing database (the module also binds a read replica).\n",[534,3252,3253,3255,3257,3260,3262,3264,3266,3269,3271,3273,3276,3278,3280,3283],{"class":536,"line":704},[534,3254,689],{"class":603},[534,3256,831],{"class":830},[534,3258,3259],{"class":540}," PlaceOrderHandler",[534,3261,1056],{"class":830},[534,3263,985],{"class":540},[534,3265,1061],{"class":607},[534,3267,3268],{"class":540},"PlaceOrderCommand",[534,3270,725],{"class":607},[534,3272,608],{"class":607},[534,3274,3275],{"class":707}," database",[534,3277,711],{"class":607},[534,3279,3228],{"class":540},[534,3281,3282],{"class":607}," }>",[534,3284,842],{"class":607},[534,3286,3287,3290,3292,3294,3296,3298,3300,3302],{"class":536,"line":739},[534,3288,3289],{"class":707},"  handle",[534,3291,698],{"class":607},[534,3293,1109],{"class":861},[534,3295,711],{"class":607},[534,3297,3204],{"class":540},[534,3299,1116],{"class":607},[534,3301,1119],{"class":540},[534,3303,842],{"class":607},[534,3305,3306],{"class":536,"line":887},[534,3307,3308],{"class":2054},"    \u002F\u002F ...\n",[534,3310,3311],{"class":536,"line":903},[534,3312,924],{"class":607},[534,3314,3315],{"class":536,"line":911},[534,3316,930],{"class":607},[499,3318,3319,3320,3323,3324,3327,3328,711],{},"Pass ",[531,3321,3322],{},"{ database: false }"," to opt a command ",[503,3325,3326],{},"out"," of the wrap entirely — for a read-only command, or one\nthat manages its own transactions — even though its module binds a ",[531,3329,77],{},[523,3331,3334],{"className":593,"code":3332,"filename":3333,"language":596,"meta":529,"style":529},"import type { CommandHandler } from \"@heximon\u002Fcqrs\";\nimport { RefreshViewCommand } from \".\u002Frefresh-view.command\";\n\nexport class RefreshViewHandler implements CommandHandler\u003CRefreshViewCommand, { database: false }> {\n  handle(command: RefreshViewCommand): void {\n    \u002F\u002F ...\n  }\n}\n","refresh-view.handler.ts",[531,3335,3336,3358,3380,3384,3417,3435,3439,3443],{"__ignoreMap":529},[534,3337,3338,3340,3342,3344,3346,3348,3350,3352,3354,3356],{"class":536,"line":537},[534,3339,604],{"class":603},[534,3341,801],{"class":603},[534,3343,608],{"class":607},[534,3345,985],{"class":611},[534,3347,615],{"class":607},[534,3349,618],{"class":603},[534,3351,621],{"class":607},[534,3353,790],{"class":543},[534,3355,627],{"class":607},[534,3357,630],{"class":607},[534,3359,3360,3362,3364,3367,3369,3371,3373,3376,3378],{"class":536,"line":633},[534,3361,604],{"class":603},[534,3363,608],{"class":607},[534,3365,3366],{"class":611}," RefreshViewCommand",[534,3368,615],{"class":607},[534,3370,618],{"class":603},[534,3372,621],{"class":607},[534,3374,3375],{"class":543},".\u002Frefresh-view.command",[534,3377,627],{"class":607},[534,3379,630],{"class":607},[534,3381,3382],{"class":536,"line":656},[534,3383,683],{"emptyLinePlaceholder":682},[534,3385,3386,3388,3390,3393,3395,3397,3399,3402,3404,3406,3408,3410,3413,3415],{"class":536,"line":679},[534,3387,689],{"class":603},[534,3389,831],{"class":830},[534,3391,3392],{"class":540}," RefreshViewHandler",[534,3394,1056],{"class":830},[534,3396,985],{"class":540},[534,3398,1061],{"class":607},[534,3400,3401],{"class":540},"RefreshViewCommand",[534,3403,725],{"class":607},[534,3405,608],{"class":607},[534,3407,3275],{"class":707},[534,3409,711],{"class":607},[534,3411,3412],{"class":540}," false",[534,3414,3282],{"class":607},[534,3416,842],{"class":607},[534,3418,3419,3421,3423,3425,3427,3429,3431,3433],{"class":536,"line":686},[534,3420,3289],{"class":707},[534,3422,698],{"class":607},[534,3424,1109],{"class":861},[534,3426,711],{"class":607},[534,3428,3366],{"class":540},[534,3430,1116],{"class":607},[534,3432,1119],{"class":540},[534,3434,842],{"class":607},[534,3436,3437],{"class":536,"line":704},[534,3438,3308],{"class":2054},[534,3440,3441],{"class":536,"line":739},[534,3442,924],{"class":607},[534,3444,3445],{"class":536,"line":887},[534,3446,930],{"class":607},[3045,3448,3449,3460],{},[3048,3450,3451],{},[3051,3452,3453,3457],{},[3054,3454,3455],{"align":3056},[531,3456,3163],{},[3054,3458,3459],{"align":3056},"Behavior",[3062,3461,3462,3473,3483],{},[3051,3463,3464,3467],{},[3067,3465,3466],{"align":3056},"omitted (default)",[3067,3468,3469,3470,3472],{"align":3056},"Auto: zero ",[531,3471,77],{},"s in scope → no wrap; exactly one → wrap on it; two or more → a build error.",[3051,3474,3475,3480],{},[3067,3476,3477,3478,831],{"align":3056},"a concrete ",[531,3479,77],{},[3067,3481,3482],{"align":3056},"Wrap on that named database (verified resolvable in the module's scope).",[3051,3484,3485,3490],{},[3067,3486,3487],{"align":3056},[531,3488,3489],{},"false",[3067,3491,3492,3493,1132],{"align":3056},"Dispatch unwrapped, even when the module binds a ",[531,3494,77],{},[499,3496,3497,3498,3500,3501,1499,3504,3506],{},"The ",[531,3499,3163],{}," field combines with ",[531,3502,3503],{},"{ override }",[531,3505,2933],{}," in the same options literal. It is read\nonly for commands — queries are never wrapped in a transaction.",[932,3508,3509,3527],{"type":3096},[499,3510,3511,3514,3515,1893,3518,3521,3522,1893,3525,3093],{},[503,3512,3513],{},"Query handler options are an extension point."," The options interface is split per family —\n",[531,3516,3517],{},"CommandHandlerOptions",[531,3519,3520],{},"{ override, retry, database }",") and ",[531,3523,3524],{},"QueryHandlerOptions",[531,3526,3503],{},[499,3528,3529,3530,3533,3534,3536,3537,3543,3544,3546,3547,1132],{},"A downstream package can ",[503,3531,3532],{},"augment"," ",[531,3535,3524],{}," with its own serializable option; the compiler\nforwards any option it does not itself consume onto the query class, where a runtime interceptor reads it. For\nexample, ",[3538,3539,3540],"a",{"href":162},[531,3541,3542],{},"@heximon\u002Fcache"," adds a ",[531,3545,2808],{}," policy so a query handler declares its caching\ninline: ",[531,3548,3549],{},"implements QueryHandler\u003CGetProductQuery, { cache: { ttlSeconds: 30; tags: [\"product\"] } }>",[512,3551,3553],{"id":3552},"wire-the-module","Wire the module",[499,3555,3556,3557,3560,3561,3564,3565,3568,3569,1132],{},"CQRS participants are declared under the ",[531,3558,3559],{},"cqrs"," namespace — ",[503,3562,3563],{},"never"," in ",[531,3566,3567],{},"providers",". The compiler routes\nhandlers to their buses and interceptors into the around-chain. Plain injectables (the store, the audit\nlog) stay in ",[531,3570,3567],{},[523,3572,3575],{"className":593,"code":3573,"filename":3574,"language":596,"meta":529,"style":529},"import { Module } from \"@heximon\u002Fruntime\";\nimport { CreateUserCommandHandler } from \".\u002Fcommands\u002Fcreate-user.handler\";\nimport { UpdateUserCommandHandler } from \".\u002Fcommands\u002Fupdate-user.handler\";\nimport { GetUserQueryHandler } from \".\u002Fqueries\u002Fget-user.handler\";\nimport { ListUsersQueryHandler } from \".\u002Fqueries\u002Flist-users.handler\";\nimport { AuditCommandInterceptor } from \".\u002Finterceptors\u002Faudit-command.interceptor\";\nimport { CacheGetUserInterceptor } from \".\u002Finterceptors\u002Fcache-get-user.interceptor\";\nimport { UsersController } from \".\u002Fusers.controller\";\nimport { AuditLog } from \".\u002Faudit-log\";\nimport { UserCache } from \".\u002Fuser-cache\";\nimport { UserStore } from \".\u002Fuser.store\";\n\nexport class UsersModule extends Module({\n  providers: [UserStore, AuditLog, UserCache],\n  http: { controllers: [UsersController] },\n  cqrs: {\n    commandHandlers: [CreateUserCommandHandler, UpdateUserCommandHandler],\n    queryHandlers: [GetUserQueryHandler, ListUsersQueryHandler],\n    commandInterceptors: [AuditCommandInterceptor],\n    queryInterceptors: [CacheGetUserInterceptor],\n  },\n  exports: [UserStore, AuditLog],\n}) {}\n","users.module.ts",[531,3576,3577,3599,3620,3642,3663,3685,3706,3727,3748,3769,3790,3811,3815,3832,3853,3873,3882,3899,3916,3928,3940,3945,3961],{"__ignoreMap":529},[534,3578,3579,3581,3583,3586,3588,3590,3592,3595,3597],{"class":536,"line":537},[534,3580,604],{"class":603},[534,3582,608],{"class":607},[534,3584,3585],{"class":611}," Module",[534,3587,615],{"class":607},[534,3589,618],{"class":603},[534,3591,621],{"class":607},[534,3593,3594],{"class":543},"@heximon\u002Fruntime",[534,3596,627],{"class":607},[534,3598,630],{"class":607},[534,3600,3601,3603,3605,3607,3609,3611,3613,3616,3618],{"class":536,"line":633},[534,3602,604],{"class":603},[534,3604,608],{"class":607},[534,3606,1053],{"class":611},[534,3608,615],{"class":607},[534,3610,618],{"class":603},[534,3612,621],{"class":607},[534,3614,3615],{"class":543},".\u002Fcommands\u002Fcreate-user.handler",[534,3617,627],{"class":607},[534,3619,630],{"class":607},[534,3621,3622,3624,3626,3629,3631,3633,3635,3638,3640],{"class":536,"line":656},[534,3623,604],{"class":603},[534,3625,608],{"class":607},[534,3627,3628],{"class":611}," UpdateUserCommandHandler",[534,3630,615],{"class":607},[534,3632,618],{"class":603},[534,3634,621],{"class":607},[534,3636,3637],{"class":543},".\u002Fcommands\u002Fupdate-user.handler",[534,3639,627],{"class":607},[534,3641,630],{"class":607},[534,3643,3644,3646,3648,3650,3652,3654,3656,3659,3661],{"class":536,"line":679},[534,3645,604],{"class":603},[534,3647,608],{"class":607},[534,3649,1387],{"class":611},[534,3651,615],{"class":607},[534,3653,618],{"class":603},[534,3655,621],{"class":607},[534,3657,3658],{"class":543},".\u002Fqueries\u002Fget-user.handler",[534,3660,627],{"class":607},[534,3662,630],{"class":607},[534,3664,3665,3667,3669,3672,3674,3676,3678,3681,3683],{"class":536,"line":686},[534,3666,604],{"class":603},[534,3668,608],{"class":607},[534,3670,3671],{"class":611}," ListUsersQueryHandler",[534,3673,615],{"class":607},[534,3675,618],{"class":603},[534,3677,621],{"class":607},[534,3679,3680],{"class":543},".\u002Fqueries\u002Flist-users.handler",[534,3682,627],{"class":607},[534,3684,630],{"class":607},[534,3686,3687,3689,3691,3693,3695,3697,3699,3702,3704],{"class":536,"line":704},[534,3688,604],{"class":603},[534,3690,608],{"class":607},[534,3692,2355],{"class":611},[534,3694,615],{"class":607},[534,3696,618],{"class":603},[534,3698,621],{"class":607},[534,3700,3701],{"class":543},".\u002Finterceptors\u002Faudit-command.interceptor",[534,3703,627],{"class":607},[534,3705,630],{"class":607},[534,3707,3708,3710,3712,3714,3716,3718,3720,3723,3725],{"class":536,"line":739},[534,3709,604],{"class":603},[534,3711,608],{"class":607},[534,3713,2685],{"class":611},[534,3715,615],{"class":607},[534,3717,618],{"class":603},[534,3719,621],{"class":607},[534,3721,3722],{"class":543},".\u002Finterceptors\u002Fcache-get-user.interceptor",[534,3724,627],{"class":607},[534,3726,630],{"class":607},[534,3728,3729,3731,3733,3735,3737,3739,3741,3744,3746],{"class":536,"line":887},[534,3730,604],{"class":603},[534,3732,608],{"class":607},[534,3734,1703],{"class":611},[534,3736,615],{"class":607},[534,3738,618],{"class":603},[534,3740,621],{"class":607},[534,3742,3743],{"class":543},".\u002Fusers.controller",[534,3745,627],{"class":607},[534,3747,630],{"class":607},[534,3749,3750,3752,3754,3756,3758,3760,3762,3765,3767],{"class":536,"line":903},[534,3751,604],{"class":603},[534,3753,608],{"class":607},[534,3755,2329],{"class":611},[534,3757,615],{"class":607},[534,3759,618],{"class":603},[534,3761,621],{"class":607},[534,3763,3764],{"class":543},".\u002Faudit-log",[534,3766,627],{"class":607},[534,3768,630],{"class":607},[534,3770,3771,3773,3775,3777,3779,3781,3783,3786,3788],{"class":536,"line":911},[534,3772,604],{"class":603},[534,3774,608],{"class":607},[534,3776,2636],{"class":611},[534,3778,615],{"class":607},[534,3780,618],{"class":603},[534,3782,621],{"class":607},[534,3784,3785],{"class":543},".\u002Fuser-cache",[534,3787,627],{"class":607},[534,3789,630],{"class":607},[534,3791,3792,3794,3796,3798,3800,3802,3804,3807,3809],{"class":536,"line":921},[534,3793,604],{"class":603},[534,3795,608],{"class":607},[534,3797,1006],{"class":611},[534,3799,615],{"class":607},[534,3801,618],{"class":603},[534,3803,621],{"class":607},[534,3805,3806],{"class":543},".\u002Fuser.store",[534,3808,627],{"class":607},[534,3810,630],{"class":607},[534,3812,3813],{"class":536,"line":927},[534,3814,683],{"emptyLinePlaceholder":682},[534,3816,3817,3819,3821,3824,3826,3828,3830],{"class":536,"line":1423},[534,3818,689],{"class":603},[534,3820,831],{"class":830},[534,3822,3823],{"class":540}," UsersModule",[534,3825,837],{"class":830},[534,3827,3585],{"class":695},[534,3829,698],{"class":611},[534,3831,701],{"class":607},[534,3833,3834,3837,3839,3842,3844,3846,3848,3851],{"class":536,"line":1428},[534,3835,3836],{"class":707},"  providers",[534,3838,711],{"class":607},[534,3840,3841],{"class":611}," [UserStore",[534,3843,725],{"class":607},[534,3845,2329],{"class":611},[534,3847,725],{"class":607},[534,3849,3850],{"class":611}," UserCache]",[534,3852,736],{"class":607},[534,3854,3855,3858,3860,3862,3865,3867,3870],{"class":536,"line":1454},[534,3856,3857],{"class":707},"  http",[534,3859,711],{"class":607},[534,3861,608],{"class":607},[534,3863,3864],{"class":707}," controllers",[534,3866,711],{"class":607},[534,3868,3869],{"class":611}," [UsersController] ",[534,3871,3872],{"class":607},"},\n",[534,3874,3875,3878,3880],{"class":536,"line":1482},[534,3876,3877],{"class":707},"  cqrs",[534,3879,711],{"class":607},[534,3881,842],{"class":607},[534,3883,3884,3887,3889,3892,3894,3897],{"class":536,"line":1487},[534,3885,3886],{"class":707},"    commandHandlers",[534,3888,711],{"class":607},[534,3890,3891],{"class":611}," [CreateUserCommandHandler",[534,3893,725],{"class":607},[534,3895,3896],{"class":611}," UpdateUserCommandHandler]",[534,3898,736],{"class":607},[534,3900,3901,3904,3906,3909,3911,3914],{"class":536,"line":1887},[534,3902,3903],{"class":707},"    queryHandlers",[534,3905,711],{"class":607},[534,3907,3908],{"class":611}," [GetUserQueryHandler",[534,3910,725],{"class":607},[534,3912,3913],{"class":611}," ListUsersQueryHandler]",[534,3915,736],{"class":607},[534,3917,3918,3921,3923,3926],{"class":536,"line":1936},[534,3919,3920],{"class":707},"    commandInterceptors",[534,3922,711],{"class":607},[534,3924,3925],{"class":611}," [AuditCommandInterceptor]",[534,3927,736],{"class":607},[534,3929,3930,3933,3935,3938],{"class":536,"line":1945},[534,3931,3932],{"class":707},"    queryInterceptors",[534,3934,711],{"class":607},[534,3936,3937],{"class":611}," [CacheGetUserInterceptor]",[534,3939,736],{"class":607},[534,3941,3942],{"class":536,"line":1950},[534,3943,3944],{"class":607},"  },\n",[534,3946,3947,3950,3952,3954,3956,3959],{"class":536,"line":1955},[534,3948,3949],{"class":707},"  exports",[534,3951,711],{"class":607},[534,3953,3841],{"class":611},[534,3955,725],{"class":607},[534,3957,3958],{"class":611}," AuditLog]",[534,3960,736],{"class":607},[534,3962,3963,3965,3967],{"class":536,"line":2006},[534,3964,742],{"class":607},[534,3966,1902],{"class":611},[534,3968,3969],{"class":607},"{}\n",[512,3971,3973],{"id":3972},"see-also","See also",[3975,3976,3977,3983,3988,3993],"ul",{},[3978,3979,3980,3982],"li",{},[3538,3981,228],{"href":229}," — drive your command handlers against aggregates that\nenforce invariants and record domain events.",[3978,3984,3985,3987],{},[3538,3986,146],{"href":147}," — flush an aggregate's events after a command saves it, then react\nin-process or across services.",[3978,3989,3990,3992],{},[3538,3991,238],{"href":239}," — the persistence contract behind a command\nhandler, with the optimistic concurrency that feeds the retry.",[3978,3994,3995,4003,4004,4006],{},[3538,3996,4000],{"href":3997,"rel":3998},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL05-cqrs",[3999],"nofollow",[503,4001,4002],{},"L05 — CQRS commands & queries","\n— runnable commands and queries, an app-wide audit interceptor, and a test that proves the 3-attempt\n",[531,4005,2929],{}," retry.",[4008,4009,4010],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .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}",{"title":529,"searchDepth":633,"depth":633,"links":4012},[4013,4014,4015,4016,4017,4018,4019,4020,4021,4022,4023],{"id":514,"depth":633,"text":515},{"id":750,"depth":633,"text":751},{"id":946,"depth":633,"text":947},{"id":1206,"depth":633,"text":1207},{"id":1492,"depth":633,"text":1493},{"id":2252,"depth":633,"text":2253},{"id":2922,"depth":633,"text":2923},{"id":3032,"depth":633,"text":3033},{"id":3139,"depth":633,"text":3140},{"id":3552,"depth":633,"text":3553},{"id":3972,"depth":633,"text":3973},"Split writes from reads with a typed CommandBus and QueryBus, one handler per message, around-chain interceptors, and automatic ConcurrencyError retry.","md",null,{},{"icon":236},{"title":233,"description":4024},"-rkI77z1qSM5KbqR2H_L0mnhmrEERMFSnNPLRnVTKBQ",[4032,4034],{"title":228,"path":229,"stem":230,"description":4033,"icon":231,"children":-1},"Model your domain with the Entity, ValueObject, and AggregateRoot bases — value equality, dirty tracking, optimistic concurrency, and domain events.",{"title":238,"path":239,"stem":240,"description":4035,"icon":241,"children":-1},"A collection-like persistence boundary with save, getById, getAll, and a zero-codegen EntityQuery, swappable behind an abstract Repository token, with optimistic-concurrency ConcurrencyError.",1783300761903]