flowfn 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/index.d.mts +1305 -0
  2. package/dist/index.d.ts +1305 -0
  3. package/dist/index.js +3180 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/index.mjs +3088 -0
  6. package/dist/index.mjs.map +1 -0
  7. package/docs/API.md +801 -0
  8. package/docs/USAGE.md +619 -0
  9. package/package.json +75 -0
  10. package/src/adapters/base.ts +46 -0
  11. package/src/adapters/memory.ts +183 -0
  12. package/src/adapters/postgres/index.ts +383 -0
  13. package/src/adapters/postgres/postgres.test.ts +100 -0
  14. package/src/adapters/postgres/schema.ts +110 -0
  15. package/src/adapters/redis.test.ts +124 -0
  16. package/src/adapters/redis.ts +331 -0
  17. package/src/core/flow-fn.test.ts +70 -0
  18. package/src/core/flow-fn.ts +198 -0
  19. package/src/core/metrics.ts +198 -0
  20. package/src/core/scheduler.test.ts +80 -0
  21. package/src/core/scheduler.ts +154 -0
  22. package/src/index.ts +57 -0
  23. package/src/monitoring/health.ts +261 -0
  24. package/src/patterns/backoff.ts +30 -0
  25. package/src/patterns/batching.ts +248 -0
  26. package/src/patterns/circuit-breaker.test.ts +52 -0
  27. package/src/patterns/circuit-breaker.ts +52 -0
  28. package/src/patterns/priority.ts +146 -0
  29. package/src/patterns/rate-limit.ts +290 -0
  30. package/src/patterns/retry.test.ts +62 -0
  31. package/src/queue/batch.test.ts +35 -0
  32. package/src/queue/dependencies.test.ts +33 -0
  33. package/src/queue/dlq.ts +222 -0
  34. package/src/queue/job.ts +67 -0
  35. package/src/queue/queue.ts +243 -0
  36. package/src/queue/types.ts +153 -0
  37. package/src/queue/worker.ts +66 -0
  38. package/src/storage/event-log.ts +205 -0
  39. package/src/storage/job-storage.ts +206 -0
  40. package/src/storage/workflow-storage.ts +182 -0
  41. package/src/stream/stream.ts +194 -0
  42. package/src/stream/types.ts +81 -0
  43. package/src/utils/hashing.ts +29 -0
  44. package/src/utils/id-generator.ts +109 -0
  45. package/src/utils/serialization.ts +142 -0
  46. package/src/utils/time.ts +167 -0
  47. package/src/workflow/advanced.test.ts +43 -0
  48. package/src/workflow/events.test.ts +39 -0
  49. package/src/workflow/types.ts +132 -0
  50. package/src/workflow/workflow.test.ts +55 -0
  51. package/src/workflow/workflow.ts +422 -0
  52. package/tests/dlq.test.ts +205 -0
  53. package/tests/health.test.ts +228 -0
  54. package/tests/integration.test.ts +253 -0
  55. package/tests/stream.test.ts +233 -0
  56. package/tests/workflow.test.ts +286 -0
  57. package/tsconfig.json +17 -0
  58. package/tsup.config.ts +10 -0
  59. package/vitest.config.ts +15 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/adapters/memory.ts","../src/queue/job.ts","../src/queue/queue.ts","../src/patterns/backoff.ts","../src/stream/stream.ts","../src/workflow/workflow.ts","../src/storage/workflow-storage.ts","../src/storage/event-log.ts","../src/core/scheduler.ts","../src/core/metrics.ts","../src/monitoring/health.ts","../src/core/flow-fn.ts","../src/queue/worker.ts","../src/queue/dlq.ts","../src/adapters/redis.ts","../src/adapters/postgres/schema.ts","../src/adapters/postgres/index.ts","../src/patterns/circuit-breaker.ts","../src/patterns/rate-limit.ts","../src/patterns/batching.ts","../src/patterns/priority.ts","../src/utils/hashing.ts","../src/utils/id-generator.ts","../src/utils/time.ts","../src/utils/serialization.ts","../src/storage/job-storage.ts"],"sourcesContent":["export * from \"./core/flow-fn.js\";\nexport * from \"./core/scheduler.js\";\nexport * from \"./core/metrics.js\";\n\nexport * from \"./queue/types.js\";\nexport * from \"./queue/worker.js\";\nexport * from \"./queue/dlq.js\";\nexport * from \"./stream/types.js\";\nexport * from \"./workflow/types.js\";\n\nexport * from \"./adapters/base.js\";\nexport * from \"./adapters/memory.js\";\nexport * from \"./adapters/redis.js\";\nexport * from \"./adapters/postgres/index.js\";\n\nexport * from \"./patterns/backoff.js\";\nexport * from \"./patterns/circuit-breaker.js\";\nexport * from \"./patterns/rate-limit.js\";\nexport {\n batch,\n chunk,\n processBatches,\n BatchWriter,\n batchByKey,\n BatchAccumulator,\n type BatchOptions as BatchingOptions,\n} from \"./patterns/batching.js\";\nexport * from \"./patterns/priority.js\";\n\nexport * from \"./monitoring/health.js\";\n\nexport * from \"./utils/hashing.js\";\nexport * from \"./utils/id-generator.js\";\nexport {\n toMilliseconds,\n fromMilliseconds,\n formatDuration,\n sleep,\n sleepDuration,\n timeout,\n now,\n delayUntil,\n isPast,\n isFuture,\n addDuration,\n parseDuration,\n type Duration as TimeDuration,\n} from \"./utils/time.js\";\nexport * from \"./utils/serialization.js\";\n\nexport * from \"./storage/job-storage.js\";\nexport {\n MemoryWorkflowStorage,\n WorkflowStorage,\n type ListOptions as StorageListOptions,\n} from \"./storage/workflow-storage.js\";\nexport * from \"./storage/event-log.js\";\n","import { FlowAdapter } from \"./base.js\";\nimport { Job, QueueStats } from \"../queue/types.js\";\nimport {\n Message,\n MessageHandler,\n Subscription,\n StreamInfo,\n} from \"../stream/types.js\";\nimport { WorkflowExecution } from \"../workflow/types.js\";\nimport { EventEmitter } from \"eventemitter3\";\n\nexport class MemoryAdapter implements FlowAdapter {\n private queues: Map<string, Job[]> = new Map();\n private allJobs: Map<string, Job> = new Map();\n private streams: Map<string, Message[]> = new Map();\n private streamEmitters: Map<string, EventEmitter> = new Map();\n private workflowStates: Map<string, WorkflowExecution> = new Map();\n\n async enqueue(queueName: string, job: Job): Promise<string> {\n if (!this.queues.has(queueName)) {\n this.queues.set(queueName, []);\n }\n const queue = this.queues.get(queueName)!;\n queue.push(job);\n this.allJobs.set(job.id, job);\n return job.id;\n }\n\n async dequeue(queueName: string): Promise<Job | null> {\n const queue = this.queues.get(queueName);\n if (!queue || queue.length === 0) return null;\n return queue.shift() || null;\n }\n\n async ack(queue: string, jobId: string): Promise<void> {\n const job = this.allJobs.get(jobId);\n if (job) {\n job.state = \"completed\";\n job.finishedOn = Date.now();\n }\n }\n\n async nack(\n queueName: string,\n jobId: string,\n requeue: boolean = true\n ): Promise<void> {\n const job = this.allJobs.get(jobId);\n if (job && requeue) {\n job.state = \"waiting\";\n const queue = this.queues.get(queueName);\n if (queue) queue.push(job);\n }\n }\n\n async getJob(queueName: string, jobId: string): Promise<Job | null> {\n return this.allJobs.get(jobId) || null;\n }\n\n async getJobs(queue: string, status: string): Promise<Job[]> {\n return Array.from(this.allJobs.values()).filter(\n (job) => job.state === status\n );\n }\n\n async getAllJobs(queue: string): Promise<Job[]> {\n return Array.from(this.allJobs.values());\n }\n\n async cleanJobs(\n queue: string,\n grace: number,\n status: string\n ): Promise<number> {\n const now = Date.now();\n const jobsToClean: string[] = [];\n\n for (const [id, job] of this.allJobs.entries()) {\n if (job.state === status) {\n const timestamp = job.finishedOn || job.timestamp;\n if (now - timestamp > grace) {\n jobsToClean.push(id);\n }\n }\n }\n\n for (const id of jobsToClean) {\n this.allJobs.delete(id);\n }\n\n return jobsToClean.length;\n }\n\n async publish(streamName: string, message: Message): Promise<string> {\n if (!this.streams.has(streamName)) {\n this.streams.set(streamName, []);\n this.streamEmitters.set(streamName, new EventEmitter());\n }\n const stream = this.streams.get(streamName)!;\n stream.push(message);\n this.streamEmitters.get(streamName)!.emit(\"message\", message);\n return message.id;\n }\n\n async subscribe(\n streamName: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n if (!this.streamEmitters.has(streamName)) {\n this.streamEmitters.set(streamName, new EventEmitter());\n this.streams.set(streamName, []);\n }\n const emitter = this.streamEmitters.get(streamName)!;\n const wrapper = (msg: Message) => {\n handler(msg).catch((err) => console.error(\"Stream handler error\", err));\n };\n emitter.on(\"message\", wrapper);\n\n return {\n unsubscribe: async () => {\n emitter.off(\"message\", wrapper);\n },\n };\n }\n\n async consume(\n stream: string,\n group: string,\n consumer: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n return this.subscribe(stream, handler);\n }\n\n async createConsumerGroup(stream: string, group: string): Promise<void> {\n // No-op for memory\n }\n\n async saveWorkflowState(\n workflowId: string,\n state: WorkflowExecution\n ): Promise<void> {\n this.workflowStates.set(workflowId, state);\n }\n\n async loadWorkflowState(\n workflowId: string\n ): Promise<WorkflowExecution | null> {\n return this.workflowStates.get(workflowId) || null;\n }\n\n async getQueueStats(queueName: string): Promise<QueueStats> {\n const length = this.queues.get(queueName)?.length || 0;\n const allInQueue = Array.from(this.allJobs.values()).filter(\n (j) => j.state === \"completed\"\n ).length;\n return {\n waiting: length,\n active: 0,\n completed: allInQueue,\n failed: 0,\n delayed: 0,\n paused: 0,\n };\n }\n\n async getStreamInfo(streamName: string): Promise<StreamInfo> {\n const length = this.streams.get(streamName)?.length || 0;\n return {\n name: streamName,\n length,\n groups: 0,\n };\n }\n\n async cleanup(): Promise<void> {\n this.queues.clear();\n this.allJobs.clear();\n this.streams.clear();\n this.workflowStates.clear();\n this.streamEmitters.clear();\n }\n}\n","import { Job, JobOptions, JobStatus } from './types.js';\nimport { v4 as uuidv4 } from 'uuid';\n\nexport class JobImpl<T = any> implements Job<T> {\n id: string;\n name: string;\n data: T;\n opts: JobOptions;\n \n state: JobStatus = 'waiting';\n progress: number = 0;\n returnvalue?: any;\n \n timestamp: number;\n processedOn?: number;\n finishedOn?: number;\n delay: number = 0;\n \n attemptsMade: number = 0;\n failedReason?: string;\n stacktrace?: string[];\n\n constructor(name: string, data: T, opts?: JobOptions) {\n this.id = opts?.jobId || uuidv4();\n this.name = name;\n this.data = data;\n this.opts = opts || {};\n this.timestamp = Date.now();\n }\n \n async update(data: Partial<T>): Promise<void> {\n this.data = { ...this.data, ...data };\n }\n\n async log(message: string): Promise<void> {\n // console.log(`[Job ${this.id}] ${message}`);\n }\n\n async updateProgress(progress: number): Promise<void> {\n this.progress = progress;\n }\n\n async moveToCompleted(returnValue: any): Promise<void> {\n this.state = 'completed';\n this.returnvalue = returnValue;\n this.finishedOn = Date.now();\n }\n\n async moveToFailed(error: Error): Promise<void> {\n this.state = 'failed';\n this.failedReason = error.message;\n this.finishedOn = Date.now();\n }\n\n async retry(): Promise<void> {\n // logical retry\n }\n\n async discard(): Promise<void> {\n // discard\n }\n\n async waitUntilFinished(): Promise<any> {\n // Poll or wait for event\n return Promise.resolve();\n }\n}\n","import {\n Queue,\n Job,\n JobOptions,\n QueueOptions,\n JobHandler,\n BatchHandler,\n BatchOptions,\n QueueStats,\n JobStatus,\n} from \"./types.js\";\nimport { FlowAdapter } from \"../adapters/base.js\";\nimport { JobImpl } from \"./job.js\";\nimport EventEmitter from \"eventemitter3\";\nimport { calculateBackoff } from \"../patterns/backoff.js\";\n\nexport class QueueImpl<T = any> extends EventEmitter implements Queue<T> {\n name: string;\n private adapter: FlowAdapter;\n private options: QueueOptions;\n private isProcessing = false;\n private currentWorkers: Set<Promise<void>> = new Set();\n\n constructor(name: string, adapter: FlowAdapter, options: QueueOptions = {}) {\n super();\n this.name = name;\n this.adapter = adapter;\n this.options = options;\n }\n\n async add(name: string, data: T, opts?: JobOptions): Promise<Job<T>> {\n const job = new JobImpl<T>(name, data, {\n ...this.options.defaultJobOptions,\n ...opts,\n });\n await this.adapter.enqueue(this.name, job);\n this.emit(\"waiting\", job);\n return job;\n }\n\n async addBulk(\n jobs: Array<{ name: string; data: T; opts?: JobOptions }>\n ): Promise<Job<T>[]> {\n return Promise.all(jobs.map((j) => this.add(j.name, j.data, j.opts)));\n }\n\n process(arg1: any, arg2?: any, arg3?: any): void {\n let handler: JobHandler<T>;\n let concurrency = 1;\n\n if (typeof arg1 === \"number\") {\n concurrency = arg1;\n handler = arg2;\n } else if (typeof arg1 === \"string\") {\n // name based processing, ignore name for now in simple impl\n if (typeof arg2 === \"number\") {\n concurrency = arg2;\n handler = arg3;\n } else {\n handler = arg2;\n }\n } else {\n handler = arg1;\n }\n\n this.resume();\n for (let i = 0; i < concurrency; i++) {\n const worker = this.startProcessing(handler);\n this.currentWorkers.add(worker);\n worker.finally(() => this.currentWorkers.delete(worker));\n }\n }\n\n private async startProcessing(handler: JobHandler<T>) {\n while (this.isProcessing) {\n const jobData = await this.adapter.dequeue(this.name);\n if (jobData) {\n const job = Object.assign(\n new JobImpl(jobData.name, jobData.data, jobData.opts),\n jobData\n );\n\n // Check dependencies\n if (job.opts.waitFor && job.opts.waitFor.length > 0) {\n let allDone = true;\n for (const depId of job.opts.waitFor) {\n const depJob = await this.adapter.getJob(this.name, depId);\n if (!depJob || depJob.state !== \"completed\") {\n allDone = false;\n break;\n }\n }\n\n if (!allDone) {\n // Not ready, requeue\n await this.adapter.enqueue(this.name, job);\n await new Promise((resolve) => setTimeout(resolve, 100));\n continue;\n }\n }\n\n try {\n job.state = \"active\";\n job.processedOn = Date.now();\n this.emit(\"active\", job);\n\n const result = await handler(job);\n\n await job.moveToCompleted(result);\n await this.adapter.ack(this.name, job.id);\n this.emit(\"completed\", job, result);\n } catch (err: any) {\n job.attemptsMade++;\n job.stacktrace = job.stacktrace || [];\n job.stacktrace.push(err.stack);\n\n const maxAttempts = job.opts.attempts || 1;\n if (job.attemptsMade < maxAttempts) {\n job.state = \"delayed\";\n const backoff = job.opts.backoff\n ? calculateBackoff(job.attemptsMade, job.opts.backoff)\n : 0;\n job.opts.delay = backoff;\n await this.adapter.enqueue(this.name, job);\n this.emit(\"failed\", job, err); // failed but retrying\n } else {\n await job.moveToFailed(err);\n // In real impl, move to DLQ or just ack to remove from active\n await this.adapter.ack(this.name, job.id);\n this.emit(\"failed\", job, err);\n }\n }\n } else {\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n }\n }\n\n processBatch(\n arg1: string | any,\n arg2: number | BatchOptions | any,\n arg3?: BatchHandler<T>\n ): void {\n let handler: BatchHandler<T>;\n let batchSize = 10;\n let maxWait = 1000;\n\n if (typeof arg2 === \"function\") {\n handler = arg2;\n } else {\n handler = arg3!;\n if (typeof arg2 === \"number\") {\n batchSize = arg2;\n } else {\n batchSize = arg2.batchSize;\n maxWait = arg2.maxWait || 1000;\n }\n }\n\n this.resume();\n this.startBatchProcessing(handler, batchSize, maxWait);\n }\n\n private async startBatchProcessing(\n handler: BatchHandler<T>,\n batchSize: number,\n maxWait: number\n ) {\n while (this.isProcessing) {\n const batch: Job[] = [];\n const start = Date.now();\n\n while (batch.length < batchSize && Date.now() - start < maxWait) {\n const jobData = await this.adapter.dequeue(this.name);\n if (jobData) {\n const job = Object.assign(\n new JobImpl(jobData.name, jobData.data, jobData.opts),\n jobData\n );\n batch.push(job);\n } else {\n await new Promise((resolve) => setTimeout(resolve, 50));\n }\n }\n\n if (batch.length > 0) {\n try {\n for (const job of batch) {\n (job as any).state = \"active\";\n (job as any).processedOn = Date.now();\n }\n\n const results = await handler(batch);\n\n for (let i = 0; i < batch.length; i++) {\n await batch[i].moveToCompleted(results[i]);\n await this.adapter.ack(this.name, batch[i].id);\n }\n } catch (err) {\n for (const job of batch) {\n await job.moveToFailed(err as Error);\n await this.adapter.ack(this.name, job.id);\n }\n }\n }\n }\n }\n\n async pause(): Promise<void> {\n this.isProcessing = false;\n }\n\n async resume(): Promise<void> {\n this.isProcessing = true;\n }\n\n async drain(): Promise<void> {\n await Promise.all(this.currentWorkers);\n }\n\n async clean(grace: number, status: JobStatus): Promise<number> {\n return this.adapter.cleanJobs(this.name, grace, status);\n }\n\n async getJob(jobId: string): Promise<Job<T> | null> {\n const job = await this.adapter.getJob(this.name, jobId);\n return job as Job<T> | null;\n }\n\n async getJobs(status: JobStatus): Promise<Job<T>[]> {\n const jobs = await this.adapter.getJobs(this.name, status);\n return jobs as Job<T>[];\n }\n\n async getJobCounts(): Promise<QueueStats> {\n return this.adapter.getQueueStats(this.name);\n }\n\n async close(): Promise<void> {\n this.isProcessing = false;\n await this.drain();\n }\n}\n","import { BackoffOptions } from '../queue/types.js';\n\nexport function calculateBackoff(attemptsMade: number, options: BackoffOptions): number {\n const { type, delay, maxDelay } = options;\n\n let resultDelay: number;\n\n switch (type) {\n case 'fixed':\n resultDelay = delay;\n break;\n case 'exponential':\n resultDelay = delay * Math.pow(2, attemptsMade - 1);\n break;\n case 'custom':\n // Custom should probably be a function passed in opts, \n // but for serialization we might need a registry.\n // Default to fixed for now if not handled.\n resultDelay = delay;\n break;\n default:\n resultDelay = delay;\n }\n\n if (maxDelay && resultDelay > maxDelay) {\n return maxDelay;\n }\n\n return resultDelay;\n}\n","import {\n Stream,\n Message,\n PublishOptions,\n SubscribeOptions,\n MessageHandler,\n Subscription,\n ConsumerOptions,\n Consumer,\n StreamInfo,\n TrimStrategy,\n StreamOptions,\n} from \"./types.js\";\nimport { FlowAdapter } from \"../adapters/base.js\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport class StreamImpl<T = any> implements Stream<T> {\n name: string;\n private adapter: FlowAdapter;\n private options: StreamOptions;\n private messages: Map<string, Message<T>> = new Map();\n\n constructor(name: string, adapter: FlowAdapter, options: StreamOptions = {}) {\n this.name = name;\n this.adapter = adapter;\n this.options = options;\n }\n\n async publish(data: T, options?: PublishOptions): Promise<string> {\n const message: Message<T> = {\n id: uuidv4(),\n stream: this.name,\n data,\n headers: options?.headers,\n timestamp: Date.now(),\n partition: options?.partition,\n key: options?.key,\n ack: async () => {},\n nack: async () => {},\n };\n\n // Store message locally for retrieval\n this.messages.set(message.id, message);\n\n // Auto-trim if maxLength is set\n if (this.options.maxLength && this.messages.size > this.options.maxLength) {\n await this.trim({ maxLength: this.options.maxLength });\n }\n\n return this.adapter.publish(this.name, message);\n }\n\n async publishBatch(\n messages: Array<{ data: T; options?: PublishOptions }>\n ): Promise<string[]> {\n return Promise.all(messages.map((m) => this.publish(m.data, m.options)));\n }\n\n async subscribe(\n handler: MessageHandler<T>,\n options?: SubscribeOptions\n ): Promise<Subscription> {\n return this.adapter.subscribe(this.name, handler as any);\n }\n\n createConsumer(consumerId: string, options: ConsumerOptions): Consumer<T> {\n let subscription: Subscription | null = null;\n let paused = false;\n\n return {\n subscribe: async (handler: MessageHandler<T>) => {\n // If fromBeginning, replay existing messages first\n if (options.fromBeginning && this.messages.size > 0) {\n const sortedMessages = Array.from(this.messages.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n );\n\n for (const msg of sortedMessages) {\n if (!paused) {\n await handler(msg).catch(console.error);\n }\n }\n }\n\n subscription = await this.adapter.consume(\n this.name,\n options.groupId,\n consumerId,\n handler as any\n );\n },\n pause: async () => {\n paused = true;\n },\n resume: async () => {\n paused = false;\n },\n close: async () => {\n if (subscription) await subscription.unsubscribe();\n },\n };\n }\n\n async getInfo(): Promise<StreamInfo> {\n const info = await this.adapter.getStreamInfo(this.name);\n return {\n ...info,\n length: this.messages.size,\n };\n }\n\n async trim(strategy: TrimStrategy): Promise<number> {\n const now = Date.now();\n const messagesToDelete: string[] = [];\n\n if (strategy.maxLength) {\n // Sort by timestamp and keep only the newest maxLength messages\n const sortedMessages = Array.from(this.messages.entries()).sort(\n (a, b) => b[1].timestamp - a[1].timestamp\n );\n\n if (sortedMessages.length > strategy.maxLength) {\n const toRemove = sortedMessages.slice(strategy.maxLength);\n messagesToDelete.push(...toRemove.map(([id]) => id));\n }\n }\n\n if (strategy.maxAgeSeconds) {\n const maxAge = strategy.maxAgeSeconds * 1000;\n for (const [id, message] of this.messages.entries()) {\n if (now - message.timestamp > maxAge) {\n messagesToDelete.push(id);\n }\n }\n }\n\n // Remove duplicates\n const uniqueToDelete = [...new Set(messagesToDelete)];\n for (const id of uniqueToDelete) {\n this.messages.delete(id);\n }\n\n return uniqueToDelete.length;\n }\n\n async getMessages(\n start: string,\n end: string,\n count?: number\n ): Promise<Message<T>[]> {\n const allMessages = Array.from(this.messages.values()).sort(\n (a, b) => a.timestamp - b.timestamp\n );\n\n // Filter by ID range (lexicographic comparison)\n let filtered = allMessages.filter((m) => m.id >= start && m.id <= end);\n\n // Apply count limit if specified\n if (count !== undefined && count > 0) {\n filtered = filtered.slice(0, count);\n }\n\n return filtered;\n }\n\n /**\n * Replay messages from a specific timestamp\n */\n async replay(\n fromTimestamp: number,\n handler: MessageHandler<T>\n ): Promise<number> {\n const messages = Array.from(this.messages.values())\n .filter((m) => m.timestamp >= fromTimestamp)\n .sort((a, b) => a.timestamp - b.timestamp);\n\n for (const message of messages) {\n await handler(message);\n }\n\n return messages.length;\n }\n\n /**\n * Get message count\n */\n getMessageCount(): number {\n return this.messages.size;\n }\n\n async close(): Promise<void> {\n this.messages.clear();\n }\n}\n","import {\n Workflow,\n WorkflowBuilder,\n WorkflowContext,\n WorkflowExecution,\n StepHandler,\n ErrorHandler,\n CompensateHandler,\n BranchOptions,\n SagaDefinition,\n ApprovalOptions,\n EventOptions,\n Duration,\n WorkflowEvent,\n WorkflowMetrics,\n ListOptions,\n} from \"./types.js\";\nimport { v4 as uuidv4 } from \"uuid\";\nimport { FlowAdapter } from \"../adapters/base.js\";\nimport {\n MemoryWorkflowStorage,\n WorkflowStorage,\n} from \"../storage/workflow-storage.js\";\nimport { MemoryEventLog, EventLog } from \"../storage/event-log.js\";\n\ntype StepDefinition = {\n type:\n | \"step\"\n | \"parallel\"\n | \"branch\"\n | \"saga\"\n | \"delay\"\n | \"delayUntil\"\n | \"wait\";\n name?: string;\n handler?: Function;\n compensate?: Function;\n options?: any;\n steps?: StepDefinition[]; // for parallel/branch-then\n elseSteps?: StepDefinition[]; // for branch-else\n condition?: (\n ctx: WorkflowContext<any>\n ) => boolean | Promise<boolean> | number;\n};\n\nexport class WorkflowBuilderImpl<T = any> implements WorkflowBuilder<T> {\n public steps: StepDefinition[] = [];\n private name: string;\n private adapter: FlowAdapter;\n\n constructor(name: string, adapter: FlowAdapter) {\n this.name = name;\n this.adapter = adapter;\n }\n\n input<I>(): WorkflowBuilder<I> {\n return this as unknown as WorkflowBuilder<I>;\n }\n\n step<R>(name: string, handler: StepHandler<T, R>): WorkflowBuilder<T> {\n this.steps.push({ type: \"step\", name, handler });\n return this;\n }\n\n parallel(steps: StepHandler<T, any>[]): WorkflowBuilder<T> {\n this.steps.push({\n type: \"parallel\",\n steps: steps.map((h, i) => ({\n type: \"step\",\n name: `parallel-${i}`,\n handler: h,\n })),\n });\n return this;\n }\n\n branch(options: BranchOptions<T>): WorkflowBuilder<T> {\n const thenSteps = (options.then as unknown as WorkflowBuilderImpl<T>).steps;\n const elseSteps = options.else\n ? (options.else as unknown as WorkflowBuilderImpl<T>).steps\n : undefined;\n\n this.steps.push({\n type: \"branch\",\n condition: options.condition,\n steps: thenSteps,\n elseSteps: elseSteps,\n });\n return this;\n }\n\n saga(name: string, saga: SagaDefinition<T>): WorkflowBuilder<T> {\n this.steps.push({\n type: \"saga\",\n name,\n handler: saga.execute,\n compensate: saga.compensate,\n });\n return this;\n }\n\n delay(duration: Duration): WorkflowBuilder<T> {\n this.steps.push({ type: \"delay\", options: duration });\n return this;\n }\n\n delayUntil(\n condition: (ctx: WorkflowContext<T>) => number\n ): WorkflowBuilder<T> {\n this.steps.push({ type: \"delayUntil\", condition });\n return this;\n }\n\n waitForApproval(\n approver: string,\n options: ApprovalOptions<T>\n ): WorkflowBuilder<T> {\n this.steps.push({\n type: \"wait\",\n name: \"approval\",\n options: { approver, ...options },\n });\n return this;\n }\n\n waitForEvent(event: string, options?: EventOptions): WorkflowBuilder<T> {\n this.steps.push({\n type: \"wait\",\n name: \"event\",\n options: { event, ...options },\n });\n return this;\n }\n\n onError(step: string, handler: ErrorHandler<T>): WorkflowBuilder<T> {\n const s = this.steps.find((s) => s.name === step);\n if (s) {\n // Attach error handler\n }\n return this;\n }\n\n compensate(step: string, handler: CompensateHandler<T>): WorkflowBuilder<T> {\n const s = this.steps.find((s) => s.name === step);\n if (s) {\n s.compensate = handler;\n }\n return this;\n }\n\n build(): Workflow<T> {\n return new WorkflowImpl(this.name, this.steps, this.adapter);\n }\n}\n\nexport class WorkflowImpl<T = any> implements Workflow<T> {\n id: string;\n name: string;\n private steps: StepDefinition[];\n private adapter: FlowAdapter;\n private storage: WorkflowStorage;\n private eventLog: EventLog;\n private executionCount = 0;\n private successCount = 0;\n private totalDuration = 0;\n\n constructor(name: string, steps: StepDefinition[], adapter: FlowAdapter) {\n this.id = uuidv4();\n this.name = name;\n this.steps = steps;\n this.adapter = adapter;\n this.storage = new MemoryWorkflowStorage();\n this.eventLog = new MemoryEventLog();\n }\n\n async execute(input: T): Promise<WorkflowExecution> {\n const executionId = uuidv4();\n const execution: WorkflowExecution = {\n id: executionId,\n workflowId: this.id,\n status: \"running\",\n input,\n state: {},\n startedAt: Date.now(),\n createdAt: Date.now(),\n updatedAt: Date.now(),\n };\n\n // Save initial state\n await this.storage.save(this.id, execution);\n await this.logEvent(executionId, \"execution.started\", { input });\n\n this.runExecution(execution).catch(console.error);\n\n return execution;\n }\n\n private async runExecution(execution: WorkflowExecution) {\n const context: WorkflowContext<T> = {\n workflowId: this.id,\n executionId: execution.id,\n input: execution.input,\n state: execution.state || {},\n metadata: {},\n set: (k, v) => {\n context.state[k] = v;\n this.storage\n .updateState(execution.id, context.state)\n .catch(console.error);\n },\n get: (k) => context.state[k],\n sleep: (ms) => new Promise((r) => setTimeout(r, ms)),\n waitForEvent: async (event, timeout) => {\n // Simplified wait: sleep for now\n // In real system, this suspends workflow until external signal\n await new Promise((r) => setTimeout(r, timeout || 100));\n },\n };\n\n const executedSagas: StepDefinition[] = [];\n\n try {\n await this.executeSteps(this.steps, context, executedSagas);\n execution.status = \"completed\";\n execution.output = context.state;\n execution.completedAt = Date.now();\n\n await this.logEvent(execution.id, \"execution.completed\", {\n output: execution.output,\n });\n this.executionCount++;\n this.successCount++;\n this.totalDuration += execution.completedAt - execution.startedAt;\n } catch (error) {\n execution.status = \"failed\";\n execution.error = error;\n execution.completedAt = Date.now();\n\n await this.logEvent(execution.id, \"execution.failed\", {\n error: (error as Error).message,\n });\n await this.compensate(executedSagas, context);\n this.executionCount++;\n this.totalDuration += execution.completedAt - execution.startedAt;\n }\n\n // Update storage with final state\n await this.storage.save(this.id, execution);\n await this.adapter.saveWorkflowState(execution.id, execution);\n }\n\n private async logEvent(\n executionId: string,\n type: string,\n data: any\n ): Promise<void> {\n await this.eventLog.append({\n type,\n aggregateId: executionId,\n aggregateType: \"workflow_execution\",\n data,\n });\n }\n\n private async executeSteps(\n steps: StepDefinition[],\n context: WorkflowContext<T>,\n executedSagas: StepDefinition[]\n ) {\n for (const step of steps) {\n if (step.type === \"step\" && step.handler) {\n await this.logEvent(context.executionId, \"step.started\", {\n step: step.name,\n });\n await step.handler(context);\n await this.logEvent(context.executionId, \"step.completed\", {\n step: step.name,\n });\n } else if (step.type === \"saga\" && step.handler) {\n await this.logEvent(context.executionId, \"saga.started\", {\n step: step.name,\n });\n await step.handler(context);\n executedSagas.push(step);\n await this.logEvent(context.executionId, \"saga.completed\", {\n step: step.name,\n });\n } else if (step.type === \"parallel\" && step.steps) {\n await this.logEvent(context.executionId, \"parallel.started\", {\n count: step.steps.length,\n });\n await Promise.all(\n step.steps.map((s) =>\n s.handler ? s.handler(context) : Promise.resolve()\n )\n );\n await this.logEvent(context.executionId, \"parallel.completed\", {});\n } else if (step.type === \"branch\" && step.condition) {\n const conditionMet = await (step.condition as any)(context);\n if (conditionMet && step.steps) {\n await this.executeSteps(step.steps, context, executedSagas);\n } else if (!conditionMet && step.elseSteps) {\n await this.executeSteps(step.elseSteps, context, executedSagas);\n }\n } else if (step.type === \"delay\") {\n const ms = step.options?.ms || 0;\n await new Promise((r) => setTimeout(r, ms));\n } else if (step.type === \"delayUntil\" && step.condition) {\n const targetTime = await (step.condition as any)(context);\n if (typeof targetTime === \"number\") {\n const now = Date.now();\n const delay = Math.max(0, targetTime - now);\n if (delay > 0) {\n // For long delays, we should suspend execution.\n // Here we just sleep.\n await new Promise((r) => setTimeout(r, delay));\n }\n }\n } else if (step.type === \"wait\") {\n // waitForApproval / waitForEvent\n // Need a mechanism to suspend/resume\n // Currently implementing as simple sleep/mock\n if (step.options?.timeout) {\n await new Promise((r) => setTimeout(r, step.options.timeout));\n }\n }\n }\n }\n\n private async compensate(\n executedSagas: StepDefinition[],\n context: WorkflowContext<T>\n ) {\n for (let i = executedSagas.length - 1; i >= 0; i--) {\n const step = executedSagas[i];\n if (step.compensate) {\n try {\n await step.compensate(context);\n } catch (err) {\n console.error(`Compensation failed for step ${step.name}`, err);\n }\n }\n }\n }\n\n async getExecution(executionId: string): Promise<WorkflowExecution> {\n const execution = await this.storage.get(executionId);\n if (!execution) {\n // Fallback to adapter\n const adapterExecution =\n await this.adapter.loadWorkflowState(executionId);\n if (!adapterExecution) {\n throw new Error(`Execution ${executionId} not found`);\n }\n return adapterExecution;\n }\n return execution;\n }\n\n async listExecutions(options?: ListOptions): Promise<WorkflowExecution[]> {\n return this.storage.list(this.id, options);\n }\n\n async cancelExecution(executionId: string): Promise<void> {\n const execution = await this.storage.get(executionId);\n if (!execution) {\n throw new Error(`Execution ${executionId} not found`);\n }\n\n if (\n execution.status === \"completed\" ||\n execution.status === \"failed\" ||\n execution.status === \"cancelled\"\n ) {\n throw new Error(`Cannot cancel execution in ${execution.status} state`);\n }\n\n await this.storage.updateStatus(executionId, \"cancelled\");\n await this.logEvent(executionId, \"execution.cancelled\", {});\n }\n\n async retryExecution(executionId: string): Promise<WorkflowExecution> {\n const execution = await this.storage.get(executionId);\n if (!execution) {\n throw new Error(`Execution ${executionId} not found`);\n }\n\n if (execution.status !== \"failed\") {\n throw new Error(\n `Can only retry failed executions, current status: ${execution.status}`\n );\n }\n\n // Create new execution with same input\n return this.execute(execution.input);\n }\n\n async getExecutionHistory(executionId: string): Promise<WorkflowEvent[]> {\n const events = await this.eventLog.getAggregateEvents(executionId);\n return events.map((e) => ({\n timestamp: e.timestamp,\n type: e.type,\n step: e.data.step,\n data: e.data,\n }));\n }\n\n async getMetrics(): Promise<WorkflowMetrics> {\n const successRate =\n this.executionCount > 0\n ? (this.successCount / this.executionCount) * 100\n : 0;\n const avgDuration =\n this.executionCount > 0 ? this.totalDuration / this.executionCount : 0;\n\n return {\n totalExecutions: this.executionCount,\n successRate,\n avgDuration,\n };\n }\n}\n","/**\n * Workflow state storage abstraction\n */\n\nimport { WorkflowExecution, ExecutionStatus } from \"../workflow/types.js\";\n\nexport interface WorkflowStorage {\n /**\n * Save workflow execution state\n */\n save(workflowId: string, execution: WorkflowExecution): Promise<void>;\n\n /**\n * Get workflow execution by ID\n */\n get(executionId: string): Promise<WorkflowExecution | null>;\n\n /**\n * List executions for a workflow\n */\n list(workflowId: string, options?: ListOptions): Promise<WorkflowExecution[]>;\n\n /**\n * Update execution status\n */\n updateStatus(executionId: string, status: string): Promise<void>;\n\n /**\n * Update execution state\n */\n updateState(executionId: string, state: Record<string, any>): Promise<void>;\n\n /**\n * Delete an execution\n */\n delete(executionId: string): Promise<void>;\n\n /**\n * Clean old executions\n */\n clean(workflowId: string, grace: number): Promise<number>;\n}\n\nexport interface ListOptions {\n status?: string;\n limit?: number;\n offset?: number;\n sortBy?: \"createdAt\" | \"updatedAt\";\n sortOrder?: \"asc\" | \"desc\";\n}\n\n/**\n * In-memory workflow storage implementation\n */\nexport class MemoryWorkflowStorage implements WorkflowStorage {\n private executions: Map<string, WorkflowExecution> = new Map();\n private workflowIndex: Map<string, Set<string>> = new Map(); // workflowId -> executionIds\n\n async save(workflowId: string, execution: WorkflowExecution): Promise<void> {\n this.executions.set(execution.id, { ...execution });\n\n // Index by workflow ID\n if (!this.workflowIndex.has(workflowId)) {\n this.workflowIndex.set(workflowId, new Set());\n }\n this.workflowIndex.get(workflowId)!.add(execution.id);\n }\n\n async get(executionId: string): Promise<WorkflowExecution | null> {\n return this.executions.get(executionId) || null;\n }\n\n async list(\n workflowId: string,\n options: ListOptions = {}\n ): Promise<WorkflowExecution[]> {\n const executionIds = this.workflowIndex.get(workflowId) || new Set();\n let executions: WorkflowExecution[] = [];\n\n for (const id of executionIds) {\n const execution = this.executions.get(id);\n if (execution) {\n // Filter by status if specified\n if (!options.status || execution.status === options.status) {\n executions.push(execution);\n }\n }\n }\n\n // Sort\n const sortBy = options.sortBy || \"createdAt\";\n const sortOrder = options.sortOrder || \"desc\";\n\n executions.sort((a, b) => {\n const aVal = a[sortBy] || 0;\n const bVal = b[sortBy] || 0;\n return sortOrder === \"asc\" ? aVal - bVal : bVal - aVal;\n });\n\n // Pagination\n const offset = options.offset || 0;\n const limit = options.limit || executions.length;\n\n return executions.slice(offset, offset + limit);\n }\n\n async updateStatus(\n executionId: string,\n status: ExecutionStatus\n ): Promise<void> {\n const execution = this.executions.get(executionId);\n if (execution) {\n execution.status = status as ExecutionStatus;\n execution.updatedAt = Date.now();\n\n if (\n status === \"completed\" ||\n status === \"failed\" ||\n status === \"cancelled\"\n ) {\n execution.completedAt = Date.now();\n }\n }\n }\n\n async updateState(\n executionId: string,\n state: Record<string, any>\n ): Promise<void> {\n const execution = this.executions.get(executionId);\n if (execution) {\n execution.state = { ...execution.state, ...state };\n execution.updatedAt = Date.now();\n }\n }\n\n async delete(executionId: string): Promise<void> {\n const execution = this.executions.get(executionId);\n if (execution) {\n // Remove from workflow index\n const workflowId = execution.workflowId;\n const executionIds = this.workflowIndex.get(workflowId);\n if (executionIds) {\n executionIds.delete(executionId);\n if (executionIds.size === 0) {\n this.workflowIndex.delete(workflowId);\n }\n }\n\n this.executions.delete(executionId);\n }\n }\n\n async clean(workflowId: string, grace: number): Promise<number> {\n const now = Date.now();\n const executionIds = this.workflowIndex.get(workflowId) || new Set();\n const toDelete: string[] = [];\n\n for (const id of executionIds) {\n const execution = this.executions.get(id);\n if (execution && execution.completedAt) {\n if (now - execution.completedAt > grace) {\n toDelete.push(id);\n }\n }\n }\n\n for (const id of toDelete) {\n await this.delete(id);\n }\n\n return toDelete.length;\n }\n\n /**\n * Clear all executions\n */\n clear(): void {\n this.executions.clear();\n this.workflowIndex.clear();\n }\n}\n","/**\n * Event log for event sourcing pattern\n */\n\nexport interface Event {\n id: string;\n type: string;\n aggregateId: string;\n aggregateType: string;\n data: any;\n metadata?: Record<string, any>;\n timestamp: number;\n version: number;\n}\n\nexport interface EventFilter {\n aggregateId?: string;\n aggregateType?: string;\n types?: string[];\n fromVersion?: number;\n toVersion?: number;\n fromTimestamp?: number;\n toTimestamp?: number;\n limit?: number;\n offset?: number;\n}\n\nexport interface EventLog {\n /**\n * Append event to the log\n */\n append(event: Omit<Event, \"id\" | \"timestamp\" | \"version\">): Promise<Event>;\n\n /**\n * Get events by filter\n */\n getEvents(filter: EventFilter): Promise<Event[]>;\n\n /**\n * Get events for an aggregate\n */\n getAggregateEvents(\n aggregateId: string,\n fromVersion?: number\n ): Promise<Event[]>;\n\n /**\n * Get latest version for an aggregate\n */\n getLatestVersion(aggregateId: string): Promise<number>;\n\n /**\n * Subscribe to event stream\n */\n subscribe(\n handler: (event: Event) => void | Promise<void>,\n filter?: EventFilter\n ): () => void;\n}\n\n/**\n * In-memory event log implementation\n */\nexport class MemoryEventLog implements EventLog {\n private events: Event[] = [];\n private aggregateVersions: Map<string, number> = new Map();\n private subscribers: Array<{\n handler: (event: Event) => void | Promise<void>;\n filter?: EventFilter;\n }> = [];\n\n async append(\n event: Omit<Event, \"id\" | \"timestamp\" | \"version\">\n ): Promise<Event> {\n const version = (this.aggregateVersions.get(event.aggregateId) || 0) + 1;\n this.aggregateVersions.set(event.aggregateId, version);\n\n const fullEvent: Event = {\n ...event,\n id: `evt_${Date.now()}_${Math.random().toString(36).substring(7)}`,\n timestamp: Date.now(),\n version,\n };\n\n this.events.push(fullEvent);\n\n // Notify subscribers\n for (const subscriber of this.subscribers) {\n if (this.matchesFilter(fullEvent, subscriber.filter)) {\n Promise.resolve(subscriber.handler(fullEvent)).catch((err) =>\n console.error(\"Event subscriber error:\", err)\n );\n }\n }\n\n return fullEvent;\n }\n\n async getEvents(filter: EventFilter): Promise<Event[]> {\n let results = [...this.events];\n\n // Apply filters\n if (filter.aggregateId) {\n results = results.filter((e) => e.aggregateId === filter.aggregateId);\n }\n\n if (filter.aggregateType) {\n results = results.filter((e) => e.aggregateType === filter.aggregateType);\n }\n\n if (filter.types && filter.types.length > 0) {\n results = results.filter((e) => filter.types!.includes(e.type));\n }\n\n if (filter.fromVersion !== undefined) {\n results = results.filter((e) => e.version >= filter.fromVersion!);\n }\n\n if (filter.toVersion !== undefined) {\n results = results.filter((e) => e.version <= filter.toVersion!);\n }\n\n if (filter.fromTimestamp !== undefined) {\n results = results.filter((e) => e.timestamp >= filter.fromTimestamp!);\n }\n\n if (filter.toTimestamp !== undefined) {\n results = results.filter((e) => e.timestamp <= filter.toTimestamp!);\n }\n\n // Sort by version\n results.sort((a, b) => a.version - b.version);\n\n // Pagination\n const offset = filter.offset || 0;\n const limit = filter.limit || results.length;\n\n return results.slice(offset, offset + limit);\n }\n\n async getAggregateEvents(\n aggregateId: string,\n fromVersion?: number\n ): Promise<Event[]> {\n return this.getEvents({\n aggregateId,\n fromVersion,\n });\n }\n\n async getLatestVersion(aggregateId: string): Promise<number> {\n return this.aggregateVersions.get(aggregateId) || 0;\n }\n\n subscribe(\n handler: (event: Event) => void | Promise<void>,\n filter?: EventFilter\n ): () => void {\n const subscriber = { handler, filter };\n this.subscribers.push(subscriber);\n\n // Return unsubscribe function\n return () => {\n const index = this.subscribers.indexOf(subscriber);\n if (index > -1) {\n this.subscribers.splice(index, 1);\n }\n };\n }\n\n private matchesFilter(event: Event, filter?: EventFilter): boolean {\n if (!filter) return true;\n\n if (filter.aggregateId && event.aggregateId !== filter.aggregateId)\n return false;\n if (filter.aggregateType && event.aggregateType !== filter.aggregateType)\n return false;\n if (filter.types && !filter.types.includes(event.type)) return false;\n if (filter.fromVersion !== undefined && event.version < filter.fromVersion)\n return false;\n if (filter.toVersion !== undefined && event.version > filter.toVersion)\n return false;\n if (\n filter.fromTimestamp !== undefined &&\n event.timestamp < filter.fromTimestamp\n )\n return false;\n if (\n filter.toTimestamp !== undefined &&\n event.timestamp > filter.toTimestamp\n )\n return false;\n\n return true;\n }\n\n /**\n * Clear all events\n */\n clear(): void {\n this.events = [];\n this.aggregateVersions.clear();\n this.subscribers = [];\n }\n}\n","import parser from 'cron-parser';\n\nexport interface ScheduleOptions {\n pattern?: string;\n timezone?: string;\n data?: any;\n startDate?: Date;\n endDate?: Date;\n limit?: number;\n every?: number; // ms\n}\n\nexport class Scheduler {\n private tasks: Map<string, {\n pattern: string | ScheduleOptions;\n handler: Function;\n nextRun: number;\n timer?: NodeJS.Timeout;\n count: number;\n paused: boolean;\n }> = new Map();\n\n async schedule(name: string, pattern: string | ScheduleOptions, handler: Function): Promise<void> {\n await this.cancel(name);\n \n const options: ScheduleOptions = typeof pattern === 'string' ? { pattern } : pattern;\n const now = Date.now();\n let nextRun = 0;\n\n if (options.pattern) {\n const interval = parser.parseExpression(options.pattern, {\n currentDate: options.startDate || new Date(),\n tz: options.timezone\n });\n nextRun = interval.next().getTime();\n } else if (options.every) {\n nextRun = (options.startDate?.getTime() || now) + options.every;\n }\n\n this.tasks.set(name, {\n pattern,\n handler,\n nextRun,\n count: 0,\n paused: false\n });\n\n this.plan(name);\n }\n \n async repeat(name: string, options: any, handler: Function): Promise<void> {\n return this.schedule(name, options, handler);\n }\n\n private plan(name: string) {\n const task = this.tasks.get(name);\n if (!task || task.paused) return;\n\n const now = Date.now();\n const delay = Math.max(0, task.nextRun - now);\n\n if (task.timer) clearTimeout(task.timer);\n\n task.timer = setTimeout(async () => {\n if (task.paused) return;\n \n try {\n const options: ScheduleOptions = typeof task.pattern === 'string' ? { pattern: task.pattern } : task.pattern;\n await task.handler(options.data);\n task.count++;\n\n // Check limits\n if (options.limit && task.count >= options.limit) {\n this.tasks.delete(name);\n return;\n }\n\n // Plan next run\n if (options.pattern) {\n const interval = parser.parseExpression(options.pattern, {\n currentDate: new Date(),\n tz: options.timezone\n });\n task.nextRun = interval.next().getTime();\n } else if (options.every) {\n task.nextRun = Date.now() + options.every;\n }\n\n if (options.endDate && task.nextRun > options.endDate.getTime()) {\n this.tasks.delete(name);\n return;\n }\n\n this.plan(name);\n } catch (err) {\n console.error(`Scheduler task \"${name}\" failed:`, err);\n // Still plan next run? Usually yes.\n this.plan(name);\n }\n }, delay);\n }\n\n async list(): Promise<any[]> {\n return Array.from(this.tasks.entries()).map(([name, task]) => ({\n name,\n nextRun: new Date(task.nextRun),\n count: task.count,\n paused: task.paused\n }));\n }\n\n async cancel(name: string): Promise<void> {\n const task = this.tasks.get(name);\n if (task) {\n if (task.timer) clearTimeout(task.timer);\n this.tasks.delete(name);\n }\n }\n\n async pause(name: string): Promise<void> {\n const task = this.tasks.get(name);\n if (task) {\n task.paused = true;\n if (task.timer) clearTimeout(task.timer);\n }\n }\n\n async resume(name: string): Promise<void> {\n const task = this.tasks.get(name);\n if (task && task.paused) {\n task.paused = false;\n // Recalculate next run if it passed while paused?\n // For cron, we just find the next occurrence from now.\n const options: ScheduleOptions = typeof task.pattern === 'string' ? { pattern: task.pattern } : task.pattern;\n if (options.pattern) {\n const interval = parser.parseExpression(options.pattern, {\n currentDate: new Date(),\n tz: options.timezone\n });\n task.nextRun = interval.next().getTime();\n } else if (options.every) {\n task.nextRun = Date.now() + options.every;\n }\n this.plan(name);\n }\n }\n\n async close(): Promise<void> {\n for (const task of this.tasks.values()) {\n if (task.timer) clearTimeout(task.timer);\n }\n this.tasks.clear();\n }\n}","import { FlowAdapter } from \"../adapters/base.js\";\n\nexport interface MetricDataPoint {\n timestamp: number;\n value: number;\n tags?: Record<string, string>;\n}\n\nexport interface TimeSeriesMetrics {\n dataPoints: MetricDataPoint[];\n\n // Aggregations\n min: number;\n max: number;\n avg: number;\n sum: number;\n count: number;\n p50?: number;\n p95?: number;\n p99?: number;\n}\n\nexport class MetricsManager {\n private adapter: FlowAdapter;\n private metrics: Map<string, MetricDataPoint[]> = new Map();\n private maxDataPoints = 1000;\n\n constructor(adapter: FlowAdapter) {\n this.adapter = adapter;\n }\n\n /**\n * Record a metric data point\n */\n record(name: string, value: number, tags?: Record<string, string>): void {\n const key = this.getMetricKey(name, tags);\n if (!this.metrics.has(key)) {\n this.metrics.set(key, []);\n }\n\n const dataPoints = this.metrics.get(key)!;\n dataPoints.push({\n timestamp: Date.now(),\n value,\n tags,\n });\n\n // Trim if exceeds max\n if (dataPoints.length > this.maxDataPoints) {\n this.metrics.set(key, dataPoints.slice(-this.maxDataPoints));\n }\n }\n\n /**\n * Get time series for a metric\n */\n getTimeSeries(\n name: string,\n options?: {\n tags?: Record<string, string>;\n since?: number;\n limit?: number;\n }\n ): TimeSeriesMetrics | null {\n const key = this.getMetricKey(name, options?.tags);\n let dataPoints = this.metrics.get(key) || [];\n\n if (options?.since) {\n dataPoints = dataPoints.filter((dp) => dp.timestamp >= options.since!);\n }\n\n if (options?.limit) {\n dataPoints = dataPoints.slice(-options.limit);\n }\n\n if (dataPoints.length === 0) {\n return null;\n }\n\n return this.calculateAggregations(dataPoints);\n }\n\n private calculateAggregations(\n dataPoints: MetricDataPoint[]\n ): TimeSeriesMetrics {\n const values = dataPoints.map((dp) => dp.value).sort((a, b) => a - b);\n const sum = values.reduce((a, b) => a + b, 0);\n const count = values.length;\n\n return {\n dataPoints,\n min: values[0],\n max: values[count - 1],\n avg: sum / count,\n sum,\n count,\n p50: this.percentile(values, 50),\n p95: this.percentile(values, 95),\n p99: this.percentile(values, 99),\n };\n }\n\n private percentile(sorted: number[], p: number): number {\n const index = Math.ceil((sorted.length * p) / 100) - 1;\n return sorted[Math.max(0, index)];\n }\n\n private getMetricKey(name: string, tags?: Record<string, string>): string {\n if (!tags) return name;\n const tagStr = Object.entries(tags)\n .sort(([a], [b]) => a.localeCompare(b))\n .map(([k, v]) => `${k}:${v}`)\n .join(\",\");\n return `${name}{${tagStr}}`;\n }\n\n async getQueueMetrics(name: string): Promise<any> {\n const stats = await this.adapter.getQueueStats(name);\n\n // Get throughput from recorded metrics\n const throughputMetrics = this.getTimeSeries(\"queue.throughput\", {\n tags: { queue: name },\n since: Date.now() - 60000, // Last minute\n });\n\n const durationMetrics = this.getTimeSeries(\"queue.job.duration\", {\n tags: { queue: name },\n });\n\n return {\n ...stats,\n throughput: throughputMetrics?.avg || 0,\n avgDuration: durationMetrics?.avg || 0,\n p95Duration: durationMetrics?.p95 || 0,\n };\n }\n\n async getStreamMetrics(name: string): Promise<any> {\n const info = await this.adapter.getStreamInfo(name);\n\n const throughputMetrics = this.getTimeSeries(\"stream.throughput\", {\n tags: { stream: name },\n since: Date.now() - 1000, // Last second\n });\n\n return {\n ...info,\n lag: 0,\n throughput: throughputMetrics?.avg || 0,\n avgLatency: 0,\n };\n }\n\n async getWorkflowMetrics(name: string): Promise<any> {\n const metricsData = this.getTimeSeries(\"workflow.executions\", {\n tags: { workflow: name },\n });\n\n return {\n totalExecutions: metricsData?.count || 0,\n running: 0,\n completed: 0,\n failed: 0,\n successRate: 0,\n avgDuration: metricsData?.avg || 0,\n };\n }\n\n async getSystemMetrics(): Promise<any> {\n const memUsage =\n typeof process !== \"undefined\" && process.memoryUsage\n ? process.memoryUsage().heapUsed\n : 0;\n\n return {\n queues: 0,\n streams: 0,\n workflows: 0,\n workers: 0,\n memoryUsage: memUsage,\n };\n }\n\n /**\n * Clear old metrics\n */\n cleanup(maxAge: number): void {\n const now = Date.now();\n for (const [key, dataPoints] of this.metrics.entries()) {\n const filtered = dataPoints.filter((dp) => now - dp.timestamp <= maxAge);\n if (filtered.length === 0) {\n this.metrics.delete(key);\n } else {\n this.metrics.set(key, filtered);\n }\n }\n }\n}\n","/**\n * Monitoring and health check system for FlowFn\n */\n\nexport interface HealthStatus {\n healthy: boolean;\n timestamp: number;\n checks: HealthCheck[];\n details?: Record<string, any>;\n}\n\nexport interface HealthCheck {\n name: string;\n status: \"pass\" | \"fail\" | \"warn\";\n message?: string;\n responseTime?: number;\n details?: Record<string, any>;\n}\n\nexport interface MonitoringMetrics {\n // Queue metrics\n queues?: {\n [queueName: string]: {\n waiting: number;\n active: number;\n completed: number;\n failed: number;\n delayed: number;\n throughput: number; // jobs/min\n avgDuration: number; // ms\n errorRate: number; // %\n };\n };\n\n // Stream metrics\n streams?: {\n [streamName: string]: {\n messageCount: number;\n publishRate: number; // msgs/sec\n consumerCount: number;\n lag: number;\n };\n };\n\n // Workflow metrics\n workflows?: {\n [workflowName: string]: {\n totalExecutions: number;\n running: number;\n completed: number;\n failed: number;\n successRate: number;\n avgDuration: number;\n };\n };\n\n // System metrics\n system?: {\n uptime: number;\n memoryUsage: number;\n cpuUsage?: number;\n };\n}\n\nexport interface HealthChecker {\n /**\n * Perform health check\n */\n check(): Promise<HealthStatus>;\n\n /**\n * Add custom health check\n */\n addCheck(name: string, checker: () => Promise<HealthCheck>): void;\n\n /**\n * Remove health check\n */\n removeCheck(name: string): void;\n}\n\n/**\n * Health checker implementation\n */\nexport class HealthCheckerImpl implements HealthChecker {\n private checks: Map<string, () => Promise<HealthCheck>> = new Map();\n private startTime = Date.now();\n\n constructor() {\n // Add default system checks\n this.addCheck(\"uptime\", async () => ({\n name: \"uptime\",\n status: \"pass\",\n responseTime: 0,\n details: {\n uptime: Date.now() - this.startTime,\n startTime: this.startTime,\n },\n }));\n\n this.addCheck(\"memory\", async () => {\n if (typeof process !== \"undefined\" && process.memoryUsage) {\n const mem = process.memoryUsage();\n const usedMB = mem.heapUsed / 1024 / 1024;\n const totalMB = mem.heapTotal / 1024 / 1024;\n const usagePercent = (usedMB / totalMB) * 100;\n\n return {\n name: \"memory\",\n status: usagePercent > 90 ? \"warn\" : \"pass\",\n message: usagePercent > 90 ? \"High memory usage\" : undefined,\n responseTime: 0,\n details: {\n heapUsedMB: Math.round(usedMB),\n heapTotalMB: Math.round(totalMB),\n usagePercent: Math.round(usagePercent),\n },\n };\n }\n\n return {\n name: \"memory\",\n status: \"pass\",\n responseTime: 0,\n };\n });\n }\n\n addCheck(name: string, checker: () => Promise<HealthCheck>): void {\n this.checks.set(name, checker);\n }\n\n removeCheck(name: string): void {\n this.checks.delete(name);\n }\n\n async check(): Promise<HealthStatus> {\n const results: HealthCheck[] = [];\n let allHealthy = true;\n\n for (const [name, checker] of this.checks.entries()) {\n try {\n const start = Date.now();\n const result = await checker();\n result.responseTime = Date.now() - start;\n results.push(result);\n\n if (result.status === \"fail\") {\n allHealthy = false;\n }\n } catch (error) {\n results.push({\n name,\n status: \"fail\",\n message: (error as Error).message,\n responseTime: 0,\n });\n allHealthy = false;\n }\n }\n\n return {\n healthy: allHealthy,\n timestamp: Date.now(),\n checks: results,\n };\n }\n}\n\n/**\n * Event tracking for monitoring\n */\nexport interface TrackedEvent {\n id: string;\n type: string;\n category: \"queue\" | \"stream\" | \"workflow\" | \"system\";\n severity: \"info\" | \"warn\" | \"error\";\n message: string;\n timestamp: number;\n metadata?: Record<string, any>;\n}\n\nexport interface EventTracker {\n /**\n * Track an event\n */\n track(event: Omit<TrackedEvent, \"id\" | \"timestamp\">): void;\n\n /**\n * Get events\n */\n getEvents(filter?: {\n category?: string;\n severity?: string;\n since?: number;\n limit?: number;\n }): TrackedEvent[];\n\n /**\n * Clear old events\n */\n cleanup(maxAge: number): number;\n}\n\nexport class MemoryEventTracker implements EventTracker {\n private events: TrackedEvent[] = [];\n private maxEvents = 10000;\n\n track(event: Omit<TrackedEvent, \"id\" | \"timestamp\">): void {\n const trackedEvent: TrackedEvent = {\n ...event,\n id: `evt_${Date.now()}_${Math.random().toString(36).substring(7)}`,\n timestamp: Date.now(),\n };\n\n this.events.push(trackedEvent);\n\n // Trim if exceeds max\n if (this.events.length > this.maxEvents) {\n this.events = this.events.slice(-this.maxEvents);\n }\n }\n\n getEvents(filter?: {\n category?: string;\n severity?: string;\n since?: number;\n limit?: number;\n }): TrackedEvent[] {\n let filtered = [...this.events];\n\n if (filter?.category) {\n filtered = filtered.filter((e) => e.category === filter.category);\n }\n\n if (filter?.severity) {\n filtered = filtered.filter((e) => e.severity === filter.severity);\n }\n\n if (filter?.since !== undefined) {\n filtered = filtered.filter((e) => e.timestamp >= filter.since!);\n }\n\n if (filter?.limit) {\n filtered = filtered.slice(-filter.limit);\n }\n\n return filtered;\n }\n\n cleanup(maxAge: number): number {\n const now = Date.now();\n const before = this.events.length;\n this.events = this.events.filter((e) => now - e.timestamp <= maxAge);\n return before - this.events.length;\n }\n\n clear(): void {\n this.events = [];\n }\n}\n","import { FlowAdapter } from \"../adapters/base.js\";\nimport { MemoryAdapter } from \"../adapters/memory.js\";\nimport { Queue, QueueOptions } from \"../queue/types.js\";\nimport { QueueImpl } from \"../queue/queue.js\";\nimport { Stream, StreamOptions } from \"../stream/types.js\";\nimport { StreamImpl } from \"../stream/stream.js\";\nimport { Workflow, WorkflowBuilder } from \"../workflow/types.js\";\nimport { WorkflowBuilderImpl } from \"../workflow/workflow.js\";\nimport { Scheduler } from \"./scheduler.js\";\nimport { MetricsManager } from \"./metrics.js\";\nimport {\n HealthCheckerImpl,\n HealthStatus,\n MemoryEventTracker,\n EventTracker,\n} from \"../monitoring/health.js\";\nimport EventEmitter from \"eventemitter3\";\n\nexport interface FlowFnConfig {\n adapter:\n | FlowAdapter\n | \"memory\"\n | \"redis\"\n | \"postgres\"\n | \"d1\"\n | \"sqs\"\n | \"kafka\";\n namespace?: string;\n defaultJobOptions?: any;\n defaultQueueOptions?: QueueOptions;\n defaultStreamOptions?: StreamOptions;\n telemetry?: {\n enabled: boolean;\n provider?: \"opentelemetry\" | \"custom\";\n };\n onError?: (error: Error, context: any) => void;\n}\n\nexport interface FlowFn {\n queue<T = any>(name: string, options?: QueueOptions): Queue<T>;\n listQueues(): Promise<string[]>;\n\n stream<T = any>(name: string, options?: StreamOptions): Stream<T>;\n listStreams(): Promise<string[]>;\n\n workflow<T = any>(name: string): WorkflowBuilder<T>;\n listWorkflows(): Promise<Workflow[]>;\n\n scheduler(): Scheduler;\n\n metrics: MetricsManager;\n healthCheck(): Promise<HealthStatus>;\n getEventTracker(): EventTracker;\n\n on(event: string, handler: (...args: any[]) => void): void;\n off(event: string, handler: (...args: any[]) => void): void;\n\n close(): Promise<void>;\n}\n\nexport class FlowFnImpl extends EventEmitter implements FlowFn {\n private adapter: FlowAdapter;\n private queues: Map<string, Queue> = new Map();\n private streams: Map<string, Stream> = new Map();\n private _metrics: MetricsManager;\n private _scheduler: Scheduler;\n private healthChecker: HealthCheckerImpl;\n private eventTracker: EventTracker;\n private startTime: number;\n\n constructor(config: FlowFnConfig) {\n super();\n this.startTime = Date.now();\n\n if (config.adapter === \"memory\") {\n this.adapter = new MemoryAdapter();\n } else if (typeof config.adapter === \"string\") {\n // Placeholder for other string-based adapter inits\n throw new Error(\n `Adapter ${config.adapter} not automatically initialized yet. Pass an instance.`\n );\n } else {\n this.adapter = config.adapter;\n }\n\n this._metrics = new MetricsManager(this.adapter);\n this._scheduler = new Scheduler();\n this.healthChecker = new HealthCheckerImpl();\n this.eventTracker = new MemoryEventTracker();\n\n // Add custom health checks\n this.setupHealthChecks();\n }\n\n private setupHealthChecks(): void {\n // Queue health check\n this.healthChecker.addCheck(\"queues\", async () => {\n const queueCount = this.queues.size;\n return {\n name: \"queues\",\n status: \"pass\",\n details: {\n count: queueCount,\n active: Array.from(this.queues.keys()),\n },\n };\n });\n\n // Adapter health check\n this.healthChecker.addCheck(\"adapter\", async () => {\n try {\n // Simple ping check\n await this.adapter.getQueueStats(\"health-check\");\n return {\n name: \"adapter\",\n status: \"pass\",\n message: \"Adapter responding\",\n };\n } catch (error) {\n return {\n name: \"adapter\",\n status: \"fail\",\n message: (error as Error).message,\n };\n }\n });\n }\n\n queue<T = any>(name: string, options?: QueueOptions): Queue<T> {\n if (!this.queues.has(name)) {\n this.queues.set(name, new QueueImpl<T>(name, this.adapter, options));\n }\n return this.queues.get(name) as Queue<T>;\n }\n\n async listQueues(): Promise<string[]> {\n return Array.from(this.queues.keys());\n }\n\n stream<T = any>(name: string, options?: StreamOptions): Stream<T> {\n if (!this.streams.has(name)) {\n this.streams.set(name, new StreamImpl<T>(name, this.adapter, options));\n }\n return this.streams.get(name) as Stream<T>;\n }\n\n async listStreams(): Promise<string[]> {\n return Array.from(this.streams.keys());\n }\n\n workflow<T = any>(name: string): WorkflowBuilder<T> {\n return new WorkflowBuilderImpl<T>(name, this.adapter);\n }\n\n async listWorkflows(): Promise<Workflow[]> {\n return [];\n }\n\n scheduler(): Scheduler {\n return this._scheduler;\n }\n\n get metrics(): MetricsManager {\n return this._metrics;\n }\n\n async healthCheck(): Promise<HealthStatus> {\n const health = await this.healthChecker.check();\n\n // Track health check event\n this.eventTracker.track({\n type: \"health.check\",\n category: \"system\",\n severity: health.healthy ? \"info\" : \"warn\",\n message: health.healthy ? \"System healthy\" : \"System unhealthy\",\n metadata: { checksCount: health.checks.length },\n });\n\n return health;\n }\n\n /**\n * Get event tracker\n */\n getEventTracker(): EventTracker {\n return this.eventTracker;\n }\n\n async close(): Promise<void> {\n await this.adapter.cleanup();\n for (const q of this.queues.values()) await q.close();\n for (const s of this.streams.values()) await s.close();\n }\n}\n\nexport function createFlow(config: FlowFnConfig): FlowFn {\n return new FlowFnImpl(config);\n}\n","import { FlowFn } from '../core/flow-fn.js';\nimport { Queue, Job } from './types.js';\nimport EventEmitter from 'eventemitter3';\n\nexport interface WorkerOptions {\n flow: FlowFn;\n queues: string[];\n concurrency?: number | Record<string, number>;\n settings?: {\n stalledInterval?: number;\n maxStalledCount?: number;\n };\n}\n\nexport class Worker extends EventEmitter {\n private flow: FlowFn;\n private queueNames: string[];\n private concurrency: number | Record<string, number>;\n private queues: Queue[] = [];\n\n constructor(options: WorkerOptions) {\n super();\n this.flow = options.flow;\n this.queueNames = options.queues;\n this.concurrency = options.concurrency || 1;\n }\n\n async run(): Promise<void> {\n for (const name of this.queueNames) {\n const queue = this.flow.queue(name);\n this.queues.push(queue);\n \n const qConcurrency = typeof this.concurrency === 'number' \n ? this.concurrency \n : (this.concurrency[name] || 1);\n\n queue.on('active', (job) => this.emit('active', job));\n queue.on('completed', (job, result) => this.emit('completed', job, result));\n queue.on('failed', (job, err) => this.emit('failed', job, err));\n \n // This is a bit simplified. In a real system, the worker would \n // have its own processing loop rather than calling queue.process.\n // But for this abstraction it works.\n // We need a way to pass the handler to the worker.\n }\n this.emit('ready');\n }\n\n // Helper to register handlers\n register(queueName: string, handler: (job: Job) => Promise<any>) {\n const queue = this.flow.queue(queueName);\n const qConcurrency = typeof this.concurrency === 'number' \n ? this.concurrency \n : (this.concurrency[queueName] || 1);\n queue.process(qConcurrency, handler);\n }\n\n async close(): Promise<void> {\n this.emit('closing');\n await Promise.all(this.queues.map(q => q.close()));\n }\n}\n\nexport function createWorker(options: WorkerOptions): Worker {\n return new Worker(options);\n}\n","/**\n * Dead-Letter Queue (DLQ) implementation for FlowFn\n */\n\nimport { Job, JobOptions } from \"../queue/types.js\";\n\nexport interface DLQOptions {\n /**\n * Queue name for dead-letter jobs\n */\n queueName?: string;\n\n /**\n * Maximum retries before moving to DLQ\n */\n maxRetries?: number;\n\n /**\n * Time to live for DLQ items (ms)\n */\n ttl?: number;\n\n /**\n * Handler called when job moves to DLQ\n */\n onDLQ?: (job: Job, reason: string) => void | Promise<void>;\n}\n\nexport interface DLQJob<T = any> extends Job<T> {\n /**\n * Original queue name\n */\n originalQueue: string;\n\n /**\n * Reason for DLQ\n */\n dlqReason: string;\n\n /**\n * Timestamp when moved to DLQ\n */\n dlqTimestamp: number;\n\n /**\n * All error messages from attempts\n */\n errors: string[];\n}\n\nexport interface DLQManager {\n /**\n * Move job to DLQ\n */\n moveToDLQ<T>(job: Job<T>, reason: string): Promise<DLQJob<T>>;\n\n /**\n * Get all DLQ jobs\n */\n getAll(): Promise<DLQJob[]>;\n\n /**\n * Get DLQ jobs by original queue\n */\n getByQueue(queueName: string): Promise<DLQJob[]>;\n\n /**\n * Retry a DLQ job\n */\n retry<T>(jobId: string): Promise<Job<T>>;\n\n /**\n * Retry all DLQ jobs from a queue\n */\n retryAll(queueName: string): Promise<number>;\n\n /**\n * Delete a DLQ job\n */\n delete(jobId: string): Promise<void>;\n\n /**\n * Clean expired DLQ jobs\n */\n clean(maxAge: number): Promise<number>;\n\n /**\n * Get DLQ stats\n */\n getStats(): Promise<{ total: number; byQueue: Record<string, number> }>;\n}\n\n/**\n * In-memory DLQ implementation\n */\nexport class MemoryDLQManager implements DLQManager {\n private dlqJobs: Map<string, DLQJob> = new Map();\n private options: DLQOptions;\n\n constructor(options: DLQOptions = {}) {\n this.options = {\n queueName: \"dlq\",\n maxRetries: 3,\n ttl: 7 * 24 * 60 * 60 * 1000, // 7 days\n ...options,\n };\n }\n\n async moveToDLQ<T>(job: Job<T>, reason: string): Promise<DLQJob<T>> {\n const dlqJob: DLQJob<T> = {\n ...job,\n originalQueue: job.name,\n dlqReason: reason,\n dlqTimestamp: Date.now(),\n errors: [...(job.stacktrace || []), job.failedReason || reason].filter(\n Boolean\n ),\n };\n\n this.dlqJobs.set(job.id, dlqJob);\n\n // Call handler if provided\n if (this.options.onDLQ) {\n await Promise.resolve(this.options.onDLQ(job, reason));\n }\n\n return dlqJob;\n }\n\n async getAll(): Promise<DLQJob[]> {\n return Array.from(this.dlqJobs.values());\n }\n\n async getByQueue(queueName: string): Promise<DLQJob[]> {\n return Array.from(this.dlqJobs.values()).filter(\n (job) => job.originalQueue === queueName\n );\n }\n\n async retry<T>(jobId: string): Promise<Job<T>> {\n const dlqJob = this.dlqJobs.get(jobId);\n if (!dlqJob) {\n throw new Error(`DLQ job ${jobId} not found`);\n }\n\n // Remove from DLQ\n this.dlqJobs.delete(jobId);\n\n // Reset job state for retry\n const retriedJob: Job<T> = {\n ...dlqJob,\n state: \"waiting\",\n attemptsMade: 0,\n failedReason: undefined,\n stacktrace: [],\n processedOn: undefined,\n finishedOn: undefined,\n } as Job<T>;\n\n return retriedJob;\n }\n\n async retryAll(queueName: string): Promise<number> {\n const jobs = await this.getByQueue(queueName);\n let count = 0;\n\n for (const job of jobs) {\n try {\n await this.retry(job.id);\n count++;\n } catch (err) {\n console.error(`Failed to retry job ${job.id}:`, err);\n }\n }\n\n return count;\n }\n\n async delete(jobId: string): Promise<void> {\n this.dlqJobs.delete(jobId);\n }\n\n async clean(maxAge: number): Promise<number> {\n const now = Date.now();\n const toDelete: string[] = [];\n\n for (const [id, job] of this.dlqJobs.entries()) {\n if (now - job.dlqTimestamp > maxAge) {\n toDelete.push(id);\n }\n }\n\n for (const id of toDelete) {\n this.dlqJobs.delete(id);\n }\n\n return toDelete.length;\n }\n\n async getStats(): Promise<{\n total: number;\n byQueue: Record<string, number>;\n }> {\n const byQueue: Record<string, number> = {};\n\n for (const job of this.dlqJobs.values()) {\n byQueue[job.originalQueue] = (byQueue[job.originalQueue] || 0) + 1;\n }\n\n return {\n total: this.dlqJobs.size,\n byQueue,\n };\n }\n\n /**\n * Clear all DLQ jobs (for testing)\n */\n clear(): void {\n this.dlqJobs.clear();\n }\n}\n","import { FlowAdapter } from \"./base.js\";\nimport { Job, QueueStats } from \"../queue/types.js\";\nimport {\n Message,\n MessageHandler,\n Subscription,\n StreamInfo,\n} from \"../stream/types.js\";\nimport { WorkflowExecution } from \"../workflow/types.js\";\nimport Redis, { RedisOptions } from \"ioredis\";\n\nexport interface RedisAdapterOptions {\n connection?: Redis | RedisOptions;\n prefix?: string;\n}\n\nexport class RedisAdapter implements FlowAdapter {\n private redis: Redis;\n private prefix: string;\n private subscriptions: Map<string, Redis[]> = new Map();\n\n constructor(options: RedisAdapterOptions = {}) {\n if (options.connection instanceof Redis) {\n this.redis = options.connection;\n } else {\n this.redis = new Redis((options.connection as RedisOptions) || {});\n }\n this.prefix = options.prefix || \"flowfn:\";\n }\n\n private key(type: string, name: string): string {\n return `${this.prefix}${type}:${name}`;\n }\n\n async enqueue(queueName: string, job: Job): Promise<string> {\n const queueKey = this.key(\"queue\", queueName);\n const jobKey = this.key(\"job\", job.id);\n\n // Store job data\n await this.redis.set(jobKey, JSON.stringify(job));\n\n if (job.opts.delay && job.opts.delay > 0) {\n const delayedKey = this.key(\"delayed\", queueName);\n await this.redis.zadd(delayedKey, Date.now() + job.opts.delay, job.id);\n } else {\n await this.redis.lpush(queueKey, job.id);\n }\n\n return job.id;\n }\n\n async dequeue(queueName: string): Promise<Job | null> {\n const queueKey = this.key(\"queue\", queueName);\n const delayedKey = this.key(\"delayed\", queueName);\n\n // Check delayed jobs first\n const now = Date.now();\n const delayed = await this.redis.zrangebyscore(\n delayedKey,\n 0,\n now,\n \"LIMIT\",\n 0,\n 1\n );\n if (delayed.length > 0) {\n const jobId = delayed[0];\n await this.redis.zrem(delayedKey, jobId);\n await this.redis.lpush(queueKey, jobId);\n }\n\n const jobId = await this.redis.rpop(queueKey);\n if (!jobId) return null;\n\n const jobData = await this.redis.get(this.key(\"job\", jobId));\n if (!jobData) return null;\n\n return JSON.parse(jobData);\n }\n\n async ack(queue: string, jobId: string): Promise<void> {\n await this.redis.del(this.key(\"job\", jobId));\n }\n\n async nack(\n queueName: string,\n jobId: string,\n requeue: boolean = true\n ): Promise<void> {\n if (requeue) {\n await this.redis.lpush(this.key(\"queue\", queueName), jobId);\n }\n }\n\n async publish(streamName: string, message: Message): Promise<string> {\n const streamKey = this.key(\"stream\", streamName);\n const id = await this.redis.xadd(\n streamKey,\n \"*\",\n \"data\",\n JSON.stringify(message.data),\n \"headers\",\n JSON.stringify(message.headers || {})\n );\n return id || \"\";\n }\n\n async subscribe(\n streamName: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n const streamKey = this.key(\"stream\", streamName);\n let active = true;\n\n // Simple polling for new messages from '$' (end)\n // Real impl might use blocking XREAD but that requires a dedicated connection or careful management\n // We'll use a polling loop with XREAD for simplicity on shared connection\n let lastId = \"$\";\n\n const poll = async () => {\n if (!active) return;\n try {\n const results = (await this.redis.xread(\n \"STREAMS\",\n streamKey,\n lastId,\n \"BLOCK\",\n 1000\n )) as any;\n if (results) {\n for (const [stream, messages] of results) {\n for (const [id, fields] of messages) {\n lastId = id;\n // fields is array [key1, val1, key2, val2...]\n const dataIdx = fields.indexOf(\"data\");\n const headersIdx = fields.indexOf(\"headers\");\n\n const data = dataIdx > -1 ? JSON.parse(fields[dataIdx + 1]) : {};\n const headers =\n headersIdx > -1 ? JSON.parse(fields[headersIdx + 1]) : {};\n\n const msg: Message = {\n id,\n stream: streamName,\n data,\n headers,\n timestamp: parseInt(id.split(\"-\")[0]),\n ack: async () => {},\n nack: async () => {},\n };\n handler(msg).catch(console.error);\n }\n }\n }\n } catch (err) {\n console.error(\"Redis stream poll error\", err);\n await new Promise((r) => setTimeout(r, 1000));\n }\n if (active) setTimeout(poll, 0);\n };\n\n // Start polling in next tick\n setTimeout(poll, 0);\n\n return {\n unsubscribe: async () => {\n active = false;\n },\n };\n }\n\n async consume(\n streamName: string,\n group: string,\n consumer: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n const streamKey = this.key(\"stream\", streamName);\n\n // Ensure group exists\n try {\n await this.redis.xgroup(\"CREATE\", streamKey, group, \"$\", \"MKSTREAM\");\n } catch (e: any) {\n if (!e.message.includes(\"BUSYGROUP\")) throw e;\n }\n\n let active = true;\n const poll = async () => {\n if (!active) return;\n try {\n // Read as consumer group\n const results = (await this.redis.xreadgroup(\n \"GROUP\",\n group,\n consumer,\n \"COUNT\",\n 10,\n \"BLOCK\",\n 1000,\n \"STREAMS\",\n streamKey,\n \">\"\n )) as any;\n\n if (results) {\n for (const [stream, messages] of results) {\n for (const [id, fields] of messages) {\n const dataIdx = fields.indexOf(\"data\");\n const headersIdx = fields.indexOf(\"headers\");\n const data = dataIdx > -1 ? JSON.parse(fields[dataIdx + 1]) : {};\n const headers =\n headersIdx > -1 ? JSON.parse(fields[headersIdx + 1]) : {};\n\n const msg: Message = {\n id,\n stream: streamName,\n data,\n headers,\n timestamp: parseInt(id.split(\"-\")[0]),\n ack: async () => {\n await this.redis.xack(streamKey, group, id);\n },\n nack: async (requeue = true) => {\n // Redis streams don't support NACK/requeue natively like AMQP.\n // The message stays in PEL (Pending Entries List).\n // We could claim it or just leave it for another consumer to claim.\n },\n };\n handler(msg).catch(console.error);\n }\n }\n }\n } catch (err) {\n console.error(\"Redis consumer poll error\", err);\n await new Promise((r) => setTimeout(r, 1000));\n }\n if (active) setTimeout(poll, 0);\n };\n\n setTimeout(poll, 0);\n\n return {\n unsubscribe: async () => {\n active = false;\n },\n };\n }\n\n async createConsumerGroup(stream: string, group: string): Promise<void> {\n const streamKey = this.key(\"stream\", stream);\n try {\n await this.redis.xgroup(\"CREATE\", streamKey, group, \"$\", \"MKSTREAM\");\n } catch (e: any) {\n if (!e.message.includes(\"BUSYGROUP\")) throw e;\n }\n }\n\n async saveWorkflowState(\n workflowId: string,\n state: WorkflowExecution\n ): Promise<void> {\n await this.redis.set(\n this.key(\"workflow\", workflowId),\n JSON.stringify(state)\n );\n }\n\n async loadWorkflowState(\n workflowId: string\n ): Promise<WorkflowExecution | null> {\n const data = await this.redis.get(this.key(\"workflow\", workflowId));\n return data ? JSON.parse(data) : null;\n }\n\n async getJob(queue: string, jobId: string): Promise<Job | null> {\n const jobData = await this.redis.get(this.key(\"job\", jobId));\n return jobData ? JSON.parse(jobData) : null;\n }\n\n async getJobs(queue: string, status: string): Promise<Job[]> {\n // Simplified implementation - would need custom tracking for status in production\n return [];\n }\n\n async getAllJobs(queue: string): Promise<Job[]> {\n // Simplified implementation - would need custom tracking in production\n return [];\n }\n\n async cleanJobs(\n queue: string,\n grace: number,\n status: string\n ): Promise<number> {\n // Simplified implementation - would need custom tracking in production\n return 0;\n }\n\n async getQueueStats(queueName: string): Promise<QueueStats> {\n const length = await this.redis.llen(this.key(\"queue\", queueName));\n const delayedLength = await this.redis.zcard(\n this.key(\"delayed\", queueName)\n );\n return {\n waiting: length,\n active: 0,\n completed: 0,\n failed: 0,\n delayed: delayedLength,\n paused: 0,\n };\n }\n\n async getStreamInfo(streamName: string): Promise<StreamInfo> {\n return {\n name: streamName,\n length: 0,\n groups: 0,\n };\n }\n\n async cleanup(): Promise<void> {\n for (const subs of this.subscriptions.values()) {\n for (const sub of subs) {\n await sub.quit();\n }\n }\n this.subscriptions.clear();\n await this.redis.quit();\n }\n}\n","import { pgTable, varchar, text, jsonb, integer, bigint, timestamp, index, uniqueIndex } from 'drizzle-orm/pg-core';\n\nexport const jobs = pgTable('flowfn_jobs', {\n id: varchar('id', { length: 255 }).primaryKey(),\n queue: varchar('queue', { length: 255 }).notNull(),\n name: varchar('name', { length: 255 }).notNull(),\n data: jsonb('data').notNull(),\n opts: jsonb('opts'),\n \n state: varchar('state', { length: 50 }).notNull(), // waiting, active, completed, failed, delayed, paused\n priority: integer('priority').default(0),\n progress: integer('progress').default(0),\n returnValue: jsonb('return_value'),\n \n timestamp: bigint('timestamp', { mode: 'number' }).notNull(),\n processedOn: bigint('processed_on', { mode: 'number' }),\n finishedOn: bigint('finished_on', { mode: 'number' }),\n delay: bigint('delay', { mode: 'number' }).default(0),\n \n attemptsMade: integer('attempts_made').default(0),\n failedReason: text('failed_reason'),\n stacktrace: jsonb('stacktrace'),\n \n createdAt: timestamp('created_at').defaultNow(),\n updatedAt: timestamp('updated_at').defaultNow(),\n}, (table) => ({\n queueStateIdx: index('idx_queue_state').on(table.queue, table.state),\n queuePriorityIdx: index('idx_queue_priority').on(table.queue, table.priority),\n timestampIdx: index('idx_timestamp').on(table.timestamp),\n}));\n\nexport const messages = pgTable('flowfn_messages', {\n id: varchar('id', { length: 255 }).primaryKey(),\n stream: varchar('stream', { length: 255 }).notNull(),\n data: jsonb('data').notNull(),\n headers: jsonb('headers'),\n \n partition: integer('partition'),\n offset: bigint('offset', { mode: 'number' }),\n key: varchar('key', { length: 255 }),\n \n timestamp: bigint('timestamp', { mode: 'number' }).notNull(),\n createdAt: timestamp('created_at').defaultNow(),\n}, (table) => ({\n streamTimestampIdx: index('idx_stream_timestamp').on(table.stream, table.timestamp),\n}));\n\nexport const consumerGroups = pgTable('flowfn_consumer_groups', {\n id: varchar('id', { length: 255 }).primaryKey(),\n stream: varchar('stream', { length: 255 }).notNull(),\n groupId: varchar('group_id', { length: 255 }).notNull(),\n consumerId: varchar('consumer_id', { length: 255 }).notNull(),\n \n lastMessageId: varchar('last_message_id', { length: 255 }),\n lastOffset: bigint('last_offset', { mode: 'number' }),\n lag: integer('lag'),\n \n createdAt: timestamp('created_at').defaultNow(),\n updatedAt: timestamp('updated_at').defaultNow(),\n}, (table) => ({\n streamGroupConsumerIdx: uniqueIndex('idx_stream_group_consumer').on(table.stream, table.groupId, table.consumerId),\n}));\n\nexport const workflows = pgTable('flowfn_workflows', {\n id: varchar('id', { length: 255 }).primaryKey(),\n name: varchar('name', { length: 255 }).notNull(),\n definition: jsonb('definition').notNull(),\n version: integer('version').default(1),\n \n status: varchar('status', { length: 50 }).notNull(),\n metadata: jsonb('metadata'),\n \n createdAt: timestamp('created_at').defaultNow(),\n updatedAt: timestamp('updated_at').defaultNow(),\n});\n\nexport const workflowExecutions = pgTable('flowfn_workflow_executions', {\n id: varchar('id', { length: 255 }).primaryKey(),\n workflowId: varchar('workflow_id', { length: 255 }).notNull(),\n workflowName: varchar('workflow_name', { length: 255 }),\n \n status: varchar('status', { length: 50 }).notNull(),\n input: jsonb('input'),\n state: jsonb('state'),\n output: jsonb('output'),\n error: text('error'),\n \n currentStep: varchar('current_step', { length: 255 }),\n completedSteps: jsonb('completed_steps'),\n \n startedAt: bigint('started_at', { mode: 'number' }).notNull(),\n updatedAt: bigint('updated_at', { mode: 'number' }),\n completedAt: bigint('completed_at', { mode: 'number' }),\n durationMs: integer('duration_ms'),\n}, (table) => ({\n workflowIdx: index('idx_workflow').on(table.workflowId),\n statusIdx: index('idx_status').on(table.status),\n}));\n\nexport const workflowEvents = pgTable('flowfn_workflow_events', {\n id: varchar('id', { length: 255 }).primaryKey(),\n executionId: varchar('execution_id', { length: 255 }).notNull(),\n \n type: varchar('type', { length: 50 }).notNull(),\n step: varchar('step', { length: 255 }),\n timestamp: bigint('timestamp', { mode: 'number' }).notNull(),\n data: jsonb('data'),\n}, (table) => ({\n executionIdx: index('idx_execution').on(table.executionId),\n}));\n","import { FlowAdapter } from \"../base.js\";\nimport { Job, QueueStats } from \"../../queue/types.js\";\nimport {\n Message,\n MessageHandler,\n Subscription,\n StreamInfo,\n} from \"../../stream/types.js\";\nimport { WorkflowExecution } from \"../../workflow/types.js\";\nimport {\n jobs,\n messages,\n workflowExecutions,\n consumerGroups,\n} from \"./schema.js\";\nimport { eq, and, lt, asc, sql } from \"drizzle-orm\";\nimport { v4 as uuidv4 } from \"uuid\";\n\nexport interface PostgresAdapterOptions {\n db: any; // Drizzle instance\n schema?: string;\n pollInterval?: number;\n}\n\nexport class PostgresAdapter implements FlowAdapter {\n private db: any;\n private pollInterval: number;\n private activeSubscriptions: Map<string, boolean> = new Map();\n\n constructor(options: PostgresAdapterOptions) {\n this.db = options.db;\n this.pollInterval = options.pollInterval || 1000;\n }\n\n async enqueue(queueName: string, job: Job): Promise<string> {\n await this.db.insert(jobs).values({\n id: job.id,\n queue: queueName,\n name: job.name,\n data: job.data,\n opts: job.opts,\n state: job.opts.delay ? \"delayed\" : \"waiting\",\n timestamp: job.timestamp,\n delay: job.opts.delay || 0,\n priority: job.opts.priority || 0,\n attemptsMade: 0,\n });\n return job.id;\n }\n\n async dequeue(queueName: string): Promise<Job | null> {\n // Attempt SKIP LOCKED if supported (Postgres)\n // Drizzle doesn't have a standardized \"for update skip locked\" across all dialects yet in generic query builder,\n // but assuming Postgres dialect here as per name.\n\n // We want to find a job that is 'waiting' OR ('delayed' AND timestamp + delay <= now)\n // And mark it 'active' atomically.\n\n const now = Date.now();\n\n return await this.db.transaction(async (tx: any) => {\n // This is a raw SQL approach for Postgres SKIP LOCKED as Drizzle query builder support varies\n // Assuming 'jobs' table is 'flowfn_jobs'\n\n // 1. Check for delayed jobs that are ready\n // (In a real high-perf system, a background process might move delayed -> waiting)\n // For simplicity, we check both here.\n\n const result = await tx.execute(sql`\n UPDATE flowfn_jobs\n SET state = 'active', processed_on = ${now}\n WHERE id = (\n SELECT id\n FROM flowfn_jobs\n WHERE queue = ${queueName}\n AND (\n state = 'waiting'\n OR (state = 'delayed' AND (timestamp + delay) <= ${now})\n )\n ORDER BY priority DESC, timestamp ASC\n FOR UPDATE SKIP LOCKED\n LIMIT 1\n )\n RETURNING *\n `);\n\n if (result.length === 0) return null;\n\n const row = result[0];\n // Normalize back to Job object\n return {\n id: row.id,\n name: row.name,\n data: row.data,\n opts: row.opts,\n state: row.state,\n progress: row.progress,\n returnvalue: row.return_value,\n timestamp: Number(row.timestamp),\n processedOn: Number(row.processed_on),\n finishedOn: Number(row.finished_on),\n delay: Number(row.delay),\n attemptsMade: row.attempts_made,\n failedReason: row.failed_reason,\n stacktrace: row.stacktrace,\n // Re-bind methods in queue implementation\n } as unknown as Job;\n });\n }\n\n async ack(queue: string, jobId: string): Promise<void> {\n // Usually mark as completed or delete.\n // If removeOnComplete, delete.\n // For now, mark completed.\n await this.db\n .update(jobs)\n .set({ state: \"completed\", finishedOn: Date.now() })\n .where(eq(jobs.id, jobId));\n }\n\n async nack(\n queue: string,\n jobId: string,\n requeue: boolean = true\n ): Promise<void> {\n if (requeue) {\n await this.db\n .update(jobs)\n .set({ state: \"waiting\", processedOn: null }) // Reset for retry\n .where(eq(jobs.id, jobId));\n } else {\n // Leave as active? Or failed?\n }\n }\n\n async publish(streamName: string, message: Message): Promise<string> {\n await this.db.insert(messages).values({\n id: message.id,\n stream: streamName,\n data: message.data,\n headers: message.headers,\n timestamp: message.timestamp,\n partition: message.partition,\n key: message.key,\n });\n return message.id;\n }\n\n async subscribe(\n streamName: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n // Polling implementation for streams\n // Real postgres could use LISTEN/NOTIFY\n\n const subId = uuidv4();\n this.activeSubscriptions.set(subId, true);\n\n let lastTimestamp = Date.now(); // Start from now\n\n const poll = async () => {\n if (!this.activeSubscriptions.get(subId)) return;\n\n try {\n const msgs = await this.db\n .select()\n .from(messages)\n .where(\n and(\n eq(messages.stream, streamName),\n sql`${messages.timestamp} > ${lastTimestamp}`\n )\n )\n .orderBy(asc(messages.timestamp))\n .limit(100);\n\n for (const row of msgs) {\n lastTimestamp = Math.max(lastTimestamp, Number(row.timestamp));\n\n const msg: Message = {\n id: row.id,\n stream: row.stream,\n data: row.data,\n headers: row.headers as any,\n timestamp: Number(row.timestamp),\n ack: async () => {},\n nack: async () => {},\n };\n handler(msg).catch(console.error);\n }\n } catch (e) {\n console.error(\"Postgres stream poll error\", e);\n }\n\n if (this.activeSubscriptions.get(subId)) {\n setTimeout(poll, this.pollInterval);\n }\n };\n\n setTimeout(poll, 0);\n\n return {\n unsubscribe: async () => {\n this.activeSubscriptions.set(subId, false);\n },\n };\n }\n\n async createConsumerGroup(stream: string, group: string): Promise<void> {\n // Manage in DB\n }\n\n async saveWorkflowState(\n workflowId: string,\n state: WorkflowExecution\n ): Promise<void> {\n // Upsert execution\n await this.db\n .insert(workflowExecutions)\n .values({\n id: state.id,\n workflowId: state.workflowId,\n status: state.status,\n input: state.input,\n output: state.output,\n error:\n state.error instanceof Error\n ? state.error.message\n : String(state.error),\n startedAt: state.startedAt,\n completedAt: state.completedAt,\n })\n .onConflictDoUpdate({\n target: workflowExecutions.id,\n set: {\n status: state.status,\n output: state.output,\n error:\n state.error instanceof Error\n ? state.error.message\n : String(state.error),\n updatedAt: Date.now(),\n completedAt: state.completedAt,\n },\n });\n }\n\n async loadWorkflowState(\n executionId: string\n ): Promise<WorkflowExecution | null> {\n const rows = await this.db\n .select()\n .from(workflowExecutions)\n .where(eq(workflowExecutions.id, executionId));\n if (rows.length === 0) return null;\n const row = rows[0];\n return {\n id: row.id,\n workflowId: row.workflowId,\n status: row.status as any, // Cast from DB string to union type\n input: row.input,\n output: row.output,\n error: row.error,\n startedAt: Number(row.startedAt),\n completedAt: row.completedAt ? Number(row.completedAt) : undefined,\n };\n }\n\n async getJob(queue: string, jobId: string): Promise<Job | null> {\n const rows = await this.db\n .select()\n .from(jobs)\n .where(and(eq(jobs.queue, queue), eq(jobs.id, jobId)));\n if (rows.length === 0) return null;\n const row = rows[0];\n return {\n id: row.id,\n name: row.name,\n data: row.data,\n opts: row.opts,\n state: row.state,\n timestamp: Number(row.timestamp),\n attemptsMade: row.attempts_made,\n } as any;\n }\n\n async getQueueStats(queueName: string): Promise<QueueStats> {\n const counts = await this.db\n .select({\n state: jobs.state,\n count: sql<number>`count(*)`,\n })\n .from(jobs)\n .where(eq(jobs.queue, queueName))\n .groupBy(jobs.state);\n\n const stats: QueueStats = {\n waiting: 0,\n active: 0,\n completed: 0,\n failed: 0,\n delayed: 0,\n paused: 0,\n };\n for (const c of counts) {\n if (c.state in stats) {\n (stats as any)[c.state] = Number(c.count);\n }\n }\n return stats;\n }\n\n async getStreamInfo(streamName: string): Promise<StreamInfo> {\n return { name: streamName, length: 0, groups: 0 };\n }\n\n async consume(\n stream: string,\n group: string,\n consumer: string,\n handler: MessageHandler<any>\n ): Promise<Subscription> {\n // Simplified consumer group implementation\n return this.subscribe(stream, handler);\n }\n\n async getJobs(queue: string, status: string): Promise<Job[]> {\n const rows = await this.db\n .select()\n .from(jobs)\n .where(and(eq(jobs.queue, queue), eq(jobs.state, status)));\n return rows.map(\n (row: any) =>\n ({\n id: row.id,\n name: row.name,\n data: row.data,\n opts: row.opts,\n state: row.state,\n timestamp: Number(row.timestamp),\n attemptsMade: row.attempts_made,\n }) as any\n );\n }\n\n async getAllJobs(queue: string): Promise<Job[]> {\n const rows = await this.db.select().from(jobs).where(eq(jobs.queue, queue));\n return rows.map(\n (row: any) =>\n ({\n id: row.id,\n name: row.name,\n data: row.data,\n opts: row.opts,\n state: row.state,\n timestamp: Number(row.timestamp),\n attemptsMade: row.attempts_made,\n }) as any\n );\n }\n\n async cleanJobs(\n queue: string,\n grace: number,\n status: string\n ): Promise<number> {\n const now = Date.now();\n const result = await this.db\n .delete(jobs)\n .where(\n and(\n eq(jobs.queue, queue),\n eq(jobs.state, status),\n sql`${jobs.finishedOn} < ${now - grace}`\n )\n );\n return result.rowCount || 0;\n }\n\n async cleanup(): Promise<void> {\n this.activeSubscriptions.clear();\n }\n}\n","import { Job } from '../queue/types.js';\n\nexport interface CircuitBreakerOptions {\n threshold: number;\n timeout: number;\n resetTimeout?: number;\n}\n\nexport type CircuitState = 'CLOSED' | 'OPEN' | 'HALF_OPEN';\n\nexport function circuitBreaker<T>(\n options: CircuitBreakerOptions,\n handler: (job: Job<T>) => Promise<any>\n) {\n let state: CircuitState = 'CLOSED';\n let failures = 0;\n let lastFailureTime = 0;\n let lastSuccessTime = 0;\n\n return async (job: Job<T>) => {\n const now = Date.now();\n\n if (state === 'OPEN') {\n if (now - lastFailureTime > options.timeout) {\n state = 'HALF_OPEN';\n } else {\n throw new Error('Circuit Breaker is OPEN');\n }\n }\n\n try {\n const result = await handler(job);\n \n if (state === 'HALF_OPEN') {\n state = 'CLOSED';\n failures = 0;\n }\n \n lastSuccessTime = now;\n return result;\n } catch (err) {\n failures++;\n lastFailureTime = now;\n\n if (state === 'HALF_OPEN' || failures >= options.threshold) {\n state = 'OPEN';\n }\n\n throw err;\n }\n };\n}\n","/**\n * Rate limiting pattern for FlowFn\n */\n\nexport interface RateLimitOptions {\n /**\n * Maximum number of requests allowed\n */\n limit: number;\n\n /**\n * Time window in milliseconds\n */\n window: number;\n\n /**\n * Strategy for handling rate limit exceeded\n */\n strategy?: \"throw\" | \"delay\" | \"drop\";\n\n /**\n * Custom key generator for partitioning rate limits\n */\n keyGenerator?: (...args: any[]) => string;\n}\n\nexport interface RateLimitResult {\n allowed: boolean;\n remaining: number;\n resetAt: number;\n retryAfter?: number;\n}\n\nexport class RateLimiter {\n private counters: Map<string, { count: number; resetAt: number }> = new Map();\n private options: RateLimitOptions;\n\n constructor(options: RateLimitOptions) {\n this.options = {\n strategy: \"throw\",\n ...options,\n };\n }\n\n /**\n * Check if request is allowed\n */\n async check(key: string = \"default\"): Promise<RateLimitResult> {\n const now = Date.now();\n let counter = this.counters.get(key);\n\n // Reset counter if window has passed\n if (!counter || now >= counter.resetAt) {\n counter = {\n count: 0,\n resetAt: now + this.options.window,\n };\n this.counters.set(key, counter);\n }\n\n const allowed = counter.count < this.options.limit;\n const remaining = Math.max(0, this.options.limit - counter.count);\n const retryAfter = allowed ? undefined : counter.resetAt - now;\n\n if (allowed) {\n counter.count++;\n }\n\n return {\n allowed,\n remaining,\n resetAt: counter.resetAt,\n retryAfter,\n };\n }\n\n /**\n * Execute a function with rate limiting\n */\n async execute<T>(fn: () => Promise<T>, key: string = \"default\"): Promise<T> {\n const result = await this.check(key);\n\n if (!result.allowed) {\n switch (this.options.strategy) {\n case \"throw\":\n throw new Error(\n `Rate limit exceeded. Retry after ${result.retryAfter}ms`\n );\n\n case \"delay\":\n await new Promise((resolve) =>\n setTimeout(resolve, result.retryAfter)\n );\n return this.execute(fn, key);\n\n case \"drop\":\n throw new Error(\"Request dropped due to rate limit\");\n\n default:\n throw new Error(\"Unknown rate limit strategy\");\n }\n }\n\n return fn();\n }\n\n /**\n * Clear all rate limit counters\n */\n reset(): void {\n this.counters.clear();\n }\n\n /**\n * Clear rate limit counter for specific key\n */\n resetKey(key: string): void {\n this.counters.delete(key);\n }\n\n /**\n * Get current limit info for a key\n */\n getInfo(key: string = \"default\"): RateLimitResult {\n const now = Date.now();\n const counter = this.counters.get(key);\n\n if (!counter || now >= counter.resetAt) {\n return {\n allowed: true,\n remaining: this.options.limit,\n resetAt: now + this.options.window,\n };\n }\n\n const allowed = counter.count < this.options.limit;\n const remaining = Math.max(0, this.options.limit - counter.count);\n\n return {\n allowed,\n remaining,\n resetAt: counter.resetAt,\n retryAfter: allowed ? undefined : counter.resetAt - now,\n };\n }\n}\n\n/**\n * Create a rate limiter\n */\nexport function createRateLimiter(options: RateLimitOptions): RateLimiter {\n return new RateLimiter(options);\n}\n\n/**\n * Sliding window rate limiter (more accurate)\n */\nexport class SlidingWindowRateLimiter {\n private requests: Map<string, number[]> = new Map();\n private options: RateLimitOptions;\n\n constructor(options: RateLimitOptions) {\n this.options = options;\n }\n\n async check(key: string = \"default\"): Promise<RateLimitResult> {\n const now = Date.now();\n const windowStart = now - this.options.window;\n\n let requests = this.requests.get(key) || [];\n\n // Remove old requests outside the window\n requests = requests.filter((timestamp) => timestamp > windowStart);\n this.requests.set(key, requests);\n\n const allowed = requests.length < this.options.limit;\n const remaining = Math.max(0, this.options.limit - requests.length);\n\n if (allowed) {\n requests.push(now);\n }\n\n const oldestRequest = requests[0];\n const resetAt = oldestRequest\n ? oldestRequest + this.options.window\n : now + this.options.window;\n const retryAfter = allowed ? undefined : resetAt - now;\n\n return {\n allowed,\n remaining,\n resetAt,\n retryAfter,\n };\n }\n\n async execute<T>(fn: () => Promise<T>, key: string = \"default\"): Promise<T> {\n const result = await this.check(key);\n\n if (!result.allowed) {\n switch (this.options.strategy || \"throw\") {\n case \"throw\":\n throw new Error(\n `Rate limit exceeded. Retry after ${result.retryAfter}ms`\n );\n case \"delay\":\n await new Promise((resolve) =>\n setTimeout(resolve, result.retryAfter)\n );\n return this.execute(fn, key);\n case \"drop\":\n throw new Error(\"Request dropped due to rate limit\");\n }\n }\n\n return fn();\n }\n\n reset(): void {\n this.requests.clear();\n }\n}\n\n/**\n * Token bucket rate limiter\n */\nexport class TokenBucketRateLimiter {\n private buckets: Map<string, { tokens: number; lastRefill: number }> =\n new Map();\n private capacity: number;\n private refillRate: number; // tokens per second\n private refillInterval: number;\n\n constructor(options: {\n capacity: number;\n refillRate: number;\n refillInterval?: number;\n }) {\n this.capacity = options.capacity;\n this.refillRate = options.refillRate;\n this.refillInterval = options.refillInterval || 1000; // default 1 second\n }\n\n private refill(key: string): void {\n const now = Date.now();\n let bucket = this.buckets.get(key);\n\n if (!bucket) {\n bucket = { tokens: this.capacity, lastRefill: now };\n this.buckets.set(key, bucket);\n return;\n }\n\n const timePassed = now - bucket.lastRefill;\n const intervals = timePassed / this.refillInterval;\n const tokensToAdd = intervals * this.refillRate;\n\n bucket.tokens = Math.min(this.capacity, bucket.tokens + tokensToAdd);\n bucket.lastRefill = now;\n }\n\n async check(\n key: string = \"default\",\n cost: number = 1\n ): Promise<RateLimitResult> {\n this.refill(key);\n const bucket = this.buckets.get(key)!;\n\n const allowed = bucket.tokens >= cost;\n\n if (allowed) {\n bucket.tokens -= cost;\n }\n\n return {\n allowed,\n remaining: Math.floor(bucket.tokens),\n resetAt: bucket.lastRefill + this.refillInterval,\n retryAfter: allowed\n ? undefined\n : Math.ceil(\n ((cost - bucket.tokens) / this.refillRate) * this.refillInterval\n ),\n };\n }\n\n reset(): void {\n this.buckets.clear();\n }\n}\n","/**\n * Batching utilities for FlowFn\n */\n\nexport interface BatchOptions {\n /**\n * Maximum number of items per batch\n */\n maxSize: number;\n\n /**\n * Maximum time to wait before flushing batch (ms)\n */\n maxWait?: number;\n\n /**\n * Minimum size before processing (default: 1)\n */\n minSize?: number;\n}\n\nexport interface BatchProcessor<T, R> {\n /**\n * Process a batch of items\n */\n (items: T[]): Promise<R[]>;\n}\n\n/**\n * Batch accumulator for collecting and processing items in batches\n */\nexport class BatchAccumulator<T, R = any> {\n private batch: T[] = [];\n private timer: NodeJS.Timeout | null = null;\n private options: Required<BatchOptions>;\n private processor: BatchProcessor<T, R>;\n private pending: Array<{\n resolve: (value: R) => void;\n reject: (error: Error) => void;\n }> = [];\n\n constructor(processor: BatchProcessor<T, R>, options: BatchOptions) {\n this.processor = processor;\n this.options = {\n minSize: 1,\n maxWait: 1000,\n ...options,\n };\n }\n\n /**\n * Add an item to the batch\n */\n async add(item: T): Promise<R> {\n return new Promise<R>((resolve, reject) => {\n this.batch.push(item);\n this.pending.push({ resolve, reject });\n\n // Flush if batch is full\n if (this.batch.length >= this.options.maxSize) {\n this.flush();\n } else if (!this.timer) {\n // Set timer for max wait\n this.timer = setTimeout(() => {\n this.flush();\n }, this.options.maxWait);\n }\n });\n }\n\n /**\n * Manually flush the current batch\n */\n async flush(): Promise<void> {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n\n if (this.batch.length < this.options.minSize) {\n return;\n }\n\n const currentBatch = this.batch;\n const currentPending = this.pending;\n\n this.batch = [];\n this.pending = [];\n\n try {\n const results = await this.processor(currentBatch);\n\n // Resolve all pending promises\n for (let i = 0; i < currentPending.length; i++) {\n currentPending[i].resolve(results[i]);\n }\n } catch (error) {\n // Reject all pending promises\n for (const pending of currentPending) {\n pending.reject(error as Error);\n }\n }\n }\n\n /**\n * Get current batch size\n */\n size(): number {\n return this.batch.length;\n }\n\n /**\n * Clear the batch without processing\n */\n clear(): void {\n if (this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n this.batch = [];\n\n // Reject all pending\n for (const pending of this.pending) {\n pending.reject(new Error(\"Batch cleared\"));\n }\n this.pending = [];\n }\n}\n\n/**\n * Create a batched version of a function\n */\nexport function batch<T, R>(\n fn: (items: T[]) => Promise<R[]>,\n options: BatchOptions\n): (item: T) => Promise<R> {\n const accumulator = new BatchAccumulator(fn, options);\n return (item: T) => accumulator.add(item);\n}\n\n/**\n * Batch array into chunks\n */\nexport function chunk<T>(array: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < array.length; i += size) {\n chunks.push(array.slice(i, i + size));\n }\n return chunks;\n}\n\n/**\n * Process array in batches with delay between batches\n */\nexport async function processBatches<T, R>(\n items: T[],\n processor: (batch: T[]) => Promise<R[]>,\n options: { batchSize: number; delayMs?: number }\n): Promise<R[]> {\n const batches = chunk(items, options.batchSize);\n const results: R[] = [];\n\n for (let i = 0; i < batches.length; i++) {\n const batchResults = await processor(batches[i]);\n results.push(...batchResults);\n\n // Add delay between batches (except after last batch)\n if (i < batches.length - 1 && options.delayMs) {\n await new Promise((resolve) => setTimeout(resolve, options.delayMs));\n }\n }\n\n return results;\n}\n\n/**\n * Batch write operations with auto-flush\n */\nexport class BatchWriter<T> {\n private accumulator: BatchAccumulator<T, void>;\n\n constructor(writer: (items: T[]) => Promise<void>, options: BatchOptions) {\n this.accumulator = new BatchAccumulator(async (items) => {\n await writer(items);\n return new Array(items.length).fill(undefined);\n }, options);\n }\n\n async write(item: T): Promise<void> {\n return this.accumulator.add(item);\n }\n\n async flush(): Promise<void> {\n return this.accumulator.flush();\n }\n\n size(): number {\n return this.accumulator.size();\n }\n\n clear(): void {\n this.accumulator.clear();\n }\n}\n\n/**\n * Group items by a key function and process in batches\n */\nexport async function batchByKey<T, R>(\n items: T[],\n keyFn: (item: T) => string,\n processor: (key: string, items: T[]) => Promise<R[]>,\n options?: { concurrency?: number }\n): Promise<R[]> {\n const grouped = new Map<string, T[]>();\n\n // Group items by key\n for (const item of items) {\n const key = keyFn(item);\n if (!grouped.has(key)) {\n grouped.set(key, []);\n }\n grouped.get(key)!.push(item);\n }\n\n // Process each group\n const results: R[] = [];\n const entries = Array.from(grouped.entries());\n\n if (options?.concurrency) {\n // Process with concurrency limit\n for (let i = 0; i < entries.length; i += options.concurrency) {\n const batch = entries.slice(i, i + options.concurrency);\n const batchResults = await Promise.all(\n batch.map(([key, items]) => processor(key, items))\n );\n results.push(...batchResults.flat());\n }\n } else {\n // Process sequentially\n for (const [key, keyItems] of entries) {\n const batchResults = await processor(key, keyItems);\n results.push(...batchResults);\n }\n }\n\n return results;\n}\n","/**\n * Priority queue pattern for FlowFn\n */\n\nexport interface PriorityItem<T> {\n value: T;\n priority: number;\n}\n\n/**\n * Priority queue implementation using binary heap\n */\nexport class PriorityQueue<T> {\n private heap: PriorityItem<T>[] = [];\n private compareFn: (a: number, b: number) => number;\n\n constructor(mode: \"min\" | \"max\" = \"max\") {\n // Max heap by default (higher priority first)\n this.compareFn =\n mode === \"max\"\n ? (a, b) => a - b // Max heap: parent >= children\n : (a, b) => b - a; // Min heap: parent <= children\n }\n\n /**\n * Add item with priority\n */\n enqueue(value: T, priority: number): void {\n this.heap.push({ value, priority });\n this.bubbleUp(this.heap.length - 1);\n }\n\n /**\n * Remove and return highest priority item\n */\n dequeue(): T | undefined {\n if (this.heap.length === 0) return undefined;\n if (this.heap.length === 1) return this.heap.pop()!.value;\n\n const result = this.heap[0];\n this.heap[0] = this.heap.pop()!;\n this.bubbleDown(0);\n\n return result.value;\n }\n\n /**\n * Peek at highest priority item without removing\n */\n peek(): T | undefined {\n return this.heap[0]?.value;\n }\n\n /**\n * Get queue size\n */\n size(): number {\n return this.heap.length;\n }\n\n /**\n * Check if queue is empty\n */\n isEmpty(): boolean {\n return this.heap.length === 0;\n }\n\n /**\n * Clear the queue\n */\n clear(): void {\n this.heap = [];\n }\n\n /**\n * Convert to array (sorted by priority)\n */\n toArray(): T[] {\n const copy = [...this.heap];\n const result: T[] = [];\n\n while (this.heap.length > 0) {\n result.push(this.dequeue()!);\n }\n\n this.heap = copy;\n return result;\n }\n\n private bubbleUp(index: number): void {\n while (index > 0) {\n const parentIndex = Math.floor((index - 1) / 2);\n\n if (\n this.compareFn(\n this.heap[index].priority,\n this.heap[parentIndex].priority\n ) <= 0\n ) {\n break;\n }\n\n [this.heap[index], this.heap[parentIndex]] = [\n this.heap[parentIndex],\n this.heap[index],\n ];\n index = parentIndex;\n }\n }\n\n private bubbleDown(index: number): void {\n while (true) {\n const leftChild = 2 * index + 1;\n const rightChild = 2 * index + 2;\n let largest = index;\n\n if (\n leftChild < this.heap.length &&\n this.compareFn(\n this.heap[leftChild].priority,\n this.heap[largest].priority\n ) > 0\n ) {\n largest = leftChild;\n }\n\n if (\n rightChild < this.heap.length &&\n this.compareFn(\n this.heap[rightChild].priority,\n this.heap[largest].priority\n ) > 0\n ) {\n largest = rightChild;\n }\n\n if (largest === index) break;\n\n [this.heap[index], this.heap[largest]] = [\n this.heap[largest],\n this.heap[index],\n ];\n index = largest;\n }\n }\n}\n","import { createHash } from \"crypto\";\n\n/**\n * Generate a hash for job deduplication\n */\nexport function hashJob(data: any, options?: { algorithm?: string }): string {\n const algorithm = options?.algorithm || \"sha256\";\n const hash = createHash(algorithm);\n\n // Normalize and stringify the data for consistent hashing\n const normalized = JSON.stringify(data, Object.keys(data).sort());\n hash.update(normalized);\n\n return hash.digest(\"hex\");\n}\n\n/**\n * Generate a deduplication key from job name and data\n */\nexport function generateDeduplicationKey(name: string, data: any): string {\n return `${name}:${hashJob(data)}`;\n}\n\n/**\n * Check if two job payloads are equivalent\n */\nexport function areJobsEquivalent(job1: any, job2: any): boolean {\n return hashJob(job1) === hashJob(job2);\n}\n","import { v4 as uuidv4, v5 as uuidv5, v1 as uuidv1 } from \"uuid\";\nimport { createHash, randomBytes } from \"crypto\";\n\n/**\n * ID generation strategies\n */\nexport type IdStrategy =\n | \"uuid-v4\"\n | \"uuid-v5\"\n | \"uuid-v1\"\n | \"nanoid\"\n | \"incremental\"\n | \"custom\";\n\nexport interface IdGeneratorOptions {\n strategy?: IdStrategy;\n namespace?: string; // For UUID v5\n prefix?: string;\n customGenerator?: () => string;\n}\n\n/**\n * Generate a unique identifier based on the specified strategy\n */\nexport function generateId(options: IdGeneratorOptions = {}): string {\n const {\n strategy = \"uuid-v4\",\n namespace,\n prefix = \"\",\n customGenerator,\n } = options;\n\n let id: string;\n\n switch (strategy) {\n case \"uuid-v4\":\n id = uuidv4();\n break;\n\n case \"uuid-v5\":\n if (!namespace) {\n throw new Error(\"UUID v5 requires a namespace\");\n }\n const name = `${Date.now()}-${randomBytes(8).toString(\"hex\")}`;\n id = uuidv5(name, namespace);\n break;\n\n case \"uuid-v1\":\n id = uuidv1();\n break;\n\n case \"nanoid\":\n // Simple nanoid-like implementation\n id = randomBytes(16).toString(\"base64url\");\n break;\n\n case \"incremental\":\n // Simple timestamp-based incremental ID\n id = `${Date.now()}-${randomBytes(4).toString(\"hex\")}`;\n break;\n\n case \"custom\":\n if (!customGenerator) {\n throw new Error(\"Custom strategy requires customGenerator function\");\n }\n id = customGenerator();\n break;\n\n default:\n id = uuidv4();\n }\n\n return prefix ? `${prefix}${id}` : id;\n}\n\n/**\n * Generate a job ID with optional prefix\n */\nexport function generateJobId(prefix?: string): string {\n return generateId({ prefix: prefix || \"job_\" });\n}\n\n/**\n * Generate a workflow execution ID\n */\nexport function generateExecutionId(prefix?: string): string {\n return generateId({ prefix: prefix || \"exec_\" });\n}\n\n/**\n * Generate a message ID for streams\n */\nexport function generateMessageId(prefix?: string): string {\n return generateId({ prefix: prefix || \"msg_\" });\n}\n\n/**\n * Generate a deterministic ID based on content (useful for idempotency)\n */\nexport function generateDeterministicId(\n content: string | object,\n prefix?: string\n): string {\n const hash = createHash(\"sha256\");\n const data = typeof content === \"string\" ? content : JSON.stringify(content);\n hash.update(data);\n const id = hash.digest(\"hex\").slice(0, 32);\n return prefix ? `${prefix}${id}` : id;\n}\n","/**\n * Time utility functions for FlowFn\n */\n\n/**\n * Duration units\n */\nexport interface Duration {\n milliseconds?: number;\n seconds?: number;\n minutes?: number;\n hours?: number;\n days?: number;\n weeks?: number;\n}\n\n/**\n * Convert duration object to milliseconds\n */\nexport function toMilliseconds(duration: Duration): number {\n let ms = 0;\n\n if (duration.milliseconds) ms += duration.milliseconds;\n if (duration.seconds) ms += duration.seconds * 1000;\n if (duration.minutes) ms += duration.minutes * 60 * 1000;\n if (duration.hours) ms += duration.hours * 60 * 60 * 1000;\n if (duration.days) ms += duration.days * 24 * 60 * 60 * 1000;\n if (duration.weeks) ms += duration.weeks * 7 * 24 * 60 * 60 * 1000;\n\n return ms;\n}\n\n/**\n * Convert milliseconds to duration object\n */\nexport function fromMilliseconds(ms: number): Duration {\n const weeks = Math.floor(ms / (7 * 24 * 60 * 60 * 1000));\n ms %= 7 * 24 * 60 * 60 * 1000;\n\n const days = Math.floor(ms / (24 * 60 * 60 * 1000));\n ms %= 24 * 60 * 60 * 1000;\n\n const hours = Math.floor(ms / (60 * 60 * 1000));\n ms %= 60 * 60 * 1000;\n\n const minutes = Math.floor(ms / (60 * 1000));\n ms %= 60 * 1000;\n\n const seconds = Math.floor(ms / 1000);\n const milliseconds = ms % 1000;\n\n return { weeks, days, hours, minutes, seconds, milliseconds };\n}\n\n/**\n * Format duration as human-readable string\n */\nexport function formatDuration(duration: Duration): string {\n const parts: string[] = [];\n\n if (duration.weeks) parts.push(`${duration.weeks}w`);\n if (duration.days) parts.push(`${duration.days}d`);\n if (duration.hours) parts.push(`${duration.hours}h`);\n if (duration.minutes) parts.push(`${duration.minutes}m`);\n if (duration.seconds) parts.push(`${duration.seconds}s`);\n if (duration.milliseconds) parts.push(`${duration.milliseconds}ms`);\n\n return parts.join(\" \") || \"0ms\";\n}\n\n/**\n * Sleep for specified milliseconds\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * Sleep for specified duration\n */\nexport async function sleepDuration(duration: Duration): Promise<void> {\n return sleep(toMilliseconds(duration));\n}\n\n/**\n * Create a timeout promise\n */\nexport function timeout<T>(\n promise: Promise<T>,\n ms: number,\n message?: string\n): Promise<T> {\n return Promise.race([\n promise,\n new Promise<T>((_, reject) =>\n setTimeout(\n () => reject(new Error(message || `Timeout after ${ms}ms`)),\n ms\n )\n ),\n ]);\n}\n\n/**\n * Get current timestamp in milliseconds\n */\nexport function now(): number {\n return Date.now();\n}\n\n/**\n * Calculate delay until a specific timestamp\n */\nexport function delayUntil(timestamp: number): number {\n return Math.max(0, timestamp - Date.now());\n}\n\n/**\n * Check if a timestamp is in the past\n */\nexport function isPast(timestamp: number): boolean {\n return timestamp < Date.now();\n}\n\n/**\n * Check if a timestamp is in the future\n */\nexport function isFuture(timestamp: number): boolean {\n return timestamp > Date.now();\n}\n\n/**\n * Add duration to timestamp\n */\nexport function addDuration(timestamp: number, duration: Duration): number {\n return timestamp + toMilliseconds(duration);\n}\n\n/**\n * Parse cron-like duration string (e.g., \"5m\", \"1h\", \"30s\")\n */\nexport function parseDuration(str: string): number {\n const match = str.match(/^(\\d+)(ms|s|m|h|d|w)$/);\n if (!match) {\n throw new Error(`Invalid duration string: ${str}`);\n }\n\n const value = parseInt(match[1], 10);\n const unit = match[2];\n\n switch (unit) {\n case \"ms\":\n return value;\n case \"s\":\n return value * 1000;\n case \"m\":\n return value * 60 * 1000;\n case \"h\":\n return value * 60 * 60 * 1000;\n case \"d\":\n return value * 24 * 60 * 60 * 1000;\n case \"w\":\n return value * 7 * 24 * 60 * 60 * 1000;\n default:\n throw new Error(`Unknown unit: ${unit}`);\n }\n}\n","/**\n * Serialization utilities for FlowFn\n */\n\nexport interface SerializationOptions {\n pretty?: boolean;\n includeUndefined?: boolean;\n dateFormat?: \"iso\" | \"timestamp\";\n}\n\n/**\n * Serialize job data to JSON string\n */\nexport function serialize<T = any>(\n data: T,\n options: SerializationOptions = {}\n): string {\n const { pretty = false, dateFormat = \"iso\" } = options;\n\n const replacer = (key: string, value: any) => {\n // Handle dates\n if (value instanceof Date) {\n return dateFormat === \"timestamp\" ? value.getTime() : value.toISOString();\n }\n\n // Handle undefined\n if (value === undefined && !options.includeUndefined) {\n return null;\n }\n\n // Handle functions (skip them)\n if (typeof value === \"function\") {\n return undefined;\n }\n\n // Handle BigInt\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n\n return value;\n };\n\n return JSON.stringify(data, replacer, pretty ? 2 : undefined);\n}\n\n/**\n * Deserialize JSON string to object\n */\nexport function deserialize<T = any>(json: string): T {\n return JSON.parse(json, (key, value) => {\n // Try to parse ISO date strings\n if (typeof value === \"string\") {\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z?$/;\n if (isoDateRegex.test(value)) {\n return new Date(value);\n }\n }\n return value;\n });\n}\n\n/**\n * Safely serialize data with circular reference handling\n */\nexport function serializeSafe<T = any>(\n data: T,\n options: SerializationOptions = {}\n): string {\n const seen = new WeakSet();\n const { pretty = false } = options;\n\n const replacer = (key: string, value: any) => {\n if (typeof value === \"object\" && value !== null) {\n if (seen.has(value)) {\n return \"[Circular]\";\n }\n seen.add(value);\n }\n\n // Handle dates\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n // Handle functions\n if (typeof value === \"function\") {\n return \"[Function]\";\n }\n\n // Handle BigInt\n if (typeof value === \"bigint\") {\n return value.toString();\n }\n\n return value;\n };\n\n return JSON.stringify(data, replacer, pretty ? 2 : undefined);\n}\n\n/**\n * Clone an object using serialization\n */\nexport function cloneViaSerialization<T>(obj: T): T {\n return deserialize(serialize(obj));\n}\n\n/**\n * Serialize with compression (base64 encode)\n */\nexport function serializeCompressed<T = any>(data: T): string {\n const json = serialize(data);\n return Buffer.from(json).toString(\"base64\");\n}\n\n/**\n * Deserialize compressed data\n */\nexport function deserializeCompressed<T = any>(compressed: string): T {\n const json = Buffer.from(compressed, \"base64\").toString(\"utf-8\");\n return deserialize(json);\n}\n\n/**\n * Check if a value is serializable\n */\nexport function isSerializable(value: any): boolean {\n try {\n serialize(value);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get size of serialized data in bytes\n */\nexport function getSerializedSize(data: any): number {\n return Buffer.byteLength(serialize(data), \"utf-8\");\n}\n","/**\n * Storage abstraction for FlowFn job persistence\n */\n\nimport { Job, JobStatus } from \"../queue/types.js\";\n\nexport interface JobStorage {\n /**\n * Save a job\n */\n save(queue: string, job: Job): Promise<void>;\n\n /**\n * Get a job by ID\n */\n get(queue: string, jobId: string): Promise<Job | null>;\n\n /**\n * Get jobs by status\n */\n getByStatus(queue: string, status: JobStatus): Promise<Job[]>;\n\n /**\n * Get all jobs for a queue\n */\n getAll(queue: string): Promise<Job[]>;\n\n /**\n * Update job status\n */\n updateStatus(queue: string, jobId: string, status: JobStatus): Promise<void>;\n\n /**\n * Update job data\n */\n update(queue: string, jobId: string, updates: Partial<Job>): Promise<void>;\n\n /**\n * Delete a job\n */\n delete(queue: string, jobId: string): Promise<void>;\n\n /**\n * Delete jobs older than grace period with given status\n */\n clean(queue: string, grace: number, status: JobStatus): Promise<number>;\n\n /**\n * Get job count by status\n */\n count(queue: string, status?: JobStatus): Promise<number>;\n\n /**\n * Check if job exists with deduplication key\n */\n existsByDeduplicationKey(queue: string, key: string): Promise<boolean>;\n}\n\n/**\n * In-memory implementation of JobStorage\n */\nexport class MemoryJobStorage implements JobStorage {\n private jobs: Map<string, Job> = new Map();\n private deduplicationKeys: Map<string, string> = new Map(); // key -> jobId\n\n async save(queue: string, job: Job): Promise<void> {\n const key = `${queue}:${job.id}`;\n this.jobs.set(key, { ...job });\n\n // Store deduplication key if present\n if (job.opts.deduplicationKey) {\n const dedupKey = `${queue}:${job.opts.deduplicationKey}`;\n this.deduplicationKeys.set(dedupKey, job.id);\n }\n }\n\n async get(queue: string, jobId: string): Promise<Job | null> {\n const key = `${queue}:${jobId}`;\n return this.jobs.get(key) || null;\n }\n\n async getByStatus(queue: string, status: JobStatus): Promise<Job[]> {\n const result: Job[] = [];\n const prefix = `${queue}:`;\n\n for (const [key, job] of this.jobs.entries()) {\n if (key.startsWith(prefix) && job.state === status) {\n result.push(job);\n }\n }\n\n return result;\n }\n\n async getAll(queue: string): Promise<Job[]> {\n const result: Job[] = [];\n const prefix = `${queue}:`;\n\n for (const [key, job] of this.jobs.entries()) {\n if (key.startsWith(prefix)) {\n result.push(job);\n }\n }\n\n return result;\n }\n\n async updateStatus(\n queue: string,\n jobId: string,\n status: JobStatus\n ): Promise<void> {\n const key = `${queue}:${jobId}`;\n const job = this.jobs.get(key);\n\n if (job) {\n job.state = status;\n if (status === \"completed\" || status === \"failed\") {\n job.finishedOn = Date.now();\n }\n }\n }\n\n async update(\n queue: string,\n jobId: string,\n updates: Partial<Job>\n ): Promise<void> {\n const key = `${queue}:${jobId}`;\n const job = this.jobs.get(key);\n\n if (job) {\n Object.assign(job, updates);\n }\n }\n\n async delete(queue: string, jobId: string): Promise<void> {\n const key = `${queue}:${jobId}`;\n const job = this.jobs.get(key);\n\n if (job?.opts.deduplicationKey) {\n const dedupKey = `${queue}:${job.opts.deduplicationKey}`;\n this.deduplicationKeys.delete(dedupKey);\n }\n\n this.jobs.delete(key);\n }\n\n async clean(\n queue: string,\n grace: number,\n status: JobStatus\n ): Promise<number> {\n const now = Date.now();\n const prefix = `${queue}:`;\n const toDelete: string[] = [];\n\n for (const [key, job] of this.jobs.entries()) {\n if (key.startsWith(prefix) && job.state === status) {\n const timestamp = job.finishedOn || job.timestamp;\n if (now - timestamp > grace) {\n toDelete.push(key);\n }\n }\n }\n\n for (const key of toDelete) {\n const job = this.jobs.get(key);\n if (job?.opts.deduplicationKey) {\n const dedupKey = `${queue}:${job.opts.deduplicationKey}`;\n this.deduplicationKeys.delete(dedupKey);\n }\n this.jobs.delete(key);\n }\n\n return toDelete.length;\n }\n\n async count(queue: string, status?: JobStatus): Promise<number> {\n const prefix = `${queue}:`;\n let count = 0;\n\n for (const [key, job] of this.jobs.entries()) {\n if (key.startsWith(prefix)) {\n if (!status || job.state === status) {\n count++;\n }\n }\n }\n\n return count;\n }\n\n async existsByDeduplicationKey(queue: string, key: string): Promise<boolean> {\n const dedupKey = `${queue}:${key}`;\n return this.deduplicationKeys.has(dedupKey);\n }\n\n /**\n * Clear all jobs\n */\n clear(): void {\n this.jobs.clear();\n this.deduplicationKeys.clear();\n }\n}\n"],"mappings":"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","names":["now","timestamp","uuidv4","import_eventemitter3","EventEmitter","jobs","batch","import_uuid","uuidv4","messages","now","import_uuid","now","index","s","uuidv4","timeout","now","now","parser","index","now","now","import_eventemitter3","EventEmitter","import_eventemitter3","EventEmitter","jobs","now","Redis","now","jobId","messages","import_uuid","now","uuidv4","now","now","timestamp","batch","items","index","import_uuid","import_crypto","uuidv4","uuidv5","uuidv1","timestamp","now","timestamp"]}