adamhaile / S

S.js - Simple, Clean, Fast Reactive Programming in Javascript

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

(Trying to get) subclocks to implement top-level S .data () synchronity

irisjae opened this issue · comments

Any way this is possible? I know I can do something like this, but I'm envisioning a logger with multiple disparate sources. Why is the exception being thrown anyway, I can't see how can log receive multiple values in the same time instant anyway.

Ah-hah, that's a bug in S.subclock(). Specifically, when creating a subclock from top level, if the code running in the subclock sets a data signal in an outer clock, that outer data signal is being marked dirty but never scheduled for propagation. When you later set A() again, S finds that log() is already still dirty and so thinks you've tried to set it twice. This only happens when creating a subclock from top level: any other context, the subclock is running as part of its parent's update, so the parent update cycle picks up the change and propagates it. I may need to add a special case to 'unwind' a subclock for this.

If you move log() into the subclock, you won't get the error. But I'm not sure that accomplishes what you're trying to do. Is the goal to have multiple signals that could feed into a single log() signal? The code you've written doesn't really take advantage of subclocks (beyond finding an error :)). Since all the signals it reads are from the outer clock, it will never have a follow-on update.

Pushed a fix and bumped npm version to 0.4.8.

Alright, the updated runkit runs now! But you're right, it doesn't preserve the synchronity. Do you think it's possible to synchrously pipe the value of one top level data into another top level data?

The piped-into data needs to be in the subclock for it to appear synchronous to top-level code.

It's not possible to pipe into a top-level data signal synchronously b/c that would actually break synchronicity :). It's not just computations that belong to a clock, it's data signals too. The top-level data signal can't update faster than its clock. Or to put it another way, if you could, how could we guarantee that no computations read the data signal before it got its new value?

To be a bit figurative, top level code looks into a subclock and sees a peaceful world: all change has been brought to completion and the subclock is at rest. Subclocks look up to top level code and see a frozen sky: immutable while they update.

So subclocks can set top level data signals, but that won't take effect until the top level itself updates. It's no different, in that case, than a top level computation updating the data signal.

@adamhaile I guess the thing I actually wanted to achieve when I asked this question was how to make a computation not be recomputed, something akin to S(() => <code>) in the same way S.value is to S.data. Imagine we have a single S.data (or S.value) store the entire state of an app, and have separate computations extract various parts of the app state to render, wheras user actions change these separate parts of the state in the big master state. Wouldn't it be useful to not always rerender a component, if the root change in state had not actually changed the component's part of state? What do you think?