@shopify/app-bridge-core
Version:
**[Join our team and work on libraries like this one.](https://www.shopify.ca/careers)**
307 lines (306 loc) • 13.1 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
var __assign = (this && this.__assign) || function () {
__assign = Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
return __assign.apply(this, arguments);
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActionSetWithChildren = exports.ActionSet = void 0;
exports.unsubscribeActions = unsubscribeActions;
var types_1 = require("../client/types");
var collection_1 = require("../util/collection");
var Error_1 = require("./Error");
var types_2 = require("./types");
var uuid_1 = __importDefault(require("./uuid"));
var helper_1 = require("./helper");
var ActionSet = /** @class */ (function () {
function ActionSet(app, type, group, id) {
var _this = this;
this.app = app;
this.type = type;
this.group = group;
this.subgroups = [];
this.subscriptions = [];
if (!app) {
(0, Error_1.throwError)(Error_1.Action.INVALID_ACTION, 'Missing required `app`');
}
this.id = id || (0, uuid_1.default)();
this.defaultGroup = group;
var defaultSet = this.set;
this.set = function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (!_this.app.hooks) {
return defaultSet.apply(_this, args);
}
return (_a = _this.app.hooks).run.apply(_a, __spreadArray([types_1.LifecycleHook.UpdateAction, defaultSet, _this], args, false));
};
}
ActionSet.prototype.set = function () {
var _ = [];
for (var _i = 0; _i < arguments.length; _i++) {
_[_i] = arguments[_i];
}
};
Object.defineProperty(ActionSet.prototype, "component", {
get: function () {
return {
id: this.id,
subgroups: this.subgroups,
type: this.type,
};
},
enumerable: false,
configurable: true
});
ActionSet.prototype.updateSubscription = function (subscriptionToRemove, group, subgroups) {
var eventType = subscriptionToRemove.eventType, callback = subscriptionToRemove.callback, component = subscriptionToRemove.component;
var currentIndex;
currentIndex = this.subscriptions.findIndex(function (subscription) { return subscription === subscriptionToRemove; });
if (currentIndex >= 0) {
this.subscriptions[currentIndex].unsubscribe();
}
else {
currentIndex = undefined;
}
this.group = group;
this.subgroups = subgroups;
Object.assign(component, { subgroups: this.subgroups });
return this.subscribe(eventType, callback, component, currentIndex);
};
ActionSet.prototype.error = function (callback) {
var _this = this;
var subscriptionIndices = [];
(0, helper_1.forEachInEnum)(Error_1.Action, function (eventNameSpace) {
// Keep track of subscription index so we can call unsubscribe later
// This ensure it will continue to work even when the subscription has been updated
subscriptionIndices.push(_this.subscriptions.length);
_this.subscribe(eventNameSpace, callback);
});
return function () {
var subscriptionsToRemove = subscriptionIndices.map(function (index) { return _this.subscriptions[index]; });
subscriptionsToRemove.forEach(function (toRemove) {
(0, collection_1.removeFromCollection)(_this.subscriptions, toRemove, function (removed) {
removed.unsubscribe();
});
});
};
};
ActionSet.prototype.subscribe = function (eventName, callback, component, currentIndex) {
var _this = this;
var eventComponent = component || this.component;
var eventType = eventName.toUpperCase();
var boundedCallback = typeof currentIndex === 'number' ? callback : callback.bind(this);
var eventNameSpace;
if ((0, Error_1.isErrorEventName)(eventName)) {
eventNameSpace = (0, helper_1.getEventNameSpace)(types_2.Group.Error, eventName, __assign(__assign({}, eventComponent), { type: '' }));
}
else {
eventNameSpace = (0, helper_1.getEventNameSpace)(this.group, eventName, eventComponent);
}
var unsubscribe = this.app.subscribe(eventNameSpace, boundedCallback, component ? component.id : this.id);
var subscription = {
eventType: eventType,
unsubscribe: unsubscribe,
callback: boundedCallback,
component: eventComponent,
updateSubscribe: function (group, subgroups) {
return _this.updateSubscription(subscription, group, subgroups);
},
};
if (typeof currentIndex === 'number' &&
currentIndex >= 0 &&
currentIndex < this.subscriptions.length) {
this.subscriptions[currentIndex] = subscription;
}
else {
this.subscriptions.push(subscription);
}
return unsubscribe;
};
ActionSet.prototype.unsubscribe = function (resetOnly) {
if (resetOnly === void 0) { resetOnly = false; }
unsubscribeActions(this.subscriptions, this.defaultGroup, resetOnly);
return this;
};
return ActionSet;
}());
exports.ActionSet = ActionSet;
var ActionSetWithChildren = /** @class */ (function (_super) {
__extends(ActionSetWithChildren, _super);
function ActionSetWithChildren() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.children = [];
return _this;
}
ActionSetWithChildren.prototype.unsubscribe = function (unsubscribeChildren, resetParentOnly) {
if (unsubscribeChildren === void 0) { unsubscribeChildren = true; }
if (resetParentOnly === void 0) { resetParentOnly = false; }
unsubscribeActions(this.subscriptions, this.defaultGroup, resetParentOnly);
this.children.forEach(function (child) {
if (child instanceof ActionSetWithChildren) {
child.unsubscribe(unsubscribeChildren, !unsubscribeChildren);
}
else {
child.unsubscribe(!unsubscribeChildren);
}
});
return this;
};
ActionSetWithChildren.prototype.getChild = function (id) {
var childIndex = this.children.findIndex(function (child) { return child.id === id; });
return childIndex >= 0 ? this.children[childIndex] : undefined;
};
ActionSetWithChildren.prototype.getChildIndex = function (id) {
return this.children.findIndex(function (child) { return child.id === id; });
};
ActionSetWithChildren.prototype.getChildSubscriptions = function (id, eventType) {
return this.subscriptions.filter(function (sub) { return sub.component.id === id && (!eventType || eventType === sub.eventType); });
};
ActionSetWithChildren.prototype.addChild = function (child, group, subgroups) {
var _this = this;
var subscriptions = child.subscriptions;
var existingChild = this.getChild(child.id);
// Add child if it doesn't already exist
if (!existingChild) {
this.children.push(child);
}
if (!subscriptions || (group === child.group && subgroups === child.subgroups)) {
return this;
}
subscriptions.forEach(function (subscription) {
var updateSubscribe = subscription.updateSubscribe;
updateSubscribe(group, subgroups);
});
// Update child's group and subgroups
Object.assign(child, { group: group, subgroups: subgroups });
// Update child's children subscriptions
if (child instanceof ActionSetWithChildren) {
child.children.forEach(function (childIter) {
return _this.addChild(childIter, group, subgroups);
});
}
return this;
};
ActionSetWithChildren.prototype.removeChild = function (id) {
var _this = this;
(0, collection_1.removeFromCollection)(this.children, this.getChild(id), function () {
var toBeRemoved = _this.subscriptions.filter(function (subs) { return subs.component.id === id; });
toBeRemoved.forEach(function (toRemove) {
(0, collection_1.removeFromCollection)(_this.subscriptions, toRemove, function (removed) {
removed.unsubscribe();
});
});
});
return this;
};
ActionSetWithChildren.prototype.subscribeToChild = function (child, eventName, callback) {
var _this = this;
var boundedCallback = callback.bind(this);
if (eventName instanceof Array) {
eventName.forEach(function (eventNameIter) { return _this.subscribeToChild(child, eventNameIter, callback); });
return this;
}
if (typeof eventName !== 'string') {
return this;
}
var eventType = eventName.toUpperCase();
var currentSubscriptions = this.getChildSubscriptions(child.id, eventType);
if (currentSubscriptions.length > 0) {
// Subscription is already there, simply update it
currentSubscriptions.forEach(function (subs) { return subs.updateSubscribe(_this.group, child.subgroups); });
}
else {
var childComponent = {
id: child.id,
subgroups: child.subgroups,
type: child.type,
};
this.subscribe(eventType, boundedCallback, childComponent);
}
return this;
};
ActionSetWithChildren.prototype.getUpdatedChildActions = function (newActions, currentActions) {
if (newActions.length === 0) {
while (currentActions.length > 0) {
var action = currentActions.pop();
if (!action) {
break;
}
this.removeChild(action.id);
}
return undefined;
}
// Only allow unique actions
var uniqueActions = newActions.filter(function (action, index, actionsArr) { return index === actionsArr.indexOf(action); });
var newActionIds = uniqueActions.map(function (action) { return action.id; });
// Remove unused actions
var unusedActions = currentActions.filter(function (action) {
return newActionIds.indexOf(action.id) < 0;
});
while (unusedActions.length > 0) {
var action = unusedActions.pop();
if (!action) {
break;
}
this.removeChild(action.id);
}
return uniqueActions;
};
return ActionSetWithChildren;
}(ActionSet));
exports.ActionSetWithChildren = ActionSetWithChildren;
function unsubscribeActions(subscriptions, defaultGroup, reassign) {
if (reassign === void 0) { reassign = false; }
subscriptions.forEach(function (subscription) {
if (reassign) {
var updateSubscribe = subscription.updateSubscribe;
// eslint-disable-next-line no-warning-comments
// TODO: Support cases where we don't wipe out group and subgroups to defaults
updateSubscribe(defaultGroup, []);
}
else {
var unsubscribe = subscription.unsubscribe;
unsubscribe();
}
});
if (!reassign) {
subscriptions.length = 0;
}
}