@lukman-ss/moke-core 0.1.0 → 0.2.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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +274 -21
  3. package/dist/application.d.ts +27 -2
  4. package/dist/application.d.ts.map +1 -1
  5. package/dist/application.js +194 -6
  6. package/dist/application.js.map +1 -1
  7. package/dist/container.d.ts +37 -4
  8. package/dist/container.d.ts.map +1 -1
  9. package/dist/container.js +272 -30
  10. package/dist/container.js.map +1 -1
  11. package/dist/decorators.d.ts +0 -8
  12. package/dist/decorators.d.ts.map +1 -1
  13. package/dist/decorators.js +3 -12
  14. package/dist/decorators.js.map +1 -1
  15. package/dist/errors.d.ts +38 -0
  16. package/dist/errors.d.ts.map +1 -0
  17. package/dist/errors.js +98 -0
  18. package/dist/errors.js.map +1 -0
  19. package/dist/index.d.ts +4 -0
  20. package/dist/index.d.ts.map +1 -1
  21. package/dist/index.js +4 -0
  22. package/dist/index.js.map +1 -1
  23. package/dist/internal/formatter.d.ts +3 -0
  24. package/dist/internal/formatter.d.ts.map +1 -0
  25. package/dist/internal/formatter.js +20 -0
  26. package/dist/internal/formatter.js.map +1 -0
  27. package/dist/lifecycle.d.ts +13 -0
  28. package/dist/lifecycle.d.ts.map +1 -0
  29. package/dist/lifecycle.js +2 -0
  30. package/dist/lifecycle.js.map +1 -0
  31. package/dist/logger.d.ts +14 -3
  32. package/dist/logger.d.ts.map +1 -1
  33. package/dist/logger.js +19 -5
  34. package/dist/logger.js.map +1 -1
  35. package/dist/module.d.ts +10 -0
  36. package/dist/module.d.ts.map +1 -0
  37. package/dist/module.js +7 -0
  38. package/dist/module.js.map +1 -0
  39. package/dist/providers.d.ts +15 -11
  40. package/dist/providers.d.ts.map +1 -1
  41. package/dist/providers.js.map +1 -1
  42. package/dist/reflection.d.ts +25 -0
  43. package/dist/reflection.d.ts.map +1 -0
  44. package/dist/reflection.js +34 -0
  45. package/dist/reflection.js.map +1 -0
  46. package/dist/service-provider.d.ts +8 -0
  47. package/dist/service-provider.d.ts.map +1 -0
  48. package/dist/service-provider.js +7 -0
  49. package/dist/service-provider.js.map +1 -0
  50. package/dist/types.js.map +1 -1
  51. package/package.json +30 -6
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 lukman-ss
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,37 +1,290 @@
1
- # @lukman-ss/moke-core
1
+ # Moke Core
2
2
 
3
- Core module for Moke web framework. Provides IoC Container, Dependency Injection, and Application Bootstrap.
3
+ The transport-agnostic Dependency Injection and Application Lifecycle foundation of the Moke web framework.
4
4
 
5
- ## Features
5
+ ## What is Moke Core?
6
6
 
7
- - **Container**: IoC Container for resolving dependencies.
8
- - **Decorators**: `@Injectable()` for class registration.
9
- - **Factory**: `MokeFactory` to bootstrap the application.
10
- - **Logger**: Standard `MokeLogger`.
7
+ Moke Core provides a robust, strictly typed Inversion of Control (IoC) container designed for ESM. It manages dependency resolution, scopes, lifecycle hooks, and modular composition without tying you to any specific transport (like HTTP).
11
8
 
12
- ## Usage
9
+ ## Requirements
10
+
11
+ - **Node.js**: >= 22.14.0
12
+ - **Format**: ESM strictly. CommonJS is not supported.
13
+ - **TypeScript**: Experimental Decorators must be enabled.
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ npm install @lukman-ss/moke-core
19
+ # or
20
+ pnpm add @lukman-ss/moke-core
21
+ # or
22
+ yarn add @lukman-ss/moke-core
23
+ # or
24
+ bun add @lukman-ss/moke-core
25
+ ```
26
+
27
+ ## TypeScript Configuration
28
+
29
+ Moke Core relies on `reflect-metadata` and experimental decorators. Ensure your `tsconfig.json` contains:
30
+
31
+ ```json
32
+ {
33
+ "compilerOptions": {
34
+ "experimentalDecorators": true,
35
+ "emitDecoratorMetadata": true,
36
+ "module": "NodeNext",
37
+ "moduleResolution": "NodeNext"
38
+ }
39
+ }
40
+ ```
41
+
42
+ ## Quick Start
13
43
 
14
44
  ```typescript
15
- import { Injectable, MokeFactory, MokeLogger } from '@lukman-ss/moke-core';
45
+ import { Injectable, MokeFactory } from '@lukman-ss/moke-core';
16
46
 
17
47
  @Injectable()
18
- class AppService {
19
- constructor(private logger: MokeLogger) {}
20
-
21
- run() {
22
- this.logger.log('App is running');
48
+ class Logger {
49
+ log(message: string) {
50
+ console.log(`[LOG]: ${message}`);
23
51
  }
24
52
  }
25
53
 
26
54
  @Injectable()
27
- class AppModule {
28
- constructor(private appService: AppService) {}
29
-
30
- start() {
31
- this.appService.run();
55
+ class UserService {
56
+ constructor(private logger: Logger) {}
57
+
58
+ async create() {
59
+ this.logger.log('Creating user...');
60
+ }
61
+ }
62
+
63
+ const app = await MokeFactory.createApplicationContext(UserService);
64
+ await app.init();
65
+
66
+ const service = app.get(UserService);
67
+ await service.create();
68
+
69
+ await app.close();
70
+ ```
71
+
72
+ ## Dependency Injection
73
+
74
+ Moke Core uses class decorators and constructor injection to resolve dependencies automatically.
75
+
76
+ ### @Injectable & @Inject
77
+
78
+ ```typescript
79
+ import { Injectable, Inject, createToken } from '@lukman-ss/moke-core';
80
+
81
+ const CACHE = createToken<Cache>('CACHE');
82
+
83
+ @Injectable()
84
+ export class UserService {
85
+ constructor(
86
+ private readonly repo: UserRepository, // Auto-inferred via reflection
87
+ @Inject(CACHE) private readonly cache: Cache // Interface/Primitive overrides
88
+ ) {}
89
+ }
90
+ ```
91
+
92
+ ## Tokens
93
+
94
+ For interfaces, primitives, or values that cannot be inferred via reflection:
95
+
96
+ ```typescript
97
+ import { createToken } from '@lukman-ss/moke-core';
98
+
99
+ const PORT = createToken<number>('PORT');
100
+ const DATABASE_URL = createToken<string>('DATABASE_URL');
101
+
102
+ @Injectable()
103
+ class Database {
104
+ constructor(@Inject(DATABASE_URL) private url: string) {}
105
+ }
106
+ ```
107
+
108
+ ## Provider Types
109
+
110
+ Moke supports four provider types:
111
+
112
+ - **ClassProvider**: `{ provide: Token, useClass: Constructor }`
113
+ - **ValueProvider**: `{ provide: Token, useValue: any }`
114
+ - **FactoryProvider**: `{ provide: Token, useFactory: (c: Container) => any }`
115
+ - **ExistingProvider (Alias)**: `{ provide: Token, useExisting: Token }`
116
+
117
+ ## Scopes
118
+
119
+ - **singleton**: One instance across the entire application and all child scopes.
120
+ - **scoped**: One instance per Container instance (useful for request-scoped instances).
121
+ - **transient**: A new instance is created every time it is injected.
122
+
123
+ ```typescript
124
+ container.singleton(DatabasePool);
125
+ container.scoped(RequestContext);
126
+ container.transient(Logger);
127
+
128
+ const childScope = container.createChild();
129
+ const service = childScope.resolve(UserService);
130
+ ```
131
+
132
+ ### Async Providers
133
+
134
+ Async providers are supported safely without corrupting synchronous APIs:
135
+
136
+ ```typescript
137
+ container.factory(DB_TOKEN, async () => await connectDb());
138
+
139
+ // container.resolve(DB_TOKEN) // Throws AsyncProviderResolutionError
140
+
141
+ const db = await container.resolveAsync(DB_TOKEN);
142
+ ```
143
+
144
+ ## Child Containers
145
+
146
+ Use `createChild()` to create isolated scopes:
147
+
148
+ ```typescript
149
+ const requestScope = app.container.createChild();
150
+ const user = requestScope.resolve(CurrentUser);
151
+ const unitOfWork = requestScope.resolve(RequestUnitOfWork);
152
+ ```
153
+
154
+ ## Modules
155
+
156
+ Group features using the `@Module` decorator.
157
+
158
+ ```typescript
159
+ import { Module } from '@lukman-ss/moke-core';
160
+
161
+ @Module({
162
+ imports: [ConfigModule],
163
+ providers: [UserService, UserRepository]
164
+ })
165
+ export class UserModule {}
166
+ ```
167
+
168
+ ## Application Context
169
+
170
+ `MokeApplicationContext` encapsulates the container and manages the application lifecycle.
171
+
172
+ ```typescript
173
+ import { MokeFactory } from '@lukman-ss/moke-core';
174
+
175
+ const app = await MokeFactory.createApplicationContext(AppModule);
176
+
177
+ const service = app.get(UserService);
178
+
179
+ // Start lifecycle hooks
180
+ await app.init();
181
+
182
+ // Graceful shutdown
183
+ await app.close();
184
+ ```
185
+
186
+ ### Lifecycle Hooks
187
+
188
+ Classes can implement lifecycle interfaces. They are executed deterministically:
189
+ - `OnModuleInit`
190
+ - `OnApplicationBootstrap`
191
+ - `OnModuleDestroy`
192
+ - `OnApplicationShutdown`
193
+
194
+ ```typescript
195
+ import { OnModuleInit, OnApplicationBootstrap } from '@lukman-ss/moke-core';
196
+
197
+ @Injectable()
198
+ class DatabaseService implements OnModuleInit, OnApplicationBootstrap {
199
+ async onModuleInit() {
200
+ // Called during app.init()
201
+ await this.connect();
202
+ }
203
+
204
+ async onApplicationBootstrap() {
205
+ // Called after onModuleInit for all modules
32
206
  }
33
207
  }
208
+ ```
209
+
210
+ ## Errors
211
+
212
+ Moke throws specific error types:
213
+
214
+ - `UnknownProviderError`: Token not found
215
+ - `CircularDependencyError`: Circular dependency detected
216
+ - `AsyncProviderResolutionError`: Sync resolve on async provider
217
+ - `DependencyResolutionError`: General resolution failure
218
+ - `MokeShutdownError`: Aggregated shutdown errors
219
+ - `DuplicateProviderError`: Duplicate provider registration
220
+ - `InvalidProviderError`: Invalid provider definition
221
+ - `PrimitiveDependencyError`: Cannot infer primitive dependency
222
+ - `MokeCircularModuleError`: Circular module imports
223
+
224
+ ## Testing
225
+
226
+ ### Override Providers for Testing
227
+
228
+ ```typescript
229
+ import { createToken } from '@lukman-ss/moke-core';
230
+
231
+ const DATABASE = createToken('DATABASE');
232
+
233
+ // Production implementation
234
+ container.singleton(DATABASE, RealDatabase);
235
+
236
+ // Test override
237
+ container.override(DATABASE, FakeDatabase);
34
238
 
35
- const app = MokeFactory.create(AppModule);
36
- app.start();
239
+ const service = container.resolve(UserService);
240
+ // Uses FakeDatabase instead of RealDatabase
37
241
  ```
242
+
243
+ ### Integration Testing Pattern
244
+
245
+ ```typescript
246
+ import { MokeFactory } from '@lukman-ss/moke-core';
247
+ import { describe, it, beforeEach } from 'mocha';
248
+
249
+ describe('UserService Integration', () => {
250
+ let app: MokeApplicationContext;
251
+
252
+ beforeEach(async () => {
253
+ const appContext = await MokeFactory.createApplicationContext(AppModule);
254
+
255
+ // Override production DB with in-memory fake
256
+ appContext.container.override(DATABASE, InMemoryDatabase);
257
+
258
+ await appContext.init();
259
+ app = appContext;
260
+ });
261
+
262
+ it('creates user', async () => {
263
+ const service = app.get(UserService);
264
+ await service.create({ name: 'Alice' });
265
+ });
266
+
267
+ afterEach(async () => {
268
+ await app.close();
269
+ });
270
+ });
271
+ ```
272
+
273
+ ## Package Status
274
+
275
+ | Package | Version | Status |
276
+ |---------|---------|--------|
277
+ | `@lukman-ss/moke-core` | 0.1.16 | Alpha |
278
+ | `@lukman-ss/moke-http` | — | Not yet released |
279
+
280
+ ### 0.x Stability
281
+
282
+ Moke Core is in **0.x alpha**. Public APIs may evolve before 1.0.0. We follow semantic versioning with awareness of early-stage instability.
283
+
284
+ ## Architecture
285
+
286
+ See `ARCHITECTURE.md` for detailed design documentation.
287
+
288
+ ## License
289
+
290
+ MIT
@@ -1,5 +1,30 @@
1
- import { Constructor } from './types.js';
1
+ import { Container } from './container.js';
2
+ import { Constructor, Token } from './types.js';
3
+ import { ServiceProvider } from './service-provider.js';
4
+ import { ProviderDefinition, Scope } from './providers.js';
5
+ export type ApplicationState = 'created' | 'initializing' | 'ready' | 'closing' | 'closed';
6
+ export declare class MokeApplicationContext {
7
+ readonly container: Container;
8
+ private _state;
9
+ private initPromise?;
10
+ private isRegistrationFrozen;
11
+ constructor(container: Container);
12
+ get state(): ApplicationState;
13
+ get<T>(token: Token<T>): T;
14
+ getAsync<T>(token: Token<T>): Promise<T>;
15
+ register<T>(token: Token<T>, providerDef: ProviderDefinition<T>, scope?: Scope): void;
16
+ registerProvider(provider: ServiceProvider): Promise<void>;
17
+ bootProviders(): Promise<void>;
18
+ init(): Promise<void>;
19
+ private _initImpl;
20
+ close(signal?: string): Promise<void>;
21
+ }
2
22
  export declare class MokeFactory {
3
- static create<T>(module: Constructor<T>): T;
23
+ /**
24
+ * Creates a MokeApplicationContext, compiling the module tree.
25
+ * Does not automatically call `init()`.
26
+ */
27
+ static createApplicationContext(module: Constructor<unknown>): Promise<MokeApplicationContext>;
28
+ private static compileModuleAsync;
4
29
  }
5
30
  //# sourceMappingURL=application.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC,qBAAa,WAAW;IACtB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC;CAS5C"}
1
+ {"version":3,"file":"application.d.ts","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,KAAK,EAAY,MAAM,gBAAgB,CAAC;AAKrE,MAAM,MAAM,gBAAgB,GAAG,SAAS,GAAG,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,QAAQ,CAAC;AAE3F,qBAAa,sBAAsB;aAKL,SAAS,EAAE,SAAS;IAJhD,OAAO,CAAC,MAAM,CAA+B;IAC7C,OAAO,CAAC,WAAW,CAAC,CAAgB;IACpC,OAAO,CAAC,oBAAoB,CAAS;gBAET,SAAS,EAAE,SAAS;IAEhD,IAAI,KAAK,IAAI,gBAAgB,CAE5B;IAED,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IAI1B,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAIxC,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,KAAmB,GAAG,IAAI;IAO5F,gBAAgB,CAAC,QAAQ,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC;IAe1D,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IAiB9B,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAyBb,SAAS;IA0BjB,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAsC5C;AAED,qBAAa,WAAW;IACtB;;;OAGG;WACU,wBAAwB,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,sBAAsB,CAAC;mBAa/E,kBAAkB;CAqDxC"}
@@ -1,12 +1,200 @@
1
1
  import { Container } from './container.js';
2
- import { MokeLogger } from './logger.js';
2
+ import { ConsoleLogger } from './logger.js';
3
+ import { ServiceProvider } from './service-provider.js';
4
+ import { ReflectionHost } from './reflection.js';
5
+ import { MokeCircularModuleError, MokeBootstrapError, MokeShutdownError } from './errors.js';
6
+ export class MokeApplicationContext {
7
+ container;
8
+ _state = 'created';
9
+ initPromise;
10
+ isRegistrationFrozen = false;
11
+ constructor(container) {
12
+ this.container = container;
13
+ }
14
+ get state() {
15
+ return this._state;
16
+ }
17
+ get(token) {
18
+ return this.container.resolve(token);
19
+ }
20
+ getAsync(token) {
21
+ return this.container.resolveAsync(token);
22
+ }
23
+ register(token, providerDef, scope = 'singleton') {
24
+ if (this._state !== 'created') {
25
+ throw new Error('Cannot register providers after application has been initialized');
26
+ }
27
+ this.container.bind(token, providerDef, scope);
28
+ }
29
+ async registerProvider(provider) {
30
+ if (this._state !== 'created') {
31
+ throw new Error('Cannot register providers after application has been initialized');
32
+ }
33
+ const registeredProviders = Reflect.getMetadata('moke:registeredProviders', provider) || [];
34
+ if (registeredProviders.includes(provider.constructor)) {
35
+ throw new Error(`ServiceProvider ${provider.constructor.name} has already been registered. Use register() instead of registerProvider() for class-based providers.`);
36
+ }
37
+ Reflect.defineMetadata('moke:registeredProviders', [...registeredProviders, provider.constructor], provider);
38
+ await provider.register?.();
39
+ }
40
+ async bootProviders() {
41
+ const bootQueue = [];
42
+ for (const instance of this.container.getInstantiatedInstances()) {
43
+ if (instance instanceof ServiceProvider) {
44
+ const registered = Reflect.getMetadata('moke:registeredProviders', instance) || [];
45
+ if (registered.length > 0) {
46
+ bootQueue.push(instance);
47
+ }
48
+ }
49
+ }
50
+ for (const provider of bootQueue) {
51
+ await provider.boot?.();
52
+ }
53
+ }
54
+ async init() {
55
+ if (this._state === 'ready')
56
+ return;
57
+ if (this._state === 'closing' || this._state === 'closed') {
58
+ throw new Error('Cannot initialize an application that is closing or closed.');
59
+ }
60
+ if (this._state === 'initializing' && this.initPromise) {
61
+ return this.initPromise;
62
+ }
63
+ this._state = 'initializing';
64
+ this.initPromise = this._initImpl();
65
+ try {
66
+ await this.initPromise;
67
+ this.container.freeze();
68
+ this._state = 'ready';
69
+ }
70
+ catch (e) {
71
+ this._state = 'created';
72
+ throw e;
73
+ }
74
+ finally {
75
+ this.initPromise = undefined;
76
+ }
77
+ }
78
+ async _initImpl() {
79
+ const instances = this.container.getInstantiatedInstances();
80
+ // 1. onModuleInit
81
+ for (const instance of instances) {
82
+ if (typeof instance.onModuleInit === 'function') {
83
+ try {
84
+ await instance.onModuleInit();
85
+ }
86
+ catch (e) {
87
+ throw new MokeBootstrapError('onModuleInit', e, instance.constructor?.name);
88
+ }
89
+ }
90
+ }
91
+ // 2. onApplicationBootstrap
92
+ for (const instance of instances) {
93
+ if (typeof instance.onApplicationBootstrap === 'function') {
94
+ try {
95
+ await instance.onApplicationBootstrap();
96
+ }
97
+ catch (e) {
98
+ throw new MokeBootstrapError('onApplicationBootstrap', e, instance.constructor?.name);
99
+ }
100
+ }
101
+ }
102
+ }
103
+ async close(signal) {
104
+ if (this._state === 'closed')
105
+ return;
106
+ this._state = 'closing';
107
+ const shutdownErrors = [];
108
+ // Reverse order for teardown
109
+ const instances = this.container.getInstantiatedInstances().reverse();
110
+ // 1. onApplicationShutdown
111
+ for (const instance of instances) {
112
+ if (typeof instance.onApplicationShutdown === 'function') {
113
+ try {
114
+ await instance.onApplicationShutdown(signal);
115
+ }
116
+ catch (e) {
117
+ shutdownErrors.push(e);
118
+ }
119
+ }
120
+ }
121
+ // 2. onModuleDestroy
122
+ for (const instance of instances) {
123
+ if (typeof instance.onModuleDestroy === 'function') {
124
+ try {
125
+ await instance.onModuleDestroy();
126
+ }
127
+ catch (e) {
128
+ shutdownErrors.push(e);
129
+ }
130
+ }
131
+ }
132
+ this.container.dispose();
133
+ this._state = 'closed';
134
+ if (shutdownErrors.length > 0) {
135
+ throw new MokeShutdownError(shutdownErrors);
136
+ }
137
+ }
138
+ }
3
139
  export class MokeFactory {
4
- static create(module) {
140
+ /**
141
+ * Creates a MokeApplicationContext, compiling the module tree.
142
+ * Does not automatically call `init()`.
143
+ */
144
+ static async createApplicationContext(module) {
5
145
  const container = new Container();
6
- // Default providers
7
- container.instance(MokeLogger, new MokeLogger());
8
- const app = container.resolve(module);
9
- return app;
146
+ // Core default registrations
147
+ container.instance(ConsoleLogger, new ConsoleLogger());
148
+ container.bind('Logger', { useExisting: ConsoleLogger });
149
+ await this.compileModuleAsync(module, container, new Set(), []);
150
+ await container.resolveAsync(module); // Resolve the root module to trigger graph instantiation
151
+ return new MokeApplicationContext(container);
152
+ }
153
+ static async compileModuleAsync(module, container, resolved, path) {
154
+ if (path.includes(module)) {
155
+ throw new MokeCircularModuleError([...path, module]);
156
+ }
157
+ if (resolved.has(module))
158
+ return;
159
+ path.push(module);
160
+ const metadata = ReflectionHost.getModuleMetadata(module);
161
+ if (!metadata) {
162
+ container.singleton(module);
163
+ resolved.add(module);
164
+ path.pop();
165
+ return;
166
+ }
167
+ if (metadata.imports) {
168
+ for (const imported of metadata.imports) {
169
+ await this.compileModuleAsync(imported, container, resolved, path);
170
+ }
171
+ }
172
+ if (metadata.providers) {
173
+ for (const provider of metadata.providers) {
174
+ if (typeof provider === 'function') {
175
+ // Provide default singleton bindings only if not already bound
176
+ // In an encapsulated model, this logic will branch. Here in the flattened model, we skip if already explicitly bound.
177
+ if (!container.hasOwn(provider)) {
178
+ container.singleton(provider);
179
+ }
180
+ }
181
+ else {
182
+ const providerDef = provider;
183
+ if (providerDef.provide && !container.hasOwn(providerDef.provide)) {
184
+ container.register(providerDef);
185
+ }
186
+ }
187
+ }
188
+ }
189
+ // Exports behavior in core is currently flattened globally.
190
+ // In Model B (Encapsulated), each module would get a child container,
191
+ // and exports would be forwarded.
192
+ // For Moke's simplicity vs NestJS-like complexity, we use a flattened global DI by default.
193
+ if (!container.hasOwn(module)) {
194
+ container.singleton(module);
195
+ }
196
+ resolved.add(module);
197
+ path.pop();
10
198
  }
11
199
  }
12
200
  //# sourceMappingURL=application.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"application.js","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGzC,MAAM,OAAO,WAAW;IACtB,MAAM,CAAC,MAAM,CAAI,MAAsB;QACrC,MAAM,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;QAElC,oBAAoB;QACpB,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,IAAI,UAAU,EAAE,CAAC,CAAC;QAEjD,MAAM,GAAG,GAAG,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QACtC,OAAO,GAAG,CAAC;IACb,CAAC;CACF"}
1
+ {"version":3,"file":"application.js","sourceRoot":"","sources":["../src/application.ts"],"names":[],"mappings":"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","sourcesContent":["import { Container } from './container.js';\nimport { ConsoleLogger, Logger } from './logger.js';\nimport { Constructor, Token } from './types.js';\nimport { ServiceProvider } from './service-provider.js';\nimport { ProviderDefinition, Scope, Provider } from './providers.js';\nimport { ReflectionHost } from './reflection.js';\n\nimport { MokeCircularModuleError, MokeBootstrapError, MokeShutdownError } from './errors.js';\n\nexport type ApplicationState = 'created' | 'initializing' | 'ready' | 'closing' | 'closed';\n\nexport class MokeApplicationContext {\n private _state: ApplicationState = 'created';\n private initPromise?: Promise<void>;\n private isRegistrationFrozen = false;\n\n constructor(public readonly container: Container) {}\n\n get state(): ApplicationState {\n return this._state;\n }\n\n get<T>(token: Token<T>): T {\n return this.container.resolve(token);\n }\n\n getAsync<T>(token: Token<T>): Promise<T> {\n return this.container.resolveAsync(token);\n }\n\n register<T>(token: Token<T>, providerDef: ProviderDefinition<T>, scope: Scope = 'singleton'): void {\n if (this._state !== 'created') {\n throw new Error('Cannot register providers after application has been initialized');\n }\n this.container.bind(token, providerDef, scope);\n }\n\n async registerProvider(provider: ServiceProvider): Promise<void> {\n if (this._state !== 'created') {\n throw new Error('Cannot register providers after application has been initialized');\n }\n \n const registeredProviders = Reflect.getMetadata('moke:registeredProviders', provider) || [];\n if (registeredProviders.includes(provider.constructor)) {\n throw new Error(`ServiceProvider ${provider.constructor.name} has already been registered. Use register() instead of registerProvider() for class-based providers.`);\n }\n \n Reflect.defineMetadata('moke:registeredProviders', [...registeredProviders, provider.constructor], provider);\n \n await provider.register?.();\n }\n\n async bootProviders(): Promise<void> {\n const bootQueue: ServiceProvider[] = [];\n \n for (const instance of this.container.getInstantiatedInstances()) {\n if (instance instanceof ServiceProvider) {\n const registered = Reflect.getMetadata('moke:registeredProviders', instance) || [];\n if (registered.length > 0) {\n bootQueue.push(instance);\n }\n }\n }\n \n for (const provider of bootQueue) {\n await provider.boot?.();\n }\n }\n\n async init(): Promise<void> {\n if (this._state === 'ready') return;\n if (this._state === 'closing' || this._state === 'closed') {\n throw new Error('Cannot initialize an application that is closing or closed.');\n }\n\n if (this._state === 'initializing' && this.initPromise) {\n return this.initPromise;\n }\n\n this._state = 'initializing';\n this.initPromise = this._initImpl();\n\n try {\n await this.initPromise;\n this.container.freeze();\n this._state = 'ready';\n } catch (e) {\n this._state = 'created';\n throw e;\n } finally {\n this.initPromise = undefined;\n }\n }\n\n private async _initImpl(): Promise<void> {\n const instances = this.container.getInstantiatedInstances();\n\n // 1. onModuleInit\n for (const instance of instances as any[]) {\n if (typeof instance.onModuleInit === 'function') {\n try {\n await instance.onModuleInit();\n } catch (e: any) {\n throw new MokeBootstrapError('onModuleInit', e, instance.constructor?.name);\n }\n }\n }\n\n // 2. onApplicationBootstrap\n for (const instance of instances as any[]) {\n if (typeof instance.onApplicationBootstrap === 'function') {\n try {\n await instance.onApplicationBootstrap();\n } catch (e: any) {\n throw new MokeBootstrapError('onApplicationBootstrap', e, instance.constructor?.name);\n }\n }\n }\n }\n\n async close(signal?: string): Promise<void> {\n if (this._state === 'closed') return;\n this._state = 'closing';\n\n const shutdownErrors: Error[] = [];\n\n // Reverse order for teardown\n const instances = this.container.getInstantiatedInstances().reverse();\n\n // 1. onApplicationShutdown\n for (const instance of instances as any[]) {\n if (typeof instance.onApplicationShutdown === 'function') {\n try {\n await instance.onApplicationShutdown(signal);\n } catch (e: any) {\n shutdownErrors.push(e);\n }\n }\n }\n\n // 2. onModuleDestroy\n for (const instance of instances as any[]) {\n if (typeof instance.onModuleDestroy === 'function') {\n try {\n await instance.onModuleDestroy();\n } catch (e: any) {\n shutdownErrors.push(e);\n }\n }\n }\n\n this.container.dispose();\n this._state = 'closed';\n\n if (shutdownErrors.length > 0) {\n throw new MokeShutdownError(shutdownErrors);\n }\n }\n}\n\nexport class MokeFactory {\n /**\n * Creates a MokeApplicationContext, compiling the module tree.\n * Does not automatically call `init()`.\n */\n static async createApplicationContext(module: Constructor<unknown>): Promise<MokeApplicationContext> {\n const container = new Container();\n \n // Core default registrations\n container.instance(ConsoleLogger, new ConsoleLogger());\n container.bind('Logger', { useExisting: ConsoleLogger });\n \n await this.compileModuleAsync(module, container, new Set(), []);\n await container.resolveAsync(module); // Resolve the root module to trigger graph instantiation\n \n return new MokeApplicationContext(container);\n }\n\n private static async compileModuleAsync(module: Constructor<unknown>, container: Container, resolved: Set<unknown>, path: Constructor<unknown>[]) {\n if (path.includes(module)) {\n throw new MokeCircularModuleError([...path, module]);\n }\n \n if (resolved.has(module)) return;\n\n path.push(module);\n\n const metadata = ReflectionHost.getModuleMetadata(module);\n \n if (!metadata) {\n container.singleton(module);\n resolved.add(module);\n path.pop();\n return;\n }\n\n if (metadata.imports) {\n for (const imported of metadata.imports) {\n await this.compileModuleAsync(imported, container, resolved, path);\n }\n }\n\n if (metadata.providers) {\n for (const provider of metadata.providers) {\n if (typeof provider === 'function') {\n // Provide default singleton bindings only if not already bound\n // In an encapsulated model, this logic will branch. Here in the flattened model, we skip if already explicitly bound.\n if (!container.hasOwn(provider)) {\n container.singleton(provider);\n }\n } else {\n const providerDef = provider as Provider;\n if (providerDef.provide && !container.hasOwn(providerDef.provide)) {\n container.register(providerDef);\n }\n }\n }\n }\n\n // Exports behavior in core is currently flattened globally.\n // In Model B (Encapsulated), each module would get a child container,\n // and exports would be forwarded.\n // For Moke's simplicity vs NestJS-like complexity, we use a flattened global DI by default.\n\n if (!container.hasOwn(module)) {\n container.singleton(module);\n }\n \n resolved.add(module);\n path.pop();\n }\n}\n"]}
@@ -1,17 +1,50 @@
1
1
  import 'reflect-metadata';
2
2
  import { Token } from './types.js';
3
- import { ProviderDefinition, Scope } from './providers.js';
3
+ import { Provider, ProviderDefinition, Scope, Resolver } from './providers.js';
4
+ interface ProviderRegistration {
5
+ provider: Provider;
6
+ scope: Scope;
7
+ instance?: unknown;
8
+ asyncPromise?: Promise<unknown>;
9
+ }
4
10
  export declare class Container {
11
+ private parent?;
5
12
  private registrations;
13
+ private instantiatedInstances;
14
+ private isDisposed;
15
+ private isActiveResolution;
16
+ private isFrozen;
17
+ constructor(parent?: Container | undefined);
18
+ createChild(): Container;
19
+ freeze(): void;
20
+ unfrozen(): boolean;
21
+ register<T>(provider: Provider<T>, scope?: Scope): void;
6
22
  bind<T>(token: Token<T>, providerDef: ProviderDefinition<T>, scope?: Scope): void;
23
+ override<T>(token: Token<T>, providerDef: ProviderDefinition<T>, scope?: Scope): void;
24
+ private internalBind;
7
25
  singleton<T>(token: Token<T>, providerDef?: ProviderDefinition<T>): void;
26
+ scoped<T>(token: Token<T>, providerDef?: ProviderDefinition<T>): void;
8
27
  transient<T>(token: Token<T>, providerDef?: ProviderDefinition<T>): void;
9
28
  instance<T>(token: Token<T>, value: T): void;
10
- factory<T>(token: Token<T>, factory: (container: Container) => T | Promise<T>, scope?: Scope): void;
29
+ factory<T>(token: Token<T>, factory: (resolver: Resolver) => T | Promise<T>, scope?: Scope): void;
11
30
  has<T>(token: Token<T>): boolean;
31
+ hasOwn<T>(token: Token<T>): boolean;
12
32
  resolve<T>(token: Token<T>): T;
13
- private resolveProvider;
14
- private instantiateClass;
33
+ resolveAsync<T>(token: Token<T>): Promise<T>;
34
+ dispose(): void;
35
+ getInstantiatedInstances(): unknown[];
36
+ protected hasRegistration(key: unknown): boolean;
37
+ protected getRegistrationRecursively(key: unknown): ProviderRegistration | undefined;
38
+ protected ensureRegistered(key: unknown, token: Token<unknown>, path: unknown[]): void;
39
+ private createResolutionProxy;
40
+ private internalResolveSync;
41
+ private internalResolveAsync;
42
+ private resolveProviderSync;
43
+ private resolveProviderAsync;
44
+ private instantiateClassSync;
45
+ private instantiateClassAsync;
46
+ private getConstructorInjections;
15
47
  private getTokenKey;
16
48
  }
49
+ export {};
17
50
  //# sourceMappingURL=container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,CAAC;AAC1B,OAAO,EAAe,KAAK,EAAkB,MAAM,YAAY,CAAC;AAChE,OAAO,EAAY,kBAAkB,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AASrE,qBAAa,SAAS;IACpB,OAAO,CAAC,aAAa,CAAwC;IAE7D,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,KAAmB;IAavF,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAIjE,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,WAAW,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAIjE,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;IAQrC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,GAAE,KAAmB;IAIzG,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO;IAIhC,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IA0B9B,OAAO,CAAC,eAAe;IAkBvB,OAAO,CAAC,gBAAgB;IAkBxB,OAAO,CAAC,WAAW;CAMpB"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}