tanstack-db-pglite 1.0.6 → 1.1.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 CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { CollectionConfig, DeleteMutationFnParams, InsertMutationFnParams, SyncConfig, UpdateMutationFnParams } from '@tanstack/db';
2
2
  import type { IndexColumn, PgTable } from 'drizzle-orm/pg-core';
3
3
  import type { PgliteDatabase } from 'drizzle-orm/pglite';
4
- export declare function drizzleCollectionOptions<Table extends PgTable, SyncParams extends Parameters<SyncConfig<Table['$inferSelect'], string>['sync']>[0] = Parameters<SyncConfig<Table['$inferSelect'], string>['sync']>[0]>({ startSync, ...config }: {
4
+ import type { CreateSelectSchema } from 'drizzle-zod';
5
+ type SyncParams<Table extends PgTable> = Parameters<SyncConfig<Table['$inferSelect'], string>['sync']>[0];
6
+ export declare function drizzleCollectionOptions<Table extends PgTable>({ startSync, ...config }: {
5
7
  db: PgliteDatabase<any>;
6
8
  table: Table;
7
9
  primaryColumn: IndexColumn;
@@ -10,9 +12,8 @@ export declare function drizzleCollectionOptions<Table extends PgTable, SyncPara
10
12
  onDelete?: (params: DeleteMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
11
13
  startSync?: boolean;
12
14
  prepare?: () => Promise<unknown> | unknown;
13
- sync?: (params: Pick<SyncParams, 'write' | 'collection'>) => Promise<void>;
14
- }): CollectionConfig<Table['$inferSelect'], string> & {
15
- utils: {
16
- runSync: () => Promise<void>;
17
- };
18
- };
15
+ sync?: (params: Pick<SyncParams<Table>, 'write' | 'collection'>) => Promise<void>;
16
+ }): CollectionConfig<Table['$inferSelect'], string, ReturnType<CreateSelectSchema<Table['$inferSelect']>>, {
17
+ runSync: () => Promise<void>;
18
+ }>;
19
+ export {};
package/dist/drizzle.js CHANGED
@@ -34,19 +34,20 @@ export function drizzleCollectionOptions({ startSync = true, ...config }) {
34
34
  const getSyncParams = async () => {
35
35
  const params = await syncParams;
36
36
  return {
37
- write: async (p) => {
37
+ write: async (message) => {
38
38
  params.begin();
39
39
  try {
40
- if (p.type === 'insert') {
41
- await onDrizzleInsert([p.value]);
40
+ if (message.type === 'insert') {
41
+ await onDrizzleInsert([message.value]);
42
42
  }
43
- else if (p.type === 'update') {
44
- await onDrizzleUpdate(params.collection.getKeyFromItem(p.value), p.value);
43
+ else if (message.type === 'update') {
44
+ await onDrizzleUpdate(params.collection.getKeyFromItem(message.value), message.value);
45
45
  }
46
- else if (p.type === 'delete') {
47
- await onDrizzleDelete([params.collection.getKeyFromItem(p.value)]);
46
+ else if (message.type === 'delete') {
47
+ const key = 'key' in message ? message.key : params.collection.getKeyFromItem(message.value);
48
+ await onDrizzleDelete([key]);
48
49
  }
49
- params.write(p);
50
+ params.write(message);
50
51
  }
51
52
  finally {
52
53
  params.commit();
@@ -60,7 +61,12 @@ export function drizzleCollectionOptions({ startSync = true, ...config }) {
60
61
  const { begin, write, commit } = await syncParams;
61
62
  begin();
62
63
  mutations.forEach((m) => {
63
- write({ type: m.type, value: m.modified });
64
+ if (m.type === 'delete') {
65
+ write({ type: 'delete', key: m.key });
66
+ }
67
+ else {
68
+ write({ type: m.type, value: m.modified });
69
+ }
64
70
  });
65
71
  commit();
66
72
  }
package/dist/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from './drizzle';
2
+ export * from './sql';
package/dist/index.js CHANGED
@@ -1 +1,2 @@
1
1
  export * from './drizzle';
2
+ export * from './sql';
package/dist/sql.d.ts CHANGED
@@ -1,20 +1,24 @@
1
1
  import type { PGlite } from '@electric-sql/pglite';
2
+ import type { PGliteWorker } from '@electric-sql/pglite/worker';
2
3
  import type { StandardSchemaV1 } from '@standard-schema/spec';
3
4
  import type { CollectionConfig, DeleteMutationFnParams, InsertMutationFnParams, SyncConfig, UpdateMutationFnParams } from '@tanstack/db';
4
- export declare function sqlCollectionOptions<ItemType extends Record<string, unknown>, Schema extends StandardSchemaV1<ItemType, ItemType> = StandardSchemaV1<ItemType, ItemType>, SyncParams extends Parameters<SyncConfig<ItemType, string>['sync']>[0] = Parameters<SyncConfig<ItemType, string>['sync']>[0]>({ startSync, ...config }: {
5
- db: PGlite;
5
+ type Output<T extends StandardSchemaV1> = StandardSchemaV1.InferOutput<T>;
6
+ type SyncParams<ItemType extends Record<string, unknown>> = Parameters<SyncConfig<ItemType, string>['sync']>[0];
7
+ export declare function sqlCollectionOptions<Schema extends StandardSchemaV1<Record<string, unknown>>>({ startSync, ...config }: {
8
+ db: PGlite | PGliteWorker;
6
9
  tableName: string;
7
- primaryKeyColumn: string;
10
+ primaryKeyColumn: Extract<keyof Output<Schema>, string>;
8
11
  schema: Schema;
9
- getKey?: (row: ItemType) => string;
10
- onInsert?: (params: InsertMutationFnParams<ItemType, string>) => Promise<void>;
11
- onUpdate?: (params: UpdateMutationFnParams<ItemType, string>) => Promise<void>;
12
- onDelete?: (params: DeleteMutationFnParams<ItemType, string>) => Promise<void>;
12
+ getKey?: (row: Output<Schema>) => string;
13
+ onInsert?: (params: InsertMutationFnParams<Output<Schema>, string>) => Promise<void>;
14
+ onUpdate?: (params: UpdateMutationFnParams<Output<Schema>, string>) => Promise<void>;
15
+ onDelete?: (params: DeleteMutationFnParams<Output<Schema>, string>) => Promise<void>;
13
16
  startSync?: boolean;
14
17
  prepare?: () => Promise<unknown> | unknown;
15
- sync?: (params: Pick<SyncParams, 'write' | 'collection'>) => Promise<void>;
16
- }): CollectionConfig<ItemType, string> & {
17
- utils: {
18
- runSync: () => Promise<void>;
19
- };
18
+ sync?: (params: Pick<SyncParams<Output<Schema>>, 'write' | 'collection'>) => Promise<void>;
19
+ }): CollectionConfig<Output<Schema>, string, Schema, {
20
+ runSync: () => Promise<void>;
21
+ }> & {
22
+ schema: Schema;
20
23
  };
24
+ export {};
package/dist/sql.js CHANGED
@@ -1,4 +1,5 @@
1
1
  function quoteId(name) {
2
+ // eslint-disable-next-line e18e/prefer-static-regex
2
3
  return `"${String(name).replace(/"/g, '""')}"`;
3
4
  }
4
5
  export function sqlCollectionOptions({ startSync = true, ...config }) {
@@ -6,11 +7,11 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
6
7
  const primaryKey = quoteId(config.primaryKeyColumn);
7
8
  const getKey = config.getKey ?? ((row) => String(row[config.primaryKeyColumn]));
8
9
  const { promise: syncParams, resolve: resolveSyncParams } = Promise.withResolvers();
9
- async function runSelect(conn) {
10
- const result = await conn.query(`SELECT * FROM ${table}`);
10
+ async function runSelect(client) {
11
+ const result = await client.query(`SELECT * FROM ${table}`);
11
12
  return (result.rows ?? []);
12
13
  }
13
- async function runInsert(conn, rows) {
14
+ async function runInsert(client, rows) {
14
15
  for (const row of rows) {
15
16
  const cols = Object.keys(row).filter(k => row[k] !== undefined);
16
17
  if (cols.length === 0)
@@ -18,21 +19,21 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
18
19
  const columns = cols.map(quoteId).join(', ');
19
20
  const placeholders = cols.map((_, i) => `$${i + 1}`).join(', ');
20
21
  const values = cols.map(c => row[c]);
21
- await conn.query(`INSERT INTO ${table} (${columns}) VALUES (${placeholders})`, values);
22
+ await client.query(`INSERT INTO ${table} (${columns}) VALUES (${placeholders})`, values);
22
23
  }
23
24
  }
24
- async function runUpdate(conn, id, changes) {
25
+ async function runUpdate(client, id, changes) {
25
26
  const entries = Object.entries(changes).filter(([, v]) => v !== undefined);
26
27
  if (entries.length === 0)
27
28
  return;
28
29
  const setClause = entries.map(([k], i) => `${quoteId(k)} = $${i + 1}`).join(', ');
29
30
  const params = [...entries.map(([, v]) => v), id];
30
- await conn.query(`UPDATE ${table} SET ${setClause} WHERE ${primaryKey} = $${params.length}`, params);
31
+ await client.query(`UPDATE ${table} SET ${setClause} WHERE ${primaryKey} = $${params.length}`, params);
31
32
  }
32
- async function runDelete(conn, ids) {
33
+ async function runDelete(client, ids) {
33
34
  if (ids.length === 0)
34
35
  return;
35
- await conn.query(`DELETE FROM ${table} WHERE ${primaryKey} = ANY($1)`, [ids]);
36
+ await client.query(`DELETE FROM ${table} WHERE ${primaryKey} = ANY($1)`, [ids]);
36
37
  }
37
38
  const getSyncParams = async () => {
38
39
  const params = await syncParams;
@@ -47,7 +48,8 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
47
48
  await runUpdate(config.db, params.collection.getKeyFromItem(p.value), p.value);
48
49
  }
49
50
  else if (p.type === 'delete') {
50
- await runDelete(config.db, [params.collection.getKeyFromItem(p.value)]);
51
+ const key = 'key' in p ? p.key : params.collection.getKeyFromItem(p.value);
52
+ await runDelete(config.db, [key]);
51
53
  }
52
54
  params.write(p);
53
55
  }
@@ -62,12 +64,17 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
62
64
  const { begin, write, commit } = await syncParams;
63
65
  begin();
64
66
  mutations.forEach((m) => {
65
- write({ type: m.type, value: m.modified });
67
+ if (m.type === 'delete') {
68
+ write({ type: 'delete', key: m.key });
69
+ }
70
+ else {
71
+ write({ type: m.type, value: m.modified });
72
+ }
66
73
  });
67
74
  commit();
68
75
  }
69
76
  return {
70
- startSync: true,
77
+ startSync,
71
78
  sync: {
72
79
  sync: (params) => {
73
80
  resolveSyncParams(params);
@@ -91,7 +98,6 @@ export function sqlCollectionOptions({ startSync = true, ...config }) {
91
98
  },
92
99
  },
93
100
  gcTime: 0,
94
- // @ts-expect-error CollectionConfig schema type does not include StandardSchemaV1
95
101
  schema: config.schema,
96
102
  getKey,
97
103
  onInsert: async (params) => {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "tanstack-db-pglite",
3
- "version": "1.0.6",
4
- "packageManager": "pnpm@10.30.3",
3
+ "version": "1.1.1",
4
+ "packageManager": "pnpm@10.32.1",
5
5
  "description": "",
6
6
  "author": "Valerii Strilets",
7
7
  "license": "MIT",
@@ -42,10 +42,11 @@
42
42
  "drizzle-zod": "^0.8.3"
43
43
  },
44
44
  "devDependencies": {
45
- "@antfu/eslint-config": "^7.6.1",
46
- "eslint": "^10.0.2",
45
+ "@antfu/eslint-config": "^7.7.2",
46
+ "@standard-schema/spec": "^1.1.0",
47
+ "eslint": "^10.0.3",
47
48
  "jiti": "^2.6.1",
48
- "taze": "^19.9.2",
49
+ "taze": "^19.10.0",
49
50
  "typescript": "^5.9.3"
50
51
  }
51
52
  }
@@ -1,20 +0,0 @@
1
- import type { CollectionConfig, DeleteMutationFnParams, InsertMutationFnParams, SyncConfig, UpdateMutationFnParams } from '@tanstack/db';
2
- import type { IndexColumn, PgTable } from 'drizzle-orm/pg-core';
3
- import type { PgliteDatabase } from 'drizzle-orm/pglite';
4
- export declare function drizzleCollectionOptions<Table extends PgTable>({ startSync, ...config }: {
5
- db: PgliteDatabase<any>;
6
- table: Table;
7
- primaryColumn: IndexColumn;
8
- onInsert?: (params: InsertMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
9
- onUpdate?: (params: UpdateMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
10
- onDelete?: (params: DeleteMutationFnParams<Table['$inferSelect'], string>) => Promise<void>;
11
- startSync?: boolean;
12
- sync: {
13
- prepare?: () => Promise<any> | any;
14
- sync: (params: Pick<Parameters<SyncConfig<Table['$inferSelect'], string>['sync']>[0], 'write' | 'collection'>) => Promise<void>;
15
- };
16
- }): CollectionConfig<Table['$inferSelect'], string> & {
17
- utils: {
18
- runSync: () => Promise<void>;
19
- };
20
- };
@@ -1,106 +0,0 @@
1
- import { eq, inArray } from 'drizzle-orm';
2
- import { createSelectSchema } from 'drizzle-zod';
3
- export function drizzleCollectionOptions({ startSync = true, ...config }) {
4
- // Sync params can be null while running PGLite migrations
5
- const { promise: syncParams, resolve: resolveSyncParams } = Promise.withResolvers();
6
- async function runMutations(mutations) {
7
- const { begin, write, commit } = await syncParams;
8
- begin();
9
- mutations.forEach((m) => {
10
- write({ type: m.type, value: m.modified });
11
- });
12
- commit();
13
- }
14
- async function onDrizzleInsert(data) {
15
- // @ts-expect-error drizzle types
16
- await config.db.insert(config.table).values(data);
17
- }
18
- async function onDrizzleUpdate(id, changes) {
19
- await config.db
20
- .update(config.table)
21
- .set(changes)
22
- .where(eq(config.primaryColumn, id));
23
- }
24
- async function onDrizzleDelete(ids) {
25
- await config.db
26
- .delete(config.table)
27
- .where(inArray(config.primaryColumn, ids));
28
- }
29
- const getSyncParams = async () => {
30
- const params = await syncParams;
31
- return {
32
- write: async (p) => {
33
- params.begin();
34
- try {
35
- if (p.type === 'insert') {
36
- await onDrizzleInsert([p.value]);
37
- }
38
- else if (p.type === 'update') {
39
- await onDrizzleUpdate(params.collection.getKeyFromItem(p.value), p.value);
40
- }
41
- else if (p.type === 'delete') {
42
- await onDrizzleDelete([params.collection.getKeyFromItem(p.value)]);
43
- }
44
- params.write(p);
45
- }
46
- finally {
47
- params.commit();
48
- }
49
- },
50
- collection: params.collection,
51
- };
52
- };
53
- return {
54
- startSync: true,
55
- sync: {
56
- sync: async (params) => {
57
- try {
58
- resolveSyncParams(params);
59
- await config.sync.prepare?.();
60
- params.begin();
61
- // @ts-expect-error drizzle types
62
- const dbs = await config.db.select().from(config.table);
63
- dbs.forEach((db) => {
64
- params.write({ type: 'insert', value: db });
65
- });
66
- params.commit();
67
- if (config.sync && startSync) {
68
- await config.sync.sync(await getSyncParams());
69
- }
70
- }
71
- finally {
72
- params.markReady();
73
- }
74
- },
75
- },
76
- gcTime: 0,
77
- schema: createSelectSchema(config.table),
78
- getKey: t => t[config.primaryColumn.name],
79
- onDelete: async (params) => {
80
- await onDrizzleDelete(params.transaction.mutations.map(m => m.key));
81
- const result = await config.onDelete?.(params);
82
- await runMutations(params.transaction.mutations);
83
- return result;
84
- },
85
- onInsert: async (params) => {
86
- await onDrizzleInsert(params.transaction.mutations.map(m => m.modified));
87
- const result = await config.onInsert?.(params);
88
- await runMutations(params.transaction.mutations);
89
- return result;
90
- },
91
- onUpdate: async (params) => {
92
- await Promise.all(params.transaction.mutations.map(m => onDrizzleUpdate(m.key, m.changes)));
93
- const result = await config.onUpdate?.(params);
94
- await runMutations(params.transaction.mutations);
95
- return result;
96
- },
97
- utils: {
98
- runSync: async () => {
99
- const params = await getSyncParams();
100
- // To wait the first sync
101
- await params.collection.stateWhenReady();
102
- await config.sync.sync(params);
103
- },
104
- },
105
- };
106
- }