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

rpug

v0.1.0

Published

Reactive client side pug templates.

Downloads

1

Readme

rpug - Reactive client side pug templates.

  • author: Onne Gorter
  • licence: CC0

Use pug[1] templates as a self updating virtual dom. Much like facebooks react[2].

Minimal example:

title rpug demo
script(src="node_modules/rpug/rpug_runtime.bundle.js")
p Some normal pug template
script.
  // javascript app
  var clicks = 0
  function addclick() { clicks += 1}
  // must be done before any :rpug statement
  require("rpug").context()
:rpug
  p Reactive pug template here.
  p You clicked #{clicks} times.
  button(onclick=addclick) click me!
$ npm install -g pug
$ npm install rpug jstransformer-rpug
$ pug example.pug
$ open example.html

[1] http://jade-lang.com [2] http://facebook.github.io/react/

work in progress

It works for what I use it for. But it can use some optimizations.

TODO

  • precompiled templates should nor require rpug to have loaded already
  • context.update() should schedule update, not immediately trigger one
  • optimize static properties vs dynamic properties, easy enough to do from pug
  • pass along the virtual node, so you can do things like vnode.hold(deep=false: Bool) to prevent updates for a while
  • find vnode.key faster, and postProcess faster
  • stop using node.classList, it is a horrible interface
  • optimize certain patterns, like p Hello does not need _t(p); _t("Hello"); _x();
  • optmize static parts of the tree, no need to run down a tree when we know it can only appear/disappear, never change
  • animations
  • do rpug_runtime.js, no require, no classes, as minimalist as possible

notes

Use the actual dom as a read-only source, that is perfectly fine pattern.

Event handlers are set only once. Creating closures in the template is just wasting resources, and likely will not do what you expect. To pass in extra data, place those on the dom, e.g.:

a(onclick=handler,data="somedata") test
function handler(event) {
    var data = event.target.getAttribute("data")
    // do stuff
}

Some attributes are handled specially: key, value, on*, on*-bind

  • key, specifically sets the vnode identifier, so it is unambigous when an element has moved or disappeared. The framework creates these automatically, but for lists (each, while), it is recommended to use. Otherwise the key will be its position.
  • value, on*, all attributes are set using node.setAttribute(), except for value and event handlers. Plus event handlers get wrapped to trigger updates, and set only once.
  • on*-bind, when postfixing an event handler with -bind, when it fires it will skip one update. Useful for native input elements.
input(oninput-bind=handler,value=text)
var text = "lorem ipsum"
function handler(event) {
    text = event.target.value
}