DEV Community

Daniel Neveux
Daniel Neveux

Posted on

Wizar devlog 09 - Reactive transformation

Last week I implemented pure view generation at the end of each step of the SAM loop.
This week I begin to make the view reactive.

For that I needed to implement a transformer which takes an IObservable A and tranform it to an IObservable B.

The transformation it self is reactive and can be used in Autorun or Reaction.

Note that it is also possible to tranform it in non observable object, for example, in a serialization scenario.

Also, it uses internaly a Computed which memoizes the value of the tranformation and optimize the need of computation.

This is the major step to get a reactive view into Ravioli. The other part of the chain being already done with Crafter-React to connect any observable to React.

Here is a small example of the API.

test("transform to observable object", function() {
  const Model = object({
    name: string(),
    inventory: array(object({id: string(), quantity: number(), isEquiped: boolean()}))
  })
  const model = Model.create({
    name: 'fraktar',
    inventory: [{id: 'sword', quantity: 0, isEquiped: false}]
  })

  let test

  const transformModel = createTransformer((m: typeof Model['Type']) => ({
    name: m.name,
    stuff: m.inventory
      .filter(item => item.isEquiped)
      .map(({id}) => ({name: id}))
  }))

  autorun(() => {
    test = transformModel(model)
  })

  expect(test.name).toEqual('fraktar')
  expect(test.stuff.slice()).toEqual([])

  getContext(toInstance(model)).transaction(() => {
    model.inventory[0].isEquiped = true
  })

  expect(test.name).toEqual('fraktar')
  expect(test.stuff.slice().length).toBe(1)
  expect(test.stuff.slice()).toEqual([{name: 'sword'}])
})

Top comments (0)