workbox-background-sync
Advanced tools
Comparing version 1.0.0 to 1.1.0
@@ -22,1502 +22,56 @@ /* | ||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
class LogGroup{constructor(){this._logs=[],this._childGroups=[],this._isFallbackMode=!1;const a=/Firefox\/(\d*)\.\d*/.exec(navigator.userAgent);if(a)try{const b=parseInt(a[1],10);55>b&&(this._isFallbackMode=!0);}catch(b){this._isFallbackMode=!0;}/Edge\/\d*\.\d*/.exec(navigator.userAgent)&&(this._isFallbackMode=!0);}addPrimaryLog(a){this._primaryLog=a;}addLog(a){this._logs.push(a);}addChildGroup(a){0===a._logs.length||this._childGroups.push(a);}print(){return 0===this._logs.length&&0===this._childGroups.length?void this._printLogDetails(this._primaryLog):void(this._primaryLog&&(this._isFallbackMode?this._printLogDetails(this._primaryLog):console.groupCollapsed(...this._getLogContent(this._primaryLog))),this._logs.forEach((a)=>{this._printLogDetails(a);}),this._childGroups.forEach((a)=>{a.print();}),this._primaryLog&&!this._isFallbackMode&&console.groupEnd())}_printLogDetails(a){const b=a.logFunc?a.logFunc:console.log;b(...this._getLogContent(a));}_getLogContent(a){let b=a.message;this._isFallbackMode&&'string'==typeof b&&(b=b.replace(/%c/g,''));let c=[b];return!this._isFallbackMode&&a.colors&&(c=c.concat(a.colors)),a.args&&(c=c.concat(a.args)),c}} | ||
function isDevBuild(){return`dev`==`dev`} | ||
self.workbox=self.workbox||{},self.workbox.LOG_LEVEL=self.workbox.LOG_LEVEL||{none:-1,verbose:0,debug:1,warn:2,error:3};const LIGHT_GREY=`#bdc3c7`; const DARK_GREY=`#7f8c8d`; const LIGHT_GREEN=`#2ecc71`; const LIGHT_YELLOW=`#f1c40f`; const LIGHT_RED=`#e74c3c`; const LIGHT_BLUE=`#3498db`;class LogHelper{constructor(){this._defaultLogLevel=isDevBuild()?self.workbox.LOG_LEVEL.debug:self.workbox.LOG_LEVEL.warn;}log(a){this._printMessage(self.workbox.LOG_LEVEL.verbose,a);}debug(a){this._printMessage(self.workbox.LOG_LEVEL.debug,a);}warn(a){this._printMessage(self.workbox.LOG_LEVEL.warn,a);}error(a){this._printMessage(self.workbox.LOG_LEVEL.error,a);}_printMessage(a,b){if(this._shouldLogMessage(a,b)){const c=this._getAllLogGroups(a,b);c.print();}}_getAllLogGroups(a,b){const c=new LogGroup,d=this._getPrimaryMessageDetails(a,b);if(c.addPrimaryLog(d),b.error){const f={message:b.error,logFunc:console.error};c.addLog(f);}const e=new LogGroup;if(b.that&&b.that.constructor&&b.that.constructor.name){const f=b.that.constructor.name;e.addLog(this._getKeyValueDetails('class',f));}return b.data&&('object'!=typeof b.data||b.data instanceof Array?e.addLog(this._getKeyValueDetails('additionalData',b.data)):Object.keys(b.data).forEach((f)=>{e.addLog(this._getKeyValueDetails(f,b.data[f]));})),c.addChildGroup(e),c}_getKeyValueDetails(a,b){return{message:`%c${a}: `,colors:[`color: ${LIGHT_BLUE}`],args:b}}_getPrimaryMessageDetails(a,b){let c,d;a===self.workbox.LOG_LEVEL.verbose?(c='Info',d=LIGHT_GREY):a===self.workbox.LOG_LEVEL.debug?(c='Debug',d=LIGHT_GREEN):a===self.workbox.LOG_LEVEL.warn?(c='Warn',d=LIGHT_YELLOW):a===self.workbox.LOG_LEVEL.error?(c='Error',d=LIGHT_RED):void 0;let e=`%c🔧 %c[${c}]`;const f=[`color: ${LIGHT_GREY}`,`color: ${d}`];let g;return'string'==typeof b?g=b:b.message&&(g=b.message),g&&(g=g.replace(/\s+/g,' '),e+=`%c ${g}`,f.push(`color: ${DARK_GREY}; font-weight: normal`)),{message:e,colors:f}}_shouldLogMessage(a,b){if(!b)return!1;let c=this._defaultLogLevel;return self&&self.workbox&&'number'==typeof self.workbox.logLevel&&(c=self.workbox.logLevel),c===self.workbox.LOG_LEVEL.none||a<c?!1:!0}}var logHelper = new LogHelper; | ||
var deprecate = ((a,b,c,d)=>{Object.prototype.hasOwnProperty.call(a,b)&&(logHelper.warn(`${b} is deprecated; use ${c} instead`,{Context:d}),a[c]=a[b]);}); | ||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* A wrapper to store for an IDB connection to a particular ObjectStore. | ||
* | ||
* @private | ||
*/ | ||
class IDBHelper { | ||
constructor(name, version, storeName) { | ||
if (name == undefined || version == undefined || storeName == undefined) { | ||
throw Error('name, version, storeName must be passed to the ' + | ||
'constructor.'); | ||
} | ||
this._name = name; | ||
this._version = version; | ||
this._storeName = storeName; | ||
} | ||
/** | ||
* Returns a promise that resolves with an open connection to IndexedDB, | ||
* either existing or newly opened. | ||
* | ||
* @private | ||
* @return {Promise<DB>} | ||
*/ | ||
_getDb() { | ||
if (this._dbPromise) { | ||
return this._dbPromise; | ||
} | ||
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => { | ||
upgradeDB.createObjectStore(this._storeName); | ||
}) | ||
.then((db) => { | ||
return db; | ||
}); | ||
return this._dbPromise; | ||
} | ||
close() { | ||
if (!this._dbPromise) { | ||
return; | ||
} | ||
return this._dbPromise | ||
.then((db) => { | ||
db.close(); | ||
this._dbPromise = null; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies saving the key/value | ||
* pair to the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @param {Object} value | ||
* @return {Promise<T>} | ||
*/ | ||
put(key, value) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.put(value, key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies deleting an entry | ||
* from the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<T>} | ||
*/ | ||
delete(key) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.delete(key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting a key's value | ||
* from the object store. | ||
* Returns a promise that fulfills with the value. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<Object>} | ||
*/ | ||
get(key) { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.get(key); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the values | ||
* in an object store. | ||
* Returns a promise that fulfills with all the values. | ||
* | ||
* @private | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllValues() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAll(); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the keys | ||
* in an object store. | ||
* Returns a promise that fulfills with all the keys. | ||
* | ||
* @private | ||
* @param {String} storeName | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllKeys() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAllKeys(); | ||
}); | ||
} | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
/** | ||
* Puts the fetched response in the IDB | ||
* | ||
* @param {Object} config | ||
* @private | ||
*/ | ||
async function putResponse({hash, idbObject, response, idbQDb}) { | ||
const _idbQHelper = idbQDb; | ||
idbObject.response = { | ||
headers: JSON.stringify([...response.headers]), | ||
status: response.status, | ||
body: await response.blob(), | ||
}; | ||
_idbQHelper.put(hash, idbObject); | ||
} | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
/** | ||
* This function returns the fetched response for the given id of the request | ||
* | ||
* @memberof module:workbox-background-sync | ||
* @private | ||
* @param {String} id The ID of the request given back by the broaadcast | ||
* channel | ||
* @return {Object} response Fetched response of the request. | ||
*/ | ||
async function getResponse({id, dbName}) { | ||
const _idbQHelper = new IDBHelper(dbName, 1, 'QueueStore'); | ||
const object = await _idbQHelper.get(id); | ||
if (object && object.response) { | ||
return object.response; | ||
} else { | ||
return null; | ||
} | ||
} | ||
class IDBHelper{constructor(a,b,c){if(a==void 0||b==void 0||c==void 0)throw Error('name, version, storeName must be passed to the constructor.');this._name=a,this._version=b,this._storeName=c;}_getDb(){return this._dbPromise?this._dbPromise:(this._dbPromise=idb.open(this._name,this._version,(a)=>{a.createObjectStore(this._storeName);}).then((a)=>{return a}),this._dbPromise)}close(){return this._dbPromise?this._dbPromise.then((a)=>{a.close(),this._dbPromise=null;}):void 0}put(a,b){return this._getDb().then((c)=>{const d=c.transaction(this._storeName,'readwrite'),e=d.objectStore(this._storeName);return e.put(b,a),d.complete})}delete(a){return this._getDb().then((b)=>{const c=b.transaction(this._storeName,'readwrite'),d=c.objectStore(this._storeName);return d.delete(a),c.complete})}get(a){return this._getDb().then((b)=>{return b.transaction(this._storeName).objectStore(this._storeName).get(a)})}getAllValues(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAll()})}getAllKeys(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAllKeys()})}} | ||
const maxAge = 5*24*60*60*1000; // 5days | ||
const defaultDBName = 'bgQueueSyncDB'; | ||
const broadcastMessageAddedType = 'BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType = 'BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName = 'DEFAULT_QUEUE'; | ||
const tagNamePrefix = 'SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta = 'SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder = 'QUEUES'; | ||
const replayAllQueuesTag = 'SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
async function putResponse({hash:a,idbObject:b,response:c,idbQDb:d}){b.response={headers:JSON.stringify([...c.headers]),status:c.status,body:await c.blob()},d.put(a,b);}async function getResponse({id:a,dbName:b}){const c=new IDBHelper(b,1,'QueueStore'),d=await c.get(a);return d&&d.response?d.response:null} | ||
/** | ||
* takes a request and gives back JSON object that is storable in IDB | ||
* | ||
* @param {Request} request request object to transform | ||
* into iDB storable object | ||
* @param {Object} config config object to be | ||
* stored along in the iDB | ||
* @return {Object} indexable object for iDB | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
async function getQueueableRequest({request, config}) { | ||
let requestObject={ | ||
config, | ||
metadata: { | ||
creationTimestamp: Date.now(), | ||
}, | ||
}; | ||
requestObject.request = { | ||
url: request.url, | ||
headers: JSON.stringify([...request.headers]), | ||
mode: request.mode, | ||
method: request.method, | ||
redirect: request.redirect, | ||
credentials: request.credentials, | ||
}; | ||
const requestBody = await request.text(); | ||
if (requestBody.length > 0) { | ||
requestObject.request.body = requestBody; | ||
} | ||
return requestObject; | ||
} | ||
const maxAge=432000000; | ||
const defaultDBName='bgQueueSyncDB'; | ||
const broadcastMessageAddedType='BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType='BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName='DEFAULT_QUEUE'; | ||
const tagNamePrefix='SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta='SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder='QUEUES'; | ||
const replayAllQueuesTag='SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
/** | ||
* takes an object and return a Request object to be executed by | ||
* the browser | ||
* @param {Object} idbRequestObject | ||
* @return {Request} | ||
* @private | ||
*/ | ||
async function getFetchableRequest({idbRequestObject}) { | ||
let reqObject = { | ||
mode: idbRequestObject.mode, | ||
method: idbRequestObject.method, | ||
redirect: idbRequestObject.redirect, | ||
headers: new Headers(JSON.parse(idbRequestObject.headers)), | ||
credentials: idbRequestObject.credentials, | ||
}; | ||
if(idbRequestObject.body) { | ||
reqObject.body = idbRequestObject.body; | ||
} | ||
return new Request(idbRequestObject.url, reqObject); | ||
} | ||
async function getQueueableRequest({request:a,config:b}){let c={config:b,metadata:{creationTimestamp:Date.now()},request:{url:a.url,headers:JSON.stringify([...a.headers]),mode:a.mode,method:a.method,redirect:a.redirect,credentials:a.credentials}};const d=await a.text();return 0<d.length&&(c.request.body=d),c}async function getFetchableRequest({idbRequestObject:a}){let b={mode:a.mode,method:a.method,redirect:a.redirect,headers:new Headers(JSON.parse(a.headers)),credentials:a.credentials};return a.body&&(b.body=a.body),new Request(a.url,b)}async function cleanupQueue(a){let b=new IDBHelper(a,1,'QueueStore'),c=await b.get(allQueuesPlaceholder);return c?void(await Promise.all(c.map(async(d)=>{const e=await b.get(d);let f=[],g=[];await Promise.all(e.map(async(h)=>{const i=await b.get(h);i&&i.metadata&&i.metadata.creationTimestamp+i.config.maxAge<=Date.now()?g.push(b.delete(h)):f.push(h);})),await Promise.all(g),b.put(d,f);}))):null} | ||
/** | ||
* clean up the queue, deleting all the tasks who are either damaged or | ||
* whose maxAge has expired | ||
* | ||
* @memberOf Queue | ||
* @private | ||
* @param {string} dbName Name of database to cleanup. | ||
* @return {Promise} | ||
*/ | ||
async function cleanupQueue(dbName) { | ||
let db = new IDBHelper(dbName, 1, 'QueueStore'); | ||
let queueObj = await db.get(allQueuesPlaceholder); | ||
class RequestManager{constructor({callbacks:a,queue:b}={}){a=a||{};const c='workbox-background-sync.RequestManager.callbacks';deprecate(a,'onResponse','replayDidSucceed',c),deprecate(a,'onRetryFailure','replayDidFail',c),this._globalCallbacks=a,this._queue=b,this.attachSyncHandler();}attachSyncHandler(){self.addEventListener('sync',(a)=>{(a.tag===tagNamePrefix+this._queue.queueName||a.tag===replayAllQueuesTag)&&a.waitUntil(this.replayRequests());});}async replayRequest(a){try{const b=await this._queue.getRequestFromQueue({hash:a});if(b.response)return;const c=await getFetchableRequest({idbRequestObject:b.request}),d=await fetch(c);if(!d.ok)return Promise.reject(d);putResponse({hash:a,idbObject:b,response:d.clone(),idbQDb:this._queue.idbQDb}),this._globalCallbacks.replayDidSucceed&&this._globalCallbacks.replayDidSucceed(a,d);}catch(b){return Promise.reject(b)}}async replayRequests(){const a=[];for(let b of this._queue.queue)try{await this.replayRequest(b);}catch(c){this._globalCallbacks.replayDidFail&&this._globalCallbacks.replayDidFail(b,c),a.push(c);}return 0<a.length?Promise.reject(a):Promise.resolve()}} | ||
if(!queueObj) { | ||
return null; | ||
} | ||
var stackframe=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d();})(commonjsGlobal,function(){'use strict';function c(t){return!isNaN(parseFloat(t))&&isFinite(t)}function d(t){return t[0].toUpperCase()+t.substring(1)}function e(t){return function(){return this[t]}}function f(t){if(t instanceof Object)for(var u=0;u<o.length;u++)t.hasOwnProperty(o[u])&&void 0!==t[o[u]]&&this['set'+d(o[u])](t[o[u]]);}var g=['isConstructor','isEval','isNative','isToplevel'],h=['columnNumber','lineNumber'],l=['fileName','functionName','source'],o=g.concat(h,l,['args']);f.prototype={getArgs:function(){return this.args},setArgs:function(t){if('[object Array]'!==Object.prototype.toString.call(t))throw new TypeError('Args must be an Array');this.args=t;},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(t){if(t instanceof f)this.evalOrigin=t;else if(t instanceof Object)this.evalOrigin=new f(t);else throw new TypeError('Eval Origin must be an Object or StackFrame')},toString:function(){var t=this.getFunctionName()||'{anonymous}',u='('+(this.getArgs()||[]).join(',')+')',w=this.getFileName()?'@'+this.getFileName():'',x=c(this.getLineNumber())?':'+this.getLineNumber():'',y=c(this.getColumnNumber())?':'+this.getColumnNumber():'';return t+u+w+x+y}};for(var q=0;q<g.length;q++)f.prototype['get'+d(g[q])]=e(g[q]),f.prototype['set'+d(g[q])]=function(t){return function(u){this[t]=!!u;}}(g[q]);for(var r=0;r<h.length;r++)f.prototype['get'+d(h[r])]=e(h[r]),f.prototype['set'+d(h[r])]=function(t){return function(u){if(!c(u))throw new TypeError(t+' must be a Number');this[t]=+u;}}(h[r]);for(var s=0;s<l.length;s++)f.prototype['get'+d(l[s])]=e(l[s]),f.prototype['set'+d(l[s])]=function(t){return function(u){this[t]=u+'';}}(l[s]);return f});}); | ||
await Promise.all(queueObj.map(async (queueName)=>{ | ||
const requestQueues = await db.get(queueName); | ||
let itemsToKeep = []; | ||
let deletionPromises = []; | ||
await Promise.all(requestQueues.map( async (hash) => { | ||
const requestData = await db.get(hash); | ||
if (requestData && requestData.metadata | ||
&& requestData.metadata.creationTimestamp + requestData.config.maxAge | ||
<= Date.now()) { | ||
// Delete items that are too old. | ||
deletionPromises.push(db.delete(hash)); | ||
} else { | ||
// Keep elements whose definition exists in idb. | ||
itemsToKeep.push(hash); | ||
} | ||
})); | ||
await Promise.all(deletionPromises); | ||
db.put(queueName, itemsToKeep); | ||
})); | ||
} | ||
var errorStackParser=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d(stackframe);})(commonjsGlobal,function(d){'use strict';var f=/(^|@)\S+\:\d+/,g=/^\s*at .*(\S+\:\d+|\(native\))/m,h=/^(eval@)?(\[native code\])?$/;return{parse:function(k){if('undefined'!=typeof k.stacktrace||'undefined'!=typeof k['opera#sourceloc'])return this.parseOpera(k);if(k.stack&&k.stack.match(g))return this.parseV8OrIE(k);if(k.stack)return this.parseFFOrSafari(k);throw new Error('Cannot parse given Error object')},extractLocation:function(k){if(-1===k.indexOf(':'))return[k];var l=/(.+?)(?:\:(\d+))?(?:\:(\d+))?$/,m=l.exec(k.replace(/[\(\)]/g,''));return[m[1],m[2]||void 0,m[3]||void 0]},parseV8OrIE:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(g)},this);return l.map(function(m){-1<m.indexOf('(eval ')&&(m=m.replace(/eval code/g,'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,''));var n=m.replace(/^\s+/,'').replace(/\(eval code/g,'(').split(/\s+/).slice(1),o=this.extractLocation(n.pop()),p=n.join(' ')||void 0,q=-1<['eval','<anonymous>'].indexOf(o[0])?void 0:o[0];return new d({functionName:p,fileName:q,lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseFFOrSafari:function(k){var l=k.stack.split('\n').filter(function(m){return!m.match(h)},this);return l.map(function(m){if(-1<m.indexOf(' > eval')&&(m=m.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,':$1')),-1===m.indexOf('@')&&-1===m.indexOf(':'))return new d({functionName:m});var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.join('@')||void 0;return new d({functionName:p,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseOpera:function(k){return!k.stacktrace||-1<k.message.indexOf('\n')&&k.message.split('\n').length>k.stacktrace.split('\n').length?this.parseOpera9(k):k.stack?this.parseOpera11(k):this.parseOpera10(k)},parseOpera9:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)/i,m=k.message.split('\n'),n=[],o=2,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera10:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,m=k.stacktrace.split('\n'),n=[],o=0,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({functionName:q[3]||void 0,fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera11:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(f)&&!m.match(/^Error created at/)},this);return l.map(function(m){var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.shift()||'',q=p.replace(/<anonymous function(: (\w+))?>/,'$2').replace(/\([^\)]*\)/g,'')||void 0,r;p.match(/\(([^\)]*)\)/)&&(r=p.replace(/^[^\(]+\(([^\)]*)\)$/,'$1'));var s=r===void 0||'[arguments not available]'===r?void 0:r.split(',');return new d({functionName:q,args:s,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)}}});}); | ||
/** | ||
* Class to handle all the request related | ||
* transformations, replaying, event handling | ||
* broadcasting back to controlled pages etc. | ||
* @class | ||
* @private | ||
*/ | ||
class RequestManager { | ||
/** | ||
* Initializes the request manager | ||
* stores the callbacks object, maintains config and | ||
* attaches event handler | ||
* @param {Object=} config | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
constructor({callbacks, queue}) { | ||
this._globalCallbacks = callbacks || {}; | ||
this._queue = queue; | ||
this.attachSyncHandler(); | ||
} | ||
function isInstance(a,b){const c=Object.keys(a).pop();a[c]instanceof b||throwError(`The '${c}' parameter must be an instance of | ||
'${b.name}'`);}function isType(a,b){const c=Object.keys(a).pop(),d=typeof a[c];d!==b&&throwError(`The '${c}' parameter has the wrong type. (Expected: | ||
${b}, actual: ${d})`);}function throwError(a){a=a.replace(/\s+/g,' ');const b=new Error(a);b.name='assertion-failed';const c=errorStackParser.parse(b);throw 3<=c.length&&(b.message=`Invalid call to ${c[2].functionName}() — `+a),b} | ||
/** | ||
* attaches sync handler to replay requests when | ||
* sync event is fired | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
attachSyncHandler() { | ||
self.addEventListener('sync', (event) => { | ||
if(event.tag === tagNamePrefix + this._queue.queueName | ||
|| event.tag === replayAllQueuesTag) { | ||
event.waitUntil(this.replayRequests()); | ||
} | ||
}); | ||
} | ||
function broadcastMessage({broadcastChannel:a,type:b,url:c}){a&&(isInstance({broadcastChannel:a},BroadcastChannel),isType({type:b},'string'),isType({url:c},'string'),a.postMessage({type:b,meta:broadcastMeta,payload:{url:c}}));} | ||
/** | ||
* function to start playing requests | ||
* in sequence | ||
* @return {void} | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
replayRequests() { | ||
return this._queue.queue.reduce((promise, hash) => { | ||
return promise | ||
.then(async (item) => { | ||
const reqData = await this._queue.getRequestFromQueue({hash}); | ||
if(reqData.response) { | ||
// check if request is not played already | ||
return; | ||
} | ||
let _requestCounter=0; let _queueCounter=0;class RequestQueue{constructor({config:a,queueName:e=defaultQueueName+'_'+_queueCounter++,idbQDb:b,broadcastChannel:c,callbacks:d}){this._isQueueNameAddedToAllQueue=!1,this._queueName=e,this._config=a,this._idbQDb=b,this._broadcastChannel=c,this._globalCallbacks=d||{},this._queue=[],this.initQueue();}async initQueue(){const a=await this._idbQDb.get(this._queueName);this._queue.concat(a);}async addQueueNameToAllQueues(){if(!this._isQueueNameAddedToAllQueue){let a=await this._idbQDb.get(allQueuesPlaceholder);a=a||[],a.includes(this._queueName)||a.push(this._queueName),this._idbQDb.put(allQueuesPlaceholder,a),this._isQueueNameAddedToAllQueue=!0;}}async saveQueue(){await this._idbQDb.put(this._queueName,this._queue);}async push({request:a}){isInstance({request:a},Request);const b=`${a.url}!${Date.now()}!${_requestCounter++}`,c=await getQueueableRequest({request:a,config:this._config});this._globalCallbacks.requestWillEnqueue&&this._globalCallbacks.requestWillEnqueue(c);try{return this._queue.push(b),this.saveQueue(),this._idbQDb.put(b,c),await this.addQueueNameToAllQueues(),self.registration&&self.registration.sync.register(tagNamePrefix+this._queueName),broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageAddedType,id:b,url:a.url}),b}catch(d){return broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageFailedType,id:b,url:a.url}),d}}async getRequestFromQueue({hash:a}){if(isType({hash:a},'string'),this._queue.includes(a)){const b=await this._idbQDb.get(a);return this._globalCallbacks.requestWillDequeue&&this._globalCallbacks.requestWillDequeue(b),b}}get queue(){return Object.assign([],this._queue)}get queueName(){return this._queueName}get idbQDb(){return this._idbQDb}} | ||
const request = await getFetchableRequest({ | ||
idbRequestObject: reqData.request, | ||
}); | ||
class Queue{constructor({broadcastChannel:a,callbacks:b,queueName:c,dbName:d=defaultDBName,maxRetentionTime:e=maxAge}={}){c&&isType({queueName:c},'string'),e&&isType({maxRetentionTime:e},'number'),a&&isInstance({broadcastChannel:a},BroadcastChannel),isType({dbName:d},'string'),this._dbName=d,this._queue=new RequestQueue({config:{maxAge:e},queueName:c,idbQDb:new IDBHelper(this._dbName,1,'QueueStore'),broadcastChannel:a,callbacks:b}),this._requestManager=new RequestManager({callbacks:b,queue:this._queue}),this.cleanupQueue();}cleanupQueue(){return cleanupQueue(this._dbName)}pushIntoQueue({request:a}){return isInstance({request:a},Request),this._queue.push({request:a})}replayRequests(){return this._requestManager.replayRequests()}getResponse({id:a}){return getResponse({id:a,dbName:this._dbName})}} | ||
return fetch(request) | ||
.then((response)=>{ | ||
if(!response.ok) { | ||
return Promise.resolve(); | ||
} else { | ||
// not blocking on putResponse. | ||
putResponse({ | ||
hash, | ||
idbObject: reqData, | ||
response: response.clone(), | ||
idbQDb: this._queue.idbQDb, | ||
}); | ||
this._globalCallbacks.onResponse | ||
&& this._globalCallbacks.onResponse(hash, response); | ||
} | ||
}) | ||
.catch((err)=>{ | ||
this._globalCallbacks.onRetryFailure | ||
&& this._globalCallbacks.onRetryFailure(hash, err); | ||
}); | ||
}); | ||
}, Promise.resolve()); | ||
} | ||
} | ||
class QueuePlugin extends Queue{fetchDidFail({request:a}){return this.pushIntoQueue({request:a})}} | ||
var stackframe = createCommonjsModule(function (module, exports) { | ||
(function (root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('stackframe', [], factory); | ||
} else { | ||
module.exports = factory(); | ||
} | ||
}(commonjsGlobal, function () { | ||
'use strict'; | ||
function _isNumber(n) { | ||
return !isNaN(parseFloat(n)) && isFinite(n); | ||
} | ||
function _capitalize(str) { | ||
return str[0].toUpperCase() + str.substring(1); | ||
} | ||
function _getter(p) { | ||
return function () { | ||
return this[p]; | ||
}; | ||
} | ||
var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel']; | ||
var numericProps = ['columnNumber', 'lineNumber']; | ||
var stringProps = ['fileName', 'functionName', 'source']; | ||
var arrayProps = ['args']; | ||
function StackFrame(obj) { | ||
if (obj instanceof Object) { | ||
var props = booleanProps.concat(numericProps.concat(stringProps.concat(arrayProps))); | ||
for (var i = 0; i < props.length; i++) { | ||
if (obj.hasOwnProperty(props[i]) && obj[props[i]] !== undefined) { | ||
this['set' + _capitalize(props[i])](obj[props[i]]); | ||
} | ||
} | ||
} | ||
} | ||
StackFrame.prototype = { | ||
getArgs: function () { | ||
return this.args; | ||
}, | ||
setArgs: function (v) { | ||
if (Object.prototype.toString.call(v) !== '[object Array]') { | ||
throw new TypeError('Args must be an Array'); | ||
} | ||
this.args = v; | ||
}, | ||
getEvalOrigin: function () { | ||
return this.evalOrigin; | ||
}, | ||
setEvalOrigin: function (v) { | ||
if (v instanceof StackFrame) { | ||
this.evalOrigin = v; | ||
} else if (v instanceof Object) { | ||
this.evalOrigin = new StackFrame(v); | ||
} else { | ||
throw new TypeError('Eval Origin must be an Object or StackFrame'); | ||
} | ||
}, | ||
toString: function () { | ||
var functionName = this.getFunctionName() || '{anonymous}'; | ||
var args = '(' + (this.getArgs() || []).join(',') + ')'; | ||
var fileName = this.getFileName() ? ('@' + this.getFileName()) : ''; | ||
var lineNumber = _isNumber(this.getLineNumber()) ? (':' + this.getLineNumber()) : ''; | ||
var columnNumber = _isNumber(this.getColumnNumber()) ? (':' + this.getColumnNumber()) : ''; | ||
return functionName + args + fileName + lineNumber + columnNumber; | ||
} | ||
}; | ||
for (var i = 0; i < booleanProps.length; i++) { | ||
StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]); | ||
StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function (p) { | ||
return function (v) { | ||
this[p] = Boolean(v); | ||
}; | ||
})(booleanProps[i]); | ||
} | ||
for (var j = 0; j < numericProps.length; j++) { | ||
StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]); | ||
StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function (p) { | ||
return function (v) { | ||
if (!_isNumber(v)) { | ||
throw new TypeError(p + ' must be a Number'); | ||
} | ||
this[p] = Number(v); | ||
}; | ||
})(numericProps[j]); | ||
} | ||
for (var k = 0; k < stringProps.length; k++) { | ||
StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]); | ||
StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function (p) { | ||
return function (v) { | ||
this[p] = String(v); | ||
}; | ||
})(stringProps[k]); | ||
} | ||
return StackFrame; | ||
})); | ||
}); | ||
var errorStackParser = createCommonjsModule(function (module, exports) { | ||
(function(root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('error-stack-parser', ['stackframe'], factory); | ||
} else { | ||
module.exports = factory(stackframe); | ||
} | ||
}(commonjsGlobal, function ErrorStackParser(StackFrame) { | ||
'use strict'; | ||
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+\:\d+/; | ||
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+\:\d+|\(native\))/m; | ||
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/; | ||
return { | ||
/** | ||
* Given an Error object, extract the most information from it. | ||
* | ||
* @param {Error} error object | ||
* @return {Array} of StackFrames | ||
*/ | ||
parse: function ErrorStackParser$$parse(error) { | ||
if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') { | ||
return this.parseOpera(error); | ||
} else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { | ||
return this.parseV8OrIE(error); | ||
} else if (error.stack) { | ||
return this.parseFFOrSafari(error); | ||
} else { | ||
throw new Error('Cannot parse given Error object'); | ||
} | ||
}, | ||
// Separate line and column numbers from a string of the form: (URI:Line:Column) | ||
extractLocation: function ErrorStackParser$$extractLocation(urlLike) { | ||
// Fail-fast but return locations like "(native)" | ||
if (urlLike.indexOf(':') === -1) { | ||
return [urlLike]; | ||
} | ||
var regExp = /(.+?)(?:\:(\d+))?(?:\:(\d+))?$/; | ||
var parts = regExp.exec(urlLike.replace(/[\(\)]/g, '')); | ||
return [parts[1], parts[2] || undefined, parts[3] || undefined]; | ||
}, | ||
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(CHROME_IE_STACK_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
if (line.indexOf('(eval ') > -1) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g, ''); | ||
} | ||
var tokens = line.replace(/^\s+/, '').replace(/\(eval code/g, '(').split(/\s+/).slice(1); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join(' ') || undefined; | ||
var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0]; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: fileName, | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
}, | ||
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !line.match(SAFARI_NATIVE_CODE_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
if (line.indexOf(' > eval') > -1) { | ||
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g, ':$1'); | ||
} | ||
if (line.indexOf('@') === -1 && line.indexOf(':') === -1) { | ||
// Safari eval frames only have function names and nothing else | ||
return new StackFrame({ | ||
functionName: line | ||
}); | ||
} else { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join('@') || undefined; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
} | ||
}, this); | ||
}, | ||
parseOpera: function ErrorStackParser$$parseOpera(e) { | ||
if (!e.stacktrace || (e.message.indexOf('\n') > -1 && | ||
e.message.split('\n').length > e.stacktrace.split('\n').length)) { | ||
return this.parseOpera9(e); | ||
} else if (!e.stack) { | ||
return this.parseOpera10(e); | ||
} else { | ||
return this.parseOpera11(e); | ||
} | ||
}, | ||
parseOpera9: function ErrorStackParser$$parseOpera9(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)/i; | ||
var lines = e.message.split('\n'); | ||
var result = []; | ||
for (var i = 2, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push(new StackFrame({ | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
})); | ||
} | ||
} | ||
return result; | ||
}, | ||
parseOpera10: function ErrorStackParser$$parseOpera10(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i; | ||
var lines = e.stacktrace.split('\n'); | ||
var result = []; | ||
for (var i = 0, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push( | ||
new StackFrame({ | ||
functionName: match[3] || undefined, | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
}) | ||
); | ||
} | ||
} | ||
return result; | ||
}, | ||
// Opera 10.65+ Error.stack very similar to FF/Safari | ||
parseOpera11: function ErrorStackParser$$parseOpera11(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/); | ||
}, this); | ||
return filtered.map(function(line) { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionCall = (tokens.shift() || ''); | ||
var functionName = functionCall | ||
.replace(/<anonymous function(: (\w+))?>/, '$2') | ||
.replace(/\([^\)]*\)/g, '') || undefined; | ||
var argsRaw; | ||
if (functionCall.match(/\(([^\)]*)\)/)) { | ||
argsRaw = functionCall.replace(/^[^\(]+\(([^\)]*)\)$/, '$1'); | ||
} | ||
var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ? | ||
undefined : argsRaw.split(','); | ||
return new StackFrame({ | ||
functionName: functionName, | ||
args: args, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
} | ||
}; | ||
})); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
function atLeastOne(object) { | ||
const parameters = Object.keys(object); | ||
if (!parameters.some((parameter) => object[parameter] !== undefined)) { | ||
throwError('Please set at least one of the following parameters: ' + | ||
parameters.map((p) => `'${p}'`).join(', ')); | ||
} | ||
} | ||
function hasMethod(object, expectedMethod) { | ||
const parameter = Object.keys(object).pop(); | ||
const type = typeof object[parameter][expectedMethod]; | ||
if (type !== 'function') { | ||
throwError(`The '${parameter}' parameter must be an object that exposes a | ||
'${expectedMethod}' method.`); | ||
} | ||
} | ||
function isInstance(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!(object[parameter] instanceof expectedClass)) { | ||
throwError(`The '${parameter}' parameter must be an instance of | ||
'${expectedClass.name}'`); | ||
} | ||
} | ||
function isOneOf(object, values) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!values.includes(object[parameter])) { | ||
throwError(`The '${parameter}' parameter must be set to one of the | ||
following: ${values}`); | ||
} | ||
} | ||
function isType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualType = typeof object[parameter]; | ||
if (actualType !== expectedType) { | ||
throwError(`The '${parameter}' parameter has the wrong type. (Expected: | ||
${expectedType}, actual: ${actualType})`); | ||
} | ||
} | ||
function isArrayOfType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedType}' elements.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (typeof item !== expectedType) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isArrayOfClass(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedClass.name}' instances.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (!(item instanceof expectedClass)) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isValue(object, expectedValue) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualValue = object[parameter]; | ||
if (actualValue !== expectedValue) { | ||
throwError(`The '${parameter}' parameter has the wrong value. (Expected: | ||
${expectedValue}, actual: ${actualValue})`); | ||
} | ||
} | ||
function throwError(message) { | ||
// Collapse any newlines or whitespace into a single space. | ||
message = message.replace(/\s+/g, ' '); | ||
const error = new Error(message); | ||
error.name = 'assertion-failed'; | ||
const stackFrames = errorStackParser.parse(error); | ||
// If, for some reason, we don't have all the stack information we need, | ||
// we'll just end up throwing a basic Error. | ||
if (stackFrames.length >= 3) { | ||
// Assuming we have the stack frames, set the message to include info | ||
// about what the underlying method was, and set the name to reflect | ||
// the assertion type that failed. | ||
error.message = `Invalid call to ${stackFrames[2].functionName}() — ` + | ||
message; | ||
} | ||
throw error; | ||
} | ||
var assert = { | ||
atLeastOne, | ||
hasMethod, | ||
isInstance, | ||
isOneOf, | ||
isType, | ||
isValue, | ||
isArrayOfType, | ||
isArrayOfClass, | ||
}; | ||
/** | ||
* broadcasts the message with the given type and url | ||
* | ||
* @param {BroadcastChannel} broadcastChannel which is used to push the | ||
* updates on | ||
* @param {Object} input | ||
* @param {string} input.type Type of the message (either success or failure) | ||
* @param {string} input.url Url for which the request was queued | ||
* @private | ||
*/ | ||
function broadcastMessage({broadcastChannel, type, url}) { | ||
if(!broadcastChannel) | ||
return; | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
assert.isType({type}, 'string'); | ||
assert.isType({url}, 'string'); | ||
broadcastChannel.postMessage({ | ||
type: type, | ||
meta: broadcastMeta, | ||
payload: { | ||
url: url, | ||
}, | ||
}); | ||
} | ||
let _requestCounter = 0; | ||
let _queueCounter = 0; | ||
/** | ||
* Queue class to maintain and perform on the logical requests queue | ||
* | ||
* @class RequestQueue | ||
* @private | ||
*/ | ||
class RequestQueue { | ||
/** | ||
* Creates an instance of RequestQueue. | ||
* | ||
* @param {Object} config | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
constructor({ | ||
config, | ||
queueName = defaultQueueName + '_' + _queueCounter++, | ||
idbQDb, | ||
broadcastChannel, | ||
}) { | ||
this._isQueueNameAddedToAllQueue = false; | ||
this._queueName = queueName; | ||
this._config = config; | ||
this._idbQDb = idbQDb; | ||
this._broadcastChannel = broadcastChannel; | ||
this._queue = []; | ||
this.initQueue(); | ||
} | ||
/** | ||
* initializes the queue from the IDB store | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async initQueue() { | ||
const idbQueue = await this._idbQDb.get(this._queueName); | ||
this._queue.concat(idbQueue); | ||
} | ||
/** | ||
* adds the current queueName to all queue array | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async addQueueNameToAllQueues() { | ||
if(!this._isQueueNameAddedToAllQueue) { | ||
let allQueues = await this._idbQDb.get(allQueuesPlaceholder); | ||
allQueues = allQueues || []; | ||
if(!allQueues.includes(this._queueName)) { | ||
allQueues.push(this._queueName); | ||
} | ||
this._idbQDb.put(allQueuesPlaceholder, allQueues); | ||
this._isQueueNameAddedToAllQueue = true; | ||
} | ||
} | ||
/** | ||
* saves the logical queue to IDB | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async saveQueue() { | ||
await this._idbQDb.put(this._queueName, this._queue); | ||
} | ||
/** | ||
* push any request to background sync queue which would be played later | ||
* preferably when network comes back | ||
* | ||
* @param {Request} request request object to be queued by this | ||
* | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async push({request}) { | ||
assert.isInstance({request}, Request); | ||
const hash = `${request.url}!${Date.now()}!${_requestCounter++}`; | ||
const queuableRequest = | ||
await getQueueableRequest({ | ||
request, | ||
config: this._config, | ||
}); | ||
try{ | ||
this._queue.push(hash); | ||
// add to queue | ||
this.saveQueue(); | ||
this._idbQDb.put(hash, queuableRequest); | ||
await this.addQueueNameToAllQueues(); | ||
// register sync | ||
self.registration && | ||
self.registration.sync.register(tagNamePrefix + this._queueName); | ||
// broadcast the success of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageAddedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} catch(e) { | ||
// broadcast the failure of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageFailedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} | ||
} | ||
/** | ||
* get the Request from the queue at a particular index | ||
* | ||
* @param {string} hash hash of the request at the given index | ||
* @return {Request} request object corresponding to given hash | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async getRequestFromQueue({hash}) { | ||
assert.isType({hash}, 'string'); | ||
if(this._queue.includes(hash)) { | ||
return await this._idbQDb.get(hash); | ||
} | ||
} | ||
/** | ||
* returns the instance of queue. | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queue() { | ||
return Object.assign([], this._queue); | ||
} | ||
/** | ||
* returns the name of the current queue | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queueName() { | ||
return this._queueName; | ||
} | ||
/** | ||
* returns the instance of IDBStore | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get idbQDb() { | ||
return this._idbQDb; | ||
} | ||
} | ||
/** | ||
* Use the instance of this class to push the failed requests into the queue. | ||
* | ||
* @example | ||
* When you want to push the requests manually | ||
* let bgQueue = new workbox.backgroundSync.Queue(); | ||
* self.addEventListener('fetch', function(e) { | ||
* if (!e.request.url.startsWith('https://jsonplaceholder.typicode.com')) { | ||
* return; | ||
* } | ||
* | ||
* const clone = e.request.clone(); | ||
* e.respondWith(fetch(e.request).catch((err)=>{ | ||
* bgQueue.pushIntoQueue({ | ||
* request: clone, | ||
* }); | ||
* throw err; | ||
* })); | ||
* }); | ||
* | ||
* @memberof module:workbox-background-sync | ||
*/ | ||
class Queue { | ||
/** | ||
* Creates an instance of Queue with the given options | ||
* | ||
* @param {Object} [input] | ||
* @param {Number} [input.maxRetentionTime = 5 days] Time for which a queued | ||
* request will live in the queue(irespective of failed/success of replay). | ||
* @param {Object} [input.callbacks] Callbacks for successfull/ failed | ||
* replay of a request. | ||
* @param {string} [input.queueName] Queue name inside db in which | ||
* requests will be queued. | ||
* @param {BroadcastChannel=} [input.broadcastChannel] BroadcastChannel | ||
* which will be used to publish messages when the request will be queued. | ||
*/ | ||
constructor({maxRetentionTime = maxAge, callbacks, queueName, | ||
broadcastChannel, dbName = defaultDBName} = {}) { | ||
if(queueName) { | ||
assert.isType({queueName}, 'string'); | ||
} | ||
if(maxRetentionTime) { | ||
assert.isType({maxRetentionTime}, 'number'); | ||
} | ||
if(broadcastChannel) { | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
} | ||
assert.isType({dbName}, 'string'); | ||
this._dbName = dbName; | ||
this._queue = new RequestQueue({ | ||
config: { | ||
maxAge: maxRetentionTime, | ||
}, | ||
queueName, | ||
idbQDb: new IDBHelper(this._dbName, 1, 'QueueStore'), | ||
broadcastChannel, | ||
}); | ||
this._requestManager = new RequestManager({callbacks, | ||
queue: this._queue}); | ||
this.cleanupQueue(); | ||
} | ||
/** | ||
* clean up the queue, deleting all the tasks whose maxAge has expired | ||
* | ||
* @memberOf Queue | ||
* @private | ||
* @return {Promise} | ||
*/ | ||
cleanupQueue() { | ||
return cleanupQueue(this._dbName); | ||
} | ||
/** | ||
* This function pushes a given request into the IndexedDb Queue. | ||
* | ||
* @param {Object} input | ||
* @param {Request} input.request The request which is to be queued | ||
* | ||
* @return {Promise} Promise which resolves when the request is pushed in | ||
* the queue. | ||
*/ | ||
pushIntoQueue({request}) { | ||
assert.isInstance({request}, Request); | ||
return this._queue.push({request}); | ||
} | ||
/** | ||
* Replays all the requests in the queue, this can be used for custom timing | ||
* of replaying requests may be in an environment where sync event is not | ||
* supported. | ||
* @return {Promise} A listener for when the requests have been replayed. | ||
*/ | ||
replayRequests() { | ||
return this._requestManager.replayRequests(); | ||
} | ||
/** | ||
* Sets the dbName, which is used to store the queue and requests | ||
* defaults to bgQueueSyncDB. | ||
* @param {String} id The ID of the request. | ||
* @return {Object} Fetched response of the request. | ||
*/ | ||
getResponse({id}) { | ||
return getResponse({ | ||
id, | ||
dbName: this._dbName, | ||
}); | ||
} | ||
} | ||
/** | ||
* Use the instance of this class to push the failed requests into the queue. | ||
* | ||
* @example <caption>When you want the workbox-sw framework to take care of | ||
* failed requests.</caption> | ||
* let bgQueue = new workbox.backgroundSync.QueuePlugin({ | ||
* callbacks: { | ||
* onResponse: async(hash, res) => { | ||
* self.registration.showNotification('Background sync demo', { | ||
* body: 'Product has been purchased.', | ||
* icon: '/images/shop-icon-384.png', | ||
* }); | ||
* }, | ||
* onRetryFailure: (hash) => {}, | ||
* }, | ||
* }); | ||
* | ||
* const requestWrapper = new workbox.runtimeCaching.RequestWrapper({ | ||
* plugins: [bgQueue], | ||
* }); | ||
* | ||
* const route = new workbox.routing.RegExpRoute({ | ||
* regExp: new RegExp('^https://jsonplaceholder.typicode.com'), | ||
* handler: new workbox.runtimeCaching.NetworkOnly({requestWrapper}), | ||
* }); | ||
* | ||
* const router = new workbox.routing.Router(); | ||
* router.registerRoute({route}); | ||
* | ||
* @memberof module:workbox-background-sync | ||
* @extends module:workbox-background-sync.Queue | ||
*/ | ||
class QueuePlugin extends Queue { | ||
/** | ||
* Wraps `pushIntoQueue` in a callback used by higher level framework. | ||
* This function pushes a given request into the IndexedDb Queue. | ||
* NOTE: If you are writting the fetch handler for background sync manually, | ||
* please ignore this. | ||
* | ||
* @param {Object} input | ||
* @param {Request} input.request The request which is to be queued | ||
* | ||
* @return {Promise} Promise which resolves when the request is pushed in | ||
* the queue. | ||
*/ | ||
fetchDidFail({request}) { | ||
return this.pushIntoQueue({request}); | ||
} | ||
} | ||
return QueuePlugin; | ||
@@ -1524,0 +78,0 @@ |
@@ -22,1452 +22,54 @@ /* | ||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
class LogGroup{constructor(){this._logs=[],this._childGroups=[],this._isFallbackMode=!1;const a=/Firefox\/(\d*)\.\d*/.exec(navigator.userAgent);if(a)try{const b=parseInt(a[1],10);55>b&&(this._isFallbackMode=!0);}catch(b){this._isFallbackMode=!0;}/Edge\/\d*\.\d*/.exec(navigator.userAgent)&&(this._isFallbackMode=!0);}addPrimaryLog(a){this._primaryLog=a;}addLog(a){this._logs.push(a);}addChildGroup(a){0===a._logs.length||this._childGroups.push(a);}print(){return 0===this._logs.length&&0===this._childGroups.length?void this._printLogDetails(this._primaryLog):void(this._primaryLog&&(this._isFallbackMode?this._printLogDetails(this._primaryLog):console.groupCollapsed(...this._getLogContent(this._primaryLog))),this._logs.forEach((a)=>{this._printLogDetails(a);}),this._childGroups.forEach((a)=>{a.print();}),this._primaryLog&&!this._isFallbackMode&&console.groupEnd())}_printLogDetails(a){const b=a.logFunc?a.logFunc:console.log;b(...this._getLogContent(a));}_getLogContent(a){let b=a.message;this._isFallbackMode&&'string'==typeof b&&(b=b.replace(/%c/g,''));let c=[b];return!this._isFallbackMode&&a.colors&&(c=c.concat(a.colors)),a.args&&(c=c.concat(a.args)),c}} | ||
function isDevBuild(){return`dev`==`dev`} | ||
self.workbox=self.workbox||{},self.workbox.LOG_LEVEL=self.workbox.LOG_LEVEL||{none:-1,verbose:0,debug:1,warn:2,error:3};const LIGHT_GREY=`#bdc3c7`; const DARK_GREY=`#7f8c8d`; const LIGHT_GREEN=`#2ecc71`; const LIGHT_YELLOW=`#f1c40f`; const LIGHT_RED=`#e74c3c`; const LIGHT_BLUE=`#3498db`;class LogHelper{constructor(){this._defaultLogLevel=isDevBuild()?self.workbox.LOG_LEVEL.debug:self.workbox.LOG_LEVEL.warn;}log(a){this._printMessage(self.workbox.LOG_LEVEL.verbose,a);}debug(a){this._printMessage(self.workbox.LOG_LEVEL.debug,a);}warn(a){this._printMessage(self.workbox.LOG_LEVEL.warn,a);}error(a){this._printMessage(self.workbox.LOG_LEVEL.error,a);}_printMessage(a,b){if(this._shouldLogMessage(a,b)){const c=this._getAllLogGroups(a,b);c.print();}}_getAllLogGroups(a,b){const c=new LogGroup,d=this._getPrimaryMessageDetails(a,b);if(c.addPrimaryLog(d),b.error){const f={message:b.error,logFunc:console.error};c.addLog(f);}const e=new LogGroup;if(b.that&&b.that.constructor&&b.that.constructor.name){const f=b.that.constructor.name;e.addLog(this._getKeyValueDetails('class',f));}return b.data&&('object'!=typeof b.data||b.data instanceof Array?e.addLog(this._getKeyValueDetails('additionalData',b.data)):Object.keys(b.data).forEach((f)=>{e.addLog(this._getKeyValueDetails(f,b.data[f]));})),c.addChildGroup(e),c}_getKeyValueDetails(a,b){return{message:`%c${a}: `,colors:[`color: ${LIGHT_BLUE}`],args:b}}_getPrimaryMessageDetails(a,b){let c,d;a===self.workbox.LOG_LEVEL.verbose?(c='Info',d=LIGHT_GREY):a===self.workbox.LOG_LEVEL.debug?(c='Debug',d=LIGHT_GREEN):a===self.workbox.LOG_LEVEL.warn?(c='Warn',d=LIGHT_YELLOW):a===self.workbox.LOG_LEVEL.error?(c='Error',d=LIGHT_RED):void 0;let e=`%c🔧 %c[${c}]`;const f=[`color: ${LIGHT_GREY}`,`color: ${d}`];let g;return'string'==typeof b?g=b:b.message&&(g=b.message),g&&(g=g.replace(/\s+/g,' '),e+=`%c ${g}`,f.push(`color: ${DARK_GREY}; font-weight: normal`)),{message:e,colors:f}}_shouldLogMessage(a,b){if(!b)return!1;let c=this._defaultLogLevel;return self&&self.workbox&&'number'==typeof self.workbox.logLevel&&(c=self.workbox.logLevel),c===self.workbox.LOG_LEVEL.none||a<c?!1:!0}}var logHelper = new LogHelper; | ||
var deprecate = ((a,b,c,d)=>{Object.prototype.hasOwnProperty.call(a,b)&&(logHelper.warn(`${b} is deprecated; use ${c} instead`,{Context:d}),a[c]=a[b]);}); | ||
var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* A wrapper to store for an IDB connection to a particular ObjectStore. | ||
* | ||
* @private | ||
*/ | ||
class IDBHelper { | ||
constructor(name, version, storeName) { | ||
if (name == undefined || version == undefined || storeName == undefined) { | ||
throw Error('name, version, storeName must be passed to the ' + | ||
'constructor.'); | ||
} | ||
this._name = name; | ||
this._version = version; | ||
this._storeName = storeName; | ||
} | ||
/** | ||
* Returns a promise that resolves with an open connection to IndexedDB, | ||
* either existing or newly opened. | ||
* | ||
* @private | ||
* @return {Promise<DB>} | ||
*/ | ||
_getDb() { | ||
if (this._dbPromise) { | ||
return this._dbPromise; | ||
} | ||
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => { | ||
upgradeDB.createObjectStore(this._storeName); | ||
}) | ||
.then((db) => { | ||
return db; | ||
}); | ||
return this._dbPromise; | ||
} | ||
close() { | ||
if (!this._dbPromise) { | ||
return; | ||
} | ||
return this._dbPromise | ||
.then((db) => { | ||
db.close(); | ||
this._dbPromise = null; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies saving the key/value | ||
* pair to the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @param {Object} value | ||
* @return {Promise<T>} | ||
*/ | ||
put(key, value) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.put(value, key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies deleting an entry | ||
* from the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<T>} | ||
*/ | ||
delete(key) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.delete(key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting a key's value | ||
* from the object store. | ||
* Returns a promise that fulfills with the value. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<Object>} | ||
*/ | ||
get(key) { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.get(key); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the values | ||
* in an object store. | ||
* Returns a promise that fulfills with all the values. | ||
* | ||
* @private | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllValues() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAll(); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the keys | ||
* in an object store. | ||
* Returns a promise that fulfills with all the keys. | ||
* | ||
* @private | ||
* @param {String} storeName | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllKeys() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAllKeys(); | ||
}); | ||
} | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
/** | ||
* Puts the fetched response in the IDB | ||
* | ||
* @param {Object} config | ||
* @private | ||
*/ | ||
async function putResponse({hash, idbObject, response, idbQDb}) { | ||
const _idbQHelper = idbQDb; | ||
idbObject.response = { | ||
headers: JSON.stringify([...response.headers]), | ||
status: response.status, | ||
body: await response.blob(), | ||
}; | ||
_idbQHelper.put(hash, idbObject); | ||
} | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
/** | ||
* This function returns the fetched response for the given id of the request | ||
* | ||
* @memberof module:workbox-background-sync | ||
* @private | ||
* @param {String} id The ID of the request given back by the broaadcast | ||
* channel | ||
* @return {Object} response Fetched response of the request. | ||
*/ | ||
async function getResponse({id, dbName}) { | ||
const _idbQHelper = new IDBHelper(dbName, 1, 'QueueStore'); | ||
const object = await _idbQHelper.get(id); | ||
if (object && object.response) { | ||
return object.response; | ||
} else { | ||
return null; | ||
} | ||
} | ||
class IDBHelper{constructor(a,b,c){if(a==void 0||b==void 0||c==void 0)throw Error('name, version, storeName must be passed to the constructor.');this._name=a,this._version=b,this._storeName=c;}_getDb(){return this._dbPromise?this._dbPromise:(this._dbPromise=idb.open(this._name,this._version,(a)=>{a.createObjectStore(this._storeName);}).then((a)=>{return a}),this._dbPromise)}close(){return this._dbPromise?this._dbPromise.then((a)=>{a.close(),this._dbPromise=null;}):void 0}put(a,b){return this._getDb().then((c)=>{const d=c.transaction(this._storeName,'readwrite'),e=d.objectStore(this._storeName);return e.put(b,a),d.complete})}delete(a){return this._getDb().then((b)=>{const c=b.transaction(this._storeName,'readwrite'),d=c.objectStore(this._storeName);return d.delete(a),c.complete})}get(a){return this._getDb().then((b)=>{return b.transaction(this._storeName).objectStore(this._storeName).get(a)})}getAllValues(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAll()})}getAllKeys(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAllKeys()})}} | ||
const maxAge = 5*24*60*60*1000; // 5days | ||
const defaultDBName = 'bgQueueSyncDB'; | ||
const broadcastMessageAddedType = 'BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType = 'BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName = 'DEFAULT_QUEUE'; | ||
const tagNamePrefix = 'SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta = 'SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder = 'QUEUES'; | ||
const replayAllQueuesTag = 'SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
async function putResponse({hash:a,idbObject:b,response:c,idbQDb:d}){b.response={headers:JSON.stringify([...c.headers]),status:c.status,body:await c.blob()},d.put(a,b);}async function getResponse({id:a,dbName:b}){const c=new IDBHelper(b,1,'QueueStore'),d=await c.get(a);return d&&d.response?d.response:null} | ||
/** | ||
* takes a request and gives back JSON object that is storable in IDB | ||
* | ||
* @param {Request} request request object to transform | ||
* into iDB storable object | ||
* @param {Object} config config object to be | ||
* stored along in the iDB | ||
* @return {Object} indexable object for iDB | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
async function getQueueableRequest({request, config}) { | ||
let requestObject={ | ||
config, | ||
metadata: { | ||
creationTimestamp: Date.now(), | ||
}, | ||
}; | ||
requestObject.request = { | ||
url: request.url, | ||
headers: JSON.stringify([...request.headers]), | ||
mode: request.mode, | ||
method: request.method, | ||
redirect: request.redirect, | ||
credentials: request.credentials, | ||
}; | ||
const requestBody = await request.text(); | ||
if (requestBody.length > 0) { | ||
requestObject.request.body = requestBody; | ||
} | ||
return requestObject; | ||
} | ||
const maxAge=432000000; | ||
const defaultDBName='bgQueueSyncDB'; | ||
const broadcastMessageAddedType='BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType='BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName='DEFAULT_QUEUE'; | ||
const tagNamePrefix='SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta='SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder='QUEUES'; | ||
const replayAllQueuesTag='SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
/** | ||
* takes an object and return a Request object to be executed by | ||
* the browser | ||
* @param {Object} idbRequestObject | ||
* @return {Request} | ||
* @private | ||
*/ | ||
async function getFetchableRequest({idbRequestObject}) { | ||
let reqObject = { | ||
mode: idbRequestObject.mode, | ||
method: idbRequestObject.method, | ||
redirect: idbRequestObject.redirect, | ||
headers: new Headers(JSON.parse(idbRequestObject.headers)), | ||
credentials: idbRequestObject.credentials, | ||
}; | ||
if(idbRequestObject.body) { | ||
reqObject.body = idbRequestObject.body; | ||
} | ||
return new Request(idbRequestObject.url, reqObject); | ||
} | ||
async function getQueueableRequest({request:a,config:b}){let c={config:b,metadata:{creationTimestamp:Date.now()},request:{url:a.url,headers:JSON.stringify([...a.headers]),mode:a.mode,method:a.method,redirect:a.redirect,credentials:a.credentials}};const d=await a.text();return 0<d.length&&(c.request.body=d),c}async function getFetchableRequest({idbRequestObject:a}){let b={mode:a.mode,method:a.method,redirect:a.redirect,headers:new Headers(JSON.parse(a.headers)),credentials:a.credentials};return a.body&&(b.body=a.body),new Request(a.url,b)}async function cleanupQueue(a){let b=new IDBHelper(a,1,'QueueStore'),c=await b.get(allQueuesPlaceholder);return c?void(await Promise.all(c.map(async(d)=>{const e=await b.get(d);let f=[],g=[];await Promise.all(e.map(async(h)=>{const i=await b.get(h);i&&i.metadata&&i.metadata.creationTimestamp+i.config.maxAge<=Date.now()?g.push(b.delete(h)):f.push(h);})),await Promise.all(g),b.put(d,f);}))):null} | ||
/** | ||
* clean up the queue, deleting all the tasks who are either damaged or | ||
* whose maxAge has expired | ||
* | ||
* @memberOf Queue | ||
* @private | ||
* @param {string} dbName Name of database to cleanup. | ||
* @return {Promise} | ||
*/ | ||
async function cleanupQueue(dbName) { | ||
let db = new IDBHelper(dbName, 1, 'QueueStore'); | ||
let queueObj = await db.get(allQueuesPlaceholder); | ||
class RequestManager{constructor({callbacks:a,queue:b}={}){a=a||{};const c='workbox-background-sync.RequestManager.callbacks';deprecate(a,'onResponse','replayDidSucceed',c),deprecate(a,'onRetryFailure','replayDidFail',c),this._globalCallbacks=a,this._queue=b,this.attachSyncHandler();}attachSyncHandler(){self.addEventListener('sync',(a)=>{(a.tag===tagNamePrefix+this._queue.queueName||a.tag===replayAllQueuesTag)&&a.waitUntil(this.replayRequests());});}async replayRequest(a){try{const b=await this._queue.getRequestFromQueue({hash:a});if(b.response)return;const c=await getFetchableRequest({idbRequestObject:b.request}),d=await fetch(c);if(!d.ok)return Promise.reject(d);putResponse({hash:a,idbObject:b,response:d.clone(),idbQDb:this._queue.idbQDb}),this._globalCallbacks.replayDidSucceed&&this._globalCallbacks.replayDidSucceed(a,d);}catch(b){return Promise.reject(b)}}async replayRequests(){const a=[];for(let b of this._queue.queue)try{await this.replayRequest(b);}catch(c){this._globalCallbacks.replayDidFail&&this._globalCallbacks.replayDidFail(b,c),a.push(c);}return 0<a.length?Promise.reject(a):Promise.resolve()}} | ||
if(!queueObj) { | ||
return null; | ||
} | ||
var stackframe=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d();})(commonjsGlobal,function(){'use strict';function c(t){return!isNaN(parseFloat(t))&&isFinite(t)}function d(t){return t[0].toUpperCase()+t.substring(1)}function e(t){return function(){return this[t]}}function f(t){if(t instanceof Object)for(var u=0;u<o.length;u++)t.hasOwnProperty(o[u])&&void 0!==t[o[u]]&&this['set'+d(o[u])](t[o[u]]);}var g=['isConstructor','isEval','isNative','isToplevel'],h=['columnNumber','lineNumber'],l=['fileName','functionName','source'],o=g.concat(h,l,['args']);f.prototype={getArgs:function(){return this.args},setArgs:function(t){if('[object Array]'!==Object.prototype.toString.call(t))throw new TypeError('Args must be an Array');this.args=t;},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(t){if(t instanceof f)this.evalOrigin=t;else if(t instanceof Object)this.evalOrigin=new f(t);else throw new TypeError('Eval Origin must be an Object or StackFrame')},toString:function(){var t=this.getFunctionName()||'{anonymous}',u='('+(this.getArgs()||[]).join(',')+')',w=this.getFileName()?'@'+this.getFileName():'',x=c(this.getLineNumber())?':'+this.getLineNumber():'',y=c(this.getColumnNumber())?':'+this.getColumnNumber():'';return t+u+w+x+y}};for(var q=0;q<g.length;q++)f.prototype['get'+d(g[q])]=e(g[q]),f.prototype['set'+d(g[q])]=function(t){return function(u){this[t]=!!u;}}(g[q]);for(var r=0;r<h.length;r++)f.prototype['get'+d(h[r])]=e(h[r]),f.prototype['set'+d(h[r])]=function(t){return function(u){if(!c(u))throw new TypeError(t+' must be a Number');this[t]=+u;}}(h[r]);for(var s=0;s<l.length;s++)f.prototype['get'+d(l[s])]=e(l[s]),f.prototype['set'+d(l[s])]=function(t){return function(u){this[t]=u+'';}}(l[s]);return f});}); | ||
await Promise.all(queueObj.map(async (queueName)=>{ | ||
const requestQueues = await db.get(queueName); | ||
let itemsToKeep = []; | ||
let deletionPromises = []; | ||
await Promise.all(requestQueues.map( async (hash) => { | ||
const requestData = await db.get(hash); | ||
if (requestData && requestData.metadata | ||
&& requestData.metadata.creationTimestamp + requestData.config.maxAge | ||
<= Date.now()) { | ||
// Delete items that are too old. | ||
deletionPromises.push(db.delete(hash)); | ||
} else { | ||
// Keep elements whose definition exists in idb. | ||
itemsToKeep.push(hash); | ||
} | ||
})); | ||
await Promise.all(deletionPromises); | ||
db.put(queueName, itemsToKeep); | ||
})); | ||
} | ||
var errorStackParser=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d(stackframe);})(commonjsGlobal,function(d){'use strict';var f=/(^|@)\S+\:\d+/,g=/^\s*at .*(\S+\:\d+|\(native\))/m,h=/^(eval@)?(\[native code\])?$/;return{parse:function(k){if('undefined'!=typeof k.stacktrace||'undefined'!=typeof k['opera#sourceloc'])return this.parseOpera(k);if(k.stack&&k.stack.match(g))return this.parseV8OrIE(k);if(k.stack)return this.parseFFOrSafari(k);throw new Error('Cannot parse given Error object')},extractLocation:function(k){if(-1===k.indexOf(':'))return[k];var l=/(.+?)(?:\:(\d+))?(?:\:(\d+))?$/,m=l.exec(k.replace(/[\(\)]/g,''));return[m[1],m[2]||void 0,m[3]||void 0]},parseV8OrIE:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(g)},this);return l.map(function(m){-1<m.indexOf('(eval ')&&(m=m.replace(/eval code/g,'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,''));var n=m.replace(/^\s+/,'').replace(/\(eval code/g,'(').split(/\s+/).slice(1),o=this.extractLocation(n.pop()),p=n.join(' ')||void 0,q=-1<['eval','<anonymous>'].indexOf(o[0])?void 0:o[0];return new d({functionName:p,fileName:q,lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseFFOrSafari:function(k){var l=k.stack.split('\n').filter(function(m){return!m.match(h)},this);return l.map(function(m){if(-1<m.indexOf(' > eval')&&(m=m.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,':$1')),-1===m.indexOf('@')&&-1===m.indexOf(':'))return new d({functionName:m});var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.join('@')||void 0;return new d({functionName:p,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseOpera:function(k){return!k.stacktrace||-1<k.message.indexOf('\n')&&k.message.split('\n').length>k.stacktrace.split('\n').length?this.parseOpera9(k):k.stack?this.parseOpera11(k):this.parseOpera10(k)},parseOpera9:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)/i,m=k.message.split('\n'),n=[],o=2,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera10:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,m=k.stacktrace.split('\n'),n=[],o=0,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({functionName:q[3]||void 0,fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera11:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(f)&&!m.match(/^Error created at/)},this);return l.map(function(m){var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.shift()||'',q=p.replace(/<anonymous function(: (\w+))?>/,'$2').replace(/\([^\)]*\)/g,'')||void 0,r;p.match(/\(([^\)]*)\)/)&&(r=p.replace(/^[^\(]+\(([^\)]*)\)$/,'$1'));var s=r===void 0||'[arguments not available]'===r?void 0:r.split(',');return new d({functionName:q,args:s,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)}}});}); | ||
/** | ||
* Class to handle all the request related | ||
* transformations, replaying, event handling | ||
* broadcasting back to controlled pages etc. | ||
* @class | ||
* @private | ||
*/ | ||
class RequestManager { | ||
/** | ||
* Initializes the request manager | ||
* stores the callbacks object, maintains config and | ||
* attaches event handler | ||
* @param {Object=} config | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
constructor({callbacks, queue}) { | ||
this._globalCallbacks = callbacks || {}; | ||
this._queue = queue; | ||
this.attachSyncHandler(); | ||
} | ||
function isInstance(a,b){const c=Object.keys(a).pop();a[c]instanceof b||throwError(`The '${c}' parameter must be an instance of | ||
'${b.name}'`);}function isType(a,b){const c=Object.keys(a).pop(),d=typeof a[c];d!==b&&throwError(`The '${c}' parameter has the wrong type. (Expected: | ||
${b}, actual: ${d})`);}function throwError(a){a=a.replace(/\s+/g,' ');const b=new Error(a);b.name='assertion-failed';const c=errorStackParser.parse(b);throw 3<=c.length&&(b.message=`Invalid call to ${c[2].functionName}() — `+a),b} | ||
/** | ||
* attaches sync handler to replay requests when | ||
* sync event is fired | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
attachSyncHandler() { | ||
self.addEventListener('sync', (event) => { | ||
if(event.tag === tagNamePrefix + this._queue.queueName | ||
|| event.tag === replayAllQueuesTag) { | ||
event.waitUntil(this.replayRequests()); | ||
} | ||
}); | ||
} | ||
function broadcastMessage({broadcastChannel:a,type:b,url:c}){a&&(isInstance({broadcastChannel:a},BroadcastChannel),isType({type:b},'string'),isType({url:c},'string'),a.postMessage({type:b,meta:broadcastMeta,payload:{url:c}}));} | ||
/** | ||
* function to start playing requests | ||
* in sequence | ||
* @return {void} | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
replayRequests() { | ||
return this._queue.queue.reduce((promise, hash) => { | ||
return promise | ||
.then(async (item) => { | ||
const reqData = await this._queue.getRequestFromQueue({hash}); | ||
if(reqData.response) { | ||
// check if request is not played already | ||
return; | ||
} | ||
let _requestCounter=0; let _queueCounter=0;class RequestQueue{constructor({config:a,queueName:e=defaultQueueName+'_'+_queueCounter++,idbQDb:b,broadcastChannel:c,callbacks:d}){this._isQueueNameAddedToAllQueue=!1,this._queueName=e,this._config=a,this._idbQDb=b,this._broadcastChannel=c,this._globalCallbacks=d||{},this._queue=[],this.initQueue();}async initQueue(){const a=await this._idbQDb.get(this._queueName);this._queue.concat(a);}async addQueueNameToAllQueues(){if(!this._isQueueNameAddedToAllQueue){let a=await this._idbQDb.get(allQueuesPlaceholder);a=a||[],a.includes(this._queueName)||a.push(this._queueName),this._idbQDb.put(allQueuesPlaceholder,a),this._isQueueNameAddedToAllQueue=!0;}}async saveQueue(){await this._idbQDb.put(this._queueName,this._queue);}async push({request:a}){isInstance({request:a},Request);const b=`${a.url}!${Date.now()}!${_requestCounter++}`,c=await getQueueableRequest({request:a,config:this._config});this._globalCallbacks.requestWillEnqueue&&this._globalCallbacks.requestWillEnqueue(c);try{return this._queue.push(b),this.saveQueue(),this._idbQDb.put(b,c),await this.addQueueNameToAllQueues(),self.registration&&self.registration.sync.register(tagNamePrefix+this._queueName),broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageAddedType,id:b,url:a.url}),b}catch(d){return broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageFailedType,id:b,url:a.url}),d}}async getRequestFromQueue({hash:a}){if(isType({hash:a},'string'),this._queue.includes(a)){const b=await this._idbQDb.get(a);return this._globalCallbacks.requestWillDequeue&&this._globalCallbacks.requestWillDequeue(b),b}}get queue(){return Object.assign([],this._queue)}get queueName(){return this._queueName}get idbQDb(){return this._idbQDb}} | ||
const request = await getFetchableRequest({ | ||
idbRequestObject: reqData.request, | ||
}); | ||
class Queue{constructor({broadcastChannel:a,callbacks:b,queueName:c,dbName:d=defaultDBName,maxRetentionTime:e=maxAge}={}){c&&isType({queueName:c},'string'),e&&isType({maxRetentionTime:e},'number'),a&&isInstance({broadcastChannel:a},BroadcastChannel),isType({dbName:d},'string'),this._dbName=d,this._queue=new RequestQueue({config:{maxAge:e},queueName:c,idbQDb:new IDBHelper(this._dbName,1,'QueueStore'),broadcastChannel:a,callbacks:b}),this._requestManager=new RequestManager({callbacks:b,queue:this._queue}),this.cleanupQueue();}cleanupQueue(){return cleanupQueue(this._dbName)}pushIntoQueue({request:a}){return isInstance({request:a},Request),this._queue.push({request:a})}replayRequests(){return this._requestManager.replayRequests()}getResponse({id:a}){return getResponse({id:a,dbName:this._dbName})}} | ||
return fetch(request) | ||
.then((response)=>{ | ||
if(!response.ok) { | ||
return Promise.resolve(); | ||
} else { | ||
// not blocking on putResponse. | ||
putResponse({ | ||
hash, | ||
idbObject: reqData, | ||
response: response.clone(), | ||
idbQDb: this._queue.idbQDb, | ||
}); | ||
this._globalCallbacks.onResponse | ||
&& this._globalCallbacks.onResponse(hash, response); | ||
} | ||
}) | ||
.catch((err)=>{ | ||
this._globalCallbacks.onRetryFailure | ||
&& this._globalCallbacks.onRetryFailure(hash, err); | ||
}); | ||
}); | ||
}, Promise.resolve()); | ||
} | ||
} | ||
var stackframe = createCommonjsModule(function (module, exports) { | ||
(function (root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('stackframe', [], factory); | ||
} else { | ||
module.exports = factory(); | ||
} | ||
}(commonjsGlobal, function () { | ||
'use strict'; | ||
function _isNumber(n) { | ||
return !isNaN(parseFloat(n)) && isFinite(n); | ||
} | ||
function _capitalize(str) { | ||
return str[0].toUpperCase() + str.substring(1); | ||
} | ||
function _getter(p) { | ||
return function () { | ||
return this[p]; | ||
}; | ||
} | ||
var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel']; | ||
var numericProps = ['columnNumber', 'lineNumber']; | ||
var stringProps = ['fileName', 'functionName', 'source']; | ||
var arrayProps = ['args']; | ||
function StackFrame(obj) { | ||
if (obj instanceof Object) { | ||
var props = booleanProps.concat(numericProps.concat(stringProps.concat(arrayProps))); | ||
for (var i = 0; i < props.length; i++) { | ||
if (obj.hasOwnProperty(props[i]) && obj[props[i]] !== undefined) { | ||
this['set' + _capitalize(props[i])](obj[props[i]]); | ||
} | ||
} | ||
} | ||
} | ||
StackFrame.prototype = { | ||
getArgs: function () { | ||
return this.args; | ||
}, | ||
setArgs: function (v) { | ||
if (Object.prototype.toString.call(v) !== '[object Array]') { | ||
throw new TypeError('Args must be an Array'); | ||
} | ||
this.args = v; | ||
}, | ||
getEvalOrigin: function () { | ||
return this.evalOrigin; | ||
}, | ||
setEvalOrigin: function (v) { | ||
if (v instanceof StackFrame) { | ||
this.evalOrigin = v; | ||
} else if (v instanceof Object) { | ||
this.evalOrigin = new StackFrame(v); | ||
} else { | ||
throw new TypeError('Eval Origin must be an Object or StackFrame'); | ||
} | ||
}, | ||
toString: function () { | ||
var functionName = this.getFunctionName() || '{anonymous}'; | ||
var args = '(' + (this.getArgs() || []).join(',') + ')'; | ||
var fileName = this.getFileName() ? ('@' + this.getFileName()) : ''; | ||
var lineNumber = _isNumber(this.getLineNumber()) ? (':' + this.getLineNumber()) : ''; | ||
var columnNumber = _isNumber(this.getColumnNumber()) ? (':' + this.getColumnNumber()) : ''; | ||
return functionName + args + fileName + lineNumber + columnNumber; | ||
} | ||
}; | ||
for (var i = 0; i < booleanProps.length; i++) { | ||
StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]); | ||
StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function (p) { | ||
return function (v) { | ||
this[p] = Boolean(v); | ||
}; | ||
})(booleanProps[i]); | ||
} | ||
for (var j = 0; j < numericProps.length; j++) { | ||
StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]); | ||
StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function (p) { | ||
return function (v) { | ||
if (!_isNumber(v)) { | ||
throw new TypeError(p + ' must be a Number'); | ||
} | ||
this[p] = Number(v); | ||
}; | ||
})(numericProps[j]); | ||
} | ||
for (var k = 0; k < stringProps.length; k++) { | ||
StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]); | ||
StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function (p) { | ||
return function (v) { | ||
this[p] = String(v); | ||
}; | ||
})(stringProps[k]); | ||
} | ||
return StackFrame; | ||
})); | ||
}); | ||
var errorStackParser = createCommonjsModule(function (module, exports) { | ||
(function(root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('error-stack-parser', ['stackframe'], factory); | ||
} else { | ||
module.exports = factory(stackframe); | ||
} | ||
}(commonjsGlobal, function ErrorStackParser(StackFrame) { | ||
'use strict'; | ||
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+\:\d+/; | ||
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+\:\d+|\(native\))/m; | ||
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/; | ||
return { | ||
/** | ||
* Given an Error object, extract the most information from it. | ||
* | ||
* @param {Error} error object | ||
* @return {Array} of StackFrames | ||
*/ | ||
parse: function ErrorStackParser$$parse(error) { | ||
if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') { | ||
return this.parseOpera(error); | ||
} else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { | ||
return this.parseV8OrIE(error); | ||
} else if (error.stack) { | ||
return this.parseFFOrSafari(error); | ||
} else { | ||
throw new Error('Cannot parse given Error object'); | ||
} | ||
}, | ||
// Separate line and column numbers from a string of the form: (URI:Line:Column) | ||
extractLocation: function ErrorStackParser$$extractLocation(urlLike) { | ||
// Fail-fast but return locations like "(native)" | ||
if (urlLike.indexOf(':') === -1) { | ||
return [urlLike]; | ||
} | ||
var regExp = /(.+?)(?:\:(\d+))?(?:\:(\d+))?$/; | ||
var parts = regExp.exec(urlLike.replace(/[\(\)]/g, '')); | ||
return [parts[1], parts[2] || undefined, parts[3] || undefined]; | ||
}, | ||
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(CHROME_IE_STACK_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
if (line.indexOf('(eval ') > -1) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g, ''); | ||
} | ||
var tokens = line.replace(/^\s+/, '').replace(/\(eval code/g, '(').split(/\s+/).slice(1); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join(' ') || undefined; | ||
var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0]; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: fileName, | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
}, | ||
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !line.match(SAFARI_NATIVE_CODE_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
if (line.indexOf(' > eval') > -1) { | ||
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g, ':$1'); | ||
} | ||
if (line.indexOf('@') === -1 && line.indexOf(':') === -1) { | ||
// Safari eval frames only have function names and nothing else | ||
return new StackFrame({ | ||
functionName: line | ||
}); | ||
} else { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join('@') || undefined; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
} | ||
}, this); | ||
}, | ||
parseOpera: function ErrorStackParser$$parseOpera(e) { | ||
if (!e.stacktrace || (e.message.indexOf('\n') > -1 && | ||
e.message.split('\n').length > e.stacktrace.split('\n').length)) { | ||
return this.parseOpera9(e); | ||
} else if (!e.stack) { | ||
return this.parseOpera10(e); | ||
} else { | ||
return this.parseOpera11(e); | ||
} | ||
}, | ||
parseOpera9: function ErrorStackParser$$parseOpera9(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)/i; | ||
var lines = e.message.split('\n'); | ||
var result = []; | ||
for (var i = 2, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push(new StackFrame({ | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
})); | ||
} | ||
} | ||
return result; | ||
}, | ||
parseOpera10: function ErrorStackParser$$parseOpera10(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i; | ||
var lines = e.stacktrace.split('\n'); | ||
var result = []; | ||
for (var i = 0, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push( | ||
new StackFrame({ | ||
functionName: match[3] || undefined, | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
}) | ||
); | ||
} | ||
} | ||
return result; | ||
}, | ||
// Opera 10.65+ Error.stack very similar to FF/Safari | ||
parseOpera11: function ErrorStackParser$$parseOpera11(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/); | ||
}, this); | ||
return filtered.map(function(line) { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionCall = (tokens.shift() || ''); | ||
var functionName = functionCall | ||
.replace(/<anonymous function(: (\w+))?>/, '$2') | ||
.replace(/\([^\)]*\)/g, '') || undefined; | ||
var argsRaw; | ||
if (functionCall.match(/\(([^\)]*)\)/)) { | ||
argsRaw = functionCall.replace(/^[^\(]+\(([^\)]*)\)$/, '$1'); | ||
} | ||
var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ? | ||
undefined : argsRaw.split(','); | ||
return new StackFrame({ | ||
functionName: functionName, | ||
args: args, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
} | ||
}; | ||
})); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
function atLeastOne(object) { | ||
const parameters = Object.keys(object); | ||
if (!parameters.some((parameter) => object[parameter] !== undefined)) { | ||
throwError('Please set at least one of the following parameters: ' + | ||
parameters.map((p) => `'${p}'`).join(', ')); | ||
} | ||
} | ||
function hasMethod(object, expectedMethod) { | ||
const parameter = Object.keys(object).pop(); | ||
const type = typeof object[parameter][expectedMethod]; | ||
if (type !== 'function') { | ||
throwError(`The '${parameter}' parameter must be an object that exposes a | ||
'${expectedMethod}' method.`); | ||
} | ||
} | ||
function isInstance(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!(object[parameter] instanceof expectedClass)) { | ||
throwError(`The '${parameter}' parameter must be an instance of | ||
'${expectedClass.name}'`); | ||
} | ||
} | ||
function isOneOf(object, values) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!values.includes(object[parameter])) { | ||
throwError(`The '${parameter}' parameter must be set to one of the | ||
following: ${values}`); | ||
} | ||
} | ||
function isType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualType = typeof object[parameter]; | ||
if (actualType !== expectedType) { | ||
throwError(`The '${parameter}' parameter has the wrong type. (Expected: | ||
${expectedType}, actual: ${actualType})`); | ||
} | ||
} | ||
function isArrayOfType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedType}' elements.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (typeof item !== expectedType) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isArrayOfClass(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedClass.name}' instances.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (!(item instanceof expectedClass)) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isValue(object, expectedValue) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualValue = object[parameter]; | ||
if (actualValue !== expectedValue) { | ||
throwError(`The '${parameter}' parameter has the wrong value. (Expected: | ||
${expectedValue}, actual: ${actualValue})`); | ||
} | ||
} | ||
function throwError(message) { | ||
// Collapse any newlines or whitespace into a single space. | ||
message = message.replace(/\s+/g, ' '); | ||
const error = new Error(message); | ||
error.name = 'assertion-failed'; | ||
const stackFrames = errorStackParser.parse(error); | ||
// If, for some reason, we don't have all the stack information we need, | ||
// we'll just end up throwing a basic Error. | ||
if (stackFrames.length >= 3) { | ||
// Assuming we have the stack frames, set the message to include info | ||
// about what the underlying method was, and set the name to reflect | ||
// the assertion type that failed. | ||
error.message = `Invalid call to ${stackFrames[2].functionName}() — ` + | ||
message; | ||
} | ||
throw error; | ||
} | ||
var assert = { | ||
atLeastOne, | ||
hasMethod, | ||
isInstance, | ||
isOneOf, | ||
isType, | ||
isValue, | ||
isArrayOfType, | ||
isArrayOfClass, | ||
}; | ||
/** | ||
* broadcasts the message with the given type and url | ||
* | ||
* @param {BroadcastChannel} broadcastChannel which is used to push the | ||
* updates on | ||
* @param {Object} input | ||
* @param {string} input.type Type of the message (either success or failure) | ||
* @param {string} input.url Url for which the request was queued | ||
* @private | ||
*/ | ||
function broadcastMessage({broadcastChannel, type, url}) { | ||
if(!broadcastChannel) | ||
return; | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
assert.isType({type}, 'string'); | ||
assert.isType({url}, 'string'); | ||
broadcastChannel.postMessage({ | ||
type: type, | ||
meta: broadcastMeta, | ||
payload: { | ||
url: url, | ||
}, | ||
}); | ||
} | ||
let _requestCounter = 0; | ||
let _queueCounter = 0; | ||
/** | ||
* Queue class to maintain and perform on the logical requests queue | ||
* | ||
* @class RequestQueue | ||
* @private | ||
*/ | ||
class RequestQueue { | ||
/** | ||
* Creates an instance of RequestQueue. | ||
* | ||
* @param {Object} config | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
constructor({ | ||
config, | ||
queueName = defaultQueueName + '_' + _queueCounter++, | ||
idbQDb, | ||
broadcastChannel, | ||
}) { | ||
this._isQueueNameAddedToAllQueue = false; | ||
this._queueName = queueName; | ||
this._config = config; | ||
this._idbQDb = idbQDb; | ||
this._broadcastChannel = broadcastChannel; | ||
this._queue = []; | ||
this.initQueue(); | ||
} | ||
/** | ||
* initializes the queue from the IDB store | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async initQueue() { | ||
const idbQueue = await this._idbQDb.get(this._queueName); | ||
this._queue.concat(idbQueue); | ||
} | ||
/** | ||
* adds the current queueName to all queue array | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async addQueueNameToAllQueues() { | ||
if(!this._isQueueNameAddedToAllQueue) { | ||
let allQueues = await this._idbQDb.get(allQueuesPlaceholder); | ||
allQueues = allQueues || []; | ||
if(!allQueues.includes(this._queueName)) { | ||
allQueues.push(this._queueName); | ||
} | ||
this._idbQDb.put(allQueuesPlaceholder, allQueues); | ||
this._isQueueNameAddedToAllQueue = true; | ||
} | ||
} | ||
/** | ||
* saves the logical queue to IDB | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async saveQueue() { | ||
await this._idbQDb.put(this._queueName, this._queue); | ||
} | ||
/** | ||
* push any request to background sync queue which would be played later | ||
* preferably when network comes back | ||
* | ||
* @param {Request} request request object to be queued by this | ||
* | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async push({request}) { | ||
assert.isInstance({request}, Request); | ||
const hash = `${request.url}!${Date.now()}!${_requestCounter++}`; | ||
const queuableRequest = | ||
await getQueueableRequest({ | ||
request, | ||
config: this._config, | ||
}); | ||
try{ | ||
this._queue.push(hash); | ||
// add to queue | ||
this.saveQueue(); | ||
this._idbQDb.put(hash, queuableRequest); | ||
await this.addQueueNameToAllQueues(); | ||
// register sync | ||
self.registration && | ||
self.registration.sync.register(tagNamePrefix + this._queueName); | ||
// broadcast the success of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageAddedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} catch(e) { | ||
// broadcast the failure of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageFailedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} | ||
} | ||
/** | ||
* get the Request from the queue at a particular index | ||
* | ||
* @param {string} hash hash of the request at the given index | ||
* @return {Request} request object corresponding to given hash | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async getRequestFromQueue({hash}) { | ||
assert.isType({hash}, 'string'); | ||
if(this._queue.includes(hash)) { | ||
return await this._idbQDb.get(hash); | ||
} | ||
} | ||
/** | ||
* returns the instance of queue. | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queue() { | ||
return Object.assign([], this._queue); | ||
} | ||
/** | ||
* returns the name of the current queue | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queueName() { | ||
return this._queueName; | ||
} | ||
/** | ||
* returns the instance of IDBStore | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get idbQDb() { | ||
return this._idbQDb; | ||
} | ||
} | ||
/** | ||
* Use the instance of this class to push the failed requests into the queue. | ||
* | ||
* @example | ||
* When you want to push the requests manually | ||
* let bgQueue = new workbox.backgroundSync.Queue(); | ||
* self.addEventListener('fetch', function(e) { | ||
* if (!e.request.url.startsWith('https://jsonplaceholder.typicode.com')) { | ||
* return; | ||
* } | ||
* | ||
* const clone = e.request.clone(); | ||
* e.respondWith(fetch(e.request).catch((err)=>{ | ||
* bgQueue.pushIntoQueue({ | ||
* request: clone, | ||
* }); | ||
* throw err; | ||
* })); | ||
* }); | ||
* | ||
* @memberof module:workbox-background-sync | ||
*/ | ||
class Queue { | ||
/** | ||
* Creates an instance of Queue with the given options | ||
* | ||
* @param {Object} [input] | ||
* @param {Number} [input.maxRetentionTime = 5 days] Time for which a queued | ||
* request will live in the queue(irespective of failed/success of replay). | ||
* @param {Object} [input.callbacks] Callbacks for successfull/ failed | ||
* replay of a request. | ||
* @param {string} [input.queueName] Queue name inside db in which | ||
* requests will be queued. | ||
* @param {BroadcastChannel=} [input.broadcastChannel] BroadcastChannel | ||
* which will be used to publish messages when the request will be queued. | ||
*/ | ||
constructor({maxRetentionTime = maxAge, callbacks, queueName, | ||
broadcastChannel, dbName = defaultDBName} = {}) { | ||
if(queueName) { | ||
assert.isType({queueName}, 'string'); | ||
} | ||
if(maxRetentionTime) { | ||
assert.isType({maxRetentionTime}, 'number'); | ||
} | ||
if(broadcastChannel) { | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
} | ||
assert.isType({dbName}, 'string'); | ||
this._dbName = dbName; | ||
this._queue = new RequestQueue({ | ||
config: { | ||
maxAge: maxRetentionTime, | ||
}, | ||
queueName, | ||
idbQDb: new IDBHelper(this._dbName, 1, 'QueueStore'), | ||
broadcastChannel, | ||
}); | ||
this._requestManager = new RequestManager({callbacks, | ||
queue: this._queue}); | ||
this.cleanupQueue(); | ||
} | ||
/** | ||
* clean up the queue, deleting all the tasks whose maxAge has expired | ||
* | ||
* @memberOf Queue | ||
* @private | ||
* @return {Promise} | ||
*/ | ||
cleanupQueue() { | ||
return cleanupQueue(this._dbName); | ||
} | ||
/** | ||
* This function pushes a given request into the IndexedDb Queue. | ||
* | ||
* @param {Object} input | ||
* @param {Request} input.request The request which is to be queued | ||
* | ||
* @return {Promise} Promise which resolves when the request is pushed in | ||
* the queue. | ||
*/ | ||
pushIntoQueue({request}) { | ||
assert.isInstance({request}, Request); | ||
return this._queue.push({request}); | ||
} | ||
/** | ||
* Replays all the requests in the queue, this can be used for custom timing | ||
* of replaying requests may be in an environment where sync event is not | ||
* supported. | ||
* @return {Promise} A listener for when the requests have been replayed. | ||
*/ | ||
replayRequests() { | ||
return this._requestManager.replayRequests(); | ||
} | ||
/** | ||
* Sets the dbName, which is used to store the queue and requests | ||
* defaults to bgQueueSyncDB. | ||
* @param {String} id The ID of the request. | ||
* @return {Object} Fetched response of the request. | ||
*/ | ||
getResponse({id}) { | ||
return getResponse({ | ||
id, | ||
dbName: this._dbName, | ||
}); | ||
} | ||
} | ||
return Queue; | ||
@@ -1474,0 +76,0 @@ |
@@ -22,3 +22,3 @@ /* | ||
const broadcastMeta = 'SW_BACKGROUND_SYNC_QUEUE'; | ||
const broadcastMeta='SW_BACKGROUND_SYNC_QUEUE'; | ||
@@ -35,464 +35,12 @@ var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; | ||
var stackframe = createCommonjsModule(function (module, exports) { | ||
(function (root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
var stackframe=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d();})(commonjsGlobal,function(){'use strict';function c(t){return!isNaN(parseFloat(t))&&isFinite(t)}function d(t){return t[0].toUpperCase()+t.substring(1)}function e(t){return function(){return this[t]}}function f(t){if(t instanceof Object)for(var u=0;u<o.length;u++)t.hasOwnProperty(o[u])&&void 0!==t[o[u]]&&this['set'+d(o[u])](t[o[u]]);}var g=['isConstructor','isEval','isNative','isToplevel'],h=['columnNumber','lineNumber'],l=['fileName','functionName','source'],o=g.concat(h,l,['args']);f.prototype={getArgs:function(){return this.args},setArgs:function(t){if('[object Array]'!==Object.prototype.toString.call(t))throw new TypeError('Args must be an Array');this.args=t;},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(t){if(t instanceof f)this.evalOrigin=t;else if(t instanceof Object)this.evalOrigin=new f(t);else throw new TypeError('Eval Origin must be an Object or StackFrame')},toString:function(){var t=this.getFunctionName()||'{anonymous}',u='('+(this.getArgs()||[]).join(',')+')',w=this.getFileName()?'@'+this.getFileName():'',x=c(this.getLineNumber())?':'+this.getLineNumber():'',y=c(this.getColumnNumber())?':'+this.getColumnNumber():'';return t+u+w+x+y}};for(var q=0;q<g.length;q++)f.prototype['get'+d(g[q])]=e(g[q]),f.prototype['set'+d(g[q])]=function(t){return function(u){this[t]=!!u;}}(g[q]);for(var r=0;r<h.length;r++)f.prototype['get'+d(h[r])]=e(h[r]),f.prototype['set'+d(h[r])]=function(t){return function(u){if(!c(u))throw new TypeError(t+' must be a Number');this[t]=+u;}}(h[r]);for(var s=0;s<l.length;s++)f.prototype['get'+d(l[s])]=e(l[s]),f.prototype['set'+d(l[s])]=function(t){return function(u){this[t]=u+'';}}(l[s]);return f});}); | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('stackframe', [], factory); | ||
} else { | ||
module.exports = factory(); | ||
} | ||
}(commonjsGlobal, function () { | ||
'use strict'; | ||
function _isNumber(n) { | ||
return !isNaN(parseFloat(n)) && isFinite(n); | ||
} | ||
var errorStackParser=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d(stackframe);})(commonjsGlobal,function(d){'use strict';var f=/(^|@)\S+\:\d+/,g=/^\s*at .*(\S+\:\d+|\(native\))/m,h=/^(eval@)?(\[native code\])?$/;return{parse:function(k){if('undefined'!=typeof k.stacktrace||'undefined'!=typeof k['opera#sourceloc'])return this.parseOpera(k);if(k.stack&&k.stack.match(g))return this.parseV8OrIE(k);if(k.stack)return this.parseFFOrSafari(k);throw new Error('Cannot parse given Error object')},extractLocation:function(k){if(-1===k.indexOf(':'))return[k];var l=/(.+?)(?:\:(\d+))?(?:\:(\d+))?$/,m=l.exec(k.replace(/[\(\)]/g,''));return[m[1],m[2]||void 0,m[3]||void 0]},parseV8OrIE:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(g)},this);return l.map(function(m){-1<m.indexOf('(eval ')&&(m=m.replace(/eval code/g,'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,''));var n=m.replace(/^\s+/,'').replace(/\(eval code/g,'(').split(/\s+/).slice(1),o=this.extractLocation(n.pop()),p=n.join(' ')||void 0,q=-1<['eval','<anonymous>'].indexOf(o[0])?void 0:o[0];return new d({functionName:p,fileName:q,lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseFFOrSafari:function(k){var l=k.stack.split('\n').filter(function(m){return!m.match(h)},this);return l.map(function(m){if(-1<m.indexOf(' > eval')&&(m=m.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,':$1')),-1===m.indexOf('@')&&-1===m.indexOf(':'))return new d({functionName:m});var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.join('@')||void 0;return new d({functionName:p,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseOpera:function(k){return!k.stacktrace||-1<k.message.indexOf('\n')&&k.message.split('\n').length>k.stacktrace.split('\n').length?this.parseOpera9(k):k.stack?this.parseOpera11(k):this.parseOpera10(k)},parseOpera9:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)/i,m=k.message.split('\n'),n=[],o=2,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera10:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,m=k.stacktrace.split('\n'),n=[],o=0,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({functionName:q[3]||void 0,fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera11:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(f)&&!m.match(/^Error created at/)},this);return l.map(function(m){var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.shift()||'',q=p.replace(/<anonymous function(: (\w+))?>/,'$2').replace(/\([^\)]*\)/g,'')||void 0,r;p.match(/\(([^\)]*)\)/)&&(r=p.replace(/^[^\(]+\(([^\)]*)\)$/,'$1'));var s=r===void 0||'[arguments not available]'===r?void 0:r.split(',');return new d({functionName:q,args:s,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)}}});}); | ||
function _capitalize(str) { | ||
return str[0].toUpperCase() + str.substring(1); | ||
} | ||
function isInstance(a,b){const c=Object.keys(a).pop();a[c]instanceof b||throwError(`The '${c}' parameter must be an instance of | ||
'${b.name}'`);}function isType(a,b){const c=Object.keys(a).pop(),d=typeof a[c];d!==b&&throwError(`The '${c}' parameter has the wrong type. (Expected: | ||
${b}, actual: ${d})`);}function throwError(a){a=a.replace(/\s+/g,' ');const b=new Error(a);b.name='assertion-failed';const c=errorStackParser.parse(b);throw 3<=c.length&&(b.message=`Invalid call to ${c[2].functionName}() — `+a),b} | ||
function _getter(p) { | ||
return function () { | ||
return this[p]; | ||
}; | ||
} | ||
function broadcastMessage({broadcastChannel:a,type:b,url:c}){a&&(isInstance({broadcastChannel:a},BroadcastChannel),isType({type:b},'string'),isType({url:c},'string'),a.postMessage({type:b,meta:broadcastMeta,payload:{url:c}}));} | ||
var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel']; | ||
var numericProps = ['columnNumber', 'lineNumber']; | ||
var stringProps = ['fileName', 'functionName', 'source']; | ||
var arrayProps = ['args']; | ||
function StackFrame(obj) { | ||
if (obj instanceof Object) { | ||
var props = booleanProps.concat(numericProps.concat(stringProps.concat(arrayProps))); | ||
for (var i = 0; i < props.length; i++) { | ||
if (obj.hasOwnProperty(props[i]) && obj[props[i]] !== undefined) { | ||
this['set' + _capitalize(props[i])](obj[props[i]]); | ||
} | ||
} | ||
} | ||
} | ||
StackFrame.prototype = { | ||
getArgs: function () { | ||
return this.args; | ||
}, | ||
setArgs: function (v) { | ||
if (Object.prototype.toString.call(v) !== '[object Array]') { | ||
throw new TypeError('Args must be an Array'); | ||
} | ||
this.args = v; | ||
}, | ||
getEvalOrigin: function () { | ||
return this.evalOrigin; | ||
}, | ||
setEvalOrigin: function (v) { | ||
if (v instanceof StackFrame) { | ||
this.evalOrigin = v; | ||
} else if (v instanceof Object) { | ||
this.evalOrigin = new StackFrame(v); | ||
} else { | ||
throw new TypeError('Eval Origin must be an Object or StackFrame'); | ||
} | ||
}, | ||
toString: function () { | ||
var functionName = this.getFunctionName() || '{anonymous}'; | ||
var args = '(' + (this.getArgs() || []).join(',') + ')'; | ||
var fileName = this.getFileName() ? ('@' + this.getFileName()) : ''; | ||
var lineNumber = _isNumber(this.getLineNumber()) ? (':' + this.getLineNumber()) : ''; | ||
var columnNumber = _isNumber(this.getColumnNumber()) ? (':' + this.getColumnNumber()) : ''; | ||
return functionName + args + fileName + lineNumber + columnNumber; | ||
} | ||
}; | ||
for (var i = 0; i < booleanProps.length; i++) { | ||
StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]); | ||
StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function (p) { | ||
return function (v) { | ||
this[p] = Boolean(v); | ||
}; | ||
})(booleanProps[i]); | ||
} | ||
for (var j = 0; j < numericProps.length; j++) { | ||
StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]); | ||
StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function (p) { | ||
return function (v) { | ||
if (!_isNumber(v)) { | ||
throw new TypeError(p + ' must be a Number'); | ||
} | ||
this[p] = Number(v); | ||
}; | ||
})(numericProps[j]); | ||
} | ||
for (var k = 0; k < stringProps.length; k++) { | ||
StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]); | ||
StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function (p) { | ||
return function (v) { | ||
this[p] = String(v); | ||
}; | ||
})(stringProps[k]); | ||
} | ||
return StackFrame; | ||
})); | ||
}); | ||
var errorStackParser = createCommonjsModule(function (module, exports) { | ||
(function(root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('error-stack-parser', ['stackframe'], factory); | ||
} else { | ||
module.exports = factory(stackframe); | ||
} | ||
}(commonjsGlobal, function ErrorStackParser(StackFrame) { | ||
'use strict'; | ||
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+\:\d+/; | ||
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+\:\d+|\(native\))/m; | ||
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/; | ||
return { | ||
/** | ||
* Given an Error object, extract the most information from it. | ||
* | ||
* @param {Error} error object | ||
* @return {Array} of StackFrames | ||
*/ | ||
parse: function ErrorStackParser$$parse(error) { | ||
if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') { | ||
return this.parseOpera(error); | ||
} else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { | ||
return this.parseV8OrIE(error); | ||
} else if (error.stack) { | ||
return this.parseFFOrSafari(error); | ||
} else { | ||
throw new Error('Cannot parse given Error object'); | ||
} | ||
}, | ||
// Separate line and column numbers from a string of the form: (URI:Line:Column) | ||
extractLocation: function ErrorStackParser$$extractLocation(urlLike) { | ||
// Fail-fast but return locations like "(native)" | ||
if (urlLike.indexOf(':') === -1) { | ||
return [urlLike]; | ||
} | ||
var regExp = /(.+?)(?:\:(\d+))?(?:\:(\d+))?$/; | ||
var parts = regExp.exec(urlLike.replace(/[\(\)]/g, '')); | ||
return [parts[1], parts[2] || undefined, parts[3] || undefined]; | ||
}, | ||
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(CHROME_IE_STACK_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
if (line.indexOf('(eval ') > -1) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g, ''); | ||
} | ||
var tokens = line.replace(/^\s+/, '').replace(/\(eval code/g, '(').split(/\s+/).slice(1); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join(' ') || undefined; | ||
var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0]; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: fileName, | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
}, | ||
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !line.match(SAFARI_NATIVE_CODE_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
if (line.indexOf(' > eval') > -1) { | ||
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g, ':$1'); | ||
} | ||
if (line.indexOf('@') === -1 && line.indexOf(':') === -1) { | ||
// Safari eval frames only have function names and nothing else | ||
return new StackFrame({ | ||
functionName: line | ||
}); | ||
} else { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join('@') || undefined; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
} | ||
}, this); | ||
}, | ||
parseOpera: function ErrorStackParser$$parseOpera(e) { | ||
if (!e.stacktrace || (e.message.indexOf('\n') > -1 && | ||
e.message.split('\n').length > e.stacktrace.split('\n').length)) { | ||
return this.parseOpera9(e); | ||
} else if (!e.stack) { | ||
return this.parseOpera10(e); | ||
} else { | ||
return this.parseOpera11(e); | ||
} | ||
}, | ||
parseOpera9: function ErrorStackParser$$parseOpera9(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)/i; | ||
var lines = e.message.split('\n'); | ||
var result = []; | ||
for (var i = 2, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push(new StackFrame({ | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
})); | ||
} | ||
} | ||
return result; | ||
}, | ||
parseOpera10: function ErrorStackParser$$parseOpera10(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i; | ||
var lines = e.stacktrace.split('\n'); | ||
var result = []; | ||
for (var i = 0, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push( | ||
new StackFrame({ | ||
functionName: match[3] || undefined, | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
}) | ||
); | ||
} | ||
} | ||
return result; | ||
}, | ||
// Opera 10.65+ Error.stack very similar to FF/Safari | ||
parseOpera11: function ErrorStackParser$$parseOpera11(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/); | ||
}, this); | ||
return filtered.map(function(line) { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionCall = (tokens.shift() || ''); | ||
var functionName = functionCall | ||
.replace(/<anonymous function(: (\w+))?>/, '$2') | ||
.replace(/\([^\)]*\)/g, '') || undefined; | ||
var argsRaw; | ||
if (functionCall.match(/\(([^\)]*)\)/)) { | ||
argsRaw = functionCall.replace(/^[^\(]+\(([^\)]*)\)$/, '$1'); | ||
} | ||
var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ? | ||
undefined : argsRaw.split(','); | ||
return new StackFrame({ | ||
functionName: functionName, | ||
args: args, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
} | ||
}; | ||
})); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
function atLeastOne(object) { | ||
const parameters = Object.keys(object); | ||
if (!parameters.some((parameter) => object[parameter] !== undefined)) { | ||
throwError('Please set at least one of the following parameters: ' + | ||
parameters.map((p) => `'${p}'`).join(', ')); | ||
} | ||
} | ||
function hasMethod(object, expectedMethod) { | ||
const parameter = Object.keys(object).pop(); | ||
const type = typeof object[parameter][expectedMethod]; | ||
if (type !== 'function') { | ||
throwError(`The '${parameter}' parameter must be an object that exposes a | ||
'${expectedMethod}' method.`); | ||
} | ||
} | ||
function isInstance(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!(object[parameter] instanceof expectedClass)) { | ||
throwError(`The '${parameter}' parameter must be an instance of | ||
'${expectedClass.name}'`); | ||
} | ||
} | ||
function isOneOf(object, values) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!values.includes(object[parameter])) { | ||
throwError(`The '${parameter}' parameter must be set to one of the | ||
following: ${values}`); | ||
} | ||
} | ||
function isType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualType = typeof object[parameter]; | ||
if (actualType !== expectedType) { | ||
throwError(`The '${parameter}' parameter has the wrong type. (Expected: | ||
${expectedType}, actual: ${actualType})`); | ||
} | ||
} | ||
function isArrayOfType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedType}' elements.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (typeof item !== expectedType) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isArrayOfClass(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedClass.name}' instances.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (!(item instanceof expectedClass)) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isValue(object, expectedValue) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualValue = object[parameter]; | ||
if (actualValue !== expectedValue) { | ||
throwError(`The '${parameter}' parameter has the wrong value. (Expected: | ||
${expectedValue}, actual: ${actualValue})`); | ||
} | ||
} | ||
function throwError(message) { | ||
// Collapse any newlines or whitespace into a single space. | ||
message = message.replace(/\s+/g, ' '); | ||
const error = new Error(message); | ||
error.name = 'assertion-failed'; | ||
const stackFrames = errorStackParser.parse(error); | ||
// If, for some reason, we don't have all the stack information we need, | ||
// we'll just end up throwing a basic Error. | ||
if (stackFrames.length >= 3) { | ||
// Assuming we have the stack frames, set the message to include info | ||
// about what the underlying method was, and set the name to reflect | ||
// the assertion type that failed. | ||
error.message = `Invalid call to ${stackFrames[2].functionName}() — ` + | ||
message; | ||
} | ||
throw error; | ||
} | ||
var assert = { | ||
atLeastOne, | ||
hasMethod, | ||
isInstance, | ||
isOneOf, | ||
isType, | ||
isValue, | ||
isArrayOfType, | ||
isArrayOfClass, | ||
}; | ||
/** | ||
* broadcasts the message with the given type and url | ||
* | ||
* @param {BroadcastChannel} broadcastChannel which is used to push the | ||
* updates on | ||
* @param {Object} input | ||
* @param {string} input.type Type of the message (either success or failure) | ||
* @param {string} input.url Url for which the request was queued | ||
* @private | ||
*/ | ||
function broadcastMessage({broadcastChannel, type, url}) { | ||
if(!broadcastChannel) | ||
return; | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
assert.isType({type}, 'string'); | ||
assert.isType({url}, 'string'); | ||
broadcastChannel.postMessage({ | ||
type: type, | ||
meta: broadcastMeta, | ||
payload: { | ||
url: url, | ||
}, | ||
}); | ||
} | ||
exports.broadcastMessage = broadcastMessage; | ||
@@ -499,0 +47,0 @@ |
@@ -22,11 +22,11 @@ /* | ||
const maxAge = 5*24*60*60*1000; // 5days | ||
const defaultDBName = 'bgQueueSyncDB'; | ||
const broadcastMessageAddedType = 'BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType = 'BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName = 'DEFAULT_QUEUE'; | ||
const tagNamePrefix = 'SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta = 'SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder = 'QUEUES'; | ||
const replayAllQueuesTag = 'SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
const maxAge=432000000; | ||
const defaultDBName='bgQueueSyncDB'; | ||
const broadcastMessageAddedType='BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType='BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName='DEFAULT_QUEUE'; | ||
const tagNamePrefix='SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta='SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder='QUEUES'; | ||
const replayAllQueuesTag='SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
@@ -33,0 +33,0 @@ exports.maxAge = maxAge; |
@@ -26,468 +26,6 @@ /* | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
class IDBHelper{constructor(a,b,c){if(a==void 0||b==void 0||c==void 0)throw Error('name, version, storeName must be passed to the constructor.');this._name=a,this._version=b,this._storeName=c;}_getDb(){return this._dbPromise?this._dbPromise:(this._dbPromise=idb.open(this._name,this._version,(a)=>{a.createObjectStore(this._storeName);}).then((a)=>{return a}),this._dbPromise)}close(){return this._dbPromise?this._dbPromise.then((a)=>{a.close(),this._dbPromise=null;}):void 0}put(a,b){return this._getDb().then((c)=>{const d=c.transaction(this._storeName,'readwrite'),e=d.objectStore(this._storeName);return e.put(b,a),d.complete})}delete(a){return this._getDb().then((b)=>{const c=b.transaction(this._storeName,'readwrite'),d=c.objectStore(this._storeName);return d.delete(a),c.complete})}get(a){return this._getDb().then((b)=>{return b.transaction(this._storeName).objectStore(this._storeName).get(a)})}getAllValues(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAll()})}getAllKeys(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAllKeys()})}} | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* A wrapper to store for an IDB connection to a particular ObjectStore. | ||
* | ||
* @private | ||
*/ | ||
class IDBHelper { | ||
constructor(name, version, storeName) { | ||
if (name == undefined || version == undefined || storeName == undefined) { | ||
throw Error('name, version, storeName must be passed to the ' + | ||
'constructor.'); | ||
} | ||
this._name = name; | ||
this._version = version; | ||
this._storeName = storeName; | ||
} | ||
/** | ||
* Returns a promise that resolves with an open connection to IndexedDB, | ||
* either existing or newly opened. | ||
* | ||
* @private | ||
* @return {Promise<DB>} | ||
*/ | ||
_getDb() { | ||
if (this._dbPromise) { | ||
return this._dbPromise; | ||
} | ||
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => { | ||
upgradeDB.createObjectStore(this._storeName); | ||
}) | ||
.then((db) => { | ||
return db; | ||
}); | ||
return this._dbPromise; | ||
} | ||
close() { | ||
if (!this._dbPromise) { | ||
return; | ||
} | ||
return this._dbPromise | ||
.then((db) => { | ||
db.close(); | ||
this._dbPromise = null; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies saving the key/value | ||
* pair to the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @param {Object} value | ||
* @return {Promise<T>} | ||
*/ | ||
put(key, value) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.put(value, key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies deleting an entry | ||
* from the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<T>} | ||
*/ | ||
delete(key) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.delete(key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting a key's value | ||
* from the object store. | ||
* Returns a promise that fulfills with the value. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<Object>} | ||
*/ | ||
get(key) { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.get(key); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the values | ||
* in an object store. | ||
* Returns a promise that fulfills with all the values. | ||
* | ||
* @private | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllValues() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAll(); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the keys | ||
* in an object store. | ||
* Returns a promise that fulfills with all the keys. | ||
* | ||
* @private | ||
* @param {String} storeName | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllKeys() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAllKeys(); | ||
}); | ||
} | ||
} | ||
return IDBHelper; | ||
@@ -494,0 +32,0 @@ |
@@ -26,563 +26,10 @@ /* | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
class IDBHelper{constructor(a,b,c){if(a==void 0||b==void 0||c==void 0)throw Error('name, version, storeName must be passed to the constructor.');this._name=a,this._version=b,this._storeName=c;}_getDb(){return this._dbPromise?this._dbPromise:(this._dbPromise=idb.open(this._name,this._version,(a)=>{a.createObjectStore(this._storeName);}).then((a)=>{return a}),this._dbPromise)}close(){return this._dbPromise?this._dbPromise.then((a)=>{a.close(),this._dbPromise=null;}):void 0}put(a,b){return this._getDb().then((c)=>{const d=c.transaction(this._storeName,'readwrite'),e=d.objectStore(this._storeName);return e.put(b,a),d.complete})}delete(a){return this._getDb().then((b)=>{const c=b.transaction(this._storeName,'readwrite'),d=c.objectStore(this._storeName);return d.delete(a),c.complete})}get(a){return this._getDb().then((b)=>{return b.transaction(this._storeName).objectStore(this._storeName).get(a)})}getAllValues(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAll()})}getAllKeys(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAllKeys()})}} | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
const allQueuesPlaceholder='QUEUES'; | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
async function getQueueableRequest({request:a,config:b}){let c={config:b,metadata:{creationTimestamp:Date.now()},request:{url:a.url,headers:JSON.stringify([...a.headers]),mode:a.mode,method:a.method,redirect:a.redirect,credentials:a.credentials}};const d=await a.text();return 0<d.length&&(c.request.body=d),c}async function getFetchableRequest({idbRequestObject:a}){let b={mode:a.mode,method:a.method,redirect:a.redirect,headers:new Headers(JSON.parse(a.headers)),credentials:a.credentials};return a.body&&(b.body=a.body),new Request(a.url,b)}async function cleanupQueue(a){let b=new IDBHelper(a,1,'QueueStore'),c=await b.get(allQueuesPlaceholder);return c?void(await Promise.all(c.map(async(d)=>{const e=await b.get(d);let f=[],g=[];await Promise.all(e.map(async(h)=>{const i=await b.get(h);i&&i.metadata&&i.metadata.creationTimestamp+i.config.maxAge<=Date.now()?g.push(b.delete(h)):f.push(h);})),await Promise.all(g),b.put(d,f);}))):null} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* A wrapper to store for an IDB connection to a particular ObjectStore. | ||
* | ||
* @private | ||
*/ | ||
class IDBHelper { | ||
constructor(name, version, storeName) { | ||
if (name == undefined || version == undefined || storeName == undefined) { | ||
throw Error('name, version, storeName must be passed to the ' + | ||
'constructor.'); | ||
} | ||
this._name = name; | ||
this._version = version; | ||
this._storeName = storeName; | ||
} | ||
/** | ||
* Returns a promise that resolves with an open connection to IndexedDB, | ||
* either existing or newly opened. | ||
* | ||
* @private | ||
* @return {Promise<DB>} | ||
*/ | ||
_getDb() { | ||
if (this._dbPromise) { | ||
return this._dbPromise; | ||
} | ||
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => { | ||
upgradeDB.createObjectStore(this._storeName); | ||
}) | ||
.then((db) => { | ||
return db; | ||
}); | ||
return this._dbPromise; | ||
} | ||
close() { | ||
if (!this._dbPromise) { | ||
return; | ||
} | ||
return this._dbPromise | ||
.then((db) => { | ||
db.close(); | ||
this._dbPromise = null; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies saving the key/value | ||
* pair to the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @param {Object} value | ||
* @return {Promise<T>} | ||
*/ | ||
put(key, value) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.put(value, key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies deleting an entry | ||
* from the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<T>} | ||
*/ | ||
delete(key) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.delete(key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting a key's value | ||
* from the object store. | ||
* Returns a promise that fulfills with the value. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<Object>} | ||
*/ | ||
get(key) { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.get(key); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the values | ||
* in an object store. | ||
* Returns a promise that fulfills with all the values. | ||
* | ||
* @private | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllValues() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAll(); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the keys | ||
* in an object store. | ||
* Returns a promise that fulfills with all the keys. | ||
* | ||
* @private | ||
* @param {String} storeName | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllKeys() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAllKeys(); | ||
}); | ||
} | ||
} | ||
const allQueuesPlaceholder = 'QUEUES'; | ||
/** | ||
* takes a request and gives back JSON object that is storable in IDB | ||
* | ||
* @param {Request} request request object to transform | ||
* into iDB storable object | ||
* @param {Object} config config object to be | ||
* stored along in the iDB | ||
* @return {Object} indexable object for iDB | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
async function getQueueableRequest({request, config}) { | ||
let requestObject={ | ||
config, | ||
metadata: { | ||
creationTimestamp: Date.now(), | ||
}, | ||
}; | ||
requestObject.request = { | ||
url: request.url, | ||
headers: JSON.stringify([...request.headers]), | ||
mode: request.mode, | ||
method: request.method, | ||
redirect: request.redirect, | ||
credentials: request.credentials, | ||
}; | ||
const requestBody = await request.text(); | ||
if (requestBody.length > 0) { | ||
requestObject.request.body = requestBody; | ||
} | ||
return requestObject; | ||
} | ||
/** | ||
* takes an object and return a Request object to be executed by | ||
* the browser | ||
* @param {Object} idbRequestObject | ||
* @return {Request} | ||
* @private | ||
*/ | ||
async function getFetchableRequest({idbRequestObject}) { | ||
let reqObject = { | ||
mode: idbRequestObject.mode, | ||
method: idbRequestObject.method, | ||
redirect: idbRequestObject.redirect, | ||
headers: new Headers(JSON.parse(idbRequestObject.headers)), | ||
credentials: idbRequestObject.credentials, | ||
}; | ||
if(idbRequestObject.body) { | ||
reqObject.body = idbRequestObject.body; | ||
} | ||
return new Request(idbRequestObject.url, reqObject); | ||
} | ||
/** | ||
* clean up the queue, deleting all the tasks who are either damaged or | ||
* whose maxAge has expired | ||
* | ||
* @memberOf Queue | ||
* @private | ||
* @param {string} dbName Name of database to cleanup. | ||
* @return {Promise} | ||
*/ | ||
async function cleanupQueue(dbName) { | ||
let db = new IDBHelper(dbName, 1, 'QueueStore'); | ||
let queueObj = await db.get(allQueuesPlaceholder); | ||
if(!queueObj) { | ||
return null; | ||
} | ||
await Promise.all(queueObj.map(async (queueName)=>{ | ||
const requestQueues = await db.get(queueName); | ||
let itemsToKeep = []; | ||
let deletionPromises = []; | ||
await Promise.all(requestQueues.map( async (hash) => { | ||
const requestData = await db.get(hash); | ||
if (requestData && requestData.metadata | ||
&& requestData.metadata.creationTimestamp + requestData.config.maxAge | ||
<= Date.now()) { | ||
// Delete items that are too old. | ||
deletionPromises.push(db.delete(hash)); | ||
} else { | ||
// Keep elements whose definition exists in idb. | ||
itemsToKeep.push(hash); | ||
} | ||
})); | ||
await Promise.all(deletionPromises); | ||
db.put(queueName, itemsToKeep); | ||
})); | ||
} | ||
exports.getQueueableRequest = getQueueableRequest; | ||
@@ -589,0 +36,0 @@ exports.getFetchableRequest = getFetchableRequest; |
@@ -22,459 +22,25 @@ /* | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
class LogGroup{constructor(){this._logs=[],this._childGroups=[],this._isFallbackMode=!1;const a=/Firefox\/(\d*)\.\d*/.exec(navigator.userAgent);if(a)try{const b=parseInt(a[1],10);55>b&&(this._isFallbackMode=!0);}catch(b){this._isFallbackMode=!0;}/Edge\/\d*\.\d*/.exec(navigator.userAgent)&&(this._isFallbackMode=!0);}addPrimaryLog(a){this._primaryLog=a;}addLog(a){this._logs.push(a);}addChildGroup(a){0===a._logs.length||this._childGroups.push(a);}print(){return 0===this._logs.length&&0===this._childGroups.length?void this._printLogDetails(this._primaryLog):void(this._primaryLog&&(this._isFallbackMode?this._printLogDetails(this._primaryLog):console.groupCollapsed(...this._getLogContent(this._primaryLog))),this._logs.forEach((a)=>{this._printLogDetails(a);}),this._childGroups.forEach((a)=>{a.print();}),this._primaryLog&&!this._isFallbackMode&&console.groupEnd())}_printLogDetails(a){const b=a.logFunc?a.logFunc:console.log;b(...this._getLogContent(a));}_getLogContent(a){let b=a.message;this._isFallbackMode&&'string'==typeof b&&(b=b.replace(/%c/g,''));let c=[b];return!this._isFallbackMode&&a.colors&&(c=c.concat(a.colors)),a.args&&(c=c.concat(a.args)),c}} | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
function isDevBuild(){return`dev`==`dev`} | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
self.workbox=self.workbox||{},self.workbox.LOG_LEVEL=self.workbox.LOG_LEVEL||{none:-1,verbose:0,debug:1,warn:2,error:3};const LIGHT_GREY=`#bdc3c7`; const DARK_GREY=`#7f8c8d`; const LIGHT_GREEN=`#2ecc71`; const LIGHT_YELLOW=`#f1c40f`; const LIGHT_RED=`#e74c3c`; const LIGHT_BLUE=`#3498db`;class LogHelper{constructor(){this._defaultLogLevel=isDevBuild()?self.workbox.LOG_LEVEL.debug:self.workbox.LOG_LEVEL.warn;}log(a){this._printMessage(self.workbox.LOG_LEVEL.verbose,a);}debug(a){this._printMessage(self.workbox.LOG_LEVEL.debug,a);}warn(a){this._printMessage(self.workbox.LOG_LEVEL.warn,a);}error(a){this._printMessage(self.workbox.LOG_LEVEL.error,a);}_printMessage(a,b){if(this._shouldLogMessage(a,b)){const c=this._getAllLogGroups(a,b);c.print();}}_getAllLogGroups(a,b){const c=new LogGroup,d=this._getPrimaryMessageDetails(a,b);if(c.addPrimaryLog(d),b.error){const f={message:b.error,logFunc:console.error};c.addLog(f);}const e=new LogGroup;if(b.that&&b.that.constructor&&b.that.constructor.name){const f=b.that.constructor.name;e.addLog(this._getKeyValueDetails('class',f));}return b.data&&('object'!=typeof b.data||b.data instanceof Array?e.addLog(this._getKeyValueDetails('additionalData',b.data)):Object.keys(b.data).forEach((f)=>{e.addLog(this._getKeyValueDetails(f,b.data[f]));})),c.addChildGroup(e),c}_getKeyValueDetails(a,b){return{message:`%c${a}: `,colors:[`color: ${LIGHT_BLUE}`],args:b}}_getPrimaryMessageDetails(a,b){let c,d;a===self.workbox.LOG_LEVEL.verbose?(c='Info',d=LIGHT_GREY):a===self.workbox.LOG_LEVEL.debug?(c='Debug',d=LIGHT_GREEN):a===self.workbox.LOG_LEVEL.warn?(c='Warn',d=LIGHT_YELLOW):a===self.workbox.LOG_LEVEL.error?(c='Error',d=LIGHT_RED):void 0;let e=`%c🔧 %c[${c}]`;const f=[`color: ${LIGHT_GREY}`,`color: ${d}`];let g;return'string'==typeof b?g=b:b.message&&(g=b.message),g&&(g=g.replace(/\s+/g,' '),e+=`%c ${g}`,f.push(`color: ${DARK_GREY}; font-weight: normal`)),{message:e,colors:f}}_shouldLogMessage(a,b){if(!b)return!1;let c=this._defaultLogLevel;return self&&self.workbox&&'number'==typeof self.workbox.logLevel&&(c=self.workbox.logLevel),c===self.workbox.LOG_LEVEL.none||a<c?!1:!0}}var logHelper = new LogHelper; | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
var deprecate = ((a,b,c,d)=>{Object.prototype.hasOwnProperty.call(a,b)&&(logHelper.warn(`${b} is deprecated; use ${c} instead`,{Context:d}),a[c]=a[b]);}); | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* Puts the fetched response in the IDB | ||
* | ||
* @param {Object} config | ||
* @private | ||
*/ | ||
async function putResponse({hash, idbObject, response, idbQDb}) { | ||
const _idbQHelper = idbQDb; | ||
idbObject.response = { | ||
headers: JSON.stringify([...response.headers]), | ||
status: response.status, | ||
body: await response.blob(), | ||
}; | ||
_idbQHelper.put(hash, idbObject); | ||
function createCommonjsModule(fn, module) { | ||
return module = { exports: {} }, fn(module, module.exports), module.exports; | ||
} | ||
const tagNamePrefix = 'SW_BACKGROUND_QUEUE_TAG_'; | ||
const replayAllQueuesTag = 'SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
/** | ||
* takes an object and return a Request object to be executed by | ||
* the browser | ||
* @param {Object} idbRequestObject | ||
* @return {Request} | ||
* @private | ||
*/ | ||
async function getFetchableRequest({idbRequestObject}) { | ||
let reqObject = { | ||
mode: idbRequestObject.mode, | ||
method: idbRequestObject.method, | ||
redirect: idbRequestObject.redirect, | ||
headers: new Headers(JSON.parse(idbRequestObject.headers)), | ||
credentials: idbRequestObject.credentials, | ||
}; | ||
if(idbRequestObject.body) { | ||
reqObject.body = idbRequestObject.body; | ||
} | ||
return new Request(idbRequestObject.url, reqObject); | ||
} | ||
async function putResponse({hash:a,idbObject:b,response:c,idbQDb:d}){b.response={headers:JSON.stringify([...c.headers]),status:c.status,body:await c.blob()},d.put(a,b);} | ||
/** | ||
* Class to handle all the request related | ||
* transformations, replaying, event handling | ||
* broadcasting back to controlled pages etc. | ||
* @class | ||
* @private | ||
*/ | ||
class RequestManager { | ||
/** | ||
* Initializes the request manager | ||
* stores the callbacks object, maintains config and | ||
* attaches event handler | ||
* @param {Object=} config | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
constructor({callbacks, queue}) { | ||
this._globalCallbacks = callbacks || {}; | ||
this._queue = queue; | ||
this.attachSyncHandler(); | ||
} | ||
const tagNamePrefix='SW_BACKGROUND_QUEUE_TAG_'; | ||
const replayAllQueuesTag='SW_BACKGROUND_QUEUE_TAG_REPLAY'; | ||
/** | ||
* attaches sync handler to replay requests when | ||
* sync event is fired | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
attachSyncHandler() { | ||
self.addEventListener('sync', (event) => { | ||
if(event.tag === tagNamePrefix + this._queue.queueName | ||
|| event.tag === replayAllQueuesTag) { | ||
event.waitUntil(this.replayRequests()); | ||
} | ||
}); | ||
} | ||
async function getFetchableRequest({idbRequestObject:a}){let b={mode:a.mode,method:a.method,redirect:a.redirect,headers:new Headers(JSON.parse(a.headers)),credentials:a.credentials};return a.body&&(b.body=a.body),new Request(a.url,b)} | ||
/** | ||
* function to start playing requests | ||
* in sequence | ||
* @return {void} | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
replayRequests() { | ||
return this._queue.queue.reduce((promise, hash) => { | ||
return promise | ||
.then(async (item) => { | ||
const reqData = await this._queue.getRequestFromQueue({hash}); | ||
if(reqData.response) { | ||
// check if request is not played already | ||
return; | ||
} | ||
class RequestManager{constructor({callbacks:a,queue:b}={}){a=a||{};const c='workbox-background-sync.RequestManager.callbacks';deprecate(a,'onResponse','replayDidSucceed',c),deprecate(a,'onRetryFailure','replayDidFail',c),this._globalCallbacks=a,this._queue=b,this.attachSyncHandler();}attachSyncHandler(){self.addEventListener('sync',(a)=>{(a.tag===tagNamePrefix+this._queue.queueName||a.tag===replayAllQueuesTag)&&a.waitUntil(this.replayRequests());});}async replayRequest(a){try{const b=await this._queue.getRequestFromQueue({hash:a});if(b.response)return;const c=await getFetchableRequest({idbRequestObject:b.request}),d=await fetch(c);if(!d.ok)return Promise.reject(d);putResponse({hash:a,idbObject:b,response:d.clone(),idbQDb:this._queue.idbQDb}),this._globalCallbacks.replayDidSucceed&&this._globalCallbacks.replayDidSucceed(a,d);}catch(b){return Promise.reject(b)}}async replayRequests(){const a=[];for(let b of this._queue.queue)try{await this.replayRequest(b);}catch(c){this._globalCallbacks.replayDidFail&&this._globalCallbacks.replayDidFail(b,c),a.push(c);}return 0<a.length?Promise.reject(a):Promise.resolve()}} | ||
const request = await getFetchableRequest({ | ||
idbRequestObject: reqData.request, | ||
}); | ||
return fetch(request) | ||
.then((response)=>{ | ||
if(!response.ok) { | ||
return Promise.resolve(); | ||
} else { | ||
// not blocking on putResponse. | ||
putResponse({ | ||
hash, | ||
idbObject: reqData, | ||
response: response.clone(), | ||
idbQDb: this._queue.idbQDb, | ||
}); | ||
this._globalCallbacks.onResponse | ||
&& this._globalCallbacks.onResponse(hash, response); | ||
} | ||
}) | ||
.catch((err)=>{ | ||
this._globalCallbacks.onRetryFailure | ||
&& this._globalCallbacks.onRetryFailure(hash, err); | ||
}); | ||
}); | ||
}, Promise.resolve()); | ||
} | ||
} | ||
return RequestManager; | ||
@@ -481,0 +47,0 @@ |
@@ -32,1004 +32,25 @@ /* | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
const broadcastMessageAddedType='BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType='BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName='DEFAULT_QUEUE'; | ||
const tagNamePrefix='SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta='SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder='QUEUES'; | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
async function getQueueableRequest({request:a,config:b}){let c={config:b,metadata:{creationTimestamp:Date.now()},request:{url:a.url,headers:JSON.stringify([...a.headers]),mode:a.mode,method:a.method,redirect:a.redirect,credentials:a.credentials}};const d=await a.text();return 0<d.length&&(c.request.body=d),c} | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
var stackframe=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d();})(commonjsGlobal,function(){'use strict';function c(t){return!isNaN(parseFloat(t))&&isFinite(t)}function d(t){return t[0].toUpperCase()+t.substring(1)}function e(t){return function(){return this[t]}}function f(t){if(t instanceof Object)for(var u=0;u<o.length;u++)t.hasOwnProperty(o[u])&&void 0!==t[o[u]]&&this['set'+d(o[u])](t[o[u]]);}var g=['isConstructor','isEval','isNative','isToplevel'],h=['columnNumber','lineNumber'],l=['fileName','functionName','source'],o=g.concat(h,l,['args']);f.prototype={getArgs:function(){return this.args},setArgs:function(t){if('[object Array]'!==Object.prototype.toString.call(t))throw new TypeError('Args must be an Array');this.args=t;},getEvalOrigin:function(){return this.evalOrigin},setEvalOrigin:function(t){if(t instanceof f)this.evalOrigin=t;else if(t instanceof Object)this.evalOrigin=new f(t);else throw new TypeError('Eval Origin must be an Object or StackFrame')},toString:function(){var t=this.getFunctionName()||'{anonymous}',u='('+(this.getArgs()||[]).join(',')+')',w=this.getFileName()?'@'+this.getFileName():'',x=c(this.getLineNumber())?':'+this.getLineNumber():'',y=c(this.getColumnNumber())?':'+this.getColumnNumber():'';return t+u+w+x+y}};for(var q=0;q<g.length;q++)f.prototype['get'+d(g[q])]=e(g[q]),f.prototype['set'+d(g[q])]=function(t){return function(u){this[t]=!!u;}}(g[q]);for(var r=0;r<h.length;r++)f.prototype['get'+d(h[r])]=e(h[r]),f.prototype['set'+d(h[r])]=function(t){return function(u){if(!c(u))throw new TypeError(t+' must be a Number');this[t]=+u;}}(h[r]);for(var s=0;s<l.length;s++)f.prototype['get'+d(l[s])]=e(l[s]),f.prototype['set'+d(l[s])]=function(t){return function(u){this[t]=u+'';}}(l[s]);return f});}); | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
var errorStackParser=createCommonjsModule(function(a){(function(c,d){'use strict';a.exports=d(stackframe);})(commonjsGlobal,function(d){'use strict';var f=/(^|@)\S+\:\d+/,g=/^\s*at .*(\S+\:\d+|\(native\))/m,h=/^(eval@)?(\[native code\])?$/;return{parse:function(k){if('undefined'!=typeof k.stacktrace||'undefined'!=typeof k['opera#sourceloc'])return this.parseOpera(k);if(k.stack&&k.stack.match(g))return this.parseV8OrIE(k);if(k.stack)return this.parseFFOrSafari(k);throw new Error('Cannot parse given Error object')},extractLocation:function(k){if(-1===k.indexOf(':'))return[k];var l=/(.+?)(?:\:(\d+))?(?:\:(\d+))?$/,m=l.exec(k.replace(/[\(\)]/g,''));return[m[1],m[2]||void 0,m[3]||void 0]},parseV8OrIE:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(g)},this);return l.map(function(m){-1<m.indexOf('(eval ')&&(m=m.replace(/eval code/g,'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g,''));var n=m.replace(/^\s+/,'').replace(/\(eval code/g,'(').split(/\s+/).slice(1),o=this.extractLocation(n.pop()),p=n.join(' ')||void 0,q=-1<['eval','<anonymous>'].indexOf(o[0])?void 0:o[0];return new d({functionName:p,fileName:q,lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseFFOrSafari:function(k){var l=k.stack.split('\n').filter(function(m){return!m.match(h)},this);return l.map(function(m){if(-1<m.indexOf(' > eval')&&(m=m.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g,':$1')),-1===m.indexOf('@')&&-1===m.indexOf(':'))return new d({functionName:m});var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.join('@')||void 0;return new d({functionName:p,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)},parseOpera:function(k){return!k.stacktrace||-1<k.message.indexOf('\n')&&k.message.split('\n').length>k.stacktrace.split('\n').length?this.parseOpera9(k):k.stack?this.parseOpera11(k):this.parseOpera10(k)},parseOpera9:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)/i,m=k.message.split('\n'),n=[],o=2,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera10:function(k){for(var q,l=/Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i,m=k.stacktrace.split('\n'),n=[],o=0,p=m.length;o<p;o+=2)q=l.exec(m[o]),q&&n.push(new d({functionName:q[3]||void 0,fileName:q[2],lineNumber:q[1],source:m[o]}));return n},parseOpera11:function(k){var l=k.stack.split('\n').filter(function(m){return!!m.match(f)&&!m.match(/^Error created at/)},this);return l.map(function(m){var n=m.split('@'),o=this.extractLocation(n.pop()),p=n.shift()||'',q=p.replace(/<anonymous function(: (\w+))?>/,'$2').replace(/\([^\)]*\)/g,'')||void 0,r;p.match(/\(([^\)]*)\)/)&&(r=p.replace(/^[^\(]+\(([^\)]*)\)$/,'$1'));var s=r===void 0||'[arguments not available]'===r?void 0:r.split(',');return new d({functionName:q,args:s,fileName:o[0],lineNumber:o[1],columnNumber:o[2],source:m})},this)}}});}); | ||
p.request = request; | ||
return p; | ||
} | ||
function isInstance(a,b){const c=Object.keys(a).pop();a[c]instanceof b||throwError(`The '${c}' parameter must be an instance of | ||
'${b.name}'`);}function isType(a,b){const c=Object.keys(a).pop(),d=typeof a[c];d!==b&&throwError(`The '${c}' parameter has the wrong type. (Expected: | ||
${b}, actual: ${d})`);}function throwError(a){a=a.replace(/\s+/g,' ');const b=new Error(a);b.name='assertion-failed';const c=errorStackParser.parse(b);throw 3<=c.length&&(b.message=`Invalid call to ${c[2].functionName}() — `+a),b} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function broadcastMessage({broadcastChannel:a,type:b,url:c}){a&&(isInstance({broadcastChannel:a},BroadcastChannel),isType({type:b},'string'),isType({url:c},'string'),a.postMessage({type:b,meta:broadcastMeta,payload:{url:c}}));} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
let _requestCounter=0; let _queueCounter=0;class RequestQueue{constructor({config:a,queueName:e=defaultQueueName+'_'+_queueCounter++,idbQDb:b,broadcastChannel:c,callbacks:d}){this._isQueueNameAddedToAllQueue=!1,this._queueName=e,this._config=a,this._idbQDb=b,this._broadcastChannel=c,this._globalCallbacks=d||{},this._queue=[],this.initQueue();}async initQueue(){const a=await this._idbQDb.get(this._queueName);this._queue.concat(a);}async addQueueNameToAllQueues(){if(!this._isQueueNameAddedToAllQueue){let a=await this._idbQDb.get(allQueuesPlaceholder);a=a||[],a.includes(this._queueName)||a.push(this._queueName),this._idbQDb.put(allQueuesPlaceholder,a),this._isQueueNameAddedToAllQueue=!0;}}async saveQueue(){await this._idbQDb.put(this._queueName,this._queue);}async push({request:a}){isInstance({request:a},Request);const b=`${a.url}!${Date.now()}!${_requestCounter++}`,c=await getQueueableRequest({request:a,config:this._config});this._globalCallbacks.requestWillEnqueue&&this._globalCallbacks.requestWillEnqueue(c);try{return this._queue.push(b),this.saveQueue(),this._idbQDb.put(b,c),await this.addQueueNameToAllQueues(),self.registration&&self.registration.sync.register(tagNamePrefix+this._queueName),broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageAddedType,id:b,url:a.url}),b}catch(d){return broadcastMessage({broadcastChannel:this._broadcastChannel,type:broadcastMessageFailedType,id:b,url:a.url}),d}}async getRequestFromQueue({hash:a}){if(isType({hash:a},'string'),this._queue.includes(a)){const b=await this._idbQDb.get(a);return this._globalCallbacks.requestWillDequeue&&this._globalCallbacks.requestWillDequeue(b),b}}get queue(){return Object.assign([],this._queue)}get queueName(){return this._queueName}get idbQDb(){return this._idbQDb}} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
const broadcastMessageAddedType = 'BACKGROUND_REQUESTED_ADDED'; | ||
const broadcastMessageFailedType = 'BACKGROUND_REQUESTED_FAILED'; | ||
const defaultQueueName = 'DEFAULT_QUEUE'; | ||
const tagNamePrefix = 'SW_BACKGROUND_QUEUE_TAG_'; | ||
const broadcastMeta = 'SW_BACKGROUND_SYNC_QUEUE'; | ||
const allQueuesPlaceholder = 'QUEUES'; | ||
/** | ||
* takes a request and gives back JSON object that is storable in IDB | ||
* | ||
* @param {Request} request request object to transform | ||
* into iDB storable object | ||
* @param {Object} config config object to be | ||
* stored along in the iDB | ||
* @return {Object} indexable object for iDB | ||
* | ||
* @memberOf RequestManager | ||
* @private | ||
*/ | ||
async function getQueueableRequest({request, config}) { | ||
let requestObject={ | ||
config, | ||
metadata: { | ||
creationTimestamp: Date.now(), | ||
}, | ||
}; | ||
requestObject.request = { | ||
url: request.url, | ||
headers: JSON.stringify([...request.headers]), | ||
mode: request.mode, | ||
method: request.method, | ||
redirect: request.redirect, | ||
credentials: request.credentials, | ||
}; | ||
const requestBody = await request.text(); | ||
if (requestBody.length > 0) { | ||
requestObject.request.body = requestBody; | ||
} | ||
return requestObject; | ||
} | ||
var stackframe = createCommonjsModule(function (module, exports) { | ||
(function (root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('stackframe', [], factory); | ||
} else { | ||
module.exports = factory(); | ||
} | ||
}(commonjsGlobal, function () { | ||
'use strict'; | ||
function _isNumber(n) { | ||
return !isNaN(parseFloat(n)) && isFinite(n); | ||
} | ||
function _capitalize(str) { | ||
return str[0].toUpperCase() + str.substring(1); | ||
} | ||
function _getter(p) { | ||
return function () { | ||
return this[p]; | ||
}; | ||
} | ||
var booleanProps = ['isConstructor', 'isEval', 'isNative', 'isToplevel']; | ||
var numericProps = ['columnNumber', 'lineNumber']; | ||
var stringProps = ['fileName', 'functionName', 'source']; | ||
var arrayProps = ['args']; | ||
function StackFrame(obj) { | ||
if (obj instanceof Object) { | ||
var props = booleanProps.concat(numericProps.concat(stringProps.concat(arrayProps))); | ||
for (var i = 0; i < props.length; i++) { | ||
if (obj.hasOwnProperty(props[i]) && obj[props[i]] !== undefined) { | ||
this['set' + _capitalize(props[i])](obj[props[i]]); | ||
} | ||
} | ||
} | ||
} | ||
StackFrame.prototype = { | ||
getArgs: function () { | ||
return this.args; | ||
}, | ||
setArgs: function (v) { | ||
if (Object.prototype.toString.call(v) !== '[object Array]') { | ||
throw new TypeError('Args must be an Array'); | ||
} | ||
this.args = v; | ||
}, | ||
getEvalOrigin: function () { | ||
return this.evalOrigin; | ||
}, | ||
setEvalOrigin: function (v) { | ||
if (v instanceof StackFrame) { | ||
this.evalOrigin = v; | ||
} else if (v instanceof Object) { | ||
this.evalOrigin = new StackFrame(v); | ||
} else { | ||
throw new TypeError('Eval Origin must be an Object or StackFrame'); | ||
} | ||
}, | ||
toString: function () { | ||
var functionName = this.getFunctionName() || '{anonymous}'; | ||
var args = '(' + (this.getArgs() || []).join(',') + ')'; | ||
var fileName = this.getFileName() ? ('@' + this.getFileName()) : ''; | ||
var lineNumber = _isNumber(this.getLineNumber()) ? (':' + this.getLineNumber()) : ''; | ||
var columnNumber = _isNumber(this.getColumnNumber()) ? (':' + this.getColumnNumber()) : ''; | ||
return functionName + args + fileName + lineNumber + columnNumber; | ||
} | ||
}; | ||
for (var i = 0; i < booleanProps.length; i++) { | ||
StackFrame.prototype['get' + _capitalize(booleanProps[i])] = _getter(booleanProps[i]); | ||
StackFrame.prototype['set' + _capitalize(booleanProps[i])] = (function (p) { | ||
return function (v) { | ||
this[p] = Boolean(v); | ||
}; | ||
})(booleanProps[i]); | ||
} | ||
for (var j = 0; j < numericProps.length; j++) { | ||
StackFrame.prototype['get' + _capitalize(numericProps[j])] = _getter(numericProps[j]); | ||
StackFrame.prototype['set' + _capitalize(numericProps[j])] = (function (p) { | ||
return function (v) { | ||
if (!_isNumber(v)) { | ||
throw new TypeError(p + ' must be a Number'); | ||
} | ||
this[p] = Number(v); | ||
}; | ||
})(numericProps[j]); | ||
} | ||
for (var k = 0; k < stringProps.length; k++) { | ||
StackFrame.prototype['get' + _capitalize(stringProps[k])] = _getter(stringProps[k]); | ||
StackFrame.prototype['set' + _capitalize(stringProps[k])] = (function (p) { | ||
return function (v) { | ||
this[p] = String(v); | ||
}; | ||
})(stringProps[k]); | ||
} | ||
return StackFrame; | ||
})); | ||
}); | ||
var errorStackParser = createCommonjsModule(function (module, exports) { | ||
(function(root, factory) { | ||
'use strict'; | ||
// Universal Module Definition (UMD) to support AMD, CommonJS/Node.js, Rhino, and browsers. | ||
/* istanbul ignore next */ | ||
if (typeof undefined === 'function' && undefined.amd) { | ||
undefined('error-stack-parser', ['stackframe'], factory); | ||
} else { | ||
module.exports = factory(stackframe); | ||
} | ||
}(commonjsGlobal, function ErrorStackParser(StackFrame) { | ||
'use strict'; | ||
var FIREFOX_SAFARI_STACK_REGEXP = /(^|@)\S+\:\d+/; | ||
var CHROME_IE_STACK_REGEXP = /^\s*at .*(\S+\:\d+|\(native\))/m; | ||
var SAFARI_NATIVE_CODE_REGEXP = /^(eval@)?(\[native code\])?$/; | ||
return { | ||
/** | ||
* Given an Error object, extract the most information from it. | ||
* | ||
* @param {Error} error object | ||
* @return {Array} of StackFrames | ||
*/ | ||
parse: function ErrorStackParser$$parse(error) { | ||
if (typeof error.stacktrace !== 'undefined' || typeof error['opera#sourceloc'] !== 'undefined') { | ||
return this.parseOpera(error); | ||
} else if (error.stack && error.stack.match(CHROME_IE_STACK_REGEXP)) { | ||
return this.parseV8OrIE(error); | ||
} else if (error.stack) { | ||
return this.parseFFOrSafari(error); | ||
} else { | ||
throw new Error('Cannot parse given Error object'); | ||
} | ||
}, | ||
// Separate line and column numbers from a string of the form: (URI:Line:Column) | ||
extractLocation: function ErrorStackParser$$extractLocation(urlLike) { | ||
// Fail-fast but return locations like "(native)" | ||
if (urlLike.indexOf(':') === -1) { | ||
return [urlLike]; | ||
} | ||
var regExp = /(.+?)(?:\:(\d+))?(?:\:(\d+))?$/; | ||
var parts = regExp.exec(urlLike.replace(/[\(\)]/g, '')); | ||
return [parts[1], parts[2] || undefined, parts[3] || undefined]; | ||
}, | ||
parseV8OrIE: function ErrorStackParser$$parseV8OrIE(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(CHROME_IE_STACK_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
if (line.indexOf('(eval ') > -1) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
line = line.replace(/eval code/g, 'eval').replace(/(\(eval at [^\()]*)|(\)\,.*$)/g, ''); | ||
} | ||
var tokens = line.replace(/^\s+/, '').replace(/\(eval code/g, '(').split(/\s+/).slice(1); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join(' ') || undefined; | ||
var fileName = ['eval', '<anonymous>'].indexOf(locationParts[0]) > -1 ? undefined : locationParts[0]; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: fileName, | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
}, | ||
parseFFOrSafari: function ErrorStackParser$$parseFFOrSafari(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !line.match(SAFARI_NATIVE_CODE_REGEXP); | ||
}, this); | ||
return filtered.map(function(line) { | ||
// Throw away eval information until we implement stacktrace.js/stackframe#8 | ||
if (line.indexOf(' > eval') > -1) { | ||
line = line.replace(/ line (\d+)(?: > eval line \d+)* > eval\:\d+\:\d+/g, ':$1'); | ||
} | ||
if (line.indexOf('@') === -1 && line.indexOf(':') === -1) { | ||
// Safari eval frames only have function names and nothing else | ||
return new StackFrame({ | ||
functionName: line | ||
}); | ||
} else { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionName = tokens.join('@') || undefined; | ||
return new StackFrame({ | ||
functionName: functionName, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
} | ||
}, this); | ||
}, | ||
parseOpera: function ErrorStackParser$$parseOpera(e) { | ||
if (!e.stacktrace || (e.message.indexOf('\n') > -1 && | ||
e.message.split('\n').length > e.stacktrace.split('\n').length)) { | ||
return this.parseOpera9(e); | ||
} else if (!e.stack) { | ||
return this.parseOpera10(e); | ||
} else { | ||
return this.parseOpera11(e); | ||
} | ||
}, | ||
parseOpera9: function ErrorStackParser$$parseOpera9(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)/i; | ||
var lines = e.message.split('\n'); | ||
var result = []; | ||
for (var i = 2, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push(new StackFrame({ | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
})); | ||
} | ||
} | ||
return result; | ||
}, | ||
parseOpera10: function ErrorStackParser$$parseOpera10(e) { | ||
var lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i; | ||
var lines = e.stacktrace.split('\n'); | ||
var result = []; | ||
for (var i = 0, len = lines.length; i < len; i += 2) { | ||
var match = lineRE.exec(lines[i]); | ||
if (match) { | ||
result.push( | ||
new StackFrame({ | ||
functionName: match[3] || undefined, | ||
fileName: match[2], | ||
lineNumber: match[1], | ||
source: lines[i] | ||
}) | ||
); | ||
} | ||
} | ||
return result; | ||
}, | ||
// Opera 10.65+ Error.stack very similar to FF/Safari | ||
parseOpera11: function ErrorStackParser$$parseOpera11(error) { | ||
var filtered = error.stack.split('\n').filter(function(line) { | ||
return !!line.match(FIREFOX_SAFARI_STACK_REGEXP) && !line.match(/^Error created at/); | ||
}, this); | ||
return filtered.map(function(line) { | ||
var tokens = line.split('@'); | ||
var locationParts = this.extractLocation(tokens.pop()); | ||
var functionCall = (tokens.shift() || ''); | ||
var functionName = functionCall | ||
.replace(/<anonymous function(: (\w+))?>/, '$2') | ||
.replace(/\([^\)]*\)/g, '') || undefined; | ||
var argsRaw; | ||
if (functionCall.match(/\(([^\)]*)\)/)) { | ||
argsRaw = functionCall.replace(/^[^\(]+\(([^\)]*)\)$/, '$1'); | ||
} | ||
var args = (argsRaw === undefined || argsRaw === '[arguments not available]') ? | ||
undefined : argsRaw.split(','); | ||
return new StackFrame({ | ||
functionName: functionName, | ||
args: args, | ||
fileName: locationParts[0], | ||
lineNumber: locationParts[1], | ||
columnNumber: locationParts[2], | ||
source: line | ||
}); | ||
}, this); | ||
} | ||
}; | ||
})); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
function atLeastOne(object) { | ||
const parameters = Object.keys(object); | ||
if (!parameters.some((parameter) => object[parameter] !== undefined)) { | ||
throwError('Please set at least one of the following parameters: ' + | ||
parameters.map((p) => `'${p}'`).join(', ')); | ||
} | ||
} | ||
function hasMethod(object, expectedMethod) { | ||
const parameter = Object.keys(object).pop(); | ||
const type = typeof object[parameter][expectedMethod]; | ||
if (type !== 'function') { | ||
throwError(`The '${parameter}' parameter must be an object that exposes a | ||
'${expectedMethod}' method.`); | ||
} | ||
} | ||
function isInstance(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!(object[parameter] instanceof expectedClass)) { | ||
throwError(`The '${parameter}' parameter must be an instance of | ||
'${expectedClass.name}'`); | ||
} | ||
} | ||
function isOneOf(object, values) { | ||
const parameter = Object.keys(object).pop(); | ||
if (!values.includes(object[parameter])) { | ||
throwError(`The '${parameter}' parameter must be set to one of the | ||
following: ${values}`); | ||
} | ||
} | ||
function isType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualType = typeof object[parameter]; | ||
if (actualType !== expectedType) { | ||
throwError(`The '${parameter}' parameter has the wrong type. (Expected: | ||
${expectedType}, actual: ${actualType})`); | ||
} | ||
} | ||
function isArrayOfType(object, expectedType) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedType}' elements.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (typeof item !== expectedType) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isArrayOfClass(object, expectedClass) { | ||
const parameter = Object.keys(object).pop(); | ||
const message = `The '${parameter}' parameter should be an array containing | ||
one or more '${expectedClass.name}' instances.`; | ||
if (!Array.isArray(object[parameter])) { | ||
throwError(message); | ||
} | ||
for (let item of object[parameter]) { | ||
if (!(item instanceof expectedClass)) { | ||
throwError(message); | ||
} | ||
} | ||
} | ||
function isValue(object, expectedValue) { | ||
const parameter = Object.keys(object).pop(); | ||
const actualValue = object[parameter]; | ||
if (actualValue !== expectedValue) { | ||
throwError(`The '${parameter}' parameter has the wrong value. (Expected: | ||
${expectedValue}, actual: ${actualValue})`); | ||
} | ||
} | ||
function throwError(message) { | ||
// Collapse any newlines or whitespace into a single space. | ||
message = message.replace(/\s+/g, ' '); | ||
const error = new Error(message); | ||
error.name = 'assertion-failed'; | ||
const stackFrames = errorStackParser.parse(error); | ||
// If, for some reason, we don't have all the stack information we need, | ||
// we'll just end up throwing a basic Error. | ||
if (stackFrames.length >= 3) { | ||
// Assuming we have the stack frames, set the message to include info | ||
// about what the underlying method was, and set the name to reflect | ||
// the assertion type that failed. | ||
error.message = `Invalid call to ${stackFrames[2].functionName}() — ` + | ||
message; | ||
} | ||
throw error; | ||
} | ||
var assert = { | ||
atLeastOne, | ||
hasMethod, | ||
isInstance, | ||
isOneOf, | ||
isType, | ||
isValue, | ||
isArrayOfType, | ||
isArrayOfClass, | ||
}; | ||
/** | ||
* broadcasts the message with the given type and url | ||
* | ||
* @param {BroadcastChannel} broadcastChannel which is used to push the | ||
* updates on | ||
* @param {Object} input | ||
* @param {string} input.type Type of the message (either success or failure) | ||
* @param {string} input.url Url for which the request was queued | ||
* @private | ||
*/ | ||
function broadcastMessage({broadcastChannel, type, url}) { | ||
if(!broadcastChannel) | ||
return; | ||
assert.isInstance({broadcastChannel}, BroadcastChannel); | ||
assert.isType({type}, 'string'); | ||
assert.isType({url}, 'string'); | ||
broadcastChannel.postMessage({ | ||
type: type, | ||
meta: broadcastMeta, | ||
payload: { | ||
url: url, | ||
}, | ||
}); | ||
} | ||
let _requestCounter = 0; | ||
let _queueCounter = 0; | ||
/** | ||
* Queue class to maintain and perform on the logical requests queue | ||
* | ||
* @class RequestQueue | ||
* @private | ||
*/ | ||
class RequestQueue { | ||
/** | ||
* Creates an instance of RequestQueue. | ||
* | ||
* @param {Object} config | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
constructor({ | ||
config, | ||
queueName = defaultQueueName + '_' + _queueCounter++, | ||
idbQDb, | ||
broadcastChannel, | ||
}) { | ||
this._isQueueNameAddedToAllQueue = false; | ||
this._queueName = queueName; | ||
this._config = config; | ||
this._idbQDb = idbQDb; | ||
this._broadcastChannel = broadcastChannel; | ||
this._queue = []; | ||
this.initQueue(); | ||
} | ||
/** | ||
* initializes the queue from the IDB store | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async initQueue() { | ||
const idbQueue = await this._idbQDb.get(this._queueName); | ||
this._queue.concat(idbQueue); | ||
} | ||
/** | ||
* adds the current queueName to all queue array | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async addQueueNameToAllQueues() { | ||
if(!this._isQueueNameAddedToAllQueue) { | ||
let allQueues = await this._idbQDb.get(allQueuesPlaceholder); | ||
allQueues = allQueues || []; | ||
if(!allQueues.includes(this._queueName)) { | ||
allQueues.push(this._queueName); | ||
} | ||
this._idbQDb.put(allQueuesPlaceholder, allQueues); | ||
this._isQueueNameAddedToAllQueue = true; | ||
} | ||
} | ||
/** | ||
* saves the logical queue to IDB | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
async saveQueue() { | ||
await this._idbQDb.put(this._queueName, this._queue); | ||
} | ||
/** | ||
* push any request to background sync queue which would be played later | ||
* preferably when network comes back | ||
* | ||
* @param {Request} request request object to be queued by this | ||
* | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async push({request}) { | ||
assert.isInstance({request}, Request); | ||
const hash = `${request.url}!${Date.now()}!${_requestCounter++}`; | ||
const queuableRequest = | ||
await getQueueableRequest({ | ||
request, | ||
config: this._config, | ||
}); | ||
try{ | ||
this._queue.push(hash); | ||
// add to queue | ||
this.saveQueue(); | ||
this._idbQDb.put(hash, queuableRequest); | ||
await this.addQueueNameToAllQueues(); | ||
// register sync | ||
self.registration && | ||
self.registration.sync.register(tagNamePrefix + this._queueName); | ||
// broadcast the success of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageAddedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} catch(e) { | ||
// broadcast the failure of request added to the queue | ||
broadcastMessage({ | ||
broadcastChannel: this._broadcastChannel, | ||
type: broadcastMessageFailedType, | ||
id: hash, | ||
url: request.url, | ||
}); | ||
} | ||
} | ||
/** | ||
* get the Request from the queue at a particular index | ||
* | ||
* @param {string} hash hash of the request at the given index | ||
* @return {Request} request object corresponding to given hash | ||
* @memberOf Queue | ||
* @private | ||
*/ | ||
async getRequestFromQueue({hash}) { | ||
assert.isType({hash}, 'string'); | ||
if(this._queue.includes(hash)) { | ||
return await this._idbQDb.get(hash); | ||
} | ||
} | ||
/** | ||
* returns the instance of queue. | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queue() { | ||
return Object.assign([], this._queue); | ||
} | ||
/** | ||
* returns the name of the current queue | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get queueName() { | ||
return this._queueName; | ||
} | ||
/** | ||
* returns the instance of IDBStore | ||
* | ||
* @readonly | ||
* | ||
* @memberOf RequestQueue | ||
* @private | ||
*/ | ||
get idbQDb() { | ||
return this._idbQDb; | ||
} | ||
} | ||
return RequestQueue; | ||
@@ -1036,0 +57,0 @@ |
@@ -26,503 +26,8 @@ /* | ||
var idb = createCommonjsModule(function (module) { | ||
'use strict'; | ||
var idb=createCommonjsModule(function(a){'use strict';(function(){function b(r){return Array.prototype.slice.call(r)}function c(r){return new Promise(function(s,t){r.onsuccess=function(){s(r.result);},r.onerror=function(){t(r.error);};})}function d(r,s,t){var u,v=new Promise(function(w,x){u=r[s].apply(r,t),c(u).then(w,x);});return v.request=u,v}function e(r,s,t){var u=d(r,s,t);return u.then(function(v){return v?new k(v,u.request):void 0})}function f(r,s,t){t.forEach(function(u){Object.defineProperty(r.prototype,u,{get:function(){return this[s][u]},set:function(v){this[s][u]=v;}});});}function g(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return d(this[s],v,arguments)});});}function h(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return this[s][v].apply(this[s],arguments)});});}function i(r,s,t,u){u.forEach(function(v){v in t.prototype&&(r.prototype[v]=function(){return e(this[s],v,arguments)});});}function j(r){this._index=r;}function k(r,s){this._cursor=r,this._request=s;}function l(r){this._store=r;}function m(r){this._tx=r,this.complete=new Promise(function(s,t){r.oncomplete=function(){s();},r.onerror=function(){t(r.error);},r.onabort=function(){t(r.error);};});}function n(r,s,t){this._db=r,this.oldVersion=s,this.transaction=new m(t);}function o(r){this._db=r;}f(j,'_index',['name','keyPath','multiEntry','unique']),g(j,'_index',IDBIndex,['get','getKey','getAll','getAllKeys','count']),i(j,'_index',IDBIndex,['openCursor','openKeyCursor']),f(k,'_cursor',['direction','key','primaryKey','value']),g(k,'_cursor',IDBCursor,['update','delete']),['advance','continue','continuePrimaryKey'].forEach(function(r){r in IDBCursor.prototype&&(k.prototype[r]=function(){var s=this,t=arguments;return Promise.resolve().then(function(){return s._cursor[r].apply(s._cursor,t),c(s._request).then(function(u){return u?new k(u,s._request):void 0})})});}),l.prototype.createIndex=function(){return new j(this._store.createIndex.apply(this._store,arguments))},l.prototype.index=function(){return new j(this._store.index.apply(this._store,arguments))},f(l,'_store',['name','keyPath','indexNames','autoIncrement']),g(l,'_store',IDBObjectStore,['put','add','delete','clear','get','getAll','getKey','getAllKeys','count']),i(l,'_store',IDBObjectStore,['openCursor','openKeyCursor']),h(l,'_store',IDBObjectStore,['deleteIndex']),m.prototype.objectStore=function(){return new l(this._tx.objectStore.apply(this._tx,arguments))},f(m,'_tx',['objectStoreNames','mode']),h(m,'_tx',IDBTransaction,['abort']),n.prototype.createObjectStore=function(){return new l(this._db.createObjectStore.apply(this._db,arguments))},f(n,'_db',['name','version','objectStoreNames']),h(n,'_db',IDBDatabase,['deleteObjectStore','close']),o.prototype.transaction=function(){return new m(this._db.transaction.apply(this._db,arguments))},f(o,'_db',['name','version','objectStoreNames']),h(o,'_db',IDBDatabase,['close']),['openCursor','openKeyCursor'].forEach(function(r){[l,j].forEach(function(s){s.prototype[r.replace('open','iterate')]=function(){var t=b(arguments),u=t[t.length-1],v=this._store||this._index,w=v[r].apply(v,t.slice(0,-1));w.onsuccess=function(){u(w.result);};};});}),[j,l].forEach(function(r){r.prototype.getAll||(r.prototype.getAll=function(s,t){var u=this,v=[];return new Promise(function(w){u.iterateCursor(s,function(x){return x?(v.push(x.value),void 0!==t&&v.length==t?void w(v):void x.continue()):void w(v)});})});});var q={open:function(r,s,t){var u=d(indexedDB,'open',[r,s]),v=u.request;return v.onupgradeneeded=function(w){t&&t(new n(v.result,w.oldVersion,v.transaction));},u.then(function(w){return new o(w)})},delete:function(r){return d(indexedDB,'deleteDatabase',[r])}};a.exports=q,a.exports.default=a.exports;})();}); | ||
(function() { | ||
function toArray(arr) { | ||
return Array.prototype.slice.call(arr); | ||
} | ||
class IDBHelper{constructor(a,b,c){if(a==void 0||b==void 0||c==void 0)throw Error('name, version, storeName must be passed to the constructor.');this._name=a,this._version=b,this._storeName=c;}_getDb(){return this._dbPromise?this._dbPromise:(this._dbPromise=idb.open(this._name,this._version,(a)=>{a.createObjectStore(this._storeName);}).then((a)=>{return a}),this._dbPromise)}close(){return this._dbPromise?this._dbPromise.then((a)=>{a.close(),this._dbPromise=null;}):void 0}put(a,b){return this._getDb().then((c)=>{const d=c.transaction(this._storeName,'readwrite'),e=d.objectStore(this._storeName);return e.put(b,a),d.complete})}delete(a){return this._getDb().then((b)=>{const c=b.transaction(this._storeName,'readwrite'),d=c.objectStore(this._storeName);return d.delete(a),c.complete})}get(a){return this._getDb().then((b)=>{return b.transaction(this._storeName).objectStore(this._storeName).get(a)})}getAllValues(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAll()})}getAllKeys(){return this._getDb().then((a)=>{return a.transaction(this._storeName).objectStore(this._storeName).getAllKeys()})}} | ||
function promisifyRequest(request) { | ||
return new Promise(function(resolve, reject) { | ||
request.onsuccess = function() { | ||
resolve(request.result); | ||
}; | ||
async function putResponse({hash:a,idbObject:b,response:c,idbQDb:d}){b.response={headers:JSON.stringify([...c.headers]),status:c.status,body:await c.blob()},d.put(a,b);}async function getResponse({id:a,dbName:b}){const c=new IDBHelper(b,1,'QueueStore'),d=await c.get(a);return d&&d.response?d.response:null} | ||
request.onerror = function() { | ||
reject(request.error); | ||
}; | ||
}); | ||
} | ||
function promisifyRequestCall(obj, method, args) { | ||
var request; | ||
var p = new Promise(function(resolve, reject) { | ||
request = obj[method].apply(obj, args); | ||
promisifyRequest(request).then(resolve, reject); | ||
}); | ||
p.request = request; | ||
return p; | ||
} | ||
function promisifyCursorRequestCall(obj, method, args) { | ||
var p = promisifyRequestCall(obj, method, args); | ||
return p.then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, p.request); | ||
}); | ||
} | ||
function proxyProperties(ProxyClass, targetProp, properties) { | ||
properties.forEach(function(prop) { | ||
Object.defineProperty(ProxyClass.prototype, prop, { | ||
get: function() { | ||
return this[targetProp][prop]; | ||
}, | ||
set: function(val) { | ||
this[targetProp][prop] = val; | ||
} | ||
}); | ||
}); | ||
} | ||
function proxyRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function proxyMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return this[targetProp][prop].apply(this[targetProp], arguments); | ||
}; | ||
}); | ||
} | ||
function proxyCursorRequestMethods(ProxyClass, targetProp, Constructor, properties) { | ||
properties.forEach(function(prop) { | ||
if (!(prop in Constructor.prototype)) return; | ||
ProxyClass.prototype[prop] = function() { | ||
return promisifyCursorRequestCall(this[targetProp], prop, arguments); | ||
}; | ||
}); | ||
} | ||
function Index(index) { | ||
this._index = index; | ||
} | ||
proxyProperties(Index, '_index', [ | ||
'name', | ||
'keyPath', | ||
'multiEntry', | ||
'unique' | ||
]); | ||
proxyRequestMethods(Index, '_index', IDBIndex, [ | ||
'get', | ||
'getKey', | ||
'getAll', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(Index, '_index', IDBIndex, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
function Cursor(cursor, request) { | ||
this._cursor = cursor; | ||
this._request = request; | ||
} | ||
proxyProperties(Cursor, '_cursor', [ | ||
'direction', | ||
'key', | ||
'primaryKey', | ||
'value' | ||
]); | ||
proxyRequestMethods(Cursor, '_cursor', IDBCursor, [ | ||
'update', | ||
'delete' | ||
]); | ||
// proxy 'next' methods | ||
['advance', 'continue', 'continuePrimaryKey'].forEach(function(methodName) { | ||
if (!(methodName in IDBCursor.prototype)) return; | ||
Cursor.prototype[methodName] = function() { | ||
var cursor = this; | ||
var args = arguments; | ||
return Promise.resolve().then(function() { | ||
cursor._cursor[methodName].apply(cursor._cursor, args); | ||
return promisifyRequest(cursor._request).then(function(value) { | ||
if (!value) return; | ||
return new Cursor(value, cursor._request); | ||
}); | ||
}); | ||
}; | ||
}); | ||
function ObjectStore(store) { | ||
this._store = store; | ||
} | ||
ObjectStore.prototype.createIndex = function() { | ||
return new Index(this._store.createIndex.apply(this._store, arguments)); | ||
}; | ||
ObjectStore.prototype.index = function() { | ||
return new Index(this._store.index.apply(this._store, arguments)); | ||
}; | ||
proxyProperties(ObjectStore, '_store', [ | ||
'name', | ||
'keyPath', | ||
'indexNames', | ||
'autoIncrement' | ||
]); | ||
proxyRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'put', | ||
'add', | ||
'delete', | ||
'clear', | ||
'get', | ||
'getAll', | ||
'getKey', | ||
'getAllKeys', | ||
'count' | ||
]); | ||
proxyCursorRequestMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'openCursor', | ||
'openKeyCursor' | ||
]); | ||
proxyMethods(ObjectStore, '_store', IDBObjectStore, [ | ||
'deleteIndex' | ||
]); | ||
function Transaction(idbTransaction) { | ||
this._tx = idbTransaction; | ||
this.complete = new Promise(function(resolve, reject) { | ||
idbTransaction.oncomplete = function() { | ||
resolve(); | ||
}; | ||
idbTransaction.onerror = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
idbTransaction.onabort = function() { | ||
reject(idbTransaction.error); | ||
}; | ||
}); | ||
} | ||
Transaction.prototype.objectStore = function() { | ||
return new ObjectStore(this._tx.objectStore.apply(this._tx, arguments)); | ||
}; | ||
proxyProperties(Transaction, '_tx', [ | ||
'objectStoreNames', | ||
'mode' | ||
]); | ||
proxyMethods(Transaction, '_tx', IDBTransaction, [ | ||
'abort' | ||
]); | ||
function UpgradeDB(db, oldVersion, transaction) { | ||
this._db = db; | ||
this.oldVersion = oldVersion; | ||
this.transaction = new Transaction(transaction); | ||
} | ||
UpgradeDB.prototype.createObjectStore = function() { | ||
return new ObjectStore(this._db.createObjectStore.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(UpgradeDB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(UpgradeDB, '_db', IDBDatabase, [ | ||
'deleteObjectStore', | ||
'close' | ||
]); | ||
function DB(db) { | ||
this._db = db; | ||
} | ||
DB.prototype.transaction = function() { | ||
return new Transaction(this._db.transaction.apply(this._db, arguments)); | ||
}; | ||
proxyProperties(DB, '_db', [ | ||
'name', | ||
'version', | ||
'objectStoreNames' | ||
]); | ||
proxyMethods(DB, '_db', IDBDatabase, [ | ||
'close' | ||
]); | ||
// Add cursor iterators | ||
// TODO: remove this once browsers do the right thing with promises | ||
['openCursor', 'openKeyCursor'].forEach(function(funcName) { | ||
[ObjectStore, Index].forEach(function(Constructor) { | ||
Constructor.prototype[funcName.replace('open', 'iterate')] = function() { | ||
var args = toArray(arguments); | ||
var callback = args[args.length - 1]; | ||
var nativeObject = this._store || this._index; | ||
var request = nativeObject[funcName].apply(nativeObject, args.slice(0, -1)); | ||
request.onsuccess = function() { | ||
callback(request.result); | ||
}; | ||
}; | ||
}); | ||
}); | ||
// polyfill getAll | ||
[Index, ObjectStore].forEach(function(Constructor) { | ||
if (Constructor.prototype.getAll) return; | ||
Constructor.prototype.getAll = function(query, count) { | ||
var instance = this; | ||
var items = []; | ||
return new Promise(function(resolve) { | ||
instance.iterateCursor(query, function(cursor) { | ||
if (!cursor) { | ||
resolve(items); | ||
return; | ||
} | ||
items.push(cursor.value); | ||
if (count !== undefined && items.length == count) { | ||
resolve(items); | ||
return; | ||
} | ||
cursor.continue(); | ||
}); | ||
}); | ||
}; | ||
}); | ||
var exp = { | ||
open: function(name, version, upgradeCallback) { | ||
var p = promisifyRequestCall(indexedDB, 'open', [name, version]); | ||
var request = p.request; | ||
request.onupgradeneeded = function(event) { | ||
if (upgradeCallback) { | ||
upgradeCallback(new UpgradeDB(request.result, event.oldVersion, request.transaction)); | ||
} | ||
}; | ||
return p.then(function(db) { | ||
return new DB(db); | ||
}); | ||
}, | ||
delete: function(name) { | ||
return promisifyRequestCall(indexedDB, 'deleteDatabase', [name]); | ||
} | ||
}; | ||
{ | ||
module.exports = exp; | ||
} | ||
}()); | ||
}); | ||
/* | ||
Copyright 2016 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. | ||
*/ | ||
/* eslint-disable require-jsdoc */ | ||
/** | ||
* A wrapper to store for an IDB connection to a particular ObjectStore. | ||
* | ||
* @private | ||
*/ | ||
class IDBHelper { | ||
constructor(name, version, storeName) { | ||
if (name == undefined || version == undefined || storeName == undefined) { | ||
throw Error('name, version, storeName must be passed to the ' + | ||
'constructor.'); | ||
} | ||
this._name = name; | ||
this._version = version; | ||
this._storeName = storeName; | ||
} | ||
/** | ||
* Returns a promise that resolves with an open connection to IndexedDB, | ||
* either existing or newly opened. | ||
* | ||
* @private | ||
* @return {Promise<DB>} | ||
*/ | ||
_getDb() { | ||
if (this._dbPromise) { | ||
return this._dbPromise; | ||
} | ||
this._dbPromise = idb.open(this._name, this._version, (upgradeDB) => { | ||
upgradeDB.createObjectStore(this._storeName); | ||
}) | ||
.then((db) => { | ||
return db; | ||
}); | ||
return this._dbPromise; | ||
} | ||
close() { | ||
if (!this._dbPromise) { | ||
return; | ||
} | ||
return this._dbPromise | ||
.then((db) => { | ||
db.close(); | ||
this._dbPromise = null; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies saving the key/value | ||
* pair to the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @param {Object} value | ||
* @return {Promise<T>} | ||
*/ | ||
put(key, value) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.put(value, key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies deleting an entry | ||
* from the object store. | ||
* Returns a Promise that fulfills when the transaction completes. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<T>} | ||
*/ | ||
delete(key) { | ||
return this._getDb().then((db) => { | ||
const tx = db.transaction(this._storeName, 'readwrite'); | ||
const objectStore = tx.objectStore(this._storeName); | ||
objectStore.delete(key); | ||
return tx.complete; | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting a key's value | ||
* from the object store. | ||
* Returns a promise that fulfills with the value. | ||
* | ||
* @private | ||
* @param {String} key | ||
* @return {Promise<Object>} | ||
*/ | ||
get(key) { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.get(key); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the values | ||
* in an object store. | ||
* Returns a promise that fulfills with all the values. | ||
* | ||
* @private | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllValues() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAll(); | ||
}); | ||
} | ||
/** | ||
* Wrapper on top of the idb wrapper, which simplifies getting all the keys | ||
* in an object store. | ||
* Returns a promise that fulfills with all the keys. | ||
* | ||
* @private | ||
* @param {String} storeName | ||
* @return {Promise<Array<Object>>} | ||
*/ | ||
getAllKeys() { | ||
return this._getDb().then((db) => { | ||
return db.transaction(this._storeName) | ||
.objectStore(this._storeName) | ||
.getAllKeys(); | ||
}); | ||
} | ||
} | ||
/** | ||
* Puts the fetched response in the IDB | ||
* | ||
* @param {Object} config | ||
* @private | ||
*/ | ||
async function putResponse({hash, idbObject, response, idbQDb}) { | ||
const _idbQHelper = idbQDb; | ||
idbObject.response = { | ||
headers: JSON.stringify([...response.headers]), | ||
status: response.status, | ||
body: await response.blob(), | ||
}; | ||
_idbQHelper.put(hash, idbObject); | ||
} | ||
/** | ||
* This function returns the fetched response for the given id of the request | ||
* | ||
* @memberof module:workbox-background-sync | ||
* @private | ||
* @param {String} id The ID of the request given back by the broaadcast | ||
* channel | ||
* @return {Object} response Fetched response of the request. | ||
*/ | ||
async function getResponse({id, dbName}) { | ||
const _idbQHelper = new IDBHelper(dbName, 1, 'QueueStore'); | ||
const object = await _idbQHelper.get(id); | ||
if (object && object.response) { | ||
return object.response; | ||
} else { | ||
return null; | ||
} | ||
} | ||
exports.putResponse = putResponse; | ||
@@ -529,0 +34,0 @@ exports.getResponse = getResponse; |
{ | ||
"name": "workbox-background-sync", | ||
"version": "1.0.0", | ||
"version": "1.1.0", | ||
"description": "Queues failed requests and uses the Background Sync API to replay them when the network is available", | ||
@@ -24,4 +24,4 @@ "keywords": [ | ||
"homepage": "https://github.com/GoogleChrome/workbox/tree/master/packages/workbox-background-sync", | ||
"main": "build/importScripts/workbox-background-sync.prod.v1.0.0.js", | ||
"module": "build/modules/workbox-background-sync.prod.v1.0.0.mjs" | ||
"main": "build/importScripts/workbox-background-sync.prod.v1.1.0.js", | ||
"module": "build/modules/workbox-background-sync.prod.v1.1.0.mjs" | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
888172
995
8