Skip to content

Commit

Permalink
Merge pull request #25 from adonisjs/feat/listen-if
Browse files Browse the repository at this point in the history
feat(emitter): add listenIf method
  • Loading branch information
thetutlage authored Aug 31, 2024
2 parents edce5c7 + 8a729b4 commit 26d0153
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
26 changes: 26 additions & 0 deletions src/emitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,32 @@ export class Emitter<EventsList extends Record<string | symbol | number, any>>
return () => this.off(event, listener)
}

/**
* Listen for an event depending on a condition
*/
listenIf<Event extends Constructor, ListenerClass extends Constructor>(
condition: boolean | (() => boolean),
event: Event,
listener: Listener<InstanceType<Event>, ListenerClass>
): UnsubscribeFunction
listenIf<Name extends keyof EventsList, ListenerClass extends Constructor>(
condition: boolean | (() => boolean),
event: Name,
listener: Listener<EventsList[Name], ListenerClass>
): UnsubscribeFunction
listenIf<Event extends AllowedEventTypes>(
condition: boolean | (() => boolean),
event: Event,
listener: Listener<any, Constructor>
): UnsubscribeFunction {
if (!condition || (typeof condition === 'function' && !condition())) {
return () => {}
}

// @ts-expect-error - TypeScript does not like overloading
return this.on(event, listener)
}

/**
* Listen for an event only once
*/
Expand Down
20 changes: 20 additions & 0 deletions tests/emitter/listen.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,26 @@ test.group('Emitter | listen', () => {
assert.equal(emitter.eventsListeners.get('new:user')?.size, 1)
})

test('listen for an event depending on a condition', async ({ assert }) => {
const stack: any[] = []

const app = new Application(BASE_URL, { environment: 'web' })
const emitter = new Emitter(app)

emitter.listenIf(true, 'new:user', (data) => {
stack.push(data)
})

emitter.listenIf(false, 'new:user2', (data) => {
stack.push(data)
})

await emitter.emit('new:user', { id: 1 })
await emitter.emit('new:user2', { id: 1 })
assert.deepEqual(stack, [{ id: 1 }])
assert.equal(emitter.eventsListeners.get('new:user')?.size, 1)
})

test('do not register multiple listeners when callback is the same', async ({ assert }) => {
const stack: any[] = []

Expand Down

0 comments on commit 26d0153

Please sign in to comment.