@cascateer/core 2.1.14 → 2.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/api.ts +37 -50
- package/src/observable/ProxyObservable.ts +28 -8
- package/src/observable/ProxySubject.ts +9 -9
- package/src/observable/Signal.ts +3 -8
- package/src/observable/index.ts +0 -1
- package/src/operators/proxyReplaySubject.ts +4 -5
- package/src/terminal.ts +8 -9
- package/src/types.ts +37 -37
- package/src/observable/AsyncObservable.ts +0 -33
package/package.json
CHANGED
package/src/api.ts
CHANGED
|
@@ -5,12 +5,12 @@ import {
|
|
|
5
5
|
isEqual,
|
|
6
6
|
isFunction,
|
|
7
7
|
memoize,
|
|
8
|
+
thru,
|
|
8
9
|
} from "lodash";
|
|
9
10
|
import objectHash from "object-hash";
|
|
10
11
|
import {
|
|
11
12
|
BehaviorSubject,
|
|
12
13
|
combineLatest,
|
|
13
|
-
defer,
|
|
14
14
|
filter,
|
|
15
15
|
finalize,
|
|
16
16
|
lastValueFrom,
|
|
@@ -20,11 +20,12 @@ import {
|
|
|
20
20
|
repeat,
|
|
21
21
|
shareReplay,
|
|
22
22
|
Subject,
|
|
23
|
+
tap,
|
|
23
24
|
UnaryFunction,
|
|
24
25
|
} from "rxjs";
|
|
25
26
|
import { asObservable, ExtendableDictionary, property } from "./lib";
|
|
26
|
-
import {
|
|
27
|
-
import { Action,
|
|
27
|
+
import { ProxyObservable } from "./observable";
|
|
28
|
+
import { Action, MaybeArray, MaybeObservable, ProxyEffect } from "./types";
|
|
28
29
|
|
|
29
30
|
interface TagsConstructor<Args, Result> {
|
|
30
31
|
(args: Args, result: Result): string[];
|
|
@@ -39,7 +40,7 @@ class Memoizable<Args, Result> {
|
|
|
39
40
|
predicate: UnaryFunction<Args, Observable<Result>>;
|
|
40
41
|
tags: TagsConstructor<Args, Result>;
|
|
41
42
|
|
|
42
|
-
subscribe: UnaryFunction<Observable<string[]>,
|
|
43
|
+
subscribe: UnaryFunction<Observable<string[]>, ProxyEffect<Args, Result>>;
|
|
43
44
|
|
|
44
45
|
share: UnaryFunction<NextObserver<string[]>, Action<Args, Result>>;
|
|
45
46
|
|
|
@@ -49,52 +50,38 @@ class Memoizable<Args, Result> {
|
|
|
49
50
|
this.tags = isFunction(tags) ? tags : constant([tags ?? []].flat());
|
|
50
51
|
|
|
51
52
|
this.subscribe = (invalidatedTags) => {
|
|
52
|
-
const memoizedEffect:
|
|
53
|
-
(args) =>
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
memoizedEffect(args).pipe(
|
|
76
|
-
map((result) => tags(args, result)),
|
|
77
|
-
),
|
|
78
|
-
invalidatedTags,
|
|
79
|
-
]).pipe(
|
|
80
|
-
filter(([tags, invalidatedTags]) =>
|
|
81
|
-
isEqual(
|
|
82
|
-
tags,
|
|
83
|
-
intersectionWith(tags, invalidatedTags),
|
|
84
|
-
),
|
|
85
|
-
),
|
|
53
|
+
const memoizedEffect: ProxyEffect<Args, Result> = memoize(
|
|
54
|
+
(args) =>
|
|
55
|
+
thru(
|
|
56
|
+
new BehaviorSubject(false),
|
|
57
|
+
(pending) =>
|
|
58
|
+
new ProxyObservable(this.predicate(args), (target) => ({
|
|
59
|
+
value: target.pipe(
|
|
60
|
+
tap({
|
|
61
|
+
subscribe: () => pending.next(true),
|
|
62
|
+
}),
|
|
63
|
+
finalize(() => pending.next(false)),
|
|
64
|
+
repeat({
|
|
65
|
+
delay: () =>
|
|
66
|
+
combineLatest([
|
|
67
|
+
memoizedEffect(args).pipe(
|
|
68
|
+
map((result) => this.tags(args, result)),
|
|
69
|
+
),
|
|
70
|
+
invalidatedTags,
|
|
71
|
+
]).pipe(
|
|
72
|
+
filter(([tags, invalidatedTags]) =>
|
|
73
|
+
isEqual(
|
|
74
|
+
tags,
|
|
75
|
+
intersectionWith(tags, invalidatedTags),
|
|
86
76
|
),
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
),
|
|
91
|
-
)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
})(this.predicate(args), this.tags);
|
|
97
|
-
},
|
|
77
|
+
),
|
|
78
|
+
),
|
|
79
|
+
}),
|
|
80
|
+
shareReplay({ bufferSize: 1, refCount: false }),
|
|
81
|
+
),
|
|
82
|
+
pending,
|
|
83
|
+
})),
|
|
84
|
+
),
|
|
98
85
|
(args) => objectHash(args ?? null),
|
|
99
86
|
);
|
|
100
87
|
|
|
@@ -108,7 +95,7 @@ class Memoizable<Args, Result> {
|
|
|
108
95
|
}
|
|
109
96
|
}
|
|
110
97
|
|
|
111
|
-
export interface ApiEffect<Args, Result> extends
|
|
98
|
+
export interface ApiEffect<Args, Result> extends ProxyEffect<Args, Result> {}
|
|
112
99
|
|
|
113
100
|
type ApiAdapterPropertyConstructor<Source, Type extends "effect" | "action"> = {
|
|
114
101
|
[T in Type]: <Args, Result>(
|
|
@@ -1,14 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Observable } from "rxjs";
|
|
1
|
+
import { thru } from "lodash";
|
|
2
|
+
import { isObservable, Observable, of } from "rxjs";
|
|
3
3
|
|
|
4
|
-
export interface
|
|
5
|
-
(target:
|
|
4
|
+
export interface ProxyObservableDescriptor<T, U> {
|
|
5
|
+
(target: T):
|
|
6
|
+
| U
|
|
7
|
+
| {
|
|
8
|
+
value: U;
|
|
9
|
+
pending?: Observable<boolean>;
|
|
10
|
+
};
|
|
6
11
|
}
|
|
7
12
|
|
|
8
|
-
export class ProxyObservable<
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
export class ProxyObservable<
|
|
14
|
+
X,
|
|
15
|
+
Y = X,
|
|
16
|
+
T extends Observable<X> = Observable<X>,
|
|
17
|
+
> extends Observable<Y> {
|
|
18
|
+
pending: Observable<boolean>;
|
|
11
19
|
|
|
12
|
-
|
|
20
|
+
constructor(
|
|
21
|
+
target: T,
|
|
22
|
+
descriptor: ProxyObservableDescriptor<T, Observable<Y>>,
|
|
23
|
+
) {
|
|
24
|
+
const { value, pending = of(false) } = thru(
|
|
25
|
+
descriptor(target),
|
|
26
|
+
(descriptor) =>
|
|
27
|
+
isObservable(descriptor) ? { value: descriptor } : descriptor,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
super((subscriber) => value.subscribe(subscriber));
|
|
31
|
+
|
|
32
|
+
this.pending = pending;
|
|
13
33
|
}
|
|
14
34
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Observer, Subject, Unsubscribable } from "rxjs";
|
|
2
|
-
import { ProxyObservable,
|
|
1
|
+
import { Observable, Observer, Subject, Unsubscribable } from "rxjs";
|
|
2
|
+
import { ProxyObservable, ProxyObservableDescriptor } from "./ProxyObservable";
|
|
3
3
|
|
|
4
|
-
export class ProxySubject<
|
|
5
|
-
extends ProxyObservable<
|
|
6
|
-
implements Observer<
|
|
4
|
+
export class ProxySubject<X, Y = X, T extends Subject<X> = Subject<X>>
|
|
5
|
+
extends ProxyObservable<X, Y, T>
|
|
6
|
+
implements Observer<X>, Unsubscribable
|
|
7
7
|
{
|
|
8
|
-
next(value:
|
|
8
|
+
next(value: X): void {
|
|
9
9
|
this.target.next(value);
|
|
10
10
|
}
|
|
11
11
|
|
|
@@ -22,9 +22,9 @@ export class ProxySubject<T, U = T>
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
constructor(
|
|
25
|
-
private target:
|
|
26
|
-
|
|
25
|
+
private target: T,
|
|
26
|
+
descriptor: ProxyObservableDescriptor<T, Observable<Y>>,
|
|
27
27
|
) {
|
|
28
|
-
super(target,
|
|
28
|
+
super(target, descriptor);
|
|
29
29
|
}
|
|
30
30
|
}
|
package/src/observable/Signal.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { clone, identity, isEqual, memoize } from "lodash";
|
|
2
|
-
import { distinctUntilChanged, map, Observable,
|
|
3
|
-
import {
|
|
2
|
+
import { distinctUntilChanged, map, Observable, UnaryFunction } from "rxjs";
|
|
3
|
+
import { ProxyObservable } from ".";
|
|
4
4
|
import {
|
|
5
5
|
asEnumerable,
|
|
6
6
|
EnumerableItem,
|
|
@@ -33,12 +33,7 @@ class SignalReflector<T> {
|
|
|
33
33
|
new SignalReflector((transform) => this.predicate(lift(transform)));
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
export class Signal<T>
|
|
37
|
-
extends ProxyObservable<T>
|
|
38
|
-
implements AsyncObservable<T>
|
|
39
|
-
{
|
|
40
|
-
pending = of(false);
|
|
41
|
-
|
|
36
|
+
export class Signal<T> extends ProxyObservable<T> {
|
|
42
37
|
clone(): Signal<T> {
|
|
43
38
|
return this;
|
|
44
39
|
}
|
package/src/observable/index.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { ReplaySubject } from "rxjs";
|
|
1
|
+
import { Observable, ReplaySubject, UnaryFunction } from "rxjs";
|
|
2
2
|
import { ProxySubject } from "../observable";
|
|
3
|
-
import { ProxyObservableHandler } from "../observable/ProxyObservable";
|
|
4
3
|
|
|
5
|
-
export const proxyReplaySubject = <
|
|
6
|
-
|
|
7
|
-
) => new ProxySubject<
|
|
4
|
+
export const proxyReplaySubject = <X, Y = X>(
|
|
5
|
+
descriptor: UnaryFunction<ReplaySubject<X>, Observable<Y>>,
|
|
6
|
+
) => new ProxySubject<X, Y, ReplaySubject<X>>(new ReplaySubject(), descriptor);
|
package/src/terminal.ts
CHANGED
|
@@ -6,13 +6,13 @@ import { ComputedSignal } from "./observable";
|
|
|
6
6
|
import { asStoreEffects, StoreAdapter, StoreEffects } from "./store";
|
|
7
7
|
import {
|
|
8
8
|
Action,
|
|
9
|
-
AsyncEffect,
|
|
10
|
-
AsyncEffectInterceptor,
|
|
11
|
-
AsyncEffects,
|
|
12
9
|
Effect,
|
|
10
|
+
ProxyEffect,
|
|
11
|
+
ProxyEffectInterceptor,
|
|
12
|
+
ProxyEffects,
|
|
13
13
|
} from "./types";
|
|
14
14
|
|
|
15
|
-
export interface TerminalEffect<Args, Result> extends
|
|
15
|
+
export interface TerminalEffect<Args, Result> extends ProxyEffect<
|
|
16
16
|
Args,
|
|
17
17
|
Result
|
|
18
18
|
> {}
|
|
@@ -64,10 +64,10 @@ export class ExtendableTerminalAdapter<
|
|
|
64
64
|
effects: StoreEffects<StoreSignals>;
|
|
65
65
|
};
|
|
66
66
|
api: {
|
|
67
|
-
effects:
|
|
67
|
+
effects: ProxyEffects<ApiEffects>;
|
|
68
68
|
};
|
|
69
69
|
terminal: {
|
|
70
|
-
effects:
|
|
70
|
+
effects: ProxyEffects<Effects>;
|
|
71
71
|
};
|
|
72
72
|
},
|
|
73
73
|
Effect<Args, Result>
|
|
@@ -80,7 +80,7 @@ export class ExtendableTerminalAdapter<
|
|
|
80
80
|
return new ExtendableTerminalAdapter(
|
|
81
81
|
this.context,
|
|
82
82
|
this.extendableEffects.extend((currentEffects) => () => {
|
|
83
|
-
const interceptor = new
|
|
83
|
+
const interceptor = new ProxyEffectInterceptor();
|
|
84
84
|
const source = {
|
|
85
85
|
store: {
|
|
86
86
|
effects: asStoreEffects(this.context.store.signals),
|
|
@@ -94,8 +94,7 @@ export class ExtendableTerminalAdapter<
|
|
|
94
94
|
};
|
|
95
95
|
|
|
96
96
|
return effects({
|
|
97
|
-
effect: (constructor) =>
|
|
98
|
-
interceptor.toAsyncEffect(constructor(source)),
|
|
97
|
+
effect: (constructor) => interceptor.proxy(constructor(source)),
|
|
99
98
|
});
|
|
100
99
|
}),
|
|
101
100
|
this.extendableActions,
|
package/src/types.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { Dictionary, mapValues,
|
|
1
|
+
import { Dictionary, mapValues, thru } from "lodash";
|
|
2
2
|
import {
|
|
3
|
+
BehaviorSubject,
|
|
3
4
|
combineLatest,
|
|
4
5
|
distinct,
|
|
5
|
-
identity,
|
|
6
6
|
map,
|
|
7
7
|
ReplaySubject,
|
|
8
8
|
switchMap,
|
|
@@ -10,67 +10,67 @@ import {
|
|
|
10
10
|
} from "rxjs";
|
|
11
11
|
import { Observable } from "rxjs/internal/Observable";
|
|
12
12
|
import { ObservableInput } from "rxjs/internal/types";
|
|
13
|
-
import {
|
|
14
|
-
import { concat } from "./operators";
|
|
13
|
+
import { ProxyObservable } from "./observable";
|
|
14
|
+
import { concat, tapSubscription } from "./operators";
|
|
15
15
|
|
|
16
16
|
export interface Effect<Args, Result> extends UnaryFunction<
|
|
17
17
|
Args,
|
|
18
18
|
Observable<Result>
|
|
19
19
|
> {}
|
|
20
20
|
|
|
21
|
-
export interface
|
|
21
|
+
export interface ProxyEffect<Args, Result> extends UnaryFunction<
|
|
22
22
|
Args,
|
|
23
|
-
|
|
23
|
+
ProxyObservable<Result>
|
|
24
24
|
> {}
|
|
25
25
|
|
|
26
|
-
export type
|
|
26
|
+
export type ProxyEffects<Effects extends Dictionary<ProxyEffect<any, any>>> = {
|
|
27
27
|
[K in keyof Effects]: ReturnType<
|
|
28
28
|
<
|
|
29
|
-
Args extends Effects[K] extends
|
|
29
|
+
Args extends Effects[K] extends ProxyEffect<infer Args, infer _>
|
|
30
30
|
? Args
|
|
31
31
|
: never,
|
|
32
|
-
Result extends Effects[K] extends
|
|
32
|
+
Result extends Effects[K] extends ProxyEffect<infer _, infer Result>
|
|
33
33
|
? Result
|
|
34
34
|
: never,
|
|
35
|
-
>() =>
|
|
35
|
+
>() => ProxyEffect<Args, Result>
|
|
36
36
|
>;
|
|
37
37
|
};
|
|
38
38
|
|
|
39
|
-
export class
|
|
40
|
-
|
|
39
|
+
export class ProxyEffectInterceptor extends ReplaySubject<
|
|
40
|
+
ProxyObservable<any>
|
|
41
41
|
> {
|
|
42
|
-
intercept<Effects extends Dictionary<
|
|
42
|
+
intercept<Effects extends Dictionary<ProxyEffect<any, any>>>(
|
|
43
43
|
effects: Effects,
|
|
44
|
-
):
|
|
44
|
+
): ProxyEffects<Effects> {
|
|
45
45
|
return mapValues(
|
|
46
46
|
effects,
|
|
47
|
-
(effect) => (args) =>
|
|
47
|
+
(effect) => (args) =>
|
|
48
|
+
thru(
|
|
49
|
+
new BehaviorSubject(false),
|
|
50
|
+
(subscribed) =>
|
|
51
|
+
new ProxyObservable(effect(args), (target) => ({
|
|
52
|
+
value: target.pipe(tapSubscription(subscribed)),
|
|
53
|
+
pending: combineLatest([target.pending, subscribed]).pipe(
|
|
54
|
+
map((values) => values.every(Boolean)),
|
|
55
|
+
),
|
|
56
|
+
})),
|
|
57
|
+
),
|
|
48
58
|
);
|
|
49
59
|
}
|
|
50
60
|
|
|
51
|
-
|
|
52
|
-
effect: Effect<Args, Result>,
|
|
53
|
-
): AsyncEffect<Args, Result> {
|
|
61
|
+
proxy<Args, Result>(effect: Effect<Args, Result>): ProxyEffect<Args, Result> {
|
|
54
62
|
return (args) =>
|
|
55
|
-
new (
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
concat(),
|
|
67
|
-
switchMap((sources) =>
|
|
68
|
-
combineLatest(sources.map((source) => source.pending)),
|
|
69
|
-
),
|
|
70
|
-
map((values) => values.some(Boolean)),
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
})(this);
|
|
63
|
+
new ProxyObservable(effect(args), (target) => ({
|
|
64
|
+
value: target,
|
|
65
|
+
pending: this.pipe(
|
|
66
|
+
distinct(),
|
|
67
|
+
concat(),
|
|
68
|
+
switchMap((sources) =>
|
|
69
|
+
combineLatest(sources.map((source) => source.pending)),
|
|
70
|
+
),
|
|
71
|
+
map((values) => values.some(Boolean)),
|
|
72
|
+
),
|
|
73
|
+
}));
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { constant } from "lodash";
|
|
2
|
-
import {
|
|
3
|
-
BehaviorSubject,
|
|
4
|
-
defer,
|
|
5
|
-
finalize,
|
|
6
|
-
isObservable,
|
|
7
|
-
Observable,
|
|
8
|
-
UnaryFunction,
|
|
9
|
-
} from "rxjs";
|
|
10
|
-
import { ProxyObservable } from "./ProxyObservable";
|
|
11
|
-
|
|
12
|
-
export interface AsyncObservable<T> {
|
|
13
|
-
pending: Observable<boolean>;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export class AsyncObservable<T> extends ProxyObservable<T> {
|
|
17
|
-
constructor(
|
|
18
|
-
source: Observable<T> | UnaryFunction<() => void, Observable<T>>,
|
|
19
|
-
) {
|
|
20
|
-
const pending = new BehaviorSubject(false);
|
|
21
|
-
const complete = () => pending.next(false);
|
|
22
|
-
|
|
23
|
-
if (isObservable(source)) {
|
|
24
|
-
source = constant(source);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
super(source(complete), (source) =>
|
|
28
|
-
defer(() => (pending.next(true), source)).pipe(finalize(complete)),
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
this.pending = pending;
|
|
32
|
-
}
|
|
33
|
-
}
|