UNPKG

nestjs-temporal-core

Version:

Complete NestJS integration for Temporal.io with auto-discovery, declarative scheduling, enhanced monitoring, and enterprise-ready features

204 lines 8.71 kB
"use strict"; var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; var __param = (this && this.__param) || function (paramIndex, decorator) { return function (target, key) { decorator(target, key, paramIndex); } }; var TemporalScheduleService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.TemporalScheduleService = void 0; const common_1 = require("@nestjs/common"); const constants_1 = require("../constants"); const logger_1 = require("../utils/logger"); let TemporalScheduleService = TemporalScheduleService_1 = class TemporalScheduleService { constructor(client, options) { this.client = client; this.options = options; this.scheduleClient = null; this.logger = (0, logger_1.createLogger)(TemporalScheduleService_1.name); } async onModuleInit() { if (!this.client) { this.logger.warn('Temporal client not initialized - schedule features will be unavailable'); return; } try { if (typeof this.client.schedule === 'undefined') { this.logger.warn('Schedule client not available in this Temporal SDK version'); return; } this.scheduleClient = this.client.schedule; this.logger.log('Temporal schedule client initialized'); } catch (error) { this.logger.error('Failed to initialize schedule client', error); } } async createCronSchedule(scheduleId, workflowType, cronExpression, taskQueue, args = [], options) { this.ensureClientInitialized(); try { const scheduleSpec = { cronExpressions: [cronExpression], ...(options?.timezone && { timeZone: options.timezone }), }; const handle = await this.scheduleClient.create({ scheduleId, spec: scheduleSpec, action: { type: 'startWorkflow', workflowType, taskQueue, args, workflowId: this.generateScheduledWorkflowId(scheduleId), }, ...(options?.description && { memo: { description: options.description } }), policies: { ...(options?.overlapPolicy && { overlap: options.overlapPolicy }), }, state: { paused: options?.startPaused || false, }, }); this.logger.log(`Created cron schedule: ${scheduleId} -> ${workflowType} (${cronExpression})${options?.timezone ? ` in ${options.timezone}` : ''}`); return handle; } catch (error) { const errorMsg = `Failed to create cron schedule '${scheduleId}': ${error.message}`; this.logger.error(errorMsg); throw new Error(errorMsg); } } async createIntervalSchedule(scheduleId, workflowType, interval, taskQueue, args = [], options) { this.ensureClientInitialized(); try { const handle = await this.scheduleClient.create({ scheduleId, spec: { intervals: [{ every: interval }], }, action: { type: 'startWorkflow', workflowType, taskQueue, args, workflowId: this.generateScheduledWorkflowId(scheduleId), }, ...(options?.description && { memo: { description: options.description } }), policies: { ...(options?.overlapPolicy && { overlap: options.overlapPolicy }), }, state: { paused: options?.startPaused || false, }, }); this.logger.log(`Created interval schedule: ${scheduleId} -> ${workflowType} (${interval})`); return handle; } catch (error) { const errorMsg = `Failed to create interval schedule '${scheduleId}': ${error.message}`; this.logger.error(errorMsg); throw new Error(errorMsg); } } async pauseSchedule(scheduleId, note) { await this.executeScheduleOperation(scheduleId, 'pause', (handle) => handle.pause(note || 'Paused via NestJS Temporal integration')); } async resumeSchedule(scheduleId, note) { await this.executeScheduleOperation(scheduleId, 'resume', (handle) => handle.unpause(note || 'Resumed via NestJS Temporal integration')); } async deleteSchedule(scheduleId) { await this.executeScheduleOperation(scheduleId, 'delete', (handle) => handle.delete()); } async triggerSchedule(scheduleId, overlapPolicy = 'ALLOW_ALL') { await this.executeScheduleOperation(scheduleId, 'trigger', (handle) => handle.trigger(overlapPolicy)); } async updateSchedule(scheduleId, updateFn) { await this.executeScheduleOperation(scheduleId, 'update', (handle) => handle.update(updateFn)); } async listSchedules(pageSize = 100) { this.ensureClientInitialized(); try { const schedules = []; for await (const schedule of this.scheduleClient.list({ pageSize })) { schedules.push(schedule); } return schedules; } catch (error) { const errorMsg = `Failed to list schedules: ${error.message}`; this.logger.error(errorMsg); throw new Error(errorMsg); } } async describeSchedule(scheduleId) { this.ensureClientInitialized(); try { const handle = await this.scheduleClient.getHandle(scheduleId); return await handle.describe(); } catch (error) { const errorMsg = `Failed to describe schedule '${scheduleId}': ${error.message}`; this.logger.error(errorMsg); throw new Error(errorMsg); } } async scheduleExists(scheduleId) { try { const schedules = await this.listSchedules(); return schedules.some((s) => s.scheduleId === scheduleId); } catch (error) { this.logger.warn(`Failed to check if schedule exists: ${error.message}`); return false; } } getScheduleClient() { return this.scheduleClient; } isHealthy() { return Boolean(this.scheduleClient); } getStatus() { return { available: Boolean(this.client), healthy: this.isHealthy(), schedulesSupported: Boolean(this.scheduleClient), }; } async executeScheduleOperation(scheduleId, operation, action) { this.ensureClientInitialized(); try { const handle = await this.scheduleClient.getHandle(scheduleId); await action(handle); this.logger.log(`Successfully ${operation}d schedule: ${scheduleId}`); } catch (error) { const errorMsg = `Failed to ${operation} schedule '${scheduleId}': ${error.message}`; this.logger.error(errorMsg); throw new Error(errorMsg); } } ensureClientInitialized() { if (!this.scheduleClient) { throw new Error(constants_1.ERRORS.SCHEDULE_CLIENT_NOT_INITIALIZED); } } generateScheduledWorkflowId(scheduleId) { return `${scheduleId}-${Date.now()}`; } }; exports.TemporalScheduleService = TemporalScheduleService; exports.TemporalScheduleService = TemporalScheduleService = TemporalScheduleService_1 = __decorate([ (0, common_1.Injectable)(), __param(0, (0, common_1.Inject)(constants_1.TEMPORAL_CLIENT)), __param(1, (0, common_1.Inject)(constants_1.TEMPORAL_MODULE_OPTIONS)), __metadata("design:paramtypes", [Object, Object]) ], TemporalScheduleService); //# sourceMappingURL=temporal-schedule.service.js.map