Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into one-event-return
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante committed Nov 17, 2024
2 parents 38142d0 + b58209b commit 8cf586f
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 0 deletions.
34 changes: 34 additions & 0 deletions source/add-listener.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# add-listener

Utility method to add listeners to events and remove them when the signal is aborted.

Currently this **requires** a `signal`. Without a `signal`, you should just use the native `addListener` method as this has no advantages over it.

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

addListener(chrome.tabs.onCreated, (tab) => {
console.log('Hurray, a new tab was created')
}, {signal: AbortSignal.timeout(1000)});
```

> [!NOTE]
> Background workers are unloaded and the status of `signal`s created within them is reset. Dealing with this is outside the responsibility of this library.
## Compatibility

- Any browser

## Permissions

- No special permissions

## Context

- Any context

## Related

- [abort-utils](https://github.com/fregante/abort-utils) - Utility functions to use and combine `AbortSignal` and `AbortController` with Promises.

## [Main page ⏎](../readme.md)
30 changes: 30 additions & 0 deletions source/add-listener.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {
describe, it, vi, expect, expectTypeOf,
} from 'vitest';
import {addListener} from './add-listener.js';

describe('addListener', () => {
it('should remove the listener when the signal is aborted', () => {
const event = {
addListener: vi.fn(),
removeListener: vi.fn(),
};
const listener = vi.fn();
const controller = new AbortController();
addListener(event, listener, {signal: controller.signal});

expect(event.addListener).toHaveBeenCalledWith(listener);

controller.abort();

expect(event.removeListener).toHaveBeenCalledWith(listener);
});

it('should have the correct types', () => {
addListener(chrome.tabs.onMoved, (tabId, tab) => {
expectTypeOf(tabId).toEqualTypeOf<number>();
expectTypeOf(tab).toEqualTypeOf<chrome.tabs.TabMoveInfo>();
}, {signal: AbortSignal.timeout(1000)});
});
});

26 changes: 26 additions & 0 deletions source/add-listener.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
type AnyFunction = (...parameters: any[]) => void;

type RemovableEvent<T = (...arguments_: unknown[]) => unknown> = {
removeListener(callback: T): void;
addListener(callback: T): void;
};

export function addListener<Event extends RemovableEvent<AnyFunction>>(
event: Event,
listener: (...parameters: Parameters<Parameters<Event['addListener']>[0]>) => void,
{
signal,
}: {
signal: AbortSignal;
},
): void {
if (signal?.aborted) {
return;
}

event.addListener(listener);

signal.addEventListener('abort', () => {
event.removeListener(listener);
}, {once: true});
}
1 change: 1 addition & 0 deletions source/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './on-context-invalidated.js';
export * from './on-extension-start.js';
export * from './one-event.js';
export * from './add-listener.js';
2 changes: 2 additions & 0 deletions source/on-context-invalidated.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ fetch('/api', {signal: onContextInvalidated.signal})
- any context

Some contexts like the background page/worker and standalone tabs will be closed by the browser automatically so the event doesn't apply there.

## [Main page ⏎](../readme.md)
2 changes: 2 additions & 0 deletions source/on-extension-start.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ onExtensionStart.addListener(listener);
- background worker
- background page
- event page (not in Chrome)

## [Main page ⏎](../readme.md)
2 changes: 2 additions & 0 deletions source/one-event.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,5 @@ Note that the signal is aborted, the promise is resolved with `undefined` rather
## Related
- [one-event](https://github.com/fregante/one-event) - The same thing, but for regular browser events.
## [Main page ⏎](../readme.md)

0 comments on commit 8cf586f

Please sign in to comment.