nestjs-temporal-core
Version:
Complete NestJS integration for Temporal.io with auto-discovery, declarative scheduling, enhanced monitoring, and enterprise-ready features
861 lines (860 loc) • 25.1 kB
TypeScript
export { RetryPolicy, Duration, SearchAttributes } from '@temporalio/common';
export { WorkflowHandle, WorkflowUpdateHandle, Client, ConnectionOptions as TemporalConnectionOptions, WorkflowIdReusePolicy, FullActivityId, ActivityOptions as StandaloneActivityOptions, ActivityHandle, ActivityExecutionInfo, CountActivityExecutions, } from '@temporalio/client';
export type { UpdateDefinition } from '@temporalio/common';
export { Worker } from '@temporalio/worker';
export type { Workflow, WorkflowResultType } from '@temporalio/workflow';
import { Type } from '@nestjs/common';
import { ScheduleClient, ScheduleHandle, WorkflowHandle, ScheduleOptions as SdkScheduleOptions, ScheduleSpec as SdkScheduleSpec, ScheduleOptionsAction, ScheduleOptionsStartWorkflowAction, ScheduleDescription as SdkScheduleDescription, ScheduleSummary, ScheduleUpdateOptions, ListScheduleOptions, ClientInterceptors, ScheduleOverlapPolicy, WorkflowOptions as SdkWorkflowOptions } from '@temporalio/client';
import { NativeConnection, Worker, WorkerOptions, WorkflowBundleOption, GrpcCompressionConfig } from '@temporalio/worker';
import { Duration, RetryPolicy, TypedSearchAttributes } from '@temporalio/common';
import { TLSConfig } from '@temporalio/common/lib/internal-non-workflow';
import type { Workflow } from '@temporalio/workflow';
export interface WorkflowProxyConfig {
workflowType: string;
taskQueue?: string;
}
export interface ClientConnectionOptions {
address: string;
tls?: boolean | TLSConfig;
metadata?: Record<string, string>;
apiKey?: string;
namespace?: string;
interceptors?: ClientInterceptors;
grpcCompression?: GrpcCompressionConfig;
}
export type ConnectionOptions = import('@temporalio/client').ConnectionOptions;
export interface RetryPolicyConfig {
maximumAttempts: number;
initialInterval: Duration;
maximumInterval: Duration;
backoffCoefficient: number;
}
export interface WorkerDefinition {
taskQueue: string;
workflowsPath?: string;
workflowBundle?: WorkflowBundleOption | Record<string, unknown>;
activityClasses?: Array<Type<object>>;
autoStart?: boolean;
autoRestart?: boolean;
maxRestarts?: number;
workerOptions?: WorkerCreateOptions;
}
export interface TemporalOptions extends LoggerConfig {
connection?: ClientConnectionOptions;
taskQueue?: string;
worker?: Omit<WorkerDefinition, 'taskQueue'>;
workers?: WorkerDefinition[];
autoRestart?: boolean;
maxRestarts?: number;
isGlobal?: boolean;
allowConnectionFailure?: boolean;
enableShutdownHooks?: boolean;
shutdownTimeout?: number;
}
export type WorkerCreateOptions = Omit<WorkerOptions, 'connection' | 'taskQueue' | 'activities' | 'workflowsPath' | 'workflowBundle' | 'namespace'> & {
enableSDKTracing?: boolean;
enableOpenTelemetry?: boolean;
};
export interface WorkerModuleOptions {
connection?: {
address?: string;
namespace?: string;
tls?: boolean | object;
apiKey?: string;
metadata?: Record<string, string>;
};
taskQueue?: string;
workflowsPath?: string;
workflowBundle?: Record<string, unknown>;
activityClasses?: Array<Type<object>>;
autoStart?: boolean;
autoRestart?: boolean;
allowWorkerFailure?: boolean;
workerOptions?: WorkerCreateOptions;
enableLogger?: boolean;
logLevel?: LogLevel;
}
export type LogLevel = 'error' | 'warn' | 'info' | 'debug' | 'verbose';
export interface GlobalLoggerConfig extends LoggerConfig {
appName?: string;
formatter?: (level: string, message: string, context: string, timestamp: string) => string;
logToFile?: boolean;
logFilePath?: string;
}
export interface LoggerConfig {
enableLogger?: boolean;
logLevel?: LogLevel;
muteErrors?: boolean;
}
export interface TemporalOptionsFactory {
createTemporalOptions(): Promise<TemporalOptions> | TemporalOptions;
}
export interface TemporalAsyncOptions {
useExisting?: Type<TemporalOptionsFactory>;
useClass?: Type<TemporalOptionsFactory>;
useFactory?: (...args: unknown[]) => Promise<TemporalOptions> | TemporalOptions;
inject?: Array<string | symbol | Type<unknown>>;
imports?: Array<Type<unknown>>;
isGlobal?: boolean;
}
export interface ActivityMethodMetadata {
name: string;
originalName: string;
options?: Record<string, string | number | boolean | object>;
handler: ActivityMethodHandler;
}
export interface ActivityMethodOptions {
name?: string;
timeout?: string | number;
maxRetries?: number;
}
export interface ActivityMetadata {
name?: string;
options?: Record<string, string | number | boolean | object>;
}
export interface ActivityOptions {
name?: string;
}
export interface DiscoveryStats {
controllers: number;
methods: number;
signals: number;
queries: number;
workflows: number;
childWorkflows: number;
}
export interface QueryMethodInfo {
methodName: string;
queryName: string;
options: QueryOptions;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
}
export interface QueryOptions {
name?: string;
}
export interface SignalMethodInfo {
methodName: string;
signalName: string;
options?: Record<string, string | number | boolean | object>;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
}
export interface SignalOptions {
name?: string;
}
export interface UpdateMethodInfo {
methodName: string;
updateName: string;
options?: Record<string, string | number | boolean | object>;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
}
export interface UpdateOptions {
name?: string;
}
export interface StartWorkflowOptions {
taskQueue: string;
workflowId?: string;
signal?: WorkflowSignalConfig;
[key: string]: unknown;
}
export interface SystemStatus {
client: {
available: boolean;
healthy: boolean;
};
worker: {
available: boolean;
status?: WorkerStatus;
health?: string;
};
discovery: DiscoveryStats;
}
export interface WorkerStatus {
isInitialized: boolean;
isRunning: boolean;
isHealthy: boolean;
taskQueue: string;
namespace: string;
workflowSource: 'bundle' | 'filesystem' | 'registered' | 'none';
activitiesCount: number;
workflowsCount?: number;
lastError?: string;
startedAt?: Date;
uptime?: number;
}
export interface MultipleWorkersInfo {
workers: Map<string, WorkerStatus>;
totalWorkers: number;
runningWorkers: number;
healthyWorkers: number;
}
export interface CreateWorkerResult {
success: boolean;
taskQueue: string;
error?: Error;
worker?: Worker;
}
export interface WorkerInstance {
worker: Worker;
taskQueue: string;
namespace: string;
isRunning: boolean;
isInitialized: boolean;
lastError: string | null;
startedAt: Date | null;
restartCount: number;
activities: Map<string, Function>;
workflowSource: 'bundle' | 'filesystem' | 'registered' | 'none';
}
export interface SignalMethodMetadata {
signalName: string;
methodName: string;
}
export interface QueryMethodMetadata {
queryName: string;
methodName: string;
}
export interface UpdateMethodMetadata {
updateName: string;
methodName: string;
}
export interface ChildWorkflowMetadata {
workflowType: string | Type<unknown>;
options?: Record<string, string | number | boolean | object>;
propertyKey: string | symbol;
}
export type ActivityMethodHandler = (...args: unknown[]) => Promise<unknown> | unknown;
export type QueryMethodHandler = (...args: unknown[]) => unknown;
export type SignalMethodHandler = (...args: unknown[]) => void | Promise<void>;
export type UpdateMethodHandler = (...args: unknown[]) => unknown | Promise<unknown>;
export interface ActivityModuleOptions extends LoggerConfig {
activityClasses?: Array<Type<unknown>>;
timeout?: string | number;
global?: boolean;
}
export interface ActivityInfo {
className: string;
instance: Record<string, unknown>;
targetClass: Type<unknown>;
methods: Array<{
name: string;
methodName: string;
options: ActivityMethodOptions;
}>;
totalMethods: number;
}
export interface ExtendedSignalMethodInfo {
className: string;
signalName: string;
methodName: string;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
instance: Record<string, unknown>;
}
export interface ExtendedQueryMethodInfo {
className: string;
queryName: string;
methodName: string;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
instance: Record<string, unknown>;
options?: Record<string, string | number | boolean | object>;
}
export interface ExtendedUpdateMethodInfo {
className: string;
updateName: string;
methodName: string;
handler: (...args: unknown[]) => unknown | Promise<unknown>;
instance: Record<string, unknown>;
options?: Record<string, string | number | boolean | object>;
}
export interface ChildWorkflowInfo {
className: string;
propertyKey: string | symbol;
workflowType: Type<unknown>;
options?: Record<string, string | number | boolean | object>;
instance: Record<string, unknown>;
}
export type ActivityFunction = (...args: unknown[]) => unknown | Promise<unknown>;
export interface ActivityMethodInfo {
methodName: string;
name: string;
metadata: ActivityMethodOptions;
}
export interface ActivityContext {
activityType: string;
className?: string;
methodName?: string;
executionId?: string;
timestamp?: Date;
}
export type ScheduleSpec = Omit<SdkScheduleSpec, 'intervals' | 'jitter'> & {
intervals?: Array<{
every: Duration | string | number;
offset?: Duration | string | number;
}>;
jitter?: Duration | string | number;
timezones?: string[];
};
export type ScheduleAction = ScheduleOptionsAction & {
retryPolicy?: RetryPolicy | Record<string, unknown>;
};
export interface WorkflowStartOptions extends Omit<Partial<SdkWorkflowOptions>, 'searchAttributes'> {
searchAttributes?: TypedSearchAttributes;
retryPolicy?: RetryPolicy;
}
export type HealthStatus = 'healthy' | 'unhealthy' | 'degraded';
export interface ServiceHealth {
status: HealthStatus;
details?: Record<string, string | number | boolean | object>;
timestamp?: Date;
}
export interface ServiceStats {
activities: {
classes: number;
methods: number;
total: number;
};
schedules: number;
discoveries: DiscoveryStats;
worker: WorkerStatus;
client: ServiceHealth;
}
export type OverlapPolicy = 'skip' | 'buffer_one' | 'buffer_all' | 'cancel_other' | 'terminate_other' | 'allow_all';
export type TemporalOverlapPolicy = ScheduleOverlapPolicy;
export interface MetadataInfo {
[key: string]: string | number | boolean | object | null;
}
export type ActivityWrapper = (...args: unknown[]) => Promise<unknown>;
export interface ProviderInstance {
[key: string]: string | number | boolean | object | null | undefined;
}
export interface NestJSWrapper {
instance?: Record<string, unknown>;
metatype?: new (...args: unknown[]) => Record<string, unknown>;
}
export interface InstanceWithConstructor {
constructor: new (...args: unknown[]) => Record<string, unknown>;
}
export interface DiscoveredActivity {
name: string;
className: string;
method: ActivityMethodInfo | ActivityMethodHandler;
instance: Record<string, unknown>;
handler: ActivityMethodHandler;
}
export interface WorkflowSignalConfig {
name: string;
args?: unknown[];
}
export type WorkflowHandleWithMetadata<T extends Workflow = Workflow> = WorkflowHandle<T> & {
handle: WorkflowHandle<T>;
};
export interface ClientServiceStatus {
available: boolean;
healthy: boolean;
initialized: boolean;
lastHealthCheck: Date | null;
namespace: string;
}
export type ClientHealthStatus = Pick<ServiceHealth, 'status'>;
export interface GenericClient {
workflow: {
start: (type: string, options: Record<string, string | number | boolean | object>) => Promise<import('@temporalio/client').WorkflowHandle>;
getHandle: (id: string, runId?: string) => import('@temporalio/client').WorkflowHandle;
};
}
export type ScheduleDescription = SdkScheduleDescription;
export type { ScheduleSummary, ScheduleUpdateOptions, ListScheduleOptions };
export interface ScheduleListResult {
success: boolean;
schedules?: AsyncIterable<ScheduleSummary>;
error?: Error;
}
export interface DiscoveryServiceStats {
methods: number;
activities: number;
totalComponents: number;
}
export interface DiscoveryHealthStatus {
isComplete: boolean;
status: 'healthy' | 'degraded' | 'unhealthy';
discoveredItems?: {
activities: number;
};
lastDiscovery?: Date | null;
discoveryDuration?: number | null;
totalComponents?: number;
}
export interface DiscoveryServiceConfig {
enableLogging: boolean;
logLevel: LogLevel;
activityClasses: Array<Type<unknown>>;
}
export interface ComponentDiscoveryResult {
success: boolean;
discoveredCount: number;
errors: Array<{
component: string;
error: string;
}>;
duration: number;
}
export interface BaseValidationResult {
isValid: boolean;
issues: string[];
warnings?: string[];
}
export interface ActivityMethodValidationResult extends BaseValidationResult {
}
export interface DiscoveryServiceOptions {
enableLogger?: boolean;
logLevel?: LogLevel;
activityClasses?: Array<Type<unknown>>;
validateOnDiscovery?: boolean;
cacheResults?: boolean;
}
export interface WrapperProcessingResult {
success: boolean;
processedCount: number;
errors: Array<{
component: string;
error: string;
}>;
}
export interface ActivityDiscoveryContext {
className: string;
instance: Record<string, unknown>;
metatype: Type<unknown>;
validationResult?: ActivityMethodValidationResult;
}
export interface ActivityMethodMetadataResult {
name: string;
originalName: string;
methodName: string;
className: string;
options?: Record<string, unknown>;
handler?: Function;
}
export interface ActivityMetadataExtractionResult {
success: boolean;
methods: Map<string, ActivityMethodMetadataResult>;
errors: Array<{
method: string;
error: string;
}>;
extractedCount: number;
}
export interface ActivityClassValidationResult extends BaseValidationResult {
className?: string;
methodCount?: number;
}
export interface MetadataValidationResult {
isValid: boolean;
missing: string[];
present: string[];
target: string;
}
export interface ActivityInfoResult {
className: string;
isActivity: boolean;
activityName: string | null;
methodNames: string[];
metadata: unknown;
activityOptions: unknown;
methodCount: number;
}
export interface CacheStatsResult {
size: number;
entries: string[];
message?: string;
note?: string;
hitRate?: number;
missRate?: number;
}
export interface MethodExtractionResult {
success: boolean;
methods: Record<string, string>;
errors: Array<{
method: string;
error: string;
}>;
}
export type SignalMethodExtractionResult = MethodExtractionResult;
export type QueryMethodExtractionResult = MethodExtractionResult;
export type UpdateMethodExtractionResult = MethodExtractionResult;
export interface ChildWorkflowExtractionResult {
success: boolean;
workflows: Record<string, unknown>;
errors: Array<{
workflow: string;
error: string;
}>;
}
export interface MetadataExtractionOptions {
includeOptions?: boolean;
validateMethods?: boolean;
cacheResults?: boolean;
strictMode?: boolean;
}
export interface ActivityMethodExtractionContext {
instance: unknown;
className: string;
methodName: string;
prototype: object;
metadata: unknown;
}
export interface ScheduleCreationOptions {
scheduleId: string;
spec: ScheduleSpec;
action: ScheduleAction;
memo?: Record<string, unknown>;
searchAttributes?: Record<string, unknown>;
paused?: boolean;
overlapPolicy?: OverlapPolicy;
catchupWindow?: string | number;
pauseOnFailure?: boolean;
description?: string;
limitedActions?: number;
}
export interface ScheduleCreationResult {
success: boolean;
scheduleId?: string;
handle?: ScheduleHandle;
error?: Error;
}
export interface ScheduleUpsertResult extends ScheduleCreationResult {
action?: 'created' | 'updated';
}
export interface ScheduleRetrievalResult {
success: boolean;
handle?: ScheduleHandle;
error?: Error;
}
export interface ScheduleOperationResult {
success: boolean;
scheduleId: string;
error?: Error;
}
export type SchedulePauseResult = ScheduleOperationResult;
export type ScheduleUnpauseResult = ScheduleOperationResult;
export type ScheduleTriggerResult = ScheduleOperationResult;
export type ScheduleDeletionResult = ScheduleOperationResult;
export type ScheduleUpdateResult = ScheduleOperationResult;
export interface ScheduleDescribeResult {
success: boolean;
scheduleId: string;
description?: ScheduleDescription;
error?: Error;
}
export interface ScheduleServiceStatus {
available: boolean;
healthy: boolean;
schedulesSupported: boolean;
initialized: boolean;
}
export interface ScheduleServiceHealth {
status: 'healthy' | 'unhealthy' | 'degraded';
schedulesCount: number;
isInitialized: boolean;
details: Record<string, unknown>;
lastError?: string;
}
export interface ScheduleServiceStats {
total: number;
active: number;
inactive: number;
errors: number;
lastUpdated?: Date;
}
export interface ScheduleDiscoveryResult {
success: boolean;
discoveredCount: number;
errors: Array<{
schedule: string;
error: string;
}>;
duration: number;
}
export interface ScheduleRegistrationResult {
success: boolean;
scheduleId: string;
handle?: ScheduleHandle;
error?: Error;
}
export interface ScheduleMetadataValidationResult extends BaseValidationResult {
scheduleId?: string;
}
export interface ScheduleClientInitResult {
success: boolean;
client?: ScheduleClient;
error?: Error;
source: 'existing' | 'new' | 'none';
}
export interface ScheduleWorkflowOptions {
taskQueue?: string;
workflowId?: string;
workflowExecutionTimeout?: Duration;
workflowRunTimeout?: Duration;
workflowTaskTimeout?: Duration;
retryPolicy?: RetryPolicy | Record<string, unknown>;
args?: unknown[];
}
export interface ScheduleSpecBuilderResult {
success: boolean;
spec?: Partial<ScheduleSpec>;
error?: Error;
}
export interface ScheduleIntervalParseResult {
success: boolean;
interval?: {
every: Duration;
};
error?: Error;
}
export interface TemporalConnection {
address: string;
namespace?: string;
tls?: boolean | object;
metadata?: Record<string, string>;
}
export type ScheduleWorkflowAction = ScheduleOptionsStartWorkflowAction<Workflow> & {
retryPolicy?: RetryPolicy | Record<string, unknown>;
};
export type ScheduleOptions = SdkScheduleOptions;
export interface WorkerConnectionOptions {
address: string;
tls?: boolean | object;
metadata?: Record<string, string>;
apiKey?: string;
namespace?: string;
}
export type WorkerConfig = WorkerOptions & {
namespace: string;
connection: NativeConnection;
activities: Record<string, Function>;
};
export interface WorkerInitResult {
success: boolean;
worker?: Worker;
error?: Error;
activitiesCount: number;
taskQueue: string;
namespace: string;
}
export interface WorkerRestartResult {
success: boolean;
error?: Error;
restartCount: number;
maxRestarts: number;
}
export interface WorkerShutdownResult {
success: boolean;
error?: Error;
shutdownTime: number;
}
export interface WorkerHealthStatus {
isHealthy: boolean;
isRunning: boolean;
isInitialized: boolean;
lastError?: string;
uptime?: number;
activitiesCount: number;
restartCount: number;
maxRestarts: number;
}
export interface WorkerStats {
isInitialized: boolean;
isRunning: boolean;
activitiesCount: number;
restartCount: number;
maxRestarts: number;
uptime?: number;
startedAt?: Date;
lastError?: string;
taskQueue: string;
namespace: string;
workflowSource: 'bundle' | 'filesystem' | 'registered' | 'none';
}
export interface ActivityRegistrationResult {
success: boolean;
registeredCount: number;
errors: Array<{
activityName: string;
error: string;
}>;
}
export interface WorkerDiscoveryResult {
success: boolean;
discoveredActivities: number;
loadedActivities: number;
errors: Array<{
name: string;
error: string;
}>;
duration: number;
}
export interface TemporalServiceInitResult {
success: boolean;
error?: Error;
servicesInitialized: {
client: boolean;
worker: boolean;
schedule: boolean;
discovery: boolean;
metadata: boolean;
};
initializationTime: number;
}
export interface WorkflowExecutionResult<T = unknown> {
success: boolean;
result?: T;
error?: Error;
workflowId?: string;
runId?: string;
executionTime?: number;
}
export interface WorkflowSignalResult {
success: boolean;
error?: Error;
workflowId: string;
signalName: string;
}
export interface WorkflowQueryResult<T = unknown> {
success: boolean;
result?: T;
error?: Error;
workflowId: string;
queryName: string;
}
export interface WorkflowTerminationResult {
success: boolean;
error?: Error;
workflowId: string;
reason?: string;
}
export interface WorkflowCancellationResult {
success: boolean;
error?: Error;
workflowId: string;
}
export interface ActivityExecutionResult<T = unknown> {
success: boolean;
result?: T;
error?: Error;
activityName: string;
executionTime?: number;
args?: unknown[];
}
export interface ServiceHealthStatus {
status: 'healthy' | 'unhealthy' | 'degraded';
isInitialized: boolean;
lastError?: string;
uptime?: number;
details?: Record<string, unknown>;
}
export interface ComponentHealthStatus {
client: ServiceHealthStatus;
worker: ServiceHealthStatus;
schedule: ServiceHealthStatus;
activity: ServiceHealthStatus;
discovery: ServiceHealthStatus;
}
export interface OverallHealthStatus {
status: 'healthy' | 'unhealthy' | 'degraded';
components: ComponentHealthStatus;
isInitialized: boolean;
namespace: string;
summary: {
totalActivities: number;
totalSchedules: number;
workerRunning: boolean;
clientConnected: boolean;
};
timestamp: Date;
}
export interface ServiceStatistics {
activities: {
classes: number;
methods: number;
total: number;
registered: number;
available: number;
};
schedules: {
total: number;
active: number;
paused: number;
};
worker: {
isRunning: boolean;
isHealthy: boolean;
activitiesCount: number;
uptime?: number;
};
client: {
isConnected: boolean;
isHealthy: boolean;
namespace: string;
};
discovery: {
isComplete: boolean;
discoveredCount: number;
errors: number;
};
}
export interface ServiceInitOptions {
waitForServices?: boolean;
maxWaitTime?: number;
retryAttempts?: number;
retryDelay?: number;
}
export interface ServiceShutdownOptions {
graceful?: boolean;
timeout?: number;
stopWorker?: boolean;
}
export interface ServiceShutdownResult {
success: boolean;
error?: Error;
shutdownTime: number;
servicesShutdown: {
worker: boolean;
client: boolean;
schedule: boolean;
};
}
export interface HealthResponse {
status: 'healthy' | 'degraded' | 'unhealthy';
timestamp: string;
uptime: number;
client: {
available: boolean;
healthy: boolean;
connected: boolean;
};
worker: {
available: boolean;
running: boolean;
healthy: boolean;
activitiesCount: number;
};
discovery: {
activities: number;
complete: boolean;
discoveredCount: number;
};
schedules: {
total: number;
active: number;
paused: number;
};
metadata: {
classes: number;
methods: number;
total: number;
};
summary: {
totalComponents: number;
healthyComponents: number;
degradedComponents: number;
unhealthyComponents: number;
};
}