UNPKG

monaco-editor

Version:
124 lines (121 loc) 5.03 kB
import { subtransaction } from '../transaction.js'; import { strictEquals } from '../../equals.js'; import '../../event.js'; import '../../lifecycle.js'; import { DebugNameData } from '../debugName.js'; import { getLogger } from '../logging/logging.js'; import { BaseObservable } from './baseObservable.js'; import { DebugLocation } from '../debugLocation.js'; /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ 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()); } 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); } 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) { // eslint-disable-next-line local/code-no-any-casts 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 = {})); export { FromEventObservable, observableFromEvent, observableFromEventOpts };