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

compose action? #15

Open
unional opened this issue Nov 9, 2017 · 2 comments
Open

compose action? #15

unional opened this issue Nov 9, 2017 · 2 comments

Comments

@unional
Copy link
Owner

unional commented Nov 9, 2017

Currently, it is not possible to compose actions.
The input type emitter and the pass in type emit does not match.
Also, the action needs to be able to return value, e.g. a Return generic may be needed.

To do this, may need to go back to redux or flux structure, where there is a separate dispatch function from the store.

In this case, it means the emitter needs to be able to produce a detached emit method, scoped with the right Payload dynamically, per composition down the chain.

const add = createEventAction<{ a: number, b: number }, { a: number, b: number, result: number}>('add', ({ a, b }) => emit => {
  emit({ a, b, result: a + b })
  return a + b
})

const multiply = createEventAction<{ a: number, b: number }, { a: number, b: number, result: number }>('multiply', ({ a, b }) => emit => {
  let total = 0
  for (let i = 0; i < a, i ++) {
    total += add(emitter, { 0, b }, undefined) // missing emitter in this context
  }
  emit({ a, b, result: total })
  return total
})

const emitter = new Emitter()
multiply(emitter, { a: 3, b: 3 }, undefined) // returns 9

If we try to do the same without EventAction, we need to work on the Event.type without scoping support and we missed the auto handling of isError.

function multiply({ emitter }, a, b) {
  let total = 0
  for (let i = 0; i < a, i++)
    total += add({ emitter }, 0, b)
  emitter.emit({ type: 'multiply', payload: { a, b, result: total }, meta: undefined, isError: false })
  return total
})

function add({ emitter }, a, b) {
  emitter.emit({ type: 'add', payload: { a, b, result: a + b }, meta: undefined, isError: false })
  return a + b
}
@unional
Copy link
Owner Author

unional commented Nov 9, 2017

One idea is to make the emitter.emit binded to begin with, and pass in emit only:

const add = createEventAction<{ a: number, b: number }, { a: number, b: number, result: number}>('add', ({ a, b }) => emit => {
  emit({ a, b, result: a + b })
  return a + b
})

const multiply = createEventAction<{ a: number, b: number }, { a: number, b: number, result: number }>('multiply', ({ a, b }) => emit => {
  let total = 0
  for (let i = 0; i < a, i ++) {
    total += add(emit, { 0, b }, undefined)
  }
  emit({ a, b, result: total })
  return total
})

const emitter = new Emitter()
multiply(emitter.emit, { a: 3, b: 3 }, undefined) // returns 9

@unional
Copy link
Owner Author

unional commented Nov 9, 2017

Input and Return should be able to be inferred.
Payload and Meta cannot.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant