deanrad/polyrhythm

Create a single-expression version of query.toPromise() and trigger();

deanrad opened this issue · 0 comments

Currently, per Command-Query Responsibility Segregation, to trigger an event and listen for a result in a subsequent event requires code like this:

const result = query('api/results').toPromise();
trigger('api/search', { q: 'query' });
result.then(/* do something with the response */);

// Presumes a listener such as this which maps api/search events to ajax/results
// in a serialized fashion.
on('api/search,({ payload }) => doAjax(payload), {
  trigger: { next: 'api/result' },
  mode: 'serial'
})

Proposed:

const resultPromise = trigger('api/search', { q: 'query' }, 'api/results');
resultPromise.then(/* do something with the response */);

Pros:

  • Simplifies a common case
  • Provides a single promise-returning expression ala fetch

Cons:

  • TypeScript will freak out (you return an Event OR a Promise from trigger?)

The reason the event was returned from trigger was so the caller could have the effects of any filters that may have modified it. If we use the third argument to provide a different return value than the event, then the listener providing the result could copy any relevant fields of the triggered event to the response. I'd like to say to hell with TypeScript not liking it if its well tested, but perhaps let's evaluate the actual DX and impact on tests, and decide from there.