Skip to content

Instantly share code, notes, and snippets.

View trvswgnr's full-sized avatar
:octocat:
hardly workin'

Travis Wagner trvswgnr

:octocat:
hardly workin'
View GitHub Profile
@trvswgnr
trvswgnr / run-concurrent-async.ts
Created July 17, 2023 09:34
generic concurrent execution
export async function runConcurrentAsync<T, A extends IterableIterator<unknown>>(tasks: Task<T>[], argsList: A[] = [], concurrency = 5): Promise<T[]> {
const semaphore = new Semaphore(concurrency);
const promises = tasks.map(async (task, index) => {
await semaphore.acquire();
try {
const args = argsList[index] || [];
return await task(...args);
} finally {
semaphore.release();
}
@trvswgnr
trvswgnr / fetch-all.ts
Created July 17, 2023 08:57
concurrent fetch with retry policy
export async function fetchAll(urls: string[], concurrency = 5, retryPolicy = defaultRetryPolicy): Promise<Response[]> {
const controller = new AbortController();
const semaphore = new Semaphore(concurrency);
const promises = urls.map(async url => {
await semaphore.acquire();
try {
return await fetchWithRetry(url, retryPolicy, controller.signal);
} catch (error) {
controller.abort(); // abort all requests on fatal error
throw error;
@trvswgnr
trvswgnr / find-array-given-subset-sums.rs
Last active June 24, 2023 00:10
Find Array Given Subset Sums
/*
You are given an integer n representing the length of an unknown array that you are trying to recover. You are also given an array sums containing the values of all 2n subset sums of the unknown array (in no particular order).
Return the array ans of length n representing the unknown array. If multiple answers exist, return any of them.
An array sub is a subset of an array arr if sub can be obtained from arr by deleting some (possibly zero or all) elements of arr. The sum of the elements in sub is one possible subset sum of arr. The sum of an empty array is considered to be 0.
Note: Test cases are generated such that there will always be at least one correct answer.
Constraints:
@trvswgnr
trvswgnr / proj10.py
Created December 1, 2022 06:45
proj10.py
from cards import Card, Deck
MENU ='''Prompt the user for an option and check that the input has the
form requested in the menu, printing an error message, if not.
Return:
TT s d: Move card from end of Tableau pile s to end of pile d.
TF s d: Move card from end of Tableau pile s to Foundation d.
WT d: Move card from Waste to Tableau pile d.
WF d: Move card from Waste to Foundation pile d.
SW : Move card from Stock to Waste.
@trvswgnr
trvswgnr / class-blacklist-item.php
Created June 25, 2022 05:45
Class for a valid blacklist item, i.e. a special string that is either a valid email address, IPv4 address, web domain, or country code.
<?php
class BlacklistItem {
private $value;
public function __construct($string) {
$string = trim($string);
if (self::isValid($string)) {
$this->value = $string;
} else {
throw new \InvalidArgumentException('$string must be a valid IP address, email, country, or web domain.');
@trvswgnr
trvswgnr / validate-file-inputs.js
Last active April 15, 2022 19:06
Add validation for file input fields using the accept and max input attributes
/**
* Convert a file size with unit to bytes
*
* @author Travis Aaron Wagner <[email protected]>
* @param {string} size File size with unit (e.g. 50MB)
* @returns {number} File size in bytes as number
*/
const getBytes = size => {
const matches = String(size).toLowerCase().replace(/[\s,]+/g, '').match(/([^a-z]+)([^\d.])/) || [];
return matches[2] ? matches[1] * (1024 ** ('kmgtpezy'.indexOf(matches[2]) + 1)) : Number(size);
@trvswgnr
trvswgnr / getfilesize.js
Last active April 15, 2022 20:13
Convert a file size with unit to another unit
/**
* Convert a file size with unit to bytes
*
* @author Travis Aaron Wagner <[email protected]>
* @param {string} size File size with unit (e.g. 50MB)
* @returns {number} File size in bytes as number
*/
const getBytes = size => {
const matches = size.toLowerCase().replace(/[\s,]+/g, '').match(/([^a-z]+)([^\d.])/) || [];
return matches[2] ? matches[1] * (1024 ** ('kmgtpezy'.indexOf(matches[2]) + 1)) : Number(size);
@trvswgnr
trvswgnr / bootstrap5-lightbox.html
Last active March 18, 2025 22:05
A Bootstrap 5 Lightbox example using only default included classes and components—no other JavaScript necessary.
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="row">
<a href="#" class="col-sm-4" data-bs-toggle="modal" data-bs-target="#exampleLightbox">
<img data-bs-target="#lightboxExampleCarousel" data-bs-slide-to="0" src="https://unsplash.it/200.jpg?image=250" class="img-fluid">
</a>
<a href="#" class="col-sm-4" data-bs-toggle="modal" data-bs-target="#exampleLightbox">
<img data-bs-target="#lightboxExampleCarousel" data-bs-slide-to="1" src="https://unsplash.it/200.jpg?image=251" class="img-fluid">
</a>
@trvswgnr
trvswgnr / Between.ts
Created September 21, 2021 10:55
TypeScript restrict range between two numbers type
type BuildPowersOf2LengthArrays<N extends number, R extends never[][]> =
R[0][N] extends never ? R : BuildPowersOf2LengthArrays<N, [[...R[0], ...R[0]], ...R]>;
type ConcatLargestUntilDone<N extends number, R extends never[][], B extends never[]> =
B["length"] extends N ? B : [...R[0], ...B][N] extends never
? ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, B>
: ConcatLargestUntilDone<N, R extends [R[0], ...infer U] ? U extends never[][] ? U : never : never, [...R[0], ...B]>;
type Replace<R extends any[], T> = { [K in keyof R]: T }
@trvswgnr
trvswgnr / index.js
Last active June 11, 2021 20:55
Change "vh" and "vh" to account for browser top and bottom bars
/**
* Update CSS variables --vh and --vh to be accurate taking mobile browser address and bottom action bars into consideration.
*
* @author Travis Aaron Wagner <[email protected]>
*/
let wHSaved = Math.min(window.innerHeight, window.outerHeight);
let wWSaved = Math.min(window.innerWidth, window.outerWidth);
/**