12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250 |
- this.workbox = this.workbox || {};
- this.workbox.backgroundSync = (function (exports, WorkboxError_js, logger_js, assert_js, getFriendlyURL_js) {
- 'use strict';
- function _extends() {
- _extends = Object.assign || function (target) {
- for (var i = 1; i < arguments.length; i++) {
- var source = arguments[i];
- for (var key in source) {
- if (Object.prototype.hasOwnProperty.call(source, key)) {
- target[key] = source[key];
- }
- }
- }
- return target;
- };
- return _extends.apply(this, arguments);
- }
- const instanceOfAny = (object, constructors) => constructors.some(c => object instanceof c);
- let idbProxyableTypes;
- let cursorAdvanceMethods;
- function getIdbProxyableTypes() {
- return idbProxyableTypes || (idbProxyableTypes = [IDBDatabase, IDBObjectStore, IDBIndex, IDBCursor, IDBTransaction]);
- }
- function getCursorAdvanceMethods() {
- return cursorAdvanceMethods || (cursorAdvanceMethods = [IDBCursor.prototype.advance, IDBCursor.prototype.continue, IDBCursor.prototype.continuePrimaryKey]);
- }
- const cursorRequestMap = new WeakMap();
- const transactionDoneMap = new WeakMap();
- const transactionStoreNamesMap = new WeakMap();
- const transformCache = new WeakMap();
- const reverseTransformCache = new WeakMap();
- function promisifyRequest(request) {
- const promise = new Promise((resolve, reject) => {
- const unlisten = () => {
- request.removeEventListener('success', success);
- request.removeEventListener('error', error);
- };
- const success = () => {
- resolve(wrap(request.result));
- unlisten();
- };
- const error = () => {
- reject(request.error);
- unlisten();
- };
- request.addEventListener('success', success);
- request.addEventListener('error', error);
- });
- promise.then(value => {
-
-
- if (value instanceof IDBCursor) {
- cursorRequestMap.set(value, request);
- }
- }).catch(() => {});
-
- reverseTransformCache.set(promise, request);
- return promise;
- }
- function cacheDonePromiseForTransaction(tx) {
-
- if (transactionDoneMap.has(tx)) return;
- const done = new Promise((resolve, reject) => {
- const unlisten = () => {
- tx.removeEventListener('complete', complete);
- tx.removeEventListener('error', error);
- tx.removeEventListener('abort', error);
- };
- const complete = () => {
- resolve();
- unlisten();
- };
- const error = () => {
- reject(tx.error || new DOMException('AbortError', 'AbortError'));
- unlisten();
- };
- tx.addEventListener('complete', complete);
- tx.addEventListener('error', error);
- tx.addEventListener('abort', error);
- });
- transactionDoneMap.set(tx, done);
- }
- let idbProxyTraps = {
- get(target, prop, receiver) {
- if (target instanceof IDBTransaction) {
-
- if (prop === 'done') return transactionDoneMap.get(target);
- if (prop === 'objectStoreNames') {
- return target.objectStoreNames || transactionStoreNamesMap.get(target);
- }
- if (prop === 'store') {
- return receiver.objectStoreNames[1] ? undefined : receiver.objectStore(receiver.objectStoreNames[0]);
- }
- }
- return wrap(target[prop]);
- },
- set(target, prop, value) {
- target[prop] = value;
- return true;
- },
- has(target, prop) {
- if (target instanceof IDBTransaction && (prop === 'done' || prop === 'store')) {
- return true;
- }
- return prop in target;
- }
- };
- function replaceTraps(callback) {
- idbProxyTraps = callback(idbProxyTraps);
- }
- function wrapFunction(func) {
-
-
-
- if (func === IDBDatabase.prototype.transaction && !('objectStoreNames' in IDBTransaction.prototype)) {
- return function (storeNames, ...args) {
- const tx = func.call(unwrap(this), storeNames, ...args);
- transactionStoreNamesMap.set(tx, storeNames.sort ? storeNames.sort() : [storeNames]);
- return wrap(tx);
- };
- }
-
-
-
-
- if (getCursorAdvanceMethods().includes(func)) {
- return function (...args) {
-
-
- func.apply(unwrap(this), args);
- return wrap(cursorRequestMap.get(this));
- };
- }
- return function (...args) {
-
-
- return wrap(func.apply(unwrap(this), args));
- };
- }
- function transformCachableValue(value) {
- if (typeof value === 'function') return wrapFunction(value);
-
- if (value instanceof IDBTransaction) cacheDonePromiseForTransaction(value);
- if (instanceOfAny(value, getIdbProxyableTypes())) return new Proxy(value, idbProxyTraps);
- return value;
- }
- function wrap(value) {
-
-
- if (value instanceof IDBRequest) return promisifyRequest(value);
-
- if (transformCache.has(value)) return transformCache.get(value);
- const newValue = transformCachableValue(value);
-
- if (newValue !== value) {
- transformCache.set(value, newValue);
- reverseTransformCache.set(newValue, value);
- }
- return newValue;
- }
- const unwrap = value => reverseTransformCache.get(value);
-
- function openDB(name, version, {
- blocked,
- upgrade,
- blocking,
- terminated
- } = {}) {
- const request = indexedDB.open(name, version);
- const openPromise = wrap(request);
- if (upgrade) {
- request.addEventListener('upgradeneeded', event => {
- upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction));
- });
- }
- if (blocked) request.addEventListener('blocked', () => blocked());
- openPromise.then(db => {
- if (terminated) db.addEventListener('close', () => terminated());
- if (blocking) db.addEventListener('versionchange', () => blocking());
- }).catch(() => {});
- return openPromise;
- }
- const readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];
- const writeMethods = ['put', 'add', 'delete', 'clear'];
- const cachedMethods = new Map();
- function getMethod(target, prop) {
- if (!(target instanceof IDBDatabase && !(prop in target) && typeof prop === 'string')) {
- return;
- }
- if (cachedMethods.get(prop)) return cachedMethods.get(prop);
- const targetFuncName = prop.replace(/FromIndex$/, '');
- const useIndex = prop !== targetFuncName;
- const isWrite = writeMethods.includes(targetFuncName);
- if (
- !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) || !(isWrite || readMethods.includes(targetFuncName))) {
- return;
- }
- const method = async function (storeName, ...args) {
-
- const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');
- let target = tx.store;
- if (useIndex) target = target.index(args.shift());
-
-
-
-
- return (await Promise.all([target[targetFuncName](...args), isWrite && tx.done]))[0];
- };
- cachedMethods.set(prop, method);
- return method;
- }
- replaceTraps(oldTraps => _extends({}, oldTraps, {
- get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),
- has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop)
- }));
- try {
- self['workbox:background-sync:6.6.0'] && _();
- } catch (e) {}
-
- const DB_VERSION = 3;
- const DB_NAME = 'workbox-background-sync';
- const REQUEST_OBJECT_STORE_NAME = 'requests';
- const QUEUE_NAME_INDEX = 'queueName';
-
- class QueueDb {
- constructor() {
- this._db = null;
- }
-
- async addEntry(entry) {
- const db = await this.getDb();
- const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, 'readwrite', {
- durability: 'relaxed'
- });
- await tx.store.add(entry);
- await tx.done;
- }
-
- async getFirstEntryId() {
- const db = await this.getDb();
- const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.openCursor();
- return cursor === null || cursor === void 0 ? void 0 : cursor.value.id;
- }
-
- async getAllEntriesByQueueName(queueName) {
- const db = await this.getDb();
- const results = await db.getAllFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
- return results ? results : new Array();
- }
-
- async getEntryCountByQueueName(queueName) {
- const db = await this.getDb();
- return db.countFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
- }
-
- async deleteEntry(id) {
- const db = await this.getDb();
- await db.delete(REQUEST_OBJECT_STORE_NAME, id);
- }
-
- async getFirstEntryByQueueName(queueName) {
- return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'next');
- }
-
- async getLastEntryByQueueName(queueName) {
- return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'prev');
- }
-
- async getEndEntryFromIndex(query, direction) {
- const db = await this.getDb();
- const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.index(QUEUE_NAME_INDEX).openCursor(query, direction);
- return cursor === null || cursor === void 0 ? void 0 : cursor.value;
- }
-
- async getDb() {
- if (!this._db) {
- this._db = await openDB(DB_NAME, DB_VERSION, {
- upgrade: this._upgradeDb
- });
- }
- return this._db;
- }
-
- _upgradeDb(db, oldVersion) {
- if (oldVersion > 0 && oldVersion < DB_VERSION) {
- if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) {
- db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME);
- }
- }
- const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, {
- autoIncrement: true,
- keyPath: 'id'
- });
- objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, {
- unique: false
- });
- }
- }
-
-
- class QueueStore {
-
- constructor(queueName) {
- this._queueName = queueName;
- this._queueDb = new QueueDb();
- }
-
- async pushEntry(entry) {
- {
- assert_js.assert.isType(entry, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'QueueStore',
- funcName: 'pushEntry',
- paramName: 'entry'
- });
- assert_js.assert.isType(entry.requestData, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'QueueStore',
- funcName: 'pushEntry',
- paramName: 'entry.requestData'
- });
- }
- delete entry.id;
- entry.queueName = this._queueName;
- await this._queueDb.addEntry(entry);
- }
-
- async unshiftEntry(entry) {
- {
- assert_js.assert.isType(entry, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'QueueStore',
- funcName: 'unshiftEntry',
- paramName: 'entry'
- });
- assert_js.assert.isType(entry.requestData, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'QueueStore',
- funcName: 'unshiftEntry',
- paramName: 'entry.requestData'
- });
- }
- const firstId = await this._queueDb.getFirstEntryId();
- if (firstId) {
-
- entry.id = firstId - 1;
- } else {
-
- delete entry.id;
- }
- entry.queueName = this._queueName;
- await this._queueDb.addEntry(entry);
- }
-
- async popEntry() {
- return this._removeEntry(await this._queueDb.getLastEntryByQueueName(this._queueName));
- }
-
- async shiftEntry() {
- return this._removeEntry(await this._queueDb.getFirstEntryByQueueName(this._queueName));
- }
-
- async getAll() {
- return await this._queueDb.getAllEntriesByQueueName(this._queueName);
- }
-
- async size() {
- return await this._queueDb.getEntryCountByQueueName(this._queueName);
- }
-
- async deleteEntry(id) {
- await this._queueDb.deleteEntry(id);
- }
-
- async _removeEntry(entry) {
- if (entry) {
- await this.deleteEntry(entry.id);
- }
- return entry;
- }
- }
-
- const serializableProperties = ['method', 'referrer', 'referrerPolicy', 'mode', 'credentials', 'cache', 'redirect', 'integrity', 'keepalive'];
-
- class StorableRequest {
-
- static async fromRequest(request) {
- const requestData = {
- url: request.url,
- headers: {}
- };
- if (request.method !== 'GET') {
-
-
-
-
- requestData.body = await request.clone().arrayBuffer();
- }
- for (const [key, value] of request.headers.entries()) {
- requestData.headers[key] = value;
- }
- for (const prop of serializableProperties) {
- if (request[prop] !== undefined) {
- requestData[prop] = request[prop];
- }
- }
- return new StorableRequest(requestData);
- }
-
- constructor(requestData) {
- {
- assert_js.assert.isType(requestData, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'StorableRequest',
- funcName: 'constructor',
- paramName: 'requestData'
- });
- assert_js.assert.isType(requestData.url, 'string', {
- moduleName: 'workbox-background-sync',
- className: 'StorableRequest',
- funcName: 'constructor',
- paramName: 'requestData.url'
- });
- }
-
- if (requestData['mode'] === 'navigate') {
- requestData['mode'] = 'same-origin';
- }
- this._requestData = requestData;
- }
-
- toObject() {
- const requestData = Object.assign({}, this._requestData);
- requestData.headers = Object.assign({}, this._requestData.headers);
- if (requestData.body) {
- requestData.body = requestData.body.slice(0);
- }
- return requestData;
- }
-
- toRequest() {
- return new Request(this._requestData.url, this._requestData);
- }
-
- clone() {
- return new StorableRequest(this.toObject());
- }
- }
-
- const TAG_PREFIX = 'workbox-background-sync';
- const MAX_RETENTION_TIME = 60 * 24 * 7;
- const queueNames = new Set();
-
- const convertEntry = queueStoreEntry => {
- const queueEntry = {
- request: new StorableRequest(queueStoreEntry.requestData).toRequest(),
- timestamp: queueStoreEntry.timestamp
- };
- if (queueStoreEntry.metadata) {
- queueEntry.metadata = queueStoreEntry.metadata;
- }
- return queueEntry;
- };
-
- class Queue {
-
- constructor(name, {
- forceSyncFallback,
- onSync,
- maxRetentionTime
- } = {}) {
- this._syncInProgress = false;
- this._requestsAddedDuringSync = false;
- if (queueNames.has(name)) {
- throw new WorkboxError_js.WorkboxError('duplicate-queue-name', {
- name
- });
- } else {
- queueNames.add(name);
- }
- this._name = name;
- this._onSync = onSync || this.replayRequests;
- this._maxRetentionTime = maxRetentionTime || MAX_RETENTION_TIME;
- this._forceSyncFallback = Boolean(forceSyncFallback);
- this._queueStore = new QueueStore(this._name);
- this._addSyncListener();
- }
-
- get name() {
- return this._name;
- }
-
- async pushRequest(entry) {
- {
- assert_js.assert.isType(entry, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'Queue',
- funcName: 'pushRequest',
- paramName: 'entry'
- });
- assert_js.assert.isInstance(entry.request, Request, {
- moduleName: 'workbox-background-sync',
- className: 'Queue',
- funcName: 'pushRequest',
- paramName: 'entry.request'
- });
- }
- await this._addRequest(entry, 'push');
- }
-
- async unshiftRequest(entry) {
- {
- assert_js.assert.isType(entry, 'object', {
- moduleName: 'workbox-background-sync',
- className: 'Queue',
- funcName: 'unshiftRequest',
- paramName: 'entry'
- });
- assert_js.assert.isInstance(entry.request, Request, {
- moduleName: 'workbox-background-sync',
- className: 'Queue',
- funcName: 'unshiftRequest',
- paramName: 'entry.request'
- });
- }
- await this._addRequest(entry, 'unshift');
- }
-
- async popRequest() {
- return this._removeRequest('pop');
- }
-
- async shiftRequest() {
- return this._removeRequest('shift');
- }
-
- async getAll() {
- const allEntries = await this._queueStore.getAll();
- const now = Date.now();
- const unexpiredEntries = [];
- for (const entry of allEntries) {
-
-
- const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;
- if (now - entry.timestamp > maxRetentionTimeInMs) {
- await this._queueStore.deleteEntry(entry.id);
- } else {
- unexpiredEntries.push(convertEntry(entry));
- }
- }
- return unexpiredEntries;
- }
-
- async size() {
- return await this._queueStore.size();
- }
-
- async _addRequest({
- request,
- metadata,
- timestamp = Date.now()
- }, operation) {
- const storableRequest = await StorableRequest.fromRequest(request.clone());
- const entry = {
- requestData: storableRequest.toObject(),
- timestamp
- };
- if (metadata) {
- entry.metadata = metadata;
- }
- switch (operation) {
- case 'push':
- await this._queueStore.pushEntry(entry);
- break;
- case 'unshift':
- await this._queueStore.unshiftEntry(entry);
- break;
- }
- {
- logger_js.logger.log(`Request for '${getFriendlyURL_js.getFriendlyURL(request.url)}' has ` + `been added to background sync queue '${this._name}'.`);
- }
-
-
- if (this._syncInProgress) {
- this._requestsAddedDuringSync = true;
- } else {
- await this.registerSync();
- }
- }
-
- async _removeRequest(operation) {
- const now = Date.now();
- let entry;
- switch (operation) {
- case 'pop':
- entry = await this._queueStore.popEntry();
- break;
- case 'shift':
- entry = await this._queueStore.shiftEntry();
- break;
- }
- if (entry) {
-
-
- const maxRetentionTimeInMs = this._maxRetentionTime * 60 * 1000;
- if (now - entry.timestamp > maxRetentionTimeInMs) {
- return this._removeRequest(operation);
- }
- return convertEntry(entry);
- } else {
- return undefined;
- }
- }
-
- async replayRequests() {
- let entry;
- while (entry = await this.shiftRequest()) {
- try {
- await fetch(entry.request.clone());
- if ("dev" !== 'production') {
- logger_js.logger.log(`Request for '${getFriendlyURL_js.getFriendlyURL(entry.request.url)}' ` + `has been replayed in queue '${this._name}'`);
- }
- } catch (error) {
- await this.unshiftRequest(entry);
- {
- logger_js.logger.log(`Request for '${getFriendlyURL_js.getFriendlyURL(entry.request.url)}' ` + `failed to replay, putting it back in queue '${this._name}'`);
- }
- throw new WorkboxError_js.WorkboxError('queue-replay-failed', {
- name: this._name
- });
- }
- }
- {
- logger_js.logger.log(`All requests in queue '${this.name}' have successfully ` + `replayed; the queue is now empty!`);
- }
- }
-
- async registerSync() {
-
- if ('sync' in self.registration && !this._forceSyncFallback) {
- try {
- await self.registration.sync.register(`${TAG_PREFIX}:${this._name}`);
- } catch (err) {
-
-
- {
- logger_js.logger.warn(`Unable to register sync event for '${this._name}'.`, err);
- }
- }
- }
- }
-
- _addSyncListener() {
-
- if ('sync' in self.registration && !this._forceSyncFallback) {
- self.addEventListener('sync', event => {
- if (event.tag === `${TAG_PREFIX}:${this._name}`) {
- {
- logger_js.logger.log(`Background sync for tag '${event.tag}' ` + `has been received`);
- }
- const syncComplete = async () => {
- this._syncInProgress = true;
- let syncError;
- try {
- await this._onSync({
- queue: this
- });
- } catch (error) {
- if (error instanceof Error) {
- syncError = error;
-
- throw syncError;
- }
- } finally {
-
-
-
-
-
- if (this._requestsAddedDuringSync && !(syncError && !event.lastChance)) {
- await this.registerSync();
- }
- this._syncInProgress = false;
- this._requestsAddedDuringSync = false;
- }
- };
- event.waitUntil(syncComplete());
- }
- });
- } else {
- {
- logger_js.logger.log(`Background sync replaying without background sync event`);
- }
-
-
- void this._onSync({
- queue: this
- });
- }
- }
-
- static get _queueNames() {
- return queueNames;
- }
- }
-
-
- class BackgroundSyncPlugin {
-
- constructor(name, options) {
-
- this.fetchDidFail = async ({
- request
- }) => {
- await this._queue.pushRequest({
- request
- });
- };
- this._queue = new Queue(name, options);
- }
- }
- exports.BackgroundSyncPlugin = BackgroundSyncPlugin;
- exports.Queue = Queue;
- exports.QueueStore = QueueStore;
- exports.StorableRequest = StorableRequest;
- return exports;
- }({}, workbox.core._private, workbox.core._private, workbox.core._private, workbox.core._private));
|