purs-pkg-deps
Version:
Query package dependencies in PureScript package-sets
310 lines (277 loc) • 6.84 kB
JavaScript
;
var AVar = function () {
function MutableQueue () {
this.head = null;
this.last = null;
this.size = 0;
}
function MutableCell (queue, value) {
this.queue = queue;
this.value = value;
this.next = null;
this.prev = null;
}
function AVar (value) {
this.draining = false;
this.error = null;
this.value = value;
this.takes = new MutableQueue();
this.reads = new MutableQueue();
this.puts = new MutableQueue();
}
var EMPTY = {};
function runEff(eff) {
try {
eff();
} catch (error) {
setTimeout(function () {
throw error;
}, 0);
}
}
function putLast (queue, value) {
var cell = new MutableCell(queue, value);
switch (queue.size) {
case 0:
queue.head = cell;
break;
case 1:
cell.prev = queue.head;
queue.head.next = cell;
queue.last = cell;
break;
default:
cell.prev = queue.last;
queue.last.next = cell;
queue.last = cell;
}
queue.size++;
return cell;
}
function takeLast (queue) {
var cell;
switch (queue.size) {
case 0:
return null;
case 1:
cell = queue.head;
queue.head = null;
break;
case 2:
cell = queue.last;
queue.head.next = null;
queue.last = null;
break;
default:
cell = queue.last;
queue.last = cell.prev;
queue.last.next = null;
}
cell.prev = null;
cell.queue = null;
queue.size--;
return cell.value;
}
function takeHead (queue) {
var cell;
switch (queue.size) {
case 0:
return null;
case 1:
cell = queue.head;
queue.head = null;
break;
case 2:
cell = queue.head;
queue.last.prev = null;
queue.head = queue.last;
queue.last = null;
break;
default:
cell = queue.head;
queue.head = cell.next;
queue.head.prev = null;
}
cell.next = null;
cell.queue = null;
queue.size--;
return cell.value;
}
function deleteCell (cell) {
if (cell.queue === null) {
return;
}
if (cell.queue.last === cell) {
takeLast(cell.queue);
return;
}
if (cell.queue.head === cell) {
takeHead(cell.queue);
return;
}
if (cell.prev) {
cell.prev.next = cell.next;
}
if (cell.next) {
cell.next.prev = cell.prev;
}
cell.queue.size--;
cell.queue = null;
cell.value = null;
cell.next = null;
cell.prev = null;
}
function drainVar (util, avar) {
if (avar.draining) {
return;
}
var ps = avar.puts;
var ts = avar.takes;
var rs = avar.reads;
var p, r, t, value, rsize;
avar.draining = true;
while (1) { // eslint-disable-line no-constant-condition
p = null;
r = null;
t = null;
value = avar.value;
rsize = rs.size;
if (avar.error !== null) {
value = util.left(avar.error);
while (p = takeHead(ps)) { // eslint-disable-line no-cond-assign
runEff(p.cb(value));
}
while (r = takeHead(rs)) { // eslint-disable-line no-cond-assign
runEff(r(value));
}
while (t = takeHead(ts)) { // eslint-disable-line no-cond-assign
runEff(t(value));
}
break;
}
// Process the next put. We do not immediately invoke the callback
// because we want to preserve ordering. If there are takes/reads
// we want to run those first.
if (value === EMPTY && (p = takeHead(ps))) {
avar.value = value = p.value;
}
if (value !== EMPTY) {
// We go ahead and queue up the next take for the same reasons as
// above. Invoking the read callbacks can affect the mutable queue.
t = takeHead(ts);
// We only want to process the reads queued up before running these
// callbacks so we guard on rsize.
while (rsize-- && (r = takeHead(rs))) {
runEff(r(util.right(value)));
}
if (t !== null) {
avar.value = EMPTY;
runEff(t(util.right(value)));
}
}
if (p !== null) {
runEff(p.cb(util.right(void 0)));
}
// Callbacks could have queued up more items so we need to guard on the
// actual mutable properties.
if (avar.value === EMPTY && ps.size === 0 || avar.value !== EMPTY && ts.size === 0) {
break;
}
}
avar.draining = false;
}
AVar.EMPTY = EMPTY;
AVar.putLast = putLast;
AVar.takeLast = takeLast;
AVar.takeHead = takeHead;
AVar.deleteCell = deleteCell;
AVar.drainVar = drainVar;
return AVar;
}();
exports.empty = function () {
return new AVar(AVar.EMPTY);
};
exports._newVar = function (value) {
return function () {
return new AVar(value);
};
};
exports._killVar = function (util, error, avar) {
return function () {
if (avar.error === null) {
avar.error = error;
avar.value = AVar.EMPTY;
AVar.drainVar(util, avar);
}
};
};
exports._putVar = function (util, value, avar, cb) {
return function () {
var cell = AVar.putLast(avar.puts, { cb: cb, value: value });
AVar.drainVar(util, avar);
return function () {
AVar.deleteCell(cell);
};
};
};
exports._takeVar = function (util, avar, cb) {
return function () {
var cell = AVar.putLast(avar.takes, cb);
AVar.drainVar(util, avar);
return function () {
AVar.deleteCell(cell);
};
};
};
exports._readVar = function (util, avar, cb) {
return function () {
var cell = AVar.putLast(avar.reads, cb);
AVar.drainVar(util, avar);
return function () {
AVar.deleteCell(cell);
};
};
};
exports._tryPutVar = function (util, value, avar) {
return function () {
if (avar.value === AVar.EMPTY && avar.error === null) {
avar.value = value;
AVar.drainVar(util, avar);
return true;
} else {
return false;
}
};
};
exports._tryTakeVar = function (util, avar) {
return function () {
var value = avar.value;
if (value === AVar.EMPTY) {
return util.nothing;
} else {
avar.value = AVar.EMPTY;
AVar.drainVar(util, avar);
return util.just(value);
}
};
};
exports._tryReadVar = function (util, avar) {
return function () {
if (avar.value === AVar.EMPTY) {
return util.nothing;
} else {
return util.just(avar.value);
}
};
};
exports._status = function (util, avar) {
return function () {
if (avar.error) {
return util.killed(avar.error);
}
if (avar.value === AVar.EMPTY) {
return util.empty;
}
return util.filled(avar.value);
};
};