Comparing version 0.0.3 to 0.0.4
var ejs = require('ejs') | ||
, ajs = require('ajs') | ||
, str = '<% if (foo) { %></p><%= foo %></p><% } %>' | ||
times = 50000; | ||
, ajs = require('./index') | ||
, str = '<% if (foo) { %><p><%= foo %></p><% } %>' | ||
times = 25000; | ||
// AJS benchmark | ||
// AJS benchmark (many short) | ||
var ajs_times = times; | ||
console.log('rendering AJS ' + ajs_times + ' times'); | ||
var start = new Date; | ||
var ajsStart = new Date; | ||
(function next(i) { | ||
ajs.render(str, {filename: 'test', locals: {foo: 'bar'}}, function(result) { | ||
if(i >= ajs_times) { | ||
console.log('AJS took ' + (new Date - start) + 'ms'); | ||
console.log('AJS took ' + (new Date - ajsStart) + 'ms'); | ||
ejsTest(); | ||
@@ -19,11 +19,39 @@ } else next(++i); | ||
// EJS benchmark | ||
// EJS benchmark (many short) | ||
function ejsTest() { | ||
var ejs_times = times; | ||
console.log('rendering EJS ' + ejs_times + ' times'); | ||
var start = new Date; | ||
var ejsStart = new Date; | ||
while(ejs_times--) { | ||
ejs.render(str, { cache: true, filename: 'test', locals: { foo: 'bar' }}); | ||
} | ||
console.log('EJS took ' + (new Date - start) + 'ms'); | ||
console.log('EJS took ' + (new Date - ejsStart) + 'ms'); | ||
longTest(); | ||
} | ||
function longTest() { | ||
console.log(); | ||
var template = []; | ||
while(times--) { | ||
template.push(str); | ||
} | ||
template = template.join(''); | ||
// AJS benchmark (one very long) | ||
console.log('rendering very long AJS'); | ||
var ajsStart2 = new Date; | ||
ajs.render(template, {filename: 'test2', locals: {foo: 'bar'}}, function(result) { | ||
console.log('AJS took ' + (new Date - ajsStart2) + 'ms'); | ||
ejsLongTest(); | ||
}); | ||
// EJS benchmark (one very long) | ||
function ejsLongTest() { | ||
console.log('rendering very long EJS'); | ||
var ejsStart2 = new Date; | ||
var result = ejs.render(template, { cache: true, filename: 'test2', locals: { foo: 'bar' }}); | ||
console.log('EJS took ' + (new Date - ejsStart2) + 'ms'); | ||
} | ||
} |
@@ -1,2 +0,2 @@ | ||
// AJS 0.0.3 | ||
// AJS 0.0.4 | ||
// (c) 2011 Evan Owen, LifeKraze LLC. | ||
@@ -17,5 +17,8 @@ // AJS may be freely distributed under the MIT license. | ||
// [vm.js](vm.html) | ||
// [cache.js](cache.html) | ||
// ------------- | ||
// [template.js](template.html) | ||
// ------------- | ||
// [compiler.js](compiler.html) | ||
@@ -22,0 +25,0 @@ // ------------- |
@@ -5,3 +5,4 @@ // [« Back to Index](index.html) | ||
, path = require('path') | ||
, Compiler = require('./compiler'); | ||
, Template = require('./template') | ||
, Cache = require('./cache'); | ||
@@ -12,3 +13,3 @@ // If you need lower-level access to an AJS template, simply require it, call it | ||
require.extensions['.ajs'] = function(module, filename) { | ||
module.exports = Loader.loadSync(filename); | ||
module.exports = AJS._loadSync(filename); | ||
return module; | ||
@@ -112,8 +113,7 @@ }; | ||
opts = opts || {}; | ||
var filename = opts.filename = opts.filename ? JSON.stringify(opts.filename) : 'undefined' | ||
, compiled; | ||
if(!(compiled = Cache._store[filename])) | ||
compiled = Cache._store[filename] = new Compiler(str, opts).compile(); | ||
return compiled; | ||
var key = JSON.stringify(opts.filename + opts.bare) | ||
, template; | ||
if(!(template = Cache._store[key])) | ||
template = Cache._store[key] = new Template(str, opts); | ||
return template; | ||
} | ||
@@ -126,6 +126,6 @@ | ||
// close with the use of a callback. Note that this is not for use in practice as its | ||
// still blocking until the rendering is complete, so nothing is being flushed to the client. | ||
// still blocking the response until rendering is complete. | ||
AJS.render = function(str, opts, callback) { | ||
var buffer = []; | ||
template = AJS.compile(str, opts); | ||
var buffer = [] | ||
, template = AJS.compile(str, opts); | ||
template(opts.locals) | ||
@@ -148,3 +148,3 @@ .on('data', function(data) { | ||
var compiled | ||
var template | ||
, cache = (typeof opts.cache != 'undefined') ? opts.cache : true; | ||
@@ -161,3 +161,4 @@ | ||
try { | ||
compiled = new Compiler(source, opts).compile(); | ||
opts.filename = filename; | ||
template = new Template(source, opts); | ||
} catch(e) { | ||
@@ -167,4 +168,4 @@ e.message = "In " + filename + ", " + e.message; | ||
} | ||
Cache.set(filename, compiled); | ||
callback(null, compiled); | ||
Cache.set(filename, template); | ||
callback(null, template); | ||
}); | ||
@@ -175,7 +176,6 @@ } | ||
// The same as Loader.load, but syncronous. If an error occurs it will be thrown. | ||
AJS._loadSync = function loadSync(filename, opts) { | ||
opts = opts || {}; | ||
var compiled | ||
var template | ||
, cache = (typeof opts.cache != 'undefined') ? opts.cache : true; | ||
@@ -188,5 +188,5 @@ | ||
opts.filename = filename; | ||
compiled = new Compiler(fs.readFileSync(filename, 'utf8'), opts).compile(); | ||
Cache.set(filename, compiled); | ||
return compiled; | ||
template = new Template(fs.readFileSync(filename, 'utf8'), opts); | ||
Cache.set(filename, template); | ||
return template; | ||
} | ||
@@ -199,49 +199,2 @@ } catch(e) { | ||
// When we include templates from a running VM, we specificy the `bare` option | ||
// so the compiler doesn't wrap the template in a new VM. | ||
AJS._loadInclude = function loadInclude(filename, opts) { | ||
return AJS._loadSync(filename, {bare: true}); | ||
} | ||
// A very simple singleton memory cache to store compiled template functions for | ||
// extremely fast retrieval. We use a file's mtime (modified time) to determine | ||
// when the cache is stale and needs to be refreshed. | ||
var Cache = new (function() { | ||
this._store = {}; | ||
this.get = function(filename, callback) { | ||
var cached = this._store[filename]; | ||
if(!cached) return callback(null, null); | ||
fs.stat(filename, function(err, stat) { | ||
if(err) return callback(err); | ||
if(cached.mtime.toString() != stat.mtime.toString()) | ||
callback(null, null); | ||
else callback(null, cached.template); | ||
}); | ||
} | ||
this.getSync = function(filename) { | ||
var cached = this._store[filename]; | ||
if(!cached) return null; | ||
var stat = fs.statSync(filename); | ||
if(cached.mtime.toString() != stat.mtime.toString()) | ||
return null; | ||
else return cached.template; | ||
} | ||
this.set = function(filename, template) { | ||
var self = this; | ||
fs.stat(filename, function(err, stat) { | ||
if(stat) { | ||
self._store[filename] = { | ||
template: template | ||
, mtime: stat.mtime | ||
}; | ||
}; | ||
}); | ||
} | ||
})(); | ||
function normalizeFilename(path) { | ||
@@ -248,0 +201,0 @@ if(path.slice(-1) == '/') |
@@ -7,3 +7,2 @@ // [« Back to Index](index.html) | ||
, Parser = require('./parser') | ||
, VM = require('./vm') | ||
, Node = Parser.Node | ||
@@ -17,2 +16,3 @@ | ||
this._bareFunc = (typeof opts.bare != 'undefined') ? opts.bare : false; | ||
this._optimize = false; | ||
@@ -44,2 +44,3 @@ this._cbFunc = "__ajs.cb"; | ||
this.compiled = "var include = __ajs.inc\n" + | ||
" , render = __ajs.ren\n" + | ||
" , print = __ajs.out;\n" + | ||
@@ -56,7 +57,3 @@ "with(__locals) {\n" + | ||
if(this._bareFunc) return fn; | ||
return function(locals) { | ||
return new VM(fn, {filename: self.filename}).render(locals); | ||
}; | ||
return fn; | ||
} | ||
@@ -99,5 +96,8 @@ | ||
if (statements.length == 0) return "{}"; | ||
return "{" + this._blockStatements(this._optimizeOutputNodes(statements)).join('; ') + "}"; | ||
var statements = this._optimize ? this._optimizeOutputNodes(statements) : statements; | ||
return "{" + this._blockStatements(statements).join('; ') + "}"; | ||
}; | ||
proto[Node.STRING] = function(str) { | ||
@@ -493,2 +493,3 @@ var dq = 0, sq = 0; | ||
nextEmbed(); | ||
return newStats.length ? newStats : statements; | ||
@@ -503,3 +504,3 @@ | ||
function nextEmbed(stat) { | ||
if(binStat.children.length == 1) { | ||
if(binStat.children.length < 3) { | ||
if(stat) newStats.push(stat); | ||
@@ -506,0 +507,0 @@ return; |
{ "name" : "ajs" | ||
, "description" : "Experimental asyncronous templating in Node" | ||
, "keywords" : ["ajs", "ejs", "template", "view", "asyncronous"] | ||
, "version" : "0.0.3" | ||
, "version" : "0.0.4" | ||
, "author" : "Evan Owen <kainosnoema@gmail.com>" | ||
@@ -6,0 +6,0 @@ , "main" : "index" |
# AJS | ||
AJS is an experimental asyncronous templating language for [Node](http://nodejs.org). Currently a work in progress, but Connect middleware is functional. | ||
AJS is an experimental asyncronous templating language for [Node](http://nodejs.org). | ||
NOTE: While AJS includes Connect middleware, it's currently **NOT** compatible with the [ExpressJS](http://expressjs.com) view system due to its synchronous handling of [template engines](https://github.com/visionmedia/express/blob/master/lib/view.js#L421) and [responses](https://github.com/visionmedia/express/blob/master/lib/response.js#L115). | ||
AJS is currently **NOT** compatible with the [ExpressJS](http://expressjs.com) view system due to its syncronous handling of [template engines](https://github.com/visionmedia/express/blob/master/lib/view.js#L421) and [responses](https://github.com/visionmedia/express/blob/master/lib/response.js#L115). | ||
## Installation | ||
@@ -16,3 +16,3 @@ | ||
AJS is [Connect](http://github.com/senchalabs/connect) middleware: | ||
AJS includes [Connect](http://github.com/senchalabs/connect) middleware: | ||
@@ -19,0 +19,0 @@ ```` javascript |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
95107
23
2589
4