CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-types--phoenix

TypeScript definitions for Phoenix JavaScript client library enabling real-time WebSocket communication with Phoenix Framework applications

Overview
Eval results
Files

channel.mddocs/

Channel Communication

Channel-based messaging system for subscribing to topics and exchanging real-time messages with Phoenix applications, including join/leave lifecycle and event handling.

Capabilities

Channel Constructor

Creates a new Channel instance for a specific topic.

/**
 * Creates a new Channel instance for a specific topic
 * @param topic - Channel topic string (e.g., "room:lobby", "user:123")
 * @param params - Channel parameters (static object or dynamic function)
 * @param socket - Socket instance (optional, can be set later)
 */
constructor(topic: string, params?: object | (() => object), socket?: Socket);

Usage Example:

import { Channel, Socket } from "phoenix";

const socket = new Socket("/socket");

// Static parameters
const lobbyChannel = new Channel("room:lobby", { user_id: 123 });

// Dynamic parameters
const userChannel = new Channel("user:456", () => ({
  token: getCurrentUserToken(),
  timestamp: Date.now()
}));

// With socket
const chatChannel = new Channel("chat:general", { role: "member" }, socket);

Channel Properties

Access channel state and topic information.

/**
 * Current channel state
 */
readonly state: ChannelState;

/**
 * Channel topic string
 */
readonly topic: string;

type ChannelState = "closed" | "errored" | "joined" | "joining" | "leaving";

Usage Example:

console.log("Channel topic:", channel.topic);
console.log("Channel state:", channel.state);

// Check if channel is ready for messages
if (channel.state === "joined") {
  channel.push("new_message", { body: "Hello!" });
}

Channel Lifecycle

Join and leave channels with timeout handling.

/**
 * Join the channel
 * @param timeout - Join timeout in milliseconds (optional)
 * @returns Push instance for handling join response
 */
join(timeout?: number): Push;

/**
 * Leave the channel
 * @param timeout - Leave timeout in milliseconds (optional)
 * @returns Push instance for handling leave response
 */
leave(timeout?: number): Push;

Usage Example:

// Basic join
channel.join()
  .receive("ok", (response) => {
    console.log("Joined successfully:", response);
  })
  .receive("error", (response) => {
    console.error("Failed to join:", response);
  })
  .receive("timeout", () => {
    console.warn("Join timed out");
  });

// Join with custom timeout (5 seconds)
channel.join(5000)
  .receive("ok", ({ messages }) => {
    console.log("Catching up on messages:", messages);
  });

// Leave channel
channel.leave()
  .receive("ok", () => {
    console.log("Left channel successfully");
  });

Event Handling

Register and remove event listeners for channel messages.

/**
 * Register event handler for channel messages
 * @param event - Event name to listen for
 * @param callback - Function to call when event is received
 * @returns Reference number for removing handler
 */
on(event: string, callback: (response?: any) => void | Promise<void>): number;

/**
 * Remove event handler
 * @param event - Event name
 * @param ref - Handler reference number (optional)
 */
off(event: string, ref?: number): void;

Usage Example:

// Listen for messages
const messageHandler = channel.on("new_message", (payload) => {
  console.log("New message:", payload.body);
  console.log("From user:", payload.user);
});

// Listen for user events
const joinHandler = channel.on("user_joined", async (payload) => {
  console.log("User joined:", payload.user.name);
  await updateUserList(payload.user);
});

// Remove specific handler
channel.off("new_message", messageHandler);

// Remove all handlers for an event
channel.off("user_joined");

Message Sending

Send messages to the channel with status handling.

/**
 * Send message to channel
 * @param event - Event name
 * @param payload - Message payload object
 * @param timeout - Send timeout in milliseconds (optional)
 * @returns Push instance for handling response
 */
push(event: string, payload: object, timeout?: number): Push;

Usage Example:

// Send basic message
channel.push("new_message", {
  body: "Hello, world!",
  user_id: 123
})
.receive("ok", (response) => {
  console.log("Message sent:", response);
})
.receive("error", (reasons) => {
  console.error("Send failed:", reasons);
});

// Send with timeout
channel.push("file_upload", {
  filename: "document.pdf",
  size: 1024000
}, 10000) // 10 second timeout
.receive("ok", ({ upload_url }) => {
  console.log("Upload URL received:", upload_url);
})
.receive("timeout", () => {
  console.warn("Upload request timed out");
});

// Send and chain multiple status handlers
channel.push("update_profile", {
  name: "John Doe",
  email: "john@example.com"
})
.receive("ok", (profile) => {
  console.log("Profile updated:", profile);
  showSuccessMessage("Profile saved!");
})
.receive("error", ({ errors }) => {
  console.error("Validation errors:", errors);
  showErrorMessage(errors);
})
.receive("timeout", () => {
  showWarningMessage("Request timed out, please try again");
});

Lifecycle Event Handlers

Register handlers for channel lifecycle events.

/**
 * Register callback for channel close events
 * @param callback - Function to call when channel closes
 * @returns Reference number for removing handler
 */
onClose(callback: (payload: any, ref: any, joinRef: any) => void | Promise<void>): number;

/**
 * Register callback for channel error events
 * @param callback - Function to call when channel errors occur
 * @returns Reference number for removing handler
 */
onError(callback: (reason?: any) => void | Promise<void>): number;

/**
 * Handle incoming messages (low-level message processing)
 * @param event - Event name
 * @param payload - Message payload
 * @param ref - Message reference
 * @returns Processed message result
 */
onMessage(event: string, payload: any, ref: any): any;

Usage Example:

// Handle channel close
const closeHandler = channel.onClose((payload, ref, joinRef) => {
  console.log("Channel closed:", payload);
  console.log("Close ref:", ref);
  console.log("Join ref:", joinRef);

  // Cleanup or redirect user
  showMessage("Connection to room lost");
});

// Handle channel errors
const errorHandler = channel.onError(async (reason) => {
  console.error("Channel error:", reason);

  // Attempt to rejoin after error
  try {
    await new Promise(resolve => setTimeout(resolve, 1000));
    channel.join();
  } catch (error) {
    console.error("Failed to rejoin channel:", error);
  }
});

// Custom message processing
channel.onMessage = (event, payload, ref) => {
  // Log all messages
  console.log(`Message [${event}]:`, payload);

  // Custom processing logic
  if (event === "custom_event") {
    return { processed: true, payload };
  }

  // Return original payload for default processing
  return payload;
};

// Remove lifecycle handlers when done
channel.off("phx_close", closeHandler);
channel.off("phx_error", errorHandler);

Advanced Usage Patterns

Channel State Management

// Monitor channel state changes
function monitorChannelState(channel: Channel) {
  const checkState = () => {
    switch (channel.state) {
      case "joining":
        console.log("Channel is joining...");
        break;
      case "joined":
        console.log("Channel is active");
        break;
      case "leaving":
        console.log("Channel is leaving...");
        break;
      case "closed":
        console.log("Channel is closed");
        break;
      case "errored":
        console.log("Channel has errors");
        break;
    }
  };

  // Check state periodically
  const interval = setInterval(checkState, 1000);

  // Cleanup
  channel.onClose(() => clearInterval(interval));
}

Error Recovery

// Automatic rejoin on error with exponential backoff
function setupAutoRejoin(channel: Channel) {
  let rejoinAttempts = 0;
  const maxAttempts = 5;

  channel.onError(async () => {
    if (rejoinAttempts < maxAttempts) {
      const delay = Math.pow(2, rejoinAttempts) * 1000; // Exponential backoff
      rejoinAttempts++;

      console.log(`Rejoining in ${delay}ms (attempt ${rejoinAttempts})`);

      await new Promise(resolve => setTimeout(resolve, delay));

      channel.join()
        .receive("ok", () => {
          rejoinAttempts = 0; // Reset on success
        });
    } else {
      console.error("Max rejoin attempts exceeded");
    }
  });
}

Install with Tessl CLI

npx tessl i tessl/npm-types--phoenix

docs

channel.md

index.md

presence.md

push.md

socket.md

utilities.md

tile.json