Skip to content

simwai/utils

Repository files navigation

@simwai/utils

Stop reinventing error handling and logging. Get type-safe, battle-tested utilities that work everywhere.

πŸš€ Quick Start

import utils from '@simwai/utils'

// Beautiful logging with colors and timestamps
utils.logger.log('Application started')
utils.logger.error('Something went wrong')

// Resilient operations with automatic retries
const result = await utils.retry.execute(async () => {
  const response = await fetch('/api/data')
  if (!response.ok) throw new Error('API failed')
  return response.json()
})

if (result.isOk()) {
  console.log('Success:', result.value)
} else {
  console.log('Failed after retries:', result.error)
}

Problems @simwai/utils Solves

❌ Manual retry logic scattered across your codebase

❌ Inconsistent error handling for async operations

❌ Plain console.log lacks context, colors, and timestamps

❌ Environment-specific bugs between Node.js and browser code

βœ… Standardized utilities with exponential backoff and type safety

βœ… Universal compatibility - one import works everywhere

βœ… Beautiful output with Dracula-inspired colors

βœ… Zero configuration - works perfectly out of the box

πŸ“¦ Installation

npm install @simwai/utils

🎯 Core Features

Cross-Platform Logging

import { ConsoleLogger } from '@simwai/utils'

const logger = new ConsoleLogger({ isTimeEnabled: true })
logger.log('Info message')     // Light gray with timestamp
logger.warn('Warning')         // Yellow
logger.error('Error occurred') // Red

File Logging (Node.js only)

import { FileLogger } from '@simwai/utils'

const fileLogger = new FileLogger({ logFilePath: './logs/app.log' })
fileLogger.error('Persistent error logging')

Intelligent Retry with Type Safety

import { Retry } from '@simwai/utils'

const retry = new Retry({
  timeout: 1000,      // Start with 1 second
  retries: 3,         // Try 3 times
  isExponential: true // 1s β†’ 2s β†’ 4s
})

// Type-safe results with neverthrow
const result = await retry.execute(async () => {
  // Your potentially failing operation
  return await riskyApiCall()
})

🌐 Browser Compatibility

Supported Environments:

  • βœ… Node.js 18+
  • βœ… Modern browsers (Chrome 80+, Firefox 72+, Safari 13+, Edge 80+)
  • βœ… ES2020+ environments
  • ❌ Internet Explorer (uses modern timer APIs)

Automatic Environment Detection:

  • Node.js: Uses native timers, includes FileLogger (~44KB + external deps)
  • Browser: Uses setTimeout, excludes FileLogger (~330KB self-contained)

πŸ“š API Reference

ConsoleLogger

interface ConsoleLoggerOptions {
  isTimeEnabled?: boolean  // Show timestamps (default: false)
}

const logger = new ConsoleLogger({ isTimeEnabled: true })
logger.log('message')    // Info level
logger.warn('message')   // Warning level
logger.error('message')  // Error level
logger.trace('message')  // Debug level

Retry

interface RetryOptions {
  timeout?: number        // Delay between retries (default: 125ms)
  retries?: number        // Max retry attempts (default: 4)
  isExponential?: boolean // Use exponential backoff (default: true)
}

const retry = new Retry(options)
const result = await retry.execute(operation, overrideOptions?)

Type-Safe Error Handling

// Results use neverthrow's Result type
if (result.isOk()) {
  // TypeScript knows this is your success type
  console.log(result.value)
} else {
  // TypeScript knows this is an Error
  console.error(result.error.message)
}

🎨 Dracula Color Palette

Consistent, beautiful colors across all environments:

  • 🀍 Log: #f8f8f2 (Light foreground)
  • 🟑 Warn: #f1fa8c (Yellow)
  • πŸ”΄ Error: #ff5555 (Red)
  • 🟣 Trace: #bd93f9 (Purple)

Bundle Size Considerations

Environment Size Dependencies Justification
Node.js ~44KB External Optimal - deps installed separately
Browser ~330KB Bundled Includes Luxon (dates) + Chalk (colors)

Why 330KB for browser?

  • Luxon (~200KB): Full-featured DateTime with timezone support
  • Chalk (~30KB): Cross-platform color support
  • Alternative: Use basic console.log if bundle size is critical

When to Use vs Alternatives

βœ… Use @simwai/utils when

  • Building libraries that work in Node.js AND browsers
  • Need consistent retry logic across projects
  • Want type-safe error handling
  • Prefer beautiful, structured logging

πŸ€” Consider alternatives when

  • Bundle size is absolutely critical (<50KB total)
  • Only need basic console.log functionality
  • Working in a single environment only
  • Have existing logging infrastructure
πŸ—οΈ Advanced: Cross-Platform Architecture

Intelligent Build System

@simwai/utils uses unbuild to create environment-specific builds:

build/
β”œβ”€β”€ node/           # Node.js optimized
β”‚   β”œβ”€β”€ index.cjs   # CommonJS format
β”‚   β”œβ”€β”€ index.mjs   # ESM format
β”‚   └── index.d.ts  # TypeScript definitions
└── browser/        # Browser optimized
    β”œβ”€β”€ index.mjs   # ESM only
    └── index.d.ts  # Browser-specific types

Package.json Conditional Exports:

{
  "exports": {
    ".": {
      "browser": "./build/browser/index.mjs",
      "node": {
        "require": "./build/node/index.cjs",
        "import": "./build/node/index.mjs"
      }
    }
  }
}

Runtime Detection:

  • Uses node:timers/promises in Node.js for optimal performance
  • Falls back to setTimeout in browsers automatically
  • FileLogger completely excluded from browser builds
πŸ”§ Development Stack

Built with modern tooling for quality and maintainability:

  • 🎨 XO: Strict linting with Prettier integration
  • πŸ“¦ unbuild: Cross-platform bundling with Rollup
  • πŸ”· TypeScript: Full type safety and modern features
  • πŸ§ͺ Ava: Fast test runner with TypeScript support
  • πŸ“‹ neverthrow: Functional error handling without exceptions

Ready to eliminate boilerplate and build more reliable applications?

npm install @simwai/utils

Built with ❀️ for developers who value reliability and great developer experience.

Packages

No packages published