1 | ;
|
2 | /*
|
3 | * Copyright (c) 2018, salesforce.com, inc.
|
4 | * All rights reserved.
|
5 | * SPDX-License-Identifier: BSD-3-Clause
|
6 | * For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/BSD-3-Clause
|
7 | */
|
8 | Object.defineProperty(exports, "__esModule", { value: true });
|
9 | const Debug = require("debug");
|
10 | /**
|
11 | * An asynchronous event listener and emitter that follows the singleton pattern. The singleton pattern allows lifecycle
|
12 | * events to be emitted from deep within a library and still be consumed by any other library or tool. It allows other
|
13 | * developers to react to certain situations or events in your library without them having to manually call the method themselves.
|
14 | *
|
15 | * An example might be transforming metadata before it is deployed to an environment. As long as an event was emitted from the
|
16 | * deploy library and you were listening on that event in the same process, you could transform the metadata before the deploy
|
17 | * regardless of where in the code that metadata was initiated.
|
18 | *
|
19 | * @example
|
20 | * ```
|
21 | * // Listen for an event in a plugin hook
|
22 | * Lifecycle.getInstance().on('deploy-metadata', transformMetadata)
|
23 | *
|
24 | * // Deep in the deploy code, fire the event for all libraries and plugins to hear.
|
25 | * Lifecycle.getInstance().emit('deploy-metadata', metadataToBeDeployed);
|
26 | * ```
|
27 | */
|
28 | class Lifecycle {
|
29 | constructor() {
|
30 | this.debug = Debug(`sfdx:${this.constructor.name}`);
|
31 | this.listeners = {};
|
32 | }
|
33 | /**
|
34 | * Retrieve the singleton instance of this class so that all listeners and emitters can interact from any library or tool
|
35 | */
|
36 | static getInstance() {
|
37 | if (!this.instance) {
|
38 | this.instance = new Lifecycle();
|
39 | }
|
40 | return this.instance;
|
41 | }
|
42 | /**
|
43 | * Remove all listeners for a given event
|
44 | * @param eventName The name of the event to remove listeners of
|
45 | */
|
46 | removeAllListeners(eventName) {
|
47 | this.listeners[eventName] = [];
|
48 | }
|
49 | /**
|
50 | * Get an array of listeners (callback functions) for a given event
|
51 | * @param eventName The name of the event to get listeners of
|
52 | */
|
53 | getListeners(eventName) {
|
54 | const listeners = this.listeners[eventName];
|
55 | if (listeners) {
|
56 | return listeners;
|
57 | }
|
58 | else {
|
59 | this.listeners[eventName] = [];
|
60 | return [];
|
61 | }
|
62 | }
|
63 | /**
|
64 | * Create a new listener for a given event
|
65 | * @param eventName The name of the event that is being listened for
|
66 | * @param cb The callback function to run when the event is emitted
|
67 | */
|
68 | on(eventName, cb) {
|
69 | const listeners = this.getListeners(eventName);
|
70 | if (listeners.length !== 0) {
|
71 | this.debug(`${listeners.length +
|
72 | 1} lifecycle events with the name ${eventName} have now been registered. When this event is emitted all ${listeners.length +
|
73 | 1} listeners will fire.`);
|
74 | }
|
75 | listeners.push(cb);
|
76 | this.listeners[eventName] = listeners;
|
77 | }
|
78 | /**
|
79 | * Emit a given event, causing all callback functions to be run in the order they were registered
|
80 | * @param eventName The name of the event to emit
|
81 | * @param data The argument to be passed to the callback function
|
82 | */
|
83 | async emit(eventName, data) {
|
84 | const listeners = this.getListeners(eventName);
|
85 | if (listeners.length === 0) {
|
86 | this.debug(`A lifecycle event with the name ${eventName} does not exist. An event must be registered before it can be emitted.`);
|
87 | }
|
88 | else {
|
89 | for (const cb of listeners) {
|
90 | await cb(data);
|
91 | }
|
92 | }
|
93 | }
|
94 | }
|
95 | exports.Lifecycle = Lifecycle;
|
96 | //# sourceMappingURL=lifecycleEvents.js.map |
\ | No newline at end of file |