Skip to content

Commit 705a8f7

Browse files
committed
A signals example/proposal
1 parent 59c140e commit 705a8f7

File tree

8 files changed

+4499
-12
lines changed

8 files changed

+4499
-12
lines changed

docs/index.js

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

docs/index.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/pyodide/index.html

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width,initial-scale=1.0">
6+
<script>
7+
globalThis.fn = () => ({ test() { return 1 } }).test.bind(null);
8+
</script>
69
<script type="module" src="../../dist/index.js"></script>
710
<script type="pyodide" async worker>
8-
from polyscript import xworker
9-
print(xworker.window.Function('return 1')())
11+
from polyscript import xworker
12+
print(xworker.window.fn()())
1013
</script>
1114
</head>
1215
</html>

test/raw/pyodide/index.html

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width,initial-scale=1.0">
66
<script type="module">
7-
import { serialize } from 'https://esm.run/@ungap/serialization-registry';
8-
import '../converter.js';
9-
10-
globalThis.test = arg => {
11-
console.log(...serialize(arg));
12-
};
13-
7+
globalThis.test = () => new Proxy(() => 1, {
8+
apply(target, thisArg, argumentsList) {
9+
for (const k in thisArg);
10+
return target(...argumentsList);
11+
}
12+
});
1413
const base = 'https://cdn.jsdelivr.net/npm/pyodide@latest';
1514
const { loadPyodide } = await import(`${base}/pyodide.mjs`);
1615
const interpreter = await loadPyodide();
@@ -19,7 +18,7 @@
1918
</script>
2019
<script type="pyodide" async>
2120
import js
22-
js.test([{'a': 123}, {'a': 456}])
21+
js.test()()
2322
</script>
2423
</head>
2524
</html>

test/signals/config.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[files]
2+
"./signals.py" = ""

test/signals/index.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
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+
<style>body { font-family: monospace; }</style>
7+
<script type="module">
8+
// PyScript (actually just Polyscript)
9+
import "../../dist/index.js";
10+
11+
// the smallest signals library I could think of
12+
import * as signals from "https://esm.run/dom-cue";
13+
globalThis.signals = signals;
14+
</script>
15+
</head>
16+
<body>
17+
<button id="increment">+</button>
18+
<span id="value">0</span>
19+
<button id="decrement">-</button>
20+
<script type="micropython" config="./config.toml" src="./main.py"></script>
21+
</body>
22+
</html>

test/signals/main.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from js import document
2+
from signals import signal, effect
3+
4+
increment, value, decrement, = document.querySelectorAll("#increment, #value, #decrement")
5+
6+
# a signal that holds the value 0 at the beginning
7+
counter = signal(0)
8+
extra = signal(1)
9+
10+
# an effect that automatically updates on `counter` changes
11+
@effect
12+
def track_counter():
13+
value.textContent = f"{counter.value} + {extra.value}"
14+
15+
# a function that adds the given value to the `counter`
16+
def add(i):
17+
counter.value += i
18+
extra.value += i
19+
20+
# two listeners, not much DOM API involved in here
21+
# just the explicit intent of the operation, everything else follows ✨
22+
increment.onclick = lambda _: add(1)
23+
decrement.onclick = lambda _: add(-1)
24+
25+
# demo: how to stop an effect?
26+
# import js; js.track_counter = track_counter

test/signals/signals.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import js
2+
signal = js.signals.signal
3+
js_effect = js.signals.effect
4+
5+
def effect(fn):
6+
return js_effect(fn)
7+
8+
__all__ = ["signal", "effect"]

0 commit comments

Comments
 (0)