This is the mirror image of #2170.

### Checklists

<!-- Note on checklists:
     If you think some of these steps are not necessary for your PR,
     just remove those checkboxes, or mark them as checked. Otherwise,
     if some checkboxes are left unmarked, we might assume that your PR
     is not ready to be merged and we might keep you waiting -->

- [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

Add `default_converter` argument to `to_js` and `toJs`. This is the mirror image of #2170.

### Checklists

<!-- Note on checklists:
     If you think some of these steps are not necessary for your PR,
     just remove those checkboxes, or mark them as checked. Otherwise,
     if some checkboxes are left unmarked, we might assume that your PR
     is not ready to be merged and we might keep you waiting -->

- [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

import { loadPyodide } from "./pyodide.mjs";

onmessage = async function (e) {
  try {
    const data = e.data;
    for (let key of Object.keys(data)) {
      if (key !== "python") {
        // Keys other than python must be arguments for the python script.
        // Set them on self, so that `from js import key` works.
        self[key] = data[key];
      }
    }

    if (!loadPyodide.inProgress) {
      self.pyodide = await loadPyodide({ indexURL: "{{ PYODIDE_BASE_URL }}" });
    }
    await self.pyodide.loadPackagesFromImports(data.python);
    let results = await self.pyodide.runPythonAsync(data.python);
    self.postMessage({ results });
  } catch (e) {
    // if you prefer messages with the error
    self.postMessage({ error: e.message + "\n" + e.stack });
    // if you prefer onerror events
    // setTimeout(() => { throw err; });
  }
};

import { loadPyodide } from "./pyodide.mjs";

onmessage = async function (e) {
  try {
    const data = e.data;
    for (let key of Object.keys(data)) {
      if (key !== "python") {
        // Keys other than python must be arguments for the python script.
        // Set them on self, so that `from js import key` works.
        self[key] = data[key];
      }
    }

    if (!loadPyodide.inProgress) {
      self.pyodide = await loadPyodide({ indexURL: "{{ PYODIDE_BASE_URL }}" });
    }
    await self.pyodide.loadPackagesFromImports(data.python);
    let results = await self.pyodide.runPythonAsync(data.python);
    self.postMessage({ results });
  } catch (e) {
    // if you prefer messages with the error
    self.postMessage({ error: e.message + "\n" + e.stack });
    // if you prefer onerror events
    // setTimeout(() => { throw err; });
  }
};
