UNPKG

atombeak

Version:

Create asynchronous atomic functions!

96 lines (95 loc) 3.75 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var Message_1 = require("./Message"); var TransactionState_1 = require("./TransactionState"); var Command_1 = require("./Command"); var Log_1 = require("../Log"); var Trampoline_1 = require("../Trampoline"); var Transaction = /** @class */ (function () { function Transaction(originalOperation, outer, dispatch) { this.originalOperation = originalOperation; this.dispatch = dispatch; this.messages = []; this.isExecuting = false; this.isDone = false; this.operation = originalOperation; var attempt = 0; var log = Log_1.Log.create(outer); this.state = new TransactionState_1.Pending(attempt, log, []); this.executeCommand(Command_1.shouldRestart(attempt, log)); } Transaction.prototype.push = function (message) { var _this = this; if (this.isDone) { return; } this.messages = this.messages.concat([message]); if (!this.isExecuting) { this.isExecuting = true; while (this.messages.length > 0) { var _a = this.messages, head = _a[0], tail = _a.slice(1); this.messages = tail; var _b = this.state.next(head), nextState = _b[0], command = _b[1]; this.state = nextState; this.executeCommand(command); } if (this.state instanceof TransactionState_1.Done) { this.state.getActions().forEach(function (action) { _this.dispatch(action); }); this.isDone = true; } this.isExecuting = false; } }; Transaction.prototype.executeCommand = function (command) { var _this = this; if (command.type === Command_1.NO_OP) { return; } else if (command.type === Command_1.RESOLVE) { // What? } else if (command.type === Command_1.SHOULD_RESTART) { this.operation = this.originalOperation; var trampoline = this.operation.execute(command.log); if (trampoline.type === Trampoline_1.ITER) { trampoline.next().then(function (_a) { var operation = _a[0], log = _a[1]; _this.operation = operation; _this.push(Message_1.nextIteration(command.attempt, log)); }); } else if (trampoline.type === Trampoline_1.DONE) { this.push(Message_1.resultReceivedMessage(command.attempt, trampoline.value)); } else { var exhaustive = trampoline; throw new Error(exhaustive); } } else if (command.type === Command_1.SHOULD_CONTINUE) { var trampoline = this.operation.execute(command.log); if (trampoline.type === Trampoline_1.ITER) { trampoline.next().then(function (_a) { var operation = _a[0], log = _a[1]; _this.operation = operation; _this.push(Message_1.nextIteration(command.attempt, log)); }); } else if (trampoline.type === Trampoline_1.DONE) { this.push(Message_1.resultReceivedMessage(command.attempt, trampoline.value)); } else { var exhaustive = trampoline; throw new Error(exhaustive); } } else { var exhaustive = command; throw new Error(exhaustive); } }; return Transaction; }()); exports.Transaction = Transaction;