With the release of 0.17 we’re making a big investment in the stability and reliability of Liveblocks. Our long term goal is to empower you to write and help evolve your apps in the best way possible, and at enterprise scale. It already was easy to get started with Liveblocks, and with these changes we want to make evolving your app just as easy.
The first step towards this goal is to take TypeScript support to the next level
for @liveblocks/client
and @liveblocks/react
(but our other packages
will soon follow suit). This will help you write code with confidence and catch
bugs as soon as possible in the development process. We have strictened our type
definitions to be more accurate and will recommend some new usage patterns, so
it will be easier for you to create bug free collaborative apps.
To upgrade @liveblocks/client
and @liveblocks/react
, run the
following command.
With these changes, we’re clearing the path to enable schema validation per room, automatic data migrations, more powerful data selector APIs, and other enterprise-level features.
Let’s dive in and take a look!
With 0.16, it was possible to initialize a storage key with useObject
,
useList
, useMap
.
Even if handy, we realized that it introduced confusion and unpredictable behavior for most users. Imagine a scenario where you have two components initializing the same storage key.
Depending on which component renders first, author
will be Margaret Hamilton
or Ada Lovelace. To make this more predictable, we’re deprecating this and
recommend initializing the storage at the RoomProvider
level.
If you run into issues with these new patterns and you need help, please let us know. We’re here to help!
In 0.16, most of our hooks accepted generic parameters that let you explicitly provide your own types. For example:
One issue with this API was that there was no good way to make sure that
RoomProvider.initialPresence
and useMyPresence
types remain
synchronized, as there was no inherent connection between these.
If we added a color
property to the Presence
type, it would still be missing
from the initialPresence
at the RoomProvider
level, and TypeScript would not
be able to catch that bug. The opposite would also fail; omitting the cursor
property on the initialPresence
would break at runtime but TypeScript would
not be able to catch this issue for you!
Another issue is that there could be many places where you’d have to provide those extra type annotations.
With 0.17, we’re fixing all of this!
To do so, we’re introducing a new API called createRoomContext
. It lets
you type your RoomProvider
and make sure that all your hooks types are
synchronized with the RoomProvider
. Besides this initial setup, you will no
longer have to provide any type annotations elsewhere anymore.
As you can see, createRoomContext
optionally takes type parameters that let
you specify the shape of your app’s data (by specifying your own Presence
,
Storage
, UserMeta
, Event
types). Depending on the complexity of your app,
you may only need to use one or more of these.
Take a look at these examples to better see how to use and configure it:
Presence
onlyUserMeta
onlyPresence
,
Storage
,
and
UserMeta
To make this refactoring as easy as possible, follow the steps below.
@liveblocks/client
and @liveblocks/react
To upgrade @liveblocks/client
and @liveblocks/react
, run the following
command.
liveblocks.config.ts
where you will create your Liveblocks client, provider and hooks and re-export them.@liveblocks/react
by your path to liveblocks.config.ts
and remove all generic params.LiveblocksProvider
at the top of your react tree. It’s not needed anymore!If you run into issues with these new patterns and you need help, please let us know. We’re here to help!
In 0.16, while LiveList
, LiveMap
, LiveObject
were generics,
they also took default type params, which made them a footgun. It was easy to
accidentally use them in a way that would discard useful type information and
hinder inference.
For example:
They now mimic their equivalent built-in TypeScript generics, so:
LiveList<T>
is now just like Array<T>
LiveMap<K, V>
is now just like Map<K, V>
LiveObject<{ a: number, b: string }>
is now just like
{ a: number, b: string }
In 0.16, we exposed a Presence
type that you could import, which was just an
alias for “any JSON object”—not that useful! Importing Presence from Liveblocks
made no sense. By definition, Presence is data owned and defined by your
application after all.
You should no longer need to import this type.
Instead, just define it:
We already talked about why, in React, we improved the way you can annotate your own app’s data, by annotating the types only once, at the “top” of your app.
For the same reason, we’re doing a similar thing in the client package.
If you run into issues with these new patterns and you need help, please let us know. We’re here to help!
We use cookies to collect data to improve your experience on our site. Read our Privacy Policy to learn more.