typedux
Version:
Slightly adjusted Redux (awesome by default) for TS
293 lines • 13.3 kB
JavaScript
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spread = (this && this.__spread) || function () {
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
return ar;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
(function (factory) {
if (typeof module === "object" && typeof module.exports === "object") {
var v = factory(require, exports);
if (v !== undefined) module.exports = v;
}
else if (typeof define === "function" && define.amd) {
define(["require", "exports", "@3fv/logger-proxy", "../reducers/RootReducer", "redux", "symbol-observable", "@3fv/guard", "../util", "../actions", "./StateObserver", "../reducers/DefaultLeafReducer", "../constants", "../internal/InternalState", "../reducers/DumbReducer", "../selectors", "lodash/get", "@3fv/prelude-ts", "../dev"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ObservableStore = exports.processLeafReducersAndStates = void 0;
var logger_proxy_1 = require("@3fv/logger-proxy");
var RootReducer_1 = __importDefault(require("../reducers/RootReducer"));
// Vendor
var redux_1 = require("redux");
require("symbol-observable");
var guard_1 = require("@3fv/guard");
var util_1 = require("../util");
var actions_1 = require("../actions");
var StateObserver_1 = __importDefault(require("./StateObserver"));
var DefaultLeafReducer_1 = require("../reducers/DefaultLeafReducer");
var constants_1 = require("../constants");
var InternalState_1 = require("../internal/InternalState");
var DumbReducer_1 = __importDefault(require("../reducers/DumbReducer"));
var selectors_1 = require("../selectors");
var get_1 = __importDefault(require("lodash/get"));
var prelude_ts_1 = require("@3fv/prelude-ts");
var dev_1 = require("../dev");
var log = logger_proxy_1.getLogger(__filename);
function processLeafReducersAndStates(leafReducersOrStates) {
var leafReducers = leafReducersOrStates.filter(function (it) {
return util_1.isFunction(guard_1.getValue(function () { return it.leaf; }));
}), leafStates = leafReducersOrStates.filter(function (it) {
return !util_1.isFunction(guard_1.getValue(function () { return it.leaf; })) &&
util_1.isString(guard_1.getValue(function () { return it.type; }));
}), otherReducers = leafReducersOrStates.filter(function (it) {
return util_1.isFunction(it);
});
return __spread(otherReducers, leafReducers, leafStates.map(function (state) { return new DumbReducer_1.default(state); }));
}
exports.processLeafReducersAndStates = processLeafReducersAndStates;
/**
* Manage the redux store for RADS
*/
var ObservableStore = /** @class */ (function () {
function ObservableStore(leafReducersOrStates, enhancer, rootStateType, defaultStateValue) {
var _this = this;
if (enhancer === void 0) { enhancer = undefined; }
if (rootStateType === void 0) { rootStateType = undefined; }
if (defaultStateValue === void 0) { defaultStateValue = undefined; }
this.rootStateType = rootStateType;
this.defaultStateValue = defaultStateValue;
this.observers = [];
this.actionFactories = new Map();
this.observable = function () {
var _a;
var store = _this;
return _a = {
/**
* The minimal observable subscription method.
* @param {Object} observer Any object that can be used as an observer.
* The observer object should have a `next` method.
* @returns {subscription} An object with an `unsubscribe` method that can
* be used to unsubscribe the observable from the store, and prevent further
* emission of values from the observable.
*/
subscribe: function (observer) {
if (typeof observer !== "object" || observer === null) {
throw new TypeError("Expected the observer to be an object.");
}
function observeState() {
if (observer.next) {
observer.next(store.getState());
}
}
observeState();
var unsubscribe = store.subscribe(observeState);
return { unsubscribe: unsubscribe };
}
},
_a[Symbol.observable] = store.observable,
_a;
};
this[Symbol.observable] = this.observable;
this.actionContainer = new actions_1.ActionContainer(this);
this.createRootReducer.apply(this, __spread([ObservableStore.createInternalReducer()], processLeafReducersAndStates(leafReducersOrStates)));
this.store = redux_1.createStore(this.rootReducerFn, this.rootReducer.defaultState(defaultStateValue), enhancer !== null && enhancer !== void 0 ? enhancer : (function (next) { return next; }));
this.subscribe(function () { return _this.scheduleNotification(); });
}
/**
* Factory method for creating a new observable store
*
* @param enhancer
* @returns {ObservableStore<S>}
* @param rootStateType
* @param defaultStateValue
* @param leafReducersOrStates
*/
ObservableStore.createObservableStore = function (leafReducersOrStates, enhancer, rootStateType, defaultStateValue) {
if (enhancer === void 0) { enhancer = undefined; }
if (rootStateType === void 0) { rootStateType = undefined; }
if (defaultStateValue === void 0) { defaultStateValue = undefined; }
return new ObservableStore(leafReducersOrStates, enhancer, rootStateType, defaultStateValue);
};
/**
* Create simple reducers
*
* @param {string | State} statesOrKeys
* @returns {Array<State>}
*/
ObservableStore.makeSimpleReducers = function () {
var statesOrKeys = [];
for (var _i = 0; _i < arguments.length; _i++) {
statesOrKeys[_i] = arguments[_i];
}
return statesOrKeys
.map(function (state) { return (util_1.isString(state) ? { type: state } : state); })
.map(function (state) { return new DumbReducer_1.default(state); });
};
/**
* Create a internal reducer
*
* @returns {DefaultLeafReducer<InternalState, ActionMessage<InternalState>>}
*/
ObservableStore.createInternalReducer = function () {
return DefaultLeafReducer_1.DefaultLeafReducer.create(constants_1.INTERNAL_KEY, InternalState_1.InternalState);
};
ObservableStore.prototype.setOnError = function (onError) {
var _a;
(_a = this.rootReducer) === null || _a === void 0 ? void 0 : _a.setOnError(onError);
return this;
};
/**
* Get a prepared set of actions
*
* @param keyOrCtor - class name of class constructor to search for
*/
ObservableStore.prototype.getActions = function (keyOrCtor) {
var _this = this;
var key = util_1.isString(keyOrCtor) ? keyOrCtor : keyOrCtor.name;
return prelude_ts_1.Option.ofNullable(this.actionFactories.get(key)).getOrCall(function () {
if (util_1.isString(keyOrCtor)) {
throw Error("No registered actions with key: " + keyOrCtor);
}
var actions = new keyOrCtor(_this);
_this.actionFactories.set(key, actions);
return actions;
});
};
/**
* Create a new root reducer
*
* @param leafReducers
* @returns {any}
*/
ObservableStore.prototype.createRootReducer = function () {
var leafReducers = [];
for (var _i = 0; _i < arguments.length; _i++) {
leafReducers[_i] = arguments[_i];
}
this.rootReducer = new (RootReducer_1.default.bind.apply(RootReducer_1.default, __spread([void 0, this,
this.rootStateType], leafReducers)))();
this.rootReducerFn = this.rootReducer.makeGenericHandler();
return this.rootReducerFn;
};
/**
* Retrieve the redux store under everything
*
* @returns {any}
*/
ObservableStore.prototype.getReduxStore = function () {
return this.store;
};
/**
* Update the reducers
*/
ObservableStore.prototype.replaceReducers = function () {
var leafReducers = [];
for (var _i = 0; _i < arguments.length; _i++) {
leafReducers[_i] = arguments[_i];
}
var rootReducerFn = this.createRootReducer.apply(this, __spread([ObservableStore.createInternalReducer()], leafReducers));
this.store.replaceReducer(rootReducerFn);
};
ObservableStore.prototype.subscribe = function (listener) {
return this.getReduxStore().subscribe(listener);
};
ObservableStore.prototype.replaceReducer = function (nextReducer) {
throw new Error("We don't play with no regular reducers ;)");
};
/**
* Retrieve the current state
* @returns {*}
*/
ObservableStore.prototype.getState = function () {
return this.getReduxStore().getState();
};
ObservableStore.prototype.getInternalState = function () {
return this.getState()[constants_1.INTERNAL_KEY];
};
/**
* Dispatch typed message
*
* @param action
* @returns {A|undefined|IAction}
*/
ObservableStore.prototype.dispatch = function (action) {
return this.getReduxStore().dispatch(action);
};
/**
* Schedule notifications to go out on next tick
*/
ObservableStore.prototype.scheduleNotification = function () {
var state = this.getState();
this.observers.forEach(function (listener) { return listener.onChange(state); });
};
/**
*
*/
ObservableStore.prototype.onChange = function () {
this.scheduleNotification();
};
/**
* Create a new selector from the store's state
*/
ObservableStore.prototype.selector = function () {
return selectors_1.selectorChain(this, null);
};
ObservableStore.prototype.observe = function (pathOrSelector, handler) {
var _this = this;
var selector;
if (util_1.isString(pathOrSelector) || Array.isArray(pathOrSelector)) {
var keyPath_1 = pathOrSelector
? Array.isArray(pathOrSelector)
? pathOrSelector
: pathOrSelector.split(".")
: [];
selector = (function (state) { return _this.getValueAtPath(state, keyPath_1); });
}
else {
selector = pathOrSelector;
}
var observer = new StateObserver_1.default(selector, handler);
this.observers.push(observer);
return function () {
if (observer.removed) {
if (log.isDebugEnabled() && dev_1.isDev) {
log.debug("Already removed this observer", observer);
}
return;
}
_this.observers.find(function (it, index) {
if (observer === it) {
_this.observers.splice(index, 1);
return true;
}
return false;
});
observer.removed = true;
};
};
ObservableStore.prototype.getValueAtPath = function (state, keyPath) {
return get_1.default(state, keyPath);
};
return ObservableStore;
}());
exports.ObservableStore = ObservableStore;
});
//# sourceMappingURL=ObservableStore.js.map