/ src / structures / Database.ts
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  }