diff --git a/libs/core/di/src/awilix-container.ts b/libs/core/di/src/awilix-container.ts index b5251ec..6ced388 100644 --- a/libs/core/di/src/awilix-container.ts +++ b/libs/core/di/src/awilix-container.ts @@ -7,6 +7,10 @@ import { createContainer, asFunction, asValue, InjectionMode, type AwilixContain import { createCache, type CacheProvider } from '@stock-bot/cache'; import { ProxyManager } from '@stock-bot/proxy'; import { getLogger } from '@stock-bot/logger'; +import { createMongoDBClient } from '@stock-bot/mongodb'; +import { createPostgreSQLClient } from '@stock-bot/postgres'; +import { createQuestDBClient } from '@stock-bot/questdb'; +import { Browser } from '@stock-bot/browser'; import type { IServiceContainer } from '@stock-bot/handlers'; // Configuration types @@ -37,6 +41,10 @@ export interface AppConfig { cachePrefix?: string; ttl?: number; }; + browser?: { + headless?: boolean; + timeout?: number; + }; } /** @@ -87,20 +95,45 @@ export function createServiceContainer(config: AppConfig): AwilixContainer { return null; }).singleton(), - // Database clients - placeholders for now - mongoClient: asFunction(() => { - // TODO: Create MongoDB client - return null; + // MongoDB client with injected logger + mongoClient: asFunction(({ mongoConfig, logger }) => { + // Parse MongoDB URI to extract host and port + const url = new URL(mongoConfig.uri); + return createMongoDBClient( + { + uri: mongoConfig.uri, + host: url.hostname, + port: parseInt(url.port || '27017'), + database: mongoConfig.database, + }, + logger + ); }).singleton(), - postgresClient: asFunction(() => { - // TODO: Create PostgreSQL client - return null; + postgresClient: asFunction(({ postgresConfig, logger }) => { + return createPostgreSQLClient( + { + host: postgresConfig.host, + port: postgresConfig.port, + database: postgresConfig.database, + username: postgresConfig.user, + password: postgresConfig.password, + }, + logger + ); }).singleton(), - questdbClient: asFunction(() => { - // TODO: Create QuestDB client - return null; + questdbClient: asFunction(({ questdbConfig, logger }) => { + return createQuestDBClient( + { + host: questdbConfig.host, + httpPort: 9000, + pgPort: questdbConfig.port || 8812, + influxPort: 9009, + database: 'questdb', + }, + logger + ); }).singleton(), // Queue manager - placeholder @@ -109,12 +142,18 @@ export function createServiceContainer(config: AppConfig): AwilixContainer { return null; }).singleton(), + // Browser automation + browser: asFunction(({ config, logger }) => { + return new Browser(logger, config.browser); + }).singleton(), + // Build the IServiceContainer for handlers serviceContainer: asFunction((cradle) => ({ logger: cradle.logger, cache: cradle.cache, proxy: cradle.proxyManager, http: cradle.httpClient, + browser: cradle.browser, mongodb: cradle.mongoClient, postgres: cradle.postgresClient, questdb: cradle.questdbClient, @@ -146,8 +185,31 @@ export async function initializeServices(container: AwilixContainer): Promise { - const client = createMongoDBClient(config, events); + const client = createMongoDBClient(config, logger, events); await client.connect(); return client; } \ No newline at end of file diff --git a/libs/data/postgres/src/client.ts b/libs/data/postgres/src/client.ts index 8441cf0..1320951 100644 --- a/libs/data/postgres/src/client.ts +++ b/libs/data/postgres/src/client.ts @@ -1,5 +1,4 @@ import { Pool, QueryResultRow } from 'pg'; -import { getLogger } from '@stock-bot/logger'; import { PostgreSQLHealthMonitor } from './health'; import { PostgreSQLQueryBuilder } from './query-builder'; import { PostgreSQLTransactionManager } from './transactions'; @@ -23,7 +22,7 @@ export class PostgreSQLClient { private pool: Pool | null = null; private readonly config: PostgreSQLClientConfig; private readonly options: PostgreSQLConnectionOptions; - private readonly logger: ReturnType; + private readonly logger: any; private readonly healthMonitor: PostgreSQLHealthMonitor; private readonly transactionManager: PostgreSQLTransactionManager; private isConnected = false; @@ -32,7 +31,7 @@ export class PostgreSQLClient { private dynamicPoolConfig?: DynamicPoolConfig; private poolMonitorInterval?: NodeJS.Timeout; - constructor(config: PostgreSQLClientConfig, options?: PostgreSQLConnectionOptions, events?: ConnectionEvents) { + constructor(config: PostgreSQLClientConfig, logger?: any, options?: PostgreSQLConnectionOptions, events?: ConnectionEvents) { this.config = config; this.options = { retryAttempts: 3, @@ -42,7 +41,7 @@ export class PostgreSQLClient { }; this.events = events; - this.logger = getLogger('postgres-client'); + this.logger = logger || console; this.healthMonitor = new PostgreSQLHealthMonitor(this); this.transactionManager = new PostgreSQLTransactionManager(this); diff --git a/libs/data/postgres/src/factory.ts b/libs/data/postgres/src/factory.ts index be3d3b8..268f47a 100644 --- a/libs/data/postgres/src/factory.ts +++ b/libs/data/postgres/src/factory.ts @@ -6,10 +6,11 @@ import type { PostgreSQLClientConfig, PostgreSQLConnectionOptions, ConnectionEve */ export function createPostgreSQLClient( config: PostgreSQLClientConfig, + logger?: any, options?: PostgreSQLConnectionOptions, events?: ConnectionEvents ): PostgreSQLClient { - return new PostgreSQLClient(config, options, events); + return new PostgreSQLClient(config, logger, options, events); } /** @@ -17,10 +18,11 @@ export function createPostgreSQLClient( */ export async function createAndConnectPostgreSQLClient( config: PostgreSQLClientConfig, + logger?: any, options?: PostgreSQLConnectionOptions, events?: ConnectionEvents ): Promise { - const client = createPostgreSQLClient(config, options, events); + const client = createPostgreSQLClient(config, logger, options, events); await client.connect(); return client; } diff --git a/libs/data/questdb/src/client.ts b/libs/data/questdb/src/client.ts index c279d3d..0fc5bc9 100644 --- a/libs/data/questdb/src/client.ts +++ b/libs/data/questdb/src/client.ts @@ -1,5 +1,4 @@ import { Pool } from 'pg'; -import { getLogger } from '@stock-bot/logger'; import { QuestDBHealthMonitor } from './health'; import { QuestDBInfluxWriter } from './influx-writer'; import { QuestDBQueryBuilder } from './query-builder'; @@ -21,14 +20,15 @@ export class QuestDBClient { private pgPool: Pool | null = null; private readonly config: QuestDBClientConfig; private readonly options: QuestDBConnectionOptions; - private readonly logger = getLogger('QuestDBClient'); + private readonly logger: any; private readonly healthMonitor: QuestDBHealthMonitor; private readonly influxWriter: QuestDBInfluxWriter; private readonly schemaManager: QuestDBSchemaManager; private isConnected = false; - constructor(config: QuestDBClientConfig, options?: QuestDBConnectionOptions) { + constructor(config: QuestDBClientConfig, logger?: any, options?: QuestDBConnectionOptions) { this.config = config; + this.logger = logger || console; this.options = { protocol: 'pg', retryAttempts: 3, diff --git a/libs/data/questdb/src/factory.ts b/libs/data/questdb/src/factory.ts index d349810..df56ebc 100644 --- a/libs/data/questdb/src/factory.ts +++ b/libs/data/questdb/src/factory.ts @@ -6,9 +6,10 @@ import type { QuestDBClientConfig, QuestDBConnectionOptions } from './types'; */ export function createQuestDBClient( config: QuestDBClientConfig, + logger?: any, options?: QuestDBConnectionOptions ): QuestDBClient { - return new QuestDBClient(config, options); + return new QuestDBClient(config, logger, options); } /** @@ -16,9 +17,10 @@ export function createQuestDBClient( */ export async function createAndConnectQuestDBClient( config: QuestDBClientConfig, + logger?: any, options?: QuestDBConnectionOptions ): Promise { - const client = createQuestDBClient(config, options); + const client = createQuestDBClient(config, logger, options); await client.connect(); return client; } \ No newline at end of file diff --git a/libs/services/browser/src/browser.ts b/libs/services/browser/src/browser.ts index bc7597c..926bd0f 100644 --- a/libs/services/browser/src/browser.ts +++ b/libs/services/browser/src/browser.ts @@ -1,20 +1,21 @@ import { BrowserContext, chromium, Page, Browser as PlaywrightBrowser } from 'playwright'; -import { getLogger } from '@stock-bot/logger'; import type { BrowserOptions, NetworkEvent, NetworkEventHandler } from './types'; -class BrowserSingleton { +export class Browser { private browser?: PlaywrightBrowser; private contexts: Map = new Map(); - private logger = getLogger('browser'); + private logger: any; private options: BrowserOptions; private initialized = false; - constructor() { + constructor(logger?: any, defaultOptions?: BrowserOptions) { + this.logger = logger || console; this.options = { headless: true, timeout: 30000, blockResources: false, enableNetworkLogging: false, + ...defaultOptions, }; } @@ -359,8 +360,5 @@ class BrowserSingleton { } } -// Export singleton instance -export const Browser = new BrowserSingleton(); - -// Also export the class for typing if needed -export { BrowserSingleton as BrowserClass }; +// Export default for backward compatibility +export default Browser; diff --git a/libs/services/browser/src/index.ts b/libs/services/browser/src/index.ts index 96cb4ab..e555b6a 100644 --- a/libs/services/browser/src/index.ts +++ b/libs/services/browser/src/index.ts @@ -1,3 +1,7 @@ export { Browser } from './browser'; -export { BrowserTabManager } from './tab-manager'; +// TODO: Update BrowserTabManager to work with non-singleton Browser +// export { BrowserTabManager } from './tab-manager'; export type { BrowserOptions, ScrapingResult } from './types'; + +// Default export for the class +export { default as BrowserClass } from './browser'; diff --git a/libs/services/browser/src/tab-manager.ts b/libs/services/browser/src/tab-manager.ts.bak similarity index 100% rename from libs/services/browser/src/tab-manager.ts rename to libs/services/browser/src/tab-manager.ts.bak