UNPKG

autotel

Version:
435 lines (432 loc) 15.2 kB
'use strict'; var chunkINJD3G4K_cjs = require('./chunk-INJD3G4K.cjs'); var chunkUTZR7P7E_cjs = require('./chunk-UTZR7P7E.cjs'); require('./chunk-GML3FBOT.cjs'); require('./chunk-D5LMF53P.cjs'); require('./chunk-JSNUWSBH.cjs'); require('./chunk-HZ3FYBJG.cjs'); require('./chunk-563EL6O6.cjs'); require('./chunk-OC6X2VIN.cjs'); require('./chunk-CEAQK2QY.cjs'); require('./chunk-ZNMBW67B.cjs'); require('./chunk-IOYFAFHJ.cjs'); require('./chunk-CMNGGTQL.cjs'); require('./chunk-CU6IDACR.cjs'); require('./chunk-6S5RUKU3.cjs'); require('./chunk-YS6C2YJE.cjs'); require('./chunk-VH77IPJN.cjs'); require('./chunk-FU6R566Y.cjs'); require('./chunk-ESLWRGAG.cjs'); require('./chunk-YREV3LGG.cjs'); require('./chunk-JEQ2X3Z6.cjs'); var api = require('@opentelemetry/api'); var workflowBaggageFields = { /** Unique identifier for the workflow instance */ workflowId: { type: "string", maxLength: 128, required: true }, /** Name/type of the workflow (e.g., "OrderFulfillment") */ workflowName: { type: "string", maxLength: 64, required: true }, /** Version of the workflow definition */ workflowVersion: { type: "string", maxLength: 32 }, /** Current step name */ stepName: { type: "string", maxLength: 64 }, /** Current step index (0-based) */ stepIndex: { type: "number" }, /** Total number of steps (if known) */ totalSteps: { type: "number" }, /** Parent workflow ID (for sub-workflows) */ parentWorkflowId: { type: "string", maxLength: 128 }, /** Correlation ID for external systems */ correlationId: { type: "string", maxLength: 128 }, /** Workflow priority */ priority: { type: "enum", values: ["low", "normal", "high", "critical"] }, /** Initiating user/system */ initiatedBy: { type: "string", maxLength: 64 }, /** Workflow start timestamp (ISO) */ startedAt: { type: "string", maxLength: 30 } }; var WorkflowBaggage = chunkINJD3G4K_cjs.createSafeBaggageSchema(workflowBaggageFields, { prefix: "workflow", hashHighCardinality: false, // Workflow IDs should be traceable redactPII: false // Workflow fields are internal identifiers }); function traceDistributedWorkflow(config) { const spanName = `workflow.${config.name}`; return (fnFactory) => { return chunkUTZR7P7E_cjs.trace( { name: spanName, spanKind: api.SpanKind.INTERNAL }, (baseCtx) => { return async (...args) => { const workflowId = config.workflowIdFrom(...args); const startedAt = (/* @__PURE__ */ new Date()).toISOString(); const baggageValues = { workflowId, workflowName: config.name, workflowVersion: config.version, stepIndex: 0, totalSteps: config.totalSteps, parentWorkflowId: config.parentWorkflowId, correlationId: config.correlationId, priority: config.priority, initiatedBy: config.initiatedBy, startedAt }; WorkflowBaggage.set(baseCtx, baggageValues); baseCtx.setAttribute("workflow.id", workflowId); baseCtx.setAttribute("workflow.name", config.name); if (config.version) { baseCtx.setAttribute("workflow.version", config.version); } if (config.totalSteps) { baseCtx.setAttribute("workflow.total_steps", config.totalSteps); } if (config.parentWorkflowId) { baseCtx.setAttribute("workflow.parent_id", config.parentWorkflowId); } if (config.priority) { baseCtx.setAttribute("workflow.priority", config.priority); } if (config.initiatedBy) { baseCtx.setAttribute("workflow.initiated_by", config.initiatedBy); } baseCtx.setAttribute("workflow.started_at", startedAt); if (config.attributes) { for (const [key, value] of Object.entries(config.attributes)) { baseCtx.setAttribute(key, value); } } const workflowCtx = { ...baseCtx, workflowId, workflowName: config.name, workflowVersion: config.version, getWorkflowBaggage() { return { ...baggageValues }; }, setWorkflowBaggage(values) { Object.assign(baggageValues, values); WorkflowBaggage.set(baseCtx, baggageValues); }, getWorkflowHeaders() { const headers = {}; const ctx = api.context.active(); api.propagation.inject(ctx, headers); return headers; }, recordStepProgress(stepName, stepIndex) { baggageValues.stepName = stepName; baggageValues.stepIndex = stepIndex; WorkflowBaggage.set(baseCtx, baggageValues); baseCtx.addEvent("workflow.step_progress", { "workflow.step.name": stepName, "workflow.step.index": stepIndex }); } }; config.onStart?.(workflowCtx); baseCtx.addEvent("workflow.started", { "workflow.id": workflowId, "workflow.name": config.name }); try { const userFn = fnFactory(workflowCtx); const result = await userFn(...args); config.onComplete?.(workflowCtx, result); baseCtx.addEvent("workflow.completed", { "workflow.id": workflowId }); return result; } catch (error) { config.onError?.(workflowCtx, error); baseCtx.addEvent("workflow.failed", { "workflow.id": workflowId, "workflow.error": error.message }); throw error; } }; } ); }; } function traceDistributedStep(config) { const spanName = `workflow.step.${config.name}`; return (fnFactory) => { return chunkUTZR7P7E_cjs.trace( { name: spanName, spanKind: api.SpanKind.INTERNAL }, (baseCtx) => { return async (...args) => { let baggageValues = null; const extractBaggage = config.extractBaggage ?? true; if (typeof extractBaggage === "function") { baggageValues = extractBaggage(args); } else if (extractBaggage) { const extracted = WorkflowBaggage.get(baseCtx); if (extracted.workflowId && extracted.workflowName) { baggageValues = extracted; } } let stepIndex; if (config.stepIndex !== void 0) { stepIndex = config.stepIndex; } else if (baggageValues?.stepIndex === void 0) { stepIndex = null; } else { stepIndex = baggageValues.stepIndex + 1; } if (baggageValues) { baggageValues.stepName = config.name; if (stepIndex !== null) { baggageValues.stepIndex = stepIndex; } WorkflowBaggage.set(baseCtx, baggageValues); } baseCtx.setAttribute("workflow.step.name", config.name); if (stepIndex !== null) { baseCtx.setAttribute("workflow.step.index", stepIndex); } if (config.idempotent !== void 0) { baseCtx.setAttribute("workflow.step.idempotent", config.idempotent); } if (config.isCompensation) { baseCtx.setAttribute("workflow.step.is_compensation", true); } if (baggageValues) { baseCtx.setAttribute("workflow.id", baggageValues.workflowId); baseCtx.setAttribute("workflow.name", baggageValues.workflowName); if (baggageValues.workflowVersion) { baseCtx.setAttribute( "workflow.version", baggageValues.workflowVersion ); } if (baggageValues.totalSteps) { baseCtx.setAttribute( "workflow.total_steps", baggageValues.totalSteps ); } } if (config.attributes) { for (const [key, value] of Object.entries(config.attributes)) { baseCtx.setAttribute(key, value); } } let compensationData; const stepCtx = { ...baseCtx, workflowId: baggageValues?.workflowId ?? null, workflowName: baggageValues?.workflowName ?? null, stepName: config.name, stepIndex, isCompensation: config.isCompensation ?? false, getWorkflowBaggage() { return baggageValues ? { ...baggageValues } : null; }, updateWorkflowBaggage(values) { if (baggageValues) { Object.assign(baggageValues, values); WorkflowBaggage.set(baseCtx, baggageValues); } }, getWorkflowHeaders() { const headers = {}; const ctx = api.context.active(); api.propagation.inject(ctx, headers); return headers; }, requiresCompensation(data) { compensationData = data; baseCtx.setAttribute("workflow.step.requires_compensation", true); baseCtx.addEvent("workflow.step.compensation_registered", { "workflow.step.name": config.name, ...data && { "workflow.step.compensation_data": JSON.stringify(data) } }); } }; config.onStart?.(stepCtx); baseCtx.addEvent("workflow.step.started", { "workflow.step.name": config.name, ...baggageValues && { "workflow.id": baggageValues.workflowId } }); try { const userFn = fnFactory(stepCtx); const result = await userFn(...args); config.onComplete?.(stepCtx, result); baseCtx.addEvent("workflow.step.completed", { "workflow.step.name": config.name }); return result; } catch (error) { config.onError?.(stepCtx, error); baseCtx.addEvent("workflow.step.failed", { "workflow.step.name": config.name, "workflow.step.error": error.message, ...compensationData && { "workflow.step.requires_compensation": true } }); throw error; } }; } ); }; } function generateWorkflowId(prefix) { const random = Math.random().toString(36).slice(2, 15); const timestamp = Date.now().toString(36); const id = `${timestamp}-${random}`; return prefix ? `${prefix}-${id}` : id; } function isInDistributedWorkflow(ctx) { const baggage = WorkflowBaggage.get(ctx); return !!(baggage.workflowId && baggage.workflowName); } function getWorkflowProgress(ctx) { const baggage = WorkflowBaggage.get(ctx); if (!baggage.workflowId || !baggage.workflowName) { return null; } const percentComplete = baggage.totalSteps && baggage.stepIndex !== void 0 ? Math.round((baggage.stepIndex + 1) / baggage.totalSteps * 100) : null; return { workflowId: baggage.workflowId, workflowName: baggage.workflowName, currentStep: baggage.stepName ?? null, currentStepIndex: baggage.stepIndex ?? null, totalSteps: baggage.totalSteps ?? null, percentComplete }; } function createWorkflowHeaders(values) { const headers = {}; const baggageEntries = []; if (values.workflowId) { baggageEntries.push( `workflow.workflowId=${encodeURIComponent(values.workflowId)}` ); } if (values.workflowName) { baggageEntries.push( `workflow.workflowName=${encodeURIComponent(values.workflowName)}` ); } if (values.workflowVersion) { baggageEntries.push( `workflow.workflowVersion=${encodeURIComponent(values.workflowVersion)}` ); } if (values.stepName) { baggageEntries.push( `workflow.stepName=${encodeURIComponent(values.stepName)}` ); } if (values.stepIndex !== void 0) { baggageEntries.push(`workflow.stepIndex=${values.stepIndex}`); } if (values.totalSteps !== void 0) { baggageEntries.push(`workflow.totalSteps=${values.totalSteps}`); } if (values.priority) { baggageEntries.push(`workflow.priority=${values.priority}`); } if (values.correlationId) { baggageEntries.push( `workflow.correlationId=${encodeURIComponent(values.correlationId)}` ); } if (values.parentWorkflowId) { baggageEntries.push( `workflow.parentWorkflowId=${encodeURIComponent(values.parentWorkflowId)}` ); } if (values.initiatedBy) { baggageEntries.push( `workflow.initiatedBy=${encodeURIComponent(values.initiatedBy)}` ); } if (values.startedAt) { baggageEntries.push( `workflow.startedAt=${encodeURIComponent(values.startedAt)}` ); } if (baggageEntries.length > 0) { headers["baggage"] = baggageEntries.join(","); } return headers; } function parseWorkflowFromBaggage(baggageHeader) { if (!baggageHeader) { return null; } const values = {}; const entries = baggageHeader.split(","); for (const entry of entries) { const [key, value] = entry.trim().split("="); if (!key || !value) continue; const decodedValue = decodeURIComponent(value); switch (key) { case "workflow.workflowId": { values.workflowId = decodedValue; break; } case "workflow.workflowName": { values.workflowName = decodedValue; break; } case "workflow.workflowVersion": { values.workflowVersion = decodedValue; break; } case "workflow.stepName": { values.stepName = decodedValue; break; } case "workflow.stepIndex": { values.stepIndex = Number.parseInt(decodedValue, 10); break; } case "workflow.totalSteps": { values.totalSteps = Number.parseInt(decodedValue, 10); break; } case "workflow.priority": { values.priority = decodedValue; break; } case "workflow.correlationId": { values.correlationId = decodedValue; break; } case "workflow.parentWorkflowId": { values.parentWorkflowId = decodedValue; break; } case "workflow.initiatedBy": { values.initiatedBy = decodedValue; break; } case "workflow.startedAt": { values.startedAt = decodedValue; break; } } } return Object.keys(values).length > 0 ? values : null; } exports.WorkflowBaggage = WorkflowBaggage; exports.createWorkflowHeaders = createWorkflowHeaders; exports.generateWorkflowId = generateWorkflowId; exports.getWorkflowProgress = getWorkflowProgress; exports.isInDistributedWorkflow = isInDistributedWorkflow; exports.parseWorkflowFromBaggage = parseWorkflowFromBaggage; exports.traceDistributedStep = traceDistributedStep; exports.traceDistributedWorkflow = traceDistributedWorkflow; //# sourceMappingURL=workflow-distributed.cjs.map //# sourceMappingURL=workflow-distributed.cjs.map