Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot use JS objects which throw on undefined property access #802

Open
semmel opened this issue Sep 30, 2022 · 0 comments
Open

Cannot use JS objects which throw on undefined property access #802

semmel opened this issue Sep 30, 2022 · 0 comments

Comments

@semmel
Copy link
Member

semmel commented Sep 30, 2022

An example of such an "exotic" object is the Cross-Origin WindowProxy object. It throws when trying to access (i.e. getOwnProperty) any property other than the handful of allowed properties.

Observed behaviour:

Combining an observable of WindowProxy with any other observable will generate a DOM SecurityError ("Blocked a frame from accessing a cross-origin frame…")

Reason:

The implementation of combine calls isObservable on the stream value. isObservable is simply winProxy._isObservable which fails.

Solution:

Can't see any.
Switching to winProxy instanceof Observable from winProxy._isObservable would work, but that was in #639 deliberately introduced to support X-frame observables I guess.

Not understanding the code, I guess combine needs to do some dependency checks and therefore inspects the incoming stream values. So no way to remove that – at first glance – useless check.

Workaround:

Wrap/Unwrap "exotic" objects before injecting into/when extracting from bacon streams. E.g. use (Edit:) [windowProxy] an object wrapper {windowProxy} as stream value.

Edit:

You cannot wrap the "exotic" object in a simple Array, because that gets flattened internally and it's items inspected (._isObservable) as well.

Maybe another topic, but

I don't expect my array-type stream events being accessed in any way (here being iterated over) by the reactive stream library for internal purposes. 😮

I mean; isn't the deal, that I put my things into the stream, which conveys the things to my combiners and my consumers?

Demo:

On JSitor REPL

B.fromEvent(button, 'click')
    .map(() => open(
      "https://example.com", 
      "demo-popup", 
      "popup,width=200,height=200"
    ))
    //.map(_ => [_])   // Edit: NO workaround
    //.map(proxy => ({proxy}))  // workaround
    .delay(2000)  // wait for example.com to respond
    .combine(B.constant("foo"), pair)
    .onValue(([, foo]) => { console.log(foo); });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant