retain

Javascript Model based on promises with plugins support

Usage no npm install needed!

<script type="module">
  import retain from 'https://cdn.skypack.dev/retain';
</script>

README

Retain

Retain is a browser (CJS) and node Javascript model with plugins support.

Build Status Coverage Status

Installation

$ npm install retain

Motivation

There are many Javascripts models out there, but the majority of them are deeply coupled inside a framework, thus making it impossible hard to use them in another project/environment.

Example

var retain = require("retain");
var Movies = retain();

Movie.attrs({
  name:String,
  watched:Boolean
})

var goodfellas = Movies.new() // Creates a Movie instance

Initialize

Retain can be initialized in two ways:

  • Creating a new Retain instance

    var retain = require("retain");
    var Movies = retain();
    
  • Extending the Retain constructor function.

    var Retain = require("retain").Retain;
    var Movies = {};
    Movies.prototype = new Retain;
    

For Coffeescript lovers, you can extend Retain like this:

retain = require "retain"

class Movies extends retain.Retain

API

First, you will have to set the Model properties with its type (for validation purpose)

Movie.attrs({
  name:String,
  watched:Boolean
})

This way, each model instance will have these properties to be setted and validated.

API methods

Each method have an option to update the data remotelly passing a callback as parameter.

Creates a local record.

var fightClub = Movie.new();

Creates a local and remote record.

var fightClub = Movie.new(function(record, err)
{
  // Record retrieved remotelly
});

NEW

The new method is responsible for creating new model instances:

Creates a local record.

var fightClub = Movie.new();

Creates a local and remote record.

var fightClub = Movie.new(function(record, err)
{
  // Record retrieved remotelly
});

You can also set the newly record parameters:

Creates a local record called 'Fight Club'.

var fightClub = Movie.new({name:"Fight Club"});

Creates a local and remote record called 'Fight Club'.

var fightClub = Movie.new({name:"Fight Club"},function(record, err)
{
  // Record retrieved remotelly
});

SET

The set method is responsible for setting and updating the model properties.

Sets the record properties locally.

fightClub.set({"name": "Fight Club", watched:true});

Sets the record properties locally and remotelly.

fightClub.set({"name": "Fight Club", watched:true},function(record, err)
{
  if(record)
  {
    // Updated record retrieved remotelly
  }
})

GET

The get method is responsible for retrieving the property value (from the local record)

Get a record property value.

fightClub.get("name") // Fight Club

ALL

The all method fetchs all the model collection locally or remotelly.

Get all the records locally.

var movies = Movie.all() // [fightClub]

Get all the records remotelly and updates/overwrites the local collection.

var movies = Movie.all(function(records, err)
{
  if(records)
  {
    // Records retrieved remotelly
  }
})

FIND

The find method is responsible for retrieving a record, searching by id or cid. Search by id only if the data were retrieved from a remote location at least once, otherwise, search by cid, which is basically, the record index at the local array.

Search for a record locally by ID or CID.

movie = Movie.find(0); // Returns fightClub reference.

Search for a record remotelly by ID or CID

movie = Movie.find(0, function(record, err)
{
  if(record)
  {
    // Record retrieved remotelly
  }
});

SEARCH

The search method searchs for records by the specified properties.

Search for a record named 'Pulp Fiction'.

pulp = Movie.search({name:"Pulp Fiction"}); // Returns an array containing all thefound records

Search remotelly for a record named 'Pulp Fiction'.

movie = Movie.find({name:"Pulp Fiction"}, function(records, err)
{
  if(records)
  {
    // Records retrieved remotelly
  }
});

REMOVE

The remove method will delete the instance, locally or/and remotelly.

Deletes a record locally.

fightClub.remove();

Deletes a record remotelly.

fightClub.remove(function(record, err)
{
  if(record)
  {
    // Record deleted remotelly.
  }
});

SAVE

The save method will sync the local record with the remote storages.

Sync the local record with the remote storages.

var moon = Movie.new()
moon.set({name:"Moon"});
moon.save(function(record, err)
{
  if(record)
  {
    done();
  }
});

Events

Retain uses the Happens library for the event system.

You can bind a callback function to a Retain instance event using the happens signature.

var godfather = Movie.new();

godfather.on("change", function(record)
{
  //Record has changed
})

Change

Fired when an instance property changes.

New

Fired when a new instance is created.

Remove

Fired when an instance is deleted.

Error

Fired when a plugin couldn't fetch the data.

API Docs.

Plugins

By default, Retain saves the data in memory (which gets removed after a browser refresh). In order to save the data in other locations such as localStorage or database, you should use one the avaliable plugins.

★ List of avaliable plugins:

Example

var retain = require("retain");
var retainAjax = require("retain-http");

var Movies = retain();

Movies.attrs({
  name:String.
  watched:Boolean
});

Movies.use(retainAjax, {url:"http://remoteserver/rest/url"});

Now, whenever the data is modified, it will be saved remotelly.

Creating a plugin

Retain use promises internally to transfer the data between the plugins.

To create a plugin, it is necessary to implement each of the following Retain methods.

  • new
  • all
  • set
  • find
  • search
  • remove