Skip to content

Commit

Permalink
dev: launchApp as registered ipc handler
Browse files Browse the repository at this point in the history
Add launchApp as a registered ipc handler, which will allow communication
between iframes (apps/puter.js) to be simplified.
  • Loading branch information
KernelDeimos committed Aug 29, 2024
1 parent 813ee95 commit 7249429
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 19 deletions.
31 changes: 12 additions & 19 deletions src/gui/src/IPC.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import update_mouse_position from './helpers/update_mouse_position.js';
import launch_app from './helpers/launch_app.js';
import item_icon from './helpers/item_icon.js';

window.ipc_handlers = {};
/**
* In Puter, apps are loaded in iframes and communicate with the graphical user interface (GUI), and each other, using the postMessage API.
* The following sets up an Inter-Process Messaging System between apps and the GUI that enables communication
Expand Down Expand Up @@ -88,6 +89,17 @@ window.addEventListener('message', async (event) => {
const msg_id = event.data.uuid;
const app_name = $(target_iframe).attr('data-app');
const app_uuid = $el_parent_window.attr('data-app_uuid');

if ( window.ipc_handlers.hasOwnProperty(event.data.msg) ) {
console.log('got message to new IPC handler', event.data.msg);
const ipc_context = {
appInstanceId: event.data.appInstanceID,
};
const spec = window.ipc_handlers[event.data.msg];
await spec.handler(event.data, { msg_id, ipc_context });
console.log('^ end of that thing');
return;
}

// todo validate all event.data stuff coming from the client (e.g. event.data.message, .msg, ...)
//-------------------------------------------------
Expand Down Expand Up @@ -846,25 +858,6 @@ window.addEventListener('message', async (event) => {
window.watchItems[event.data.item_uid].push(event.data.appInstanceID);
}
//--------------------------------------------------------
// launchApp
//--------------------------------------------------------
else if(event.data.msg === 'launchApp'){
// TODO: Determine if the app is allowed to launch child apps? We may want to limit this to prevent abuse.
// remember app for launch callback later
const child_instance_id = window.uuidv4();
window.child_launch_callbacks[child_instance_id] = {
parent_instance_id: event.data.appInstanceID,
launch_msg_id: msg_id,
};
// launch child app
launch_app({
name: event.data.app_name ?? app_name,
args: event.data.args ?? {},
parent_instance_id: event.data.appInstanceID,
uuid: child_instance_id,
});
}
//--------------------------------------------------------
// readAppDataFile
//--------------------------------------------------------
else if(event.data.msg === 'readAppDataFile' && event.data.path !== undefined){
Expand Down
4 changes: 4 additions & 0 deletions src/gui/src/initgui.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ import update_mouse_position from './helpers/update_mouse_position.js';
import { LaunchOnInitService } from './services/LaunchOnInitService.js';
import item_icon from './helpers/item_icon.js';
import { AntiCSRFService } from './services/AntiCSRFService.js';
import { IPCService } from './services/IPCService.js';
import { ExecService } from './services/ExecService.js';

const launch_services = async function (options) {
// === Services Data Structures ===
Expand Down Expand Up @@ -75,6 +77,8 @@ const launch_services = async function (options) {
globalThis.service_script_api_promise.resolve(service_script_api);

// === Builtin Services ===
register('ipc', new IPCService());
register('exec', new ExecService());
register('broadcast', new BroadcastService());
register('theme', new ThemeService());
register('process', new ProcessService());
Expand Down
26 changes: 26 additions & 0 deletions src/gui/src/services/ExecService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Service } from "../definitions.js";
import launch_app from "../helpers/launch_app.js";

export class ExecService extends Service {
async _init ({ services }) {
const svc_ipc = services.get('ipc');
svc_ipc.register_ipc_handler('launchApp', {
handler: this.launchApp.bind(this),
});
}

launchApp ({ app_name, args }, { ipc_context, msg_id } = {}) {
const child_instance_id = window.uuidv4();
window.child_launch_callbacks[child_instance_id] = {
parent_instance_id: event.data.appInstanceID,
launch_msg_id: msg_id,
};
// launch child app
launch_app({
name: app_name,
args: args ?? {},
parent_instance_id: ipc_context?.appInstanceId,
uuid: child_instance_id,
});
}
}
11 changes: 11 additions & 0 deletions src/gui/src/services/IPCService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { Service } from "../definitions.js";

export class IPCService extends Service {
async _init () {
//
}

register_ipc_handler (name, spec) {
window.ipc_handlers[name] = spec;
}
}

0 comments on commit 7249429

Please sign in to comment.