electric-sql / pglite

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

[Feature Request]: `postgres.wasm`, `postgres.data`, `extension.tar.gz` asset paths (Chrome Extension Use Case) #426

Open f0rr0 opened 6 days ago

f0rr0 commented 6 days ago

Currently, Pglite does not provide a neat mechanism (or if it does, it is not well documented) to properly handle serving wasm or the tar.gz assets when building a Chrome extension. I encounter fetch errors because the required files are not found in the desired paths unless manually configured.

Given this:

import { OpfsAhpFS } from "@electric-sql/pglite/opfs-ahp";
import { PGlite } from "@electric-sql/pglite";
import { vector } from '@electric-sql/pglite/vector';

export const getDatabase = async () => {
  const pg = new PGlite({
    fs: new OpfsAhpFS('test.db'),
    extensions: { vector }
  });
  return pg;
};

To ensure the files are accessible, I need to use the following viteStaticCopy configuration:

viteStaticCopy({
  targets: [
    {
      src: "node_modules/@electric-sql/pglite/dist/postgres.wasm",
      dest: env.mode === "production" ? "assets" : "",
    },
    {
      src: "node_modules/@electric-sql/pglite/dist/postgres.data",
      dest: env.mode === "production" ? "assets" : "",
    },
    {
      src: "node_modules/@electric-sql/pglite/dist/vector.tar.gz",
      dest: "",
    },
  ],
}),

The worker importing the assets is present at ./assets/worker.js.

This workaround helps in making the necessary files available in the desired output paths, but it feels cumbersome and not as clean as it could be.

Suggestion: An approach similar to what is used by web-tree-sitter may improve developer experience. The library solves for similar issues using a locateFile function, as documented here.

locateFile(scriptName: string, scriptDirectory: string) {
  return scriptName;
}

I am then able to do:

import webTreeSitterWasmUrl from "web-tree-sitter/tree-sitter.wasm?url";

await Parser.init({
    locateFile: () => webTreeSitterWasmUrl,
});

Would it be possible to either provide a built-in mechanism within Pglite to handle asset serving more cleanly or to document an approach that integrates better with bundlers such as Vite for building Chrome extensions?