@onebun/core 0.2.8 → 0.2.9
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.
package/package.json
CHANGED
|
@@ -38,6 +38,7 @@ import {
|
|
|
38
38
|
} from '../decorators/decorators';
|
|
39
39
|
import { Controller as BaseController } from '../module/controller';
|
|
40
40
|
import { BaseMiddleware } from '../module/middleware';
|
|
41
|
+
import { clearGlobalServicesRegistry } from '../module/module';
|
|
41
42
|
import { Service } from '../module/service';
|
|
42
43
|
import { QueueService, QUEUE_NOT_ENABLED_ERROR_MESSAGE } from '../queue';
|
|
43
44
|
import { Subscribe } from '../queue/decorators';
|
|
@@ -157,6 +158,7 @@ describe('OneBunApplication', () => {
|
|
|
157
158
|
|
|
158
159
|
afterEach(() => {
|
|
159
160
|
register.clear();
|
|
161
|
+
clearGlobalServicesRegistry();
|
|
160
162
|
});
|
|
161
163
|
|
|
162
164
|
describe('Constructor and basic initialization', () => {
|
|
@@ -4036,5 +4038,49 @@ describe('OneBunApplication', () => {
|
|
|
4036
4038
|
|
|
4037
4039
|
await app.stop();
|
|
4038
4040
|
});
|
|
4041
|
+
|
|
4042
|
+
test('QueueService is injectable in controllers of child modules', async () => {
|
|
4043
|
+
@Controller('/child-queue')
|
|
4044
|
+
class ChildQueueController extends BaseController {
|
|
4045
|
+
constructor(private queueService: QueueService) {
|
|
4046
|
+
super();
|
|
4047
|
+
}
|
|
4048
|
+
|
|
4049
|
+
publishTest(pattern: string, data: unknown) {
|
|
4050
|
+
return this.queueService.publish(pattern, data);
|
|
4051
|
+
}
|
|
4052
|
+
}
|
|
4053
|
+
|
|
4054
|
+
@Controller('/child-sub')
|
|
4055
|
+
class ChildSubscribeController extends BaseController {
|
|
4056
|
+
@Subscribe('child.test')
|
|
4057
|
+
async handle(): Promise<void> {}
|
|
4058
|
+
}
|
|
4059
|
+
|
|
4060
|
+
@Module({
|
|
4061
|
+
controllers: [ChildQueueController, ChildSubscribeController],
|
|
4062
|
+
})
|
|
4063
|
+
class ChildQueueModule {}
|
|
4064
|
+
|
|
4065
|
+
@Module({
|
|
4066
|
+
imports: [ChildQueueModule],
|
|
4067
|
+
})
|
|
4068
|
+
class ParentQueueModule {}
|
|
4069
|
+
|
|
4070
|
+
const app = createTestApp(ParentQueueModule, {
|
|
4071
|
+
port: 0,
|
|
4072
|
+
queue: { enabled: true, adapter: 'memory' },
|
|
4073
|
+
});
|
|
4074
|
+
await app.start();
|
|
4075
|
+
|
|
4076
|
+
const rootModule = (app as unknown as { rootModule: ModuleInstance }).rootModule;
|
|
4077
|
+
const controller = rootModule.getControllerInstance?.(ChildQueueController) as
|
|
4078
|
+
| ChildQueueController
|
|
4079
|
+
| undefined;
|
|
4080
|
+
expect(controller).toBeDefined();
|
|
4081
|
+
await expect(controller!.publishTest('child.test', { ok: true })).resolves.toBeDefined();
|
|
4082
|
+
|
|
4083
|
+
await app.stop();
|
|
4084
|
+
});
|
|
4039
4085
|
});
|
|
4040
4086
|
});
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
DEFAULT_SSE_HEARTBEAT_MS,
|
|
54
54
|
DEFAULT_SSE_TIMEOUT,
|
|
55
55
|
} from '../module/controller';
|
|
56
|
-
import { OneBunModule } from '../module/module';
|
|
56
|
+
import { OneBunModule, registerGlobalService } from '../module/module';
|
|
57
57
|
import {
|
|
58
58
|
QueueService,
|
|
59
59
|
QueueServiceProxy,
|
|
@@ -490,19 +490,19 @@ export class OneBunApplication {
|
|
|
490
490
|
this.logger.info('Application configuration initialized');
|
|
491
491
|
}
|
|
492
492
|
|
|
493
|
-
//
|
|
494
|
-
// so
|
|
495
|
-
this.rootModule = OneBunModule.create(this.moduleClass, this.loggerLayer, this.config);
|
|
496
|
-
|
|
497
|
-
// Register QueueService proxy in DI so controllers/providers/middleware can inject QueueService.
|
|
493
|
+
// Register QueueService proxy in global registry BEFORE creating the root module,
|
|
494
|
+
// so all modules (including child modules) pick it up via PHASE 0 of initModule().
|
|
498
495
|
// After initializeQueue(), setDelegate(real) is called when queue is enabled.
|
|
499
496
|
this.queueServiceProxy = new QueueServiceProxy();
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
497
|
+
registerGlobalService(
|
|
498
|
+
QueueServiceTag as Context.Tag<unknown, QueueService>,
|
|
499
|
+
this.queueServiceProxy as unknown as QueueService,
|
|
500
|
+
);
|
|
501
|
+
|
|
502
|
+
// Create the root module AFTER config is initialized and QueueService proxy is registered,
|
|
503
|
+
// so services can safely use this.config.get() in their constructors
|
|
504
|
+
// and inject QueueService in any module depth.
|
|
505
|
+
this.rootModule = OneBunModule.create(this.moduleClass, this.loggerLayer, this.config);
|
|
506
506
|
|
|
507
507
|
// Register test provider overrides (must happen before setup() so controllers receive mocks)
|
|
508
508
|
if (this.options._testProviders) {
|
package/src/module/module.ts
CHANGED
|
@@ -72,6 +72,16 @@ export function clearGlobalServicesRegistry(): void {
|
|
|
72
72
|
processedGlobalModules.clear();
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Register a service instance in the global services registry so it is available
|
|
77
|
+
* in all modules (including child modules) via PHASE 0 of module initialization.
|
|
78
|
+
* Must be called BEFORE creating the root module.
|
|
79
|
+
* @internal
|
|
80
|
+
*/
|
|
81
|
+
export function registerGlobalService<T>(tag: Context.Tag<unknown, T>, instance: T): void {
|
|
82
|
+
globalServicesRegistry.set(tag as Context.Tag<unknown, unknown>, instance);
|
|
83
|
+
}
|
|
84
|
+
|
|
75
85
|
/**
|
|
76
86
|
* Get all global services (useful for debugging)
|
|
77
87
|
* @internal
|
|
@@ -435,7 +435,7 @@ describe('Custom adapter NATS JetStream (docs/api/queue.md)', () => {
|
|
|
435
435
|
class NatsJetStreamAdapter implements QueueAdapter {
|
|
436
436
|
readonly name = 'nats-jetstream';
|
|
437
437
|
readonly type = 'jetstream';
|
|
438
|
-
constructor(private opts: { servers: string;
|
|
438
|
+
constructor(private opts: { servers: string; streams?: Array<{ name: string; subjects: string[] }> }) {}
|
|
439
439
|
async connect(): Promise<void> {}
|
|
440
440
|
async disconnect(): Promise<void> {}
|
|
441
441
|
isConnected(): boolean {
|
|
@@ -473,7 +473,7 @@ describe('Custom adapter NATS JetStream (docs/api/queue.md)', () => {
|
|
|
473
473
|
|
|
474
474
|
const adapter = new NatsJetStreamAdapter({
|
|
475
475
|
servers: 'nats://localhost:4222',
|
|
476
|
-
|
|
476
|
+
streams: [{ name: 'EVENTS', subjects: ['events.>'] }],
|
|
477
477
|
});
|
|
478
478
|
await adapter.connect();
|
|
479
479
|
expect(adapter.name).toBe('nats-jetstream');
|