-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9454fee
commit 64ddb54
Showing
7 changed files
with
217 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# porter-router | ||
# Porter Router | ||
|
||
A router for the Porter framework |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
|
||
class RoutePath { | ||
|
||
static forwardSlash = /\//; | ||
static startsWithColon = /^\:/; | ||
static validChars = '([a-zA-Z0-9-_~\\.%@]+)'; | ||
static matchForwardSlash = "\\/"; | ||
|
||
|
||
constructor(pattern, action) { | ||
this.action = action; | ||
this.rawPattern = pattern; | ||
this.fragments = []; | ||
this.tokens = []; | ||
this.setPattern(pattern); | ||
} | ||
|
||
setPattern(pattern){ | ||
if (pattern instanceof RegExp) { | ||
this.pattern = pattern; | ||
} else { | ||
this.pattern = this.compile(pattern); | ||
} | ||
} | ||
|
||
compile(pattern) { | ||
let parts = pattern.split(RoutePath.forwardSlash); | ||
|
||
parts.forEach((part, index) => { | ||
if (part.match(RoutePath.startsWithColon)) { | ||
this.tokens.push(part.replace(RoutePath.startsWithColon, '')); | ||
this.fragments.push(RoutePath.validChars); | ||
} else { | ||
this.fragments.push(part); | ||
} | ||
}); | ||
|
||
return this.compileRegexp(); | ||
} | ||
|
||
compileRegexp() { | ||
return new RegExp(this.fragments.join(RoutePath.matchForwardSlash) + "$"); | ||
} | ||
|
||
parseTokens(path) { | ||
// unsure why +1 | ||
let tokenLength = this.tokens.length + 1; | ||
let matches = path.match(this.pattern); | ||
if (!matches) { | ||
return []; | ||
} | ||
let values = matches.slice(1, tokenLength); | ||
return this.tokens.reduce((finalValues, token, index, tokens) => { | ||
finalValues[token] = values[index]; | ||
return finalValues; | ||
}, | ||
{} // initial finalValues | ||
); | ||
} | ||
} | ||
|
||
export default RoutePath; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
|
||
import {Channel} from "porter-client"; | ||
|
||
import {queryStringToObject} from "../utilities/helpers"; | ||
import RoutePath from "./RoutePath"; | ||
|
||
|
||
class Router { | ||
// Broadcasts {path, search, hash, error, query, tokens} | ||
constructor(channel) { | ||
if (!(channel instanceof Channel)) throw "Router: a valid channel is required."; | ||
this.channel = channel; | ||
this.routes = []; | ||
this.changeRoute = "changeRoute"; | ||
this.defaultRoute = null; | ||
window.onload = e => this.connect(); | ||
} | ||
|
||
addDefaultRoute(action) { | ||
this.defaultRoute = new RoutePath(/([\s\S])+/, action); // matches anything | ||
} | ||
|
||
addRoute(pattern, action) { | ||
this.routes.push(new RoutePath(pattern, action)); | ||
} | ||
|
||
parseHash(hash) { | ||
let parts = hash.split("?"); | ||
return { | ||
path: parts[0], | ||
search: parts[1] || null, | ||
hash: hash, | ||
}; | ||
} | ||
|
||
firstMatchingRoute(parts) { | ||
let matchingRoutes = this.routes.filter(route => { | ||
return parts.path.match(route.pattern); | ||
}); | ||
return matchingRoutes[0]; | ||
} | ||
|
||
match(hash) { | ||
let parts = this.parseHash(hash); | ||
let route = this.firstMatchingRoute(parts) | ||
let error = null; | ||
if (!route) { | ||
error = "NotFound"; | ||
route = this.defaultRoute; | ||
} | ||
return this.parseMessage(route, parts, error); | ||
} | ||
|
||
parseMessage(route, parts, error) { | ||
if (!route) { | ||
console.warn("Router: unmatched route and no default", hash); | ||
return null; | ||
} | ||
return { | ||
...parts, | ||
error: error, | ||
query: queryStringToObject(parts.search), | ||
tokens: route.parseTokens(parts.path), | ||
action: route.action, | ||
}; | ||
} | ||
|
||
updateRoute() { | ||
console.log("updating route"); | ||
let match = this.match(window.location.hash); | ||
console.log("match is", match); | ||
if (match) { | ||
console.log("route Matched", match); | ||
this.channel.publish(this.changeRoute, match); | ||
} | ||
} | ||
|
||
connect(){ | ||
window.addEventListener("hashchange", event => { | ||
console.info("hashchange", event); | ||
this.updateRoute(); | ||
}); | ||
this.updateRoute(); | ||
} | ||
} | ||
|
||
export default Router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "porter-router", | ||
"homepage": "https://github.com/agrarianlabs/porter-router#readme", | ||
"authors": [ | ||
"Jason Goldberger <[email protected]>", | ||
"Michael Christenson II <[email protected]>" | ||
], | ||
"description": "A contract for a new form of communication between front and backend tech.", | ||
"main": "index.js", | ||
"moduleType": [], | ||
"keywords": [ | ||
"porter", | ||
"connector", | ||
"channel", | ||
"plugin", | ||
"router" | ||
], | ||
"license": "MIT", | ||
"ignore": [ | ||
"**/.*", | ||
"node_modules", | ||
"bower_components", | ||
"test", | ||
"tests" | ||
], | ||
"dependencies": { | ||
"porter": "~0.8.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
export { default as Router } from './Router'; | ||
export { default as RoutePath } from './RoutePath'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "porter-router", | ||
"version": "0.1.0", | ||
"homepage": "https://github.com/agrarianlabs/porter-router#readme", | ||
"description": "A router for porter that acts as a channel to window hash changes and links hash paths to callbacks.", | ||
"keywords": [ | ||
"porter", | ||
"connector", | ||
"channel", | ||
"plugin", | ||
"router" | ||
], | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/agrarianlabs/porter-router.git" | ||
}, | ||
"contributors": [ | ||
"Jason Goldberger <[email protected]>", | ||
"Michael Christenson II <[email protected]>" | ||
], | ||
"license": "MIT", | ||
"bugs": { | ||
"url": "https://github.com/agrarianlabs/porter-router/issues" | ||
}, | ||
"dependencies": { | ||
"porter-client": "^0.11.0" | ||
} | ||
} |