source: frontend/node_modules/workbox-google-analytics/initialize.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 Copyright 2018 Google LLC
3
4 Use of this source code is governed by an MIT-style
5 license that can be found in the LICENSE file or at
6 https://opensource.org/licenses/MIT.
7*/
8import { BackgroundSyncPlugin } from 'workbox-background-sync/BackgroundSyncPlugin.js';
9import { cacheNames } from 'workbox-core/_private/cacheNames.js';
10import { getFriendlyURL } from 'workbox-core/_private/getFriendlyURL.js';
11import { logger } from 'workbox-core/_private/logger.js';
12import { Route } from 'workbox-routing/Route.js';
13import { Router } from 'workbox-routing/Router.js';
14import { NetworkFirst } from 'workbox-strategies/NetworkFirst.js';
15import { NetworkOnly } from 'workbox-strategies/NetworkOnly.js';
16import { QUEUE_NAME, MAX_RETENTION_TIME, GOOGLE_ANALYTICS_HOST, GTM_HOST, ANALYTICS_JS_PATH, GTAG_JS_PATH, GTM_JS_PATH, COLLECT_PATHS_REGEX, } from './utils/constants.js';
17import './_version.js';
18/**
19 * Creates the requestWillDequeue callback to be used with the background
20 * sync plugin. The callback takes the failed request and adds the
21 * `qt` param based on the current time, as well as applies any other
22 * user-defined hit modifications.
23 *
24 * @param {Object} config See {@link workbox-google-analytics.initialize}.
25 * @return {Function} The requestWillDequeue callback function.
26 *
27 * @private
28 */
29const createOnSyncCallback = (config) => {
30 return async ({ queue }) => {
31 let entry;
32 while ((entry = await queue.shiftRequest())) {
33 const { request, timestamp } = entry;
34 const url = new URL(request.url);
35 try {
36 // Measurement protocol requests can set their payload parameters in
37 // either the URL query string (for GET requests) or the POST body.
38 const params = request.method === 'POST'
39 ? new URLSearchParams(await request.clone().text())
40 : url.searchParams;
41 // Calculate the qt param, accounting for the fact that an existing
42 // qt param may be present and should be updated rather than replaced.
43 const originalHitTime = timestamp - (Number(params.get('qt')) || 0);
44 const queueTime = Date.now() - originalHitTime;
45 // Set the qt param prior to applying hitFilter or parameterOverrides.
46 params.set('qt', String(queueTime));
47 // Apply `parameterOverrides`, if set.
48 if (config.parameterOverrides) {
49 for (const param of Object.keys(config.parameterOverrides)) {
50 const value = config.parameterOverrides[param];
51 params.set(param, value);
52 }
53 }
54 // Apply `hitFilter`, if set.
55 if (typeof config.hitFilter === 'function') {
56 config.hitFilter.call(null, params);
57 }
58 // Retry the fetch. Ignore URL search params from the URL as they're
59 // now in the post body.
60 await fetch(new Request(url.origin + url.pathname, {
61 body: params.toString(),
62 method: 'POST',
63 mode: 'cors',
64 credentials: 'omit',
65 headers: { 'Content-Type': 'text/plain' },
66 }));
67 if (process.env.NODE_ENV !== 'production') {
68 logger.log(`Request for '${getFriendlyURL(url.href)}' ` + `has been replayed`);
69 }
70 }
71 catch (err) {
72 await queue.unshiftRequest(entry);
73 if (process.env.NODE_ENV !== 'production') {
74 logger.log(`Request for '${getFriendlyURL(url.href)}' ` +
75 `failed to replay, putting it back in the queue.`);
76 }
77 throw err;
78 }
79 }
80 if (process.env.NODE_ENV !== 'production') {
81 logger.log(`All Google Analytics request successfully replayed; ` +
82 `the queue is now empty!`);
83 }
84 };
85};
86/**
87 * Creates GET and POST routes to catch failed Measurement Protocol hits.
88 *
89 * @param {BackgroundSyncPlugin} bgSyncPlugin
90 * @return {Array<Route>} The created routes.
91 *
92 * @private
93 */
94const createCollectRoutes = (bgSyncPlugin) => {
95 const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&
96 COLLECT_PATHS_REGEX.test(url.pathname);
97 const handler = new NetworkOnly({
98 plugins: [bgSyncPlugin],
99 });
100 return [new Route(match, handler, 'GET'), new Route(match, handler, 'POST')];
101};
102/**
103 * Creates a route with a network first strategy for the analytics.js script.
104 *
105 * @param {string} cacheName
106 * @return {Route} The created route.
107 *
108 * @private
109 */
110const createAnalyticsJsRoute = (cacheName) => {
111 const match = ({ url }) => url.hostname === GOOGLE_ANALYTICS_HOST &&
112 url.pathname === ANALYTICS_JS_PATH;
113 const handler = new NetworkFirst({ cacheName });
114 return new Route(match, handler, 'GET');
115};
116/**
117 * Creates a route with a network first strategy for the gtag.js script.
118 *
119 * @param {string} cacheName
120 * @return {Route} The created route.
121 *
122 * @private
123 */
124const createGtagJsRoute = (cacheName) => {
125 const match = ({ url }) => url.hostname === GTM_HOST && url.pathname === GTAG_JS_PATH;
126 const handler = new NetworkFirst({ cacheName });
127 return new Route(match, handler, 'GET');
128};
129/**
130 * Creates a route with a network first strategy for the gtm.js script.
131 *
132 * @param {string} cacheName
133 * @return {Route} The created route.
134 *
135 * @private
136 */
137const createGtmJsRoute = (cacheName) => {
138 const match = ({ url }) => url.hostname === GTM_HOST && url.pathname === GTM_JS_PATH;
139 const handler = new NetworkFirst({ cacheName });
140 return new Route(match, handler, 'GET');
141};
142/**
143 * @param {Object=} [options]
144 * @param {Object} [options.cacheName] The cache name to store and retrieve
145 * analytics.js. Defaults to the cache names provided by `workbox-core`.
146 * @param {Object} [options.parameterOverrides]
147 * [Measurement Protocol parameters](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters),
148 * expressed as key/value pairs, to be added to replayed Google Analytics
149 * requests. This can be used to, e.g., set a custom dimension indicating
150 * that the request was replayed.
151 * @param {Function} [options.hitFilter] A function that allows you to modify
152 * the hit parameters prior to replaying
153 * the hit. The function is invoked with the original hit's URLSearchParams
154 * object as its only argument.
155 *
156 * @memberof workbox-google-analytics
157 */
158const initialize = (options = {}) => {
159 const cacheName = cacheNames.getGoogleAnalyticsName(options.cacheName);
160 const bgSyncPlugin = new BackgroundSyncPlugin(QUEUE_NAME, {
161 maxRetentionTime: MAX_RETENTION_TIME,
162 onSync: createOnSyncCallback(options),
163 });
164 const routes = [
165 createGtmJsRoute(cacheName),
166 createAnalyticsJsRoute(cacheName),
167 createGtagJsRoute(cacheName),
168 ...createCollectRoutes(bgSyncPlugin),
169 ];
170 const router = new Router();
171 for (const route of routes) {
172 router.registerRoute(route);
173 }
174 router.addFetchListener();
175};
176export { initialize };
Note: See TracBrowser for help on using the repository browser.