import { OrderedMap } from "immutable"; import { Guid, Unit, SynchronizationOperationResult } from "../../main"; import { CoTypedFactory } from "../coroutines/builder"; import { Coroutine } from "../coroutines/state"; import { BasicFun } from "../fun/state"; export const QueueCoroutine = < Context, State, OperationResult extends SynchronizationOperationResult = SynchronizationOperationResult, >( removeItem: BasicFun>, getItemsToProcess: BasicFun< Context & State, OrderedMap< Guid, { preprocess: Coroutine; operation: Coroutine; postprocess: BasicFun< OperationResult, Coroutine >; reenqueue: BasicFun< OperationResult, Coroutine >; } > >, ): Coroutine => { const Co = CoTypedFactory(); return Co.Repeat( Co.GetState().then((current) => { let operations = getItemsToProcess(current); return Co.Seq([ Co.All( operations.toArray().map(([id, k]) => k.preprocess .then(() => k.operation) .then((_) => k.postprocess(_).then(() => { if (_.kind == "should be enqueued again") { return k.reenqueue(_); } else { return Co.Return({}); } }), ) .then(() => removeItem(id)), ), ), ]); }), ); };