mirror of
https://github.com/HeyPuter/puter
synced 2024-11-14 22:06:00 +00:00
feat: add connectToInstance method to puter.ui
This commit is contained in:
parent
e2cb6194bb
commit
62634b0afe
@ -23,6 +23,10 @@ class WispClient {
|
||||
}
|
||||
}
|
||||
|
||||
puter.ui.on('connection', event => {
|
||||
console.log('emulator got connection event', event);
|
||||
});
|
||||
|
||||
window.onload = async function()
|
||||
{
|
||||
const resp = await fetch(
|
||||
|
@ -85,6 +85,10 @@ export class Process extends AdvancedBase{
|
||||
this._signal(sig);
|
||||
}
|
||||
|
||||
handle_connection (other_process) {
|
||||
throw new Error('Not implemented');
|
||||
}
|
||||
|
||||
get type () {
|
||||
const _to_type_name = (name) => {
|
||||
return name.replace(/Process$/, '').toLowerCase();
|
||||
@ -139,6 +143,15 @@ export class PortalProcess extends Process {
|
||||
const target = this.references.iframe.contentWindow;
|
||||
// NEXT: ...
|
||||
}
|
||||
|
||||
handle_connection (other_process, args) {
|
||||
const target = this.references.iframe.contentWindow;
|
||||
target.postMessage({
|
||||
msg: 'connection',
|
||||
appInstanceID: other_process.uuid,
|
||||
args,
|
||||
});
|
||||
}
|
||||
};
|
||||
export class PseudoProcess extends Process {
|
||||
_construct () { this.type_ = 'ui' }
|
||||
|
@ -11,6 +11,9 @@ export class ExecService extends Service {
|
||||
svc_ipc.register_ipc_handler('launchApp', {
|
||||
handler: this.launchApp.bind(this),
|
||||
});
|
||||
svc_ipc.register_ipc_handler('connectToInstance', {
|
||||
handler: this.connectToInstance.bind(this),
|
||||
});
|
||||
}
|
||||
|
||||
// This method is exposed to apps via IPCService.
|
||||
@ -70,4 +73,34 @@ export class ExecService extends Service {
|
||||
usesSDK: true,
|
||||
};
|
||||
}
|
||||
|
||||
async connectToInstance ({ app_name, args }, { ipc_context, msg_id } = {}) {
|
||||
const caller_process = ipc_context?.caller?.process;
|
||||
if ( ! caller_process ) {
|
||||
throw new Error('Caller process not found');
|
||||
}
|
||||
|
||||
console.log(
|
||||
caller_process.name,
|
||||
app_name,
|
||||
);
|
||||
// TODO: permissions integration; for now it's hardcoded
|
||||
if ( caller_process.name !== 'phoenix' ) {
|
||||
throw new Error('Connection not allowed.');
|
||||
}
|
||||
if ( app_name !== 'test-emu' ) {
|
||||
throw new Error('Connection not allowed.');
|
||||
}
|
||||
|
||||
const svc_process = this.services.get('process');
|
||||
const options = svc_process.select_by_name(app_name);
|
||||
const process = options[0];
|
||||
|
||||
await process.handle_connection(caller_process, args);
|
||||
|
||||
return {
|
||||
appInstanceID: process.uuid,
|
||||
response,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,16 @@ export class ProcessService extends Service {
|
||||
return this.uuid_to_treelist.get(uuid);
|
||||
}
|
||||
|
||||
select_by_name (name) {
|
||||
const list = [];
|
||||
for ( const process of this.processes ) {
|
||||
if ( process.name === name ) {
|
||||
list.push(process);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
register (process) {
|
||||
this.register_(process);
|
||||
this.attach_to_parent_(process);
|
||||
|
@ -35,6 +35,7 @@ import { MultiWriter } from '../ansi-shell/ioutil/MultiWriter.js';
|
||||
import { CompositeCommandProvider } from './providers/CompositeCommandProvider.js';
|
||||
import { ScriptCommandProvider } from './providers/ScriptCommandProvider.js';
|
||||
import { PuterAppCommandProvider } from './providers/PuterAppCommandProvider.js';
|
||||
import { EmuCommandProvider } from './providers/EmuCommandProvider.js';
|
||||
|
||||
const argparser_registry = {
|
||||
[SimpleArgParser.name]: SimpleArgParser
|
||||
@ -92,6 +93,7 @@ export const launchPuterShell = async (ctx) => {
|
||||
// PuterAppCommandProvider is only usable on Puter
|
||||
...(ctx.platform.name === 'puter' ? [new PuterAppCommandProvider()] : []),
|
||||
new ScriptCommandProvider(),
|
||||
new EmuCommandProvider(),
|
||||
]);
|
||||
|
||||
ctx = ctx.sub({
|
||||
|
46
src/phoenix/src/puter-shell/providers/EmuCommandProvider.js
Normal file
46
src/phoenix/src/puter-shell/providers/EmuCommandProvider.js
Normal file
@ -0,0 +1,46 @@
|
||||
import { Exit } from "../coreutils/coreutil_lib/exit";
|
||||
|
||||
export class EmuCommandProvider {
|
||||
static AVAILABLE = [
|
||||
'bash',
|
||||
'htop',
|
||||
];
|
||||
|
||||
static EMU_APP_NAME = 'test-emu';
|
||||
|
||||
constructor () {
|
||||
this.available = this.constructor.AVAILABLE;
|
||||
this.emulator = null;
|
||||
}
|
||||
|
||||
async aquire_emulator () {
|
||||
if ( this.emulator ) return this.emulator;
|
||||
|
||||
// FUTURE: when we have a way to query instances
|
||||
// without exposing the real instance id
|
||||
/*
|
||||
const instances = await puter.ui.queryInstances();
|
||||
if ( instances.length < 0 ) {
|
||||
return;
|
||||
}
|
||||
const instance = instances[0];
|
||||
*/
|
||||
|
||||
const conn = await puter.ui.connectToInstance(this.constructor.EMU_APP_NAME);
|
||||
return this.emulator = conn;
|
||||
}
|
||||
|
||||
async lookup (id, { ctx }) {
|
||||
if ( ! this.available.includes(id) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const emu = await this.aquire_emulator();
|
||||
if ( ! emu ) {
|
||||
ctx.externs.out.write('No emulator available.\n');
|
||||
return new Exit(1);
|
||||
}
|
||||
|
||||
ctx.externs.out.write(`Launching ${id} in emulator ${emu.appInstanceID}\n`);
|
||||
}
|
||||
}
|
@ -203,6 +203,7 @@ class UI extends EventListener {
|
||||
const eventNames = [
|
||||
'localeChanged',
|
||||
'themeChanged',
|
||||
'connection',
|
||||
];
|
||||
super(eventNames);
|
||||
this.#eventNames = eventNames;
|
||||
@ -460,6 +461,15 @@ class UI extends EventListener {
|
||||
this.emit(name, data);
|
||||
this.#lastBroadcastValue.set(name, data);
|
||||
}
|
||||
else if ( e.data.msg === 'connection' ) {
|
||||
const conn = AppConnection.from(e.data, {
|
||||
appInstanceID: this.appInstanceID,
|
||||
messageTarget: window.parent,
|
||||
});
|
||||
this.emit('connection', {
|
||||
conn
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// We need to send the mouse position to the host environment
|
||||
@ -951,6 +961,20 @@ class UI extends EventListener {
|
||||
});
|
||||
}
|
||||
|
||||
connectToInstance = async function connectToInstance (app_name) {
|
||||
const app_info = await this.#ipc_stub({
|
||||
method: 'connectToInstance',
|
||||
parameters: {
|
||||
app_name,
|
||||
}
|
||||
});
|
||||
|
||||
return AppConnection.from(app_info, {
|
||||
appInstanceID: this.appInstanceID,
|
||||
messageTarget: this.messageTarget,
|
||||
});
|
||||
}
|
||||
|
||||
parentApp() {
|
||||
return this.#parentAppConnection;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user