tanstack-db-pglite 1.3.5 → 1.3.7

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 (2) hide show
  1. package/README.md +133 -24
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,25 +1,34 @@
1
1
  # tanstack-db-pglite
2
2
 
3
- A seamless integration between [TanStack DB](https://tanstack.com/db) and [PGLite](https://github.com/electric-sql/pglite) with [Drizzle ORM](https://orm.drizzle.team/) for browser-based database management.
3
+ A seamless integration between [TanStack DB](https://tanstack.com/db) and [PGLite](https://github.com/electric-sql/pglite) with optional [Drizzle ORM](https://orm.drizzle.team/) support for browser-based database management.
4
4
 
5
5
  ## Installation
6
6
 
7
7
  ```bash
8
- npm install tanstack-db-pglite @tanstack/db drizzle-orm @electric-sql/pglite
8
+ npm install tanstack-db-pglite @tanstack/db @electric-sql/pglite
9
9
  ```
10
10
 
11
- > **Note:** `@tanstack/db` and `drizzle-orm` are peer dependencies and must be installed separately.
11
+ > **Note:** `@tanstack/db` and `@electric-sql/pglite` are peer dependencies. `drizzle-orm` is an optional peer dependency required only when using `drizzleCollectionOptions`.
12
12
 
13
- ## Quick Start
13
+ ## APIs
14
+
15
+ This package exports two collection option creators:
16
+
17
+ - `drizzleCollectionOptions` — uses Drizzle ORM on top of PGlite
18
+ - `sqlCollectionOptions` — uses raw SQL queries directly on PGlite
19
+
20
+ Both follow the TanStack DB [collection options creator](https://tanstack.com/db/latest/docs/guides/collection-options-creator) pattern.
21
+
22
+ ## Quick Start (Drizzle)
14
23
 
15
24
  ```typescript
16
- import { PGLite } from '@electric-sql/pglite'
25
+ import { PGlite } from '@electric-sql/pglite'
17
26
  import { createCollection } from '@tanstack/react-db'
18
27
  import { drizzle } from 'drizzle-orm/pglite'
19
28
  import { drizzleCollectionOptions } from 'tanstack-db-pglite'
20
29
  import { chats } from '~/drizzle'
21
30
 
22
- const pglite = new PGLite()
31
+ const pglite = new PGlite()
23
32
  const db = drizzle(pglite)
24
33
 
25
34
  export const chatsCollection = createCollection(drizzleCollectionOptions({
@@ -27,26 +36,21 @@ export const chatsCollection = createCollection(drizzleCollectionOptions({
27
36
  table: chats,
28
37
  primaryColumn: chats.id,
29
38
  prepare: async () => {
30
- // Prepare your database before starting the collection (e.g., run migrations)
31
39
  await waitForMigrations()
32
40
  },
33
- sync: async ({ collection, write }) => {
34
- // Send some data to your backend to sync and receive the response
35
- const sync = await syncWithCloud(
36
- collection.toArray.map(c => ({
37
- id: c.id,
38
- updatedAt: c.updatedAt
39
- }))
40
- )
41
-
42
- sync.forEach((item) => {
43
- if (item.type === 'delete') {
44
- write({ type: 'delete', value: collection.get(item.value)! })
45
- }
46
- else {
47
- write(item)
48
- }
49
- })
41
+ sync: async ({ write, markReady }) => {
42
+ const eventSource = new EventSource('/api/chats/sync')
43
+
44
+ eventSource.onmessage = (event) => {
45
+ const item = JSON.parse(event.data)
46
+ write(item)
47
+ }
48
+
49
+ eventSource.addEventListener('ready', () => markReady())
50
+
51
+ return () => {
52
+ eventSource.close()
53
+ }
50
54
  },
51
55
  onInsert: async (params) => {
52
56
  await saveInCloud(params)
@@ -59,3 +63,108 @@ export const chatsCollection = createCollection(drizzleCollectionOptions({
59
63
  },
60
64
  }))
61
65
  ```
66
+
67
+ ## Quick Start (Raw SQL)
68
+
69
+ ```typescript
70
+ import { PGlite } from '@electric-sql/pglite'
71
+ import { createCollection } from '@tanstack/react-db'
72
+ import { sqlCollectionOptions } from 'tanstack-db-pglite'
73
+ import { z } from 'zod'
74
+
75
+ const pglite = new PGlite()
76
+
77
+ const chatSchema = z.object({
78
+ id: z.string(),
79
+ name: z.string(),
80
+ updatedAt: z.string(),
81
+ })
82
+
83
+ export const chatsCollection = createCollection(sqlCollectionOptions({
84
+ db: pglite,
85
+ tableName: 'chats',
86
+ primaryKeyColumn: 'id',
87
+ schema: chatSchema,
88
+ prepare: async () => {
89
+ await pglite.query(`
90
+ CREATE TABLE IF NOT EXISTS chats (
91
+ id TEXT PRIMARY KEY,
92
+ name TEXT NOT NULL,
93
+ "updatedAt" TEXT NOT NULL
94
+ )
95
+ `)
96
+ },
97
+ sync: async ({ write, markReady }) => {
98
+ const eventSource = new EventSource('/api/chats/sync')
99
+
100
+ eventSource.onmessage = (event) => {
101
+ const item = JSON.parse(event.data)
102
+ write(item)
103
+ }
104
+
105
+ eventSource.addEventListener('ready', () => markReady())
106
+
107
+ return () => {
108
+ eventSource.close()
109
+ }
110
+ },
111
+ }))
112
+ ```
113
+
114
+ ## Options
115
+
116
+ ### Common Options
117
+
118
+ | Option | Type | Description |
119
+ |--------|------|-------------|
120
+ | `startSync` | `boolean` | Whether to run the `sync` callback automatically on startup. Defaults to `true`. When `false`, use `collection.utils.runSync()` to trigger manually. |
121
+ | `prepare` | `() => Promise<unknown> \| unknown` | Runs before the initial data load (e.g., run migrations). |
122
+ | `sync` | `(params) => Promise<(() => void) \| void>` | Sync callback receiving `write`, `markReady`, `collection`, and `metadata`. Return a cleanup function to close subscriptions. |
123
+ | `rowUpdateMode` | `'partial' \| 'full'` | Whether sync updates contain partial changes or full row replacements. |
124
+ | `onInsert` | `(params) => Promise<void>` | Called when a row is inserted optimistically. Persist to your backend here. |
125
+ | `onUpdate` | `(params) => Promise<void>` | Called when a row is updated optimistically. Persist to your backend here. |
126
+ | `onDelete` | `(params) => Promise<void>` | Called when a row is deleted optimistically. Persist to your backend here. |
127
+
128
+ ### `drizzleCollectionOptions` Specific
129
+
130
+ | Option | Type | Description |
131
+ |--------|------|-------------|
132
+ | `db` | `PgliteDatabase` | Drizzle PGlite database instance. |
133
+ | `table` | `PgTable` | Drizzle table definition. |
134
+ | `primaryColumn` | `IndexColumn` | The primary key column from the table. |
135
+
136
+ ### `sqlCollectionOptions` Specific
137
+
138
+ | Option | Type | Description |
139
+ |--------|------|-------------|
140
+ | `db` | `PGlite \| PGliteWorker` | PGlite instance (or worker). |
141
+ | `tableName` | `string` | SQL table name. |
142
+ | `primaryKeyColumn` | `string` | Name of the primary key column. |
143
+ | `schema` | `StandardSchemaV1` | A Standard Schema (e.g., Zod) for the row type. |
144
+ | `getKey` | `(row) => string` | Custom key extractor. Defaults to `row[primaryKeyColumn]`. |
145
+
146
+ ## Utilities
147
+
148
+ Both adapters expose a `utils` object on the collection:
149
+
150
+ ```typescript
151
+ // Manually trigger sync (cleans up any previous sync, then re-syncs)
152
+ await chatsCollection.utils.runSync()
153
+ ```
154
+
155
+ This is useful when `startSync: false` and you want to control when sync starts (e.g., after authentication).
156
+
157
+ ## Sync Callback
158
+
159
+ The `sync` callback receives:
160
+
161
+ - **`write(message)`** — writes a change to both PGlite and the TanStack DB collection. Accepts `{ type: 'insert', value }`, `{ type: 'update', value }`, or `{ type: 'delete', key }`.
162
+ - **`markReady()`** — signals that the initial data is loaded and the collection is ready for queries. Must be called once.
163
+ - **`collection`** — reference to the collection instance.
164
+ - **`metadata`** — persisted sync metadata API for storing resume tokens, cursors, etc.
165
+
166
+ Return a cleanup function to close long-lived connections (WebSocket, EventSource, etc.) when the collection is destroyed or `runSync()` is called again.
167
+
168
+ ## License
169
+
170
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tanstack-db-pglite",
3
- "version": "1.3.5",
3
+ "version": "1.3.7",
4
4
  "author": "Valerii Strilets",
5
5
  "license": "MIT",
6
6
  "repository": {