Skip to content

Package does not work in electron due to current checks of IN_NODE #813

@vitonsky

Description

@vitonsky

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

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions