Skip to content

Instantly share code, notes, and snippets.

View KrofDrakula's full-sized avatar

Klemen Slavič KrofDrakula

View GitHub Profile
@KrofDrakula
KrofDrakula / useRequest.ts
Last active December 6, 2023 19:18
An abortable React hook for making simple GET requests
import { useCallback, useEffect, useState } from 'react'
type UrlInput = Parameters<typeof fetch>[0]
type Overrides = {
fetch?: typeof fetch
onError?: (arg: unknown) => void
}
export const useRequest = <T>(url: UrlInput, overrides?: Overrides) => {
@KrofDrakula
KrofDrakula / README.md
Last active November 17, 2023 15:29
Scanning for usage of NPM packages

Run with deno:

deno task deps <path to source dir>
@KrofDrakula
KrofDrakula / abortable-fetch.ts
Created August 7, 2023 14:12
Abortable `fetch`
export const isAbortError = (err: unknown): err is Error =>
(err as Error)?.name == 'AbortError'
export const abortableFetch = (
url: RequestInfo | URL,
options?: RequestInit | undefined,
fetchImpl?: typeof fetch
): [promise: Promise<Response>, abort: (reason?: any) => void] => {
const controller = new AbortController()
options = { ...options, signal: controller.signal }
@KrofDrakula
KrofDrakula / extras.ts
Created December 14, 2022 15:00
`Map` and `Set` functional method extensions for convenience
interface Set<T> {
map: <V>(
this: Set<T>,
mapper: (this: Set<T>, value: T, index: number, set: Set<T>) => V
) => Set<V>;
filter: (
this: Set<T>,
predicate: (this: Set<T>, value: T, index: number, set: Set<T>) => boolean
) => Set<T>;
reduce: <V>(
@KrofDrakula
KrofDrakula / README.md
Last active February 24, 2022 09:54
Disabling autofill with standard and vendor workarounds

Strategies for disabling autofill prompts in browsers

This document gathers possible mitigation strategies when dealing with browser or extension provided autofill suggestions that impact usability of a given website's UI and UX.

You should apply the least amount of workaround you can get away with, since it could affect the accessibility of your website when taken too far. Always verify your application with your intended audience in mind.

Disabling autofill with standard HTML attributes

@KrofDrakula
KrofDrakula / interruptible_fetch.ts
Created January 6, 2022 08:24
Fetch with timeout and optional cancellation
export const fetchWithTimeout = (
uri: RequestInfo,
timeout: number,
options: RequestInit = {}
): [Promise<Response>, () => void] => {
const controller = new AbortController();
const timer = setTimeout(controller.abort, timeout);
const promise = fetch(uri, { ...options, signal: controller.signal });
promise.finally(() => clearTimeout(timer));
return [promise, controller.abort];
@KrofDrakula
KrofDrakula / async-example.tsx
Created December 22, 2021 13:48
An await component example
import { JSX } from 'preact';
import { useEffect, useState } from 'preact/hooks';
export const useAwait = <T,>(value: Promise<T>) => {
const [isFulfilled, setFulfilled] = useState<boolean>(false);
const [resolved, setResolved] = useState<T>(undefined);
const [rejected, setRejected] = useState<any>(undefined);
useEffect(() => {
// tslint:disable-next-line: no-floating-promises
@KrofDrakula
KrofDrakula / shortcuts.md
Created February 13, 2021 20:01
Talespire shortcuts

Navigation

Action Keys
move view around WASD / arrow keys / right click drag
rotate view middle mouse drag
zoom view scroll wheel

Interface

const SPECIAL_CHARS = /[-\/\\^$*+?.()|[\]{}]/g;
const ESCAPED_CHAR = "\\$&";
const escapeRegExp = (s: string) => s.replace(SPECIAL_CHARS, ESCAPED_CHAR);
const regexp = (flags?: string) =>
(strings: string[], ...values: string[]) =>
new RegExp(strings[0] + values.map((value, index) => escapeRegExp(value) + strings[index + 1]).join(""), flags);
@KrofDrakula
KrofDrakula / clone.ts
Created April 3, 2019 08:00
Just stashing a proof-of-concept
const isPrimitive = (obj) => {
if (typeof obj === 'number' || typeof obj === 'boolean' || typeof obj === 'string') return true;
if (Number.isNaN(obj) || obj === null || obj === undefined) return true;
return false;
}
const isIterable = (obj) => !isPrimitive(obj);
const clone = (obj) => {
if (isIterable(obj)) {