UNPKG

fable-compiler

Version:
116 lines 4.52 kB
import { OperationCanceledError, Trampoline } from "./AsyncBuilder"; import { CancellationToken } from "./AsyncBuilder"; import { protectedCont } from "./AsyncBuilder"; import { protectedBind } from "./AsyncBuilder"; import { protectedReturn } from "./AsyncBuilder"; import { choice1, choice2 } from "./Option"; import { map } from "./Seq"; // Implemented just for type references export default class Async { } function emptyContinuation(x) { // NOP } // MakeAsync: body:(AsyncActivation<'T> -> AsyncReturn) -> Async<'T> export function makeAsync(body) { return body; } // Invoke: computation: Async<'T> -> ctxt:AsyncActivation<'T> -> AsyncReturn export function invoke(computation, ctx) { return computation(ctx); } // CallThenInvoke: ctxt:AsyncActivation<'T> -> result1:'U -> part2:('U -> Async<'T>) -> AsyncReturn export function callThenInvoke(ctx, result1, part2) { return part2(result1)(ctx); } // Bind: ctxt:AsyncActivation<'T> -> part1:Async<'U> -> part2:('U -> Async<'T>) -> AsyncReturn export function bind(ctx, part1, part2) { return protectedBind(part1, part2)(ctx); } export function createCancellationToken(arg) { const token = new CancellationToken(typeof arg === "boolean" ? arg : false); if (typeof arg === "number") { setTimeout(() => { token.cancel(); }, arg); } return token; } export function cancel(token) { token.cancel(); } export function cancelAfter(token, ms) { setTimeout(() => { token.cancel(); }, ms); } export function isCancellationRequested(token) { return token != null && token.isCancelled; } export function startChild(computation) { const promise = startAsPromise(computation); // JS Promises are hot, computation has already started // but we delay returning the result return protectedCont((ctx) => protectedReturn(awaitPromise(promise))(ctx)); } export function awaitPromise(p) { return fromContinuations((conts) => p.then(conts[0]).catch((err) => (err instanceof OperationCanceledError ? conts[2] : conts[1])(err))); } export function cancellationToken() { return protectedCont((ctx) => ctx.onSuccess(ctx.cancelToken)); } export const defaultCancellationToken = new CancellationToken(); export function catchAsync(work) { return protectedCont((ctx) => { work({ onSuccess: (x) => ctx.onSuccess(choice1(x)), onError: (ex) => ctx.onSuccess(choice2(ex)), onCancel: ctx.onCancel, cancelToken: ctx.cancelToken, trampoline: ctx.trampoline, }); }); } export function fromContinuations(f) { return protectedCont((ctx) => f([ctx.onSuccess, ctx.onError, ctx.onCancel])); } export function ignore(computation) { return protectedBind(computation, (x) => protectedReturn(void 0)); } export function parallel(computations) { return awaitPromise(Promise.all(map((w) => startAsPromise(w), computations))); } export function sleep(millisecondsDueTime) { return protectedCont((ctx) => { let tokenId; const timeoutId = setTimeout(() => { ctx.cancelToken.removeListener(tokenId); ctx.onSuccess(void 0); }, millisecondsDueTime); tokenId = ctx.cancelToken.addListener(() => { clearTimeout(timeoutId); ctx.onCancel(new OperationCanceledError()); }); }); } export function start(computation, cancellationToken) { return startWithContinuations(computation, cancellationToken); } export function startImmediate(computation, cancellationToken) { return start(computation, cancellationToken); } export function startWithContinuations(computation, continuation, exceptionContinuation, cancellationContinuation, cancelToken) { if (typeof continuation !== "function") { cancelToken = continuation; continuation = null; } const trampoline = new Trampoline(); computation({ onSuccess: continuation ? continuation : emptyContinuation, onError: exceptionContinuation ? exceptionContinuation : emptyContinuation, onCancel: cancellationContinuation ? cancellationContinuation : emptyContinuation, cancelToken: cancelToken ? cancelToken : defaultCancellationToken, trampoline, }); } export function startAsPromise(computation, cancellationToken) { return new Promise((resolve, reject) => startWithContinuations(computation, resolve, reject, reject, cancellationToken ? cancellationToken : defaultCancellationToken)); } //# sourceMappingURL=Async.js.map