Skip to content

A lightweight, promise-based HTTP client for the browser with streaming support and batch processing capabilities.

License

Notifications You must be signed in to change notification settings

Panintelligence/api-client-js

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

api-client-js

A lightweight, promise-based HTTP client for the browser with streaming support and batch processing capabilities.

Features

  • Simple, promise-based API for making HTTP requests
  • Support for all HTTP methods (GET, POST, PUT, DELETE, PATCH, etc.)
  • JSON request and response handling
  • Streaming response processing
  • Parallel batch request processing
  • Chat completions API support (regular, JSON streaming, and SSE)
  • Detailed response information with convenient utility methods
  • Typed interfaces with TypeScript declarations
  • Zero dependencies
  • Works directly in the browser without bundling

Installation

Direct inclusion in HTML

<script src="https://cdn.jsdelivr.net/gh/mingzilla/api-client-js@latest/api-client.js"></script>

TypeScript Support for Direct Inclusion

If you're using TypeScript with direct script inclusion, you can reference the type definitions in one of these ways:

  1. Download the definition file and place it in your project, then reference it in your tsconfig.json:

    {
      "compilerOptions": {
        "typeRoots": ["./typings", "./node_modules/@types"]
      }
    }

    And create a folder structure:

    your-project/
    ├── typings/
    │   └── api-client-js/
    │       └── index.d.ts  // Copy contents from api-client.d.ts
    
  2. Reference the declaration file directly using a triple-slash directive:

    /// <reference path="./typings/api-client.d.ts" />
  3. Use the CDN for the declaration file:

    // In your TypeScript file
    declare module 'api-client-js';
    // Then add a reference in your HTML
    // <script src="https://cdn.jsdelivr.net/gh/mingzilla/api-client-js@latest/api-client.js"></script>

NPM

npm install @mingzilla/api-client-js

Usage

Basic Request

// Make a simple GET request
ApiClient.send(ApiClientInput.get('https://api.example.com/data', {}))
  .then(response => {
    if (response.isSuccessful()) {
      const data = response.parseJsonBody();
      console.log('Response data:', data);
    } else {
      console.error('Request failed:', response.getFailureReason());
    }
  });

// POST with JSON body
const data = { name: 'Example', value: 42 };
ApiClient.send(ApiClientInput.postJson('https://api.example.com/data', data, {}))
  .then(response => {
    console.log('Status code:', response.statusCode);
    console.log('Response body:', response.body);
  });

Streaming Response

ApiClient.stream(
  ApiClientInput.get('https://api.example.com/stream', {}),
  () => console.log('Stream started'), // onStart
  (chunk) => console.log('Received chunk:', chunk), // onChunk
  (fullResponse) => console.log('Stream complete, full response:', fullResponse), // onFinish
  (error) => console.error('Stream error:', error.getFailureReason()) // onFailure
);

Chat Completions API (Regular Request)

// Create a chat input body
const chatBody = ApiClientInputBody.chat(
  'model-name', // Model identifier
  [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Hello, how are you?' }
  ],
  false, // Not streaming
  0.7 // Temperature
);

// Send the chat request
ApiClient.send(ApiClientInput.chat('https://api.example.com/chat/completions', chatBody, {}))
  .then(response => {
    if (response.isSuccessful()) {
      const data = response.parseJsonBody();
      console.log('Assistant response:', data.message.content);
    } else {
      console.error('Chat request failed:', response.getFailureReason());
    }
  });

Chat Completions API (JSON Streaming)

// Create a streaming chat input body
const streamingChatBody = ApiClientInputBody.chat(
  'model-name', // Model identifier
  [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Write a short poem about coding.' }
  ],
  true, // Enable streaming
  0.7 // Temperature
);

let fullResponse = '';

// Send the streaming chat request
ApiClient.stream(
  ApiClientInput.chat('https://api.example.com/chat/completions', streamingChatBody, {}),
  () => console.log('Chat stream started'), // onStart
  (chunk) => {
    try {
      // Each chunk is a JSON object with a message fragment
      const jsonChunk = JSON.parse(chunk);
      if (jsonChunk.message && jsonChunk.message.content) {
        const content = jsonChunk.message.content;
        fullResponse += content;
        console.log('Received content:', content);
      }
    } catch (e) {
      console.warn('Failed to parse chunk as JSON:', chunk);
    }
  }, // onChunk
  (response) => {
    console.log('Chat stream complete, full response:', fullResponse);
  }, // onFinish
  (error) => console.error('Chat stream error:', error.getFailureReason()) // onFailure
);

Chat Completions API (Server-Sent Events)

// Create an SSE chat input body (streaming is always enabled for SSE)
const sseChatBody = ApiClientInputBody.sse(
  'model-name', // Model identifier
  [
    { role: 'system', content: 'You are a helpful assistant.' },
    { role: 'user', content: 'Explain how SSE works.' }
  ],
  0.7 // Temperature
);

let sseResponse = '';
let eventSource = null;

// For SSE, we'll use the browser's EventSource API
function startSSEStream() {
  // First, prepare the request by converting the input body to JSON
  const requestBody = sseChatBody.toJsonObject();
  
  // Create URL with parameters for GET request
  const params = new URLSearchParams();
  params.append('request', JSON.stringify(requestBody));
  
  // Create and configure EventSource
  eventSource = new EventSource(`https://api.example.com/chat/sse?${params.toString()}`);
  
  // Handle incoming messages
  eventSource.onmessage = (event) => {
    if (event.data === '[DONE]') {
      console.log('SSE stream ended');
      eventSource.close();
      console.log('Complete SSE response:', sseResponse);
    } else {
      try {
        const jsonData = JSON.parse(event.data);
        if (jsonData.message && jsonData.message.content) {
          const content = jsonData.message.content;
          sseResponse += content;
          console.log('SSE chunk:', content);
        }
      } catch (e) {
        console.warn('Failed to parse SSE data:', event.data);
      }
    }
  };
  
  // Handle errors
  eventSource.onerror = (error) => {
    console.error('SSE error:', error);
    eventSource.close();
  };
}

// Start the SSE stream
startSSEStream();

// To stop the stream manually
function stopSSEStream() {
  if (eventSource) {
    eventSource.close();
    eventSource = null;
  }
}

Parallel Batch Requests

const requests = [
  ApiClientInput.get('https://api.example.com/data/1', {}),
  ApiClientInput.get('https://api.example.com/data/2', {}),
  ApiClientInput.get('https://api.example.com/data/3', {})
];

ApiClient.batchSendParallel(
  requests,
  () => console.log('Batch started'), // onStart
  (response) => console.log('Completed request:', response.statusCode), // onUnit
  (batchResult) => console.log('All requests complete:', batchResult.parseJsonBody()), // onFinished
  (error) => console.error('Batch error:', error.getFailureReason()) // onFailure
);

API Reference

ApiClientInputBody

Factory class for creating chat completion request bodies.

Static Methods

  • chat(model, messages, stream, temperature): Create a chat completion request body
  • sse(model, messages, temperature): Create an SSE chat completion request body
  • chatMessage(content, stream): Create a simple chat completion with a single user message

ApiClientInput

Factory class for creating HTTP request inputs.

Static Methods

  • create(method, url, body, headers): Create a request with specified parameters
  • get(url, headers): Create a GET request
  • post(url, body, headers): Create a POST request
  • put(url, body, headers): Create a PUT request
  • delete(url, headers): Create a DELETE request
  • patch(url, body, headers): Create a PATCH request
  • createJson(method, url, jsonObject, headers): Create a request with a JSON body
  • postJson(url, jsonObject, headers): Create a POST request with a JSON body
  • putJson(url, jsonObject, headers): Create a PUT request with a JSON body
  • patchJson(url, jsonObject, headers): Create a PATCH request with a JSON body
  • chat(url, inputBody, headers): Create a chat completions request

ApiClientOutput

Class representing HTTP response outputs with utility methods.

Properties

  • statusCode: HTTP status code
  • headers: Response headers
  • body: Response body as string
  • error: Error object if request failed

Methods

  • isSuccessful(): Returns true if request was successful (status 200-299)
  • getFailureReason(): Returns error message if request failed
  • getHeader(name): Get a specific header value
  • parseJsonBody(): Parse response body as JSON (returns null if invalid)
  • asMap(): Return response data as a convenient map

ApiClient

Static utility class for making HTTP requests.

Methods

  • send(input): Make an HTTP request
  • stream(input, onStart, onChunk, onFinish, onFailure): Make a streaming HTTP request
  • batchSendParallel(inputs, onStart, onUnit, onFinished, onFailure): Execute multiple requests in parallel
  • isDone(record): Determines if a stream is completed based on reader record from fetch API

License

MIT

Author

Ming Huang (mingzilla)

About

A lightweight, promise-based HTTP client for the browser with streaming support and batch processing capabilities.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 72.6%
  • HTML 15.5%
  • Shell 11.9%