[{"data":1,"prerenderedAt":3467},["ShallowReactive",2],{"navigation_docs":3,"-docs-under-the-hood-advanced-di":493,"-docs-under-the-hood-advanced-di-surround":3462},[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":416,"body":495,"description":3455,"extension":3456,"links":3457,"meta":3458,"navigation":3459,"path":417,"seo":3460,"stem":418,"__hash__":3461},"docs\u002Fdocs\u002F08.under-the-hood\u002F08.advanced-di.md",{"type":496,"value":497,"toc":3439},"minimark",[498,514,519,546,975,1019,1024,1027,1182,1197,1205,1216,1238,1245,1254,1399,1441,1447,1452,1506,1519,1526,1562,1780,1819,1823,1840,2060,2174,2198,2207,2211,2229,2416,2453,2457,2481,2491,2691,2708,2819,2998,3012,3016,3049,3353,3363,3380,3384,3435],[499,500,501,504,505,509,510,513],"p",{},[502,503,53],"a",{"href":54}," covers the provider forms every app reaches for — bare\nclasses, ",[506,507,508],"code",{},"useClass",", a single-dependency ",[506,511,512],{},"useFactory",". This page is the full depth behind that survey: how\nproviding one concrete class can satisfy an abstract token with no alias in sight, how to route several\nabstract tokens to one provider, how to alias one provider under a second name, why a generic class can't\nbe a DI token, and how to reshape the error envelope every response renders through. None of this is\nexotic — it's the mechanics the framework itself uses once your app grows past its first few modules.",[515,516,518],"h2",{"id":517},"a-provider-satisfies-its-abstract-base-no-alias-needed","A provider satisfies its abstract base, no alias needed",[499,520,521,522,525,526,530,531,534,535,537,538,541,542,545],{},"Class identity is the only DI token, but that doesn't mean every consumer has to ask for the exact\nconcrete class a module provides. When a constructor parameter or an ",[506,523,524],{},"exports"," entry is typed by an\n",[527,528,529],"strong",{},"abstract"," base that no provider names as its own ",[506,532,533],{},"provide"," token, the compiler looks for the one\nprovider in scope whose token — or ",[506,536,508],{}," implementation — ",[506,539,540],{},"extends"," or ",[506,543,544],{},"implements"," that base\nanywhere up its chain, and binds it there.",[547,548,554],"pre",{"className":549,"code":550,"filename":551,"language":552,"meta":553,"style":553},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export class AuthModule extends Module({\n  providers: [\n    UserAccountStore,\n    { provide: PasswordHashingAlgorithm, useClass: Scrypt },\n    JWTAuthMiddleware,\n    {\n      provide: IdentityKeyPair,\n      useFactory: (): Promise\u003CIdentityKeyPair> => IdentityKeyPair.resolve(),\n    },\n    {\n      provide: JWTFactory,\n      useFactory: (keys: IdentityKeyPair): JWTFactory => new JWTFactory(keys.privateKey),\n    },\n    {\n      provide: AuthContext,\n      useFactory: (context: Context, verifier: JWTVerifier): AuthContext =>\n        new AuthContext(context, verifier, new CookieTokenSource(\"accessToken\")),\n    },\n  ],\n  http: { controllers: [AuthController, JwksController] },\n  exports: [\n    AuthContext,\n    JWTAuthMiddleware,\n    JWTVerifier,\n    JWTFactory,\n    UserAccountStore,\n    PasswordHashingAlgorithm,\n  ],\n}) {}\n","examples\u002Fladder\u002FL07-auth\u002Fsrc\u002Fauth\u002Fauth.module.ts (excerpt)","ts","",[506,555,556,588,601,610,638,646,652,665,704,710,715,727,767,772,777,789,823,861,866,874,900,910,918,925,933,941,948,956,963],{"__ignoreMap":553},[557,558,561,565,569,573,576,580,584],"span",{"class":559,"line":560},"line",1,[557,562,564],{"class":563},"s7zQu","export",[557,566,568],{"class":567},"spNyl"," class",[557,570,572],{"class":571},"sBMFI"," AuthModule",[557,574,575],{"class":567}," extends",[557,577,579],{"class":578},"s2Zo4"," Module",[557,581,583],{"class":582},"sTEyZ","(",[557,585,587],{"class":586},"sMK4o","{\n",[557,589,591,595,598],{"class":559,"line":590},2,[557,592,594],{"class":593},"swJcz","  providers",[557,596,597],{"class":586},":",[557,599,600],{"class":582}," [\n",[557,602,604,607],{"class":559,"line":603},3,[557,605,606],{"class":582},"    UserAccountStore",[557,608,609],{"class":586},",\n",[557,611,613,616,619,621,624,627,630,632,635],{"class":559,"line":612},4,[557,614,615],{"class":586},"    {",[557,617,618],{"class":593}," provide",[557,620,597],{"class":586},[557,622,623],{"class":582}," PasswordHashingAlgorithm",[557,625,626],{"class":586},",",[557,628,629],{"class":593}," useClass",[557,631,597],{"class":586},[557,633,634],{"class":582}," Scrypt ",[557,636,637],{"class":586},"},\n",[557,639,641,644],{"class":559,"line":640},5,[557,642,643],{"class":582},"    JWTAuthMiddleware",[557,645,609],{"class":586},[557,647,649],{"class":559,"line":648},6,[557,650,651],{"class":586},"    {\n",[557,653,655,658,660,663],{"class":559,"line":654},7,[557,656,657],{"class":593},"      provide",[557,659,597],{"class":586},[557,661,662],{"class":582}," IdentityKeyPair",[557,664,609],{"class":586},[557,666,668,671,673,676,679,682,685,688,691,693,696,699,702],{"class":559,"line":667},8,[557,669,670],{"class":578},"      useFactory",[557,672,597],{"class":586},[557,674,675],{"class":586}," ():",[557,677,678],{"class":571}," Promise",[557,680,681],{"class":586},"\u003C",[557,683,684],{"class":571},"IdentityKeyPair",[557,686,687],{"class":586},">",[557,689,690],{"class":567}," =>",[557,692,662],{"class":582},[557,694,695],{"class":586},".",[557,697,698],{"class":578},"resolve",[557,700,701],{"class":582},"()",[557,703,609],{"class":586},[557,705,707],{"class":559,"line":706},9,[557,708,709],{"class":586},"    },\n",[557,711,713],{"class":559,"line":712},10,[557,714,651],{"class":586},[557,716,718,720,722,725],{"class":559,"line":717},11,[557,719,657],{"class":593},[557,721,597],{"class":586},[557,723,724],{"class":582}," JWTFactory",[557,726,609],{"class":586},[557,728,730,732,734,737,741,743,745,748,750,752,755,757,760,762,765],{"class":559,"line":729},12,[557,731,670],{"class":578},[557,733,597],{"class":586},[557,735,736],{"class":586}," (",[557,738,740],{"class":739},"sHdIc","keys",[557,742,597],{"class":586},[557,744,662],{"class":571},[557,746,747],{"class":586},"):",[557,749,724],{"class":571},[557,751,690],{"class":567},[557,753,754],{"class":586}," new",[557,756,724],{"class":578},[557,758,759],{"class":582},"(keys",[557,761,695],{"class":586},[557,763,764],{"class":582},"privateKey)",[557,766,609],{"class":586},[557,768,770],{"class":559,"line":769},13,[557,771,709],{"class":586},[557,773,775],{"class":559,"line":774},14,[557,776,651],{"class":586},[557,778,780,782,784,787],{"class":559,"line":779},15,[557,781,657],{"class":593},[557,783,597],{"class":586},[557,785,786],{"class":582}," AuthContext",[557,788,609],{"class":586},[557,790,792,794,796,798,801,803,806,808,811,813,816,818,820],{"class":559,"line":791},16,[557,793,670],{"class":578},[557,795,597],{"class":586},[557,797,736],{"class":586},[557,799,800],{"class":739},"context",[557,802,597],{"class":586},[557,804,805],{"class":571}," Context",[557,807,626],{"class":586},[557,809,810],{"class":739}," verifier",[557,812,597],{"class":586},[557,814,815],{"class":571}," JWTVerifier",[557,817,747],{"class":586},[557,819,786],{"class":571},[557,821,822],{"class":567}," =>\n",[557,824,826,829,831,834,836,838,840,842,845,847,850,854,856,859],{"class":559,"line":825},17,[557,827,828],{"class":586},"        new",[557,830,786],{"class":578},[557,832,833],{"class":582},"(context",[557,835,626],{"class":586},[557,837,810],{"class":582},[557,839,626],{"class":586},[557,841,754],{"class":586},[557,843,844],{"class":578}," CookieTokenSource",[557,846,583],{"class":582},[557,848,849],{"class":586},"\"",[557,851,853],{"class":852},"sfazB","accessToken",[557,855,849],{"class":586},[557,857,858],{"class":582},"))",[557,860,609],{"class":586},[557,862,864],{"class":559,"line":863},18,[557,865,709],{"class":586},[557,867,869,872],{"class":559,"line":868},19,[557,870,871],{"class":582},"  ]",[557,873,609],{"class":586},[557,875,877,880,882,885,888,890,893,895,898],{"class":559,"line":876},20,[557,878,879],{"class":593},"  http",[557,881,597],{"class":586},[557,883,884],{"class":586}," {",[557,886,887],{"class":593}," controllers",[557,889,597],{"class":586},[557,891,892],{"class":582}," [AuthController",[557,894,626],{"class":586},[557,896,897],{"class":582}," JwksController] ",[557,899,637],{"class":586},[557,901,903,906,908],{"class":559,"line":902},21,[557,904,905],{"class":593},"  exports",[557,907,597],{"class":586},[557,909,600],{"class":582},[557,911,913,916],{"class":559,"line":912},22,[557,914,915],{"class":582},"    AuthContext",[557,917,609],{"class":586},[557,919,921,923],{"class":559,"line":920},23,[557,922,643],{"class":582},[557,924,609],{"class":586},[557,926,928,931],{"class":559,"line":927},24,[557,929,930],{"class":582},"    JWTVerifier",[557,932,609],{"class":586},[557,934,936,939],{"class":559,"line":935},25,[557,937,938],{"class":582},"    JWTFactory",[557,940,609],{"class":586},[557,942,944,946],{"class":559,"line":943},26,[557,945,606],{"class":582},[557,947,609],{"class":586},[557,949,951,954],{"class":559,"line":950},27,[557,952,953],{"class":582},"    PasswordHashingAlgorithm",[557,955,609],{"class":586},[557,957,959,961],{"class":559,"line":958},28,[557,960,871],{"class":582},[557,962,609],{"class":586},[557,964,966,969,972],{"class":559,"line":965},29,[557,967,968],{"class":586},"}",[557,970,971],{"class":582},") ",[557,973,974],{"class":586},"{}\n",[499,976,977,978,981,982,984,985,988,989,992,993,995,996,999,1000,1003,1004,1006,1007,1009,1010,1014,1015,1018],{},"No provider here names ",[506,979,980],{},"JWTVerifier"," as its ",[506,983,533],{}," token. ",[506,986,987],{},"JWTFactory extends JWTVerifier"," — it\nverifies with the same key it signs with — so the one ",[506,990,991],{},"JWTFactory"," instance this module constructs is\nalso the provider that satisfies ",[506,994,980],{},": the ",[506,997,998],{},"AuthContext"," factory's ",[506,1001,1002],{},"verifier: JWTVerifier","\nparameter above resolves to it, and the bare ",[506,1005,980],{}," entry in ",[506,1008,524],{}," re-exports that same\ninstance for another module to inject. This nominal-satisfier walk crosses a package boundary too — a\nprovider your app lists can satisfy an abstract token a ",[1011,1012,1013],"em",{},"different"," package's shipped ",[506,1016,1017],{},".d.ts"," declares, as\nlong as its heritage chain reaches it.",[1020,1021,1023],"h3",{"id":1022},"two-satisfiers-is-a-build-error-not-a-guess","Two satisfiers is a build error, not a guess",[499,1025,1026],{},"Exactly one satisfier binds silently. When two providers in scope both nominally satisfy the same abstract\ntoken, the compiler refuses to guess which one you meant:",[547,1028,1031],{"className":549,"code":1029,"filename":1030,"language":552,"meta":553,"style":553},"export abstract class AthleteRepository {\n  abstract find(id: string): Promise\u003Cunknown>;\n}\n\nexport class MemoryAthleteRepository extends AthleteRepository {\n  async find(id) { return null; }\n}\n\nexport class MySQL2AthleteRepository extends DrizzleBase implements AthleteRepository {\n  async find(id) { return null; }\n}\n","packages\u002Fkernel\u002Fruntime\u002Ftest\u002Fcompile.test.ts (fixture, trimmed)",[506,1032,1033,1048,1078,1083,1089,1104,1129,1133,1137,1158,1178],{"__ignoreMap":553},[557,1034,1035,1037,1040,1042,1045],{"class":559,"line":560},[557,1036,564],{"class":563},[557,1038,1039],{"class":567}," abstract",[557,1041,568],{"class":567},[557,1043,1044],{"class":571}," AthleteRepository",[557,1046,1047],{"class":586}," {\n",[557,1049,1050,1053,1056,1058,1061,1063,1066,1068,1070,1072,1075],{"class":559,"line":590},[557,1051,1052],{"class":567},"  abstract",[557,1054,1055],{"class":593}," find",[557,1057,583],{"class":586},[557,1059,1060],{"class":739},"id",[557,1062,597],{"class":586},[557,1064,1065],{"class":571}," string",[557,1067,747],{"class":586},[557,1069,678],{"class":571},[557,1071,681],{"class":586},[557,1073,1074],{"class":571},"unknown",[557,1076,1077],{"class":586},">;\n",[557,1079,1080],{"class":559,"line":603},[557,1081,1082],{"class":586},"}\n",[557,1084,1085],{"class":559,"line":612},[557,1086,1088],{"emptyLinePlaceholder":1087},true,"\n",[557,1090,1091,1093,1095,1098,1100,1102],{"class":559,"line":640},[557,1092,564],{"class":563},[557,1094,568],{"class":567},[557,1096,1097],{"class":571}," MemoryAthleteRepository",[557,1099,575],{"class":567},[557,1101,1044],{"class":571},[557,1103,1047],{"class":586},[557,1105,1106,1109,1111,1113,1115,1118,1120,1123,1126],{"class":559,"line":648},[557,1107,1108],{"class":567},"  async",[557,1110,1055],{"class":593},[557,1112,583],{"class":586},[557,1114,1060],{"class":739},[557,1116,1117],{"class":586},")",[557,1119,884],{"class":586},[557,1121,1122],{"class":563}," return",[557,1124,1125],{"class":586}," null;",[557,1127,1128],{"class":586}," }\n",[557,1130,1131],{"class":559,"line":654},[557,1132,1082],{"class":586},[557,1134,1135],{"class":559,"line":667},[557,1136,1088],{"emptyLinePlaceholder":1087},[557,1138,1139,1141,1143,1146,1148,1151,1154,1156],{"class":559,"line":706},[557,1140,564],{"class":563},[557,1142,568],{"class":567},[557,1144,1145],{"class":571}," MySQL2AthleteRepository",[557,1147,575],{"class":567},[557,1149,1150],{"class":571}," DrizzleBase",[557,1152,1153],{"class":567}," implements",[557,1155,1044],{"class":571},[557,1157,1047],{"class":586},[557,1159,1160,1162,1164,1166,1168,1170,1172,1174,1176],{"class":559,"line":712},[557,1161,1108],{"class":567},[557,1163,1055],{"class":593},[557,1165,583],{"class":586},[557,1167,1060],{"class":739},[557,1169,1117],{"class":586},[557,1171,884],{"class":586},[557,1173,1122],{"class":563},[557,1175,1125],{"class":586},[557,1177,1128],{"class":586},[557,1179,1180],{"class":559,"line":717},[557,1181,1082],{"class":586},[499,1183,1184,1185,1188,1189,1192,1193,1196],{},"Listing both ",[506,1186,1187],{},"MemoryAthleteRepository"," and ",[506,1190,1191],{},"MySQL2AthleteRepository"," as bare providers in one module —\nneither is named ",[506,1194,1195],{},"AthleteRepository",", but both reach it — fails the build:",[547,1198,1203],{"className":1199,"code":1201,"language":1202,"meta":553},[1200],"language-text","error [resolve\u002Fambiguous-providers]  AthleteService: ambiguous providers satisfying 'AthleteRepository'\n(MemoryAthleteRepository, MySQL2AthleteRepository)\n  ╰─ help: disambiguate with useClass\u002FuseExisting or narrow the scope.\n","text",[506,1204,1201],{"__ignoreMap":553},[499,1206,1207,1208,1211,1212,1215],{},"Disambiguate with an exact binding — ",[506,1209,1210],{},"{ provide: AthleteRepository, useClass: MySQL2AthleteRepository }","\n(or ",[506,1213,1214],{},"useExisting",") — naming the one you want.",[499,1217,1218,1219,1222,1223,1226,1227,1229,1230,1233,1234,1237],{},"That exact binding wins for a reason worth remembering: a ",[506,1220,1221],{},"{ provide: Token, use… }"," entry for a token's\nown precise identity is always checked ",[527,1224,1225],{},"before"," the compiler starts the nominal-satisfier walk, so\nbinding the abstract identity once is also how you break a tie the walk can't resolve on its own. This\nordering is why the transactional outbox's relay in\n",[502,1228,243],{"href":244}," can type its dependency by the abstract\n",[506,1231,1232],{},"IntegrationEventTransport"," token and simply let an exact ",[506,1235,1236],{},"{ provide: IntegrationEventTransport, useFactory: … }"," binding resolve it, with no bare-listed satisfier around to disambiguate from.",[515,1239,1241,1242,1244],{"id":1240},"array-provide-alias-several-tokens-at-once","Array ",[506,1243,533],{},": alias several tokens at once",[499,1246,1247,1248,1250,1251,1253],{},"When a composition root must route several abstract tokens to the same provider, an array ",[506,1249,533],{},"\ncollapses what would otherwise be repeated ",[506,1252,1214],{}," lines into one entry. The compiler desugars it at\nparse time, so the implementation is still constructed exactly once no matter how many tokens alias it:",[547,1255,1258],{"className":549,"code":1256,"filename":1257,"language":552,"meta":553,"style":553},"export class ArrayProvideModule extends Module({\n  providers: [\n    TargetService,\n    { provide: [AlphaService, BetaToken, GammaToken], useClass: AlphaService },\n    { provide: [DeltaToken, EpsilonToken], useExisting: TargetService },\n  ],\n  exports: [AlphaService, BetaToken, GammaToken, TargetService, DeltaToken, EpsilonToken],\n}) {}\n","packages\u002Fkernel\u002Fruntime\u002Ftest\u002Ffixtures\u002Farray-provide\u002Farray-provide.module.ts",[506,1259,1260,1277,1285,1292,1324,1352,1358,1391],{"__ignoreMap":553},[557,1261,1262,1264,1266,1269,1271,1273,1275],{"class":559,"line":560},[557,1263,564],{"class":563},[557,1265,568],{"class":567},[557,1267,1268],{"class":571}," ArrayProvideModule",[557,1270,575],{"class":567},[557,1272,579],{"class":578},[557,1274,583],{"class":582},[557,1276,587],{"class":586},[557,1278,1279,1281,1283],{"class":559,"line":590},[557,1280,594],{"class":593},[557,1282,597],{"class":586},[557,1284,600],{"class":582},[557,1286,1287,1290],{"class":559,"line":603},[557,1288,1289],{"class":582},"    TargetService",[557,1291,609],{"class":586},[557,1293,1294,1296,1298,1300,1303,1305,1308,1310,1313,1315,1317,1319,1322],{"class":559,"line":612},[557,1295,615],{"class":586},[557,1297,618],{"class":593},[557,1299,597],{"class":586},[557,1301,1302],{"class":582}," [AlphaService",[557,1304,626],{"class":586},[557,1306,1307],{"class":582}," BetaToken",[557,1309,626],{"class":586},[557,1311,1312],{"class":582}," GammaToken]",[557,1314,626],{"class":586},[557,1316,629],{"class":593},[557,1318,597],{"class":586},[557,1320,1321],{"class":582}," AlphaService ",[557,1323,637],{"class":586},[557,1325,1326,1328,1330,1332,1335,1337,1340,1342,1345,1347,1350],{"class":559,"line":640},[557,1327,615],{"class":586},[557,1329,618],{"class":593},[557,1331,597],{"class":586},[557,1333,1334],{"class":582}," [DeltaToken",[557,1336,626],{"class":586},[557,1338,1339],{"class":582}," EpsilonToken]",[557,1341,626],{"class":586},[557,1343,1344],{"class":593}," useExisting",[557,1346,597],{"class":586},[557,1348,1349],{"class":582}," TargetService ",[557,1351,637],{"class":586},[557,1353,1354,1356],{"class":559,"line":648},[557,1355,871],{"class":582},[557,1357,609],{"class":586},[557,1359,1360,1362,1364,1366,1368,1370,1372,1375,1377,1380,1382,1385,1387,1389],{"class":559,"line":654},[557,1361,905],{"class":593},[557,1363,597],{"class":586},[557,1365,1302],{"class":582},[557,1367,626],{"class":586},[557,1369,1307],{"class":582},[557,1371,626],{"class":586},[557,1373,1374],{"class":582}," GammaToken",[557,1376,626],{"class":586},[557,1378,1379],{"class":582}," TargetService",[557,1381,626],{"class":586},[557,1383,1384],{"class":582}," DeltaToken",[557,1386,626],{"class":586},[557,1388,1339],{"class":582},[557,1390,609],{"class":586},[557,1392,1393,1395,1397],{"class":559,"line":667},[557,1394,968],{"class":586},[557,1396,971],{"class":582},[557,1398,974],{"class":586},[499,1400,1401,1402,1404,1405,1408,1409,1412,1413,1416,1417,1420,1421,1423,1424,1426,1427,1416,1430,1433,1434,1437,1438,1440],{},"With ",[506,1403,508],{},", the ",[527,1406,1407],{},"first"," listed token (",[506,1410,1411],{},"AlphaService",") gets the real binding and the rest\n(",[506,1414,1415],{},"BetaToken",", ",[506,1418,1419],{},"GammaToken",") become ",[506,1422,1214],{}," aliases pointing back at it. With ",[506,1425,1214],{},", every\nlisted token (",[506,1428,1429],{},"DeltaToken",[506,1431,1432],{},"EpsilonToken",") aliases the named target (",[506,1435,1436],{},"TargetService",") directly — there's no\n\"first token\" distinction because ",[506,1439,1214],{}," never constructs anything of its own.",[515,1442,1444,1446],{"id":1443},"useexisting-alias-one-token-to-another-providers-instance",[506,1445,1214],{},": alias one token to another provider's instance",[499,1448,1449,1451],{},[506,1450,1214],{}," makes a second token resolve to an already-provided instance, with no second construction —\nuseful when a concrete implementation needs to answer to an abstract token too, without re-running its\nconstructor:",[547,1453,1455],{"className":549,"code":1454,"language":552,"meta":553,"style":553},"providers: [\n  DrizzleUsersRepository,\n  { provide: UsersRepository, useExisting: DrizzleUsersRepository }, \u002F\u002F same instance, two names\n]\n",[506,1456,1457,1466,1473,1501],{"__ignoreMap":553},[557,1458,1459,1462,1464],{"class":559,"line":560},[557,1460,1461],{"class":571},"providers",[557,1463,597],{"class":586},[557,1465,600],{"class":582},[557,1467,1468,1471],{"class":559,"line":590},[557,1469,1470],{"class":582},"  DrizzleUsersRepository",[557,1472,609],{"class":586},[557,1474,1475,1478,1480,1482,1485,1487,1489,1491,1494,1497],{"class":559,"line":603},[557,1476,1477],{"class":586},"  {",[557,1479,618],{"class":593},[557,1481,597],{"class":586},[557,1483,1484],{"class":582}," UsersRepository",[557,1486,626],{"class":586},[557,1488,1344],{"class":593},[557,1490,597],{"class":586},[557,1492,1493],{"class":582}," DrizzleUsersRepository ",[557,1495,1496],{"class":586},"},",[557,1498,1500],{"class":1499},"sHwdD"," \u002F\u002F same instance, two names\n",[557,1502,1503],{"class":559,"line":612},[557,1504,1505],{"class":582},"]\n",[499,1507,1508,1509,1188,1512,1515,1516,1518],{},"Both ",[506,1510,1511],{},"DrizzleUsersRepository",[506,1513,1514],{},"UsersRepository"," resolve to the one instance the compiler constructs\nfor ",[506,1517,1511],{}," — a consumer injecting either token gets the same object.",[515,1520,1522,1525],{"id":1521},"usevalue-and-eager-boot-for-opaque-providers",[506,1523,1524],{},"useValue"," and eager boot for opaque providers",[499,1527,1528,1530,1531,541,1534,1536,1537,1540,1541,1543,1544,1546,1547,1550,1551,1553,1554,1557,1558,1561],{},[506,1529,1524],{}," binds an already-built value to a token — most often a config object. The compiler can chain-walk\na bare ",[506,1532,1533],{},"class",[506,1535,508],{}," provider's implementation to see whether it implements ",[506,1538,1539],{},"OnBootstrap"," and force-load\nit at boot automatically. A ",[506,1542,1524],{}," value (and a ",[506,1545,512],{}," result) is ",[527,1548,1549],{},"opaque"," to that walk — the\ncompiler can't read methods off a value it didn't construct — so an opaque provider that implements\n",[506,1552,1539],{}," needs an explicit ",[506,1555,1556],{},"eager: true"," to be force-loaded at ",[506,1559,1560],{},"createApp"," instead of waiting for the\nfirst request that resolves it.",[547,1563,1566],{"className":549,"code":1564,"filename":1565,"language":552,"meta":553,"style":553},"import { Context, Module } from \"@heximon\u002Fruntime\";\nimport { FeedRegistration } from \".\u002Ffeed-registration\";\nimport { ServiceRegistry } from \".\u002Fservice-registry\";\n\nexport class FeedModule extends Module({\n  providers: [\n    ServiceRegistry,\n    \u002F\u002F `FeedRegistration` is built by a factory, so its hooks are opaque — `eager: true` opts it into the\n    \u002F\u002F boot force-load + onBootstrap dispatch. The TYPE system REQUIRES the flag here (the factory result\n    \u002F\u002F implements OnBootstrap), so forgetting it is a compile error, not silently-dropped boot work.\n    {\n      provide: FeedRegistration,\n      useFactory: (context: Context, registry: ServiceRegistry) =>\n        new FeedRegistration(context, registry),\n      eager: true,\n    },\n  ],\n}) {}\n","src\u002Ffeed\u002Ffeed.module.ts",[506,1567,1568,1598,1620,1642,1646,1663,1671,1678,1683,1688,1693,1697,1707,1734,1749,1762,1766,1772],{"__ignoreMap":553},[557,1569,1570,1573,1575,1577,1579,1581,1584,1587,1590,1593,1595],{"class":559,"line":560},[557,1571,1572],{"class":563},"import",[557,1574,884],{"class":586},[557,1576,805],{"class":582},[557,1578,626],{"class":586},[557,1580,579],{"class":582},[557,1582,1583],{"class":586}," }",[557,1585,1586],{"class":563}," from",[557,1588,1589],{"class":586}," \"",[557,1591,1592],{"class":852},"@heximon\u002Fruntime",[557,1594,849],{"class":586},[557,1596,1597],{"class":586},";\n",[557,1599,1600,1602,1604,1607,1609,1611,1613,1616,1618],{"class":559,"line":590},[557,1601,1572],{"class":563},[557,1603,884],{"class":586},[557,1605,1606],{"class":582}," FeedRegistration",[557,1608,1583],{"class":586},[557,1610,1586],{"class":563},[557,1612,1589],{"class":586},[557,1614,1615],{"class":852},".\u002Ffeed-registration",[557,1617,849],{"class":586},[557,1619,1597],{"class":586},[557,1621,1622,1624,1626,1629,1631,1633,1635,1638,1640],{"class":559,"line":603},[557,1623,1572],{"class":563},[557,1625,884],{"class":586},[557,1627,1628],{"class":582}," ServiceRegistry",[557,1630,1583],{"class":586},[557,1632,1586],{"class":563},[557,1634,1589],{"class":586},[557,1636,1637],{"class":852},".\u002Fservice-registry",[557,1639,849],{"class":586},[557,1641,1597],{"class":586},[557,1643,1644],{"class":559,"line":612},[557,1645,1088],{"emptyLinePlaceholder":1087},[557,1647,1648,1650,1652,1655,1657,1659,1661],{"class":559,"line":640},[557,1649,564],{"class":563},[557,1651,568],{"class":567},[557,1653,1654],{"class":571}," FeedModule",[557,1656,575],{"class":567},[557,1658,579],{"class":578},[557,1660,583],{"class":582},[557,1662,587],{"class":586},[557,1664,1665,1667,1669],{"class":559,"line":648},[557,1666,594],{"class":593},[557,1668,597],{"class":586},[557,1670,600],{"class":582},[557,1672,1673,1676],{"class":559,"line":654},[557,1674,1675],{"class":582},"    ServiceRegistry",[557,1677,609],{"class":586},[557,1679,1680],{"class":559,"line":667},[557,1681,1682],{"class":1499},"    \u002F\u002F `FeedRegistration` is built by a factory, so its hooks are opaque — `eager: true` opts it into the\n",[557,1684,1685],{"class":559,"line":706},[557,1686,1687],{"class":1499},"    \u002F\u002F boot force-load + onBootstrap dispatch. The TYPE system REQUIRES the flag here (the factory result\n",[557,1689,1690],{"class":559,"line":712},[557,1691,1692],{"class":1499},"    \u002F\u002F implements OnBootstrap), so forgetting it is a compile error, not silently-dropped boot work.\n",[557,1694,1695],{"class":559,"line":717},[557,1696,651],{"class":586},[557,1698,1699,1701,1703,1705],{"class":559,"line":729},[557,1700,657],{"class":593},[557,1702,597],{"class":586},[557,1704,1606],{"class":582},[557,1706,609],{"class":586},[557,1708,1709,1711,1713,1715,1717,1719,1721,1723,1726,1728,1730,1732],{"class":559,"line":769},[557,1710,670],{"class":578},[557,1712,597],{"class":586},[557,1714,736],{"class":586},[557,1716,800],{"class":739},[557,1718,597],{"class":586},[557,1720,805],{"class":571},[557,1722,626],{"class":586},[557,1724,1725],{"class":739}," registry",[557,1727,597],{"class":586},[557,1729,1628],{"class":571},[557,1731,1117],{"class":586},[557,1733,822],{"class":567},[557,1735,1736,1738,1740,1742,1744,1747],{"class":559,"line":774},[557,1737,828],{"class":586},[557,1739,1606],{"class":578},[557,1741,833],{"class":582},[557,1743,626],{"class":586},[557,1745,1746],{"class":582}," registry)",[557,1748,609],{"class":586},[557,1750,1751,1754,1756,1760],{"class":559,"line":779},[557,1752,1753],{"class":593},"      eager",[557,1755,597],{"class":586},[557,1757,1759],{"class":1758},"sfNiH"," true",[557,1761,609],{"class":586},[557,1763,1764],{"class":559,"line":791},[557,1765,709],{"class":586},[557,1767,1768,1770],{"class":559,"line":825},[557,1769,871],{"class":582},[557,1771,609],{"class":586},[557,1773,1774,1776,1778],{"class":559,"line":863},[557,1775,968],{"class":586},[557,1777,971],{"class":582},[557,1779,974],{"class":586},[499,1781,1782,1783,1786,1787,1789,1790,1793,1794,1796,1797,1799,1800,1796,1803,1806,1807,1810,1811,1813,1814,1818],{},"The flag is ",[527,1784,1785],{},"type-required"," the moment the produced value implements ",[506,1788,1539],{}," — omitting it is a\n",[506,1791,1792],{},"Module(...)"," config error naming the offending entry, so eager-boot work (a queue consumer's poll loop, a\nscheduler's timers) can never be silently dropped just because it happened to be built by a factory. A\n",[506,1795,1524],{},"\u002F",[506,1798,512],{}," provider also runs ",[506,1801,1802],{},"onInit",[506,1804,1805],{},"onShutdown"," if its value declares them, with no flag\nneeded for those two hooks — only ",[506,1808,1809],{},"onBootstrap"," needs ",[506,1812,1556],{},". See\n",[502,1815,1817],{"href":1816},"\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle#eager-boot-for-opaque-providers","Application Lifecycle"," for the\nfull boot-phase picture this flag participates in.",[515,1820,1822],{"id":1821},"factory-form-module-configs","Factory-form module configs",[499,1824,1825,1826,1828,1829,1832,1833,1836,1837,695],{},"Most modules build their dependencies from a fixed config value and never need a parameter — a plain\n",[506,1827,512],{}," over an imported config value covers that case, and it's the idiom most apps stay on. When\nthe ",[527,1830,1831],{},"same"," module must be imported with genuinely different values in different places, use the factory\nform instead: ",[506,1834,1835],{},"Module((config) => ({...}))",", configured at the import site with ",[506,1838,1839],{},"new SomeModule(config)",[547,1841,1844],{"className":549,"code":1842,"filename":1843,"language":552,"meta":553,"style":553},"import { Module } from \"src\u002Findex\";\nimport { AuthConfig } from \".\u002Fauth-config\";\nimport { AuthService } from \".\u002Fauth-service\";\n\ninterface AuthOptions {\n  readonly publicKey: string;\n}\n\nexport class AuthModule extends Module((config: AuthOptions) => ({\n  providers: [\n    { provide: AuthConfig, useFactory: () => new AuthConfig(config.publicKey) },\n    AuthService,\n  ],\n  exports: [AuthConfig, AuthService],\n})) {}\n","packages\u002Fkernel\u002Fruntime\u002Ftest\u002Ffixtures\u002Fparameterized\u002Fauth.module.ts",[506,1845,1846,1867,1889,1911,1915,1925,1939,1943,1947,1978,1986,2022,2029,2035,2051],{"__ignoreMap":553},[557,1847,1848,1850,1852,1854,1856,1858,1860,1863,1865],{"class":559,"line":560},[557,1849,1572],{"class":563},[557,1851,884],{"class":586},[557,1853,579],{"class":582},[557,1855,1583],{"class":586},[557,1857,1586],{"class":563},[557,1859,1589],{"class":586},[557,1861,1862],{"class":852},"src\u002Findex",[557,1864,849],{"class":586},[557,1866,1597],{"class":586},[557,1868,1869,1871,1873,1876,1878,1880,1882,1885,1887],{"class":559,"line":590},[557,1870,1572],{"class":563},[557,1872,884],{"class":586},[557,1874,1875],{"class":582}," AuthConfig",[557,1877,1583],{"class":586},[557,1879,1586],{"class":563},[557,1881,1589],{"class":586},[557,1883,1884],{"class":852},".\u002Fauth-config",[557,1886,849],{"class":586},[557,1888,1597],{"class":586},[557,1890,1891,1893,1895,1898,1900,1902,1904,1907,1909],{"class":559,"line":603},[557,1892,1572],{"class":563},[557,1894,884],{"class":586},[557,1896,1897],{"class":582}," AuthService",[557,1899,1583],{"class":586},[557,1901,1586],{"class":563},[557,1903,1589],{"class":586},[557,1905,1906],{"class":852},".\u002Fauth-service",[557,1908,849],{"class":586},[557,1910,1597],{"class":586},[557,1912,1913],{"class":559,"line":612},[557,1914,1088],{"emptyLinePlaceholder":1087},[557,1916,1917,1920,1923],{"class":559,"line":640},[557,1918,1919],{"class":567},"interface",[557,1921,1922],{"class":571}," AuthOptions",[557,1924,1047],{"class":586},[557,1926,1927,1930,1933,1935,1937],{"class":559,"line":648},[557,1928,1929],{"class":567},"  readonly",[557,1931,1932],{"class":593}," publicKey",[557,1934,597],{"class":586},[557,1936,1065],{"class":571},[557,1938,1597],{"class":586},[557,1940,1941],{"class":559,"line":654},[557,1942,1082],{"class":586},[557,1944,1945],{"class":559,"line":667},[557,1946,1088],{"emptyLinePlaceholder":1087},[557,1948,1949,1951,1953,1955,1957,1959,1961,1963,1966,1968,1970,1972,1974,1976],{"class":559,"line":706},[557,1950,564],{"class":563},[557,1952,568],{"class":567},[557,1954,572],{"class":571},[557,1956,575],{"class":567},[557,1958,579],{"class":578},[557,1960,583],{"class":582},[557,1962,583],{"class":586},[557,1964,1965],{"class":739},"config",[557,1967,597],{"class":586},[557,1969,1922],{"class":571},[557,1971,1117],{"class":586},[557,1973,690],{"class":567},[557,1975,736],{"class":582},[557,1977,587],{"class":586},[557,1979,1980,1982,1984],{"class":559,"line":712},[557,1981,594],{"class":593},[557,1983,597],{"class":586},[557,1985,600],{"class":582},[557,1987,1988,1990,1992,1994,1996,1998,2001,2003,2006,2008,2010,2012,2015,2017,2020],{"class":559,"line":717},[557,1989,615],{"class":586},[557,1991,618],{"class":593},[557,1993,597],{"class":586},[557,1995,1875],{"class":582},[557,1997,626],{"class":586},[557,1999,2000],{"class":578}," useFactory",[557,2002,597],{"class":586},[557,2004,2005],{"class":586}," ()",[557,2007,690],{"class":567},[557,2009,754],{"class":586},[557,2011,1875],{"class":578},[557,2013,2014],{"class":582},"(config",[557,2016,695],{"class":586},[557,2018,2019],{"class":582},"publicKey) ",[557,2021,637],{"class":586},[557,2023,2024,2027],{"class":559,"line":729},[557,2025,2026],{"class":582},"    AuthService",[557,2028,609],{"class":586},[557,2030,2031,2033],{"class":559,"line":769},[557,2032,871],{"class":582},[557,2034,609],{"class":586},[557,2036,2037,2039,2041,2044,2046,2049],{"class":559,"line":774},[557,2038,905],{"class":593},[557,2040,597],{"class":586},[557,2042,2043],{"class":582}," [AuthConfig",[557,2045,626],{"class":586},[557,2047,2048],{"class":582}," AuthService]",[557,2050,609],{"class":586},[557,2052,2053,2055,2058],{"class":559,"line":779},[557,2054,968],{"class":586},[557,2056,2057],{"class":582},")) ",[557,2059,974],{"class":586},[547,2061,2064],{"className":549,"code":2062,"filename":2063,"language":552,"meta":553,"style":553},"import { Module } from \"src\u002Findex\";\nimport { AuthModule } from \".\u002Fauth.module\";\n\nexport class AppModule extends Module({\n  imports: [new AuthModule({ publicKey: \"PK-REGISTER-TIME\" })],\n}) {}\n","packages\u002Fkernel\u002Fruntime\u002Ftest\u002Ffixtures\u002Fparameterized\u002Fapp.module.ts",[506,2065,2066,2086,2107,2111,2128,2166],{"__ignoreMap":553},[557,2067,2068,2070,2072,2074,2076,2078,2080,2082,2084],{"class":559,"line":560},[557,2069,1572],{"class":563},[557,2071,884],{"class":586},[557,2073,579],{"class":582},[557,2075,1583],{"class":586},[557,2077,1586],{"class":563},[557,2079,1589],{"class":586},[557,2081,1862],{"class":852},[557,2083,849],{"class":586},[557,2085,1597],{"class":586},[557,2087,2088,2090,2092,2094,2096,2098,2100,2103,2105],{"class":559,"line":590},[557,2089,1572],{"class":563},[557,2091,884],{"class":586},[557,2093,572],{"class":582},[557,2095,1583],{"class":586},[557,2097,1586],{"class":563},[557,2099,1589],{"class":586},[557,2101,2102],{"class":852},".\u002Fauth.module",[557,2104,849],{"class":586},[557,2106,1597],{"class":586},[557,2108,2109],{"class":559,"line":603},[557,2110,1088],{"emptyLinePlaceholder":1087},[557,2112,2113,2115,2117,2120,2122,2124,2126],{"class":559,"line":612},[557,2114,564],{"class":563},[557,2116,568],{"class":567},[557,2118,2119],{"class":571}," AppModule",[557,2121,575],{"class":567},[557,2123,579],{"class":578},[557,2125,583],{"class":582},[557,2127,587],{"class":586},[557,2129,2130,2133,2135,2138,2141,2143,2145,2148,2150,2152,2154,2157,2159,2161,2164],{"class":559,"line":640},[557,2131,2132],{"class":593},"  imports",[557,2134,597],{"class":586},[557,2136,2137],{"class":582}," [",[557,2139,2140],{"class":586},"new",[557,2142,572],{"class":578},[557,2144,583],{"class":582},[557,2146,2147],{"class":586},"{",[557,2149,1932],{"class":593},[557,2151,597],{"class":586},[557,2153,1589],{"class":586},[557,2155,2156],{"class":852},"PK-REGISTER-TIME",[557,2158,849],{"class":586},[557,2160,1583],{"class":586},[557,2162,2163],{"class":582},")]",[557,2165,609],{"class":586},[557,2167,2168,2170,2172],{"class":559,"line":648},[557,2169,968],{"class":586},[557,2171,971],{"class":582},[557,2173,974],{"class":586},[499,2175,2176,2177,1416,2179,2181,2182,2184,2185,2188,2189,1796,2191,2193,2194,2197],{},"The compiler reads the returned config object's static shape — ",[506,2178,1461],{},[506,2180,524],{},", everything else —\nthe same way it reads a plain object config; the only difference is that the ",[506,2183,1965],{}," supplied at the\n",[506,2186,2187],{},"new AuthModule(config)"," import site is threaded into the module's ",[506,2190,1524],{},[506,2192,512],{}," providers,\nletting two ",[506,2195,2196],{},"imports"," entries for the same module class carry two different values.",[2199,2200,2202,2203,2206],"callout",{"type":2201},"tip","Importing a parameterized module instance neutralizes the editor's dependency and export checks for ",[1011,2204,2205],{},"that\none import"," — the factory form's config isn't known until the import site, so the editor can't pre-validate\nit the way it does a plain object config. The compiler still validates it fully at build time.",[515,2208,2210],{"id":2209},"a-factory-with-several-dependencies","A factory with several dependencies",[499,2212,2213,2214,2216,2217,2220,2221,2224,2225,2228],{},"A ",[506,2215,512],{},"'s parameter types ",[527,2218,2219],{},"are"," its dependency declaration, exactly like a constructor — there's\nno separate ",[506,2222,2223],{},"inject"," array to keep in sync. When two providers both need the same upstream value, declare\nit once and let each factory take it as a parameter; the compiler works out the construction order so both\nfactories see the same instance — the same ",[506,2226,2227],{},"AuthModule"," from above is also this pattern in action:",[547,2230,2232],{"className":549,"code":2231,"filename":551,"language":552,"meta":553,"style":553},"{\n  provide: IdentityKeyPair,\n  useFactory: (): Promise\u003CIdentityKeyPair> => IdentityKeyPair.resolve(),\n},\n{\n  provide: JWTFactory,\n  useFactory: (keys: IdentityKeyPair): JWTFactory => new JWTFactory(keys.privateKey),\n},\n{\n  provide: AuthContext,\n  useFactory: (context: Context, verifier: JWTVerifier): AuthContext =>\n    new AuthContext(context, verifier, new CookieTokenSource(\"accessToken\")),\n},\n",[506,2233,2234,2238,2249,2278,2282,2286,2296,2333,2337,2341,2351,2379,2412],{"__ignoreMap":553},[557,2235,2236],{"class":559,"line":560},[557,2237,587],{"class":586},[557,2239,2240,2243,2245,2247],{"class":559,"line":590},[557,2241,2242],{"class":571},"  provide",[557,2244,597],{"class":586},[557,2246,662],{"class":582},[557,2248,609],{"class":586},[557,2250,2251,2254,2256,2258,2260,2262,2264,2266,2268,2270,2272,2274,2276],{"class":559,"line":603},[557,2252,2253],{"class":571},"  useFactory",[557,2255,597],{"class":586},[557,2257,675],{"class":586},[557,2259,678],{"class":571},[557,2261,681],{"class":586},[557,2263,684],{"class":571},[557,2265,687],{"class":586},[557,2267,690],{"class":567},[557,2269,662],{"class":582},[557,2271,695],{"class":586},[557,2273,698],{"class":578},[557,2275,701],{"class":593},[557,2277,609],{"class":586},[557,2279,2280],{"class":559,"line":612},[557,2281,637],{"class":586},[557,2283,2284],{"class":559,"line":640},[557,2285,587],{"class":586},[557,2287,2288,2290,2292,2294],{"class":559,"line":648},[557,2289,2242],{"class":571},[557,2291,597],{"class":586},[557,2293,724],{"class":582},[557,2295,609],{"class":586},[557,2297,2298,2300,2302,2304,2306,2308,2310,2312,2314,2316,2318,2320,2322,2324,2326,2329,2331],{"class":559,"line":654},[557,2299,2253],{"class":571},[557,2301,597],{"class":586},[557,2303,736],{"class":586},[557,2305,740],{"class":739},[557,2307,597],{"class":586},[557,2309,662],{"class":571},[557,2311,747],{"class":586},[557,2313,724],{"class":571},[557,2315,690],{"class":567},[557,2317,754],{"class":586},[557,2319,724],{"class":578},[557,2321,583],{"class":593},[557,2323,740],{"class":582},[557,2325,695],{"class":586},[557,2327,2328],{"class":582},"privateKey",[557,2330,1117],{"class":593},[557,2332,609],{"class":586},[557,2334,2335],{"class":559,"line":667},[557,2336,637],{"class":586},[557,2338,2339],{"class":559,"line":706},[557,2340,587],{"class":586},[557,2342,2343,2345,2347,2349],{"class":559,"line":712},[557,2344,2242],{"class":571},[557,2346,597],{"class":586},[557,2348,786],{"class":582},[557,2350,609],{"class":586},[557,2352,2353,2355,2357,2359,2361,2363,2365,2367,2369,2371,2373,2375,2377],{"class":559,"line":717},[557,2354,2253],{"class":571},[557,2356,597],{"class":586},[557,2358,736],{"class":586},[557,2360,800],{"class":739},[557,2362,597],{"class":586},[557,2364,805],{"class":571},[557,2366,626],{"class":586},[557,2368,810],{"class":739},[557,2370,597],{"class":586},[557,2372,815],{"class":571},[557,2374,747],{"class":586},[557,2376,786],{"class":571},[557,2378,822],{"class":567},[557,2380,2381,2384,2386,2388,2390,2392,2394,2396,2398,2400,2402,2404,2406,2408,2410],{"class":559,"line":729},[557,2382,2383],{"class":586},"    new",[557,2385,786],{"class":578},[557,2387,583],{"class":593},[557,2389,800],{"class":582},[557,2391,626],{"class":586},[557,2393,810],{"class":582},[557,2395,626],{"class":586},[557,2397,754],{"class":586},[557,2399,844],{"class":578},[557,2401,583],{"class":593},[557,2403,849],{"class":586},[557,2405,853],{"class":852},[557,2407,849],{"class":586},[557,2409,858],{"class":593},[557,2411,609],{"class":586},[557,2413,2414],{"class":559,"line":769},[557,2415,637],{"class":586},[499,2417,2418,2420,2421,2424,2425,2427,2428,2430,2431,2433,2434,2436,2437,2439,2440,2443,2444,2446,2447,2449,2450,2452],{},[506,2419,684],{}," is provided by an ",[527,2422,2423],{},"async"," ",[506,2426,512],{}," — ",[506,2429,1560],{}," awaits it once at boot, so the whole\napp shares one freshly resolved key pair. Both ",[506,2432,991],{}," and the ",[506,2435,998],{}," factory depend on\ndownstream values built from that same pair (",[506,2438,991],{}," reads ",[506,2441,2442],{},"keys.privateKey","; ",[506,2445,998],{}," takes the\n",[506,2448,980],{}," that ",[506,2451,991],{}," itself satisfies, per the nominal-satisfier walk above) — the compiler works\nout the construction order from the parameter types alone, so nothing needs a manual sequencing hint.",[515,2454,2456],{"id":2455},"a-generic-class-is-not-a-token","A generic class is not a token",[499,2458,2459,2460,2463,2464,2467,2468,2471,2472,1188,2474,2477,2478,2480],{},"Class identity is the only DI token, and ",[527,2461,2462],{},"type arguments are erased for resolution"," — a parameter typed\n",[506,2465,2466],{},"Repository\u003CUser>"," resolves the bare ",[506,2469,2470],{},"Repository"," identity, so ",[506,2473,2466],{},[506,2475,2476],{},"Repository\u003COrder>","\ncollapse to the ",[1011,2479,1831],{}," token. Injecting a parameterized generic base directly is a compile error, because\nthe compiler has no way to know which specialization you meant.",[499,2482,2483,2486,2487,2490],{},[506,2484,2485],{},"@heximon\u002Fdrizzle","'s ",[506,2488,2489],{},"DrizzleLibSQLConfig\u003CTSchema, TRelations>"," is the concrete case every app with a\ndatabase hits: the config class is generic over your schema and relations, so it can never be a token by\nitself.",[547,2492,2495],{"className":549,"code":2493,"filename":2494,"language":552,"meta":553,"style":553},"import { DrizzleLibSQLConfig } from \"@heximon\u002Fdrizzle\u002Flibsql\u002Fconfig\";\nimport { relations, schema } from \".\u002Fschema\";\n\nexport const databaseConfig = new DrizzleLibSQLConfig(schema, relations, {\n  dialect: \"sqlite\",\n  schema: \".\u002Fsrc\u002Fdatabase\u002Fschema.ts\",\n  out: \".\u002Fmigrations\",\n  url: \":memory:\",\n});\n\nexport type DatabaseSchema = typeof schema;\nexport type DatabaseRelations = typeof relations;\n","examples\u002Fladder\u002FL04-database\u002Fsrc\u002Fdatabase\u002Fdatabase.config.ts",[506,2496,2497,2519,2546,2550,2578,2594,2610,2626,2642,2650,2654,2674],{"__ignoreMap":553},[557,2498,2499,2501,2503,2506,2508,2510,2512,2515,2517],{"class":559,"line":560},[557,2500,1572],{"class":563},[557,2502,884],{"class":586},[557,2504,2505],{"class":582}," DrizzleLibSQLConfig",[557,2507,1583],{"class":586},[557,2509,1586],{"class":563},[557,2511,1589],{"class":586},[557,2513,2514],{"class":852},"@heximon\u002Fdrizzle\u002Flibsql\u002Fconfig",[557,2516,849],{"class":586},[557,2518,1597],{"class":586},[557,2520,2521,2523,2525,2528,2530,2533,2535,2537,2539,2542,2544],{"class":559,"line":590},[557,2522,1572],{"class":563},[557,2524,884],{"class":586},[557,2526,2527],{"class":582}," relations",[557,2529,626],{"class":586},[557,2531,2532],{"class":582}," schema",[557,2534,1583],{"class":586},[557,2536,1586],{"class":563},[557,2538,1589],{"class":586},[557,2540,2541],{"class":852},".\u002Fschema",[557,2543,849],{"class":586},[557,2545,1597],{"class":586},[557,2547,2548],{"class":559,"line":603},[557,2549,1088],{"emptyLinePlaceholder":1087},[557,2551,2552,2554,2557,2560,2563,2565,2567,2570,2572,2574,2576],{"class":559,"line":612},[557,2553,564],{"class":563},[557,2555,2556],{"class":567}," const",[557,2558,2559],{"class":582}," databaseConfig ",[557,2561,2562],{"class":586},"=",[557,2564,754],{"class":586},[557,2566,2505],{"class":578},[557,2568,2569],{"class":582},"(schema",[557,2571,626],{"class":586},[557,2573,2527],{"class":582},[557,2575,626],{"class":586},[557,2577,1047],{"class":586},[557,2579,2580,2583,2585,2587,2590,2592],{"class":559,"line":640},[557,2581,2582],{"class":593},"  dialect",[557,2584,597],{"class":586},[557,2586,1589],{"class":586},[557,2588,2589],{"class":852},"sqlite",[557,2591,849],{"class":586},[557,2593,609],{"class":586},[557,2595,2596,2599,2601,2603,2606,2608],{"class":559,"line":648},[557,2597,2598],{"class":593},"  schema",[557,2600,597],{"class":586},[557,2602,1589],{"class":586},[557,2604,2605],{"class":852},".\u002Fsrc\u002Fdatabase\u002Fschema.ts",[557,2607,849],{"class":586},[557,2609,609],{"class":586},[557,2611,2612,2615,2617,2619,2622,2624],{"class":559,"line":654},[557,2613,2614],{"class":593},"  out",[557,2616,597],{"class":586},[557,2618,1589],{"class":586},[557,2620,2621],{"class":852},".\u002Fmigrations",[557,2623,849],{"class":586},[557,2625,609],{"class":586},[557,2627,2628,2631,2633,2635,2638,2640],{"class":559,"line":667},[557,2629,2630],{"class":593},"  url",[557,2632,597],{"class":586},[557,2634,1589],{"class":586},[557,2636,2637],{"class":852},":memory:",[557,2639,849],{"class":586},[557,2641,609],{"class":586},[557,2643,2644,2646,2648],{"class":559,"line":706},[557,2645,968],{"class":586},[557,2647,1117],{"class":582},[557,2649,1597],{"class":586},[557,2651,2652],{"class":559,"line":712},[557,2653,1088],{"emptyLinePlaceholder":1087},[557,2655,2656,2658,2661,2664,2667,2670,2672],{"class":559,"line":717},[557,2657,564],{"class":563},[557,2659,2660],{"class":567}," type",[557,2662,2663],{"class":571}," DatabaseSchema",[557,2665,2666],{"class":586}," =",[557,2668,2669],{"class":586}," typeof",[557,2671,2532],{"class":582},[557,2673,1597],{"class":586},[557,2675,2676,2678,2680,2683,2685,2687,2689],{"class":559,"line":729},[557,2677,564],{"class":563},[557,2679,2660],{"class":567},[557,2681,2682],{"class":571}," DatabaseRelations",[557,2684,2666],{"class":586},[557,2686,2669],{"class":586},[557,2688,2527],{"class":582},[557,2690,1597],{"class":586},[499,2692,2693,2696,2697,2700,2701,2703,2704,2707],{},[506,2694,2695],{},"databaseConfig"," is a ",[527,2698,2699],{},"value"," here, never injected — it's closed over by a factory, not listed in\n",[506,2702,1461],{},". The database itself needs its own token, and that token is a ",[527,2705,2706],{},"named subclass"," that fixes\nthe generic base's type parameters once:",[547,2709,2712],{"className":549,"code":2710,"filename":2711,"language":552,"meta":553,"style":553},"import { DrizzleLibSQLDatabase } from \"@heximon\u002Fdrizzle\u002Flibsql\";\nimport { relations } from \".\u002Frelations\";\nimport * as schema from \".\u002Fschema\";\n\n\u002F\u002F A named concrete token — fixes the generic base's type parameters once.\nexport class AppDatabase extends DrizzleLibSQLDatabase\u003Ctypeof schema, typeof relations> {}\n","examples\u002Fladder\u002FL06-ddd\u002Fsrc\u002Fdatabase\u002Fapp-database.ts",[506,2713,2714,2736,2757,2781,2785,2790],{"__ignoreMap":553},[557,2715,2716,2718,2720,2723,2725,2727,2729,2732,2734],{"class":559,"line":560},[557,2717,1572],{"class":563},[557,2719,884],{"class":586},[557,2721,2722],{"class":582}," DrizzleLibSQLDatabase",[557,2724,1583],{"class":586},[557,2726,1586],{"class":563},[557,2728,1589],{"class":586},[557,2730,2731],{"class":852},"@heximon\u002Fdrizzle\u002Flibsql",[557,2733,849],{"class":586},[557,2735,1597],{"class":586},[557,2737,2738,2740,2742,2744,2746,2748,2750,2753,2755],{"class":559,"line":590},[557,2739,1572],{"class":563},[557,2741,884],{"class":586},[557,2743,2527],{"class":582},[557,2745,1583],{"class":586},[557,2747,1586],{"class":563},[557,2749,1589],{"class":586},[557,2751,2752],{"class":852},".\u002Frelations",[557,2754,849],{"class":586},[557,2756,1597],{"class":586},[557,2758,2759,2761,2764,2767,2770,2773,2775,2777,2779],{"class":559,"line":603},[557,2760,1572],{"class":563},[557,2762,2763],{"class":586}," *",[557,2765,2766],{"class":563}," as",[557,2768,2769],{"class":582}," schema ",[557,2771,2772],{"class":563},"from",[557,2774,1589],{"class":586},[557,2776,2541],{"class":852},[557,2778,849],{"class":586},[557,2780,1597],{"class":586},[557,2782,2783],{"class":559,"line":612},[557,2784,1088],{"emptyLinePlaceholder":1087},[557,2786,2787],{"class":559,"line":640},[557,2788,2789],{"class":1499},"\u002F\u002F A named concrete token — fixes the generic base's type parameters once.\n",[557,2791,2792,2794,2796,2799,2801,2803,2806,2808,2810,2812,2814,2816],{"class":559,"line":648},[557,2793,564],{"class":563},[557,2795,568],{"class":567},[557,2797,2798],{"class":571}," AppDatabase",[557,2800,575],{"class":567},[557,2802,2722],{"class":571},[557,2804,2805],{"class":586},"\u003Ctypeof",[557,2807,2532],{"class":582},[557,2809,626],{"class":586},[557,2811,2669],{"class":586},[557,2813,2527],{"class":582},[557,2815,687],{"class":586},[557,2817,2818],{"class":586}," {}\n",[547,2820,2823],{"className":549,"code":2821,"filename":2822,"language":552,"meta":553,"style":553},"import { type Context, Module } from \"@heximon\u002Fruntime\";\nimport { AppDatabase } from \".\u002Fapp-database\";\nimport { databaseConfig } from \".\u002Fdatabase.config\";\n\nexport class DatabaseModule extends Module({\n  providers: [\n    {\n      provide: AppDatabase,\n      useFactory: (context: Context) => new AppDatabase(databaseConfig, context),\n    },\n  ],\n  exports: [AppDatabase],\n}) {}\n","examples\u002Fladder\u002FL04-database\u002Fsrc\u002Fdatabase\u002Fdatabase.module.ts",[506,2824,2825,2851,2872,2894,2898,2915,2923,2927,2937,2969,2973,2979,2990],{"__ignoreMap":553},[557,2826,2827,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849],{"class":559,"line":560},[557,2828,1572],{"class":563},[557,2830,884],{"class":586},[557,2832,2660],{"class":563},[557,2834,805],{"class":582},[557,2836,626],{"class":586},[557,2838,579],{"class":582},[557,2840,1583],{"class":586},[557,2842,1586],{"class":563},[557,2844,1589],{"class":586},[557,2846,1592],{"class":852},[557,2848,849],{"class":586},[557,2850,1597],{"class":586},[557,2852,2853,2855,2857,2859,2861,2863,2865,2868,2870],{"class":559,"line":590},[557,2854,1572],{"class":563},[557,2856,884],{"class":586},[557,2858,2798],{"class":582},[557,2860,1583],{"class":586},[557,2862,1586],{"class":563},[557,2864,1589],{"class":586},[557,2866,2867],{"class":852},".\u002Fapp-database",[557,2869,849],{"class":586},[557,2871,1597],{"class":586},[557,2873,2874,2876,2878,2881,2883,2885,2887,2890,2892],{"class":559,"line":603},[557,2875,1572],{"class":563},[557,2877,884],{"class":586},[557,2879,2880],{"class":582}," databaseConfig",[557,2882,1583],{"class":586},[557,2884,1586],{"class":563},[557,2886,1589],{"class":586},[557,2888,2889],{"class":852},".\u002Fdatabase.config",[557,2891,849],{"class":586},[557,2893,1597],{"class":586},[557,2895,2896],{"class":559,"line":612},[557,2897,1088],{"emptyLinePlaceholder":1087},[557,2899,2900,2902,2904,2907,2909,2911,2913],{"class":559,"line":640},[557,2901,564],{"class":563},[557,2903,568],{"class":567},[557,2905,2906],{"class":571}," DatabaseModule",[557,2908,575],{"class":567},[557,2910,579],{"class":578},[557,2912,583],{"class":582},[557,2914,587],{"class":586},[557,2916,2917,2919,2921],{"class":559,"line":648},[557,2918,594],{"class":593},[557,2920,597],{"class":586},[557,2922,600],{"class":582},[557,2924,2925],{"class":559,"line":654},[557,2926,651],{"class":586},[557,2928,2929,2931,2933,2935],{"class":559,"line":667},[557,2930,657],{"class":593},[557,2932,597],{"class":586},[557,2934,2798],{"class":582},[557,2936,609],{"class":586},[557,2938,2939,2941,2943,2945,2947,2949,2951,2953,2955,2957,2959,2962,2964,2967],{"class":559,"line":706},[557,2940,670],{"class":578},[557,2942,597],{"class":586},[557,2944,736],{"class":586},[557,2946,800],{"class":739},[557,2948,597],{"class":586},[557,2950,805],{"class":571},[557,2952,1117],{"class":586},[557,2954,690],{"class":567},[557,2956,754],{"class":586},[557,2958,2798],{"class":578},[557,2960,2961],{"class":582},"(databaseConfig",[557,2963,626],{"class":586},[557,2965,2966],{"class":582}," context)",[557,2968,609],{"class":586},[557,2970,2971],{"class":559,"line":712},[557,2972,709],{"class":586},[557,2974,2975,2977],{"class":559,"line":717},[557,2976,871],{"class":582},[557,2978,609],{"class":586},[557,2980,2981,2983,2985,2988],{"class":559,"line":729},[557,2982,905],{"class":593},[557,2984,597],{"class":586},[557,2986,2987],{"class":582}," [AppDatabase]",[557,2989,609],{"class":586},[557,2991,2992,2994,2996],{"class":559,"line":769},[557,2993,968],{"class":586},[557,2995,971],{"class":582},[557,2997,974],{"class":586},[499,2999,3000,3001,3004,3005,1416,3008,3011],{},"A repository then injects ",[506,3002,3003],{},"AppDatabase"," — a real class-identity token — never the type-erased generic\nbase. This is the same pitfall behind \"generic tokens need a named subclass\" wherever you wrap a generic\nframework class: ",[506,3006,3007],{},"Repository\u003CT>",[506,3009,3010],{},"DrizzleLibSQLDatabase\u003CTSchema, TRelations>",", any parameterized base.\nFix it once, at the token declaration, and every consumer downstream injects the plain concrete class like\nany other provider.",[515,3013,3015],{"id":3014},"overriding-the-error-envelope","Overriding the error envelope",[499,3017,3018,3019,3022,3023,3026,3027,3030,3031,3034,3035,3037,3038,3040,3041,3044,3045,3048],{},"Every ",[506,3020,3021],{},"HeximonError"," renders through one chokepoint: ",[506,3024,3025],{},"ErrorEnvelope",", an abstract class bound by default to\n",[506,3028,3029],{},"Rfc9457ErrorEnvelope"," — the RFC 9457 ",[506,3032,3033],{},"application\u002Fproblem+json"," shape ",[502,3036,106],{"href":107},"\ncovers. Bind your own subclass at the root module's ",[506,3039,1461],{}," to reshape ",[527,3042,3043],{},"every"," error response at\nonce — a legacy API that must emit ",[506,3046,3047],{},"{ error, code, message }"," instead of the standard envelope, say:",[547,3050,3053],{"className":549,"code":3051,"filename":3052,"language":552,"meta":553,"style":553},"import { ErrorEnvelope, type ErrorRenderInput, type ErrorRenderMetadata, type ErrorSchemaDescription } from \"@heximon\u002Fruntime\u002Ferrors\";\n\nclass LegacyEnvelope extends ErrorEnvelope {\n  public readonly contentType: string = \"application\u002Fjson\";\n\n  public override format(\n    input: ErrorRenderInput,\n    _metadata: ErrorRenderMetadata,\n  ): Record\u003Cstring, unknown> {\n    return { error: input.name, code: input.statusCode, message: input.message };\n  }\n\n  public override describe(): ErrorSchemaDescription {\n    return {\n      jsonSchema: {},\n      validate: (value) => ({ value: value as Record\u003Cstring, unknown> }),\n    };\n  }\n}\n","packages\u002Fapi\u002Fhttp\u002Ftest\u002Ferror-envelope.e2e.test.ts (excerpt)",[506,3054,3055,3098,3102,3115,3141,3145,3158,3169,3180,3202,3253,3258,3262,3278,3284,3294,3340,3345,3349],{"__ignoreMap":553},[557,3056,3057,3059,3061,3064,3066,3068,3071,3073,3075,3078,3080,3082,3085,3087,3089,3091,3094,3096],{"class":559,"line":560},[557,3058,1572],{"class":563},[557,3060,884],{"class":586},[557,3062,3063],{"class":582}," ErrorEnvelope",[557,3065,626],{"class":586},[557,3067,2660],{"class":563},[557,3069,3070],{"class":582}," ErrorRenderInput",[557,3072,626],{"class":586},[557,3074,2660],{"class":563},[557,3076,3077],{"class":582}," ErrorRenderMetadata",[557,3079,626],{"class":586},[557,3081,2660],{"class":563},[557,3083,3084],{"class":582}," ErrorSchemaDescription",[557,3086,1583],{"class":586},[557,3088,1586],{"class":563},[557,3090,1589],{"class":586},[557,3092,3093],{"class":852},"@heximon\u002Fruntime\u002Ferrors",[557,3095,849],{"class":586},[557,3097,1597],{"class":586},[557,3099,3100],{"class":559,"line":590},[557,3101,1088],{"emptyLinePlaceholder":1087},[557,3103,3104,3106,3109,3111,3113],{"class":559,"line":603},[557,3105,1533],{"class":567},[557,3107,3108],{"class":571}," LegacyEnvelope",[557,3110,575],{"class":567},[557,3112,3063],{"class":571},[557,3114,1047],{"class":586},[557,3116,3117,3120,3123,3126,3128,3130,3132,3134,3137,3139],{"class":559,"line":612},[557,3118,3119],{"class":567},"  public",[557,3121,3122],{"class":567}," readonly",[557,3124,3125],{"class":593}," contentType",[557,3127,597],{"class":586},[557,3129,1065],{"class":571},[557,3131,2666],{"class":586},[557,3133,1589],{"class":586},[557,3135,3136],{"class":852},"application\u002Fjson",[557,3138,849],{"class":586},[557,3140,1597],{"class":586},[557,3142,3143],{"class":559,"line":640},[557,3144,1088],{"emptyLinePlaceholder":1087},[557,3146,3147,3149,3152,3155],{"class":559,"line":648},[557,3148,3119],{"class":567},[557,3150,3151],{"class":567}," override",[557,3153,3154],{"class":593}," format",[557,3156,3157],{"class":586},"(\n",[557,3159,3160,3163,3165,3167],{"class":559,"line":654},[557,3161,3162],{"class":739},"    input",[557,3164,597],{"class":586},[557,3166,3070],{"class":571},[557,3168,609],{"class":586},[557,3170,3171,3174,3176,3178],{"class":559,"line":667},[557,3172,3173],{"class":739},"    _metadata",[557,3175,597],{"class":586},[557,3177,3077],{"class":571},[557,3179,609],{"class":586},[557,3181,3182,3185,3188,3190,3193,3195,3198,3200],{"class":559,"line":706},[557,3183,3184],{"class":586},"  ):",[557,3186,3187],{"class":571}," Record",[557,3189,681],{"class":586},[557,3191,3192],{"class":571},"string",[557,3194,626],{"class":586},[557,3196,3197],{"class":571}," unknown",[557,3199,687],{"class":586},[557,3201,1047],{"class":586},[557,3203,3204,3207,3209,3212,3214,3217,3219,3222,3224,3227,3229,3231,3233,3236,3238,3241,3243,3245,3247,3250],{"class":559,"line":712},[557,3205,3206],{"class":563},"    return",[557,3208,884],{"class":586},[557,3210,3211],{"class":593}," error",[557,3213,597],{"class":586},[557,3215,3216],{"class":582}," input",[557,3218,695],{"class":586},[557,3220,3221],{"class":582},"name",[557,3223,626],{"class":586},[557,3225,3226],{"class":593}," code",[557,3228,597],{"class":586},[557,3230,3216],{"class":582},[557,3232,695],{"class":586},[557,3234,3235],{"class":582},"statusCode",[557,3237,626],{"class":586},[557,3239,3240],{"class":593}," message",[557,3242,597],{"class":586},[557,3244,3216],{"class":582},[557,3246,695],{"class":586},[557,3248,3249],{"class":582},"message",[557,3251,3252],{"class":586}," };\n",[557,3254,3255],{"class":559,"line":717},[557,3256,3257],{"class":586},"  }\n",[557,3259,3260],{"class":559,"line":729},[557,3261,1088],{"emptyLinePlaceholder":1087},[557,3263,3264,3266,3268,3271,3274,3276],{"class":559,"line":769},[557,3265,3119],{"class":567},[557,3267,3151],{"class":567},[557,3269,3270],{"class":593}," describe",[557,3272,3273],{"class":586},"():",[557,3275,3084],{"class":571},[557,3277,1047],{"class":586},[557,3279,3280,3282],{"class":559,"line":774},[557,3281,3206],{"class":563},[557,3283,1047],{"class":586},[557,3285,3286,3289,3291],{"class":559,"line":779},[557,3287,3288],{"class":593},"      jsonSchema",[557,3290,597],{"class":586},[557,3292,3293],{"class":586}," {},\n",[557,3295,3296,3299,3301,3303,3305,3307,3309,3311,3313,3316,3318,3320,3322,3324,3326,3328,3330,3332,3334,3336,3338],{"class":559,"line":791},[557,3297,3298],{"class":578},"      validate",[557,3300,597],{"class":586},[557,3302,736],{"class":586},[557,3304,2699],{"class":739},[557,3306,1117],{"class":586},[557,3308,690],{"class":567},[557,3310,736],{"class":593},[557,3312,2147],{"class":586},[557,3314,3315],{"class":593}," value",[557,3317,597],{"class":586},[557,3319,3315],{"class":582},[557,3321,2766],{"class":563},[557,3323,3187],{"class":571},[557,3325,681],{"class":586},[557,3327,3192],{"class":571},[557,3329,626],{"class":586},[557,3331,3197],{"class":571},[557,3333,687],{"class":586},[557,3335,1583],{"class":586},[557,3337,1117],{"class":593},[557,3339,609],{"class":586},[557,3341,3342],{"class":559,"line":825},[557,3343,3344],{"class":586},"    };\n",[557,3346,3347],{"class":559,"line":863},[557,3348,3257],{"class":586},[557,3350,3351],{"class":559,"line":868},[557,3352,1082],{"class":586},[499,3354,3355,3356,3359,3360,695],{},"Bind it with a provider override — ",[506,3357,3358],{},"providers: [{ provide: ErrorEnvelope, useClass: LegacyEnvelope }]"," —\nand the DI runtime substitutes your class everywhere the envelope is resolved, reshaping the wire body of\nevery error response at once, including the unmatched-route ",[506,3361,3362],{},"404",[499,3364,3365,2424,3368,3371,3372,3375,3376,3379],{},[527,3366,3367],{},"An envelope override is runtime-only.",[506,3369,3370],{},"@heximon\u002Fopenapi"," and the FE self-client are both FE-safe,\ncontract-only consumers of a contract's ",[506,3373,3374],{},".responses()"," map; they reflect the default envelope's schema\nbaked at module load. Overriding the envelope does ",[527,3377,3378],{},"not"," change the contract, the generated OpenAPI\ndocument, or the FE client type — an app that wants its API surface to match a custom envelope shape\nre-declares matching error schemas in its contracts.",[515,3381,3383],{"id":3382},"see-also","See also",[3385,3386,3387,3401,3417,3426],"ul",{},[3388,3389,3390,3392,3393,1796,3395,1796,3397,3400],"li",{},[502,3391,53],{"href":54}," — the provider-form survey this page goes deeper on,\nplus ",[506,3394,2196],{},[506,3396,524],{},[506,3398,3399],{},"requires"," and the editor-vs-build-time DI checks.",[3388,3402,3403,2427,3405,1796,3408,1796,3410,3413,3414,3416],{},[502,3404,1817],{"href":127},[506,3406,3407],{},"OnInit",[506,3409,1539],{},[506,3411,3412],{},"OnShutdown",",\nthe two-phase boot, and the full eager-provider picture ",[506,3415,1556],{}," opts into.",[3388,3418,3419,3421,3422,3425],{},[502,3420,106],{"href":107}," — throwing framework errors, ",[506,3423,3424],{},"ErrorFilter",", and the RFC 9457\nenvelope this page's override section customizes.",[3388,3427,3428,2427,3431,3434],{},[502,3429,3430],{"href":112},"Testing",[506,3432,3433],{},"createTestApp({ overrides })",", the test-only substitute for any\nprovider form covered here, keyed by the same class-identity tokens.",[3436,3437,3438],"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 .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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":553,"searchDepth":590,"depth":590,"links":3440},[3441,3444,3446,3448,3450,3451,3452,3453,3454],{"id":517,"depth":590,"text":518,"children":3442},[3443],{"id":1022,"depth":603,"text":1023},{"id":1240,"depth":590,"text":3445},"Array provide: alias several tokens at once",{"id":1443,"depth":590,"text":3447},"useExisting: alias one token to another provider's instance",{"id":1521,"depth":590,"text":3449},"useValue and eager boot for opaque providers",{"id":1821,"depth":590,"text":1822},{"id":2209,"depth":590,"text":2210},{"id":2455,"depth":590,"text":2456},{"id":3014,"depth":590,"text":3015},{"id":3382,"depth":590,"text":3383},"The nominal-satisfier walk (a concrete subclass satisfies an abstract token, AmbiguousProviders on a tie), array-provide, useExisting aliasing, useFactory with multiple dependencies, the generic-token pitfall (DrizzleLibSQLConfig and named subclasses), useValue with eager, factory-form Module((config) => ({...})) configs, and overriding the ErrorEnvelope.","md",null,{},{"icon":419},{"title":416,"description":3455},"TvEssvGUSVqQRQXALsNYGlxJxCI7jkiSIhvu49fcmVo",[3463,3465],{"title":412,"path":413,"stem":414,"description":3464,"icon":207,"children":-1},"The Heximon Agent Skill at docs\u002Fskills\u002Fheximon, its SKILL.md and references, and the llms.txt and MCP endpoints Docus serves for this site.",{"title":427,"path":428,"stem":429,"description":3466,"icon":430,"children":-1},"Inject the abstract EmailTransport DI token, compose an EmailMessage with Mustache placeholders, and send it — with a capture transport for dev\u002Ftests and ResendTransport as the one-line production swap.",1783300761903]