{"version":3,"file":"workflow-distributed.cjs","names":["createSafeBaggageSchema","trace","SpanKind","context"],"sources":["../src/workflow-distributed.ts"],"sourcesContent":["/**\n * Distributed workflow tracing with cross-service correlation\n *\n * Enables tracking workflows that span multiple microservices by propagating\n * workflow identity (workflowId, stepName, stepIndex) via baggage in message headers.\n *\n * Unlike local workflow.ts (which uses AsyncLocalStorage), distributed workflows\n * propagate context across network boundaries using W3C baggage.\n *\n * @example Order fulfillment saga across services\n * ```typescript\n * // Service A: Order Service\n * import { traceDistributedWorkflow, WorkflowBaggage } from 'autotel/workflow-distributed';\n * import { traceProducer } from 'autotel/messaging';\n *\n * export const createOrder = traceDistributedWorkflow({\n *   name: 'OrderFulfillment',\n *   workflowIdFrom: (order) => order.id,\n *   version: '1.0.0',\n * })(ctx => async (order: Order) => {\n *   // Workflow baggage is auto-set\n *   await publishToInventory(order);\n * });\n *\n * const publishToInventory = traceProducer({\n *   system: 'kafka',\n *   destination: 'inventory-requests',\n *   propagateBaggage: true,  // Includes workflow.* baggage\n * })(ctx => async (order) => {\n *   await producer.send({ topic: 'inventory-requests', value: order });\n * });\n *\n * // Service B: Inventory Service\n * import { traceDistributedStep, WorkflowBaggage } from 'autotel/workflow-distributed';\n *\n * export const processInventory = traceDistributedStep({\n *   name: 'ReserveInventory',\n *   extractBaggage: true,  // Extracts workflow.* from headers\n * })(ctx => async (message) => {\n *   const workflow = WorkflowBaggage.get(ctx);\n *   // workflow.workflowId === order.id (propagated from Service A)\n *   console.log(`Processing step for workflow ${workflow.workflowId}`);\n *   await reserveItems(message.items);\n * });\n * ```\n *\n * @module\n */\n\nimport { context, propagation, SpanKind } from '@opentelemetry/api';\nimport { createSafeBaggageSchema } from './business-baggage';\nimport { emitCorrelatedEvent } from './correlated-events';\nimport { trace } from './functional';\nimport type { TraceContext } from './trace-context';\n\n// ============================================================================\n// Workflow Baggage Schema\n// ============================================================================\n\n/**\n * Workflow baggage field definitions\n */\nconst workflowBaggageFields = {\n  /** Unique identifier for the workflow instance */\n  workflowId: { type: 'string' as const, maxLength: 128, required: true },\n\n  /** Name/type of the workflow (e.g., \"OrderFulfillment\") */\n  workflowName: { type: 'string' as const, maxLength: 64, required: true },\n\n  /** Version of the workflow definition */\n  workflowVersion: { type: 'string' as const, maxLength: 32 },\n\n  /** Current step name */\n  stepName: { type: 'string' as const, maxLength: 64 },\n\n  /** Current step index (0-based) */\n  stepIndex: { type: 'number' as const },\n\n  /** Total number of steps (if known) */\n  totalSteps: { type: 'number' as const },\n\n  /** Parent workflow ID (for sub-workflows) */\n  parentWorkflowId: { type: 'string' as const, maxLength: 128 },\n\n  /** Correlation ID for external systems */\n  correlationId: { type: 'string' as const, maxLength: 128 },\n\n  /** Workflow priority */\n  priority: {\n    type: 'enum' as const,\n    values: ['low', 'normal', 'high', 'critical'] as const,\n  },\n\n  /** Initiating user/system */\n  initiatedBy: { type: 'string' as const, maxLength: 64 },\n\n  /** Workflow start timestamp (ISO) */\n  startedAt: { type: 'string' as const, maxLength: 30 },\n} as const;\n\n/**\n * Pre-built baggage schema for distributed workflows\n *\n * Use this to read/write workflow context that propagates across services.\n *\n * @example Setting workflow baggage\n * ```typescript\n * WorkflowBaggage.set(ctx, {\n *   workflowId: 'order-12345',\n *   workflowName: 'OrderFulfillment',\n *   stepName: 'ReserveInventory',\n *   stepIndex: 1,\n * });\n * ```\n *\n * @example Reading workflow baggage in downstream service\n * ```typescript\n * const { workflowId, workflowName, stepIndex } = WorkflowBaggage.get(ctx);\n * console.log(`Processing ${workflowName} step ${stepIndex}`);\n * ```\n */\nexport const WorkflowBaggage = createSafeBaggageSchema(workflowBaggageFields, {\n  prefix: 'workflow',\n  hashHighCardinality: false, // Workflow IDs should be traceable\n  redactPII: false, // Workflow fields are internal identifiers\n});\n\n/**\n * Type for workflow baggage values\n */\nexport type WorkflowBaggageValues = {\n  workflowId: string;\n  workflowName: string;\n  workflowVersion?: string;\n  stepName?: string;\n  stepIndex?: number;\n  totalSteps?: number;\n  parentWorkflowId?: string;\n  correlationId?: string;\n  priority?: 'low' | 'normal' | 'high' | 'critical';\n  initiatedBy?: string;\n  startedAt?: string;\n};\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Configuration for distributed workflow tracing\n */\nexport interface DistributedWorkflowConfig {\n  /** Workflow name/type (e.g., \"OrderFulfillment\", \"UserOnboarding\") */\n  name: string;\n\n  /**\n   * Extract workflow ID from function arguments\n   *\n   * Receives all arguments passed to the workflow function, allowing\n   * multi-parameter handlers to derive workflow IDs from any argument.\n   *\n   * @example Single argument\n   * ```typescript\n   * workflowIdFrom: (order) => order.id\n   * ```\n   *\n   * @example Multiple arguments (payload + metadata)\n   * ```typescript\n   * workflowIdFrom: (payload, metadata) => metadata.correlationId ?? payload.id\n   * ```\n   */\n  workflowIdFrom: (...args: unknown[]) => string;\n\n  /** Workflow version (e.g., \"1.0.0\", \"2023-01-15\") */\n  version?: string;\n\n  /** Total number of steps if known */\n  totalSteps?: number;\n\n  /** Parent workflow ID (for sub-workflows) */\n  parentWorkflowId?: string;\n\n  /** Correlation ID for external systems */\n  correlationId?: string;\n\n  /** Workflow priority */\n  priority?: 'low' | 'normal' | 'high' | 'critical';\n\n  /** User/system that initiated the workflow */\n  initiatedBy?: string;\n\n  /** Additional span attributes */\n  attributes?: Record<string, string | number | boolean>;\n\n  /** Callback on workflow start */\n  onStart?: (ctx: DistributedWorkflowContext) => void;\n\n  /** Callback on workflow completion */\n  onComplete?: (ctx: DistributedWorkflowContext, result: unknown) => void;\n\n  /** Callback on workflow error */\n  onError?: (ctx: DistributedWorkflowContext, error: Error) => void;\n}\n\n/**\n * Configuration for distributed workflow step\n */\nexport interface DistributedStepConfig {\n  /** Step name (e.g., \"ReserveInventory\", \"ChargePayment\") */\n  name: string;\n\n  /**\n   * Extract baggage from incoming message/request\n   *\n   * If true, reads workflow baggage from current context (assumes already extracted).\n   * If function, extracts from arguments.\n   *\n   * @default true\n   */\n  extractBaggage?:\n    | boolean\n    | ((args: unknown[]) => WorkflowBaggageValues | null);\n\n  /** Override step index (otherwise uses baggage or auto-increments) */\n  stepIndex?: number;\n\n  /** Additional span attributes */\n  attributes?: Record<string, string | number | boolean>;\n\n  /** Whether this step is idempotent (safe to retry) */\n  idempotent?: boolean;\n\n  /** Whether this step is a compensation/rollback step */\n  isCompensation?: boolean;\n\n  /** Callback on step start */\n  onStart?: (ctx: DistributedStepContext) => void;\n\n  /** Callback on step completion */\n  onComplete?: (ctx: DistributedStepContext, result: unknown) => void;\n\n  /** Callback on step error */\n  onError?: (ctx: DistributedStepContext, error: Error) => void;\n}\n\n/**\n * Extended context for distributed workflow root\n */\nexport interface DistributedWorkflowContext extends TraceContext {\n  /** The workflow ID */\n  workflowId: string;\n\n  /** The workflow name */\n  workflowName: string;\n\n  /** The workflow version */\n  workflowVersion?: string;\n\n  /** Get workflow baggage for propagation to other services */\n  getWorkflowBaggage(): WorkflowBaggageValues;\n\n  /** Set additional workflow baggage fields */\n  setWorkflowBaggage(values: Partial<WorkflowBaggageValues>): void;\n\n  /** Get headers with workflow baggage for outgoing requests */\n  getWorkflowHeaders(): Record<string, string>;\n\n  /** Record workflow step completion (for progress tracking) */\n  recordStepProgress(stepName: string, stepIndex: number): void;\n}\n\n/**\n * Extended context for distributed workflow step\n */\nexport interface DistributedStepContext extends TraceContext {\n  /** The workflow ID (from baggage) */\n  workflowId: string | null;\n\n  /** The workflow name (from baggage) */\n  workflowName: string | null;\n\n  /** The current step name */\n  stepName: string;\n\n  /** The current step index */\n  stepIndex: number | null;\n\n  /** Whether this step is a compensation */\n  isCompensation: boolean;\n\n  /** Get the full workflow baggage */\n  getWorkflowBaggage(): WorkflowBaggageValues | null;\n\n  /** Update workflow baggage (e.g., increment step index) */\n  updateWorkflowBaggage(values: Partial<WorkflowBaggageValues>): void;\n\n  /** Get headers with updated workflow baggage for downstream calls */\n  getWorkflowHeaders(): Record<string, string>;\n\n  /** Mark step as requiring compensation on failure */\n  requiresCompensation(compensationData?: Record<string, unknown>): void;\n}\n\n// ============================================================================\n// Distributed Workflow Tracer\n// ============================================================================\n\n/**\n * Create a traced distributed workflow function\n *\n * Wraps a function as the entry point for a distributed workflow. Automatically:\n * - Generates or extracts workflow ID\n * - Sets workflow baggage for downstream propagation\n * - Creates root span with workflow attributes\n *\n * @param config - Workflow configuration\n * @returns Factory function for the workflow handler\n *\n * @example Basic usage\n * ```typescript\n * export const createOrder = traceDistributedWorkflow({\n *   name: 'OrderFulfillment',\n *   workflowIdFrom: (order) => order.id,\n *   version: '1.0.0',\n * })(ctx => async (order: Order) => {\n *   ctx.recordStepProgress('ValidateOrder', 0);\n *   await validateOrder(order);\n *\n *   ctx.recordStepProgress('ReserveInventory', 1);\n *   await publishToInventoryService(order);\n *\n *   return { workflowId: ctx.workflowId, status: 'started' };\n * });\n * ```\n */\nexport function traceDistributedWorkflow<TArgs extends unknown[], TReturn>(\n  config: DistributedWorkflowConfig,\n) {\n  const spanName = `workflow.${config.name}`;\n\n  return (\n    fnFactory: (\n      ctx: DistributedWorkflowContext,\n    ) => (...args: TArgs) => Promise<TReturn>,\n  ): ((...args: TArgs) => Promise<TReturn>) => {\n    return trace<TArgs, TReturn>(\n      { name: spanName, spanKind: SpanKind.INTERNAL },\n      (baseCtx) => {\n        return async (...args: TArgs) => {\n          // Extract workflow ID from arguments (spread to allow multi-arg access)\n          const workflowId = config.workflowIdFrom(...args);\n          const startedAt = new Date().toISOString();\n\n          // Initialize workflow baggage\n          const baggageValues: WorkflowBaggageValues = {\n            workflowId,\n            workflowName: config.name,\n            workflowVersion: config.version,\n            stepIndex: 0,\n            totalSteps: config.totalSteps,\n            parentWorkflowId: config.parentWorkflowId,\n            correlationId: config.correlationId,\n            priority: config.priority,\n            initiatedBy: config.initiatedBy,\n            startedAt,\n          };\n\n          // Set baggage\n          WorkflowBaggage.set(baseCtx, baggageValues);\n\n          // Set span attributes\n          baseCtx.setAttribute('workflow.id', workflowId);\n          baseCtx.setAttribute('workflow.name', config.name);\n          if (config.version) {\n            baseCtx.setAttribute('workflow.version', config.version);\n          }\n          if (config.totalSteps) {\n            baseCtx.setAttribute('workflow.total_steps', config.totalSteps);\n          }\n          if (config.parentWorkflowId) {\n            baseCtx.setAttribute('workflow.parent_id', config.parentWorkflowId);\n          }\n          if (config.priority) {\n            baseCtx.setAttribute('workflow.priority', config.priority);\n          }\n          if (config.initiatedBy) {\n            baseCtx.setAttribute('workflow.initiated_by', config.initiatedBy);\n          }\n          baseCtx.setAttribute('workflow.started_at', startedAt);\n\n          // Apply custom attributes\n          if (config.attributes) {\n            for (const [key, value] of Object.entries(config.attributes)) {\n              baseCtx.setAttribute(key, value);\n            }\n          }\n\n          // Create extended context\n          const workflowCtx: DistributedWorkflowContext = {\n            ...baseCtx,\n            workflowId,\n            workflowName: config.name,\n            workflowVersion: config.version,\n\n            getWorkflowBaggage(): WorkflowBaggageValues {\n              return { ...baggageValues };\n            },\n\n            setWorkflowBaggage(values: Partial<WorkflowBaggageValues>): void {\n              Object.assign(baggageValues, values);\n              WorkflowBaggage.set(baseCtx, baggageValues);\n            },\n\n            getWorkflowHeaders(): Record<string, string> {\n              const headers: Record<string, string> = {};\n              const ctx = context.active();\n              propagation.inject(ctx, headers);\n              return headers;\n            },\n\n            recordStepProgress(stepName: string, stepIndex: number): void {\n              baggageValues.stepName = stepName;\n              baggageValues.stepIndex = stepIndex;\n              WorkflowBaggage.set(baseCtx, baggageValues);\n\n              emitCorrelatedEvent(baseCtx, 'workflow.step_progress', {\n                'workflow.step.name': stepName,\n                'workflow.step.index': stepIndex,\n              });\n            },\n          };\n\n          // Call onStart callback\n          config.onStart?.(workflowCtx);\n\n          // Add start event\n          emitCorrelatedEvent(baseCtx, 'workflow.started', {\n            'workflow.id': workflowId,\n            'workflow.name': config.name,\n          });\n\n          try {\n            const userFn = fnFactory(workflowCtx);\n            const result = await userFn(...args);\n\n            // Call onComplete callback\n            config.onComplete?.(workflowCtx, result);\n\n            // Add completion event\n            emitCorrelatedEvent(baseCtx, 'workflow.completed', {\n              'workflow.id': workflowId,\n            });\n\n            return result;\n          } catch (error) {\n            // Call onError callback\n            config.onError?.(workflowCtx, error as Error);\n\n            // Add error event\n            emitCorrelatedEvent(baseCtx, 'workflow.failed', {\n              'workflow.id': workflowId,\n              'workflow.error': (error as Error).message,\n            });\n\n            throw error;\n          }\n        };\n      },\n    );\n  };\n}\n\n// ============================================================================\n// Distributed Step Tracer\n// ============================================================================\n\n/**\n * Create a traced distributed workflow step\n *\n * Use in downstream services to trace steps that are part of a distributed workflow.\n * Automatically extracts workflow baggage from the current context.\n *\n * @param config - Step configuration\n * @returns Factory function for the step handler\n *\n * @example Consumer in downstream service\n * ```typescript\n * export const processInventory = traceConsumer({\n *   system: 'kafka',\n *   destination: 'inventory-requests',\n *   extractBaggage: true,  // Extracts workflow.* from headers\n * })(ctx => {\n *   // Wrap inner logic with traceDistributedStep\n *   return traceDistributedStep({\n *     name: 'ReserveInventory',\n *   })(stepCtx => async (message) => {\n *     console.log(`Processing workflow ${stepCtx.workflowId}`);\n *     await reserveItems(message.items);\n *   })(message);\n * });\n * ```\n *\n * @example Standalone step handler\n * ```typescript\n * export const reserveInventory = traceDistributedStep({\n *   name: 'ReserveInventory',\n *   idempotent: true,\n * })(ctx => async (request: InventoryRequest) => {\n *   if (ctx.workflowId) {\n *     console.log(`Part of workflow ${ctx.workflowId}, step ${ctx.stepIndex}`);\n *   }\n *   return await inventoryService.reserve(request.items);\n * });\n * ```\n */\nexport function traceDistributedStep<TArgs extends unknown[], TReturn>(\n  config: DistributedStepConfig,\n) {\n  const spanName = `workflow.step.${config.name}`;\n\n  return (\n    fnFactory: (\n      ctx: DistributedStepContext,\n    ) => (...args: TArgs) => Promise<TReturn>,\n  ): ((...args: TArgs) => Promise<TReturn>) => {\n    return trace<TArgs, TReturn>(\n      { name: spanName, spanKind: SpanKind.INTERNAL },\n      (baseCtx) => {\n        return async (...args: TArgs) => {\n          // Extract workflow baggage\n          let baggageValues: WorkflowBaggageValues | null = null;\n\n          const extractBaggage = config.extractBaggage ?? true;\n          if (typeof extractBaggage === 'function') {\n            baggageValues = extractBaggage(args);\n          } else if (extractBaggage) {\n            // Read from current context\n            const extracted = WorkflowBaggage.get(baseCtx);\n            if (extracted.workflowId && extracted.workflowName) {\n              baggageValues = extracted as WorkflowBaggageValues;\n            }\n          }\n\n          // Determine step index\n          // If explicit stepIndex provided in config, use it\n          // Otherwise, auto-increment from baggage if available\n          let stepIndex: number | null;\n          if (config.stepIndex !== undefined) {\n            stepIndex = config.stepIndex;\n          } else if (baggageValues?.stepIndex === undefined) {\n            stepIndex = null;\n          } else {\n            // Auto-increment from previous step\n            stepIndex = baggageValues.stepIndex + 1;\n          }\n\n          // Update baggage with current step\n          if (baggageValues) {\n            baggageValues.stepName = config.name;\n            if (stepIndex !== null) {\n              baggageValues.stepIndex = stepIndex;\n            }\n            WorkflowBaggage.set(baseCtx, baggageValues);\n          }\n\n          // Set span attributes\n          baseCtx.setAttribute('workflow.step.name', config.name);\n          if (stepIndex !== null) {\n            baseCtx.setAttribute('workflow.step.index', stepIndex);\n          }\n          if (config.idempotent !== undefined) {\n            baseCtx.setAttribute('workflow.step.idempotent', config.idempotent);\n          }\n          if (config.isCompensation) {\n            baseCtx.setAttribute('workflow.step.is_compensation', true);\n          }\n\n          // Add workflow context attributes if available\n          if (baggageValues) {\n            baseCtx.setAttribute('workflow.id', baggageValues.workflowId);\n            baseCtx.setAttribute('workflow.name', baggageValues.workflowName);\n            if (baggageValues.workflowVersion) {\n              baseCtx.setAttribute(\n                'workflow.version',\n                baggageValues.workflowVersion,\n              );\n            }\n            if (baggageValues.totalSteps) {\n              baseCtx.setAttribute(\n                'workflow.total_steps',\n                baggageValues.totalSteps,\n              );\n            }\n          }\n\n          // Apply custom attributes\n          if (config.attributes) {\n            for (const [key, value] of Object.entries(config.attributes)) {\n              baseCtx.setAttribute(key, value);\n            }\n          }\n\n          // Compensation data storage\n          let compensationData: Record<string, unknown> | undefined;\n\n          // Create extended context\n          const stepCtx: DistributedStepContext = {\n            ...baseCtx,\n            workflowId: baggageValues?.workflowId ?? null,\n            workflowName: baggageValues?.workflowName ?? null,\n            stepName: config.name,\n            stepIndex,\n            isCompensation: config.isCompensation ?? false,\n\n            getWorkflowBaggage(): WorkflowBaggageValues | null {\n              return baggageValues ? { ...baggageValues } : null;\n            },\n\n            updateWorkflowBaggage(\n              values: Partial<WorkflowBaggageValues>,\n            ): void {\n              if (baggageValues) {\n                Object.assign(baggageValues, values);\n                WorkflowBaggage.set(baseCtx, baggageValues);\n              }\n            },\n\n            getWorkflowHeaders(): Record<string, string> {\n              const headers: Record<string, string> = {};\n              const ctx = context.active();\n              propagation.inject(ctx, headers);\n              return headers;\n            },\n\n            requiresCompensation(data?: Record<string, unknown>): void {\n              compensationData = data;\n              baseCtx.setAttribute('workflow.step.requires_compensation', true);\n              emitCorrelatedEvent(\n                baseCtx,\n                'workflow.step.compensation_registered',\n                {\n                  'workflow.step.name': config.name,\n                  ...(data && {\n                    'workflow.step.compensation_data': JSON.stringify(data),\n                  }),\n                },\n              );\n            },\n          };\n\n          // Call onStart callback\n          config.onStart?.(stepCtx);\n\n          // Add start event\n          emitCorrelatedEvent(baseCtx, 'workflow.step.started', {\n            'workflow.step.name': config.name,\n            ...(baggageValues && { 'workflow.id': baggageValues.workflowId }),\n          });\n\n          try {\n            const userFn = fnFactory(stepCtx);\n            const result = await userFn(...args);\n\n            // Call onComplete callback\n            config.onComplete?.(stepCtx, result);\n\n            // Add completion event\n            emitCorrelatedEvent(baseCtx, 'workflow.step.completed', {\n              'workflow.step.name': config.name,\n            });\n\n            return result;\n          } catch (error) {\n            // Call onError callback\n            config.onError?.(stepCtx, error as Error);\n\n            // Add error event with compensation info if registered\n            emitCorrelatedEvent(baseCtx, 'workflow.step.failed', {\n              'workflow.step.name': config.name,\n              'workflow.step.error': (error as Error).message,\n              ...(compensationData && {\n                'workflow.step.requires_compensation': true,\n              }),\n            });\n\n            throw error;\n          }\n        };\n      },\n    );\n  };\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Generate a unique workflow ID\n *\n * @param prefix - Optional prefix for the ID\n * @returns A unique workflow ID\n *\n * @example\n * ```typescript\n * const workflowId = generateWorkflowId('order'); // \"order-abc123def456\"\n * ```\n */\nexport function generateWorkflowId(prefix?: string): string {\n  const random = Math.random().toString(36).slice(2, 15);\n  const timestamp = Date.now().toString(36);\n  const id = `${timestamp}-${random}`;\n  return prefix ? `${prefix}-${id}` : id;\n}\n\n/**\n * Check if the current context is part of a distributed workflow\n *\n * @param ctx - The trace context\n * @returns True if workflow baggage is present\n */\nexport function isInDistributedWorkflow(ctx: TraceContext): boolean {\n  const baggage = WorkflowBaggage.get(ctx);\n  return !!(baggage.workflowId && baggage.workflowName);\n}\n\n/**\n * Get workflow progress information\n *\n * @param ctx - The trace context\n * @returns Progress info or null if not in a workflow\n */\nexport function getWorkflowProgress(ctx: TraceContext): {\n  workflowId: string;\n  workflowName: string;\n  currentStep: string | null;\n  currentStepIndex: number | null;\n  totalSteps: number | null;\n  percentComplete: number | null;\n} | null {\n  const baggage = WorkflowBaggage.get(ctx);\n  if (!baggage.workflowId || !baggage.workflowName) {\n    return null;\n  }\n\n  const percentComplete =\n    baggage.totalSteps && baggage.stepIndex !== undefined\n      ? Math.round(((baggage.stepIndex + 1) / baggage.totalSteps) * 100)\n      : null;\n\n  return {\n    workflowId: baggage.workflowId,\n    workflowName: baggage.workflowName,\n    currentStep: baggage.stepName ?? null,\n    currentStepIndex: baggage.stepIndex ?? null,\n    totalSteps: baggage.totalSteps ?? null,\n    percentComplete,\n  };\n}\n\n/**\n * Create workflow correlation headers for manual propagation\n *\n * Use when you need to manually add workflow context to outgoing requests.\n *\n * @param values - Workflow baggage values\n * @returns Headers object with workflow baggage\n *\n * @example\n * ```typescript\n * const headers = createWorkflowHeaders({\n *   workflowId: 'order-123',\n *   workflowName: 'OrderFulfillment',\n *   stepIndex: 2,\n * });\n *\n * await fetch('/api/inventory', { headers });\n * ```\n */\nexport function createWorkflowHeaders(\n  values: Partial<WorkflowBaggageValues>,\n): Record<string, string> {\n  const headers: Record<string, string> = {};\n\n  // Build baggage string\n  const baggageEntries: string[] = [];\n\n  if (values.workflowId) {\n    baggageEntries.push(\n      `workflow.workflowId=${encodeURIComponent(values.workflowId)}`,\n    );\n  }\n  if (values.workflowName) {\n    baggageEntries.push(\n      `workflow.workflowName=${encodeURIComponent(values.workflowName)}`,\n    );\n  }\n  if (values.workflowVersion) {\n    baggageEntries.push(\n      `workflow.workflowVersion=${encodeURIComponent(values.workflowVersion)}`,\n    );\n  }\n  if (values.stepName) {\n    baggageEntries.push(\n      `workflow.stepName=${encodeURIComponent(values.stepName)}`,\n    );\n  }\n  if (values.stepIndex !== undefined) {\n    baggageEntries.push(`workflow.stepIndex=${values.stepIndex}`);\n  }\n  if (values.totalSteps !== undefined) {\n    baggageEntries.push(`workflow.totalSteps=${values.totalSteps}`);\n  }\n  if (values.priority) {\n    baggageEntries.push(`workflow.priority=${values.priority}`);\n  }\n  if (values.correlationId) {\n    baggageEntries.push(\n      `workflow.correlationId=${encodeURIComponent(values.correlationId)}`,\n    );\n  }\n  if (values.parentWorkflowId) {\n    baggageEntries.push(\n      `workflow.parentWorkflowId=${encodeURIComponent(values.parentWorkflowId)}`,\n    );\n  }\n  if (values.initiatedBy) {\n    baggageEntries.push(\n      `workflow.initiatedBy=${encodeURIComponent(values.initiatedBy)}`,\n    );\n  }\n  if (values.startedAt) {\n    baggageEntries.push(\n      `workflow.startedAt=${encodeURIComponent(values.startedAt)}`,\n    );\n  }\n\n  if (baggageEntries.length > 0) {\n    headers['baggage'] = baggageEntries.join(',');\n  }\n\n  return headers;\n}\n\n/**\n * Parse workflow context from baggage header\n *\n * @param baggageHeader - The baggage header value\n * @returns Parsed workflow values or null\n */\nexport function parseWorkflowFromBaggage(\n  baggageHeader: string,\n): Partial<WorkflowBaggageValues> | null {\n  if (!baggageHeader) {\n    return null;\n  }\n\n  const values: Partial<WorkflowBaggageValues> = {};\n  const entries = baggageHeader.split(',');\n\n  for (const entry of entries) {\n    const [key, value] = entry.trim().split('=');\n    if (!key || !value) continue;\n\n    const decodedValue = decodeURIComponent(value);\n\n    switch (key) {\n      case 'workflow.workflowId': {\n        values.workflowId = decodedValue;\n        break;\n      }\n      case 'workflow.workflowName': {\n        values.workflowName = decodedValue;\n        break;\n      }\n      case 'workflow.workflowVersion': {\n        values.workflowVersion = decodedValue;\n        break;\n      }\n      case 'workflow.stepName': {\n        values.stepName = decodedValue;\n        break;\n      }\n      case 'workflow.stepIndex': {\n        values.stepIndex = Number.parseInt(decodedValue, 10);\n        break;\n      }\n      case 'workflow.totalSteps': {\n        values.totalSteps = Number.parseInt(decodedValue, 10);\n        break;\n      }\n      case 'workflow.priority': {\n        values.priority = decodedValue as WorkflowBaggageValues['priority'];\n        break;\n      }\n      case 'workflow.correlationId': {\n        values.correlationId = decodedValue;\n        break;\n      }\n      case 'workflow.parentWorkflowId': {\n        values.parentWorkflowId = decodedValue;\n        break;\n      }\n      case 'workflow.initiatedBy': {\n        values.initiatedBy = decodedValue;\n        break;\n      }\n      case 'workflow.startedAt': {\n        values.startedAt = decodedValue;\n        break;\n      }\n    }\n  }\n\n  return Object.keys(values).length > 0 ? values : null;\n}\n"],"mappings":"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"}