Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.fanfare.io/llms.txt

Use this file to discover all available pages before exploring further.

Event System

The Fanfare SDK emits events for all significant state changes. This allows your application to react to changes in real-time without polling.

Subscribing to Events

Use the on() method to subscribe to events. It returns an unsubscribe function.
// Subscribe
const unsubscribe = fanfare.on("queue:admitted", (data) => {
  console.log("Admitted to queue:", data.queueId);
  console.log("Token:", data.token);
});

// Later: unsubscribe
unsubscribe();

Event Types

SDKEvents Interface

interface SDKEvents {
  // Authentication events
  "auth:authenticated": { session: Session };
  "auth:logout": void;

  // Queue events
  "queue:entered": { queueId: string; position: number };
  "queue:left": { queueId: string };
  "queue:position-changed": { queueId: string; position: number; estimatedWait: number };
  "queue:admitted": { queueId: string; token: string; expiresAt?: string };
  "queue:expired": { queueId: string };
  "queue:denied": { queueId: string; reason: string };
  "queue:error": { queueId: string; error: Error };

  // Draw events
  "draw:entered": { drawId: string };
  "draw:left": { drawId: string };
  "draw:won": { drawId: string; result: DrawResult };
  "draw:lost": { drawId: string; result: DrawResult };
  "draw:expired": { drawId: string };
  "draw:status-updated": { drawId: string };
  "draw:error": { drawId: string; error: Error };

  // Auction events
  "auction:entered": { auctionId: string };
  "auction:left": { auctionId: string };
  "auction:bid-placed": { auctionId: string; amount: string; status: string };
  "auction:outbid": { auctionId: string; highestBid: string };
  "auction:winning": { auctionId: string; amount: string; highestBid: string };
  "auction:won": { auctionId: string };
  "auction:lost": { auctionId: string; highestBid: string };
  "auction:status-updated": { auctionId: string; status: AuctionStatus };
  "auction:bid-updated": { auctionId: string; highestBid: string; bidCount: number };
  "auction:auto-rebid-enabled": { auctionId: string };
  "auction:auto-rebid-disabled": { auctionId: string };
  "auction:error": { auctionId: string; error: Error };

  // Waitlist events
  "waitlist:entered": { waitlistId: string; enteredAt: string };
  "waitlist:left": { waitlistId: string };
  "waitlist:error": { waitlistId: string; error: string };

  // Timed release events
  "timed_release:entered": { timedReleaseId: string; enteredAt: string };
  "timed_release:left": { timedReleaseId: string };
  "timed_release:completed": { timedReleaseId: string; completedAt: string };
  "timed_release:status-updated": { timedReleaseId: string };
  "timed_release:error": { timedReleaseId: string; error: Error };
}

Authentication Events

auth:authenticated

Fired when a session is created or upgraded.
fanfare.on("auth:authenticated", ({ session }) => {
  console.log("Session created:", session.consumerId);
  console.log("Type:", session.type);

  if (session.type === "authenticated") {
    console.log("Email:", session.email);
  }
});

auth:logout

Fired when the session is ended.
fanfare.on("auth:logout", () => {
  console.log("Session ended");
  redirectToLogin();
});

Queue Events

queue:entered

Fired when successfully entering a queue.
fanfare.on("queue:entered", ({ queueId, position }) => {
  console.log(`Entered queue ${queueId} at position ${position}`);
});

queue:left

Fired when leaving a queue.
fanfare.on("queue:left", ({ queueId }) => {
  console.log(`Left queue ${queueId}`);
});

queue:position-changed

Fired when queue position changes (from polling).
fanfare.on("queue:position-changed", ({ queueId, position, estimatedWait }) => {
  console.log(`Position: ${position}, Wait: ${estimatedWait}s`);
  updatePositionDisplay(position, estimatedWait);
});

queue:admitted

Fired when admitted from the queue.
fanfare.on("queue:admitted", ({ queueId, token, expiresAt }) => {
  console.log("Admitted! Token:", token);
  if (expiresAt) {
    console.log("Token expires:", expiresAt);
  }
  redirectToCheckout(token);
});

queue:expired

Fired when the admission token expires.
fanfare.on("queue:expired", ({ queueId }) => {
  console.log("Admission expired");
  showExpiredMessage();
});

queue:denied

Fired when denied entry to a queue.
fanfare.on("queue:denied", ({ queueId, reason }) => {
  console.log("Denied:", reason);
  showDeniedMessage(reason);
});

Draw Events

draw:entered

Fired when entering a draw.
fanfare.on("draw:entered", ({ drawId }) => {
  console.log("Entered draw:", drawId);
  showEnteredState();
});

draw:won

Fired when winning a draw.
fanfare.on("draw:won", ({ drawId, result }) => {
  console.log("Won draw:", drawId);
  console.log("Admission token:", result.admissionToken);
  showWinnerConfetti();
  redirectToCheckout(result.admissionToken);
});

draw:lost

Fired when not selected in a draw.
fanfare.on("draw:lost", ({ drawId, result }) => {
  console.log("Did not win:", drawId);
  showBetterLuckMessage();
});

draw:status-updated

Fired when draw status is refreshed.
fanfare.on("draw:status-updated", ({ drawId }) => {
  // Refresh UI with latest status
  refreshDrawDisplay(drawId);
});

Auction Events

auction:entered

Fired when entering an auction.
fanfare.on("auction:entered", ({ auctionId }) => {
  console.log("Entered auction:", auctionId);
});

auction:bid-placed

Fired when a bid is placed.
fanfare.on("auction:bid-placed", ({ auctionId, amount, status }) => {
  console.log(`Bid placed: ${amount}`);
  console.log(`Status: ${status}`); // "winning" | "outbid" | "accepted"
});

auction:outbid

Fired when your bid is surpassed.
fanfare.on("auction:outbid", ({ auctionId, highestBid }) => {
  console.log(`Outbid! Current highest: ${highestBid}`);
  showOutbidNotification(highestBid);
});

auction:winning

Fired when you become the highest bidder.
fanfare.on("auction:winning", ({ auctionId, amount, highestBid }) => {
  console.log("You are winning!");
  showWinningBadge();
});

auction:won

Fired when the auction ends and you won.
fanfare.on("auction:won", ({ auctionId }) => {
  console.log("Auction won!");
  showWinnerCelebration();
});

auction:lost

Fired when the auction ends and you lost.
fanfare.on("auction:lost", ({ auctionId, highestBid }) => {
  console.log(`Auction lost. Winning bid: ${highestBid}`);
  showLostMessage();
});

auction:bid-updated

Fired when the highest bid changes.
fanfare.on("auction:bid-updated", ({ auctionId, highestBid, bidCount }) => {
  updateBidDisplay(highestBid, bidCount);
});

Waitlist Events

waitlist:entered

Fired when joining a waitlist.
fanfare.on("waitlist:entered", ({ waitlistId, enteredAt }) => {
  console.log("Joined waitlist at:", enteredAt);
  showWaitlistConfirmation();
});

waitlist:left

Fired when leaving a waitlist.
fanfare.on("waitlist:left", ({ waitlistId }) => {
  console.log("Left waitlist");
});

Timed Release Events

timed_release:entered

Fired when entering a timed release.
fanfare.on("timed_release:entered", ({ timedReleaseId, enteredAt }) => {
  console.log("Entered timed release at:", enteredAt);
  redirectToShop();
});

timed_release:completed

Fired when completing a timed release (after purchase).
fanfare.on("timed_release:completed", ({ timedReleaseId, completedAt }) => {
  console.log("Timed release completed!");
  showThankYouMessage();
});

Error Events

All modules emit error events for failures:
fanfare.on("queue:error", ({ queueId, error }) => {
  console.error(`Queue error (${queueId}):`, error.message);
  showErrorToast(error.message);
});

fanfare.on("draw:error", ({ drawId, error }) => {
  console.error(`Draw error (${drawId}):`, error.message);
});

fanfare.on("auction:error", ({ auctionId, error }) => {
  console.error(`Auction error (${auctionId}):`, error.message);
});

fanfare.on("timed_release:error", ({ timedReleaseId, error }) => {
  console.error(`Timed release error (${timedReleaseId}):`, error.message);
});

Multiple Subscriptions

You can subscribe to the same event multiple times:
// Analytics tracking
fanfare.on("queue:admitted", ({ queueId, token }) => {
  analytics.track("queue_admitted", { queueId });
});

// UI updates
fanfare.on("queue:admitted", ({ token }) => {
  redirectToCheckout(token);
});

Cleanup Pattern

Always unsubscribe when components unmount:
// React example
useEffect(() => {
  const unsubscribes = [
    fanfare.on("queue:position-changed", handlePositionChange),
    fanfare.on("queue:admitted", handleAdmitted),
    fanfare.on("queue:error", handleError),
  ];

  return () => {
    unsubscribes.forEach((unsub) => unsub());
  };
}, [fanfare]);

TypeScript Support

Events are fully typed. The handler receives the correct data type:
// TypeScript infers data type from event name
fanfare.on("queue:admitted", (data) => {
  // data is typed as { queueId: string; token: string; expiresAt?: string }
  console.log(data.token); // string
  console.log(data.queueId); // string
});

fanfare.on("auction:bid-placed", (data) => {
  // data is typed as { auctionId: string; amount: string; status: string }
  console.log(data.amount); // string
});