connectToDriftWorker function

Future<DatabaseConnection> connectToDriftWorker(
  1. String workerJsUri, {
  2. DriftWorkerMode mode = DriftWorkerMode.dedicated,
})

Spawn or connect to a web worker written with driftWorkerMain.

Depending on the mode option, this method creates either a regular Worker or attaches itself to an SharedWorker in the current browsing context. For more details on the different modes, see DriftWorkerMode. By default, a dedicated worker will be used (DriftWorkerMode.dedicated).

The workerJsUri describes the path to the worker (e.g. /database_worker.dart.js if the original Dart file defining the worker is in web/database_worker.dart).

When using a shared worker, the database (including stream queries!) are shared across multiple tabs in realtime.

Implementation

Future<DatabaseConnection> connectToDriftWorker(String workerJsUri,
    {DriftWorkerMode mode = DriftWorkerMode.dedicated}) {
  StreamChannel<Object?> channel;

  if (mode == DriftWorkerMode.dedicated) {
    final worker = Worker(workerJsUri.toJS);
    final webChannel = MessageChannel();

    // Transfer first port to the channel, we'll use the second port on this side.
    worker.postMessage(webChannel.port1, [webChannel.port1].toJS);
    channel = webChannel.port2.channel();
  } else {
    final worker = SharedWorker(workerJsUri.toJS, 'drift database'.toJS);
    final port = worker.port;

    var didGetInitializationResponse = false;
    port.postMessage(mode.name.toJS);
    channel = port.channel().transformStream(StreamTransformer.fromHandlers(
      handleData: (data, sink) {
        if (didGetInitializationResponse) {
          sink.add(data);
        } else {
          didGetInitializationResponse = true;

          final response = data as bool;
          if (response) {
            // Initialization ok, all good!
          } else {
            sink
              ..addError(StateError(
                  'Shared worker disagrees with desired mode $mode, is there '
                  'another tab using `connectToDriftWorker()` in a different '
                  'mode?'))
              ..close();
          }
        }
      },
    ));
  }

  return connectToRemoteAndInitialize(channel);
}