- Publishing & Subscribing
- Subscriptions
Subscriptions
Subscription patterns determine which events are delivered to a subscriber. Ironflow uses NATS-style wildcards for flexible pattern matching.
Wildcard Syntax
| Token | Description | Example |
|---|---|---|
* | Matches one segment. | system.run.*.created |
> | Matches all remaining segments. | events:> |
Connection Lifecycle
For real-time subscriptions, the SDK maintains a persistent connection (WebSocket or ConnectRPC stream).
import { ironflow } from "@ironflow/browser";
// 1. Connect to the streamawait ironflow.connect();
// 2. Monitor connection stateconst off = ironflow.onConnectionChange((state) => { console.log(`Connection state: ${state}`); // 'connected', 'reconnecting', etc.});
// 3. Disconnect when finishedironflow.disconnect();off();// Connect with a timeout contextctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)defer cancel()
if err := subClient.Connect(ctx); err != nil { log.Fatal(err)}defer subClient.Close()Pattern Helpers
Browser (Singleton):
import { ironflow } from "@ironflow/browser";await ironflow.subscribe("events:order.*", { onEvent: (e) => {} });Node.js (Instance):
import { createSubscriptionClient } from "@ironflow/node";
const subClient = createSubscriptionClient({ serverUrl: "http://localhost:9123", apiKey: "...",});await subClient.connect();const sub = await subClient.subscribe("system.run.>", { onEvent: (e) => {} });sub, err := subClient.Subscribe(ctx, ironflow.Patterns.AllRuns(), nil)Lifecycle & Storage
Regular subscriptions are ephemeral and stored in-memory on the server.
- Disconnect: If a client disconnects, the subscription is removed from the server.
- Reconnect: SDKs restore the pattern, filter, consumer group, metadata, acknowledgment, backpressure, and namespace options.
- Position: The start position depends on how you subscribed.
replay applies only to the initial subscription. Reapplying the same count on
every reconnect would repeat an arbitrary historical window. On reconnect:
- A consumer group resumes from its server-owned durable position.
- A fan-out subscription with
startAfterSequenceresumes after the last sequence delivered to the caller. Delivery remains at least once. - An unpositioned fan-out subscription starts at the current tail and may miss events published while it was offline.
Use startAfterSequence for positioned fan-out delivery. Do not combine it
with replay or a consumer group.
onEvent is not awaited, so advance the cursor only after your own work
completes. An async handler runs unsupervised: the next event can be
delivered before it settles, and a rejection becomes an unhandled rejection
rather than reaching onError. Serialize the handler yourself if the cursor
must never run ahead of the work it stands for.
await ironflow.subscribe("events:>", { startAfterSequence: lastDeliveredSequence, onEvent: (event) => console.log(event),});sub, err := subClient.Subscribe(ctx, "events:>", &ironflow.SubscribeOptions{ StartAfterSequence: &lastDeliveredSequence,})