8000 Fix #77 - Allow `configURL` to be passed for custom types by WebReflection · Pull Request #78 · pyscript/polyscript · GitHub
[go: up one dir, main page]

Skip to content

Fix #77 - Allow configURL to be passed for custom types #78

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

Merged
merged 1 commit into from
Jan 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -586,6 +586,7 @@ The list of options' fields is described as such and all of these are *optional*
| :------------------------ | :-------------------------------------------- | :--------|
| interpreter | `{interpreter: 'pyodide'}` | Specifies the interpreter to use, such as *pyodide*, *micropython*, *wasmoon* or others. |
| config | `{config: 'type.toml'}` `{config: {}}` | Ensure such config is already parsed and available, if not already passed as object, for every custom `type` that execute code. |
| configURL | `{configURL: '/absolute/url/config.json'}` | If the passed `config` is an already resolved object, this field is neded to help resolving files in *fetch* or *packages* or others. |
| version | `{version: '0.23.2'}` | Allow the usage of a specific version of an interpreter, same way `version` attribute works with `<script>` elements. |
| env | `{env: 'my-project'}` | Guarantee same environment for every custom `type`, avoiding conflicts with any other possible default or custom environment. |
| onerror | `(error, element) => { throw error; }` | Allows custom types to intercept early errors possibly happened while bootstrapping elements. |
Expand Down
4 changes: 2 additions & 2 deletions docs/core.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/core.js.map

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions esm/custom.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export const handleCustomType = (node) => {
known.add(node);
const {
interpreter: runtime,
configURL,
config,
version,
env,
Expand All @@ -55,6 +56,7 @@ export const handleCustomType = (node) => {
const xworker = XWorker.call(new Hook(null, hooks), worker, {
...nodeInfo(node, type),
version,
configURL,
type: runtime,
custom: type,
config: node.getAttribute('config') || config || {},
Expand All @@ -78,6 +80,7 @@ export const handleCustomType = (node) => {
name,
version,
config,
configURL,
runtime
);
engine.then((interpreter) => {
Expand Down
3 changes: 3 additions & 0 deletions esm/exports.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// this file simply exports enough stuff to allow
// 3rd party libraries, including PyScript, to work
import toJSONCallback from 'to-json-callback';
export { toJSONCallback };

export * from './fetch-utils.js';
export * from './index.js';
export * from './script-handler.js';
Expand Down
20 changes: 20 additions & 0 deletions esm/interpreter/_io.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// REQUIRES INTEGRATION TEST
/* c8 ignore start */
export const io = new WeakMap();
export const stdio = (init) => {
const context = init || console;
const localIO = {
stderr: (context.stderr || console.error).bind(context),
stdout: (context.stdout || console.log).bind(context),
};
return {
stderr: (...args) => localIO.stderr(...args),
stdout: (...args) => localIO.stdout(...args),
async get(engine) {
const interpreter = await engine;
io.set(interpreter, localIO);
return interpreter;
},
};
};
/* c8 ignore stop */
2 changes: 1 addition & 1 deletion esm/interpreter/_python.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { dedent } from '../utils.js';
import { io } from './_utils.js';
import { io } from './_io.js';

// REQUIRES INTEGRATION TEST
/* c8 ignore start */
Expand Down
17 changes: 0 additions & 17 deletions esm/interpreter/_utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,6 @@ import { absoluteURL, all, entries, importCSS, importJS, isArray, isCSS } from '

// REQUIRES INTEGRATION TEST
/* c8 ignore start */
export const io = new WeakMap();
export const stdio = (init) => {
const context = init || console;
const localIO = {
stderr: (context.stderr || console.error).bind(context),
stdout: (context.stdout || console.log).bind(context),
};
return {
stderr: (...args) => localIO.stderr(...args),
stdout: (...args) => localIO.stdout(...args),
async get(engine) {
const interpreter = await engine;
io.set(interpreter, localIO);
return interpreter;
},
};
};

// This should be the only helper needed for all Emscripten based FS exports
export const writeFile = ({ FS, PATH, PATH_FS }, path, buffer) => {
Expand Down
3 changes: 2 additions & 1 deletion esm/interpreter/micropython.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, writeFile } from './_utils.js';
import { registerJSModule, run, runAsync, runEvent } from './_python.js';
import { stdio } from './_io.js';
import mip from '../python/mip.js';

const type = 'micropython';
Expand Down
3 changes: 2 additions & 1 deletion esm/interpreter/pyodide.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { fetchFiles, fetchJSModules, fetchPaths, stdio, writeFile } from './_utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, writeFile } from './_utils.js';
import { registerJSModule, run, runAsync, runEvent } from './_python.js';
import { stdio } from './_io.js';

const type = 'pyodide';
const toJsOptions = { dict_converter: Object.fromEntries };
Expand Down
3 changes: 2 additions & 1 deletion esm/interpreter/wasmoon.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { dedent } from '../utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, io, stdio, writeFileShim } from './_utils.js';
import { fetchFiles, fetchJSModules, fetchPaths, writeFileShim } from './_utils.js';
import { io, stdio } from './_io.js';

const type = 'wasmoon';

Expand Down
11 changes: 6 additions & 5 deletions esm/loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ import { getJSON, getText } from './fetch-utils.js';

// REQUIRES INTEGRATION TEST
/* c8 ignore start */
export const getConfigURLAndType = config => {
export const getConfigURLAndType = (config, configURL = './config.txt') => {
let type = typeof config;
if (type === 'string' && /\.(json|toml|txt)$/.test(config))
type = RegExp.$1;
else
config = './config.txt';
config = configURL;
return [absoluteURL(config), type];
};

Expand All @@ -29,15 +29,16 @@ const parseString = config => {
* options to use as it is to avoid needing at all a fetch operation.
* In latter case, config will be suffixed as `config.txt`.
* @param {string} id the interpreter name @ version identifier
* @param {string} [config] optional config file to parse
* @param {string | object} config optional config file to parse
* @param {string} [configURL] optional config URL if config is not string
* @param {object} [options] optional options used to bootstrap XWorker
* @returns
*/
export const getRuntime = (id, config, options = {}) => {
export const getRuntime = (id, config, configURL, options = {}) => {
if (config) {
// REQUIRES INTEGRATION TEST
/* c8 ignore start */
const [absolute, type] = getConfigURLAndType(config);
const [absolute, type] = getConfigURLAndType(config, configURL);
if (type === 'json') {
options = fetch(absolute).then(getJSON);
} else if (type === 'toml') {
Expand Down
4 changes: 2 additions & 2 deletions esm/script-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ const getValue = (ref, prefix) => {
return value ? prefix + value : '';
};

export const getDetails = (type, id, name, version, config, runtime = type) => {
export const getDetails = (type, id, name, version, config, configURL, runtime = type) => {
if (!interpreters.has(id)) {
const details = {
interpreter: getRuntime(name, config),
interpreter: getRuntime(name, config, configURL),
queue: resolve(),
XWorker: $xworker(type, version),
};
Expand Down
2 changes: 1 addition & 1 deletion esm/utils.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import $dedent from 'codedent';
import { unescape as $unescape } from 'html-escaper';
import { io } from './interpreter/_utils.js';
import { io } from './interpreter/_io.js';

/** @type {(tpl: string | TemplateStringsArray, ...values:any[]) => string} */
const dedent = $dedent;
Expand Down
4 changes: 2 additions & 2 deletions esm/worker/_template.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,13 +65,13 @@ const xworker = {
postMessage: postMessage.bind(self),
};

add('message', ({ data: { options, config: baseURL, code, hooks } }) => {
add('message', ({ data: { options, config: baseURL, configURL, code, hooks } }) => {
interpreter = (async () => {
try {
const { id, tag, type, custom, version, config, async: isAsync } = options;
const runtimeID = getRuntimeID(type, version);

const interpreter = await getRuntime(runtimeID, baseURL, config);
const interpreter = await getRuntime(runtimeID, baseURL, configURL, config);

const mainModules = configs.get(runtimeID).js_modules?.main;

Expand Down
5 changes: 3 additions & 2 deletions esm/worker/class.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ import Hook from './hook.js';
* @typedef {Object} WorkerOptions custom configuration
* @prop {string} type the interpreter type to use
* @prop {string} [version] the optional interpreter version to use
* @prop {string} [config] the optional config to use within such interpreter
* @prop {string | object} [config] the optional config to use within such interpreter
* @prop {string} [configURL] the optional configURL used to resolve config entries
*/

export default (...args) =>
Expand All @@ -34,7 +35,7 @@ export default (...args) =>
// provide a base url to fetch or load config files from a Worker
// because there's no location at all in the Worker as it's embedded.
// fallback to a generic, ignored, config.txt file to still provide a URL.
const [ config ] = getConfigURLAndType(options.config);
const [ config ] = getConfigURLAndType(options.config, options.configURL);

const bootstrap = fetch(url)
.then(getText)
Expand Down
4 changes: 3 additions & 1 deletion esm/worker/hook.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import toJSONCallback from 'to-json-callback';

import { dedent } from '../utils.js';
import { js as jsHooks, code as codeHooks } from '../hooks.js';

Expand All @@ -18,7 +20,7 @@ export default class Hook {
const hooks = {};
// ignore onWorker as that's main only
for (const key of jsHooks.slice(1)) {
if (t 1241 his[key]) hooks[key] = String(this[key]);
if (this[key]) hooks[key] = toJSONCallback(this[key]);
}
// code related: exclude `onReady` callback
for (const key of codeHooks) {
Expand Down
Loading
0