@pattern-stack/codegen 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.
- package/CHANGELOG.md +67 -0
- package/README.md +214 -0
- package/dist/runtime/analytics/index.d.ts +6 -0
- package/dist/runtime/analytics/index.js +49 -0
- package/dist/runtime/analytics/index.js.map +1 -0
- package/dist/runtime/analytics/metrics.d.ts +75 -0
- package/dist/runtime/analytics/metrics.js +1 -0
- package/dist/runtime/analytics/metrics.js.map +1 -0
- package/dist/runtime/analytics/packs/crm-entity-measures.d.ts +21 -0
- package/dist/runtime/analytics/packs/crm-entity-measures.js +1 -0
- package/dist/runtime/analytics/packs/crm-entity-measures.js.map +1 -0
- package/dist/runtime/analytics/packs/index.d.ts +3 -0
- package/dist/runtime/analytics/packs/index.js +1 -0
- package/dist/runtime/analytics/packs/index.js.map +1 -0
- package/dist/runtime/analytics/packs/monetary-measures.d.ts +21 -0
- package/dist/runtime/analytics/packs/monetary-measures.js +1 -0
- package/dist/runtime/analytics/packs/monetary-measures.js.map +1 -0
- package/dist/runtime/analytics/specs.d.ts +49 -0
- package/dist/runtime/analytics/specs.js +1 -0
- package/dist/runtime/analytics/specs.js.map +1 -0
- package/dist/runtime/analytics/types.d.ts +85 -0
- package/dist/runtime/analytics/types.js +49 -0
- package/dist/runtime/analytics/types.js.map +1 -0
- package/dist/runtime/base-classes/activity-entity-repository.d.ts +26 -0
- package/dist/runtime/base-classes/activity-entity-repository.js +195 -0
- package/dist/runtime/base-classes/activity-entity-repository.js.map +1 -0
- package/dist/runtime/base-classes/activity-entity-service.d.ts +39 -0
- package/dist/runtime/base-classes/activity-entity-service.js +214 -0
- package/dist/runtime/base-classes/activity-entity-service.js.map +1 -0
- package/dist/runtime/base-classes/base-read-use-cases.d.ts +68 -0
- package/dist/runtime/base-classes/base-read-use-cases.js +32 -0
- package/dist/runtime/base-classes/base-read-use-cases.js.map +1 -0
- package/dist/runtime/base-classes/base-repository.d.ts +99 -0
- package/dist/runtime/base-classes/base-repository.js +160 -0
- package/dist/runtime/base-classes/base-repository.js.map +1 -0
- package/dist/runtime/base-classes/base-service.d.ts +98 -0
- package/dist/runtime/base-classes/base-service.js +186 -0
- package/dist/runtime/base-classes/base-service.js.map +1 -0
- package/dist/runtime/base-classes/index.d.ts +18 -0
- package/dist/runtime/base-classes/index.js +617 -0
- package/dist/runtime/base-classes/index.js.map +1 -0
- package/dist/runtime/base-classes/knowledge-entity-repository.d.ts +17 -0
- package/dist/runtime/base-classes/knowledge-entity-repository.js +166 -0
- package/dist/runtime/base-classes/knowledge-entity-repository.js.map +1 -0
- package/dist/runtime/base-classes/knowledge-entity-service.d.ts +15 -0
- package/dist/runtime/base-classes/knowledge-entity-service.js +192 -0
- package/dist/runtime/base-classes/knowledge-entity-service.js.map +1 -0
- package/dist/runtime/base-classes/lifecycle-events.d.ts +49 -0
- package/dist/runtime/base-classes/lifecycle-events.js +76 -0
- package/dist/runtime/base-classes/lifecycle-events.js.map +1 -0
- package/dist/runtime/base-classes/metadata-entity-repository.d.ts +27 -0
- package/dist/runtime/base-classes/metadata-entity-repository.js +212 -0
- package/dist/runtime/base-classes/metadata-entity-repository.js.map +1 -0
- package/dist/runtime/base-classes/metadata-entity-service.d.ts +39 -0
- package/dist/runtime/base-classes/metadata-entity-service.js +214 -0
- package/dist/runtime/base-classes/metadata-entity-service.js.map +1 -0
- package/dist/runtime/base-classes/synced-entity-repository.d.ts +32 -0
- package/dist/runtime/base-classes/synced-entity-repository.js +203 -0
- package/dist/runtime/base-classes/synced-entity-repository.js.map +1 -0
- package/dist/runtime/base-classes/synced-entity-service.d.ts +41 -0
- package/dist/runtime/base-classes/synced-entity-service.js +215 -0
- package/dist/runtime/base-classes/synced-entity-service.js.map +1 -0
- package/dist/runtime/base-classes/with-analytics.d.ts +18 -0
- package/dist/runtime/base-classes/with-analytics.js +11 -0
- package/dist/runtime/base-classes/with-analytics.js.map +1 -0
- package/dist/runtime/constants/tokens.d.ts +29 -0
- package/dist/runtime/constants/tokens.js +8 -0
- package/dist/runtime/constants/tokens.js.map +1 -0
- package/dist/runtime/subsystems/analytics/analytics-query.protocol.d.ts +30 -0
- package/dist/runtime/subsystems/analytics/analytics-query.protocol.js +1 -0
- package/dist/runtime/subsystems/analytics/analytics-query.protocol.js.map +1 -0
- package/dist/runtime/subsystems/analytics/analytics.module.d.ts +34 -0
- package/dist/runtime/subsystems/analytics/analytics.module.js +117 -0
- package/dist/runtime/subsystems/analytics/analytics.module.js.map +1 -0
- package/dist/runtime/subsystems/analytics/analytics.tokens.d.ts +24 -0
- package/dist/runtime/subsystems/analytics/analytics.tokens.js +10 -0
- package/dist/runtime/subsystems/analytics/analytics.tokens.js.map +1 -0
- package/dist/runtime/subsystems/analytics/cube-backend.d.ts +28 -0
- package/dist/runtime/subsystems/analytics/cube-backend.js +71 -0
- package/dist/runtime/subsystems/analytics/cube-backend.js.map +1 -0
- package/dist/runtime/subsystems/analytics/index.d.ts +6 -0
- package/dist/runtime/subsystems/analytics/index.js +122 -0
- package/dist/runtime/subsystems/analytics/index.js.map +1 -0
- package/dist/runtime/subsystems/analytics/noop-backend.d.ts +7 -0
- package/dist/runtime/subsystems/analytics/noop-backend.js +25 -0
- package/dist/runtime/subsystems/analytics/noop-backend.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.d.ts +43 -0
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js +133 -0
- package/dist/runtime/subsystems/cache/cache.drizzle-backend.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.memory-backend.d.ts +21 -0
- package/dist/runtime/subsystems/cache/cache.memory-backend.js +100 -0
- package/dist/runtime/subsystems/cache/cache.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.module.d.ts +37 -0
- package/dist/runtime/subsystems/cache/cache.module.js +272 -0
- package/dist/runtime/subsystems/cache/cache.module.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.protocol.d.ts +42 -0
- package/dist/runtime/subsystems/cache/cache.protocol.js +1 -0
- package/dist/runtime/subsystems/cache/cache.protocol.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.schema.d.ts +64 -0
- package/dist/runtime/subsystems/cache/cache.schema.js +18 -0
- package/dist/runtime/subsystems/cache/cache.schema.js.map +1 -0
- package/dist/runtime/subsystems/cache/cache.tokens.d.ts +18 -0
- package/dist/runtime/subsystems/cache/cache.tokens.js +8 -0
- package/dist/runtime/subsystems/cache/cache.tokens.js.map +1 -0
- package/dist/runtime/subsystems/cache/index.d.ts +11 -0
- package/dist/runtime/subsystems/cache/index.js +277 -0
- package/dist/runtime/subsystems/cache/index.js.map +1 -0
- package/dist/runtime/subsystems/events/domain-events.schema.d.ts +187 -0
- package/dist/runtime/subsystems/events/domain-events.schema.js +32 -0
- package/dist/runtime/subsystems/events/domain-events.schema.js.map +1 -0
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.d.ts +38 -0
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js +199 -0
- package/dist/runtime/subsystems/events/event-bus.drizzle-backend.js.map +1 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.d.ts +18 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js +71 -0
- package/dist/runtime/subsystems/events/event-bus.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/events/event-bus.protocol.d.ts +52 -0
- package/dist/runtime/subsystems/events/event-bus.protocol.js +1 -0
- package/dist/runtime/subsystems/events/event-bus.protocol.js.map +1 -0
- package/dist/runtime/subsystems/events/event-bus.redis-backend.d.ts +95 -0
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js +229 -0
- package/dist/runtime/subsystems/events/event-bus.redis-backend.js.map +1 -0
- package/dist/runtime/subsystems/events/events.module.d.ts +46 -0
- package/dist/runtime/subsystems/events/events.module.js +531 -0
- package/dist/runtime/subsystems/events/events.module.js.map +1 -0
- package/dist/runtime/subsystems/events/events.tokens.d.ts +19 -0
- package/dist/runtime/subsystems/events/events.tokens.js +8 -0
- package/dist/runtime/subsystems/events/events.tokens.js.map +1 -0
- package/dist/runtime/subsystems/events/index.d.ts +12 -0
- package/dist/runtime/subsystems/events/index.js +536 -0
- package/dist/runtime/subsystems/events/index.js.map +1 -0
- package/dist/runtime/subsystems/index.d.ts +24 -0
- package/dist/runtime/subsystems/index.js +1643 -0
- package/dist/runtime/subsystems/index.js.map +1 -0
- package/dist/runtime/subsystems/jobs/index.d.ts +14 -0
- package/dist/runtime/subsystems/jobs/index.js +680 -0
- package/dist/runtime/subsystems/jobs/index.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.d.ts +54 -0
- package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.js +186 -0
- package/dist/runtime/subsystems/jobs/job-queue.bullmq-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.d.ts +38 -0
- package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.js +228 -0
- package/dist/runtime/subsystems/jobs/job-queue.drizzle-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.memory-backend.d.ts +12 -0
- package/dist/runtime/subsystems/jobs/job-queue.memory-backend.js +44 -0
- package/dist/runtime/subsystems/jobs/job-queue.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.protocol.d.ts +48 -0
- package/dist/runtime/subsystems/jobs/job-queue.protocol.js +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.protocol.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.redis-backend.d.ts +46 -0
- package/dist/runtime/subsystems/jobs/job-queue.redis-backend.js +187 -0
- package/dist/runtime/subsystems/jobs/job-queue.redis-backend.js.map +1 -0
- package/dist/runtime/subsystems/jobs/job-queue.schema.d.ts +237 -0
- package/dist/runtime/subsystems/jobs/job-queue.schema.js +44 -0
- package/dist/runtime/subsystems/jobs/job-queue.schema.js.map +1 -0
- package/dist/runtime/subsystems/jobs/jobs.module.d.ts +18 -0
- package/dist/runtime/subsystems/jobs/jobs.module.js +676 -0
- package/dist/runtime/subsystems/jobs/jobs.module.js.map +1 -0
- package/dist/runtime/subsystems/jobs/jobs.tokens.d.ts +13 -0
- package/dist/runtime/subsystems/jobs/jobs.tokens.js +8 -0
- package/dist/runtime/subsystems/jobs/jobs.tokens.js.map +1 -0
- package/dist/runtime/subsystems/storage/index.d.ts +6 -0
- package/dist/runtime/subsystems/storage/index.js +204 -0
- package/dist/runtime/subsystems/storage/index.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.local-backend.d.ts +18 -0
- package/dist/runtime/subsystems/storage/storage.local-backend.js +108 -0
- package/dist/runtime/subsystems/storage/storage.local-backend.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.memory-backend.d.ts +28 -0
- package/dist/runtime/subsystems/storage/storage.memory-backend.js +72 -0
- package/dist/runtime/subsystems/storage/storage.memory-backend.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.module.d.ts +40 -0
- package/dist/runtime/subsystems/storage/storage.module.js +201 -0
- package/dist/runtime/subsystems/storage/storage.module.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.protocol.d.ts +69 -0
- package/dist/runtime/subsystems/storage/storage.protocol.js +1 -0
- package/dist/runtime/subsystems/storage/storage.protocol.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.tokens.d.ts +11 -0
- package/dist/runtime/subsystems/storage/storage.tokens.js +6 -0
- package/dist/runtime/subsystems/storage/storage.tokens.js.map +1 -0
- package/dist/runtime/subsystems/storage/storage.utils.d.ts +9 -0
- package/dist/runtime/subsystems/storage/storage.utils.js +18 -0
- package/dist/runtime/subsystems/storage/storage.utils.js.map +1 -0
- package/dist/runtime/types/drizzle.d.ts +17 -0
- package/dist/runtime/types/drizzle.js +1 -0
- package/dist/runtime/types/drizzle.js.map +1 -0
- package/dist/src/cli/index.d.ts +1 -0
- package/dist/src/cli/index.js +7365 -0
- package/dist/src/cli/index.js.map +1 -0
- package/dist/src/index.d.ts +2384 -0
- package/dist/src/index.js +2198 -0
- package/dist/src/index.js.map +1 -0
- package/package.json +114 -0
- package/templates/broadcast/new/backend-interface.ejs.t +47 -0
- package/templates/broadcast/new/bridge-listener.ejs.t +67 -0
- package/templates/broadcast/new/channel.ejs.t +77 -0
- package/templates/broadcast/new/index.ejs.t +21 -0
- package/templates/broadcast/new/memory-backend.ejs.t +87 -0
- package/templates/broadcast/new/module.ejs.t +57 -0
- package/templates/broadcast/new/prompt.js +268 -0
- package/templates/broadcast/new/websocket-backend.ejs.t +259 -0
- package/templates/entity/new/backend/application/commands/create.ejs.t +55 -0
- package/templates/entity/new/backend/application/commands/delete.ejs.t +45 -0
- package/templates/entity/new/backend/application/commands/grouped-index.ejs.t +149 -0
- package/templates/entity/new/backend/application/commands/index.ejs.t +15 -0
- package/templates/entity/new/backend/application/commands/update.ejs.t +58 -0
- package/templates/entity/new/backend/application/queries/declarative-queries.ejs.t +36 -0
- package/templates/entity/new/backend/application/queries/get-by-id.ejs.t +42 -0
- package/templates/entity/new/backend/application/queries/grouped-index.ejs.t +81 -0
- package/templates/entity/new/backend/application/queries/index.ejs.t +14 -0
- package/templates/entity/new/backend/application/queries/list.ejs.t +36 -0
- package/templates/entity/new/backend/application/schemas/_inject-index.ejs.t +7 -0
- package/templates/entity/new/backend/application/schemas/dto.ejs.t +45 -0
- package/templates/entity/new/backend/database/_inject-index.ejs.t +7 -0
- package/templates/entity/new/backend/database/electric-migration.ejs.t +21 -0
- package/templates/entity/new/backend/database/repository.ejs.t +450 -0
- package/templates/entity/new/backend/database/schema.ejs.t +248 -0
- package/templates/entity/new/backend/domain/_inject-index.ejs.t +12 -0
- package/templates/entity/new/backend/domain/entity.ejs.t +108 -0
- package/templates/entity/new/backend/domain/grouped-index.ejs.t +163 -0
- package/templates/entity/new/backend/domain/index.ejs.t +15 -0
- package/templates/entity/new/backend/domain/repository-interface.ejs.t +71 -0
- package/templates/entity/new/backend/modules/core/_ensure-anchor-tokens.ejs.t +10 -0
- package/templates/entity/new/backend/modules/core/_inject-token.ejs.t +7 -0
- package/templates/entity/new/backend/modules/core/module.ejs.t +67 -0
- package/templates/entity/new/backend/modules/trpc/module.ejs.t +67 -0
- package/templates/entity/new/backend/presentation/controller.ejs.t +201 -0
- package/templates/entity/new/clean-lite-ps/controller.ejs.t +37 -0
- package/templates/entity/new/clean-lite-ps/dto/create.ejs.t +17 -0
- package/templates/entity/new/clean-lite-ps/dto/output.ejs.t +25 -0
- package/templates/entity/new/clean-lite-ps/dto/update.ejs.t +11 -0
- package/templates/entity/new/clean-lite-ps/entity.ejs.t +52 -0
- package/templates/entity/new/clean-lite-ps/index.ejs.t +20 -0
- package/templates/entity/new/clean-lite-ps/module.ejs.t +43 -0
- package/templates/entity/new/clean-lite-ps/prompt-extension.js +617 -0
- package/templates/entity/new/clean-lite-ps/repository.ejs.t +62 -0
- package/templates/entity/new/clean-lite-ps/service.ejs.t +34 -0
- package/templates/entity/new/clean-lite-ps/use-cases/declarative-queries.ejs.t +34 -0
- package/templates/entity/new/clean-lite-ps/use-cases/find-by-id.ejs.t +16 -0
- package/templates/entity/new/clean-lite-ps/use-cases/list.ejs.t +16 -0
- package/templates/entity/new/frontend/_inject-entities-entry.ejs.t +7 -0
- package/templates/entity/new/frontend/_inject-entities-import.ejs.t +7 -0
- package/templates/entity/new/frontend/collections/_ensure-anchor-collections.ejs.t +10 -0
- package/templates/entity/new/frontend/collections/_inject-index.ejs.t +9 -0
- package/templates/entity/new/frontend/collections/_inject-schema-import.ejs.t +9 -0
- package/templates/entity/new/frontend/collections/collection.ejs.t +61 -0
- package/templates/entity/new/frontend/collections/collections-base.ejs.t +24 -0
- package/templates/entity/new/frontend/entity/collection.ejs.t +172 -0
- package/templates/entity/new/frontend/entity/combined.ejs.t +474 -0
- package/templates/entity/new/frontend/entity/fields.ejs.t +104 -0
- package/templates/entity/new/frontend/entity/hooks.ejs.t +73 -0
- package/templates/entity/new/frontend/entity/index.ejs.t +21 -0
- package/templates/entity/new/frontend/entity/mutation-hooks.ejs.t +84 -0
- package/templates/entity/new/frontend/entity/mutations.ejs.t +38 -0
- package/templates/entity/new/frontend/entity/types.ejs.t +59 -0
- package/templates/entity/new/frontend/generated/_inject-index-export.ejs.t +7 -0
- package/templates/entity/new/frontend/generated/_inject-index-import.ejs.t +7 -0
- package/templates/entity/new/frontend/generated/_inject-index-registry.ejs.t +7 -0
- package/templates/entity/new/frontend/store/_inject-collection-import.ejs.t +9 -0
- package/templates/entity/new/frontend/store/_inject-collections.ejs.t +9 -0
- package/templates/entity/new/frontend/store/_inject-entity.ejs.t +9 -0
- package/templates/entity/new/frontend/store/_inject-import.ejs.t +9 -0
- package/templates/entity/new/frontend/store/_inject-lookups.ejs.t +9 -0
- package/templates/entity/new/frontend/store/_inject-resolve.ejs.t +10 -0
- package/templates/entity/new/frontend/store/hooks.ejs.t +72 -0
- package/templates/entity/new/frontend/unified-entity.ejs.t +28 -0
- package/templates/entity/new/prompt.js +1421 -0
- package/templates/relationship/new/controller.ejs.t +36 -0
- package/templates/relationship/new/dto/create.ejs.t +41 -0
- package/templates/relationship/new/dto/output.ejs.t +44 -0
- package/templates/relationship/new/dto/update.ejs.t +10 -0
- package/templates/relationship/new/entity.ejs.t +98 -0
- package/templates/relationship/new/index.ejs.t +19 -0
- package/templates/relationship/new/module.ejs.t +35 -0
- package/templates/relationship/new/prompt.js +682 -0
- package/templates/relationship/new/repository.ejs.t +54 -0
- package/templates/relationship/new/service.ejs.t +31 -0
- package/templates/relationship/new/use-cases/declarative-queries.ejs.t +34 -0
- package/templates/relationship/new/use-cases/find-by-id.ejs.t +16 -0
- package/templates/relationship/new/use-cases/list.ejs.t +16 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { OnModuleInit, OnModuleDestroy } from '@nestjs/common';
|
|
2
|
+
import { IEventBus, DomainEvent, DrizzleTransaction } from './event-bus.protocol.js';
|
|
3
|
+
import '../../types/drizzle.js';
|
|
4
|
+
import 'drizzle-orm/node-postgres';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* RedisEventBus — Redis Pub/Sub backend for the event bus.
|
|
8
|
+
*
|
|
9
|
+
* Publishes events to Redis channels and dispatches incoming messages to
|
|
10
|
+
* registered in-process subscribers. Events are serialized as JSON strings.
|
|
11
|
+
*
|
|
12
|
+
* Channel naming:
|
|
13
|
+
* - Per-type channel: events:{event.type} (e.g. events:contact_created)
|
|
14
|
+
* - Catch-all channel: events:*
|
|
15
|
+
*
|
|
16
|
+
* Transactional semantics:
|
|
17
|
+
* The `tx` parameter (Drizzle transaction) is accepted to satisfy the
|
|
18
|
+
* IEventBus interface but has no effect — Redis Pub/Sub is not transactional.
|
|
19
|
+
* Events published with a `tx` argument are dispatched immediately without
|
|
20
|
+
* waiting for the surrounding transaction to commit. If you need
|
|
21
|
+
* at-least-once delivery tied to a database transaction, use DrizzleEventBus.
|
|
22
|
+
*
|
|
23
|
+
* Connection model:
|
|
24
|
+
* ioredis requires a dedicated connection for subscribers (a client in
|
|
25
|
+
* subscribe mode cannot issue regular commands). This backend creates two
|
|
26
|
+
* clients: one for publishing (`publisher`) and one for subscribing
|
|
27
|
+
* (`subscriber`). Both are connected on module init and disconnected on
|
|
28
|
+
* module destroy.
|
|
29
|
+
*
|
|
30
|
+
* Usage:
|
|
31
|
+
* EventsModule.forRoot({ backend: 'redis', redisUrl: 'redis://localhost:6379' })
|
|
32
|
+
*
|
|
33
|
+
* Requires `ioredis` — install it separately if you use this backend:
|
|
34
|
+
* npm install ioredis / bun add ioredis
|
|
35
|
+
*/
|
|
36
|
+
|
|
37
|
+
declare class RedisEventBus implements IEventBus, OnModuleInit, OnModuleDestroy {
|
|
38
|
+
private readonly redisUrl;
|
|
39
|
+
private readonly logger;
|
|
40
|
+
private publisher;
|
|
41
|
+
private subscriber;
|
|
42
|
+
private connected;
|
|
43
|
+
/**
|
|
44
|
+
* In-process subscriber registry. Handlers registered here are called when
|
|
45
|
+
* a message arrives on the subscriber client — keeping fan-out within the
|
|
46
|
+
* same process without an extra round-trip through Redis.
|
|
47
|
+
*/
|
|
48
|
+
private readonly handlers;
|
|
49
|
+
/**
|
|
50
|
+
* Track which event types have active Redis subscriptions.
|
|
51
|
+
* Used to avoid subscribing multiple times to the same type channel.
|
|
52
|
+
*/
|
|
53
|
+
private readonly subscribedTypes;
|
|
54
|
+
constructor(redisUrl: string);
|
|
55
|
+
onModuleInit(): Promise<void>;
|
|
56
|
+
onModuleDestroy(): Promise<void>;
|
|
57
|
+
/**
|
|
58
|
+
* Publish a single event.
|
|
59
|
+
*
|
|
60
|
+
* `tx` is accepted but ignored — see module-level JSDoc for details.
|
|
61
|
+
*/
|
|
62
|
+
publish(event: DomainEvent, tx?: DrizzleTransaction): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Publish multiple events using a pipeline so all PUBLISH commands are sent
|
|
65
|
+
* in a single round-trip.
|
|
66
|
+
*
|
|
67
|
+
* `tx` is accepted but ignored — see module-level JSDoc for details.
|
|
68
|
+
*/
|
|
69
|
+
publishMany(events: DomainEvent[], tx?: DrizzleTransaction): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Register a handler for a specific event type.
|
|
72
|
+
* Returns an unsubscribe function — call it to remove the handler.
|
|
73
|
+
*
|
|
74
|
+
* On first handler for a type, subscribes to the per-type Redis channel.
|
|
75
|
+
* On removal of the last handler for a type, unsubscribes from the channel.
|
|
76
|
+
*/
|
|
77
|
+
subscribe<T extends DomainEvent = DomainEvent>(eventType: string, handler: (event: T) => Promise<void>): () => void;
|
|
78
|
+
private assertConnected;
|
|
79
|
+
private serialize;
|
|
80
|
+
private deserialize;
|
|
81
|
+
private handleMessage;
|
|
82
|
+
private dispatch;
|
|
83
|
+
/**
|
|
84
|
+
* Subscribe to a per-type Redis channel.
|
|
85
|
+
* Called lazily when the first handler is registered for a type.
|
|
86
|
+
*/
|
|
87
|
+
private subscribeToType;
|
|
88
|
+
/**
|
|
89
|
+
* Unsubscribe from a per-type Redis channel.
|
|
90
|
+
* Called when the last handler for a type is removed.
|
|
91
|
+
*/
|
|
92
|
+
private unsubscribeFromType;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export { RedisEventBus };
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
3
|
+
var __decorateClass = (decorators, target, key, kind) => {
|
|
4
|
+
var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
|
|
5
|
+
for (var i = decorators.length - 1, decorator; i >= 0; i--)
|
|
6
|
+
if (decorator = decorators[i])
|
|
7
|
+
result = (kind ? decorator(target, key, result) : decorator(result)) || result;
|
|
8
|
+
if (kind && result) __defProp(target, key, result);
|
|
9
|
+
return result;
|
|
10
|
+
};
|
|
11
|
+
var __decorateParam = (index, decorator) => (target, key) => decorator(target, key, index);
|
|
12
|
+
|
|
13
|
+
// runtime/subsystems/events/event-bus.redis-backend.ts
|
|
14
|
+
import { Injectable, Inject, Logger } from "@nestjs/common";
|
|
15
|
+
|
|
16
|
+
// runtime/subsystems/events/events.tokens.ts
|
|
17
|
+
var REDIS_URL = /* @__PURE__ */ Symbol("REDIS_URL");
|
|
18
|
+
|
|
19
|
+
// runtime/subsystems/events/event-bus.redis-backend.ts
|
|
20
|
+
var CHANNEL_PREFIX = "events:";
|
|
21
|
+
async function createRedisClient(url) {
|
|
22
|
+
let Redis;
|
|
23
|
+
try {
|
|
24
|
+
const mod = await import("ioredis");
|
|
25
|
+
Redis = mod.default ?? mod;
|
|
26
|
+
} catch {
|
|
27
|
+
throw new Error(
|
|
28
|
+
'RedisEventBus requires the "ioredis" package. Install it with: npm install ioredis'
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
return new Redis(url);
|
|
32
|
+
}
|
|
33
|
+
var RedisEventBus = class {
|
|
34
|
+
constructor(redisUrl) {
|
|
35
|
+
this.redisUrl = redisUrl;
|
|
36
|
+
}
|
|
37
|
+
redisUrl;
|
|
38
|
+
logger = new Logger(RedisEventBus.name);
|
|
39
|
+
publisher = null;
|
|
40
|
+
subscriber = null;
|
|
41
|
+
connected = false;
|
|
42
|
+
/**
|
|
43
|
+
* In-process subscriber registry. Handlers registered here are called when
|
|
44
|
+
* a message arrives on the subscriber client — keeping fan-out within the
|
|
45
|
+
* same process without an extra round-trip through Redis.
|
|
46
|
+
*/
|
|
47
|
+
handlers = /* @__PURE__ */ new Map();
|
|
48
|
+
/**
|
|
49
|
+
* Track which event types have active Redis subscriptions.
|
|
50
|
+
* Used to avoid subscribing multiple times to the same type channel.
|
|
51
|
+
*/
|
|
52
|
+
subscribedTypes = /* @__PURE__ */ new Set();
|
|
53
|
+
// ============================================================================
|
|
54
|
+
// Lifecycle
|
|
55
|
+
// ============================================================================
|
|
56
|
+
async onModuleInit() {
|
|
57
|
+
this.publisher = await createRedisClient(this.redisUrl);
|
|
58
|
+
this.subscriber = await createRedisClient(this.redisUrl);
|
|
59
|
+
this.publisher.on(
|
|
60
|
+
"error",
|
|
61
|
+
(err) => this.logger.error(`Redis publisher error: ${err.message}`, err.stack)
|
|
62
|
+
);
|
|
63
|
+
this.subscriber.on(
|
|
64
|
+
"error",
|
|
65
|
+
(err) => this.logger.error(`Redis subscriber error: ${err.message}`, err.stack)
|
|
66
|
+
);
|
|
67
|
+
this.subscriber.on("message", (channel, message) => {
|
|
68
|
+
void this.handleMessage(channel, message);
|
|
69
|
+
});
|
|
70
|
+
this.connected = true;
|
|
71
|
+
this.logger.log(`RedisEventBus connected to ${this.redisUrl}`);
|
|
72
|
+
}
|
|
73
|
+
async onModuleDestroy() {
|
|
74
|
+
this.connected = false;
|
|
75
|
+
if (this.subscriber) {
|
|
76
|
+
await this.subscriber.unsubscribe();
|
|
77
|
+
this.subscriber.disconnect();
|
|
78
|
+
this.subscriber = null;
|
|
79
|
+
}
|
|
80
|
+
if (this.publisher) {
|
|
81
|
+
this.publisher.disconnect();
|
|
82
|
+
this.publisher = null;
|
|
83
|
+
}
|
|
84
|
+
this.subscribedTypes.clear();
|
|
85
|
+
this.logger.log("RedisEventBus disconnected");
|
|
86
|
+
}
|
|
87
|
+
// ============================================================================
|
|
88
|
+
// IEventBus
|
|
89
|
+
// ============================================================================
|
|
90
|
+
/**
|
|
91
|
+
* Publish a single event.
|
|
92
|
+
*
|
|
93
|
+
* `tx` is accepted but ignored — see module-level JSDoc for details.
|
|
94
|
+
*/
|
|
95
|
+
async publish(event, tx) {
|
|
96
|
+
void tx;
|
|
97
|
+
this.assertConnected();
|
|
98
|
+
const payload = this.serialize(event);
|
|
99
|
+
const channel = `${CHANNEL_PREFIX}${event.type}`;
|
|
100
|
+
await this.publisher.publish(channel, payload);
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Publish multiple events using a pipeline so all PUBLISH commands are sent
|
|
104
|
+
* in a single round-trip.
|
|
105
|
+
*
|
|
106
|
+
* `tx` is accepted but ignored — see module-level JSDoc for details.
|
|
107
|
+
*/
|
|
108
|
+
async publishMany(events, tx) {
|
|
109
|
+
void tx;
|
|
110
|
+
if (events.length === 0) return;
|
|
111
|
+
this.assertConnected();
|
|
112
|
+
const pipeline = this.publisher.pipeline();
|
|
113
|
+
for (const event of events) {
|
|
114
|
+
const payload = this.serialize(event);
|
|
115
|
+
const channel = `${CHANNEL_PREFIX}${event.type}`;
|
|
116
|
+
pipeline.publish(channel, payload);
|
|
117
|
+
}
|
|
118
|
+
await pipeline.exec();
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Register a handler for a specific event type.
|
|
122
|
+
* Returns an unsubscribe function — call it to remove the handler.
|
|
123
|
+
*
|
|
124
|
+
* On first handler for a type, subscribes to the per-type Redis channel.
|
|
125
|
+
* On removal of the last handler for a type, unsubscribes from the channel.
|
|
126
|
+
*/
|
|
127
|
+
subscribe(eventType, handler) {
|
|
128
|
+
if (!this.handlers.has(eventType)) {
|
|
129
|
+
this.handlers.set(eventType, /* @__PURE__ */ new Set());
|
|
130
|
+
void this.subscribeToType(eventType);
|
|
131
|
+
}
|
|
132
|
+
const set = this.handlers.get(eventType);
|
|
133
|
+
const h = handler;
|
|
134
|
+
set.add(h);
|
|
135
|
+
return () => {
|
|
136
|
+
set.delete(h);
|
|
137
|
+
if (set.size === 0) {
|
|
138
|
+
this.handlers.delete(eventType);
|
|
139
|
+
void this.unsubscribeFromType(eventType);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
// ============================================================================
|
|
144
|
+
// Internal helpers
|
|
145
|
+
// ============================================================================
|
|
146
|
+
assertConnected() {
|
|
147
|
+
if (!this.connected || !this.publisher) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
"RedisEventBus is not connected. Ensure the module has been initialised before publishing."
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
serialize(event) {
|
|
154
|
+
return JSON.stringify({
|
|
155
|
+
...event,
|
|
156
|
+
occurredAt: event.occurredAt.toISOString()
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
deserialize(raw) {
|
|
160
|
+
const parsed = JSON.parse(raw);
|
|
161
|
+
return {
|
|
162
|
+
...parsed,
|
|
163
|
+
occurredAt: new Date(parsed.occurredAt)
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
async handleMessage(channel, message) {
|
|
167
|
+
let event;
|
|
168
|
+
try {
|
|
169
|
+
event = this.deserialize(message);
|
|
170
|
+
} catch (err) {
|
|
171
|
+
this.logger.warn(`Failed to deserialize event on channel "${channel}": ${err}`);
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
await this.dispatch(event);
|
|
175
|
+
}
|
|
176
|
+
async dispatch(event) {
|
|
177
|
+
const set = this.handlers.get(event.type);
|
|
178
|
+
if (!set) return;
|
|
179
|
+
for (const handler of set) {
|
|
180
|
+
try {
|
|
181
|
+
await handler(event);
|
|
182
|
+
} catch (err) {
|
|
183
|
+
this.logger.error(
|
|
184
|
+
`Handler error for event type "${event.type}" (id: ${event.id}): ${err}`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Subscribe to a per-type Redis channel.
|
|
191
|
+
* Called lazily when the first handler is registered for a type.
|
|
192
|
+
*/
|
|
193
|
+
async subscribeToType(eventType) {
|
|
194
|
+
if (this.subscribedTypes.has(eventType)) {
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const channel = `${CHANNEL_PREFIX}${eventType}`;
|
|
198
|
+
try {
|
|
199
|
+
await this.subscriber.subscribe(channel);
|
|
200
|
+
this.subscribedTypes.add(eventType);
|
|
201
|
+
} catch (err) {
|
|
202
|
+
this.logger.error(`Failed to subscribe to channel "${channel}": ${err}`);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Unsubscribe from a per-type Redis channel.
|
|
207
|
+
* Called when the last handler for a type is removed.
|
|
208
|
+
*/
|
|
209
|
+
async unsubscribeFromType(eventType) {
|
|
210
|
+
if (!this.subscribedTypes.has(eventType)) {
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const channel = `${CHANNEL_PREFIX}${eventType}`;
|
|
214
|
+
try {
|
|
215
|
+
await this.subscriber.unsubscribe(channel);
|
|
216
|
+
this.subscribedTypes.delete(eventType);
|
|
217
|
+
} catch (err) {
|
|
218
|
+
this.logger.error(`Failed to unsubscribe from channel "${channel}": ${err}`);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
RedisEventBus = __decorateClass([
|
|
223
|
+
Injectable(),
|
|
224
|
+
__decorateParam(0, Inject(REDIS_URL))
|
|
225
|
+
], RedisEventBus);
|
|
226
|
+
export {
|
|
227
|
+
RedisEventBus
|
|
228
|
+
};
|
|
229
|
+
//# sourceMappingURL=event-bus.redis-backend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../runtime/subsystems/events/event-bus.redis-backend.ts","../../../../runtime/subsystems/events/events.tokens.ts"],"sourcesContent":["/**\n * RedisEventBus — Redis Pub/Sub backend for the event bus.\n *\n * Publishes events to Redis channels and dispatches incoming messages to\n * registered in-process subscribers. Events are serialized as JSON strings.\n *\n * Channel naming:\n * - Per-type channel: events:{event.type} (e.g. events:contact_created)\n * - Catch-all channel: events:*\n *\n * Transactional semantics:\n * The `tx` parameter (Drizzle transaction) is accepted to satisfy the\n * IEventBus interface but has no effect — Redis Pub/Sub is not transactional.\n * Events published with a `tx` argument are dispatched immediately without\n * waiting for the surrounding transaction to commit. If you need\n * at-least-once delivery tied to a database transaction, use DrizzleEventBus.\n *\n * Connection model:\n * ioredis requires a dedicated connection for subscribers (a client in\n * subscribe mode cannot issue regular commands). This backend creates two\n * clients: one for publishing (`publisher`) and one for subscribing\n * (`subscriber`). Both are connected on module init and disconnected on\n * module destroy.\n *\n * Usage:\n * EventsModule.forRoot({ backend: 'redis', redisUrl: 'redis://localhost:6379' })\n *\n * Requires `ioredis` — install it separately if you use this backend:\n * npm install ioredis / bun add ioredis\n */\nimport { Injectable, OnModuleInit, OnModuleDestroy, Inject, Logger } from '@nestjs/common';\nimport type { DomainEvent, DrizzleTransaction, IEventBus } from './event-bus.protocol';\nimport { REDIS_URL } from './events.tokens';\n\n/** Redis channel prefix for all domain events. */\nconst CHANNEL_PREFIX = 'events:';\n/** Catch-all channel that receives every published event. */\nconst WILDCARD_CHANNEL = 'events:*';\n\n// ioredis is an optional peer dependency; import lazily so consumers who do\n// not use this backend do not need it on their classpath.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype RedisClient = any;\n\nasync function createRedisClient(url: string): Promise<RedisClient> {\n let Redis: { new (url: string): RedisClient };\n try {\n const mod = await import('ioredis');\n Redis = mod.default ?? mod;\n } catch {\n throw new Error(\n 'RedisEventBus requires the \"ioredis\" package. Install it with: npm install ioredis',\n );\n }\n return new Redis(url);\n}\n\n@Injectable()\nexport class RedisEventBus implements IEventBus, OnModuleInit, OnModuleDestroy {\n private readonly logger = new Logger(RedisEventBus.name);\n\n private publisher: RedisClient | null = null;\n private subscriber: RedisClient | null = null;\n private connected = false;\n\n /**\n * In-process subscriber registry. Handlers registered here are called when\n * a message arrives on the subscriber client — keeping fan-out within the\n * same process without an extra round-trip through Redis.\n */\n private readonly handlers = new Map<string, Set<(event: DomainEvent) => Promise<void>>>();\n\n /**\n * Track which event types have active Redis subscriptions.\n * Used to avoid subscribing multiple times to the same type channel.\n */\n private readonly subscribedTypes = new Set<string>();\n\n constructor(@Inject(REDIS_URL) private readonly redisUrl: string) {}\n\n // ============================================================================\n // Lifecycle\n // ============================================================================\n\n async onModuleInit(): Promise<void> {\n this.publisher = await createRedisClient(this.redisUrl);\n this.subscriber = await createRedisClient(this.redisUrl);\n\n // Surface connection errors without crashing the process.\n this.publisher.on('error', (err: Error) =>\n this.logger.error(`Redis publisher error: ${err.message}`, err.stack),\n );\n this.subscriber.on('error', (err: Error) =>\n this.logger.error(`Redis subscriber error: ${err.message}`, err.stack),\n );\n\n // Set up message listener for per-type subscriptions.\n // Subscriptions are created lazily when the first handler is registered for a type.\n this.subscriber.on('message', (channel: string, message: string) => {\n void this.handleMessage(channel, message);\n });\n\n this.connected = true;\n this.logger.log(`RedisEventBus connected to ${this.redisUrl}`);\n }\n\n async onModuleDestroy(): Promise<void> {\n this.connected = false;\n\n if (this.subscriber) {\n // Unsubscribe from all channels and disconnect the subscriber.\n // unsubscribe() with no args unsubscribes from all channels.\n await this.subscriber.unsubscribe();\n this.subscriber.disconnect();\n this.subscriber = null;\n }\n\n if (this.publisher) {\n this.publisher.disconnect();\n this.publisher = null;\n }\n\n this.subscribedTypes.clear();\n this.logger.log('RedisEventBus disconnected');\n }\n\n // ============================================================================\n // IEventBus\n // ============================================================================\n\n /**\n * Publish a single event.\n *\n * `tx` is accepted but ignored — see module-level JSDoc for details.\n */\n async publish(event: DomainEvent, tx?: DrizzleTransaction): Promise<void> {\n void tx; // intentionally unused — Redis Pub/Sub is not transactional\n this.assertConnected();\n\n const payload = this.serialize(event);\n const channel = `${CHANNEL_PREFIX}${event.type}`;\n\n await this.publisher!.publish(channel, payload);\n }\n\n /**\n * Publish multiple events using a pipeline so all PUBLISH commands are sent\n * in a single round-trip.\n *\n * `tx` is accepted but ignored — see module-level JSDoc for details.\n */\n async publishMany(events: DomainEvent[], tx?: DrizzleTransaction): Promise<void> {\n void tx; // intentionally unused — Redis Pub/Sub is not transactional\n if (events.length === 0) return;\n this.assertConnected();\n\n const pipeline = this.publisher!.pipeline();\n for (const event of events) {\n const payload = this.serialize(event);\n const channel = `${CHANNEL_PREFIX}${event.type}`;\n pipeline.publish(channel, payload);\n }\n await pipeline.exec();\n }\n\n /**\n * Register a handler for a specific event type.\n * Returns an unsubscribe function — call it to remove the handler.\n *\n * On first handler for a type, subscribes to the per-type Redis channel.\n * On removal of the last handler for a type, unsubscribes from the channel.\n */\n subscribe<T extends DomainEvent = DomainEvent>(\n eventType: string,\n handler: (event: T) => Promise<void>,\n ): () => void {\n if (!this.handlers.has(eventType)) {\n this.handlers.set(eventType, new Set());\n // First handler for this type — subscribe to the per-type channel in Redis.\n void this.subscribeToType(eventType);\n }\n const set = this.handlers.get(eventType)!;\n const h = handler as (event: DomainEvent) => Promise<void>;\n set.add(h);\n\n return () => {\n set.delete(h);\n // If no more handlers for this type, unsubscribe from the Redis channel.\n if (set.size === 0) {\n this.handlers.delete(eventType);\n void this.unsubscribeFromType(eventType);\n }\n };\n }\n\n // ============================================================================\n // Internal helpers\n // ============================================================================\n\n private assertConnected(): void {\n if (!this.connected || !this.publisher) {\n throw new Error(\n 'RedisEventBus is not connected. Ensure the module has been initialised before publishing.',\n );\n }\n }\n\n private serialize(event: DomainEvent): string {\n return JSON.stringify({\n ...event,\n occurredAt: event.occurredAt.toISOString(),\n });\n }\n\n private deserialize(raw: string): DomainEvent {\n const parsed = JSON.parse(raw) as DomainEvent & { occurredAt: string };\n return {\n ...parsed,\n occurredAt: new Date(parsed.occurredAt),\n };\n }\n\n private async handleMessage(channel: string, message: string): Promise<void> {\n let event: DomainEvent;\n try {\n event = this.deserialize(message);\n } catch (err) {\n this.logger.warn(`Failed to deserialize event on channel \"${channel}\": ${err}`);\n return;\n }\n\n await this.dispatch(event);\n }\n\n private async dispatch(event: DomainEvent): Promise<void> {\n const set = this.handlers.get(event.type);\n if (!set) return;\n for (const handler of set) {\n try {\n await handler(event);\n } catch (err) {\n this.logger.error(\n `Handler error for event type \"${event.type}\" (id: ${event.id}): ${err}`,\n );\n }\n }\n }\n\n /**\n * Subscribe to a per-type Redis channel.\n * Called lazily when the first handler is registered for a type.\n */\n private async subscribeToType(eventType: string): Promise<void> {\n if (this.subscribedTypes.has(eventType)) {\n return; // Already subscribed to this type.\n }\n\n const channel = `${CHANNEL_PREFIX}${eventType}`;\n try {\n await this.subscriber!.subscribe(channel);\n this.subscribedTypes.add(eventType);\n } catch (err) {\n this.logger.error(`Failed to subscribe to channel \"${channel}\": ${err}`);\n }\n }\n\n /**\n * Unsubscribe from a per-type Redis channel.\n * Called when the last handler for a type is removed.\n */\n private async unsubscribeFromType(eventType: string): Promise<void> {\n if (!this.subscribedTypes.has(eventType)) {\n return; // Not subscribed to this type.\n }\n\n const channel = `${CHANNEL_PREFIX}${eventType}`;\n try {\n await this.subscriber!.unsubscribe(channel);\n this.subscribedTypes.delete(eventType);\n } catch (err) {\n this.logger.error(`Failed to unsubscribe from channel \"${channel}\": ${err}`);\n }\n }\n}\n","/**\n * Injection token for the event bus.\n *\n * String constant (not Symbol) so it matches by value across import boundaries.\n * Matches the token in runtime/constants/tokens.ts — both are 'EVENT_BUS'.\n *\n * Usage in use cases:\n * ```typescript\n * constructor(@Inject(EVENT_BUS) private readonly eventBus: IEventBus) {}\n * ```\n */\nexport const EVENT_BUS = 'EVENT_BUS' as const;\n\n/**\n * Injection token for the Redis connection URL used by RedisEventBus.\n * Provided automatically by EventsModule.forRoot({ backend: 'redis' }).\n */\nexport const REDIS_URL = Symbol('REDIS_URL');\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { DynamicModule } from '@nestjs/common';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* EventsModule — DynamicModule factory for the event bus subsystem.
|
|
5
|
+
*
|
|
6
|
+
* Register once in AppModule:
|
|
7
|
+
* ```typescript
|
|
8
|
+
* @Module({
|
|
9
|
+
* imports: [
|
|
10
|
+
* EventsModule.forRoot({ backend: 'drizzle' }),
|
|
11
|
+
* ],
|
|
12
|
+
* })
|
|
13
|
+
* export class AppModule {}
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* Tests swap to the memory backend without touching application code:
|
|
17
|
+
* ```typescript
|
|
18
|
+
* Test.createTestingModule({
|
|
19
|
+
* imports: [EventsModule.forRoot({ backend: 'memory' })],
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* `global: true` means entity modules do not need to import EventsModule
|
|
24
|
+
* individually — the EVENT_BUS token is available project-wide.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
interface EventsModuleOptions {
|
|
28
|
+
backend: 'drizzle' | 'memory' | 'redis';
|
|
29
|
+
/**
|
|
30
|
+
* Redis connection URL used when `backend` is `'redis'`.
|
|
31
|
+
* Falls back to the REDIS_URL environment variable, then
|
|
32
|
+
* `redis://localhost:6379` if neither is set.
|
|
33
|
+
*/
|
|
34
|
+
redisUrl?: string;
|
|
35
|
+
}
|
|
36
|
+
interface EventsModuleAsyncOptions {
|
|
37
|
+
useFactory: (...args: unknown[]) => Promise<EventsModuleOptions> | EventsModuleOptions;
|
|
38
|
+
inject?: unknown[];
|
|
39
|
+
imports?: unknown[];
|
|
40
|
+
}
|
|
41
|
+
declare class EventsModule {
|
|
42
|
+
static forRootAsync(asyncOptions: EventsModuleAsyncOptions): DynamicModule;
|
|
43
|
+
static forRoot(options?: EventsModuleOptions): DynamicModule;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { EventsModule, type EventsModuleAsyncOptions, type EventsModuleOptions };
|