Upgrading - Upgrading to 3.18
Liveblocks 3.18 introduces a new JSON-based serialization model for Live
structures. .toJSON() replaces .toImmutable() as the canonical way to read
Storage snapshots, and useStorage now returns plain objects instead of Map
instances for LiveMap values.
Why this change?
Previously, useStorage returned Map instances for LiveMap values, while
LiveObject values were returned as plain objects. This difference caused
practical problems in real apps: because Maps cannot be serialized with
JSON.stringify(), the result of useStorage() could never be assumed to be
legal JSON, even though many users expected that. Instead, LiveMaps would appear
as empty objects when serialized to JSON.
By unifying the return value of useStorage() for every Live structure to JSON,
users can now "just" store the results of useStorage() where they want, pass
it around, and serialize it without worrying about the underlying structure.
The downside however, is a syntactically breaking change for LiveMap users:
instead of Map instances, these now appear as plain objects. However, since
the change is purely syntactical and mechanical, no real functionality is lost:
every read-only Map operation has an equivalent plain-object expression. See
the migration table below for a complete list
of rewrites.
How to upgrade
First of all, let's upgrade all Liveblocks dependencies to their latest versions. The easiest way to do that is to run the following command:
There are some potentially breaking changes in this update.
Does this affect you?
If you're reading LiveMap values from useStorage, the return type has
changed from Map to a plain object. See
LiveMap values in useStorage.
If you're using .toImmutable() on any Live structure, it has been removed.
See Removed .toImmutable().
If you're using .toObject() on LiveObject, it has been removed. See
Removed .toObject().
If you're using .toArray() on LiveList, it has been removed. See
Removed .toArray().
If you're using the ToImmutable type, it has been removed. See
Removed ToImmutable type.
Otherwise, you can simply upgrade your packages and no changes will affect you.
LiveMap values in useStorage
useStorage now returns plain objects for LiveMap values instead of Map
instances. If you're accessing LiveMap data through useStorage, you'll need
to update your code. The change is fully mechanical. Every Map method has a
direct plain-object equivalent:
| ❌ Before | ✅ After |
|---|---|
myMap.get("my-node") | myMap["my-node"] |
myMap.has("my-node") | "my-node" in myMap |
myMap.size | Object.keys(myMap).length |
Array.from(myMap.keys()) | Object.keys(myMap) |
Array.from(myMap.values()) | Object.values(myMap) |
Array.from(myMap.entries()) | Object.entries(myMap) |
Of course, if you prefer, you can still convert the plain object back to a Map
if your application requires it:
Removed .toImmutable()
.toImmutable() has been removed from all Live structures (LiveObject,
LiveList, LiveMap). Use .toJSON() instead, which returns a cached,
JSON-compatible snapshot. If you aren't using any LiveMaps in your
application, the results will be identical.
Removed .toObject()
.toObject() has been removed from LiveObject. Use .toJSON() or .get(key)
instead:
Removed .toArray()
.toArray() has been removed from LiveList. Use .toJSON() or iterate
directly:
Removed ToImmutable type
The ToImmutable type has been removed. Use ToJson instead: