first commit
This commit is contained in:
211
build/node_modules/sw-toolbox/lib/helpers.js
generated
vendored
Normal file
211
build/node_modules/sw-toolbox/lib/helpers.js
generated
vendored
Normal file
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var globalOptions = require('./options');
|
||||
var idbCacheExpiration = require('./idb-cache-expiration');
|
||||
|
||||
function debug(message, options) {
|
||||
options = options || {};
|
||||
var flag = options.debug || globalOptions.debug;
|
||||
if (flag) {
|
||||
console.log('[sw-toolbox] ' + message);
|
||||
}
|
||||
}
|
||||
|
||||
function openCache(options) {
|
||||
var cacheName;
|
||||
if (options && options.cache) {
|
||||
cacheName = options.cache.name;
|
||||
}
|
||||
cacheName = cacheName || globalOptions.cache.name;
|
||||
|
||||
return caches.open(cacheName);
|
||||
}
|
||||
|
||||
function fetchAndCache(request, options) {
|
||||
options = options || {};
|
||||
var successResponses = options.successResponses ||
|
||||
globalOptions.successResponses;
|
||||
|
||||
return fetch(request.clone()).then(function(response) {
|
||||
// Only cache GET requests with successful responses.
|
||||
// Since this is not part of the promise chain, it will be done
|
||||
// asynchronously and will not block the response from being returned to the
|
||||
// page.
|
||||
if (request.method === 'GET' && successResponses.test(response.status)) {
|
||||
openCache(options).then(function(cache) {
|
||||
cache.put(request, response).then(function() {
|
||||
// If any of the options are provided in options.cache then use them.
|
||||
// Do not fallback to the global options for any that are missing
|
||||
// unless they are all missing.
|
||||
var cacheOptions = options.cache || globalOptions.cache;
|
||||
|
||||
// Only run the cache expiration logic if at least one of the maximums
|
||||
// is set, and if we have a name for the cache that the options are
|
||||
// being applied to.
|
||||
if ((cacheOptions.maxEntries || cacheOptions.maxAgeSeconds) &&
|
||||
cacheOptions.name) {
|
||||
queueCacheExpiration(request, cache, cacheOptions);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return response.clone();
|
||||
});
|
||||
}
|
||||
|
||||
var cleanupQueue;
|
||||
function queueCacheExpiration(request, cache, cacheOptions) {
|
||||
var cleanup = cleanupCache.bind(null, request, cache, cacheOptions);
|
||||
|
||||
if (cleanupQueue) {
|
||||
cleanupQueue = cleanupQueue.then(cleanup);
|
||||
} else {
|
||||
cleanupQueue = cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
function cleanupCache(request, cache, cacheOptions) {
|
||||
var requestUrl = request.url;
|
||||
var maxAgeSeconds = cacheOptions.maxAgeSeconds;
|
||||
var maxEntries = cacheOptions.maxEntries;
|
||||
var cacheName = cacheOptions.name;
|
||||
|
||||
var now = Date.now();
|
||||
debug('Updating LRU order for ' + requestUrl + '. Max entries is ' +
|
||||
maxEntries + ', max age is ' + maxAgeSeconds);
|
||||
|
||||
return idbCacheExpiration.getDb(cacheName).then(function(db) {
|
||||
return idbCacheExpiration.setTimestampForUrl(db, requestUrl, now);
|
||||
}).then(function(db) {
|
||||
return idbCacheExpiration.expireEntries(db, maxEntries, maxAgeSeconds, now);
|
||||
}).then(function(urlsToDelete) {
|
||||
debug('Successfully updated IDB.');
|
||||
|
||||
var deletionPromises = urlsToDelete.map(function(urlToDelete) {
|
||||
return cache.delete(urlToDelete);
|
||||
});
|
||||
|
||||
return Promise.all(deletionPromises).then(function() {
|
||||
debug('Done with cache cleanup.');
|
||||
});
|
||||
}).catch(function(error) {
|
||||
debug(error);
|
||||
});
|
||||
}
|
||||
|
||||
function renameCache(source, destination, options) {
|
||||
debug('Renaming cache: [' + source + '] to [' + destination + ']', options);
|
||||
return caches.delete(destination).then(function() {
|
||||
return Promise.all([
|
||||
caches.open(source),
|
||||
caches.open(destination)
|
||||
]).then(function(results) {
|
||||
var sourceCache = results[0];
|
||||
var destCache = results[1];
|
||||
|
||||
return sourceCache.keys().then(function(requests) {
|
||||
return Promise.all(requests.map(function(request) {
|
||||
return sourceCache.match(request).then(function(response) {
|
||||
return destCache.put(request, response);
|
||||
});
|
||||
}));
|
||||
}).then(function() {
|
||||
return caches.delete(source);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function cache(url, options) {
|
||||
return openCache(options).then(function(cache) {
|
||||
return cache.add(url);
|
||||
});
|
||||
}
|
||||
|
||||
function uncache(url, options) {
|
||||
return openCache(options).then(function(cache) {
|
||||
return cache.delete(url);
|
||||
});
|
||||
}
|
||||
|
||||
function precache(items) {
|
||||
if (!(items instanceof Promise)) {
|
||||
validatePrecacheInput(items);
|
||||
}
|
||||
|
||||
globalOptions.preCacheItems = globalOptions.preCacheItems.concat(items);
|
||||
}
|
||||
|
||||
function validatePrecacheInput(items) {
|
||||
var isValid = Array.isArray(items);
|
||||
if (isValid) {
|
||||
items.forEach(function(item) {
|
||||
if (!(typeof item === 'string' || (item instanceof Request))) {
|
||||
isValid = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (!isValid) {
|
||||
throw new TypeError('The precache method expects either an array of ' +
|
||||
'strings and/or Requests or a Promise that resolves to an array of ' +
|
||||
'strings and/or Requests.');
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
function isResponseFresh(response, maxAgeSeconds, now) {
|
||||
// If we don't have a response, then it's not fresh.
|
||||
if (!response) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only bother checking the age of the response if maxAgeSeconds is set.
|
||||
if (maxAgeSeconds) {
|
||||
var dateHeader = response.headers.get('date');
|
||||
// If there's no Date: header, then fall through and return true.
|
||||
if (dateHeader) {
|
||||
var parsedDate = new Date(dateHeader);
|
||||
// If the Date: header was invalid for some reason, parsedDate.getTime()
|
||||
// will return NaN, and the comparison will always be false. That means
|
||||
// that an invalid date will be treated as if the response is fresh.
|
||||
if ((parsedDate.getTime() + (maxAgeSeconds * 1000)) < now) {
|
||||
// Only return false if all the other conditions are met.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Fall back on returning true by default, to match the previous behavior in
|
||||
// which we never bothered checking to see whether the response was fresh.
|
||||
return true;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
debug: debug,
|
||||
fetchAndCache: fetchAndCache,
|
||||
openCache: openCache,
|
||||
renameCache: renameCache,
|
||||
cache: cache,
|
||||
uncache: uncache,
|
||||
precache: precache,
|
||||
validatePrecacheInput: validatePrecacheInput,
|
||||
isResponseFresh: isResponseFresh
|
||||
};
|
||||
158
build/node_modules/sw-toolbox/lib/idb-cache-expiration.js
generated
vendored
Normal file
158
build/node_modules/sw-toolbox/lib/idb-cache-expiration.js
generated
vendored
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var DB_PREFIX = 'sw-toolbox-';
|
||||
var DB_VERSION = 1;
|
||||
var STORE_NAME = 'store';
|
||||
var URL_PROPERTY = 'url';
|
||||
var TIMESTAMP_PROPERTY = 'timestamp';
|
||||
var cacheNameToDbPromise = {};
|
||||
|
||||
function openDb(cacheName) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var request = indexedDB.open(DB_PREFIX + cacheName, DB_VERSION);
|
||||
|
||||
request.onupgradeneeded = function() {
|
||||
var objectStore = request.result.createObjectStore(STORE_NAME,
|
||||
{keyPath: URL_PROPERTY});
|
||||
objectStore.createIndex(TIMESTAMP_PROPERTY, TIMESTAMP_PROPERTY,
|
||||
{unique: false});
|
||||
};
|
||||
|
||||
request.onsuccess = function() {
|
||||
resolve(request.result);
|
||||
};
|
||||
|
||||
request.onerror = function() {
|
||||
reject(request.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function getDb(cacheName) {
|
||||
if (!(cacheName in cacheNameToDbPromise)) {
|
||||
cacheNameToDbPromise[cacheName] = openDb(cacheName);
|
||||
}
|
||||
|
||||
return cacheNameToDbPromise[cacheName];
|
||||
}
|
||||
|
||||
function setTimestampForUrl(db, url, now) {
|
||||
return new Promise(function(resolve, reject) {
|
||||
var transaction = db.transaction(STORE_NAME, 'readwrite');
|
||||
var objectStore = transaction.objectStore(STORE_NAME);
|
||||
objectStore.put({url: url, timestamp: now});
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
resolve(db);
|
||||
};
|
||||
|
||||
transaction.onabort = function() {
|
||||
reject(transaction.error);
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function expireOldEntries(db, maxAgeSeconds, now) {
|
||||
// Bail out early by resolving with an empty array if we're not using
|
||||
// maxAgeSeconds.
|
||||
if (!maxAgeSeconds) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var maxAgeMillis = maxAgeSeconds * 1000;
|
||||
var urls = [];
|
||||
|
||||
var transaction = db.transaction(STORE_NAME, 'readwrite');
|
||||
var objectStore = transaction.objectStore(STORE_NAME);
|
||||
var index = objectStore.index(TIMESTAMP_PROPERTY);
|
||||
|
||||
index.openCursor().onsuccess = function(cursorEvent) {
|
||||
var cursor = cursorEvent.target.result;
|
||||
if (cursor) {
|
||||
if (now - maxAgeMillis > cursor.value[TIMESTAMP_PROPERTY]) {
|
||||
var url = cursor.value[URL_PROPERTY];
|
||||
urls.push(url);
|
||||
objectStore.delete(url);
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
resolve(urls);
|
||||
};
|
||||
|
||||
transaction.onabort = reject;
|
||||
});
|
||||
}
|
||||
|
||||
function expireExtraEntries(db, maxEntries) {
|
||||
// Bail out early by resolving with an empty array if we're not using
|
||||
// maxEntries.
|
||||
if (!maxEntries) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var urls = [];
|
||||
|
||||
var transaction = db.transaction(STORE_NAME, 'readwrite');
|
||||
var objectStore = transaction.objectStore(STORE_NAME);
|
||||
var index = objectStore.index(TIMESTAMP_PROPERTY);
|
||||
|
||||
var countRequest = index.count();
|
||||
index.count().onsuccess = function() {
|
||||
var initialCount = countRequest.result;
|
||||
|
||||
if (initialCount > maxEntries) {
|
||||
index.openCursor().onsuccess = function(cursorEvent) {
|
||||
var cursor = cursorEvent.target.result;
|
||||
if (cursor) {
|
||||
var url = cursor.value[URL_PROPERTY];
|
||||
urls.push(url);
|
||||
objectStore.delete(url);
|
||||
if (initialCount - urls.length > maxEntries) {
|
||||
cursor.continue();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
transaction.oncomplete = function() {
|
||||
resolve(urls);
|
||||
};
|
||||
|
||||
transaction.onabort = reject;
|
||||
});
|
||||
}
|
||||
|
||||
function expireEntries(db, maxEntries, maxAgeSeconds, now) {
|
||||
return expireOldEntries(db, maxAgeSeconds, now).then(function(oldUrls) {
|
||||
return expireExtraEntries(db, maxEntries).then(function(extraUrls) {
|
||||
return oldUrls.concat(extraUrls);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getDb: getDb,
|
||||
setTimestampForUrl: setTimestampForUrl,
|
||||
expireEntries: expireEntries
|
||||
};
|
||||
75
build/node_modules/sw-toolbox/lib/listeners.js
generated
vendored
Normal file
75
build/node_modules/sw-toolbox/lib/listeners.js
generated
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// For cache.addAll.
|
||||
require('serviceworker-cache-polyfill');
|
||||
|
||||
var helpers = require('./helpers');
|
||||
var router = require('./router');
|
||||
var options = require('./options');
|
||||
|
||||
// Event listeners
|
||||
|
||||
function fetchListener(event) {
|
||||
var handler = router.match(event.request);
|
||||
|
||||
if (handler) {
|
||||
event.respondWith(handler(event.request));
|
||||
} else if (router.default &&
|
||||
event.request.method === 'GET' &&
|
||||
// Ensure that chrome-extension:// requests don't trigger the default route.
|
||||
event.request.url.indexOf('http') === 0) {
|
||||
event.respondWith(router.default(event.request));
|
||||
}
|
||||
}
|
||||
|
||||
function activateListener(event) {
|
||||
helpers.debug('activate event fired');
|
||||
var inactiveCache = options.cache.name + '$$$inactive$$$';
|
||||
event.waitUntil(helpers.renameCache(inactiveCache, options.cache.name));
|
||||
}
|
||||
|
||||
function flatten(items) {
|
||||
return items.reduce(function(a, b) {
|
||||
return a.concat(b);
|
||||
}, []);
|
||||
}
|
||||
|
||||
function installListener(event) {
|
||||
var inactiveCache = options.cache.name + '$$$inactive$$$';
|
||||
helpers.debug('install event fired');
|
||||
helpers.debug('creating cache [' + inactiveCache + ']');
|
||||
event.waitUntil(
|
||||
helpers.openCache({cache: {name: inactiveCache}})
|
||||
.then(function(cache) {
|
||||
return Promise.all(options.preCacheItems)
|
||||
.then(flatten)
|
||||
.then(helpers.validatePrecacheInput)
|
||||
.then(function(preCacheItems) {
|
||||
helpers.debug('preCache list: ' +
|
||||
(preCacheItems.join(', ') || '(none)'));
|
||||
return cache.addAll(preCacheItems);
|
||||
});
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
fetchListener: fetchListener,
|
||||
activateListener: activateListener,
|
||||
installListener: installListener
|
||||
};
|
||||
40
build/node_modules/sw-toolbox/lib/options.js
generated
vendored
Normal file
40
build/node_modules/sw-toolbox/lib/options.js
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// TODO: This is necessary to handle different implementations in the wild
|
||||
// The spec defines self.registration, but it was not implemented in Chrome 40.
|
||||
var scope;
|
||||
if (self.registration) {
|
||||
scope = self.registration.scope;
|
||||
} else {
|
||||
scope = self.scope || new URL('./', self.location).href;
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
cache: {
|
||||
name: '$$$toolbox-cache$$$' + scope + '$$$',
|
||||
maxAgeSeconds: null,
|
||||
maxEntries: null
|
||||
},
|
||||
debug: false,
|
||||
networkTimeoutSeconds: null,
|
||||
preCacheItems: [],
|
||||
// A regular expression to apply to HTTP response codes. Codes that match
|
||||
// will be considered successes, while others will not, and will not be
|
||||
// cached.
|
||||
successResponses: /^0|([123]\d\d)|(40[14567])|410$/
|
||||
};
|
||||
60
build/node_modules/sw-toolbox/lib/route.js
generated
vendored
Normal file
60
build/node_modules/sw-toolbox/lib/route.js
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// TODO: Use self.registration.scope instead of self.location
|
||||
var url = new URL('./', self.location);
|
||||
var basePath = url.pathname;
|
||||
var pathRegexp = require('path-to-regexp');
|
||||
|
||||
var Route = function(method, path, handler, options) {
|
||||
if (path instanceof RegExp) {
|
||||
this.fullUrlRegExp = path;
|
||||
} else {
|
||||
// The URL() constructor can't parse express-style routes as they are not
|
||||
// valid urls. This means we have to manually manipulate relative urls into
|
||||
// absolute ones. This check is extremely naive but implementing a tweaked
|
||||
// version of the full algorithm seems like overkill
|
||||
// (https://url.spec.whatwg.org/#concept-basic-url-parser)
|
||||
if (path.indexOf('/') !== 0) {
|
||||
path = basePath + path;
|
||||
}
|
||||
|
||||
this.keys = [];
|
||||
this.regexp = pathRegexp(path, this.keys);
|
||||
}
|
||||
|
||||
this.method = method;
|
||||
this.options = options;
|
||||
this.handler = handler;
|
||||
};
|
||||
|
||||
Route.prototype.makeHandler = function(url) {
|
||||
var values;
|
||||
if (this.regexp) {
|
||||
var match = this.regexp.exec(url);
|
||||
values = {};
|
||||
this.keys.forEach(function(key, index) {
|
||||
values[key.name] = match[index + 1];
|
||||
});
|
||||
}
|
||||
|
||||
return function(request) {
|
||||
return this.handler(request, values, this.options);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
module.exports = Route;
|
||||
133
build/node_modules/sw-toolbox/lib/router.js
generated
vendored
Normal file
133
build/node_modules/sw-toolbox/lib/router.js
generated
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
var Route = require('./route');
|
||||
var helpers = require('./helpers');
|
||||
|
||||
function regexEscape(s) {
|
||||
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
||||
}
|
||||
|
||||
var keyMatch = function(map, string) {
|
||||
// This would be better written as a for..of loop, but that would break the
|
||||
// minifyify process in the build.
|
||||
var entriesIterator = map.entries();
|
||||
var item = entriesIterator.next();
|
||||
var matches = [];
|
||||
while (!item.done) {
|
||||
var pattern = new RegExp(item.value[0]);
|
||||
if (pattern.test(string)) {
|
||||
matches.push(item.value[1]);
|
||||
}
|
||||
item = entriesIterator.next();
|
||||
}
|
||||
return matches;
|
||||
};
|
||||
|
||||
var Router = function() {
|
||||
this.routes = new Map();
|
||||
// Create the dummy origin for RegExp-based routes
|
||||
this.routes.set(RegExp, new Map());
|
||||
this.default = null;
|
||||
};
|
||||
|
||||
['get', 'post', 'put', 'delete', 'head', 'any'].forEach(function(method) {
|
||||
Router.prototype[method] = function(path, handler, options) {
|
||||
return this.add(method, path, handler, options);
|
||||
};
|
||||
});
|
||||
|
||||
Router.prototype.add = function(method, path, handler, options) {
|
||||
options = options || {};
|
||||
var origin;
|
||||
|
||||
if (path instanceof RegExp) {
|
||||
// We need a unique key to use in the Map to distinguish RegExp paths
|
||||
// from Express-style paths + origins. Since we can use any object as the
|
||||
// key in a Map, let's use the RegExp constructor!
|
||||
origin = RegExp;
|
||||
} else {
|
||||
origin = options.origin || self.location.origin;
|
||||
if (origin instanceof RegExp) {
|
||||
origin = origin.source;
|
||||
} else {
|
||||
origin = regexEscape(origin);
|
||||
}
|
||||
}
|
||||
|
||||
method = method.toLowerCase();
|
||||
|
||||
var route = new Route(method, path, handler, options);
|
||||
|
||||
if (!this.routes.has(origin)) {
|
||||
this.routes.set(origin, new Map());
|
||||
}
|
||||
|
||||
var methodMap = this.routes.get(origin);
|
||||
if (!methodMap.has(method)) {
|
||||
methodMap.set(method, new Map());
|
||||
}
|
||||
|
||||
var routeMap = methodMap.get(method);
|
||||
var regExp = route.regexp || route.fullUrlRegExp;
|
||||
|
||||
if (routeMap.has(regExp.source)) {
|
||||
helpers.debug('"' + path + '" resolves to same regex as existing route.');
|
||||
}
|
||||
|
||||
routeMap.set(regExp.source, route);
|
||||
};
|
||||
|
||||
Router.prototype.matchMethod = function(method, url) {
|
||||
var urlObject = new URL(url);
|
||||
var origin = urlObject.origin;
|
||||
var path = urlObject.pathname;
|
||||
|
||||
// We want to first check to see if there's a match against any
|
||||
// "Express-style" routes (string for the path, RegExp for the origin).
|
||||
// Checking for Express-style matches first maintains the legacy behavior.
|
||||
// If there's no match, we next check for a match against any RegExp routes,
|
||||
// where the RegExp in question matches the full URL (both origin and path).
|
||||
return this._match(method, keyMatch(this.routes, origin), path) ||
|
||||
this._match(method, [this.routes.get(RegExp)], url);
|
||||
};
|
||||
|
||||
Router.prototype._match = function(method, methodMaps, pathOrUrl) {
|
||||
if (methodMaps.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var i = 0; i < methodMaps.length; i++) {
|
||||
var methodMap = methodMaps[i];
|
||||
var routeMap = methodMap && methodMap.get(method.toLowerCase());
|
||||
if (routeMap) {
|
||||
var routes = keyMatch(routeMap, pathOrUrl);
|
||||
if (routes.length > 0) {
|
||||
return routes[0].makeHandler(pathOrUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
Router.prototype.match = function(request) {
|
||||
return this.matchMethod(request.method, request.url) ||
|
||||
this.matchMethod('any', request.url);
|
||||
};
|
||||
|
||||
module.exports = new Router();
|
||||
36
build/node_modules/sw-toolbox/lib/strategies/cacheFirst.js
generated
vendored
Normal file
36
build/node_modules/sw-toolbox/lib/strategies/cacheFirst.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var globalOptions = require('../options');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
function cacheFirst(request, values, options) {
|
||||
options = options || {};
|
||||
helpers.debug('Strategy: cache first [' + request.url + ']', options);
|
||||
return helpers.openCache(options).then(function(cache) {
|
||||
return cache.match(request).then(function(response) {
|
||||
var cacheOptions = options.cache || globalOptions.cache;
|
||||
var now = Date.now();
|
||||
if (helpers.isResponseFresh(response, cacheOptions.maxAgeSeconds, now)) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return helpers.fetchAndCache(request, options);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = cacheFirst;
|
||||
36
build/node_modules/sw-toolbox/lib/strategies/cacheOnly.js
generated
vendored
Normal file
36
build/node_modules/sw-toolbox/lib/strategies/cacheOnly.js
generated
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var globalOptions = require('../options');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
function cacheOnly(request, values, options) {
|
||||
options = options || {};
|
||||
helpers.debug('Strategy: cache only [' + request.url + ']', options);
|
||||
return helpers.openCache(options).then(function(cache) {
|
||||
return cache.match(request).then(function(response) {
|
||||
var cacheOptions = options.cache || globalOptions.cache;
|
||||
var now = Date.now();
|
||||
if (helpers.isResponseFresh(response, cacheOptions.maxAgeSeconds, now)) {
|
||||
return response;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = cacheOnly;
|
||||
53
build/node_modules/sw-toolbox/lib/strategies/fastest.js
generated
vendored
Normal file
53
build/node_modules/sw-toolbox/lib/strategies/fastest.js
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var helpers = require('../helpers');
|
||||
var cacheOnly = require('./cacheOnly');
|
||||
|
||||
function fastest(request, values, options) {
|
||||
helpers.debug('Strategy: fastest [' + request.url + ']', options);
|
||||
|
||||
return new Promise(function(resolve, reject) {
|
||||
var rejected = false;
|
||||
var reasons = [];
|
||||
|
||||
var maybeReject = function(reason) {
|
||||
reasons.push(reason.toString());
|
||||
if (rejected) {
|
||||
reject(new Error('Both cache and network failed: "' +
|
||||
reasons.join('", "') + '"'));
|
||||
} else {
|
||||
rejected = true;
|
||||
}
|
||||
};
|
||||
|
||||
var maybeResolve = function(result) {
|
||||
if (result instanceof Response) {
|
||||
resolve(result);
|
||||
} else {
|
||||
maybeReject('No result returned');
|
||||
}
|
||||
};
|
||||
|
||||
helpers.fetchAndCache(request.clone(), options)
|
||||
.then(maybeResolve, maybeReject);
|
||||
|
||||
cacheOnly(request, values, options)
|
||||
.then(maybeResolve, maybeReject);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = fastest;
|
||||
22
build/node_modules/sw-toolbox/lib/strategies/index.js
generated
vendored
Normal file
22
build/node_modules/sw-toolbox/lib/strategies/index.js
generated
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
module.exports = {
|
||||
networkOnly: require('./networkOnly'),
|
||||
networkFirst: require('./networkFirst'),
|
||||
cacheOnly: require('./cacheOnly'),
|
||||
cacheFirst: require('./cacheFirst'),
|
||||
fastest: require('./fastest')
|
||||
};
|
||||
97
build/node_modules/sw-toolbox/lib/strategies/networkFirst.js
generated
vendored
Normal file
97
build/node_modules/sw-toolbox/lib/strategies/networkFirst.js
generated
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
Copyright 2015 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var globalOptions = require('../options');
|
||||
var helpers = require('../helpers');
|
||||
|
||||
function networkFirst(request, values, options) {
|
||||
options = options || {};
|
||||
var successResponses = options.successResponses ||
|
||||
globalOptions.successResponses;
|
||||
// This will bypass options.networkTimeout if it's set to a false-y value like
|
||||
// 0, but that's the sane thing to do anyway.
|
||||
var networkTimeoutSeconds = options.networkTimeoutSeconds ||
|
||||
globalOptions.networkTimeoutSeconds;
|
||||
helpers.debug('Strategy: network first [' + request.url + ']', options);
|
||||
|
||||
return helpers.openCache(options).then(function(cache) {
|
||||
var timeoutId;
|
||||
var promises = [];
|
||||
var originalResponse;
|
||||
|
||||
if (networkTimeoutSeconds) {
|
||||
var cacheWhenTimedOutPromise = new Promise(function(resolve) {
|
||||
timeoutId = setTimeout(function() {
|
||||
cache.match(request).then(function(response) {
|
||||
var cacheOptions = options.cache || globalOptions.cache;
|
||||
// Only resolve this promise if there's a valid response in the
|
||||
// cache. This ensures that we won't time out a network request
|
||||
// unless there's a cached entry to fallback on, which is arguably
|
||||
// the preferable behavior.
|
||||
var now = Date.now();
|
||||
var maxAgeSeconds = cacheOptions.maxAgeSeconds;
|
||||
if (helpers.isResponseFresh(response, maxAgeSeconds, now)) {
|
||||
resolve(response);
|
||||
}
|
||||
});
|
||||
}, networkTimeoutSeconds * 1000);
|
||||
});
|
||||
promises.push(cacheWhenTimedOutPromise);
|
||||
}
|
||||
|
||||
var networkPromise = helpers.fetchAndCache(request, options)
|
||||
.then(function(response) {
|
||||
// We've got a response, so clear the network timeout if there is one.
|
||||
if (timeoutId) {
|
||||
clearTimeout(timeoutId);
|
||||
}
|
||||
|
||||
if (successResponses.test(response.status)) {
|
||||
return response;
|
||||
}
|
||||
|
||||
helpers.debug('Response was an HTTP error: ' + response.statusText,
|
||||
options);
|
||||
originalResponse = response;
|
||||
throw new Error('Bad response');
|
||||
}).catch(function(error) {
|
||||
helpers.debug('Network or response error, fallback to cache [' +
|
||||
request.url + ']', options);
|
||||
return cache.match(request).then(function(response) {
|
||||
// If there's a match in the cache, resolve with that.
|
||||
if (response) {
|
||||
return response;
|
||||
}
|
||||
|
||||
// If we have a Response object from the previous fetch, then resolve
|
||||
// with that, even though it corresponds to an error status code.
|
||||
if (originalResponse) {
|
||||
return originalResponse;
|
||||
}
|
||||
|
||||
// If we don't have a Response object from the previous fetch, likely
|
||||
// due to a network failure, then reject with the failure error.
|
||||
throw error;
|
||||
});
|
||||
});
|
||||
|
||||
promises.push(networkPromise);
|
||||
|
||||
return Promise.race(promises);
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = networkFirst;
|
||||
24
build/node_modules/sw-toolbox/lib/strategies/networkOnly.js
generated
vendored
Normal file
24
build/node_modules/sw-toolbox/lib/strategies/networkOnly.js
generated
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
var helpers = require('../helpers');
|
||||
|
||||
function networkOnly(request, values, options) {
|
||||
helpers.debug('Strategy: network only [' + request.url + ']', options);
|
||||
return fetch(request);
|
||||
}
|
||||
|
||||
module.exports = networkOnly;
|
||||
46
build/node_modules/sw-toolbox/lib/sw-toolbox.js
generated
vendored
Normal file
46
build/node_modules/sw-toolbox/lib/sw-toolbox.js
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
Copyright 2014 Google Inc. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
'use strict';
|
||||
|
||||
// This is the entrypoint for the sw-toolbox bundle. All code with
|
||||
// side effects (e.g. adding event listeners) should be in this file.
|
||||
|
||||
var options = require('./options');
|
||||
var router = require('./router');
|
||||
var helpers = require('./helpers');
|
||||
var strategies = require('./strategies');
|
||||
var listeners = require('./listeners');
|
||||
|
||||
helpers.debug('Service Worker Toolbox is loading');
|
||||
|
||||
// Set up listeners.
|
||||
|
||||
self.addEventListener('install', listeners.installListener);
|
||||
self.addEventListener('activate', listeners.activateListener);
|
||||
self.addEventListener('fetch', listeners.fetchListener);
|
||||
|
||||
module.exports = {
|
||||
networkOnly: strategies.networkOnly,
|
||||
networkFirst: strategies.networkFirst,
|
||||
cacheOnly: strategies.cacheOnly,
|
||||
cacheFirst: strategies.cacheFirst,
|
||||
fastest: strategies.fastest,
|
||||
router: router,
|
||||
options: options,
|
||||
cache: helpers.cache,
|
||||
uncache: helpers.uncache,
|
||||
precache: helpers.precache
|
||||
};
|
||||
Reference in New Issue
Block a user