Skip to content

Instantly share code, notes, and snippets.

@thehydroimpulse
Last active December 12, 2015 01:58
Show Gist options
  • Save thehydroimpulse/4694955 to your computer and use it in GitHub Desktop.
Save thehydroimpulse/4694955 to your computer and use it in GitHub Desktop.
adapter(key)
.type('string')
.to(function(value) { return value; })
.from(function(value) { return value; })
.type('boolean')
.type('date')
.type('datetime')
.type('time')
.type('number')
.type('integer')
.type('float')
.mixin({
/*
* ['field', 'status', 'published'] // 3 values
* ['field', 'title', 'match', /[aA]/] // 4 values
* ['field', 'createdAt', 'lte', new Date] // 4 values
*/
find: function(criteria, callback) {
var collections = this._compileCriteriaForFind(criteria);
if (collections.length > 1) {
// async iterate
var i = 0
, recordsByType = {}
, collection;
function iterate() {
// on second time around, you would append post ids to comments query,
// stuff like that.
collection = collections[i];
// collection[0] is the collection name
// collection[1] are the query conditions
this.db.collectionFor(collection[0]).find(collection[1]).toArray(function(error, records) {
i++;
if (i >= collections.length) {
callback(null, records);
} else {
// save post records so you can use them in comments record query
recordsByType[collection[0]] = records;
process.nextTick(iterate);
}
});
}
iterate();
} else {
this.db.collectionFor(collections[0][0]).find(collections[0][1]).toArray(callback);
}
callback.call(this, undefined, collections);
return this;
},
create: function(criteria, callback) {
},
update: function(criteria, callback) {
},
destroy: function(criteria, callback) {
},
save: function(criteria, callback) {
},
findOrCreate: function(criteria, callback) {
},
stream: function(criteria, callback) {
},
connect: function(callback) {
callback.call(this);
return this;
},
disconnect: function(callback) {
},
_compileCriteriaForFind: function(criteria) {
var i = 0
, n = criteria.length
, criterion
, collections = []
, collection
, conditions;
while (i < n) {
criterion = criteria[i];
switch (criterion[0]) {
case 'start':
// this is hasMany, but is ready for graph queries.
case 'incoming':
conditions = {};
collection = [criterion[1], conditions];
collections.push(collection);
break;
case 'field':
if (criterion.length === 3) {
conditions[criterion[1]] = criterion[2];
} else {
conditions[criterion[1]] || (conditions[criterion[1]] = {});
conditions[criterion[1]][criterion[2]] = criterion[3];
}
break;
}
i++;
}
return collections;
}
});
(function () {
'use strict';
var next_id, Context;
next_id = 1;
Context = function () {
this.id = next_id++;
this.invalidateBindings = [];
};
Context.current = null;
Context.prototype.onInvalidate = function(cb) {
this.invalidateBindings.push(cb);
};
Context.prototype.invalidate = function() {
var id;
for (id in this.invalidateBindings) {
if (this.invalidateBindings.hasOwnProperty(id)) {
this.invalidateBindings[id]();
}
}
};
_.extend(Context.prototype, {
run: function(cb) {
var previous = Context.current;
Context.current = this;
try {
return cb();
} finally {
Context.current = previous;
}
}
});
module.exports = Context;
}());
(function() {
var ContextSet = function() {
this._set = {};
};
ContextSet.prototype.add = function(ctx) {
if (ctx && ctx instanceof Context) {
var self = this;
if (ctx && ! (ctx.id in self._set)) {
self._set[ctx.id] = ctx;
ctx.onInvalidate(function() {
delete self._set[ctx.id];
});
}
return true;
}
return false;
};
ContextSet.prototype.addCurrentContext = function() {
var context = Context.current;
if (! context) {
return false;
}
return this.add(context);
};
ContextSet.prototype.invalidateAll = function() {
for (var id in this._set) {
this._set[id].invalidate();
}
};
module.exports = ContextSet;
}());
App.reactive(function(){
console.log("Notification Count: " + App.Notification.all().count());
});
(function() {
var reactive = function (cb) {
// Create a new context;
var context = new Context();
// When the context is invalidated, re-run the whole reactive setup:
context.onInvalidate(function(){
reactive(cb);
});
// Run the context;
context.run(function(){
cb();
});
};
module.exports = reactive;
}());
(function(){
var Session = function() {
this.keys = {};
this.deps = {};
this.keys['hello'] = "Giv";
};
Session.prototype.set = function(key, value) {
this.keys[key] = value;
var invalidateAll = function(ctx) {
ctx && ctx.invalidateAll();
};
invalidateAll(this.deps[key]);
};
Session.prototype.get = function(key) {
if (this.deps[key] != null) {
this.deps[key].addCurrentContext();
} else {
this.deps[key] = new ContextSet();
this.deps[key].addCurrentContext();
}
return this.keys[key];
};
module.exports = Session;
}());
// Client-side;
<!doctype html>
<html>
<head>
<title>Blog</title>
<script src='https://cloud.towerjs.org/tower.package.js'></script>
</head>
<body>
<script type='text/x-handlebars' id='posts'>
<ul>
{{#each post in controller}}
<li>
<a {{action show post}}>{{post.title}}</a>
</li>
{{/each}}
</ul>
</script>
<script type='text/x-handlebars' id='posts.show'>
<h2>{{title}}</h2>
<div class='content'>{{content}}</div>
</script>
<script>
var app = tower.create()
, route = app.route
, model = app.model;
route('/posts', 'posts');
route('/posts/:id', 'posts.show');
App.PostsRoute = Tower.Route.extend({
connect: function(controller, callback) {
controller.stream(callback);
},
request: function(controller, callback) {
App.reactive(function(){
controller.all(function(err, data){
render('template', data);
});
});
});
});
model('post')
.field('title', 'string')
.field('body', 'text');
app.initialize();
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment