A music player that connects to your cloud/distributed storage.
1//
2// IndexedDB
3// \ (•◡•) /
4//
5// The local database.
6// This is used instead of localStorage.
7
8
9import delay from "delay"
10import retryPromise from "p-retry"
11
12
13const WAITING_MSG = "Waiting for database"
14
15
16const indexedDB =
17 self.indexedDB ||
18 self.webkitIndexedDB ||
19 self.mozIndexedDB ||
20 self.msIndexedDB
21
22
23export const storeNames = {
24 main: "main",
25 tracks: "tracks"
26}
27
28
29let db, idx
30
31
32idx = indexedDB.open("diffuse", 1)
33idx.onupgradeneeded = event => {
34 event.target.result.createObjectStore(storeNames.main)
35 event.target.result.createObjectStore(storeNames.tracks)
36}
37
38idx.onsuccess = _ => {
39 db = idx.result
40}
41
42idx.onerror = event => {
43 console.error("IndexedDB error: " + event.target.error)
44}
45
46
47
48// Get
49// ---
50
51export const getFromIndex = args => retry(() => {
52 return new Promise((resolve, reject) => {
53 if (!db) throw new Error(WAITING_MSG)
54
55 const sto = args.store || storeNames.main
56 const key = args.key
57 const tra = db.transaction([sto], "readonly")
58 const req = tra.objectStore(sto).get(key)
59
60 req.onsuccess = _ => {
61 if (req.result) {
62 resolve(req.result)
63 } else {
64 resolve(null)
65 }
66 }
67
68 req.onerror = reject
69 })
70})
71
72
73export const keys = args => retry(() => {
74 return new Promise((resolve, reject) => {
75 if (!db) throw new Error(WAITING_MSG)
76
77 const sto = (args || {}).store || storeNames.main
78 const tra = db.transaction([sto], "readonly")
79 const req = tra.objectStore(sto).getAllKeys()
80
81 req.onsuccess = _ => {
82 if (req.result) {
83 resolve(req.result)
84 } else {
85 resolve(null)
86 }
87 }
88
89 req.onerror = reject
90 })
91})
92
93
94
95// Set
96// ---
97
98export const setInIndex = args => retry(() => {
99 return new Promise((resolve, reject) => {
100 if (!db) throw new Error(WAITING_MSG)
101
102 const sto = args.store || storeNames.main
103 const key = args.key
104 const dat = args.data
105
106 const tra = db.transaction([sto], "readwrite")
107 const req = tra.objectStore(sto).put(dat, key)
108
109 req.onsuccess = resolve
110 req.onerror = reject
111 })
112})
113
114
115
116// Delete
117// ------
118
119export const deleteFromIndex = args => retry(() => {
120 return new Promise((resolve, reject) => {
121 if (!db) throw new Error(WAITING_MSG)
122
123 const sto = args.store || storeNames.main
124 const key = args.key
125 const tra = db.transaction([sto], "readwrite")
126 const req = tra.objectStore(sto).delete(key)
127
128 req.onsuccess = resolve
129 req.onerror = reject
130 })
131})
132
133
134
135// ⚗️
136// --
137
138function retry(func) {
139 return retryPromise(func, { onFailedAttempt: _ => delay(250), retries: 20 })
140}