removed old di fully and replaced with awilix
This commit is contained in:
parent
d8ae0cb3c5
commit
c6c55e2979
9 changed files with 200 additions and 747 deletions
|
|
@ -6,59 +6,89 @@
|
|||
import { Browser } from '@stock-bot/browser';
|
||||
import { createCache, type CacheProvider } from '@stock-bot/cache';
|
||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
||||
import { getLogger } from '@stock-bot/logger';
|
||||
import { getLogger, type Logger } from '@stock-bot/logger';
|
||||
import { MongoDBClient } from '@stock-bot/mongodb';
|
||||
import { createPostgreSQLClient } from '@stock-bot/postgres';
|
||||
import { createPostgreSQLClient, type PostgreSQLClient } from '@stock-bot/postgres';
|
||||
import { ProxyManager } from '@stock-bot/proxy';
|
||||
import { createQuestDBClient } from '@stock-bot/questdb';
|
||||
import { createQuestDBClient, type QuestDBClient } from '@stock-bot/questdb';
|
||||
import { type QueueManager } from '@stock-bot/queue';
|
||||
import { asFunction, asValue, createContainer, InjectionMode, type AwilixContainer } from 'awilix';
|
||||
import { z } from 'zod';
|
||||
|
||||
// Configuration types
|
||||
export interface AppConfig {
|
||||
redis: {
|
||||
enabled?: boolean;
|
||||
host: string;
|
||||
port: number;
|
||||
password?: string;
|
||||
username?: string;
|
||||
db?: number;
|
||||
};
|
||||
mongodb: {
|
||||
enabled?: boolean;
|
||||
uri: string;
|
||||
database: string;
|
||||
};
|
||||
postgres: {
|
||||
enabled?: boolean;
|
||||
host: string;
|
||||
port: number;
|
||||
database: string;
|
||||
user: string;
|
||||
password: string;
|
||||
};
|
||||
questdb?: {
|
||||
enabled?: boolean;
|
||||
host: string;
|
||||
httpPort?: number;
|
||||
pgPort?: number;
|
||||
influxPort?: number;
|
||||
database?: string;
|
||||
};
|
||||
proxy?: {
|
||||
cachePrefix?: string;
|
||||
ttl?: number;
|
||||
};
|
||||
browser?: {
|
||||
headless?: boolean;
|
||||
timeout?: number;
|
||||
};
|
||||
// Configuration schema with validation
|
||||
const appConfigSchema = z.object({
|
||||
redis: z.object({
|
||||
enabled: z.boolean().optional(),
|
||||
host: z.string(),
|
||||
port: z.number(),
|
||||
password: z.string().optional(),
|
||||
username: z.string().optional(),
|
||||
db: z.number().optional(),
|
||||
}),
|
||||
mongodb: z.object({
|
||||
enabled: z.boolean().optional(),
|
||||
uri: z.string(),
|
||||
database: z.string(),
|
||||
}),
|
||||
postgres: z.object({
|
||||
enabled: z.boolean().optional(),
|
||||
host: z.string(),
|
||||
port: z.number(),
|
||||
database: z.string(),
|
||||
user: z.string(),
|
||||
password: z.string(),
|
||||
}),
|
||||
questdb: z.object({
|
||||
enabled: z.boolean().optional(),
|
||||
host: z.string(),
|
||||
httpPort: z.number().optional(),
|
||||
pgPort: z.number().optional(),
|
||||
influxPort: z.number().optional(),
|
||||
database: z.string().optional(),
|
||||
}).optional(),
|
||||
proxy: z.object({
|
||||
cachePrefix: z.string().optional(),
|
||||
ttl: z.number().optional(),
|
||||
}).optional(),
|
||||
browser: z.object({
|
||||
headless: z.boolean().optional(),
|
||||
timeout: z.number().optional(),
|
||||
}).optional(),
|
||||
});
|
||||
|
||||
export type AppConfig = z.infer<typeof appConfigSchema>;
|
||||
|
||||
/**
|
||||
* Service type definitions for type-safe resolution
|
||||
*/
|
||||
export interface ServiceDefinitions {
|
||||
// Configuration
|
||||
config: AppConfig;
|
||||
logger: Logger;
|
||||
|
||||
// Core services
|
||||
cache: CacheProvider | null;
|
||||
proxyManager: ProxyManager | null;
|
||||
browser: Browser;
|
||||
queueManager: QueueManager | null;
|
||||
|
||||
// Database clients
|
||||
mongoClient: MongoDBClient | null;
|
||||
postgresClient: PostgreSQLClient | null;
|
||||
questdbClient: QuestDBClient | null;
|
||||
|
||||
// Aggregate service container
|
||||
serviceContainer: IServiceContainer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create and configure the DI container
|
||||
* Create and configure the DI container with type safety
|
||||
*/
|
||||
export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||
const container = createContainer({
|
||||
export function createServiceContainer(rawConfig: unknown): AwilixContainer<ServiceDefinitions> {
|
||||
// Validate configuration
|
||||
const config = appConfigSchema.parse(rawConfig);
|
||||
|
||||
const container = createContainer<ServiceDefinitions>({
|
||||
injectionMode: InjectionMode.PROXY,
|
||||
});
|
||||
|
||||
|
|
@ -153,10 +183,22 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
|||
registrations.questdbClient = asValue(null);
|
||||
}
|
||||
|
||||
// Queue manager - placeholder
|
||||
registrations.queueManager = asFunction(() => {
|
||||
// TODO: Create queue manager when decoupled
|
||||
return null;
|
||||
// Queue manager - placeholder until decoupled from singleton
|
||||
registrations.queueManager = asFunction(({ redisConfig, cache, logger }) => {
|
||||
// Import dynamically to avoid circular dependency
|
||||
const { QueueManager } = require('@stock-bot/queue');
|
||||
|
||||
// Check if already initialized (singleton pattern)
|
||||
if (QueueManager.isInitialized()) {
|
||||
return QueueManager.getInstance();
|
||||
}
|
||||
|
||||
// Initialize if not already done
|
||||
return QueueManager.initialize({
|
||||
redis: { host: redisConfig.host, port: redisConfig.port, db: redisConfig.db },
|
||||
enableScheduledJobs: true,
|
||||
delayWorkerStart: true // We'll start workers manually
|
||||
});
|
||||
}).singleton();
|
||||
|
||||
// Browser automation
|
||||
|
|
@ -247,19 +289,6 @@ export async function initializeServices(container: AwilixContainer): Promise<vo
|
|||
}
|
||||
}
|
||||
|
||||
// Type definitions for container resolution
|
||||
export interface ServiceCradle {
|
||||
config: AppConfig;
|
||||
logger: any;
|
||||
cache: CacheProvider;
|
||||
proxyManager: ProxyManager;
|
||||
browser: any;
|
||||
mongoClient: any;
|
||||
postgresClient: any;
|
||||
questdbClient: any;
|
||||
queueManager: any;
|
||||
serviceContainer: IServiceContainer;
|
||||
}
|
||||
|
||||
// Export typed container
|
||||
export type ServiceContainer = AwilixContainer<ServiceCradle>;
|
||||
export type ServiceContainer = AwilixContainer<ServiceDefinitions>;
|
||||
export type ServiceCradle = ServiceDefinitions;
|
||||
Loading…
Add table
Add a link
Reference in a new issue