rdesktop^2
filip mertens 2 years ago
parent 171518f49a
commit 93973004e9
  1. 8
      apps/1test/src/electron/engine.ts
  2. 4
      apps/1test/src/electron/fsPlugin.ts
  3. 4
      apps/1test/src/electron/gitPlugin.ts
  4. 6
      apps/1test/src/electron/lib/electronPluginClient.ts
  5. 2
      apps/1test/src/global.d.ts
  6. 5
      apps/1test/src/preload.ts
  7. 19
      apps/1test/src/remix/fsPlugin.ts
  8. 17
      apps/1test/src/remix/gitPlugin.ts
  9. 46
      apps/1test/src/remix/lib/electronPluginConnector.ts
  10. 36
      apps/1test/src/remix/lib/fsPlugin.ts
  11. 36
      apps/1test/src/remix/lib/gitPlugin.ts
  12. 30
      apps/1test/src/renderer.ts

@ -10,9 +10,11 @@ const gitPlugin = new GitPlugin()
engine.register(appManager) engine.register(appManager)
engine.register(fsPlugin) engine.register(fsPlugin)
engine.register(gitPlugin) engine.register(gitPlugin)
//appManager.activatePlugin('fs')
ipcMain.on('engine:activatePlugin', (event, arg) => { ipcMain.handle('engine:activatePlugin', async (event, arg) => {
console.log('engine:activatePlugin', arg) console.log('engine:activatePlugin', arg)
appManager.activatePlugin(arg) if(await appManager.isActive(arg)){
return true
}
return await appManager.activatePlugin(arg)
}) })

@ -1,10 +1,9 @@
import { PluginClient } from "@remixproject/plugin"; import { PluginClient } from "@remixproject/plugin";
import { createClient } from "./electronPluginClient" import { createClient } from "./lib/electronPluginClient"
import { Engine, PluginManager, Plugin } from '@remixproject/engine'; import { Engine, PluginManager, Plugin } from '@remixproject/engine';
import fs from 'fs/promises' import fs from 'fs/promises'
import { Stats } from "fs"; import { Stats } from "fs";
const profile = { const profile = {
displayName: 'fs', displayName: 'fs',
name: 'fs', name: 'fs',
@ -21,6 +20,7 @@ export class FSPlugin extends Plugin {
console.log('fsPlugin onActivation') console.log('fsPlugin onActivation')
this.client = new FSPluginClient() this.client = new FSPluginClient()
} }
} }
class FSPluginClient extends PluginClient { class FSPluginClient extends PluginClient {

@ -2,7 +2,7 @@ import { Plugin } from "@remixproject/engine";
import { PluginClient } from "@remixproject/plugin"; import { PluginClient } from "@remixproject/plugin";
import { Profile } from "@remixproject/plugin-utils"; import { Profile } from "@remixproject/plugin-utils";
import { spawn } from "child_process"; import { spawn } from "child_process";
import { createClient } from "./electronPluginClient"; import { createClient } from "./lib/electronPluginClient";
const profile: Profile = { const profile: Profile = {
name: 'git', name: 'git',
@ -17,9 +17,9 @@ export class GitPlugin extends Plugin {
} }
onActivation(): void { onActivation(): void {
console.log('GitPlugin onActivation')
this.client = new GitPluginClient() this.client = new GitPluginClient()
} }
} }
class GitPluginClient extends PluginClient { class GitPluginClient extends PluginClient {

@ -2,26 +2,22 @@ import { ClientConnector, connectClient, applyApi, Client, PluginClient } from '
import type { Message, Api, ApiMap } from '@remixproject/plugin-utils' import type { Message, Api, ApiMap } from '@remixproject/plugin-utils'
import { IRemixApi } from '@remixproject/plugin-api' import { IRemixApi } from '@remixproject/plugin-api'
import { ipcMain } from 'electron' import { ipcMain } from 'electron'
import { mainWindow } from '..' import { mainWindow } from '../..'
export class ElectronPluginClientConnector implements ClientConnector { export class ElectronPluginClientConnector implements ClientConnector {
constructor(public IPCName: string) { constructor(public IPCName: string) {
console.log('ElectronPluginClientConnector constructor', IPCName)
} }
/** Send a message to the engine */ /** Send a message to the engine */
send(message: Partial<Message>) { send(message: Partial<Message>) {
console.log('ElectronPluginConnector send', message)
mainWindow.webContents.send(this.IPCName + ':send', message) mainWindow.webContents.send(this.IPCName + ':send', message)
} }
/** Listen to message from the engine */ /** Listen to message from the engine */
on(cb: (message: Partial<Message>) => void) { on(cb: (message: Partial<Message>) => void) {
console.log('ElectronPluginConnector on', cb)
ipcMain.on(this.IPCName + ':on', (event, message) => { ipcMain.on(this.IPCName + ':on', (event, message) => {
console.log('ElectronPluginConnector on message received', message)
cb(message) cb(message)
}) })
} }

@ -1,5 +1,5 @@
export interface IElectronAPI { export interface IElectronAPI {
activatePlugin: (name: string) => void activatePlugin: (name: string) => Promise<boolean>
receiveFromFS: (cb: any) => void receiveFromFS: (cb: any) => void
sendToFS: (message: Partial<Message>) => void sendToFS: (message: Partial<Message>) => void
receiveFromGit: (cb: any) => void receiveFromGit: (cb: any) => void

@ -6,11 +6,10 @@ console.log('preload.ts')
contextBridge.exposeInMainWorld('api', { contextBridge.exposeInMainWorld('api', {
activatePlugin: (name: string) => { activatePlugin: (name: string) => {
console.log('activatePlugin', name) return ipcRenderer.invoke('engine:activatePlugin', name)
ipcRenderer.send('engine:activatePlugin', name)
}, },
receiveFromFS: (cb:any) => ipcRenderer.on('fs:send', cb), receiveFromFS: (cb:any) => ipcRenderer.on('fs:send', cb),
sendToFS: (message: Partial<Message>) => ipcRenderer.send('fs:on', message), sendToFS: (message: Partial<Message>) => ipcRenderer.send('fs:on', message),
receiveFromGit: (cb:any) => ipcRenderer.on('git:send', cb), receiveFromGit: (cb:any) => ipcRenderer.on('git:send', cb),
sendToGit: (message: Partial<Message>) => ipcRenderer.send('git:on', message) sendToGit: (message: Partial<Message>) => ipcRenderer.send('git:on', message)
}) })

@ -0,0 +1,19 @@
import { Engine, PluginManager, Plugin, PluginConnector } from '@remixproject/engine';
import { Message, Profile } from '@remixproject/plugin-utils';
import { ElectronPluginConnector } from './lib/electronPluginConnector';
export class fsPlugin extends ElectronPluginConnector {
constructor(){
super({
displayName: 'fs',
name: 'fs',
description: 'fs',
}, {
sendAPI: window.api.sendToFS,
receiveAPI: window.api.receiveFromFS
})
this.methods = ['readdir', 'readFile', 'writeFile', 'mkdir', 'rmdir', 'unlink', 'rename', 'stat', 'exists']
}
}

@ -0,0 +1,17 @@
import { Engine, PluginManager, Plugin, PluginConnector } from '@remixproject/engine';
import { Message, Profile } from '@remixproject/plugin-utils';
import { ElectronPluginConnector } from './lib/electronPluginConnector';
export class gitPlugin extends ElectronPluginConnector {
constructor(){
super({
displayName: 'git',
name: 'git',
description: 'git',
},{
sendAPI: window.api.sendToGit,
receiveAPI: window.api.receiveFromGit
})
this.methods = ['log', 'status', 'add', 'commit', 'push', 'pull', 'clone', 'checkout', 'branch', 'merge', 'reset', 'revert', 'diff', 'stash', 'apply', 'cherryPick', 'rebase', 'tag', 'fetch', 'remote', 'config', 'show', 'init', 'help', 'version']
}
}

@ -2,8 +2,9 @@ import type { ExternalProfile, Profile, Message, PluginOptions } from '@remixpro
import { Plugin } from '@remixproject/engine'; import { Plugin } from '@remixproject/engine';
export interface PluginConnectorOptions extends PluginOptions { export interface ElectronPluginConnectorOptions extends PluginOptions {
engine?:string sendAPI?: (message: Partial<Message>) => void
receiveAPI?: (cb: (event:any, message: Partial<Message>) => void) => void
} }
@ -11,24 +12,40 @@ export abstract class ElectronPluginConnector extends Plugin {
protected loaded: boolean protected loaded: boolean
protected id = 0 protected id = 0
protected pendingRequest: Record<number, (result: any, error: Error | string) => void> = {} protected pendingRequest: Record<number, (result: any, error: Error | string) => void> = {}
protected options: PluginConnectorOptions protected options: ElectronPluginConnectorOptions
profile: Profile profile: Profile
constructor(profile: Profile) { constructor(profile: Profile, options: ElectronPluginConnectorOptions = {}) {
super(profile) super(profile)
this.loaded = false
if(!options.sendAPI || !options.receiveAPI) throw new Error('ElectronPluginConnector requires sendAPI and receiveAPI')
this.options = options
options.receiveAPI((event: any, message: any) => {
this.getMessage(message)
})
} }
/** /**
* Send a message to the external plugin * Send a message to the external plugin
* @param message the message passed to the plugin * @param message the message passed to the plugin
*/ */
protected abstract send(message: Partial<Message>): void protected send(message: Partial<Message>): void {
if(this.loaded)
this.options.sendAPI(message)
}
/** /**
* Open connection with the plugin * Open connection with the plugin
* @param url The transformed url the plugin should connect to * @param name The name of the plugin should connect to
*/ */
protected abstract connect(name: string): any | Promise<any> protected async connect(name: string) {
if(await window.api.activatePlugin(name) && !this.loaded){
this.handshake()
}
}
/** Close connection with the plugin */ /** Close connection with the plugin */
protected abstract disconnect(): any | Promise<any> protected disconnect(): any | Promise<any> {
}
async activate() { async activate() {
await this.connect(this.profile.name) await this.connect(this.profile.name)
@ -42,7 +59,7 @@ export abstract class ElectronPluginConnector extends Plugin {
} }
/** Set options for an external plugin */ /** Set options for an external plugin */
setOptions(options: Partial<PluginConnectorOptions> = {}) { setOptions(options: Partial<ElectronPluginConnectorOptions> = {}) {
super.setOptions(options) super.setOptions(options)
} }
@ -61,27 +78,23 @@ export abstract class ElectronPluginConnector extends Plugin {
/** Perform handshake with the client if not loaded yet */ /** Perform handshake with the client if not loaded yet */
protected async handshake() { protected async handshake() {
console.log('ElectronPluginConnector handshake', this.loaded)
if (!this.loaded) { if (!this.loaded) {
this.loaded = true this.loaded = true
let methods: string[]; let methods: string[];
try { try {
console.log('ElectronPluginConnector handshake calling plugin method') methods = await this.callPluginMethod('handshake', [this.profile.name])
methods = await this.callPluginMethod('handshake', [this.profile.name, this.options?.engine])
console.log('ElectronPluginConnector handshake methods', methods)
} catch (err) { } catch (err) {
console.error('ElectronPluginConnector handshake error', err)
this.loaded = false this.loaded = false
throw err; throw err;
} }
this.emit('loaded', this.name)
if (methods) { if (methods) {
this.profile.methods = methods this.profile.methods = methods
this.call('manager', 'updateProfile', this.profile) this.call('manager', 'updateProfile', this.profile)
} }
} else { } else {
// If there is a broken connection we want send back the handshake to the plugin client // If there is a broken connection we want send back the handshake to the plugin client
console.log('ElectronPluginConnector handshake already loaded') return this.callPluginMethod('handshake', [this.profile.name])
return this.callPluginMethod('handshake', [this.profile.name, this.options?.engine])
} }
} }
@ -90,7 +103,6 @@ export abstract class ElectronPluginConnector extends Plugin {
* @param message The message sent by the client * @param message The message sent by the client
*/ */
protected async getMessage(message: Message) { protected async getMessage(message: Message) {
console.log('ElectronPluginConnector getMessage', message)
// Check for handshake request from the client // Check for handshake request from the client
if (message.action === 'request' && message.key === 'handshake') { if (message.action === 'request' && message.key === 'handshake') {
return this.handshake() return this.handshake()

@ -1,36 +0,0 @@
import { Engine, PluginManager, Plugin, PluginConnector } from '@remixproject/engine';
import { Message, Profile } from '@remixproject/plugin-utils';
import { ElectronPluginConnector } from './electronPluginConnector';
export class fsPlugin extends ElectronPluginConnector {
constructor(){
super({
displayName: 'fs',
name: 'fs',
description: 'fs',
})
}
onActivation(): void {
console.log('fsPlugin onActivation')
//window.api.activatePlugin('fs')
}
protected connect(name: string) {
console.log('fsPlugin connect', name)
window.api.activatePlugin(name)
window.api.receiveFromFS((event: any, message: any) => {
console.log('fsPlugin fsClientSend message received', message)
this.getMessage(message)
})
}
protected send(message: Partial<Message>): void {
console.log('fsPlugin send', message)
window.api.sendToFS(message)
}
protected disconnect() {
console.log('fsPlugin disconnect')
}
}

@ -1,36 +0,0 @@
import { Engine, PluginManager, Plugin, PluginConnector } from '@remixproject/engine';
import { Message, Profile } from '@remixproject/plugin-utils';
import { ElectronPluginConnector } from './electronPluginConnector';
export class gitPlugin extends ElectronPluginConnector {
constructor(){
super({
displayName: 'git',
name: 'git',
description: 'git',
})
}
onActivation(): void {
console.log('git onActivation')
//window.api.activatePlugin('fs')
}
protected connect(name: string) {
console.log('git connect', name)
window.api.activatePlugin(name)
window.api.receiveFromGit((event: any, message: any) => {
console.log('git fsClientSend message received', message)
this.getMessage(message)
})
}
protected send(message: Partial<Message>): void {
console.log('git send', message)
window.api.sendToGit(message)
}
protected disconnect() {
console.log('git disconnect')
}
}

@ -1,13 +1,26 @@
import { Engine, PluginManager, Plugin, PluginConnector } from '@remixproject/engine'; import { Engine, PluginManager } from '@remixproject/engine';
import { Profile } from '@remixproject/plugin-utils'; import { fsPlugin } from './remix/fsPlugin';
import { fsPlugin } from './remix/lib/fsPlugin'; import { gitPlugin } from './remix/gitPlugin';
import { gitPlugin } from './remix/lib/gitPlugin';
class MyAppManager extends PluginManager {
onActivation(): void {
this.on('fs', 'loaded', async () => {
const files = await this.call('fs', 'readdir', './src')
console.log('files', files)
})
this.on('git', 'loaded', async () => {
const log = await this.call('git', 'log', './src')
console.log('log', log)
})
}
}
const engine = new Engine() const engine = new Engine()
const appManager = new PluginManager() const appManager = new MyAppManager()
const fs = new fsPlugin() const fs = new fsPlugin()
const git = new gitPlugin() const git = new gitPlugin()
engine.register(appManager) engine.register(appManager)
@ -16,10 +29,9 @@ engine.register(git)
appManager.activatePlugin('fs') appManager.activatePlugin('fs')
appManager.activatePlugin('git') appManager.activatePlugin('git')
setTimeout(async () => { setTimeout(async () => {
const files = await appManager.call('fs', 'readdir', './') const files = await appManager.call('fs', 'readdir', './src')
console.log('files', files) console.log('files', files)
const log = await appManager.call('git', 'log', './') }, 1000)
console.log('log', log)
}, 5000)

Loading…
Cancel
Save