Full Code of alibaba/fish-redux for AI

master 40b853bfa084 cached
314 files
554.9 KB
148.8k tokens
833 symbols
1 requests
Download .txt
Showing preview only (624K chars total). Download the full file or copy to clipboard to get everything.
Repository: alibaba/fish-redux
Branch: master
Commit: 40b853bfa084
Files: 314
Total size: 554.9 KB

Directory structure:
gitextract_al9_2a3r/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       ├── custom.md
│       └── feature_request.md
├── .gitignore
├── .metadata
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── doc/
│   ├── README-cn.md
│   ├── README.md
│   ├── concept/
│   │   ├── action-cn.md
│   │   ├── action.md
│   │   ├── adapter-cn.md
│   │   ├── adapter.md
│   │   ├── auto-dispose-cn.md
│   │   ├── auto-dispose.md
│   │   ├── component-cn.md
│   │   ├── component.md
│   │   ├── connector-cn.md
│   │   ├── connector.md
│   │   ├── custom-adapter-cn.md
│   │   ├── custom-adapter.md
│   │   ├── dependencies-cn.md
│   │   ├── dependencies.md
│   │   ├── dependent-cn.md
│   │   ├── dependent.md
│   │   ├── directory-cn.md
│   │   ├── directory.md
│   │   ├── dynamic-flow-adapter-cn.md
│   │   ├── dynamic-flow-adapter.md
│   │   ├── effect-cn.md
│   │   ├── effect.md
│   │   ├── evolution-of-fish-redux.md
│   │   ├── features.md
│   │   ├── filter-cn.md
│   │   ├── filter.md
│   │   ├── higher-effect-cn.md
│   │   ├── higher-effect.md
│   │   ├── lifecycle-cn.md
│   │   ├── lifecycle.md
│   │   ├── mechanism-cn.md
│   │   ├── mechanism.md
│   │   ├── middleware-cn.md
│   │   ├── middleware.md
│   │   ├── on-error-cn.md
│   │   ├── on-error.md
│   │   ├── oop-cn.md
│   │   ├── oop.md
│   │   ├── page-cn.md
│   │   ├── page.md
│   │   ├── reducer-cn.md
│   │   ├── reducer.md
│   │   ├── redux-cn.md
│   │   ├── redux.md
│   │   ├── should-update-cn.md
│   │   ├── should-update.md
│   │   ├── static-flow-adapter-cn.md
│   │   ├── static-flow-adapter.md
│   │   ├── view-cn.md
│   │   ├── view.md
│   │   ├── what's-adapter.md
│   │   ├── what's-connector.md
│   │   ├── what's-the-diiference-cn.md
│   │   ├── what's-the-diiference.md
│   │   ├── widget-wrapper-cn.md
│   │   └── widget-wrapper.md
│   └── introduction/
│       ├── README-cn.md
│       └── README.md
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _navbar.md
│   ├── _sidebar.md
│   ├── concept/
│   │   ├── _navbar.md
│   │   ├── _sidebar.md
│   │   ├── action.md
│   │   ├── adapter.md
│   │   ├── auto-dispose.md
│   │   ├── component.md
│   │   ├── connector.md
│   │   ├── custom-adapter.md
│   │   ├── dependencies.md
│   │   ├── dependent.md
│   │   ├── directory.md
│   │   ├── dynamic-flow-adapter.md
│   │   ├── effect.md
│   │   ├── evolution-of-fish-redux.md
│   │   ├── features.md
│   │   ├── filter.md
│   │   ├── higher-effect.md
│   │   ├── lifecycle.md
│   │   ├── mechanism.md
│   │   ├── middleware-cn.md
│   │   ├── middleware.md
│   │   ├── on-error.md
│   │   ├── oop.md
│   │   ├── page.md
│   │   ├── reducer.md
│   │   ├── redux.md
│   │   ├── should-update.md
│   │   ├── static-flow-adapter.md
│   │   ├── view.md
│   │   ├── what's-adapter.md
│   │   ├── what's-connector.md
│   │   ├── what's-the-diiference.md
│   │   └── widget-wrapper.md
│   ├── index.html
│   └── zh-cn/
│       ├── README.md
│       ├── _sidebar.md
│       └── concept/
│           ├── _navbar.md
│           ├── _sidebar.md
│           ├── action.md
│           ├── adapter.md
│           ├── auto-dispose.md
│           ├── component.md
│           ├── connector.md
│           ├── custom-adapter.md
│           ├── dependencies.md
│           ├── dependent.md
│           ├── directory.md
│           ├── dynamic-flow-adapter.md
│           ├── effect.md
│           ├── filter.md
│           ├── higher-effect.md
│           ├── lifecycle.md
│           ├── mechanism.md
│           ├── middleware.md
│           ├── on-error.md
│           ├── oop.md
│           ├── page.md
│           ├── reducer.md
│           ├── redux.md
│           ├── should-update.md
│           ├── static-flow-adapter.md
│           ├── view.md
│           ├── what's-adapter.md
│           ├── what's-connector.md
│           ├── what's-the-diiference.md
│           └── widget-wrapper.md
├── example/
│   ├── .flutter-plugins-dependencies
│   ├── .gitignore
│   ├── .metadata
│   ├── README.md
│   ├── lib/
│   │   ├── app.dart
│   │   ├── global_store/
│   │   │   ├── action.dart
│   │   │   ├── reducer.dart
│   │   │   ├── state.dart
│   │   │   └── store.dart
│   │   ├── main.dart
│   │   ├── todo_edit_page/
│   │   │   ├── action.dart
│   │   │   ├── effect.dart
│   │   │   ├── page.dart
│   │   │   ├── state.dart
│   │   │   └── view.dart
│   │   └── todo_list_page/
│   │       ├── action.dart
│   │       ├── effect.dart
│   │       ├── flow_adapter/
│   │       │   ├── adapter.dart
│   │       │   ├── connector.dart
│   │       │   └── reducer.dart
│   │       ├── list_adapter/
│   │       │   ├── action.dart
│   │       │   ├── adapter.dart
│   │       │   └── reducer.dart
│   │       ├── page.dart
│   │       ├── reducer.dart
│   │       ├── report_component/
│   │       │   ├── component.dart
│   │       │   ├── state.dart
│   │       │   └── view.dart
│   │       ├── state.dart
│   │       ├── todo_component/
│   │       │   ├── action.dart
│   │       │   ├── component.dart
│   │       │   ├── effect.dart
│   │       │   ├── reducer.dart
│   │       │   ├── state.dart
│   │       │   └── view.dart
│   │       └── view.dart
│   ├── pubspec.yaml
│   ├── test/
│   │   └── widget_test.dart
│   └── web/
│       ├── index.html
│       └── manifest.json
├── fish_redux.iml
├── lib/
│   ├── fish_redux.dart
│   └── src/
│       ├── extensions/
│       │   ├── adapter_extensions.dart
│       │   ├── component_extensions.dart
│       │   ├── connector_extensions.dart
│       │   └── extendsions.dart
│       ├── redux/
│       │   ├── apply_middleware.dart
│       │   ├── basic.dart
│       │   ├── combine_reducers.dart
│       │   ├── connector.dart
│       │   ├── create_store.dart
│       │   └── redux.dart
│       ├── redux_adapter/
│       │   ├── adapter.dart
│       │   ├── dynamic_flow_adapter.dart
│       │   ├── flow_adapter.dart
│       │   ├── recycle_context.dart
│       │   ├── redux_adapter.dart
│       │   ├── source_flow_adapter.dart
│       │   └── static_flow_adapter.dart
│       ├── redux_aop/
│       │   ├── aop.dart
│       │   ├── common_aop/
│       │   │   ├── common_aop.dart
│       │   │   ├── debounce.dart
│       │   │   ├── debug.dart
│       │   │   ├── delay.dart
│       │   │   ├── log.dart
│       │   │   ├── memoize.dart
│       │   │   ├── performance.dart
│       │   │   ├── throttle.dart
│       │   │   └── wait_until.dart
│       │   └── redux_aop.dart
│       ├── redux_component/
│       │   ├── auto_dispose.dart
│       │   ├── basic.dart
│       │   ├── batch_store.dart
│       │   ├── component.dart
│       │   ├── context.dart
│       │   ├── dependencies.dart
│       │   ├── dependent.dart
│       │   ├── dispatch_bus.dart
│       │   ├── enhancer.dart
│       │   ├── helper.dart
│       │   ├── lifecycle.dart
│       │   ├── local.dart
│       │   ├── logic.dart
│       │   ├── page.dart
│       │   └── redux_component.dart
│       ├── redux_component_mixin/
│       │   ├── keep_alive_mixin.dart
│       │   ├── private_reducer_mixin.dart
│       │   ├── redux_component_mixin.dart
│       │   ├── single_ticker_provider_mixin.dart
│       │   ├── ticker_provider_mixin.dart
│       │   ├── visible_change_mixin.dart
│       │   └── widgets_binding_observer_mixin.dart
│       ├── redux_connector/
│       │   ├── connector.dart
│       │   ├── generator.dart
│       │   ├── helper.dart
│       │   ├── map_like.dart
│       │   ├── none.dart
│       │   ├── op_mixin.dart
│       │   ├── redux_connector.dart
│       │   └── reselect.dart
│       ├── redux_middleware/
│       │   ├── adapter_middleware/
│       │   │   ├── adapter_middleware.dart
│       │   │   └── safety_adapter.dart
│       │   ├── middleware/
│       │   │   ├── log.dart
│       │   │   ├── middleware.dart
│       │   │   └── performance.dart
│       │   ├── redux_middleware.dart
│       │   └── view_middleware/
│       │       ├── safety_view.dart
│       │       └── view_middleware.dart
│       ├── redux_routes/
│       │   ├── page_routes.dart
│       │   └── redux_routes.dart
│       └── utils/
│           ├── collections.dart
│           ├── debug.dart
│           ├── hash.dart
│           ├── tuple.dart
│           └── utils.dart
├── pubspec.yaml
└── test/
    ├── lib/
    │   ├── all_test.dart
    │   ├── instrument.dart
    │   ├── redux/
    │   │   ├── redux_test.dart
    │   │   └── store_test.dart
    │   ├── redux_adapter/
    │   │   ├── adapter_test.dart
    │   │   ├── dynamic_adapter_test.dart
    │   │   ├── redux_adapter_test.dart
    │   │   ├── source_adapter_test.dart
    │   │   └── static_flow_adapter_test.dart
    │   ├── redux_aop/
    │   │   ├── memoize_test.dart
    │   │   └── redux_aop_test.dart
    │   ├── redux_component/
    │   │   ├── auto_dispose_test.dart
    │   │   ├── component_test.dart
    │   │   ├── lifecycle_test.dart
    │   │   ├── page_test.dart
    │   │   └── redux_component_test.dart
    │   ├── redux_connector/
    │   │   ├── map_like_test.dart
    │   │   ├── redux_connector_test.dart
    │   │   └── reselect_test.dart
    │   ├── redux_middleware/
    │   │   └── redux_middleware_test.dart
    │   ├── redux_routes/
    │   │   └── redux_routes_test.dart
    │   ├── track.dart
    │   └── utils/
    │       ├── collections_test.dart
    │       └── utils_test.dart
    ├── pubspec.yaml
    └── test_widgets/
        ├── .gitignore
        ├── lib/
        │   ├── adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── component/
        │   │   ├── action.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── dynamic_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── component.dart
        │   │   ├── dynamic_flow_adapter.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── main.dart
        │   ├── page/
        │   │   ├── action.dart
        │   │   ├── exception.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── source_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   ├── source_flow_adapter.dart
        │   │   └── state.dart
        │   ├── static_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   ├── state.dart
        │   │   └── static_flow_adapter.dart
        │   └── test_base.dart
        └── pubspec.yaml

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: ''
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is. 
Show the code you wrote as completely as possible.
```dart
/// your code here
``` 

**To Reproduce**
Steps to reproduce the behavior.

**Expected behavior**
A clear and concise description of what you expected to happen.

**Additional context**
1. The version of fish-redux which you are using.
2. The information from flutter doctor.


================================================
FILE: .github/ISSUE_TEMPLATE/custom.md
================================================
---
name: Custom issue template
about: Describe this issue template's purpose here.
title: ''
labels: ''
assignees: ''

---




================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution you'd like**
A clear and concise description of what you want to happen.

**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.

**Additional context**
Add any other context or screenshots about the feature request here.


================================================
FILE: .gitignore
================================================
.DS_Store
.atom/
.idea/
.vscode/
.packages
.pub/
.dart_tool/
build/
pubspec.lock
android/
ios/
.gradle/
build.gradle
gradle/
gradlew
gradlew.bat
local.properties
redux.iml
pubspec.lock
android/local.properties

# docs
node_modules/


================================================
FILE: .metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
  revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
  channel: stable

project_type: package


================================================
FILE: .travis.yml
================================================
os:
    - linux
sudo: false
addons:
    apt:
        sources:
            - ubuntu-toolchain-r-test
        packages:
            - libstdc++6
            # - fonts-droid
before_script:
    - git clone https://github.com/flutter/flutter.git -b stable --depth 1
    - ./flutter/bin/flutter doctor
script:
    - ./flutter/bin/flutter test --coverage --coverage-path=lcov.info
after_success:
    - bash <(curl -s https://codecov.io/bash)
cache:
    directories:
        - $HOME/.pub-cache


================================================
FILE: CHANGELOG.md
================================================
## [0.3.7]
- fix test .
- revert issue 613

## [0.3.6]
- fix some dos .

## [0.3.5]
- fix deprecated using of api - inheritFromWidgetOfExactType .

## [0.3.4]
- fix PureViewComponent's dispatch bug

## [0.3.3]
- fix Page name duplication
- easy to use reselect
- add keep-alive-client wrapper
- fix spell error on pure-view-widget
- add default widget for component.buildComponent api
- add docsify to view docs
- add unit test for collection utils and maplike connector

## [0.3.2]
- fix Page name duplication

## [0.3.1]
- rename AdapterSource’s api 
- add PureViewComponent 
- deprecate broadcastEffect 
- 
## [0.3.0]
- add SourceFlowAdapter
- Use SourceFlowAdapter instead of DynamicFlowAdapter in example
- deprecate DynamicFlowAdapter

## [0.2.8]
- fix item-bean clone bug #493

## [0.2.7]
- add StateKey #461
- reselect optimization #482

## [0.2.6]
- add TickerProviderMixin
- let dispatch return whatever result in effect. #462 
- fix Reselect's _listEquals bug #457 
- fix SingleTickerProviderMixin & TickerProviderMixin’s dispose bug #461 
- add ClearOnDependenciesChanged 

## [0.2.5]
- add ctx.listen api
- rename LocalState to LocalProps
- correct some comments 

## [0.2.4]
- fix Context.broadcast bug #375
- fix PrivateReducerMixin bug #380 
- add LocalState

## [0.2.3]
- Reconstruct Context
- Breaking-change 
  - Reconstruct dependencies
  - Remove OOP style
  - Remove higherEffect
  - Remove deprecated api(Connector, createMixedStore, AutoDispose:follow, AutoDispose:follower)
  - Remove unused DisposedException
- Hide widgets.dart's Action to compate with flutter1.7
- Compate with flutter_web

## [0.2.2]
- add congruent conn 
- fields mainCtx & viewUpdater in ComponentState become public 
- fix bug when a store recived action after teardown

## [0.2.1]
- add forceUpdate api on context
- fix bug in adapter’s appear & disappear if items are recycled
- fix bug in connectStores api if page has no reducer

## [0.2.0]
- force update if driven by outside observable 
- fix inverter bugs & optimization connectStores api 
- modify the use of global state in example 

## [0.1.9]
- add mixed-store's batch notification feature

## [0.1.8]
- add api to subscribe app-store for page-store
- add api to subscribe app-store for component
- add viewMiddleware
- add adapterMiddleware
- add effectMiddleware
- add protected attribute method, more friendly to OOP
- remove debug_report

## [0.1.7]
- reconstruct mixed-store
- reconstruct communication
- rename appBroadcast to broadcast
- rename pageBroadcast to broadcastEffect
- add dispatch-bus
- enhance dispatch-api
- add some docs
- move test to dev_dependencies

## [0.1.6]
- fix bug if component has no reducer in app-routes
- reconstruct createStore
- app-routes's store to be visible

## [0.1.5]
- fix bug if notified on building
- reconstruct test
- add mergeMiddleware\$

## [0.1.4]
- add support for AppStore
- add routes
- move middleware/aop to the top dir
- add PrivateReducerMixin
- add reselect
- add docs

## [0.1.3]
- add support for immutable-state #111
- fix the same type of state component reuse in listview #107
- remove warnings in logMiddleware for debug-actions #98
- correct spelling
- modify bindAction #73

## [0.1.2]
- add stfState field in Context #58
- add batchedNotify feature in page-store
- add some docs
- correct spelling

## [0.1.1]
- fix hot-reload bug
- add excluedSelf in broadcast
- rename sample to example
- rename docs to doc


































================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright 2019 Alibaba, Inc.

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.

================================================
FILE: README.md
================================================
<p align="center"><img src="https://img.alicdn.com/tfs/TB1r74NJyLaK1RjSZFxXXamPFXa-1024-1024.png" align="center" width="175"></p>
<h1 align="center">Fish Redux</h1>

[![Build Status](https://travis-ci.org/alibaba/fish-redux.svg?branch=master)](https://travis-ci.org/alibaba/fish-redux) [![pub package](https://img.shields.io/pub/v/fish_redux.svg)](https://pub.dartlang.org/packages/fish_redux) [![codecov](https://codecov.io/gh/alibaba/fish-redux/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/fish-redux)

## What is Fish Redux ?

Fish Redux is an assembled flutter application framework based on Redux state management.
It is suitable for building medium and large applications.

It has four characteristics:

> 1. Functional Programming

> 2. Predictable state container

> 3. Pluggable componentization

> 4. Non-destructive performance

## Architecture diagram

<img src="https://img.alicdn.com/tfs/TB1pkhoJr2pK1RjSZFsXXaNlXXa-1004-1370.png" width="500px" height="680px">

## Installation

[Go](https://pub.dartlang.org/packages/fish_redux#-installing-tab-)

## Documentation

Language: [English](doc/README.md) | [中文简体](doc/README-cn.md)

## Examples

-   [todo list](example) - a simple todo list demo.
-   run it:

```
cd ./example
flutter create .
flutter run
```

## What's the difference between 'Fish Redux' and 'Redux' ?

-   [answers](doc/concept/what's-the-diiference.md)

## Plugins

### Code Template

-   [Fish Redux Template For Android Studio](https://github.com/BakerJQ/FishReduxTemplateForAS), by BakerJQ.
-   [Fish Redux Template For VSCode](https://github.com/huangjianke/fish-redux-template), by huangjianke.

### Dev-Tools

-   Redux Inspector (using [Flutter Debugger](https://github.com/blankapp/flutter-debugger) and [flipperkit_fish_redux_middleware](https://pub.dartlang.org/packages/flipperkit_fish_redux_middleware)) for Fish Redux apps, by [JianyingLi](https://github.com/lijy91)

## License

-   Fish Redux is released under the Apache 2.0 license. See [LICENSE](LICENSE) for details.


## 关于我们
阿里巴巴-闲鱼技术是国内最早也是最大规模线上运行Flutter的团队。

我们在公众号中为你精选了Flutter独家干货,全面而深入。

内容包括:Flutter的接入、规模化应用、引擎探秘、工程体系、创新技术等教程和开源信息。

**架构/服务端/客户端/前端/质量工程师 在公众号中投递简历,名额不限哦**

欢迎来闲鱼做一个好奇、幸福、有影响力的程序员,简历投递:tino.wjf@alibaba-inc.com

订阅地址

<img src="https://img.alicdn.com/tfs/TB17Ki5XubviK0jSZFNXXaApXXa-656-656.png" width="328px" height="328px">

[For English](https://twitter.com/xianyutech "For English")


================================================
FILE: analysis_options.yaml
================================================
# Specify analysis options.
#
# Until there are meta linter rules, each desired lint must be explicitly enabled.
# See: https://github.com/dart-lang/linter/issues/288
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
# See the configuration guide for more
# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
#
# There are four similar analysis options files in the flutter repos:
#   - analysis_options.yaml (this file)
#   - packages/flutter/lib/analysis_options_user.yaml
#   - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
#   - https://github.com/flutter/engine/blob/master/analysis_options.yaml
#
# This file contains the analysis options used by Flutter tools, such as IntelliJ,
# Android Studio, and the `flutter analyze` command.
#
# The flutter/plugins repo contains a copy of this file, which should be kept
# in sync with this file.

analyzer:
    language:
        enableSuperMixins: true
    strong-mode:
        implicit-dynamic: false
    errors:
        # treat missing required parameters as a warning (not a hint)
        missing_required_param: warning
        # treat missing returns as a warning (not a hint)
        missing_return: warning
        # allow having TODOs in the code
        todo: ignore

    exclude:
        - 'bin/cache/**'
        - 'flutter/**'
        # the following two are relative to the stocks example and the flutter package respectively
        # see https://github.com/dart-lang/sdk/issues/28463
        - 'lib/i18n/stock_messages_*.dart'
        - 'lib/src/http/**'

linter:
    rules:
        # these rules are documented on and in the same order as
        # the Dart Lint rules page to make maintenance easier
        # https://github.com/dart-lang/linter/blob/master/example/all.yaml
        - always_declare_return_types
        - always_put_control_body_on_new_line
        # - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
        - always_require_non_null_named_parameters
        - always_specify_types
        - annotate_overrides
        # - avoid_annotating_with_dynamic # conflicts with always_specify_types
        - avoid_as
        # - avoid_bool_literals_in_conditional_expressions # not yet tested
        # - avoid_catches_without_on_clauses # we do this commonly
        # - avoid_catching_errors # we do this commonly
        - avoid_classes_with_only_static_members
        - avoid_empty_else
        - avoid_function_literals_in_foreach_calls
        - avoid_init_to_null
        - avoid_null_checks_in_equality_operators
        # - avoid_positional_boolean_parameters # not yet tested
        # - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
        - avoid_relative_lib_imports
        - avoid_renaming_method_parameters
        - avoid_return_types_on_setters
        # - avoid_returning_null # we do this commonly
        # - avoid_returning_this # https://github.com/dart-lang/linter/issues/842
        # - avoid_setters_without_getters # not yet tested
        # - avoid_single_cascade_in_expression_statements # not yet tested
        - avoid_slow_async_io
        # - avoid_types_as_parameter_names # https://github.com/dart-lang/linter/pull/954/files
        # - avoid_types_on_closure_parameters # conflicts with always_specify_types
        # - avoid_unused_constructor_parameters # https://github.com/dart-lang/linter/pull/847
        - await_only_futures
        - camel_case_types
        - cancel_subscriptions
        # - cascade_invocations # not yet tested
        # - close_sinks # https://github.com/flutter/flutter/issues/5789
        # - comment_references # blocked on https://github.com/dart-lang/dartdoc/issues/1153
        # - constant_identifier_names # https://github.com/dart-lang/linter/issues/204
        - control_flow_in_finally
        - directives_ordering
        - empty_catches
        - empty_constructor_bodies
        - empty_statements
        - hash_and_equals
        - implementation_imports
        # - invariant_booleans # https://github.com/flutter/flutter/issues/5790
        - iterable_contains_unrelated_type
        # - join_return_with_assignment # not yet tested
        - library_names
        - library_prefixes
        - list_remove_unrelated_type
        # - literal_only_boolean_expressions # https://github.com/flutter/flutter/issues/5791
        - no_adjacent_strings_in_list
        - no_duplicate_case_values
        - non_constant_identifier_names
        # - omit_local_variable_types # opposite of always_specify_types
        # - one_member_abstracts # too many false positives
        # - only_throw_errors # https://github.com/flutter/flutter/issues/5792
        - overridden_fields
        - package_api_docs
        - package_names
        - package_prefixed_library_names
        # - parameter_assignments # we do this commonly
        - prefer_adjacent_string_concatenation
        - prefer_asserts_in_initializer_lists
        - prefer_bool_in_asserts
        - prefer_collection_literals
        - prefer_conditional_assignment
        - prefer_const_constructors
        - prefer_const_constructors_in_immutables
        - prefer_const_declarations
        - prefer_const_literals_to_create_immutables
        # - prefer_constructors_over_static_methods # not yet tested
        - prefer_contains
        # - prefer_equal_for_default_values # not yet tested
        # - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
        - prefer_final_fields
        - prefer_final_locals
        - prefer_foreach
        # - prefer_function_declarations_over_variables # not yet tested
        - prefer_initializing_formals
        # - prefer_interpolation_to_compose_strings # not yet tested
        - prefer_is_empty
        - prefer_is_not_empty
        - prefer_single_quotes
        - prefer_typing_uninitialized_variables
        - recursive_getters
        - slash_for_doc_comments
        # - sort_constructors_first
        - sort_unnamed_constructors_first
        - super_goes_last
        - test_types_in_equals
        - throw_in_finally
        # - type_annotate_public_apis # subset of always_specify_types
        - type_init_formals
        # - unawaited_futures # https://github.com/flutter/flutter/issues/5793
        - unnecessary_brace_in_string_interps
        - unnecessary_getters_setters
        # - unnecessary_lambdas # https://github.com/dart-lang/linter/issues/498
        - unnecessary_null_aware_assignments
        - unnecessary_null_in_if_null_operators
        - unnecessary_overrides
        # - unnecessary_parenthesis
        # - unnecessary_statements # not yet tested
        - unnecessary_this
        - unnecessary_new
        - unnecessary_const
        - unrelated_type_equality_checks
        - use_rethrow_when_possible
        # - use_setters_to_change_properties # not yet tested
        # - use_string_buffers # https://github.com/dart-lang/linter/pull/664
        # - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
        - valid_regexps


================================================
FILE: doc/README-cn.md
================================================
-   **简介**
    -   [关于](introduction/README-cn.md)
    -   [演进](concept/evolution-of-fish-redux.md)
    -   [特性](concept/features.md)
-   **核心概念**
    -   [Redux](concept/redux-cn.md)
        -   [Action](concept/action-cn.md)
        -   [Connector](concept/connector-cn.md)
        -   [Reducer](concept/reducer-cn.md)
        -   [Middleware](concept/middleware-cn.md)
    -   [Component](concept/component-cn.md)
        -   [View](concept/view-cn.md)
        -   [Reducer](concept/reducer-cn.md)
        -   [Effect](concept/effect-cn.md)
        -   [HigherEffect](concept/higher-effect-cn.md)
        -   [Lifecycle](concept/lifecycle-cn.md)
        -   [Dependencies](concept/dependencies-cn.md)
        -   [Dependent](concept/dependent-cn.md)
        -   [ShouldUpdate](concept/should-update-cn.md)
        -   [OnError](concept/on-error-cn.md)
        -   [Filter](concept/filter-cn.md)
        -   [OOP](concept/oop-cn.md)
        -   [WidgetWrapper](concept/widget-wrapper-cn.md)
        -   [Page](concept/page-cn.md)
    -   [Adapter](concept/adapter-cn.md)
        -   [StaticFlowAdapter](concept/static-flow-adapter-cn.md)
        -   [DynamicFlowAdapter](concept/dynamic-flow-adapter-cn.md)
        -   [CustomAdapter](concept/custom-adapter-cn.md)
-   **其他**
    -   [What's the difference between 'Fish Redux' and 'Redux' ?](concept/what's-the-diiference-cn.md)
    -   [What's-adapter](concept/what's-adapter.md)
    -   [What's-connector](concept/what's-connector.md)
    -   [Mechanism](concept/mechanism-cn.md)
    -   [Directory](concept/directory-cn.md)


================================================
FILE: doc/README.md
================================================
- **Introduction**
  - [About](introduction/README.md)
  - [Evolution](concept/evolution-of-fish-redux.md)
  - [Features](concept/features.md)
- **Core Concepts**
  - [Redux](concept/redux.md)
    - [Action](concept/action.md)
    - [Connector](concept/connector.md)
    - [Reducer](concept/reducer.md)
    - [Middleware](concept/middleware.md)
  - [Component](concept/component.md)
    - [View](concept/view.md)
    - [Reducer](concept/reducer.md)
    - [Effect](concept/effect.md)
    - [HigherEffect](concept/higher-effect.md)
    - [Lifecycle](concept/lifecycle.md)
    - [Dependencies](concept/dependencies.md)
    - [Dependent](concept/dependent.md)
    - [ShouldUpdate](concept/should-update.md)
    - [OnError](concept/on-error.md)
    - [Filter](concept/filter.md)
    - [OOP](concept/oop.md)
    - [WidgetWrapper](concept/widget-wrapper.md)
    - [Page](concept/page.md)
  - [Adapter](concept/adapter.md)
    - [StaticFlowAdapter](concept/static-flow-adapter.md)
    - [DynamicFlowAdapter](concept/dynamic-flow-adapter.md)
    - [CustomAdapter](concept/custom-adapter.md)
- **Others**
  - [What's the difference between 'Fish Redux' and 'Redux' ?](concept/what's-the-diiference.md)
  - [What is an adapter?](concept/what's-adapter.md)
  - [What is a connector?](concept/what's-connector.md)
  - [Communication mechanism of fish-redux](concept/mechanism.md)
  - [Recommended directory structure](concept/directory.md)


================================================
FILE: doc/concept/action-cn.md
================================================
# Action

-   Action 包含两个字段
    -   type
    -   payload
-   推荐的写法是
    -   为一个组件|适配器创建一个 action.dart 文件,包含两个类
        -   为 type 字段起一个枚举类
        -   为 Action 的创建起一个 ActionCreator 类,这样利于约束 payload 的类型。
    -   Effect 接受处理的 Action,以 on{Verb} 命名
    -   Reducer 接受处理的 Action,以{verb} 命名
    -   示例代码

```dart
enum MessageAction {
    onShare,
    shared,
}

class MessageActionCreator {
    static Action onShare(Map<String, Object> payload) {
        return Action(MessageAction.onShare, payload: payload);
    }

    static Action shared() {
        return const Action(MessageAction.shared);
    }
}
```


================================================
FILE: doc/concept/action.md
================================================
# Action

-   Action contains two fields
    -   type
    -   payload
-   Recommended way of writing action
    -   Create an action.dart file for a component|adapter that contains two classes
        -   An enumeration class for the type field
        -   An ActionCreator class is created for the creator of the Action, which helps to constrain the type of payload.
    -   Effect Accepted Action which's type is named after `on{verb}`
    -   Reducer Accepted Action which's type is named after `{verb}`
    -   Sample code

```dart
enum MessageAction {
    onShare,
    shared,
}

class MessageActionCreator {
    static Action onShare(Map<String, Object> payload) {
        return Action(MessageAction.onShare, payload: payload);
    }

    static Action shared() {
        return const Action(MessageAction.shared);
    }
}
```


================================================
FILE: doc/concept/adapter-cn.md
================================================
# Adapter

-   我们在基础 Component 的概念外,额外增加了一种组件化的抽象 Adapter。它的目标是解决 Component 模型在 ListView 的场景下的 3 个问题
    -   1)将一个"Big-Cell"放在 ListView 里,无法享受 ListView 代码的性能优化。
    -   2)Component 无法区分 appear|disappear 和 init|dispose 事件。
    -   3)Effect 的生命周期和 View 的耦合,在 ListView 的有些场景下不符合直观的预期。
-   一个 Adapter 和 Component 几乎都是一致的,除了以下几点
    -   Component 生成一个 Widget,Adapter 生成一个 ListAdapter,ListAdapter 有能力生成一组 Widget。
        -   不具体生成 Widget,而是一个 ListAdapter,能非常大的提升页面帧率和流畅度。
    -   Effect-Lifecycle-Promote
        -   Component 的 Effect 是跟着 Widget 的生命周期走的,Adapter 的 Effect 是跟着上一级的 Widget 的生命周期走。
        -   Effect​ 提升,极大的解除了业务逻辑和视图生命的耦合,即使它的展示还未出现,的其他模块依然能通过 dispatch-api,调用它的能力。
    -   appear|disappear 的通知
        -   由于 Effect 生命周期的提升,我们就能更加精细的区分 init|dispose 和 appear|disappear。而这在 Component 的模型中是无法区分的。
    -   Reducer is long-lived, Effect is medium-lived, View is short-lived.
-   Adapter 的三种实现
    -   [DynamicFlowAdapter](dynamic-flow-adapter-cn.md)
    -   [StaticFlowAdapter](static-flow-adapter-cn.md)
    -   [CustomAdapter](custom-adapter-cn.md)


================================================
FILE: doc/concept/adapter.md
================================================
# Adapter

-   In addition to the concept of the underlying Component, we have added a componentized abstract Adapter. Its goal is to solve the 3 problems of the Component model in the ListView scene.

    -   1)Putting a "Big-Cell" in the ListView does not enjoy the performance optimization of the ListView code.
    -   2)Component cannot distinguish between the appear|disappear and init|dispose events.
    -   3)The life cycle of the Effect and the coupling of the View do not meet the intuitive expectations in some scenes of the ListView.

-   An Adapter and a Component are almost identical except for the following points

    -   Component generates a Widget, Adapter generates a ListAdapter, and ListAdapter has the ability to generate a list of Widgets.。
        -   Not specifically generating a Widget but a ListAdapter can greatly improve the page frame rate and fluency.
    -   Effect-Lifecycle-Promote
        -   The Effect of Component follows the life cycle of the Widget, and the Adapter's Effect follows the life cycle of the parent Widget.
        -   The improvement of the life cycle of the effect greatly removes the coupling between the business logic and the view life. Even if its display has not yet appeared, other modules can still call its capabilities through dispatch-api.
    -   Appearance|disappear event notification
        -   As the Effect lifecycle improves, we can more closely distinguish between init|dispose and appear|disappear. This is indistinguishable from the Model's model.
    -   Reducer is long-lived, Effect is medium-lived, View is short-lived.

-   Three implementations of Adapter
    -   [DynamicFlowAdapter](dynamic-flow-adapter.md)
    -   [StaticFlowAdapter](static-flow-adapter.md)
    -   [CustomAdapter](custom-adapter.md)


================================================
FILE: doc/concept/auto-dispose-cn.md
================================================
# Auto-Dispose

-   它是一个非常简易管理生命周期对象的方式。一个 auto-dispose 对象可以自我主动释放,或者在它 follow 的 托管对象释放的时候,释放。
-   在 Effect 中使用的 Context,以及 HigherEffect 中的 EffectPart,都是 auto-dispose 对象。所以我们可以方便的将自定义的需要做生命周期管理的对象托管给它们。
-   示例代码

```dart
class ItemWidgetBindingObserver extends WidgetsBindingObserver
    with AutoDispose {
  ItemWidgetBindingObserver() : super() {
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (AppConfig.flutterBinding.framesEnabled &&
        state == AppLifecycleState.resumed) {
      AppConfig.flutterBinding.performReassemble();
    }
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
}

void _init(Action action, Context<ItemPageContainerState> ctx) {
    final ItemWidgetBindingObserver observer = ItemWidgetBindingObserver();
    observer.follow(ctx);
}

```


================================================
FILE: doc/concept/auto-dispose.md
================================================
# Auto-Dispose

-   AutoDispose is a very simple way to manage lifecycle objects. An auto-dispose object can be released on its own initiative or released when the managed object it follows is released.
-   The Context used in Effect and the EffectPart in HigherEffect are auto-dispose objects. So we can easily host custom objects that need to be managed for lifecycle management.
-   Sample Code

```dart
class ItemWidgetBindingObserver extends WidgetsBindingObserver
    with AutoDispose {
  ItemWidgetBindingObserver() : super() {
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (AppConfig.flutterBinding.framesEnabled &&
        state == AppLifecycleState.resumed) {
      AppConfig.flutterBinding.performReassemble();
    }
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
}

void _init(Action action, Context<ItemPageContainerState> ctx) {
    final ItemWidgetBindingObserver observer = ItemWidgetBindingObserver();
    observer.follow(ctx);
}

```


================================================
FILE: doc/concept/component-cn.md
================================================
# Component

组件是对视图展现和逻辑功能的封装。
面向当下,从 Redux 的视角看,我们对组件分为状态修改的功能(Reducer)和其他。
面向未来,从 UI-Automation 的视角看,我们对组件分为展现表达和其他。
结合上面两个视角,于是我们得到了,View、 Effect、Reducer 三部分,称之为组件的三要素,分别负责了组件的展示、非修改数据的行为、修改数据的操作。

我们以显式配置的方式来完成大组件所依赖的小组件、适配器的注册,这份依赖配置称之为 Dependencies。

所以有了这个公式
Component = View + Effect(可选) + Reducer(可选) + Dependencies(可选)

分治:从组件的角度
<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

集中:从 Store 的角度
<img src="https://img.alicdn.com/tfs/TB1sThMJYvpK1RjSZFqXXcXUVXa-1426-762.png" width="713px" height="381px">


================================================
FILE: doc/concept/component.md
================================================
# Component

Component is the encapsulation of view presentation and logic functions.
For the moment, from the perspective of Redux, we divide the component into state-manage functions (Reducers) and others.
Looking to the future, from the perspective of UI-Automation, we divide the component into presentations and others.

Combining the above two perspectives, we got the three parts of View, SideEffect, and Reducer, which are called the three factors of the component.

We use explicit configuration to complete the registration of components and adapters on which large component depend. This dependency configuration is called Dependencies.

So with this formula:
Component = View + Effect(Optional) + Reducer(Optional) + Dependencies(Optional)

Division: From the perspective of the component
<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

Concentration: From the perspective of the Store
<img src="https://img.alicdn.com/tfs/TB1sThMJYvpK1RjSZFqXXcXUVXa-1426-762.png" width="713px" height="381px">


================================================
FILE: doc/concept/connector-cn.md
================================================
# Connector<T, P>

-   它表达了如何从一个大数据中读取小数据,同时对小数据的修改如何同步给大数据,这样的数据连接关系。
-   它是将一个集中式的 Reducer,可以由多层次多模块的小 Reducer 自动拼装的关键。
    -   它大大降低了我们使用 Redux 的复杂度。我们不再关心组装过程,我们关心的核心是什么动作促使数据怎么变化。
-   它使用在配置 Dependencies 中,在配置中我们就固化了大组件和小组件之间的连接关系(数据管道),所以在我们使用小组件的时候是不需要传入任何动态参数的。
-   ![image.png | left | 719x375](https://cdn.nlark.com/lark/0/2018/png/82574/1545365202743-01074be7-f067-45c7-aae0-91b12cd50ae6.png)

-   Sample Code

```dart
class DetialState {
    Profile profile;
    String message;
}

ConnOp<DetialState, String> messageConnector() {
    return ConnOp<DetialState, String>(
        get: (DetialState state) => state.message,
        set: (DetialState state, String message) => state.message = message,
    );
}
```


================================================
FILE: doc/concept/connector.md
================================================
# Connector<T, P>

-   It expresses a data connection relationship of how to read small data from a big data, and how to synchronize to big data when the small data is modified。
-   It is the key to a centralized Reducer that can be assembled automatically by a multi-level, multi-module, small Reducer
    -   It greatly reduces the difficulty of using Redux. We no longer care about the assembly process, we care about what specific actions cause the state to change.
-   It is used in the configuration Dependencies, in the configuration we have solidified the connection between the large component and the small component, so we do not need to pass in any dynamic parameters when we use the small component.
-   ![image.png | left | 719x375](https://cdn.nlark.com/lark/0/2018/png/82574/1545365202743-01074be7-f067-45c7-aae0-91b12cd50ae6.png)

-   Sample Code

```dart
class DetialState {
    Profile profile;
    String message;
}

ConnOp<DetialState, String> messageConnector() {
    return ConnOp<DetialState, String>(
        get: (DetialState state) => state.message,
        set: (DetialState state, String message) => state.message = message,
    );
}
```


================================================
FILE: doc/concept/custom-adapter-cn.md
================================================
# CustomAdapter

-   对大 Cell 的自定义实现
-   要素和 Component 类似,不一样的地方是 Adapter 的视图部分返回的是一个 ListAdapter
-   示例代码

```dart
class CommentAdapter extends Adapter<CommentState> {
    CommentAdapter()
        : super(
            adapter: buildCommentAdapter,
            effect: buildCommentEffect(),
            reducer: buildCommentReducer(),
        );
}

ListAdapter buildCommentAdapter(CommentState state, Dispatch dispatch, ViewService service) {
    final List<IndexedWidgetBuilder> builders = Collections.compact(<IndexedWidgetBuilder>[]
    ..add((BuildContext buildContext, int index) =>
        _buildDetailCommentHeader(state, dispatch, service))
    ..addAll(_buildCommentViewList(state, dispatch, service))
    ..add(isEmpty(state.commentListRes?.items)
        ? (BuildContext buildContext, int index) =>
            _buildDetailCommentEmpty(state.itemInfo, dispatch)
        : null)
    ..add(state.commentListRes?.getHasMore() == true
        ? (BuildContext buildContext, int index) => _buildLoadMore(dispatch)
        : null));
    return ListAdapter(
    (BuildContext buildContext, int index) =>
        builders[index](buildContext, index),
    builders.length,
    );
}

///builds
```


================================================
FILE: doc/concept/custom-adapter.md
================================================
# CustomAdapter

-   Custom implementation of large Cell in LisView.
-   The Factors of the Adapter are similar to the Component's. The difference is that the view part of the Adapter returns a ListAdapter.
-   Sample Code

```dart
class CommentAdapter extends Adapter<CommentState> {
    CommentAdapter()
        : super(
            adapter: buildCommentAdapter,
            effect: buildCommentEffect(),
            reducer: buildCommentReducer(),
        );
}

ListAdapter buildCommentAdapter(CommentState state, Dispatch dispatch, ViewService service) {
    final List<IndexedWidgetBuilder> builders = Collections.compact(<IndexedWidgetBuilder>[]
    ..add((BuildContext buildContext, int index) =>
        _buildDetailCommentHeader(state, dispatch, service))
    ..addAll(_buildCommentViewList(state, dispatch, service))
    ..add(isEmpty(state.commentListRes?.items)
        ? (BuildContext buildContext, int index) =>
            _buildDetailCommentEmpty(state.itemInfo, dispatch)
        : null)
    ..add(state.commentListRes?.getHasMore() == true
        ? (BuildContext buildContext, int index) => _buildLoadMore(dispatch)
        : null));
    return ListAdapter(
    (BuildContext buildContext, int index) =>
        builders[index](buildContext, index),
    builders.length,
    );
}

///builds
```


================================================
FILE: doc/concept/dependencies-cn.md
================================================
# Dependencies

-   Dependencies 是一个表达组件之间依赖关系的结构。它接收两个字段
    -   slots
        -   <String, [Dependent](dependent-cn.md)>{}
    -   [adapter](adapter-cn.md)
-   它主要包含三方面的信息
    -   slots,组件依赖的插槽。
    -   adapter,组件依赖的具体适配器(用来构建高性能的 ListView)。
    -   [Dependent](dependent-cn.md) 是 subComponent | subAdapter + [connector](connector-cn.md) 的组合。
    -   一个 组件的 [Reducer](reducer-cn.md) 由 Component 自身配置的 Reducer 和它的 Dependencies 下的所有子 Reducers 自动复合而成。
-   示例代码

```dart
///register in component
class ItemComponent extends ItemComponent<ItemState> {
  ItemComponent()
      : super(
          view: buildItemView,
          reducer: buildItemReducer(),
          dependencies: Dependencies<ItemState>(
            slots: <String, Dependent<ItemState>>{
              'appBar': AppBarComponent().asDependent(AppBarConnector()),
              'body': ItemBodyComponent().asDependent(ItemBodyConnector()),
              'ad_ball': ADBallComponent().asDependent(ADBallConnector()),
              'bottomBar': BottomBarComponent().asDependent(BottomBarConnector()),
            },
          ),
        );
}

///call in view
Widget buildItemView(ItemState state, Dispatch dispatch, ViewService service) {
  return Scaffold(
      body: Stack(
        children: <Widget>[
          service.buildComponent('body'),
          service.buildComponent('ad_ball'),
          Positioned(
            child: service.buildComponent('bottomBar'),
            left: 0.0,
            bottom: 0.0,
            right: 0.0,
            height: 100.0,
          ),
        ],
      ),
      appBar: AppbarPreferSize(child: service.buildComponent('appBar')));
}
```


================================================
FILE: doc/concept/dependencies.md
================================================
# Dependencies

-   Dependencies is a structure that expresses dependencies between components. It accepts two fields
    -   slots
        -   <String, [Dependent](dependent.md)>{}
    -   [adapter](adapter.md)
-   It mainly contains three aspects of information
    -   The slots that the component depends on.
    -   The adapter that the component depends on (used to build a high-performance ListView).
    -   [Dependent](dependent.md) Is a combination of subComponent | subAdapter + [connector](connector.md)。
    -   A component's [Reducer](reducer.md) is automatically compounded by the Reducer configured by the Component itself and all of the Reducers under its Dependencies.
-   Sample Code

```dart
///register in component
class ItemComponent extends ItemComponent<ItemState> {
  ItemComponent()
      : super(
          view: buildItemView,
          reducer: buildItemReducer(),
          dependencies: Dependencies<ItemState>(
            slots: <String, Dependent<ItemState>>{
              'appBar': AppBarComponent().asDependent(AppBarConnector()),
              'body': ItemBodyComponent().asDependent(ItemBodyConnector()),
              'ad_ball': ADBallComponent().asDependent(ADBallConnector()),
              'bottomBar': BottomBarComponent().asDependent(BottomBarConnector()),
            },
          ),
        );
}

///call in view
Widget buildItemView(ItemState state, Dispatch dispatch, ViewService service) {
  return Scaffold(
      body: Stack(
        children: <Widget>[
          service.buildComponent('body'),
          service.buildComponent('ad_ball'),
          Positioned(
            child: service.buildComponent('bottomBar'),
            left: 0.0,
            bottom: 0.0,
            right: 0.0,
            height: 100.0,
          ),
        ],
      ),
      appBar: AppbarPreferSize(child: service.buildComponent('appBar')));
}
```


================================================
FILE: doc/concept/dependent-cn.md
================================================
### Dependent

-   Dependent = connector<T, P> + subComponent | subAdapter 的组合,它表达了小组件|小适配器是如何连接到 Component 的。
-   示例代码

```dart
/// todo
```


================================================
FILE: doc/concept/dependent.md
================================================
### Dependent

-   Dependent = connector<T, P> + subComponent | subAdapter
-   It expresses how the small component or adapter are connected to it's parent component.
-   Sample Code

```dart
/// todo
```


================================================
FILE: doc/concept/directory-cn.md
================================================
# Directory

推荐的目录结构会是这样

```
sample_page
    -- action.dart /// define action types and action creator
    -- page.dart /// config a page or component
    -- view.dart /// define a function which expresses the presentation of user interface
    -- effect.dart /// define a function which handles the side-effect
    -- reducer.dart /// define a function which handles state-change
    -- state.dart /// define a state and some connector of substate
    components
        sample_component
        -- action.dart
        -- component.dart
        -- view.dart
        -- effect.dart
        -- reducer.dart
        -- state.dart
```

上层负责组装,下层负责实现。


================================================
FILE: doc/concept/directory.md
================================================
# Directory

The recommended directory structure

```
sample_page
    -- action.dart /// define action types and action creator
    -- page.dart /// config a page or component
    -- view.dart /// define a function which expresses the presentation of user interface
    -- effect.dart /// define a function which handles the side-effect
    -- reducer.dart /// define a function which handles state-change
    -- state.dart /// define a state and some connector of substate
    components
        sample_component
        -- action.dart
        -- component.dart
        -- view.dart
        -- effect.dart
        -- reducer.dart
        -- state.dart
```

The upper layer is responsible for assembly and the lower layer is responsible for implementation.


================================================
FILE: doc/concept/dynamic-flow-adapter-cn.md
================================================
# DynamicFlowAdapter

-   模版是一个 Map,接受一个数组类型的数据驱动
-   示例代码

```dart
class RecommendAdapter extends DynamicFlowAdapter<RecommendState> {
    RecommendAdapter()
        : super(
            pool: <String, Component<Object>>{
                'card_0': RecommendTitleComponent(),
                'card_1': RecommendRowComponent(),
            },
            connector: RecommendCardListConnector(),
        );
}
```
<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: doc/concept/dynamic-flow-adapter.md
================================================
# DynamicFlowAdapter

-   The template is a Map that accepts an array-like data driven
-   Sample Code

```dart
class RecommendAdapter extends DynamicFlowAdapter<RecommendState> {
    RecommendAdapter()
        : super(
            pool: <String, Component<Object>>{
                'card_0': RecommendTitleComponent(),
                'card_1': RecommendRowComponent(),
            },
            connector: RecommendCardListConnector(),
        );
}
```

<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: doc/concept/effect-cn.md
================================================
# Effect

Effect顾名思义,用于处理Action的副作用。

我估摸着有人就要问我了,副作用是啥玩意?

打个比方吧,假如我拥有一个函数 `f()`

```text
fn f(x):
  return x * 1
```

此时此刻,另一个函数 `g()`

```text
fn g(x):
  changeSystemEntropy()
  return ax ^ 2 + bx + c
```

我们可以发现,`g()`里边有个改变系统熵的行为。这在函数式编程思想中,就叫做副作用,因为它可能影响到除了这个函数内部自身状态以外的其他状态。

在Fish-Redux中同样,我们通过 `dispatch()` 一些action实现状态修改,但是相对于状态来说,对外部的操作,类似于 `SystemChrome.setSystemUIOverlayStyle()`这样的操作,都是副作用。

现在介绍完了副作用,也没啥可介绍的了。

Effect用法跟Reducer差不太多,但是作用完全不同。

除了上面介绍的场景之外,异步请求也是一个经常会有的情况,这时候Effect可以帮你方便的解决这些问题。

你可以通过控制effect的返回值来达到某些目的,默认情况下,effect会在reducer之前被执行。

当前effect返回 `true` 的时候,就会停止后续的effect和reducer的操作

当前effect返回 `false` 的时候,后续effect和reducer继续执行

-   Effect 是一个处理所有副作用的函数。它接收下面的参数
    -   Action action
    -   Context context
        -   BuildContext context
        -   T state
        -   dispatch
        -   isDisposed
        
Effect会接收来自 View 的“意图”,包括对应的生命周期的回调,然后做出具体的执行。
    -   它的处理可能是一个异步函数,数据可能在过程中被修改,所以我们应该通过 context.state 获取最新数据。
    -   如果它要修改数据,应该发一个 Action 到 Reducer 里去处理。它对数据是只读的,不能直接去修改数据。
    -   如果它的返回值是一个非空值,则代表自己优先处理,不再做下一步的动作;否则广播给其他组件的 Effect 部分,同时发送给 Reducer。

> Self-First-Broadcast。
> ![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

-   示例代码

```dart
/// one style of writing
FutureOr<Object> sideEffect(Action action, Context<String> ctx) async {
  if (action.type == Lifecycle.initState) {
    //do something on initState
    return true;
  } else if (action.type == 'onShare') {
    //do something on onShare
    await Future<void>.delayed(Duration(milliseconds: 1000));
    ctx.dispatch(const Action('shared'));
    return true;
  }
  return null;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: sideEffect,
        );
}
```

```dart
/// another style of writing
Effect<String> buildEffect() {
  return combineEffects(<Object, Effect<String>>{
    Lifecycle.initState: _initState,
    'onShare': _onShare,
  });
}

void _initState(Action action, Context<String> ctx) {
  //do something on initState
}

void _onShare(Action action, Context<String> ctx) async {
  //do something on onShare
  await Future<void>.delayed(Duration(milliseconds: 1000));
  ctx.dispatch(const Action('shared'));
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
        );
}
```


================================================
FILE: doc/concept/effect.md
================================================
# Effect

-   Effect is a function that handles all side effects. It receives the following parameters
    -   Action action
    -   Context context
        -   BuildContext context
        -   T state
        -   dispatch
        -   isDisposed
-   It mainly contains four aspects of information
    -   Receive "intent" from the View, including the corresponding lifecycle callback, and then make specific execution.
    -   Its processing may be an asynchronous function, the data may be changed in the process, so we should get the latest data through context.state.
    -   If you want to modify the data, you should send an Action to the Reducer to handle. It is read-only for data and cannot be modified directly in a effect function.
    -   If its return value is a non-null value, it will take precedence for itself and will not do the next step; otherwise it will broadcast to the Effect part of other components and sent the action to the Reducer.

> Self-First-Broadcast。
> ![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

-   Sample Code

```dart
/// one style of writing
FutureOr<Object> sideEffect(Action action, Context<String> ctx) async {
  if (action.type == Lifecycle.initState) {
    //do something on initState
    return true;
  } else if (action.type == 'onShare') {
    //do something on onShare
    await Future<void>.delayed(Duration(milliseconds: 1000));
    ctx.dispatch(const Action('shared'));
    return true;
  }
  return null;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: sideEffect,
        );
}
```

```dart
/// another style of writing
Effect<String> buildEffect() {
  return combineEffects(<Object, Effect<String>>{
    Lifecycle.initState: _initState,
    'onShare': _onShare,
  });
}

void _initState(Action action, Context<String> ctx) {
  //do something on initState
}

void _onShare(Action action, Context<String> ctx) async {
  //do something on onShare
  await Future<void>.delayed(Duration(milliseconds: 1000));
  ctx.dispatch(const Action('shared'));
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
        );
}
```


================================================
FILE: doc/concept/evolution-of-fish-redux.md
================================================
# fish-redux 的演进史

fish-redux 是一个不断演进的框架,甚至是在不断的回炉重造,在这个过程中

<img src="https://img.alicdn.com/tfs/TB1aeJELpzqK1RjSZFCXXbbxVXa-1794-938.png" width="897px" height="469px">

-   1. 第一个版本是基于社区内的 flutter_redux 进行的改造,核心是提供了 UI 代码的组件化,当然问题也非常明显,针对复杂的业务场景,往往业务逻辑很多,无法做到逻辑代码的分治和复用。

-   2. 第二个版本针对第一个版本的问题,做出了比较重大的修改,解决了 UI 代码和逻辑代码的分治问题,但设计上打破了 redux 的原则,丢失了 Redux 的精华。

-   3. 在第三个版本进行重构时,我们确立了整体的架构原则与分层要求,一方面按照 reduxjs 的代码进行了 flutter 侧的 redux 实现,将 redux 完整保留下来。另一方面针对组件化的问题,提供了 redux 之上的 component 的封装,并创新的通过这一层的架构设计提供了业务代码分治的能力。第三版 完成了 Redux, Component 两层的设计,其中包含了 Connector,Dependencies,Context 等重要概念。

    -   3.1 解决集中和分治的矛盾的核心在于 [Connector](what's-connector.md)
    -   3.2 这一层的组件的分治是面向通用设计的。通过在 [Dependencies](dependencies-cn.md) 配置 slots,得到了可插拔的组件系统。

-   4. 在第三个版本 Redux & Component 之外,提供了面向 ListView 场景的分治设计 Adapter。
    -   解决了在面向 ListView 场景下的逻辑的分治和性能降低的矛盾。
    -   [what's-adapter](what's-adapter.md)

> 目前,fish redux 已经在闲鱼线上稳定运行,未来,期待 fish redux 给社区带来更多的输入。


================================================
FILE: doc/concept/features.md
================================================
# Features

## 直接使用 flutter 会面临的问题?

> [flutter](https://github.com/flutter/flutter) 是 google 推出的新一代跨平台渲染框架.
> 它帮助开发者解决了跨平台,高性能,富有表现力和灵活的 UI 表达,快速开发等核心问题。
> 但是如果开发大应用,还需要解决以下问题。
>
> > 1. 数据流问题
> > 2. 通信问题
> > 3. 可插拔的组件系统
> > 4. 展示和逻辑解耦
> > 5. 统一的编程模型和规范
>
> 我们可以类比 flutter 和 React,事实上在中大型应用中 React 会面临的绝大多数问题,flutter 也同样面临考验。

## 数据流问题

> 目前社区流行的数据流方案有:
> 单向数据流方案,以 Redux 为代表
> 响应式数据流方案,以 Mobx 为代表
> 其他,以 rxjs 为代表
> 那么哪一种架构最合适 flutter ?
> 我们追随了 javascript 栈绝大多数开发者的选择 - [ReduxJs](https://github.com/reduxjs/redux)
> 感谢 ReduxJs,我们是几乎 100%的还原了它在 dart 上的实现。所以我们也继承了它的优点:[Predictable],[Centralized],[Debuggable],[Flexible]。

## 通信问题

> 直接使用 flutter,在 Widgets 之间传递状态和回调,随着应用复杂度的上升,会变成是一件可怕而糟糕的事情。
> 通过 fish redux,依托于集中的 Redux 和分治的 Effect 模块,通过一个极简的 [dispatch-api](mechanism.md),完成所有的通信的诉求。

## 可插拔的组件系统

> fish redux 通过一个配置式的 Dependencies,来完成灵活的可插拔的组件系统。同时有这一配置的存在,它解放了我们手动拼装 Reducer 的繁琐工作。
> 参考:
>
> > 1. [what's-connector](what's-connector.md)
> > 2. [connector](connector.md)
> > 3. [dependencies](dependencies.md)
> > 4. [component](component.md)
> > 5. [adapter](adapter.md)
> > 6. [what's-adapter](what's-adapter.md)

## 展示和逻辑解耦

> fish redux 从 [elm](https://guide.elm-lang.org/) 中得到了非常多的设计灵感。
> 将一个组件,拆分为相互独立的 View,Effect,Reducer 三个函数,我们优雅的解决了展示和逻辑解耦的问题。
> 通过这样的拆分,我们将 UI 的表达隔离于一个函数内,它让我们更好的面向未来,一份 UI 表达它可能来自于开发者,可能来自于深度学习框架的 UI 代码生成,可能是面向移动终端,也可能是面向浏览器。它让我们有了更多的组合的可能。
> 同时函数式的编程模型带来了更容易编写,更容易扩展,更容易测试,更容易维护等特性。

## 统一的编程模型和规范

> [directory](directory.md)


================================================
FILE: doc/concept/filter-cn.md
================================================
# Filter

-   Filter 是用来优化 Reducer 的性能的。因为 Reducer 是层层组装的,所以处理每一个 Action,理论上会遍历一遍所有的小 Reducer,在一些非常复杂的场景下,这样的一次深度遍历的耗时可能会到毫秒级别(一般情况下都应该小于 1 毫秒)。那么我们需要对 Reducer 做性能优化,提前决定要不要遍历这份 Reducer 子树,减少遍历的深度和次数。
-   示例代码

```dart
bool filter(Action action) {
    return action.type == 'some action';
}
```


================================================
FILE: doc/concept/filter.md
================================================
# Filter

-   Filter is used to optimize the performance of the Reducer. Because the Reducer is layer-assembled, each Action is processed, and in theory, all the small Reducers are traversed. In some very complicated scenarios, such a deep traversal may take up to the millisecond level (generally Should be less than 1 millisecond). Then we need to optimize the performance of the Reducer, decide in advance whether to traverse this Reducer subtree, reduce the depth and number of traversal.
-   Sample Code

```dart
bool filter(Action action) {
    return action.type == 'some action';
}
```


================================================
FILE: doc/concept/higher-effect-cn.md
================================================
# HigherEffect

-   由于 Effect 有可能有自己一些临时状态(尽管不建议这么做,但还是提供了支持),为了支持这个特性,我们将 Effect 提升为高阶函数,将它的状态放在闭包里。
-   框架支持 Effect|HigherEffect 的配置,但是不能对一个组件或适配器同时都配置,那样会带来困扰,一般情况下,都配置往往是个显式的疏忽大意。
-   HigherEffect = (Context ctx) => (Action action) => FutureOr
-   更详细的例子请参考 [OOP](oop-cn.md) - EffectPart


================================================
FILE: doc/concept/higher-effect.md
================================================
# HigherEffect

-   Since Effect may have some temporary state of its own (although it is not recommended, support is provided), in order to support this feature, we promote the Effect to a higher-order function and put its state in the closure.
-   The framework supports the configuration of Effect|HigherEffect on component or adapter, but it can't be configured for one component or adapter at the same time, which will cause trouble. In general, the configuration is often an explicit negligence.
-   HigherEffect = (Context ctx) => (Action action) => FutureOr
-   For more detailed examples, please refer to [OOP](oop.md) - EffectPart


================================================
FILE: doc/concept/lifecycle-cn.md
================================================
# Lifecycle

-   默认的所有生命周期,本质上都来自于 flutter State<StatefulWidget> 中的生命周期。
    -   initState
    -   didChangeDependencies
    -   build
    -   didUpdateWidget
    -   deactivate
    -   dispose
-   在组件内,Reducer 的生命周期是和页面一致的,Effect 和 View 的生命周期是和组件的 Widget 一致的。
-   在适配器中,Reducer 的生命周期是和页面一致的,Effect 的生命周期是和 ListView 的生命周期一致,View 的生命周期是短暂的(划入不可见区域即销毁)。同时增加了 appear 和 disappear 的生命周期, 代表这个 adapter 管理的视图数组,刚进入显示区和完全离开显示区的回调。


================================================
FILE: doc/concept/lifecycle.md
================================================
# Lifecycle

-   The default all lifecycles are essentially derived from the lifecycle in flutter State<StatefulWidget>.
    -   initState
    -   didChangeDependencies
    -   build
    -   didUpdateWidget
    -   deactivate
    -   dispose
-   Within the component, the Lifecycle of the Reducer is consistent with the page, and the lifecycle of Effect and View is consistent with the component's Widget.
-   In the adapter, the Lifecycle of the Reducer is consistent with the page. The life cycle of the Effect is the same as the life cycle of the ListView. The life cycle of the View is short-lived (destroyed in the invisible area). At the same time, the life cycle of appear and disappear is added, representing the view array managed by this adapter, the callback just entering the display area and completely leaving the display area.


================================================
FILE: doc/concept/mechanism-cn.md
================================================
# Communication Mechanism

## 页面内通信

-   组件|适配器内通信
-   组件|适配器间内通信

![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

Self-First-Broadcast。
发出的 Action,自己优先处理,否则广播给其他组件和 Redux 处理。

最终我们通过一个简单而直观的 dispatch 完成了组件内,组件间(父到子,子到父,兄弟间等)的通信。

## 页面间通信

-   页面间通信
    -   Context.appBroadcast
        -   每一个页面的 PageStore 都会收到消息,各自独立负责处理。

![image.png | left | 691x519](https://cdn.nlark.com/lark/0/2018/png/82574/1545368705599-745c46a3-f5c6-41a7-a757-1bc6f9a389d4.png)

# Refresh Mechanism

## 数据刷新

-   局部数据修改,自动层层触发上层数据的浅拷贝,对业务代码是透明的。
-   层层的数据的拷贝
    -   一方面是对 Redux 数据修改的严格的 follow。
    -   另一方面也是对数据驱动展示的严格的 follow。
        -   数据的任何一个局部的变动,必须要让能看到这个局部的所有视图感知到。如果不拷贝,对应的视图通过新旧两份数据的比较(同一个引用),会错以为自己没有发生变化。

![image.png | left | 747x361](https://cdn.nlark.com/lark/0/2018/png/82574/1545386668521-0081cb5f-8017-47d1-ad7c-8802bb0be8a0.png)

## 视图刷新

-   扁平化通知到所有组件,组件通过 shouldUpdate 确定自己是否需要刷新

![image.png | left | 747x336](https://cdn.nlark.com/lark/0/2018/png/82574/1545386773247-2eddfa99-e6b9-4be9-ac43-d1944ff44e9b.png)


================================================
FILE: doc/concept/mechanism.md
================================================
# Communication Mechanism

## Page internal communication

-   Component internal communication
-   Inter-component communication

![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

Self-First-Broadcast。
The emitted Action will be processed first by its own Effect, otherwise it will be broadcast to other components and Redux.

We completed the communication between the components (parent to child, child to parent, brother, etc.) through a simple and intuitive dispatch.

## Inter-page communication

-   Context.appBroadcast
    -   Each page's PageStore receives an action which is handled independently.

![image.png | left | 691x519](https://cdn.nlark.com/lark/0/2018/png/82574/1545368705599-745c46a3-f5c6-41a7-a757-1bc6f9a389d4.png)

# Refresh Mechanism

## 数据刷新

-   Local data modification automatically triggers a shallow copy of the upper layer data and is transparent to the business code.

![image.png | left | 747x361](https://cdn.nlark.com/lark/0/2018/png/82574/1545386668521-0081cb5f-8017-47d1-ad7c-8802bb0be8a0.png)

## View refresh

-   When the state changes, the store flatly notifies all the components and the [ShouldUpdate](should-update.md) decide whether the view should be refreshed

![image.png | left | 747x336](https://cdn.nlark.com/lark/0/2018/png/82574/1545386773247-2eddfa99-e6b9-4be9-ac43-d1944ff44e9b.png)


================================================
FILE: doc/concept/middleware-cn.md
================================================
# Middleware

关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。

示例代码

```dart
Middleware<T> logMiddleware<T>({
  String tag = 'redux',
  String Function(T) monitor,
}) {
  return ({Dispatch dispatch, Get<T> getState}) {
    return (Dispatch next) {
      return isDebug()
          ? (Action action) {
              print('---------- [$tag] ----------');
              print('[$tag] ${action.type} ${action.payload}');

              final T prevState = getState();
              if (monitor != null) {
                print('[$tag] prev-state: ${monitor(prevState)}');
              }

              next(action);

              final T nextState = getState();
              if (monitor != null) {
                print('[$tag] next-state: ${monitor(nextState)}');
              }

              if (prevState == nextState) {
                print('[$tag] warning: ${action.type} has not been used.');
              }

              print('========== [$tag] ================');
            }
          : next;
    };
  };
}
```

更多的参考 src/utils/common_middleware


================================================
FILE: doc/concept/middleware.md
================================================
# Middleware

-   The definition and signature of Middleware is consistent with the ReduxJS community.
-   Sample Code

```dart
Middleware<T> logMiddleware<T>({
  String tag = 'redux',
  String Function(T) monitor,
}) {
  return ({Dispatch dispatch, Get<T> getState}) {
    return (Dispatch next) {
      return isDebug()
          ? (Action action) {
              print('---------- [$tag] ----------');
              print('[$tag] ${action.type} ${action.payload}');

              final T prevState = getState();
              if (monitor != null) {
                print('[$tag] prev-state: ${monitor(prevState)}');
              }

              next(action);

              final T nextState = getState();
              if (monitor != null) {
                print('[$tag] next-state: ${monitor(nextState)}');
              }

              if (prevState == nextState) {
                print('[$tag] warning: ${action.type} has not been used.');
              }

              print('========== [$tag] ================');
            }
          : next;
    };
  };
}
```

更多的参考 src/utils/common_middleware


================================================
FILE: doc/concept/on-error-cn.md
================================================
# OnError

-   集中处理由 Effect 产生的业务异常,无论是同步函数还是异步函数。有了统一的异常处理机制,我们就能站在一个更高的抽象角度,对业务代码做出合理的简化。
-   示例代码

```dart
bool onMessageError(Exception e, Context<String> ctx) {
    if(e is BizException) {
        ///do some toast
        return true;
    }
    return false;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
            onError: onMessageError,
        );
}
```


================================================
FILE: doc/concept/on-error.md
================================================
# OnError

-   Centralizes the business exceptions generated by Effect, whether it is a synchronous function or an asynchronous function. With a unified exception handling mechanism, we can stand on a higher level of abstraction and make reasonable simplifications of business code.
-   Sample Code

```dart
bool onMessageError(Exception e, Context<String> ctx) {
    if(e is BizException) {
        ///do some toast
        return true;
    }
    return false;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
            onError: onMessageError,
        );
}
```


================================================
FILE: doc/concept/oop-cn.md
================================================
# OOP

-   虽然框架推荐使用的函数式的编程方式,也提供面向对象式的编程方式的支持。
    -   ViewPart
        -   需要复写 build 函数。
        -   需要的 state,dispatch,viewService 的参数,已经成为了对象的字段可以直接使用。
        -   它是@immutable 的,所以不应该也不需要在内部定义可变字段。
    -   EffectPart
        -   需要复写 createMap 函数。
        -   需要的 Context 已经被打平,作为了对象的字段可以直接使用。
        -   可以定义字段,它的可见性也仅限于自身。
        -   它必须配合 higherEffect 一起使用。
-   示例代码

```dart
class MessageView extends ViewPart<MessageState> {
    @override
    Widget build() {
        return Column(children: [
            viewService.buildComponent('profile'),
            InkWell(
                child: Text('$message'),
                onTap: () => dispatch(const Action('onShare')),
            ),
        ]);
    }
}

class MessageEffect extends EffectPart<MessageState> {
    ///we could put some Non-UI fields here.

    @override
    Map<Object, OnAction> createMap() {
        return <Object, OnAction>{
            Lifecycle.initState: _initState,
            'onShare': _onShare,
        };
    }

    void _initState(Action action) {
        //do something on initState
    }

    void _onShare(Action action) async {
        //do something on onShare
        await Future<void>.delayed(Duration(milliseconds: 1000));
        dispatch(const Action('shared'));
    }
}

class MessageComponent extends Component<MessageState> {
    MessageComponent(): super(
        view: MessageView().asView(),
        higherEffect: higherEffect(() => MessageEffect()),
    );
}
```


================================================
FILE: doc/concept/oop.md
================================================
# OOP

-   Although the framework recommends the use of functional programming, it also provides object-oriented programming support.
    -   ViewPart
        -   Need to override the 'build' function.
        -   The required state, dispatch, and viewService parameters have become fields of the object and can be used directly.
        -   It is immutable, so there should be no need to define variable fields internally.
    -   EffectPart
        -   Need to override the 'createMap' function.
        -   The required Context has been flattened as the fields which can be used directly.
        -   Fields can be defined and their visibility is limited to themselves.
        -   It must be used with higherEffect.
-   Sample Code

```dart
class MessageView extends ViewPart<MessageState> {
    @override
    Widget build() {
        return Column(children: [
            viewService.buildComponent('profile'),
            InkWell(
                child: Text('$message'),
                onTap: () => dispatch(const Action('onShare')),
            ),
        ]);
    }
}

class MessageEffect extends EffectPart<MessageState> {
    ///we could put some Non-UI fields here.

    @override
    Map<Object, OnAction> createMap() {
        return <Object, OnAction>{
            Lifecycle.initState: _initState,
            'onShare': _onShare,
        };
    }

    void _initState(Action action) {
        //do something on initState
    }

    void _onShare(Action action) async {
        //do something on onShare
        await Future<void>.delayed(Duration(milliseconds: 1000));
        dispatch(const Action('shared'));
    }
}

class MessageComponent extends Component<MessageState> {
    MessageComponent(): super(
        view: MessageView().asView(),
        higherEffect: higherEffect(() => MessageEffect()),
    );
}
```


================================================
FILE: doc/concept/page-cn.md
================================================
# Page

-   一个页面内都有且仅有一个 Store
-   Page 继承于 Component,所以它能配置所有 Component 的要素
-   Page 能配置 Middleware,用于对 Redux 做 AOP 管理
-   Page 必须配置一个初始化页面数据的初始化函数  initState
    <img src="https://img.alicdn.com/tfs/TB1ASfDJ9zqK1RjSZFHXXb3CpXa-1636-756.png" width="818px" height="378px">

-   示例代码

```dart
/// Hello World
class HelloWordPage extends Page<String, String> {
    HelloWordPage():
        super(
            initState: (String msg) => msg,
            view:(String msg, _, __) => Text('Hello ${msg}'),
        );
}

HelloWordPage().buildPage('world')
```


================================================
FILE: doc/concept/page.md
================================================
# Page

-   One and only one store in one page
-   Page inherits from Component, so it can configure all the factors of Component.
-   Page can configure Middleware for AOP management of Redux.
-   Page must be configured with an initialization function that initializes page data initState.
    <img src="https://img.alicdn.com/tfs/TB1ASfDJ9zqK1RjSZFHXXb3CpXa-1636-756.png" width="818px" height="378px">

-   Sample Code

```dart
/// Hello World
class HelloWordPage extends Page<String, String> {
    HelloWordPage():
        super(
            initState: (String msg) => msg,
            view:(String msg, _, __) => Text('Hello ${msg}'),
        );
}

HelloWordPage().buildPage('world')
```


================================================
FILE: doc/concept/reducer-cn.md
================================================
# Reducer

-   Reducer 是一个上下文无关的 pure function。它接收下面的参数
    -   T state
    -   Action action
-   它主要包含三方面的信息
    -   接收一个“意图”, 做出数据修改。
    -   如果要修改数据,需要创建一份新的拷贝,修改在拷贝上。
    -   如果数据修改了,它会自动触发 State 的层层数据的拷贝,再以扁平化方式通知组件刷新。
-   示例代码

```dart
/// one style of writing
String messageReducer(String msg, Action action) {
  if (action.type == 'shared') {
    return '$msg [shared]';
  }
  return msg;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: messageReducer,
        );
}
```

```dart
/// another style of writing
Reducer<String> buildMessageReducer() {
  return asReducer(<Object, Reducer<String>>{
    'shared': _shared,
  });
}

String _shared(String msg, Action action) {
  return '$msg [shared]';
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
        );
}
```

> 推荐的是第二种写法


================================================
FILE: doc/concept/reducer.md
================================================
# Reducer

-   The Reducer is a context-independent pure function. It receives the following parameters
    -   T state
    -   Action action
-   It mainly contains three aspects of information
    -   Receive an "intent" and make a state modification.
    -   If you want to modify the state, you need to create a new copy and modify it on the copy.
    -   If the small state is modified, it will automatically trigger the copy of the main state's layers data, and then notify the components to refresh in a flattened manner.
-   Sample Code

```dart
/// one style of writing
String messageReducer(String msg, Action action) {
  if (action.type == 'shared') {
    return '$msg [shared]';
  }
  return msg;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: messageReducer,
        );
}
```

```dart
/// another style of writing
Reducer<String> buildMessageReducer() {
  return asReducer(<Object, Reducer<String>>{
    'shared': _shared,
  });
}

String _shared(String msg, Action action) {
  return '$msg [shared]';
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
        );
}
```

> 推荐的是第二种写法


================================================
FILE: doc/concept/redux-cn.md
================================================
### Redux

-   State
-   [Action](action-cn.md)
-   [Reducer](reducer-cn.md)
-   Store
-   [Middleware](middleware-cn.md)

以上概念和社区的 Redux 是完全一致的。
Redux 是一个用来做[可预测][集中式][易调试][灵活性]的数据管理的框架。
如果想对 Redux 有更近一步的理解,请参考 [https://github.com/reduxjs/redux](https://github.com/reduxjs/redux)


================================================
FILE: doc/concept/redux.md
================================================
### Redux

-   State
-   [Action](action.md)
-   [Reducer](reducer.md)
-   Store
-   [Middleware](middleware.md)
    The above concepts are exactly the same as the community's Redux.
    Redux is a framework for state management with [predictable][centralized] [easy to debug][flexibility].
    If you want to have a closer understanding of Redux, please refer to [https://github.com/reduxjs/redux](https://github.com/reduxjs/redux)


================================================
FILE: doc/concept/should-update-cn.md
================================================
# ShouldUpdate

-   当数据发生变更,Store 扁平化地通知所有组件
-   框架默认使用 identical 比较新旧两份数据来决定是否需要刷新。
-   如果我们对组件的刷新会有非常精确化的诉求, 那么我们可以自己定义一个 ShouldUpdate。
-   示例代码

```dart
bool shouldUpdate(DetailState old, DetailState now) {
    return old.message != now.message;
}
```


================================================
FILE: doc/concept/should-update.md
================================================
# ShouldUpdate

-   When the state changes, the store flatly notifies all the components.
-   By default, the framework uses identical to compare the old and new state to determine if a refresh is needed.
-   If we have a very precise request for component refresh, then we can define a ShouldUpdate ourselves.
-   Sample Code

```dart
bool shouldUpdate(DetailState old, DetailState now) {
    return old.message != now.message;
}
```


================================================
FILE: doc/concept/static-flow-adapter-cn.md
================================================
# StaticFlowAdapter

-   模版是一个 Array,接受 Object|Map 的数据驱动。
-   模版接收一个 Dependent 的数组,每一个 Dependent 可以是 Component 或者 Adapter + Connector<T,P> 的组合。
-   抽象地看,它非常的像是一个 flatMap + compact 的操作。
-   示例代码

```dart
class ItemBodyComponent extends Component<ItemBodyState> {
    ItemBodyComponent()
        : super(
            view: buildItemBody,
            dependencies: Dependencies<ItemBodyState>(
            adapter: StaticFlowAdapter<ItemBodyState>(
                slots: <Dependent<ItemBodyState>>[
                    VideoAdapter().asDependent(videoConnector()),
                    UserInfoComponent().asDependent(userInfoConnector()),
                    DescComponent().asDependent(descConnector()),
                    ItemImageComponent().asDependent(itemImageConnector()),
                    OriginDescComponent().asDependent(originDescConnector()),
                    VisitComponent().asDependent(visitConnector()),
                    SameMoreComponent().asDependent(sameMoreConnector()),
                    PondComponent().asDependent(pondConnector()),
                    CommentAdapter().asDependent(commentConnector()),
                    RecommendAdapter().asDependent(recommendConnector()),
                    PaddingComponent().asDependent(paddingConnector()),
                ]),
            ),
        );
}

```

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">


================================================
FILE: doc/concept/static-flow-adapter.md
================================================
# StaticFlowAdapter

-   The template is an Array that accepts map-like data driven.
-   The template receives an array of Dependents.
-   It's similar with a flatMap + compact operation abstractly.
-   Sample Code

```dart
class ItemBodyComponent extends Component<ItemBodyState> {
    ItemBodyComponent()
        : super(
            view: buildItemBody,
            dependencies: Dependencies<ItemBodyState>(
            adapter: StaticFlowAdapter<ItemBodyState>(
                slots: <Dependent<ItemBodyState>>[
                    VideoAdapter().asDependent(videoConnector()),
                    UserInfoComponent().asDependent(userInfoConnector()),
                    DescComponent().asDependent(descConnector()),
                    ItemImageComponent().asDependent(itemImageConnector()),
                    OriginDescComponent().asDependent(originDescConnector()),
                    VisitComponent().asDependent(visitConnector()),
                    SameMoreComponent().asDependent(sameMoreConnector()),
                    PondComponent().asDependent(pondConnector()),
                    CommentAdapter().asDependent(commentConnector()),
                    RecommendAdapter().asDependent(recommendConnector()),
                    PaddingComponent().asDependent(paddingConnector()),
                ]),
            ),
        );
}

```

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">


================================================
FILE: doc/concept/view-cn.md
================================================
# View

-   View 是一个输出 Widget 的上下文无关的函数。它接收下面的参数
    -   T state
    -   Dispatch
    -   ViewService
-   它主要包含三方面的信息
    -   视图完全由数据驱动。
    -   视图产生的事件/回调,通过 Dispatch 发出“意图”,但绝不做具体的实现。
    -   使用依赖的组件/适配器,通过在组件上显示配置,再通过 ViewService 标准化调用。
        -   其中 ViewService 提供了三个能力
            -   BuildContext context,获取 flutter Build-Context 的能力
            -   Widget buildView(String name), 直接创建子组件的能力
                -   这里传入的 name 即在 Dependencies 上配置的名称。
                -   创建子组件不需要传入任何其他的参数,因为子组件需要的参数,已经通过 Dependencies 配置中,将它们的数据关系,通过 connector 确立。
            -   ListAdapter buildAdapter(), 直接创建适配器的能力
-   示例代码

```dart
Widget buildMessageView(String message, Dispatch dispatch, ViewService viewService) {
  return Column(children: [
    viewService.buildComponent('profile'),
    InkWell(
      child: Text('$message'),
      onTap: () => dispatch(const Action('onShare')),
    ),
  ]);
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
        );
}
```


================================================
FILE: doc/concept/view.md
================================================
# View

-   View is a context-independent function that outputs Widget. It receives the following parameters
    -   T state
    -   Dispatch
    -   ViewService
-   It mainly contains three aspects of information
    -   The view is completely driven by data.
    -   The event/callback triggered by the view, use Dispatch to send "intent", but never do a specific implementation.
    -   Use dependent component/adapter, by explicitly configuring it on the parent component, and then standardizing calls through the ViewService.
        -   Where ViewService provides three capabilities
            -   BuildContext context: Ability to get widget's BuildContext
            -   Widget buildView(String name): Ability to create subcomponents directly
                -   The name passed in here is the name configured on Dependencies.
                -   Creating subcomponents does not require passing in any other parameters, since the parameters required by the subcomponents have been passed through the Dependencies configuration, and their data relationships are established via the connector.
            -   ListAdapter buildAdapter(): Ability to create adapter directly
-   Sample Code

```dart
Widget buildMessageView(String message, Dispatch dispatch, ViewService viewService) {
  return Column(children: [
    viewService.buildComponent('profile'),
    InkWell(
      child: Text('$message'),
      onTap: () => dispatch(const Action('onShare')),
    ),
  ]);
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
        );
}
```


================================================
FILE: doc/concept/what's-adapter.md
================================================
# What's adapter

面向 ListView 场景的分治设计 Adapter。

> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更多的局限于它展现部分,而它的逻辑部分往往是集中的。而当我们试图将 ListView 下的某一局部的展现和逻辑封装在一起,我们就会遇到"Big-Cell"问题,面临性能的显著降低。
> 这里面存在一个分治和性能上的矛盾。这个矛盾带来了复用难,可维护差,难以协作等中大型场景下的问题。
>
> 解决这个问题,有两种思路:
>
> 1. 下沉到 UI 表达层(Widgets),去实现一个高性能的 ScrollView。
> 2. 向上做模型抽象,得到一个逻辑上的 ScrollView,性能上的 ListView。
>
> fish redux 选择了第二条更加通用的路径来解决 LisView 下的分治问题。
>
> 一个 ListView 对应了一个 Adapter,这看上去非常的像 Android 里的设计,但事实上 fish-redux 里的 Adapter 概念走的更远。
>
> 1. 一个 Adapter 是可以由多个 Component 和 Adapter 组合而成,它有点像 flatmap & compact 的 api 的叠加。
> 2. Adapter 以及它的子 Adapter 的生命周期是和 ListView 是等效的。它像跨斗一般附着于 ListView 的生命周期之上。同时由于 Adapter 生命周期的提升,我们额外收获了两个非常有用的事件消息(appear & disappear)。
>
> > 注意 ⚠️ 在 Adapter 里配置的子 Component,它的生命周期和它所对应的 WidgetState 是一致的,所以它的是短暂的。

-   Adapter 的容器有两类,用图来说明吧:

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">

<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: doc/concept/what's-connector.md
================================================
# What's connector

在解答 connector 是什么之前,我们来先看一个代码片段

```javascript
let hasChanged = false;
const nextState = {};
for (let i = 0; i < finalReducerKeys.length; i++) {
	const key = finalReducerKeys[i];
	const reducer = finalReducers[key];
	const previousStateForKey = state[key];
	const nextStateForKey = reducer(previousStateForKey, action);
	if (typeof nextStateForKey === 'undefined') {
		const errorMessage = getUndefinedStateErrorMessage(key, action);
		throw new Error(errorMessage);
	}
	nextState[key] = nextStateForKey;
	hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
return hasChanged ? nextState : state;
```

以上来自于 Reduxjs-[combineReducers](https://github.com/reduxjs/redux/blob/master/src/combineReducers.js)的核心实现。

combineReducers 是一个将 Reducer 分治的函数,让一个庞大数据的 Reducer 可以由多层的更小的 Reducer 组合而成。

这是 Redux 框架里的核心 API,但是他有缺点。他有非常明显的语言的局限性,如下 3 点:

1. 浅拷贝一个任意对象

```javascript
const nextState = {};
```

2. 读取字段

```javascript
const previousStateForKey = state[key];
```

3. 写入字段

```javascript
nextState[key] = nextStateForKey;
```

将上面的 3 点抽象来看:

1. State 的 clone 的能力(浅拷贝)
2. Get & Set 的能力,即为 Connector 的概念。

有了 以上两点,我们才完全集成了 Redux 的所有精华,同时将它的设计更上一个通用的维度。


================================================
FILE: doc/concept/what's-the-diiference-cn.md
================================================
# What's different with Redux ?

## 它们是解决不同层面问题的两个框架

> Redux 是一个专注于状态管理的框架;Fish Redux 是基于 Redux 做状态管理的应用框架。

> 应用框架不仅仅要解决状态管理的问题,还要解决分治,通信,数据驱动,解耦等等问题。

## Fish Redux 解决了集中和分治的矛盾。

> Redux 通过使用者手动组织代码的形式来完成从小的 Reducer 到主 Reducer 的合并过程;

> Fish Redux 通过显式的表达组件之间的依赖关系,由框架自动完成从细力度的 Reducer 到主 Reducer 的合并过程;

<img src="https://img.alicdn.com/tfs/TB1oeXKJYPpK1RjSZFFXXa5PpXa-1976-568.png" width="988px" height="284px">

## Fish Redux 提供了一个简单的组件抽象模型

> 它通过简单的 3 个函数组合而成

<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

## Fish Redux 提供了一个 Adapter 的抽象组件模型

> 在基础的组件模型以外,Fish Redux 提供了一个 Adapter 抽象模型,用来解决在 ListView 上大 Cell 的性能问题。

> 通过上层抽象,我们得到了逻辑上的 ScrollView,性能上的 ListView。

<img src="https://img.alicdn.com/tfs/TB1x51VJ7PoK1RjSZKbXXX1IXXa-1852-612.png" width="617px" height="204px">


================================================
FILE: doc/concept/what's-the-diiference.md
================================================
# What's different with Redux ?

## They are two frameworks for solving problems at different layers.

> Redux is a framework focused on state management; Fish Redux is an application framework based on Redux for state management.

> The application framework not only solves the problem of state management, but also solves the problems of divide and conquer, communication, data drive, decoupling and so on.

## Fish Redux solves the contradiction between concentration and division.

> Redux completes the merge process from the small Reducers to the main Reducer by the user manually organizing the code;

> Fish Redux automatically completes the merge process from the small Reducers to the main Reducer by explicitly expressing the dependencies between components;

<img src="https://img.alicdn.com/tfs/TB1oeXKJYPpK1RjSZFFXXa5PpXa-1976-568.png" width="988px" height="284px">

## Fish Redux provides a simple component abstract model

> It is a combination of simple 3 functions

<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

## Fish Redux provides an abstract component model of the Adapter

> In addition to the underlying component model, Fish Redux provides an Adapter abstraction model to solve the performance problems of large cells on ListView.

> Through the upper abstraction, we get the logical ScrollView, the performance of the ListView.

<img src="https://img.alicdn.com/tfs/TB1x51VJ7PoK1RjSZKbXXX1IXXa-1852-612.png" width="617px" height="204px">


================================================
FILE: doc/concept/widget-wrapper-cn.md
================================================
### WidgetWrapper

-   它用来解决 flutter 的 ui 体系下,一些需要实现特色接口的 Widget,比如 KeepAlive,因为通过 Component 产生的 Widget 会被一个框架内部的 Stateful 的 Widget 所包裹。
-   示例代码

```dart
import 'package:flutter/material.dart' hide Action, Page;

Widget repaintBoundaryWrapper(Widget widget) {
  return RepaintBoundary(child: widget);
}
```


================================================
FILE: doc/concept/widget-wrapper.md
================================================
### WidgetWrapper

-   It is used to solve flutter's ui system, some Widgets that need to implement the featured interface, such as KeepAlive, because the Widget generated by Component will be wrapped by a Stateful Widget inside the fish redux framework.
-   Sample Code

```dart
import 'package:flutter/material.dart' hide Action, Page;

Widget repaintBoundaryWrapper(Widget widget) {
  return RepaintBoundary(child: widget);
}
```


================================================
FILE: doc/introduction/README-cn.md
================================================
# 简介

Fish Redux 是一个基于 Redux 数据管理的组装式 flutter 应用框架, 它特别适用于构建中大型的复杂应用。

它的特点是配置式组装。
一方面我们将一个大的页面,对视图和数据层层拆解为互相独立的 Component|Adapter,上层负责组装,下层负责实现;
另一方面将 Component|Adapter 拆分为 View,Reducer,Effect 等相互独立的上下文无关函数。

所以它会非常干净,易维护,易协作。

Fish Redux 的灵感主要来自于 Redux, Elm, Dva 这样的优秀框架。而 Fish Redux 站在巨人的肩膀上,将集中,分治,复用,隔离做的更进一步。


================================================
FILE: doc/introduction/README.md
================================================
# Introduction

Fish Redux is an assembled flutter application framework based on Redux state management, it is especially suitable for building medium to large complex applications.

It features a profiled assembly. On the one hand, we disassemble a large page into separate Component|Adapters. The upper layer is responsible for assembly, and the lower layer is responsible for implementation. On the other hand, the Component|Adapter is split into separate context-independent functions such as View, Reducer, and Effect.

So it will be very clean, easy to maintain, and easy to collaborate.

Fish Redux is inspired by the excellent frameworks such as Redux, Elm, Dva.

Standing on the shoulders of giants, Fish Redux will do it further on the characteristics of concentration, division, reuse and isolation.


================================================
FILE: docs/.nojekyll
================================================


================================================
FILE: docs/README.md
================================================
<p align="center"><img src="https://img.alicdn.com/tfs/TB1r74NJyLaK1RjSZFxXXamPFXa-1024-1024.png" align="center" width="175"></p>
<h1 align="center">Fish Redux</h1>

[![Build Status](https://travis-ci.org/alibaba/fish-redux.svg?branch=master)](https://travis-ci.org/alibaba/fish-redux) [![pub package](https://img.shields.io/pub/v/fish_redux.svg)](https://pub.dartlang.org/packages/fish_redux) [![codecov](https://codecov.io/gh/alibaba/fish-redux/branch/master/graph/badge.svg)](https://codecov.io/gh/alibaba/fish-redux)

## What is Fish Redux ?

Fish Redux is an assembled flutter application framework based on Redux state management.
It is suitable for building medium and large applications.

It has four characteristics:

> 1. Functional Programming

> 2. Predictable state container

> 3. Pluggable componentization

> 4. Non-destructive performance

## Architecture diagram

<img src="https://img.alicdn.com/tfs/TB1pkhoJr2pK1RjSZFsXXaNlXXa-1004-1370.png" width="500px" height="680px">

## Installation

[Go](https://pub.dartlang.org/packages/fish_redux#-installing-tab-)

## Documentation

Language: [English](/) | [中文简体](/zh-cn/)

## Examples

-   [todo list](example) - a simple todo list demo.
-   run it:

```
cd ./example
flutter create .
flutter run
```

## What's the difference between 'Fish Redux' and 'Redux' ?

-   [answers](doc/concept/what's-the-diiference.md)

## Plugins

### Code Template

-   [Fish Redux Template For Android Studio](https://github.com/BakerJQ/FishReduxTemplateForAS), by BakerJQ.
-   [Fish Redux Template For VSCode](https://github.com/huangjianke/fish-redux-template), by huangjianke.

### Dev-Tools

-   Redux Inspector (using [Flutter Debugger](https://github.com/blankapp/flutter-debugger) and [flipperkit_fish_redux_middleware](https://pub.dartlang.org/packages/flipperkit_fish_redux_middleware)) for Fish Redux apps, by [JianyingLi](https://github.com/lijy91)

## License

-   Fish Redux is released under the Apache 2.0 license. See [LICENSE](LICENSE) for details.


## 关于我们
阿里巴巴-闲鱼技术是国内最早也是最大规模线上运行Flutter的团队。

我们在公众号中为你精选了Flutter独家干货,全面而深入。

内容包括:Flutter的接入、规模化应用、引擎探秘、工程体系、创新技术等教程和开源信息。

**架构/服务端/客户端/前端/质量工程师 在公众号中投递简历,名额不限哦**

欢迎来闲鱼做一个好奇、幸福、有影响力的程序员,简历投递:tino.wjf@alibaba-inc.com

订阅地址

<img src="https://img.alicdn.com/tfs/TB17Ki5XubviK0jSZFNXXaApXXa-656-656.png" width="328px" height="328px">

[For English](https://twitter.com/xianyutech "For English")


================================================
FILE: docs/_navbar.md
================================================
* [En](/)
* [中文](/zh-cn/)


================================================
FILE: docs/_sidebar.md
================================================
* [Redux](concept/redux.md)
* [Action](concept/action.md)
* [Connector](concept/connector.md)
* [Reducer](concept/reducer.md)
* [Middleware](concept/middleware.md)
* [Component](concept/component.md)
* [View](concept/view.md)
* [Reducer](concept/reducer.md)
* [Effect](concept/effect.md)
* [HigherEffect](concept/higher-effect.md)
* [Lifecycle](concept/lifecycle.md)
* [Dependencies](concept/dependencies.md)
* [Dependent](concept/dependent.md)
* [ShouldUpdate](concept/should-update.md)
* [OnError](concept/on-error.md)
* [Filter](concept/filter.md)
* [OOP](concept/oop.md)
* [WidgetWrapper](concept/widget-wrapper.md)
* [Page](concept/page.md)
* [Adapter](concept/adapter.md)
* [StaticFlowAdapter](concept/static-flow-adapter.md)
* [DynamicFlowAdapter](concept/dynamic-flow-adapter.md)
* [CustomAdapter](concept/custom-adapter.md)
* [What's the difference between 'Fish Redux' and 'Redux' ?](concept/what's-the-diiference.md)
* [What's-adapter](concept/what's-adapter.md)
* [What's-connector](concept/what's-connector.md)
* [Mechanism](concept/mechanism.md)
* [Directory](concept/directory.md)


================================================
FILE: docs/concept/_navbar.md
================================================
* [En](/)
* [中文](/zh-cn/)


================================================
FILE: docs/concept/_sidebar.md
================================================
* [Redux](concept/redux.md)
* [Action](concept/action.md)
* [Connector](concept/connector.md)
* [Reducer](concept/reducer.md)
* [Middleware](concept/middleware.md)
* [Component](concept/component.md)
* [View](concept/view.md)
* [Reducer](concept/reducer.md)
* [Effect](concept/effect.md)
* [HigherEffect](concept/higher-effect.md)
* [Lifecycle](concept/lifecycle.md)
* [Dependencies](concept/dependencies.md)
* [Dependent](concept/dependent.md)
* [ShouldUpdate](concept/should-update.md)
* [OnError](concept/on-error.md)
* [Filter](concept/filter.md)
* [OOP](concept/oop.md)
* [WidgetWrapper](concept/widget-wrapper.md)
* [Page](concept/page.md)
* [Adapter](concept/adapter.md)
* [StaticFlowAdapter](concept/static-flow-adapter.md)
* [DynamicFlowAdapter](concept/dynamic-flow-adapter.md)
* [CustomAdapter](concept/custom-adapter.md)
* [What's the difference between 'Fish Redux' and 'Redux' ?](concept/what's-the-diiference.md)
* [What's-adapter](concept/what's-adapter.md)
* [What's-connector](concept/what's-connector.md)
* [Mechanism](concept/mechanism.md)
* [Directory](concept/directory.md)


================================================
FILE: docs/concept/action.md
================================================
# Action

-   Action contains two fields
    -   type
    -   payload
-   Recommended way of writing action
    -   Create an action.dart file for a component|adapter that contains two classes
        -   An enumeration class for the type field
        -   An ActionCreator class is created for the creator of the Action, which helps to constrain the type of payload.
    -   Effect Accepted Action which's type is named after `on{verb}`
    -   Reducer Accepted Action which's type is named after `{verb}`
    -   Sample code

```dart
enum MessageAction {
    onShare,
    shared,
}

class MessageActionCreator {
    static Action onShare(Map<String, Object> payload) {
        return Action(MessageAction.onShare, payload: payload);
    }

    static Action shared() {
        return const Action(MessageAction.shared);
    }
}
```


================================================
FILE: docs/concept/adapter.md
================================================
# Adapter

-   In addition to the concept of the underlying Component, we have added a componentized abstract Adapter. Its goal is to solve the 3 problems of the Component model in the ListView scene.

    -   1)Putting a "Big-Cell" in the ListView does not enjoy the performance optimization of the ListView code.
    -   2)Component cannot distinguish between the appear|disappear and init|dispose events.
    -   3)The life cycle of the Effect and the coupling of the View do not meet the intuitive expectations in some scenes of the ListView.

-   An Adapter and a Component are almost identical except for the following points

    -   Component generates a Widget, Adapter generates a ListAdapter, and ListAdapter has the ability to generate a list of Widgets.。
        -   Not specifically generating a Widget but a ListAdapter can greatly improve the page frame rate and fluency.
    -   Effect-Lifecycle-Promote
        -   The Effect of Component follows the life cycle of the Widget, and the Adapter's Effect follows the life cycle of the parent Widget.
        -   The improvement of the life cycle of the effect greatly removes the coupling between the business logic and the view life. Even if its display has not yet appeared, other modules can still call its capabilities through dispatch-api.
    -   Appearance|disappear event notification
        -   As the Effect lifecycle improves, we can more closely distinguish between init|dispose and appear|disappear. This is indistinguishable from the Model's model.
    -   Reducer is long-lived, Effect is medium-lived, View is short-lived.

-   Three implementations of Adapter
    -   [DynamicFlowAdapter](dynamic-flow-adapter.md)
    -   [StaticFlowAdapter](static-flow-adapter.md)
    -   [CustomAdapter](custom-adapter.md)


================================================
FILE: docs/concept/auto-dispose.md
================================================
# Auto-Dispose

-   AutoDispose is a very simple way to manage lifecycle objects. An auto-dispose object can be released on its own initiative or released when the managed object it follows is released.
-   The Context used in Effect and the EffectPart in HigherEffect are auto-dispose objects. So we can easily host custom objects that need to be managed for lifecycle management.
-   Sample Code

```dart
class ItemWidgetBindingObserver extends WidgetsBindingObserver
    with AutoDispose {
  ItemWidgetBindingObserver() : super() {
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (AppConfig.flutterBinding.framesEnabled &&
        state == AppLifecycleState.resumed) {
      AppConfig.flutterBinding.performReassemble();
    }
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
}

void _init(Action action, Context<ItemPageContainerState> ctx) {
    final ItemWidgetBindingObserver observer = ItemWidgetBindingObserver();
    observer.follow(ctx);
}

```


================================================
FILE: docs/concept/component.md
================================================
# Component

Component is the encapsulation of view presentation and logic functions.
For the moment, from the perspective of Redux, we divide the component into state-manage functions (Reducers) and others.
Looking to the future, from the perspective of UI-Automation, we divide the component into presentations and others.

Combining the above two perspectives, we got the three parts of View, SideEffect, and Reducer, which are called the three factors of the component.

We use explicit configuration to complete the registration of components and adapters on which large component depend. This dependency configuration is called Dependencies.

So with this formula:
Component = View + Effect(Optional) + Reducer(Optional) + Dependencies(Optional)

Division: From the perspective of the component
<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

Concentration: From the perspective of the Store
<img src="https://img.alicdn.com/tfs/TB1sThMJYvpK1RjSZFqXXcXUVXa-1426-762.png" width="713px" height="381px">


================================================
FILE: docs/concept/connector.md
================================================
# Connector<T, P>

-   It expresses a data connection relationship of how to read small data from a big data, and how to synchronize to big data when the small data is modified。
-   It is the key to a centralized Reducer that can be assembled automatically by a multi-level, multi-module, small Reducer
    -   It greatly reduces the difficulty of using Redux. We no longer care about the assembly process, we care about what specific actions cause the state to change.
-   It is used in the configuration Dependencies, in the configuration we have solidified the connection between the large component and the small component, so we do not need to pass in any dynamic parameters when we use the small component.
-   ![image.png | left | 719x375](https://cdn.nlark.com/lark/0/2018/png/82574/1545365202743-01074be7-f067-45c7-aae0-91b12cd50ae6.png)

-   Sample Code

```dart
class DetialState {
    Profile profile;
    String message;
}

ConnOp<DetialState, String> messageConnector() {
    return ConnOp<DetialState, String>(
        get: (DetialState state) => state.message,
        set: (DetialState state, String message) => state.message = message,
    );
}
```


================================================
FILE: docs/concept/custom-adapter.md
================================================
# CustomAdapter

-   Custom implementation of large Cell in LisView.
-   The Factors of the Adapter are similar to the Component's. The difference is that the view part of the Adapter returns a ListAdapter.
-   Sample Code

```dart
class CommentAdapter extends Adapter<CommentState> {
    CommentAdapter()
        : super(
            adapter: buildCommentAdapter,
            effect: buildCommentEffect(),
            reducer: buildCommentReducer(),
        );
}

ListAdapter buildCommentAdapter(CommentState state, Dispatch dispatch, ViewService service) {
    final List<IndexedWidgetBuilder> builders = Collections.compact(<IndexedWidgetBuilder>[]
    ..add((BuildContext buildContext, int index) =>
        _buildDetailCommentHeader(state, dispatch, service))
    ..addAll(_buildCommentViewList(state, dispatch, service))
    ..add(isEmpty(state.commentListRes?.items)
        ? (BuildContext buildContext, int index) =>
            _buildDetailCommentEmpty(state.itemInfo, dispatch)
        : null)
    ..add(state.commentListRes?.getHasMore() == true
        ? (BuildContext buildContext, int index) => _buildLoadMore(dispatch)
        : null));
    return ListAdapter(
    (BuildContext buildContext, int index) =>
        builders[index](buildContext, index),
    builders.length,
    );
}

///builds
```


================================================
FILE: docs/concept/dependencies.md
================================================
# Dependencies

-   Dependencies is a structure that expresses dependencies between components. It accepts two fields
    -   slots
        -   <String, [Dependent](dependent.md)>{}
    -   [adapter](adapter.md)
-   It mainly contains three aspects of information
    -   The slots that the component depends on.
    -   The adapter that the component depends on (used to build a high-performance ListView).
    -   [Dependent](dependent.md) Is a combination of subComponent | subAdapter + [connector](connector.md)。
    -   A component's [Reducer](reducer.md) is automatically compounded by the Reducer configured by the Component itself and all of the Reducers under its Dependencies.
-   Sample Code

```dart
///register in component
class ItemComponent extends ItemComponent<ItemState> {
  ItemComponent()
      : super(
          view: buildItemView,
          reducer: buildItemReducer(),
          dependencies: Dependencies<ItemState>(
            slots: <String, Dependent<ItemState>>{
              'appBar': AppBarComponent().asDependent(AppBarConnector()),
              'body': ItemBodyComponent().asDependent(ItemBodyConnector()),
              'ad_ball': ADBallComponent().asDependent(ADBallConnector()),
              'bottomBar': BottomBarComponent().asDependent(BottomBarConnector()),
            },
          ),
        );
}

///call in view
Widget buildItemView(ItemState state, Dispatch dispatch, ViewService service) {
  return Scaffold(
      body: Stack(
        children: <Widget>[
          service.buildComponent('body'),
          service.buildComponent('ad_ball'),
          Positioned(
            child: service.buildComponent('bottomBar'),
            left: 0.0,
            bottom: 0.0,
            right: 0.0,
            height: 100.0,
          ),
        ],
      ),
      appBar: AppbarPreferSize(child: service.buildComponent('appBar')));
}
```


================================================
FILE: docs/concept/dependent.md
================================================
### Dependent

-   Dependent = connector<T, P> + subComponent | subAdapter
-   It expresses how the small component or adapter are connected to it's parent component.
-   Sample Code

```dart
/// todo
```


================================================
FILE: docs/concept/directory.md
================================================
# Directory

The recommended directory structure

```
sample_page
    -- action.dart /// define action types and action creator
    -- page.dart /// config a page or component
    -- view.dart /// define a function which expresses the presentation of user interface
    -- effect.dart /// define a function which handles the side-effect
    -- reducer.dart /// define a function which handles state-change
    -- state.dart /// define a state and some connector of substate
    components
        sample_component
        -- action.dart
        -- component.dart
        -- view.dart
        -- effect.dart
        -- reducer.dart
        -- state.dart
```

The upper layer is responsible for assembly and the lower layer is responsible for implementation.


================================================
FILE: docs/concept/dynamic-flow-adapter.md
================================================
# DynamicFlowAdapter

-   The template is a Map that accepts an array-like data driven
-   Sample Code

```dart
class RecommendAdapter extends DynamicFlowAdapter<RecommendState> {
    RecommendAdapter()
        : super(
            pool: <String, Component<Object>>{
                'card_0': RecommendTitleComponent(),
                'card_1': RecommendRowComponent(),
            },
            connector: RecommendCardListConnector(),
        );
}
```

<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: docs/concept/effect.md
================================================
# Effect

-   Effect is a function that handles all side effects. It receives the following parameters
    -   Action action
    -   Context context
        -   BuildContext context
        -   T state
        -   dispatch
        -   isDisposed
-   It mainly contains four aspects of information
    -   Receive "intent" from the View, including the corresponding lifecycle callback, and then make specific execution.
    -   Its processing may be an asynchronous function, the data may be changed in the process, so we should get the latest data through context.state.
    -   If you want to modify the data, you should send an Action to the Reducer to handle. It is read-only for data and cannot be modified directly in a effect function.
    -   If its return value is a non-null value, it will take precedence for itself and will not do the next step; otherwise it will broadcast to the Effect part of other components and sent the action to the Reducer.

> Self-First-Broadcast。
> ![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

-   Sample Code

```dart
/// one style of writing
FutureOr<Object> sideEffect(Action action, Context<String> ctx) async {
  if (action.type == Lifecycle.initState) {
    //do something on initState
    return true;
  } else if (action.type == 'onShare') {
    //do something on onShare
    await Future<void>.delayed(Duration(milliseconds: 1000));
    ctx.dispatch(const Action('shared'));
    return true;
  }
  return null;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: sideEffect,
        );
}
```

```dart
/// another style of writing
Effect<String> buildEffect() {
  return combineEffects(<Object, Effect<String>>{
    Lifecycle.initState: _initState,
    'onShare': _onShare,
  });
}

void _initState(Action action, Context<String> ctx) {
  //do something on initState
}

void _onShare(Action action, Context<String> ctx) async {
  //do something on onShare
  await Future<void>.delayed(Duration(milliseconds: 1000));
  ctx.dispatch(const Action('shared'));
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
        );
}
```


================================================
FILE: docs/concept/evolution-of-fish-redux.md
================================================
# fish-redux 的演进史

fish-redux 是一个不断演进的框架,甚至是在不断的回炉重造,在这个过程中

<img src="https://img.alicdn.com/tfs/TB1aeJELpzqK1RjSZFCXXbbxVXa-1794-938.png" width="897px" height="469px">

-   1. 第一个版本是基于社区内的 flutter_redux 进行的改造,核心是提供了 UI 代码的组件化,当然问题也非常明显,针对复杂的业务场景,往往业务逻辑很多,无法做到逻辑代码的分治和复用。

-   2. 第二个版本针对第一个版本的问题,做出了比较重大的修改,解决了 UI 代码和逻辑代码的分治问题,但设计上打破了 redux 的原则,丢失了 Redux 的精华。

-   3. 在第三个版本进行重构时,我们确立了整体的架构原则与分层要求,一方面按照 reduxjs 的代码进行了 flutter 侧的 redux 实现,将 redux 完整保留下来。另一方面针对组件化的问题,提供了 redux 之上的 component 的封装,并创新的通过这一层的架构设计提供了业务代码分治的能力。第三版 完成了 Redux, Component 两层的设计,其中包含了 Connector,Dependencies,Context 等重要概念。

    -   3.1 解决集中和分治的矛盾的核心在于 [Connector](what's-connector.md)
    -   3.2 这一层的组件的分治是面向通用设计的。通过在 [Dependencies](dependencies-cn.md) 配置 slots,得到了可插拔的组件系统。

-   4. 在第三个版本 Redux & Component 之外,提供了面向 ListView 场景的分治设计 Adapter。
    -   解决了在面向 ListView 场景下的逻辑的分治和性能降低的矛盾。
    -   [what's-adapter](what's-adapter.md)

> 目前,fish redux 已经在闲鱼线上稳定运行,未来,期待 fish redux 给社区带来更多的输入。


================================================
FILE: docs/concept/features.md
================================================
# Features

## 直接使用 flutter 会面临的问题?

> [flutter](https://github.com/flutter/flutter) 是 google 推出的新一代跨平台渲染框架.
> 它帮助开发者解决了跨平台,高性能,富有表现力和灵活的 UI 表达,快速开发等核心问题。
> 但是如果开发大应用,还需要解决以下问题。
>
> > 1. 数据流问题
> > 2. 通信问题
> > 3. 可插拔的组件系统
> > 4. 展示和逻辑解耦
> > 5. 统一的编程模型和规范
>
> 我们可以类比 flutter 和 React,事实上在中大型应用中 React 会面临的绝大多数问题,flutter 也同样面临考验。

## 数据流问题

> 目前社区流行的数据流方案有:
> 单向数据流方案,以 Redux 为代表
> 响应式数据流方案,以 Mobx 为代表
> 其他,以 rxjs 为代表
> 那么哪一种架构最合适 flutter ?
> 我们追随了 javascript 栈绝大多数开发者的选择 - [ReduxJs](https://github.com/reduxjs/redux)
> 感谢 ReduxJs,我们是几乎 100%的还原了它在 dart 上的实现。所以我们也继承了它的优点:[Predictable],[Centralized],[Debuggable],[Flexible]。

## 通信问题

> 直接使用 flutter,在 Widgets 之间传递状态和回调,随着应用复杂度的上升,会变成是一件可怕而糟糕的事情。
> 通过 fish redux,依托于集中的 Redux 和分治的 Effect 模块,通过一个极简的 [dispatch-api](mechanism.md),完成所有的通信的诉求。

## 可插拔的组件系统

> fish redux 通过一个配置式的 Dependencies,来完成灵活的可插拔的组件系统。同时有这一配置的存在,它解放了我们手动拼装 Reducer 的繁琐工作。
> 参考:
>
> > 1. [what's-connector](what's-connector.md)
> > 2. [connector](connector.md)
> > 3. [dependencies](dependencies.md)
> > 4. [component](component.md)
> > 5. [adapter](adapter.md)
> > 6. [what's-adapter](what's-adapter.md)

## 展示和逻辑解耦

> fish redux 从 [elm](https://guide.elm-lang.org/) 中得到了非常多的设计灵感。
> 将一个组件,拆分为相互独立的 View,Effect,Reducer 三个函数,我们优雅的解决了展示和逻辑解耦的问题。
> 通过这样的拆分,我们将 UI 的表达隔离于一个函数内,它让我们更好的面向未来,一份 UI 表达它可能来自于开发者,可能来自于深度学习框架的 UI 代码生成,可能是面向移动终端,也可能是面向浏览器。它让我们有了更多的组合的可能。
> 同时函数式的编程模型带来了更容易编写,更容易扩展,更容易测试,更容易维护等特性。

## 统一的编程模型和规范

> [directory](directory.md)


================================================
FILE: docs/concept/filter.md
================================================
# Filter

-   Filter is used to optimize the performance of the Reducer. Because the Reducer is layer-assembled, each Action is processed, and in theory, all the small Reducers are traversed. In some very complicated scenarios, such a deep traversal may take up to the millisecond level (generally Should be less than 1 millisecond). Then we need to optimize the performance of the Reducer, decide in advance whether to traverse this Reducer subtree, reduce the depth and number of traversal.
-   Sample Code

```dart
bool filter(Action action) {
    return action.type == 'some action';
}
```


================================================
FILE: docs/concept/higher-effect.md
================================================
# HigherEffect

-   Since Effect may have some temporary state of its own (although it is not recommended, support is provided), in order to support this feature, we promote the Effect to a higher-order function and put its state in the closure.
-   The framework supports the configuration of Effect|HigherEffect on component or adapter, but it can't be configured for one component or adapter at the same time, which will cause trouble. In general, the configuration is often an explicit negligence.
-   HigherEffect = (Context ctx) => (Action action) => FutureOr
-   For more detailed examples, please refer to [OOP](oop.md) - EffectPart


================================================
FILE: docs/concept/lifecycle.md
================================================
# Lifecycle

-   The default all lifecycles are essentially derived from the lifecycle in flutter State<StatefulWidget>.
    -   initState
    -   didChangeDependencies
    -   build
    -   didUpdateWidget
    -   deactivate
    -   dispose
-   Within the component, the Lifecycle of the Reducer is consistent with the page, and the lifecycle of Effect and View is consistent with the component's Widget.
-   In the adapter, the Lifecycle of the Reducer is consistent with the page. The life cycle of the Effect is the same as the life cycle of the ListView. The life cycle of the View is short-lived (destroyed in the invisible area). At the same time, the life cycle of appear and disappear is added, representing the view array managed by this adapter, the callback just entering the display area and completely leaving the display area.


================================================
FILE: docs/concept/mechanism.md
================================================
# Communication Mechanism

## Page internal communication

-   Component internal communication
-   Inter-component communication

![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

Self-First-Broadcast。
The emitted Action will be processed first by its own Effect, otherwise it will be broadcast to other components and Redux.

We completed the communication between the components (parent to child, child to parent, brother, etc.) through a simple and intuitive dispatch.

## Inter-page communication

-   Context.appBroadcast
    -   Each page's PageStore receives an action which is handled independently.

![image.png | left | 691x519](https://cdn.nlark.com/lark/0/2018/png/82574/1545368705599-745c46a3-f5c6-41a7-a757-1bc6f9a389d4.png)

# Refresh Mechanism

## 数据刷新

-   Local data modification automatically triggers a shallow copy of the upper layer data and is transparent to the business code.

![image.png | left | 747x361](https://cdn.nlark.com/lark/0/2018/png/82574/1545386668521-0081cb5f-8017-47d1-ad7c-8802bb0be8a0.png)

## View refresh

-   When the state changes, the store flatly notifies all the components and the [ShouldUpdate](should-update.md) decide whether the view should be refreshed

![image.png | left | 747x336](https://cdn.nlark.com/lark/0/2018/png/82574/1545386773247-2eddfa99-e6b9-4be9-ac43-d1944ff44e9b.png)


================================================
FILE: docs/concept/middleware-cn.md
================================================
# Middleware

关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。

示例代码

```dart
Middleware<T> logMiddleware<T>({
  String tag = 'redux',
  String Function(T) monitor,
}) {
  return ({Dispatch dispatch, Get<T> getState}) {
    return (Dispatch next) {
      return isDebug()
          ? (Action action) {
              print('---------- [$tag] ----------');
              print('[$tag] ${action.type} ${action.payload}');

              final T prevState = getState();
              if (monitor != null) {
                print('[$tag] prev-state: ${monitor(prevState)}');
              }

              next(action);

              final T nextState = getState();
              if (monitor != null) {
                print('[$tag] next-state: ${monitor(nextState)}');
              }

              if (prevState == nextState) {
                print('[$tag] warning: ${action.type} has not been used.');
              }

              print('========== [$tag] ================');
            }
          : next;
    };
  };
}
```

更多的参考 src/utils/common_middleware


================================================
FILE: docs/concept/middleware.md
================================================
# Middleware

-   The definition and signature of Middleware is consistent with the ReduxJS community.
-   Sample Code

```dart
Middleware<T> logMiddleware<T>({
  String tag = 'redux',
  String Function(T) monitor,
}) {
  return ({Dispatch dispatch, Get<T> getState}) {
    return (Dispatch next) {
      return isDebug()
          ? (Action action) {
              print('---------- [$tag] ----------');
              print('[$tag] ${action.type} ${action.payload}');

              final T prevState = getState();
              if (monitor != null) {
                print('[$tag] prev-state: ${monitor(prevState)}');
              }

              next(action);

              final T nextState = getState();
              if (monitor != null) {
                print('[$tag] next-state: ${monitor(nextState)}');
              }

              if (prevState == nextState) {
                print('[$tag] warning: ${action.type} has not been used.');
              }

              print('========== [$tag] ================');
            }
          : next;
    };
  };
}
```

更多的参考 src/utils/common_middleware


================================================
FILE: docs/concept/on-error.md
================================================
# OnError

-   Centralizes the business exceptions generated by Effect, whether it is a synchronous function or an asynchronous function. With a unified exception handling mechanism, we can stand on a higher level of abstraction and make reasonable simplifications of business code.
-   Sample Code

```dart
bool onMessageError(Exception e, Context<String> ctx) {
    if(e is BizException) {
        ///do some toast
        return true;
    }
    return false;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
            onError: onMessageError,
        );
}
```


================================================
FILE: docs/concept/oop.md
================================================
# OOP

-   Although the framework recommends the use of functional programming, it also provides object-oriented programming support.
    -   ViewPart
        -   Need to override the 'build' function.
        -   The required state, dispatch, and viewService parameters have become fields of the object and can be used directly.
        -   It is immutable, so there should be no need to define variable fields internally.
    -   EffectPart
        -   Need to override the 'createMap' function.
        -   The required Context has been flattened as the fields which can be used directly.
        -   Fields can be defined and their visibility is limited to themselves.
        -   It must be used with higherEffect.
-   Sample Code

```dart
class MessageView extends ViewPart<MessageState> {
    @override
    Widget build() {
        return Column(children: [
            viewService.buildComponent('profile'),
            InkWell(
                child: Text('$message'),
                onTap: () => dispatch(const Action('onShare')),
            ),
        ]);
    }
}

class MessageEffect extends EffectPart<MessageState> {
    ///we could put some Non-UI fields here.

    @override
    Map<Object, OnAction> createMap() {
        return <Object, OnAction>{
            Lifecycle.initState: _initState,
            'onShare': _onShare,
        };
    }

    void _initState(Action action) {
        //do something on initState
    }

    void _onShare(Action action) async {
        //do something on onShare
        await Future<void>.delayed(Duration(milliseconds: 1000));
        dispatch(const Action('shared'));
    }
}

class MessageComponent extends Component<MessageState> {
    MessageComponent(): super(
        view: MessageView().asView(),
        higherEffect: higherEffect(() => MessageEffect()),
    );
}
```


================================================
FILE: docs/concept/page.md
================================================
# Page

-   One and only one store in one page
-   Page inherits from Component, so it can configure all the factors of Component.
-   Page can configure Middleware for AOP management of Redux.
-   Page must be configured with an initialization function that initializes page data initState.
    <img src="https://img.alicdn.com/tfs/TB1ASfDJ9zqK1RjSZFHXXb3CpXa-1636-756.png" width="818px" height="378px">

-   Sample Code

```dart
/// Hello World
class HelloWordPage extends Page<String, String> {
    HelloWordPage():
        super(
            initState: (String msg) => msg,
            view:(String msg, _, __) => Text('Hello ${msg}'),
        );
}

HelloWordPage().buildPage('world')
```


================================================
FILE: docs/concept/reducer.md
================================================
# Reducer

-   The Reducer is a context-independent pure function. It receives the following parameters
    -   T state
    -   Action action
-   It mainly contains three aspects of information
    -   Receive an "intent" and make a state modification.
    -   If you want to modify the state, you need to create a new copy and modify it on the copy.
    -   If the small state is modified, it will automatically trigger the copy of the main state's layers data, and then notify the components to refresh in a flattened manner.
-   Sample Code

```dart
/// one style of writing
String messageReducer(String msg, Action action) {
  if (action.type == 'shared') {
    return '$msg [shared]';
  }
  return msg;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: messageReducer,
        );
}
```

```dart
/// another style of writing
Reducer<String> buildMessageReducer() {
  return asReducer(<Object, Reducer<String>>{
    'shared': _shared,
  });
}

String _shared(String msg, Action action) {
  return '$msg [shared]';
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
        );
}
```

> 推荐的是第二种写法


================================================
FILE: docs/concept/redux.md
================================================
### Redux

-   State
-   [Action](action.md)
-   [Reducer](reducer.md)
-   Store
-   [Middleware](middleware.md)
    The above concepts are exactly the same as the community's Redux.
    Redux is a framework for state management with [predictable][centralized] [easy to debug][flexibility].
    If you want to have a closer understanding of Redux, please refer to [https://github.com/reduxjs/redux](https://github.com/reduxjs/redux)


================================================
FILE: docs/concept/should-update.md
================================================
# ShouldUpdate

-   When the state changes, the store flatly notifies all the components.
-   By default, the framework uses identical to compare the old and new state to determine if a refresh is needed.
-   If we have a very precise request for component refresh, then we can define a ShouldUpdate ourselves.
-   Sample Code

```dart
bool shouldUpdate(DetailState old, DetailState now) {
    return old.message != now.message;
}
```


================================================
FILE: docs/concept/static-flow-adapter.md
================================================
# StaticFlowAdapter

-   The template is an Array that accepts map-like data driven.
-   The template receives an array of Dependents.
-   It's similar with a flatMap + compact operation abstractly.
-   Sample Code

```dart
class ItemBodyComponent extends Component<ItemBodyState> {
    ItemBodyComponent()
        : super(
            view: buildItemBody,
            dependencies: Dependencies<ItemBodyState>(
            adapter: StaticFlowAdapter<ItemBodyState>(
                slots: <Dependent<ItemBodyState>>[
                    VideoAdapter().asDependent(videoConnector()),
                    UserInfoComponent().asDependent(userInfoConnector()),
                    DescComponent().asDependent(descConnector()),
                    ItemImageComponent().asDependent(itemImageConnector()),
                    OriginDescComponent().asDependent(originDescConnector()),
                    VisitComponent().asDependent(visitConnector()),
                    SameMoreComponent().asDependent(sameMoreConnector()),
                    PondComponent().asDependent(pondConnector()),
                    CommentAdapter().asDependent(commentConnector()),
                    RecommendAdapter().asDependent(recommendConnector()),
                    PaddingComponent().asDependent(paddingConnector()),
                ]),
            ),
        );
}

```

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">


================================================
FILE: docs/concept/view.md
================================================
# View

-   View is a context-independent function that outputs Widget. It receives the following parameters
    -   T state
    -   Dispatch
    -   ViewService
-   It mainly contains three aspects of information
    -   The view is completely driven by data.
    -   The event/callback triggered by the view, use Dispatch to send "intent", but never do a specific implementation.
    -   Use dependent component/adapter, by explicitly configuring it on the parent component, and then standardizing calls through the ViewService.
        -   Where ViewService provides three capabilities
            -   BuildContext context: Ability to get widget's BuildContext
            -   Widget buildView(String name): Ability to create subcomponents directly
                -   The name passed in here is the name configured on Dependencies.
                -   Creating subcomponents does not require passing in any other parameters, since the parameters required by the subcomponents have been passed through the Dependencies configuration, and their data relationships are established via the connector.
            -   ListAdapter buildAdapter(): Ability to create adapter directly
-   Sample Code

```dart
Widget buildMessageView(String message, Dispatch dispatch, ViewService viewService) {
  return Column(children: [
    viewService.buildComponent('profile'),
    InkWell(
      child: Text('$message'),
      onTap: () => dispatch(const Action('onShare')),
    ),
  ]);
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
        );
}
```


================================================
FILE: docs/concept/what's-adapter.md
================================================
# What's adapter

面向 ListView 场景的分治设计 Adapter。

> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更多的局限于它展现部分,而它的逻辑部分往往是集中的。而当我们试图将 ListView 下的某一局部的展现和逻辑封装在一起,我们就会遇到"Big-Cell"问题,面临性能的显著降低。
> 这里面存在一个分治和性能上的矛盾。这个矛盾带来了复用难,可维护差,难以协作等中大型场景下的问题。
>
> 解决这个问题,有两种思路:
>
> 1. 下沉到 UI 表达层(Widgets),去实现一个高性能的 ScrollView。
> 2. 向上做模型抽象,得到一个逻辑上的 ScrollView,性能上的 ListView。
>
> fish redux 选择了第二条更加通用的路径来解决 LisView 下的分治问题。
>
> 一个 ListView 对应了一个 Adapter,这看上去非常的像 Android 里的设计,但事实上 fish-redux 里的 Adapter 概念走的更远。
>
> 1. 一个 Adapter 是可以由多个 Component 和 Adapter 组合而成,它有点像 flatmap & compact 的 api 的叠加。
> 2. Adapter 以及它的子 Adapter 的生命周期是和 ListView 是等效的。它像跨斗一般附着于 ListView 的生命周期之上。同时由于 Adapter 生命周期的提升,我们额外收获了两个非常有用的事件消息(appear & disappear)。
>
> > 注意 ⚠️ 在 Adapter 里配置的子 Component,它的生命周期和它所对应的 WidgetState 是一致的,所以它的是短暂的。

-   Adapter 的容器有两类,用图来说明吧:

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">

<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: docs/concept/what's-connector.md
================================================
# What's connector

在解答 connector 是什么之前,我们来先看一个代码片段

```javascript
let hasChanged = false;
const nextState = {};
for (let i = 0; i < finalReducerKeys.length; i++) {
	const key = finalReducerKeys[i];
	const reducer = finalReducers[key];
	const previousStateForKey = state[key];
	const nextStateForKey = reducer(previousStateForKey, action);
	if (typeof nextStateForKey === 'undefined') {
		const errorMessage = getUndefinedStateErrorMessage(key, action);
		throw new Error(errorMessage);
	}
	nextState[key] = nextStateForKey;
	hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
return hasChanged ? nextState : state;
```

以上来自于 Reduxjs-[combineReducers](https://github.com/reduxjs/redux/blob/master/src/combineReducers.js)的核心实现。

combineReducers 是一个将 Reducer 分治的函数,让一个庞大数据的 Reducer 可以由多层的更小的 Reducer 组合而成。

这是 Redux 框架里的核心 API,但是他有缺点。他有非常明显的语言的局限性,如下 3 点:

1. 浅拷贝一个任意对象

```javascript
const nextState = {};
```

2. 读取字段

```javascript
const previousStateForKey = state[key];
```

3. 写入字段

```javascript
nextState[key] = nextStateForKey;
```

将上面的 3 点抽象来看:

1. State 的 clone 的能力(浅拷贝)
2. Get & Set 的能力,即为 Connector 的概念。

有了 以上两点,我们才完全集成了 Redux 的所有精华,同时将它的设计更上一个通用的维度。


================================================
FILE: docs/concept/what's-the-diiference.md
================================================
# What's different with Redux ?

## They are two frameworks for solving problems at different layers.

> Redux is a framework focused on state management; Fish Redux is an application framework based on Redux for state management.

> The application framework not only solves the problem of state management, but also solves the problems of divide and conquer, communication, data drive, decoupling and so on.

## Fish Redux solves the contradiction between concentration and division.

> Redux completes the merge process from the small Reducers to the main Reducer by the user manually organizing the code;

> Fish Redux automatically completes the merge process from the small Reducers to the main Reducer by explicitly expressing the dependencies between components;

<img src="https://img.alicdn.com/tfs/TB1oeXKJYPpK1RjSZFFXXa5PpXa-1976-568.png" width="988px" height="284px">

## Fish Redux provides a simple component abstract model

> It is a combination of simple 3 functions

<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

## Fish Redux provides an abstract component model of the Adapter

> In addition to the underlying component model, Fish Redux provides an Adapter abstraction model to solve the performance problems of large cells on ListView.

> Through the upper abstraction, we get the logical ScrollView, the performance of the ListView.

<img src="https://img.alicdn.com/tfs/TB1x51VJ7PoK1RjSZKbXXX1IXXa-1852-612.png" width="617px" height="204px">


================================================
FILE: docs/concept/widget-wrapper.md
================================================
### WidgetWrapper

-   It is used to solve flutter's ui system, some Widgets that need to implement the featured interface, such as KeepAlive, because the Widget generated by Component will be wrapped by a Stateful Widget inside the fish redux framework.
-   Sample Code

```dart
import 'package:flutter/material.dart' hide Action;

Widget repaintBoundaryWrapper(Widget widget) {
  return RepaintBoundary(child: widget);
}
```


================================================
FILE: docs/index.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
  <meta name="description" content="Description">
  <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
  <link rel="stylesheet" href="//unpkg.com/docsify/lib/themes/vue.css">
</head>
<body>

  <div id="app"></div>
  <script>
    window.$docsify = {
      name: '',
      repo: '',
      el: '#app',
      repo: 'https://github.com/alibaba/fish-redux',

      // 加载 _navbar.md
      loadNavbar: true,
      // 加载 _navbar.md
      loadNavbar: '_navbar.md',

      // 加载 _sidebar.md
      loadSidebar: true,
      // 加载 _sidebar.md
      loadSidebar: '_sidebar.md',

      // 完整配置参数
      search: {
        maxAge: 86400000, // 过期时间,单位毫秒,默认一天
        paths: [], // or 'auto'
        placeholder: 'Type to search',

        // 支持本地化
        placeholder: {
          '/zh-cn/': '搜索',
          '/': 'Type to search'
        },

        noData: 'No Results!',

        // 支持本地化
        noData: {
          '/zh-cn/': '找不到结果',
          '/': 'No Results'
        },

        // 搜索标题的最大程级, 1 - 6
        depth: 2
      },

      plugins: [
        function (hook) {
          var footer = [
            '<hr/>',
            '<footer>',
            '<span>Proudly published with <a href="https://github.com/docsifyjs/docsify" target="_blank">docsify</a>.</span>',
            '</footer>'
          ].join('')

          hook.afterEach(function (html) {
            return html + footer
          })
        }
      ]

    }
  </script>
  <script src="//unpkg.com/docsify/lib/docsify.min.js"></script>
  <script src="//unpkg.com/docsify/lib/plugins/zoom-image.js"></script>
</body>
</html>


================================================
FILE: docs/zh-cn/README.md
================================================

-   **核心概念**
    -   [Redux](/zh-cn/concept/redux.md)
        -   [Action](/zh-cn/concept/action.md)
        -   [Connector](/zh-cn/concept/connector.md)
        -   [Reducer](/zh-cn/concept/reducer.md)
        -   [Middleware](/zh-cn/concept/middleware.md)
    -   [Component](/zh-cn/concept/component.md)
        -   [View](/zh-cn/concept/view.md)
        -   [Reducer](/zh-cn/concept/reducer.md)
        -   [Effect](/zh-cn/concept/effect.md)
        -   [HigherEffect](/zh-cn/concept/higher-effect.md)
        -   [Lifecycle](/zh-cn/concept/lifecycle.md)
        -   [Dependencies](/zh-cn/concept/dependencies.md)
        -   [Dependent](/zh-cn/concept/dependent.md)
        -   [ShouldUpdate](/zh-cn/concept/should-update.md)
        -   [OnError](/zh-cn/concept/on-error.md)
        -   [Filter](/zh-cn/concept/filter.md)
        -   [OOP](/zh-cn/concept/oop.md)
        -   [WidgetWrapper](/zh-cn/concept/widget-wrapper.md)
        -   [Page](/zh-cn/concept/page.md)
    -   [Adapter](/zh-cn/concept/adapter.md)
        -   [StaticFlowAdapter](/zh-cn/concept/static-flow-adapter.md)
        -   [DynamicFlowAdapter](/zh-cn/concept/dynamic-flow-adapter.md)
        -   [CustomAdapter](/zh-cn/concept/custom-adapter.md)
-   **其他**
    -   [What's the difference between 'Fish Redux' and 'Redux' ?](/zh-cn/concept/what's-the-diiference.md)
    -   [What's-adapter](/zh-cn/concept/what's-adapter.md)
    -   [What's-connector](/zh-cn/concept/what's-connector.md)
    -   [Mechanism](/zh-cn/concept/mechanism.md)
    -   [Directory](/zh-cn/concept/directory.md)


================================================
FILE: docs/zh-cn/_sidebar.md
================================================

* [Redux](zh-cn/concept/redux.md)
* [Action](zh-cn/concept/action.md)
* [Connector](zh-cn/concept/connector.md)
* [Reducer](zh-cn/concept/reducer.md)
* [Middleware](zh-cn/concept/middleware.md)
* [Component](zh-cn/concept/component.md)
* [View](zh-cn/concept/view.md)
* [Reducer](zh-cn/concept/reducer.md)
* [Effect](zh-cn/concept/effect.md)
* [HigherEffect](zh-cn/concept/higher-effect.md)
* [Lifecycle](zh-cn/concept/lifecycle.md)
* [Dependencies](zh-cn/concept/dependencies.md)
* [Dependent](zh-cn/concept/dependent.md)
* [ShouldUpdate](zh-cn/concept/should-update.md)
* [OnError](zh-cn/concept/on-error.md)
* [Filter](zh-cn/concept/filter.md)
* [OOP](zh-cn/concept/oop.md)
* [WidgetWrapper](zh-cn/concept/widget-wrapper.md)
* [Page](zh-cn/concept/page.md)
* [Adapter](zh-cn/concept/adapter.md)
* [StaticFlowAdapter](zh-cn/concept/static-flow-adapter.md)
* [DynamicFlowAdapter](zh-cn/concept/dynamic-flow-adapter.md)
* [CustomAdapter](zh-cn/concept/custom-adapter.md)
* [What's the difference between 'Fish Redux' and 'Redux' ?](zh-cn/concept/what's-the-diiference.md)
* [What's-adapter](zh-cn/concept/what's-adapter.md)
* [What's-connector](zh-cn/concept/what's-connector.md)
* [Mechanism](zh-cn/concept/mechanism.md)
* [Directory](zh-cn/concept/directory.md)


================================================
FILE: docs/zh-cn/concept/_navbar.md
================================================
* [En](/)
* [中文](/zh-cn/)


================================================
FILE: docs/zh-cn/concept/_sidebar.md
================================================

* [Redux](zh-cn/concept/redux.md)
* [Action](zh-cn/concept/action.md)
* [Connector](zh-cn/concept/connector.md)
* [Reducer](zh-cn/concept/reducer.md)
* [Middleware](zh-cn/concept/middleware.md)
* [Component](zh-cn/concept/component.md)
* [View](zh-cn/concept/view.md)
* [Reducer](zh-cn/concept/reducer.md)
* [Effect](zh-cn/concept/effect.md)
* [HigherEffect](zh-cn/concept/higher-effect.md)
* [Lifecycle](zh-cn/concept/lifecycle.md)
* [Dependencies](zh-cn/concept/dependencies.md)
* [Dependent](zh-cn/concept/dependent.md)
* [ShouldUpdate](zh-cn/concept/should-update.md)
* [OnError](zh-cn/concept/on-error.md)
* [Filter](zh-cn/concept/filter.md)
* [OOP](zh-cn/concept/oop.md)
* [WidgetWrapper](zh-cn/concept/widget-wrapper.md)
* [Page](zh-cn/concept/page.md)
* [Adapter](zh-cn/concept/adapter.md)
* [StaticFlowAdapter](zh-cn/concept/static-flow-adapter.md)
* [DynamicFlowAdapter](zh-cn/concept/dynamic-flow-adapter.md)
* [CustomAdapter](zh-cn/concept/custom-adapter.md)
* [What's the difference between 'Fish Redux' and 'Redux' ?](zh-cn/concept/what's-the-diiference.md)
* [What's-adapter](zh-cn/concept/what's-adapter.md)
* [What's-connector](zh-cn/concept/what's-connector.md)
* [Mechanism](zh-cn/concept/mechanism.md)
* [Directory](zh-cn/concept/directory.md)


================================================
FILE: docs/zh-cn/concept/action.md
================================================
# Action

-   Action 包含两个字段
    -   type
    -   payload
-   推荐的写法是
    -   为一个组件|适配器创建一个 action.dart 文件,包含两个类
        -   为 type 字段起一个枚举类
        -   为 Action 的创建起一个 ActionCreator 类,这样利于约束 payload 的类型。
    -   Effect 接受处理的 Action,以 on{Verb} 命名
    -   Reducer 接受处理的 Action,以{verb} 命名
    -   示例代码

```dart
enum MessageAction {
    onShare,
    shared,
}

class MessageActionCreator {
    static Action onShare(Map<String, Object> payload) {
        return Action(MessageAction.onShare, payload: payload);
    }

    static Action shared() {
        return const Action(MessageAction.shared);
    }
}
```


================================================
FILE: docs/zh-cn/concept/adapter.md
================================================
# Adapter

-   我们在基础 Component 的概念外,额外增加了一种组件化的抽象 Adapter。它的目标是解决 Component 模型在 ListView 的场景下的 3 个问题
    -   1)将一个"Big-Cell"放在 ListView 里,无法享受 ListView 代码的性能优化。
    -   2)Component 无法区分 appear|disappear 和 init|dispose 事件。
    -   3)Effect 的生命周期和 View 的耦合,在 ListView 的有些场景下不符合直观的预期。
-   一个 Adapter 和 Component 几乎都是一致的,除了以下几点
    -   Component 生成一个 Widget,Adapter 生成一个 ListAdapter,ListAdapter 有能力生成一组 Widget。
        -   不具体生成 Widget,而是一个 ListAdapter,能非常大的提升页面帧率和流畅度。
    -   Effect-Lifecycle-Promote
        -   Component 的 Effect 是跟着 Widget 的生命周期走的,Adapter 的 Effect 是跟着上一级的 Widget 的生命周期走。
        -   Effect​ 提升,极大的解除了业务逻辑和视图生命的耦合,即使它的展示还未出现,的其他模块依然能通过 dispatch-api,调用它的能力。
    -   appear|disappear 的通知
        -   由于 Effect 生命周期的提升,我们就能更加精细的区分 init|dispose 和 appear|disappear。而这在 Component 的模型中是无法区分的。
    -   Reducer is long-lived, Effect is medium-lived, View is short-lived.
-   Adapter 的三种实现
    -   [DynamicFlowAdapter](dynamic-flow-adapter-cn.md)
    -   [StaticFlowAdapter](static-flow-adapter-cn.md)
    -   [CustomAdapter](custom-adapter-cn.md)


================================================
FILE: docs/zh-cn/concept/auto-dispose.md
================================================
# Auto-Dispose

-   它是一个非常简易管理生命周期对象的方式。一个 auto-dispose 对象可以自我主动释放,或者在它 follow 的 托管对象释放的时候,释放。
-   在 Effect 中使用的 Context,以及 HigherEffect 中的 EffectPart,都是 auto-dispose 对象。所以我们可以方便的将自定义的需要做生命周期管理的对象托管给它们。
-   示例代码

```dart
class ItemWidgetBindingObserver extends WidgetsBindingObserver
    with AutoDispose {
  ItemWidgetBindingObserver() : super() {
    WidgetsBinding.instance.addObserver(this);
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    if (AppConfig.flutterBinding.framesEnabled &&
        state == AppLifecycleState.resumed) {
      AppConfig.flutterBinding.performReassemble();
    }
  }

  @override
  void dispose() {
    super.dispose();
    WidgetsBinding.instance.removeObserver(this);
  }
}

void _init(Action action, Context<ItemPageContainerState> ctx) {
    final ItemWidgetBindingObserver observer = ItemWidgetBindingObserver();
    observer.follow(ctx);
}

```


================================================
FILE: docs/zh-cn/concept/component.md
================================================
# Component

组件是对视图展现和逻辑功能的封装。
面向当下,从 Redux 的视角看,我们对组件分为状态修改的功能(Reducer)和其他。
面向未来,从 UI-Automation 的视角看,我们对组件分为展现表达和其他。
结合上面两个视角,于是我们得到了,View、 Effect、Reducer 三部分,称之为组件的三要素,分别负责了组件的展示、非修改数据的行为、修改数据的操作。

我们以显式配置的方式来完成大组件所依赖的小组件、适配器的注册,这份依赖配置称之为 Dependencies。

所以有了这个公式
Component = View + Effect(可选) + Reducer(可选) + Dependencies(可选)

分治:从组件的角度
<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

集中:从 Store 的角度
<img src="https://img.alicdn.com/tfs/TB1sThMJYvpK1RjSZFqXXcXUVXa-1426-762.png" width="713px" height="381px">


================================================
FILE: docs/zh-cn/concept/connector.md
================================================
# Connector<T, P>

-   它表达了如何从一个大数据中读取小数据,同时对小数据的修改如何同步给大数据,这样的数据连接关系。
-   它是将一个集中式的 Reducer,可以由多层次多模块的小 Reducer 自动拼装的关键。
    -   它大大降低了我们使用 Redux 的复杂度。我们不再关心组装过程,我们关心的核心是什么动作促使数据怎么变化。
-   它使用在配置 Dependencies 中,在配置中我们就固化了大组件和小组件之间的连接关系(数据管道),所以在我们使用小组件的时候是不需要传入任何动态参数的。
-   ![image.png | left | 719x375](https://cdn.nlark.com/lark/0/2018/png/82574/1545365202743-01074be7-f067-45c7-aae0-91b12cd50ae6.png)

-   Sample Code

```dart
class DetialState {
    Profile profile;
    String message;
}

ConnOp<DetialState, String> messageConnector() {
    return ConnOp<DetialState, String>(
        get: (DetialState state) => state.message,
        set: (DetialState state, String message) => state.message = message,
    );
}
```


================================================
FILE: docs/zh-cn/concept/custom-adapter.md
================================================
# CustomAdapter

-   对大 Cell 的自定义实现
-   要素和 Component 类似,不一样的地方是 Adapter 的视图部分返回的是一个 ListAdapter
-   示例代码

```dart
class CommentAdapter extends Adapter<CommentState> {
    CommentAdapter()
        : super(
            adapter: buildCommentAdapter,
            effect: buildCommentEffect(),
            reducer: buildCommentReducer(),
        );
}

ListAdapter buildCommentAdapter(CommentState state, Dispatch dispatch, ViewService service) {
    final List<IndexedWidgetBuilder> builders = Collections.compact(<IndexedWidgetBuilder>[]
    ..add((BuildContext buildContext, int index) =>
        _buildDetailCommentHeader(state, dispatch, service))
    ..addAll(_buildCommentViewList(state, dispatch, service))
    ..add(isEmpty(state.commentListRes?.items)
        ? (BuildContext buildContext, int index) =>
            _buildDetailCommentEmpty(state.itemInfo, dispatch)
        : null)
    ..add(state.commentListRes?.getHasMore() == true
        ? (BuildContext buildContext, int index) => _buildLoadMore(dispatch)
        : null));
    return ListAdapter(
    (BuildContext buildContext, int index) =>
        builders[index](buildContext, index),
    builders.length,
    );
}

///builds
```


================================================
FILE: docs/zh-cn/concept/dependencies.md
================================================
# Dependencies

-   Dependencies 是一个表达组件之间依赖关系的结构。它接收两个字段
    -   slots
        -   <String, [Dependent](dependent-cn.md)>{}
    -   [adapter](adapter-cn.md)
-   它主要包含三方面的信息
    -   slots,组件依赖的插槽。
    -   adapter,组件依赖的具体适配器(用来构建高性能的 ListView)。
    -   [Dependent](dependent-cn.md) 是 subComponent | subAdapter + [connector](connector-cn.md) 的组合。
    -   一个 组件的 [Reducer](reducer-cn.md) 由 Component 自身配置的 Reducer 和它的 Dependencies 下的所有子 Reducers 自动复合而成。
-   示例代码

```dart
///register in component
class ItemComponent extends ItemComponent<ItemState> {
  ItemComponent()
      : super(
          view: buildItemView,
          reducer: buildItemReducer(),
          dependencies: Dependencies<ItemState>(
            slots: <String, Dependent<ItemState>>{
              'appBar': AppBarComponent().asDependent(AppBarConnector()),
              'body': ItemBodyComponent().asDependent(ItemBodyConnector()),
              'ad_ball': ADBallComponent().asDependent(ADBallConnector()),
              'bottomBar': BottomBarComponent().asDependent(BottomBarConnector()),
            },
          ),
        );
}

///call in view
Widget buildItemView(ItemState state, Dispatch dispatch, ViewService service) {
  return Scaffold(
      body: Stack(
        children: <Widget>[
          service.buildComponent('body'),
          service.buildComponent('ad_ball'),
          Positioned(
            child: service.buildComponent('bottomBar'),
            left: 0.0,
            bottom: 0.0,
            right: 0.0,
            height: 100.0,
          ),
        ],
      ),
      appBar: AppbarPreferSize(child: service.buildComponent('appBar')));
}
```


================================================
FILE: docs/zh-cn/concept/dependent.md
================================================
### Dependent

-   Dependent = connector<T, P> + subComponent | subAdapter 的组合,它表达了小组件|小适配器是如何连接到 Component 的。
-   示例代码

```dart
/// todo
```


================================================
FILE: docs/zh-cn/concept/directory.md
================================================
# Directory

推荐的目录结构会是这样

```
sample_page
    -- action.dart /// define action types and action creator
    -- page.dart /// config a page or component
    -- view.dart /// define a function which expresses the presentation of user interface
    -- effect.dart /// define a function which handles the side-effect
    -- reducer.dart /// define a function which handles state-change
    -- state.dart /// define a state and some connector of substate
    components
        sample_component
        -- action.dart
        -- component.dart
        -- view.dart
        -- effect.dart
        -- reducer.dart
        -- state.dart
```

上层负责组装,下层负责实现。


================================================
FILE: docs/zh-cn/concept/dynamic-flow-adapter.md
================================================
# DynamicFlowAdapter

-   模版是一个 Map,接受一个数组类型的数据驱动
-   示例代码

```dart
class RecommendAdapter extends DynamicFlowAdapter<RecommendState> {
    RecommendAdapter()
        : super(
            pool: <String, Component<Object>>{
                'card_0': RecommendTitleComponent(),
                'card_1': RecommendRowComponent(),
            },
            connector: RecommendCardListConnector(),
        );
}
```
<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: docs/zh-cn/concept/effect.md
================================================
# Effect

Effect顾名思义,用于处理Action的副作用。

我估摸着有人就要问我了,副作用是啥玩意?

打个比方吧,假如我拥有一个函数 `f()`

```text
fn f(x):
  return x * 1
```

此时此刻,另一个函数 `g()`

```text
fn g(x):
  changeSystemEntropy()
  return ax ^ 2 + bx + c
```

我们可以发现,`g()`里边有个改变系统熵的行为。这在函数式编程思想中,就叫做副作用,因为它可能影响到除了这个函数内部自身状态以外的其他状态。

在Fish-Redux中同样,我们通过 `dispatch()` 一些action实现状态修改,但是相对于状态来说,对外部的操作,类似于 `SystemChrome.setSystemUIOverlayStyle()`这样的操作,都是副作用。

现在介绍完了副作用,也没啥可介绍的了。

Effect用法跟Reducer差不太多,但是作用完全不同。

除了上面介绍的场景之外,异步请求也是一个经常会有的情况,这时候Effect可以帮你方便的解决这些问题。

你可以通过控制effect的返回值来达到某些目的,默认情况下,effect会在reducer之前被执行。

当前effect返回 `true` 的时候,就会停止后续的effect和reducer的操作

当前effect返回 `false` 的时候,后续effect和reducer继续执行

-   Effect 是一个处理所有副作用的函数。它接收下面的参数
    -   Action action
    -   Context context
        -   BuildContext context
        -   T state
        -   dispatch
        -   isDisposed
        
Effect会接收来自 View 的“意图”,包括对应的生命周期的回调,然后做出具体的执行。
    -   它的处理可能是一个异步函数,数据可能在过程中被修改,所以我们应该通过 context.state 获取最新数据。
    -   如果它要修改数据,应该发一个 Action 到 Reducer 里去处理。它对数据是只读的,不能直接去修改数据。
    -   如果它的返回值是一个非空值,则代表自己优先处理,不再做下一步的动作;否则广播给其他组件的 Effect 部分,同时发送给 Reducer。

> Self-First-Broadcast。
> ![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

-   示例代码

```dart
/// one style of writing
FutureOr<Object> sideEffect(Action action, Context<String> ctx) async {
  if (action.type == Lifecycle.initState) {
    //do something on initState
    return true;
  } else if (action.type == 'onShare') {
    //do something on onShare
    await Future<void>.delayed(Duration(milliseconds: 1000));
    ctx.dispatch(const Action('shared'));
    return true;
  }
  return null;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: sideEffect,
        );
}
```

```dart
/// another style of writing
Effect<String> buildEffect() {
  return combineEffects(<Object, Effect<String>>{
    Lifecycle.initState: _initState,
    'onShare': _onShare,
  });
}

void _initState(Action action, Context<String> ctx) {
  //do something on initState
}

void _onShare(Action action, Context<String> ctx) async {
  //do something on onShare
  await Future<void>.delayed(Duration(milliseconds: 1000));
  ctx.dispatch(const Action('shared'));
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
        );
}
```


================================================
FILE: docs/zh-cn/concept/filter.md
================================================
# Filter

-   Filter 是用来优化 Reducer 的性能的。因为 Reducer 是层层组装的,所以处理每一个 Action,理论上会遍历一遍所有的小 Reducer,在一些非常复杂的场景下,这样的一次深度遍历的耗时可能会到毫秒级别(一般情况下都应该小于 1 毫秒)。那么我们需要对 Reducer 做性能优化,提前决定要不要遍历这份 Reducer 子树,减少遍历的深度和次数。
-   示例代码

```dart
bool filter(Action action) {
    return action.type == 'some action';
}
```


================================================
FILE: docs/zh-cn/concept/higher-effect.md
================================================
# HigherEffect

-   由于 Effect 有可能有自己一些临时状态(尽管不建议这么做,但还是提供了支持),为了支持这个特性,我们将 Effect 提升为高阶函数,将它的状态放在闭包里。
-   框架支持 Effect|HigherEffect 的配置,但是不能对一个组件或适配器同时都配置,那样会带来困扰,一般情况下,都配置往往是个显式的疏忽大意。
-   HigherEffect = (Context ctx) => (Action action) => FutureOr
-   更详细的例子请参考 [OOP](oop-cn.md) - EffectPart


================================================
FILE: docs/zh-cn/concept/lifecycle.md
================================================
# Lifecycle

-   默认的所有生命周期,本质上都来自于 flutter State<StatefulWidget> 中的生命周期。
    -   initState
    -   didChangeDependencies
    -   build
    -   didUpdateWidget
    -   deactivate
    -   dispose
-   在组件内,Reducer 的生命周期是和页面一致的,Effect 和 View 的生命周期是和组件的 Widget 一致的。
-   在适配器中,Reducer 的生命周期是和页面一致的,Effect 的生命周期是和 ListView 的生命周期一致,View 的生命周期是短暂的(划入不可见区域即销毁)。同时增加了 appear 和 disappear 的生命周期, 代表这个 adapter 管理的视图数组,刚进入显示区和完全离开显示区的回调。


================================================
FILE: docs/zh-cn/concept/mechanism.md
================================================
# Communication Mechanism

## 页面内通信

-   组件|适配器内通信
-   组件|适配器间内通信

![image.png | left | 747x399](https://cdn.nlark.com/lark/0/2018/png/82574/1545365233153-4c8105b4-050c-49e6-be02-dbf28a861caa.png)

Self-First-Broadcast。
发出的 Action,自己优先处理,否则广播给其他组件和 Redux 处理。

最终我们通过一个简单而直观的 dispatch 完成了组件内,组件间(父到子,子到父,兄弟间等)的通信。

## 页面间通信

-   页面间通信
    -   Context.appBroadcast
        -   每一个页面的 PageStore 都会收到消息,各自独立负责处理。

![image.png | left | 691x519](https://cdn.nlark.com/lark/0/2018/png/82574/1545368705599-745c46a3-f5c6-41a7-a757-1bc6f9a389d4.png)

# Refresh Mechanism

## 数据刷新

-   局部数据修改,自动层层触发上层数据的浅拷贝,对业务代码是透明的。
-   层层的数据的拷贝
    -   一方面是对 Redux 数据修改的严格的 follow。
    -   另一方面也是对数据驱动展示的严格的 follow。
        -   数据的任何一个局部的变动,必须要让能看到这个局部的所有视图感知到。如果不拷贝,对应的视图通过新旧两份数据的比较(同一个引用),会错以为自己没有发生变化。

![image.png | left | 747x361](https://cdn.nlark.com/lark/0/2018/png/82574/1545386668521-0081cb5f-8017-47d1-ad7c-8802bb0be8a0.png)

## 视图刷新

-   扁平化通知到所有组件,组件通过 shouldUpdate 确定自己是否需要刷新

![image.png | left | 747x336](https://cdn.nlark.com/lark/0/2018/png/82574/1545386773247-2eddfa99-e6b9-4be9-ac43-d1944ff44e9b.png)


================================================
FILE: docs/zh-cn/concept/middleware.md
================================================
# Middleware

关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。

示例代码

```dart
Middleware<T> logMiddleware<T>({
  String tag = 'redux',
  String Function(T) monitor,
}) {
  return ({Dispatch dispatch, Get<T> getState}) {
    return (Dispatch next) {
      return isDebug()
          ? (Action action) {
              print('---------- [$tag] ----------');
              print('[$tag] ${action.type} ${action.payload}');

              final T prevState = getState();
              if (monitor != null) {
                print('[$tag] prev-state: ${monitor(prevState)}');
              }

              next(action);

              final T nextState = getState();
              if (monitor != null) {
                print('[$tag] next-state: ${monitor(nextState)}');
              }

              if (prevState == nextState) {
                print('[$tag] warning: ${action.type} has not been used.');
              }

              print('========== [$tag] ================');
            }
          : next;
    };
  };
}
```

更多的参考 src/utils/common_middleware


================================================
FILE: docs/zh-cn/concept/on-error.md
================================================
# OnError

-   集中处理由 Effect 产生的业务异常,无论是同步函数还是异步函数。有了统一的异常处理机制,我们就能站在一个更高的抽象角度,对业务代码做出合理的简化。
-   示例代码

```dart
bool onMessageError(Exception e, Context<String> ctx) {
    if(e is BizException) {
        ///do some toast
        return true;
    }
    return false;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
            onError: onMessageError,
        );
}
```


================================================
FILE: docs/zh-cn/concept/oop.md
================================================
# OOP

-   虽然框架推荐使用的函数式的编程方式,也提供面向对象式的编程方式的支持。
    -   ViewPart
        -   需要复写 build 函数。
        -   需要的 state,dispatch,viewService 的参数,已经成为了对象的字段可以直接使用。
        -   它是@immutable 的,所以不应该也不需要在内部定义可变字段。
    -   EffectPart
        -   需要复写 createMap 函数。
        -   需要的 Context 已经被打平,作为了对象的字段可以直接使用。
        -   可以定义字段,它的可见性也仅限于自身。
        -   它必须配合 higherEffect 一起使用。
-   示例代码

```dart
class MessageView extends ViewPart<MessageState> {
    @override
    Widget build() {
        return Column(children: [
            viewService.buildComponent('profile'),
            InkWell(
                child: Text('$message'),
                onTap: () => dispatch(const Action('onShare')),
            ),
        ]);
    }
}

class MessageEffect extends EffectPart<MessageState> {
    ///we could put some Non-UI fields here.

    @override
    Map<Object, OnAction> createMap() {
        return <Object, OnAction>{
            Lifecycle.initState: _initState,
            'onShare': _onShare,
        };
    }

    void _initState(Action action) {
        //do something on initState
    }

    void _onShare(Action action) async {
        //do something on onShare
        await Future<void>.delayed(Duration(milliseconds: 1000));
        dispatch(const Action('shared'));
    }
}

class MessageComponent extends Component<MessageState> {
    MessageComponent(): super(
        view: MessageView().asView(),
        higherEffect: higherEffect(() => MessageEffect()),
    );
}
```


================================================
FILE: docs/zh-cn/concept/page.md
================================================
# Page

-   一个页面内都有且仅有一个 Store
-   Page 继承于 Component,所以它能配置所有 Component 的要素
-   Page 能配置 Middleware,用于对 Redux 做 AOP 管理
-   Page 必须配置一个初始化页面数据的初始化函数  initState
    <img src="https://img.alicdn.com/tfs/TB1ASfDJ9zqK1RjSZFHXXb3CpXa-1636-756.png" width="818px" height="378px">

-   示例代码

```dart
/// Hello World
class HelloWordPage extends Page<String, String> {
    HelloWordPage():
        super(
            initState: (String msg) => msg,
            view:(String msg, _, __) => Text('Hello ${msg}'),
        );
}

HelloWordPage().buildPage('world')
```


================================================
FILE: docs/zh-cn/concept/reducer.md
================================================
# Reducer

-   Reducer 是一个上下文无关的 pure function。它接收下面的参数
    -   T state
    -   Action action
-   它主要包含三方面的信息
    -   接收一个“意图”, 做出数据修改。
    -   如果要修改数据,需要创建一份新的拷贝,修改在拷贝上。
    -   如果数据修改了,它会自动触发 State 的层层数据的拷贝,再以扁平化方式通知组件刷新。
-   示例代码

```dart
/// one style of writing
String messageReducer(String msg, Action action) {
  if (action.type == 'shared') {
    return '$msg [shared]';
  }
  return msg;
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: messageReducer,
        );
}
```

```dart
/// another style of writing
Reducer<String> buildMessageReducer() {
  return asReducer(<Object, Reducer<String>>{
    'shared': _shared,
  });
}

String _shared(String msg, Action action) {
  return '$msg [shared]';
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
            effect: buildEffect(),
            reducer: buildMessageReducer(),
        );
}
```

> 推荐的是第二种写法


================================================
FILE: docs/zh-cn/concept/redux.md
================================================
### Redux

-   State
-   [Action](action-cn.md)
-   [Reducer](reducer-cn.md)
-   Store
-   [Middleware](middleware-cn.md)

以上概念和社区的 Redux 是完全一致的。
Redux 是一个用来做[可预测][集中式][易调试][灵活性]的数据管理的框架。
如果想对 Redux 有更近一步的理解,请参考 [https://github.com/reduxjs/redux](https://github.com/reduxjs/redux)


================================================
FILE: docs/zh-cn/concept/should-update.md
================================================
# ShouldUpdate

-   当数据发生变更,Store 扁平化地通知所有组件
-   框架默认使用 identical 比较新旧两份数据来决定是否需要刷新。
-   如果我们对组件的刷新会有非常精确化的诉求, 那么我们可以自己定义一个 ShouldUpdate。
-   示例代码

```dart
bool shouldUpdate(DetailState old, DetailState now) {
    return old.message != now.message;
}
```


================================================
FILE: docs/zh-cn/concept/static-flow-adapter.md
================================================
# StaticFlowAdapter

-   模版是一个 Array,接受 Object|Map 的数据驱动。
-   模版接收一个 Dependent 的数组,每一个 Dependent 可以是 Component 或者 Adapter + Connector<T,P> 的组合。
-   抽象地看,它非常的像是一个 flatMap + compact 的操作。
-   示例代码

```dart
class ItemBodyComponent extends Component<ItemBodyState> {
    ItemBodyComponent()
        : super(
            view: buildItemBody,
            dependencies: Dependencies<ItemBodyState>(
            adapter: StaticFlowAdapter<ItemBodyState>(
                slots: <Dependent<ItemBodyState>>[
                    VideoAdapter().asDependent(videoConnector()),
                    UserInfoComponent().asDependent(userInfoConnector()),
                    DescComponent().asDependent(descConnector()),
                    ItemImageComponent().asDependent(itemImageConnector()),
                    OriginDescComponent().asDependent(originDescConnector()),
                    VisitComponent().asDependent(visitConnector()),
                    SameMoreComponent().asDependent(sameMoreConnector()),
                    PondComponent().asDependent(pondConnector()),
                    CommentAdapter().asDependent(commentConnector()),
                    RecommendAdapter().asDependent(recommendConnector()),
                    PaddingComponent().asDependent(paddingConnector()),
                ]),
            ),
        );
}

```

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">


================================================
FILE: docs/zh-cn/concept/view.md
================================================
# View

-   View 是一个输出 Widget 的上下文无关的函数。它接收下面的参数
    -   T state
    -   Dispatch
    -   ViewService
-   它主要包含三方面的信息
    -   视图完全由数据驱动。
    -   视图产生的事件/回调,通过 Dispatch 发出“意图”,但绝不做具体的实现。
    -   使用依赖的组件/适配器,通过在组件上显示配置,再通过 ViewService 标准化调用。
        -   其中 ViewService 提供了三个能力
            -   BuildContext context,获取 flutter Build-Context 的能力
            -   Widget buildView(String name), 直接创建子组件的能力
                -   这里传入的 name 即在 Dependencies 上配置的名称。
                -   创建子组件不需要传入任何其他的参数,因为子组件需要的参数,已经通过 Dependencies 配置中,将它们的数据关系,通过 connector 确立。
            -   ListAdapter buildAdapter(), 直接创建适配器的能力
-   示例代码

```dart
Widget buildMessageView(String message, Dispatch dispatch, ViewService viewService) {
  return Column(children: [
    viewService.buildComponent('profile'),
    InkWell(
      child: Text('$message'),
      onTap: () => dispatch(const Action('onShare')),
    ),
  ]);
}

class MessageComponent extends Component<String> {
    MessageComponent(): super(
            view: buildMessageView,
        );
}
```


================================================
FILE: docs/zh-cn/concept/what's-adapter.md
================================================
# What's adapter

面向 ListView 场景的分治设计 Adapter。

> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更多的局限于它展现部分,而它的逻辑部分往往是集中的。而当我们试图将 ListView 下的某一局部的展现和逻辑封装在一起,我们就会遇到"Big-Cell"问题,面临性能的显著降低。
> 这里面存在一个分治和性能上的矛盾。这个矛盾带来了复用难,可维护差,难以协作等中大型场景下的问题。
>
> 解决这个问题,有两种思路:
>
> 1. 下沉到 UI 表达层(Widgets),去实现一个高性能的 ScrollView。
> 2. 向上做模型抽象,得到一个逻辑上的 ScrollView,性能上的 ListView。
>
> fish redux 选择了第二条更加通用的路径来解决 LisView 下的分治问题。
>
> 一个 ListView 对应了一个 Adapter,这看上去非常的像 Android 里的设计,但事实上 fish-redux 里的 Adapter 概念走的更远。
>
> 1. 一个 Adapter 是可以由多个 Component 和 Adapter 组合而成,它有点像 flatmap & compact 的 api 的叠加。
> 2. Adapter 以及它的子 Adapter 的生命周期是和 ListView 是等效的。它像跨斗一般附着于 ListView 的生命周期之上。同时由于 Adapter 生命周期的提升,我们额外收获了两个非常有用的事件消息(appear & disappear)。
>
> > 注意 ⚠️ 在 Adapter 里配置的子 Component,它的生命周期和它所对应的 WidgetState 是一致的,所以它的是短暂的。

-   Adapter 的容器有两类,用图来说明吧:

<img src="https://img.alicdn.com/tfs/TB1sXXOLQvoK1RjSZPfXXXPKFXa-1666-1104.png" width="833px" height="552px">

<img src="https://img.alicdn.com/tfs/TB10lxHLMDqK1RjSZSyXXaxEVXa-1838-1024.png" width="919px" height="512px">


================================================
FILE: docs/zh-cn/concept/what's-connector.md
================================================
# What's connector

在解答 connector 是什么之前,我们来先看一个代码片段

```javascript
let hasChanged = false;
const nextState = {};
for (let i = 0; i < finalReducerKeys.length; i++) {
	const key = finalReducerKeys[i];
	const reducer = finalReducers[key];
	const previousStateForKey = state[key];
	const nextStateForKey = reducer(previousStateForKey, action);
	if (typeof nextStateForKey === 'undefined') {
		const errorMessage = getUndefinedStateErrorMessage(key, action);
		throw new Error(errorMessage);
	}
	nextState[key] = nextStateForKey;
	hasChanged = hasChanged || nextStateForKey !== previousStateForKey;
}
return hasChanged ? nextState : state;
```

以上来自于 Reduxjs-[combineReducers](https://github.com/reduxjs/redux/blob/master/src/combineReducers.js)的核心实现。

combineReducers 是一个将 Reducer 分治的函数,让一个庞大数据的 Reducer 可以由多层的更小的 Reducer 组合而成。

这是 Redux 框架里的核心 API,但是他有缺点。他有非常明显的语言的局限性,如下 3 点:

1. 浅拷贝一个任意对象

```javascript
const nextState = {};
```

2. 读取字段

```javascript
const previousStateForKey = state[key];
```

3. 写入字段

```javascript
nextState[key] = nextStateForKey;
```

将上面的 3 点抽象来看:

1. State 的 clone 的能力(浅拷贝)
2. Get & Set 的能力,即为 Connector 的概念。

有了 以上两点,我们才完全集成了 Redux 的所有精华,同时将它的设计更上一个通用的维度。


================================================
FILE: docs/zh-cn/concept/what's-the-diiference.md
================================================
# What's different with Redux ?

## 它们是解决不同层面问题的两个框架

> Redux 是一个专注于状态管理的框架;Fish Redux 是基于 Redux 做状态管理的应用框架。

> 应用框架不仅仅要解决状态管理的问题,还要解决分治,通信,数据驱动,解耦等等问题。

## Fish Redux 解决了集中和分治的矛盾。

> Redux 通过使用者手动组织代码的形式来完成从小的 Reducer 到主 Reducer 的合并过程;

> Fish Redux 通过显式的表达组件之间的依赖关系,由框架自动完成从细力度的 Reducer 到主 Reducer 的合并过程;

<img src="https://img.alicdn.com/tfs/TB1oeXKJYPpK1RjSZFFXXa5PpXa-1976-568.png" width="988px" height="284px">

## Fish Redux 提供了一个简单的组件抽象模型

> 它通过简单的 3 个函数组合而成

<img src="https://img.alicdn.com/tfs/TB1vqB2J4YaK1RjSZFnXXa80pXa-900-780.png" width="450px" height="390px">

## Fish Redux 提供了一个 Adapter 的抽象组件模型

> 在基础的组件模型以外,Fish Redux 提供了一个 Adapter 抽象模型,用来解决在 ListView 上大 Cell 的性能问题。

> 通过上层抽象,我们得到了逻辑上的 ScrollView,性能上的 ListView。

<img src="https://img.alicdn.com/tfs/TB1x51VJ7PoK1RjSZKbXXX1IXXa-1852-612.png" width="617px" height="204px">


================================================
FILE: docs/zh-cn/concept/widget-wrapper.md
================================================
### WidgetWrapper

-   它用来解决 flutter 的 ui 体系下,一些需要实现特色接口的 Widget,比如 KeepAlive,因为通过 Component 产生的 Widget 会被一个框架内部的 Stateful 的 Widget 所包裹。
-   示例代码

```dart
import 'package:flutter/material.dart' hide Action;

Widget repaintBoundaryWrapper(Widget widget) {
  return RepaintBoundary(child: widget);
}
```


================================================
FILE: example/.flutter-plugins-dependencies
================================================
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"path_provider","path":"/Users/linyunhe/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"android":[{"name":"path_provider","path":"/Users/linyunhe/.pub-cache/hosted/pub.dartlang.org/path_provider-0.4.1/","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"path_provider","dependencies":[]}],"date_created":"2021-06-08 17:37:57.339650","version":"1.22.6-xianyu"}

================================================
FILE: example/.gitignore
================================================
# Miscellaneous
*.class
*.lock
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# Visual Studio Code related
.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
build/

# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java

# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*

# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages


================================================
FILE: example/.metadata
================================================
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.

version:
  revision: 5391447fae6209bb21a89e6a5a6583cac1af9b4b
  channel: stable

project_type: app


================================================
FILE: example/README.md
================================================
# sample

A new Flutter project.

## Getting Started

This project is a starting point for a Flutter application.

A few resources to get you started if this is your first Flutter project:

- [Lab: Write your first Flutter app](https://flutter.io/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.io/docs/cookbook)

For help getting started with Flutter, view our 
[online documentation](https://flutter.io/docs), which offers tutorials, 
samples, guidance on mobile development, and a full API reference.


================================================
FILE: example/lib/app.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import 'global_store/state.dart';
import 'global_store/store.dart';
import 'todo_edit_page/page.dart';
import 'todo_list_page/page.dart';

/// 创建应用的根 Widget
/// 1. 创建一个简单的路由,并注册页面
/// 2. 对所需的页面进行和 AppStore 的连接
/// 3. 对所需的页面进行 AOP 的增强
Widget createApp() {
  final AbstractRoutes routes = PageRoutes(
    pages: <String, Page<Object, dynamic>>{
      /// 注册TodoList主页面
      'todo_list': ToDoListPage(),

      /// 注册Todo编辑页面
      'todo_edit': TodoEditPage(),
    },
    visitor: (String path, Page<Object, dynamic> page) {
      /// 只有特定的范围的 Page 才需要建立和 AppStore 的连接关系
      /// 满足 Page<T> ,T 是 GlobalBaseState 的子类
      if (page.isTypeof<GlobalBaseState>()) {
        /// 建立 AppStore 驱动 PageStore 的单向数据连接
        /// 1. 参数1 AppStore
        /// 2. 参数2 当 AppStore.state 变化时, PageStore.state 该如何变化
        page.connectExtraStore<GlobalState>(GlobalStore.store,
            (Object pagestate, GlobalState appState) {
          final GlobalBaseState p = pagestate;
          if (p.themeColor != appState.themeColor) {
            if (pagestate is Cloneable) {
              final Object copy = pagestate.clone();
              final GlobalBaseState newState = copy;
              newState.themeColor = appState.themeColor;
              return newState;
            }
          }
          return pagestate;
        });
      }

      /// AOP
      /// 页面可以有一些私有的 AOP 的增强, 但往往会有一些 AOP 是整个应用下,所有页面都会有的。
      /// 这些公共的通用 AOP ,通过遍历路由页面的形式统一加入。
      page.enhancer.append(
        /// View AOP
        viewMiddleware: <ViewMiddleware<dynamic>>[
          safetyView<dynamic>(),
        ],

        /// Adapter AOP
        adapterMiddleware: <AdapterMiddleware<dynamic>>[
          safetyAdapter<dynamic>()
        ],

        /// Effect AOP
        effectMiddleware: <EffectMiddleware<dynamic>>[
          _pageAnalyticsMiddleware<dynamic>(),
        ],

        /// Store AOP
        middleware: <Middleware<dynamic>>[
          logMiddleware<dynamic>(tag: page.runtimeType.toString()),
        ],
      );
    },
  );

  return MaterialApp(
    title: 'Fluro',
    debugShowCheckedModeBanner: false,
    theme: ThemeData(
      primarySwatch: Colors.blue,
    ),
    home: routes.buildPage('todo_list', null),
    onGenerateRoute: (RouteSettings settings) {
      return MaterialPageRoute<Object>(builder: (BuildContext context) {
        return routes.buildPage(settings.name, settings.arguments);
      });
    },
  );
}

/// 简单的 Effect AOP
/// 只针对页面的生命周期进行打印
EffectMiddleware<T> _pageAnalyticsMiddleware<T>({String tag = 'redux'}) {
  return (AbstractLogic<dynamic> logic, Store<T> store) {
    return (Effect<dynamic> effect) {
      return (Action action, Context<dynamic> ctx) {
        if (logic is Page<dynamic, dynamic> && action.type is Lifecycle) {
          print('${logic.runtimeType} ${action.type.toString()} ');
        }
        return effect?.call(action, ctx);
      };
    };
  };
}


================================================
FILE: example/lib/global_store/action.dart
================================================
import 'package:fish_redux/fish_redux.dart';

enum GlobalAction { changeThemeColor }

class GlobalActionCreator {
  static Action onchangeThemeColor() {
    return const Action(GlobalAction.changeThemeColor);
  }
}


================================================
FILE: example/lib/global_store/reducer.dart
================================================
import 'dart:ui';

import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import 'action.dart';
import 'state.dart';

Reducer<GlobalState> buildReducer() {
  return asReducer(
    <Object, Reducer<GlobalState>>{
      GlobalAction.changeThemeColor: _onchangeThemeColor,
    },
  );
}

List<Color> _colors = <Color>[
  Colors.green,
  Colors.red,
  Colors.black,
  Colors.blue
];

GlobalState _onchangeThemeColor(GlobalState state, Action action) {
  final Color next =
      _colors[((_colors.indexOf(state.themeColor) + 1) % _colors.length)];
  return state.clone()..themeColor = next;
}


================================================
FILE: example/lib/global_store/state.dart
================================================
import 'dart:ui';

import 'package:fish_redux/fish_redux.dart';

abstract class GlobalBaseState {
  Color get themeColor;
  set themeColor(Color color);
}

class GlobalState implements GlobalBaseState, Cloneable<GlobalState> {
  @override
  Color themeColor;

  @override
  GlobalState clone() {
    return GlobalState();
  }
}


================================================
FILE: example/lib/global_store/store.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'reducer.dart';
import 'state.dart';

/// 建立一个AppStore
/// 目前它的功能只有切换主题
class GlobalStore {
  static Store<GlobalState> _globalStore;

  static Store<GlobalState> get store =>
      _globalStore ??= createStore<GlobalState>(GlobalState(), buildReducer());
}


================================================
FILE: example/lib/main.dart
================================================
import 'package:flutter/material.dart' hide Action, Page;

import 'app.dart';

void main() => runApp(createApp());


================================================
FILE: example/lib/todo_edit_page/action.dart
================================================
import 'package:fish_redux/fish_redux.dart';

enum ToDoEditAction { onDone, onChangeTheme }

class ToDoEditActionCreator {
  static Action onDone() {
    return const Action(ToDoEditAction.onDone);
  }

  static Action onChangeTheme() {
    return const Action(ToDoEditAction.onChangeTheme);
  }
}


================================================
FILE: example/lib/todo_edit_page/effect.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import '../global_store/action.dart';
import '../global_store/store.dart';
import '../todo_list_page/todo_component/component.dart';
import 'action.dart';
import 'state.dart';

Effect<TodoEditState> buildEffect() {
  return combineEffects(<Object, Effect<TodoEditState>>{
    ToDoEditAction.onDone: _onDone,
    ToDoEditAction.onChangeTheme: _onChangeTheme,
  });
}

void _onDone(Action action, Context<TodoEditState> ctx) {
  Navigator.of(ctx.context).pop<ToDoState>(
    ctx.state.toDo.clone()
      ..desc = ctx.state.descEditController.text
      ..title = ctx.state.nameEditController.text,
  );
}

void _onChangeTheme(Action action, Context<TodoEditState> ctx) {
  GlobalStore.store.dispatch(GlobalActionCreator.onchangeThemeColor());
}


================================================
FILE: example/lib/todo_edit_page/page.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../todo_list_page/todo_component/component.dart';
import 'effect.dart';
import 'state.dart';
import 'view.dart';

class TodoEditPage extends Page<TodoEditState, ToDoState> {
  TodoEditPage()
      : super(
          initState: initState,
          effect: buildEffect(),
          view: buildView,

          /// 页面私有AOP,如果需要
          // middleware: <Middleware<TodoEditState>>[
          //   logMiddleware(tag: 'TodoEditPage'),
          // ],
        );
}


================================================
FILE: example/lib/todo_edit_page/state.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import '../global_store/state.dart';
import '../todo_list_page/todo_component/component.dart';

class TodoEditState implements GlobalBaseState, Cloneable<TodoEditState> {
  ToDoState toDo;

  TextEditingController nameEditController;
  TextEditingController descEditController;

  FocusNode focusNodeName;
  FocusNode focusNodeDesc;

  @override
  Color themeColor;

  @override
  TodoEditState clone() {
    return TodoEditState()
      ..nameEditController = nameEditController
      ..descEditController = descEditController
      ..focusNodeName = focusNodeName
      ..focusNodeDesc = focusNodeDesc
      ..toDo = toDo
      ..themeColor = themeColor;
  }
}

TodoEditState initState(ToDoState arg) {
  final TodoEditState state = TodoEditState();
  state.toDo = arg?.clone() ?? ToDoState();
  state.nameEditController = TextEditingController(text: arg?.title);
  state.descEditController = TextEditingController(text: arg?.desc);
  state.focusNodeName = FocusNode();
  state.focusNodeDesc = FocusNode();

  return state;
}


================================================
FILE: example/lib/todo_edit_page/view.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import 'action.dart';
import 'state.dart';

Widget buildView(
    TodoEditState state, Dispatch dispatch, ViewService viewService) {
  return Scaffold(
    appBar: AppBar(
      backgroundColor: state.themeColor,
      title: const Text('Todo'),
    ),
    body: Container(
      padding: const EdgeInsets.all(16.0),
      child: Column(
        children: <Widget>[
          Container(
            child: Row(
              children: <Widget>[
                Container(
                  child: const Text('title:',
                      style: TextStyle(color: Colors.black, fontSize: 20.0)),
                  width: 56.0,
                  alignment: AlignmentDirectional.topEnd,
                ),
                Expanded(
                    child: Container(
                  color: const Color(0xFFE0E0E0),
                  padding: const EdgeInsets.all(8.0),
                  margin: const EdgeInsets.only(left: 8.0),
                  child: EditableText(
                    controller: state.nameEditController,
                    focusNode: state.focusNodeName,
                    autofocus: true,
                    style: const TextStyle(color: Colors.black, fontSize: 16.0),
                    cursorColor: Colors.yellow,
                    backgroundCursorColor: const Color(0xFFFFF59D),
                  ),
                ))
              ],
            ),
          ),
          RaisedButton(
              padding: const EdgeInsets.only(
                  left: 20.0, top: 10.0, right: 20.0, bottom: 10.0),
              color: Colors.blue,
              child: const Text('Change theme',
                  style: TextStyle(fontSize: 18),
                  overflow: TextOverflow.ellipsis),
              onPressed: () {
                dispatch(ToDoEditActionCreator.onChangeTheme());
              }),
          Expanded(
              child: Container(
            margin: const EdgeInsets.only(top: 32.0),
            alignment: AlignmentDirectional.topStart,
            child: Row(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: <Widget>[
                Container(
                  child: const Text('desc:',
                      style: TextStyle(color: Colors.black, fontSize: 20.0)),
                  width: 56.0,
                  alignment: AlignmentDirectional.topEnd,
                ),
                Expanded(
                    child: Container(
                  color: const Color(0xFFE0E0E0),
                  padding: const EdgeInsets.all(8.0),
                  margin: const EdgeInsets.only(left: 8.0),
                  child: EditableText(
                      controller: state.descEditController,
                      backgroundCursorColor: const Color(0xFFE0E0E0),
                      maxLines: 10,
                      focusNode: state.focusNodeDesc,
                      style:
                          const TextStyle(color: Colors.black, fontSize: 16.0),
                      cursorColor: Colors.yellow),
                ))
              ],
            ),
          ))
        ],
      ),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: () => dispatch(ToDoEditActionCreator.onDone()),
      tooltip: 'Done',
      child: const Icon(Icons.done),
    ),
    floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
  );
}


================================================
FILE: example/lib/todo_list_page/action.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'todo_component/component.dart';

enum PageAction { initToDos, onAdd }

class PageActionCreator {
  static Action initToDosAction(List<ToDoState> toDos) {
    return Action(PageAction.initToDos, payload: toDos);
  }

  static Action onAddAction() {
    return const Action(PageAction.onAdd);
  }
}


================================================
FILE: example/lib/todo_list_page/effect.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import 'action.dart';
import 'list_adapter/action.dart' as list_action;
import 'state.dart';
import 'todo_component/component.dart';

Effect<PageState> buildEffect() {
  return combineEffects(<Object, Effect<PageState>>{
    Lifecycle.initState: _init,
    PageAction.onAdd: _onAdd,
  });
}

void _init(Action action, Context<PageState> ctx) {
  final List<ToDoState> initToDos = <ToDoState>[
    ToDoState(
      uniqueId: '0',
      title: 'Hello world',
      desc: 'Learn how to program.',
      isDone: true,
    ),
    ToDoState(
      uniqueId: '1',
      title: 'Hello Flutter',
      desc: 'Learn how to build a flutter application.',
      isDone: true,
    ),
    ToDoState(
      uniqueId: '2',
      title: 'How Fish Redux',
      desc: 'Learn how to use Fish Redux in a flutter application.',
      isDone: false,
    )
  ];

  ctx.dispatch(PageActionCreator.initToDosAction(initToDos));
}

void _onAdd(Action action, Context<PageState> ctx) {
  Navigator.of(ctx.context)
      .pushNamed('todo_edit', arguments: null)
      .then((dynamic toDo) {
    if (toDo != null &&
        (toDo.title?.isNotEmpty == true || toDo.desc?.isNotEmpty == true)) {
      ctx.dispatch(list_action.ToDoListActionCreator.add(toDo));
    }
  });
}


================================================
FILE: example/lib/todo_list_page/flow_adapter/adapter.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';
import 'reducer.dart';
import 'connector.dart';

FlowAdapter<PageState> get adapter =>
    FlowAdapter<PageState>(
      reducer: buildReducer(),
        view: (PageState state) =>
            DependentArray<PageState>(
              length: state.itemCount,
              builder: (int index) {
                return ToDoConnector(index: index) + ToDoComponent();
              },
            ));


================================================
FILE: example/lib/todo_list_page/flow_adapter/connector.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';

class ToDoConnector
    extends ConnOp<PageState, ToDoState> {

      ToDoConnector({this.index});

      final int index;

  @override
  ToDoState get(PageState state) {
    if (index >= state.toDos.length) {
      return null;
    }
    return state.toDos[index];
  }

  @override
  void set(PageState state, ToDoState subState) {
    state.toDos[index] = subState;
  }
}

================================================
FILE: example/lib/todo_list_page/flow_adapter/reducer.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../list_adapter/action.dart';
import '../state.dart';
import '../todo_component/action.dart' as todo_action;
import '../todo_component/component.dart';

Reducer<PageState> buildReducer() {
  return asReducer(<Object, Reducer<PageState>>{
    ToDoListAction.add: _add,
    todo_action.ToDoAction.remove: _remove
  });
}

PageState _add(PageState state, Action action) {
  final ToDoState toDo = action.payload;
  return state.clone()..toDos = (state.toDos.toList()..add(toDo));
}

PageState _remove(PageState state, Action action) {
  final String unique = action.payload;
  return state.clone()
    ..toDos = (state.toDos.toList()
      ..removeWhere((ToDoState state) => state.uniqueId == unique));
}


================================================
FILE: example/lib/todo_list_page/list_adapter/action.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import '../todo_component/component.dart';

enum ToDoListAction { add }

class ToDoListActionCreator {
  static Action add(ToDoState state) {
    return Action(ToDoListAction.add, payload: state);
  }
}


================================================
FILE: example/lib/todo_list_page/list_adapter/adapter.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/component.dart';
import 'reducer.dart';

class ToDoListAdapter extends SourceFlowAdapter<PageState> {
  ToDoListAdapter()
      : super(
          pool: <String, Component<Object>>{
            'toDo': ToDoComponent(),
          },
          reducer: buildReducer(),
        );
}


================================================
FILE: example/lib/todo_list_page/list_adapter/reducer.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import '../state.dart';
import '../todo_component/action.dart' as todo_action;
import '../todo_component/component.dart';
import 'action.dart';

Reducer<PageState> buildReducer() {
  return asReducer(<Object, Reducer<PageState>>{
    ToDoListAction.add: _add,
    todo_action.ToDoAction.remove: _remove
  });
}

PageState _add(PageState state, Action action) {
  final ToDoState toDo = action.payload;
  return state.clone()..toDos = (state.toDos.toList()..add(toDo));
}

PageState _remove(PageState state, Action action) {
  final String unique = action.payload;
  return state.clone()
    ..toDos = (state.toDos.toList()
      ..removeWhere((ToDoState state) => state.uniqueId == unique));
}


================================================
FILE: example/lib/todo_list_page/page.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import 'effect.dart';
import 'list_adapter/adapter.dart';
import 'flow_adapter/adapter.dart';
import 'reducer.dart';
import 'report_component/component.dart';
import 'state.dart';

import 'view.dart';

class ToDoListPage extends Page<PageState, Map<String, dynamic>> {
  ToDoListPage()
      : super(
          initState: initState,
          effect: buildEffect(),
          reducer: buildReducer(),
          view: buildView,
          dependencies: Dependencies<PageState>(
              adapter: const NoneConn<PageState>() + adapter,//NoneConn<PageState>() + ToDoListAdapter(),
              slots: <String, Dependent<PageState>>{
                'report': ReportConnector() + ReportComponent()
              }),

          /// 页面私有AOP, 如果需要
          // middleware: <Middleware<PageState>>[
          //   logMiddleware(tag: 'ToDoListPage'),
          // ],
        );
}


================================================
FILE: example/lib/todo_list_page/reducer.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import 'action.dart';
import 'state.dart';
import 'todo_component/component.dart';

Reducer<PageState> buildReducer() {
  return asReducer(
    <Object, Reducer<PageState>>{PageAction.initToDos: _initToDosReducer},
  );
}

PageState _initToDosReducer(PageState state, Action action) {
  final List<ToDoState> toDos = action.payload ?? <ToDoState>[];
  final PageState newState = state.clone();
  newState.toDos = toDos;
  return newState;
}


================================================
FILE: example/lib/todo_list_page/report_component/component.dart
================================================
import 'package:fish_redux/fish_redux.dart';

import 'state.dart';
import 'view.dart';

export 'state.dart';

class ReportComponent extends Component<ReportState> {
  ReportComponent()
      : super(
          view: buildView,
        );
}


================================================
FILE: example/lib/todo_list_page/report_component/state.dart
================================================
import 'package:fish_redux/fish_redux.dart';

class ReportState implements Cloneable<ReportState> {
  int total;
  int done;

  ReportState({this.total = 0, this.done = 0});

  @override
  ReportState clone() {
    return ReportState()
      ..total = total
      ..done = done;
  }

  @override
  String toString() {
    return 'ReportState{total: $total, done: $done}';
  }
}


================================================
FILE: example/lib/todo_list_page/report_component/view.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'package:flutter/material.dart' hide Action, Page;

import 'state.dart';

Widget buildView(
  ReportState state,
  Dispatch dispatch,
  ViewService viewService,
) {
  return Container(
      margin: const EdgeInsets.all(8.0),
      padding: const EdgeInsets.all(8.0),
      color: Colors.blue,
      child: Row(
        children: <Widget>[
          Container(
            child: const Icon(Icons.report),
            margin: const EdgeInsets.only(right: 8.0),
          ),
          Text(
            'Total ${state.total} tasks, ${state.done} done.',
            style: const TextStyle(fontSize: 18.0, color: Colors.white),
          )
        ],
      ));
}


================================================
FILE: example/lib/todo_list_page/state.dart
================================================
import 'dart:ui';

import 'package:fish_redux/fish_redux.dart';
import '../global_store/state.dart';
import 'report_component/component.dart';
import 'todo_component/component.dart';

class PageState extends ItemListLike
    implements GlobalBaseState, Cloneable<PageState> {
  List<ToDoState> toDos;

  @override
  Color themeColor;

  @override
  PageState clone() {
    return PageState()
      ..toDos = toDos
      ..themeColor = themeColor;
  }

  @override
  Object getItemData(int index) => toDos[index];

  @override
  String getItemType(int index) => 'toDo';

  @override
  int get itemCount => toDos?.length ?? 0;

  @override
  ItemListLike updateItemData(int index, Object data, bool isStateCopied) {
    toDos[index] = data;
    return this;
  }
}

PageState initState(Map<String, dynamic> args) {
  //just demo, do nothing here...
  return PageState();
}

class ReportConnector extends ConnOp<PageState, ReportState>
    with ReselectMixin<PageState, ReportState> {
  @override
  ReportState computed(PageState state) {
    return ReportState()
      ..done = state.toDos.where((ToDoState tds) => tds.isDone).length
      ..total = state.toDos.length;
  }

  @override
  List<dynamic> factors(PageState state) {
    return <int>[
      state.toDos.where((ToDoState tds) => tds.isDone).length,
      state.toDos.length
    ];
  }

  @override
  void set(PageState state, ReportState subState) {
    throw Exception('Unexcepted to set PageState from ReportState');
  }
}


================================================
FILE: example/lib/todo_list_page/todo_component/action.dart
================================================
import 'package:fish_redux/fish_redux.dart';
import 'state.dart';

enum ToDoAction { onEdit, edit, done, onRemove, remove }

class ToDoActionCreator {
  static Action onEditAction(String uniqueId) {
    return Action(ToDoAction.onEdit, payload: uniqueId);
  }

  static Action editAction(ToDoState toDo) {
    return Action(ToDoAction.edit, payload: toDo);
  }

  static Action doneAction(String uniqueId) {
    return Action(ToDoAction.done, payload: uniqueId);
  }

  static Action onRemoveAction(String uniqueId) {
    return Action(ToDoAction.onRemove, payload: uniqueId);
  }

  static Action removeAction(String uniqueId) {
    return Action(ToDoAction.remove, payload: uniqueId);
  }
}


================================================
FILE: example/lib/todo_list_page/todo_component/component.dart
================
Download .txt
gitextract_al9_2a3r/

├── .github/
│   └── ISSUE_TEMPLATE/
│       ├── bug_report.md
│       ├── custom.md
│       └── feature_request.md
├── .gitignore
├── .metadata
├── .travis.yml
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── doc/
│   ├── README-cn.md
│   ├── README.md
│   ├── concept/
│   │   ├── action-cn.md
│   │   ├── action.md
│   │   ├── adapter-cn.md
│   │   ├── adapter.md
│   │   ├── auto-dispose-cn.md
│   │   ├── auto-dispose.md
│   │   ├── component-cn.md
│   │   ├── component.md
│   │   ├── connector-cn.md
│   │   ├── connector.md
│   │   ├── custom-adapter-cn.md
│   │   ├── custom-adapter.md
│   │   ├── dependencies-cn.md
│   │   ├── dependencies.md
│   │   ├── dependent-cn.md
│   │   ├── dependent.md
│   │   ├── directory-cn.md
│   │   ├── directory.md
│   │   ├── dynamic-flow-adapter-cn.md
│   │   ├── dynamic-flow-adapter.md
│   │   ├── effect-cn.md
│   │   ├── effect.md
│   │   ├── evolution-of-fish-redux.md
│   │   ├── features.md
│   │   ├── filter-cn.md
│   │   ├── filter.md
│   │   ├── higher-effect-cn.md
│   │   ├── higher-effect.md
│   │   ├── lifecycle-cn.md
│   │   ├── lifecycle.md
│   │   ├── mechanism-cn.md
│   │   ├── mechanism.md
│   │   ├── middleware-cn.md
│   │   ├── middleware.md
│   │   ├── on-error-cn.md
│   │   ├── on-error.md
│   │   ├── oop-cn.md
│   │   ├── oop.md
│   │   ├── page-cn.md
│   │   ├── page.md
│   │   ├── reducer-cn.md
│   │   ├── reducer.md
│   │   ├── redux-cn.md
│   │   ├── redux.md
│   │   ├── should-update-cn.md
│   │   ├── should-update.md
│   │   ├── static-flow-adapter-cn.md
│   │   ├── static-flow-adapter.md
│   │   ├── view-cn.md
│   │   ├── view.md
│   │   ├── what's-adapter.md
│   │   ├── what's-connector.md
│   │   ├── what's-the-diiference-cn.md
│   │   ├── what's-the-diiference.md
│   │   ├── widget-wrapper-cn.md
│   │   └── widget-wrapper.md
│   └── introduction/
│       ├── README-cn.md
│       └── README.md
├── docs/
│   ├── .nojekyll
│   ├── README.md
│   ├── _navbar.md
│   ├── _sidebar.md
│   ├── concept/
│   │   ├── _navbar.md
│   │   ├── _sidebar.md
│   │   ├── action.md
│   │   ├── adapter.md
│   │   ├── auto-dispose.md
│   │   ├── component.md
│   │   ├── connector.md
│   │   ├── custom-adapter.md
│   │   ├── dependencies.md
│   │   ├── dependent.md
│   │   ├── directory.md
│   │   ├── dynamic-flow-adapter.md
│   │   ├── effect.md
│   │   ├── evolution-of-fish-redux.md
│   │   ├── features.md
│   │   ├── filter.md
│   │   ├── higher-effect.md
│   │   ├── lifecycle.md
│   │   ├── mechanism.md
│   │   ├── middleware-cn.md
│   │   ├── middleware.md
│   │   ├── on-error.md
│   │   ├── oop.md
│   │   ├── page.md
│   │   ├── reducer.md
│   │   ├── redux.md
│   │   ├── should-update.md
│   │   ├── static-flow-adapter.md
│   │   ├── view.md
│   │   ├── what's-adapter.md
│   │   ├── what's-connector.md
│   │   ├── what's-the-diiference.md
│   │   └── widget-wrapper.md
│   ├── index.html
│   └── zh-cn/
│       ├── README.md
│       ├── _sidebar.md
│       └── concept/
│           ├── _navbar.md
│           ├── _sidebar.md
│           ├── action.md
│           ├── adapter.md
│           ├── auto-dispose.md
│           ├── component.md
│           ├── connector.md
│           ├── custom-adapter.md
│           ├── dependencies.md
│           ├── dependent.md
│           ├── directory.md
│           ├── dynamic-flow-adapter.md
│           ├── effect.md
│           ├── filter.md
│           ├── higher-effect.md
│           ├── lifecycle.md
│           ├── mechanism.md
│           ├── middleware.md
│           ├── on-error.md
│           ├── oop.md
│           ├── page.md
│           ├── reducer.md
│           ├── redux.md
│           ├── should-update.md
│           ├── static-flow-adapter.md
│           ├── view.md
│           ├── what's-adapter.md
│           ├── what's-connector.md
│           ├── what's-the-diiference.md
│           └── widget-wrapper.md
├── example/
│   ├── .flutter-plugins-dependencies
│   ├── .gitignore
│   ├── .metadata
│   ├── README.md
│   ├── lib/
│   │   ├── app.dart
│   │   ├── global_store/
│   │   │   ├── action.dart
│   │   │   ├── reducer.dart
│   │   │   ├── state.dart
│   │   │   └── store.dart
│   │   ├── main.dart
│   │   ├── todo_edit_page/
│   │   │   ├── action.dart
│   │   │   ├── effect.dart
│   │   │   ├── page.dart
│   │   │   ├── state.dart
│   │   │   └── view.dart
│   │   └── todo_list_page/
│   │       ├── action.dart
│   │       ├── effect.dart
│   │       ├── flow_adapter/
│   │       │   ├── adapter.dart
│   │       │   ├── connector.dart
│   │       │   └── reducer.dart
│   │       ├── list_adapter/
│   │       │   ├── action.dart
│   │       │   ├── adapter.dart
│   │       │   └── reducer.dart
│   │       ├── page.dart
│   │       ├── reducer.dart
│   │       ├── report_component/
│   │       │   ├── component.dart
│   │       │   ├── state.dart
│   │       │   └── view.dart
│   │       ├── state.dart
│   │       ├── todo_component/
│   │       │   ├── action.dart
│   │       │   ├── component.dart
│   │       │   ├── effect.dart
│   │       │   ├── reducer.dart
│   │       │   ├── state.dart
│   │       │   └── view.dart
│   │       └── view.dart
│   ├── pubspec.yaml
│   ├── test/
│   │   └── widget_test.dart
│   └── web/
│       ├── index.html
│       └── manifest.json
├── fish_redux.iml
├── lib/
│   ├── fish_redux.dart
│   └── src/
│       ├── extensions/
│       │   ├── adapter_extensions.dart
│       │   ├── component_extensions.dart
│       │   ├── connector_extensions.dart
│       │   └── extendsions.dart
│       ├── redux/
│       │   ├── apply_middleware.dart
│       │   ├── basic.dart
│       │   ├── combine_reducers.dart
│       │   ├── connector.dart
│       │   ├── create_store.dart
│       │   └── redux.dart
│       ├── redux_adapter/
│       │   ├── adapter.dart
│       │   ├── dynamic_flow_adapter.dart
│       │   ├── flow_adapter.dart
│       │   ├── recycle_context.dart
│       │   ├── redux_adapter.dart
│       │   ├── source_flow_adapter.dart
│       │   └── static_flow_adapter.dart
│       ├── redux_aop/
│       │   ├── aop.dart
│       │   ├── common_aop/
│       │   │   ├── common_aop.dart
│       │   │   ├── debounce.dart
│       │   │   ├── debug.dart
│       │   │   ├── delay.dart
│       │   │   ├── log.dart
│       │   │   ├── memoize.dart
│       │   │   ├── performance.dart
│       │   │   ├── throttle.dart
│       │   │   └── wait_until.dart
│       │   └── redux_aop.dart
│       ├── redux_component/
│       │   ├── auto_dispose.dart
│       │   ├── basic.dart
│       │   ├── batch_store.dart
│       │   ├── component.dart
│       │   ├── context.dart
│       │   ├── dependencies.dart
│       │   ├── dependent.dart
│       │   ├── dispatch_bus.dart
│       │   ├── enhancer.dart
│       │   ├── helper.dart
│       │   ├── lifecycle.dart
│       │   ├── local.dart
│       │   ├── logic.dart
│       │   ├── page.dart
│       │   └── redux_component.dart
│       ├── redux_component_mixin/
│       │   ├── keep_alive_mixin.dart
│       │   ├── private_reducer_mixin.dart
│       │   ├── redux_component_mixin.dart
│       │   ├── single_ticker_provider_mixin.dart
│       │   ├── ticker_provider_mixin.dart
│       │   ├── visible_change_mixin.dart
│       │   └── widgets_binding_observer_mixin.dart
│       ├── redux_connector/
│       │   ├── connector.dart
│       │   ├── generator.dart
│       │   ├── helper.dart
│       │   ├── map_like.dart
│       │   ├── none.dart
│       │   ├── op_mixin.dart
│       │   ├── redux_connector.dart
│       │   └── reselect.dart
│       ├── redux_middleware/
│       │   ├── adapter_middleware/
│       │   │   ├── adapter_middleware.dart
│       │   │   └── safety_adapter.dart
│       │   ├── middleware/
│       │   │   ├── log.dart
│       │   │   ├── middleware.dart
│       │   │   └── performance.dart
│       │   ├── redux_middleware.dart
│       │   └── view_middleware/
│       │       ├── safety_view.dart
│       │       └── view_middleware.dart
│       ├── redux_routes/
│       │   ├── page_routes.dart
│       │   └── redux_routes.dart
│       └── utils/
│           ├── collections.dart
│           ├── debug.dart
│           ├── hash.dart
│           ├── tuple.dart
│           └── utils.dart
├── pubspec.yaml
└── test/
    ├── lib/
    │   ├── all_test.dart
    │   ├── instrument.dart
    │   ├── redux/
    │   │   ├── redux_test.dart
    │   │   └── store_test.dart
    │   ├── redux_adapter/
    │   │   ├── adapter_test.dart
    │   │   ├── dynamic_adapter_test.dart
    │   │   ├── redux_adapter_test.dart
    │   │   ├── source_adapter_test.dart
    │   │   └── static_flow_adapter_test.dart
    │   ├── redux_aop/
    │   │   ├── memoize_test.dart
    │   │   └── redux_aop_test.dart
    │   ├── redux_component/
    │   │   ├── auto_dispose_test.dart
    │   │   ├── component_test.dart
    │   │   ├── lifecycle_test.dart
    │   │   ├── page_test.dart
    │   │   └── redux_component_test.dart
    │   ├── redux_connector/
    │   │   ├── map_like_test.dart
    │   │   ├── redux_connector_test.dart
    │   │   └── reselect_test.dart
    │   ├── redux_middleware/
    │   │   └── redux_middleware_test.dart
    │   ├── redux_routes/
    │   │   └── redux_routes_test.dart
    │   ├── track.dart
    │   └── utils/
    │       ├── collections_test.dart
    │       └── utils_test.dart
    ├── pubspec.yaml
    └── test_widgets/
        ├── .gitignore
        ├── lib/
        │   ├── adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── component/
        │   │   ├── action.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── dynamic_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── component.dart
        │   │   ├── dynamic_flow_adapter.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── main.dart
        │   ├── page/
        │   │   ├── action.dart
        │   │   ├── exception.dart
        │   │   ├── page.dart
        │   │   └── state.dart
        │   ├── source_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── adapter.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   ├── source_flow_adapter.dart
        │   │   └── state.dart
        │   ├── static_flow_adapter/
        │   │   ├── action.dart
        │   │   ├── component.dart
        │   │   ├── page.dart
        │   │   ├── state.dart
        │   │   └── static_flow_adapter.dart
        │   └── test_base.dart
        └── pubspec.yaml
Download .txt
SYMBOL INDEX (833 symbols across 145 files)

FILE: example/lib/app.dart
  function createApp (line 13) | Widget createApp()
  function _pageAnalyticsMiddleware (line 88) | EffectMiddleware<T> _pageAnalyticsMiddleware<T>({String tag = 'redux'})

FILE: example/lib/global_store/action.dart
  type GlobalAction (line 3) | enum GlobalAction { changeThemeColor }
  class GlobalActionCreator (line 5) | class GlobalActionCreator {
    method onchangeThemeColor (line 6) | Action onchangeThemeColor()

FILE: example/lib/global_store/reducer.dart
  function buildReducer (line 9) | Reducer<GlobalState> buildReducer()
  function _onchangeThemeColor (line 24) | GlobalState _onchangeThemeColor(GlobalState state, Action action)

FILE: example/lib/global_store/state.dart
  class GlobalBaseState (line 5) | abstract class GlobalBaseState {
  class GlobalState (line 10) | class GlobalState implements GlobalBaseState, Cloneable<GlobalState> {
    method clone (line 15) | GlobalState clone()

FILE: example/lib/global_store/store.dart
  class GlobalStore (line 7) | class GlobalStore {

FILE: example/lib/main.dart
  function main (line 5) | void main()

FILE: example/lib/todo_edit_page/action.dart
  type ToDoEditAction (line 3) | enum ToDoEditAction { onDone, onChangeTheme }
  class ToDoEditActionCreator (line 5) | class ToDoEditActionCreator {
    method onDone (line 6) | Action onDone()
    method onChangeTheme (line 10) | Action onChangeTheme()

FILE: example/lib/todo_edit_page/effect.dart
  function buildEffect (line 10) | Effect<TodoEditState> buildEffect()
  function _onDone (line 17) | void _onDone(Action action, Context<TodoEditState> ctx)
  function _onChangeTheme (line 25) | void _onChangeTheme(Action action, Context<TodoEditState> ctx)

FILE: example/lib/todo_edit_page/page.dart
  class TodoEditPage (line 8) | class TodoEditPage extends Page<TodoEditState, ToDoState> {

FILE: example/lib/todo_edit_page/state.dart
  class TodoEditState (line 7) | class TodoEditState implements GlobalBaseState, Cloneable<TodoEditState> {
    method clone (line 20) | TodoEditState clone()
  function initState (line 31) | TodoEditState initState(ToDoState arg)

FILE: example/lib/todo_edit_page/view.dart
  function buildView (line 7) | Widget buildView(

FILE: example/lib/todo_list_page/action.dart
  type PageAction (line 4) | enum PageAction { initToDos, onAdd }
  class PageActionCreator (line 6) | class PageActionCreator {
    method initToDosAction (line 7) | Action initToDosAction(List<ToDoState> toDos)
    method onAddAction (line 11) | Action onAddAction()

FILE: example/lib/todo_list_page/effect.dart
  function buildEffect (line 9) | Effect<PageState> buildEffect()
  function _init (line 16) | void _init(Action action, Context<PageState> ctx)
  function _onAdd (line 41) | void _onAdd(Action action, Context<PageState> ctx)

FILE: example/lib/todo_list_page/flow_adapter/connector.dart
  class ToDoConnector (line 6) | class ToDoConnector
    method get (line 14) | ToDoState get(PageState state)
    method set (line 22) | void set(PageState state, ToDoState subState)

FILE: example/lib/todo_list_page/flow_adapter/reducer.dart
  function buildReducer (line 8) | Reducer<PageState> buildReducer()
  function _add (line 15) | PageState _add(PageState state, Action action)
  function _remove (line 20) | PageState _remove(PageState state, Action action)

FILE: example/lib/todo_list_page/list_adapter/action.dart
  type ToDoListAction (line 4) | enum ToDoListAction { add }
  class ToDoListActionCreator (line 6) | class ToDoListActionCreator {
    method add (line 7) | Action add(ToDoState state)

FILE: example/lib/todo_list_page/list_adapter/adapter.dart
  class ToDoListAdapter (line 7) | class ToDoListAdapter extends SourceFlowAdapter<PageState> {

FILE: example/lib/todo_list_page/list_adapter/reducer.dart
  function buildReducer (line 8) | Reducer<PageState> buildReducer()
  function _add (line 15) | PageState _add(PageState state, Action action)
  function _remove (line 20) | PageState _remove(PageState state, Action action)

FILE: example/lib/todo_list_page/page.dart
  class ToDoListPage (line 12) | class ToDoListPage extends Page<PageState, Map<String, dynamic>> {

FILE: example/lib/todo_list_page/reducer.dart
  function buildReducer (line 7) | Reducer<PageState> buildReducer()
  function _initToDosReducer (line 13) | PageState _initToDosReducer(PageState state, Action action)

FILE: example/lib/todo_list_page/report_component/component.dart
  class ReportComponent (line 8) | class ReportComponent extends Component<ReportState> {

FILE: example/lib/todo_list_page/report_component/state.dart
  class ReportState (line 3) | class ReportState implements Cloneable<ReportState> {
    method clone (line 10) | ReportState clone()
    method toString (line 17) | String toString()

FILE: example/lib/todo_list_page/report_component/view.dart
  function buildView (line 6) | Widget buildView(

FILE: example/lib/todo_list_page/state.dart
  class PageState (line 8) | class PageState extends ItemListLike
    method clone (line 16) | PageState clone()
    method getItemData (line 23) | Object getItemData(int index)
    method getItemType (line 26) | String getItemType(int index)
    method updateItemData (line 32) | ItemListLike updateItemData(int index, Object data, bool isStateCopied)
  function initState (line 38) | PageState initState(Map<String, dynamic> args)
  class ReportConnector (line 43) | class ReportConnector extends ConnOp<PageState, ReportState>
    method computed (line 46) | ReportState computed(PageState state)
    method factors (line 53) | List<dynamic> factors(PageState state)
    method set (line 61) | void set(PageState state, ReportState subState)

FILE: example/lib/todo_list_page/todo_component/action.dart
  type ToDoAction (line 4) | enum ToDoAction { onEdit, edit, done, onRemove, remove }
  class ToDoActionCreator (line 6) | class ToDoActionCreator {
    method onEditAction (line 7) | Action onEditAction(String uniqueId)
    method editAction (line 11) | Action editAction(ToDoState toDo)
    method doneAction (line 15) | Action doneAction(String uniqueId)
    method onRemoveAction (line 19) | Action onRemoveAction(String uniqueId)
    method removeAction (line 23) | Action removeAction(String uniqueId)

FILE: example/lib/todo_list_page/todo_component/component.dart
  class ToDoComponent (line 10) | class ToDoComponent extends Component<ToDoState> {

FILE: example/lib/todo_list_page/todo_component/effect.dart
  function buildEffect (line 7) | Effect<ToDoState> buildEffect()
  function _onEdit (line 14) | void _onEdit(Action action, Context<ToDoState> ctx)
  function _onRemove (line 29) | void _onRemove(Action action, Context<ToDoState> ctx)

FILE: example/lib/todo_list_page/todo_component/reducer.dart
  function buildReducer (line 6) | Reducer<ToDoState> buildReducer()
  function _edit (line 13) | ToDoState _edit(ToDoState state, Action action)
  function _markDone (line 23) | ToDoState _markDone(ToDoState state, Action action)

FILE: example/lib/todo_list_page/todo_component/state.dart
  class ToDoState (line 4) | class ToDoState implements Cloneable<ToDoState> {
    method clone (line 17) | ToDoState clone()
    method toString (line 26) | String toString()

FILE: example/lib/todo_list_page/todo_component/view.dart
  function buildView (line 7) | Widget buildView(

FILE: example/lib/todo_list_page/view.dart
  function buildView (line 7) | Widget buildView(PageState state, Dispatch dispatch, ViewService viewSer...

FILE: example/test/widget_test.dart
  function main (line 10) | void main()

FILE: lib/src/extensions/adapter_extensions.dart
  class SimpleFlowAdapter (line 10) | class SimpleFlowAdapter<T> extends FlowAdapter<T> {
  function _buildByStatic (line 70) | FlowAdapterView<T> _buildByStatic<T>(List<Dependent<T>> children)
  function _buildByListLike (line 78) | FlowAdapterView<T> _buildByListLike<T>({
  function _buildByDynamic (line 102) | FlowAdapterView<T> _buildByDynamic<T>({

FILE: lib/src/extensions/component_extensions.dart
  class SimpleComponent (line 5) | abstract class SimpleComponent<T> extends Component<T> {
    method view (line 34) | Widget view(T state, Dispatch dispatch, ViewService viewService)
    method reducer (line 36) | T reducer(T state, Action action)
    method effect (line 41) | dynamic effect(Action action, Context<T> ctx)

FILE: lib/src/extensions/connector_extensions.dart
  function getByIndex (line 12) | P getByIndex(T state, int index)
  function get (line 15) | P get(T state)
  function checkNextState (line 21) | P checkNextState(Object newState)
  class ImmutableIndexedConn (line 34) | abstract class ImmutableIndexedConn<T, P> extends ImmutableConn<T, P>
    method setByIndex (line 40) | T setByIndex(T state, P subState, int index)
    method set (line 43) | T set(T state, P subState)
  class MutableIndexedConn (line 46) | abstract class MutableIndexedConn<T, P> extends MutableConn<T, P>
    method setByIndex (line 52) | void setByIndex(T state, P subState, int index)
    method set (line 55) | void set(T state, P subState)
  class IndexedListConn (line 59) | class IndexedListConn<P> extends MutableIndexedConn<List<P>, P>
    method getByIndex (line 64) | P getByIndex(List<P> state, int index)
    method setByIndex (line 70) | void setByIndex(List<P> state, Object subState, int index)
  class IndexedListLikeConn (line 75) | class IndexedListLikeConn<T extends MutableItemListLike>
    method getByIndex (line 80) | Object getByIndex(T state, int index)
    method setByIndex (line 86) | void setByIndex(T state, Object subState, int index)

FILE: lib/src/redux/apply_middleware.dart
  function applyMiddleware (line 5) | StoreEnhancer<T> applyMiddleware<T>(List<Middleware<T>> middleware)

FILE: lib/src/redux/basic.dart
  class Action (line 23) | class Action {
  type Reducer (line 31) | typedef Reducer<T> = T Function(T state, Action action);
  type Dispatch (line 35) | typedef Dispatch = dynamic Function(Action action);
  type Subscribe (line 39) | typedef Subscribe = void Function() Function(void Function() callback);
  type ReplaceReducer (line 42) | typedef ReplaceReducer<T> = void Function(Reducer<T> reducer);
  type Observable (line 45) | typedef Observable<T> = Stream<T> Function();
  type Composable (line 48) | typedef Composable<T> = T Function(T next);
  type Get (line 51) | typedef Get<R> = R Function();
  type Middleware (line 54) | typedef Middleware<T> = Composable<Dispatch> Function({
  class Store (line 60) | class Store<T> {
  type StoreCreator (line 70) | typedef StoreCreator<T> = Store<T> Function(
  type StoreEnhancer (line 76) | typedef StoreEnhancer<T> = StoreCreator<T> Function(StoreCreator<T> crea...
  type SubReducer (line 81) | typedef SubReducer<T> = T Function(T state, Action action, bool isStateC...
  class AbstractConnector (line 87) | abstract class AbstractConnector<S, P> {
    method get (line 88) | P get(S state)
    method subReducer (line 100) | SubReducer<S> subReducer(Reducer<P> reducer)

FILE: lib/src/redux/combine_reducers.dart
  function combineSubReducers (line 4) | Reducer<T> combineSubReducers<T>(Iterable<SubReducer<T>> subReducers)
  function combineReducers (line 31) | Reducer<T> combineReducers<T>(Iterable<Reducer<T>> reducers)
  function castReducer (line 53) | Reducer<Sub> castReducer<Sub extends Sup, Sup>(Reducer<Sup> sup)

FILE: lib/src/redux/connector.dart
  class ImmutableConn (line 17) | abstract class ImmutableConn<T, P> implements AbstractConnector<T, P> {
    method set (line 20) | T set(T state, P subState)
    method subReducer (line 23) | SubReducer<T> subReducer(Reducer<P> reducer)
  class Cloneable (line 44) | abstract class Cloneable<T extends Cloneable<T>> {
    method clone (line 45) | T clone()
  function _clone (line 49) | dynamic _clone<T>(T state)
  class MutableConn (line 80) | abstract class MutableConn<T, P> implements AbstractConnector<T, P> {
    method set (line 83) | void set(T state, P subState)
    method subReducer (line 86) | SubReducer<T> subReducer(Reducer<P> reducer)

FILE: lib/src/redux/create_store.dart
  function _noop (line 5) | Reducer<T> _noop<T>()
  type _VoidCallback (line 7) | typedef _VoidCallback = void Function();
  function _throwIfNot (line 9) | void _throwIfNot(bool condition, [String message])
  function _createStore (line 15) | Store<T> _createStore<T>(final T preloadedState, final Reducer<T> reducer)
  function createStore (line 90) | Store<T> createStore<T>(T preloadedState, Reducer<T> reducer,
  function composeStoreEnhancer (line 96) | StoreEnhancer<T> composeStoreEnhancer<T>(List<StoreEnhancer<T>> enhancers)

FILE: lib/src/redux_adapter/adapter.dart
  class Adapter (line 7) | abstract class Adapter<T> extends Logic<T> implements AbstractAdapter<T> {
    method buildAdapter (line 33) | ListAdapter buildAdapter(ContextSys<T> ctx)
    method createContext (line 40) | ContextSys<T> createContext(
  class AdapterContext (line 59) | class AdapterContext<T> extends LogicContext<T> {
    method buildAdapter (line 78) | ListAdapter buildAdapter()

FILE: lib/src/redux_adapter/dynamic_flow_adapter.dart
  class DynamicFlowAdapter (line 12) | @deprecated
    method buildAdapter (line 40) | ListAdapter buildAdapter(ContextSys<T> ctx)
  function _dynamicReducer (line 92) | Reducer<T> _dynamicReducer<T>(
  function _subGetter (line 126) | Get<Object> _subGetter(Get<List<ItemBean>> getter, int index)
  function _couldReuse (line 145) | bool _couldReuse(ItemBean beanA, ItemBean beanB)

FILE: lib/src/redux_adapter/flow_adapter.dart
  class FlowAdapter (line 7) | class FlowAdapter<T> extends Logic<T>
    method buildAdapter (line 33) | ListAdapter buildAdapter(ContextSys<T> ctx)
  type IndexedDependentBuilder (line 84) | typedef IndexedDependentBuilder<T> = Dependent<T> Function(int);
  class DependentArray (line 86) | class DependentArray<T> {
  type FlowAdapterView (line 99) | typedef FlowAdapterView<T> = DependentArray<T> Function(T);
  class FlowDependencies (line 101) | class FlowDependencies<T> {
    method createReducer (line 106) | Reducer<T> createReducer()
  class ItemListLike (line 126) | abstract class ItemListLike {
    method getItemType (line 129) | String getItemType(int index)
    method getItemData (line 131) | Object getItemData(int index)
    method updateItemData (line 133) | ItemListLike updateItemData(int index, Object data, bool isStateCopied)
  class MutableItemListLike (line 136) | abstract class MutableItemListLike extends ItemListLike {
    method updateItemData (line 139) | MutableItemListLike updateItemData(
    method setItemData (line 145) | void setItemData(int index, Object data)
    method clone (line 147) | MutableItemListLike clone()
  class ImmutableItemListLike (line 150) | abstract class ImmutableItemListLike extends ItemListLike {
    method updateItemData (line 153) | ImmutableItemListLike updateItemData(
    method setItemData (line 157) | ImmutableItemListLike setItemData(int index, Object data)
    method clone (line 159) | ImmutableItemListLike clone()
  class ItemBean (line 163) | class ItemBean {
    method clone (line 169) | ItemBean clone({String type, Object data})
  function _memoize (line 174) | R Function(P) _memoize<P, R>(R Function(P) functor)

FILE: lib/src/redux_adapter/recycle_context.dart
  class RecycleContext (line 7) | class RecycleContext<T> extends AdapterContext<T> {
    method onLifecycle (line 29) | void onLifecycle(Action action)
    method markAllUnused (line 39) | void markAllUnused()
    method reuseOrCreate (line 43) | ContextSys<Object> reuseOrCreate(Object key, Get<ContextSys<Object>> c...
    method cleanUnused (line 59) | void cleanUnused()
  function createContext (line 76) | RecycleContext<T> createContext(
  function combineListAdapters (line 96) | ListAdapter combineListAdapters(Iterable<ListAdapter> adapters)
  function memoizeListAdapter (line 133) | ListAdapter memoizeListAdapter(
  function _memoizeListAdapter (line 147) | ListAdapter _memoizeListAdapter(ListAdapter adapter)

FILE: lib/src/redux_adapter/source_flow_adapter.dart
  class SourceFlowAdapter (line 13) | @deprecated
    method buildAdapter (line 40) | ListAdapter buildAdapter(ContextSys<T> ctx)
  function _dynamicReducer (line 92) | Reducer<T> _dynamicReducer<T extends ItemListLike>(
  function _subGetter (line 120) | Get<Object> _subGetter(Get<ItemListLike> getter, int index)
  function _couldReuse (line 148) | bool _couldReuse({String typeA, String typeB, Object dataA, Object dataB})

FILE: lib/src/redux_adapter/static_flow_adapter.dart
  class StaticFlowAdapter (line 12) | @deprecated
    method buildAdapter (line 49) | ListAdapter buildAdapter(ContextSys<T> ctx)

FILE: lib/src/redux_aop/aop.dart
  type TypedApplyLike (line 1) | typedef TypedApplyLike<R> = R Function(List<dynamic>, [Map<Symbol, dynam...
  type ApplyLike (line 4) | typedef ApplyLike = dynamic Function(List<dynamic>, [Map<Symbol, dynamic...
  type ApplyLikeEnhancer (line 7) | typedef ApplyLikeEnhancer = ApplyLike Function(ApplyLike functor);
  function _identity (line 9) | ApplyLike _identity(ApplyLike f)
  function _combine (line 11) | ApplyLikeEnhancer _combine(ApplyLikeEnhancer e0, ApplyLikeEnhancer e1)
  class AOP (line 26) | class AOP {
    method enhance (line 34) | TypedApplyLike<R> enhance<R>(Function functor)
    method withZero (line 56) | R Function() withZero<R>(R Function() f)
    method withOne (line 61) | R Function(P) withOne<R, P>(R Function(P) f)
    method withTwo (line 66) | R Function(P0, P1) withTwo<R, P0, P1>(R Function(P0, P1) f)
    method withThree (line 71) | R Function(P0, P1, P2) withThree<R, P0, P1, P2>(R Function(P0, P1, P2) f)
    method withFour (line 78) | R Function(P0, P1, P2, P3) withFour<R, P0, P1, P2, P3>(
    method withFive (line 86) | R Function(P0, P1, P2, P3, P4) withFive<R, P0, P1, P2, P3, P4>(
    method withSix (line 95) | R Function(P0, P1, P2, P3, P4, P5) withSix<R, P0, P1, P2, P3, P4, P5>(

FILE: lib/src/redux_aop/common_aop/debounce.dart
  function debounce (line 7) | ApplyLikeEnhancer debounce(int millis)

FILE: lib/src/redux_aop/common_aop/debug.dart
  function isDebug (line 4) | bool isDebug()

FILE: lib/src/redux_aop/common_aop/delay.dart
  function delay (line 6) | ApplyLikeEnhancer delay(int millis)

FILE: lib/src/redux_aop/common_aop/log.dart
  function logAOP (line 7) | ApplyLikeEnhancer logAOP(String tag)

FILE: lib/src/redux_aop/common_aop/memoize.dart
  function _listEquals (line 3) | bool _listEquals<E>(List<E> list1, List<E> list2)
  function memoize (line 23) | ApplyLikeEnhancer memoize()

FILE: lib/src/redux_aop/common_aop/performance.dart
  function _microSecsSinceEpoch (line 6) | int _microSecsSinceEpoch()
  function performanceAOP (line 9) | ApplyLikeEnhancer performanceAOP(String tag)

FILE: lib/src/redux_aop/common_aop/throttle.dart
  function _microSecsSinceEpoch (line 3) | int _microSecsSinceEpoch()
  function throttle (line 7) | ApplyLikeEnhancer throttle(int millis)

FILE: lib/src/redux_aop/common_aop/wait_until.dart
  function waitUntil (line 5) | ApplyLikeEnhancer waitUntil()

FILE: lib/src/redux_component/auto_dispose.dart
  class _Fields (line 1) | class _Fields {
  class AutoDispose (line 14) | class AutoDispose {
    method visit (line 17) | void visit(void Function(AutoDispose) visitor)
    method dispose (line 22) | void dispose()
    method onDisposed (line 44) | void onDisposed(void Function() onDisposed)
    method setParent (line 53) | void setParent(AutoDispose newParent)
    method registerOnDisposed (line 76) | AutoDispose registerOnDisposed(void Function() onDisposed)

FILE: lib/src/redux_component/basic.dart
  type ViewBuilder (line 10) | typedef ViewBuilder<T> = Widget Function(
  class ListAdapter (line 18) | class ListAdapter {
  type AdapterBuilder (line 28) | typedef AdapterBuilder<T> = ListAdapter Function(
  class ViewUpdater (line 37) | abstract class ViewUpdater<T> {
    method buildWidget (line 38) | Widget buildWidget()
    method didUpdateWidget (line 39) | void didUpdateWidget()
    method onNotify (line 40) | void onNotify()
    method forceUpdate (line 41) | void forceUpdate()
    method clearCache (line 42) | void clearCache()
  type ShouldUpdate (line 51) | typedef ShouldUpdate<T> = bool Function(T old, T now);
  type Effect (line 56) | typedef Effect<T> = dynamic Function(Action action, Context<T> ctx);
  type ViewMiddleware (line 84) | typedef ViewMiddleware<T> = Composable<ViewBuilder<dynamic>> Function(
  type AdapterMiddleware (line 90) | typedef AdapterMiddleware<T> = Composable<AdapterBuilder<dynamic>> Funct...
  type EffectMiddleware (line 109) | typedef EffectMiddleware<T> = Composable<Effect<dynamic>> Function(
  class Enhancer (line 115) | abstract class Enhancer<T> {
    method viewEnhance (line 116) | ViewBuilder<K> viewEnhance<K>(
    method adapterEnhance (line 122) | AdapterBuilder<K> adapterEnhance<K>(
    method effectEnhance (line 128) | Effect<K> effectEnhance<K>(
    method storeEnhance (line 134) | StoreCreator<T> storeEnhance(StoreCreator<T> creator)
    method unshift (line 136) | void unshift({
    method append (line 143) | void append({
  class ExtraData (line 153) | abstract class ExtraData {
  class ViewService (line 159) | abstract class ViewService implements ExtraData {
    method buildAdapter (line 161) | ListAdapter buildAdapter()
    method buildComponent (line 164) | Widget buildComponent(String name, {Widget defaultWidget})
    method broadcast (line 170) | void broadcast(Action action)
    method broadcastEffect (line 176) | void broadcastEffect(Action action, {bool excluded})
  class Context (line 180) | abstract class Context<T> extends AutoDispose implements ExtraData {
    method dispatch (line 185) | dynamic dispatch(Action action)
    method buildComponent (line 208) | Widget buildComponent(String name)
    method broadcast (line 211) | void broadcast(Action action)
    method broadcastEffect (line 214) | void broadcastEffect(Action action, {bool excluded})
    method addObservable (line 217) | void Function() addObservable(Subscribe observable)
    method forceUpdate (line 219) | void forceUpdate()
    method listen (line 222) | void Function() listen({
  class ContextSys (line 229) | abstract class ContextSys<T> extends Context<T> implements ViewService {
    method onLifecycle (line 231) | void onLifecycle(Action action)
    method bindForceUpdate (line 233) | void bindForceUpdate(void Function() forceUpdate)
  class AbstractAdapterBuilder (line 242) | abstract class AbstractAdapterBuilder<T> {
    method buildAdapter (line 243) | ListAdapter buildAdapter(ContextSys<T> ctx)
  class Dependent (line 247) | abstract class Dependent<T> implements AbstractAdapterBuilder<Object> {
    method subGetter (line 248) | Get<Object> subGetter(Get<T> getter)
    method createSubReducer (line 250) | SubReducer<T> createSubReducer()
    method buildComponent (line 252) | Widget buildComponent(
    method createContext (line 259) | ContextSys<Object> createContext(
    method isComponent (line 267) | bool isComponent()
    method isAdapter (line 269) | bool isAdapter()
    method key (line 271) | Object key(T state)
  class AbstractLogic (line 276) | abstract class AbstractLogic<T> {
    method createReducer (line 278) | Reducer<T> createReducer()
    method onReducer (line 281) | Object onReducer(Object state, Action action)
    method createEffectDispatch (line 284) | Dispatch createEffectDispatch(ContextSys<T> ctx, Enhancer<Object> enha...
    method createNextDispatch (line 287) | Dispatch createNextDispatch(ContextSys<T> ctx, Enhancer<Object> enhancer)
    method createDispatch (line 291) | Dispatch createDispatch(
    method createContext (line 298) | ContextSys<T> createContext(
    method key (line 307) | Object key(T state)
    method slot (line 310) | Dependent<T> slot(String name)
    method adapterDep (line 313) | Dependent<T> adapterDep()
  class AbstractComponent (line 318) | abstract class AbstractComponent<T> implements AbstractLogic<T> {
    method buildComponent (line 320) | Widget buildComponent(
  class AbstractAdapter (line 328) | abstract class AbstractAdapter<T>
  type ReducerFilter (line 333) | typedef ReducerFilter<T> = bool Function(T state, Action action);
  class StateKey (line 341) | abstract class StateKey {
    method key (line 342) | Object key()
  class DispatchBus (line 346) | abstract class DispatchBus {
    method attach (line 347) | void attach(DispatchBus parent)
    method detach (line 349) | void detach()
    method dispatch (line 351) | void dispatch(Action action, {Dispatch excluded})
    method broadcast (line 353) | void broadcast(Action action, {DispatchBus excluded})
    method registerReceiver (line 355) | void Function() registerReceiver(Dispatch dispatch)

FILE: lib/src/redux_component/batch_store.dart
  function setupBatch (line 15) | void setupBatch()
  function isInSuitablePhase (line 30) | bool isInSuitablePhase()
  function _batch (line 38) | void _batch()
  class _BatchStore (line 66) | class _BatchStore<T> extends Store<T> with _BatchNotify<T> {
  function createBatchStore (line 79) | Store<T> createBatchStore<T>(
  type _UpdateState (line 94) | enum _UpdateState { Assign }
  function _appendUpdateStateReducer (line 97) | Reducer<T> _appendUpdateStateReducer<T>(Reducer<T> reducer)
  function connectStores (line 102) | Store<T> connectStores<T, K>(

FILE: lib/src/redux_component/component.dart
  type WidgetWrapper (line 12) | typedef WidgetWrapper = Widget Function(Widget child);
  class Component (line 14) | @immutable
    method buildComponent (line 56) | Widget buildComponent(
    method createContext (line 78) | ComponentContext<T> createContext(
    method createState (line 108) | ComponentState<T> createState()
    method neverUpdate (line 112) | ShouldUpdate<K> neverUpdate<K>()
    method alwaysUpdate (line 114) | ShouldUpdate<K> alwaysUpdate<K>()
    method updateByDefault (line 116) | ShouldUpdate<K> updateByDefault<K>()
    method _wrapperByDefault (line 119) | Widget _wrapperByDefault(Widget child)
  class ComponentWidget (line 122) | class ComponentWidget<T> extends StatefulWidget {
    method createState (line 142) | ComponentState<T> createState()
  class ComponentState (line 145) | class ComponentState<T> extends State<ComponentWidget<T>> {
    method build (line 152) | Widget build(BuildContext context)
    method reassemble (line 157) | void reassemble()
    method initState (line 165) | void initState()
    method didChangeDependencies (line 190) | void didChangeDependencies()
    method deactivate (line 202) | void deactivate()
    method didUpdateWidget (line 209) | void didUpdateWidget(ComponentWidget<T> oldWidget)
    method disposeCtx (line 216) | void disposeCtx()
    method dispose (line 226) | void dispose()

FILE: lib/src/redux_component/context.dart
  class LogicContext (line 14) | abstract class LogicContext<T> extends ContextSys<T> with _ExtraMixin {
    method bindForceUpdate (line 65) | void bindForceUpdate(void Function() forceUpdate)
    method dispatch (line 77) | dynamic dispatch(Action action)
    method buildComponent (line 80) | Widget buildComponent(String name, {Widget defaultWidget})
    method onLifecycle (line 91) | void onLifecycle(Action action)
    method dispose (line 97) | void dispose()
    method _throwIfDisposed (line 103) | bool _throwIfDisposed()
    method broadcastEffect (line 122) | void broadcastEffect(Action action, {bool excluded})
    method broadcast (line 126) | void broadcast(Action action)
    method addObservable (line 129) | void Function() addObservable(Subscribe observable)
    method forceUpdate (line 138) | void forceUpdate()
    method listen (line 141) | void Function() listen({
  class ComponentContext (line 166) | class ComponentContext<T> extends LogicContext<T> implements ViewUpdater...
    method onLifecycle (line 203) | void onLifecycle(Action action)
    method buildAdapter (line 209) | ListAdapter buildAdapter()
    method buildWidget (line 216) | Widget buildWidget()
    method didUpdateWidget (line 227) | void didUpdateWidget()
    method onNotify (line 236) | void onNotify()
    method clearCache (line 248) | void clearCache()
    method forceUpdate (line 253) | void forceUpdate()
  class PureViewViewService (line 265) | class PureViewViewService implements ViewService {
    method broadcast (line 274) | void broadcast(Action action)
    method broadcastEffect (line 277) | void broadcastEffect(Action action, {bool excluded})
    method buildAdapter (line 280) | ListAdapter buildAdapter()
    method buildComponent (line 284) | Widget buildComponent(String name, {Widget defaultWidget})

FILE: lib/src/redux_component/dependencies.dart
  class Dependencies (line 4) | class Dependencies<T> {
    method createReducer (line 16) | Reducer<T> createReducer()
    method slot (line 32) | Dependent<T> slot(String type)
    method trim (line 34) | Dependencies<T> trim()

FILE: lib/src/redux_component/dependent.dart
  class _Dependent (line 7) | class _Dependent<T, P> implements Dependent<T> {
    method createSubReducer (line 22) | SubReducer<T> createSubReducer()
    method buildComponent (line 25) | Widget buildComponent(
    method buildAdapter (line 43) | ListAdapter buildAdapter(covariant ContextSys<P> ctx)
    method subGetter (line 50) | Get<P> subGetter(Get<T> getter)
    method createContext (line 53) | ContextSys<P> createContext(
    method isComponent (line 71) | bool isComponent()
    method isAdapter (line 74) | bool isAdapter()
    method key (line 77) | Object key(T state)
  function createDependent (line 86) | Dependent<K> createDependent<K, T>(

FILE: lib/src/redux_component/dispatch_bus.dart
  class DispatchBusDefault (line 4) | class DispatchBusDefault implements DispatchBus {
    method attach (line 12) | void attach(DispatchBus parent)
    method detach (line 19) | void detach()
    method dispatch (line 24) | void dispatch(Action action, {Dispatch excluded})
    method broadcast (line 35) | void broadcast(Action action, {DispatchBus excluded})
    method registerReceiver (line 40) | void Function() registerReceiver(Dispatch dispatch)

FILE: lib/src/redux_component/enhancer.dart
  class EnhancerDefault (line 6) | class EnhancerDefault<T> implements Enhancer<T> {
    method unshift (line 33) | void unshift({
    method append (line 58) | void append({
    method viewEnhance (line 83) | ViewBuilder<K> viewEnhance<K>(
    method adapterEnhance (line 92) | AdapterBuilder<K> adapterEnhance<K>(
    method effectEnhance (line 103) | Effect<K> effectEnhance<K>(
    method storeEnhance (line 112) | StoreCreator<T> storeEnhance(StoreCreator<T> creator)
    method _inverterEffect (line 115) | Effect<dynamic> _inverterEffect<K>(Effect<K> effect)
    method _inverterView (line 119) | ViewBuilder<dynamic> _inverterView<K>(ViewBuilder<K> view)
    method _inverterAdapter (line 124) | AdapterBuilder<dynamic> _inverterAdapter<K>(AdapterBuilder<K> adapter)

FILE: lib/src/redux_component/helper.dart
  function asGetter (line 10) | Get<T> asGetter<T>(Get<Object> getter)
  function asAdapter (line 23) | AdapterBuilder<T> asAdapter<T>(ViewBuilder<T> view)
  function mergeReducers (line 34) | Reducer<T> mergeReducers<T extends K, K>(Reducer<K> sup, [Reducer<T> sub])
  function mergeEffects (line 40) | Effect<T> mergeEffects<T extends K, K>(Effect<K> sup, [Effect<T> sub])
  function asReducer (line 48) | Reducer<T> asReducer<T>(Map<Object, Reducer<T>> map)
  function filterReducer (line 60) | Reducer<T> filterReducer<T>(Reducer<T> reducer, ReducerFilter<T> filter)
  type SubEffect (line 70) | typedef SubEffect<T> = FutureOr<void> Function(Action action, Context<T>...
  function combineEffects (line 74) | Effect<T> combineEffects<T>(Map<Object, SubEffect<T>> map)
  function createEffectDispatch (line 100) | Dispatch createEffectDispatch<T>(Effect<T> userEffect, Context<T> ctx)
  function createNextDispatch (line 114) | Dispatch createNextDispatch<T>(ContextSys<T> ctx)
  function createDispatch (line 120) | Dispatch createDispatch<T>(Dispatch onEffect, Dispatch next, Context<T> ...
  function mergeViewMiddleware (line 130) | ViewMiddleware<T> mergeViewMiddleware<T>(List<ViewMiddleware<T>> middlew...
  function mergeAdapterMiddleware (line 143) | AdapterMiddleware<T> mergeAdapterMiddleware<T>(
  function mergeEffectMiddleware (line 158) | EffectMiddleware<T> mergeEffectMiddleware<T>(

FILE: lib/src/redux_component/lifecycle.dart
  type Lifecycle (line 5) | enum Lifecycle {
  class LifecycleCreator (line 34) | class LifecycleCreator {
    method initState (line 35) | Action initState()
    method build (line 37) | Action build(String name)
    method reassemble (line 39) | Action reassemble()
    method dispose (line 41) | Action dispose()
    method didUpdateWidget (line 45) | Action didUpdateWidget()
    method didChangeDependencies (line 47) | Action didChangeDependencies()
    method deactivate (line 50) | Action deactivate()
    method appear (line 52) | Action appear(int index)
    method disappear (line 54) | Action disappear(int index)
    method didChangeAppLifecycleState (line 57) | Action didChangeAppLifecycleState(AppLifecycleState state)

FILE: lib/src/redux_component/local.dart
  class LocalProps (line 42) | abstract class LocalProps<T extends LocalProps<T>> {
    method destructor (line 44) | void destructor(Context<Object> ctx)
    method provide (line 46) | _LocalPropsProvider<T> provide<T extends LocalProps<T>>(
  class _LocalPropsProvider (line 54) | @immutable
    method of (line 63) | T of(ExtraData context)

FILE: lib/src/redux_component/logic.dart
  class Logic (line 14) | abstract class Logic<T> implements AbstractLogic<T> {
    method isSuperTypeof (line 61) | bool isSuperTypeof<K>()
    method isTypeof (line 63) | bool isTypeof<K>()
    method isAssignFrom (line 65) | bool isAssignFrom<P, Q>()
    method cache (line 71) | R cache<R>(String key, Get<R> getter)
    method createReducer (line 76) | Reducer<T> createReducer()
    method onReducer (line 82) | Object onReducer(Object state, Action action)
    method createEffectDispatch (line 87) | Dispatch createEffectDispatch(ContextSys<T> ctx, Enhancer<Object> enha...
    method createNextDispatch (line 100) | Dispatch createNextDispatch(ContextSys<T> ctx, Enhancer<Object> enhancer)
    method createDispatch (line 104) | Dispatch createDispatch(
    method key (line 112) | Object key(T state)
    method slot (line 115) | Dependent<T> slot(String type)
    method adapterDep (line 118) | Dependent<T> adapterDep()

FILE: lib/src/redux_component/page.dart
  type InitState (line 12) | typedef InitState<T, P> = T Function(P params);
  type StoreUpdater (line 14) | typedef StoreUpdater<T> = Store<T> Function(Store<T> store);
  class Page (line 18) | @immutable
    method buildPage (line 70) | Widget buildPage(P param)
    method createStore (line 75) | Store<T> createStore(P param)
    method updateStore (line 81) | Store<T> updateStore(Store<T> store)
    method connectExtraStore (line 88) | void connectExtraStore<K>(
    method createPageBus (line 100) | DispatchBus createPageBus()
    method unshift (line 102) | void unshift({
    method append (line 116) | void append({
  class _PageWidget (line 131) | class _PageWidget<T, P> extends StatefulWidget {
    method createState (line 142) | State<StatefulWidget> createState()
  class _PageState (line 145) | class _PageState<T, P> extends State<_PageWidget<T, P>> {
    method initState (line 152) | void initState()
    method didChangeDependencies (line 159) | void didChangeDependencies()
    method build (line 167) | Widget build(BuildContext context)
    method dispose (line 183) | void dispose()
  class PageProvider (line 190) | @deprecated
    method tryOf (line 206) | PageProvider tryOf(BuildContext context)
    method updateShouldNotify (line 213) | bool updateShouldNotify(PageProvider oldWidget)

FILE: lib/src/redux_component_mixin/keep_alive_mixin.dart
  function createState (line 14) | ComponentState<T> createState()
  class _KeepAliveStfState (line 17) | class _KeepAliveStfState<T> extends ComponentState<T>
    method build (line 23) | Widget build(BuildContext context)
  function keepAliveClientWrapper (line 36) | Widget keepAliveClientWrapper(Widget child)
  class _KeepAliveWidget (line 38) | class _KeepAliveWidget extends StatefulWidget {
    method createState (line 44) | State<StatefulWidget> createState()
  class _KeepAliveState (line 47) | class _KeepAliveState extends State<_KeepAliveWidget>
    method build (line 53) | Widget build(BuildContext context)

FILE: lib/src/redux_component_mixin/private_reducer_mixin.dart
  function createDispatch (line 25) | Dispatch createDispatch(Dispatch effect, Dispatch next, Context<T> ctx)
  class PrivateAction (line 40) | class PrivateAction extends Action {
    method asAction (line 45) | Action asAction()

FILE: lib/src/redux_component_mixin/single_ticker_provider_mixin.dart
  function createState (line 14) | _SingleTickerProviderStfState<T> createState()
  class _SingleTickerProviderStfState (line 18) | class _SingleTickerProviderStfState<T> extends ComponentState<T>
    method dispose (line 22) | void dispose()

FILE: lib/src/redux_component_mixin/ticker_provider_mixin.dart
  function createState (line 14) | _TickerProviderStfState<T> createState()
  class _TickerProviderStfState (line 17) | class _TickerProviderStfState<T> extends ComponentState<T>
    method dispose (line 21) | void dispose()

FILE: lib/src/redux_component_mixin/visible_change_mixin.dart
  function buildAdapter (line 16) | ListAdapter buildAdapter(ContextSys<T> ctx)
  class _VisibleChangeState (line 21) | class _VisibleChangeState extends State<_VisibleChangeWidget> {
    method build (line 23) | Widget build(BuildContext context)
    method initState (line 27) | void initState()
    method dispose (line 33) | void dispose()
  class _VisibleChangeWidget (line 39) | class _VisibleChangeWidget extends StatefulWidget {
    method createState (line 52) | State<StatefulWidget> createState()
  function _wrapVisibleChange (line 55) | ListAdapter _wrapVisibleChange<T>(
  class _VisibleChangeDispatch (line 75) | class _VisibleChangeDispatch extends AutoDispose {
    method onAction (line 81) | void onAction(Action action)

FILE: lib/src/redux_component_mixin/widgets_binding_observer_mixin.dart
  function createState (line 14) | _WidgetsBindingObserverStfState<T> createState()
  class _WidgetsBindingObserverStfState (line 18) | class _WidgetsBindingObserverStfState<T> extends ComponentState<T>
    method initState (line 21) | void initState()
    method dispose (line 27) | void dispose()
    method didChangeAppLifecycleState (line 33) | void didChangeAppLifecycleState(AppLifecycleState state)

FILE: lib/src/redux_connector/connector.dart
  class ConnOp (line 5) | class ConnOp<T, P> extends MutableConn<T, P> with ConnOpMixin<T, P> {
    method get (line 16) | P get(T state)
    method set (line 19) | void set(T state, P subState)

FILE: lib/src/redux_connector/generator.dart
  function generator (line 1) | String Function() generator()

FILE: lib/src/redux_connector/helper.dart
  class ConnHelper (line 4) | class ConnHelper {
    method to (line 5) | AbstractConnector<T, K> to<T, P, K>(
    method join (line 10) | Dependent<T> join<T, P>(
  class _AbstractConnector (line 15) | class _AbstractConnector<T, P, K> extends AbstractConnector<T, K> {
    method get (line 22) | K get(T state)
    method subReducer (line 27) | SubReducer<T> subReducer(Reducer<K> reducer)

FILE: lib/src/redux_connector/map_like.dart
  class MapLike (line 4) | abstract class MapLike {
    method clear (line 7) | void clear()
    method containsKey (line 13) | bool containsKey(String key)
    method copyFrom (line 15) | void copyFrom(MapLike from)
  function withMapLike (line 19) | ConnOp<T, P> withMapLike<T extends MapLike, P>(String key)
  class AutoInitConnector (line 24) | class AutoInitConnector<T extends MapLike, P> extends ConnOp<T, P> {
    method get (line 37) | P get(T state)
    method set (line 41) | void set(T state, P subState)

FILE: lib/src/redux_connector/none.dart
  class NoneConn (line 4) | class NoneConn<T> extends ImmutableConn<T, T> with ConnOpMixin<T, T> {
    method get (line 8) | T get(T state)
    method set (line 11) | T set(T state, T subState)

FILE: lib/src/redux_connector/reselect.dart
  function _listEquals (line 6) | bool _listEquals(List<dynamic> list1, List<dynamic> list2)
  class _BasicReselect (line 31) | abstract class _BasicReselect<T, P> extends MutableConn<T, P>
    method getSubs (line 37) | List<dynamic> getSubs(T state)
    method reduceSubs (line 39) | P reduceSubs(List<dynamic> list)
    method get (line 42) | P get(T state)
  class Reselect1 (line 53) | abstract class Reselect1<T, P, K0> extends _BasicReselect<T, P> {
    method getSub0 (line 54) | K0 getSub0(T state)
    method computed (line 55) | P computed(K0 state)
    method getSubs (line 58) | List<dynamic> getSubs(T state)
    method reduceSubs (line 61) | P reduceSubs(List<dynamic> list)
  class Reselect2 (line 64) | abstract class Reselect2<T, P, K0, K1> extends _BasicReselect<T, P> {
    method getSub0 (line 65) | K0 getSub0(T state)
    method getSub1 (line 66) | K1 getSub1(T state)
    method computed (line 67) | P computed(K0 sub0, K1 sub1)
    method getSubs (line 70) | List<dynamic> getSubs(T state)
    method reduceSubs (line 73) | P reduceSubs(List<dynamic> list)
  class Reselect3 (line 76) | abstract class Reselect3<T, P, K0, K1, K2> extends _BasicReselect<T, P> {
    method getSub0 (line 77) | K0 getSub0(T state)
    method getSub1 (line 78) | K1 getSub1(T state)
    method getSub2 (line 79) | K2 getSub2(T state)
    method computed (line 80) | P computed(K0 sub0, K1 sub1, K2 sub2)
    method getSubs (line 83) | List<dynamic> getSubs(T state)
    method reduceSubs (line 90) | P reduceSubs(List<dynamic> list)
  class Reselect4 (line 93) | abstract class Reselect4<T, P, K0, K1, K2, K3> extends _BasicReselect<T,...
    method getSub0 (line 94) | K0 getSub0(T state)
    method getSub1 (line 95) | K1 getSub1(T state)
    method getSub2 (line 96) | K2 getSub2(T state)
    method getSub3 (line 97) | K3 getSub3(T state)
    method computed (line 98) | P computed(K0 sub0, K1 sub1, K2 sub2, K3 sub3)
    method getSubs (line 101) | List<dynamic> getSubs(T state)
    method reduceSubs (line 109) | P reduceSubs(List<dynamic> list)
  class Reselect5 (line 112) | abstract class Reselect5<T, P, K0, K1, K2, K3, K4>
    method getSub0 (line 114) | K0 getSub0(T state)
    method getSub1 (line 115) | K1 getSub1(T state)
    method getSub2 (line 116) | K2 getSub2(T state)
    method getSub3 (line 117) | K3 getSub3(T state)
    method getSub4 (line 118) | K4 getSub4(T state)
    method computed (line 119) | P computed(K0 sub0, K1 sub1, K2 sub2, K3 sub3, K4 sub4)
    method getSubs (line 122) | List<dynamic> getSubs(T state)
    method reduceSubs (line 131) | P reduceSubs(List<dynamic> list)
  class Reselect6 (line 134) | abstract class Reselect6<T, P, K0, K1, K2, K3, K4, K5>
    method getSub0 (line 136) | K0 getSub0(T state)
    method getSub1 (line 137) | K1 getSub1(T state)
    method getSub2 (line 138) | K2 getSub2(T state)
    method getSub3 (line 139) | K3 getSub3(T state)
    method getSub4 (line 140) | K4 getSub4(T state)
    method getSub5 (line 141) | K5 getSub5(T state)
    method computed (line 142) | P computed(K0 sub0, K1 sub1, K2 sub2, K3 sub3, K4 sub4, K5 sub5)
    method getSubs (line 145) | List<dynamic> getSubs(T state)
    method reduceSubs (line 155) | P reduceSubs(List<dynamic> list)
  class Reselect (line 158) | abstract class Reselect<T, P> extends _BasicReselect<T, P> {
    method computed (line 159) | P computed(List<dynamic> list)
    method reduceSubs (line 162) | P reduceSubs(List<dynamic> list)
  function computed (line 171) | P computed(T state)
  function factors (line 173) | List<dynamic> factors(T state)
  function get (line 177) | P get(T state)

FILE: lib/src/redux_middleware/adapter_middleware/safety_adapter.dart
  function safetyAdapter (line 8) | AdapterMiddleware<T> safetyAdapter<T>({

FILE: lib/src/redux_middleware/middleware/log.dart
  function logMiddleware (line 6) | Middleware<T> logMiddleware<T>({

FILE: lib/src/redux_middleware/middleware/performance.dart
  function performanceMiddleware (line 6) | Middleware<T> performanceMiddleware<T>({String tag = 'redux'})

FILE: lib/src/redux_middleware/view_middleware/safety_view.dart
  function safetyView (line 7) | ViewMiddleware<T> safetyView<T>(

FILE: lib/src/redux_routes/page_routes.dart
  class AbstractRoutes (line 6) | abstract class AbstractRoutes {
    method buildPage (line 7) | Widget buildPage(String path, dynamic arguments)
  class PageRoutes (line 11) | @immutable
    method buildPage (line 27) | Widget buildPage(String path, dynamic arguments)

FILE: lib/src/utils/collections.dart
  class Collections (line 4) | class Collections {
    method reduce (line 6) | E reduce<E>(List<E> list, E combine(E e0, E e1))
    method fold (line 10) | T fold<T, E>(T init, List<E> list, T combine(T e0, E e1))
    method flatten (line 19) | List<E> flatten<E>(List<List<E>> lists)
    method merge (line 25) | List<T> merge<T>(Iterable<T> a, Iterable<T> b)
    method clone (line 28) | List<T> clone<T>(Iterable<T> a)
    method castMapToList (line 36) | List<T> castMapToList<T, K, V>(Map<K, V> map0, T map(V v, K k))
    method castMap (line 42) | Map<K, V1> castMap<K, V0, V1>(Map<K, V0> map0, V1 map(V0 v0, K k))
    method compact (line 50) | List<T> compact<T>(Iterable<T> list, {bool growable = true})
    method isEmpty (line 54) | bool isEmpty(Object value)
    method isNotEmpty (line 72) | bool isNotEmpty(Object value)

FILE: lib/src/utils/debug.dart
  function isDebug (line 4) | bool isDebug()
  function println (line 15) | bool println(Object object)

FILE: lib/src/utils/hash.dart
  function hash (line 4) | int hash(Iterable<int> values)

FILE: lib/src/utils/tuple.dart
  class Tuple0 (line 3) | class Tuple0<T0> {
  class Tuple1 (line 15) | class Tuple1<T0> {
    method toString (line 21) | String toString()
  class Tuple2 (line 31) | class Tuple2<T0, T1> {
    method toString (line 42) | String toString()
  class Tuple3 (line 53) | class Tuple3<T0, T1, T2> {
    method toString (line 61) | String toString()
  class Tuple4 (line 72) | class Tuple4<T0, T1, T2, T3> {
    method toString (line 81) | String toString()
  class Tuple5 (line 97) | class Tuple5<T0, T1, T2, T3, T4> {
    method toString (line 107) | String toString()
  class Tuple6 (line 124) | class Tuple6<T0, T1, T2, T3, T4, T5> {
    method toString (line 135) | String toString()

FILE: test/lib/all_test.dart
  function main (line 12) | void main()

FILE: test/lib/instrument.dart
  type ViewInstrument (line 3) | typedef ViewInstrument<T> = void Function(
  function instrumentView (line 6) | ViewBuilder<T> instrumentView<T>(
  type initStateInstrumentPre (line 20) | typedef initStateInstrumentPre<P> = void Function(P);
  type initStateInstrumentSuf (line 21) | typedef initStateInstrumentSuf<T extends Cloneable<T>> = void Function(T);
  function instrumentInitState (line 23) | InitState<T, P> instrumentInitState<T extends Cloneable<T>, P>(
  type ReducerInstrument (line 40) | typedef ReducerInstrument<T> = void Function(T state, Action action);
  function instrumentReducer (line 42) | Reducer<T> instrumentReducer<T>(Reducer<T> reducer,
  type EffectInstrument (line 65) | typedef EffectInstrument<T> = void Function(Action action, Get<T> getSta...
  function instrumentEffect (line 67) | Effect<T> instrumentEffect<T>(Effect<T> effect, EffectInstrument<T> pre)
  type MiddlewareInstrument (line 75) | typedef MiddlewareInstrument<T> = void Function(Action action, Get<T> ge...
  function instrumentMiddleware (line 77) | Middleware<T> instrumentMiddleware<T>(Middleware<T> middleware,
  type ErrorInstrument (line 98) | typedef ErrorInstrument<T> = void Function(Exception exception, Context<...

FILE: test/lib/redux/redux_test.dart
  function main (line 5) | void main()

FILE: test/lib/redux/store_test.dart
  type ToDoAction (line 10) | enum ToDoAction { add, remove, done }
  class Todo (line 12) | class Todo {
  class ToDoList (line 29) | class ToDoList {
  function toDoReducer (line 39) | ToDoList toDoReducer(ToDoList state, Action action)
  function defaultReducer (line 56) | ToDoList defaultReducer(ToDoList state, Action action)
  function main (line 58) | void main()

FILE: test/lib/redux_adapter/adapter_test.dart
  function main (line 13) | void main()

FILE: test/lib/redux_adapter/dynamic_adapter_test.dart
  class ToDoComponentInstrument (line 14) | class ToDoComponentInstrument extends TestComponent<Todo> {
  class ToDoComponentNoReducer (line 40) | class ToDoComponentNoReducer extends TestComponent<Todo> {
  function toDoListDependencies (line 62) | Dependencies<ToDoList> toDoListDependencies(final Track track,
  function main (line 98) | void main()

FILE: test/lib/redux_adapter/redux_adapter_test.dart
  function main (line 8) | void main()

FILE: test/lib/redux_adapter/source_adapter_test.dart
  class ToDoComponentInstrument (line 14) | class ToDoComponentInstrument extends TestComponent<Todo> {
  class ToDoComponentNoReducer (line 40) | class ToDoComponentNoReducer extends TestComponent<Todo> {
  function toDoListDependencies (line 62) | Dependencies<ToDoList> toDoListDependencies(final Track track,
  function main (line 89) | void main()

FILE: test/lib/redux_adapter/static_flow_adapter_test.dart
  class ToDoComponentInstrument (line 14) | class ToDoComponentInstrument extends TestComponent<Todo> {
  class ToDoAdapterInstrument (line 39) | class ToDoAdapterInstrument extends TestAdapter<Todo> {
  class Component0 (line 63) | class Component0 extends ToDoComponentInstrument {
  class Adapter1 (line 67) | class Adapter1 extends ToDoAdapterInstrument {
  class Component2 (line 71) | class Component2 extends ToDoComponentInstrument {
  class Adapter3 (line 75) | class Adapter3 extends ToDoAdapterInstrument {
  function toDoListDependencies (line 79) | Dependencies<ToDoList> toDoListDependencies(final Track track)
  function main (line 118) | void main()

FILE: test/lib/redux_aop/memoize_test.dart
  class _Pair (line 4) | class _Pair {
  function mkPair (line 12) | _Pair mkPair(int value, String label)
  function main (line 14) | void main()

FILE: test/lib/redux_aop/redux_aop_test.dart
  function main (line 5) | void main()

FILE: test/lib/redux_component/auto_dispose_test.dart
  function main (line 4) | void main()

FILE: test/lib/redux_component/component_test.dart
  class ToDoComponentInstrument (line 13) | class ToDoComponentInstrument extends TestComponent<Todo> {
  class Component0 (line 40) | class Component0 extends ToDoComponentInstrument {
  class Component1 (line 44) | class Component1 extends ToDoComponentInstrument {
  class Component2 (line 48) | class Component2 extends ToDoComponentInstrument {
  class Component3 (line 52) | class Component3 extends ToDoComponentInstrument {
  function toDoListDependencies (line 56) | Dependencies<ToDoList> toDoListDependencies(final Track track)
  function pageView (line 76) | Widget pageView(
  function main (line 133) | void main()

FILE: test/lib/redux_component/lifecycle_test.dart
  class ToDoComponentInstrument (line 13) | class ToDoComponentInstrument extends TestComponent<Todo> {
  function toDoListDependencies (line 46) | Dependencies<ToDoList> toDoListDependencies(final Track track)
  function pageView (line 57) | Widget pageView(
  function main (line 95) | void main()

FILE: test/lib/redux_component/page_test.dart
  function main (line 12) | void main()

FILE: test/lib/redux_component/redux_component_test.dart
  function main (line 8) | void main()

FILE: test/lib/redux_connector/map_like_test.dart
  class _Info (line 4) | class _Info extends MapLike {
  function main (line 11) | void main()

FILE: test/lib/redux_connector/redux_connector_test.dart
  function main (line 6) | void main()

FILE: test/lib/redux_connector/reselect_test.dart
  class _Parent (line 4) | class _Parent {
  class _Info (line 12) | class _Info {
  class _InfoConn (line 19) | class _InfoConn extends Reselect2<_Parent, _Info, int, String> {
    method computed (line 21) | _Info computed(int sub0, String sub1)
    method getSub0 (line 24) | int getSub0(_Parent state)
    method getSub1 (line 27) | String getSub1(_Parent state)
    method set (line 30) | void set(_Parent state, _Info subState)
  function main (line 36) | void main()

FILE: test/lib/redux_middleware/redux_middleware_test.dart
  function main (line 3) | void main()

FILE: test/lib/redux_routes/redux_routes_test.dart
  function main (line 3) | void main()

FILE: test/lib/track.dart
  class Track (line 1) | class Track {
    method append (line 24) | void append(String tag, [Object value])
    method countOfTag (line 28) | int countOfTag(String tag)
    method remove (line 31) | void remove(String tag)
    method toString (line 33) | String toString()
    method reset (line 50) | void reset()
  class Pin (line 55) | class Pin {
    method toString (line 65) | String toString()

FILE: test/lib/utils/collections_test.dart
  function main (line 4) | void main()

FILE: test/lib/utils/utils_test.dart
  function main (line 5) | void main()

FILE: test/test_widgets/lib/adapter/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {

FILE: test/test_widgets/lib/adapter/adapter.dart
  function toDoView (line 7) | Widget toDoView(
  function toDoListEffect (line 79) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListEffectAsync (line 100) | dynamic toDoListEffectAsync(Action action, Context<ToDoList> ctx)
  function toDoListHigherEffect (line 112) | Dispatch toDoListHigherEffect(Context<ToDoList> ctx)
  function toDoListReducer (line 115) | ToDoList toDoListReducer(ToDoList state, Action action)
  function toDoListAdapter (line 140) | ListAdapter toDoListAdapter(

FILE: test/test_widgets/lib/adapter/page.dart
  function pageView (line 8) | Widget pageView(
  function initState (line 48) | ToDoList initState(Map map)
  class PageWrapper (line 50) | class PageWrapper extends StatelessWidget {
    method build (line 56) | Widget build(BuildContext context)
  function createAdapterWidget (line 61) | Widget createAdapterWidget(BuildContext context)

FILE: test/test_widgets/lib/adapter/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()

FILE: test/test_widgets/lib/component/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {
  type ToDoAction (line 9) | enum ToDoAction {

FILE: test/test_widgets/lib/component/component.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 100) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 108) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 111) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 125) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 127) | bool reducerFilter(Todo toDo, Action action)
  class ToDoComponent (line 131) | class ToDoComponent extends Component<Todo> {
  class ComponentWrapper (line 141) | class ComponentWrapper extends StatelessWidget {
    method build (line 147) | Widget build(BuildContext context)

FILE: test/test_widgets/lib/component/page.dart
  function toDoListView (line 9) | Widget toDoListView(
  function toDoListEffect (line 63) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListEffectAsync (line 76) | dynamic toDoListEffectAsync(Action action, Context<ToDoList> ctx)
  function toDoListHigherEffect (line 85) | Dispatch toDoListHigherEffect(Context<ToDoList> ctx)
  function toDoListReducer (line 88) | ToDoList toDoListReducer(ToDoList state, Action action)
  function initState (line 133) | ToDoList initState(Map map)
  class ToDoComponent0 (line 135) | class ToDoComponent0 extends ToDoComponent {}
  class ToDoComponent1 (line 137) | class ToDoComponent1 extends ToDoComponent {}
  class ToDoComponent2 (line 139) | class ToDoComponent2 extends ToDoComponent {}
  class ToDoComponent3 (line 141) | class ToDoComponent3 extends ToDoComponent {}

FILE: test/test_widgets/lib/component/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()

FILE: test/test_widgets/lib/dynamic_flow_adapter/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {
  type ToDoAction (line 8) | enum ToDoAction {
  type PageAction (line 16) | enum PageAction {

FILE: test/test_widgets/lib/dynamic_flow_adapter/adapter.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 99) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 107) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 110) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 124) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 128) | bool reducerFilter(Todo toDo, Action action)

FILE: test/test_widgets/lib/dynamic_flow_adapter/component.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 100) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 108) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 111) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 125) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 129) | bool reducerFilter(Todo toDo, Action action)
  class ToDoComponent (line 133) | class ToDoComponent extends Component<Todo> {
  class ComponentWrapper (line 143) | class ComponentWrapper extends StatelessWidget {
    method build (line 149) | Widget build(BuildContext context)

FILE: test/test_widgets/lib/dynamic_flow_adapter/dynamic_flow_adapter.dart
  function toDoListEffect (line 8) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListReducer (line 18) | ToDoList toDoListReducer(ToDoList state, Action action)

FILE: test/test_widgets/lib/dynamic_flow_adapter/page.dart
  function pageView (line 9) | Widget pageView(
  function pageEffect (line 77) | bool pageEffect(Action action, Context<ToDoList> ctx)
  function initState (line 87) | ToDoList initState(Map map)
  function createDynamicAdapterWidget (line 89) | Widget createDynamicAdapterWidget(BuildContext context)

FILE: test/test_widgets/lib/dynamic_flow_adapter/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()

FILE: test/test_widgets/lib/main.dart
  function main (line 18) | void main()

FILE: test/test_widgets/lib/page/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {

FILE: test/test_widgets/lib/page/exception.dart
  class KnowException (line 1) | class KnowException implements Exception{
  class UnKnowException (line 6) | class UnKnowException implements Exception{

FILE: test/test_widgets/lib/page/page.dart
  function toDoView (line 9) | Widget toDoView(Todo toDo, BuildContext context, Dispatch dispatch)
  function toDoListView (line 79) | Widget toDoListView(
  function toDoListEffect (line 134) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListEffectAsync (line 163) | dynamic toDoListEffectAsync(Action action, Context<ToDoList> ctx)
  function toDoListReducer (line 175) | ToDoList toDoListReducer(ToDoList state, Action action)
  function forbidRefreshUI (line 200) | bool forbidRefreshUI(ToDoList old, ToDoList now)
  function toDoListErrorHandler (line 204) | bool toDoListErrorHandler(Exception exception, Context<ToDoList> ctx)
  function toDoListMiddleware (line 213) | Composable<Dispatch> toDoListMiddleware({
  function initState (line 265) | ToDoList initState(Map map)
  class PageWrapper (line 267) | class PageWrapper extends StatelessWidget {
    method build (line 273) | Widget build(BuildContext context)
  function createPageWidget (line 278) | Widget createPageWidget(BuildContext context)

FILE: test/test_widgets/lib/page/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()

FILE: test/test_widgets/lib/source_flow_adapter/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {
  type ToDoAction (line 8) | enum ToDoAction {
  type PageAction (line 16) | enum PageAction {

FILE: test/test_widgets/lib/source_flow_adapter/adapter.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 99) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 107) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 110) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 124) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 128) | bool reducerFilter(Todo toDo, Action action)

FILE: test/test_widgets/lib/source_flow_adapter/component.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 100) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 108) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 111) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 125) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 129) | bool reducerFilter(Todo toDo, Action action)
  class ToDoComponent (line 133) | class ToDoComponent extends Component<Todo> {
  class ComponentWrapper (line 143) | class ComponentWrapper extends StatelessWidget {
    method build (line 149) | Widget build(BuildContext context)

FILE: test/test_widgets/lib/source_flow_adapter/page.dart
  function pageView (line 9) | Widget pageView(
  function pageEffect (line 77) | bool pageEffect(Action action, Context<ToDoList> ctx)
  function initState (line 87) | ToDoList initState(Map map)
  function createDynamicAdapterWidget (line 89) | Widget createDynamicAdapterWidget(BuildContext context)

FILE: test/test_widgets/lib/source_flow_adapter/source_flow_adapter.dart
  function toDoListEffect (line 8) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListReducer (line 18) | ToDoList toDoListReducer(ToDoList state, Action action)

FILE: test/test_widgets/lib/source_flow_adapter/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList extends ItemListLike implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()
    method getItemData (line 81) | Object getItemData(int index)
    method getItemType (line 84) | String getItemType(int index)
    method updateItemData (line 90) | ItemListLike updateItemData(int index, Object data, bool isStateCopied)

FILE: test/test_widgets/lib/static_flow_adapter/action.dart
  type ToDoListAction (line 1) | enum ToDoListAction {
  type ToDoAction (line 7) | enum ToDoAction {

FILE: test/test_widgets/lib/static_flow_adapter/component.dart
  function toDoView (line 7) | Widget toDoView(Todo toDo, Dispatch dispatch, ViewService viewService)
  function toDoEffect (line 77) | bool toDoEffect(Action action, Context<Todo> ctx)
  function toDoEffectAsync (line 94) | dynamic toDoEffectAsync(Action action, Context<Todo> ctx)
  function toDoHigherEffect (line 102) | Dispatch toDoHigherEffect(Context<Todo> ctx)
  function toDoReducer (line 105) | Todo toDoReducer(Todo state, Action action)
  function shouldUpdate (line 119) | bool shouldUpdate(Todo old, Todo now)
  function reducerFilter (line 121) | bool reducerFilter(Todo toDo, Action action)
  class ToDoComponent (line 125) | class ToDoComponent extends Component<Todo> {

FILE: test/test_widgets/lib/static_flow_adapter/page.dart
  function pageView (line 8) | Widget pageView(
  function initState (line 48) | ToDoList initState(Map map)
  function createStaticAdapterWidget (line 50) | Widget createStaticAdapterWidget(BuildContext context)

FILE: test/test_widgets/lib/static_flow_adapter/state.dart
  class Todo (line 3) | class Todo implements Cloneable<Todo> {
    method clone (line 18) | Todo clone()
    method toString (line 43) | String toString()
  class ToDoList (line 48) | class ToDoList implements Cloneable<ToDoList> {
    method clone (line 54) | ToDoList clone()
    method toString (line 76) | String toString()

FILE: test/test_widgets/lib/static_flow_adapter/static_flow_adapter.dart
  function toDoListEffect (line 7) | bool toDoListEffect(Action action, Context<ToDoList> ctx)
  function toDoListEffectAsync (line 18) | dynamic toDoListEffectAsync(Action action, Context<ToDoList> ctx)
  function toDoListHigherEffect (line 27) | Dispatch toDoListHigherEffect(Context<ToDoList> ctx)
  function toDoListReducer (line 30) | ToDoList toDoListReducer(ToDoList state, Action action)
  class ToDoComponent0 (line 45) | class ToDoComponent0 extends ToDoComponent {}
  class ToDoComponent1 (line 47) | class ToDoComponent1 extends ToDoComponent {}
  class ToDoComponent2 (line 49) | class ToDoComponent2 extends ToDoComponent {}
  class ToDoComponent3 (line 51) | class ToDoComponent3 extends ToDoComponent {}

FILE: test/test_widgets/lib/test_base.dart
  class TestStub (line 4) | @immutable
    method createState (line 12) | _StubState createState()
  class _StubState (line 15) | class _StubState extends State<TestStub> {
    method build (line 17) | Widget build(BuildContext context)
  class TestPage (line 26) | class TestPage<T extends Cloneable<T>, P> extends Page<T, P> {
  class TestComponent (line 52) | class TestComponent<T extends Cloneable<T>> extends Component<T> {
  class TestAdapter (line 73) | class TestAdapter<T extends Cloneable<T>> extends Adapter<T> {
  class TestStaticFlowAdapter (line 88) | class TestStaticFlowAdapter<T extends Cloneable<T>>
  class TestDynamicFlowAdapter (line 98) | class TestDynamicFlowAdapter<T extends Cloneable<T>>
  class TestSourceFlowAdapter (line 114) | class TestSourceFlowAdapter<T extends AdapterSource>
Condensed preview — 314 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (607K chars).
[
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "chars": 513,
    "preview": "---\nname: Bug report\nabout: Create a report to help us improve\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Describe the b"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/custom.md",
    "chars": 126,
    "preview": "---\nname: Custom issue template\nabout: Describe this issue template's purpose here.\ntitle: ''\nlabels: ''\nassignees: ''\n\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "chars": 595,
    "preview": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: ''\nassignees: ''\n\n---\n\n**Is your fea"
  },
  {
    "path": ".gitignore",
    "chars": 232,
    "preview": ".DS_Store\n.atom/\n.idea/\n.vscode/\n.packages\n.pub/\n.dart_tool/\nbuild/\npubspec.lock\nandroid/\nios/\n.gradle/\nbuild.gradle\ngra"
  },
  {
    "path": ".metadata",
    "chars": 309,
    "preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
  },
  {
    "path": ".travis.yml",
    "chars": 486,
    "preview": "os:\n    - linux\nsudo: false\naddons:\n    apt:\n        sources:\n            - ubuntu-toolchain-r-test\n        packages:\n  "
  },
  {
    "path": "CHANGELOG.md",
    "chars": 3472,
    "preview": "## [0.3.7]\n- fix test .\n- revert issue 613\n\n## [0.3.6]\n- fix some dos .\n\n## [0.3.5]\n- fix deprecated using of api - inhe"
  },
  {
    "path": "LICENSE",
    "chars": 11342,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "README.md",
    "chars": 2431,
    "preview": "<p align=\"center\"><img src=\"https://img.alicdn.com/tfs/TB1r74NJyLaK1RjSZFxXXamPFXa-1024-1024.png\" align=\"center\" width=\""
  },
  {
    "path": "analysis_options.yaml",
    "chars": 7351,
    "preview": "# Specify analysis options.\n#\n# Until there are meta linter rules, each desired lint must be explicitly enabled.\n# See: "
  },
  {
    "path": "doc/README-cn.md",
    "chars": 1580,
    "preview": "-   **简介**\n    -   [关于](introduction/README-cn.md)\n    -   [演进](concept/evolution-of-fish-redux.md)\n    -   [特性](concept"
  },
  {
    "path": "doc/README.md",
    "chars": 1427,
    "preview": "- **Introduction**\n  - [About](introduction/README.md)\n  - [Evolution](concept/evolution-of-fish-redux.md)\n  - [Features"
  },
  {
    "path": "doc/concept/action-cn.md",
    "chars": 605,
    "preview": "# Action\n\n-   Action 包含两个字段\n    -   type\n    -   payload\n-   推荐的写法是\n    -   为一个组件|适配器创建一个 action.dart 文件,包含两个类\n        -"
  },
  {
    "path": "doc/concept/action.md",
    "chars": 834,
    "preview": "# Action\n\n-   Action contains two fields\n    -   type\n    -   payload\n-   Recommended way of writing action\n    -   Crea"
  },
  {
    "path": "doc/concept/adapter-cn.md",
    "chars": 1055,
    "preview": "# Adapter\n\n-   我们在基础 Component 的概念外,额外增加了一种组件化的抽象 Adapter。它的目标是解决 Component 模型在 ListView 的场景下的 3 个问题\n    -   1)将一个\"Big-C"
  },
  {
    "path": "doc/concept/adapter.md",
    "chars": 1792,
    "preview": "# Adapter\n\n-   In addition to the concept of the underlying Component, we have added a componentized abstract Adapter. I"
  },
  {
    "path": "doc/concept/auto-dispose-cn.md",
    "chars": 916,
    "preview": "# Auto-Dispose\n\n-   它是一个非常简易管理生命周期对象的方式。一个 auto-dispose 对象可以自我主动释放,或者在它 follow 的 托管对象释放的时候,释放。\n-   在 Effect 中使用的 Context"
  },
  {
    "path": "doc/concept/auto-dispose.md",
    "chars": 1102,
    "preview": "# Auto-Dispose\n\n-   AutoDispose is a very simple way to manage lifecycle objects. An auto-dispose object can be released"
  },
  {
    "path": "doc/concept/component-cn.md",
    "chars": 573,
    "preview": "# Component\n\n组件是对视图展现和逻辑功能的封装。\n面向当下,从 Redux 的视角看,我们对组件分为状态修改的功能(Reducer)和其他。\n面向未来,从 UI-Automation 的视角看,我们对组件分为展现表达和其他。\n结"
  },
  {
    "path": "doc/concept/component.md",
    "chars": 1068,
    "preview": "# Component\n\nComponent is the encapsulation of view presentation and logic functions.\nFor the moment, from the perspecti"
  },
  {
    "path": "doc/concept/connector-cn.md",
    "chars": 724,
    "preview": "# Connector<T, P>\n\n-   它表达了如何从一个大数据中读取小数据,同时对小数据的修改如何同步给大数据,这样的数据连接关系。\n-   它是将一个集中式的 Reducer,可以由多层次多模块的小 Reducer 自动拼装的关键"
  },
  {
    "path": "doc/concept/connector.md",
    "chars": 1167,
    "preview": "# Connector<T, P>\n\n-   It expresses a data connection relationship of how to read small data from a big data, and how to"
  },
  {
    "path": "doc/concept/custom-adapter-cn.md",
    "chars": 1197,
    "preview": "# CustomAdapter\n\n-   对大 Cell 的自定义实现\n-   要素和 Component 类似,不一样的地方是 Adapter 的视图部分返回的是一个 ListAdapter\n-   示例代码\n\n```dart\nclass"
  },
  {
    "path": "doc/concept/custom-adapter.md",
    "chars": 1314,
    "preview": "# CustomAdapter\n\n-   Custom implementation of large Cell in LisView.\n-   The Factors of the Adapter are similar to the C"
  },
  {
    "path": "doc/concept/dependencies-cn.md",
    "chars": 1641,
    "preview": "# Dependencies\n\n-   Dependencies 是一个表达组件之间依赖关系的结构。它接收两个字段\n    -   slots\n        -   <String, [Dependent](dependent-cn.md"
  },
  {
    "path": "doc/concept/dependencies.md",
    "chars": 1884,
    "preview": "# Dependencies\n\n-   Dependencies is a structure that expresses dependencies between components. It accepts two fields\n  "
  },
  {
    "path": "doc/concept/dependent-cn.md",
    "chars": 142,
    "preview": "### Dependent\n\n-   Dependent = connector<T, P> + subComponent | subAdapter 的组合,它表达了小组件|小适配器是如何连接到 Component 的。\n-   示例代码\n"
  },
  {
    "path": "doc/concept/dependent.md",
    "chars": 205,
    "preview": "### Dependent\n\n-   Dependent = connector<T, P> + subComponent | subAdapter\n-   It expresses how the small component or a"
  },
  {
    "path": "doc/concept/directory-cn.md",
    "chars": 649,
    "preview": "# Directory\n\n推荐的目录结构会是这样\n\n```\nsample_page\n    -- action.dart /// define action types and action creator\n    -- page.dart"
  },
  {
    "path": "doc/concept/directory.md",
    "chars": 757,
    "preview": "# Directory\n\nThe recommended directory structure\n\n```\nsample_page\n    -- action.dart /// define action types and action "
  },
  {
    "path": "doc/concept/dynamic-flow-adapter-cn.md",
    "chars": 522,
    "preview": "# DynamicFlowAdapter\n\n-   模版是一个 Map,接受一个数组类型的数据驱动\n-   示例代码\n\n```dart\nclass RecommendAdapter extends DynamicFlowAdapter<Re"
  },
  {
    "path": "doc/concept/dynamic-flow-adapter.md",
    "chars": 567,
    "preview": "# DynamicFlowAdapter\n\n-   The template is a Map that accepts an array-like data driven\n-   Sample Code\n\n```dart\nclass Re"
  },
  {
    "path": "doc/concept/effect-cn.md",
    "chars": 2482,
    "preview": "# Effect\n\nEffect顾名思义,用于处理Action的副作用。\n\n我估摸着有人就要问我了,副作用是啥玩意?\n\n打个比方吧,假如我拥有一个函数 `f()`\n\n```text\nfn f(x):\n  return x * 1\n```\n\n"
  },
  {
    "path": "doc/concept/effect.md",
    "chars": 2350,
    "preview": "# Effect\n\n-   Effect is a function that handles all side effects. It receives the following parameters\n    -   Action ac"
  },
  {
    "path": "doc/concept/evolution-of-fish-redux.md",
    "chars": 964,
    "preview": "# fish-redux 的演进史\n\nfish-redux 是一个不断演进的框架,甚至是在不断的回炉重造,在这个过程中\n\n<img src=\"https://img.alicdn.com/tfs/TB1aeJELpzqK1RjSZFCXXb"
  },
  {
    "path": "doc/concept/features.md",
    "chars": 1460,
    "preview": "# Features\n\n## 直接使用 flutter 会面临的问题?\n\n> [flutter](https://github.com/flutter/flutter) 是 google 推出的新一代跨平台渲染框架.\n> 它帮助开发者解决了"
  },
  {
    "path": "doc/concept/filter-cn.md",
    "chars": 295,
    "preview": "# Filter\n\n-   Filter 是用来优化 Reducer 的性能的。因为 Reducer 是层层组装的,所以处理每一个 Action,理论上会遍历一遍所有的小 Reducer,在一些非常复杂的场景下,这样的一次深度遍历的耗时可能"
  },
  {
    "path": "doc/concept/filter.md",
    "chars": 594,
    "preview": "# Filter\n\n-   Filter is used to optimize the performance of the Reducer. Because the Reducer is layer-assembled, each Ac"
  },
  {
    "path": "doc/concept/higher-effect-cn.md",
    "chars": 292,
    "preview": "# HigherEffect\n\n-   由于 Effect 有可能有自己一些临时状态(尽管不建议这么做,但还是提供了支持),为了支持这个特性,我们将 Effect 提升为高阶函数,将它的状态放在闭包里。\n-   框架支持 Effect|Hi"
  },
  {
    "path": "doc/concept/higher-effect.md",
    "chars": 641,
    "preview": "# HigherEffect\n\n-   Since Effect may have some temporary state of its own (although it is not recommended, support is pr"
  },
  {
    "path": "doc/concept/lifecycle-cn.md",
    "chars": 423,
    "preview": "# Lifecycle\n\n-   默认的所有生命周期,本质上都来自于 flutter State<StatefulWidget> 中的生命周期。\n    -   initState\n    -   didChangeDependencies"
  },
  {
    "path": "doc/concept/lifecycle.md",
    "chars": 842,
    "preview": "# Lifecycle\n\n-   The default all lifecycles are essentially derived from the lifecycle in flutter State<StatefulWidget>."
  },
  {
    "path": "doc/concept/mechanism-cn.md",
    "chars": 1097,
    "preview": "# Communication Mechanism\n\n## 页面内通信\n\n-   组件|适配器内通信\n-   组件|适配器间内通信\n\n![image.png | left | 747x399](https://cdn.nlark.com/l"
  },
  {
    "path": "doc/concept/mechanism.md",
    "chars": 1421,
    "preview": "# Communication Mechanism\n\n## Page internal communication\n\n-   Component internal communication\n-   Inter-component comm"
  },
  {
    "path": "doc/concept/middleware-cn.md",
    "chars": 1053,
    "preview": "# Middleware\n\n关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。\n\n示例代码\n\n```dart\nMiddleware<T> logMiddleware<T>({\n  String tag = 'redu"
  },
  {
    "path": "doc/concept/middleware.md",
    "chars": 1114,
    "preview": "# Middleware\n\n-   The definition and signature of Middleware is consistent with the ReduxJS community.\n-   Sample Code\n\n"
  },
  {
    "path": "doc/concept/on-error-cn.md",
    "chars": 518,
    "preview": "# OnError\n\n-   集中处理由 Effect 产生的业务异常,无论是同步函数还是异步函数。有了统一的异常处理机制,我们就能站在一个更高的抽象角度,对业务代码做出合理的简化。\n-   示例代码\n\n```dart\nbool onMes"
  },
  {
    "path": "doc/concept/on-error.md",
    "chars": 716,
    "preview": "# OnError\n\n-   Centralizes the business exceptions generated by Effect, whether it is a synchronous function or an async"
  },
  {
    "path": "doc/concept/oop-cn.md",
    "chars": 1475,
    "preview": "# OOP\n\n-   虽然框架推荐使用的函数式的编程方式,也提供面向对象式的编程方式的支持。\n    -   ViewPart\n        -   需要复写 build 函数。\n        -   需要的 state,dispatc"
  },
  {
    "path": "doc/concept/oop.md",
    "chars": 1834,
    "preview": "# OOP\n\n-   Although the framework recommends the use of functional programming, it also provides object-oriented program"
  },
  {
    "path": "doc/concept/page-cn.md",
    "chars": 554,
    "preview": "# Page\n\n-   一个页面内都有且仅有一个 Store\n-   Page 继承于 Component,所以它能配置所有 Component 的要素\n-   Page 能配置 Middleware,用于对 Redux 做 AOP 管理\n"
  },
  {
    "path": "doc/concept/page.md",
    "chars": 693,
    "preview": "# Page\n\n-   One and only one store in one page\n-   Page inherits from Component, so it can configure all the factors of "
  },
  {
    "path": "doc/concept/reducer-cn.md",
    "chars": 1063,
    "preview": "# Reducer\n\n-   Reducer 是一个上下文无关的 pure function。它接收下面的参数\n    -   T state\n    -   Action action\n-   它主要包含三方面的信息\n    -   接收"
  },
  {
    "path": "doc/concept/reducer.md",
    "chars": 1374,
    "preview": "# Reducer\n\n-   The Reducer is a context-independent pure function. It receives the following parameters\n    -   T state\n"
  },
  {
    "path": "doc/concept/redux-cn.md",
    "chars": 281,
    "preview": "### Redux\n\n-   State\n-   [Action](action-cn.md)\n-   [Reducer](reducer-cn.md)\n-   Store\n-   [Middleware](middleware-cn.md"
  },
  {
    "path": "doc/concept/redux.md",
    "chars": 433,
    "preview": "### Redux\n\n-   State\n-   [Action](action.md)\n-   [Reducer](reducer.md)\n-   Store\n-   [Middleware](middleware.md)\n    The"
  },
  {
    "path": "doc/concept/should-update-cn.md",
    "chars": 255,
    "preview": "# ShouldUpdate\n\n-   当数据发生变更,Store 扁平化地通知所有组件\n-   框架默认使用 identical 比较新旧两份数据来决定是否需要刷新。\n-   如果我们对组件的刷新会有非常精确化的诉求, 那么我们可以自己定"
  },
  {
    "path": "doc/concept/should-update.md",
    "chars": 435,
    "preview": "# ShouldUpdate\n\n-   When the state changes, the store flatly notifies all the components.\n-   By default, the framework "
  },
  {
    "path": "doc/concept/static-flow-adapter-cn.md",
    "chars": 1445,
    "preview": "# StaticFlowAdapter\n\n-   模版是一个 Array,接受 Object|Map 的数据驱动。\n-   模版接收一个 Dependent 的数组,每一个 Dependent 可以是 Component 或者 Adapte"
  },
  {
    "path": "doc/concept/static-flow-adapter.md",
    "chars": 1466,
    "preview": "# StaticFlowAdapter\n\n-   The template is an Array that accepts map-like data driven.\n-   The template receives an array "
  },
  {
    "path": "doc/concept/view-cn.md",
    "chars": 1030,
    "preview": "# View\n\n-   View 是一个输出 Widget 的上下文无关的函数。它接收下面的参数\n    -   T state\n    -   Dispatch\n    -   ViewService\n-   它主要包含三方面的信息\n  "
  },
  {
    "path": "doc/concept/view.md",
    "chars": 1611,
    "preview": "# View\n\n-   View is a context-independent function that outputs Widget. It receives the following parameters\n    -   T s"
  },
  {
    "path": "doc/concept/what's-adapter.md",
    "chars": 1060,
    "preview": "# What's adapter\n\n面向 ListView 场景的分治设计 Adapter。\n\n> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更"
  },
  {
    "path": "doc/concept/what's-connector.md",
    "chars": 1184,
    "preview": "# What's connector\n\n在解答 connector 是什么之前,我们来先看一个代码片段\n\n```javascript\nlet hasChanged = false;\nconst nextState = {};\nfor (le"
  },
  {
    "path": "doc/concept/what's-the-diiference-cn.md",
    "chars": 843,
    "preview": "# What's different with Redux ?\n\n## 它们是解决不同层面问题的两个框架\n\n> Redux 是一个专注于状态管理的框架;Fish Redux 是基于 Redux 做状态管理的应用框架。\n\n> 应用框架不仅仅要"
  },
  {
    "path": "doc/concept/what's-the-diiference.md",
    "chars": 1529,
    "preview": "# What's different with Redux ?\n\n## They are two frameworks for solving problems at different layers.\n\n> Redux is a fram"
  },
  {
    "path": "doc/concept/widget-wrapper-cn.md",
    "chars": 308,
    "preview": "### WidgetWrapper\n\n-   它用来解决 flutter 的 ui 体系下,一些需要实现特色接口的 Widget,比如 KeepAlive,因为通过 Component 产生的 Widget 会被一个框架内部的 Statef"
  },
  {
    "path": "doc/concept/widget-wrapper.md",
    "chars": 433,
    "preview": "### WidgetWrapper\n\n-   It is used to solve flutter's ui system, some Widgets that need to implement the featured interfa"
  },
  {
    "path": "doc/introduction/README-cn.md",
    "chars": 315,
    "preview": "# 简介\n\nFish Redux 是一个基于 Redux 数据管理的组装式 flutter 应用框架, 它特别适用于构建中大型的复杂应用。\n\n它的特点是配置式组装。\n一方面我们将一个大的页面,对视图和数据层层拆解为互相独立的 Compone"
  },
  {
    "path": "doc/introduction/README.md",
    "chars": 812,
    "preview": "# Introduction\n\nFish Redux is an assembled flutter application framework based on Redux state management, it is especial"
  },
  {
    "path": "docs/.nojekyll",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/README.md",
    "chars": 2410,
    "preview": "<p align=\"center\"><img src=\"https://img.alicdn.com/tfs/TB1r74NJyLaK1RjSZFxXXamPFXa-1024-1024.png\" align=\"center\" width=\""
  },
  {
    "path": "docs/_navbar.md",
    "chars": 26,
    "preview": "* [En](/)\n* [中文](/zh-cn/)\n"
  },
  {
    "path": "docs/_sidebar.md",
    "chars": 1096,
    "preview": "* [Redux](concept/redux.md)\n* [Action](concept/action.md)\n* [Connector](concept/connector.md)\n* [Reducer](concept/reduce"
  },
  {
    "path": "docs/concept/_navbar.md",
    "chars": 26,
    "preview": "* [En](/)\n* [中文](/zh-cn/)\n"
  },
  {
    "path": "docs/concept/_sidebar.md",
    "chars": 1096,
    "preview": "* [Redux](concept/redux.md)\n* [Action](concept/action.md)\n* [Connector](concept/connector.md)\n* [Reducer](concept/reduce"
  },
  {
    "path": "docs/concept/action.md",
    "chars": 834,
    "preview": "# Action\n\n-   Action contains two fields\n    -   type\n    -   payload\n-   Recommended way of writing action\n    -   Crea"
  },
  {
    "path": "docs/concept/adapter.md",
    "chars": 1792,
    "preview": "# Adapter\n\n-   In addition to the concept of the underlying Component, we have added a componentized abstract Adapter. I"
  },
  {
    "path": "docs/concept/auto-dispose.md",
    "chars": 1102,
    "preview": "# Auto-Dispose\n\n-   AutoDispose is a very simple way to manage lifecycle objects. An auto-dispose object can be released"
  },
  {
    "path": "docs/concept/component.md",
    "chars": 1068,
    "preview": "# Component\n\nComponent is the encapsulation of view presentation and logic functions.\nFor the moment, from the perspecti"
  },
  {
    "path": "docs/concept/connector.md",
    "chars": 1167,
    "preview": "# Connector<T, P>\n\n-   It expresses a data connection relationship of how to read small data from a big data, and how to"
  },
  {
    "path": "docs/concept/custom-adapter.md",
    "chars": 1314,
    "preview": "# CustomAdapter\n\n-   Custom implementation of large Cell in LisView.\n-   The Factors of the Adapter are similar to the C"
  },
  {
    "path": "docs/concept/dependencies.md",
    "chars": 1884,
    "preview": "# Dependencies\n\n-   Dependencies is a structure that expresses dependencies between components. It accepts two fields\n  "
  },
  {
    "path": "docs/concept/dependent.md",
    "chars": 205,
    "preview": "### Dependent\n\n-   Dependent = connector<T, P> + subComponent | subAdapter\n-   It expresses how the small component or a"
  },
  {
    "path": "docs/concept/directory.md",
    "chars": 757,
    "preview": "# Directory\n\nThe recommended directory structure\n\n```\nsample_page\n    -- action.dart /// define action types and action "
  },
  {
    "path": "docs/concept/dynamic-flow-adapter.md",
    "chars": 567,
    "preview": "# DynamicFlowAdapter\n\n-   The template is a Map that accepts an array-like data driven\n-   Sample Code\n\n```dart\nclass Re"
  },
  {
    "path": "docs/concept/effect.md",
    "chars": 2350,
    "preview": "# Effect\n\n-   Effect is a function that handles all side effects. It receives the following parameters\n    -   Action ac"
  },
  {
    "path": "docs/concept/evolution-of-fish-redux.md",
    "chars": 964,
    "preview": "# fish-redux 的演进史\n\nfish-redux 是一个不断演进的框架,甚至是在不断的回炉重造,在这个过程中\n\n<img src=\"https://img.alicdn.com/tfs/TB1aeJELpzqK1RjSZFCXXb"
  },
  {
    "path": "docs/concept/features.md",
    "chars": 1460,
    "preview": "# Features\n\n## 直接使用 flutter 会面临的问题?\n\n> [flutter](https://github.com/flutter/flutter) 是 google 推出的新一代跨平台渲染框架.\n> 它帮助开发者解决了"
  },
  {
    "path": "docs/concept/filter.md",
    "chars": 594,
    "preview": "# Filter\n\n-   Filter is used to optimize the performance of the Reducer. Because the Reducer is layer-assembled, each Ac"
  },
  {
    "path": "docs/concept/higher-effect.md",
    "chars": 641,
    "preview": "# HigherEffect\n\n-   Since Effect may have some temporary state of its own (although it is not recommended, support is pr"
  },
  {
    "path": "docs/concept/lifecycle.md",
    "chars": 842,
    "preview": "# Lifecycle\n\n-   The default all lifecycles are essentially derived from the lifecycle in flutter State<StatefulWidget>."
  },
  {
    "path": "docs/concept/mechanism.md",
    "chars": 1421,
    "preview": "# Communication Mechanism\n\n## Page internal communication\n\n-   Component internal communication\n-   Inter-component comm"
  },
  {
    "path": "docs/concept/middleware-cn.md",
    "chars": 1053,
    "preview": "# Middleware\n\n关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。\n\n示例代码\n\n```dart\nMiddleware<T> logMiddleware<T>({\n  String tag = 'redu"
  },
  {
    "path": "docs/concept/middleware.md",
    "chars": 1114,
    "preview": "# Middleware\n\n-   The definition and signature of Middleware is consistent with the ReduxJS community.\n-   Sample Code\n\n"
  },
  {
    "path": "docs/concept/on-error.md",
    "chars": 716,
    "preview": "# OnError\n\n-   Centralizes the business exceptions generated by Effect, whether it is a synchronous function or an async"
  },
  {
    "path": "docs/concept/oop.md",
    "chars": 1834,
    "preview": "# OOP\n\n-   Although the framework recommends the use of functional programming, it also provides object-oriented program"
  },
  {
    "path": "docs/concept/page.md",
    "chars": 693,
    "preview": "# Page\n\n-   One and only one store in one page\n-   Page inherits from Component, so it can configure all the factors of "
  },
  {
    "path": "docs/concept/reducer.md",
    "chars": 1374,
    "preview": "# Reducer\n\n-   The Reducer is a context-independent pure function. It receives the following parameters\n    -   T state\n"
  },
  {
    "path": "docs/concept/redux.md",
    "chars": 433,
    "preview": "### Redux\n\n-   State\n-   [Action](action.md)\n-   [Reducer](reducer.md)\n-   Store\n-   [Middleware](middleware.md)\n    The"
  },
  {
    "path": "docs/concept/should-update.md",
    "chars": 435,
    "preview": "# ShouldUpdate\n\n-   When the state changes, the store flatly notifies all the components.\n-   By default, the framework "
  },
  {
    "path": "docs/concept/static-flow-adapter.md",
    "chars": 1466,
    "preview": "# StaticFlowAdapter\n\n-   The template is an Array that accepts map-like data driven.\n-   The template receives an array "
  },
  {
    "path": "docs/concept/view.md",
    "chars": 1611,
    "preview": "# View\n\n-   View is a context-independent function that outputs Widget. It receives the following parameters\n    -   T s"
  },
  {
    "path": "docs/concept/what's-adapter.md",
    "chars": 1060,
    "preview": "# What's adapter\n\n面向 ListView 场景的分治设计 Adapter。\n\n> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更"
  },
  {
    "path": "docs/concept/what's-connector.md",
    "chars": 1184,
    "preview": "# What's connector\n\n在解答 connector 是什么之前,我们来先看一个代码片段\n\n```javascript\nlet hasChanged = false;\nconst nextState = {};\nfor (le"
  },
  {
    "path": "docs/concept/what's-the-diiference.md",
    "chars": 1529,
    "preview": "# What's different with Redux ?\n\n## They are two frameworks for solving problems at different layers.\n\n> Redux is a fram"
  },
  {
    "path": "docs/concept/widget-wrapper.md",
    "chars": 427,
    "preview": "### WidgetWrapper\n\n-   It is used to solve flutter's ui system, some Widgets that need to implement the featured interfa"
  },
  {
    "path": "docs/index.html",
    "chars": 1889,
    "preview": "<!DOCTYPE html>\r\n<html lang=\"en\">\r\n<head>\r\n  <meta charset=\"UTF-8\">\r\n  <title>Document</title>\r\n  <meta http-equiv=\"X-UA"
  },
  {
    "path": "docs/zh-cn/README.md",
    "chars": 1565,
    "preview": "\n-   **核心概念**\n    -   [Redux](/zh-cn/concept/redux.md)\n        -   [Action](/zh-cn/concept/action.md)\n        -   [Conne"
  },
  {
    "path": "docs/zh-cn/_sidebar.md",
    "chars": 1265,
    "preview": "\n* [Redux](zh-cn/concept/redux.md)\n* [Action](zh-cn/concept/action.md)\n* [Connector](zh-cn/concept/connector.md)\n* [Redu"
  },
  {
    "path": "docs/zh-cn/concept/_navbar.md",
    "chars": 26,
    "preview": "* [En](/)\n* [中文](/zh-cn/)\n"
  },
  {
    "path": "docs/zh-cn/concept/_sidebar.md",
    "chars": 1265,
    "preview": "\n* [Redux](zh-cn/concept/redux.md)\n* [Action](zh-cn/concept/action.md)\n* [Connector](zh-cn/concept/connector.md)\n* [Redu"
  },
  {
    "path": "docs/zh-cn/concept/action.md",
    "chars": 605,
    "preview": "# Action\n\n-   Action 包含两个字段\n    -   type\n    -   payload\n-   推荐的写法是\n    -   为一个组件|适配器创建一个 action.dart 文件,包含两个类\n        -"
  },
  {
    "path": "docs/zh-cn/concept/adapter.md",
    "chars": 1055,
    "preview": "# Adapter\n\n-   我们在基础 Component 的概念外,额外增加了一种组件化的抽象 Adapter。它的目标是解决 Component 模型在 ListView 的场景下的 3 个问题\n    -   1)将一个\"Big-C"
  },
  {
    "path": "docs/zh-cn/concept/auto-dispose.md",
    "chars": 916,
    "preview": "# Auto-Dispose\n\n-   它是一个非常简易管理生命周期对象的方式。一个 auto-dispose 对象可以自我主动释放,或者在它 follow 的 托管对象释放的时候,释放。\n-   在 Effect 中使用的 Context"
  },
  {
    "path": "docs/zh-cn/concept/component.md",
    "chars": 573,
    "preview": "# Component\n\n组件是对视图展现和逻辑功能的封装。\n面向当下,从 Redux 的视角看,我们对组件分为状态修改的功能(Reducer)和其他。\n面向未来,从 UI-Automation 的视角看,我们对组件分为展现表达和其他。\n结"
  },
  {
    "path": "docs/zh-cn/concept/connector.md",
    "chars": 724,
    "preview": "# Connector<T, P>\n\n-   它表达了如何从一个大数据中读取小数据,同时对小数据的修改如何同步给大数据,这样的数据连接关系。\n-   它是将一个集中式的 Reducer,可以由多层次多模块的小 Reducer 自动拼装的关键"
  },
  {
    "path": "docs/zh-cn/concept/custom-adapter.md",
    "chars": 1197,
    "preview": "# CustomAdapter\n\n-   对大 Cell 的自定义实现\n-   要素和 Component 类似,不一样的地方是 Adapter 的视图部分返回的是一个 ListAdapter\n-   示例代码\n\n```dart\nclass"
  },
  {
    "path": "docs/zh-cn/concept/dependencies.md",
    "chars": 1641,
    "preview": "# Dependencies\n\n-   Dependencies 是一个表达组件之间依赖关系的结构。它接收两个字段\n    -   slots\n        -   <String, [Dependent](dependent-cn.md"
  },
  {
    "path": "docs/zh-cn/concept/dependent.md",
    "chars": 142,
    "preview": "### Dependent\n\n-   Dependent = connector<T, P> + subComponent | subAdapter 的组合,它表达了小组件|小适配器是如何连接到 Component 的。\n-   示例代码\n"
  },
  {
    "path": "docs/zh-cn/concept/directory.md",
    "chars": 649,
    "preview": "# Directory\n\n推荐的目录结构会是这样\n\n```\nsample_page\n    -- action.dart /// define action types and action creator\n    -- page.dart"
  },
  {
    "path": "docs/zh-cn/concept/dynamic-flow-adapter.md",
    "chars": 522,
    "preview": "# DynamicFlowAdapter\n\n-   模版是一个 Map,接受一个数组类型的数据驱动\n-   示例代码\n\n```dart\nclass RecommendAdapter extends DynamicFlowAdapter<Re"
  },
  {
    "path": "docs/zh-cn/concept/effect.md",
    "chars": 2482,
    "preview": "# Effect\n\nEffect顾名思义,用于处理Action的副作用。\n\n我估摸着有人就要问我了,副作用是啥玩意?\n\n打个比方吧,假如我拥有一个函数 `f()`\n\n```text\nfn f(x):\n  return x * 1\n```\n\n"
  },
  {
    "path": "docs/zh-cn/concept/filter.md",
    "chars": 295,
    "preview": "# Filter\n\n-   Filter 是用来优化 Reducer 的性能的。因为 Reducer 是层层组装的,所以处理每一个 Action,理论上会遍历一遍所有的小 Reducer,在一些非常复杂的场景下,这样的一次深度遍历的耗时可能"
  },
  {
    "path": "docs/zh-cn/concept/higher-effect.md",
    "chars": 292,
    "preview": "# HigherEffect\n\n-   由于 Effect 有可能有自己一些临时状态(尽管不建议这么做,但还是提供了支持),为了支持这个特性,我们将 Effect 提升为高阶函数,将它的状态放在闭包里。\n-   框架支持 Effect|Hi"
  },
  {
    "path": "docs/zh-cn/concept/lifecycle.md",
    "chars": 423,
    "preview": "# Lifecycle\n\n-   默认的所有生命周期,本质上都来自于 flutter State<StatefulWidget> 中的生命周期。\n    -   initState\n    -   didChangeDependencies"
  },
  {
    "path": "docs/zh-cn/concept/mechanism.md",
    "chars": 1097,
    "preview": "# Communication Mechanism\n\n## 页面内通信\n\n-   组件|适配器内通信\n-   组件|适配器间内通信\n\n![image.png | left | 747x399](https://cdn.nlark.com/l"
  },
  {
    "path": "docs/zh-cn/concept/middleware.md",
    "chars": 1053,
    "preview": "# Middleware\n\n关于 Middleware 的定义、签名和 ReduxJS 社区是一致的。\n\n示例代码\n\n```dart\nMiddleware<T> logMiddleware<T>({\n  String tag = 'redu"
  },
  {
    "path": "docs/zh-cn/concept/on-error.md",
    "chars": 518,
    "preview": "# OnError\n\n-   集中处理由 Effect 产生的业务异常,无论是同步函数还是异步函数。有了统一的异常处理机制,我们就能站在一个更高的抽象角度,对业务代码做出合理的简化。\n-   示例代码\n\n```dart\nbool onMes"
  },
  {
    "path": "docs/zh-cn/concept/oop.md",
    "chars": 1475,
    "preview": "# OOP\n\n-   虽然框架推荐使用的函数式的编程方式,也提供面向对象式的编程方式的支持。\n    -   ViewPart\n        -   需要复写 build 函数。\n        -   需要的 state,dispatc"
  },
  {
    "path": "docs/zh-cn/concept/page.md",
    "chars": 554,
    "preview": "# Page\n\n-   一个页面内都有且仅有一个 Store\n-   Page 继承于 Component,所以它能配置所有 Component 的要素\n-   Page 能配置 Middleware,用于对 Redux 做 AOP 管理\n"
  },
  {
    "path": "docs/zh-cn/concept/reducer.md",
    "chars": 1063,
    "preview": "# Reducer\n\n-   Reducer 是一个上下文无关的 pure function。它接收下面的参数\n    -   T state\n    -   Action action\n-   它主要包含三方面的信息\n    -   接收"
  },
  {
    "path": "docs/zh-cn/concept/redux.md",
    "chars": 281,
    "preview": "### Redux\n\n-   State\n-   [Action](action-cn.md)\n-   [Reducer](reducer-cn.md)\n-   Store\n-   [Middleware](middleware-cn.md"
  },
  {
    "path": "docs/zh-cn/concept/should-update.md",
    "chars": 255,
    "preview": "# ShouldUpdate\n\n-   当数据发生变更,Store 扁平化地通知所有组件\n-   框架默认使用 identical 比较新旧两份数据来决定是否需要刷新。\n-   如果我们对组件的刷新会有非常精确化的诉求, 那么我们可以自己定"
  },
  {
    "path": "docs/zh-cn/concept/static-flow-adapter.md",
    "chars": 1445,
    "preview": "# StaticFlowAdapter\n\n-   模版是一个 Array,接受 Object|Map 的数据驱动。\n-   模版接收一个 Dependent 的数组,每一个 Dependent 可以是 Component 或者 Adapte"
  },
  {
    "path": "docs/zh-cn/concept/view.md",
    "chars": 1030,
    "preview": "# View\n\n-   View 是一个输出 Widget 的上下文无关的函数。它接收下面的参数\n    -   T state\n    -   Dispatch\n    -   ViewService\n-   它主要包含三方面的信息\n  "
  },
  {
    "path": "docs/zh-cn/concept/what's-adapter.md",
    "chars": 1060,
    "preview": "# What's adapter\n\n面向 ListView 场景的分治设计 Adapter。\n\n> 在解答什么是 adapter 之前,我们来看下一般框架对 ListView 的分治是怎么做的。传统的手段,我们对 ListView 的分治更"
  },
  {
    "path": "docs/zh-cn/concept/what's-connector.md",
    "chars": 1184,
    "preview": "# What's connector\n\n在解答 connector 是什么之前,我们来先看一个代码片段\n\n```javascript\nlet hasChanged = false;\nconst nextState = {};\nfor (le"
  },
  {
    "path": "docs/zh-cn/concept/what's-the-diiference.md",
    "chars": 843,
    "preview": "# What's different with Redux ?\n\n## 它们是解决不同层面问题的两个框架\n\n> Redux 是一个专注于状态管理的框架;Fish Redux 是基于 Redux 做状态管理的应用框架。\n\n> 应用框架不仅仅要"
  },
  {
    "path": "docs/zh-cn/concept/widget-wrapper.md",
    "chars": 302,
    "preview": "### WidgetWrapper\n\n-   它用来解决 flutter 的 ui 体系下,一些需要实现特色接口的 Widget,比如 KeepAlive,因为通过 Component 产生的 Widget 会被一个框架内部的 Statef"
  },
  {
    "path": "example/.flutter-plugins-dependencies",
    "chars": 536,
    "preview": "{\"info\":\"This is a generated file; do not edit or check into version control.\",\"plugins\":{\"ios\":[{\"name\":\"path_provider\""
  },
  {
    "path": "example/.gitignore",
    "chars": 1294,
    "preview": "# Miscellaneous\n*.class\n*.lock\n*.log\n*.pyc\n*.swp\n.DS_Store\n.atom/\n.buildlog/\n.history\n.svn/\n\n# IntelliJ related\n*.iml\n*."
  },
  {
    "path": "example/.metadata",
    "chars": 305,
    "preview": "# This file tracks properties of this Flutter project.\n# Used by Flutter tool to assess capabilities and perform upgrade"
  },
  {
    "path": "example/README.md",
    "chars": 535,
    "preview": "# sample\n\nA new Flutter project.\n\n## Getting Started\n\nThis project is a starting point for a Flutter application.\n\nA few"
  },
  {
    "path": "example/lib/app.dart",
    "chars": 3003,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'global_s"
  },
  {
    "path": "example/lib/global_store/action.dart",
    "chars": 215,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nenum GlobalAction { changeThemeColor }\n\nclass GlobalActionCreator {\n  stat"
  },
  {
    "path": "example/lib/global_store/reducer.dart",
    "chars": 638,
    "preview": "import 'dart:ui';\n\nimport 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page"
  },
  {
    "path": "example/lib/global_store/state.dart",
    "chars": 328,
    "preview": "import 'dart:ui';\n\nimport 'package:fish_redux/fish_redux.dart';\n\nabstract class GlobalBaseState {\n  Color get themeColor"
  },
  {
    "path": "example/lib/global_store/store.dart",
    "chars": 310,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'reducer.dart';\nimport 'state.dart';\n\n/// 建立一个AppStore\n/// 目前它的功能只有切"
  },
  {
    "path": "example/lib/main.dart",
    "chars": 115,
    "preview": "import 'package:flutter/material.dart' hide Action, Page;\n\nimport 'app.dart';\n\nvoid main() => runApp(createApp());\n"
  },
  {
    "path": "example/lib/todo_edit_page/action.dart",
    "chars": 298,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nenum ToDoEditAction { onDone, onChangeTheme }\n\nclass ToDoEditActionCreator"
  },
  {
    "path": "example/lib/todo_edit_page/effect.dart",
    "chars": 847,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport '../globa"
  },
  {
    "path": "example/lib/todo_edit_page/page.dart",
    "chars": 514,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../todo_list_page/todo_component/component.dart';\nimport 'effect.d"
  },
  {
    "path": "example/lib/todo_edit_page/state.dart",
    "chars": 1132,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport '../globa"
  },
  {
    "path": "example/lib/todo_edit_page/view.dart",
    "chars": 3477,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'action.d"
  },
  {
    "path": "example/lib/todo_list_page/action.dart",
    "chars": 350,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'todo_component/component.dart';\n\nenum PageAction { initToDos, onAdd"
  },
  {
    "path": "example/lib/todo_list_page/effect.dart",
    "chars": 1346,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'action.d"
  },
  {
    "path": "example/lib/todo_list_page/flow_adapter/adapter.dart",
    "chars": 512,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../state.dart';\nimport '../todo_component/component.dart';\nimport "
  },
  {
    "path": "example/lib/todo_list_page/flow_adapter/connector.dart",
    "chars": 487,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../state.dart';\nimport '../todo_component/component.dart';\n\nclass "
  },
  {
    "path": "example/lib/todo_list_page/flow_adapter/reducer.dart",
    "chars": 756,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../list_adapter/action.dart';\nimport '../state.dart';\nimport '../t"
  },
  {
    "path": "example/lib/todo_list_page/list_adapter/action.dart",
    "chars": 248,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport '../todo_component/component.dart';\n\nenum ToDoListAction { add }\n\ncl"
  },
  {
    "path": "example/lib/todo_list_page/list_adapter/adapter.dart",
    "chars": 376,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../state.dart';\nimport '../todo_component/component.dart';\nimport "
  },
  {
    "path": "example/lib/todo_list_page/list_adapter/reducer.dart",
    "chars": 740,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../state.dart';\nimport '../todo_component/action.dart' as todo_act"
  },
  {
    "path": "example/lib/todo_list_page/page.dart",
    "chars": 923,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport 'effect.dart';\nimport 'list_adapter/adapter.dart';\nimport 'flow_ada"
  },
  {
    "path": "example/lib/todo_list_page/reducer.dart",
    "chars": 487,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport 'action.dart';\nimport 'state.dart';\nimport 'todo_component/componen"
  },
  {
    "path": "example/lib/todo_list_page/report_component/component.dart",
    "chars": 240,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport 'state.dart';\nimport 'view.dart';\n\nexport 'state.dart';\n\nclass Repo"
  },
  {
    "path": "example/lib/todo_list_page/report_component/state.dart",
    "chars": 378,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nclass ReportState implements Cloneable<ReportState> {\n  int total;\n  int d"
  },
  {
    "path": "example/lib/todo_list_page/report_component/view.dart",
    "chars": 713,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'state.da"
  },
  {
    "path": "example/lib/todo_list_page/state.dart",
    "chars": 1484,
    "preview": "import 'dart:ui';\n\nimport 'package:fish_redux/fish_redux.dart';\nimport '../global_store/state.dart';\nimport 'report_comp"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/action.dart",
    "chars": 693,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'state.dart';\n\nenum ToDoAction { onEdit, edit, done, onRemove, remov"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/component.dart",
    "chars": 347,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport 'effect.dart';\nimport 'reducer.dart';\nimport 'state.dart';\nimport '"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/effect.dart",
    "chars": 1673,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'action.d"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/reducer.dart",
    "chars": 680,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport 'action.dart';\nimport 'state.dart';\n\nReducer<ToDoState> buildReduce"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/state.dart",
    "chars": 632,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n// import 'package:uuid/uuid.dart';\n\nclass ToDoState implements Cloneable<T"
  },
  {
    "path": "example/lib/todo_list_page/todo_component/view.dart",
    "chars": 2521,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'action.d"
  },
  {
    "path": "example/lib/todo_list_page/view.dart",
    "chars": 901,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/material.dart' hide Action, Page;\n\nimport 'action.d"
  },
  {
    "path": "example/pubspec.yaml",
    "chars": 2323,
    "preview": "name: sample\ndescription: Demonstrates how to use the fish_redux.\n\n# The following defines the version and build number "
  },
  {
    "path": "example/test/widget_test.dart",
    "chars": 503,
    "preview": "// This is a basic Flutter widget test.\n//\n// To perform an interaction with a widget in your test, use the WidgetTester"
  },
  {
    "path": "example/web/index.html",
    "chars": 1503,
    "preview": "<!DOCTYPE html>\n<html>\n<head>\n  <!--\n    If you are serving your web app in a path other than the root, change the\n    h"
  },
  {
    "path": "example/web/manifest.json",
    "chars": 570,
    "preview": "{\n    \"name\": \"example\",\n    \"short_name\": \"example\",\n    \"start_url\": \".\",\n    \"display\": \"standalone\",\n    \"background"
  },
  {
    "path": "fish_redux.iml",
    "chars": 15987,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"NewModuleRootManager\" "
  },
  {
    "path": "lib/fish_redux.dart",
    "chars": 453,
    "preview": "export 'src/extensions/extendsions.dart';\nexport 'src/redux/redux.dart';\nexport 'src/redux_adapter/redux_adapter.dart';\n"
  },
  {
    "path": "lib/src/extensions/adapter_extensions.dart",
    "chars": 3696,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/foundation.dart';\n\nimport '../redux/basic.dart';\nim"
  },
  {
    "path": "lib/src/extensions/component_extensions.dart",
    "chars": 1149,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/foundation.dart';\nimport 'package:flutter/widgets.d"
  },
  {
    "path": "lib/src/extensions/connector_extensions.dart",
    "chars": 2457,
    "preview": "import 'package:fish_redux/fish_redux.dart';\n\nimport '../redux/redux.dart';\nimport '../redux_component/basic.dart';\nimpo"
  },
  {
    "path": "lib/src/extensions/extendsions.dart",
    "chars": 106,
    "preview": "export 'adapter_extensions.dart';\nexport 'component_extensions.dart';\nexport 'connector_extensions.dart';\n"
  },
  {
    "path": "lib/src/redux/apply_middleware.dart",
    "chars": 1339,
    "preview": "import 'basic.dart';\n\n/// Accumulate a list of Middleware that enhances Dispatch to the Store.\n/// The wrapped direction"
  },
  {
    "path": "lib/src/redux/basic.dart",
    "chars": 3974,
    "preview": "import 'dart:async';\n\n/// This document describes the core concepts under the Redux system and their standard definition"
  },
  {
    "path": "lib/src/redux/combine_reducers.dart",
    "chars": 1744,
    "preview": "import 'basic.dart';\n\n/// Combine an iterable of SubReducer<T> into one Reducer<T>\nReducer<T> combineSubReducers<T>(Iter"
  },
  {
    "path": "lib/src/redux/connector.dart",
    "chars": 3021,
    "preview": "import 'basic.dart';\n\n/// Define a basic connector for immutable state.\n///     /// Example:\n///     class State {\n///  "
  },
  {
    "path": "lib/src/redux/create_store.dart",
    "chars": 2872,
    "preview": "import 'dart:async';\n\nimport 'basic.dart';\n\nReducer<T> _noop<T>() => (T state, Action action) => state;\n\ntypedef _VoidCa"
  },
  {
    "path": "lib/src/redux/redux.dart",
    "chars": 138,
    "preview": "export 'apply_middleware.dart';\nexport 'basic.dart';\nexport 'combine_reducers.dart';\nexport 'connector.dart';\nexport 'cr"
  },
  {
    "path": "lib/src/redux_adapter/adapter.dart",
    "chars": 2280,
    "preview": "import 'package:flutter/widgets.dart' hide Action, Page;\n\nimport '../redux/redux.dart';\nimport '../redux_component/redux"
  },
  {
    "path": "lib/src/redux_adapter/dynamic_flow_adapter.dart",
    "chars": 5057,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/widgets.dart' hide Action, Page;\n\nimport '../redux/"
  },
  {
    "path": "lib/src/redux_adapter/flow_adapter.dart",
    "chars": 5318,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/widgets.dart' hide Action, Page;\nimport '../redux/r"
  },
  {
    "path": "lib/src/redux_adapter/recycle_context.dart",
    "chars": 4374,
    "preview": "import 'package:flutter/widgets.dart' hide Action, Page;\n\nimport '../redux/redux.dart';\nimport '../redux_component/redux"
  },
  {
    "path": "lib/src/redux_adapter/redux_adapter.dart",
    "chars": 188,
    "preview": "export 'adapter.dart';\nexport 'dynamic_flow_adapter.dart';\nexport 'flow_adapter.dart';\nexport 'recycle_context.dart';\nex"
  },
  {
    "path": "lib/src/redux_adapter/source_flow_adapter.dart",
    "chars": 4956,
    "preview": "import 'package:fish_redux/fish_redux.dart';\nimport 'package:flutter/widgets.dart' hide Action, Page;\n\nimport '../redux/"
  },
  {
    "path": "lib/src/redux_adapter/static_flow_adapter.dart",
    "chars": 2778,
    "preview": "import 'package:flutter/widgets.dart' hide Action, Page;\n\nimport '../redux/redux.dart';\nimport '../redux_component/redux"
  },
  {
    "path": "lib/src/redux_aop/aop.dart",
    "chars": 3600,
    "preview": "typedef TypedApplyLike<R> = R Function(List<dynamic>, [Map<Symbol, dynamic>]);\n\n/// Unified abstraction of functions whi"
  }
]

// ... and 114 more files (download for full content)

About this extraction

This page contains the full source code of the alibaba/fish-redux GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 314 files (554.9 KB), approximately 148.8k tokens, and a symbol index with 833 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!