the-arbiter v0.1.6
The Arbiter
The Arbiter is a HTML routing and analytics system for front-end applications and websites. (based on ExpressJS Route handling and React-like loading - for front-end only)
The Arbiter preloads pages into memory and swaps pages into a container. This significantly decreases render time and page navigation.
Custom page-specific rendering can be done in one of three states: preRender
, onRender
, postRender
.
Installation:
npm install the-arbiter
Set up and config
Set up
If you are using gulp
in conjuction with this module, place the following code in your global.js
file.
function locationHashChanged( e ) {
if( !_a.isPageRouted( location.hash ) ) return;
if( !_a.hashToKey( location.hash ) || _a.currentPage === '' ) return;
if( _a.isPageRendered( location.hash ) ) return;
_a.load( location.hash, true, () => console.log( location.hash + ' loaded' ) );
Arbiter.onLocationHashChanged( e );
}
function pageDidChange( e ) {
locationHashChanged( e );
Arbiter.onPageDidChange( e );
}
window.onhashchange = locationHashChanged;
window.addEventListener( 'popstate', pageDidChange );
document.addEventListener( 'DOMContentLoaded', e => Arbiter.onApplicationDidAppear() );
window.onload = Arbiter.onApplicationDidLoad;
window.onbeforeunload = Arbiter.onApplicationDidUnload;
Configuration
const
_pages = {
pagePath: 'main',
mainFile: 'home',
pages: [
{
name: 'home',
title: 'Website | Home',
preload: false,
data: null,
preRender: "console.log( 'pre' )",
onRender: "console.log( 'on' )",
postRender: "console.log( 'post' )"
}
]
},
Arbiter = require( 'the-arbiter' ),
_a = new Arbiter( _pages, true );
_a.init();
_pages
is the primary variable. This can be an in-memory object, or loaded json
.
Required keys for _pages
pagePath
: (string) location of all your page filesmainFile
: (string) your "index.html" or "primary" landing page.pages
: (array) list of all pages in application
Required fields for a Page
name
: (string) the name of the filetitle
: (string) equivalent to<title>
at the top of your pages - will set the page titlepreload
: (bool) tells the application topreload
your file onApplicationDidAppear
Optional fields for a Page
data
(string) the raw HTML for your pagepreRender
(function | string) the function called before the page is loadedonRender
(function | string) the function called when the page is loadedpostRender
(function | string) the function called after the page is loaded
Application Lifecycle
onApplicationDidAppear
: called immediately when the application starts to loadonApplicationDidLoad
: called after the DOM loadsonApplicationIsReady
: called after The Arbiter finishes loading and the application is readyonPageDidChange
: called on page change (Example: back, forward, refresh)onLocationHashChanged
: called when the hyperlink hash changes (Example:#home
to#login
)onApplicationDidUnload
: called when the application starts to closeonApplicationDidDisappear
: called just before the application closesapplicationDidReceiveMemoryWarning
: called if The Monitor detects a memory issue
The Arbiter
Manages page routing, monitoring, and lifecycle.
constructor
- Arguments:
(array) pages: config object including the array of pages for the arbiter to manage
(boolean) verbose: log the Arbiter's actions
- Sets up routes, pages, and
currentPage
- Arguments:
init
- Arguments:
(function) fn: function to run on initialization
(function) globalExecution: add globally executed function
- Gets the
body
container - modify this to call anotherdiv
if you have a permanent navigation bar or something like that - Constructs the pages
- Loads the
mainFile
and callsonApplicationIsReady
- Arguments:
render
- Arguments:
(Page) page
- Calls
preRender
,onRender
, andpostRender
in their respective order - Sets
currentPage
- Sets
document.title
andlocation.hash
based onpage
object - Sends page data to the render container
- Arguments:
request
- Arguments:
(string) url
- Loads the html page - can be used to load any http page
- Arguments:
load
- Arguments:
(string) name
: name of the page(bool) render
: set render page flag(function) handler
: optional call back
- Renders a page if it is loaded into memory, otherwise,
request
's it, stores it, and then callsrender
- Responses with the
XMLHttpRequest
onreadyState 4
- Arguments:
changePage
- Arguments:
(string) hash
- Primary navigation function
- Changes page location to the desired page - notifies
Arbiter.onLocationHashChanged
- Arguments:
hashToKey
- Arguments:
(string) hash
- Removes
#
inlocation.hash
URI component and returns result
- Arguments:
hashToKey
- Arguments:
(string) hash
- Adds
#
forlocation.hash
URI component and returns result
- Arguments:
isPageRouted
- Arguments:
(string) hash
- Returns if(?) the page is routed and managed by The Arbiter
- Arguments:
isPageLoaded
- Arguments:
(string) hash
- Returns if(?) the page has been loaded into memory
- Arguments:
isPageRendered
- Arguments:
(string) hash
- Returns if(?) the page is currently rendered
- Arguments:
isPage
- Arguments:
(Page) page
- Returns if(?)
page
is an instance ofPage
- Arguments:
pageToHash
- Arguments:
(Page | string) page
- Returns
hash
of a page or string
- Arguments:
getPage
- Arguments:
(Page | string) page
- Returns a
Page
from ahash
,key
, orPage
- Arguments:
setPreRenderForPage
- Arguments:
(Page | string) page
(function) fn
- Sets the
PreRender
function for a specific page
- Arguments:
setOnRenderForPage
- Arguments:
(Page | string) page
(function) fn
- Sets the
OnRender
function for a specific page
- Arguments:
setPostRenderForPage
- Arguments:
(Page | string) page
(function) fn
- Sets the
PostRender
function for a specific page
- Arguments:
setMainFile
- Arguments:
(string) page
- Sets the
mainFile
on in-memory configuation - Example use: After a user logs in, set the main page from
login
todashboard
- Arguments:
addGlobalExecution
- Arguments:
(function) fn
- Subscribes a function to the
globalExecution
pubsub (see below)
- Arguments:
invokeGlobalExecution
- Arguments:
(ANY) event
- Publishes anything to all subscribers of
globalExecution
- Arguments:
subscribeToPage
- Arguments:
(Page | string) page
(function) fn
- Subscribes a function to a specified
Page
- Arguments:
publishForPage
- Arguments:
(Page | string) page
(AND) event
- Publishes anything to all subscribers of a specified
Page
- Arguments:
Static Methods
onApplicationDidAppear
- Called immediately when URL for website is requested
onApplicationDidLoad
- Called when DOM/
document
is ready
- Called when DOM/
onApplicationIsReady
- Called when The Arbiter is prepared
onPageDidChange
- Called on page history change
refresh
,forward
,backward
- Called on page history change
onLocationHashChanged
- Called when
location.hash
is changed
- Called when
onApplicationDidUnload
- Called when the tab is set to close or the URL changes
onApplicationDidDisappear
- Called just before the application closes
- Volatile code execution will occur, not really to be used
onApplicationDidReceiveMemoryWarning
- Called if The Monitor detects a memory issue
- Clears out large in-memory objects
Important methods/variables
globalExecution
- Global Execution is a Post-Render function or multiple functions that are run globally and have no ties to a specific page.
saveOnUnload
- Attempts to save the state of the application before fully unloading
- Returns
onApplicationDidDisappear
- if changed to return a(string)
a warning box will appear and block all code execution
The Monitor
Monitors memory, page duration, and activity.
constructor
- Arguments:
none
- Sets up monitoring
- Arguments:
analyze
- Arguments:
(string) name
- Calls
start
andstop
to handle page change requests - Checks and reports on memory usage
- Arguments:
onMemoryWarning
- Arguments:
none
- Manual override memory warning to stop the monitor from running
- Arguments:
inquiry
- Arguments:
none
- Returns the current list of page analytics
- Arguments:
start
- Arguments:
none
- Starts a "timer" for the currently rendered page
- Arguments:
stop
- Arguments: nothing
- Stops the "timer" for the currently rendered page
- Adds:
activePage
,navigatedTo
,viewTime
,viewDuration
,memoryUsage
toviews
object - Saves state of The Monitor
The Generator
Sets up a promisified generatorFunction
to contain and manage a code execution.
A contained code execution environment allows code passed in JSON to be executed without effecting other code in the window
.
generator
- Arguments:
(__generatorFunction__) gen
- Wraps a
generator
into a handled promise-like state forsuccess
anderror
handling
- Arguments:
generator.container
- Arguments:
(function) func
- Creates a container around a function so code execution is separate from the others
- Arguments:
toPromise
- Arguments:
(object) obj
- Coerces anything into a promise
- Arguments:
thunkToPromise
- Arguments:
(function) fn
- Sometimes you think a function returns or is a promise, but it's not. Sometimes you think it's a
function
but it doesn't have "arguments". - This function takes what you thunk was a promise, calls it, and sends it back as an actual promise.
- Arguments:
arrayToPromise
- Arguments:
(array) obj
- Coerces an Array into a promise
- Arguments:
objectToPromise
- Arguments:
(object) obj
- Coerces an Object into a promise
- Arguments:
isPromise
- Arguments:
(Anything) obj
- Returns if(?) it's
thenable
- Arguments:
isGenerator
- Arguments:
(Anything) obj
- Returns if(?) it's
thenable
andthrowable
because it must catch errors
- Arguments:
isGeneratorFunction
- Arguments:
(Anything) obj
- Returns if(?) an object is a
generator
- Arguments:
isObject
- Arguments:
(Anything) obj
- Returns if(?)
obj
is a realobject
- Arguments:
The Executor
Executes a string of code in a container
.
constructor
- Builds a
Generator
- Executes the string as code inside a container
- Builds a
success
- Called if things are OK
error
- Called if things aren't OK
The Librarian
// TODO: Document Librarian
Containment
Containment is a simple try-catch
function.
Surprisingly enough, it is about 93% MORE EFFICIENT to put only ONE try catch in your code and have try-catch
functions passed in... who-da-thunk?
constructor
- Arguments:
(object) flood
(function) try
function to attempt(function) error
function in the event of an error(function) finally
function called regardless of the result(function) result
function called with the result oftry
- Arguments:
getResult
- Arguments:
none
- Returns the result of a
try
OR callsresult
again
- Arguments:
getError
- Arguments:
none
- Returns the error (likely the
stackTrace
) of an attemptedtry
- Arguments:
Example use case:
const containment = new Containment( {
try: () => {
const i = 123;
return i = 321;
},
error: e => {
console.error( 'error', e );
},
finally: () => {
console.log( 'finally' );
},
result: r => {
console.log( 'result', r );
}
} );
PubSub
PubSub
is a Publish-Subscribe class to register functions to a specific event.
constructor
- Arguments:
(string) name
of "topic"(array) subscribers
List of subscribers
- Arguments:
isFunction
- Arguments:
(ANY) fn
- Returns if(?)
fn
is afunction
- Arguments:
addSubscription
- Arguments:
(function) fn
- Adds function to list of
subscribers
- Arguments:
listSubscribers
- Arguments:
none
- Returns the list of
subscribers
- Arguments:
publish
- Arguments:
(ANY) event
- Invokes all subscribed functions and passes
event
- Arguments:
CHANGELOG
v0.1.7
- Addedverbose
flag for Arbiter loggingv0.1.6
- Added Cleansing for The Librarianv0.1.5
- Bug fixesv0.1.4
- Fixed page refreshing issues on unhandled pathsv0.1.3
- Fixed a fewlocation
issuesv0.1.2
- Fixedquerystring-handling
v0.1.1
- Fixeddeep-path-handling
v0.1.0
- Added Cleansing for Polyfill -universal-browser-support
v0.0.7
- Added The Librarian - still in progressv0.0.6
- Added PubSub class for publications on eventsv0.0.5
- Added separate page classv0.0.4
- Converted from loose files to a module, added The Monitorv0.0.3
- Added Generator and Executor for string-javascript executionv0.0.2
- Removed double request issue on preloaded pagesv0.0.1
- First Commit