Make it possible to destructure lazy webpack finds

This commit is contained in:
V 2023-11-22 06:48:59 +01:00 committed by Nuckyz
parent ffe6512693
commit b21b6d7e5d
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
4 changed files with 36 additions and 18 deletions

View file

@ -18,9 +18,8 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { proxyLazy } from "@utils/lazy";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByProps, findByPropsLazy, findStoreLazy } from "@webpack"; import { findByPropsLazy, findStoreLazy } from "@webpack";
import { FluxDispatcher, i18n } from "@webpack/common"; import { FluxDispatcher, i18n } from "@webpack/common";
import FolderSideBar from "./FolderSideBar"; import FolderSideBar from "./FolderSideBar";
@ -31,7 +30,7 @@ enum FolderIconDisplay {
MoreThanOneFolderExpanded MoreThanOneFolderExpanded
} }
const GuildsTree = proxyLazy(() => findByProps("GuildsTree").GuildsTree); const { GuildsTree } = findByPropsLazy("GuildsTree");
const SortedGuildStore = findStoreLazy("SortedGuildStore"); const SortedGuildStore = findStoreLazy("SortedGuildStore");
export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore"); export const ExpandedGuildFolderStore = findStoreLazy("ExpandedGuildFolderStore");
const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand"); const FolderUtils = findByPropsLazy("move", "toggleGuildFolderExpand");

View file

@ -18,9 +18,8 @@
import { definePluginSettings } from "@api/Settings"; import { definePluginSettings } from "@api/Settings";
import { Devs } from "@utils/constants"; import { Devs } from "@utils/constants";
import { proxyLazy } from "@utils/lazy";
import definePlugin, { OptionType } from "@utils/types"; import definePlugin, { OptionType } from "@utils/types";
import { findByProps, findByPropsLazy } from "@webpack"; import { findByPropsLazy } from "@webpack";
import { ContextMenu, FluxDispatcher, Menu } from "@webpack/common"; import { ContextMenu, FluxDispatcher, Menu } from "@webpack/common";
import { Channel, Message } from "discord-types/general"; import { Channel, Message } from "discord-types/general";
@ -51,7 +50,7 @@ const settings = definePluginSettings({
}>(); }>();
const MessageActions = findByPropsLazy("sendGreetMessage"); const MessageActions = findByPropsLazy("sendGreetMessage");
const WELCOME_STICKERS = proxyLazy(() => findByProps("WELCOME_STICKERS")?.WELCOME_STICKERS); const { WELCOME_STICKERS } = findByPropsLazy("WELCOME_STICKERS");
function greet(channel: Channel, message: Message, stickers: string[]) { function greet(channel: Channel, message: Message, stickers: string[]) {
const options = MessageActions.getSendMessageOptionsForReply({ const options = MessageActions.getSendMessageOptionsForReply({

View file

@ -43,7 +43,6 @@ for (const method of [
"construct", "construct",
"defineProperty", "defineProperty",
"deleteProperty", "deleteProperty",
"get",
"getOwnPropertyDescriptor", "getOwnPropertyDescriptor",
"getPrototypeOf", "getPrototypeOf",
"has", "has",
@ -86,7 +85,11 @@ handler.getOwnPropertyDescriptor = (target, p) => {
* Note that the example below exists already as an api, see {@link findByPropsLazy} * Note that the example below exists already as an api, see {@link findByPropsLazy}
* @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah); * @example const mod = proxyLazy(() => findByProps("blah")); console.log(mod.blah);
*/ */
export function proxyLazy<T>(factory: () => T, attempts = 5): T { export function proxyLazy<T>(factory: () => T, attempts = 5, isChild = false): T {
let isSameTick = true;
if (!isChild)
setTimeout(() => isSameTick = false, 0);
let tries = 0; let tries = 0;
const proxyDummy = Object.assign(function () { }, { const proxyDummy = Object.assign(function () { }, {
[kCACHE]: void 0 as T | undefined, [kCACHE]: void 0 as T | undefined,
@ -100,5 +103,21 @@ export function proxyLazy<T>(factory: () => T, attempts = 5): T {
} }
}); });
return new Proxy(proxyDummy, handler) as any; return new Proxy(proxyDummy, {
...handler,
get(target, p, receiver) {
// if we're still in the same tick, it means the lazy was immediately used.
// thus, we lazy proxy the get access to make things like destructuring work as expected
// meow here will also be a lazy
// `const { meow } = findByPropsLazy("meow");`
if (!isChild && isSameTick)
return proxyLazy(
() => Reflect.get(target[kGET](), p, receiver),
attempts,
true
);
return Reflect.get(target[kGET](), p, receiver);
}
}) as any;
} }

View file

@ -16,11 +16,10 @@
* 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 { proxyLazy } from "@utils/lazy";
import type * as Stores from "discord-types/stores"; import type * as Stores from "discord-types/stores";
// eslint-disable-next-line path-alias/no-relative // eslint-disable-next-line path-alias/no-relative
import { filters, findByProps, findByPropsLazy, mapMangledModuleLazy } from "../webpack"; import { filters, findByPropsLazy, mapMangledModuleLazy } from "../webpack";
import { waitForStore } from "./internal"; import { waitForStore } from "./internal";
import * as t from "./types/stores"; import * as t from "./types/stores";
@ -78,13 +77,15 @@ export const MaskedLinkStore = mapMangledModuleLazy('"MaskedLinkStore"', {
* *
* @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id); * @example const user = useStateFromStores([UserStore], () => UserStore.getCurrentUser(), null, (old, current) => old.id === current.id);
*/ */
export const useStateFromStores: <T>( export const { useStateFromStores }: {
useStateFromStores: <T>(
stores: t.FluxStore[], stores: t.FluxStore[],
mapper: () => T, mapper: () => T,
idk?: any, idk?: any,
isEqual?: (old: T, newer: T) => boolean isEqual?: (old: T, newer: T) => boolean
) => T ) => T;
= proxyLazy(() => findByProps("useStateFromStores").useStateFromStores); }
= findByPropsLazy("useStateFromStores");
waitForStore("DraftStore", s => DraftStore = s); waitForStore("DraftStore", s => DraftStore = s);
waitForStore("UserStore", s => UserStore = s); waitForStore("UserStore", s => UserStore = s);