typedux
Version:
Slightly adjusted Redux (awesome by default) for TS
168 lines • 4.63 kB
JavaScript
import { Option } from "@3fv/prelude-ts";
import { getLogger } from "@3fv/logger-proxy";
import { makeId } from "../util/IdGenerator";
import { INTERNAL_KEY } from "../constants";
// const
// _cloneDeep = require('lodash.cloneDeep')
const log = getLogger(__filename);
/**
* Create a fully qualified action type
*
* @param leaf
* @param type
*
* @returns {string}
*/
export function createLeafActionType(leaf, type) {
return type.indexOf(".") > -1 ? type : `${leaf}.${type}`;
}
export function createActionRegistration(actionFactoryCtor, leaf, type, action, options = {}) {
return {
type,
fullName: createLeafActionType(leaf, type),
leaf,
options,
actionFactoryCtor,
action: (decorator, ...args) => {
let actions = decorator ? decorator(actionFactoryCtor) : null;
if (!actions) {
const newFactory = options.factoryCtor || actionFactoryCtor;
actions = new newFactory();
}
return action.apply(actions, args);
}
};
}
let globalStore;
// /**
// * Reference to a dispatcher
// */
// let dispatch:DispatchState
//
// /**
// * Reference to store state
// */
// let getStoreState:GetStoreState
export const getGlobalStore = () => globalStore;
export const getGlobalStoreState = () => { var _a; return (_a = getGlobalStore()) === null || _a === void 0 ? void 0 : _a.getState(); };
const globalDispatchProvider = ((action) => Option.ofNullable(globalStore)
.map(store => store.dispatch(action))
.getOrThrow(`Invalid store`));
/**
* Get the current store state get
* function - usually set when a new state is created
*
* @returns {GetStoreState}
*/
export function getGlobalStateProvider() {
return getGlobalStoreState;
}
/**
* Get the current store
* dispatch function
*
* @returns {DispatchState}
*/
export function getGlobalDispatchProvider() {
return globalDispatchProvider;
}
/**
* Get the stores internal state
*
* @returns {GetStoreState|any}
*/
export function getGlobalStoreInternalState() {
return Option.ofNullable(getGlobalStoreState())
.map(state => state[INTERNAL_KEY])
.getOrUndefined();
}
/**
* Set the global store provider
*
* @param newStore
*/
export function setGlobalStore(newStore) {
if (!newStore && process.env.NODE_ENV === "development") {
console.warn(`You are setting the global store to null`);
}
// Cast the guarded type
globalStore = newStore;
}
export class ActionContainer {
constructor(store) {
this.store = store;
this.registeredActions = {};
this.actionInterceptors = [];
}
/**
* Add an interceptor
*
* @param interceptor
* @returns {()=>undefined}
*/
addActionInterceptor(interceptor) {
const { actionInterceptors } = this;
actionInterceptors.push(interceptor);
return () => {
const index = actionInterceptors.findIndex(o => interceptor === o);
if (index > -1)
actionInterceptors.splice(index, 1);
};
}
/**
* Execute an interceptor at a specific index
*
* @param index
* @param reg
* @param actionId
* @param action
* @param args
* @returns {any}
*/
executeActionInterceptor(index, reg, actionId, action, args) {
const { actionInterceptors, store } = this;
if (actionInterceptors.length > index) {
return actionInterceptors[index](reg, () => {
return this.executeActionInterceptor(index + 1, reg, actionId, action, args);
}, ...args);
}
else {
return action(actionId, ...args);
}
}
/**
* Execute a given action chain
*
* @param reg
* @param actionFn
* @param args
* @returns {any|any}
*/
executeActionChain(reg, actionFn, ...args) {
return this.executeActionInterceptor(0, reg, makeId(), actionFn, args);
}
/**
* Register an action from a decoration usually
*
* @param reg
* @return {ActionRegistration}
*/
registerAction(reg) {
this.registeredActions[reg.fullName] = reg;
return reg;
}
/**
* Retrieve a registered leaf action
*
* @param leaf
* @param type
* @returns {ActionRegistration}
*/
getAction(leaf, type) {
return this.registeredActions[createLeafActionType(leaf, type)];
}
getAllActions() {
return this.registeredActions; // _cloneDeep(registeredActions)
}
}
//# sourceMappingURL=Actions.js.map