commit 2bef7dd2ceea199b97ca169dc0c3a20751001c9a Author: Sami Samhuri Date: Sat Oct 2 22:21:28 2010 -0700 first commit diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..c37eb40 --- /dev/null +++ b/LICENSE @@ -0,0 +1,18 @@ +Copyright 2010 Sami Samhuri. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/lib/array-ext.js b/lib/array-ext.js new file mode 100644 index 0000000..878d81a --- /dev/null +++ b/lib/array-ext.js @@ -0,0 +1,72 @@ +exports.extend = function(obj) { + ArrayExt.extend(obj) +} + +var ArrayExt = exports.ArrayExt = { + + extend: function(obj) { + Object.keys(this).forEach(function(k) { + if (k === 'extend' || obj[k]) return + var fn = this[k] + obj[k] = function() { + fn.apply(this, [this].concat([].slice.call(arguments))) + } + }) + } + +// abbrev +// assoc + + // [1,2,3,4,5].at(-1) => 5 + , at: function(a, i) { + if (i >= 0) return a[i] + return a[a.length + i] + } + + // TODO make this work for non-array objects + , compact: function(a) { + var b = [] + , i = a.length + while (i--) + if (a[i] !== null && a[i] !== undefined) b[i] = a[i] + return b + } + + , first: function(a) { return a[0] } + + // Based on underscore.js's flatten + , flatten: function(a) { + return a.reduce(function(initial, elem) { + if (elem && elem.flatten) initial = initial.concat(elem.flatten()) + else initial.push(elem) + return initial + }) + } + + , grep: function(a, regex) { + return a.filter(function(v) { return regex.match(v) }) + } + + , last: function(a) { return a[a.length-1] } + + , max: function(a) { + return a.reduce(function(max, v) { return v > max ? v : max }) + } + + , min: function(a) { + return a.reduce(function(min, v) { return v < min ? v : min }) + } + + // pack + // partition + // rassoc + + , unique: function(a) { + var b = [] + , i = 0 + , n = a.length + for (; i < n; ++i) + if (b.indexOf(a[i]) === -1) b.push(a[i]) + return b + } +} diff --git a/lib/ext.js b/lib/ext.js new file mode 100644 index 0000000..8bdf469 --- /dev/null +++ b/lib/ext.js @@ -0,0 +1,18 @@ +exports.createExt = function() { + return new Ext() +} + +var Ext = exports.Ext = function(){} +Ext.prototype = { + extend: function(obj) { + Object.keys(this).forEach(function(k) { + if (obj[k]) return // don't overwrite existing members + var fn = this[k] + obj[k] = function() { + // Like JavaScript itself functions effectively take `this` as the first param + var args = [].slice.call(arguments).shift(this) + fn.apply(null, args) + } + }) + } +} diff --git a/lib/file-ext.js b/lib/file-ext.js new file mode 100644 index 0000000..0a602a4 --- /dev/null +++ b/lib/file-ext.js @@ -0,0 +1,23 @@ +var fs = require('fs') + , LineEmitter = require('./line-emitter').LineEmitter + +exports.extend = function(obj) { + FileExt.extend(obj) +} + +var FileExt = exports.FileExt = { + + eachLine: function(f, fn, cb) { + var le = new LineEmitter(fs.createReadStream(f)) + le.on('line', fn) + le.on('end', cb) + } + + , readLines: function(f, cb) { + var lines = [] + , addLine = function(line) { + lines.push(line) + } + FileExt.eachLine(f, addLine, function() { cb(lines) }) + } +} diff --git a/lib/index.js b/lib/index.js new file mode 100644 index 0000000..4b7e729 --- /dev/null +++ b/lib/index.js @@ -0,0 +1,10 @@ +var AE = require('./array-ext') + , FE = require('./file-ext') + +module.exports = { ArrayExt: AE.ArrayExt + , FileExt: FE.FileExt + , extendNative: function() { + AE.extend(Object.getPrototypeOf(Array)) + FE.extend(require('fs')) + } + } diff --git a/lib/line-emitter.js b/lib/line-emitter.js new file mode 100644 index 0000000..12fb1fd --- /dev/null +++ b/lib/line-emitter.js @@ -0,0 +1,26 @@ +var sys = require('sys') + , EventEmitter = require('events').EventEmitter + +exports.LineEmitter = LineEmitter +function LineEmitter(stream) { + var self = this + this.buffer = '' + stream.on('data', function(chunk) { + self.buffer += chunk + process.nextTick(function() { self.checkForLine() }) + }) + stream.on('end', function() { this.emit('end') }) + stream.on('error', function(err) { this.emit('error', err) }) +} +sys.inherits(LineEmitter, EventEmitter) + +LineEmitter.prototype.checkForLine = function() { + var i = this.buffer.indexOf('\n') + , self = this + if (i === -1) return + this.emit('line', this.buffer.slice(0, i)) + this.buffer = this.buffer.slice(i + 1) + if (this.buffer.indexOf('\n') !== -1) { + process.nextTick(function() { self.checkForLine() }) + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..15af7f6 --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ "name" : "batteries" +, "description" : "A general purpose library for Node" +, "version" : "0.0.1" +, "homepage" : "http://samhuri.net/node/batteries" +, "author" : "Sami Samhuri " +, "repository" : + { "type" : "git" + , "url" : "http://github.com/samsonjs/batteries.git" + } +, "bugs" : + { "mail" : "sami.samhuri+batteries@gmail.com" + , "web" : "http://github.com/samsonjs/batteries/issues" + } +, "directories" : { "lib" : "./lib" } +, "bin" : { "node-batteries" : "./repl.js" } +, "main" : "./lib/index" +, "engines" : { "node" : ">=0.2.0" } +, "licenses" : + [ { "type" : "MIT" + , "url" : "http://github.com/samsonjs/batteries/raw/master/LICENSE" + } + ] +} \ No newline at end of file