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 = _a = _pages true ; _a;
_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 = { const i = 123; return i = 321; } { console; } { console; } { console; } ;
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