├── .editorconfig
├── .gitignore
├── .jshintrc
├── .markdown-doctest-setup.js
├── .travis.yml
├── LICENSE
├── README.md
├── binarydisposable.js
├── code-of-conduct.md
├── compositedisposable.js
├── disposable.js
├── doc
├── binarydisposable.md
├── compositedisposable.md
├── disposable.md
├── narydisposable.md
├── refcountdisposable.md
├── serialdisposable.md
└── singleassignmentdisposable.md
├── index.js
├── narydisposable.js
├── package.json
├── refcountdisposable.js
├── serialdisposable.js
├── singleassignmentdisposable.js
└── test
├── binarydisposable.js
├── disposable.js
├── narydisposable.js
├── refcountdisposable.js
├── serialdisposable.js
└── singleassignmentdisposable.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | end_of_line = lf
5 | insert_final_newline = false
6 | indent_style = space
7 | indent_size = 2
8 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27 | node_modules
28 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "latedef": true,
6 | "newcap": true,
7 | "noarg": true,
8 | "sub": true,
9 | "undef": true,
10 | "unused": true,
11 | "boss": true,
12 | "eqnull": true,
13 | "node": true,
14 | "-W030": true,
15 | "predef": [ "Promise" ]
16 | }
17 |
--------------------------------------------------------------------------------
/.markdown-doctest-setup.js:
--------------------------------------------------------------------------------
1 | var disposables = require(__dirname);
2 |
3 | module.exports = {
4 | require: {
5 | 'rx.disposables': disposables
6 | },
7 |
8 | globals: disposables
9 | }
10 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "0.10"
4 | - "0.12"
5 | - 4
6 | - 5
7 | env:
8 | global:
9 | - secure: "JwyiLIEV6S7wzr9eUgQ/rP8BeeSY6ZabknHpUKSk4miA7d+/acFeuMAYu0d79BG8ndFIdG9EYbA7ZY1TH/metqDTrExzYLooa0XrAYg2x+cDSboII9albVn5bvdmmWIcgcmcZwKvi5JYLHWcA3Px84Aaf3YXN9V4lS1uLhl0eBI="
10 | - secure: "BVYlZy3vIt21bhrzKPgQzRlbwGCBrdBtRPRvX/qCGi1jYAoAtrT0bYllZpNqduPLouW3LaJDwOJx9zLDmZDwKDvPgTinpVwmkhZYRFl1kNweku3ZfeHR5ejOVYvdQEqVU4rOtTBLk6emItEPTuFtC9SPSYQZQtjnZAjHTg0jqLU="
11 | notifications:
12 | slack: reactivex:e424dAgQ2W9kuRMe6ngxHQbv
13 | webhooks:
14 | urls:
15 | - https://webhooks.gitter.im/e/8f1482d7420d95b647ce
16 | on_success: change # options: [always|never|change] default: always
17 | on_failure: always # options: [always|never|change] default: always
18 | on_start: false # default: false
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Microsoft Corporation
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/Reactive-Extensions/rx.disposables)
2 | [](https://github.com/Reactive-Extensions/rx.disposables)
3 | [](https://www.npmjs.com/package/rx.disposables)
4 | [](https://www.npmjs.com/package/rx.disposables)
5 | # `rx.disposables` - RxJS disposables
6 |
7 | This is a standalone version of the RxJS disposable classes which can manage the lifetime of any given resource.
8 |
9 | This includes the following disposables with their documentation:
10 | - [`BinaryDisposable`](doc/binarydisposable.md)
11 | - [`CompositeDisposable`](doc/compositedisposable.md)
12 | - [`Disposable`](doc/disposable.md)
13 | - [`NAryDisposable`](doc/narydisposable.md)
14 | - [`SerialDisposable`](doc/serialdisposable.md)
15 | - [`SingleAssignmentDisposable`](doc/singleassignmentdisposable.md)
16 |
17 | ## Installation
18 |
19 | The `rx.disposables` library can be installed by the following:
20 |
21 | ### NPM
22 | ```bash
23 | $ npm install rx.disposables
24 | ```
25 |
26 | ## Usage
27 |
28 | Here is some basic usage a simple `Disposable` to handle resources:
29 | ```js
30 | const Disposable = require('rx.disposables').Disposable;
31 |
32 | // Imagine this to be some sort of resource
33 | let isDisposed = false;
34 | const d = Disposable.create(() => isDisposed = true);
35 |
36 | d.dispose();
37 | console.log(`isDisposed is ${isDisposed}`);
38 | // => isDisposed is true
39 | ```
40 |
41 | There may be some instances when you want the disposable to be ref counted so that it only disposes when all dependent observables have been disposed, for example a file handle.
42 |
43 | ```js
44 | const d = require('rx.disposables');
45 |
46 | // Imagine this to be a resource
47 | let isDisposed = false;
48 | const dd = d.Disposable.create(() => isDisposed = true);
49 |
50 | const r = new d.RefCountDisposable(dd);
51 |
52 | // Make two references
53 | const d1 = r.getDisposable();
54 | const d2 = r.getDisposable();
55 |
56 | // Clean up each
57 | d1.dispose();
58 | d2.dispose();
59 |
60 | // Now we can clean up now that ref count went to zero
61 | r.dispose();
62 | console.log(`isDisposed is ${isDisposed}`);
63 | // => isDisposed is true
64 | ```
65 |
66 | We can also handle collections in multiple ways, either with the immutable disposables such as the `BinaryDisposable` for handling two disposables, and `NAryDisposable` for handling arrays. If you wish to add and remove disposables from a list, you can use the `CompositeDisposable`.
67 |
68 | ```js
69 | const d = require('rx.disposables');
70 |
71 | const d1 = d.Disposable.create(() => console.log('one'));
72 | const d2 = d.Disposable.create(() => console.log('two'));
73 |
74 | const c = new d.CompositeDisposable(d1, d2);
75 |
76 | const d3 = d.Disposable.create(() => console.log('three'));
77 | c.add(d3);
78 |
79 | c.remove(d3);
80 | // => three
81 |
82 | c.dispose();
83 | // => one
84 | // => two
85 | ```
86 |
87 | There may also be times when you need to set the disposable later, so you can manage it in a container such as the `SingleAssignmentDisposable` for handling only one assignment, and the `SerialDisposable` which disposes the previous and sets the new disposable if the `SerialDisposable` has not been disposed.
88 |
89 | For example, we could set it later using the `SingleAssignmentDisposable`:
90 |
91 | ```js
92 | const d = require('rx.disposables');
93 |
94 | const sad = new d.SingleAssignmentDisposable();
95 |
96 | const d1 = d.Disposable.create(() => console.log('one'));
97 |
98 | // Set the disposable later
99 | sad.setDisposable(d1);
100 |
101 | sad.dispose();
102 | // => one
103 | ```
104 |
105 | And we could also use the `SerialDisposable` if we have the need to swap out our disposable:
106 |
107 | ```js
108 | const d = require('rx.disposables');
109 |
110 | const sd = new d.SerialDisposable();
111 |
112 | const d1 = d.Disposable.create(() => console.log('one'));
113 |
114 | // Set the disposable later
115 | sd.setDisposable(d1);
116 |
117 | const d2 = d.Disposable.create(() => console.log('two'));
118 |
119 | // Replace the disposable
120 | sd.setDisposable(d2);
121 | // => one
122 |
123 | sd.dispose();
124 | // => two
125 | ```
126 |
127 | ## Contributing
128 |
129 | We appreciate any contributions by the community as long as they abide by the [Code of Conduct](code-of-conduct.md).
130 |
131 | Want to get started? Here are some ways you can get involved.
132 | 1. Documentation
133 | - Examples
134 | - How Do I?
135 | - API Documentation
136 | 2. Code
137 | - Additional disposables
138 | - Unit tests
139 |
140 | # LICENSE
141 |
142 | The MIT License (MIT)
143 |
144 | Copyright (c) 2016 Microsoft Corporation
145 |
146 | Permission is hereby granted, free of charge, to any person obtaining a copy
147 | of this software and associated documentation files (the "Software"), to deal
148 | in the Software without restriction, including without limitation the rights
149 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
150 | copies of the Software, and to permit persons to whom the Software is
151 | furnished to do so, subject to the following conditions:
152 |
153 | The above copyright notice and this permission notice shall be included in all
154 | copies or substantial portions of the Software.
155 |
156 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
157 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
158 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
159 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
160 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
161 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
162 | SOFTWARE.
163 |
--------------------------------------------------------------------------------
/binarydisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Represents a group of disposable resources that are disposed together.
5 | * @constructor
6 | * Creates a new group of disposable resources that are disposed together.
7 | * @param [Any] first The first disposable resoruce to add to the group.
8 | * @param [Any] second The second disposable resoruce to add to the group.
9 | */
10 | function BinaryDisposable(first, second) {
11 | this._first = first;
12 | this._second = second;
13 | this.isDisposed = false;
14 | }
15 |
16 | /**
17 | * Disposes all disposables in the group.
18 | */
19 | BinaryDisposable.prototype.dispose = function () {
20 | if (!this.isDisposed) {
21 | this.isDisposed = true;
22 | var old1 = this._first;
23 | this._first = null;
24 | old1 && old1.dispose();
25 | var old2 = this._second;
26 | this._second = null;
27 | old2 && old2.dispose();
28 | }
29 | };
30 |
31 | module.exports = BinaryDisposable;
32 |
--------------------------------------------------------------------------------
/code-of-conduct.md:
--------------------------------------------------------------------------------
1 | # Code of Conduct #
2 |
3 | [_Adapted from the Rust Code of Conduct_](https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct)
4 |
5 | We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic.
6 | - On any communication medium, please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all.
7 | - Please be kind and courteous. There's no need to be mean or rude.
8 | - Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer.
9 | - Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works.
10 | - We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups.
11 | - Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one the RxJS team immediately. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back.
12 | - Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome.
13 |
--------------------------------------------------------------------------------
/compositedisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Represents a group of disposable resources that are disposed together.
5 | * @constructor
6 | */
7 | function CompositeDisposable () {
8 | var args = [], i, len;
9 | if (Array.isArray(arguments[0])) {
10 | args = arguments[0];
11 | len = args.length;
12 | } else {
13 | len = arguments.length;
14 | args = new Array(len);
15 | for(i = 0; i < len; i++) { args[i] = arguments[i]; }
16 | }
17 | this._disposables = args;
18 | this.isDisposed = false;
19 | this.length = args.length;
20 | }
21 |
22 | /**
23 | * Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
24 | * @param {Any} item Disposable to add.
25 | */
26 | CompositeDisposable.prototype.add = function (item) {
27 | if (this.isDisposed) {
28 | item.dispose();
29 | } else {
30 | this._disposables.push(item);
31 | this.length++;
32 | }
33 | };
34 |
35 | /**
36 | * Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
37 | * @param {Any} item Disposable to remove.
38 | * @returns {Boolean} true if found; false otherwise.
39 | */
40 | CompositeDisposable.prototype.remove = function (item) {
41 | var shouldDispose = false;
42 | if (!this.isDisposed) {
43 | var idx = this._disposables.indexOf(item);
44 | if (idx !== -1) {
45 | shouldDispose = true;
46 | this._disposables.splice(idx, 1);
47 | this.length--;
48 | item.dispose();
49 | }
50 | }
51 | return shouldDispose;
52 | };
53 |
54 | /**
55 | * Disposes all disposables in the group and removes them from the group but
56 | * does not dispose the CompositeDisposable.
57 | */
58 | CompositeDisposable.prototype.clear = function () {
59 | if (!this.isDisposed) {
60 | var len = this._disposables.length, currentDisposables = new Array(len);
61 | for(var i = 0; i < len; i++) { currentDisposables[i] = this._disposables[i]; }
62 | this._disposables = [];
63 | this.length = 0;
64 |
65 | for (i = 0; i < len; i++) {
66 | currentDisposables[i].dispose();
67 | }
68 | }
69 | };
70 |
71 | /**
72 | * Disposes all disposables in the group and removes them from the group.
73 | */
74 | CompositeDisposable.prototype.dispose = function () {
75 | if (!this.isDisposed) {
76 | this.isDisposed = true;
77 | var len = this._disposables.length, currentDisposables = new Array(len);
78 | for(var i = 0; i < len; i++) { currentDisposables[i] = this._disposables[i]; }
79 | this._disposables = [];
80 | this.length = 0;
81 |
82 | for (i = 0; i < len; i++) {
83 | currentDisposables[i].dispose();
84 | }
85 | }
86 | };
87 |
88 | module.exports = CompositeDisposable;
89 |
--------------------------------------------------------------------------------
/disposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | function noop () { }
4 |
5 | var isFunction = module.exports = (function () {
6 | var isFn = function (value) {
7 | return typeof value === 'function' || false;
8 | };
9 |
10 | // fallback for older versions of Chrome and Safari
11 | if (isFn(/x/)) {
12 | isFn = function(value) {
13 | return typeof value === 'function' &&
14 | Object.prototype.toString.call(value) === '[object Function]';
15 | };
16 | }
17 | return isFn;
18 | }());
19 |
20 | /**
21 | * Provides a set of static methods for creating Disposables.
22 | * @param {Function} action Action to run during the first call to dispose.
23 | * The action is guaranteed to be run at most once.
24 | */
25 | function Disposable (action) {
26 | this.isDisposed = false;
27 | this.action = isFunction(action) ? action : noop;
28 | }
29 |
30 | /** Performs the task of cleaning up resources. */
31 | Disposable.prototype.dispose = function () {
32 | if (!this.isDisposed) {
33 | this.action();
34 | this.isDisposed = true;
35 | }
36 | };
37 |
38 | /**
39 | * Creates a disposable object that invokes the specified action when disposed.
40 | * @param {Function} dispose Action to run during the first call to dispose.
41 | * The action is guaranteed to be run at most once.
42 | * @return {Disposable} The disposable object that runs the given action upon disposal.
43 | */
44 | Disposable.create = function (action) { return new Disposable(action); };
45 |
46 | /**
47 | * Gets the disposable that does nothing when disposed.
48 | */
49 | Disposable.empty = { dispose: noop };
50 |
51 | /**
52 | * Validates whether the given object is a disposable
53 | * @param {Object} Object to test whether it has a dispose method
54 | * @returns {Boolean} true if a disposable object, else false.
55 | */
56 | Disposable.isDisposable = function (d) {
57 | return d && isFunction(d.dispose);
58 | };
59 |
60 | Disposable._fixup = function (result) {
61 | return Disposable.isDisposable(result) ? result : Disposable.empty;
62 | };
63 |
64 | module.exports = Disposable;
65 |
--------------------------------------------------------------------------------
/doc/binarydisposable.md:
--------------------------------------------------------------------------------
1 | # `BinaryDisposable` class #
2 |
3 | Represents an immutable group of two disposable resources that are disposed together.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `BinaryDisposable`.
8 |
9 | ```js
10 | const d1 = Disposable.create(() => console.log('one'));
11 | const d2 = Disposable.create(() => console.log('two'));
12 |
13 | // Initialize with two disposables
14 | const disposables = new BinaryDisposable(d1, d2);
15 |
16 | disposables.dispose();
17 | // => one
18 | // => two
19 | ```
20 |
21 | ## `BinaryDisposable Constructor` ##
22 | - [`constructor`](#binarydisposablefirst-second)
23 |
24 | ## `BinaryDisposable Instance Methods` ##
25 | - [`dispose`](#binarydisposableprototypedispose)
26 |
27 | ## `BinaryDisposable Instance Properties` ##
28 | - [`isDisposed`](#isdisposed)
29 |
30 | ## _BinaryDisposable Constructor_ ##
31 |
32 | ### `BinaryDisposable(first, second)`
33 |
34 | Creates a new group of two disposable resources that are disposed together.
35 |
36 | #### Arguments
37 | 1. `first`: `Disposable` - The first disposable resource to add to the group.
38 | 2. `second`: `Disposable` - The second disposable resource to add to the group.
39 |
40 | #### Example
41 | ```js
42 | const d1 = Disposable.create(() => console.log('one'));
43 | const d2 = Disposable.create(() => console.log('two'));
44 |
45 | // Initialize with two disposables
46 | const disposables = new BinaryDisposable(d1, d2);
47 |
48 | disposables.dispose();
49 | // => one
50 | // => two
51 | ```
52 |
53 | * * *
54 |
55 | ## _BinaryDisposable Instance Methods_ ##
56 |
57 | ### `BinaryDisposable.prototype.dispose()`
58 |
59 | Disposes the underlying disposables.
60 |
61 | #### Example
62 |
63 | ```js
64 | const d1 = Disposable.create(() => console.log('one'));
65 | const d2 = Disposable.create(() => console.log('two'));
66 |
67 | const disposables = new BinaryDisposable(d1, d2);
68 |
69 | disposables.dispose();
70 | // => one
71 | // => two
72 |
73 | console.log(disposables.length);
74 | // => 0
75 | ```
76 | * * *
77 |
78 | ## _BinaryDisposable Instance Properties_ ##
79 |
80 | ### `isDisposed`
81 |
82 | Gets a value that indicates whether the object is disposed.
83 |
84 | #### Example
85 | ```js
86 | const d1 = Disposable.create(() => console.log('one'));
87 | const d2 = Disposable.create(() => console.log('two'));
88 |
89 | const disposables = new BinaryDisposable(d1, d2);
90 |
91 | console.log(disposables.isDisposed);
92 | // => false
93 |
94 | disposables.dispose();
95 | // => disposed
96 |
97 | console.log(disposables.isDisposed);
98 | // => true
99 | ```
100 |
101 | * * *
102 |
--------------------------------------------------------------------------------
/doc/compositedisposable.md:
--------------------------------------------------------------------------------
1 | # `CompositeDisposable` class #
2 |
3 | Represents a group of disposable resources that are disposed together that can be added to and removed from.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `CompositeDisposable`.
8 |
9 | ```js
10 | const d1 = Disposable.create(() => console.log('one'));
11 | const d2 = Disposable.create(() => console.log('two'));
12 |
13 | // Initialize with two disposables
14 | const disposables = new CompositeDisposable(d1, d2);
15 |
16 | disposables.dispose();
17 | // => one
18 | // => two
19 | ```
20 |
21 | ## `CompositeDisposable` Constructor ##
22 | - [`constructor`](#compositedisposablergs)
23 |
24 | ## `CompositeDisposable` Instance Methods ##
25 | - [`add`](#compositedisposableprototypeadditem)
26 | - [`clear`](#compositedisposableprototypeclear)
27 | - [`dispose`](#compositedisposableprototypedispose)
28 | - [`remove`](#compositedisposableprototyperemoveitem)
29 |
30 | ## `CompositeDisposable` Instance Properties ##
31 | - [`isDisposed`](#isdisposed)
32 | - [`length`](#length)
33 |
34 | ## _CompositeDisposable Constructor_ ##
35 |
36 | ### `CompositeDisposable(...args)`
37 |
38 | Initializes a new instance of the `CompositeDisposable` class from a group of disposables.
39 |
40 | #### Arguments
41 | 1. `args`: `Array|arguments` - Disposables that will be disposed together.
42 |
43 | #### Example
44 | ```js
45 | const d1 = Disposable.create(() => console.log('one'));
46 | const d2 = Disposable.create(() => console.log('two'));
47 |
48 | // Initialize with two disposables
49 | const disposables = new CompositeDisposable(d1, d2);
50 |
51 | disposables.dispose();
52 | // => one
53 | // => two
54 | ```
55 |
56 | * * *
57 |
58 | ## _CompositeDisposable Instance Methods_ ##
59 |
60 | ### `CompositeDisposable.prototype.add(item)`
61 |
62 | Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed.
63 |
64 | #### Arguments
65 | 1. `item` `Disposable`: Disposable to add.
66 |
67 | #### Example
68 |
69 | ```js
70 | const disposables = new CompositeDisposable();
71 |
72 | const d1 = Disposable.create(() => console.log('one'));
73 |
74 | disposables.add(d1);
75 |
76 | disposables.dispose();
77 | // => one
78 | ```
79 |
80 | * * *
81 |
82 | ### `CompositeDisposable.prototype.clear()`
83 |
84 | Disposes all disposables in the group and removes them from the group but does not dispose the CompositeDisposable.
85 |
86 | #### Example
87 |
88 | ```js
89 | const d1 = Disposable.create(() => console.log('one'));
90 | const d2 = Disposable.create(() => console.log('two'));
91 |
92 | const disposables = new CompositeDisposable(d1, d2);
93 |
94 | disposables.dispose();
95 | // => one
96 | // => two
97 |
98 | console.log(disposables.isDisposed);
99 | // => false
100 | ```
101 |
102 | * * *
103 |
104 | ### `CompositeDisposable.prototype.dispose()`
105 |
106 | Disposes all disposables in the group and removes them from the group.
107 |
108 | #### Example
109 |
110 | ```js
111 | const d1 = Disposable.create(() => console.log('one'));
112 | const d2 = Disposable.create(() => console.log('two'));
113 |
114 | const disposables = new CompositeDisposable(d1, d2);
115 |
116 | disposables.dispose();
117 | // => one
118 | // => two
119 |
120 | console.log(disposables.length);
121 | // => 0
122 | ```
123 |
124 | * * *
125 |
126 | ### `CompositeDisposable.prototype.remove(item)`
127 |
128 | Removes and disposes the first occurrence of a disposable from the CompositeDisposable.
129 |
130 | #### Arguments
131 | 1. `item` `Disposable`: Disposable to remove.
132 |
133 | #### Returns
134 | `Boolean`: `true` if the disposable was found and disposed; otherwise, `false`.
135 |
136 | #### Example
137 |
138 | ```js
139 | const disposables = new CompositeDisposable();
140 |
141 | const d1 = Disposable.create(function () {
142 | console.log('one');
143 | });
144 |
145 | disposables.add(d1);
146 |
147 | console.log(disposables.remove(d1));
148 | // => true
149 | ```
150 |
151 | * * *
152 |
153 | ## _CompositeDisposable Instance Properties_ ##
154 |
155 | ### `isDisposed`
156 | #
157 |
158 | Gets a value that indicates whether the object is disposed.
159 |
160 | #### Example
161 | ```js
162 | const disposables = new CompositeDisposable();
163 |
164 | const d1 = Disposable.create(() => console.log('disposed'));
165 |
166 | disposables.add(d1);
167 |
168 | console.log(disposables.isDisposed);
169 | // => false
170 |
171 | disposables.dispose();
172 | // => disposed
173 |
174 | console.log(disposables.isDisposed);
175 | // => true
176 | ```
177 |
178 | * * *
179 |
180 | ### `length`
181 | #
182 |
183 | Gets the number of disposables in the CompositeDisposable.
184 |
185 | #### Example
186 | ```js
187 | const disposables = new CompositeDisposable();
188 |
189 | const d1 = Disposable.create(() => console.log('disposed'));
190 |
191 | disposables.add(d1);
192 |
193 | console.log(disposables.length);
194 | // => 1
195 |
196 | disposables.dispose();
197 | // => disposed
198 |
199 | console.log(disposables.length);
200 | // => 0
201 | ```
202 |
203 | * * *
204 |
--------------------------------------------------------------------------------
/doc/disposable.md:
--------------------------------------------------------------------------------
1 | # `Disposable` class #
2 |
3 | Provides a set of static methods for creating Disposables, which defines a method to release allocated resources.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of an `Disposable`.
8 |
9 | ```js
10 | const disposable = Disposable.create(() => console.log('disposed'));
11 |
12 | disposable.dispose();
13 | // => disposed
14 | ```
15 |
16 | ## `Disposable` Class Methods ##
17 | - [`create`](#disposablecreateaction)
18 | - [`isDisposable`](#disposableisdisposabled)
19 |
20 | ## `Disposable` Class Properties ##
21 | - [`empty`](#disposableempty)
22 |
23 | ## `Disposable` Instance Methods ##
24 | - [`dispose`](#disposableprototypedispose)
25 |
26 | ## _Class Methods_ ##
27 |
28 | ### `Disposable.create(action)`
29 |
30 | Creates a disposable object that invokes the specified action when disposed.
31 |
32 | #### Arguments
33 | 1. `action` `Function`: Function to run during the first call to `dispose`. The action is guaranteed to be run at most once.
34 |
35 | #### Returns
36 | `Disposable`: The disposable object that runs the given action upon disposal.
37 |
38 | #### Example
39 | ```js
40 | const disposable = Disposable.create(() => console.log('disposed'));
41 |
42 | disposable.dispose();
43 | // => disposed
44 | ```
45 |
46 | * * *
47 |
48 | ### `Disposable.isDisposable(d)`
49 |
50 | Creates a disposable object that invokes the specified action when disposed.
51 |
52 | #### Arguments
53 | 1. `d`: `Object` - Object to validate whether it has a dispose method.
54 |
55 | #### Returns
56 | `Boolean` - `true` if is a disposable object, else `false`.
57 |
58 | #### Example
59 | ```js
60 | const disposable = Disposable.empty;
61 | console.log(Disposable.isDisposable(disposable));
62 | // => true
63 | ```
64 |
65 | * * *
66 |
67 | ## _Disposable Class Properties_ ##
68 |
69 | ### `Disposable.empty`
70 |
71 | Gets the disposable that does nothing when disposed.
72 |
73 | #### Returns
74 | `Disposable`: The disposable that does nothing when disposed.
75 |
76 | #### Example
77 |
78 | ```js
79 | const disposable = Disposable.empty;
80 |
81 | disposable.dispose(); // Does nothing
82 | ```
83 |
84 | * * *
85 |
86 | ## _Disposable Instance Methods_ ##
87 |
88 | ### `Disposable.prototype.dispose()`
89 |
90 | Performs the task of cleaning up resources.
91 |
92 | #### Example
93 |
94 | ```js
95 | const disposable = Disposable.create(() => console.log('disposed'));
96 |
97 | disposable.dispose();
98 | // => disposed
99 | ```
100 | * * *
101 |
--------------------------------------------------------------------------------
/doc/narydisposable.md:
--------------------------------------------------------------------------------
1 | # `NAryDisposable` class #
2 |
3 | Represents an immutable group of disposable resources that are disposed together.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `NAryDisposable`.
8 |
9 | ```js
10 | const d1 = Disposable.create(() => console.log('one'));
11 | const d2 = Disposable.create(() => console.log('two'));
12 | const d3 = Disposable.create(() => console.log('three'));
13 |
14 | // Initialize with two disposables
15 | const disposables = new NAryDisposable([d1, d2, d3]);
16 |
17 | disposables.dispose();
18 | // => one
19 | // => two
20 | // => three
21 | ```
22 |
23 | ## `NAryDisposable Constructor` ##
24 | - [`constructor`](#narydisposabledisposables)
25 |
26 | ## `NAryDisposable Instance Methods` ##
27 | - [`dispose`](#narydisposableprototypedispose)
28 |
29 | ## `NAryDisposable Instance Properties` ##
30 | - [`isDisposed`](#isdisposed)
31 |
32 | ## _NAryDisposable Constructor_ ##
33 |
34 | ### `NAryDisposable(disposables)`
35 |
36 | Creates a new group of disposable resources that are disposed together.
37 |
38 | #### Arguments
39 | 1. `disposables`: `Array` - Disposables that will be disposed together.
40 |
41 | #### Example
42 | ```js
43 | const d1 = Disposable.create(() => console.log('one'));
44 | const d2 = Disposable.create(() => console.log('two'));
45 | const d3 = Disposable.create(() => console.log('three'));
46 |
47 | // Initialize with two disposables
48 | const disposables = new NAryDisposable([d1, d2, d3]);
49 |
50 | disposables.dispose();
51 | // => one
52 | // => two
53 | // => three
54 | ```
55 |
56 | * * *
57 |
58 | ## _NAryDisposable Instance Methods_ ##
59 |
60 | ### `NAryDisposable.prototype.dispose()`
61 |
62 | Disposes the underlying disposables.
63 |
64 | #### Example
65 |
66 | ```js
67 | const d1 = Disposable.create(() => console.log('one'));
68 | const d2 = Disposable.create(() => console.log('two'));
69 | const d3 = Disposable.create(() => console.log('three'));
70 |
71 | // Initialize with two disposables
72 | const disposables = new NAryDisposable([d1, d2, d3]);
73 |
74 | disposables.dispose();
75 | // => one
76 | // => two
77 | // => three
78 | ```
79 | * * *
80 |
81 | ## _NAryDisposable Instance Properties_ ##
82 |
83 | ### `isDisposed`
84 |
85 | Gets a value that indicates whether the object is disposed.
86 |
87 | #### Example
88 | ```js
89 | const d1 = Disposable.create(() => console.log('one'));
90 | const d2 = Disposable.create(() => console.log('two'));
91 | const d3 = Disposable.create(() => console.log('three'));
92 |
93 | const disposables = new NAryDisposable([d1, d2, d3]);
94 |
95 | console.log(disposables.isDisposed);
96 | // => false
97 |
98 | disposables.dispose();
99 | // => disposed
100 |
101 | console.log(disposables.isDisposed);
102 | // => true
103 | ```
104 |
105 | * * *
106 |
--------------------------------------------------------------------------------
/doc/refcountdisposable.md:
--------------------------------------------------------------------------------
1 | # `RefCountDisposable` class #
2 |
3 | Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `RefCountDisposable`.
8 |
9 | ```js
10 | const d = Disposable.create(() => console.log('disposed'));
11 |
12 | const r = new RefCountDisposable(d);
13 |
14 | const d1 = r.getDisposable();
15 | const d2 = r.getDisposable();
16 |
17 | d1.dispose();
18 | console.log(d.isDisposed);
19 | // => false
20 |
21 | d2.dispose();
22 | console.log(d.isDisposed);
23 | // => false
24 |
25 | r.dispose();
26 | // => disposed
27 | console.log(d.isDisposed);
28 | // => true
29 | ```
30 |
31 | ## `RefCountDisposable` Constructor ##
32 | - [`constructor`](#refcountdisposabledisposable)
33 |
34 | ## `RefCountDisposable` Instance Methods ##
35 | - [`dispose`](#refcountdisposableprototypedispose)
36 | - [`getDisposable`](#refcountdisposableprototypegetdisposable)
37 | - [`setDisposable`](#refcountdisposableprototypesetdisposable)
38 |
39 | ## `RefCountDisposable` Instance Properties ##
40 | - [`isDisposed`](#isdisposed)
41 |
42 | ## _RefCountDisposable Constructor_ ##
43 |
44 | ### `RefCountDisposable(disposable)`
45 |
46 | Initializes a new instance of the `RefCountDisposable` class with the specified disposable.
47 |
48 | #### Example
49 | ```js
50 | const d = Disposable.create(() => console.log('disposed'));
51 |
52 | const r = new RefCountDisposable(d);
53 |
54 | r.dispose();
55 | // => disposed
56 | ```
57 |
58 | * * *
59 |
60 | ## _RefCountDisposable Instance Methods_ ##
61 |
62 | ### `RefCountDisposable.prototype.dispose()`
63 |
64 | Disposes the underlying disposable only when all dependent disposables have been disposed.
65 |
66 | #### Example
67 |
68 | ```js
69 | const d = Disposable.create(() => console.log('disposed'));
70 |
71 | const r = new RefCountDisposable(d);
72 |
73 | const d1 = r.getDisposable();
74 | const d2 = r.getDisposable();
75 |
76 | d1.dispose();
77 | console.log(d.isDisposed);
78 | // => false
79 |
80 | d2.dispose();
81 | console.log(d.isDisposed);
82 | // => false
83 |
84 | // All have been disposed
85 | r.dispose();
86 | // => disposed
87 | console.log(d.isDisposed);
88 | // => true
89 | ```
90 |
91 | * * *
92 |
93 | ### `RefCountDisposable.prototype.getDisposable()`
94 |
95 | Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
96 |
97 | #### Returns
98 | `Disposable` - A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
99 |
100 | #### Example
101 |
102 | ```js
103 | const d = Disposable.create(() => console.log('disposed'));
104 |
105 | const r = new RefCountDisposable(d);
106 |
107 | // Ref count by two
108 | const d1 = r.getDisposable();
109 | const d2 = r.getDisposable();
110 |
111 | // Dispose both
112 | d1.dispose();
113 | d2.dispose();
114 |
115 | r.dispose();
116 | // => disposed
117 | console.log(d.isDisposed);
118 | // => true
119 | ```
120 |
121 | * * *
122 |
123 | ## _RefCountDisposable Instance Properties_ ##
124 |
125 | ### `isDisposed`
126 |
127 | Gets a value that indicates whether the object is disposed.
128 |
129 | #### Example
130 | ```js
131 | const d = Disposable.create(() => console.log('disposed'));
132 |
133 | var r = new RefCountDisposable(d);
134 |
135 | console.log(d.isDisposed);
136 | // => false
137 |
138 | r.dispose();
139 | // => disposed
140 |
141 | console.log(r.isDisposed);
142 | // => true
143 | ```
144 |
145 | * * *
146 |
--------------------------------------------------------------------------------
/doc/serialdisposable.md:
--------------------------------------------------------------------------------
1 | # `SerialDisposable` class #
2 |
3 | Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `SerialDisposable`.
8 |
9 | ```js
10 | const serialDisposable = new SerialDisposable();
11 |
12 | const d1 = Disposable.create(() => console.log('one'));
13 |
14 | serialDisposable.setDisposable(d1);
15 |
16 | const d2 = Disposable.create(() => console.log('two'));
17 |
18 | serialDisposable.setDisposable(d2);
19 | // => one
20 |
21 | serialDisposable.dispose();
22 | // = two
23 | ```
24 |
25 | ## `SerialDisposable` Constructor ##
26 | - [`constructor`](#serialdisposable)
27 |
28 | ## `SerialDisposable` Instance Methods ##
29 | - [`dispose`](#serialdisposableprototypedispose)
30 | - [`getDisposable`](#serialdisposableprototypegetdisposable)
31 | - [`setDisposable`](#serialdisposableprototypesetdisposable)
32 |
33 | ## `SerialDisposable` Instance Properties ##
34 | - [`isDisposed`](#isdisposed)
35 |
36 | ## _SerialDisposable Constructor_ ##
37 |
38 | ### `SerialDisposable()`
39 |
40 | Initializes a new instance of the `SerialDisposable` class.
41 |
42 | #### Example
43 | ```js
44 | const serialDisposable = new SerialDisposable();
45 |
46 | console.log(serialDisposable.isDisposed);
47 | // => false
48 | ```
49 |
50 | * * *
51 |
52 | ## _SerialDisposable Instance Methods_ ##
53 |
54 | ### `SerialDisposable.prototype.dispose()`
55 |
56 | Disposes the underlying disposable as well as all future replacements.
57 |
58 | #### Example
59 |
60 | ```js
61 | const serialDisposable = new SerialDisposable();
62 |
63 | const d1 = Disposable.create(() => console.log('one'));
64 |
65 | serialDisposable.setDisposable(d1);
66 |
67 | serialDisposable.dispose();
68 | // => one
69 | ```
70 |
71 | * * *
72 |
73 | ### `SerialDisposable.prototype.getDisposable()`
74 |
75 | Gets the underlying disposable.
76 |
77 | #### Returns
78 | `Disposable` - The underlying disposable.
79 |
80 | #### Example
81 |
82 | ```js
83 | const serialDisposable = new SerialDisposable();
84 |
85 | const d1 = Disposable.create(() => console.log('one'));
86 |
87 | serialDisposable.setDisposable(d1);
88 |
89 | console.log(serialDisposable.getDisposable() === d1);
90 | // => true
91 | ```
92 |
93 | * * *
94 |
95 | ### `SerialDisposable.prototype.setDisposable(value)`
96 |
97 | Sets the underlying disposable.
98 |
99 | #### Arguments
100 | 1. `value` `Disposable`: The new underlying disposable.
101 |
102 | #### Example
103 |
104 | ```js
105 | const serialDisposable = new SerialDisposable();
106 |
107 | const d1 = Disposable.create(() => console.log('one'));
108 |
109 | serialDisposable.setDisposable(d1);
110 |
111 | serialDisposable.dispose();
112 | // => one
113 |
114 | const d2 = Disposable.create(() => console.log('two'));
115 |
116 | serialDisposable.setDisposable(d2);
117 | // => two
118 | ```
119 |
120 | * * *
121 |
122 | ## _SerialDisposable Instance Properties_ ##
123 |
124 | ### `isDisposed`
125 |
126 | Gets a value that indicates whether the object is disposed.
127 |
128 | #### Example
129 | ```js
130 | const serialDisposable = new SerialDisposable();
131 |
132 | const d1 = Disposable.create(() => console.log('one'));
133 |
134 | serialDisposable.setDisposable(d1);
135 |
136 | console.log(serialDisposable.isDisposed);
137 | // => false
138 |
139 | serialDisposable.dispose();
140 | // => one
141 |
142 | console.log(serialDisposable.isDisposed);
143 | // => true
144 | ```
145 |
146 | * * *
147 |
--------------------------------------------------------------------------------
/doc/singleassignmentdisposable.md:
--------------------------------------------------------------------------------
1 | # `SingleAssignmentDisposable` class #
2 |
3 | Represents a disposable resource which only allows a single assignment of its underlying disposable resource. If an underlying disposable resource has already been set, future attempts to set the underlying disposable resource will throw an Error.
4 |
5 | ## Usage ##
6 |
7 | The follow example shows the basic usage of a `SingleAssignmentDisposable`.
8 |
9 | ```js
10 | const singleDisposable = new SingleAssignmentDisposable();
11 |
12 | const disposable = Disposable.create(() => console.log('disposed'));
13 |
14 | singleDisposable.setDisposable(disposable);
15 |
16 | singleDisposable.dispose();
17 | // => disposed
18 | ```
19 |
20 | ## `SingleAssignmentDisposable Constructor` ##
21 | - [`constructor`](#singleassignmentdisposable)
22 |
23 | ## `SingleAssignmentDisposable Instance Methods` ##
24 | - [`dispose`](#singleassignmentdisposableprototypedispose)
25 | - [`getDisposable`](#singleassignmentdisposableprototypegetdisposable)
26 | - [`setDisposable`](#singleassignmentdisposableprototypesetdisposable)
27 |
28 | ## `SingleAssignmentDisposable Instance Properties` ##
29 | - [`isDisposed`](#isdisposed)
30 |
31 | ## _SingleAssignmentDisposable Constructor_ ##
32 |
33 | ### `SingleAssignmentDisposable()`
34 |
35 | Initializes a new instance of the `SingleAssignmentDisposable` class.
36 |
37 | #### Example
38 | ```js
39 | const singleDisposable = new SingleAssignmentDisposable();
40 |
41 | console.log(singleDisposable.isDisposed);
42 | // => false
43 | ```
44 |
45 | * * *
46 |
47 | ## _SingleAssignmentDisposable Instance Methods_ ##
48 |
49 | ### `SingleAssignmentDisposable.prototype.dispose()`
50 |
51 | Disposes the underlying disposable.
52 |
53 | #### Example
54 |
55 | ```js
56 | const singleDisposable = new SingleAssignmentDisposable();
57 |
58 | const disposable = Disposable.create(() => console.log('disposed'));
59 |
60 | singleDisposable.setDisposable(disposable);
61 |
62 | console.log(singleDisposable.isDisposed);
63 | // => false
64 |
65 | singleDisposable.dispose();
66 | // => disposed
67 |
68 | console.log(singleDisposable.isDisposed);
69 | // => true
70 | ```
71 |
72 | * * *
73 |
74 | ### `SingleAssignmentDisposable.prototype.getDisposable()`
75 |
76 | Gets the underlying disposable. After disposal, the result of getting this method is undefined.
77 |
78 | #### Returns
79 | `Disposable` - The underlying disposable.
80 |
81 | #### Example
82 |
83 | ```js
84 | const singleDisposable = new SingleAssignmentDisposable();
85 |
86 | const disposable = Disposable.create(() => console.log('disposed'));
87 |
88 | singleDisposable.setDisposable(disposable);
89 |
90 | console.log(singleDisposable.getDisposable() === disposable);
91 | ```
92 |
93 | * * *
94 |
95 | ### `SingleAssignmentDisposable.prototype.setDisposable(value)`
96 |
97 | Sets the underlying disposable.
98 |
99 | #### Arguments
100 | 1. `value`: `Disposable`: The new underlying disposable.
101 |
102 | #### Example
103 |
104 | ```js
105 | const singleDisposable = new SingleAssignmentDisposable();
106 |
107 | const d1 = Disposable.create(() => console.log('one'));
108 |
109 | singleDisposable.setDisposable(d1);
110 |
111 | const d2 = Disposable.create(() => console.log('two'));
112 |
113 | try {
114 | singleDisposable.setDisposable(d2);
115 | } catch (e) {
116 | console.log(e.message);
117 | }
118 |
119 | // => Disposable has already been assigned
120 | ```
121 |
122 | * * *
123 |
124 | ## _SingleAssignmentDisposable Instance Properties_ ##
125 |
126 | ### `isDisposed`
127 |
128 | Gets a value that indicates whether the object is disposed.
129 |
130 | #### Example
131 | ```js
132 | const singleDisposable = new SingleAssignmentDisposable();
133 |
134 | const disposable = Disposable.create(() => console.log('disposed'));
135 |
136 | singleDisposable.setDisposable(disposable);
137 |
138 | console.log(singleDisposable.isDisposed);
139 | // => false
140 |
141 | singleDisposable.dispose();
142 | // => disposed
143 |
144 | console.log(singleDisposable.isDisposed);
145 | // => true
146 | ```
147 |
148 | * * *
149 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = {
4 | BinaryDisposable: require('./binarydisposable'),
5 | CompositeDisposable: require('./compositedisposable'),
6 | Disposable: require('./disposable'),
7 | NAryDisposable: require('./narydisposable'),
8 | RefCountDisposable: require('./refcountdisposable'),
9 | SerialDisposable: require('./serialdisposable'),
10 | SingleAssignmentDisposable: require('./singleassignmentdisposable')
11 | };
12 |
--------------------------------------------------------------------------------
/narydisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * Represents a group of disposable resources that are disposed together.
5 | * @constructor
6 | * Creates a new group of disposable resources that are disposed together.
7 | * @param [Any] disposables Disposable resources to add to the group.
8 | */
9 | function NAryDisposable(disposables) {
10 | this._disposables = disposables;
11 | this.isDisposed = false;
12 | }
13 |
14 | /**
15 | * Disposes all disposables in the group.
16 | */
17 | NAryDisposable.prototype.dispose = function () {
18 | if (!this.isDisposed) {
19 | this.isDisposed = true;
20 | for (var i = 0, len = this._disposables.length; i < len; i++) {
21 | this._disposables[i].dispose();
22 | }
23 | this._disposables.length = 0;
24 | }
25 | };
26 |
27 | module.exports = NAryDisposable;
28 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "rx.disposables",
3 | "version": "1.0.0",
4 | "description": "Library for Disposables which can be used independently from RxJS",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "tape test/**/*.js | tap-spec && markdown-doctest"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/Reactive-Extensions/rx.disposables.git"
12 | },
13 | "keywords": [
14 | "Rx",
15 | "RxJS",
16 | "Disposables"
17 | ],
18 | "author": "Microsoft Corporation",
19 | "license": "MIT",
20 | "bugs": {
21 | "url": "https://github.com/Reactive-Extensions/rx.disposables/issues"
22 | },
23 | "homepage": "https://github.com/Reactive-Extensions/rx.disposables#readme",
24 | "devDependencies": {
25 | "markdown-doctest": "^0.3.0",
26 | "tap-spec": "^4.1.1",
27 | "tape": "^4.4.0"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/refcountdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var Disposable = require('./disposable');
4 |
5 | function InnerDisposable(disposable) {
6 | this._disposable = disposable;
7 | }
8 |
9 | InnerDisposable.prototype.dispose = function () {
10 | var temp = this._disposable;
11 | this._disposable = null;
12 | temp && temp._release();
13 | };
14 |
15 | /**
16 | * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed.
17 | */
18 | function RefCountDisposable(disposable) {
19 | this._disposable = disposable;
20 | this.isDisposed = false;
21 | this._isPrimaryDisposed = false;
22 | this._count = 0;
23 | }
24 |
25 | /**
26 | * Disposes the underlying disposable only when all dependent disposables have been disposed
27 | */
28 | RefCountDisposable.prototype.dispose = function () {
29 | if (!this.isDisposed && !this._isPrimaryDisposed) {
30 | this._isPrimaryDisposed = true;
31 | if (this._count === 0) {
32 | this.isDisposed = true;
33 | this._disposable.dispose();
34 | this._disposable = null;
35 | this.isDisposed = true;
36 | }
37 | }
38 | };
39 |
40 | RefCountDisposable.prototype._release = function () {
41 | if (this._disposable) {
42 | this._count--;
43 | if (this._isPrimaryDisposed && this._count === 0) {
44 | this._disposable.dispose();
45 | this._disposable = null;
46 | this.isDisposed = true;
47 | }
48 | }
49 | };
50 |
51 | /**
52 | * Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable.
53 | * @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime.
54 | */
55 | RefCountDisposable.prototype.getDisposable = function () {
56 | if (this.isDisposed) {
57 | return Disposable.empty;
58 | } else {
59 | this._count++;
60 | return new InnerDisposable(this);
61 | }
62 | };
63 |
64 | module.exports = RefCountDisposable;
65 |
--------------------------------------------------------------------------------
/serialdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @constructor
5 | * Represents a disposable resource whose underlying disposable resource can
6 | * be replaced by another disposable resource, causing automatic disposal of
7 | * the previous underlying disposable resource.
8 | */
9 | function SerialDisposable() {
10 | this.isDisposed = false;
11 | this._current = null;
12 | }
13 |
14 | /**
15 | * Gets the underlying disposable.
16 | * @returns {Any} the underlying disposable.
17 | */
18 | SerialDisposable.prototype.getDisposable = function () {
19 | return this._current;
20 | };
21 |
22 | SerialDisposable.prototype.setDisposable = function (value) {
23 | var shouldDispose = this.isDisposed;
24 | if (!shouldDispose) {
25 | var old = this._current;
26 | this._current = value;
27 | old && old.dispose();
28 | }
29 |
30 | shouldDispose && value && value.dispose();
31 | };
32 |
33 | /** Performs the task of cleaning up resources. */
34 | SerialDisposable.prototype.dispose = function () {
35 | if (!this.isDisposed) {
36 | this.isDisposed = true;
37 | var old = this._current;
38 | this._current = null;
39 | old && old.dispose();
40 | }
41 | };
42 |
43 | module.exports = SerialDisposable;
44 |
--------------------------------------------------------------------------------
/singleassignmentdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | /**
4 | * @constructor
5 | * Represents a disposable resource which only allows a single assignment of
6 | * its underlying disposable resource. If an underlying disposable resource has
7 | * already been set, future attempts to set the underlying disposable resource
8 | * will throw an Error.
9 | */
10 | function SingleAssignmentDisposable () {
11 | this.isDisposed = false;
12 | this._current = null;
13 | }
14 |
15 | /**
16 | * Gets the underlying disposable. After disposal, the result of getting
17 | * this method is null.
18 | * @returns {Any} the underlying disposable.
19 | */
20 | SingleAssignmentDisposable.prototype.getDisposable = function () {
21 | return this._current;
22 | };
23 |
24 | /**
25 | * Sets the underlying disposable. Throws an error if the
26 | * SingleAssignmentDisposable has already been assigned to.
27 | * @param {Any} value the underlying disposable to set.
28 | */
29 | SingleAssignmentDisposable.prototype.setDisposable = function (value) {
30 | if (this._current) { throw new Error('Disposable has already been assigned'); }
31 | var shouldDispose = this.isDisposed;
32 | !shouldDispose && (this._current = value);
33 | shouldDispose && value && value.dispose();
34 | };
35 |
36 | /** Performs the task of cleaning up resources. */
37 | SingleAssignmentDisposable.prototype.dispose = function () {
38 | if (!this.isDisposed) {
39 | this.isDisposed = true;
40 | var old = this._current;
41 | this._current = null;
42 | old && old.dispose();
43 | }
44 | };
45 |
46 | module.exports = SingleAssignmentDisposable;
47 |
--------------------------------------------------------------------------------
/test/binarydisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var Disposable = require('../disposable');
5 | var BinaryDisposable = require('../binarydisposable');
6 |
7 | test('BinaryDisposable#constructor', function (t) {
8 | var disp1 = false;
9 | var disp2 = false;
10 |
11 | var d1 = Disposable.create(function () { disp1 = true; });
12 | var d2 = Disposable.create(function () { disp2 = true; });
13 |
14 | var b = new BinaryDisposable(d1, d2);
15 |
16 | t.equal(b.isDisposed, false, 'should not be disposed');
17 | t.equal(disp1, false, 'first should not be disposed');
18 | t.equal(disp2, false, 'second should not be disposed');
19 |
20 | t.end();
21 | });
22 |
23 | test('BinaryDisposable#dispose', function (t) {
24 | var disp1 = false;
25 | var disp2 = false;
26 |
27 | var d1 = Disposable.create(function () { disp1 = true; });
28 | var d2 = Disposable.create(function () { disp2 = true; });
29 |
30 | var b = new BinaryDisposable(d1, d2);
31 |
32 | t.equal(b.isDisposed, false, 'should not be disposed');
33 | t.equal(disp1, false, 'first should not be disposed');
34 | t.equal(disp2, false, 'second should not be disposed');
35 |
36 | b.dispose();
37 |
38 | t.equal(b.isDisposed, true, 'should be disposed');
39 | t.equal(disp1, true, 'first should be disposed');
40 | t.equal(disp2, true, 'second should be disposed');
41 |
42 | b.dispose();
43 |
44 | t.equal(b.isDisposed, true, 'should be idempotent');
45 | t.equal(disp1, true, 'first should be idempotent');
46 | t.equal(disp2, true, 'second should be idempotent');
47 |
48 | t.end();
49 | });
50 |
--------------------------------------------------------------------------------
/test/disposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var Disposable = require('../disposable');
5 |
6 | test('Disposable#create', function (t) {
7 | var disposable = Disposable.create(function () { });
8 | t.ok(disposable, 'disposable should not be undefined');
9 | t.end();
10 | });
11 |
12 | test('Disposable#dispose', function (t) {
13 | var disposed = false;
14 | var d = Disposable.create(function () { disposed = true; });
15 |
16 | t.ok(!disposed, 'should not be disposed');
17 | d.dispose();
18 | t.ok(disposed, 'should be disposed');
19 | t.end();
20 | });
21 |
22 | test('Disposable#empty', function (t) {
23 | var d = Disposable.empty;
24 | t.ok(d, 'should not be null');
25 | d.dispose();
26 | t.end();
27 | });
28 |
--------------------------------------------------------------------------------
/test/narydisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var Disposable = require('../disposable');
5 | var NAryDisposable = require('../narydisposable');
6 |
7 | test('NAryDisposable#constructor', function (t) {
8 | var disp1 = false;
9 | var disp2 = false;
10 | var disp3 = false;
11 |
12 | var d1 = Disposable.create(function () { disp1 = true; });
13 | var d2 = Disposable.create(function () { disp2 = true; });
14 | var d3 = Disposable.create(function () { disp3 = true; });
15 |
16 | var b = new NAryDisposable([d1, d2, d3]);
17 |
18 | t.equal(b.isDisposed, false, 'should not be disposed');
19 | t.equal(disp1, false, 'first should not be disposed');
20 | t.equal(disp2, false, 'second should not be disposed');
21 | t.equal(disp3, false, 'third should not be disposed');
22 |
23 | t.end();
24 | });
25 |
26 | test('NAryDisposable#dispose', function (t) {
27 | var disp1 = false;
28 | var disp2 = false;
29 | var disp3 = false;
30 |
31 | var d1 = Disposable.create(function () { disp1 = true; });
32 | var d2 = Disposable.create(function () { disp2 = true; });
33 | var d3 = Disposable.create(function () { disp3 = true; });
34 |
35 | var b = new NAryDisposable([d1, d2, d3]);
36 |
37 | t.equal(b.isDisposed, false, 'should not be disposed');
38 | t.equal(disp1, false, 'first should not be disposed');
39 | t.equal(disp2, false, 'second should not be disposed');
40 | t.equal(disp1, false, 'third should not be disposed');
41 |
42 | b.dispose();
43 |
44 | t.equal(b.isDisposed, true, 'should be disposed');
45 | t.equal(disp1, true, 'first should be disposed');
46 | t.equal(disp2, true, 'second should be disposed');
47 | t.equal(disp2, true, 'third should be disposed');
48 |
49 | b.dispose();
50 |
51 | t.equal(b.isDisposed, true, 'should be idempotent');
52 | t.equal(disp1, true, 'first should be idempotent');
53 | t.equal(disp2, true, 'second should be idempotent');
54 | t.equal(disp2, true, 'third should be idempotent');
55 |
56 | t.end();
57 | });
58 |
--------------------------------------------------------------------------------
/test/refcountdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var RefCountDisposable = require('../refcountdisposable');
5 |
6 | function BooleanDisposable() {
7 | this.isDisposed = false;
8 | }
9 |
10 | BooleanDisposable.prototype.dispose = function () {
11 | !this.isDisposed && (this.isDisposed = true);
12 | };
13 |
14 | test('RefCountDisposable single reference', function (t) {
15 | var d = new BooleanDisposable();
16 | var r = new RefCountDisposable(d);
17 | t.notOk(d.isDisposed, 'should not be disposed');
18 | r.dispose();
19 | t.ok(d.isDisposed, 'should be disposed');
20 | r.dispose();
21 | t.ok(d.isDisposed, 'should still be disposed');
22 |
23 | t.end();
24 | });
25 |
26 | test('RefCountDisposable ref counting', function (t) {
27 | var d = new BooleanDisposable();
28 | var r = new RefCountDisposable(d);
29 | t.notOk(d.isDisposed, 'should not be disposed');
30 |
31 | var d1 = r.getDisposable();
32 | var d2 = r.getDisposable();
33 | t.notOk(d.isDisposed, 'after two getDisposable() calls should not be disposed');
34 |
35 | d1.dispose();
36 | t.notOk(d.isDisposed, 'after one dispose() should not be disposed');
37 |
38 | d2.dispose();
39 | t.notOk(d.isDisposed, 'after two dispose() should be disposed');
40 |
41 | r.dispose();
42 | t.ok(d.isDisposed, 'the outer should be disposed');
43 | t.ok(r.isDisposed, 'the ref counted should be disposed');
44 |
45 | var d3 = r.getDisposable(); // CHECK
46 | d3.dispose();
47 |
48 | t.end();
49 | });
50 |
51 | test('RefCountDisposable primary disposes first', function (t) {
52 | var d = new BooleanDisposable();
53 | var r = new RefCountDisposable(d);
54 | t.notOk(d.isDisposed, 'should not be disposed after creation');
55 |
56 | var d1 = r.getDisposable();
57 | var d2 = r.getDisposable();
58 | t.notOk(d.isDisposed, 'should not be disposed after two getDisposable() calls');
59 |
60 | d1.dispose();
61 | t.notOk(d.isDisposed, 'should not be disposed after one dispose() call');
62 |
63 | r.dispose();
64 | t.notOk(d.isDisposed, 'should not dispose outer if inner has refs');
65 |
66 | d2.dispose();
67 | t.ok(d.isDisposed, 'should dispose outer if dispose() called twice');
68 |
69 | t.end();
70 | });
71 |
--------------------------------------------------------------------------------
/test/serialdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var SerialDisposable = require('../serialdisposable');
5 | var Disposable = require('../disposable');
6 |
7 |
8 | test('SerialDisposable#constructor', function (t) {
9 | var m = new SerialDisposable();
10 |
11 | t.ok(!m.getDisposable(), 'should not have a disposable');
12 |
13 | t.end();
14 | });
15 |
16 | test('SerialDisposable replace before dispose()', function (t) {
17 | var disp1 = false;
18 | var disp2 = false;
19 |
20 | var m = new SerialDisposable();
21 |
22 | var d1 = Disposable.create(function () { disp1 = true; });
23 | m.setDisposable(d1);
24 |
25 | t.equal(d1, m.getDisposable(), 'should have a disposable set');
26 | t.ok(!disp1, 'should not be disposed');
27 |
28 | var d2 = Disposable.create(function () { disp2 = true; });
29 | m.setDisposable(d2);
30 |
31 | t.equal(d2, m.getDisposable(), 'should have a new disposable set');
32 | t.ok(disp1, 'first should be disposed');
33 | t.ok(!disp2, 'next should not be disposed');
34 |
35 | t.end();
36 | });
37 |
38 | test('SerialDisposable replace after dispose', function (t) {
39 | var disp1 = false;
40 | var disp2 = false;
41 |
42 | var m = new SerialDisposable();
43 | m.dispose();
44 |
45 | var d1 = Disposable.create(function () { disp1 = true; });
46 | m.setDisposable(d1);
47 |
48 | t.equal(null, m.getDisposable(), 'should not have a set disposable after dispose');
49 | t.ok(disp1, 'should be disposed');
50 |
51 | var d2 = Disposable.create(function () { disp2 = true; });
52 | m.setDisposable(d2);
53 |
54 | t.equal(null, m.getDisposable(), 'should not have a set disposable after dispose');
55 | t.ok(disp2, 'should be disposed');
56 |
57 | t.end();
58 | });
59 |
60 | test('SerialDisposable#dispose', function (t) {
61 | var disp = false;
62 |
63 | var m = new SerialDisposable();
64 | var d = Disposable.create(function () { disp = true; });
65 | m.setDisposable(d);
66 |
67 | t.equal(d, m.getDisposable(), 'should have set the disposable');
68 | t.ok(!disp, 'should not be disposed before dispose()');
69 |
70 | m.dispose();
71 |
72 | t.ok(disp, 'should be disposed after dispose()');
73 | t.equal(null, m.getDisposable(), 'should clear the current disposable');
74 |
75 | t.end();
76 | });
77 |
--------------------------------------------------------------------------------
/test/singleassignmentdisposable.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var test = require('tape');
4 | var SingleAssignmentDisposable = require('../singleassignmentdisposable');
5 | var Disposable = require('../disposable');
6 |
7 | test('SingleAssignmentDisposable setDisposable null', function (t) {
8 | var d = new SingleAssignmentDisposable();
9 |
10 | d.setDisposable(null);
11 |
12 | t.equal(null, d.getDisposable(), 'getDisposable should return null');
13 |
14 | t.end();
15 | });
16 |
17 | test('SingleAssignmentDisposable dispose after set', function (t) {
18 | var disposed = false,
19 | d = new SingleAssignmentDisposable(),
20 | dd = Disposable.create(function () { disposed = true; });
21 |
22 | d.setDisposable(dd);
23 | t.equal(dd, d.getDisposable(), 'should have set the disposable via setDisposable');
24 | t.ok(!disposed, 'should not be disposed');
25 |
26 | d.dispose();
27 | t.ok(disposed, 'should be disposed after dispose()');
28 |
29 | d.dispose();
30 | t.ok(disposed, 'should be idempotent after dispose()');
31 |
32 | t.end();
33 | });
34 |
35 | test('SingleAssignmentDisposable dispose before setDisposable', function (t) {
36 | var disposed = false,
37 | d = new SingleAssignmentDisposable(),
38 | dd = Disposable.create(function () { disposed = true; });
39 | t.ok(!disposed, 'should not be disposed');
40 |
41 | d.dispose();
42 | t.ok(!disposed, 'should not be disposed after disposed');
43 |
44 | d.setDisposable(dd);
45 | t.ok(d.getDisposable() == null, 'should not set disposable');
46 | t.ok(disposed, 'should be disposed after setDisposable');
47 |
48 | d.dispose();
49 | t.ok(disposed, 'calling dispose should dispose idempotent');
50 |
51 | t.end();
52 | });
53 |
--------------------------------------------------------------------------------