Comparing version 1.5.0 to 1.5.1
{ | ||
"name": "delux", | ||
"version": "1.5.0", | ||
"version": "1.5.1", | ||
"description": "Beautiful, light and simple state manager inspired by Redux", | ||
"main": "bin/index.js", | ||
"main": "dist/index.js", | ||
"repository": { | ||
@@ -19,3 +19,3 @@ "type": "git", | ||
"start": "npm run build -- --watch", | ||
"build": "babel src --out-dir bin", | ||
"build": "babel src --out-dir dist", | ||
"test": "jest $2" | ||
@@ -26,7 +26,6 @@ }, | ||
"bugs": { | ||
"url": "https://github.com/aniddan/delux/issues" | ||
"url": "https://github.com/iddan/delux/issues" | ||
}, | ||
"homepage": "https://github.com/aniddan/delux", | ||
"homepage": "https://github.com/iddan/delux", | ||
"dependencies": { | ||
"es6-promise": "3.2.1", | ||
"flux-standard-action": "^0.6.1" | ||
@@ -36,14 +35,12 @@ }, | ||
"babel-cli": "^6.18.0", | ||
"babel-preset-es2015": "^6.14.0", | ||
"babel-eslint": "^7.1.1", | ||
"babel-preset-env": "^1.2.1", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"chai": "^3.5.0", | ||
"chokidar": "^1.6.1", | ||
"eslint": "^3.17.1", | ||
"eslint-config-fbjs": "^1.1.1", | ||
"eslint-plugin-babel": "^4.1.1", | ||
"jest": "^16.0.0" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015", | ||
"stage-0" | ||
] | ||
}, | ||
"jest": { | ||
@@ -50,0 +47,0 @@ "testEnvironment": "node" |
@@ -1,18 +0,18 @@ | ||
import {forceArray} from './utils'; | ||
import { forceArray } from './utils'; | ||
export default class Collection { | ||
reducers = {}; | ||
subscribers = []; | ||
constructor (init) { | ||
let set = ::this.set; | ||
Object.defineProperty(this, 'state', { | ||
get () { | ||
return Object.freeze(Object.assign({set}, init)); | ||
}, | ||
set (state) { | ||
init = state; | ||
return this.state; | ||
}, | ||
}); | ||
} | ||
reducers = {}; | ||
subscribers = []; | ||
constructor(init) { | ||
let { set } = this; | ||
Object.defineProperty(this, 'state', { | ||
get() { | ||
return Object.freeze(Object.assign({ set }, init)); | ||
}, | ||
set(state) { | ||
init = state; | ||
return this.state; | ||
}, | ||
}); | ||
} | ||
/** | ||
@@ -24,8 +24,8 @@ * Adds a reducer for specific action types. | ||
*/ | ||
on (types, reducer) { | ||
for (let type of forceArray(types)) { | ||
this.reducers[type] = reducer; | ||
} | ||
return this; | ||
} | ||
on = (types, reducer) => { | ||
for (let type of forceArray(types)) { | ||
this.reducers[type] = reducer; | ||
} | ||
return this; | ||
} | ||
/** | ||
@@ -36,5 +36,5 @@ * Mutates the current state with new data. | ||
*/ | ||
set (data) { | ||
return Object.assign(new this.state.constructor(), this.state, data); | ||
} | ||
set = (data) => { | ||
return Object.assign(new this.state.constructor(), this.state, data); | ||
} | ||
} |
import Store from './store'; | ||
import Collection from './collection'; | ||
require('es6-promise').polyfill(); | ||
export Collection from './collection'; | ||
module.exports = Store; | ||
module.exports.Collection = Collection; | ||
export default Store; |
@@ -1,12 +0,12 @@ | ||
import {getByKeys} from './utils'; | ||
import { getByKeys } from './utils'; | ||
export default class State { | ||
constructor (store) { | ||
for (let [name, collection] of store.collectionEntries) { | ||
this[name] = collection.state; | ||
} | ||
} | ||
get (names) { | ||
return getByKeys(this, names); | ||
} | ||
constructor(store) { | ||
for (let [name, collection] of store.collectionEntries) { | ||
this[name] = collection.state; | ||
} | ||
} | ||
get(names) { | ||
return getByKeys(this, names); | ||
} | ||
} |
166
src/store.js
@@ -1,5 +0,5 @@ | ||
import {isFSA} from 'flux-standard-action'; | ||
import { isFSA } from 'flux-standard-action'; | ||
import Collection from './collection'; | ||
import State from './state'; | ||
import {forceArray} from './utils'; | ||
import { forceArray } from './utils'; | ||
@@ -10,28 +10,28 @@ /** | ||
export default class Store { | ||
middlewares = []; | ||
queued = Promise.resolve(); | ||
middlewares = []; | ||
queued = Promise.resolve(); | ||
/** | ||
* object with mutations of the collections' states | ||
*/ | ||
get state () { | ||
return new State(this); | ||
} | ||
get state() { | ||
return new State(this); | ||
} | ||
/** | ||
* Array of the collection names. | ||
*/ | ||
get collectionNames () { | ||
return Object.keys(this).filter(key => this[key] instanceof Collection); | ||
} | ||
get collectionNames() { | ||
return Object.keys(this).filter(key => this[key] instanceof Collection); | ||
} | ||
/** | ||
* Array of the collection objects. | ||
*/ | ||
get collections () { | ||
return Object.values(this).filter(value => value instanceof Collection); | ||
} | ||
get collections() { | ||
return Object.values(this).filter(value => value instanceof Collection); | ||
} | ||
/** | ||
* Array of the collections entries. | ||
*/ | ||
get collectionEntries () { | ||
return Object.entries(this).filter((entry) => entry[1] instanceof Collection); | ||
} | ||
get collectionEntries() { | ||
return Object.entries(this).filter((entry) => entry[1] instanceof Collection); | ||
} | ||
/** | ||
@@ -43,22 +43,22 @@ * Adds an observer for mutations in the store's collections | ||
*/ | ||
use (middleware) { | ||
const [arg0, arg1] = arguments; | ||
this.middlewares.push({ | ||
// store.use(function) | ||
function: middleware, | ||
// store.use(string, function) | ||
string (action) { | ||
if (action.type === arg0) { | ||
return arg1(action); | ||
} | ||
}, | ||
// store.use(object) | ||
object (action) { | ||
if (arg0[action.type]) { | ||
return arg0[action.type](action); | ||
} | ||
} | ||
}[typeof arg0]); | ||
return this; | ||
} | ||
use(middleware) { | ||
const [arg0, arg1] = arguments; | ||
this.middlewares.push({ | ||
// store.use(function) | ||
function: middleware, | ||
// store.use(string, function) | ||
string(action) { | ||
if (action.type === arg0) { | ||
return arg1(action); | ||
} | ||
}, | ||
// store.use(object) | ||
object(action) { | ||
if (arg0[action.type]) { | ||
return arg0[action.type](action); | ||
} | ||
}, | ||
}[typeof arg0]); | ||
return this; | ||
} | ||
/** | ||
@@ -69,36 +69,36 @@ * Dispatches a Flux Standard Action on the state. | ||
*/ | ||
dispatch (action) { | ||
const {middlewares, collectionEntries} = this; | ||
if (!isFSA(action)) { | ||
throw new TypeError('Dispatched action must follow the Flux Standard Action scheme. https://github.com/acdlite/flux-standard-action'); | ||
} | ||
// wait for the middlewares to mutate the actions | ||
for (let middleware of middlewares) { | ||
this.queue(() => Promise.resolve(middleware(action))); | ||
} | ||
return this.queue(() => | ||
Promise.all( | ||
collectionEntries.map(([name, collection]) => { | ||
let {state, reducers, subscribers} = collection; | ||
if (!reducers[action.type]) { | ||
return Promise.resolve(); | ||
} | ||
return Promise.resolve(reducers[action.type](state, action)) | ||
.then((newCollectionState = state) => { | ||
if (newCollectionState !== state) { | ||
collection.state = newCollectionState; | ||
for (let subscriber of subscribers) { | ||
subscriber(this.state, action, name); | ||
} | ||
} | ||
return newCollectionState; | ||
}); | ||
}) | ||
) | ||
.then(() => this.state) | ||
.catch(err => { | ||
throw err; | ||
}) | ||
); | ||
} | ||
dispatch(action) { | ||
const { middlewares, collectionEntries } = this; | ||
if (!isFSA(action)) { | ||
throw new TypeError('Dispatched action must follow the Flux Standard Action scheme. https://github.com/acdlite/flux-standard-action'); | ||
} | ||
// wait for the middlewares to mutate the actions | ||
for (let middleware of middlewares) { | ||
this.queue(() => Promise.resolve(middleware(action))); | ||
} | ||
return this.queue(() => | ||
Promise.all( | ||
collectionEntries.map(([name, collection]) => { | ||
let { state, reducers, subscribers } = collection; | ||
if (!reducers[action.type]) { | ||
return Promise.resolve(); | ||
} | ||
return Promise.resolve(reducers[action.type](state, action)) | ||
.then((newCollectionState = state) => { | ||
if (newCollectionState !== state) { | ||
collection.state = newCollectionState; | ||
for (let subscriber of subscribers) { | ||
subscriber(this.state, action, name); | ||
} | ||
} | ||
return newCollectionState; | ||
}); | ||
}) | ||
) | ||
.then(() => this.state) | ||
.catch(err => { | ||
throw err; | ||
}) | ||
); | ||
} | ||
/** | ||
@@ -110,7 +110,7 @@ * Subscribes for mutations in the store's collections. | ||
*/ | ||
subscribe (collectionNames, subscriber) { | ||
for (let name of forceArray(collectionNames)) { | ||
this[name].subscribers.push(subscriber); | ||
} | ||
} | ||
subscribe(collectionNames, subscriber) { | ||
for (let name of forceArray(collectionNames)) { | ||
this[name].subscribers.push(subscriber); | ||
} | ||
} | ||
/** | ||
@@ -122,7 +122,7 @@ * Unsubscribes the subscriber function provided for the collections. | ||
*/ | ||
unsubscribe (collectionNames, subscriber) { | ||
for (let name of forceArray(collectionNames)) { | ||
this[name].subscribers = this[name].subscribers.filter(func => func === subscriber); | ||
} | ||
} | ||
unsubscribe(collectionNames, subscriber) { | ||
for (let name of forceArray(collectionNames)) { | ||
this[name].subscribers = this[name].subscribers.filter(func => func === subscriber); | ||
} | ||
} | ||
/** | ||
@@ -133,5 +133,5 @@ * Adds a function to the store's execute queue | ||
*/ | ||
queue (action) { | ||
return this.queued = this.queued.then(action); | ||
} | ||
queue(action) { | ||
return this.queued = this.queued.then(action); | ||
} | ||
} |
/* globals it */ | ||
const {expect} = require('chai'); | ||
import { expect } from 'chai'; | ||
const Store = require('..'); | ||
const {Collection} = Store; | ||
import Store, { Collection } from '..'; | ||
// it ('mutates the store state', () => { | ||
const store = new Store; | ||
const store = new Store(); | ||
// collections are sub classes with init | ||
store.images = new Store.Collection({}); | ||
store.people = new Collection({}); | ||
// collections are sub classes with init | ||
store.images = new Store.Collection({}); | ||
store.people = new Collection({}); | ||
// FETCH MIDDLEWARE | ||
// FETCH MIDDLEWARE | ||
store.use(action => { | ||
return fetch(action.payload.request) | ||
.then(response => { | ||
action.payload.response = response; | ||
}); | ||
}); | ||
store.use(action => { | ||
return fetch(action.payload.request) | ||
.then(response => { | ||
action.payload.response = response; | ||
}); | ||
}); | ||
// MIDDLEWARES ACCURE IN ORDER | ||
// MIDDLEWARES ACCURE IN ORDER | ||
store.use(action => { | ||
return action.payload.response.json().then(response => { | ||
action.payload.response = response; | ||
}); | ||
}); | ||
store.use(action => { | ||
return action.payload.response.json().then(response => { | ||
action.payload.response = response; | ||
}); | ||
}); | ||
// gets state from a getter | ||
store.images.on('getAllImages', (state, action) => { | ||
for (let image of action.payload.response) { | ||
state = state.set({ | ||
[image.id]: image | ||
}); | ||
} | ||
return state; | ||
}); | ||
// gets state from a getter | ||
store.images.on('getAllImages', (state, action) => { | ||
for (let image of action.payload.response) { | ||
state = state.set({ | ||
[image.id]: image | ||
}); | ||
} | ||
return state; | ||
}); | ||
// don't worry you can do this | ||
store.images.on(['removeAllImages'], (state) => { | ||
for (let key in state) { | ||
state = state.set({ | ||
[key]: undefined | ||
}); | ||
} | ||
return state; | ||
}); | ||
// don't worry you can do this | ||
store.images.on(['removeAllImages'], (state) => { | ||
for (let key in state) { | ||
state = state.set({ | ||
[key]: undefined | ||
}); | ||
} | ||
return state; | ||
}); | ||
// flux actions, so pretty | ||
store.dispatch({ | ||
type: 'getAllImages', | ||
payload: { | ||
request: { | ||
url: 'kjfkdjfkjdf', | ||
method: 'get' | ||
}, | ||
} | ||
}); | ||
// flux actions, so pretty | ||
store.dispatch({ | ||
type: 'getAllImages', | ||
payload: { | ||
request: { | ||
url: 'kjfkdjfkjdf', | ||
method: 'get' | ||
}, | ||
} | ||
}); | ||
// look at these results! | ||
store.subscribe('images', (state) => expect(state.images.foo).to.deep.equal({ | ||
id: 'foo', | ||
image_url: 'http://bar.com' | ||
})); | ||
// look at these results! | ||
store.subscribe('images', (state) => expect(state.images.foo).to.deep.equal({ | ||
id: 'foo', | ||
image_url: 'http://bar.com' | ||
})); | ||
store.subscribe('images', (state) => expect(state.get('images')).to.deep.equal({images: state.images})); | ||
store.subscribe('images', (state) => expect(state.get('images')).to.deep.equal({ images: state.images })); | ||
// }); | ||
const fetch = () => Promise.resolve({ | ||
json: () => Promise.resolve([{ | ||
id: 'foo', | ||
image_url: 'http://bar.com' | ||
}]) | ||
json: () => Promise.resolve([{ | ||
id: 'foo', | ||
image_url: 'http://bar.com' | ||
}]) | ||
}); |
/* globals it */ | ||
const {expect} = require('chai'); | ||
const Store = require('..'); | ||
import { expect } from 'chai'; | ||
import Store, { Collection } from '..'; | ||
let store = new Store(); | ||
let images = new Store.Collection([]); | ||
let people = new Store.Collection({}); | ||
let images = new Collection([]); | ||
let people = new Collection({}); | ||
it('should detect added collections', () => { | ||
expect(store.collections.length).to.equal(0); | ||
store.images = images; | ||
expect(store.collections.length).to.equal(1); | ||
store.people = people; | ||
expect(store.collections.length).to.equal(2); | ||
expect(store.collections.length).to.equal(0); | ||
store.images = images; | ||
expect(store.collections.length).to.equal(1); | ||
store.people = people; | ||
expect(store.collections.length).to.equal(2); | ||
}); | ||
it('should have frozen state', () => { | ||
expect(Object.isFrozen(images.state)).to.be.true; | ||
expect(Object.isFrozen(images.state)).to.be.true; | ||
}); |
/* globals it */ | ||
const {expect} = require('chai'); | ||
const Store = require('..'); | ||
import { expect } from 'chai'; | ||
import Store from '..'; | ||
@@ -8,12 +8,12 @@ let store = new Store(); | ||
it('should add a middleware', () => { | ||
expect(store.middlewares.length).to.equal(0); | ||
store.use((action) => { | ||
action.passedMiddleware = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(1); | ||
expect(store.middlewares.length).to.equal(0); | ||
store.use((action) => { | ||
action.passedMiddleware = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(1); | ||
}); | ||
it('should apply middlewares', () => { | ||
store.use((action) => expect(action.passedMiddleware).to.be.true); | ||
store.dispatch({type: 'test'}); | ||
store.use((action) => expect(action.passedMiddleware).to.be.true); | ||
store.dispatch({ type: 'test' }); | ||
}); |
/* globals it */ | ||
const {expect} = require('chai'); | ||
const Store = require('..'); | ||
import {expect} from 'chai'; | ||
import Store from '..'; | ||
@@ -5,0 +5,0 @@ let store = new Store(); |
/* eslint-disable no-console */ | ||
/* globals it */ | ||
const Store = require('..'); | ||
const {expect} = require('chai'); | ||
import Store from '..'; | ||
import { expect } from 'chai'; | ||
let store = new Store; | ||
let store = new Store(); | ||
it('adds one middleware', () => { | ||
store.use((action) => { | ||
console.log(action); | ||
action.general = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(1); | ||
store.use((action) => { | ||
console.log(action); | ||
action.general = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(1); | ||
}); | ||
it('adds another middleware', () => { | ||
store.use('hop', (action) => { | ||
action.hip = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(2); | ||
store.use('hop', (action) => { | ||
action.hip = true; | ||
}); | ||
expect(store.middlewares.length).to.equal(2); | ||
}); | ||
it('adds one more middleware', () => { | ||
store.use({ | ||
addLove (action) { | ||
action.love = 1; | ||
} | ||
}); | ||
expect(store.middlewares.length).to.equal(3); | ||
store.use({ | ||
addLove(action) { | ||
action.love = 1; | ||
} | ||
}); | ||
expect(store.middlewares.length).to.equal(3); | ||
}); | ||
it('applies middlewares', () => { | ||
store.use(action => { | ||
if (action.type === 'hop') { | ||
expect(action.hip).to.be.true; | ||
expect(action.general).to.be.true; | ||
} | ||
else if (action.type === 'addLove') { | ||
expect(action.addLove).to.be.equal(1); | ||
expect(action.general).to.be.true; | ||
} | ||
}); | ||
store.dispatch({ | ||
type: 'hop' | ||
}); | ||
store.dispatch({ | ||
type: 'addLove' | ||
}); | ||
store.use(action => { | ||
if (action.type === 'hop') { | ||
expect(action.hip).to.be.true; | ||
expect(action.general).to.be.true; | ||
} | ||
else if (action.type === 'addLove') { | ||
expect(action.addLove).to.be.equal(1); | ||
expect(action.general).to.be.true; | ||
} | ||
}); | ||
store.dispatch({ | ||
type: 'hop' | ||
}); | ||
store.dispatch({ | ||
type: 'addLove' | ||
}); | ||
}); |
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
157397
1
24
10
749
- Removedes6-promise@3.2.1
- Removedes6-promise@3.2.1(transitive)