Skip to content

Commit 3bed14f

Browse files
committed
feat(expo-persistence): add official expo sqlite adapter
Add a dedicated expo-sqlite persistence package with real simulator/emulator smoke coverage so Expo apps can use the official SQLite runtime instead of the op-sqlite wrapper. Made-with: Cursor
1 parent 9ce6ae0 commit 3bed14f

29 files changed

Lines changed: 4942 additions & 60 deletions
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# @tanstack/db-expo-sqlite-persisted-collection
2+
3+
Thin SQLite persistence for Expo apps using the official `expo-sqlite` adapter.
4+
5+
## Public API
6+
7+
- `createExpoSQLitePersistence(...)`
8+
- `persistedCollectionOptions(...)` (re-exported from core)
9+
10+
## Quick start
11+
12+
```ts
13+
import * as SQLite from 'expo-sqlite'
14+
import { createCollection } from '@tanstack/db'
15+
import {
16+
createExpoSQLitePersistence,
17+
persistedCollectionOptions,
18+
} from '@tanstack/db-expo-sqlite-persisted-collection'
19+
20+
type Todo = {
21+
id: string
22+
title: string
23+
completed: boolean
24+
}
25+
26+
const database = await SQLite.openDatabaseAsync(`tanstack-db.sqlite`)
27+
28+
// One shared persistence instance for the whole database.
29+
const persistence = createExpoSQLitePersistence({
30+
database,
31+
})
32+
33+
export const todosCollection = createCollection(
34+
persistedCollectionOptions<Todo, string>({
35+
id: `todos`,
36+
getKey: (todo) => todo.id,
37+
persistence,
38+
schemaVersion: 1, // Per-collection schema version
39+
}),
40+
)
41+
```
42+
43+
## Notes
44+
45+
- This package targets the official `expo-sqlite` async database API.
46+
- `createExpoSQLitePersistence` is shared across collections.
47+
- Mode defaults (`sync-present` vs `sync-absent`) are inferred from whether a
48+
`sync` config is present in `persistedCollectionOptions`.
49+
- The React Native `op-sqlite` wrapper remains available in
50+
`@tanstack/db-react-native-sqlite-persisted-collection`.
51+
- Expo web is not part of the emulator-backed E2E path in this package. Use the
52+
browser SQLite package for browser-focused persistence coverage.
53+
54+
## E2E
55+
56+
- `pnpm --filter @tanstack/db-expo-sqlite-persisted-collection test:e2e`
57+
runs the shared Node-backed conformance suite.
58+
- `pnpm --filter @tanstack/db-expo-sqlite-persisted-collection test:e2e:expo:ios`
59+
runs the real Expo iOS Simulator path.
60+
- `pnpm --filter @tanstack/db-expo-sqlite-persisted-collection test:e2e:expo:android`
61+
runs the real Expo Android Emulator path.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { expect, it } from 'vitest'
2+
import { ensureExpoEmulatorRuntime } from '../tests/helpers/expo-emulator-runtime'
3+
4+
const runtimePlatform = process.env.TANSTACK_DB_EXPO_RUNTIME_PLATFORM?.trim()
5+
const shouldRun =
6+
runtimePlatform === `ios` || runtimePlatform === `android`
7+
8+
it.runIf(shouldRun)(
9+
`runs a persistence smoke test inside a real Expo runtime`,
10+
async () => {
11+
const runtime = await ensureExpoEmulatorRuntime(
12+
runtimePlatform === `android` ? `android` : `ios`,
13+
)
14+
const smokeResult = await runtime.runPersistenceSmokeTest(
15+
`expo-runtime-smoke.sqlite`,
16+
)
17+
18+
expect(smokeResult.insertedTitle).toBe(`Persisted from Expo runtime`)
19+
expect(smokeResult.reloadedCount).toBe(1)
20+
},
21+
)
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { it } from 'vitest'
2+
import { createExpoSQLitePersistence } from '../src'
3+
import { runMobilePersistedCollectionConformanceSuite } from './mobile-persisted-collection-conformance-suite'
4+
5+
const runtimePlatform = process.env.TANSTACK_DB_EXPO_RUNTIME_PLATFORM?.trim()
6+
7+
if (!runtimePlatform) {
8+
runMobilePersistedCollectionConformanceSuite(
9+
`expo persisted collection conformance`,
10+
(database) => createExpoSQLitePersistence({ database }),
11+
)
12+
} else {
13+
it.skip(`runs the conformance suite in shimmed e2e mode only`, () => {})
14+
}

0 commit comments

Comments
 (0)