Skip to content

Commit

Permalink
feat: added a signal for unsubscribing on abort
Browse files Browse the repository at this point in the history
  • Loading branch information
Agnaev committed Dec 14, 2024
1 parent 6b41670 commit 08f357d
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 3 deletions.
30 changes: 27 additions & 3 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,23 @@ export type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<
EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>
>;

export type SubscribeParams = {
signal: AbortSignal
}

export interface Emitter<Events extends Record<EventType, unknown>> {
all: EventHandlerMap<Events>;

on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
on(type: '*', handler: WildcardHandler<Events>): void;
on<Key extends keyof Events>(
type: Key,
handler: Handler<Events[Key]>,
params?: Partial<SubscribeParams>
): void;
on(
type: '*',
handler: WildcardHandler<Events>,
params?: Partial<SubscribeParams>
): void;

off<Key extends keyof Events>(
type: Key,
Expand Down Expand Up @@ -63,13 +75,25 @@ export default function mitt<Events extends Record<EventType, unknown>>(
* @param {Function} handler Function to call in response to given event
* @memberOf mitt
*/
on<Key extends keyof Events>(type: Key, handler: GenericEventHandler) {
on<Key extends keyof Events>(
type: Key,
handler: GenericEventHandler,
params?: Partial<SubscribeParams>,
) {
if (params?.signal?.aborted) {
return;
}

const handlers: Array<GenericEventHandler> | undefined = all!.get(type);
if (handlers) {
handlers.push(handler);
} else {
all!.set(type, [handler] as EventHandlerList<Events[keyof Events]>);
}

params?.signal?.addEventListener('abort', () => {
this.off<Key>(type, handler as Handler<Events[keyof Events]>);
});
},

/**
Expand Down
37 changes: 37 additions & 0 deletions test/index_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,43 @@ describe('mitt#', () => {
inst.on('foo', foo);
expect(events.get('foo')).to.deep.equal([foo, foo]);
});

it('should unsubscribe when signal aborted', () => {
const foo = spy();
const abortController = new AbortController();

inst.on(
'foo',
foo,
{ signal: abortController.signal }
);
inst.emit('foo');

abortController.abort();

inst.emit('foo');

expect(foo).to.have.been.callCount(1);
});

it('should make multiple unsubscribe when aborted', () => {
const foo = spy();
const bar = spy();
const abortController = new AbortController();

inst.on('foo', foo, { signal: abortController.signal });
inst.on('bar', bar, { signal: abortController.signal });
inst.emit('foo');
inst.emit('bar');

abortController.abort();

inst.emit('foo');
inst.emit('bar');

expect(foo).to.have.been.callCount(1);
expect(bar).to.have.been.callCount(1);
});
});

describe('off()', () => {
Expand Down

0 comments on commit 08f357d

Please sign in to comment.