2.10.14 • Published 9 years ago

lance v2.10.14

Weekly downloads
325
License
-
Repository
github
Last release
9 years ago

Lance

The alpha-strike web framework.
A framework with sane defaults, aiming to handle everything for you as automatically as possible.

API Stability: Semi-Unstable

Minimal API

  • new Lance( config )
  • lance.initailize()

What just happened:

  • An HTTP server was started
  • Compiled, minified, bundled and watched Stylus, CoffeeScript, CJSX, CSS, JS + Saved to the static directory
  • Populated the static asset directory at ./static + Assets like img.png, robots.txt are copied over with their preserved directory structure.
  • Set up request routing
  • Began serving static assets from ./static
  • Began utlizing a templating engine in ./views
  • Began parsing http requests; forms, file transfers

All parts of Lance can be utilized outside of the config. Lance always utilizes promises for async operations.

See the ./config - effectively an API reference.

The minimal example:

Lance = require 'lance'

lance = new Lance {
	routes: [
		[ "GET", '/:api(a|b|c|d)', (o) ->
				console.log 'ayyy' if o.route.api is 'a'
				o.serve { body: 'woo!' }
		]
	]
}

lance.initialize().then -> # Server is up!

The full example:

###
The directory structure:
/project/
	/static/
	/views/
		index.jade
		style.styl
		app.coffee
		/images/
			image.png
	
	server.coffee (this)
###

Lance = require 'lance'

lance = new Lance {
	server:
		host: '0.0.0.0'
		port: 1337
		static: './static' # Automatically intercepts and serves static content
	
	templater:
		findIn: './views'
		saveTo: './static'
		
		###
		Bundle up all Stylus/Css or Coffee/Js dependencies into a single file
		by utilizing Stylus and browserify.
		###
		bundle:
			# destination	: source
			"my/css/here.css": "style.styl"
			"app.js": "app.coffee"
			
		templater:
			ext: '.jade'
			engine: require 'jade'
}

# Routes can be defined after instantiation, outside of the config, too
lance.router.get '/:api(a|b|c|d)', (o) ->
	###
	`o` is a special options object containing request information in a pre-parsed manner. `o` is passed to all route requests in place of `req` and `res`.
	
	More info on this later.
	###
	
	if o.route.api is 'a'
		console.log 'ayyy'
	
	# This will resolve to our ./project/views/index.jade file
	o.template.view = 'index'
	
	###
	o.serve() serves a response based on either arguements passed to it or depending on properties in `o`.
	
	if `o.template.view` is set, the template will be rendered
	if `o.redirect` is set, a redirection will occur
	if neither are set, Lance serves JSON by default.
	
	You may also instead call `o.serveTemplate()`, `o.serveHttpCode()`, `o.serveJson()`, `o.serveRedirect()` or a basic `o.respond()`
	###
	o.serve()
	
###
This will build the templates then start the server, all depending on the config. 
###
lance.initialize().then ->
	# we're ready

###
Alternitavely...

There is a choice between `lance.initialize()`, which initializes everything in order, and manually initializing aspects of lance for more control.
###

lance.templater.initialize().then ->
	# The bundles have been compiled to:
	#	./projectDirectory/static/style.css
	#	./projectDirectory/static/app.js
	# from the ./projectDirectory/views directory.
	# and will be watched for changes (and any of their dependencies)
	# then recompiled automatically

	lance.start().then ->
		# we're ready
		
###
The new directory structure:
/project/
	/static/
		/my/
			/css/
				here.css
		app.js
		/images/
			image.png
	/views/
		index.jade
		style.styl
		app.coffee
		/images/
			image.png
	
	server.coffee (this)
###

Requests

Requests from a http server normally use response and request parameters. Lance supplies an object as outlined below:

###
	Assuming you visited:
	GET http://yourdomain.com/b?test.a=1
###
lance.router.get '/:api(a|b|c|d)', 'aRouteName', (o) ->

	# HTTP request object
	o.req
	
	# HTTP response object
	o.res
	
	# Response HTTP code
	o.code is 200
	
	# Response headers
	o.headers is { 'content-type': 'text/html; charset=utf-8' }
	
	# Fallback body to respond with if not template is used
	o.body is ''
	
	# Sent as JSON for JSON responses
	o.json is {}
	
	# Relative or absolute path to a template
	o.template.view is ''
	
	# Local variable for the template
	o.template.data is {}
	
	# Optional lance.Templater instance
	o.template.templater is o.lance.templater
	
	# Redirects to this as a path if set
	o.redirect is ''
	
	# Used as a GET response query if redirecting
	o.redirectQuery is {}
	
	# Parsed query, whether it be GET, POST etc.
	o.query is {
		test: {
			a: '1'
		}
	}
	
	# Any files
	o.files is {
		# Example file
		'exampleFile': {
			field      : 'exampleFile'
			filename   : 'file.txt'
			encoding   : 'utf8'
			mimetype   : 'text/plain'
			ext        : 'txt'
			
			# Temporary file path, saved to the OS's temp directory
			# Will be auto deleted after a timer
			file       : tempFilePath
			
			# Call this to delete the temporary file
			delete     : [Function]
			truncated  : false
		}
	}
	
	o.method is 'GET'
	o.route is {
		path     : { api: 'b' }
		splats   : []
		name     : 'aRouteName'
		callback : [ThisFunction]
		pattern  : '/:api(a|b|c|d)'
		regex    : /./ # Final regex from pattern
	}
	
	o.path is o.route.path
	o.splats is o.route.splats
	o.cookies is new require('cookies')( o.req, o.res )
	
	# These properties above are also passed into a template, accessable under the "o" property
	
	template = { view: './someTemplate', data: { woo: 1 } }
	template is o.template
	
	o.serve template
	o.serve()
	###
		When `o.serve` is called without parameters it will execute this logic:
		
		if o.redirect
			o.serveRedirect( o.redirect, o.redirectQuery )
		else
			if o.template.view
				o.serveTemplate()
			else
				o.serveJson()
	###

Templating

You can specify your own templater middleware. If none are specified, then Lance will default to checking whether ect is installed and will use that.

# Uses Jade
new Lance {
	templater:
		templater:
			ext: '.jade'
			engine: require 'jade'
			options: {} # Supplied to the engine on instantiation
}

# Uses ECT.js if `ect` is installed
new Lance {
	templater:
		templater: {}
}

Optional modules

For these features to become avaliable, simply make sure they're installed.

  • browserify for bundling coffee/js + coffee-reactify for embedding JSX into Coffee + coffeeify only normal coffeescript
  • ect fallback templater
  • stylus
  • coffee-script
  • uglify-js for js compression
  • lactate for static file serving

Stylus

Stylus is compulsary if you're going to bundle css assets; because Stylus can exist as pure css with the benefit of the @require() and @import bundling syntax. Any plain CSS file is concatenated, it is not resolved to an @import.

Static assets

Lance handles these mostly automatically:

  • CSS and Stylus
  • CoffeeScript, CJSX and Javascript
  • Static assets such as images, json, robots.txt etc.

On initialization:

  • Bundles are rendered to the static directory
  • Bundles are watched for changes, then rerendered
  • Assets files are copied over to the static directory
  • Assets files are watched for changes, then resaved
  • Directories are watched for new directories and files

By default all static assets that match the regexp (found in the config's templater.assets.match) will be copied over to the static directory.

  • For some filetypes, such as images, this means they can also be optimized. + TODO: Impliment asset stream hooking
new Lance {
	templater:
		findIn: './views'
		saveTo: './static'
		
		###
		true by default, this causes `assets` to keep their directory structure inside the saveTo folder.
		###
		preserveDirectory: true
		
		bundle:
			# destination	: source
			"style.css"		: "style.styl"
			"app.js"		: "app.coffee"
}

The result is that the static directory will always have only what you want to make public, in one place, with a directory structure that will mirror your views.

Tests

Cloned via the github repo, tests are manual in nature at the moment. Due to the complexity of a web server, they consist of scenarios for which must be manually tested and interacted with in the browser, currently.

All dependencies have unit tests.

Upgrading from 1.x.x

  • Replacements + clone.merge.hard to clone + clone.merge to clone + slugify to format.slugify
  • Removals + toArray + helpers.promisify helpers.*
       __                     
      / /___ _____  ________  
     / / __ `/ __ \/ ___/ _ \ 
    / / /_/ / / / / /__/  __/ 
   /_/\__/_/_/ /_/\___/\___/  
   
2.10.14

9 years ago

2.10.13

9 years ago

2.10.12

9 years ago

2.10.11

9 years ago

2.10.10

9 years ago

2.10.9

9 years ago

2.10.8

9 years ago

2.10.7

9 years ago

2.10.6

9 years ago

2.10.5

9 years ago

2.10.4

9 years ago

2.10.3

9 years ago

2.10.2

9 years ago

2.10.1

9 years ago

2.10.0

9 years ago

2.9.1

9 years ago

2.9.0

9 years ago

2.8.5

9 years ago

2.8.4

9 years ago

2.8.3

9 years ago

2.8.2

9 years ago

2.8.1

9 years ago

2.8.0

9 years ago

2.7.0

9 years ago

2.6.6

9 years ago

2.6.5

9 years ago

2.6.4

9 years ago

2.6.3

9 years ago

2.6.2

9 years ago

2.6.1

9 years ago

2.6.0

9 years ago

2.5.2

9 years ago

2.5.1

9 years ago

2.5.0

9 years ago

2.4.10

9 years ago

2.4.9

9 years ago

2.4.8

9 years ago

2.4.6

9 years ago

2.4.5

9 years ago

2.4.4

9 years ago

2.4.3

9 years ago

2.4.2

9 years ago

2.4.1

9 years ago

2.4.0

9 years ago

2.3.11

9 years ago

2.3.10

9 years ago

2.3.9

9 years ago

2.3.8

9 years ago

2.3.7

9 years ago

2.3.6

9 years ago

2.3.5

9 years ago

2.3.4

9 years ago

2.3.3

9 years ago

2.3.2

9 years ago

2.3.1

9 years ago

2.3.0

9 years ago

2.2.2

9 years ago

2.2.0

9 years ago

2.1.7

9 years ago

2.1.6

9 years ago

2.1.2

9 years ago

2.1.1

9 years ago

2.1.0

9 years ago

2.0.9

9 years ago

2.0.5

9 years ago

2.0.4

9 years ago

2.0.3

9 years ago

2.0.2

9 years ago

2.0.1

9 years ago

2.0.0

9 years ago

1.48.0

9 years ago

1.44.0

9 years ago

1.41.1

9 years ago

1.41.0

9 years ago

1.40.0

9 years ago

0.29.3

10 years ago

0.29.2

10 years ago

0.29.1

10 years ago

0.29.0

10 years ago

0.26.0

10 years ago

0.24.1

10 years ago

0.24.0

10 years ago

0.22.2

10 years ago

0.22.1

10 years ago

0.20.0

10 years ago

0.17.1

10 years ago

0.17.0

10 years ago

0.16.2

11 years ago

0.15.0

11 years ago

0.14.1

11 years ago

0.13.5

11 years ago

0.13.4

11 years ago

0.12.1

11 years ago

0.12.0

11 years ago

0.11.2

11 years ago

0.11.1

11 years ago

0.11.0

11 years ago

0.9.1

11 years ago

0.8.2

11 years ago

0.8.1

11 years ago

0.8.0

11 years ago

0.7.9

11 years ago

0.7.8

11 years ago

0.7.7

11 years ago

0.7.6

11 years ago

0.7.5

11 years ago

0.7.4

11 years ago

0.7.3

11 years ago

0.7.2

11 years ago

0.7.1

11 years ago

0.7.0

11 years ago