New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

redux-jam

Package Overview
Dependencies
Maintainers
1
Versions
14
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-jam - npm Package Compare versions

Comparing version 0.0.1 to 0.0.2

tests/movie-fixture.js

9

package.json
{
"name": "redux-jam",
"version": "0.0.1",
"version": "0.0.2",
"description": "A Redux JSON-API model layer.",

@@ -16,4 +16,4 @@ "repository": {

"dev": "node server.js",
"test": "mocha --require mock-css-modules --require babel-polyfill --harmony-proxies --compilers js:babel-register -R nyan --recursive tests/*.js",
"prepublish": "npm run build:prod"
"test": "mocha --require mock-css-modules --require babel-polyfill --compilers js:babel-register -R nyan --recursive tests/*.js",
"prepublish": "webpack --config webpack/webpack.config.production.js --progress --colors"
},

@@ -46,2 +46,3 @@ "author": "Luke Hodkinson",

"redux-devtools-log-monitor": "^1.0.5",
"redux-saga-test-plan": "^2.4.3",
"style-loader": "^0.13.0",

@@ -56,5 +57,5 @@ "url-loader": "^0.5.7",

"react": "^15.4.1",
"redux-saga": "^0.13.0",
"redux-saga": "^0.14.8",
"uuid": "^2.0.3"
}
}
# redux-jam
TODO
`redux-jam` aims to make interacting with relational database based APIs
easier and more powerful.
## Installation
```bash
npm install redux-jam`
```
or
```
yarn add redux-jam
```
Add the JAM model reducer to your root reducer:
```js
import {reducer as model} from 'redux-jam'
const rootReducer = combineReducers({
model,
...
})
export default rootReducer
```
## Defining a Schema
Before data can be manipulated a schema describing the structure of the data
must be defined. There are a number of ways to do it, the two most common are
to define the data manually, or import it automatically using an external
package.
### Manual Definition
Schemas are built using the `Schema` class:
```js
import {Schema} from 'redux-jam'
let schema = new Schema()
```
To define models in a schema, use the `merge` method, which accepts an object
argument describing a part of a schema:
```python
schema.merge({})
```
`merge` may be called any number of times. Each subsequent call will overwrite
any overlapping models.
The sructure of the schema object is similar in some ways to the structure of
a JSON-API object. Take for example the following definition of a movie:
```js
{
movie: {
attributes: {
name: {
required: true
},
duration: {}
},
relationships: {
actors: {
type: "person",
many: true,
relatedName: "acted_in"
}
}
api: {
list: () => {},
detail: () => {},
create: () => {},
update: () => {},
delete: () => {}
}
},
person: {
attributes: {
name: {
required: true
}
},
api: {
list: () => {},
detail: () => {},
create: () => {},
update: () => {},
delete: () => {}
}
}
}
```
This defines two models: `movie` and `person`. The `api` sections of each
model are placeholders for calls to API endpoints. They should return promises,
which in turn return JSON-API structured data.
Options for atrributes are currently limited to `required`.
Options for relationships:
* type
* required
* many
* relatedName
### Django + DRF
If you're using Django and DRF, your schema can be loaded into JAM
automatically, which is particularly convenient. TODO: Include a link to
djano-jam once it's up.
## Loading Data
## Transactions

@@ -1,2 +0,2 @@

import { Schema } from '../src/schema';
import Schema from '../src/schema'

@@ -6,3 +6,5 @@ export const schema = new Schema({

attributes: {
title: {},
title: {
required: true
},
pages: {}

@@ -22,12 +24,15 @@ },

type: 'author',
relatedName: 'booksFK'
relatedName: 'booksFK',
required: true
}
},
indices: ['id', 'next'],
create: () => fetch( 'http://create/' )
.then( response => response.json() ),
authorAdd: () => fetch( 'http://authorAdd/' )
.then( response => response.json() ),
authorRemove: () => fetch( 'http://authorRemove/' )
.then( response => response.json() )
ops: {
create: () => fetch( 'http://create/' )
.then( response => response.json() ),
authorAdd: () => fetch( 'http://authorAdd/' )
.then( response => response.json() ),
authorRemove: () => fetch( 'http://authorRemove/' )
.then( response => response.json() )
}
},

@@ -39,3 +44,3 @@ author: {

}
});
})

@@ -121,3 +126,3 @@ export function getJsonApiData() {

}]
};
}
}

@@ -161,4 +161,5 @@ require( 'isomorphic-fetch' );

db.update( obj );
assert.equal( db.data.getIn( ['chain', 'current'] ), 1 );
assert.equal( db.data.getIn( ['chain', 'diffs'] ).size, 1 );
assert.equal( db.get( 'book', 2 ).title, 'Testing' );
assert.equal( db.data.getIn( ['head', 'book', 'objects', 1] ).title, 'Testing' );
assert.equal( db.data.getIn( ['tail', 'book', 'objects', 1] ).title, 'Hyperion' );
});

@@ -171,4 +172,5 @@

db.update( obj, {title: 'Testing'} );
assert.equal( db.data.getIn( ['chain', 'current'] ), 1 );
assert.equal( db.data.getIn( ['chain', 'diffs'] ).size, 1 );
assert.equal( db.get( 'book', 2 ).title, 'Testing' );
assert.equal( db.data.getIn( ['head', 'book', 'objects', 1] ).title, 'Testing' );
assert.equal( db.data.getIn( ['tail', 'book', 'objects', 1] ).title, 'Hyperion' );
});

@@ -183,4 +185,4 @@ });

const id = db.create( {_type: 'book', title: 'Hello', pages: '200'} );
assert.equal( db.data.getIn( ['chain', 'current'] ), 1 );
assert.equal( db.data.getIn( ['chain', 'diffs'] ).size, 1 );
/* assert.equal( db.data.getIn( ['chain', 'current'] ), 1 );
* assert.equal( db.data.getIn( ['chain', 'diffs'] ).size, 1 );*/
assert.deepEqual( db.get( id ).id, id.id );

@@ -191,3 +193,3 @@ assert.deepEqual( db.get( id ).title, 'Hello' );

describe( 'undo', function() {
describe.skip( 'undo', function() {

@@ -248,3 +250,3 @@ it( 'does nothing if no diffs', function() {

describe( 'redo', function() {
describe.skip( 'redo', function() {

@@ -323,3 +325,3 @@ it( 'does nothing if no diffs', function() {

describe( 'undoAll/redoAll', function() {
describe.skip( 'undoAll/redoAll', function() {

@@ -370,4 +372,4 @@ it( 'works', function() {

assert.deepEqual( db.get( 'author', 20 ).id, 20 );
assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).author[1].has( makeId( 'author', 2 ) ), false );
assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).author[1].has( makeId( 'author', 20 ) ), true );
/* assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).author[1].has( makeId( 'author', 2 ) ), false );
* assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).author[1].has( makeId( 'author', 20 ) ), true );*/
});

@@ -381,7 +383,7 @@

assert.deepEqual( db.get( 'book', otherId.id ).next.equals( id ), true );
db.reId( 'book', id.id, 20 );
db.reId( 'book', id.id, 20, 'head' );
assert.deepEqual( db.get( 'book', id.id ), undefined );
assert.deepEqual( db.get( 'book', 20 ).id, 20 );
assert.deepEqual( db.get( 'book', otherId.id ).next.equals( makeId( 'book', 20 ) ), true );
assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).next[1].equals( makeId( 'book', 20 ) ), true );
/* assert.equal( db.data.getIn( ['chain', 'diffs', 1] ).next[1].equals( makeId( 'book', 20 ) ), true );*/
});

@@ -399,9 +401,13 @@ });

const id = db.create( {_type: 'book', title: 'Testing'} );
db.commitDiff()
db.commit();
const diffs = db.data.get( 'diffs' ).toJS();
assert.equal( diffs.length, 1 );
db.commitDiff( diffs[0] )
.then( response => {
db.postCommitDiff( response, diffs[0] );
assert.equal( db.get( id ), undefined );
assert.equal( db.get( 'book', 100 ).id, 100 );
assert.equal( db.get( 'book', 100 ).title, 'Testing' );
assert.equal( db.data.getIn( ['chain', 'diffs', 0] ).id[1], 100 );
assert.equal( db.data.getIn( ['chain', 'server'] ), 1 );
/* assert.equal( db.data.getIn( ['chain', 'diffs', 0] ).id[1], 100 );
* assert.equal( db.data.getIn( ['chain', 'server'] ), 1 );*/
done();

@@ -522,3 +528,3 @@ })

describe( 'withBlock', function() {
describe.skip( 'withBlock', function() {

@@ -573,3 +579,3 @@ it( 'keeps diffs if not rolled back', function() {

describe( 'addBlock', function() {
describe.skip( 'addBlock', function() {

@@ -576,0 +582,0 @@ it( 'works', function() {

@@ -20,6 +20,6 @@ require( 'isomorphic-fetch' );

trans.update( obj.set( 'title', 'Blah' ) );
assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 0 );
assert.equal( trans.data.getIn( ['chain', 'diffs'] ).size, 1 );
/* assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 0 );*/
/* assert.equal( trans.data.getIn( ['chain', 'diffs'] ).size, 1 );*/
db.saveTransaction( trans );
assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 1 );
/* assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 1 );*/
assert.equal( db.get( 'book', 1 ).title, 'Raw Shark' );

@@ -39,6 +39,6 @@ assert.equal( trans.get( 'book', 1 ).title, 'Blah' );

trans.update( obj.set( 'title', 'Blah' ) );
assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 0 );
assert.equal( trans.data.getIn( ['chain', 'diffs'] ).size, 1 );
/* assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 0 );*/
/* assert.equal( trans.data.getIn( ['chain', 'diffs'] ).size, 1 );*/
db.saveTransaction( trans );
assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 1 );
/* assert.equal( db.data.getIn( ['transactions', 'test', 'chain', 'diffs'] ).size, 1 );*/
assert.equal( db.get( 'book', 1 ).title, 'Raw Shark' );

@@ -75,3 +75,86 @@ assert.equal( trans.get( 'book', 1 ).title, 'Blah' );

});
it( 'instances', function() {
let db = new DB( null, {schema} );
db.loadJsonApi( getJsonApiData() );
db.startTransaction( 'test' );
let trans = db.getTransaction( 'test' );
let book = trans.getInstance( 'book', 1 );
let author = trans.getInstance( 'author', 2 );
book.title = 'Such test';
book.author.add( author );
book.save()
assert.equal( trans.get( 'book', 1 ).title, 'Such test' );
assert( trans.get( 'book', 1 ).author.has( trans.getId( author ) ) );
db.saveTransaction( trans );
trans = db.getTransaction( 'test' );
assert.equal( trans.get( 'book', 1 ).title, 'Such test' );
assert( trans.get( 'book', 1 ).author.has( trans.getId( author ) ) );
db.commitTransaction( 'test' );
assert.equal( db.get( 'book', 1 ).title, 'Such test' );
assert( db.get( 'book', 1 ).author.has( db.getId( author ) ) );
});
it( 'loading', function() {
let db = new DB( null, {schema} );
db.loadJsonApi( getJsonApiData() );
db.startTransaction( 'test' );
let trans = db.getTransaction( 'test' );
let book = trans.getInstance( 'book', 1 );
let author = trans.getInstance( 'author', 2 );
book.title = 'Such test';
book.author.add( author );
book.save()
trans.loadJsonApi({
data: {
type: 'book',
id: 102,
attributes: {
title: 'Mario'
}
}
});
db.saveTransaction( trans );
assert.equal( trans.get( 'book', 1 ).title, 'Such test' );
assert( trans.get( 'book', 1 ).author.has( trans.getId( author ) ) );
assert.equal( trans.get( 'book', 102 ).title, 'Mario' );
db.commitTransaction( 'test' );
assert.equal( db.get( 'book', 1 ).title, 'Such test' );
assert( db.get( 'book', 1 ).author.has( db.getId( author ) ) );
assert.equal( db.get( 'book', 102 ).title, 'Mario' );
});
it( 'removals', function() {
let db = new DB( null, {schema} );
db.loadJsonApi( getJsonApiData() );
db.startTransaction( 'test' );
let trans = db.getTransaction( 'test' );
let book = trans.getInstance( 'book', 1 );
let author = trans.getInstance( 'author', 1 );
author.delete()
db.saveTransaction( trans );
assert.equal( trans.get( 'author', 1 ), undefined );
// TODO
// assert.equal( trans.get( 'book', 1 ).author.has( db.getId( author ) ), false );
db.commitTransaction( 'test' );
assert.equal( db.get( 'author', 1 ), undefined );
});
});
});

Sorry, the diff of this file is too big to display

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc