@atlaspack/events 2.14.2-typescript-6de04fbae.0 → 2.14.2-typescript-08dcc1c9b.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/Disposable.js +35 -37
- package/lib/ValueEmitter.js +61 -59
- package/lib/errors.js +7 -11
- package/lib/index.js +23 -25
- package/lib/types.js +1 -4
- package/package.json +6 -18
- package/src/{Disposable.mts → Disposable.ts} +4 -4
- package/src/{ValueEmitter.mts → ValueEmitter.ts} +8 -6
- package/src/index.ts +3 -0
- package/src/{types.mts → types.ts} +1 -1
- package/test/{Disposable.test.mts → Disposable.test.ts} +11 -12
- package/test/{ValueEmitter.test.mts → ValueEmitter.test.ts} +3 -4
- package/lib/Disposable.d.mts +0 -10
- package/lib/Disposable.mjs +0 -32
- package/lib/ValueEmitter.d.mts +0 -8
- package/lib/ValueEmitter.mjs +0 -62
- package/lib/errors.d.mts +0 -2
- package/lib/errors.mjs +0 -5
- package/lib/index.d.mts +0 -3
- package/lib/index.js.flow +0 -26
- package/lib/index.mjs +0 -3
- package/lib/types.d.mts +0 -6
- package/lib/types.mjs +0 -1
- package/src/index.mts +0 -3
- /package/src/{errors.mts → errors.ts} +0 -0
package/lib/Disposable.js
CHANGED
|
@@ -1,48 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
+
value: true
|
|
4
5
|
});
|
|
5
|
-
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
function _assert() {
|
|
8
|
+
const data = _interopRequireDefault(require("assert"));
|
|
9
|
+
_assert = function () {
|
|
10
|
+
return data;
|
|
11
|
+
};
|
|
12
|
+
return data;
|
|
13
|
+
}
|
|
14
|
+
var _errors = require("./errors");
|
|
15
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
16
|
+
/*
|
|
6
17
|
* A general-purpose disposable class. It can normalize disposable-like values
|
|
7
18
|
* (such as single functions or IDisposables), as well as hold multiple
|
|
8
19
|
* disposable-like values to be disposed of at once.
|
|
9
|
-
*/
|
|
10
|
-
enumerable: true,
|
|
11
|
-
get: function() {
|
|
12
|
-
return Disposable;
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
const _assert = /*#__PURE__*/ _interop_require_default(require("assert"));
|
|
16
|
-
const _errors = require("./errors.mjs");
|
|
17
|
-
function _interop_require_default(obj) {
|
|
18
|
-
return obj && obj.__esModule ? obj : {
|
|
19
|
-
default: obj
|
|
20
|
-
};
|
|
21
|
-
}
|
|
20
|
+
*/
|
|
22
21
|
class Disposable {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
disposed = false;
|
|
23
|
+
#disposables;
|
|
24
|
+
constructor(...disposables) {
|
|
25
|
+
this.#disposables = new Set(disposables);
|
|
26
|
+
}
|
|
27
|
+
add(...disposables) {
|
|
28
|
+
if (this.disposed) {
|
|
29
|
+
throw new _errors.AlreadyDisposedError('Cannot add new disposables after disposable has been disposed');
|
|
27
30
|
}
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
(0, _assert.default)(this.#disposables != null);
|
|
33
|
-
for (let disposable of disposables){
|
|
34
|
-
this.#disposables.add(disposable);
|
|
35
|
-
}
|
|
31
|
+
(0, _assert().default)(this.#disposables != null);
|
|
32
|
+
for (let disposable of disposables) {
|
|
33
|
+
this.#disposables.add(disposable);
|
|
36
34
|
}
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
this.disposed = true;
|
|
42
|
-
(0, _assert.default)(this.#disposables != null);
|
|
43
|
-
await Promise.all([
|
|
44
|
-
...this.#disposables
|
|
45
|
-
].map((disposable)=>typeof disposable === 'function' ? disposable() : disposable.dispose()));
|
|
46
|
-
this.#disposables = null;
|
|
35
|
+
}
|
|
36
|
+
async dispose() {
|
|
37
|
+
if (this.disposed) {
|
|
38
|
+
return;
|
|
47
39
|
}
|
|
40
|
+
this.disposed = true;
|
|
41
|
+
(0, _assert().default)(this.#disposables != null);
|
|
42
|
+
await Promise.all([...this.#disposables].map(disposable => typeof disposable === 'function' ? disposable() : disposable.dispose()));
|
|
43
|
+
this.#disposables = null;
|
|
44
|
+
}
|
|
48
45
|
}
|
|
46
|
+
exports.default = Disposable;
|
package/lib/ValueEmitter.js
CHANGED
|
@@ -1,72 +1,74 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
+
value: true
|
|
4
5
|
});
|
|
5
|
-
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _errors = require("./errors");
|
|
8
|
+
// Like an EventEmitter, but for only a single "event". This provides type-safety
|
|
6
9
|
// for the values emitted. Rather than passing predetermined strings (which can
|
|
7
10
|
// be misspelled), create an instance of ValueEmitter for every logical "event"
|
|
8
11
|
// to be dispatched, and type it according to the type of value emitted.
|
|
9
|
-
"default", {
|
|
10
|
-
enumerable: true,
|
|
11
|
-
get: function() {
|
|
12
|
-
return ValueEmitter;
|
|
13
|
-
}
|
|
14
|
-
});
|
|
15
|
-
const _errors = require("./errors.mjs");
|
|
16
12
|
class ValueEmitter {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
this._listeners.push(listener);
|
|
27
|
-
// Close over a reference to this emitter in the disposable below, rather
|
|
28
|
-
// than referencing `this` directly. This allows us to set it to null after
|
|
29
|
-
// slicing out the listener.
|
|
30
|
-
// This prevents anyone holding onto the disposable after disposal from
|
|
31
|
-
// unintentionally retaining a reference to this emitter.
|
|
32
|
-
let emitter = this;
|
|
33
|
-
return {
|
|
34
|
-
dispose () {
|
|
35
|
-
if (emitter == null) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
if (emitter._disposed) {
|
|
39
|
-
emitter = null;
|
|
40
|
-
return;
|
|
41
|
-
}
|
|
42
|
-
let listeners = emitter._listeners;
|
|
43
|
-
let listenerIndex = listeners.indexOf(listener);
|
|
44
|
-
if (listenerIndex > -1) {
|
|
45
|
-
listeners.splice(listenerIndex, 1);
|
|
46
|
-
}
|
|
47
|
-
emitter = null;
|
|
48
|
-
}
|
|
49
|
-
};
|
|
13
|
+
// An array of listeners. One might think a Set would be better for O(1) removal,
|
|
14
|
+
// but splicing a JS array gets pretty close, and copying the array (as is done
|
|
15
|
+
// in emit) is far faster than a Set copy: https://github.com/atom/event-kit/pull/39
|
|
16
|
+
_listeners = [];
|
|
17
|
+
_disposed = false;
|
|
18
|
+
addListener(listener) {
|
|
19
|
+
if (this._disposed) {
|
|
20
|
+
throw new _errors.AlreadyDisposedError('Cannot add a listener since this ValueEmitter has been disposed');
|
|
50
21
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
22
|
+
this._listeners.push(listener);
|
|
23
|
+
|
|
24
|
+
// Close over a reference to this emitter in the disposable below, rather
|
|
25
|
+
// than referencing `this` directly. This allows us to set it to null after
|
|
26
|
+
// slicing out the listener.
|
|
27
|
+
// This prevents anyone holding onto the disposable after disposal from
|
|
28
|
+
// unintentionally retaining a reference to this emitter.
|
|
29
|
+
let emitter = this;
|
|
30
|
+
return {
|
|
31
|
+
dispose() {
|
|
32
|
+
if (emitter == null) {
|
|
33
|
+
return;
|
|
54
34
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
// other listeners from receiving the event.
|
|
60
|
-
let listeners = this._listeners.slice();
|
|
61
|
-
for(let i = 0; i < listeners.length; i++){
|
|
62
|
-
listeners[i](value);
|
|
35
|
+
if (emitter._disposed) {
|
|
36
|
+
// @ts-expect-error - Setting emitter to null to prevent memory leaks
|
|
37
|
+
emitter = null;
|
|
38
|
+
return;
|
|
63
39
|
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (
|
|
67
|
-
|
|
40
|
+
let listeners = emitter._listeners;
|
|
41
|
+
let listenerIndex = listeners.indexOf(listener);
|
|
42
|
+
if (listenerIndex > -1) {
|
|
43
|
+
listeners.splice(listenerIndex, 1);
|
|
68
44
|
}
|
|
69
|
-
|
|
70
|
-
|
|
45
|
+
|
|
46
|
+
// @ts-expect-error - Setting emitter to null to prevent memory leaks
|
|
47
|
+
emitter = null;
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
emit(value) {
|
|
52
|
+
if (this._disposed) {
|
|
53
|
+
throw new _errors.AlreadyDisposedError('Cannot emit since this ValueEmitter has been disposed');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Iterate over a copy of listeners. This prevents the following cases:
|
|
57
|
+
// * When a listener callback can itself register a new listener and be
|
|
58
|
+
// emitted as part of this iteration.
|
|
59
|
+
// * When a listener callback disposes of this emitter mid-emit, preventing
|
|
60
|
+
// other listeners from receiving the event.
|
|
61
|
+
let listeners = this._listeners.slice();
|
|
62
|
+
for (let i = 0; i < listeners.length; i++) {
|
|
63
|
+
listeners[i](value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
dispose() {
|
|
67
|
+
if (this._disposed) {
|
|
68
|
+
return;
|
|
71
69
|
}
|
|
70
|
+
this._listeners = [];
|
|
71
|
+
this._disposed = true;
|
|
72
|
+
}
|
|
72
73
|
}
|
|
74
|
+
exports.default = ValueEmitter;
|
package/lib/errors.js
CHANGED
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
+
value: true
|
|
4
5
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
return AlreadyDisposedError;
|
|
9
|
-
}
|
|
10
|
-
});
|
|
11
|
-
class AlreadyDisposedError extends Error {
|
|
12
|
-
}
|
|
6
|
+
exports.AlreadyDisposedError = void 0;
|
|
7
|
+
class AlreadyDisposedError extends Error {}
|
|
8
|
+
exports.AlreadyDisposedError = AlreadyDisposedError;
|
|
13
9
|
Object.defineProperty(AlreadyDisposedError.prototype, 'name', {
|
|
14
|
-
|
|
15
|
-
});
|
|
10
|
+
value: 'AlreadyDisposedError'
|
|
11
|
+
});
|
package/lib/index.js
CHANGED
|
@@ -1,29 +1,27 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
|
|
2
3
|
Object.defineProperty(exports, "__esModule", {
|
|
3
|
-
|
|
4
|
+
value: true
|
|
4
5
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
AlreadyDisposedError: function() {
|
|
13
|
-
return _errors.AlreadyDisposedError;
|
|
14
|
-
},
|
|
15
|
-
Disposable: function() {
|
|
16
|
-
return _Disposable.default;
|
|
17
|
-
},
|
|
18
|
-
ValueEmitter: function() {
|
|
19
|
-
return _ValueEmitter.default;
|
|
20
|
-
}
|
|
6
|
+
Object.defineProperty(exports, "AlreadyDisposedError", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _errors.AlreadyDisposedError;
|
|
10
|
+
}
|
|
21
11
|
});
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
12
|
+
Object.defineProperty(exports, "Disposable", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _Disposable.default;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(exports, "ValueEmitter", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () {
|
|
21
|
+
return _ValueEmitter.default;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
var _Disposable = _interopRequireDefault(require("./Disposable"));
|
|
25
|
+
var _ValueEmitter = _interopRequireDefault(require("./ValueEmitter"));
|
|
26
|
+
var _errors = require("./errors");
|
|
27
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
package/lib/types.js
CHANGED
package/package.json
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/events",
|
|
3
|
-
"version": "2.14.2-typescript-
|
|
3
|
+
"version": "2.14.2-typescript-08dcc1c9b.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
|
-
"type": "commonjs",
|
|
6
5
|
"publishConfig": {
|
|
7
6
|
"access": "public"
|
|
8
7
|
},
|
|
@@ -11,25 +10,14 @@
|
|
|
11
10
|
"url": "https://github.com/atlassian-labs/atlaspack.git"
|
|
12
11
|
},
|
|
13
12
|
"main": "lib/index.js",
|
|
14
|
-
"
|
|
13
|
+
"source": "src/index.ts",
|
|
15
14
|
"engines": {
|
|
16
15
|
"node": ">= 16.0.0"
|
|
17
16
|
},
|
|
18
|
-
"
|
|
19
|
-
".": {
|
|
20
|
-
"atlaspack::sources": "./src/index.mts",
|
|
21
|
-
"types": [
|
|
22
|
-
"./lib/index.d.mts",
|
|
23
|
-
"./src/index.mts"
|
|
24
|
-
],
|
|
25
|
-
"import": "./lib/index.mjs",
|
|
26
|
-
"require": "./lib/index.js",
|
|
27
|
-
"default": "./lib/index.js"
|
|
28
|
-
},
|
|
29
|
-
"./*": "./*"
|
|
30
|
-
},
|
|
17
|
+
"type": "commonjs",
|
|
31
18
|
"scripts": {
|
|
32
|
-
"
|
|
19
|
+
"check-ts": "tsc --noEmit"
|
|
33
20
|
},
|
|
34
|
-
"
|
|
21
|
+
"types": "src/index.ts",
|
|
22
|
+
"gitHead": "08dcc1c9bcdc6ab931d55e05ccc0f45669de2f22"
|
|
35
23
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type {IDisposable} from './types
|
|
1
|
+
import type {IDisposable} from './types';
|
|
2
2
|
|
|
3
3
|
import invariant from 'assert';
|
|
4
|
-
import {AlreadyDisposedError} from './errors
|
|
4
|
+
import {AlreadyDisposedError} from './errors';
|
|
5
5
|
|
|
6
|
-
type DisposableLike = IDisposable | (() =>
|
|
6
|
+
type DisposableLike = IDisposable | (() => unknown);
|
|
7
7
|
|
|
8
8
|
/*
|
|
9
9
|
* A general-purpose disposable class. It can normalize disposable-like values
|
|
@@ -12,7 +12,7 @@ type DisposableLike = IDisposable | (() => (any | Promise<any>));
|
|
|
12
12
|
*/
|
|
13
13
|
export default class Disposable implements IDisposable {
|
|
14
14
|
disposed: boolean = false;
|
|
15
|
-
#disposables: Set<DisposableLike> | null;
|
|
15
|
+
#disposables: Set<DisposableLike> | null | undefined;
|
|
16
16
|
|
|
17
17
|
constructor(...disposables: Array<DisposableLike>) {
|
|
18
18
|
this.#disposables = new Set(disposables);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type {IDisposable} from './types
|
|
1
|
+
import type {IDisposable} from './types';
|
|
2
2
|
|
|
3
|
-
import {AlreadyDisposedError} from './errors
|
|
3
|
+
import {AlreadyDisposedError} from './errors';
|
|
4
4
|
|
|
5
5
|
// Like an EventEmitter, but for only a single "event". This provides type-safety
|
|
6
6
|
// for the values emitted. Rather than passing predetermined strings (which can
|
|
@@ -10,10 +10,10 @@ export default class ValueEmitter<TValue> implements IDisposable {
|
|
|
10
10
|
// An array of listeners. One might think a Set would be better for O(1) removal,
|
|
11
11
|
// but splicing a JS array gets pretty close, and copying the array (as is done
|
|
12
12
|
// in emit) is far faster than a Set copy: https://github.com/atom/event-kit/pull/39
|
|
13
|
-
_listeners: Array<(value: TValue) =>
|
|
13
|
+
_listeners: Array<(value: TValue) => unknown> = [];
|
|
14
14
|
_disposed: boolean = false;
|
|
15
15
|
|
|
16
|
-
addListener(listener: (value: TValue) =>
|
|
16
|
+
addListener(listener: (value: TValue) => unknown): IDisposable {
|
|
17
17
|
if (this._disposed) {
|
|
18
18
|
throw new AlreadyDisposedError(
|
|
19
19
|
'Cannot add a listener since this ValueEmitter has been disposed',
|
|
@@ -27,7 +27,7 @@ export default class ValueEmitter<TValue> implements IDisposable {
|
|
|
27
27
|
// slicing out the listener.
|
|
28
28
|
// This prevents anyone holding onto the disposable after disposal from
|
|
29
29
|
// unintentionally retaining a reference to this emitter.
|
|
30
|
-
let emitter
|
|
30
|
+
let emitter = this;
|
|
31
31
|
return {
|
|
32
32
|
dispose() {
|
|
33
33
|
if (emitter == null) {
|
|
@@ -35,6 +35,7 @@ export default class ValueEmitter<TValue> implements IDisposable {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
if (emitter._disposed) {
|
|
38
|
+
// @ts-expect-error - Setting emitter to null to prevent memory leaks
|
|
38
39
|
emitter = null;
|
|
39
40
|
return;
|
|
40
41
|
}
|
|
@@ -45,6 +46,7 @@ export default class ValueEmitter<TValue> implements IDisposable {
|
|
|
45
46
|
listeners.splice(listenerIndex, 1);
|
|
46
47
|
}
|
|
47
48
|
|
|
49
|
+
// @ts-expect-error - Setting emitter to null to prevent memory leaks
|
|
48
50
|
emitter = null;
|
|
49
51
|
},
|
|
50
52
|
};
|
|
@@ -68,7 +70,7 @@ export default class ValueEmitter<TValue> implements IDisposable {
|
|
|
68
70
|
}
|
|
69
71
|
}
|
|
70
72
|
|
|
71
|
-
dispose()
|
|
73
|
+
dispose() {
|
|
72
74
|
if (this._disposed) {
|
|
73
75
|
return;
|
|
74
76
|
}
|
package/src/index.ts
ADDED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
|
-
import Disposable from '../src/Disposable
|
|
3
|
-
import {AlreadyDisposedError} from '../src/errors
|
|
2
|
+
import Disposable from '../src/Disposable';
|
|
3
|
+
import {AlreadyDisposedError} from '../src/errors';
|
|
4
4
|
|
|
5
5
|
describe('Disposable', () => {
|
|
6
6
|
it('can wrap an IDisposable', () => {
|
|
7
|
-
let disposed;
|
|
7
|
+
let disposed: any;
|
|
8
8
|
|
|
9
9
|
new Disposable({
|
|
10
10
|
dispose() {
|
|
@@ -15,7 +15,7 @@ describe('Disposable', () => {
|
|
|
15
15
|
});
|
|
16
16
|
|
|
17
17
|
it('can wrap a function to dispose', () => {
|
|
18
|
-
let disposed;
|
|
18
|
+
let disposed: any;
|
|
19
19
|
new Disposable(() => {
|
|
20
20
|
disposed = true;
|
|
21
21
|
}).dispose();
|
|
@@ -23,8 +23,8 @@ describe('Disposable', () => {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
it('can wrap many disposable-likes', () => {
|
|
26
|
-
let disposed1;
|
|
27
|
-
let disposed2;
|
|
26
|
+
let disposed1: any;
|
|
27
|
+
let disposed2: any;
|
|
28
28
|
|
|
29
29
|
new Disposable(
|
|
30
30
|
{
|
|
@@ -41,10 +41,10 @@ describe('Disposable', () => {
|
|
|
41
41
|
});
|
|
42
42
|
|
|
43
43
|
it('can add disposables after construction', () => {
|
|
44
|
-
let disposed1;
|
|
45
|
-
let disposed2;
|
|
46
|
-
let disposed3;
|
|
47
|
-
let disposed4;
|
|
44
|
+
let disposed1: any;
|
|
45
|
+
let disposed2: any;
|
|
46
|
+
let disposed3: any;
|
|
47
|
+
let disposed4: any;
|
|
48
48
|
|
|
49
49
|
let disposable = new Disposable(
|
|
50
50
|
{
|
|
@@ -85,10 +85,9 @@ describe('Disposable', () => {
|
|
|
85
85
|
'does not dispose inner disposables more than once,' +
|
|
86
86
|
' and does not throw on subsequent disposals',
|
|
87
87
|
() => {
|
|
88
|
-
let disposed:
|
|
88
|
+
let disposed: any;
|
|
89
89
|
let disposable = new Disposable(() => {
|
|
90
90
|
if (disposed) {
|
|
91
|
-
// $FlowFixMe
|
|
92
91
|
assert.fail();
|
|
93
92
|
}
|
|
94
93
|
disposed = true;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import assert from 'assert';
|
|
2
|
-
import ValueEmitter from '../src/ValueEmitter
|
|
3
|
-
import {AlreadyDisposedError} from '../src/errors
|
|
4
|
-
import type { IDisposable } from '../src/types.mts';
|
|
2
|
+
import ValueEmitter from '../src/ValueEmitter';
|
|
3
|
+
import {AlreadyDisposedError} from '../src/errors';
|
|
5
4
|
|
|
6
5
|
describe('ValueEmitter', () => {
|
|
7
6
|
let emitter: ValueEmitter<number>;
|
|
@@ -37,7 +36,7 @@ describe('ValueEmitter', () => {
|
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
it('does not emit to listeners that were just registered', () => {
|
|
40
|
-
let innerDisposable:
|
|
39
|
+
let innerDisposable: any;
|
|
41
40
|
let disposable = emitter.addListener(() => {
|
|
42
41
|
innerDisposable = emitter.addListener(numberListener);
|
|
43
42
|
});
|
package/lib/Disposable.d.mts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import type { IDisposable } from './types.mts';
|
|
2
|
-
type DisposableLike = IDisposable | (() => (any | Promise<any>));
|
|
3
|
-
export default class Disposable implements IDisposable {
|
|
4
|
-
#private;
|
|
5
|
-
disposed: boolean;
|
|
6
|
-
constructor(...disposables: Array<DisposableLike>);
|
|
7
|
-
add(...disposables: Array<DisposableLike>): void;
|
|
8
|
-
dispose(): Promise<void>;
|
|
9
|
-
}
|
|
10
|
-
export {};
|
package/lib/Disposable.mjs
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import invariant from 'assert';
|
|
2
|
-
import { AlreadyDisposedError } from "./errors.mjs";
|
|
3
|
-
/*
|
|
4
|
-
* A general-purpose disposable class. It can normalize disposable-like values
|
|
5
|
-
* (such as single functions or IDisposables), as well as hold multiple
|
|
6
|
-
* disposable-like values to be disposed of at once.
|
|
7
|
-
*/
|
|
8
|
-
export default class Disposable {
|
|
9
|
-
disposed = false;
|
|
10
|
-
#disposables;
|
|
11
|
-
constructor(...disposables) {
|
|
12
|
-
this.#disposables = new Set(disposables);
|
|
13
|
-
}
|
|
14
|
-
add(...disposables) {
|
|
15
|
-
if (this.disposed) {
|
|
16
|
-
throw new AlreadyDisposedError('Cannot add new disposables after disposable has been disposed');
|
|
17
|
-
}
|
|
18
|
-
invariant(this.#disposables != null);
|
|
19
|
-
for (let disposable of disposables) {
|
|
20
|
-
this.#disposables.add(disposable);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
async dispose() {
|
|
24
|
-
if (this.disposed) {
|
|
25
|
-
return;
|
|
26
|
-
}
|
|
27
|
-
this.disposed = true;
|
|
28
|
-
invariant(this.#disposables != null);
|
|
29
|
-
await Promise.all([...this.#disposables].map((disposable) => typeof disposable === 'function' ? disposable() : disposable.dispose()));
|
|
30
|
-
this.#disposables = null;
|
|
31
|
-
}
|
|
32
|
-
}
|
package/lib/ValueEmitter.d.mts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { IDisposable } from './types.mts';
|
|
2
|
-
export default class ValueEmitter<TValue> implements IDisposable {
|
|
3
|
-
_listeners: Array<(value: TValue) => (any | Promise<any>)>;
|
|
4
|
-
_disposed: boolean;
|
|
5
|
-
addListener(listener: (value: TValue) => (any | Promise<any>)): IDisposable;
|
|
6
|
-
emit(value: TValue): void;
|
|
7
|
-
dispose(): void;
|
|
8
|
-
}
|
package/lib/ValueEmitter.mjs
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { AlreadyDisposedError } from "./errors.mjs";
|
|
2
|
-
// Like an EventEmitter, but for only a single "event". This provides type-safety
|
|
3
|
-
// for the values emitted. Rather than passing predetermined strings (which can
|
|
4
|
-
// be misspelled), create an instance of ValueEmitter for every logical "event"
|
|
5
|
-
// to be dispatched, and type it according to the type of value emitted.
|
|
6
|
-
export default class ValueEmitter {
|
|
7
|
-
// An array of listeners. One might think a Set would be better for O(1) removal,
|
|
8
|
-
// but splicing a JS array gets pretty close, and copying the array (as is done
|
|
9
|
-
// in emit) is far faster than a Set copy: https://github.com/atom/event-kit/pull/39
|
|
10
|
-
_listeners = [];
|
|
11
|
-
_disposed = false;
|
|
12
|
-
addListener(listener) {
|
|
13
|
-
if (this._disposed) {
|
|
14
|
-
throw new AlreadyDisposedError('Cannot add a listener since this ValueEmitter has been disposed');
|
|
15
|
-
}
|
|
16
|
-
this._listeners.push(listener);
|
|
17
|
-
// Close over a reference to this emitter in the disposable below, rather
|
|
18
|
-
// than referencing `this` directly. This allows us to set it to null after
|
|
19
|
-
// slicing out the listener.
|
|
20
|
-
// This prevents anyone holding onto the disposable after disposal from
|
|
21
|
-
// unintentionally retaining a reference to this emitter.
|
|
22
|
-
let emitter = this;
|
|
23
|
-
return {
|
|
24
|
-
dispose() {
|
|
25
|
-
if (emitter == null) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
if (emitter._disposed) {
|
|
29
|
-
emitter = null;
|
|
30
|
-
return;
|
|
31
|
-
}
|
|
32
|
-
let listeners = emitter._listeners;
|
|
33
|
-
let listenerIndex = listeners.indexOf(listener);
|
|
34
|
-
if (listenerIndex > -1) {
|
|
35
|
-
listeners.splice(listenerIndex, 1);
|
|
36
|
-
}
|
|
37
|
-
emitter = null;
|
|
38
|
-
},
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
emit(value) {
|
|
42
|
-
if (this._disposed) {
|
|
43
|
-
throw new AlreadyDisposedError('Cannot emit since this ValueEmitter has been disposed');
|
|
44
|
-
}
|
|
45
|
-
// Iterate over a copy of listeners. This prevents the following cases:
|
|
46
|
-
// * When a listener callback can itself register a new listener and be
|
|
47
|
-
// emitted as part of this iteration.
|
|
48
|
-
// * When a listener callback disposes of this emitter mid-emit, preventing
|
|
49
|
-
// other listeners from receiving the event.
|
|
50
|
-
let listeners = this._listeners.slice();
|
|
51
|
-
for (let i = 0; i < listeners.length; i++) {
|
|
52
|
-
listeners[i](value);
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
dispose() {
|
|
56
|
-
if (this._disposed) {
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
this._listeners = [];
|
|
60
|
-
this._disposed = true;
|
|
61
|
-
}
|
|
62
|
-
}
|
package/lib/errors.d.mts
DELETED
package/lib/errors.mjs
DELETED
package/lib/index.d.mts
DELETED
package/lib/index.js.flow
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
|
-
export interface IDisposable {
|
|
4
|
-
/** This can return a Promise, as dispose() of all inner disposables are
|
|
5
|
-
* awaited in Disposable#dispose()
|
|
6
|
-
*/
|
|
7
|
-
dispose(): mixed;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export type DisposableLike = IDisposable | (() => mixed);
|
|
11
|
-
|
|
12
|
-
declare export class Disposable implements IDisposable {
|
|
13
|
-
disposed: boolean;
|
|
14
|
-
add(...disposables: Array<DisposableLike>): void;
|
|
15
|
-
dispose(): Promise<void> ;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
declare export class AlreadyDisposedError extends Error {
|
|
19
|
-
name: string
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
declare export class ValueEmitter<TValue> implements IDisposable {
|
|
23
|
-
addListener(listener: (value: TValue) => mixed): IDisposable;
|
|
24
|
-
emit(value: TValue): void;
|
|
25
|
-
dispose(): void;
|
|
26
|
-
}
|
package/lib/index.mjs
DELETED
package/lib/types.d.mts
DELETED
package/lib/types.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
package/src/index.mts
DELETED
|
File without changes
|