aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 18:04:58 +0100
committereunhhu <[email protected]>2026-09-29 18:04:58 +0100
commitac975237e07f61d5969586ea0fc4f0b1f918a778 (patch)
tree7a4ad70958c681e00ca5c6eca1eb7d4ad05ee2c5
parent8fe9ce66573be53ff56fe2a8afc693dabeae9585 (diff)
downloadpure-ac975237e07f61d5969586ea0fc4f0b1f918a778.tar.gz
pure-ac975237e07f61d5969586ea0fc4f0b1f918a778.zip
Serve documents when a module keeps a collection, not by its inputs' names
pure-serve took a module with an input named show or edit for a document app and refused it unless both were keyed messages: an app with a plain message named edit compiled and then would not start (review 004, an earlier P2). Documents are what a module keeps in a keyed collection; now the host serves them when the module declares one, and inputs named show and edit are otherwise messages as any other. check.py's server_plain_edit starts such an app and posts to edit.
-rw-r--r--serve/serve.c6
-rw-r--r--tests/check.py31
2 files changed, 35 insertions, 2 deletions
diff --git a/serve/serve.c b/serve/serve.c
index 96e1b1d..e8b3ec3 100644
--- a/serve/serve.c
+++ b/serve/serve.c
@@ -2131,9 +2131,11 @@ static bool load_module(PureModule *m, const char *path, bool *documents, uint32
fprintf(stderr, "Module: %s\n", error);
return false;
}
- /* Documents are served when the module has show and edit, as keyed messages. */
+ /* Documents are served when the module keeps a keyed collection: its keyed
+ * messages show and edit read and write one by key. Without one, inputs
+ * named show and edit are messages as any other. */
int show = pure_module_input(m, "show"), edit = pure_module_input(m, "edit");
- *documents = show >= 0 || edit >= 0;
+ *documents = m->collections > 0;
if (*documents && (show < 0 || edit < 0 || m->input[show].kind != PURE_KIND_MESSAGE || !m->input[show].keyed ||
m->input[edit].kind != PURE_KIND_MESSAGE || !m->input[edit].keyed)) {
fputs("Module: documents need keyed messages named show and edit\n", stderr);
diff --git a/tests/check.py b/tests/check.py
index de4f066..645b7ae 100644
--- a/tests/check.py
+++ b/tests/check.py
@@ -2329,6 +2329,36 @@ view stamped_view = stamped
"""
+PLAIN_EDIT_SOURCE = """state n = 0
+input edit = message { value: number }
+on edit { n = edit.value }
+view result = n
+"""
+
+
+def server_plain_edit(aup, pure, work):
+ """An input named edit that is a plain message (the module keeps no
+ document collection) is served as any other input: the app starts, and a
+ POST to it changes its state (review 004, an earlier P2)."""
+ from http.client import HTTPConnection
+ module, source = work / 'plain-edit.pmod', work / 'plain-edit.aup'
+ source.write_text(PLAIN_EDIT_SOURCE)
+ compile_module(aup, source, module)
+ host = HttpHost([pure / 'build/pure-serve', '--module', module, '--store', work / 'plain-edit'])
+ try:
+ connection = HTTPConnection('127.0.0.1', host.port, timeout=10)
+ body = json.dumps({'value': 5}).encode()
+ connection.request('POST', '/inputs/edit', body, {'Content-Length': str(len(body)), 'Content-Type': 'application/json'})
+ status = connection.getresponse().status
+ connection.close()
+ assert status == 200, status
+ result = http(host.port, 'GET', '/views/result')
+ assert result[0] == 200 and float(result[3]) == 5, result
+ finally:
+ host.stop()
+ return 5
+
+
HEARTBEAT_SOURCE = """input beat = every 20 ms
output pulse = message { value: number }
on beat { send pulse { value: 1 } }
@@ -2569,6 +2599,7 @@ def main():
server_app(aup, pure, work, range(args.seeds), threads=3)
report['server_json_requests'] = server_json(aup, pure, work)
report['server_timer_beats'] = server_timers(aup, pure, work)
+ report['server_plain_edit'] = server_plain_edit(aup, pure, work)
report['server_links'] = server_links(aup, pure, work)
report['server_links_udp'] = server_links_udp(aup, pure, work)
report['server_links_udp_lossy'] = server_links_udp_lossy(aup, pure, work)