Repository navigation
Conversation
This was referenced Nov 2, 2026
`DatabaseOptions` takes `{ kind: "pglite" }`; `{ url, ... }` is unchanged.
`makePgliteTransport` runs an in-memory PGlite: it shares the transaction
bridge with Postgres, has nothing to retry, and needs no advisory lock.
- `runTransaction` is the Effect-to-promise bridge from the Postgres
transaction, with the commit-status check as a Postgres-only hook.
- `Drizzle` is the driver-neutral `PgDatabase`, and
`selectMaxExecutionIndex` selects from the subquery instead of reading
`db.execute`, whose result has a different shape on each driver.
- `makeDbClient` fails when the database is used inside a transaction
instead of `tx`, including from fibers that `f` forks. That statement
runs outside the transaction on Postgres, and waits on it forever on
PGlite, whose one session the transaction holds. Transactions from
separate fibers queue behind each other on PGlite's own mutex.
PGlite reads a text value that starts with U+FEFF without it: its
protocol reader decodes each field with a `TextDecoder` that strips a
leading BOM. It is documented on `makePgliteTransport`, with no
workaround yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kyscott18
force-pushed
the
feat/db-pglite
branch
from
November 2, 2026 21:22
49ebafe to
f2f530c
Compare
kyscott18
marked this pull request as ready for review
November 2, 2026 21:22
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second of four stacked PRs, on #112: db transport → PGlite transport → sim DB as a transport with injected errors → PGlite for the sim.
DatabaseOptionstakes{ kind: "pglite" }, an in-memory PGlite that lasts as long as the process.{ url, ... }is unchanged (kindis optional for Postgres), so existing configs keep working.makePgliteTransport(@electric-sql/pglite0.5.8, the version abipg already pins): a real PGlite transaction, no retries (notAppliedis never set: there is no connection to lose), and a no-op advisory lock (only this process can reach an in-memory database).runTransactionis the Effect-to-promise bridge, taken out of the Postgres transaction so both transports share it; the commit-status check stays a Postgres-only hook. A failed statement still fails the transaction even iffrecovers. On PGlite, aCOMMITafter a failed statement silently rolls back and resolves.Drizzleis now the driver-neutralPgDatabase<PgQueryResultHKT>.selectMaxExecutionIndexselects from the subquery (max(max)::text) instead of readingdb.execute, which returns{ rows }on PGlite but an array on Bun SQL.Transaction guard. PGlite has one session. Its
query/transactionalready queue behind an open transaction, so transactions from separate fibers can't overlap. The real hazard is a statement ondbinstead oftxinsidef. On PGlite that waits on its own transaction forever; on Postgres it silently runs outside the transaction.makeDbClientrunsfwith anInTransactionreference, andquery/transactiondie when it is set, including in fibers thatfforks.Known issue, no workaround yet. PGlite reads a text value that starts with U+FEFF (a BOM) without it. Its protocol reader decodes each field with
new TextDecoder("utf-8"), which strips a leading BOM by default; the stored bytes are correct. Still the case in 0.5.14. Documented onmakePgliteTransport. The runtime never reads text columns back, and the sim stores no strings since #111, so nothing here is affected.db-query.test.tsstays on Postgres: pointed at PGlite, its BOM case fails and every other string passes.Checked:
bun testwithDATABASE_URL(84 pass);db.queryinfand in a forked fiber die, whiletx.queryand two fibers' concurrent transactions pass;0xe,0x11,0x41pass on Postgres, the same as refactor(typewriter): split the database into a transport and a client #112.🤖 Generated with Claude Code