UNPKG

8.87 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 });
14exports.buildMiddleware = void 0;
15var app_bridge_1 = require("@shopify/app-bridge");
16var validator_1 = require("@shopify/app-bridge/actions/validator");
17var Error_1 = require("@shopify/app-bridge/actions/Error");
18var collection_1 = require("@shopify/app-bridge/util/collection");
19var actions_1 = require("./actions");
20var clientValidator_1 = require("./clientValidator");
21var async_1 = require("./store/async");
22function buildMiddleware(key, dispatchClientEventHandler, isAsync) {
23 if (isAsync === void 0) { isAsync = false; }
24 var transports = [];
25 var transportListener = app_bridge_1.createTransportListener();
26 var subscribe = transportListener.createSubscribeHandler();
27 var store;
28 var actionsQueue;
29 var middleware = function (hostStore) {
30 store = hostStore;
31 if (isAsync) {
32 actionsQueue = async_1.createActionsQueue(store);
33 }
34 return function (next) { return function (action) {
35 if (validator_1.isAppBridgeAction(action)) {
36 for (var _i = 0, transports_1 = transports; _i < transports_1.length; _i++) {
37 var transport = transports_1[_i];
38 var features = store.getState()[key].features[transport.context];
39 if (validator_1.isPermitted(features, action, app_bridge_1.PermissionType.Subscribe)) {
40 transport.dispatch({
41 payload: action,
42 type: 'dispatch',
43 });
44 }
45 }
46 }
47 if (isAsync && actions_1.isLoadReducerCompleteAction(action)) {
48 actionsQueue.resolve(action.payload.feature);
49 }
50 return next(action);
51 }; };
52 };
53 middleware.load = function provideApplicationInterface(data) {
54 var config = data.config;
55 var clientHandlers = createClientHandlers();
56 store.dispatch(actions_1.apiClientLoad(config));
57 return {
58 attach: function (to) {
59 var _this = this;
60 var contextualClientHandlers = clientHandlers[to.context];
61 contextualClientHandlers.unsubscribe();
62 if (isAsync) {
63 actionsQueue.clear(to.context);
64 }
65 var unsubscribe = to.subscribe(function (event) {
66 var context = to.context;
67 var message = event.data;
68 var type = message === null || message === void 0 ? void 0 : message.type;
69 var action = message === null || message === void 0 ? void 0 : message.payload;
70 var source = message === null || message === void 0 ? void 0 : message.source;
71 if (!clientValidator_1.isValidConfig(source, config)) {
72 clientValidator_1.throwInvalidConfigError(source, config, action);
73 }
74 if (to.frameWindow !== event.source) {
75 return;
76 }
77 transportListener.handleMessage(message);
78 switch (type) {
79 case 'dispatch':
80 var appState = _this.getState();
81 var features = appState.features[context];
82 if (!features || !validator_1.isPermitted(features, action, app_bridge_1.PermissionType.Dispatch)) {
83 store.dispatch(Error_1.permissionAction(action));
84 return;
85 }
86 transportListener.handleActionDispatch(action);
87 if (isAsync && !async_1.isReducerLoaded(appState, action)) {
88 actionsQueue.add(to.context, action);
89 }
90 else {
91 store.dispatch(__assign(__assign({}, action), { source: source }));
92 }
93 if (dispatchClientEventHandler) {
94 var appId = config.appId, shopId = config.shopId;
95 dispatchClientEventHandler({
96 action: action,
97 appId: appId,
98 shopId: shopId,
99 });
100 }
101 break;
102 case 'getState':
103 var defaultState = _this.getState();
104 var state = __assign(__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(action);
112 break;
113 case 'unsubscribe':
114 contextualClientHandlers.unsubscribe(action);
115 break;
116 default:
117 Error_1.throwError(Error_1.ActionType.INVALID_ACTION, message, 'Unknown message 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: subscribe,
141 isTransportSubscribed: function (context, type, id) {
142 return clientHandlers[context].isSubscribed(type, id);
143 },
144 };
145 };
146 return middleware;
147}
148exports.buildMiddleware = buildMiddleware;
149function createClientHandlers() {
150 var _a, _b;
151 var subscriptions = (_a = {}, _a[app_bridge_1.Context.Main] = {}, _a[app_bridge_1.Context.Modal] = {}, _a);
152 return _b = {},
153 _b[app_bridge_1.Context.Main] = createSubscriptionsHandler(subscriptions[app_bridge_1.Context.Main]),
154 _b[app_bridge_1.Context.Modal] = createSubscriptionsHandler(subscriptions[app_bridge_1.Context.Modal]),
155 _b;
156}
157function createSubscriptionsHandler(subscriptions) {
158 return {
159 isSubscribed: function (type, id) {
160 var contextSubscribers = subscriptions[type] || [];
161 var subscribers = contextSubscribers.filter(function (sub) { return sub.id === id; });
162 return subscribers.length > 0;
163 },
164 subscribe: function (payload) {
165 var type = payload.type;
166 if (!subscriptions[type]) {
167 subscriptions[type] = [];
168 }
169 var eventSubscriptions = subscriptions[type] || [];
170 collection_1.addAndRemoveFromCollection(eventSubscriptions, payload);
171 },
172 unsubscribe: function (payload) {
173 if (!payload) {
174 subscriptions = {};
175 return;
176 }
177 var type = payload.type, id = payload.id;
178 var eventSubscriptions = subscriptions[type];
179 if (!eventSubscriptions) {
180 return;
181 }
182 if (id) {
183 var index = eventSubscriptions.findIndex(function (sub) { return sub.id === id; });
184 if (index >= 0) {
185 return eventSubscriptions.splice(index);
186 }
187 }
188 eventSubscriptions.pop();
189 },
190 };
191}