npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@embed-ai/sdk

v0.2.1

Published

The typescript sdk package for embed AI APIs.

Readme

Embed TypeScript

The core TypeScript package for embed APIs, featuring an Effect-based HTTP client with robust error handling and configurable retry logic for mbd.xyz API.

Features

  • 🚀 Effect-based HTTP client with structured error handling
  • 🔄 Configurable retry logic with exponential backoff
  • 🛡️ Type-safe error handling with tagged error types
  • ⏱️ Request timeouts with proper timeout handling
  • 🔐 Automatic authentication with Bearer tokens
  • 📝 All required headers set automatically
  • 📊 Built-in logging of failed requests and retries
  • 🎯 Selective retry logic for different error types

Installation

bun install @embed-ai/sdk effect

Note: effect is a peer dependency and must be installed alongside @embed-ai/sdk

Quick Start

Basic Usage

import { getClient } from "@embed-ai/sdk"
const client = getClient(process.env.API_KEY_EMBED)
const feed = await client.feed.byUserId("16085")
console.log("✅ Success we got:", feed.length, "items")

Error Handling Guide

The @embed-ai/sdk package provides comprehensive error handling with typed errors and automatic retries. Here's everything you need to know.

What Gets Retried Automatically

  • Network errors (connection failures, DNS issues)
  • Timeout errors (requests taking too long)
  • Server errors (500, 502, 503, 504 by default)
  • Rate limiting (429 when configured)
  • Parse errors (malformed JSON responses)
  • Client errors (4xx except when configured)

Basic Error Handling

For simple applications, basic try/catch is sufficient:

import { getClient } from "@embed-ai/sdk"

const client = getClient(process.env.API_KEY_EMBED)

try {
  const feed = await client.feed.byUserId("16085")
  return feed
} catch (error) {
  console.error("API request failed:", error)
  throw error // Re-throw or handle as needed
}

Understanding Error Types

The package exports four specific error types for structured error handling:

import {
  HttpRequestError,  // HTTP response errors (4xx, 5xx)
  NetworkError,      // Network connection issues
  TimeoutError,      // Request timeout errors
  ParseError         // JSON parsing errors
} from "@embed-ai/sdk"

Each error type contains rich information to help you understand and handle the issue:

// HttpRequestError - HTTP response errors
{
  status: 401,                    // HTTP status code
  statusText: "Unauthorized",     // Status text
  url: "https://api.mbd.xyz/...", // Request URL
  body: "Invalid API key"         // Response body (if available)
}

// NetworkError - Connection issues
{
  message: "Failed to fetch",     // Error description
  cause: Error                    // Original error
}

// TimeoutError - Request timeouts
{
  message: "Request timed out",   // Error description
  timeoutMs: 30000               // Timeout duration
}

// ParseError - JSON parsing issues
{
  message: "Failed to parse JSON", // Error description
  cause: SyntaxError              // Original parsing error
}

Basic Usage with Error Handling

import { getClient, HttpRequestError, NetworkError, TimeoutError } from "@embed-ai/sdk"

const client = getClient(process.env.API_KEY_EMBED)

try {
  const feed = await client.feed.byUserId("16085")
  console.log("✅ Success:", feed.length, "items")
} catch (error) {
  console.error("❌ Error:", error)
  
  // Handle specific error types
  if (error instanceof HttpRequestError) {
    console.error(`HTTP ${error.status}: ${error.statusText}`)
  } else if (error instanceof NetworkError) {
    console.error("Network connection failed")
  } else if (error instanceof TimeoutError) {
    console.error(`Request timed out after ${error.timeoutMs}ms`)
  }
}

Typed Error Handling

For production applications, use typed error handling for better control:

import { 
  getClient, 
  HttpRequestError, 
  NetworkError, 
  TimeoutError, 
  ParseError 
} from "@embed-ai/sdk"

const client = getClient(process.env.API_KEY_EMBED)

async function getFeedWithErrorHandling(userId: string) {
  try {
    return await client.feed.byUserId(userId)
  } catch (error) {
    if (error instanceof HttpRequestError) {
      switch (error.status) {
        case 401:
          throw new Error("Invalid API key - please check your credentials")
        case 403:
          throw new Error("Access denied - check your API permissions")
        case 404:
          throw new Error("User not found")
        case 429:
          throw new Error("Rate limit exceeded - please try again later")
        case 500:
        case 502:
        case 503:
        case 504:
          throw new Error("Server error - please try again later")
        default:
          throw new Error(`HTTP error ${error.status}: ${error.statusText}`)
      }
    } else if (error instanceof NetworkError) {
      throw new Error("Network connection failed - check your internet connection")
    } else if (error instanceof TimeoutError) {
      throw new Error(`Request timed out after ${error.timeoutMs}ms`)
    } else if (error instanceof ParseError) {
      throw new Error("Invalid response from server")
    } else {
      throw new Error("Unknown error occurred")
    }
  }
}

Custom Retry Configuration

Configure retry behavior for your specific needs:

import { getClient } from "@embed-ai/sdk"

const client = getClient(process.env.API_KEY_EMBED, {
  retry: {
    maxRetries: 5,                    // Max retry attempts
    initialDelay: 1000,               // Initial delay in ms
    exponentialBackoff: true,         // Use exponential backoff
    maxDelay: 15000,                  // Max delay between retries
    retryableStatusCodes: [429, 500, 502, 503, 504], // HTTP codes to retry
    timeoutMs: 60000                  // Request timeout in ms
  }
})

// Now all requests will use this retry configuration
const feed = await client.feed.byWalletAddress("0x123...")

What Happens When Retries Fail

When all retry attempts are exhausted, you receive the last error that occurred with full context:

try {
  const feed = await client.feed.byUserId("16085")
} catch (error) {
  // This error represents the final failure after all retries
  if (error instanceof HttpRequestError) {
    console.error(`Final HTTP error after retries: ${error.status}`)
    console.error(`Request URL: ${error.url}`)
    console.error(`Response body: ${error.body}`)
  } else if (error instanceof NetworkError) {
    console.error(`Final network error after retries: ${error.message}`)
  }
}

Error Flow:

  1. Request made → Network fails
  2. Retry 1 → Network fails
  3. Retry 2 → Network fails
  4. Retry 3 → Network fails
  5. Final errorNetworkError with original failure details

Error Handling Best Practices

1. Use Typed Error Handling in Production

// ✅ Good - Specific error handling
try {
  const feed = await client.feed.byUserId(userId)
} catch (error) {
  if (error instanceof HttpRequestError) {
    // Handle specific HTTP errors
  } else if (error instanceof NetworkError) {
    // Handle network issues
  }
}

// ❌ Avoid - Generic error handling
try {
  const feed = await client.feed.byUserId(userId)
} catch (error) {
  console.error("Something went wrong:", error) // Too generic
}

2. Provide User-Friendly Error Messages

function getUserFriendlyError(error: unknown): string {
  if (error instanceof HttpRequestError) {
    switch (error.status) {
      case 401: return "Please check your API key"
      case 429: return "Too many requests - please wait a moment"
      case 500: return "Server is temporarily unavailable"
      default: return "Something went wrong with the request"
    }
  } else if (error instanceof NetworkError) {
    return "Please check your internet connection"
  } else if (error instanceof TimeoutError) {
    return "Request took too long - please try again"
  }
  return "An unexpected error occurred"
}

3. Implement Cache Strategies

async function getFeedWithCache(userId: string) {
  try {
    return await client.feed.byUserId(userId)
  } catch (error) {
    if (error instanceof HttpRequestError && error.status === 404) {
      // User not found - return empty feed
      return []
    } else if (error instanceof NetworkError || error instanceof TimeoutError) {
      // Network issues - return cached data if available
      return getCachedFeed(userId) || []
    }
    throw error // Re-throw other errors
  }
}

4. Log Errors for Monitoring

import { getClient, HttpRequestError } from "@embed-ai/sdk"

const client = getClient(process.env.API_KEY_EMBED)

async function getFeedWithLogging(userId: string) {
  try {
    return await client.feed.byUserId(userId)
  } catch (error) {
    // Log error details for monitoring
    if (error instanceof HttpRequestError) {
      console.error("API Error:", {
        status: error.status,
        url: error.url,
        userId,
        timestamp: new Date().toISOString()
      })
    }
    throw error
  }
}

API Methods

Available Methods

// Get personalized "For You" feed by user ID
await client.feed.byUserId(userId: string, options?: FeedOptions)

// Get personalized "For You" feed by wallet address
await client.feed.byWalletAddress(walletAddress: string, options?: FeedOptions)

// Feed management to create new feeds and manage these custom feeds e.g. as custom feed per user in your app, which can be built on top of base feeds
await client.feed.createConfig(options: CreateFeedOptions)
await client.feed.getConfig(configId: string)
await client.feed.listConfigs(visibility?: "private" | "template" | "public")
await client.feed.updateConfig(options: UpdateFeedOptions)

Factory Function

import { getClient } from "@embed-ai/sdk"

// Create client with factory function
const client = getClient(process.env.API_KEY_EMBED, {
  retry: { maxRetries: 5 }
})

Why Effect?

  • Structured Error Handling: Type-safe error channels prevent runtime surprises
  • Composable: Chain and combine operations with powerful combinators
  • Reliable: Automatic retries handle transient failures gracefully
  • Observable: Built-in logging and tracing for debugging
  • Type-Safe: Full TypeScript support with inferred types