refactored di into more composable parts
This commit is contained in:
parent
177fe30586
commit
26ebc77fe6
22 changed files with 908 additions and 281 deletions
27
libs/core/di/src/registrations/cache.registration.ts
Normal file
27
libs/core/di/src/registrations/cache.registration.ts
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { asClass, asFunction, asValue, type AwilixContainer } from 'awilix';
|
||||
import { createCache, type CacheProvider } from '@stock-bot/cache';
|
||||
import type { AppConfig } from '../config/schemas';
|
||||
import type { ServiceDefinitions } from '../container/types';
|
||||
|
||||
export function registerCacheServices(
|
||||
container: AwilixContainer<ServiceDefinitions>,
|
||||
config: AppConfig
|
||||
): void {
|
||||
if (config.redis.enabled) {
|
||||
container.register({
|
||||
cache: asFunction(() => {
|
||||
return createCache({
|
||||
redisConfig: {
|
||||
host: config.redis.host,
|
||||
port: config.redis.port,
|
||||
password: config.redis.password,
|
||||
},
|
||||
});
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
cache: asValue(null),
|
||||
});
|
||||
}
|
||||
}
|
||||
14
libs/core/di/src/registrations/core.registration.ts
Normal file
14
libs/core/di/src/registrations/core.registration.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
import { asValue, type AwilixContainer } from 'awilix';
|
||||
import { getLogger, type Logger } from '@stock-bot/logger';
|
||||
import type { AppConfig } from '../config/schemas';
|
||||
import type { ServiceDefinitions } from '../container/types';
|
||||
|
||||
export function registerCoreServices(
|
||||
container: AwilixContainer<ServiceDefinitions>,
|
||||
config: AppConfig
|
||||
): void {
|
||||
container.register({
|
||||
config: asValue(config),
|
||||
logger: asValue(getLogger('di-container')),
|
||||
});
|
||||
}
|
||||
79
libs/core/di/src/registrations/database.registration.ts
Normal file
79
libs/core/di/src/registrations/database.registration.ts
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
import { MongoDBClient } from '@stock-bot/mongodb';
|
||||
import { PostgreSQLClient } from '@stock-bot/postgres';
|
||||
import { QuestDBClient } from '@stock-bot/questdb';
|
||||
import { asFunction, asValue, type AwilixContainer } from 'awilix';
|
||||
import type { AppConfig } from '../config/schemas';
|
||||
import type { ServiceDefinitions } from '../container/types';
|
||||
|
||||
export function registerDatabaseServices(
|
||||
container: AwilixContainer<ServiceDefinitions>,
|
||||
config: AppConfig
|
||||
): void {
|
||||
// MongoDB
|
||||
if (config.mongodb.enabled) {
|
||||
container.register({
|
||||
mongoClient: asFunction(({ logger }) => {
|
||||
// Parse MongoDB URI to extract components
|
||||
const uriMatch = config.mongodb.uri.match(/mongodb:\/\/(?:([^:]+):([^@]+)@)?([^:\/]+):(\d+)\/([^?]+)(?:\?authSource=(.+))?/);
|
||||
const mongoConfig = {
|
||||
host: uriMatch?.[3] || 'localhost',
|
||||
port: parseInt(uriMatch?.[4] || '27017'),
|
||||
database: config.mongodb.database,
|
||||
username: uriMatch?.[1],
|
||||
password: uriMatch?.[2],
|
||||
authSource: uriMatch?.[6] || 'admin',
|
||||
uri: config.mongodb.uri,
|
||||
};
|
||||
return new MongoDBClient(mongoConfig, logger);
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
mongoClient: asValue(null),
|
||||
});
|
||||
}
|
||||
|
||||
// PostgreSQL
|
||||
if (config.postgres.enabled) {
|
||||
container.register({
|
||||
postgresClient: asFunction(({ logger }) => {
|
||||
return new PostgreSQLClient(
|
||||
{
|
||||
host: config.postgres.host,
|
||||
port: config.postgres.port,
|
||||
database: config.postgres.database,
|
||||
username: config.postgres.user,
|
||||
password: config.postgres.password,
|
||||
},
|
||||
logger
|
||||
);
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
postgresClient: asValue(null),
|
||||
});
|
||||
}
|
||||
|
||||
// QuestDB
|
||||
if (config.questdb?.enabled) {
|
||||
container.register({
|
||||
questdbClient: asFunction(({ logger }) => {
|
||||
return new QuestDBClient(
|
||||
{
|
||||
host: config.questdb!.host,
|
||||
httpPort: config.questdb!.httpPort,
|
||||
pgPort: config.questdb!.pgPort,
|
||||
influxPort: config.questdb!.influxPort,
|
||||
database: config.questdb!.database,
|
||||
},
|
||||
logger
|
||||
);
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
questdbClient: asValue(null),
|
||||
});
|
||||
}
|
||||
}
|
||||
4
libs/core/di/src/registrations/index.ts
Normal file
4
libs/core/di/src/registrations/index.ts
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
export { registerCoreServices } from './core.registration';
|
||||
export { registerCacheServices } from './cache.registration';
|
||||
export { registerDatabaseServices } from './database.registration';
|
||||
export { registerApplicationServices } from './service.registration';
|
||||
81
libs/core/di/src/registrations/service.registration.ts
Normal file
81
libs/core/di/src/registrations/service.registration.ts
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
import { asClass, asFunction, asValue, type AwilixContainer } from 'awilix';
|
||||
import { Browser } from '@stock-bot/browser';
|
||||
import { ProxyManager } from '@stock-bot/proxy';
|
||||
import { NamespacedCache } from '@stock-bot/cache';
|
||||
import type { QueueManager } from '@stock-bot/queue';
|
||||
import type { AppConfig } from '../config/schemas';
|
||||
import type { ServiceDefinitions } from '../container/types';
|
||||
|
||||
export function registerApplicationServices(
|
||||
container: AwilixContainer<ServiceDefinitions>,
|
||||
config: AppConfig
|
||||
): void {
|
||||
// Browser
|
||||
if (config.browser) {
|
||||
container.register({
|
||||
browser: asClass(Browser)
|
||||
.singleton()
|
||||
.inject(() => ({
|
||||
options: {
|
||||
headless: config.browser!.headless,
|
||||
timeout: config.browser!.timeout,
|
||||
},
|
||||
})),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
browser: asValue(null as any), // Required field
|
||||
});
|
||||
}
|
||||
|
||||
// Proxy Manager
|
||||
if (config.proxy && config.redis.enabled) {
|
||||
container.register({
|
||||
proxyManager: asFunction(({ cache, logger }) => {
|
||||
if (!cache) return null;
|
||||
const proxyCache = new NamespacedCache(cache, 'proxy');
|
||||
return new ProxyManager(proxyCache, logger);
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
proxyManager: asValue(null),
|
||||
});
|
||||
}
|
||||
|
||||
// Queue Manager
|
||||
if (config.queue?.enabled && config.redis.enabled) {
|
||||
container.register({
|
||||
queueManager: asFunction(({ logger }) => {
|
||||
const { QueueManager } = require('@stock-bot/queue');
|
||||
const queueConfig = {
|
||||
redis: {
|
||||
host: config.redis.host,
|
||||
port: config.redis.port,
|
||||
password: config.redis.password,
|
||||
db: config.redis.db,
|
||||
},
|
||||
defaultQueueOptions: {
|
||||
workers: 1,
|
||||
concurrency: 1,
|
||||
defaultJobOptions: {
|
||||
removeOnComplete: 100,
|
||||
removeOnFail: 50,
|
||||
attempts: 3,
|
||||
backoff: {
|
||||
type: 'exponential',
|
||||
delay: 1000,
|
||||
},
|
||||
},
|
||||
},
|
||||
enableScheduledJobs: true,
|
||||
};
|
||||
return new QueueManager(queueConfig, logger);
|
||||
}).singleton(),
|
||||
});
|
||||
} else {
|
||||
container.register({
|
||||
queueManager: asValue(null),
|
||||
});
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue