Merge branch 'immediate-finds' into immediate-finds-modules-proxy

This commit is contained in:
Nuckyz 2024-05-30 01:10:26 -03:00
commit 9084459933
No known key found for this signature in database
GPG key ID: 440BF8296E1C4AD9
6 changed files with 58 additions and 74 deletions

View file

@ -391,7 +391,7 @@ async function runtime(token: string) {
// True if resolved, false otherwise // True if resolved, false otherwise
const chunksSearchPromises = [] as Array<() => boolean>; const chunksSearchPromises = [] as Array<() => boolean>;
const LazyChunkRegex = canonicalizeMatch(/(?:Promise\.all\(\[(\i\.\i\("[^)]+?"\)[^\]]+?)\]\)|(\i\.\i\("[^)]+?"\)))\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/g); const LazyChunkRegex = canonicalizeMatch(/(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?)\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/g);
async function searchAndLoadLazyChunks(factoryCode: string) { async function searchAndLoadLazyChunks(factoryCode: string) {
const lazyChunks = factoryCode.matchAll(LazyChunkRegex); const lazyChunks = factoryCode.matchAll(LazyChunkRegex);
@ -401,8 +401,7 @@ async function runtime(token: string) {
// the chunk containing the component // the chunk containing the component
const shouldForceDefer = factoryCode.includes(".Messages.GUILD_FEED_UNFEATURE_BUTTON_TEXT"); const shouldForceDefer = factoryCode.includes(".Messages.GUILD_FEED_UNFEATURE_BUTTON_TEXT");
await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIdsArray, rawChunkIdsSingle, entryPoint]) => { await Promise.all(Array.from(lazyChunks).map(async ([, rawChunkIds, entryPoint]) => {
const rawChunkIds = rawChunkIdsArray ?? rawChunkIdsSingle;
const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Vencord.Webpack.ChunkIdsRegex)).map(m => m[1]) : []; const chunkIds = rawChunkIds ? Array.from(rawChunkIds.matchAll(Vencord.Webpack.ChunkIdsRegex)).map(m => m[1]) : [];
if (chunkIds.length === 0) { if (chunkIds.length === 0) {
@ -521,8 +520,7 @@ async function runtime(token: string) {
} }
} }
// eslint-disable-next-line prefer-const await Promise.all(Vencord.Webpack.webpackSearchHistory.map(async ([searchType, args]) => {
for (let [searchType, args] of Vencord.Webpack.webpackSearchHistory) {
args = [...args]; args = [...args];
try { try {
@ -538,9 +536,9 @@ async function runtime(token: string) {
case "extractAndLoadChunks": { case "extractAndLoadChunks": {
const [code, matcher] = args; const [code, matcher] = args;
const module = Vencord.Webpack.findModuleFactory(...code); result = await Vencord.Webpack.extractAndLoadChunks(code, matcher);
if (module) { if (result === false) {
result = String(module).match(Vencord.Util.canonicalizeMatch(matcher)); result = null;
} }
break; break;
@ -610,7 +608,7 @@ async function runtime(token: string) {
console.log("[PUP_WEBPACK_FIND_FAIL]", logMessage); console.log("[PUP_WEBPACK_FIND_FAIL]", logMessage);
} }
} }));
setTimeout(() => console.log("[PUPPETEER_TEST_DONE_SIGNAL]"), 1000); setTimeout(() => console.log("[PUPPETEER_TEST_DONE_SIGNAL]"), 1000);
} catch (e) { } catch (e) {

View file

@ -56,8 +56,7 @@ const PermissionUtil = findByProps("computePermissions", "canEveryoneRole") as {
computePermissions({ ...args }): bigint; computePermissions({ ...args }): bigint;
}; };
const Tag = findComponentByCode(".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP,") as React.ComponentType<{ type?: number, className?: string, useRemSizes?: boolean; }>; const Tag = findComponentByCode(".DISCORD_SYSTEM_MESSAGE_BOT_TAG_TOOLTIP,") as React.ComponentType<{ type?: number, className?: string, useRemSizes?: boolean; }> & { Types: Record<string, number>; };
const { BotTagTypes } = findByProps("BotTagTypes");
const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot(); const isWebhook = (message: Message, user: User) => !!message?.webhookId && user.isNonUserBot();
@ -123,7 +122,7 @@ function SettingsComponent(props: { setValue(v: any): void; }) {
onMouseEnter={onMouseEnter} onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave} onMouseLeave={onMouseLeave}
> >
{t.displayName} Tag <Tag type={BotTagTypes[t.name]} /> {t.displayName} Tag <Tag type={Tag.Types[t.name]} />
</div> </div>
)} )}
</Tooltip> </Tooltip>
@ -303,7 +302,7 @@ export default definePlugin({
return obj; return obj;
}, },
isOPTag: (tag: number) => tag === BotTagTypes.ORIGINAL_POSTER || tags.some(t => tag === BotTagTypes[`${t.name}-OP`]), isOPTag: (tag: number) => tag === Tag.Types.ORIGINAL_POSTER || tags.some(t => tag === Tag.Types[`${t.name}-OP`]),
getTagText(passedTagName: string, strings: Record<string, string>) { getTagText(passedTagName: string, strings: Record<string, string>) {
if (!passedTagName) return strings.APP_TAG; if (!passedTagName) return strings.APP_TAG;
@ -336,9 +335,9 @@ export default definePlugin({
if (!user) if (!user)
return null; return null;
if (location === "chat" && user.id === "1") if (location === "chat" && user.id === "1")
return BotTagTypes.OFFICIAL; return Tag.Types.OFFICIAL;
if (user.isClyde()) if (user.isClyde())
return BotTagTypes.AI; return Tag.Types.AI;
let type = typeof origType === "number" ? origType : null; let type = typeof origType === "number" ? origType : null;
@ -366,11 +365,11 @@ export default definePlugin({
(tag.condition?.(message!, user, channel)) (tag.condition?.(message!, user, channel))
) { ) {
if (channel.isForumPost() && channel.ownerId === user.id) if (channel.isForumPost() && channel.ownerId === user.id)
type = BotTagTypes[`${tag.name}-OP`]; type = Tag.Types[`${tag.name}-OP`];
else if (user.bot && !isWebhook(message!, user) && !settings.dontShowBotTag) else if (user.bot && !isWebhook(message!, user) && !settings.dontShowBotTag)
type = BotTagTypes[`${tag.name}-BOT`]; type = Tag.Types[`${tag.name}-BOT`];
else else
type = BotTagTypes[tag.name]; type = Tag.Types[tag.name];
break; break;
} }
} }

View file

@ -68,6 +68,7 @@ const handler: ProxyHandler<any> = {
/** /**
* Wraps the result of factory in a Proxy you can consume as if it wasn't lazy. * Wraps the result of factory in a Proxy you can consume as if it wasn't lazy.
* On first property access, the factory is evaluated. * On first property access, the factory is evaluated.
*
* @param factory Factory returning the result * @param factory Factory returning the result
* @param attempts How many times to try to evaluate the factory before giving up * @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function * @returns Result of factory function

View file

@ -9,13 +9,6 @@ import { makeLazy } from "./lazy";
/** /**
* A lazy component. The factory method is called on first render. * A lazy component. The factory method is called on first render.
* *
* IMPORTANT: You cannot access properties set on the lazy component using this method.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = LazyComponent(...);
* console.log(Component.Types); // This will not work
* ````
* @param factory Function returning a component * @param factory Function returning a component
* @param attempts How many times to try to get the component before giving up * @param attempts How many times to try to get the component before giving up
* @returns Result of factory function * @returns Result of factory function
@ -31,6 +24,7 @@ export function LazyComponent<T extends object = any>(factory: () => React.Compo
const ResultComponent = get(); const ResultComponent = get();
if (ResultComponent != null) { if (ResultComponent != null) {
InnerComponent = ResultComponent; InnerComponent = ResultComponent;
Object.assign(LazyComponent, ResultComponent);
} }
} }

View file

@ -43,6 +43,7 @@ const handler: ProxyHandler<any> = {
/** /**
* A proxy which has an inner value that can be set later. * A proxy which has an inner value that can be set later.
* When a property is accessed, the proxy looks for the property value in its inner value, and errors if it's not set. * When a property is accessed, the proxy looks for the property value in its inner value, and errors if it's not set.
*
* @param err The error message to throw when the inner value is not set * @param err The error message to throw when the inner value is not set
* @param primitiveErr The error message to throw when the inner value is a primitive * @param primitiveErr The error message to throw when the inner value is a primitive
* @returns A proxy which will act like the inner value when accessed * @returns A proxy which will act like the inner value when accessed

View file

@ -130,6 +130,7 @@ function printFilter(filter: FilterFn) {
* then call the callback with the module as the first argument. * then call the callback with the module as the first argument.
* *
* If the module is already required, the callback will be called immediately. * If the module is already required, the callback will be called immediately.
*
* @param filter A function that takes a module and returns a boolean * @param filter A function that takes a module and returns a boolean
* @param callback A function that takes the found module as its first argument * @param callback A function that takes the found module as its first argument
*/ */
@ -173,6 +174,7 @@ export function waitFor(filter: FilterFn, callback: ModCallbackFn, { isIndirect
* The callback must return a value that will be used as the proxy inner value. * The callback must return a value that will be used as the proxy inner value.
* *
* If no callback is specified, the default callback will assign the proxy inner value to all the module. * If no callback is specified, the default callback will assign the proxy inner value to all the module.
*
* @param filter A function that takes a module and returns a boolean * @param filter A function that takes a module and returns a boolean
* @param callback A function that takes the found module as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the module, instead of all of it. Defaults to the module itself * @param callback A function that takes the found module as its first argument and returns something to use as the proxy inner value. Useful if you want to use a value from the module, instead of all of it. Defaults to the module itself
* @returns A proxy that has the callback return value as its true value, or the callback return value if the callback was called when the function was called * @returns A proxy that has the callback return value as its true value, or the callback return value if the callback was called when the function was called
@ -198,13 +200,6 @@ export function find<T = AnyObject>(filter: FilterFn, callback: (module: ModuleE
/** /**
* Find the first component that matches the filter. * Find the first component that matches the filter.
* *
* IMPORTANT: You cannot access properties set on the found component using this method. You should instead try to obtain the property using a non component find instead.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = findComponent(...);
* console.log(Component.Types); // This will not work
* ````
* @param filter A function that takes a module and returns a boolean * @param filter A function that takes a module and returns a boolean
* @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component * @param parse A function that takes the found component as its first argument and returns a component. Useful if you want to wrap the found component in something. Defaults to the original component
* @returns The component if found, or a noop component * @returns The component if found, or a noop component
@ -230,7 +225,7 @@ export function findComponent<T extends object = any>(filter: FilterFn, parse: (
waitFor(filter, (v: any) => { waitFor(filter, (v: any) => {
const parsedComponent = parse(v); const parsedComponent = parse(v);
InnerComponent = parsedComponent; InnerComponent = parsedComponent;
Object.assign(InnerComponent, parsedComponent); Object.assign(WrapperComponent, parsedComponent);
}, { isIndirect: true }); }, { isIndirect: true });
if (IS_DEV) { if (IS_DEV) {
@ -249,13 +244,6 @@ export function findComponent<T extends object = any>(filter: FilterFn, parse: (
/** /**
* Find the first component that is exported by the first prop name. * Find the first component that is exported by the first prop name.
* *
* IMPORTANT: You cannot access properties set on the found component using this method. You should instead try to obtain the property using a non component find instead.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = findExportedComponent(...);
* console.log(Component.Types); // This will not work
* ````
* @example findExportedComponent("FriendRow") * @example findExportedComponent("FriendRow")
* @example findExportedComponent("FriendRow", "Friend", FriendRow => React.memo(FriendRow)) * @example findExportedComponent("FriendRow", "Friend", FriendRow => React.memo(FriendRow))
* *
@ -285,7 +273,7 @@ export function findExportedComponent<T extends object = any>(...props: string[]
waitFor(filter, (v: any) => { waitFor(filter, (v: any) => {
const parsedComponent = parse(v[newProps[0]]); const parsedComponent = parse(v[newProps[0]]);
InnerComponent = parsedComponent; InnerComponent = parsedComponent;
Object.assign(InnerComponent, parsedComponent); Object.assign(WrapperComponent, parsedComponent);
}, { isIndirect: true }); }, { isIndirect: true });
if (IS_DEV) { if (IS_DEV) {
@ -301,13 +289,6 @@ export function findExportedComponent<T extends object = any>(...props: string[]
/** /**
* Find the first component in a default export that includes all the given code. * Find the first component in a default export that includes all the given code.
* *
* IMPORTANT: You cannot access properties set on the found component using this method. You should instead try to obtain the property using a non component find instead.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = findComponentByCode(...);
* console.log(Component.Types); // This will not work
* ````
* @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR") * @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR")
* @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)", ColorPicker => React.memo(ColorPicker)) * @example findComponentByCode(".Messages.USER_SETTINGS_PROFILE_COLOR_SELECT_COLOR", ".BACKGROUND_PRIMARY)", ColorPicker => React.memo(ColorPicker))
* *
@ -375,6 +356,7 @@ export function findStore<T = GenericStore>(name: string) {
/** /**
* Find the first already required module that matches the filter. * Find the first already required module that matches the filter.
*
* @param filter A function that takes a module and returns a boolean * @param filter A function that takes a module and returns a boolean
* @returns The found module or null * @returns The found module or null
*/ */
@ -422,6 +404,7 @@ export function cacheFindAll(filter: FilterFn) {
/** /**
* Same as {@link cacheFind} but in bulk. * Same as {@link cacheFind} but in bulk.
*
* @param filterFns Array of filters. Please note that this array will be modified in place, so if you still * @param filterFns Array of filters. Please note that this array will be modified in place, so if you still
* need it afterwards, pass a copy. * need it afterwards, pass a copy.
* @returns Array of results in the same order as the passed filters * @returns Array of results in the same order as the passed filters
@ -528,6 +511,7 @@ export function findModuleFactory(...code: string[]) {
* *
* Wraps the result of factory in a Proxy you can consume as if it wasn't lazy. * Wraps the result of factory in a Proxy you can consume as if it wasn't lazy.
* On first property access, the factory is evaluated. * On first property access, the factory is evaluated.
*
* @param factory Factory returning the result * @param factory Factory returning the result
* @param attempts How many times to try to evaluate the factory before giving up * @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function * @returns Result of factory function
@ -543,13 +527,6 @@ export function webpackDependantLazy<T = AnyObject>(factory: () => T, attempts?:
* *
* A lazy component. The factory method is called on first render. * A lazy component. The factory method is called on first render.
* *
* IMPORTANT: You cannot access properties set on the lazy component using this method.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = webpackDependantLazyComponent(...);
* console.log(Component.Types); // This will not work
* ````
* @param factory Function returning a Component * @param factory Function returning a Component
* @param attempts How many times to try to get the component before giving up * @param attempts How many times to try to get the component before giving up
* @returns Result of factory function * @returns Result of factory function
@ -574,6 +551,7 @@ function deprecatedRedirect<T extends (...args: any[]) => any>(oldMethod: string
* *
* Wraps the result of factory in a Proxy you can consume as if it wasn't lazy. * Wraps the result of factory in a Proxy you can consume as if it wasn't lazy.
* On first property access, the factory is evaluated. * On first property access, the factory is evaluated.
*
* @param factory Factory returning the result * @param factory Factory returning the result
* @param attempts How many times to try to evaluate the factory before giving up * @param attempts How many times to try to evaluate the factory before giving up
* @returns Result of factory function * @returns Result of factory function
@ -587,13 +565,6 @@ export const proxyLazyWebpack = deprecatedRedirect("proxyLazyWebpack", "webpackD
* *
* A lazy component. The factory method is called on first render. * A lazy component. The factory method is called on first render.
* *
* IMPORTANT: You cannot access properties set on the lazy component using this method.
*
* Example of how you cannot access the properties set on the component:
* ```
* const Component = LazyComponentWebpack(...);
* console.log(Component.Types); // This will not work
* ````
* @param factory Function returning a Component * @param factory Function returning a Component
* @param attempts How many times to try to get the component before giving up * @param attempts How many times to try to get the component before giving up
* @returns Result of factory function * @returns Result of factory function
@ -659,20 +630,22 @@ export const findAll = deprecatedRedirect("findAll", "cacheFindAll", cacheFindAl
* @deprecated Use {@link cacheFindBulk} instead * @deprecated Use {@link cacheFindBulk} instead
* *
* Same as {@link cacheFind} but in bulk * Same as {@link cacheFind} but in bulk
*
* @param filterFns Array of filters. Please note that this array will be modified in place, so if you still * @param filterFns Array of filters. Please note that this array will be modified in place, so if you still
* need it afterwards, pass a copy. * need it afterwards, pass a copy.
* @returns Array of results in the same order as the passed filters * @returns Array of results in the same order as the passed filters
*/ */
export const findBulk = deprecatedRedirect("findBulk", "cacheFindBulk", cacheFindBulk); export const findBulk = deprecatedRedirect("findBulk", "cacheFindBulk", cacheFindBulk);
export const DefaultExtractAndLoadChunksRegex = /(?:Promise\.all\(\[(\i\.\i\("[^)]+?"\)[^\]]+?)\]\)|(\i\.\i\("[^)]+?"\))|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/; export const DefaultExtractAndLoadChunksRegex = /(?:(?:Promise\.all\(\[)?(\i\.e\("[^)]+?"\)[^\]]*?)(?:\]\))?|Promise\.resolve\(\))\.then\(\i\.bind\(\i,"([^)]+?)"\)\)/;
export const ChunkIdsRegex = /\("(.+?)"\)/g; export const ChunkIdsRegex = /\("([^"]+?)"\)/g;
/** /**
* Extract and load chunks using their entry point. * Extract and load chunks using their entry point.
*
* @param code An array of all the code the module factory containing the lazy chunk loading must include * @param code An array of all the code the module factory containing the lazy chunk loading must include
* @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the first lazy chunk loading found in the module factory
* @returns A promise that resolves when the chunks were loaded * @returns A promise that resolves with a boolean whether the chunks were loaded
*/ */
export async function extractAndLoadChunks(code: string[], matcher: RegExp = DefaultExtractAndLoadChunksRegex) { export async function extractAndLoadChunks(code: string[], matcher: RegExp = DefaultExtractAndLoadChunksRegex) {
const module = findModuleFactory(...code); const module = findModuleFactory(...code);
@ -680,7 +653,11 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = Def
const err = new Error("extractAndLoadChunks: Couldn't find module factory"); const err = new Error("extractAndLoadChunks: Couldn't find module factory");
logger.warn(err, "Code:", code, "Matcher:", matcher); logger.warn(err, "Code:", code, "Matcher:", matcher);
return; // Strict behaviour in DevBuilds to fail early and make sure the issue is found
if (IS_DEV && !devToolsOpen)
throw err;
return false;
} }
const match = String(module).match(canonicalizeMatch(matcher)); const match = String(module).match(canonicalizeMatch(matcher));
@ -692,10 +669,10 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = Def
if (IS_DEV && !devToolsOpen) if (IS_DEV && !devToolsOpen)
throw err; throw err;
return; return false;
} }
const [, rawChunkIdsArray, rawChunkIdsSingle, entryPointId] = match; const [, rawChunkIds, entryPointId] = match;
if (Number.isNaN(Number(entryPointId))) { if (Number.isNaN(Number(entryPointId))) {
const err = new Error("extractAndLoadChunks: Matcher didn't return a capturing group with the chunk ids array, or the entry point id returned as the second group wasn't a number"); const err = new Error("extractAndLoadChunks: Matcher didn't return a capturing group with the chunk ids array, or the entry point id returned as the second group wasn't a number");
logger.warn(err, "Code:", code, "Matcher:", matcher); logger.warn(err, "Code:", code, "Matcher:", matcher);
@ -704,25 +681,37 @@ export async function extractAndLoadChunks(code: string[], matcher: RegExp = Def
if (IS_DEV && !devToolsOpen) if (IS_DEV && !devToolsOpen)
throw err; throw err;
return; return false;
} }
const rawChunkIds = rawChunkIdsArray ?? rawChunkIdsSingle;
if (rawChunkIds) { if (rawChunkIds) {
const chunkIds = Array.from(rawChunkIds.matchAll(ChunkIdsRegex)).map((m: any) => m[1]); const chunkIds = Array.from(rawChunkIds.matchAll(ChunkIdsRegex)).map((m: any) => m[1]);
await Promise.all(chunkIds.map(id => wreq.e(id))); await Promise.all(chunkIds.map(id => wreq.e(id)));
} }
if (wreq.m[entryPointId] == null) {
const err = new Error("extractAndLoadChunks: Entry point is not loaded in the module factories, perhaps one of the chunks failed to load");
logger.warn(err, "Code:", code, "Matcher:", matcher);
// Strict behaviour in DevBuilds to fail early and make sure the issue is found
if (IS_DEV && !devToolsOpen)
throw err;
return false;
}
wreq(entryPointId); wreq(entryPointId);
return true;
} }
/** /**
* This is just a wrapper around {@link extractAndLoadChunks} to make our reporter test for your webpack finds. * This is just a wrapper around {@link extractAndLoadChunks} to make our reporter test for your webpack finds.
* *
* Extract and load chunks using their entry point. * Extract and load chunks using their entry point.
*
* @param code An array of all the code the module factory containing the lazy chunk loading must include * @param code An array of all the code the module factory containing the lazy chunk loading must include
* @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the lazy chunk loading found in the module factory * @param matcher A RegExp that returns the chunk ids array as the first capture group and the entry point id as the second. Defaults to a matcher that captures the first lazy chunk loading found in the module factory
* @returns A function that returns a promise that resolves when the chunks were loaded, on first call * @returns A function that returns a promise that resolves with a boolean whether the chunks were loaded, on first call
*/ */
export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtractAndLoadChunksRegex) { export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtractAndLoadChunksRegex) {
if (IS_DEV) webpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]); if (IS_DEV) webpackSearchHistory.push(["extractAndLoadChunks", [code, matcher]]);
@ -732,7 +721,8 @@ export function extractAndLoadChunksLazy(code: string[], matcher = DefaultExtrac
/** /**
* Search modules by keyword. This searches the factory methods, * Search modules by keyword. This searches the factory methods,
* meaning you can search all sorts of things, displayName, methodName, strings somewhere in the code, etc * meaning you can search all sorts of things, methodName, strings somewhere in the code, etc.
*
* @param filters One or more strings or regexes * @param filters One or more strings or regexes
* @returns Mapping of found modules * @returns Mapping of found modules
*/ */
@ -759,6 +749,7 @@ export function search(...filters: Array<string | RegExp>) {
* to view a massive file. extract then returns the extracted module so you can jump to it. * to view a massive file. extract then returns the extracted module so you can jump to it.
* As mentioned above, note that this extracted module is not actually used, * As mentioned above, note that this extracted module is not actually used,
* so putting breakpoints or similar will have no effect. * so putting breakpoints or similar will have no effect.
*
* @param id The id of the module to extract * @param id The id of the module to extract
*/ */
export function extract(id: PropertyKey) { export function extract(id: PropertyKey) {