Skip to content

Objects created in a different window are not reactively wrapped by store #2366

@katywings

Description

@katywings

Describe the bug

If you share a store setter from an iframe to its parent and call it via the parent, objects assigned to the store via this method, will not be reactive.

Your Example Website or App

https://stackblitz.com/edit/github-gerxph-42ncis?file=src%2Froutes%2Findex.tsx

Steps to Reproduce the Bug or Issue

  1. Share a store setter from an iframe with its parent window
  2. Listen to all values inside of the store, e.g. with createEffect(() => console.log(JSON.stringify(state))
  3. Via the parent window, assign a new object to the store
  4. Via the parent window, update a value inside of this new object
  5. Notice how this change will not trigger a console.log

Expected behavior

Objects assigned to a store via a different window should become reactive like any other object.

Screenshots or Videos

No response

Platform

  • OS: [Linux]
  • Browser: [Chrome, Firefox]

Additional context

The reason why objects assigned this way will not be reactive, is the prototype check in

proto === Object.prototype ||
. Different windows have different Object.prototype and therefore an object assigned via another window, will not be considered as wrappable by solid store.

Since the prototype check works as intended for normal non-iframe use cases, a sensible way would be to just allow a hook into the check, e.g. something like this:

const wrappablePrototypes = [Object.prototype];
export const registerWrappablePrototype = (p) => wrappablePrototypes.push(p);

export function isWrappable(obj: any) {
  let proto;
  return (
    obj != null &&
    typeof obj === "object" &&
    (obj[$PROXY] ||
      !(proto = Object.getPrototypeOf(obj)) ||
      wrappablePrototypes.indexOf(proto) >= 0 ||
      Array.isArray(obj))
  );
}

registerWrappablePrototype would allow advanced developers to add parent/iframe Object.prototype, vice-versa.


Edit: Alternative: how about we use duck typing to figure out if proto is wrappable, if it quacks like a Object.prototype it must be one. We would just have to make sure that the duck typing works across realms.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions