electric-sql / pglite

Lightweight WASM Postgres with real-time, reactive bindings.
https://pglite.dev
Apache License 2.0
7.99k stars 152 forks source link

Support Deno #191

Closed alexgleason closed 3 weeks ago

alexgleason commented 1 month ago

I really want to use pglite, but I need it to work in Deno. It's so close. It should work. But it just doesn't for some reason. It may be something we can work around on the pglite side, or if we can pinpoint the exact issue we can open an issue in the Deno repository and they will likely fix it.

Previously we debugged it here: https://github.com/electric-sql/pglite/pull/3#issuecomment-1967274794 But now the issue is different.

With pglite 0.2.0 and Deno, v1.45.5, I'm seeing this behavior:

➜  ~ deno         
Deno 1.45.5
exit using ctrl+d, ctrl+c, or close()
REPL is running with all permissions allowed.
To specify permissions, run `deno repl` with allow flags.
> import { PGlite } from "npm:@electric-sql/pglite@0.2.0";
undefined
> const db = new PGlite("./pgdata");
undefined
> prerun(C-node) worker= false
Running in main thread, faking onCustomMessage
> await db.query('create table test (id int);');
Uncaught TypeError: expected typed ArrayBufferView
    at Module.writeSync (ext:deno_io/12_io.js:122:15)
    at innerWriteSync (ext:deno_node/_fs/_fs_write.mjs:35:27)
    at Object.writeSync (ext:deno_node/_fs/_fs_write.mjs:53:12)
    at file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:125306
    at Object.tryFSOperation (file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:121629)
    at Object.write (file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:125284)
    at Object.write (file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:142636)
    at doWritev (file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:216886)
    at _fd_write (file:///home/alex/.cache/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:218357)
    at <anonymous> (wasm://wasm/01c8086e:1:5297298)

The ./pgdata directory is being created:

➜  ~ ls pgdata 
base    pg_commit_ts  pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal
global  pg_dynshmem   pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact

I think this is actually an improvement over how it was before?

But I still can't query it.

alexgleason commented 1 month ago

Deno already fixed the ArrayBufferView problem upstream, but now they are running into a different issue. See: https://github.com/denoland/deno/issues/25028#issuecomment-2289715916

prerun(C-node) worker= false
Running in main thread, faking onCustomMessage
error: Uncaught (in promise) RuntimeError: Aborted(). Build with -sASSERTIONS for more info.
    at abort (file:///Users/nathanwhit/Library/Caches/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:76250)
    at __abort_js (file:///Users/nathanwhit/Library/Caches/deno/npm/registry.npmjs.org/@electric-sql/pglite/0.2.0/dist/postgres.js:9:189060)
    at <anonymous> (wasm://wasm/01c8086e:1:5297547)
    at <anonymous> (wasm://wasm/01c8086e:1:1979957)
    at <anonymous> (wasm://wasm/01c8086e:1:1969165)
    at <anonymous> (wasm://wasm/01c8086e:1:2251556)
    at <anonymous> (wasm://wasm/01c8086e:1:2229558)
    at <anonymous> (wasm://wasm/01c8086e:1:2266472)
    at <anonymous> (wasm://wasm/01c8086e:1:3323992)
    at <anonymous> (wasm://wasm/01c8086e:1:5119845)

If anyone here knows what that could be, please comment on https://github.com/denoland/deno/issues/25028#issuecomment-2289715916

nerochiaro commented 1 month ago

In case it helps pinpoint the issue, note that I get that same error when passing a path to the constructor for creating on-disk data. But it seems to work just fine when used in-memory (i.e. without passing anything to the constructor)

import { PGlite } from "npm:@electric-sql/pglite@0.2.0";
const db = new PGlite()
console.log(await db.query("select 'Hello world' as message;"))
❯ deno --version
deno 1.45.5 (release, x86_64-unknown-linux-gnu)
v8 12.7.224.13
typescript 5.5.2
❯ deno run --allow-read localdb.ts
prerun(C-node) worker= false
Running in main thread, faking onCustomMessage
{
  rows: [ { message: "Hello world" } ],
  fields: [ { name: "message", dataTypeID: 25 } ],
  affectedRows: 0
}
samwillis commented 1 month ago

Hey, thanks for looking into this, I've posters over on the Deno issue, I'm very keen to make this happen.

One thing I am aware of if that the Emscripten generated code checks the environment with this:

var ENVIRONMENT_IS_WEB = typeof window == 'object'
var ENVIRONMENT_IS_WORKER = typeof importScripts == 'function'
var ENVIRONMENT_IS_NODE =
  typeof process == 'object' &&
  typeof process.versions == 'object' &&
  typeof process.versions.node == 'string'

this is mostly outside our control without patching Emscripten, when you try to run PGlite from a local build, rather than the published package, you will get errors such as:

> Uncaught TypeError: Cannot read properties of undefined (reading 'pathname')
    at loadPackage (file:///Users/samwillis/Code/pglite/packages/pglite/dist/postgres.js:38:29)
    at file:///Users/samwillis/Code/pglite/packages/pglite/dist/postgres.js:441:7
    at file:///Users/samwillis/Code/pglite/packages/pglite/dist/postgres.js:3951:7
    at Dt.Tr (file:///Users/samwillis/Code/pglite/packages/pglite/dist/index.js:1:53885)
    at eventLoopTick (ext:core/01_core.js:168:7)

Essentially the Enscripten code goes down a path where it's expecting to be in a browser environment.

We could look into trying to have a fix applied to Emscripten but I don't know how easy that will be.

alexgleason commented 1 month ago

This is fixed on Deno's development build now! I grabbed the download for Linux from here: https://dl.deno.land/canary/ff4226a3cd20ef6cfb155ca206c745785b6e098f/deno-x86_64-unknown-linux-gnu.zip

@samwillis should we close this to? Or do you want to wait for them to release it / to update the pglite README?

samwillis commented 1 month ago

@alexgleason this is all so awsome!

The last to-do if so me to add some tests to CI, let's leave it open till early next week, I'll need the reminder!

alexgleason commented 1 week ago

@samwillis Deno included pglite in their release video for v1.46. And they misspelled it :joy: but I still think it's cool.

image

https://www.reddit.com/r/Deno/comments/1f83kg0/deno_146_in_case_you_missed_it/