Writing Data with Mutators
Zero generates basic CRUD mutators for every table you sync. Mutators are available at zero.mutate.<tablename>
:
const z = new Zero(...);
z.mutate.user.insert({
id: nanoid(),
username: 'abby',
language: 'en-us',
});
Insert
Create new records with insert
:
z.mutate.user.insert({
id: nanoid(),
username: 'sam',
language: 'js',
});
Nullable fields can be set to null
to explicitly set the new field to null
. They can also be set to undefined
to take the default value (which is often null
but can also be some generated value server-side).
// schema.ts
import {table, string, number} from '@rocicorp/zero';
const user = table('user')
.columns({
id: string(),
username: string(),
language: string().nullable(),
createdAt: number().onInsert(() => Date.now()),
updatedAt: number()
.onInsert(() => Date.now())
.onUpdate(() => Date.now()),
})
.primaryKey('id');
// app.tsx
// Columns with onInsert() defaults are automatically populated
z.mutate.user.insert({
id: '1',
username: 'John Doe',
});
// { id: '1', username: 'John Doe', createdAt: 1743018158777, updatedAt: 1743018158777 }
// Sets language to `null` specifically
z.mutate.user.insert({
id: nanoid(),
username: 'sam',
language: null,
});
// Sets language to the default server-side value. Could be null, or some
// generated or constant default value too.
z.mutate.user.insert({
id: nanoid(),
username: 'sam',
});
// Same as above
z.mutate.user.insert({
id: nanoid(),
username: 'sam',
language: undefined,
});
Upsert
Create new records or update existing ones with upsert
:
z.mutate.user.upsert({
id: samID,
username: 'sam',
language: 'ts',
});
upsert
supports the same null
/ undefined
semantics for nullable fields that insert
does (see above).
Update
Update an existing record. Does nothing if the specified record (by PK) does not exist.
You can pass a partial, leaving fields out that you donβt want to change. For example here we leave the username the same:
// Leaves username field to previous value. updatedAt is automatically set.
z.mutate.user.update({
id: samID,
language: 'golang',
});
// Same as above
z.mutate.user.update({
id: samID,
username: undefined,
language: 'haskell',
});
// Reset language field to `null`
z.mutate.user.update({
id: samID,
language: null,
});
Delete
Delete an existing record. Does nothing if specified record does not exist.
z.mutate.user.delete({
id: samID,
});
Batch Mutate
You can do multiple CRUD mutates in a single batch. If any of the mutations fails, all will. They also all appear together atomically in a single transaction to other clients.
z.mutateBatch(async tx => {
const samID = nanoid();
tx.user.insert({
id: samID,
username: 'sam',
});
const langID = nanoid();
tx.language.insert({
id: langID,
userID: samID,
name: 'js',
});
});