@serwist/background-sync 8.4.3 → 9.0.0-preview.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BackgroundSyncPlugin.d.ts +1 -0
- package/dist/BackgroundSyncPlugin.d.ts.map +1 -0
- package/dist/Queue.d.ts +2 -1
- package/dist/Queue.d.ts.map +1 -0
- package/dist/QueueDb.d.ts +1 -0
- package/dist/QueueDb.d.ts.map +1 -0
- package/dist/QueueStore.d.ts +1 -0
- package/dist/QueueStore.d.ts.map +1 -0
- package/dist/StorableRequest.d.ts +1 -0
- package/dist/StorableRequest.d.ts.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +18 -17
- package/src/BackgroundSyncPlugin.ts +40 -0
- package/src/Queue.ts +444 -0
- package/src/QueueDb.ts +176 -0
- package/src/QueueStore.ts +161 -0
- package/src/StorableRequest.ts +144 -0
- package/src/index.ts +37 -0
- package/dist/index.cjs +0 -710
- package/dist/index.d.cts +0 -23
package/src/QueueDb.ts
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2021 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { DBSchema, IDBPDatabase } from "idb";
|
|
10
|
+
import { openDB } from "idb";
|
|
11
|
+
|
|
12
|
+
import type { RequestData } from "./StorableRequest.js";
|
|
13
|
+
|
|
14
|
+
interface QueueDBSchema extends DBSchema {
|
|
15
|
+
requests: {
|
|
16
|
+
key: number;
|
|
17
|
+
value: QueueStoreEntry;
|
|
18
|
+
indexes: { queueName: string };
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const DB_VERSION = 3;
|
|
23
|
+
const DB_NAME = "serwist-background-sync";
|
|
24
|
+
const REQUEST_OBJECT_STORE_NAME = "requests";
|
|
25
|
+
const QUEUE_NAME_INDEX = "queueName";
|
|
26
|
+
|
|
27
|
+
export interface UnidentifiedQueueStoreEntry {
|
|
28
|
+
requestData: RequestData;
|
|
29
|
+
timestamp: number;
|
|
30
|
+
id?: number;
|
|
31
|
+
queueName?: string;
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export interface QueueStoreEntry extends UnidentifiedQueueStoreEntry {
|
|
36
|
+
id: number;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* A class to interact directly an IndexedDB created specifically to save and
|
|
41
|
+
* retrieve QueueStoreEntries. This class encapsulates all the schema details
|
|
42
|
+
* to store the representation of a Queue.
|
|
43
|
+
*
|
|
44
|
+
* @private
|
|
45
|
+
*/
|
|
46
|
+
|
|
47
|
+
export class QueueDb {
|
|
48
|
+
private _db: IDBPDatabase<QueueDBSchema> | null = null;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Add QueueStoreEntry to underlying db.
|
|
52
|
+
*
|
|
53
|
+
* @param entry
|
|
54
|
+
*/
|
|
55
|
+
async addEntry(entry: UnidentifiedQueueStoreEntry): Promise<void> {
|
|
56
|
+
const db = await this.getDb();
|
|
57
|
+
const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, "readwrite", {
|
|
58
|
+
durability: "relaxed",
|
|
59
|
+
});
|
|
60
|
+
await tx.store.add(entry as QueueStoreEntry);
|
|
61
|
+
await tx.done;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Returns the first entry id in the ObjectStore.
|
|
66
|
+
*
|
|
67
|
+
* @returns
|
|
68
|
+
*/
|
|
69
|
+
async getFirstEntryId(): Promise<number | undefined> {
|
|
70
|
+
const db = await this.getDb();
|
|
71
|
+
const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.openCursor();
|
|
72
|
+
return cursor?.value.id;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Get all the entries filtered by index
|
|
77
|
+
*
|
|
78
|
+
* @param queueName
|
|
79
|
+
* @returns
|
|
80
|
+
*/
|
|
81
|
+
async getAllEntriesByQueueName(queueName: string): Promise<QueueStoreEntry[]> {
|
|
82
|
+
const db = await this.getDb();
|
|
83
|
+
const results = await db.getAllFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
|
|
84
|
+
return results ? results : new Array<QueueStoreEntry>();
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Returns the number of entries filtered by index
|
|
89
|
+
*
|
|
90
|
+
* @param queueName
|
|
91
|
+
* @returns
|
|
92
|
+
*/
|
|
93
|
+
async getEntryCountByQueueName(queueName: string): Promise<number> {
|
|
94
|
+
const db = await this.getDb();
|
|
95
|
+
return db.countFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Deletes a single entry by id.
|
|
100
|
+
*
|
|
101
|
+
* @param id the id of the entry to be deleted
|
|
102
|
+
*/
|
|
103
|
+
async deleteEntry(id: number): Promise<void> {
|
|
104
|
+
const db = await this.getDb();
|
|
105
|
+
await db.delete(REQUEST_OBJECT_STORE_NAME, id);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
*
|
|
110
|
+
* @param queueName
|
|
111
|
+
* @returns
|
|
112
|
+
*/
|
|
113
|
+
async getFirstEntryByQueueName(queueName: string): Promise<QueueStoreEntry | undefined> {
|
|
114
|
+
return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), "next");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
*
|
|
119
|
+
* @param queueName
|
|
120
|
+
* @returns
|
|
121
|
+
*/
|
|
122
|
+
async getLastEntryByQueueName(queueName: string): Promise<QueueStoreEntry | undefined> {
|
|
123
|
+
return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), "prev");
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Returns either the first or the last entries, depending on direction.
|
|
128
|
+
* Filtered by index.
|
|
129
|
+
*
|
|
130
|
+
* @param direction
|
|
131
|
+
* @param query
|
|
132
|
+
* @returns
|
|
133
|
+
* @private
|
|
134
|
+
*/
|
|
135
|
+
async getEndEntryFromIndex(query: IDBKeyRange, direction: IDBCursorDirection): Promise<QueueStoreEntry | undefined> {
|
|
136
|
+
const db = await this.getDb();
|
|
137
|
+
|
|
138
|
+
const cursor = await db.transaction(REQUEST_OBJECT_STORE_NAME).store.index(QUEUE_NAME_INDEX).openCursor(query, direction);
|
|
139
|
+
return cursor?.value;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Returns an open connection to the database.
|
|
144
|
+
*
|
|
145
|
+
* @private
|
|
146
|
+
*/
|
|
147
|
+
private async getDb() {
|
|
148
|
+
if (!this._db) {
|
|
149
|
+
this._db = await openDB(DB_NAME, DB_VERSION, {
|
|
150
|
+
upgrade: this._upgradeDb,
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
return this._db;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* Upgrades QueueDB
|
|
158
|
+
*
|
|
159
|
+
* @param db
|
|
160
|
+
* @param oldVersion
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
private _upgradeDb(db: IDBPDatabase<QueueDBSchema>, oldVersion: number) {
|
|
164
|
+
if (oldVersion > 0 && oldVersion < DB_VERSION) {
|
|
165
|
+
if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) {
|
|
166
|
+
db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, {
|
|
171
|
+
autoIncrement: true,
|
|
172
|
+
keyPath: "id",
|
|
173
|
+
});
|
|
174
|
+
objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, { unique: false });
|
|
175
|
+
}
|
|
176
|
+
}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
import { assert } from "@serwist/core/internal";
|
|
9
|
+
|
|
10
|
+
import type { QueueStoreEntry, UnidentifiedQueueStoreEntry } from "./QueueDb.js";
|
|
11
|
+
import { QueueDb } from "./QueueDb.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A class to manage storing requests from a Queue in IndexedDB,
|
|
15
|
+
* indexed by their queue name for easier access.
|
|
16
|
+
*
|
|
17
|
+
* Most developers will not need to access this class directly;
|
|
18
|
+
* it is exposed for advanced use cases.
|
|
19
|
+
*/
|
|
20
|
+
export class QueueStore {
|
|
21
|
+
private readonly _queueName: string;
|
|
22
|
+
private readonly _queueDb: QueueDb;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Associates this instance with a Queue instance, so entries added can be
|
|
26
|
+
* identified by their queue name.
|
|
27
|
+
*
|
|
28
|
+
* @param queueName
|
|
29
|
+
*/
|
|
30
|
+
constructor(queueName: string) {
|
|
31
|
+
this._queueName = queueName;
|
|
32
|
+
this._queueDb = new QueueDb();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Append an entry last in the queue.
|
|
37
|
+
*
|
|
38
|
+
* @param entry
|
|
39
|
+
*/
|
|
40
|
+
async pushEntry(entry: UnidentifiedQueueStoreEntry): Promise<void> {
|
|
41
|
+
if (process.env.NODE_ENV !== "production") {
|
|
42
|
+
assert!.isType(entry, "object", {
|
|
43
|
+
moduleName: "@serwist/background-sync",
|
|
44
|
+
className: "QueueStore",
|
|
45
|
+
funcName: "pushEntry",
|
|
46
|
+
paramName: "entry",
|
|
47
|
+
});
|
|
48
|
+
assert!.isType(entry.requestData, "object", {
|
|
49
|
+
moduleName: "@serwist/background-sync",
|
|
50
|
+
className: "QueueStore",
|
|
51
|
+
funcName: "pushEntry",
|
|
52
|
+
paramName: "entry.requestData",
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// biome-ignore lint/performance/noDelete: Don't specify an ID since one is automatically generated.
|
|
57
|
+
delete entry.id;
|
|
58
|
+
entry.queueName = this._queueName;
|
|
59
|
+
|
|
60
|
+
await this._queueDb.addEntry(entry);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Prepend an entry first in the queue.
|
|
65
|
+
*
|
|
66
|
+
* @param entry
|
|
67
|
+
*/
|
|
68
|
+
async unshiftEntry(entry: UnidentifiedQueueStoreEntry): Promise<void> {
|
|
69
|
+
if (process.env.NODE_ENV !== "production") {
|
|
70
|
+
assert!.isType(entry, "object", {
|
|
71
|
+
moduleName: "@serwist/background-sync",
|
|
72
|
+
className: "QueueStore",
|
|
73
|
+
funcName: "unshiftEntry",
|
|
74
|
+
paramName: "entry",
|
|
75
|
+
});
|
|
76
|
+
assert!.isType(entry.requestData, "object", {
|
|
77
|
+
moduleName: "@serwist/background-sync",
|
|
78
|
+
className: "QueueStore",
|
|
79
|
+
funcName: "unshiftEntry",
|
|
80
|
+
paramName: "entry.requestData",
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const firstId = await this._queueDb.getFirstEntryId();
|
|
85
|
+
|
|
86
|
+
if (firstId) {
|
|
87
|
+
// Pick an ID one less than the lowest ID in the object store.
|
|
88
|
+
entry.id = firstId - 1;
|
|
89
|
+
} else {
|
|
90
|
+
// biome-ignore lint/performance/noDelete: Let the auto-incrementor assign the ID.
|
|
91
|
+
delete entry.id;
|
|
92
|
+
}
|
|
93
|
+
entry.queueName = this._queueName;
|
|
94
|
+
|
|
95
|
+
await this._queueDb.addEntry(entry);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Removes and returns the last entry in the queue matching the `queueName`.
|
|
100
|
+
*
|
|
101
|
+
* @returns
|
|
102
|
+
*/
|
|
103
|
+
async popEntry(): Promise<QueueStoreEntry | undefined> {
|
|
104
|
+
return this._removeEntry(await this._queueDb.getLastEntryByQueueName(this._queueName));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Removes and returns the first entry in the queue matching the `queueName`.
|
|
109
|
+
*
|
|
110
|
+
* @returns
|
|
111
|
+
*/
|
|
112
|
+
async shiftEntry(): Promise<QueueStoreEntry | undefined> {
|
|
113
|
+
return this._removeEntry(await this._queueDb.getFirstEntryByQueueName(this._queueName));
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns all entries in the store matching the `queueName`.
|
|
118
|
+
*
|
|
119
|
+
* @returns
|
|
120
|
+
*/
|
|
121
|
+
async getAll(): Promise<QueueStoreEntry[]> {
|
|
122
|
+
return await this._queueDb.getAllEntriesByQueueName(this._queueName);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Returns the number of entries in the store matching the `queueName`.
|
|
127
|
+
*
|
|
128
|
+
* @returns
|
|
129
|
+
*/
|
|
130
|
+
async size(): Promise<number> {
|
|
131
|
+
return await this._queueDb.getEntryCountByQueueName(this._queueName);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Deletes the entry for the given ID.
|
|
136
|
+
*
|
|
137
|
+
* WARNING: this method does not ensure the deleted entry belongs to this
|
|
138
|
+
* queue (i.e. matches the `queueName`). But this limitation is acceptable
|
|
139
|
+
* as this class is not publicly exposed. An additional check would make
|
|
140
|
+
* this method slower than it needs to be.
|
|
141
|
+
*
|
|
142
|
+
* @param id
|
|
143
|
+
*/
|
|
144
|
+
async deleteEntry(id: number): Promise<void> {
|
|
145
|
+
await this._queueDb.deleteEntry(id);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Removes and returns the first or last entry in the queue (based on the
|
|
150
|
+
* `direction` argument) matching the `queueName`.
|
|
151
|
+
*
|
|
152
|
+
* @returns
|
|
153
|
+
* @private
|
|
154
|
+
*/
|
|
155
|
+
async _removeEntry(entry?: QueueStoreEntry): Promise<QueueStoreEntry | undefined> {
|
|
156
|
+
if (entry) {
|
|
157
|
+
await this.deleteEntry(entry.id);
|
|
158
|
+
}
|
|
159
|
+
return entry;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import type { MapLikeObject } from "@serwist/core";
|
|
10
|
+
import { assert } from "@serwist/core/internal";
|
|
11
|
+
|
|
12
|
+
type SerializableProperties = "method" | "referrer" | "referrerPolicy" | "mode" | "credentials" | "cache" | "redirect" | "integrity" | "keepalive";
|
|
13
|
+
|
|
14
|
+
const serializableProperties: SerializableProperties[] = [
|
|
15
|
+
"method",
|
|
16
|
+
"referrer",
|
|
17
|
+
"referrerPolicy",
|
|
18
|
+
"mode",
|
|
19
|
+
"credentials",
|
|
20
|
+
"cache",
|
|
21
|
+
"redirect",
|
|
22
|
+
"integrity",
|
|
23
|
+
"keepalive",
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
export interface RequestData extends MapLikeObject {
|
|
27
|
+
url: string;
|
|
28
|
+
headers: MapLikeObject;
|
|
29
|
+
body?: ArrayBuffer;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* A class to make it easier to serialize and de-serialize requests so they
|
|
34
|
+
* can be stored in IndexedDB.
|
|
35
|
+
*
|
|
36
|
+
* Most developers will not need to access this class directly;
|
|
37
|
+
* it is exposed for advanced use cases.
|
|
38
|
+
*/
|
|
39
|
+
class StorableRequest {
|
|
40
|
+
private readonly _requestData: RequestData;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Converts a Request object to a plain object that can be structured
|
|
44
|
+
* cloned or JSON-stringified.
|
|
45
|
+
*
|
|
46
|
+
* @param request
|
|
47
|
+
* @returns
|
|
48
|
+
*/
|
|
49
|
+
static async fromRequest(request: Request): Promise<StorableRequest> {
|
|
50
|
+
const requestData: RequestData = {
|
|
51
|
+
url: request.url,
|
|
52
|
+
headers: {},
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
// Set the body if present.
|
|
56
|
+
if (request.method !== "GET") {
|
|
57
|
+
// Use ArrayBuffer to support non-text request bodies.
|
|
58
|
+
// NOTE: we can't use Blobs becuse Safari doesn't support storing
|
|
59
|
+
// Blobs in IndexedDB in some cases:
|
|
60
|
+
// https://github.com/dfahlander/Dexie.js/issues/618#issuecomment-398348457
|
|
61
|
+
requestData.body = await request.clone().arrayBuffer();
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
request.headers.forEach((value, key) => {
|
|
65
|
+
requestData.headers[key] = value;
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// Add all other serializable request properties
|
|
69
|
+
for (const prop of serializableProperties) {
|
|
70
|
+
if (request[prop] !== undefined) {
|
|
71
|
+
requestData[prop] = request[prop];
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return new StorableRequest(requestData);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Accepts an object of request data that can be used to construct a
|
|
80
|
+
* `Request` but can also be stored in IndexedDB.
|
|
81
|
+
*
|
|
82
|
+
* @param requestData An object of request data that includes the `url` plus any relevant properties of
|
|
83
|
+
* [requestInit](https://fetch.spec.whatwg.org/#requestinit).
|
|
84
|
+
*/
|
|
85
|
+
constructor(requestData: RequestData) {
|
|
86
|
+
if (process.env.NODE_ENV !== "production") {
|
|
87
|
+
assert!.isType(requestData, "object", {
|
|
88
|
+
moduleName: "@serwist/background-sync",
|
|
89
|
+
className: "StorableRequest",
|
|
90
|
+
funcName: "constructor",
|
|
91
|
+
paramName: "requestData",
|
|
92
|
+
});
|
|
93
|
+
assert!.isType(requestData.url, "string", {
|
|
94
|
+
moduleName: "@serwist/background-sync",
|
|
95
|
+
className: "StorableRequest",
|
|
96
|
+
funcName: "constructor",
|
|
97
|
+
paramName: "requestData.url",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// If the request's mode is `navigate`, convert it to `same-origin` since
|
|
102
|
+
// navigation requests can't be constructed via script.
|
|
103
|
+
if (requestData.mode === "navigate") {
|
|
104
|
+
requestData.mode = "same-origin";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
this._requestData = requestData;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Returns a deep clone of the instances `_requestData` object.
|
|
112
|
+
*
|
|
113
|
+
* @returns
|
|
114
|
+
*/
|
|
115
|
+
toObject(): RequestData {
|
|
116
|
+
const requestData = Object.assign({}, this._requestData);
|
|
117
|
+
requestData.headers = Object.assign({}, this._requestData.headers);
|
|
118
|
+
if (requestData.body) {
|
|
119
|
+
requestData.body = requestData.body.slice(0);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return requestData;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Converts this instance to a Request.
|
|
127
|
+
*
|
|
128
|
+
* @returns
|
|
129
|
+
*/
|
|
130
|
+
toRequest(): Request {
|
|
131
|
+
return new Request(this._requestData.url, this._requestData);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Creates and returns a deep clone of the instance.
|
|
136
|
+
*
|
|
137
|
+
* @returns
|
|
138
|
+
*/
|
|
139
|
+
clone(): StorableRequest {
|
|
140
|
+
return new StorableRequest(this.toObject());
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
export { StorableRequest };
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright 2018 Google LLC
|
|
3
|
+
|
|
4
|
+
Use of this source code is governed by an MIT-style
|
|
5
|
+
license that can be found in the LICENSE file or at
|
|
6
|
+
https://opensource.org/licenses/MIT.
|
|
7
|
+
*/
|
|
8
|
+
import { BackgroundSyncPlugin } from "./BackgroundSyncPlugin.js";
|
|
9
|
+
import type { QueueEntry, QueueOptions } from "./Queue.js";
|
|
10
|
+
import { Queue } from "./Queue.js";
|
|
11
|
+
import { QueueStore } from "./QueueStore.js";
|
|
12
|
+
import { StorableRequest } from "./StorableRequest.js";
|
|
13
|
+
|
|
14
|
+
// See https://github.com/GoogleChrome/workbox/issues/2946
|
|
15
|
+
interface SyncManager {
|
|
16
|
+
getTags(): Promise<string[]>;
|
|
17
|
+
register(tag: string): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
declare global {
|
|
21
|
+
interface ServiceWorkerRegistration {
|
|
22
|
+
readonly sync: SyncManager;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface SyncEvent extends ExtendableEvent {
|
|
26
|
+
readonly lastChance: boolean;
|
|
27
|
+
readonly tag: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface ServiceWorkerGlobalScopeEventMap {
|
|
31
|
+
sync: SyncEvent;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export { BackgroundSyncPlugin, Queue, QueueStore, StorableRequest };
|
|
36
|
+
|
|
37
|
+
export type { QueueOptions, QueueEntry };
|