npm.io
0.30.0 • Published 2 months ago

@vytches/ddd-domain-services

Licence
MIT
Version
0.30.0
Deps
4
Size
43 kB
Vulns
0
Weekly
0

@vytches/ddd-domain-services

npm version TypeScript License: MIT

Base classes and decorators for Domain Services

Domain Services encapsulate business operations that don't belong naturally on a single aggregate or value object.

Installation

pnpm add @vytches/ddd-domain-services

What's included

Base classes
Export Kind Description
PlainDomainService class Minimal base — no logger, no DI, no event bus. For pure stateless operations.
IBaseDomainService class Base with a built-in Logger via Logger.forContext()
AsyncDomainService class IBaseDomainService with async lifecycle hooks
EventAwareDomainService class IBaseDomainService + setEventBus(bus) for domain event publishing
UnitOfWorkAwareDomainService class IBaseDomainService + setUnitOfWork(uow) for transactional coordination
Decorator
Export Kind Description
DomainService decorator Marks a class for DI auto-discovery; stores service metadata
getDomainServiceMetadata(cls) function Reads metadata set by @DomainService
getDIDomainServiceMetadata(cls) function Reads DI-specific metadata
isDomainServicePendingDIRegistration(cls) function Returns true if the class has been decorated but not yet registered
Interfaces
Export Kind Description
IDomainService interface Core service contract (has serviceId)
IAsyncDomainService interface Adds initialize() / dispose()
IEventBusAware interface setEventBus(bus) contract
IUnitOfWorkAware interface setUnitOfWork(uow) contract
DomainServiceOptions interface Options accepted by @DomainService
DIServiceMetadata interface DI metadata shape
EnhancedDomainServiceOptions interface Extended options with DI lifetime and context
Errors
Export Kind Description
ServiceCircularError class Circular service dependency detected
ServiceDuplicateError class Service registered more than once
ServiceNotFoundError class Requested service not in registry

Usage

PlainDomainService — infrastructure-free
import { PlainDomainService } from '@vytches/ddd-domain-services';

class TaxCalculator extends PlainDomainService {
  constructor() {
    super('TaxCalculator');
  }

  calculate(amount: number, rate: number): number {
    return amount * rate;
  }
}
IBaseDomainService — with logging
import { IBaseDomainService } from '@vytches/ddd-domain-services';

class PricingService extends IBaseDomainService {
  constructor() {
    super('PricingService');
  }

  applyDiscount(price: number, pct: number): number {
    this.logger.debug('Applying discount', { price, pct });
    return price * (1 - pct / 100);
  }
}
EventAwareDomainService — publish domain events
import {
  EventAwareDomainService,
  DomainService,
} from '@vytches/ddd-domain-services';
import { DomainEvent } from '@vytches/ddd-events';

@DomainService('OrderFulfillmentService', { context: 'Orders' })
class OrderFulfillmentService extends EventAwareDomainService {
  constructor() {
    super('OrderFulfillmentService');
  }

  async fulfill(orderId: string): Promise<void> {
    // ... business logic ...
    await this.eventBus?.publish(
      new DomainEvent('OrderFulfilled', { orderId })
    );
  }
}
UnitOfWorkAwareDomainService — transactional coordination
import { UnitOfWorkAwareDomainService } from '@vytches/ddd-domain-services';

class TransferService extends UnitOfWorkAwareDomainService {
  constructor() { super('TransferService'); }

  async transfer(fromId: string, toId: string, amount: number): Promise<void> {
    await this.unitOfWork?.begin();
    try {
      // ... operations ...
      await this.unitOfWork?.commit();
    } catch {
      await this.unitOfWork?.rollback();
      throw;
    }
  }
}

Package boundaries

@vytches/ddd-domain-services depends on:

  • @vytches/ddd-contractsIEventBus
  • @vytches/ddd-loggingLogger
  • @vytches/ddd-repositoriesIUnitOfWork

License

MIT

Keywords