8000 Improved py:all-done event (#1778) · pyscript/pyscript@50f7ab0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 50f7ab0

Browse files
Improved py:all-done event (#1778)
1 parent fdc35ce commit 50f7ab0

File tree

5 files changed

+62
-65
lines changed

5 files changed

+62
-65
lines changed

pyscript.core/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyscript.core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
"dependencies": {
3434
"@ungap/with-resolvers": "^0.1.0",
3535
"basic-devtools": "^0.1.6",
36-
"polyscript": "^0.4.8",
36+
"polyscript": "^0.4.11",
3737
"type-checked-collections": "^0.1.7"
3838
},
3939
"devDependencies": {

pyscript.core/src/all-done.js

Lines changed: 8 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,17 @@
11
import TYPES from "./types.js";
2-
import hooks from "./hooks.js";
3-
4-
const DONE = "py:all-done";
5-
6-
const {
7-
onAfterRun,
8-
onAfterRunAsync,
9-
codeAfterRunWorker,
10-
codeAfterRunWorkerAsync,
11-
} = hooks;
122

133
const waitForIt = [];
14-
const codes = [];
15-
16-
const codeFor = (element) => {
17-
const isAsync = element.hasAttribute("async");
18-
const { promise, resolve } = Promise.withResolvers();
19-
const type = `${DONE}:${waitForIt.push(promise)}`;
204

21-
// resolve each promise once notified
22-
addEventListener(type, resolve, { once: true });
23-
24-
if (element.hasAttribute("worker")) {
25-
const code = `
26-
from pyscript import window as _w
27-
_w.dispatchEvent(_w.Event.new("${type}"))
28-
`;
29-
if (isAsync) codeAfterRunWorkerAsync.add(code);
30-
else codeAfterRunWorker.add(code);
31-
return code;
5+
for (const [TYPE] of TYPES) {
6+
const selectors = [`script[type="${TYPE}"]`, `${TYPE}-script`];
7+
for (const element of document.querySelectorAll(selectors.join(","))) {
8+
const { promise, resolve } = Promise.withResolvers();
9+
waitForIt.push(promise);
10+
element.addEventListener(`${TYPE}:done`, resolve, { once: true });
3211
}
33-
34-
// dispatch only once the ready element is the same
35-
const code = (_, el) => {
36-
if (el === element) dispatchEvent(new Event(type));
37-
};
38-
39-
if (isAsync) onAfterRunAsync.add(code);
40-
else onAfterRun.add(code);
41-
return code;
42-
};
43-
44-
const selector = [];
45-
for (const [TYPE] of TYPES)
46-
selector.push(`script[type="${TYPE}"]`, `${TYPE}-script`);
47-
48-
// loop over all known scripts and elements
49-
for (const element of document.querySelectorAll(selector.join(",")))
50-
codes.push(codeFor(element));
12+
}
5113

5214
// wait for all the things then cleanup
5315
Promise.all(waitForIt).then(() => {
54-
// cleanup unnecessary hooks
55-
for (const code of codes) {
56-
onAfterRun.delete(code);
57-
onAfterRunAsync.delete(code);
58-
codeAfterRunWorker.delete(code);
59-
codeAfterRunWorkerAsync.delete(code);
60-
}
61-
dispatchEvent(new Event(DONE));
16+
dispatchEvent(new Event("py:all-done"));
6217
});

pyscript.core/src/core.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ const exportedConfig = {};
9090
export { exportedConfig as config, hooks };
9191

9292
for (const [TYPE, interpreter] of TYPES) {
93+
const dispatchDone = (element, isAsync, result) => {
94+
if (isAsync) result.then(() => dispatch(element, TYPE, "done"));
95+
else dispatch(element, TYPE, "done");
96+
};
97+
9398
const { config, plugins, error } = configs.get(TYPE);
9499

95100
// create a unique identifier when/if needed
@@ -211,9 +216,13 @@ for (const [TYPE, interpreter] of TYPES) {
211216
defineProperty(element, "target", { value: show });
212217

213218
// notify before the code runs
214-
dispatch(element, TYPE);
215-
wrap[`run${isAsync ? "Async" : ""}`](
216-
await fetchSource(element, wrap.io, true),
219+
dispatch(element, TYPE, "ready");
220+
dispatchDone(
221+
element,
222+
isAsync,
223+
wrap[`run${isAsync ? "Async" : ""}`](
224+
await fetchSource(element, wrap.io, true),
225+
),
217226
);
218227
} else {
219228
// resolve PyScriptElement to allow connectedCallback
@@ -246,18 +255,21 @@ for (const [TYPE, interpreter] of TYPES) {
246255
async connectedCallback() {
247256
if (!this.executed) {
248257
this.executed = true;
258+
const isAsync = this.hasAttribute("async");
249259
const { io, run, runAsync } = await this._wrap.promise;
250-
const runner = this.hasAttribute("async") ? runAsync : run;
251260
this.srcCode = await fetchSource(
252261
this,
253262
io,
254263
!this.childElementCount,
255264
);
256265
this.replaceChildren();
257-
// notify before the code runs
258-
dispatch(this, TYPE);
259-
runner(this.srcCode);
260266
this.style.display = "block";
267+
dispatch(this, TYPE, "ready");
268+
dispatchDone(
269+
this,
270+
isAsync,
271+
(isAsync ? runAsync : run)(this.srcCode),
272+
);
261273
}
262274
}
263275
}

pyscript.core/test/display.html

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
6+
<title>PyScript Next</title>
7+
<script>
8+
addEventListener("py:all-done", ({ type }) => console.log(type));
9+
</script>
10+
<link rel="stylesheet" href="../dist/core.css">
11+
<script type="module" src="../dist/core.js"></script>
12+
</head>
13+
<body>
14+
<script type="py" worker async>
15+
from pyscript import display
16+
display('hello 1')
17+
18+
import js
19+
import time
20+
js.console.log('sleeping...')
21+
time.sleep(2)
22+
js.console.log('...done')
23+
</script>
24+
<p>hello 2</p>
25+
<script type="py" worker async>
26+
from pyscript import display
27+
display('hello 3')
28+
</script>
29+
</body>
30+
</html>

0 commit comments

Comments
 (0)
0