UNPKG

16 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 };
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15var __assign = (this && this.__assign) || function () {
16 __assign = Object.assign || function(t) {
17 for (var s, i = 1, n = arguments.length; i < n; i++) {
18 s = arguments[i];
19 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
20 t[p] = s[p];
21 }
22 return t;
23 };
24 return __assign.apply(this, arguments);
25};
26var __importDefault = (this && this.__importDefault) || function (mod) {
27 return (mod && mod.__esModule) ? mod : { "default": mod };
28};
29Object.defineProperty(exports, "__esModule", { value: true });
30var Error_1 = require("../actions/Error");
31var types_1 = require("../client/types");
32var collection_1 = require("../util/collection");
33var constants_1 = require("./constants");
34var merge_1 = __importDefault(require("./merge"));
35var types_2 = require("./types");
36var constants_2 = require("./constants");
37var uuid_1 = __importDefault(require("./uuid"));
38var packageJson = require('../package.json');
39function actionWrapper(action) {
40 return __assign({}, action, { version: getVersion(), clientInterface: {
41 name: packageJson.name,
42 version: getVersion(),
43 } });
44}
45exports.actionWrapper = actionWrapper;
46function getVersion() {
47 return packageJson.version;
48}
49exports.getVersion = getVersion;
50/**
51 * Returns full event name with prefix, group, subgroups and type formatted with separators
52 * @internal
53 * */
54function getEventNameSpace(group, eventName, component) {
55 var eventNameSpace = groupToEventNameSpace(group);
56 if (component) {
57 var subgroups_1 = component.subgroups, type = component.type;
58 if (subgroups_1 && subgroups_1.length > 0) {
59 eventNameSpace += eventNameSpace.length > 0 ? constants_2.SEPARATOR : '';
60 subgroups_1.forEach(function (subgroup, index) {
61 eventNameSpace += "" + subgroup.toUpperCase() + (index < subgroups_1.length - 1 ? constants_2.SEPARATOR : '');
62 });
63 }
64 if (type !== group && type) {
65 eventNameSpace += "" + (eventNameSpace.length > 0 ? constants_2.SEPARATOR : '') + type.toUpperCase();
66 }
67 }
68 if (eventNameSpace) {
69 eventNameSpace += "" + (eventNameSpace.length > 0 ? constants_2.SEPARATOR : '') + eventName.toUpperCase();
70 }
71 return "" + constants_1.PREFIX + constants_2.SEPARATOR + eventNameSpace;
72}
73exports.getEventNameSpace = getEventNameSpace;
74function isValidOptionalNumber(value) {
75 return value === null || value === undefined || typeof value === 'number';
76}
77exports.isValidOptionalNumber = isValidOptionalNumber;
78function isValidOptionalString(value) {
79 return value === null || value === undefined || typeof value === 'string';
80}
81exports.isValidOptionalString = isValidOptionalString;
82var ActionSet = /** @class */ (function () {
83 function ActionSet(app, type, group, id) {
84 var _this = this;
85 this.app = app;
86 this.type = type;
87 this.group = group;
88 this.subgroups = [];
89 this.subscriptions = [];
90 if (!app) {
91 Error_1.throwError(Error_1.ActionType.INVALID_OPTIONS, 'Missing required `app`');
92 }
93 this.id = id || uuid_1.default();
94 this.defaultGroup = group;
95 var defaultSet = this.set;
96 this.set = function () {
97 var args = [];
98 for (var _i = 0; _i < arguments.length; _i++) {
99 args[_i] = arguments[_i];
100 }
101 var _a;
102 if (!_this.app.hooks) {
103 return defaultSet.apply(_this, args);
104 }
105 return (_a = _this.app.hooks).run.apply(_a, [types_1.LifecycleHook.UpdateAction, defaultSet, _this].concat(args));
106 };
107 }
108 ActionSet.prototype.set = function () {
109 var _ = [];
110 for (var _i = 0; _i < arguments.length; _i++) {
111 _[_i] = arguments[_i];
112 }
113 };
114 Object.defineProperty(ActionSet.prototype, "component", {
115 get: function () {
116 return {
117 id: this.id,
118 subgroups: this.subgroups,
119 type: this.type,
120 };
121 },
122 enumerable: true,
123 configurable: true
124 });
125 ActionSet.prototype.updateSubscription = function (subscriptionToRemove, group, subgroups) {
126 var eventType = subscriptionToRemove.eventType, callback = subscriptionToRemove.callback, component = subscriptionToRemove.component;
127 var currentIndex;
128 currentIndex = this.subscriptions.findIndex(function (subscription) { return subscription === subscriptionToRemove; });
129 if (currentIndex >= 0) {
130 this.subscriptions[currentIndex].unsubscribe();
131 }
132 else {
133 currentIndex = undefined;
134 }
135 this.group = group;
136 this.subgroups = subgroups;
137 Object.assign(component, { subgroups: this.subgroups });
138 return this.subscribe(eventType, callback, component, currentIndex);
139 };
140 ActionSet.prototype.error = function (callback) {
141 var _this = this;
142 var subscriptionIndices = [];
143 forEachInEnum(Error_1.Action, function (eventNameSpace) {
144 // Keep track of subscription index so we can call unsubscribe later
145 // This ensure it will continue to work even when the subscription has been updated
146 subscriptionIndices.push(_this.subscriptions.length);
147 _this.subscribe(eventNameSpace, callback);
148 });
149 return function () {
150 var subscriptionsToRemove = subscriptionIndices.map(function (index) { return _this.subscriptions[index]; });
151 subscriptionsToRemove.forEach(function (toRemove) {
152 collection_1.removeFromCollection(_this.subscriptions, toRemove, function (removed) {
153 removed.unsubscribe();
154 });
155 });
156 };
157 };
158 ActionSet.prototype.subscribe = function (eventName, callback, component, currentIndex) {
159 var _this = this;
160 var eventComponent = component || this.component;
161 var eventType = eventName.toUpperCase();
162 var boundedCallback = typeof currentIndex === 'number' ? callback : callback.bind(this);
163 var eventNameSpace;
164 if (Error_1.isErrorEventName(eventName)) {
165 eventNameSpace = getEventNameSpace(types_2.Group.Error, eventName, __assign({}, eventComponent, { type: '' }));
166 }
167 else {
168 eventNameSpace = getEventNameSpace(this.group, eventName, eventComponent);
169 }
170 var unsubscribe = this.app.subscribe(eventNameSpace, boundedCallback, component ? component.id : this.id);
171 var subscription = {
172 eventType: eventType,
173 unsubscribe: unsubscribe,
174 callback: boundedCallback,
175 component: eventComponent,
176 updateSubscribe: function (group, subgroups) {
177 return _this.updateSubscription.call(_this, subscription, group, subgroups);
178 },
179 };
180 if (typeof currentIndex === 'number' &&
181 currentIndex >= 0 &&
182 currentIndex < this.subscriptions.length) {
183 this.subscriptions[currentIndex] = subscription;
184 }
185 else {
186 this.subscriptions.push(subscription);
187 }
188 return unsubscribe;
189 };
190 ActionSet.prototype.unsubscribe = function (resetOnly) {
191 if (resetOnly === void 0) { resetOnly = false; }
192 unsubscribeActions(this.subscriptions, this.defaultGroup, resetOnly);
193 return this;
194 };
195 return ActionSet;
196}());
197exports.ActionSet = ActionSet;
198var ActionSetWithChildren = /** @class */ (function (_super) {
199 __extends(ActionSetWithChildren, _super);
200 function ActionSetWithChildren() {
201 var _this = _super !== null && _super.apply(this, arguments) || this;
202 _this.children = [];
203 return _this;
204 }
205 ActionSetWithChildren.prototype.unsubscribe = function (unsubscribeChildren, resetParentOnly) {
206 if (unsubscribeChildren === void 0) { unsubscribeChildren = true; }
207 if (resetParentOnly === void 0) { resetParentOnly = false; }
208 unsubscribeActions(this.subscriptions, this.defaultGroup, resetParentOnly);
209 this.children.forEach(function (child) {
210 if (ActionSetWithChildren.prototype.isPrototypeOf(child)) {
211 child.unsubscribe(unsubscribeChildren, unsubscribeChildren ? false : true);
212 }
213 else {
214 child.unsubscribe(unsubscribeChildren ? false : true);
215 }
216 });
217 return this;
218 };
219 ActionSetWithChildren.prototype.getChild = function (id) {
220 var childIndex = this.children.findIndex(function (child) { return child.id === id; });
221 return childIndex >= 0 ? this.children[childIndex] : undefined;
222 };
223 ActionSetWithChildren.prototype.getChildIndex = function (id) {
224 return this.children.findIndex(function (child) { return child.id === id; });
225 };
226 ActionSetWithChildren.prototype.getChildSubscriptions = function (id, eventType) {
227 return this.subscriptions.filter(function (sub) { return sub.component.id === id && (!eventType || eventType === sub.eventType); });
228 };
229 ActionSetWithChildren.prototype.addChild = function (child, group, subgroups) {
230 var _this = this;
231 var subscriptions = child.subscriptions;
232 var existingChild = this.getChild(child.id);
233 // Add child if it doesn't already exist
234 if (!existingChild) {
235 this.children.push(child);
236 }
237 if (!subscriptions || (group === child.group && subgroups === child.subgroups)) {
238 return this;
239 }
240 subscriptions.forEach(function (subscription) {
241 var updateSubscribe = subscription.updateSubscribe;
242 updateSubscribe(group, subgroups);
243 });
244 // Update child's group and subgroups
245 Object.assign(child, { group: group, subgroups: subgroups });
246 // Update child's children subscriptions
247 if (ActionSetWithChildren.prototype.isPrototypeOf(child)) {
248 child.children.forEach(function (c) { return _this.addChild(c, group, subgroups); });
249 }
250 return this;
251 };
252 ActionSetWithChildren.prototype.removeChild = function (id) {
253 var _this = this;
254 collection_1.removeFromCollection(this.children, this.getChild(id), function () {
255 var toBeRemoved = _this.subscriptions.filter(function (subs) { return subs.component.id === id; });
256 toBeRemoved.forEach(function (toRemove) {
257 collection_1.removeFromCollection(_this.subscriptions, toRemove, function (removed) {
258 removed.unsubscribe();
259 });
260 });
261 });
262 return this;
263 };
264 ActionSetWithChildren.prototype.subscribeToChild = function (child, eventName, callback) {
265 var _this = this;
266 var boundedCallback = callback.bind(this);
267 if (eventName instanceof Array) {
268 eventName.forEach(function (e) { return _this.subscribeToChild(child, e, callback); });
269 return this;
270 }
271 if (typeof eventName !== 'string') {
272 return this;
273 }
274 var eventType = eventName.toUpperCase();
275 var currentSubscriptions = this.getChildSubscriptions(child.id, eventType);
276 if (currentSubscriptions.length > 0) {
277 // Subscription is already there, simply update it
278 currentSubscriptions.forEach(function (subs) { return subs.updateSubscribe(_this.group, child.subgroups); });
279 }
280 else {
281 var childComponent = {
282 id: child.id,
283 subgroups: child.subgroups,
284 type: child.type,
285 };
286 this.subscribe(eventType, boundedCallback, childComponent);
287 }
288 return this;
289 };
290 ActionSetWithChildren.prototype.getUpdatedChildActions = function (newActions, currentActions) {
291 if (newActions.length === 0) {
292 while (currentActions.length > 0) {
293 var action = currentActions.pop();
294 if (!action) {
295 break;
296 }
297 this.removeChild(action.id);
298 }
299 return undefined;
300 }
301 // Only allow unique actions
302 var uniqueActions = newActions.filter(function (action, index, actionsArr) { return index === actionsArr.indexOf(action); });
303 var newActionIds = uniqueActions.map(function (action) { return action.id; });
304 // Remove unused actions
305 var unusedActions = currentActions.filter(function (action) {
306 return newActionIds.indexOf(action.id) < 0;
307 });
308 while (unusedActions.length > 0) {
309 var action = unusedActions.pop();
310 if (!action) {
311 break;
312 }
313 this.removeChild(action.id);
314 }
315 return uniqueActions;
316 };
317 return ActionSetWithChildren;
318}(ActionSet));
319exports.ActionSetWithChildren = ActionSetWithChildren;
320function unsubscribeActions(subscriptions, defaultGroup, reassign) {
321 if (reassign === void 0) { reassign = false; }
322 subscriptions.forEach(function (subscription) {
323 if (reassign) {
324 var updateSubscribe = subscription.updateSubscribe;
325 // TODO: Support cases where we don't wipe out group and subgroups to defaults
326 updateSubscribe(defaultGroup, []);
327 }
328 else {
329 var unsubscribe = subscription.unsubscribe;
330 unsubscribe();
331 }
332 });
333 if (!reassign) {
334 subscriptions.length = 0;
335 }
336}
337function updateActionFromPayload(action, newProps) {
338 var id = action.id;
339 if (id === newProps.id) {
340 // Merge new properties
341 Object.assign(action, getMergedProps(action, newProps));
342 return true;
343 }
344 return false;
345}
346exports.updateActionFromPayload = updateActionFromPayload;
347function getMergedProps(props, newProps) {
348 var merged = merge_1.default(props, newProps);
349 if (!merged) {
350 // tslint:disable-next-line:prefer-object-spread
351 var cloned = Object.assign(props, newProps);
352 return cloned;
353 }
354 return merged;
355}
356exports.getMergedProps = getMergedProps;
357function forEachInEnum(types, callback) {
358 Object.keys(types).forEach(function (key) {
359 callback(types[key]);
360 });
361}
362exports.forEachInEnum = forEachInEnum;
363function findMatchInEnum(types, lookup) {
364 var match = Object.keys(types).find(function (key) {
365 return lookup === types[key];
366 });
367 return match ? types[match] : undefined;
368}
369exports.findMatchInEnum = findMatchInEnum;
370function camelCaseToSnakeCase(value) {
371 return value.replace(/([A-Z])/g, function (matcher, _val, index) {
372 return "" + (index !== 0 ? '_' : '') + matcher[0].toLowerCase();
373 });
374}
375/**
376 * Maps the group name to its event name
377 * @internal
378 * @remarks - This method is necessary for the new pattern of using snake case
379 * which makes it more readable and easier to reconstruct the group from an event name.
380 * Example: `ContextualSaveBar` becomes `CONTEXTUAL_SAVE_BAR`
381 * */
382function groupToEventNameSpace(group) {
383 switch (group) {
384 case types_2.Group.ContextualSaveBar:
385 return camelCaseToSnakeCase(group).toUpperCase();
386 default:
387 return group.toUpperCase();
388 }
389}