Skip to content

Commit

Permalink
Switch back to NodeJS plugin runtime
Browse files Browse the repository at this point in the history
  • Loading branch information
gschier committed Jan 20, 2025
1 parent 7f4ad43 commit 65299c7
Show file tree
Hide file tree
Showing 15 changed files with 263 additions and 298 deletions.
103 changes: 33 additions & 70 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"app-dev": "tauri dev --no-watch --config ./src-tauri/tauri-dev.conf.json",
"build": "npm run --workspaces --if-present build",
"bootstrap": "run-p bootstrap:* && npm run --workspaces --if-present bootstrap",
"bootstrap:vendor-deno": "node scripts/vendor-deno.cjs",
"bootstrap:vendor-node": "node scripts/vendor-node.cjs",
"bootstrap:vendor-plugins": "node scripts/vendor-plugins.cjs",
"bootstrap:vendor-protoc": "node scripts/vendor-protoc.cjs",
"lint": "npm run --workspaces --if-present lint",
Expand Down
4 changes: 3 additions & 1 deletion packages/plugin-runtime-types/src/bindings/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export type EditorLanguage = "text" | "javascript" | "json" | "html" | "xml" | "

export type EmptyPayload = {};

export type ErrorResponse = { error: string, };

export type ExportHttpRequestRequest = { httpRequest: HttpRequest, };

export type ExportHttpRequestResponse = { content: string, };
Expand Down Expand Up @@ -244,7 +246,7 @@ export type ImportResponse = { resources: ImportResources, };

export type InternalEvent = { id: string, pluginRefId: string, pluginName: string, replyId: string | null, payload: InternalEventPayload, windowContext: WindowContext, };

export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_request" } & EmptyPayload | { "type": "get_http_authentication_response" } & GetHttpAuthenticationResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload;
export type InternalEventPayload = { "type": "boot_request" } & BootRequest | { "type": "boot_response" } & BootResponse | { "type": "reload_request" } & EmptyPayload | { "type": "reload_response" } & EmptyPayload | { "type": "terminate_request" } | { "type": "terminate_response" } | { "type": "import_request" } & ImportRequest | { "type": "import_response" } & ImportResponse | { "type": "filter_request" } & FilterRequest | { "type": "filter_response" } & FilterResponse | { "type": "export_http_request_request" } & ExportHttpRequestRequest | { "type": "export_http_request_response" } & ExportHttpRequestResponse | { "type": "send_http_request_request" } & SendHttpRequestRequest | { "type": "send_http_request_response" } & SendHttpRequestResponse | { "type": "get_http_request_actions_request" } & EmptyPayload | { "type": "get_http_request_actions_response" } & GetHttpRequestActionsResponse | { "type": "call_http_request_action_request" } & CallHttpRequestActionRequest | { "type": "get_template_functions_request" } | { "type": "get_template_functions_response" } & GetTemplateFunctionsResponse | { "type": "call_template_function_request" } & CallTemplateFunctionRequest | { "type": "call_template_function_response" } & CallTemplateFunctionResponse | { "type": "get_http_authentication_request" } & EmptyPayload | { "type": "get_http_authentication_response" } & GetHttpAuthenticationResponse | { "type": "call_http_authentication_request" } & CallHttpAuthenticationRequest | { "type": "call_http_authentication_response" } & CallHttpAuthenticationResponse | { "type": "copy_text_request" } & CopyTextRequest | { "type": "render_http_request_request" } & RenderHttpRequestRequest | { "type": "render_http_request_response" } & RenderHttpRequestResponse | { "type": "template_render_request" } & TemplateRenderRequest | { "type": "template_render_response" } & TemplateRenderResponse | { "type": "show_toast_request" } & ShowToastRequest | { "type": "prompt_text_request" } & PromptTextRequest | { "type": "prompt_text_response" } & PromptTextResponse | { "type": "get_http_request_by_id_request" } & GetHttpRequestByIdRequest | { "type": "get_http_request_by_id_response" } & GetHttpRequestByIdResponse | { "type": "find_http_responses_request" } & FindHttpResponsesRequest | { "type": "find_http_responses_response" } & FindHttpResponsesResponse | { "type": "empty_response" } & EmptyPayload | { "type": "error_response" } & ErrorResponse;

export type PromptTextRequest = { id: string, title: string, label: string, description?: string, defaultValue?: string, placeholder?: string,
/**
Expand Down
10 changes: 9 additions & 1 deletion packages/plugin-runtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,14 @@
"bootstrap": "npm run build",
"build": "run-p build:*",
"build:main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.cjs",
"build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.worker.cjs"
"build:worker": "esbuild src/index.worker.ts --bundle --platform=node --outfile=../../src-tauri/vendored/plugin-runtime/index.worker.cjs",
"build:__main": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/target/debug/vendored/plugin-runtime/index.cjs",
"build:__worker": "esbuild src/index.ts --bundle --platform=node --outfile=../../src-tauri/target/debug/vendored/plugin-runtime/index.worker.cjs"
},
"dependencies": {
"ws": "^8.18.0"
},
"devDependencies": {
"@types/ws": "^8.5.13"
}
}
13 changes: 5 additions & 8 deletions packages/plugin-runtime/src/PluginHandle.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { BootRequest, InternalEvent } from '@yaakapp/api';
import path from 'node:path';
import { Worker } from 'node:worker_threads';
import type { EventChannel } from './EventChannel';
import type { PluginWorkerData } from './index.worker';
import path from 'node:path';

export class PluginHandle {
#worker: Worker;
Expand All @@ -24,19 +24,16 @@ export class PluginHandle {
}

#createWorker(): Worker {
const workerPath = path.join(__dirname, './index.worker.cjs');
const workerPath = process.env.YAAK_WORKER_PATH ?? path.join(__dirname, 'index.worker.cjs');
const workerData: PluginWorkerData = {
pluginRefId: this.pluginRefId,
bootRequest: this.bootRequest,
};
const worker = new Worker(workerPath, {
workerData,
deno: {
permissions: 'none',
},
});

worker.on('message', (e: InternalEvent) => this.events.emit(e));
worker.on('message', (e) => this.events.emit(e));
worker.on('error', this.#handleError.bind(this));
worker.on('exit', this.#handleExit.bind(this));

Expand All @@ -45,11 +42,11 @@ export class PluginHandle {
return worker;
}

#handleError(err: Error) {
async #handleError(err: Error) {
console.error('Plugin errored', this.bootRequest.dir, err);
}

#handleExit(code: number) {
async #handleExit(code: number) {
if (code === 0) {
console.log('Plugin exited successfully', this.bootRequest.dir);
} else {
Expand Down
24 changes: 10 additions & 14 deletions packages/plugin-runtime/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,34 @@
import type { InternalEvent } from '@yaakapp/api';
import { EventChannel } from './EventChannel';
import { PluginHandle } from './PluginHandle';
import WebSocket from 'ws';

const port = process.env.PORT || '50051';
const port = process.env.YAAK_PLUGIN_SERVER_PORT || '9442';

const events = new EventChannel();
const plugins: Record<string, PluginHandle> = {};

const ws = new WebSocket(`ws://localhost:${port}`);
ws.addEventListener('message', async (e) => {

ws.on('message', async (e: Buffer) => {
try {
await handleIncoming(e);
await handleIncoming(e.toString());
} catch (err) {
console.log('Failed to handle incoming plugin event', err);
}
});
ws.addEventListener('open', () => {
console.log('Plugin runtime connected to websocket');
});
ws.addEventListener('error', (e) => {
console.error('Plugin runtime websocket error', e);
});
ws.addEventListener('close', () => {
console.log('Plugin runtime websocket closed');
});
ws.on('open', (e) => console.log('Plugin runtime connected to websocket', e));
ws.on('error', (e) => console.error('Plugin runtime websocket error', e));
ws.on('close', (e) => console.log('Plugin runtime websocket closed', e));

// Listen for incoming events from plugins
events.listen((e) => {
const eventStr = JSON.stringify(e);
ws.send(eventStr);
});

async function handleIncoming(msg: MessageEvent) {
const pluginEvent: InternalEvent = JSON.parse(msg.data);
async function handleIncoming(msg: string) {
const pluginEvent: InternalEvent = JSON.parse(msg);
// Handle special event to bootstrap plugin
if (pluginEvent.payload.type === 'boot_request') {
const plugin = new PluginHandle(pluginEvent.pluginRefId, pluginEvent.payload, events);
Expand Down
Loading

0 comments on commit 65299c7

Please sign in to comment.