UNPKG

8.27 kBTypeScriptView Raw
1declare module '@ember/destroyable' {
2 export {
3 assertDestroyablesDestroyed,
4 associateDestroyableChild,
5 destroy,
6 enableDestroyableTracking,
7 isDestroying,
8 isDestroyed,
9 } from '@glimmer/destroyable';
10 /**
11 Ember manages the lifecycles and lifetimes of many built in constructs, such
12 as components, and does so in a hierarchical way - when a parent component is
13 destroyed, all of its children are destroyed as well.
14
15 This destroyables API exposes the basic building blocks for destruction:
16
17 * registering a function to be ran when an object is destroyed
18 * checking if an object is in a destroying state
19 * associate an object as a child of another so that the child object will be destroyed
20 when the associated parent object is destroyed.
21
22 @module @ember/destroyable
23 @public
24 */
25 /**
26 This function is used to associate a destroyable object with a parent. When the parent
27 is destroyed, all registered children will also be destroyed.
28
29 ```js
30 class CustomSelect extends Component {
31 constructor(...args) {
32 super(...args);
33
34 // obj is now a child of the component. When the component is destroyed,
35 // obj will also be destroyed, and have all of its destructors triggered.
36 this.obj = associateDestroyableChild(this, {});
37 }
38 }
39 ```
40
41 Returns the associated child for convenience.
42
43 @method associateDestroyableChild
44 @for @ember/destroyable
45 @param {Object|Function} parent the destroyable to entangle the child destroyables lifetime with
46 @param {Object|Function} child the destroyable to be entangled with the parents lifetime
47 @returns {Object|Function} the child argument
48 @static
49 @public
50 */
51 /**
52 Receives a destroyable, and returns true if the destroyable has begun destroying. Otherwise returns
53 false.
54
55 ```js
56 let obj = {};
57 isDestroying(obj); // false
58 destroy(obj);
59 isDestroying(obj); // true
60 // ...sometime later, after scheduled destruction
61 isDestroyed(obj); // true
62 isDestroying(obj); // true
63 ```
64
65 @method isDestroying
66 @for @ember/destroyable
67 @param {Object|Function} destroyable the object to check
68 @returns {Boolean}
69 @static
70 @public
71 */
72 /**
73 Receives a destroyable, and returns true if the destroyable has finished destroying. Otherwise
74 returns false.
75
76 ```js
77 let obj = {};
78
79 isDestroyed(obj); // false
80 destroy(obj);
81
82 // ...sometime later, after scheduled destruction
83
84 isDestroyed(obj); // true
85 ```
86
87 @method isDestroyed
88 @for @ember/destroyable
89 @param {Object|Function} destroyable the object to check
90 @returns {Boolean}
91 @static
92 @public
93 */
94 /**
95 Initiates the destruction of a destroyable object. It runs all associated destructors, and then
96 destroys all children recursively.
97
98 ```js
99 let obj = {};
100
101 registerDestructor(obj, () => console.log('destroyed!'));
102
103 destroy(obj); // this will schedule the destructor to be called
104
105 // ...some time later, during scheduled destruction
106
107 // destroyed!
108 ```
109
110 Destruction via `destroy()` follows these steps:
111
112 1, Mark the destroyable such that `isDestroying(destroyable)` returns `true`
113 2, Call `destroy()` on each of the destroyable's associated children
114 3, Schedule calling the destroyable's destructors
115 4, Schedule setting destroyable such that `isDestroyed(destroyable)` returns `true`
116
117 This results in the entire tree of destroyables being first marked as destroying,
118 then having all of their destructors called, and finally all being marked as isDestroyed.
119 There won't be any in between states where some items are marked as `isDestroying` while
120 destroying, while others are not.
121
122 @method destroy
123 @for @ember/destroyable
124 @param {Object|Function} destroyable the object to destroy
125 @static
126 @public
127 */
128 /**
129 This function asserts that all objects which have associated destructors or associated children
130 have been destroyed at the time it is called. It is meant to be a low level hook that testing
131 frameworks can use to hook into and validate that all destroyables have in fact been destroyed.
132
133 This function requires that `enableDestroyableTracking` was called previously, and is only
134 available in non-production builds.
135
136 @method assertDestroyablesDestroyed
137 @for @ember/destroyable
138 @static
139 @public
140 */
141 /**
142 This function instructs the destroyable system to keep track of all destroyables (their
143 children, destructors, etc). This enables a future usage of `assertDestroyablesDestroyed`
144 to be used to ensure that all destroyable tasks (registered destructors and associated children)
145 have completed when `assertDestroyablesDestroyed` is called.
146
147 @method enableDestroyableTracking
148 @for @ember/destroyable
149 @static
150 @public
151 */
152 /**
153 Receives a destroyable object and a destructor function, and associates the
154 function with it. When the destroyable is destroyed with destroy, or when its
155 parent is destroyed, the destructor function will be called.
156
157 ```js
158 import Component from '@glimmer/component';
159 import { registerDestructor } from '@ember/destroyable';
160
161 class Modal extends Component {
162 @service resize;
163
164 constructor(...args) {
165 super(...args);
166
167 this.resize.register(this, this.layout);
168
169 registerDestructor(this, () => this.resize.unregister(this));
170 }
171 }
172 ```
173
174 Multiple destructors can be associated with a given destroyable, and they can be
175 associated over time, allowing libraries to dynamically add destructors as needed.
176 `registerDestructor` also returns the associated destructor function, for convenience.
177
178 The destructor function is passed a single argument, which is the destroyable itself.
179 This allows the function to be reused multiple times for many destroyables, rather
180 than creating a closure function per destroyable.
181
182 ```js
183 import Component from '@glimmer/component';
184 import { registerDestructor } from '@ember/destroyable';
185
186 function unregisterResize(instance) {
187 instance.resize.unregister(instance);
188 }
189
190 class Modal extends Component {
191 @service resize;
192
193 constructor(...args) {
194 super(...args);
195
196 this.resize.register(this, this.layout);
197
198 registerDestructor(this, unregisterResize);
199 }
200 }
201 ```
202
203 @method registerDestructor
204 @for @ember/destroyable
205 @param {Object|Function} destroyable the destroyable to register the destructor function with
206 @param {Function} destructor the destructor to run when the destroyable object is destroyed
207 @static
208 @public
209 */
210 export function registerDestructor<T extends object>(
211 destroyable: T,
212 destructor: (destroyable: T) => void
213 ): (destroyable: T) => void;
214 /**
215 Receives a destroyable and a destructor function, and de-associates the destructor
216 from the destroyable.
217
218 ```js
219 import Component from '@glimmer/component';
220 import { registerDestructor, unregisterDestructor } from '@ember/destroyable';
221
222 class Modal extends Component {
223 @service modals;
224
225 constructor(...args) {
226 super(...args);
227
228 this.modals.add(this);
229
230 this.modalDestructor = registerDestructor(this, () => this.modals.remove(this));
231 }
232
233 @action pinModal() {
234 unregisterDestructor(this, this.modalDestructor);
235 }
236 }
237 ```
238
239 @method unregisterDestructor
240 @for @ember/destroyable
241 @param {Object|Function} destroyable the destroyable to unregister the destructor function from
242 @param {Function} destructor the destructor to remove from the destroyable
243 @static
244 @public
245 */
246 export function unregisterDestructor<T extends object>(
247 destroyable: T,
248 destructor: (destroyable: T) => void
249 ): void;
250}