config.ts 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { ConfigManager, ConfigMigrationsDict } from "@sv443-network/userutils";
  2. import { featInfo } from "./features/index";
  3. import { FeatureConfig } from "./types";
  4. import { info, log } from "./utils";
  5. import { siteEvents } from "./events";
  6. /** If this number is incremented, the features object data will be migrated to the new format */
  7. export const formatVersion = 3;
  8. /** Config data format migration dictionary */
  9. export const migrations: ConfigMigrationsDict = {
  10. // 1 -> 2
  11. 2: (oldData: Record<string, unknown>) => {
  12. const queueBtnsEnabled = Boolean(oldData.queueButtons);
  13. delete oldData.queueButtons;
  14. return {
  15. ...oldData,
  16. deleteFromQueueButton: queueBtnsEnabled,
  17. lyricsQueueButton: queueBtnsEnabled,
  18. };
  19. },
  20. // 2 -> 3
  21. 3: (oldData: Record<string, unknown>) => ({
  22. ...oldData,
  23. removeShareTrackingParam: true,
  24. numKeysSkipToTime: true,
  25. fixSpacing: true,
  26. scrollToActiveSongBtn: true,
  27. logLevel: 1,
  28. }),
  29. };
  30. export const defaultConfig = (Object.keys(featInfo) as (keyof typeof featInfo)[])
  31. .reduce<Partial<FeatureConfig>>((acc, key) => {
  32. acc[key] = featInfo[key].default as unknown as undefined;
  33. return acc;
  34. }, {}) as FeatureConfig;
  35. const cfgMgr = new ConfigManager({
  36. id: "bytm-config",
  37. formatVersion,
  38. defaultConfig,
  39. migrations,
  40. });
  41. /** Initializes the ConfigManager instance and loads persistent data into memory */
  42. export async function initConfig() {
  43. const oldFmtVer = Number(await GM.getValue(`_uucfgver-${cfgMgr.id}`, NaN));
  44. const data = await cfgMgr.loadData();
  45. log(`Initialized ConfigManager (format version = ${cfgMgr.formatVersion})`);
  46. if(isNaN(oldFmtVer))
  47. info("Config data initialized with default values");
  48. else if(oldFmtVer !== cfgMgr.formatVersion)
  49. info(`Config data migrated from version ${oldFmtVer} to ${cfgMgr.formatVersion}`);
  50. return data;
  51. }
  52. /** Returns the current feature config from the in-memory cache */
  53. export function getFeatures() {
  54. return cfgMgr.getData();
  55. }
  56. /** Saves the feature config synchronously to the in-memory cache and asynchronously to the persistent storage */
  57. export async function saveFeatures(featureConf: FeatureConfig) {
  58. await cfgMgr.setData(featureConf);
  59. siteEvents.emit("configChanged", cfgMgr.getData());
  60. info("Saved new feature config:", featureConf);
  61. }
  62. /** Saves the default feature config synchronously to the in-memory cache and asynchronously to persistent storage */
  63. export async function setDefaultFeatures() {
  64. await cfgMgr.saveDefaultData();
  65. siteEvents.emit("configChanged", cfgMgr.getData());
  66. info("Reset feature config to its default values");
  67. }
  68. /** Clears the feature config from the persistent storage - since the cache will be out of whack, this should only be run before a site re-/unload */
  69. export async function clearConfig() {
  70. await cfgMgr.deleteConfig();
  71. info("Deleted config from persistent storage");
  72. }