UNPKG

monaco-editor-core

Version:

A browser based code editor

259 lines (258 loc) • 8.22 kB
/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ let globalObservableLogger; export function setLogger(logger) { globalObservableLogger = logger; } export function getLogger() { return globalObservableLogger; } export class ConsoleObservableLogger { constructor() { this.indentation = 0; this.changedObservablesSets = new WeakMap(); } textToConsoleArgs(text) { return consoleTextToArgs([ normalText(repeat('| ', this.indentation)), text, ]); } formatInfo(info) { if (!info.hadValue) { return [ normalText(` `), styled(formatValue(info.newValue, 60), { color: 'green', }), normalText(` (initial)`), ]; } return info.didChange ? [ normalText(` `), styled(formatValue(info.oldValue, 70), { color: 'red', strikeThrough: true, }), normalText(` `), styled(formatValue(info.newValue, 60), { color: 'green', }), ] : [normalText(` (unchanged)`)]; } handleObservableChanged(observable, info) { console.log(...this.textToConsoleArgs([ formatKind('observable value changed'), styled(observable.debugName, { color: 'BlueViolet' }), ...this.formatInfo(info), ])); } formatChanges(changes) { if (changes.size === 0) { return undefined; } return styled(' (changed deps: ' + [...changes].map((o) => o.debugName).join(', ') + ')', { color: 'gray' }); } handleDerivedCreated(derived) { const existingHandleChange = derived.handleChange; this.changedObservablesSets.set(derived, new Set()); derived.handleChange = (observable, change) => { this.changedObservablesSets.get(derived).add(observable); return existingHandleChange.apply(derived, [observable, change]); }; } handleDerivedRecomputed(derived, info) { const changedObservables = this.changedObservablesSets.get(derived); console.log(...this.textToConsoleArgs([ formatKind('derived recomputed'), styled(derived.debugName, { color: 'BlueViolet' }), ...this.formatInfo(info), this.formatChanges(changedObservables), { data: [{ fn: derived._debugNameData.referenceFn ?? derived._computeFn }] } ])); changedObservables.clear(); } handleFromEventObservableTriggered(observable, info) { console.log(...this.textToConsoleArgs([ formatKind('observable from event triggered'), styled(observable.debugName, { color: 'BlueViolet' }), ...this.formatInfo(info), { data: [{ fn: observable._getValue }] } ])); } handleAutorunCreated(autorun) { const existingHandleChange = autorun.handleChange; this.changedObservablesSets.set(autorun, new Set()); autorun.handleChange = (observable, change) => { this.changedObservablesSets.get(autorun).add(observable); return existingHandleChange.apply(autorun, [observable, change]); }; } handleAutorunTriggered(autorun) { const changedObservables = this.changedObservablesSets.get(autorun); console.log(...this.textToConsoleArgs([ formatKind('autorun'), styled(autorun.debugName, { color: 'BlueViolet' }), this.formatChanges(changedObservables), { data: [{ fn: autorun._debugNameData.referenceFn ?? autorun._runFn }] } ])); changedObservables.clear(); this.indentation++; } handleAutorunFinished(autorun) { this.indentation--; } handleBeginTransaction(transaction) { let transactionName = transaction.getDebugName(); if (transactionName === undefined) { transactionName = ''; } console.log(...this.textToConsoleArgs([ formatKind('transaction'), styled(transactionName, { color: 'BlueViolet' }), { data: [{ fn: transaction._fn }] } ])); this.indentation++; } handleEndTransaction() { this.indentation--; } } function consoleTextToArgs(text) { const styles = new Array(); const data = []; let firstArg = ''; function process(t) { if ('length' in t) { for (const item of t) { if (item) { process(item); } } } else if ('text' in t) { firstArg += `%c${t.text}`; styles.push(t.style); if (t.data) { data.push(...t.data); } } else if ('data' in t) { data.push(...t.data); } } process(text); const result = [firstArg, ...styles]; result.push(...data); return result; } function normalText(text) { return styled(text, { color: 'black' }); } function formatKind(kind) { return styled(padStr(`${kind}: `, 10), { color: 'black', bold: true }); } function styled(text, options = { color: 'black', }) { function objToCss(styleObj) { return Object.entries(styleObj).reduce((styleString, [propName, propValue]) => { return `${styleString}${propName}:${propValue};`; }, ''); } const style = { color: options.color, }; if (options.strikeThrough) { style['text-decoration'] = 'line-through'; } if (options.bold) { style['font-weight'] = 'bold'; } return { text, style: objToCss(style), }; } function formatValue(value, availableLen) { switch (typeof value) { case 'number': return '' + value; case 'string': if (value.length + 2 <= availableLen) { return `"${value}"`; } return `"${value.substr(0, availableLen - 7)}"+...`; case 'boolean': return value ? 'true' : 'false'; case 'undefined': return 'undefined'; case 'object': if (value === null) { return 'null'; } if (Array.isArray(value)) { return formatArray(value, availableLen); } return formatObject(value, availableLen); case 'symbol': return value.toString(); case 'function': return `[[Function${value.name ? ' ' + value.name : ''}]]`; default: return '' + value; } } function formatArray(value, availableLen) { let result = '[ '; let first = true; for (const val of value) { if (!first) { result += ', '; } if (result.length - 5 > availableLen) { result += '...'; break; } first = false; result += `${formatValue(val, availableLen - result.length)}`; } result += ' ]'; return result; } function formatObject(value, availableLen) { let result = '{ '; let first = true; for (const [key, val] of Object.entries(value)) { if (!first) { result += ', '; } if (result.length - 5 > availableLen) { result += '...'; break; } first = false; result += `${key}: ${formatValue(val, availableLen - result.length)}`; } result += ' }'; return result; } function repeat(str, count) { let result = ''; for (let i = 1; i <= count; i++) { result += str; } return result; } function padStr(str, length) { while (str.length < length) { str += ' '; } return str; }