From dcfe40c1d7bb133bfd4bac0cdc1fb65e248405e5 Mon Sep 17 00:00:00 2001 From: PalmDevs Date: Mon, 11 Aug 2025 16:39:23 +0700 Subject: [PATCH] feat(lib/storage): add `Storage#subscribe` --- lib/storage/src/_internal.ts | 6 ------ lib/storage/src/index.ts | 16 ++++++++++++---- .../preinit/api.storage/define-storage-use.ts | 10 ++-------- 3 files changed, 14 insertions(+), 18 deletions(-) delete mode 100644 lib/storage/src/_internal.ts diff --git a/lib/storage/src/_internal.ts b/lib/storage/src/_internal.ts deleted file mode 100644 index 53a3577..0000000 --- a/lib/storage/src/_internal.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type { Storage, StorageSubscription } from '.' - -export const instanceToSubscriptions = new WeakMap< - Storage, - Set> ->() diff --git a/lib/storage/src/index.ts b/lib/storage/src/index.ts index e3bc711..3986c45 100644 --- a/lib/storage/src/index.ts +++ b/lib/storage/src/index.ts @@ -3,7 +3,6 @@ import { FileModule } from '@revenge-mod/discord/native' import { getErrorStack } from '@revenge-mod/utils/error' import { mergeDeep } from '@revenge-mod/utils/object' -import { instanceToSubscriptions } from './_internal' import type { AnyObject, DeepPartial } from '@revenge-mod/utils/types' export type StorageSubscription = ( @@ -22,7 +21,6 @@ export function Storage( const fullPath = `${dirPath}/${path}` const subscriptions = new Set>() - instanceToSubscriptions.set(this, subscriptions) this.loaded = false this.cache = options?.default @@ -30,6 +28,11 @@ export function Storage( this.exists = () => FileModule.fileExists(fullPath) this.delete = () => FileModule.removeFile(directory, path) + this.subscribe = callback => { + subscriptions.add(callback) + return () => subscriptions.delete(callback) + } + this.get = async function () { if (!(await this.exists())) { this.cache = options?.default ?? {} @@ -73,7 +76,7 @@ export function Storage( } // React is only initialized right before the init stage, so this is a dummy method -// See init.ts for the actual implementation +// See define-storage-use.ts in api.storage plugin for the actual implementation Storage.prototype.use = () => { throw new Error('Storage#use can only be called after the init stage!') } @@ -153,8 +156,13 @@ export interface Storage { * // ... * } */ - use(filter?: UseStorageFilter): T | undefined + /** + * Subscribe to storage updates. The callback will be called with what was called in `Storage#set`. + * @param callback The callback to call when the storage is updated. + * @returns A function to unsubscribe. + */ + subscribe(callback: StorageSubscription): () => void /** * Get the storage. */ diff --git a/src/plugins/preinit/api.storage/define-storage-use.ts b/src/plugins/preinit/api.storage/define-storage-use.ts index b78dfc8..60b5eaf 100644 --- a/src/plugins/preinit/api.storage/define-storage-use.ts +++ b/src/plugins/preinit/api.storage/define-storage-use.ts @@ -1,7 +1,6 @@ import { Storage } from '@revenge-mod/storage' import { useReRender } from '@revenge-mod/utils/react' import { useEffect } from 'react' -import { instanceToSubscriptions } from '../../../../lib/storage/src/_internal' import type { StorageSubscription } from '@revenge-mod/storage' // Actual implementation of Storage#use @@ -10,7 +9,6 @@ SP.use = function (filter) { if (!this.cache) this.get() const reRender = useReRender() - const subscriptions = instanceToSubscriptions.get(this)! useEffect(() => { const sub: StorageSubscription = filter @@ -19,12 +17,8 @@ SP.use = function (filter) { } : reRender - subscriptions.add(sub) - - return () => { - subscriptions.delete(sub) - } - }, [filter, reRender, subscriptions.add, subscriptions.delete]) + return this.subscribe(sub) + }, [filter, reRender]) return this.cache }