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

tiny-lr-fork

v0.0.5

Published

Tiny LiveReload server, background-friendly

Downloads

236,393

Readme

This is a fork of tiny-lr. The maintainer of tiny-lr appears to be on a hiatus and this fork takes care of lingering issues until the maintainer of tiny-lr (hopefully) returns.

Changes made:

  • Quieter, removes console.logs
  • Use WSS when livereload.js is on HTTPS
  • Normalize windows paths in livereload.js

tiny-lr

This script manages a tiny LiveReload server implementation you can spawn in the background.

It exposes:

  • a background-friendly bin wrapper (thanks to @FGRibreau pid.js gist)

  • Grunt tasks to start the server and trigger reload notification. Every task name is prefixed by tinylr-.

  • Generic targets to include in your Makefile (include node_modules/tiny-lr/tasks/tiny-lr.mk)

It doesn't have any watch ability, it must be done at the build process or application level.

Instead, it exposes a very simple API to notify the server that some changes have been made, that is then broadcasted to every livereload client connected.

# notify a single change
curl http://localhost:35729/changed?files=style.css

# notify using a longer path
curl http://localhost:35729/changed?files=js/app.js

# notify multiple changes, comma or space delimited
curl http://localhost:35729/changed?files=index.html,style.css,docs/docco.css

Or you can bulk the information into a POST request, with body as a JSON array of files.

curl -X POST http://localhost:35729/changed -d '{ "files": ["style.css", "app.js"] }'

As for the livereload client, you need to install the browser extension: http://feedback.livereload.com/knowledgebase/articles/86242-how-do-i-install-and-use-the-browser-extensions- (note: you need to listen on port 35729 to be able to use with your brower extension)

or add the livereload script tag manually: http://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually- (and here you can choose whatever port you want)

Integration

This package exposes a bin you can decide to install globally, but it's not recommended.

tiny-lr --help

Usage: tiny-lr [options]

Options:
  -h, --help        - Show help usage
  -v, --version     - Show package version
  -p, --port        - Port to listen on (default: 35729)
  --pid             - Path to the generated PID file (default: ./tiny-lr.pid)

The best way to integrate the runner in your workflow is to add it as a reload step within your build tool. This build tool can then use the internal binary linked by npm in node_modules/.bin/tiny-lr to not rely on global installs (or use the server programmtically).

You can start the server using the binary provided, or use your own start script.

var tinylr = require('tiny-lr');

// standard LiveReload port
var port = 35729;

// tinylr(opts) => new tinylr.Server(opts);
tinylr().listen(port, function() {
  if(err) {
    // deal with err
    return;
  }

  console.log('... Listening on %s (pid: %s) ...', port);
})

You can define your own route and listen for specific request:

var server = tinylr();

server.on('GET /myplace', function(req, res) {
  res.write('Mine');
  res.end();
})

And stop the server manually:

server.close();

This will close any websocket connection established and emit a close event.

Middleware

To use as a connect / express middleware, tiny-lr needs query / bodyParse middlewares prior in the stack.

Any handled requests ends at the tinylr level, not found and errors are nexted to the rest of the stack.

// This binds both express app and tinylr on the same port
var app = express();
app.use(express.query())
  .use(express.bodyParser())
  .use(tinylr.middleware({ app: app }))
  .use(express.static(path.resolve('./')))
  .use(express.directory(path.resolve('./')))
  .listen(35729, function() {
    console.log('Listening on %d', 35729);
  })

The port you listen on is important, and tinylr should always listen on the LiveReload standard one: 35729. Otherwise, you won't be able to rely on the browser extensions, though you can still use the manual snippet approach.

You can also start two different servers, one on your app port, the other listening on the LiveReload port. Check the examples/express/server.js file to see how.

Using grunt

This package exposes a tasks/ directory, that you can use within your Gruntfile with:

grunt.loadNpmTasks('tiny-lr');
  • tinylr-start - Starts a new tiny-lr Server, with the provided port.
  • tinylr-reload - Sends a reload notification to the previously started server.

tinylr-start should be used with the watch task, probably with an alias that triggers both tinylr-start watch tasks.

tinylr-reload should be configured as a "watch" task in your Gruntfile.

grunt.initConfig({
  watch: {
    reload: {
      files: ['**/*.html', '**/*.js', '**/*.css', '**/*.{png,jpg}'],
      tasks: 'tinylr-reload'
    }
  }
});

grunt.registerTask('reload', ['tinylr-start', 'watch']);

Using make

See tasks/tiny-lr.mk.

Include this file into your project Makefile to bring in the following targets:

  • start - Start the LiveReload server
  • stop - Stops the LiveReload server
  • livereload - alias to start
  • livereload-stop - aias to stop

Then define your "empty" targets, and the list of files you want to monitor.

CSS_DIR = app/styles
CSS_FILES = $(shell find $(CSS_DIR) -name '*.css')

# include the livereload targets
include node_modules/tiny-lr/tasks/*.mk

$(CSS_DIR): $(CSS_FILES)
  @echo CSS files changed: $?
    @touch $@
  curl -X POST http://localhost:35729/changed -d '{ "files": "$?" }'

reload-css: livereload $(CSS_DIR)

.PHONY: reload-css

The pattern is always the same:

  • define a target for your root directory that triggers a POST request
  • touch the directory to update its mtime
  • add reload target with livereload and the list of files to "watch" as prerequisites

You can chain multiple "reload" targets in a single one:

reload: reload-js reload-css reload-img reload-EVERYTHING

Combine this with visionmedia/watch and you have a livereload environment.

watch make reload

# add a -q flag to the watch command to suppress most of the annoying output
watch -q reload

The -q flag only outputs STDERR, you can in your Makefile redirect the output of your commands to >&2 to see them in watch -q mode.

Tests

npm test

TOC

var url = parse(this.request.url);
var server = this.app;

var ws = this.ws = new WebSocket('ws://' + url.host + '/livereload');

ws.onopen = function(event) {
  var hello = {
    command: 'hello',
    protocols: ['http://livereload.com/protocols/official-7']
  };

  ws.send(JSON.stringify(hello));
};

ws.onmessage = function(event) {
  assert.deepEqual(event.data, JSON.stringify({
    command: 'hello',
    protocols: ['http://livereload.com/protocols/official-7'],
    serverName: 'tiny-lr'
  }));

  assert.ok(Object.keys(server.clients).length);
  done();
};

properly cleans up established connection on exit.

var ws = this.ws;

ws.onclose = done.bind(null, null);

request(this.server)
  .get('/kill')
  .expect(200, function() {
    console.log('server shutdown');
  });
request(this.server)
  .get('/')
  .expect('Content-Type', /json/)
  .expect('{"tinylr":"Welcome","version":"0.0.1"}')
  .expect(200, done);

unknown route respond with proper 404 and error message.

request(this.server)
  .get('/whatev')
  .expect('Content-Type', /json/)
  .expect('{"error":"not_found","reason":"no such route"}')
  .expect(404, done);
request(this.server)
  .get('/changed')
  .expect('Content-Type', /json/)
  .expect(/"clients":\[\]/)
  .expect(/"files":\[\]/)
  .expect(200, done);

with no clients, some files.

request(this.server)
  .get('/changed?files=gonna.css,test.css,it.css')
  .expect('Content-Type', /json/)
  .expect('{"clients":[],"files":["gonna.css","test.css","it.css"]}')
  .expect(200, done);
request(this.server)
  .post('/changed')
  .expect('Content-Type', /json/)
  .expect(/"clients":\[\]/)
  .expect(/"files":\[\]/)
  .expect(200, done);

with no clients, some files.

var data = { clients: [], files: ['cat.css', 'sed.css', 'ack.js'] };

request(this.server)
  .post('/changed')
  .send({ files: data.files })
  .expect('Content-Type', /json/)
  .expect(JSON.stringify(data))
  .expect(200, done);
request(this.server)
  .get('/livereload.js')
  .expect(/LiveReload/)
  .expect(200, done);
var server = this.server;
request(server)
  .get('/kill')
  .expect(200, function(err) {
    if(err) return done(err);
    assert.ok(!server._handle);
    done();
  });

  • 2013-01-21 - v0.0.5 - PR #18 / PR #21 - https support / expose reload flags through options
  • 2013-01-21 - v0.0.4 - middleware support
  • 2013-01-20 - v0.0.3 - serve livereload from repo (#4)
  • 2013-01-12 - v0.0.2 - tasks - support for grunt 0.3.x (#1)
  • 2013-01-05 - v0.0.1 - Initial release