/**
 * Provides a client-side Session which is capable of timing out due to inactivity.
 *
 * Sample usage:
 *     // Load the module and create an instance.
 *     var AppSession = require('AppSession');
 *     var appSession = new AppSession();
 *     appSession.setTimeoutMs(30000); // A value of 0 means never timeout.
 *
 *     // Start a new Session, e.g. after an app login.
 *     // You can track session-specific info if you wish, just provide some object.
 *     appSession.startNewSession({username : 'pxtrick'});
 *
 *     // Touch the Session whenever an app UI events occurs.
 *     appSession.touch();
 *
 *     // Inspect Session values.
 *     appSession.getSessionInfo(); // Will be {username : 'pxtrick'}, provided to session creation.
 *     appSession.isLive();         // Will be 'true' as long as there is 'touch' activity.
 *
 *     // Terminate the Session, e.g. after an app logout.
 *     appSession.endSession();
 *     appSession.isLive();  // Will be 'false'.
 *
 * @author Patrick Seda - @pxtrick
 */
var AppSession = function() {
	// +-----------------------+
	// | Private members.      |
	// +-----------------------+
	// The TTL for a Session. A value of 0 means never timeout.
	var sessionTimeoutMs = 600000; // Default to 600000 ms (10 min)

	var lastAccessTime = null;
	var heartbeatTimer = null;
	var sessionInfo = null;

	// Determine if the Session can ever timeout.
	var usingTimeout = function() {
		return sessionTimeoutMs > 0;
	};
	
	// Remove the entry for the sessionInfo.
	var clearSessionInfo = function() {
		sessionInfo = null;
	};
	
	// Start the internal heartbeat thread (if timeout is enabled).
	var startHeartbeat = function() {
		if (usingTimeout()) {
			var mostFrequentPeriodMs = 15000;
			var heartbeatMs = Math.max(mostFrequentPeriodMs, sessionTimeoutMs/4);
			heartbeatTimer = setInterval(function() {
				if (!isSessionLive()) {
					// Session is dead, perform internal cleanup.
					endSession();
				}
			}, heartbeatMs);
		}
	};
	
	// Stop the internal life-check thread.
	var stopHeartbeat = function() {
		if (heartbeatTimer !== null) {
			clearInterval(heartbeatTimer);
			heartbeatTimer = null;
		}
	};
	
	
	// +-----------------------+
	// | Public members.       |
	// +-----------------------+
	// Touch the Session to indicate it is still active.
	var touchSession = function() {
		if (isSessionLive()) {
			lastAccessTime = new Date(); // now
		} else {
			Ti.API.info('TOUCH (dead Session)');
		}
	};
	
	// Get the sessionInfo for the Session.
	var getSessionInfo = function() {
		if (isSessionLive()) {
			touchSession();
		} else {
			endSession();
		}
		return sessionInfo;
	};
	
	// Set the Session timeout.
	function setTimeoutMs(_timeoutMs) {
		if (_timeoutMs && (_timeoutMs >= 0)) {
			sessionTimeoutMs = _timeoutMs;
		}
	};
	
	// Get the Session timeout.
	var getTimeoutMs = function() {
		return sessionTimeoutMs;
	};
	
	// Start a new Session.
	var startNewSession = function(_sessionInfo) {
		endSession();
		_sessionInfo && (sessionInfo = _sessionInfo);
		lastAccessTime = new Date(); // now
		startHeartbeat();
	};
	
	// Determine if the Session has expired since the last request.
	var isSessionLive = function() {
		if (lastAccessTime === null) {
			return false;
		}
		if (!usingTimeout()) {
			return true;
		}
		var now = new Date();
		return (now.getTime() - lastAccessTime.getTime() < sessionTimeoutMs);
	};
	
	// Remove all information related to the current Session.
	var endSession = function() {
		stopHeartbeat();
		lastAccessTime = null;
		clearSessionInfo();
		Ti.API.info('Your Session has ended!');
	};
	
	
	// +-----------------------+
	// | Public API.           |
	// +-----------------------+
	return {
		getSessionInfo : getSessionInfo,

		setTimeoutMs : setTimeoutMs,
		getTimeoutMs : getTimeoutMs,

		startNewSession : startNewSession,
		touch : touchSession,
		isLive : isSessionLive,
		endSession : endSession
	};
};

module.exports = AppSession;

@@ -229,35 +229,78 @@
  new AppSession(
+%7BtimeoutMs : 0, sessionTimedOutCB : someCB%7D
 );%0A
-
  *     appSessio
@@ -1091,24 +1091,28 @@
  = function(
+args
 ) %7B%0A%09// +---
@@ -1189,24 +1189,48 @@
 ----------+%0A
+%09var args = args %7C%7C %7B%7D;%0A
 %09// The TTL 
@@ -1342,16 +1342,153 @@
 (10 min)
+%0A%09var sessionTimedOutCB = null;%0A%09%0A%09setTimeoutMs(args.timeoutMs);%0A%09args.sessionTimedOutCB && (sessionTimedOutCB = args.sessionTimedOutCB);
 %0A%0A%09var l
@@ -2145,16 +2145,16 @@
 leanup.%0A
-
 %09%09%09%09%09end
@@ -2164,16 +2164,63 @@
 sion();%0A
+%09%09%09%09%09sessionTimedOutCB && sessionTimedOutCB();%0A
 %09%09%09%09%7D%0A%09%09

Add a callback for when an unattended session times out. Update input parameters.