UNPKG

12.8 kBTypeScriptView Raw
1declare module '@ember/engine' {
2 export { getEngineParent, setEngineParent } from '@ember/engine/parent';
3 import Namespace from '@ember/application/namespace';
4 import { Registry } from '@ember/-internals/container';
5 import type { ResolverClass } from '@ember/-internals/container';
6 import type { EngineInstanceOptions } from '@ember/engine/instance';
7 import EngineInstance from '@ember/engine/instance';
8 import { RegistryProxyMixin } from '@ember/-internals/runtime';
9 export interface Initializer<T> {
10 name: string;
11 initialize: (target: T) => void;
12 before?: string | string[];
13 after?: string | string[];
14 }
15 /**
16 @module @ember/engine
17 */
18 /**
19 The `Engine` class contains core functionality for both applications and
20 engines.
21
22 Each engine manages a registry that's used for dependency injection and
23 exposed through `RegistryProxy`.
24
25 Engines also manage initializers and instance initializers.
26
27 Engines can spawn `EngineInstance` instances via `buildInstance()`.
28
29 @class Engine
30 @extends Ember.Namespace
31 @uses RegistryProxyMixin
32 @public
33 */
34 interface Engine extends RegistryProxyMixin {}
35 const Engine_base: Readonly<typeof Namespace> &
36 (new (owner?: import('@ember/owner').default | undefined) => Namespace) &
37 import('@ember/object/mixin').default;
38 class Engine extends Engine_base {
39 static initializers: Record<string, Initializer<Engine>>;
40 static instanceInitializers: Record<string, Initializer<EngineInstance>>;
41 /**
42 The goal of initializers should be to register dependencies and injections.
43 This phase runs once. Because these initializers may load code, they are
44 allowed to defer application readiness and advance it. If you need to access
45 the container or store you should use an InstanceInitializer that will be run
46 after all initializers and therefore after all code is loaded and the app is
47 ready.
48
49 Initializer receives an object which has the following attributes:
50 `name`, `before`, `after`, `initialize`. The only required attribute is
51 `initialize`, all others are optional.
52
53 * `name` allows you to specify under which name the initializer is registered.
54 This must be a unique name, as trying to register two initializers with the
55 same name will result in an error.
56
57 ```app/initializer/named-initializer.js
58 import { debug } from '@ember/debug';
59
60 export function initialize() {
61 debug('Running namedInitializer!');
62 }
63
64 export default {
65 name: 'named-initializer',
66 initialize
67 };
68 ```
69
70 * `before` and `after` are used to ensure that this initializer is ran prior
71 or after the one identified by the value. This value can be a single string
72 or an array of strings, referencing the `name` of other initializers.
73
74 An example of ordering initializers, we create an initializer named `first`:
75
76 ```app/initializer/first.js
77 import { debug } from '@ember/debug';
78
79 export function initialize() {
80 debug('First initializer!');
81 }
82
83 export default {
84 name: 'first',
85 initialize
86 };
87 ```
88
89 ```bash
90 // DEBUG: First initializer!
91 ```
92
93 We add another initializer named `second`, specifying that it should run
94 after the initializer named `first`:
95
96 ```app/initializer/second.js
97 import { debug } from '@ember/debug';
98
99 export function initialize() {
100 debug('Second initializer!');
101 }
102
103 export default {
104 name: 'second',
105 after: 'first',
106 initialize
107 };
108 ```
109
110 ```
111 // DEBUG: First initializer!
112 // DEBUG: Second initializer!
113 ```
114
115 Afterwards we add a further initializer named `pre`, this time specifying
116 that it should run before the initializer named `first`:
117
118 ```app/initializer/pre.js
119 import { debug } from '@ember/debug';
120
121 export function initialize() {
122 debug('Pre initializer!');
123 }
124
125 export default {
126 name: 'pre',
127 before: 'first',
128 initialize
129 };
130 ```
131
132 ```bash
133 // DEBUG: Pre initializer!
134 // DEBUG: First initializer!
135 // DEBUG: Second initializer!
136 ```
137
138 Finally we add an initializer named `post`, specifying it should run after
139 both the `first` and the `second` initializers:
140
141 ```app/initializer/post.js
142 import { debug } from '@ember/debug';
143
144 export function initialize() {
145 debug('Post initializer!');
146 }
147
148 export default {
149 name: 'post',
150 after: ['first', 'second'],
151 initialize
152 };
153 ```
154
155 ```bash
156 // DEBUG: Pre initializer!
157 // DEBUG: First initializer!
158 // DEBUG: Second initializer!
159 // DEBUG: Post initializer!
160 ```
161
162 * `initialize` is a callback function that receives one argument,
163 `application`, on which you can operate.
164
165 Example of using `application` to register an adapter:
166
167 ```app/initializer/api-adapter.js
168 import ApiAdapter from '../utils/api-adapter';
169
170 export function initialize(application) {
171 application.register('api-adapter:main', ApiAdapter);
172 }
173
174 export default {
175 name: 'post',
176 after: ['first', 'second'],
177 initialize
178 };
179 ```
180
181 @method initializer
182 @param initializer {Object}
183 @public
184 */
185 static initializer: (this: typeof Engine, initializer: Initializer<Engine>) => void;
186 /**
187 Instance initializers run after all initializers have run. Because
188 instance initializers run after the app is fully set up. We have access
189 to the store, container, and other items. However, these initializers run
190 after code has loaded and are not allowed to defer readiness.
191
192 Instance initializer receives an object which has the following attributes:
193 `name`, `before`, `after`, `initialize`. The only required attribute is
194 `initialize`, all others are optional.
195
196 * `name` allows you to specify under which name the instanceInitializer is
197 registered. This must be a unique name, as trying to register two
198 instanceInitializer with the same name will result in an error.
199
200 ```app/initializer/named-instance-initializer.js
201 import { debug } from '@ember/debug';
202
203 export function initialize() {
204 debug('Running named-instance-initializer!');
205 }
206
207 export default {
208 name: 'named-instance-initializer',
209 initialize
210 };
211 ```
212
213 * `before` and `after` are used to ensure that this initializer is ran prior
214 or after the one identified by the value. This value can be a single string
215 or an array of strings, referencing the `name` of other initializers.
216
217 * See Application.initializer for discussion on the usage of before
218 and after.
219
220 Example instanceInitializer to preload data into the store.
221
222 ```app/initializer/preload-data.js
223
224 export function initialize(application) {
225 var userConfig, userConfigEncoded, store;
226 // We have a HTML escaped JSON representation of the user's basic
227 // configuration generated server side and stored in the DOM of the main
228 // index.html file. This allows the app to have access to a set of data
229 // without making any additional remote calls. Good for basic data that is
230 // needed for immediate rendering of the page. Keep in mind, this data,
231 // like all local models and data can be manipulated by the user, so it
232 // should not be relied upon for security or authorization.
233
234 // Grab the encoded data from the meta tag
235 userConfigEncoded = document.querySelector('head meta[name=app-user-config]').attr('content');
236
237 // Unescape the text, then parse the resulting JSON into a real object
238 userConfig = JSON.parse(unescape(userConfigEncoded));
239
240 // Lookup the store
241 store = application.lookup('service:store');
242
243 // Push the encoded JSON into the store
244 store.pushPayload(userConfig);
245 }
246
247 export default {
248 name: 'named-instance-initializer',
249 initialize
250 };
251 ```
252
253 @method instanceInitializer
254 @param instanceInitializer
255 @public
256 */
257 static instanceInitializer: (
258 this: typeof Engine,
259 initializer: Initializer<EngineInstance>
260 ) => void;
261 /**
262 This creates a registry with the default Ember naming conventions.
263
264 It also configures the registry:
265
266 * registered views are created every time they are looked up (they are
267 not singletons)
268 * registered templates are not factories; the registered value is
269 returned directly.
270 * the router receives the application as its `namespace` property
271 * all controllers receive the router as their `target` and `controllers`
272 properties
273 * all controllers receive the application as their `namespace` property
274 * the application view receives the application controller as its
275 `controller` property
276 * the application view receives the application template as its
277 `defaultTemplate` property
278
279 @method buildRegistry
280 @static
281 @param {Application} namespace the application for which to
282 build the registry
283 @return {Ember.Registry} the built registry
284 @private
285 */
286 static buildRegistry(namespace: Engine): Registry;
287 /**
288 Set this to provide an alternate class to `DefaultResolver`
289
290 @property resolver
291 @public
292 */
293 Resolver: ResolverClass;
294 init(properties: object | undefined): void;
295 /**
296 A private flag indicating whether an engine's initializers have run yet.
297
298 @private
299 @property _initializersRan
300 */
301 _initializersRan: boolean;
302 /**
303 Ensure that initializers are run once, and only once, per engine.
304
305 @private
306 @method ensureInitializers
307 */
308 ensureInitializers(): void;
309 /**
310 Create an EngineInstance for this engine.
311
312 @public
313 @method buildInstance
314 @return {EngineInstance} the engine instance
315 */
316 buildInstance(options?: EngineInstanceOptions): EngineInstance;
317 /**
318 Build and configure the registry for the current engine.
319
320 @private
321 @method buildRegistry
322 @return {Ember.Registry} the configured registry
323 */
324 buildRegistry(): Registry;
325 /**
326 @private
327 @method initializer
328 */
329 initializer(initializer: Initializer<Engine>): void;
330 /**
331 @private
332 @method instanceInitializer
333 */
334 instanceInitializer(initializer: Initializer<EngineInstance>): void;
335 /**
336 @private
337 @method runInitializers
338 */
339 runInitializers(): void;
340 /**
341 @private
342 @since 1.12.0
343 @method runInstanceInitializers
344 */
345 runInstanceInitializers<T extends EngineInstance>(instance: T): void;
346 _runInitializer<
347 B extends 'initializers' | 'instanceInitializers',
348 T extends B extends 'initializers' ? Engine : EngineInstance
349 >(bucketName: B, cb: (name: string, initializer: Initializer<T> | undefined) => void): void;
350 }
351 /** @internal */
352 export function buildInitializerMethod<
353 B extends 'initializers' | 'instanceInitializers',
354 T extends B extends 'initializers' ? Engine : EngineInstance
355 >(bucketName: B, humanName: string): (this: typeof Engine, initializer: Initializer<T>) => void;
356 export default Engine;
357}