1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 | Object.defineProperty(exports, "__esModule", { value: true });
|
7 | exports.LifeCycleObserverRegistry = exports.DEFAULT_ORDERED_GROUPS = void 0;
|
8 | const tslib_1 = require("tslib");
|
9 | const context_1 = require("@loopback/context");
|
10 | const debug_1 = tslib_1.__importDefault(require("debug"));
|
11 | const keys_1 = require("./keys");
|
12 | const lifecycle_1 = require("./lifecycle");
|
13 | const debug = (0, debug_1.default)('loopback:core:lifecycle');
|
14 | exports.DEFAULT_ORDERED_GROUPS = ['server'];
|
15 |
|
16 |
|
17 |
|
18 | let LifeCycleObserverRegistry = class LifeCycleObserverRegistry {
|
19 | constructor(context, observersView, options = {
|
20 | parallel: true,
|
21 | orderedGroups: exports.DEFAULT_ORDERED_GROUPS,
|
22 | }) {
|
23 | this.context = context;
|
24 | this.observersView = observersView;
|
25 | this.options = options;
|
26 | }
|
27 | setOrderedGroups(groups) {
|
28 | this.options.orderedGroups = groups;
|
29 | }
|
30 | |
31 |
|
32 |
|
33 | getObserverGroupsByOrder() {
|
34 | const bindings = this.observersView.bindings;
|
35 | const groups = this.sortObserverBindingsByGroup(bindings);
|
36 | if (debug.enabled) {
|
37 | debug('Observer groups: %j', groups.map(g => ({
|
38 | group: g.group,
|
39 | bindings: g.bindings.map(b => b.key),
|
40 | })));
|
41 | }
|
42 | return groups;
|
43 | }
|
44 | |
45 |
|
46 |
|
47 |
|
48 | getObserverGroup(binding) {
|
49 |
|
50 | let group = binding.tagMap[keys_1.CoreTags.LIFE_CYCLE_OBSERVER_GROUP];
|
51 | if (!group) {
|
52 |
|
53 | group = this.options.orderedGroups.find(g => binding.tagMap[g] === g);
|
54 | }
|
55 | group = group || '';
|
56 | debug('Binding %s is configured with observer group %s', binding.key, group);
|
57 | return group;
|
58 | }
|
59 | |
60 |
|
61 |
|
62 |
|
63 |
|
64 |
|
65 | sortObserverBindingsByGroup(bindings) {
|
66 |
|
67 | const groupMap = new Map();
|
68 | (0, context_1.sortBindingsByPhase)(bindings, keys_1.CoreTags.LIFE_CYCLE_OBSERVER_GROUP, this.options.orderedGroups);
|
69 | for (const binding of bindings) {
|
70 | const group = this.getObserverGroup(binding);
|
71 | let bindingsInGroup = groupMap.get(group);
|
72 | if (bindingsInGroup == null) {
|
73 | bindingsInGroup = [];
|
74 | groupMap.set(group, bindingsInGroup);
|
75 | }
|
76 | bindingsInGroup.push(binding);
|
77 | }
|
78 |
|
79 | const groups = [];
|
80 | for (const [group, bindingsInGroup] of groupMap) {
|
81 | groups.push({ group, bindings: bindingsInGroup });
|
82 | }
|
83 | return groups;
|
84 | }
|
85 | |
86 |
|
87 |
|
88 |
|
89 |
|
90 | async notifyObservers(observers, bindings, event) {
|
91 | if (!this.options.parallel) {
|
92 | let index = 0;
|
93 | for (const observer of observers) {
|
94 | debug('Invoking %s observer for binding %s', event, bindings[index].key);
|
95 | index++;
|
96 | await this.invokeObserver(observer, event);
|
97 | }
|
98 | return;
|
99 | }
|
100 |
|
101 | const notifiers = observers.map((observer, index) => {
|
102 | debug('Invoking %s observer for binding %s', event, bindings[index].key);
|
103 | return this.invokeObserver(observer, event);
|
104 | });
|
105 | await Promise.all(notifiers);
|
106 | }
|
107 | |
108 |
|
109 |
|
110 |
|
111 |
|
112 | async invokeObserver(observer, event) {
|
113 | if (typeof observer[event] === 'function') {
|
114 |
|
115 |
|
116 | await (0, context_1.invokeMethod)(observer, event, this.context, [undefined], {
|
117 | skipInterceptors: true,
|
118 | });
|
119 | }
|
120 | }
|
121 | |
122 |
|
123 |
|
124 |
|
125 |
|
126 | async notifyGroups(events, groups, reverse = false) {
|
127 | var _a;
|
128 | const observers = await this.observersView.values();
|
129 | const bindings = this.observersView.bindings;
|
130 | const found = observers.some(observer => events.some(e => typeof observer[e] === 'function'));
|
131 | if (!found)
|
132 | return;
|
133 | if (reverse) {
|
134 |
|
135 | groups = [...groups].reverse();
|
136 | }
|
137 | for (const group of groups) {
|
138 | if ((_a = this.options.disabledGroups) === null || _a === void 0 ? void 0 : _a.includes(group.group)) {
|
139 | debug('Notification skipped (Group is disabled): %s', group.group);
|
140 | continue;
|
141 | }
|
142 | const observersForGroup = [];
|
143 | const bindingsInGroup = reverse
|
144 | ? group.bindings.reverse()
|
145 | : group.bindings;
|
146 | for (const binding of bindingsInGroup) {
|
147 | const index = bindings.indexOf(binding);
|
148 | observersForGroup.push(observers[index]);
|
149 | }
|
150 | for (const event of events) {
|
151 | debug('Beginning notification %s of %s...', event);
|
152 | await this.notifyObservers(observersForGroup, group.bindings, event);
|
153 | debug('Finished notification %s of %s', event);
|
154 | }
|
155 | }
|
156 | }
|
157 | |
158 |
|
159 |
|
160 | async init() {
|
161 | debug('Initializing the %s...');
|
162 | const groups = this.getObserverGroupsByOrder();
|
163 | await this.notifyGroups(['init'], groups);
|
164 | }
|
165 | |
166 |
|
167 |
|
168 | async start() {
|
169 | debug('Starting the %s...');
|
170 | const groups = this.getObserverGroupsByOrder();
|
171 | await this.notifyGroups(['start'], groups);
|
172 | }
|
173 | |
174 |
|
175 |
|
176 | async stop() {
|
177 | debug('Stopping the %s...');
|
178 | const groups = this.getObserverGroupsByOrder();
|
179 |
|
180 | await this.notifyGroups(['stop'], groups, true);
|
181 | }
|
182 | };
|
183 | LifeCycleObserverRegistry = tslib_1.__decorate([
|
184 | tslib_1.__param(0, context_1.inject.context()),
|
185 | tslib_1.__param(1, context_1.inject.view(lifecycle_1.lifeCycleObserverFilter)),
|
186 | tslib_1.__param(2, (0, context_1.inject)(keys_1.CoreBindings.LIFE_CYCLE_OBSERVER_OPTIONS, { optional: true })),
|
187 | tslib_1.__metadata("design:paramtypes", [context_1.Context,
|
188 | context_1.ContextView, Object])
|
189 | ], LifeCycleObserverRegistry);
|
190 | exports.LifeCycleObserverRegistry = LifeCycleObserverRegistry;
|
191 |
|
\ | No newline at end of file |