atombeak
Version:
Create asynchronous atomic functions!
134 lines (133 loc) • 4.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
var LogItem_1 = require("./LogItem");
var filterMap_1 = require("./filterMap");
exports.APPEND_SUCCESS = 'APPEND_SUCCESS';
function appendSuccess(log) {
return {
type: exports.APPEND_SUCCESS,
log: log
};
}
exports.appendSuccess = appendSuccess;
exports.RESTART_WITH_OUTER = 'RESTART_WITH_OUTER';
function restartWithOuter(outer) {
return {
type: exports.RESTART_WITH_OUTER,
outer: outer
};
}
exports.restartWithOuter = restartWithOuter;
var Log = /** @class */ (function () {
function Log(itemsReversed) {
this.itemsReversed = itemsReversed;
}
Log.create = function (originalOuter) {
return new Log([{ type: LogItem_1.STATE, outer: originalOuter }]);
};
Log.prototype.read = function (id, reader) {
var fromLog = this.findMostRecentReadOrWrite(id);
if (fromLog === null) {
var inner = this.fromState(reader);
var updatedLog = this.appendReadOrWrite({ type: LogItem_1.READ, id: id, reader: reader, value: inner });
return [inner, updatedLog];
}
else {
return [fromLog.value, this];
}
};
Log.prototype.findMostRecentReadOrWrite = function (id) {
var readsOrWritesReversed = filterMap_1.filterMap(this.itemsReversed, function (item) {
if (item.type === LogItem_1.READ || item.type === LogItem_1.WRITE) {
return item;
}
else {
return null;
}
});
var itemWithSamePath = readsOrWritesReversed.find(function (item) { return item.id === id; });
if (itemWithSamePath === undefined) {
return null;
}
else {
return { value: itemWithSamePath.value };
}
};
Log.prototype.fromState = function (reader) {
var statesReversed = filterMap_1.filterMap(this.itemsReversed, function (item) {
if (item.type === LogItem_1.STATE) {
return item;
}
else {
return null;
}
});
var mostRecentState = statesReversed[0];
if (mostRecentState === undefined) {
throw new Error('Expected at least one state (the original state).');
}
return reader(mostRecentState.outer);
};
Log.prototype.write = function (id, inner, action) {
return this.appendReadOrWrite({ type: LogItem_1.WRITE, id: id, value: inner, action: action });
};
Log.prototype.appendReadOrWrite = function (logItem) {
return new Log([logItem].concat(this.itemsReversed));
};
Log.prototype.isConsistentWithOuter = function (outer) {
return this.itemsReversed.every(function (i) {
if (i.type === LogItem_1.WRITE) {
return true;
}
else if (i.type === LogItem_1.READ) {
return i.reader(outer) === i.value;
}
else if (i.type === LogItem_1.STATE) {
return true;
}
else {
var exhaustive = i;
throw new Error(exhaustive);
}
});
};
Log.prototype.getActions = function () {
var actions = [];
this.itemsReversed.forEach(function (item) {
if (item.type === LogItem_1.WRITE) {
actions.unshift(item.action);
}
});
return actions;
};
Log.prototype.appendState = function (outer) {
var logItem = { type: LogItem_1.STATE, outer: outer };
if (this.isConsistentWithOuter(logItem.outer)) {
var newLog = new Log([logItem].concat(this.itemsReversed));
return appendSuccess(newLog);
}
else {
return restartWithOuter(logItem.outer);
}
};
Log.prototype.appendStates = function () {
var outers = [];
for (var _i = 0; _i < arguments.length; _i++) {
outers[_i] = arguments[_i];
}
return outers.reduce(function (acc, curr) {
if (acc.type === exports.APPEND_SUCCESS) {
return acc.log.appendState(curr);
}
else if (acc.type === exports.RESTART_WITH_OUTER) {
return restartWithOuter(curr);
}
else {
var exhaustive = acc;
throw new Error(exhaustive);
}
}, appendSuccess(this));
};
return Log;
}());
exports.Log = Log;