function Session(async) { var session = { character: JSON.parse(localStorage.getItem('character')), game: JSON.parse(localStorage.getItem('game')), options: JSON.parse(localStorage.getItem('options')) || defaultOptions() }; return { get: get, set: set, syncGame: syncGame, update: update }; function defaultOptions() { var o = { layout: { 'a': 'A', 'b': 'B', 'ArrowLeft': 'Left', 'ArrowRight': 'Right', 'ArrowUp': 'Up', 'ArrowDown': 'Down', 'Enter': 'Start', ' ': 'Select' }, textSpeed: 'medium' }; save('options', o); return o; } function get(path, obj) { obj = obj || session; if(Array.isArray(path)) { if(path.length == 0) { return obj; } else { var key = path.shift(); return get(path, obj[key]); } } else { return obj[path]; } } function save(key, value) { if(key != undefined) { localStorage.setItem(key, JSON.stringify(value || session[key])); } else { for(var key in session) { save(key); } } } function set(newSession) { for(var key in newSession) { session[key] = newSession[key]; save(key); } } function syncGame() { return async.bind( messaging.receive(function(message) { return message.tag == "Game"; }), function(message) { session.game = message.contents; return async.wrap(); } ); } function update(newSession) { for(var key in newSession) { merge(session[key], newSession[key]); save(key); } } function merge(a, b) { for(var key in b) { var value = b[key]; if(typeof value == "object") { if(Array.isArray(value)) { a[key] = []; for(var i = 0; i < value.length; i++) { a[key][i] = value[i]; } } else { merge(a[key], value); } } else { if(value !== undefined) { a[key] = value; } else { delete a[key]; } } } } }