Files
orca/src/main/plugins/plugin-event-bus.ts
T
Neil 1b2be7dd08 feat(plugins): Orca plugin system — kernel, content packs, panels, workers, marketplace v0 (experimental)
Adds Orca's experimental plugin system behind a settings flag: a
supervised kernel, declarative content packs (VM recipes, commands and
keybindings, language packs), sandboxed iframe panels, forked worker
hosts, and a Git-backed marketplace v0 with consent, provenance and
kill-list enforcement.

Theme, icon-theme and terminal-theme contributions are deferred to a
follow-up pass.
2026-07-27 00:27:26 -07:00

43 lines
1.6 KiB
TypeScript

import { PLUGIN_EVENT_PAYLOAD_SCHEMAS } from '../../shared/plugins/plugin-events'
import type { PluginEventName } from '../../shared/plugins/plugin-manifest'
/**
* Server-side event filtering: plugins receive only events they subscribed
* to (manifest `contributes.events` or a runtime `events.subscribe` call) —
* never a firehose. Manifest subscriptions are durable activation triggers;
* dynamic subscriptions live only as long as the worker that made them.
*/
export class PluginEventBus {
private readonly dynamicSubscriptions = new Map<string, Set<PluginEventName>>()
subscribe(pluginKey: string, events: PluginEventName[]): PluginEventName[] {
const existing = this.dynamicSubscriptions.get(pluginKey) ?? new Set<PluginEventName>()
for (const event of events) {
existing.add(event)
}
this.dynamicSubscriptions.set(pluginKey, existing)
return [...existing]
}
isDynamicallySubscribed(pluginKey: string, event: PluginEventName): boolean {
return this.dynamicSubscriptions.get(pluginKey)?.has(event) ?? false
}
/** Dynamic subscriptions die with the worker that registered them. */
clear(pluginKey: string): void {
this.dynamicSubscriptions.delete(pluginKey)
}
/** Validates and bounds an event payload before it reaches any plugin. */
projectPayload(
event: PluginEventName,
payload: unknown
): { ok: true; payload: unknown } | { ok: false; error: string } {
const parsed = PLUGIN_EVENT_PAYLOAD_SCHEMAS[event].safeParse(payload)
return parsed.success
? { ok: true, payload: parsed.data }
: { ok: false, error: `malformed ${event} payload` }
}
}