mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-25 02:13:00 +08:00
feat(infra): livedata flatten (#6083)
This commit is contained in:
@@ -185,4 +185,42 @@ describe('livedata', () => {
|
|||||||
});
|
});
|
||||||
expect(value).toBe(1);
|
expect(value).toBe(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('flat', () => {
|
||||||
|
{
|
||||||
|
const wrapped = new LiveData(new LiveData(0));
|
||||||
|
const flatten = wrapped.flat();
|
||||||
|
expect(flatten.value).toBe(0);
|
||||||
|
|
||||||
|
wrapped.next(new LiveData(1));
|
||||||
|
expect(flatten.value).toBe(1);
|
||||||
|
|
||||||
|
wrapped.next(LiveData.from(of(2, 3), 0));
|
||||||
|
expect(flatten.value).toBe(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const wrapped = new LiveData(
|
||||||
|
new LiveData([
|
||||||
|
new LiveData(new LiveData(1)),
|
||||||
|
new LiveData(new LiveData(2)),
|
||||||
|
])
|
||||||
|
);
|
||||||
|
const flatten = wrapped.flat();
|
||||||
|
expect(flatten.value).toStrictEqual([1, 2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const wrapped = new LiveData([new LiveData(0), new LiveData(1)]);
|
||||||
|
const flatten = wrapped.flat();
|
||||||
|
|
||||||
|
expect(flatten.value).toEqual([0, 1]);
|
||||||
|
|
||||||
|
const inner = new LiveData(2);
|
||||||
|
wrapped.next([inner, new LiveData(3)]);
|
||||||
|
expect(flatten.value).toEqual([2, 3]);
|
||||||
|
inner.next(4);
|
||||||
|
expect(flatten.value).toEqual([4, 3]);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { DebugLogger } from '@affine/debug';
|
import { DebugLogger } from '@affine/debug';
|
||||||
import {
|
import {
|
||||||
|
combineLatest,
|
||||||
distinctUntilChanged,
|
distinctUntilChanged,
|
||||||
EMPTY,
|
EMPTY,
|
||||||
filter,
|
filter,
|
||||||
@@ -192,7 +193,7 @@ export class LiveData<T = unknown> implements InteropObservable<T> {
|
|||||||
return subscription;
|
return subscription;
|
||||||
}
|
}
|
||||||
|
|
||||||
map<R>(mapper: (v: T) => R): LiveData<R> {
|
map<R>(mapper: (v: T) => R) {
|
||||||
const sub = LiveData.from(
|
const sub = LiveData.from(
|
||||||
new Observable<R>(subscriber =>
|
new Observable<R>(subscriber =>
|
||||||
this.subscribe({
|
this.subscribe({
|
||||||
@@ -268,6 +269,42 @@ export class LiveData<T = unknown> implements InteropObservable<T> {
|
|||||||
this.upstreamSubscription?.unsubscribe();
|
this.upstreamSubscription?.unsubscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flatten the livedata
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* new LiveData(new LiveData(0)).flat() // LiveData<number>
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* ```
|
||||||
|
* new LiveData([new LiveData(0)]).flat() // LiveData<number[]>
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
flat(): Flat<this> {
|
||||||
|
return LiveData.from(
|
||||||
|
this.pipe(
|
||||||
|
switchMap(v => {
|
||||||
|
if (v instanceof LiveData) {
|
||||||
|
return (v as LiveData<any>).flat();
|
||||||
|
} else if (Array.isArray(v)) {
|
||||||
|
return combineLatest(
|
||||||
|
v.map(v => {
|
||||||
|
if (v instanceof LiveData) {
|
||||||
|
return v.flat();
|
||||||
|
} else {
|
||||||
|
return of(v);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return of(v);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
),
|
||||||
|
null as any
|
||||||
|
) as any;
|
||||||
|
}
|
||||||
|
|
||||||
reactSubscribe = (cb: () => void) => {
|
reactSubscribe = (cb: () => void) => {
|
||||||
this.ops.next('watch');
|
this.ops.next('watch');
|
||||||
const subscription = this.raw
|
const subscription = this.raw
|
||||||
@@ -297,3 +334,12 @@ export class LiveData<T = unknown> implements InteropObservable<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export type LiveDataOperation = 'set' | 'get' | 'watch' | 'unwatch';
|
export type LiveDataOperation = 'set' | 'get' | 'watch' | 'unwatch';
|
||||||
|
|
||||||
|
export type Unwrap<T> =
|
||||||
|
T extends LiveData<infer Z>
|
||||||
|
? Unwrap<Z>
|
||||||
|
: T extends LiveData<infer A>[]
|
||||||
|
? Unwrap<A>[]
|
||||||
|
: T;
|
||||||
|
|
||||||
|
export type Flat<T> = T extends LiveData<infer P> ? LiveData<Unwrap<P>> : T;
|
||||||
|
|||||||
Reference in New Issue
Block a user