[next] Porting most basic examples (#1631)

This commit is contained in:
Andrea Giammarchi
2023-08-10 22:42:01 +02:00
committed by GitHub
parent 8a1db288fc
commit 75a57a49f5
38 changed files with 451 additions and 70 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,17 +1,17 @@
{
"name": "@pyscript/core",
"version": "0.1.3",
"version": "0.1.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@pyscript/core",
"version": "0.1.3",
"version": "0.1.4",
"license": "APACHE-2.0",
"dependencies": {
"@ungap/with-resolvers": "^0.1.0",
"basic-devtools": "^0.1.6",
"polyscript": "^0.1.9"
"polyscript": "^0.1.10"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.1.0",
@@ -935,9 +935,9 @@
}
},
"node_modules/polyscript": {
"version": "0.1.9",
"resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.1.9.tgz",
"integrity": "sha512-UhBcpN7FAE7MZPg10cQOXpIE9vLG6cYOrQRX37CPps4Rvl8vbUgHkzkB3qsd1DL5ztMykfeSvYPI+AIP7lx4Yw==",
"version": "0.1.10",
"resolved": "https://registry.npmjs.org/polyscript/-/polyscript-0.1.10.tgz",
"integrity": "sha512-NdO0inJIJyNgM8bYvD9z8aYbs1chQWq3iNtXjj7YrDT84A7IOVELPCFDlXzLU8UngpO/yQm3j4YrEoln89LbsA==",
"dependencies": {
"@ungap/structured-clone": "^1.2.0",
"@ungap/with-resolvers": "^0.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@pyscript/core",
"version": "0.1.3",
"version": "0.1.4",
"type": "module",
"description": "PyScript",
"main": "core.js",
@@ -32,7 +32,7 @@
"dependencies": {
"@ungap/with-resolvers": "^0.1.0",
"basic-devtools": "^0.1.6",
"polyscript": "^0.1.9"
"polyscript": "^0.1.10"
},
"devDependencies": {
"@rollup/plugin-node-resolve": "^15.1.0",

View File

@@ -54,15 +54,12 @@ const after = () => {
* It either throws an error if the 'src' can't be fetched or it returns a fallback
* content as source.
*/
const fetchSource = async (tag) => {
const fetchSource = async (tag, io) => {
if (tag.hasAttribute("src")) {
try {
const response = await fetch(tag.getAttribute("src"));
return response.then(getText);
return await fetch(tag.getAttribute("src")).then(getText);
} catch (error) {
// TODO _createAlertBanner(err) instead ?
alert(error.message);
throw error;
io.stderr(error);
}
}
return tag.textContent;
@@ -105,8 +102,16 @@ const registerModule = ({ XWorker: $XWorker, interpreter, io }) => {
? currentElement.target.id
: currentElement.id;
return (what, target = id, append = true) => {
pyDisplay.callKwargs(...[].concat(what), { target, append });
return (...args) => {
const last = args.at(-1);
let kw = { target: id, append: false };
if (
typeof last === "object" &&
last &&
("target" in last || "append" in last)
)
kw = { ...kw, ...args.pop() };
pyDisplay.callKwargs(...args, kw);
};
},
});
@@ -199,7 +204,9 @@ define("py", {
// document.currentScript.target if needed
defineProperty(element, "target", { value: show });
pyodide[`run${isAsync ? "Async" : ""}`](await fetchSource(element));
pyodide[`run${isAsync ? "Async" : ""}`](
await fetchSource(element, pyodide.io),
);
} else {
// resolve PyScriptElement to allow connectedCallback
element._pyodide.resolve(pyodide);
@@ -217,11 +224,10 @@ class PyScriptElement extends HTMLElement {
async connectedCallback() {
if (!this.executed) {
this.executed = true;
const { run } = await this._pyodide.promise;
this.srcCode = await fetchSource(this);
const { io, run } = await this._pyodide.promise;
this.srcCode = await fetchSource(this, io);
this.textContent = "";
const result = run(this.srcCode);
if (!this.textContent && result) this.textContent = result;
run(this.srcCode);
this.style.display = "block";
}
}

View File

@@ -10,7 +10,7 @@
<body>
<script type="py">
from pyscript import display
display("Hello PyScript Next")
display("Hello", "PyScript Next", append=False)
</script>
</body>
</html>

View File

@@ -0,0 +1,10 @@
export { ie as default };
declare function ie(e: any, ...r: any[]): any;
declare namespace ie {
import transfer = m.transfer;
export { transfer };
}
declare function m(t: any, { parse: n, stringify: r, transform: u }?: JSON): any;
declare namespace m {
function transfer(...e: any[]): any[];
}

View File

@@ -0,0 +1,54 @@
export const CUSTOM_SELECTORS: any[];
export function handleCustomType(node: Element): void;
export function define(type: string, options: CustomOptions): void;
export function whenDefined(type: string): Promise<object>;
/**
* custom configuration
*/
export type Runtime = {
/**
* the bootstrapped interpreter
*/
interpreter: object;
/**
* an XWorker constructor that defaults to same interpreter on the Worker.
*/
XWorker: (url: string, options?: object) => Worker;
/**
* a cloned config used to bootstrap the interpreter
*/
config: object;
/**
* an utility to run code within the interpreter
*/
run: (code: string) => any;
/**
* an utility to run code asynchronously within the interpreter
*/
runAsync: (code: string) => Promise<any>;
/**
* an utility to write a file in the virtual FS, if available
*/
writeFile: (path: string, data: ArrayBuffer) => void;
};
/**
* custom configuration
*/
export type CustomOptions = {
/**
* the interpreter to use
*/
interpreter: 'pyodide' | 'micropython' | 'wasmoon' | 'ruby-wasm-wasi';
/**
* the optional interpreter version to use
*/
version?: string;
/**
* the optional config to use within such interpreter
*/
config?: string;
/**
* the callback that will be invoked once
*/
onInterpreterReady?: (environment: object, node: Element) => void;
};

View File

@@ -0,0 +1,3 @@
export function getBuffer(response: Response): Promise<ArrayBuffer>;
export function getJSON(response: Response): Promise<any>;
export function getText(response: Response): Promise<string>;

View File

@@ -0,0 +1,3 @@
export { env } from "./listeners.js";
export const XWorker: (url: string, options?: import("./worker/class.js").WorkerOptions) => Worker;
export { define, whenDefined } from "./custom.js";

View File

@@ -0,0 +1,4 @@
export function registerJSModule(interpreter: any, name: any, value: any): void;
export function run(interpreter: any, code: any): any;
export function runAsync(interpreter: any, code: any): any;
export function runEvent(interpreter: any, code: any, event: any): Promise<void>;

View File

@@ -0,0 +1,15 @@
export function clean(code: string): string;
export const io: WeakMap<object, any>;
export function stdio(init: any): {
stderr: (...args: any[]) => any;
stdout: (...args: any[]) => any;
get(engine: any): Promise<any>;
};
export function writeFile({ FS, PATH, PATH_FS }: {
FS: any;
PATH: any;
PATH_FS: any;
}, path: any, buffer: any): any;
export function writeFileShim(FS: any, path: any, buffer: any): any;
export const base: WeakMap<object, any>;
export function fetchPaths(module: any, interpreter: any, config_fetch: any): Promise<any[]>;

View File

@@ -0,0 +1,25 @@
declare namespace _default {
export { type };
export function module(version?: string): string;
export function engine({ loadMicroPython }: {
loadMicroPython: any;
}, config: any, url: any): Promise<any>;
export { registerJSModule };
export { run };
export { runAsync };
export { runEvent };
export function transform(_: any, value: any): any;
export function writeFile({ FS, _module: { PATH, PATH_FS } }: {
FS: any;
_module: {
PATH: any;
PATH_FS: any;
};
}, path: any, buffer: any): any;
}
export default _default;
declare const type: "micropython";
import { registerJSModule } from './_python.js';
import { run } from './_python.js';
import { runAsync } from './_python.js';
import { runEvent } from './_python.js';

View File

@@ -0,0 +1,25 @@
declare namespace _default {
export { type };
export function module(version?: string): string;
export function engine({ loadPyodide }: {
loadPyodide: any;
}, config: any, url: any): Promise<any>;
export { registerJSModule };
export { run };
export { runAsync };
export { runEvent };
export function transform(interpreter: any, value: any): any;
export function writeFile({ FS, PATH, _module: { PATH_FS } }: {
FS: any;
PATH: any;
_module: {
PATH_FS: any;
};
}, path: any, buffer: any): any;
}
export default _default;
declare const type: "pyodide";
import { registerJSModule } from './_python.js';
import { run } from './_python.js';
import { runAsync } from './_python.js';
import { runEvent } from './_python.js';

View File

@@ -0,0 +1,16 @@
declare namespace _default {
export { type };
export let experimental: boolean;
export function module(version?: string): string;
export function engine({ DefaultRubyVM }: {
DefaultRubyVM: any;
}, config: any, url: any): Promise<any>;
export function registerJSModule(interpreter: any, _: any, value: any): void;
export function run(interpreter: any, code: any): any;
export function runAsync(interpreter: any, code: any): any;
export function runEvent(interpreter: any, code: any, event: any): Promise<void>;
export function transform(_: any, value: any): any;
export function writeFile(): never;
}
export default _default;
declare const type: "ruby-wasm-wasi";

View File

@@ -0,0 +1,22 @@
declare namespace _default {
export { type };
export function module(version?: string): string;
export function engine({ LuaFactory, LuaLibraries }: {
LuaFactory: any;
LuaLibraries: any;
}, config: any): Promise<any>;
export function registerJSModule(interpreter: any, _: any, value: any): void;
export function run(interpreter: any, code: any): any;
export function runAsync(interpreter: any, code: any): any;
export function runEvent(interpreter: any, code: any, event: any): Promise<void>;
export function transform(_: any, value: any): any;
export function writeFile({ cmodule: { module: { FS }, }, }: {
cmodule: {
module: {
FS: any;
};
};
}, path: any, buffer: any): any;
}
export default _default;
declare const type: "wasmoon";

View File

@@ -0,0 +1,9 @@
/** @type {Map<string, object>} */
export const registry: Map<string, object>;
/** @type {Map<string, object>} */
export const configs: Map<string, object>;
/** @type {string[]} */
export const selectors: string[];
/** @type {string[]} */
export const prefixes: string[];
export const interpreter: Map<any, any>;

View File

@@ -0,0 +1,3 @@
export const env: any;
export function listener(event: any): Promise<void>;
export function addAllListeners(root: Document | Element): void;

View File

@@ -0,0 +1,2 @@
export function getRuntime(id: string, config?: string, options?: object): Promise<any>;
export function getRuntimeID(type: string, version?: string): string;

View File

@@ -0,0 +1,4 @@
export function queryTarget(script: any, idOrSelector: any): any;
export const interpreters: Map<any, any>;
export function getDetails(type: any, id: any, name: any, version: any, config: any, runtime?: any): any;
export function handle(script: HTMLScriptElement): Promise<void>;

View File

@@ -0,0 +1 @@
export function parse(text: string): object;

View File

@@ -0,0 +1,29 @@
export const isArray: (arg: any) => arg is any[];
export const assign: {
<T extends {}, U>(target: T, source: U): T & U;
<T_1 extends {}, U_1, V>(target: T_1, source1: U_1, source2: V): T_1 & U_1 & V;
<T_2 extends {}, U_2, V_1, W>(target: T_2, source1: U_2, source2: V_1, source3: W): T_2 & U_2 & V_1 & W;
(target: object, ...sources: any[]): any;
};
export const create: {
(o: object): any;
(o: object, properties: PropertyDescriptorMap & ThisType<any>): any;
};
export const defineProperties: <T>(o: T, properties: PropertyDescriptorMap & ThisType<any>) => T;
export const defineProperty: <T>(o: T, p: PropertyKey, attributes: PropertyDescriptor & ThisType<any>) => T;
export const entries: {
<T>(o: {
[s: string]: T;
} | ArrayLike<T>): [string, T][];
(o: {}): [string, any][];
};
export const all: {
<T>(values: Iterable<T | PromiseLike<T>>): Promise<Awaited<T>[]>;
<T_1 extends [] | readonly unknown[]>(values: T_1): Promise<{ -readonly [P in keyof T_1]: Awaited<T_1[P]>; }>;
};
export const resolve: {
(): Promise<void>;
<T>(value: T): Promise<Awaited<T>>;
<T_1>(value: T_1 | PromiseLike<T_1>): Promise<Awaited<T_1>>;
};
export function absoluteURL(path: any, base?: string): string;

View File

@@ -0,0 +1,19 @@
declare function _default(...args: any[]): (url: string, options?: WorkerOptions) => Worker;
export default _default;
/**
* custom configuration
*/
export type WorkerOptions = {
/**
* the interpreter type to use
*/
type: string;
/**
* the optional interpreter version to use
*/
version?: string;
/**
* the optional config to use within such interpreter
*/
config?: string;
};

View File

@@ -0,0 +1,6 @@
export class Hook {
constructor(interpreter: any, options: any);
interpreter: any;
onWorkerReady: any;
get stringHooks(): {};
}

View File

@@ -0,0 +1,2 @@
declare function _default(): Worker;
export default _default;

View File

@@ -0,0 +1,25 @@
/**
* A `Worker` facade able to bootstrap on the worker thread only a PyScript module.
* @param {string} file the python file to run ina worker.
* @param {{config?: string | object, async?: boolean}} [options] optional configuration for the worker.
* @returns {Worker & {sync: ProxyHandler<object>}}
*/
export function PyWorker(file: string, options?: {
config?: string | object;
async?: boolean;
}): Worker & {
sync: ProxyHandler<object>;
};
export namespace hooks {
let onBeforeRun: Set<Function>;
let onBeforeRunAync: Set<Function>;
let onAfterRun: Set<Function>;
let onAfterRunAsync: Set<Function>;
let onInterpreterReady: Set<Function>;
let codeBeforeRunWorker: Set<string>;
let codeBeforeRunWorkerAsync: Set<string>;
let codeAfterRunWorker: Set<string>;
let codeAfterRunWorkerAsync: Set<string>;
}
declare let config: any;
export {};

View File

@@ -0,0 +1,27 @@
export function _createAlertBanner(message: any, level: any, messageType?: string, logMessage?: boolean): void;
export namespace ErrorCode {
let GENERIC: string;
let FETCH_ERROR: string;
let FETCH_NAME_ERROR: string;
let FETCH_UNAUTHORIZED_ERROR: string;
let FETCH_FORBIDDEN_ERROR: string;
let FETCH_NOT_FOUND_ERROR: string;
let FETCH_SERVER_ERROR: string;
let FETCH_UNAVAILABLE_ERROR: string;
let BAD_CONFIG: string;
let MICROPIP_INSTALL_ERROR: string;
let BAD_PLUGIN_FILE_EXTENSION: string;
let NO_DEFAULT_EXPORT: string;
let TOP_LEVEL_AWAIT: string;
}
export class UserError extends Error {
constructor(errorCode: any, message?: string, messageType?: string);
errorCode: any;
messageType: string;
}
export class FetchError extends UserError {
constructor(errorCode: any, message: any);
}
export class InstallError extends UserError {
constructor(errorCode: any, message: any);
}

View File

@@ -0,0 +1,10 @@
/**
* This is a fetch wrapper that handles any non 200 responses and throws a
* FetchError with the right ErrorCode. This is useful because our FetchError
* will automatically create an alert banner.
*
* @param {string} url - URL to fetch
* @param {Request} [options] - options to pass to fetch
* @returns {Promise<Response>}
*/
export function robustFetch(url: string, options?: Request): Promise<Response>;