Add tracer, fix MessageActions slow startup
This commit is contained in:
		
							parent
							
								
									851d07f31a
								
							
						
					
					
						commit
						0af4579204
					
				
					 4 changed files with 87 additions and 21 deletions
				
			
		
							
								
								
									
										63
									
								
								src/debug/Tracer.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/debug/Tracer.ts
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,63 @@ | ||||||
|  | /* | ||||||
|  |  * Vencord, a modification for Discord's desktop app | ||||||
|  |  * Copyright (c) 2022 Vendicated and contributors | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | import Logger from "../utils/logger"; | ||||||
|  | 
 | ||||||
|  | if (IS_DEV) { | ||||||
|  |     var traces = {} as Record<string, [number, any[]]>; | ||||||
|  |     var logger = new Logger("Tracer", "#FFD166"); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const noop = function () { }; | ||||||
|  | 
 | ||||||
|  | export const beginTrace = !IS_DEV ? noop : | ||||||
|  |     function beginTrace(name: string, ...args: any[]) { | ||||||
|  |         if (name in traces) | ||||||
|  |             throw new Error(`Trace ${name} already exists!`); | ||||||
|  | 
 | ||||||
|  |         traces[name] = [performance.now(), args]; | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  | export const finishTrace = !IS_DEV ? noop : function finishTrace(name: string) { | ||||||
|  |     const end = performance.now(); | ||||||
|  | 
 | ||||||
|  |     const [start, args] = traces[name]; | ||||||
|  |     delete traces[name]; | ||||||
|  | 
 | ||||||
|  |     logger.debug(`${name} took ${end - start}ms`, args); | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | type Func = (...args: any[]) => any; | ||||||
|  | type TraceNameMapper<F extends Func> = (...args: Parameters<F>) => string; | ||||||
|  | 
 | ||||||
|  | const noopTracer = | ||||||
|  |     <F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>) => f; | ||||||
|  | 
 | ||||||
|  | export const traceFunction = !IS_DEV | ||||||
|  |     ? noopTracer | ||||||
|  |     : function traceFunction<F extends Func>(name: string, f: F, mapper?: TraceNameMapper<F>): F { | ||||||
|  |         return function (this: any, ...args: Parameters<F>) { | ||||||
|  |             const traceName = mapper?.(...args) ?? name; | ||||||
|  | 
 | ||||||
|  |             beginTrace(traceName, ...arguments); | ||||||
|  |             const result = f.apply(this, args); | ||||||
|  |             finishTrace(traceName); | ||||||
|  | 
 | ||||||
|  |             return result; | ||||||
|  |         } as F; | ||||||
|  |     }; | ||||||
|  | @ -20,6 +20,7 @@ import Plugins from "~plugins"; | ||||||
| 
 | 
 | ||||||
| import { registerCommand, unregisterCommand } from "../api/Commands"; | import { registerCommand, unregisterCommand } from "../api/Commands"; | ||||||
| import { Settings } from "../api/settings"; | import { Settings } from "../api/settings"; | ||||||
|  | import { traceFunction } from "../debug/Tracer"; | ||||||
| import Logger from "../utils/logger"; | import Logger from "../utils/logger"; | ||||||
| import { Patch, Plugin } from "../utils/types"; | import { Patch, Plugin } from "../utils/types"; | ||||||
| 
 | 
 | ||||||
|  | @ -43,12 +44,12 @@ for (const p of Object.values(Plugins)) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| export function startAllPlugins() { | export const startAllPlugins = traceFunction("startAllPlugins", function startAllPlugins() { | ||||||
|     for (const name in Plugins) |     for (const name in Plugins) | ||||||
|         if (isPluginEnabled(name)) { |         if (isPluginEnabled(name)) { | ||||||
|             startPlugin(Plugins[name]); |             startPlugin(Plugins[name]); | ||||||
|         } |         } | ||||||
| } | }); | ||||||
| 
 | 
 | ||||||
| export function startDependenciesRecursive(p: Plugin) { | export function startDependenciesRecursive(p: Plugin) { | ||||||
|     let restartNeeded = false; |     let restartNeeded = false; | ||||||
|  | @ -70,7 +71,7 @@ export function startDependenciesRecursive(p: Plugin) { | ||||||
|     return { restartNeeded, failures }; |     return { restartNeeded, failures }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function startPlugin(p: Plugin) { | export const startPlugin = traceFunction("startPlugin", function startPlugin(p: Plugin) { | ||||||
|     if (p.start) { |     if (p.start) { | ||||||
|         logger.info("Starting plugin", p.name); |         logger.info("Starting plugin", p.name); | ||||||
|         if (p.started) { |         if (p.started) { | ||||||
|  | @ -100,9 +101,9 @@ export function startPlugin(p: Plugin) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | }, p => `startPlugin ${p.name}`); | ||||||
| 
 | 
 | ||||||
| export function stopPlugin(p: Plugin) { | export const stopPlugin = traceFunction("stopPlugin", function stopPlugin(p: Plugin) { | ||||||
|     if (p.stop) { |     if (p.stop) { | ||||||
|         logger.info("Stopping plugin", p.name); |         logger.info("Stopping plugin", p.name); | ||||||
|         if (!p.started) { |         if (!p.started) { | ||||||
|  | @ -131,4 +132,4 @@ export function stopPlugin(p: Plugin) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | }, p => `stopPlugin ${p.name}`); | ||||||
|  |  | ||||||
|  | @ -17,9 +17,10 @@ | ||||||
| */ | */ | ||||||
| 
 | 
 | ||||||
| import { addClickListener, removeClickListener } from "../api/MessageEvents"; | import { addClickListener, removeClickListener } from "../api/MessageEvents"; | ||||||
|  | import { lazyWebpack } from "../utils"; | ||||||
| import { Devs } from "../utils/constants"; | import { Devs } from "../utils/constants"; | ||||||
| import definePlugin from "../utils/types"; | import definePlugin from "../utils/types"; | ||||||
| import { find, findByProps } from "../webpack"; | import { filters } from "../webpack"; | ||||||
| import { UserStore } from "../webpack/common"; | import { UserStore } from "../webpack/common"; | ||||||
| 
 | 
 | ||||||
| let isDeletePressed = false; | let isDeletePressed = false; | ||||||
|  | @ -33,10 +34,10 @@ export default definePlugin({ | ||||||
|     dependencies: ["MessageEventsAPI"], |     dependencies: ["MessageEventsAPI"], | ||||||
| 
 | 
 | ||||||
|     start() { |     start() { | ||||||
|         const { deleteMessage, startEditMessage } = findByProps("deleteMessage", "startEditMessage"); |         const MessageActions = lazyWebpack(filters.byProps("deleteMessage", "startEditMessage")); | ||||||
|         const { can } = findByProps("can", "initialize"); |         const PermissionStore = lazyWebpack(filters.byProps("can", "initialize")); | ||||||
|         const { MANAGE_MESSAGES } = find(m => typeof m.MANAGE_MESSAGES === "bigint"); |         const Permissions = lazyWebpack(m => typeof m.MANAGE_MESSAGES === "bigint"); | ||||||
|         const { isEditing } = findByProps("isEditing", "isEditingAny"); |         const EditStore = lazyWebpack(filters.byProps("isEditing", "isEditingAny")); | ||||||
| 
 | 
 | ||||||
|         document.addEventListener("keydown", keydown); |         document.addEventListener("keydown", keydown); | ||||||
|         document.addEventListener("keyup", keyup); |         document.addEventListener("keyup", keyup); | ||||||
|  | @ -44,12 +45,12 @@ export default definePlugin({ | ||||||
|         this.onClick = addClickListener((msg, chan, event) => { |         this.onClick = addClickListener((msg, chan, event) => { | ||||||
|             const isMe = msg.author.id === UserStore.getCurrentUser().id; |             const isMe = msg.author.id === UserStore.getCurrentUser().id; | ||||||
|             if (!isDeletePressed) { |             if (!isDeletePressed) { | ||||||
|                 if (isMe && event.detail >= 2 && !isEditing(chan.id, msg.id)) { |                 if (isMe && event.detail >= 2 && !EditStore.isEditing(chan.id, msg.id)) { | ||||||
|                     startEditMessage(chan.id, msg.id, msg.content); |                     MessageActions.startEditMessage(chan.id, msg.id, msg.content); | ||||||
|                     event.preventDefault(); |                     event.preventDefault(); | ||||||
|                 } |                 } | ||||||
|             } else if (isMe || can(MANAGE_MESSAGES, chan)) { |             } else if (isMe || PermissionStore.can(Permissions.MANAGE_MESSAGES, chan)) { | ||||||
|                 deleteMessage(chan.id, msg.id); |                 MessageActions.deleteMessage(chan.id, msg.id); | ||||||
|                 event.preventDefault(); |                 event.preventDefault(); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|  |  | ||||||
|  | @ -18,6 +18,7 @@ | ||||||
| 
 | 
 | ||||||
| import type { WebpackInstance } from "discord-types/other"; | import type { WebpackInstance } from "discord-types/other"; | ||||||
| 
 | 
 | ||||||
|  | import { traceFunction } from "../debug/Tracer"; | ||||||
| import Logger from "../utils/logger"; | import Logger from "../utils/logger"; | ||||||
| import { proxyLazy } from "../utils/proxyLazy"; | import { proxyLazy } from "../utils/proxyLazy"; | ||||||
| 
 | 
 | ||||||
|  | @ -74,7 +75,7 @@ if (IS_DEV && !IS_WEB) { | ||||||
|     }, 0); |     }, 0); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function find(filter: FilterFn, getDefault = true, isWaitFor = false) { | export const find = traceFunction("find", function find(filter: FilterFn, getDefault = true, isWaitFor = false) { | ||||||
|     if (typeof filter !== "function") |     if (typeof filter !== "function") | ||||||
|         throw new Error("Invalid filter. Expected a function got " + typeof filter); |         throw new Error("Invalid filter. Expected a function got " + typeof filter); | ||||||
| 
 | 
 | ||||||
|  | @ -109,7 +110,7 @@ export function find(filter: FilterFn, getDefault = true, isWaitFor = false) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return null; |     return null; | ||||||
| } | }); | ||||||
| 
 | 
 | ||||||
| export function findAll(filter: FilterFn, getDefault = true) { | export function findAll(filter: FilterFn, getDefault = true) { | ||||||
|     if (typeof filter !== "function") |     if (typeof filter !== "function") | ||||||
|  | @ -222,7 +223,7 @@ export function bulk(...filterFns: FilterFn[]) { | ||||||
|  * @param code Code |  * @param code Code | ||||||
|  * @returns number or null |  * @returns number or null | ||||||
|  */ |  */ | ||||||
| export function findModuleId(code: string) { | export const findModuleId = traceFunction("findModuleId", function findModuleId(code: string) { | ||||||
|     for (const id in wreq.m) { |     for (const id in wreq.m) { | ||||||
|         if (wreq.m[id].toString().includes(code)) { |         if (wreq.m[id].toString().includes(code)) { | ||||||
|             return Number(id); |             return Number(id); | ||||||
|  | @ -239,7 +240,7 @@ export function findModuleId(code: string) { | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     return null; |     return null; | ||||||
| } | }); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Finds a mangled module by the provided code "code" (must be unique and can be anywhere in the module) |  * Finds a mangled module by the provided code "code" (must be unique and can be anywhere in the module) | ||||||
|  | @ -253,7 +254,7 @@ export function findModuleId(code: string) { | ||||||
|  *             closeModal: filters.byCode("key==") |  *             closeModal: filters.byCode("key==") | ||||||
|  *          }) |  *          }) | ||||||
|  */ |  */ | ||||||
| export function mapMangledModule<S extends string>(code: string, mappers: Record<S, FilterFn>): Record<S, any> { | export const mapMangledModule = traceFunction("mapMangledModule", function mapMangledModule<S extends string>(code: string, mappers: Record<S, FilterFn>): Record<S, any> { | ||||||
|     const exports = {} as Record<S, any>; |     const exports = {} as Record<S, any>; | ||||||
| 
 | 
 | ||||||
|     const id = findModuleId(code); |     const id = findModuleId(code); | ||||||
|  | @ -273,7 +274,7 @@ export function mapMangledModule<S extends string>(code: string, mappers: Record | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|     return exports; |     return exports; | ||||||
| } | }); | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Same as {@link mapMangledModule} but lazy |  * Same as {@link mapMangledModule} but lazy | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue