({
timeout = 10_000,
addEventListener,
removeEventListener
}: {
timeout?: number;
addEventListener: (event: string, handler: Function) => void;
removeEventListener: (predicate: (listener: any) => boolean) => void;
})
| 101 | }): { |
| 102 | responseId: string; |
| 103 | promise: Promise<T>; |
| 104 | controller: AbortController; |
| 105 | } { |
| 106 | const responseId = generateId('res'); |
| 107 | const controller = new AbortController(); |
| 108 | const signal = controller.signal; |
| 109 | |
| 110 | // Create a promise that resolves when we get a matching Custom event |
| 111 | const promise = new Promise<T>((resolve, reject) => { |
| 112 | // Set up temporary event listener for Custom events |
| 113 | const handleCustomEvent = (eventData: any) => { |
| 114 | const data = eventData?.data; |
| 115 | // Check if this is our response by matching responseId |
| 116 | if (data?.eventName === responseId) { |
| 117 | controller.abort(); // Clean up |
| 118 | resolve(data?.args as T); |
| 119 | } |
| 120 | }; |
| 121 | |
| 122 | // Add listener with cleanup |
| 123 | addEventListener('Custom.Event', handleCustomEvent); |
| 124 | |
| 125 | // Set up timeout |
| 126 | const timeoutId = setTimeout(() => { |
| 127 | controller.abort(); |
| 128 | reject(new Error('Timed out waiting for Custom Event')); |
| 129 | }, timeout); |
| 130 | |
| 131 | // Cleanup function |
| 132 | signal.addEventListener( |
| 133 | 'abort', |
| 134 | () => { |
| 135 | clearTimeout(timeoutId); |
| 136 | // Remove the event listener |
| 137 | removeEventListener( |
| 138 | (listener) => |
| 139 | listener.events?.includes('Custom.Event') && listener.callback === handleCustomEvent, |
| 140 | ); |
| 141 | }, |
| 142 | { once: true }, |
| 143 | ); |
| 144 | }); |
| 145 | |
| 146 | return { responseId, promise, controller }; |
| 147 | } |
no test coverage detected