{"id":20495307,"url":"https://github.com/kevinast/feature-redux","last_synced_at":"2025-06-13T13:02:14.355Z","repository":{"id":29062372,"uuid":"119876977","full_name":"KevinAst/feature-redux","owner":"KevinAst","description":"feature-u redux integration","archived":false,"fork":false,"pushed_at":"2022-12-07T20:36:59.000Z","size":1626,"stargazers_count":3,"open_issues_count":14,"forks_count":3,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-07T08:36:49.076Z","etag":null,"topics":["feature","feature-u","features","react","redux"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/KevinAst.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-02-01T18:35:13.000Z","updated_at":"2020-02-05T19:53:37.000Z","dependencies_parsed_at":"2023-01-14T14:03:41.575Z","dependency_job_id":null,"html_url":"https://github.com/KevinAst/feature-redux","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Ffeature-redux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Ffeature-redux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Ffeature-redux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/KevinAst%2Ffeature-redux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/KevinAst","download_url":"https://codeload.github.com/KevinAst/feature-redux/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248756504,"owners_count":21156780,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["feature","feature-u","features","react","redux"],"created_at":"2024-11-15T17:45:25.156Z","updated_at":"2025-04-13T17:43:41.349Z","avatar_url":"https://github.com/KevinAst.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# feature-redux *(feature-u redux integration)*\n\n**feature-redux** is your [feature-u] integration point to [redux]!\nIt promotes the [`reducerAspect`] _(a [feature-u] plugin)_ that\nfacilitates [redux] integration to your features.\n\n**Backdrop:**\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\n[feature-u] is a utility that facilitates feature-based project\norganization for your [react] project. It helps organize your\nproject by individual features.  [feature-u] is extendable. It\noperates under an open plugin architecture where Aspects integrate\n**feature-u** to other framework/utilities that match your specific\nrun-time stack.\n\n\u003c/ul\u003e\n\n\n\u003c!--- Badges for CI Builds ---\u003e \n[![Build Status](https://travis-ci.org/KevinAst/feature-redux.svg?branch=master)](https://travis-ci.org/KevinAst/feature-redux)\n[![Codacy Badge](https://api.codacy.com/project/badge/Grade/9c93a52aa6b6484ebd382ac976176836)](https://www.codacy.com/app/KevinAst/feature-redux?utm_source=github.com\u0026amp;utm_medium=referral\u0026amp;utm_content=KevinAst/feature-redux\u0026amp;utm_campaign=Badge_Grade)\n[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/9c93a52aa6b6484ebd382ac976176836)](https://www.codacy.com/app/KevinAst/feature-redux?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=KevinAst/feature-redux\u0026utm_campaign=Badge_Coverage)\n[![Known Vulnerabilities](https://snyk.io/test/github/kevinast/feature-redux/badge.svg?targetFile=package.json)](https://snyk.io/test/github/kevinast/feature-redux?targetFile=package.json)\n[![NPM Version Badge](https://img.shields.io/npm/v/feature-redux.svg)](https://www.npmjs.com/package/feature-redux)\n\n\n**Overview:**\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\n**feature-redux** configures [redux] through the [`reducerAspect`]\n(_which is supplied to_ **feature-u**'s [`launchApp()`]).  This\nextends **feature-u**'s [`Feature`] object by adding support for the\n`Feature.reducer` property, referencing feature-based [reducers].\n\nA feature-based reducer is simply a normal reducer that manages the\nfeature's slice of the the overall appState.  The only thing different\nis it must be embellished with [`slicedReducer()`], which provides\ninstructions on where to insert it in the overall top-level appState.\n\nOnly [reducers] are of interest to **feature-redux** because that is\nwhat is needed to configure [redux].  All other **redux** items (_[actions],\n[selectors], etc._) are internal implementation details of the feature.\n\nIt is important to understand that you continue to use [redux] the\nsame way you always have.  It's just that now you are dealing with a\n**smaller context** ... _within the boundaries of your feature_!\n\nAs an aside, because **feature-redux** manages redux, it also\nprovides an integration point to other Aspects that need to inject\ntheir [redux middleware].\n\n\u003c/ul\u003e\n\nLet's see how this all works together ...\n\n\n## At a Glance\n\n- [Install](#install)\n- [Usage](#usage)\n- [A Closer Look](#a-closer-look)\n  - [Actions](#actions)\n    - [Public Actions](#public-actions)\n    - [Action Uniqueness (Single Source of Truth)](#action-uniqueness-single-source-of-truth)\n  - [Reducers (state)](#reducers-state)\n    - [Sliced Reducers]\n    - [State Root (Single Source of Truth)](#state-root-single-source-of-truth)\n  - [Selectors (encapsulating state)](#selectors-encapsulating-state)\n    - [Public Selectors](#public-selectors)\n    - [Feature State Location (Single Source of Truth)](#feature-state-location-single-source-of-truth)\n- [Interface Points](#interface-points)\n  - [Inputs](#inputs)\n  - [Exposure](#exposure)\n  - [Error Conditions](#error-conditions)\n- [API](#api)\n  - [`reducerAspect: Aspect`](#reduceraspect-aspect)\n  - [`slicedReducer(slice, reducer): reducerFn`](#slicedreducer)\n- [Potential Need for Polyfills](#potential-need-for-polyfills)\n\n\n## Install\n\n- **peerDependencies** ... you should already have these, **because\n  this is our integration point** _(but just in case)_:\n\n  ```shell\n  npm install --save feature-u\n  npm install --save react\n  npm install --save redux\n  npm install --save react-redux\n  ```\n  \u003c!--- WITH REVEAL of USAGE:\n  npm install --save feature-u    # VER: \u003e=3.0.0   USAGE: createAspect(), extendAspectProperty() (v1 replaces App with Fassets obj -AND- publicFace with fassets aspect)\n  npm install --save react        # VER: \u003e=0.14.0  USAGE: inject \u003cProvider\u003e component\n  npm install --save redux        # VER: \u003e=3.1.0   USAGE: applyMiddleware(), combineReducers(), compose(), createStore()\n  npm install --save react-redux  # VER: \u003e=1.0.0   USAGE: \u003cProvider\u003e component\n  ---\u003e \n\n- **the main event**:\n\n  ```shell\n  npm install --save feature-redux\n  ```\n\n**SideBar**: Depending on how current your target browser is\n_(i.e. it's JavaScript engine)_, you may need to polyfill your app\n_(please refer to [Potential Need for\nPolyfills](#potential-need-for-polyfills))_.\n\n\n## Usage\n\n1. Within your mainline, register the **feature-redux**\n   [`reducerAspect`] to **feature-u**'s [`launchApp()`] _(see: `**1**`\n   below)_.\n\n   **src/app.js**\n   ```js\n   import {launchApp}           from 'feature-u';\n   import {createReducerAspect} from 'feature-redux'; // **1**\n   import features              from './feature';\n\n   export default launchApp({\n\n     aspects: [\n       createReducerAspect(),                         // **1**\n       ... other Aspects here\n     ],\n\n     features,\n\n     registerRootAppElm(rootAppElm) {\n       ReactDOM.render(rootAppElm,\n                       getElementById('myAppRoot'));\n     }\n   });\n   ```\n\n2. Within each feature that maintains state, simply register the\n   feature's reducer through the `Feature.reducer` property _(using\n   **feature-u**'s [`createFeature()`])_ ... _see: `**2**` below_.\n\n   Because the state of each feature is combined into one overall\n   appState, the feature reducer must identify it's root location,\n   through the [`slicedReducer()`] function.  This **slice** can\n   optionally reference a federated namespace corresponding to the\n   desired target shape.\n\n   **src/feature/myXyzFeature/index.js**\n   ```js\n   import {createFeature}  from 'feature-u';\n   import {slicedReducer}  from 'feature-redux';\n   import myXyzFeatureReducer from './state';\n   \n   export default createFeature({\n\n     name:     'myXyzFeature',\n\n     reducer:  slicedReducer('my.feature.state.location', myXyzFeatureReducer), // **2**\n\n     ... snip snip (other aspect properties here)\n   });\n   ```\n\n**Well that was easy!!** At this point **redux** is **completely setup\nfor your application!** The [redux store] has been created and is\naccessible through the standard **redux** [`connect()`] HoC,\nor the newer [`Hooks`] API.\n\nIn the nutshell, that's a highlight of most everything you need to know to use\n**feature-redux**!  _Go forth and compute!_\n\n\n## A Closer Look\n\n**feature-redux** automatically configures [redux] by creating the\n[store] _(accumulating feature [reducers] across your app)_, and\nmaking the [store] available through the standard **redux**\n[`connect()`] HoC (or the newer [`Hooks`] API), _(by injecting the\nstandard **redux** [`\u003cProvider\u003e`] component at the root of your app)_.\n\nIt is important to understand that your interface to [redux] has not\nchanged in any way.  In other words, you continue to use [redux] the\nsame way you always have.  It's just that now you are dealing with a\n**smaller context** ... _within the boundaries of your feature_!\n\nWith that said, as always, you should strive to keep each feature\nisolated, so it is truly **plug-and-play**.\nWorking with [redux], involves interacting with [actions],\n[reducers], and [selectors].  Let's take a closer look at some\n**Feature-Based Best Practices** in regard to [redux] usage.\n\n### Actions\n\nWithin the [redux] framework, [actions] are the basic building blocks\nthat facilitate application activity.\n\n- Actions follow a pre-defined convention that promote an action type\n  and a type-specific payload.\n\n- Actions are dispatched throughout the system (both UI components,\n  and logic modules).\n\n- Actions are monitored by [reducers] (which in turn change state), and\n  trigger UI changes.\n\n- Actions can also be monitored by logic modules _(when using\n  [redux-logic])_, that implement a variety of app-level logic\n  ... things like asynchronously gathering server resources, and even\n  dispatching other actions.\n\nIn general, **[actions] are considered to be an internal detail of the\nfeature**, and therefore are **NOT managed by feature-u**.  In other\nwords, *each feature will define and use it's own set of [actions]*.\n\nThis allows you to manage your actions however you wish.  Best\npractices prescribe that actions be created by [action creators]\n_(functions that return actions)_.  It is common to manage your action\ncreators and action types through a library like [action-u] or\n[redux-actions].\n\n#### Public Actions\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nThere are a small number of cases where feature-based actions may need\nto be promoted outside of a feature's boundary.  Say, for example,\nfeatureA's reducer needs to monitor one of featureB's actions, or one\nof featureB's logic modules needs to dispatch a featureA action.\n\nWhen this happens the **feature-u** [`fassets aspect`] can be used for\nthis promotion.\n\nPlease note that in consideration of feature encapsulation, *best\npractices would strive to minimize the public promotion of actions\noutside the feature boundary*.\n\n\u003c/ul\u003e\n\n#### Action Uniqueness (Single Source of Truth)\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nOne characteristic that [actions] must adhere to is: **action types must\nbe unique across the entire app**, *because they are interpreted at an\napp-level scope*.\n\nThis uniqueness is the responsibility of your implementation, because\n[feature-u] is not involved.  This may simply naturally happen in\nyour implementation.  \n\nIf however, you wish to systematically insure this uniqueness, the\nsimplest thing to do is to **prefix all your action types with the\nfeature name** _(**feature-u** guarantees all feature names are unique)_.\nThis has the *added benefit of readily associating dispatched action\nflows to the feature they belong to*.\n\n**Note**: Ideally you could use the `Feature.name` as the\nsingle-source-of-truth, however importing feature from your action\nmodules is problematic _(the [`Feature`] object will most likely not be\nfully resolved during in-line code expansion)_.  As a result, a **best\npractice** is to import a separate `featureName` constant (*that\nsimply holds the name*).  Here is an example:\n\n**src/feature/timer/featureName.js**\n```js\nexport default 'timer';\n```\n\n**src/feature/timer/actions.js**\n```js\nimport featureName  from './featureName';\n\n// action type constants\nexport const TIMER_START  = `${featureName}.TIMER_START`;\nexport const TIMER_CANCEL = `${featureName}.TIMER_CANCEL`;\nexport const TIMER_RESET  = `${featureName}.TIMER_RESET`;\nexport const TIMER_END    = `${featureName}.TIMER_END`;\n\n... snip snip\n```\n\n\u003c/ul\u003e\n\n### Reducers (state)\n\nWithin the [redux] framework, [reducers] monitor [actions], changing\nappState, which in turn triggers UI changes.\n\nEach feature (that maintains state), defines it's own reducer,\nmaintaining it's slice of the overall appState.\n\nWhile these [reducers] are truly opaque assets _(internal to the\nfeature)_, they are of interest to **feature-redux** to the extent\nthat they are needed to configure redux.\n\nEach feature that maintains state, simply registers it's reducer\nthrough the `Feature.reducer` property _(using **feature-u**'s\n[`createFeature()`])_.  \n\nBecause [reducers] may require access to **feature-u**'s [`Fassets\nobject`] during code expansion, this property can also be a\n**feature-u** [`expandWithFassets()`] callback _(a function that\nreturns the reducer)_ ... please refer to **feature-u**'s discussion\nof [Managed Code Expansion].\n\n#### Sliced Reducers\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nBecause **feature-redux** must combine the [reducers] from all features\ninto one overall appState, it requires that each reducer be\nembellished through the [`slicedReducer()`] function.  \n\nThis merely injects a slice property on the reducer function\n_(interpreted by **feature-redux**)_, specifying the location of the\nreducer within the top-level appState tree.\n\nThis **slice** can optionally reference a federated namespace\ncorresponding to the desired target shape.\n\nAs an example, consider the following definition _(see: `**4**`)_:\n\n```js\nconst currentView = createFeature({\n  name:     'currentView',\n  reducer:  slicedReducer('view.currentView', currentViewReducer), // **4**\n  ...\n});\n\nconst fooBar = createFeature({\n  name:     'fooBar',\n  reducer:  slicedReducer('view.fooBar', fooBarReducer),           // **4**\n  ...\n});\n```\n\nWhich yields the following overall appState:\n\n```js\nappState: {\n  view: {\n    currentView {\n      ... state managed by currentViewReducer\n    },\n    fooBar: {\n      ... state managed by fooBarReducer\n    },\n  },\n}\n```\n\n\u003c/ul\u003e\n\n\n#### State Root (Single Source of Truth)\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nYou are free to use any root location for your feature's state\n(i.e. the slice).  In many cases, this is dictated by the overall\nstate shape.\n\nHowever, depending on the context, it is often useful to use the\n`featureName` somewhere within this definition.  This **best\npractice** has the added benefit of readily associating each slice of\nstate to the feature they belong to.\n\nWe can refine the example above, by programmatically injecting the\n`featureName`.  This yields the same result as before, but benefits\nfrom the **single-source-of-truth** principle.\n\n```js\nimport featureName from './featureName';\nimport reducer     from './reducer';\n\nconst currentView = createFeature({\n  name:     featureName,\n  reducer:  slicedReducer(`view.${featureName}`, reducer),\n  ...\n});\n```\n\n\u003c/ul\u003e\n\n\n\n### Selectors (encapsulating state)\n\n[Selectors] are a [redux] best practice which encapsulates both the\nstate shape location and the business logic interpretation of that\nstate.\n\nSelectors should be used to encapsulate all your state.  Most\nselectors are promoted/used internally within the feature _(defined in\nclose proximity to your [reducers])_.\n\n\n#### Public Selectors\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nWhile **feature-redux** does not directly manage anything about\nselectors, a feature may wish to promote some of it's selectors using\nthe **feature-u** [`fassets aspect`].\n\nPlease note that in consideration of feature encapsulation, *best\npractices would strive to minimize the public promotion of feature\nstate (and selectors) outside the feature boundary*.\n\n\u003c/ul\u003e\n\n\n#### Feature State Location (Single Source of Truth)\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\nAnother benefit of [`slicedReducer()`] is that not only does it\nembellish the reducer with a `slice` property _(interpreted by\n**feature-redux**)_, it also injects a selector that returns the\nslicedState root, given the appState:\n\n```js\nreducer.getSlicedState(appState): slicedState\n```\n\nIn our case the slicedState is one in the same as the featureState, so\nas a **best practice** it can be used in all your selectors to further\nencapsulate this detail (**employing another single-source-of-truth\nprinciple**).\n\nHere is an example _(see: `**5**` and `**6**`)_:\n\n\n```js\n                             // **5** DEFINITION\n                             /** Our feature state root (a single-source-of-truth) */\nconst getFeatureState      = (appState) =\u003e reducer.getSlicedState(appState);\n\n                             // **6** USAGE\n                             /** Is device ready to run app */\nexport const isDeviceReady = (appState) =\u003e getFeatureState(appState).status === 'READY';\n\n... more selectors\n```\n\n\u003c/ul\u003e\n\n\n## Interface Points\n\nThe primary accomplishment of **feature-redux** is the creation (_and\nconfiguration_) of the [redux store].  The **Aspect Interface** to\nthis process (_i.e. the inputs and outputs_) are documented here.\n\n### Inputs\n\n1. **Primary Input**:\n\n   The primary input to **feature-redux** is the set of [reducers]\n   that make up the overall app reducer.  This is specified by each of\n   your features (_that maintain state_) through the `Feature.reducer`\n   property, containing a [`slicedReducer()`] that\n   manages the state of that corresponding feature.\n\n2. **Middleware Integration**:\n\n   Because **feature-redux** manages [redux], other Aspects can\n   promote their [redux middleware] through **feature-redux**'s\n   `Aspect.getReduxMiddleware()` API (an \"aspect cross-communication\n   mechanism\").  As an example, the [feature-redux-logic] Aspect\n   integrates **redux-logic**.\n\n3. **Enhancer Integration**:\n\n   Because **feature-redux** manages [redux], other Aspects can\n   promote their [redux enhancer] through **feature-redux**'s\n   `Aspect.getReduxEnhancer()` API (an \"aspect cross-communication\n   mechanism\").\n\n\n### Exposure\n\n1. **Primary Output**:\n\n   The primary way in which **feature-redux** exposes [redux] to your\n   app is by injecting the standard **redux** [`\u003cProvider\u003e`] component at\n   the root of your application DOM.  This enables app component\n   access to the [redux store] (along with it's `dispatch()` and\n   `getState()`) through the standard **redux** [`connect()`] HoC,\n   or the newer [`Hooks`] API.\n\n2. **Application Life Cycle Hooks - namedParams**:\n\n   **feature-redux** promotes the redux `getState`/`dispatch`\n   functions as namedParams of **feature-u**'s [Application Life Cycle\n   Hooks].\n\n3. **Redux Middleware**:\n\n   Because **feature-redux** allows other aspects to inject their\n   [redux middleware], whatever that middleware exposes is made\n   available.  As an example, the [feature-redux-logic] Aspect\n   injects **redux-logic**.\n\n4. **Redux Enhancer**:\n\n   Because **feature-redux** allows other aspects to inject their\n   [redux enhancer], whatever that enhancer exposes is made\n   available.\n   \n5. **Other**:\n\n   - For good measure, **feature-redux** promotes the [redux store]\n     through the `Aspect.getReduxStore()` method.  This provides direct\n     access to the [store] to any external process that needs it.\n\n   - Integration with Redux DevTools is automatically configured (when\n     detected).\n\n\n### Error Conditions\n\n- **NO REDUCERS**:\n\n  When **feature-redux** detects that no reducers have been\n  specified by any of your features, it will (by default) throw the\n  following exception:\n\n  ```\n  ***ERROR*** feature-redux found NO reducers within your features\n              ... did you forget to register Feature.reducer aspects in your features?\n              (please refer to the feature-redux docs to see how to override this behavior).\n  ```\n\n  Most likely this should in fact be considered an error _(for example\n  you neglected to specify the reducer aspects within your features)_.\n  **The reasoning is**: _why would you not specify any reducers if your\n  using redux?_\n\n  You can change this behavior through the `allowNoReducers` parameter:\n\n  ```js\n  createReducerAspect({allowNoReducers: true})\n  ```\n\n  - when `true`, and no reducers are found, redux will be configured\n    with an identity reducer (accompanied with a WARNING logging\n    probe).\n\n  - you can also specify your own app-wide reducer function in place\n    of the `true` value, which will be used ONLY in the scenario where\n    no reducers were specified by your features.\n\n\n## API\n\n### reducerAspect: Aspect\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\n```\nAPI: createReducerAspect({name:'reducer',\n                          initialState:undefined,\n                          allowNoReducers:false}): reducerAspect\n```\n\nThe `reducerAspect` is the [feature-u] plugin that facilitates\n[redux] integration to your features.\n\n**PARAMS**: _(**Please Note**: only named parameters are used)_\n\n- **name**: The name of this reducer (defaults to 'reducer')\n\n- **initialState**: An optional pre-loaded state that will become the initial\n  state of your store.  \n\n  Typically this is not needed, because your reducers will define the\n  initial state.\n  However, it can be useful to hydrate the state from the server (in\n  universal apps), or to restore a previously serialized user session.\n\n  When supplied, any validation/errors will be detected by redux, as\n  it is passed directly to it's `createStore()`.\n\n- **allowNoReducers**: A boolean -or- app-wide reducer function, that\n  specifies what to do when **no reducers** are found in any or your\n  features (defaults to `false` which throws an error) ... see: **NO\n  REDUCERS** section of [Error Conditions](#error-conditions)\n\n\n**USAGE**:\n\n- Within your mainline, register the **feature-redux**\n  `reducerAspect` to **feature-u**'s [`launchApp()`].\n\n- Within each feature that maintains state, simply register the\n  feature's reducer through the `Feature.reducer` property _(using\n  **feature-u**'s [`createFeature()`])_.\n\n  Because the state of each feature is combined into one overall\n  appState, the feature reducer must identify it's root location,\n  through the [`slicedReducer()`] function.  This **slice** can\n  optionally reference a federated namespace corresponding to the\n  desired target shape.\n\nPlease refer to the [Usage] section for examples of this process.\n\n\u003c/ul\u003e\n\n\n### slicedReducer()\n\n\u003cul\u003e\u003c!--- indentation hack for github - other attempts with style is stripped (be careful with number bullets) ---\u003e \n\n**API:** `slicedReducer(slice, reducer): reducer`\n\nEmbellish the supplied reducer with a slice property - a\nspecification (interpreted by **feature-redux**) as to the\nlocation of the reducer within the top-level appState tree.\n\nPlease refer to the [Sliced Reducers] section for a\ncomplete description with examples.\n\n**Note:** `slicedReducer()` should always wrap the the outer\nfunction passed to [`createFeature()`], even when [`expandWithFassets()`]\nis used.  This gives your app code access to the embellished\n`getSlicedState()` selector, even prior to expansion occurring (_used\nas a single-source-of-truth in your selector definitions_).\n\n\n**Parameters**:\n\n- **slice**: string\n\n  The location of the managed state within the overall top-level\n  appState tree.  This can be a federated namespace _(delimited by\n  dots)_.  Example: `'views.currentView'`\n\n- **reducer**: reducerFn\n\n  The redux [reducer] function to be embellished with the slice\n  specification.\n\n**Return**: reducerFn\n\n\u003cul style=\"margin-left: 2em;\"\u003e\n\nthe supplied reducer, embellished with both the slice and a\nconvenience selector:\n\n```js\nreducer.slice: slice\nreducer.getSlicedState(appState): slicedState\n```\n\u003c/ul\u003e\n\n\u003c/ul\u003e\n\n\n## Potential Need for Polyfills\n\nThe implementation of this library employs modern es2015+ JavaScript\nconstructs.  Even though the library distribution is transpiled to\n[es5](https://en.wikipedia.org/wiki/ECMAScript#5th_Edition) _(the\nleast common denominator)_, **polyfills may be required** if you are\nusing an antiquated JavaScript engine _(such as the IE browser)_.\n\nWe take the approach that **polyfills are the responsibility of the\nclient app**.  This is a legitimate approach, as specified by the [W3C\nPolyfill Findings](https://www.w3.org/2001/tag/doc/polyfills/)\n_(specifically [Advice for library\nauthors](https://www.w3.org/2001/tag/doc/polyfills/#advice-for-library-and-framework-authors))_.\n\n- polyfills should only be introduced one time _(during code expansion\n  of the app)_\n- a library should not pollute the global name space _(by including\n  polyfills at the library level)_\n- a library should not needlessly increase it's bundle size _(by\n  including polyfills that are unneeded in a majority of target\n  environments)_\n\nAs it turns out, **app-level polyfills are not hard to implement**,\nwith the advent of third-party utilities, such as babel:\n\n- simply import [babel-polyfill](https://babeljs.io/docs/en/babel-polyfill.html)\n- or use babel's\n  [babel-preset-env](https://babeljs.io/docs/en/babel-preset-env.html)\n  in conjunction with babel 7's `\"useBuiltins\": \"usage\"` option\n\n**If your target JavaScript engine is inadequate, it will generate\nnative run-time errors, and you will need to address the polyfills.**\nUnfortunately, in many cases these errors can be very obscure _(even\nto seasoned developers)_.  The following [Babel Feature\nRequest](https://github.com/babel/babel/issues/8089) _(if/when\nimplemented)_ is intended to address this issue.\n\n\n\n\n\u003c!--- *** REFERENCE LINKS *** ---\u003e \n\n\u003c!--- **feature-redux** ---\u003e \n[`reducerAspect`]:   #reduceraspect-aspect\n[Sliced Reducers]:   #sliced-reducers\n[Usage]:             #usage\n[`slicedReducer()`]: #slicedreducer\n\n\u003c!--- **feature-redux-logic** ---\u003e \n[feature-redux-logic]:  https://github.com/KevinAst/feature-redux-logic/\n\n\u003c!--- feature-u ---\u003e \n[feature-u]:              https://feature-u.js.org/\n[`launchApp()`]:          https://feature-u.js.org/cur/api.html#launchApp\n[`createFeature()`]:      https://feature-u.js.org/cur/api.html#createFeature\n[`expandWithFassets()`]:  https://feature-u.js.org/cur/api.html#expandWithFassets\n[`fassets aspect`]:       https://feature-u.js.org/cur/api.html#fassets\n[`Feature`]:              https://feature-u.js.org/cur/api.html#Feature\n[`Fassets object`]:       https://feature-u.js.org/cur/api.html#Fassets\n[Managed Code Expansion]: https://feature-u.js.org/cur/crossCommunication.html#managed-code-expansion\n\n\u003c!--- react ---\u003e \n[react]:            https://reactjs.org/\n\n\n\u003c!--- redux ---\u003e \n\n[redux]:            https://redux.js.org/\n[redux store]:      https://redux.js.org/glossary#store\n[store]:            https://redux.js.org/glossary#store\n[redux middleware]: https://redux.js.org/glossary#middleware\n[redux enhancer]:   https://redux.js.org/glossary#store-enhancer\n[actions]:          https://redux.js.org/glossary#action\n[action creators]:  https://redux.js.org/glossary#action-creator\n[reducers]:         https://redux.js.org/glossary#reducer\n[reducer]:          https://redux.js.org/glossary#reducer\n[selectors]:        https://gist.github.com/abhiaiyer91/aaf6e325cf7fc5fd5ebc70192a1fa170\n[`connect()`]:      https://react-redux.js.org/api/connect\n[`Hooks`]:          https://react-redux.js.org/api/hooks\n[`\u003cProvider\u003e`]:     https://react-redux.js.org/api/provider\n\n\u003c!--- redux-logic ---\u003e \n[redux-logic]:      https://github.com/jeffbski/redux-logic\n\n\u003c!--- 3rd party action managers ---\u003e \n[action-u]:         https://action-u.js.org/\n[redux-actions]:    https://github.com/reduxactions/redux-actions\n[Application Life Cycle Hooks]: https://feature-u.js.org/cur/appLifeCycle.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinast%2Ffeature-redux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkevinast%2Ffeature-redux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkevinast%2Ffeature-redux/lists"}