osr-mono/packages/osr-code-bot/utils/aspects_simple.js
2025-01-30 00:50:58 +01:00

157 lines
9.6 KiB
JavaScript

"use strict";
/* -------------------------------------------------------------------------
* aspects.ts
*
* A robust “aspect” system supporting:
* - before: optionally modifies arguments (sync or async)
* - after: optionally modifies return value (sync or async)
* - around: complete control over function invocation
* - error: intercept errors (sync or async)
*
* Only supports direct function wrappers (e.g. fn = before(fn, ...)).
* ------------------------------------------------------------------------ */
Object.defineProperty(exports, "__esModule", { value: true });
exports.SIGNALS = void 0;
exports.before = before;
exports.after = after;
exports.around = around;
exports.error = error;
/* -------------------------------------------------------------------------
* 1) SIGNALS Enum (string-based to avoid symbol issues)
* ------------------------------------------------------------------------ */
var SIGNALS;
(function (SIGNALS) {
SIGNALS["BEFORE"] = "BEFORE";
SIGNALS["AFTER"] = "AFTER";
SIGNALS["AROUND"] = "AROUND";
SIGNALS["ERROR"] = "ERROR";
})(SIGNALS || (exports.SIGNALS = SIGNALS = {}));
/* -------------------------------------------------------------------------
* 5) The SignalMap Implementation
* - This is where the actual "wrapping" logic lives.
* ------------------------------------------------------------------------ */
const SignalMap = {
/**
* BEFORE:
* - Possibly modifies arguments
* - If returns a Promise, we await it before calling original
* - If returns an array, we use that as new arguments
*/
[SIGNALS.BEFORE](original, advice) {
return function (...args) {
const maybeNewArgs = advice(this, args);
if (maybeNewArgs instanceof Promise) {
return maybeNewArgs.then((resolvedArgs) => {
const finalArgs = resolvedArgs || args;
const result = original.apply(this, finalArgs);
return (result instanceof Promise) ? result : Promise.resolve(result);
});
}
else {
const finalArgs = Array.isArray(maybeNewArgs) ? maybeNewArgs : args;
return original.apply(this, finalArgs);
}
};
},
/**
* AFTER:
* - Possibly modifies the return value
* - If original is async, we chain on its promise
* - Advice can be sync or async
*/
[SIGNALS.AFTER](original, advice) {
return function (...args) {
const result = original.apply(this, args);
if (result instanceof Promise) {
return result.then((unwrapped) => {
const maybeNewResult = advice(this, unwrapped, args);
return (maybeNewResult instanceof Promise) ? maybeNewResult : maybeNewResult;
});
}
else {
const maybeNewResult = advice(this, result, args);
if (maybeNewResult instanceof Promise) {
return maybeNewResult.then(r => r);
}
return maybeNewResult;
}
};
},
/**
* AROUND:
* - Full control over invocation
* - Typically you do: proceed(...args)
* - If you want to skip or call multiple times, you can
*/
[SIGNALS.AROUND](original, advice) {
return function (...args) {
const proceed = (...innerArgs) => original.apply(this, innerArgs);
return advice(proceed, this, args);
};
},
/**
* ERROR:
* - Intercepts errors thrown by the original function or a rejected Promise
* - Optionally returns a fallback or rethrows
*/
[SIGNALS.ERROR](original, advice) {
return function (...args) {
try {
const result = original.apply(this, args);
if (result instanceof Promise) {
// Handle async rejections
return result.catch((err) => {
return advice(err, this, args);
});
}
return result;
}
catch (err) {
// Synchronous error
return advice(err, this, args);
}
};
},
};
/* -------------------------------------------------------------------------
* 6) Direct Usage Functions (no decorator support)
* ------------------------------------------------------------------------ */
/**
* `before`:
* Direct usage => myFn = before(myFn, (ctx, args) => ...)
*/
function before(fn, advice) {
return SignalMap[SIGNALS.BEFORE](fn, advice);
}
/**
* `after`:
* Direct usage => myFn = after(myFn, (ctx, result, args) => ...)
*/
function after(fn, advice) {
return SignalMap[SIGNALS.AFTER](fn, advice);
}
/**
* `around`:
* Direct usage => myFn = around(myFn, (proceed, ctx, args) => ...)
*/
function around(fn, advice) {
return SignalMap[SIGNALS.AROUND](fn, advice);
}
/**
* `error`:
* Direct usage => myFn = error(myFn, (err, ctx, args) => ...)
*/
function error(fn, advice) {
return SignalMap[SIGNALS.ERROR](fn, advice);
}
/* -------------------------------------------------------------------------
* 7) Default Export
* ------------------------------------------------------------------------ */
exports.default = {
SIGNALS,
before,
after,
around,
error,
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNwZWN0c19zaW1wbGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvdXRpbHMvYXNwZWN0c19zaW1wbGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOzs7Ozs7Ozs7OzhFQVU4RTs7O0FBdUw1RSx3QkFFQztBQU1ELHNCQUVDO0FBTUQsd0JBRUM7QUFNRCxzQkFFQztBQS9NSDs7OEVBRThFO0FBQzlFLElBQVksT0FLVDtBQUxILFdBQVksT0FBTztJQUNmLDRCQUFpQixDQUFBO0lBQ2pCLDBCQUFlLENBQUE7SUFDZiw0QkFBaUIsQ0FBQTtJQUNqQiwwQkFBZSxDQUFBO0FBQ2pCLENBQUMsRUFMUyxPQUFPLHVCQUFQLE9BQU8sUUFLaEI7QUEyRUQ7Ozs4RUFHOEU7QUFDOUUsTUFBTSxTQUFTLEdBQWU7SUFDNUI7Ozs7O09BS0c7SUFDSCxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBd0IsUUFBVyxFQUFFLE1BQXVCO1FBQzFFLE9BQU8sVUFBc0MsR0FBRyxJQUFtQjtZQUNqRSxNQUFNLFlBQVksR0FBRyxNQUFNLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBRXhDLElBQUksWUFBWSxZQUFZLE9BQU8sRUFBRSxDQUFDO2dCQUNwQyxPQUFPLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxZQUFZLEVBQUUsRUFBRTtvQkFDeEMsTUFBTSxTQUFTLEdBQUcsWUFBWSxJQUFJLElBQUksQ0FBQztvQkFDdkMsTUFBTSxNQUFNLEdBQUcsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBQy9DLE9BQU8sQ0FBQyxNQUFNLFlBQVksT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDeEUsQ0FBQyxDQUFrQixDQUFDO1lBQ3RCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLFNBQVMsR0FB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