When you visit Tilde Friends in a web browser, you are presented with a terminal interface, typically with a big text output box covering most of the page and an input box at the bottom, into which text or commands can be entered. A script runs to produce text output and consume user input.
The script is a Tilde Friends application, and it runs on the server, which means that unlike client-side JavaScript, it can have the ability to read and write files on the server or create network connections to other machines. Unlike node.js or other server-side runtime environments, applications are limited for security reasons to not interfere with each other or bring the entire server down.
Above the terminal, an "Edit" link brings a visitor to the source code for the current Tilde Friends application, which they can then edit, save as their own, and run.
Tilde Friends is a C++ application with a JavaScript runtime that provides restricted access to filesystem, network, and other system resources. The core process runs a core set of scripts that implement a web server, typically starting a new process for each visitor's session which runs scripts for the active application and stopping it when the visitor leaves.
In the same way that web browsers expose APIs for scripts running in the browser to modify the document, play sounds and video, and draw, Tilde Friends exposes APIs for scripts running on a Tilde Friends server to interact with a visitor's web browser, read and write files on the server, and otherwise interact with the world.
First, there are low-level functions exposed from C++ to JavaScript. Most of these are only available to the core process. These typically only go through a basic JavaScript to C++ transition and are relatively fast and immediate.
```js
// Displays some text to the server's console.
print('Hello, world!');
```
There is a mechanism for communicating between processes. Functions can be exported and called across process boundaries. When this is done, any arguments are serialized to a network protocol, deserialized by the other process, the function called, and finally any return value is passed back in the same way. Any functions referenced by the arguments or return value are also exported and can be subsequently called across process boundaries. Functions called across process boundaries are always asynchronous, returning a Promise. Care must be taken for security reasons to not pass dangerous functions ("deleteAllMydata()") to untrusted processes, and it is best for performance reasons to minimize the data size transferred between processes.
```js
// Send an "add" function to any other running processes. When called, it
// will run in this process.
core.broadcast({
add: function (x, y) {
return x + y;
},
});
// Receive the above message and call the function.
core.register('onMessage', function (sender, message) {
All interaction with a human user is through a terminal-like interface. Though it is somewhat limiting, it makes simple things easy, and it is possible to construct complicated interfaces by creating and interacting with an iframe.
Tilde Friends uses lmdb as a basic key value store. Keys and values are all expected to be of type String. Each application gets its own isolated database.