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

arc-router

v3.0.1

Published

A purely functional router for independently evaluating a path against a list of routes

Downloads

6,628

Readme

arc-router

A purely functional router for independently evaluating a path against a list of routes

Install

$ npm install arc-router --save

Features

  • complex route evaluation

Basic Usage

const ArcRouter = require('arc-router');

//We use the same constructor signatures as RegExp
let Journey = new ArcRouter({
    '/!wallpaper/**filePath[/]/:fileName([^\.]*\.jpg)':'wallpaper',
    '/!shared/!docs/2*filePath/#docId':'doc',
    '/!shared/!docs':'docsFolder'
});

//Example 1
const example1 = Journey.travel('/wallpaper/2016/australia/sydney/beach.jpg');
expect(example1).toEqual({
    'match':'wallpaper', //matches are reduced to an independent name assigned in the map
    'wallpaper':'wallpaper', //explicit matches still cast to their key value
    'filePath':'2016/australia/sydney', //the [/] bind modifier was used to join this recursive match
    'fileName': 'beach.jpg' //We cast fileName as the var name, and captured the matching results as the value
});

//Example 2
const example2 = Journey.travel('/shared/docs/important/contracts/123');
expect(example2).toEqual({
    'match':'doc',
    'shared':'shared',
    'docs':'docs',
    'filePath':['important','contracts'], //We did not use the bind modifier, so the recursive is cast to an array
    'docId': '123' //We used a numeric requirement. If this does not cast to numeric, it will not match
});

//Example 3: Even though this overlaps with Example 2, each path is evaluated and should return in the best match
const example2 = Journey.travel('/shared/docs');
expect(example2).toEqual({
    'match':'docsFolder',
    'shared':'shared',
    'docs':'docs'
});

//No Match 1
const falseMatch = Journey.travel('/shared/docs/fail'); 

//No Match 2
const falseMatch = Journey.travel('/shared/docs/import/contracts/string/123');

API

new ArcRouter([routeMap:Object])

Create a new ArcRouter object. Requires new, routeMap is optional in the constructor.

.setMap(routeMap:Object)

Take an object in the form of {[ROUTE]:[MATCH_NAME]} and evaluate against it

.setStripQueryParams(value:Boolean)

Sets whether or not the router should strip patterns that look like URL query params from a route being traveled. (ie ?var=1). By default set to TRUE

.setStripAnchor(value:Boolean)

Sets whether or not the router should strip patterns that look like a URL anchor from a route being traveled (ie. #someAnchor). By default set to TRUE

.setCaptureQuery(value:Boolean)

Sets whether or not query parameter like patterns should be captured, parsed and returned as part of the routeData object on return. By default set to FALSE. If set to TRUE query parameters will be appended to the routeData object as a {key:val} object under query

.setCaptureAnchor(value:Boolean)

Sets whether or not query parameter like patterns should be captured, parsed and returned as part of the routeData object on return. By default set to FALSE. If set to TRUE any value after a URL # will become the value of anchor on the RouteData object.

.travel(routeString:String)

Accept a string to travel the route map with. Travel returns a routeData object, binding variables based on the map route patterns.

Testing

npm test

Rule Explanation

! is an explicit match - format: /!stringToMatch Note: not case sensitive. stringToMatch is also used as keyName (boolean value)

+ is a Filter match - format: /+keyName(filterName) Note: requires a Filter object to be added through the AddFilter method

: is a Regex match - format: /:keyName(regExPattern) Note: regex current cannot use / anywhere in the pattern (we may handle this later on)

# is a numeric match - format: /#keyName

* is a wildcard match - format: /\*keyName

Additional modifiers:

Recursive Matching - Modifier*2

usage: !!/++/::/##/!**

Recursive states attempt to consume everything from that point until the next identifier matches.

So for example: /!wallpaper/!**filePath/:fileName([^\.]*\.jpg) would match the following route /wallpaper/vacations/australia/goldcoast/beach.jpg

In the event of recursive or multiple matching the data is stored in an array (so routeData.filePath would === [vacations,australia,goldcoast])

Multi Match - IntModifier

usage. 2* or 3+ etc

Multi states require the full number of matches to successfully match to be a match

So for example: /!file/3*namespace/!*object would match the following /file/Ocelot/Engine/Toolbox/Router.php

Binding Modifier - [BindingPattern] (must be at end of routeChunk)

usage: [/]

This is used to bind certain parts of the route back together

So for example: /!file/3*namespace[/]/!*object would still match the following /file/Ocelot/Engine/Toolbox/Router.php but RouteData->namespace() would no longer be an array, instead it would be Ocelot/Engine/Toolbox

Note:

This code was based upon ancient code, which was based upon ancient code, continually tweaked as we used it for more. It works fairly well but has some assumed bugs

Bug2: / in anything will pretty much fail. While we built a special case for the binding parameter, we still use it to split which will result in obvious failure

These bugs are all pretty fixable. / will continue to be what we split with but for regEx we could tokenize the regex the same we tokenize the binding, and then reassign