diff --git a/Doxyfile b/Doxyfile index 9e298157..677d8b47 100644 --- a/Doxyfile +++ b/Doxyfile @@ -342,7 +342,7 @@ OPTIMIZE_OUTPUT_SLICE = NO # # Note see also the list of default file extension mappings. -EXTENSION_MAPPING = +EXTENSION_MAPPING = js=javascript # If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments # according to the Markdown format, which allows for more readable @@ -944,9 +944,14 @@ WARN_LOGFILE = # Note: If this tag is empty the current directory is searched. INPUT = README.md \ + core/app.js \ + core/core.js \ + core/http.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 @@ -986,6 +991,7 @@ INPUT_FILE_ENCODING = # *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. FILE_PATTERNS = *.h \ + *.js \ *.md # The RECURSIVE tag can be used to specify whether or not subdirectories should diff --git a/core/core.js b/core/core.js index 0b34bb71..77081405 100644 --- a/core/core.js +++ b/core/core.js @@ -1,12 +1,25 @@ +/** +** \defgroup tfcore Tilde Friends Core JS +** Tilde Friends process management, in JavaScript. +** @{ +*/ + import * as app from './app.js'; import * as http from './http.js'; +/** All running processes. */ let gProcesses = {}; +/** Whether stats are currently being sent. */ let gStatsTimer = false; +/** Effectively a process ID. */ let g_handler_index = 0; - +/** Time between pings, in milliseconds. */ const k_ping_interval = 60 * 1000; +/** +** Print an error. +** @param error The error. +*/ function printError(error) { if (error.stackTrace) { print(error.fileName + ':' + error.lineNumber + ': ' + error.message); @@ -19,6 +32,12 @@ 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. +*/ function invoke(handlers, argv) { let promises = []; if (handlers) { @@ -39,6 +58,12 @@ function invoke(handlers, argv) { return Promise.all(promises); } +/** +** 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)) { @@ -49,6 +74,11 @@ function broadcastEvent(eventName, argv) { return Promise.all(promises); } +/** +** 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 = []; @@ -65,6 +95,15 @@ function broadcast(message) { return Promise.all(promises); } +/** +** 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, @@ -87,6 +126,11 @@ function broadcastAppEventToUser( return Promise.all(promises); } +/** +** 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, @@ -97,12 +141,26 @@ function getUser(caller, process) { }; } +/** +** 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]); } } +/** +** 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)) { @@ -652,6 +710,10 @@ ssb.addEventListener('connections', function () { broadcastEvent('onConnectionsChanged', []); }); +/** +** Load settings from the database. +** @return The settings as a key value pairs object. +*/ async function loadSettings() { let data = {}; try { @@ -670,6 +732,9 @@ async function loadSettings() { return data; } +/** +** Send periodic stats to all clients. +*/ function sendStats() { let apps = Object.values(gProcesses) .filter((process) => process.app) @@ -685,6 +750,16 @@ 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. +*/ exports.callAppHandler = async function callAppHandler( response, app_blob_id, @@ -750,4 +825,6 @@ exports.callAppHandler = async function callAppHandler( response.end(answer?.data); }; -export {invoke, getProcessBlob}; +/** @} */ + +export { invoke, getProcessBlob };