CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-undici

An HTTP/1.1 client, written from scratch for Node.js

Pending
Overview
Eval results
Files

web-standards.mddocs/

Web Standards Implementation

Complete WHATWG-compliant implementations of fetch, WebSocket, EventSource, and related Web APIs for Node.js environments.

Capabilities

fetch

WHATWG fetch API implementation with full Web Standards compliance and performance optimizations.

/**
 * WHATWG fetch API implementation
 * @param input - URL or Request object
 * @param init - Request initialization options
 * @returns Promise resolving to Response
 */
function fetch(input: RequestInfo, init?: RequestInit): Promise<Response>;

type RequestInfo = string | URL | Request;

interface RequestInit {
  method?: string;
  headers?: HeadersInit;
  body?: BodyInit;
  mode?: RequestMode;
  credentials?: RequestCredentials;
  cache?: RequestCache;
  redirect?: RequestRedirect;
  referrer?: string;
  referrerPolicy?: ReferrerPolicy;
  integrity?: string;
  keepalive?: boolean;
  signal?: AbortSignal;
  window?: null;
  duplex?: RequestDuplex;
}

type RequestMode = 'cors' | 'no-cors' | 'same-origin' | 'navigate';
type RequestCredentials = 'omit' | 'same-origin' | 'include';
type RequestCache = 'default' | 'no-store' | 'reload' | 'no-cache' | 'force-cache' | 'only-if-cached';
type RequestRedirect = 'follow' | 'error' | 'manual';
type RequestDuplex = 'half';

Usage Examples:

import { fetch } from 'undici';

// Simple GET request
const response = await fetch('https://api.example.com/users');
const users = await response.json();

// POST request with JSON
const createResponse = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ name: 'Alice', email: 'alice@example.com' })
});

// Request with abort signal
const controller = new AbortController();
setTimeout(() => controller.abort(), 5000);

try {
  const response = await fetch('https://slow-api.example.com/data', {
    signal: controller.signal
  });
  const data = await response.json();
} catch (error) {
  if (error.name === 'AbortError') {
    console.log('Request was aborted');
  }
}

// Custom request options
const response = await fetch('https://api.example.com/data', {
  method: 'GET',
  mode: 'cors',
  credentials: 'include',
  cache: 'no-cache',
  redirect: 'follow'
});

Request

WHATWG Request API implementation for representing HTTP requests.

/**
 * Represents an HTTP request
 */
class Request {
  constructor(input: RequestInfo, init?: RequestInit);
  
  readonly method: string;
  readonly url: string;
  readonly headers: Headers;
  readonly body: ReadableStream | null;
  readonly bodyUsed: boolean;
  readonly mode: RequestMode;
  readonly credentials: RequestCredentials;
  readonly cache: RequestCache;
  readonly redirect: RequestRedirect;
  readonly referrer: string;
  readonly referrerPolicy: ReferrerPolicy;
  readonly integrity: string;
  readonly keepalive: boolean;
  readonly signal: AbortSignal;
  readonly duplex: RequestDuplex;
  
  clone(): Request;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  bytes(): Promise<Uint8Array>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
}

Usage Examples:

import { Request, fetch } from 'undici';

// Create reusable request
const baseRequest = new Request('https://api.example.com/users', {
  method: 'GET',
  headers: { 'Authorization': 'Bearer token123' }
});

// Clone and modify requests
const userRequest = baseRequest.clone();
const postsRequest = new Request('https://api.example.com/posts', baseRequest);

// Use with fetch
const response = await fetch(userRequest);
const users = await response.json();

Response

WHATWG Response API implementation for representing HTTP responses.

/**
 * Represents an HTTP response
 */
class Response {
  constructor(body?: BodyInit, init?: ResponseInit);
  
  readonly status: number;
  readonly statusText: string;
  readonly ok: boolean;
  readonly redirected: boolean;
  readonly type: ResponseType;
  readonly url: string;
  readonly headers: Headers;
  readonly body: ReadableStream | null;
  readonly bodyUsed: boolean;
  
  static error(): Response;
  static json(data: any, init?: ResponseInit): Response;
  static redirect(url: string | URL, status?: number): Response;
  
  clone(): Response;
  arrayBuffer(): Promise<ArrayBuffer>;
  blob(): Promise<Blob>;
  bytes(): Promise<Uint8Array>;
  formData(): Promise<FormData>;
  json(): Promise<any>;
  text(): Promise<string>;
}

interface ResponseInit {
  status?: number;
  statusText?: string;
  headers?: HeadersInit;
}

type ResponseType = 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect';

Usage Examples:

import { Response } from 'undici';

// Create custom responses
const jsonResponse = Response.json({ message: 'Hello World' });
const redirectResponse = Response.redirect('https://example.com/new-url', 302);
const errorResponse = Response.error();

// Process response data
const response = await fetch('https://api.example.com/data');

if (response.ok) {
  const contentType = response.headers.get('content-type');
  
  if (contentType?.includes('application/json')) {
    const data = await response.json();
    console.log(data);
  } else {
    const text = await response.text();
    console.log(text);
  }
} else {
  console.error(`Request failed: ${response.status} ${response.statusText}`);
}

WebSocket

WHATWG WebSocket API implementation for real-time bidirectional communication.

/**
 * WebSocket client implementation
 */
class WebSocket extends EventTarget {
  constructor(url: string | URL, protocols?: string | string[], options?: WebSocketInit);
  
  static readonly CONNECTING: 0;
  static readonly OPEN: 1;
  static readonly CLOSING: 2;
  static readonly CLOSED: 3;
  
  readonly url: string;
  readonly readyState: number;
  readonly extensions: string;
  readonly protocol: string;
  binaryType: BinaryType;
  
  send(data: string | ArrayBuffer | ArrayBufferView | Blob): void;
  close(code?: number, reason?: string): void;
  
  // Event handlers
  onopen: ((event: Event) => void) | null;
  onmessage: ((event: MessageEvent) => void) | null;
  onerror: ((event: ErrorEvent) => void) | null;
  onclose: ((event: CloseEvent) => void) | null;
}

interface WebSocketInit {
  protocols?: string[];
  headers?: HeadersInit;
  followRedirects?: boolean;
  maxRedirects?: number;
  maxPayload?: number;
  skipUTF8Validation?: boolean;
  dispatcher?: Dispatcher;
}

type BinaryType = 'blob' | 'arraybuffer';

Usage Examples:

import { WebSocket } from 'undici';

// Basic WebSocket connection
const ws = new WebSocket('wss://echo.websocket.org');

ws.onopen = (event) => {
  console.log('WebSocket connected');
  ws.send('Hello Server!');
};

ws.onmessage = (event) => {
  console.log('Received:', event.data);
};

ws.onerror = (event) => {
  console.error('WebSocket error:', event);
};

ws.onclose = (event) => {
  console.log(`WebSocket closed: ${event.code} ${event.reason}`);
};

// WebSocket with protocols and headers
const authWs = new WebSocket('wss://api.example.com/socket', ['chat', 'v1'], {
  headers: {
    'Authorization': 'Bearer token123'
  },
  maxPayload: 64 * 1024 // 64KB
});

// Send different data types
authWs.send('text message');
authWs.send(new ArrayBuffer(8));
authWs.send(new Uint8Array([1, 2, 3, 4]));

// Close with custom code and reason
authWs.close(1000, 'Normal closure');

WebSocket Events

WebSocket event classes for handling connection lifecycle.

/**
 * WebSocket close event
 */
class CloseEvent extends Event {
  constructor(type: string, eventInitDict?: CloseEventInit);
  
  readonly code: number;
  readonly reason: string;
  readonly wasClean: boolean;
}

interface CloseEventInit extends EventInit {
  code?: number;
  reason?: string;
  wasClean?: boolean;
}

/**
 * WebSocket error event
 */
class ErrorEvent extends Event {
  constructor(type: string, eventInitDict?: ErrorEventInit);
  
  readonly message: string;
  readonly error: any;
}

interface ErrorEventInit extends EventInit {
  message?: string;
  error?: any;
}

/**
 * WebSocket message event
 */
class MessageEvent extends Event {
  constructor(type: string, eventInitDict?: MessageEventInit);
  
  readonly data: any;
  readonly origin: string;
  readonly lastEventId: string;
  readonly source: any;
  readonly ports: MessagePort[];
}

interface MessageEventInit extends EventInit {
  data?: any;
  origin?: string;
  lastEventId?: string;
  source?: any;
  ports?: MessagePort[];
}

WebSocket Utilities

/**
 * Send a ping frame to a WebSocket
 * @param ws - WebSocket instance
 * @param data - Optional ping data
 * @returns Promise resolving when pong is received
 */
function ping(ws: WebSocket, data?: Buffer): Promise<void>;

Usage Examples:

import { WebSocket, ping } from 'undici';

const ws = new WebSocket('wss://example.com/socket');

ws.onopen = async () => {
  // Send ping and wait for pong
  try {
    await ping(ws, Buffer.from('ping-data'));
    console.log('Ping successful');
  } catch (error) {
    console.error('Ping failed:', error);
  }
};

WebSocket Streams

Streaming WebSocket implementation providing a simpler streams-based API.

/**
 * Streaming WebSocket implementation
 */
class WebSocketStream {
  constructor(url: string | URL, options?: WebSocketStreamInit);
  
  readonly url: string;
  readonly connection: Promise<WebSocketConnection>;
  
  close(closeInfo?: WebSocketCloseInfo): void;
}

interface WebSocketStreamInit {
  protocols?: string[];
  signal?: AbortSignal;
}

interface WebSocketConnection {
  readonly readable: ReadableStream;
  readonly writable: WritableStream;
  readonly extensions: string;
  readonly protocol: string;
}

interface WebSocketCloseInfo {
  code?: number;
  reason?: string;
}

WebSocket Errors

Specialized error types for WebSocket operations.

/**
 * WebSocket-specific error class
 */
class WebSocketError extends Error {
  constructor(message: string, init?: WebSocketErrorInit);
  
  readonly closeCode?: number;
  readonly reason?: string;
}

interface WebSocketErrorInit {
  closeCode?: number;
  reason?: string;
}

Usage Examples:

import { WebSocketStream, WebSocketError } from 'undici';

// Create a streaming WebSocket connection
const wsStream = new WebSocketStream('wss://api.example.com/stream');

try {
  const connection = await wsStream.connection;
  
  // Use readable stream
  const reader = connection.readable.getReader();
  while (true) {
    const { value, done } = await reader.read();
    if (done) break;
    console.log('Received:', value);
  }
  
  // Use writable stream
  const writer = connection.writable.getWriter();
  await writer.write('Hello Stream!');
  await writer.close();
  
} catch (error) {
  if (error instanceof WebSocketError) {
    console.error(`WebSocket error: ${error.message}, code: ${error.closeCode}`);
  }
}

EventSource

WHATWG EventSource API implementation for server-sent events.

/**
 * Server-sent events client
 */
class EventSource extends EventTarget {
  constructor(url: string | URL, eventSourceInitDict?: EventSourceInit);
  
  static readonly CONNECTING: 0;
  static readonly OPEN: 1;
  static readonly CLOSED: 2;
  
  readonly url: string;
  readonly readyState: number;
  readonly withCredentials: boolean;
  
  close(): void;
  
  // Event handlers
  onopen: ((event: Event) => void) | null;
  onmessage: ((event: MessageEvent) => void) | null;
  onerror: ((event: Event) => void) | null;
}

interface EventSourceInit {
  withCredentials?: boolean;
  headers?: HeadersInit;
  dispatcher?: Dispatcher;
}

Usage Examples:

import { EventSource } from 'undici';

// Basic EventSource connection
const eventSource = new EventSource('https://api.example.com/events');

eventSource.onopen = () => {
  console.log('EventSource connected');
};

eventSource.onmessage = (event) => {
  console.log('Received event:', JSON.parse(event.data));
};

eventSource.onerror = (event) => {
  console.error('EventSource error:', event);
};

// EventSource with credentials and custom headers
const authEventSource = new EventSource('https://api.example.com/private-events', {
  withCredentials: true,
  headers: {
    'Authorization': 'Bearer token123'
  }
});

// Listen for custom event types
authEventSource.addEventListener('user-update', (event) => {
  const userData = JSON.parse(event.data);
  console.log('User updated:', userData);
});

// Close connection
setTimeout(() => {
  eventSource.close();
}, 30000);

Types

Body and Header Types

type BodyInit = 
  | ArrayBuffer 
  | AsyncIterable<Uint8Array> 
  | Blob 
  | FormData 
  | Iterable<Uint8Array> 
  | NodeJS.ArrayBufferView 
  | URLSearchParams 
  | null 
  | string;

type HeadersInit = 
  | Headers 
  | Record<string, string | ReadonlyArray<string>> 
  | Iterable<readonly [string, string]>;

type ReferrerPolicy = 
  | '' 
  | 'no-referrer' 
  | 'no-referrer-when-downgrade' 
  | 'same-origin' 
  | 'origin' 
  | 'strict-origin' 
  | 'origin-when-cross-origin' 
  | 'strict-origin-when-cross-origin' 
  | 'unsafe-url';

Install with Tessl CLI

npx tessl i tessl/npm-undici

docs

caching.md

connection-management.md

cookies.md

core-http.md

errors.md

global-config.md

headers-body.md

index.md

interceptors.md

mock-testing.md

web-standards.md

tile.json