This commit is contained in:
ryan-0324 2024-05-13 07:52:22 -04:00 committed by GitHub
parent a2afaa491a
commit 4ef9a22f79
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 1177 additions and 211 deletions

View file

@ -52,6 +52,7 @@
"@typescript-eslint/eslint-plugin": "^5.59.1", "@typescript-eslint/eslint-plugin": "^5.59.1",
"@typescript-eslint/parser": "^5.59.1", "@typescript-eslint/parser": "^5.59.1",
"diff": "^5.1.0", "diff": "^5.1.0",
"discord-api-types": "^0.37.83",
"discord-types": "^1.3.26", "discord-types": "^1.3.26",
"esbuild": "^0.15.18", "esbuild": "^0.15.18",
"eslint": "^8.46.0", "eslint": "^8.46.0",

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

View file

@ -18,7 +18,7 @@
export * from "./classes"; export * from "./classes";
export * from "./components"; export * from "./components";
export * from "./fluxEvents"; export * from "./fluxActions";
export * from "./i18nMessages"; export * from "./i18nMessages";
export * from "./menu"; export * from "./menu";
export * from "./settingsStores"; export * from "./settingsStores";

View file

@ -16,10 +16,11 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import { DraftType } from "@webpack/common"; import type { DraftType } from "@webpack/common";
import { Channel, Guild, Role } from "discord-types/general"; import type { APIUser, ApplicationFlags, OAuth2Scopes, UserFlags, UserPremiumType } from "discord-api-types/v9";
import { Channel, Guild, Role } from "discord-types/general"; // TODO
import type { FluxActionHandlers, FluxActionType, FluxDispatcher, FluxPayload } from "./utils"; import type { FluxAction, FluxActionType, FluxActionHandlers, FluxDispatchBand, FluxDispatcher } from "./utils";
type Nullish = null | undefined; type Nullish = null | undefined;
@ -36,11 +37,10 @@ class FluxChangeListeners {
remove: (listener: FluxChangeListener) => void; remove: (listener: FluxChangeListener) => void;
} }
export class FluxStore< export class FluxStore<
Dispatcher extends FluxDispatcher<infer P> = FluxDispatcher, Dispatcher extends FluxDispatcher<infer A> = FluxDispatcher,
Payload = P<infer A>, Action = A<infer T>,
ActionType = A ActionType = T
> { > {
constructor( constructor(
dispatcher: Dispatcher, dispatcher: Dispatcher,
@ -59,9 +59,9 @@ export class FluxStore<
getName(): string; getName(): string;
initialize(): void; initialize(): void;
initializeIfNeeded(): void; initializeIfNeeded(): void;
mustEmitChanges(mustEmitChanges?: ((payload: Payload) => boolean) | Nullish /* = () => true */): void; mustEmitChanges(mustEmitChanges?: ((action: Action) => boolean) | Nullish /* = () => true */): void;
registerActionHandlers(actionHandlers: FluxActionHandlers<ActionType>, band?: number | Nullish): void; registerActionHandlers(actionHandlers: FluxActionHandlers<ActionType>, band?: FluxDispatchBand | Nullish): void;
syncWith(stores: FluxStore<Dispatcher>[], func: () => boolean | void, delay?: number | Nullish); syncWith(stores: FluxStore<Dispatcher>[], func: () => boolean | void, timeout?: number | Nullish): void;
waitFor(...stores: FluxStore<Dispatcher>[]): void; waitFor(...stores: FluxStore<Dispatcher>[]): void;
__getLocalVars: undefined; __getLocalVars: undefined;
@ -69,7 +69,7 @@ export class FluxStore<
_dispatcher: Dispatcher; _dispatcher: Dispatcher;
_dispatchToken: string; _dispatchToken: string;
_isInitialized: boolean; _isInitialized: boolean;
_mustEmitChanges: ((payload: Payload) => boolean) | Nullish; _mustEmitChanges: ((action: Action) => boolean) | Nullish;
_reactChangeCallbacks: FluxChangeListeners; _reactChangeCallbacks: FluxChangeListeners;
_syncWiths: { _syncWiths: {
func: () => boolean | void; func: () => boolean | void;
@ -82,6 +82,30 @@ export class FluxStore<
removeReactChangeListener: FluxChangeListeners["remove"]; removeReactChangeListener: FluxChangeListeners["remove"];
} }
type FluxSnapshotStoreActionType = Exclude<FluxActionType, "CLEAR_CACHES" | "WRITE_CACHES">;
interface FluxSnapshot<Data = any> {
data: Data;
version: number;
}
export class FluxSnapshotStore<
Constructor extends typeof FluxSnapshotStore,
SnapshotData = any,
Action extends FluxAction<FluxSnapshotStoreActionType> = FluxAction<FluxSnapshotStoreActionType>
> extends FluxStore<FluxDispatcher<Action>> {
constructor(actionHandlers: FluxActionHandlers<Action>);
static allStores: FluxSnapshotStore[];
static clearAll(): void;
clear(): void;
getClass(): Constructor;
get persistKey(): string;
readSnapshot(version: number): SnapshotData | null;
save(): void;
}
export interface Flux { export interface Flux {
Store: typeof FluxStore; Store: typeof FluxStore;
} }
@ -89,10 +113,26 @@ export interface Flux {
export type useStateFromStores = <T>( export type useStateFromStores = <T>(
stores: FluxStore[], stores: FluxStore[],
getStateFromStores: () => T, getStateFromStores: () => T,
dependencies?: any[] | null | undefined, dependencies?: any[] | Nullish,
areStatesEqual?: ((prevState: T, currState: T) => boolean) | undefined areStatesEqual?: ((prevState: T, currState: T) => boolean) | undefined
) => T; ) => T;
// Original name: Record, renamed to avoid conflict with the Record util type
export class ImmutableRecord<OwnProperties extends object = Record<PropertyKey, any>> {
merge(collection: Partial<OwnProperties>): this;
set<K extends keyof OwnProperties>(key: K, value: OwnProperties[K]): this;
toJS(): OwnProperties;
update<K extends keyof OwnProperties>(
key: K,
updater: (value: OwnProperties[K]) => OwnProperties[K]
): this;
update<K extends keyof OwnProperties>(
key: K,
notSetValue: OwnProperties[K],
updater: (value: OwnProperties[K]) => OwnProperties[K]
): this;
}
export interface DraftObject { export interface DraftObject {
channelId: string; channelId: string;
timestamp: number; timestamp: number;
@ -107,7 +147,6 @@ interface DraftState {
} | undefined; } | undefined;
} }
export class DraftStore extends FluxStore { export class DraftStore extends FluxStore {
getDraft(channelId: string, type: DraftType): string; getDraft(channelId: string, type: DraftType): string;
getRecentlyEditedDrafts(type: DraftType): DraftObject[]; getRecentlyEditedDrafts(type: DraftType): DraftObject[];
@ -226,20 +265,117 @@ export class GuildStore extends FluxStore {
getAllGuildRoles(): Record<string, Record<string, Role>>; getAllGuildRoles(): Record<string, Record<string, Role>>;
} }
export class User { enum ApplicationIntegrationType {
constructor(user: object); // TEMP GUILD_INSTALL,
USER_INSTALL
}
addGuildAvatarHash(guildId: string, avatarHash: string): User; interface UserProfileFetchFailed {
get avatarDecoration(): { accentColor: null;
asset: string; application: null;
skuId: string; applicationRoleConnections: [];
banner: null;
bio: "";
connectedAccounts: [];
lastFetched: number;
legacyUsername: null;
premiumGuildSince: null;
premiumSince: null;
profileFetchFailed: true;
pronouns: "";
userId: string;
}
interface UserProfileFetchSucceeded {
application: {
customInstallUrl: string | Nullish;
flags: ApplicationFlags;
id: string;
installParams: {
scopes: OAuth2Scopes[] | Nullish;
permissions: string | Nullish;
} | Nullish;
integrationTypesConfig: Partial<Record<ApplicationIntegrationType, any /* | Nullish */>> | Nullish; // TEMP
popularApplicationCommandIds: string[] | undefined;
primarySkuId: string | Nullish;
storefront_available: boolean;
} | null; } | null;
set avatarDecoration(avatarDecoration: { accentColor: number | Nullish;
applicationRoleConnections: any[]; // TEMP
badges: {
description: string;
icon: string;
id: string;
link?: string;
}[];
banner: string | Nullish;
bio: string;
connectedAccounts: {
id: string;
metadata?: Record<string, any>;
name: string;
type: string;
verified: boolean;
}[];
lastFetched: number;
legacyUsername: string | Nullish;
popoutAnimationParticleType: Nullish; // TEMP
premiumGuildSince: Date | null;
premiumSince: Date | null;
premiumType: UserPremiumType | Nullish;
profileEffectId: string | undefined;
profileFetchFailed: false;
pronouns: string;
themeColors: [primaryColor: number, accentColor: number] | Nullish;
userId: string;
}
export type UserProfile<FetchFailed extends boolean = boolean> = FetchFailed extends true
? UserProfileFetchFailed
: UserProfileFetchSucceeded;
interface UserProfileStoreSnapshotData {
userId: string;
profile: UserProfile | undefined;
}
export class UserProfileStore extends FluxSnapshotStore<typeof UserProfileStore, UserProfileStoreSnapshotData> {
static displayName: "UserProfileStore";
static LATEST_SNAPSHOT_VERSION: number;
getUserProfile<FetchFailed extends boolean = boolean>(userId: string): UserProfile<FetchFailed> | undefined;
getGuildMemberProfile<T extends string | Nullish>(userId: string, guildId: T): T extends Nullish ? null : any | undefined; // TEMP
getIsAccessibilityTooltipViewed(): boolean;
getMutualFriends(userId: string): any; // TEMP
getMutualFriendsCount(userId: string): number;
getMutualGuilds(userId: string): any; // TEMP
isFetchingFriends(userId: string): boolean;
isFetchingProfile(userId: string): boolean;
get isSubmitting(): boolean;
takeSnapshot(): FluxSnapshot<UserProfileStoreSnapshotData>;
loadCache: () => void;
}
interface AvatarDecorationData {
asset: string; asset: string;
skuId: string; skuId: string;
}
type UserRecordOwnProperties = Pick<UserRecord, "avatar" | "avatarDecorationData" | "bot" | "clan" | "desktop" | "discriminator" | "email" | "flags" | "globalName" | "guildMemberAvatars" | "hasAnyStaffLevel" | "hasBouncedEmail" | "hasFlag" | "id" | "isStaff" | "isStaffPersonal" | "mfaEnabled" | "mobile" | "nsfwAllowed" | "personalConnectionId" | "phone" | "premiumType" | "premiumUsageFlags" | "publicFlags" | "purchasedFlags" | "system" | "username" | "verified">;
export class UserRecord extends ImmutableRecord<UserRecordOwnProperties> {
constructor(userFromServer: APIUser);
addGuildAvatarHash(guildId: string, avatarHash: string): this;
get avatarDecoration(): AvatarDecorationData | null;
set avatarDecoration(avatarDecorationData: {
asset: string;
skuId?: string;
sku_id?: string;
} | null): void; } | null): void;
get createdAt(): Date; get createdAt(): Date;
getAvatarSource(guildId?: string | Nullish, canAnimate?: boolean | undefined): { uri: string; }; getAvatarSource(guildId?: string | Nullish, canAnimate?: boolean | undefined, avatarSize?: number | undefined): { uri: string; };
getAvatarURL(guildId?: string | Nullish, avatarSize?: number | undefined, canAnimate?: boolean | undefined): string; getAvatarURL(guildId?: string | Nullish, avatarSize?: number | undefined, canAnimate?: boolean | undefined): string;
hasAvatarForGuild(guildId?: string | Nullish): boolean; hasAvatarForGuild(guildId?: string | Nullish): boolean;
hasDisabledPremium(): boolean; hasDisabledPremium(): boolean;
@ -258,23 +394,25 @@ export class User {
isPomelo(): boolean; isPomelo(): boolean;
isSystemUser(): boolean; isSystemUser(): boolean;
isVerifiedBot(): boolean; isVerifiedBot(): boolean;
removeGuildAvatarHash(guildId: string): User; removeGuildAvatarHash(guildId: string): UserRecord;
get tag(): string; get tag(): string;
toString(): string;
avatar: string; avatar: string | null;
avatarDecorationData: { avatarDecorationData: AvatarDecorationData | null;
asset: string; banner: string | Nullish;
skuId: string;
} | null;
bot: boolean; bot: boolean;
clan: null; // TEMP clan: {
badge: string | Nullish;
identityEnabled: boolean | undefined;
identityGuildId: string | Nullish;
tag: string | Nullish;
} | null;
desktop: boolean; desktop: boolean;
discriminator: string; discriminator: string;
email: string | null; email: string | null;
flags: number; flags: UserFlags;
globalName: string | null; globalName: string | Nullish;
guildMemberAvatars: Record<string, string>; guildMemberAvatars: Record</* guildId: */string, /* avatarHash: */string>;
hasAnyStaffLevel: () => boolean; hasAnyStaffLevel: () => boolean;
hasBouncedEmail: boolean; hasBouncedEmail: boolean;
hasFlag: (flag: number) => boolean; hasFlag: (flag: number) => boolean;
@ -283,90 +421,37 @@ export class User {
isStaffPersonal: () => boolean; isStaffPersonal: () => boolean;
mfaEnabled: boolean; mfaEnabled: boolean;
mobile: boolean; mobile: boolean;
nsfwAllowed: boolean | null; nsfwAllowed: boolean;
personalConnectionId: string | null; personalConnectionId: string | null;
phone: string | null; phone: string | null;
premiumType: number | null | undefined; premiumType: UserPremiumType | Nullish; // discord seems to have recently made it so that premiumType is nullish for every UserRecord
premiumUsageFlags: number; premiumUsageFlags: number;
publicFlags: number; publicFlags: UserFlags;
purchasedFlags: number; purchasedFlags: number;
system: boolean; system: boolean;
username: string; username: string;
verified: boolean; verified: boolean;
} }
export class UserStore extends FluxStore { interface UserStoreSnapshotData { users: [UserRecord] | []; };
export class UserStore extends FluxSnapshotStore<typeof UserStore, UserStoreSnapshotData> {
static displayName: "UserStore"; static displayName: "UserStore";
static LATEST_SNAPSHOT_VERSION: number; static LATEST_SNAPSHOT_VERSION: number;
filter(predicate: (user: User) => any): User[]; filter(predicate: (user: UserRecord) => any, sort?: boolean | undefined): UserRecord[];
findByTag(username: string, discriminator?: string | Nullish): User | undefined; findByTag(username: string, discriminator?: string | Nullish): UserRecord | undefined;
forEach(callback: (user: User) => void): void; forEach(callback: (user: UserRecord) => void): void;
getCurrentUser(): User /* | undefined */; getCurrentUser(): UserRecord | Nullish; // returns undefined if called before the first USER_UPDATE action for the current user. discord seems to always check != null too
getUser(userId: string): User | undefined; getUser(userId: string): UserRecord | Nullish;
getUsers(): Record<string, User>; getUsers(): Record<string, UserRecord>;
getUserStoreVersion(): number; getUserStoreVersion(): number;
handleLoadCache(arg: object): void; // TEMP handleLoadCache(cache: {
takeSnapshot(): { initialGuildChannels: any[]; // TEMP
data: { users: [User] | []; }; privateChannels: any[]; // TEMP
version: number; users: any[] | Nullish; // TEMP
}; }): void;
} takeSnapshot(): FluxSnapshot<UserStoreSnapshotData>;
export interface UserProfile {
application: null; // TEMP
accentColor: number | null;
applicationRoleConnections: []; // TEMP
badges: {
description: string;
icon: string;
id: string;
link?: string;
}[];
banner: string | null | undefined;
bio: string;
connectedAccounts: {
id: string;
metadata?: Record<string, any>;
name: string;
type: string;
verified: boolean;
}[];
lastFetched: number;
legacyUsername: string | null;
popoutAnimationParticleType?: null | undefined; // TEMP
premiumGuildSince: Date | null;
premiumSince: Date | null;
premiumType: number | null | undefined;
profileEffectId: string | undefined;
profileFetchFailed: boolean;
pronouns: string;
themeColors?: [primaryColor: number, accentColor: number] | undefined;
userId: string;
}
export class UserProfileStore extends FluxStore {
static displayName: "UserProfileStore";
static LATEST_SNAPSHOT_VERSION: number;
getUserProfile(userId: string): UserProfile | undefined;
getGuildMemberProfile<T extends string | Nullish>(userId: string, guildId: T): T extends Nullish ? null : object | undefined; // TEMP
getIsAccessibilityTooltipViewed(): boolean;
getMutualFriends(userId: string): object; // TEMP
getMutualFriendsCount(userId: string): number;
getMutualGuilds(userId: string): object; // TEMP
isFetchingFriends(userId: string): boolean;
isFetchingProfile(userId: string): boolean;
get isSubmitting(): boolean;
takeSnapshot(): {
data: {
userId: string;
profile: UserProfile | undefined;
};
version: number;
};
loadCache: () => void;
} }
export class WindowStore extends FluxStore { export class WindowStore extends FluxStore {

View file

@ -17,24 +17,16 @@
*/ */
import type { EventEmitter } from "events"; // Discord uses a polyfill for node's EventEmitter import type { EventEmitter } from "events"; // Discord uses a polyfill for node's EventEmitter
import type { Guild, GuildMember } from "discord-types/general"; import { Guild, GuildMember } from "discord-types/general"; // TODO
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import type { FluxActionType } from "./fluxActionType"; import type { FluxAction, FluxActionType } from "./fluxActions";
import type { i18nMessages } from "./i18nMessages"; import type { i18nMessages } from "./i18nMessages";
export { FluxActionType }; export { FluxAction, FluxActionType };
type Nullish = null | undefined; type Nullish = null | undefined;
export interface FluxPayload<ActionType extends FluxActionType = FluxActionType> extends Record<PropertyKey, any> {
type: ActionType;
}
export type FluxActionHandlers<T extends FluxActionType = FluxActionType> = {
[K in T]?: (payload: FluxPayload<K>) => void;
};
class DepGraph<Data = any> { class DepGraph<Data = any> {
constructor(options?: { circular?: boolean | undefined; } | undefined); constructor(options?: { circular?: boolean | undefined; } | undefined);
@ -57,41 +49,54 @@ class DepGraph<Data = any> {
incomingEdges: Record<string, string[]>; incomingEdges: Record<string, string[]>;
} }
export type FluxActionHandler<Action extends FluxAction = FluxAction> = (action: Action) => void;
export type FluxActionHandlers<
Action extends FluxAction<infer T> = FluxAction,
ActionType = T
> = { [Type in ActionType]?: FluxActionHandler<Action<Type>>; };
interface FluxActionHandlersGraphNode< interface FluxActionHandlersGraphNode<
Payload extends FluxPayload = FluxPayload Payload extends FluxAction = FluxAction
> { > {
name: string; name: string;
band: number; band: number;
actionHandler: (payload: Payload) => void; actionHandler: FluxActionHandler<Payload>;
storeDidChange: (payload: Payload) => void; storeDidChange: FluxActionHandler<Payload>;
} }
type FluxOrderedActionHandlers<Payload extends FluxPayload = FluxPaylod> = Omit<FluxActionHandlersGraphNode<Payload>, "band">[]; type FluxOrderedActionHandlers<Payload extends FluxAction = FluxAction> = Omit<FluxActionHandlersGraphNode<Payload>, "band">[];
export enum FluxDispatchBand {
Early,
Database,
Default
}
class FluxActionHandlersGraph< class FluxActionHandlersGraph<
Payload extends FluxPayload<infer A> = FluxPayload, Action extends FluxAction<infer T> = FluxAction,
ActionType = A ActionType = T
> { > {
_addToBand(token: string, band: number): void; _addToBand(token: string, band: FluxDispatchBand): void;
_bandToken(band: number): string; _bandToken(band: DispatcherBand): string;
_computeOrderedActionHandlers(actionType: ActionType): FluxOrderedActionHandlers<Payload>; _computeOrderedActionHandlers(actionType: ActionType): FluxOrderedActionHandlers<Action>;
_computeOrderedCallbackTokens(): string[]; _computeOrderedCallbackTokens(): string[];
_invalidateCaches(): void; _invalidateCaches(): void;
_validateDependencies(fromToken: string, toToken: string): void; _validateDependencies(fromToken: string, toToken: string): void;
addDependencies(fromToken: string, toTokens: string[]): void; addDependencies(fromToken: string, toTokens: string[]): void;
createToken(): string; createToken(): string;
getOrderedActionHandlers(payload: Payload): FluxOrderedActionHandlers<Payload>; getOrderedActionHandlers(action: Action): FluxOrderedActionHandlers<Action>;
register( register(
name: string, name: string,
actionHandlers: FluxActionHandlers<ActionType>, actionHandlers: FluxActionHandlers<ActionType>,
storeDidChange: (payload: Payload) => void, storeDidChange: FluxActionHandler<Action>,
band: number, band: FluxDispatchBand,
token?: string | undefined token?: string | undefined
): string; ): string;
_dependencyGraph: DepGraph<FluxActionHandlersGraphNode<Payload>>; _dependencyGraph: DepGraph<FluxActionHandlersGraphNode<Action>>;
_lastID: number; _lastID: number;
_orderedActionHandlers: Record<ActionType, FluxOrderedActionHandlers<Payload> | null>; _orderedActionHandlers: Record<ActionType, FluxOrderedActionHandlers<Action> | null>;
_orderedCallbackTokens: string[] | null; _orderedCallbackTokens: string[] | null;
} }
@ -105,18 +110,21 @@ interface SentryUtils {
}) => void; }) => void;
} }
type ActionMetric<ActionType extends FluxActionType = FluxActionType>
= [storeName: string, actionType: ActionType, totalTime: number];
class FluxActionLog< class FluxActionLog<
Payload extends FluxPayload<infer A> = FluxPayload, Action extends FluxAction<infer T> = FluxAction,
ActionType = A ActionType = T
> { > {
constructor(actionType: Payload); constructor(actionType: ActionType);
get name(): ActionType; get name(): ActionType;
toJSON(): Pick<FluxActionLog<ActionType>, "action" | "createdAt" | "traces"> & { toJSON(): Pick<FluxActionLog<ActionType>, "action" | "createdAt" | "traces"> & {
created_at: FluxActionLog["createdAt"]; created_at: FluxActionLog["createdAt"];
}; };
action: Payload; action: Action;
createdAt: Date; createdAt: Date;
error: Error | undefined; error: Error | undefined;
id: number; id: number;
@ -129,69 +137,77 @@ class FluxActionLog<
} }
class FluxActionLogger< class FluxActionLogger<
Payload extends FluxPayload<infer A> = FluxPayload, Action extends FluxAction<infer T> = FluxAction,
ActionType = A ActionType = T
> extends EventEmitter { > extends EventEmitter {
constructor(options?: { persist?: boolean | undefined; } | undefined); constructor(options?: { persist?: boolean | undefined; } | undefined);
getLastActionMetrics(title: string, quantity?: number | undefined /* = 20 */): [ getLastActionMetrics(
storeName: string, title: string,
actionType: ActionType, limit?: number | undefined /* = 20 */
totalTime: number ): ActionMetric<ActionType>[];
]; getSlowestActions(
getSlowestActions(actionType?: ActionType | Nullish, quantity?: number | undefined /* = 20 */): []; actionType?: ActionType | Nullish,
log<T extends ActionType>( limit?: number | undefined /* = 20 */
actionType: T, ): ActionMetric<ActionType>[];
log<A extends Action>(
action: A,
callback: (func: <U extends () => any>(storeName: string, func: U) => ReturnType<U>) => void callback: (func: <U extends () => any>(storeName: string, func: U) => ReturnType<U>) => void
): FluxActionLog<T>; ): FluxActionLog<A>;
logs: FluxActionLog<ActionType>[]; logs: FluxActionLog<Action>[];
persist: boolean; persist: boolean;
} }
export class FluxDispatcher< export class FluxDispatcher<
Payload extends FluxPayload<infer A> = FluxPayload, Action extends FluxAction<infer T> = FluxAction,
ActionType = A ActionType = T
> { > {
constructor( constructor(
defaultBand?: number | undefined /* = 0 */, defaultBand?: number | undefined /* = 0 */,
actionLogger?: FluxActionLogger<Payload> | Nullish, actionLogger?: FluxActionLogger<Action> | Nullish,
sentryUtils?: SentryUtils | Nullish sentryUtils?: SentryUtils | Nullish
); );
_dispatch( _dispatch(
payload: Payload, action: Action,
func: <U extends () => any>(storeName: string, func: U) => ReturnType<U> func: <U extends () => any>(storeName: string, func: U) => ReturnType<U>
): false | void; ): false | void;
_dispatchWithDevtools(payload: Payload): void; _dispatchWithDevtools(action: Action): void;
_dispatchWithLogging(payload: Payload): void; _dispatchWithLogging(action: Action): void;
addDependencies(fromToken: string, toTokens: string[]): void; addDependencies(fromToken: string, toTokens: string[]): void;
addInterceptor(interceptor: (payload: Payload) => boolean): void; addInterceptor(interceptor: FluxActionHandler<Action>): void;
createToken(): string; createToken(): string;
dispatch(payload: Payload): Promise<void>; dispatch(action: Action): Promise<void>;
flushWaitQueue(): void; flushWaitQueue(): void;
isDispatching(): boolean; isDispatching(): boolean;
register( register(
name: string, name: string,
actionHandlers: FluxActionHandlers<ActionType>, actionHandlers: FluxActionHandlers<ActionType>,
storeDidChange: (payload: Payload) => void, storeDidChange: FluxActionHandler<Action>,
band?: number | Nullish, band?: number | Nullish,
token?: string | undefined token?: string | undefined
): string; ): string;
subscribe(actionType: ActionType, listener: (payload: Payload) => void): void; subscribe<A extends Action<infer U>, AT = U>(
unsubscribe(actionType: ActionType, listener: (payload: Payload) => void): void; actionType: AT,
listener: FluxActionHandler<A>
): void;
unsubscribe<A extends Action<infer U>, AT = U>(
actionType: AT,
listener: FluxActionHandler<A>
): void;
wait(callback: () => void): void; wait(callback: () => void): void;
_actionHandlers: FluxActionHandlersGraph<Payload>; _actionHandlers: FluxActionHandlersGraph<Action>;
_currentDispatchActionType: ActionType | Nullish; _currentDispatchActionType: ActionType | Nullish;
_defaultBand: number; _defaultBand: number;
_interceptors: ((payload: Payload) => boolean)[]; _interceptors: ((action: Action) => boolean)[];
_processingWaitQueue: boolean; _processingWaitQueue: boolean;
_sentryUtils: SentryUtils | Nullish; _sentryUtils: SentryUtils | Nullish;
_subscriptions: Record<ActionType, Set<(payload: Payload) => void> | Nullish>; _subscriptions: Record<ActionType, Set<FluxActionHandler<Action>> | Nullish>;
_waitQueue: (() => void)[]; _waitQueue: (() => void)[];
actionLogger: FluxActionLogger<Payload>; actionLogger: FluxActionLogger<Action>;
functionCache: Record<ActionType, (payload: Payload) => void>; functionCache: Record<ActionType, FluxActionHandler<Action>>;
} }
export type Parser = Record< export type Parser = Record<