| /** |
| * @license |
| * Copyright 2022 Google LLC |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| export interface GerritServiceWorkerState { |
| latestUpdateTimestampMs: number; |
| allowBrowserNotificationsPreference: boolean; |
| } |
| |
| const SERVICE_WORKER_DB = 'service-worker-db-1'; |
| // Object store - kind of table that holds objects |
| // https://developer.mozilla.org/en-US/docs/Web/API/IDBObjectStore |
| const SERVICE_WORKER_STORE = 'states'; |
| // Service Worker State needs just 1 entry in object store which is rewritten |
| // every time state is saved. This entry has SERVICE_WORKER_STATE_ID. |
| const SERVICE_WORKER_STATE_ID = 1; |
| |
| function getServiceWorkerDB(): Promise<IDBDatabase> { |
| return new Promise((resolve, reject) => { |
| const request = indexedDB.open(SERVICE_WORKER_DB); |
| request.onsuccess = () => resolve(request.result); |
| request.onerror = reject; |
| request.onblocked = reject; |
| // Event is fired when an attempt was made to open a database with a version |
| // higher than its current version. |
| // https://developer.mozilla.org/en-US/docs/Web/API/IDBOpenDBRequest/upgradeneeded_event |
| // It's mainly used to create object stores. |
| // https://web.dev/indexeddb/#creating-object-stores |
| request.onupgradeneeded = () => { |
| const db = request.result; |
| if (db.objectStoreNames.contains(SERVICE_WORKER_STORE)) return; |
| const states = db.createObjectStore(SERVICE_WORKER_STORE, { |
| keyPath: 'id', |
| }); |
| states.createIndex('states_id_unique', 'id', {unique: true}); |
| }; |
| }); |
| } |
| |
| export async function putServiceWorkerState(state: GerritServiceWorkerState) { |
| const db = await getServiceWorkerDB(); |
| const tx = db.transaction(SERVICE_WORKER_STORE, 'readwrite'); |
| const store = tx.objectStore(SERVICE_WORKER_STORE); |
| store.put({...state, id: SERVICE_WORKER_STATE_ID}); |
| |
| return new Promise<void>(resolve => { |
| tx.oncomplete = () => resolve(); |
| }); |
| } |
| |
| export async function getServiceWorkerState(): Promise<GerritServiceWorkerState> { |
| const db = await getServiceWorkerDB(); |
| const tx = db.transaction(SERVICE_WORKER_STORE, 'readonly'); |
| const store = tx.objectStore(SERVICE_WORKER_STORE); |
| |
| return new Promise((resolve, reject) => { |
| const request = store.get(SERVICE_WORKER_STATE_ID); |
| request.onsuccess = () => resolve(request.result); |
| request.onerror = reject; |
| }); |
| } |