Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,19 +133,22 @@ const { errors, warnings } = await window.ir.validate(ir);
console.log({ issues, errors, warnings });
```

### Runtime bridge & ArrowKey publisher smoke test
### Runtime bridge smoke test (ArrowKeyPub + ConsoleSub)

The preload now exposes `window.runtime` alongside the runner and IR bridges. With the dev app running:

```js
typeof window.runtime; // "object"
const id = window.runtime.create("ArrowKeyPub", { topic: "keys/arrows" });
window.runtime.start(id);
const pubId = window.runtime.create("ArrowKeyPub", { topic: "keys/arrows" });
const subId = window.runtime.create("ConsoleSub", { topic: "keys/arrows" });
window.runtime.start(pubId);
window.runtime.start(subId);
// Press arrow keys while the Electron window is focused:
// [publish] keys/arrows <- { key: "left", ts: ... }
// [node:ArrowKeyPub_1] pressed: left
window.runtime.stop(id);
window.runtime.list(); // ["ArrowKeyPub_1"]
// [node:ConsoleSub_1] received from ArrowKeyPub_1: {"key":"left","ts":...}
window.runtime.stop(subId);
window.runtime.stop(pubId);
window.runtime.list(); // ["ArrowKeyPub_1", "ConsoleSub_1"]
```

If `window.runtime` is missing, run `pnpm --filter ./apps/desktop-app build:main` again to regenerate the preload bridges.
Expand Down
42 changes: 42 additions & 0 deletions apps/desktop-app/src/renderer/runtime/nodes/ConsoleSub.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { NodeContext, NodeInstance, Publish } from "@bros2/runtime";

type ConsoleSubConfig = {
topic?: string;
format?: (payload: Publish["data"]) => string;
};

/** Subscribes to a topic and logs inbound messages via ctx.log. */
export class ConsoleSub implements NodeInstance {
id: string;
private ctx: NodeContext;
private topic: string;
private handler?: (evt: Publish) => void;
private format: (payload: Publish["data"]) => string;

constructor(ctx: NodeContext, config: ConsoleSubConfig = {}) {
this.id = ctx.id;
this.ctx = ctx;
this.topic = config.topic ?? "keys/arrows";
this.format =
config.format ??
((payload) => (typeof payload === "string" ? payload : JSON.stringify(payload)));
}

start() {
if (this.handler) return;

this.ctx.log(`subscribing to "${this.topic}"`);
this.handler = (evt: Publish) => {
const message = this.format(evt.data);
this.ctx.log(`received from ${evt.from}: ${message}`);
};
this.ctx.bus.on(this.topic, this.handler);
}

stop() {
if (!this.handler) return;
this.ctx.bus.off(this.topic, this.handler);
this.handler = undefined;
this.ctx.log(`stopped subscribing to "${this.topic}"`);
}
}
4 changes: 3 additions & 1 deletion apps/desktop-app/src/renderer/runtime/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@
import { Runtime } from "@bros2/runtime";
import type { NodeContext, NodeInstance } from "@bros2/runtime";
import { ArrowKeyPub } from "./nodes/ArrowKeyPub";
import { ConsoleSub } from "./nodes/ConsoleSub";

type Factory = (ctx: NodeContext, config?: any) => NodeInstance;

export const registry: Record<string, Factory> = {
ArrowKeyPub: (ctx, config) => new ArrowKeyPub(ctx, config),
ConsoleSub: (ctx, config) => new ConsoleSub(ctx, config),
};

export const runtime = new Runtime(registry);
export const runtime = new Runtime(registry);
4 changes: 3 additions & 1 deletion apps/desktop-app/src/shared/runtime/registry.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { Runtime, type NodeFactory } from "@bros2/runtime";
import { ArrowKeyPub } from "../../renderer/runtime/nodes/ArrowKeyPub";
import { ConsoleSub } from "../../renderer/runtime/nodes/ConsoleSub";

export const registry: Record<string, NodeFactory> = {
ArrowKeyPub: (ctx, config) => new ArrowKeyPub(ctx, config)
ArrowKeyPub: (ctx, config) => new ArrowKeyPub(ctx, config),
ConsoleSub: (ctx, config) => new ConsoleSub(ctx, config),
};

export const runtime = new Runtime(registry);