latte_lib
Version:
1,711 lines (1,572 loc) • 127 kB
JavaScript
(function() {
var LATTE_NAMESPACE = "latte";
var global = (function() {
return this;
})();
if (!LATTE_NAMESPACE && typeof requirejs !== "undefined")
return;
var _define = function(module, deps, payload) {
if (typeof module !== 'string') {
if (_define.original)
_define.original.apply(window, arguments);
else {
console.error('dropping module because define wasn\'t a string.');
console.trace();
}
return;
}
if (arguments.length == 2)
payload = deps;
if (!_define.modules) {
_define.modules = {};
_define.payloads = {};
}
_define.payloads[module] = payload;
_define.modules[module] = null;
};
var _require = function(parentId, module, callback) {
if (Object.prototype.toString.call(module) === "[object Array]") {
var params = [];
for (var i = 0, l = module.length; i < l; ++i) {
var dep = lookup(parentId, module[i]);
if (!dep && _require.original)
return _require.original.apply(window, arguments);
params.push(dep);
}
if (callback) {
callback.apply(null, params);
}
}
else if (typeof module === 'string') {
var payload = lookup(parentId, module);
if (!payload && _require.original)
return _require.original.apply(window, arguments);
if (callback) {
callback();
}
return payload;
}
else {
if (_require.original)
return _require.original.apply(window, arguments);
}
};
var resolve = function(parentId, moduleName) {
if(moduleName.charAt(0) == ".") {
var ps = parentId.split("/");
var base = ps.pop();
//var paths = ps.join("/");
var ms = moduleName.split("/");
var n ;
while((n = ms.shift())) {
if(n == "..") {
ps.pop();
}else if(n != "."){
ps.push(n);
}
}
return ps.join("/");
}
return moduleName;
}
var normalizeModule = function(parentId, moduleName) {
// normalize plugin requires
if (moduleName.indexOf("!") !== -1) {
var chunks = moduleName.split("!");
return normalizeModule(parentId, chunks[0]) + "!" + normalizeModule(parentId, chunks[1]);
}
// normalize relative requires
/*if (moduleName.charAt(0) == ".") {
var base = parentId.split("/").slice(0, -1).join("/");
moduleName = base + "/" + moduleName;
while(moduleName.indexOf(".") !== -1 && previous != moduleName) {
var previous = moduleName;
moduleName = moduleName.replace(/\/\.\//, "/").replace(/[^\/]+\/\.\.\//, "");
}
}*/
//console.log(parentId, moduleName);
name = resolve(parentId, moduleName);
//console.log(parentId, moduleName, name);
return name;
};
var lookup = function(parentId, moduleName) {
moduleName = normalizeModule(parentId, moduleName);
var module = _define.modules[moduleName];
if (!module) {
module = _define.payloads[moduleName];
if (typeof module === 'function') {
var exports = {};
var mod = {
id: moduleName,
uri: '',
exports: exports,
packaged: true
};
var req = function(module, callback) {
return _require(moduleName, module, callback);
};
var returnValue = module(req, exports, mod, global);
exports = returnValue || mod.exports;
_define.modules[moduleName] = exports;
delete _define.payloads[moduleName];
}
module = exports || module;
if(!module && moduleName.indexOf(".js") == -1) {
module = _define.modules[moduleName] = lookup(parentId, moduleName + ".js");
}
if(!module && moduleName.indexOf("/index") == -1) {
module = _define.modules[moduleName] = lookup(parentId, moduleName+"/index");
}
if(!module && moduleName.indexOf("/index.js") == -1) {
module = _define.modules[moduleName] = lookup(parentId, moduleName+"/index.js");
}
}
if(!module) {
//console.log("unload error",parentId, moduleName);
}
_define.modules[moduleName] = module;
return module;
};
function exportWindow(ns) {
var require = function(module, callback) {
return _require("", module, callback);
};
var root = global;
if (ns) {
if (!global[ns])
global[ns] = {};
root = global[ns];
}
if (!root.define || !root.define.packaged) {
_define.original = root.define;
root.define = _define;
root.define.packaged = true;
}
if (!root.require || !root.require.packaged) {
_require.original = root.require;
root.require = require;
root.require.packaged = true;
root.require.find = function(path, all) {
var pathStrNum = path.length;
var callbackArray = [];
Object.keys(_define.modules).forEach(function(p) {
if(p.indexOf(path) == 0) {
var nPath = p.substring(pathStrNum);
if(all) {
callbackArray.push(nPath);
}else{
if(nPath.indexOf("/") == -1) {
callbackArray.push(nPath);
}
}
}
});
return callbackArray;
}
}
}
exportWindow(LATTE_NAMESPACE);
//window._require = require;
})();
latte.global = this;
this.define = latte.define;
latte.config = {};
(function() {
this.config = {};
}).call(latte);
(function(define) {'use strict'
define("latte_lib/basic/array.js", ["require", "exports", "module", "window"],
function(require, exports, module, window) {
var latte_lib = require("./lib.js")
, events = require("./events.js")
, LatteObject = require("./object");
/*
相关的splice 等返回事件 请返回latteObject 而不是Object对象 现在还没全修改完
2016-7-7
*/
var LatteArray = function(data) {
var self = this;
this.data = [];
var doEvent = function(name, value, oldValue) {
var index = self.data.indexOf(this);
if(index != -1) {
self.emit(index + "." + name, value, oldValue, data);
self.emit("change", index + "." + name, value, oldValue, data);
}else{
removeEvent(this);
}
};
var addEvent = function(value) {
value.on("change", doEvent);
};
var removeEvent = function(value) {
if(LatteObject.isLatteObject(value)) {
value.off("change", doEvent);
}
};
(function init() {
data.forEach(function(o, i) {
var n = LatteObject.create(o);
if(n) {
addEvent(n);
self.data[i] = n;
}else{
self.data[i] = o;
}
});
})();
/**
var data = latte_lib.object.create({
list: []
});
data.on("list", function(value, list) {
});
data.set("list", [1,2,3]);
*/
var set = function(key, value, mode) {
if(!latte_lib.isArray(key)) {
key = key.toString().split(".");
}
if(key.length == 1) {
var k = key[0];
var ov = self.data[k];
var od = data[k];
var nv;
switch(mode) {
case 1:
break;
default:
removeEvent(ov);
var nv = LatteObject.create(value);
if(nv) {
addEvent(nv);
}else{
nv = value;
}
self.data[k] = nv;
data[k] = value;
return {
ov: ov,
nv: nv
};
break;
}
}else{
var k = key.pop();
var o = self;
var parent;
for(var i = 0, len = key.length ; i < len; i++) {
parent = o;
o = o.get(key[i]);
if(!o) {
o = new LatteObject({});
parent.set(key[i], o);
}
}
return self.get(key).set(k, value, mode);
}
};
this._set = set;
this.set = function(key, value, mode) {
var result = set(key, value , mode);
if(key.indexOf(".") == -1) {
self.emit("change", key, result.nv, result.ov);
self.emit(key, result.nv, result.ov);
}
self.emit("set", key, result.nv, result.ov);
return result;
}
this.get = function(key) {
if(key == "this" && !self.data[key]) {
return self;
}
if(!latte_lib.isArray(key)) {
key = key.toString().split(".");
}
var v = self;
if(key.length == 1) {
return self.data[key[0]];
}else{
var k = key.shift();
return self.data[k].get(key);
}
}
/**
@method push
@param o {any}
*/
this.push = function(o) {
var key = self.data.length;
var data = set(key, o);
self.emit("splice", key, [], [data.nv]);
self.emit("change", key, data.nv);
}
this.pop = function() {
var data = set(self.length - 1, null);
self.data.pop();
self.emit("splice", self.length, [data.ov], []);
}
/**
var data = latte_lib.object.create({
a: [{
c:1
}],
b:[1]
});
data.get("a").on("splice", function(index, removeArray, addArray) {
});
data.get("a").shift();
data.get("b").on("splice", function(index, removeArray, addArray) {
});
data.get("b").shift();
*/
this.shift = function() {
var old = self.data.shift();
removeEvent(old);
self.emit("splice", 0, [old],[]);
for(var i = 0, len = self.data.length; i < len; i++) {
self.emit("change", i, self.data[i]);
}
self.emit("change", self.data.length, null);
}
this.unshift = function() {
var args = Array.prototype.map.call(arguments, function(value) {
var o = LatteObject.create(value);
if(o) {
o.on("change", doEvent);
}
return o || value;
});
self.data.unshift.apply(self.data, args);
self.emit("splice", 0, [], args);
for(var i = 0, len = self.data.length; i < len; i++) {
self.emit("change", i, self.data[i]);
}
}
this.splice = function(startIndex, num) {
var oLength = self.data.length;
var adds = Array.prototype.splice.call(arguments, 2).map(function(o) {
var n = LatteObject.create(o);
if(n) {
n.on("change", doEvent);
}
return n || o;
});
var olds = [];
for(var i = 0; i < num; i++) {
var old = self.get(startIndex+i);
if(old){
removeEvent(old);
olds.push(old);
}
}
self.data.splice.apply(self.data, [startIndex, num].concat(adds));
self.emit("splice", startIndex, olds, adds);
for(var i = 0, len = Math.max(oLength, self.data.length); i < len; i++) {
self.emit("change", i, self.data[i]);
}
}
this.toJSON = function() {
return data;
}
this.indexOf = function(data) {
return self.data.indexOf(data);
}
this.forEach = function(callback) {
self.data.forEach(callback);
};
this.map = function(callback) {
return self.data.map(callback);
}
this.filter = function(callback) {
return self.data.filter(callback);
}
Object.defineProperty(self, "length", {
get: function() {
return self.data.length;
},
set: function(value) {
throw new Error("暂时没处理")
}
});
this.getKeys = function() {
return Object.keys(self.data);
}
};
latte_lib.inherits(LatteArray, events);
(function() {
}).call(LatteArray);
module.exports = LatteArray;
});
})(typeof define === "function"? define: function(name, reqs, factory) { factory(require, exports, module); });
(function(define) {'use strict'
define("latte_lib/basic/async.js", ["require", "exports", "module", "window"],
function(require, exports, module, window) {
var latte_lib = require("./lib.js");
if(!latte_lib) {
console.log("no load lib");
}
/**
* @class async
* @namespace latte_lib
* @module basic
*/
(function() {
var _self = this;
this.setImmediate = latte_lib.setImmediate;
/**
* 单次执行
* @method only_once
* @static
* @param {function} fn 只执行一次的函数
* @public
* @async
* @since 0.0.1
* @example
var async = require("latte_lib").async;
var f = async.only_once(function(data) {
log(data);
});
f("a");
f("b");
//"a"
//error callback was already called.
*/
var only_once = this.only_once = function(fn) {
var called = false;
return function() {
if (called) throw new Error("Callback was already called.");
called = true;
fn.apply(_self, arguments);
}
};
/**
* 并行执行
* @method forEach
* @static
* @param arr {array} 需要被执行函数的数组
* @param iterator {function} 执行函数
* @param callback {function} 回调函数
* @async
* @since 0.0.1
* @example
var async = require("latte_lib").async;
var result = [];
async.forEach([1,2,3,4], function(data, callback) {
if(data == 3) {
callback("is 3");
}else{
result.push(data * 2);
callback();
}
}, function(err, data) {
log(err); //is 3
log(result);// [2,4]
});
var result2 = [];
async.forEach([1,2,3,4], function(data, callback) {
if(data == 3) {
setTimeout(function() {
callback("is 3");
}, 1);
}else{
result2.push(data * 2);
callback();
}
}, function(err, data) {
log(err); //is 3
log(result2);// [2,4,8]
});
*
*/
this.forEach = this.each = function(arr, iterator, callback) {
callback = callback || function(){};
if(!arr.length) {
return callback();
}
var completed = 0;
latte_lib.forEach(arr, function (x) {
iterator(x, only_once(done) );
});
function done(err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed >= arr.length) {
callback();
}
}
}
};
/**
串行执行
@method forEachSeries
@static
@param arr {array} 需要被执行函数的数组
@param iterator {function} 执行函数
@param callback {function} 回调函数
@sync
@since 0.0.1
@example
var async = require("latte_lib").async;
var result = [];
async.forEachSeries([1,2,3,4], function(data, callback) {
if(data == 3) {
callback("is 3");
}else{
result.push(data * 2);
callback();
}
}, function(err, data) {
log(err); //is 3
log(result);// [2,4]
});
var result2 = [];
async.forEachSeries([1,2,3,4], function(data, callback) {
if(data == 3) {
setTimeout(function() {
callback("is 3");
}, 1);
}else{
result2.push(data * 2);
callback();
}
}, function(err, data) {
log(err); //is 3
log(result2);// [2,4,8]
});
*/
this.forEachSeries = this.eachSeries = function(arr, iterator, callback) {
callback = callback || function() {};
if (!arr.length) {
return callback();
}
var completed = 0;
(function iterate() {
iterator(arr[completed], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
if (completed >= arr.length) {
callback();
}
else {
iterate();
}
}
});
})();
};
this.forEachLimit = this.eachLimit = function(arr, limit, iterator, callback) {
var fn = _eachLimit(limit);
fn.apply(null, [arr, iterator, callback]);
};
var _eachLimit = function(limit) {
return function(arr, iterator, callback) {
callback = callback || function() {};
if (!arr.length || limit <= 0) {
return callback();
}
var completed = 0;
var started = 0;
var running = 0;
(function replenish () {
if (completed >= arr.length) {
return callback();
}
while (running < limit && started < arr.length) {
started += 1;
running += 1;
iterator(arr[started - 1], function (err) {
if (err) {
callback(err);
callback = function () {};
}
else {
completed += 1;
running -= 1;
if (completed >= arr.length) {
callback();
}
else {
replenish();
}
}
});
}
})();
};
};
var doParallel = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [_self.each].concat(args));
};
};
var doParallelLimit = function(limit, fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [_eachLimit(limit)].concat(args));
};
};
var doSeries = function (fn) {
return function () {
var args = Array.prototype.slice.call(arguments);
return fn.apply(null, [_self.eachSeries].concat(args));
};
};
var _asyncMap = function(eachfn, arr, iterator, callback) {
arr = latte_lib.map(arr, function(x, i) {
return {
index: i,
value: x
};
});
if (!callback) {
eachfn(arr, function (x, callback) {
iterator(x.value, function (err) {
callback(err);
});
});
} else {
var results = [];
eachfn(arr, function (x, callback) {
iterator(x.value, function (err, v) {
results[x.index] = v;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
this.map = doParallel(_asyncMap);
this.mapSeries = doSeries(_asyncMap);
var _mapLimit = function(limit) {
return doParallelLimit(limit, _asyncMap);
};
this.mapLimit = function(arr, limit, iterator, callback) {
return _mapLimit(limit)(arr, iterator, callback);
};
this.inject = this.foldl = this.reduce = function(arr, memo, iterator, callback) {
_self.eachSeries(arr, function(x, callback) {
iterator(memo, x, function (err, v) {
memo = v;
callback(err);
});
}, function (err) {
callback(err, memo);
});
};
this.foldr = this.reduceRight = function (arr, memo, iterator, callback) {
var reversed = latte_lib.map(arr, function (x) {
return x;
}).reverse();
_self.reduce(reversed, memo, iterator, callback);
};
var _filter = function (eachfn, arr, iterator, callback) {
var results = [];
arr = latte_lib.map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(latte_lib.map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
this.select = this.filter = doParallel(_filter);
this.selectSeries = this.filterSeries = doSeries(_filter);
var _reject = function (eachfn, arr, iterator, callback) {
var results = [];
arr = latte_lib.map(arr, function (x, i) {
return {index: i, value: x};
});
eachfn(arr, function (x, callback) {
iterator(x.value, function (v) {
if (!v) {
results.push(x);
}
callback();
});
}, function (err) {
callback(latte_lib.map(results.sort(function (a, b) {
return a.index - b.index;
}), function (x) {
return x.value;
}));
});
};
this.reject = doParallel(_reject);
this.rejectSeries = doSeries(_reject);
var _detect = function (eachfn, arr, iterator, main_callback) {
eachfn(arr, function (x, callback) {
iterator(x, function (result) {
if (result) {
main_callback(x);
main_callback = function () {};
}
else {
callback();
}
});
}, function (err) {
main_callback();
});
};
this.detect = doParallel(_detect);
this.detectSeries = doSeries(_detect);
this.any = this.some = function(arr, iterator, main_callback) {
_self.each(arr, function (x, callback) {
iterator(x, function (v) {
if (v) {
main_callback(true);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(false);
});
};
this.all = this.every = function (arr, iterator, main_callback) {
_self.each(arr, function (x, callback) {
iterator(x, function (v) {
if (!v) {
main_callback(false);
main_callback = function () {};
}
callback();
});
}, function (err) {
main_callback(true);
});
};
this.sortBy = function (arr, iterator, callback) {
_self.map(arr, function (x, callback) {
iterator(x, function (err, criteria) {
if (err) {
callback(err);
}
else {
callback(null, {value: x, criteria: criteria});
}
});
}, function (err, results) {
if (err) {
return callback(err);
}
else {
var fn = function (left, right) {
var a = left.criteria, b = right.criteria;
return a < b ? -1 : a > b ? 1 : 0;
};
callback(null, latte_lib.map(results.sort(fn), function (x) {
return x.value;
}));
}
});
};
/**
自动 并行 如果有依赖的话等依赖好了在执行
@method auto
@static
@param {json} tasks
@param {function} callback
@async
@since 0.0.1
@example
var async = require("latte_lib").async;
async.auto({
a: ["c",function(callback) {
log("a");
callback(null,3);
}],
b: function(callback) {
log("b");
callback(null, 1);
},
c: function(callback) {
log("c");
callback(null, 2);
},
d: ["a", function(callback) {
log("d");
callback(null, 4);
}]
}, function(err, results) {
log("err:",err);
log("results:", results);// {"b":1,"c":2,"a":3,"d":4}
});
async.auto({
a: ["c",function(callback) {
log("a");
callback("is 3", 3);
}],
b: function(callback) {
log("b");
callback(null, 1);
},
c: function(callback) {
log("c");
callback(null, 2);
},
d: ["a", function(callback) {
log("d");
callback(null, 4);
}]
}, function(err, results) {
log("err:",err); // is 3
log("results:", results);// {"b":1,"c":2, "a":3}
});
*/
this.auto = function (tasks, callback) {
callback = callback || function () {};
var keys = latte_lib.keys(tasks);
var remainingTasks = keys.length
if (!remainingTasks) {
return callback();
}
var results = {};
var listeners = [];
var addListener = function (fn) {
listeners.unshift(fn);
};
var removeListener = function (fn) {
for (var i = 0; i < listeners.length; i += 1) {
if (listeners[i] === fn) {
listeners.splice(i, 1);
return;
}
}
};
var taskComplete = function () {
remainingTasks--
latte_lib.forEach(listeners.slice(0), function (fn) {
fn();
});
};
addListener(function () {
if (!remainingTasks) {
var theCallback = callback;
// prevent final callback from calling itself if it errors
callback = function () {};
theCallback(null, results);
}
});
latte_lib.forEach(keys, function (k) {
var task = latte_lib.isArray(tasks[k]) ? tasks[k]: [tasks[k]];
var taskCallback = function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
if (err) {
var safeResults = {};
latte_lib.forEach(latte_lib.keys(results), function(rkey) {
safeResults[rkey] = results[rkey];
});
safeResults[k] = args;
callback(err, safeResults);
// stop subsequent errors hitting callback multiple times
callback = function () {};
}
else {
results[k] = args;
latte_lib.setImmediate(taskComplete);
}
};
var requires = task.slice(0, Math.abs(task.length - 1)) || [];
var ready = function () {
return latte_lib.reduce(requires, function (a, x) {
return (a && results.hasOwnProperty(x));
}, true) && !results.hasOwnProperty(k);
};
if (ready()) {
task[task.length - 1](taskCallback, results);
}
else {
var listener = function () {
if (ready()) {
removeListener(listener);
task[task.length - 1](taskCallback, results);
}
};
addListener(listener);
}
});
};
this.retry = function(times, task, callback) {
var DEFAULT_TIMES = 5;
var attempts = [];
// Use defaults if times not passed
if (typeof times === 'function') {
callback = task;
task = times;
times = DEFAULT_TIMES;
}
// Make sure times is a number
times = parseInt(times, 10) || DEFAULT_TIMES;
var wrappedTask = function(wrappedCallback, wrappedResults) {
var retryAttempt = function(task, finalAttempt) {
return function(seriesCallback) {
task(function(err, result){
seriesCallback(!err || finalAttempt, {err: err, result: result});
}, wrappedResults);
};
};
while (times) {
attempts.push(retryAttempt(task, !(times-=1)));
}
_self.series(attempts, function(done, data){
data = data[data.length - 1];
(wrappedCallback || callback)(data.err, data.result);
});
}
// If a callback is passed, run this as a controll flow
return callback ? wrappedTask() : wrappedTask
};
this.waterfall = function (tasks, callback) {
callback = callback || function () {};
if (!latte_lib.isArray(tasks)) {
var err = new Error('First argument to waterfall must be an array of functions');
return callback(err);
}
if (!tasks.length) {
return callback();
}
var wrapIterator = function (iterator) {
return function (err) {
if (err) {
callback.apply(null, arguments);
callback = function () {};
}
else {
var args = Array.prototype.slice.call(arguments, 1);
var next = iterator.next();
if (next) {
args.push(wrapIterator(next));
}
else {
args.push(callback);
}
latte_lib.setImmediate(function () {
iterator.apply(null, args);
});
}
};
};
wrapIterator(_self.iterator(tasks))();
};
var _parallel = function(eachfn, tasks, callback) {
callback = callback || function () {};
if (latte_lib.isArray(tasks)) {
eachfn.map(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
eachfn.each(latte_lib.keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
/**
并行
@method parallel
@async
@param {function[]} tasks
@param {function} callback
@example
var async = require("latte_lib").async;
async.parallel([
function(cb) {
cb(null, 1);
},
function(cb) {
setTimeout(function() {
cb("is 2");
}, 1);
},
function(cb) {
cb(null, 3);
}
],function(err, result) {
log(err); //is 2
log(result);//[1,null,3]
});
*/
this.parallel = function (tasks, callback) {
_parallel({ map: _self.map, each: _self.each }, tasks, callback);
};
this.parallelLimit = function(tasks, limit, callback) {
_parallel({ map: _mapLimit(limit), each: _eachLimit(limit) }, tasks, callback);
};
/**
@method series
@async
@param {function[]} tasks
@param {function} callback
@example
var async = require("latte_lib").async;
async.series([
function(cb) {
cb(null, 1);
},
function(cb) {
setTimeout(function() {
cb("is 2");
}, 1);
},
function(cb) {
cb(null, 3);
}
],function(err, result) {
log(err); //is 2
log(result);//[1,null]
});
*/
this.series = function (tasks, callback) {
callback = callback || function () {};
if (latte_lib.isArray(tasks)) {
_self.mapSeries(tasks, function (fn, callback) {
if (fn) {
fn(function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
callback.call(null, err, args);
});
}
}, callback);
}
else {
var results = {};
_self.eachSeries(_keys(tasks), function (k, callback) {
tasks[k](function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (args.length <= 1) {
args = args[0];
}
results[k] = args;
callback(err);
});
}, function (err) {
callback(err, results);
});
}
};
this.iterator = function (tasks) {
var makeCallback = function (index) {
var fn = function () {
if (tasks.length) {
tasks[index].apply(null, arguments);
}
return fn.next();
};
fn.next = function () {
return (index < tasks.length - 1) ? makeCallback(index + 1): null;
};
return fn;
};
return makeCallback(0);
};
this.apply = function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
return function () {
return fn.apply(
null, args.concat(Array.prototype.slice.call(arguments))
);
};
};
var _concat = function (eachfn, arr, fn, callback) {
var r = [];
eachfn(arr, function (x, cb) {
fn(x, function (err, y) {
r = r.concat(y || []);
cb(err);
});
}, function (err) {
callback(err, r);
});
};
this.concat = doParallel(_concat);
this.concatSeries = doSeries(_concat);
this.whilst = function (test, iterator, callback) {
if (test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
_self.whilst(test, iterator, callback);
});
}
else {
callback();
}
};
this.doWhilst = function (iterator, test, callback) {
iterator(function (err) {
if (err) {
return callback(err);
}
var args = Array.prototype.slice.call(arguments, 1);
if (test.apply(null, args)) {
_self.doWhilst(iterator, test, callback);
}
else {
callback();
}
});
};
this.until = function(test, iterator, callback) {
if (!test()) {
iterator(function (err) {
if (err) {
return callback(err);
}
_self.until(test, iterator, callback);
});
}
else {
callback();
}
};
this.doUntil = function (iterator, test, callback) {
iterator(function (err) {
if (err) {
return callback(err);
}
var args = Array.prototype.slice.call(arguments, 1);
if (!test.apply(null, args)) {
_self.doUntil(iterator, test, callback);
}
else {
callback();
}
});
};
this.queue = function (worker, concurrency) {
if (concurrency === undefined) {
concurrency = 1;
}
function _insert(q, data, pos, callback) {
if (!q.started){
q.started = true;
}
if (!_isArray(data)) {
data = [data];
}
if(data.length == 0) {
// call drain immediately if there are no tasks
return latte_lib.setImmediate(function() {
if (q.drain) {
q.drain();
}
});
}
latte_lib.forEach(data, function(task) {
var item = {
data: task,
callback: typeof callback === 'function' ? callback : null
};
if (pos) {
q.tasks.unshift(item);
} else {
q.tasks.push(item);
}
if (q.saturated && q.tasks.length === q.concurrency) {
q.saturated();
}
latte_lib.setImmediate(q.process);
});
}
var workers = 0;
var q = {
tasks: [],
concurrency: concurrency,
saturated: null,
empty: null,
drain: null,
started: false,
paused: false,
push: function (data, callback) {
_insert(q, data, false, callback);
},
kill: function () {
q.drain = null;
q.tasks = [];
},
unshift: function (data, callback) {
_insert(q, data, true, callback);
},
process: function () {
if (!q.paused && workers < q.concurrency && q.tasks.length) {
var task = q.tasks.shift();
if (q.empty && q.tasks.length === 0) {
q.empty();
}
workers += 1;
var next = function () {
workers -= 1;
if (task.callback) {
task.callback.apply(task, arguments);
}
if (q.drain && q.tasks.length + workers === 0) {
q.drain();
}
q.process();
};
var cb = only_once(next);
worker(task.data, cb);
}
},
length: function () {
return q.tasks.length;
},
running: function () {
return workers;
},
idle: function() {
return q.tasks.length + workers === 0;
},
pause: function () {
if (q.paused === true) { return; }
q.paused = true;
q.process();
},
resume: function () {
if (q.paused === false) { return; }
q.paused = false;
q.process();
}
};
return q;
};
this.priorityQueue = function(worker, concurrency) {
function _compareTasks(a, b){
return a.priority - b.priority;
};
function _binarySearch(sequence, item, compare) {
var beg = -1,
end = sequence.length - 1;
while (beg < end) {
var mid = beg + ((end - beg + 1) >>> 1);
if (compare(item, sequence[mid]) >= 0) {
beg = mid;
} else {
end = mid - 1;
}
}
return beg;
}
function _insert(q, data, priority, callback) {
if (!q.started){
q.started = true;
}
if (!_isArray(data)) {
data = [data];
}
if(data.length == 0) {
// call drain immediately if there are no tasks
return latte_lib.setImmediate(function() {
if (q.drain) {
q.drain();
}
});
}
latte_lib.forEach(data, function(task) {
var item = {
data: task,
priority: priority,
callback: typeof callback === 'function' ? callback : null
};
q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
if (q.saturated && q.tasks.length === q.concurrency) {
q.saturated();
}
latte_lib.setImmediate(q.process);
});
}
// Start with a normal queue
var q = _self.queue(worker, concurrency);
// Override push to accept second parameter representing priority
q.push = function (data, priority, callback) {
_insert(q, data, priority, callback);
};
// Remove unshift function
delete q.unshift;
return q;
};
this.cargo = function (worker, payload) {
var working = false,
tasks = [];
var cargo = {
tasks: tasks,
payload: payload,
saturated: null,
empty: null,
drain: null,
drained: true,
push: function (data, callback) {
if (!latte_lib.isArray(data)) {
data = [data];
}
latte_lib.forEach(data, function(task) {
tasks.push({
data: task,
callback: typeof callback === 'function' ? callback : null
});
cargo.drained = false;
if (cargo.saturated && tasks.length === payload) {
cargo.saturated();
}
});
latte_lib.setImmediate(cargo.process);
},
process: function process() {
if (working) return;
if (tasks.length === 0) {
if(cargo.drain && !cargo.drained) cargo.drain();
cargo.drained = true;
return;
}
var ts = typeof payload === 'number'
? tasks.splice(0, payload)
: tasks.splice(0, tasks.length);
var ds = latte_lib.map(ts, function (task) {
return task.data;
});
if(cargo.empty) cargo.empty();
working = true;
worker(ds, function () {
working = false;
var args = arguments;
latte_lib.forEach(ts, function (data) {
if (data.callback) {
data.callback.apply(null, args);
}
});
process();
});
},
length: function () {
return tasks.length;
},
running: function () {
return working;
}
};
return cargo;
};
var _console_fn = function (name) {
return function (fn) {
var args = Array.prototype.slice.call(arguments, 1);
fn.apply(null, args.concat([function (err) {
var args = Array.prototype.slice.call(arguments, 1);
if (typeof console !== 'undefined') {
if (err) {
if (console.error) {
console.error(err);
}
}
else if (console[name]) {
latte_lib.forEach(args, function (x) {
console[name](x);
});
}
}
}]));
};
};
this.log = _console_fn('log');
this.dir = _console_fn('dir');
this.memoize = function (fn, hasher) {
var memo = {};
var queues = {};
hasher = hasher || function (x) {
return x;
};
var memoized = function () {
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
var key = hasher.apply(null, args);
if (key in memo) {
latte_lib.nextTick(function () {
callback.apply(null, memo[key]);
});
}
else if (key in queues) {
queues[key].push(callback);
}
else {
queues[key] = [callback];
fn.apply(null, args.concat([function () {
memo[key] = arguments;
var q = queues[key];
delete queues[key];
for (var i = 0, l = q.length; i < l; i++) {
q[i].apply(null, arguments);
}
}]));
}
};
memoized.memo = memo;
memoized.unmemoized = fn;
return memoized;
};
this.unmemoize = function (fn) {
return function () {
return (fn.unmemoized || fn).apply(null, arguments);
};
};
this.times = function (count, iterator, callback) {
var counter = [];
for (var i = 0; i < count; i++) {
counter.push(i);
}
return _self.map(counter, iterator, callback);
};
this.timesSeries = function (count, iterator, callback) {
var counter = [];
for (var i = 0; i < count; i++) {
counter.push(i);
}
return _self.mapSeries(counter, iterator, callback);
};
/**
@method seq
@static
@async
@param {function[]} functions
@return {function}
@since 0.0.1
@example
var async = require("latte_lib").async;
var fun = async.seq(function(a, callback) {
log("1",a);//2
callback(null, a+1, a-1);
}, function(data1, data2, callback) {
log("2",data1,data2);//3,1
callback("is 2", (data1 + data2 + 2) / (data1- data2 + 2) );
});
fun(2, function(err,b,c) {
log(err ,b,c);//is 2, 1.5
});
*/
this.seq = function (/* functions... */) {
var fns = arguments;
return function () {
var that = this;
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
_self.reduce(fns, args, function (newargs, fn, cb) {
fn.apply(that, newargs.concat([function () {
var err = arguments[0];
var nextargs = Array.prototype.slice.call(arguments, 1);
cb(err, nextargs);
}]))
},
function (err, results) {
callback.apply(that, [err].concat(results));
});
};
};
this.compose = function (/* functions... */) {
//颠倒参数
return _self.seq.apply(null, Array.prototype.reverse.call(arguments));
};
var _applyEach = function (eachfn, fns /*args...*/) {
var go = function () {
var that = this;
var args = Array.prototype.slice.call(arguments);
var callback = args.pop();
return eachfn(fns, function (fn, cb) {
fn.apply(that, args.concat([cb]));
},
callback);
};
if (arguments.length > 2) {
var args = Array.prototype.slice.call(arguments, 2);
return go.apply(this, args);
}
else {
return go;
}
};
this.applyEach = doParallel(_applyEach);
this.applyEachSeries = doSeries(_applyEach);
/**
循环执行出现错误停止
@method forever
@static
@param fn {function} 循环执行到函数
@param callback {function} 循环执行出现错误之后回调函数
@example
var async = require("latte_lib").async;
var i = 0;
async.forever(function(next) {
if(++i == 3) {
next("is 3");
}else{
log("forever", i);
next();
};
}, function(err) {
log(err);
});
*/
this.forever = function (fn, callback) {
function next(err) {
if (err) {
if (callback) {
return callback(err);
}
throw err;
}
fn(next);
}
next();
};
}).call(module.exports);
});
})(typeof define === "function"? define: function(name, reqs, factory) { factory(require, exports, module); });
(function(define) {'use strict'
define("latte_lib/basic/events.js", ["require", "exports", "module", "window"],
function(require, exports, module, window) {
var events;
var latte_lib = require("./lib.j