docs: Expose the rest of the core js to doxygen.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m35s
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m35s
This commit is contained in:
4
Doxyfile
4
Doxyfile
@@ -945,13 +945,13 @@ WARN_LOGFILE =
|
||||
|
||||
INPUT = README.md \
|
||||
core/app.js \
|
||||
core/client.js \
|
||||
core/core.js \
|
||||
core/http.js \
|
||||
core/tfrpc.js \
|
||||
docs/ \
|
||||
src/
|
||||
|
||||
# Not yet: core/tfrpc.js core/client.js
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
|
||||
|
285
core/client.js
285
core/client.js
@@ -1,3 +1,11 @@
|
||||
/**
|
||||
* \file
|
||||
* \defgroup tfclient Tilde Friends Client JS
|
||||
* Tilde Friends client-side browser JavaScript.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \cond */
|
||||
import {LitElement, html, css, svg} from '/lit/lit-all.min.js';
|
||||
|
||||
let cm6;
|
||||
@@ -13,8 +21,9 @@ let gUnloading;
|
||||
let kErrorColor = '#dc322f';
|
||||
let kDisconnectColor = '#f00';
|
||||
let kStatusColor = '#fff';
|
||||
/** \endcond */
|
||||
|
||||
// Functions that server-side app code can call through the app object.
|
||||
/** Functions that server-side app code can call through the app object. */
|
||||
const k_api = {
|
||||
setDocument: {args: ['content'], func: api_setDocument},
|
||||
postMessage: {args: ['message'], func: api_postMessage},
|
||||
@@ -26,29 +35,14 @@ const k_api = {
|
||||
setHash: {args: ['hash'], func: api_setHash},
|
||||
};
|
||||
|
||||
// TODO(tasiaiso): this is only used once, move it down ?
|
||||
const k_global_style = css`
|
||||
a:link {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #6c71c4;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #2aa198;
|
||||
}
|
||||
`;
|
||||
|
||||
/**
|
||||
* Class that represents the top bar
|
||||
*/
|
||||
class TfNavigationElement extends LitElement {
|
||||
/**
|
||||
* Get Lit Html properties.
|
||||
* @return The properties.
|
||||
*/
|
||||
static get properties() {
|
||||
return {
|
||||
credentials: {type: Object},
|
||||
@@ -64,6 +58,9 @@ class TfNavigationElement extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TfNavigationElement instance.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.permissions = {};
|
||||
@@ -76,7 +73,7 @@ class TfNavigationElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
* @param event The HTML event.
|
||||
*/
|
||||
toggle_edit(event) {
|
||||
event.preventDefault();
|
||||
@@ -89,7 +86,7 @@ class TfNavigationElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param key The permission to reset.
|
||||
*/
|
||||
reset_permission(key) {
|
||||
send({action: 'resetPermission', permission: key});
|
||||
@@ -97,9 +94,9 @@ class TfNavigationElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param {*} options
|
||||
* @returns
|
||||
* @param key The spark line identifier.
|
||||
* @param options Spark line options.
|
||||
* @return A spark line HTML element.
|
||||
*/
|
||||
get_spark_line(key, options) {
|
||||
if (!this.spark_lines[key]) {
|
||||
@@ -118,29 +115,49 @@ class TfNavigationElement extends LitElement {
|
||||
return this.spark_lines[key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the active SSB identity for the current application.
|
||||
* @param id The identity.
|
||||
*/
|
||||
set_active_identity(id) {
|
||||
send({action: 'setActiveIdentity', identity: id});
|
||||
this.renderRoot.getElementById('id_dropdown').classList.remove('w3-show');
|
||||
}
|
||||
|
||||
create_identity(event) {
|
||||
/**
|
||||
* Create a new SSB identity.
|
||||
*/
|
||||
create_identity() {
|
||||
if (confirm('Are you sure you want to create a new identity?')) {
|
||||
send({action: 'createIdentity'});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle visibility of the ID dropdown.
|
||||
*/
|
||||
toggle_id_dropdown() {
|
||||
this.renderRoot.getElementById('id_dropdown').classList.toggle('w3-show');
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit the current identity's SSB profile.
|
||||
*/
|
||||
edit_profile() {
|
||||
window.location.href = '/~core/ssb/#' + this.identity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sign out of the current Tilde Friends user.
|
||||
*/
|
||||
logout() {
|
||||
window.location.href = `/login/logout?return=${encodeURIComponent(url() + hash())}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render the identity dropdown.
|
||||
* @return Lit HTML.
|
||||
*/
|
||||
render_identity() {
|
||||
let self = this;
|
||||
|
||||
@@ -287,6 +304,9 @@ class TfNavigationElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear the current error.
|
||||
*/
|
||||
clear_error() {
|
||||
this.status = {};
|
||||
}
|
||||
@@ -297,6 +317,23 @@ class TfNavigationElement extends LitElement {
|
||||
*/
|
||||
render() {
|
||||
let self = this;
|
||||
const k_global_style = css`
|
||||
a:link {
|
||||
color: #268bd2;
|
||||
}
|
||||
|
||||
a:visited {
|
||||
color: #6c71c4;
|
||||
}
|
||||
|
||||
a:hover {
|
||||
color: #859900;
|
||||
}
|
||||
|
||||
a:active {
|
||||
color: #2aa198;
|
||||
}
|
||||
`;
|
||||
return html`
|
||||
<link type="text/css" rel="stylesheet" href="/static/w3.css" />
|
||||
<style>
|
||||
@@ -407,6 +444,10 @@ customElements.define('tf-navigation', TfNavigationElement);
|
||||
* TODOC
|
||||
*/
|
||||
class TfFilesElement extends LitElement {
|
||||
/**
|
||||
* LitElement properties.
|
||||
* @return The properties.
|
||||
*/
|
||||
static get properties() {
|
||||
return {
|
||||
current: {type: String},
|
||||
@@ -416,6 +457,9 @@ class TfFilesElement extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TfFilesElement instance.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.files = {};
|
||||
@@ -424,7 +468,7 @@ class TfFilesElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} file
|
||||
* @param file The file.
|
||||
*/
|
||||
file_click(file) {
|
||||
this.dispatchEvent(
|
||||
@@ -440,8 +484,8 @@ class TfFilesElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} file
|
||||
* @returns
|
||||
* @param file The file.
|
||||
* @returns Lit HTML.
|
||||
*/
|
||||
render_file(file) {
|
||||
let classes = ['file'];
|
||||
@@ -464,7 +508,7 @@ class TfFilesElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
* @param event The event.
|
||||
*/
|
||||
async drop(event) {
|
||||
event.preventDefault();
|
||||
@@ -490,7 +534,7 @@ class TfFilesElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
* @param event The event.
|
||||
*/
|
||||
drag_enter(event) {
|
||||
this.dropping++;
|
||||
@@ -500,7 +544,7 @@ class TfFilesElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
* @param event The event.
|
||||
*/
|
||||
drag_leave(event) {
|
||||
this.dropping--;
|
||||
@@ -509,6 +553,10 @@ class TfFilesElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Drag over event.
|
||||
* @param event The event.
|
||||
*/
|
||||
drag_over(event) {
|
||||
event.preventDefault();
|
||||
}
|
||||
@@ -565,6 +613,10 @@ customElements.define('tf-files', TfFilesElement);
|
||||
* TODOC
|
||||
*/
|
||||
class TfFilesPaneElement extends LitElement {
|
||||
/**
|
||||
* Get Lit Html properties.
|
||||
* @return The properties.
|
||||
*/
|
||||
static get properties() {
|
||||
return {
|
||||
expanded: {type: Boolean},
|
||||
@@ -573,6 +625,9 @@ class TfFilesPaneElement extends LitElement {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a TfFilesPaneElement instance.
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
this.expanded = window.localStorage.getItem('files') != '0';
|
||||
@@ -581,7 +636,7 @@ class TfFilesPaneElement extends LitElement {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} expanded
|
||||
* @param expanded Whether the files pane is expanded.
|
||||
*/
|
||||
set_expanded(expanded) {
|
||||
this.expanded = expanded;
|
||||
@@ -760,10 +815,9 @@ window.addEventListener('keydown', function (event) {
|
||||
});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} nodes
|
||||
* @param {*} callback
|
||||
* @returns
|
||||
* Make sure a set of dependencies are loaded
|
||||
* @param nodes An array of descriptions of dependencies to load.
|
||||
* @param callback Called when all dependencies are loaded.
|
||||
*/
|
||||
function ensureLoaded(nodes, callback) {
|
||||
if (!nodes.length) {
|
||||
@@ -857,23 +911,10 @@ function trace() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @returns
|
||||
*/
|
||||
function guessMode(name) {
|
||||
return name.endsWith('.js')
|
||||
? 'javascript'
|
||||
: name.endsWith('.html')
|
||||
? 'htmlmixed'
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @param {*} id
|
||||
* @returns
|
||||
* Load a single file.
|
||||
* @param name The name by which the file is known.
|
||||
* @param id The file's ID.
|
||||
* @return A promise resolved with the file's contents.
|
||||
*/
|
||||
function loadFile(name, id) {
|
||||
return fetch('/' + id + '/view')
|
||||
@@ -899,9 +940,9 @@ function loadFile(name, id) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
* @returns
|
||||
* Load files for the app.
|
||||
* @param path The app path to load.
|
||||
* @return A promise resolved when the app is laoded.
|
||||
*/
|
||||
async function load(path) {
|
||||
let response = await fetch((path || url()) + 'view');
|
||||
@@ -958,9 +999,9 @@ function explodePath() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} save_to
|
||||
* @returns
|
||||
* Save the app.
|
||||
* @param save_to An optional path to which to save the app.
|
||||
* @return A promise resoled when the app is saved.
|
||||
*/
|
||||
function save(save_to) {
|
||||
document.getElementById('save').disabled = true;
|
||||
@@ -1129,8 +1170,8 @@ function hash() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} content
|
||||
* Set the iframe document contents.
|
||||
* @param content The contents.
|
||||
*/
|
||||
function api_setDocument(content) {
|
||||
let iframe = document.getElementById('document');
|
||||
@@ -1138,8 +1179,8 @@ function api_setDocument(content) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* Send a message to the sandboxed iframe.
|
||||
* @param message The message.
|
||||
*/
|
||||
function api_postMessage(message) {
|
||||
let iframe = document.getElementById('document');
|
||||
@@ -1148,7 +1189,7 @@ function api_postMessage(message) {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} error
|
||||
* @param error The error.
|
||||
*/
|
||||
function api_error(error) {
|
||||
if (error) {
|
||||
@@ -1162,28 +1203,28 @@ function api_error(error) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @param {*} value
|
||||
et a value in local storage.
|
||||
* @param key The key.
|
||||
* @param value The value.
|
||||
*/
|
||||
function api_localStorageSet(key, value) {
|
||||
window.localStorage.setItem('app:' + key, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} key
|
||||
* @returns
|
||||
* Get a value from local storage.
|
||||
* @param key The key.
|
||||
* @return The value.
|
||||
*/
|
||||
function api_localStorageGet(key) {
|
||||
return window.localStorage.getItem('app:' + key);
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} permission
|
||||
* @param {*} id
|
||||
* @returns
|
||||
* Request a permission
|
||||
* @param permission The permission to request.
|
||||
* @param id The id requeesting the permission.
|
||||
* @return A promise fulfilled if the permission was granted.
|
||||
*/
|
||||
function api_requestPermission(permission, id) {
|
||||
let outer = document.createElement('div');
|
||||
@@ -1259,8 +1300,8 @@ function api_print() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} hash
|
||||
* Set the window's location hash.
|
||||
* @param hash The new hash.
|
||||
*/
|
||||
function api_setHash(hash) {
|
||||
window.location.hash = hash;
|
||||
@@ -1268,7 +1309,7 @@ function api_setHash(hash) {
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* @param message The message.
|
||||
*/
|
||||
function _receive_websocket_message(message) {
|
||||
if (message && message.action == 'session') {
|
||||
@@ -1364,9 +1405,9 @@ function _receive_websocket_message(message) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* @param {*} color
|
||||
* Set the status message.
|
||||
* @param message The message.
|
||||
* @param color The message's color.
|
||||
*/
|
||||
function setStatusMessage(message, color) {
|
||||
document.getElementsByTagName('tf-navigation')[0].status = {
|
||||
@@ -1377,8 +1418,8 @@ function setStatusMessage(message, color) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} value
|
||||
* Send a message to the app.
|
||||
* @param value The message.
|
||||
*/
|
||||
function send(value) {
|
||||
try {
|
||||
@@ -1390,49 +1431,6 @@ function send(value) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} sourceData
|
||||
* @param {*} maxWidth
|
||||
* @param {*} maxHeight
|
||||
* @param {*} callback
|
||||
*/
|
||||
function fixImage(sourceData, maxWidth, maxHeight, callback) {
|
||||
let result = sourceData;
|
||||
let image = new Image();
|
||||
image.crossOrigin = 'anonymous';
|
||||
image.referrerPolicy = 'no-referrer';
|
||||
image.onload = function () {
|
||||
if (image.width > maxWidth || image.height > maxHeight) {
|
||||
let downScale = Math.min(
|
||||
maxWidth / image.width,
|
||||
maxHeight / image.height
|
||||
);
|
||||
let canvas = document.createElement('canvas');
|
||||
canvas.width = image.width * downScale;
|
||||
canvas.height = image.height * downScale;
|
||||
let context = canvas.getContext('2d');
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
image.width = canvas.width;
|
||||
image.height = canvas.height;
|
||||
context.drawImage(image, 0, 0, image.width, image.height);
|
||||
result = canvas.toDataURL();
|
||||
}
|
||||
callback(result);
|
||||
};
|
||||
image.src = sourceData;
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} image
|
||||
*/
|
||||
function sendImage(image) {
|
||||
fixImage(image, 320, 240, function (result) {
|
||||
send({image: result});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
*/
|
||||
@@ -1461,8 +1459,8 @@ function blur() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} event
|
||||
* Handle a message.
|
||||
* @param event The message.
|
||||
*/
|
||||
function message(event) {
|
||||
if (
|
||||
@@ -1510,8 +1508,8 @@ function message(event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
* Reconnect the WebSocket.
|
||||
* @param path The path to which the WebSocket should be connected.
|
||||
*/
|
||||
function reconnect(path) {
|
||||
let oldSocket = gSocket;
|
||||
@@ -1526,8 +1524,8 @@ function reconnect(path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} path
|
||||
* Connect the WebSocket.
|
||||
* @param path The path to which to connect.
|
||||
*/
|
||||
function connectSocket(path) {
|
||||
if (!gSocket || gSocket.readyState != gSocket.OPEN) {
|
||||
@@ -1593,8 +1591,8 @@ function connectSocket(path) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* Open a file by name.
|
||||
* @param name The file to open.
|
||||
*/
|
||||
function openFile(name) {
|
||||
let newDoc =
|
||||
@@ -1641,8 +1639,8 @@ function updateFiles() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* Create a new file with the given name.
|
||||
* @param name The file's name.
|
||||
*/
|
||||
function makeNewFile(name) {
|
||||
gFiles[name] = {
|
||||
@@ -1703,10 +1701,10 @@ async function appExport() {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} name
|
||||
* @param {*} file
|
||||
* @returns
|
||||
* Save a file.
|
||||
* @param name The file to svae.
|
||||
* @param file The file contents.
|
||||
* @return A promise resolved with the blob ID of the saved file.
|
||||
*/
|
||||
async function save_file_to_blob_id(name, file) {
|
||||
console.log(`Saving ${name}.`);
|
||||
@@ -1801,7 +1799,7 @@ async function appImport() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Prettify the current source file.
|
||||
*/
|
||||
async function sourcePretty() {
|
||||
let prettier = (await import('/prettier/standalone.mjs')).default;
|
||||
@@ -1829,6 +1827,9 @@ async function sourcePretty() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle visible whitespace.
|
||||
*/
|
||||
function toggleVisibleWhitespace() {
|
||||
let editor_style = document.getElementById('editor_style');
|
||||
/*
|
||||
@@ -1902,3 +1903,5 @@ window.addEventListener('load', function () {
|
||||
toggleVisibleWhitespace();
|
||||
}
|
||||
});
|
||||
|
||||
/** @} */
|
||||
|
125
core/core.js
125
core/core.js
@@ -1,12 +1,17 @@
|
||||
/**
|
||||
** \defgroup tfcore Tilde Friends Core JS
|
||||
** Tilde Friends process management, in JavaScript.
|
||||
** @{
|
||||
*/
|
||||
* \file
|
||||
* \defgroup tfcore Tilde Friends Core JS
|
||||
* Tilde Friends process management, in JavaScript.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \cond */
|
||||
import * as app from './app.js';
|
||||
import * as http from './http.js';
|
||||
|
||||
export {invoke, getProcessBlob};
|
||||
/** \endcond */
|
||||
|
||||
/** All running processes. */
|
||||
let gProcesses = {};
|
||||
/** Whether stats are currently being sent. */
|
||||
@@ -17,9 +22,9 @@ let g_handler_index = 0;
|
||||
const k_ping_interval = 60 * 1000;
|
||||
|
||||
/**
|
||||
** Print an error.
|
||||
** @param error The error.
|
||||
*/
|
||||
* Print an error.
|
||||
* @param error The error.
|
||||
*/
|
||||
function printError(error) {
|
||||
if (error.stackTrace) {
|
||||
print(error.fileName + ':' + error.lineNumber + ': ' + error.message);
|
||||
@@ -33,11 +38,11 @@ function printError(error) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Invoke a handler.
|
||||
** @param handlers The handlers on which to invoke the callback.
|
||||
** @param argv Arguments to pass to the handlers.
|
||||
** @return A promise.
|
||||
*/
|
||||
* Invoke a handler.
|
||||
* @param handlers The handlers on which to invoke the callback.
|
||||
* @param argv Arguments to pass to the handlers.
|
||||
* @return A promise.
|
||||
*/
|
||||
function invoke(handlers, argv) {
|
||||
let promises = [];
|
||||
if (handlers) {
|
||||
@@ -59,11 +64,11 @@ function invoke(handlers, argv) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Broadcast a named event to all registered apps.
|
||||
** @param eventName the name of the event.
|
||||
** @param argv Arguments to pass to the handlers.
|
||||
** @return A promise.
|
||||
*/
|
||||
* Broadcast a named event to all registered apps.
|
||||
* @param eventName the name of the event.
|
||||
* @param argv Arguments to pass to the handlers.
|
||||
* @return A promise.
|
||||
*/
|
||||
function broadcastEvent(eventName, argv) {
|
||||
let promises = [];
|
||||
for (let process of Object.values(gProcesses)) {
|
||||
@@ -75,10 +80,10 @@ function broadcastEvent(eventName, argv) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Send a message to all other instances of the same app.
|
||||
** @param message The message.
|
||||
** @return A promise.
|
||||
*/
|
||||
* Send a message to all other instances of the same app.
|
||||
* @param message The message.
|
||||
* @return A promise.
|
||||
*/
|
||||
function broadcast(message) {
|
||||
let sender = this;
|
||||
let promises = [];
|
||||
@@ -96,14 +101,14 @@ function broadcast(message) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Send a message to all instances of the same app running as the same user.
|
||||
** @param user The user.
|
||||
** @param packageOwner The owner of the app.
|
||||
** @param packageName The name of the app.
|
||||
** @param eventName The name of the event.
|
||||
** @param argv The arguments to pass.
|
||||
** @return A promise.
|
||||
*/
|
||||
* Send a message to all instances of the same app running as the same user.
|
||||
* @param user The user.
|
||||
* @param packageOwner The owner of the app.
|
||||
* @param packageName The name of the app.
|
||||
* @param eventName The name of the event.
|
||||
* @param argv The arguments to pass.
|
||||
* @return A promise.
|
||||
*/
|
||||
function broadcastAppEventToUser(
|
||||
user,
|
||||
packageOwner,
|
||||
@@ -127,10 +132,10 @@ function broadcastAppEventToUser(
|
||||
}
|
||||
|
||||
/**
|
||||
** Get user context information for a call.
|
||||
** @param caller The calling process.
|
||||
** @param process The receiving process.
|
||||
*/
|
||||
* Get user context information for a call.
|
||||
* @param caller The calling process.
|
||||
* @param process The receiving process.
|
||||
*/
|
||||
function getUser(caller, process) {
|
||||
return {
|
||||
key: process.key,
|
||||
@@ -142,12 +147,12 @@ function getUser(caller, process) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Send a message.
|
||||
** @param from The calling process.
|
||||
** @param to The receiving process.
|
||||
** @param message The message.
|
||||
** @return A promise.
|
||||
*/
|
||||
* Send a message.
|
||||
* @param from The calling process.
|
||||
* @param to The receiving process.
|
||||
* @param message The message.
|
||||
* @return A promise.
|
||||
*/
|
||||
function postMessageInternal(from, to, message) {
|
||||
if (to.eventHandlers['message']) {
|
||||
return invoke(to.eventHandlers['message'], [getUser(from, from), message]);
|
||||
@@ -155,12 +160,12 @@ function postMessageInternal(from, to, message) {
|
||||
}
|
||||
|
||||
/**
|
||||
** Get or create a process for an app blob.
|
||||
** @param blobId The blob identifier.
|
||||
** @param key A unique key for the invocation.
|
||||
** @param options Other options.
|
||||
** @return The process.
|
||||
*/
|
||||
* Get or create a process for an app blob.
|
||||
* @param blobId The blob identifier.
|
||||
* @param key A unique key for the invocation.
|
||||
* @param options Other options.
|
||||
* @return The process.
|
||||
*/
|
||||
async function getProcessBlob(blobId, key, options) {
|
||||
let process = gProcesses[key];
|
||||
if (!process && !(options && 'create' in options && !options.create)) {
|
||||
@@ -711,9 +716,9 @@ ssb.addEventListener('connections', function () {
|
||||
});
|
||||
|
||||
/**
|
||||
** Load settings from the database.
|
||||
** @return The settings as a key value pairs object.
|
||||
*/
|
||||
* Load settings from the database.
|
||||
* @return The settings as a key value pairs object.
|
||||
*/
|
||||
async function loadSettings() {
|
||||
let data = {};
|
||||
try {
|
||||
@@ -733,8 +738,8 @@ async function loadSettings() {
|
||||
}
|
||||
|
||||
/**
|
||||
** Send periodic stats to all clients.
|
||||
*/
|
||||
* Send periodic stats to all clients.
|
||||
*/
|
||||
function sendStats() {
|
||||
let apps = Object.values(gProcesses)
|
||||
.filter((process) => process.app)
|
||||
@@ -751,15 +756,15 @@ function sendStats() {
|
||||
}
|
||||
|
||||
/**
|
||||
** Invoke an app's handler.js.
|
||||
** @param response The response object.
|
||||
** @param app_blob_id The app's blob identifier.
|
||||
** @param path The request path.
|
||||
** @param query The request query string.
|
||||
** @param headers The request headers.
|
||||
** @param package_owner The app's owner.
|
||||
** @param package_name The app's name.
|
||||
*/
|
||||
* Invoke an app's handler.js.
|
||||
* @param response The response object.
|
||||
* @param app_blob_id The app's blob identifier.
|
||||
* @param path The request path.
|
||||
* @param query The request query string.
|
||||
* @param headers The request headers.
|
||||
* @param package_owner The app's owner.
|
||||
* @param package_name The app's name.
|
||||
*/
|
||||
exports.callAppHandler = async function callAppHandler(
|
||||
response,
|
||||
app_blob_id,
|
||||
@@ -826,5 +831,3 @@ exports.callAppHandler = async function callAppHandler(
|
||||
};
|
||||
|
||||
/** @} */
|
||||
|
||||
export { invoke, getProcessBlob };
|
||||
|
@@ -1,6 +1,17 @@
|
||||
/**
|
||||
* \file
|
||||
* \defgroup tfrpc Tilde Friends RPC.
|
||||
* Tilde Friends RPC.
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** Whether this module is being run in a web browser. */
|
||||
const k_is_browser = get_is_browser();
|
||||
/** Registered methods. */
|
||||
let g_api = {};
|
||||
/** The next method identifier. */
|
||||
let g_next_id = 1;
|
||||
/** Identifiers of pending calls. */
|
||||
let g_calls = {};
|
||||
|
||||
/**
|
||||
@@ -15,16 +26,30 @@ function get_is_browser() {
|
||||
}
|
||||
}
|
||||
|
||||
/** \cond */
|
||||
if (k_is_browser) {
|
||||
print = console.log;
|
||||
}
|
||||
|
||||
if (k_is_browser) {
|
||||
window.addEventListener('message', function (event) {
|
||||
call_rpc(event.data);
|
||||
});
|
||||
} else {
|
||||
core.register('message', function (message) {
|
||||
call_rpc(message?.message);
|
||||
});
|
||||
}
|
||||
|
||||
export let rpc = new Proxy({}, {get: make_rpc});
|
||||
/** \endcond */
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} target
|
||||
* @param {*} prop
|
||||
* @param {*} receiver
|
||||
* @returns
|
||||
* Make a function to invoke a remote procedure.
|
||||
* @param target The target.
|
||||
* @param prop The name of the function.
|
||||
* @param receiver The receiver.
|
||||
* @return A function.
|
||||
*/
|
||||
function make_rpc(target, prop, receiver) {
|
||||
return function () {
|
||||
@@ -55,8 +80,8 @@ function make_rpc(target, prop, receiver) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} response
|
||||
* Send a response.
|
||||
* @param response The response.
|
||||
*/
|
||||
function send(response) {
|
||||
if (k_is_browser) {
|
||||
@@ -67,8 +92,8 @@ function send(response) {
|
||||
}
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} message
|
||||
* Invoke a remote procedure.
|
||||
* @param message An object describing the call.
|
||||
*/
|
||||
function call_rpc(message) {
|
||||
if (message && message.message === 'tfrpc') {
|
||||
@@ -112,22 +137,12 @@ function call_rpc(message) {
|
||||
}
|
||||
}
|
||||
|
||||
if (k_is_browser) {
|
||||
window.addEventListener('message', function (event) {
|
||||
call_rpc(event.data);
|
||||
});
|
||||
} else {
|
||||
core.register('message', function (message) {
|
||||
call_rpc(message?.message);
|
||||
});
|
||||
}
|
||||
|
||||
export let rpc = new Proxy({}, {get: make_rpc});
|
||||
|
||||
/**
|
||||
* TODOC
|
||||
* @param {*} method
|
||||
* Register a function that to be called remotely.
|
||||
* @param method The method.
|
||||
*/
|
||||
export function register(method) {
|
||||
g_api[method.name] = method;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
|
Reference in New Issue
Block a user