Observe your immutable state trees.
Vana adds observability to normal objects without mutating their public appearance. The only exception to that rule is that all objects are made immutable. This is Vana at its core.
Read the introduction.
Basic usage
The returned state
is immutable and observable.
Before we make any changes, let's observe our state
object:
// This callback is called synchronously whenever `state` changes.tapstate,
The first kind of mutation passes a callback to the revise
function. Any
changes made within the callback are used to create an immutable copy of our
state
object.
assertbase !== copyassertcopy === state // Our `state` variable is updated.
The copy
object is now observed by whoever was observing the base
object,
and revising the base
object is now forbidden.
The second kind of mutation passes an object to the revise
function. This is
essentially the Object.assign
of Vana.
Those are the basics. Here is a sandbox you can play with:
https://codesandbox.io/s/z33pzx31wp
https://github.com/alloc/vana-sandbox
Install
yarn add vana
Integrations
- React (recommended)
Advanced usage
Here are some advanced use cases.
Cloning an observable object
Clone an observable object by passing it to the o
function.
// The "copy" has its own observable identity.assertisObservablecopyassertbase !== copy // The "base" is still observable and revisable.assertisObservablebasetapbase, console.logrevisebase,
Controlled observables
Pass a callback to the o
function to create a controlled observable.
// This pattern is great for memoized subscriptions.// Log every new value.foo.tapconsole.log
latest
function
The Give any value and receive the latest revision (if possible), else return it as-is.
asserto1 !== o3assertlatesto1 === o3 // Trash in, trash outassertlatest1 === 1
keepAlive
function
The Use the keepAlive
function to make a "living" object out of an observable object. The returned object is a mirror of the observable's current value.
// The latest revision is always reflectedassertstate.a === 2 // Can be passed to `latest`assertlateststate === lastState // Be sure to call dispose when appropriatestate.dispose
watch
function
The This function lets you watch any property path in a state tree.
// An observable that updates when `obj.a.b.c` is changed // Run a function when the property value is changed // Get the current property valueprop.get // Shallow properties can be observed more efficiently // You can use a selector function if you want
Every property in the path is observed.
The property value is deeply observed if possible.
Array helpers
These functions are for working with immutable arrays. Each function works for any array regardless of mutability. They always return a modified copy of the given array (or the given array if no changes were made).
// Append one or more values to a copy of the given array.appendarr, ...values // Prepend one or more values to a copy of the given array.prependarr, ...values // Insert one or more values into a copy of the given array.insertarr, index, ...values // Merge one or more arrays into a copy of the given array.concatarr, ...values // Remove one or more values from a copy of the given array.removearr, index, count = 1
Custom immutable classes
Any class can be made compatible with Vana's cloning logic.
assertObject.isFrozenfooassertfoo.bar === 0 foo = foo.setBar1assertfoo.bar === 1 // works with `keepAlive` assertfoo3 !== fooassertfoo3.bar === 2assertfooLatest.bar === 2 // and with `latest`foo = latestfooassertfoo === foo3
TODO: Provide more advanced use cases