[{"data":1,"prerenderedAt":2795},["ShallowReactive",2],{"navigation_docs":3,"-docs-essentials-modules-and-di":493,"-docs-essentials-modules-and-di-surround":2790},[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":53,"body":495,"description":2783,"extension":2784,"links":2785,"meta":2786,"navigation":2787,"path":54,"seo":2788,"stem":55,"__hash__":2789},"docs\u002Fdocs\u002F02.essentials\u002F01.modules-and-di.md",{"type":496,"value":497,"toc":2770},"minimark",[498,512,698,701,706,712,921,924,1081,1108,1121,1124,1203,1212,1227,1231,1240,1341,1463,1480,1486,1492,1504,1650,1674,1697,1706,1879,1900,1917,1921,1927,2041,2051,2054,2182,2186,2200,2210,2225,2229,2254,2260,2270,2273,2328,2339,2344,2353,2367,2378,2382,2389,2449,2455,2493,2542,2556,2594,2620,2629,2655,2661,2683,2694,2698,2766],[499,500,501,502,506,507,511],"p",{},"A module groups one feature and lists what it owns. It's a class that extends ",[503,504,505],"code",{},"Module({...})"," with a\nconfig object naming the classes the feature is built from — its services, its controllers, whatever it\nexposes to other modules. That one list ",[508,509,510],"em",{},"is"," the registration: there's no decorator to add to each class\nand no central registry to keep in sync.",[513,514,520],"pre",{"className":515,"code":516,"filename":517,"language":518,"meta":519,"style":519},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { Module } from \"@heximon\u002Fruntime\";\nimport { UsersController } from \".\u002Fusers.controller\";\nimport { UsersRepository } from \".\u002Fusers.repository\";\n\nexport class UsersModule extends Module({\n  providers: [UsersRepository],\n  http: { controllers: [UsersController] },\n  exports: [UsersRepository],\n}) {}\n","src\u002Fusers\u002Fusers.module.ts","ts","",[503,521,522,558,581,604,611,637,653,674,686],{"__ignoreMap":519},[523,524,527,531,535,539,542,545,548,552,555],"span",{"class":525,"line":526},"line",1,[523,528,530],{"class":529},"s7zQu","import",[523,532,534],{"class":533},"sMK4o"," {",[523,536,538],{"class":537},"sTEyZ"," Module",[523,540,541],{"class":533}," }",[523,543,544],{"class":529}," from",[523,546,547],{"class":533}," \"",[523,549,551],{"class":550},"sfazB","@heximon\u002Fruntime",[523,553,554],{"class":533},"\"",[523,556,557],{"class":533},";\n",[523,559,561,563,565,568,570,572,574,577,579],{"class":525,"line":560},2,[523,562,530],{"class":529},[523,564,534],{"class":533},[523,566,567],{"class":537}," UsersController",[523,569,541],{"class":533},[523,571,544],{"class":529},[523,573,547],{"class":533},[523,575,576],{"class":550},".\u002Fusers.controller",[523,578,554],{"class":533},[523,580,557],{"class":533},[523,582,584,586,588,591,593,595,597,600,602],{"class":525,"line":583},3,[523,585,530],{"class":529},[523,587,534],{"class":533},[523,589,590],{"class":537}," UsersRepository",[523,592,541],{"class":533},[523,594,544],{"class":529},[523,596,547],{"class":533},[523,598,599],{"class":550},".\u002Fusers.repository",[523,601,554],{"class":533},[523,603,557],{"class":533},[523,605,607],{"class":525,"line":606},4,[523,608,610],{"emptyLinePlaceholder":609},true,"\n",[523,612,614,617,621,625,628,631,634],{"class":525,"line":613},5,[523,615,616],{"class":529},"export",[523,618,620],{"class":619},"spNyl"," class",[523,622,624],{"class":623},"sBMFI"," UsersModule",[523,626,627],{"class":619}," extends",[523,629,538],{"class":630},"s2Zo4",[523,632,633],{"class":537},"(",[523,635,636],{"class":533},"{\n",[523,638,640,644,647,650],{"class":525,"line":639},6,[523,641,643],{"class":642},"swJcz","  providers",[523,645,646],{"class":533},":",[523,648,649],{"class":537}," [UsersRepository]",[523,651,652],{"class":533},",\n",[523,654,656,659,661,663,666,668,671],{"class":525,"line":655},7,[523,657,658],{"class":642},"  http",[523,660,646],{"class":533},[523,662,534],{"class":533},[523,664,665],{"class":642}," controllers",[523,667,646],{"class":533},[523,669,670],{"class":537}," [UsersController] ",[523,672,673],{"class":533},"},\n",[523,675,677,680,682,684],{"class":525,"line":676},8,[523,678,679],{"class":642},"  exports",[523,681,646],{"class":533},[523,683,649],{"class":537},[523,685,652],{"class":533},[523,687,689,692,695],{"class":525,"line":688},9,[523,690,691],{"class":533},"}",[523,693,694],{"class":537},") ",[523,696,697],{"class":533},"{}\n",[499,699,700],{},"That's a complete feature: a repository it constructs, a controller it serves, and the repository made\navailable to other modules. The class body stays empty — everything lives in the config, because that's\nthe part Heximon reads to wire the app.",[702,703,705],"h2",{"id":704},"providers-are-plain-classes-wired-by-constructor","Providers are plain classes, wired by constructor",[499,707,708,711],{},[503,709,710],{},"providers"," holds the plain classes the module constructs — services, repositories, factories. A class\nbecomes injectable simply by being listed here; there's no decorator and no token to declare. Declare\nthe dependency as a constructor parameter typed by the class you want, and the compiler matches the type\nto a provider by identity and passes the right instance in — no token, no decorator.",[513,713,716],{"className":515,"code":714,"filename":715,"language":518,"meta":519,"style":519},"import type { Controller, Get } from \"@heximon\u002Fhttp\";\n\nexport class UsersController implements Controller\u003C\"\u002Fusers\"> {\n  \u002F\u002F resolved by class identity — no token, no decorator\n  constructor(private readonly users: UsersRepository) {}\n\n  public async list(_action: Get\u003C\"\u002F\", { scopes: [\"public\"] }>): Promise\u003CUser[]> {\n    return this.users.list();\n  }\n}\n","src\u002Fusers\u002Fusers.controller.ts",[503,717,718,749,753,782,788,815,819,888,910,915],{"__ignoreMap":519},[523,719,720,722,725,727,730,733,736,738,740,742,745,747],{"class":525,"line":526},[523,721,530],{"class":529},[523,723,724],{"class":529}," type",[523,726,534],{"class":533},[523,728,729],{"class":537}," Controller",[523,731,732],{"class":533},",",[523,734,735],{"class":537}," Get",[523,737,541],{"class":533},[523,739,544],{"class":529},[523,741,547],{"class":533},[523,743,744],{"class":550},"@heximon\u002Fhttp",[523,746,554],{"class":533},[523,748,557],{"class":533},[523,750,751],{"class":525,"line":560},[523,752,610],{"emptyLinePlaceholder":609},[523,754,755,757,759,761,764,766,769,771,774,776,779],{"class":525,"line":583},[523,756,616],{"class":529},[523,758,620],{"class":619},[523,760,567],{"class":623},[523,762,763],{"class":619}," implements",[523,765,729],{"class":623},[523,767,768],{"class":533},"\u003C",[523,770,554],{"class":533},[523,772,773],{"class":550},"\u002Fusers",[523,775,554],{"class":533},[523,777,778],{"class":533},">",[523,780,781],{"class":533}," {\n",[523,783,784],{"class":525,"line":606},[523,785,787],{"class":786},"sHwdD","  \u002F\u002F resolved by class identity — no token, no decorator\n",[523,789,790,793,795,798,801,805,807,809,812],{"class":525,"line":613},[523,791,792],{"class":619},"  constructor",[523,794,633],{"class":533},[523,796,797],{"class":619},"private",[523,799,800],{"class":619}," readonly",[523,802,804],{"class":803},"sHdIc"," users",[523,806,646],{"class":533},[523,808,590],{"class":623},[523,810,811],{"class":533},")",[523,813,814],{"class":533}," {}\n",[523,816,817],{"class":525,"line":639},[523,818,610],{"emptyLinePlaceholder":609},[523,820,821,824,827,830,832,835,837,839,841,843,846,848,850,852,855,857,860,862,865,867,870,873,876,878,881,884,886],{"class":525,"line":655},[523,822,823],{"class":619},"  public",[523,825,826],{"class":619}," async",[523,828,829],{"class":642}," list",[523,831,633],{"class":533},[523,833,834],{"class":803},"_action",[523,836,646],{"class":533},[523,838,735],{"class":623},[523,840,768],{"class":533},[523,842,554],{"class":533},[523,844,845],{"class":550},"\u002F",[523,847,554],{"class":533},[523,849,732],{"class":533},[523,851,534],{"class":533},[523,853,854],{"class":642}," scopes",[523,856,646],{"class":533},[523,858,859],{"class":537}," [",[523,861,554],{"class":533},[523,863,864],{"class":550},"public",[523,866,554],{"class":533},[523,868,869],{"class":537},"] ",[523,871,872],{"class":533},"}>):",[523,874,875],{"class":623}," Promise",[523,877,768],{"class":533},[523,879,880],{"class":623},"User",[523,882,883],{"class":537},"[]",[523,885,778],{"class":533},[523,887,781],{"class":533},[523,889,890,893,896,899,902,905,908],{"class":525,"line":676},[523,891,892],{"class":529},"    return",[523,894,895],{"class":533}," this.",[523,897,898],{"class":537},"users",[523,900,901],{"class":533},".",[523,903,904],{"class":630},"list",[523,906,907],{"class":642},"()",[523,909,557],{"class":533},[523,911,912],{"class":525,"line":688},[523,913,914],{"class":533},"  }\n",[523,916,918],{"class":525,"line":917},10,[523,919,920],{"class":533},"}\n",[499,922,923],{},"The repository itself is just as plain — no Heximon imports at all. Heximon constructs it once and shares\nthat single instance with every consumer.",[513,925,928],{"className":515,"code":926,"filename":927,"language":518,"meta":519,"style":519},"export interface User {\n  readonly id: string;\n  readonly name: string;\n}\n\nexport class UsersRepository {\n  private readonly usersById = new Map\u003Cstring, User>();\n\n  public async list(): Promise\u003CUser[]> {\n    return [...this.usersById.values()];\n  }\n}\n","src\u002Fusers\u002Fusers.repository.ts",[503,929,930,942,957,970,974,978,988,1022,1026,1049,1071,1076],{"__ignoreMap":519},[523,931,932,934,937,940],{"class":525,"line":526},[523,933,616],{"class":529},[523,935,936],{"class":619}," interface",[523,938,939],{"class":623}," User",[523,941,781],{"class":533},[523,943,944,947,950,952,955],{"class":525,"line":560},[523,945,946],{"class":619},"  readonly",[523,948,949],{"class":642}," id",[523,951,646],{"class":533},[523,953,954],{"class":623}," string",[523,956,557],{"class":533},[523,958,959,961,964,966,968],{"class":525,"line":583},[523,960,946],{"class":619},[523,962,963],{"class":642}," name",[523,965,646],{"class":533},[523,967,954],{"class":623},[523,969,557],{"class":533},[523,971,972],{"class":525,"line":606},[523,973,920],{"class":533},[523,975,976],{"class":525,"line":613},[523,977,610],{"emptyLinePlaceholder":609},[523,979,980,982,984,986],{"class":525,"line":639},[523,981,616],{"class":529},[523,983,620],{"class":619},[523,985,590],{"class":623},[523,987,781],{"class":533},[523,989,990,993,995,998,1001,1004,1007,1009,1012,1014,1016,1018,1020],{"class":525,"line":655},[523,991,992],{"class":619},"  private",[523,994,800],{"class":619},[523,996,997],{"class":642}," usersById",[523,999,1000],{"class":533}," =",[523,1002,1003],{"class":533}," new",[523,1005,1006],{"class":642}," Map",[523,1008,768],{"class":533},[523,1010,1011],{"class":623},"string",[523,1013,732],{"class":533},[523,1015,939],{"class":623},[523,1017,778],{"class":533},[523,1019,907],{"class":537},[523,1021,557],{"class":533},[523,1023,1024],{"class":525,"line":676},[523,1025,610],{"emptyLinePlaceholder":609},[523,1027,1028,1030,1032,1034,1037,1039,1041,1043,1045,1047],{"class":525,"line":688},[523,1029,823],{"class":619},[523,1031,826],{"class":619},[523,1033,829],{"class":642},[523,1035,1036],{"class":533},"():",[523,1038,875],{"class":623},[523,1040,768],{"class":533},[523,1042,880],{"class":623},[523,1044,883],{"class":537},[523,1046,778],{"class":533},[523,1048,781],{"class":533},[523,1050,1051,1053,1055,1058,1061,1063,1066,1069],{"class":525,"line":917},[523,1052,892],{"class":529},[523,1054,859],{"class":642},[523,1056,1057],{"class":533},"...this.",[523,1059,1060],{"class":537},"usersById",[523,1062,901],{"class":533},[523,1064,1065],{"class":630},"values",[523,1067,1068],{"class":642},"()]",[523,1070,557],{"class":533},[523,1072,1074],{"class":525,"line":1073},11,[523,1075,914],{"class":533},[523,1077,1079],{"class":525,"line":1078},12,[523,1080,920],{"class":533},[499,1082,1083,1086,1087,1090,1091,1094,1095,1097,1098,1100,1101,1100,1104,1107],{},[503,1084,1085],{},"UsersRepository"," is a provider; ",[503,1088,1089],{},"UsersController"," is listed under ",[503,1092,1093],{},"http",". The distinction matters:\n",[503,1096,710],{}," is for plain injectables, while controllers, event handlers, command handlers, and the like\ngo under their feature's key (",[503,1099,1093],{},", ",[503,1102,1103],{},"events",[503,1105,1106],{},"cqrs",", …) so Heximon knows what kind of thing each is.",[499,1109,1110,1111,1114,1115,1117,1118,1120],{},"That class is ",[508,1112,1113],{},"also"," a provider, resolvable exactly like an entry in ",[503,1116,710],{},", which is why you\nnever list a controller twice. Putting a controller in ",[503,1119,710],{}," would construct it but never route to it.",[499,1122,1123],{},"Every module config draws from the same small set of kernel fields, all optional:",[1125,1126,1127,1141],"table",{},[1128,1129,1130],"thead",{},[1131,1132,1133,1138],"tr",{},[1134,1135,1137],"th",{"align":1136},"left","Field",[1134,1139,1140],{"align":1136},"Purpose",[1142,1143,1144,1154,1169,1179,1189],"tbody",{},[1131,1145,1146,1151],{},[1147,1148,1149],"td",{"align":1136},[503,1150,710],{},[1147,1152,1153],{"align":1136},"The plain classes this module constructs and owns.",[1131,1155,1156,1161],{},[1147,1157,1158],{"align":1136},[503,1159,1160],{},"imports",[1147,1162,1163,1164,1168],{"align":1136},"Other modules whose ",[1165,1166,1167],"strong",{},"exported"," providers become visible here.",[1131,1170,1171,1176],{},[1147,1172,1173],{"align":1136},[503,1174,1175],{},"exports",[1147,1177,1178],{"align":1136},"Providers (or whole modules) this module makes visible to its importers.",[1131,1180,1181,1186],{},[1147,1182,1183],{"align":1136},[503,1184,1185],{},"requires",[1147,1187,1188],{"align":1136},"Tokens this module expects its host to supply, declared but not provided here.",[1131,1190,1191,1196],{},[1147,1192,1193],{"align":1136},[503,1194,1195],{},"overrides",[1147,1197,1198,1199,901],{"align":1136},"Test-only substitutes for real providers — see ",[1200,1201,1202],"a",{"href":112},"Testing",[499,1204,1205,1206,1208,1209,1211],{},"A module's classes can inject its own ",[503,1207,710],{}," plus everything its ",[503,1210,1160],{}," export — nothing more.\nThat boundary is the point: it keeps each feature's internals private and makes every cross-module\ndependency an explicit, visible edge.",[499,1213,1214,1217,1218,1221,1222,1226],{},[1165,1215,1216],{},"Config errors are field-level."," The ",[503,1219,1220],{},"Module(...)"," call is generically typed, so a broken dependency lands\nas an editor error on the offending entry — naming the missing type or the misspelled key — rather than the\nopaque \"Expected 2 arguments, but got 1\" an untyped guard produces. See\n",[1200,1223,1225],{"href":1224},"#what-the-editor-catches-and-what-stays-build-time","What the editor catches"," below for the full list.",[702,1228,1230],{"id":1229},"share-a-provider-with-imports-and-exports","Share a provider with imports and exports",[499,1232,1233,1234,1236,1237,1239],{},"A provider is private to its module by default. To let another module inject it, list it in ",[503,1235,1175],{},";\nto gain access, ",[503,1238,530],{}," the module that exports it. Both halves are required, so every shared\ndependency is an intentional, two-sided agreement.",[513,1241,1244],{"className":515,"code":1242,"filename":1243,"language":518,"meta":519,"style":519},"import { Module } from \"@heximon\u002Fruntime\";\nimport { DatabaseConnection } from \".\u002Fdatabase-connection\";\n\nexport class DatabaseModule extends Module({\n  providers: [DatabaseConnection],\n  exports: [DatabaseConnection], \u002F\u002F visible to any module that imports DatabaseModule\n}) {}\n","src\u002Fdatabase\u002Fdatabase.module.ts",[503,1245,1246,1266,1288,1292,1309,1320,1333],{"__ignoreMap":519},[523,1247,1248,1250,1252,1254,1256,1258,1260,1262,1264],{"class":525,"line":526},[523,1249,530],{"class":529},[523,1251,534],{"class":533},[523,1253,538],{"class":537},[523,1255,541],{"class":533},[523,1257,544],{"class":529},[523,1259,547],{"class":533},[523,1261,551],{"class":550},[523,1263,554],{"class":533},[523,1265,557],{"class":533},[523,1267,1268,1270,1272,1275,1277,1279,1281,1284,1286],{"class":525,"line":560},[523,1269,530],{"class":529},[523,1271,534],{"class":533},[523,1273,1274],{"class":537}," DatabaseConnection",[523,1276,541],{"class":533},[523,1278,544],{"class":529},[523,1280,547],{"class":533},[523,1282,1283],{"class":550},".\u002Fdatabase-connection",[523,1285,554],{"class":533},[523,1287,557],{"class":533},[523,1289,1290],{"class":525,"line":583},[523,1291,610],{"emptyLinePlaceholder":609},[523,1293,1294,1296,1298,1301,1303,1305,1307],{"class":525,"line":606},[523,1295,616],{"class":529},[523,1297,620],{"class":619},[523,1299,1300],{"class":623}," DatabaseModule",[523,1302,627],{"class":619},[523,1304,538],{"class":630},[523,1306,633],{"class":537},[523,1308,636],{"class":533},[523,1310,1311,1313,1315,1318],{"class":525,"line":613},[523,1312,643],{"class":642},[523,1314,646],{"class":533},[523,1316,1317],{"class":537}," [DatabaseConnection]",[523,1319,652],{"class":533},[523,1321,1322,1324,1326,1328,1330],{"class":525,"line":639},[523,1323,679],{"class":642},[523,1325,646],{"class":533},[523,1327,1317],{"class":537},[523,1329,732],{"class":533},[523,1331,1332],{"class":786}," \u002F\u002F visible to any module that imports DatabaseModule\n",[523,1334,1335,1337,1339],{"class":525,"line":655},[523,1336,691],{"class":533},[523,1338,694],{"class":537},[523,1340,697],{"class":533},[513,1342,1344],{"className":515,"code":1343,"filename":517,"language":518,"meta":519,"style":519},"import { Module } from \"@heximon\u002Fruntime\";\nimport { DatabaseModule } from \"..\u002Fdatabase\u002Fdatabase.module\";\nimport { UsersRepository } from \".\u002Fusers.repository\";\n\nexport class UsersModule extends Module({\n  imports: [DatabaseModule],    \u002F\u002F brings DatabaseConnection into view\n  providers: [UsersRepository], \u002F\u002F its constructor can now inject DatabaseConnection\n}) {}\n",[503,1345,1346,1366,1387,1407,1411,1427,1442,1455],{"__ignoreMap":519},[523,1347,1348,1350,1352,1354,1356,1358,1360,1362,1364],{"class":525,"line":526},[523,1349,530],{"class":529},[523,1351,534],{"class":533},[523,1353,538],{"class":537},[523,1355,541],{"class":533},[523,1357,544],{"class":529},[523,1359,547],{"class":533},[523,1361,551],{"class":550},[523,1363,554],{"class":533},[523,1365,557],{"class":533},[523,1367,1368,1370,1372,1374,1376,1378,1380,1383,1385],{"class":525,"line":560},[523,1369,530],{"class":529},[523,1371,534],{"class":533},[523,1373,1300],{"class":537},[523,1375,541],{"class":533},[523,1377,544],{"class":529},[523,1379,547],{"class":533},[523,1381,1382],{"class":550},"..\u002Fdatabase\u002Fdatabase.module",[523,1384,554],{"class":533},[523,1386,557],{"class":533},[523,1388,1389,1391,1393,1395,1397,1399,1401,1403,1405],{"class":525,"line":583},[523,1390,530],{"class":529},[523,1392,534],{"class":533},[523,1394,590],{"class":537},[523,1396,541],{"class":533},[523,1398,544],{"class":529},[523,1400,547],{"class":533},[523,1402,599],{"class":550},[523,1404,554],{"class":533},[523,1406,557],{"class":533},[523,1408,1409],{"class":525,"line":606},[523,1410,610],{"emptyLinePlaceholder":609},[523,1412,1413,1415,1417,1419,1421,1423,1425],{"class":525,"line":613},[523,1414,616],{"class":529},[523,1416,620],{"class":619},[523,1418,624],{"class":623},[523,1420,627],{"class":619},[523,1422,538],{"class":630},[523,1424,633],{"class":537},[523,1426,636],{"class":533},[523,1428,1429,1432,1434,1437,1439],{"class":525,"line":639},[523,1430,1431],{"class":642},"  imports",[523,1433,646],{"class":533},[523,1435,1436],{"class":537}," [DatabaseModule]",[523,1438,732],{"class":533},[523,1440,1441],{"class":786},"    \u002F\u002F brings DatabaseConnection into view\n",[523,1443,1444,1446,1448,1450,1452],{"class":525,"line":655},[523,1445,643],{"class":642},[523,1447,646],{"class":533},[523,1449,649],{"class":537},[523,1451,732],{"class":533},[523,1453,1454],{"class":786}," \u002F\u002F its constructor can now inject DatabaseConnection\n",[523,1456,1457,1459,1461],{"class":525,"line":676},[523,1458,691],{"class":533},[523,1460,694],{"class":537},[523,1462,697],{"class":533},[499,1464,1465,1466,1469,1470,1472,1473,1476,1477,1479],{},"Importing ",[503,1467,1468],{},"DatabaseModule"," makes only its ",[1165,1471,1175],{}," visible — ",[503,1474,1475],{},"DatabaseConnection",", not whatever else\n",[503,1478,1468],{}," keeps to itself. If you export a token the module doesn't own (it isn't your provider\nor an imported module's export), that's a build error, so a module can never promise something it can't\ndeliver.",[499,1481,1482,1483,1485],{},"A module can also re-export an imported module wholesale: list the module itself in ",[503,1484,1175],{},", and its\nentire export set flows onward to anyone importing yours. That's how a shared \"infrastructure\" module\nforwards a database, a cache, and a clock as a single import.",[702,1487,1489,1490],{"id":1488},"declare-what-you-expect-the-host-to-supply-requires","Declare what you expect the host to supply: ",[503,1491,1185],{},[499,1493,1494,1496,1497,1500,1501,1503],{},[503,1495,1185],{}," is for a module that expects a token from ",[1165,1498,1499],{},"outside itself"," — a published feature module, or a\nbounded-context module that deliberately doesn't own its persistence choice. It's a promise in the other\ndirection from ",[503,1502,1175],{},": instead of \"here's something I provide\", it's \"here's something I need someone\nelse to\".",[513,1505,1508],{"className":515,"code":1506,"filename":1507,"language":518,"meta":519,"style":519},"import { Module } from \"@heximon\u002Fruntime\";\nimport { BillingDatabase } from \".\u002Fbilling-database\";\nimport { BillingRepository, BillingService } from \".\u002Fbilling.service\";\n\nexport class BillingModule extends Module({\n  requires: [BillingDatabase],           \u002F\u002F the composing app must provide this\n  providers: [BillingRepository, BillingService],\n  exports: [BillingService],\n}) {}\n","src\u002Fbilling\u002Fbilling.module.ts",[503,1509,1510,1530,1552,1579,1583,1600,1615,1631,1642],{"__ignoreMap":519},[523,1511,1512,1514,1516,1518,1520,1522,1524,1526,1528],{"class":525,"line":526},[523,1513,530],{"class":529},[523,1515,534],{"class":533},[523,1517,538],{"class":537},[523,1519,541],{"class":533},[523,1521,544],{"class":529},[523,1523,547],{"class":533},[523,1525,551],{"class":550},[523,1527,554],{"class":533},[523,1529,557],{"class":533},[523,1531,1532,1534,1536,1539,1541,1543,1545,1548,1550],{"class":525,"line":560},[523,1533,530],{"class":529},[523,1535,534],{"class":533},[523,1537,1538],{"class":537}," BillingDatabase",[523,1540,541],{"class":533},[523,1542,544],{"class":529},[523,1544,547],{"class":533},[523,1546,1547],{"class":550},".\u002Fbilling-database",[523,1549,554],{"class":533},[523,1551,557],{"class":533},[523,1553,1554,1556,1558,1561,1563,1566,1568,1570,1572,1575,1577],{"class":525,"line":583},[523,1555,530],{"class":529},[523,1557,534],{"class":533},[523,1559,1560],{"class":537}," BillingRepository",[523,1562,732],{"class":533},[523,1564,1565],{"class":537}," BillingService",[523,1567,541],{"class":533},[523,1569,544],{"class":529},[523,1571,547],{"class":533},[523,1573,1574],{"class":550},".\u002Fbilling.service",[523,1576,554],{"class":533},[523,1578,557],{"class":533},[523,1580,1581],{"class":525,"line":606},[523,1582,610],{"emptyLinePlaceholder":609},[523,1584,1585,1587,1589,1592,1594,1596,1598],{"class":525,"line":613},[523,1586,616],{"class":529},[523,1588,620],{"class":619},[523,1590,1591],{"class":623}," BillingModule",[523,1593,627],{"class":619},[523,1595,538],{"class":630},[523,1597,633],{"class":537},[523,1599,636],{"class":533},[523,1601,1602,1605,1607,1610,1612],{"class":525,"line":639},[523,1603,1604],{"class":642},"  requires",[523,1606,646],{"class":533},[523,1608,1609],{"class":537}," [BillingDatabase]",[523,1611,732],{"class":533},[523,1613,1614],{"class":786},"           \u002F\u002F the composing app must provide this\n",[523,1616,1617,1619,1621,1624,1626,1629],{"class":525,"line":655},[523,1618,643],{"class":642},[523,1620,646],{"class":533},[523,1622,1623],{"class":537}," [BillingRepository",[523,1625,732],{"class":533},[523,1627,1628],{"class":537}," BillingService]",[523,1630,652],{"class":533},[523,1632,1633,1635,1637,1640],{"class":525,"line":676},[523,1634,679],{"class":642},[523,1636,646],{"class":533},[523,1638,1639],{"class":537}," [BillingService]",[523,1641,652],{"class":533},[523,1643,1644,1646,1648],{"class":525,"line":688},[523,1645,691],{"class":533},[523,1647,694],{"class":537},[523,1649,697],{"class":533},[499,1651,1652,1655,1656,1658,1659,1100,1661,1664,1665,1667,1668,1670,1671,1673],{},[1165,1653,1654],{},"The propagation rule: a token flows only along a declared edge, one hop at a time."," If a module you\n",[503,1657,530],{}," declares a ",[503,1660,1185],{},[508,1662,1663],{},"your"," module must do one of two things — provide that token itself, or\nre-declare it under your own ",[503,1666,1185],{}," so the obligation passes one hop further up. Nothing tunnels through\nan ",[503,1669,1160],{}," edge unnoticed: the editor checks this the moment you compose, and the compiler enforces the\nsame rule at build time — a hop that drops a token fails the build naming the module that dropped it, and a\nroot module's leftover ",[503,1672,1185],{}," (nothing above it to pass to) fails the same way.",[499,1675,1676,1677,1680,1681,1100,1684,1100,1687,1690,1691,1693,1694,1696],{},"The flagship example's ",[503,1678,1679],{},"MonolithModule"," is the canonical case: it bundles bounded-context modules\n(",[503,1682,1683],{},"CatalogModule",[503,1685,1686],{},"OrdersModule",[503,1688,1689],{},"PaymentsModule",", …), each of which declares its own persistence and\nplatform seams under ",[503,1692,1185],{}," — but ",[503,1695,1679],{}," itself binds no database and no platform adapter.",[499,1698,1699,1700,1702,1703,1705],{},"It must re-declare every one of those tokens under its own ",[503,1701,1185],{},", so the app that finally composes\n",[503,1704,1679],{}," sees exactly what it owes:",[513,1707,1710],{"className":515,"code":1708,"filename":1709,"language":518,"meta":519,"style":519},"export class MonolithModule extends Module({\n  requires: [\n    Storage,\n    Cache,\n    EventRepository,     \u002F\u002F required by the imported CatalogModule\n    OrderRepository,     \u002F\u002F required by the imported OrdersModule\n    Database,            \u002F\u002F required by the imported OrdersModule\n    PaymentRepository,   \u002F\u002F required by the imported PaymentsModule\n    PaymentGateway,      \u002F\u002F required by the imported PaymentsModule\n    BlobStore,           \u002F\u002F required by the imported BannerModule\n  ],\n  imports: [\n    CatalogModule,\n    OrdersModule,\n    PaymentsModule,\n    \u002F\u002F …\n  ],\n  \u002F\u002F …\n}) {}\n","examples\u002Fflagship\u002Fpackages\u002Fapp\u002Fsrc\u002Fmonolith.module.ts",[503,1711,1712,1729,1738,1745,1752,1762,1772,1782,1792,1802,1812,1819,1827,1835,1843,1851,1857,1864,1870],{"__ignoreMap":519},[523,1713,1714,1716,1718,1721,1723,1725,1727],{"class":525,"line":526},[523,1715,616],{"class":529},[523,1717,620],{"class":619},[523,1719,1720],{"class":623}," MonolithModule",[523,1722,627],{"class":619},[523,1724,538],{"class":630},[523,1726,633],{"class":537},[523,1728,636],{"class":533},[523,1730,1731,1733,1735],{"class":525,"line":560},[523,1732,1604],{"class":642},[523,1734,646],{"class":533},[523,1736,1737],{"class":537}," [\n",[523,1739,1740,1743],{"class":525,"line":583},[523,1741,1742],{"class":537},"    Storage",[523,1744,652],{"class":533},[523,1746,1747,1750],{"class":525,"line":606},[523,1748,1749],{"class":537},"    Cache",[523,1751,652],{"class":533},[523,1753,1754,1757,1759],{"class":525,"line":613},[523,1755,1756],{"class":537},"    EventRepository",[523,1758,732],{"class":533},[523,1760,1761],{"class":786},"     \u002F\u002F required by the imported CatalogModule\n",[523,1763,1764,1767,1769],{"class":525,"line":639},[523,1765,1766],{"class":537},"    OrderRepository",[523,1768,732],{"class":533},[523,1770,1771],{"class":786},"     \u002F\u002F required by the imported OrdersModule\n",[523,1773,1774,1777,1779],{"class":525,"line":655},[523,1775,1776],{"class":537},"    Database",[523,1778,732],{"class":533},[523,1780,1781],{"class":786},"            \u002F\u002F required by the imported OrdersModule\n",[523,1783,1784,1787,1789],{"class":525,"line":676},[523,1785,1786],{"class":537},"    PaymentRepository",[523,1788,732],{"class":533},[523,1790,1791],{"class":786},"   \u002F\u002F required by the imported PaymentsModule\n",[523,1793,1794,1797,1799],{"class":525,"line":688},[523,1795,1796],{"class":537},"    PaymentGateway",[523,1798,732],{"class":533},[523,1800,1801],{"class":786},"      \u002F\u002F required by the imported PaymentsModule\n",[523,1803,1804,1807,1809],{"class":525,"line":917},[523,1805,1806],{"class":537},"    BlobStore",[523,1808,732],{"class":533},[523,1810,1811],{"class":786},"           \u002F\u002F required by the imported BannerModule\n",[523,1813,1814,1817],{"class":525,"line":1073},[523,1815,1816],{"class":537},"  ]",[523,1818,652],{"class":533},[523,1820,1821,1823,1825],{"class":525,"line":1078},[523,1822,1431],{"class":642},[523,1824,646],{"class":533},[523,1826,1737],{"class":537},[523,1828,1830,1833],{"class":525,"line":1829},13,[523,1831,1832],{"class":537},"    CatalogModule",[523,1834,652],{"class":533},[523,1836,1838,1841],{"class":525,"line":1837},14,[523,1839,1840],{"class":537},"    OrdersModule",[523,1842,652],{"class":533},[523,1844,1846,1849],{"class":525,"line":1845},15,[523,1847,1848],{"class":537},"    PaymentsModule",[523,1850,652],{"class":533},[523,1852,1854],{"class":525,"line":1853},16,[523,1855,1856],{"class":786},"    \u002F\u002F …\n",[523,1858,1860,1862],{"class":525,"line":1859},17,[523,1861,1816],{"class":537},[523,1863,652],{"class":533},[523,1865,1867],{"class":525,"line":1866},18,[523,1868,1869],{"class":786},"  \u002F\u002F …\n",[523,1871,1873,1875,1877],{"class":525,"line":1872},19,[523,1874,691],{"class":533},[523,1876,694],{"class":537},[523,1878,697],{"class":533},[499,1880,1881,1882,1885,1886,1889,1890,1892,1893,1896,1897,1899],{},"When a bundle forgets one of these — say it re-declares only ",[503,1883,1884],{},"Storage"," and ",[503,1887,1888],{},"Cache"," — the editor flags the\noffending ",[503,1891,1160],{}," entry immediately, naming each unmet token, and a build reports the same hop as\n",[503,1894,1895],{},"graph.requires-not-propagated",". The fix is always the same: provide the token in the bundle, or name it\nunder the bundle's own ",[503,1898,1185],{}," to pass the obligation up.",[1901,1902,1904,1906,1907,1910,1911,1913,1914,1916],"callout",{"type":1903},"tip",[503,1905,1175],{}," does ",[1165,1908,1909],{},"not"," automatically include a module's namespace concept classes (controllers, handlers,\n…) — only ",[503,1912,710],{}," and re-exported imports. If a module wants an importer to reach a handler class\ndirectly (for inspection in a test, say), it must list that class in ",[503,1915,1175],{}," explicitly, even though the\nclass is already DI-visible inside its own module.",[702,1918,1920],{"id":1919},"compose-the-app-from-a-root-module","Compose the app from a root module",[499,1922,1923,1924,1926],{},"A root module composes feature modules through ",[503,1925,1160],{},". It usually declares nothing of its own — it\njust names the features that make up the app.",[513,1928,1931],{"className":515,"code":1929,"filename":1930,"language":518,"meta":519,"style":519},"import { Module } from \"@heximon\u002Fruntime\";\nimport { CatalogModule } from \".\u002Fcatalog\u002Fcatalog.module\";\nimport { UsersModule } from \".\u002Fusers\u002Fusers.module\";\n\nexport class AppModule extends Module({\n  imports: [UsersModule, CatalogModule],\n}) {}\n","src\u002Fapp.module.ts",[503,1932,1933,1953,1975,1996,2000,2017,2033],{"__ignoreMap":519},[523,1934,1935,1937,1939,1941,1943,1945,1947,1949,1951],{"class":525,"line":526},[523,1936,530],{"class":529},[523,1938,534],{"class":533},[523,1940,538],{"class":537},[523,1942,541],{"class":533},[523,1944,544],{"class":529},[523,1946,547],{"class":533},[523,1948,551],{"class":550},[523,1950,554],{"class":533},[523,1952,557],{"class":533},[523,1954,1955,1957,1959,1962,1964,1966,1968,1971,1973],{"class":525,"line":560},[523,1956,530],{"class":529},[523,1958,534],{"class":533},[523,1960,1961],{"class":537}," CatalogModule",[523,1963,541],{"class":533},[523,1965,544],{"class":529},[523,1967,547],{"class":533},[523,1969,1970],{"class":550},".\u002Fcatalog\u002Fcatalog.module",[523,1972,554],{"class":533},[523,1974,557],{"class":533},[523,1976,1977,1979,1981,1983,1985,1987,1989,1992,1994],{"class":525,"line":583},[523,1978,530],{"class":529},[523,1980,534],{"class":533},[523,1982,624],{"class":537},[523,1984,541],{"class":533},[523,1986,544],{"class":529},[523,1988,547],{"class":533},[523,1990,1991],{"class":550},".\u002Fusers\u002Fusers.module",[523,1993,554],{"class":533},[523,1995,557],{"class":533},[523,1997,1998],{"class":525,"line":606},[523,1999,610],{"emptyLinePlaceholder":609},[523,2001,2002,2004,2006,2009,2011,2013,2015],{"class":525,"line":613},[523,2003,616],{"class":529},[523,2005,620],{"class":619},[523,2007,2008],{"class":623}," AppModule",[523,2010,627],{"class":619},[523,2012,538],{"class":630},[523,2014,633],{"class":537},[523,2016,636],{"class":533},[523,2018,2019,2021,2023,2026,2028,2031],{"class":525,"line":639},[523,2020,1431],{"class":642},[523,2022,646],{"class":533},[523,2024,2025],{"class":537}," [UsersModule",[523,2027,732],{"class":533},[523,2029,2030],{"class":537}," CatalogModule]",[523,2032,652],{"class":533},[523,2034,2035,2037,2039],{"class":525,"line":655},[523,2036,691],{"class":533},[523,2038,694],{"class":537},[523,2040,697],{"class":533},[499,2042,2043,2044,2046,2047,2050],{},"The root is just the module no other module imports — Heximon picks it up as your app automatically, with\nno entry file to register it. From here Heximon follows the ",[503,2045,1160],{}," to build one dependency graph for\nthe whole application: every constructor parameter across every module is resolved into the single\n",[503,2048,2049],{},"new Foo(bar)"," chain that boots your app.",[499,2052,2053],{},"A root module can also carry feature keys of its own. Module-level HTTP middleware, for instance,\npropagates down the import graph and wraps every inherited route — useful for a request logger that\nshould run app-wide:",[513,2055,2057],{"className":515,"code":2056,"filename":1930,"language":518,"meta":519,"style":519},"import { Module } from \"@heximon\u002Fruntime\";\nimport { RequestLogMiddleware } from \".\u002Frequest-log.middleware\";\nimport { UsersModule } from \".\u002Fusers\u002Fusers.module\";\n\nexport class AppModule extends Module({\n  imports: [UsersModule],\n  http: { middlewares: [RequestLogMiddleware] }, \u002F\u002F wraps every route under UsersModule\n}) {}\n",[503,2058,2059,2079,2101,2121,2125,2141,2152,2174],{"__ignoreMap":519},[523,2060,2061,2063,2065,2067,2069,2071,2073,2075,2077],{"class":525,"line":526},[523,2062,530],{"class":529},[523,2064,534],{"class":533},[523,2066,538],{"class":537},[523,2068,541],{"class":533},[523,2070,544],{"class":529},[523,2072,547],{"class":533},[523,2074,551],{"class":550},[523,2076,554],{"class":533},[523,2078,557],{"class":533},[523,2080,2081,2083,2085,2088,2090,2092,2094,2097,2099],{"class":525,"line":560},[523,2082,530],{"class":529},[523,2084,534],{"class":533},[523,2086,2087],{"class":537}," RequestLogMiddleware",[523,2089,541],{"class":533},[523,2091,544],{"class":529},[523,2093,547],{"class":533},[523,2095,2096],{"class":550},".\u002Frequest-log.middleware",[523,2098,554],{"class":533},[523,2100,557],{"class":533},[523,2102,2103,2105,2107,2109,2111,2113,2115,2117,2119],{"class":525,"line":583},[523,2104,530],{"class":529},[523,2106,534],{"class":533},[523,2108,624],{"class":537},[523,2110,541],{"class":533},[523,2112,544],{"class":529},[523,2114,547],{"class":533},[523,2116,1991],{"class":550},[523,2118,554],{"class":533},[523,2120,557],{"class":533},[523,2122,2123],{"class":525,"line":606},[523,2124,610],{"emptyLinePlaceholder":609},[523,2126,2127,2129,2131,2133,2135,2137,2139],{"class":525,"line":613},[523,2128,616],{"class":529},[523,2130,620],{"class":619},[523,2132,2008],{"class":623},[523,2134,627],{"class":619},[523,2136,538],{"class":630},[523,2138,633],{"class":537},[523,2140,636],{"class":533},[523,2142,2143,2145,2147,2150],{"class":525,"line":639},[523,2144,1431],{"class":642},[523,2146,646],{"class":533},[523,2148,2149],{"class":537}," [UsersModule]",[523,2151,652],{"class":533},[523,2153,2154,2156,2158,2160,2163,2165,2168,2171],{"class":525,"line":655},[523,2155,658],{"class":642},[523,2157,646],{"class":533},[523,2159,534],{"class":533},[523,2161,2162],{"class":642}," middlewares",[523,2164,646],{"class":533},[523,2166,2167],{"class":537}," [RequestLogMiddleware] ",[523,2169,2170],{"class":533},"},",[523,2172,2173],{"class":786}," \u002F\u002F wraps every route under UsersModule\n",[523,2175,2176,2178,2180],{"class":525,"line":676},[523,2177,691],{"class":533},[523,2179,694],{"class":537},[523,2181,697],{"class":533},[702,2183,2185],{"id":2184},"how-a-module-becomes-wiring","How a module becomes wiring",[499,2187,2188,2189,2192,2193,1100,2195,652,2197,2199],{},"A module config is a ",[1165,2190,2191],{},"declaration",", not code that runs. Heximon reads the ",[503,2194,1160],{},[503,2196,710],{},[503,2198,1175],{},", and feature keys directly from your source to build the dependency graph — it never executes\nthe module to discover what's inside. Two consequences follow, and both are deliberate.",[499,2201,2202,2203,2206,2207,2209],{},"First, those arrays must be ",[1165,2204,2205],{},"literal"," in the source — no conditionally assembled ",[503,2208,1160],{},", no\ncomputed provider lists. That's what lets the wiring be settled before your app starts, so there's no\ncontainer resolving the graph at runtime and nothing to warm up on boot.",[499,2211,2212,2213,2216,2217,2220,2221,2224],{},"Second, a class is only recognized by being ",[1165,2214,2215],{},"listed"," under the right key — a controller because it\nsits in ",[503,2218,2219],{},"http: { controllers }",", an event handler because it sits in ",[503,2222,2223],{},"events: { handlers }",". There's no\nwhole-codebase scan and no ambient magic: every part of your app is something a module explicitly named.\nWhen you want to know what a feature contains, you read its module — the list is the truth.",[702,2226,2228],{"id":2227},"what-the-editor-catches-and-what-stays-build-time","What the editor catches, and what stays build-time",[499,2230,2231,2233,2234,2236,2237,2240,2241,2243,2244,845,2247,2249,2250,2253],{},[503,2232,1220],{},"'s generic typing is an authoring aid that runs entirely in your editor, before the compiler\never sees your code. As you type, it catches: a constructor dependency (in ",[503,2235,710],{},", in a namespace\nconcept class, or in a ",[503,2238,2239],{},"useFactory","'s parameters) that nothing visible provides; an ",[503,2242,1175],{}," entry nothing\nbacks; a ",[503,2245,2246],{},"useValue",[503,2248,2239],{}," result that needs ",[503,2251,2252],{},"eager: true"," and doesn't have it; a misspelled top-level\nkey.",[499,2255,2256,2257,2259],{},"It also catches the ",[503,2258,1185],{}," propagation rule above — an imported module's unmet requirement.",[499,2261,2262,2263,2265,2266,2269],{},"The compiler enforces the propagation rule too (",[503,2264,1895],{}," per dropped hop,\n",[503,2267,2268],{},"app.unmet-requires"," for a root's own leftovers), so a hop the editor misses still fails the build.",[499,2271,2272],{},"A few things are deliberately left to the build-time compiler, which remains the real source of truth for\nthe DI graph:",[2274,2275,2276,2298,2304,2318],"ul",{},[2277,2278,2279,2282,2283,2286,2287,2290,2291,1885,2294,2297],"li",{},[1165,2280,2281],{},"Ambiguity and cycles."," The editor check is existential — it only asks \"is ",[508,2284,2285],{},"some"," visible provider a\nmatch?\", so it can't notice that ",[508,2288,2289],{},"two"," providers satisfy the same token, or that two modules import each\nother. The compiler's ",[503,2292,2293],{},"DiagnosticCode.AmbiguousProviders",[503,2295,2296],{},"DependencyCycle"," diagnostics catch those.",[2277,2299,2300,2303],{},[1165,2301,2302],{},"Union-typed constructor parameters."," A parameter typed as a union of classes is rejected by the editor\ncheck outright, rather than partially validated — the compiler's own resolution is the real check there.",[2277,2305,2306,2309,2310,2313,2314,2317],{},[1165,2307,2308],{},"Factory-form module imports."," Importing a parameterized module instance (",[503,2311,2312],{},"new FeatureModule(config)",")\nneutralizes the editor's dependency and export checks for ",[508,2315,2316],{},"that one import"," — the compiler still validates\nit at build time.",[2277,2319,2320,2323,2324,2327],{},[1165,2321,2322],{},"Marker tokens with no fields."," An empty class used purely as a DI marker structurally matches any\nvisible instance in the editor's eyes; the compiler's ",[503,2325,2326],{},"NoProvider"," diagnostic is the real backstop until\nthe token carries at least one member.",[499,2329,2330,2331,2334,2335,2338],{},"None of these are silent in the end — every one still fails the build (",[503,2332,2333],{},"pnpm check"," \u002F ",[503,2336,2337],{},"vp dev"," \u002F CI) if it's\nwrong. The editor check just narrows how early you find out.",[2340,2341,2343],"h3",{"id":2342},"compiled-verdicts-come-back-into-the-editor","Compiled verdicts come back into the editor",[499,2345,2346,2347,2334,2349,2352],{},"The build-time-only list above shrinks in practice: every compile (",[503,2348,2337],{},[503,2350,2351],{},"vp build",") also writes a\ngenerated declaration file that mirrors the compiler's error verdicts back to their natural user-code\nsites.",[499,2354,2355,2356,2363,2364,2366],{},"A module whose last compile found a defect — an ambiguity, a transitive no-provider, an unmet root\nrequirement — gets the verdict reported ",[1165,2357,2358,2359,2362],{},"at its own ",[503,2360,2361],{},"class"," declaration","; a dirty precompiled module gets\nit at the ",[503,2365,1160],{}," entry that pulls it in.",[499,2368,2369,2370,2373,2374,2377],{},"The same file brands every detected marker token with an optional ",[503,2371,2372],{},"heximonToken"," member, closing the\nstructural-match hole for tokens the compiler has seen. The file is additive-only and gracefully absent: on\na fresh clone (before the first compile) nothing fires, and a compile after a fix rewrites it clean. The\nfirst compile adds the generated-directory include entry to your ",[503,2375,2376],{},"tsconfig.json"," for you.",[702,2379,2381],{"id":2380},"advanced-provider-forms","Advanced provider forms",[499,2383,2384,2385,2388],{},"A bare class provider covers most of an app. Reach for the ",[503,2386,2387],{},"{ provide, use* }"," form when the token and\nthe implementation should differ — an abstract base bound to a concrete class, a value computed at boot,\nan existing instance reused:",[1125,2390,2391,2401],{},[1128,2392,2393],{},[1131,2394,2395,2398],{},[1134,2396,2397],{"align":1136},"Form",[1134,2399,2400],{"align":1136},"When to use",[1142,2402,2403,2411,2421,2430,2439],{},[1131,2404,2405,2408],{},[1147,2406,2407],{"align":1136},"Bare class",[1147,2409,2410],{"align":1136},"The class is its own token and Heximon can read its constructor.",[1131,2412,2413,2418],{},[1147,2414,2415],{"align":1136},[503,2416,2417],{},"useClass",[1147,2419,2420],{"align":1136},"Bind an abstract token to a concrete, swappable implementation.",[1131,2422,2423,2427],{},[1147,2424,2425],{"align":1136},[503,2426,2239],{},[1147,2428,2429],{"align":1136},"The constructor isn't Heximon-visible, or you need async or explicit build logic.",[1131,2431,2432,2436],{},[1147,2433,2434],{"align":1136},[503,2435,2246],{},[1147,2437,2438],{"align":1136},"Supply a pre-built value — a config object, a shared instance.",[1131,2440,2441,2446],{},[1147,2442,2443],{"align":1136},[503,2444,2445],{},"useExisting",[1147,2447,2448],{"align":1136},"Alias one token to another provider's instance, with no second construction.",[499,2450,2451,2454],{},[1165,2452,2453],{},"Bind an abstract token to a concrete class"," — the repository pattern: the abstract base is the stable\nseam your service depends on, and the concrete class is swappable per environment (an in-memory store in\ntests, Drizzle in production) without touching a consumer.",[513,2456,2458],{"className":515,"code":2457,"filename":517,"language":518,"meta":519,"style":519},"providers: [{ provide: UsersRepository, useClass: DrizzleUsersRepository }]\n",[503,2459,2460],{"__ignoreMap":519},[523,2461,2462,2464,2466,2468,2471,2474,2476,2478,2480,2483,2485,2488,2490],{"class":525,"line":526},[523,2463,710],{"class":623},[523,2465,646],{"class":533},[523,2467,859],{"class":537},[523,2469,2470],{"class":533},"{",[523,2472,2473],{"class":642}," provide",[523,2475,646],{"class":533},[523,2477,590],{"class":537},[523,2479,732],{"class":533},[523,2481,2482],{"class":642}," useClass",[523,2484,646],{"class":533},[523,2486,2487],{"class":537}," DrizzleUsersRepository ",[523,2489,691],{"class":533},[523,2491,2492],{"class":537},"]\n",[513,2494,2497],{"className":515,"code":2495,"filename":2496,"language":518,"meta":519,"style":519},"export class UsersService {\n  \u002F\u002F typed as the abstract UsersRepository; gets DrizzleUsersRepository at runtime\n  public constructor(private readonly users: UsersRepository) {}\n}\n","src\u002Fusers\u002Fusers.service.ts",[503,2498,2499,2510,2515,2538],{"__ignoreMap":519},[523,2500,2501,2503,2505,2508],{"class":525,"line":526},[523,2502,616],{"class":529},[523,2504,620],{"class":619},[523,2506,2507],{"class":623}," UsersService",[523,2509,781],{"class":533},[523,2511,2512],{"class":525,"line":560},[523,2513,2514],{"class":786},"  \u002F\u002F typed as the abstract UsersRepository; gets DrizzleUsersRepository at runtime\n",[523,2516,2517,2519,2522,2524,2526,2528,2530,2532,2534,2536],{"class":525,"line":583},[523,2518,823],{"class":619},[523,2520,2521],{"class":619}," constructor",[523,2523,633],{"class":533},[523,2525,797],{"class":619},[523,2527,800],{"class":619},[523,2529,804],{"class":803},[523,2531,646],{"class":533},[523,2533,590],{"class":623},[523,2535,811],{"class":533},[523,2537,814],{"class":533},[523,2539,2540],{"class":525,"line":606},[523,2541,920],{"class":533},[499,2543,2544,2545,845,2548,2551,2552,2555],{},"Satisfaction follows the provider's whole ",[503,2546,2547],{},"extends",[503,2549,2550],{},"implements"," chain — including a chain that lives\nentirely inside an installed package, read from its shipped type declarations. Two bindings reaching the\nsame base are an ",[503,2553,2554],{},"AmbiguousProviders"," build error, never a silent pick.",[499,2557,2558,2561,2562,2565,2566,2569,2570,2573,2574,1885,2576,2579,2580,2583,2584,2587,2588,2591,2592,901],{},[1165,2559,2560],{},"Generic tokens need a named subclass."," Class identity is the only token, and ",[1165,2563,2564],{},"type arguments are\nerased for resolution"," — a parameter typed ",[503,2567,2568],{},"Repository\u003CUser>"," resolves the bare ",[503,2571,2572],{},"Repository"," identity,\nso ",[503,2575,2568],{},[503,2577,2578],{},"Repository\u003COrder>"," are the ",[508,2581,2582],{},"same"," token, and injecting a parameterized generic\nbase is a compile error. Bind a specific parameterization by subclassing the generic base into a named\nconcrete token and injecting that instead — the same pitfall shows up with ",[503,2585,2586],{},"@heximon\u002Fdrizzle","'s generic\n",[503,2589,2590],{},"DrizzleLibSQLConfig",", worked through in full on ",[1200,2593,416],{"href":417},[499,2595,2596,2598,2599,2602,2603,2606,2607,2609,2610,2613,2614,2616,2617,901],{},[503,2597,2239],{},"'s ",[1165,2600,2601],{},"parameter types are its dependency declaration",", exactly like a constructor, so there's\nno separate ",[503,2604,2605],{},"inject"," array; a factory result and a ",[503,2608,2246],{}," value are ",[1165,2611,2612],{},"opaque"," to the compiler, so\neager-boot work on either needs an explicit ",[503,2615,2252],{}," flag — see\n",[1200,2618,2619],{"href":127},"Application Lifecycle",[499,2621,2622,2624,2625,2628],{},[503,2623,2445],{}," aliases a second token to an already-provided instance with no second construction, and an\narray ",[503,2626,2627],{},"provide"," collapses several aliases of the same provider into one entry.",[499,2630,2631,2634,2635,2637,2638,2641,2642,2645,2646,2648,2649,2651,2652,901],{},[1165,2632,2633],{},"Configure a module at its import site."," Most modules build their dependencies from a fixed config\nvalue and never need a parameter. When the ",[1165,2636,2582],{}," module must be imported with different values in\ndifferent places, use the factory form — ",[503,2639,2640],{},"Module((config) => ({...}))"," — and thread the supplied\n",[503,2643,2644],{},"config"," into a ",[503,2647,2246],{}," or ",[503,2650,2239],{}," provider, configured per import with ",[503,2653,2654],{},"new SomeModule(config)",[1901,2656,2657,2658,2660],{"type":1903},"Reach for the factory form only when a module genuinely needs different values per import. If a feature\njust reads one app-wide config, a plain module with a ",[503,2659,2239],{}," over an imported config value is the\nsimpler idiom — and the one most apps stay on.",[499,2662,2663,2666,2667,2670,2671,2674,2675,2677,2678,845,2680,2682],{},[1165,2664,2665],{},"Swap a provider in a test"," with ",[503,2668,2669],{},"createTestApp({ overrides })",", keyed by the class-identity token — an\noverride replaces a DI token everywhere it is injected, from same-module construction to ",[503,2672,2673],{},"app.get(Token)",".\nSee ",[1200,2676,1202],{"href":112}," for the full harness, including the one real limit: a precompiled\npackage is overridable only at its declared ",[503,2679,1185],{},[503,2681,1175],{}," seams, never its internals.",[499,2684,2685,2686,2688,2689,2691,2692,901],{},"For multi-dependency factories, the generic-token pitfall worked through end to end, ",[503,2687,2445],{},"\u002Farray\n",[503,2690,2627],{}," with real fences, the factory-form module in full, and overriding the error envelope, see\n",[1200,2693,416],{"href":417},[702,2695,2697],{"id":2696},"see-also","See also",[2274,2699,2700,2716,2724,2732,2743,2753],{},[2277,2701,2702,2704,2705,2708,2709,2334,2712,2715],{},[1200,2703,2619],{"href":127}," — ",[503,2706,2707],{},"createApp",", the app handle, and the\n",[503,2710,2711],{},"onInit",[503,2713,2714],{},"onShutdown"," hooks Heximon weaves into the wiring.",[2277,2717,2718,2720,2721,2723],{},[1200,2719,57],{"href":58}," — what goes under the ",[503,2722,1093],{}," key, and the two ways to\ndeclare routes.",[2277,2725,2726,2704,2728,2731],{},[1200,2727,1202],{"href":112},[503,2729,2730],{},"createTestApp",", overrides, and the full test harness.",[2277,2733,2734,2742],{},[1200,2735,2739],{"href":2736,"rel":2737},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL01-minimal",[2738],"nofollow",[1165,2740,2741],{},"Example L01 — minimal"," — one\nfeature module plus a root module with app-wide middleware, the smallest complete app.",[2277,2744,2745,2752],{},[1200,2746,2749],{"href":2747,"rel":2748},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL02-http-validation",[2738],[1165,2750,2751],{},"Example L02 — HTTP validation","\n— two feature modules composed by a root module, each owning its own providers and controller.",[2277,2754,2755,2762,2763,2765],{},[1200,2756,2759],{"href":2757,"rel":2758},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL07-auth",[2738],[1165,2760,2761],{},"Example L07 — auth","\n— async ",[503,2764,2239],{}," providers that generate a signing key pair at boot and split it across a signer\nand a verifier.",[2767,2768,2769],"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 .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 .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 .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}",{"title":519,"searchDepth":560,"depth":560,"links":2771},[2772,2773,2774,2776,2777,2778,2781,2782],{"id":704,"depth":560,"text":705},{"id":1229,"depth":560,"text":1230},{"id":1488,"depth":560,"text":2775},"Declare what you expect the host to supply: requires",{"id":1919,"depth":560,"text":1920},{"id":2184,"depth":560,"text":2185},{"id":2227,"depth":560,"text":2228,"children":2779},[2780],{"id":2342,"depth":583,"text":2343},{"id":2380,"depth":560,"text":2381},{"id":2696,"depth":560,"text":2697},"Group a feature with Module(...), wire providers with constructor injection, share them via imports and exports, and let the editor catch a broken DI graph before you build.","md",null,{},{"icon":48},{"title":53,"description":2783},"RMcjoj2TM7dvCM_EdNnPgmE1g5nLUxJlq62thWWSCUA",[2791,2793],{"title":41,"path":42,"stem":43,"description":2792,"icon":44,"children":-1},"Fixes for the common first-run issues — missing routes, unresolved dependencies, validation 400s, a hanging middleware, a failed build after an edit — plus deeper diagnostics for contracts, scopes, and context.",{"title":57,"path":58,"stem":59,"description":2794,"icon":60,"children":-1},"Build the HTTP surface with Controllers — routes declared by the handler's action parameter type, the HttpAction dispatcher, middleware, error filters, and contract binding.",1783300761903]