@livestore/livestore 0.4.0-dev.21 → 0.4.0-dev.22

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 (75) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/effect/LiveStore.d.ts +123 -2
  3. package/dist/effect/LiveStore.d.ts.map +1 -1
  4. package/dist/effect/LiveStore.js +195 -1
  5. package/dist/effect/LiveStore.js.map +1 -1
  6. package/dist/effect/mod.d.ts +1 -1
  7. package/dist/effect/mod.d.ts.map +1 -1
  8. package/dist/effect/mod.js +3 -1
  9. package/dist/effect/mod.js.map +1 -1
  10. package/dist/mod.d.ts +1 -0
  11. package/dist/mod.d.ts.map +1 -1
  12. package/dist/mod.js +1 -0
  13. package/dist/mod.js.map +1 -1
  14. package/dist/store/StoreRegistry.d.ts +190 -0
  15. package/dist/store/StoreRegistry.d.ts.map +1 -0
  16. package/dist/store/StoreRegistry.js +244 -0
  17. package/dist/store/StoreRegistry.js.map +1 -0
  18. package/dist/store/StoreRegistry.test.d.ts +2 -0
  19. package/dist/store/StoreRegistry.test.d.ts.map +1 -0
  20. package/dist/store/StoreRegistry.test.js +380 -0
  21. package/dist/store/StoreRegistry.test.js.map +1 -0
  22. package/dist/store/create-store.d.ts +50 -4
  23. package/dist/store/create-store.d.ts.map +1 -1
  24. package/dist/store/create-store.js +19 -0
  25. package/dist/store/create-store.js.map +1 -1
  26. package/dist/store/devtools.d.ts.map +1 -1
  27. package/dist/store/devtools.js +13 -0
  28. package/dist/store/devtools.js.map +1 -1
  29. package/dist/store/store-types.d.ts +10 -25
  30. package/dist/store/store-types.d.ts.map +1 -1
  31. package/dist/store/store-types.js.map +1 -1
  32. package/dist/store/store.d.ts +23 -6
  33. package/dist/store/store.d.ts.map +1 -1
  34. package/dist/store/store.js +20 -2
  35. package/dist/store/store.js.map +1 -1
  36. package/docs/building-with-livestore/complex-ui-state/index.md +0 -2
  37. package/docs/building-with-livestore/crud/index.md +0 -2
  38. package/docs/building-with-livestore/data-modeling/index.md +29 -0
  39. package/docs/building-with-livestore/examples/todo-workspaces/index.md +0 -6
  40. package/docs/building-with-livestore/opentelemetry/index.md +25 -6
  41. package/docs/building-with-livestore/rules-for-ai-agents/index.md +2 -2
  42. package/docs/building-with-livestore/state/sql-queries/index.md +22 -0
  43. package/docs/building-with-livestore/state/sqlite-schema/index.md +2 -2
  44. package/docs/building-with-livestore/store/index.md +344 -0
  45. package/docs/framework-integrations/react-integration/index.md +380 -361
  46. package/docs/framework-integrations/vue-integration/index.md +2 -2
  47. package/docs/getting-started/expo/index.md +189 -43
  48. package/docs/getting-started/react-web/index.md +77 -24
  49. package/docs/getting-started/vue/index.md +3 -3
  50. package/docs/index.md +1 -2
  51. package/docs/llms.txt +0 -1
  52. package/docs/misc/troubleshooting/index.md +3 -3
  53. package/docs/overview/how-livestore-works/index.md +1 -1
  54. package/docs/overview/introduction/index.md +409 -1
  55. package/docs/overview/why-livestore/index.md +108 -2
  56. package/docs/patterns/auth/index.md +185 -34
  57. package/docs/patterns/effect/index.md +11 -1
  58. package/docs/patterns/storybook/index.md +43 -26
  59. package/docs/platform-adapters/expo-adapter/index.md +36 -19
  60. package/docs/platform-adapters/web-adapter/index.md +71 -2
  61. package/docs/tutorial/1-setup-starter-project/index.md +5 -5
  62. package/docs/tutorial/3-read-and-write-todos-via-livestore/index.md +54 -35
  63. package/docs/tutorial/5-expand-business-logic/index.md +1 -1
  64. package/docs/tutorial/6-persist-ui-state/index.md +12 -12
  65. package/package.json +6 -6
  66. package/src/effect/LiveStore.ts +385 -3
  67. package/src/effect/mod.ts +13 -1
  68. package/src/mod.ts +1 -0
  69. package/src/store/StoreRegistry.test.ts +516 -0
  70. package/src/store/StoreRegistry.ts +393 -0
  71. package/src/store/create-store.ts +50 -4
  72. package/src/store/devtools.ts +15 -0
  73. package/src/store/store-types.ts +17 -5
  74. package/src/store/store.ts +25 -5
  75. package/docs/building-with-livestore/examples/index.md +0 -30
@@ -4,9 +4,9 @@ The [vue-livestore](https://github.com/slashv/vue-livestore) package provides in
4
4
 
5
5
  ## API
6
6
 
7
- ### `LiveStoreProvider`
7
+ ### `<LiveStoreProvider>`
8
8
 
9
- In order to use LiveStore with Vue, you need to wrap your application in a `LiveStoreProvider`.
9
+ In order to use LiveStore with Vue, you need to wrap your application in a `<LiveStoreProvider>`.
10
10
 
11
11
  ## `reference/framework-integrations/vue/provider.vue`
12
12
 
@@ -242,47 +242,125 @@ const state = State.SQLite.makeState({ tables, materializers })
242
242
  export const schema = makeSchema({ events, state })
243
243
  ```
244
244
 
245
- ## Add the LiveStore Provider
245
+ ## Configure the store
246
246
 
247
- To make the LiveStore available throughout your app, wrap your app's root component with the `LiveStoreProvider` component from `@livestore/react`. This provider manages your app’s data store, loading, and error states.
247
+ Create a `store.ts` file in the `src/livestore` folder. This file configures the store adapter and exports a custom hook that components will use to access the store.
248
248
 
249
- Here's an example:
249
+ The `useStore()` hook accepts store configuration options (schema, adapter, store ID) and returns a store instance. It suspends while the store is loading, so make sure to use a `Suspense` boundary to handle the loading state.
250
250
 
251
- ## `getting-started/expo/Root.tsx`
251
+ ## `getting-started/expo/livestore/store.ts`
252
252
 
253
- ```tsx filename="getting-started/expo/Root.tsx"
253
+ ```ts filename="getting-started/expo/livestore/store.ts"
254
254
 
255
- const storeId = 'expo-todomvc'
256
255
  const syncUrl = 'https://example.org/sync'
257
256
 
258
257
  const adapter = makePersistedAdapter({
259
258
  sync: { backend: makeWsSync({ url: syncUrl }) },
260
259
  })
261
260
 
262
- export const Root: FC = () => (
263
- <SafeAreaView style={{ flex: 1 }}>
264
- <LiveStoreProvider
265
- schema={schema}
266
- adapter={adapter}
267
- storeId={storeId}
268
- batchUpdates={batchUpdates}
269
- renderLoading={(status) => <Text>Loading LiveStore ({status.stage})...</Text>}
270
- renderError={(error) => <Text>Error: {String(error)}</Text>}
271
- renderShutdown={() => <Text>LiveStore shutdown</Text>}
272
- boot={(store) => {
273
- if (store.query(tables.todos.count()) === 0) {
274
- store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Make coffee' }))
275
- }
276
- }}
277
- >
278
- <View style={{ flex: 1, gap: 24, padding: 24 }}>
279
- <NewTodo />
280
- <ListTodos />
281
- </View>
282
- </LiveStoreProvider>
283
- <StatusBar style="auto" />
284
- </SafeAreaView>
261
+ export const useAppStore = () =>
262
+ useStore({
263
+ storeId: 'expo-todomvc',
264
+ schema,
265
+ adapter,
266
+ batchUpdates,
267
+ boot: (store) => {
268
+ if (store.query(tables.todos.count()) === 0) {
269
+ store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Make coffee' }))
270
+ }
271
+ },
272
+ })
273
+ ```
274
+
275
+ ### `getting-started/expo/livestore/schema.ts`
276
+
277
+ ```ts filename="getting-started/expo/livestore/schema.ts"
278
+
279
+ export const tables = {
280
+ todos: State.SQLite.table({
281
+ name: 'todos',
282
+ columns: {
283
+ id: State.SQLite.text({ primaryKey: true }),
284
+ text: State.SQLite.text({ default: '' }),
285
+ completed: State.SQLite.boolean({ default: false }),
286
+ deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
287
+ },
288
+ }),
289
+ uiState: State.SQLite.clientDocument({
290
+ name: 'uiState',
291
+ schema: Schema.Struct({ newTodoText: Schema.String, filter: Schema.Literal('all', 'active', 'completed') }),
292
+ default: { id: SessionIdSymbol, value: { newTodoText: '', filter: 'all' } },
293
+ }),
294
+ }
295
+
296
+ export const events = {
297
+ todoCreated: Events.synced({
298
+ name: 'v1.TodoCreated',
299
+ schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
300
+ }),
301
+ todoCompleted: Events.synced({
302
+ name: 'v1.TodoCompleted',
303
+ schema: Schema.Struct({ id: Schema.String }),
304
+ }),
305
+ todoUncompleted: Events.synced({
306
+ name: 'v1.TodoUncompleted',
307
+ schema: Schema.Struct({ id: Schema.String }),
308
+ }),
309
+ todoDeleted: Events.synced({
310
+ name: 'v1.TodoDeleted',
311
+ schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
312
+ }),
313
+ todoClearedCompleted: Events.synced({
314
+ name: 'v1.TodoClearedCompleted',
315
+ schema: Schema.Struct({ deletedAt: Schema.Date }),
316
+ }),
317
+ uiStateSet: tables.uiState.set,
318
+ }
319
+
320
+ const materializers = State.SQLite.materializers(events, {
321
+ 'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
322
+ 'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
323
+ 'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
324
+ 'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
325
+ 'v1.TodoClearedCompleted': ({ deletedAt }) => tables.todos.update({ deletedAt }).where({ completed: true }),
326
+ })
327
+
328
+ const state = State.SQLite.makeState({ tables, materializers })
329
+
330
+ export const schema = makeSchema({ events, state })
331
+ ```
332
+
333
+ ## Set up the store registry
334
+
335
+ To enable store management throughout your app, create a `StoreRegistry` and provide it with a `<StoreRegistryProvider>`. The registry manages store instance lifecycles (loading, caching, disposal).
336
+
337
+ Wrap the provider in a `Suspense` boundary to handle the loading state for when the store is loading.
338
+
339
+ ## `getting-started/expo/Root.tsx`
340
+
341
+ ```tsx filename="getting-started/expo/Root.tsx"
342
+
343
+ const AppContent: FC = () => (
344
+ <View style={{ flex: 1, gap: 24, padding: 24 }}>
345
+ <NewTodo />
346
+ <ListTodos />
347
+ </View>
285
348
  )
349
+
350
+ export const Root: FC = () => {
351
+ const [storeRegistry] = useState(() => new StoreRegistry())
352
+
353
+ return (
354
+ <SafeAreaView style={{ flex: 1 }}>
355
+ <Suspense fallback={<Text>Loading LiveStore...</Text>}>
356
+ <StoreRegistryProvider storeRegistry={storeRegistry}>
357
+ <AppContent />
358
+ </StoreRegistryProvider>
359
+ </Suspense>
360
+ <StatusBar style="auto" />
361
+ </SafeAreaView>
362
+ )
363
+ }
286
364
  ```
287
365
 
288
366
  ### `getting-started/expo/components/ListTodos.tsx`
@@ -290,8 +368,8 @@ export const Root: FC = () => (
290
368
  ```tsx filename="getting-started/expo/components/ListTodos.tsx"
291
369
 
292
370
  export const ListTodos: FC = () => {
293
- const { store } = useStore()
294
- const todos = useQuery(visibleTodos$)
371
+ const store = useAppStore()
372
+ const todos = store.useQuery(visibleTodos$)
295
373
 
296
374
  const toggleTodo = useCallback(
297
375
  ({ id, completed }: typeof tables.todos.Type) => {
@@ -339,8 +417,8 @@ export const ListTodos: FC = () => {
339
417
  ```tsx filename="getting-started/expo/components/NewTodo.tsx"
340
418
 
341
419
  export const NewTodo: FC = () => {
342
- const { store } = useStore()
343
- const { newTodoText } = useQuery(uiState$)
420
+ const store = useAppStore()
421
+ const { newTodoText } = store.useQuery(uiState$)
344
422
 
345
423
  const updateText = (text: string) => store.commit(events.uiStateSet({ newTodoText: text }))
346
424
  const createTodo = () =>
@@ -444,19 +522,41 @@ const state = State.SQLite.makeState({ tables, materializers })
444
522
  export const schema = makeSchema({ events, state })
445
523
  ```
446
524
 
447
- ### Commit events
525
+ ### `getting-started/expo/livestore/store.ts`
526
+
527
+ ```ts filename="getting-started/expo/livestore/store.ts"
528
+
529
+ const syncUrl = 'https://example.org/sync'
530
+
531
+ const adapter = makePersistedAdapter({
532
+ sync: { backend: makeWsSync({ url: syncUrl }) },
533
+ })
534
+
535
+ export const useAppStore = () =>
536
+ useStore({
537
+ storeId: 'expo-todomvc',
538
+ schema,
539
+ adapter,
540
+ batchUpdates,
541
+ boot: (store) => {
542
+ if (store.query(tables.todos.count()) === 0) {
543
+ store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Make coffee' }))
544
+ }
545
+ },
546
+ })
547
+ ```
448
548
 
449
- After wrapping your app with the `LiveStoreProvider`, you can use the `useStore` hook from any component to commit events.
549
+ ## Commit events
450
550
 
451
- Here's an example:
551
+ After setting up the registry, use the `useAppStore()` hook from any component to access the store and commit events.
452
552
 
453
553
  ## `getting-started/expo/components/NewTodo.tsx`
454
554
 
455
555
  ```tsx filename="getting-started/expo/components/NewTodo.tsx"
456
556
 
457
557
  export const NewTodo: FC = () => {
458
- const { store } = useStore()
459
- const { newTodoText } = useQuery(uiState$)
558
+ const store = useAppStore()
559
+ const { newTodoText } = store.useQuery(uiState$)
460
560
 
461
561
  const updateText = (text: string) => store.commit(events.uiStateSet({ newTodoText: text }))
462
562
  const createTodo = () =>
@@ -560,21 +660,43 @@ const state = State.SQLite.makeState({ tables, materializers })
560
660
  export const schema = makeSchema({ events, state })
561
661
  ```
562
662
 
663
+ ### `getting-started/expo/livestore/store.ts`
664
+
665
+ ```ts filename="getting-started/expo/livestore/store.ts"
666
+
667
+ const syncUrl = 'https://example.org/sync'
668
+
669
+ const adapter = makePersistedAdapter({
670
+ sync: { backend: makeWsSync({ url: syncUrl }) },
671
+ })
672
+
673
+ export const useAppStore = () =>
674
+ useStore({
675
+ storeId: 'expo-todomvc',
676
+ schema,
677
+ adapter,
678
+ batchUpdates,
679
+ boot: (store) => {
680
+ if (store.query(tables.todos.count()) === 0) {
681
+ store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Make coffee' }))
682
+ }
683
+ },
684
+ })
685
+ ```
686
+
563
687
  ## Queries
564
688
 
565
- 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`.
689
+ To retrieve data from the database, define a query using `queryDb` from `@livestore/livestore`, then execute it with `store.useQuery()`.
566
690
 
567
691
  Consider abstracting queries into a separate file to keep your code organized, though you can also define them directly within components if preferred.
568
692
 
569
- Here's an example:
570
-
571
693
  ## `getting-started/expo/components/ListTodos.tsx`
572
694
 
573
695
  ```tsx filename="getting-started/expo/components/ListTodos.tsx"
574
696
 
575
697
  export const ListTodos: FC = () => {
576
- const { store } = useStore()
577
- const todos = useQuery(visibleTodos$)
698
+ const store = useAppStore()
699
+ const todos = store.useQuery(visibleTodos$)
578
700
 
579
701
  const toggleTodo = useCallback(
580
702
  ({ id, completed }: typeof tables.todos.Type) => {
@@ -694,6 +816,30 @@ const state = State.SQLite.makeState({ tables, materializers })
694
816
  export const schema = makeSchema({ events, state })
695
817
  ```
696
818
 
819
+ ### `getting-started/expo/livestore/store.ts`
820
+
821
+ ```ts filename="getting-started/expo/livestore/store.ts"
822
+
823
+ const syncUrl = 'https://example.org/sync'
824
+
825
+ const adapter = makePersistedAdapter({
826
+ sync: { backend: makeWsSync({ url: syncUrl }) },
827
+ })
828
+
829
+ export const useAppStore = () =>
830
+ useStore({
831
+ storeId: 'expo-todomvc',
832
+ schema,
833
+ adapter,
834
+ batchUpdates,
835
+ boot: (store) => {
836
+ if (store.query(tables.todos.count()) === 0) {
837
+ store.commit(events.todoCreated({ id: crypto.randomUUID(), text: 'Make coffee' }))
838
+ }
839
+ },
840
+ })
841
+ ```
842
+
697
843
  ## Devtools
698
844
 
699
845
  To open the devtools, run the app and from your terminal press `shift + m`, then select LiveStore Devtools and press `Enter`.
@@ -250,15 +250,15 @@ const state = State.SQLite.makeState({ tables, materializers })
250
250
  export const schema = makeSchema({ events, state })
251
251
  ```
252
252
 
253
- ## Add the LiveStore provider
253
+ ## Configure the store
254
254
 
255
- To make the LiveStore available throughout your app, wrap your app's root component with the `LiveStoreProvider` component from `@livestore/react`. This provider manages your app's data store, loading, and error states.
255
+ Create a `store.ts` file in the `src` folder. This file configures the store adapter and exports a custom hook that components will use to access the store.
256
256
 
257
- Here's an example:
257
+ The `useStore()` hook accepts store configuration options (schema, adapter, store ID) and returns a store instance. It suspends while the store is loading, so make sure to use a `Suspense` boundary to handle the loading state.
258
258
 
259
- ## `getting-started/react-web/Root.tsx`
259
+ ## `getting-started/react-web/store.ts`
260
260
 
261
- ```tsx filename="getting-started/react-web/Root.tsx"
261
+ ```ts filename="getting-started/react-web/store.ts"
262
262
 
263
263
  const adapter = makePersistedAdapter({
264
264
  storage: { type: 'opfs' },
@@ -266,17 +266,13 @@ const adapter = makePersistedAdapter({
266
266
  sharedWorker: LiveStoreSharedWorker,
267
267
  })
268
268
 
269
- export const App: React.FC = () => (
270
- <LiveStoreProvider
271
- schema={schema}
272
- adapter={adapter}
273
- renderLoading={(_) => <div>Loading LiveStore ({_.stage})...</div>}
274
- batchUpdates={batchUpdates}
275
- storeId="my-app-store"
276
- >
277
- <div className="todoapp">{/* Your app components go here */}</div>
278
- </LiveStoreProvider>
279
- )
269
+ export const useAppStore = () =>
270
+ useStore({
271
+ storeId: 'app-root',
272
+ schema,
273
+ adapter,
274
+ batchUpdates,
275
+ })
280
276
  ```
281
277
 
282
278
  ### `getting-started/react-web/livestore/schema.ts`
@@ -341,11 +337,32 @@ const state = State.SQLite.makeState({ tables, materializers })
341
337
  export const schema = makeSchema({ events, state })
342
338
  ```
343
339
 
344
- ### Commit events
340
+ ## Set up the store registry
341
+
342
+ To enable store management throughout your app, create a `StoreRegistry` and provide it with a `<StoreRegistryProvider>`. The registry manages store instance lifecycles (loading, caching, disposal).
343
+
344
+ Wrap the provider in a `Suspense` boundary to handle the loading state for when the store is loading.
345
+
346
+ ## `getting-started/react-web/Root.tsx`
347
+
348
+ ```tsx filename="getting-started/react-web/Root.tsx"
349
+
350
+ export const App: React.FC = () => {
351
+ const [storeRegistry] = useState(() => new StoreRegistry())
345
352
 
346
- After wrapping your app with the `LiveStoreProvider`, you can use the `useStore` hook from any component to commit events.
353
+ return (
354
+ <Suspense fallback={<div>Loading app...</div>}>
355
+ <StoreRegistryProvider storeRegistry={storeRegistry}>
356
+ <div className="todoapp">{/* Your app components go here */}</div>
357
+ </StoreRegistryProvider>
358
+ </Suspense>
359
+ )
360
+ }
361
+ ```
347
362
 
348
- Here's an example:
363
+ ## Commit events
364
+
365
+ After setting up the registry, use the `useAppStore()` hook from any component to access the store and commit events.
349
366
 
350
367
  ## `getting-started/react-web/Header.tsx`
351
368
 
@@ -354,7 +371,7 @@ Here's an example:
354
371
  const uiState$ = queryDb(tables.uiState.get(), { label: 'uiState' })
355
372
 
356
373
  export const Header: React.FC = () => {
357
- const { store } = useStore()
374
+ const store = useAppStore()
358
375
  const { newTodoText } = store.useQuery(uiState$)
359
376
 
360
377
  const updateNewTodoText = (text: string) => store.commit(events.uiStateSet({ newTodoText: text }))
@@ -446,14 +463,31 @@ const state = State.SQLite.makeState({ tables, materializers })
446
463
  export const schema = makeSchema({ events, state })
447
464
  ```
448
465
 
466
+ ### `getting-started/react-web/store.ts`
467
+
468
+ ```ts filename="getting-started/react-web/store.ts"
469
+
470
+ const adapter = makePersistedAdapter({
471
+ storage: { type: 'opfs' },
472
+ worker: LiveStoreWorker,
473
+ sharedWorker: LiveStoreSharedWorker,
474
+ })
475
+
476
+ export const useAppStore = () =>
477
+ useStore({
478
+ storeId: 'app-root',
479
+ schema,
480
+ adapter,
481
+ batchUpdates,
482
+ })
483
+ ```
484
+
449
485
  ## Queries
450
486
 
451
- 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`.
487
+ To retrieve data from the database, define a query using `queryDb` from `@livestore/livestore`, then execute it with `store.useQuery()`.
452
488
 
453
489
  Consider abstracting queries into a separate file to keep your code organized, though you can also define them directly within components if preferred.
454
490
 
455
- Here's an example:
456
-
457
491
  ## `getting-started/react-web/MainSection.tsx`
458
492
 
459
493
  ```tsx filename="getting-started/react-web/MainSection.tsx"
@@ -472,7 +506,7 @@ const visibleTodos$ = queryDb(
472
506
  )
473
507
 
474
508
  export const MainSection: React.FC = () => {
475
- const { store } = useStore()
509
+ const store = useAppStore()
476
510
 
477
511
  const toggleTodo = React.useCallback(
478
512
  ({ id, completed }: typeof tables.todos.Type) =>
@@ -571,3 +605,22 @@ const state = State.SQLite.makeState({ tables, materializers })
571
605
 
572
606
  export const schema = makeSchema({ events, state })
573
607
  ```
608
+
609
+ ### `getting-started/react-web/store.ts`
610
+
611
+ ```ts filename="getting-started/react-web/store.ts"
612
+
613
+ const adapter = makePersistedAdapter({
614
+ storage: { type: 'opfs' },
615
+ worker: LiveStoreWorker,
616
+ sharedWorker: LiveStoreSharedWorker,
617
+ })
618
+
619
+ export const useAppStore = () =>
620
+ useStore({
621
+ storeId: 'app-root',
622
+ schema,
623
+ adapter,
624
+ batchUpdates,
625
+ })
626
+ ```
@@ -198,7 +198,7 @@ export const schema = makeSchema({ events, state })
198
198
 
199
199
  ### Add the LiveStore provider
200
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.
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
202
 
203
203
  Here's an example:
204
204
 
@@ -292,7 +292,7 @@ export const schema = makeSchema({ events, state })
292
292
 
293
293
  ### Commit events
294
294
 
295
- After wrapping your app with the `LiveStoreProvider`, you can use the `useStore` hook from any component to commit events.
295
+ After wrapping your app with the `<LiveStoreProvider>`, you can use the `useStore()` hook from any component to commit events.
296
296
 
297
297
  Here's an example:
298
298
 
@@ -382,7 +382,7 @@ export const schema = makeSchema({ events, state })
382
382
 
383
383
  ### Queries
384
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`.
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
386
 
387
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
388
 
package/docs/index.md CHANGED
@@ -35,7 +35,7 @@
35
35
 
36
36
  ## State of the documentation
37
37
 
38
- Please note that the documentation is still work in progress with many parts missing and often only containing notes/bullet points.
38
+ Please note that the documentation is still work in progress. Please [leave feedback](https://github.com/livestorejs/livestore/issues) if you didn't find the information you were looking for and [consider contributing](/sustainable-open-source/contributing/docs) yourself.
39
39
 
40
40
  ### Docs for LLMs
41
41
 
@@ -102,7 +102,6 @@ Currently, we have the following root-level files:
102
102
 
103
103
  ### Examples
104
104
 
105
- - [Data modeling](/building-with-livestore/examples): How to model data in LiveStore.
106
105
  - [Todo app with shared workspaces](/building-with-livestore/examples/todo-workspaces): How to model a todo workspace app with shared workspaces in LiveStore.
107
106
  - [Turn-based game](/building-with-livestore/examples/turnbased-game): How to model a turn-based game in LiveStore.
108
107
  - [AI agent](/building-with-livestore/examples/ai-agent): How to model an AI agent in LiveStore.
package/docs/llms.txt CHANGED
@@ -65,7 +65,6 @@
65
65
 
66
66
  ### Examples
67
67
 
68
- - [Data modeling](/building-with-livestore/examples): How to model data in LiveStore.
69
68
  - [Todo app with shared workspaces](/building-with-livestore/examples/todo-workspaces): How to model a todo workspace app with shared workspaces in LiveStore.
70
69
  - [Turn-based game](/building-with-livestore/examples/turnbased-game): How to model a turn-based game in LiveStore.
71
70
  - [AI agent](/building-with-livestore/examples/ai-agent): How to model an AI agent in LiveStore.
@@ -53,17 +53,17 @@ Note on terminology
53
53
 
54
54
  ### Query doesn't update properly
55
55
 
56
- If you notice the result of a `useQuery` hook is not updating properly, you might be missing some dependencies in the query's hash.
56
+ If you notice the result of a `useQuery()` hook is not updating properly, you might be missing some dependencies in the query's hash.
57
57
 
58
58
  For example, the following query:
59
59
 
60
60
  ```ts
61
61
  // Don't do this
62
- const query$ = useQuery(queryDb(tables.issues.query.where({ id: issueId }).first()))
62
+ const query$ = store.useQuery(queryDb(tables.issues.query.where({ id: issueId }).first()))
63
63
  // ^^^^^^^ missing in deps
64
64
 
65
65
  // Do this instead
66
- const query$ = useQuery(queryDb(tables.issues.query.where({ id: issueId }).first(), { deps: [issueId] }))
66
+ const query$ = store.useQuery(queryDb(tables.issues.query.where({ id: issueId }).first(), { deps: [issueId] }))
67
67
  ```
68
68
 
69
69
  ## `node_modules` related issues
@@ -14,7 +14,7 @@ On the client, LiveStore provides a reactive SQLite database for application sta
14
14
 
15
15
  Application state is materialized into a local SQLite database, offering high-performance, offline-capable data access. This SQLite database is reactive: UI components subscribe to data changes and update automatically when the state changes. LiveStore uses in-memory SQLite for sub-millisecond queries and persistent SQLite for durable storage across application sessions.
16
16
 
17
- #### Event Sourcing
17
+ #### Event sourcing
18
18
 
19
19
  Underpinning the reactive state, LiveStore implements the event sourcing pattern. All data modifications are captured as an immutable, ordered sequence of events. This eventlog serves as the canonical history, enabling reliable state reconstruction and providing inherent auditability, which aids in debugging. The reactive SQLite state is a projection of this eventlog.
20
20