UNPKG

execution-engine

Version:

A TypeScript library for tracing and visualizing code execution workflows.

80 lines (79 loc) 3.45 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.executionTrace = executionTrace; const execute_1 = require("./execute"); const functionMetadata_1 = require("../common/utils/functionMetadata"); const safeError_1 = require("../common/utils/safeError"); const executionTimer_1 = require("../timer/executionTimer"); function calculateTimeAndDuration(executionTimer) { executionTimer.stop(); const timerDetails = executionTimer.getInfo(undefined, undefined, 3); delete timerDetails.executionId; return timerDetails; } /** * Executes a given function (`blockFunction`) while tracing its execution details, including inputs, outputs, * timing, metadata, and potential errors. Supports both synchronous and asynchronous functions. * * @template O - The return type of `blockFunction`, which can be synchronous (`O`) or a `Promise<O>`. * * @param blockFunction - The function to execute and trace. * @param inputs - An array of input parameters to pass to `blockFunction`. Defaults to an empty array. * @param onTraceEvent - An optional callback function that processes the trace context after execution. * @param options - Optional configuration: * - `contextKey`: A key to store and retrieve execution context. * - `errorStrategy`: Determines how errors are handled: * - `'catch'`: Captures errors and includes them in the trace. * - `'throw'`: Throws the error after recording it in the trace. * * @returns An Either: * - `ExecutionTrace` object containing execution details. * - If `blockFunction` is asynchronous, returns a `Promise<ExecutionTrace>`. */ function executionTrace(blockFunction, inputs = [], onTraceEvent, options = { contextKey: undefined, errorStrategy: 'throw' }) { const id = crypto.randomUUID(); const executionTimer = new executionTimer_1.ExecutionTimer(id); executionTimer?.start(); const executionTrace = { id, inputs, startTime: executionTimer.getStartDate() }; const functionMetadata = (0, functionMetadata_1.extractFunctionMetadata)(blockFunction); let traceContext = { metadata: functionMetadata, ...executionTrace }; if (this && options.contextKey) { traceContext = { ...traceContext, ...this[options.contextKey] }; this[options.contextKey] = traceContext; } return execute_1.execute.bind(this)(blockFunction.bind(this), inputs, [traceContext], function (outputs, isPromise) { const { startTime, ...traceContextWithoutStartTime } = traceContext; traceContext = { ...traceContextWithoutStartTime, outputs, isPromise, startTime, ...calculateTimeAndDuration(executionTimer) }; if (typeof onTraceEvent === 'function') { onTraceEvent(traceContext); } return traceContext; }, function (e, isPromise) { const { startTime, ...traceContextWithoutStartTime } = traceContext; traceContext = { ...traceContextWithoutStartTime, errors: [(0, safeError_1.safeError)(e)], isPromise, startTime, ...calculateTimeAndDuration(executionTimer) }; if (typeof onTraceEvent === 'function') { onTraceEvent(traceContext); } if (options?.errorStrategy === 'catch') { return traceContext; } else { throw e; } }); }