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

@seaspark/utils-sdk

v0.1.0

Published

SeaSpark Utils SDK - 通用工具集合,包含文件上传、图片压缩等功能

Downloads

8

Readme

@seaspark/utils-sdk

SeaVerse Utils SDK - Collection of utility tools 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 - Automatic compression to 1080p, configurable quality and dimensions
  • 📊 Upload Progress - Real-time progress callbacks with speed and remaining time calculation
  • File Validation - Size and type validation
  • TypeScript - Complete type definitions
  • 🌍 Environment Support - Multi-environment configuration

Installation

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

Quick Start

Basic Usage

import { UtilsClient } from '@seaspark/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 Configuration

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://seaspark-resource-hub.dev.seaspark.ai
  • timeout (number, optional): Request timeout (milliseconds), default 60000
  • compress (CompressionConfig, optional): Image compression configuration

CompressionConfig:

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

uploadFile()

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

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 configuration)
    • 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 (milliseconds)
  expiresAt: string        // Expiration time
}

Errors:

  • Throws UtilsAPIError exception

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 configuration.

updateCompressionConfig(config: Partial<CompressionConfig>): void

Utility Functions

validateFile()

Validate file size and type.

import { validateFile } from '@seaspark/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 images.

import { compressImage } from '@seaspark/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 readable string.

import { formatBytes } from '@seaspark/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 '@seaspark/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

Different environments use different baseURLs:

// Development environment (default)
const client = new UtilsClient({
  token: devToken,
  // baseURL defaults to 'https://seaspark-resource-hub.dev.seaspark.ai'
});

// Production environment
const client = new UtilsClient({
  baseURL: 'https://resource.sg.seaverse.dev',
  token: prodToken,
});

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

Integration with Auth SDK

import { SeaVerseBackendAPIClient } from '@seaspark/auth-sdk';
import { UtilsClient } from '@seaspark/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 same token
const utilsClient = new UtilsClient({
  token: loginResult.token,
});

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

Upload Flow Description

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 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 Details

Compression Strategy

  • Maximum dimensions: 1080×1080 pixels (default configuration)
  • Maintains aspect ratio with automatic scaling
  • Configurable compression quality (0-1)
  • Supports custom max width/height (maxWidth, maxHeight)

Compression Trigger Conditions

Compression only occurs when all of the following conditions are met:

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

Skip Compression

// Method 1: Globally disable
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 a token?

A: Login via @seaspark/auth-sdk to get Bearer Token

Q2: What file types are supported?

A:

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

Q3: Upload file size limit?

A:

  • Default limit: 100MB
  • Can customize via validation rules
  • Images are automatically 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 quality
  • Can adjust via quality parameter (0-1)
  • Recommended value: 0.7-0.9

Development

# Install dependencies
pnpm install

# Build
pnpm build

# Development mode
pnpm dev

# Type checking
pnpm typecheck

License

MIT © SeaSpark Team

Changelog

v0.1.0 (2026-01-07)

  • 🎉 Initial release
  • ✨ File upload support (presigned URL mode)
  • ✨ Automatic image compression (1080p)
  • ✨ Upload progress callbacks
  • ✨ File validation support
  • ✨ Complete TypeScript type definitions