Skip to content

ziegel-platform

The @breadstone/ziegel-platform package provides core component functionality and infrastructure for the ziegel framework. It delivers foundational component model, type conversion systems, object factories, globalization support, and service abstractions for enterprise applications.

Platform Foundation: Essential component infrastructure and cross-cutting concerns that power enterprise application development.

🚀 Why ziegel-platform?

  • 🏗️ Component Model: Interfaces for initializable, startable, stoppable components with property change notifications
  • 🔄 Type Conversion: Comprehensive type converter system with built-in converters for all primitive types
  • 🏭 Object Factories: Advanced object creation patterns with activation handling and dependency injection support
  • 🌍 Globalization: Culture providers with reactive culture management and localization support
  • 📅 Date/Time Adapters: Pluggable date/time library support for moment.js, date-fns, luxon integration
  • 💾 Caching Services: Sophisticated cache registration and management with weak reference support
  • 🎯 Decorators: Powerful memoization, notification, and type conversion decorators
  • ⏱️ Interval Management: Aggregated interval handling for periodic operations and background tasks

📦 Installation

bash
npm install @breadstone/ziegel-platform
# or
yarn add @breadstone/ziegel-platform

Dependencies: @breadstone/ziegel-core

⭐ Key Features

Component Model & Lifecycle

Enterprise component lifecycle management with standardized interfaces:

typescript
import {
  IInitializable,
  IStartable,
  IStopable,
  INotifyPropertyChanged
} from '@breadstone/ziegel-platform';

class DatabaseService implements IInitializable, IStartable, IStopable {
  private isConnected = false;

  async initialize(): Promise<void> {
    console.log('Initializing database configuration...');
    // Load configuration, validate settings
  }

  async start(): Promise<void> {
    console.log('Starting database connection...');
    this.isConnected = true;
    // Establish connections, start health checks
  }

  async stop(): Promise<void> {
    console.log('Stopping database service...');
    this.isConnected = false;
    // Close connections, cleanup resources
  }
}

// Component with property change notifications
class UserProfile implements INotifyPropertyChanged {
  private _name: string = '';

  get name(): string { return this._name; }
  set name(value: string) {
    if (this._name !== value) {
      this._name = value;
      this.notifyPropertyChanged('name');
    }
  }

  notifyPropertyChanged(propertyName: string): void {
    // Emit property change events
  }
}

Advanced Type Conversion System

Robust type conversion with support for complex scenarios:

typescript
import {
  TypeConverters,
  ArrayTypeConverter,
  BooleanTypeConverter,
  NumberTypeConverter,
  TypeConverter
} from '@breadstone/ziegel-platform';

// Built-in type converters
const stringArray = TypeConverters.array.convert(['1', '2', '3'], Number);
// Result: [1, 2, 3]

const boolValue = TypeConverters.boolean.convert('true');
// Result: true

const numberValue = TypeConverters.number.convert('42.5');
// Result: 42.5

// Custom type converter with decorator
class ApiResponse {
  constructor(public data: any, public status: number) {}
}

class ApiResponseConverter {
  convert(value: any): ApiResponse {
    return new ApiResponse(value.data, value.status);
  }
}

@TypeConverter(ApiResponse, ApiResponseConverter)
class ApiService {
  @TypeConverter(String, 'upper')
  formatResponse(data: any): string {
    return TypeConverters.string.convert(data).toUpperCase();
  }
}

Object Factory Pattern

Enterprise object creation with dependency injection support:

typescript
import { ObjectFactory, IObjectFactory } from '@breadstone/ziegel-platform';

interface IEmailService {
  sendEmail(to: string, subject: string, body: string): Promise<void>;
}

class SmtpEmailService implements IEmailService {
  async sendEmail(to: string, subject: string, body: string): Promise<void> {
    console.log(`Sending email to ${to}: ${subject}`);
  }
}

class SendGridEmailService implements IEmailService {
  async sendEmail(to: string, subject: string, body: string): Promise<void> {
    console.log(`Sending via SendGrid to ${to}: ${subject}`);
  }
}

// Factory registration
const factory = new ObjectFactory();

factory.register('EmailService', () => {
  const env = process.env.NODE_ENV;
  return env === 'production'
    ? new SendGridEmailService()
    : new SmtpEmailService();
});

factory.register('UserService', (factory) => {
  const emailService = factory.create<IEmailService&gt;('EmailService');
  return new UserService(emailService);
});

// Usage
const userService = factory.create<UserService&gt;('UserService');
// Initialize services after registration
const userRepo = container.get('IUserRepository');
userRepo.initialize();

} }

// Register provider container.addProvider(new DataServiceProvider());


### Application Builder
Streamlined application setup and configuration:

```typescript
import { ApplicationBuilder } from '@breadstone/ziegel-platform';

const app = ApplicationBuilder
  .create()
  .configureServices(services => {
    services.addSingleton('ILogger', ConsoleLogger);
    services.addTransient('IEmailService', EmailService);
  })
  .configureLogging(logging => {
    logging.setMinimumLevel('INFO');
    logging.addConsole();
  })
  .build();

await app.start();

Configuration Management

Type-safe configuration with environment support:

typescript
import { Configuration, ConfigurationBuilder } from '@breadstone/ziegel-platform';

interface AppConfig {
  database: {
    connectionString: string;
    timeout: number;
  };
  api: {
    baseUrl: string;
    timeout: number;
  };
}

const config = ConfigurationBuilder
  .create<AppConfig&gt;()
  .addJsonFile('appsettings.json')
  .addJsonFile(`appsettings.${process.env.NODE_ENV}.json`, optional: true)
  .addEnvironmentVariables()
  .build();

// Type-safe access
const dbConnection = config.get('database.connectionString');
const apiTimeout = config.get('api.timeout');

Culture Provider

Internationalization and localization support:

typescript
import { CultureProvider, CultureInfo } from '@breadstone/ziegel-platform';

const cultureProvider = new CultureProvider();

// Set application culture
cultureProvider.setCulture('de-DE');

// Get current culture info
const culture = cultureProvider.getCurrentCulture();
console.log(culture.name); // "de-DE"
console.log(culture.displayName); // "German (Germany)"

// Format numbers and dates according to culture
const numberFormat = culture.numberFormat;
const dateFormat = culture.dateTimeFormat;

Event System

Robust event-driven architecture support:

typescript
import { EventBus, Event, EventHandler } from '@breadstone/ziegel-platform';

// Define events
class UserCreatedEvent extends Event {
  constructor(public readonly userId: string, public readonly email: string) {
    super();
  }
}

// Define event handlers
@EventHandler(UserCreatedEvent)
class SendWelcomeEmailHandler {
  handle(event: UserCreatedEvent): void {
    console.log(`Sending welcome email to ${event.email}`);
  }
}

// Setup event bus
const eventBus = new EventBus();
eventBus.subscribe(UserCreatedEvent, new SendWelcomeEmailHandler());

// Publish events
await eventBus.publish(new UserCreatedEvent('123', 'user@example.com'));

Advanced Usage

Custom Service Lifetimes

Control how services are instantiated and managed:

typescript
import { ServiceLifetime } from '@breadstone/ziegel-platform';

// Singleton - one instance for the entire application
container.register(DatabaseService, ServiceLifetime.Singleton);

// Transient - new instance every time
container.register(EmailService, ServiceLifetime.Transient);

// Scoped - one instance per scope/request
container.register(UserContext, ServiceLifetime.Scoped);

Middleware Pipeline

Build processing pipelines with middleware:

typescript
import { Pipeline, Middleware } from '@breadstone/ziegel-platform';

class ValidationMiddleware implements Middleware<Request, Response&gt; {
  async invoke(context: Request, next: () => Promise&lt;Response&gt;): Promise&lt;Response&gt; {
    // Validate request
    if (!this.isValid(context)) {
      throw new ValidationError('Invalid request');
    }
    return await next();
  }
}

const pipeline = Pipeline.create<Request, Response&gt;()
  .use(new ValidationMiddleware())
  .use(new AuthenticationMiddleware())
  .use(new BusinessLogicMiddleware());

const result = await pipeline.execute(request);

Best Practices

1. Use Interface-Based Registration

Register services by interfaces for better testability:

typescript
// ✅ Good
container.bind<IUserService&gt;('IUserService').to(UserService);

// ❌ Avoid
container.register(UserService);

2. Organize with Service Providers

Group related service registrations:

typescript
class SecurityServiceProvider extends ServiceProvider {
  register(container: Container): void {
    container.bind('IAuthService').to(JwtAuthService);
    container.bind('IEncryption').to(AesEncryption);
    container.bind('IHasher').to(BcryptHasher);
  }
}

3. Use Configuration Sections

Organize configuration into logical sections:

typescript
// appsettings.json
{
  "database": {
    "connectionString": "...",
    "timeout": 30
  },
  "logging": {
    "level": "Information"
  }
}

// Access sections
const dbConfig = config.getSection('database');
const connectionString = dbConfig.get('connectionString');

4. Handle Events Asynchronously

Use async event handlers for better performance:

typescript
@EventHandler(OrderCreatedEvent)
class UpdateInventoryHandler {
  async handle(event: OrderCreatedEvent): Promise&lt;void&gt; {
    await this.inventoryService.updateStock(event.productId, event.quantity);
  }
}

Integration with Other Packages

ziegel-platform serves as the foundation for many other ziegel packages:

Testing

Mock services easily for unit testing:

typescript
import { Container } from '@breadstone/ziegel-platform';

describe('UserService', () => {
  let container: Container;
  let userService: UserService;
  let mockDatabase: jest.Mocked<DatabaseService&gt;;

  beforeEach(() => {
    mockDatabase = {
      connect: jest.fn(),
      query: jest.fn()
    } as any;

    container = new Container();
    container.bind(DatabaseService).toConstantValue(mockDatabase);
    container.bind(UserService).toSelf();

    userService = container.get(UserService);
  });

  it('should connect to database when getting users', async () => {
    await userService.getUsers();
    expect(mockDatabase.connect).toHaveBeenCalled();
  });
});

Migration Guide

From Other DI Containers

From InversifyJS

typescript
// InversifyJS
container.bind<IUserService&gt;(TYPES.UserService).to(UserService);

// ziegel-platform
container.bind<IUserService&gt;('IUserService').to(UserService);

From TypeDI

typescript
// TypeDI
@Service()
class UserService {}

// ziegel-platform
@Injectable()
class UserService {}

API Reference

For detailed API documentation, see the generated API reference.