@forinda/kickjs 5.16.0 → 5.18.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/adapter-D_uzU-QA.d.mts +2121 -0
  2. package/dist/adapter-D_uzU-QA.d.mts.map +1 -0
  3. package/dist/{context-decorator-DDZ30BIW.d.mts → app-module-CuAS6hJC.d.mts} +184 -4
  4. package/dist/app-module-CuAS6hJC.d.mts.map +1 -0
  5. package/dist/application-BU5N6o_M.mjs +12 -0
  6. package/dist/application-BU5N6o_M.mjs.map +1 -0
  7. package/dist/{application-CAnpDQ8d.d.mts → application-pbx53JnX.d.mts} +31 -5
  8. package/dist/application-pbx53JnX.d.mts.map +1 -0
  9. package/dist/{bootstrap-CFK2aAjA.mjs → bootstrap-CFog4v_L.mjs} +3 -3
  10. package/dist/{bootstrap-CFK2aAjA.mjs.map → bootstrap-CFog4v_L.mjs.map} +1 -1
  11. package/dist/{bootstrap-8DDzBjhx.d.mts → bootstrap-DzfBj6Ja.d.mts} +2 -2
  12. package/dist/{bootstrap-8DDzBjhx.d.mts.map → bootstrap-DzfBj6Ja.d.mts.map} +1 -1
  13. package/dist/config/index.mjs +2 -2
  14. package/dist/{config-BW5taOVX.mjs → config-Di3HlRTS.mjs} +3 -3
  15. package/dist/{config-BW5taOVX.mjs.map → config-Di3HlRTS.mjs.map} +1 -1
  16. package/dist/{container-D1gfs6__.mjs → container-BiGimG12.mjs} +3 -3
  17. package/dist/{container-D1gfs6__.mjs.map → container-BiGimG12.mjs.map} +1 -1
  18. package/dist/context-leZajQAj.mjs +12 -0
  19. package/dist/context-leZajQAj.mjs.map +1 -0
  20. package/dist/core/adapter.d.mts +1 -1
  21. package/dist/core/adapter.mjs +1 -1
  22. package/dist/core/app-module.d.mts +1 -1
  23. package/dist/core/app-module.mjs +1 -1
  24. package/dist/core/cache.mjs +1 -1
  25. package/dist/core/container.mjs +2 -2
  26. package/dist/core/cron.mjs +2 -2
  27. package/dist/core/decorators.mjs +2 -2
  28. package/dist/core/errors.d.mts +1 -1
  29. package/dist/core/errors.mjs +2 -2
  30. package/dist/core/errors.mjs.map +1 -1
  31. package/dist/core/interfaces.mjs +1 -1
  32. package/dist/core/logger.mjs +1 -1
  33. package/dist/core/path.mjs +1 -1
  34. package/dist/core/plugin.d.mts +1 -1
  35. package/dist/core/plugin.mjs +1 -1
  36. package/dist/core/reactivity.mjs +1 -1
  37. package/dist/{core-Db2uyqtM.mjs → core-Y_xSqZ7v.mjs} +3 -3
  38. package/dist/{core-Db2uyqtM.mjs.map → core-Y_xSqZ7v.mjs.map} +1 -1
  39. package/dist/{env-nwsfCpdy.mjs → env-BoMBrGWs.mjs} +3 -3
  40. package/dist/{env-nwsfCpdy.mjs.map → env-BoMBrGWs.mjs.map} +1 -1
  41. package/dist/{errors-CRCTjEUK.d.mts → errors-n0H96eEz.d.mts} +3 -1
  42. package/dist/errors-n0H96eEz.d.mts.map +1 -0
  43. package/dist/http/application.d.mts +1 -1
  44. package/dist/http/application.mjs +2 -2
  45. package/dist/http/bootstrap.d.mts +1 -1
  46. package/dist/http/bootstrap.mjs +2 -2
  47. package/dist/http/context.d.mts +2 -2
  48. package/dist/http/context.mjs +2 -2
  49. package/dist/http/middleware/cors.mjs +1 -1
  50. package/dist/http/middleware/csrf.mjs +1 -1
  51. package/dist/http/middleware/error-handler.mjs +2 -2
  52. package/dist/http/middleware/helmet.mjs +1 -1
  53. package/dist/http/middleware/rate-limit.mjs +1 -1
  54. package/dist/http/middleware/request-id.mjs +1 -1
  55. package/dist/http/middleware/request-logger.mjs +2 -2
  56. package/dist/http/middleware/session.mjs +1 -1
  57. package/dist/http/middleware/spa.d.mts +1 -1
  58. package/dist/http/middleware/spa.mjs +2 -2
  59. package/dist/http/middleware/upload.d.mts +2 -2
  60. package/dist/http/middleware/upload.mjs +3 -3
  61. package/dist/http/middleware/upload.mjs.map +1 -1
  62. package/dist/http/middleware/validate.mjs +2 -2
  63. package/dist/http/middleware/views.d.mts +1 -1
  64. package/dist/http/middleware/views.mjs +2 -2
  65. package/dist/http/query/index.d.mts +2 -2
  66. package/dist/http/query/index.mjs +2 -2
  67. package/dist/http/router-builder.d.mts +2 -2
  68. package/dist/http/router-builder.mjs +2 -2
  69. package/dist/http/router-builder.mjs.map +1 -1
  70. package/dist/http/runtimes/fastify.d.mts +66 -0
  71. package/dist/http/runtimes/fastify.d.mts.map +1 -0
  72. package/dist/http/runtimes/fastify.mjs +13 -0
  73. package/dist/http/runtimes/fastify.mjs.map +1 -0
  74. package/dist/http/runtimes/h3.d.mts +29 -0
  75. package/dist/http/runtimes/h3.d.mts.map +1 -0
  76. package/dist/http/runtimes/h3.mjs +12 -0
  77. package/dist/http/runtimes/h3.mjs.map +1 -0
  78. package/dist/{index-kEmG8nWU.d.mts → index-BtWJ9SLP.d.mts} +53 -7
  79. package/dist/{index-kEmG8nWU.d.mts.map → index-BtWJ9SLP.d.mts.map} +1 -1
  80. package/dist/index.d.mts +12 -17
  81. package/dist/index.mjs +2 -2
  82. package/dist/index.mjs.map +1 -1
  83. package/dist/{metadata-Cll3P0N0.mjs → metadata-Pvgc-K8a.mjs} +2 -2
  84. package/dist/{metadata-Cll3P0N0.mjs.map → metadata-Pvgc-K8a.mjs.map} +1 -1
  85. package/dist/query-B3PhfU6M.mjs +12 -0
  86. package/dist/query-B3PhfU6M.mjs.map +1 -0
  87. package/dist/request-scope-BaM8_e_8.mjs +12 -0
  88. package/dist/request-scope-BaM8_e_8.mjs.map +1 -0
  89. package/dist/router-builder-Bh3qSiDz.d.mts +39 -0
  90. package/dist/router-builder-Bh3qSiDz.d.mts.map +1 -0
  91. package/dist/{spa-IRFC2eMN.d.mts → spa-BdvZFXJz.d.mts} +3 -2
  92. package/dist/spa-BdvZFXJz.d.mts.map +1 -0
  93. package/dist/{upload-D6edAELH.d.mts → upload-Bc_rBRtE.d.mts} +37 -2
  94. package/dist/upload-Bc_rBRtE.d.mts.map +1 -0
  95. package/dist/{views-BCl-mETX.d.mts → views-DcTVDiOh.d.mts} +31 -7
  96. package/dist/views-DcTVDiOh.d.mts.map +1 -0
  97. package/package.json +29 -1
  98. package/dist/adapter-CkpcZwzZ.d.mts +0 -407
  99. package/dist/adapter-CkpcZwzZ.d.mts.map +0 -1
  100. package/dist/app-module-BTzb-Vd6.d.mts +0 -92
  101. package/dist/app-module-BTzb-Vd6.d.mts.map +0 -1
  102. package/dist/application-CAnpDQ8d.d.mts.map +0 -1
  103. package/dist/application-DnnqoDWx.mjs +0 -12
  104. package/dist/application-DnnqoDWx.mjs.map +0 -1
  105. package/dist/context-Dnt2Di7p.d.mts +0 -434
  106. package/dist/context-Dnt2Di7p.d.mts.map +0 -1
  107. package/dist/context-MD7Mc_o_.mjs +0 -12
  108. package/dist/context-MD7Mc_o_.mjs.map +0 -1
  109. package/dist/context-decorator-DDZ30BIW.d.mts.map +0 -1
  110. package/dist/errors-CRCTjEUK.d.mts.map +0 -1
  111. package/dist/execution-context-B4cfhivz.d.mts +0 -98
  112. package/dist/execution-context-B4cfhivz.d.mts.map +0 -1
  113. package/dist/index-frSEHiL_.d.mts +0 -796
  114. package/dist/index-frSEHiL_.d.mts.map +0 -1
  115. package/dist/plugin-BQCn6zyj.d.mts +0 -260
  116. package/dist/plugin-BQCn6zyj.d.mts.map +0 -1
  117. package/dist/query-D-FiLfmd.mjs +0 -12
  118. package/dist/query-D-FiLfmd.mjs.map +0 -1
  119. package/dist/router-builder-oQpcQMWl.d.mts +0 -31
  120. package/dist/router-builder-oQpcQMWl.d.mts.map +0 -1
  121. package/dist/spa-IRFC2eMN.d.mts.map +0 -1
  122. package/dist/upload-D6edAELH.d.mts.map +0 -1
  123. package/dist/views-BCl-mETX.d.mts.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter-D_uzU-QA.d.mts","names":[],"sources":["../src/core/introspect.ts","../src/core/augmentation.ts","../src/core/module-registry.ts","../src/core/plugin.ts","../src/core/define-plugin.ts","../src/core/define-module.ts","../src/core/define-modules.ts","../src/core/kick-error.ts","../src/core/metadata.ts","../src/core/circuit-breaker.ts","../src/core/context-errors.ts","../src/core/contributor-pipeline.ts","../src/core/contributor-runner.ts","../src/core/mount-sort.ts","../src/core/define-adapter.ts","../src/core/asset-keys.ts","../src/http/context.ts","../src/http/runtime.ts","../src/core/adapter.ts"],"mappings":"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"}
@@ -1,7 +1,101 @@
1
1
 
2
2
  import { i as Constructor, o as MaybePromise } from "./interfaces-DbTyKGdS.mjs";
3
- import { s as InjectionToken } from "./container-TWOUyR_0.mjs";
4
- import { i as MetaValue, n as ContextMeta, r as ExecutionContext, t as ContextKeys } from "./execution-context-B4cfhivz.mjs";
3
+ import { s as InjectionToken, t as Container } from "./container-TWOUyR_0.mjs";
4
+ //#region src/core/execution-context.d.ts
5
+ /**
6
+ * Transport-agnostic execution context primitives.
7
+ *
8
+ * `ExecutionContext` is the minimal contract every transport-specific
9
+ * context object satisfies — `RequestContext` (HTTP) implements it today;
10
+ * `WsContext`, `QueueContext`, and `CronContext` will adopt it in V2.
11
+ *
12
+ * `ContextMeta` is the augmentable per-request key/type registry. Apps and
13
+ * plugins extend it via module augmentation to get type-safe `ctx.get/set`
14
+ * across the codebase. It lives in core/ (not http/) so non-HTTP transports
15
+ * share a single declaration site.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * declare module '@forinda/kickjs' {
20
+ * interface ContextMeta {
21
+ * user: { id: string; email: string }
22
+ * tenant: { id: string; name: string }
23
+ * }
24
+ * }
25
+ *
26
+ * function loadProject(ctx: ExecutionContext) {
27
+ * const user = ctx.get('user') // typed: { id: string; email: string } | undefined
28
+ * }
29
+ * ```
30
+ */
31
+ /**
32
+ * Augmentable per-request **value-type** registry.
33
+ *
34
+ * Extend via module augmentation to give `ctx.get()` / `ctx.set()` static
35
+ * type information for a given key. Unknown keys still resolve via an
36
+ * explicit generic: `ctx.get<MyType>('custom')`.
37
+ *
38
+ * ```ts
39
+ * declare module '@forinda/kickjs' {
40
+ * interface ContextMeta {
41
+ * tenant: { id: string; name: string }
42
+ * }
43
+ * }
44
+ * ```
45
+ *
46
+ * Every key declared here is automatically a valid `dependsOn` key — see
47
+ * {@link ContextKeys} for the relationship.
48
+ */
49
+ interface ContextMeta {}
50
+ /**
51
+ * Augmentable per-request **key** registry — the set of context keys a
52
+ * project's contributors populate, independent of whether each key has a
53
+ * declared value type in {@link ContextMeta}.
54
+ *
55
+ * This exists so `dependsOn` (and any other key-level typing) can be
56
+ * narrowed to real keys WITHOUT forcing every key to carry a value type.
57
+ * Before it, `dependsOn` was typed against `keyof ContextMeta` alone, so
58
+ * the moment a project augmented `ContextMeta` for *some* keys, any
59
+ * contributor that depended on a key you hadn't added to `ContextMeta`
60
+ * stopped compiling — even though that key was a perfectly valid
61
+ * contributor. Splitting the two registries removes that coupling:
62
+ *
63
+ * - Put a key in `ContextMeta` when you want `ctx.get(key)` typed.
64
+ * - Put a key in `ContextKeys` when it's a real contributor key but you
65
+ * don't need a value type for it (e.g. a marker, or a value you only
66
+ * ever read with an explicit generic).
67
+ *
68
+ * Keys from BOTH registries are accepted by `dependsOn`, so adding a
69
+ * value type via `ContextMeta` never breaks a `dependsOn` elsewhere.
70
+ *
71
+ * ```ts
72
+ * declare module '@forinda/kickjs' {
73
+ * interface ContextKeys {
74
+ * session: true // value type irrelevant; the key just exists
75
+ * }
76
+ * }
77
+ * ```
78
+ */
79
+ interface ContextKeys {}
80
+ /** Resolve a {@link ContextMeta} value type, falling back to `Fallback` for unknown keys. */
81
+ type MetaValue<K extends string, Fallback = unknown> = K extends keyof ContextMeta ? ContextMeta[K] : Fallback;
82
+ /**
83
+ * Minimal transport-agnostic execution context.
84
+ *
85
+ * `RequestContext` (HTTP) implements this directly; future `WsContext`,
86
+ * `QueueContext`, and `CronContext` (V2) will too. The Context Contributor
87
+ * pipeline only depends on this interface — contributors authored against
88
+ * `ExecutionContext` work across every transport that adopts it.
89
+ */
90
+ interface ExecutionContext {
91
+ /** Read a typed value from per-request metadata. */
92
+ get<K extends string>(key: K): MetaValue<K> | undefined;
93
+ /** Write a typed value into per-request metadata. */
94
+ set<K extends string>(key: K, value: MetaValue<K>): void;
95
+ /** Unique per-request identifier (HTTP: x-request-id; WS/queue/cron: transport-defined). */
96
+ readonly requestId: string | undefined;
97
+ }
98
+ //#endregion
5
99
  //#region src/core/context-decorator.d.ts
6
100
  /**
7
101
  * String-literal union of every known context key — the union of the
@@ -341,5 +435,91 @@ interface DefineContextDecoratorFn {
341
435
  */
342
436
  declare const defineContextDecorator: DefineContextDecoratorFn;
343
437
  //#endregion
344
- export { ContextMetaKey as a, DepValue as c, ContextDecoratorTarget as i, ResolvedDeps as l, ContextDecorator as n, ContributorRegistration as o, ContextDecoratorSpec as r, ContributorRegistrations as s, AnyContributorRegistration as t, defineContextDecorator as u };
345
- //# sourceMappingURL=context-decorator-DDZ30BIW.d.mts.map
438
+ //#region src/core/app-module.d.ts
439
+ /**
440
+ * Route set returned by a module's routes() method.
441
+ * Combined with versioning: /{apiPrefix}/v{version}{path}
442
+ *
443
+ * **Either** `controller` or `router` is required. Pass `controller`
444
+ * for the common case — the framework calls `buildRoutes(controller)`
445
+ * internally to derive the Express Router. Pass `router` directly
446
+ * only when you need to compose multiple controllers under one path
447
+ * or hand-build the router yourself.
448
+ */
449
+ interface ModuleRoutes {
450
+ /** URL prefix (e.g. '/users') */
451
+ path: string;
452
+ /**
453
+ * Express Router instance. Optional — when omitted, the framework
454
+ * builds one from `controller` via `buildRoutes(controller)`. Pass
455
+ * an explicit router only when you need to compose multiple
456
+ * controllers or hand-roll the router shape.
457
+ */
458
+ router?: any;
459
+ /** Optional API version override (defaults to Application.defaultVersion) */
460
+ version?: number;
461
+ /**
462
+ * Controller class. Required unless `router` is provided. Used both
463
+ * for the auto-derived router (via `buildRoutes(controller)`) and
464
+ * for OpenAPI spec generation via `SwaggerAdapter`.
465
+ */
466
+ controller?: any;
467
+ }
468
+ /**
469
+ * Interface that every feature module must implement.
470
+ * Modules register their DI bindings and declare their routes.
471
+ *
472
+ * `register` is **optional**. Modules that only contain decorated classes
473
+ * (`@Service`, `@Controller`, `@Repository`, `@Component`) don't need it
474
+ * because the decorators handle DI registration automatically. Implement
475
+ * `register(container)` only when you need to bind a token (typically a
476
+ * repository interface symbol) to a concrete implementation via
477
+ * `container.registerFactory()` / `container.registerInstance()`.
478
+ */
479
+ interface AppModule {
480
+ /** Optional — bind interfaces to implementations in the container */
481
+ register?(container: Container): void;
482
+ /**
483
+ * Return Context Contributors (#107) that apply to every route this
484
+ * module mounts. Module-level contributors are merged into the per-route
485
+ * pipeline at the `'module'` precedence level — they win over adapter
486
+ * and global contributors but lose to method and class decorators.
487
+ *
488
+ * Optional — modules without per-module contributors omit this hook.
489
+ */
490
+ contributors?(): ContributorRegistrations;
491
+ /** Return route definitions for this module, or null for non-HTTP modules */
492
+ routes(): ModuleRoutes | ModuleRoutes[] | null;
493
+ }
494
+ /**
495
+ * Constructor type for the legacy `class FooModule implements AppModule`
496
+ * pattern. The framework still accepts these — bootstrap discriminates
497
+ * class vs instance at boot — but new code should prefer
498
+ * {@link defineModule} for parity with {@link defineAdapter} and
499
+ * {@link definePlugin}, plus typed config + `.scoped()` / `.definition`.
500
+ *
501
+ * @deprecated Use `defineModule({ ... })` and `AppModuleEntry` for the
502
+ * `bootstrap({ modules })` array. The class form continues to work
503
+ * through v5 and is not slated for removal in any specific release —
504
+ * this annotation is a soft "prefer the factory form" hint, not an
505
+ * imminent deprecation.
506
+ */
507
+ type AppModuleClass = new () => AppModule;
508
+ /**
509
+ * Either form accepted by `bootstrap({ modules })` and
510
+ * `KickPlugin.modules?()`:
511
+ *
512
+ * - **Class** — the legacy form. Bootstrap calls `new ModuleClass()`.
513
+ * - **Instance** — produced by {@link defineModule}'s factory call
514
+ * (e.g. `TasksModule({ scope: 'admin' })`). Bootstrap uses it
515
+ * directly without `new`.
516
+ *
517
+ * Both shapes route through the same lifecycle (`register`,
518
+ * `contributors`, `routes`) — the only difference is who owns
519
+ * instantiation. defineModule callers use this union so adopters can
520
+ * mix-and-match in the same `modules` array.
521
+ */
522
+ type AppModuleEntry = AppModuleClass | AppModule;
523
+ //#endregion
524
+ export { ExecutionContext as _, AnyContributorRegistration as a, ContextDecoratorTarget as c, ContributorRegistrations as d, DepValue as f, ContextMeta as g, ContextKeys as h, ModuleRoutes as i, ContextMetaKey as l, defineContextDecorator as m, AppModuleClass as n, ContextDecorator as o, ResolvedDeps as p, AppModuleEntry as r, ContextDecoratorSpec as s, AppModule as t, ContributorRegistration as u, MetaValue as v };
525
+ //# sourceMappingURL=app-module-CuAS6hJC.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app-module-CuAS6hJC.d.mts","names":[],"sources":["../src/core/execution-context.ts","../src/core/context-decorator.ts","../src/core/app-module.ts"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
+ *
4
+ * Copyright (c) Felix Orinda
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ * @license MIT
10
+ */
11
+ import{n as tokenName,r as moduleRouteMissingControllerError,t as Container}from"./container-BiGimG12.mjs";import{METADATA}from"./core/interfaces.mjs";import{Logger,createLogger}from"./core/logger.mjs";import{t as getClassMeta}from"./metadata-Pvgc-K8a.mjs";import{g as MutableModuleRegistry,s as mountSort}from"./core-Y_xSqZ7v.mjs";import{normalizePath}from"./core/path.mjs";import{requestId}from"./http/middleware/request-id.mjs";import{errorHandler,notFoundHandler}from"./http/middleware/error-handler.mjs";import{i as requestStore,t as RequestContext}from"./context-leZajQAj.mjs";import{n as isRequestScopeMiddleware,r as requestScopeMiddleware}from"./request-scope-BaM8_e_8.mjs";import{_setExternalContributorSources,buildRouteTable}from"./http/router-builder.mjs";import{validate}from"./http/middleware/validate.mjs";import{buildUploadMiddleware}from"./http/middleware/upload.mjs";import http from"node:http";import express,{Router}from"express";function materializeRouter(entries){let router=Router();for(let entry of entries){let method=entry.method.toLowerCase(),handlers=[];entry.meta.validation&&handlers.push(validate(entry.meta.validation)),entry.meta.upload&&handlers.push(buildUploadMiddleware(entry.meta.upload));for(let mw of entry.middlewares)handlers.push((req,res,next)=>{let ctx=new RequestContext(req,res,next);Promise.resolve(mw(ctx,next)).catch(next)});if(entry.contributorRunner){let run=entry.contributorRunner;handlers.push(async(req,res,next)=>{let ctx=new RequestContext(req,res,next);try{await run(ctx),next()}catch(err){next(err)}})}handlers.push(async(req,res,next)=>{let ctx=new RequestContext(req,res,next);try{await entry.handler(ctx)}catch(err){next(err)}}),router[method](entry.path,...handlers)}return router}function buildRoutes(controllerClass,options={}){return materializeRouter(buildRouteTable(controllerClass,options))}function expressRuntime(){return{name:`express`,createApp(options={}){let app=express();return app.disable(`x-powered-by`),app.set(`trust proxy`,options.trustProxy??!1),app},nodeHandler(app){return(req,res,next)=>{next?app(req,res,next):app(req,res)}},mountRoutes(app,table){for(let{mountPath,routes}of table)app.use(mountPath,materializeRouter(routes))},useConnect(app,mw,opts={}){opts.path===void 0?app.use(mw):app.use(opts.path,mw)},serveStatic(app,prefix,dir){app.use(prefix,express.static(dir))},setNotFound(app,mw){app.use(mw)},setErrorHandler(app,mw){app.use(mw)},capabilities:{render:!0,uploads:!0,connectMiddleware:!0,nativeBodyParsing:!1}}}const log=createLogger(`Application`);var Application=class{options;app;runtime;container;httpServer=null;adapters;plugins;_moduleContributors=[];_inFlightRequests=0;_draining=!1;_shutdownInitiated=!1;_drainResolvers=[];constructor(options){this.options=options,this.runtime=options.runtime??expressRuntime(),this.app=this.runtime.createApp({trustProxy:options.trustProxy}),this.container=Container.getInstance(),this.plugins=mountSort(options.plugins??[],`plugin`);let allAdapters=[...this.plugins.flatMap(p=>p.adapters?.()??[]),...options.adapters??[]],anonAdapterCount=0,namedAdapters=allAdapters.map(adapter=>{if(!adapter.name){let ctorName=adapter.constructor?.name,fallback=ctorName&&ctorName!==`Object`?ctorName:`AnonymousAdapter#${anonAdapterCount++}`;return Object.assign(adapter,{name:fallback})}return adapter});this.adapters=mountSort(namedAdapters,`adapter`),Container._requestStoreProvider=()=>requestStore.getStore()??null}get isDraining(){return this._draining}get inFlightRequests(){return this._inFlightRequests}getContainer(){return this.container}handle(req,res,next){let handler=this.runtime.nodeHandler(this.app);next?handler(req,res,next):handler(req,res)}adapterCtx(server){let env=process.env.NODE_ENV??`development`;return{http:this.adapterHttp(),app:this.app,container:this.container,server,env,isProduction:env===`production`}}adapterHttp(){return{route:(method,path,handler)=>{let entry={method,path,middlewares:[],contributorRunner:null,handler,meta:{}};this.runtime.mountRoutes(this.app,[{mountPath:`/`,routes:[entry]}])},mount:(prefix,routes)=>{this.runtime.mountRoutes(this.app,[{mountPath:prefix,routes}])},serveStatic:(prefix,dir)=>{this.runtime.serveStatic(this.app,prefix,dir)},use:(mw,opts)=>{this.runtime.useConnect(this.app,mw,opts)}}}async callHook(hook,ctx){if(hook)try{let result=hook(ctx);result&&typeof result.then==`function`&&await result}catch(err){log.error(err,`Adapter hook failed`)}}async setup(){log.debug(`Bootstrapping application...`),this._moduleContributors=[];let adapterMw=this.collectAdapterMiddleware();this.app.__kickApp=this;let ctx=this.adapterCtx();for(let adapter of this.adapters)await this.callHook(adapter.beforeMount?.bind(adapter),ctx);this.runtime.useConnect(this.app,this.requestTrackingMiddleware()),this.mountHealthEndpoints(),this.shouldAutoMountRequestScope()&&this.runtime.useConnect(this.app,requestScopeMiddleware()),this.mountMiddlewareList(adapterMw.beforeGlobal);for(let plugin of this.plugins)plugin.register?.(this.container);for(let plugin of this.plugins)try{let mw=plugin.middleware?.()??[];for(let handler of mw)this.runtime.useConnect(this.app,handler)}catch(err){log.error(err,`Plugin middleware failed: ${plugin.name??`unknown`}`)}if(this.options.security?.helmet!==!1)try{let{helmet:helmetFn}=await import(`./http/middleware/helmet.mjs`);this.runtime.useConnect(this.app,helmetFn())}catch{}let userMiddlewares=this.options.middlewares??this.options.middleware;if(userMiddlewares)for(let entry of userMiddlewares)this.mountMiddlewareEntry(entry);else this.runtime.useConnect(this.app,requestId()),this.runtime.capabilities.nativeBodyParsing||this.runtime.useConnect(this.app,express.json({limit:this.options.jsonLimit??`1mb`}));this.mountMiddlewareList(adapterMw.afterGlobal);let moduleRegistry=new MutableModuleRegistry;for(let plugin of this.plugins){for(let m of plugin.modules?.()??[])moduleRegistry.mount(m);plugin.setup?.(moduleRegistry)}for(let m of this.options.modules)moduleRegistry.mount(m);this.options.setup?.(moduleRegistry);let modules=moduleRegistry.entries.map(entry=>{let mod=typeof entry==`function`?new entry:entry;return mod.register?.(this.container),mod});this.container.bootstrap(),this.container.has(Logger)||this.container.registerInstance(Logger,new Logger),this.mountMiddlewareList(adapterMw.beforeRoutes);let apiPrefix=this.options.apiPrefix??`/api`,defaultVersion=this.options.defaultVersion??1,shouldLogRoutes=this.options.logRouteTable??this.options.logRoutesTable??!1,mountedRoutes=[],adapterSources=[];for(let adapter of this.adapters){let adapterContribs=adapter.contributors?.()??[],adapterLabel=adapter.name??adapter.constructor.name??`adapter`;for(let registration of adapterContribs)adapterSources.push({source:`adapter`,registration,label:adapterLabel})}for(let plugin of this.plugins){let pluginContribs=plugin.contributors?.()??[],pluginLabel=plugin.name??plugin.constructor?.name??`plugin`;for(let registration of pluginContribs)adapterSources.push({source:`adapter`,registration,label:pluginLabel})}let globalSources=(this.options.contributors??[]).map(registration=>({source:`global`,registration,label:`bootstrap`}));this._moduleContributors=[];for(let mod of modules){let declaredName=mod.name,ctorName=mod.constructor?.name,moduleLabel=typeof declaredName==`string`&&declaredName.length>0?declaredName:ctorName&&ctorName!==`Object`?ctorName:`module`,moduleSources=(mod.contributors?.()??[]).map(registration=>({source:`module`,registration,label:moduleLabel}));for(let src of moduleSources)this._moduleContributors.push({registration:src.registration,label:moduleLabel});_setExternalContributorSources([...moduleSources,...adapterSources,...globalSources]);try{let result=mod.routes();if(!result)continue;let routeSets=Array.isArray(result)?result:[result];for(let route of routeSets){let mountPath=`${apiPrefix}/v${route.version??defaultVersion}${normalizePath(route.path)}`;if(route.router)this.runtime.useConnect(this.app,route.router,{path:mountPath});else if(route.controller)this.runtime.mountRoutes(this.app,[{mountPath,routes:buildRouteTable(route.controller)}]);else throw moduleRouteMissingControllerError(mountPath);if(route.controller){for(let adapter of this.adapters)try{adapter.onRouteMount?.(route.controller,mountPath)}catch(err){log.error(err,`adapter.onRouteMount() failed for ${mountPath}`)}shouldLogRoutes&&mountedRoutes.push({controller:route.controller,mountPath})}}}finally{_setExternalContributorSources([])}}if(shouldLogRoutes&&mountedRoutes.length>0){let methodOrder=[`GET`,`POST`,`PUT`,`PATCH`,`DELETE`,`HEAD`,`OPTIONS`],methodRank=m=>{let i=methodOrder.indexOf(m);return i===-1?99:i},totalRoutes=0;log.info(`Routes:`);for(let{controller,mountPath}of mountedRoutes){let defs=getClassMeta(METADATA.ROUTES,controller,[]);if(defs.length===0)continue;let counts={};for(let def of defs){let m=def.method.toUpperCase();counts[m]=(counts[m]||0)+1}totalRoutes+=defs.length;let methods=Object.entries(counts).toSorted(([a],[b])=>methodRank(a)-methodRank(b)).map(([m,n])=>`${n} ${m}`).join(`, `),name=controller.name||`Controller`;log.info(` ${name.padEnd(30)} ${mountPath.padEnd(25)} ${defs.length} routes (${methods})`)}log.info(` Total: ${totalRoutes} routes`)}this.mountMiddlewareList(adapterMw.afterRoutes);for(let adapter of this.adapters)await this.callHook(adapter.beforeStart?.bind(adapter),ctx);this.runtime.setNotFound(this.app,this.options.onNotFound??notFoundHandler()),this.runtime.setErrorHandler(this.app,this.options.onError??errorHandler())}async registerOnly(){await this.setup()}async start(){await this.setup();let g=globalThis;if(g.__kickjs_httpServer){this.httpServer=g.__kickjs_httpServer,log.debug(`Attached to Vite dev server`),g.__kickjs_app_shutdown=()=>this.shutdown();for(let adapter of this.adapters){let ctx=this.adapterCtx(this.httpServer);await this.callHook(adapter.afterStart?.bind(adapter),ctx)}for(let plugin of this.plugins)await plugin.onReady?.(this.container);return}let port=this.options.port??parseInt(process.env.PORT||`3000`,10);this.httpServer=http.createServer(this.runtime.nodeHandler(this.app)),this.httpServer.on(`error`,err=>{throw err.code===`EADDRINUSE`&&(log.error(`Port ${port} is already in use. Kill the existing process or use a different port:\n PORT=${port+1} kick dev\n lsof -i :${port} # find what's using it\n kill <PID> # stop it`),process.exit(1)),err}),await new Promise((resolve,reject)=>{this.httpServer.listen(port,async()=>{try{log.info(`Server running on http://localhost:${port}`);for(let adapter of this.adapters){let afterCtx=this.adapterCtx(this.httpServer);await this.callHook(adapter.afterStart?.bind(adapter),afterCtx)}for(let plugin of this.plugins)await plugin.onReady?.(this.container);resolve()}catch(err){reject(err)}})})}async rebuild(){let prevApp=this.app,prevContainer=this.container;try{Container.reset(),this.container=Container.getInstance(),this.app=this.runtime.createApp({trustProxy:this.options.trustProxy}),await this.setup()}catch(err){log.error(err,`HMR rebuild failed, keeping previous app`),this.app=prevApp,this.container=prevContainer;return}this.httpServer&&(this.httpServer.removeAllListeners(`request`),this.httpServer.on(`request`,this.runtime.nodeHandler(this.app)),log.debug(`HMR: app rebuilt and swapped`))}async shutdown(){if(this._shutdownInitiated){log.debug(`Shutdown already in progress, skipping duplicate call`);return}this._shutdownInitiated=!0,this._draining=!0,log.debug(`Shutting down — draining in-flight requests...`);let timeoutMs=this.options.shutdownTimeout??3e4,timer,forceExitPromise=timeoutMs>0?new Promise(resolve=>{timer=setTimeout(()=>resolve(`timeout`),timeoutMs),timer.unref()}):new Promise(()=>{});try{if(this.httpServer&&this.httpServer.close(()=>{}),this._inFlightRequests>0){log.debug(`Waiting for ${this._inFlightRequests} in-flight request(s) to complete...`);let drainPromise=new Promise(resolve=>{this._drainResolvers.push(()=>resolve(`drained`))});await Promise.race([drainPromise,forceExitPromise])===`timeout`?log.warn(`Shutdown timeout (${timeoutMs}ms) reached with ${this._inFlightRequests} request(s) still in-flight, forcing shutdown`):log.debug(`All in-flight requests completed`)}let results=await Promise.allSettled([...this.plugins.map(plugin=>Promise.resolve(plugin.shutdown?.())),...this.adapters.map(adapter=>Promise.resolve(adapter.shutdown?.()))]);for(let result of results)result.status===`rejected`&&log.error({err:result.reason},`Adapter shutdown failed`)}finally{timer&&clearTimeout(timer)}}getRuntimeApp(){return this.app}getExpressApp(){return this.app}getAdapters(){return this.adapters}getPlugins(){return this.plugins}getContributors(){let out=[],ingest=(list,source,label)=>{if(list)for(let reg of list){let r=reg;if(r.key===void 0||r.key===null)continue;let key=typeof r.key==`string`?r.key:tokenName(r.key);out.push({key,source,label,dependsOn:Array.isArray(r.dependsOn)?r.dependsOn:[]})}};for(let adapter of this.adapters)ingest(adapter.contributors?.(),`adapter`,adapter.name??`adapter`);for(let plugin of this.plugins)ingest(plugin.contributors?.(),`plugin`,plugin.name??`plugin`);for(let{registration,label}of this._moduleContributors)ingest([registration],`module`,label);return ingest(this.options.contributors,`global`,`bootstrap`),out}getHttpServer(){return this.httpServer}shouldAutoMountRequestScope(){if(this.options.contextStore===`manual`)return!1;let userEntries=this.options.middlewares??this.options.middleware??[];for(let entry of userEntries)if(isRequestScopeMiddleware(typeof entry==`function`?entry:entry.handler))return!1;return!0}collectAdapterMiddleware(){let result={beforeGlobal:[],afterGlobal:[],beforeRoutes:[],afterRoutes:[]};for(let adapter of this.adapters){let entries=adapter.middleware?.()??[];for(let entry of entries)result[entry.phase??`afterGlobal`].push(entry)}return result}mountMiddlewareList(entries){for(let entry of entries){if(entry.path===void 0){this.runtime.useConnect(this.app,entry.handler);continue}this.runtime.useConnect(this.app,entry.handler,{path:entry.path})}}mountMiddlewareEntry(entry){typeof entry==`function`?this.runtime.useConnect(this.app,entry):this.runtime.useConnect(this.app,entry.handler,{path:entry.path})}requestTrackingMiddleware(){return(_req,res,next)=>{this._inFlightRequests++;let onFinish=()=>{if(res.removeListener(`finish`,onFinish),res.removeListener(`close`,onFinish),this._inFlightRequests--,this._draining&&this._inFlightRequests===0){for(let resolve of this._drainResolvers)resolve();this._drainResolvers=[]}};res.on(`finish`,onFinish),res.on(`close`,onFinish),next()}}mountHealthEndpoints(){let http=this.adapterHttp();http.route(`GET`,`/health/live`,ctx=>{this._draining?ctx.res.status(503).json({status:`draining`,uptime:process.uptime()}):ctx.json({status:`ok`,uptime:process.uptime()})}),http.route(`GET`,`/health/ready`,async ctx=>{if(this._draining){ctx.res.status(503).json({status:`draining`,checks:[]});return}let adaptersWithHealth=this.adapters.filter(a=>a.onHealthCheck),results=(await Promise.allSettled(adaptersWithHealth.map(a=>a.onHealthCheck()))).map((c,i)=>c.status===`fulfilled`?c.value:{name:adaptersWithHealth[i].name??`unknown`,status:`down`}),healthy=results.every(r=>r.status===`up`);ctx.res.status(healthy?200:503).json({status:healthy?`ready`:`degraded`,checks:results})})}};export{materializeRouter as i,buildRoutes as n,expressRuntime as r,Application as t};
12
+ //# sourceMappingURL=application-BU5N6o_M.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-BU5N6o_M.mjs","names":[],"sources":["../src/http/runtimes/express.ts","../src/http/application.ts"],"sourcesContent":["// The default Express runtime — the M1 reference implementation of HttpRuntime.\n//\n// Its route materializer rebuilds the exact `(req, res, next)` handler chain\n// the old `buildRoutes()` produced, so swapping decorators → RouteTable →\n// runtime is behavior-neutral under Express. `buildRoutes()` (the public,\n// Router-returning API) now lives here as a thin shim over `buildRouteTable()`\n// + this materializer.\n\nimport express, {\n Router,\n type Express,\n type Request,\n type Response,\n type NextFunction,\n type RequestHandler,\n} from 'express'\n\nimport { buildRouteTable, type BuildRoutesOptions } from '../router-builder'\nimport { RequestContext } from '../context'\nimport { validate } from '../middleware/validate'\nimport { buildUploadMiddleware } from '../middleware/upload'\nimport type {\n ConnectMiddleware,\n HttpRuntime,\n RouteEntry,\n RouteTable,\n RuntimeAppOptions,\n UseConnectOptions,\n} from '../runtime'\n\n/**\n * Materialize a controller's {@link RouteEntry}[] onto a fresh `express.Router`.\n * Reproduces the legacy handler ordering precisely: validation → upload →\n * `(ctx, next)` middleware → contributor runner → terminal handler. Each step\n * constructs its own `RequestContext` over the same `req`/`res` — request-scoped\n * state lives in the AsyncLocalStorage store, not on the ctx instance, so the\n * per-step instances share state exactly as before.\n */\nexport function materializeRouter(entries: RouteEntry[]): Router {\n const router = Router()\n\n for (const entry of entries) {\n const method = entry.method.toLowerCase() as 'get' | 'post' | 'put' | 'delete' | 'patch'\n const handlers: RequestHandler[] = []\n\n // Validation middleware (shared with the standalone validate() export).\n if (entry.meta.validation) {\n handlers.push(validate(entry.meta.validation))\n }\n\n // @FileUpload — auto-attach upload middleware from metadata.\n if (entry.meta.upload) {\n handlers.push(buildUploadMiddleware(entry.meta.upload))\n }\n\n // Class + method middleware — wrapped as Express middleware with error catching.\n for (const mw of entry.middlewares) {\n handlers.push((req: Request, res: Response, next: NextFunction) => {\n const ctx = new RequestContext(req, res, next)\n Promise.resolve(mw(ctx, next)).catch(next)\n })\n }\n\n // Context Contributor pipeline (#107) — runs, then advances the chain.\n if (entry.contributorRunner) {\n const run = entry.contributorRunner\n handlers.push(async (req: Request, res: Response, next: NextFunction) => {\n const ctx = new RequestContext(req, res, next)\n try {\n await run(ctx)\n next()\n } catch (err) {\n next(err)\n }\n })\n }\n\n // Terminal handler.\n handlers.push(async (req: Request, res: Response, next: NextFunction) => {\n const ctx = new RequestContext(req, res, next)\n try {\n await entry.handler(ctx)\n } catch (err) {\n next(err)\n }\n })\n ;(router as any)[method](entry.path, ...handlers)\n }\n\n return router\n}\n\n/**\n * Build an Express Router from a controller class decorated with @Get, @Post,\n * etc. The public, back-compatible entry point: a thin shim over\n * {@link buildRouteTable} + {@link materializeRouter}. Returns an\n * `express.Router` exactly as before — modules pass it to `app.use(path, router)`.\n *\n * @see buildRouteTable for the engine-neutral route-table form.\n */\nexport function buildRoutes(controllerClass: any, options: BuildRoutesOptions = {}): Router {\n return materializeRouter(buildRouteTable(controllerClass, options))\n}\n\n/**\n * The default HTTP runtime. Express stays a peer dependency of `@forinda/kickjs`;\n * apps that pass no `runtime` get this and behave exactly as before.\n */\nexport function expressRuntime(): HttpRuntime<Express> {\n return {\n name: 'express',\n\n createApp(options: RuntimeAppOptions = {}): Express {\n const app = express()\n // Engine hardening + config the Application used to apply directly.\n app.disable('x-powered-by')\n app.set('trust proxy', options.trustProxy ?? false)\n return app\n },\n\n nodeHandler(app) {\n return (req, res, next) => {\n if (next) {\n ;(app as any)(req, res, next)\n } else {\n ;(app as any)(req, res)\n }\n }\n },\n\n mountRoutes(app, table: RouteTable) {\n for (const { mountPath, routes } of table) {\n app.use(mountPath, materializeRouter(routes))\n }\n },\n\n useConnect(app, mw: ConnectMiddleware, opts: UseConnectOptions = {}) {\n if (opts.path !== undefined) {\n ;(app as any).use(opts.path, mw)\n } else {\n ;(app as any).use(mw)\n }\n },\n\n serveStatic(app, prefix, dir) {\n app.use(prefix, express.static(dir))\n },\n\n setNotFound(app, mw: ConnectMiddleware) {\n ;(app as any).use(mw)\n },\n\n setErrorHandler(app, mw: ConnectMiddleware) {\n ;(app as any).use(mw)\n },\n\n capabilities: {\n render: true,\n uploads: true,\n connectMiddleware: true,\n nativeBodyParsing: false,\n },\n }\n}\n","import http from 'node:http'\nimport express, { type Express, type RequestHandler } from 'express'\nimport {\n Container,\n createLogger,\n Logger,\n normalizePath,\n tokenName,\n METADATA,\n type AppModule,\n type AppModuleClass,\n type AppModuleEntry,\n type AppAdapter,\n type AdapterContext,\n type AdapterMiddleware,\n type ContributorRegistrations,\n type KickPlugin,\n type ModuleRegistry,\n type RouteDefinition,\n type SourcedRegistration,\n mountSort,\n MutableModuleRegistry,\n} from '../core'\nimport { moduleRouteMissingControllerError } from '../core/kick-errors'\nimport { getClassMeta } from '../core/metadata'\nimport { requestId } from './middleware/request-id'\nimport { notFoundHandler, errorHandler } from './middleware/error-handler'\nimport { requestScopeMiddleware, isRequestScopeMiddleware } from './middleware/request-scope'\nimport { _setExternalContributorSources, buildRouteTable } from './router-builder'\nimport { expressRuntime } from './runtimes/express'\nimport type { ActiveRuntime, AdapterHttp, HttpRuntime, RouteEntry } from './runtime'\nimport { requestStore } from './request-store'\n\nconst log = createLogger('Application')\n\n/**\n * A middleware entry in the declarative pipeline.\n * Can be a bare handler or an object with path scoping.\n */\nexport type MiddlewareEntry = RequestHandler | { path: string; handler: RequestHandler }\n\nexport interface ApplicationOptions {\n /**\n * Feature modules to load. Accepts both class form\n * (`SomeModule extends AppModule`, instantiated via `new`) and\n * instance form (output of {@link defineModule}'s factory call,\n * e.g. `TasksModule({ scope: 'admin' })`) — the loader discriminates\n * and either `new`-s the class or uses the instance directly.\n *\n * Static path — for conditional / dynamic registration, use the\n * {@link ApplicationOptions.setup} callback instead.\n */\n modules: AppModuleEntry[]\n\n /**\n * Imperative module registration callback. Receives a\n * {@link ModuleRegistry} you call `.mount(module)` on to register\n * modules conditionally — based on env flags, runtime config, a\n * tenant list, etc. Runs after every plugin's `setup()` hook and\n * after the static `modules: [...]` array is collected.\n *\n * @example\n * ```ts\n * bootstrap({\n * modules: [HelloModule()],\n * setup(registry) {\n * if (env.ENABLE_ADMIN) registry.mount(AdminModule())\n * },\n * })\n * ```\n */\n setup?(registry: ModuleRegistry): void\n /** Adapters that hook into the lifecycle (DB, Redis, Swagger, etc.) */\n adapters?: AppAdapter[]\n /** Server port (falls back to PORT env var, then 3000) */\n port?: number\n /** Global API prefix (default: '/api') */\n apiPrefix?: string\n /** Default API version (default: 1) — routes become /{prefix}/v{version}/{path} */\n defaultVersion?: number\n\n /**\n * Global middleware pipeline. Declared in order.\n * Replaces the hardcoded middleware stack — you control exactly what runs.\n *\n * @example\n * ```ts\n * bootstrap({\n * modules,\n * middlewares: [\n * helmet(),\n * cors(),\n * compression(),\n * morgan('dev'),\n * express.json({ limit: '1mb' }),\n * ],\n * })\n * ```\n *\n * If omitted, a sensible default is applied:\n * requestId(), express.json({ limit: '100kb' })\n */\n middlewares?: MiddlewareEntry[]\n /**\n * @deprecated Use {@link ApplicationOptions.middlewares} (plural).\n * Kept as an alias for back-compat; `middlewares` wins when both are\n * set.\n */\n middleware?: MiddlewareEntry[]\n\n /** Plugins that bundle modules, adapters, middleware, and DI bindings */\n plugins?: KickPlugin[]\n\n /**\n * Global Context Contributors (#107) that apply to every route in the\n * application. Merge into the per-route pipeline at the `'global'`\n * precedence level — they lose to module, adapter, class, and method\n * contributors with the same key, providing app-wide defaults that any\n * narrower scope can override.\n *\n * @example\n * ```ts\n * const StartedAt = defineContextDecorator({\n * key: 'requestStartedAt',\n * resolve: () => Date.now(),\n * })\n *\n * bootstrap({\n * modules,\n * contributors: [StartedAt.registration],\n * })\n * ```\n */\n contributors?: ContributorRegistrations\n\n /**\n * Backing store strategy for {@link RequestContext} `set/get` and the\n * Context Contributor pipeline (#107).\n *\n * - `'auto'` (default) — Application mounts {@link requestScopeMiddleware}\n * automatically before any user middleware. If the user-supplied\n * `middleware` list already includes `requestScopeMiddleware()`,\n * detection skips the auto-mount so adopters can control its position.\n * - `'manual'` — Application never mounts the wrapper. The Context\n * Contributor pipeline still runs on every route — the runner is\n * inserted by `router-builder` regardless of ALS state. What\n * degrades without an ALS frame is the *backing store*:\n * REQUEST-scoped DI throws (no `requestStore.getStore()` to read\n * from) and `RequestContext.set/get` throws. Use `'manual'` only when you\n * genuinely intend to wrap requests in your own ALS frame (rare —\n * multi-tenant adapters used to do this; post-Phase 3 they share\n * the framework's frame instead).\n */\n contextStore?: 'auto' | 'manual'\n\n /**\n * Controls whether KickJS registers process-level handlers at bootstrap.\n *\n * - `'auto'` (default) — register `uncaughtException` /\n * `unhandledRejection` loggers AND `SIGINT` / `SIGTERM` →\n * `app.shutdown()` → `process.exit(0)`.\n * - `'errors-only'` — register the error loggers; skip the signal\n * handlers. Use this when you have your own shutdown choreographer\n * (OpenTelemetry SDK, Sentry, custom orchestrator) that calls\n * `app.shutdown()` itself and you don't want two listeners racing\n * to call `process.exit`.\n * - `'manual'` — skip everything. Adopter is responsible for both\n * error logging and signal-driven shutdown.\n *\n * Background: many observability SDKs install their own SIGTERM\n * handler to flush spans/metrics before the process exits. Two\n * separate handlers calling `process.exit(0)` race each other and\n * can truncate the in-flight flush. Setting this to `'errors-only'`\n * or `'manual'` lets the SDK own the lifecycle while still letting\n * KickJS surface uncaught exceptions / rejections via the logger.\n *\n * The dev mode auto-detect (`__kickjs_httpServer` set by the Vite\n * plugin) suppresses signal registration regardless of this option,\n * since Vite owns the lifecycle in development.\n */\n processHooks?: 'auto' | 'errors-only' | 'manual'\n\n /**\n * The HTTP engine driver. Defaults to {@link expressRuntime} — Express stays\n * the zero-config default, so existing apps are unaffected.\n *\n * Any `HttpRuntime` is accepted — pass `fastifyRuntime()` (from\n * `@forinda/kickjs/fastify`) or a custom engine driver. Defaults to\n * {@link expressRuntime}. The engine-native escape hatches\n * (`getRuntimeApp()`, `AdapterContext.app`) follow the active runtime via the\n * registry (`ActiveRuntime`, spec §4.3b) — Express by default, or the augmented\n * engine once the `kick/runtime` typegen output is present.\n */\n runtime?: HttpRuntime\n\n /** Express `trust proxy` setting */\n trustProxy?: boolean | number | string | ((ip: string, hopIndex: number) => boolean)\n /** Maximum JSON body size (only used when middleware is not provided) */\n jsonLimit?: string | number\n /**\n * Print the route table on startup. Default: `false`. Set to `true`\n * to log a per-controller summary (method counts + mount paths) once\n * the app has mounted. Emitted at `info` level, so it is still subject\n * to `LOG_LEVEL` filtering (visible at the default `info`; hidden at\n * `warn`/`error`/`silent`).\n */\n logRouteTable?: boolean\n /**\n * @deprecated Use {@link ApplicationOptions.logRouteTable}. Kept as an\n * alias for back-compat; `logRouteTable` wins when both are set.\n */\n logRoutesTable?: boolean\n /**\n * Maximum time (ms) to wait for graceful shutdown before forcing exit.\n * Default: 30000 (30 seconds). Set to 0 to disable forced exit.\n */\n shutdownTimeout?: number\n\n /**\n * Enable cluster mode for multi-core utilization.\n *\n * When enabled, the primary process forks worker processes that share the\n * same port via Node's built-in `cluster` module (OS load balancing).\n *\n * - `true` — use all available CPU cores\n * - `{ workers: N }` — use exactly N workers\n *\n * Workers are auto-restarted on crash. SIGTERM/SIGINT on the primary is\n * forwarded to all workers.\n *\n * @example\n * ```ts\n * bootstrap({ modules, cluster: true })\n * bootstrap({ modules, cluster: { workers: 4 } })\n * ```\n */\n cluster?: boolean | { workers?: number }\n\n /**\n * Custom 404 handler for unmatched routes. Receives the raw Express\n * `(req, res, next)` args. When omitted, the built-in handler returns\n * `{ message: 'Not Found' }` with status 404.\n *\n * @example\n * ```ts\n * bootstrap({\n * modules,\n * onNotFound: (req, res) => {\n * res.status(404).json({ error: 'Route not found', path: req.originalUrl })\n * },\n * })\n * ```\n */\n onNotFound?: (req: any, res: any, next: any) => void\n\n /**\n * Custom global error handler. Receives `(err, req, res, next)` — the\n * standard Express error-handling signature. When omitted, the built-in\n * handler formats ZodError, HttpException, and unexpected errors.\n *\n * @example\n * ```ts\n * bootstrap({\n * modules,\n * onError: (err, req, res, next) => {\n * logger.error(err)\n * res.status(err.status ?? 500).json({ error: err.message })\n * },\n * })\n * ```\n */\n onError?: (err: any, req: any, res: any, next: any) => void\n\n /**\n * Security defaults applied automatically unless opted out.\n *\n * When not specified, secure defaults are applied:\n * - Helmet security headers are auto-injected\n * - JSON body limit defaults to 1MB\n *\n * @example\n * ```ts\n * bootstrap({\n * modules,\n * security: {\n * helmet: false, // disable auto-helmet\n * },\n * })\n * ```\n */\n security?: {\n /** Auto-inject helmet security headers. Default: true */\n helmet?: boolean\n }\n}\n\n/**\n * The main application class. Wires together Express, the DI container,\n * feature modules, adapters, and the middleware pipeline.\n */\nexport class Application {\n private app: Express\n /** The HTTP engine driver. Defaults to {@link expressRuntime}. */\n private readonly runtime: HttpRuntime\n private container: Container\n private httpServer: http.Server | null = null\n private readonly adapters: AppAdapter[]\n\n private readonly plugins: KickPlugin[]\n\n /**\n * Snapshot of every module-level Context Contributor registration\n * captured during `setup()`. The registrations themselves are\n * frozen by `defineContextDecorator`, so storing references is\n * safe — they outlive the module instances they came from.\n *\n * Used by {@link getContributors} so DevTools and adopter tooling\n * can render the module-level contributors alongside the adapter /\n * plugin / global ones. Populated once per `setup()` call; cleared\n * at the start of each invocation so a re-setup (test harnesses,\n * dev-server restarts) doesn't accumulate stale entries.\n */\n private _moduleContributors: Array<{\n registration: { key: string; dependsOn: readonly string[] }\n label: string\n }> = []\n\n /** Number of HTTP requests currently being processed */\n private _inFlightRequests = 0\n /** Whether the application is draining (shutting down gracefully) */\n private _draining = false\n /** Whether shutdown has already been initiated (prevents double-shutdown) */\n private _shutdownInitiated = false\n /** Resolvers waiting for in-flight requests to reach zero */\n private _drainResolvers: Array<() => void> = []\n\n constructor(private readonly options: ApplicationOptions) {\n this.runtime = options.runtime ?? expressRuntime()\n // `this.app` is the engine-native app; typed Express here (the default) for\n // the legacy escape hatches. Under another runtime it holds that engine's\n // app — `getRuntimeApp()` / `AdapterContext.app` expose it via ActiveRuntime.\n this.app = this.runtime.createApp({ trustProxy: options.trustProxy }) as Express\n this.container = Container.getInstance()\n\n // Sort plugins by `dependsOn` declarations BEFORE reading their adapters/etc.\n // Plugins without `dependsOn` keep their declaration order — this is a\n // pure refinement; no behaviour change for apps that don't use the field.\n this.plugins = mountSort(options.plugins ?? [], 'plugin')\n\n // Build adapter list from plugin adapters + user adapters, synthesize\n // a stable name for any anonymous adapter (so duplicate-name detection\n // and `dependsOn` resolution have something to key on), then sort by\n // adapter `dependsOn`. Plugin-shipped adapters keep their plugin's\n // relative order unless their own `dependsOn` says otherwise.\n const allAdapters = [\n ...this.plugins.flatMap((p) => p.adapters?.() ?? []),\n ...(options.adapters ?? []),\n ]\n let anonAdapterCount = 0\n const namedAdapters: Array<AppAdapter & { name: string }> = allAdapters.map((adapter) => {\n if (!adapter.name) {\n // `constructor.name === 'Object'` for plain object-literal adapters —\n // useless as an identity since two anonymous literals would collide.\n // Only borrow the constructor name when it's an actual class.\n const ctorName = adapter.constructor?.name\n const fallback =\n ctorName && ctorName !== 'Object' ? ctorName : `AnonymousAdapter#${anonAdapterCount++}`\n return Object.assign(adapter, { name: fallback })\n }\n return adapter as AppAdapter & { name: string }\n })\n this.adapters = mountSort(namedAdapters, 'adapter')\n // Wire the request store provider so Container can resolve REQUEST-scoped deps\n Container._requestStoreProvider = () => requestStore.getStore() ?? null\n }\n\n /** Whether the application is currently draining in-flight requests */\n get isDraining(): boolean {\n return this._draining\n }\n\n /** Number of HTTP requests currently being processed */\n get inFlightRequests(): number {\n return this._inFlightRequests\n }\n\n /** Get the DI container instance */\n getContainer(): Container {\n return this.container\n }\n\n /**\n * Express request handler — delegates to the internal Express app.\n *\n * Used by the Vite dev-server plugin to route requests through KickJS:\n * ```ts\n * const mod = await ssrLoadModule('virtual:kickjs/app')\n * mod.app.handle(req, res, next)\n * ```\n *\n * Also works as a standard Node.js request handler for production:\n * ```ts\n * http.createServer(app.handle.bind(app))\n * ```\n */\n handle(req: http.IncomingMessage, res: http.ServerResponse, next?: (err?: any) => void): void {\n const handler = this.runtime.nodeHandler(this.app)\n if (next) {\n handler(req, res, next)\n } else {\n handler(req, res)\n }\n }\n\n /**\n * Full setup pipeline:\n * 1. Adapter beforeMount hooks (early routes — docs, health)\n * 2. Adapter middleware (phase: beforeGlobal)\n * 3. Global middleware (user-declared or defaults)\n * 4. Adapter middleware (phase: afterGlobal)\n * 5. Module registration + DI bootstrap\n * 6. Adapter middleware (phase: beforeRoutes)\n * 7. Module route mounting\n * 8. Adapter middleware (phase: afterRoutes)\n * 9. Error handlers (notFound + global)\n * 10. Adapter beforeStart hooks\n */\n /** Build the adapter context object (shared across all hooks) */\n private adapterCtx(server?: any): AdapterContext {\n const env = process.env.NODE_ENV ?? 'development'\n return {\n http: this.adapterHttp(),\n app: this.app,\n container: this.container,\n server,\n env,\n isProduction: env === 'production',\n }\n }\n\n /**\n * The engine-agnostic HTTP surface handed to adapters as `ctx.http`. Each\n * call routes through the active runtime over the current `this.app`, so an\n * adapter written against this works under any runtime.\n */\n private adapterHttp(): AdapterHttp {\n return {\n route: (method, path, handler) => {\n const entry: RouteEntry = {\n method,\n path,\n middlewares: [],\n contributorRunner: null,\n handler,\n meta: {},\n }\n this.runtime.mountRoutes(this.app, [{ mountPath: '/', routes: [entry] }])\n },\n mount: (prefix, routes) => {\n this.runtime.mountRoutes(this.app, [{ mountPath: prefix, routes }])\n },\n serveStatic: (prefix, dir) => {\n this.runtime.serveStatic(this.app, prefix, dir)\n },\n use: (mw, opts) => {\n this.runtime.useConnect(this.app, mw, opts)\n },\n }\n }\n\n /** Call an adapter hook, awaiting async hooks and catching errors */\n private async callHook(\n hook: ((ctx: AdapterContext) => void | Promise<void>) | undefined,\n ctx: AdapterContext,\n ): Promise<void> {\n if (!hook) return\n try {\n const result = hook(ctx)\n if (result && typeof (result as Promise<void>).then === 'function') {\n await result\n }\n } catch (err) {\n log.error(err, 'Adapter hook failed')\n }\n }\n\n async setup(): Promise<void> {\n log.debug('Bootstrapping application...')\n\n // Reset module-contributor snapshot at the very top of each\n // setup pass — before anything that could throw — so a partial\n // failure doesn't leave stale entries that getContributors()\n // would surface on the next call. See _moduleContributors field\n // declaration for the use case.\n this._moduleContributors = []\n\n // Collect adapter middleware by phase\n const adapterMw = this.collectAdapterMiddleware()\n\n // Expose the Application instance on the Express app for adapter discovery\n ;(this.app as any).__kickApp = this\n\n const ctx = this.adapterCtx()\n\n // ── 1. Adapter beforeMount hooks ──────────────────────────────────\n for (const adapter of this.adapters) {\n await this.callHook(adapter.beforeMount?.bind(adapter), ctx)\n }\n\n // ── 2. Hardened defaults ──────────────────────────────────────────\n // x-powered-by disable + trust proxy now live in `runtime.createApp()`.\n\n // ── 2a. In-flight request tracking ──────────────────────────────\n this.runtime.useConnect(this.app, this.requestTrackingMiddleware())\n\n // ── 2b. Health check endpoints (before middleware, at root) ──────\n this.mountHealthEndpoints()\n\n // ── 2c. Request scope (AsyncLocalStorage) ────────────────────────\n // Auto-mounted unless the user opted out (`contextStore: 'manual'`)\n // or already included one in their middleware list.\n if (this.shouldAutoMountRequestScope()) {\n this.runtime.useConnect(this.app, requestScopeMiddleware())\n }\n\n // ── 3. Adapter middleware: beforeGlobal ───────────────────────────\n this.mountMiddlewareList(adapterMw.beforeGlobal)\n\n // ── 3b. Plugin registration ──────────────────────────────────────\n for (const plugin of this.plugins) {\n plugin.register?.(this.container)\n }\n\n // ── 3c. Plugin middleware ─────────────────────────────────────────\n for (const plugin of this.plugins) {\n try {\n const mw = plugin.middleware?.() ?? []\n for (const handler of mw) {\n this.runtime.useConnect(this.app, handler)\n }\n } catch (err) {\n log.error(err, `Plugin middleware failed: ${(plugin as any).name ?? 'unknown'}`)\n }\n }\n\n // ── 4. Global middleware ─────────────────────────────────────────\n // Auto-inject helmet unless opted out\n const autoHelmet = this.options.security?.helmet !== false\n if (autoHelmet) {\n try {\n const { helmet: helmetFn } = await import('./middleware/helmet')\n this.runtime.useConnect(this.app, helmetFn())\n } catch {\n // helmet middleware not available — skip silently\n }\n }\n\n const userMiddlewares = this.options.middlewares ?? this.options.middleware\n if (userMiddlewares) {\n // User-declared pipeline — full control\n for (const entry of userMiddlewares) {\n this.mountMiddlewareEntry(entry)\n }\n } else {\n // Sensible defaults when no middleware declared\n this.runtime.useConnect(this.app, requestId())\n // Skip express.json on engines that parse bodies natively (Fastify, h3) —\n // otherwise the body stream is read twice and the engine's parser hangs.\n if (!this.runtime.capabilities.nativeBodyParsing) {\n this.runtime.useConnect(this.app, express.json({ limit: this.options.jsonLimit ?? '1mb' }))\n }\n }\n\n // ── 5. Adapter middleware: afterGlobal ────────────────────────────\n this.mountMiddlewareList(adapterMw.afterGlobal)\n\n // ── 6. Module registration + DI bootstrap ────────────────────────\n // Module collection — the static `modules: [...]` array AND the\n // imperative `setup(registry)` callback feed into the same\n // ordered list. Plugins go first so plugin modules / setup\n // calls run before user code (existing precedence).\n //\n // Order within the registry:\n // 1. plugin static modules (`plugin.modules?()`)\n // 2. plugin setup() calls (in plugin dependsOn-sorted order)\n // 3. user static modules (`options.modules`)\n // 4. user setup() callback\n const moduleRegistry = new MutableModuleRegistry()\n for (const plugin of this.plugins) {\n for (const m of plugin.modules?.() ?? []) moduleRegistry.mount(m)\n plugin.setup?.(moduleRegistry)\n }\n for (const m of this.options.modules) moduleRegistry.mount(m)\n this.options.setup?.(moduleRegistry)\n const allModuleEntries: AppModuleEntry[] = moduleRegistry.entries\n const modules = allModuleEntries.map((entry) => {\n // Discriminate class vs instance: classes are functions whose\n // `prototype` carries the AppModule shape; defineModule output is\n // a plain object with `routes`, `register`, `contributors`. Calling\n // `new` on a plain object throws, so we branch up-front rather\n // than try/catch.\n const mod: AppModule = typeof entry === 'function' ? new (entry as AppModuleClass)() : entry\n // `register()` is optional — modules whose classes are entirely\n // decorator-managed (@Service, @Controller, @Repository) don't need it.\n mod.register?.(this.container)\n return mod\n })\n this.container.bootstrap()\n\n // Register Logger as an injectable singleton so @Inject(Logger)\n // works in constructors. Without this, Logger is just a plain\n // class with static methods and no DI binding.\n if (!this.container.has(Logger)) {\n this.container.registerInstance(Logger, new Logger())\n }\n\n // ── 7. Adapter middleware: beforeRoutes ───────────────────────────\n this.mountMiddlewareList(adapterMw.beforeRoutes)\n\n // ── 8. Mount module routes with versioning ───────────────────────\n const apiPrefix = this.options.apiPrefix ?? '/api'\n const defaultVersion = this.options.defaultVersion ?? 1\n // Opt-in, default off. `logRouteTable` is the current name;\n // `logRoutesTable` is the deprecated alias.\n const shouldLogRoutes = this.options.logRouteTable ?? this.options.logRoutesTable ?? false\n\n // Collect route metadata during mounting (avoids calling mod.routes() twice)\n const mountedRoutes: Array<{ controller: any; mountPath: string }> = []\n\n // Context Contributors (#107) — collect adapter + plugin + global once;\n // per-module sources are computed inside the loop so module isolation is\n // preserved.\n //\n // Plugin contributors merge at the same `'adapter'` precedence as adapter\n // contributors. Plugins are conceptually \"bundles of adapters + extras\",\n // so a plugin that ships a typed contributor without standing up an\n // accompanying adapter behaves identically to one that does.\n const adapterSources: SourcedRegistration[] = []\n for (const adapter of this.adapters) {\n const adapterContribs = adapter.contributors?.() ?? []\n const adapterLabel = adapter.name ?? adapter.constructor.name ?? 'adapter'\n for (const registration of adapterContribs) {\n adapterSources.push({ source: 'adapter', registration, label: adapterLabel })\n }\n }\n for (const plugin of this.plugins) {\n const pluginContribs = plugin.contributors?.() ?? []\n const pluginLabel = plugin.name ?? plugin.constructor?.name ?? 'plugin'\n for (const registration of pluginContribs) {\n adapterSources.push({ source: 'adapter', registration, label: pluginLabel })\n }\n }\n const globalSources: SourcedRegistration[] = (this.options.contributors ?? []).map(\n (registration): SourcedRegistration => ({\n source: 'global',\n registration,\n label: 'bootstrap',\n }),\n )\n\n // Reset module-contributor snapshot at the start of each setup\n // pass so re-running `setup()` (test harnesses, dev-server\n // restarts) doesn't accumulate stale entries.\n this._moduleContributors = []\n\n for (const mod of modules) {\n // Prefer the declared `name` field (set by `defineModule({ name: 'X', ... })`)\n // over `constructor.name`. Factory-built modules are plain objects whose\n // constructor is `Object` — falling straight to `constructor.name` would\n // degrade every label in the DevTools Contributors table to \"Object\".\n const declaredName = (mod as { name?: unknown }).name\n const ctorName = mod.constructor?.name\n const moduleLabel =\n typeof declaredName === 'string' && declaredName.length > 0\n ? declaredName\n : ctorName && ctorName !== 'Object'\n ? ctorName\n : 'module'\n const moduleSources: SourcedRegistration[] = (mod.contributors?.() ?? []).map(\n (registration): SourcedRegistration => ({\n source: 'module',\n registration,\n label: moduleLabel,\n }),\n )\n // Retain registrations for `getContributors()` — these would\n // otherwise be unreachable post-bootstrap (module instances\n // are not kept on the Application).\n for (const src of moduleSources) {\n this._moduleContributors.push({\n registration: src.registration as { key: string; dependsOn: readonly string[] },\n label: moduleLabel,\n })\n }\n\n // Thread per-module + adapter + global sources to buildRoutes via the\n // module-scoped slot. Module setup is sequential, so the slot is\n // race-free. The slot MUST stay populated across both `mod.routes()`\n // AND any framework-driven `buildRoutes(controller)` calls below —\n // when a module returns `{ path, controller }` (auto-derive shape),\n // buildRoutes runs here, not inside routes(). Clearing the slot in\n // the routes()-finally would drop module/adapter/global contributors\n // on the floor and surface as `MissingContributorError` for any\n // class/method-level dependsOn referencing a module-level key.\n _setExternalContributorSources([...moduleSources, ...adapterSources, ...globalSources])\n try {\n const result = mod.routes()\n if (!result) continue // Non-HTTP modules (queues, cron) may return null\n\n const routeSets = Array.isArray(result) ? result : [result]\n\n for (const route of routeSets) {\n const version = route.version ?? defaultVersion\n const mountPath = `${apiPrefix}/v${version}${normalizePath(route.path)}`\n // Common-case `{ path, controller }`: build the engine-neutral route\n // table and let the runtime materialize it natively (Express Router /\n // Fastify routes / …). Adopters who hand-build a `router` (composing\n // multiple controllers, third-party routers) pass it explicitly — that\n // is an Express-specific connect handler, mounted via `useConnect`.\n if (route.router) {\n this.runtime.useConnect(this.app, route.router, { path: mountPath })\n } else if (route.controller) {\n this.runtime.mountRoutes(this.app, [\n { mountPath, routes: buildRouteTable(route.controller) },\n ])\n } else {\n throw moduleRouteMissingControllerError(mountPath)\n }\n\n // Notify adapters (e.g. SwaggerAdapter for OpenAPI spec generation)\n if (route.controller) {\n for (const adapter of this.adapters) {\n try {\n adapter.onRouteMount?.(route.controller, mountPath)\n } catch (err) {\n log.error(err, `adapter.onRouteMount() failed for ${mountPath}`)\n }\n }\n if (shouldLogRoutes) {\n mountedRoutes.push({ controller: route.controller, mountPath })\n }\n }\n }\n } finally {\n _setExternalContributorSources([])\n }\n }\n\n // ── 8b. Log route summary ─────────────────────────────────────────\n if (shouldLogRoutes && mountedRoutes.length > 0) {\n const methodOrder = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']\n const methodRank = (m: string) => {\n const i = methodOrder.indexOf(m)\n return i === -1 ? 99 : i\n }\n\n let totalRoutes = 0\n log.info('Routes:')\n\n for (const { controller, mountPath } of mountedRoutes) {\n const defs: RouteDefinition[] = getClassMeta<RouteDefinition[]>(\n METADATA.ROUTES,\n controller,\n [],\n )\n if (defs.length === 0) continue\n\n const counts: Record<string, number> = {}\n for (const def of defs) {\n const m = def.method.toUpperCase()\n counts[m] = (counts[m] || 0) + 1\n }\n totalRoutes += defs.length\n\n const methods = Object.entries(counts)\n .toSorted(([a], [b]) => methodRank(a) - methodRank(b))\n .map(([m, n]) => `${n} ${m}`)\n .join(', ')\n const name = controller.name || 'Controller'\n log.info(` ${name.padEnd(30)} ${mountPath.padEnd(25)} ${defs.length} routes (${methods})`)\n }\n\n log.info(` Total: ${totalRoutes} routes`)\n }\n\n // ── 9. Adapter middleware: afterRoutes ────────────────────────────\n this.mountMiddlewareList(adapterMw.afterRoutes)\n\n // ── 10. Adapter beforeStart hooks ────────────────────────────────\n // Runs BEFORE error handlers so adapters can still mount Express\n // routes (e.g. `McpAdapter` registers `/_mcp/messages` here). If\n // error handlers were registered first, the notFoundHandler — a\n // catch-all that never calls next() — would pre-empt anything an\n // adapter adds afterwards and adapter-mounted endpoints would 404.\n for (const adapter of this.adapters) {\n await this.callHook(adapter.beforeStart?.bind(adapter), ctx)\n }\n\n // ── 11. Error handlers ───────────────────────────────────────────\n // Last in the chain so any adapter-mounted route (step 10) gets\n // a chance to match before the catch-all 404 fires.\n this.runtime.setNotFound(this.app, this.options.onNotFound ?? notFoundHandler())\n this.runtime.setErrorHandler(this.app, this.options.onError ?? errorHandler())\n }\n\n /** Register modules and DI without starting the HTTP server (used by kick tinker) */\n async registerOnly(): Promise<void> {\n await this.setup()\n }\n\n /**\n * Start the HTTP server.\n *\n * In **dev mode** (Vite plugin active): reuses `globalThis.__kickjs_httpServer`\n * created by Vite. Adapters (WsAdapter, Socket.IO, etc.) receive the real\n * `http.Server` through `afterStart({ server })` — zero adapter changes needed.\n *\n * In **production**: creates its own `http.Server` and binds to the port.\n */\n async start(): Promise<void> {\n await this.setup()\n\n const g = globalThis as any\n\n if (g.__kickjs_httpServer) {\n // ── DEV MODE: Vite owns the http.Server ──────────────────────\n // Don't create a new server or listen — Vite is already listening.\n // Just wire up adapters with the Vite-created server.\n this.httpServer = g.__kickjs_httpServer\n log.debug('Attached to Vite dev server')\n\n // Dev mode suppresses our own SIGINT/SIGTERM handlers (Vite owns\n // the process lifecycle), so a Ctrl+C would otherwise skip graceful\n // shutdown entirely — `adapter.shutdown()`, request draining, and\n // any shutdown logs never run. Expose `shutdown()` on globalThis so\n // the CLI dev server (`kick dev`) can drive it before tearing down\n // Vite. Same process, so the CLI's signal handler can reach this.\n g.__kickjs_app_shutdown = () => this.shutdown()\n\n for (const adapter of this.adapters) {\n const ctx = this.adapterCtx(this.httpServer!)\n await this.callHook(adapter.afterStart?.bind(adapter), ctx)\n }\n\n for (const plugin of this.plugins) {\n await plugin.onReady?.(this.container)\n }\n\n return\n }\n\n // ── PRODUCTION: Create and own the http.Server ─────────────────\n const port = this.options.port ?? parseInt(process.env.PORT || '3000', 10)\n this.httpServer = http.createServer(this.runtime.nodeHandler(this.app))\n\n this.httpServer.on('error', (err: NodeJS.ErrnoException) => {\n if (err.code === 'EADDRINUSE') {\n log.error(\n `Port ${port} is already in use. Kill the existing process or use a different port:\\n` +\n ` PORT=${port + 1} kick dev\\n` +\n ` lsof -i :${port} # find what's using it\\n` +\n ` kill <PID> # stop it`,\n )\n process.exit(1)\n }\n throw err\n })\n\n // Wrap listen in a Promise so afterStart/onReady errors propagate\n await new Promise<void>((resolve, reject) => {\n this.httpServer!.listen(port, async () => {\n try {\n log.info(`Server running on http://localhost:${port}`)\n\n for (const adapter of this.adapters) {\n const afterCtx = this.adapterCtx(this.httpServer!)\n await this.callHook(adapter.afterStart?.bind(adapter), afterCtx)\n }\n\n // Plugin onReady hooks\n for (const plugin of this.plugins) {\n await plugin.onReady?.(this.container)\n }\n\n resolve()\n } catch (err) {\n reject(err)\n }\n })\n })\n }\n\n /** HMR rebuild: swap Express handler without restarting the server */\n async rebuild(): Promise<void> {\n // Build the new app fully before swapping — if setup() throws,\n // the old app keeps running so the server stays responsive.\n const prevApp = this.app\n const prevContainer = this.container\n\n try {\n Container.reset()\n this.container = Container.getInstance()\n this.app = this.runtime.createApp({ trustProxy: this.options.trustProxy }) as Express\n await this.setup()\n } catch (err) {\n log.error(err, 'HMR rebuild failed, keeping previous app')\n // Restore previous state so the server stays responsive\n this.app = prevApp\n this.container = prevContainer\n return\n }\n\n if (this.httpServer) {\n this.httpServer.removeAllListeners('request')\n this.httpServer.on('request', this.runtime.nodeHandler(this.app))\n log.debug('HMR: app rebuilt and swapped')\n }\n }\n\n /**\n * Graceful shutdown with request draining.\n *\n * 1. Stops accepting new connections (server.close())\n * 2. Waits for in-flight requests to complete (up to shutdownTimeout)\n * 3. Calls adapter.shutdown() for all registered adapters\n * 4. Force-closes after timeout\n *\n * Safe to call multiple times — subsequent calls return the same promise.\n */\n async shutdown(): Promise<void> {\n // Prevent double-shutdown — return immediately if already initiated\n if (this._shutdownInitiated) {\n log.debug('Shutdown already in progress, skipping duplicate call')\n return\n }\n this._shutdownInitiated = true\n this._draining = true\n\n log.debug('Shutting down — draining in-flight requests...')\n\n const timeoutMs = this.options.shutdownTimeout ?? 30_000\n let timer: ReturnType<typeof setTimeout> | undefined\n\n // Start a force-exit timer if timeout is configured\n const forceExitPromise =\n timeoutMs > 0\n ? new Promise<'timeout'>((resolve) => {\n timer = setTimeout(() => resolve('timeout'), timeoutMs)\n timer.unref()\n })\n : new Promise<never>(() => {}) // never resolves — no forced exit\n\n try {\n // Step 1: Stop accepting new connections.\n // server.close() prevents new connections. Its callback fires only when\n // ALL existing connections are fully closed, so we do NOT await it here —\n // we track request draining separately via the tracking middleware.\n if (this.httpServer) {\n this.httpServer.close(() => {})\n }\n\n // Step 2: Wait for in-flight requests to drain (or timeout)\n if (this._inFlightRequests > 0) {\n log.debug(`Waiting for ${this._inFlightRequests} in-flight request(s) to complete...`)\n const drainPromise = new Promise<'drained'>((resolve) => {\n this._drainResolvers.push(() => resolve('drained'))\n })\n\n const result = await Promise.race([drainPromise, forceExitPromise])\n if (result === 'timeout') {\n log.warn(\n `Shutdown timeout (${timeoutMs}ms) reached with ${this._inFlightRequests} request(s) still in-flight, forcing shutdown`,\n )\n } else {\n log.debug('All in-flight requests completed')\n }\n }\n\n // Step 3: Run all plugin + adapter shutdowns concurrently\n const results = await Promise.allSettled([\n ...this.plugins.map((plugin) => Promise.resolve(plugin.shutdown?.())),\n ...this.adapters.map((adapter) => Promise.resolve(adapter.shutdown?.())),\n ])\n for (const result of results) {\n if (result.status === 'rejected') {\n log.error({ err: result.reason }, 'Adapter shutdown failed')\n }\n }\n } finally {\n if (timer) clearTimeout(timer)\n }\n }\n\n /**\n * The engine-native app instance, typed from the active runtime\n * ({@link ActiveRuntime} — Express by default). Prefer this over\n * {@link getExpressApp}; under a non-Express runtime the type follows the\n * augmented registry.\n */\n getRuntimeApp(): ActiveRuntime['app'] {\n return this.app\n }\n\n /** @deprecated Use {@link getRuntimeApp}. Returns the engine-native app. */\n getExpressApp(): Express {\n return this.app\n }\n\n /** Get registered adapters — used by DevToolsAdapter for peer discovery */\n getAdapters(): AppAdapter[] {\n return this.adapters\n }\n\n /**\n * Get registered plugins — used by DevToolsAdapter for topology\n * introspection (architecture.md §23). Read-only; returns the\n * already-sorted plugin list (post-`dependsOn` topo-sort).\n */\n getPlugins(): readonly KickPlugin[] {\n return this.plugins\n }\n\n /**\n * Snapshot of every Context Contributor reachable from this app —\n * walks **four** registration sites: adapters, plugins, modules,\n * and the bootstrap `contributors` option. The devtools Topology\n * tab consumes this for the Contributors panel; tests + adopters\n * can call it for diagnostics.\n *\n * Per-route (method/class-decorator) registrations are NOT included\n * here — they live on the route registry rather than on any of\n * the four collection sites this method walks. A future RPC will\n * surface them separately.\n *\n * Result shape stays minimal — `{ key, source, label, dependsOn }`\n * — so we don't leak `resolve` closures or other internal fields.\n * `source` matches the five-level precedence union from\n * `ContributorSource` (minus `'method'` / `'class'` which require\n * the per-route walk noted above).\n */\n getContributors(): ReadonlyArray<{\n key: string\n source: 'module' | 'adapter' | 'plugin' | 'global'\n label: string\n dependsOn: readonly string[]\n }> {\n const out: Array<{\n key: string\n source: 'module' | 'adapter' | 'plugin' | 'global'\n label: string\n dependsOn: readonly string[]\n }> = []\n const ingest = (\n list: ReadonlyArray<unknown> | null | undefined,\n source: 'module' | 'adapter' | 'plugin' | 'global',\n label: string,\n ): void => {\n if (!list) return\n for (const reg of list) {\n const r = reg as { key?: unknown; dependsOn?: unknown }\n if (r.key === undefined || r.key === null) continue\n // `key` is typically a string but createToken<T>() yields a\n // branded token object — normalise via tokenName so both\n // surfaces flow through.\n const key = typeof r.key === 'string' ? r.key : tokenName(r.key)\n out.push({\n key,\n source,\n label,\n dependsOn: Array.isArray(r.dependsOn) ? (r.dependsOn as string[]) : [],\n })\n }\n }\n for (const adapter of this.adapters) {\n ingest(adapter.contributors?.(), 'adapter', adapter.name ?? 'adapter')\n }\n for (const plugin of this.plugins) {\n ingest(plugin.contributors?.(), 'plugin', plugin.name ?? 'plugin')\n }\n // Module-level registrations — captured during `setup()` because\n // module instances are not retained on the Application. Walk the\n // snapshot rather than calling `mod.contributors()` here.\n for (const { registration, label } of this._moduleContributors) {\n ingest([registration], 'module', label)\n }\n ingest(this.options.contributors, 'global', 'bootstrap')\n return out\n }\n\n getHttpServer(): http.Server | null {\n return this.httpServer\n }\n\n // ── Internal helpers ────────────────────────────────────────────────\n\n /**\n * Decide whether {@link Application} should auto-mount the\n * {@link requestScopeMiddleware} ALS wrapper.\n *\n * Returns `false` when:\n * - `contextStore: 'manual'` was set (caller manages ALS frames), or\n * - the user-supplied `middleware` list already includes a\n * `requestScopeMiddleware()` (detected via the symbol marker stamped\n * in `middleware/request-scope.ts`).\n *\n * Otherwise `true` — preserves the historical default of \"always wrap\n * requests in an ALS frame\" so existing apps see no behavior change.\n */\n private shouldAutoMountRequestScope(): boolean {\n if (this.options.contextStore === 'manual') return false\n\n const userEntries = this.options.middlewares ?? this.options.middleware ?? []\n for (const entry of userEntries) {\n const handler = typeof entry === 'function' ? entry : entry.handler\n if (isRequestScopeMiddleware(handler)) return false\n }\n return true\n }\n\n private collectAdapterMiddleware() {\n const result = {\n beforeGlobal: [] as AdapterMiddleware[],\n afterGlobal: [] as AdapterMiddleware[],\n beforeRoutes: [] as AdapterMiddleware[],\n afterRoutes: [] as AdapterMiddleware[],\n }\n\n for (const adapter of this.adapters) {\n const entries = adapter.middleware?.() ?? []\n for (const entry of entries) {\n const phase = entry.phase ?? 'afterGlobal'\n result[phase].push(entry)\n }\n }\n\n return result\n }\n\n private mountMiddlewareList(entries: AdapterMiddleware[]): void {\n for (const entry of entries) {\n if (entry.path === undefined) {\n this.runtime.useConnect(this.app, entry.handler)\n continue\n }\n this.runtime.useConnect(this.app, entry.handler, { path: entry.path })\n }\n }\n\n private mountMiddlewareEntry(entry: MiddlewareEntry): void {\n if (typeof entry === 'function') {\n this.runtime.useConnect(this.app, entry)\n } else {\n this.runtime.useConnect(this.app, entry.handler, { path: entry.path })\n }\n }\n\n /** Middleware that tracks in-flight requests for graceful draining */\n private requestTrackingMiddleware(): RequestHandler {\n return (_req, res, next) => {\n this._inFlightRequests++\n const onFinish = () => {\n res.removeListener('finish', onFinish)\n res.removeListener('close', onFinish)\n this._inFlightRequests--\n // If draining and no more in-flight requests, resolve all waiters\n if (this._draining && this._inFlightRequests === 0) {\n for (const resolve of this._drainResolvers) {\n resolve()\n }\n this._drainResolvers = []\n }\n }\n res.on('finish', onFinish)\n res.on('close', onFinish)\n next()\n }\n }\n\n /** Mount /health/live and /health/ready endpoints at the root (no API prefix) */\n private mountHealthEndpoints(): void {\n const http = this.adapterHttp()\n\n http.route('GET', '/health/live', (ctx) => {\n if (this._draining) {\n ctx.res.status(503).json({ status: 'draining', uptime: process.uptime() })\n } else {\n ctx.json({ status: 'ok', uptime: process.uptime() })\n }\n })\n\n http.route('GET', '/health/ready', async (ctx) => {\n if (this._draining) {\n ctx.res.status(503).json({ status: 'draining', checks: [] })\n return\n }\n const adaptersWithHealth = this.adapters.filter((a) => a.onHealthCheck)\n const checks = await Promise.allSettled(adaptersWithHealth.map((a) => a.onHealthCheck!()))\n const results = checks.map((c, i) => {\n if (c.status === 'fulfilled') return c.value\n return { name: adaptersWithHealth[i].name ?? 'unknown', status: 'down' as const }\n })\n const healthy = results.every((r) => r.status === 'up')\n ctx.res.status(healthy ? 200 : 503).json({\n status: healthy ? 'ready' : 'degraded',\n checks: results,\n })\n })\n }\n}\n"],"mappings":"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"}
@@ -1,9 +1,7 @@
1
1
 
2
2
  import { t as Container } from "./container-TWOUyR_0.mjs";
3
- import { s as ContributorRegistrations } from "./context-decorator-DDZ30BIW.mjs";
4
- import { r as AppAdapter } from "./adapter-CkpcZwzZ.mjs";
5
- import { r as AppModuleEntry } from "./app-module-BTzb-Vd6.mjs";
6
- import { n as ModuleRegistry, t as KickPlugin } from "./plugin-BQCn6zyj.mjs";
3
+ import { d as ContributorRegistrations, r as AppModuleEntry } from "./app-module-CuAS6hJC.mjs";
4
+ import { Mt as ModuleRegistry, f as HttpRuntime, jt as KickPlugin, r as AppAdapter, s as ActiveRuntime } from "./adapter-D_uzU-QA.mjs";
7
5
  import http from "node:http";
8
6
  import { Express, RequestHandler } from "express";
9
7
 
@@ -150,6 +148,18 @@ interface ApplicationOptions {
150
148
  * since Vite owns the lifecycle in development.
151
149
  */
152
150
  processHooks?: 'auto' | 'errors-only' | 'manual';
151
+ /**
152
+ * The HTTP engine driver. Defaults to {@link expressRuntime} — Express stays
153
+ * the zero-config default, so existing apps are unaffected.
154
+ *
155
+ * Any `HttpRuntime` is accepted — pass `fastifyRuntime()` (from
156
+ * `@forinda/kickjs/fastify`) or a custom engine driver. Defaults to
157
+ * {@link expressRuntime}. The engine-native escape hatches
158
+ * (`getRuntimeApp()`, `AdapterContext.app`) follow the active runtime via the
159
+ * registry (`ActiveRuntime`, spec §4.3b) — Express by default, or the augmented
160
+ * engine once the `kick/runtime` typegen output is present.
161
+ */
162
+ runtime?: HttpRuntime;
153
163
  /** Express `trust proxy` setting */
154
164
  trustProxy?: boolean | number | string | ((ip: string, hopIndex: number) => boolean);
155
165
  /** Maximum JSON body size (only used when middleware is not provided) */
@@ -254,6 +264,8 @@ interface ApplicationOptions {
254
264
  declare class Application {
255
265
  private readonly options;
256
266
  private app;
267
+ /** The HTTP engine driver. Defaults to {@link expressRuntime}. */
268
+ private readonly runtime;
257
269
  private container;
258
270
  private httpServer;
259
271
  private readonly adapters;
@@ -316,6 +328,12 @@ declare class Application {
316
328
  */
317
329
  /** Build the adapter context object (shared across all hooks) */
318
330
  private adapterCtx;
331
+ /**
332
+ * The engine-agnostic HTTP surface handed to adapters as `ctx.http`. Each
333
+ * call routes through the active runtime over the current `this.app`, so an
334
+ * adapter written against this works under any runtime.
335
+ */
336
+ private adapterHttp;
319
337
  /** Call an adapter hook, awaiting async hooks and catching errors */
320
338
  private callHook;
321
339
  setup(): Promise<void>;
@@ -344,6 +362,14 @@ declare class Application {
344
362
  * Safe to call multiple times — subsequent calls return the same promise.
345
363
  */
346
364
  shutdown(): Promise<void>;
365
+ /**
366
+ * The engine-native app instance, typed from the active runtime
367
+ * ({@link ActiveRuntime} — Express by default). Prefer this over
368
+ * {@link getExpressApp}; under a non-Express runtime the type follows the
369
+ * augmented registry.
370
+ */
371
+ getRuntimeApp(): ActiveRuntime['app'];
372
+ /** @deprecated Use {@link getRuntimeApp}. Returns the engine-native app. */
347
373
  getExpressApp(): Express;
348
374
  /** Get registered adapters — used by DevToolsAdapter for peer discovery */
349
375
  getAdapters(): AppAdapter[];
@@ -402,4 +428,4 @@ declare class Application {
402
428
  }
403
429
  //#endregion
404
430
  export { ApplicationOptions as n, MiddlewareEntry as r, Application as t };
405
- //# sourceMappingURL=application-CAnpDQ8d.d.mts.map
431
+ //# sourceMappingURL=application-pbx53JnX.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"application-pbx53JnX.d.mts","names":[],"sources":["../src/http/application.ts"],"mappings":";;;;;;;;;;;AAuCA;KAAY,eAAA,GAAkB,cAAA;EAAmB,IAAA;EAAc,OAAA,EAAS,cAAc;AAAA;AAAA,UAErE,kBAAA;EAF8C;;;AAAuB;AAEtF;;;;;;EAWE,OAAA,EAAS,cAAA;EAwDI;;;;;;;;;;;;;;;;;EArCb,KAAA,EAAO,QAAA,EAAU,cAAA;EAqCjB;EAnCA,QAAA,GAAW,UAAA;EAsCX;EApCA,IAAA;EA0DA;EAxDA,SAAA;EA4EA;EA1EA,cAAA;EAkHA;;;;;;;;;;;;;;;;;;;;;EA3FA,WAAA,GAAc,eAAA;EA8LN;AAAA;AAQV;;;EAhME,UAAA,GAAa,eAAA;EAuRG;EApRhB,OAAA,GAAU,UAAA;EAsS6B;;;;;;;;;;;;;;;;;;;;EAhRvC,YAAA,GAAe,wBAAA;EA6LP;;;;;;;;;;;;;;;;;;EAzKR,YAAA;EA4PoE;;;;;;;;;;;;;;;;;;;;;;;;;EAjOpE,YAAA;EA81BE;;;;;;;;;;;EAj1BF,OAAA,GAAU,WAAA;EA09BkB;EAv9B5B,UAAA,iCAA2C,EAAA,UAAY,QAAA;;EAEvD,SAAA;;;;;;;;EAQA,aAAA;;;;;EAKA,cAAA;;;;;EAKA,eAAA;;;;;;;;;;;;;;;;;;;EAoBA,OAAA;IAAsB,OAAA;EAAA;;;;;;;;;;;;;;;;EAiBtB,UAAA,IAAc,GAAA,OAAU,GAAA,OAAU,IAAA;;;;;;;;;;;;;;;;;EAkBlC,OAAA,IAAW,GAAA,OAAU,GAAA,OAAU,GAAA,OAAU,IAAA;;;;;;;;;;;;;;;;;;EAmBzC,QAAA;6DAEE,MAAA;EAAA;AAAA;;;;;cAQS,WAAA;EAAA,iBAoCkB,OAAA;EAAA,QAnCrB,GAAA;;mBAES,OAAA;EAAA,QACT,SAAA;EAAA,QACA,UAAA;EAAA,iBACS,QAAA;EAAA,iBAEA,OAAA;;;;;;;;;;;;;UAcT,mBAAA;;UAMA,iBAAA;;UAEA,SAAA;;UAEA,kBAAA;;UAEA,eAAA;EAER,WAAA,CAA6B,OAAA,EAAS,kBAAA;;MAyClC,UAAA;;MAKA,gBAAA;;EAKJ,YAAA,IAAgB,SAAA;;;;;;;;;;;;;;;EAkBhB,MAAA,CAAO,GAAA,EAAK,IAAA,CAAK,eAAA,EAAiB,GAAA,EAAK,IAAA,CAAK,cAAA,EAAgB,IAAA,IAAQ,GAAA;;;;;;;;;;;;;;;UAuB5D,UAAA;;;;;;UAiBA,WAAA;;UA0BM,QAAA;EAeR,KAAA,IAAS,OAAA;;EAgUT,YAAA,IAAgB,OAAA;;;;;;;;;;EAahB,KAAA,IAAS,OAAA;;EA0ET,OAAA,IAAW,OAAA;;;;;;;;;;;EAoCX,QAAA,IAAY,OAAA;;;;;;;EAsElB,aAAA,IAAiB,aAAA;;EAKjB,aAAA,IAAiB,OAAA;;EAKjB,WAAA,IAAe,UAAA;;;;;;EASf,UAAA,aAAuB,UAAA;;;;;;;;;;;;;;;;;;;EAsBvB,eAAA,IAAmB,aAAA;IACjB,GAAA;IACA,MAAA;IACA,KAAA;IACA,SAAA;EAAA;EA6CF,aAAA,IAAiB,IAAA,CAAK,MAAA;;;;;;;;;;;;;;UAmBd,2BAAA;EAAA,QAWA,wBAAA;EAAA,QAmBA,mBAAA;EAAA,QAUA,oBAAA;;UASA,yBAAA;;UAsBA,oBAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @forinda/kickjs v5.16.0
2
+ * @forinda/kickjs v5.18.0-alpha.0
3
3
  *
4
4
  * Copyright (c) Felix Orinda
5
5
  *
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- import{t as Container}from"./container-D1gfs6__.mjs";import{createLogger}from"./core/logger.mjs";import"./core-Db2uyqtM.mjs";import{reactive,ref}from"./core/reactivity.mjs";import{t as Application}from"./application-DnnqoDWx.mjs";import{o as reloadEnv}from"./env-nwsfCpdy.mjs";import cluster from"node:cluster";import os from"node:os";const log$1=createLogger(`Cluster`);function isClusterPrimary(){return cluster.isPrimary}function setupClusterPrimary(opts){let numWorkers=opts.workers??os.cpus().length,gracefulTimeout=opts.gracefulShutdownTimeout??5e3,restartDelay=opts.restartDelay??1e3,maxFailures=opts.maxFailures??5,restartWindow=opts.restartWindow??3e4,startupTimeouts=new Map,state=reactive({failureTimestamps:[],shuttingDown:!1}),activeWorkers=ref(0);log$1.info(`Primary ${process.pid} starting ${numWorkers} worker(s)`);for(let i=0;i<numWorkers;i++)cluster.fork();cluster.on(`fork`,worker=>{let timeout=setTimeout(()=>{log$1.error(`Worker ${worker.process.pid} did not respond within 10s, killing...`),worker.kill()},1e4);startupTimeouts.set(worker.id,timeout),activeWorkers.value++,log$1.debug(`Worker ${worker.process.pid} forked (id=${worker.id})`)}),cluster.on(`listening`,(worker,address)=>{let timeout=startupTimeouts.get(worker.id);timeout&&(clearTimeout(timeout),startupTimeouts.delete(worker.id)),log$1.info(`Worker ${worker.process.pid} listening on ${address.address}:${address.port}`)}),cluster.on(`online`,worker=>{log$1.debug(`Worker ${worker.process.pid} online (id=${worker.id})`)}),cluster.on(`exit`,(worker,code,signal)=>{let timeout=startupTimeouts.get(worker.id);if(timeout&&(clearTimeout(timeout),startupTimeouts.delete(worker.id)),activeWorkers.value--,worker.exitedAfterDisconnect){log$1.info(`Worker ${worker.process.pid} exited gracefully (id=${worker.id})`);return}let now=Date.now();for(;state.failureTimestamps.length>0&&now-state.failureTimestamps[0]>=restartWindow;)state.failureTimestamps.shift();if(state.failureTimestamps.push(now),state.failureTimestamps.length>maxFailures){log$1.error(`${state.failureTimestamps.length} worker failures in ${restartWindow}ms, giving up`),activeWorkers.value===0&&(log$1.error(`All workers have crashed, exiting primary`),process.exit(1));return}log$1.warn(`Worker ${worker.process.pid} died (code=${code}, signal=${signal}), restarting in ${restartDelay}ms... (failures: ${state.failureTimestamps.length}/${maxFailures})`),setTimeout(()=>{activeWorkers.value<numWorkers&&cluster.fork()},restartDelay)}),cluster.on(`disconnect`,worker=>{log$1.debug(`Worker ${worker.process.pid} disconnected (id=${worker.id})`)});for(let signal of[`SIGTERM`,`SIGINT`])process.on(signal,()=>{state.shuttingDown||(state.shuttingDown=!0,log$1.info(`Primary received ${signal}, disconnecting workers...`),cluster.disconnect(()=>{log$1.info(`All workers disconnected, exiting primary`),process.exit(0)}),setTimeout(()=>{log$1.warn(`Graceful shutdown timed out, forcing exit`),process.exit(1)},gracefulTimeout).unref())})}function tryReloadEnv(){try{reloadEnv()}catch{}}const log=createLogger(`Process`);async function bootstrap(options){let isViteDev=!!globalThis.__kickjs_httpServer;if(options.cluster&&isViteDev&&log.warn(`Cluster mode is ignored in dev — Vite owns the server. Cluster applies in production (kick start).`),options.cluster&&cluster.isPrimary&&!isViteDev)return setupClusterPrimary(typeof options.cluster==`object`?options.cluster:{}),new Application(options);let g=globalThis,processHooks=options.processHooks??`auto`;if(!g.__kickBootstrapped){if(processHooks!==`manual`&&(process.on(`uncaughtException`,err=>{log.error(err,`Uncaught exception`)}),process.on(`unhandledRejection`,reason=>{log.error(reason,`Unhandled rejection`)})),processHooks===`auto`&&!g.__kickjs_httpServer)for(let signal of[`SIGINT`,`SIGTERM`])process.on(signal,async()=>{log.info(`Received ${signal}, shutting down...`),g.__app&&await g.__app.shutdown(),process.exit(0)});g.__kickBootstrapped=!0}if(g.__app){log.debug(`HMR rebuild triggered`),tryReloadEnv(),Container.reset();let freshApp=new Application(options);return g.__app=freshApp,g.__kickjs_container=freshApp.getContainer(),await freshApp.start(),log.debug(`HMR rebuild complete`),freshApp}let app=new Application(options);return g.__app=app,g.__kickjs_container=app.getContainer(),process.env.KICK_TINKER?(await app.registerOnly(),app):(await app.start(),app)}export{isClusterPrimary as n,bootstrap as t};
12
- //# sourceMappingURL=bootstrap-CFK2aAjA.mjs.map
11
+ import{t as Container}from"./container-BiGimG12.mjs";import{createLogger}from"./core/logger.mjs";import"./core-Y_xSqZ7v.mjs";import{reactive,ref}from"./core/reactivity.mjs";import{t as Application}from"./application-BU5N6o_M.mjs";import{o as reloadEnv}from"./env-BoMBrGWs.mjs";import cluster from"node:cluster";import os from"node:os";const log$1=createLogger(`Cluster`);function isClusterPrimary(){return cluster.isPrimary}function setupClusterPrimary(opts){let numWorkers=opts.workers??os.cpus().length,gracefulTimeout=opts.gracefulShutdownTimeout??5e3,restartDelay=opts.restartDelay??1e3,maxFailures=opts.maxFailures??5,restartWindow=opts.restartWindow??3e4,startupTimeouts=new Map,state=reactive({failureTimestamps:[],shuttingDown:!1}),activeWorkers=ref(0);log$1.info(`Primary ${process.pid} starting ${numWorkers} worker(s)`);for(let i=0;i<numWorkers;i++)cluster.fork();cluster.on(`fork`,worker=>{let timeout=setTimeout(()=>{log$1.error(`Worker ${worker.process.pid} did not respond within 10s, killing...`),worker.kill()},1e4);startupTimeouts.set(worker.id,timeout),activeWorkers.value++,log$1.debug(`Worker ${worker.process.pid} forked (id=${worker.id})`)}),cluster.on(`listening`,(worker,address)=>{let timeout=startupTimeouts.get(worker.id);timeout&&(clearTimeout(timeout),startupTimeouts.delete(worker.id)),log$1.info(`Worker ${worker.process.pid} listening on ${address.address}:${address.port}`)}),cluster.on(`online`,worker=>{log$1.debug(`Worker ${worker.process.pid} online (id=${worker.id})`)}),cluster.on(`exit`,(worker,code,signal)=>{let timeout=startupTimeouts.get(worker.id);if(timeout&&(clearTimeout(timeout),startupTimeouts.delete(worker.id)),activeWorkers.value--,worker.exitedAfterDisconnect){log$1.info(`Worker ${worker.process.pid} exited gracefully (id=${worker.id})`);return}let now=Date.now();for(;state.failureTimestamps.length>0&&now-state.failureTimestamps[0]>=restartWindow;)state.failureTimestamps.shift();if(state.failureTimestamps.push(now),state.failureTimestamps.length>maxFailures){log$1.error(`${state.failureTimestamps.length} worker failures in ${restartWindow}ms, giving up`),activeWorkers.value===0&&(log$1.error(`All workers have crashed, exiting primary`),process.exit(1));return}log$1.warn(`Worker ${worker.process.pid} died (code=${code}, signal=${signal}), restarting in ${restartDelay}ms... (failures: ${state.failureTimestamps.length}/${maxFailures})`),setTimeout(()=>{activeWorkers.value<numWorkers&&cluster.fork()},restartDelay)}),cluster.on(`disconnect`,worker=>{log$1.debug(`Worker ${worker.process.pid} disconnected (id=${worker.id})`)});for(let signal of[`SIGTERM`,`SIGINT`])process.on(signal,()=>{state.shuttingDown||(state.shuttingDown=!0,log$1.info(`Primary received ${signal}, disconnecting workers...`),cluster.disconnect(()=>{log$1.info(`All workers disconnected, exiting primary`),process.exit(0)}),setTimeout(()=>{log$1.warn(`Graceful shutdown timed out, forcing exit`),process.exit(1)},gracefulTimeout).unref())})}function tryReloadEnv(){try{reloadEnv()}catch{}}const log=createLogger(`Process`);async function bootstrap(options){let isViteDev=!!globalThis.__kickjs_httpServer;if(options.cluster&&isViteDev&&log.warn(`Cluster mode is ignored in dev — Vite owns the server. Cluster applies in production (kick start).`),options.cluster&&cluster.isPrimary&&!isViteDev)return setupClusterPrimary(typeof options.cluster==`object`?options.cluster:{}),new Application(options);let g=globalThis,processHooks=options.processHooks??`auto`;if(!g.__kickBootstrapped){if(processHooks!==`manual`&&(process.on(`uncaughtException`,err=>{log.error(err,`Uncaught exception`)}),process.on(`unhandledRejection`,reason=>{log.error(reason,`Unhandled rejection`)})),processHooks===`auto`&&!g.__kickjs_httpServer)for(let signal of[`SIGINT`,`SIGTERM`])process.on(signal,async()=>{log.info(`Received ${signal}, shutting down...`),g.__app&&await g.__app.shutdown(),process.exit(0)});g.__kickBootstrapped=!0}if(g.__app){log.debug(`HMR rebuild triggered`),tryReloadEnv(),Container.reset();let freshApp=new Application(options);return g.__app=freshApp,g.__kickjs_container=freshApp.getContainer(),await freshApp.start(),log.debug(`HMR rebuild complete`),freshApp}let app=new Application(options);return g.__app=app,g.__kickjs_container=app.getContainer(),process.env.KICK_TINKER?(await app.registerOnly(),app):(await app.start(),app)}export{isClusterPrimary as n,bootstrap as t};
12
+ //# sourceMappingURL=bootstrap-CFog4v_L.mjs.map