Created
December 9, 2014 12:14
-
-
Save skrat/39b9532c4d06a2f4fda2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright (c) 2014, Facebook, Inc. | |
* All rights reserved. | |
* | |
* This source code is licensed under the BSD-style license found in the | |
* https://raw.github.com/facebook/regenerator/master/LICENSE file. An | |
* additional grant of patent rights can be found in the PATENTS file in | |
* the same directory. | |
*/ | |
!(function() { | |
var hasOwn = Object.prototype.hasOwnProperty; | |
var undefined; // More compressible than void 0. | |
var iteratorSymbol = | |
typeof Symbol === "function" && Symbol.iterator || "@@iterator"; | |
// Make a reasonable attempt to provide a Promise polyfill. | |
if (typeof Promise === "undefined") try { | |
Promise = require("promise"); | |
} catch (ignored) {} | |
if (typeof regeneratorRuntime === "object") { | |
return; | |
} | |
var runtime = regeneratorRuntime = | |
typeof exports === "undefined" ? {} : exports; | |
function wrap(innerFn, outerFn, self, tryList) { | |
return new Generator(innerFn, outerFn, self || null, tryList || []); | |
} | |
runtime.wrap = wrap; | |
var GenStateSuspendedStart = "suspendedStart"; | |
var GenStateSuspendedYield = "suspendedYield"; | |
var GenStateExecuting = "executing"; | |
var GenStateCompleted = "completed"; | |
// Returning this object from the innerFn has the same effect as | |
// breaking out of the dispatch switch statement. | |
var ContinueSentinel = {}; | |
// Dummy constructor that we use as the .constructor property for | |
// functions that return Generator objects. | |
function GeneratorFunction() {} | |
var Gp = Generator.prototype; | |
var GFp = GeneratorFunction.prototype = Object.create(Function.prototype); | |
GFp.constructor = GeneratorFunction; | |
GFp.prototype = Gp; | |
Gp.constructor = GFp; | |
// Ensure isGeneratorFunction works when Function#name not supported. | |
if (GeneratorFunction.name !== "GeneratorFunction") { | |
GeneratorFunction.name = "GeneratorFunction"; | |
} | |
if (GeneratorFunction.name !== "GeneratorFunction") { | |
throw new Error("GeneratorFunction renamed?"); | |
} | |
runtime.isGeneratorFunction = function(genFun) { | |
var ctor = genFun && genFun.constructor; | |
return ctor ? GeneratorFunction.name === ctor.name : false; | |
}; | |
runtime.mark = function(genFun) { | |
genFun.__proto__ = GFp; | |
genFun.prototype = Object.create(Gp); | |
return genFun; | |
}; | |
runtime.async = function(innerFn, outerFn, self, tryList) { | |
return new Promise(function(resolve, reject) { | |
var generator = wrap(innerFn, outerFn, self, tryList); | |
var callNext = step.bind(generator.next); | |
var callThrow = step.bind(generator.throw); | |
function step(arg) { | |
try { | |
var info = this(arg); | |
var value = info.value; | |
} catch (error) { | |
return reject(error); | |
} | |
if (info.done) { | |
resolve(value); | |
} else { | |
Promise.resolve(value).then(callNext, callThrow); | |
} | |
} | |
callNext(); | |
}); | |
}; | |
function Generator(innerFn, outerFn, self, tryList) { | |
var generator = outerFn ? Object.create(outerFn.prototype) : this; | |
var context = new Context(tryList); | |
var state = GenStateSuspendedStart; | |
function invoke(method, arg) { | |
if (state === GenStateExecuting) { | |
throw new Error("Generator is already running"); | |
} | |
if (state === GenStateCompleted) { | |
throw new Error("Generator has already finished"); | |
} | |
while (true) { | |
var delegate = context.delegate; | |
if (delegate) { | |
try { | |
var info = delegate.iterator[method](arg); | |
// Delegate generator ran and handled its own exceptions so | |
// regardless of what the method was, we continue as if it is | |
// "next" with an undefined arg. | |
method = "next"; | |
arg = undefined; | |
} catch (uncaught) { | |
context.delegate = null; | |
// Like returning generator.throw(uncaught), but without the | |
// overhead of an extra function call. | |
method = "throw"; | |
arg = uncaught; | |
continue; | |
} | |
if (info.done) { | |
context[delegate.resultName] = info.value; | |
context.next = delegate.nextLoc; | |
} else { | |
state = GenStateSuspendedYield; | |
return info; | |
} | |
context.delegate = null; | |
} | |
if (method === "next") { | |
if (state === GenStateSuspendedStart && | |
typeof arg !== "undefined") { | |
// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume | |
throw new TypeError( | |
"attempt to send " + JSON.stringify(arg) + " to newborn generator" | |
); | |
} | |
if (state === GenStateSuspendedYield) { | |
context.sent = arg; | |
} else { | |
delete context.sent; | |
} | |
} else if (method === "throw") { | |
if (state === GenStateSuspendedStart) { | |
state = GenStateCompleted; | |
throw arg; | |
} | |
if (context.dispatchException(arg)) { | |
// If the dispatched exception was caught by a catch block, | |
// then let that catch block handle the exception normally. | |
method = "next"; | |
arg = undefined; | |
} | |
} else if (method === "return") { | |
context.abrupt("return", arg); | |
} | |
state = GenStateExecuting; | |
try { | |
var value = innerFn.call(self, context); | |
// If an exception is thrown from innerFn, we leave state === | |
// GenStateExecuting and loop back for another invocation. | |
state = context.done | |
? GenStateCompleted | |
: GenStateSuspendedYield; | |
var info = { | |
value: value, | |
done: context.done | |
}; | |
if (value === ContinueSentinel) { | |
if (context.delegate && method === "next") { | |
// Deliberately forget the last sent value so that we don't | |
// accidentally pass it on to the delegate. | |
arg = undefined; | |
} | |
} else { | |
return info; | |
} | |
} catch (thrown) { | |
state = GenStateCompleted; | |
if (method === "next") { | |
context.dispatchException(thrown); | |
} else { | |
arg = thrown; | |
} | |
} | |
} | |
} | |
generator.next = invoke.bind(generator, "next"); | |
generator.throw = invoke.bind(generator, "throw"); | |
generator.return = invoke.bind(generator, "return"); | |
return generator; | |
} | |
Gp[iteratorSymbol] = function() { | |
return this; | |
}; | |
Gp.toString = function() { | |
return "[object Generator]"; | |
}; | |
function pushTryEntry(triple) { | |
var entry = { tryLoc: triple[0] }; | |
if (1 in triple) { | |
entry.catchLoc = triple[1]; | |
} | |
if (2 in triple) { | |
entry.finallyLoc = triple[2]; | |
} | |
this.tryEntries.push(entry); | |
} | |
function resetTryEntry(entry, i) { | |
var record = entry.completion || {}; | |
record.type = i === 0 ? "normal" : "return"; | |
delete record.arg; | |
entry.completion = record; | |
} | |
function Context(tryList) { | |
// The root entry object (effectively a try statement without a catch | |
// or a finally block) gives us a place to store values thrown from | |
// locations where there is no enclosing try statement. | |
this.tryEntries = [{ tryLoc: "root" }]; | |
tryList.forEach(pushTryEntry, this); | |
this.reset(); | |
} | |
runtime.keys = function(object) { | |
var keys = []; | |
for (var key in object) { | |
keys.push(key); | |
} | |
keys.reverse(); | |
// Rather than returning an object with a next method, we keep | |
// things simple and return the next function itself. | |
return function next() { | |
while (keys.length) { | |
var key = keys.pop(); | |
if (key in object) { | |
next.value = key; | |
next.done = false; | |
return next; | |
} | |
} | |
// To avoid creating an additional object, we just hang the .value | |
// and .done properties off the next function object itself. This | |
// also ensures that the minifier will not anonymize the function. | |
next.done = true; | |
return next; | |
}; | |
}; | |
function values(iterable) { | |
var iterator = iterable; | |
if (iteratorSymbol in iterable) { | |
iterator = iterable[iteratorSymbol](); | |
} else if (!isNaN(iterable.length)) { | |
var i = -1; | |
iterator = function next() { | |
while (++i < iterable.length) { | |
if (i in iterable) { | |
next.value = iterable[i]; | |
next.done = false; | |
return next; | |
} | |
}; | |
next.done = true; | |
return next; | |
}; | |
iterator.next = iterator; | |
} | |
return iterator; | |
} | |
runtime.values = values; | |
Context.prototype = { | |
constructor: Context, | |
reset: function() { | |
this.prev = 0; | |
this.next = 0; | |
this.sent = undefined; | |
this.done = false; | |
this.delegate = null; | |
this.tryEntries.forEach(resetTryEntry); | |
// Pre-initialize at least 20 temporary variables to enable hidden | |
// class optimizations for simple generators. | |
for (var tempIndex = 0, tempName; | |
hasOwn.call(this, tempName = "t" + tempIndex) || tempIndex < 20; | |
++tempIndex) { | |
this[tempName] = null; | |
} | |
}, | |
stop: function() { | |
this.done = true; | |
var rootEntry = this.tryEntries[0]; | |
var rootRecord = rootEntry.completion; | |
if (rootRecord.type === "throw") { | |
throw rootRecord.arg; | |
} | |
return this.rval; | |
}, | |
dispatchException: function(exception) { | |
if (this.done) { | |
throw exception; | |
} | |
var context = this; | |
function handle(loc, caught) { | |
record.type = "throw"; | |
record.arg = exception; | |
context.next = loc; | |
return !!caught; | |
} | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
var record = entry.completion; | |
if (entry.tryLoc === "root") { | |
// Exception thrown outside of any try block that could handle | |
// it, so set the completion value of the entire function to | |
// throw the exception. | |
return handle("end"); | |
} | |
if (entry.tryLoc <= this.prev) { | |
var hasCatch = hasOwn.call(entry, "catchLoc"); | |
var hasFinally = hasOwn.call(entry, "finallyLoc"); | |
if (hasCatch && hasFinally) { | |
if (this.prev < entry.catchLoc) { | |
return handle(entry.catchLoc, true); | |
} else if (this.prev < entry.finallyLoc) { | |
return handle(entry.finallyLoc); | |
} | |
} else if (hasCatch) { | |
if (this.prev < entry.catchLoc) { | |
return handle(entry.catchLoc, true); | |
} | |
} else if (hasFinally) { | |
if (this.prev < entry.finallyLoc) { | |
return handle(entry.finallyLoc); | |
} | |
} else { | |
throw new Error("try statement without catch or finally"); | |
} | |
} | |
} | |
}, | |
_findFinallyEntry: function(finallyLoc) { | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
if (entry.tryLoc <= this.prev && | |
hasOwn.call(entry, "finallyLoc") && ( | |
entry.finallyLoc === finallyLoc || | |
this.prev < entry.finallyLoc)) { | |
return entry; | |
} | |
} | |
}, | |
abrupt: function(type, arg) { | |
var entry = this._findFinallyEntry(); | |
var record = entry ? entry.completion : {}; | |
record.type = type; | |
record.arg = arg; | |
if (entry) { | |
this.next = entry.finallyLoc; | |
} else { | |
this.complete(record); | |
} | |
return ContinueSentinel; | |
}, | |
complete: function(record) { | |
if (record.type === "throw") { | |
throw record.arg; | |
} | |
if (record.type === "break" || | |
record.type === "continue") { | |
this.next = record.arg; | |
} else if (record.type === "return") { | |
this.rval = record.arg; | |
this.next = "end"; | |
} | |
return ContinueSentinel; | |
}, | |
finish: function(finallyLoc) { | |
var entry = this._findFinallyEntry(finallyLoc); | |
return this.complete(entry.completion); | |
}, | |
"catch": function(tryLoc) { | |
for (var i = this.tryEntries.length - 1; i >= 0; --i) { | |
var entry = this.tryEntries[i]; | |
if (entry.tryLoc === tryLoc) { | |
var record = entry.completion; | |
if (record.type === "throw") { | |
var thrown = record.arg; | |
resetTryEntry(entry, i); | |
} | |
return thrown; | |
} | |
} | |
// The context.catch method must only be called with a location | |
// argument that corresponds to a known catch block. | |
throw new Error("illegal catch attempt"); | |
}, | |
delegateYield: function(iterable, resultName, nextLoc) { | |
this.delegate = { | |
iterator: values(iterable), | |
resultName: resultName, | |
nextLoc: nextLoc | |
}; | |
return ContinueSentinel; | |
} | |
}; | |
})(); | |
"use strict"; | |
require = (function e(t, n, r) { | |
function s(o, u) { | |
if (!n[o]) { | |
if (!t[o]) { | |
var a = typeof require == "function" && require;if (!u && a) return a(o, !0);if (i) return i(o, !0);throw new Error("Cannot find module '" + o + "'"); | |
}var f = n[o] = { exports: {} };t[o][0].call(f.exports, function (e) { | |
var n = t[o][1][e];return s(n ? n : e); | |
}, f, f.exports, e, t, n, r); | |
}return n[o].exports; | |
}var i = typeof require == "function" && require;for (var o = 0; o < r.length; o++) s(r[o]);return s; | |
})({ 1: [function (require, module, exports) { | |
"use strict"; | |
var buffers = require("./impl/buffers"); | |
var channels = require("./impl/channels"); | |
var select = require("./impl/select"); | |
var process = require("./impl/process"); | |
var timers = require("./impl/timers"); | |
function spawn(gen, returnChannel) { | |
if (returnChannel) { | |
var ch = channels.chan(buffers.fixed(1)); | |
(new process.Process(gen, function (value) { | |
process.put_then_callback(ch, value, function (ok) { | |
ch.close(); | |
}); | |
})).run(); | |
return ch; | |
} else { | |
(new process.Process(gen)).run(); | |
return null; | |
} | |
}; | |
function go(f, args, returnChannel) { | |
var gen = f.apply(null, args); | |
return spawn(gen, returnChannel); | |
}; | |
function chan(bufferOrNumber) { | |
var buf; | |
if (bufferOrNumber === 0) { | |
bufferOrNumber = null; | |
} | |
if (typeof bufferOrNumber === "number") { | |
buf = buffers.fixed(bufferOrNumber); | |
} else { | |
buf = bufferOrNumber; | |
} | |
return channels.chan(buf); | |
}; | |
module.exports = { | |
buffers: { | |
fixed: buffers.fixed, | |
dropping: buffers.dropping, | |
sliding: buffers.sliding | |
}, | |
spawn: spawn, | |
go: go, | |
chan: chan, | |
DEFAULT: select.DEFAULT, | |
CLOSED: channels.CLOSED, | |
put: process.put, | |
take: process.take, | |
sleep: process.sleep, | |
alts: process.alts, | |
putAsync: process.put_then_callback, | |
takeAsync: process.take_then_callback, | |
timeout: timers.timeout | |
}; | |
}, { "./impl/buffers": 5, "./impl/channels": 6, "./impl/process": 8, "./impl/select": 9, "./impl/timers": 10 }], i2jwt0: [function (require, module, exports) { | |
"use strict"; | |
var csp = require("./csp.core"); | |
var operations = require("./csp.operations"); | |
csp.operations = operations; | |
module.exports = csp; | |
}, { "./csp.core": 1, "./csp.operations": 4 }], csp: [function (require, module, exports) { | |
module.exports = require("i2jwt0"); | |
}, {}], 4: [function (require, module, exports) { | |
var mapcat = regeneratorRuntime.mark(function mapcat(f, src, dst) { | |
var value, seq, length, i; | |
return regeneratorRuntime.wrap(function mapcat$(_context2) { | |
while (true) switch (_context2.prev = _context2.next) { | |
case 0: | |
if (!true) { | |
_context2.next = 22; | |
break; | |
} | |
_context2.next = 3; | |
return take(src); | |
case 3: value = _context2.sent; | |
if (!(value === CLOSED)) { | |
_context2.next = 9; | |
break; | |
} | |
dst.close(); | |
return _context2.abrupt("break", 22); | |
case 9: seq = f(value); | |
length = seq.length; | |
i = 0; | |
case 12: | |
if (!(i < length)) { | |
_context2.next = 18; | |
break; | |
} | |
_context2.next = 15; | |
return put(dst, seq[i]); | |
case 15: i++; | |
_context2.next = 12; | |
break; | |
case 18: | |
if (!dst.is_closed()) { | |
_context2.next = 20; | |
break; | |
} | |
return _context2.abrupt("break", 22); | |
case 20: _context2.next = 0; | |
break; | |
case 22: | |
case "end": return _context2.stop(); | |
} | |
}, mapcat, this); | |
}); | |
"use strict"; | |
var Box = require("./impl/channels").Box; | |
var csp = require("./csp.core"), go = csp.go, take = csp.take, put = csp.put, takeAsync = csp.takeAsync, putAsync = csp.putAsync, alts = csp.alts, chan = csp.chan, CLOSED = csp.CLOSED; | |
function noOp(v) {} | |
function mapFrom(f, ch) { | |
return { | |
is_closed: function () { | |
return ch.is_closed(); | |
}, | |
close: function () { | |
ch.close(); | |
}, | |
_put: function (value, handler) { | |
return ch._put(value, handler); | |
}, | |
_take: function (handler) { | |
var result = ch._take({ | |
is_active: function () { | |
return handler.is_active(); | |
}, | |
commit: function () { | |
var take_cb = handler.commit(); | |
return function (value) { | |
return take_cb(value === CLOSED ? CLOSED : f(value)); | |
}; | |
} | |
}); | |
if (result) { | |
var value = result.value; | |
return new Box(value === CLOSED ? CLOSED : f(value)); | |
} else { | |
return null; | |
} | |
} | |
}; | |
} | |
function mapInto(f, ch) { | |
return { | |
is_closed: function () { | |
return ch.is_closed(); | |
}, | |
close: function () { | |
ch.close(); | |
}, | |
_put: function (value, handler) { | |
return ch._put(f(value), handler); | |
}, | |
_take: function (handler) { | |
return ch._take(handler); | |
} | |
}; | |
} | |
function filterFrom(p, ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
go(regeneratorRuntime.mark(function _callee() { | |
var value; | |
return regeneratorRuntime.wrap(function _callee$(_context) { | |
while (true) switch (_context.prev = _context.next) { | |
case 0: | |
if (!true) { | |
_context.next = 12; | |
break; | |
} | |
_context.next = 3; | |
return take(ch); | |
case 3: value = _context.sent; | |
if (!(value === CLOSED)) { | |
_context.next = 7; | |
break; | |
} | |
out.close(); | |
return _context.abrupt("break", 12); | |
case 7: | |
if (!p(value)) { | |
_context.next = 10; | |
break; | |
} | |
_context.next = 10; | |
return put(out, value); | |
case 10: _context.next = 0; | |
break; | |
case 12: | |
case "end": return _context.stop(); | |
} | |
}, _callee, this); | |
})); | |
return out; | |
} | |
function filterInto(p, ch) { | |
return { | |
is_closed: function () { | |
return ch.is_closed(); | |
}, | |
close: function () { | |
ch.close(); | |
}, | |
_put: function (value, handler) { | |
if (p(value)) { | |
return ch._put(value, handler); | |
} else { | |
return new Box(!ch.is_closed()); | |
} | |
}, | |
_take: function (handler) { | |
return ch._take(handler); | |
} | |
}; | |
} | |
function removeFrom(p, ch) { | |
return filterFrom(function (value) { | |
return !p(value); | |
}, ch); | |
} | |
function removeInto(p, ch) { | |
return filterInto(function (value) { | |
return !p(value); | |
}, ch); | |
} | |
function mapcatFrom(f, ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
go(mapcat, [f, ch, out]); | |
return out; | |
} | |
function mapcatInto(f, ch, bufferOrN) { | |
var src = chan(bufferOrN); | |
go(mapcat, [f, src, ch]); | |
return src; | |
} | |
function pipe(src, dst, keepOpen) { | |
go(regeneratorRuntime.mark(function _callee2() { | |
var value; | |
return regeneratorRuntime.wrap(function _callee2$(_context3) { | |
while (true) switch (_context3.prev = _context3.next) { | |
case 0: | |
if (!true) { | |
_context3.next = 13; | |
break; | |
} | |
_context3.next = 3; | |
return take(src); | |
case 3: value = _context3.sent; | |
if (!(value === CLOSED)) { | |
_context3.next = 7; | |
break; | |
} | |
if (!keepOpen) { | |
dst.close(); | |
} | |
return _context3.abrupt("break", 13); | |
case 7: _context3.next = 9; | |
return put(dst, value); | |
case 9: | |
if (_context3.sent) { | |
_context3.next = 11; | |
break; | |
} | |
return _context3.abrupt("break", 13); | |
case 11: _context3.next = 0; | |
break; | |
case 13: | |
case "end": return _context3.stop(); | |
} | |
}, _callee2, this); | |
})); | |
return dst; | |
} | |
function split(p, ch, trueBufferOrN, falseBufferOrN) { | |
var tch = chan(trueBufferOrN); | |
var fch = chan(falseBufferOrN); | |
go(regeneratorRuntime.mark(function _callee3() { | |
var value; | |
return regeneratorRuntime.wrap(function _callee3$(_context4) { | |
while (true) switch (_context4.prev = _context4.next) { | |
case 0: | |
if (!true) { | |
_context4.next = 12; | |
break; | |
} | |
_context4.next = 3; | |
return take(ch); | |
case 3: value = _context4.sent; | |
if (!(value === CLOSED)) { | |
_context4.next = 8; | |
break; | |
} | |
tch.close(); | |
fch.close(); | |
return _context4.abrupt("break", 12); | |
case 8: _context4.next = 10; | |
return put(p(value) ? tch : fch, value); | |
case 10: _context4.next = 0; | |
break; | |
case 12: | |
case "end": return _context4.stop(); | |
} | |
}, _callee3, this); | |
})); | |
return [tch, fch]; | |
} | |
function reduce(f, init, ch) { | |
return go(regeneratorRuntime.mark(function _callee4() { | |
var result, value; | |
return regeneratorRuntime.wrap(function _callee4$(_context5) { | |
while (true) switch (_context5.prev = _context5.next) { | |
case 0: result = init; | |
case 1: | |
if (!true) { | |
_context5.next = 12; | |
break; | |
} | |
_context5.next = 4; | |
return take(ch); | |
case 4: value = _context5.sent; | |
if (!(value === CLOSED)) { | |
_context5.next = 9; | |
break; | |
} | |
return _context5.abrupt("return", result); | |
case 9: | |
result = f(result, value); | |
case 10: _context5.next = 1; | |
break; | |
case 12: | |
case "end": return _context5.stop(); | |
} | |
}, _callee4, this); | |
}), [], true); | |
} | |
function onto(ch, coll, keepOpen) { | |
return go(regeneratorRuntime.mark(function _callee5() { | |
var length, i; | |
return regeneratorRuntime.wrap(function _callee5$(_context6) { | |
while (true) switch (_context6.prev = _context6.next) { | |
case 0: length = coll.length; | |
i = 0; | |
case 2: | |
if (!(i < length)) { | |
_context6.next = 8; | |
break; | |
} | |
_context6.next = 5; | |
return put(ch, coll[i]); | |
case 5: i++; | |
_context6.next = 2; | |
break; | |
case 8: | |
if (!keepOpen) { | |
ch.close(); | |
} | |
case 9: | |
case "end": return _context6.stop(); | |
} | |
}, _callee5, this); | |
})); | |
} | |
// TODO: Bounded? | |
function fromColl(coll) { | |
var ch = chan(coll.length); | |
onto(ch, coll); | |
return ch; | |
} | |
function map(f, chs, bufferOrN) { | |
var out = chan(bufferOrN); | |
var length = chs.length; | |
// Array holding 1 round of values | |
var values = new Array(length); | |
// TODO: Not sure why we need a size-1 buffer here | |
var dchan = chan(1); | |
// How many more items this round | |
var dcount; | |
// put callbacks for each channel | |
var dcallbacks = new Array(length); | |
for (var i = 0; i < length; i++) { | |
dcallbacks[i] = (function (i) { | |
return function (value) { | |
values[i] = value; | |
dcount--; | |
if (dcount === 0) { | |
putAsync(dchan, values.slice(0), noOp); | |
} | |
}; | |
}(i)); | |
} | |
go(regeneratorRuntime.mark(function _callee6() { | |
var i, values; | |
return regeneratorRuntime.wrap(function _callee6$(_context7) { | |
while (true) switch (_context7.prev = _context7.next) { | |
case 0: | |
if (!true) { | |
_context7.next = 18; | |
break; | |
} | |
dcount = length; | |
// We could just launch n goroutines here, but for effciency we | |
// don't | |
for (i = 0; i < length; i++) { | |
try { | |
takeAsync(chs[i], dcallbacks[i]); | |
} catch (e) { | |
// FIX: Hmm why catching here? | |
dcount--; | |
} | |
} | |
_context7.next = 5; | |
return take(dchan); | |
case 5: values = _context7.sent; | |
i = 0; | |
case 7: | |
if (!(i < length)) { | |
_context7.next = 14; | |
break; | |
} | |
if (!(values[i] === CLOSED)) { | |
_context7.next = 11; | |
break; | |
} | |
out.close(); | |
return _context7.abrupt("return"); | |
case 11: i++; | |
_context7.next = 7; | |
break; | |
case 14: _context7.next = 16; | |
return put(out, f.apply(null, values)); | |
case 16: _context7.next = 0; | |
break; | |
case 18: | |
case "end": return _context7.stop(); | |
} | |
}, _callee6, this); | |
})); | |
return out; | |
} | |
function merge(chs, bufferOrN) { | |
var out = chan(bufferOrN); | |
var actives = chs.slice(0); | |
go(regeneratorRuntime.mark(function _callee7() { | |
var r, value, i; | |
return regeneratorRuntime.wrap(function _callee7$(_context8) { | |
while (true) switch (_context8.prev = _context8.next) { | |
case 0: | |
if (!true) { | |
_context8.next = 15; | |
break; | |
} | |
if (!(actives.length === 0)) { | |
_context8.next = 3; | |
break; | |
} | |
return _context8.abrupt("break", 15); | |
case 3: _context8.next = 5; | |
return alts(actives); | |
case 5: r = _context8.sent; | |
value = r.value; | |
if (!(value === CLOSED)) { | |
_context8.next = 11; | |
break; | |
} | |
i = actives.indexOf(r.channel); | |
actives.splice(i, 1); | |
return _context8.abrupt("continue", 0); | |
case 11: _context8.next = 13; | |
return put(out, value); | |
case 13: _context8.next = 0; | |
break; | |
case 15: | |
out.close(); | |
case 16: | |
case "end": return _context8.stop(); | |
} | |
}, _callee7, this); | |
})); | |
return out; | |
} | |
function into(coll, ch) { | |
var result = coll.slice(0); | |
return reduce(function (result, item) { | |
result.push(item); | |
return result; | |
}, result, ch); | |
} | |
function takeN(n, ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
go(regeneratorRuntime.mark(function _callee8() { | |
var i, value; | |
return regeneratorRuntime.wrap(function _callee8$(_context9) { | |
while (true) switch (_context9.prev = _context9.next) { | |
case 0: i = 0; | |
case 1: | |
if (!(i < n)) { | |
_context9.next = 12; | |
break; | |
} | |
_context9.next = 4; | |
return take(ch); | |
case 4: value = _context9.sent; | |
if (!(value === CLOSED)) { | |
_context9.next = 7; | |
break; | |
} | |
return _context9.abrupt("break", 12); | |
case 7: _context9.next = 9; | |
return put(out, value); | |
case 9: i++; | |
_context9.next = 1; | |
break; | |
case 12: | |
out.close(); | |
case 13: | |
case "end": return _context9.stop(); | |
} | |
}, _callee8, this); | |
})); | |
return out; | |
} | |
var NOTHING = {}; | |
function unique(ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
var last = NOTHING; | |
go(regeneratorRuntime.mark(function _callee9() { | |
var value; | |
return regeneratorRuntime.wrap(function _callee9$(_context10) { | |
while (true) switch (_context10.prev = _context10.next) { | |
case 0: | |
if (!true) { | |
_context10.next = 13; | |
break; | |
} | |
_context10.next = 3; | |
return take(ch); | |
case 3: value = _context10.sent; | |
if (!(value === CLOSED)) { | |
_context10.next = 6; | |
break; | |
} | |
return _context10.abrupt("break", 13); | |
case 6: | |
if (!(value === last)) { | |
_context10.next = 8; | |
break; | |
} | |
return _context10.abrupt("continue", 0); | |
case 8: | |
last = value; | |
_context10.next = 11; | |
return put(out, value); | |
case 11: _context10.next = 0; | |
break; | |
case 13: | |
out.close(); | |
case 14: | |
case "end": return _context10.stop(); | |
} | |
}, _callee9, this); | |
})); | |
return out; | |
} | |
function partitionBy(f, ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
var part = []; | |
var last = NOTHING; | |
go(regeneratorRuntime.mark(function _callee10() { | |
var value, newItem; | |
return regeneratorRuntime.wrap(function _callee10$(_context11) { | |
while (true) switch (_context11.prev = _context11.next) { | |
case 0: | |
if (!true) { | |
_context11.next = 23; | |
break; | |
} | |
_context11.next = 3; | |
return take(ch); | |
case 3: value = _context11.sent; | |
if (!(value === CLOSED)) { | |
_context11.next = 12; | |
break; | |
} | |
if (!(part.length > 0)) { | |
_context11.next = 8; | |
break; | |
} | |
_context11.next = 8; | |
return put(out, part); | |
case 8: | |
out.close(); | |
return _context11.abrupt("break", 23); | |
case 12: newItem = f(value); | |
if (!(newItem === last || last === NOTHING)) { | |
_context11.next = 17; | |
break; | |
} | |
part.push(value); | |
_context11.next = 20; | |
break; | |
case 17: _context11.next = 19; | |
return put(out, part); | |
case 19: | |
part = [value]; | |
case 20: | |
last = newItem; | |
case 21: _context11.next = 0; | |
break; | |
case 23: | |
case "end": return _context11.stop(); | |
} | |
}, _callee10, this); | |
})); | |
return out; | |
} | |
function partition(n, ch, bufferOrN) { | |
var out = chan(bufferOrN); | |
go(regeneratorRuntime.mark(function _callee11() { | |
var part, i, value; | |
return regeneratorRuntime.wrap(function _callee11$(_context12) { | |
while (true) switch (_context12.prev = _context12.next) { | |
case 0: | |
if (!true) { | |
_context12.next = 21; | |
break; | |
} | |
part = new Array(n); | |
i = 0; | |
case 3: | |
if (!(i < n)) { | |
_context12.next = 17; | |
break; | |
} | |
_context12.next = 6; | |
return take(ch); | |
case 6: value = _context12.sent; | |
if (!(value === CLOSED)) { | |
_context12.next = 13; | |
break; | |
} | |
if (!(i > 0)) { | |
_context12.next = 11; | |
break; | |
} | |
_context12.next = 11; | |
return put(out, part.slice(0, i)); | |
case 11: | |
out.close(); | |
return _context12.abrupt("return"); | |
case 13: | |
part[i] = value; | |
case 14: i++; | |
_context12.next = 3; | |
break; | |
case 17: _context12.next = 19; | |
return put(out, part); | |
case 19: _context12.next = 0; | |
break; | |
case 21: | |
case "end": return _context12.stop(); | |
} | |
}, _callee11, this); | |
})); | |
return out; | |
} | |
module.exports = { | |
mapFrom: mapFrom, | |
mapInto: mapInto, | |
filterFrom: filterFrom, | |
filterInto: filterInto, | |
removeFrom: removeFrom, | |
removeInto: removeInto, | |
mapcatFrom: mapcatFrom, | |
mapcatInto: mapcatInto, | |
pipe: pipe, | |
split: split, | |
reduce: reduce, | |
onto: onto, | |
fromColl: fromColl, | |
map: map, | |
merge: merge, | |
into: into, | |
take: takeN, | |
unique: unique, | |
partition: partition, | |
partitionBy: partitionBy | |
}; | |
// Possible "fluid" interfaces: | |
// thread( | |
// [fromColl, [1, 2, 3, 4]], | |
// [mapFrom, inc], | |
// [into, []] | |
// ) | |
// thread( | |
// [fromColl, [1, 2, 3, 4]], | |
// [mapFrom, inc, _], | |
// [into, [], _] | |
// ) | |
// wrap() | |
// .fromColl([1, 2, 3, 4]) | |
// .mapFrom(inc) | |
// .into([]) | |
// .unwrap(); | |
}, { "./csp.core": 1, "./impl/channels": 6 }], 5: [function (require, module, exports) { | |
"use strict"; | |
// TODO: Consider EmptyError & FullError to avoid redundant bound | |
// checks, to improve performance (may need benchmarks) | |
function acopy(src, src_start, dst, dst_start, length) { | |
var count = 0; | |
while (true) { | |
if (count >= length) { | |
break; | |
} | |
dst[dst_start + count] = src[src_start + count]; | |
count++; | |
} | |
} | |
var EMPTY = { | |
toString: function () { | |
return "[object EMPTY]"; | |
} | |
}; | |
var RingBuffer = function (head, tail, length, array) { | |
this.length = length; | |
this.array = array; | |
this.head = head; | |
this.tail = tail; | |
}; | |
// Internal method, callers must do bound check | |
RingBuffer.prototype._unshift = function (item) { | |
var array = this.array; | |
var head = this.head; | |
array[head] = item; | |
this.head = (head + 1) % array.length; | |
this.length++; | |
}; | |
RingBuffer.prototype._resize = function () { | |
var array = this.array; | |
var new_length = 2 * array.length; | |
var new_array = new Array(new_length); | |
var head = this.head; | |
var tail = this.tail; | |
var length = this.length; | |
if (tail < head) { | |
acopy(array, tail, new_array, 0, length); | |
this.tail = 0; | |
this.head = length; | |
this.array = new_array; | |
} else if (tail > head) { | |
acopy(array, tail, new_array, 0, array.length - tail); | |
acopy(array, 0, new_array, array.length - tail, head); | |
this.tail = 0; | |
this.head = length; | |
this.array = new_array; | |
} else if (tail === head) { | |
this.tail = 0; | |
this.head = 0; | |
this.array = new_array; | |
} | |
}; | |
RingBuffer.prototype.unbounded_unshift = function (item) { | |
if (this.length + 1 === this.array.length) { | |
this._resize(); | |
} | |
this._unshift(item); | |
}; | |
RingBuffer.prototype.pop = function () { | |
if (this.length === 0) { | |
return EMPTY; | |
} | |
var array = this.array; | |
var tail = this.tail; | |
var item = array[tail]; | |
array[tail] = null; | |
this.tail = (tail + 1) % array.length; | |
this.length--; | |
return item; | |
}; | |
RingBuffer.prototype.cleanup = function (predicate) { | |
var length = this.length; | |
for (var i = 0; i < length; i++) { | |
var item = this.pop(); | |
if (predicate(item)) { | |
this._unshift(item); | |
} | |
} | |
}; | |
var FixedBuffer = function (buf, n) { | |
this.buf = buf; | |
this.n = n; | |
}; | |
FixedBuffer.prototype.is_full = function () { | |
return this.buf.length == this.n; | |
}; | |
FixedBuffer.prototype.remove = function () { | |
return this.buf.pop(); | |
}; | |
FixedBuffer.prototype.add = function (item) { | |
if (this.is_full()) { | |
throw new Error("Can't add to a full buffer"); | |
} | |
this.buf._unshift(item); | |
}; | |
FixedBuffer.prototype.count = function () { | |
return this.buf.length; | |
}; | |
var DroppingBuffer = function (buf, n) { | |
this.buf = buf; | |
this.n = n; | |
}; | |
DroppingBuffer.prototype.is_full = function () { | |
return false; | |
}; | |
DroppingBuffer.prototype.remove = function () { | |
return this.buf.pop(); | |
}; | |
DroppingBuffer.prototype.add = function (item) { | |
if (this.buf.length < this.n) { | |
this.buf._unshift(item); | |
} | |
}; | |
DroppingBuffer.prototype.count = function () { | |
return this.buf.length; | |
}; | |
var SlidingBuffer = function (buf, n) { | |
this.buf = buf; | |
this.n = n; | |
}; | |
SlidingBuffer.prototype.is_full = function () { | |
return false; | |
}; | |
SlidingBuffer.prototype.remove = function () { | |
return this.buf.pop(); | |
}; | |
SlidingBuffer.prototype.add = function (item) { | |
if (this.buf.length === this.n) { | |
this.buf.pop(); | |
} | |
this.buf._unshift(item); | |
}; | |
SlidingBuffer.prototype.count = function () { | |
return this.buf.length; | |
}; | |
var ring = exports.ring = function ring_buffer(n) { | |
return new RingBuffer(0, 0, 0, new Array(n)); | |
}; | |
exports.fixed = function fixed_buffer(n) { | |
return new FixedBuffer(ring(n), n); | |
}; | |
exports.dropping = function dropping_buffer(n) { | |
return new DroppingBuffer(ring(n), n); | |
}; | |
exports.sliding = function sliding_buffer(n) { | |
return new SlidingBuffer(ring(n), n); | |
}; | |
exports.EMPTY = EMPTY; | |
}, {}], 6: [function (require, module, exports) { | |
"use strict"; | |
var buffers = require("./buffers"); | |
var dispatch = require("./dispatch"); | |
var MAX_DIRTY = 64; | |
var MAX_QUEUE_SIZE = 1024; | |
var CLOSED = null; | |
var Box = function (value) { | |
this.value = value; | |
}; | |
var PutBox = function (handler, value) { | |
this.handler = handler; | |
this.value = value; | |
}; | |
var Channel = function (takes, puts, buf) { | |
this.buf = buf; | |
this.takes = takes; | |
this.puts = puts; | |
this.dirty_takes = 0; | |
this.dirty_puts = 0; | |
this.closed = false; | |
}; | |
Channel.prototype._put = function (value, handler) { | |
if (value === CLOSED) { | |
throw new Error("Cannot put CLOSED on a channel."); | |
} | |
if (this.closed || !handler.is_active()) { | |
return new Box(!this.closed); | |
} | |
while (true) { | |
var taker = this.takes.pop(); | |
if (taker !== buffers.EMPTY) { | |
if (taker.is_active()) { | |
var callback = taker.commit(); | |
handler.commit(); | |
dispatch.run(function () { | |
callback(value); | |
}); | |
return new Box(true); | |
} else { | |
continue; | |
} | |
} else { | |
if (this.buf && !this.buf.is_full()) { | |
handler.commit(); | |
this.buf.add(value); | |
return new Box(true); | |
} else { | |
if (this.dirty_puts > MAX_DIRTY) { | |
this.puts.cleanup(function (putter) { | |
return putter.handler.is_active(); | |
}); | |
this.dirty_puts = 0; | |
} else { | |
this.dirty_puts++; | |
} | |
if (this.puts.length >= MAX_QUEUE_SIZE) { | |
throw new Error("No more than " + MAX_QUEUE_SIZE + " pending puts are allowed on a single channel."); | |
} | |
this.puts.unbounded_unshift(new PutBox(handler, value)); | |
} | |
} | |
break; | |
} | |
return null; | |
}; | |
Channel.prototype._take = function (handler) { | |
if (!handler.is_active()) { | |
return null; | |
} | |
if (this.buf && this.buf.count() > 0) { | |
handler.commit(); | |
return new Box(this.buf.remove()); | |
} | |
while (true) { | |
var putter = this.puts.pop(); | |
if (putter !== buffers.EMPTY) { | |
var put_handler = putter.handler; | |
if (put_handler.is_active()) { | |
handler.commit(); | |
var callback = put_handler.commit(); | |
dispatch.run(function () { | |
callback(true); | |
}); | |
return new Box(putter.value); | |
} else { | |
continue; | |
} | |
} else { | |
if (this.closed) { | |
handler.commit(); | |
return new Box(CLOSED); | |
} else { | |
if (this.dirty_takes > MAX_DIRTY) { | |
this.takes.cleanup(function (handler) { | |
return handler.is_active(); | |
}); | |
this.dirty_takes = 0; | |
} else { | |
this.dirty_takes++; | |
} | |
if (this.takes.length >= MAX_QUEUE_SIZE) { | |
throw new Error("No more than " + MAX_QUEUE_SIZE + " pending takes are allowed on a single channel."); | |
} | |
this.takes.unbounded_unshift(handler); | |
} | |
} | |
break; | |
} | |
return null; | |
}; | |
Channel.prototype.close = function () { | |
if (this.closed) { | |
return; | |
} | |
this.closed = true; | |
while (true) { | |
var taker = this.takes.pop(); | |
if (taker === buffers.EMPTY) { | |
break; | |
} | |
if (taker.is_active()) { | |
var callback = taker.commit(); | |
dispatch.run(function () { | |
callback(CLOSED); | |
}); | |
} | |
} | |
// TODO: Tests | |
while (true) { | |
var putter = this.puts.pop(); | |
if (putter === buffers.EMPTY) { | |
break; | |
} | |
if (putter.handler.is_active()) { | |
var put_callback = putter.handler.commit(); | |
dispatch.run(function () { | |
put_callback(false); | |
}); | |
} | |
} | |
}; | |
Channel.prototype.is_closed = function () { | |
return this.closed; | |
}; | |
exports.chan = function (buf) { | |
return new Channel(buffers.ring(32), buffers.ring(32), buf); | |
}; | |
exports.Box = Box; | |
exports.CLOSED = CLOSED; | |
}, { "./buffers": 5, "./dispatch": 7 }], 7: [function (require, module, exports) { | |
"use strict"; | |
// TODO: Use process.nextTick if it's available since it's more | |
// efficient | |
// http://howtonode.org/understanding-process-next-tick | |
// Maybe we don't even need to queue ourselves in that case? | |
// XXX: But http://blog.nodejs.org/2013/03/11/node-v0-10-0-stable/ | |
// Looks like it will blow up the stack (or is that just about | |
// pre-empting IO (but that's already bad enough IMO)?) | |
// Looks like | |
// http://nodejs.org/api/process.html#process_process_nexttick_callback | |
// is the equivalent of our TASK_BATCH_SIZE | |
var buffers = require("./buffers"); | |
var TASK_BATCH_SIZE = 1024; | |
var tasks = buffers.ring(32); | |
var running = false; | |
var queued = false; | |
var queue_dispatcher; | |
function process_messages() { | |
running = true; | |
queued = false; | |
var count = 0; | |
while (true) { | |
var task = tasks.pop(); | |
if (task === buffers.EMPTY) { | |
break; | |
} | |
// TODO: Don't we need a try/finally here? | |
task(); | |
if (count >= TASK_BATCH_SIZE) { | |
break; | |
} | |
count++; | |
} | |
running = false; | |
if (tasks.length > 0) { | |
queue_dispatcher(); | |
} | |
} | |
if (typeof MessageChannel !== "undefined") { | |
var message_channel = new MessageChannel(); | |
message_channel.port1.onmessage = function (_) { | |
process_messages(); | |
}; | |
queue_dispatcher = function () { | |
if (!(queued && running)) { | |
queued = true; | |
message_channel.port2.postMessage(0); | |
} | |
}; | |
} else if (typeof setImmediate !== "undefined") { | |
queue_dispatcher = function () { | |
if (!(queued && running)) { | |
queued = true; | |
setImmediate(process_messages); | |
} | |
}; | |
} else { | |
queue_dispatcher = function () { | |
if (!(queued && running)) { | |
queued = true; | |
setTimeout(process_messages, 0); | |
} | |
}; | |
} | |
exports.run = function (f) { | |
tasks.unbounded_unshift(f); | |
queue_dispatcher(); | |
}; | |
exports.queue_delay = function (f, delay) { | |
setTimeout(f, delay); | |
}; | |
}, { "./buffers": 5 }], 8: [function (require, module, exports) { | |
"use strict"; | |
var dispatch = require("./dispatch"); | |
var select = require("./select"); | |
var FnHandler = function (f) { | |
this.f = f; | |
}; | |
FnHandler.prototype.is_active = function () { | |
return true; | |
}; | |
FnHandler.prototype.commit = function () { | |
return this.f; | |
}; | |
function put_then_callback(channel, value, callback) { | |
var result = channel._put(value, new FnHandler(callback)); | |
if (result) { | |
callback(result.value); | |
} | |
} | |
function take_then_callback(channel, callback) { | |
var result = channel._take(new FnHandler(callback)); | |
if (result) { | |
callback(result.value); | |
} | |
} | |
var Process = function (gen, onFinish) { | |
this.gen = gen; | |
this.finished = false; | |
this.onFinish = onFinish; | |
}; | |
var Instruction = function (op, data) { | |
this.op = op; | |
this.data = data; | |
}; | |
var TAKE = "take"; | |
var PUT = "put"; | |
var SLEEP = "sleep"; | |
var ALTS = "alts"; | |
// TODO FIX XXX: This is a (probably) temporary hack to avoid blowing | |
// up the stack, but it means double queueing when the value is not | |
// immediately available | |
Process.prototype._continue = function (response) { | |
var self = this; | |
dispatch.run(function () { | |
self.run(response); | |
}); | |
}; | |
Process.prototype._done = function (value) { | |
if (!this.finished) { | |
this.finished = true; | |
var onFinish = this.onFinish; | |
if (typeof onFinish === "function") { | |
dispatch.run(function () { | |
onFinish(value); | |
}); | |
} | |
} | |
}; | |
Process.prototype.run = function (response) { | |
if (this.finished) { | |
return; | |
} | |
// TODO: Shouldn't we (optionally) stop error propagation here (and | |
// signal the error through a channel or something)? Otherwise the | |
// uncaught exception will crash some runtimes (e.g. Node) | |
var iter = this.gen.next(response); | |
if (iter.done) { | |
this._done(iter.value); | |
return; | |
} | |
var ins = iter.value; | |
if (ins instanceof Instruction) { | |
var self = this; | |
switch (ins.op) { | |
case PUT: | |
var data = ins.data; | |
put_then_callback(data.channel, data.value, function (ok) { | |
self._continue(ok); | |
}); | |
break; | |
case TAKE: | |
var channel = ins.data; | |
take_then_callback(channel, function (value) { | |
self._continue(value); | |
}); | |
break; | |
case SLEEP: | |
var msecs = ins.data; | |
dispatch.queue_delay(function () { | |
self.run(null); | |
}, msecs); | |
break; | |
case ALTS: | |
select.do_alts(ins.data.operations, function (result) { | |
self._continue(result); | |
}, ins.data.options); | |
break; | |
} | |
} else { | |
this._continue(ins); | |
} | |
}; | |
function take(channel) { | |
return new Instruction(TAKE, channel); | |
} | |
function put(channel, value) { | |
return new Instruction(PUT, { | |
channel: channel, | |
value: value | |
}); | |
} | |
function sleep(msecs) { | |
return new Instruction(SLEEP, msecs); | |
} | |
function alts(operations, options) { | |
return new Instruction(ALTS, { | |
operations: operations, | |
options: options | |
}); | |
} | |
exports.put_then_callback = put_then_callback; | |
exports.take_then_callback = take_then_callback; | |
exports.put = put; | |
exports.take = take; | |
exports.sleep = sleep; | |
exports.alts = alts; | |
exports.Process = Process; | |
}, { "./dispatch": 7, "./select": 9 }], 9: [function (require, module, exports) { | |
"use strict"; | |
var Box = require("./channels").Box; | |
var AltHandler = function (flag, f) { | |
this.f = f; | |
this.flag = flag; | |
}; | |
AltHandler.prototype.is_active = function () { | |
return this.flag.value; | |
}; | |
AltHandler.prototype.commit = function () { | |
this.flag.value = false; | |
return this.f; | |
}; | |
var AltResult = function (value, channel) { | |
this.value = value; | |
this.channel = channel; | |
}; | |
function rand_int(n) { | |
return Math.floor(Math.random() * (n + 1)); | |
} | |
function random_array(n) { | |
var a = new Array(n); | |
var i; | |
for (i = 0; i < n; i++) { | |
a[i] = 0; | |
} | |
for (i = 1; i < n; i++) { | |
var j = rand_int(i); | |
a[i] = a[j]; | |
a[j] = i; | |
} | |
return a; | |
} | |
var hasOwnProperty = Object.prototype.hasOwnProperty; | |
var DEFAULT = { | |
toString: function () { | |
return "[object DEFAULT]"; | |
} | |
}; | |
// TODO: Accept a priority function or something | |
exports.do_alts = function (operations, callback, options) { | |
var length = operations.length; | |
// XXX Hmm | |
if (length === 0) { | |
throw new Error("Empty alt list"); | |
} | |
var priority = (options && options.priority) ? true : false; | |
if (!priority) { | |
var indexes = random_array(length); | |
} | |
var flag = new Box(true); | |
for (var i = 0; i < length; i++) { | |
var operation = operations[priority ? i : indexes[i]]; | |
var port, result; | |
// XXX Hmm | |
if (operation instanceof Array) { | |
var value = operation[1]; | |
port = operation[0]; | |
result = port._put(value, (function (port) { | |
return new AltHandler(flag, function (ok) { | |
callback(new AltResult(ok, port)); | |
}); | |
})(port)); | |
} else { | |
port = operation; | |
result = port._take((function (port) { | |
return new AltHandler(flag, function (value) { | |
callback(new AltResult(value, port)); | |
}); | |
})(port)); | |
} | |
// XXX Hmm | |
if (result instanceof Box) { | |
callback(new AltResult(result.value, port)); | |
break; | |
} | |
} | |
if (!(result instanceof Box) && options && hasOwnProperty.call(options, "default")) { | |
if (flag.value) { | |
flag.value = false; | |
callback(new AltResult(options["default"], DEFAULT)); | |
} | |
} | |
}; | |
exports.DEFAULT = DEFAULT; | |
}, { "./channels": 6 }], 10: [function (require, module, exports) { | |
"use strict"; | |
var dispatch = require("./dispatch"); | |
var channels = require("./channels"); | |
exports.timeout = function timeout_channel(msecs) { | |
var chan = channels.chan(); | |
dispatch.queue_delay(function () { | |
chan.close(); | |
}, msecs); | |
return chan; | |
}; | |
}, { "./channels": 6, "./dispatch": 7 }] }, {}, ["i2jwt0"]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment