@sussudio/platform
Version:
Internal APIs for VS Code's service injection the base services.
152 lines (151 loc) • 4.27 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Event } from '@sussudio/base/common/event.mjs';
import { URI } from '@sussudio/base/common/uri.mjs';
import { AbstractLoggerService, AbstractMessageLogger, AdapterLogger, log, LogLevel, LogService } from './log.mjs';
export class LogLevelChannel {
logService;
loggerService;
onDidChangeLogLevel;
constructor(logService, loggerService) {
this.logService = logService;
this.loggerService = loggerService;
this.onDidChangeLogLevel = Event.buffer(logService.onDidChangeLogLevel, true);
}
listen(_, event) {
switch (event) {
case 'onDidChangeLogLevel':
return this.onDidChangeLogLevel;
}
throw new Error(`Event not found: ${event}`);
}
async call(_, command, arg) {
switch (command) {
case 'setLevel':
return arg[1] ? this.loggerService.setLevel(URI.revive(arg[1]), arg[0]) : this.logService.setLevel(arg[0]);
}
throw new Error(`Call not found: ${command}`);
}
}
export class LogLevelChannelClient {
channel;
constructor(channel) {
this.channel = channel;
}
get onDidChangeLogLevel() {
return this.channel.listen('onDidChangeLogLevel');
}
setLevel(level, resource) {
LogLevelChannelClient.setLevel(this.channel, level, resource);
}
static setLevel(channel, level, resource) {
return channel.call('setLevel', [level, resource]);
}
}
export class LoggerChannel {
loggerService;
loggers = new Map();
constructor(loggerService) {
this.loggerService = loggerService;
}
listen(_, event) {
throw new Error(`Event not found: ${event}`);
}
async call(_, command, arg) {
switch (command) {
case 'createLogger':
this.createLogger(URI.revive(arg[0]), arg[1]);
return;
case 'log':
return this.log(URI.revive(arg[0]), arg[1]);
case 'consoleLog':
return this.consoleLog(arg[0], arg[1]);
}
throw new Error(`Call not found: ${command}`);
}
createLogger(file, options) {
this.loggers.set(file.toString(), this.loggerService.createLogger(file, options));
}
consoleLog(level, args) {
let consoleFn = console.log;
switch (level) {
case LogLevel.Error:
consoleFn = console.error;
break;
case LogLevel.Warning:
consoleFn = console.warn;
break;
case LogLevel.Info:
consoleFn = console.info;
break;
}
consoleFn.call(console, ...args);
}
log(file, messages) {
const logger = this.loggers.get(file.toString());
if (!logger) {
throw new Error('Create the logger before logging');
}
for (const [level, message] of messages) {
log(logger, level, message);
}
}
}
export class LoggerChannelClient extends AbstractLoggerService {
channel;
constructor(logLevel, onDidChangeLogLevel, channel) {
super(logLevel, onDidChangeLogLevel);
this.channel = channel;
}
createConsoleMainLogger() {
return new AdapterLogger({
log: (level, args) => {
this.channel.call('consoleLog', [level, args]);
},
});
}
doCreateLogger(file, logLevel, options) {
return new Logger(this.channel, file, logLevel, options);
}
}
class Logger extends AbstractMessageLogger {
channel;
file;
isLoggerCreated = false;
buffer = [];
constructor(channel, file, logLevel, loggerOptions) {
super(loggerOptions?.always);
this.channel = channel;
this.file = file;
this.setLevel(logLevel);
this.channel.call('createLogger', [file, loggerOptions]).then(() => {
this.doLog(this.buffer);
this.isLoggerCreated = true;
});
}
log(level, message) {
const messages = [[level, message]];
if (this.isLoggerCreated) {
this.doLog(messages);
} else {
this.buffer.push(...messages);
}
}
doLog(messages) {
this.channel.call('log', [this.file, messages]);
}
}
export class FollowerLogService extends LogService {
parent;
constructor(parent, logService) {
super(logService);
this.parent = parent;
this._register(parent.onDidChangeLogLevel((level) => logService.setLevel(level)));
}
setLevel(level) {
super.setLevel(level);
this.parent.setLevel(level);
}
}