-
Notifications
You must be signed in to change notification settings - Fork 330
Description
The problem
I use PGLite in electron app on frontend side (renderer process with browser environment). I build code with WebPack with target 'web'.
Currently I have a lot of fatal errors like these
Uncaught (in promise) TypeError: (intermediate value).readFile is not a function
Failed to fetch extension: pg_trgm TypeError: r.createGunzip is not a function
It looks the problems is caused by current implementation of environment checks
pglite/packages/pglite/src/utils.ts
Lines 6 to 9 in a5d8a21
| export const IN_NODE = | |
| typeof process === 'object' && | |
| typeof process.versions === 'object' && | |
| typeof process.versions.node === 'string' |
Renderer process in electron is a web environment with browser API and with no access to node API.
However, object globalThis.process is available at runtime with subset of node features.
As you can see above, currently IN_NODE will be set as true in case of process is available. So pglite thinks it runs on node and tries to use API that does not exist.
It lead us to fatal errors that crash our app that works around database.
The request
Current behaviour looks like a bug. Let's improve definition of IN_NODE to distinguish if node API is really available.
Renderer context actually may include node API in case flag nodeIntegration is provided. There are many reasons why app may be not able to enable this flag. In our app we can't because of security reasons and because of maintenance costs (our app may run in browser and in electron both).
So we should research how to detect electron and then update IN_NODE initialization code.
As additional measure to prevent similar bugs in future I propose to allow user to set their environment explicitly. Straight ways to implement this feature is
- Add option to PGLite constructor. This would be ideal solution from user perspective, but it would require us to forward this flag to a low level code that is may be not trivial
- Make this option global. It could be implemented enough trivial
We could add export to a @electric-sql/pglite with some object like env that would contain environment settings
export const env = {
api: 'node'
};
export const IN_NODE = env.api ? env.api.toLowerCase() === 'node' : fallback();User would run something like
import { env } from '@electric-sql/pglite';
env.api = 'node';to set environment globally.
Alternatively we could just check value of some symbol like that
export const IN_NODE = globalThis[Symbol.for('pglite_env')] === 'node' : fallback();If you know another way how to make code works in electron with no toggle flag nodeIntegration please tell about it.