Skip to content

Getting started with LiveStore + Vue

  • Recommended: Bun 1.2 or higher
  • Node.js 23.0.0 or higher

Vue integration is still in beta and being incubated as a separate repository. Please direct any issues or contributions to Vue LiveStore

For a quick start, we recommend referencing the playground folder in the Vue LiveStore repository.

  1. Install dependencies

    It’s strongly recommended to use bun or pnpm for the simplest and most reliable dependency setup (see note on package management for more details).

    Terminal window
    bun install @livestore/livestore@0.4.0-dev.14 @livestore/wa-sqlite@0.4.0-dev.14 @livestore/adapter-web@0.4.0-dev.14 @livestore/utils@0.4.0-dev.14 @livestore/peer-deps@0.4.0-dev.14 @livestore/devtools-vite@0.4.0-dev.14 slashv/vue-livestore@0.4.0-dev.14
  2. Update Vite config

    Add the following code to your vite.config.js file:

    import { livestoreDevtoolsPlugin } from '@livestore/devtools-vite'
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueDevTools from 'vite-plugin-vue-devtools'
    export default defineConfig({
    plugins: [
    vue(),
    vueDevTools(),
    livestoreDevtoolsPlugin({ schemaPath: './src/livestore/schema.ts' }),
    ],
    worker: { format: 'es' },
    })

Create a file named schema.ts inside the src/livestore folder. This file defines your LiveStore schema consisting of your app’s event definitions (describing how data changes), derived state (i.e. SQLite tables), and materializers (how state is derived from events).

Here’s an example schema:

import {
import Events
Events
,
const makeSchema: <TInputSchema extends InputSchema>(inputSchema: TInputSchema) => FromInputSchema.DeriveSchema<TInputSchema>
makeSchema
,
import Schema
Schema
,
type SessionIdSymbol = typeof SessionIdSymbol
const SessionIdSymbol: typeof SessionIdSymbol

Can be used in queries to refer to the current session id. Will be replaced with the actual session id at runtime

In client document table:

const uiState = State.SQLite.clientDocument({
name: 'ui_state',
schema: Schema.Struct({
theme: Schema.Literal('dark', 'light', 'system'),
user: Schema.String,
showToolbar: Schema.Boolean,
}),
default: { value: defaultFrontendState, id: SessionIdSymbol },
})

Or in a client document query:

const query$ = queryDb(tables.uiState.get(SessionIdSymbol))

SessionIdSymbol
,
import State
State
} from '@livestore/livestore'
export const
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
= {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
:
import State
State
.
import SQLite
SQLite
.
function table<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
columnType: "integer";
... 4 more ...;
autoIncrement: false;
};
}, Partial<...>>(args: {
...;
} & Partial<...>): State.SQLite.TableDef<...> (+2 overloads)

Creates a SQLite table definition from columns or an Effect Schema.

This function supports two main ways to define a table:

  1. Using explicit column definitions
  2. Using an Effect Schema (either the name property needs to be provided or the schema needs to have a title/identifier)
// Using explicit columns
const usersTable = State.SQLite.table({
name: 'users',
columns: {
id: State.SQLite.text({ primaryKey: true }),
name: State.SQLite.text({ nullable: false }),
email: State.SQLite.text({ nullable: false }),
age: State.SQLite.integer({ nullable: true }),
},
})
// Using Effect Schema with annotations
import { Schema } from '@livestore/utils/effect'
const UserSchema = Schema.Struct({
id: Schema.Int.pipe(State.SQLite.withPrimaryKey).pipe(State.SQLite.withAutoIncrement),
email: Schema.String.pipe(State.SQLite.withUnique),
name: Schema.String,
active: Schema.Boolean.pipe(State.SQLite.withDefault(true)),
createdAt: Schema.optional(Schema.Date),
})
// Option 1: With explicit name
const usersTable = State.SQLite.table({
name: 'users',
schema: UserSchema,
})
// Option 2: With name from schema annotation (title or identifier)
const AnnotatedUserSchema = UserSchema.annotations({ title: 'users' })
const usersTable2 = State.SQLite.table({
schema: AnnotatedUserSchema,
})
// Adding indexes
const PostSchema = Schema.Struct({
id: Schema.String.pipe(State.SQLite.withPrimaryKey),
title: Schema.String,
authorId: Schema.String,
createdAt: Schema.Date,
}).annotations({ identifier: 'posts' })
const postsTable = State.SQLite.table({
schema: PostSchema,
indexes: [
{ name: 'idx_posts_author', columns: ['authorId'] },
{ name: 'idx_posts_created', columns: ['createdAt'], isUnique: false },
],
})

table
({
name: "todos"
name
: 'todos',
columns: {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}
columns
: {
id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
}
id
:
import State
State
.
import SQLite
SQLite
.
const text: <string, string, false, typeof NoDefault, true, false>(args: {
schema?: Schema.Schema<string, string, never>;
default?: typeof NoDefault;
nullable?: false;
primaryKey?: true;
autoIncrement?: false;
}) => {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
} (+1 overload)
text
({
primaryKey?: true
primaryKey
: true }),
text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
}
text
:
import State
State
.
import SQLite
SQLite
.
const text: <string, string, false, "", false, false>(args: {
schema?: Schema.Schema<string, string, never>;
default?: "";
nullable?: false;
primaryKey?: false;
autoIncrement?: false;
}) => {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
} (+1 overload)
text
({
default?: ""
default
: '' }),
completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
}
completed
:
import State
State
.
import SQLite
SQLite
.
const boolean: <boolean, false, false, false, false>(args: {
default?: false;
nullable?: false;
primaryKey?: false;
autoIncrement?: false;
}) => {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
} (+1 overload)
boolean
({
default?: false
default
: false }),
deletedAt: {
columnType: "integer";
schema: Schema.Schema<Date | null, number | null, never>;
default: None<never>;
nullable: true;
primaryKey: false;
autoIncrement: false;
}
deletedAt
:
import State
State
.
import SQLite
SQLite
.
const integer: <number, Date, true, typeof NoDefault, false, false>(args: {
schema?: Schema.Schema<Date, number, never>;
default?: typeof NoDefault;
nullable?: true;
primaryKey?: false;
autoIncrement?: false;
}) => {
columnType: "integer";
schema: Schema.Schema<Date | null, number | null, never>;
default: None<never>;
nullable: true;
primaryKey: false;
autoIncrement: false;
} (+1 overload)
integer
({
nullable?: true
nullable
: true,
schema?: Schema.Schema<Date, number, never>
schema
:
import Schema
Schema
.
class DateFromNumber

Defines a schema that converts a number into a Date object using the new Date constructor. This schema does not validate the numerical input, allowing potentially invalid values such as NaN, Infinity, and -Infinity to be converted into Date objects. During the encoding process, any invalid Date object will be encoded to NaN.

@since3.10.0

DateFromNumber
}),
},
}),
uiState: State.SQLite.ClientDocumentTableDef<"uiState", {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
partialSet: true;
default: {
id: typeof SessionIdSymbol;
value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}>
uiState
:
import State
State
.
import SQLite
SQLite
.
clientDocument<"uiState", {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
readonly name: "uiState";
readonly schema: Schema.Struct<{
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}>;
readonly default: {
readonly id: typeof SessionIdSymbol;
readonly value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}>({ name, schema: valueSchema, ...inputOptions }: {
name: "uiState";
schema: Schema.Schema<{
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
...;
}, never>;
} & {
readonly name: "uiState";
readonly schema: Schema.Struct<{
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}>;
readonly default: {
readonly id: typeof SessionIdSymbol;
readonly value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}): State.SQLite.ClientDocumentTableDef<...>
export clientDocument

Special:

  • Synced across client sessions (e.g. tabs) but not across different clients
  • Derived setters
    • Emits client-only events
    • Has implicit setter-materializers
  • Similar to React.useState (except it's persisted)

Careful:

  • When changing the table definitions in a non-backwards compatible way, the state might be lost without explicit materializers to handle the old auto-generated events

Usage:

// Querying data
// `'some-id'` can be ommited for SessionIdSymbol
store.queryDb(clientDocumentTable.get('some-id'))
// Setting data
// Again, `'some-id'` can be ommited for SessionIdSymbol
store.commit(clientDocumentTable.set({ someField: 'some-value' }, 'some-id'))

clientDocument
({
name: "uiState"
name
: 'uiState',
schema: Schema.Schema<{
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, never> & Schema.Struct<{
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}>
schema
:
import Schema
Schema
.
function Struct<{
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}>(fields: {
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}): Schema.Struct<{
newTodoText: typeof Schema.String;
filter: Schema.Literal<["all", "active", "completed"]>;
}> (+1 overload)

@since3.10.0

Struct
({
newTodoText: typeof Schema.String
newTodoText
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
filter: Schema.Literal<["all", "active", "completed"]>
filter
:
import Schema
Schema
.
function Literal<["all", "active", "completed"]>(literals_0: "all", literals_1: "active", literals_2: "completed"): Schema.Literal<["all", "active", "completed"]> (+2 overloads)

@since3.10.0

Literal
('all', 'active', 'completed') }),
default: {
readonly id: typeof SessionIdSymbol;
readonly value: {
readonly newTodoText: "";
readonly filter: "all";
};
}
default
: {
id: typeof SessionIdSymbol
id
:
const SessionIdSymbol: typeof SessionIdSymbol

Can be used in queries to refer to the current session id. Will be replaced with the actual session id at runtime

In client document table:

const uiState = State.SQLite.clientDocument({
name: 'ui_state',
schema: Schema.Struct({
theme: Schema.Literal('dark', 'light', 'system'),
user: Schema.String,
showToolbar: Schema.Boolean,
}),
default: { value: defaultFrontendState, id: SessionIdSymbol },
})

Or in a client document query:

const query$ = queryDb(tables.uiState.get(SessionIdSymbol))

SessionIdSymbol
,
value: {
readonly newTodoText: "";
readonly filter: "all";
}
value
: {
newTodoText: ""
newTodoText
: '',
filter: "all"
filter
: 'all' } },
}),
}
export const
const events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
}
events
= {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>
todoCreated
:
import Events
Events
.
synced<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}>(args: {
name: "v1.TodoCreated";
schema: Schema.Schema<{
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, never>;
} & Omit<State.SQLite.DefineEventOptions<{
readonly text: string;
readonly id: string;
}, false>, "derived" | "clientOnly">): State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>
export synced
synced
({
name: "v1.TodoCreated"
name
: 'v1.TodoCreated',
schema: Schema.Schema<{
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, never>
schema
:
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
text: typeof Schema.String;
}>(fields: {
id: typeof Schema.String;
text: typeof Schema.String;
}): Schema.Struct<{
id: typeof Schema.String;
text: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
text: typeof Schema.String
text
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
}),
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>
todoCompleted
:
import Events
Events
.
synced<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}>(args: {
name: "v1.TodoCompleted";
schema: Schema.Schema<{
readonly id: string;
}, {
readonly id: string;
}, never>;
} & Omit<State.SQLite.DefineEventOptions<{
readonly id: string;
}, false>, "derived" | "clientOnly">): State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>
export synced
synced
({
name: "v1.TodoCompleted"
name
: 'v1.TodoCompleted',
schema: Schema.Schema<{
readonly id: string;
}, {
readonly id: string;
}, never>
schema
:
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
}>(fields: {
id: typeof Schema.String;
}): Schema.Struct<{
id: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
}),
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>
todoUncompleted
:
import Events
Events
.
synced<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}>(args: {
name: "v1.TodoUncompleted";
schema: Schema.Schema<{
readonly id: string;
}, {
readonly id: string;
}, never>;
} & Omit<State.SQLite.DefineEventOptions<{
readonly id: string;
}, false>, "derived" | "clientOnly">): State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>
export synced
synced
({
name: "v1.TodoUncompleted"
name
: 'v1.TodoUncompleted',
schema: Schema.Schema<{
readonly id: string;
}, {
readonly id: string;
}, never>
schema
:
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
}>(fields: {
id: typeof Schema.String;
}): Schema.Struct<{
id: typeof Schema.String;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
}),
}),
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>
todoDeleted
:
import Events
Events
.
synced<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}>(args: {
name: "v1.TodoDeleted";
schema: Schema.Schema<{
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, never>;
} & Omit<State.SQLite.DefineEventOptions<{
readonly id: string;
readonly deletedAt: Date;
}, false>, "derived" | "clientOnly">): State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>
export synced
synced
({
name: "v1.TodoDeleted"
name
: 'v1.TodoDeleted',
schema: Schema.Schema<{
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, never>
schema
:
import Schema
Schema
.
function Struct<{
id: typeof Schema.String;
deletedAt: typeof Schema.Date;
}>(fields: {
id: typeof Schema.String;
deletedAt: typeof Schema.Date;
}): Schema.Struct<{
id: typeof Schema.String;
deletedAt: typeof Schema.Date;
}> (+1 overload)

@since3.10.0

Struct
({
id: typeof Schema.String
id
:
import Schema
Schema
.
class String
export String

@since3.10.0

String
,
deletedAt: typeof Schema.Date
deletedAt
:
import Schema
Schema
.
class Date
export Date

This schema converts a string into a Date object using the new Date constructor. It ensures that only valid date strings are accepted, rejecting any strings that would result in an invalid date, such as new Date("Invalid Date").

@since3.10.0

Date
}),
}),
todoClearedCompleted: State.SQLite.EventDef<"v1.TodoClearedCompleted", {
readonly deletedAt: Date;
}, {
readonly deletedAt: string;
}, false>
todoClearedCompleted
:
import Events
Events
.
synced<"v1.TodoClearedCompleted", {
readonly deletedAt: Date;
}, {
readonly deletedAt: string;
}>(args: {
name: "v1.TodoClearedCompleted";
schema: Schema.Schema<{
readonly deletedAt: Date;
}, {
readonly deletedAt: string;
}, never>;
} & Omit<State.SQLite.DefineEventOptions<{
readonly deletedAt: Date;
}, false>, "derived" | "clientOnly">): State.SQLite.EventDef<"v1.TodoClearedCompleted", {
readonly deletedAt: Date;
}, {
readonly deletedAt: string;
}, false>
export synced
synced
({
name: "v1.TodoClearedCompleted"
name
: 'v1.TodoClearedCompleted',
schema: Schema.Schema<{
readonly deletedAt: Date;
}, {
readonly deletedAt: string;
}, never>
schema
:
import Schema
Schema
.
function Struct<{
deletedAt: typeof Schema.Date;
}>(fields: {
deletedAt: typeof Schema.Date;
}): Schema.Struct<{
deletedAt: typeof Schema.Date;
}> (+1 overload)

@since3.10.0

Struct
({
deletedAt: typeof Schema.Date
deletedAt
:
import Schema
Schema
.
class Date
export Date

This schema converts a string into a Date object using the new Date constructor. It ensures that only valid date strings are accepted, rejecting any strings that would result in an invalid date, such as new Date("Invalid Date").

@since3.10.0

Date
}),
}),
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<"uiState", {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
partialSet: true;
default: {
id: typeof SessionIdSymbol;
value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}>
uiStateSet
:
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
uiState: State.SQLite.ClientDocumentTableDef<"uiState", {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
partialSet: true;
default: {
id: typeof SessionIdSymbol;
value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}>
uiState
.
ClientDocumentTableDef<TName extends string, TType, TEncoded, TOptions extends ClientDocumentTableOptions<TType>>.Trait<"uiState", { readonly filter: "completed" | "all" | "active"; readonly newTodoText: string; }, { readonly filter: "completed" | "all" | "active"; readonly newTodoText: string; }, { ...; }>.set: State.SQLite.ClientDocumentTableDef.SetEventDefLike<"uiState", {
readonly filter: "completed" | "all" | "active";
readonly newTodoText: string;
}, {
partialSet: true;
default: {
id: typeof SessionIdSymbol;
value: {
readonly newTodoText: "";
readonly filter: "all";
};
};
}>

Derived event definition for setting the value of the client document table. If the document doesn't exist yet, the first .set event will create it.

@example

const someDocumentTable = State.SQLite.clientDocument({
name: 'SomeDocumentTable',
schema: Schema.Struct({
someField: Schema.String,
someOtherField: Schema.String,
}),
default: { value: { someField: 'some-default-value', someOtherField: 'some-other-default-value' } },
})
const setEventDef = store.commit(someDocumentTable.set({ someField: 'explicit-value' }, 'some-id'))
// Will commit an event with the following payload:
// { id: 'some-id', value: { someField: 'explicit-value', someOtherField: 'some-other-default-value' } }

Similar to .get, you can omit the id argument if you've set a default id.

@example

const uiState = State.SQLite.clientDocument({
name: 'UiState',
schema: Schema.Struct({ someField: Schema.String }),
default: { id: SessionIdSymbol, value: { someField: 'some-default-value' } },
})
const setEventDef = store.commit(uiState.set({ someField: 'explicit-value' }))
// Will commit an event with the following payload:
// { id: '...', value: { someField: 'explicit-value' } }
// ^^^
// Automatically replaced with the client session id

set
,
}
const
const materializers: {
"v1.TodoCreated": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>>;
"v1.TodoCompleted": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>>;
"v1.TodoUncompleted": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>>;
"v1.TodoDeleted": State.SQLite.Materializer<...>;
"v1.TodoClearedCompleted": State.SQLite.Materializer<...>;
}
materializers
=
import State
State
.
import SQLite
SQLite
.
const materializers: <{
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
}>(_eventDefRecord: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
}, handlers: {
...;
}) => {
...;
}
materializers
(
const events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
}
events
, {
'v1.TodoCreated': ({
id: string
id
,
text: string
text
}) =>
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
.
insert: (values: {
readonly id: string;
readonly text?: string;
readonly completed?: boolean;
readonly deletedAt?: Date | null;
}) => QueryBuilder<readonly {
readonly id: string;
readonly text: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
...;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">

Insert a new row into the table

Example:

db.todos.insert({ id: '123', text: 'Buy milk', status: 'active' })

insert
({
id: string
id
,
text?: string
text
,
completed?: boolean
completed
: false }),
'v1.TodoCompleted': ({
id: string
id
}) =>
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
.
update: (values: Partial<{
readonly text: string;
readonly id: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}>) => QueryBuilder<readonly {
readonly id: string;
readonly text: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
...;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">

Update rows in the table that match the where clause

Example:

db.todos.update({ status: 'completed' }).where({ id: '123' })

update
({
completed?: boolean
completed
: true }).
where: (params: Partial<{
readonly id: string | {
op: QueryBuilder<TResult, TTableDef extends State.SQLite.TableDefBase, TWithout extends QueryBuilder.ApiFeature = never>.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly text: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly completed: boolean | ... 2 more ... | undefined;
readonly deletedAt: Date | ... 3 more ... | undefined;
}>) => QueryBuilder<...> (+2 overloads)
where
({
id?: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined
id
}),
'v1.TodoUncompleted': ({
id: string
id
}) =>
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
.
update: (values: Partial<{
readonly text: string;
readonly id: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}>) => QueryBuilder<readonly {
readonly id: string;
readonly text: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
...;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">

Update rows in the table that match the where clause

Example:

db.todos.update({ status: 'completed' }).where({ id: '123' })

update
({
completed?: boolean
completed
: false }).
where: (params: Partial<{
readonly id: string | {
op: QueryBuilder<TResult, TTableDef extends State.SQLite.TableDefBase, TWithout extends QueryBuilder.ApiFeature = never>.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly text: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly completed: boolean | ... 2 more ... | undefined;
readonly deletedAt: Date | ... 3 more ... | undefined;
}>) => QueryBuilder<...> (+2 overloads)
where
({
id?: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined
id
}),
'v1.TodoDeleted': ({
id: string
id
,
deletedAt: Date
deletedAt
}) =>
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
.
update: (values: Partial<{
readonly text: string;
readonly id: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}>) => QueryBuilder<readonly {
readonly id: string;
readonly text: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
...;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">

Update rows in the table that match the where clause

Example:

db.todos.update({ status: 'completed' }).where({ id: '123' })

update
({
deletedAt?: Date | null
deletedAt
}).
where: (params: Partial<{
readonly id: string | {
op: QueryBuilder<TResult, TTableDef extends State.SQLite.TableDefBase, TWithout extends QueryBuilder.ApiFeature = never>.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly text: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly completed: boolean | ... 2 more ... | undefined;
readonly deletedAt: Date | ... 3 more ... | undefined;
}>) => QueryBuilder<...> (+2 overloads)
where
({
id?: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined
id
}),
'v1.TodoClearedCompleted': ({
deletedAt: Date
deletedAt
}) =>
const tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
.
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>
todos
.
update: (values: Partial<{
readonly text: string;
readonly id: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}>) => QueryBuilder<readonly {
readonly id: string;
readonly text: string;
readonly completed: boolean;
readonly deletedAt: Date | null;
}[], State.SQLite.TableDefBase<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
...;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>>, "select" | ... 6 more ... | "row">

Update rows in the table that match the where clause

Example:

db.todos.update({ status: 'completed' }).where({ id: '123' })

update
({
deletedAt?: Date | null
deletedAt
}).
where: (params: Partial<{
readonly id: string | {
op: QueryBuilder<TResult, TTableDef extends State.SQLite.TableDefBase, TWithout extends QueryBuilder.ApiFeature = never>.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly text: string | {
op: QueryBuilder.WhereOps.SingleValue;
value: string;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly string[];
} | undefined;
readonly completed: boolean | ... 2 more ... | undefined;
readonly deletedAt: Date | ... 3 more ... | undefined;
}>) => QueryBuilder<...> (+2 overloads)
where
({
completed?: boolean | {
op: QueryBuilder.WhereOps.SingleValue;
value: boolean;
} | {
op: QueryBuilder.WhereOps.MultiValue;
value: readonly boolean[];
} | undefined
completed
: true }),
})
const
const state: InternalState
state
=
import State
State
.
import SQLite
SQLite
.
const makeState: <{
tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
};
materializers: {
...;
};
}>(inputSchema: {
tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
};
materializers: {
...;
};
}) => InternalState
makeState
({
tables: {
todos: State.SQLite.TableDef<State.SQLite.SqliteTableDefForInput<"todos", {
readonly id: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: None<never>;
nullable: false;
primaryKey: true;
autoIncrement: false;
};
readonly text: {
columnType: "text";
schema: Schema.Schema<string, string, never>;
default: Some<"">;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly completed: {
columnType: "integer";
schema: Schema.Schema<boolean, number, never>;
default: Some<false>;
nullable: false;
primaryKey: false;
autoIncrement: false;
};
readonly deletedAt: {
...;
};
}>, State.SQLite.WithDefaults<...>, Schema.Schema<...>>;
uiState: State.SQLite.ClientDocumentTableDef<...>;
}
tables
,
materializers: {
"v1.TodoCreated": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>>;
"v1.TodoCompleted": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>>;
"v1.TodoUncompleted": State.SQLite.Materializer<State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>>;
"v1.TodoDeleted": State.SQLite.Materializer<...>;
"v1.TodoClearedCompleted": State.SQLite.Materializer<...>;
}
materializers
})
export const
const schema: FromInputSchema.DeriveSchema<{
events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
};
state: InternalState;
}>
schema
=
makeSchema<{
events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
};
state: InternalState;
}>(inputSchema: {
events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
};
state: InternalState;
}): FromInputSchema.DeriveSchema<...>
makeSchema
({
events: {
todoCreated: State.SQLite.EventDef<"v1.TodoCreated", {
readonly text: string;
readonly id: string;
}, {
readonly text: string;
readonly id: string;
}, false>;
todoCompleted: State.SQLite.EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: State.SQLite.EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: State.SQLite.EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: State.SQLite.EventDef<...>;
uiStateSet: State.SQLite.ClientDocumentTableDef.SetEventDefLike<...>;
}
events
,
state: InternalState
state
})

Create a file named livestore.worker.ts inside the src/livestore folder. This file will contain the LiveStore web worker. When importing this file, make sure to add the ?worker extension to the import path to ensure that Vite treats it as a worker file.

import {
const makeWorker: (options: WorkerOptions) => void
makeWorker
} from '@livestore/adapter-web/worker'
import {
const schema: FromInputSchema.DeriveSchema<{
events: {
todoCreated: EventDef<"v1.TodoCreated", {
readonly id: string;
readonly text: string;
}, {
readonly id: string;
readonly text: string;
}, false>;
todoCompleted: EventDef<"v1.TodoCompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoUncompleted: EventDef<"v1.TodoUncompleted", {
readonly id: string;
}, {
readonly id: string;
}, false>;
todoDeleted: EventDef<"v1.TodoDeleted", {
readonly id: string;
readonly deletedAt: Date;
}, {
readonly id: string;
readonly deletedAt: string;
}, false>;
todoClearedCompleted: EventDef<...>;
uiStateSet: ClientDocumentTableDef.SetEventDefLike<...>;
};
state: InternalState;
}>
schema
} from './schema.ts'
function makeWorker(options: WorkerOptions): void
makeWorker
({
schema: LiveStoreSchema<DbSchema, EventDefRecord>
schema
})

To make the LiveStore available throughout your app, wrap your app’s root component with the LiveStoreProvider component from vue-livestore. This provider manages your app’s data store, loading, and error states.

Here’s an example:

<script setup lang="ts">
import { makePersistedAdapter } from '@livestore/adapter-web'
import LiveStoreSharedWorker from '@livestore/adapter-web/shared-worker?sharedworker'
import LiveStoreWorker from './livestore/livestore.worker.ts?worker'
import { schema } from './livestore/schema'
import { LiveStoreProvider } from 'vue-livestore'
import ToDos from './components/to-dos.vue'
const adapter = makePersistedAdapter({
storage: { type: 'opfs' },
worker: LiveStoreWorker,
sharedWorker: LiveStoreSharedWorker,
})
const storeOptions = {
schema,
adapter,
storeId: 'test_store',
}
</script>
<template>
<LiveStoreProvider :options="storeOptions">
<template #loading>
<div>Loading LiveStore...</div>
</template>
<ToDos />
</LiveStoreProvider>
</template>

After wrapping your app with the LiveStoreProvider, you can use the useStore hook from any component to commit events.

Here’s an example:

<script setup lang="ts">
import { ref } from 'vue'
import { events } from '../livestore/schema'
const { store } = useStore()
const newTodoText = ref('')
// Events
const createTodo = () => {
store.commit(events.todoCreated({ id: crypto.randomUUID(), text: newTodoText.value }))
newTodoText.value = ''
}
</script>
<template>
<div>
<input v-model="newTodoText" />
<button @click="createTodo">Create</button>
</div>
</template>

To retrieve data from the database, first define a query using queryDb from @livestore/livestore. Then, execute the query with the useQuery hook from @livestore/react.

Consider abstracting queries into a separate file to keep your code organized, though you can also define them directly within components if preferred.

Here’s an example:

<script setup lang="ts">
import { queryDb } from '@livestore/livestore'
import { useQuery } from 'vue-livestore'
import { events, tables } from '../livestore/schema'
const visibleTodos$ = queryDb(
() => tables.todos.where({ deletedAt: null }),
{ label: 'visibleTodos' },
)
const todos = useQuery(visibleTodos$)
</script>
<template>
<div>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
</div>
</template>