• Stars
    star
    248
  • Rank 163,560 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created over 13 years ago
  • Updated about 2 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

An indexedDB adapter for Backbonejs

build status This is an IndexedDB adapter for Backbone.js.

Warnings

It lacks a lot of documentation, so it's good idea to look at the tests if you're interested in using it.

Browser support and limitations

In Firefox, backbone-indexeddb.js should work from 4.0 up; but it

  • won't work at all with local files (file:/// URLs). As soon as you try to create the database it will raise an error Permission denied for <file://> to create wrapper for object of class UnnamedClass
  • will ask the user for permission before creating a database
  • requests permission again when the database grows to a certain size (50MB by default). After this the disk is the limit, unlike the fairly concrete and currently fixed limit (5MB by default) that localStorage gets (which will just fail after that with no way to ask the user to increase it).

Chrome 11 and later are supported. (Chrome 9 and 10 should also work but are untested.) In Chrome 11, backbone-indexeddb.js

  • will work with file:/// URLs, but
  • poses some hard size limit (5MB? quantity untested) unless Chrome is started with --unlimited-quota-for-indexeddb, with apparently no way to request increasing the quota.

IE10 support has been added thanks to lcalvy.

Other browsers implementing the Indexed Database API Working Draft should work, with some of these limitations possibly cropping up or possibly not. Support and ease of use is expected to improve in upcoming releases of browsers.

Tests

Just open the /tests/test.html in your favorite browser. (or serve if from a webserver for Firefox, which can't run indexedDB on local file.)

Node

This is quite useless to most people, but there is also an npm module for this. It's useless because IndexedDB hasn't been (yet?) ported to node.js. It can be used in the context of browserify though... and this is exactly why this npm version exists.

Implementation

Database & Schema

Both your Backbone model and collections need to point to a database and a storeName attributes that are used by the adapter.

The storeName is the name of the store used for the objects of this Model or Collection. You should use the same storeName for the model and collections of that same model.

The database is an object literal that define the following :

  • id : and unique id for the database
  • description : a description of the database [OPTIONAL]
  • migrations : an array of migration to be applied to the database to get the schema that your app needs.

The migrations are object literals with the following :

  • version : the version of the database once the migration is applied.
  • migrate : a Javascript function that will be called by the driver to perform the migration. It is called with a IDBDatabase object, a IDBVersionChangeRequest object and a function that needs to be called when the migration is performed, so that the next migration can be executed.
  • before [optional] : a Javascript function that will be called with the database, before the transaction is run. It's useful to update fields before updating the schema.
  • after [optional] : a Javascript function that will be called with the database, after the transaction has been run. It's useful to update fields after updating the schema.

Example

var database = {
	id: "my-database",
	description: "The database for the Movies",
	migrations : [
		{
			version: "1.0",
			before: function(next) {
			    // Do magic stuff before the migration. For example, before adding indices, the Chrome implementation requires to set define a value for each of the objects.
			    next();
			}
			migrate: function(transaction, next) {
				var store = transaction.db.createObjectStore("movies"); // Adds a store, we will use "movies" as the storeName in our Movie model and Collections
				next();
			}
		}, {
			version: "1.1",
			migrate: function(transaction, next) {
				var store = transaction.db.objectStore("movies")
				store.createIndex("titleIndex", "title", { unique: true});  // Adds an index on the movies titles
				store.createIndex("formatIndex", "format", { unique: false}); // Adds an index on the movies formats
				store.createIndex("genreIndex", "genre", { unique: false}); // Adds an index on the movies genres
				next();
			}
		}
	]
}

Models

Not much change to your usual models. The only significant change is that you can now fetch a given model with its id, or with a value for one of its index.

For example, in your traditional backbone apps, you would do something like :

var movie = new Movie({id: "123"})
movie.fetch()

to fetch from the remote server the Movie with the id 123. This is convenient when you know the id. With this adapter, you can do something like

var movie = new Movie({title: "Avatar"})
movie.fetch()

Obviously, to perform this, you need to have and index on title, and a movie with "Avatar" as a title obviously. If the index is not unique, the database will only return the first one.

Collections

I added a lot of fun things to the collections, that make use of the options param used in Backbone to take advantage of IndexedDB's features, namely indices, cursors and bounds.

First, you can limit and offset the number of items that are being fetched by a collection.

var theater = new Theater() // Theater is a collection of movies
theater.fetch({
	offset: 1,
	limit: 3,
	success: function() {
		// The theater collection will be populated with at most 3 items, skipping the first one
	}
});

You can also provide a range applied to the id.

var theater = new Theater() // Theater is a collection of movies
theater.fetch({
	range: ["a", "b"],
	success: function() {
		// The theater collection will be populated with all the items with an id comprised between "a" and "b" ("alphonse" is between "a" and "b")
	}
});

You can also get all items with a given value for a specific value of an index. We use the conditions keyword.

var theater = new Theater() // Theater is a collection of movies
theater.fetch({
	conditions: {genre: "adventure"},
	success: function() {
		// The theater collection will be populated with all the movies whose genre is "adventure"
	}
});

You can also get all items for which an indexed value is comprised between 2 values. The collection will be sorted based on the order of these 2 keys.

var theater = new Theater() // Theater is a collection of movies
theater.fetch({
	conditions: {genre: ["a", "e"]},
	success: function() {
		// The theater collection will be populated with all the movies whose genre is "adventure", "comic", "drama", but not "thriller".
	}
});

You can also selects indexed value with some "Comparison Query Operators" (like mongodb) The options are:

  • $gte = greater than or equal to (i.e. >=)
  • $gt = greater than (i.e. >)
  • $lte = less than or equal to (i.e. <=)
  • $lt = less than (i.e. <)

See an example.

var theater = new Theater() // Theater is a collection of movies
theater.fetch({
	conditions: {year: {$gte: 2013},
	success: function() {
		// The theater collection will be populated with all the movies with year >= 2013
	}
});

You can also get all items after a certain object (excluding that object), or from a certain object (including) to a certain object (including) (using their ids). This combined with the addIndividually option allows you to lazy load a full collection, by always loading the next element.

    var theater = new Theater() // Theater is a collection of movies
    theater.fetch({
    	from: new Movie({id: 12345, ...}),
    	after: new Movie({id: 12345, ...}),
    	to: new Movie({id: 12345, ...}),
    	success: function() {
    		// The theater collection will be populated with all the movies whose genre is "adventure", "comic", "drama", but not "thriller".
    	}
    });

You can also obviously combine all these.

Optional Persistence

If needing to persist via ajax as well as indexed-db, just override your model's sync to use ajax instead.

class MyMode extends Backbone.Model

  sync: Backbone.ajaxSync

Any more complex dual persistence can be provided in method overrides, which could eventually drive out the design for a multi-layer persistence adapter.

More Repositories

1

xmpp-server

A full blown XMPP server based on https://github.com/node-xmpp/node-xmpp with modules
JavaScript
211
star
2

ejabberd-websockets

An ejabberd component to handle XMPP over Websockets
JavaScript
211
star
3

subtome

A universal Subscribe/Follow button.
JavaScript
164
star
4

superpipes

Superfeedr powered pipes!
JavaScript
134
star
5

superfeedr-ruby

Ruby Client for Superfeedr.com, based on Babylon
Ruby
64
star
6

news-bot

This is a news bot which uses Superfeedr's API to send and receive RSS notifications.
JavaScript
53
star
7

notifixlight

Defunct RSS to IM bot, powered by Google App Engine. Check Notifix for a better replacement!
Python
48
star
8

feediscovery

Feed discovery to share :)
Python
40
star
9

rack-superfeedr

A gem that provides a rack middleware to interract with Superfeedr's API.
Ruby
38
star
10

superfeedr-node

A library to interract with Superfeedr's XMPP API in any node application
JavaScript
31
star
11

superfeedr-python

Superfeedr API Wrapper in Python
Python
25
star
12

popular-feeds

Various Lists of Popular feeds curated by Superfeedr and team :)
21
star
13

river.news

A river of news application implemented in React which uses Superfeedr for its backend
JavaScript
18
star
14

documentation

The Superfeedr Documentation
HTML
15
star
15

ChitChatRooms

A small Chat Application on Google App Engine with file exchange and XMPP integration
Python
15
star
16

superfeedr-engine

A Superfeedr engine for Ruby on Rails. Handles notifications for you.
Ruby
12
star
17

feender

A module that's able to extract feed urls from any url.
JavaScript
11
star
18

pubsubjubhub

A PubSubHubbub subscriber in Javascript
Python
11
star
19

readernews

A Superfeedr API retrieve demo as a React application
JavaScript
9
star
20

node-relmeauth

A rel=me auth middleware implementation in node.js. Works with any connect-type web application
JavaScript
9
star
21

superfeedr-pshb

PubSubHubbub API wrapper for Superfeedr
JavaScript
8
star
22

superfeedr-jquery

A Jquery plugin to access Superfeedr's retrieve API
JavaScript
7
star
23

node-feediscovery

A wrapper around http://feediscovery.appspot.com/
JavaScript
6
star
24

superfeedr-hapi

A module for Hapi.js Node.js web server
JavaScript
6
star
25

superfeedr-node-sample

This is a sample application to show how you can use node-superfeedr on Heroku!
JavaScript
4
star
26

feedbox

A dropbox for RSS feeds
HTML
4
star
27

angular-superfeedr

An Angular Provider which wraps the Superfeedr HTTP API
4
star
28

feediscovery-rb

A ruby gem for http://feediscovery.appspot.com/
Ruby
3
star
29

supergrover

A Superfeedr to Grove.io brigde hosted on Heroku.
JavaScript
2
star
30

webhooks-test

An app to test Github's webhhoks!
1
star
31

superfeedr-rb

A Superfeedr API library written on top of Blather
Ruby
1
star
32

superfeedr-publisher-callback

Publisher Callback Sample Application
Python
1
star
33

blog.superfeedr.com

http://blog.superfeedr.com
1
star
34

superfeedr-connect-middleware

PuSH & Superfeedr middleware for Node.js (Connect/Express)
JavaScript
1
star