Skip to content

Transport client

The ./bridge subpath is the client half of the Python host’s dispatcher. It speaks envelopes over an injected transport, so a test can script a failure instead of reproducing one inside a running QGIS.

import { BridgeClient } from "@archont561/qgis-sdk"; // or "@archont561/qgis-sdk/bridge"
const client = new BridgeClient({
send: (message) => channel.send(JSON.stringify(message)),
subscribe: (listener) => {
const handler = (text: string): void => listener(JSON.parse(text));
channel.onmessage = handler;
return () => {
channel.onmessage = null;
};
},
});
const layer = await client.invoke("layers.info", { layer_id: "sites" });

Calls and subscriptions have explicit outcomes and lifecycle guarantees.

A reply that names no pending call is counted, never delivered to whichever call happens to be waiting.

A local abort, a timeout and a closed client are three errors, and a timeout says the outcome is unknown. Nothing is retried automatically.

client.subscribe(operation, payload, { onEvent, onTerminal }) resolves with a handle once the host acknowledges it. Frames must arrive with a seq that continues the sequence; anything else ends the subscription with a gap terminal instead of delivering out of order. close() notifies the host once, and closing an already-ended subscription sends nothing.

const subscription = await client.subscribe("project.changes", {}, {
onEvent: (event) => render(event.payload),
onTerminal: (terminal) => console.info("stream ended:", terminal.kind),
});
subscription.close();

Protocol version 1 is unchanged by subscriptions: a client that never subscribes still sees nothing but the replies to its own calls.