Add hereditary option to as_object_map. This automatically apply as_object_map to the values of the map when the values are "plain old objects".

This behavior is slightly naive but I think it will satisfy most people who have requested this feature.


- [x] Add a [CHANGELOG](https://github.com/pyodide/pyodide/blob/main/docs/project/changelog.md) entry
- [x] Add / update tests
- [x] Add new / update outdated documentation

#ifndef JSPROXY_H
#define JSPROXY_H
// clang-format off
#define PY_SSIZE_T_CLEAN
#include "Python.h"
// clang-format on
#include "hiwire.h"

/** A Python object that a JavaScript object inside. Used for any non-standard
 *  data types that are passed from JavaScript to Python.
 */

/** Make a new JsProxy.
 *  \param v The JavaScript object.
 *  \return The Python object wrapping the JavaScript object.
 */
PyObject*
JsProxy_create(JsRef v);

PyObject*
JsProxy_create_with_this(JsRef object, JsRef this);

/** Check if a Python object is a JsProxy object.
 *  \param x The Python object
 *  \return true if the object is a JsProxy object.
 */
bool
JsProxy_Check(PyObject* x);

/** Grab the underlying JavaScript object from the JsProxy object.
 *  \param x The JsProxy object.  Must confirm that it is a JsProxy object using
 *    JsProxy_Check. \return The JavaScript object.
 */
JsRef
JsProxy_AsJs(PyObject* x);

/**
 * obj must be a JsProxy of a buffer (we do no checking!)
 * Make a new Python Buffer object and copy the data from obj into
 *
 */
PyObject*
JsBuffer_CloneIntoPython(JsRef jsbuffer,
                         Py_ssize_t byteLength,
                         char* format,
                         Py_ssize_t itemsize);

/** Initialize global state for the JsProxy functionality. */
int
JsProxy_init(PyObject* core_module);

#endif /* JSPROXY_H */

/**
 * A Python object that wraps a JavaScript object. Used to allow JavaScript
 * objects to be passed into Python.
 */
#ifndef JSPROXY_H
#define JSPROXY_H
// clang-format off
#define PY_SSIZE_T_CLEAN
#include "Python.h"
// clang-format on
#include "hiwire.h"

/**
 *
 */
int
JsProxy_compute_typeflags(JsRef obj);

PyObject*
JsProxy_create_with_type(int type_flags, JsRef object, JsRef this);

PyObject*
JsProxy_create_objmap(JsRef object, bool objmap);

/**
 * Make a new JsProxy.
 * @param object The JavaScript object.
 * @param this If object is a function, the value of this to be used when
 *        calling it.
 * @return The Python object wrapping the JavaScript object.
 */
PyObject*
JsProxy_create_with_this(JsRef object, JsRef this);

/**
 * Make a new JsProxy.
 * @param v The JavaScript object.
 * @return The Python object wrapping the JavaScript object.
 */
PyObject*
JsProxy_create(JsRef v);

/**
 * Check if a Python object is a JsProxy.
 * @param x The Python object
 * @return true if the object is a JsProxy.
 */
bool
JsProxy_Check(PyObject* x);

/**
 * Grab the underlying JavaScript object from the JsProxy.
 * @param x The JsProxy object. Will fatally fail if it isn't a JsProxy.
 * @return The JavaScript object.
 */
JsRef
JsProxy_AsJs(PyObject* x);

/** Initialize global state for JsProxy functionality. */
int
JsProxy_init(PyObject* core_module);

#endif /* JSPROXY_H */
