forked from ReactiveX/rxjs
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathinterop-helper.ts
66 lines (62 loc) · 2.29 KB
/
interop-helper.ts
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
55
56
57
58
59
60
61
62
63
64
65
66
import { Observable, Subject, Subscriber, Subscription } from 'rxjs';
import { rxSubscriber as symbolSubscriber } from 'rxjs/internal/symbol/rxSubscriber';
/**
* Returns an observable that will be deemed by this package's implementation
* to be an observable that requires interop. The returned observable will fail
* the `instanceof Observable` test and will deem any `Subscriber` passed to
* its `subscribe` method to be untrusted.
*/
export function asInteropObservable<T>(observable: Observable<T>): Observable<T> {
return new Proxy(observable, {
get(target: Observable<T>, key: string | number | symbol) {
if (key === 'subscribe') {
const { subscribe } = target;
return interopSubscribe(subscribe);
}
return Reflect.get(target, key);
},
getPrototypeOf(target: Observable<T>) {
const { subscribe, ...rest } = Object.getPrototypeOf(target);
return {
...rest,
subscribe: interopSubscribe(subscribe)
};
}
});
}
/**
* Returns a subject that will be deemed by this package's implementation to
* be untrusted. The returned subject will not include the symbol that
* identifies trusted subjects.
*/
export function asInteropSubject<T>(subject: Subject<T>): Subject<T> {
return asInteropSubscriber(subject as any) as any;
}
/**
* Returns a subscriber that will be deemed by this package's implementation to
* be untrusted. The returned subscriber will fail the `instanceof Subscriber`
* test and will not include the symbol that identifies trusted subscribers.
*/
export function asInteropSubscriber<T>(subscriber: Subscriber<T>): Subscriber<T> {
return new Proxy(subscriber, {
get(target: Subscriber<T>, key: string | number | symbol) {
if (key === symbolSubscriber) {
return undefined;
}
return Reflect.get(target, key);
},
getPrototypeOf(target: Subscriber<T>) {
const { [symbolSubscriber]: symbol, ...rest } = Object.getPrototypeOf(target);
return rest;
}
});
}
function interopSubscribe<T>(subscribe: (...args: any[]) => Subscription) {
return function (this: Observable<T>, ...args: any[]): Subscription {
const [arg] = args;
if (arg instanceof Subscriber) {
return subscribe.call(this, asInteropSubscriber(arg));
}
return subscribe.apply(this, args);
};
}