Skip to content

Commit f0d9542

Browse files
author
NellowTCS
committed
Tiny stuff
1 parent 9c81a2d commit f0d9542

File tree

9 files changed

+121
-156
lines changed

9 files changed

+121
-156
lines changed

Build/src/platform/integrations/discordService.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
/**
2-
* Discord Rich Presence Service
3-
* Handles sending track updates to the Discord backend API
4-
*/
1+
// WIP WARNING
52

63
export interface DiscordPresenceData {
74
userId: string;
Lines changed: 25 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,32 @@
1-
const DB_NAME = "HTMLPlayerDB";
2-
const DB_VERSION = 2;
3-
const STORE = "albumArt";
4-
5-
const openDatabase = (): Promise<IDBDatabase> => {
6-
return new Promise((resolve, reject) => {
7-
const request = indexedDB.open(DB_NAME, DB_VERSION);
8-
9-
request.onerror = () => reject(request.error);
10-
request.onsuccess = () => resolve(request.result);
11-
12-
request.onupgradeneeded = (event) => {
13-
const db = (event.target as IDBOpenDBRequest).result;
14-
if (!db.objectStoreNames.contains(STORE)) {
15-
db.createObjectStore(STORE, { keyPath: "songId" });
16-
}
17-
};
18-
});
19-
};
1+
import { getDb, STORES } from "./db";
202

213
const albumArtCache = new Map<string, string>();
224
const MAX_CACHE = 50;
235

6+
function evictCache() {
7+
if (albumArtCache.size >= MAX_CACHE) {
8+
const firstKey = albumArtCache.keys().next().value;
9+
if (firstKey) albumArtCache.delete(firstKey);
10+
}
11+
}
12+
2413
export const albumArtStorage = {
2514
async load(songId: string): Promise<string | null> {
2615
if (albumArtCache.has(songId)) {
2716
return albumArtCache.get(songId)!;
2817
}
2918

3019
try {
31-
const db = await openDatabase();
32-
const tx = db.transaction([STORE], "readonly");
33-
const store = tx.objectStore(STORE);
20+
const db = await getDb();
21+
const tx = db.transaction(STORES.ALBUM_ART, "readonly");
22+
const store = tx.objectStore(STORES.ALBUM_ART);
3423

35-
const result = await new Promise<
36-
{ songId: string; albumArt: string } | undefined
37-
>((resolve, reject) => {
24+
const result = await new Promise<{ songId: string; albumArt: string } | undefined>((resolve, reject) => {
3825
const req = store.get(songId);
3926
req.onsuccess = () => resolve(req.result);
4027
req.onerror = () => reject(req.error);
4128
});
4229

43-
db.close();
44-
4530
if (result?.albumArt) {
4631
evictCache();
4732
albumArtCache.set(songId, result.albumArt);
@@ -70,25 +55,20 @@ export const albumArtStorage = {
7055
if (toLoad.length === 0) return result;
7156

7257
try {
73-
const db = await openDatabase();
74-
const tx = db.transaction([STORE], "readonly");
75-
const store = tx.objectStore(STORE);
58+
const db = await getDb();
59+
const tx = db.transaction(STORES.ALBUM_ART, "readonly");
60+
const store = tx.objectStore(STORES.ALBUM_ART);
7661

7762
const loaded = await Promise.all(
78-
toLoad.map(
79-
(songId) =>
80-
new Promise<{ songId: string; albumArt: string } | null>(
81-
(resolve, reject) => {
82-
const req = store.get(songId);
83-
req.onsuccess = () => resolve(req.result || null);
84-
req.onerror = () => reject(req.error);
85-
},
86-
),
87-
),
63+
toLoad.map((songId) =>
64+
new Promise<{ songId: string; albumArt: string } | null>((resolve, reject) => {
65+
const req = store.get(songId);
66+
req.onsuccess = () => resolve(req.result || null);
67+
req.onerror = () => reject(req.error);
68+
})
69+
)
8870
);
8971

90-
db.close();
91-
9272
for (const art of loaded) {
9373
if (art?.albumArt) {
9474
evictCache();
@@ -106,17 +86,16 @@ export const albumArtStorage = {
10686

10787
async save(songId: string, albumArt: string): Promise<void> {
10888
try {
109-
const db = await openDatabase();
110-
const tx = db.transaction([STORE], "readwrite");
111-
const store = tx.objectStore(STORE);
89+
const db = await getDb();
90+
const tx = db.transaction(STORES.ALBUM_ART, "readwrite");
91+
const store = tx.objectStore(STORES.ALBUM_ART);
11292

11393
await new Promise<void>((resolve, reject) => {
11494
const req = store.put({ songId, albumArt });
11595
req.onsuccess = () => resolve();
11696
req.onerror = () => reject(req.error);
11797
});
11898

119-
db.close();
12099
evictCache();
121100
albumArtCache.set(songId, albumArt);
122101
} catch (error) {
@@ -135,16 +114,4 @@ export const albumArtStorage = {
135114
get(songId: string): string | undefined {
136115
return albumArtCache.get(songId);
137116
},
138-
139-
set(songId: string, albumArt: string): void {
140-
evictCache();
141-
albumArtCache.set(songId, albumArt);
142-
},
143117
};
144-
145-
function evictCache() {
146-
if (albumArtCache.size >= MAX_CACHE) {
147-
const firstKey = albumArtCache.keys().next().value;
148-
if (firstKey) albumArtCache.delete(firstKey);
149-
}
150-
}

Build/src/platform/storage/audio.ts

Lines changed: 11 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,4 @@
1-
const DB_NAME = "HTMLPlayerDB";
2-
const DB_VERSION = 2;
3-
const STORE = "audioData";
4-
5-
const openDatabase = (): Promise<IDBDatabase> => {
6-
return new Promise((resolve, reject) => {
7-
const request = indexedDB.open(DB_NAME, DB_VERSION);
8-
9-
request.onerror = () => reject(request.error);
10-
request.onsuccess = () => resolve(request.result);
11-
12-
request.onupgradeneeded = (event) => {
13-
const db = (event.target as IDBOpenDBRequest).result;
14-
if (!db.objectStoreNames.contains(STORE)) {
15-
const store = db.createObjectStore(STORE, { keyPath: "songId" });
16-
store.createIndex("lastAccessed", "lastAccessed", { unique: false });
17-
}
18-
};
19-
});
20-
};
1+
import { getDb, STORES } from "./db";
212

223
export interface AudioData {
234
fileData: ArrayBuffer;
@@ -27,9 +8,9 @@ export interface AudioData {
278
export const audioStorage = {
289
async load(songId: string): Promise<AudioData | null> {
2910
try {
30-
const db = await openDatabase();
31-
const tx = db.transaction([STORE], "readwrite");
32-
const store = tx.objectStore(STORE);
11+
const db = await getDb();
12+
const tx = db.transaction(STORES.AUDIO_DATA, "readwrite");
13+
const store = tx.objectStore(STORES.AUDIO_DATA);
3314

3415
const result = await new Promise<any>((resolve, reject) => {
3516
const req = store.get(songId);
@@ -41,10 +22,7 @@ export const audioStorage = {
4122
store.put({ ...result, lastAccessed: Date.now() });
4223
}
4324

44-
db.close();
45-
return result
46-
? { fileData: result.fileData, mimeType: result.mimeType }
47-
: null;
25+
return result ? { fileData: result.fileData, mimeType: result.mimeType } : null;
4826
} catch (error) {
4927
console.error(`Failed to load audio data for song ${songId}:`, error);
5028
return null;
@@ -53,9 +31,9 @@ export const audioStorage = {
5331

5432
async save(songId: string, audioData: AudioData): Promise<void> {
5533
try {
56-
const db = await openDatabase();
57-
const tx = db.transaction([STORE], "readwrite");
58-
const store = tx.objectStore(STORE);
34+
const db = await getDb();
35+
const tx = db.transaction(STORES.AUDIO_DATA, "readwrite");
36+
const store = tx.objectStore(STORES.AUDIO_DATA);
5937

6038
await new Promise<void>((resolve, reject) => {
6139
const req = store.put({
@@ -67,8 +45,6 @@ export const audioStorage = {
6745
req.onsuccess = () => resolve();
6846
req.onerror = () => reject(req.error);
6947
});
70-
71-
db.close();
7248
} catch (error) {
7349
console.error(`Failed to save audio data for song ${songId}:`, error);
7450
throw error;
@@ -77,17 +53,15 @@ export const audioStorage = {
7753

7854
async remove(songId: string): Promise<void> {
7955
try {
80-
const db = await openDatabase();
81-
const tx = db.transaction([STORE], "readwrite");
82-
const store = tx.objectStore(STORE);
56+
const db = await getDb();
57+
const tx = db.transaction(STORES.AUDIO_DATA, "readwrite");
58+
const store = tx.objectStore(STORES.AUDIO_DATA);
8359

8460
await new Promise<void>((resolve, reject) => {
8561
const req = store.delete(songId);
8662
req.onsuccess = () => resolve();
8763
req.onerror = () => reject(req.error);
8864
});
89-
90-
db.close();
9165
} catch (error) {
9266
console.error(`Failed to remove audio data for song ${songId}:`, error);
9367
throw error;

Build/src/platform/storage/db.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
const DB_NAME = "HTMLPlayerDB";
2+
const DB_VERSION = 2;
3+
4+
let dbInstance: IDBDatabase | null = null;
5+
let dbPromise: Promise<IDBDatabase> | null = null;
6+
7+
export const STORES = {
8+
LIBRARY: "library",
9+
SETTINGS: "settings",
10+
AUDIO_DATA: "audioData",
11+
ALBUM_ART: "albumArt",
12+
} as const;
13+
14+
function openDatabase(): Promise<IDBDatabase> {
15+
if (dbInstance) return Promise.resolve(dbInstance);
16+
if (dbPromise) return dbPromise;
17+
18+
dbPromise = new Promise((resolve, reject) => {
19+
const request = indexedDB.open(DB_NAME, DB_VERSION);
20+
21+
request.onerror = () => reject(request.error);
22+
request.onsuccess = () => {
23+
dbInstance = request.result;
24+
resolve(dbInstance);
25+
};
26+
27+
request.onupgradeneeded = (event) => {
28+
const db = (event.target as IDBOpenDBRequest).result;
29+
30+
if (!db.objectStoreNames.contains(STORES.LIBRARY)) {
31+
db.createObjectStore(STORES.LIBRARY, { keyPath: "id" });
32+
}
33+
if (!db.objectStoreNames.contains(STORES.SETTINGS)) {
34+
db.createObjectStore(STORES.SETTINGS, { keyPath: "id" });
35+
}
36+
if (!db.objectStoreNames.contains(STORES.AUDIO_DATA)) {
37+
const store = db.createObjectStore(STORES.AUDIO_DATA, { keyPath: "songId" });
38+
store.createIndex("lastAccessed", "lastAccessed", { unique: false });
39+
}
40+
if (!db.objectStoreNames.contains(STORES.ALBUM_ART)) {
41+
db.createObjectStore(STORES.ALBUM_ART, { keyPath: "songId" });
42+
}
43+
};
44+
});
45+
46+
return dbPromise;
47+
}
48+
49+
export function getDb(): Promise<IDBDatabase> {
50+
return openDatabase();
51+
}
52+
53+
export function closeDb(): void {
54+
if (dbInstance) {
55+
dbInstance.close();
56+
dbInstance = null;
57+
dbPromise = null;
58+
}
59+
}

0 commit comments

Comments
 (0)