UNPKG

@steambrew/client

Version:
185 lines (157 loc) 5 kB
/** Returnable IPC types */ type IPC_types = string | number | boolean; /* Global Millennium API for developers. */ type Millennium = { /** * Call a method on the backend * @deprecated Use `callable` instead. * Example usage: * ```typescript * // before * const result = await Millennium.callServerMethod('methodName', { arg1: 'value' }); * // after * const method = callable<[{ arg1: string }]>("methodName"); * * const result1 = await method({ arg1: 'value1' }); * const result2 = await method({ arg1: 'value2' }); * ``` */ callServerMethod: (methodName: string, kwargs?: object) => Promise<any>; findElement: (privateDocument: Document, querySelector: string, timeOut?: number) => Promise<NodeListOf<Element>>; exposeObj?: <T extends object>(obj: T) => any; AddWindowCreateHook?: (callback: (context: object) => void) => void; }; /** * Make reusable IPC call declarations * * frontend: * ```typescript * const method = callable<[{ arg1: string }]>("methodName"); // declare the method * method({ arg1: 'value' }); // call the method * ``` * * backend: * ```python * def methodName(arg1: str): * pass * ``` */ declare const callable: <Args extends any[] = [], T = IPC_types>(route: string) => (...args: Args) => Promise<T>; const m_private_context: any = undefined; export const pluginSelf = m_private_context; declare global { interface Window { Millennium: Millennium; MILLENNIUM_CHROME_DEV_TOOLS_PROTOCOL_DO_NOT_USE_OR_OVERRIDE_ONMESSAGE: any; CHROME_DEV_TOOLS_PROTOCOL_API_BINDING: MillenniumChromeDevToolsProtocol; } } declare const BindPluginSettings: () => any; interface FileInfo { content: string; filePath: string; fileName: string; } type BufferEncoding = 'ascii' | 'utf8' | 'utf-8' | 'utf16le' | 'ucs2' | 'ucs-2' | 'base64' | 'latin1' | 'binary' | 'hex'; interface SingleFileExprProps { basePath?: string; encoding?: BufferEncoding; } interface MultiFileExprProps { basePath?: string; include?: string; // A regex pattern to include files encoding?: BufferEncoding; } /** * Create a compile time filesystem expression. * This function will evaluate a file path at compile time, and embed a files content statically into the bundle. */ declare const constSysfsExpr: { (fileName: string, props: SingleFileExprProps): FileInfo; (props: MultiFileExprProps): FileInfo[]; }; interface CDPMessage { id?: number; method: string; params?: Record<string, any>; sessionId?: string; // Optional session ID for targeted commands result?: any; error?: { message: string; code: number; }; } class MillenniumChromeDevToolsProtocol { devTools: any; currentId: number; pendingRequests: Map<number, { resolve: (value: any) => void; reject: (reason?: any) => void }>; constructor() { this.devTools = window.MILLENNIUM_CHROME_DEV_TOOLS_PROTOCOL_DO_NOT_USE_OR_OVERRIDE_ONMESSAGE; this.currentId = 0; this.pendingRequests = new Map(); // Override the onmessage callback to handle responses this.devTools.onmessage = (message: any) => { this.handleMessage(message); }; } handleMessage(message: any) { const data = typeof message === 'string' ? JSON.parse(message) : message; // Check if this is a response to one of our requests if (data.id !== undefined && this.pendingRequests.has(data.id)) { const pending = this.pendingRequests.get(data.id); this.pendingRequests.delete(data.id); if (pending) { const { resolve, reject } = pending; if (data.error) { reject(new Error(`CDP Error: ${data.error.message} (${data.error.code})`)); } else { resolve(data.result); } } } } send(method: string, params: any = {}, sessionId?: string) { return new Promise((resolve, reject) => { const id = this.currentId++; // Store the promise resolvers this.pendingRequests.set(id, { resolve, reject }); // Prepare the message const message: CDPMessage = { id: id, method: method, }; // Only add params if they're provided and not empty if (params && Object.keys(params).length > 0) { message.params = params; } // If a sessionId is provided, include it in the message if (sessionId) { message.sessionId = sessionId; } // Send the message try { this.devTools.send(JSON.stringify(message)); } catch (error) { // Clean up if send fails this.pendingRequests.delete(id); reject(error); } }); } // Helper method to send without waiting for response (fire and forget) sendNoResponse(method: string, params = {}) { const message: CDPMessage = { id: this.currentId++, method: method, }; if (params && Object.keys(params).length > 0) { message.params = params; } this.devTools.send(JSON.stringify(message)); } } const ChromeDevToolsProtocol: MillenniumChromeDevToolsProtocol = new MillenniumChromeDevToolsProtocol(); const Millennium: Millennium = window.Millennium; export { ChromeDevToolsProtocol, Millennium, callable, BindPluginSettings, constSysfsExpr };