UNPKG

15.7 kBJavaScriptView Raw
1/*
2 * Copyright 2017-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with
5 * the License. A copy of the License is located at
6 *
7 * http://aws.amazon.com/apache2.0/
8 *
9 * or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
10 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions
11 * and limitations under the License.
12 */
13var __assign = (this && this.__assign) || function () {
14 __assign = Object.assign || function(t) {
15 for (var s, i = 1, n = arguments.length; i < n; i++) {
16 s = arguments[i];
17 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
18 t[p] = s[p];
19 }
20 return t;
21 };
22 return __assign.apply(this, arguments);
23};
24var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
25 function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
26 return new (P || (P = Promise))(function (resolve, reject) {
27 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
28 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
29 function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
30 step((generator = generator.apply(thisArg, _arguments || [])).next());
31 });
32};
33var __generator = (this && this.__generator) || function (thisArg, body) {
34 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
35 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
36 function verb(n) { return function (v) { return step([n, v]); }; }
37 function step(op) {
38 if (f) throw new TypeError("Generator is already executing.");
39 while (_) try {
40 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
41 if (y = 0, t) op = [op[0] & 2, t.value];
42 switch (op[0]) {
43 case 0: case 1: t = op; break;
44 case 4: _.label++; return { value: op[1], done: false };
45 case 5: _.label++; y = op[1]; op = [0]; continue;
46 case 7: op = _.ops.pop(); _.trys.pop(); continue;
47 default:
48 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
49 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
50 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
51 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
52 if (t[2]) _.ops.pop();
53 _.trys.pop(); continue;
54 }
55 op = body.call(thisArg, _);
56 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
57 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
58 }
59};
60import { Amplify, ConsoleLogger as Logger, Hub, Parser, } from '@aws-amplify/core';
61import { AWSPinpointProvider } from './Providers/AWSPinpointProvider';
62import { PageViewTracker, EventTracker, SessionTracker } from './trackers';
63var logger = new Logger('AnalyticsClass');
64var AMPLIFY_SYMBOL = (typeof Symbol !== 'undefined' &&
65 typeof Symbol.for === 'function'
66 ? Symbol.for('amplify_default')
67 : '@@amplify_default');
68var dispatchAnalyticsEvent = function (event, data, message) {
69 Hub.dispatch('analytics', { event: event, data: data, message: message }, 'Analytics', AMPLIFY_SYMBOL);
70};
71var trackers = {
72 pageView: PageViewTracker,
73 event: EventTracker,
74 session: SessionTracker,
75};
76var _instance = null;
77/**
78 * Provide mobile analytics client functions
79 */
80var AnalyticsClass = /** @class */ (function () {
81 /**
82 * Initialize Analtyics
83 * @param config - Configuration of the Analytics
84 */
85 function AnalyticsClass() {
86 this._config = {};
87 this._pluggables = [];
88 this._disabled = false;
89 this._trackers = {};
90 _instance = this;
91 this.record = this.record.bind(this);
92 Hub.listen('auth', listener);
93 Hub.listen('storage', listener);
94 Hub.listen('analytics', listener);
95 }
96 AnalyticsClass.prototype.getModuleName = function () {
97 return 'Analytics';
98 };
99 /**
100 * configure Analytics
101 * @param {Object} config - Configuration of the Analytics
102 */
103 AnalyticsClass.prototype.configure = function (config) {
104 var _this = this;
105 if (!config)
106 return this._config;
107 logger.debug('configure Analytics', config);
108 var amplifyConfig = Parser.parseMobilehubConfig(config);
109 this._config = Object.assign({}, this._config, amplifyConfig.Analytics, config);
110 if (this._config['disabled']) {
111 this._disabled = true;
112 }
113 // turn on the autoSessionRecord if not specified
114 if (this._config['autoSessionRecord'] === undefined) {
115 this._config['autoSessionRecord'] = true;
116 }
117 this._pluggables.forEach(function (pluggable) {
118 // for backward compatibility
119 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
120 !_this._config['AWSPinpoint']
121 ? _this._config
122 : _this._config[pluggable.getProviderName()];
123 pluggable.configure(__assign({ disabled: _this._config['disabled'], autoSessionRecord: _this._config['autoSessionRecord'] }, providerConfig));
124 });
125 if (this._pluggables.length === 0) {
126 this.addPluggable(new AWSPinpointProvider());
127 }
128 dispatchAnalyticsEvent('configured', null, "The Analytics category has been configured successfully");
129 logger.debug('current configuration', this._config);
130 return this._config;
131 };
132 /**
133 * add plugin into Analytics category
134 * @param {Object} pluggable - an instance of the plugin
135 */
136 AnalyticsClass.prototype.addPluggable = function (pluggable) {
137 if (pluggable && pluggable.getCategory() === 'Analytics') {
138 this._pluggables.push(pluggable);
139 // for backward compatibility
140 var providerConfig = pluggable.getProviderName() === 'AWSPinpoint' &&
141 !this._config['AWSPinpoint']
142 ? this._config
143 : this._config[pluggable.getProviderName()];
144 var config = __assign({ disabled: this._config['disabled'] }, providerConfig);
145 pluggable.configure(config);
146 return config;
147 }
148 };
149 /**
150 * Get the plugin object
151 * @param providerName - the name of the plugin
152 */
153 AnalyticsClass.prototype.getPluggable = function (providerName) {
154 for (var i = 0; i < this._pluggables.length; i += 1) {
155 var pluggable = this._pluggables[i];
156 if (pluggable.getProviderName() === providerName) {
157 return pluggable;
158 }
159 }
160 logger.debug('No plugin found with providerName', providerName);
161 return null;
162 };
163 /**
164 * Remove the plugin object
165 * @param providerName - the name of the plugin
166 */
167 AnalyticsClass.prototype.removePluggable = function (providerName) {
168 var idx = 0;
169 while (idx < this._pluggables.length) {
170 if (this._pluggables[idx].getProviderName() === providerName) {
171 break;
172 }
173 idx += 1;
174 }
175 if (idx === this._pluggables.length) {
176 logger.debug('No plugin found with providerName', providerName);
177 return;
178 }
179 else {
180 this._pluggables.splice(idx, idx + 1);
181 return;
182 }
183 };
184 /**
185 * stop sending events
186 */
187 AnalyticsClass.prototype.disable = function () {
188 this._disabled = true;
189 };
190 /**
191 * start sending events
192 */
193 AnalyticsClass.prototype.enable = function () {
194 this._disabled = false;
195 };
196 /**
197 * Record Session start
198 * @return - A promise which resolves if buffer doesn't overflow
199 */
200 AnalyticsClass.prototype.startSession = function (provider) {
201 return __awaiter(this, void 0, void 0, function () {
202 var params;
203 return __generator(this, function (_a) {
204 params = { event: { name: '_session.start' }, provider: provider };
205 return [2 /*return*/, this._sendEvent(params)];
206 });
207 });
208 };
209 /**
210 * Record Session stop
211 * @return - A promise which resolves if buffer doesn't overflow
212 */
213 AnalyticsClass.prototype.stopSession = function (provider) {
214 return __awaiter(this, void 0, void 0, function () {
215 var params;
216 return __generator(this, function (_a) {
217 params = { event: { name: '_session.stop' }, provider: provider };
218 return [2 /*return*/, this._sendEvent(params)];
219 });
220 });
221 };
222 /**
223 * Record one analytic event and send it to Pinpoint
224 * @param {String} name - The name of the event
225 * @param {Object} [attributes] - Attributes of the event
226 * @param {Object} [metrics] - Event metrics
227 * @return - A promise which resolves if buffer doesn't overflow
228 */
229 AnalyticsClass.prototype.record = function (event, provider, metrics) {
230 return __awaiter(this, void 0, void 0, function () {
231 var params;
232 return __generator(this, function (_a) {
233 params = null;
234 // this is just for compatibility, going to be deprecated
235 if (typeof event === 'string') {
236 params = {
237 event: {
238 name: event,
239 attributes: provider,
240 metrics: metrics,
241 },
242 provider: 'AWSPinpoint',
243 };
244 }
245 else {
246 params = { event: event, provider: provider };
247 }
248 return [2 /*return*/, this._sendEvent(params)];
249 });
250 });
251 };
252 AnalyticsClass.prototype.updateEndpoint = function (attrs, provider) {
253 return __awaiter(this, void 0, void 0, function () {
254 var event;
255 return __generator(this, function (_a) {
256 event = __assign(__assign({}, attrs), { name: '_update_endpoint' });
257 return [2 /*return*/, this.record(event, provider)];
258 });
259 });
260 };
261 AnalyticsClass.prototype._sendEvent = function (params) {
262 var _this = this;
263 if (this._disabled) {
264 logger.debug('Analytics has been disabled');
265 return Promise.resolve();
266 }
267 var provider = params.provider ? params.provider : 'AWSPinpoint';
268 return new Promise(function (resolve, reject) {
269 _this._pluggables.forEach(function (pluggable) {
270 if (pluggable.getProviderName() === provider) {
271 pluggable.record(params, { resolve: resolve, reject: reject });
272 }
273 });
274 });
275 };
276 AnalyticsClass.prototype.autoTrack = function (trackerType, opts) {
277 if (!trackers[trackerType]) {
278 logger.debug('invalid tracker type');
279 return;
280 }
281 // to sync up two different configuration ways of auto session tracking
282 if (trackerType === 'session') {
283 this._config['autoSessionRecord'] = opts['enable'];
284 }
285 var tracker = this._trackers[trackerType];
286 if (!tracker) {
287 this._trackers[trackerType] = new trackers[trackerType](this.record, opts);
288 }
289 else {
290 tracker.configure(opts);
291 }
292 };
293 return AnalyticsClass;
294}());
295export { AnalyticsClass };
296var endpointUpdated = false;
297var authConfigured = false;
298var analyticsConfigured = false;
299var listener = function (capsule) {
300 var channel = capsule.channel, payload = capsule.payload;
301 logger.debug('on hub capsule ' + channel, payload);
302 switch (channel) {
303 case 'auth':
304 authEvent(payload);
305 break;
306 case 'storage':
307 storageEvent(payload);
308 break;
309 case 'analytics':
310 analyticsEvent(payload);
311 break;
312 default:
313 break;
314 }
315};
316var storageEvent = function (payload) {
317 var _a = payload.data, attrs = _a.attrs, metrics = _a.metrics;
318 if (!attrs)
319 return;
320 if (analyticsConfigured) {
321 _instance
322 .record({
323 name: 'Storage',
324 attributes: attrs,
325 metrics: metrics,
326 })
327 .catch(function (e) {
328 logger.debug('Failed to send the storage event automatically', e);
329 });
330 }
331};
332var authEvent = function (payload) {
333 var event = payload.event;
334 if (!event) {
335 return;
336 }
337 var recordAuthEvent = function (eventName) { return __awaiter(void 0, void 0, void 0, function () {
338 var err_1;
339 return __generator(this, function (_a) {
340 switch (_a.label) {
341 case 0:
342 if (!(authConfigured && analyticsConfigured)) return [3 /*break*/, 4];
343 _a.label = 1;
344 case 1:
345 _a.trys.push([1, 3, , 4]);
346 return [4 /*yield*/, _instance.record({ name: "_userauth." + eventName })];
347 case 2: return [2 /*return*/, _a.sent()];
348 case 3:
349 err_1 = _a.sent();
350 logger.debug("Failed to send the " + eventName + " event automatically", err_1);
351 return [3 /*break*/, 4];
352 case 4: return [2 /*return*/];
353 }
354 });
355 }); };
356 switch (event) {
357 case 'signIn':
358 return recordAuthEvent('sign_in');
359 case 'signUp':
360 return recordAuthEvent('sign_up');
361 case 'signOut':
362 return recordAuthEvent('sign_out');
363 case 'signIn_failure':
364 return recordAuthEvent('auth_fail');
365 case 'configured':
366 authConfigured = true;
367 if (authConfigured && analyticsConfigured) {
368 sendEvents();
369 }
370 break;
371 }
372};
373var analyticsEvent = function (payload) {
374 var event = payload.event;
375 if (!event)
376 return;
377 switch (event) {
378 case 'pinpointProvider_configured':
379 analyticsConfigured = true;
380 if (authConfigured && analyticsConfigured) {
381 sendEvents();
382 }
383 break;
384 }
385};
386var sendEvents = function () {
387 var config = _instance.configure();
388 if (!endpointUpdated && config['autoSessionRecord']) {
389 _instance.updateEndpoint({ immediate: true }).catch(function (e) {
390 logger.debug('Failed to update the endpoint', e);
391 });
392 endpointUpdated = true;
393 }
394 _instance.autoTrack('session', {
395 enable: config['autoSessionRecord'],
396 });
397};
398export var Analytics = new AnalyticsClass();
399Amplify.register(Analytics);
400//# sourceMappingURL=Analytics.js.map
\No newline at end of file