add dist directory

typescript v0.1.0
Yanick Champoux 2019-10-22 18:15:08 -04:00
parent 31c6060041
commit c83443c95f
14 changed files with 672 additions and 0 deletions

60
dist/actions.test.js vendored Normal file
View File

@ -0,0 +1,60 @@
"use strict";
var _ = _interopRequireDefault(require("."));
var _updeep = _interopRequireDefault(require("updeep"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
test('actions defined in effects and mutations, multi-level', () => {
const {
actions
} = (0, _.default)({
effects: {
foo: api => next => action => {}
},
mutations: {
bar: () => () => null
},
subduxes: {
mysub: {
effects: {
baz: api => next => action => {}
},
mutations: {
quux: () => () => null
},
actions: {
foo: limit => ({
limit
})
}
},
myothersub: {
effects: {
foo: () => () => () => {}
}
}
}
});
const types = Object.keys(actions);
types.sort();
expect(types).toEqual(['bar', 'baz', 'foo', 'quux']);
expect(actions.bar()).toEqual({
type: 'bar'
});
expect(actions.bar('xxx')).toEqual({
type: 'bar',
payload: 'xxx'
});
expect(actions.bar(undefined, 'yyy')).toEqual({
type: 'bar',
meta: 'yyy'
});
expect(actions.foo(12)).toEqual({
type: 'foo',
payload: {
limit: 12
}
});
});

32
dist/buildActions/index.js vendored Normal file
View File

@ -0,0 +1,32 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildActions;
var _fp = _interopRequireDefault(require("lodash/fp"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function actionFor(type) {
const creator = (payload = undefined, meta = undefined) => _fp.default.pickBy(v => v !== undefined)({
type,
payload,
meta
});
creator._genericAction = true;
return creator;
}
function buildActions(creators = {}, mutations = {}, effects = {}, subActions = []) {
// priority => generics => generic subs => craft subs => creators
const [crafted, generic] = _fp.default.partition(([type, f]) => !f._genericAction)(_fp.default.flatten(subActions.map(x => Object.entries(x))).filter(([_, f]) => f));
const actions = [...[...Object.keys(mutations), ...Object.keys(effects)].map(type => [type, actionFor(type)]), ...generic, ...crafted, ...Object.entries(creators).map(([type, payload]) => [type, (...args) => ({
type,
payload: payload(...args)
})])];
return _fp.default.fromPairs(actions);
}

24
dist/buildCreateStore.js vendored Normal file
View File

@ -0,0 +1,24 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildCreateStore;
var _redux = require("redux");
function buildCreateStore(reducer, initial, middleware, actions) {
return () => {
const store = (0, _redux.createStore)(reducer, initial, (0, _redux.applyMiddleware)(middleware));
for (let a in actions) {
store.dispatch[a] = (...args) => {
store.dispatch(actions[a](...args));
};
}
return store;
};
}
;

14
dist/buildInitial/index.js vendored Normal file
View File

@ -0,0 +1,14 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildInitial;
var _fp = _interopRequireDefault(require("lodash/fp"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function buildInitial(initial = {}, subduxes = {}) {
return _fp.default.isPlainObject(initial) ? _fp.default.mergeAll([subduxes, initial]) : initial;
}

1
dist/buildInitial/index.test-d.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";

1
dist/buildInitial/test-d.js vendored Normal file
View File

@ -0,0 +1 @@
"use strict";

27
dist/buildMiddleware.js vendored Normal file
View File

@ -0,0 +1,27 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildMiddleware;
var _fp = _interopRequireDefault(require("lodash/fp"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const MiddlewareFor = (type, mw) => api => next => action => {
if (type !== '*' && action.type !== type) return next(action);
return mw(api)(next)(action);
};
function buildMiddleware(effects = {}, actions = {}, subduxes = {}) {
return api => {
for (let type in actions) {
api.dispatch[type] = (...args) => api.dispatch(actions[type](...args));
}
return original_next => {
return [..._fp.default.toPairs(effects).map(([type, effect]) => MiddlewareFor(type, effect)), ..._fp.default.map('middleware', subduxes)].filter(x => x).reduceRight((next, mw) => mw(api)(next), original_next);
};
};
}

52
dist/buildMutations/index.js vendored Normal file
View File

@ -0,0 +1,52 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildMutations;
var _fp = _interopRequireDefault(require("lodash/fp"));
var _updeep = _interopRequireDefault(require("updeep"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const composeMutations = mutations => mutations.reduce((m1, m2) => (payload = null, action = {}) => state => m2(payload, action)(m1(payload, action)(state)));
function buildMutations(mutations = {}, subduxes = {}) {
// we have to differentiate the subduxes with '*' than those
// without, as the root '*' is not the same as any sub-'*'
const actions = _fp.default.uniq(Object.keys(mutations).concat(...Object.values(subduxes).map(({
mutations = {}
}) => Object.keys(mutations))));
let mergedMutations = {};
let [globby, nonGlobby] = _fp.default.partition(([_, {
mutations = {}
}]) => mutations['*'], Object.entries(subduxes));
globby = _fp.default.flow([_fp.default.fromPairs, _fp.default.mapValues(({
reducer
}) => (_, action = {}) => state => reducer(state, action))])(globby);
const globbyMutation = (payload, action) => (0, _updeep.default)(_fp.default.mapValues(mut => mut(payload, action))(globby));
actions.forEach(action => {
mergedMutations[action] = [globbyMutation];
});
nonGlobby.forEach(([slice, {
mutations = {},
reducer = {}
}]) => {
Object.entries(mutations).forEach(([type, mutation]) => {
const localized = (payload = null, action = {}) => _updeep.default.updateIn(slice)(mutation(payload, action));
mergedMutations[type].push(localized);
});
});
Object.entries(mutations).forEach(([type, mutation]) => {
mergedMutations[type].push(mutation);
});
return _fp.default.mapValues(composeMutations)(mergedMutations);
}

19
dist/buildUpreducer/index.js vendored Normal file
View File

@ -0,0 +1,19 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = buildUpreducer;
var _fp = _interopRequireDefault(require("lodash/fp"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function buildUpreducer(initial, mutations) {
return (action = {}) => state => {
if (state === null) state = initial;
const a = mutations[action.type] || mutations['*'];
if (!a) return state;
return a(action.payload, action)(state);
};
}

18
dist/index.js vendored Normal file
View File

@ -0,0 +1,18 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = updux;
var _fp = _interopRequireDefault(require("lodash/fp"));
var _updeep = _interopRequireDefault(require("updeep"));
var _updux = _interopRequireDefault(require("./updux"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function updux(config) {
return new _updux.default(config);
}

92
dist/middleware.test.js vendored Normal file
View File

@ -0,0 +1,92 @@
"use strict";
var _ = _interopRequireDefault(require("."));
var _updeep = _interopRequireDefault(require("updeep"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
test('simple effect', () => {
const tracer = jest.fn();
const store = (0, _.default)({
effects: {
foo: api => next => action => {
tracer();
next(action);
}
}
}).createStore();
expect(tracer).not.toHaveBeenCalled();
store.dispatch({
type: 'bar'
});
expect(tracer).not.toHaveBeenCalled();
store.dispatch.foo();
expect(tracer).toHaveBeenCalled();
});
test('effect and sub-effect', () => {
const tracer = jest.fn();
const tracerEffect = signature => api => next => action => {
tracer(signature);
next(action);
};
const store = (0, _.default)({
effects: {
foo: tracerEffect('root')
},
subduxes: {
zzz: (0, _.default)({
effects: {
foo: tracerEffect('child')
}
})
}
}).createStore();
expect(tracer).not.toHaveBeenCalled();
store.dispatch({
type: 'bar'
});
expect(tracer).not.toHaveBeenCalled();
store.dispatch.foo();
expect(tracer).toHaveBeenNthCalledWith(1, 'root');
expect(tracer).toHaveBeenNthCalledWith(2, 'child');
});
test('"*" effect', () => {
const tracer = jest.fn();
const store = (0, _.default)({
effects: {
'*': api => next => action => {
tracer();
next(action);
}
}
}).createStore();
expect(tracer).not.toHaveBeenCalled();
store.dispatch({
type: 'bar'
});
expect(tracer).toHaveBeenCalled();
});
test('async effect', async () => {
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
const tracer = jest.fn();
const store = (0, _.default)({
effects: {
foo: api => next => async action => {
next(action);
await timeout(1000);
tracer();
}
}
}).createStore();
expect(tracer).not.toHaveBeenCalled();
store.dispatch.foo();
expect(tracer).not.toHaveBeenCalled();
await timeout(1000);
expect(tracer).toHaveBeenCalled();
});

79
dist/splat.test.js vendored Normal file
View File

@ -0,0 +1,79 @@
"use strict";
var _ = _interopRequireDefault(require("."));
var _updeep = _interopRequireDefault(require("updeep"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const tracer = chr => (0, _updeep.default)({
tracer: s => (s || '') + chr
});
test('mutations, simple', () => {
const dux = (0, _.default)({
mutations: {
foo: () => tracer('a'),
'*': (p, a) => tracer('b')
}
});
const store = dux.createStore();
expect(store.getState()).toEqual({
tracer: 'b'
});
store.dispatch.foo();
expect(store.getState()).toEqual({
tracer: 'ba'
});
store.dispatch({
type: 'bar'
});
expect(store.getState()).toEqual({
tracer: 'bab'
});
});
test('with subduxes', () => {
const dux = (0, _.default)({
mutations: {
foo: () => tracer('a'),
'*': (dummy, a) => tracer('b'),
bar: () => ({
bar
}) => ({
bar,
tracer: bar.tracer
})
},
subduxes: {
bar: (0, _.default)({
mutations: {
foo: () => tracer('d'),
'*': (dummy, a) => tracer('e')
}
})
}
});
const store = dux.createStore();
expect(store.getState()).toEqual({
tracer: 'b',
bar: {
tracer: 'e'
}
});
store.dispatch.foo();
expect(store.getState()).toEqual({
tracer: 'ba',
bar: {
tracer: 'ed'
}
});
store.dispatch({
type: 'bar'
});
expect(store.getState()).toEqual({
tracer: 'ede',
bar: {
tracer: 'ede'
}
});
});

205
dist/test.js vendored Normal file
View File

@ -0,0 +1,205 @@
"use strict";
var _ = _interopRequireDefault(require("."));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
test('actions from mutations', () => {
const {
actions: {
foo,
bar
}
} = (0, _.default)({
mutations: {
foo: () => x => x
}
});
expect(foo()).toEqual({
type: 'foo'
});
expect(foo(true)).toEqual({
type: 'foo',
payload: true
});
expect(foo({
bar: 2
}, {
timestamp: 613
})).toEqual({
type: 'foo',
payload: {
bar: 2
},
meta: {
timestamp: 613
}
});
});
test('reducer', () => {
const {
actions,
reducer
} = (0, _.default)({
initial: {
counter: 1
},
mutations: {
inc: () => ({
counter
}) => ({
counter: counter + 1
})
}
});
let state = reducer(null, {});
expect(state).toEqual({
counter: 1
});
state = reducer(state, actions.inc());
expect(state).toEqual({
counter: 2
});
});
test('sub reducers', () => {
const foo = (0, _.default)({
initial: 1,
mutations: {
doFoo: () => x => x + 1,
doAll: () => x => x + 10
}
});
const bar = (0, _.default)({
initial: 'a',
mutations: {
doBar: () => x => x + 'a',
doAll: () => x => x + 'b'
}
});
const {
initial,
actions,
reducer
} = (0, _.default)({
subduxes: {
foo,
bar
}
});
expect(initial).toEqual({
foo: 1,
bar: 'a'
});
expect(Object.keys(actions)).toHaveLength(3);
let state = reducer(null, {});
expect(state).toEqual({
foo: 1,
bar: 'a'
});
state = reducer(state, actions.doFoo());
expect(state).toEqual({
foo: 2,
bar: 'a'
});
state = reducer(state, actions.doBar());
expect(state).toEqual({
foo: 2,
bar: 'aa'
});
state = reducer(state, actions.doAll());
expect(state).toEqual({
foo: 12,
bar: 'aab'
});
});
test('precedence between root and sub-reducers', () => {
const {
initial,
reducer,
actions
} = (0, _.default)({
initial: {
foo: {
bar: 4
}
},
mutations: {
inc: () => state => {
return { ...state,
surprise: state.foo.bar
};
}
},
subduxes: {
foo: (0, _.default)({
initial: {
bar: 2,
quux: 3
},
mutations: {
inc: () => state => ({ ...state,
bar: state.bar + 1
})
}
})
}
});
expect(initial).toEqual({
foo: {
bar: 4,
quux: 3
}
});
expect(reducer(null, actions.inc())).toEqual({
foo: {
bar: 5,
quux: 3
},
surprise: 5
});
});
function timeout(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
test('middleware', async () => {
const {
middleware,
createStore
} = (0, _.default)({
initial: "",
mutations: {
inc: addition => state => state + addition,
doEeet: () => state => {
return state + 'Z';
}
},
effects: {
doEeet: api => next => async action => {
api.dispatch.inc('a');
next(action);
await timeout(1000);
api.dispatch.inc('c');
}
},
subduxes: {
foo: (0, _.default)({
effects: {
doEeet: api => next => action => {
api.dispatch({
type: 'inc',
payload: 'b'
});
next(action);
}
}
})
}
});
const store = createStore();
store.dispatch.doEeet();
expect(store.getState()).toEqual('abZ');
await timeout(1000);
expect(store.getState()).toEqual('abZc');
});

48
dist/updux.js vendored Normal file
View File

@ -0,0 +1,48 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = exports.Updux = void 0;
var _fp = _interopRequireDefault(require("lodash/fp"));
var _buildActions = _interopRequireDefault(require("./buildActions"));
var _buildInitial = _interopRequireDefault(require("./buildInitial"));
var _buildMutations = _interopRequireDefault(require("./buildMutations"));
var _buildCreateStore = _interopRequireDefault(require("./buildCreateStore"));
var _buildMiddleware = _interopRequireDefault(require("./buildMiddleware"));
var _buildUpreducer = _interopRequireDefault(require("./buildUpreducer"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
class Updux {
constructor(config) {
this.subduxes = _fp.default.mapValues(value => _fp.default.isPlainObject(value) ? new Updux(value) : value)(_fp.default.getOr({}, 'subduxes', config));
this.actions = (0, _buildActions.default)(config.actions, config.mutations, config.effects, Object.values(this.subduxes).map(({
actions
}) => actions));
this.initial = (0, _buildInitial.default)(config.initial, _fp.default.mapValues(({
initial
}) => initial)(this.subduxes));
this.mutations = (0, _buildMutations.default)(config.mutations, this.subduxes);
this.upreducer = (0, _buildUpreducer.default)(this.initial, this.mutations);
this.reducer = (state, action) => {
return this.upreducer(action)(state);
};
this.middleware = (0, _buildMiddleware.default)(config.effects, this.actions, config.subduxes);
this.createStore = (0, _buildCreateStore.default)(this.reducer, this.initial, this.middleware, this.actions);
}
}
exports.Updux = Updux;
var _default = Updux;
exports.default = _default;