mirror of
https://github.com/HeyPuter/puter
synced 2024-11-15 06:15:47 +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()
|
window.onload = async function()
|
||||||
{
|
{
|
||||||
const resp = await fetch(
|
const resp = await fetch(
|
||||||
|
@ -85,6 +85,10 @@ export class Process extends AdvancedBase{
|
|||||||
this._signal(sig);
|
this._signal(sig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handle_connection (other_process) {
|
||||||
|
throw new Error('Not implemented');
|
||||||
|
}
|
||||||
|
|
||||||
get type () {
|
get type () {
|
||||||
const _to_type_name = (name) => {
|
const _to_type_name = (name) => {
|
||||||
return name.replace(/Process$/, '').toLowerCase();
|
return name.replace(/Process$/, '').toLowerCase();
|
||||||
@ -139,6 +143,15 @@ export class PortalProcess extends Process {
|
|||||||
const target = this.references.iframe.contentWindow;
|
const target = this.references.iframe.contentWindow;
|
||||||
// NEXT: ...
|
// 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 {
|
export class PseudoProcess extends Process {
|
||||||
_construct () { this.type_ = 'ui' }
|
_construct () { this.type_ = 'ui' }
|
||||||
|
@ -11,6 +11,9 @@ export class ExecService extends Service {
|
|||||||
svc_ipc.register_ipc_handler('launchApp', {
|
svc_ipc.register_ipc_handler('launchApp', {
|
||||||
handler: this.launchApp.bind(this),
|
handler: this.launchApp.bind(this),
|
||||||
});
|
});
|
||||||
|
svc_ipc.register_ipc_handler('connectToInstance', {
|
||||||
|
handler: this.connectToInstance.bind(this),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method is exposed to apps via IPCService.
|
// This method is exposed to apps via IPCService.
|
||||||
@ -70,4 +73,34 @@ export class ExecService extends Service {
|
|||||||
usesSDK: true,
|
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);
|
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) {
|
register (process) {
|
||||||
this.register_(process);
|
this.register_(process);
|
||||||
this.attach_to_parent_(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 { CompositeCommandProvider } from './providers/CompositeCommandProvider.js';
|
||||||
import { ScriptCommandProvider } from './providers/ScriptCommandProvider.js';
|
import { ScriptCommandProvider } from './providers/ScriptCommandProvider.js';
|
||||||
import { PuterAppCommandProvider } from './providers/PuterAppCommandProvider.js';
|
import { PuterAppCommandProvider } from './providers/PuterAppCommandProvider.js';
|
||||||
|
import { EmuCommandProvider } from './providers/EmuCommandProvider.js';
|
||||||
|
|
||||||
const argparser_registry = {
|
const argparser_registry = {
|
||||||
[SimpleArgParser.name]: SimpleArgParser
|
[SimpleArgParser.name]: SimpleArgParser
|
||||||
@ -92,6 +93,7 @@ export const launchPuterShell = async (ctx) => {
|
|||||||
// PuterAppCommandProvider is only usable on Puter
|
// PuterAppCommandProvider is only usable on Puter
|
||||||
...(ctx.platform.name === 'puter' ? [new PuterAppCommandProvider()] : []),
|
...(ctx.platform.name === 'puter' ? [new PuterAppCommandProvider()] : []),
|
||||||
new ScriptCommandProvider(),
|
new ScriptCommandProvider(),
|
||||||
|
new EmuCommandProvider(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
ctx = ctx.sub({
|
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 = [
|
const eventNames = [
|
||||||
'localeChanged',
|
'localeChanged',
|
||||||
'themeChanged',
|
'themeChanged',
|
||||||
|
'connection',
|
||||||
];
|
];
|
||||||
super(eventNames);
|
super(eventNames);
|
||||||
this.#eventNames = eventNames;
|
this.#eventNames = eventNames;
|
||||||
@ -460,6 +461,15 @@ class UI extends EventListener {
|
|||||||
this.emit(name, data);
|
this.emit(name, data);
|
||||||
this.#lastBroadcastValue.set(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
|
// 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() {
|
parentApp() {
|
||||||
return this.#parentAppConnection;
|
return this.#parentAppConnection;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user