Database.ts
1 import { initializeApp, FirebaseApp } from 'firebase/app' 2 import { getDatabase, Database as FirebaseDatabase, onValue, ref } from 'firebase/database' 3 import { getStorage, FirebaseStorage, ref as storageRef } from 'firebase/storage' 4 import { databaseCallback } from '../typings/station'; 5 import { stationType } from '../typings/firebase'; 6 7 export class Database { 8 private app: FirebaseApp; 9 private db: FirebaseDatabase; 10 private storage: FirebaseStorage; 11 private launchCallback: databaseCallback; 12 private _stations: Record<string, stationType<false>> = {}; 13 private readyCount = 0; 14 private _ready = false 15 16 constructor() { 17 this.start() 18 } 19 20 public get ready() { 21 return this._ready; 22 } 23 public get stations() { 24 return this._stations; 25 } 26 27 public onLaunch(callback: databaseCallback) { 28 this.launchCallback = callback; 29 }; 30 public audioRef(id: string) { 31 return storageRef(this.storage, `${id}.mp3`) 32 } 33 34 private pushStation(station: stationType<true>) { 35 const emojiRegex = /(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])/ 36 const emoji = station.title.match(emojiRegex)?.[0] ?? null; 37 38 this._stations[station.id] = { 39 ...station, 40 authors: JSON.parse(station.authors).filter((x: string) => x !== 'x'), 41 tracks: JSON.parse(station.tracks), 42 emoji, 43 title: station.title.replace(emojiRegex, '').trim() 44 } 45 } 46 private async createStations() { 47 onValue(ref(this.db, 'stations'), async(snap) => { 48 const values = snap.val() as Record<string, stationType<true>>; 49 50 Object.values(values).forEach(this.pushStation.bind(this)); 51 52 setTimeout(() => { 53 this.readyCount++; 54 this.checkReady(); 55 }, 1000) 56 }) 57 } 58 private checkReady() { 59 if (this.readyCount === 1) { 60 this._ready = true; 61 62 if (!!this.launchCallback) { 63 this.launchCallback(this); 64 } 65 } 66 } 67 68 private start() { 69 this.app = initializeApp({ 70 databaseURL: process.env.dbUrl, 71 storageBucket: process.env.bucketUrl 72 }) 73 74 this.db = getDatabase(this.app) 75 this.storage = getStorage(this.app) 76 77 this.createStations() 78 } 79 }