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