0
# Lumino Disposable
1
2
Lumino Disposable provides a comprehensive implementation of the disposable pattern for TypeScript/JavaScript applications, enabling proper resource management and cleanup in object-oriented code. It offers core interfaces and concrete implementations that allow developers to create objects that can be properly disposed of when no longer needed, with support for observable disposal events through the Lumino signaling system.
3
4
## Package Information
5
6
- **Package Name**: @lumino/disposable
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install @lumino/disposable`
10
11
## Core Imports
12
13
```typescript
14
import {
15
IDisposable,
16
IObservableDisposable,
17
DisposableDelegate,
18
ObservableDisposableDelegate,
19
DisposableSet,
20
ObservableDisposableSet
21
} from "@lumino/disposable";
22
```
23
24
For CommonJS:
25
26
```javascript
27
const {
28
IDisposable,
29
IObservableDisposable,
30
DisposableDelegate,
31
ObservableDisposableDelegate,
32
DisposableSet,
33
ObservableDisposableSet
34
} = require("@lumino/disposable");
35
```
36
37
## Basic Usage
38
39
```typescript
40
import {
41
DisposableDelegate,
42
DisposableSet,
43
ObservableDisposableDelegate
44
} from "@lumino/disposable";
45
46
// Create a simple disposable with a callback
47
const resource = new DisposableDelegate(() => {
48
console.log("Resource cleaned up!");
49
});
50
51
// Create an observable disposable that signals when disposed
52
const observableResource = new ObservableDisposableDelegate(() => {
53
console.log("Observable resource cleaned up!");
54
});
55
56
// Listen for disposal events
57
observableResource.disposed.connect(() => {
58
console.log("Disposal event received!");
59
});
60
61
// Manage multiple disposables as a collection
62
const disposables = new DisposableSet();
63
disposables.add(resource);
64
disposables.add(observableResource);
65
66
// Dispose all resources at once (in order they were added)
67
disposables.dispose();
68
```
69
70
## Architecture
71
72
Lumino Disposable is built around the disposable pattern with several key components:
73
74
- **Core Interfaces**: `IDisposable` and `IObservableDisposable` define the basic disposable contract
75
- **Delegate Pattern**: `DisposableDelegate` and `ObservableDisposableDelegate` wrap callback functions as disposable objects
76
- **Collection Management**: `DisposableSet` and `ObservableDisposableSet` manage multiple disposables with ordered disposal
77
- **Observable Events**: Observable variants emit signals when disposed, integrating with the Lumino signaling system
78
- **Safe Disposal**: All dispose methods are safe to call multiple times and maintain proper cleanup order
79
80
## Capabilities
81
82
### Core Interfaces
83
84
Basic interfaces defining the disposable pattern contract.
85
86
```typescript { .api }
87
/**
88
* An object which implements the disposable pattern.
89
*/
90
interface IDisposable {
91
/**
92
* Test whether the object has been disposed.
93
* This property is always safe to access.
94
*/
95
readonly isDisposed: boolean;
96
97
/**
98
* Dispose of the resources held by the object.
99
* If called more than once, subsequent calls are no-ops.
100
* It is undefined behavior to use the object after disposal.
101
*/
102
dispose(): void;
103
}
104
105
/**
106
* A disposable object with an observable disposed signal.
107
*/
108
interface IObservableDisposable extends IDisposable {
109
/**
110
* A signal emitted when the object is disposed.
111
*/
112
readonly disposed: ISignal<this, void>;
113
}
114
```
115
116
### Disposable Delegate
117
118
Wraps a callback function as a disposable object, allowing functional cleanup code to participate in the disposable pattern.
119
120
```typescript { .api }
121
/**
122
* A disposable object which delegates to a callback function.
123
*/
124
class DisposableDelegate implements IDisposable {
125
/**
126
* Construct a new disposable delegate.
127
* @param fn - The callback function to invoke on dispose
128
*/
129
constructor(fn: () => void);
130
131
/**
132
* Test whether the delegate has been disposed.
133
*/
134
readonly isDisposed: boolean;
135
136
/**
137
* Dispose of the delegate and invoke the callback function.
138
* Safe to call multiple times.
139
*/
140
dispose(): void;
141
}
142
```
143
144
**Usage Examples:**
145
146
```typescript
147
import { DisposableDelegate } from "@lumino/disposable";
148
149
// Clean up event listeners
150
const disposable = new DisposableDelegate(() => {
151
element.removeEventListener('click', handler);
152
});
153
154
// Clean up timers
155
const timer = new DisposableDelegate(() => {
156
clearInterval(intervalId);
157
});
158
159
// Clean up resources
160
const resource = new DisposableDelegate(() => {
161
connection.close();
162
fileHandle.close();
163
});
164
165
// Dispose when done
166
resource.dispose(); // Callback is invoked
167
resource.dispose(); // Safe no-op
168
```
169
170
### Observable Disposable Delegate
171
172
Observable version of DisposableDelegate that emits a signal when disposed, enabling reactive cleanup patterns.
173
174
```typescript { .api }
175
/**
176
* An observable disposable object which delegates to a callback function.
177
*/
178
class ObservableDisposableDelegate extends DisposableDelegate implements IObservableDisposable {
179
/**
180
* A signal emitted when the delegate is disposed.
181
*/
182
readonly disposed: ISignal<this, void>;
183
184
/**
185
* Dispose of the delegate, invoke the callback, and emit the disposed signal.
186
* Safe to call multiple times.
187
*/
188
dispose(): void;
189
}
190
```
191
192
**Usage Examples:**
193
194
```typescript
195
import { ObservableDisposableDelegate } from "@lumino/disposable";
196
197
const resource = new ObservableDisposableDelegate(() => {
198
console.log("Resource cleaned up");
199
});
200
201
// React to disposal
202
resource.disposed.connect(() => {
203
console.log("Disposal event received");
204
updateUI();
205
});
206
207
resource.dispose();
208
// Output: "Resource cleaned up"
209
// Output: "Disposal event received"
210
```
211
212
### Disposable Set
213
214
Manages a collection of disposable items, disposing them in insertion order when the set itself is disposed.
215
216
```typescript { .api }
217
/**
218
* An object which manages a collection of disposable items.
219
*/
220
class DisposableSet implements IDisposable {
221
/**
222
* Test whether the set has been disposed.
223
*/
224
readonly isDisposed: boolean;
225
226
/**
227
* Dispose of the set and all items it contains.
228
* Items are disposed in the order they were added.
229
* Safe to call multiple times.
230
*/
231
dispose(): void;
232
233
/**
234
* Test whether the set contains a specific item.
235
* @param item - The item of interest
236
* @returns true if the set contains the item, false otherwise
237
*/
238
contains(item: IDisposable): boolean;
239
240
/**
241
* Add a disposable item to the set.
242
* If the item is already in the set, this is a no-op.
243
* @param item - The item to add to the set
244
*/
245
add(item: IDisposable): void;
246
247
/**
248
* Remove a disposable item from the set without disposing it.
249
* If the item is not in the set, this is a no-op.
250
* @param item - The item to remove from the set
251
*/
252
remove(item: IDisposable): void;
253
254
/**
255
* Remove all items from the set without disposing them.
256
*/
257
clear(): void;
258
}
259
```
260
261
**Usage Examples:**
262
263
```typescript
264
import { DisposableSet, DisposableDelegate } from "@lumino/disposable";
265
266
const disposables = new DisposableSet();
267
268
// Add individual disposables
269
disposables.add(new DisposableDelegate(() => cleanup1()));
270
disposables.add(new DisposableDelegate(() => cleanup2()));
271
272
// Check contents
273
const item = new DisposableDelegate(() => cleanup3());
274
disposables.add(item);
275
console.log(disposables.contains(item)); // true
276
277
// Remove without disposing
278
disposables.remove(item);
279
console.log(disposables.contains(item)); // false
280
281
// Dispose all remaining items in order
282
disposables.dispose();
283
```
284
285
### Observable Disposable Set
286
287
Observable version of DisposableSet that emits a signal when the set is disposed.
288
289
```typescript { .api }
290
/**
291
* An observable object which manages a collection of disposable items.
292
*/
293
class ObservableDisposableSet extends DisposableSet implements IObservableDisposable {
294
/**
295
* A signal emitted when the set is disposed.
296
*/
297
readonly disposed: ISignal<this, void>;
298
299
/**
300
* Dispose of the set, all contained items, and emit the disposed signal.
301
* Items are disposed in insertion order.
302
* Safe to call multiple times.
303
*/
304
dispose(): void;
305
}
306
```
307
308
### Static Factory Methods
309
310
Factory methods for creating disposable sets from iterables.
311
312
```typescript { .api }
313
namespace DisposableSet {
314
/**
315
* Create a disposable set from an iterable of items.
316
* @param items - The iterable object of interest
317
* @returns A new disposable set initialized with the given items
318
*/
319
function from(items: Iterable<IDisposable>): DisposableSet;
320
}
321
322
namespace ObservableDisposableSet {
323
/**
324
* Create an observable disposable set from an iterable of items.
325
* @param items - The iterable object of interest
326
* @returns A new observable disposable set initialized with the given items
327
*/
328
function from(items: Iterable<IDisposable>): ObservableDisposableSet;
329
}
330
```
331
332
**Usage Examples:**
333
334
```typescript
335
import { DisposableSet, ObservableDisposableSet } from "@lumino/disposable";
336
337
// Create from array
338
const items = [
339
new DisposableDelegate(() => cleanup1()),
340
new DisposableDelegate(() => cleanup2()),
341
new DisposableDelegate(() => cleanup3())
342
];
343
344
const set1 = DisposableSet.from(items);
345
const set2 = ObservableDisposableSet.from(items);
346
347
// Listen for disposal on observable set
348
set2.disposed.connect(() => {
349
console.log("All items disposed");
350
});
351
352
set2.dispose(); // Disposes all items in order and emits signal
353
```
354
355
## Types
356
357
```typescript { .api }
358
// Re-exported from @lumino/signaling
359
interface ISignal<T, U> {
360
connect(slot: (sender: T, args: U) => void, thisArg?: any): void;
361
disconnect(slot: (sender: T, args: U) => void, thisArg?: any): void;
362
emit(args: U): void;
363
}
364
```
365
366
## Error Handling
367
368
The package follows a fail-safe approach:
369
370
- All `dispose()` methods are safe to call multiple times - subsequent calls are no-ops
371
- Adding duplicate items to sets is a no-op
372
- Removing non-existent items from sets is a no-op
373
- Using objects after disposal results in undefined behavior (as documented)
374
- Observable disposal events are emitted synchronously during the `dispose()` call