isolateWorkerModule<A, S> function

Module<S> isolateWorkerModule<A, S>(
  1. IsolateWorkersCreator workersCreator
)

Implementation

Module<S> isolateWorkerModule<A, S>(
    IsolateWorkersCreator workersCreator
) => Module('isolateWorkerModule', (dispatcher, initialize, state, next) {
  final MutableStateChannel<dynamic> channel = StateChannelImpl<dynamic>();

  List<IsolateWorkerWrapper<A, S>>? workerWrappers;
  final unsentStates = <S>[
    state.valueOrNull()?.state as S // initial state
  ];
  final unsentActions = <A>[];

  final registrationKey = Uuid().v4();
  final registrationCompleter = IsolateWorkerManager.instance!.registerWorker(registrationKey, workersCreator);

  registrationCompleter.future
    .then((workers) {
      workerWrappers = workers.map((workerType) => IsolateWorkerManager.instance!.createWorker<A, S>(workerType))
        .toList();

      for(final worker in workerWrappers!) {
        worker.where((event) => event is IsolateWorkerOutActionEvent)
          .cast<IsolateWorkerOutActionEvent>()
          .listen((event) {
            dispatcher(event.action);
          });
      }

      for(final state in unsentStates) {
        for (final worker in workerWrappers!) {
          worker.add(IsolateWorkerStateEvent<S>(null, state));
        }
      }

      for(final action in unsentActions) {
        for (final worker in workerWrappers!) {
          worker.add(IsolateWorkerInActionEvent<A>(null, action));
        }
      }
  });

  state.asStream()
    .listen((state) {
      if(workerWrappers != null) {
        for (final worker in workerWrappers!) {
          worker.add(IsolateWorkerStateEvent<S>(null, state.state));
        }
      } else {
        unsentStates.add(state.state);
      }
    });

  channel.asStream()
    .where((action) => action is A)
    .cast<A>()
    .listen((action) {
      if(workerWrappers == null) {
        unsentActions.add(action);
      } else {
        for(final worker in workerWrappers!) {
          worker.add(IsolateWorkerInActionEvent<A>(null, action));
        }
      }
    });

  return (dynamic action) async {
    if(action is MeowChannelClose) {
      channel.close();
    } else {
      channel.send(action);
    }

    await next(action);
  };
});