Mirror of https://github.com/roostorg/coop github.com/roostorg/coop
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 111 lines 3.3 kB view raw
1import { setTimeout as setTimeoutPromise } from 'node:timers/promises'; 2 3export function filterNullOrUndefined<T>( 4 array: T[], 5): Exclude<T, null | undefined>[]; 6export function filterNullOrUndefined<T>( 7 array: readonly T[], 8): readonly Exclude<T, null | undefined>[]; 9export function filterNullOrUndefined<T>(array: readonly T[]) { 10 return array.filter( 11 (it): it is Exclude<T, null | undefined> => it !== null && it !== undefined, 12 ); 13} 14 15export function moveArrayElement<T>( 16 array: T[], 17 fromIndex: number, 18 toIndex: number, 19) { 20 if ( 21 fromIndex === toIndex || 22 fromIndex < 0 || 23 toIndex < 0 || 24 fromIndex >= array.length || 25 toIndex >= array.length 26 ) { 27 return array.slice(); 28 } 29 30 const element = array[fromIndex]; // Get the element at the original index 31 const newArray = array.slice(0, fromIndex).concat(array.slice(fromIndex + 1)); // Remove the element from the original index 32 newArray.splice(toIndex, 0, element); // Insert the element at the new index 33 return newArray; 34} 35 36export async function asyncIterableToArray<T>( 37 it: AsyncIterable<T>, 38): Promise<T[]> { 39 const result = []; 40 for await (const x of it) { 41 result.push(x); 42 } 43 return result; 44} 45 46/** 47 * Gets an iterator from the given iterable and iterates it until the timeout is 48 * hit, at which point it returns an array of all the items that have been 49 * yielded up until that moment. When the timeout is hit, it also calls return() 50 * on the iterator to signal disinterest in further consumption. 51 */ 52export async function asyncIterableToArrayWithTimeout<T>( 53 it: AsyncIterable<T>, 54 timeoutMs: number, 55): Promise<T[]> { 56 const items: T[] = []; 57 let timeoutReached = false; 58 59 const timeoutPromise = setTimeoutPromise(timeoutMs).then(() => { 60 timeoutReached = true; 61 }); 62 63 const itemsIterationPromise = (async () => { 64 for await (const item of it) { 65 items.push(item); 66 67 // Once timeout's reached, stop awaiting more items. This will implicitly 68 // call iterator.return() to let the iterator know we're done consuming. 69 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 70 if (timeoutReached) { 71 break; 72 } 73 } 74 })(); 75 76 await Promise.race([timeoutPromise, itemsIterationPromise]); 77 return items; 78} 79 80/** 81 * Same as above, except this function also takes a limit to the number of items 82 * the caller wants, and returns as soon as that limit is reached. 83 */ 84export async function asyncIterableToArrayWithTimeoutAndLimit<T>( 85 it: AsyncIterable<T>, 86 timeoutMs: number, 87 limit: number, 88): Promise<T[]> { 89 const items: T[] = []; 90 let timeoutReached = false; 91 92 const timeoutPromise = setTimeoutPromise(timeoutMs).then(() => { 93 timeoutReached = true; 94 }); 95 96 const itemsIterationPromise = (async () => { 97 for await (const item of it) { 98 items.push(item); 99 100 // Once timeout's reached or the limit is reached, stop awaiting more items. This will implicitly 101 // call iterator.return() to let the iterator know we're done consuming. 102 // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition 103 if (timeoutReached || items.length >= limit) { 104 break; 105 } 106 } 107 })(); 108 109 await Promise.race([timeoutPromise, itemsIterationPromise]); 110 return items; 111}