
Security News
Software Engineering Daily Podcast: Feross on AI, Open Source, and Supply Chain Risk
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.
@ribbon-studios/js-utils
Advanced tools
Collection of generic javascript utilities curated by the Rainbow Cafe~
Collection of generic javascript utilities curated by the Ribbon Studios Team~
delayCreates 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
delay.fallbackThis 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
assertOn 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
}
assert.definedEnsures 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!');
}
neverCreates 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
retryRetries 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);
rfetchLightweight wrapper around fetch that automatically handles:
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; }
}
rfetch.getShorthand for GET requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for GET requests.
await rfetch.get<MyExpectedResponse>('https://ribbonstudios.com');
rfetch.putShorthand for PUT requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for PUT requests.
await rfetch.put<MyExpectedResponse>('https://ribbonstudios.com');
rfetch.postShorthand for POST requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for POST requests.
await rfetch.post<MyExpectedResponse>('https://ribbonstudios.com');
rfetch.patchShorthand for PATCH requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for PATCH requests.
await rfetch.patch<MyExpectedResponse>('https://ribbonstudios.com');
rfetch.deleteShorthand for DELETE requests.
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
// Shorthand for DELETE requests.
await rfetch.delete<MyExpectedResponse>('https://ribbonstudios.com');
rfetch.interceptors.requestUseful 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.request.add(interceptor); // Add the interceptor
rfetch.interceptors.request.remove(interceptor); // Remove the interceptor
rfetch.interceptors.request.clear(); // Clear all interceptors
rfetch.interceptors.rejectUseful for handling special cases when a failed request occurs
import { rfetch, type RibbonFetchError } from '@ribbon-studios/js-utils';
const interceptor = (url: URL, error: RibbonFetchError): RibbonFetchError | Promise<RibbonFetchError> => {
return error; // Return the modified error!
};
rfetch.interceptors.reject.add(interceptor); // Add the interceptor
rfetch.interceptors.reject.remove(interceptor); // Remove the interceptor
rfetch.interceptors.reject.clear(); // Clear all interceptors
rfetch.delimitersSpecifies 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'],
},
});
rfetch.is.errorA 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;
}
FAQs
Collection of generic javascript utilities curated by the Rainbow Cafe~
We found that @ribbon-studios/js-utils demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Socket CEO Feross Aboukhadijeh joins Software Engineering Daily to discuss modern software supply chain attacks and rising AI-driven security risks.

Security News
GitHub has revoked npm classic tokens for publishing; maintainers must migrate, but OpenJS warns OIDC trusted publishing still has risky gaps for critical projects.

Security News
Rust’s crates.io team is advancing an RFC to add a Security tab that surfaces RustSec vulnerability and unsoundness advisories directly on crate pages.