spaday 0.2.0__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {spaday-0.2.0 → spaday-0.2.2}/Cargo.lock +9 -9
- {spaday-0.2.0 → spaday-0.2.2}/Cargo.toml +1 -1
- {spaday-0.2.0 → spaday-0.2.2}/PKG-INFO +1 -2
- {spaday-0.2.0 → spaday-0.2.2}/js/Cargo.toml +1 -1
- {spaday-0.2.0 → spaday-0.2.2}/js/build.mjs +8 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/package.json +1 -1
- {spaday-0.2.0 → spaday-0.2.2}/js/src/rust/lib.rs +14 -3
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/actions.ts +2 -2
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/signals.ts +4 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/actions.spec.js +37 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/signals.spec.js +32 -0
- {spaday-0.2.0 → spaday-0.2.2}/pyproject.toml +3 -4
- {spaday-0.2.0 → spaday-0.2.2}/rust/Cargo.toml +1 -1
- spaday-0.2.2/rust/coverage +1347 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/action.rs +54 -3
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/lib.rs +1 -1
- {spaday-0.2.0 → spaday-0.2.2}/spaday/__init__.py +3 -1
- {spaday-0.2.0 → spaday-0.2.2}/spaday/actions.py +25 -6
- {spaday-0.2.0 → spaday-0.2.2}/spaday/backends/aiohttp.py +16 -3
- {spaday-0.2.0 → spaday-0.2.2}/spaday/backends/flask.py +16 -3
- {spaday-0.2.0 → spaday-0.2.2}/spaday/backends/starlette.py +5 -2
- {spaday-0.2.0 → spaday-0.2.2}/spaday/backends/tornado.py +16 -3
- {spaday-0.2.0 → spaday-0.2.2}/spaday/bootstrap.py +59 -22
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/shell.py +24 -7
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/index.js +23 -13
- spaday-0.2.2/spaday/extension/cdn/index.js.map +7 -0
- spaday-0.2.2/spaday/extension/cdn/widget.js +1017 -0
- spaday-0.2.2/spaday/extension/cdn/widget.js.map +7 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/widget.webawesome.js +24 -14
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/widget.webawesome.js.map +2 -2
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/pkg/spaday.js +20 -12
- spaday-0.2.2/spaday/extension/pkg/spaday_bg.wasm +0 -0
- spaday-0.2.2/spaday/extension/transports/cdn/index.js +608 -0
- spaday-0.2.2/spaday/extension/transports/cdn/index.js.map +7 -0
- spaday-0.2.2/spaday/extension/transports/pkg/transports.d.ts +115 -0
- spaday-0.2.2/spaday/extension/transports/pkg/transports.js +501 -0
- spaday-0.2.2/spaday/extension/transports/pkg/transports_bg.wasm +0 -0
- spaday-0.2.2/spaday/extension/transports/pkg/transports_bg.wasm.d.ts +23 -0
- spaday-0.2.2/spaday/spaday.abi3.so +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_actions.py +14 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_backend_starlette.py +10 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_bootstrap.py +22 -4
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_shell.py +41 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_validate.py +8 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/validate.py +9 -3
- spaday-0.2.0/rust/coverage +0 -1311
- spaday-0.2.0/spaday/extension/cdn/index.js.map +0 -7
- spaday-0.2.0/spaday/extension/cdn/widget.js +0 -1007
- spaday-0.2.0/spaday/extension/cdn/widget.js.map +0 -7
- spaday-0.2.0/spaday/extension/pkg/spaday_bg.wasm +0 -0
- spaday-0.2.0/spaday/spaday.abi3.so +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/.gitignore +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/LICENSE +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/README.md +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/playwright.config.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/pnpm-lock.yaml +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/pnpm-workspace.yaml +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/css/index.css +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/html/index.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/cem.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/css.d.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/examples/gateway.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/handlers.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/index.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/runtime.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/shell.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/store-sync.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/value.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/wasm-ready.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/wasm.d.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/webawesome.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/widget.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/wrappers/lightweight-chart.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/src/ts/wrappers/perspective-workspace.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/cem.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/hydrate.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/index.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/layout.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/layout.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/lightweight-chart.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/lightweight-chart.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/runtime.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/runtime.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/shell.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/show.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/store-sync.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/widget-webawesome.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/widget-webawesome.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/widget.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tests/widget.spec.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tools/bundle.mjs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tools/css.mjs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tools/externals.mjs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tools/getarg.mjs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tools/html.mjs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/js/tsconfig.json +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/.config/nextest.toml +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/Cargo.lock +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/python/example/mod.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/python/lib.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/python/patch/mod.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/cem.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/diff.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/example.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/json.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/node.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/value.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/rust/src/wire.rs +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/backends/__init__.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/cem.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/component.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/__init__.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/form.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/lightweight_charts.cem.json +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/lightweight_charts.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/perspective.cem.json +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/perspective.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/components/webawesome.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/README.md +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/__init__.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/__main__.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/cluster.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/devices.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/embed.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/form.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/fragment.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/gateway.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/reactive.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/ssr.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/examples/widget.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/examples/gateway.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/examples/gateway.js.map +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/examples/webawesome.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/examples/webawesome.js.map +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/wrappers/lightweight-chart.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/wrappers/lightweight-chart.js.map +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/wrappers/perspective-workspace.js +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/cdn/wrappers/perspective-workspace.js.map +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/css/index.css +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/css/webawesome.css +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/index.html +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/pkg/spaday.d.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/extension/pkg/spaday_bg.wasm.d.ts +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/render.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/fixtures/webawesome.3.9.0.cem.json +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/fixtures/webawesome.cem.json +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_all.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_backend_aiohttp.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_backend_flask.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_backend_tornado.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_bindings.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_cem.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_cluster.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_examples.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_form.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_gateway.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_imports.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_render.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_theme.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_widget.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_wire.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/tests/test_wrappers.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/theme.py +0 -0
- {spaday-0.2.0 → spaday-0.2.2}/spaday/widget.py +0 -0
|
@@ -84,9 +84,9 @@ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
|
|
84
84
|
|
|
85
85
|
[[package]]
|
|
86
86
|
name = "memchr"
|
|
87
|
-
version = "2.8.
|
|
87
|
+
version = "2.8.3"
|
|
88
88
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
89
|
-
checksum = "
|
|
89
|
+
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
|
|
90
90
|
|
|
91
91
|
[[package]]
|
|
92
92
|
name = "num-traits"
|
|
@@ -184,9 +184,9 @@ dependencies = [
|
|
|
184
184
|
|
|
185
185
|
[[package]]
|
|
186
186
|
name = "quote"
|
|
187
|
-
version = "1.0.
|
|
187
|
+
version = "1.0.46"
|
|
188
188
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
189
|
-
checksum = "
|
|
189
|
+
checksum = "dfbc457d0c7a0759a614551b11a6409e5951f6c7537be1f1b7682b9ae9230368"
|
|
190
190
|
dependencies = [
|
|
191
191
|
"proc-macro2",
|
|
192
192
|
]
|
|
@@ -212,9 +212,9 @@ dependencies = [
|
|
|
212
212
|
|
|
213
213
|
[[package]]
|
|
214
214
|
name = "rustversion"
|
|
215
|
-
version = "1.0.
|
|
215
|
+
version = "1.0.23"
|
|
216
216
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
217
|
-
checksum = "
|
|
217
|
+
checksum = "cf54715a573b99ac80df0bc206da022bcd442c974952c7b9720069370852e21f"
|
|
218
218
|
|
|
219
219
|
[[package]]
|
|
220
220
|
name = "serde"
|
|
@@ -278,7 +278,7 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5"
|
|
|
278
278
|
|
|
279
279
|
[[package]]
|
|
280
280
|
name = "spaday"
|
|
281
|
-
version = "0.2.
|
|
281
|
+
version = "0.2.2"
|
|
282
282
|
dependencies = [
|
|
283
283
|
"serde",
|
|
284
284
|
"serde_json",
|
|
@@ -287,7 +287,7 @@ dependencies = [
|
|
|
287
287
|
|
|
288
288
|
[[package]]
|
|
289
289
|
name = "spaday_js"
|
|
290
|
-
version = "0.2.
|
|
290
|
+
version = "0.2.2"
|
|
291
291
|
dependencies = [
|
|
292
292
|
"js-sys",
|
|
293
293
|
"serde",
|
|
@@ -298,7 +298,7 @@ dependencies = [
|
|
|
298
298
|
|
|
299
299
|
[[package]]
|
|
300
300
|
name = "spaday_py"
|
|
301
|
-
version = "0.2.
|
|
301
|
+
version = "0.2.2"
|
|
302
302
|
dependencies = [
|
|
303
303
|
"pyo3",
|
|
304
304
|
"spaday",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spaday
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: Build reactive web-component UIs configured in Python, executed in the browser
|
|
5
5
|
Project-URL: Repository, https://github.com/1kbgz/spaday
|
|
6
6
|
Project-URL: Homepage, https://github.com/1kbgz/spaday
|
|
@@ -10,7 +10,6 @@ License-File: LICENSE
|
|
|
10
10
|
Classifier: Development Status :: 3 - Alpha
|
|
11
11
|
Classifier: Programming Language :: Python
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
13
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
16
15
|
Classifier: Programming Language :: Python :: 3.13
|
|
@@ -108,6 +108,14 @@ async function build() {
|
|
|
108
108
|
!file.relativePath.startsWith("esm/") &&
|
|
109
109
|
!file.relativePath.startsWith("dist/esm/"),
|
|
110
110
|
});
|
|
111
|
+
await cpy(
|
|
112
|
+
"node_modules/@1kbgz/transports/dist/cdn/index.js*",
|
|
113
|
+
"../spaday/extension/transports/cdn",
|
|
114
|
+
);
|
|
115
|
+
await cpy(
|
|
116
|
+
"node_modules/@1kbgz/transports/dist/pkg/*",
|
|
117
|
+
"../spaday/extension/transports/pkg",
|
|
118
|
+
);
|
|
111
119
|
}
|
|
112
120
|
|
|
113
121
|
build();
|
|
@@ -25,7 +25,7 @@ extern "C" {
|
|
|
25
25
|
#[wasm_bindgen(method, js_name = sendPatch)]
|
|
26
26
|
fn send_patch(this: &Host, model: &str, field: &str, value: JsValue);
|
|
27
27
|
#[wasm_bindgen(method, js_name = callEndpoint)]
|
|
28
|
-
fn call_endpoint(this: &Host, method: &str, url:
|
|
28
|
+
fn call_endpoint(this: &Host, method: &str, url: JsValue, body: JsValue, result: Option<&str>);
|
|
29
29
|
#[wasm_bindgen(method, js_name = callNamed)]
|
|
30
30
|
fn call_named(this: &Host, handler: &str);
|
|
31
31
|
}
|
|
@@ -100,15 +100,19 @@ fn run(action: &spaday::Action, host: &Host) {
|
|
|
100
100
|
body,
|
|
101
101
|
result,
|
|
102
102
|
} => {
|
|
103
|
+
let u = match url {
|
|
104
|
+
spaday::EndpointUrl::Static(value) => JsValue::from_str(value),
|
|
105
|
+
spaday::EndpointUrl::Expr(expr) => eval(expr, host),
|
|
106
|
+
};
|
|
103
107
|
let b = body.as_ref().map_or(JsValue::UNDEFINED, |e| eval(e, host));
|
|
104
|
-
host.call_endpoint(method,
|
|
108
|
+
host.call_endpoint(method, u, b, result.as_deref());
|
|
105
109
|
}
|
|
106
110
|
NamedJs { handler } => host.call_named(handler),
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
113
|
|
|
110
114
|
fn eval(expr: &spaday::Expr, host: &Host) -> JsValue {
|
|
111
|
-
use spaday::Expr::{Event, Field, Lit, Not, Obj, Prop};
|
|
115
|
+
use spaday::Expr::{Concat, Event, Field, Lit, Not, Obj, Prop};
|
|
112
116
|
match expr {
|
|
113
117
|
// json_compatible: JSON objects become plain JS objects (not Maps), so they round-trip through
|
|
114
118
|
// `JSON.stringify` (e.g. a CallEndpoint body) and set cleanly as props.
|
|
@@ -130,6 +134,13 @@ fn eval(expr: &spaday::Expr, host: &Host) -> JsValue {
|
|
|
130
134
|
}
|
|
131
135
|
obj.into()
|
|
132
136
|
}
|
|
137
|
+
Concat { parts } => {
|
|
138
|
+
let values = js_sys::Array::new();
|
|
139
|
+
for part in parts {
|
|
140
|
+
values.push(&eval(part, host));
|
|
141
|
+
}
|
|
142
|
+
values.join("").into()
|
|
143
|
+
}
|
|
133
144
|
}
|
|
134
145
|
}
|
|
135
146
|
|
|
@@ -68,11 +68,11 @@ function host(ctx: ActionContext) {
|
|
|
68
68
|
// UI, e.g. show a 422 validation error); without one it stays fire-and-forget.
|
|
69
69
|
callEndpoint: (
|
|
70
70
|
method: string,
|
|
71
|
-
url:
|
|
71
|
+
url: unknown,
|
|
72
72
|
body: unknown,
|
|
73
73
|
result?: string,
|
|
74
74
|
) => {
|
|
75
|
-
const request = fetch(url, {
|
|
75
|
+
const request = fetch(String(url), {
|
|
76
76
|
method,
|
|
77
77
|
headers:
|
|
78
78
|
body === undefined
|
|
@@ -126,6 +126,10 @@ export function evalExpr(expr: unknown, store: Store): unknown {
|
|
|
126
126
|
out[k] = evalExpr(v, store);
|
|
127
127
|
return out;
|
|
128
128
|
}
|
|
129
|
+
case "concat":
|
|
130
|
+
return (e.parts as unknown[])
|
|
131
|
+
.map((part) => String(evalExpr(part, store)))
|
|
132
|
+
.join("");
|
|
129
133
|
default:
|
|
130
134
|
return undefined;
|
|
131
135
|
}
|
|
@@ -357,6 +357,43 @@ test("CallEndpoint composes a body from the signal store via field exprs", async
|
|
|
357
357
|
expect(JSON.parse(seen[0])).toEqual({ symbol: "AAPL", qty: 250 });
|
|
358
358
|
});
|
|
359
359
|
|
|
360
|
+
test("CallEndpoint composes its URL from signal-store fields", async ({
|
|
361
|
+
page,
|
|
362
|
+
}) => {
|
|
363
|
+
const seen = [];
|
|
364
|
+
await page.route("**/send/basket/*", (route) => {
|
|
365
|
+
seen.push(new URL(route.request().url()).pathname);
|
|
366
|
+
return route.fulfill({ status: 200, body: "ok" });
|
|
367
|
+
});
|
|
368
|
+
await page.evaluate(() => {
|
|
369
|
+
const { mount, Store } = window.__spaday;
|
|
370
|
+
const store = new Store({ key: "B" });
|
|
371
|
+
const btn = mount(
|
|
372
|
+
document.body,
|
|
373
|
+
{
|
|
374
|
+
tag: "button",
|
|
375
|
+
events: {
|
|
376
|
+
click: {
|
|
377
|
+
kind: "call",
|
|
378
|
+
method: "POST",
|
|
379
|
+
url: {
|
|
380
|
+
expr: "concat",
|
|
381
|
+
parts: [
|
|
382
|
+
{ expr: "lit", value: "/send/basket/" },
|
|
383
|
+
{ expr: "field", name: "key" },
|
|
384
|
+
],
|
|
385
|
+
},
|
|
386
|
+
},
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
store,
|
|
390
|
+
);
|
|
391
|
+
btn.click();
|
|
392
|
+
});
|
|
393
|
+
await page.waitForTimeout(150);
|
|
394
|
+
expect(seen).toEqual(["/send/basket/B"]);
|
|
395
|
+
});
|
|
396
|
+
|
|
360
397
|
test("SetField writes a store field (a plain button drives reactive state)", async ({
|
|
361
398
|
page,
|
|
362
399
|
}) => {
|
|
@@ -234,6 +234,38 @@ test("a cond expr selects between two values by a field, reactively", async ({
|
|
|
234
234
|
expect(result.after).toBe("dark");
|
|
235
235
|
});
|
|
236
236
|
|
|
237
|
+
test("a concat expr composes strings from fields reactively", async ({
|
|
238
|
+
page,
|
|
239
|
+
}) => {
|
|
240
|
+
const result = await page.evaluate(() => {
|
|
241
|
+
const { mount, Store } = window.__spaday;
|
|
242
|
+
const store = new Store({ key: "A" });
|
|
243
|
+
const root = mount(
|
|
244
|
+
document.createElement("div"),
|
|
245
|
+
{
|
|
246
|
+
tag: "span",
|
|
247
|
+
bindings: {
|
|
248
|
+
textContent: {
|
|
249
|
+
compute: {
|
|
250
|
+
expr: "concat",
|
|
251
|
+
parts: [
|
|
252
|
+
{ expr: "lit", value: "Basket " },
|
|
253
|
+
{ expr: "field", name: "key" },
|
|
254
|
+
],
|
|
255
|
+
},
|
|
256
|
+
mode: "one-way",
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
store,
|
|
261
|
+
);
|
|
262
|
+
const initial = root.textContent;
|
|
263
|
+
store.set("key", "B");
|
|
264
|
+
return { initial, after: root.textContent };
|
|
265
|
+
});
|
|
266
|
+
expect(result).toEqual({ initial: "Basket A", after: "Basket B" });
|
|
267
|
+
});
|
|
268
|
+
|
|
237
269
|
test("a root-class binding toggles a class on <html> from a field", async ({
|
|
238
270
|
page,
|
|
239
271
|
}) => {
|
|
@@ -14,7 +14,7 @@ authors = [
|
|
|
14
14
|
description = "Build reactive web-component UIs configured in Python, executed in the browser"
|
|
15
15
|
readme = "README.md"
|
|
16
16
|
license = { text = "Apache-2.0" }
|
|
17
|
-
version = "0.2.
|
|
17
|
+
version = "0.2.2"
|
|
18
18
|
requires-python = ">=3.10"
|
|
19
19
|
keywords = []
|
|
20
20
|
|
|
@@ -25,7 +25,6 @@ classifiers = [
|
|
|
25
25
|
"Programming Language :: Python :: Implementation :: CPython",
|
|
26
26
|
"Programming Language :: Python :: Implementation :: PyPy",
|
|
27
27
|
"Programming Language :: Python :: 3",
|
|
28
|
-
"Programming Language :: Python :: 3.10",
|
|
29
28
|
"Programming Language :: Python :: 3.11",
|
|
30
29
|
"Programming Language :: Python :: 3.12",
|
|
31
30
|
"Programming Language :: Python :: 3.13",
|
|
@@ -79,7 +78,7 @@ Repository = "https://github.com/1kbgz/spaday"
|
|
|
79
78
|
Homepage = "https://github.com/1kbgz/spaday"
|
|
80
79
|
|
|
81
80
|
[tool.bumpversion]
|
|
82
|
-
current_version = "0.2.
|
|
81
|
+
current_version = "0.2.2"
|
|
83
82
|
commit = true
|
|
84
83
|
tag = false
|
|
85
84
|
commit_args = "-s"
|
|
@@ -115,7 +114,7 @@ search = 'version = "{current_version}"'
|
|
|
115
114
|
replace = 'version = "{new_version}"'
|
|
116
115
|
|
|
117
116
|
[tool.cibuildwheel]
|
|
118
|
-
build = "
|
|
117
|
+
build = "cp311-*"
|
|
119
118
|
test-command = "pytest -vvv {project}/spaday/tests"
|
|
120
119
|
test-extras = "develop"
|
|
121
120
|
|