RxJS incorrectly defines observable symbol

Bug Report

It would appear that the current way RxJS detects other observables is not working as expected, while other libraries can adapt from each other.

Current Behavior
The from function in RxJS 6.3.3 does not seem able to adapt xstream and most while the older RxJS 5 Observable.from was able to. The following error is reproduced in both cases:

TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

Both xstream and most provide Symbol polyfills:

Additional testing has confirmed:

  • This issue does not occur in webpack but it does in node, jest, and browserify.
  • The order of import seems to matter.

Reproduction

  • From xstream to rxjs, does not work:
const { from: observableFrom } = require('rxjs')
const { isInteropObservable } = require('rxjs/internal/util/isInteropObservable')
const { default: xs } = require('xstream')

const num$ = xs.from([ 1, 2, 3, 4 ])
console.log('Is num$ an observable?', isInteropObservable(num$)) // false

const adapt$ = observableFrom(num$) // error here
adapt$.subscribe(console.log)
  • From xstream to rxjs, working after importing xstream first:
const { default: xs } = require('xstream')
const { from: observableFrom } = require('rxjs')
const { isInteropObservable } = require('rxjs/internal/util/isInteropObservable')

const num$ = xs.from([ 1, 2, 3, 4 ])
console.log('Is num$ an observable?', isInteropObservable(num$)) // true

const adapt$ = observableFrom(num$)
adapt$.subscribe(console.log)
  • The same behaviour in most, not working:
const { from: observableFrom } = require('rxjs')
const { isInteropObservable } = require('rxjs/internal/util/isInteropObservable')
const most = require('most')

const num$ = most.from([ 1, 2, 3, 4 ])
console.log('Is num$ an observable?', isInteropObservable(num$)) // false

const adapt$ = observableFrom(num$) // error here
adapt$.subscribe(console.log)
  • We cannot convert rxjs to xstream either unless we import xstream first:
const { from: observableFrom } = require('rxjs')
const { default: xs } = require('xstream')

const num$ = observableFrom([ 1, 2, 3, 4 ])
const adapt$ = xs.from(num$)

adapt$.addListener({
  next: console.log
})

Expected behavior
The order of import should not matter, and the jest environment would work like webpack.

Environment

  • Runtime: Node v11.3.0
  • RxJS version: 6.3.3
  • xstream version: 11.7.0
  • most version: 1.7.3

Possible Solution

  • The file rxjs/src/internal/symbol/observable.ts could be defined the same way the other libraries do it:
Symbol('observable')
  • The isInteropObservable could be patched to check for the same symbol xstream and most use?
  • A similar polyfill to xstream or most could be included?

Additional context/Screenshots

  • This issue came about while working on a cyclejs project with rxjs.
  • Adding the following to jest.setup.js seems to have fixed the issue for now:
import xs from 'xstream' // eslint-disable-line

Thank you and sorry in advance if I’ve diagnosed the wrong source 🙇‍♂️

1 possible answer(s) on “RxJS incorrectly defines observable symbol

  1. Any updates on this? I faced this issue with refract-rxjs which revalidates existence of symbol. It brought a hard to track bug that started to occur when I reordered my imports.