Skip to content

Types Reference ​

Home > Documentation > API Reference > Types

Overview ​

ParleyJS is written in TypeScript and provides comprehensive type definitions for all configuration options, message payloads, event handlers, and error types. This reference documents all exported types and interfaces.

Table of Contents ​

  1. Core Types
  2. Configuration Types
  3. Message Types
  4. Handler Types
  5. Event Types
  6. Error Types
  7. Utility Types
  8. Type Guards
  9. Generic Usage

Core Types ​

Parley ​

The main ParleyJS class for establishing communication channels.

typescript
class Parley {
    constructor(config?: ParleyConfig);

    on<T = any, R = any>(
        channel: string,
        handler: MessageHandler<T, R>,
        options?: HandlerOptions
    ): () => void;

    send<T = any, R = any>(
        channel: string,
        payload: T,
        options?: SendOptions
    ): Promise<R>;

    emit<T = any>(channel: string, payload: T): void;

    off(channel: string, handler?: MessageHandler): void;

    destroy(): void;
}

Type Parameters:

  • T: Type of message payload
  • R: Type of response data

Example:

typescript
import { Parley } from 'parleyjs';

interface UserData {
    userId: number;
    username: string;
}

interface UserResponse {
    success: boolean;
    user?: UserData;
}

const parley = new Parley();

// Typed message handler
parley.on<UserData, UserResponse>('create-user', (payload, respond) => {
    // payload is typed as UserData
    const user = createUser(payload);

    // respond accepts UserResponse
    respond({ success: true, user });
});

// Typed send
const response = await parley.send<UserData, UserResponse>('create-user', {
    userId: 123,
    username: 'alice',
});
// response is typed as UserResponse

Configuration Types ​

ParleyConfig ​

Main configuration object for Parley instances.

typescript
interface ParleyConfig {
    /**
     * Target for communication (window, worker, iframe)
     * @default self (current context)
     */
    target?: Window | Worker | MessagePort;

    /**
     * Type of target being communicated with
     */
    targetType?: TargetType;

    /**
     * Default timeout for request-response operations (ms)
     * @default 30000
     */
    timeout?: number;

    /**
     * Allowed origins for security validation
     * @default ['*'] (allow all - not recommended for production)
     */
    allowedOrigins?: string[];

    /**
     * Heartbeat monitoring configuration
     */
    heartbeat?: HeartbeatConfig;

    /**
     * Enable debug logging
     * @default false
     */
    debug?: boolean;

    /**
     * Custom serializer for message payloads
     */
    serializer?: MessageSerializer;

    /**
     * Namespace prefix for message channels
     */
    namespace?: string;
}

Example:

typescript
const config: ParleyConfig = {
    target: workerInstance,
    targetType: 'worker',
    timeout: 10000,
    allowedOrigins: ['https://app.example.com'],
    heartbeat: {
        enabled: true,
        interval: 5000,
        timeout: 15000,
    },
    debug: process.env.NODE_ENV === 'development',
    namespace: 'myapp',
};

const parley = new Parley(config);

HeartbeatConfig ​

Configuration for heartbeat monitoring to detect connection issues.

typescript
interface HeartbeatConfig {
    /**
     * Enable heartbeat monitoring
     * @default false
     */
    enabled: boolean;

    /**
     * Interval between heartbeat pings (ms)
     * @default 5000
     */
    interval?: number;

    /**
     * Timeout before considering target unresponsive (ms)
     * @default 15000
     */
    timeout?: number;

    /**
     * Maximum missed heartbeats before triggering timeout
     * @default 3
     */
    maxMissed?: number;
}

Example:

typescript
const heartbeat: HeartbeatConfig = {
    enabled: true,
    interval: 3000, // Send ping every 3 seconds
    timeout: 10000, // Fail if no pong within 10 seconds
    maxMissed: 2, // Fail after 2 consecutive missed heartbeats
};

const parley = new Parley({ heartbeat });

TargetType ​

Enum-like type for different communication targets.

typescript
type TargetType = 'window' | 'worker' | 'iframe' | 'port';

Usage:

typescript
import { Parley, TargetType } from 'parleyjs';

const workerParley = new Parley({
    target: myWorker,
    targetType: 'worker' as TargetType,
});

const iframeParley = new Parley({
    target: iframeWindow,
    targetType: 'iframe' as TargetType,
});

Message Types ​

SendOptions ​

Options for send() operations.

typescript
interface SendOptions {
    /**
     * Override default timeout for this message (ms)
     */
    timeout?: number;

    /**
     * Message priority (higher number = higher priority)
     * @default 0
     */
    priority?: number;

    /**
     * Transfer ownership of Transferable objects
     */
    transfer?: Transferable[];

    /**
     * Metadata to attach to message
     */
    metadata?: Record<string, any>;
}

Example:

typescript
// Send with custom timeout
const response = await parley.send('slow-operation', data, {
    timeout: 60000, // 60 second timeout
});

// Send with transferable objects (e.g., ArrayBuffer)
const buffer = new ArrayBuffer(1024);
await parley.send(
    'process-buffer',
    { buffer },
    {
        transfer: [buffer], // Transfer ownership to worker
    }
);

// Send with priority
await parley.send('urgent-task', data, {
    priority: 10, // Higher priority than default
    metadata: { userId: 123, requestId: 'req-456' },
});

MessageMetadata ​

Metadata attached to every message.

typescript
interface MessageMetadata {
    /**
     * Unique message identifier
     */
    messageId: string;

    /**
     * Message channel name
     */
    channel: string;

    /**
     * Timestamp when message was sent
     */
    timestamp: number;

    /**
     * Origin of the message sender
     */
    origin?: string;

    /**
     * Custom metadata provided in SendOptions
     */
    custom?: Record<string, any>;

    /**
     * Whether this message expects a response
     */
    expectsResponse: boolean;
}

Example:

typescript
parley.on('process', (payload, respond, metadata) => {
    console.log('Message ID:', metadata.messageId);
    console.log('Sent at:', new Date(metadata.timestamp));
    console.log('From origin:', metadata.origin);
    console.log('Custom data:', metadata.custom);

    respond({ processed: true });
});

MessageSerializer ​

Interface for custom message serialization.

typescript
interface MessageSerializer {
    /**
     * Serialize payload before sending
     */
    serialize(payload: any): any;

    /**
     * Deserialize payload after receiving
     */
    deserialize(data: any): any;
}

Example:

typescript
import { ParleyConfig, MessageSerializer } from 'parleyjs';

// Custom serializer using MessagePack
const msgpackSerializer: MessageSerializer = {
    serialize(payload) {
        return msgpack.encode(payload);
    },
    deserialize(data) {
        return msgpack.decode(data);
    },
};

const config: ParleyConfig = {
    serializer: msgpackSerializer,
};

Handler Types ​

MessageHandler ​

Type for message event handlers.

typescript
type MessageHandler<T = any, R = any> = (
    payload: T,
    respond: ResponseFunction<R>,
    metadata: MessageMetadata
) => void | Promise<void>;

Type Parameters:

  • T: Type of incoming payload
  • R: Type of response data

Example:

typescript
import { MessageHandler } from 'parleyjs';

interface CalculateRequest {
    operation: 'add' | 'subtract';
    a: number;
    b: number;
}

interface CalculateResponse {
    result: number;
}

const calculateHandler: MessageHandler<CalculateRequest, CalculateResponse> = (
    payload,
    respond,
    metadata
) => {
    const result =
        payload.operation === 'add'
            ? payload.a + payload.b
            : payload.a - payload.b;

    respond({ result });
};

parley.on('calculate', calculateHandler);

ResponseFunction ​

Function signature for responding to messages.

typescript
type ResponseFunction<R = any> = (response: R) => void;

Example:

typescript
parley.on<UserQuery, UserData>('get-user', async (payload, respond) => {
    const user = await fetchUser(payload.userId);

    // respond is typed as ResponseFunction<UserData>
    respond({ userId: user.id, username: user.name });
});

HandlerOptions ​

Options for registering message handlers.

typescript
interface HandlerOptions {
    /**
     * JSON schema for payload validation
     */
    schema?: object;

    /**
     * Validate payload before calling handler
     * @default true if schema provided
     */
    validate?: boolean;

    /**
     * Handler priority (higher = called earlier)
     * @default 0
     */
    priority?: number;

    /**
     * Call handler only once, then auto-unregister
     * @default false
     */
    once?: boolean;
}

Example:

typescript
const userSchema = {
    type: 'object',
    properties: {
        userId: { type: 'number' },
        email: { type: 'string', format: 'email' },
    },
    required: ['userId', 'email'],
};

parley.on('create-user', handler, {
    schema: userSchema, // Auto-validate against schema
    validate: true, // Enable validation
    priority: 10, // High priority handler
    once: false, // Can be called multiple times
});

Event Types ​

System Events ​

ParleyJS emits various system events for monitoring.

typescript
type SystemEvent =
    | 'ready'
    | 'error'
    | 'message:sent'
    | 'message:received'
    | 'connection:established'
    | 'connection:lost'
    | 'heartbeat:sent'
    | 'heartbeat:received'
    | 'heartbeat:timeout';

Example:

typescript
import { Parley, SystemEvent } from 'parleyjs';

const parley = new Parley();

parley.on('ready', () => {
    console.log('Parley is ready');
});

parley.on('error', (error) => {
    console.error('Error occurred:', error);
});

parley.on('connection:lost', () => {
    console.warn('Connection lost - attempting reconnect');
});

parley.on('heartbeat:timeout', () => {
    console.error('Target is unresponsive');
});

EventCallback ​

Generic callback type for system events.

typescript
type EventCallback<T = any> = (data: T) => void | Promise<void>;

Error Types ​

All error types extend the base ParleyError class. See Error Codes Reference for detailed documentation.

ParleyError ​

typescript
class ParleyError extends Error {
    code: string;
    details?: any;
    timestamp: number;
}

ValidationError ​

typescript
class ValidationError extends ParleyError {
    validationErrors: Array<{
        field: string;
        message: string;
        value?: any;
    }>;
    schema?: object;
    payload?: any;
}

TimeoutError ​

typescript
class TimeoutError extends ParleyError {
    messageId: string;
    timeout: number;
    channel: string;
}

TargetNotFoundError ​

typescript
class TargetNotFoundError extends ParleyError {
    targetId?: string;
    targetType?: string;
}

SecurityError ​

typescript
class SecurityError extends ParleyError {
    origin?: string;
    expectedOrigin?: string;
    violationType?: string;
}

SerializationError ​

typescript
class SerializationError extends ParleyError {
    payload?: any;
    serializationType?: string;
}

ConnectionError ​

typescript
class ConnectionError extends ParleyError {
    targetType?: string;
    reconnectable?: boolean;
}

ConfigurationError ​

typescript
class ConfigurationError extends ParleyError {
    configKey?: string;
    providedValue?: any;
    expectedType?: string;
}

Utility Types ​

UnsubscribeFunction ​

Return type from parley.on() for unsubscribing handlers.

typescript
type UnsubscribeFunction = () => void;

Example:

typescript
const unsubscribe = parley.on('message', handler);

// Later, unsubscribe from this specific handler
unsubscribe();

ResolvedConfig ​

Internal type representing fully resolved configuration with defaults applied.

typescript
interface ResolvedConfig extends Required<ParleyConfig> {
    // All optional ParleyConfig fields become required
}

Type Guards ​

isParleyError ​

Check if an error is a ParleyError instance.

typescript
function isParleyError(error: any): error is ParleyError {
    return error instanceof ParleyError;
}

Example:

typescript
import { isParleyError, ParleyError } from 'parleyjs';

try {
    await parley.send('operation', data);
} catch (error) {
    if (isParleyError(error)) {
        console.error('ParleyJS error:', error.code);
        console.error('Details:', error.details);
    } else {
        console.error('Unknown error:', error);
    }
}

isValidationError ​

typescript
function isValidationError(error: any): error is ValidationError {
    return error instanceof ValidationError;
}

isTimeoutError ​

typescript
function isTimeoutError(error: any): error is TimeoutError {
    return error instanceof TimeoutError;
}

isSecurityError ​

typescript
function isSecurityError(error: any): error is SecurityError {
    return error instanceof SecurityError;
}

Example:

typescript
import { isValidationError, isTimeoutError, isSecurityError } from 'parleyjs';

try {
    await parley.send('process', data);
} catch (error) {
    if (isValidationError(error)) {
        handleValidationErrors(error.validationErrors);
    } else if (isTimeoutError(error)) {
        retryWithLongerTimeout(error.channel);
    } else if (isSecurityError(error)) {
        logSecurityIncident(error.origin);
    }
}

Generic Usage ​

Strongly Typed Handlers ​

Define interfaces for your message contracts and use generics for type safety.

typescript
// Define message contracts
interface UserCreateRequest {
    username: string;
    email: string;
    password: string;
}

interface UserCreateResponse {
    success: boolean;
    userId?: number;
    errors?: string[];
}

// Typed handler
const createUserHandler: MessageHandler<
    UserCreateRequest,
    UserCreateResponse
> = (payload, respond) => {
    // payload is fully typed
    const user = createUser(payload.username, payload.email, payload.password);

    // respond accepts only UserCreateResponse
    respond({
        success: true,
        userId: user.id,
    });
};

// Register with types
parley.on<UserCreateRequest, UserCreateResponse>(
    'user:create',
    createUserHandler
);

// Send with types
const result = await parley.send<UserCreateRequest, UserCreateResponse>(
    'user:create',
    { username: 'alice', email: 'alice@example.com', password: 'secret' }
);

// result is typed as UserCreateResponse
if (result.success) {
    console.log('User created:', result.userId);
}

Union Types for Channels ​

typescript
type AppChannel =
    | 'user:create'
    | 'user:update'
    | 'user:delete'
    | 'post:create'
    | 'post:publish';

type ChannelPayload<T extends AppChannel> = T extends 'user:create'
    ? UserCreateRequest
    : T extends 'user:update'
      ? UserUpdateRequest
      : T extends 'user:delete'
        ? { userId: number }
        : T extends 'post:create'
          ? PostCreateRequest
          : T extends 'post:publish'
            ? { postId: number }
            : never;

// Type-safe channel messaging
async function typedSend<T extends AppChannel>(
    channel: T,
    payload: ChannelPayload<T>
) {
    return parley.send(channel, payload);
}

// Usage - TypeScript ensures correct payload type
await typedSend('user:create', {
    username: 'alice',
    email: '...',
    password: '...',
});
await typedSend('post:publish', { postId: 123 });

Discriminated Unions for Responses ​

typescript
type ApiResponse<T> =
    | { success: true; data: T }
    | { success: false; error: string; code: string };

interface User {
    id: number;
    username: string;
}

const response = await parley.send<{ userId: number }, ApiResponse<User>>(
    'get-user',
    { userId: 123 }
);

// TypeScript narrows type based on success field
if (response.success) {
    console.log('User:', response.data.username); // data is available
} else {
    console.error('Error:', response.error); // error is available
}

Custom Type Validators ​

typescript
import { MessageHandler } from 'parleyjs';

function createTypedHandler<T, R>(
    validator: (payload: any) => payload is T,
    handler: (payload: T, respond: (r: R) => void) => void | Promise<void>
): MessageHandler<any, R> {
    return (payload, respond, metadata) => {
        if (!validator(payload)) {
            throw new ValidationError('Invalid payload type');
        }
        return handler(payload, respond);
    };
}

// Type guard
function isUserRequest(payload: any): payload is UserCreateRequest {
    return (
        typeof payload === 'object' &&
        typeof payload.username === 'string' &&
        typeof payload.email === 'string'
    );
}

// Usage
const handler = createTypedHandler<UserCreateRequest, UserCreateResponse>(
    isUserRequest,
    (payload, respond) => {
        // payload is guaranteed to be UserCreateRequest
        respond({ success: true, userId: createUser(payload) });
    }
);

parley.on('user:create', handler);

Previous: Error Codes Next: Guides

Related:

Back to: API Reference

Released under the MIT License.