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
JavaScript
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
;