Remove cold derivation reads
Prior to this commit, the first render of every `useDerivation()` resulted in a cold read of its inner derivation. Cold reads are predictably slow. The reason we'd run cold reads was to comply with react's rule of not running side-effects during render. (Turning a derivation hot is _technically_ a side-effect).
However, now that users are animating scenes with hundreds of objects in the same sequence, the lag started to be noticable.
This commit changes `useDerivation()` so that it turns its derivation hot before rendering them.
Freshen derivations before render
Previously in order to avoid the zombie child problem (https://kaihao.dev/posts/stale-props-and-zombie-children-in-redux) we deferred freshening the derivations to the render phase of components. This meant that if a derivation's dependencies changed, `useDerivation()` would schedule a re-render, regardless of whether that change actually affected the derivation's value. Here is a contrived example:
```
const num = new Box(1)
const isPositiveD = prism(() => num.derivation.getValue() >= 0)
const Comp = () => {
return <div>{useDerivation(isPositiveD)}</div>
}
num.set(2) // would cause Comp to re-render- even though 1 is still a positive number
```
We now avoid this problem by freshening the derivation (i.e. calling `der.getValue()`) inside `runQueue()`, and then only causing a re-render if the derivation's value is actually changed.
This still avoids the zombie-child problem because `runQueue` reads the derivations in-order of their position in the mounting tree.
On the off-chance that one of them still turns out to be a zombile child, `runQueue` will defer that particular `useDerivation()` to be read inside a normal react render phase.
This implements some basic infra for testing Theatre.js with popular setups such as npm/yarn/pnpm, webpack/vite/parcel, js/ts, etc.
So far, the only existing setup has been with create-react-app. Will add more in the future.
Co-authored-by: Fülöp <fulopkovacs@users.noreply.github.com>
Co-authored-by: Aria Minaei <aria.minaei@gmail.com>