Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mckamey committed Jan 24, 2012
0 parents commit 926adde
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 0 deletions.
7 changes: 7 additions & 0 deletions .gitignore
@@ -0,0 +1,7 @@
.DS_Store
.classpath
.project
.settings
.iml
.ipr
.iws
133 changes: 133 additions & 0 deletions README.md
@@ -0,0 +1,133 @@
jQuery.lscache()
================

This simple jQuery plugin adds an [lscache](http://github.com/pamelafox/lscache) buffer into
$.ajax() calls (or any fetch method returning a promise object). `lscache` is a Memcached-style
key-value cache built on top of `localStorage`. The semantics are the same as `$.ajax(options)`
but with an additional argument for the cache item.

Requirements
------------

- jQuery 1.5 or later. http://jquery.org
- lscache: http://github.com/pamelafox/lscache

Usage
-----

```
$.lscache(cacheItem, fetch|options);
```

Where the first argument is the cache item implemented as an object literal with two properties:

- string `key`: lscache key
- number `time`: time until expiration in minutes (see [lscache](http://github.com/pamelafox/lscache#readme))

The second argument is *either* a callback function to retrieve the item value, or
an `$.ajax` `options` object to retrive the value via jqXHR.

Examples
--------

This example retrieves the current user data from a remote API. If it has not been fetched within the last hour,
it will get a new copy of the data, store it in cache and return it. The result will be the same whether it is
stored in cache or is remotely fetched.

```
$.lscache(
{
key: 'current-user',
time: 60
},
{
type: 'GET',
url: '/api/user',
data: {
userid: 1234
}
}).done(function(user) {
alert('Successfully retrieved user '+user.name);
}).fail(function(xhr, status, responseText) {
alert('Remote fetch failed for user 1234: '+responseText);
});
```

The next example shows a custom fetch method that isn't based upon `$.ajax`. The `fetch` argument can be any function
that returns a `jQuery.Deferred` promise object. This allows any asynchronous callbacks with success/fail semantics.

```
$.lscache(
{
key: 'current-user',
time: 60
},
function() {
var defd = $.Deferred();
// ...perform asynchronous work here
setTimeout(function() {
// NOTE: this happens after the fetch function returns
if (wasResultWasSuccessful) {
// if successful respond with result
defd.resolve({
id: 1234
name: 'Bob',
email: 'bob@example.com'
});
} else {
// if failed respond with contextual information
defd.reject(rejection);
}
}, 5000);
return defd.promise();
}).done(function(user) {
alert('Successfully retrieved user '+user.name);
}).fail(function(rejection) {
alert('Remote fetch failed for user 1234');
});
```

By building upon the jQuery.Deferred object, you can actually chain multiple fetch calls together where some of them may be
populated from lscache and others are remotely fetched, each with their own expiration policies. jQuery provides the
`$.when` method for this purpose:

```
$.when(
$.lscache({
key: 'current-user',
time: 10
},
{
type: 'GET',
url: '/api/user',
data: {
userid: 1234
}
}),
$.lscache({
key: 'current-profile',
time: 60
},
{
type: 'POST',
url: '/api/user/profile',
data: {
userid: 1234
}
})
).done(function(user, profile) {
// work with both objects together
}).fail(function(xhr, status, responseText) {
console.log('user/profile failed for 1234: '+responseText);
});
```
66 changes: 66 additions & 0 deletions jquery.lscache.js
@@ -0,0 +1,66 @@
/*global jQuery, lscache *//*jshint smarttabs:true */
/*
* jQuery lscache plugin v0.1.0
*
* Copyright 2012 Stephen M. McKamey
* Licensed under the MIT license.
* http://www.opensource.org/licenses/mit-license.php
*/

(function(jQuery, lscache){
'use strict';

jQuery.extend({
lscache:
/**
* Buffered loading checks lscache first then defers to fetch if not found
*
* @param {object} item
* @param {object|function():jQuery.Deferred} options jqXHR options or callback to async fetch data
* @return {jQuery.Deferred}
*/
function(item, options) {
if (!item || !item.key) {
throw 'missing cache item';
}

var fetch = (typeof options === 'function') ?
options :
function() { return jQuery.ajax(options); };

// wrap response in deferred
var defd = jQuery.Deferred();

// lookup in cache
var value = lscache.get(item.key);

if (value !== null) {
//console.log('cache-hit: '+item.key);
// found in cache
defd.resolve(value);

} else {
//console.log('cache-miss: '+item.key);

// not found, remotely fetch
fetch().done(function(value) {
// intercept and cache value
lscache.set(item.key, value, item.time);

//console.log('cache-set: '+item.key);

// fetch succeeded
defd.resolve(value);

}).fail(function() {
// fetch failed
defd.reject.apply(defd, arguments);
});
}

// return promise object
return defd.promise();
}
});

})(jQuery, lscache);

0 comments on commit 926adde

Please sign in to comment.