tanstack-db-pglite 1.2.6 → 1.3.1
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.
- package/dist/drizzle.d.ts +10 -1
- package/dist/drizzle.js +37 -26
- package/dist/sql.d.ts +10 -1
- package/dist/sql.js +35 -24
- package/dist/utils.d.ts +0 -1
- package/package.json +3 -3
package/dist/drizzle.d.ts
CHANGED
|
@@ -5,12 +5,21 @@ import type { PgliteDatabase } from 'drizzle-orm/pglite';
|
|
|
5
5
|
import type { PgliteUtils } from './utils';
|
|
6
6
|
type Schema<Table extends PgTable> = StandardSchemaV1<Table['$inferSelect'], Table['$inferSelect']>;
|
|
7
7
|
type SyncParams<Table extends PgTable> = Parameters<SyncConfig<Table['$inferSelect'], string>['sync']>[0];
|
|
8
|
+
/**
|
|
9
|
+
* Creates collection options backed by Drizzle ORM on PGlite.
|
|
10
|
+
*
|
|
11
|
+
* The adapter loads initial data from PGlite before invoking the user-provided `sync` callback.
|
|
12
|
+
* If your sync establishes a real-time subscription, events emitted during the initial PGlite
|
|
13
|
+
* read may be missed. To avoid data loss, subscribe to real-time events first and buffer them
|
|
14
|
+
* until `markReady()` is called.
|
|
15
|
+
*/
|
|
8
16
|
export declare function drizzleCollectionOptions<Table extends PgTable>({ startSync, ...config }: {
|
|
9
17
|
db: PgliteDatabase<any>;
|
|
10
18
|
startSync?: boolean;
|
|
11
19
|
table: Table;
|
|
12
20
|
primaryColumn: IndexColumn;
|
|
13
|
-
|
|
21
|
+
rowUpdateMode?: 'partial' | 'full';
|
|
22
|
+
sync?: (params: Pick<SyncParams<Table>, 'write' | 'collection' | 'markReady' | 'metadata'>) => Promise<(() => void) | void>;
|
|
14
23
|
prepare?: () => Promise<unknown> | unknown;
|
|
15
24
|
onInsert?: (params: InsertMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
|
|
16
25
|
onUpdate?: (params: UpdateMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
|
package/dist/drizzle.js
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import { BasicIndex } from '@tanstack/db';
|
|
2
2
|
import { eq, inArray } from 'drizzle-orm';
|
|
3
3
|
import { createSelectSchema } from 'drizzle-zod';
|
|
4
|
+
/**
|
|
5
|
+
* Creates collection options backed by Drizzle ORM on PGlite.
|
|
6
|
+
*
|
|
7
|
+
* The adapter loads initial data from PGlite before invoking the user-provided `sync` callback.
|
|
8
|
+
* If your sync establishes a real-time subscription, events emitted during the initial PGlite
|
|
9
|
+
* read may be missed. To avoid data loss, subscribe to real-time events first and buffer them
|
|
10
|
+
* until `markReady()` is called.
|
|
11
|
+
*/
|
|
4
12
|
export function drizzleCollectionOptions({ startSync = true, ...config }) {
|
|
5
|
-
let resolvers = Promise.withResolvers();
|
|
6
13
|
// Sync params can be null while running PGLite migrations
|
|
7
14
|
const { promise: syncParams, resolve: resolveSyncParams } = Promise.withResolvers();
|
|
8
15
|
// eslint-disable-next-line ts/no-explicit-any
|
|
@@ -63,15 +70,16 @@ export function drizzleCollectionOptions({ startSync = true, ...config }) {
|
|
|
63
70
|
.from(config.table)
|
|
64
71
|
.where(eq(config.primaryColumn, m.key))));
|
|
65
72
|
}
|
|
66
|
-
const sync = async () => {
|
|
73
|
+
const sync = async (force = false) => {
|
|
74
|
+
const params = await syncParams;
|
|
75
|
+
if (force) {
|
|
76
|
+
params.truncate();
|
|
77
|
+
}
|
|
67
78
|
if (!config.sync) {
|
|
79
|
+
params.markReady();
|
|
68
80
|
return;
|
|
69
81
|
}
|
|
70
|
-
|
|
71
|
-
const previousResolvers = resolvers;
|
|
72
|
-
resolvers = Promise.withResolvers();
|
|
73
|
-
previousResolvers.resolve({ continue: true });
|
|
74
|
-
await config.sync({
|
|
82
|
+
return config.sync({
|
|
75
83
|
write: async (message) => {
|
|
76
84
|
if (message.type === 'insert') {
|
|
77
85
|
await onDrizzleInsert([message.value]);
|
|
@@ -88,37 +96,41 @@ export function drizzleCollectionOptions({ startSync = true, ...config }) {
|
|
|
88
96
|
params.commit();
|
|
89
97
|
},
|
|
90
98
|
collection: params.collection,
|
|
99
|
+
markReady: params.markReady,
|
|
100
|
+
...(params.metadata && { metadata: params.metadata }),
|
|
91
101
|
});
|
|
92
|
-
resolvers.resolve({ continue: false });
|
|
93
|
-
};
|
|
94
|
-
const waitForSync = async () => {
|
|
95
|
-
await resolvers.promise.then(r => r.continue ? waitForSync() : undefined);
|
|
96
102
|
};
|
|
97
103
|
return {
|
|
98
|
-
startSync
|
|
104
|
+
startSync,
|
|
99
105
|
autoIndex: 'eager',
|
|
100
106
|
defaultIndexType: BasicIndex,
|
|
101
107
|
sync: {
|
|
108
|
+
...(config.rowUpdateMode && { rowUpdateMode: config.rowUpdateMode }),
|
|
102
109
|
sync: (params) => {
|
|
103
110
|
resolveSyncParams(params);
|
|
111
|
+
let cleanup;
|
|
104
112
|
(async () => {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
await config.prepare?.();
|
|
114
|
+
// @ts-expect-error drizzle types
|
|
115
|
+
const dbs = await config.db.select().from(config.table);
|
|
116
|
+
params.begin();
|
|
117
|
+
dbs.forEach((db) => {
|
|
118
|
+
params.write({ type: 'insert', value: db });
|
|
119
|
+
});
|
|
120
|
+
params.commit();
|
|
121
|
+
if (startSync) {
|
|
122
|
+
const result = await sync();
|
|
123
|
+
if (typeof result === 'function') {
|
|
124
|
+
cleanup = result;
|
|
116
125
|
}
|
|
117
126
|
}
|
|
118
|
-
|
|
127
|
+
else {
|
|
119
128
|
params.markReady();
|
|
120
129
|
}
|
|
121
130
|
})();
|
|
131
|
+
return () => {
|
|
132
|
+
cleanup?.();
|
|
133
|
+
};
|
|
122
134
|
},
|
|
123
135
|
},
|
|
124
136
|
schema: createSelectSchema(config.table),
|
|
@@ -160,9 +172,8 @@ export function drizzleCollectionOptions({ startSync = true, ...config }) {
|
|
|
160
172
|
}
|
|
161
173
|
const params = await syncParams;
|
|
162
174
|
await params.collection.stateWhenReady();
|
|
163
|
-
await sync();
|
|
175
|
+
await sync(true);
|
|
164
176
|
},
|
|
165
|
-
waitForSync,
|
|
166
177
|
},
|
|
167
178
|
};
|
|
168
179
|
}
|
package/dist/sql.d.ts
CHANGED
|
@@ -5,15 +5,24 @@ import type { CollectionConfig, DeleteMutationFnParams, InsertMutationFnParams,
|
|
|
5
5
|
import type { PgliteUtils } from './utils';
|
|
6
6
|
type Output<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
|
|
7
7
|
type SyncParams<ItemType extends Record<string, unknown>> = Parameters<SyncConfig<ItemType, string>['sync']>[0];
|
|
8
|
+
/**
|
|
9
|
+
* Creates collection options backed by raw SQL on PGlite.
|
|
10
|
+
*
|
|
11
|
+
* The adapter loads initial data from PGlite before invoking the user-provided `sync` callback.
|
|
12
|
+
* If your sync establishes a real-time subscription, events emitted during the initial PGlite
|
|
13
|
+
* read may be missed. To avoid data loss, subscribe to real-time events first and buffer them
|
|
14
|
+
* until `markReady()` is called.
|
|
15
|
+
*/
|
|
8
16
|
export declare function sqlCollectionOptions<Schema extends StandardSchemaV1<Record<string, unknown>>>({ startSync, ...config }: {
|
|
9
17
|
db: PGlite | PGliteWorker;
|
|
10
18
|
startSync?: boolean;
|
|
11
19
|
tableName: string;
|
|
12
20
|
primaryKeyColumn: Extract<keyof Output<Schema>, string>;
|
|
21
|
+
rowUpdateMode?: 'partial' | 'full';
|
|
13
22
|
schema: Schema;
|
|
14
23
|
getKey?: (row: Output<Schema>) => string;
|
|
15
24
|
prepare?: () => Promise<unknown> | unknown;
|
|
16
|
-
sync?: (params: Pick<SyncParams<Output<Schema>>, 'write' | 'collection'>) => Promise<void>;
|
|
25
|
+
sync?: (params: Pick<SyncParams<Output<Schema>>, 'write' | 'collection' | 'markReady' | 'metadata'>) => Promise<(() => void) | void>;
|
|
17
26
|
onInsert?: (params: InsertMutationFnParams<Output<Schema>, string>) => Promise<void>;
|
|
18
27
|
onUpdate?: (params: UpdateMutationFnParams<Output<Schema>, string>) => Promise<void>;
|
|
19
28
|
onDelete?: (params: DeleteMutationFnParams<Output<Schema>, string>) => Promise<void>;
|
package/dist/sql.js
CHANGED
|
@@ -3,8 +3,15 @@ function quoteId(name) {
|
|
|
3
3
|
// eslint-disable-next-line e18e/prefer-static-regex
|
|
4
4
|
return `"${String(name).replace(/"/g, '""')}"`;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Creates collection options backed by raw SQL on PGlite.
|
|
8
|
+
*
|
|
9
|
+
* The adapter loads initial data from PGlite before invoking the user-provided `sync` callback.
|
|
10
|
+
* If your sync establishes a real-time subscription, events emitted during the initial PGlite
|
|
11
|
+
* read may be missed. To avoid data loss, subscribe to real-time events first and buffer them
|
|
12
|
+
* until `markReady()` is called.
|
|
13
|
+
*/
|
|
6
14
|
export function sqlCollectionOptions({ startSync = true, ...config }) {
|
|
7
|
-
let resolvers = Promise.withResolvers();
|
|
8
15
|
const table = quoteId(config.tableName);
|
|
9
16
|
const primaryKey = quoteId(config.primaryKeyColumn);
|
|
10
17
|
const getKey = config.getKey ?? ((row) => String(row[config.primaryKeyColumn]));
|
|
@@ -50,15 +57,16 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
|
|
|
50
57
|
});
|
|
51
58
|
commit();
|
|
52
59
|
}
|
|
53
|
-
const sync = async () => {
|
|
60
|
+
const sync = async (force = false) => {
|
|
61
|
+
const params = await syncParams;
|
|
62
|
+
if (force) {
|
|
63
|
+
params.truncate();
|
|
64
|
+
}
|
|
54
65
|
if (!config.sync) {
|
|
66
|
+
params.markReady();
|
|
55
67
|
return;
|
|
56
68
|
}
|
|
57
|
-
|
|
58
|
-
const previousResolvers = resolvers;
|
|
59
|
-
resolvers = Promise.withResolvers();
|
|
60
|
-
previousResolvers.resolve({ continue: true });
|
|
61
|
-
await config.sync({
|
|
69
|
+
return config.sync({
|
|
62
70
|
write: async (p) => {
|
|
63
71
|
if (p.type === 'insert') {
|
|
64
72
|
await runInsert(config.db, [p.value]);
|
|
@@ -75,36 +83,40 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
|
|
|
75
83
|
params.commit();
|
|
76
84
|
},
|
|
77
85
|
collection: params.collection,
|
|
86
|
+
markReady: params.markReady,
|
|
87
|
+
...(params.metadata && { metadata: params.metadata }),
|
|
78
88
|
});
|
|
79
|
-
resolvers.resolve({ continue: false });
|
|
80
|
-
};
|
|
81
|
-
const waitForSync = async () => {
|
|
82
|
-
await resolvers.promise.then(r => r.continue ? waitForSync() : undefined);
|
|
83
89
|
};
|
|
84
90
|
return {
|
|
85
91
|
startSync,
|
|
86
92
|
autoIndex: 'eager',
|
|
87
93
|
defaultIndexType: BasicIndex,
|
|
88
94
|
sync: {
|
|
95
|
+
...(config.rowUpdateMode && { rowUpdateMode: config.rowUpdateMode }),
|
|
89
96
|
sync: (params) => {
|
|
90
97
|
resolveSyncParams(params);
|
|
98
|
+
let cleanup;
|
|
91
99
|
(async () => {
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
await config.prepare?.();
|
|
101
|
+
const rows = await runSelect(config.db);
|
|
102
|
+
params.begin();
|
|
103
|
+
rows.forEach((row) => {
|
|
104
|
+
params.write({ type: 'insert', value: row });
|
|
105
|
+
});
|
|
106
|
+
params.commit();
|
|
107
|
+
if (startSync) {
|
|
108
|
+
const result = await sync();
|
|
109
|
+
if (typeof result === 'function') {
|
|
110
|
+
cleanup = result;
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
|
-
|
|
113
|
+
else {
|
|
105
114
|
params.markReady();
|
|
106
115
|
}
|
|
107
116
|
})();
|
|
117
|
+
return () => {
|
|
118
|
+
cleanup?.();
|
|
119
|
+
};
|
|
108
120
|
},
|
|
109
121
|
},
|
|
110
122
|
schema: config.schema,
|
|
@@ -143,9 +155,8 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
|
|
|
143
155
|
}
|
|
144
156
|
const params = await syncParams;
|
|
145
157
|
await params.collection.stateWhenReady();
|
|
146
|
-
await sync();
|
|
158
|
+
await sync(true);
|
|
147
159
|
},
|
|
148
|
-
waitForSync,
|
|
149
160
|
},
|
|
150
161
|
};
|
|
151
162
|
}
|
package/dist/utils.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tanstack-db-pglite",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "",
|
|
3
|
+
"version": "1.3.1",
|
|
5
4
|
"author": "Valerii Strilets",
|
|
6
5
|
"license": "MIT",
|
|
7
6
|
"repository": {
|
|
@@ -12,7 +11,8 @@
|
|
|
12
11
|
"tanstack",
|
|
13
12
|
"db",
|
|
14
13
|
"pglite",
|
|
15
|
-
"drizzle"
|
|
14
|
+
"drizzle",
|
|
15
|
+
"sql"
|
|
16
16
|
],
|
|
17
17
|
"main": "dist/index.js",
|
|
18
18
|
"types": "dist/index.d.ts",
|