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

Refactor core #34

Merged
merged 6 commits into from Jul 28, 2022
Merged

Refactor core #34

merged 6 commits into from Jul 28, 2022

Conversation

wycats
Copy link
Member

@wycats wycats commented Jul 27, 2022

This is a somewhat substantial refactor of the core of Starbeam to address some timing issues that came up when trying to do more elaborate demos. It also culls a decent amount of development cruft, and consolidates duplicate concepts that arose from codebase iteration.

Some big-picture changes:

  • The original reason for this work was to clarify the timing of various operations. For example, Cells are now reliably initialized with the timestamp at the point of initialization. This means that when a brand new cell is added to a frame, the frame's timestamp will be at least as current as the time the cell was created. While these timing concerns tended to work out before, they were not well specified and were the source of bugs in the core composition that were tricky to track down or address.
  • In addition, the core concepts needed to describe reactive composition were consolidated into @starbeam/timeline. This made it possible to write unit-style tests against @starbeam/timeline that more directly assert low-level details. Along the same lines, this PR makes it easy to implement core interfaces (such as ReactiveInternals) with simple POJOs. Previously, the interfaces were defined in @starbeam/timeline, but they were annoying to implement, and the codebase practically assumed that you would use concrete implementations provided by @starbeam/core.
  • These changes consolidated most of the composition in the codebase around ReactiveProtocol. Previously, some composition was described in terms of ReactiveProtocol, but there were many APIs that used Reactive<T> or ReactiveInternals instead. This PR isn't an exhaustive migration to ReactiveProtocol, and follow-up PRs will finish the job.
  • As part of that change, this PR eliminates the .current property on Reactive<T> in favor of a read() method. That change simplifies code that composes over Reactive<T>, and both Cell<T> and FormulaFn<T> still have .current properties. I expect to do some follow-up work to make sure that the .current convenience is available when using any of the high-level APIs.
  • Formulas, PolledFormulas, and Resources are significantly simplified to take advantage of the clearer architecture.
  • The Setup concept, which makes it possible to have auto-validating lifecycle hooks, was also significantly simplified. Setup was a recently added API, and because it's designed to deterministically perform setup and cleanup, the exact timing semantics was much less forgiving. Building Setup on the rigorously defined timing semantics of @starbeam/timeline addressed all of the open issues I was tracking.
  • In this PR, I renamed Formula to FormulaFn, and repurposed the name Formula for a lower-level API that makes it possible to validate the formula without recomputing it. This previously existed as FormulaState and direct invocations of TIMELINE.evaluateFormula, but both of those APIs were too cumbersome and caveated for third-party abstraction builders. The new Formula API is intended to evolve into a fully public API that is used by power users. That said, I may switch the naming back to Formula and FormulaSomethingElse before 0.6.
  • The React APIs were refreshed to use the new APIs from @starbeam/timeline and @starbeam/core, fixing the open problems I was tracking directly.
  • The @starbeamx packages were refreshed to use the new APIs.
  • The demos were updated to use the new APIs.
  • The log-style debugging APIs (the APIs to get a reactive value's description, and print its dependencies as a tree) were refreshed to be based on ReactiveProtocol and are working.
  • The in-progress preact-based devtools (@starbeamx/devtools) were refreshed to fix type error and lint errors, but I have not tested them yet and don't expect them to work yet. A follow-up PR will get them working again (at least as well as they were working before).

Removed

  • DOMResource, which was an in-progress API based on resources that had layout and idle lifecycle events. I plan to bring something like this back, but base it more closely on normal resources (previously, DOMResource duplicated quite a bit of functionality for no good reason).
  • A number of APIs that duplicated functionality in TIMELINE.on.change, such as TIMELINE.render, Pollable, Pollables, Renderables, etc.
  • The queuing/async functionality related to those APIs. Long story short: TIMELINE.on.change now fires synchronously, which allows renderers to use their framework's specific timing behavior. It is now illegal to read from cells or write to cells in an .on.change handler. Instead, renderers should do the minimum possible to cause their framework to re-render the component (and therefore cause the reactive value to be polled). For example, the React renderer simply notifies React (using a useState variable). This operation simply tells React to enqueue a task that renders the component (if one was not already enqueued), and does not read or write from any Starbeam cells.

Probable Regression in Description Threading and Dev-Mode Assertions

This change affected quite a bit of code that threaded descriptions through various abstractions (and tagging the description with the correct stack). It also changed a lot of the fundamental code involved in the untracked consumption error in #25.

These are all temporary regressions that will be addressed immediately in follow-up PRs.

The Timing

@wycats
Copy link
Member Author

wycats commented Jul 27, 2022

The very long PR description above is not exhaustive and probably misses important details.

Please ask away if you have questions. I also plan to update the new code in @starbeam/timeline with inline documentation in the near future.

@wycats wycats merged commit bd40215 into starbeamjs:main Jul 28, 2022
@wycats wycats deleted the refactor-core branch July 28, 2022 17:32
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

Successfully merging this pull request may close these issues.

None yet

1 participant