worker.js raw

   1  // A dedicated worker that owns the wasm light client. The page talks to it
   2  // with postMessage({type:'sync', uri, chain}) and receives status objects.
   3  // Closing the tab terminates the worker, which closes the WebSocket; the
   4  // bridge sees the close and releases its node connection.
   5  'use strict';
   6  
   7  let booting = null;
   8  
   9  function boot() {
  10    if (booting) return booting;
  11    booting = (async () => {
  12      importScripts('wasm_exec.js');
  13      const go = new Go();
  14      let instance;
  15      try {
  16        instance = (await WebAssembly.instantiateStreaming(
  17          fetch('nostrino.wasm'),
  18          go.importObject
  19        )).instance;
  20      } catch (err) {
  21        const bytes = await (await fetch('nostrino.wasm')).arrayBuffer();
  22        instance = (await WebAssembly.instantiate(bytes, go.importObject)).instance;
  23      }
  24      go.run(instance);
  25      for (let i = 0; i < 500 && !self.nostrino; i++) {
  26        await new Promise((r) => setTimeout(r, 10));
  27      }
  28      if (!self.nostrino) throw new Error('wasm did not install nostrino');
  29      return self.nostrino;
  30    })();
  31    return booting;
  32  }
  33  
  34  let polling = null;
  35  
  36  async function sync(uri, chain) {
  37    const nostrino = await boot();
  38    postMessage({ type: 'status', status: JSON.parse(nostrino.status()) });
  39    nostrino.sync(uri, chain);
  40    if (polling) return;
  41    polling = setInterval(() => {
  42      const status = JSON.parse(self.nostrino.status());
  43      postMessage({ type: 'status', status });
  44      if (!status.running) {
  45        clearInterval(polling);
  46        polling = null;
  47      }
  48    }, 250);
  49  }
  50  
  51  onmessage = (event) => {
  52    const msg = event.data || {};
  53    if (msg.type === 'sync') {
  54      sync(msg.uri, msg.chain).catch((err) =>
  55        postMessage({ type: 'error', error: String(err) })
  56      );
  57    } else if (msg.type === 'cancel') {
  58      if (self.nostrino) self.nostrino.cancel();
  59    } else if (msg.type === 'profile') {
  60      if (self.nostrino) {
  61        const err = self.nostrino.profile(msg.json);
  62        if (err) postMessage({ type: 'error', error: err });
  63      }
  64    } else if (msg.type === 'match') {
  65      if (self.nostrino) {
  66        postMessage({ type: 'matches', matches: JSON.parse(self.nostrino.match(msg.script)) });
  67      }
  68    }
  69  };
  70