{
  "author": {
    "name": "mklabs"
  },
  "name": "tiny-lr",
  "description": "Tiny LiveReload server, background-friendly",
  "version": "0.0.4",
  "homepage": "https://github.com/mklabs/tiny-lr",
  "repository": {
    "url": "git://github.com/mklabs/tiny-lr.git"
  },
  "bin": {
    "tiny-lr": "./bin/tiny-lr"
  },
  "main": "./lib",
  "scripts": {
    "prepublish:": "npm test",
    "test": "mocha --reporter list",
    "test-debug": "DEBUG=tinylr:* mocha --reporter list",
    "test-debug-all": "DEBUG=* mocha --reporter list"
  },
  "dependencies": {
    "qs": "~0.5.2",
    "faye-websocket": "~0.4.3",
    "noptify": "latest",
    "debug": "~0.7.0"
  },
  "devDependencies": {
    "mocha": "~1.7.1",
    "request": "~2.12.0",
    "supertest": "~0.4.2",
    "express": "~3.0.6",
    "connect": "~2.7.2"
  },
  "config": {
    "test_port": "9001"
  },
  "readme": "tiny-lr\n-------\n\nThis script manages a tiny [LiveReload](http://livereload.com/) server\nimplementation you can spawn in the background.\n\nIt exposes:\n\n- a background-friendly bin wrapper (thanks to\n  [@FGRibreau](https://github.com/FGRibreau) [pid.js\n  gist](https://gist.github.com/1846952))\n\n- [Grunt tasks](https://github.com/mklabs/tiny-lr#using-grunt) to start the server and trigger reload notification. Every task\n  name is prefixed by `tinylr-`.\n\n- [Generic targets](https://github.com/mklabs/tiny-lr#using-make) to include in\n  your Makefile (`include node_modules/tiny-lr/tasks/tiny-lr.mk`)\n\nIt doesn't have any watch ability, it must be done at the build process or\napplication level.\n\nInstead, it exposes a very simple API to notify the server that some\nchanges have been made, that is then broadcasted to every livereload client\nconnected.\n\n    # notify a single change\n    curl http://localhost:35729/changed?files=style.css\n\n    # notify using a longer path\n    curl http://localhost:35729/changed?files=js/app.js\n\n    # notify multiple changes, comma or space delimited\n    curl http://localhost:35729/changed?files=index.html,style.css,docs/docco.css\n\nOr you can bulk the information into a POST request, with body as a JSON array of files.\n\n    curl -X POST http://localhost:35729/changed -d '{ \"files\": [\"style.css\", \"app.js\"] }'\n\nAs for the livereload client, you need to install the browser extension:\nhttp://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions-\n(**note**: you need to listen on port 35729 to be able to use with your\nbrower extension)\n\nor add the livereload script tag manually:\nhttp://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually-\n(and here you can choose whatever port you want)\n\n## Integration\n\nThis package exposes a `bin` you can decide to install globally, but it's not recommended.\n\n    tiny-lr --help\n\n    Usage: tiny-lr [options]\n\n    Options:\n      -h, --help        - Show help usage\n      -v, --version     - Show package version\n      -p, --port        - Port to listen on (default: 35729)\n      --pid             - Path to the generated PID file (default: ./tiny-lr.pid)\n\n\nThe best way to integrate the runner in your workflow is to add it as a `reload`\nstep within your build tool. This build tool can then use the internal binary\nlinked by npm in `node_modules/.bin/tiny-lr` to not rely on global installs (or\nuse the server programmtically).\n\nYou can start the server using the binary provided, or use your own start script.\n\n```js\nvar tinylr = require('tiny-lr');\n\n// standard LiveReload port\nvar port = 35729;\n\n// tinylr(opts) => new tinylr.Server(opts);\ntinylr().listen(port, function() {\n  if(err) {\n    // deal with err\n    return;\n  }\n\n  console.log('... Listening on %s (pid: %s) ...', port);\n})\n```\n\nYou can define your own route and listen for specific request:\n\n```js\nvar server = tinylr();\n\nserver.on('GET /myplace', function(req, res) {\n  res.write('Mine');\n  res.end();\n})\n```\n\nAnd stop the server manually:\n\n```js\nserver.close();\n```\n\nThis will close any websocket connection established and emit a close event.\n\n### Middleware\n\nTo use as a connect / express middleware, tiny-lr needs query /\nbodyParse middlewares prior in the stack.\n\nAny handled requests ends at the tinylr level, not found and errors are\nnexted to the rest of the stack.\n\n```js\n// This binds both express app and tinylr on the same port\nvar app = express();\napp.use(express.query())\n  .use(express.bodyParser())\n  .use(tinylr.middleware({ app: app }))\n  .use(express.static(path.resolve('./')))\n  .use(express.directory(path.resolve('./')))\n  .listen(35729, function() {\n    console.log('Listening on %d', 35729);\n  })\n```\n\nThe port you listen on is important, and tinylr should **always** listen on\nthe LiveReload standard one: `35729`. Otherwise, you won't be able to rely\non the browser extensions, though you can still use the manual snippet\napproach.\n\nYou can also start two different servers, one on your app port, the\nother listening on the LiveReload port. Check the\n`examples/express/server.js` file to see how.\n\n### Using grunt\n\nThis package exposes a `tasks/` directory, that you can use within your Gruntfile with:\n\n```js\ngrunt.loadNpmTasks('tiny-lr');\n```\n\n- tinylr-start    - Starts a new tiny-lr Server, with the provided port.\n- tinylr-reload   - Sends a reload notification to the previously started server.\n\n`tinylr-start` should be used with the `watch` task, probably with an alias\nthat triggers both `tinylr-start watch` tasks.\n\n`tinylr-reload` should be configured as a \"watch\" task in your Gruntfile.\n\n```js\ngrunt.initConfig({\n  watch: {\n    reload: {\n      files: ['**/*.html', '**/*.js', '**/*.css', '**/*.{png,jpg}'],\n      tasks: 'tinylr-reload'\n    }\n  }\n});\n\ngrunt.registerTask('reload', 'tinylr-start watch');\n```\n\n\n### Using make\n\nSee `tasks/tiny-lr.mk`.\n\nInclude this file into your project Makefile to bring in the following targets:\n\n- start \t\t\t\t\t\t- Start the LiveReload server\n- stop \t\t\t\t\t\t\t- Stops the LiveReload server\n- livereload \t\t\t\t- alias to start\n- livereload-stop \t- aias to stop\n\nThen define your \"empty\" targets, and the list of files you want to monitor.\n\n```make\nCSS_DIR = app/styles\nCSS_FILES = $(shell find $(CSS_DIR) -name '*.css')\n\n# include the livereload targets\ninclude node_modules/tiny-lr/tasks/*.mk\n\n$(CSS_DIR): $(CSS_FILES)\n  @echo CSS files changed: $?\n    @touch $@\n  curl -X POST http://localhost:35729/changed -d '{ \"files\": \"$?\" }'\n\nreload-css: livereload $(CSS_DIR)\n\n.PHONY: reload-css\n```\n\nThe pattern is always the same:\n\n- define a target for your root directory that triggers a POST request\n- `touch` the directory to update its mtime\n- add reload target with `livereload` and the list of files to \"watch\" as\n  prerequisites\n\nYou can chain multiple \"reload\" targets in a single one:\n\n```make\nreload: reload-js reload-css reload-img reload-EVERYTHING\n```\n\nCombine this with [visionmedia/watch](https://github.com/visionmedia/watch) and\nyou have a livereload environment.\n\n    watch make reload\n\n    # add a -q flag to the watch command to suppress most of the annoying output\n    watch -q reload\n\nThe `-q` flag only outputs STDERR, you can in your Makefile redirect the\noutput of your commands to `>&2` to see them in `watch -q` mode.\n\n\n## Tests\n\n    npm test\n\n---\n\n\n# TOC\n   - [tiny-lr](#tiny-lr)\n     - [GET /](#tiny-lr-get-)\n     - [GET /changed](#tiny-lr-get-changed)\n     - [POST /changed](#tiny-lr-post-changed)\n     - [GET /livereload.js](#tiny-lr-get-livereloadjs)\n     - [GET /kill](#tiny-lr-get-kill)\n<a name=\"\" />\n\n<a name=\"tiny-lr\" />\n# tiny-lr\naccepts ws clients.\n\n```js\nvar url = parse(this.request.url);\nvar server = this.app;\n\nvar ws = this.ws = new WebSocket('ws://' + url.host + '/livereload');\n\nws.onopen = function(event) {\n  var hello = {\n    command: 'hello',\n    protocols: ['http://livereload.com/protocols/official-7']\n  };\n\n  ws.send(JSON.stringify(hello));\n};\n\nws.onmessage = function(event) {\n  assert.deepEqual(event.data, JSON.stringify({\n    command: 'hello',\n    protocols: ['http://livereload.com/protocols/official-7'],\n    serverName: 'tiny-lr'\n  }));\n\n  assert.ok(Object.keys(server.clients).length);\n  done();\n};\n```\n\nproperly cleans up established connection on exit.\n\n```js\nvar ws = this.ws;\n\nws.onclose = done.bind(null, null);\n\nrequest(this.server)\n  .get('/kill')\n  .expect(200, function() {\n    console.log('server shutdown');\n  });\n```\n\n<a name=\"tiny-lr\" />\n# tiny-lr\n<a name=\"tiny-lr-get-\" />\n## GET /\nrespond with nothing, but respond.\n\n```js\nrequest(this.server)\n  .get('/')\n  .expect('Content-Type', /json/)\n  .expect('{\"tinylr\":\"Welcome\",\"version\":\"0.0.1\"}')\n  .expect(200, done);\n```\n\nunknown route respond with proper 404 and error message.\n\n```js\nrequest(this.server)\n  .get('/whatev')\n  .expect('Content-Type', /json/)\n  .expect('{\"error\":\"not_found\",\"reason\":\"no such route\"}')\n  .expect(404, done);\n```\n\n<a name=\"tiny-lr-get-changed\" />\n## GET /changed\nwith no clients, no files.\n\n```js\nrequest(this.server)\n  .get('/changed')\n  .expect('Content-Type', /json/)\n  .expect(/\"clients\":\\[\\]/)\n  .expect(/\"files\":\\[\\]/)\n  .expect(200, done);\n```\n\nwith no clients, some files.\n\n```js\nrequest(this.server)\n  .get('/changed?files=gonna.css,test.css,it.css')\n  .expect('Content-Type', /json/)\n  .expect('{\"clients\":[],\"files\":[\"gonna.css\",\"test.css\",\"it.css\"]}')\n  .expect(200, done);\n```\n\n<a name=\"tiny-lr-post-changed\" />\n## POST /changed\nwith no clients, no files.\n\n```js\nrequest(this.server)\n  .post('/changed')\n  .expect('Content-Type', /json/)\n  .expect(/\"clients\":\\[\\]/)\n  .expect(/\"files\":\\[\\]/)\n  .expect(200, done);\n```\n\nwith no clients, some files.\n\n```js\nvar data = { clients: [], files: ['cat.css', 'sed.css', 'ack.js'] };\n\nrequest(this.server)\n  .post('/changed')\n  .send({ files: data.files })\n  .expect('Content-Type', /json/)\n  .expect(JSON.stringify(data))\n  .expect(200, done);\n```\n\n<a name=\"tiny-lr-get-livereloadjs\" />\n## GET /livereload.js\nrespond with livereload script.\n\n```js\nrequest(this.server)\n  .get('/livereload.js')\n  .expect(/LiveReload/)\n  .expect(200, done);\n```\n\n<a name=\"tiny-lr-get-kill\" />\n## GET /kill\nshutdown the server.\n\n```js\nvar server = this.server;\nrequest(server)\n  .get('/kill')\n  .expect(200, function(err) {\n    if(err) return done(err);\n    assert.ok(!server._handle);\n    done();\n  });\n```\n\n---\n\n- 2013-01-21 - v0.0.4 - middleware support\n- 2013-01-20 - v0.0.3 - serve livereload from repo (#4)\n- 2013-01-12 - v0.0.2 - tasks - support for grunt 0.3.x (#1)\n- 2013-01-05 - v0.0.1 - Initial release\n",
  "readmeFilename": "readme.md",
  "_id": "tiny-lr@0.0.4",
  "dist": {
    "shasum": "15ce90c78bfda70efbec0ad13925026f54951905"
  },
  "_from": "tiny-lr@0.0.4",
  "_resolved": "https://registry.npmjs.org/tiny-lr/-/tiny-lr-0.0.4.tgz"
}
