Skip to content

Core Components

Overview

The @nx/core package provides essential base classes, helpers, and infrastructure components that all backend services extend. These components standardize application setup, data access patterns, cross-service communication, real-time messaging, and event-driven architecture.

ComponentDescriptionIGNIS Reference
DefaultApplicationBase application class with auth, CORS, Swagger, and health checksApplication
SoftDeletableRepositoryRepository with soft-delete pattern (deletedAt timestamp)Repositories
BaseSocketEventServiceBase service for WebSocket event broadcasting via WebSocketEmitterWebSocket
IdentityNetworkServiceCross-service HTTP client for identity authenticationNetwork Helper
Bootstrap HelpersbootstrapApplication() and bootstrapMigration() entry-point helpersBootstrapping
RedisConnectionFactoryRedis connection management (single or cluster mode)Redis Helper
Event BusPub/sub messaging abstraction with Redis Pub/Sub adapter-

Component Hierarchy

Repository Hierarchy


BaseSocketEventService

Base service for broadcasting WebSocket events through the IGNIS WebSocketEmitter. Used by @nx/signal to implement SignalEventService.

Source: packages/core/src/base/service/base-socket-event.service.ts

MethodSignatureDescription
broadcastbroadcast<T>({ topic, data }): Promise<void>Send to all clients in the default room
sendToRoomsendToRoom<T>({ room, topic, data }): Promise<void>Send to all clients in a specific room
isReadyisReady(): booleanCheck if the WebSocketEmitter binding is available
emitterget emitter(): WebSocketEmitterLazy getter for the emitter from the DI container

Usage:

typescript
import { BaseSocketEventService } from '@nx/core';
import { BaseApplication, inject } from '@venizia/ignis';

export class MyEventService extends BaseSocketEventService {
  constructor(
    @inject({ key: CoreBindings.APPLICATION_INSTANCE })
    application: BaseApplication,
  ) {
    super(application, {
      scope: MyEventService.name,
      emitterBindingKey: '@my-package/websocket-emitter',
    });
  }

  async notifyOrderCreated(orderId: string) {
    await this.broadcast({ topic: 'order:created', data: { orderId } });
  }
}

See the IGNIS WebSocket Component for emitter configuration details.


Bootstrap Helpers

Helper functions that standardize application and migration entry points across all packages.

Source: packages/core/src/helpers/bootstraps/

bootstrapApplication

Creates and starts the application with banner display and graceful shutdown.

typescript
// packages/sale/src/index.ts
import { bootstrapApplication } from '@nx/core';
import { Application } from './application';
import { appConfig } from './common/app-config';

bootstrapApplication({
  ApplicationClass: Application,
  config: appConfig,
  options: { bannerPath: resolve(__dirname, '../resources/banner.txt') },
});

bootstrapMigration

Creates the application in migration mode and runs seed/migration processes.

typescript
// packages/sale/src/migrate.ts
import { bootstrapMigration } from '@nx/core';
import { Application } from './application';
import { getMigrationProcesses } from './migrations/processes/migration-process';

bootstrapMigration({
  ApplicationClass: Application,
  getMigrationProcesses,
});

createMigrationProcessLoader

Factory for loading migration process files from a directory.

typescript
// packages/sale/src/migrations/processes/migration-process.ts
import { createMigrationProcessLoader } from '@nx/core';

export const getMigrationProcesses = createMigrationProcessLoader({
  seedPaths: ['sale-0001-seed-order-statuses'],
  importFn: path => import(`../processes/${path}.js`),
});

See IGNIS Bootstrapping for the underlying framework lifecycle.


RedisConnectionFactory

Static factory for creating Redis connections in either single-instance or cluster mode.

Source: packages/core/src/helpers/redis/redis-connection.factory.ts

MethodSignatureDescription
createstatic create(opts: TRedisConnectionOptions): DefaultRedisHelperCreate a RedisHelper (single) or RedisClusterHelper (cluster)
parseClusterNodesstatic parseClusterNodes({ raw }): Array<{ host, port }>Parse "host1:port1,host2:port2" into node objects

Single mode:

typescript
import { RedisConnectionFactory } from '@nx/core';

const redis = RedisConnectionFactory.create({
  mode: 'single',
  name: 'cache-redis',
  host: 'localhost',
  port: 6379,
  password: 'secret',
  database: 0,
  maxRetry: 5,
  autoConnect: false,
});

Cluster mode:

typescript
const redis = RedisConnectionFactory.create({
  mode: 'cluster',
  name: 'cache-redis-cluster',
  nodes: RedisConnectionFactory.parseClusterNodes({
    raw: 'node1:6379,node2:6379,node3:6379',
  }),
  password: 'secret',
});

See IGNIS Redis Helper for RedisHelper and RedisClusterHelper API details.


Event Bus

Pub/sub messaging abstraction with a pluggable adapter pattern. Currently provides a Redis Pub/Sub adapter.

Source: packages/core/src/helpers/event-bus/

IEventBus Interface

typescript
interface IEventBus {
  publish<T>(opts: { channel: string; data: T }): Promise<void>;
  subscribe<T>(opts: { channel: string; handler: (data: T) => Promise<void> }): Promise<void>;
  unsubscribe(opts: { channel: string }): Promise<void>;
  disconnect(): Promise<void>;
}

IEventBusMessage Envelope

Every published message is wrapped in a standard envelope:

typescript
interface IEventBusMessage<T = unknown> {
  id: string;          // Snowflake ID
  type: string;        // Channel name
  publishedAt: string; // ISO timestamp
  data: T;             // Payload
  metadata?: Record<string, unknown>;
}

RedisPubSubAdapter

The default adapter using two RedisHelper instances (one publisher, one subscriber).

typescript
import { RedisPubSubAdapter } from '@nx/core';

const eventBus = new RedisPubSubAdapter({
  publisher: publisherRedisHelper,
  subscriber: subscriberRedisHelper,
});

// Subscribe
await eventBus.subscribe({
  channel: 'payment:success',
  handler: async (data) => {
    console.log('Payment succeeded:', data);
  },
});

// Publish
await eventBus.publish({
  channel: 'payment:success',
  data: { orderId: '123', amount: 50000 },
});
MethodDescription
publish({ channel, data })Wrap data in IEventBusMessage and publish to Redis
subscribe({ channel, handler })Register a handler for a channel (idempotent)
unsubscribe({ channel })Remove handler and unsubscribe from Redis
disconnect()Unsubscribe all channels and close Redis connections
getSubscriptions()Return list of subscribed channel names
getHandlerCount()Return number of registered handlers
isSubscribed(channel)Check if a channel has an active subscription

WARNING

Redis Pub/Sub does not support message acknowledgment or retry. If a handler throws an error, the message is lost. Implement retry logic within your handler if needed, or use BullMQ queues for at-least-once delivery.


Next Steps

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.