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

@seaverse/utils-sdk

v0.1.1

Published

SeaVerse Utils SDK - Utility toolkit including file upload, image compression, and more

Readme

@seaverse/utils-sdk

SeaVerse Utils SDK - A utility toolkit including file upload, image compression, and more.

npm version License: MIT

Features

  • 📤 File Upload - Two-step upload with presigned URLs, secure and efficient
  • 🖼️ Image Compression - Auto compress to 1080p, configurable quality and dimensions
  • 📊 Upload Progress - Real-time progress callback with speed and remaining time
  • File Validation - Size and type validation
  • TypeScript - Complete type definitions
  • 🌍 Environment Config - Support for multiple environment switching

Installation

npm install @seaverse/utils-sdk
# or
pnpm add @seaverse/utils-sdk

Quick Start

Basic Usage

import { UtilsClient } from '@seaverse/utils-sdk';

// Initialize client
const client = new UtilsClient({
  token: 'your-bearer-token',
});

// Upload file
const file = document.querySelector('input[type="file"]').files[0];
const result = await client.uploadFile(file);

console.log('CDN URL:', result.cdnUrl);
console.log('File size:', result.fileSize);
console.log('Compressed:', result.compressed);

With Progress Callback

const result = await client.uploadFile(file, {
  onProgress: (progress) => {
    console.log(`Progress: ${progress.percent}%`);
    console.log(`Stage: ${progress.stage}`);
    console.log(`Speed: ${progress.speed} bytes/sec`);
    console.log(`Remaining time: ${progress.remainingTime} sec`);
  },
});

Disable Image Compression

const result = await client.uploadFile(file, {
  compress: false, // Disable compression
});

Custom Compression Config

const client = new UtilsClient({
  token: 'your-bearer-token',
  compress: {
    enabled: true,
    maxWidth: 1920,    // Custom max width
    maxHeight: 1080,   // Custom max height
    quality: 0.9,      // Custom compression quality
  },
});

API Reference

UtilsClient

Constructor

new UtilsClient(options: UtilsClientOptions)

Parameters:

  • token (string, required): Bearer Token
  • baseURL (string, optional): API base URL, default https://resource.seaverse.ai
  • timeout (number, optional): Request timeout (ms), default 60000
  • compress (CompressionConfig, optional): Image compression config

CompressionConfig:

  • enabled (boolean): Enable compression, default true
  • maxWidth (number): Max width, default 1080
  • maxHeight (number): Max height, default 1080
  • quality (number): Compression quality (0-1), default 0.8

uploadFile()

Upload file with automatic compression, validation, and upload flow.

async uploadFile(file: File, options?: UploadOptions): Promise<UploadResult>

Parameters:

  • file: File object to upload
  • options (optional):
    • onProgress: Progress callback function
    • compress: Whether to compress (overrides global config)
    • metadata: Custom metadata

Returns:

{
  fileName: string          // File name
  originalFileName: string  // Original file name
  cdnUrl: string           // CDN access URL
  objectPath: string       // Storage path
  fileSize: number         // File size (bytes)
  originalSize: number     // Original size (bytes)
  compressed: boolean      // Whether compressed
  contentType: string      // MIME type
  duration: number         // Upload duration (ms)
  expiresAt: string        // Expiration time
}

Errors:

  • Throws UtilsAPIError on failure

Example:

try {
  const result = await client.uploadFile(file, {
    onProgress: (progress) => {
      updateProgressBar(progress.percent);
    },
  });
  console.log('Upload successful:', result.cdnUrl);
} catch (error) {
  if (error instanceof UtilsAPIError) {
    console.error(`Upload failed [${error.code}]: ${error.message}`);
  }
}

setToken()

Update Bearer Token.

setToken(token: string): void

setBaseURL()

Update base URL.

setBaseURL(baseURL: string): void

updateCompressionConfig()

Update compression config.

updateCompressionConfig(config: Partial<CompressionConfig>): void

Utility Functions

validateFile()

Validate file size and type.

import { validateFile } from '@seaverse/utils-sdk';

const result = validateFile(file, {
  maxSize: 10 * 1024 * 1024,  // 10MB
  allowedTypes: ['image/jpeg', 'image/png'],
});

if (!result.valid) {
  console.error('Validation failed:', result.errors);
}

compressImage()

Manually compress image.

import { compressImage } from '@seaverse/utils-sdk';

const result = await compressImage(file, {
  maxWidth: 1920,
  maxHeight: 1080,
  quality: 0.8,
});

console.log('Compression ratio:', result.compressionRatio);
console.log('Compressed size:', result.compressedSize);

formatBytes()

Format bytes to human-readable string.

import { formatBytes } from '@seaverse/utils-sdk';

console.log(formatBytes(1024));       // "1 KB"
console.log(formatBytes(1048576));    // "1 MB"
console.log(formatBytes(1073741824)); // "1 GB"

Error Handling

import { UtilsAPIError, ErrorCode } from '@seaverse/utils-sdk';

try {
  const result = await client.uploadFile(file);
} catch (error) {
  if (error instanceof UtilsAPIError) {
    switch (error.code) {
      case ErrorCode.FILE_TOO_LARGE:
        alert('File too large, please select a file smaller than 100MB');
        break;
      case ErrorCode.INVALID_FILE_TYPE:
        alert('Unsupported file type');
        break;
      case ErrorCode.NETWORK_ERROR:
        alert('Network error, please check your connection');
        break;
      default:
        alert(`Upload failed: ${error.message}`);
    }
  }
}

Error Codes

| Error Code | Description | |------------|-------------| | FILE_TOO_LARGE | File size exceeds limit | | INVALID_FILE_TYPE | Unsupported file type | | PRESIGNED_URL_FAILED | Failed to get presigned URL | | UPLOAD_FAILED | Upload failed | | COMPRESSION_FAILED | Image compression failed | | NETWORK_ERROR | Network error | | TIMEOUT | Request timeout | | VALIDATION_FAILED | File validation failed |

Environment Configuration

The SDK provides predefined environment URLs:

import { UtilsClient, ENVIRONMENT_URLS } from '@seaverse/utils-sdk';

// Production environment (default)
const client = new UtilsClient({
  token: prodToken,
  // baseURL defaults to 'https://resource.seaverse.ai'
});

// Staging/Test environment
const stagingClient = new UtilsClient({
  baseURL: ENVIRONMENT_URLS.STAGING, // 'https://resource.sg.seaverse.dev'
  token: stagingToken,
});

// Local development
const localClient = new UtilsClient({
  baseURL: ENVIRONMENT_URLS.LOCAL, // 'http://localhost:8003'
  token: localToken,
});

Available Environment URLs

| Environment | URL | Constant | |-------------|-----|----------| | Production | https://resource.seaverse.ai | ENVIRONMENT_URLS.PRODUCTION | | Staging | https://resource.sg.seaverse.dev | ENVIRONMENT_URLS.STAGING | | Local | http://localhost:8003 | ENVIRONMENT_URLS.LOCAL |

Integration with Auth SDK

import { SeaVerseBackendAPIClient } from '@seaverse/auth-sdk';
import { UtilsClient } from '@seaverse/utils-sdk';

// 1. Login with Auth SDK
const authClient = new SeaVerseBackendAPIClient({
  appId: 'your-app-id',
});

const loginResult = await authClient.login({
  email: '[email protected]',
  password: 'password',
});

// 2. Initialize Utils SDK with the same token
const utilsClient = new UtilsClient({
  token: loginResult.token,
});

// 3. Upload file
const result = await utilsClient.uploadFile(file);

Upload Flow

The SDK uses presigned URL two-step upload mode:

1. Get presigned URL
   POST /api/v1/resources/presign-upload
   → Returns upload_url and cdn_url

2. Upload to GCS
   PUT {upload_url}
   → Direct upload to Google Cloud Storage

3. Return CDN URL
   Use cdn_url to access the file

Advantages:

  • ✅ Secure: Token not exposed to third-party storage
  • ✅ Efficient: Direct upload to GCS, no backend proxy
  • ✅ Reliable: GCS provides high availability guarantee

Image Compression

Compression Strategy

  • Max size: 1080×1080 pixels (default config)
  • Maintains aspect ratio with auto scaling
  • Configurable compression quality (0-1)
  • Supports custom max width/height (maxWidth, maxHeight)

Compression Trigger Conditions

Compression only occurs when all conditions are met:

  1. File is an image type (MIME type starts with image/)
  2. Compression is enabled (compress.enabled === true)
  3. Not explicitly disabled in upload options (options.compress !== false)

Skip Compression

// Method 1: Disable globally
const client = new UtilsClient({
  token: 'xxx',
  compress: { enabled: false },
});

// Method 2: Disable for single upload
const result = await client.uploadFile(file, {
  compress: false,
});

FAQ

Q1: How to get token?

A: Get Bearer Token by logging in with @seaverse/auth-sdk

Q2: What file types are supported?

A:

  • Images: JPEG, PNG, GIF, WebP
  • Documents: PDF, TXT, MD
  • Others: Depends on backend configuration

Q3: What's the file size limit?

A:

  • Default limit: 100MB
  • Can be customized via validation rules
  • Images are auto-compressed to reduce transfer size

Q4: How to handle upload failures?

A:

try {
  await client.uploadFile(file);
} catch (error) {
  if (error instanceof UtilsAPIError) {
    // Handle based on error code
    if (error.code === ErrorCode.NETWORK_ERROR) {
      // Retry logic
    }
  }
}

Q5: Does compression affect image quality?

A:

  • Default quality is 0.8, balancing file size and image quality
  • Adjustable via quality parameter (0-1)
  • Recommended range: 0.7-0.9

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Development mode
pnpm dev

# Type check
pnpm typecheck

License

MIT © SeaVerse Team

Changelog

v0.1.0 (2026-01-07)

  • 🎉 Initial release
  • ✨ Support file upload (presigned URL mode)
  • ✨ Support auto image compression (1080p)
  • ✨ Support upload progress callback
  • ✨ Support file validation
  • ✨ Complete TypeScript type definitions