UNPKG

4.46 kBJavaScriptView Raw
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*/
8import { openDB } from 'idb';
9import '../_version.js';
10const DB_VERSION = 3;
11const DB_NAME = 'workbox-background-sync';
12const REQUEST_OBJECT_STORE_NAME = 'requests';
13const QUEUE_NAME_INDEX = 'queueName';
14/**
15 * A class to interact directly an IndexedDB created specifically to save and
16 * retrieve QueueStoreEntries. This class encapsulates all the schema details
17 * to store the representation of a Queue.
18 *
19 * @private
20 */
21export class QueueDb {
22 constructor() {
23 this._db = null;
24 }
25 /**
26 * Add QueueStoreEntry to underlying db.
27 *
28 * @param {UnidentifiedQueueStoreEntry} entry
29 */
30 async addEntry(entry) {
31 const db = await this.getDb();
32 const tx = db.transaction(REQUEST_OBJECT_STORE_NAME, 'readwrite', {
33 durability: 'relaxed',
34 });
35 await tx.store.add(entry);
36 await tx.done;
37 }
38 /**
39 * Returns the first entry id in the ObjectStore.
40 *
41 * @return {number | undefined}
42 */
43 async getFirstEntryId() {
44 const db = await this.getDb();
45 const cursor = await db
46 .transaction(REQUEST_OBJECT_STORE_NAME)
47 .store.openCursor();
48 return cursor === null || cursor === void 0 ? void 0 : cursor.value.id;
49 }
50 /**
51 * Get all the entries filtered by index
52 *
53 * @param queueName
54 * @return {Promise<QueueStoreEntry[]>}
55 */
56 async getAllEntriesByQueueName(queueName) {
57 const db = await this.getDb();
58 const results = await db.getAllFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
59 return results ? results : new Array();
60 }
61 /**
62 * Returns the number of entries filtered by index
63 *
64 * @param queueName
65 * @return {Promise<number>}
66 */
67 async getEntryCountByQueueName(queueName) {
68 const db = await this.getDb();
69 return db.countFromIndex(REQUEST_OBJECT_STORE_NAME, QUEUE_NAME_INDEX, IDBKeyRange.only(queueName));
70 }
71 /**
72 * Deletes a single entry by id.
73 *
74 * @param {number} id the id of the entry to be deleted
75 */
76 async deleteEntry(id) {
77 const db = await this.getDb();
78 await db.delete(REQUEST_OBJECT_STORE_NAME, id);
79 }
80 /**
81 *
82 * @param queueName
83 * @returns {Promise<QueueStoreEntry | undefined>}
84 */
85 async getFirstEntryByQueueName(queueName) {
86 return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'next');
87 }
88 /**
89 *
90 * @param queueName
91 * @returns {Promise<QueueStoreEntry | undefined>}
92 */
93 async getLastEntryByQueueName(queueName) {
94 return await this.getEndEntryFromIndex(IDBKeyRange.only(queueName), 'prev');
95 }
96 /**
97 * Returns either the first or the last entries, depending on direction.
98 * Filtered by index.
99 *
100 * @param {IDBCursorDirection} direction
101 * @param {IDBKeyRange} query
102 * @return {Promise<QueueStoreEntry | undefined>}
103 * @private
104 */
105 async getEndEntryFromIndex(query, direction) {
106 const db = await this.getDb();
107 const cursor = await db
108 .transaction(REQUEST_OBJECT_STORE_NAME)
109 .store.index(QUEUE_NAME_INDEX)
110 .openCursor(query, direction);
111 return cursor === null || cursor === void 0 ? void 0 : cursor.value;
112 }
113 /**
114 * Returns an open connection to the database.
115 *
116 * @private
117 */
118 async getDb() {
119 if (!this._db) {
120 this._db = await openDB(DB_NAME, DB_VERSION, {
121 upgrade: this._upgradeDb,
122 });
123 }
124 return this._db;
125 }
126 /**
127 * Upgrades QueueDB
128 *
129 * @param {IDBPDatabase<QueueDBSchema>} db
130 * @param {number} oldVersion
131 * @private
132 */
133 _upgradeDb(db, oldVersion) {
134 if (oldVersion > 0 && oldVersion < DB_VERSION) {
135 if (db.objectStoreNames.contains(REQUEST_OBJECT_STORE_NAME)) {
136 db.deleteObjectStore(REQUEST_OBJECT_STORE_NAME);
137 }
138 }
139 const objStore = db.createObjectStore(REQUEST_OBJECT_STORE_NAME, {
140 autoIncrement: true,
141 keyPath: 'id',
142 });
143 objStore.createIndex(QUEUE_NAME_INDEX, QUEUE_NAME_INDEX, { unique: false });
144 }
145}