UNPKG

nestjs-temporal-core

Version:

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

208 lines 8.53 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 TemporalMetadataAccessor_1; Object.defineProperty(exports, "__esModule", { value: true }); exports.TemporalMetadataAccessor = void 0; const common_1 = require("@nestjs/common"); const constants_1 = require("../constants"); const logger_1 = require("../utils/logger"); let TemporalMetadataAccessor = TemporalMetadataAccessor_1 = class TemporalMetadataAccessor { constructor() { this.logger = (0, logger_1.createLogger)(TemporalMetadataAccessor_1.name); this.activityClassCache = new WeakMap(); this.activityMethodCache = new WeakMap(); } isActivity(target) { if (!target || typeof target !== 'function') { return false; } if (this.activityClassCache.has(target)) { return this.activityClassCache.get(target) !== null; } const metadata = this.getActivityMetadata(target); const isActivity = metadata !== null; this.activityClassCache.set(target, metadata); return isActivity; } getActivityOptions(target) { if (!target || typeof target !== 'function') { return null; } if (this.activityClassCache.has(target)) { return this.activityClassCache.get(target) || null; } const metadata = this.getActivityMetadata(target); this.activityClassCache.set(target, metadata); return metadata; } isActivityMethod(target) { return (target && typeof target === 'function' && Boolean(Reflect.getMetadata(constants_1.TEMPORAL_ACTIVITY_METHOD, target))); } getActivityMethodName(target) { if (!target || typeof target !== 'function') { return null; } const metadata = Reflect.getMetadata(constants_1.TEMPORAL_ACTIVITY_METHOD, target); return metadata?.name || null; } getActivityMethodOptions(target) { if (!target || typeof target !== 'function') { return null; } const metadata = Reflect.getMetadata(constants_1.TEMPORAL_ACTIVITY_METHOD, target); return metadata || null; } extractActivityMethods(instance) { if (!instance || typeof instance !== 'object') { this.logger.warn('Invalid instance provided to extractActivityMethods'); return new Map(); } const { constructor } = instance; if (this.activityMethodCache.has(constructor)) { const cachedMethods = this.activityMethodCache.get(constructor); const boundMethods = new Map(); for (const [name, metadata] of cachedMethods.entries()) { boundMethods.set(name, metadata.handler.bind(instance)); } return boundMethods; } const methods = this.extractMethodsFromPrototype(instance); this.activityMethodCache.set(constructor, methods); const boundMethods = new Map(); for (const [name, metadata] of methods.entries()) { boundMethods.set(name, metadata.handler.bind(instance)); } return boundMethods; } getActivityMethodMetadata(instance, methodName) { const methods = this.extractActivityMethods(instance); for (const [activityName, handler] of methods.entries()) { const cachedMethods = this.activityMethodCache.get(instance.constructor); if (cachedMethods) { const metadata = cachedMethods.get(activityName); if (metadata && metadata.originalName === methodName) { return { ...metadata, handler, }; } } } return null; } getActivityMethodNames(target) { if (!target || typeof target !== 'function') { return []; } const cachedMethods = this.activityMethodCache.get(target); if (cachedMethods) { return Array.from(cachedMethods.keys()); } const { prototype } = target; if (!prototype) { return []; } const methodNames = []; const propertyNames = Object.getOwnPropertyNames(prototype); for (const propertyName of propertyNames) { if (propertyName === 'constructor') continue; try { const method = prototype[propertyName]; if (typeof method === 'function' && this.isActivityMethod(method)) { const activityName = this.getActivityMethodName(method) || propertyName; methodNames.push(activityName); } } catch (error) { this.logger.debug(`Error checking method ${propertyName}: ${error.message}`); } } return methodNames; } getActivityInfo(target) { return { isActivity: this.isActivity(target), activityOptions: this.getActivityOptions(target), methodNames: this.getActivityMethodNames(target), methodCount: this.getActivityMethodNames(target).length, }; } validateActivityClass(target) { const issues = []; if (!this.isActivity(target)) { issues.push('Class is not marked with @Activity decorator'); } const methodNames = this.getActivityMethodNames(target); if (methodNames.length === 0) { issues.push('Activity class has no methods marked with @ActivityMethod'); } return { isValid: issues.length === 0, issues, }; } clearCache() { this.logger.debug('Metadata accessor cache cleared'); } getCacheStats() { return { message: 'Cache statistics not available', note: 'WeakMap-based caching prevents memory leaks but limits size reporting', }; } getActivityMetadata(target) { try { const metadata = Reflect.getMetadata(constants_1.TEMPORAL_ACTIVITY, target); return metadata || null; } catch (error) { this.logger.debug(`Error getting activity metadata: ${error.message}`); return null; } } extractMethodsFromPrototype(instance) { const methods = new Map(); const prototype = Object.getPrototypeOf(instance); if (!prototype) { return methods; } const propertyNames = Object.getOwnPropertyNames(prototype); for (const propertyName of propertyNames) { if (propertyName === 'constructor') continue; try { const method = prototype[propertyName]; if (typeof method !== 'function') continue; if (this.isActivityMethod(method)) { const metadata = this.getActivityMethodOptions(method); const activityName = metadata?.name || propertyName; methods.set(activityName, { name: activityName, originalName: propertyName, options: metadata || undefined, handler: method, }); this.logger.debug(`Found activity method: ${instance.constructor.name}.${propertyName} -> ${activityName}`); } } catch (error) { this.logger.warn(`Error processing method ${propertyName} in ${instance.constructor.name}: ${error.message}`); } } return methods; } }; exports.TemporalMetadataAccessor = TemporalMetadataAccessor; exports.TemporalMetadataAccessor = TemporalMetadataAccessor = TemporalMetadataAccessor_1 = __decorate([ (0, common_1.Injectable)() ], TemporalMetadataAccessor); //# sourceMappingURL=temporal-metadata.accessor.js.map