Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

redux-actuator

Package Overview
Dependencies
Maintainers
1
Versions
4
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

redux-actuator - npm Package Compare versions

Comparing version 1.0.0 to 2.0.1

14

lib/__tests__/actions.spec.js

@@ -7,3 +7,3 @@ 'use strict';

it('should create flux standard action with type ACTUATE', function () {
var action = (0, _actions.actuate)();
var action = (0, _actions.actuate)('f00z');
expect(action.type).toBe(_actions.ACTUATE);

@@ -13,10 +13,10 @@ expect(action.payload).toMatchObject({});

it('creates ACTUATE action on a default channel', function () {
var action = (0, _actions.actuate)();
expect(action.payload.channel).toBe('default');
it('uses first arg as a name of the channel', function () {
var action = (0, _actions.actuate)('foo');
expect(action.payload.channel).toBe('foo');
});
it('takes the name of the event as a first arg', function () {
it('puts an empty array if args are not specified', function () {
var action = (0, _actions.actuate)('foo');
expect(action.payload.event.type).toBe('foo');
expect(action.payload.args).toEqual([]);
});

@@ -26,4 +26,4 @@

var action = (0, _actions.actuate)('foo', 'what', 'the', 'hell');
expect(action.payload.event.args).toEqual(['what', 'the', 'hell']);
expect(action.payload.args).toEqual(['what', 'the', 'hell']);
});
});
'use strict';
require('raf/polyfill');
var _enzyme = require('enzyme');
var _enzyme2 = _interopRequireDefault(_enzyme);
var _react = require('react');

@@ -13,2 +17,6 @@

var _enzymeAdapterReact = require('enzyme-adapter-react-16');
var _enzymeAdapterReact2 = _interopRequireDefault(_enzymeAdapterReact);
var _index = require('../index');

@@ -20,2 +28,4 @@

_enzyme2.default.configure({ adapter: new _enzymeAdapterReact2.default() });
var delay = function delay(ms) {

@@ -36,3 +46,3 @@ return new Promise(function (resolve) {

describe('Actuator component', function () {
it('catches events on default channel', function () {
it('catches an event via on prop', function () {
var store = createStore();

@@ -44,3 +54,3 @@ var eventHandler = jest.fn();

{ store: store },
_react2.default.createElement(_index.Actuator, { events: { foo: eventHandler } })
_react2.default.createElement(_index.Actuator, { channel: 'foo', on: eventHandler })
));

@@ -59,3 +69,3 @@

{ store: store },
_react2.default.createElement(_index.Actuator, { events: { foo: eventHandler } })
_react2.default.createElement(_index.Actuator, { channel: 'foo', on: eventHandler })
));

@@ -79,3 +89,3 @@

{ store: store },
_react2.default.createElement(_index.Actuator, { events: { foo: eventHandler } })
_react2.default.createElement(_index.Actuator, { channel: 'foo', on: eventHandler })
));

@@ -97,3 +107,3 @@

{ store: store },
_react2.default.createElement(_index.Actuator, { events: { baz: eventHandler }, deltaError: 40 })
_react2.default.createElement(_index.Actuator, { channel: 'baz', on: eventHandler, deltaError: 100 })
));

@@ -115,3 +125,3 @@

{ store: store },
_react2.default.createElement(_index.Actuator, { events: { bar: eventHandler }, deltaError: 25 })
_react2.default.createElement(_index.Actuator, { channel: 'bar', on: eventHandler, deltaError: 25 })
));

@@ -122,2 +132,29 @@

});
it('allows to subscribe to multiple chans at once', function () {
var store = createStore();
var handlerA = jest.fn();
var handlerB = jest.fn();
var handlerC = jest.fn();
(0, _enzyme.mount)(_react2.default.createElement(
_reactRedux.Provider,
{ store: store },
_react2.default.createElement(_index.Actuator, {
on: {
foo: handlerA,
bar: handlerB,
baz: handlerC
}
})
));
store.dispatch((0, _index.actuate)('foo'));
store.dispatch((0, _index.actuate)('bar'));
expect(handlerA).toHaveBeenCalled();
expect(handlerB).toHaveBeenCalled();
expect(handlerC).not.toHaveBeenCalled();
});
});

@@ -22,3 +22,3 @@ 'use strict';

type: _actions.ACTUATE,
payload: { channel: 'm00t', event: { timestamp: 1337 } }
payload: { channel: 'm00t', timestamp: 1337 }
});

@@ -25,0 +25,0 @@

@@ -6,3 +6,3 @@ 'use strict';

});
exports.actuateChannel = exports.actuate = exports.ACTUATE = undefined;
exports.actuate = exports.ACTUATE = undefined;

@@ -14,26 +14,32 @@ var _currentTimestamp = require('./utils/currentTimestamp');

var actuateFactory = function actuateFactory(channel) {
return function (eventType) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
var clock = 0;
var timestamp = (0, _currentTimestamp.currentTimestamp)();
var genKey = function genKey(ts, clock) {
return ts + '::' + clock;
};
return {
type: ACTUATE,
payload: {
channel: channel,
event: {
type: eventType,
timestamp: timestamp,
args: args
}
}
};
var actuate = exports.actuate = function actuate(channel) {
for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
args[_key - 1] = arguments[_key];
}
// channel has to be specified
if (!channel) {
var warning = 'Triggering actions without a channel is no longer ' + 'supported by `redux-actuator`. These actions will be ' + 'ingored by the actuator.';
console.warn(warning);
}
var timestamp = (0, _currentTimestamp.currentTimestamp)();
clock += 1;
return {
type: ACTUATE,
payload: {
key: genKey(timestamp, clock),
channel: channel,
timestamp: timestamp,
args: args
}
};
};
// Action creators
var actuate = exports.actuate = actuateFactory('default');
var actuateChannel = exports.actuateChannel = actuateFactory;
};

@@ -6,5 +6,8 @@ 'use strict';

});
exports.Actuator = undefined;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
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; };
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _react = require('react');

@@ -20,36 +23,169 @@

var _ActuatorInner = require('./ActuatorInner');
var _currentTimestamp = require('../utils/currentTimestamp');
var _ActuatorInner2 = _interopRequireDefault(_ActuatorInner);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; }
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
var Actuator = function Actuator(_ref) {
var event = _ref.event,
events = _ref.events,
props = _objectWithoutProperties(_ref, ['event', 'events']);
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
return _react2.default.createElement(_ActuatorInner2.default, _extends({ event: event, handlers: events }, props));
};
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var mapStateToProps = function mapStateToProps(state, ownProps) {
var channels = state.actuator || {};
var event = channels[ownProps.channel];
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
return { event: event };
};
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
var WrappedActuator = (0, _reactRedux.connect)(mapStateToProps)(Actuator);
var Actuator = exports.Actuator = function (_React$Component) {
_inherits(Actuator, _React$Component);
WrappedActuator.propTypes = {
function Actuator(props, context) {
_classCallCheck(this, Actuator);
// Used to store last visible keys on per-channel basis
// format channel -> last key
var _this = _possibleConstructorReturn(this, (Actuator.__proto__ || Object.getPrototypeOf(Actuator)).call(this, props, context));
_this._keyCache = {};
return _this;
}
_createClass(Actuator, [{
key: 'getChanHandlers',
value: function getChanHandlers() {
var _props = this.props,
on = _props.on,
channel = _props.channel;
if (typeof on === 'function') {
return _defineProperty({}, channel, on);
}
return on;
}
}, {
key: 'getObservedChannels',
value: function getObservedChannels() {
return Object.keys(this.getChanHandlers());
}
}, {
key: 'onStateChanged',
value: function onStateChanged() {
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null;
state = state || this.context.store.getState();
if (!state.actuator) return null;
var channels = this.getObservedChannels();
for (var _len = arguments.length, restOpts = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
restOpts[_key - 1] = arguments[_key];
}
for (var i = 0; i < channels.length; ++i) {
var chan = channels[i];
var event = state.actuator[chan];
if (!event) continue;
this.checkEvent.apply(this, [chan, event].concat(restOpts));
}
}
}, {
key: 'callChanHandler',
value: function callChanHandler(channel, args) {
var handlers = this.getChanHandlers();
handlers[channel] && handlers[channel].apply(handlers, _toConsumableArray(args));
}
}, {
key: 'checkEvent',
value: function checkEvent(channel, event) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
// Compare event keys (they have to be unique)
var _prevKey = this._keyCache[channel];
if (_prevKey && _prevKey === event.key) {
return;
}
this._keyCache[channel] = event.key;
// Special case when the event was dispatched before
// the mount. If you need to handle cases like
// this one, pass `deltaError` prop, which literally means:
// "handle missed events on mount if it's younger than `deltaError`"
var shouldHandleOnMount = false;
var deltaError = this.props.deltaError;
if (options.onMount && deltaError) {
var now = (0, _currentTimestamp.currentTimestamp)();
var delta = Math.abs(now - event.timestamp);
shouldHandleOnMount = delta <= deltaError;
}
if (options.onMount && !shouldHandleOnMount) {
return;
}
this.callChanHandler(channel, event.args);
}
}, {
key: 'componentDidMount',
value: function componentDidMount() {
var _this2 = this;
var store = this.context.store;
if (store) {
this._sub = store.subscribe(function () {
return _this2.onStateChanged();
});
// trigger on mount check
var state = store.getState();
this.onStateChanged(state, { onMount: true });
}
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this._sub && this._sub();
}
}, {
key: 'render',
value: function render() {
if (!this.props.children) return null;
return this.props.children;
}
}]);
return Actuator;
}(_react2.default.Component);
Actuator.propTypes = {
channel: _propTypes2.default.string,
events: _propTypes2.default.object.isRequired
on: _propTypes2.default.oneOfType([
// Can be simple event handler of a map of handlers
// e.g. { chanOne: ..., chanTwo: ... }
_propTypes2.default.func, _propTypes2.default.objectOf(_propTypes2.default.func)]).isRequired,
deltaError: _propTypes2.default.number,
// Always require `channel` prop, unless the map
// of listeners wasn't passed with `on` prop.
_requireChannel: function _requireChannel(props) {
var isMapOfHandlers = props.on !== null && _typeof(props.on) === 'object';
if (!props.channel && !isMapOfHandlers) {
return new Error('channel is required');
}
}
};
WrappedActuator.defaultProps = {
channel: 'default'
Actuator.contextTypes = {
store: _propTypes2.default.object
};
exports.default = WrappedActuator;
exports.default = Actuator;

@@ -25,10 +25,10 @@ 'use strict';

var event = rest.event || {};
// Ignore mailformed actions
// Channel isn't given, ignore
if (!channel) {
if (!channel || !rest) {
return state;
}
return _extends({}, state, _defineProperty({}, channel, event));
return _extends({}, state, _defineProperty({}, channel, rest));
}

@@ -35,0 +35,0 @@ return state;

@@ -6,4 +6,20 @@ "use strict";

});
var currentTimestamp = exports.currentTimestamp = function currentTimestamp() {
return new Date().getTime();
};
var currentTimestamp = function () {
var _window = window,
performance = _window.performance;
if (performance && performance.now) {
return function () {
return performance.now();
};
}
// use a fallback if `performance.now`
// isn't supported by the browser.
return function () {
return new Date().getTime();
};
}();
exports.currentTimestamp = currentTimestamp;

@@ -5,3 +5,3 @@ {

"license": "MIT",
"version": "1.0.0",
"version": "2.0.1",
"repository": "molefrog/redux-actuator",

@@ -28,15 +28,15 @@ "description": "Communicate between components through Redux store",

"babel-plugin-transform-object-rest-spread": "^6.20.2",
"babel-preset-env": "^1.6.1",
"babel-preset-react": "^6.16.0",
"babel-preset-env": "^1.6.1",
"enzyme": "^2.7.0",
"enzyme": "^3.2.0",
"enzyme-adapter-react-16": "^1.1.0",
"jest": "^18.1.0",
"react": "^15.4.1",
"react-addons-test-utils": "^15.4.1",
"react-dom": "^15.4.1",
"react-redux": "^5.0.1",
"redux": "^3.6.0"
"raf": "^3.4.0",
"react": "^16.2.0",
"react-dom": "^16.2.0",
"react-redux": "^5.0.6",
"redux": "^3.7.2"
},
"peerDependencies": {
"react": ">= 0.14.0",
"react-redux": ">= 4.0.0",
"redux": "^2.0.0 || ^3.0.0"

@@ -43,0 +43,0 @@ },

@@ -45,2 +45,3 @@ # Redux Actuator

npm install --save redux-actuator
# or yarn add redux-actuator
```

@@ -70,3 +71,3 @@

In order to do that simply put `<Actuator>` component and specify how events should be handled:
In order to do that simply put `<Actuator>` component with channel provided.

@@ -85,3 +86,3 @@ ```JavaScript

return (
<Actuator events={{ say: (phrase) => this.saySomething(phrase) }}>
<Actuator channel="talking-guy" on={(phrase) => this.saySomething(phrase)}>
<div>

@@ -95,3 +96,3 @@ ...

How we are ready to trigger actions from the bussiness-logic part of the app:
Now let's trigger actions from the bussiness-logic part of the app:

@@ -103,27 +104,15 @@ ```JavaScript

// the rest is interpreted as event arguments
store.dispatch(actuate('say', 'Hola!')
store.dispatch(actuate('say', 'Hello!')
store.dispatch(actuate('talking-guy', 'Hola!')
store.dispatch(actuate('talking-guy', 'Hello!')
```
## Using Channels
In the next example we now have 4 talking heads and we would like to trigger
`'say'` event for a specific head:
**Subscribing to multiple channels.** You can also subscribe to a multiple channels at once using this form:
![](assets/talking-guys.gif)
Actuator provides support for channels. Channels can be useful if you'd like to
distinguish similar events passed for different components:
```JavaScript
// If you don't specify a channel, 'default' will be used
<Actuator
channel='gustav'
events={{ say: (phrase) => this.saySomething(phrase) }} />
import { actuateChannel } from 'redux-actuator'
// actuateChanell is an action creator-creator
const actuateGustav = actuateChannel('gustav')
store.dispatch(actuateGustav('say', 'Goeiedag!'))
// Note: no need to pass a `channel` prop
// Format is { chanOne: handler, chanTwo: ... }
<Actuator on={{
instantNotification: () => ...,
focusToolbar: () => ...
}} />
```

@@ -130,0 +119,0 @@

@@ -5,3 +5,3 @@ import { ACTUATE, actuate } from '../actions'

it('should create flux standard action with type ACTUATE', () => {
const action = actuate()
const action = actuate('f00z')
expect(action.type).toBe(ACTUATE)

@@ -11,10 +11,10 @@ expect(action.payload).toMatchObject({})

it('creates ACTUATE action on a default channel', () => {
const action = actuate()
expect(action.payload.channel).toBe('default')
it('uses first arg as a name of the channel', () => {
const action = actuate('foo')
expect(action.payload.channel).toBe('foo')
})
it('takes the name of the event as a first arg', () => {
it('puts an empty array if args are not specified', () => {
const action = actuate('foo')
expect(action.payload.event.type).toBe('foo')
expect(action.payload.args).toEqual([])
})

@@ -24,4 +24,4 @@

const action = actuate('foo', 'what', 'the', 'hell')
expect(action.payload.event.args).toEqual([ 'what', 'the', 'hell' ])
expect(action.payload.args).toEqual(['what', 'the', 'hell'])
})
})

@@ -1,9 +0,15 @@

import { mount } from 'enzyme'
import 'raf/polyfill'
import Enzyme, { mount } from 'enzyme'
import React from 'react'
import { createStore as createReduxStore, combineReducers } from 'redux'
import { Provider } from 'react-redux'
import Adapter from 'enzyme-adapter-react-16'
import 'raf/polyfill'
Enzyme.configure({ adapter: new Adapter() })
import createEngine, { actuate, Actuator } from '../index'
const delay = (ms) => new Promise(resolve => setTimeout(resolve, ms))
const delay = ms => new Promise(resolve => setTimeout(resolve, ms))

@@ -19,3 +25,3 @@ const createStore = () => {

describe('Actuator component', () => {
it('catches events on default channel', () => {
it('catches an event via on prop', () => {
const store = createStore()

@@ -26,4 +32,5 @@ const eventHandler = jest.fn()

<Provider store={store}>
<Actuator events={{foo: eventHandler}} />
</Provider>)
<Actuator channel="foo" on={eventHandler} />
</Provider>
)

@@ -40,4 +47,5 @@ store.dispatch(actuate('foo', 1, 2, 3))

<Provider store={store}>
<Actuator events={{foo: eventHandler}} />
</Provider>)
<Actuator channel="foo" on={eventHandler} />
</Provider>
)

@@ -59,4 +67,5 @@ store.dispatch(actuate('foo'))

<Provider store={store}>
<Actuator events={{foo: eventHandler}} />
</Provider>)
<Actuator channel="foo" on={eventHandler} />
</Provider>
)

@@ -76,4 +85,5 @@ expect(eventHandler).not.toHaveBeenCalled()

<Provider store={store}>
<Actuator events={{baz: eventHandler}} deltaError={40} />
</Provider>)
<Actuator channel="baz" on={eventHandler} deltaError={100} />
</Provider>
)

@@ -93,4 +103,5 @@ expect(eventHandler).toHaveBeenCalled()

<Provider store={store}>
<Actuator events={{bar: eventHandler}} deltaError={25} />
</Provider>)
<Actuator channel="bar" on={eventHandler} deltaError={25} />
</Provider>
)

@@ -100,2 +111,29 @@ expect(eventHandler).not.toHaveBeenCalled()

})
it('allows to subscribe to multiple chans at once', () => {
const store = createStore()
const handlerA = jest.fn()
const handlerB = jest.fn()
const handlerC = jest.fn()
mount(
<Provider store={store}>
<Actuator
on={{
foo: handlerA,
bar: handlerB,
baz: handlerC
}}
/>
</Provider>
)
store.dispatch(actuate('foo'))
store.dispatch(actuate('bar'))
expect(handlerA).toHaveBeenCalled()
expect(handlerB).toHaveBeenCalled()
expect(handlerC).not.toHaveBeenCalled()
})
})

@@ -13,7 +13,9 @@ import createReducer from '../reducer'

it('should handle ACTUATE action when channel is given', () => {
const state = reducer({},
const state = reducer(
{},
{
type: ACTUATE,
payload: { channel: 'm00t', event: { timestamp: 1337 } }
})
payload: { channel: 'm00t', timestamp: 1337 }
}
)

@@ -20,0 +22,0 @@ expect(state.m00t).toBeTruthy()

@@ -6,21 +6,29 @@ import { currentTimestamp } from './utils/currentTimestamp'

const actuateFactory = (channel) =>
(eventType, ...args) => {
const timestamp = currentTimestamp()
let clock = 0
return {
type: ACTUATE,
payload: {
channel,
event: {
type: eventType,
timestamp,
args
}
}
const genKey = (ts, clock) => `${ts}::${clock}`
export const actuate = (channel, ...args) => {
// channel has to be specified
if (!channel) {
const warning =
'Triggering actions without a channel is no longer ' +
'supported by `redux-actuator`. These actions will be ' +
'ingored by the actuator.'
console.warn(warning)
}
const timestamp = currentTimestamp()
clock += 1
return {
type: ACTUATE,
payload: {
key: genKey(timestamp, clock),
channel,
timestamp,
args
}
}
// Action creators
export const actuate = actuateFactory('default')
export const actuateChannel = actuateFactory
}

@@ -5,26 +5,126 @@ import React from 'react'

import { connect } from 'react-redux'
import ActuatorInner from './ActuatorInner'
import { currentTimestamp } from '../utils/currentTimestamp'
const Actuator = ({ event, events, ...props }) => (
<ActuatorInner event={event} handlers={events} {...props} />
)
export class Actuator extends React.Component {
constructor(props, context) {
super(props, context)
const mapStateToProps = (state, ownProps) => {
const channels = state.actuator || {}
const event = channels[ownProps.channel]
// Used to store last visible keys on per-channel basis
// format channel -> last key
this._keyCache = {}
}
return { event }
getChanHandlers() {
const { on, channel } = this.props
if (typeof on === 'function') {
return { [channel]: on }
}
return on
}
getObservedChannels() {
return Object.keys(this.getChanHandlers())
}
onStateChanged(state = null, ...restOpts) {
state = state || this.context.store.getState()
if (!state.actuator) return null
const channels = this.getObservedChannels()
for (let i = 0; i < channels.length; ++i) {
const chan = channels[i]
const event = state.actuator[chan]
if (!event) continue
this.checkEvent(chan, event, ...restOpts)
}
}
callChanHandler(channel, args) {
const handlers = this.getChanHandlers()
handlers[channel] && handlers[channel](...args)
}
checkEvent(channel, event, options = {}) {
// Compare event keys (they have to be unique)
const _prevKey = this._keyCache[channel]
if (_prevKey && _prevKey === event.key) {
return
}
this._keyCache[channel] = event.key
// Special case when the event was dispatched before
// the mount. If you need to handle cases like
// this one, pass `deltaError` prop, which literally means:
// "handle missed events on mount if it's younger than `deltaError`"
let shouldHandleOnMount = false
const { deltaError } = this.props
if (options.onMount && deltaError) {
const now = currentTimestamp()
const delta = Math.abs(now - event.timestamp)
shouldHandleOnMount = delta <= deltaError
}
if (options.onMount && !shouldHandleOnMount) {
return
}
this.callChanHandler(channel, event.args)
}
componentDidMount() {
const store = this.context.store
if (store) {
this._sub = store.subscribe(() => this.onStateChanged())
// trigger on mount check
const state = store.getState()
this.onStateChanged(state, { onMount: true })
}
}
componentWillUnmount() {
this._sub && this._sub()
}
render() {
if (!this.props.children) return null
return this.props.children
}
}
const WrappedActuator = connect(mapStateToProps)(Actuator)
Actuator.propTypes = {
channel: PropTypes.string,
WrappedActuator.propTypes = {
channel: PropTypes.string,
events: PropTypes.object.isRequired
on: PropTypes.oneOfType([
// Can be simple event handler of a map of handlers
// e.g. { chanOne: ..., chanTwo: ... }
PropTypes.func,
PropTypes.objectOf(PropTypes.func)
]).isRequired,
deltaError: PropTypes.number,
// Always require `channel` prop, unless the map
// of listeners wasn't passed with `on` prop.
_requireChannel: props => {
const isMapOfHandlers = props.on !== null && typeof props.on === 'object'
if (!props.channel && !isMapOfHandlers) {
return new Error('channel is required')
}
}
}
WrappedActuator.defaultProps = {
channel: 'default'
Actuator.contextTypes = {
store: PropTypes.object
}
export default WrappedActuator
export default Actuator
import { ACTUATE } from './actions'
const createReducer = (engine) =>
(state = {}, action) => {
if (action.type === ACTUATE) {
const { channel, ...rest } = action.payload || {}
const event = rest.event || {}
const createReducer = engine => (state = {}, action) => {
if (action.type === ACTUATE) {
const { channel, ...rest } = action.payload || {}
// Channel isn't given, ignore
if (!channel) {
return state
}
// Ignore mailformed actions
if (!channel || !rest) {
return state
}
return {
...state,
[channel]: event
}
return {
...state,
[channel]: rest
}
return state
}
return state
}
export default createReducer

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

const currentTimestamp = (() => {
const { performance } = window
export const currentTimestamp = () => (new Date()).getTime()
if (performance && performance.now) {
return () => performance.now()
}
// use a fallback if `performance.now`
// isn't supported by the browser.
return () => new Date().getTime()
})()
export { currentTimestamp }

Sorry, the diff of this file is not supported yet

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