[{"data":1,"prerenderedAt":2743},["ShallowReactive",2],{"navigation_docs":3,"-docs-architecture-repository-pattern":493,"-docs-architecture-repository-pattern-surround":2738},[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":238,"body":495,"description":2731,"extension":2732,"links":2733,"meta":2734,"navigation":2735,"path":239,"seo":2736,"stem":240,"__hash__":2737},"docs\u002Fdocs\u002F04.architecture\u002F04.repository-pattern.md",{"type":496,"value":497,"toc":2720},"minimark",[498,511,516,528,862,866,872,1106,1113,1483,1487,1510,1647,1654,1658,1670,1838,1904,1923,1940,1944,1970,2122,2128,2132,2140,2228,2453,2464,2468,2479,2486,2492,2496,2515,2630,2650,2660,2664,2716],[499,500,501,502,506,507,510],"p",{},"A repository is the collection-like boundary between your domain and the database. Your handlers treat\nit like an in-memory collection of aggregates — ",[503,504,505],"code",{},"users.save(user)",", ",[503,508,509],{},"users.getById(id)"," — and it turns\nthose calls into inserts, version-guarded updates, and queries, so no domain or HTTP code touches SQL.",[512,513,515],"h2",{"id":514},"inject-a-repository-as-a-dependency","Inject a repository as a dependency",[499,517,518,519,522,523,527],{},"A repository is a plain provider: list it in the module's ",[503,520,521],{},"providers",", type a constructor parameter with\nit, and the compiler injects it. Code that ",[524,525,526],"em",{},"uses"," a repository needs no special base — it's just a class.",[529,530,536],"pre",{"className":531,"code":532,"filename":533,"language":534,"meta":535,"style":535},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import type { Controller, Get } from \"@heximon\u002Fhttp\";\nimport { type UserId } from \".\u002Fuser.entity\";\nimport { UserRepository } from \".\u002Fuser.repository\";\n\nexport class UserController implements Controller\u003C\"\u002Fusers\"> {\n  \u002F\u002F Injected by class identity from the parameter type — no token to declare.\n  constructor(private readonly users: UserRepository) {}\n\n  public async find(action: Get\u003C\"\u002F:id\">): Promise\u003CUserResponse | undefined> {\n    const user = await this.users.getById(action.request.pathParams.id as UserId);\n    return user && UserController.toResponse(user);\n  }\n}\n","src\u002Fusers\u002Fuser.controller.ts","ts","",[503,537,538,583,608,631,638,673,680,710,715,767,823,850,856],{"__ignoreMap":535},[539,540,543,547,550,554,558,561,564,567,570,573,577,580],"span",{"class":541,"line":542},"line",1,[539,544,546],{"class":545},"s7zQu","import",[539,548,549],{"class":545}," type",[539,551,553],{"class":552},"sMK4o"," {",[539,555,557],{"class":556},"sTEyZ"," Controller",[539,559,560],{"class":552},",",[539,562,563],{"class":556}," Get",[539,565,566],{"class":552}," }",[539,568,569],{"class":545}," from",[539,571,572],{"class":552}," \"",[539,574,576],{"class":575},"sfazB","@heximon\u002Fhttp",[539,578,579],{"class":552},"\"",[539,581,582],{"class":552},";\n",[539,584,586,588,590,592,595,597,599,601,604,606],{"class":541,"line":585},2,[539,587,546],{"class":545},[539,589,553],{"class":552},[539,591,549],{"class":545},[539,593,594],{"class":556}," UserId",[539,596,566],{"class":552},[539,598,569],{"class":545},[539,600,572],{"class":552},[539,602,603],{"class":575},".\u002Fuser.entity",[539,605,579],{"class":552},[539,607,582],{"class":552},[539,609,611,613,615,618,620,622,624,627,629],{"class":541,"line":610},3,[539,612,546],{"class":545},[539,614,553],{"class":552},[539,616,617],{"class":556}," UserRepository",[539,619,566],{"class":552},[539,621,569],{"class":545},[539,623,572],{"class":552},[539,625,626],{"class":575},".\u002Fuser.repository",[539,628,579],{"class":552},[539,630,582],{"class":552},[539,632,634],{"class":541,"line":633},4,[539,635,637],{"emptyLinePlaceholder":636},true,"\n",[539,639,641,644,648,652,655,657,660,662,665,667,670],{"class":541,"line":640},5,[539,642,643],{"class":545},"export",[539,645,647],{"class":646},"spNyl"," class",[539,649,651],{"class":650},"sBMFI"," UserController",[539,653,654],{"class":646}," implements",[539,656,557],{"class":650},[539,658,659],{"class":552},"\u003C",[539,661,579],{"class":552},[539,663,664],{"class":575},"\u002Fusers",[539,666,579],{"class":552},[539,668,669],{"class":552},">",[539,671,672],{"class":552}," {\n",[539,674,676],{"class":541,"line":675},6,[539,677,679],{"class":678},"sHwdD","  \u002F\u002F Injected by class identity from the parameter type — no token to declare.\n",[539,681,683,686,689,692,695,699,702,704,707],{"class":541,"line":682},7,[539,684,685],{"class":646},"  constructor",[539,687,688],{"class":552},"(",[539,690,691],{"class":646},"private",[539,693,694],{"class":646}," readonly",[539,696,698],{"class":697},"sHdIc"," users",[539,700,701],{"class":552},":",[539,703,617],{"class":650},[539,705,706],{"class":552},")",[539,708,709],{"class":552}," {}\n",[539,711,713],{"class":541,"line":712},8,[539,714,637],{"emptyLinePlaceholder":636},[539,716,718,721,724,728,730,733,735,737,739,741,744,746,749,752,754,757,760,763,765],{"class":541,"line":717},9,[539,719,720],{"class":646},"  public",[539,722,723],{"class":646}," async",[539,725,727],{"class":726},"swJcz"," find",[539,729,688],{"class":552},[539,731,732],{"class":697},"action",[539,734,701],{"class":552},[539,736,563],{"class":650},[539,738,659],{"class":552},[539,740,579],{"class":552},[539,742,743],{"class":575},"\u002F:id",[539,745,579],{"class":552},[539,747,748],{"class":552},">):",[539,750,751],{"class":650}," Promise",[539,753,659],{"class":552},[539,755,756],{"class":650},"UserResponse",[539,758,759],{"class":552}," |",[539,761,762],{"class":650}," undefined",[539,764,669],{"class":552},[539,766,672],{"class":552},[539,768,770,773,776,779,782,785,788,791,795,797,799,801,804,806,809,811,814,817,819,821],{"class":541,"line":769},10,[539,771,772],{"class":646},"    const",[539,774,775],{"class":556}," user",[539,777,778],{"class":552}," =",[539,780,781],{"class":545}," await",[539,783,784],{"class":552}," this.",[539,786,787],{"class":556},"users",[539,789,790],{"class":552},".",[539,792,794],{"class":793},"s2Zo4","getById",[539,796,688],{"class":726},[539,798,732],{"class":556},[539,800,790],{"class":552},[539,802,803],{"class":556},"request",[539,805,790],{"class":552},[539,807,808],{"class":556},"pathParams",[539,810,790],{"class":552},[539,812,813],{"class":556},"id",[539,815,816],{"class":545}," as",[539,818,594],{"class":650},[539,820,706],{"class":726},[539,822,582],{"class":552},[539,824,826,829,831,834,836,838,841,843,846,848],{"class":541,"line":825},11,[539,827,828],{"class":545},"    return",[539,830,775],{"class":556},[539,832,833],{"class":552}," &&",[539,835,651],{"class":556},[539,837,790],{"class":552},[539,839,840],{"class":793},"toResponse",[539,842,688],{"class":726},[539,844,845],{"class":556},"user",[539,847,706],{"class":726},[539,849,582],{"class":552},[539,851,853],{"class":541,"line":852},12,[539,854,855],{"class":552},"  }\n",[539,857,859],{"class":541,"line":858},13,[539,860,861],{"class":552},"}\n",[512,863,865],{"id":864},"save-an-aggregate","Save an aggregate",[499,867,868,871],{},[503,869,870],{},"save(aggregate)"," is one call for both insert and update — the repository decides which from the\nentity's lifecycle state. A freshly built aggregate inserts; one you loaded and mutated updates. You\nnever write that branch at the call site.",[529,873,875],{"className":531,"code":874,"filename":533,"language":534,"meta":535,"style":535},"export class UserController implements Controller\u003C\"\u002Fusers\"> {\n  public async create(action: Post\u003C\"\u002F\", { body: typeof createUserSchema }>): Promise\u003CTypedResponse> {\n    const body = await action.request.readValidatedBody();\n    const user = User.create(uuid.v7\u003CUserId>(), body); \u002F\u002F a new, never-persisted aggregate\n\n    await this.users.save(user); \u002F\u002F → INSERT, at version 1\n\n    return action.respond(201, UserController.toResponse(user));\n  }\n}\n",[503,876,877,901,957,984,1031,1035,1060,1064,1098,1102],{"__ignoreMap":535},[539,878,879,881,883,885,887,889,891,893,895,897,899],{"class":541,"line":542},[539,880,643],{"class":545},[539,882,647],{"class":646},[539,884,651],{"class":650},[539,886,654],{"class":646},[539,888,557],{"class":650},[539,890,659],{"class":552},[539,892,579],{"class":552},[539,894,664],{"class":575},[539,896,579],{"class":552},[539,898,669],{"class":552},[539,900,672],{"class":552},[539,902,903,905,907,910,912,914,916,919,921,923,926,928,930,932,935,937,940,943,946,948,950,953,955],{"class":541,"line":585},[539,904,720],{"class":646},[539,906,723],{"class":646},[539,908,909],{"class":726}," create",[539,911,688],{"class":552},[539,913,732],{"class":697},[539,915,701],{"class":552},[539,917,918],{"class":650}," Post",[539,920,659],{"class":552},[539,922,579],{"class":552},[539,924,925],{"class":575},"\u002F",[539,927,579],{"class":552},[539,929,560],{"class":552},[539,931,553],{"class":552},[539,933,934],{"class":726}," body",[539,936,701],{"class":552},[539,938,939],{"class":552}," typeof",[539,941,942],{"class":556}," createUserSchema ",[539,944,945],{"class":552},"}>):",[539,947,751],{"class":650},[539,949,659],{"class":552},[539,951,952],{"class":650},"TypedResponse",[539,954,669],{"class":552},[539,956,672],{"class":552},[539,958,959,961,963,965,967,970,972,974,976,979,982],{"class":541,"line":610},[539,960,772],{"class":646},[539,962,934],{"class":556},[539,964,778],{"class":552},[539,966,781],{"class":545},[539,968,969],{"class":556}," action",[539,971,790],{"class":552},[539,973,803],{"class":556},[539,975,790],{"class":552},[539,977,978],{"class":793},"readValidatedBody",[539,980,981],{"class":726},"()",[539,983,582],{"class":552},[539,985,986,988,990,992,995,997,1000,1002,1005,1007,1010,1012,1015,1017,1019,1021,1023,1025,1028],{"class":541,"line":633},[539,987,772],{"class":646},[539,989,775],{"class":556},[539,991,778],{"class":552},[539,993,994],{"class":556}," User",[539,996,790],{"class":552},[539,998,999],{"class":793},"create",[539,1001,688],{"class":726},[539,1003,1004],{"class":556},"uuid",[539,1006,790],{"class":552},[539,1008,1009],{"class":793},"v7",[539,1011,659],{"class":552},[539,1013,1014],{"class":650},"UserId",[539,1016,669],{"class":552},[539,1018,981],{"class":726},[539,1020,560],{"class":552},[539,1022,934],{"class":556},[539,1024,706],{"class":726},[539,1026,1027],{"class":552},";",[539,1029,1030],{"class":678}," \u002F\u002F a new, never-persisted aggregate\n",[539,1032,1033],{"class":541,"line":640},[539,1034,637],{"emptyLinePlaceholder":636},[539,1036,1037,1040,1042,1044,1046,1049,1051,1053,1055,1057],{"class":541,"line":675},[539,1038,1039],{"class":545},"    await",[539,1041,784],{"class":552},[539,1043,787],{"class":556},[539,1045,790],{"class":552},[539,1047,1048],{"class":793},"save",[539,1050,688],{"class":726},[539,1052,845],{"class":556},[539,1054,706],{"class":726},[539,1056,1027],{"class":552},[539,1058,1059],{"class":678}," \u002F\u002F → INSERT, at version 1\n",[539,1061,1062],{"class":541,"line":682},[539,1063,637],{"emptyLinePlaceholder":636},[539,1065,1066,1068,1070,1072,1075,1077,1081,1083,1085,1087,1089,1091,1093,1096],{"class":541,"line":712},[539,1067,828],{"class":545},[539,1069,969],{"class":556},[539,1071,790],{"class":552},[539,1073,1074],{"class":793},"respond",[539,1076,688],{"class":726},[539,1078,1080],{"class":1079},"sbssI","201",[539,1082,560],{"class":552},[539,1084,651],{"class":556},[539,1086,790],{"class":552},[539,1088,840],{"class":793},[539,1090,688],{"class":726},[539,1092,845],{"class":556},[539,1094,1095],{"class":726},"))",[539,1097,582],{"class":552},[539,1099,1100],{"class":541,"line":717},[539,1101,855],{"class":552},[539,1103,1104],{"class":541,"line":769},[539,1105,861],{"class":552},[499,1107,1108,1109,1112],{},"Updates read the same way — load, call domain methods, save. You mutate real fields in plain TypeScript;\nat save time the repository diffs the aggregate against the snapshot it took at load (no Proxy) and emits\nan ",[503,1110,1111],{},"UPDATE"," for only the changed columns. An unchanged save is a no-op.",[529,1114,1116],{"className":531,"code":1115,"filename":533,"language":534,"meta":535,"style":535},"export class UserController implements Controller\u003C\"\u002Fusers\"> {\n  public async update(action: Patch\u003C\"\u002F:id\", { body: typeof updateUserSchema }>): Promise\u003CTypedResponse> {\n    const id = action.request.pathParams.id as UserId;\n    const body = await action.request.readValidatedBody();\n    const user = await this.users.getById(id);\n    if (user === undefined) return action.respond(404, { error: `User ${id} not found` });\n\n    if (body.name !== undefined) user.rename(body.name);   \u002F\u002F mutate through domain methods\n    if (body.email !== undefined) user.changeEmail(body.email);\n\n    await this.users.save(user); \u002F\u002F → version-guarded UPDATE of the changed columns only\n\n    return UserController.toResponse(user);\n  }\n}\n",[503,1117,1118,1142,1193,1222,1246,1272,1339,1343,1386,1424,1428,1451,1455,1473,1478],{"__ignoreMap":535},[539,1119,1120,1122,1124,1126,1128,1130,1132,1134,1136,1138,1140],{"class":541,"line":542},[539,1121,643],{"class":545},[539,1123,647],{"class":646},[539,1125,651],{"class":650},[539,1127,654],{"class":646},[539,1129,557],{"class":650},[539,1131,659],{"class":552},[539,1133,579],{"class":552},[539,1135,664],{"class":575},[539,1137,579],{"class":552},[539,1139,669],{"class":552},[539,1141,672],{"class":552},[539,1143,1144,1146,1148,1151,1153,1155,1157,1160,1162,1164,1166,1168,1170,1172,1174,1176,1178,1181,1183,1185,1187,1189,1191],{"class":541,"line":585},[539,1145,720],{"class":646},[539,1147,723],{"class":646},[539,1149,1150],{"class":726}," update",[539,1152,688],{"class":552},[539,1154,732],{"class":697},[539,1156,701],{"class":552},[539,1158,1159],{"class":650}," Patch",[539,1161,659],{"class":552},[539,1163,579],{"class":552},[539,1165,743],{"class":575},[539,1167,579],{"class":552},[539,1169,560],{"class":552},[539,1171,553],{"class":552},[539,1173,934],{"class":726},[539,1175,701],{"class":552},[539,1177,939],{"class":552},[539,1179,1180],{"class":556}," updateUserSchema ",[539,1182,945],{"class":552},[539,1184,751],{"class":650},[539,1186,659],{"class":552},[539,1188,952],{"class":650},[539,1190,669],{"class":552},[539,1192,672],{"class":552},[539,1194,1195,1197,1200,1202,1204,1206,1208,1210,1212,1214,1216,1218,1220],{"class":541,"line":610},[539,1196,772],{"class":646},[539,1198,1199],{"class":556}," id",[539,1201,778],{"class":552},[539,1203,969],{"class":556},[539,1205,790],{"class":552},[539,1207,803],{"class":556},[539,1209,790],{"class":552},[539,1211,808],{"class":556},[539,1213,790],{"class":552},[539,1215,813],{"class":556},[539,1217,816],{"class":545},[539,1219,594],{"class":650},[539,1221,582],{"class":552},[539,1223,1224,1226,1228,1230,1232,1234,1236,1238,1240,1242,1244],{"class":541,"line":633},[539,1225,772],{"class":646},[539,1227,934],{"class":556},[539,1229,778],{"class":552},[539,1231,781],{"class":545},[539,1233,969],{"class":556},[539,1235,790],{"class":552},[539,1237,803],{"class":556},[539,1239,790],{"class":552},[539,1241,978],{"class":793},[539,1243,981],{"class":726},[539,1245,582],{"class":552},[539,1247,1248,1250,1252,1254,1256,1258,1260,1262,1264,1266,1268,1270],{"class":541,"line":640},[539,1249,772],{"class":646},[539,1251,775],{"class":556},[539,1253,778],{"class":552},[539,1255,781],{"class":545},[539,1257,784],{"class":552},[539,1259,787],{"class":556},[539,1261,790],{"class":552},[539,1263,794],{"class":793},[539,1265,688],{"class":726},[539,1267,813],{"class":556},[539,1269,706],{"class":726},[539,1271,582],{"class":552},[539,1273,1274,1277,1280,1282,1285,1287,1290,1293,1295,1297,1299,1301,1304,1306,1308,1311,1313,1316,1319,1322,1324,1327,1330,1333,1335,1337],{"class":541,"line":675},[539,1275,1276],{"class":545},"    if",[539,1278,1279],{"class":726}," (",[539,1281,845],{"class":556},[539,1283,1284],{"class":552}," ===",[539,1286,762],{"class":552},[539,1288,1289],{"class":726},") ",[539,1291,1292],{"class":545},"return",[539,1294,969],{"class":556},[539,1296,790],{"class":552},[539,1298,1074],{"class":793},[539,1300,688],{"class":726},[539,1302,1303],{"class":1079},"404",[539,1305,560],{"class":552},[539,1307,553],{"class":552},[539,1309,1310],{"class":726}," error",[539,1312,701],{"class":552},[539,1314,1315],{"class":552}," `",[539,1317,1318],{"class":575},"User ",[539,1320,1321],{"class":552},"${",[539,1323,813],{"class":556},[539,1325,1326],{"class":552},"}",[539,1328,1329],{"class":575}," not found",[539,1331,1332],{"class":552},"`",[539,1334,566],{"class":552},[539,1336,706],{"class":726},[539,1338,582],{"class":552},[539,1340,1341],{"class":541,"line":682},[539,1342,637],{"emptyLinePlaceholder":636},[539,1344,1345,1347,1349,1352,1354,1357,1360,1362,1364,1366,1368,1371,1373,1375,1377,1379,1381,1383],{"class":541,"line":712},[539,1346,1276],{"class":545},[539,1348,1279],{"class":726},[539,1350,1351],{"class":556},"body",[539,1353,790],{"class":552},[539,1355,1356],{"class":556},"name",[539,1358,1359],{"class":552}," !==",[539,1361,762],{"class":552},[539,1363,1289],{"class":726},[539,1365,845],{"class":556},[539,1367,790],{"class":552},[539,1369,1370],{"class":793},"rename",[539,1372,688],{"class":726},[539,1374,1351],{"class":556},[539,1376,790],{"class":552},[539,1378,1356],{"class":556},[539,1380,706],{"class":726},[539,1382,1027],{"class":552},[539,1384,1385],{"class":678},"   \u002F\u002F mutate through domain methods\n",[539,1387,1388,1390,1392,1394,1396,1399,1401,1403,1405,1407,1409,1412,1414,1416,1418,1420,1422],{"class":541,"line":717},[539,1389,1276],{"class":545},[539,1391,1279],{"class":726},[539,1393,1351],{"class":556},[539,1395,790],{"class":552},[539,1397,1398],{"class":556},"email",[539,1400,1359],{"class":552},[539,1402,762],{"class":552},[539,1404,1289],{"class":726},[539,1406,845],{"class":556},[539,1408,790],{"class":552},[539,1410,1411],{"class":793},"changeEmail",[539,1413,688],{"class":726},[539,1415,1351],{"class":556},[539,1417,790],{"class":552},[539,1419,1398],{"class":556},[539,1421,706],{"class":726},[539,1423,582],{"class":552},[539,1425,1426],{"class":541,"line":769},[539,1427,637],{"emptyLinePlaceholder":636},[539,1429,1430,1432,1434,1436,1438,1440,1442,1444,1446,1448],{"class":541,"line":825},[539,1431,1039],{"class":545},[539,1433,784],{"class":552},[539,1435,787],{"class":556},[539,1437,790],{"class":552},[539,1439,1048],{"class":793},[539,1441,688],{"class":726},[539,1443,845],{"class":556},[539,1445,706],{"class":726},[539,1447,1027],{"class":552},[539,1449,1450],{"class":678}," \u002F\u002F → version-guarded UPDATE of the changed columns only\n",[539,1452,1453],{"class":541,"line":852},[539,1454,637],{"emptyLinePlaceholder":636},[539,1456,1457,1459,1461,1463,1465,1467,1469,1471],{"class":541,"line":858},[539,1458,828],{"class":545},[539,1460,651],{"class":556},[539,1462,790],{"class":552},[539,1464,840],{"class":793},[539,1466,688],{"class":726},[539,1468,845],{"class":556},[539,1470,706],{"class":726},[539,1472,582],{"class":552},[539,1474,1476],{"class":541,"line":1475},14,[539,1477,855],{"class":552},[539,1479,1481],{"class":541,"line":1480},15,[539,1482,861],{"class":552},[512,1484,1486],{"id":1485},"read-with-getbyid-getmany-and-getall","Read with getById, getMany, and getAll",[499,1488,1489,1490,1493,1494,1497,1498,1501,1502,1505,1506,1509],{},"The read surface mirrors a collection. ",[503,1491,1492],{},"getById(id)"," returns one aggregate or ",[503,1495,1496],{},"undefined",",\n",[503,1499,1500],{},"getMany(ids)"," batch-fetches, ",[503,1503,1504],{},"getAll(query?)"," returns every aggregate matching an optional query, and\n",[503,1507,1508],{},"count(query?)"," counts without materializing rows.",[529,1511,1513],{"className":531,"code":1512,"filename":533,"language":534,"meta":535,"style":535},"export class UserController implements Controller\u003C\"\u002Fusers\"> {\n  public async list(_action: Get\u003C\"\u002F\">): Promise\u003CUserResponse[]> {\n    const users = await this.users.getAll();\n    return users.map((user) => UserController.toResponse(user));\n  }\n}\n",[503,1514,1515,1539,1580,1603,1639,1643],{"__ignoreMap":535},[539,1516,1517,1519,1521,1523,1525,1527,1529,1531,1533,1535,1537],{"class":541,"line":542},[539,1518,643],{"class":545},[539,1520,647],{"class":646},[539,1522,651],{"class":650},[539,1524,654],{"class":646},[539,1526,557],{"class":650},[539,1528,659],{"class":552},[539,1530,579],{"class":552},[539,1532,664],{"class":575},[539,1534,579],{"class":552},[539,1536,669],{"class":552},[539,1538,672],{"class":552},[539,1540,1541,1543,1545,1548,1550,1553,1555,1557,1559,1561,1563,1565,1567,1569,1571,1573,1576,1578],{"class":541,"line":585},[539,1542,720],{"class":646},[539,1544,723],{"class":646},[539,1546,1547],{"class":726}," list",[539,1549,688],{"class":552},[539,1551,1552],{"class":697},"_action",[539,1554,701],{"class":552},[539,1556,563],{"class":650},[539,1558,659],{"class":552},[539,1560,579],{"class":552},[539,1562,925],{"class":575},[539,1564,579],{"class":552},[539,1566,748],{"class":552},[539,1568,751],{"class":650},[539,1570,659],{"class":552},[539,1572,756],{"class":650},[539,1574,1575],{"class":556},"[]",[539,1577,669],{"class":552},[539,1579,672],{"class":552},[539,1581,1582,1584,1586,1588,1590,1592,1594,1596,1599,1601],{"class":541,"line":610},[539,1583,772],{"class":646},[539,1585,698],{"class":556},[539,1587,778],{"class":552},[539,1589,781],{"class":545},[539,1591,784],{"class":552},[539,1593,787],{"class":556},[539,1595,790],{"class":552},[539,1597,1598],{"class":793},"getAll",[539,1600,981],{"class":726},[539,1602,582],{"class":552},[539,1604,1605,1607,1609,1611,1614,1616,1618,1620,1622,1625,1627,1629,1631,1633,1635,1637],{"class":541,"line":633},[539,1606,828],{"class":545},[539,1608,698],{"class":556},[539,1610,790],{"class":552},[539,1612,1613],{"class":793},"map",[539,1615,688],{"class":726},[539,1617,688],{"class":552},[539,1619,845],{"class":697},[539,1621,706],{"class":552},[539,1623,1624],{"class":646}," =>",[539,1626,651],{"class":556},[539,1628,790],{"class":552},[539,1630,840],{"class":793},[539,1632,688],{"class":726},[539,1634,845],{"class":556},[539,1636,1095],{"class":726},[539,1638,582],{"class":552},[539,1640,1641],{"class":541,"line":640},[539,1642,855],{"class":552},[539,1644,1645],{"class":541,"line":675},[539,1646,861],{"class":552},[499,1648,1649,1650,1653],{},"Every aggregate reads back ",[524,1651,1652],{},"clean"," — carrying its persisted version and counting as unmodified until you\nmutate it, which is what makes the load-mutate-save loop safe without any bookkeeping.",[512,1655,1657],{"id":1656},"filter-with-entityquery","Filter with EntityQuery",[499,1659,1660,1662,1663,1665,1666,1669],{},[503,1661,1504],{}," and ",[503,1664,1508],{}," take an ",[503,1667,1668],{},"EntityQuery\u003CTEntity>"," — a typed filter, ordering, and\npagination object keyed against your entity's own fields. It's a pure TypeScript mapped type with no\nper-entity codegen, so a query is just data you build inline.",[529,1671,1673],{"className":531,"code":1672,"language":534,"meta":535,"style":535},"import type { EntityQuery } from \"@heximon\u002Fdomain\";\n\n\u002F\u002F Active users whose name starts with \"ali\", newest first, first page of 20.\nconst query: EntityQuery\u003CUser> = {\n  filter: { status: { eq: \"active\" }, name: { ilike: \"ali%\" } },\n  order: { createdAt: \"desc\" },\n  limit: 20,\n  offset: 0,\n};\n",[503,1674,1675,1699,1703,1708,1731,1786,1809,1821,1833],{"__ignoreMap":535},[539,1676,1677,1679,1681,1683,1686,1688,1690,1692,1695,1697],{"class":541,"line":542},[539,1678,546],{"class":545},[539,1680,549],{"class":545},[539,1682,553],{"class":552},[539,1684,1685],{"class":556}," EntityQuery",[539,1687,566],{"class":552},[539,1689,569],{"class":545},[539,1691,572],{"class":552},[539,1693,1694],{"class":575},"@heximon\u002Fdomain",[539,1696,579],{"class":552},[539,1698,582],{"class":552},[539,1700,1701],{"class":541,"line":585},[539,1702,637],{"emptyLinePlaceholder":636},[539,1704,1705],{"class":541,"line":610},[539,1706,1707],{"class":678},"\u002F\u002F Active users whose name starts with \"ali\", newest first, first page of 20.\n",[539,1709,1710,1713,1716,1718,1720,1722,1725,1727,1729],{"class":541,"line":633},[539,1711,1712],{"class":646},"const",[539,1714,1715],{"class":556}," query",[539,1717,701],{"class":552},[539,1719,1685],{"class":650},[539,1721,659],{"class":552},[539,1723,1724],{"class":650},"User",[539,1726,669],{"class":552},[539,1728,778],{"class":552},[539,1730,672],{"class":552},[539,1732,1733,1736,1738,1740,1743,1745,1747,1750,1752,1754,1757,1759,1762,1765,1767,1769,1772,1774,1776,1779,1781,1783],{"class":541,"line":640},[539,1734,1735],{"class":726},"  filter",[539,1737,701],{"class":552},[539,1739,553],{"class":552},[539,1741,1742],{"class":726}," status",[539,1744,701],{"class":552},[539,1746,553],{"class":552},[539,1748,1749],{"class":726}," eq",[539,1751,701],{"class":552},[539,1753,572],{"class":552},[539,1755,1756],{"class":575},"active",[539,1758,579],{"class":552},[539,1760,1761],{"class":552}," },",[539,1763,1764],{"class":726}," name",[539,1766,701],{"class":552},[539,1768,553],{"class":552},[539,1770,1771],{"class":726}," ilike",[539,1773,701],{"class":552},[539,1775,572],{"class":552},[539,1777,1778],{"class":575},"ali%",[539,1780,579],{"class":552},[539,1782,566],{"class":552},[539,1784,1785],{"class":552}," },\n",[539,1787,1788,1791,1793,1795,1798,1800,1802,1805,1807],{"class":541,"line":675},[539,1789,1790],{"class":726},"  order",[539,1792,701],{"class":552},[539,1794,553],{"class":552},[539,1796,1797],{"class":726}," createdAt",[539,1799,701],{"class":552},[539,1801,572],{"class":552},[539,1803,1804],{"class":575},"desc",[539,1806,579],{"class":552},[539,1808,1785],{"class":552},[539,1810,1811,1814,1816,1819],{"class":541,"line":682},[539,1812,1813],{"class":726},"  limit",[539,1815,701],{"class":552},[539,1817,1818],{"class":1079}," 20",[539,1820,1497],{"class":552},[539,1822,1823,1826,1828,1831],{"class":541,"line":712},[539,1824,1825],{"class":726},"  offset",[539,1827,701],{"class":552},[539,1829,1830],{"class":1079}," 0",[539,1832,1497],{"class":552},[539,1834,1835],{"class":541,"line":717},[539,1836,1837],{"class":552},"};\n",[499,1839,1840,1841,1844,1845,1848,1849,1848,1852,1848,1855,1848,1858,1848,1861,1848,1864,1848,1867,1870,1871,1848,1874,1848,1877,1848,1880,1848,1883,1848,1886,1889,1890,1848,1893,1848,1896,1899,1900,1903],{},"Each field accepts a ",[503,1842,1843],{},"FieldFilter",": ",[503,1846,1847],{},"eq"," \u002F ",[503,1850,1851],{},"ne",[503,1853,1854],{},"gt",[503,1856,1857],{},"gte",[503,1859,1860],{},"lt",[503,1862,1863],{},"lte",[503,1865,1866],{},"in",[503,1868,1869],{},"notIn"," \u002F\n",[503,1872,1873],{},"like",[503,1875,1876],{},"ilike",[503,1878,1879],{},"notLike",[503,1881,1882],{},"notIlike",[503,1884,1885],{},"isNull",[503,1887,1888],{},"isNotNull",", combined with ",[503,1891,1892],{},"AND",[503,1894,1895],{},"OR",[503,1897,1898],{},"NOT",".\nThe filter descends: a value object filters by its sub-fields (",[503,1901,1902],{},"filter: { name: { fullName: { eq } } }",")\nwhen it is stored across columns, or as a whole value when serialized into one; a relation recurses into\nits own fields.",[499,1905,1906,1907,1914,1915,1918,1919,1922],{},"The query is trusted, never re-coerced — validating untrusted input is the HTTP DTO's job, done at the\nboundary with a ",[1908,1909,1913],"a",{"href":1910,"rel":1911},"https:\u002F\u002Fstandardschema.dev",[1912],"nofollow","Standard Schema"," (e.g. ",[503,1916,1917],{},"@heximon\u002Fschema","'s ",[503,1920,1921],{},"QuerySchema.create",").",[499,1924,1925,1926,1929,1930,1932,1933,1936,1937,790],{},"When the field names a consumer filters in differ from the entity's — a renamed or reshaped response —\na ",[503,1927,1928],{},"QueryMapper"," (from ",[503,1931,1694],{},") translates that response-shaped query into the ",[503,1934,1935],{},"EntityQuery"," via one\ndeclarative field map, so the controller carries no hand-written mapping. See ",[503,1938,1939],{},"examples\u002Fflagship\u002Fpackages\u002Fcatalog",[512,1941,1943],{"id":1942},"define-the-repository-contract","Define the repository contract",[499,1945,1946,1947,1950,1951,506,1953,506,1955,506,1957,1497,1960,506,1963,506,1966,1969],{},"A repository is a class extending a dialect base. For a Drizzle-backed aggregate,\n",[503,1948,1949],{},"DrizzleLibSQLEntityRepository"," supplies the whole surface — ",[503,1952,1048],{},[503,1954,794],{},[503,1956,1598],{},[503,1958,1959],{},"getMany",[503,1961,1962],{},"count",[503,1964,1965],{},"delete",[503,1967,1968],{},"transaction"," — so the body is just a constructor passing the table key and entity\nconstructor.",[529,1971,1974],{"className":531,"code":1972,"filename":1973,"language":534,"meta":535,"style":535},"import {\n  DrizzleLibSQLDatabase,\n  DrizzleLibSQLEntityRepository,\n} from \"@heximon\u002Fdrizzle\u002Flibsql\";\nimport { User } from \".\u002Fuser.entity\";\n\nexport class UserRepository extends DrizzleLibSQLEntityRepository\u003CDrizzleLibSQLDatabase, User> {\n  \u002F\u002F The shared Database is the only DI-resolved dependency — resolved by its class type.\n  public constructor(database: DrizzleLibSQLDatabase) {\n    super(database, \"Users\", User);\n  }\n}\n","src\u002Fusers\u002Fuser.repository.ts",[503,1975,1976,1982,1989,1996,2011,2031,2035,2062,2067,2088,2114,2118],{"__ignoreMap":535},[539,1977,1978,1980],{"class":541,"line":542},[539,1979,546],{"class":545},[539,1981,672],{"class":552},[539,1983,1984,1987],{"class":541,"line":585},[539,1985,1986],{"class":556},"  DrizzleLibSQLDatabase",[539,1988,1497],{"class":552},[539,1990,1991,1994],{"class":541,"line":610},[539,1992,1993],{"class":556},"  DrizzleLibSQLEntityRepository",[539,1995,1497],{"class":552},[539,1997,1998,2000,2002,2004,2007,2009],{"class":541,"line":633},[539,1999,1326],{"class":552},[539,2001,569],{"class":545},[539,2003,572],{"class":552},[539,2005,2006],{"class":575},"@heximon\u002Fdrizzle\u002Flibsql",[539,2008,579],{"class":552},[539,2010,582],{"class":552},[539,2012,2013,2015,2017,2019,2021,2023,2025,2027,2029],{"class":541,"line":640},[539,2014,546],{"class":545},[539,2016,553],{"class":552},[539,2018,994],{"class":556},[539,2020,566],{"class":552},[539,2022,569],{"class":545},[539,2024,572],{"class":552},[539,2026,603],{"class":575},[539,2028,579],{"class":552},[539,2030,582],{"class":552},[539,2032,2033],{"class":541,"line":675},[539,2034,637],{"emptyLinePlaceholder":636},[539,2036,2037,2039,2041,2043,2046,2049,2051,2054,2056,2058,2060],{"class":541,"line":682},[539,2038,643],{"class":545},[539,2040,647],{"class":646},[539,2042,617],{"class":650},[539,2044,2045],{"class":646}," extends",[539,2047,2048],{"class":650}," DrizzleLibSQLEntityRepository",[539,2050,659],{"class":552},[539,2052,2053],{"class":650},"DrizzleLibSQLDatabase",[539,2055,560],{"class":552},[539,2057,994],{"class":650},[539,2059,669],{"class":552},[539,2061,672],{"class":552},[539,2063,2064],{"class":541,"line":712},[539,2065,2066],{"class":678},"  \u002F\u002F The shared Database is the only DI-resolved dependency — resolved by its class type.\n",[539,2068,2069,2071,2074,2076,2079,2081,2084,2086],{"class":541,"line":717},[539,2070,720],{"class":646},[539,2072,2073],{"class":646}," constructor",[539,2075,688],{"class":552},[539,2077,2078],{"class":697},"database",[539,2080,701],{"class":552},[539,2082,2083],{"class":650}," DrizzleLibSQLDatabase",[539,2085,706],{"class":552},[539,2087,672],{"class":552},[539,2089,2090,2093,2095,2097,2099,2101,2104,2106,2108,2110,2112],{"class":541,"line":769},[539,2091,2092],{"class":556},"    super",[539,2094,688],{"class":726},[539,2096,2078],{"class":556},[539,2098,560],{"class":552},[539,2100,572],{"class":552},[539,2102,2103],{"class":575},"Users",[539,2105,579],{"class":552},[539,2107,560],{"class":552},[539,2109,994],{"class":556},[539,2111,706],{"class":726},[539,2113,582],{"class":552},[539,2115,2116],{"class":541,"line":825},[539,2117,855],{"class":552},[539,2119,2120],{"class":541,"line":852},[539,2121,861],{"class":552},[499,2123,2124,2125,2127],{},"Every repository shares the one ",[503,2126,77],{},", so a transaction opened on one is visible to all within the\nsame request.",[512,2129,2131],{"id":2130},"swap-implementations-behind-an-abstract-token","Swap implementations behind an abstract token",[499,2133,2134,2135,2139],{},"To make a repository swappable — an in-memory double in tests, a different dialect per environment —\ntype your consumers against an ",[2136,2137,2138],"strong",{},"abstract"," repository and bind the concrete one with a provider. The\nabstract class is the DI token; the class extending it is what gets constructed.",[529,2141,2143],{"className":531,"code":2142,"filename":1973,"language":534,"meta":535,"style":535},"import { Repository } from \"@heximon\u002Fdomain\";\nimport type { User, UserId } from \".\u002Fuser.entity\";\n\n\u002F\u002F The token consumers inject — both the interface and the DI key.\nexport abstract class UserRepository extends Repository\u003CUser, UserId> {}\n",[503,2144,2145,2166,2192,2196,2201],{"__ignoreMap":535},[539,2146,2147,2149,2151,2154,2156,2158,2160,2162,2164],{"class":541,"line":542},[539,2148,546],{"class":545},[539,2150,553],{"class":552},[539,2152,2153],{"class":556}," Repository",[539,2155,566],{"class":552},[539,2157,569],{"class":545},[539,2159,572],{"class":552},[539,2161,1694],{"class":575},[539,2163,579],{"class":552},[539,2165,582],{"class":552},[539,2167,2168,2170,2172,2174,2176,2178,2180,2182,2184,2186,2188,2190],{"class":541,"line":585},[539,2169,546],{"class":545},[539,2171,549],{"class":545},[539,2173,553],{"class":552},[539,2175,994],{"class":556},[539,2177,560],{"class":552},[539,2179,594],{"class":556},[539,2181,566],{"class":552},[539,2183,569],{"class":545},[539,2185,572],{"class":552},[539,2187,603],{"class":575},[539,2189,579],{"class":552},[539,2191,582],{"class":552},[539,2193,2194],{"class":541,"line":610},[539,2195,637],{"emptyLinePlaceholder":636},[539,2197,2198],{"class":541,"line":633},[539,2199,2200],{"class":678},"\u002F\u002F The token consumers inject — both the interface and the DI key.\n",[539,2202,2203,2205,2208,2210,2212,2214,2216,2218,2220,2222,2224,2226],{"class":541,"line":640},[539,2204,643],{"class":545},[539,2206,2207],{"class":646}," abstract",[539,2209,647],{"class":646},[539,2211,617],{"class":650},[539,2213,2045],{"class":646},[539,2215,2153],{"class":650},[539,2217,659],{"class":552},[539,2219,1724],{"class":650},[539,2221,560],{"class":552},[539,2223,594],{"class":650},[539,2225,669],{"class":552},[539,2227,709],{"class":552},[529,2229,2232],{"className":531,"code":2230,"filename":2231,"language":534,"meta":535,"style":535},"import { Module } from \"@heximon\u002Fruntime\";\nimport { DatabaseModule } from \"..\u002Fdatabase\u002Fdatabase.module\";\nimport { DrizzleUserRepository } from \".\u002Fdrizzle-user.repository\";\nimport { UserController } from \".\u002Fuser.controller\";\nimport { UserRepository } from \".\u002Fuser.repository\";\n\nexport class UserModule extends Module({\n  imports: [DatabaseModule],\n  providers: [{ provide: UserRepository, useClass: DrizzleUserRepository }],\n  http: { controllers: [UserController] },\n  exports: [UserRepository],\n}) {}\n","src\u002Fusers\u002Fuser.module.ts",[503,2233,2234,2256,2278,2300,2321,2341,2345,2363,2375,2412,2432,2444],{"__ignoreMap":535},[539,2235,2236,2238,2240,2243,2245,2247,2249,2252,2254],{"class":541,"line":542},[539,2237,546],{"class":545},[539,2239,553],{"class":552},[539,2241,2242],{"class":556}," Module",[539,2244,566],{"class":552},[539,2246,569],{"class":545},[539,2248,572],{"class":552},[539,2250,2251],{"class":575},"@heximon\u002Fruntime",[539,2253,579],{"class":552},[539,2255,582],{"class":552},[539,2257,2258,2260,2262,2265,2267,2269,2271,2274,2276],{"class":541,"line":585},[539,2259,546],{"class":545},[539,2261,553],{"class":552},[539,2263,2264],{"class":556}," DatabaseModule",[539,2266,566],{"class":552},[539,2268,569],{"class":545},[539,2270,572],{"class":552},[539,2272,2273],{"class":575},"..\u002Fdatabase\u002Fdatabase.module",[539,2275,579],{"class":552},[539,2277,582],{"class":552},[539,2279,2280,2282,2284,2287,2289,2291,2293,2296,2298],{"class":541,"line":610},[539,2281,546],{"class":545},[539,2283,553],{"class":552},[539,2285,2286],{"class":556}," DrizzleUserRepository",[539,2288,566],{"class":552},[539,2290,569],{"class":545},[539,2292,572],{"class":552},[539,2294,2295],{"class":575},".\u002Fdrizzle-user.repository",[539,2297,579],{"class":552},[539,2299,582],{"class":552},[539,2301,2302,2304,2306,2308,2310,2312,2314,2317,2319],{"class":541,"line":633},[539,2303,546],{"class":545},[539,2305,553],{"class":552},[539,2307,651],{"class":556},[539,2309,566],{"class":552},[539,2311,569],{"class":545},[539,2313,572],{"class":552},[539,2315,2316],{"class":575},".\u002Fuser.controller",[539,2318,579],{"class":552},[539,2320,582],{"class":552},[539,2322,2323,2325,2327,2329,2331,2333,2335,2337,2339],{"class":541,"line":640},[539,2324,546],{"class":545},[539,2326,553],{"class":552},[539,2328,617],{"class":556},[539,2330,566],{"class":552},[539,2332,569],{"class":545},[539,2334,572],{"class":552},[539,2336,626],{"class":575},[539,2338,579],{"class":552},[539,2340,582],{"class":552},[539,2342,2343],{"class":541,"line":675},[539,2344,637],{"emptyLinePlaceholder":636},[539,2346,2347,2349,2351,2354,2356,2358,2360],{"class":541,"line":682},[539,2348,643],{"class":545},[539,2350,647],{"class":646},[539,2352,2353],{"class":650}," UserModule",[539,2355,2045],{"class":646},[539,2357,2242],{"class":793},[539,2359,688],{"class":556},[539,2361,2362],{"class":552},"{\n",[539,2364,2365,2368,2370,2373],{"class":541,"line":712},[539,2366,2367],{"class":726},"  imports",[539,2369,701],{"class":552},[539,2371,2372],{"class":556}," [DatabaseModule]",[539,2374,1497],{"class":552},[539,2376,2377,2380,2382,2385,2388,2391,2393,2395,2397,2400,2402,2405,2407,2410],{"class":541,"line":717},[539,2378,2379],{"class":726},"  providers",[539,2381,701],{"class":552},[539,2383,2384],{"class":556}," [",[539,2386,2387],{"class":552},"{",[539,2389,2390],{"class":726}," provide",[539,2392,701],{"class":552},[539,2394,617],{"class":556},[539,2396,560],{"class":552},[539,2398,2399],{"class":726}," useClass",[539,2401,701],{"class":552},[539,2403,2404],{"class":556}," DrizzleUserRepository ",[539,2406,1326],{"class":552},[539,2408,2409],{"class":556},"]",[539,2411,1497],{"class":552},[539,2413,2414,2417,2419,2421,2424,2426,2429],{"class":541,"line":769},[539,2415,2416],{"class":726},"  http",[539,2418,701],{"class":552},[539,2420,553],{"class":552},[539,2422,2423],{"class":726}," controllers",[539,2425,701],{"class":552},[539,2427,2428],{"class":556}," [UserController] ",[539,2430,2431],{"class":552},"},\n",[539,2433,2434,2437,2439,2442],{"class":541,"line":825},[539,2435,2436],{"class":726},"  exports",[539,2438,701],{"class":552},[539,2440,2441],{"class":556}," [UserRepository]",[539,2443,1497],{"class":552},[539,2445,2446,2448,2450],{"class":541,"line":852},[539,2447,1326],{"class":552},[539,2449,1289],{"class":556},[539,2451,2452],{"class":552},"{}\n",[499,2454,2455,2456,2459,2460,2463],{},"Every class that injects ",[503,2457,2458],{},"UserRepository"," gets the bound implementation, and swapping the dialect is a\none-line change to ",[503,2461,2462],{},"useClass"," — nothing downstream moves. Don't need the seam? Provide the concrete\nrepository directly, as the first example does.",[512,2465,2467],{"id":2466},"deep-aggregate-persistence","Deep aggregate persistence",[499,2469,2470,2471,2474,2475,2478],{},"When a Drizzle-backed repository is configured with an eager-load relation graph, ",[503,2472,2473],{},"save(entity)"," persists\n",[2136,2476,2477],{},"deeply"," — the root and every eager-loaded child in one transaction. Child rows that were present at\nload but removed from the collection (orphans) are deleted; new rows are inserted; mutated rows are\nupdated with column-level diffs.",[499,2480,2481,2482,2485],{},"Optimistic concurrency is checked at every level: a stale version in any row throws ",[503,2483,2484],{},"ConcurrencyError",". An\nin-memory savepoint reverts the entity's dirty-state and version if the transaction rolls back, so the\naggregate is always consistent with the database after a failed save.",[499,2487,2488,2489,2491],{},"This is handled entirely by the Drizzle dialect — see ",[1908,2490,82],{"href":83}," for how to declare\nthe relation graph and the value-object column type.",[512,2493,2495],{"id":2494},"detect-a-conflict-with-optimistic-concurrency","Detect a conflict with optimistic concurrency",[499,2497,2498,2499,2502,2503,2505,2506,2508,2509,2512,2513,790],{},"When two requests load the same aggregate and both save, the second would silently overwrite the first.\nA ",[503,2500,2501],{},"version"," column closes that race: ",[503,2504,1048],{}," guards its ",[503,2507,1111],{}," with ",[503,2510,2511],{},"WHERE version = \u003Cloaded>",", so if\nanother writer already bumped the version, zero rows update — which the repository reports as a\n",[503,2514,2484],{},[529,2516,2518],{"className":531,"code":2517,"language":534,"meta":535,"style":535},"import { ConcurrencyError } from \"@heximon\u002Fruntime\u002Ferrors\";\n\ntry {\n  await this.users.save(user); \u002F\u002F UPDATE ... WHERE version = 3\n} catch (error) {\n  if (error instanceof ConcurrencyError) {\n    \u002F\u002F Someone else won the race; reload and retry against fresh state.\n  }\n  throw error;\n}\n",[503,2519,2520,2542,2546,2553,2577,2589,2608,2613,2617,2626],{"__ignoreMap":535},[539,2521,2522,2524,2526,2529,2531,2533,2535,2538,2540],{"class":541,"line":542},[539,2523,546],{"class":545},[539,2525,553],{"class":552},[539,2527,2528],{"class":556}," ConcurrencyError",[539,2530,566],{"class":552},[539,2532,569],{"class":545},[539,2534,572],{"class":552},[539,2536,2537],{"class":575},"@heximon\u002Fruntime\u002Ferrors",[539,2539,579],{"class":552},[539,2541,582],{"class":552},[539,2543,2544],{"class":541,"line":585},[539,2545,637],{"emptyLinePlaceholder":636},[539,2547,2548,2551],{"class":541,"line":610},[539,2549,2550],{"class":545},"try",[539,2552,672],{"class":552},[539,2554,2555,2558,2560,2562,2564,2566,2568,2570,2572,2574],{"class":541,"line":633},[539,2556,2557],{"class":545},"  await",[539,2559,784],{"class":552},[539,2561,787],{"class":556},[539,2563,790],{"class":552},[539,2565,1048],{"class":793},[539,2567,688],{"class":726},[539,2569,845],{"class":556},[539,2571,706],{"class":726},[539,2573,1027],{"class":552},[539,2575,2576],{"class":678}," \u002F\u002F UPDATE ... WHERE version = 3\n",[539,2578,2579,2581,2584,2587],{"class":541,"line":640},[539,2580,1326],{"class":552},[539,2582,2583],{"class":545}," catch",[539,2585,2586],{"class":556}," (error) ",[539,2588,2362],{"class":552},[539,2590,2591,2594,2596,2599,2602,2604,2606],{"class":541,"line":675},[539,2592,2593],{"class":545},"  if",[539,2595,1279],{"class":726},[539,2597,2598],{"class":556},"error",[539,2600,2601],{"class":552}," instanceof",[539,2603,2528],{"class":650},[539,2605,1289],{"class":726},[539,2607,2362],{"class":552},[539,2609,2610],{"class":541,"line":682},[539,2611,2612],{"class":678},"    \u002F\u002F Someone else won the race; reload and retry against fresh state.\n",[539,2614,2615],{"class":541,"line":712},[539,2616,855],{"class":552},[539,2618,2619,2622,2624],{"class":541,"line":717},[539,2620,2621],{"class":545},"  throw",[539,2623,1310],{"class":556},[539,2625,582],{"class":552},[539,2627,2628],{"class":541,"line":769},[539,2629,861],{"class":552},[2631,2632,2634,2642,2643,2649],"callout",{"type":2633},"info",[2136,2635,2636,2638,2639,2641],{},[503,2637,2484],{}," comes from ",[503,2640,2537],{},", not the repository package."," Anything\nthat catches it — including the ",[1908,2644,2646],{"href":2645},"\u002Fdocs\u002Farchitecture\u002Fcqrs#automatic-concurrencyerror-retry",[503,2647,2648],{},"CommandBus"," —\nkeys on that one error type.",[499,2651,2652,2653,2656,2657,2659],{},"Inside a command handler you usually skip that try\u002Fcatch: the repository's job is to ",[524,2654,2655],{},"detect"," and throw,\nand the ",[503,2658,2648],{}," retries against fresh state. Only contention triggers a retry — every other error\npropagates, which keeps retries scoped to real races.",[512,2661,2663],{"id":2662},"see-also","See also",[2665,2666,2667,2676,2684,2689,2701],"ul",{},[2668,2669,2670,2672,2673,2675],"li",{},[1908,2671,228],{"href":229}," — the entities, value objects, and aggregates a repository\nloads and saves, including the lifecycle that tells ",[503,2674,1048],{}," insert from update.",[2668,2677,2678,2680,2681,2683],{},[1908,2679,233],{"href":234}," — command handlers that inject a repository and rely on its\n",[503,2682,2484],{}," to drive the automatic retry.",[2668,2685,2686,2688],{},[1908,2687,82],{"href":83}," — the concrete dialect behind the contract: value-object columns, nested\ntransactions, and auto-wired entity mappers.",[2668,2690,2691,2694,2695,506,2697,2700],{},[1908,2692,2693],{"href":88},"Database Wiring"," — the single shared ",[503,2696,77],{},[503,2698,2699],{},"runInTransaction"," transactions, and the\noptimistic-concurrency contract every dialect implements.",[2668,2702,2703,2710,2711,2713,2714,790],{},[1908,2704,2707],{"href":2705,"rel":2706},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL06-ddd",[1912],[2136,2708,2709],{},"L06 — DDD","\n— a ",[503,2712,1724],{}," aggregate behind a Drizzle repository, proven by a test that races two writers into a\n",[503,2715,2484],{},[2717,2718,2719],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":535,"searchDepth":585,"depth":585,"links":2721},[2722,2723,2724,2725,2726,2727,2728,2729,2730],{"id":514,"depth":585,"text":515},{"id":864,"depth":585,"text":865},{"id":1485,"depth":585,"text":1486},{"id":1656,"depth":585,"text":1657},{"id":1942,"depth":585,"text":1943},{"id":2130,"depth":585,"text":2131},{"id":2466,"depth":585,"text":2467},{"id":2494,"depth":585,"text":2495},{"id":2662,"depth":585,"text":2663},"A collection-like persistence boundary with save, getById, getAll, and a zero-codegen EntityQuery, swappable behind an abstract Repository token, with optimistic-concurrency ConcurrencyError.","md",null,{},{"icon":241},{"title":238,"description":2731},"ykQRhHOrvGocZFwBcpLElIO9IvovhCH6ANifJMEdlJM",[2739,2741],{"title":233,"path":234,"stem":235,"description":2740,"icon":236,"children":-1},"Split writes from reads with a typed CommandBus and QueryBus, one handler per message, around-chain interceptors, and automatic ConcurrencyError retry.",{"title":243,"path":244,"stem":245,"description":2742,"icon":246,"children":-1},"Cross-context and cross-service events with IntegrationEvent producers, IntegrationEventHandler consumers, and the transactional outbox (OutboxStore, OutboxRelay, OutboxIntegrationEventTransport).",1783300761903]