npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

lance

v2.10.14

Published

The alpha-strike framework

Downloads

213

Readme

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.*
       __                     
      / /___ _____  ________  
     / / __ `/ __ \/ ___/ _ \ 
    / / /_/ / / / / /__/  __/ 
   /_/\__/_/_/ /_/\___/\___/