helene
Version:
Real-time Web Apps for Node.js
100 lines • 3.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Method = void 0;
const utils_1 = require("../utils");
const ejson_1 = require("../ejson");
const isEmpty_1 = __importDefault(require("lodash/isEmpty"));
const perf_hooks_1 = __importDefault(require("perf_hooks"));
const yup_1 = require("yup");
const helene_async_local_storage_1 = require("./helene-async-local-storage");
function customMemoize(fn, options = {}) {
const cache = new Map();
const { maxAge = 60000 } = options;
return function (...args) {
const key = ejson_1.EJSON.stringify(args[0]); // Normalize first argument (params)
const now = Date.now();
const cached = cache.get(key);
if (cached && now - cached.timestamp < maxAge) {
return cached.value;
}
const result = fn.apply(this, args);
cache.set(key, { value: result, timestamp: now });
return result;
};
}
class Method {
uuid;
fn;
isProtected;
middleware;
schema = null;
name;
server;
constructor(server, name, fn, opts) {
const { cache, maxAge = 60000, schema } = opts ?? {};
this.server = server;
this.name = name;
this.uuid = utils_1.Presentation.uuid();
this.isProtected = opts?.protected;
this.middleware = opts?.middleware;
this.fn = cache ? customMemoize(fn, { maxAge }) : fn;
this.schema = schema;
}
async runMiddleware(params, node) {
if ((0, isEmpty_1.default)(this.middleware))
return params;
const wrapped = this.middleware.map(m => (0, utils_1.intercept)(m));
let buffer = params;
for (const step of wrapped) {
buffer = await step.call(node, buffer);
}
return buffer;
}
async exec(params, node) {
const start = perf_hooks_1.default.performance.now();
let cleanParams = params;
if (this.schema) {
try {
if (this.schema instanceof yup_1.ObjectSchema) {
await this.schema.validate(params);
cleanParams = this.schema.cast(params, { stripUnknown: true });
}
if (isZodSchema(this.schema)) {
await this.schema.parseAsync(params);
cleanParams = this.schema.parse(params);
}
}
catch (error) {
console.error(JSON.stringify(error, null, 2));
throw new utils_1.SchemaValidationError(utils_1.Errors.INVALID_PARAMS);
}
}
const result = await helene_async_local_storage_1.HeleneAsyncLocalStorage.run({ executionId: utils_1.Presentation.uuid(), context: node.context }, async () => {
const middlewareResult = await this.runMiddleware(cleanParams, node);
return this.fn.call(node, middlewareResult);
});
const end = perf_hooks_1.default.performance.now();
this.server.emit(utils_1.ServerEvents.METHOD_EXECUTION, {
method: this.name,
time: end - start,
params: cleanParams,
result,
});
return result;
}
}
exports.Method = Method;
function isZodSchema(schema) {
if (!schema || typeof schema !== 'object') {
return false;
}
return ('_def' in schema &&
'parse' in schema &&
typeof schema.parse === 'function' &&
'safeParse' in schema &&
typeof schema.safeParse === 'function');
}
//# sourceMappingURL=method.js.map