Schema modeling
Live State's schema is a declarative model of your data (collections, fields, relations). It's used both in the server and the client to process queries and mutations.
Defining a schema
You can define a schema using the createSchema function, which takes an object of collections and relations:
import {
createSchema,
object,
id,
string,
reference,
createRelations,
} from "@live-state/sync";
const tasks = object("tasks", {
id: id(),
title: string(),
authorId: reference("users.id"),
});
const users = object("users", {
id: id(),
name: string(),
});
const taskRelations = createRelations(tasks, ({ one }) => ({
author: one(users, "authorId"),
}));
const userRelations = createRelations(users, ({ many }) => ({
tasks: many(tasks, "authorId"),
}));
export const schema = createSchema({
tasks,
users,
taskRelations,
userRelations,
});Collections
Collections are the main building blocks of a schema, they represent tables in the database. They are defined using the object function, which takes a name and the fields of the collection:
const tasks = object("tasks", {
id: id(),
title: string(),
completed: boolean(),
priority: number().default(0),
createdAt: date(),
authorId: reference("users.id"),
});The available field types are:
id(): a unique identifier for the collectionstring(): a string fieldboolean(): a boolean fieldnumber(): a number fielddate(): a datetime fieldreference(collectionName): a reference to another collection (foreign key)
There are also optional modifiers available, like default, nullable, unique, index, etc, which can be combined together:
const tasks = object("tasks", {
id: id(),
title: string().default("Untitled"),
completed: boolean().default(false),
priority: number().default(0),
createdAt: date(),
});It's not possible yet to use functions or SQL expressions for default
values.
So, things like default(() => new Date()) or default('now()') are
not supported.
Relations
Relations can be defined for collections using the createRelations function.
One-to-many
One-to-many relations are defined using the many function, which takes the target collection and the foreign key column:
const userRelations = createRelations(users, ({ many }) => ({
tasks: many(tasks, "authorId"), // users → tasks (one user has many tasks)
}));Optional relations
You can mark a one-to-many relation as optional by marking the foreign key column as nullable:
const posts = object("posts", {
id: id(),
title: string(),
authorId: reference("users.id").nullable(),
});
const postRelations = createRelations(posts, ({ one }) => ({
author: one(users, "authorId"),
}));Many-to-one
Many-to-one relations are defined using the one function, which takes the target collection and the foreign key column:
const taskRelations = createRelations(tasks, ({ one }) => ({
author: one(users, "authorId"), // tasks → users (each task has one author)
}));