electric-sql / pglite

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

pglite-sync preventing creation of PGliteWorker since v0.2.8 #357

Closed theunsa closed 1 month ago

theunsa commented 1 month ago

main script

  const pg = new PGliteWorker(
    new Worker(new URL('../public/pglite-worker.js', import.meta.url), {
      type: 'module',
    }),
    {
      dataDir: 'idb://my-pgdata'
      extensions: {
        live,
        electric: electricSync(),  // !!! if this is commented out for pglite-sync version >= 0.2.8 then PGliteWorker is created fine
      },
    }
  )

../public/pglite-worker.js

import { PGlite } from '@electric-sql/pglite'
import { worker } from '@electric-sql/pglite/worker'

worker({
  async init(options) {
    console.log('worker init: options', options)
    const pglite = new PGlite({
      ...options
    })
    console.log('worker init: pglite', pglite)
    return pglite
  },
})

deps

    "@electric-sql/client": "^0.6.0",
    "@electric-sql/pglite": "^0.2.9",
    "@electric-sql/pglite-sync": "0.2.10",
    "@electric-sql/pglite-vue": "^0.2.9",
    "vue": "^3.5.10"

The above works fine for pglite-sync v0.2.7 but the PGliteWorker creation step never even calls the worker init() for v0.2.8 and greater.

Another way to obviously test is to remove the extension electric: electricSync(), line from the options then v0.2.8 and greater creates the PGliteWorker fine.

If there is any additional debugging I can enable to help trace the issue please let me know.

samwillis commented 1 month ago

Hey @theunsa

The sync plugin needs to be imported and installed in the worker, not on the main thread. Something like:

// ../public/pglite-worker.js
import { PGlite } from '@electric-sql/pglite'
import { worker } from '@electric-sql/pglite/worker'
import { electricSync } from '@electric-sql/pglite-sync'

worker({
  async init(options) {
    console.log('worker init: options', options)
    const pglite = new PGlite({
      ...options,
      extensions: {
         sync: electricSync()
      {
    })
    console.log('worker init: pglite', pglite)
    return pglite
  },
})

In general you can't pass through extensions from the main thread to the worker as they are js functions and can't be sterilised and transferred.

Note: There is the issue currently that having the sync plugin on the worker thread prevents you from calling sync methods from the main thread. I am working on that, we will make the stink methods available on both threads soon.

theunsa commented 1 month ago

Hi @samwillis

"sterilised" ... LOL ... intended or not, that pun is funny

Thanks for pointing that out, it makes total sense and works.

Existing main-thread-sync-block issue noted, I'll watch our for your fix but there is enough to still play with in mean time.