@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,187 +0,0 @@
1
- # MCP integration
2
-
3
- LiveStore includes MCP (Model Context Protocol) integration that allows AI assistants like Claude to access LiveStore documentation, examples, and development tools.
4
-
5
- :::caution[Experimental]
6
- The MCP integration is experimental and under active development. Features may change.
7
- :::
8
-
9
- For installation and general CLI usage, see the [LiveStore CLI](/building-with-livestore/tools/cli) documentation.
10
-
11
- ## What is MCP?
12
-
13
- MCP (Model Context Protocol) is a standard for providing AI assistants with access to external resources and tools. LiveStore's MCP server gives AI assistants access to:
14
-
15
- - LiveStore documentation and guides
16
- - Schema examples for common app types
17
- - Development tools and utilities
18
-
19
- ## Usage
20
-
21
- Start the MCP server:
22
-
23
- ```bash
24
- bunx @livestore/cli mcp
25
- ```
26
-
27
- ## Available commands
28
-
29
- ### `bunx @livestore/cli mcp coach`
30
- Starts an AI coaching assistant with access to LiveStore documentation and best practices.
31
-
32
- ### `bunx @livestore/cli mcp tools`
33
- Provides development tools and utilities for working with LiveStore projects.
34
-
35
- ### LiveStore Runtime Tools
36
-
37
- - `livestore_instance_connect`
38
- - Connects a single in-process LiveStore instance by dynamically importing a module that exports `schema` and a `syncBackend` factory (and optionally `syncPayload`).
39
- - Notes:
40
- - Only one instance can be active at a time; connecting again shuts down and replaces the previous instance.
41
- - Reconnecting creates a fresh, in-memory client database. The visible state is populated by your backend's initial sync. Until sync completes, queries may return empty or partial results.
42
- - Module contract (generic example):
43
-
44
- ## `reference/mcp/module-contract.ts`
45
-
46
- ```ts filename="reference/mcp/module-contract.ts"
47
-
48
- export { schema } from './schema.ts'
49
-
50
- export const syncBackend = makeWsSync({ url: process.env.LIVESTORE_SYNC_URL ?? 'ws://localhost:8787' })
51
-
52
- export const syncPayload = { authToken: process.env.LIVESTORE_SYNC_AUTH_TOKEN ?? 'insecure-token-change-me' }
53
- ```
54
-
55
- ### `reference/mcp/schema.ts`
56
-
57
- ```ts filename="reference/mcp/schema.ts"
58
-
59
- const events = {
60
- entityCreated: Events.synced({
61
- name: 'v1.EntityCreated',
62
- schema: Schema.Struct({
63
- id: Schema.String,
64
- title: Schema.String,
65
- createdAt: Schema.DateFromString,
66
- }),
67
- }),
68
- }
69
-
70
- const tables = {
71
- entities: State.SQLite.table({
72
- name: 'entities',
73
- columns: {
74
- id: State.SQLite.text({ primaryKey: true }),
75
- title: State.SQLite.text({ default: '' }),
76
- createdAt: State.SQLite.text({ default: '' }),
77
- },
78
- }),
79
- }
80
-
81
- const materializers = State.SQLite.materializers(events, {
82
- 'v1.EntityCreated': ({ id, title, createdAt }) =>
83
- tables.entities.insert({ id, title, createdAt: createdAt.toISOString() }),
84
- })
85
-
86
- const state = State.SQLite.makeState({ tables, materializers })
87
-
88
- export const schema = makeSchema({ events, state })
89
- ```
90
-
91
- - Params example: `{ "configPath": "livestore-cli.config.ts", "storeId": "<store-id>" }`
92
- - Returns example:
93
- `{ "storeId": "<store-id>", "clientId": "client-123", "sessionId": "session-abc", "schemaInfo": { "tableNames": ["..."], "eventNames": ["..."] } }`
94
-
95
- - `livestore_instance_query`
96
- - Executes raw SQL against the client database (read-only).
97
- - Notes:
98
- - SQLite dialect; use valid SQLite syntax.
99
- - `bindValues` must be an array (positional `?`) or a record (named `$key`). Do not pass stringified JSON.
100
- - Params example (positional): `{ "sql": "SELECT * FROM my_table WHERE userId = ?", "bindValues": ["u1"] }`
101
- - Params example (named): `{ "sql": "SELECT * FROM my_table WHERE userId = $userId", "bindValues": { "userId": "u1" } }`
102
- - Returns example: `{ "rows": [{ "col": "value" }], "rowCount": 1 }`
103
-
104
- - `livestore_instance_commit_events`
105
- - Commits one or more events defined by your connected schema.
106
- - Notes:
107
- - Use the canonical event name declared in your schema (e.g., `v1.EntityCreated`).
108
- - `args` must be a non-stringified JSON object matching the event schema. Date fields typically accept ISO 8601 strings.
109
- - Params example: `{ "events": [{ "name": "v1.EntityCreated", "args": { "id": "e1", "title": "Hello", "createdAt": "2024-01-01T00:00:00.000Z" } }] }`
110
- - Returns example: `{ "committed": 1 }`
111
-
112
- - `livestore_instance_status`
113
- - Reports instance/runtime info.
114
- - Returns example (connected): `{ "_tag": "connected", "storeId": "<store-id>", "clientId": "client-123", "sessionId": "session-abc", "tableCounts": { "my_table": 12 } }`
115
- - Returns example (not connected): `{ "_tag": "disconnected" }`
116
-
117
- - `livestore_instance_disconnect`
118
- - Disconnects the current LiveStore instance and releases resources.
119
- - Returns: `{ "_tag": "disconnected" }`
120
-
121
- ### Sync export/import tools
122
-
123
- These tools connect directly to the sync backend (without creating a full LiveStore instance) to export or import events. Useful for backup, migration, and debugging.
124
-
125
- - `livestore_sync_export`
126
- - Exports all events from a sync backend to JSON data.
127
- - Notes:
128
- - Connects directly to the sync backend and pulls all events.
129
- - Returns the export data as a JSON object that can be saved or passed to import.
130
- - Params example: `{ "configPath": "livestore-cli.config.ts", "storeId": "my-store" }`
131
- - Returns example: `{ "storeId": "my-store", "eventCount": 127, "exportedAt": "2024-01-15T10:30:00.000Z", "data": { "version": 1, "storeId": "my-store", "events": [...] } }`
132
-
133
- - `livestore_sync_import`
134
- - Imports events from export data to a sync backend.
135
- - Notes:
136
- - The sync backend must be empty before importing.
137
- - Use `force: true` to import even if the store ID in the data doesn't match.
138
- - Use `dryRun: true` to validate the import without actually importing.
139
- - Params example: `{ "configPath": "livestore-cli.config.ts", "storeId": "my-store", "data": { "version": 1, "storeId": "my-store", "events": [...] } }`
140
- - Params with options: `{ "configPath": "...", "storeId": "...", "data": {...}, "force": true, "dryRun": true }`
141
- - Returns example: `{ "storeId": "my-store", "eventCount": 127, "dryRun": false }`
142
-
143
- ## Local Cloudflare sync (dev)
144
-
145
- Run a local Cloudflare sync backend:
146
-
147
- 1. Start the sync worker (wrangler):
148
- - `cd tests/integration/src/tests/adapter-cloudflare/fixtures`
149
- - `wrangler dev`
150
- - You should see an info page at `http://localhost:8787/`.
151
-
152
- 2. Start the MCP server in another terminal:
153
- - `bunx @livestore/cli mcp server`
154
-
155
- 3. From your MCP client (e.g., Claude Desktop), call tools:
156
- - Use your own config file path and storeId. The repo also provides an example: `examples/cf-chat/livestore-cli.config.ts`.
157
- - Connect: `livestore_instance_connect` with `{ "configPath": "livestore-cli.config.ts", "storeId": "<store-id>" }`
158
- - Commit: `livestore_instance_commit_events` with `[ { "name": "v1.EntityCreated", "args": { "id": "e1", "title": "Hello", "createdAt": "2024-01-01T00:00:00.000Z" } } ]`
159
- - Query: `livestore_instance_query` with `{ "sql": "SELECT * FROM my_table ORDER BY createdAt DESC LIMIT 5" }`
160
- - Status: `livestore_instance_status`
161
- - Disconnect: `livestore_instance_disconnect`
162
-
163
- ## Adding to Claude
164
-
165
- To use with Claude Desktop, add the MCP server to your Claude configuration:
166
-
167
- ```json
168
- {
169
- "mcpServers": {
170
- "livestore": {
171
- "command": "bunx",
172
- "args": ["@livestore/cli", "mcp"]
173
- }
174
- }
175
- }
176
- ```
177
-
178
- ## Available resources
179
-
180
- The MCP server provides access to:
181
-
182
- - **Documentation**: Overview, features, getting started guides
183
- - **Architecture**: Technical design and principles
184
- - **Schema Examples**: Pre-built schemas for todo, blog, e-commerce, and social apps
185
- - **Development Tools**: Project scaffolding and utilities
186
-
187
- This enables AI assistants to provide context-aware help with LiveStore development.
@@ -1,44 +0,0 @@
1
- # Cloudflare Durable Objects examples
2
-
3
- # Cloudflare Durable Objects Examples
4
-
5
- Examples using `@livestore/adapter-cloudflare` for Cloudflare Workers and Durable Objects.
6
-
7
- <CardGrid>
8
- {cloudflareExamples.map((example) => {
9
- const { url, label } = getExampleDemoLinks(example);
10
-
11
- return (
12
- <Card title={example.title} key={example.title}>
13
- {example.image ? (
14
- <Image src={example.image.url} width={example.image.width} height={example.image.height} alt={`${example.title} application interface`} />
15
- ) : (
16
- <div style="background: linear-gradient(135deg, #1f2937 0%, #374151 100%); height: 200px; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 14px; border-radius: 8px;">
17
- Screenshot coming soon
18
- </div>
19
- )}
20
- <p>{example.description}</p>
21
- <p><strong>Technologies:</strong> {example.technologies.join(' • ')}</p>
22
- {example.syncProvider && (
23
- <p><strong>Sync Provider:</strong> {example.syncProvider}</p>
24
- )}
25
- <div style="margin-top: auto; padding-top: 1rem;">
26
- {url && (
27
- <p style="margin: 0 0 0.5rem 0;"><a href={url} target="_blank" rel="noopener noreferrer">{label}</a></p>
28
- )}
29
- <p style="margin: 0;"><a href={example.sourceUrl} target="_blank" rel="noopener noreferrer">View Source →</a></p>
30
- </div>
31
- </Card>
32
- );
33
- })}
34
- </CardGrid>
35
-
36
- ## Cloudflare Adapter
37
-
38
- - Runs LiveStore inside Cloudflare Durable Objects
39
- - Uses Durable Object Storage API (not traditional databases)
40
- - SQLite WASM with Cloudflare-specific VFS
41
- - No WebSocket support - uses Durable Objects' distributed consistency
42
-
43
- ---
44
- <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples`}>View all examples on GitHub →</a>
@@ -1,44 +0,0 @@
1
- # Expo adapter examples
2
-
3
- # Expo Adapter Examples
4
-
5
- Examples using `@livestore/adapter-expo` for React Native mobile applications.
6
-
7
- <CardGrid>
8
- {expoExamples.map((example) => {
9
- const { url, label } = getExampleDemoLinks(example);
10
-
11
- return (
12
- <Card title={example.title} key={example.title}>
13
- {example.image ? (
14
- <Image src={example.image.url} width={example.image.width} height={example.image.height} alt={`${example.title} application interface`} />
15
- ) : (
16
- <div style="background: linear-gradient(135deg, #1f2937 0%, #374151 100%); height: 200px; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 14px; border-radius: 8px;">
17
- Screenshot coming soon
18
- </div>
19
- )}
20
- <p>{example.description}</p>
21
- <p><strong>Technologies:</strong> {example.technologies.join(' • ')}</p>
22
- {example.syncProvider && (
23
- <p><strong>Sync Provider:</strong> {example.syncProvider}</p>
24
- )}
25
- <div style="margin-top: auto; padding-top: 1rem;">
26
- {url && (
27
- <p style="margin: 0 0 0.5rem 0;"><a href={url} target="_blank" rel="noopener noreferrer">{label}</a></p>
28
- )}
29
- <p style="margin: 0;"><a href={example.sourceUrl} target="_blank" rel="noopener noreferrer">View Source →</a></p>
30
- </div>
31
- </Card>
32
- );
33
- })}
34
- </CardGrid>
35
-
36
- ## Expo Adapter
37
-
38
- - Uses native Expo SQLite stored in device's SQLite directory
39
- - Requires New Architecture (Fabric) - incompatible with old architecture
40
- - Single-threaded operation in main thread
41
- - WebSocket connections for sync via React Native dev server
42
-
43
- ---
44
- <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples`}>View all examples on GitHub →</a>
@@ -1,55 +0,0 @@
1
- # Examples
2
-
3
- # Example Applications
4
-
5
- Discover how to build local-first applications with LiveStore through our comprehensive collection of example apps. Each example demonstrates different features, patterns, and platform integrations to help you get started quickly.
6
-
7
- ## Browse by platform adapter
8
-
9
- LiveStore supports multiple platform adapters, each optimized for different environments. Choose the adapter that matches your target platform:
10
-
11
- <CardGrid>
12
- <LinkCard
13
- title="Web Adapter"
14
- href="/examples/web-adapter/"
15
- description={`Browser-based applications with SQLite WASM, Web Workers, and framework integrations. ${webExamples.length} examples • React, SolidJS, Svelte, Web Components`}
16
- />
17
-
18
- <LinkCard
19
- title="Node Adapter"
20
- href="/examples/node-adapter/"
21
- description={`Server-side applications, CLI tools, and backend services with native SQLite performance. ${nodeExamples.length} examples • Effect, CLI applications`}
22
- />
23
-
24
- <LinkCard
25
- title="Expo Adapter"
26
- href="/examples/expo-adapter/"
27
- description={`React Native mobile applications with offline-first architecture and cross-platform sync. ${expoExamples.length} examples • iOS, Android, React Native`}
28
- />
29
-
30
- <LinkCard
31
- title="Cloudflare Durable Objects"
32
- href="/examples/cloudflare-adapter/"
33
- description={`Edge computing with Durable Objects, global distribution, and serverless scaling. ${cloudflareExamples.length} examples • Workers, Durable Objects, Edge`}
34
- />
35
- </CardGrid>
36
-
37
- ## Getting started
38
-
39
- 1. **Choose your platform** from the adapter categories above
40
- 2. **Browse examples** that match your use case and framework preference
41
- 3. **Clone and run** the examples locally to see LiveStore in action
42
- 4. **Study the source code** to understand patterns and best practices
43
-
44
- ## Multi-adapter examples
45
-
46
- Some examples demonstrate **cross-platform synchronization** by using multiple adapters:
47
- - **CF Chat** uses both Web and Cloudflare adapters for hybrid client-server architecture
48
- - **Sync-enabled examples** show how to connect different platforms seamlessly
49
-
50
- ## About LiveStore
51
-
52
- LiveStore is a local-first data layer that runs everywhere - from browsers to mobile apps to edge computing. Each adapter provides platform-optimized features while maintaining a consistent API across all environments.
53
-
54
- ---
55
- <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples`}>View all examples on GitHub →</a>
@@ -1,44 +0,0 @@
1
- # Node adapter examples
2
-
3
- # Node Adapter Examples
4
-
5
- Examples using `@livestore/adapter-node` for Node.js server-side applications.
6
-
7
- <CardGrid>
8
- {nodeExamples.map((example) => {
9
- const { url, label } = getExampleDemoLinks(example);
10
-
11
- return (
12
- <Card title={example.title} key={example.title}>
13
- {example.image ? (
14
- <Image src={example.image.url} width={example.image.width} height={example.image.height} alt={`${example.title} application interface`} />
15
- ) : (
16
- <div style="background: linear-gradient(135deg, #1f2937 0%, #374151 100%); height: 200px; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 14px; border-radius: 8px;">
17
- Screenshot coming soon
18
- </div>
19
- )}
20
- <p>{example.description}</p>
21
- <p><strong>Technologies:</strong> {example.technologies.join(' • ')}</p>
22
- {example.syncProvider && (
23
- <p><strong>Sync Provider:</strong> {example.syncProvider}</p>
24
- )}
25
- <div style="margin-top: auto; padding-top: 1rem;">
26
- {url && (
27
- <p style="margin: 0 0 0.5rem 0;"><a href={url} target="_blank" rel="noopener noreferrer">{label}</a></p>
28
- )}
29
- <p style="margin: 0;"><a href={example.sourceUrl} target="_blank" rel="noopener noreferrer">View Source →</a></p>
30
- </div>
31
- </Card>
32
- );
33
- })}
34
- </CardGrid>
35
-
36
- ## Node Adapter
37
-
38
- - Uses native Node.js SQLite with file system storage
39
- - Stores SQLite files directly on disk (default: current directory)
40
- - Supports single-threaded or worker thread modes
41
- - WebSocket connections for sync and devtools integration
42
-
43
- ---
44
- <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples`}>View all examples on GitHub →</a>
@@ -1,52 +0,0 @@
1
- # Web adapter examples
2
-
3
- # Web Adapter Examples
4
-
5
- Examples using `@livestore/adapter-web` for browser environments.
6
-
7
- <CardGrid>
8
- {webExamples.map((example) => {
9
- const { url, label } = getExampleDemoLinks(example);
10
-
11
- return (
12
- <Card title={example.title} key={example.title}>
13
- {example.image ? (
14
- <Image src={example.image.url} width={example.image.width} height={example.image.height} alt={`${example.title} application interface`} />
15
- ) : (
16
- <div style="background: linear-gradient(135deg, #1f2937 0%, #374151 100%); height: 200px; display: flex; align-items: center; justify-content: center; color: #9ca3af; font-size: 14px; border-radius: 8px;">
17
- Screenshot coming soon
18
- </div>
19
- )}
20
- <p>{example.description}</p>
21
- <p><strong>Technologies:</strong> {example.technologies.join(' • ')}</p>
22
- {example.syncProvider && (
23
- <p><strong>Sync Provider:</strong> {example.syncProvider}</p>
24
- )}
25
- <div style="margin-top: auto; padding-top: 1rem;">
26
- {url && (
27
- <p style="margin: 0 0 0.5rem 0;"><a href={url} target="_blank" rel="noopener noreferrer">{label}</a></p>
28
- )}
29
- <p style="margin: 0;"><a href={example.sourceUrl} target="_blank" rel="noopener noreferrer">View Source →</a></p>
30
- </div>
31
- </Card>
32
- );
33
- })}
34
- </CardGrid>
35
-
36
- ## Web Adapter
37
-
38
- - Uses SQLite WASM with OPFS (Origin Private File System) for browser storage
39
- - Runs in Web Workers and SharedWorkers for multi-tab coordination
40
- - Persists data via OPFS Access Handle Pool VFS
41
- - Supports WebSocket connections for sync and devtools
42
-
43
- ## Frameworks
44
-
45
- - React (`@livestore/react`)
46
- - SolidJS (`@livestore/solid`)
47
- - Svelte (`@livestore/svelte`)
48
- - Web Components
49
- - Vanilla JavaScript
50
-
51
- ---
52
- <a href={`https://github.com/livestorejs/livestore/tree/${getBranchName()}/examples`}>View all examples on GitHub →</a>
@@ -1,142 +0,0 @@
1
- # Custom elements
2
-
3
- LiveStore can be used with custom elements/web components.
4
-
5
- ## Example
6
-
7
- See [examples](/examples) for a complete example.
8
-
9
- ## `reference/custom-elements/main.ts`
10
-
11
- ```ts filename="reference/custom-elements/main.ts"
12
-
13
- const adapter = makePersistedAdapter({
14
- storage: { type: 'opfs' },
15
- worker: LiveStoreWorker,
16
- sharedWorker: LiveStoreSharedWorker,
17
- })
18
-
19
- const store = await createStorePromise({ schema, adapter, storeId: 'custom-elements-demo' })
20
-
21
- const visibleTodos$ = queryDb(tables.todos.where({ deletedAt: null }))
22
-
23
- class TodoListElement extends HTMLElement {
24
- private list: HTMLUListElement
25
- private input: HTMLInputElement
26
-
27
- constructor() {
28
- super()
29
- const shadow = this.attachShadow({ mode: 'open' })
30
-
31
- this.input = document.createElement('input')
32
- this.input.placeholder = 'What needs to be done?'
33
-
34
- this.list = document.createElement('ul')
35
- this.list.style.listStyle = 'none'
36
- this.list.style.padding = '0'
37
- this.list.style.margin = '16px 0 0'
38
-
39
- this.input.addEventListener('keydown', (event) => {
40
- if (event.key === 'Enter' && this.input.value.trim()) {
41
- store.commit(events.todoCreated({ id: crypto.randomUUID(), text: this.input.value.trim() }))
42
- this.input.value = ''
43
- }
44
- })
45
-
46
- shadow.append(this.input, this.list)
47
- }
48
-
49
- connectedCallback(): void {
50
- this.renderTodos(Array.from(store.query(tables.todos.where({ deletedAt: null }))))
51
-
52
- store.subscribe(visibleTodos$, (todos) => this.renderTodos(todos))
53
- }
54
-
55
- private renderTodos(todos: ReadonlyArray<typeof tables.todos.Type>): void {
56
- const nodes = Array.from(todos, (todo) => {
57
- const item = document.createElement('li')
58
- item.textContent = todo.text
59
- item.style.cursor = 'pointer'
60
- item.addEventListener('click', () => {
61
- store.commit(todo.completed ? events.todoUncompleted({ id: todo.id }) : events.todoCompleted({ id: todo.id }))
62
- })
63
-
64
- const deleteButton = document.createElement('button')
65
- deleteButton.type = 'button'
66
- deleteButton.textContent = '✕'
67
- deleteButton.style.marginLeft = '8px'
68
- deleteButton.addEventListener('click', (event) => {
69
- event.stopPropagation()
70
- store.commit(events.todoDeleted({ id: todo.id, deletedAt: new Date() }))
71
- })
72
-
73
- const row = document.createElement('div')
74
- row.style.display = 'flex'
75
- row.style.alignItems = 'center'
76
- row.appendChild(item)
77
- row.appendChild(deleteButton)
78
-
79
- const wrapper = document.createElement('li')
80
- wrapper.appendChild(row)
81
- return wrapper
82
- })
83
-
84
- this.list.replaceChildren(...nodes)
85
- }
86
- }
87
-
88
- customElements.define('todo-list', TodoListElement)
89
- ```
90
-
91
- ### `reference/custom-elements/livestore/schema.ts`
92
-
93
- ```ts filename="reference/custom-elements/livestore/schema.ts"
94
-
95
- export const tables = {
96
- todos: State.SQLite.table({
97
- name: 'todos',
98
- columns: {
99
- id: State.SQLite.text({ primaryKey: true }),
100
- text: State.SQLite.text({ default: '' }),
101
- completed: State.SQLite.boolean({ default: false }),
102
- deletedAt: State.SQLite.integer({ nullable: true, schema: Schema.DateFromNumber }),
103
- },
104
- }),
105
- uiState: State.SQLite.clientDocument({
106
- name: 'uiState',
107
- schema: Schema.Struct({ newTodoText: Schema.String }),
108
- default: { id: SessionIdSymbol, value: { newTodoText: '' } },
109
- }),
110
- }
111
-
112
- export const events = {
113
- todoCreated: Events.synced({
114
- name: 'v1.TodoCreated',
115
- schema: Schema.Struct({ id: Schema.String, text: Schema.String }),
116
- }),
117
- todoCompleted: Events.synced({
118
- name: 'v1.TodoCompleted',
119
- schema: Schema.Struct({ id: Schema.String }),
120
- }),
121
- todoUncompleted: Events.synced({
122
- name: 'v1.TodoUncompleted',
123
- schema: Schema.Struct({ id: Schema.String }),
124
- }),
125
- todoDeleted: Events.synced({
126
- name: 'v1.TodoDeleted',
127
- schema: Schema.Struct({ id: Schema.String, deletedAt: Schema.Date }),
128
- }),
129
- uiStateSet: tables.uiState.set,
130
- }
131
-
132
- const materializers = State.SQLite.materializers(events, {
133
- 'v1.TodoCreated': ({ id, text }) => tables.todos.insert({ id, text, completed: false }),
134
- 'v1.TodoCompleted': ({ id }) => tables.todos.update({ completed: true }).where({ id }),
135
- 'v1.TodoUncompleted': ({ id }) => tables.todos.update({ completed: false }).where({ id }),
136
- 'v1.TodoDeleted': ({ id, deletedAt }) => tables.todos.update({ deletedAt }).where({ id }),
137
- })
138
-
139
- const state = State.SQLite.makeState({ tables, materializers })
140
-
141
- export const schema = makeSchema({ events, state })
142
- ```