index.js
function queryState(defaults, options) {
  options = options || {};
  var history = options.history || windowHistory(defaults, options);
  validateHistoryAPI(history);

  history.onChanged(updateQuery)

  var query = history.get() || Object.create(null);

  var api = {

    /**
     * Gets current state.
     *
     * @param {string?} keyName if present then value for this key is returned.
     * Otherwise the entire app state is returned.
     */
    get: getValue,

    /**
     * Merges current app state with new key/value.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */
    set: setValue,

    /**
     * Removes value from the query string
     */
    unset: unsetValue,

    /**
     * Similar to `set()`, but only sets value if it was not set before.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */
    setIfEmpty: setIfEmpty,

    /**
     * Releases all resources acquired by query state. After calling this method
     * no hash monitoring will happen and no more events will be fired.
     */
    dispose: dispose,

    onChange: onChange,
    offChange: offChange,

    getHistoryObject: getHistoryObject,
  }

  var eventBus = eventify({});

  return api;

  function onChange(callback, ctx) {
    eventBus.on('change', callback, ctx);
  }

  function offChange(callback, ctx) {
    eventBus.off('change', callback, ctx)
  }

  function getHistoryObject() {
    return history;
  }

  function dispose() {
    // dispose all history listeners
    history.dispose();

    // And remove our own listeners
    eventBus.off();
  }

  function getValue(keyName) {
    if (keyName === undefined) return query;

    return query[keyName];
  }

  function setValue(keyName, value) {
    var keyNameType = typeof keyName;

    if (keyNameType === 'object') {
      Object.keys(keyName).forEach(function(key) {
        query[key] = keyName[key];
      });
    } else if (keyNameType === 'string') {
      query[keyName] = value;
    }

    history.set(query);

    return api;
  }

  function unsetValue(keyName) {
    if (!(keyName in query)) return; // nothing to do

    delete query[keyName];
    history.set(query);

    return api;
  }

  function updateQuery(newAppState) {
    query = newAppState;
    eventBus.fire('change', query);
  }

  function setIfEmpty(keyName, value) {
    if (typeof keyName === 'object') {
      Object.keys(keyName).forEach(function(key) {
        // TODO: Can I remove code duplication? The main reason why I don't
        // want recursion here is to avoid spamming `history.set()`
        if (key in query) return; // key name is not empty

        query[key] = keyName[key];
      });
    }

    if (keyName in query) return; // key name is not empty
    query[keyName] = value;

    history.set(query);

    return api;
  }
}
function queryState(defaults, options) {
  options = options || {};
  var history = options.history || windowHistory(defaults, options);
  validateHistoryAPI(history);

  history.onChanged(updateQuery)

  var query = history.get() || Object.create(null);

  var api = {

    /**
     * Gets current state.
     *
     * @param {string?} keyName if present then value for this key is returned.
     * Otherwise the entire app state is returned.
     */
    get: getValue,

    /**
     * Merges current app state with new key/value.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */
    set: setValue,

    /**
     * Removes value from the query string
     */
    unset: unsetValue,

    /**
     * Similar to `set()`, but only sets value if it was not set before.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */
    setIfEmpty: setIfEmpty,

    /**
     * Releases all resources acquired by query state. After calling this method
     * no hash monitoring will happen and no more events will be fired.
     */
    dispose: dispose,

    onChange: onChange,
    offChange: offChange,

    getHistoryObject: getHistoryObject,
  }

  var eventBus = eventify({});

  return api;

  function onChange(callback, ctx) {
    eventBus.on('change', callback, ctx);
  }

  function offChange(callback, ctx) {
    eventBus.off('change', callback, ctx)
  }

  function getHistoryObject() {
    return history;
  }

  function dispose() {
    // dispose all history listeners
    history.dispose();

    // And remove our own listeners
    eventBus.off();
  }

  function getValue(keyName) {
    if (keyName === undefined) return query;

    return query[keyName];
  }

  function setValue(keyName, value) {
    var keyNameType = typeof keyName;

    if (keyNameType === 'object') {
      Object.keys(keyName).forEach(function(key) {
        query[key] = keyName[key];
      });
    } else if (keyNameType === 'string') {
      query[keyName] = value;
    }

    history.set(query);

    return api;
  }

  function unsetValue(keyName) {
    if (!(keyName in query)) return; // nothing to do

    delete query[keyName];
    history.set(query);

    return api;
  }

  function updateQuery(newAppState) {
    query = newAppState;
    eventBus.fire('change', query);
  }

  function setIfEmpty(keyName, value) {
    if (typeof keyName === 'object') {
      Object.keys(keyName).forEach(function(key) {
        // TODO: Can I remove code duplication? The main reason why I don't
        // want recursion here is to avoid spamming `history.set()`
        if (key in query) return; // key name is not empty

        query[key] = keyName[key];
      });
    }

    if (keyName in query) return; // key name is not empty
    query[keyName] = value;

    history.set(query);

    return api;
  }
}
function queryState ( defaults , options ) { options = options || { } ; var history = options . history || windowHistory ( defaults , options ) ; validateHistoryAPI ( history ) ; history . onChanged ( updateQuery ) var query = history . get ( ) || Object . create ( null ) ; var api = { /**
     * Gets current state.
     *
     * @param {string?} keyName if present then value for this key is returned.
     * Otherwise the entire app state is returned.
     */ get : getValue , /**
     * Merges current app state with new key/value.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */ set : setValue , /**
     * Removes value from the query string
     */ unset : unsetValue , /**
     * Similar to `set()`, but only sets value if it was not set before.
     *
     * @param {string} key name
     * @param {string|number|date} value
     */ setIfEmpty : setIfEmpty , /**
     * Releases all resources acquired by query state. After calling this method
     * no hash monitoring will happen and no more events will be fired.
     */ dispose : dispose , onChange : onChange , offChange : offChange , getHistoryObject : getHistoryObject , } var eventBus = eventify ( { } ) ; return api ; function onChange ( callback , ctx ) { eventBus . on ( 'change' , callback , ctx ) ; } function offChange ( callback , ctx ) { eventBus . off ( 'change' , callback , ctx ) } function getHistoryObject ( ) { return history ; } function dispose ( ) { // dispose all history listeners history . dispose ( ) ; // And remove our own listeners eventBus . off ( ) ; } function getValue ( keyName ) { if ( keyName === undefined ) return query ; return query [ keyName ] ; } function setValue ( keyName , value ) { var keyNameType = typeof keyName ; if ( keyNameType === 'object' ) { Object . keys ( keyName ) . forEach ( function ( key ) { query [ key ] = keyName [ key ] ; } ) ; } else if ( keyNameType === 'string' ) { query [ keyName ] = value ; } history . set ( query ) ; return api ; } function unsetValue ( keyName ) { if ( ! ( keyName in query ) ) return ; // nothing to do delete query [ keyName ] ; history . set ( query ) ; return api ; } function updateQuery ( newAppState ) { query = newAppState ; eventBus . fire ( 'change' , query ) ; } function setIfEmpty ( keyName , value ) { if ( typeof keyName === 'object' ) { Object . keys ( keyName ) . forEach ( function ( key ) { // TODO: Can I remove code duplication? The main reason why I don't // want recursion here is to avoid spamming `history.set()` if ( key in query ) return ; // key name is not empty query [ key ] = keyName [ key ] ; } ) ; } if ( keyName in query ) return ; // key name is not empty query [ keyName ] = value ; history . set ( query ) ; return api ; } }
Creates new instance of the query state.
Creates new instance of the query state .