feat(examples): add op-sqlite persistence to React Native offline-transactions demo#1351
feat(examples): add op-sqlite persistence to React Native offline-transactions demo#1351
Conversation
|
More templates
@tanstack/angular-db
@tanstack/db
@tanstack/db-browser-wa-sqlite-persisted-collection
@tanstack/db-electron-sqlite-persisted-collection
@tanstack/db-ivm
@tanstack/db-node-sqlite-persisted-collection
@tanstack/db-react-native-sqlite-persisted-collection
@tanstack/db-sqlite-persisted-collection-core
@tanstack/electric-db-collection
@tanstack/offline-transactions
@tanstack/powersync-db-collection
@tanstack/query-db-collection
@tanstack/react-db
@tanstack/rxdb-db-collection
@tanstack/solid-db
@tanstack/svelte-db
@tanstack/trailbase-db-collection
@tanstack/vue-db
commit: |
|
Size Change: +1 B (0%) Total Size: 110 kB
ℹ️ View Unchanged
|
|
Size Change: 0 B Total Size: 4.23 kB ℹ️ View Unchanged
|
df61339 to
1c7a974
Compare
37c3bf5 to
ca46819
Compare
ca2c92a to
6798af5
Compare
|
Quick review from GPT5.4: Findings
const { data: todoList = [] } = useLiveQuery((q) =>
q.from({ todo: collection }).orderBy(({ todo }) => todo.createdAt, `desc`),
){/* Todo list */}
{todoList.length === 0 ? (
<View style={styles.emptyContainer}>
<Text style={styles.emptyText}>No todos yet. Add one above!</Text>
<Text style={styles.emptySubtext}>
Todos persist in SQLite and sync to server when online
async function syncTodos({
transaction,
idempotencyKey,
}: {
transaction: { mutations: Array<PendingMutation> }
idempotencyKey: string
}) {
const mutations = transaction.mutations
console.log(
`[Sync] Processing ${mutations.length} mutations`,
idempotencyKey,
)
for (const mutation of mutations) {
try {
switch (mutation.type) {
case `insert`: {
const todoData = mutation.modified as Todo
await todoApi.create({
id: todoData.id,
text: todoData.text,
completed: todoData.completed,// POST create todo
app.post('/api/todos', async (req, res) => {
console.log('POST /api/todos', req.body)
await delay(200)
const { id, text, completed } = req.body
if (!text || text.trim() === '') {
return res.status(400).json({ error: 'Todo text is required' })
}
const now = new Date().toISOString()
const todo: Todo = {
id: id || generateId(),
text,
completed: completed ?? false,
createdAt: now,
updatedAt: now,
}
todosStore.set(todo.id, todo)
import { readFileSync, writeFileSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'
import cors from 'cors'
import express from 'express'
const app = express()
const PORT = 3001
const DATA_FILE = join(dirname(fileURLToPath(import.meta.url)), 'todos.json')No additional React Native example findings stood out beyond those on this pass. |
|
@samwillis Thanks for the review! Finding 1 (loading UX) — Good catch, fixed in 8ed3fd3. Restored Finding 2 (idempotent inserts) — I think this is fine as-is for a demo. The server's Finding 3 (todos.json) — Good catch, fixed in 970bc7d. Added a |
b29e240 to
4daa9f5
Compare
4daa9f5 to
005aab7
Compare
…nsactions demo Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
react-native 0.79.6 accepts react@^19.0.0 as a peer dependency, so upgrading from the pinned 19.0.0 to ^19.2.4 is safe and fixes the sheriff version consistency check. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
react-native 0.79.6 bundles a hardcoded react-native-renderer@19.0.0 which must exactly match the react version at runtime. Exclude the RN example from sherif's version consistency check instead. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Show a loading indicator instead of the empty state while the query is still hydrating, preventing a brief "No todos yet" flash on cold start when existing data needs to be fetched. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The demo server persists todos to server/todos.json at runtime, which would dirty the working tree without an ignore rule. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
005aab7 to
b7c38db
Compare
Summary
Test plan
🤖 Generated with Claude Code