Skip to content

Commit

Permalink
oneEvent - Return arguments of listener call (#30)
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante authored Nov 17, 2024
1 parent b58209b commit e7e1059
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 12 deletions.
10 changes: 4 additions & 6 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,15 @@ Or download the [standalone bundle](https://bundle.fregante.com/?pkg=webext-even

This package exports various utilities, just import what you need.

- [onContextInvalidated](./source/on-context-invalidated.md)
- [onExtensionStart](./source/on-extension-start.md)
- [oneEvent](./source/one-event.md)
- [onContextInvalidated](./source/on-context-invalidated.md) - Fires in content scripts when the extension is disabled, updated or reloaded.
- [onExtensionStart](./source/on-extension-start.md) - Fires when the extension starts or is enabled. This is what yuou thought `chrome.runtime.onStartup` was for.
- [oneEvent](./source/one-event.md) - Creates a promise that resolves when an event is received.
- [addListener](./source/add-listener.md) - Like `.addEventListener` but with a `signal` to remove the listener.

## Related

- [webext-tools](https://github.com/fregante/webext-tools) - Utility functions for Web Extensions.
- [webext-content-scripts](https://github.com/fregante/webext-content-scripts) - Utility functions to inject content scripts in WebExtensions.
- [webext-detect](https://github.com/fregante/webext-detect) - Detects where the current browser extension code is being run.
- [webext-base-css](https://github.com/fregante/webext-base-css) - Extremely minimal stylesheet/setup for Web Extensions’ options pages (also dark mode)
- [webext-options-sync](https://github.com/fregante/webext-options-sync) - Helps you manage and autosave your extension's options.
- [More…](https://github.com/fregante/webext-fun)

## License
Expand Down
13 changes: 13 additions & 0 deletions source/one-event.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,17 @@ await oneEvent(chrome.tabs.onCreated);
console.log('Hurray, a new tab was created')
```

It will return the arguments of the event:

```js
import {oneEvent} from 'webext-events';

const [message, sender] = await oneEvent(chrome.runtime.onMessage);
console.log('Message received:', message);
console.log('Message sender:', sender);
```


It also supports filtering:

```js
Expand Down Expand Up @@ -42,6 +53,8 @@ if (timeout.aborted) {
}
```
Note that the signal is aborted, the promise is resolved with `undefined` rather than with the event arguments array.
## Compatibility
- Any browser
Expand Down
12 changes: 9 additions & 3 deletions source/one-event.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,17 @@ describe('oneEvent', () => {
});

it('it should resolve original event\'s parameters', () => {
void oneEvent(chrome.tabs.onMoved, {
const onMoved = oneEvent(chrome.tabs.onMoved, {
filter(tabId, moveInfo) {
expectTypeOf(tabId).toEqualTypeOf<number>();
expectTypeOf(moveInfo).toEqualTypeOf<chrome.tabs.TabMoveInfo>();
return true;
},
});

void oneEvent(chrome.runtime.onMessage, {
expectTypeOf(onMoved).toEqualTypeOf<Promise<[number, chrome.tabs.TabMoveInfo] | void>>();

const onMessage = oneEvent(chrome.runtime.onMessage, {
filter(message, sender, sendResponse) {
expectTypeOf(message).toEqualTypeOf<any>();
expectTypeOf(sender).toEqualTypeOf<Runtime.MessageSender>();
Expand All @@ -67,11 +69,15 @@ describe('oneEvent', () => {
},
});

void oneEvent(chrome.cookies.onChanged, {
expectTypeOf(onMessage).toEqualTypeOf<Promise<[any, Runtime.MessageSender, (response?: any) => void] | void>>();

const onChanged = oneEvent(chrome.cookies.onChanged, {
filter(changeInfo) {
expectTypeOf(changeInfo).toEqualTypeOf<Cookies.CookieChangeInfo>();
return true;
},
});

expectTypeOf(onChanged).toEqualTypeOf<Promise<[Cookies.CookieChangeInfo] | void>>();
});
});
6 changes: 3 additions & 3 deletions source/one-event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,16 @@ export async function oneEvent<Event extends RemovableEvent<AnyFunction>>(
filter?: (...parameters: EventParameters<Event>) => boolean;
signal?: AbortSignal;
} = {},
): Promise<void> {
): Promise<EventParameters<Event> | void> {
if (signal?.aborted) {
return;
}

await new Promise<void>(resolve => {
return new Promise<EventParameters<Event> | void>(resolve => {
// TODO: VoidFunction should not be necessary, it's equivalent to using "any"
const listener: VoidFunction = (...parameters: EventParameters<Event>) => {
if (!filter || filter(...parameters)) {
resolve();
resolve(parameters);
event.removeListener(listener);
}
};
Expand Down

0 comments on commit e7e1059

Please sign in to comment.