UNPKG

@aappddeevv/dynamics-client-ui

Version:

## What is it? A library to help you create great dynamics applications.

143 lines 5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /** Redux action management utilities. */ const effects_1 = require("redux-saga/effects"); /** * Create an action creator. Returns a function that creates an action message * with "type" type and argNames as properties on that message corresponding * to the arguments of the function call. The actual properties are computed * at runtime and hence, we cannot statically make a perfect return type. */ function makeActionCreator(type, ...argNames) { return (...args) => { // tslint:disable-next-line:no-object-literal-type-assertion const action = { type }; argNames.forEach((arg, index) => { action[arg] = args[index]; // was action[argNames[index]] = args[index] }); return action; }; } exports.makeActionCreator = makeActionCreator; /** Default set of prefixes and arg names for createMultiSelect() */ const multiPrefixes = [ { key: "SET_REFDATA", args: ["data"] }, { key: "SET", args: ["data"] }, { key: "ADD", args: ["data"] }, { key: "REMOVE", args: ["data"] }, { key: "CLEAR", args: [] }, { key: "SET_ALL", args: [] }, ]; // the above in object form, much easier to work with... const multiPrefixes2 = { SET_REFDATA: ["data"], SET: ["data"], ADD: ["data"], REMOVE: ["data"], CLEAR: [], SET_ALL: [], }; /** * Return an object with well-known keys that have action creators as values. * The returned object has properties from "key" but the * actual message type is under the property ACTION on the creator function and is * made up of the id and key together. * * TODO: Convert to object syntax for input, not goofy array. */ function createActionMap(id, prefixes) { // tslint:disable-next-line:no-object-literal-type-assertion const rval = {}; prefixes.forEach(p => { const key = p.key; const str = id + "." + key; // first arg must be "type", the rest are more data properties, if present const func = makeActionCreator.apply(null, [str].concat(p.args || [])); func.ACTION = str; rval[key] = func; }); return rval; } exports.createActionMap = createActionMap; /** * Create string ids and action creators i.e. Record<string, ActionCreator> * * ``` * const choices = createMultiSelect("somechoices") // returns an object * ``` * Dispatching: * ``` * dispatch(choices.SET_REFDATA(actionData)) * ``` * Reducing: * ``` * function reducer(state, action) { ... * case choices.SET_ALL.ACTION: * const data = action.data * ... * } * ``` */ function createMultiSelect(id) { return createActionMap(id, multiPrefixes); } exports.createMultiSelect = createMultiSelect; const singlePrefixes = [ { key: "SET_REFDATA", args: ["data"] }, { key: "SET", args: ["data"] }, { key: "CLEAR", args: [] }, ]; /** * Create a single select set of actions. * This is just a subset of those in a multi select, SET_REFDATA, SET and CLEAR. */ function createSingleSelect(id) { return createActionMap(id, singlePrefixes); } exports.createSingleSelect = createSingleSelect; /** * Create action and type for changing something. Args will be a subaction. * Name on object will be "change.prefix" by default. * * @deprecated Use mkWrapper */ exports.mkChange = (prefix, aname = "change") => { const actionName = `${aname}.${prefix}`; const func = makeActionCreator.apply(null, [actionName, "subaction"]); func.ACTION = actionName; return func; }; /** * Create action and type for changing something. Args will be a subaction. * Name on object will be "wrapper.prefix". */ exports.mkWrapper = (prefix) => exports.mkChange(prefix, "wrapper"); /** * Make a function from a "filterName" to create a saga * action channel on and a handler to call with the most * recent state. The subaction is dispatched before calling * the handler. You this to track the a message which wraps another * message and that needs to be detected in the saga middleware. * filterName should be called channelName. You still need to call * the returned function. * * @param {string} filterName Name of channel message type. * @param {Function} handler (action,state) => generator * @param {boolean} dispatchSubActon Dispatch subaction before calling the handler. * @return generator */ function mkSubactionSaga(filterName, handler, dispatchSubaction = true) { return function* () { const channel = yield effects_1.actionChannel(filterName); while (true) { const action = yield effects_1.take(channel); if (dispatchSubaction && action.subaction) yield effects_1.put.resolve(action.subaction); const state = yield effects_1.select(); if (handler) yield effects_1.call(() => handler(action, state)); } }; } exports.mkSubactionSaga = mkSubactionSaga; //# sourceMappingURL=actionutils.js.map