UNPKG

@difizen/mana-core

Version:

350 lines (346 loc) 16.1 kB
var _dec, _class2, _VSDisposable; function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); } function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _wrapNativeSuper(Class) { var _cache = typeof Map === "function" ? new Map() : undefined; _wrapNativeSuper = function _wrapNativeSuper(Class) { if (Class === null || !_isNativeFunction(Class)) return Class; if (typeof Class !== "function") { throw new TypeError("Super expression must either be null or a function"); } if (typeof _cache !== "undefined") { if (_cache.has(Class)) return _cache.get(Class); _cache.set(Class, Wrapper); } function Wrapper() { return _construct(Class, arguments, _getPrototypeOf(this).constructor); } Wrapper.prototype = Object.create(Class.prototype, { constructor: { value: Wrapper, enumerable: false, writable: true, configurable: true } }); return _setPrototypeOf(Wrapper, Class); }; return _wrapNativeSuper(Class); } function _construct(Parent, args, Class) { if (_isNativeReflectConstruct()) { _construct = Reflect.construct.bind(); } else { _construct = function _construct(Parent, args, Class) { var a = [null]; a.push.apply(a, args); var Constructor = Function.bind.apply(Parent, a); var instance = new Constructor(); if (Class) _setPrototypeOf(instance, Class.prototype); return instance; }; } return _construct.apply(null, arguments); } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _isNativeFunction(fn) { try { return Function.toString.call(fn).indexOf("[native code]") !== -1; } catch (e) { return typeof fn === "function"; } } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); } function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import { Iterable } from '@difizen/mana-common'; import { injectable } from '@difizen/mana-syringe'; export function once(fn) { // eslint-disable-next-line @typescript-eslint/no-this-alias var _this = this; var didCall = false; var result; return function () { if (didCall) { return result; } didCall = true; // eslint-disable-next-line prefer-rest-params result = fn.apply(_this, Array.prototype.slice.call(arguments)); return result; }; } /** * Enables logging of potentially leaked disposables. * * A disposable is considered leaked if it is not disposed or not registered as the child of * another disposable. This tracking is very simple an only works for classes that either * extend VSDisposable or use a DisposableStore. This means there are a lot of false positives. */ var TRACK_DISPOSABLES = false; var disposableTracker = null; export function setDisposableTracker(tracker) { disposableTracker = tracker; } if (TRACK_DISPOSABLES) { var __is_disposable_tracked__ = '__is_disposable_tracked__'; disposableTracker = new ( /*#__PURE__*/function () { function _class() { _classCallCheck(this, _class); } _createClass(_class, [{ key: "trackDisposable", value: function trackDisposable(x) { var stack = new Error('Potentially leaked disposable').stack; setTimeout(function () { if (!x[__is_disposable_tracked__]) { console.warn(stack); } }, 3000); } }, { key: "markTracked", value: function markTracked(x) { // eslint-disable-next-line @typescript-eslint/no-use-before-define if (x && x !== VSDisposable.None) { try { x[__is_disposable_tracked__] = true; } catch (_unused) { // noop } } } }]); return _class; }())(); } function markTracked(x) { if (!disposableTracker) { return; } disposableTracker.markTracked(x); } export function trackDisposable(x) { if (!disposableTracker) { return x; } disposableTracker.trackDisposable(x); return x; } export var MultiDisposeError = /*#__PURE__*/function (_Error) { _inherits(MultiDisposeError, _Error); var _super = _createSuper(MultiDisposeError); function MultiDisposeError(errors) { var _this2; _classCallCheck(this, MultiDisposeError); _this2 = _super.call(this, "Encountered errors while disposing of store. Errors: [".concat(errors.join(', '), "]")); _this2.errors = errors; return _this2; } return _createClass(MultiDisposeError); }( /*#__PURE__*/_wrapNativeSuper(Error)); export function isDisposable(thing) { return typeof thing.dispose === 'function' && thing.dispose.length === 0; } export function dispose(arg) { if (Iterable.is(arg)) { var errors = []; var _iterator = _createForOfIteratorHelper(arg), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var d = _step.value; if (d) { markTracked(d); try { d.dispose(); } catch (e) { errors.push(e); } } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (errors.length === 1) { throw errors[0]; } else if (errors.length > 1) { throw new MultiDisposeError(errors); } return Array.isArray(arg) ? [] : arg; } if (arg) { markTracked(arg); arg.dispose(); return arg; } } export function combinedDisposable() { for (var _len = arguments.length, disposables = new Array(_len), _key = 0; _key < _len; _key++) { disposables[_key] = arguments[_key]; } disposables.forEach(markTracked); return toDisposable(function () { return dispose(disposables); }); } export function toDisposable(fn) { var self = trackDisposable({ dispose: function dispose() { markTracked(self); fn(); } }); return self; } export var DisposableStore = /*#__PURE__*/function () { function DisposableStore() { _classCallCheck(this, DisposableStore); this._toDispose = new Set(); this._isDisposed = false; } _createClass(DisposableStore, [{ key: "dispose", value: /** * Dispose of all registered disposables and mark this object as disposed. * * Any future disposables added to this object will be disposed of on `add`. */ function dispose() { if (this._isDisposed) { return; } markTracked(this); this._isDisposed = true; this.clear(); } /** * Dispose of all registered disposables but do not mark this object as disposed. */ }, { key: "clear", value: function clear() { try { dispose(this._toDispose.values()); } finally { this._toDispose.clear(); } } }, { key: "add", value: function add(t) { if (!t) { return t; } if (t === this) { throw new Error('Cannot register a disposable on itself!'); } markTracked(t); if (this._isDisposed) { if (!DisposableStore.DISABLE_DISPOSED_WARNING) { console.warn(new Error('Trying to add a disposable to a DisposableStore that has already been disposed of. The added object will be leaked!').stack); } } else { this._toDispose.add(t); } return t; } }]); return DisposableStore; }(); DisposableStore.DISABLE_DISPOSED_WARNING = false; export var VSDisposable = (_dec = injectable(), _dec(_class2 = (_VSDisposable = /*#__PURE__*/function () { function VSDisposable() { _classCallCheck(this, VSDisposable); this._store = new DisposableStore(); trackDisposable(this); } _createClass(VSDisposable, [{ key: "dispose", value: function dispose() { markTracked(this); this._store.dispose(); } }, { key: "_register", value: function _register(t) { if (t === this) { throw new Error('Cannot register a disposable on itself!'); } return this._store.add(t); } }]); return VSDisposable; }(), _VSDisposable.None = Object.freeze({ dispose: function dispose() { // } }), _VSDisposable)) || _class2); /** * Manages the lifecycle of a disposable value that may be changed. * * This ensures that when the disposable value is changed, the previously held disposable is disposed of. You can * also register a `MutableDisposable` on a `VSDisposable` to ensure it is automatically cleaned up. */ export var MutableDisposable = /*#__PURE__*/function () { function MutableDisposable() { _classCallCheck(this, MutableDisposable); this._isDisposed = false; trackDisposable(this); } _createClass(MutableDisposable, [{ key: "value", get: function get() { return this._isDisposed ? undefined : this._value; }, set: function set(value) { var _this$_value; if (this._isDisposed || value === this._value) { return; } (_this$_value = this._value) === null || _this$_value === void 0 || _this$_value.dispose(); if (value) { markTracked(value); } this._value = value; } }, { key: "clear", value: function clear() { this.value = undefined; } }, { key: "dispose", value: function dispose() { var _this$_value2; this._isDisposed = true; markTracked(this); (_this$_value2 = this._value) === null || _this$_value2 === void 0 || _this$_value2.dispose(); this._value = undefined; } }]); return MutableDisposable; }(); export var ReferenceCollection = /*#__PURE__*/function () { function ReferenceCollection() { _classCallCheck(this, ReferenceCollection); this.references = new Map(); } _createClass(ReferenceCollection, [{ key: "acquire", value: function acquire(key) { var _this3 = this; var reference = this.references.get(key); if (!reference) { for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { args[_key2 - 1] = arguments[_key2]; } reference = { counter: 0, object: this.createReferencedObject.apply(this, [key].concat(args)) }; this.references.set(key, reference); } var _reference = reference, object = _reference.object; // eslint-disable-next-line @typescript-eslint/no-shadow var dispose = once(function () { if (--reference.counter === 0) { _this3.destroyReferencedObject(key, reference.object); _this3.references.delete(key); } }); reference.counter++; return { object: object, dispose: dispose }; } }]); return ReferenceCollection; }(); export var ImmortalReference = /*#__PURE__*/function () { function ImmortalReference(object) { _classCallCheck(this, ImmortalReference); this.object = object; } _createClass(ImmortalReference, [{ key: "dispose", value: function dispose() { /* noop */ } }]); return ImmortalReference; }();