UNPKG

8.78 kBJavaScriptView Raw
1"use strict";
2var __assign = (this && this.__assign) || function () {
3 __assign = Object.assign || function(t) {
4 for (var s, i = 1, n = arguments.length; i < n; i++) {
5 s = arguments[i];
6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 t[p] = s[p];
8 }
9 return t;
10 };
11 return __assign.apply(this, arguments);
12};
13Object.defineProperty(exports, "__esModule", { value: true });
14var app_bridge_1 = require("@shopify/app-bridge");
15var validator_1 = require("@shopify/app-bridge/actions/validator");
16var Error_1 = require("@shopify/app-bridge/actions/Error");
17var collection_1 = require("@shopify/app-bridge/util/collection");
18var actions_1 = require("./actions");
19var clientValidator_1 = require("./clientValidator");
20var async_1 = require("./store/async");
21function buildMiddleware(key, dispatchClientEventHandler, isAsync) {
22 if (isAsync === void 0) { isAsync = false; }
23 var transports = [];
24 var subscribers = [];
25 var store;
26 var actionsQueue;
27 var middleware = function (hostStore) {
28 store = hostStore;
29 if (isAsync) {
30 actionsQueue = async_1.createActionsQueue(store);
31 }
32 return function (next) { return function (action) {
33 if (validator_1.isAppBridgeAction(action)) {
34 for (var _i = 0, transports_1 = transports; _i < transports_1.length; _i++) {
35 var transport = transports_1[_i];
36 var features = store.getState()[key].features[transport.context];
37 if (validator_1.isPermitted(features, action, app_bridge_1.PermissionType.Subscribe)) {
38 transport.dispatch({
39 payload: action,
40 type: 'dispatch',
41 });
42 }
43 }
44 }
45 if (isAsync && actions_1.isLoadReducerCompleteAction(action)) {
46 actionsQueue.resolve(action.payload.feature);
47 }
48 return next(action);
49 }; };
50 };
51 middleware.load = function provideApplicationInterface(data) {
52 var config = data.config;
53 var clientHandlers = createClientHandlers();
54 store.dispatch(actions_1.apiClientLoad(config));
55 return {
56 attach: function (to) {
57 var _this = this;
58 var contextualClientHandlers = clientHandlers[to.context];
59 contextualClientHandlers.unsubscribe();
60 if (isAsync) {
61 actionsQueue.clear(to.context);
62 }
63 var unsubscribe = to.subscribe(function (event) {
64 var context = to.context;
65 var action = event.data;
66 var type = action && action.type;
67 var payload = action && action.payload;
68 var source = action && action.source;
69 if (!clientValidator_1.isValidConfig(source, config)) {
70 clientValidator_1.throwInvalidConfigError(source, config, payload);
71 }
72 if (to.frameWindow !== event.source) {
73 return;
74 }
75 for (var _i = 0, subscribers_1 = subscribers; _i < subscribers_1.length; _i++) {
76 var listener = subscribers_1[_i];
77 listener(action);
78 }
79 switch (type) {
80 case 'dispatch':
81 var appState = _this.getState();
82 var features = appState.features[context];
83 if (!validator_1.isPermitted(features, payload, app_bridge_1.PermissionType.Dispatch)) {
84 store.dispatch(Error_1.permissionAction(payload));
85 return;
86 }
87 if (isAsync && !async_1.isReducerLoaded(appState, payload)) {
88 actionsQueue.add(to.context, payload);
89 }
90 else {
91 store.dispatch(__assign({}, payload, { source: source }));
92 }
93 if (dispatchClientEventHandler) {
94 var appId = config.appId, shopId = config.shopId;
95 dispatchClientEventHandler({
96 action: payload,
97 appId: appId,
98 shopId: shopId,
99 });
100 }
101 break;
102 case 'getState':
103 var defaultState = _this.getState();
104 var state = __assign({}, defaultState, { features: defaultState.features[context], context: context });
105 to.dispatch({
106 type: type,
107 payload: state,
108 });
109 break;
110 case 'subscribe':
111 contextualClientHandlers.subscribe(payload);
112 break;
113 case 'unsubscribe':
114 contextualClientHandlers.unsubscribe(payload);
115 break;
116 default:
117 Error_1.throwError(Error_1.ActionType.INVALID_ACTION, action, 'Unknown action type. Expected `dispatch` or `getState`.');
118 }
119 });
120 var detach = collection_1.addAndRemoveFromCollection(transports, to, unsubscribe);
121 return function (unload) {
122 if (unload === void 0) { unload = true; }
123 var origin = new URL(config.url).origin;
124 var removed = detach() && !transports.find(function (transport) { return transport.localOrigin === origin; });
125 contextualClientHandlers.unsubscribe();
126 if (isAsync && removed) {
127 actionsQueue.clear(to.context);
128 }
129 if (removed && unload) {
130 store.dispatch(actions_1.apiClientUnload(config));
131 }
132 };
133 },
134 dispatch: function (action) {
135 store.dispatch(action);
136 },
137 getState: function () {
138 return store.getState()[key];
139 },
140 subscribe: function (listener) {
141 return collection_1.addAndRemoveFromCollection(subscribers, listener);
142 },
143 isTransportSubscribed: function (context, type, id) {
144 return clientHandlers[context].isSubscribed(type, id);
145 },
146 };
147 };
148 return middleware;
149}
150exports.buildMiddleware = buildMiddleware;
151function createClientHandlers() {
152 var _a, _b;
153 var subscriptions = (_a = {}, _a[app_bridge_1.Context.Main] = {}, _a[app_bridge_1.Context.Modal] = {}, _a);
154 return _b = {},
155 _b[app_bridge_1.Context.Main] = createSubscriptionsHandler(subscriptions[app_bridge_1.Context.Main]),
156 _b[app_bridge_1.Context.Modal] = createSubscriptionsHandler(subscriptions[app_bridge_1.Context.Modal]),
157 _b;
158}
159function createSubscriptionsHandler(subscriptions) {
160 return {
161 isSubscribed: function (type, id) {
162 var contextSubscribers = subscriptions[type] || [];
163 var subscribers = contextSubscribers.filter(function (sub) { return sub.id === id; });
164 return subscribers.length > 0;
165 },
166 subscribe: function (payload) {
167 var type = payload.type;
168 if (!subscriptions[type]) {
169 subscriptions[type] = [];
170 }
171 var eventSubscriptions = subscriptions[type] || [];
172 collection_1.addAndRemoveFromCollection(eventSubscriptions, payload);
173 },
174 unsubscribe: function (payload) {
175 if (!payload) {
176 subscriptions = {};
177 return;
178 }
179 var type = payload.type, id = payload.id;
180 var eventSubscriptions = subscriptions[type];
181 if (!eventSubscriptions) {
182 return;
183 }
184 if (id) {
185 var index = eventSubscriptions.findIndex(function (sub) { return sub.id === id; });
186 if (index >= 0) {
187 return eventSubscriptions.splice(index);
188 }
189 }
190 eventSubscriptions.pop();
191 },
192 };
193}