ses
Version:
Hardened JavaScript for Fearless Cooperation
77 lines (67 loc) • 2.09 kB
JavaScript
// @ts-check
/* eslint-disable @endo/no-polymorphic-call */
/* eslint-disable no-restricted-globals */
import { makeLRUCacheMap } from '../make-lru-cachemap.js';
/**
* @import {LogArgs} from './internal-types.js';
*/
const { freeze } = Object;
const { isSafeInteger } = Number;
const defaultLoggedErrorsBudget = 1000;
const defaultArgsPerErrorBudget = 100;
/**
* @param {number} [errorsBudget]
* @param {number} [argsPerErrorBudget]
*/
export const makeNoteLogArgsArrayKit = (
errorsBudget = defaultLoggedErrorsBudget,
argsPerErrorBudget = defaultArgsPerErrorBudget,
) => {
if (!isSafeInteger(argsPerErrorBudget) || argsPerErrorBudget < 1) {
throw TypeError(
'argsPerErrorBudget must be a safe positive integer number',
);
}
/**
* @type {WeakMap<Error, LogArgs[]>}
*
* Maps from an error to an array of log args, where each log args is
* remembered as an annotation on that error. This can be used, for example,
* to keep track of additional causes of the error. The elements of any
* log args may include errors which are associated with further annotations.
* An augmented console, like the causal console of `console.js`, could
* then retrieve the graph of such annotations.
*/
const noteLogArgsArrayMap = makeLRUCacheMap(errorsBudget);
/**
* @param {Error} error
* @param {LogArgs} logArgs
*/
const addLogArgs = (error, logArgs) => {
const logArgsArray = noteLogArgsArrayMap.get(error);
if (logArgsArray !== undefined) {
if (logArgsArray.length >= argsPerErrorBudget) {
logArgsArray.shift();
}
logArgsArray.push(logArgs);
} else {
noteLogArgsArrayMap.set(error, [logArgs]);
}
};
freeze(addLogArgs);
/**
* @param {Error} error
* @returns {LogArgs[] | undefined}
*/
const takeLogArgsArray = error => {
const result = noteLogArgsArrayMap.get(error);
noteLogArgsArrayMap.delete(error);
return result;
};
freeze(takeLogArgsArray);
return freeze({
addLogArgs,
takeLogArgsArray,
});
};
freeze(makeNoteLogArgsArrayKit);