Using coffee instead (derby new --coffee first-project)

This commit is contained in:
Tyler Renelle
2012-04-26 22:19:31 -04:00
parent 2f8b80b74e
commit 45caad3c3c
9 changed files with 142 additions and 158 deletions

1
.gitignore vendored
View File

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

2
Makefile Normal file
View File

@@ -0,0 +1,2 @@
compile:
./node_modules/coffee-script/bin/coffee -bw -o ./lib -c ./src

View File

@@ -1,83 +0,0 @@
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()
}
})

View File

@@ -1,53 +0,0 @@
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})

View File

@@ -1,21 +0,0 @@
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)
}
}
}

View File

@@ -8,5 +8,8 @@
"express": "3.x",
"gzippo": ">=0.1.4"
},
"private": true
"private": true,
"devDependencies": {
"coffee-script": ">=1.2"
}
}

66
src/app/index.coffee Normal file
View File

@@ -0,0 +1,66 @@
{get, view, ready} = require('derby').createApp module
## ROUTES ##
start = +new Date()
# Derby routes can be rendered on the client and the server
get '/:roomName?', (page, model, {roomName}) ->
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}", (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 (model) ->
timer = null
# 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 = ->
# 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
do exports.start = ->
model.set '_stopped', false
timer = setInterval ->
model.set '_timer', (((+new Date()) - start) / 1000).toFixed(1)
, 100
model.set '_showReconnect', true
exports.connect = ->
# Hide the reconnect link for a second after clicking it
model.set '_showReconnect', false
setTimeout (-> model.set '_showReconnect', true), 1000
model.socket.socket.connect()
exports.reload = -> window.location.reload()

51
src/server/index.coffee Normal file
View File

@@ -0,0 +1,51 @@
http = require 'http'
path = require 'path'
express = require 'express'
gzippo = require 'gzippo'
derby = require 'derby'
app = require '../app'
serverError = require './serverError'
## SERVER CONFIGURATION ##
ONE_YEAR = 1000 * 60 * 60 * 24 * 365
root = path.dirname path.dirname __dirname
publicPath = path.join root, 'public'
(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 '*', (req) ->
throw "404: #{req.url}"
## STORE SETUP ##
store = app.createStore listen: server

View File

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