MCPcopy Create free account
hub / github.com/PaperDebugger/paperdebugger / makeFunction

Function makeFunction

webapp/_webapp/src/intermediate.ts:80–149  ·  view source on GitHub ↗

* Create a function that communicates via window events. * * - In ISOLATED world: registers event handler that calls chrome.runtime.sendMessage * - In any world: returns a function that dispatches events and waits for response * * This allows MAIN world to call functions that require chrome.run

(handlerName: string, opts?: MakeFunctionOpts)

Source from the content-addressed store, hash-verified

78 * by sending events to ISOLATED world.
79 */
80function makeFunction<A, T>(handlerName: string, opts?: MakeFunctionOpts): (args: A) => Promise<T> {
81 const reqEvtName = `paperdebugger:req:${handlerName}`;
82 const resEvtName = `paperdebugger:res:${handlerName}`;
83 const errEvtName = `paperdebugger:err:${handlerName}`;
84
85 // Only register the event handler in ISOLATED world (where chrome.runtime is available)
86 if (isIsolatedWorld) {
87 const eventHandler = (evt: Event) => {
88 const browserAPI = getBrowserAPI();
89 const customEvt = evt as CustomEvent;
90 const { seq, req } = customEvt.detail;
91 if (!seq) return;
92 if (!browserAPI?.runtime?.sendMessage) return;
93 browserAPI.runtime
94 .sendMessage({
95 action: handlerName,
96 args: req,
97 })
98 .then((res: { error?: string }) => {
99 if (res.error) {
100 window.dispatchEvent(
101 new CustomEvent(`${errEvtName}/${seq}`, {
102 detail: { seq, err: res.error },
103 }),
104 );
105 } else {
106 window.dispatchEvent(new CustomEvent(`${resEvtName}/${seq}`, { detail: { seq, res } }));
107 }
108 })
109 .catch((err: { error?: string }) => {
110 window.dispatchEvent(new CustomEvent(`${errEvtName}/${seq}`, { detail: { seq, err } }));
111 });
112 };
113 window.addEventListener(reqEvtName, eventHandler);
114 }
115
116 // The callable function - works in both MAIN and ISOLATED world
117 // Dispatches event and waits for response from ISOLATED world's handler
118 const fn = (args: A): Promise<T> => {
119 const seq = uuidv4();
120 window.dispatchEvent(new CustomEvent(reqEvtName, { detail: { seq, req: args } }));
121 return new Promise((resolve, reject) => {
122 function resListener(evt: Event): void {
123 const customEvt = evt as CustomEvent;
124 const { res } = customEvt.detail;
125 cleanup();
126 resolve(res);
127 }
128 function errListener(evt: Event): void {
129 const customEvt = evt as CustomEvent;
130 const { err } = customEvt.detail;
131 cleanup();
132 reject(err);
133 }
134 function cleanup(): void {
135 window.removeEventListener(`${resEvtName}/${seq}`, resListener);
136 window.removeEventListener(`${errEvtName}/${seq}`, errListener);
137 }

Callers 1

intermediate.tsFile · 0.85

Calls

no outgoing calls

Tested by

no test coverage detected