@livestore/livestore 0.4.0-dev.21 → 0.4.0-dev.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -1
- package/dist/.tsbuildinfo +1 -1
- package/dist/QueryCache.js +1 -1
- package/dist/QueryCache.js.map +1 -1
- package/dist/SqliteDbWrapper.d.ts +5 -5
- package/dist/SqliteDbWrapper.d.ts.map +1 -1
- package/dist/SqliteDbWrapper.js +8 -8
- package/dist/SqliteDbWrapper.js.map +1 -1
- package/dist/SqliteDbWrapper.test.js +2 -2
- package/dist/SqliteDbWrapper.test.js.map +1 -1
- package/dist/effect/LiveStore.d.ts +130 -2
- package/dist/effect/LiveStore.d.ts.map +1 -1
- package/dist/effect/LiveStore.js +185 -6
- package/dist/effect/LiveStore.js.map +1 -1
- package/dist/effect/LiveStore.test.d.ts +2 -0
- package/dist/effect/LiveStore.test.d.ts.map +1 -0
- package/dist/effect/LiveStore.test.js +42 -0
- package/dist/effect/LiveStore.test.js.map +1 -0
- package/dist/effect/mod.d.ts +1 -1
- package/dist/effect/mod.d.ts.map +1 -1
- package/dist/effect/mod.js +3 -1
- package/dist/effect/mod.js.map +1 -1
- package/dist/live-queries/base-class.d.ts +3 -3
- package/dist/live-queries/base-class.d.ts.map +1 -1
- package/dist/live-queries/base-class.js +2 -2
- package/dist/live-queries/base-class.js.map +1 -1
- package/dist/live-queries/client-document-get-query.d.ts +1 -1
- package/dist/live-queries/client-document-get-query.d.ts.map +1 -1
- package/dist/live-queries/client-document-get-query.js +1 -1
- package/dist/live-queries/client-document-get-query.js.map +1 -1
- package/dist/live-queries/computed.d.ts.map +1 -1
- package/dist/live-queries/computed.js +2 -2
- package/dist/live-queries/computed.js.map +1 -1
- package/dist/live-queries/db-query.js +14 -14
- package/dist/live-queries/db-query.js.map +1 -1
- package/dist/live-queries/db-query.test.js +2 -2
- package/dist/live-queries/db-query.test.js.map +1 -1
- package/dist/live-queries/signal.test.js +2 -2
- package/dist/live-queries/signal.test.js.map +1 -1
- package/dist/mod.d.ts +2 -1
- package/dist/mod.d.ts.map +1 -1
- package/dist/mod.js +1 -0
- package/dist/mod.js.map +1 -1
- package/dist/reactive.d.ts +9 -9
- package/dist/reactive.d.ts.map +1 -1
- package/dist/reactive.js +9 -26
- package/dist/reactive.js.map +1 -1
- package/dist/reactive.test.js +2 -2
- package/dist/reactive.test.js.map +1 -1
- package/dist/store/StoreRegistry.d.ts +215 -0
- package/dist/store/StoreRegistry.d.ts.map +1 -0
- package/dist/store/StoreRegistry.js +267 -0
- package/dist/store/StoreRegistry.js.map +1 -0
- package/dist/store/StoreRegistry.test.d.ts +2 -0
- package/dist/store/StoreRegistry.test.d.ts.map +1 -0
- package/dist/store/StoreRegistry.test.js +381 -0
- package/dist/store/StoreRegistry.test.js.map +1 -0
- package/dist/store/create-store.d.ts +56 -6
- package/dist/store/create-store.d.ts.map +1 -1
- package/dist/store/create-store.js +32 -7
- package/dist/store/create-store.js.map +1 -1
- package/dist/store/devtools.d.ts +1 -1
- package/dist/store/devtools.d.ts.map +1 -1
- package/dist/store/devtools.js +16 -3
- package/dist/store/devtools.js.map +1 -1
- package/dist/store/store-eventstream.test.js +2 -2
- package/dist/store/store-eventstream.test.js.map +1 -1
- package/dist/store/store-types.d.ts +59 -9
- package/dist/store/store-types.d.ts.map +1 -1
- package/dist/store/store-types.js.map +1 -1
- package/dist/store/store-types.test.js +1 -1
- package/dist/store/store-types.test.js.map +1 -1
- package/dist/store/store.d.ts +102 -6
- package/dist/store/store.d.ts.map +1 -1
- package/dist/store/store.js +148 -47
- package/dist/store/store.js.map +1 -1
- package/dist/utils/dev.js.map +1 -1
- package/dist/utils/stack-info.js +2 -2
- package/dist/utils/stack-info.js.map +1 -1
- package/dist/utils/tests/fixture.d.ts +1 -1
- package/dist/utils/tests/fixture.d.ts.map +1 -1
- package/dist/utils/tests/fixture.js.map +1 -1
- package/dist/utils/tests/otel.d.ts.map +1 -1
- package/dist/utils/tests/otel.js +5 -5
- package/dist/utils/tests/otel.js.map +1 -1
- package/package.json +59 -18
- package/src/QueryCache.ts +1 -1
- package/src/SqliteDbWrapper.test.ts +4 -2
- package/src/SqliteDbWrapper.ts +12 -11
- package/src/ambient.d.ts +0 -7
- package/src/effect/LiveStore.test.ts +61 -0
- package/src/effect/LiveStore.ts +381 -8
- package/src/effect/mod.ts +13 -1
- package/src/live-queries/__snapshots__/db-query.test.ts.snap +336 -231
- package/src/live-queries/base-class.ts +7 -6
- package/src/live-queries/client-document-get-query.ts +4 -2
- package/src/live-queries/computed.ts +3 -2
- package/src/live-queries/db-query.test.ts +3 -2
- package/src/live-queries/db-query.ts +15 -15
- package/src/live-queries/signal.test.ts +3 -2
- package/src/mod.ts +2 -0
- package/src/reactive.test.ts +3 -2
- package/src/reactive.ts +22 -23
- package/src/store/StoreRegistry.test.ts +540 -0
- package/src/store/StoreRegistry.ts +418 -0
- package/src/store/create-store.ts +76 -15
- package/src/store/devtools.ts +20 -6
- package/src/store/store-eventstream.test.ts +4 -2
- package/src/store/store-types.test.ts +3 -1
- package/src/store/store-types.ts +64 -13
- package/src/store/store.ts +197 -60
- package/src/utils/dev.ts +2 -2
- package/src/utils/stack-info.ts +2 -2
- package/src/utils/tests/fixture.ts +2 -1
- package/src/utils/tests/otel.ts +8 -7
- package/docs/api/index.md +0 -3
- package/docs/building-with-livestore/complex-ui-state/index.md +0 -5
- package/docs/building-with-livestore/crud/index.md +0 -5
- package/docs/building-with-livestore/data-modeling/index.md +0 -1
- package/docs/building-with-livestore/debugging/index.md +0 -17
- package/docs/building-with-livestore/devtools/index.md +0 -79
- package/docs/building-with-livestore/events/index.md +0 -355
- package/docs/building-with-livestore/examples/ai-agent/index.md +0 -5
- package/docs/building-with-livestore/examples/index.md +0 -30
- package/docs/building-with-livestore/examples/todo-workspaces/index.md +0 -891
- package/docs/building-with-livestore/examples/turnbased-game/index.md +0 -7
- package/docs/building-with-livestore/opentelemetry/index.md +0 -208
- package/docs/building-with-livestore/production-checklist/index.md +0 -5
- package/docs/building-with-livestore/reactivity-system/index.md +0 -202
- package/docs/building-with-livestore/rules-for-ai-agents/index.md +0 -9
- package/docs/building-with-livestore/state/materializers/index.md +0 -300
- package/docs/building-with-livestore/state/sql-queries/index.md +0 -72
- package/docs/building-with-livestore/state/sqlite/index.md +0 -45
- package/docs/building-with-livestore/state/sqlite-schema/index.md +0 -306
- package/docs/building-with-livestore/state/sqlite-schema-effect/index.md +0 -300
- package/docs/building-with-livestore/store/index.md +0 -281
- package/docs/building-with-livestore/syncing/index.md +0 -136
- package/docs/building-with-livestore/tools/cli/index.md +0 -177
- package/docs/building-with-livestore/tools/mcp/index.md +0 -187
- package/docs/examples/cloudflare-adapter/index.md +0 -44
- package/docs/examples/expo-adapter/index.md +0 -44
- package/docs/examples/index.md +0 -55
- package/docs/examples/node-adapter/index.md +0 -44
- package/docs/examples/web-adapter/index.md +0 -52
- package/docs/framework-integrations/custom-elements/index.md +0 -142
- package/docs/framework-integrations/react-integration/index.md +0 -918
- package/docs/framework-integrations/solid-integration/index.md +0 -293
- package/docs/framework-integrations/svelte-integration/index.md +0 -42
- package/docs/framework-integrations/vue-integration/index.md +0 -294
- package/docs/getting-started/expo/index.md +0 -736
- package/docs/getting-started/node/index.md +0 -115
- package/docs/getting-started/react-web/index.md +0 -573
- package/docs/getting-started/solid/index.md +0 -3
- package/docs/getting-started/vue/index.md +0 -471
- package/docs/index.md +0 -209
- package/docs/llms.txt +0 -147
- package/docs/misc/CODE_OF_CONDUCT/index.md +0 -133
- package/docs/misc/FAQ/index.md +0 -37
- package/docs/misc/community/index.md +0 -88
- package/docs/misc/credits/index.md +0 -14
- package/docs/misc/design-partners/index.md +0 -13
- package/docs/misc/package-management/index.md +0 -21
- package/docs/misc/performance/index.md +0 -25
- package/docs/misc/resources/index.md +0 -46
- package/docs/misc/state-of-the-project/index.md +0 -37
- package/docs/misc/troubleshooting/index.md +0 -82
- package/docs/overview/concepts/index.md +0 -78
- package/docs/overview/how-livestore-works/index.md +0 -56
- package/docs/overview/introduction/index.md +0 -5
- package/docs/overview/technology-comparison/index.md +0 -40
- package/docs/overview/when-livestore/index.md +0 -81
- package/docs/overview/why-livestore/index.md +0 -5
- package/docs/patterns/ai/index.md +0 -15
- package/docs/patterns/anonymous-user-transition/index.md +0 -10
- package/docs/patterns/app-evolution/index.md +0 -72
- package/docs/patterns/auth/index.md +0 -226
- package/docs/patterns/effect/index.md +0 -1495
- package/docs/patterns/encryption/index.md +0 -6
- package/docs/patterns/external-data/index.md +0 -5
- package/docs/patterns/file-management/index.md +0 -11
- package/docs/patterns/file-structure/index.md +0 -14
- package/docs/patterns/list-ordering/index.md +0 -369
- package/docs/patterns/offline/index.md +0 -32
- package/docs/patterns/orm/index.md +0 -18
- package/docs/patterns/presence/index.md +0 -11
- package/docs/patterns/rich-text-editing/index.md +0 -11
- package/docs/patterns/server-side-clients/index.md +0 -97
- package/docs/patterns/side-effects/index.md +0 -11
- package/docs/patterns/state-machines/index.md +0 -11
- package/docs/patterns/storybook/index.md +0 -192
- package/docs/patterns/undo-redo/index.md +0 -9
- package/docs/patterns/version-control/index.md +0 -8
- package/docs/platform-adapters/cloudflare-durable-object-adapter/index.md +0 -453
- package/docs/platform-adapters/electron-adapter/index.md +0 -15
- package/docs/platform-adapters/expo-adapter/index.md +0 -245
- package/docs/platform-adapters/node-adapter/index.md +0 -160
- package/docs/platform-adapters/tauri-adapter/index.md +0 -15
- package/docs/platform-adapters/web-adapter/index.md +0 -218
- package/docs/sustainable-open-source/contributing/docs/index.md +0 -94
- package/docs/sustainable-open-source/contributing/info/index.md +0 -63
- package/docs/sustainable-open-source/contributing/monorepo/index.md +0 -195
- package/docs/sustainable-open-source/sponsoring/index.md +0 -104
- package/docs/sync-providers/cloudflare/index.md +0 -773
- package/docs/sync-providers/custom/index.md +0 -65
- package/docs/sync-providers/electricsql/index.md +0 -159
- package/docs/sync-providers/s2/index.md +0 -230
- package/docs/tutorial/0-welcome/index.md +0 -48
- package/docs/tutorial/1-setup-starter-project/index.md +0 -105
- package/docs/tutorial/2-deploy-to-cloudflare/index.md +0 -195
- package/docs/tutorial/3-read-and-write-todos-via-livestore/index.md +0 -511
- package/docs/tutorial/4-sync-data-via-cloudflare/index.md +0 -210
- package/docs/tutorial/5-expand-business-logic/index.md +0 -174
- package/docs/tutorial/6-persist-ui-state/index.md +0 -453
- package/docs/tutorial/7-next-steps/index.md +0 -22
- package/docs/understanding-livestore/design-decisions/index.md +0 -33
- package/docs/understanding-livestore/event-sourcing/index.md +0 -40
|
@@ -1,471 +0,0 @@
|
|
|
1
|
-
# Getting started with LiveStore + Vue
|
|
2
|
-
|
|
3
|
-
{/* We're adjusting the package to use the dev version on the dev branch */}
|
|
4
|
-
export const manualInstallDepsStr = [
|
|
5
|
-
'@livestore/livestore' + versionNpmSuffix,
|
|
6
|
-
'@livestore/wa-sqlite' + versionNpmSuffix,
|
|
7
|
-
'@livestore/adapter-web' + versionNpmSuffix,
|
|
8
|
-
'@livestore/utils' + versionNpmSuffix,
|
|
9
|
-
'@livestore/peer-deps' + versionNpmSuffix,
|
|
10
|
-
'@livestore/devtools-vite' + versionNpmSuffix,
|
|
11
|
-
'slashv/vue-livestore' + versionNpmSuffix,
|
|
12
|
-
'vue',
|
|
13
|
-
'@vitejs/plugin-vue',
|
|
14
|
-
'vite-plugin-vue-devtools',
|
|
15
|
-
].join(' ')
|
|
16
|
-
|
|
17
|
-
## Prerequisites
|
|
18
|
-
|
|
19
|
-
- Recommended: Bun 1.2 or higher
|
|
20
|
-
- Node.js {MIN_NODE_VERSION} or higher
|
|
21
|
-
|
|
22
|
-
## About Vue integration
|
|
23
|
-
|
|
24
|
-
Vue integration is still in beta and being incubated as a separate repository. Please direct any issues or contributions to [Vue LiveStore](https://github.com/slashv/vue-livestore)
|
|
25
|
-
|
|
26
|
-
## Option A: Quick start
|
|
27
|
-
|
|
28
|
-
For a quick start, we recommend referencing the [playground](https://github.com/slashv/vue-livestore/tree/main/playground) folder in the Vue LiveStore repository.
|
|
29
|
-
|
|
30
|
-
## Option B: Existing project setup \{#existing-project-setup\}
|
|
31
|
-
|
|
32
|
-
<Steps>
|
|
33
|
-
|
|
34
|
-
1. **Install dependencies**
|
|
35
|
-
|
|
36
|
-
It's strongly recommended to use `bun` or `pnpm` for the simplest and most reliable dependency setup (see [note on package management](/misc/package-management) for more details).
|
|
37
|
-
|
|
38
|
-
<Tabs syncKey="package-manager">
|
|
39
|
-
<TabItem label="bun">
|
|
40
|
-
<Code code={'bun install ' + manualInstallDepsStr} lang="sh" />
|
|
41
|
-
</TabItem>
|
|
42
|
-
<TabItem label="pnpm">
|
|
43
|
-
<Code code={'pnpm add ' + manualInstallDepsStr} lang="sh" />
|
|
44
|
-
</TabItem>
|
|
45
|
-
<TabItem label="npm">
|
|
46
|
-
<Code code={'npm install ' + manualInstallDepsStr} lang="sh" />
|
|
47
|
-
</TabItem>
|
|
48
|
-
</Tabs>
|
|
49
|
-
|
|
50
|
-
2. **Update Vite config**
|
|
51
|
-
|
|
52
|
-
Add the following code to your `vite.config.js` file:
|
|
53
|
-
|
|
54
|
-
## `getting-started/vue/vite-config.ts`
|
|
55
|
-
|
|
56
|
-
```ts filename="getting-started/vue/vite-config.ts"
|
|
57
|
-
|
|
58
|
-
export default defineConfig({
|
|
59
|
-
plugins: [vue(), vueDevTools(), livestoreDevtoolsPlugin({ schemaPath: './src/livestore/schema.ts' })],
|
|
60
|
-
worker: { format: 'es' },
|
|
61
|
-
})
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
</Steps>
|
|
65
|
-
|
|
66
|
-
### Define your schema
|
|
67
|
-
|
|
68
|
-
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).
|
|
69
|
-
|
|
70
|
-
Here's an example schema:
|
|
71
|
-
|
|
72
|
-
## `getting-started/vue/livestore/schema.ts`
|
|
73
|
-
|
|
74
|
-
```ts filename="getting-started/vue/livestore/schema.ts"
|
|
75
|
-
|
|
76
|
-
export const tables = {
|
|
77
|
-
todos: State.SQLite.table({
|
|
78
|
-
name: 'todos',
|
|
79
|
-
columns: {
|
|
80
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
81
|
-
text: State.SQLite.text({ default: '' }),
|
|
82
|
-
completed: State.SQLite.boolean({ default: false }),
|
|
83
|
-
deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
|
|
84
|
-
},
|
|
85
|
-
}),
|
|
86
|
-
uiState: State.SQLite.clientDocument({
|
|
87
|
-
name: 'uiState',
|
|
88
|
-
schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
|
|
89
|
-
default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
|
|
90
|
-
}),
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
export const events = {
|
|
94
|
-
todoCreated: Events.synced({
|
|
95
|
-
name: 'v1.TodoCreated',
|
|
96
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
|
|
97
|
-
}),
|
|
98
|
-
todoCompleted: Events.synced({
|
|
99
|
-
name: 'v1.TodoCompleted',
|
|
100
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
101
|
-
}),
|
|
102
|
-
todoUncompleted: Events.synced({
|
|
103
|
-
name: 'v1.TodoUncompleted',
|
|
104
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
105
|
-
}),
|
|
106
|
-
todoDeleted: Events.synced({
|
|
107
|
-
name: 'v1.TodoDeleted',
|
|
108
|
-
schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
|
|
109
|
-
}),
|
|
110
|
-
todoClearedCompleted: Events.synced({
|
|
111
|
-
name: 'v1.TodoClearedCompleted',
|
|
112
|
-
schema: Schema.Struct({ deletedAt: Schema.Date }),
|
|
113
|
-
}),
|
|
114
|
-
uiStateSet: tables.uiState.set,
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
const materializers = State.SQLite.materializers(events, {
|
|
118
|
-
'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
|
|
119
|
-
'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
|
|
120
|
-
'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
|
|
121
|
-
'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
|
|
122
|
-
'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
|
|
123
|
-
})
|
|
124
|
-
|
|
125
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
126
|
-
|
|
127
|
-
export const schema = makeSchema({ events, state })
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### Create the LiveStore worker
|
|
131
|
-
|
|
132
|
-
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.
|
|
133
|
-
|
|
134
|
-
## `getting-started/vue/livestore/livestore.worker.ts`
|
|
135
|
-
|
|
136
|
-
```ts filename="getting-started/vue/livestore/livestore.worker.ts"
|
|
137
|
-
|
|
138
|
-
makeWorker({ schema })
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
### `getting-started/vue/livestore/schema.ts`
|
|
142
|
-
|
|
143
|
-
```ts filename="getting-started/vue/livestore/schema.ts"
|
|
144
|
-
|
|
145
|
-
export const tables = {
|
|
146
|
-
todos: State.SQLite.table({
|
|
147
|
-
name: 'todos',
|
|
148
|
-
columns: {
|
|
149
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
150
|
-
text: State.SQLite.text({ default: '' }),
|
|
151
|
-
completed: State.SQLite.boolean({ default: false }),
|
|
152
|
-
deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
|
|
153
|
-
},
|
|
154
|
-
}),
|
|
155
|
-
uiState: State.SQLite.clientDocument({
|
|
156
|
-
name: 'uiState',
|
|
157
|
-
schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
|
|
158
|
-
default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
|
|
159
|
-
}),
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
export const events = {
|
|
163
|
-
todoCreated: Events.synced({
|
|
164
|
-
name: 'v1.TodoCreated',
|
|
165
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
|
|
166
|
-
}),
|
|
167
|
-
todoCompleted: Events.synced({
|
|
168
|
-
name: 'v1.TodoCompleted',
|
|
169
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
170
|
-
}),
|
|
171
|
-
todoUncompleted: Events.synced({
|
|
172
|
-
name: 'v1.TodoUncompleted',
|
|
173
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
174
|
-
}),
|
|
175
|
-
todoDeleted: Events.synced({
|
|
176
|
-
name: 'v1.TodoDeleted',
|
|
177
|
-
schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
|
|
178
|
-
}),
|
|
179
|
-
todoClearedCompleted: Events.synced({
|
|
180
|
-
name: 'v1.TodoClearedCompleted',
|
|
181
|
-
schema: Schema.Struct({ deletedAt: Schema.Date }),
|
|
182
|
-
}),
|
|
183
|
-
uiStateSet: tables.uiState.set,
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
const materializers = State.SQLite.materializers(events, {
|
|
187
|
-
'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
|
|
188
|
-
'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
|
|
189
|
-
'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
|
|
190
|
-
'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
|
|
191
|
-
'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
|
|
192
|
-
})
|
|
193
|
-
|
|
194
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
195
|
-
|
|
196
|
-
export const schema = makeSchema({ events, state })
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
### Add the LiveStore provider
|
|
200
|
-
|
|
201
|
-
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.
|
|
202
|
-
|
|
203
|
-
Here's an example:
|
|
204
|
-
|
|
205
|
-
## `getting-started/vue/app.vue`
|
|
206
|
-
|
|
207
|
-
```vue filename="getting-started/vue/app.vue"
|
|
208
|
-
<script setup lang="ts">
|
|
209
|
-
|
|
210
|
-
const adapter = makePersistedAdapter({
|
|
211
|
-
storage: { type: 'opfs' },
|
|
212
|
-
worker: LiveStoreWorker,
|
|
213
|
-
sharedWorker: LiveStoreSharedWorker,
|
|
214
|
-
})
|
|
215
|
-
|
|
216
|
-
const storeOptions = {
|
|
217
|
-
schema,
|
|
218
|
-
adapter,
|
|
219
|
-
storeId: 'test_store',
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
void storeOptions
|
|
223
|
-
</script>
|
|
224
|
-
|
|
225
|
-
<template>
|
|
226
|
-
<LiveStoreProvider :options="storeOptions">
|
|
227
|
-
<template #loading>
|
|
228
|
-
<div>Loading LiveStore...</div>
|
|
229
|
-
</template>
|
|
230
|
-
<slot />
|
|
231
|
-
</LiveStoreProvider>
|
|
232
|
-
</template>
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
### `getting-started/vue/livestore/schema.ts`
|
|
236
|
-
|
|
237
|
-
```ts filename="getting-started/vue/livestore/schema.ts"
|
|
238
|
-
|
|
239
|
-
export const tables = {
|
|
240
|
-
todos: State.SQLite.table({
|
|
241
|
-
name: 'todos',
|
|
242
|
-
columns: {
|
|
243
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
244
|
-
text: State.SQLite.text({ default: '' }),
|
|
245
|
-
completed: State.SQLite.boolean({ default: false }),
|
|
246
|
-
deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
|
|
247
|
-
},
|
|
248
|
-
}),
|
|
249
|
-
uiState: State.SQLite.clientDocument({
|
|
250
|
-
name: 'uiState',
|
|
251
|
-
schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
|
|
252
|
-
default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
|
|
253
|
-
}),
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
export const events = {
|
|
257
|
-
todoCreated: Events.synced({
|
|
258
|
-
name: 'v1.TodoCreated',
|
|
259
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
|
|
260
|
-
}),
|
|
261
|
-
todoCompleted: Events.synced({
|
|
262
|
-
name: 'v1.TodoCompleted',
|
|
263
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
264
|
-
}),
|
|
265
|
-
todoUncompleted: Events.synced({
|
|
266
|
-
name: 'v1.TodoUncompleted',
|
|
267
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
268
|
-
}),
|
|
269
|
-
todoDeleted: Events.synced({
|
|
270
|
-
name: 'v1.TodoDeleted',
|
|
271
|
-
schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
|
|
272
|
-
}),
|
|
273
|
-
todoClearedCompleted: Events.synced({
|
|
274
|
-
name: 'v1.TodoClearedCompleted',
|
|
275
|
-
schema: Schema.Struct({ deletedAt: Schema.Date }),
|
|
276
|
-
}),
|
|
277
|
-
uiStateSet: tables.uiState.set,
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const materializers = State.SQLite.materializers(events, {
|
|
281
|
-
'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
|
|
282
|
-
'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
|
|
283
|
-
'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
|
|
284
|
-
'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
|
|
285
|
-
'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
|
|
286
|
-
})
|
|
287
|
-
|
|
288
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
289
|
-
|
|
290
|
-
export const schema = makeSchema({ events, state })
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
### Commit events
|
|
294
|
-
|
|
295
|
-
After wrapping your app with the `LiveStoreProvider`, you can use the `useStore` hook from any component to commit events.
|
|
296
|
-
|
|
297
|
-
Here's an example:
|
|
298
|
-
|
|
299
|
-
## `getting-started/vue/commit-events.vue`
|
|
300
|
-
|
|
301
|
-
```vue filename="getting-started/vue/commit-events.vue"
|
|
302
|
-
<script setup lang="ts">
|
|
303
|
-
|
|
304
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: Vue composables run at script setup level
|
|
305
|
-
const { store } = useStore()
|
|
306
|
-
|
|
307
|
-
const newTodoText = ref('')
|
|
308
|
-
|
|
309
|
-
const createTodo = () => {
|
|
310
|
-
store.commit(events.todoCreated({ id: crypto.randomUUID(), text: newTodoText.value }))
|
|
311
|
-
newTodoText.value = ''
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
void createTodo
|
|
315
|
-
</script>
|
|
316
|
-
|
|
317
|
-
<template>
|
|
318
|
-
<div>
|
|
319
|
-
<input v-model="newTodoText" />
|
|
320
|
-
<button @click="createTodo">Create</button>
|
|
321
|
-
</div>
|
|
322
|
-
</template>
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
### `getting-started/vue/livestore/schema.ts`
|
|
326
|
-
|
|
327
|
-
```ts filename="getting-started/vue/livestore/schema.ts"
|
|
328
|
-
|
|
329
|
-
export const tables = {
|
|
330
|
-
todos: State.SQLite.table({
|
|
331
|
-
name: 'todos',
|
|
332
|
-
columns: {
|
|
333
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
334
|
-
text: State.SQLite.text({ default: '' }),
|
|
335
|
-
completed: State.SQLite.boolean({ default: false }),
|
|
336
|
-
deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
|
|
337
|
-
},
|
|
338
|
-
}),
|
|
339
|
-
uiState: State.SQLite.clientDocument({
|
|
340
|
-
name: 'uiState',
|
|
341
|
-
schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
|
|
342
|
-
default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
|
|
343
|
-
}),
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
export const events = {
|
|
347
|
-
todoCreated: Events.synced({
|
|
348
|
-
name: 'v1.TodoCreated',
|
|
349
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
|
|
350
|
-
}),
|
|
351
|
-
todoCompleted: Events.synced({
|
|
352
|
-
name: 'v1.TodoCompleted',
|
|
353
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
354
|
-
}),
|
|
355
|
-
todoUncompleted: Events.synced({
|
|
356
|
-
name: 'v1.TodoUncompleted',
|
|
357
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
358
|
-
}),
|
|
359
|
-
todoDeleted: Events.synced({
|
|
360
|
-
name: 'v1.TodoDeleted',
|
|
361
|
-
schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
|
|
362
|
-
}),
|
|
363
|
-
todoClearedCompleted: Events.synced({
|
|
364
|
-
name: 'v1.TodoClearedCompleted',
|
|
365
|
-
schema: Schema.Struct({ deletedAt: Schema.Date }),
|
|
366
|
-
}),
|
|
367
|
-
uiStateSet: tables.uiState.set,
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const materializers = State.SQLite.materializers(events, {
|
|
371
|
-
'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
|
|
372
|
-
'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
|
|
373
|
-
'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
|
|
374
|
-
'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
|
|
375
|
-
'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
|
|
376
|
-
})
|
|
377
|
-
|
|
378
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
379
|
-
|
|
380
|
-
export const schema = makeSchema({ events, state })
|
|
381
|
-
```
|
|
382
|
-
|
|
383
|
-
### Queries
|
|
384
|
-
|
|
385
|
-
To retrieve data from the database, first define a query using `queryDb` from `@livestore/livestore`. Then, execute the query with the `useQuery` hook from `vue-livestore`.
|
|
386
|
-
|
|
387
|
-
Consider abstracting queries into a separate file to keep your code organized, though you can also define them directly within components if preferred.
|
|
388
|
-
|
|
389
|
-
Here's an example:
|
|
390
|
-
|
|
391
|
-
## `getting-started/vue/queries.vue`
|
|
392
|
-
|
|
393
|
-
```vue filename="getting-started/vue/queries.vue"
|
|
394
|
-
<script setup lang="ts">
|
|
395
|
-
|
|
396
|
-
const visibleTodos$ = queryDb(() => tables.todos.where({ completed: false }), { label: 'visibleTodos' })
|
|
397
|
-
|
|
398
|
-
// biome-ignore lint/correctness/useHookAtTopLevel: Vue composables run at script setup level
|
|
399
|
-
const todos = useQuery(visibleTodos$)
|
|
400
|
-
|
|
401
|
-
void todos
|
|
402
|
-
</script>
|
|
403
|
-
|
|
404
|
-
<template>
|
|
405
|
-
<div>
|
|
406
|
-
<ul>
|
|
407
|
-
<li v-for="todo in todos" :key="todo.id">
|
|
408
|
-
{{ todo.text }}
|
|
409
|
-
</li>
|
|
410
|
-
</ul>
|
|
411
|
-
</div>
|
|
412
|
-
</template>
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
### `getting-started/vue/livestore/schema.ts`
|
|
416
|
-
|
|
417
|
-
```ts filename="getting-started/vue/livestore/schema.ts"
|
|
418
|
-
|
|
419
|
-
export const tables = {
|
|
420
|
-
todos: State.SQLite.table({
|
|
421
|
-
name: 'todos',
|
|
422
|
-
columns: {
|
|
423
|
-
id: State.SQLite.text({ primaryKey: true }),
|
|
424
|
-
text: State.SQLite.text({ default: '' }),
|
|
425
|
-
completed: State.SQLite.boolean({ default: false }),
|
|
426
|
-
deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
|
|
427
|
-
},
|
|
428
|
-
}),
|
|
429
|
-
uiState: State.SQLite.clientDocument({
|
|
430
|
-
name: 'uiState',
|
|
431
|
-
schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
|
|
432
|
-
default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
|
|
433
|
-
}),
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
export const events = {
|
|
437
|
-
todoCreated: Events.synced({
|
|
438
|
-
name: 'v1.TodoCreated',
|
|
439
|
-
schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
|
|
440
|
-
}),
|
|
441
|
-
todoCompleted: Events.synced({
|
|
442
|
-
name: 'v1.TodoCompleted',
|
|
443
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
444
|
-
}),
|
|
445
|
-
todoUncompleted: Events.synced({
|
|
446
|
-
name: 'v1.TodoUncompleted',
|
|
447
|
-
schema: Schema.Struct({ id: Schema.String }),
|
|
448
|
-
}),
|
|
449
|
-
todoDeleted: Events.synced({
|
|
450
|
-
name: 'v1.TodoDeleted',
|
|
451
|
-
schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
|
|
452
|
-
}),
|
|
453
|
-
todoClearedCompleted: Events.synced({
|
|
454
|
-
name: 'v1.TodoClearedCompleted',
|
|
455
|
-
schema: Schema.Struct({ deletedAt: Schema.Date }),
|
|
456
|
-
}),
|
|
457
|
-
uiStateSet: tables.uiState.set,
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
const materializers = State.SQLite.materializers(events, {
|
|
461
|
-
'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
|
|
462
|
-
'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
|
|
463
|
-
'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
|
|
464
|
-
'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
|
|
465
|
-
'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
|
|
466
|
-
})
|
|
467
|
-
|
|
468
|
-
const state = State.SQLite.makeState({ tables, materializers })
|
|
469
|
-
|
|
470
|
-
export const schema = makeSchema({ events, state })
|
|
471
|
-
```
|
package/docs/index.md
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
# Docs
|
|
2
|
-
|
|
3
|
-
<CardGrid>
|
|
4
|
-
<LinkCard
|
|
5
|
-
title="Getting started"
|
|
6
|
-
description="Learn how to get started with LiveStore"
|
|
7
|
-
href="/getting-started/react-web"
|
|
8
|
-
/>
|
|
9
|
-
<LinkCard
|
|
10
|
-
title="Introduction"
|
|
11
|
-
description="Introduction to LiveStore"
|
|
12
|
-
href="/overview/introduction"
|
|
13
|
-
/>
|
|
14
|
-
<LinkCard
|
|
15
|
-
title="Evaluation"
|
|
16
|
-
description="Evaluate LiveStore for your use case"
|
|
17
|
-
href="/understanding-livestore/design-decisions"
|
|
18
|
-
/>
|
|
19
|
-
<LinkCard
|
|
20
|
-
title="Patterns"
|
|
21
|
-
description="A collection of patterns for using LiveStore in different scenarios"
|
|
22
|
-
href="/patterns/anonymous-user-transition/"
|
|
23
|
-
/>
|
|
24
|
-
<LinkCard
|
|
25
|
-
title="Community"
|
|
26
|
-
description="Community resources for LiveStore"
|
|
27
|
-
href="/misc/community"
|
|
28
|
-
/>
|
|
29
|
-
<LinkCard
|
|
30
|
-
title="Contributing"
|
|
31
|
-
description="Contributing to LiveStore"
|
|
32
|
-
href="/sustainable-open-source/contributing/info"
|
|
33
|
-
/>
|
|
34
|
-
</CardGrid>
|
|
35
|
-
|
|
36
|
-
## State of the documentation
|
|
37
|
-
|
|
38
|
-
Please note that the documentation is still work in progress with many parts missing and often only containing notes/bullet points.
|
|
39
|
-
|
|
40
|
-
### Docs for LLMs
|
|
41
|
-
|
|
42
|
-
We support the [llms.txt](https://llmstxt.org/) convention for making documentation available to large language models and the applications that make use of them.
|
|
43
|
-
|
|
44
|
-
Currently, we have the following root-level files:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
## Getting started
|
|
48
|
-
|
|
49
|
-
- [Getting started with LiveStore + React](/getting-started/react-web): How to use LiveStore with React on the web.
|
|
50
|
-
- [Expo](/getting-started/expo): Learn how to use LiveStore with Expo.
|
|
51
|
-
- [Node](/getting-started/node): Learn how to use LiveStore with Node.
|
|
52
|
-
- [Getting started with LiveStore + Vue](/getting-started/vue): How to use LiveStore with Vue.
|
|
53
|
-
- [Solid](/getting-started/solid): Learn how to use LiveStore with Solid.
|
|
54
|
-
|
|
55
|
-
## Tutorial
|
|
56
|
-
|
|
57
|
-
- [Overview and prerequisites](/tutorial/0-welcome)
|
|
58
|
-
- [1. Set up starter project with React, Vite & Tailwind](/tutorial/1-setup-starter-project)
|
|
59
|
-
- [2. Deploy to Cloudflare Workers](/tutorial/2-deploy-to-cloudflare)
|
|
60
|
-
- [3. Read and write todos via LiveStore](/tutorial/3-read-and-write-todos-via-livestore)
|
|
61
|
-
- [4. Sync data to Cloudflare](/tutorial/4-sync-data-via-cloudflare)
|
|
62
|
-
- [5. Expand business logic with more events](/tutorial/5-expand-business-logic)
|
|
63
|
-
- [6. Persist UI state](/tutorial/6-persist-ui-state)
|
|
64
|
-
- [Next steps](/tutorial/7-next-steps)
|
|
65
|
-
|
|
66
|
-
## Overview
|
|
67
|
-
|
|
68
|
-
- [Introduction](/overview/introduction)
|
|
69
|
-
- [Why LiveStore?](/overview/why-livestore)
|
|
70
|
-
- [How LiveStore works](/overview/how-livestore-works)
|
|
71
|
-
- [Concepts](/overview/concepts): Concepts in LiveStore
|
|
72
|
-
- [When to use LiveStore (and when not)](/overview/when-livestore): Considerations when deciding to use LiveStore.
|
|
73
|
-
- [Technology comparison](/overview/technology-comparison): How LiveStore compares to other related technologies
|
|
74
|
-
|
|
75
|
-
## Building with LiveStore
|
|
76
|
-
|
|
77
|
-
- [Rules for AI agents](/building-with-livestore/rules-for-ai-agents)
|
|
78
|
-
- [Events](/building-with-livestore/events)
|
|
79
|
-
- [Data modeling](/building-with-livestore/data-modeling)
|
|
80
|
-
- [CRUD](/building-with-livestore/crud): CRUD
|
|
81
|
-
- [Store](/building-with-livestore/store)
|
|
82
|
-
- [Complex UI state](/building-with-livestore/complex-ui-state): How to model complex UI state in LiveStore.
|
|
83
|
-
- [Reactivity system](/building-with-livestore/reactivity-system)
|
|
84
|
-
- [Syncing](/building-with-livestore/syncing): Syncing
|
|
85
|
-
- [Debugging a LiveStore app](/building-with-livestore/debugging)
|
|
86
|
-
- [Devtools](/building-with-livestore/devtools)
|
|
87
|
-
- [OpenTelemetry](/building-with-livestore/opentelemetry)
|
|
88
|
-
- [Production checklist](/building-with-livestore/production-checklist): Checklist for productionizing a LiveStore app
|
|
89
|
-
|
|
90
|
-
### State
|
|
91
|
-
|
|
92
|
-
- [SQLite state schema](/building-with-livestore/state/sqlite-schema)
|
|
93
|
-
- [SQLite state schema (Effect schema)](/building-with-livestore/state/sqlite-schema-effect)
|
|
94
|
-
- [SQL queries](/building-with-livestore/state/sql-queries)
|
|
95
|
-
- [Materializers](/building-with-livestore/state/materializers)
|
|
96
|
-
- [SQLite in LiveStore](/building-with-livestore/state/sqlite): Notes on how to use SQLite in LiveStore
|
|
97
|
-
|
|
98
|
-
### Tools
|
|
99
|
-
|
|
100
|
-
- [LiveStore CLI](/building-with-livestore/tools/cli): Command-line interface for LiveStore project scaffolding and development tools.
|
|
101
|
-
- [MCP integration](/building-with-livestore/tools/mcp): Model Context Protocol integration for AI assistants like Claude.
|
|
102
|
-
|
|
103
|
-
### Examples
|
|
104
|
-
|
|
105
|
-
- [Data modeling](/building-with-livestore/examples): How to model data in LiveStore.
|
|
106
|
-
- [Todo app with shared workspaces](/building-with-livestore/examples/todo-workspaces): How to model a todo workspace app with shared workspaces in LiveStore.
|
|
107
|
-
- [Turn-based game](/building-with-livestore/examples/turnbased-game): How to model a turn-based game in LiveStore.
|
|
108
|
-
- [AI agent](/building-with-livestore/examples/ai-agent): How to model an AI agent in LiveStore.
|
|
109
|
-
|
|
110
|
-
## Framework integrations
|
|
111
|
-
|
|
112
|
-
- [React integration for LiveStore](/framework-integrations/react-integration): How to integrate LiveStore with React.
|
|
113
|
-
- [Custom elements](/framework-integrations/custom-elements): How to integrate LiveStore with Custom Elements aka Web Components.
|
|
114
|
-
- [Svelte integration](/framework-integrations/svelte-integration): How to integrate LiveStore with Svelte.
|
|
115
|
-
- [Vue integration for LiveStore](/framework-integrations/vue-integration): How to integrate LiveStore with Vue.
|
|
116
|
-
- [Solid integration](/framework-integrations/solid-integration): How to integrate LiveStore with Solid.
|
|
117
|
-
|
|
118
|
-
## Platform adapters
|
|
119
|
-
|
|
120
|
-
- [Web adapter](/platform-adapters/web-adapter): Information about LiveStore's web adapter
|
|
121
|
-
- [Expo Adapter](/platform-adapters/expo-adapter): LiveStore adapter for React Native apps built with Expo
|
|
122
|
-
- [Node adapter](/platform-adapters/node-adapter)
|
|
123
|
-
- [Cloudflare Durable Object adapter](/platform-adapters/cloudflare-durable-object-adapter)
|
|
124
|
-
- [Tauri adapter](/platform-adapters/tauri-adapter)
|
|
125
|
-
- [Electron adapter](/platform-adapters/electron-adapter)
|
|
126
|
-
|
|
127
|
-
## Sync providers
|
|
128
|
-
|
|
129
|
-
- [Cloudflare Workers](/sync-providers/cloudflare)
|
|
130
|
-
- [ElectricSQL](/sync-providers/electricsql)
|
|
131
|
-
- [S2](/sync-providers/s2): Use the official S2 backend with LiveStore via @livestore/sync-s2
|
|
132
|
-
- [Build your own sync provider](/sync-providers/custom)
|
|
133
|
-
|
|
134
|
-
## Patterns
|
|
135
|
-
|
|
136
|
-
- [Server-side clients](/patterns/server-side-clients)
|
|
137
|
-
- [Encryption](/patterns/encryption)
|
|
138
|
-
- [Effect](/patterns/effect)
|
|
139
|
-
- [Rich Text Editing](/patterns/rich-text-editing)
|
|
140
|
-
- [Auth](/patterns/auth)
|
|
141
|
-
- [Rich text editing](/patterns/rich-text-editing)
|
|
142
|
-
- [List Ordering](/patterns/list-ordering): Implement drag-and-drop list ordering with fractional indexing
|
|
143
|
-
- [External data](/patterns/external-data)
|
|
144
|
-
- [Offline support](/patterns/offline)
|
|
145
|
-
- [Side effect](/patterns/side-effects): How to run side-effects for LiveStore events
|
|
146
|
-
- [Version control](/patterns/version-control)
|
|
147
|
-
- [Anonymous user transition](/patterns/anonymous-user-transition): How to transition an anonymous user to a logged in user
|
|
148
|
-
- [File management](/patterns/file-management): How to manage files with LiveStore
|
|
149
|
-
- [State machines](/patterns/state-machines): How to use state machines with LiveStore
|
|
150
|
-
- [App evolution](/patterns/app-evolution): How to evolve your app and roll out new app versions
|
|
151
|
-
- [Storybook testing (React)](/patterns/storybook): How to set up LiveStore with Storybook for component development and testing in React.
|
|
152
|
-
- [Undo/Redo](/patterns/undo-redo): How to implement undo/redo functionality with LiveStore
|
|
153
|
-
- [File structure](/patterns/file-structure)
|
|
154
|
-
- [Presence](/patterns/presence): How to implement presence functionality with LiveStore
|
|
155
|
-
- [ORM](/patterns/orm): How to use an ORM with LiveStore
|
|
156
|
-
- [AI](/patterns/ai): How to use LiveStore to build AI applications
|
|
157
|
-
|
|
158
|
-
## Understanding LiveStore
|
|
159
|
-
|
|
160
|
-
- [Event sourcing](/understanding-livestore/event-sourcing): Why and how LiveStore uses event sourcing for data flow, syncing and migrations.
|
|
161
|
-
- [Design decisions](/understanding-livestore/design-decisions): Design decisions and trade-offs made in the development of LiveStore
|
|
162
|
-
|
|
163
|
-
## Sustainable open source
|
|
164
|
-
|
|
165
|
-
- [Sponsoring LiveStore](/sustainable-open-source/sponsoring)
|
|
166
|
-
|
|
167
|
-
### Contributing
|
|
168
|
-
|
|
169
|
-
- [Info](/sustainable-open-source/contributing/info): Notes for developers interested in contributing to LiveStore.
|
|
170
|
-
- [Monorepo](/sustainable-open-source/contributing/monorepo): Notes on the monorepo setup of LiveStore.
|
|
171
|
-
- [Docs](/sustainable-open-source/contributing/docs): Notes on contributing to the LiveStore docs
|
|
172
|
-
|
|
173
|
-
## Miscellaneous
|
|
174
|
-
|
|
175
|
-
- [Frequently asked questions](/misc/FAQ): Frequently asked questions about LiveStore
|
|
176
|
-
- [State of the project](/misc/state-of-the-project): A high-level overview of the current state of the project.
|
|
177
|
-
- [Performance](/misc/performance)
|
|
178
|
-
- [Community](/misc/community)
|
|
179
|
-
- [Troubleshooting](/misc/troubleshooting): Common issues in apps using LiveStore and possible solutions.
|
|
180
|
-
- [Credits](/misc/credits): Credits and acknowledgements
|
|
181
|
-
- [Resources](/misc/resources): Resources, assets, logos, etc about LiveStore
|
|
182
|
-
- [Design partners](/misc/design-partners)
|
|
183
|
-
- [Code of conduct](/misc/CODE_OF_CONDUCT): Our code of conduct for the LiveStore community.
|
|
184
|
-
- [Note on package management](/misc/package-management)
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
### npm packages
|
|
188
|
-
|
|
189
|
-
- Main package: <NpmLink packageName="livestore" />
|
|
190
|
-
- Framework integrations:
|
|
191
|
-
- React: <NpmLink packageName="react" />
|
|
192
|
-
- Solid: <NpmLink packageName="solid" />
|
|
193
|
-
- Platform adapters:
|
|
194
|
-
- Web: <NpmLink packageName="adapter-web" />
|
|
195
|
-
- Expo: <NpmLink packageName="adapter-expo" />
|
|
196
|
-
- Node: <NpmLink packageName="adapter-node" />
|
|
197
|
-
- Sync provider:
|
|
198
|
-
- Cloudflare: <NpmLink packageName="sync-cf" />
|
|
199
|
-
- Electric: <NpmLink packageName="sync-electric" />
|
|
200
|
-
- Devtools:
|
|
201
|
-
- Vite: <NpmLink packageName="devtools-vite" />
|
|
202
|
-
- Expo: <NpmLink packageName="devtools-expo" />
|
|
203
|
-
- SQLite packages:
|
|
204
|
-
- sqlite-wasm (wrapper around wa-sqlite): <NpmLink packageName="sqlite-wasm" />
|
|
205
|
-
- wa-sqlite fork: <NpmLink packageName="wa-sqlite" />
|
|
206
|
-
- Internal packages:
|
|
207
|
-
- <NpmLink packageName="peer-deps" />
|
|
208
|
-
- <NpmLink packageName="utils" />
|
|
209
|
-
- <NpmLink packageName="common" />
|