Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .changeset/update-agent-skills.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
'@tanstack/angular-db': patch
'@tanstack/db': patch
'@tanstack/offline-transactions': patch
'@tanstack/react-db': patch
'@tanstack/solid-db': patch
'@tanstack/svelte-db': patch
'@tanstack/vue-db': patch
---

Update agent skills to match current APIs and behavior.
6 changes: 5 additions & 1 deletion packages/angular-db/skills/angular-db/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ description: >
type: framework
library: db
framework: angular
library_version: '0.6.0'
library_version: '0.6.17'
requires:
- db-core
sources:
Expand Down Expand Up @@ -101,6 +101,10 @@ const query = injectLiveQuery({
})
```

A bare `{ query }` config defaults to `startSync: true` and `gcTime: 0`, like
the query-function overload. Explicit values in the config override those
defaults.

## Angular-Specific Patterns

### Reactive params with signals
Expand Down
6 changes: 3 additions & 3 deletions packages/db/skills/db-core/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ name: db-core
description: >
TanStack DB core concepts: createCollection with queryCollectionOptions,
electricCollectionOptions, powerSyncCollectionOptions, rxdbCollectionOptions,
trailbaseCollectionOptions, localOnlyCollectionOptions. Live queries via
trailBaseCollectionOptions, localOnlyCollectionOptions. Live queries via
query builder (from, where, join, select, groupBy, orderBy, limit). Optimistic
mutations with draft proxy (collection.insert, collection.update,
collection.delete). createOptimisticAction, createTransaction,
createPacedMutations. Entry point for all TanStack DB skills.
type: core
library: db
library_version: '0.6.0'
library_version: '0.6.17'
---

# TanStack DB — Core Concepts
Expand Down Expand Up @@ -60,4 +60,4 @@ For framework-specific hooks:

## Version

Targets @tanstack/db v0.6.0.
Targets @tanstack/db v0.6.17.
33 changes: 24 additions & 9 deletions packages/db/skills/db-core/collection-setup/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,17 @@ description: >
Creating typed collections with createCollection. Adapter selection:
queryCollectionOptions (REST/TanStack Query), electricCollectionOptions
(ElectricSQL real-time sync), powerSyncCollectionOptions (PowerSync SQLite),
rxdbCollectionOptions (RxDB), trailbaseCollectionOptions (TrailBase),
rxdbCollectionOptions (RxDB), trailBaseCollectionOptions (TrailBase),
localOnlyCollectionOptions, localStorageCollectionOptions. CollectionConfig
options: getKey, schema, sync, gcTime, autoIndex (default off), defaultIndexType,
syncMode (eager/on-demand, plus progressive for Electric). StandardSchema validation
with Zod/Valibot/ArkType. Collection lifecycle (idle/loading/ready/error).
Adapter-specific sync patterns including Electric txid tracking, Query direct
writes, and PowerSync query-driven sync with onLoad/onLoadSubset hooks.
writes, Query initial data and scoped factories, and PowerSync query-driven
sync with onLoad/onLoadSubset hooks.
type: sub-skill
library: db
library_version: '0.6.0'
library_version: '0.6.17'
sources:
- 'TanStack/db:docs/overview.md'
- 'TanStack/db:docs/guides/schemas.md'
Expand Down Expand Up @@ -80,7 +81,7 @@ const todoCollection = createCollection(
| ElectricSQL (real-time Postgres) | `electricCollectionOptions` | `@tanstack/electric-db-collection` |
| PowerSync (SQLite offline) | `powerSyncCollectionOptions` | `@tanstack/powersync-db-collection` |
| RxDB (reactive database) | `rxdbCollectionOptions` | `@tanstack/rxdb-db-collection` |
| TrailBase (event streaming) | `trailbaseCollectionOptions` | `@tanstack/trailbase-db-collection` |
| TrailBase (event streaming) | `trailBaseCollectionOptions` | `@tanstack/trailbase-db-collection` |
| No backend (UI state) | `localOnlyCollectionOptions` | `@tanstack/db` |
| Browser localStorage | `localStorageCollectionOptions` | `@tanstack/db` |

Expand Down Expand Up @@ -218,7 +219,10 @@ queryCollectionOptions({
})
```

`queryFn` result is treated as complete server state. Returning `[]` means "server has no items", deleting all existing collection data.
In eager mode, `queryFn` is complete collection state. Returning `[]` means
"the server has no items" and removes all rows. In on-demand mode, a result is
complete only for that exact subset/Query key; an empty result releases that
subset's ownership, while overlapping subsets can keep shared rows.

Source: docs/collections/query-collection.md

Expand Down Expand Up @@ -309,7 +313,9 @@ queryCollectionOptions({
})
```

`queryFn` result replaces all collection data. For incremental fetches, merge with existing data.
An eager `queryFn` result replaces all collection data. For incremental eager
fetches, merge with existing data. In on-demand mode, return the complete state
for the requested subset instead.

Source: docs/collections/query-collection.md

Expand Down Expand Up @@ -390,11 +396,20 @@ When a schema transforms types, `TInput` must accept both the pre-transform and

Source: docs/guides/schemas.md

### HIGH React Native missing crypto.randomUUID polyfill
### HIGH Runtime has no secure random number generator

TanStack DB uses `crypto.randomUUID()` internally. React Native doesn't provide this. Install `react-native-random-uuid` and import it at your app entry point.
TanStack DB's `safeRandomUUID()` uses `crypto.randomUUID()` when available and
falls back to `crypto.getRandomValues()`, including on non-secure HTTP origins.
Add a Web Crypto polyfill only in runtimes, including some React Native
versions, that provide neither API.

Source: docs/overview.md
```ts
import { safeRandomUUID } from '@tanstack/db'

collection.insert({ id: safeRandomUUID(), text: 'New item' })
```

Source: packages/db/src/utils/uuid.ts, packages/db/tests/uuid.test.ts

### MEDIUM Providing both explicit type parameter and schema

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,23 @@ const collection = createCollection(
| `id` | (none) | Unique collection identifier |
| `schema` | (none) | StandardSchema validator |
| `shapeOptions.params` | (none) | Additional shape params (e.g. `{ table: 'todos' }`) |
| `syncMode` | `eager` | `eager`, `on-demand`, or `progressive` |
| `onInsert` | (none) | Persistence handler; should return `{ txid }` |
| `onUpdate` | (none) | Persistence handler; should return `{ txid }` |
| `onDelete` | (none) | Persistence handler; should return `{ txid }` |

## Sync Modes

- `eager` loads the full shape before use.
- `on-demand` loads only the subsets requested by live queries.
- `progressive` loads the requested subset first, then completes the full sync
in the background.

With SQLite persistence, progressive resume keeps hydrated rows visible while
the full Electric stream resumes. On-demand subset snapshots use a bounded
refresh wait, so a stalled native long-poll refresh does not block loading
forever.

## Three Sync Strategies

### 1. Txid Return (Recommended)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,18 @@ import {

const collection = createCollection(
localOnlyCollectionOptions({
id: 'ui-state',
getKey: (item) => item.id,
}),
)
```

- `id` -- unique collection identifier
- `getKey` -- extracts unique key from each item

### Optional Config

| Option | Default | Description |
| ------------- | ------- | -------------------------------------- |
| `id` | UUID | Unique collection identifier |
| `schema` | (none) | StandardSchema validator |
| `initialData` | (none) | Array of items to populate on creation |
| `onInsert` | (none) | Handler before confirming inserts |
Expand Down Expand Up @@ -101,27 +100,26 @@ import {

const collection = createCollection(
localStorageCollectionOptions({
id: 'user-preferences',
storageKey: 'app-user-prefs',
getKey: (item) => item.id,
}),
)
```

- `id` -- unique collection identifier
- `storageKey` -- localStorage key for all collection data
- `getKey` -- extracts unique key from each item

### Optional Config

| Option | Default | Description |
| ----------------- | -------------- | -------------------------------------------------------------------- |
| `schema` | (none) | StandardSchema validator |
| `storage` | `localStorage` | Custom storage (`sessionStorage` or any localStorage-compatible API) |
| `storageEventApi` | `window` | Event API for cross-tab sync |
| `onInsert` | (none) | Handler on insert |
| `onUpdate` | (none) | Handler on update |
| `onDelete` | (none) | Handler on delete |
| Option | Default | Description |
| ----------------- | ---------------- | -------------------------------------------------------------------- |
| `id` | From storage key | `local-collection:${storageKey}` |
| `schema` | (none) | StandardSchema validator |
| `storage` | `localStorage` | Custom storage (`sessionStorage` or any localStorage-compatible API) |
| `storageEventApi` | `window` | Event API for cross-tab sync |
| `onInsert` | (none) | Handler on insert |
| `onUpdate` | (none) | Handler on update |
| `onDelete` | (none) | Handler on delete |

### Using sessionStorage

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pnpm add @tanstack/powersync-db-collection @powersync/web @journeyapps/wa-sqlite
## Required Config

```typescript
import { createCollection } from '@tanstack/react-db'
import { createCollection, safeRandomUUID } from '@tanstack/react-db'
import { powerSyncCollectionOptions } from '@tanstack/powersync-db-collection'
import { Schema, Table, column, PowerSyncDatabase } from '@powersync/web'

Expand Down Expand Up @@ -164,7 +164,7 @@ const APP_SCHEMA = new Schema({
})

await collection.insert(
{ id: crypto.randomUUID(), name: 'Report' },
{ id: safeRandomUUID(), name: 'Report' },
{ metadata: { source: 'web-app', userId: 'user-123' } },
).isPersisted.promise
```
Expand All @@ -187,7 +187,7 @@ const tx = createTransaction({
})
tx.mutate(() => {
documentsCollection.insert({
id: crypto.randomUUID(),
id: safeRandomUUID(),
name: 'Doc 1',
created_at: new Date().toISOString(),
})
Expand Down
Loading
Loading