@gravito/flux 1.0.0-beta.6 → 1.0.0-beta.7

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.
@@ -622,6 +622,7 @@ var FluxEngine = class {
622
622
  status: "rolling_back",
623
623
  error: originalError.message
624
624
  });
625
+ let compensatedCount = 0;
625
626
  for (let i = failedAtIndex - 1; i >= 0; i--) {
626
627
  const step = definition.steps[i];
627
628
  const execution = ctx.history[i];
@@ -634,6 +635,7 @@ var FluxEngine = class {
634
635
  await step.compensate(ctx);
635
636
  execution.status = "compensated";
636
637
  execution.compensatedAt = /* @__PURE__ */ new Date();
638
+ compensatedCount++;
637
639
  await this.emitTrace({
638
640
  type: "step:compensate",
639
641
  timestamp: Date.now(),
@@ -658,14 +660,18 @@ var FluxEngine = class {
658
660
  }
659
661
  await this.storage.save(this.contextManager.toState(ctx));
660
662
  }
661
- Object.assign(ctx, { status: "rolled_back" });
662
- await this.emitTrace({
663
- type: "workflow:rollback_complete",
664
- timestamp: Date.now(),
665
- workflowId: ctx.id,
666
- workflowName: ctx.name,
667
- status: "rolled_back"
668
- });
663
+ if (compensatedCount > 0) {
664
+ Object.assign(ctx, { status: "rolled_back" });
665
+ await this.emitTrace({
666
+ type: "workflow:rollback_complete",
667
+ timestamp: Date.now(),
668
+ workflowId: ctx.id,
669
+ workflowName: ctx.name,
670
+ status: "rolled_back"
671
+ });
672
+ } else {
673
+ Object.assign(ctx, { status: "failed" });
674
+ }
669
675
  }
670
676
  async runFrom(definition, ctx, stateMachine, startTime, startIndex, meta) {
671
677
  try {
@@ -995,4 +1001,4 @@ export {
995
1001
  FluxSilentLogger,
996
1002
  OrbitFlux
997
1003
  };
998
- //# sourceMappingURL=chunk-CICUXW2L.js.map
1004
+ //# sourceMappingURL=chunk-LULCFPIK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/builder/WorkflowBuilder.ts","../src/core/ContextManager.ts","../src/core/StateMachine.ts","../src/core/StepExecutor.ts","../src/storage/MemoryStorage.ts","../src/engine/FluxEngine.ts","../src/trace/JsonFileTraceSink.ts","../src/logger/FluxLogger.ts","../src/orbit/OrbitFlux.ts"],"sourcesContent":["/**\n * @fileoverview Workflow Builder - Fluent API for defining workflows\n *\n * Type-safe, chainable workflow definition.\n *\n * @module @gravito/flux/builder\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepDescriptor,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n} from '../types'\n\n/**\n * Step options\n */\ninterface StepOptions<TInput = any, TData = any> {\n retries?: number\n timeout?: number\n when?: (ctx: WorkflowContext<TInput, TData>) => boolean\n compensate?: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void\n}\n\n/**\n * Workflow Builder\n *\n * Provides fluent API for defining workflows with type inference.\n *\n * @example\n * ```typescript\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processOrder(ctx.data.order)\n * }, {\n * compensate: async (ctx) => {\n * await cancelOrder(ctx.data.order.id)\n * }\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n * ```\n */\nexport class WorkflowBuilder<TInput = unknown, TData = Record<string, unknown>> {\n private _name: string\n private _steps: StepDefinition[] = []\n private _validateInput?: (input: unknown) => input is TInput\n\n constructor(name: string) {\n this._name = name\n }\n\n /**\n * Define input type\n *\n * This method is used for TypeScript type inference.\n */\n input<T>(): WorkflowBuilder<T, TData> {\n return this as unknown as WorkflowBuilder<T, TData>\n }\n\n /**\n * Define workflow data (state) type\n *\n * This method is used for TypeScript type inference.\n */\n data<T>(): WorkflowBuilder<TInput, T> {\n return this as unknown as WorkflowBuilder<TInput, T>\n }\n\n /**\n * Add input validator\n */\n validate(validator: (input: unknown) => input is TInput): this {\n this._validateInput = validator\n return this\n }\n\n /**\n * Add a step to the workflow\n */\n step(\n name: string,\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n options?: StepOptions<TInput, TData>\n ): this {\n this._steps.push({\n name,\n handler: handler as (\n ctx: WorkflowContext\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n compensate: options?.compensate as\n | ((ctx: WorkflowContext) => Promise<void> | void)\n | undefined,\n commit: false,\n })\n return this\n }\n\n /**\n * Add a commit step (always executes, even on replay)\n *\n * Commit steps are for side effects that should not be skipped,\n * such as database writes or external API calls.\n */\n commit(\n name: string,\n handler: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void,\n options?: Omit<StepOptions<TInput, TData>, 'compensate'>\n ): this {\n this._steps.push({\n name,\n handler: handler as (ctx: WorkflowContext) => Promise<void> | void,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n commit: true,\n })\n return this\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDefinition<TInput, TData> {\n if (this._steps.length === 0) {\n throw new Error(`Workflow \"${this._name}\" has no steps`)\n }\n\n return {\n name: this._name,\n steps: [...this._steps],\n validateInput: this._validateInput,\n }\n }\n\n /**\n * Describe workflow (serializable metadata)\n */\n describe(): WorkflowDescriptor {\n const steps: StepDescriptor[] = this._steps.map((step) => ({\n name: step.name,\n commit: Boolean(step.commit),\n retries: step.retries,\n timeout: step.timeout,\n hasCondition: Boolean(step.when),\n }))\n\n return {\n name: this._name,\n steps,\n }\n }\n\n /**\n * Get workflow name\n */\n get name(): string {\n return this._name\n }\n\n /**\n * Get step count\n */\n get stepCount(): number {\n return this._steps.length\n }\n}\n\n/**\n * Create a new workflow builder\n *\n * @param name - Unique workflow name\n * @returns WorkflowBuilder instance\n *\n * @example\n * ```typescript\n * const uploadFlow = createWorkflow('image-upload')\n * .input<{ file: Buffer }>()\n * .step('resize', async (ctx) => {\n * ctx.data.resized = await sharp(ctx.input.file).resize(200).toBuffer()\n * })\n * .commit('save', async (ctx) => {\n * await storage.put(ctx.data.resized)\n * })\n * ```\n */\nexport function createWorkflow(name: string): WorkflowBuilder {\n return new WorkflowBuilder(name)\n}\n","/**\n * @fileoverview Context Manager for workflow execution\n *\n * Manages workflow context lifecycle and state snapshots.\n *\n * @module @gravito/flux/core\n */\n\nimport type { StepExecution, WorkflowContext, WorkflowState, WorkflowStatus } from '../types'\n\n/**\n * Generate unique ID using crypto.randomUUID (Web Standard)\n */\nfunction generateId(): string {\n return crypto.randomUUID()\n}\n\n/**\n * Context Manager\n *\n * Creates and manages workflow execution contexts.\n */\nexport class ContextManager {\n /**\n * Create a new workflow context\n */\n create<TInput, TData = any>(\n name: string,\n input: TInput,\n stepCount: number\n ): WorkflowContext<TInput, TData> {\n const history: StepExecution[] = Array.from({ length: stepCount }, (_, _i) => ({\n name: '',\n status: 'pending',\n retries: 0,\n }))\n\n return {\n id: generateId(),\n name,\n input,\n data: {} as TData,\n status: 'pending',\n currentStep: 0,\n history,\n }\n }\n\n /**\n * Restore context from saved state\n */\n restore<TInput, TData = any>(\n state: WorkflowState<TInput, TData>\n ): WorkflowContext<TInput, TData> {\n return {\n id: state.id,\n name: state.name,\n input: state.input as TInput,\n data: { ...state.data } as unknown as TData,\n status: state.status,\n currentStep: state.currentStep,\n history: state.history.map((h) => ({ ...h })),\n }\n }\n\n /**\n * Convert context to serializable state\n */\n toState<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowState<TInput, TData> {\n return {\n id: ctx.id,\n name: ctx.name,\n status: ctx.status,\n input: ctx.input,\n data: { ...(ctx.data as any) },\n currentStep: ctx.currentStep,\n history: ctx.history.map((h) => ({ ...h })),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n }\n\n /**\n * Update context status (returns new context for immutability)\n */\n updateStatus<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n status: WorkflowStatus\n ): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n status,\n }\n }\n\n /**\n * Advance to next step\n */\n advanceStep<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n currentStep: ctx.currentStep + 1,\n }\n }\n\n /**\n * Update step name in history\n */\n setStepName<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n index: number,\n name: string\n ): void {\n if (ctx.history[index]) {\n ctx.history[index].name = name\n }\n }\n}\n","/**\n * @fileoverview State Machine for workflow status transitions\n *\n * Pure state machine with no runtime dependencies.\n *\n * @module @gravito/flux/core\n */\n\nimport type { WorkflowStatus } from '../types'\n\n/**\n * Valid state transitions\n */\nconst TRANSITIONS: Record<WorkflowStatus, WorkflowStatus[]> = {\n pending: ['running', 'failed'],\n running: ['paused', 'completed', 'failed', 'suspended', 'rolling_back'],\n paused: ['running', 'failed'],\n suspended: ['running', 'failed'],\n rolling_back: ['rolled_back', 'failed'],\n rolled_back: ['pending'], // allow retry from scratch\n completed: [], // terminal state\n failed: ['pending'], // allow retry\n}\n\n/**\n * State Machine for workflow status management\n *\n * Provides validated state transitions using EventTarget for events.\n */\nexport class StateMachine extends EventTarget {\n private _status: WorkflowStatus = 'pending'\n\n /**\n * Current status\n */\n get status(): WorkflowStatus {\n return this._status\n }\n\n /**\n * Check if transition to target status is allowed\n */\n canTransition(to: WorkflowStatus): boolean {\n return TRANSITIONS[this._status].includes(to)\n }\n\n /**\n * Transition to a new status\n *\n * @throws {Error} If transition is not allowed\n */\n transition(to: WorkflowStatus): void {\n if (!this.canTransition(to)) {\n throw new Error(`Invalid state transition: ${this._status} → ${to}`)\n }\n\n const from = this._status\n this._status = to\n\n // Emit transition event\n this.dispatchEvent(\n new CustomEvent('transition', {\n detail: { from, to },\n })\n )\n }\n\n /**\n * Force set status (for replay/restore)\n */\n forceStatus(status: WorkflowStatus): void {\n this._status = status\n }\n\n /**\n * Check if workflow is in terminal state\n */\n isTerminal(): boolean {\n return (\n this._status === 'completed' || this._status === 'failed' || this._status === 'rolled_back'\n )\n }\n\n /**\n * Check if workflow can be executed\n */\n canExecute(): boolean {\n return this._status === 'pending' || this._status === 'paused'\n }\n}\n","/**\n * @fileoverview Step Executor for workflow steps\n *\n * Handles step execution with retry and timeout support.\n *\n * @module @gravito/flux/core\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepExecution,\n StepResult,\n WorkflowContext,\n} from '../types'\n\n/**\n * Step Executor\n *\n * Executes individual workflow steps with retry and timeout support.\n */\nexport class StepExecutor {\n private defaultRetries: number\n private defaultTimeout: number\n private onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n\n constructor(\n options: {\n defaultRetries?: number\n defaultTimeout?: number\n onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n } = {}\n ) {\n this.defaultRetries = options.defaultRetries ?? 3\n this.defaultTimeout = options.defaultTimeout ?? 30000\n this.onRetry = options.onRetry\n }\n\n /**\n * Execute a step with retry and timeout\n */\n async execute<TInput, TData>(\n step: StepDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n execution: StepExecution\n ): Promise<StepResult> {\n const maxRetries = step.retries ?? this.defaultRetries\n const timeout = step.timeout ?? this.defaultTimeout\n const startTime = Date.now()\n\n // Check condition\n if (step.when && !step.when(ctx)) {\n execution.status = 'skipped'\n return {\n success: true,\n duration: 0,\n }\n }\n\n execution.status = 'running'\n execution.startedAt = new Date()\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n execution.retries = attempt\n\n try {\n // Execute with timeout\n const result = await this.executeWithTimeout(step.handler, ctx, timeout)\n\n if (\n result &&\n typeof result === 'object' &&\n '__kind' in result &&\n result.__kind === 'flux_wait'\n ) {\n execution.status = 'suspended'\n execution.waitingFor = result.signal\n execution.suspendedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n suspended: true,\n waitingFor: result.signal,\n duration: execution.duration,\n }\n }\n\n execution.status = 'completed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n duration: execution.duration,\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // If not last retry, continue\n if (attempt < maxRetries) {\n await this.onRetry?.(step, ctx, lastError, attempt + 1, maxRetries)\n // Exponential backoff\n await this.sleep(Math.min(1000 * 2 ** attempt, 10000))\n }\n }\n }\n\n // All retries failed\n execution.status = 'failed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n execution.error = lastError?.message\n\n return {\n success: false,\n error: lastError,\n duration: execution.duration,\n }\n }\n\n /**\n * Execute handler with timeout\n */\n private async executeWithTimeout<TInput, TData>(\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n ctx: WorkflowContext<TInput, TData>,\n timeout: number\n ): Promise<void | FluxWaitResult> {\n let timer: ReturnType<typeof setTimeout> | null = null\n try {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Step timeout')), timeout)\n })\n\n return await Promise.race([Promise.resolve(handler(ctx)), timeoutPromise])\n } finally {\n if (timer) {\n clearTimeout(timer)\n }\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n }\n}\n","/**\n * @fileoverview In-memory storage adapter\n *\n * Simple storage for development and testing.\n *\n * @module @gravito/flux/storage\n */\n\nimport type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types'\n\n/**\n * Memory Storage\n *\n * In-memory storage adapter for development and testing.\n * Data is not persisted across restarts.\n */\nexport class MemoryStorage implements WorkflowStorage {\n private store = new Map<string, WorkflowState>()\n\n async save(state: WorkflowState): Promise<void> {\n this.store.set(state.id, {\n ...state,\n updatedAt: new Date(),\n })\n }\n\n async load(id: string): Promise<WorkflowState | null> {\n return this.store.get(id) ?? null\n }\n\n async list(filter?: WorkflowFilter): Promise<WorkflowState[]> {\n let results = Array.from(this.store.values())\n\n if (filter?.name) {\n results = results.filter((s) => s.name === filter.name)\n }\n\n if (filter?.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status]\n results = results.filter((s) => statuses.includes(s.status))\n }\n\n // Sort by createdAt desc\n results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n\n // Apply pagination\n if (filter?.offset) {\n results = results.slice(filter.offset)\n }\n if (filter?.limit) {\n results = results.slice(0, filter.limit)\n }\n\n return results\n }\n\n async delete(id: string): Promise<void> {\n this.store.delete(id)\n }\n\n async init(): Promise<void> {\n // No-op for memory storage\n }\n\n async close(): Promise<void> {\n this.store.clear()\n }\n\n /**\n * Get store size (for testing)\n */\n size(): number {\n return this.store.size\n }\n}\n","/**\n * @fileoverview Flux Engine - Main workflow execution engine\n *\n * Orchestrates workflow execution with storage and event handling.\n *\n * @module @gravito/flux\n */\n\nimport { WorkflowBuilder } from '../builder/WorkflowBuilder'\nimport { ContextManager } from '../core/ContextManager'\nimport { StateMachine } from '../core/StateMachine'\nimport { StepExecutor } from '../core/StepExecutor'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type {\n FluxConfig,\n FluxResult,\n FluxTraceEvent,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowState,\n WorkflowStorage,\n} from '../types'\n\n/**\n * Flux Engine\n *\n * Main workflow execution engine.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({ storage: new MemoryStorage() })\n *\n * const workflow = createWorkflow('process-order')\n * .input<{ orderId: string }>()\n * .step('fetch', async (ctx) => { ... })\n * .step('validate', async (ctx) => { ... })\n * .commit('save', async (ctx) => { ... })\n *\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n */\nexport class FluxEngine {\n private storage: WorkflowStorage\n private executor: StepExecutor\n private contextManager: ContextManager\n private config: FluxConfig\n\n constructor(config: FluxConfig = {}) {\n this.config = config\n this.storage = config.storage ?? new MemoryStorage()\n this.executor = new StepExecutor({\n defaultRetries: config.defaultRetries,\n defaultTimeout: config.defaultTimeout,\n onRetry: async (step, ctx, error, attempt, maxRetries) => {\n await this.emitTrace({\n type: 'step:retry',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: ctx.currentStep,\n commit: Boolean(step.commit),\n retries: attempt,\n maxRetries,\n error: error.message,\n status: 'running',\n })\n },\n })\n this.contextManager = new ContextManager()\n }\n\n /**\n * Execute a workflow with input data\n *\n * @param workflow - Workflow builder or definition\n * @param input - Input data for the workflow\n * @returns Execution result\n */\n async execute<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n input: TInput\n ): Promise<FluxResult<TData>> {\n const startTime = Date.now()\n const definition = this.resolveDefinition(workflow)\n\n // Validate input if validator provided\n if (definition.validateInput && !definition.validateInput(input)) {\n throw new Error(`Invalid input for workflow \"${definition.name}\"`)\n }\n\n // Create context\n const ctx = this.contextManager.create<TInput, TData>(\n definition.name,\n input,\n definition.steps.length\n ) as WorkflowContext<TInput, TData>\n\n // Create state machine\n const stateMachine = new StateMachine()\n\n // Save initial state\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, startTime, 0)\n }\n\n /**\n * Resume a paused or failed workflow\n *\n * @param workflowId - Workflow instance ID\n * @returns Execution result or null if not found\n */\n async resume<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n options?: { fromStep?: number | string }\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; resume is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, options?.fromStep, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n resume: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Send a signal to a suspended workflow\n */\n async signal<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n signalName: string,\n payload?: any\n ): Promise<FluxResult<TData>> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n throw new Error('Workflow not found')\n }\n if (state.status !== 'suspended') {\n throw new Error(`Workflow is not suspended (status: ${state.status})`)\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const currentStep = ctx.history[ctx.currentStep]\n\n if (!currentStep || currentStep.status !== 'suspended') {\n throw new Error('Workflow state invalid: no suspended step found')\n }\n if (currentStep.waitingFor !== signalName) {\n throw new Error(\n `Workflow waiting for signal \"${currentStep.waitingFor}\", received \"${signalName}\"`\n )\n }\n\n // Complete the suspended step\n currentStep.status = 'completed'\n currentStep.completedAt = new Date()\n currentStep.output = payload\n // If payload contains data, we might want to merge it?\n // For now, allow next step to access it via history or we need a cleaner way.\n // Let's assume user grabs it from history for now or we build a helper later.\n\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('suspended')\n // ctx status will be updated to 'running' in runFrom\n\n await this.emitTrace({\n type: 'signal:received',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'suspended',\n input: payload,\n })\n\n // Resume from NEXT step\n const nextStepIndex = ctx.currentStep + 1\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), nextStepIndex, {\n resume: true,\n fromStep: nextStepIndex,\n })\n }\n\n /**\n * Retry a specific step (replays from that step onward)\n */\n async retryStep<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n stepName: string\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; retry is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, stepName, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n retry: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Get workflow state by ID\n */\n async get<TInput = any, TData = any>(\n workflowId: string\n ): Promise<WorkflowState<TInput, TData> | null> {\n return this.storage.load(workflowId) as Promise<WorkflowState<TInput, TData> | null>\n }\n\n /**\n * Save workflow state manually (e.g., for external updates)\n */\n async saveState<TInput, TData>(state: WorkflowState<TInput, TData>): Promise<void> {\n return this.storage.save(state)\n }\n\n /**\n * List workflows\n */\n async list(filter?: Parameters<WorkflowStorage['list']>[0]) {\n return this.storage.list(filter)\n }\n\n /**\n * Initialize engine (init storage)\n */\n async init(): Promise<void> {\n await this.storage.init?.()\n }\n\n /**\n * Shutdown engine (cleanup)\n */\n async close(): Promise<void> {\n await this.storage.close?.()\n }\n\n private resolveDefinition<TInput, TData>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>\n ): WorkflowDefinition<TInput, TData> {\n return workflow instanceof WorkflowBuilder ? workflow.build() : workflow\n }\n\n private resolveStartIndex<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n fromStep: number | string | undefined,\n fallback: number\n ): number {\n if (typeof fromStep === 'number') {\n if (fromStep < 0 || fromStep >= definition.steps.length) {\n throw new Error(`Invalid step index: ${fromStep}`)\n }\n return fromStep\n }\n if (typeof fromStep === 'string') {\n const index = definition.steps.findIndex((step) => step.name === fromStep)\n if (index === -1) {\n throw new Error(`Step not found: ${fromStep}`)\n }\n return index\n }\n return Math.max(0, Math.min(fallback, definition.steps.length - 1))\n }\n\n private resetHistoryFrom<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n startIndex: number\n ): void {\n for (let i = startIndex; i < ctx.history.length; i++) {\n const entry = ctx.history[i]\n if (!entry) {\n continue\n }\n entry.status = 'pending'\n entry.startedAt = undefined\n entry.completedAt = undefined\n entry.duration = undefined\n entry.error = undefined\n entry.retries = 0\n }\n }\n\n /**\n * Rollback workflow by executing compensation handlers in reverse order\n */\n private async rollback<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n failedAtIndex: number,\n originalError: Error\n ): Promise<void> {\n Object.assign(ctx, { status: 'rolling_back' })\n\n await this.emitTrace({\n type: 'workflow:rollback_start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolling_back',\n error: originalError.message,\n })\n\n let compensatedCount = 0\n\n // Iterate backwards from the step BEFORE the failed one\n for (let i = failedAtIndex - 1; i >= 0; i--) {\n const step = definition.steps[i]\n const execution = ctx.history[i]\n\n // Only compensate completed steps with compensation handler\n if (!step || !step.compensate || !execution || execution.status !== 'completed') {\n continue\n }\n\n try {\n execution.status = 'compensating'\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n await step.compensate(ctx)\n\n execution.status = 'compensated'\n execution.compensatedAt = new Date()\n compensatedCount++\n\n await this.emitTrace({\n type: 'step:compensate',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n status: 'compensated',\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n // Compensation failed - this is bad. Mark workflow as failed (not rolled_back)\n Object.assign(ctx, { status: 'failed' })\n\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n error: `Compensation failed at step \"${step.name}\": ${error.message}`,\n })\n return // Stop rollback\n }\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n if (compensatedCount > 0) {\n Object.assign(ctx, { status: 'rolled_back' })\n await this.emitTrace({\n type: 'workflow:rollback_complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolled_back',\n })\n } else {\n // No compensation occurred, revert to failed status\n Object.assign(ctx, { status: 'failed' })\n }\n }\n\n private async runFrom<TInput, TData = any>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n stateMachine: StateMachine,\n startTime: number,\n startIndex: number,\n meta?: { resume?: boolean; retry?: boolean; fromStep?: number }\n ): Promise<FluxResult<TData>> {\n try {\n // Transition to running\n stateMachine.transition('running')\n Object.assign(ctx, { status: 'running' })\n if (!meta?.resume) {\n await this.emitTrace({\n type: 'workflow:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n input: ctx.input,\n meta,\n })\n }\n\n // Execute steps\n for (let i = startIndex; i < definition.steps.length; i++) {\n const step = definition.steps[i]!\n const execution = ctx.history[i]!\n\n // Update step name\n this.contextManager.setStepName(ctx, i, step.name)\n Object.assign(ctx, { currentStep: i })\n\n // Emit step start event\n this.config.on?.stepStart?.(step.name, ctx as any)\n await this.emitTrace({\n type: 'step:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n status: execution.status,\n meta,\n })\n\n // Execute step\n const result = await this.executor.execute(step, ctx, execution)\n\n if (result.success) {\n if (result.suspended) {\n // Handle suspension\n stateMachine.transition('suspended')\n Object.assign(ctx, { status: 'suspended' })\n\n await this.emitTrace({\n type: 'step:suspend',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n meta: { signal: result.waitingFor },\n })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return {\n id: ctx.id,\n status: 'suspended',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n }\n\n // Emit step complete event\n this.config.on?.stepComplete?.(step.name, ctx as any, result)\n if (execution.status === 'skipped') {\n await this.emitTrace({\n type: 'step:skipped',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n } else {\n await this.emitTrace({\n type: 'step:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n }\n } else {\n // Emit step error event\n this.config.on?.stepError?.(step.name, ctx as any, result.error!)\n await this.emitTrace({\n type: 'step:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n error: result.error?.message,\n status: execution.status,\n meta,\n })\n\n // Fail workflow with potential rollback\n await this.rollback<TInput, TData>(definition, ctx, i, result.error!)\n\n const finalStatus = ctx.status\n stateMachine.forceStatus(finalStatus)\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: result.error?.message,\n })\n\n return {\n id: ctx.id,\n status: finalStatus,\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: result.error,\n }\n }\n\n // Save progress after each step\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n // Complete workflow\n stateMachine.transition('completed')\n Object.assign(ctx, { status: 'completed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n completedAt: new Date(),\n })\n\n // Emit workflow complete event\n this.config.on?.workflowComplete?.(ctx as any)\n await this.emitTrace({\n type: 'workflow:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n duration: Date.now() - startTime,\n data: ctx.data as Record<string, unknown>,\n meta,\n })\n\n return {\n id: ctx.id,\n status: 'completed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n\n // Emit workflow error event\n this.config.on?.workflowError?.(ctx as any, err)\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n duration: Date.now() - startTime,\n error: err.message,\n meta,\n })\n\n stateMachine.forceStatus('failed')\n Object.assign(ctx, { status: 'failed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: err.message,\n })\n\n return {\n id: ctx.id,\n status: 'failed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: err,\n }\n }\n }\n\n private async emitTrace(event: FluxTraceEvent): Promise<void> {\n try {\n await this.config.trace?.emit(event)\n } catch {\n // Ignore trace failures to avoid breaking workflow execution\n }\n }\n}\n","/**\n * @fileoverview JSON file trace sink (NDJSON)\n *\n * Writes trace events to a newline-delimited JSON file.\n */\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { FluxTraceEvent, FluxTraceSink } from '../types'\n\nexport interface JsonFileTraceSinkOptions {\n path: string\n reset?: boolean\n}\n\nexport class JsonFileTraceSink implements FluxTraceSink {\n private path: string\n private ready: Promise<void>\n\n constructor(options: JsonFileTraceSinkOptions) {\n this.path = options.path\n this.ready = this.init(options.reset ?? true)\n }\n\n private async init(reset: boolean): Promise<void> {\n await mkdir(dirname(this.path), { recursive: true })\n if (reset) {\n await writeFile(this.path, '', 'utf8')\n }\n }\n\n async emit(event: FluxTraceEvent): Promise<void> {\n await this.ready\n await appendFile(this.path, `${JSON.stringify(event)}\\n`, 'utf8')\n }\n}\n","/**\n * @fileoverview Console Logger for FluxEngine\n *\n * Default logger implementation using console.\n *\n * @module @gravito/flux\n */\n\nimport type { FluxLogger } from '../types'\n\n/**\n * Console Logger\n *\n * Default logger that outputs to console.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({\n * logger: new FluxConsoleLogger()\n * })\n * ```\n */\nexport class FluxConsoleLogger implements FluxLogger {\n private prefix: string\n\n constructor(prefix = '[Flux]') {\n this.prefix = prefix\n }\n\n debug(message: string, ...args: unknown[]): void {\n console.debug(`${this.prefix} ${message}`, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n console.info(`${this.prefix} ${message}`, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n console.warn(`${this.prefix} ${message}`, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n console.error(`${this.prefix} ${message}`, ...args)\n }\n}\n\n/**\n * Silent Logger\n *\n * Logger that outputs nothing (for testing or production).\n */\nexport class FluxSilentLogger implements FluxLogger {\n debug(): void {}\n info(): void {}\n warn(): void {}\n error(): void {}\n}\n","/**\n * @fileoverview OrbitFlux - Gravito PlanetCore Integration\n *\n * Integrates FluxEngine with Gravito's PlanetCore for seamless workflow management.\n *\n * @module @gravito/flux\n */\n\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { BunSQLiteStorage } from '../storage/BunSQLiteStorage'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type { FluxConfig, FluxLogger, WorkflowStorage } from '../types'\n\n/**\n * Minimal PlanetCore interface for type compatibility\n * (Avoids importing @gravito/core sources which causes rootDir issues)\n */\ninterface PlanetCore {\n logger: {\n debug(message: string, ...args: unknown[]): void\n info(message: string, ...args: unknown[]): void\n warn(message: string, ...args: unknown[]): void\n error(message: string, ...args: unknown[]): void\n }\n services: {\n set(key: string, value: unknown): void\n get<T>(key: string): T | undefined\n }\n hooks: {\n doAction(name: string, payload?: unknown): void\n }\n}\n\n/**\n * GravitoOrbit interface\n */\nexport interface GravitoOrbit {\n install(core: PlanetCore): void | Promise<void>\n}\n\n/**\n * OrbitFlux configuration options\n */\nexport interface OrbitFluxOptions {\n /**\n * Storage driver: 'memory' | 'sqlite' | custom WorkflowStorage\n * @default 'memory'\n */\n storage?: 'memory' | 'sqlite' | WorkflowStorage\n\n /**\n * SQLite database path (only used if storage is 'sqlite')\n * @default ':memory:'\n */\n dbPath?: string\n\n /**\n * Service name in core.services\n * @default 'flux'\n */\n exposeAs?: string\n\n /**\n * Custom logger\n */\n logger?: FluxLogger\n\n /**\n * Default retry count for steps\n * @default 3\n */\n defaultRetries?: number\n\n /**\n * Default timeout for steps (ms)\n * @default 30000\n */\n defaultTimeout?: number\n}\n\n/**\n * OrbitFlux - Gravito Workflow Integration\n *\n * @example\n * ```typescript\n * import { OrbitFlux } from '@gravito/flux'\n *\n * const core = await PlanetCore.boot({\n * orbits: [\n * new OrbitFlux({ storage: 'sqlite', dbPath: './data/workflows.db' })\n * ]\n * })\n *\n * // Access via services\n * const flux = core.services.get<FluxEngine>('flux')\n * await flux.execute(myWorkflow, input)\n * ```\n */\nexport class OrbitFlux implements GravitoOrbit {\n private options: OrbitFluxOptions\n private engine?: FluxEngine\n\n constructor(options: OrbitFluxOptions = {}) {\n this.options = {\n storage: 'memory',\n exposeAs: 'flux',\n defaultRetries: 3,\n defaultTimeout: 30000,\n ...options,\n }\n }\n\n /**\n * Create OrbitFlux with configuration\n */\n static configure(options: OrbitFluxOptions = {}): OrbitFlux {\n return new OrbitFlux(options)\n }\n\n /**\n * Install into PlanetCore\n *\n * @param core - The PlanetCore instance\n */\n async install(core: PlanetCore): Promise<void> {\n const { storage, dbPath, exposeAs, defaultRetries, defaultTimeout, logger } = this.options\n\n // Resolve storage adapter\n let storageAdapter: WorkflowStorage\n\n if (typeof storage === 'string') {\n switch (storage) {\n case 'sqlite':\n storageAdapter = new BunSQLiteStorage({ path: dbPath })\n break\n default:\n storageAdapter = new MemoryStorage()\n }\n } else {\n storageAdapter = storage!\n }\n\n // Initialize storage\n await storageAdapter.init?.()\n\n // Create engine configuration\n const engineConfig: FluxConfig = {\n storage: storageAdapter,\n defaultRetries,\n defaultTimeout,\n logger: logger ?? {\n debug: (msg) => core.logger.debug(`[Flux] ${msg}`),\n info: (msg) => core.logger.info(`[Flux] ${msg}`),\n warn: (msg) => core.logger.warn(`[Flux] ${msg}`),\n error: (msg) => core.logger.error(`[Flux] ${msg}`),\n },\n on: {\n stepStart: (step) => {\n core.hooks.doAction('flux:step:start', { step })\n },\n stepComplete: (step, ctx, result) => {\n core.hooks.doAction('flux:step:complete', { step, ctx, result })\n },\n stepError: (step, ctx, error) => {\n core.hooks.doAction('flux:step:error', { step, ctx, error })\n },\n workflowComplete: (ctx) => {\n core.hooks.doAction('flux:workflow:complete', { ctx })\n },\n workflowError: (ctx, error) => {\n core.hooks.doAction('flux:workflow:error', { ctx, error })\n },\n },\n }\n\n // Create engine\n this.engine = new FluxEngine(engineConfig)\n\n // Register in core services\n core.services.set(exposeAs!, this.engine)\n\n core.logger.info(\n `[OrbitFlux] Initialized (Storage: ${typeof storage === 'string' ? storage : 'custom'})`\n )\n }\n\n /**\n * Get the FluxEngine instance\n */\n getEngine(): FluxEngine | undefined {\n return this.engine\n }\n}\n"],"mappings":"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","names":[]}
@@ -622,6 +622,7 @@ var FluxEngine = class {
622
622
  status: "rolling_back",
623
623
  error: originalError.message
624
624
  });
625
+ let compensatedCount = 0;
625
626
  for (let i = failedAtIndex - 1; i >= 0; i--) {
626
627
  const step = definition.steps[i];
627
628
  const execution = ctx.history[i];
@@ -634,6 +635,7 @@ var FluxEngine = class {
634
635
  await step.compensate(ctx);
635
636
  execution.status = "compensated";
636
637
  execution.compensatedAt = /* @__PURE__ */ new Date();
638
+ compensatedCount++;
637
639
  await this.emitTrace({
638
640
  type: "step:compensate",
639
641
  timestamp: Date.now(),
@@ -658,14 +660,18 @@ var FluxEngine = class {
658
660
  }
659
661
  await this.storage.save(this.contextManager.toState(ctx));
660
662
  }
661
- Object.assign(ctx, { status: "rolled_back" });
662
- await this.emitTrace({
663
- type: "workflow:rollback_complete",
664
- timestamp: Date.now(),
665
- workflowId: ctx.id,
666
- workflowName: ctx.name,
667
- status: "rolled_back"
668
- });
663
+ if (compensatedCount > 0) {
664
+ Object.assign(ctx, { status: "rolled_back" });
665
+ await this.emitTrace({
666
+ type: "workflow:rollback_complete",
667
+ timestamp: Date.now(),
668
+ workflowId: ctx.id,
669
+ workflowName: ctx.name,
670
+ status: "rolled_back"
671
+ });
672
+ } else {
673
+ Object.assign(ctx, { status: "failed" });
674
+ }
669
675
  }
670
676
  async runFrom(definition, ctx, stateMachine, startTime, startIndex, meta) {
671
677
  try {
@@ -995,4 +1001,4 @@ var OrbitFlux = class _OrbitFlux {
995
1001
 
996
1002
 
997
1003
  exports.WorkflowBuilder = WorkflowBuilder; exports.createWorkflow = createWorkflow; exports.ContextManager = ContextManager; exports.StateMachine = StateMachine; exports.StepExecutor = StepExecutor; exports.MemoryStorage = MemoryStorage; exports.FluxEngine = FluxEngine; exports.JsonFileTraceSink = JsonFileTraceSink; exports.FluxConsoleLogger = FluxConsoleLogger; exports.FluxSilentLogger = FluxSilentLogger; exports.OrbitFlux = OrbitFlux;
998
- //# sourceMappingURL=chunk-BGLG7HAC.cjs.map
1004
+ //# sourceMappingURL=chunk-X3NC7HS4.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-X3NC7HS4.cjs","../src/builder/WorkflowBuilder.ts","../src/core/ContextManager.ts","../src/core/StateMachine.ts","../src/core/StepExecutor.ts","../src/storage/MemoryStorage.ts","../src/engine/FluxEngine.ts","../src/trace/JsonFileTraceSink.ts","../src/logger/FluxLogger.ts","../src/orbit/OrbitFlux.ts"],"names":[],"mappings":"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","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-X3NC7HS4.cjs","sourcesContent":[null,"/**\n * @fileoverview Workflow Builder - Fluent API for defining workflows\n *\n * Type-safe, chainable workflow definition.\n *\n * @module @gravito/flux/builder\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepDescriptor,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n} from '../types'\n\n/**\n * Step options\n */\ninterface StepOptions<TInput = any, TData = any> {\n retries?: number\n timeout?: number\n when?: (ctx: WorkflowContext<TInput, TData>) => boolean\n compensate?: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void\n}\n\n/**\n * Workflow Builder\n *\n * Provides fluent API for defining workflows with type inference.\n *\n * @example\n * ```typescript\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processOrder(ctx.data.order)\n * }, {\n * compensate: async (ctx) => {\n * await cancelOrder(ctx.data.order.id)\n * }\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n * ```\n */\nexport class WorkflowBuilder<TInput = unknown, TData = Record<string, unknown>> {\n private _name: string\n private _steps: StepDefinition[] = []\n private _validateInput?: (input: unknown) => input is TInput\n\n constructor(name: string) {\n this._name = name\n }\n\n /**\n * Define input type\n *\n * This method is used for TypeScript type inference.\n */\n input<T>(): WorkflowBuilder<T, TData> {\n return this as unknown as WorkflowBuilder<T, TData>\n }\n\n /**\n * Define workflow data (state) type\n *\n * This method is used for TypeScript type inference.\n */\n data<T>(): WorkflowBuilder<TInput, T> {\n return this as unknown as WorkflowBuilder<TInput, T>\n }\n\n /**\n * Add input validator\n */\n validate(validator: (input: unknown) => input is TInput): this {\n this._validateInput = validator\n return this\n }\n\n /**\n * Add a step to the workflow\n */\n step(\n name: string,\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n options?: StepOptions<TInput, TData>\n ): this {\n this._steps.push({\n name,\n handler: handler as (\n ctx: WorkflowContext\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n compensate: options?.compensate as\n | ((ctx: WorkflowContext) => Promise<void> | void)\n | undefined,\n commit: false,\n })\n return this\n }\n\n /**\n * Add a commit step (always executes, even on replay)\n *\n * Commit steps are for side effects that should not be skipped,\n * such as database writes or external API calls.\n */\n commit(\n name: string,\n handler: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void,\n options?: Omit<StepOptions<TInput, TData>, 'compensate'>\n ): this {\n this._steps.push({\n name,\n handler: handler as (ctx: WorkflowContext) => Promise<void> | void,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n commit: true,\n })\n return this\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDefinition<TInput, TData> {\n if (this._steps.length === 0) {\n throw new Error(`Workflow \"${this._name}\" has no steps`)\n }\n\n return {\n name: this._name,\n steps: [...this._steps],\n validateInput: this._validateInput,\n }\n }\n\n /**\n * Describe workflow (serializable metadata)\n */\n describe(): WorkflowDescriptor {\n const steps: StepDescriptor[] = this._steps.map((step) => ({\n name: step.name,\n commit: Boolean(step.commit),\n retries: step.retries,\n timeout: step.timeout,\n hasCondition: Boolean(step.when),\n }))\n\n return {\n name: this._name,\n steps,\n }\n }\n\n /**\n * Get workflow name\n */\n get name(): string {\n return this._name\n }\n\n /**\n * Get step count\n */\n get stepCount(): number {\n return this._steps.length\n }\n}\n\n/**\n * Create a new workflow builder\n *\n * @param name - Unique workflow name\n * @returns WorkflowBuilder instance\n *\n * @example\n * ```typescript\n * const uploadFlow = createWorkflow('image-upload')\n * .input<{ file: Buffer }>()\n * .step('resize', async (ctx) => {\n * ctx.data.resized = await sharp(ctx.input.file).resize(200).toBuffer()\n * })\n * .commit('save', async (ctx) => {\n * await storage.put(ctx.data.resized)\n * })\n * ```\n */\nexport function createWorkflow(name: string): WorkflowBuilder {\n return new WorkflowBuilder(name)\n}\n","/**\n * @fileoverview Context Manager for workflow execution\n *\n * Manages workflow context lifecycle and state snapshots.\n *\n * @module @gravito/flux/core\n */\n\nimport type { StepExecution, WorkflowContext, WorkflowState, WorkflowStatus } from '../types'\n\n/**\n * Generate unique ID using crypto.randomUUID (Web Standard)\n */\nfunction generateId(): string {\n return crypto.randomUUID()\n}\n\n/**\n * Context Manager\n *\n * Creates and manages workflow execution contexts.\n */\nexport class ContextManager {\n /**\n * Create a new workflow context\n */\n create<TInput, TData = any>(\n name: string,\n input: TInput,\n stepCount: number\n ): WorkflowContext<TInput, TData> {\n const history: StepExecution[] = Array.from({ length: stepCount }, (_, _i) => ({\n name: '',\n status: 'pending',\n retries: 0,\n }))\n\n return {\n id: generateId(),\n name,\n input,\n data: {} as TData,\n status: 'pending',\n currentStep: 0,\n history,\n }\n }\n\n /**\n * Restore context from saved state\n */\n restore<TInput, TData = any>(\n state: WorkflowState<TInput, TData>\n ): WorkflowContext<TInput, TData> {\n return {\n id: state.id,\n name: state.name,\n input: state.input as TInput,\n data: { ...state.data } as unknown as TData,\n status: state.status,\n currentStep: state.currentStep,\n history: state.history.map((h) => ({ ...h })),\n }\n }\n\n /**\n * Convert context to serializable state\n */\n toState<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowState<TInput, TData> {\n return {\n id: ctx.id,\n name: ctx.name,\n status: ctx.status,\n input: ctx.input,\n data: { ...(ctx.data as any) },\n currentStep: ctx.currentStep,\n history: ctx.history.map((h) => ({ ...h })),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n }\n\n /**\n * Update context status (returns new context for immutability)\n */\n updateStatus<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n status: WorkflowStatus\n ): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n status,\n }\n }\n\n /**\n * Advance to next step\n */\n advanceStep<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n currentStep: ctx.currentStep + 1,\n }\n }\n\n /**\n * Update step name in history\n */\n setStepName<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n index: number,\n name: string\n ): void {\n if (ctx.history[index]) {\n ctx.history[index].name = name\n }\n }\n}\n","/**\n * @fileoverview State Machine for workflow status transitions\n *\n * Pure state machine with no runtime dependencies.\n *\n * @module @gravito/flux/core\n */\n\nimport type { WorkflowStatus } from '../types'\n\n/**\n * Valid state transitions\n */\nconst TRANSITIONS: Record<WorkflowStatus, WorkflowStatus[]> = {\n pending: ['running', 'failed'],\n running: ['paused', 'completed', 'failed', 'suspended', 'rolling_back'],\n paused: ['running', 'failed'],\n suspended: ['running', 'failed'],\n rolling_back: ['rolled_back', 'failed'],\n rolled_back: ['pending'], // allow retry from scratch\n completed: [], // terminal state\n failed: ['pending'], // allow retry\n}\n\n/**\n * State Machine for workflow status management\n *\n * Provides validated state transitions using EventTarget for events.\n */\nexport class StateMachine extends EventTarget {\n private _status: WorkflowStatus = 'pending'\n\n /**\n * Current status\n */\n get status(): WorkflowStatus {\n return this._status\n }\n\n /**\n * Check if transition to target status is allowed\n */\n canTransition(to: WorkflowStatus): boolean {\n return TRANSITIONS[this._status].includes(to)\n }\n\n /**\n * Transition to a new status\n *\n * @throws {Error} If transition is not allowed\n */\n transition(to: WorkflowStatus): void {\n if (!this.canTransition(to)) {\n throw new Error(`Invalid state transition: ${this._status} → ${to}`)\n }\n\n const from = this._status\n this._status = to\n\n // Emit transition event\n this.dispatchEvent(\n new CustomEvent('transition', {\n detail: { from, to },\n })\n )\n }\n\n /**\n * Force set status (for replay/restore)\n */\n forceStatus(status: WorkflowStatus): void {\n this._status = status\n }\n\n /**\n * Check if workflow is in terminal state\n */\n isTerminal(): boolean {\n return (\n this._status === 'completed' || this._status === 'failed' || this._status === 'rolled_back'\n )\n }\n\n /**\n * Check if workflow can be executed\n */\n canExecute(): boolean {\n return this._status === 'pending' || this._status === 'paused'\n }\n}\n","/**\n * @fileoverview Step Executor for workflow steps\n *\n * Handles step execution with retry and timeout support.\n *\n * @module @gravito/flux/core\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepExecution,\n StepResult,\n WorkflowContext,\n} from '../types'\n\n/**\n * Step Executor\n *\n * Executes individual workflow steps with retry and timeout support.\n */\nexport class StepExecutor {\n private defaultRetries: number\n private defaultTimeout: number\n private onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n\n constructor(\n options: {\n defaultRetries?: number\n defaultTimeout?: number\n onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n } = {}\n ) {\n this.defaultRetries = options.defaultRetries ?? 3\n this.defaultTimeout = options.defaultTimeout ?? 30000\n this.onRetry = options.onRetry\n }\n\n /**\n * Execute a step with retry and timeout\n */\n async execute<TInput, TData>(\n step: StepDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n execution: StepExecution\n ): Promise<StepResult> {\n const maxRetries = step.retries ?? this.defaultRetries\n const timeout = step.timeout ?? this.defaultTimeout\n const startTime = Date.now()\n\n // Check condition\n if (step.when && !step.when(ctx)) {\n execution.status = 'skipped'\n return {\n success: true,\n duration: 0,\n }\n }\n\n execution.status = 'running'\n execution.startedAt = new Date()\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n execution.retries = attempt\n\n try {\n // Execute with timeout\n const result = await this.executeWithTimeout(step.handler, ctx, timeout)\n\n if (\n result &&\n typeof result === 'object' &&\n '__kind' in result &&\n result.__kind === 'flux_wait'\n ) {\n execution.status = 'suspended'\n execution.waitingFor = result.signal\n execution.suspendedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n suspended: true,\n waitingFor: result.signal,\n duration: execution.duration,\n }\n }\n\n execution.status = 'completed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n duration: execution.duration,\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // If not last retry, continue\n if (attempt < maxRetries) {\n await this.onRetry?.(step, ctx, lastError, attempt + 1, maxRetries)\n // Exponential backoff\n await this.sleep(Math.min(1000 * 2 ** attempt, 10000))\n }\n }\n }\n\n // All retries failed\n execution.status = 'failed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n execution.error = lastError?.message\n\n return {\n success: false,\n error: lastError,\n duration: execution.duration,\n }\n }\n\n /**\n * Execute handler with timeout\n */\n private async executeWithTimeout<TInput, TData>(\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n ctx: WorkflowContext<TInput, TData>,\n timeout: number\n ): Promise<void | FluxWaitResult> {\n let timer: ReturnType<typeof setTimeout> | null = null\n try {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Step timeout')), timeout)\n })\n\n return await Promise.race([Promise.resolve(handler(ctx)), timeoutPromise])\n } finally {\n if (timer) {\n clearTimeout(timer)\n }\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n }\n}\n","/**\n * @fileoverview In-memory storage adapter\n *\n * Simple storage for development and testing.\n *\n * @module @gravito/flux/storage\n */\n\nimport type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types'\n\n/**\n * Memory Storage\n *\n * In-memory storage adapter for development and testing.\n * Data is not persisted across restarts.\n */\nexport class MemoryStorage implements WorkflowStorage {\n private store = new Map<string, WorkflowState>()\n\n async save(state: WorkflowState): Promise<void> {\n this.store.set(state.id, {\n ...state,\n updatedAt: new Date(),\n })\n }\n\n async load(id: string): Promise<WorkflowState | null> {\n return this.store.get(id) ?? null\n }\n\n async list(filter?: WorkflowFilter): Promise<WorkflowState[]> {\n let results = Array.from(this.store.values())\n\n if (filter?.name) {\n results = results.filter((s) => s.name === filter.name)\n }\n\n if (filter?.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status]\n results = results.filter((s) => statuses.includes(s.status))\n }\n\n // Sort by createdAt desc\n results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n\n // Apply pagination\n if (filter?.offset) {\n results = results.slice(filter.offset)\n }\n if (filter?.limit) {\n results = results.slice(0, filter.limit)\n }\n\n return results\n }\n\n async delete(id: string): Promise<void> {\n this.store.delete(id)\n }\n\n async init(): Promise<void> {\n // No-op for memory storage\n }\n\n async close(): Promise<void> {\n this.store.clear()\n }\n\n /**\n * Get store size (for testing)\n */\n size(): number {\n return this.store.size\n }\n}\n","/**\n * @fileoverview Flux Engine - Main workflow execution engine\n *\n * Orchestrates workflow execution with storage and event handling.\n *\n * @module @gravito/flux\n */\n\nimport { WorkflowBuilder } from '../builder/WorkflowBuilder'\nimport { ContextManager } from '../core/ContextManager'\nimport { StateMachine } from '../core/StateMachine'\nimport { StepExecutor } from '../core/StepExecutor'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type {\n FluxConfig,\n FluxResult,\n FluxTraceEvent,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowState,\n WorkflowStorage,\n} from '../types'\n\n/**\n * Flux Engine\n *\n * Main workflow execution engine.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({ storage: new MemoryStorage() })\n *\n * const workflow = createWorkflow('process-order')\n * .input<{ orderId: string }>()\n * .step('fetch', async (ctx) => { ... })\n * .step('validate', async (ctx) => { ... })\n * .commit('save', async (ctx) => { ... })\n *\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n */\nexport class FluxEngine {\n private storage: WorkflowStorage\n private executor: StepExecutor\n private contextManager: ContextManager\n private config: FluxConfig\n\n constructor(config: FluxConfig = {}) {\n this.config = config\n this.storage = config.storage ?? new MemoryStorage()\n this.executor = new StepExecutor({\n defaultRetries: config.defaultRetries,\n defaultTimeout: config.defaultTimeout,\n onRetry: async (step, ctx, error, attempt, maxRetries) => {\n await this.emitTrace({\n type: 'step:retry',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: ctx.currentStep,\n commit: Boolean(step.commit),\n retries: attempt,\n maxRetries,\n error: error.message,\n status: 'running',\n })\n },\n })\n this.contextManager = new ContextManager()\n }\n\n /**\n * Execute a workflow with input data\n *\n * @param workflow - Workflow builder or definition\n * @param input - Input data for the workflow\n * @returns Execution result\n */\n async execute<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n input: TInput\n ): Promise<FluxResult<TData>> {\n const startTime = Date.now()\n const definition = this.resolveDefinition(workflow)\n\n // Validate input if validator provided\n if (definition.validateInput && !definition.validateInput(input)) {\n throw new Error(`Invalid input for workflow \"${definition.name}\"`)\n }\n\n // Create context\n const ctx = this.contextManager.create<TInput, TData>(\n definition.name,\n input,\n definition.steps.length\n ) as WorkflowContext<TInput, TData>\n\n // Create state machine\n const stateMachine = new StateMachine()\n\n // Save initial state\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, startTime, 0)\n }\n\n /**\n * Resume a paused or failed workflow\n *\n * @param workflowId - Workflow instance ID\n * @returns Execution result or null if not found\n */\n async resume<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n options?: { fromStep?: number | string }\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; resume is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, options?.fromStep, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n resume: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Send a signal to a suspended workflow\n */\n async signal<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n signalName: string,\n payload?: any\n ): Promise<FluxResult<TData>> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n throw new Error('Workflow not found')\n }\n if (state.status !== 'suspended') {\n throw new Error(`Workflow is not suspended (status: ${state.status})`)\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const currentStep = ctx.history[ctx.currentStep]\n\n if (!currentStep || currentStep.status !== 'suspended') {\n throw new Error('Workflow state invalid: no suspended step found')\n }\n if (currentStep.waitingFor !== signalName) {\n throw new Error(\n `Workflow waiting for signal \"${currentStep.waitingFor}\", received \"${signalName}\"`\n )\n }\n\n // Complete the suspended step\n currentStep.status = 'completed'\n currentStep.completedAt = new Date()\n currentStep.output = payload\n // If payload contains data, we might want to merge it?\n // For now, allow next step to access it via history or we need a cleaner way.\n // Let's assume user grabs it from history for now or we build a helper later.\n\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('suspended')\n // ctx status will be updated to 'running' in runFrom\n\n await this.emitTrace({\n type: 'signal:received',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'suspended',\n input: payload,\n })\n\n // Resume from NEXT step\n const nextStepIndex = ctx.currentStep + 1\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), nextStepIndex, {\n resume: true,\n fromStep: nextStepIndex,\n })\n }\n\n /**\n * Retry a specific step (replays from that step onward)\n */\n async retryStep<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n stepName: string\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; retry is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, stepName, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n retry: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Get workflow state by ID\n */\n async get<TInput = any, TData = any>(\n workflowId: string\n ): Promise<WorkflowState<TInput, TData> | null> {\n return this.storage.load(workflowId) as Promise<WorkflowState<TInput, TData> | null>\n }\n\n /**\n * Save workflow state manually (e.g., for external updates)\n */\n async saveState<TInput, TData>(state: WorkflowState<TInput, TData>): Promise<void> {\n return this.storage.save(state)\n }\n\n /**\n * List workflows\n */\n async list(filter?: Parameters<WorkflowStorage['list']>[0]) {\n return this.storage.list(filter)\n }\n\n /**\n * Initialize engine (init storage)\n */\n async init(): Promise<void> {\n await this.storage.init?.()\n }\n\n /**\n * Shutdown engine (cleanup)\n */\n async close(): Promise<void> {\n await this.storage.close?.()\n }\n\n private resolveDefinition<TInput, TData>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>\n ): WorkflowDefinition<TInput, TData> {\n return workflow instanceof WorkflowBuilder ? workflow.build() : workflow\n }\n\n private resolveStartIndex<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n fromStep: number | string | undefined,\n fallback: number\n ): number {\n if (typeof fromStep === 'number') {\n if (fromStep < 0 || fromStep >= definition.steps.length) {\n throw new Error(`Invalid step index: ${fromStep}`)\n }\n return fromStep\n }\n if (typeof fromStep === 'string') {\n const index = definition.steps.findIndex((step) => step.name === fromStep)\n if (index === -1) {\n throw new Error(`Step not found: ${fromStep}`)\n }\n return index\n }\n return Math.max(0, Math.min(fallback, definition.steps.length - 1))\n }\n\n private resetHistoryFrom<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n startIndex: number\n ): void {\n for (let i = startIndex; i < ctx.history.length; i++) {\n const entry = ctx.history[i]\n if (!entry) {\n continue\n }\n entry.status = 'pending'\n entry.startedAt = undefined\n entry.completedAt = undefined\n entry.duration = undefined\n entry.error = undefined\n entry.retries = 0\n }\n }\n\n /**\n * Rollback workflow by executing compensation handlers in reverse order\n */\n private async rollback<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n failedAtIndex: number,\n originalError: Error\n ): Promise<void> {\n Object.assign(ctx, { status: 'rolling_back' })\n\n await this.emitTrace({\n type: 'workflow:rollback_start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolling_back',\n error: originalError.message,\n })\n\n let compensatedCount = 0\n\n // Iterate backwards from the step BEFORE the failed one\n for (let i = failedAtIndex - 1; i >= 0; i--) {\n const step = definition.steps[i]\n const execution = ctx.history[i]\n\n // Only compensate completed steps with compensation handler\n if (!step || !step.compensate || !execution || execution.status !== 'completed') {\n continue\n }\n\n try {\n execution.status = 'compensating'\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n await step.compensate(ctx)\n\n execution.status = 'compensated'\n execution.compensatedAt = new Date()\n compensatedCount++\n\n await this.emitTrace({\n type: 'step:compensate',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n status: 'compensated',\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n // Compensation failed - this is bad. Mark workflow as failed (not rolled_back)\n Object.assign(ctx, { status: 'failed' })\n\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n error: `Compensation failed at step \"${step.name}\": ${error.message}`,\n })\n return // Stop rollback\n }\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n if (compensatedCount > 0) {\n Object.assign(ctx, { status: 'rolled_back' })\n await this.emitTrace({\n type: 'workflow:rollback_complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolled_back',\n })\n } else {\n // No compensation occurred, revert to failed status\n Object.assign(ctx, { status: 'failed' })\n }\n }\n\n private async runFrom<TInput, TData = any>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n stateMachine: StateMachine,\n startTime: number,\n startIndex: number,\n meta?: { resume?: boolean; retry?: boolean; fromStep?: number }\n ): Promise<FluxResult<TData>> {\n try {\n // Transition to running\n stateMachine.transition('running')\n Object.assign(ctx, { status: 'running' })\n if (!meta?.resume) {\n await this.emitTrace({\n type: 'workflow:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n input: ctx.input,\n meta,\n })\n }\n\n // Execute steps\n for (let i = startIndex; i < definition.steps.length; i++) {\n const step = definition.steps[i]!\n const execution = ctx.history[i]!\n\n // Update step name\n this.contextManager.setStepName(ctx, i, step.name)\n Object.assign(ctx, { currentStep: i })\n\n // Emit step start event\n this.config.on?.stepStart?.(step.name, ctx as any)\n await this.emitTrace({\n type: 'step:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n status: execution.status,\n meta,\n })\n\n // Execute step\n const result = await this.executor.execute(step, ctx, execution)\n\n if (result.success) {\n if (result.suspended) {\n // Handle suspension\n stateMachine.transition('suspended')\n Object.assign(ctx, { status: 'suspended' })\n\n await this.emitTrace({\n type: 'step:suspend',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n meta: { signal: result.waitingFor },\n })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return {\n id: ctx.id,\n status: 'suspended',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n }\n\n // Emit step complete event\n this.config.on?.stepComplete?.(step.name, ctx as any, result)\n if (execution.status === 'skipped') {\n await this.emitTrace({\n type: 'step:skipped',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n } else {\n await this.emitTrace({\n type: 'step:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n }\n } else {\n // Emit step error event\n this.config.on?.stepError?.(step.name, ctx as any, result.error!)\n await this.emitTrace({\n type: 'step:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n error: result.error?.message,\n status: execution.status,\n meta,\n })\n\n // Fail workflow with potential rollback\n await this.rollback<TInput, TData>(definition, ctx, i, result.error!)\n\n const finalStatus = ctx.status\n stateMachine.forceStatus(finalStatus)\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: result.error?.message,\n })\n\n return {\n id: ctx.id,\n status: finalStatus,\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: result.error,\n }\n }\n\n // Save progress after each step\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n // Complete workflow\n stateMachine.transition('completed')\n Object.assign(ctx, { status: 'completed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n completedAt: new Date(),\n })\n\n // Emit workflow complete event\n this.config.on?.workflowComplete?.(ctx as any)\n await this.emitTrace({\n type: 'workflow:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n duration: Date.now() - startTime,\n data: ctx.data as Record<string, unknown>,\n meta,\n })\n\n return {\n id: ctx.id,\n status: 'completed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n\n // Emit workflow error event\n this.config.on?.workflowError?.(ctx as any, err)\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n duration: Date.now() - startTime,\n error: err.message,\n meta,\n })\n\n stateMachine.forceStatus('failed')\n Object.assign(ctx, { status: 'failed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: err.message,\n })\n\n return {\n id: ctx.id,\n status: 'failed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: err,\n }\n }\n }\n\n private async emitTrace(event: FluxTraceEvent): Promise<void> {\n try {\n await this.config.trace?.emit(event)\n } catch {\n // Ignore trace failures to avoid breaking workflow execution\n }\n }\n}\n","/**\n * @fileoverview JSON file trace sink (NDJSON)\n *\n * Writes trace events to a newline-delimited JSON file.\n */\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { FluxTraceEvent, FluxTraceSink } from '../types'\n\nexport interface JsonFileTraceSinkOptions {\n path: string\n reset?: boolean\n}\n\nexport class JsonFileTraceSink implements FluxTraceSink {\n private path: string\n private ready: Promise<void>\n\n constructor(options: JsonFileTraceSinkOptions) {\n this.path = options.path\n this.ready = this.init(options.reset ?? true)\n }\n\n private async init(reset: boolean): Promise<void> {\n await mkdir(dirname(this.path), { recursive: true })\n if (reset) {\n await writeFile(this.path, '', 'utf8')\n }\n }\n\n async emit(event: FluxTraceEvent): Promise<void> {\n await this.ready\n await appendFile(this.path, `${JSON.stringify(event)}\\n`, 'utf8')\n }\n}\n","/**\n * @fileoverview Console Logger for FluxEngine\n *\n * Default logger implementation using console.\n *\n * @module @gravito/flux\n */\n\nimport type { FluxLogger } from '../types'\n\n/**\n * Console Logger\n *\n * Default logger that outputs to console.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({\n * logger: new FluxConsoleLogger()\n * })\n * ```\n */\nexport class FluxConsoleLogger implements FluxLogger {\n private prefix: string\n\n constructor(prefix = '[Flux]') {\n this.prefix = prefix\n }\n\n debug(message: string, ...args: unknown[]): void {\n console.debug(`${this.prefix} ${message}`, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n console.info(`${this.prefix} ${message}`, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n console.warn(`${this.prefix} ${message}`, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n console.error(`${this.prefix} ${message}`, ...args)\n }\n}\n\n/**\n * Silent Logger\n *\n * Logger that outputs nothing (for testing or production).\n */\nexport class FluxSilentLogger implements FluxLogger {\n debug(): void {}\n info(): void {}\n warn(): void {}\n error(): void {}\n}\n","/**\n * @fileoverview OrbitFlux - Gravito PlanetCore Integration\n *\n * Integrates FluxEngine with Gravito's PlanetCore for seamless workflow management.\n *\n * @module @gravito/flux\n */\n\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { BunSQLiteStorage } from '../storage/BunSQLiteStorage'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type { FluxConfig, FluxLogger, WorkflowStorage } from '../types'\n\n/**\n * Minimal PlanetCore interface for type compatibility\n * (Avoids importing @gravito/core sources which causes rootDir issues)\n */\ninterface PlanetCore {\n logger: {\n debug(message: string, ...args: unknown[]): void\n info(message: string, ...args: unknown[]): void\n warn(message: string, ...args: unknown[]): void\n error(message: string, ...args: unknown[]): void\n }\n services: {\n set(key: string, value: unknown): void\n get<T>(key: string): T | undefined\n }\n hooks: {\n doAction(name: string, payload?: unknown): void\n }\n}\n\n/**\n * GravitoOrbit interface\n */\nexport interface GravitoOrbit {\n install(core: PlanetCore): void | Promise<void>\n}\n\n/**\n * OrbitFlux configuration options\n */\nexport interface OrbitFluxOptions {\n /**\n * Storage driver: 'memory' | 'sqlite' | custom WorkflowStorage\n * @default 'memory'\n */\n storage?: 'memory' | 'sqlite' | WorkflowStorage\n\n /**\n * SQLite database path (only used if storage is 'sqlite')\n * @default ':memory:'\n */\n dbPath?: string\n\n /**\n * Service name in core.services\n * @default 'flux'\n */\n exposeAs?: string\n\n /**\n * Custom logger\n */\n logger?: FluxLogger\n\n /**\n * Default retry count for steps\n * @default 3\n */\n defaultRetries?: number\n\n /**\n * Default timeout for steps (ms)\n * @default 30000\n */\n defaultTimeout?: number\n}\n\n/**\n * OrbitFlux - Gravito Workflow Integration\n *\n * @example\n * ```typescript\n * import { OrbitFlux } from '@gravito/flux'\n *\n * const core = await PlanetCore.boot({\n * orbits: [\n * new OrbitFlux({ storage: 'sqlite', dbPath: './data/workflows.db' })\n * ]\n * })\n *\n * // Access via services\n * const flux = core.services.get<FluxEngine>('flux')\n * await flux.execute(myWorkflow, input)\n * ```\n */\nexport class OrbitFlux implements GravitoOrbit {\n private options: OrbitFluxOptions\n private engine?: FluxEngine\n\n constructor(options: OrbitFluxOptions = {}) {\n this.options = {\n storage: 'memory',\n exposeAs: 'flux',\n defaultRetries: 3,\n defaultTimeout: 30000,\n ...options,\n }\n }\n\n /**\n * Create OrbitFlux with configuration\n */\n static configure(options: OrbitFluxOptions = {}): OrbitFlux {\n return new OrbitFlux(options)\n }\n\n /**\n * Install into PlanetCore\n *\n * @param core - The PlanetCore instance\n */\n async install(core: PlanetCore): Promise<void> {\n const { storage, dbPath, exposeAs, defaultRetries, defaultTimeout, logger } = this.options\n\n // Resolve storage adapter\n let storageAdapter: WorkflowStorage\n\n if (typeof storage === 'string') {\n switch (storage) {\n case 'sqlite':\n storageAdapter = new BunSQLiteStorage({ path: dbPath })\n break\n default:\n storageAdapter = new MemoryStorage()\n }\n } else {\n storageAdapter = storage!\n }\n\n // Initialize storage\n await storageAdapter.init?.()\n\n // Create engine configuration\n const engineConfig: FluxConfig = {\n storage: storageAdapter,\n defaultRetries,\n defaultTimeout,\n logger: logger ?? {\n debug: (msg) => core.logger.debug(`[Flux] ${msg}`),\n info: (msg) => core.logger.info(`[Flux] ${msg}`),\n warn: (msg) => core.logger.warn(`[Flux] ${msg}`),\n error: (msg) => core.logger.error(`[Flux] ${msg}`),\n },\n on: {\n stepStart: (step) => {\n core.hooks.doAction('flux:step:start', { step })\n },\n stepComplete: (step, ctx, result) => {\n core.hooks.doAction('flux:step:complete', { step, ctx, result })\n },\n stepError: (step, ctx, error) => {\n core.hooks.doAction('flux:step:error', { step, ctx, error })\n },\n workflowComplete: (ctx) => {\n core.hooks.doAction('flux:workflow:complete', { ctx })\n },\n workflowError: (ctx, error) => {\n core.hooks.doAction('flux:workflow:error', { ctx, error })\n },\n },\n }\n\n // Create engine\n this.engine = new FluxEngine(engineConfig)\n\n // Register in core services\n core.services.set(exposeAs!, this.engine)\n\n core.logger.info(\n `[OrbitFlux] Initialized (Storage: ${typeof storage === 'string' ? storage : 'custom'})`\n )\n }\n\n /**\n * Get the FluxEngine instance\n */\n getEngine(): FluxEngine | undefined {\n return this.engine\n }\n}\n"]}
package/dist/index.cjs CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- var _chunkBGLG7HACcjs = require('./chunk-BGLG7HAC.cjs');
13
+ var _chunkX3NC7HS4cjs = require('./chunk-X3NC7HS4.cjs');
14
14
 
15
15
 
16
16
  var _chunkSJSPR4ZUcjs = require('./chunk-SJSPR4ZU.cjs');
@@ -21,8 +21,8 @@ var WorkflowProfiler = class {
21
21
  constructor(engine) {
22
22
  this.engine = engine;
23
23
  if (!this.engine) {
24
- this.engine = new (0, _chunkBGLG7HACcjs.FluxEngine)({
25
- logger: new (0, _chunkBGLG7HACcjs.FluxSilentLogger)()
24
+ this.engine = new (0, _chunkX3NC7HS4cjs.FluxEngine)({
25
+ logger: new (0, _chunkX3NC7HS4cjs.FluxSilentLogger)()
26
26
  });
27
27
  }
28
28
  }
@@ -131,5 +131,5 @@ var Flux = {
131
131
 
132
132
 
133
133
 
134
- exports.BunSQLiteStorage = _chunkSJSPR4ZUcjs.BunSQLiteStorage; exports.ContextManager = _chunkBGLG7HACcjs.ContextManager; exports.Flux = Flux; exports.FluxConsoleLogger = _chunkBGLG7HACcjs.FluxConsoleLogger; exports.FluxEngine = _chunkBGLG7HACcjs.FluxEngine; exports.FluxSilentLogger = _chunkBGLG7HACcjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkBGLG7HACcjs.JsonFileTraceSink; exports.MemoryStorage = _chunkBGLG7HACcjs.MemoryStorage; exports.OrbitFlux = _chunkBGLG7HACcjs.OrbitFlux; exports.StateMachine = _chunkBGLG7HACcjs.StateMachine; exports.StepExecutor = _chunkBGLG7HACcjs.StepExecutor; exports.WorkflowBuilder = _chunkBGLG7HACcjs.WorkflowBuilder; exports.WorkflowProfiler = WorkflowProfiler; exports.createWorkflow = _chunkBGLG7HACcjs.createWorkflow;
134
+ exports.BunSQLiteStorage = _chunkSJSPR4ZUcjs.BunSQLiteStorage; exports.ContextManager = _chunkX3NC7HS4cjs.ContextManager; exports.Flux = Flux; exports.FluxConsoleLogger = _chunkX3NC7HS4cjs.FluxConsoleLogger; exports.FluxEngine = _chunkX3NC7HS4cjs.FluxEngine; exports.FluxSilentLogger = _chunkX3NC7HS4cjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkX3NC7HS4cjs.JsonFileTraceSink; exports.MemoryStorage = _chunkX3NC7HS4cjs.MemoryStorage; exports.OrbitFlux = _chunkX3NC7HS4cjs.OrbitFlux; exports.StateMachine = _chunkX3NC7HS4cjs.StateMachine; exports.StepExecutor = _chunkX3NC7HS4cjs.StepExecutor; exports.WorkflowBuilder = _chunkX3NC7HS4cjs.WorkflowBuilder; exports.WorkflowProfiler = WorkflowProfiler; exports.createWorkflow = _chunkX3NC7HS4cjs.createWorkflow;
135
135
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ import {
10
10
  StepExecutor,
11
11
  WorkflowBuilder,
12
12
  createWorkflow
13
- } from "./chunk-CICUXW2L.js";
13
+ } from "./chunk-LULCFPIK.js";
14
14
  import {
15
15
  BunSQLiteStorage
16
16
  } from "./chunk-ZAMVC732.js";
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- var _chunkBGLG7HACcjs = require('./chunk-BGLG7HAC.cjs');
13
+ var _chunkX3NC7HS4cjs = require('./chunk-X3NC7HS4.cjs');
14
14
  require('./chunk-SJSPR4ZU.cjs');
15
15
 
16
16
 
@@ -24,5 +24,5 @@ require('./chunk-SJSPR4ZU.cjs');
24
24
 
25
25
 
26
26
 
27
- exports.ContextManager = _chunkBGLG7HACcjs.ContextManager; exports.FluxConsoleLogger = _chunkBGLG7HACcjs.FluxConsoleLogger; exports.FluxEngine = _chunkBGLG7HACcjs.FluxEngine; exports.FluxSilentLogger = _chunkBGLG7HACcjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkBGLG7HACcjs.JsonFileTraceSink; exports.MemoryStorage = _chunkBGLG7HACcjs.MemoryStorage; exports.OrbitFlux = _chunkBGLG7HACcjs.OrbitFlux; exports.StateMachine = _chunkBGLG7HACcjs.StateMachine; exports.StepExecutor = _chunkBGLG7HACcjs.StepExecutor; exports.WorkflowBuilder = _chunkBGLG7HACcjs.WorkflowBuilder; exports.createWorkflow = _chunkBGLG7HACcjs.createWorkflow;
27
+ exports.ContextManager = _chunkX3NC7HS4cjs.ContextManager; exports.FluxConsoleLogger = _chunkX3NC7HS4cjs.FluxConsoleLogger; exports.FluxEngine = _chunkX3NC7HS4cjs.FluxEngine; exports.FluxSilentLogger = _chunkX3NC7HS4cjs.FluxSilentLogger; exports.JsonFileTraceSink = _chunkX3NC7HS4cjs.JsonFileTraceSink; exports.MemoryStorage = _chunkX3NC7HS4cjs.MemoryStorage; exports.OrbitFlux = _chunkX3NC7HS4cjs.OrbitFlux; exports.StateMachine = _chunkX3NC7HS4cjs.StateMachine; exports.StepExecutor = _chunkX3NC7HS4cjs.StepExecutor; exports.WorkflowBuilder = _chunkX3NC7HS4cjs.WorkflowBuilder; exports.createWorkflow = _chunkX3NC7HS4cjs.createWorkflow;
28
28
  //# sourceMappingURL=index.node.cjs.map
@@ -10,7 +10,7 @@ import {
10
10
  StepExecutor,
11
11
  WorkflowBuilder,
12
12
  createWorkflow
13
- } from "./chunk-CICUXW2L.js";
13
+ } from "./chunk-LULCFPIK.js";
14
14
  import "./chunk-ZAMVC732.js";
15
15
  export {
16
16
  ContextManager,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gravito/flux",
3
- "version": "1.0.0-beta.6",
3
+ "version": "1.0.0-beta.7",
4
4
  "description": "Platform-agnostic workflow engine for Gravito",
5
5
  "type": "module",
6
6
  "main": "./dist/index.node.cjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-BGLG7HAC.cjs","../src/builder/WorkflowBuilder.ts","../src/core/ContextManager.ts","../src/core/StateMachine.ts","../src/core/StepExecutor.ts","../src/storage/MemoryStorage.ts","../src/engine/FluxEngine.ts","../src/trace/JsonFileTraceSink.ts","../src/logger/FluxLogger.ts","../src/orbit/OrbitFlux.ts"],"names":[],"mappings":"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","file":"/Users/carl/Dev/Carl/gravito-core/packages/flux/dist/chunk-BGLG7HAC.cjs","sourcesContent":[null,"/**\n * @fileoverview Workflow Builder - Fluent API for defining workflows\n *\n * Type-safe, chainable workflow definition.\n *\n * @module @gravito/flux/builder\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepDescriptor,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n} from '../types'\n\n/**\n * Step options\n */\ninterface StepOptions<TInput = any, TData = any> {\n retries?: number\n timeout?: number\n when?: (ctx: WorkflowContext<TInput, TData>) => boolean\n compensate?: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void\n}\n\n/**\n * Workflow Builder\n *\n * Provides fluent API for defining workflows with type inference.\n *\n * @example\n * ```typescript\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processOrder(ctx.data.order)\n * }, {\n * compensate: async (ctx) => {\n * await cancelOrder(ctx.data.order.id)\n * }\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n * ```\n */\nexport class WorkflowBuilder<TInput = unknown, TData = Record<string, unknown>> {\n private _name: string\n private _steps: StepDefinition[] = []\n private _validateInput?: (input: unknown) => input is TInput\n\n constructor(name: string) {\n this._name = name\n }\n\n /**\n * Define input type\n *\n * This method is used for TypeScript type inference.\n */\n input<T>(): WorkflowBuilder<T, TData> {\n return this as unknown as WorkflowBuilder<T, TData>\n }\n\n /**\n * Define workflow data (state) type\n *\n * This method is used for TypeScript type inference.\n */\n data<T>(): WorkflowBuilder<TInput, T> {\n return this as unknown as WorkflowBuilder<TInput, T>\n }\n\n /**\n * Add input validator\n */\n validate(validator: (input: unknown) => input is TInput): this {\n this._validateInput = validator\n return this\n }\n\n /**\n * Add a step to the workflow\n */\n step(\n name: string,\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n options?: StepOptions<TInput, TData>\n ): this {\n this._steps.push({\n name,\n handler: handler as (\n ctx: WorkflowContext\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n compensate: options?.compensate as\n | ((ctx: WorkflowContext) => Promise<void> | void)\n | undefined,\n commit: false,\n })\n return this\n }\n\n /**\n * Add a commit step (always executes, even on replay)\n *\n * Commit steps are for side effects that should not be skipped,\n * such as database writes or external API calls.\n */\n commit(\n name: string,\n handler: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void,\n options?: Omit<StepOptions<TInput, TData>, 'compensate'>\n ): this {\n this._steps.push({\n name,\n handler: handler as (ctx: WorkflowContext) => Promise<void> | void,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n commit: true,\n })\n return this\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDefinition<TInput, TData> {\n if (this._steps.length === 0) {\n throw new Error(`Workflow \"${this._name}\" has no steps`)\n }\n\n return {\n name: this._name,\n steps: [...this._steps],\n validateInput: this._validateInput,\n }\n }\n\n /**\n * Describe workflow (serializable metadata)\n */\n describe(): WorkflowDescriptor {\n const steps: StepDescriptor[] = this._steps.map((step) => ({\n name: step.name,\n commit: Boolean(step.commit),\n retries: step.retries,\n timeout: step.timeout,\n hasCondition: Boolean(step.when),\n }))\n\n return {\n name: this._name,\n steps,\n }\n }\n\n /**\n * Get workflow name\n */\n get name(): string {\n return this._name\n }\n\n /**\n * Get step count\n */\n get stepCount(): number {\n return this._steps.length\n }\n}\n\n/**\n * Create a new workflow builder\n *\n * @param name - Unique workflow name\n * @returns WorkflowBuilder instance\n *\n * @example\n * ```typescript\n * const uploadFlow = createWorkflow('image-upload')\n * .input<{ file: Buffer }>()\n * .step('resize', async (ctx) => {\n * ctx.data.resized = await sharp(ctx.input.file).resize(200).toBuffer()\n * })\n * .commit('save', async (ctx) => {\n * await storage.put(ctx.data.resized)\n * })\n * ```\n */\nexport function createWorkflow(name: string): WorkflowBuilder {\n return new WorkflowBuilder(name)\n}\n","/**\n * @fileoverview Context Manager for workflow execution\n *\n * Manages workflow context lifecycle and state snapshots.\n *\n * @module @gravito/flux/core\n */\n\nimport type { StepExecution, WorkflowContext, WorkflowState, WorkflowStatus } from '../types'\n\n/**\n * Generate unique ID using crypto.randomUUID (Web Standard)\n */\nfunction generateId(): string {\n return crypto.randomUUID()\n}\n\n/**\n * Context Manager\n *\n * Creates and manages workflow execution contexts.\n */\nexport class ContextManager {\n /**\n * Create a new workflow context\n */\n create<TInput, TData = any>(\n name: string,\n input: TInput,\n stepCount: number\n ): WorkflowContext<TInput, TData> {\n const history: StepExecution[] = Array.from({ length: stepCount }, (_, _i) => ({\n name: '',\n status: 'pending',\n retries: 0,\n }))\n\n return {\n id: generateId(),\n name,\n input,\n data: {} as TData,\n status: 'pending',\n currentStep: 0,\n history,\n }\n }\n\n /**\n * Restore context from saved state\n */\n restore<TInput, TData = any>(\n state: WorkflowState<TInput, TData>\n ): WorkflowContext<TInput, TData> {\n return {\n id: state.id,\n name: state.name,\n input: state.input as TInput,\n data: { ...state.data } as unknown as TData,\n status: state.status,\n currentStep: state.currentStep,\n history: state.history.map((h) => ({ ...h })),\n }\n }\n\n /**\n * Convert context to serializable state\n */\n toState<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowState<TInput, TData> {\n return {\n id: ctx.id,\n name: ctx.name,\n status: ctx.status,\n input: ctx.input,\n data: { ...(ctx.data as any) },\n currentStep: ctx.currentStep,\n history: ctx.history.map((h) => ({ ...h })),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n }\n\n /**\n * Update context status (returns new context for immutability)\n */\n updateStatus<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n status: WorkflowStatus\n ): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n status,\n }\n }\n\n /**\n * Advance to next step\n */\n advanceStep<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n currentStep: ctx.currentStep + 1,\n }\n }\n\n /**\n * Update step name in history\n */\n setStepName<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n index: number,\n name: string\n ): void {\n if (ctx.history[index]) {\n ctx.history[index].name = name\n }\n }\n}\n","/**\n * @fileoverview State Machine for workflow status transitions\n *\n * Pure state machine with no runtime dependencies.\n *\n * @module @gravito/flux/core\n */\n\nimport type { WorkflowStatus } from '../types'\n\n/**\n * Valid state transitions\n */\nconst TRANSITIONS: Record<WorkflowStatus, WorkflowStatus[]> = {\n pending: ['running', 'failed'],\n running: ['paused', 'completed', 'failed', 'suspended', 'rolling_back'],\n paused: ['running', 'failed'],\n suspended: ['running', 'failed'],\n rolling_back: ['rolled_back', 'failed'],\n rolled_back: ['pending'], // allow retry from scratch\n completed: [], // terminal state\n failed: ['pending'], // allow retry\n}\n\n/**\n * State Machine for workflow status management\n *\n * Provides validated state transitions using EventTarget for events.\n */\nexport class StateMachine extends EventTarget {\n private _status: WorkflowStatus = 'pending'\n\n /**\n * Current status\n */\n get status(): WorkflowStatus {\n return this._status\n }\n\n /**\n * Check if transition to target status is allowed\n */\n canTransition(to: WorkflowStatus): boolean {\n return TRANSITIONS[this._status].includes(to)\n }\n\n /**\n * Transition to a new status\n *\n * @throws {Error} If transition is not allowed\n */\n transition(to: WorkflowStatus): void {\n if (!this.canTransition(to)) {\n throw new Error(`Invalid state transition: ${this._status} → ${to}`)\n }\n\n const from = this._status\n this._status = to\n\n // Emit transition event\n this.dispatchEvent(\n new CustomEvent('transition', {\n detail: { from, to },\n })\n )\n }\n\n /**\n * Force set status (for replay/restore)\n */\n forceStatus(status: WorkflowStatus): void {\n this._status = status\n }\n\n /**\n * Check if workflow is in terminal state\n */\n isTerminal(): boolean {\n return (\n this._status === 'completed' || this._status === 'failed' || this._status === 'rolled_back'\n )\n }\n\n /**\n * Check if workflow can be executed\n */\n canExecute(): boolean {\n return this._status === 'pending' || this._status === 'paused'\n }\n}\n","/**\n * @fileoverview Step Executor for workflow steps\n *\n * Handles step execution with retry and timeout support.\n *\n * @module @gravito/flux/core\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepExecution,\n StepResult,\n WorkflowContext,\n} from '../types'\n\n/**\n * Step Executor\n *\n * Executes individual workflow steps with retry and timeout support.\n */\nexport class StepExecutor {\n private defaultRetries: number\n private defaultTimeout: number\n private onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n\n constructor(\n options: {\n defaultRetries?: number\n defaultTimeout?: number\n onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n } = {}\n ) {\n this.defaultRetries = options.defaultRetries ?? 3\n this.defaultTimeout = options.defaultTimeout ?? 30000\n this.onRetry = options.onRetry\n }\n\n /**\n * Execute a step with retry and timeout\n */\n async execute<TInput, TData>(\n step: StepDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n execution: StepExecution\n ): Promise<StepResult> {\n const maxRetries = step.retries ?? this.defaultRetries\n const timeout = step.timeout ?? this.defaultTimeout\n const startTime = Date.now()\n\n // Check condition\n if (step.when && !step.when(ctx)) {\n execution.status = 'skipped'\n return {\n success: true,\n duration: 0,\n }\n }\n\n execution.status = 'running'\n execution.startedAt = new Date()\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n execution.retries = attempt\n\n try {\n // Execute with timeout\n const result = await this.executeWithTimeout(step.handler, ctx, timeout)\n\n if (\n result &&\n typeof result === 'object' &&\n '__kind' in result &&\n result.__kind === 'flux_wait'\n ) {\n execution.status = 'suspended'\n execution.waitingFor = result.signal\n execution.suspendedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n suspended: true,\n waitingFor: result.signal,\n duration: execution.duration,\n }\n }\n\n execution.status = 'completed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n duration: execution.duration,\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // If not last retry, continue\n if (attempt < maxRetries) {\n await this.onRetry?.(step, ctx, lastError, attempt + 1, maxRetries)\n // Exponential backoff\n await this.sleep(Math.min(1000 * 2 ** attempt, 10000))\n }\n }\n }\n\n // All retries failed\n execution.status = 'failed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n execution.error = lastError?.message\n\n return {\n success: false,\n error: lastError,\n duration: execution.duration,\n }\n }\n\n /**\n * Execute handler with timeout\n */\n private async executeWithTimeout<TInput, TData>(\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n ctx: WorkflowContext<TInput, TData>,\n timeout: number\n ): Promise<void | FluxWaitResult> {\n let timer: ReturnType<typeof setTimeout> | null = null\n try {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Step timeout')), timeout)\n })\n\n return await Promise.race([Promise.resolve(handler(ctx)), timeoutPromise])\n } finally {\n if (timer) {\n clearTimeout(timer)\n }\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n }\n}\n","/**\n * @fileoverview In-memory storage adapter\n *\n * Simple storage for development and testing.\n *\n * @module @gravito/flux/storage\n */\n\nimport type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types'\n\n/**\n * Memory Storage\n *\n * In-memory storage adapter for development and testing.\n * Data is not persisted across restarts.\n */\nexport class MemoryStorage implements WorkflowStorage {\n private store = new Map<string, WorkflowState>()\n\n async save(state: WorkflowState): Promise<void> {\n this.store.set(state.id, {\n ...state,\n updatedAt: new Date(),\n })\n }\n\n async load(id: string): Promise<WorkflowState | null> {\n return this.store.get(id) ?? null\n }\n\n async list(filter?: WorkflowFilter): Promise<WorkflowState[]> {\n let results = Array.from(this.store.values())\n\n if (filter?.name) {\n results = results.filter((s) => s.name === filter.name)\n }\n\n if (filter?.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status]\n results = results.filter((s) => statuses.includes(s.status))\n }\n\n // Sort by createdAt desc\n results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n\n // Apply pagination\n if (filter?.offset) {\n results = results.slice(filter.offset)\n }\n if (filter?.limit) {\n results = results.slice(0, filter.limit)\n }\n\n return results\n }\n\n async delete(id: string): Promise<void> {\n this.store.delete(id)\n }\n\n async init(): Promise<void> {\n // No-op for memory storage\n }\n\n async close(): Promise<void> {\n this.store.clear()\n }\n\n /**\n * Get store size (for testing)\n */\n size(): number {\n return this.store.size\n }\n}\n","/**\n * @fileoverview Flux Engine - Main workflow execution engine\n *\n * Orchestrates workflow execution with storage and event handling.\n *\n * @module @gravito/flux\n */\n\nimport { WorkflowBuilder } from '../builder/WorkflowBuilder'\nimport { ContextManager } from '../core/ContextManager'\nimport { StateMachine } from '../core/StateMachine'\nimport { StepExecutor } from '../core/StepExecutor'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type {\n FluxConfig,\n FluxResult,\n FluxTraceEvent,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowState,\n WorkflowStorage,\n} from '../types'\n\n/**\n * Flux Engine\n *\n * Main workflow execution engine.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({ storage: new MemoryStorage() })\n *\n * const workflow = createWorkflow('process-order')\n * .input<{ orderId: string }>()\n * .step('fetch', async (ctx) => { ... })\n * .step('validate', async (ctx) => { ... })\n * .commit('save', async (ctx) => { ... })\n *\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n */\nexport class FluxEngine {\n private storage: WorkflowStorage\n private executor: StepExecutor\n private contextManager: ContextManager\n private config: FluxConfig\n\n constructor(config: FluxConfig = {}) {\n this.config = config\n this.storage = config.storage ?? new MemoryStorage()\n this.executor = new StepExecutor({\n defaultRetries: config.defaultRetries,\n defaultTimeout: config.defaultTimeout,\n onRetry: async (step, ctx, error, attempt, maxRetries) => {\n await this.emitTrace({\n type: 'step:retry',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: ctx.currentStep,\n commit: Boolean(step.commit),\n retries: attempt,\n maxRetries,\n error: error.message,\n status: 'running',\n })\n },\n })\n this.contextManager = new ContextManager()\n }\n\n /**\n * Execute a workflow with input data\n *\n * @param workflow - Workflow builder or definition\n * @param input - Input data for the workflow\n * @returns Execution result\n */\n async execute<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n input: TInput\n ): Promise<FluxResult<TData>> {\n const startTime = Date.now()\n const definition = this.resolveDefinition(workflow)\n\n // Validate input if validator provided\n if (definition.validateInput && !definition.validateInput(input)) {\n throw new Error(`Invalid input for workflow \"${definition.name}\"`)\n }\n\n // Create context\n const ctx = this.contextManager.create<TInput, TData>(\n definition.name,\n input,\n definition.steps.length\n ) as WorkflowContext<TInput, TData>\n\n // Create state machine\n const stateMachine = new StateMachine()\n\n // Save initial state\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, startTime, 0)\n }\n\n /**\n * Resume a paused or failed workflow\n *\n * @param workflowId - Workflow instance ID\n * @returns Execution result or null if not found\n */\n async resume<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n options?: { fromStep?: number | string }\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; resume is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, options?.fromStep, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n resume: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Send a signal to a suspended workflow\n */\n async signal<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n signalName: string,\n payload?: any\n ): Promise<FluxResult<TData>> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n throw new Error('Workflow not found')\n }\n if (state.status !== 'suspended') {\n throw new Error(`Workflow is not suspended (status: ${state.status})`)\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const currentStep = ctx.history[ctx.currentStep]\n\n if (!currentStep || currentStep.status !== 'suspended') {\n throw new Error('Workflow state invalid: no suspended step found')\n }\n if (currentStep.waitingFor !== signalName) {\n throw new Error(\n `Workflow waiting for signal \"${currentStep.waitingFor}\", received \"${signalName}\"`\n )\n }\n\n // Complete the suspended step\n currentStep.status = 'completed'\n currentStep.completedAt = new Date()\n currentStep.output = payload\n // If payload contains data, we might want to merge it?\n // For now, allow next step to access it via history or we need a cleaner way.\n // Let's assume user grabs it from history for now or we build a helper later.\n\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('suspended')\n // ctx status will be updated to 'running' in runFrom\n\n await this.emitTrace({\n type: 'signal:received',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'suspended',\n input: payload,\n })\n\n // Resume from NEXT step\n const nextStepIndex = ctx.currentStep + 1\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), nextStepIndex, {\n resume: true,\n fromStep: nextStepIndex,\n })\n }\n\n /**\n * Retry a specific step (replays from that step onward)\n */\n async retryStep<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n stepName: string\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; retry is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, stepName, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n retry: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Get workflow state by ID\n */\n async get<TInput = any, TData = any>(\n workflowId: string\n ): Promise<WorkflowState<TInput, TData> | null> {\n return this.storage.load(workflowId) as Promise<WorkflowState<TInput, TData> | null>\n }\n\n /**\n * Save workflow state manually (e.g., for external updates)\n */\n async saveState<TInput, TData>(state: WorkflowState<TInput, TData>): Promise<void> {\n return this.storage.save(state)\n }\n\n /**\n * List workflows\n */\n async list(filter?: Parameters<WorkflowStorage['list']>[0]) {\n return this.storage.list(filter)\n }\n\n /**\n * Initialize engine (init storage)\n */\n async init(): Promise<void> {\n await this.storage.init?.()\n }\n\n /**\n * Shutdown engine (cleanup)\n */\n async close(): Promise<void> {\n await this.storage.close?.()\n }\n\n private resolveDefinition<TInput, TData>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>\n ): WorkflowDefinition<TInput, TData> {\n return workflow instanceof WorkflowBuilder ? workflow.build() : workflow\n }\n\n private resolveStartIndex<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n fromStep: number | string | undefined,\n fallback: number\n ): number {\n if (typeof fromStep === 'number') {\n if (fromStep < 0 || fromStep >= definition.steps.length) {\n throw new Error(`Invalid step index: ${fromStep}`)\n }\n return fromStep\n }\n if (typeof fromStep === 'string') {\n const index = definition.steps.findIndex((step) => step.name === fromStep)\n if (index === -1) {\n throw new Error(`Step not found: ${fromStep}`)\n }\n return index\n }\n return Math.max(0, Math.min(fallback, definition.steps.length - 1))\n }\n\n private resetHistoryFrom<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n startIndex: number\n ): void {\n for (let i = startIndex; i < ctx.history.length; i++) {\n const entry = ctx.history[i]\n if (!entry) {\n continue\n }\n entry.status = 'pending'\n entry.startedAt = undefined\n entry.completedAt = undefined\n entry.duration = undefined\n entry.error = undefined\n entry.retries = 0\n }\n }\n\n /**\n * Rollback workflow by executing compensation handlers in reverse order\n */\n private async rollback<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n failedAtIndex: number,\n originalError: Error\n ): Promise<void> {\n Object.assign(ctx, { status: 'rolling_back' })\n\n await this.emitTrace({\n type: 'workflow:rollback_start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolling_back',\n error: originalError.message,\n })\n\n // Iterate backwards from the step BEFORE the failed one\n for (let i = failedAtIndex - 1; i >= 0; i--) {\n const step = definition.steps[i]\n const execution = ctx.history[i]\n\n // Only compensate completed steps\n if (!step || !step.compensate || !execution || execution.status !== 'completed') {\n continue\n }\n\n try {\n execution.status = 'compensating'\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n await step.compensate(ctx)\n\n execution.status = 'compensated'\n execution.compensatedAt = new Date()\n\n await this.emitTrace({\n type: 'step:compensate',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n status: 'compensated',\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n // Compensation failed - this is bad. Mark workflow as failed (not rolled_back)\n Object.assign(ctx, { status: 'failed' })\n\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n error: `Compensation failed at step \"${step.name}\": ${error.message}`,\n })\n return // Stop rollback\n }\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n Object.assign(ctx, { status: 'rolled_back' })\n await this.emitTrace({\n type: 'workflow:rollback_complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolled_back',\n })\n }\n\n private async runFrom<TInput, TData = any>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n stateMachine: StateMachine,\n startTime: number,\n startIndex: number,\n meta?: { resume?: boolean; retry?: boolean; fromStep?: number }\n ): Promise<FluxResult<TData>> {\n try {\n // Transition to running\n stateMachine.transition('running')\n Object.assign(ctx, { status: 'running' })\n if (!meta?.resume) {\n await this.emitTrace({\n type: 'workflow:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n input: ctx.input,\n meta,\n })\n }\n\n // Execute steps\n for (let i = startIndex; i < definition.steps.length; i++) {\n const step = definition.steps[i]!\n const execution = ctx.history[i]!\n\n // Update step name\n this.contextManager.setStepName(ctx, i, step.name)\n Object.assign(ctx, { currentStep: i })\n\n // Emit step start event\n this.config.on?.stepStart?.(step.name, ctx as any)\n await this.emitTrace({\n type: 'step:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n status: execution.status,\n meta,\n })\n\n // Execute step\n const result = await this.executor.execute(step, ctx, execution)\n\n if (result.success) {\n if (result.suspended) {\n // Handle suspension\n stateMachine.transition('suspended')\n Object.assign(ctx, { status: 'suspended' })\n\n await this.emitTrace({\n type: 'step:suspend',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n meta: { signal: result.waitingFor },\n })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return {\n id: ctx.id,\n status: 'suspended',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n }\n\n // Emit step complete event\n this.config.on?.stepComplete?.(step.name, ctx as any, result)\n if (execution.status === 'skipped') {\n await this.emitTrace({\n type: 'step:skipped',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n } else {\n await this.emitTrace({\n type: 'step:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n }\n } else {\n // Emit step error event\n this.config.on?.stepError?.(step.name, ctx as any, result.error!)\n await this.emitTrace({\n type: 'step:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n error: result.error?.message,\n status: execution.status,\n meta,\n })\n\n // Fail workflow with potential rollback\n await this.rollback<TInput, TData>(definition, ctx, i, result.error!)\n\n const finalStatus = ctx.status\n stateMachine.forceStatus(finalStatus)\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: result.error?.message,\n })\n\n return {\n id: ctx.id,\n status: finalStatus,\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: result.error,\n }\n }\n\n // Save progress after each step\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n // Complete workflow\n stateMachine.transition('completed')\n Object.assign(ctx, { status: 'completed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n completedAt: new Date(),\n })\n\n // Emit workflow complete event\n this.config.on?.workflowComplete?.(ctx as any)\n await this.emitTrace({\n type: 'workflow:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n duration: Date.now() - startTime,\n data: ctx.data as Record<string, unknown>,\n meta,\n })\n\n return {\n id: ctx.id,\n status: 'completed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n\n // Emit workflow error event\n this.config.on?.workflowError?.(ctx as any, err)\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n duration: Date.now() - startTime,\n error: err.message,\n meta,\n })\n\n stateMachine.forceStatus('failed')\n Object.assign(ctx, { status: 'failed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: err.message,\n })\n\n return {\n id: ctx.id,\n status: 'failed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: err,\n }\n }\n }\n\n private async emitTrace(event: FluxTraceEvent): Promise<void> {\n try {\n await this.config.trace?.emit(event)\n } catch {\n // Ignore trace failures to avoid breaking workflow execution\n }\n }\n}\n","/**\n * @fileoverview JSON file trace sink (NDJSON)\n *\n * Writes trace events to a newline-delimited JSON file.\n */\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { FluxTraceEvent, FluxTraceSink } from '../types'\n\nexport interface JsonFileTraceSinkOptions {\n path: string\n reset?: boolean\n}\n\nexport class JsonFileTraceSink implements FluxTraceSink {\n private path: string\n private ready: Promise<void>\n\n constructor(options: JsonFileTraceSinkOptions) {\n this.path = options.path\n this.ready = this.init(options.reset ?? true)\n }\n\n private async init(reset: boolean): Promise<void> {\n await mkdir(dirname(this.path), { recursive: true })\n if (reset) {\n await writeFile(this.path, '', 'utf8')\n }\n }\n\n async emit(event: FluxTraceEvent): Promise<void> {\n await this.ready\n await appendFile(this.path, `${JSON.stringify(event)}\\n`, 'utf8')\n }\n}\n","/**\n * @fileoverview Console Logger for FluxEngine\n *\n * Default logger implementation using console.\n *\n * @module @gravito/flux\n */\n\nimport type { FluxLogger } from '../types'\n\n/**\n * Console Logger\n *\n * Default logger that outputs to console.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({\n * logger: new FluxConsoleLogger()\n * })\n * ```\n */\nexport class FluxConsoleLogger implements FluxLogger {\n private prefix: string\n\n constructor(prefix = '[Flux]') {\n this.prefix = prefix\n }\n\n debug(message: string, ...args: unknown[]): void {\n console.debug(`${this.prefix} ${message}`, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n console.info(`${this.prefix} ${message}`, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n console.warn(`${this.prefix} ${message}`, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n console.error(`${this.prefix} ${message}`, ...args)\n }\n}\n\n/**\n * Silent Logger\n *\n * Logger that outputs nothing (for testing or production).\n */\nexport class FluxSilentLogger implements FluxLogger {\n debug(): void {}\n info(): void {}\n warn(): void {}\n error(): void {}\n}\n","/**\n * @fileoverview OrbitFlux - Gravito PlanetCore Integration\n *\n * Integrates FluxEngine with Gravito's PlanetCore for seamless workflow management.\n *\n * @module @gravito/flux\n */\n\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { BunSQLiteStorage } from '../storage/BunSQLiteStorage'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type { FluxConfig, FluxLogger, WorkflowStorage } from '../types'\n\n/**\n * Minimal PlanetCore interface for type compatibility\n * (Avoids importing @gravito/core sources which causes rootDir issues)\n */\ninterface PlanetCore {\n logger: {\n debug(message: string, ...args: unknown[]): void\n info(message: string, ...args: unknown[]): void\n warn(message: string, ...args: unknown[]): void\n error(message: string, ...args: unknown[]): void\n }\n services: {\n set(key: string, value: unknown): void\n get<T>(key: string): T | undefined\n }\n hooks: {\n doAction(name: string, payload?: unknown): void\n }\n}\n\n/**\n * GravitoOrbit interface\n */\nexport interface GravitoOrbit {\n install(core: PlanetCore): void | Promise<void>\n}\n\n/**\n * OrbitFlux configuration options\n */\nexport interface OrbitFluxOptions {\n /**\n * Storage driver: 'memory' | 'sqlite' | custom WorkflowStorage\n * @default 'memory'\n */\n storage?: 'memory' | 'sqlite' | WorkflowStorage\n\n /**\n * SQLite database path (only used if storage is 'sqlite')\n * @default ':memory:'\n */\n dbPath?: string\n\n /**\n * Service name in core.services\n * @default 'flux'\n */\n exposeAs?: string\n\n /**\n * Custom logger\n */\n logger?: FluxLogger\n\n /**\n * Default retry count for steps\n * @default 3\n */\n defaultRetries?: number\n\n /**\n * Default timeout for steps (ms)\n * @default 30000\n */\n defaultTimeout?: number\n}\n\n/**\n * OrbitFlux - Gravito Workflow Integration\n *\n * @example\n * ```typescript\n * import { OrbitFlux } from '@gravito/flux'\n *\n * const core = await PlanetCore.boot({\n * orbits: [\n * new OrbitFlux({ storage: 'sqlite', dbPath: './data/workflows.db' })\n * ]\n * })\n *\n * // Access via services\n * const flux = core.services.get<FluxEngine>('flux')\n * await flux.execute(myWorkflow, input)\n * ```\n */\nexport class OrbitFlux implements GravitoOrbit {\n private options: OrbitFluxOptions\n private engine?: FluxEngine\n\n constructor(options: OrbitFluxOptions = {}) {\n this.options = {\n storage: 'memory',\n exposeAs: 'flux',\n defaultRetries: 3,\n defaultTimeout: 30000,\n ...options,\n }\n }\n\n /**\n * Create OrbitFlux with configuration\n */\n static configure(options: OrbitFluxOptions = {}): OrbitFlux {\n return new OrbitFlux(options)\n }\n\n /**\n * Install into PlanetCore\n *\n * @param core - The PlanetCore instance\n */\n async install(core: PlanetCore): Promise<void> {\n const { storage, dbPath, exposeAs, defaultRetries, defaultTimeout, logger } = this.options\n\n // Resolve storage adapter\n let storageAdapter: WorkflowStorage\n\n if (typeof storage === 'string') {\n switch (storage) {\n case 'sqlite':\n storageAdapter = new BunSQLiteStorage({ path: dbPath })\n break\n default:\n storageAdapter = new MemoryStorage()\n }\n } else {\n storageAdapter = storage!\n }\n\n // Initialize storage\n await storageAdapter.init?.()\n\n // Create engine configuration\n const engineConfig: FluxConfig = {\n storage: storageAdapter,\n defaultRetries,\n defaultTimeout,\n logger: logger ?? {\n debug: (msg) => core.logger.debug(`[Flux] ${msg}`),\n info: (msg) => core.logger.info(`[Flux] ${msg}`),\n warn: (msg) => core.logger.warn(`[Flux] ${msg}`),\n error: (msg) => core.logger.error(`[Flux] ${msg}`),\n },\n on: {\n stepStart: (step) => {\n core.hooks.doAction('flux:step:start', { step })\n },\n stepComplete: (step, ctx, result) => {\n core.hooks.doAction('flux:step:complete', { step, ctx, result })\n },\n stepError: (step, ctx, error) => {\n core.hooks.doAction('flux:step:error', { step, ctx, error })\n },\n workflowComplete: (ctx) => {\n core.hooks.doAction('flux:workflow:complete', { ctx })\n },\n workflowError: (ctx, error) => {\n core.hooks.doAction('flux:workflow:error', { ctx, error })\n },\n },\n }\n\n // Create engine\n this.engine = new FluxEngine(engineConfig)\n\n // Register in core services\n core.services.set(exposeAs!, this.engine)\n\n core.logger.info(\n `[OrbitFlux] Initialized (Storage: ${typeof storage === 'string' ? storage : 'custom'})`\n )\n }\n\n /**\n * Get the FluxEngine instance\n */\n getEngine(): FluxEngine | undefined {\n return this.engine\n }\n}\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/builder/WorkflowBuilder.ts","../src/core/ContextManager.ts","../src/core/StateMachine.ts","../src/core/StepExecutor.ts","../src/storage/MemoryStorage.ts","../src/engine/FluxEngine.ts","../src/trace/JsonFileTraceSink.ts","../src/logger/FluxLogger.ts","../src/orbit/OrbitFlux.ts"],"sourcesContent":["/**\n * @fileoverview Workflow Builder - Fluent API for defining workflows\n *\n * Type-safe, chainable workflow definition.\n *\n * @module @gravito/flux/builder\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepDescriptor,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowDescriptor,\n} from '../types'\n\n/**\n * Step options\n */\ninterface StepOptions<TInput = any, TData = any> {\n retries?: number\n timeout?: number\n when?: (ctx: WorkflowContext<TInput, TData>) => boolean\n compensate?: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void\n}\n\n/**\n * Workflow Builder\n *\n * Provides fluent API for defining workflows with type inference.\n *\n * @example\n * ```typescript\n * const workflow = createWorkflow('order-process')\n * .input<{ orderId: string }>()\n * .step('validate', async (ctx) => {\n * ctx.data.order = await fetchOrder(ctx.input.orderId)\n * })\n * .step('process', async (ctx) => {\n * await processOrder(ctx.data.order)\n * }, {\n * compensate: async (ctx) => {\n * await cancelOrder(ctx.data.order.id)\n * }\n * })\n * .commit('notify', async (ctx) => {\n * await sendEmail(ctx.data.order.email)\n * })\n * ```\n */\nexport class WorkflowBuilder<TInput = unknown, TData = Record<string, unknown>> {\n private _name: string\n private _steps: StepDefinition[] = []\n private _validateInput?: (input: unknown) => input is TInput\n\n constructor(name: string) {\n this._name = name\n }\n\n /**\n * Define input type\n *\n * This method is used for TypeScript type inference.\n */\n input<T>(): WorkflowBuilder<T, TData> {\n return this as unknown as WorkflowBuilder<T, TData>\n }\n\n /**\n * Define workflow data (state) type\n *\n * This method is used for TypeScript type inference.\n */\n data<T>(): WorkflowBuilder<TInput, T> {\n return this as unknown as WorkflowBuilder<TInput, T>\n }\n\n /**\n * Add input validator\n */\n validate(validator: (input: unknown) => input is TInput): this {\n this._validateInput = validator\n return this\n }\n\n /**\n * Add a step to the workflow\n */\n step(\n name: string,\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n options?: StepOptions<TInput, TData>\n ): this {\n this._steps.push({\n name,\n handler: handler as (\n ctx: WorkflowContext\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n compensate: options?.compensate as\n | ((ctx: WorkflowContext) => Promise<void> | void)\n | undefined,\n commit: false,\n })\n return this\n }\n\n /**\n * Add a commit step (always executes, even on replay)\n *\n * Commit steps are for side effects that should not be skipped,\n * such as database writes or external API calls.\n */\n commit(\n name: string,\n handler: (ctx: WorkflowContext<TInput, TData>) => Promise<void> | void,\n options?: Omit<StepOptions<TInput, TData>, 'compensate'>\n ): this {\n this._steps.push({\n name,\n handler: handler as (ctx: WorkflowContext) => Promise<void> | void,\n retries: options?.retries,\n timeout: options?.timeout,\n when: options?.when as ((ctx: WorkflowContext) => boolean) | undefined,\n commit: true,\n })\n return this\n }\n\n /**\n * Build the workflow definition\n */\n build(): WorkflowDefinition<TInput, TData> {\n if (this._steps.length === 0) {\n throw new Error(`Workflow \"${this._name}\" has no steps`)\n }\n\n return {\n name: this._name,\n steps: [...this._steps],\n validateInput: this._validateInput,\n }\n }\n\n /**\n * Describe workflow (serializable metadata)\n */\n describe(): WorkflowDescriptor {\n const steps: StepDescriptor[] = this._steps.map((step) => ({\n name: step.name,\n commit: Boolean(step.commit),\n retries: step.retries,\n timeout: step.timeout,\n hasCondition: Boolean(step.when),\n }))\n\n return {\n name: this._name,\n steps,\n }\n }\n\n /**\n * Get workflow name\n */\n get name(): string {\n return this._name\n }\n\n /**\n * Get step count\n */\n get stepCount(): number {\n return this._steps.length\n }\n}\n\n/**\n * Create a new workflow builder\n *\n * @param name - Unique workflow name\n * @returns WorkflowBuilder instance\n *\n * @example\n * ```typescript\n * const uploadFlow = createWorkflow('image-upload')\n * .input<{ file: Buffer }>()\n * .step('resize', async (ctx) => {\n * ctx.data.resized = await sharp(ctx.input.file).resize(200).toBuffer()\n * })\n * .commit('save', async (ctx) => {\n * await storage.put(ctx.data.resized)\n * })\n * ```\n */\nexport function createWorkflow(name: string): WorkflowBuilder {\n return new WorkflowBuilder(name)\n}\n","/**\n * @fileoverview Context Manager for workflow execution\n *\n * Manages workflow context lifecycle and state snapshots.\n *\n * @module @gravito/flux/core\n */\n\nimport type { StepExecution, WorkflowContext, WorkflowState, WorkflowStatus } from '../types'\n\n/**\n * Generate unique ID using crypto.randomUUID (Web Standard)\n */\nfunction generateId(): string {\n return crypto.randomUUID()\n}\n\n/**\n * Context Manager\n *\n * Creates and manages workflow execution contexts.\n */\nexport class ContextManager {\n /**\n * Create a new workflow context\n */\n create<TInput, TData = any>(\n name: string,\n input: TInput,\n stepCount: number\n ): WorkflowContext<TInput, TData> {\n const history: StepExecution[] = Array.from({ length: stepCount }, (_, _i) => ({\n name: '',\n status: 'pending',\n retries: 0,\n }))\n\n return {\n id: generateId(),\n name,\n input,\n data: {} as TData,\n status: 'pending',\n currentStep: 0,\n history,\n }\n }\n\n /**\n * Restore context from saved state\n */\n restore<TInput, TData = any>(\n state: WorkflowState<TInput, TData>\n ): WorkflowContext<TInput, TData> {\n return {\n id: state.id,\n name: state.name,\n input: state.input as TInput,\n data: { ...state.data } as unknown as TData,\n status: state.status,\n currentStep: state.currentStep,\n history: state.history.map((h) => ({ ...h })),\n }\n }\n\n /**\n * Convert context to serializable state\n */\n toState<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowState<TInput, TData> {\n return {\n id: ctx.id,\n name: ctx.name,\n status: ctx.status,\n input: ctx.input,\n data: { ...(ctx.data as any) },\n currentStep: ctx.currentStep,\n history: ctx.history.map((h) => ({ ...h })),\n createdAt: new Date(),\n updatedAt: new Date(),\n }\n }\n\n /**\n * Update context status (returns new context for immutability)\n */\n updateStatus<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n status: WorkflowStatus\n ): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n status,\n }\n }\n\n /**\n * Advance to next step\n */\n advanceStep<TInput, TData>(ctx: WorkflowContext<TInput, TData>): WorkflowContext<TInput, TData> {\n return {\n ...ctx,\n currentStep: ctx.currentStep + 1,\n }\n }\n\n /**\n * Update step name in history\n */\n setStepName<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n index: number,\n name: string\n ): void {\n if (ctx.history[index]) {\n ctx.history[index].name = name\n }\n }\n}\n","/**\n * @fileoverview State Machine for workflow status transitions\n *\n * Pure state machine with no runtime dependencies.\n *\n * @module @gravito/flux/core\n */\n\nimport type { WorkflowStatus } from '../types'\n\n/**\n * Valid state transitions\n */\nconst TRANSITIONS: Record<WorkflowStatus, WorkflowStatus[]> = {\n pending: ['running', 'failed'],\n running: ['paused', 'completed', 'failed', 'suspended', 'rolling_back'],\n paused: ['running', 'failed'],\n suspended: ['running', 'failed'],\n rolling_back: ['rolled_back', 'failed'],\n rolled_back: ['pending'], // allow retry from scratch\n completed: [], // terminal state\n failed: ['pending'], // allow retry\n}\n\n/**\n * State Machine for workflow status management\n *\n * Provides validated state transitions using EventTarget for events.\n */\nexport class StateMachine extends EventTarget {\n private _status: WorkflowStatus = 'pending'\n\n /**\n * Current status\n */\n get status(): WorkflowStatus {\n return this._status\n }\n\n /**\n * Check if transition to target status is allowed\n */\n canTransition(to: WorkflowStatus): boolean {\n return TRANSITIONS[this._status].includes(to)\n }\n\n /**\n * Transition to a new status\n *\n * @throws {Error} If transition is not allowed\n */\n transition(to: WorkflowStatus): void {\n if (!this.canTransition(to)) {\n throw new Error(`Invalid state transition: ${this._status} → ${to}`)\n }\n\n const from = this._status\n this._status = to\n\n // Emit transition event\n this.dispatchEvent(\n new CustomEvent('transition', {\n detail: { from, to },\n })\n )\n }\n\n /**\n * Force set status (for replay/restore)\n */\n forceStatus(status: WorkflowStatus): void {\n this._status = status\n }\n\n /**\n * Check if workflow is in terminal state\n */\n isTerminal(): boolean {\n return (\n this._status === 'completed' || this._status === 'failed' || this._status === 'rolled_back'\n )\n }\n\n /**\n * Check if workflow can be executed\n */\n canExecute(): boolean {\n return this._status === 'pending' || this._status === 'paused'\n }\n}\n","/**\n * @fileoverview Step Executor for workflow steps\n *\n * Handles step execution with retry and timeout support.\n *\n * @module @gravito/flux/core\n */\n\nimport type {\n FluxWaitResult,\n StepDefinition,\n StepExecution,\n StepResult,\n WorkflowContext,\n} from '../types'\n\n/**\n * Step Executor\n *\n * Executes individual workflow steps with retry and timeout support.\n */\nexport class StepExecutor {\n private defaultRetries: number\n private defaultTimeout: number\n private onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n\n constructor(\n options: {\n defaultRetries?: number\n defaultTimeout?: number\n onRetry?: (\n step: StepDefinition<any, any>,\n ctx: WorkflowContext<any, any>,\n error: Error,\n attempt: number,\n maxRetries: number\n ) => void | Promise<void>\n } = {}\n ) {\n this.defaultRetries = options.defaultRetries ?? 3\n this.defaultTimeout = options.defaultTimeout ?? 30000\n this.onRetry = options.onRetry\n }\n\n /**\n * Execute a step with retry and timeout\n */\n async execute<TInput, TData>(\n step: StepDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n execution: StepExecution\n ): Promise<StepResult> {\n const maxRetries = step.retries ?? this.defaultRetries\n const timeout = step.timeout ?? this.defaultTimeout\n const startTime = Date.now()\n\n // Check condition\n if (step.when && !step.when(ctx)) {\n execution.status = 'skipped'\n return {\n success: true,\n duration: 0,\n }\n }\n\n execution.status = 'running'\n execution.startedAt = new Date()\n\n let lastError: Error | undefined\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n execution.retries = attempt\n\n try {\n // Execute with timeout\n const result = await this.executeWithTimeout(step.handler, ctx, timeout)\n\n if (\n result &&\n typeof result === 'object' &&\n '__kind' in result &&\n result.__kind === 'flux_wait'\n ) {\n execution.status = 'suspended'\n execution.waitingFor = result.signal\n execution.suspendedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n suspended: true,\n waitingFor: result.signal,\n duration: execution.duration,\n }\n }\n\n execution.status = 'completed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n\n return {\n success: true,\n duration: execution.duration,\n }\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error))\n\n // If not last retry, continue\n if (attempt < maxRetries) {\n await this.onRetry?.(step, ctx, lastError, attempt + 1, maxRetries)\n // Exponential backoff\n await this.sleep(Math.min(1000 * 2 ** attempt, 10000))\n }\n }\n }\n\n // All retries failed\n execution.status = 'failed'\n execution.completedAt = new Date()\n execution.duration = Date.now() - startTime\n execution.error = lastError?.message\n\n return {\n success: false,\n error: lastError,\n duration: execution.duration,\n }\n }\n\n /**\n * Execute handler with timeout\n */\n private async executeWithTimeout<TInput, TData>(\n handler: (\n ctx: WorkflowContext<TInput, TData>\n ) => Promise<void | FluxWaitResult> | void | FluxWaitResult,\n ctx: WorkflowContext<TInput, TData>,\n timeout: number\n ): Promise<void | FluxWaitResult> {\n let timer: ReturnType<typeof setTimeout> | null = null\n try {\n const timeoutPromise = new Promise<never>((_, reject) => {\n timer = setTimeout(() => reject(new Error('Step timeout')), timeout)\n })\n\n return await Promise.race([Promise.resolve(handler(ctx)), timeoutPromise])\n } finally {\n if (timer) {\n clearTimeout(timer)\n }\n }\n }\n\n /**\n * Sleep helper\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n }\n}\n","/**\n * @fileoverview In-memory storage adapter\n *\n * Simple storage for development and testing.\n *\n * @module @gravito/flux/storage\n */\n\nimport type { WorkflowFilter, WorkflowState, WorkflowStorage } from '../types'\n\n/**\n * Memory Storage\n *\n * In-memory storage adapter for development and testing.\n * Data is not persisted across restarts.\n */\nexport class MemoryStorage implements WorkflowStorage {\n private store = new Map<string, WorkflowState>()\n\n async save(state: WorkflowState): Promise<void> {\n this.store.set(state.id, {\n ...state,\n updatedAt: new Date(),\n })\n }\n\n async load(id: string): Promise<WorkflowState | null> {\n return this.store.get(id) ?? null\n }\n\n async list(filter?: WorkflowFilter): Promise<WorkflowState[]> {\n let results = Array.from(this.store.values())\n\n if (filter?.name) {\n results = results.filter((s) => s.name === filter.name)\n }\n\n if (filter?.status) {\n const statuses = Array.isArray(filter.status) ? filter.status : [filter.status]\n results = results.filter((s) => statuses.includes(s.status))\n }\n\n // Sort by createdAt desc\n results.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())\n\n // Apply pagination\n if (filter?.offset) {\n results = results.slice(filter.offset)\n }\n if (filter?.limit) {\n results = results.slice(0, filter.limit)\n }\n\n return results\n }\n\n async delete(id: string): Promise<void> {\n this.store.delete(id)\n }\n\n async init(): Promise<void> {\n // No-op for memory storage\n }\n\n async close(): Promise<void> {\n this.store.clear()\n }\n\n /**\n * Get store size (for testing)\n */\n size(): number {\n return this.store.size\n }\n}\n","/**\n * @fileoverview Flux Engine - Main workflow execution engine\n *\n * Orchestrates workflow execution with storage and event handling.\n *\n * @module @gravito/flux\n */\n\nimport { WorkflowBuilder } from '../builder/WorkflowBuilder'\nimport { ContextManager } from '../core/ContextManager'\nimport { StateMachine } from '../core/StateMachine'\nimport { StepExecutor } from '../core/StepExecutor'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type {\n FluxConfig,\n FluxResult,\n FluxTraceEvent,\n WorkflowContext,\n WorkflowDefinition,\n WorkflowState,\n WorkflowStorage,\n} from '../types'\n\n/**\n * Flux Engine\n *\n * Main workflow execution engine.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({ storage: new MemoryStorage() })\n *\n * const workflow = createWorkflow('process-order')\n * .input<{ orderId: string }>()\n * .step('fetch', async (ctx) => { ... })\n * .step('validate', async (ctx) => { ... })\n * .commit('save', async (ctx) => { ... })\n *\n * const result = await engine.execute(workflow, { orderId: '123' })\n * ```\n */\nexport class FluxEngine {\n private storage: WorkflowStorage\n private executor: StepExecutor\n private contextManager: ContextManager\n private config: FluxConfig\n\n constructor(config: FluxConfig = {}) {\n this.config = config\n this.storage = config.storage ?? new MemoryStorage()\n this.executor = new StepExecutor({\n defaultRetries: config.defaultRetries,\n defaultTimeout: config.defaultTimeout,\n onRetry: async (step, ctx, error, attempt, maxRetries) => {\n await this.emitTrace({\n type: 'step:retry',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: ctx.currentStep,\n commit: Boolean(step.commit),\n retries: attempt,\n maxRetries,\n error: error.message,\n status: 'running',\n })\n },\n })\n this.contextManager = new ContextManager()\n }\n\n /**\n * Execute a workflow with input data\n *\n * @param workflow - Workflow builder or definition\n * @param input - Input data for the workflow\n * @returns Execution result\n */\n async execute<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n input: TInput\n ): Promise<FluxResult<TData>> {\n const startTime = Date.now()\n const definition = this.resolveDefinition(workflow)\n\n // Validate input if validator provided\n if (definition.validateInput && !definition.validateInput(input)) {\n throw new Error(`Invalid input for workflow \"${definition.name}\"`)\n }\n\n // Create context\n const ctx = this.contextManager.create<TInput, TData>(\n definition.name,\n input,\n definition.steps.length\n ) as WorkflowContext<TInput, TData>\n\n // Create state machine\n const stateMachine = new StateMachine()\n\n // Save initial state\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, startTime, 0)\n }\n\n /**\n * Resume a paused or failed workflow\n *\n * @param workflowId - Workflow instance ID\n * @returns Execution result or null if not found\n */\n async resume<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n options?: { fromStep?: number | string }\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; resume is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, options?.fromStep, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n resume: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Send a signal to a suspended workflow\n */\n async signal<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n signalName: string,\n payload?: any\n ): Promise<FluxResult<TData>> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n throw new Error('Workflow not found')\n }\n if (state.status !== 'suspended') {\n throw new Error(`Workflow is not suspended (status: ${state.status})`)\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const currentStep = ctx.history[ctx.currentStep]\n\n if (!currentStep || currentStep.status !== 'suspended') {\n throw new Error('Workflow state invalid: no suspended step found')\n }\n if (currentStep.waitingFor !== signalName) {\n throw new Error(\n `Workflow waiting for signal \"${currentStep.waitingFor}\", received \"${signalName}\"`\n )\n }\n\n // Complete the suspended step\n currentStep.status = 'completed'\n currentStep.completedAt = new Date()\n currentStep.output = payload\n // If payload contains data, we might want to merge it?\n // For now, allow next step to access it via history or we need a cleaner way.\n // Let's assume user grabs it from history for now or we build a helper later.\n\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('suspended')\n // ctx status will be updated to 'running' in runFrom\n\n await this.emitTrace({\n type: 'signal:received',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'suspended',\n input: payload,\n })\n\n // Resume from NEXT step\n const nextStepIndex = ctx.currentStep + 1\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), nextStepIndex, {\n resume: true,\n fromStep: nextStepIndex,\n })\n }\n\n /**\n * Retry a specific step (replays from that step onward)\n */\n async retryStep<TInput, TData = any>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>,\n workflowId: string,\n stepName: string\n ): Promise<FluxResult<TData> | null> {\n const definition = this.resolveDefinition(workflow)\n const state = await this.storage.load(workflowId)\n if (!state) {\n return null\n }\n if (state.name !== definition.name) {\n throw new Error(`Workflow name mismatch: ${state.name} !== ${definition.name}`)\n }\n if (state.history.length !== definition.steps.length) {\n throw new Error('Workflow definition changed; retry is not safe')\n }\n\n const ctx = this.contextManager.restore<TInput, TData>(state)\n const stateMachine = new StateMachine()\n stateMachine.forceStatus('pending')\n\n const startIndex = this.resolveStartIndex(definition, stepName, ctx.currentStep)\n this.resetHistoryFrom(ctx, startIndex)\n Object.assign(ctx, { status: 'pending', currentStep: startIndex })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return this.runFrom(definition, ctx, stateMachine, Date.now(), startIndex, {\n retry: true,\n fromStep: startIndex,\n })\n }\n\n /**\n * Get workflow state by ID\n */\n async get<TInput = any, TData = any>(\n workflowId: string\n ): Promise<WorkflowState<TInput, TData> | null> {\n return this.storage.load(workflowId) as Promise<WorkflowState<TInput, TData> | null>\n }\n\n /**\n * Save workflow state manually (e.g., for external updates)\n */\n async saveState<TInput, TData>(state: WorkflowState<TInput, TData>): Promise<void> {\n return this.storage.save(state)\n }\n\n /**\n * List workflows\n */\n async list(filter?: Parameters<WorkflowStorage['list']>[0]) {\n return this.storage.list(filter)\n }\n\n /**\n * Initialize engine (init storage)\n */\n async init(): Promise<void> {\n await this.storage.init?.()\n }\n\n /**\n * Shutdown engine (cleanup)\n */\n async close(): Promise<void> {\n await this.storage.close?.()\n }\n\n private resolveDefinition<TInput, TData>(\n workflow: WorkflowBuilder<TInput, TData> | WorkflowDefinition<TInput, TData>\n ): WorkflowDefinition<TInput, TData> {\n return workflow instanceof WorkflowBuilder ? workflow.build() : workflow\n }\n\n private resolveStartIndex<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n fromStep: number | string | undefined,\n fallback: number\n ): number {\n if (typeof fromStep === 'number') {\n if (fromStep < 0 || fromStep >= definition.steps.length) {\n throw new Error(`Invalid step index: ${fromStep}`)\n }\n return fromStep\n }\n if (typeof fromStep === 'string') {\n const index = definition.steps.findIndex((step) => step.name === fromStep)\n if (index === -1) {\n throw new Error(`Step not found: ${fromStep}`)\n }\n return index\n }\n return Math.max(0, Math.min(fallback, definition.steps.length - 1))\n }\n\n private resetHistoryFrom<TInput, TData>(\n ctx: WorkflowContext<TInput, TData>,\n startIndex: number\n ): void {\n for (let i = startIndex; i < ctx.history.length; i++) {\n const entry = ctx.history[i]\n if (!entry) {\n continue\n }\n entry.status = 'pending'\n entry.startedAt = undefined\n entry.completedAt = undefined\n entry.duration = undefined\n entry.error = undefined\n entry.retries = 0\n }\n }\n\n /**\n * Rollback workflow by executing compensation handlers in reverse order\n */\n private async rollback<TInput, TData>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n failedAtIndex: number,\n originalError: Error\n ): Promise<void> {\n Object.assign(ctx, { status: 'rolling_back' })\n\n await this.emitTrace({\n type: 'workflow:rollback_start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolling_back',\n error: originalError.message,\n })\n\n // Iterate backwards from the step BEFORE the failed one\n for (let i = failedAtIndex - 1; i >= 0; i--) {\n const step = definition.steps[i]\n const execution = ctx.history[i]\n\n // Only compensate completed steps\n if (!step || !step.compensate || !execution || execution.status !== 'completed') {\n continue\n }\n\n try {\n execution.status = 'compensating'\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n await step.compensate(ctx)\n\n execution.status = 'compensated'\n execution.compensatedAt = new Date()\n\n await this.emitTrace({\n type: 'step:compensate',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n status: 'compensated',\n })\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err))\n // Compensation failed - this is bad. Mark workflow as failed (not rolled_back)\n Object.assign(ctx, { status: 'failed' })\n\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n error: `Compensation failed at step \"${step.name}\": ${error.message}`,\n })\n return // Stop rollback\n }\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n Object.assign(ctx, { status: 'rolled_back' })\n await this.emitTrace({\n type: 'workflow:rollback_complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'rolled_back',\n })\n }\n\n private async runFrom<TInput, TData = any>(\n definition: WorkflowDefinition<TInput, TData>,\n ctx: WorkflowContext<TInput, TData>,\n stateMachine: StateMachine,\n startTime: number,\n startIndex: number,\n meta?: { resume?: boolean; retry?: boolean; fromStep?: number }\n ): Promise<FluxResult<TData>> {\n try {\n // Transition to running\n stateMachine.transition('running')\n Object.assign(ctx, { status: 'running' })\n if (!meta?.resume) {\n await this.emitTrace({\n type: 'workflow:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n input: ctx.input,\n meta,\n })\n }\n\n // Execute steps\n for (let i = startIndex; i < definition.steps.length; i++) {\n const step = definition.steps[i]!\n const execution = ctx.history[i]!\n\n // Update step name\n this.contextManager.setStepName(ctx, i, step.name)\n Object.assign(ctx, { currentStep: i })\n\n // Emit step start event\n this.config.on?.stepStart?.(step.name, ctx as any)\n await this.emitTrace({\n type: 'step:start',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n status: execution.status,\n meta,\n })\n\n // Execute step\n const result = await this.executor.execute(step, ctx, execution)\n\n if (result.success) {\n if (result.suspended) {\n // Handle suspension\n stateMachine.transition('suspended')\n Object.assign(ctx, { status: 'suspended' })\n\n await this.emitTrace({\n type: 'step:suspend',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n meta: { signal: result.waitingFor },\n })\n\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n\n return {\n id: ctx.id,\n status: 'suspended',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n }\n\n // Emit step complete event\n this.config.on?.stepComplete?.(step.name, ctx as any, result)\n if (execution.status === 'skipped') {\n await this.emitTrace({\n type: 'step:skipped',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n } else {\n await this.emitTrace({\n type: 'step:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n status: execution.status,\n meta,\n })\n }\n } else {\n // Emit step error event\n this.config.on?.stepError?.(step.name, ctx as any, result.error!)\n await this.emitTrace({\n type: 'step:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n stepName: step.name,\n stepIndex: i,\n commit: Boolean(step.commit),\n retries: execution.retries,\n duration: result.duration,\n error: result.error?.message,\n status: execution.status,\n meta,\n })\n\n // Fail workflow with potential rollback\n await this.rollback<TInput, TData>(definition, ctx, i, result.error!)\n\n const finalStatus = ctx.status\n stateMachine.forceStatus(finalStatus)\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: result.error?.message,\n })\n\n return {\n id: ctx.id,\n status: finalStatus,\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: result.error,\n }\n }\n\n // Save progress after each step\n await this.storage.save(this.contextManager.toState<TInput, TData>(ctx))\n }\n\n // Complete workflow\n stateMachine.transition('completed')\n Object.assign(ctx, { status: 'completed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n completedAt: new Date(),\n })\n\n // Emit workflow complete event\n this.config.on?.workflowComplete?.(ctx as any)\n await this.emitTrace({\n type: 'workflow:complete',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: ctx.status,\n duration: Date.now() - startTime,\n data: ctx.data as Record<string, unknown>,\n meta,\n })\n\n return {\n id: ctx.id,\n status: 'completed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n }\n } catch (error) {\n const err = error instanceof Error ? error : new Error(String(error))\n\n // Emit workflow error event\n this.config.on?.workflowError?.(ctx as any, err)\n await this.emitTrace({\n type: 'workflow:error',\n timestamp: Date.now(),\n workflowId: ctx.id,\n workflowName: ctx.name,\n status: 'failed',\n duration: Date.now() - startTime,\n error: err.message,\n meta,\n })\n\n stateMachine.forceStatus('failed')\n Object.assign(ctx, { status: 'failed' })\n\n await this.storage.save({\n ...this.contextManager.toState<TInput, TData>(ctx),\n error: err.message,\n })\n\n return {\n id: ctx.id,\n status: 'failed',\n data: ctx.data as TData,\n history: ctx.history,\n duration: Date.now() - startTime,\n error: err,\n }\n }\n }\n\n private async emitTrace(event: FluxTraceEvent): Promise<void> {\n try {\n await this.config.trace?.emit(event)\n } catch {\n // Ignore trace failures to avoid breaking workflow execution\n }\n }\n}\n","/**\n * @fileoverview JSON file trace sink (NDJSON)\n *\n * Writes trace events to a newline-delimited JSON file.\n */\n\nimport { appendFile, mkdir, writeFile } from 'node:fs/promises'\nimport { dirname } from 'node:path'\nimport type { FluxTraceEvent, FluxTraceSink } from '../types'\n\nexport interface JsonFileTraceSinkOptions {\n path: string\n reset?: boolean\n}\n\nexport class JsonFileTraceSink implements FluxTraceSink {\n private path: string\n private ready: Promise<void>\n\n constructor(options: JsonFileTraceSinkOptions) {\n this.path = options.path\n this.ready = this.init(options.reset ?? true)\n }\n\n private async init(reset: boolean): Promise<void> {\n await mkdir(dirname(this.path), { recursive: true })\n if (reset) {\n await writeFile(this.path, '', 'utf8')\n }\n }\n\n async emit(event: FluxTraceEvent): Promise<void> {\n await this.ready\n await appendFile(this.path, `${JSON.stringify(event)}\\n`, 'utf8')\n }\n}\n","/**\n * @fileoverview Console Logger for FluxEngine\n *\n * Default logger implementation using console.\n *\n * @module @gravito/flux\n */\n\nimport type { FluxLogger } from '../types'\n\n/**\n * Console Logger\n *\n * Default logger that outputs to console.\n *\n * @example\n * ```typescript\n * const engine = new FluxEngine({\n * logger: new FluxConsoleLogger()\n * })\n * ```\n */\nexport class FluxConsoleLogger implements FluxLogger {\n private prefix: string\n\n constructor(prefix = '[Flux]') {\n this.prefix = prefix\n }\n\n debug(message: string, ...args: unknown[]): void {\n console.debug(`${this.prefix} ${message}`, ...args)\n }\n\n info(message: string, ...args: unknown[]): void {\n console.info(`${this.prefix} ${message}`, ...args)\n }\n\n warn(message: string, ...args: unknown[]): void {\n console.warn(`${this.prefix} ${message}`, ...args)\n }\n\n error(message: string, ...args: unknown[]): void {\n console.error(`${this.prefix} ${message}`, ...args)\n }\n}\n\n/**\n * Silent Logger\n *\n * Logger that outputs nothing (for testing or production).\n */\nexport class FluxSilentLogger implements FluxLogger {\n debug(): void {}\n info(): void {}\n warn(): void {}\n error(): void {}\n}\n","/**\n * @fileoverview OrbitFlux - Gravito PlanetCore Integration\n *\n * Integrates FluxEngine with Gravito's PlanetCore for seamless workflow management.\n *\n * @module @gravito/flux\n */\n\nimport { FluxEngine } from '../engine/FluxEngine'\nimport { BunSQLiteStorage } from '../storage/BunSQLiteStorage'\nimport { MemoryStorage } from '../storage/MemoryStorage'\nimport type { FluxConfig, FluxLogger, WorkflowStorage } from '../types'\n\n/**\n * Minimal PlanetCore interface for type compatibility\n * (Avoids importing @gravito/core sources which causes rootDir issues)\n */\ninterface PlanetCore {\n logger: {\n debug(message: string, ...args: unknown[]): void\n info(message: string, ...args: unknown[]): void\n warn(message: string, ...args: unknown[]): void\n error(message: string, ...args: unknown[]): void\n }\n services: {\n set(key: string, value: unknown): void\n get<T>(key: string): T | undefined\n }\n hooks: {\n doAction(name: string, payload?: unknown): void\n }\n}\n\n/**\n * GravitoOrbit interface\n */\nexport interface GravitoOrbit {\n install(core: PlanetCore): void | Promise<void>\n}\n\n/**\n * OrbitFlux configuration options\n */\nexport interface OrbitFluxOptions {\n /**\n * Storage driver: 'memory' | 'sqlite' | custom WorkflowStorage\n * @default 'memory'\n */\n storage?: 'memory' | 'sqlite' | WorkflowStorage\n\n /**\n * SQLite database path (only used if storage is 'sqlite')\n * @default ':memory:'\n */\n dbPath?: string\n\n /**\n * Service name in core.services\n * @default 'flux'\n */\n exposeAs?: string\n\n /**\n * Custom logger\n */\n logger?: FluxLogger\n\n /**\n * Default retry count for steps\n * @default 3\n */\n defaultRetries?: number\n\n /**\n * Default timeout for steps (ms)\n * @default 30000\n */\n defaultTimeout?: number\n}\n\n/**\n * OrbitFlux - Gravito Workflow Integration\n *\n * @example\n * ```typescript\n * import { OrbitFlux } from '@gravito/flux'\n *\n * const core = await PlanetCore.boot({\n * orbits: [\n * new OrbitFlux({ storage: 'sqlite', dbPath: './data/workflows.db' })\n * ]\n * })\n *\n * // Access via services\n * const flux = core.services.get<FluxEngine>('flux')\n * await flux.execute(myWorkflow, input)\n * ```\n */\nexport class OrbitFlux implements GravitoOrbit {\n private options: OrbitFluxOptions\n private engine?: FluxEngine\n\n constructor(options: OrbitFluxOptions = {}) {\n this.options = {\n storage: 'memory',\n exposeAs: 'flux',\n defaultRetries: 3,\n defaultTimeout: 30000,\n ...options,\n }\n }\n\n /**\n * Create OrbitFlux with configuration\n */\n static configure(options: OrbitFluxOptions = {}): OrbitFlux {\n return new OrbitFlux(options)\n }\n\n /**\n * Install into PlanetCore\n *\n * @param core - The PlanetCore instance\n */\n async install(core: PlanetCore): Promise<void> {\n const { storage, dbPath, exposeAs, defaultRetries, defaultTimeout, logger } = this.options\n\n // Resolve storage adapter\n let storageAdapter: WorkflowStorage\n\n if (typeof storage === 'string') {\n switch (storage) {\n case 'sqlite':\n storageAdapter = new BunSQLiteStorage({ path: dbPath })\n break\n default:\n storageAdapter = new MemoryStorage()\n }\n } else {\n storageAdapter = storage!\n }\n\n // Initialize storage\n await storageAdapter.init?.()\n\n // Create engine configuration\n const engineConfig: FluxConfig = {\n storage: storageAdapter,\n defaultRetries,\n defaultTimeout,\n logger: logger ?? {\n debug: (msg) => core.logger.debug(`[Flux] ${msg}`),\n info: (msg) => core.logger.info(`[Flux] ${msg}`),\n warn: (msg) => core.logger.warn(`[Flux] ${msg}`),\n error: (msg) => core.logger.error(`[Flux] ${msg}`),\n },\n on: {\n stepStart: (step) => {\n core.hooks.doAction('flux:step:start', { step })\n },\n stepComplete: (step, ctx, result) => {\n core.hooks.doAction('flux:step:complete', { step, ctx, result })\n },\n stepError: (step, ctx, error) => {\n core.hooks.doAction('flux:step:error', { step, ctx, error })\n },\n workflowComplete: (ctx) => {\n core.hooks.doAction('flux:workflow:complete', { ctx })\n },\n workflowError: (ctx, error) => {\n core.hooks.doAction('flux:workflow:error', { ctx, error })\n },\n },\n }\n\n // Create engine\n this.engine = new FluxEngine(engineConfig)\n\n // Register in core services\n core.services.set(exposeAs!, this.engine)\n\n core.logger.info(\n `[OrbitFlux] Initialized (Storage: ${typeof storage === 'string' ? storage : 'custom'})`\n )\n }\n\n /**\n * Get the FluxEngine instance\n */\n getEngine(): FluxEngine | undefined {\n return this.engine\n }\n}\n"],"mappings":"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","names":[]}