-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathdoll-effect.ts
More file actions
54 lines (46 loc) · 1.59 KB
/
doll-effect.ts
File metadata and controls
54 lines (46 loc) · 1.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { Subject, Observable } from 'rxjs'
import { take } from 'rxjs/operators'
import { addDisposer } from 'mobx-state-tree'
import type { AnyInstance, IsEmptyPayload, PayloadFunc } from '../types'
import type { ValidEffectActions } from './action'
import { subscribe } from './utils'
export type DollEffectFactory<P, R = void> = (
payload$: Observable<P>,
dollSignal: PayloadFunc<R, void>,
) => Observable<ValidEffectActions>
export type DollEffectDispatcher<P, R> = IsEmptyPayload<P> extends true
? <T = R>(
payload?: undefined,
handler?: (result$: Observable<R>) => Observable<T>,
) => Promise<T | undefined>
: <T = R>(
payload: P,
handler?: (result$: Observable<R>) => Observable<T>,
) => Promise<T | undefined>
export function dollEffect<P, R = unknown>(
self: AnyInstance,
factory: DollEffectFactory<P, R>,
): DollEffectDispatcher<P, R>
export function dollEffect(
self: AnyInstance,
factory: DollEffectFactory<any, any>,
): DollEffectDispatcher<any, any> {
const payloadSource = new Subject()
const signalSource = new Subject()
const effect$ = factory(payloadSource.asObservable(), (value) => signalSource.next(value))
const subscription = subscribe(self, factory, effect$)
addDisposer(self, () => {
payloadSource.complete()
signalSource.complete()
subscription.unsubscribe()
})
return (payload: any, handler: any) => {
const promise = (
typeof handler === 'function' ? handler(signalSource.asObservable()) : signalSource
)
.pipe(take(1))
.toPromise()
payloadSource.next(payload)
return promise
}
}