A general pattern I’ve developed after tinkering quite a bit with getting JavaScript browsers to act as clients for SWI-Prolog servers is to use JSON calls and responses.
The basic idea is the browser sends JSON which looks something like this
{"cmd": "some command name", "arg1": "whatever arg 1 is", ....}
The prolog server code looks like this:
:- use_module([ library(http/http_unix_daemon)
, library(http/http_server)
]).
:- http_handler(/, cmd_handler, []).
cmd_handler(Request) :-
http_read_json_dict(Request, DictIn),
cmd_manager(DictIn.cmd, DictIn, DictOut),
reply_json_dict(DictOut).
cmd_manager("some command name", DictIn, DictOut}) :-
% manipulate DictIn.arg1 etc to produce DictOut
....
This is accessed from the browser by JavaScript along these lines;
function foo(event) {
fetch('/cmd', { method: 'POST'
, headers: {"Content-Type": "application/json"}
, body: JSON.stringify({ "cmd": "some command name"
, "arg1": "whatever arg1 is"
...
})
})
.then(response => response.json())
.then(data => ... manipulate the return JSON values ....);
}
A newby mistake I originally made was to use SWI Prolog as the root http server serving entire HTML documents, when all I really wanted were little JSON dictionary messages going back and forth.
A practical example of the above is a browser based editor I recently mentioned in a different discussion at at Is there a Prolog mode for CodeMirror?
The above basic framework is very easy to extend. The text editor I started on a few days ago already has a shell commandline, file navigator…