Collection of generic javascript utilities curated by the Ribbon Studios Team~
Creates a delayed promise for the given amount of seconds and given promises. This can be useful for allowing spinners / loading skeletons to exist for a bit rather then quickly popping in and out.
import { delay } from '@ribbon-studios/js-utils';
const promise = delay(); // Returns a promise with the preset delay
const promise = delay(1000); // Returns a promise with the given delay
const promise = delay(Promise.resolve('hello')); // Returns the original promise with the preset delay
const promise = delay(Promise.resolve('hello'), 1000); // Returns the original promise with the given delay
This overrides the default delay value
import { delay } from '@ribbon-studios/js-utils';
const promise = delay(); // Returns a promise with a delay of 500ms
delay.fallback(100);
const promise = delay(); // Returns a promise with a delay of 100ms
On its own assert isn't overly useful just because of how type assertion works.
import { assert } from '@ribbon-studios/js-utils';
export async function example() {
const promise: Promise<string | undefined> = Promise.resolve('hello');
// Run an assertion on the promises response
const assertedPromise: Promise<string | undefined> = assert(promise, (value) => typeof value !== 'undefined');
// Unfortunately our response is still considered undefined because we can't forward the assertion
}
Ensures the promise result is defined.
import { assert } from '@ribbon-studios/js-utils';
export async function example() {
const promise: Promise<string | undefined> = Promise.resolve('hello');
// Run an assertion on the promises response
const assertedPromise: Promise<string> = assert.defined(promise);
// Our promise is no longer considered undefined!
// You can also pass a message to throw!
const assertedPromise: Promise<string> = assert.defined(promise, 'Expected our thing to exist!');
}
Creates a promise that never resolves. Primary use-case for this is testing loading states.
In the event a promise is passed it will log a warning in the console as a reminder not to leave it in.
import { never } from '@ribbon-studios/js-utils';
const promise = never(); // Returns a promise that never resolves
const promise = never(Promise.resolve('hello')); // Returns a promise that never resolves
Retries a function n
times until it resolves successfully.
This can be useful for requests that tend to be flaky.
import { retry } from '@ribbon-studios/js-utils';
// Returns a promise that resolves when the request is successful or fails after its exceeded that maximum attempts.
const promise = retry(() => getMaps(), 5);
Lightweight wrapper around fetch that automatically handles:
- Query Params
- Form Data & JSON bodies
- JSON Responses (fallsback to text)
- Type Casting
- Errors
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
try {
const response = await rfetch<MyExpectedResponse>('https://ribbonstudios.com', {
params: {
hello: 'world',
},
body: {
hallo: 'welt',
},
});
console.log(response);
// => MyExpectedResponse
} catch (error: RibbonFetchError<MyExpectedErrorResponse>) {
console.error(error);
// => { status: number; content: MyExpectedErrorResponse; }
}
Shorthand for GET requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for GET requests.
await rfetch.get<MyExpectedResponse>('https://ribbonstudios.com');
Shorthand for PUT requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for PUT requests.
await rfetch.put<MyExpectedResponse>('https://ribbonstudios.com');
Shorthand for POST requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for POST requests.
await rfetch.post<MyExpectedResponse>('https://ribbonstudios.com');
Shorthand for PATCH requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for PATCH requests.
await rfetch.patch<MyExpectedResponse>('https://ribbonstudios.com');
Shorthand for DELETE requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for DELETE requests.
await rfetch.delete<MyExpectedResponse>('https://ribbonstudios.com');
Useful for enhancing requests with additional information
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
const interceptor = (url: URL, options: RequestInit): RequestInit | Promise<RequestInit> => {
return options; // Return the modified options!
};
rfetch.interceptors.add(interceptor); // Add the interceptor
rfetch.interceptors.remove(interceptor); // Remove the interceptor
rfetch.interceptors.clear(); // Clear all interceptors
Specifies which delimiters should be used.
import { rfetch, DelimiterType } from '@ribbon-studios/js-utils';
rfetch.delimiters(DelimiterType.DUPLICATE); // Use duplicate query params
// This is the default functionality
// https://ribbonstudios.com?hello=world&hello=welt
await rfetch.get('https://ribbonstudios.com', {
params: {
hello: ['world', 'welt'],
},
});
rfetch.delimiters(DelimiterType.COMMA); // Use comma separators
// https://ribbonstudios.com?hello=world,welt
await rfetch.get('https://ribbonstudios.com', {
params: {
hello: ['world', 'welt'],
},
});
A type guard that helps determine if the error is from a rfetch
response.
import { rfetch } from '@ribbon-studios/js-utils';
try {
await rfetch.get('https://ribbonstudios.com');
} catch (error: any) {
if (rfetch.is.error(error) && error.status === 404) {
// Do something!
}
throw error;
}