@flowscripter/mpeg-sdl-parser
Version:
ISO/IEC 14496-34 Syntactic Description Language (MPEG SDL) parser implemented in TypeScript
152 lines (137 loc) • 3.83 kB
text/typescript
import process from "node:process";
declare global {
var defaultLogger: Logger | undefined;
}
type LoggerFunction = (
message: object | (() => string) | string,
...optionalParams: unknown[]
) => void;
export interface Logger {
trace: LoggerFunction;
debug: LoggerFunction;
info: LoggerFunction;
warn: LoggerFunction;
error: LoggerFunction;
}
const LEVEL_PADDINGS: Record<string, string> = {
TRACE: " ",
DEBUG: " ",
INFO: " ",
WARN: " ",
ERROR: " ",
};
export const debugEnabled = process?.env["MPEG_SDL_PARSER_DEBUG"] !== undefined;
let maxLoggerNameLength = 0;
const LOGGER_NAME_PADDINGS: Record<string, string> = {};
function getDefaultLogger(): Logger {
return {
trace: () => {},
debug: (message, ...optionalParams) => {
console.debug(message, ...optionalParams);
},
info: (message, ...optionalParams) => {
console.info(message, ...optionalParams);
},
warn: (message, ...optionalParams) => {
console.warn(message, ...optionalParams);
},
error: (message, ...optionalParams) => {
console.error(message, ...optionalParams);
},
};
}
function wrapDefaultLogger(
loggerName: string,
levelPadding: string,
loggerFunction: LoggerFunction,
): LoggerFunction {
return (message, ...optionalParams) => {
if (message instanceof Function) {
loggerFunction(
`${levelPadding} [${loggerName}]${
LOGGER_NAME_PADDINGS[loggerName]
} ${message()}`,
...optionalParams,
);
return;
}
if (message instanceof Object) {
loggerFunction(
`${levelPadding} [${loggerName}]${LOGGER_NAME_PADDINGS[loggerName]} ${
JSON.stringify(message)
}`,
...optionalParams,
);
return;
}
loggerFunction(
`${levelPadding} [${loggerName}]${
LOGGER_NAME_PADDINGS[loggerName]
} ${message}`,
...optionalParams,
);
};
}
/**
* Retrieves a logger instance with the specified name. If the name length exceeds the current maximum logger name length,
* it updates the padding for all existing logger names to ensure consistent formatting.
*
* @param loggerName The name of the logger to retrieve.
* @returns A logger instance with the specified name.
*/
export default function getLogger(loggerName: string): Logger {
if (globalThis.defaultLogger === undefined) {
globalThis.defaultLogger = getDefaultLogger();
}
if (loggerName.length > maxLoggerNameLength) {
maxLoggerNameLength = loggerName.length;
for (const key of Object.keys(LOGGER_NAME_PADDINGS)) {
LOGGER_NAME_PADDINGS[key] = " ".repeat(maxLoggerNameLength - key.length);
}
LOGGER_NAME_PADDINGS[loggerName] = "";
} else if (LOGGER_NAME_PADDINGS[loggerName] === undefined) {
LOGGER_NAME_PADDINGS[loggerName] = " ".repeat(
maxLoggerNameLength - loggerName.length,
);
}
if (debugEnabled) {
return {
trace: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.TRACE,
globalThis.defaultLogger.trace,
),
debug: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.DEBUG,
globalThis.defaultLogger.debug,
),
info: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.INFO,
globalThis.defaultLogger.info,
),
warn: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.WARN,
globalThis.defaultLogger.warn,
),
error: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.ERROR,
globalThis.defaultLogger.error,
),
};
}
return {
trace: () => {},
debug: () => {},
info: () => {},
warn: () => {},
error: wrapDefaultLogger(
loggerName,
LEVEL_PADDINGS.ERROR,
globalThis.defaultLogger.error,
),
};
}