Event Versioning
As your system evolves, event schemas change. Synkro supports versioned events so that handlers for older versions continue to receive events alongside handlers for specific versions.
Naming convention
Versioned events follow the pattern base:event:vN:
user:created ← base (unversioned)user:created:v1 ← version 1user:created:v2 ← version 2Fanout behavior
When you publish a versioned event, Synkro delivers the message to both the versioned channel and the base channel:
await synkro.publish("user:created:v2", { id: "u1", name: "Alice", role: "admin" });This triggers:
- All handlers registered for
user:created:v2. - All handlers registered for
user:created(the base channel).
This lets you register a catch-all handler on the base event while also having version-specific handlers:
// Receives ALL versionssynkro.on("user:created", async (ctx) => { console.log("User event (any version):", ctx.payload);});
// Receives only v2synkro.on("user:created:v2", async (ctx) => { console.log("User event v2:", ctx.payload);});Utility functions
Synkro exports two utility functions for working with versioned events:
parseEventType
Parses an event type string into its components:
import { parseEventType } from "@synkro/core";
parseEventType("user:created:v2");// { base: "user:created", version: 2, raw: "user:created:v2" }
parseEventType("user:created");// { base: "user:created", version: null, raw: "user:created" }isVersionedEvent
Returns true if the event type contains a version suffix:
import { isVersionedEvent } from "@synkro/core";
isVersionedEvent("user:created:v2"); // trueisVersionedEvent("user:created"); // falseMigration strategy
- Add a new handler for
user:created:v2with the updated schema. - Keep the existing
user:created:v1handler (or the base handler) running. - Publishers migrate to emitting
user:created:v2at their own pace. - Once all publishers have migrated, retire the old handler.