Cannot use JS objects which throw on undefined property access
semmel opened this issue · comments
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:) an object wrapper [windowProxy]
{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); });