dependency hell fixes
This commit is contained in:
parent
50e5b5cbed
commit
24768446f5
20 changed files with 219 additions and 197 deletions
|
|
@ -9,7 +9,8 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stock-bot/config": "workspace:*",
|
"@stock-bot/config": "workspace:*",
|
||||||
"@stock-bot/logger": "workspace:*"
|
"@stock-bot/logger": "workspace:*",
|
||||||
|
"@stock-bot/handlers": "workspace:*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/pg": "^8.10.7"
|
"@types/pg": "^8.10.7"
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
import type { Browser } from '@stock-bot/browser';
|
import type { Browser } from '@stock-bot/browser';
|
||||||
import type { CacheProvider } from '@stock-bot/cache';
|
import type { CacheProvider } from '@stock-bot/cache';
|
||||||
import type { AppConfig as StockBotAppConfig } from '@stock-bot/config';
|
import type { AppConfig as StockBotAppConfig } from '@stock-bot/config';
|
||||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
import type { Logger } from '@stock-bot/logger';
|
import type { Logger } from '@stock-bot/logger';
|
||||||
import type { MongoDBClient } from '@stock-bot/mongodb';
|
import type { MongoDBClient } from '@stock-bot/mongodb';
|
||||||
import type { PostgreSQLClient } from '@stock-bot/postgres';
|
import type { PostgreSQLClient } from '@stock-bot/postgres';
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Browser } from '@stock-bot/browser';
|
import type { Browser } from '@stock-bot/browser';
|
||||||
import type { CacheProvider } from '@stock-bot/cache';
|
import type { CacheProvider } from '@stock-bot/cache';
|
||||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
import type { Logger } from '@stock-bot/logger';
|
import type { Logger } from '@stock-bot/logger';
|
||||||
import type { MongoDBClient } from '@stock-bot/mongodb';
|
import type { MongoDBClient } from '@stock-bot/mongodb';
|
||||||
import type { PostgreSQLClient } from '@stock-bot/postgres';
|
import type { PostgreSQLClient } from '@stock-bot/postgres';
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { getLogger, setLoggerConfig, shutdownLoggers, type Logger } from '@stock
|
||||||
import { Shutdown } from '@stock-bot/shutdown';
|
import { Shutdown } from '@stock-bot/shutdown';
|
||||||
import type { AppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
import type { AppConfig as StockBotAppConfig, UnifiedAppConfig } from '@stock-bot/config';
|
||||||
import { toUnifiedConfig } from '@stock-bot/config';
|
import { toUnifiedConfig } from '@stock-bot/config';
|
||||||
import type { IServiceContainer } from '@stock-bot/handlers';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
import type { ServiceContainer } from './awilix-container';
|
import type { ServiceContainer } from './awilix-container';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -332,7 +332,7 @@ export class ServiceApplication {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.logger.debug('Creating scheduled jobs from registered handlers...');
|
this.logger.debug('Creating scheduled jobs from registered handlers...');
|
||||||
const { handlerRegistry } = await import('@stock-bot/types');
|
const { handlerRegistry } = await import('@stock-bot/handlers');
|
||||||
const allHandlers = handlerRegistry.getAllHandlersWithSchedule();
|
const allHandlers = handlerRegistry.getAllHandlersWithSchedule();
|
||||||
|
|
||||||
let totalScheduledJobs = 0;
|
let totalScheduledJobs = 0;
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@stock-bot/config": "workspace:*",
|
"@stock-bot/config": "workspace:*",
|
||||||
"@stock-bot/logger": "workspace:*",
|
"@stock-bot/logger": "workspace:*",
|
||||||
"@stock-bot/types": "workspace:*",
|
"@stock-bot/types": "workspace:*"
|
||||||
"@stock-bot/di": "workspace:*"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^20.11.0",
|
"@types/node": "^20.11.0",
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,11 @@
|
||||||
import type { Collection } from 'mongodb';
|
import type { Collection } from 'mongodb';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import {
|
import type { HandlerConfigWithSchedule } from '@stock-bot/types';
|
||||||
createJobHandler,
|
|
||||||
handlerRegistry,
|
|
||||||
type HandlerConfigWithSchedule,
|
|
||||||
} from '@stock-bot/types';
|
|
||||||
import { fetch } from '@stock-bot/utils';
|
import { fetch } from '@stock-bot/utils';
|
||||||
import { createNamespacedCache } from '@stock-bot/cache';
|
import { createNamespacedCache } from '@stock-bot/cache';
|
||||||
import type { IServiceContainer } from '../types/service-container';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
|
import { handlerRegistry } from '../registry/handler-registry';
|
||||||
|
import { createJobHandler } from '../utils/create-job-handler';
|
||||||
import type { ExecutionContext, IHandler } from '../types/types';
|
import type { ExecutionContext, IHandler } from '../types/types';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@
|
||||||
export { BaseHandler, ScheduledHandler } from './base/BaseHandler';
|
export { BaseHandler, ScheduledHandler } from './base/BaseHandler';
|
||||||
export type { JobScheduleOptions } from './base/BaseHandler';
|
export type { JobScheduleOptions } from './base/BaseHandler';
|
||||||
|
|
||||||
// Handler registry (re-exported from types to avoid circular deps)
|
// Handler registry
|
||||||
export { handlerRegistry } from '@stock-bot/types';
|
export { handlerRegistry } from './registry/handler-registry';
|
||||||
|
|
||||||
|
// Utilities
|
||||||
|
export { createJobHandler } from './utils/create-job-handler';
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
export type {
|
export type {
|
||||||
|
|
@ -18,9 +21,8 @@ export type {
|
||||||
OperationMetadata,
|
OperationMetadata,
|
||||||
} from './types/types';
|
} from './types/types';
|
||||||
|
|
||||||
export type { IServiceContainer } from './types/service-container';
|
// Re-export IServiceContainer from types package
|
||||||
|
export type { IServiceContainer } from '@stock-bot/types';
|
||||||
export { createJobHandler } from './types/types';
|
|
||||||
|
|
||||||
// Decorators
|
// Decorators
|
||||||
export {
|
export {
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@ import { readdirSync, statSync } from 'fs';
|
||||||
import { join, relative } from 'path';
|
import { join, relative } from 'path';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
import { BaseHandler } from '../base/BaseHandler';
|
import { BaseHandler } from '../base/BaseHandler';
|
||||||
import type { IServiceContainer } from '../types/service-container';
|
import type { IServiceContainer } from '@stock-bot/types';
|
||||||
|
|
||||||
const logger = getLogger('handler-auto-register');
|
const logger = getLogger('handler-auto-register');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/**
|
/**
|
||||||
* Handler Registry - Lightweight registry for queue handlers
|
* Handler Registry - Runtime registry for queue handlers
|
||||||
* Moved here to avoid circular dependencies between handlers and queue
|
* Properly located in handlers package instead of types
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type {
|
import type {
|
||||||
|
|
@ -8,7 +8,7 @@ import type {
|
||||||
HandlerConfigWithSchedule,
|
HandlerConfigWithSchedule,
|
||||||
JobHandler,
|
JobHandler,
|
||||||
ScheduledJob,
|
ScheduledJob,
|
||||||
} from './handlers';
|
} from '@stock-bot/types';
|
||||||
import { getLogger } from '@stock-bot/logger';
|
import { getLogger } from '@stock-bot/logger';
|
||||||
|
|
||||||
class HandlerRegistry {
|
class HandlerRegistry {
|
||||||
|
|
@ -108,6 +108,28 @@ class HandlerRegistry {
|
||||||
return Array.from(this.handlers.keys());
|
return Array.from(this.handlers.keys());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get registry statistics
|
||||||
|
*/
|
||||||
|
getStats(): { handlers: number; operations: number; scheduledJobs: number } {
|
||||||
|
let operationCount = 0;
|
||||||
|
let scheduledJobCount = 0;
|
||||||
|
|
||||||
|
for (const [_, config] of this.handlers) {
|
||||||
|
operationCount += Object.keys(config).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const [_, jobs] of this.handlerSchedules) {
|
||||||
|
scheduledJobCount += jobs.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
handlers: this.handlers.size,
|
||||||
|
operations: operationCount,
|
||||||
|
scheduledJobs: scheduledJobCount,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clear all registrations (useful for testing)
|
* Clear all registrations (useful for testing)
|
||||||
*/
|
*/
|
||||||
|
|
@ -10,5 +10,3 @@ export type {
|
||||||
ScheduledJob,
|
ScheduledJob,
|
||||||
TypedJobHandler,
|
TypedJobHandler,
|
||||||
} from '@stock-bot/types';
|
} from '@stock-bot/types';
|
||||||
|
|
||||||
export { createJobHandler } from '@stock-bot/types';
|
|
||||||
|
|
|
||||||
16
libs/core/handlers/src/utils/create-job-handler.ts
Normal file
16
libs/core/handlers/src/utils/create-job-handler.ts
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
/**
|
||||||
|
* Utility for creating typed job handlers
|
||||||
|
*/
|
||||||
|
|
||||||
|
import type { JobHandler, TypedJobHandler } from '@stock-bot/types';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a typed job handler with validation
|
||||||
|
*/
|
||||||
|
export function createJobHandler<TPayload = unknown, TResult = unknown>(
|
||||||
|
handler: TypedJobHandler<TPayload, TResult>
|
||||||
|
): JobHandler<unknown, TResult> {
|
||||||
|
return async (payload: unknown): Promise<TResult> => {
|
||||||
|
return handler(payload as TPayload);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -71,13 +71,3 @@ export interface OperationMetadata {
|
||||||
validation?: (input: unknown) => boolean;
|
validation?: (input: unknown) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a typed job handler with validation
|
|
||||||
*/
|
|
||||||
export function createJobHandler<TPayload = unknown, TResult = unknown>(
|
|
||||||
handler: TypedJobHandler<TPayload, TResult>
|
|
||||||
): JobHandler<unknown, TResult> {
|
|
||||||
return async (payload: unknown): Promise<TResult> => {
|
|
||||||
return handler(payload as TPayload);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -60,7 +60,7 @@ export type {
|
||||||
ScheduledJob,
|
ScheduledJob,
|
||||||
TypedJobHandler,
|
TypedJobHandler,
|
||||||
} from './handlers';
|
} from './handlers';
|
||||||
export { createJobHandler } from './handlers';
|
|
||||||
|
|
||||||
// Export handler registry
|
|
||||||
export { handlerRegistry } from './handler-registry';
|
// Export service container types
|
||||||
|
export type { IServiceContainer } from './service-container';
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,6 @@
|
||||||
* Simple, comprehensive container with all services available
|
* Simple, comprehensive container with all services available
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ProxyManager } from '@stock-bot/proxy';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Universal service container with all common services
|
* Universal service container with all common services
|
||||||
* Designed to work across different service contexts (data-ingestion, processing, etc.)
|
* Designed to work across different service contexts (data-ingestion, processing, etc.)
|
||||||
|
|
@ -15,7 +13,7 @@ export interface IServiceContainer {
|
||||||
readonly cache?: any; // Cache provider (Redis/Dragonfly) - optional
|
readonly cache?: any; // Cache provider (Redis/Dragonfly) - optional
|
||||||
readonly globalCache?: any; // Global cache provider (shared across services) - optional
|
readonly globalCache?: any; // Global cache provider (shared across services) - optional
|
||||||
readonly queue?: any; // Queue manager (BullMQ) - optional
|
readonly queue?: any; // Queue manager (BullMQ) - optional
|
||||||
readonly proxy?: ProxyManager; // Proxy manager service - optional (depends on cache)
|
readonly proxy?: any; // Proxy manager service - optional (depends on cache)
|
||||||
readonly browser?: any; // Browser automation (Playwright)
|
readonly browser?: any; // Browser automation (Playwright)
|
||||||
|
|
||||||
// Database clients - all optional to support selective enabling
|
// Database clients - all optional to support selective enabling
|
||||||
|
|
@ -15,7 +15,8 @@
|
||||||
"rate-limiter-flexible": "^3.0.0",
|
"rate-limiter-flexible": "^3.0.0",
|
||||||
"@stock-bot/cache": "*",
|
"@stock-bot/cache": "*",
|
||||||
"@stock-bot/logger": "*",
|
"@stock-bot/logger": "*",
|
||||||
"@stock-bot/types": "*"
|
"@stock-bot/types": "*",
|
||||||
|
"@stock-bot/handlers": "*"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"typescript": "^5.3.0",
|
"typescript": "^5.3.0",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
export { Queue, type QueueWorkerConfig } from './queue';
|
export { Queue, type QueueWorkerConfig } from './queue';
|
||||||
export { QueueManager } from './queue-manager';
|
export { QueueManager } from './queue-manager';
|
||||||
export { SmartQueueManager } from './smart-queue-manager';
|
export { SmartQueueManager } from './smart-queue-manager';
|
||||||
export { createJobHandler } from './types';
|
|
||||||
export { ServiceCache, createServiceCache } from './service-cache';
|
export { ServiceCache, createServiceCache } from './service-cache';
|
||||||
export {
|
export {
|
||||||
SERVICE_REGISTRY,
|
SERVICE_REGISTRY,
|
||||||
|
|
@ -12,8 +11,8 @@ export {
|
||||||
parseQueueName
|
parseQueueName
|
||||||
} from './service-registry';
|
} from './service-registry';
|
||||||
|
|
||||||
// Re-export handler registry from types package
|
// Re-export handler registry and utilities from handlers package
|
||||||
export { handlerRegistry } from '@stock-bot/types';
|
export { handlerRegistry, createJobHandler } from '@stock-bot/handlers';
|
||||||
|
|
||||||
// Batch processing
|
// Batch processing
|
||||||
export { processBatchJob, processItems } from './batch-processor';
|
export { processBatchJob, processItems } from './batch-processor';
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Queue as BullQueue, QueueEvents, Worker, type Job } from 'bullmq';
|
import { Queue as BullQueue, QueueEvents, Worker, type Job } from 'bullmq';
|
||||||
import { handlerRegistry } from '@stock-bot/types';
|
import { handlerRegistry } from '@stock-bot/handlers';
|
||||||
import type { JobData, JobOptions, QueueStats, RedisConfig } from './types';
|
import type { JobData, JobOptions, QueueStats, RedisConfig } from './types';
|
||||||
import { getRedisConnection } from './utils';
|
import { getRedisConnection } from './utils';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { Queue as BullQueue, type Job } from 'bullmq';
|
import { Queue as BullQueue, type Job } from 'bullmq';
|
||||||
import { handlerRegistry } from '@stock-bot/types';
|
import { handlerRegistry } from '@stock-bot/handlers';
|
||||||
import { getLogger, type Logger } from '@stock-bot/logger';
|
import { getLogger, type Logger } from '@stock-bot/logger';
|
||||||
import { QueueManager } from './queue-manager';
|
import { QueueManager } from './queue-manager';
|
||||||
import { Queue } from './queue';
|
import { Queue } from './queue';
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,6 @@ export interface QueueConfig extends QueueManagerConfig {
|
||||||
enableMetrics?: boolean;
|
enableMetrics?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export { createJobHandler } from '@stock-bot/types';
|
|
||||||
|
|
||||||
export interface BatchJobData {
|
export interface BatchJobData {
|
||||||
payloadKey: string;
|
payloadKey: string;
|
||||||
|
|
|
||||||
|
|
@ -42,22 +42,21 @@ libs=(
|
||||||
"data/postgres" # PostgreSQL client - depends on core libs
|
"data/postgres" # PostgreSQL client - depends on core libs
|
||||||
"data/questdb" # QuestDB client - depends on core libs
|
"data/questdb" # QuestDB client - depends on core libs
|
||||||
|
|
||||||
|
# Core handlers - must be built before services that depend on it
|
||||||
|
"core/handlers" # Handlers - depends on core libs
|
||||||
|
|
||||||
# Service libraries
|
# Service libraries
|
||||||
"services/event-bus" # Event bus - depends on core libs
|
"services/event-bus" # Event bus - depends on core libs
|
||||||
"services/shutdown" # Shutdown - depends on core libs
|
"services/shutdown" # Shutdown - depends on core libs
|
||||||
"services/browser" # Browser - depends on core libs
|
"services/browser" # Browser - depends on core libs
|
||||||
"services/queue" # Queue - depends on core libs and cache
|
"services/queue" # Queue - depends on core libs, cache, and handlers
|
||||||
"services/proxy" # Proxy manager - depends on core libs and cache
|
"services/proxy" # Proxy manager - depends on core libs and cache
|
||||||
|
|
||||||
# Utils
|
# Utils
|
||||||
"utils" # Utilities - depends on many libs
|
"utils" # Utilities - depends on many libs
|
||||||
|
|
||||||
# DI - dependency injection library
|
# DI - dependency injection library
|
||||||
"core/di" # Dependency injection - depends on data and service libs
|
"core/di" # Dependency injection - depends on data, service libs, and handlers
|
||||||
"core/handlers" # Handlers - depends on core libs and utils
|
|
||||||
|
|
||||||
# Note: core/handlers is not included in lib build chain since no libs depend on it
|
|
||||||
# It's built separately when needed by applications
|
|
||||||
)
|
)
|
||||||
|
|
||||||
# Build each library in order
|
# Build each library in order
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue