UNPKG

nestjs-temporal-core

Version:

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

191 lines 7.94 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 TemporalDiscoveryService_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.TemporalDiscoveryService = void 0; const common_1 = require("@nestjs/common"); const core_1 = require("@nestjs/core"); const constants_1 = require("../constants"); const logger_1 = require("../utils/logger"); let TemporalDiscoveryService = TemporalDiscoveryService_1 = class TemporalDiscoveryService { constructor(discoveryService, metadataScanner) { this.discoveryService = discoveryService; this.metadataScanner = metadataScanner; this.logger = (0, logger_1.createLogger)(TemporalDiscoveryService_1.name); this.scheduledWorkflows = new Map(); this.signals = new Map(); this.queries = new Map(); } async onModuleInit() { await this.discoverComponents(); } async discoverComponents() { const allWrappers = [ ...this.discoveryService.getProviders(), ...this.discoveryService.getControllers(), ]; for (const wrapper of allWrappers) { await this.processWrapper(wrapper); } this.logDiscoveryResults(); } async processWrapper(wrapper) { const { instance, metatype } = wrapper; if (!instance || !metatype) { return; } this.logger.debug(`Processing wrapper: ${metatype.name}`); await this.discoverMethods(instance); } async discoverMethods(instance) { const prototype = Object.getPrototypeOf(instance); const methodNames = this.metadataScanner .scanFromPrototype(instance, prototype, (methodName) => methodName !== 'constructor' ? methodName : null) .filter((methodName) => Boolean(methodName)); for (const methodName of methodNames) { const method = prototype[methodName]; if (!method || typeof method !== 'function') { continue; } this.categorizeMethod(instance, methodName, method); } } categorizeMethod(instance, methodName, method) { const boundMethod = method.bind(instance); const scheduleMetadata = Reflect.getMetadata(constants_1.TEMPORAL_SCHEDULED_WORKFLOW, method); if (scheduleMetadata) { const scheduledInfo = this.createScheduledMethodInfo(methodName, scheduleMetadata, boundMethod, instance); this.scheduledWorkflows.set(scheduleMetadata.scheduleId, scheduledInfo); } const signalMetadata = Reflect.getMetadata(constants_1.TEMPORAL_SIGNAL_METHOD, method); if (signalMetadata) { const signalInfo = this.createSignalMethodInfo(methodName, signalMetadata, boundMethod); this.signals.set(signalMetadata.name || methodName, signalInfo); } const queryMetadata = Reflect.getMetadata(constants_1.TEMPORAL_QUERY_METHOD, method); if (queryMetadata) { const queryInfo = this.createQueryMethodInfo(methodName, queryMetadata, boundMethod); this.queries.set(queryMetadata.name || methodName, queryInfo); } } createScheduledMethodInfo(methodName, scheduleMetadata, boundMethod, instance) { const metadata = scheduleMetadata; return { methodName, workflowName: metadata.workflowName || methodName, scheduleOptions: metadata, workflowOptions: { taskQueue: metadata.taskQueue || 'default', }, handler: boundMethod, controllerInfo: { name: instance.constructor.name, instance, }, }; } createSignalMethodInfo(methodName, metadata, boundMethod) { const signalMetadata = metadata; return { methodName, signalName: signalMetadata.name || methodName, options: signalMetadata, handler: boundMethod, }; } createQueryMethodInfo(methodName, metadata, boundMethod) { const queryMetadata = metadata; return { methodName, queryName: queryMetadata.name || methodName, options: queryMetadata, handler: boundMethod, }; } getScheduledWorkflows() { return Array.from(this.scheduledWorkflows.values()); } getScheduledWorkflow(scheduleId) { return this.scheduledWorkflows.get(scheduleId); } getScheduleIds() { return Array.from(this.scheduledWorkflows.keys()); } hasSchedule(scheduleId) { return this.scheduledWorkflows.has(scheduleId); } getSignals() { return Array.from(this.signals.values()); } getSignal(signalName) { return this.signals.get(signalName); } getQueries() { return Array.from(this.queries.values()); } getQuery(queryName) { return this.queries.get(queryName); } getStats() { return { controllers: 0, methods: 0, scheduled: this.scheduledWorkflows.size, signals: this.signals.size, queries: this.queries.size, }; } getHealthStatus() { const stats = this.getStats(); const status = stats.scheduled > 0 || stats.signals > 0 || stats.queries > 0 ? 'healthy' : 'degraded'; return { status, discoveredItems: stats, lastDiscovery: new Date(), }; } getWorkflowControllers() { this.logger.warn('getWorkflowControllers() is deprecated - workflow controllers are no longer supported'); return []; } getWorkflowMethod(_workflowName) { this.logger.warn('getWorkflowMethod() is deprecated - workflow methods are no longer supported'); return undefined; } getWorkflowNames() { this.logger.warn('getWorkflowNames() is deprecated - workflow names are no longer supported'); return []; } hasWorkflow(_workflowName) { this.logger.warn('hasWorkflow() is deprecated - workflow existence check is no longer supported'); return false; } logDiscoveryResults() { const stats = this.getStats(); this.logger.log(`Discovery completed: ${stats.scheduled} scheduled workflows, ${stats.signals} signals, ${stats.queries} queries`); if (stats.scheduled > 0) { this.logger.debug(`Discovered scheduled workflows: ${Array.from(this.scheduledWorkflows.keys()).join(', ')}`); } if (stats.signals > 0) { this.logger.debug(`Discovered signals: ${Array.from(this.signals.keys()).join(', ')}`); } if (stats.queries > 0) { this.logger.debug(`Discovered queries: ${Array.from(this.queries.keys()).join(', ')}`); } } }; exports.TemporalDiscoveryService = TemporalDiscoveryService; exports.TemporalDiscoveryService = TemporalDiscoveryService = TemporalDiscoveryService_1 = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [core_1.DiscoveryService, core_1.MetadataScanner]) ], TemporalDiscoveryService); //# sourceMappingURL=temporal-discovery.service.js.map