pglite icon indicating copy to clipboard operation
pglite copied to clipboard

missing WebSocket dependency for node environments

Open nurturenature opened this issue 1 year ago • 2 comments

Hi,

When trying to use PGlite with node:

{
    "dependencies": {
      "@electric-sql/pglite": "canary",
      "electric-sql": "canary"
  }
}
/* PGlite */
import { PGlite } from "@electric-sql/pglite";
import { electrify } from 'electric-sql/pglite'
import { schema } from './generated/client/index.js'
import { ElectricConfig } from "electric-sql/config"
import { insecureAuthToken } from 'electric-sql/auth'

/* create an electric conn, database, and client */
const config: ElectricConfig = {
    url: process.env.ELECTRIC_SERVICE || 'http://electric:5133',
    debug: true
}
const pglite = new PGlite()
const electric = await electrify(pglite, schema, config)
await electric.connect(insecureAuthToken({ "sub": "insecure" }))

And at runtime:

> [email protected] app:start
> node dist/index.js

Using Postgres version: PostgreSQL 15devel on aarch64-apple-darwin22.6.0, compiled by emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.56 (cf90417346b78455089e64eb909d71d091ecc055), 32-bit
applying migration: 0
applying migration: 1
applying migration: 2
no lsn retrieved from store
connecting to electric server
server returned an error while establishing connection: WebSocket is not defined
connectAndStartRetryHandler was cancelled: WebSocket is not defined
connectAndStartRetryHandler was cancelled: WebSocket is not defined
file://.../pglite/node_modules/electric-sql/dist/sockets/web.js:9
    const ws = new WebSocket(opts.url, [this.protocolVsn]);
               ^

ReferenceError: WebSocket is not defined
    at WebSocketWeb.makeSocket (file://.../pglite/node_modules/electric-sql/dist/sockets/web.js:9:16)
    at WebSocketWeb.open (file://.../pglite/node_modules/electric-sql/dist/sockets/genericSocket.js:25:24)
    at file://.../pglite/node_modules/electric-sql/dist/satellite/client.js:228:19
    at new Promise (<anonymous>)
    at SatelliteClient.connect (file://.../pglite/node_modules/electric-sql/dist/satellite/client.js:188:12)
    at SatelliteProcess._connect (file://.../pglite/node_modules/electric-sql/dist/satellite/process.js:602:25)
    at BackOff.request (file://.../pglite/node_modules/electric-sql/dist/satellite/process.js:559:18)
    at BackOff.<anonymous> (/.../pglite/node_modules/exponential-backoff/dist/backoff.js:76:51)
    at step (/.../pglite/node_modules/exponential-backoff/dist/backoff.js:33:23)
    at Object.next (/.../pglite/node_modules/exponential-backoff/dist/backoff.js:14:53)

Node.js v20.12.2

Adding:

{
    "dependencies": {
      "ws": "^8.17.0"
  }
}

and doing:

sed -i "1s/^/import { WebSocket } from 'ws';\\n/" "./node_modules/electric-sql/dist/sockets/web.js"

allows the application to run.

From searching for this error message, it seems that WebSocket is available in the browser runtime but must be depended on by node?

nurturenature avatar May 21 '24 23:05 nurturenature

you might also want to try a newer version of node, as they added native WebSocket support behind a flag in v20.10 and without a flag in v22: https://nodejs.org/docs/latest/api/globals.html#websocket

slaskis avatar May 22 '24 07:05 slaskis

Upgrading node:

$ node -v
v22.2.0

and installing:

$ rm -rf src/generated dist node_modules
$ npm install

fails:

npm error code 1
npm error path .../node_modules/electric-sql/node_modules/better-sqlite3
npm error command failed
npm error command sh -c prebuild-install || node-gyp rebuild --release
npm error make: Entering directory '.../node_modules/electric-sql/node_modules/better-sqlite3/build'
npm error   TOUCH ba23eeee118cd63e16015df367567cb043fed872.intermediate
npm error   ACTION deps_sqlite3_gyp_locate_sqlite3_target_copy_builtin_sqlite3 ba23eeee118cd63e16015df367567cb043fed872.intermediate
npm error   TOUCH Release/obj.target/deps/locate_sqlite3.stamp
npm error   CC(target) Release/obj.target/sqlite3/gen/sqlite3/sqlite3.o
npm error rm -f Release/obj.target/deps/sqlite3.a Release/obj.target/deps/sqlite3.a.ar-file-list; mkdir -p `dirname Release/obj.target/deps/sqlite3.a`
npm error ar crs Release/obj.target/deps/sqlite3.a @Release/obj.target/deps/sqlite3.a.ar-file-list
npm error   COPY Release/sqlite3.a
npm error   CXX(target) Release/obj.target/better_sqlite3/src/better_sqlite3.o
npm error rm ba23eeee118cd63e16015df367567cb043fed872.intermediate
npm error make: Leaving directory '.../node_modules/electric-sql/node_modules/better-sqlite3/build'
npm error prebuild-install warn install No prebuilt binaries found (target=22.2.0 runtime=node arch=x64 libc= platform=linux)
npm error gyp info it worked if it ends with ok
npm error gyp info using [email protected]
npm error gyp info using [email protected] | linux | x64
npm error gyp info find Python using Python version 3.11.2 found at "/usr/bin/python3"
npm error gyp info spawn /usr/bin/python3
npm error gyp info spawn args [
npm error gyp info spawn args '/usr/lib/node_modules/npm/node_modules/node-gyp/gyp/gyp_main.py',
npm error gyp info spawn args 'binding.gyp',
npm error gyp info spawn args '-f',
npm error gyp info spawn args 'make',
npm error gyp info spawn args '-I',
npm error gyp info spawn args '.../node_modules/electric-sql/node_modules/better-sqlite3/build/config.gypi',
npm error gyp info spawn args '-I',
npm error gyp info spawn args '/usr/lib/node_modules/npm/node_modules/node-gyp/addon.gypi',
npm error gyp info spawn args '-I',
npm error gyp info spawn args '.../.cache/node-gyp/22.2.0/include/node/common.gypi',
npm error gyp info spawn args '-Dlibrary=shared_library',
npm error gyp info spawn args '-Dvisibility=default',
npm error gyp info spawn args '-Dnode_root_dir=.../.cache/node-gyp/22.2.0',
npm error gyp info spawn args '-Dnode_gyp_dir=/usr/lib/node_modules/npm/node_modules/node-gyp',
npm error gyp info spawn args '-Dnode_lib_file=.../.cache/node-gyp/22.2.0/<(target_arch)/node.lib',
npm error gyp info spawn args '-Dmodule_root_dir=.../node_modules/electric-sql/node_modules/better-sqlite3',
npm error gyp info spawn args '-Dnode_engine=v8',
npm error gyp info spawn args '--depth=.',
npm error gyp info spawn args '--no-parallel',
npm error gyp info spawn args '--generator-output',
npm error gyp info spawn args 'build',
npm error gyp info spawn args '-Goutput_dir=.'
npm error gyp info spawn args ]
npm error gyp info spawn make
npm error gyp info spawn args [ 'BUILDTYPE=Release', '-C', 'build' ]
npm error In file included from ./src/better_sqlite3.lzz:11,
npm error                  from ../src/better_sqlite3.cpp:4:
npm error .../.cache/node-gyp/22.2.0/include/node/node.h:1248:7: warning: cast between incompatible function types from ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, v8::Local<v8::Context>)’ to ‘node::addon_context_register_func’ {aka ‘void (*)(v8::Local<v8::Object>, v8::Local<v8::Value>, v8::Local<v8::Context>, void*)’} [-Wcast-function-type]
npm error  1248 |       (node::addon_context_register_func) (regfunc),                  \
npm error       |       ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
npm error .../.cache/node-gyp/22.2.0/include/node/node.h:1266:3: note: in expansion of macro ‘NODE_MODULE_CONTEXT_AWARE_X’
npm error  1266 |   NODE_MODULE_CONTEXT_AWARE_X(modname, regfunc, NULL, 0)
npm error       |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
npm error .../.cache/node-gyp/22.2.0/include/node/node.h:1297:3: note: in expansion of macro ‘NODE_MODULE_CONTEXT_AWARE’
npm error  1297 |   NODE_MODULE_CONTEXT_AWARE(NODE_GYP_MODULE_NAME,                     \
npm error       |   ^~~~~~~~~~~~~~~~~~~~~~~~~
npm error ./src/better_sqlite3.lzz:67:1: note: in expansion of macro ‘NODE_MODULE_INIT’
npm error ./src/util/macros.lzz: In function ‘void SetPrototypeGetter(v8::Isolate*, v8::Local<v8::External>, v8::Local<v8::FunctionTemplate>, const char*, v8::AccessorGetterCallback)’:
npm error ./src/util/macros.lzz:150:46: error: no matching function for call to ‘v8::ObjectTemplate::SetAccessor(v8::Local<v8::String>, void (*&)(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>&), int, v8::Local<v8::External>&, v8::AccessControl, v8::PropertyAttribute)’
npm error In file included from .../.cache/node-gyp/22.2.0/include/node/v8-function.h:15,
npm error                  from .../.cache/node-gyp/22.2.0/include/node/v8.h:33,
npm error                  from .../.cache/node-gyp/22.2.0/include/node/node.h:73:
npm error .../.cache/node-gyp/22.2.0/include/node/v8-template.h:1055:8: note: candidate: ‘void v8::ObjectTemplate::SetAccessor(v8::Local<v8::Name>, v8::AccessorNameGetterCallback, v8::AccessorNameSetterCallback, v8::Local<v8::Value>, v8::PropertyAttribute, v8::SideEffectType, v8::SideEffectType)’
npm error  1055 |   void SetAccessor(
npm error       |        ^~~~~~~~~~~
npm error .../.cache/node-gyp/22.2.0/include/node/v8-template.h:1058:61: note:   no known conversion for argument 5 from ‘v8::AccessControl’ to ‘v8::PropertyAttribute’
npm error  1058 |       Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
npm error       |                                           ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
npm error .../.cache/node-gyp/22.2.0/include/node/v8-template.h:1049:8: note: candidate: ‘void v8::ObjectTemplate::SetAccessor(v8::Local<v8::String>, v8::AccessorGetterCallback, v8::AccessorSetterCallback, v8::Local<v8::Value>, v8::PropertyAttribute, v8::SideEffectType, v8::SideEffectType)’
npm error  1049 |   void SetAccessor(
npm error       |        ^~~~~~~~~~~
npm error .../.cache/node-gyp/22.2.0/include/node/v8-template.h:1052:61: note:   no known conversion for argument 5 from ‘v8::AccessControl’ to ‘v8::PropertyAttribute’
npm error  1052 |       Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
npm error       |                                           ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~
npm error ./src/util/data.lzz: In function ‘v8::Local<v8::Value> Data::GetValueJS(v8::Isolate*, sqlite3_stmt*, int, bool)’:
npm error ./src/util/data.lzz:73:92: warning: this statement may fall through [-Wimplicit-fallthrough=]
npm error ./src/util/data.lzz:73:197: note: here
npm error ./src/util/data.lzz: In function ‘v8::Local<v8::Value> Data::GetValueJS(v8::Isolate*, sqlite3_value*, bool)’:
npm error ./src/util/data.lzz:77:81: warning: this statement may fall through [-Wimplicit-fallthrough=]
npm error ./src/util/data.lzz:77:175: note: here
npm error make: *** [better_sqlite3.target.mk:120: Release/obj.target/better_sqlite3/src/better_sqlite3.o] Error 1
npm error gyp ERR! build error 
npm error gyp ERR! stack Error: `make` failed with exit code: 2
npm error gyp ERR! stack at ChildProcess.<anonymous> (/usr/lib/node_modules/npm/node_modules/node-gyp/lib/build.js:209:23)
npm error gyp ERR! System Linux 6.1.0-21-amd64
npm error gyp ERR! command "/usr/bin/node" "/usr/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js" "rebuild" "--release"
npm error gyp ERR! cwd .../node_modules/electric-sql/node_modules/better-sqlite3
npm error gyp ERR! node -v v22.2.0
npm error gyp ERR! node-gyp -v v10.1.0
npm error gyp ERR! not ok

nurturenature avatar May 22 '24 19:05 nurturenature

This error is related to the legacy Electric sync and so I'm going to close.

samwillis avatar Aug 11 '24 15:08 samwillis