Skip to content

pwentz/localRecord

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

61 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LocalRecord

an object relational mapper for localStorage that works like ActiveRecord, the popular ORM from the Rails framework. I did my best to replicate the way ActiveRecord works with these functions, so that those coming from Rails can pick this up right away.

Table of Contents

Getting Started

npm install LocalRecord
const LocalRecord = require('LocalRecord')

const whateverYouWantToCallIt = new LocalRecord()

.all()

To retrieve all the objects you have in localStorage, simply use .all()

// if the following *stringified* items are already in localStorage

// { wow: 'cool'}
// { ok: 'neat' }
// { super: 'awesome' }

const localRecord = new LocalRecord()

console.log(localRecord.all())
// [{ wow: 'cool' }, { ok: 'super' }, { super: 'awesome' }]

.create()

When called, the .create function takes an argument that is the object that you want to create, and returns an uninvoked function. The second argument for the function is the ID/reference to the object you're saving. You can pass a string or number as an argument if you'd like to keep a manual reference...or you can not pass an argument and LocalRecord will auto-generate a unique key for you.

const localRecord = new LocalRecord()

const myObject = { wow: 'cool' }

localRecord.create(myObject)(123) // <= works

localRecord.create(myObject)() // <= also works

.create() returns a function so that LocalRecord can simulate the .new and .create validation flow that gives ActiveRecord its reliable flexibility.

const newRecord = localRecord.create({ wow: 'neat' })
if (newRecord()) {
  // success control flow
}
else {
  // failure control flow
}

This is also useful for memoizing your variables if your jumbling a lot of manual references.

const newRecord = localRecord.create({ wow: 'neat' })

const savedRecord = newRecord('mightBeTaken') || newRecord()

If the first create function is passed anything other than an object - an error will be thrown immediately.

localRecord = new LocalRecord()
localRecord.create({ wow: 'cool' }) // <= fine

localRecord.create('myRecord') // <= throws ArgumentError

The second function call will return false under two conditions:

  • An exact copy of the object already exists in localStorage
localRecord.create({ wow: 'cool' })()
const newRecord = localRecord.create({ wow: 'cool' })

newRecord() // will return false
  • The ID parameter that the user passed is already taken
localRecord.create({ wow: 'cool' })('myRecord')
const newRecord = localRecord.create({ ok: 'neat'})

newRecord('myRecord') // will return false

If creation was a success, the second function call should return the object that was saved:

const newRecord = localRecord.create({ wow: 'neat'})

const mySavedRecord = newRecord()

console.log(mySavedRecord)
// { wow: 'neat' }

.find()

The .create function returns an uninvoked function. So the object isn't written into localStorage until second function is called.

If you'd like to be able to easily reference this object later down the line, you can pass an optional argument to the second function call which would serve as the object's id. Otherwise, a random ID will be dynamically generated.

localRecord.create({ wow: 'cool' })('myRecord')

// now the object can be referenced later using .find()

const record = localRecord.find('myRecord')

console.log(record)
// { wow: 'cool' }

.findBy()

If you choose to let LocalRecord generate your id, you can retrieve it by searching for its props using .findBy()

const newRecord = { wow: 'cool', awesome: 'neat' }
localRecord.create(newRecord)() // <= ID is auto-generated

// reference object by querying for its props

const record = localRecord.findBy({ wow: 'cool' })

console.log(record)
{ wow: 'cool', awesome: 'neat' }

.where()

...and of course you can query by collection using .where()

localRecord.create({ height: 'tall', eyes: 'brown' })()
localRecord.create({ height: 'tall', eyes: 'green' })()
localRecord.create({ height: 'tall', eyes: 'blue' })()

const records = localRecord.where({ height: 'tall' })

console.log(records)
/* [{ height: 'tall', eyes: 'brown'},
    { height: 'tall', eyes: 'green'},
    { height: 'tall', eyes: 'blue'}] */
Warning

Similar to .create(), .findBy(), and .where() will throw an error if passed anything other than an object.

localRecord.create({ height: 'tall', eyes: 'brown' })()

const record = localRecord.where('tall')
// throws InvalidArgumentError

.update()

Similar to ActiveRecord's update methods, .update() is a slightly more rigid than .create() with what it allows.

const existingObject = { wow: 'cool',
                         neat: 'okay'}

localRecord.create(existingObject)()

// first argument MUST be the object
// second argument are the changes to be made

const updatedRecord = localRecord.update(existingObject, { wow: 'lets go' })

console.log(updatedRecord)
// { wow: 'lets go', neat: 'okay' }
localRecord.create({ wow: 'cool' })()

localRecord.update('myObject', { wow: 'ok' })

// throws an InvalidArgumentError first if it doesn't receive an object
// this record is not saved

const nonExistentRecord = { wow: 'cool' }

localRecord.update(nonExistentRecord, { wow: 'ok' })

// throws a ReferenceError if object does not exist in storage

Also, similar to ActiveRecord, you cannot update properties that don't exist on the object

const existingObject = { wow: 'cool' }
localRecord.create(existingObject)()

localRecord.update(existingObject, { ok: 'neat' })

// throws an UnknownPropertyError because 'ok' is not a property on existing object

If you want to add a property to an existing object, you must use the improvised...

.createProperty()

.createProperty() does not exist on ActiveRecord, but is included to allow users to further update an existing object in storage.

const existingObject = { wow: 'cool' }
localRecord.create(existingObject)()

// first argument is existing object
// second argument is properties you wish to add (can be more than 1)

const newObject = localRecord.createProperty(existingObject, { ok: 'neat', super: 'awesome' })

console.log(newObject)
// { wow: 'cool', ok: 'neat', super: 'awesome' }

.destroy()

.destroy() works exactly like you would expect:

const existingRecord = { wow: 'ok' }
localRecord.create(existingRecord)()

localRecord.destroy(existingRecord)
// returns { wow: 'ok' }
const nonExistentRecord = { wow: 'ok' }

localRecord.destroy(nonExistentRecord)
// throws a ReferenceError if record is not in storage

.destroyAll()

.destroyAll() also operates much like ActiveRecord's destroy_all

const firstRecord = { wow: 'ok' }
const secondRecord = { ok: 'neat' }
const thirdRecord = { super: 'awesome' }

localRecord.create(firstRecord)()
localRecord.create(secondRecord)()
localRecord.create(thirdRecord)()

localRecord.destroyAll()
// returns [ { wow: 'ok' }, { ok: 'neat' }, { super: 'awesome' }]

About

A lightweight ORM for localStorage

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published