added disabled functioality
This commit is contained in:
parent
fabf42dc7f
commit
d8ae0cb3c5
16 changed files with 147 additions and 75 deletions
4
.env
4
.env
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
# Core Application Settings
|
# Core Application Settings
|
||||||
NODE_ENV=development
|
NODE_ENV=development
|
||||||
LOG_LEVEL=debug
|
LOG_LEVEL=trace
|
||||||
LOG_HIDE_OBJECT=false
|
LOG_HIDE_OBJECT=true
|
||||||
|
|
||||||
# Data Service Configuration
|
# Data Service Configuration
|
||||||
DATA_SERVICE_PORT=2001
|
DATA_SERVICE_PORT=2001
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { z } from 'zod';
|
||||||
import { EnvLoader } from './loaders/env.loader';
|
import { EnvLoader } from './loaders/env.loader';
|
||||||
import { FileLoader } from './loaders/file.loader';
|
import { FileLoader } from './loaders/file.loader';
|
||||||
import { ConfigError, ConfigValidationError } from './errors';
|
import { ConfigError, ConfigValidationError } from './errors';
|
||||||
import {
|
import type {
|
||||||
ConfigLoader,
|
ConfigLoader,
|
||||||
ConfigManagerOptions,
|
ConfigManagerOptions,
|
||||||
ConfigSchema,
|
ConfigSchema,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,8 @@
|
||||||
import { EnvLoader } from './loaders/env.loader';
|
import { EnvLoader } from './loaders/env.loader';
|
||||||
import { FileLoader } from './loaders/file.loader';
|
import { FileLoader } from './loaders/file.loader';
|
||||||
import { ConfigManager } from './config-manager';
|
import { ConfigManager } from './config-manager';
|
||||||
import { AppConfig, appConfigSchema } from './schemas';
|
import type { AppConfig } from './schemas';
|
||||||
|
import { appConfigSchema } from './schemas';
|
||||||
|
|
||||||
// Create singleton instance
|
// Create singleton instance
|
||||||
let configInstance: ConfigManager<AppConfig> | null = null;
|
let configInstance: ConfigManager<AppConfig> | null = null;
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { readFileSync } from 'fs';
|
import { readFileSync } from 'fs';
|
||||||
import { ConfigLoaderError } from '../errors';
|
import { ConfigLoaderError } from '../errors';
|
||||||
import { ConfigLoader } from '../types';
|
import type { ConfigLoader } from '../types';
|
||||||
|
|
||||||
export interface EnvLoaderOptions {
|
export interface EnvLoaderOptions {
|
||||||
convertCase?: boolean;
|
convertCase?: boolean;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { existsSync, readFileSync } from 'fs';
|
import { existsSync, readFileSync } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
import { ConfigLoaderError } from '../errors';
|
import { ConfigLoaderError } from '../errors';
|
||||||
import { ConfigLoader } from '../types';
|
import type { ConfigLoader } from '../types';
|
||||||
|
|
||||||
export class FileLoader implements ConfigLoader {
|
export class FileLoader implements ConfigLoader {
|
||||||
readonly priority = 50; // Medium priority
|
readonly priority = 50; // Medium priority
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { z } from 'zod';
|
||||||
|
|
||||||
// PostgreSQL configuration
|
// PostgreSQL configuration
|
||||||
export const postgresConfigSchema = z.object({
|
export const postgresConfigSchema = z.object({
|
||||||
|
enabled: z.boolean().default(true),
|
||||||
host: z.string().default('localhost'),
|
host: z.string().default('localhost'),
|
||||||
port: z.number().default(5432),
|
port: z.number().default(5432),
|
||||||
database: z.string(),
|
database: z.string(),
|
||||||
|
|
@ -15,6 +16,7 @@ export const postgresConfigSchema = z.object({
|
||||||
|
|
||||||
// QuestDB configuration
|
// QuestDB configuration
|
||||||
export const questdbConfigSchema = z.object({
|
export const questdbConfigSchema = z.object({
|
||||||
|
enabled: z.boolean().default(true),
|
||||||
host: z.string().default('localhost'),
|
host: z.string().default('localhost'),
|
||||||
ilpPort: z.number().default(9009),
|
ilpPort: z.number().default(9009),
|
||||||
httpPort: z.number().default(9000),
|
httpPort: z.number().default(9000),
|
||||||
|
|
@ -28,6 +30,7 @@ export const questdbConfigSchema = z.object({
|
||||||
|
|
||||||
// MongoDB configuration
|
// MongoDB configuration
|
||||||
export const mongodbConfigSchema = z.object({
|
export const mongodbConfigSchema = z.object({
|
||||||
|
enabled: z.boolean().default(true),
|
||||||
uri: z.string().url().optional(),
|
uri: z.string().url().optional(),
|
||||||
host: z.string().default('localhost'),
|
host: z.string().default('localhost'),
|
||||||
port: z.number().default(27017),
|
port: z.number().default(27017),
|
||||||
|
|
@ -41,6 +44,7 @@ export const mongodbConfigSchema = z.object({
|
||||||
|
|
||||||
// Dragonfly/Redis configuration
|
// Dragonfly/Redis configuration
|
||||||
export const dragonflyConfigSchema = z.object({
|
export const dragonflyConfigSchema = z.object({
|
||||||
|
enabled: z.boolean().default(true),
|
||||||
host: z.string().default('localhost'),
|
host: z.string().default('localhost'),
|
||||||
port: z.number().default(6379),
|
port: z.number().default(6379),
|
||||||
password: z.string().optional(),
|
password: z.string().optional(),
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,7 @@ import { asFunction, asValue, createContainer, InjectionMode, type AwilixContain
|
||||||
// Configuration types
|
// Configuration types
|
||||||
export interface AppConfig {
|
export interface AppConfig {
|
||||||
redis: {
|
redis: {
|
||||||
|
enabled?: boolean;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
password?: string;
|
password?: string;
|
||||||
|
|
@ -23,10 +24,12 @@ export interface AppConfig {
|
||||||
db?: number;
|
db?: number;
|
||||||
};
|
};
|
||||||
mongodb: {
|
mongodb: {
|
||||||
|
enabled?: boolean;
|
||||||
uri: string;
|
uri: string;
|
||||||
database: string;
|
database: string;
|
||||||
};
|
};
|
||||||
postgres: {
|
postgres: {
|
||||||
|
enabled?: boolean;
|
||||||
host: string;
|
host: string;
|
||||||
port: number;
|
port: number;
|
||||||
database: string;
|
database: string;
|
||||||
|
|
@ -34,6 +37,7 @@ export interface AppConfig {
|
||||||
password: string;
|
password: string;
|
||||||
};
|
};
|
||||||
questdb?: {
|
questdb?: {
|
||||||
|
enabled?: boolean;
|
||||||
host: string;
|
host: string;
|
||||||
httpPort?: number;
|
httpPort?: number;
|
||||||
pgPort?: number;
|
pgPort?: number;
|
||||||
|
|
@ -59,7 +63,7 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Register configuration values
|
// Register configuration values
|
||||||
container.register({
|
const registrations: any = {
|
||||||
// Configuration
|
// Configuration
|
||||||
config: asValue(config),
|
config: asValue(config),
|
||||||
redisConfig: asValue(config.redis),
|
redisConfig: asValue(config.redis),
|
||||||
|
|
@ -69,9 +73,11 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
|
|
||||||
// Core services with dependency injection
|
// Core services with dependency injection
|
||||||
logger: asFunction(() => getLogger('app')).singleton(),
|
logger: asFunction(() => getLogger('app')).singleton(),
|
||||||
|
};
|
||||||
// Cache with injected config and logger
|
|
||||||
cache: asFunction(({ redisConfig, logger }) =>
|
// Conditionally register cache/dragonfly
|
||||||
|
if (config.redis?.enabled !== false) {
|
||||||
|
registrations.cache = asFunction(({ redisConfig, logger }) =>
|
||||||
createCache({
|
createCache({
|
||||||
redisConfig,
|
redisConfig,
|
||||||
logger,
|
logger,
|
||||||
|
|
@ -79,23 +85,37 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
ttl: 3600,
|
ttl: 3600,
|
||||||
enableMetrics: true,
|
enableMetrics: true,
|
||||||
})
|
})
|
||||||
).singleton(),
|
).singleton();
|
||||||
|
} else {
|
||||||
// Proxy manager with injected cache and logger
|
registrations.cache = asValue(null);
|
||||||
proxyManager: asFunction(({ cache, config, logger }) => {
|
}
|
||||||
const manager = new ProxyManager(
|
|
||||||
cache,
|
// Proxy manager depends on cache
|
||||||
config.proxy || {},
|
registrations.proxyManager = asFunction(({ cache, config, logger }) => {
|
||||||
logger
|
if (!cache) {
|
||||||
);
|
logger.warn('Cache is disabled, ProxyManager will have limited functionality');
|
||||||
// Note: initialization happens in initializeServices function
|
return null;
|
||||||
return manager;
|
}
|
||||||
}).singleton(), // MongoDB client with injected dependencies
|
const manager = new ProxyManager(
|
||||||
mongoClient: asFunction(({ mongoConfig, logger }) => {
|
cache,
|
||||||
|
config.proxy || {},
|
||||||
|
logger
|
||||||
|
);
|
||||||
|
return manager;
|
||||||
|
}).singleton();
|
||||||
|
|
||||||
|
// Conditionally register MongoDB client
|
||||||
|
if (config.mongodb?.enabled !== false) {
|
||||||
|
registrations.mongoClient = asFunction(({ mongoConfig, logger }) => {
|
||||||
return new MongoDBClient(mongoConfig, logger);
|
return new MongoDBClient(mongoConfig, logger);
|
||||||
}).singleton(),
|
}).singleton();
|
||||||
|
} else {
|
||||||
postgresClient: asFunction(({ postgresConfig, logger }) => {
|
registrations.mongoClient = asValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conditionally register PostgreSQL client
|
||||||
|
if (config.postgres?.enabled !== false) {
|
||||||
|
registrations.postgresClient = asFunction(({ postgresConfig, logger }) => {
|
||||||
return createPostgreSQLClient(
|
return createPostgreSQLClient(
|
||||||
{
|
{
|
||||||
host: postgresConfig.host,
|
host: postgresConfig.host,
|
||||||
|
|
@ -106,9 +126,14 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
},
|
},
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
}).singleton(),
|
}).singleton();
|
||||||
|
} else {
|
||||||
questdbClient: asFunction(({ questdbConfig, logger }) => {
|
registrations.postgresClient = asValue(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conditionally register QuestDB client
|
||||||
|
if (config.questdb?.enabled !== false) {
|
||||||
|
registrations.questdbClient = asFunction(({ questdbConfig, logger }) => {
|
||||||
console.log('Creating QuestDB client with config:', questdbConfig);
|
console.log('Creating QuestDB client with config:', questdbConfig);
|
||||||
return createQuestDBClient(
|
return createQuestDBClient(
|
||||||
{
|
{
|
||||||
|
|
@ -123,32 +148,35 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
},
|
},
|
||||||
logger
|
logger
|
||||||
);
|
);
|
||||||
}).singleton(),
|
}).singleton();
|
||||||
|
} else {
|
||||||
// Queue manager - placeholder
|
registrations.questdbClient = asValue(null);
|
||||||
queueManager: asFunction(() => {
|
}
|
||||||
// TODO: Create queue manager when decoupled
|
|
||||||
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,
|
|
||||||
browser: cradle.browser,
|
|
||||||
mongodb: cradle.mongoClient,
|
|
||||||
postgres: cradle.postgresClient,
|
|
||||||
questdb: cradle.questdbClient,
|
|
||||||
queue: cradle.queueManager,
|
|
||||||
} as IServiceContainer)).singleton(),
|
|
||||||
});
|
|
||||||
|
|
||||||
|
// Queue manager - placeholder
|
||||||
|
registrations.queueManager = asFunction(() => {
|
||||||
|
// TODO: Create queue manager when decoupled
|
||||||
|
return null;
|
||||||
|
}).singleton();
|
||||||
|
|
||||||
|
// Browser automation
|
||||||
|
registrations.browser = asFunction(({ config, logger }) => {
|
||||||
|
return new Browser(logger, config.browser);
|
||||||
|
}).singleton();
|
||||||
|
|
||||||
|
// Build the IServiceContainer for handlers
|
||||||
|
registrations.serviceContainer = asFunction((cradle) => ({
|
||||||
|
logger: cradle.logger,
|
||||||
|
cache: cradle.cache,
|
||||||
|
proxy: cradle.proxyManager,
|
||||||
|
browser: cradle.browser,
|
||||||
|
mongodb: cradle.mongoClient,
|
||||||
|
postgres: cradle.postgresClient,
|
||||||
|
questdb: cradle.questdbClient,
|
||||||
|
queue: cradle.queueManager,
|
||||||
|
} as IServiceContainer)).singleton();
|
||||||
|
|
||||||
|
container.register(registrations);
|
||||||
return container;
|
return container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,40 +185,53 @@ export function createServiceContainer(config: AppConfig): AwilixContainer {
|
||||||
*/
|
*/
|
||||||
export async function initializeServices(container: AwilixContainer): Promise<void> {
|
export async function initializeServices(container: AwilixContainer): Promise<void> {
|
||||||
const logger = container.resolve('logger');
|
const logger = container.resolve('logger');
|
||||||
|
const config = container.resolve('config');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Wait for cache to be ready first
|
// Wait for cache to be ready first (if enabled)
|
||||||
const cache = container.resolve('cache');
|
const cache = container.resolve('cache');
|
||||||
if (cache && typeof cache.waitForReady === 'function') {
|
if (cache && typeof cache.waitForReady === 'function') {
|
||||||
await cache.waitForReady(10000);
|
await cache.waitForReady(10000);
|
||||||
logger.info('Cache is ready');
|
logger.info('Cache is ready');
|
||||||
|
} else if (config.redis?.enabled === false) {
|
||||||
|
logger.info('Cache is disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize proxy manager
|
// Initialize proxy manager (depends on cache)
|
||||||
const proxyManager = container.resolve('proxyManager');
|
const proxyManager = container.resolve('proxyManager');
|
||||||
if (proxyManager && typeof proxyManager.initialize === 'function') {
|
if (proxyManager && typeof proxyManager.initialize === 'function') {
|
||||||
await proxyManager.initialize();
|
await proxyManager.initialize();
|
||||||
logger.info('Proxy manager initialized');
|
logger.info('Proxy manager initialized');
|
||||||
|
} else {
|
||||||
|
logger.info('Proxy manager is disabled (requires cache)');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Connect database clients
|
// Connect MongoDB client (if enabled)
|
||||||
const mongoClient = container.resolve('mongoClient');
|
const mongoClient = container.resolve('mongoClient');
|
||||||
if (mongoClient && typeof mongoClient.connect === 'function') {
|
if (mongoClient && typeof mongoClient.connect === 'function') {
|
||||||
await mongoClient.connect();
|
await mongoClient.connect();
|
||||||
logger.info('MongoDB connected');
|
logger.info('MongoDB connected');
|
||||||
|
} else if (config.mongodb?.enabled === false) {
|
||||||
|
logger.info('MongoDB is disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Connect PostgreSQL client (if enabled)
|
||||||
const postgresClient = container.resolve('postgresClient');
|
const postgresClient = container.resolve('postgresClient');
|
||||||
if (postgresClient && typeof postgresClient.connect === 'function') {
|
if (postgresClient && typeof postgresClient.connect === 'function') {
|
||||||
await postgresClient.connect();
|
await postgresClient.connect();
|
||||||
logger.info('PostgreSQL connected');
|
logger.info('PostgreSQL connected');
|
||||||
|
} else if (config.postgres?.enabled === false) {
|
||||||
|
logger.info('PostgreSQL is disabled');
|
||||||
}
|
}
|
||||||
|
|
||||||
// const questdbClient = container.resolve('questdbClient');
|
// Connect QuestDB client (if enabled)
|
||||||
// if (questdbClient && typeof questdbClient.connect === 'function') {
|
const questdbClient = container.resolve('questdbClient');
|
||||||
// await questdbClient.connect();
|
if (questdbClient && typeof questdbClient.connect === 'function') {
|
||||||
// logger.info('QuestDB connected');
|
await questdbClient.connect();
|
||||||
// }
|
logger.info('QuestDB connected');
|
||||||
|
} else if (config.questdb?.enabled === false) {
|
||||||
|
logger.info('QuestDB is disabled');
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize browser if configured
|
// Initialize browser if configured
|
||||||
const browser = container.resolve('browser');
|
const browser = container.resolve('browser');
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,22 @@ export function QueueSchedule(
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disabled decorator - marks a handler as disabled for auto-registration
|
||||||
|
* Handlers marked with @Disabled() will be skipped during auto-registration
|
||||||
|
*/
|
||||||
|
export function Disabled() {
|
||||||
|
return function <T extends { new (...args: any[]): {} }>(
|
||||||
|
target: T,
|
||||||
|
_context?: any
|
||||||
|
) {
|
||||||
|
// Store disabled flag on the constructor
|
||||||
|
(target as any).__disabled = true;
|
||||||
|
|
||||||
|
return target;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Combined decorator for scheduled operations
|
* Combined decorator for scheduled operations
|
||||||
* Automatically creates both an operation and a schedule
|
* Automatically creates both an operation and a schedule
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,7 @@ export type { IServiceContainer } from './types/service-container';
|
||||||
export { createJobHandler } from './types/types';
|
export { createJobHandler } from './types/types';
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
export { Handler, Operation, QueueSchedule, ScheduledOperation } from './decorators/decorators';
|
export { Handler, Operation, QueueSchedule, ScheduledOperation, Disabled } from './decorators/decorators';
|
||||||
|
|
||||||
// Auto-registration utilities
|
// Auto-registration utilities
|
||||||
export { autoRegisterHandlers, createAutoHandlerRegistry } from './registry/auto-register';
|
export { autoRegisterHandlers, createAutoHandlerRegistry } from './registry/auto-register';
|
||||||
|
|
|
||||||
|
|
@ -108,6 +108,12 @@ export async function autoRegisterHandlers(
|
||||||
for (const HandlerClass of handlerClasses) {
|
for (const HandlerClass of handlerClasses) {
|
||||||
const handlerName = HandlerClass.name;
|
const handlerName = HandlerClass.name;
|
||||||
|
|
||||||
|
// Check if handler is disabled
|
||||||
|
if ((HandlerClass as any).__disabled) {
|
||||||
|
logger.info(`Skipping disabled handler: ${handlerName} from ${relativePath}`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (dryRun) {
|
if (dryRun) {
|
||||||
logger.info(`[DRY RUN] Would register handler: ${handlerName} from ${relativePath}`);
|
logger.info(`[DRY RUN] Would register handler: ${handlerName} from ${relativePath}`);
|
||||||
registered.push(handlerName);
|
registered.push(handlerName);
|
||||||
|
|
|
||||||
|
|
@ -12,15 +12,15 @@ import type { ProxyManager } from '@stock-bot/proxy';
|
||||||
export interface IServiceContainer {
|
export interface IServiceContainer {
|
||||||
// Core infrastructure
|
// Core infrastructure
|
||||||
readonly logger: any; // Logger instance
|
readonly logger: any; // Logger instance
|
||||||
readonly cache: any; // Cache provider (Redis/Dragonfly)
|
readonly cache?: any; // Cache provider (Redis/Dragonfly) - optional
|
||||||
readonly queue: any; // Queue manager (BullMQ)
|
readonly queue?: any; // Queue manager (BullMQ) - optional
|
||||||
readonly proxy: ProxyManager; // Proxy manager service
|
readonly proxy?: ProxyManager; // Proxy manager service - optional (depends on cache)
|
||||||
readonly browser?: any; // Browser automation (Playwright)
|
readonly browser?: any; // Browser automation (Playwright)
|
||||||
|
|
||||||
// Database clients
|
// Database clients - all optional to support selective enabling
|
||||||
readonly mongodb: any; // MongoDB client
|
readonly mongodb?: any; // MongoDB client
|
||||||
readonly postgres: any; // PostgreSQL client
|
readonly postgres?: any; // PostgreSQL client
|
||||||
readonly questdb: any; // QuestDB client (time-series)
|
readonly questdb?: any; // QuestDB client (time-series)
|
||||||
|
|
||||||
// Optional extensions for future use
|
// Optional extensions for future use
|
||||||
readonly custom?: Record<string, any>;
|
readonly custom?: Record<string, any>;
|
||||||
|
|
|
||||||
2
libs/data/cache/src/redis-cache.ts
vendored
2
libs/data/cache/src/redis-cache.ts
vendored
|
|
@ -1,6 +1,6 @@
|
||||||
import Redis from 'ioredis';
|
import Redis from 'ioredis';
|
||||||
import { RedisConnectionManager } from './connection-manager';
|
import { RedisConnectionManager } from './connection-manager';
|
||||||
import { CacheOptions, CacheProvider, CacheStats } from './types';
|
import type { CacheOptions, CacheProvider, CacheStats } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplified Redis-based cache provider using connection manager
|
* Simplified Redis-based cache provider using connection manager
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import type { Logger } from '@stock-bot/core/logger';
|
import type { Logger } from '@stock-bot/core/logger';
|
||||||
import { Collection, Db, MongoClient, OptionalUnlessRequiredId } from 'mongodb';
|
import { Collection, Db, MongoClient } from 'mongodb';
|
||||||
|
import type { OptionalUnlessRequiredId } from 'mongodb';
|
||||||
import type { ConnectionEvents, DocumentBase, DynamicPoolConfig, MongoDBClientConfig, PoolMetrics } from './types';
|
import type { ConnectionEvents, DocumentBase, DynamicPoolConfig, MongoDBClientConfig, PoolMetrics } from './types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { Pool, QueryResultRow } from 'pg';
|
import { Pool } from 'pg';
|
||||||
|
import type { QueryResultRow } from 'pg';
|
||||||
import { PostgreSQLHealthMonitor } from './health';
|
import { PostgreSQLHealthMonitor } from './health';
|
||||||
import { PostgreSQLQueryBuilder } from './query-builder';
|
import { PostgreSQLQueryBuilder } from './query-builder';
|
||||||
import { PostgreSQLTransactionManager } from './transactions';
|
import { PostgreSQLTransactionManager } from './transactions';
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { BrowserContext, chromium, Page, Browser as PlaywrightBrowser } from 'playwright';
|
import { chromium } from 'playwright';
|
||||||
|
import type { BrowserContext, Page, Browser as PlaywrightBrowser } from 'playwright';
|
||||||
import type { BrowserOptions, NetworkEvent, NetworkEventHandler } from './types';
|
import type { BrowserOptions, NetworkEvent, NetworkEventHandler } from './types';
|
||||||
|
|
||||||
export class Browser {
|
export class Browser {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import { CacheProvider, createCache } from '@stock-bot/cache';
|
import { createCache } from '@stock-bot/cache';
|
||||||
|
import type { CacheProvider } from '@stock-bot/cache';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import { Queue, type QueueWorkerConfig } from './queue';
|
import { Queue, type QueueWorkerConfig } from './queue';
|
||||||
import { QueueRateLimiter } from './rate-limiter';
|
import { QueueRateLimiter } from './rate-limiter';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue