Skip to content

Instantly share code, notes, and snippets.

import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.isActive
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock
import kotlin.time.Duration
@tlux
tlux / use-has-overflow.ts
Created January 3, 2025 18:05
React hook to detect overflow on a ref
import { type RefObject, useEffect, useState } from 'react';
function checkOverflow(el: HTMLElement | null): boolean {
if (!el) return false;
return el.offsetHeight < el.scrollHeight || el.offsetWidth < el.scrollWidth;
}
export function useHasOverflow(ref: RefObject<HTMLElement | null>) {
const [overflow, setOverflow] = useState(false);
@tlux
tlux / use-file.ts
Created December 17, 2024 20:46
React hook to trigger file selection dialog
import { useCallback, useEffect, useRef, useState } from 'react';
function wrapArray<T>(value: T | T[]): T[] {
return Array.isArray(value) ? value : [value];
}
type UseFileOnSelectCallbackArg<TMultiple extends boolean | undefined> =
TMultiple extends true ? FileList : File;
type UseFileOnSelectCallback<TMultiple extends boolean | undefined = false> = (
@tlux
tlux / use-download.ts
Created December 17, 2024 20:26
React hook to trigger a download of a Blob/File or MediaSource
import { useCallback } from 'react';
export function useDownload() {
return useCallback((obj: Blob | MediaSource, filename: string) => {
const url = URL.createObjectURL(obj);
const link = document.createElement('a');
link.href = url;
if (filename) {
@tlux
tlux / fix-nix.sh
Created November 27, 2024 14:05
Fix Nix after Mac OS update
#!/bin/bash
read -r -d '' INJECT << EOM
# Nix
if [ -e '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh' ]; then
. '/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh'
fi
# End Nix
EOM
@tlux
tlux / EnumTypeConverter.kt
Last active September 15, 2024 01:17
Hibernate Attibute Converter for Enums
abstract class EnumConverter<T : Enum<T>, V>(
private val entries: EnumEntries<T>,
private val dumpValue: (T) -> V
) : AttributeConverter<T, V> {
override fun convertToDatabaseColumn(enumValue: T?): V? {
return enumValue?.let { dumpValue(it) }
}
override fun convertToEntityAttribute(dbValue: V?): T? {
return dbValue?.let { value ->
@tlux
tlux / Duplicates.kt
Last active September 2, 2024 18:13
Kotlin extensions to find duplicates in an Iterable
/**
* Gets a set of duplicates in the given iterable.
*/
fun <T> Iterable<T>.duplicates(): Set<T> = duplicatesBy { it }
/**
* Gets a set of duplicates in the given iterable using the specified selector.
*/
fun <T, K> Iterable<T>.duplicatesBy(selector: (T) -> K): Set<K> =
groupingBy(selector).eachCount().filterValues { it > 1 }.keys.toSet()
@tlux
tlux / observable.ex
Last active August 14, 2024 17:55
Simple Elixir Observable using GenStage
defmodule Observable do
@moduledoc """
A module that provides creating an observible value that emits the values to
a stream.
"""
alias Observable.Server
defstruct [:producer, :consumer]
@tlux
tlux / FlowDedup.kt
Last active February 18, 2025 15:19
Kotlin Flow Dedup Extension Functions
package io.redigital.rebased.ext.flow
import arrow.core.None
import arrow.core.Option
import arrow.core.some
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.transform
fun <T> Flow<T>.dedup(): Flow<T> = dedupBy { it }
@tlux
tlux / FieldsOfType.ts
Last active October 3, 2023 15:27
Extract fields of a specific type from a Record in TypeScript
type AllowedFieldsWithType<TObj, TKey> = {
[K in keyof TObj]: TObj[K] extends TKey ? K : never;
};
export type FieldsOfType<T, K> = AllowedFieldsWithType<T, K>[keyof T];
// Usage Example:
//
// const obj = {
// foo: 'bar',