feat(lib/discord): add flux APIs

This commit is contained in:
PalmDevs 2025-08-05 20:36:08 +07:00
parent ed966a7772
commit ce188950cd
No known key found for this signature in database
GPG key ID: 6FAE8F8677ACA8BA
5 changed files with 104 additions and 1 deletions

View file

@ -21,6 +21,9 @@
"./design": {
"default": "./src/design.ts"
},
"./flux": {
"default": "./src/flux.ts"
},
"./native": {
"default": "./src/native.ts"
},

92
lib/discord/src/flux.ts Normal file
View file

@ -0,0 +1,92 @@
import { Dispatcher } from './common/flux'
import type { DiscordModules } from './types'
const fPatchesAll: Set<FluxEventDispatchPatch> = new Set()
const fPatches: Map<string, Set<FluxEventDispatchPatch>> = new Map()
export type FluxEventDispatchPatch = (
payload: DiscordModules.Flux.DispatcherPayload,
) => DiscordModules.Flux.DispatcherPayload | undefined | void
;(Dispatcher._interceptors ??= []).unshift(payload => {
let res: typeof payload | undefined | void = payload
for (const patch of fPatchesAll)
try {
res = patch(res!)
if (!res) break
} catch {}
if (res) {
const specifics = fPatches.get(payload.type)
if (specifics?.size)
for (const patch of specifics)
try {
res = patch(res!)
if (!res) break
} catch {}
}
return !res
})
/**
* Registers a patch for all Flux events.
*
* @see {@link onFluxEventDispatched} for more details.
*
* @param patch The patch function to apply when any Flux event is dispatched.
* @returns A function that can be used to remove the patch.
*/
export function onAnyFluxEventDispatched(patch: FluxEventDispatchPatch) {
fPatchesAll.add(patch)
return () => {
fPatchesAll.delete(patch)
}
}
/**
* Registers a patch for a specific Flux event type.
* @param type The type of the Flux event to patch.
* @param patch The patch function to apply when the event is dispatched.
* @returns A function that can be used to remove the patch.
*
* @example Blocking the disptach
* ```ts
* // Returning falsy values will prevent the event from being dispatched.
* onFluxEventDispatched('TYPING_START', () => {})
* ```
*
* @example Modifying the payload
* ```ts
* onFluxEventDispatched('TYPING_START', payload => {
* // Send the typing event to this channel instead.
* payload.channelId = '123456789012345678'
* // Make sure to return the modified payload!
* return payload
* })
* ```
*
* @example Reading and passing through the payload
* ```ts
* onFluxEventDispatched('TYPING_START', payload => {
* console.log('Typing started:', payload)
* // Do nothing, just return the payload.
* return payload
* })
* ```
*/
export function onFluxEventDispatched(
type: DiscordModules.Flux.DispatcherPayload['type'],
patch: FluxEventDispatchPatch,
) {
let set = fPatches.get(type)
if (!set) fPatches.set(type, (set = new Set<FluxEventDispatchPatch>()))
set.add(patch)
return () => {
set.delete(patch)
}
}

View file

@ -29,7 +29,10 @@ export * from './revenge'
export namespace DiscordModules {
export namespace Flux {
export type DispatcherPayload = any
export interface DispatcherPayload {
type: string
[key: PropertyKey]: any
}
export type DispatcherDependency = any
export interface StoreChangeCallbacks {

View file

@ -4,6 +4,7 @@ export interface PluginApiDiscord {
actions: PluginApiDiscord.Actions
common: PluginApiDiscord.Common
design: PluginApiDiscord.Design
flux: PluginApiDiscord.Flux
modules: PluginApiDiscord.Modules
native: PluginApiDiscord.Native
}
@ -12,6 +13,7 @@ export namespace PluginApiDiscord {
export type Actions = typeof import('@revenge-mod/discord/actions')
export type Common = typeof import('@revenge-mod/discord/common')
export type Design = typeof import('@revenge-mod/discord/design')
export type Flux = typeof import('@revenge-mod/discord/flux')
export type Native = typeof import('@revenge-mod/discord/native')
export interface Modules {

View file

@ -36,6 +36,9 @@ registerPlugin(
design: () => {
return require('@revenge-mod/discord/design')
},
flux: () => {
return require('@revenge-mod/discord/flux')
},
native: () => {
return require('@revenge-mod/discord/native')
},