Usage with drizzle in React?
const client = await PGlite.create({
dataDir: "idb://pgdata",
extensions: { live },
});
const db = drizzle({ client, schema: { usersTable } });
Is it possible to make PGliteProvider accept drizzle and make it work with useLiveQuery? The usePGlite works, the types are wrong though.
I created my own custom wrapper for useLiveQuery that uses injected drizzle statements. The final hook actually ended up being quite simple!
/**
/* Hook
/**
import { useLiveIncrementalQuery } from "@electric-sql/pglite-react";
import type { Query } from "drizzle-orm";
export const useSubscription = (query: Query, key: string) => {
const res = useLiveIncrementalQuery(query.sql, query.params, key);
if (!res) {
return {
status: "loading",
};
}
return {
status: "success",
data: res.rows,
};
};
/**
/* Usage
/**
const me = useSubscription(
db.query.usersTable
.findFirst({
where: (users, { eq }) => eq(users.uuid, userUuid),
})
.toSQL(),
"uuid",
);
Hope this helps!
EDIT:
After fooling around a bit more. I managed to keep the drizzle type-inference!
interface LoadingState {
status: "loading";
}
interface SuccessState<T> {
status: "success";
data: T[];
}
type SubscriptionResult<T> = LoadingState | SuccessState<T>;
export const useSubscription = <T>(
query: PgRelationalQuery<T>,
key: string,
): SubscriptionResult<T> => {
const sql = query.toSQL();
const res = useLiveIncrementalQuery(sql.sql, sql.params, key);
if (!res) {
return {
status: "loading",
};
}
return {
status: "success",
data: res.rows as T[],
};
};
Happy coding!
@SemStassen The hook looks clever! I can't get it all to work though. How do you feed your PGliteProvider? Or are you using db from drizzle directly?
@JanChodorowski
The db is indeed from drizzle directly.
However I do still expose the PG instance through the PGliteProvider.
export const pg = await PGliteWorker.create(new PGWorker(), {
extensions: {
live,
sync: electricSync(),
},
});
/**
/* This is the drizzle-orm instance we use in the useSubscription hook!
/**
export const db = drizzle({ client: pg, schema: schema });
export const MasonPGliteProvider = ({
children,
}: { children: React.ReactNode }) => {
return <PGliteProvider db={pg}>{children}</PGliteProvider>;
};
Hope this helps!
just chiming in to say there is a really decent lib published for this
https://jsr.io/@makisuo/pglite-drizzle
The db is indeed from drizzle directly.
However I do still expose the PG instance through the PGliteProvider.
export const pg = await PGliteWorker.create(new PGWorker(), { extensions: { live, sync: electricSync(), ...
Do you have or would you be willing to create a repo with a simple hello world version of this example to see how you stitch this all together?
This seems like a very nice and simple way to do things and can probably figure it out from here either way. Thank you