Skip to content

feat!: use alien-signals for reactivity#50

Open
littensy wants to merge 143 commits intomainfrom
alien-signals
Open

feat!: use alien-signals for reactivity#50
littensy wants to merge 143 commits intomainfrom
alien-signals

Conversation

@littensy
Copy link
Copy Markdown
Owner

@littensy littensy commented May 4, 2025

Rewrite Charm using the alien-signals reactive algorithm.

Why?

Adopting alien-signals brings benefits and guarantees like predictable effect ordering, nested effect cleanup, and more efficient computed() memoization, all without a significant compromise to performance. Building Charm on this signal algorithm should improve Charm's overall efficiency and reliability.

What's New?

  • signal(initialValue): create a state container with a separate getter and setter function
  • effectScope(fn): cleans up a group of effects and subscriptions
  • onCleanup(fn): runs fn once the current effect/scope reruns or gets disposed
  • listen(selector, listener): similar to subscribe(), but runs once immediately
  • reactive(object): makes a mutable table deeply reactive
  • untracked(fn): similar to peek(), but doesn't track effects created inside
  • trigger(getter): manually triggers an update in one or more signals
  • Optimized mapped() to cache values and avoid unnecessary updates
  • Optimized computed() to use lazy evaluation instead of eager updates

Breaking Changes

  • peek() was changed to untracked() for parity with other state managers
  • Nested effects automatically dispose when the parent effect reruns or the scope is disposed
    • This applies to observe(), which wraps observer calls in an effect scope.
    • Subscriptions are automatically cleaned up since they are also effects, but the listener callback runs in untracked(), so inner effects created in the listener are not tracked.
    • Use untracked() or create a detached effect scope if you need to run code outside the parent effect's lifecycle.
  • Effects and subscriptions created inside observe() now automatically dispose when the item is removed

Notes

  • In Roblox Studio, the following flags will be enabled by default:
    • flags.strict: Formerly _G.__DEV__, this bans unsafe yielding and enables additional checks in Charm Sync.
    • flags.frozen: Deep-freeze all atom values to enforce immutable state updates.

@littensy littensy added the enhancement New feature or request label May 4, 2025
@littensy littensy marked this pull request as draft May 5, 2025 08:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

2 participants