This commit is contained in:
2025-11-02 19:17:20 +08:00
parent ebf784146e
commit e71b69db5f
2575 changed files with 1242294 additions and 95 deletions

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { onUnexpectedError } from './commonFacade/deps.js';
/**
* This function is used to indicate that the caller recovered from an error that indicates a bug.
*/
export function handleBugIndicatingErrorRecovery(message) {
const err = new Error('BugIndicatingErrorRecovery: ' + message);
onUnexpectedError(err);
console.error('recovered from an error that indicates a bug', err);
}
//# sourceMappingURL=base.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { BugIndicatingError } from './commonFacade/deps.js';
/**
* Subscribes to and records changes and the last value of the given observables.
* Don't use the key "changes", as it is reserved for the changes array!
*/
export function recordChanges(obs) {
return {
createChangeSummary: (_previousChangeSummary) => {
return {
changes: [],
};
},
handleChange(ctx, changeSummary) {
for (const key in obs) {
if (ctx.didChange(obs[key])) {
changeSummary.changes.push({ key, change: ctx.change });
}
}
return true;
},
beforeUpdate(reader, changeSummary) {
for (const key in obs) {
if (key === 'changes') {
throw new BugIndicatingError('property name "changes" is reserved for change tracking');
}
changeSummary[key] = obs[key].read(reader);
}
}
};
}
/**
* Subscribes to and records changes and the last value of the given observables.
* Don't use the key "changes", as it is reserved for the changes array!
*/
export function recordChangesLazy(getObs) {
let obs = undefined;
return {
createChangeSummary: (_previousChangeSummary) => {
return {
changes: [],
};
},
handleChange(ctx, changeSummary) {
if (!obs) {
obs = getObs();
}
for (const key in obs) {
if (ctx.didChange(obs[key])) {
changeSummary.changes.push({ key, change: ctx.change });
}
}
return true;
},
beforeUpdate(reader, changeSummary) {
if (!obs) {
obs = getObs();
}
for (const key in obs) {
if (key === 'changes') {
throw new BugIndicatingError('property name "changes" is reserved for change tracking');
}
changeSummary[key] = obs[key].read(reader);
}
}
};
}
//# sourceMappingURL=changeTracker.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export { CancellationError } from '../../errors.js';
export { CancellationToken, CancellationTokenSource, cancelOnDispose } from '../../cancellation.js';
//# sourceMappingURL=cancellation.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/commonFacade/cancellation.ts","vs/base/common/observableInternal/commonFacade/cancellation.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC","file":"cancellation.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport { CancellationError } from '../../errors.js';\nexport { CancellationToken, CancellationTokenSource, cancelOnDispose } from '../../cancellation.js';\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport { CancellationError } from '../../errors.js';\nexport { CancellationToken, CancellationTokenSource, cancelOnDispose } from '../../cancellation.js';\n"]}

View File

@@ -0,0 +1,10 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export { assertFn } from '../../assert.js';
export { strictEquals } from '../../equals.js';
export { BugIndicatingError, onBugIndicatingError, onUnexpectedError } from '../../errors.js';
export { Event } from '../../event.js';
export { DisposableStore, markAsDisposed, toDisposable, trackDisposable } from '../../lifecycle.js';
//# sourceMappingURL=deps.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/commonFacade/deps.ts","vs/base/common/observableInternal/commonFacade/deps.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAyB,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAC9F,OAAO,EAAE,KAAK,EAA8B,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAoB,cAAc,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC","file":"deps.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport { assertFn } from '../../assert.js';\nexport { type EqualityComparer, strictEquals } from '../../equals.js';\nexport { BugIndicatingError, onBugIndicatingError, onUnexpectedError } from '../../errors.js';\nexport { Event, type IValueWithChangeEvent } from '../../event.js';\nexport { DisposableStore, type IDisposable, markAsDisposed, toDisposable, trackDisposable } from '../../lifecycle.js';\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nexport { assertFn } from '../../assert.js';\nexport { type EqualityComparer, strictEquals } from '../../equals.js';\nexport { BugIndicatingError, onBugIndicatingError, onUnexpectedError } from '../../errors.js';\nexport { Event, type IValueWithChangeEvent } from '../../event.js';\nexport { DisposableStore, type IDisposable, markAsDisposed, toDisposable, trackDisposable } from '../../lifecycle.js';\n"]}

View File

@@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export var DebugLocation;
(function (DebugLocation) {
let enabled = false;
function enable() {
enabled = true;
}
DebugLocation.enable = enable;
function ofCaller() {
if (!enabled) {
return undefined;
}
const Err = Error; // For the monaco editor checks, which don't have the nodejs types.
const l = Err.stackTraceLimit;
Err.stackTraceLimit = 3;
const stack = new Error().stack;
Err.stackTraceLimit = l;
return DebugLocationImpl.fromStack(stack, 2);
}
DebugLocation.ofCaller = ofCaller;
})(DebugLocation || (DebugLocation = {}));
class DebugLocationImpl {
static fromStack(stack, parentIdx) {
const lines = stack.split('\n');
const location = parseLine(lines[parentIdx + 1]);
if (location) {
return new DebugLocationImpl(location.fileName, location.line, location.column, location.id);
}
else {
return undefined;
}
}
constructor(fileName, line, column, id) {
this.fileName = fileName;
this.line = line;
this.column = column;
this.id = id;
}
}
function parseLine(stackLine) {
const match = stackLine.match(/\((.*):(\d+):(\d+)\)/);
if (match) {
return {
fileName: match[1],
line: parseInt(match[2]),
column: parseInt(match[3]),
id: stackLine,
};
}
const match2 = stackLine.match(/at ([^\(\)]*):(\d+):(\d+)/);
if (match2) {
return {
fileName: match2[1],
line: parseInt(match2[2]),
column: parseInt(match2[3]),
id: stackLine,
};
}
return undefined;
}
//# sourceMappingURL=debugLocation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,108 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class DebugNameData {
constructor(owner, debugNameSource, referenceFn) {
this.owner = owner;
this.debugNameSource = debugNameSource;
this.referenceFn = referenceFn;
}
getDebugName(target) {
return getDebugName(target, this);
}
}
const countPerName = new Map();
const cachedDebugName = new WeakMap();
export function getDebugName(target, data) {
const cached = cachedDebugName.get(target);
if (cached) {
return cached;
}
const dbgName = computeDebugName(target, data);
if (dbgName) {
let count = countPerName.get(dbgName) ?? 0;
count++;
countPerName.set(dbgName, count);
const result = count === 1 ? dbgName : `${dbgName}#${count}`;
cachedDebugName.set(target, result);
return result;
}
return undefined;
}
function computeDebugName(self, data) {
const cached = cachedDebugName.get(self);
if (cached) {
return cached;
}
const ownerStr = data.owner ? formatOwner(data.owner) + `.` : '';
let result;
const debugNameSource = data.debugNameSource;
if (debugNameSource !== undefined) {
if (typeof debugNameSource === 'function') {
result = debugNameSource();
if (result !== undefined) {
return ownerStr + result;
}
}
else {
return ownerStr + debugNameSource;
}
}
const referenceFn = data.referenceFn;
if (referenceFn !== undefined) {
result = getFunctionName(referenceFn);
if (result !== undefined) {
return ownerStr + result;
}
}
if (data.owner !== undefined) {
const key = findKey(data.owner, self);
if (key !== undefined) {
return ownerStr + key;
}
}
return undefined;
}
function findKey(obj, value) {
for (const key in obj) {
if (obj[key] === value) {
return key;
}
}
return undefined;
}
const countPerClassName = new Map();
const ownerId = new WeakMap();
function formatOwner(owner) {
const id = ownerId.get(owner);
if (id) {
return id;
}
const className = getClassName(owner) ?? 'Object';
let count = countPerClassName.get(className) ?? 0;
count++;
countPerClassName.set(className, count);
const result = count === 1 ? className : `${className}#${count}`;
ownerId.set(owner, result);
return result;
}
export function getClassName(obj) {
const ctor = obj.constructor;
if (ctor) {
if (ctor.name === 'Object') {
return undefined;
}
return ctor.name;
}
return undefined;
}
export function getFunctionName(fn) {
const fnSrc = fn.toString();
// Pattern: /** @description ... */
const regexp = /\/\*\*\s*@description\s*([^*]*)\*\//;
const match = regexp.exec(fnSrc);
const result = match ? match[1] : undefined;
return result?.trim();
}
//# sourceMappingURL=debugName.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,41 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { strictEquals, BugIndicatingError } from '../commonFacade/deps.js';
import { subtransaction } from '../transaction.js';
import { DebugNameData } from '../debugName.js';
import { DerivedWithSetter } from '../observables/derivedImpl.js';
import { DebugLocation } from '../debugLocation.js';
/**
* Creates an observable value that is based on values and changes from other observables.
* Additionally, a reducer can report how that state changed.
*/
export function observableReducerSettable(owner, options) {
let prevValue = undefined;
let hasValue = false;
const d = new DerivedWithSetter(new DebugNameData(owner, undefined, options.update), (reader, changeSummary) => {
if (!hasValue) {
prevValue = options.initial instanceof Function ? options.initial() : options.initial;
hasValue = true;
}
const newValue = options.update(reader, prevValue, changeSummary);
prevValue = newValue;
return newValue;
}, options.changeTracker, () => {
if (hasValue) {
options.disposeFinal?.(prevValue);
hasValue = false;
}
}, options.equalityComparer ?? strictEquals, (value, tx, change) => {
if (!hasValue) {
throw new BugIndicatingError('Can only set when there is a listener! This is to prevent leaks.');
}
subtransaction(tx, tx => {
prevValue = value;
d.setValue(value, tx, change);
});
}, DebugLocation.ofCaller());
return d;
}
//# sourceMappingURL=reducer.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,14 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { derivedObservableWithCache } from '../utils/utils.js';
/**
* Works like a derived.
* However, if the value is not undefined, it is cached and will not be recomputed anymore.
* In that case, the derived will unsubscribe from its dependencies.
*/
export function derivedConstOnceDefined(owner, fn) {
return derivedObservableWithCache(owner, (reader, lastValue) => lastValue ?? fn(reader));
}
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/experimental/utils.ts","vs/base/common/observableInternal/experimental/utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAIhG,OAAO,EAAE,0BAA0B,EAAE,MAAM,mBAAmB,CAAC;AAE/D;;;;EAIE;AACF,MAAM,UAAU,uBAAuB,CAAI,KAAiB,EAAE,EAA0B;IACvF,OAAO,0BAA0B,CAAgB,KAAK,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,SAAS,IAAI,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC;AACzG,CAAC","file":"utils.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable, IReader } from '../base.js';\nimport { DebugOwner } from '../debugName.js';\nimport { derivedObservableWithCache } from '../utils/utils.js';\n\n/**\n * Works like a derived.\n * However, if the value is not undefined, it is cached and will not be recomputed anymore.\n * In that case, the derived will unsubscribe from its dependencies.\n*/\nexport function derivedConstOnceDefined<T>(owner: DebugOwner, fn: (reader: IReader) => T): IObservable<T | undefined> {\n\treturn derivedObservableWithCache<T | undefined>(owner, (reader, lastValue) => lastValue ?? fn(reader));\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable, IReader } from '../base.js';\nimport { DebugOwner } from '../debugName.js';\nimport { derivedObservableWithCache } from '../utils/utils.js';\n\n/**\n * Works like a derived.\n * However, if the value is not undefined, it is cached and will not be recomputed anymore.\n * In that case, the derived will unsubscribe from its dependencies.\n*/\nexport function derivedConstOnceDefined<T>(owner: DebugOwner, fn: (reader: IReader) => T): IObservable<T | undefined> {\n\treturn derivedObservableWithCache<T | undefined>(owner, (reader, lastValue) => lastValue ?? fn(reader));\n}\n"]}

View File

@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// This is a facade for the observable implementation. Only import from here!
export { observableValueOpts } from './observables/observableValueOpts.js';
export { autorun, autorunDelta, autorunHandleChanges, autorunOpts, autorunWithStore, autorunWithStoreHandleChanges } from './reactions/autorun.js';
export { disposableObservableValue } from './observables/observableValue.js';
export { derived, derivedDisposable, derivedHandleChanges, derivedOpts, derivedWithSetter } from './observables/derived.js';
export { ObservablePromise, PromiseResult } from './utils/promise.js';
export { waitForState } from './utils/utilsCancellation.js';
export { debouncedObservable, derivedObservableWithCache, derivedObservableWithWritableCache, keepObserved, mapObservableArrayCached, recomputeInitiallyAndOnChange } from './utils/utils.js';
export { recordChanges, recordChangesLazy } from './changeTracker.js';
export { constObservable } from './observables/constObservable.js';
export { observableSignal } from './observables/observableSignal.js';
export { observableFromEventOpts } from './observables/observableFromEvent.js';
export { observableSignalFromEvent } from './observables/observableSignalFromEvent.js';
export { asyncTransaction, globalTransaction, subtransaction, transaction, TransactionImpl } from './transaction.js';
export { observableFromValueWithChangeEvent, ValueWithChangeEventFromObservable } from './utils/valueWithChangeEvent.js';
export { runOnChange, runOnChangeWithCancellationToken, runOnChangeWithStore } from './utils/runOnChange.js';
export { derivedConstOnceDefined } from './experimental/utils.js';
export { observableFromEvent } from './observables/observableFromEvent.js';
export { observableValue } from './observables/observableValue.js';
export { DebugLocation } from './debugLocation.js';
import { addLogger, setLogObservableFn } from './logging/logging.js';
import { ConsoleObservableLogger, logObservableToConsole } from './logging/consoleObservableLogger.js';
import { DevToolsLogger } from './logging/debugger/devToolsLogger.js';
import { env } from '../process.js';
import { _setDebugGetDependencyGraph } from './observables/baseObservable.js';
import { debugGetDependencyGraph } from './logging/debugGetDependencyGraph.js';
_setDebugGetDependencyGraph(debugGetDependencyGraph);
setLogObservableFn(logObservableToConsole);
// Remove "//" in the next line to enable logging
const enableLogging = false;
if (enableLogging) {
addLogger(new ConsoleObservableLogger());
}
if (env && env['VSCODE_DEV_DEBUG_OBSERVABLES']) {
// To debug observables you also need the extension "ms-vscode.debug-value-editor"
addLogger(DevToolsLogger.getInstance());
}
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,332 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { addLogger } from './logging.js';
import { getClassName } from '../debugName.js';
import { Derived } from '../observables/derivedImpl.js';
let consoleObservableLogger;
export function logObservableToConsole(obs) {
if (!consoleObservableLogger) {
consoleObservableLogger = new ConsoleObservableLogger();
addLogger(consoleObservableLogger);
}
consoleObservableLogger.addFilteredObj(obs);
}
export class ConsoleObservableLogger {
constructor() {
this.indentation = 0;
this.changedObservablesSets = new WeakMap();
}
addFilteredObj(obj) {
if (!this._filteredObjects) {
this._filteredObjects = new Set();
}
this._filteredObjects.add(obj);
}
_isIncluded(obj) {
return this._filteredObjects?.has(obj) ?? true;
}
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)`)];
}
handleObservableCreated(observable) {
if (observable instanceof Derived) {
const derived = observable;
this.changedObservablesSets.set(derived, new Set());
const debugTrackUpdating = false;
if (debugTrackUpdating) {
const updating = [];
derived.__debugUpdating = updating;
const existingBeginUpdate = derived.beginUpdate;
derived.beginUpdate = (obs) => {
updating.push(obs);
return existingBeginUpdate.apply(derived, [obs]);
};
const existingEndUpdate = derived.endUpdate;
derived.endUpdate = (obs) => {
const idx = updating.indexOf(obs);
if (idx === -1) {
console.error('endUpdate called without beginUpdate', derived.debugName, obs.debugName);
}
updating.splice(idx, 1);
return existingEndUpdate.apply(derived, [obs]);
};
}
}
}
handleOnListenerCountChanged(observable, newCount) {
}
handleObservableUpdated(observable, info) {
if (!this._isIncluded(observable)) {
return;
}
if (observable instanceof Derived) {
this._handleDerivedRecomputed(observable, info);
return;
}
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' });
}
handleDerivedDependencyChanged(derived, observable, change) {
if (!this._isIncluded(derived)) {
return;
}
this.changedObservablesSets.get(derived)?.add(observable);
}
_handleDerivedRecomputed(derived, info) {
if (!this._isIncluded(derived)) {
return;
}
const changedObservables = this.changedObservablesSets.get(derived);
if (!changedObservables) {
return;
}
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();
}
handleDerivedCleared(derived) {
if (!this._isIncluded(derived)) {
return;
}
console.log(...this.textToConsoleArgs([
formatKind('derived cleared'),
styled(derived.debugName, { color: 'BlueViolet' }),
]));
}
handleAutorunCreated(autorun) {
if (!this._isIncluded(autorun)) {
return;
}
this.changedObservablesSets.set(autorun, new Set());
}
handleAutorunDisposed(autorun) {
}
handleAutorunDependencyChanged(autorun, observable, change) {
if (!this._isIncluded(autorun)) {
return;
}
this.changedObservablesSets.get(autorun).add(observable);
}
handleAutorunStarted(autorun) {
const changedObservables = this.changedObservablesSets.get(autorun);
if (!changedObservables) {
return;
}
if (this._isIncluded(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 = '';
}
if (this._isIncluded(transaction)) {
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),
};
}
export 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) {
if (typeof value.toString === 'function' && value.toString !== Object.prototype.toString) {
const val = value.toString();
if (val.length <= availableLen) {
return val;
}
return val.substring(0, availableLen - 3) + '...';
}
const className = getClassName(value);
let result = className ? className + '(' : '{ ';
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 += className ? ')' : ' }';
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;
}
//# sourceMappingURL=consoleObservableLogger.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,71 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Derived } from '../observables/derivedImpl.js';
import { FromEventObservable } from '../observables/observableFromEvent.js';
import { ObservableValue } from '../observables/observableValue.js';
import { AutorunObserver } from '../reactions/autorunImpl.js';
import { formatValue } from './consoleObservableLogger.js';
export function debugGetDependencyGraph(obs, options) {
const debugNamePostProcessor = options?.debugNamePostProcessor ?? ((str) => str);
const info = Info.from(obs, debugNamePostProcessor);
if (!info) {
return '';
}
const alreadyListed = new Set();
return formatObservableInfo(info, 0, alreadyListed).trim();
}
function formatObservableInfo(info, indentLevel, alreadyListed) {
const indent = '\t\t'.repeat(indentLevel);
const lines = [];
const isAlreadyListed = alreadyListed.has(info.sourceObj);
if (isAlreadyListed) {
lines.push(`${indent}* ${info.type} ${info.name} (already listed)`);
return lines.join('\n');
}
alreadyListed.add(info.sourceObj);
lines.push(`${indent}* ${info.type} ${info.name}:`);
lines.push(`${indent} value: ${formatValue(info.value, 50)}`);
lines.push(`${indent} state: ${info.state}`);
if (info.dependencies.length > 0) {
lines.push(`${indent} dependencies:`);
for (const dep of info.dependencies) {
lines.push(formatObservableInfo(dep, indentLevel + 1, alreadyListed));
}
}
return lines.join('\n');
}
class Info {
static from(obs, debugNamePostProcessor) {
if (obs instanceof AutorunObserver) {
const state = obs.debugGetState();
return new Info(obs, debugNamePostProcessor(obs.debugName), 'autorun', undefined, state.stateStr, Array.from(state.dependencies).map(dep => Info.from(dep, debugNamePostProcessor) || Info.unknown(dep)));
}
else if (obs instanceof Derived) {
const state = obs.debugGetState();
return new Info(obs, debugNamePostProcessor(obs.debugName), 'derived', state.value, state.stateStr, Array.from(state.dependencies).map(dep => Info.from(dep, debugNamePostProcessor) || Info.unknown(dep)));
}
else if (obs instanceof ObservableValue) {
const state = obs.debugGetState();
return new Info(obs, debugNamePostProcessor(obs.debugName), 'observableValue', state.value, 'upToDate', []);
}
else if (obs instanceof FromEventObservable) {
const state = obs.debugGetState();
return new Info(obs, debugNamePostProcessor(obs.debugName), 'fromEvent', state.value, state.hasValue ? 'upToDate' : 'initial', []);
}
return undefined;
}
static unknown(obs) {
return new Info(obs, '(unknown)', 'unknown', undefined, 'unknown', []);
}
constructor(sourceObj, name, type, value, state, dependencies) {
this.sourceObj = sourceObj;
this.name = name;
this.type = type;
this.value = value;
this.state = state;
this.dependencies = dependencies;
}
}
//# sourceMappingURL=debugGetDependencyGraph.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,64 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { SimpleTypedRpcConnection } from './rpc.js';
export function registerDebugChannel(channelId, createClient) {
const g = globalThis;
let queuedNotifications = [];
let curHost = undefined;
const { channel, handler } = createChannelFactoryFromDebugChannel({
sendNotification: (data) => {
if (curHost) {
curHost.sendNotification(data);
}
else {
queuedNotifications.push(data);
}
},
});
let curClient = undefined;
(g.$$debugValueEditor_debugChannels ?? (g.$$debugValueEditor_debugChannels = {}))[channelId] = (host) => {
curClient = createClient();
curHost = host;
for (const n of queuedNotifications) {
host.sendNotification(n);
}
queuedNotifications = [];
return handler;
};
return SimpleTypedRpcConnection.createClient(channel, () => {
if (!curClient) {
throw new Error('Not supported');
}
return curClient;
});
}
function createChannelFactoryFromDebugChannel(host) {
let h;
const channel = (handler) => {
h = handler;
return {
sendNotification: data => {
host.sendNotification(data);
},
sendRequest: data => {
throw new Error('not supported');
},
};
};
return {
channel: channel,
handler: {
handleRequest: (data) => {
if (data.type === 'notification') {
return h?.handleNotification(data.data);
}
else {
return h?.handleRequest(data.data);
}
},
},
};
}
//# sourceMappingURL=debuggerRpc.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,440 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { AutorunObserver } from '../../reactions/autorunImpl.js';
import { formatValue } from '../consoleObservableLogger.js';
import { registerDebugChannel } from './debuggerRpc.js';
import { deepAssign, deepAssignDeleteNulls, Throttler } from './utils.js';
import { isDefined } from '../../../types.js';
import { FromEventObservable } from '../../observables/observableFromEvent.js';
import { BugIndicatingError, onUnexpectedError } from '../../../errors.js';
import { Derived } from '../../observables/derivedImpl.js';
import { ObservableValue } from '../../observables/observableValue.js';
import { DebugLocation } from '../../debugLocation.js';
export class DevToolsLogger {
static { this._instance = undefined; }
static getInstance() {
if (DevToolsLogger._instance === undefined) {
DevToolsLogger._instance = new DevToolsLogger();
}
return DevToolsLogger._instance;
}
getTransactionState() {
const affected = [];
const txs = [...this._activeTransactions];
if (txs.length === 0) {
return undefined;
}
const observerQueue = txs.flatMap(t => t.debugGetUpdatingObservers() ?? []).map(o => o.observer);
const processedObservers = new Set();
while (observerQueue.length > 0) {
const observer = observerQueue.shift();
if (processedObservers.has(observer)) {
continue;
}
processedObservers.add(observer);
const state = this._getInfo(observer, d => {
if (!processedObservers.has(d)) {
observerQueue.push(d);
}
});
if (state) {
affected.push(state);
}
}
return { names: txs.map(t => t.getDebugName() ?? 'tx'), affected };
}
_getObservableInfo(observable) {
const info = this._instanceInfos.get(observable);
if (!info) {
onUnexpectedError(new BugIndicatingError('No info found'));
return undefined;
}
return info;
}
_getAutorunInfo(autorun) {
const info = this._instanceInfos.get(autorun);
if (!info) {
onUnexpectedError(new BugIndicatingError('No info found'));
return undefined;
}
return info;
}
_getInfo(observer, queue) {
if (observer instanceof Derived) {
const observersToUpdate = [...observer.debugGetObservers()];
for (const o of observersToUpdate) {
queue(o);
}
const info = this._getObservableInfo(observer);
if (!info) {
return;
}
const observerState = observer.debugGetState();
const base = { name: observer.debugName, instanceId: info.instanceId, updateCount: observerState.updateCount };
const changedDependencies = [...info.changedObservables].map(o => this._instanceInfos.get(o)?.instanceId).filter(isDefined);
if (observerState.isComputing) {
return { ...base, type: 'observable/derived', state: 'updating', changedDependencies, initialComputation: false };
}
switch (observerState.state) {
case 0 /* DerivedState.initial */:
return { ...base, type: 'observable/derived', state: 'noValue' };
case 3 /* DerivedState.upToDate */:
return { ...base, type: 'observable/derived', state: 'upToDate' };
case 2 /* DerivedState.stale */:
return { ...base, type: 'observable/derived', state: 'stale', changedDependencies };
case 1 /* DerivedState.dependenciesMightHaveChanged */:
return { ...base, type: 'observable/derived', state: 'possiblyStale' };
}
}
else if (observer instanceof AutorunObserver) {
const info = this._getAutorunInfo(observer);
if (!info) {
return undefined;
}
const base = { name: observer.debugName, instanceId: info.instanceId, updateCount: info.updateCount };
const changedDependencies = [...info.changedObservables].map(o => this._instanceInfos.get(o).instanceId);
if (observer.debugGetState().isRunning) {
return { ...base, type: 'autorun', state: 'updating', changedDependencies };
}
switch (observer.debugGetState().state) {
case 3 /* AutorunState.upToDate */:
return { ...base, type: 'autorun', state: 'upToDate' };
case 2 /* AutorunState.stale */:
return { ...base, type: 'autorun', state: 'stale', changedDependencies };
case 1 /* AutorunState.dependenciesMightHaveChanged */:
return { ...base, type: 'autorun', state: 'possiblyStale' };
}
}
return undefined;
}
_formatObservable(obs) {
const info = this._getObservableInfo(obs);
if (!info) {
return undefined;
}
return { name: obs.debugName, instanceId: info.instanceId };
}
_formatObserver(obs) {
if (obs instanceof Derived) {
return { name: obs.toString(), instanceId: this._getObservableInfo(obs)?.instanceId };
}
const autorunInfo = this._getAutorunInfo(obs);
if (autorunInfo) {
return { name: obs.toString(), instanceId: autorunInfo.instanceId };
}
return undefined;
}
constructor() {
this._declarationId = 0;
this._instanceId = 0;
this._declarations = new Map();
this._instanceInfos = new WeakMap();
this._aliveInstances = new Map();
this._activeTransactions = new Set();
this._channel = registerDebugChannel('observableDevTools', () => {
return {
notifications: {
setDeclarationIdFilter: declarationIds => {
},
logObservableValue: (observableId) => {
console.log('logObservableValue', observableId);
},
flushUpdates: () => {
this._flushUpdates();
},
resetUpdates: () => {
this._pendingChanges = null;
this._channel.api.notifications.handleChange(this._fullState, true);
},
},
requests: {
getDeclarations: () => {
const result = {};
for (const decl of this._declarations.values()) {
result[decl.id] = decl;
}
return { decls: result };
},
getSummarizedInstances: () => {
return null;
},
getObservableValueInfo: instanceId => {
const obs = this._aliveInstances.get(instanceId);
return {
observers: [...obs.debugGetObservers()].map(d => this._formatObserver(d)).filter(isDefined),
};
},
getDerivedInfo: instanceId => {
const d = this._aliveInstances.get(instanceId);
return {
dependencies: [...d.debugGetState().dependencies].map(d => this._formatObservable(d)).filter(isDefined),
observers: [...d.debugGetObservers()].map(d => this._formatObserver(d)).filter(isDefined),
};
},
getAutorunInfo: instanceId => {
const obs = this._aliveInstances.get(instanceId);
return {
dependencies: [...obs.debugGetState().dependencies].map(d => this._formatObservable(d)).filter(isDefined),
};
},
getTransactionState: () => {
return this.getTransactionState();
},
setValue: (instanceId, jsonValue) => {
const obs = this._aliveInstances.get(instanceId);
if (obs instanceof Derived) {
obs.debugSetValue(jsonValue);
}
else if (obs instanceof ObservableValue) {
obs.debugSetValue(jsonValue);
}
else if (obs instanceof FromEventObservable) {
obs.debugSetValue(jsonValue);
}
else {
throw new BugIndicatingError('Observable is not supported');
}
const observers = [...obs.debugGetObservers()];
for (const d of observers) {
d.beginUpdate(obs);
}
for (const d of observers) {
d.handleChange(obs, undefined);
}
for (const d of observers) {
d.endUpdate(obs);
}
},
getValue: instanceId => {
const obs = this._aliveInstances.get(instanceId);
if (obs instanceof Derived) {
return formatValue(obs.debugGetState().value, 200);
}
else if (obs instanceof ObservableValue) {
return formatValue(obs.debugGetState().value, 200);
}
return undefined;
},
logValue: (instanceId) => {
const obs = this._aliveInstances.get(instanceId);
if (obs && 'get' in obs) {
console.log('Logged Value:', obs.get());
}
else {
throw new BugIndicatingError('Observable is not supported');
}
},
rerun: (instanceId) => {
const obs = this._aliveInstances.get(instanceId);
if (obs instanceof Derived) {
obs.debugRecompute();
}
else if (obs instanceof AutorunObserver) {
obs.debugRerun();
}
else {
throw new BugIndicatingError('Observable is not supported');
}
},
}
};
});
this._pendingChanges = null;
this._changeThrottler = new Throttler();
this._fullState = {};
this._flushUpdates = () => {
if (this._pendingChanges !== null) {
this._channel.api.notifications.handleChange(this._pendingChanges, false);
this._pendingChanges = null;
}
};
DebugLocation.enable();
}
_handleChange(update) {
deepAssignDeleteNulls(this._fullState, update);
if (this._pendingChanges === null) {
this._pendingChanges = update;
}
else {
deepAssign(this._pendingChanges, update);
}
this._changeThrottler.throttle(this._flushUpdates, 10);
}
_getDeclarationId(type, location) {
if (!location) {
return -1;
}
let decInfo = this._declarations.get(location.id);
if (decInfo === undefined) {
decInfo = {
id: this._declarationId++,
type,
url: location.fileName,
line: location.line,
column: location.column,
};
this._declarations.set(location.id, decInfo);
this._handleChange({ decls: { [decInfo.id]: decInfo } });
}
return decInfo.id;
}
handleObservableCreated(observable, location) {
const declarationId = this._getDeclarationId('observable/value', location);
const info = {
declarationId,
instanceId: this._instanceId++,
listenerCount: 0,
lastValue: undefined,
updateCount: 0,
changedObservables: new Set(),
};
this._instanceInfos.set(observable, info);
}
handleOnListenerCountChanged(observable, newCount) {
const info = this._getObservableInfo(observable);
if (!info) {
return;
}
if (info.listenerCount === 0 && newCount > 0) {
const type = observable instanceof Derived ? 'observable/derived' : 'observable/value';
this._aliveInstances.set(info.instanceId, observable);
this._handleChange({
instances: {
[info.instanceId]: {
instanceId: info.instanceId,
declarationId: info.declarationId,
formattedValue: info.lastValue,
type,
name: observable.debugName,
}
}
});
}
else if (info.listenerCount > 0 && newCount === 0) {
this._handleChange({
instances: { [info.instanceId]: null }
});
this._aliveInstances.delete(info.instanceId);
}
info.listenerCount = newCount;
}
handleObservableUpdated(observable, changeInfo) {
if (observable instanceof Derived) {
this._handleDerivedRecomputed(observable, changeInfo);
return;
}
const info = this._getObservableInfo(observable);
if (info) {
if (changeInfo.didChange) {
info.lastValue = formatValue(changeInfo.newValue, 30);
if (info.listenerCount > 0) {
this._handleChange({
instances: { [info.instanceId]: { formattedValue: info.lastValue } }
});
}
}
}
}
handleAutorunCreated(autorun, location) {
const declarationId = this._getDeclarationId('autorun', location);
const info = {
declarationId,
instanceId: this._instanceId++,
updateCount: 0,
changedObservables: new Set(),
};
this._instanceInfos.set(autorun, info);
this._aliveInstances.set(info.instanceId, autorun);
if (info) {
this._handleChange({
instances: {
[info.instanceId]: {
instanceId: info.instanceId,
declarationId: info.declarationId,
runCount: 0,
type: 'autorun',
name: autorun.debugName,
}
}
});
}
}
handleAutorunDisposed(autorun) {
const info = this._getAutorunInfo(autorun);
if (!info) {
return;
}
this._handleChange({
instances: { [info.instanceId]: null }
});
this._instanceInfos.delete(autorun);
this._aliveInstances.delete(info.instanceId);
}
handleAutorunDependencyChanged(autorun, observable, change) {
const info = this._getAutorunInfo(autorun);
if (!info) {
return;
}
info.changedObservables.add(observable);
}
handleAutorunStarted(autorun) {
}
handleAutorunFinished(autorun) {
const info = this._getAutorunInfo(autorun);
if (!info) {
return;
}
info.changedObservables.clear();
info.updateCount++;
this._handleChange({
instances: { [info.instanceId]: { runCount: info.updateCount } }
});
}
handleDerivedDependencyChanged(derived, observable, change) {
const info = this._getObservableInfo(derived);
if (info) {
info.changedObservables.add(observable);
}
}
_handleDerivedRecomputed(observable, changeInfo) {
const info = this._getObservableInfo(observable);
if (!info) {
return;
}
const formattedValue = formatValue(changeInfo.newValue, 30);
info.updateCount++;
info.changedObservables.clear();
info.lastValue = formattedValue;
if (info.listenerCount > 0) {
this._handleChange({
instances: { [info.instanceId]: { formattedValue: formattedValue, recomputationCount: info.updateCount } }
});
}
}
handleDerivedCleared(observable) {
const info = this._getObservableInfo(observable);
if (!info) {
return;
}
info.lastValue = undefined;
info.changedObservables.clear();
if (info.listenerCount > 0) {
this._handleChange({
instances: {
[info.instanceId]: {
formattedValue: undefined,
}
}
});
}
}
handleBeginTransaction(transaction) {
this._activeTransactions.add(transaction);
}
handleEndTransaction(transaction) {
this._activeTransactions.delete(transaction);
}
}
//# sourceMappingURL=devToolsLogger.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,55 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class SimpleTypedRpcConnection {
static createClient(channelFactory, getHandler) {
return new SimpleTypedRpcConnection(channelFactory, getHandler);
}
constructor(_channelFactory, _getHandler) {
this._channelFactory = _channelFactory;
this._getHandler = _getHandler;
this._channel = this._channelFactory({
handleNotification: (notificationData) => {
const m = notificationData;
const fn = this._getHandler().notifications[m[0]];
if (!fn) {
throw new Error(`Unknown notification "${m[0]}"!`);
}
fn(...m[1]);
},
handleRequest: (requestData) => {
const m = requestData;
try {
const result = this._getHandler().requests[m[0]](...m[1]);
return { type: 'result', value: result };
}
catch (e) {
return { type: 'error', value: e };
}
},
});
const requests = new Proxy({}, {
get: (target, key) => {
return async (...args) => {
const result = await this._channel.sendRequest([key, args]);
if (result.type === 'error') {
throw result.value;
}
else {
return result.value;
}
};
}
});
const notifications = new Proxy({}, {
get: (target, key) => {
return (...args) => {
this._channel.sendNotification([key, args]);
};
}
});
this.api = { notifications: notifications, requests: requests };
}
}
//# sourceMappingURL=rpc.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,46 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export class Throttler {
constructor() {
this._timeout = undefined;
}
throttle(fn, timeoutMs) {
if (this._timeout === undefined) {
this._timeout = setTimeout(() => {
this._timeout = undefined;
fn();
}, timeoutMs);
}
}
dispose() {
if (this._timeout !== undefined) {
clearTimeout(this._timeout);
}
}
}
export function deepAssign(target, source) {
for (const key in source) {
if (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {
deepAssign(target[key], source[key]);
}
else {
target[key] = source[key];
}
}
}
export function deepAssignDeleteNulls(target, source) {
for (const key in source) {
if (source[key] === null) {
delete target[key];
}
else if (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {
deepAssignDeleteNulls(target[key], source[key]);
}
else {
target[key] = source[key];
}
}
}
//# sourceMappingURL=utils.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/logging/debugger/utils.ts","vs/base/common/observableInternal/logging/debugger/utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAIhG,MAAM,OAAO,SAAS;IAAtB;QACS,aAAQ,GAAwB,SAAS,CAAC;IAgBnD,CAAC;IAdO,QAAQ,CAAC,EAAc,EAAE,SAAiB;QAChD,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,GAAG,UAAU,CAAC,GAAG,EAAE;gBAC/B,IAAI,CAAC,QAAQ,GAAG,SAAS,CAAC;gBAC1B,EAAE,EAAE,CAAC;YACN,CAAC,EAAE,SAAS,CAAC,CAAC;QACf,CAAC;IACF,CAAC;IAED,OAAO;QACN,IAAI,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YACjC,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAC7B,CAAC;IACF,CAAC;CACD;AAED,MAAM,UAAU,UAAU,CAAI,MAAS,EAAE,MAAS;IACjD,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1G,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACtC,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;AACF,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAI,MAAS,EAAE,MAAS;IAC5D,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QAC1B,IAAI,MAAM,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;aAAM,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;YACjH,qBAAqB,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACP,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;IACF,CAAC;AACF,CAAC","file":"utils.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../lifecycle.js';\n\nexport class Throttler implements IDisposable {\n\tprivate _timeout: Timeout | undefined = undefined;\n\n\tpublic throttle(fn: () => void, timeoutMs: number): void {\n\t\tif (this._timeout === undefined) {\n\t\t\tthis._timeout = setTimeout(() => {\n\t\t\t\tthis._timeout = undefined;\n\t\t\t\tfn();\n\t\t\t}, timeoutMs);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tif (this._timeout !== undefined) {\n\t\t\tclearTimeout(this._timeout);\n\t\t}\n\t}\n}\n\nexport function deepAssign<T>(target: T, source: T): void {\n\tfor (const key in source) {\n\t\tif (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {\n\t\t\tdeepAssign(target[key], source[key]);\n\t\t} else {\n\t\t\ttarget[key] = source[key];\n\t\t}\n\t}\n}\n\nexport function deepAssignDeleteNulls<T>(target: T, source: T): void {\n\tfor (const key in source) {\n\t\tif (source[key] === null) {\n\t\t\tdelete target[key];\n\t\t} else if (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {\n\t\t\tdeepAssignDeleteNulls(target[key], source[key]);\n\t\t} else {\n\t\t\ttarget[key] = source[key];\n\t\t}\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IDisposable } from '../../../lifecycle.js';\n\nexport class Throttler implements IDisposable {\n\tprivate _timeout: Timeout | undefined = undefined;\n\n\tpublic throttle(fn: () => void, timeoutMs: number): void {\n\t\tif (this._timeout === undefined) {\n\t\t\tthis._timeout = setTimeout(() => {\n\t\t\t\tthis._timeout = undefined;\n\t\t\t\tfn();\n\t\t\t}, timeoutMs);\n\t\t}\n\t}\n\n\tdispose(): void {\n\t\tif (this._timeout !== undefined) {\n\t\t\tclearTimeout(this._timeout);\n\t\t}\n\t}\n}\n\nexport function deepAssign<T>(target: T, source: T): void {\n\tfor (const key in source) {\n\t\tif (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {\n\t\t\tdeepAssign(target[key], source[key]);\n\t\t} else {\n\t\t\ttarget[key] = source[key];\n\t\t}\n\t}\n}\n\nexport function deepAssignDeleteNulls<T>(target: T, source: T): void {\n\tfor (const key in source) {\n\t\tif (source[key] === null) {\n\t\t\tdelete target[key];\n\t\t} else if (!!target[key] && typeof target[key] === 'object' && !!source[key] && typeof source[key] === 'object') {\n\t\t\tdeepAssignDeleteNulls(target[key], source[key]);\n\t\t} else {\n\t\t\ttarget[key] = source[key];\n\t\t}\n\t}\n}\n"]}

View File

@@ -0,0 +1,89 @@
/*---------------------------------------------------------------------------------------------
* 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 addLogger(logger) {
if (!globalObservableLogger) {
globalObservableLogger = logger;
}
else if (globalObservableLogger instanceof ComposedLogger) {
globalObservableLogger.loggers.push(logger);
}
else {
globalObservableLogger = new ComposedLogger([globalObservableLogger, logger]);
}
}
export function getLogger() {
return globalObservableLogger;
}
let globalObservableLoggerFn = undefined;
export function setLogObservableFn(fn) {
globalObservableLoggerFn = fn;
}
class ComposedLogger {
constructor(loggers) {
this.loggers = loggers;
}
handleObservableCreated(observable, location) {
for (const logger of this.loggers) {
logger.handleObservableCreated(observable, location);
}
}
handleOnListenerCountChanged(observable, newCount) {
for (const logger of this.loggers) {
logger.handleOnListenerCountChanged(observable, newCount);
}
}
handleObservableUpdated(observable, info) {
for (const logger of this.loggers) {
logger.handleObservableUpdated(observable, info);
}
}
handleAutorunCreated(autorun, location) {
for (const logger of this.loggers) {
logger.handleAutorunCreated(autorun, location);
}
}
handleAutorunDisposed(autorun) {
for (const logger of this.loggers) {
logger.handleAutorunDisposed(autorun);
}
}
handleAutorunDependencyChanged(autorun, observable, change) {
for (const logger of this.loggers) {
logger.handleAutorunDependencyChanged(autorun, observable, change);
}
}
handleAutorunStarted(autorun) {
for (const logger of this.loggers) {
logger.handleAutorunStarted(autorun);
}
}
handleAutorunFinished(autorun) {
for (const logger of this.loggers) {
logger.handleAutorunFinished(autorun);
}
}
handleDerivedDependencyChanged(derived, observable, change) {
for (const logger of this.loggers) {
logger.handleDerivedDependencyChanged(derived, observable, change);
}
}
handleDerivedCleared(observable) {
for (const logger of this.loggers) {
logger.handleDerivedCleared(observable);
}
}
handleBeginTransaction(transaction) {
for (const logger of this.loggers) {
logger.handleBeginTransaction(transaction);
}
}
handleEndTransaction(transaction) {
for (const logger of this.loggers) {
logger.handleEndTransaction(transaction);
}
}
}
//# sourceMappingURL=logging.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,112 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DebugLocation } from '../debugLocation.js';
import { getFunctionName } from '../debugName.js';
import { getLogger } from '../logging/logging.js';
let _derived;
/**
* @internal
* This is to allow splitting files.
*/
export function _setDerivedOpts(derived) {
_derived = derived;
}
let _recomputeInitiallyAndOnChange;
export function _setRecomputeInitiallyAndOnChange(recomputeInitiallyAndOnChange) {
_recomputeInitiallyAndOnChange = recomputeInitiallyAndOnChange;
}
let _keepObserved;
export function _setKeepObserved(keepObserved) {
_keepObserved = keepObserved;
}
let _debugGetDependencyGraph;
export function _setDebugGetDependencyGraph(debugGetDependencyGraph) {
_debugGetDependencyGraph = debugGetDependencyGraph;
}
export class ConvenientObservable {
get TChange() { return null; }
reportChanges() {
this.get();
}
/** @sealed */
read(reader) {
if (reader) {
return reader.readObservable(this);
}
else {
return this.get();
}
}
map(fnOrOwner, fnOrUndefined, debugLocation = DebugLocation.ofCaller()) {
const owner = fnOrUndefined === undefined ? undefined : fnOrOwner;
const fn = fnOrUndefined === undefined ? fnOrOwner : fnOrUndefined;
return _derived({
owner,
debugName: () => {
const name = getFunctionName(fn);
if (name !== undefined) {
return name;
}
// regexp to match `x => x.y` or `x => x?.y` where x and y can be arbitrary identifiers (uses backref):
const regexp = /^\s*\(?\s*([a-zA-Z_$][a-zA-Z_$0-9]*)\s*\)?\s*=>\s*\1(?:\??)\.([a-zA-Z_$][a-zA-Z_$0-9]*)\s*$/;
const match = regexp.exec(fn.toString());
if (match) {
return `${this.debugName}.${match[2]}`;
}
if (!owner) {
return `${this.debugName} (mapped)`;
}
return undefined;
},
debugReferenceFn: fn,
}, (reader) => fn(this.read(reader), reader), debugLocation);
}
/**
* @sealed
* Converts an observable of an observable value into a direct observable of the value.
*/
flatten() {
return _derived({
owner: undefined,
debugName: () => `${this.debugName} (flattened)`,
}, (reader) => this.read(reader).read(reader));
}
recomputeInitiallyAndOnChange(store, handleValue) {
store.add(_recomputeInitiallyAndOnChange(this, handleValue));
return this;
}
}
export class BaseObservable extends ConvenientObservable {
constructor(debugLocation) {
super();
this._observers = new Set();
getLogger()?.handleObservableCreated(this, debugLocation);
}
addObserver(observer) {
const len = this._observers.size;
this._observers.add(observer);
if (len === 0) {
this.onFirstObserverAdded();
}
if (len !== this._observers.size) {
getLogger()?.handleOnListenerCountChanged(this, this._observers.size);
}
}
removeObserver(observer) {
const deleted = this._observers.delete(observer);
if (deleted && this._observers.size === 0) {
this.onLastObserverRemoved();
}
if (deleted) {
getLogger()?.handleOnListenerCountChanged(this, this._observers.size);
}
}
onFirstObserverAdded() { }
onLastObserverRemoved() { }
debugGetObservers() {
return this._observers;
}
}
//# sourceMappingURL=baseObservable.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ConvenientObservable } from './baseObservable.js';
/**
* Represents an efficient observable whose value never changes.
*/
export function constObservable(value) {
return new ConstObservable(value);
}
class ConstObservable extends ConvenientObservable {
constructor(value) {
super();
this.value = value;
}
get debugName() {
return this.toString();
}
get() {
return this.value;
}
addObserver(observer) {
// NO OP
}
removeObserver(observer) {
// NO OP
}
toString() {
return `Const: ${this.value}`;
}
}
//# sourceMappingURL=constObservable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/observables/constObservable.ts","vs/base/common/observableInternal/observables/constObservable.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAE3D;;GAEG;AAEH,MAAM,UAAU,eAAe,CAAI,KAAQ;IAC1C,OAAO,IAAI,eAAe,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AACD,MAAM,eAAmB,SAAQ,oBAA6B;IAC7D,YAA6B,KAAQ;QACpC,KAAK,EAAE,CAAC;QADoB,UAAK,GAAL,KAAK,CAAG;IAErC,CAAC;IAED,IAAoB,SAAS;QAC5B,OAAO,IAAI,CAAC,QAAQ,EAAE,CAAC;IACxB,CAAC;IAEM,GAAG;QACT,OAAO,IAAI,CAAC,KAAK,CAAC;IACnB,CAAC;IACM,WAAW,CAAC,QAAmB;QACrC,QAAQ;IACT,CAAC;IACM,cAAc,CAAC,QAAmB;QACxC,QAAQ;IACT,CAAC;IAEQ,QAAQ;QAChB,OAAO,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC;IAC/B,CAAC;CACD","file":"constObservable.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable, IObserver } from '../base.js';\nimport { ConvenientObservable } from './baseObservable.js';\n\n/**\n * Represents an efficient observable whose value never changes.\n */\n\nexport function constObservable<T>(value: T): IObservable<T> {\n\treturn new ConstObservable(value);\n}\nclass ConstObservable<T> extends ConvenientObservable<T, void> {\n\tconstructor(private readonly value: T) {\n\t\tsuper();\n\t}\n\n\tpublic override get debugName(): string {\n\t\treturn this.toString();\n\t}\n\n\tpublic get(): T {\n\t\treturn this.value;\n\t}\n\tpublic addObserver(observer: IObserver): void {\n\t\t// NO OP\n\t}\n\tpublic removeObserver(observer: IObserver): void {\n\t\t// NO OP\n\t}\n\n\toverride toString(): string {\n\t\treturn `Const: ${this.value}`;\n\t}\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable, IObserver } from '../base.js';\nimport { ConvenientObservable } from './baseObservable.js';\n\n/**\n * Represents an efficient observable whose value never changes.\n */\n\nexport function constObservable<T>(value: T): IObservable<T> {\n\treturn new ConstObservable(value);\n}\nclass ConstObservable<T> extends ConvenientObservable<T, void> {\n\tconstructor(private readonly value: T) {\n\t\tsuper();\n\t}\n\n\tpublic override get debugName(): string {\n\t\treturn this.toString();\n\t}\n\n\tpublic get(): T {\n\t\treturn this.value;\n\t}\n\tpublic addObserver(observer: IObserver): void {\n\t\t// NO OP\n\t}\n\tpublic removeObserver(observer: IObserver): void {\n\t\t// NO OP\n\t}\n\n\toverride toString(): string {\n\t\treturn `Const: ${this.value}`;\n\t}\n}\n"]}

View File

@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DisposableStore, strictEquals } from '../commonFacade/deps.js';
import { DebugLocation } from '../debugLocation.js';
import { DebugNameData } from '../debugName.js';
import { _setDerivedOpts } from './baseObservable.js';
import { Derived, DerivedWithSetter } from './derivedImpl.js';
export function derived(computeFnOrOwner, computeFn, debugLocation = DebugLocation.ofCaller()) {
if (computeFn !== undefined) {
return new Derived(new DebugNameData(computeFnOrOwner, undefined, computeFn), computeFn, undefined, undefined, strictEquals, debugLocation);
}
return new Derived(new DebugNameData(undefined, undefined, computeFnOrOwner), computeFnOrOwner, undefined, undefined, strictEquals, debugLocation);
}
export function derivedWithSetter(owner, computeFn, setter, debugLocation = DebugLocation.ofCaller()) {
return new DerivedWithSetter(new DebugNameData(owner, undefined, computeFn), computeFn, undefined, undefined, strictEquals, setter, debugLocation);
}
export function derivedOpts(options, computeFn, debugLocation = DebugLocation.ofCaller()) {
return new Derived(new DebugNameData(options.owner, options.debugName, options.debugReferenceFn), computeFn, undefined, options.onLastObserverRemoved, options.equalsFn ?? strictEquals, debugLocation);
}
_setDerivedOpts(derivedOpts);
/**
* Represents an observable that is derived from other observables.
* The value is only recomputed when absolutely needed.
*
* {@link computeFn} should start with a JS Doc using `@description` to name the derived.
*
* Use `createEmptyChangeSummary` to create a "change summary" that can collect the changes.
* Use `handleChange` to add a reported change to the change summary.
* The compute function is given the last change summary.
* The change summary is discarded after the compute function was called.
*
* @see derived
*/
export function derivedHandleChanges(options, computeFn, debugLocation = DebugLocation.ofCaller()) {
return new Derived(new DebugNameData(options.owner, options.debugName, undefined), computeFn, options.changeTracker, undefined, options.equalityComparer ?? strictEquals, debugLocation);
}
export function derivedDisposable(computeFnOrOwner, computeFnOrUndefined, debugLocation = DebugLocation.ofCaller()) {
let computeFn;
let owner;
if (computeFnOrUndefined === undefined) {
computeFn = computeFnOrOwner;
owner = undefined;
}
else {
owner = computeFnOrOwner;
computeFn = computeFnOrUndefined;
}
let store = undefined;
return new Derived(new DebugNameData(owner, undefined, computeFn), r => {
if (!store) {
store = new DisposableStore();
}
else {
store.clear();
}
const result = computeFn(r);
if (result) {
store.add(result);
}
return result;
}, undefined, () => {
if (store) {
store.dispose();
store = undefined;
}
}, strictEquals, debugLocation);
}
//# sourceMappingURL=derived.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,348 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { BaseObservable } from './baseObservable.js';
import { BugIndicatingError, DisposableStore, assertFn, onBugIndicatingError } from '../commonFacade/deps.js';
import { getLogger } from '../logging/logging.js';
function derivedStateToString(state) {
switch (state) {
case 0 /* DerivedState.initial */: return 'initial';
case 1 /* DerivedState.dependenciesMightHaveChanged */: return 'dependenciesMightHaveChanged';
case 2 /* DerivedState.stale */: return 'stale';
case 3 /* DerivedState.upToDate */: return 'upToDate';
default: return '<unknown>';
}
}
export class Derived extends BaseObservable {
get debugName() {
return this._debugNameData.getDebugName(this) ?? '(anonymous)';
}
constructor(_debugNameData, _computeFn, _changeTracker, _handleLastObserverRemoved = undefined, _equalityComparator, debugLocation) {
super(debugLocation);
this._debugNameData = _debugNameData;
this._computeFn = _computeFn;
this._changeTracker = _changeTracker;
this._handleLastObserverRemoved = _handleLastObserverRemoved;
this._equalityComparator = _equalityComparator;
this._state = 0 /* DerivedState.initial */;
this._value = undefined;
this._updateCount = 0;
this._dependencies = new Set();
this._dependenciesToBeRemoved = new Set();
this._changeSummary = undefined;
this._isUpdating = false;
this._isComputing = false;
this._didReportChange = false;
this._isInBeforeUpdate = false;
this._isReaderValid = false;
this._store = undefined;
this._delayedStore = undefined;
this._removedObserverToCallEndUpdateOn = null;
this._changeSummary = this._changeTracker?.createChangeSummary(undefined);
}
onLastObserverRemoved() {
/**
* We are not tracking changes anymore, thus we have to assume
* that our cache is invalid.
*/
this._state = 0 /* DerivedState.initial */;
this._value = undefined;
getLogger()?.handleDerivedCleared(this);
for (const d of this._dependencies) {
d.removeObserver(this);
}
this._dependencies.clear();
if (this._store !== undefined) {
this._store.dispose();
this._store = undefined;
}
if (this._delayedStore !== undefined) {
this._delayedStore.dispose();
this._delayedStore = undefined;
}
this._handleLastObserverRemoved?.();
}
get() {
const checkEnabled = false; // TODO set to true
if (this._isComputing && checkEnabled) {
// investigate why this fails in the diff editor!
throw new BugIndicatingError('Cyclic deriveds are not supported yet!');
}
if (this._observers.size === 0) {
let result;
// Without observers, we don't know when to clean up stuff.
// Thus, we don't cache anything to prevent memory leaks.
try {
this._isReaderValid = true;
let changeSummary = undefined;
if (this._changeTracker) {
changeSummary = this._changeTracker.createChangeSummary(undefined);
this._changeTracker.beforeUpdate?.(this, changeSummary);
}
result = this._computeFn(this, changeSummary);
}
finally {
this._isReaderValid = false;
}
// Clear new dependencies
this.onLastObserverRemoved();
return result;
}
else {
do {
// We might not get a notification for a dependency that changed while it is updating,
// thus we also have to ask all our depedencies if they changed in this case.
if (this._state === 1 /* DerivedState.dependenciesMightHaveChanged */) {
for (const d of this._dependencies) {
/** might call {@link handleChange} indirectly, which could make us stale */
d.reportChanges();
if (this._state === 2 /* DerivedState.stale */) {
// The other dependencies will refresh on demand, so early break
break;
}
}
}
// We called report changes of all dependencies.
// If we are still not stale, we can assume to be up to date again.
if (this._state === 1 /* DerivedState.dependenciesMightHaveChanged */) {
this._state = 3 /* DerivedState.upToDate */;
}
if (this._state !== 3 /* DerivedState.upToDate */) {
this._recompute();
}
// In case recomputation changed one of our dependencies, we need to recompute again.
} while (this._state !== 3 /* DerivedState.upToDate */);
return this._value;
}
}
_recompute() {
let didChange = false;
this._isComputing = true;
this._didReportChange = false;
const emptySet = this._dependenciesToBeRemoved;
this._dependenciesToBeRemoved = this._dependencies;
this._dependencies = emptySet;
try {
const changeSummary = this._changeSummary;
this._isReaderValid = true;
if (this._changeTracker) {
this._isInBeforeUpdate = true;
this._changeTracker.beforeUpdate?.(this, changeSummary);
this._isInBeforeUpdate = false;
this._changeSummary = this._changeTracker?.createChangeSummary(changeSummary);
}
const hadValue = this._state !== 0 /* DerivedState.initial */;
const oldValue = this._value;
this._state = 3 /* DerivedState.upToDate */;
const delayedStore = this._delayedStore;
if (delayedStore !== undefined) {
this._delayedStore = undefined;
}
try {
if (this._store !== undefined) {
this._store.dispose();
this._store = undefined;
}
/** might call {@link handleChange} indirectly, which could invalidate us */
this._value = this._computeFn(this, changeSummary);
}
finally {
this._isReaderValid = false;
// We don't want our observed observables to think that they are (not even temporarily) not being observed.
// Thus, we only unsubscribe from observables that are definitely not read anymore.
for (const o of this._dependenciesToBeRemoved) {
o.removeObserver(this);
}
this._dependenciesToBeRemoved.clear();
if (delayedStore !== undefined) {
delayedStore.dispose();
}
}
didChange = this._didReportChange || (hadValue && !(this._equalityComparator(oldValue, this._value)));
getLogger()?.handleObservableUpdated(this, {
oldValue,
newValue: this._value,
change: undefined,
didChange,
hadValue,
});
}
catch (e) {
onBugIndicatingError(e);
}
this._isComputing = false;
if (!this._didReportChange && didChange) {
for (const r of this._observers) {
r.handleChange(this, undefined);
}
}
else {
this._didReportChange = false;
}
}
toString() {
return `LazyDerived<${this.debugName}>`;
}
// IObserver Implementation
beginUpdate(_observable) {
if (this._isUpdating) {
throw new BugIndicatingError('Cyclic deriveds are not supported yet!');
}
this._updateCount++;
this._isUpdating = true;
try {
const propagateBeginUpdate = this._updateCount === 1;
if (this._state === 3 /* DerivedState.upToDate */) {
this._state = 1 /* DerivedState.dependenciesMightHaveChanged */;
// If we propagate begin update, that will already signal a possible change.
if (!propagateBeginUpdate) {
for (const r of this._observers) {
r.handlePossibleChange(this);
}
}
}
if (propagateBeginUpdate) {
for (const r of this._observers) {
r.beginUpdate(this); // This signals a possible change
}
}
}
finally {
this._isUpdating = false;
}
}
endUpdate(_observable) {
this._updateCount--;
if (this._updateCount === 0) {
// End update could change the observer list.
const observers = [...this._observers];
for (const r of observers) {
r.endUpdate(this);
}
if (this._removedObserverToCallEndUpdateOn) {
const observers = [...this._removedObserverToCallEndUpdateOn];
this._removedObserverToCallEndUpdateOn = null;
for (const r of observers) {
r.endUpdate(this);
}
}
}
assertFn(() => this._updateCount >= 0);
}
handlePossibleChange(observable) {
// In all other states, observers already know that we might have changed.
if (this._state === 3 /* DerivedState.upToDate */ && this._dependencies.has(observable) && !this._dependenciesToBeRemoved.has(observable)) {
this._state = 1 /* DerivedState.dependenciesMightHaveChanged */;
for (const r of this._observers) {
r.handlePossibleChange(this);
}
}
}
handleChange(observable, change) {
if (this._dependencies.has(observable) && !this._dependenciesToBeRemoved.has(observable) || this._isInBeforeUpdate) {
getLogger()?.handleDerivedDependencyChanged(this, observable, change);
let shouldReact = false;
try {
shouldReact = this._changeTracker ? this._changeTracker.handleChange({
changedObservable: observable,
change,
didChange: (o) => o === observable,
}, this._changeSummary) : true;
}
catch (e) {
onBugIndicatingError(e);
}
const wasUpToDate = this._state === 3 /* DerivedState.upToDate */;
if (shouldReact && (this._state === 1 /* DerivedState.dependenciesMightHaveChanged */ || wasUpToDate)) {
this._state = 2 /* DerivedState.stale */;
if (wasUpToDate) {
for (const r of this._observers) {
r.handlePossibleChange(this);
}
}
}
}
}
// IReader Implementation
_ensureReaderValid() {
if (!this._isReaderValid) {
throw new BugIndicatingError('The reader object cannot be used outside its compute function!');
}
}
readObservable(observable) {
this._ensureReaderValid();
// Subscribe before getting the value to enable caching
observable.addObserver(this);
/** This might call {@link handleChange} indirectly, which could invalidate us */
const value = observable.get();
// Which is why we only add the observable to the dependencies now.
this._dependencies.add(observable);
this._dependenciesToBeRemoved.delete(observable);
return value;
}
get store() {
this._ensureReaderValid();
if (this._store === undefined) {
this._store = new DisposableStore();
}
return this._store;
}
addObserver(observer) {
const shouldCallBeginUpdate = !this._observers.has(observer) && this._updateCount > 0;
super.addObserver(observer);
if (shouldCallBeginUpdate) {
if (this._removedObserverToCallEndUpdateOn && this._removedObserverToCallEndUpdateOn.has(observer)) {
this._removedObserverToCallEndUpdateOn.delete(observer);
}
else {
observer.beginUpdate(this);
}
}
}
removeObserver(observer) {
if (this._observers.has(observer) && this._updateCount > 0) {
if (!this._removedObserverToCallEndUpdateOn) {
this._removedObserverToCallEndUpdateOn = new Set();
}
this._removedObserverToCallEndUpdateOn.add(observer);
}
super.removeObserver(observer);
}
debugGetState() {
return {
state: this._state,
stateStr: derivedStateToString(this._state),
updateCount: this._updateCount,
isComputing: this._isComputing,
dependencies: this._dependencies,
value: this._value,
};
}
debugSetValue(newValue) {
this._value = newValue;
}
debugRecompute() {
if (!this._isComputing) {
this._recompute();
}
else {
this._state = 2 /* DerivedState.stale */;
}
}
setValue(newValue, tx, change) {
this._value = newValue;
const observers = this._observers;
tx.updateObserver(this, this);
for (const d of observers) {
d.handleChange(this, change);
}
}
}
export class DerivedWithSetter extends Derived {
constructor(debugNameData, computeFn, changeTracker, handleLastObserverRemoved = undefined, equalityComparator, set, debugLocation) {
super(debugNameData, computeFn, changeTracker, handleLastObserverRemoved, equalityComparator, debugLocation);
this.set = set;
}
}
//# sourceMappingURL=derivedImpl.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,123 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TransactionImpl } from '../transaction.js';
import { getLogger } from '../logging/logging.js';
import { BaseObservable } from './baseObservable.js';
/**
* Holds off updating observers until the value is actually read.
*/
export class LazyObservableValue extends BaseObservable {
get debugName() {
return this._debugNameData.getDebugName(this) ?? 'LazyObservableValue';
}
constructor(_debugNameData, initialValue, _equalityComparator, debugLocation) {
super(debugLocation);
this._debugNameData = _debugNameData;
this._equalityComparator = _equalityComparator;
this._isUpToDate = true;
this._deltas = [];
this._updateCounter = 0;
this._value = initialValue;
}
get() {
this._update();
return this._value;
}
_update() {
if (this._isUpToDate) {
return;
}
this._isUpToDate = true;
if (this._deltas.length > 0) {
for (const change of this._deltas) {
getLogger()?.handleObservableUpdated(this, { change, didChange: true, oldValue: '(unknown)', newValue: this._value, hadValue: true });
for (const observer of this._observers) {
observer.handleChange(this, change);
}
}
this._deltas.length = 0;
}
else {
getLogger()?.handleObservableUpdated(this, { change: undefined, didChange: true, oldValue: '(unknown)', newValue: this._value, hadValue: true });
for (const observer of this._observers) {
observer.handleChange(this, undefined);
}
}
}
_beginUpdate() {
this._updateCounter++;
if (this._updateCounter === 1) {
for (const observer of this._observers) {
observer.beginUpdate(this);
}
}
}
_endUpdate() {
this._updateCounter--;
if (this._updateCounter === 0) {
this._update();
// End update could change the observer list.
const observers = [...this._observers];
for (const r of observers) {
r.endUpdate(this);
}
}
}
addObserver(observer) {
const shouldCallBeginUpdate = !this._observers.has(observer) && this._updateCounter > 0;
super.addObserver(observer);
if (shouldCallBeginUpdate) {
observer.beginUpdate(this);
}
}
removeObserver(observer) {
const shouldCallEndUpdate = this._observers.has(observer) && this._updateCounter > 0;
super.removeObserver(observer);
if (shouldCallEndUpdate) {
// Calling end update after removing the observer makes sure endUpdate cannot be called twice here.
observer.endUpdate(this);
}
}
set(value, tx, change) {
if (change === undefined && this._equalityComparator(this._value, value)) {
return;
}
let _tx;
if (!tx) {
tx = _tx = new TransactionImpl(() => { }, () => `Setting ${this.debugName}`);
}
try {
this._isUpToDate = false;
this._setValue(value);
if (change !== undefined) {
this._deltas.push(change);
}
tx.updateObserver({
beginUpdate: () => this._beginUpdate(),
endUpdate: () => this._endUpdate(),
handleChange: (observable, change) => { },
handlePossibleChange: (observable) => { },
}, this);
if (this._updateCounter > 1) {
// We already started begin/end update, so we need to manually call handlePossibleChange
for (const observer of this._observers) {
observer.handlePossibleChange(this);
}
}
}
finally {
if (_tx) {
_tx.finish();
}
}
}
toString() {
return `${this.debugName}: ${this._value}`;
}
_setValue(newValue) {
this._value = newValue;
}
}
//# sourceMappingURL=lazyObservableValue.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,118 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { subtransaction } from '../transaction.js';
import { strictEquals } from '../commonFacade/deps.js';
import { DebugNameData } from '../debugName.js';
import { getLogger } from '../logging/logging.js';
import { BaseObservable } from './baseObservable.js';
import { DebugLocation } from '../debugLocation.js';
export function observableFromEvent(...args) {
let owner;
let event;
let getValue;
let debugLocation;
if (args.length === 2) {
[event, getValue] = args;
}
else {
[owner, event, getValue, debugLocation] = args;
}
return new FromEventObservable(new DebugNameData(owner, undefined, getValue), event, getValue, () => FromEventObservable.globalTransaction, strictEquals, debugLocation ?? DebugLocation.ofCaller());
}
export function observableFromEventOpts(options, event, getValue, debugLocation = DebugLocation.ofCaller()) {
return new FromEventObservable(new DebugNameData(options.owner, options.debugName, options.debugReferenceFn ?? getValue), event, getValue, () => FromEventObservable.globalTransaction, options.equalsFn ?? strictEquals, debugLocation);
}
export class FromEventObservable extends BaseObservable {
constructor(_debugNameData, event, _getValue, _getTransaction, _equalityComparator, debugLocation) {
super(debugLocation);
this._debugNameData = _debugNameData;
this.event = event;
this._getValue = _getValue;
this._getTransaction = _getTransaction;
this._equalityComparator = _equalityComparator;
this._hasValue = false;
this.handleEvent = (args) => {
const newValue = this._getValue(args);
const oldValue = this._value;
const didChange = !this._hasValue || !(this._equalityComparator(oldValue, newValue));
let didRunTransaction = false;
if (didChange) {
this._value = newValue;
if (this._hasValue) {
didRunTransaction = true;
subtransaction(this._getTransaction(), (tx) => {
getLogger()?.handleObservableUpdated(this, { oldValue, newValue, change: undefined, didChange, hadValue: this._hasValue });
for (const o of this._observers) {
tx.updateObserver(o, this);
o.handleChange(this, undefined);
}
}, () => {
const name = this.getDebugName();
return 'Event fired' + (name ? `: ${name}` : '');
});
}
this._hasValue = true;
}
if (!didRunTransaction) {
getLogger()?.handleObservableUpdated(this, { oldValue, newValue, change: undefined, didChange, hadValue: this._hasValue });
}
};
}
getDebugName() {
return this._debugNameData.getDebugName(this);
}
get debugName() {
const name = this.getDebugName();
return 'From Event' + (name ? `: ${name}` : '');
}
onFirstObserverAdded() {
this._subscription = this.event(this.handleEvent);
}
onLastObserverRemoved() {
this._subscription.dispose();
this._subscription = undefined;
this._hasValue = false;
this._value = undefined;
}
get() {
if (this._subscription) {
if (!this._hasValue) {
this.handleEvent(undefined);
}
return this._value;
}
else {
// no cache, as there are no subscribers to keep it updated
const value = this._getValue(undefined);
return value;
}
}
debugSetValue(value) {
this._value = value;
}
debugGetState() {
return { value: this._value, hasValue: this._hasValue };
}
}
(function (observableFromEvent) {
observableFromEvent.Observer = FromEventObservable;
function batchEventsGlobally(tx, fn) {
let didSet = false;
if (FromEventObservable.globalTransaction === undefined) {
FromEventObservable.globalTransaction = tx;
didSet = true;
}
try {
fn();
}
finally {
if (didSet) {
FromEventObservable.globalTransaction = undefined;
}
}
}
observableFromEvent.batchEventsGlobally = batchEventsGlobally;
})(observableFromEvent || (observableFromEvent = {}));
//# sourceMappingURL=observableFromEvent.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,45 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { transaction } from '../transaction.js';
import { DebugNameData } from '../debugName.js';
import { BaseObservable } from './baseObservable.js';
import { DebugLocation } from '../debugLocation.js';
export function observableSignal(debugNameOrOwner, debugLocation = DebugLocation.ofCaller()) {
if (typeof debugNameOrOwner === 'string') {
return new ObservableSignal(debugNameOrOwner, undefined, debugLocation);
}
else {
return new ObservableSignal(undefined, debugNameOrOwner, debugLocation);
}
}
class ObservableSignal extends BaseObservable {
get debugName() {
return new DebugNameData(this._owner, this._debugName, undefined).getDebugName(this) ?? 'Observable Signal';
}
toString() {
return this.debugName;
}
constructor(_debugName, _owner, debugLocation) {
super(debugLocation);
this._debugName = _debugName;
this._owner = _owner;
}
trigger(tx, change) {
if (!tx) {
transaction(tx => {
this.trigger(tx, change);
}, () => `Trigger signal ${this.debugName}`);
return;
}
for (const o of this._observers) {
tx.updateObserver(o, this);
o.handleChange(this, change);
}
}
get() {
// NO OP
}
}
//# sourceMappingURL=observableSignal.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,39 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { transaction } from '../transaction.js';
import { DebugNameData } from '../debugName.js';
import { BaseObservable } from './baseObservable.js';
import { DebugLocation } from '../debugLocation.js';
export function observableSignalFromEvent(owner, event, debugLocation = DebugLocation.ofCaller()) {
return new FromEventObservableSignal(typeof owner === 'string' ? owner : new DebugNameData(owner, undefined, undefined), event, debugLocation);
}
class FromEventObservableSignal extends BaseObservable {
constructor(debugNameDataOrName, event, debugLocation) {
super(debugLocation);
this.event = event;
this.handleEvent = () => {
transaction((tx) => {
for (const o of this._observers) {
tx.updateObserver(o, this);
o.handleChange(this, undefined);
}
}, () => this.debugName);
};
this.debugName = typeof debugNameDataOrName === 'string'
? debugNameDataOrName
: debugNameDataOrName.getDebugName(this) ?? 'Observable Signal From Event';
}
onFirstObserverAdded() {
this.subscription = this.event(this.handleEvent);
}
onLastObserverRemoved() {
this.subscription.dispose();
this.subscription = undefined;
}
get() {
// NO OP
}
}
//# sourceMappingURL=observableSignalFromEvent.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,101 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { TransactionImpl } from '../transaction.js';
import { BaseObservable } from './baseObservable.js';
import { strictEquals } from '../commonFacade/deps.js';
import { DebugNameData } from '../debugName.js';
import { getLogger } from '../logging/logging.js';
import { DebugLocation } from '../debugLocation.js';
export function observableValue(nameOrOwner, initialValue, debugLocation = DebugLocation.ofCaller()) {
let debugNameData;
if (typeof nameOrOwner === 'string') {
debugNameData = new DebugNameData(undefined, nameOrOwner, undefined);
}
else {
debugNameData = new DebugNameData(nameOrOwner, undefined, undefined);
}
return new ObservableValue(debugNameData, initialValue, strictEquals, debugLocation);
}
export class ObservableValue extends BaseObservable {
get debugName() {
return this._debugNameData.getDebugName(this) ?? 'ObservableValue';
}
constructor(_debugNameData, initialValue, _equalityComparator, debugLocation) {
super(debugLocation);
this._debugNameData = _debugNameData;
this._equalityComparator = _equalityComparator;
this._value = initialValue;
getLogger()?.handleObservableUpdated(this, { hadValue: false, newValue: initialValue, change: undefined, didChange: true, oldValue: undefined });
}
get() {
return this._value;
}
set(value, tx, change) {
if (change === undefined && this._equalityComparator(this._value, value)) {
return;
}
let _tx;
if (!tx) {
tx = _tx = new TransactionImpl(() => { }, () => `Setting ${this.debugName}`);
}
try {
const oldValue = this._value;
this._setValue(value);
getLogger()?.handleObservableUpdated(this, { oldValue, newValue: value, change, didChange: true, hadValue: true });
for (const observer of this._observers) {
tx.updateObserver(observer, this);
observer.handleChange(this, change);
}
}
finally {
if (_tx) {
_tx.finish();
}
}
}
toString() {
return `${this.debugName}: ${this._value}`;
}
_setValue(newValue) {
this._value = newValue;
}
debugGetState() {
return {
value: this._value,
};
}
debugSetValue(value) {
this._value = value;
}
}
/**
* A disposable observable. When disposed, its value is also disposed.
* When a new value is set, the previous value is disposed.
*/
export function disposableObservableValue(nameOrOwner, initialValue, debugLocation = DebugLocation.ofCaller()) {
let debugNameData;
if (typeof nameOrOwner === 'string') {
debugNameData = new DebugNameData(undefined, nameOrOwner, undefined);
}
else {
debugNameData = new DebugNameData(nameOrOwner, undefined, undefined);
}
return new DisposableObservableValue(debugNameData, initialValue, strictEquals, debugLocation);
}
export class DisposableObservableValue extends ObservableValue {
_setValue(newValue) {
if (this._value === newValue) {
return;
}
if (this._value) {
this._value.dispose();
}
this._value = newValue;
}
dispose() {
this._value?.dispose();
}
}
//# sourceMappingURL=observableValue.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DebugNameData } from '../debugName.js';
import { strictEquals } from '../commonFacade/deps.js';
import { ObservableValue } from './observableValue.js';
import { LazyObservableValue } from './lazyObservableValue.js';
import { DebugLocation } from '../debugLocation.js';
export function observableValueOpts(options, initialValue, debugLocation = DebugLocation.ofCaller()) {
if (options.lazy) {
return new LazyObservableValue(new DebugNameData(options.owner, options.debugName, undefined), initialValue, options.equalsFn ?? strictEquals, debugLocation);
}
return new ObservableValue(new DebugNameData(options.owner, options.debugName, undefined), initialValue, options.equalsFn ?? strictEquals, debugLocation);
}
//# sourceMappingURL=observableValueOpts.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/observables/observableValueOpts.ts","vs/base/common/observableInternal/observables/observableValueOpts.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,aAAa,EAAkB,MAAM,iBAAiB,CAAC;AAChE,OAAO,EAAoB,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACzE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,UAAU,mBAAmB,CAClC,OAGC,EACD,YAAe,EACf,aAAa,GAAG,aAAa,CAAC,QAAQ,EAAE;IAExC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAClB,OAAO,IAAI,mBAAmB,CAC7B,IAAI,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAC9D,YAAY,EACZ,OAAO,CAAC,QAAQ,IAAI,YAAY,EAChC,aAAa,CACb,CAAC;IACH,CAAC;IACD,OAAO,IAAI,eAAe,CACzB,IAAI,aAAa,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAC9D,YAAY,EACZ,OAAO,CAAC,QAAQ,IAAI,YAAY,EAChC,aAAa,CACb,CAAC;AACH,CAAC","file":"observableValueOpts.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ISettableObservable } from '../base.js';\nimport { DebugNameData, IDebugNameData } from '../debugName.js';\nimport { EqualityComparer, strictEquals } from '../commonFacade/deps.js';\nimport { ObservableValue } from './observableValue.js';\nimport { LazyObservableValue } from './lazyObservableValue.js';\nimport { DebugLocation } from '../debugLocation.js';\n\nexport function observableValueOpts<T, TChange = void>(\n\toptions: IDebugNameData & {\n\t\tequalsFn?: EqualityComparer<T>;\n\t\tlazy?: boolean;\n\t},\n\tinitialValue: T,\n\tdebugLocation = DebugLocation.ofCaller(),\n): ISettableObservable<T, TChange> {\n\tif (options.lazy) {\n\t\treturn new LazyObservableValue(\n\t\t\tnew DebugNameData(options.owner, options.debugName, undefined),\n\t\t\tinitialValue,\n\t\t\toptions.equalsFn ?? strictEquals,\n\t\t\tdebugLocation\n\t\t);\n\t}\n\treturn new ObservableValue(\n\t\tnew DebugNameData(options.owner, options.debugName, undefined),\n\t\tinitialValue,\n\t\toptions.equalsFn ?? strictEquals,\n\t\tdebugLocation\n\t);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { ISettableObservable } from '../base.js';\nimport { DebugNameData, IDebugNameData } from '../debugName.js';\nimport { EqualityComparer, strictEquals } from '../commonFacade/deps.js';\nimport { ObservableValue } from './observableValue.js';\nimport { LazyObservableValue } from './lazyObservableValue.js';\nimport { DebugLocation } from '../debugLocation.js';\n\nexport function observableValueOpts<T, TChange = void>(\n\toptions: IDebugNameData & {\n\t\tequalsFn?: EqualityComparer<T>;\n\t\tlazy?: boolean;\n\t},\n\tinitialValue: T,\n\tdebugLocation = DebugLocation.ofCaller(),\n): ISettableObservable<T, TChange> {\n\tif (options.lazy) {\n\t\treturn new LazyObservableValue(\n\t\t\tnew DebugNameData(options.owner, options.debugName, undefined),\n\t\t\tinitialValue,\n\t\t\toptions.equalsFn ?? strictEquals,\n\t\t\tdebugLocation\n\t\t);\n\t}\n\treturn new ObservableValue(\n\t\tnew DebugNameData(options.owner, options.debugName, undefined),\n\t\tinitialValue,\n\t\toptions.equalsFn ?? strictEquals,\n\t\tdebugLocation\n\t);\n}\n"]}

View File

@@ -0,0 +1,85 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { DisposableStore, toDisposable } from '../commonFacade/deps.js';
import { DebugNameData } from '../debugName.js';
import { AutorunObserver } from './autorunImpl.js';
import { DebugLocation } from '../debugLocation.js';
/**
* Runs immediately and whenever a transaction ends and an observed observable changed.
* {@link fn} should start with a JS Doc using `@description` to name the autorun.
*/
export function autorun(fn, debugLocation = DebugLocation.ofCaller()) {
return new AutorunObserver(new DebugNameData(undefined, undefined, fn), fn, undefined, debugLocation);
}
/**
* Runs immediately and whenever a transaction ends and an observed observable changed.
* {@link fn} should start with a JS Doc using `@description` to name the autorun.
*/
export function autorunOpts(options, fn, debugLocation = DebugLocation.ofCaller()) {
return new AutorunObserver(new DebugNameData(options.owner, options.debugName, options.debugReferenceFn ?? fn), fn, undefined, debugLocation);
}
/**
* Runs immediately and whenever a transaction ends and an observed observable changed.
* {@link fn} should start with a JS Doc using `@description` to name the autorun.
*
* Use `changeTracker.createChangeSummary` to create a "change summary" that can collect the changes.
* Use `changeTracker.handleChange` to add a reported change to the change summary.
* The run function is given the last change summary.
* The change summary is discarded after the run function was called.
*
* @see autorun
*/
export function autorunHandleChanges(options, fn, debugLocation = DebugLocation.ofCaller()) {
return new AutorunObserver(new DebugNameData(options.owner, options.debugName, options.debugReferenceFn ?? fn), fn, options.changeTracker, debugLocation);
}
/**
* @see autorunHandleChanges (but with a disposable store that is cleared before the next run or on dispose)
*/
export function autorunWithStoreHandleChanges(options, fn) {
const store = new DisposableStore();
const disposable = autorunHandleChanges({
owner: options.owner,
debugName: options.debugName,
debugReferenceFn: options.debugReferenceFn ?? fn,
changeTracker: options.changeTracker,
}, (reader, changeSummary) => {
store.clear();
fn(reader, changeSummary, store);
});
return toDisposable(() => {
disposable.dispose();
store.dispose();
});
}
/**
* @see autorun (but with a disposable store that is cleared before the next run or on dispose)
*
* @deprecated Use `autorun(reader => { reader.store.add(...) })` instead!
*/
export function autorunWithStore(fn) {
const store = new DisposableStore();
const disposable = autorunOpts({
owner: undefined,
debugName: undefined,
debugReferenceFn: fn,
}, reader => {
store.clear();
fn(reader, store);
});
return toDisposable(() => {
disposable.dispose();
store.dispose();
});
}
export function autorunDelta(observable, handler) {
let _lastValue;
return autorunOpts({ debugReferenceFn: handler }, (reader) => {
const newValue = observable.read(reader);
const lastValue = _lastValue;
_lastValue = newValue;
handler({ lastValue, newValue });
});
}
//# sourceMappingURL=autorun.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,210 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { assertFn, BugIndicatingError, DisposableStore, markAsDisposed, onBugIndicatingError, trackDisposable } from '../commonFacade/deps.js';
import { getLogger } from '../logging/logging.js';
function autorunStateToString(state) {
switch (state) {
case 1 /* AutorunState.dependenciesMightHaveChanged */: return 'dependenciesMightHaveChanged';
case 2 /* AutorunState.stale */: return 'stale';
case 3 /* AutorunState.upToDate */: return 'upToDate';
default: return '<unknown>';
}
}
export class AutorunObserver {
get debugName() {
return this._debugNameData.getDebugName(this) ?? '(anonymous)';
}
constructor(_debugNameData, _runFn, _changeTracker, debugLocation) {
this._debugNameData = _debugNameData;
this._runFn = _runFn;
this._changeTracker = _changeTracker;
this._state = 2 /* AutorunState.stale */;
this._updateCount = 0;
this._disposed = false;
this._dependencies = new Set();
this._dependenciesToBeRemoved = new Set();
this._isRunning = false;
this._store = undefined;
this._delayedStore = undefined;
this._changeSummary = this._changeTracker?.createChangeSummary(undefined);
getLogger()?.handleAutorunCreated(this, debugLocation);
this._run();
trackDisposable(this);
}
dispose() {
if (this._disposed) {
return;
}
this._disposed = true;
for (const o of this._dependencies) {
o.removeObserver(this); // Warning: external call!
}
this._dependencies.clear();
if (this._store !== undefined) {
this._store.dispose();
}
if (this._delayedStore !== undefined) {
this._delayedStore.dispose();
}
getLogger()?.handleAutorunDisposed(this);
markAsDisposed(this);
}
_run() {
const emptySet = this._dependenciesToBeRemoved;
this._dependenciesToBeRemoved = this._dependencies;
this._dependencies = emptySet;
this._state = 3 /* AutorunState.upToDate */;
try {
if (!this._disposed) {
getLogger()?.handleAutorunStarted(this);
const changeSummary = this._changeSummary;
const delayedStore = this._delayedStore;
if (delayedStore !== undefined) {
this._delayedStore = undefined;
}
try {
this._isRunning = true;
if (this._changeTracker) {
this._changeTracker.beforeUpdate?.(this, changeSummary);
this._changeSummary = this._changeTracker.createChangeSummary(changeSummary); // Warning: external call!
}
if (this._store !== undefined) {
this._store.dispose();
this._store = undefined;
}
this._runFn(this, changeSummary); // Warning: external call!
}
catch (e) {
onBugIndicatingError(e);
}
finally {
this._isRunning = false;
if (delayedStore !== undefined) {
delayedStore.dispose();
}
}
}
}
finally {
if (!this._disposed) {
getLogger()?.handleAutorunFinished(this);
}
// We don't want our observed observables to think that they are (not even temporarily) not being observed.
// Thus, we only unsubscribe from observables that are definitely not read anymore.
for (const o of this._dependenciesToBeRemoved) {
o.removeObserver(this); // Warning: external call!
}
this._dependenciesToBeRemoved.clear();
}
}
toString() {
return `Autorun<${this.debugName}>`;
}
// IObserver implementation
beginUpdate(_observable) {
if (this._state === 3 /* AutorunState.upToDate */) {
this._state = 1 /* AutorunState.dependenciesMightHaveChanged */;
}
this._updateCount++;
}
endUpdate(_observable) {
try {
if (this._updateCount === 1) {
do {
if (this._state === 1 /* AutorunState.dependenciesMightHaveChanged */) {
this._state = 3 /* AutorunState.upToDate */;
for (const d of this._dependencies) {
d.reportChanges(); // Warning: external call!
if (this._state === 2 /* AutorunState.stale */) {
// The other dependencies will refresh on demand
break;
}
}
}
if (this._state !== 3 /* AutorunState.upToDate */) {
this._run(); // Warning: indirect external call!
}
} while (this._state !== 3 /* AutorunState.upToDate */);
}
}
finally {
this._updateCount--;
}
assertFn(() => this._updateCount >= 0);
}
handlePossibleChange(observable) {
if (this._state === 3 /* AutorunState.upToDate */ && this._isDependency(observable)) {
this._state = 1 /* AutorunState.dependenciesMightHaveChanged */;
}
}
handleChange(observable, change) {
if (this._isDependency(observable)) {
getLogger()?.handleAutorunDependencyChanged(this, observable, change);
try {
// Warning: external call!
const shouldReact = this._changeTracker ? this._changeTracker.handleChange({
changedObservable: observable,
change,
didChange: (o) => o === observable,
}, this._changeSummary) : true;
if (shouldReact) {
this._state = 2 /* AutorunState.stale */;
}
}
catch (e) {
onBugIndicatingError(e);
}
}
}
_isDependency(observable) {
return this._dependencies.has(observable) && !this._dependenciesToBeRemoved.has(observable);
}
// IReader implementation
_ensureNoRunning() {
if (!this._isRunning) {
throw new BugIndicatingError('The reader object cannot be used outside its compute function!');
}
}
readObservable(observable) {
this._ensureNoRunning();
// In case the run action disposes the autorun
if (this._disposed) {
return observable.get(); // warning: external call!
}
observable.addObserver(this); // warning: external call!
const value = observable.get(); // warning: external call!
this._dependencies.add(observable);
this._dependenciesToBeRemoved.delete(observable);
return value;
}
get store() {
this._ensureNoRunning();
if (this._disposed) {
throw new BugIndicatingError('Cannot access store after dispose');
}
if (this._store === undefined) {
this._store = new DisposableStore();
}
return this._store;
}
debugGetState() {
return {
isRunning: this._isRunning,
updateCount: this._updateCount,
dependencies: this._dependencies,
state: this._state,
stateStr: autorunStateToString(this._state),
};
}
debugRerun() {
if (!this._isRunning) {
this._run();
}
else {
this._state = 2 /* AutorunState.stale */;
}
}
}
//# sourceMappingURL=autorunImpl.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,107 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { handleBugIndicatingErrorRecovery } from './base.js';
import { getFunctionName } from './debugName.js';
import { getLogger } from './logging/logging.js';
/**
* Starts a transaction in which many observables can be changed at once.
* {@link fn} should start with a JS Doc using `@description` to give the transaction a debug name.
* Reaction run on demand or when the transaction ends.
*/
export function transaction(fn, getDebugName) {
const tx = new TransactionImpl(fn, getDebugName);
try {
fn(tx);
}
finally {
tx.finish();
}
}
let _globalTransaction = undefined;
export function globalTransaction(fn) {
if (_globalTransaction) {
fn(_globalTransaction);
}
else {
const tx = new TransactionImpl(fn, undefined);
_globalTransaction = tx;
try {
fn(tx);
}
finally {
tx.finish(); // During finish, more actions might be added to the transaction.
// Which is why we only clear the global transaction after finish.
_globalTransaction = undefined;
}
}
}
/** @deprecated */
export async function asyncTransaction(fn, getDebugName) {
const tx = new TransactionImpl(fn, getDebugName);
try {
await fn(tx);
}
finally {
tx.finish();
}
}
/**
* Allows to chain transactions.
*/
export function subtransaction(tx, fn, getDebugName) {
if (!tx) {
transaction(fn, getDebugName);
}
else {
fn(tx);
}
}
export class TransactionImpl {
constructor(_fn, _getDebugName) {
this._fn = _fn;
this._getDebugName = _getDebugName;
this._updatingObservers = [];
getLogger()?.handleBeginTransaction(this);
}
getDebugName() {
if (this._getDebugName) {
return this._getDebugName();
}
return getFunctionName(this._fn);
}
updateObserver(observer, observable) {
if (!this._updatingObservers) {
// This happens when a transaction is used in a callback or async function.
// If an async transaction is used, make sure the promise awaits all users of the transaction (e.g. no race).
handleBugIndicatingErrorRecovery('Transaction already finished!');
// Error recovery
transaction(tx => {
tx.updateObserver(observer, observable);
});
return;
}
// When this gets called while finish is active, they will still get considered
this._updatingObservers.push({ observer, observable });
observer.beginUpdate(observable);
}
finish() {
const updatingObservers = this._updatingObservers;
if (!updatingObservers) {
handleBugIndicatingErrorRecovery('transaction.finish() has already been called!');
return;
}
for (let i = 0; i < updatingObservers.length; i++) {
const { observer, observable } = updatingObservers[i];
observer.endUpdate(observable);
}
// Prevent anyone from updating observers from now on.
this._updatingObservers = null;
getLogger()?.handleEndTransaction(this);
}
debugGetUpdatingObservers() {
return this._updatingObservers;
}
}
//# sourceMappingURL=transaction.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,54 @@
import { transaction } from '../transaction.js';
import { observableValue } from '../observables/observableValue.js';
/**
* A promise whose state is observable.
*/
export class ObservablePromise {
constructor(promise) {
this._value = observableValue(this, undefined);
/**
* The current state of the promise.
* Is `undefined` if the promise didn't resolve yet.
*/
this.promiseResult = this._value;
this.promise = promise.then(value => {
transaction(tx => {
/** @description onPromiseResolved */
this._value.set(new PromiseResult(value, undefined), tx);
});
return value;
}, error => {
transaction(tx => {
/** @description onPromiseRejected */
this._value.set(new PromiseResult(undefined, error), tx);
});
throw error;
});
}
}
export class PromiseResult {
constructor(
/**
* The value of the resolved promise.
* Undefined if the promise rejected.
*/
data,
/**
* The error in case of a rejected promise.
* Undefined if the promise resolved.
*/
error) {
this.data = data;
this.error = error;
}
/**
* Returns the value if the promise resolved, otherwise throws the error.
*/
getDataOrThrow() {
if (this.error) {
throw this.error;
}
return this.data;
}
}
//# sourceMappingURL=promise.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { cancelOnDispose } from '../commonFacade/cancellation.js';
import { DisposableStore } from '../commonFacade/deps.js';
import { autorunWithStoreHandleChanges } from '../reactions/autorun.js';
export function runOnChange(observable, cb) {
let _previousValue;
let _firstRun = true;
return autorunWithStoreHandleChanges({
changeTracker: {
createChangeSummary: () => ({ deltas: [], didChange: false }),
handleChange: (context, changeSummary) => {
if (context.didChange(observable)) {
const e = context.change;
if (e !== undefined) {
changeSummary.deltas.push(e);
}
changeSummary.didChange = true;
}
return true;
},
}
}, (reader, changeSummary) => {
const value = observable.read(reader);
const previousValue = _previousValue;
if (changeSummary.didChange) {
_previousValue = value;
// didChange can never be true on the first autorun, so we know previousValue is defined
cb(value, previousValue, changeSummary.deltas);
}
if (_firstRun) {
_firstRun = false;
_previousValue = value;
}
});
}
export function runOnChangeWithStore(observable, cb) {
const store = new DisposableStore();
const disposable = runOnChange(observable, (value, previousValue, deltas) => {
store.clear();
cb(value, previousValue, deltas, store);
});
return {
dispose() {
disposable.dispose();
store.dispose();
}
};
}
export function runOnChangeWithCancellationToken(observable, cb) {
return runOnChangeWithStore(observable, (value, previousValue, deltas, store) => {
cb(value, previousValue, deltas, cancelOnDispose(store));
});
}
//# sourceMappingURL=runOnChange.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,190 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { autorun } from '../reactions/autorun.js';
import { DisposableStore, toDisposable } from '../commonFacade/deps.js';
import { derived, derivedOpts } from '../observables/derived.js';
import { observableFromEvent } from '../observables/observableFromEvent.js';
import { observableSignal } from '../observables/observableSignal.js';
import { _setKeepObserved, _setRecomputeInitiallyAndOnChange } from '../observables/baseObservable.js';
/**
* Creates an observable that debounces the input observable.
*/
export function debouncedObservable(observable, debounceMs) {
let hasValue = false;
let lastValue;
let timeout = undefined;
return observableFromEvent(cb => {
const d = autorun(reader => {
const value = observable.read(reader);
if (!hasValue) {
hasValue = true;
lastValue = value;
}
else {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
lastValue = value;
cb();
}, debounceMs);
}
});
return {
dispose() {
d.dispose();
hasValue = false;
lastValue = undefined;
},
};
}, () => {
if (hasValue) {
return lastValue;
}
else {
return observable.get();
}
});
}
/**
* This makes sure the observable is being observed and keeps its cache alive.
*/
export function keepObserved(observable) {
const o = new KeepAliveObserver(false, undefined);
observable.addObserver(o);
return toDisposable(() => {
observable.removeObserver(o);
});
}
_setKeepObserved(keepObserved);
/**
* This converts the given observable into an autorun.
*/
export function recomputeInitiallyAndOnChange(observable, handleValue) {
const o = new KeepAliveObserver(true, handleValue);
observable.addObserver(o);
try {
o.beginUpdate(observable);
}
finally {
o.endUpdate(observable);
}
return toDisposable(() => {
observable.removeObserver(o);
});
}
_setRecomputeInitiallyAndOnChange(recomputeInitiallyAndOnChange);
export class KeepAliveObserver {
constructor(_forceRecompute, _handleValue) {
this._forceRecompute = _forceRecompute;
this._handleValue = _handleValue;
this._counter = 0;
}
beginUpdate(observable) {
this._counter++;
}
endUpdate(observable) {
if (this._counter === 1 && this._forceRecompute) {
if (this._handleValue) {
this._handleValue(observable.get());
}
else {
observable.reportChanges();
}
}
this._counter--;
}
handlePossibleChange(observable) {
// NO OP
}
handleChange(observable, change) {
// NO OP
}
}
export function derivedObservableWithCache(owner, computeFn) {
let lastValue = undefined;
const observable = derivedOpts({ owner, debugReferenceFn: computeFn }, reader => {
lastValue = computeFn(reader, lastValue);
return lastValue;
});
return observable;
}
export function derivedObservableWithWritableCache(owner, computeFn) {
let lastValue = undefined;
const onChange = observableSignal('derivedObservableWithWritableCache');
const observable = derived(owner, reader => {
onChange.read(reader);
lastValue = computeFn(reader, lastValue);
return lastValue;
});
return Object.assign(observable, {
clearCache: (tx) => {
lastValue = undefined;
onChange.trigger(tx);
},
setCache: (newValue, tx) => {
lastValue = newValue;
onChange.trigger(tx);
}
});
}
/**
* When the items array changes, referential equal items are not mapped again.
*/
export function mapObservableArrayCached(owner, items, map, keySelector) {
let m = new ArrayMap(map, keySelector);
const self = derivedOpts({
debugReferenceFn: map,
owner,
onLastObserverRemoved: () => {
m.dispose();
m = new ArrayMap(map);
}
}, (reader) => {
m.setItems(items.read(reader));
return m.getItems();
});
return self;
}
class ArrayMap {
constructor(_map, _keySelector) {
this._map = _map;
this._keySelector = _keySelector;
this._cache = new Map();
this._items = [];
}
dispose() {
this._cache.forEach(entry => entry.store.dispose());
this._cache.clear();
}
setItems(items) {
const newItems = [];
const itemsToRemove = new Set(this._cache.keys());
for (const item of items) {
const key = this._keySelector ? this._keySelector(item) : item;
let entry = this._cache.get(key);
if (!entry) {
const store = new DisposableStore();
const out = this._map(item, store);
entry = { out, store };
this._cache.set(key, entry);
}
else {
itemsToRemove.delete(key);
}
newItems.push(entry.out);
}
for (const item of itemsToRemove) {
const entry = this._cache.get(item);
entry.store.dispose();
this._cache.delete(item);
}
this._items = newItems;
}
getItems() {
return this._items;
}
}
//# sourceMappingURL=utils.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationError } from '../commonFacade/cancellation.js';
import { autorun } from '../reactions/autorun.js';
export function waitForState(observable, predicate, isError, cancellationToken) {
if (!predicate) {
predicate = state => state !== null && state !== undefined;
}
return new Promise((resolve, reject) => {
let isImmediateRun = true;
let shouldDispose = false;
const stateObs = observable.map(state => {
/** @description waitForState.state */
return {
isFinished: predicate(state),
error: isError ? isError(state) : false,
state
};
});
const d = autorun(reader => {
/** @description waitForState */
const { isFinished, error, state } = stateObs.read(reader);
if (isFinished || error) {
if (isImmediateRun) {
// The variable `d` is not initialized yet
shouldDispose = true;
}
else {
d.dispose();
}
if (error) {
reject(error === true ? state : error);
}
else {
resolve(state);
}
}
});
if (cancellationToken) {
const dc = cancellationToken.onCancellationRequested(() => {
d.dispose();
dc.dispose();
reject(new CancellationError());
});
if (cancellationToken.isCancellationRequested) {
d.dispose();
dc.dispose();
reject(new CancellationError());
return;
}
}
isImmediateRun = false;
if (shouldDispose) {
d.dispose();
}
});
}
//# sourceMappingURL=utilsCancellation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,24 @@
/*---------------------------------------------------------------------------------------------
* 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 '../commonFacade/deps.js';
import { observableFromEvent } from '../observables/observableFromEvent.js';
export class ValueWithChangeEventFromObservable {
constructor(observable) {
this.observable = observable;
}
get onDidChange() {
return Event.fromObservableLight(this.observable);
}
get value() {
return this.observable.get();
}
}
export function observableFromValueWithChangeEvent(owner, value) {
if (value instanceof ValueWithChangeEventFromObservable) {
return value.observable;
}
return observableFromEvent(owner, value.onDidChange, () => value.value);
}
//# sourceMappingURL=valueWithChangeEvent.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src/vs/base/common/observableInternal/utils/valueWithChangeEvent.ts","vs/base/common/observableInternal/utils/valueWithChangeEvent.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,EAAE,KAAK,EAAyB,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AAE5E,MAAM,OAAO,kCAAkC;IAC9C,YAA4B,UAA0B;QAA1B,eAAU,GAAV,UAAU,CAAgB;IACtD,CAAC;IAED,IAAI,WAAW;QACd,OAAO,KAAK,CAAC,mBAAmB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,KAAK;QACR,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;IAC9B,CAAC;CACD;AAED,MAAM,UAAU,kCAAkC,CAAI,KAAiB,EAAE,KAA+B;IACvG,IAAI,KAAK,YAAY,kCAAkC,EAAE,CAAC;QACzD,OAAO,KAAK,CAAC,UAAU,CAAC;IACzB,CAAC;IACD,OAAO,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;AACzE,CAAC","file":"valueWithChangeEvent.js","sourceRoot":"file:///mnt/vss/_work/1/s/dependencies/vscode/out-editor-src","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable } from '../base.js';\nimport { Event, IValueWithChangeEvent } from '../commonFacade/deps.js';\nimport { DebugOwner } from '../debugName.js';\nimport { observableFromEvent } from '../observables/observableFromEvent.js';\n\nexport class ValueWithChangeEventFromObservable<T> implements IValueWithChangeEvent<T> {\n\tconstructor(public readonly observable: IObservable<T>) {\n\t}\n\n\tget onDidChange(): Event<void> {\n\t\treturn Event.fromObservableLight(this.observable);\n\t}\n\n\tget value(): T {\n\t\treturn this.observable.get();\n\t}\n}\n\nexport function observableFromValueWithChangeEvent<T>(owner: DebugOwner, value: IValueWithChangeEvent<T>): IObservable<T> {\n\tif (value instanceof ValueWithChangeEventFromObservable) {\n\t\treturn value.observable;\n\t}\n\treturn observableFromEvent(owner, value.onDidChange, () => value.value);\n}\n","/*---------------------------------------------------------------------------------------------\n * Copyright (c) Microsoft Corporation. All rights reserved.\n * Licensed under the MIT License. See License.txt in the project root for license information.\n *--------------------------------------------------------------------------------------------*/\n\nimport { IObservable } from '../base.js';\nimport { Event, IValueWithChangeEvent } from '../commonFacade/deps.js';\nimport { DebugOwner } from '../debugName.js';\nimport { observableFromEvent } from '../observables/observableFromEvent.js';\n\nexport class ValueWithChangeEventFromObservable<T> implements IValueWithChangeEvent<T> {\n\tconstructor(public readonly observable: IObservable<T>) {\n\t}\n\n\tget onDidChange(): Event<void> {\n\t\treturn Event.fromObservableLight(this.observable);\n\t}\n\n\tget value(): T {\n\t\treturn this.observable.get();\n\t}\n}\n\nexport function observableFromValueWithChangeEvent<T>(owner: DebugOwner, value: IValueWithChangeEvent<T>): IObservable<T> {\n\tif (value instanceof ValueWithChangeEventFromObservable) {\n\t\treturn value.observable;\n\t}\n\treturn observableFromEvent(owner, value.onDidChange, () => value.value);\n}\n"]}