jekyll-pwa-plugin-fork 2.1.1.pre.fork2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. checksums.yaml +7 -0
  2. data/lib/jekyll-pwa-plugin-fork.rb +185 -0
  3. data/lib/vendor/workbox-v3.6.3/workbox-background-sync.dev.js +593 -0
  4. data/lib/vendor/workbox-v3.6.3/workbox-background-sync.dev.js.map +1 -0
  5. data/lib/vendor/workbox-v3.6.3/workbox-background-sync.prod.js +3 -0
  6. data/lib/vendor/workbox-v3.6.3/workbox-background-sync.prod.js.map +1 -0
  7. data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.dev.js +395 -0
  8. data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.dev.js.map +1 -0
  9. data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.prod.js +3 -0
  10. data/lib/vendor/workbox-v3.6.3/workbox-broadcast-cache-update.prod.js.map +1 -0
  11. data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.dev.js +740 -0
  12. data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.dev.js.map +1 -0
  13. data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.prod.js +3 -0
  14. data/lib/vendor/workbox-v3.6.3/workbox-cache-expiration.prod.js.map +1 -0
  15. data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.dev.js +236 -0
  16. data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.dev.js.map +1 -0
  17. data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.prod.js +3 -0
  18. data/lib/vendor/workbox-v3.6.3/workbox-cacheable-response.prod.js.map +1 -0
  19. data/lib/vendor/workbox-v3.6.3/workbox-core.dev.js +1736 -0
  20. data/lib/vendor/workbox-v3.6.3/workbox-core.dev.js.map +1 -0
  21. data/lib/vendor/workbox-v3.6.3/workbox-core.prod.js +3 -0
  22. data/lib/vendor/workbox-v3.6.3/workbox-core.prod.js.map +1 -0
  23. data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.dev.js +255 -0
  24. data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.dev.js.map +1 -0
  25. data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.prod.js +3 -0
  26. data/lib/vendor/workbox-v3.6.3/workbox-google-analytics.prod.js.map +1 -0
  27. data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.dev.js +159 -0
  28. data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.dev.js.map +1 -0
  29. data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.prod.js +3 -0
  30. data/lib/vendor/workbox-v3.6.3/workbox-navigation-preload.prod.js.map +1 -0
  31. data/lib/vendor/workbox-v3.6.3/workbox-precaching.dev.js +1171 -0
  32. data/lib/vendor/workbox-v3.6.3/workbox-precaching.dev.js.map +1 -0
  33. data/lib/vendor/workbox-v3.6.3/workbox-precaching.prod.js +3 -0
  34. data/lib/vendor/workbox-v3.6.3/workbox-precaching.prod.js.map +1 -0
  35. data/lib/vendor/workbox-v3.6.3/workbox-range-requests.dev.js +299 -0
  36. data/lib/vendor/workbox-v3.6.3/workbox-range-requests.dev.js.map +1 -0
  37. data/lib/vendor/workbox-v3.6.3/workbox-range-requests.prod.js +3 -0
  38. data/lib/vendor/workbox-v3.6.3/workbox-range-requests.prod.js.map +1 -0
  39. data/lib/vendor/workbox-v3.6.3/workbox-routing.dev.js +863 -0
  40. data/lib/vendor/workbox-v3.6.3/workbox-routing.dev.js.map +1 -0
  41. data/lib/vendor/workbox-v3.6.3/workbox-routing.prod.js +3 -0
  42. data/lib/vendor/workbox-v3.6.3/workbox-routing.prod.js.map +1 -0
  43. data/lib/vendor/workbox-v3.6.3/workbox-strategies.dev.js +1172 -0
  44. data/lib/vendor/workbox-v3.6.3/workbox-strategies.dev.js.map +1 -0
  45. data/lib/vendor/workbox-v3.6.3/workbox-strategies.prod.js +3 -0
  46. data/lib/vendor/workbox-v3.6.3/workbox-strategies.prod.js.map +1 -0
  47. data/lib/vendor/workbox-v3.6.3/workbox-streams.dev.js +380 -0
  48. data/lib/vendor/workbox-v3.6.3/workbox-streams.dev.js.map +1 -0
  49. data/lib/vendor/workbox-v3.6.3/workbox-streams.prod.js +3 -0
  50. data/lib/vendor/workbox-v3.6.3/workbox-streams.prod.js.map +1 -0
  51. data/lib/vendor/workbox-v3.6.3/workbox-sw.js +3 -0
  52. data/lib/vendor/workbox-v3.6.3/workbox-sw.js.map +1 -0
  53. metadata +108 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 4f49d01d9e96158cc77801c2d7d798649464a0c8602161bc360a66f49ea7d9ff
4
+ data.tar.gz: 4aceca9762e08d67bb3c6bb01deb7a80c1057a25f2b8b78b9214f298667a8534
5
+ SHA512:
6
+ metadata.gz: cc845f9d411c57581333f891051e3993fbbc898981e0f30900d058ff304449d726aecfa68f8713d8855a2497972995b85dd28e45a197c86b95cdb88f3f214956
7
+ data.tar.gz: 8598f73511723a5fa72f7da8f0c4c5522f9385c5fb99104f11d1fb8d4ce6d7041eb8b8b26bfe31548f40b3dc37ed5918567d39f0a23321dfd39160626ae58fb2
@@ -0,0 +1,185 @@
1
+ require 'uglifier'
2
+ class SWHelper
3
+ WORKBOX_VERSION = 'v3.6.3'
4
+ REGISTER_SCRIPT = Uglifier.new.compile(
5
+ <<-SCRIPT
6
+ window.onload = function () {
7
+ var script = document.createElement('script');
8
+ var firstScript = document.getElementsByTagName('script')[0];
9
+ script.type = 'text/javascript';
10
+ script.async = true;
11
+ script.src = '%PAGEURL%/sw-register.js?v=' + Date.now();
12
+ firstScript.parentNode.insertBefore(script, firstScript);
13
+ };
14
+ SCRIPT
15
+ )
16
+
17
+ def initialize(site, config)
18
+ @site = site
19
+ @config = config
20
+ @sw_filename = @config['sw_dest_filename'] || 'service-worker.js'
21
+ @sw_src_filepath = @config['sw_src_filepath'] || 'service-worker.js'
22
+ end
23
+
24
+ def write_sw_register()
25
+ sw_register_filename = 'sw-register.js'
26
+ sw_register_file = File.new(@site.in_dest_dir(sw_register_filename), 'w')
27
+ # add build version in url params
28
+ sw_register_file_script =
29
+ <<-SCRIPT
30
+ if ('serviceWorker' in navigator) {
31
+ navigator.serviceWorker.register('#{@site.baseurl.to_s}/#{@sw_filename}?v=#{@site.time.to_i.to_s}').then(function(reg) {
32
+ reg.onupdatefound = function() {
33
+ var installingWorker = reg.installing;
34
+ installingWorker.onstatechange = function() {
35
+ switch (installingWorker.state) {
36
+ case 'installed':
37
+ if (navigator.serviceWorker.controller) {
38
+ var event = document.createEvent('Event');
39
+ event.initEvent('sw.update', true, true);
40
+ window.dispatchEvent(event);
41
+ }
42
+ break;
43
+ }
44
+ };
45
+ };
46
+ }).catch(function(e) {
47
+ console.error('Error during service worker registration:', e);
48
+ });
49
+ }
50
+ SCRIPT
51
+
52
+ sw_register_file.puts(Uglifier.new.compile(sw_register_file_script))
53
+ sw_register_file.close
54
+ end
55
+
56
+ def generate_workbox_precache()
57
+ directory = @config['precache_glob_directory'] || '/'
58
+ directory = @site.in_dest_dir(directory)
59
+ patterns = @config['precache_glob_patterns'] || ['**/*.{html,js,css,eot,svg,ttf,woff}']
60
+ ignores = @config['precache_glob_ignores'] || []
61
+ recent_posts_num = @config['precache_recent_posts_num']
62
+
63
+ # according to workbox precache {url: 'main.js', revision: 'xxxx'}
64
+ @precache_list = []
65
+
66
+ # find precache files with glob
67
+ precache_files = []
68
+ patterns.each do |pattern|
69
+ Dir.glob(File.join(directory, pattern)) do |filepath|
70
+ precache_files.push(filepath)
71
+ end
72
+ end
73
+ precache_files = precache_files.uniq
74
+
75
+ # precache recent n posts
76
+ posts_path_url_map = {}
77
+ if recent_posts_num
78
+ precache_files.concat(
79
+ @site.posts.docs
80
+ .reverse.take(recent_posts_num)
81
+ .map do |post|
82
+ posts_path_url_map[post.path] = post.url
83
+ post.path
84
+ end
85
+ )
86
+ end
87
+
88
+ # filter with ignores
89
+ ignores.each do |pattern|
90
+ Dir.glob(File.join(directory, pattern)) do |ignored_filepath|
91
+ precache_files.delete(ignored_filepath)
92
+ end
93
+ end
94
+
95
+ # generate md5 for each precache file
96
+ md5 = Digest::MD5.new
97
+ precache_files.each do |filepath|
98
+ md5.reset
99
+ md5 << File.read(filepath)
100
+ if posts_path_url_map[filepath]
101
+ url = posts_path_url_map[filepath]
102
+ else
103
+ url = filepath.sub(@site.dest, '')
104
+ end
105
+ @precache_list.push({
106
+ url: @site.baseurl.to_s + url,
107
+ revision: md5.hexdigest
108
+ })
109
+ end
110
+ end
111
+
112
+ def write_sw()
113
+
114
+ dest_js_directory = @config['dest_js_directory'] || 'js'
115
+
116
+ # copy polyfill & workbox.js to js/
117
+ script_directory = @site.in_dest_dir(dest_js_directory)
118
+ FileUtils.mkdir_p(script_directory) unless Dir.exist?(script_directory)
119
+ FileUtils.cp_r(File.expand_path('../vendor/', __FILE__) + '/.', script_directory)
120
+
121
+ # generate precache list
122
+ precache_list_str = @precache_list.map do |precache_item|
123
+ precache_item.to_json
124
+ end
125
+ .join(",")
126
+
127
+ # write service-worker.js
128
+ full_src_filepath = @site.in_source_dir(@sw_src_filepath)
129
+ if not File.file?(full_src_filepath)
130
+ full_src_filepath = @site.in_theme_dir(@sw_src_filepath)
131
+ end
132
+ sw_src_file_str = File.read(@site.in_theme_dir(full_src_filepath))
133
+ workbox_dir = File.join(@site.baseurl.to_s, dest_js_directory, "workbox-#{SWHelper::WORKBOX_VERSION}")
134
+ import_scripts_str =
135
+ <<-SCRIPT
136
+ importScripts("#{workbox_dir}/workbox-sw.js");
137
+ workbox.setConfig({modulePathPrefix: "#{workbox_dir}"});
138
+ SCRIPT
139
+
140
+ sw_dest_file = File.new(@site.in_dest_dir(@sw_filename), 'w')
141
+ sw_dest_file.puts(
142
+ <<-SCRIPT
143
+ #{import_scripts_str}
144
+ self.__precacheManifest = [#{precache_list_str}];
145
+ #{sw_src_file_str}
146
+ SCRIPT
147
+ )
148
+ sw_dest_file.close
149
+ end
150
+
151
+ def self.insert_sw_register_into_body(page)
152
+ script = SWHelper::REGISTER_SCRIPT.sub('%PAGEURL%', page.site.baseurl.to_s)
153
+ page.output = page.output.sub('</body>',
154
+ <<-SCRIPT
155
+ <script>
156
+ #{script}
157
+ </script>
158
+ </body>
159
+ SCRIPT
160
+ )
161
+ end
162
+ end
163
+
164
+ module Jekyll
165
+
166
+ Hooks.register :pages, :post_render do |page|
167
+ # append <script> for sw-register.js in <body>
168
+ SWHelper.insert_sw_register_into_body(page)
169
+ end
170
+
171
+ Hooks.register :documents, :post_render do |document|
172
+ # append <script> for sw-register.js in <body>
173
+ SWHelper.insert_sw_register_into_body(document)
174
+ end
175
+
176
+ Hooks.register :site, :post_write do |site|
177
+ pwa_config = site.config['pwa'] || {}
178
+ sw_helper = SWHelper.new(site, pwa_config)
179
+
180
+ sw_helper.write_sw_register()
181
+ sw_helper.generate_workbox_precache()
182
+ sw_helper.write_sw()
183
+ end
184
+
185
+ end
@@ -0,0 +1,593 @@
1
+ this.workbox = this.workbox || {};
2
+ this.workbox.backgroundSync = (function (DBWrapper_mjs,WorkboxError_mjs,logger_mjs,assert_mjs,getFriendlyURL_mjs) {
3
+ 'use strict';
4
+
5
+ try {
6
+ self.workbox.v['workbox:background-sync:3.6.3'] = 1;
7
+ } catch (e) {} // eslint-disable-line
8
+
9
+ /*
10
+ Copyright 2017 Google Inc. All Rights Reserved.
11
+ Licensed under the Apache License, Version 2.0 (the "License");
12
+ you may not use this file except in compliance with the License.
13
+ You may obtain a copy of the License at
14
+
15
+ http://www.apache.org/licenses/LICENSE-2.0
16
+
17
+ Unless required by applicable law or agreed to in writing, software
18
+ distributed under the License is distributed on an "AS IS" BASIS,
19
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ See the License for the specific language governing permissions and
21
+ limitations under the License.
22
+ */
23
+
24
+ const serializableProperties = ['method', 'referrer', 'referrerPolicy', 'mode', 'credentials', 'cache', 'redirect', 'integrity', 'keepalive'];
25
+
26
+ /**
27
+ * A class to make it easier to serialize and de-serialize requests so they
28
+ * can be stored in IndexedDB.
29
+ *
30
+ * @private
31
+ */
32
+ class StorableRequest {
33
+ /**
34
+ * Converts a Request object to a plain object that can be structured
35
+ * cloned or JSON-stringified.
36
+ *
37
+ * @param {Request} request
38
+ * @return {Promise<StorableRequest>}
39
+ *
40
+ * @private
41
+ */
42
+ static fromRequest(request) {
43
+ return babelHelpers.asyncToGenerator(function* () {
44
+ const requestInit = { headers: {} };
45
+
46
+ // Set the body if present.
47
+ if (request.method !== 'GET') {
48
+ // Use blob to support non-text request bodies,
49
+ // and clone first in case the caller still needs the request.
50
+ requestInit.body = yield request.clone().blob();
51
+ }
52
+
53
+ // Convert the headers from an iterable to an object.
54
+ for (const [key, value] of request.headers.entries()) {
55
+ requestInit.headers[key] = value;
56
+ }
57
+
58
+ // Add all other serializable request properties
59
+ for (const prop of serializableProperties) {
60
+ if (request[prop] !== undefined) {
61
+ requestInit[prop] = request[prop];
62
+ }
63
+ }
64
+
65
+ return new StorableRequest({ url: request.url, requestInit });
66
+ })();
67
+ }
68
+
69
+ /**
70
+ * Accepts a URL and RequestInit dictionary that can be used to create a
71
+ * new Request object. A timestamp is also generated so consumers can
72
+ * reference when the object was created.
73
+ *
74
+ * @param {Object} param1
75
+ * @param {string} param1.url
76
+ * @param {Object} param1.requestInit
77
+ * See: https://fetch.spec.whatwg.org/#requestinit
78
+ * @param {number} param1.timestamp The time the request was created,
79
+ * defaulting to the current time if not specified.
80
+ *
81
+ * @private
82
+ */
83
+ constructor({ url, requestInit, timestamp = Date.now() }) {
84
+ this.url = url;
85
+ this.requestInit = requestInit;
86
+
87
+ // "Private"
88
+ this._timestamp = timestamp;
89
+ }
90
+
91
+ /**
92
+ * Gets the private _timestamp property.
93
+ *
94
+ * @return {number}
95
+ *
96
+ * @private
97
+ */
98
+ get timestamp() {
99
+ return this._timestamp;
100
+ }
101
+
102
+ /**
103
+ * Coverts this instance to a plain Object.
104
+ *
105
+ * @return {Object}
106
+ *
107
+ * @private
108
+ */
109
+ toObject() {
110
+ return {
111
+ url: this.url,
112
+ timestamp: this.timestamp,
113
+ requestInit: this.requestInit
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Converts this instance to a Request.
119
+ *
120
+ * @return {Request}
121
+ *
122
+ * @private
123
+ */
124
+ toRequest() {
125
+ return new Request(this.url, this.requestInit);
126
+ }
127
+
128
+ /**
129
+ * Creates and returns a deep clone of the instance.
130
+ *
131
+ * @return {StorableRequest}
132
+ *
133
+ * @private
134
+ */
135
+ clone() {
136
+ const requestInit = Object.assign({}, this.requestInit);
137
+ requestInit.headers = Object.assign({}, this.requestInit.headers);
138
+ if (this.requestInit.body) {
139
+ requestInit.body = this.requestInit.body.slice();
140
+ }
141
+
142
+ return new StorableRequest({
143
+ url: this.url,
144
+ timestamp: this.timestamp,
145
+ requestInit
146
+ });
147
+ }
148
+ }
149
+
150
+ /*
151
+ Copyright 2017 Google Inc. All Rights Reserved.
152
+ Licensed under the Apache License, Version 2.0 (the "License");
153
+ you may not use this file except in compliance with the License.
154
+ You may obtain a copy of the License at
155
+
156
+ http://www.apache.org/licenses/LICENSE-2.0
157
+
158
+ Unless required by applicable law or agreed to in writing, software
159
+ distributed under the License is distributed on an "AS IS" BASIS,
160
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
161
+ See the License for the specific language governing permissions and
162
+ limitations under the License.
163
+ */
164
+
165
+ const DB_NAME = 'workbox-background-sync';
166
+ const OBJECT_STORE_NAME = 'requests';
167
+ const INDEXED_PROP = 'queueName';
168
+ const TAG_PREFIX = 'workbox-background-sync';
169
+ const MAX_RETENTION_TIME = 60 * 24 * 7; // 7 days in minutes
170
+
171
+ /*
172
+ Copyright 2017 Google Inc. All Rights Reserved.
173
+ Licensed under the Apache License, Version 2.0 (the "License");
174
+ you may not use this file except in compliance with the License.
175
+ You may obtain a copy of the License at
176
+
177
+ http://www.apache.org/licenses/LICENSE-2.0
178
+
179
+ Unless required by applicable law or agreed to in writing, software
180
+ distributed under the License is distributed on an "AS IS" BASIS,
181
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
182
+ See the License for the specific language governing permissions and
183
+ limitations under the License.
184
+ */
185
+
186
+ /**
187
+ * A class to manage storing requests from a Queue in IndexedbDB,
188
+ * indexed by their queue name for easier access.
189
+ *
190
+ * @private
191
+ */
192
+ class QueueStore {
193
+ /**
194
+ * Associates this instance with a Queue instance, so entries added can be
195
+ * identified by their queue name.
196
+ *
197
+ * @param {Queue} queue
198
+ *
199
+ * @private
200
+ */
201
+ constructor(queue) {
202
+ this._queue = queue;
203
+ this._db = new DBWrapper_mjs.DBWrapper(DB_NAME, 1, {
204
+ onupgradeneeded: evt => evt.target.result.createObjectStore(OBJECT_STORE_NAME, { autoIncrement: true }).createIndex(INDEXED_PROP, INDEXED_PROP, { unique: false })
205
+ });
206
+ }
207
+
208
+ /**
209
+ * Takes a StorableRequest instance, converts it to an object and adds it
210
+ * as an entry in the object store.
211
+ *
212
+ * @param {StorableRequest} storableRequest
213
+ *
214
+ * @private
215
+ */
216
+ addEntry(storableRequest) {
217
+ var _this = this;
218
+
219
+ return babelHelpers.asyncToGenerator(function* () {
220
+ yield _this._db.add(OBJECT_STORE_NAME, {
221
+ queueName: _this._queue.name,
222
+ storableRequest: storableRequest.toObject()
223
+ });
224
+ })();
225
+ }
226
+
227
+ /**
228
+ * Gets the oldest entry in the object store, removes it, and returns the
229
+ * value as a StorableRequest instance. If no entry exists, it returns
230
+ * undefined.
231
+ *
232
+ * @return {StorableRequest|undefined}
233
+ *
234
+ * @private
235
+ */
236
+ getAndRemoveOldestEntry() {
237
+ var _this2 = this;
238
+
239
+ return babelHelpers.asyncToGenerator(function* () {
240
+ const [entry] = yield _this2._db.getAllMatching(OBJECT_STORE_NAME, {
241
+ index: INDEXED_PROP,
242
+ query: IDBKeyRange.only(_this2._queue.name),
243
+ count: 1,
244
+ includeKeys: true
245
+ });
246
+
247
+ if (entry) {
248
+ yield _this2._db.delete(OBJECT_STORE_NAME, entry.primaryKey);
249
+ return new StorableRequest(entry.value.storableRequest);
250
+ }
251
+ })();
252
+ }
253
+ }
254
+
255
+ /*
256
+ Copyright 2017 Google Inc. All Rights Reserved.
257
+ Licensed under the Apache License, Version 2.0 (the "License");
258
+ you may not use this file except in compliance with the License.
259
+ You may obtain a copy of the License at
260
+
261
+ http://www.apache.org/licenses/LICENSE-2.0
262
+
263
+ Unless required by applicable law or agreed to in writing, software
264
+ distributed under the License is distributed on an "AS IS" BASIS,
265
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
266
+ See the License for the specific language governing permissions and
267
+ limitations under the License.
268
+ */
269
+
270
+ const queueNames = new Set();
271
+
272
+ /**
273
+ * A class to manage storing failed requests in IndexedDB and retrying them
274
+ * later. All parts of the storing and replaying process are observable via
275
+ * callbacks.
276
+ *
277
+ * @memberof workbox.backgroundSync
278
+ */
279
+ class Queue {
280
+ /**
281
+ * Creates an instance of Queue with the given options
282
+ *
283
+ * @param {string} name The unique name for this queue. This name must be
284
+ * unique as it's used to register sync events and store requests
285
+ * in IndexedDB specific to this instance. An error will be thrown if
286
+ * a duplicate name is detected.
287
+ * @param {Object} [options]
288
+ * @param {Object} [options.callbacks] Callbacks to observe the lifecycle of
289
+ * queued requests. Use these to respond to or modify the requests
290
+ * during the replay process.
291
+ * @param {function(StorableRequest):undefined}
292
+ * [options.callbacks.requestWillEnqueue]
293
+ * Invoked immediately before the request is stored to IndexedDB. Use
294
+ * this callback to modify request data at store time.
295
+ * @param {function(StorableRequest):undefined}
296
+ * [options.callbacks.requestWillReplay]
297
+ * Invoked immediately before the request is re-fetched. Use this
298
+ * callback to modify request data at fetch time.
299
+ * @param {function(Array<StorableRequest>):undefined}
300
+ * [options.callbacks.queueDidReplay]
301
+ * Invoked after all requests in the queue have successfully replayed.
302
+ * @param {number} [options.maxRetentionTime = 7 days] The amount of time (in
303
+ * minutes) a request may be retried. After this amount of time has
304
+ * passed, the request will be deleted from the queue.
305
+ */
306
+ constructor(name, {
307
+ callbacks = {},
308
+ maxRetentionTime = MAX_RETENTION_TIME
309
+ } = {}) {
310
+ // Ensure the store name is not already being used
311
+ if (queueNames.has(name)) {
312
+ throw new WorkboxError_mjs.WorkboxError('duplicate-queue-name', { name });
313
+ } else {
314
+ queueNames.add(name);
315
+ }
316
+
317
+ this._name = name;
318
+ this._callbacks = callbacks;
319
+ this._maxRetentionTime = maxRetentionTime;
320
+ this._queueStore = new QueueStore(this);
321
+
322
+ this._addSyncListener();
323
+ }
324
+
325
+ /**
326
+ * @return {string}
327
+ */
328
+ get name() {
329
+ return this._name;
330
+ }
331
+
332
+ /**
333
+ * Stores the passed request into IndexedDB. The database used is
334
+ * `workbox-background-sync` and the object store name is the same as
335
+ * the name this instance was created with (to guarantee it's unique).
336
+ *
337
+ * @param {Request} request The request object to store.
338
+ */
339
+ addRequest(request) {
340
+ var _this = this;
341
+
342
+ return babelHelpers.asyncToGenerator(function* () {
343
+ {
344
+ assert_mjs.assert.isInstance(request, Request, {
345
+ moduleName: 'workbox-background-sync',
346
+ className: 'Queue',
347
+ funcName: 'addRequest',
348
+ paramName: 'request'
349
+ });
350
+ }
351
+
352
+ const storableRequest = yield StorableRequest.fromRequest(request.clone());
353
+ yield _this._runCallback('requestWillEnqueue', storableRequest);
354
+ yield _this._queueStore.addEntry(storableRequest);
355
+ yield _this._registerSync();
356
+ {
357
+ logger_mjs.logger.log(`Request for '${getFriendlyURL_mjs.getFriendlyURL(storableRequest.url)}' has been
358
+ added to background sync queue '${_this._name}'.`);
359
+ }
360
+ })();
361
+ }
362
+
363
+ /**
364
+ * Retrieves all stored requests in IndexedDB and retries them. If the
365
+ * queue contained requests that were successfully replayed, the
366
+ * `queueDidReplay` callback is invoked (which implies the queue is
367
+ * now empty). If any of the requests fail, a new sync registration is
368
+ * created to retry again later.
369
+ */
370
+ replayRequests() {
371
+ var _this2 = this;
372
+
373
+ return babelHelpers.asyncToGenerator(function* () {
374
+ const now = Date.now();
375
+ const replayedRequests = [];
376
+ const failedRequests = [];
377
+
378
+ let storableRequest;
379
+ while (storableRequest = yield _this2._queueStore.getAndRemoveOldestEntry()) {
380
+ // Make a copy so the unmodified request can be stored
381
+ // in the event of a replay failure.
382
+ const storableRequestClone = storableRequest.clone();
383
+
384
+ // Ignore requests older than maxRetentionTime.
385
+ const maxRetentionTimeInMs = _this2._maxRetentionTime * 60 * 1000;
386
+ if (now - storableRequest.timestamp > maxRetentionTimeInMs) {
387
+ continue;
388
+ }
389
+
390
+ yield _this2._runCallback('requestWillReplay', storableRequest);
391
+
392
+ const replay = { request: storableRequest.toRequest() };
393
+
394
+ try {
395
+ // Clone the request before fetching so callbacks get an unused one.
396
+ replay.response = yield fetch(replay.request.clone());
397
+ {
398
+ logger_mjs.logger.log(`Request for '${getFriendlyURL_mjs.getFriendlyURL(storableRequest.url)}'
399
+ has been replayed`);
400
+ }
401
+ } catch (err) {
402
+ {
403
+ logger_mjs.logger.log(`Request for '${getFriendlyURL_mjs.getFriendlyURL(storableRequest.url)}'
404
+ failed to replay`);
405
+ }
406
+ replay.error = err;
407
+ failedRequests.push(storableRequestClone);
408
+ }
409
+
410
+ replayedRequests.push(replay);
411
+ }
412
+
413
+ yield _this2._runCallback('queueDidReplay', replayedRequests);
414
+
415
+ // If any requests failed, put the failed requests back in the queue
416
+ // and rethrow the failed requests count.
417
+ if (failedRequests.length) {
418
+ yield Promise.all(failedRequests.map(function (storableRequest) {
419
+ return _this2._queueStore.addEntry(storableRequest);
420
+ }));
421
+
422
+ throw new WorkboxError_mjs.WorkboxError('queue-replay-failed', { name: _this2._name, count: failedRequests.length });
423
+ }
424
+ })();
425
+ }
426
+
427
+ /**
428
+ * Runs the passed callback if it exists.
429
+ *
430
+ * @private
431
+ * @param {string} name The name of the callback on this._callbacks.
432
+ * @param {...*} args The arguments to invoke the callback with.
433
+ */
434
+ _runCallback(name, ...args) {
435
+ var _this3 = this;
436
+
437
+ return babelHelpers.asyncToGenerator(function* () {
438
+ if (typeof _this3._callbacks[name] === 'function') {
439
+ yield _this3._callbacks[name].apply(null, args);
440
+ }
441
+ })();
442
+ }
443
+
444
+ /**
445
+ * In sync-supporting browsers, this adds a listener for the sync event.
446
+ * In non-sync-supporting browsers, this will retry the queue on service
447
+ * worker startup.
448
+ *
449
+ * @private
450
+ */
451
+ _addSyncListener() {
452
+ if ('sync' in registration) {
453
+ self.addEventListener('sync', event => {
454
+ if (event.tag === `${TAG_PREFIX}:${this._name}`) {
455
+ {
456
+ logger_mjs.logger.log(`Background sync for tag '${event.tag}'
457
+ has been received, starting replay now`);
458
+ }
459
+ event.waitUntil(this.replayRequests());
460
+ }
461
+ });
462
+ } else {
463
+ {
464
+ logger_mjs.logger.log(`Background sync replaying without background sync event`);
465
+ }
466
+ // If the browser doesn't support background sync, retry
467
+ // every time the service worker starts up as a fallback.
468
+ this.replayRequests();
469
+ }
470
+ }
471
+
472
+ /**
473
+ * Registers a sync event with a tag unique to this instance.
474
+ *
475
+ * @private
476
+ */
477
+ _registerSync() {
478
+ var _this4 = this;
479
+
480
+ return babelHelpers.asyncToGenerator(function* () {
481
+ if ('sync' in registration) {
482
+ try {
483
+ yield registration.sync.register(`${TAG_PREFIX}:${_this4._name}`);
484
+ } catch (err) {
485
+ // This means the registration failed for some reason, possibly due to
486
+ // the user disabling it.
487
+ {
488
+ logger_mjs.logger.warn(`Unable to register sync event for '${_this4._name}'.`, err);
489
+ }
490
+ }
491
+ }
492
+ })();
493
+ }
494
+
495
+ /**
496
+ * Returns the set of queue names. This is primarily used to reset the list
497
+ * of queue names in tests.
498
+ *
499
+ * @return {Set}
500
+ *
501
+ * @private
502
+ */
503
+ static get _queueNames() {
504
+ return queueNames;
505
+ }
506
+ }
507
+
508
+ /*
509
+ Copyright 2017 Google Inc. All Rights Reserved.
510
+ Licensed under the Apache License, Version 2.0 (the "License");
511
+ you may not use this file except in compliance with the License.
512
+ You may obtain a copy of the License at
513
+
514
+ http://www.apache.org/licenses/LICENSE-2.0
515
+
516
+ Unless required by applicable law or agreed to in writing, software
517
+ distributed under the License is distributed on an "AS IS" BASIS,
518
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
519
+ See the License for the specific language governing permissions and
520
+ limitations under the License.
521
+ */
522
+
523
+ /**
524
+ * A class implementing the `fetchDidFail` lifecycle callback. This makes it
525
+ * easier to add failed requests to a background sync Queue.
526
+ *
527
+ * @memberof workbox.backgroundSync
528
+ */
529
+ class Plugin {
530
+ /**
531
+ * @param {...*} queueArgs Args to forward to the composed Queue instance.
532
+ * See the [Queue]{@link workbox.backgroundSync.Queue} documentation for
533
+ * parameter details.
534
+ */
535
+ constructor(...queueArgs) {
536
+ this._queue = new Queue(...queueArgs);
537
+ this.fetchDidFail = this.fetchDidFail.bind(this);
538
+ }
539
+
540
+ /**
541
+ * @param {Object} options
542
+ * @param {Request} options.request
543
+ * @private
544
+ */
545
+ fetchDidFail({ request }) {
546
+ var _this = this;
547
+
548
+ return babelHelpers.asyncToGenerator(function* () {
549
+ yield _this._queue.addRequest(request);
550
+ })();
551
+ }
552
+ }
553
+
554
+ /*
555
+ Copyright 2017 Google Inc. All Rights Reserved.
556
+ Licensed under the Apache License, Version 2.0 (the "License");
557
+ you may not use this file except in compliance with the License.
558
+ You may obtain a copy of the License at
559
+
560
+ http://www.apache.org/licenses/LICENSE-2.0
561
+
562
+ Unless required by applicable law or agreed to in writing, software
563
+ distributed under the License is distributed on an "AS IS" BASIS,
564
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
565
+ See the License for the specific language governing permissions and
566
+ limitations under the License.
567
+ */
568
+
569
+ var publicAPI = /*#__PURE__*/Object.freeze({
570
+ Queue: Queue,
571
+ Plugin: Plugin
572
+ });
573
+
574
+ /*
575
+ Copyright 2017 Google Inc. All Rights Reserved.
576
+ Licensed under the Apache License, Version 2.0 (the "License");
577
+ you may not use this file except in compliance with the License.
578
+ You may obtain a copy of the License at
579
+
580
+ http://www.apache.org/licenses/LICENSE-2.0
581
+
582
+ Unless required by applicable law or agreed to in writing, software
583
+ distributed under the License is distributed on an "AS IS" BASIS,
584
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
585
+ See the License for the specific language governing permissions and
586
+ limitations under the License.
587
+ */
588
+
589
+ return publicAPI;
590
+
591
+ }(workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private,workbox.core._private));
592
+
593
+ //# sourceMappingURL=workbox-background-sync.dev.js.map