Skip to content

Instantly share code, notes, and snippets.

@brianmcallister
Last active December 14, 2015 00:39
Show Gist options
  • Save brianmcallister/5000368 to your computer and use it in GitHub Desktop.
Save brianmcallister/5000368 to your computer and use it in GitHub Desktop.
Wrapper around localStorage to do time based caching of data.
# Class for using localStorage to cache data for a set amount of time.
# https://gist.github.com/brianmcallister/5000368
#
# name - Name for this cache.
#
# Examples
#
# cache = new Cache('my-cache').set 'my-data', {data: 'hats'}, 120
class Cache
# Private: Just a function that returns null.
#
# Returns null.
noop = -> null
# Public: Constructor. Returns an object that matches the public API of this
# class if your browser doesn't support localStorage.
#
# name - Name of your cache.
#
# Returns this.
constructor: (@name) ->
unless localStorage
match =
set: noop
get: noop
fresh: noop
invalidate: noop
return match
return this
# Public: Set data in the cache.
#
# key - Key to save the data under.
# data - Data to save. Can be of any type.
# duration - How long to cache the data, in hours. Defaults to 24.
#
# Returns this.
set: (key, value, duration = 24) ->
now = new Date().getTime()
expiration = now + (duration * 3600 * 1000)
existing = this.get()
# Create the data envelope.
envelope =
name: @name
data: if existing.data? then existing.data else {}
# Set the key meta information.
envelope.data[key] =
set: now
expires: expiration
# Not fresh if setting the value to null.
fresh: if value? then true else false
value: value
# Set the data.
localStorage.setItem @name, JSON.stringify envelope
return this
# Public: Get data. Optional, get data by specific key.
#
# key - Optional key name to get a specific item from the cache.
# Defaults to null, which will return the entire cache.
# withMeta - Pass true to get the key's meta information in the response.
# Defaults to false.
#
# Returns an object of data, or null if the specified key does not exist.
get: (key = null, withMeta = false) ->
now = new Date().getTime()
cache = JSON.parse localStorage.getItem @name
return false unless cache # No data.
return cache unless key # All the data.
return false unless cache.data[key] # That data isn't here.
# Test if the data is fresh.
cache.data[key].fresh =
if cache.data[key].expires > now then true else false
# Return the key.
return if withMeta then cache.data[key] else cache.data[key].value
# Public: Check if the cache data is fresh.
#
# key - Name of the data in the cache to check.
#
# Returns true if data is fresh, false if not or if key doesn't exist.
fresh: (key) ->
data = @get key, true
return if data? then data.fresh else false
# Public: Invalidate a key in the cache. Doesn't check if the key exists
# because you can always overwrite the value for that key later.
#
# key - Name of the key to remove
#
# Returns this.
invalidate: (key) ->
@set key, null
return this
# Add support for loading with require.
if typeof define is 'function'
define [], -> Cache
else
window.Cache = Cache
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment