Upgrading 0.18 to 0.21
Upgrading 0.18 → 0.21
Section titled “Upgrading 0.18 → 0.21”0.21.0 is released. These are the ### Breaking entries of its
changelog section, one at a time, with what each one asks you
to change. 0.19 and 0.20 declare no breaking change, so this is one hop from
0.18 — read it before you move to 0.21, not after.
Both are compile errors rather than silent changes of behaviour: the build points at every line that needs editing, and the grep under each section finds them before the build does.
31. context.client.data no longer compiles in a collection callback
Section titled “31. context.client.data no longer compiles in a collection callback”RebaseCallContext["client"] is RebaseCallbackClient now: RebaseClient
without data. Server-side that client is the rebase singleton, which has had
no data since 0.18, so context.client.data.collection(…) compiled and then
threw Cannot read properties of undefined (reading 'collection') on every
call. It is a compile error instead.
What to change: query through context.data, the accessor a callback’s
queries were always meant to use. It runs with the privilege of whatever
triggered the callback, on the write’s own transaction. The
callbacks guide covers what each accessor on the
context can reach.
afterSave: async ({ context }) => { await context.client.data.audit_logs.create({ action: "approved" }); await context.data.audit_logs.create({ action: "approved" });}grep -rn "client\.data\b" configcontext.client.dataAsAdmin is still there for a callback that must see what an
admin may see. admin.browserCallbacks changes too: the old spelling ran there,
because the panel’s client carries data, and it stops compiling all the same.
useRebaseContext().client in a React component keeps its data.
32. selectedEntities is gone: a selection is rows or a query
Section titled “32. selectedEntities is gone: a selection is rows or a query”A collection view can now select every row that matches its filter, not only
the rows it has loaded, so SelectionController no longer hands out an
Entity[]. selectionController.selection is an EntitySelection union:
{ type: "entities", entities } for rows ticked by hand, or
{ type: "query", query, excluded, count? } for every row matching a query,
most of which nobody has read.
What to change: a custom action that reads the selection turns it into rows
with resolveSelection from @rebasepro/cms. It returns the ticked rows at
once, and reads a query selection a page at a time — with an optional progress
callback — throwing rather than returning a prefix when the query matches more
than 20,000 rows.
const handlePublish = async () => { for (const entity of selectionController.selectedEntities) { const selected = await resolveSelection({ selection: selectionController.selection, accessor: data.collection(path) }); for (const entity of selected) { await data.collection(entity.path).update(entity.id, { status: "published" }); }};grep -rn "selectedEntities" config frontendThree smaller moves come with it:
selectionController.selectedEntities.length→selectionController.selectedCount. It isundefined, never 0, when every row matching a query is selected and the collection cannot be counted — render that case, do not default it.setSelectedEntities(prev => …)→setSelection(prev => …), which receives and returns anEntitySelection.setSelectedEntities(rows)with an array still works.- A check for “is anything selected” is
selectionController.hasSelection.
isEntitySelected and toggleEntitySelection are unchanged, and are what a
per-row checkbox should keep using. The
collection actions example
shows the whole pattern.