Comparing version 1.1.0 to 1.2.0
{ | ||
"name": "delux", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "Beautiful, light and simple state manager inspired by Redux", | ||
"main": "index.js", | ||
"main": "src/index.js", | ||
"repository": { | ||
@@ -18,3 +18,5 @@ "type": "git", | ||
"scripts": { | ||
"test": "node test.js" | ||
"start": "webpack --watch", | ||
"build": "webpack", | ||
"test": "npm build && node test" | ||
}, | ||
@@ -28,5 +30,17 @@ "author": "Iddan Aharonson <mail@iddan.co> (http://iddan.co)", | ||
"dependencies": { | ||
"es6-promise": "3.2.1", | ||
"proxy-polyfill": "^0.1.6" | ||
"es6-promise": "3.2.1" | ||
}, | ||
"devDependencies": { | ||
"babel-core": "^6.14.0", | ||
"babel-loader": "^6.2.5", | ||
"babel-preset-es2015": "^6.14.0", | ||
"babel-preset-stage-0": "^6.5.0", | ||
"webpack": "^1.13.2" | ||
}, | ||
"babel": { | ||
"presets": [ | ||
"es2015", | ||
"stage-0" | ||
] | ||
} | ||
} |
@@ -18,3 +18,3 @@ <h1> | ||
store.tasks.on('addTask', (action, state) => state.push({ | ||
store.tasks.on('addTask', (tasks, action) => tasks.concat({ | ||
name: action.payload, | ||
@@ -28,6 +28,11 @@ completed: false | ||
type: 'addTask', | ||
payload: 'Try Redux' | ||
payload: 'Try Delux' | ||
}); | ||
``` | ||
## Motivation | ||
``` | ||
- In Flux there's a design flaw: it's hard to manage several stores. | ||
- So came Redux with one store. | ||
- But: Redux lacks a defined API | ||
## Features | ||
@@ -40,5 +45,4 @@ | ||
- [Ordered middlewares][Express Middlewares] | ||
- [No switches nor returns required][Redux Reducers] | ||
- [No switches or combinations required][Redux Reducers] | ||
## API Reference | ||
@@ -116,2 +120,12 @@ | ||
##### Store.prototype.queue() | ||
Adds a function to the store's execute queue | ||
```JavaScript | ||
store.queue(() => callback()); | ||
``` | ||
###### Parameters | ||
### Collection | ||
@@ -137,3 +151,3 @@ | ||
Returns a new mutation of the collections's state | ||
Reflects the collections's state | ||
@@ -144,2 +158,6 @@ ###### Collection.prototype.reducers | ||
###### Collection.prototype.observers | ||
Reflects the collections's observers | ||
##### Methods | ||
@@ -152,3 +170,3 @@ | ||
```JavaScript | ||
store.collectionName.on(['actionType'], (action, state) => { | ||
store.collectionName.on(['actionType'], (state, action) => { | ||
@@ -161,3 +179,3 @@ }); | ||
- **types | type** - array of action types or a single type to apply the reducer on | ||
- **reducer** - a function that with a given action mutates the collection state. The arguments to the function are as follows: | ||
- **reducer** - a function that with a given action mutates the collection state and returns the new state. The arguments to the function are as follows: | ||
@@ -167,4 +185,4 @@ | ||
|--------|-----------------------| | ||
| state | The collection state | | ||
| action | The dispatched action | | ||
| state | The collection state | | ||
@@ -171,0 +189,0 @@ [Delux Logo]: https://cdn.rawgit.com/aniddan/delux/master/assets/delux.svg |
@@ -1,22 +0,15 @@ | ||
const ArrayTree = require('./arraytree'); | ||
const validateArray = require('./validate-array'); | ||
import {ensureArray} from './utils'; | ||
module.exports = class Collection { | ||
constructor (init = {}) { | ||
let states = [init]; | ||
let reducers = new ArrayTree({multiple: false}); | ||
Object.defineProperties(this, { | ||
on: {value: (types, reducer) => { | ||
reducers.set(validateArray(types), reducer); | ||
return this; | ||
}}, | ||
state: {get: () => { | ||
let length = states.length; | ||
let last = Object.freeze(states[length - 1]); | ||
states.push(Object.assign(last.constructor(), last)); | ||
return states[length]; | ||
}}, | ||
reducers: {get: () => ArrayTree.toImmutable(reducers)} | ||
}); | ||
export default class Collection { | ||
reducers = {}; | ||
observers = []; | ||
constructor (init) { | ||
this.state = init; | ||
} | ||
}; | ||
on (types, reducer) { | ||
types = ensureArray(types); | ||
for (let type of types) { | ||
this.reducers[type] = reducer; | ||
} | ||
} | ||
} |
102
src/store.js
@@ -1,68 +0,29 @@ | ||
const Collection = require('./collection'); | ||
const ArrayTree = require('./arraytree'); | ||
const validateArray = require('./validate-array'); | ||
import Collection from './collection'; | ||
import {ensureArray} from './utils'; | ||
module.exports = class Store { | ||
constructor () { | ||
let middlewares = []; | ||
let observers = new ArrayTree; | ||
Object.defineProperties(this, { | ||
queue: { | ||
value: Promise.resolve(), | ||
writable: true | ||
}, | ||
middlewares: { | ||
get: () => Object.assign([], middlewares) | ||
}, | ||
observers: { | ||
get: () => ArrayTree.toImmutable(observers) | ||
}, | ||
use: { | ||
value: (middleware) => { | ||
middlewares.push(middleware); | ||
return this; | ||
} | ||
}, | ||
observe: { | ||
value: (collections, observer) => { | ||
observers.set(validateArray(collections), observer); | ||
return this; | ||
} | ||
} | ||
}); | ||
export default class Store { | ||
middlewares = []; | ||
queued = Promise.resolve(); | ||
state = {}; | ||
use (middleware) { | ||
this.middlewares.push(middleware); | ||
} | ||
get state () { | ||
let state = {}; | ||
for (let key in this) { | ||
Object.defineProperty(state, key, { | ||
get: () => { | ||
let value = this[key]; | ||
if (value instanceof Collection) { | ||
return value.state; | ||
} | ||
else { | ||
return value; | ||
} | ||
}, | ||
enumerable: true | ||
}); | ||
dispatch (action) { | ||
for (let middleware of this.middlewares) { | ||
this.queue(() => Promise.resolve(middleware(action))); | ||
} | ||
return state; | ||
} | ||
dispatch (action) { | ||
this.queue = this.queue.then(applyMiddlewares.bind(this, action)) | ||
.then(action => { | ||
for (let collection_name in this) { | ||
let collection = this[collection_name]; | ||
this.queue(() => { | ||
for (let name in this) { | ||
let collection = this[name]; | ||
if (collection instanceof Collection) { | ||
let {state, reducers} = collection; | ||
let reducer = reducers.get(action.type); | ||
if (reducer) { | ||
Promise.resolve(reducer.call(this, action, state)) | ||
.then(() => { | ||
for (let observer of this.observers.get(collection_name)) { | ||
observer(this.state); | ||
let oldState = collection.state; | ||
Promise.resolve(collection.reducers[action.type](oldState, action)) | ||
.then((newState = oldState) => { | ||
if (newState !== oldState) { | ||
collection.state = newState; | ||
for (let observer of collection.observers) { | ||
observer(Object.assign(this.state, {[name]: newState}), action, name); | ||
} | ||
}); | ||
} | ||
} | ||
}); | ||
} | ||
@@ -72,12 +33,11 @@ } | ||
} | ||
}; | ||
function applyMiddlewares (action) { | ||
let middlewares_queue = Promise.resolve(); | ||
for (let middleware of this.middlewares) { | ||
middlewares_queue = middlewares_queue.then(middleware.bind(this, action)); | ||
observe (collectionNames, observer) { | ||
collectionNames = ensureArray(collectionNames); | ||
for (let name of collectionNames) { | ||
this[name].observers.push(observer); | ||
} | ||
} | ||
return middlewares_queue.then(() => action); | ||
queue (callback) { | ||
this.queued = this.queued.then(callback); | ||
} | ||
} | ||
module.exports.Collection = Collection; |
10
test.js
@@ -1,2 +0,2 @@ | ||
const Store = require('.'); | ||
const Store = require('./lib/index'); | ||
const {Collection} = Store; | ||
@@ -35,13 +35,15 @@ | ||
// gets state from a getter | ||
store.images.on('getAllImages', (action, state) => { | ||
store.images.on('getAllImages', (state, action) => { | ||
for (let image of action.payload.response) { | ||
state[image.id] = image; | ||
} | ||
return Object.assign({}, state); | ||
}); | ||
// don't worry you can do this | ||
store.images.on(['removeAllImages'], (action, state) => { | ||
store.images.on(['removeAllImages'], (state) => { | ||
for (let key in state) { | ||
delete state[key]; | ||
} | ||
return Object.assign({}, state); | ||
}); | ||
@@ -51,3 +53,3 @@ | ||
store.observe('images', (state) => console.log(state.images)); | ||
store.observe(['images'], (state) => console.log(state.images)); | ||
store.observe(['images'], (state, action) => console.log(state.images)); | ||
@@ -54,0 +56,0 @@ // flux actions, so pretty |
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
Uses eval
Supply chain riskPackage uses dynamic code execution (e.g., eval()), which is a dangerous practice. This can prevent the code from running in certain environments and increases the risk that the code may contain exploits or malicious behavior.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
62581
1
13
1399
189
5
2
3
- Removedproxy-polyfill@^0.1.6
- Removedproxy-polyfill@0.1.7(transitive)