Skip to content

Commit 89b712e

Browse files
committed
feat: remove Symbol.observable export (#4466)
BREAKING CHANGE: `observable` (the `Symbol.observable` symbol instance) is no longer exported. Use a polyfill like `symbol-observable`, or use `Symbol.observable ?? '@@observable'` as a workaround.
1 parent 8b9d0ef commit 89b712e

File tree

9 files changed

+46
-59
lines changed

9 files changed

+46
-59
lines changed
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import { expect } from 'chai';
22
import { Observable, of, Subscriber } from 'rxjs';
3-
import { observable as symbolObservable } from 'rxjs/internal/symbol/observable';
43
import { asInteropObservable, asInteropSubscriber } from './interop-helper';
54

65
describe('interop helper', () => {
76
it('should simulate interop observables', () => {
87
const observable: any = asInteropObservable(of(42));
98
expect(observable).to.not.be.instanceOf(Observable);
10-
expect(observable[symbolObservable]).to.be.a('function');
9+
expect(observable[Symbol.observable ?? '@@observable']).to.be.a('function');
1110
});
1211

1312
it('should simulate interop subscribers', () => {
1413
const subscriber: any = asInteropSubscriber(new Subscriber());
1514
expect(subscriber).to.not.be.instanceOf(Subscriber);
1615
});
17-
});
16+
});
Lines changed: 28 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { of, asyncScheduler, Observable, scheduled, ObservableInput } from 'rxjs';
2-
import { observable } from 'rxjs/internal/symbol/observable';
32
import { iterator } from 'rxjs/internal/symbol/iterator';
43

54
if (process && process.on) {
@@ -9,7 +8,7 @@ if (process && process.on) {
98
* it handles the rejected promise where it does not notice
109
* that the test failed.
1110
*/
12-
process.on('unhandledRejection', err => {
11+
process.on('unhandledRejection', (err) => {
1312
console.error(err);
1413
process.exit(1);
1514
});
@@ -18,45 +17,45 @@ if (process && process.on) {
1817
export function lowerCaseO<T>(...args: Array<any>): Observable<T> {
1918
const o: any = {
2019
subscribe(observer: any) {
21-
args.forEach(v => observer.next(v));
20+
args.forEach((v) => observer.next(v));
2221
observer.complete();
2322
return {
24-
unsubscribe() { /* do nothing */ }
23+
unsubscribe() {
24+
/* do nothing */
25+
},
2526
};
26-
}
27+
},
2728
};
2829

29-
o[observable] = function (this: any) {
30+
o[Symbol.observable ?? '@@observable'] = function (this: any) {
3031
return this;
3132
};
3233

3334
return <any>o;
3435
}
3536

36-
export const createObservableInputs = <T>(value: T) => of(
37-
of(value),
38-
scheduled([value], asyncScheduler),
39-
[value],
40-
Promise.resolve(value),
41-
{
42-
[iterator]: () => {
43-
const iteratorResults = [
44-
{ value, done: false },
45-
{ done: true }
46-
];
47-
return {
48-
next: () => {
49-
return iteratorResults.shift();
50-
}
51-
};
52-
}
53-
} as any as Iterable<T>,
54-
{
55-
[observable]: () => of(value)
56-
} as any
57-
) as Observable<ObservableInput<T>>;
37+
export const createObservableInputs = <T>(value: T) =>
38+
of(
39+
of(value),
40+
scheduled([value], asyncScheduler),
41+
[value],
42+
Promise.resolve(value),
43+
{
44+
[iterator]: () => {
45+
const iteratorResults = [{ value, done: false }, { done: true }];
46+
return {
47+
next: () => {
48+
return iteratorResults.shift();
49+
},
50+
};
51+
},
52+
} as any as Iterable<T>,
53+
{
54+
[Symbol.observable ?? '@@observable']: () => of(value),
55+
} as any
56+
) as Observable<ObservableInput<T>>;
5857

5958
/**
6059
* Used to signify no subscriptions took place to `expectSubscriptions` assertions.
6160
*/
62-
export const NO_SUBS: string[] = [];
61+
export const NO_SUBS: string[] = [];

packages/rxjs/spec/observables/from-spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/** @prettier */
22
import { expect } from 'chai';
33
import { TestScheduler } from 'rxjs/testing';
4-
import { asyncScheduler, of, from, Observer, observable, Subject, noop, Subscription } from 'rxjs';
4+
import { of, from, Observer, Subject, noop, Subscription } from 'rxjs';
55
import { first, concatMap, delay, take, tap } from 'rxjs/operators';
66
import { ReadableStream } from 'web-streams-polyfill';
77
import { observableMatcher } from '../helpers/observableMatcher';
@@ -166,7 +166,7 @@ describe('from', () => {
166166
});
167167

168168
const fakervable = <T>(...values: T[]) => ({
169-
[observable]: () => ({
169+
[Symbol.observable ?? '@@observable']: () => ({
170170
subscribe: (observer: Observer<T>) => {
171171
for (const value of values) {
172172
observer.next(value);
@@ -178,7 +178,7 @@ describe('from', () => {
178178

179179
const fakeArrayObservable = <T>(...values: T[]) => {
180180
let arr: any = ['bad array!'];
181-
arr[observable] = () => {
181+
arr[Symbol.observable ?? '@@observable'] = () => {
182182
return {
183183
subscribe: (observer: Observer<T>) => {
184184
for (const value of values) {
@@ -277,7 +277,7 @@ describe('from', () => {
277277
it(`should accept a function that implements [Symbol.observable]`, (done) => {
278278
const subject = new Subject<any>();
279279
const handler: any = (arg: any) => subject.next(arg);
280-
handler[observable] = () => subject;
280+
handler[Symbol.observable ?? '@@observable'] = () => subject;
281281
let nextInvoked = false;
282282

283283
from(handler as any)

packages/rxjs/src/index.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
export { Observable } from './internal/Observable';
1717
export { GroupedObservable } from './internal/operators/groupBy';
1818
export { Operator } from './internal/Operator';
19-
export { observable } from './internal/symbol/observable';
2019
export { animationFrames } from './internal/observable/dom/animationFrames';
2120

2221
/* Subjects */

packages/rxjs/src/internal/Observable.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { Subscriber } from './Subscriber';
22
import { Subscription } from './Subscription';
33
import { TeardownLogic, UnaryFunction, Subscribable, Observer, OperatorFunction } from './types';
4-
import { observable as Symbol_observable } from './symbol/observable';
54
import { pipeFromArray } from './util/pipe';
65
/**
76
* A representation of any set of values over any amount of time. This is the most basic building block
@@ -240,7 +239,7 @@ export class Observable<T> implements Subscribable<T> {
240239
* An interop point defined by the es7-observable spec https://github.com/zenparsing/es-observable
241240
* @return This instance of the observable.
242241
*/
243-
[Symbol_observable]() {
242+
[Symbol.observable ?? '@@observable']() {
244243
return this;
245244
}
246245

packages/rxjs/src/internal/observable/from.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import { isReadableStreamLike, readableStreamLikeToAsyncGenerator } from '../uti
1010
import { Subscriber } from '../Subscriber';
1111
import { isFunction } from '../util/isFunction';
1212
import { reportUnhandledError } from '../util/reportUnhandledError';
13-
import { observable as Symbol_observable } from '../symbol/observable';
1413

1514
/**
1615
* Creates an Observable from an Array, an array-like object, a Promise, an iterable object, or an Observable-like object.
@@ -117,7 +116,7 @@ export function from<T>(input: ObservableInput<T>): Observable<T> {
117116
*/
118117
function fromInteropObservable<T>(obj: any) {
119118
return new Observable((subscriber: Subscriber<T>) => {
120-
const obs = obj[Symbol_observable]();
119+
const obs = obj[Symbol.observable ?? '@@observable']();
121120
if (isFunction(obs.subscribe)) {
122121
return obs.subscribe(subscriber);
123122
}

packages/rxjs/src/internal/symbol/observable.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.
Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import { InteropObservable } from '../types';
2-
import { observable as Symbol_observable } from '../symbol/observable';
32
import { isFunction } from './isFunction';
43

54
/** Identifies an input as being Observable (but not necessary an Rx Observable) */
65
export function isInteropObservable(input: any): input is InteropObservable<any> {
7-
return isFunction(input[Symbol_observable]);
6+
return isFunction(input[Symbol.observable ?? '@@observable']);
87
}

yarn.lock

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,10 +2510,10 @@
25102510
resolved "https://registry.npmjs.org/@types/node/-/node-12.20.55.tgz"
25112511
integrity sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ==
25122512

2513-
"@types/node@^20.6.3":
2514-
version "20.6.3"
2515-
resolved "https://registry.yarnpkg.com/@types/node/-/node-20.6.3.tgz#5b763b321cd3b80f6b8dde7a37e1a77ff9358dd9"
2516-
integrity sha512-HksnYH4Ljr4VQgEy2lTStbCKv/P590tmPe5HqOnv9Gprffgv5WXAY+Y5Gqniu0GGqeTCUdBnzC3QSrzPkBkAMA==
2513+
"@types/node@^14.14.6":
2514+
version "14.18.63"
2515+
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.18.63.tgz#1788fa8da838dbb5f9ea994b834278205db6ca2b"
2516+
integrity sha512-fAtCfv4jJg+ExtXhvCkCqUKZ+4ok/JQk01qDKhL5BDDoS3AxKXhV5/MAVUZyQnSEd2GT92fkgZl0pz0Q0AzcIQ==
25172517

25182518
"@types/normalize-package-data@^2.4.0":
25192519
version "2.4.1"
@@ -16182,16 +16182,16 @@ [email protected]:
1618216182
resolved "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz"
1618316183
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
1618416184

16185-
typescript@^5.2.2:
16186-
version "5.2.2"
16187-
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78"
16188-
integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==
16189-
1619016185
typescript@~4.5.4:
1619116186
version "4.5.5"
1619216187
resolved "https://registry.npmjs.org/typescript/-/typescript-4.5.5.tgz"
1619316188
integrity sha512-TCTIul70LyWe6IJWT8QSYeA54WQe8EjQFU4wY52Fasj5UKx88LNYKCgBEHcOMOrFF1rKGbD8v/xcNWVUq9SymA==
1619416189

16190+
typescript@~4.9.4:
16191+
version "4.9.5"
16192+
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
16193+
integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
16194+
1619516195
ua-parser-js@^0.7.30:
1619616196
version "0.7.36"
1619716197
resolved "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.36.tgz"

0 commit comments

Comments
 (0)