Comparing version 3.1.0 to 4.0.0
254
lib/index.js
@@ -1,253 +0,1 @@ | ||
/* fluxury - Copyright 2015 JC Fisher */ | ||
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { | ||
value: true | ||
}); | ||
exports.dispatch = undefined; | ||
var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; | ||
exports.subscribe = subscribe; | ||
exports.promiseAction = promiseAction; | ||
exports.replaceState = replaceState; | ||
exports.getState = getState; | ||
exports.getStores = getStores; | ||
exports.createStore = createStore; | ||
var _Dispatcher = require('./Dispatcher'); | ||
var _Dispatcher2 = _interopRequireDefault(_Dispatcher); | ||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | ||
var rootState = Object.freeze({}), | ||
stores = {}, | ||
dispatcher = new _Dispatcher2.default(), | ||
waitFor = dispatcher.waitFor.bind(dispatcher), | ||
rootListeners = [], | ||
rootNextListeners = []; | ||
function copyIfSame(current, next) { | ||
if (current === next) return current.slice(); | ||
return next; | ||
} | ||
function updateRootState(name, newState) { | ||
var changes = {}; | ||
changes[name] = (typeof newState === 'undefined' ? 'undefined' : _typeof(newState)) === 'object' ? Object.freeze(newState) : newState; | ||
rootState = Object.assign({}, rootState, changes); | ||
} | ||
function rootNotify(action) { | ||
// notify root listeners | ||
var listeners = rootListeners = rootNextListeners; | ||
for (var i = 0; i < listeners.length; i++) { | ||
var listener = listeners[i]; | ||
listener(rootState, action); | ||
} | ||
} | ||
function subscribe(cb) { | ||
if (typeof cb !== 'function') { | ||
throw "Listener must be a function"; | ||
} | ||
// avoid mutating list that could be iterating during dispatch | ||
var subscribed = true; | ||
rootNextListeners = copyIfSame(rootListeners, rootNextListeners); | ||
rootNextListeners.push(cb); | ||
return function () { | ||
if (!subscribed) return; | ||
subscribed = false; | ||
rootNextListeners = copyIfSame(rootListeners, rootNextListeners); | ||
var index = rootNextListeners.indexOf(cb); | ||
rootNextListeners.splice(index, 1); | ||
}; | ||
} | ||
function promiseAction(type, data) { | ||
return Promise.resolve({ type: type, data: data }); | ||
} | ||
function replaceState(newState) { | ||
rootState = newState; | ||
} | ||
function _dispatch(action, data) { | ||
try { | ||
if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object' && typeof action.then === 'function') { | ||
return action.then(function (result) { | ||
_dispatch(result); | ||
return Promise.resolve(result); | ||
}); | ||
} else if ((typeof action === 'undefined' ? 'undefined' : _typeof(action)) === 'object') {} else if (typeof action === 'string') { | ||
action = { type: action, data: data }; | ||
} else { | ||
return Promise.reject('Invalid action!'); | ||
} | ||
// keep a reference to current rootState | ||
var currentState = rootState; | ||
// dispatch the action to the stores | ||
dispatcher.dispatch(action); | ||
// notify if root state changes! | ||
if (currentState !== rootState) { | ||
rootNotify(action); | ||
} | ||
// Return a promise that resolves to the action. | ||
return Promise.resolve(action); | ||
} catch (e) { | ||
return Promise.reject(e); | ||
} | ||
} | ||
// construct a reducer method with a spec | ||
exports.dispatch = _dispatch; | ||
function makeReducer(spec) { | ||
return function (state, action) { | ||
// Check if action has definition and run it if available. | ||
if (action && typeof action.type === 'string' && spec.hasOwnProperty(action.type)) { | ||
return spec[action.type](state, action.data, waitFor); | ||
} | ||
// Return current state when action has no handler. | ||
return state; | ||
}; | ||
} | ||
function bindSelectors(name, selectors) { | ||
return Object.keys(selectors).reduce(function (a, b, i) { | ||
var newFunc = {}; | ||
newFunc[b] = function () { | ||
for (var _len = arguments.length, params = Array(_len), _key = 0; _key < _len; _key++) { | ||
params[_key] = arguments[_key]; | ||
} | ||
return selectors[b].apply(selectors, [rootState[name]].concat(params)); | ||
}; | ||
return Object.assign(a, newFunc); | ||
}, {}); | ||
} | ||
function getState() { | ||
return rootState; | ||
} | ||
function getStores() { | ||
return stores; | ||
} | ||
function createStore(name, reducerOrSpec) { | ||
var selectors = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; | ||
if (typeof name !== 'string') throw 'Expect name to be string.'; | ||
if (typeof reducerOrSpec !== 'function' && (typeof reducerOrSpec === 'undefined' ? 'undefined' : _typeof(reducerOrSpec)) !== 'object') throw 'Expect reducer to be function or object spec.'; | ||
if ((typeof selectors === 'undefined' ? 'undefined' : _typeof(selectors)) !== 'object') throw 'Expect selectors to be object.'; | ||
var isSpec = (typeof reducerOrSpec === 'undefined' ? 'undefined' : _typeof(reducerOrSpec)) === 'object', | ||
reducer = isSpec ? makeReducer(reducerOrSpec) : reducerOrSpec, | ||
actions = {}, | ||
currentListeners = [], | ||
nextListeners = []; | ||
updateRootState(name, isSpec ? reducerOrSpec.getInitialState ? reducerOrSpec.getInitialState() : undefined : reducer(undefined, {}, function () {})); | ||
rootNotify(undefined); | ||
var dispatchToken = dispatcher.register(function (action) { | ||
var newState = reducer(rootState[name], action, waitFor); | ||
if (rootState[name] !== newState) { | ||
updateRootState(name, newState); | ||
// avoid looping over potentially mutating list | ||
var listeners = currentListeners = nextListeners; | ||
for (var i = 0; i < listeners.length; i++) { | ||
var listener = listeners[i]; | ||
listener(newState, action); | ||
} | ||
} | ||
}); | ||
function subscribe(cb) { | ||
if (typeof cb !== 'function') { | ||
throw "Listener must be a function"; | ||
} | ||
// avoid mutating list that could be iterating during dispatch | ||
var subscribed = true; | ||
nextListeners = copyIfSame(currentListeners, nextListeners); | ||
nextListeners.push(cb); | ||
return function () { | ||
if (!subscribed) return; | ||
subscribed = false; | ||
nextListeners = copyIfSame(currentListeners, nextListeners); | ||
var index = nextListeners.indexOf(cb); | ||
nextListeners.splice(index, 1); | ||
}; | ||
} | ||
if (isSpec) { | ||
// create helpful action methods | ||
actions = Object.keys(reducerOrSpec).reduce(function (a, b) { | ||
if (b === 'getInitialState') return a; | ||
a[b] = function (data) { | ||
return _dispatch({ | ||
type: b, | ||
data: data | ||
}); | ||
}; | ||
return a; | ||
}, {}); | ||
} | ||
var store = Object.assign({}, actions, bindSelectors(name, selectors), { | ||
name: name, | ||
dispatch: function dispatch() { | ||
return _dispatch.apply(undefined, arguments); | ||
}, | ||
dispatchToken: dispatchToken, | ||
subscribe: subscribe, | ||
replaceReducer: function replaceReducer(newReducer) { | ||
return reducer = newReducer; | ||
}, | ||
setState: function setState(state) { | ||
updateRootState(name, state); | ||
}, | ||
getReducer: function getReducer() { | ||
return reducer; | ||
}, | ||
getState: function getState() { | ||
return rootState[name]; | ||
} | ||
}); | ||
if (name[0] !== '_') stores[name] = store; | ||
return store; | ||
} | ||
var rootStore = { | ||
dispatch: _dispatch, | ||
replaceState: replaceState, | ||
subscribe: subscribe, | ||
getState: getState | ||
}; | ||
exports.default = rootStore; | ||
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?factory(exports):typeof define==="function"&&define.amd?define(["exports"],factory):factory(global.fluxury={})})(this,function(exports){"use strict";function Dispatcher(){var lastId=1;var prefix="ID_";var callbacks={};var isPending={};var isDispatching=false;var pendingPayload=null;function invokeCallback(id){isPending[id]=true;callbacks[id](pendingPayload)}this.register=function(callback){var id=prefix+lastId++;callbacks[id]=callback;return id};this.unregister=function(id){if(!callbacks.hasOwnProperty(id)){return new Error("Cannot unregister unknown ID!")}delete callbacks[id];return id};this.waitFor=function(ids){for(var i=0;i<ids.length;i++){var id=ids[id];if(isPending[id]){return new Error("Circular dependency waiting for "+id)}if(!callbacks[id]){return new Error("waitFor: "+id+" is not a registered callback.")}invokeCallback(id)}return undefined};this.dispatch=function(payload){if(isDispatching){return new Error("Cannot dispatch while dispatching.")}for(var id in callbacks){isPending[id]=false}pendingPayload=payload;isDispatching=true;try{for(var id in callbacks){if(isPending[id]){continue}invokeCallback(id)}}finally{pendingPayload=null;isDispatching=false}return payload}}var rootState=Object.freeze({}),stores={},dispatcher=new Dispatcher,waitFor=dispatcher.waitFor.bind(dispatcher),rootListeners=[],rootNextListeners=[];function copyIfSame(current,next){if(current===next){return current.slice()}return next}function updateRootState(name,newState){var changes={};changes[name]=typeof newState==="object"?Object.freeze(newState):newState;rootState=Object.assign({},rootState,changes)}function rootNotify(action){var listeners=rootListeners=rootNextListeners;for(var i=0;i<listeners.length;i++){var listener=listeners[i];listener(rootState,action)}}function subscribe(cb){if(typeof cb!=="function"){throw"Listener must be a function"}var subscribed=true;rootNextListeners=copyIfSame(rootListeners,rootNextListeners);rootNextListeners.push(cb);return function(){if(!subscribed){return}subscribed=false;rootNextListeners=copyIfSame(rootListeners,rootNextListeners);var index=rootNextListeners.indexOf(cb);rootNextListeners.splice(index,1)}}function promiseAction(type,data){return Promise.resolve({type:type,data:data})}function replaceState(newState){rootState=newState}function dispatch(action,data){try{if(typeof action==="object"&&typeof action.then==="function"){return action.then(function(result){dispatch(result);return Promise.resolve(result)})}else if(typeof action==="object"){}else if(typeof action==="string"){action={type:action,data:data}}else{return Promise.reject("Invalid action!")}var currentState=rootState;dispatcher.dispatch(action);if(currentState!==rootState){rootNotify(action)}return Promise.resolve(action)}catch(e){return Promise.reject(e)}}function makeReducer(spec){return function(state,action){if(action&&typeof action.type==="string"&&spec.hasOwnProperty(action.type)){return spec[action.type](state,action.data,waitFor)}return state}}function bindSelectors(name,selectors){return Object.keys(selectors).reduce(function(a,b,i){var newFunc={};newFunc[b]=function(){var params=[],len=arguments.length;while(len--)params[len]=arguments[len];return selectors[b].apply(selectors,[rootState[name]].concat(params))};return Object.assign(a,newFunc)},{})}function getState(){return rootState}function getStores(){return stores}function createStore(name,reducerOrSpec,selectors){if(selectors===void 0)selectors={};if(typeof name!=="string"){throw"Expect name to be string."}if(typeof reducerOrSpec!=="function"&&typeof reducerOrSpec!=="object"){throw"Expect reducer to be function or object spec."}if(typeof selectors!=="object"){throw"Expect selectors to be object."}var isSpec=typeof reducerOrSpec==="object",reducer=isSpec?makeReducer(reducerOrSpec):reducerOrSpec,actions={},currentListeners=[],nextListeners=[];updateRootState(name,isSpec?reducerOrSpec.getInitialState?reducerOrSpec.getInitialState():undefined:reducer(undefined,{},function(){}));rootNotify(undefined);var dispatchToken=dispatcher.register(function(action){var newState=reducer(rootState[name],action,waitFor);if(rootState[name]!==newState){updateRootState(name,newState);var listeners=currentListeners=nextListeners;for(var i=0;i<listeners.length;i++){var listener=listeners[i];listener(newState,action)}}});function subscribe(cb){if(typeof cb!=="function"){throw"Listener must be a function"}var subscribed=true;nextListeners=copyIfSame(currentListeners,nextListeners);nextListeners.push(cb);return function(){if(!subscribed){return}subscribed=false;nextListeners=copyIfSame(currentListeners,nextListeners);var index=nextListeners.indexOf(cb);nextListeners.splice(index,1)}}if(isSpec){actions=Object.keys(reducerOrSpec).reduce(function(a,b){if(b==="getInitialState"){return a}a[b]=function(data){return dispatch({type:b,data:data})};return a},{})}var store=Object.assign({},actions,bindSelectors(name,selectors),{name:name,dispatch:function(){var action=[],len=arguments.length;while(len--)action[len]=arguments[len];return dispatch.apply(void 0,action)},dispatchToken:dispatchToken,subscribe:subscribe,replaceReducer:function(newReducer){return reducer=newReducer},setState:function(state){updateRootState(name,state)},getReducer:function(){return reducer},getState:function(){return rootState[name]}});if(name[0]!=="_"){stores[name]=store}return store}exports.subscribe=subscribe;exports.promiseAction=promiseAction;exports.replaceState=replaceState;exports.dispatch=dispatch;exports.getState=getState;exports.getStores=getStores;exports.createStore=createStore;Object.defineProperty(exports,"__esModule",{value:true})}); |
{ | ||
"name": "fluxury", | ||
"version": "3.1.0", | ||
"description": "Redux with waitFor.", | ||
"version": "4.0.0", | ||
"description": "state management in js", | ||
"main": "./lib/index.js", | ||
"scripts": { | ||
"build": "gulp", | ||
"test": "babel-node test" | ||
"build": "npx rollup --format=umd --name=fluxury src/index.js | npx buble | npx uglifyjs > lib/index.js", | ||
"test": "npx nodent test.js" | ||
}, | ||
"engines": { | ||
"node": ">=6.0" | ||
"node": ">=8.0" | ||
}, | ||
@@ -16,15 +16,13 @@ "author": "JC Fisher", | ||
"devDependencies": { | ||
"babel-cli": "^6.1.2", | ||
"babel-core": "^6.1.2", | ||
"babel-plugin-transform-es2015-modules-commonjs": "^6.1.3", | ||
"babel-preset-es2015": "^6.1.2", | ||
"gulp": "^3.9.1", | ||
"gulp-babel": "^6.1.2", | ||
"buble": "^0.19.3", | ||
"immutable": "^3.7.5", | ||
"nodent": "^3.2.6", | ||
"rollup": "^0.59.1", | ||
"tape": "^4.2.2", | ||
"tape-async": "^2.1.1" | ||
"tape-async": "^2.1.1", | ||
"uglify-js": "^3.3.25" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/formula/fluxury.git" | ||
"url": "git+https://github.com/jcfisher007/fluxury.git" | ||
}, | ||
@@ -37,5 +35,5 @@ "keywords": [ | ||
"bugs": { | ||
"url": "https://github.com/formula/fluxury/issues" | ||
"url": "https://github.com/jcfisher007/fluxury/issues" | ||
}, | ||
"homepage": "https://github.com/formula/fluxury#readme" | ||
"homepage": "https://github.com/jcfisher007/fluxury#readme" | ||
} |
109
README.md
# fluxury | ||
[](https://circleci.com/gh/formula/fluxury/tree/master) | ||
[](https://circleci.com/gh/jcfisher007/fluxury/tree/master) | ||
## Overview | ||
State management library, works like redux but with side effects (e.g. waitFor). | ||
State management library; works like redux but with option for many stores, side effects, Promises and other practical things. | ||
Library includes: | ||
- createStore(name, reducerOrSpec, actionsOrSelectors) | ||
- dispatch(action) | ||
- getStores() | ||
- getReducer() | ||
- getState() | ||
- promiseAction(type, data) | ||
- replaceState(state) | ||
- subscribe(cb) | ||
- createStore(key, reducerOrSpec, actionsOrSelectors) | ||
- dispatch(action) | ||
- getStores() | ||
- getReducer() | ||
- getState() | ||
- promiseAction(type, data) | ||
- replaceState(state) | ||
- subscribe(cb) | ||
@@ -27,3 +27,3 @@ ## Quick start | ||
```js | ||
import rootStore, { | ||
import { | ||
createStore, | ||
@@ -36,27 +36,28 @@ dispatch, | ||
subscribe | ||
} | ||
from 'fluxury' | ||
} from "fluxury"; | ||
// creates a key="A" in the root store, connected to a reducer function. | ||
let storeA = createStore('a', (state=0, action) => | ||
action.type === 'setA' ? | ||
action.data : state ) | ||
let storeA = createStore( | ||
"a1", | ||
(state = 0, action) => (action.type === "setA" ? action.data : state) | ||
); | ||
let storeB = createStore('b', (state=0, action) => | ||
action.type === 'setB' ? | ||
action.data : state ) | ||
let storeB = createStore( | ||
"b1", | ||
(state = 0, action) => (action.type === "setB" ? action.data : state) | ||
); | ||
// Store with dependencies on state in storeA and storeB. | ||
let storeC = createStore('c', (state=0, action, waitFor) => { | ||
let storeC = createStore("c1", (state = 0, action, waitFor) => { | ||
// Ensure storeA and storeB reducers run prior to continuing. | ||
waitFor([storeA.dispatchToken, storeB.dispatchToken]); | ||
// Side effect! Get state from other stores. | ||
return storeA.getState() + storeB.getState(); | ||
}) | ||
}); | ||
rootStore.subscribe((...args) => console.log('action', ...args)) | ||
rootStore.dispatch('setA', 2) | ||
rootStore.dispatch('setB', 2) | ||
rootStore.getState() // -> { a: 2, b: 2, c: 4 } | ||
subscribe((...args) => console.log("action", ...args)); | ||
dispatch("setA", 2); | ||
dispatch("setB", 2); | ||
getState(); // -> { a1: 2, b1: 2, c1: 4 } | ||
``` | ||
@@ -68,9 +69,9 @@ | ||
Install required polyfills with [core-js](https://github.com/zloirock/core-js): | ||
Manually install required polyfills with [core-js](https://github.com/zloirock/core-js): | ||
```js | ||
require('core-js/fn/promise'); | ||
require('core-js/fn/object/assign'); | ||
require('core-js/fn/object/freeze'); | ||
require('core-js/fn/object/keys'); | ||
require("core-js/fn/promise"); | ||
require("core-js/fn/object/assign"); | ||
require("core-js/fn/object/freeze"); | ||
require("core-js/fn/object/keys"); | ||
``` | ||
@@ -80,3 +81,3 @@ | ||
### createStore( name, reducerOrSpec, actionsOrSelectors ) | ||
### createStore( key, reducerOrSpec, actionsOrSelectors ) | ||
@@ -90,3 +91,3 @@ A store responds to actions by returning the next state. | ||
// a simple counting store | ||
var store = createStore( "CountStoreWithReducer", (state=0, action) => { | ||
var store = createStore( "count", (state=0, action) => { | ||
switch (action.type) | ||
@@ -114,18 +115,18 @@ case inc: | ||
```js | ||
const inc = 'inc' | ||
import { createStore } from 'fluxury'; | ||
const inc = "inc"; | ||
import { createStore } from "fluxury"; | ||
// a simple counting store | ||
var countStore = createStore( "CountStoreWithSpec", { | ||
var countStore = createStore("count", { | ||
// life-cycle method for initialization. | ||
getInitialState: () => 0, | ||
// handles { type: 'inc' } | ||
inc: (state) => state+1, | ||
inc: state => state + 1, | ||
// handles { type: 'incN' } | ||
incN: (state, n) => state+n, | ||
}) | ||
incN: (state, n) => state + n | ||
}); | ||
// object spec makes action creators automatically... | ||
countStore.inc() | ||
countStore.incN(10) | ||
countStore.inc(); | ||
countStore.incN(10); | ||
``` | ||
@@ -135,3 +136,3 @@ | ||
The entry point to effecting state changes in the app is when an action is dispatch. | ||
The entry point to effecting state changes in the app is when an action is dispatch. | ||
@@ -153,3 +154,2 @@ Dispatch accepts action as object, promise, or type/data; returns promise. | ||
dispatch( 'loadSettings', { a: 1, b: 2 } ) | ||
``` | ||
@@ -161,11 +161,11 @@ | ||
| name | comment | | ||
|---------|------| | ||
| name | The name of the store | | ||
| dispatch | Access to dispatch function | | ||
| dispatchToken | A number used to identity the store | | ||
| subscribe | A function to tegister a listener | | ||
| getState | A function to access state | | ||
| setState | Replace the store's state | | ||
| replaceReducer | Replace the store's reducer | | ||
| name | comment | | ||
| -------------- | ----------------------------------- | | ||
| name | The name of the store | | ||
| dispatch | Access to dispatch function | | ||
| dispatchToken | A number used to identity the store | | ||
| subscribe | A function to tegister a listener | | ||
| getState | A function to access state | | ||
| setState | Replace the store's state | | ||
| replaceReducer | Replace the store's reducer | | ||
@@ -182,4 +182,4 @@ ### getStores( ) | ||
replaceState({ | ||
'MyCountStore': 1 | ||
}) | ||
MyCountStore: 1 | ||
}); | ||
``` | ||
@@ -201,4 +201,5 @@ | ||
``` | ||
### getReducer( ) | ||
Return app's reducer function, use with Redux. |
466
test.js
@@ -1,297 +0,333 @@ | ||
var test = require('tape-async'); | ||
var pf = require('./src/index') | ||
var getState = pf.getState | ||
var getStores = pf.getStores | ||
var createStore = pf.createStore | ||
var dispatch = pf.dispatch | ||
var replaceState = pf.replaceState | ||
var subscribe = pf.subscribe | ||
var test = require("tape-async"); | ||
var pf = require("./lib/index"); | ||
var getState = pf.getState; | ||
var getStores = pf.getStores; | ||
var createStore = pf.createStore; | ||
var dispatch = pf.dispatch; | ||
var replaceState = pf.replaceState; | ||
var subscribe = pf.subscribe; | ||
test("Basic Tests", function*(t) { | ||
t.plan(19); | ||
import rootStore from './src/index' | ||
t.equal(typeof pf, "object"); | ||
t.equal(typeof pf.createStore, "function"); | ||
t.equal(typeof pf.dispatch, "function"); | ||
test( 'Basic Tests', function* (t) { | ||
t.plan(20) | ||
var inc = "inc"; | ||
var dec = "dec"; | ||
var set = "set"; | ||
t.equal(typeof pf, 'object') | ||
t.equal(typeof rootStore, 'object') | ||
t.equal(typeof pf.createStore, 'function') | ||
t.equal(typeof pf.dispatch, 'function') | ||
process.env.NODE_ENV = "development"; | ||
var inc = 'inc' | ||
var dec = 'dec' | ||
var set = 'set' | ||
process.env.NODE_ENV = 'development' | ||
var store = pf.createStore("test1SetStore", (state, action) => { | ||
switch (action.type) { | ||
case set: | ||
// combine both objects into a single new object | ||
return Object.assign({}, state, action.data) | ||
default: | ||
return state; | ||
var store = pf.createStore( | ||
"test1SetStore", | ||
(state, action) => { | ||
switch (action.type) { | ||
case set: | ||
// combine both objects into a single new object | ||
return Object.assign({}, state, action.data); | ||
default: | ||
return state; | ||
} | ||
}, | ||
{ | ||
getFoo: state => state.foo, | ||
getBar: state => state.bar, | ||
filterHey: (state, param) => state.hey.filter(d => d === param), | ||
filterNotHey: (state, param) => state.hey.filter(d => d !== param) | ||
} | ||
}, { | ||
getFoo: (state) => state.foo, | ||
getBar: (state) => state.bar, | ||
filterHey: (state, param) => state.hey.filter((d) => d === param), | ||
filterNotHey: (state, param) => state.hey.filter((d) => d !== param) | ||
}); | ||
); | ||
var listenerCount = 0; | ||
store.subscribe( () => listenerCount++ ) | ||
var result = yield pf.dispatch(set, { foo: 1, bar: 2 }) | ||
t.equal( result.type, set, 'promise should resolve to action with type' ) | ||
t.deepEqual( result.data, { foo: 1, bar: 2 }, 'promise should resolve to action with data' ) | ||
store.subscribe(() => listenerCount++); | ||
var result = yield pf.dispatch(set, { foo: 1, bar: 2 }); | ||
t.equal(result.type, set, "promise should resolve to action with type"); | ||
t.deepEqual( | ||
result.data, | ||
{ foo: 1, bar: 2 }, | ||
"promise should resolve to action with data" | ||
); | ||
t.deepEqual(store.getState(), { foo: 1, bar: 2 }) | ||
t.equal(store.getFoo(), 1) | ||
t.equal(store.getBar(), 2) | ||
rootStore.dispatch(set, { foo: 2 }) | ||
t.deepEqual(store.getState(), { foo: 2, bar: 2 }) | ||
pf.dispatch(set, { hey: ['ho', 'let\'s', 'go'] }) | ||
t.deepEqual(store.getState(), { foo: 2, bar: 2, hey: ['ho', 'let\'s', 'go'] }) | ||
store.dispatch(set, { foo: 3 }) | ||
t.deepEqual(store.getState(), { foo: 3, bar: 2, hey: ['ho', 'let\'s', 'go'] }) | ||
t.deepEqual(store.filterHey('go'), ['go']); | ||
t.deepEqual(store.filterNotHey('go'), ['ho', 'let\'s']); | ||
t.deepEqual(store.getState(), { foo: 1, bar: 2 }); | ||
t.equal(store.getFoo(), 1); | ||
t.equal(store.getBar(), 2); | ||
dispatch(set, { foo: 2 }); | ||
t.deepEqual(store.getState(), { foo: 2, bar: 2 }); | ||
pf.dispatch(set, { hey: ["ho", "let's", "go"] }); | ||
t.deepEqual(store.getState(), { foo: 2, bar: 2, hey: ["ho", "let's", "go"] }); | ||
store.dispatch(set, { foo: 3 }); | ||
t.deepEqual(store.getState(), { foo: 3, bar: 2, hey: ["ho", "let's", "go"] }); | ||
t.deepEqual(store.filterHey("go"), ["go"]); | ||
t.deepEqual(store.filterNotHey("go"), ["ho", "let's"]); | ||
// ensure that callback is invoked correct number of times | ||
t.equal(listenerCount, 4); | ||
var store = pf.createStore("test1CountStore", (state=0, action) => { | ||
var store = pf.createStore("test1CountStore", (state = 0, action) => { | ||
switch (action.type) { | ||
case inc: | ||
return state+1; | ||
return state + 1; | ||
case dec: | ||
return state-1; | ||
return state - 1; | ||
default: | ||
return state; | ||
return state; | ||
} | ||
}); | ||
pf.dispatch(inc) | ||
t.equal(store.getState(), 1) | ||
pf.dispatch(inc); | ||
t.equal(store.getState(), 1); | ||
pf.dispatch(inc) | ||
t.equal(store.getState(), 2) | ||
pf.dispatch(inc); | ||
t.equal(store.getState(), 2); | ||
pf.dispatch(dec) | ||
t.equal(store.getState(), 1) | ||
pf.dispatch(dec); | ||
t.equal(store.getState(), 1); | ||
pf.dispatch(dec) | ||
t.equal(store.getState(), 0) | ||
pf.dispatch(dec); | ||
t.equal(store.getState(), 0); | ||
t.deepEqual( Object.keys(store).sort(), [ 'dispatch', 'dispatchToken', 'getReducer', 'getState', 'name', 'replaceReducer', 'setState', 'subscribe' ].sort() ); | ||
t.deepEqual( | ||
Object.keys(store).sort(), | ||
[ | ||
"dispatch", | ||
"dispatchToken", | ||
"getReducer", | ||
"getState", | ||
"name", | ||
"replaceReducer", | ||
"setState", | ||
"subscribe" | ||
].sort() | ||
); | ||
}); | ||
}) | ||
test('CountStore', function(t) { | ||
test("CountStore", function(t) { | ||
// ensure store with non-object initialState handled correctly | ||
var MessageCountStore = createStore("test2MessageCountStore", (count=0, action) => { | ||
switch(action.type) { | ||
case 'receiveMessage': return count + 1; | ||
default: return count | ||
var MessageCountStore = createStore( | ||
"test2MessageCountStore", | ||
(count = 0, action) => { | ||
switch (action.type) { | ||
case "receiveMessage": | ||
return count + 1; | ||
default: | ||
return count; | ||
} | ||
} | ||
}) | ||
); | ||
t.plan(4) | ||
t.plan(4); | ||
t.equals(MessageCountStore.getState(), 0) | ||
MessageCountStore.dispatch('receiveMessage', 'Hello') | ||
t.equals(MessageCountStore.getState(), 1) | ||
MessageCountStore.dispatch('receiveMessage', 'Hello') | ||
t.equals(MessageCountStore.getState(), 2) | ||
t.equals(MessageCountStore.getState(), 0); | ||
MessageCountStore.dispatch("receiveMessage", "Hello"); | ||
t.equals(MessageCountStore.getState(), 1); | ||
MessageCountStore.dispatch("receiveMessage", "Hello"); | ||
t.equals(MessageCountStore.getState(), 2); | ||
// Test the reducer independently | ||
let reducer = MessageCountStore.getReducer(); | ||
t.equals( reducer( 1, { type: 'receiveMessage' } ), 2 ) | ||
t.equals(reducer(1, { type: "receiveMessage" }), 2); | ||
}); | ||
}) | ||
test("ImmutableMapStoreWithObjectSpec", function(t) { | ||
t.plan(10); | ||
test('ImmutableMapStoreWithObjectSpec', function(t) { | ||
t.plan(10) | ||
var dispatch = pf.dispatch, | ||
Immutable = require('immutable'); | ||
Immutable = require("immutable"); | ||
process.env.NODE_ENV = 'prod' | ||
process.env.NODE_ENV = "prod"; | ||
// For when switch cases seem like overkill. | ||
var store = pf.createStore("test3ImmutableMapStore", { | ||
getInitialState: () => Immutable.Map(), | ||
set: (state, data) => state.merge(data) | ||
}, { | ||
get: (state, param) => state.get(param), | ||
has: (state, param) => state.has(param), | ||
includes: (state, param) => state.includes(param), | ||
first: (state) => state.first(), | ||
last: (state) => state.last(), | ||
all: (state) => state.toJS(), | ||
}); | ||
var store = pf.createStore( | ||
"test3ImmutableMapStore", | ||
{ | ||
getInitialState: () => Immutable.Map(), | ||
set: (state, data) => state.merge(data) | ||
}, | ||
{ | ||
get: (state, param) => state.get(param), | ||
has: (state, param) => state.has(param), | ||
includes: (state, param) => state.includes(param), | ||
first: state => state.first(), | ||
last: state => state.last(), | ||
all: state => state.toJS() | ||
} | ||
); | ||
// should only be when | ||
t.equal(typeof store.replaceState, 'undefined') | ||
t.equal(typeof store.replaceState, "undefined"); | ||
t.deepEqual( Object.keys(store).sort(), [ | ||
'get', | ||
'has', | ||
'includes', | ||
'first', | ||
'last', | ||
'all', | ||
'dispatchToken', | ||
'subscribe', | ||
'name', | ||
'replaceReducer', | ||
'set', | ||
'setState', | ||
'dispatch', | ||
'getState', | ||
'getReducer' | ||
].sort()); | ||
t.deepEqual( | ||
Object.keys(store).sort(), | ||
[ | ||
"get", | ||
"has", | ||
"includes", | ||
"first", | ||
"last", | ||
"all", | ||
"dispatchToken", | ||
"subscribe", | ||
"name", | ||
"replaceReducer", | ||
"set", | ||
"setState", | ||
"dispatch", | ||
"getState", | ||
"getReducer" | ||
].sort() | ||
); | ||
store.set({ states: ['CA', 'OR', 'WA'] }) | ||
dispatch('set', { programs: [{ name: 'A', states: ['CA']}] }) | ||
dispatch('set', { selectedState: 'CA' }) | ||
store.set({ states: ["CA", "OR", "WA"] }); | ||
dispatch("set", { programs: [{ name: "A", states: ["CA"] }] }); | ||
dispatch("set", { selectedState: "CA" }); | ||
t.deepEqual( store.get('states').toJS(), ['CA', 'OR', 'WA'] ); | ||
t.deepEqual( store.get('programs').toJS(), [{ name: 'A', states: ['CA']}] ); | ||
t.deepEqual( store.get('selectedState'), 'CA' ); | ||
t.deepEqual( store.all(), { states: ['CA', 'OR', 'WA'], programs: [{ name: 'A', states: ['CA']}] , selectedState: 'CA' } ); | ||
t.deepEqual(store.get("states").toJS(), ["CA", "OR", "WA"]); | ||
t.deepEqual(store.get("programs").toJS(), [{ name: "A", states: ["CA"] }]); | ||
t.deepEqual(store.get("selectedState"), "CA"); | ||
t.deepEqual(store.all(), { | ||
states: ["CA", "OR", "WA"], | ||
programs: [{ name: "A", states: ["CA"] }], | ||
selectedState: "CA" | ||
}); | ||
t.deepEqual( store.has('states'), true ); | ||
t.deepEqual( store.first().toJS(), ['CA', 'OR', 'WA'] ); | ||
t.deepEqual( store.last(), 'CA' ); | ||
t.deepEqual( store.includes('CA'), true ); | ||
t.deepEqual(store.has("states"), true); | ||
t.deepEqual(store.first().toJS(), ["CA", "OR", "WA"]); | ||
t.deepEqual(store.last(), "CA"); | ||
t.deepEqual(store.includes("CA"), true); | ||
}); | ||
}) | ||
test("waitFor and events works correctly", function*(t) { | ||
var dispatchCount = 0, | ||
dispatchCount2 = 0; | ||
test('waitFor and events works correctly', function* (t) { | ||
t.plan(18); | ||
var dispatchCount = 0, dispatchCount2 = 0; | ||
t.plan(18) | ||
var MessageStore = createStore("test4MessageStore", function(state=[], action) { | ||
switch(action.type) { | ||
case 'loadMessage': | ||
return state.concat(action.data) | ||
var MessageStore = createStore("test4MessageStore", function( | ||
state = [], | ||
action | ||
) { | ||
switch (action.type) { | ||
case "loadMessage": | ||
return state.concat(action.data); | ||
default: | ||
return state | ||
return state; | ||
} | ||
}) | ||
}); | ||
var MessageCountStore = createStore( | ||
"test4MessageCountStore", | ||
function(state=0, action, waitFor) { | ||
// ensure that MessageStore reducer is executed before continuing | ||
waitFor([MessageStore.dispatchToken]) | ||
switch(action.type) { | ||
case 'loadMessage': | ||
return state+1 | ||
default: | ||
return state | ||
} | ||
var MessageCountStore = createStore("test4MessageCountStore", function( | ||
state = 0, | ||
action, | ||
waitFor | ||
) { | ||
// ensure that MessageStore reducer is executed before continuing | ||
waitFor([MessageStore.dispatchToken]); | ||
switch (action.type) { | ||
case "loadMessage": | ||
return state + 1; | ||
default: | ||
return state; | ||
} | ||
) | ||
}); | ||
var unsubscribe = MessageStore.subscribe(function() { | ||
dispatchCount += 1 | ||
}) | ||
dispatchCount += 1; | ||
}); | ||
var unsubscribe2 = MessageCountStore.subscribe(function() { | ||
dispatchCount2 += 1 | ||
}) | ||
dispatchCount2 += 1; | ||
}); | ||
t.equals( typeof unsubscribe, 'function') | ||
t.equals(typeof unsubscribe, "function"); | ||
dispatch("loadMessage", "Test"); | ||
t.equals(MessageStore.getState().length, 1); | ||
t.equals(MessageCountStore.getState(), 1); | ||
t.deepEqual(MessageStore.getState(), ["Test"]); | ||
t.equal(dispatchCount, 1); | ||
t.equal(dispatchCount2, 1); | ||
dispatch('loadMessage', 'Test') | ||
t.equals(MessageStore.getState().length, 1) | ||
t.equals(MessageCountStore.getState(), 1) | ||
t.deepEqual(MessageStore.getState(), ['Test']) | ||
t.equal(dispatchCount, 1) | ||
t.equal(dispatchCount2, 1) | ||
dispatch("foo", "Test"); | ||
dispatch('foo', 'Test') | ||
t.equal(dispatchCount, 1); | ||
t.equal(dispatchCount2, 1); | ||
t.equal(dispatchCount, 1) | ||
t.equal(dispatchCount2, 1) | ||
unsubscribe2(); | ||
unsubscribe2() | ||
dispatch("loadMessage", "Test2"); | ||
t.equals(MessageStore.getState().length, 2); | ||
t.equals(MessageCountStore.getState(), 2); | ||
t.deepEqual(MessageStore.getState(), ["Test", "Test2"]); | ||
t.equal(dispatchCount, 2); | ||
t.equal(dispatchCount2, 1); | ||
dispatch('loadMessage', 'Test2') | ||
t.equals(MessageStore.getState().length, 2) | ||
t.equals(MessageCountStore.getState(), 2) | ||
t.deepEqual(MessageStore.getState(), ['Test', 'Test2']) | ||
t.equal(dispatchCount, 2) | ||
t.equal(dispatchCount2, 1) | ||
unsubscribe(); | ||
var result = yield dispatch( | ||
Promise.resolve({ type: "loadMessage", data: "Test3" }) | ||
); | ||
unsubscribe() | ||
t.equals(MessageStore.getState().length, 3); | ||
t.equals(MessageCountStore.getState(), 3); | ||
t.deepEqual(MessageStore.getState(), ["Test", "Test2", "Test3"]); | ||
var result = yield dispatch( Promise.resolve({ type: 'loadMessage', data: 'Test3'}) ) | ||
t.equal(dispatchCount, 2); | ||
t.equal(dispatchCount2, 1); | ||
}); | ||
t.equals(MessageStore.getState().length, 3) | ||
t.equals(MessageCountStore.getState(), 3) | ||
t.deepEqual(MessageStore.getState(), ['Test', 'Test2', 'Test3']) | ||
test("check root store", function*(t) { | ||
t.plan(10); | ||
t.equal(dispatchCount, 2) | ||
t.equal(dispatchCount2, 1) | ||
var count = 0; | ||
}) | ||
var rootListener = subscribe(() => count++); | ||
dispatch("no-action-here", "Test3"); | ||
test('check root store', function *(t) { | ||
t.equal(count, 0); | ||
t.plan(10) | ||
yield dispatch("no-handler-action-here", "Test3"); | ||
yield dispatch("loadMessage", "Test3"); | ||
var count = 0; | ||
t.equal(count, 1); | ||
var rootListener = rootStore.subscribe(() => count++) | ||
dispatch('no-action-here', 'Test3') | ||
let rootState; | ||
t.equal(count, 0) | ||
yield dispatch('no-handler-action-here', 'Test3') | ||
yield dispatch('loadMessage', 'Test3') | ||
t.equal(count, 1) | ||
// try to modify/replace state | ||
var modifiedState = Object.assign({}, rootState) | ||
delete modifiedState.master | ||
var modifiedState = Object.assign({}, rootState); | ||
delete modifiedState.master; | ||
replaceState(modifiedState) | ||
replaceState(modifiedState); | ||
let rootState = getState() | ||
t.equal(Object.keys(rootState).length, Object.keys(modifiedState).length) | ||
rootState = getState(); | ||
t.equal(Object.keys(rootState).length, Object.keys(modifiedState).length); | ||
yield dispatch('no-handler-action-here', 'Test3') | ||
yield dispatch('no-handler-action-here', 'Test3') | ||
yield dispatch('loadMessage', 'Test3') | ||
t.equal( count, 3) | ||
yield dispatch('loadMessage', 'Test3') | ||
t.equal( count, 4) | ||
yield dispatch('loadMessage', 'Test3') | ||
t.equal( count, 5) | ||
yield dispatch("no-handler-action-here", "Test3"); | ||
yield dispatch("no-handler-action-here", "Test3"); | ||
yield dispatch("loadMessage", "Test3"); | ||
t.equal(count, 3); | ||
yield dispatch("loadMessage", "Test3"); | ||
t.equal(count, 4); | ||
yield dispatch("loadMessage", "Test3"); | ||
t.equal(count, 5); | ||
var last; | ||
var subscribe3 = subscribe( (state, action) => { last = { state, action }} ) | ||
var subscribe3 = subscribe((state, action) => { | ||
last = { state, action }; | ||
}); | ||
yield dispatch('loadMessage', 'Test3') | ||
yield dispatch("loadMessage", "Test3"); | ||
t.equal( count, 6) | ||
t.equal(count, 6); | ||
t.deepEqual( last, { | ||
state: { test1CountStore: 0, test2MessageCountStore: 0, test4MessageStore: [ 'Test3', 'Test3', 'Test3', 'Test3' ], test4MessageCountStore: 4 }, | ||
action: { type: 'loadMessage', data: 'Test3'} | ||
}) | ||
t.deepEqual(last, { | ||
state: { | ||
test1CountStore: 0, | ||
test2MessageCountStore: 0, | ||
test4MessageStore: ["Test3", "Test3", "Test3", "Test3"], | ||
test4MessageCountStore: 4 | ||
}, | ||
action: { type: "loadMessage", data: "Test3" } | ||
}); | ||
// verify that state and action are passed to listener | ||
t.equal(Object.keys(last.state).length, 4) | ||
t.equal(last.action.type, 'loadMessage') | ||
}) | ||
t.equal(Object.keys(last.state).length, 4); | ||
t.equal(last.action.type, "loadMessage"); | ||
}); |
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
34173
7
195
9
298
1