Events API

The StabilizeEmitter behind orm.events

StabilizeEmitter

typescript
export class StabilizeEmitter {
on(event: StabilizeEvent, handler: StabilizeEventHandler): void
off(event: StabilizeEvent, handler: StabilizeEventHandler): void
emit(event: StabilizeEvent, ...args: any[]): void
}
export type StabilizeEventHandler = (...args: any[]) => void;
// Accessor, created in the Stabilize constructor:
orm.events: StabilizeEmitter

Every Stabilize instance creates one emitter in its constructor, reachable as orm.events. There is no once() method — register with on() and remove with off().

Methods:

  • on Registers a handler for an event
  • off Removes a handler by exact reference
  • emit Invokes every registered handler for an event
example/events.ts
orm.events.on("connection:open", (type) => {
console.log("Connected to " + type);
});

Event names

typescript
type StabilizeEvent =
| "query"
| "error"
| "migration:start"
| "migration:complete"
| "transaction:start"
| "transaction:complete"
| "transaction:error"
| "connection:open"
| "connection:close";

All nine names are emitted. Each event carries one payload object, except connection:open, which carries the DBType on its own.

  • connection:open Payload is the DBType, e.g. "postgres". Fires from the Stabilize constructor — see the note below.
  • connection:close No payload
  • query { dbType, query, params, executionTime } — once per statement, after it returns
  • error { dbType, phase, error, ... } — phase is "query", "migration" or "transaction". The query phase fires on every attempt, so it also reports failures that were retried and succeeded.
  • transaction:start { dbType } — not fired for a nested call already inside a transaction
  • transaction:complete { dbType } — after the transaction commits
  • transaction:error { dbType, phase: "transaction", error } — the callback threw and the transaction rolled back
  • migration:start { dbType, name, index, total } — once per migration, or per table for autoMigrate()
  • migration:complete { dbType, name, index, total }

connection:open fires inside the constructor, before the instance is returned, so a handler registered on orm.events afterwards never sees it. Build a StabilizeEmitter, subscribe, then pass it as the fifth constructor argument.

off()

typescript
off(event: StabilizeEvent, handler: StabilizeEventHandler): void

Removes a handler by exact reference — it looks the function up with indexOf and removes it with splice. An inline arrow function cannot be unsubscribed, because a new function object is a different reference.

example/off.ts
// Keep a named reference so you can unsubscribe later.
function onOpen(type) {
console.log("Connected to " + type);
}
orm.events.on("connection:open", onOpen);
orm.events.off("connection:open", onOpen);
// This does NOT work -- the second arrow is a different reference
// and is not present in the handler list:
orm.events.on("connection:open", () => {});
orm.events.off("connection:open", () => {});

emit()

typescript
emit(event: StabilizeEvent, ...args: any[]): void

Passes ...args to every registered handler for the event.

Handler exceptions are swallowed.

Each handler is invoked inside try { handler(...args) } catch {}, so a handler that throws fails silently. It will not propagate to your code, and it will not stop the other handlers from running — but you will not see the error unless you catch it inside the handler yourself.