docs: Expose the rest of the core js to doxygen.
All checks were successful
Build Tilde Friends / Build-All (push) Successful in 31m35s

This commit is contained in:
2025-07-27 21:48:18 -04:00
parent e4729b22f2
commit 705e8b553f
4 changed files with 248 additions and 227 deletions

View File

@@ -945,13 +945,13 @@ WARN_LOGFILE =
INPUT = README.md \ INPUT = README.md \
core/app.js \ core/app.js \
core/client.js \
core/core.js \ core/core.js \
core/http.js \ core/http.js \
core/tfrpc.js \
docs/ \ docs/ \
src/ src/
# Not yet: core/tfrpc.js core/client.js
# This tag can be used to specify the character encoding of the source files # 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 # 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 # libiconv (or the iconv built into libc) for the transcoding. See the libiconv

View File

@@ -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'; import {LitElement, html, css, svg} from '/lit/lit-all.min.js';
let cm6; let cm6;
@@ -13,8 +21,9 @@ let gUnloading;
let kErrorColor = '#dc322f'; let kErrorColor = '#dc322f';
let kDisconnectColor = '#f00'; let kDisconnectColor = '#f00';
let kStatusColor = '#fff'; 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 = { const k_api = {
setDocument: {args: ['content'], func: api_setDocument}, setDocument: {args: ['content'], func: api_setDocument},
postMessage: {args: ['message'], func: api_postMessage}, postMessage: {args: ['message'], func: api_postMessage},
@@ -26,29 +35,14 @@ const k_api = {
setHash: {args: ['hash'], func: api_setHash}, 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 that represents the top bar
*/ */
class TfNavigationElement extends LitElement { class TfNavigationElement extends LitElement {
/**
* Get Lit Html properties.
* @return The properties.
*/
static get properties() { static get properties() {
return { return {
credentials: {type: Object}, credentials: {type: Object},
@@ -64,6 +58,9 @@ class TfNavigationElement extends LitElement {
}; };
} }
/**
* Create a TfNavigationElement instance.
*/
constructor() { constructor() {
super(); super();
this.permissions = {}; this.permissions = {};
@@ -76,7 +73,7 @@ class TfNavigationElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} event * @param event The HTML event.
*/ */
toggle_edit(event) { toggle_edit(event) {
event.preventDefault(); event.preventDefault();
@@ -89,7 +86,7 @@ class TfNavigationElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} key * @param key The permission to reset.
*/ */
reset_permission(key) { reset_permission(key) {
send({action: 'resetPermission', permission: key}); send({action: 'resetPermission', permission: key});
@@ -97,9 +94,9 @@ class TfNavigationElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} key * @param key The spark line identifier.
* @param {*} options * @param options Spark line options.
* @returns * @return A spark line HTML element.
*/ */
get_spark_line(key, options) { get_spark_line(key, options) {
if (!this.spark_lines[key]) { if (!this.spark_lines[key]) {
@@ -118,29 +115,49 @@ class TfNavigationElement extends LitElement {
return this.spark_lines[key]; return this.spark_lines[key];
} }
/**
* Set the active SSB identity for the current application.
* @param id The identity.
*/
set_active_identity(id) { set_active_identity(id) {
send({action: 'setActiveIdentity', identity: id}); send({action: 'setActiveIdentity', identity: id});
this.renderRoot.getElementById('id_dropdown').classList.remove('w3-show'); 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?')) { if (confirm('Are you sure you want to create a new identity?')) {
send({action: 'createIdentity'}); send({action: 'createIdentity'});
} }
} }
/**
* Toggle visibility of the ID dropdown.
*/
toggle_id_dropdown() { toggle_id_dropdown() {
this.renderRoot.getElementById('id_dropdown').classList.toggle('w3-show'); this.renderRoot.getElementById('id_dropdown').classList.toggle('w3-show');
} }
/**
* Edit the current identity's SSB profile.
*/
edit_profile() { edit_profile() {
window.location.href = '/~core/ssb/#' + this.identity; window.location.href = '/~core/ssb/#' + this.identity;
} }
/**
* Sign out of the current Tilde Friends user.
*/
logout() { logout() {
window.location.href = `/login/logout?return=${encodeURIComponent(url() + hash())}`; window.location.href = `/login/logout?return=${encodeURIComponent(url() + hash())}`;
} }
/**
* Render the identity dropdown.
* @return Lit HTML.
*/
render_identity() { render_identity() {
let self = this; let self = this;
@@ -287,6 +304,9 @@ class TfNavigationElement extends LitElement {
} }
} }
/**
* Clear the current error.
*/
clear_error() { clear_error() {
this.status = {}; this.status = {};
} }
@@ -297,6 +317,23 @@ class TfNavigationElement extends LitElement {
*/ */
render() { render() {
let self = this; 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` return html`
<link type="text/css" rel="stylesheet" href="/static/w3.css" /> <link type="text/css" rel="stylesheet" href="/static/w3.css" />
<style> <style>
@@ -407,6 +444,10 @@ customElements.define('tf-navigation', TfNavigationElement);
* TODOC * TODOC
*/ */
class TfFilesElement extends LitElement { class TfFilesElement extends LitElement {
/**
* LitElement properties.
* @return The properties.
*/
static get properties() { static get properties() {
return { return {
current: {type: String}, current: {type: String},
@@ -416,6 +457,9 @@ class TfFilesElement extends LitElement {
}; };
} }
/**
* Create a TfFilesElement instance.
*/
constructor() { constructor() {
super(); super();
this.files = {}; this.files = {};
@@ -424,7 +468,7 @@ class TfFilesElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} file * @param file The file.
*/ */
file_click(file) { file_click(file) {
this.dispatchEvent( this.dispatchEvent(
@@ -440,8 +484,8 @@ class TfFilesElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} file * @param file The file.
* @returns * @returns Lit HTML.
*/ */
render_file(file) { render_file(file) {
let classes = ['file']; let classes = ['file'];
@@ -464,7 +508,7 @@ class TfFilesElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} event * @param event The event.
*/ */
async drop(event) { async drop(event) {
event.preventDefault(); event.preventDefault();
@@ -490,7 +534,7 @@ class TfFilesElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} event * @param event The event.
*/ */
drag_enter(event) { drag_enter(event) {
this.dropping++; this.dropping++;
@@ -500,7 +544,7 @@ class TfFilesElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} event * @param event The event.
*/ */
drag_leave(event) { drag_leave(event) {
this.dropping--; this.dropping--;
@@ -509,6 +553,10 @@ class TfFilesElement extends LitElement {
} }
} }
/**
* Drag over event.
* @param event The event.
*/
drag_over(event) { drag_over(event) {
event.preventDefault(); event.preventDefault();
} }
@@ -565,6 +613,10 @@ customElements.define('tf-files', TfFilesElement);
* TODOC * TODOC
*/ */
class TfFilesPaneElement extends LitElement { class TfFilesPaneElement extends LitElement {
/**
* Get Lit Html properties.
* @return The properties.
*/
static get properties() { static get properties() {
return { return {
expanded: {type: Boolean}, expanded: {type: Boolean},
@@ -573,6 +625,9 @@ class TfFilesPaneElement extends LitElement {
}; };
} }
/**
* Create a TfFilesPaneElement instance.
*/
constructor() { constructor() {
super(); super();
this.expanded = window.localStorage.getItem('files') != '0'; this.expanded = window.localStorage.getItem('files') != '0';
@@ -581,7 +636,7 @@ class TfFilesPaneElement extends LitElement {
/** /**
* TODOC * TODOC
* @param {*} expanded * @param expanded Whether the files pane is expanded.
*/ */
set_expanded(expanded) { set_expanded(expanded) {
this.expanded = expanded; this.expanded = expanded;
@@ -760,10 +815,9 @@ window.addEventListener('keydown', function (event) {
}); });
/** /**
* TODOC * Make sure a set of dependencies are loaded
* @param {*} nodes * @param nodes An array of descriptions of dependencies to load.
* @param {*} callback * @param callback Called when all dependencies are loaded.
* @returns
*/ */
function ensureLoaded(nodes, callback) { function ensureLoaded(nodes, callback) {
if (!nodes.length) { if (!nodes.length) {
@@ -857,23 +911,10 @@ function trace() {
} }
/** /**
* TODOC * Load a single file.
* @param {*} name * @param name The name by which the file is known.
* @returns * @param id The file's ID.
*/ * @return A promise resolved with the file's contents.
function guessMode(name) {
return name.endsWith('.js')
? 'javascript'
: name.endsWith('.html')
? 'htmlmixed'
: null;
}
/**
* TODOC
* @param {*} name
* @param {*} id
* @returns
*/ */
function loadFile(name, id) { function loadFile(name, id) {
return fetch('/' + id + '/view') return fetch('/' + id + '/view')
@@ -899,9 +940,9 @@ function loadFile(name, id) {
} }
/** /**
* TODOC * Load files for the app.
* @param {*} path * @param path The app path to load.
* @returns * @return A promise resolved when the app is laoded.
*/ */
async function load(path) { async function load(path) {
let response = await fetch((path || url()) + 'view'); let response = await fetch((path || url()) + 'view');
@@ -958,9 +999,9 @@ function explodePath() {
} }
/** /**
* TODOC * Save the app.
* @param {*} save_to * @param save_to An optional path to which to save the app.
* @returns * @return A promise resoled when the app is saved.
*/ */
function save(save_to) { function save(save_to) {
document.getElementById('save').disabled = true; document.getElementById('save').disabled = true;
@@ -1129,8 +1170,8 @@ function hash() {
} }
/** /**
* TODOC * Set the iframe document contents.
* @param {*} content * @param content The contents.
*/ */
function api_setDocument(content) { function api_setDocument(content) {
let iframe = document.getElementById('document'); let iframe = document.getElementById('document');
@@ -1138,8 +1179,8 @@ function api_setDocument(content) {
} }
/** /**
* TODOC * Send a message to the sandboxed iframe.
* @param {*} message * @param message The message.
*/ */
function api_postMessage(message) { function api_postMessage(message) {
let iframe = document.getElementById('document'); let iframe = document.getElementById('document');
@@ -1148,7 +1189,7 @@ function api_postMessage(message) {
/** /**
* TODOC * TODOC
* @param {*} error * @param error The error.
*/ */
function api_error(error) { function api_error(error) {
if (error) { if (error) {
@@ -1162,28 +1203,28 @@ function api_error(error) {
} }
/** /**
* TODOC et a value in local storage.
* @param {*} key * @param key The key.
* @param {*} value * @param value The value.
*/ */
function api_localStorageSet(key, value) { function api_localStorageSet(key, value) {
window.localStorage.setItem('app:' + key, value); window.localStorage.setItem('app:' + key, value);
} }
/** /**
* TODOC * Get a value from local storage.
* @param {*} key * @param key The key.
* @returns * @return The value.
*/ */
function api_localStorageGet(key) { function api_localStorageGet(key) {
return window.localStorage.getItem('app:' + key); return window.localStorage.getItem('app:' + key);
} }
/** /**
* TODOC * Request a permission
* @param {*} permission * @param permission The permission to request.
* @param {*} id * @param id The id requeesting the permission.
* @returns * @return A promise fulfilled if the permission was granted.
*/ */
function api_requestPermission(permission, id) { function api_requestPermission(permission, id) {
let outer = document.createElement('div'); let outer = document.createElement('div');
@@ -1259,8 +1300,8 @@ function api_print() {
} }
/** /**
* TODOC * Set the window's location hash.
* @param {*} hash * @param hash The new hash.
*/ */
function api_setHash(hash) { function api_setHash(hash) {
window.location.hash = hash; window.location.hash = hash;
@@ -1268,7 +1309,7 @@ function api_setHash(hash) {
/** /**
* TODOC * TODOC
* @param {*} message * @param message The message.
*/ */
function _receive_websocket_message(message) { function _receive_websocket_message(message) {
if (message && message.action == 'session') { if (message && message.action == 'session') {
@@ -1364,9 +1405,9 @@ function _receive_websocket_message(message) {
} }
/** /**
* TODOC * Set the status message.
* @param {*} message * @param message The message.
* @param {*} color * @param color The message's color.
*/ */
function setStatusMessage(message, color) { function setStatusMessage(message, color) {
document.getElementsByTagName('tf-navigation')[0].status = { document.getElementsByTagName('tf-navigation')[0].status = {
@@ -1377,8 +1418,8 @@ function setStatusMessage(message, color) {
} }
/** /**
* TODOC * Send a message to the app.
* @param {*} value * @param value The message.
*/ */
function send(value) { function send(value) {
try { 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 * TODOC
*/ */
@@ -1461,8 +1459,8 @@ function blur() {
} }
/** /**
* TODOC * Handle a message.
* @param {*} event * @param event The message.
*/ */
function message(event) { function message(event) {
if ( if (
@@ -1510,8 +1508,8 @@ function message(event) {
} }
/** /**
* TODOC * Reconnect the WebSocket.
* @param {*} path * @param path The path to which the WebSocket should be connected.
*/ */
function reconnect(path) { function reconnect(path) {
let oldSocket = gSocket; let oldSocket = gSocket;
@@ -1526,8 +1524,8 @@ function reconnect(path) {
} }
/** /**
* TODOC * Connect the WebSocket.
* @param {*} path * @param path The path to which to connect.
*/ */
function connectSocket(path) { function connectSocket(path) {
if (!gSocket || gSocket.readyState != gSocket.OPEN) { if (!gSocket || gSocket.readyState != gSocket.OPEN) {
@@ -1593,8 +1591,8 @@ function connectSocket(path) {
} }
/** /**
* TODOC * Open a file by name.
* @param {*} name * @param name The file to open.
*/ */
function openFile(name) { function openFile(name) {
let newDoc = let newDoc =
@@ -1641,8 +1639,8 @@ function updateFiles() {
} }
/** /**
* TODOC * Create a new file with the given name.
* @param {*} name * @param name The file's name.
*/ */
function makeNewFile(name) { function makeNewFile(name) {
gFiles[name] = { gFiles[name] = {
@@ -1703,10 +1701,10 @@ async function appExport() {
} }
/** /**
* TODOC * Save a file.
* @param {*} name * @param name The file to svae.
* @param {*} file * @param file The file contents.
* @returns * @return A promise resolved with the blob ID of the saved file.
*/ */
async function save_file_to_blob_id(name, file) { async function save_file_to_blob_id(name, file) {
console.log(`Saving ${name}.`); console.log(`Saving ${name}.`);
@@ -1801,7 +1799,7 @@ async function appImport() {
} }
/** /**
* * Prettify the current source file.
*/ */
async function sourcePretty() { async function sourcePretty() {
let prettier = (await import('/prettier/standalone.mjs')).default; let prettier = (await import('/prettier/standalone.mjs')).default;
@@ -1829,6 +1827,9 @@ async function sourcePretty() {
} }
} }
/**
* Toggle visible whitespace.
*/
function toggleVisibleWhitespace() { function toggleVisibleWhitespace() {
let editor_style = document.getElementById('editor_style'); let editor_style = document.getElementById('editor_style');
/* /*
@@ -1902,3 +1903,5 @@ window.addEventListener('load', function () {
toggleVisibleWhitespace(); toggleVisibleWhitespace();
} }
}); });
/** @} */

View File

@@ -1,12 +1,17 @@
/** /**
** \defgroup tfcore Tilde Friends Core JS * \file
** Tilde Friends process management, in JavaScript. * \defgroup tfcore Tilde Friends Core JS
** @{ * Tilde Friends process management, in JavaScript.
* @{
*/ */
/** \cond */
import * as app from './app.js'; import * as app from './app.js';
import * as http from './http.js'; import * as http from './http.js';
export {invoke, getProcessBlob};
/** \endcond */
/** All running processes. */ /** All running processes. */
let gProcesses = {}; let gProcesses = {};
/** Whether stats are currently being sent. */ /** Whether stats are currently being sent. */
@@ -17,8 +22,8 @@ let g_handler_index = 0;
const k_ping_interval = 60 * 1000; const k_ping_interval = 60 * 1000;
/** /**
** Print an error. * Print an error.
** @param error The error. * @param error The error.
*/ */
function printError(error) { function printError(error) {
if (error.stackTrace) { if (error.stackTrace) {
@@ -33,10 +38,10 @@ function printError(error) {
} }
/** /**
** Invoke a handler. * Invoke a handler.
** @param handlers The handlers on which to invoke the callback. * @param handlers The handlers on which to invoke the callback.
** @param argv Arguments to pass to the handlers. * @param argv Arguments to pass to the handlers.
** @return A promise. * @return A promise.
*/ */
function invoke(handlers, argv) { function invoke(handlers, argv) {
let promises = []; let promises = [];
@@ -59,10 +64,10 @@ function invoke(handlers, argv) {
} }
/** /**
** Broadcast a named event to all registered apps. * Broadcast a named event to all registered apps.
** @param eventName the name of the event. * @param eventName the name of the event.
** @param argv Arguments to pass to the handlers. * @param argv Arguments to pass to the handlers.
** @return A promise. * @return A promise.
*/ */
function broadcastEvent(eventName, argv) { function broadcastEvent(eventName, argv) {
let promises = []; let promises = [];
@@ -75,9 +80,9 @@ function broadcastEvent(eventName, argv) {
} }
/** /**
** Send a message to all other instances of the same app. * Send a message to all other instances of the same app.
** @param message The message. * @param message The message.
** @return A promise. * @return A promise.
*/ */
function broadcast(message) { function broadcast(message) {
let sender = this; let sender = this;
@@ -96,13 +101,13 @@ function broadcast(message) {
} }
/** /**
** Send a message to all instances of the same app running as the same user. * Send a message to all instances of the same app running as the same user.
** @param user The user. * @param user The user.
** @param packageOwner The owner of the app. * @param packageOwner The owner of the app.
** @param packageName The name of the app. * @param packageName The name of the app.
** @param eventName The name of the event. * @param eventName The name of the event.
** @param argv The arguments to pass. * @param argv The arguments to pass.
** @return A promise. * @return A promise.
*/ */
function broadcastAppEventToUser( function broadcastAppEventToUser(
user, user,
@@ -127,9 +132,9 @@ function broadcastAppEventToUser(
} }
/** /**
** Get user context information for a call. * Get user context information for a call.
** @param caller The calling process. * @param caller The calling process.
** @param process The receiving process. * @param process The receiving process.
*/ */
function getUser(caller, process) { function getUser(caller, process) {
return { return {
@@ -142,11 +147,11 @@ function getUser(caller, process) {
} }
/** /**
** Send a message. * Send a message.
** @param from The calling process. * @param from The calling process.
** @param to The receiving process. * @param to The receiving process.
** @param message The message. * @param message The message.
** @return A promise. * @return A promise.
*/ */
function postMessageInternal(from, to, message) { function postMessageInternal(from, to, message) {
if (to.eventHandlers['message']) { if (to.eventHandlers['message']) {
@@ -155,11 +160,11 @@ function postMessageInternal(from, to, message) {
} }
/** /**
** Get or create a process for an app blob. * Get or create a process for an app blob.
** @param blobId The blob identifier. * @param blobId The blob identifier.
** @param key A unique key for the invocation. * @param key A unique key for the invocation.
** @param options Other options. * @param options Other options.
** @return The process. * @return The process.
*/ */
async function getProcessBlob(blobId, key, options) { async function getProcessBlob(blobId, key, options) {
let process = gProcesses[key]; let process = gProcesses[key];
@@ -711,8 +716,8 @@ ssb.addEventListener('connections', function () {
}); });
/** /**
** Load settings from the database. * Load settings from the database.
** @return The settings as a key value pairs object. * @return The settings as a key value pairs object.
*/ */
async function loadSettings() { async function loadSettings() {
let data = {}; let data = {};
@@ -733,7 +738,7 @@ async function loadSettings() {
} }
/** /**
** Send periodic stats to all clients. * Send periodic stats to all clients.
*/ */
function sendStats() { function sendStats() {
let apps = Object.values(gProcesses) let apps = Object.values(gProcesses)
@@ -751,14 +756,14 @@ function sendStats() {
} }
/** /**
** Invoke an app's handler.js. * Invoke an app's handler.js.
** @param response The response object. * @param response The response object.
** @param app_blob_id The app's blob identifier. * @param app_blob_id The app's blob identifier.
** @param path The request path. * @param path The request path.
** @param query The request query string. * @param query The request query string.
** @param headers The request headers. * @param headers The request headers.
** @param package_owner The app's owner. * @param package_owner The app's owner.
** @param package_name The app's name. * @param package_name The app's name.
*/ */
exports.callAppHandler = async function callAppHandler( exports.callAppHandler = async function callAppHandler(
response, response,
@@ -826,5 +831,3 @@ exports.callAppHandler = async function callAppHandler(
}; };
/** @} */ /** @} */
export { invoke, getProcessBlob };

View File

@@ -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(); const k_is_browser = get_is_browser();
/** Registered methods. */
let g_api = {}; let g_api = {};
/** The next method identifier. */
let g_next_id = 1; let g_next_id = 1;
/** Identifiers of pending calls. */
let g_calls = {}; let g_calls = {};
/** /**
@@ -15,16 +26,30 @@ function get_is_browser() {
} }
} }
/** \cond */
if (k_is_browser) { if (k_is_browser) {
print = console.log; 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 * Make a function to invoke a remote procedure.
* @param {*} target * @param target The target.
* @param {*} prop * @param prop The name of the function.
* @param {*} receiver * @param receiver The receiver.
* @returns * @return A function.
*/ */
function make_rpc(target, prop, receiver) { function make_rpc(target, prop, receiver) {
return function () { return function () {
@@ -55,8 +80,8 @@ function make_rpc(target, prop, receiver) {
} }
/** /**
* TODOC * Send a response.
* @param {*} response * @param response The response.
*/ */
function send(response) { function send(response) {
if (k_is_browser) { if (k_is_browser) {
@@ -67,8 +92,8 @@ function send(response) {
} }
/** /**
* TODOC * Invoke a remote procedure.
* @param {*} message * @param message An object describing the call.
*/ */
function call_rpc(message) { function call_rpc(message) {
if (message && message.message === 'tfrpc') { 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 * Register a function that to be called remotely.
* @param {*} method * @param method The method.
*/ */
export function register(method) { export function register(method) {
g_api[method.name] = method; g_api[method.name] = method;
} }
/** @} */