mirror of
https://github.com/littensy/charm.git
synced 2026-10-21 11:44:08 +00:00
docs: add migration tips
This commit is contained in:
parent
90399a816f
commit
3d4ce41d20
1 changed files with 56 additions and 2 deletions
58
README.md
58
README.md
|
|
@ -58,6 +58,7 @@
|
|||
- [Server API](#config)
|
||||
- [Client API](#clientaddsignalssetters)
|
||||
- [Sync Caveats](#sync-caveats)
|
||||
- [Migration](#migration)
|
||||
- [Examples](#examples)
|
||||
|
||||
</details>
|
||||
|
|
@ -165,7 +166,7 @@ setCounter(function(count)
|
|||
end)
|
||||
```
|
||||
|
||||
Accessing the signal's value in an effect or computed signal will subscribe to it as a dependency. Changing the value will immediately update every effect and computed signal that depends signal, ensuring every part of your state is correct and up-to-date.
|
||||
Accessing the signal's value in an effect or computed signal will subscribe to it as a dependency. Changing the value will immediately notify every effect and computed signal that depends on said signal, ensuring all of your state is correct and up-to-date.
|
||||
|
||||
You can also pass a custom equality function to only update the signal if the new value is _not_ equal to the current value:
|
||||
|
||||
|
|
@ -180,7 +181,7 @@ setMax(-1) --> 2
|
|||
```
|
||||
|
||||
> [!NOTE]
|
||||
> Looking for atoms? You can still use `atom()` to create a signal with a combined getter and setter. To use signals for APIs that require atoms, use `signalToAtom()`.
|
||||
> Looking for atoms? You can still use [`atom()`](#atominitialvalue-equals) to create a signal with a combined getter and setter.
|
||||
|
||||
---
|
||||
|
||||
|
|
@ -794,6 +795,59 @@ This means nilable values can be represented as `None`, and code working with up
|
|||
|
||||
---
|
||||
|
||||
## Migration
|
||||
|
||||
Charm v0.11 introduces _a lot_ of breaking changes, so below are some tips that might help you migrate from an older version.
|
||||
|
||||
<details>
|
||||
<summary><b>Terminology changes</b></summary>
|
||||
|
||||
- Signal: A state container with one function to get the state, and another to update it
|
||||
- Atom: A signal with the getter and setter combined into one function
|
||||
- Effect: Main way to react to state changes
|
||||
- `subscribe(getter, callback)`: Creates an effect that only subscribes to signals accessed in the getter
|
||||
|
||||
</details>
|
||||
|
||||
<br/>
|
||||
|
||||
**What to look out for:**
|
||||
|
||||
1. Address all of the type errors introduced in your project after updating Charm. Most of them are caused by changes like:
|
||||
- `batch()` was renamed to `batched()`
|
||||
- The second arguments of `atom()` and `computed()` changed from an `options` table to an equality function
|
||||
- Removed the cleanup argument in effect callbacks (`effect(function(cleanup) end)`)
|
||||
|
||||
2. If you use Charm Sync, you'll have to rewrite a lot of your sync code. Fortunately, most of the changes should make your code _less_ complicated:
|
||||
- You can now sync signals per-client, including computed signals. You shouldn't have to modify sync payloads to filter data anymore.
|
||||
- Instead of creating client/server syncers, these modules now act like singletons. Sync APIs are called directly through `CharmSync.client`/`server`.
|
||||
- [Read the updated docs for syncing state →](#client-server-sync)
|
||||
|
||||
3. The [`strict` and `frozen` flags](#globals) are automatically enabled in Roblox Studio, so unsafe Charm code will start throwing errors if you didn't use the old `__DEV__` flag. The flags have the following behavior:
|
||||
- `strict`: Yielding in effects, signals, and other critical Charm functions will throw an error
|
||||
- `frozen`: Tables passed to signals are deeply frozen to strictly enforce data immutability and prevent accidental mutations
|
||||
|
||||
4. Nested effects automatically clean up when the parent effect re-runs or gets disposed. In other words, all effects created during the execution of another effect will be added as a "child" and clean up with the parent effect. This might cause issues in code that relied on the old behavior, where effects were detached from the parent.
|
||||
- This feature applies to all reaction APIs, including the listener function in `subscribe()` and the observer function in `observe()`.
|
||||
- Effects that should not be tracked by a parent effect/scope should be wrapped in [`untracked()`](#untrackedcallback).
|
||||
- This feature can cause runtime bugs that are hard to track! If you need to narrow down a cause, you can disable this feature by setting [`globals.trackInnerEffects`](#globals) to `false`.
|
||||
- > [!NOTE]
|
||||
> An example of this feature causing a bug is an old implementation of [`VideCharm.useAtom`](./packages/vide-charm/src/init.luau) that did not wrap the source update in `untracked()`. Because Vide effects run immediately after a source updates, Vide will notify components during the execution of the Charm effect in `useAtom`.
|
||||
>
|
||||
> This meant effects created as a side effect of a source update would implicitly get added as a child of the `useAtom` effect, and they could get disposed at the wrong time and desync UI.
|
||||
|
||||
5. Consider refactoring your code to use some new quality-of-life features. Many of these are made possible with many thanks to [alien-signals](https://github.com/stackblitz/alien-signals)!
|
||||
- Added [`signal()`](#signalinitialvalue-equals) to make reads and writes more explicit
|
||||
- Added [`listen()`](#listengetter-callback) for running a subscription once immediately
|
||||
- Added [`effectScope()`](#effectscopecallback) for collecting and cleaning up multiple effects at once
|
||||
- Added [`onCleanup()`](#oncleanupcallback-failsilently) for running code when the currently-running effect, subscription, or observer cleans up
|
||||
- The [`computed()`](#computedgetter) callback now gets called with the previous computed value
|
||||
- Optimized `computed()` to use lazy evaluation instead of eager updates
|
||||
- Optimized `mapped()` to only map values that changed in the original table
|
||||
- Effect execution and ordering is more reliable
|
||||
|
||||
---
|
||||
|
||||
## Examples
|
||||
|
||||
Check out this simple [example project →](https://github.com/littensy/charm-example)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue