Files
2026-06-10 12:38:42 -03:00

145 lines
3.9 KiB
JavaScript

//#region src/utils.ts
/**
* Coerce `value`.
*/
function coerce(value) {
if (value instanceof Error) return value.stack || value.message;
return value;
}
/**
* Selects a color for a debug namespace
* @return An ANSI color code for the given namespace
*/
function selectColor(colors, namespace) {
let hash = 0;
for (let i = 0; i < namespace.length; i++) {
hash = (hash << 5) - hash + namespace.charCodeAt(i);
hash |= 0;
}
return colors[Math.abs(hash) % colors.length];
}
/**
* Checks if the given string matches a namespace template, honoring
* asterisks as wildcards.
*/
function matchesTemplate(search, template) {
let searchIndex = 0;
let templateIndex = 0;
let starIndex = -1;
let matchIndex = 0;
while (searchIndex < search.length) if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === "*")) if (template[templateIndex] === "*") {
starIndex = templateIndex;
matchIndex = searchIndex;
templateIndex++;
} else {
searchIndex++;
templateIndex++;
}
else if (starIndex !== -1) {
templateIndex = starIndex + 1;
matchIndex++;
searchIndex = matchIndex;
} else return false;
while (templateIndex < template.length && template[templateIndex] === "*") templateIndex++;
return templateIndex === template.length;
}
function humanize(value) {
if (value >= 1e3) return `${(value / 1e3).toFixed(1)}s`;
return `${value}ms`;
}
//#endregion
//#region src/core.ts
let globalNamespaces = "";
/**
* Returns a string of the currently enabled debug namespaces.
*/
function namespaces() {
return globalNamespaces;
}
function createDebug(namespace, options) {
let prevTime;
let enableOverride;
let namespacesCache;
let enabledCache;
const debug = (...args) => {
if (!debug.enabled) return;
const curr = Date.now();
const diff = curr - (prevTime || curr);
prevTime = curr;
args[0] = coerce(args[0]);
if (typeof args[0] !== "string") args.unshift("%O");
let index = 0;
args[0] = args[0].replace(/%([a-z%])/gi, (match, format) => {
if (match === "%%") return "%";
index++;
const formatter = options.formatters[format];
if (typeof formatter === "function") {
const value = args[index];
match = formatter.call(debug, value);
args.splice(index, 1);
index--;
}
return match;
});
options.formatArgs.call(debug, diff, args);
debug.log(...args);
};
debug.extend = function(namespace, delimiter = ":") {
return createDebug(this.namespace + delimiter + namespace, {
useColors: this.useColors,
color: this.color,
formatArgs: this.formatArgs,
formatters: this.formatters,
inspectOpts: this.inspectOpts,
log: this.log,
humanize: this.humanize
});
};
Object.assign(debug, options);
debug.namespace = namespace;
Object.defineProperty(debug, "enabled", {
enumerable: true,
configurable: false,
get: () => {
if (enableOverride != null) return enableOverride;
if (namespacesCache !== globalNamespaces) {
namespacesCache = globalNamespaces;
enabledCache = enabled(namespace);
}
return enabledCache;
},
set: (v) => {
enableOverride = v;
}
});
return debug;
}
let names = [];
let skips = [];
function enable(namespaces) {
globalNamespaces = namespaces;
names = [];
skips = [];
const split = globalNamespaces.trim().replace(/\s+/g, ",").split(",").filter(Boolean);
for (const ns of split) if (ns[0] === "-") skips.push(ns.slice(1));
else names.push(ns);
}
/**
* Disable debug output.
*/
function disable() {
const namespaces = [...names, ...skips.map((namespace) => `-${namespace}`)].join(",");
enable("");
return namespaces;
}
/**
* Returns true if the given mode name is enabled, false otherwise.
*/
function enabled(name) {
for (const skip of skips) if (matchesTemplate(name, skip)) return false;
for (const ns of names) if (matchesTemplate(name, ns)) return true;
return false;
}
//#endregion
export { namespaces as a, enabled as i, disable as n, humanize as o, enable as r, selectColor as s, createDebug as t };