For the best experience please use the latest Chrome, Safari or Firefox browser.

All Your Base 2012


@brianleroux

lawnchair

simple json storage

(Img credit Drawbuck.)

Build native mobile apps using html, css, and javascript.

Packaged apps are naturally persistent. The files live on the device.

(Sometimes these are called 'installable web apps'.)

Installed apps might not be online and this is the first thing Apple tests in the app store review proccess.

We quickly realized we needed network introspection and persistence apis.


var states = {}

states[navigator.connection.UNKNOWN] = 'Unknown connection'
states[navigator.connection.ETHERNET] = 'Ethernet connection'
states[navigator.connection.WIFI] = 'WiFi connection'
states[navigator.connection.CELL_2G] = 'Cell 2G connection'
states[navigator.connection.CELL_3G] = 'Cell 3G connection'
states[navigator.connection.CELL_4G] = 'Cell 4G connection'
states[navigator.connection.NONE] = 'No network connection'

console.log(states[navigator.connection.type])
        
        
Warning! This is deprecated.

navigator.connection.addEventListener('change', function() {
  console.log(navigator.connection.bandwidth);
}, false)

        
Lets check the spec!
        
// ever played with Infinity?
        
        
        
// one last wtf
console.log(navigator.onLine)
        
        
the whatwg spec
So, that is the current state of network introspection APIs today. Lets look at actual persistence.
Cookies. Just use the PPK script if you must. Keith Clark came up with a clever hack using cookies as the transport to get viewport detection back to the server when user agent fails. Don't judge. You may need this!
SQL in the browser. SQLite specifically. Probably, anyhow.

Gears SQLite API


db.open('database-test');
db.execute('create table if not exists Test (Phrase text, Timestamp int)');
db.execute('insert into Test values (?, ?)', ['Monkey!', new Date().getTime()]);
var rs = db.execute('select * from Test order by Timestamp desc');
while (rs.isValidRow()) {
    alert(rs.field(0) + '@' + rs.field(1));
    rs.next();
}
rs.close();

(On 5.0 Browser. We no longer support.)

(On 5.0 Browser. We no longer support.)


var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024)

db.transaction(function (tx) {
    tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)')
    tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "whatevs")')
    tx.executeSql('SELECT * FROM foo', [], printer)
})

function printer (tx, results) {
    for (var i = 0, l = results.rows.length; i < l; i++) {
        console.log(results.rows.item(i).text);
    }
}

This is an improvement on gears. Its async. Fairly terse. Lets check support.
Bugger. (There is a Firefox plugin but that is a crap solution. Ppl don't like plugins. Trust me: I work for Adobe!
SQLite is an implementation not a standard.

var db = openDatabase('mydb', '1.0', 'my first database', 2 * 1024 * 1024)

db.transaction(function (tx) {
    tx.executeSql('CREATE TABLE IF NOT EXISTS foo (id unique, text)')
    tx.executeSql('INSERT INTO foo (id, text) VALUES (1, "whatevs")')
    tx.executeSql('SELECT * FROM fo', [], printer)
})

function printer (tx, results) {
    for (var i = 0, l = results.rows.length; i < l; i++) {
        console.log(results.rows.item(i).text);
    }
}

Relational data on the client is questionable. It is likely you've denormalized already for presentation. Consider versioning rigid schemas across occasionally connected clients. Yikes!
Web storage, lets hack you.
I really love this API however it is synchronous therefore blocks on IO. Also: no complex types, not very robust querying mechanisms.
Keep in mind that supported basically everywhere is not the same as supported everywhere. Opera Mini has significant marketshare.
Android Webkit: 23.2 %Mobile Safari: 21.9 %Internet Explorer: 18.8 %Opera Mini: 15.4 %Chrome: 6.6 %Others: 14.1 %Source: Akamai IO (Beta)
Its simple! We need for async api that is transactional, can store complex types, and has robust querying capability. Lets call it WebSimpleDB!

Thusly renamed to Indexed DB.


var request = indexedDB.open('all-your-base')

request.onsuccess = function (e) {
    var version = '1.0'
    var db = e.target.result

    if (version != db.version) {
        // the only place you can create a store...deprecated for onupgradeneeded
        var setVrequest = db.setVersion(version)

        setVrequest.onsuccess = function(e) {
            var store = db.createObjectStore('all-your-base', {keyPath: 'timeStamp'})
            e.target.transaction.oncomplete = function() { console.log('created a store')}
        }
    } 
}


var trans = db.transaction(['all-your-base'], 'readwrite')
var store = trans.objectStore('all-your-base')
var request = store.put({'text':'ya data store', 'timeStamp':new Date().getTime()})

request.onsuccess = request.onerror = function(e) { console.log(e) }


var cursorRequest = store.openCursor(IDBKeyRange.lowerBound(0))

cursorRequest.onsuccess = function(e) {
    var result = e.target.result.value 
    result.continue()
}


// removing data is intuitive...
var request = store.delete(id)

So, can we use?
Of course, you could polyfill.

So anyhow, that is why I created Lawnchair.

This probably comes as no surprise but there is other weird stuff in web persistence worth mentioning.
Flash can be used to create an unkillable cookie..

// store unlimited data on all browsers, accessible from any domain, I shit you not
window.name


// store unlimited data on all browsers, accessible from any domain, I shit you not
window.name

So, web sockets are great but tcp or udp sockets mean we could have a web page open a database connection. (!) WebRTC PeerChannel and DataConnection APIs also mental.
There is strong indication of first class File APIs coming to browsers. Happy days! Confusingly there is split into a couple of specs. The File API and Directories and System API.
The various File APIs are verbosely async but FilerJS shows a sane UNIXy wrapper is possible. Probably desirable.
Our friends at Mozilla are working out an Archive API in their Firefox OS research. This could enable super-fast self-updating packaged apps. We do something like this in PhoneGap/Build we called "Hydration".
Packaged web apps are happening. Consider: Microsoft Windows 8, Google Chrome apps, and Firefox OS. PhoneGap is the polyfill for the places you can't package an app, yet. App Cache lets you package apps for offline in most browsers today---but its kinda fucked up.
Thanks, eh.

Use a spacebar or arrow keys to navigate