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

@playframe/router

v1.0.1

Published

1kB Trie Router

Downloads

10

Readme

PlayFrame

Router

1kB Trie Router for PlayFrame

Installation

npm install --save @playframe/router

Usage

import {h, app, route, mount, Component} from '@playframe/playframe'

route({
  counter: 1,
  _: {
    inc: (e, state)=> state.counter++,
    dec: (e, state)=> state.counter--
  },
  routes: {
    '/': ({state})=> <a href="/hello/world"><h1>Link</h1></a>,
    '/counter': ({state})=> CounterView(state),
    '/hello/:name': ({state, param})=> <h1>Hello {param.name}!</h1>,
    '/*': ()=>  <h1>404</h1>
  }
})(
  mount(document.body)
)

Source

doc = @document
{isArray} = Array

NAMED = Symbol 'NAMED'
WILDCARD = Symbol 'WILD'
LEAF = Symbol 'LEAF'


forest = new WeakMap


_sync = null

_state = null
_href = null
_props = null
_Page = null
_subscribed = false

_404 = => 404
_fallback = => _Page = _404



module.exports = view = (sync)=> _sync = sync; (state, l)=>
  _state = state
  {href} = l or= location

  if not _subscribed and doc
    do subscribe
    _subscribed = true

  unless href is _href
    set_Page l

  do add_methods unless state._.push

  _props.state = state
  _Page _props


add_methods = =>
  hop = => _sync.next =>
    set_Page location
    _state._ {}
    _sync.frame => scrollTo 0, 0
    return

  _state._.push = (href)=>
    history.replaceState {height: document.body.clientHeight}, ''
    history.pushState {}, '', href
    do hop
    return

  _state._.replace = (href)=>
    history.replaceState {}, '', href
    do hop
    return
  
  return


subscribe = =>
  doc.addEventListener(
    if doc.ontouchstart then 'touchstart' else 'click'
    (event)=>
      el = event.composedPath?()[0] or event.target
      el = el.parentNode while el and el.nodeName isnt 'A'

      return if not el or event.button isnt 0 or
        event.metaKey or event.altKey or event.ctrlKey or event.shiftKey or
        el.target is '_blank' or el.origin isnt location.origin or
        el.getAttribute('href').startsWith('#')

      event.preventDefault()

      _state._.push el.href
  )


  addEventListener 'popstate', ({state})=>
    {style} = doc.body
    style.minHeight = "#{state?.height}px"
    set_Page location
    _state._ {}
    setTimeout (=> _sync.render => style.minHeight = ''), 1000
  
  return


set_Page = (l)=>
  {href, pathname, search, hash, query} = l
  _href = href
  unless query
    query = {}
    for pair, i in search.slice(1).split '&'
      [k, v] = pair.split '='
      query[k] = v

  match get_trie(_state.routes), pathname
  _props = {_props..., pathname, search, query, hash}
  return



get_trie = (routes)=>
  unless trie = forest.get routes
    forest.set routes, trie = make_trie routes
  trie



match = (trie, pathname)=>
  path = pathname.split '/'
  param = {}
  walk_trie param, trie, path, 1, _fallback



walk_trie = (param, trie, path, position, fallback)=>
  fallback = trie[WILDCARD] or fallback

  if step = path[position]
    if sub_trie = trie[step]
      walk_trie param, sub_trie, path, position + 1, fallback

    else if named = trie[NAMED]
      named param, trie, path, position,
        => fallback param, trie, path, position

    else
      fallback param, trie, path, position

  else if Page = trie[LEAF]
    _props = {param}
    _Page = Page

  else
    fallback param, trie, path, position

  return



make_trie = (routes)=>
  trie = {}
  for k, v of routes
    route = k.split '/'

    pos = 0
    if route[1]? and not route[0]
      pos = 1

    if typeof v is 'object'
      # Nested router
      Object.assign grow_trie(trie, route, pos), get_trie v

    else # function Page
      grow_trie trie, route, pos, v

  trie



grow_trie = (trie, route, position, Page)=>
  if step = route[position]
    first_char = step.charCodeAt 0
    if first_char is 58 # starts with `:`
      name = step.slice 1
      named_trie = trie[NAMED] or= (param, trie, path, position, fallback)=>
        fallback = trie[WILDCARD] or fallback
        param = {param...}
        param[name] = path[position]
        walk_trie param, named_trie, path, position + 1, fallback
        return

      grow_trie named_trie, route, position + 1, Page

    else if first_char is 42 # starts with `*`
      trie[WILDCARD] = (param, trie, path, position)=>
        wild = path.slice position
        _props = {param, wild}
        _Page = Page
        return

      trie

    else
      grow_trie (trie[step] or= {}), route, position + 1, Page

  else
    trie[LEAF] = Page if Page

    trie