Skip to content

Commit

Permalink
Merge pull request #19 from filefoxper/3.2.7
Browse files Browse the repository at this point in the history
## v3.2.7 2021-03-16
  • Loading branch information
filefoxper authored Mar 16, 2021
2 parents 34ef557 + ec93997 commit 7d0e687
Show file tree
Hide file tree
Showing 21 changed files with 476 additions and 23 deletions.
7 changes: 6 additions & 1 deletion CHANGE_LOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,9 @@ in this version, `runtime.cache` used in MiddleWare is independent.

## v3.2.2 2021-03-12

* [bug] fix when `use-agent-reducer` update state by its brothers, react throw error: `Cannot update a component (`xxx`) while rendering a different component (`xxx`)`
* [bug] fix when `use-agent-reducer` update state by its brothers, react throw error: `Cannot update a component (`xxx`) while rendering a different component (`xxx`)`

## v3.2.7 2021-03-16

* [api] add `sharing` for generating a persistent model.
* [api] add `weakSharing` for generating a weak persistent model.
7 changes: 6 additions & 1 deletion CHANGE_LOG_ZH.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,9 @@

## v3.2.2 2021-03-12

* [bug] 解决 `use-agent-reducer` 同步更新数据时, react throw error: `Cannot update a component (`xxx`) while rendering a different component (`xxx`)`
* [bug] 解决 `use-agent-reducer` 同步更新数据时, react throw error: `Cannot update a component (`xxx`) while rendering a different component (`xxx`)`

## v3.2.7 2021-03-16

* [api] 新增接口 `sharing` 用于生成持久化模型.
* [api] 新增接口 `weakSharing` 用于生成弱持久化模型
47 changes: 45 additions & 2 deletions documents/en/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,49 @@ const {
takeDebounceAssignable
} = MiddleWarePresets;
```
8 . [not often usage](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_often_use.md): There are some apis which are not often used, if you want to know, check them [here](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_often_use.md).

9 . [not recommend](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_recommend.md): There are some apis which are not recommended to use, if you want to know, check them [here](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_recommend.md).
8 . [sharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/sharing.md) is for generating a persistent model.

```typescript
import {sharing, createAgentReducer, OriginAgent} from 'agent-reducer';

class Model implements OriginAgent<any>{

state = {};

method():any{
return {}
}

}

const sharingModelRef1 = sharing(()=>Model);

const {agent:agent1} = createAgentReducer(sharingModelRef1.current);
const {agent:agent2} = createAgentReducer(sharingModelRef1.current);
```

9 . [weakSharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/weak_sharing.md) is for generating a weak persistent model.

```typescript
import {weakSharing, createAgentReducer, OriginAgent} from 'agent-reducer';

class Model implements OriginAgent<any>{

state = {};

method():any{
return {}
}

}

const sharingModelRef1 = weakSharing(()=>Model);

const {agent:agent1} = createAgentReducer(sharingModelRef1.current);
const {agent:agent2} = createAgentReducer(sharingModelRef1.current);
```

10 . [not often usage](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_often_use.md): There are some apis which are not often used, if you want to know, check them [here](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_often_use.md).

11 . [not recommend](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_recommend.md): There are some apis which are not recommended to use, if you want to know, check them [here](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_recommend.md).
16 changes: 16 additions & 0 deletions documents/en/api/sharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#### sharing(factory)

This api function is used for generating a persistent model. [check concept](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/introduction/concept.md)

```typescript
function sharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - a factory callback function for generating a model(class or object)

It returns a wrap object which contains a persistent model at property `current`.
16 changes: 16 additions & 0 deletions documents/en/api/weak_sharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#### weakSharing(factory)

This api function is used for generating a weak persistent model. [check concept](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/introduction/concept.md)

```typescript
function weakSharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - a factory callback function for generating a model(class or object)

It returns a wrap object which contains a weak persistent model at property `current`. When `Agents` from this model are all destroyed, the factory callback generates a new one.
2 changes: 2 additions & 0 deletions documents/en/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@
* [MiddleWares](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/middle_wares.md)
* [LifecycleMiddleWares](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/lifecycle_middle_wares.md)
* [MiddleWarePresets](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/middle_ware_presets.md)
* [sharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/sharing.md)
* [weakSharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/weak_sharing.md)
* [not often usage](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_often_use.md)
* [not recommend](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/api/not_recommend.md)

Expand Down
50 changes: 45 additions & 5 deletions documents/en/introduction/concept.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

## Overview

`agent-reducer` is a reducer transforming tool. It turns model ([OriginAgent](#OriginAgent)) to a reducer function ([AgentReducer](#AgentReducer)), and generates a model proxy object (`Agent`). When you call a method from `Agent` directly, its result (method returns) will be passed into `MiddleWare` system for reproducing, after that, the final result will be `dispatched` to the reducer function which is transfromed from [OriginAgent](#OriginAgent).
`agent-reducer` is a reducer transforming tool. It transforms a model ([OriginAgent](#OriginAgent)) into a reducer function ([AgentReducer](#AgentReducer)), and generates a proxy object (`Agent`) of this model. Everytime, after a method of `Agent` is called, `Agent` changes its state to be what the method returns.

## OriginAgent

`OriginAgent` is an object or a class which has a `state` property for storing the data you want to persist. And you can maintian `methods` in it, for producing a `next state`. So, consider it as a data-flow model.
`OriginAgent` is an object or a class which has a `state` property for storing the data you want to persist. And you can maintian `methods` in it, for producing a `next state`. So, consider it as a data processing model.

1. Property `state` stores the data you want to persist, it can be any type. When you want to use it, please ensure it is immutable.
2. `method` is a function for producing a `next state`.
Expand All @@ -21,17 +21,17 @@ class CountAgent implements OriginAgent<number> {
// OriginAgent should has a state for storing what you want persist
state = 0;

// you can use arrow function to generate the next state candidate
// you can use arrow function to generate the next state
stepUp = (): number => this.state + 1;

// you can use a method function to generate the next state candidate
// you can use a method function to generate the next state
stepDown(): number {
// use this.state to generate next state
return this.state - 1;
}

step(isUp: boolean): number {
// use other functions here to generate a next state candidate,
// use other functions here to generate a next state,
// when the method in 'agent' is called,
// only the final result will be dispatched into 'reducer',
// the inside methods 'stepUp' ,'stepDown' only provides data.
Expand Down Expand Up @@ -83,6 +83,7 @@ const agent=reducer.agent;
4. `namespace`: it is designed for the reducer tools like `redux` which may need it.
5. `env`: it is the running environment data for `agent`. It contains properties like `strict`,`expired`... , these properties can affect `agent` running features, and they will be introduced in [guide](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/guides/about_env.md).
6. `recordStateChanges`: this function is designed for unit test. It records state change histories when you used it in your unit test.
7. `destroy`: this function is used for destroy an `Agent` object.

using AgentReducer properties example:

Expand Down Expand Up @@ -196,4 +197,43 @@ const MiddleWare = <T>(runtime: Runtime<T>):NextProcess | void =>{

If you want to know how to chain `MiddleWares` together, and how the chained `MiddleWare` work with system, [see the guides about middle ware](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/guides/about_middle_ware.md).

## model sharing

Model sharing is a new feature from `agent-reducer@3.2.0`. It declares every `Agent` bases on a same model (`OriginAgent`) object shares state updating with each other.

That means we can create `Agents` base on a same model object in different react components, and they can update state synchronously. It is similar with the subscribe system in redux.

This feature is similar with redux, and you should know if you are using a normal object model, or using one generated from API `sharing` , the model is persistent。If you need a weak persistent model, try another API `weakSharing`. A weak persistent model is often reset when its `Agents` are all destroyed.

#### sharing
```typescript
function sharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - a factory callback function for generating a model(class or object)

It returns a wrap object which contains a persistent model at property `current`.

#### weakSharing

```typescript
function weakSharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - a factory callback function for generating a model(class or object)

It returns a wrap object which contains a weak persistent model at property `current`. When `Agents` from this model are all destroyed, the factory callback generates a new one.

[model sharing unit test](https://github.com/filefoxper/agent-reducer/blob/master/test/zh/spec/modelSharing.spec.ts) source code.

[next to installation](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/introduction/installation.md)
4 changes: 2 additions & 2 deletions documents/en/introduction/motivation.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# motivation

`Reducer` is very popular in state immutable system, like `react`,`redux`. It provides a stable processing environment, and makes data flow clear. But it has troubles too, when we `dispatch an action` into a `reducer function`. We have to collect an `action` object first, and inside the `reducer function`, we need to make a distinction between each `action types (action.type)` for processing different flow.
The pure functional data processor `reducer` is widely used in state immutable systems, like `react`, `redux`. It provides a stable processing environment, and makes data flow clear. But it still has space for evolution, such as the dispatching mechanism. It seems to be a good design for dispatching an action as a param to `reducer` function, but `dispatch` function is still not the `reducer` function, and `action` object is still not natural enough as function arguments.

If we can use a class instance to replace `reducer`, and make calling a method as dispatching an `action`, the usage will be easy enough. Then we keep the best feature of `reducer` on, `return a next state in method` and use a class to build a `reducer`.
We have made a tool working with a ES6 class processor, every method of this class processor is used for producing a next state, just like what a `reducer` does, so we call this tool `agent-reducer`. And you can consider it as a upgraded `reducer` tool.

[next to concept](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/introduction/concept.md)
2 changes: 1 addition & 1 deletion documents/en/tutorial/intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

This tutorial assumes you are familiar with [Jest](https://github.com/facebook/jest) or standard `unit test`, and we will write examples by `unit test` style.

In this tutorial, we will build a searching page model, and show how this model works. If you are interested in building a simple web app, please waiting for the tutorial of [use-agent-reducer](https://www.npmjs.com/package/use-agent-reducer).
In this tutorial, we will build a searching page model, and show how this model works. If you are interested in building a simple web app, please check the [tutorial](https://filefoxper.github.io/use-agent-reducer/#/tutorial) of `use-agent-reducer`.

* [a simple search page model](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/tutorial/basic.md)
* [use MiddleWare](https://github.com/filefoxper/agent-reducer/blob/master/documents/en/tutorial/middle_ware.md)
Expand Down
47 changes: 45 additions & 2 deletions documents/zh/api/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,49 @@ const {
takeDebounceAssignable
} = MiddleWarePresets;
```
8 . [不常用 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_often_use.md): 有些API可能一辈子也用不到,但我们依然列出了它们以供不时之需。

9 . [不推荐使用的 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_recommend.md): 有些设计不理想API,我们并不推荐使用,但我们依然列出了它们。
8 . [sharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/sharing.md) 用于创建一个持久化共享模型。

```typescript
import {sharing, createAgentReducer, OriginAgent} from 'agent-reducer';

class Model implements OriginAgent<any>{

state = {};

method():any{
return {}
}

}

const sharingModelRef1 = sharing(()=>Model);

const {agent:agent1} = createAgentReducer(sharingModelRef1.current);
const {agent:agent2} = createAgentReducer(sharingModelRef1.current);
```

9 . [weakSharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/weak_sharing.md) 用于创建一个弱持久化共享模型。

```typescript
import {weakSharing, createAgentReducer, OriginAgent} from 'agent-reducer';

class Model implements OriginAgent<any>{

state = {};

method():any{
return {}
}

}

const sharingModelRef1 = weakSharing(()=>Model);

const {agent:agent1} = createAgentReducer(sharingModelRef1.current);
const {agent:agent2} = createAgentReducer(sharingModelRef1.current);
```

10 . [不常用 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_often_use.md): 有些API可能一辈子也用不到,但我们依然列出了它们以供不时之需。

11 . [不推荐使用的 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_recommend.md): 有些设计不理想API,我们并不推荐使用,但我们依然列出了它们。
16 changes: 16 additions & 0 deletions documents/zh/api/sharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#### sharing(factory)

用于创建一个持久化共享模型。[参考概念](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/introduction/concept.md)

```typescript
function sharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - 生成共享模型的工厂方法,通过该方法返回一个被共享的模型(class 或 object)

该方法返回一个持久化共享模型包装,从返回值的 `current` 属性中可取出模型。
16 changes: 16 additions & 0 deletions documents/zh/api/weak_sharing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#### weakSharing(factory)

用于创建一个弱持久化共享模型。[参考概念](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/introduction/concept.md)

```typescript
function weakSharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - 生成共享模型的工厂方法,通过该方法返回一个被共享的模型(class 或 object)

该方法返回一个弱持久化共享模型包装,从返回值的 `current` 属性中可取出模型,当模型生成的 `Agent` 代理全被销毁时,模型会通过传入的 factory 工厂方法进行模型重置。
2 changes: 2 additions & 0 deletions documents/zh/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
* [MiddleWares](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/middle_wares.md)
* [LifecycleMiddleWares](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/lifecycle_middle_wares.md)
* [MiddleWarePresets](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/middle_ware_presets.md)
* [sharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/sharing.md)
* [weakSharing](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/weak_sharing.md)
* [不常用 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_often_use.md)
* [不推荐使用的 API](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/api/not_recommend.md)

Expand Down
41 changes: 41 additions & 0 deletions documents/zh/introduction/concept.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const agent=reducer.agent;
4. `namespace`: 提供给类似`redux`这类需要名字空间的reducer工具使用。
5. `env`: `agent`运行环境参数,它包含了属性 `strict`,`expired`... , 这些属性可用于控制`agent`的运行方式,影响其运行结果。
6. `recordStateChanges`: 该方法目前只允许用于单元测试,通过使用该方法,可以记录`agent`的state变更情况。
7. `destroy`: 该方法用于销毁一个 `Agent` 对象。

例子:
```typescript
Expand Down Expand Up @@ -185,4 +186,44 @@ const MiddleWare = <T>(runtime: Runtime<T>):NextProcess | void =>{
```
如果你希望了解如何串连`MiddleWares`,或是串行好的`MiddleWare`是如何工作的,[请参考引导章节中关于MiddleWare的说明](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/guides/about_middle_ware.md)

## 模型共享

模型共享是 `agent-reducer@3.2.0` 新加入的特性。该特性声明为所有建立在同一`对象模型`上的 `Agent` 代理共享 state 数据更新。

也就是说,不同组件中的`Agent`只要使用了同一个`对象化的模型`,那么它们的数据更改与相关的组件渲染就是同步的。这与 redux 的 subscribe 行为非常类似。

该特性与 redux 表现得非常类似,需要注意的是,如果使用的是普通对象模型,或者通过 API `sharing` 产生的模型,那模型将是持久存在的,它并不会随着 `Agent` 代理被一并销毁;如果你需要的是一份弱持久化的模型,可通过另一个 API `weakSharing` 来生成,当弱持久化模型的所有 `Agent` 代理全被销毁时,整个模型将被重置。

#### sharing(factory)
```typescript
function sharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - 生成共享模型的工厂方法,通过该方法返回一个被共享的模型(class 或 object)

该方法返回一个持久化共享模型包装,从返回值的 `current` 属性中可取出模型。

#### weakSharing(factory)

```typescript
function weakSharing<
S,
T extends OriginAgent<S> = OriginAgent<S>
>(
factory:()=>T|{new ():T},
):{current:T}
```

* factory - 生成共享模型的工厂方法,通过该方法返回一个被共享的模型(class 或 object)

该方法返回一个弱持久化共享模型包装,从返回值的 `current` 属性中可取出模型,当模型生成的 `Agent` 代理全被销毁时,模型会通过传入的 factory 工厂方法进行模型重置。

[模型共享单元测试](https://github.com/filefoxper/agent-reducer/blob/master/test/zh/spec/modelSharing.spec.ts)源码


[下一节,安装](https://github.com/filefoxper/agent-reducer/blob/master/documents/zh/introduction/installation.md)
Loading

0 comments on commit 7d0e687

Please sign in to comment.