convex-helpers
Version:
A collection of useful code to complement the official convex package.
98 lines (97 loc) • 2.96 kB
JavaScript
/**
* asyncMap returns the results of applying an async function over an list.
*
* The list can even be a promise, or an iterable like a Set.
* @param list - Iterable object of items, e.g. an Array, Set, Object.keys
* @param asyncTransform
* @returns
*/
export async function asyncMap(list, asyncTransform) {
const promises = [];
let index = 0;
for (const item of await list) {
promises.push(asyncTransform(item, index));
index += 1;
}
return Promise.all(promises);
}
/**
* Filters out null elements from an array.
* @param list List of elements that might be null.
* @returns List of elements with nulls removed.
*/
export function pruneNull(list) {
return list.filter((i) => i !== null);
}
export class NullDocumentError extends Error {
}
/**
* Throws if there is a null element in the array.
* @param list List of elements that might have a null element.
* @returns Same list of elements with a refined type.
*/
export function nullThrows(doc, message) {
if (doc === null) {
throw new NullDocumentError(message ?? "Unexpected null document.");
}
return doc;
}
/**
* pick helps you pick keys from an object more concisely.
*
* e.g. `pick({a: v.string(), b: v.number()}, ["a"])` is equivalent to
* `{a: v.string()}`
* The alternative could be something like:
* ```js
* const obj = { a: v.string(), b: v.number() };
* // pick does the following
* const { a } = obj;
* const onlyA = { a };
* ```
*
* @param obj The object to pick from. Often like { a: v.string() }
* @param keys The keys to pick from the object.
* @returns A new object with only the keys you picked and their values.
*/
export const pick = (obj, keys) => {
return Object.fromEntries(Object.entries(obj).filter(([k]) => keys.includes(k)));
};
/**
* omit helps you omit keys from an object more concisely.
*
* e.g. `omit({a: v.string(), b: v.number()}, ["a"])` is equivalent to
* `{b: v.number()}`
*
* The alternative could be something like:
* ```js
* const obj = { a: v.string(), b: v.number() };
* // omit does the following
* const { a, ...rest } = obj;
* const withoutA = rest;
* ```
*
* @param obj The object to return a copy of without the specified keys.
* @param keys The keys to omit from the object.
* @returns A new object with the keys you omitted removed.
*/
export const omit = (obj, keys) => {
return Object.fromEntries(Object.entries(obj).filter(([k]) => !keys.includes(k)));
};
// Type utils:
const error = Symbol();
/**
* A utility for both compile-time type assertions and runtime assertions.
*
* @example
* ```ts
* // Compile-time assertion
* assert<Equals<1, 1>>();
* ```
* @param arg A value to assert the truthiness of.
*/
export function assert(arg) {
// no need to do anything! we're just asserting at compile time that the type
// parameter is true.
if (arg !== undefined && !arg)
throw new Error(`Assertion failed: ${arg}`);
}