@flowlab/all
Version:
A cool library focusing on handling various flows
249 lines (212 loc) • 9.14 kB
text/typescript
// src/core/interfaces.ts
import { Logger } from 'pino';
import { Stream } from 'stream'; // Node.js stream type
import { Db as MongoDb, Collection as MongoCollection, Filter as MongoFilter } from 'mongodb';
import { Redis as IORedisClient } from 'ioredis';
import { PrismaClient } from '@prisma/client'; // Already there
import {
IFlowNode as IFlowNodeCore,
FlowExecutionContext,
FlowRegistry, // Assuming registry instance is imported elsewhere or passed
InputPayload,
OutputResult,
NodeConfigSchema
} from '@flowlab/core'; // <--- ASSUMED IMPORT PATH AND TYPES
// --- Configuration Types ---
export interface BaseSourceConfig {
type: string; // e.g., 'postgresql', 'mongodb', 'redis', 'mysql', 'file', 'api'
connection?: any; // Connection details (varies by type)
[key: string]: any; // Allow other options
}
export interface DatabaseSourceConfig extends BaseSourceConfig {
type: 'postgresql' | 'mongodb' | 'redis' | 'mysql';
connection: any; // Specific connection object (e.g., PrismaClient instance, connection string)
query?: string | object | MongoFilter<any>; // SQL query or MongoDB query object
batchSize?: number; // For batch extraction
}
export interface FileSourceConfig extends BaseSourceConfig {
type: 'file';
path: string;
format: 'json' | 'csv' | 'text'; // Add more formats as needed
encoding?: BufferEncoding;
}
export interface ApiSourceConfig extends BaseSourceConfig {
type: 'api';
url: string;
method?: 'GET' | 'POST'; // etc.
headers?: Record<string, string>;
body?: any;
}
export type ProcessingErrorStrategy = 'fail' | 'skip' | 'log' | 'dlq';
export type SourceConfig = DatabaseSourceConfig | FileSourceConfig | ApiSourceConfig | BaseSourceConfig; // Union type
export type IFlowLabNode = IFlowNodeCore;
export interface BaseTargetConfig {
type: string; // e.g., 'postgresql', 'mongodb', 'redis', 'mysql', 'file', 'api'
connection?: any;
[key: string]: any;
}
// MARK: - DatabaseTarget
export interface DatabaseTargetConfig extends BaseTargetConfig {
type: 'postgresql' | 'mongodb' | 'redis' | 'mysql';
connection: any; // e.g., PrismaClient
table?: string; // Or collection name
// Add options like 'upsert', 'update', etc.
}
// MARK: - FileTarget
export interface FileTargetConfig extends BaseTargetConfig {
type: 'file';
path: string;
format: 'json' | 'csv' | 'text';
encoding?: BufferEncoding;
mode?: 'append' | 'overwrite'; // Default to overwrite?
}
// MARK: - ApiTarget
export interface ApiTargetConfig extends BaseTargetConfig {
type: 'api';
url: string;
method?: 'POST' | 'PUT'; // etc.
headers?: Record<string, string>;
}
// MARK: - Pipeline
export interface PipelineConfig {
// ... id, source, steps, target ...
options?: {
batchSize?: number;
concurrency?: number; // Added for parallel processing later
errorHandling?: {
retries?: number; // Retries for Extract/Load operations
delay?: number; // ms
itemProcessingErrorStrategy?: ProcessingErrorStrategy; // Strategy for step errors
dlqTarget?: TargetConfig; // Configuration for the Dead Letter Queue loader
};
};
}
// MARK: - Connections
export interface PrismaConnection { client: PrismaClient, model: string };
export interface MongoConnection { db: MongoDb, collection: string };
export interface RedisConnection { client: IORedisClient };
// MARK: - DatabaseSource
export interface DatabaseSourceConfig extends BaseSourceConfig {
type: 'postgresql' | 'mongodb' | 'redis' | 'mysql';
// Use a union for more specific connection types based on 'type'
connection: PrismaConnection | MongoConnection | RedisConnection | any; // Keep 'any' for flexibility if needed
query?: string | MongoFilter<any> | object | undefined; // SQL query, MongoDB filter, or other object
batchSize?: number;
// Add specific options per DB type if necessary
redisScanMatch?: string; // For Redis extractor SCAN pattern
redisKeyType?: 'string' | 'hash' | 'list' // For Redis extractor
}
export interface DatabaseTargetConfig extends BaseTargetConfig {
type: 'postgresql' | 'mongodb' | 'redis' | 'mysql';
connection: PrismaConnection | MongoConnection | RedisConnection | any;
table?: string; // SQL table, Redis key prefix?
collection?: string; // Mongo collection
// Add specific options per DB type
mongoOperation?: 'insertMany' | 'bulkWrite'; // Default insertMany
bulkWriteOperations?: (item: any) => any; // Function to generate bulkWrite ops array
redisOperation?: 'set' | 'hmset' | 'lpush' | 'rpush' // etc.
redisKeyField?: string; // Field in item to use as Redis key
}
export type TargetConfig = DatabaseTargetConfig | FileTargetConfig | ApiTargetConfig | BaseTargetConfig; // Union type
// MARK: - FailedItemInfo
export interface FailedItemInfo {
pipelineId: string;
runId: string;
timestamp: string;
step: string; // Name/type of step that failed
error: {
message: string;
stack?: string;
name?: string;
};
originalItem: any; // The item that failed processing
}
// --- Component Interfaces ---
/** Represents an object or stream that can yield data items */
export type DataSource<T> = T[] | AsyncIterable<T>;
// MARK: - PipelineContext
export interface PipelineContext {
logger: Logger;
runId: string; // Unique identifier for this pipeline run
[key: string]: any; // Allow extensions
errorStrategy?: ProcessingErrorStrategy;
dlqLoader?: ILoader<FailedItemInfo>; // DLQ loader instance
}
/** Extracts data from a source */
export interface IExtractor<TOutput> {
extract(context: PipelineContext): Promise<DataSource<TOutput>>;
}
/** Cleans a single data item */
export interface ICleaner<TInput> {
clean(data: TInput, context: PipelineContext): Promise<TInput | null | undefined>; // Return null/undefined to filter out item
}
/** Transforms a single data item */
export interface ITransformer<TInput, TOutput> {
transform(data: TInput, context: PipelineContext): Promise<TOutput>;
}
/** Loads a batch of data items to a target */
export interface ILoader<TInput> {
loadBatch(batch: TInput[], context: PipelineContext): Promise<void>;
}
/** Processes a real-time stream */
// TInput is the raw message type from the stream, TOutput is the processed type
export interface IStreamProcessor<TInput, TOutput> {
initialize?(context: PipelineContext): Promise<void>; // Optional setup
process(message: TInput, context: PipelineContext): Promise<TOutput | null | undefined>; // Process single message
handleBatch?(batch: TOutput[], context: PipelineContext): Promise<void>; // Optional: Load/handle processed batch
onError?(error: Error, message: TInput | null, context: PipelineContext): Promise<void>; // Handle processing errors
shutdown?(context: PipelineContext): Promise<void>; // Optional cleanup
}
/** Configuration for stream processing */
export interface StreamProcessingConfig {
source: {
type: 'kafka' | 'redis-streams' | string; // Extensible
config: any; // e.g., KafkaJS client config, Redis connection options
topic?: string; // Kafka topic
group?: string; // Consumer group
streamKey?: string; // Redis stream key
// ... other stream-specific options
};
processor: IStreamProcessor<any, any>;
batchSize?: number; // Process messages in batches?
concurrency?: number;
errorHandling?: {
retries?: number;
delay?: number; // ms
deadLetterTopic?: string; // Topic/queue for failed messages
};
}
// --- FlowLab Node Registration ---
// Assume a core @flowlab/core package defines these
export interface IFlowLabNode {
readonly id: string; // Unique ID for this node instance
readonly type: string; // Type of node (e.g., 'extractor', 'loader', '@flowlab/data:pipeline')
execute(payload: any, context: any): Promise<any>; // Execution logic
// potentially methods for configuration schema, validation, etc.
}
export interface IFlowLabRegistry {
register(node: IFlowLabNode): void;
}
// --- Pipeline Configuration (for JSON/YAML) ---
export interface PipelineStepConfig {
type: 'clean' | 'transform' | 'map' | 'extract' | 'load' | 'custom';
// Options depend on type:
cleaner?: string | object; // reference to registered cleaner or inline config
transformer?: string | object; // reference to registered transformer or inline config
rules?: Record<string, string | object>; // For mapping transformer
customFunctionPath?: string; // Path to a JS file exporting a transform function
}
export interface PipelineConfig {
id: string; // Unique ID for this pipeline definition
source: SourceConfig;
steps: PipelineStepConfig[];
target: TargetConfig;
options?: {
batchSize?: number;
errorHandling?: {
retries?: number;
delay?: number; // ms
};
// concurrency options?
};
}