Simplify handling of multiple derived effects
- Dominant language
- TypeScript
- Stars
- 4.9k
- Forks
- 280
- Avg merge
- 2d 6h
- Merged PRs (30d)
- 7
Description
## Proposal
Know for me it's too hard to handle multiple derived effects. Patronum has `pending()` but it doesnt help a lot:
```js
const $processing = pending({ effects: [loadFirst, loadSecond] });
```
```ts
export const $message = createStore('');
export const helloFx = createEffect(async () => {
return new Promise(resolve => setTimeout(() => resolve('hello'), 3000))
})
export const byeFx = createEffect(async () => {
return new Promise(resolve => setTimeout(() => resolve('bye'), 500))
})
const changeEvent = createEvent() // changeEvent triggers someFx3
const $processing = patronum.pending({
effects: [helloFx, byeFx],
})
sample({
clock: changeEvent,
target: [helloFx, byeFx],
})
//now what if i need to construct store from fetched data?
// i can do this? No, becase it runs each time separately
sample({
clock: [helloFx.doneData, byeFx.doneData],
source: $processing,
fn: (processing, data) => {
},
target: $message,
})
// i can construct it like that, but it's too hard to handle.
$message.on(helloFx.doneData, (message, data) => {
if(message != '') {
return `${data}${message}`
} else {
return `${data}_`;
}
});
$message.on(byeFx.doneData, (message, data) => {
if(message != '') {
return `${message}${data}`
} else {
return `_${data}`;
}
})
// we can do this
// but it's a lot of work too, because we need to create two separate stores for data.
const $helloRes = createStore('');
const $byeRes = createStore('');
$helloRes.on(helloFx.doneData, (_, data) => data);
$byeRes.on(byeFx.doneData, (_, data) => data);
const $new_message = combine($helloRes, $byeRes, (hello, bye) => `${hello}_${bye}`);
//okay, let's say that it's good. What if I want now to get new byeFx with different query params and use it in another store.
const anotherEvent = createEvent();
forward({
from: anotherEvent,
to: byeFx,
});
anotherEvent();
//know all units and samples that depends on byeFx will be called and my app will be crashed.
//we can solve issue with attach. Moreover, attach is not for creating copy of Fx semantically its for passing data from stores.
const byeCopy1Fx = attach({
effect: byeFx,
mapParams: params => params,
})
const byeCopy2Fx = attach({
effect: byeFx,
mapParams: params => params,
})
//then we need to fix our code
const $helloRes = createStore('');
const $byeRes = createStore('');
const $someCoolStore = createStore('');
$helloRes.on(helloFx.doneData, (_, data) => data);
$byeRes.on(byeCopy1Fx.doneData, (_, data) => data);
$someCoolStore.on(byeCopy2Fx.doneData, (_, data) => data);
const $new_message = combine($helloRes, $byeRes, (hello, bye) => `${hello}_${bye}`);
const anotherEvent = createEvent();
forward({
from: anotherEvent,
to: byeCopy2Fx,
});
forward({
from: changeEvent,
to: [helloFx, byeCopy1Fx],
});
someEvent();
anotherEvent();
```
Can we somehow simplify work with multiple effects?
## Use case
Contributor guide
Assessment
This issue has not been assessed yet.