Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oneEvent - Return arguments of listener call #30

Merged
merged 5 commits into from
Nov 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading