FabienArcellier / writer-framework

No-code in the front, Python in the back. An open-source framework for creating data apps.
https://streamsync.cloud
Apache License 2.0
0 stars 1 forks source link

trigger a calculated property on mutation #37

Open FabienArcellier opened 6 months ago

FabienArcellier commented 6 months ago

When a state proxy field is modified, a signal is triggered. All functions subscribed to this signal are called with four optional argument the state proxy instance, the property name, previous value and new value.

class MyState(wf.WriterState):
  counter: int
  total: int

def cumulative_sum(state: MyState):
  state.total += state.counter

initial_state = ss.init_state({
    "counter": 0,
    "total": 0
}, schema=MyState)

initial_state.subscribe_mutation('counter', cumulative_sum)

Computed properties use this mechanism to be triggered. It is possible to have a calculated property that depends on another calculated property.

class MyState(wf.WriterState):
  counter: int

  @wf.property('counter')
  def cumulative_sum(self):
    return self.counter

We can depends from many properties

class MyState(wf.WriterState):
  counterA: int
  counterB: int

  @wf.property(['counterA', 'counterB'])
  def cumulative_sum(self):
    return self.counter

Nested calculated property

class MyAppState(wf.State):
  title: str

class MyState(wf.WriterState):
  counter: int
  app: MyAppState

  @wf.property(['counter', 'app.title'])
  def cumulative_sum(self):
    return self.counter
class MyAppState(wf.State):
  title: str
  counter: int

  @wf.property(['title'])
  def count(self):
    self.counter += 1

class MyState(wf.WriterState):
  counter: int
  app: MyAppState

  @wf.property(['counter', 'app.title'])
  def cumulative_sum(self):
    return self.counter

ramedina86 commented 6 months ago

Regarding this

initial_state.subscribe_mutation(MyState.counter, cumulative_sum)

FabienArcellier commented 6 months ago

It doesn't have to be explicitly called when declaring a calculated property, right?

Yes it doesn't have

Why would there be mutations to the initial_state?

It would allow to trigger automatic behavior based on property change at the application level. For example, if a counter change, we call a webhook.