mirror of
https://github.com/pyscript/pyscript.git
synced 2025-12-19 18:27:29 -05:00
Added py:all-done event (#1756)
This commit is contained in:
committed by
GitHub
parent
b9a1227e47
commit
3ac2ac0982
62
pyscript.core/src/all-done.js
Normal file
62
pyscript.core/src/all-done.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import TYPES from "./types.js";
|
||||
import hooks from "./hooks.js";
|
||||
|
||||
const DONE = "py:all-done";
|
||||
|
||||
const {
|
||||
onAfterRun,
|
||||
onAfterRunAsync,
|
||||
codeAfterRunWorker,
|
||||
codeAfterRunWorkerAsync,
|
||||
} = hooks;
|
||||
|
||||
const waitForIt = [];
|
||||
const codes = [];
|
||||
|
||||
const codeFor = (element) => {
|
||||
const isAsync = element.hasAttribute("async");
|
||||
const { promise, resolve } = Promise.withResolvers();
|
||||
const type = `${DONE}:${waitForIt.push(promise)}`;
|
||||
|
||||
// resolve each promise once notified
|
||||
addEventListener(type, resolve, { once: true });
|
||||
|
||||
if (element.hasAttribute("worker")) {
|
||||
const code = `
|
||||
from pyscript import window as _w
|
||||
_w.dispatchEvent(_w.Event.new("${type}"))
|
||||
`;
|
||||
if (isAsync) codeAfterRunWorkerAsync.add(code);
|
||||
else codeAfterRunWorker.add(code);
|
||||
return code;
|
||||
}
|
||||
|
||||
// dispatch only once the ready element is the same
|
||||
const code = (_, el) => {
|
||||
if (el === element) dispatchEvent(new Event(type));
|
||||
};
|
||||
|
||||
if (isAsync) onAfterRunAsync.add(code);
|
||||
else onAfterRun.add(code);
|
||||
return code;
|
||||
};
|
||||
|
||||
const selector = [];
|
||||
for (const [TYPE] of TYPES)
|
||||
selector.push(`script[type="${TYPE}"]`, `${TYPE}-script`);
|
||||
|
||||
// loop over all known scripts and elements
|
||||
for (const element of document.querySelectorAll(selector.join(",")))
|
||||
codes.push(codeFor(element));
|
||||
|
||||
// wait for all the things then cleanup
|
||||
Promise.all(waitForIt).then(() => {
|
||||
// cleanup unnecessary hooks
|
||||
for (const code of codes) {
|
||||
onAfterRun.delete(code);
|
||||
onAfterRunAsync.delete(code);
|
||||
codeAfterRunWorker.delete(code);
|
||||
codeAfterRunWorkerAsync.delete(code);
|
||||
}
|
||||
dispatchEvent(new Event(DONE));
|
||||
});
|
||||
@@ -1,16 +1,21 @@
|
||||
/*! (c) PyScript Development Team */
|
||||
|
||||
import "@ungap/with-resolvers";
|
||||
import { INVALID_CONTENT, define, XWorker } from "polyscript";
|
||||
|
||||
// TODO: this is not strictly polyscript related but handy ... not sure
|
||||
// we should factor this utility out a part but this works anyway.
|
||||
// These imports can hook more than usual and help debugging possible polyscript issues
|
||||
import {
|
||||
INVALID_CONTENT,
|
||||
define,
|
||||
XWorker,
|
||||
} from "../node_modules/polyscript/esm/index.js";
|
||||
import { queryTarget } from "../node_modules/polyscript/esm/script-handler.js";
|
||||
import { dedent, dispatch } from "../node_modules/polyscript/esm/utils.js";
|
||||
import { Hook } from "../node_modules/polyscript/esm/worker/hooks.js";
|
||||
|
||||
import "./all-done.js";
|
||||
import TYPES from "./types.js";
|
||||
import configs from "./config.js";
|
||||
import hooks from "./hooks.js";
|
||||
import sync from "./sync.js";
|
||||
import stdlib from "./stdlib.js";
|
||||
import { ErrorCode } from "./exceptions.js";
|
||||
@@ -66,28 +71,6 @@ const registerModule = ({ XWorker: $XWorker, interpreter, io }) => {
|
||||
interpreter.runPython(stdlib, { globals: interpreter.runPython("{}") });
|
||||
};
|
||||
|
||||
export const hooks = {
|
||||
/** @type {Set<function>} */
|
||||
onBeforeRun: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onBeforeRunAsync: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onAfterRun: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onAfterRunAsync: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onInterpreterReady: new Set(),
|
||||
|
||||
/** @type {Set<string>} */
|
||||
codeBeforeRunWorker: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeBeforeRunWorkerAsync: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeAfterRunWorker: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeAfterRunWorkerAsync: new Set(),
|
||||
};
|
||||
|
||||
const workerHooks = {
|
||||
codeBeforeRunWorker: () =>
|
||||
[stdlib, ...hooks.codeBeforeRunWorker].map(dedent).join("\n"),
|
||||
@@ -100,7 +83,7 @@ const workerHooks = {
|
||||
};
|
||||
|
||||
const exportedConfig = {};
|
||||
export { exportedConfig as config };
|
||||
export { exportedConfig as config, hooks };
|
||||
|
||||
for (const [TYPE, interpreter] of TYPES) {
|
||||
const { config, plugins, error } = configs.get(TYPE);
|
||||
|
||||
21
pyscript.core/src/hooks.js
Normal file
21
pyscript.core/src/hooks.js
Normal file
@@ -0,0 +1,21 @@
|
||||
export default {
|
||||
/** @type {Set<function>} */
|
||||
onBeforeRun: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onBeforeRunAsync: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onAfterRun: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onAfterRunAsync: new Set(),
|
||||
/** @type {Set<function>} */
|
||||
onInterpreterReady: new Set(),
|
||||
|
||||
/** @type {Set<string>} */
|
||||
codeBeforeRunWorker: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeBeforeRunWorkerAsync: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeAfterRunWorker: new Set(),
|
||||
/** @type {Set<string>} */
|
||||
codeAfterRunWorkerAsync: new Set(),
|
||||
};
|
||||
Reference in New Issue
Block a user