Adding empty derby project

This commit is contained in:
Tyler Renelle
2012-04-26 22:03:01 -04:00
parent c47368714d
commit 2f8b80b74e
13 changed files with 303 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
.DS_Store
public/gen
node_modules
*.swp

1
README.md Normal file
View File

@@ -0,0 +1 @@
# first-project

83
lib/app/index.js Normal file
View File

@@ -0,0 +1,83 @@
var app = require('derby').createApp(module)
, get = app.get
, view = app.view
, ready = app.ready
, start
// ROUTES //
start = +new Date()
// Derby routes can be rendered on the client and the server
get('/:roomName?', function(page, model, params) {
var roomName = params.roomName || 'home'
// Subscribes the model to any updates on this room's object. Calls back
// with a scoped model equivalent to:
// room = model.at('rooms.' + roomName)
model.subscribe('rooms.' + roomName, function(err, room) {
model.ref('_room', room)
// setNull will set a value if the object is currently null or undefined
room.setNull('welcome', 'Welcome to ' + roomName + '!')
room.incr('visits')
// This value is set for when the page initially renders
model.set('_timer', '0.0')
// Reset the counter when visiting a new route client-side
start = +new Date()
// Render will use the model data as well as an optional context object
page.render({
roomName: roomName
, randomUrl: parseInt(Math.random() * 1e9).toString(36)
})
})
})
// CONTROLLER FUNCTIONS //
ready(function(model) {
var timer
// Expose the model as a global variable in the browser. This is fun in
// development, but it should be removed when writing an app
window.model = model
// Exported functions are exposed as a global in the browser with the same
// name as the module that includes Derby. They can also be bound to DOM
// events using the "x-bind" attribute in a template.
exports.stop = function() {
// Any path name that starts with an underscore is private to the current
// client. Nothing set under a private path is synced back to the server.
model.set('_stopped', true)
clearInterval(timer)
}
exports.start = function() {
model.set('_stopped', false)
timer = setInterval(function() {
model.set('_timer', (((+new Date()) - start) / 1000).toFixed(1))
}, 100)
}
exports.start()
model.set('_showReconnect', true)
exports.connect = function() {
// Hide the reconnect link for a second after clicking it
model.set('_showReconnect', false)
setTimeout(function() {
model.set('_showReconnect', true)
}, 1000)
model.socket.socket.connect()
}
exports.reload = function() {
window.location.reload()
}
})

53
lib/server/index.js Normal file
View File

@@ -0,0 +1,53 @@
var http = require('http')
, path = require('path')
, express = require('express')
, gzippo = require('gzippo')
, derby = require('derby')
, app = require('../app')
, serverError = require('./serverError')
// SERVER CONFIGURATION //
var ONE_YEAR = 1000 * 60 * 60 * 24 * 365
, root = path.dirname(path.dirname(__dirname))
, publicPath = path.join(root, 'public')
, expressApp, server, store
;(expressApp = express())
.use(express.favicon())
// Gzip static files and serve from memory
.use(gzippo.staticGzip(publicPath, {maxAge: ONE_YEAR}))
// Gzip dynamically rendered content
.use(express.compress())
// Uncomment to add form data parsing support
// .use(express.bodyParser())
// .use(express.methodOverride())
// Derby session middleware creates req.model and subscribes to _session
// .use(express.cookieParser('secret_sauce'))
// .use(express.session({
// cookie: {maxAge: ONE_YEAR}
// })
// .use(app.session())
// The router method creates an express middleware from the app's routes
.use(app.router())
.use(expressApp.router)
.use(serverError(root))
module.exports = server = http.createServer(expressApp)
// SERVER ONLY ROUTES //
expressApp.all('*', function(req) {
throw '404: ' + req.url
})
// STORE SETUP //
store = app.createStore({listen: server})

21
lib/server/serverError.js Normal file
View File

@@ -0,0 +1,21 @@
var derby = require('derby')
, isProduction = derby.util.isProduction
module.exports = function(root) {
var staticPages = derby.createStatic(root)
return function(err, req, res, next) {
if (err == null) return next()
console.log(err.stack ? err.stack : err)
// Customize error handling here
var message = err.message || err.toString()
, status = parseInt(message)
if (status === 404) {
staticPages.render('404', res, {url: req.url}, 404)
} else {
res.send( ((status >= 400) && (status < 600)) ? status : 500)
}
}
}

12
package.json Normal file
View File

@@ -0,0 +1,12 @@
{
"name": "first-project",
"description": "",
"version": "0.0.0",
"main": "./server.js",
"dependencies": {
"derby": "*",
"express": "3.x",
"gzippo": ">=0.1.4"
},
"private": true
}

1
server.js Normal file
View File

@@ -0,0 +1 @@
require('derby').run(__dirname + '/lib/server')

1
styles/404.styl Normal file
View File

@@ -0,0 +1 @@
@import "./base";

20
styles/app/index.styl Normal file
View File

@@ -0,0 +1,20 @@
@import "../base";
#alert {
position: absolute;
text-align: center;
top: 0;
left: 0;
width: 100%;
height: 0;
z-index: 99;
}
#alert > p {
background: #fff1a8;
border: 1px solid #999;
border-top: 0;
border-radius: 0 0 3px 3px;
display: inline-block;
line-height: 21px;
padding: 0 12px;
}

13
styles/base.styl Normal file
View File

@@ -0,0 +1,13 @@
@import "./reset";
@import "nib/vendor";
body {
padding: 2em;
}
h1 {
font-size: 2em;
margin-bottom: .5em;
}
p {
line-height: 2em;
}

21
styles/reset.styl Normal file
View File

@@ -0,0 +1,21 @@
body,h1,h2,h3,h4,th {
font: 13px/normal Arial,sans-serif;
}
body {
background: #fff;
color: #000;
}
body,fieldset,form,h1,h2,h3,h4,li,ol,p,td,th,ul {
margin: 0;
padding: 0;
}
ul {
margin: 0 normal;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
fieldset,img {
border: 0;
}

16
views/404.html Normal file
View File

@@ -0,0 +1,16 @@
<!--
This is a static template file, so it doesn't have an associated app.
It is rendered by the server via a staticPages renderer.
Since static pages don't include the Derby client library, they can't have
bound variables that automatically update. However, they do support initial
template tag rendering from a context object and/or model.
-->
<Title:>
Not found
<Body:>
<h1>404</h1>
<p>Sorry, we can't find anything at <b>{{url}}</b>.
<p>Try heading back to the <a href="/">home page</a>.

57
views/app/index.html Normal file
View File

@@ -0,0 +1,57 @@
<!--
Derby templates are similar to Handlebars, except that they are first
parsed as HTML, and there are a few extensions to make them work directly
with models. A single HTML template defines the HTML output, the event
handlers that update the model after user interaction, and the event handlers
that update the DOM when the model changes.
As in Handlebars, double curly braces output a value literally. Derby
templates add single curly braces, which output a value and set up
model <- -> view bindings for that object.
Elements that end in colon define template names. Pre-defined templates
are capitalized by convention, but template names are case-insensitive.
Pre-defined templates are automatically included when the page is rendered.
-->
<Title:>
{{roomName}} - {_room.visits} visits
<Header:>
<!-- Other templates are referenced like custom HTML elements -->
<app:alert>
<Body:>
<h1>{_room.welcome}</h1>
<p><label>Welcome message: <input value="{_room.welcome}"></label></p>
<p>This page has been visted {_room.visits} times. <app:timer></p>
<p>Let's go <a href="/{{randomUrl}}">somewhere random</a>.</p>
<timer:>
{#if _stopped}
<a x-bind="click:start">Start timer</a>
{else}
You have been here for {_timer} seconds. <a x-bind="click:stop">Stop</a>
{/}
<!--
connected and canConnect are built-in properties of model. If a variable
is not defined in the current context, it will be looked up in the model
data and the model properties
-->
<alert:>
<div id="alert">
{#unless connected}
<p>
{#if canConnect}
<!-- Leading space is removed, and trailing space is maintained -->
Offline
{#if _showReconnect}&ndash; <a x-bind="click:connect">Reconnect</a>{/}
{else}
Unable to reconnect &ndash; <a x-bind="click:reload">Reload</a>
{/}
</p>
{/}
</div>