@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.
Files changed (216) hide show
  1. package/README.md +0 -1
  2. package/dist/.tsbuildinfo +1 -1
  3. package/dist/QueryCache.js +1 -1
  4. package/dist/QueryCache.js.map +1 -1
  5. package/dist/SqliteDbWrapper.d.ts +5 -5
  6. package/dist/SqliteDbWrapper.d.ts.map +1 -1
  7. package/dist/SqliteDbWrapper.js +8 -8
  8. package/dist/SqliteDbWrapper.js.map +1 -1
  9. package/dist/SqliteDbWrapper.test.js +2 -2
  10. package/dist/SqliteDbWrapper.test.js.map +1 -1
  11. package/dist/effect/LiveStore.d.ts +130 -2
  12. package/dist/effect/LiveStore.d.ts.map +1 -1
  13. package/dist/effect/LiveStore.js +185 -6
  14. package/dist/effect/LiveStore.js.map +1 -1
  15. package/dist/effect/LiveStore.test.d.ts +2 -0
  16. package/dist/effect/LiveStore.test.d.ts.map +1 -0
  17. package/dist/effect/LiveStore.test.js +42 -0
  18. package/dist/effect/LiveStore.test.js.map +1 -0
  19. package/dist/effect/mod.d.ts +1 -1
  20. package/dist/effect/mod.d.ts.map +1 -1
  21. package/dist/effect/mod.js +3 -1
  22. package/dist/effect/mod.js.map +1 -1
  23. package/dist/live-queries/base-class.d.ts +3 -3
  24. package/dist/live-queries/base-class.d.ts.map +1 -1
  25. package/dist/live-queries/base-class.js +2 -2
  26. package/dist/live-queries/base-class.js.map +1 -1
  27. package/dist/live-queries/client-document-get-query.d.ts +1 -1
  28. package/dist/live-queries/client-document-get-query.d.ts.map +1 -1
  29. package/dist/live-queries/client-document-get-query.js +1 -1
  30. package/dist/live-queries/client-document-get-query.js.map +1 -1
  31. package/dist/live-queries/computed.d.ts.map +1 -1
  32. package/dist/live-queries/computed.js +2 -2
  33. package/dist/live-queries/computed.js.map +1 -1
  34. package/dist/live-queries/db-query.js +14 -14
  35. package/dist/live-queries/db-query.js.map +1 -1
  36. package/dist/live-queries/db-query.test.js +2 -2
  37. package/dist/live-queries/db-query.test.js.map +1 -1
  38. package/dist/live-queries/signal.test.js +2 -2
  39. package/dist/live-queries/signal.test.js.map +1 -1
  40. package/dist/mod.d.ts +2 -1
  41. package/dist/mod.d.ts.map +1 -1
  42. package/dist/mod.js +1 -0
  43. package/dist/mod.js.map +1 -1
  44. package/dist/reactive.d.ts +9 -9
  45. package/dist/reactive.d.ts.map +1 -1
  46. package/dist/reactive.js +9 -26
  47. package/dist/reactive.js.map +1 -1
  48. package/dist/reactive.test.js +2 -2
  49. package/dist/reactive.test.js.map +1 -1
  50. package/dist/store/StoreRegistry.d.ts +215 -0
  51. package/dist/store/StoreRegistry.d.ts.map +1 -0
  52. package/dist/store/StoreRegistry.js +267 -0
  53. package/dist/store/StoreRegistry.js.map +1 -0
  54. package/dist/store/StoreRegistry.test.d.ts +2 -0
  55. package/dist/store/StoreRegistry.test.d.ts.map +1 -0
  56. package/dist/store/StoreRegistry.test.js +381 -0
  57. package/dist/store/StoreRegistry.test.js.map +1 -0
  58. package/dist/store/create-store.d.ts +56 -6
  59. package/dist/store/create-store.d.ts.map +1 -1
  60. package/dist/store/create-store.js +32 -7
  61. package/dist/store/create-store.js.map +1 -1
  62. package/dist/store/devtools.d.ts +1 -1
  63. package/dist/store/devtools.d.ts.map +1 -1
  64. package/dist/store/devtools.js +16 -3
  65. package/dist/store/devtools.js.map +1 -1
  66. package/dist/store/store-eventstream.test.js +2 -2
  67. package/dist/store/store-eventstream.test.js.map +1 -1
  68. package/dist/store/store-types.d.ts +59 -9
  69. package/dist/store/store-types.d.ts.map +1 -1
  70. package/dist/store/store-types.js.map +1 -1
  71. package/dist/store/store-types.test.js +1 -1
  72. package/dist/store/store-types.test.js.map +1 -1
  73. package/dist/store/store.d.ts +102 -6
  74. package/dist/store/store.d.ts.map +1 -1
  75. package/dist/store/store.js +148 -47
  76. package/dist/store/store.js.map +1 -1
  77. package/dist/utils/dev.js.map +1 -1
  78. package/dist/utils/stack-info.js +2 -2
  79. package/dist/utils/stack-info.js.map +1 -1
  80. package/dist/utils/tests/fixture.d.ts +1 -1
  81. package/dist/utils/tests/fixture.d.ts.map +1 -1
  82. package/dist/utils/tests/fixture.js.map +1 -1
  83. package/dist/utils/tests/otel.d.ts.map +1 -1
  84. package/dist/utils/tests/otel.js +5 -5
  85. package/dist/utils/tests/otel.js.map +1 -1
  86. package/package.json +59 -18
  87. package/src/QueryCache.ts +1 -1
  88. package/src/SqliteDbWrapper.test.ts +4 -2
  89. package/src/SqliteDbWrapper.ts +12 -11
  90. package/src/ambient.d.ts +0 -7
  91. package/src/effect/LiveStore.test.ts +61 -0
  92. package/src/effect/LiveStore.ts +381 -8
  93. package/src/effect/mod.ts +13 -1
  94. package/src/live-queries/__snapshots__/db-query.test.ts.snap +336 -231
  95. package/src/live-queries/base-class.ts +7 -6
  96. package/src/live-queries/client-document-get-query.ts +4 -2
  97. package/src/live-queries/computed.ts +3 -2
  98. package/src/live-queries/db-query.test.ts +3 -2
  99. package/src/live-queries/db-query.ts +15 -15
  100. package/src/live-queries/signal.test.ts +3 -2
  101. package/src/mod.ts +2 -0
  102. package/src/reactive.test.ts +3 -2
  103. package/src/reactive.ts +22 -23
  104. package/src/store/StoreRegistry.test.ts +540 -0
  105. package/src/store/StoreRegistry.ts +418 -0
  106. package/src/store/create-store.ts +76 -15
  107. package/src/store/devtools.ts +20 -6
  108. package/src/store/store-eventstream.test.ts +4 -2
  109. package/src/store/store-types.test.ts +3 -1
  110. package/src/store/store-types.ts +64 -13
  111. package/src/store/store.ts +197 -60
  112. package/src/utils/dev.ts +2 -2
  113. package/src/utils/stack-info.ts +2 -2
  114. package/src/utils/tests/fixture.ts +2 -1
  115. package/src/utils/tests/otel.ts +8 -7
  116. package/docs/api/index.md +0 -3
  117. package/docs/building-with-livestore/complex-ui-state/index.md +0 -5
  118. package/docs/building-with-livestore/crud/index.md +0 -5
  119. package/docs/building-with-livestore/data-modeling/index.md +0 -1
  120. package/docs/building-with-livestore/debugging/index.md +0 -17
  121. package/docs/building-with-livestore/devtools/index.md +0 -79
  122. package/docs/building-with-livestore/events/index.md +0 -355
  123. package/docs/building-with-livestore/examples/ai-agent/index.md +0 -5
  124. package/docs/building-with-livestore/examples/index.md +0 -30
  125. package/docs/building-with-livestore/examples/todo-workspaces/index.md +0 -891
  126. package/docs/building-with-livestore/examples/turnbased-game/index.md +0 -7
  127. package/docs/building-with-livestore/opentelemetry/index.md +0 -208
  128. package/docs/building-with-livestore/production-checklist/index.md +0 -5
  129. package/docs/building-with-livestore/reactivity-system/index.md +0 -202
  130. package/docs/building-with-livestore/rules-for-ai-agents/index.md +0 -9
  131. package/docs/building-with-livestore/state/materializers/index.md +0 -300
  132. package/docs/building-with-livestore/state/sql-queries/index.md +0 -72
  133. package/docs/building-with-livestore/state/sqlite/index.md +0 -45
  134. package/docs/building-with-livestore/state/sqlite-schema/index.md +0 -306
  135. package/docs/building-with-livestore/state/sqlite-schema-effect/index.md +0 -300
  136. package/docs/building-with-livestore/store/index.md +0 -281
  137. package/docs/building-with-livestore/syncing/index.md +0 -136
  138. package/docs/building-with-livestore/tools/cli/index.md +0 -177
  139. package/docs/building-with-livestore/tools/mcp/index.md +0 -187
  140. package/docs/examples/cloudflare-adapter/index.md +0 -44
  141. package/docs/examples/expo-adapter/index.md +0 -44
  142. package/docs/examples/index.md +0 -55
  143. package/docs/examples/node-adapter/index.md +0 -44
  144. package/docs/examples/web-adapter/index.md +0 -52
  145. package/docs/framework-integrations/custom-elements/index.md +0 -142
  146. package/docs/framework-integrations/react-integration/index.md +0 -918
  147. package/docs/framework-integrations/solid-integration/index.md +0 -293
  148. package/docs/framework-integrations/svelte-integration/index.md +0 -42
  149. package/docs/framework-integrations/vue-integration/index.md +0 -294
  150. package/docs/getting-started/expo/index.md +0 -736
  151. package/docs/getting-started/node/index.md +0 -115
  152. package/docs/getting-started/react-web/index.md +0 -573
  153. package/docs/getting-started/solid/index.md +0 -3
  154. package/docs/getting-started/vue/index.md +0 -471
  155. package/docs/index.md +0 -209
  156. package/docs/llms.txt +0 -147
  157. package/docs/misc/CODE_OF_CONDUCT/index.md +0 -133
  158. package/docs/misc/FAQ/index.md +0 -37
  159. package/docs/misc/community/index.md +0 -88
  160. package/docs/misc/credits/index.md +0 -14
  161. package/docs/misc/design-partners/index.md +0 -13
  162. package/docs/misc/package-management/index.md +0 -21
  163. package/docs/misc/performance/index.md +0 -25
  164. package/docs/misc/resources/index.md +0 -46
  165. package/docs/misc/state-of-the-project/index.md +0 -37
  166. package/docs/misc/troubleshooting/index.md +0 -82
  167. package/docs/overview/concepts/index.md +0 -78
  168. package/docs/overview/how-livestore-works/index.md +0 -56
  169. package/docs/overview/introduction/index.md +0 -5
  170. package/docs/overview/technology-comparison/index.md +0 -40
  171. package/docs/overview/when-livestore/index.md +0 -81
  172. package/docs/overview/why-livestore/index.md +0 -5
  173. package/docs/patterns/ai/index.md +0 -15
  174. package/docs/patterns/anonymous-user-transition/index.md +0 -10
  175. package/docs/patterns/app-evolution/index.md +0 -72
  176. package/docs/patterns/auth/index.md +0 -226
  177. package/docs/patterns/effect/index.md +0 -1495
  178. package/docs/patterns/encryption/index.md +0 -6
  179. package/docs/patterns/external-data/index.md +0 -5
  180. package/docs/patterns/file-management/index.md +0 -11
  181. package/docs/patterns/file-structure/index.md +0 -14
  182. package/docs/patterns/list-ordering/index.md +0 -369
  183. package/docs/patterns/offline/index.md +0 -32
  184. package/docs/patterns/orm/index.md +0 -18
  185. package/docs/patterns/presence/index.md +0 -11
  186. package/docs/patterns/rich-text-editing/index.md +0 -11
  187. package/docs/patterns/server-side-clients/index.md +0 -97
  188. package/docs/patterns/side-effects/index.md +0 -11
  189. package/docs/patterns/state-machines/index.md +0 -11
  190. package/docs/patterns/storybook/index.md +0 -192
  191. package/docs/patterns/undo-redo/index.md +0 -9
  192. package/docs/patterns/version-control/index.md +0 -8
  193. package/docs/platform-adapters/cloudflare-durable-object-adapter/index.md +0 -453
  194. package/docs/platform-adapters/electron-adapter/index.md +0 -15
  195. package/docs/platform-adapters/expo-adapter/index.md +0 -245
  196. package/docs/platform-adapters/node-adapter/index.md +0 -160
  197. package/docs/platform-adapters/tauri-adapter/index.md +0 -15
  198. package/docs/platform-adapters/web-adapter/index.md +0 -218
  199. package/docs/sustainable-open-source/contributing/docs/index.md +0 -94
  200. package/docs/sustainable-open-source/contributing/info/index.md +0 -63
  201. package/docs/sustainable-open-source/contributing/monorepo/index.md +0 -195
  202. package/docs/sustainable-open-source/sponsoring/index.md +0 -104
  203. package/docs/sync-providers/cloudflare/index.md +0 -773
  204. package/docs/sync-providers/custom/index.md +0 -65
  205. package/docs/sync-providers/electricsql/index.md +0 -159
  206. package/docs/sync-providers/s2/index.md +0 -230
  207. package/docs/tutorial/0-welcome/index.md +0 -48
  208. package/docs/tutorial/1-setup-starter-project/index.md +0 -105
  209. package/docs/tutorial/2-deploy-to-cloudflare/index.md +0 -195
  210. package/docs/tutorial/3-read-and-write-todos-via-livestore/index.md +0 -511
  211. package/docs/tutorial/4-sync-data-via-cloudflare/index.md +0 -210
  212. package/docs/tutorial/5-expand-business-logic/index.md +0 -174
  213. package/docs/tutorial/6-persist-ui-state/index.md +0 -453
  214. package/docs/tutorial/7-next-steps/index.md +0 -22
  215. package/docs/understanding-livestore/design-decisions/index.md +0 -33
  216. package/docs/understanding-livestore/event-sourcing/index.md +0 -40
@@ -1,293 +0,0 @@
1
- # Solid integration
2
-
3
- ## Example
4
-
5
- See [examples](/examples) for a complete example.
6
-
7
- ## `reference/solid-integration/livestore/store.ts`
8
-
9
- ```ts filename="reference/solid-integration/livestore/store.ts"
10
-
11
- const adapter = makePersistedAdapter({
12
- storage: { type: 'opfs' },
13
- worker: LiveStoreWorker,
14
- sharedWorker: LiveStoreSharedWorker,
15
- })
16
-
17
- export const store = await getStore({
18
- adapter,
19
- schema,
20
- storeId: 'default',
21
- })
22
- ```
23
-
24
- ### `reference/solid-integration/livestore/schema.ts`
25
-
26
- ```ts filename="reference/solid-integration/livestore/schema.ts"
27
-
28
- export const tables = {
29
- todos: State.SQLite.table({
30
- name: 'todos',
31
- columns: {
32
- id: State.SQLite.text({ primaryKey: true }),
33
- text: State.SQLite.text({ default: '' }),
34
- completed: State.SQLite.boolean({ default: false }),
35
- deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
36
- },
37
- }),
38
- uiState: State.SQLite.clientDocument({
39
- name: 'uiState',
40
- schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
41
- default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
42
- }),
43
- }
44
-
45
- export const events = {
46
- todoCreated: Events.synced({
47
- name: 'v1.TodoCreated',
48
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
49
- }),
50
- todoCompleted: Events.synced({
51
- name: 'v1.TodoCompleted',
52
- schema: Schema.Struct({ id: Schema.String }),
53
- }),
54
- todoUncompleted: Events.synced({
55
- name: 'v1.TodoUncompleted',
56
- schema: Schema.Struct({ id: Schema.String }),
57
- }),
58
- todoDeleted: Events.synced({
59
- name: 'v1.TodoDeleted',
60
- schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
61
- }),
62
- todoClearedCompleted: Events.synced({
63
- name: 'v1.TodoClearedCompleted',
64
- schema: Schema.Struct({ deletedAt: Schema.Date }),
65
- }),
66
- uiStateSet: tables.uiState.set,
67
- }
68
-
69
- const materializers = State.SQLite.materializers(events, {
70
- 'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
71
- 'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
72
- 'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
73
- 'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
74
- 'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
75
- })
76
-
77
- const state = State.SQLite.makeState({ tables, materializers })
78
-
79
- export const schema = makeSchema({ events, state })
80
- ```
81
-
82
- ## `reference/solid-integration/MainSection.tsx`
83
-
84
- ```tsx filename="reference/solid-integration/MainSection.tsx"
85
- /** biome-ignore-all lint/a11y/noLabelWithoutControl: TODO 🫠 */
86
- /** @jsxImportSource solid-js */
87
-
88
- export const MainSection: Component = () => {
89
- const todos = query(visibleTodos$, [] as (typeof tables.todos.Type)[])
90
- const todoItems = () => todos() ?? ([] as (typeof tables.todos.Type)[])
91
-
92
- const toggleTodo = ({ id, completed }: typeof tables.todos.Type) =>
93
- store()?.commit(completed ? events.todoUncompleted({ id }) : events.todoCompleted({ id }))
94
-
95
- const deleteTodo = (id: string) => store()?.commit(events.todoDeleted({ id, deletedAt: new Date() }))
96
-
97
- return (
98
- <section class="main">
99
- <ul class="todo-list">
100
- <For each={todoItems()}>
101
- {(todo: typeof tables.todos.Type) => (
102
- <li>
103
- <div class="view">
104
- <input type="checkbox" class="toggle" checked={todo.completed} onChange={() => toggleTodo(todo)} />
105
- <label>{todo.text}</label>
106
- <button type="button" class="destroy" onClick={() => deleteTodo(todo.id)} />
107
- </div>
108
- </li>
109
- )}
110
- </For>
111
- </ul>
112
- </section>
113
- )
114
- }
115
- ```
116
-
117
- ### `reference/solid-integration/livestore/queries.ts`
118
-
119
- ```ts filename="reference/solid-integration/livestore/queries.ts"
120
-
121
- export const uiState$ = queryDb(tables.uiState.get(), { label: 'uiState' })
122
-
123
- export const visibleTodos$ = queryDb(
124
- (get) => {
125
- const { filter } = get(uiState$)
126
-
127
- return tables.todos.where({
128
- deletedAt: null,
129
- completed: filter === 'all' ? undefined : filter === 'completed',
130
- })
131
- },
132
- { label: 'visibleTodos' },
133
- )
134
- ```
135
-
136
- ### `reference/solid-integration/livestore/schema.ts`
137
-
138
- ```ts filename="reference/solid-integration/livestore/schema.ts"
139
-
140
- export const tables = {
141
- todos: State.SQLite.table({
142
- name: 'todos',
143
- columns: {
144
- id: State.SQLite.text({ primaryKey: true }),
145
- text: State.SQLite.text({ default: '' }),
146
- completed: State.SQLite.boolean({ default: false }),
147
- deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
148
- },
149
- }),
150
- uiState: State.SQLite.clientDocument({
151
- name: 'uiState',
152
- schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
153
- default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
154
- }),
155
- }
156
-
157
- export const events = {
158
- todoCreated: Events.synced({
159
- name: 'v1.TodoCreated',
160
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
161
- }),
162
- todoCompleted: Events.synced({
163
- name: 'v1.TodoCompleted',
164
- schema: Schema.Struct({ id: Schema.String }),
165
- }),
166
- todoUncompleted: Events.synced({
167
- name: 'v1.TodoUncompleted',
168
- schema: Schema.Struct({ id: Schema.String }),
169
- }),
170
- todoDeleted: Events.synced({
171
- name: 'v1.TodoDeleted',
172
- schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
173
- }),
174
- todoClearedCompleted: Events.synced({
175
- name: 'v1.TodoClearedCompleted',
176
- schema: Schema.Struct({ deletedAt: Schema.Date }),
177
- }),
178
- uiStateSet: tables.uiState.set,
179
- }
180
-
181
- const materializers = State.SQLite.materializers(events, {
182
- 'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
183
- 'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
184
- 'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
185
- 'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
186
- 'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
187
- })
188
-
189
- const state = State.SQLite.makeState({ tables, materializers })
190
-
191
- export const schema = makeSchema({ events, state })
192
- ```
193
-
194
- ### `reference/solid-integration/livestore/store.ts`
195
-
196
- ```ts filename="reference/solid-integration/livestore/store.ts"
197
-
198
- const adapter = makePersistedAdapter({
199
- storage: { type: 'opfs' },
200
- worker: LiveStoreWorker,
201
- sharedWorker: LiveStoreSharedWorker,
202
- })
203
-
204
- export const store = await getStore({
205
- adapter,
206
- schema,
207
- storeId: 'default',
208
- })
209
- ```
210
-
211
- ### Logging
212
-
213
- You can control logging for Solid's runtime helpers via optional options passed to `getStore`:
214
-
215
- ## `reference/solid-integration/store-logging.ts`
216
-
217
- ```ts filename="reference/solid-integration/store-logging.ts"
218
-
219
- // ---cut---
220
-
221
- const adapter = makePersistedAdapter({
222
- storage: { type: 'opfs' },
223
- worker: LiveStoreWorker,
224
- sharedWorker: LiveStoreSharedWorker,
225
- })
226
-
227
- const _store = await getStore({
228
- schema,
229
- adapter,
230
- storeId: 'default',
231
- // Optional: swap logger and minimum log level
232
- logger: Logger.prettyWithThread('window'),
233
- logLevel: LogLevel.Info, // use LogLevel.None to disable logs
234
- })
235
- ```
236
-
237
- ### `reference/solid-integration/livestore/schema.ts`
238
-
239
- ```ts filename="reference/solid-integration/livestore/schema.ts"
240
-
241
- export const tables = {
242
- todos: State.SQLite.table({
243
- name: 'todos',
244
- columns: {
245
- id: State.SQLite.text({ primaryKey: true }),
246
- text: State.SQLite.text({ default: '' }),
247
- completed: State.SQLite.boolean({ default: false }),
248
- deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
249
- },
250
- }),
251
- uiState: State.SQLite.clientDocument({
252
- name: 'uiState',
253
- schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
254
- default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
255
- }),
256
- }
257
-
258
- export const events = {
259
- todoCreated: Events.synced({
260
- name: 'v1.TodoCreated',
261
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
262
- }),
263
- todoCompleted: Events.synced({
264
- name: 'v1.TodoCompleted',
265
- schema: Schema.Struct({ id: Schema.String }),
266
- }),
267
- todoUncompleted: Events.synced({
268
- name: 'v1.TodoUncompleted',
269
- schema: Schema.Struct({ id: Schema.String }),
270
- }),
271
- todoDeleted: Events.synced({
272
- name: 'v1.TodoDeleted',
273
- schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
274
- }),
275
- todoClearedCompleted: Events.synced({
276
- name: 'v1.TodoClearedCompleted',
277
- schema: Schema.Struct({ deletedAt: Schema.Date }),
278
- }),
279
- uiStateSet: tables.uiState.set,
280
- }
281
-
282
- const materializers = State.SQLite.materializers(events, {
283
- 'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
284
- 'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
285
- 'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
286
- 'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
287
- 'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
288
- })
289
-
290
- const state = State.SQLite.makeState({ tables, materializers })
291
-
292
- export const schema = makeSchema({ events, state })
293
- ```
@@ -1,42 +0,0 @@
1
- # Svelte integration
2
-
3
- LiveStore's Svelte bindings expose a single helper, `createStore`, which binds `store.query` into Svelte's reactivity. When you call `store.query` inside markup or `$effect`, query results automatically re-run when LiveStore emits updates, and requests are cancelled on teardown via Svelte's abort signal.
4
-
5
- ## Example
6
-
7
- ## `reference/framework-integrations/svelte/create-store.svelte`
8
-
9
- ```svelte filename="reference/framework-integrations/svelte/create-store.svelte"
10
- <script lang="ts">
11
-
12
- const adapter = makePersistedAdapter({
13
- storage: { type: 'opfs' },
14
- worker: LiveStoreWorker,
15
- sharedWorker: LiveStoreSharedWorker,
16
- })
17
-
18
- const store = await createStore<typeof schema>({
19
- adapter,
20
- schema,
21
- storeId: 'default',
22
- })
23
-
24
- const todos$ = queryDb(tables.todos.where({ completed: false }), {
25
- label: 'todos',
26
- })
27
- </script>
28
-
29
- <ul>
30
- {#each store.query(todos$) as todo (todo.id)}
31
- <li>{todo.text}</li>
32
- {/each}
33
- </ul>
34
- ```
35
-
36
- ## Usage notes
37
-
38
- - `createStore` is async; instantiate it where you have access to the adapter (e.g. route load, `onMount`, or a top-level module when running in the browser).
39
- - `store.query` opts into Svelte reactivity when called inside `$effect` or markup. Outside reactive contexts, you can still use `store.subscribe` directly.
40
- - Works with the Web adapter out of the box. For SSR routes, construct the store on the client since `@livestore/adapter-web` is browser-only.
41
-
42
- See the <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples/web-todomvc-svelte`}>Svelte TodoMVC example</a> for a complete app.
@@ -1,294 +0,0 @@
1
- # Vue integration for LiveStore
2
-
3
- The [vue-livestore](https://github.com/slashv/vue-livestore) package provides integration with Vue. It's currently in beta but aims to match feature parity with the React integration.
4
-
5
- ## API
6
-
7
- ### `LiveStoreProvider`
8
-
9
- In order to use LiveStore with Vue, you need to wrap your application in a `LiveStoreProvider`.
10
-
11
- ## `reference/framework-integrations/vue/provider.vue`
12
-
13
- ```vue filename="reference/framework-integrations/vue/provider.vue"
14
- <script setup lang="ts">
15
-
16
- const adapter = makeInMemoryAdapter()
17
- const storeId = 'demo-store'
18
- const _options = { schema, adapter, storeId }
19
- </script>
20
-
21
- <template>
22
- <LiveStoreProvider :options="options">
23
- <template #loading>
24
- <div>Loading LiveStore...</div>
25
- </template>
26
- <slot />
27
- </LiveStoreProvider>
28
- </template>
29
- ```
30
-
31
- ### `reference/framework-integrations/react/schema.ts`
32
-
33
- ```ts filename="reference/framework-integrations/react/schema.ts"
34
-
35
- export const tables = {
36
- todos: State.SQLite.table({
37
- name: 'todos',
38
- columns: {
39
- id: State.SQLite.text({ primaryKey: true }),
40
- text: State.SQLite.text(),
41
- completed: State.SQLite.boolean({ default: false }),
42
- },
43
- }),
44
- uiState: State.SQLite.clientDocument({
45
- name: 'UiState',
46
- schema: Schema.Struct({ text: Schema.String }),
47
- default: { value: { text: '' } },
48
- }),
49
- } as const
50
-
51
- export const events = {
52
- todoCreated: Events.synced({
53
- name: 'v1.TodoCreated',
54
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
55
- }),
56
- } as const
57
-
58
- const materializers = State.SQLite.materializers(events, {
59
- [events.todoCreated.name]: defineMaterializer(events.todoCreated, ({ id, text }) =>
60
- tables.todos.insert({ id, text, completed: false }),
61
- ),
62
- })
63
-
64
- const state = State.SQLite.makeState({ tables, materializers })
65
-
66
- export const schema = makeSchema({ events, state })
67
- ```
68
-
69
- ### `reference/framework-integrations/vue/schema.ts`
70
-
71
- ```ts filename="reference/framework-integrations/vue/schema.ts"
72
- export { events, schema, tables } from '../react/schema.ts'
73
- ```
74
-
75
- ### useStore
76
-
77
- ## `reference/framework-integrations/vue/use-store.ts`
78
-
79
- ```ts filename="reference/framework-integrations/vue/use-store.ts"
80
-
81
- export const createTodo = () => {
82
- const { store } = useStore()
83
-
84
- store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Eat broccoli' }))
85
- }
86
- ```
87
-
88
- ### `reference/framework-integrations/react/schema.ts`
89
-
90
- ```ts filename="reference/framework-integrations/react/schema.ts"
91
-
92
- export const tables = {
93
- todos: State.SQLite.table({
94
- name: 'todos',
95
- columns: {
96
- id: State.SQLite.text({ primaryKey: true }),
97
- text: State.SQLite.text(),
98
- completed: State.SQLite.boolean({ default: false }),
99
- },
100
- }),
101
- uiState: State.SQLite.clientDocument({
102
- name: 'UiState',
103
- schema: Schema.Struct({ text: Schema.String }),
104
- default: { value: { text: '' } },
105
- }),
106
- } as const
107
-
108
- export const events = {
109
- todoCreated: Events.synced({
110
- name: 'v1.TodoCreated',
111
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
112
- }),
113
- } as const
114
-
115
- const materializers = State.SQLite.materializers(events, {
116
- [events.todoCreated.name]: defineMaterializer(events.todoCreated, ({ id, text }) =>
117
- tables.todos.insert({ id, text, completed: false }),
118
- ),
119
- })
120
-
121
- const state = State.SQLite.makeState({ tables, materializers })
122
-
123
- export const schema = makeSchema({ events, state })
124
- ```
125
-
126
- ### `reference/framework-integrations/vue/schema.ts`
127
-
128
- ```ts filename="reference/framework-integrations/vue/schema.ts"
129
- export { events, schema, tables } from '../react/schema.ts'
130
- ```
131
-
132
- ### useQuery
133
-
134
- ## `reference/framework-integrations/vue/use-query.vue`
135
-
136
- ```vue filename="reference/framework-integrations/vue/use-query.vue"
137
- <script setup lang="ts">
138
-
139
- const visibleTodos$ = queryDb(() => tables.todos.where({ completed: false }), { label: 'visibleTodos' })
140
-
141
- // biome-ignore lint/correctness/useHookAtTopLevel: Vue composables run at script setup level
142
- const todos = useQuery(visibleTodos$)
143
-
144
- void todos
145
- </script>
146
-
147
- <template>
148
- <div>
149
- <ul>
150
- <li v-for="todo in todos" :key="todo.id">
151
- {{ todo.text }}
152
- </li>
153
- </ul>
154
- </div>
155
- </template>
156
- ```
157
-
158
- ### `reference/framework-integrations/react/schema.ts`
159
-
160
- ```ts filename="reference/framework-integrations/react/schema.ts"
161
-
162
- export const tables = {
163
- todos: State.SQLite.table({
164
- name: 'todos',
165
- columns: {
166
- id: State.SQLite.text({ primaryKey: true }),
167
- text: State.SQLite.text(),
168
- completed: State.SQLite.boolean({ default: false }),
169
- },
170
- }),
171
- uiState: State.SQLite.clientDocument({
172
- name: 'UiState',
173
- schema: Schema.Struct({ text: Schema.String }),
174
- default: { value: { text: '' } },
175
- }),
176
- } as const
177
-
178
- export const events = {
179
- todoCreated: Events.synced({
180
- name: 'v1.TodoCreated',
181
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
182
- }),
183
- } as const
184
-
185
- const materializers = State.SQLite.materializers(events, {
186
- [events.todoCreated.name]: defineMaterializer(events.todoCreated, ({ id, text }) =>
187
- tables.todos.insert({ id, text, completed: false }),
188
- ),
189
- })
190
-
191
- const state = State.SQLite.makeState({ tables, materializers })
192
-
193
- export const schema = makeSchema({ events, state })
194
- ```
195
-
196
- ### `reference/framework-integrations/vue/schema.ts`
197
-
198
- ```ts filename="reference/framework-integrations/vue/schema.ts"
199
- export { events, schema, tables } from '../react/schema.ts'
200
- ```
201
-
202
- ### useClientDocument
203
-
204
- **[!] The interface for useClientDocument is experimental and might change**
205
-
206
- Since it's more common in Vue to work with a single writable ref (as compared to state, setState in React) the useClientDocument composable for Vue tries to make that easier by directly returning a collection of refs.
207
-
208
- The current implementation destructures all client state variables into the return object which allows directly binding to v-model or editing the .value reactivly.
209
-
210
- ## `reference/framework-integrations/vue/use-client-document.vue`
211
-
212
- ```vue filename="reference/framework-integrations/vue/use-client-document.vue"
213
- <script setup lang="ts">
214
-
215
- // biome-ignore lint/correctness/useHookAtTopLevel: Vue composables run at script setup level
216
- const { text: newTodoText, filters } = useClientDocument(tables.uiState)
217
-
218
- void newTodoText
219
- void filters
220
-
221
- void newTodoText
222
- void filters
223
- </script>
224
-
225
- <template>
226
- <div>
227
- <input type="text" v-model="newTodoText" />
228
-
229
- <select v-model="filters">
230
- <option value="all">All</option>
231
- <option value="active">Active</option>
232
- <option value="completed">Completed</option>
233
- </select>
234
- </div>
235
- </template>
236
- ```
237
-
238
- ### `reference/framework-integrations/react/schema.ts`
239
-
240
- ```ts filename="reference/framework-integrations/react/schema.ts"
241
-
242
- export const tables = {
243
- todos: State.SQLite.table({
244
- name: 'todos',
245
- columns: {
246
- id: State.SQLite.text({ primaryKey: true }),
247
- text: State.SQLite.text(),
248
- completed: State.SQLite.boolean({ default: false }),
249
- },
250
- }),
251
- uiState: State.SQLite.clientDocument({
252
- name: 'UiState',
253
- schema: Schema.Struct({ text: Schema.String }),
254
- default: { value: { text: '' } },
255
- }),
256
- } as const
257
-
258
- export const events = {
259
- todoCreated: Events.synced({
260
- name: 'v1.TodoCreated',
261
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
262
- }),
263
- } as const
264
-
265
- const materializers = State.SQLite.materializers(events, {
266
- [events.todoCreated.name]: defineMaterializer(events.todoCreated, ({ id, text }) =>
267
- tables.todos.insert({ id, text, completed: false }),
268
- ),
269
- })
270
-
271
- const state = State.SQLite.makeState({ tables, materializers })
272
-
273
- export const schema = makeSchema({ events, state })
274
- ```
275
-
276
- ### `reference/framework-integrations/vue/schema.ts`
277
-
278
- ```ts filename="reference/framework-integrations/vue/schema.ts"
279
- export { events, schema, tables } from '../react/schema.ts'
280
- ```
281
-
282
- ## Usage with ...
283
-
284
- ### Vite
285
-
286
- LiveStore and vue-livestore works with Vite out of the box.
287
-
288
- ### Nuxt.js
289
-
290
- Works out of the box with Nuxt if SSR is disabled by just wrapping the main content in a LiveStoreProvider. Example repo upcoming.
291
-
292
- ## Technical notes
293
-
294
- - Vue-livestore uses the provider component pattern similar to the React integration. In Vue the plugin pattern is more common but it isn't clear that that's the most suitable structure for LiveStore in Vue. We might switch to the plugin pattern if we later find that more suitable especially with regards to Nuxt support and supporting multiple stores.