
Security News
Deno 2.6 + Socket: Supply Chain Defense In Your CLI
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.
@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~
The npm package @ribbon-studios/js-utils receives a total of 43 weekly downloads. As such, @ribbon-studios/js-utils popularity was classified as not popular.
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
Deno 2.6 introduces deno audit with a new --socket flag that plugs directly into Socket to bring supply chain security checks into the Deno CLI.

Security News
New DoS and source code exposure bugs in React Server Components and Next.js: what’s affected and how to update safely.

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