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 🙏

© 2024 – Pkg Stats / Ryan Hefner

@dukeferdinand/ts-utils

v1.3.2

Published

A collection of typed utils and classes geared towards my own use

Downloads

24

Readme

@dukeferdinand/ts-utils

Build Status Maintainability Test Coverage

Welcome to my library!

If you're reading this you're probably looking for a small, easy to use library without a lot of frills, and with first class TypeScript support.

If so, you're in the right place!

What's included

So far, not a lot. But what is included is rock solid and tested to hell and back :)

sync utils

  • clone<T>(data: T): T -> adds proper typing to the standard JSON.parse(JSON.stringify(DATA)) pattern for cloning data in memory
  • toString(data: any): string -> Slightly more user friendly JSON.stringify that primarily acts as a wrapper while disallowing functions (personal choice)
  • wrapped<T, E extends Error, F extends Function>(fn: F): () => Result<T, E> -> this one is a heavy hitter. It builds off of my other library @dukeferdinand/ts-results and acts as a synchronous error wrapper for any function that may or may not fail

async utils

  • asyncWrapped<T, E extends Error, F extends Function>(fn: F): () => Promise<Result<T, E>> -> This one is pretty much just the async version of the previous wrapped util. It allows you to await a fallible function and gives you an Ok or Err response from whatever function you put in

fetch util

  • smartFetch -> see code block below for full type declaration (it's long). This builds directly off of something I've use in production environments for critical internal systems. It's basically the same approach as the asyncWrapped util, but it adds a LOT more good stuff directly geared towards HTTP requests. You can use it almost 100% as a replacement for fetch because it's just a wrapper that catches and labels errors and ok values alike. I say almost as there's probably some edge case I won't ever run into in my typical use cases, but feel free to open an issue and I'll add it in.

Here's the main declaration as promised! See the main fetch namespace for more technical details and types.

smartFetch<T, E>(
  method: RequestMethods, url: string, body?: any, config: GlobalConfig = {}
): Promise<Result<T, E>>

Here's a basic flow chart for how to use smartFetch:

  1. Init your global config if needed:

import { SmartFetch } from '@dukeferdinand/ts-utils'

// Optionally destructure here
SmartFetch.initSmartFetch({
  baseUrl: 'https://yourcompany.com'
})
  1. Make a request, get your data!
const {RequestMethods} = SmartFetch

interface YourExpectedData {
  data: string;
  username: string;
}

interface YourCustomError {
  error: string;
  code: number;
  reason: string;
}

const res =
  await SmartFetch.smartFetch<YourExpectedData, YourCustomError>(RequestMethods.GET,'/get-route')

if (res.isOk()) {
  // Use your data
  return res.unwrap() // -> YourExpectedData
} else {
  // Handle your error
  return res.unwrapErr() // -> YourCustomError
}
  1. Optionally, if your API returns something with a non standard HTTP error (i.e. a 200 can still be an error), create a custom handler. Your custom handler will be passed a res variable, which is anything that can possibly be returned to your app, but NOT a normal HTTP error, see the main fetch namespace for more technical details. This is mainly because the error checking is fairly generic and only really checks res.ok before parsing anything as json.
// Mock example to catch any response with an 'error' key, but only if 'error' is not an empty string
function shouldThrow(res: { [index: string]: any }) {
  if (Object.keys(res).includes('error') && res.error !== '') {
    return true
  }
  return false
}

// Break because error is not an empty string
const shouldError = await SmartFetch.smartFetch(RequestMethods.GET, '/bad-route', null, {
  shouldThrow
})