Skip to content

Instantly share code, notes, and snippets.

View jtmthf's full-sized avatar

Jack Moore jtmthf

View GitHub Profile
# Revert test files that have one line modified
git diff --numstat \
| grep 'test.tsx' \
| awk '{ if($1==1 && $2==1) print $3 }' \
| xargs git checkout --
class MapKeySetView<T> implements Set<T> {
readonly #map: Map<T, unknown>;
constructor(map: Map<T, unknown>) {
this.#map = map;
}
get size() {
return this.#map.size;
}
type IterableRange = IterableIterator<number> & {
start: number;
end: number;
step: number;
};
function range(
startOrEnd: number,
maybeEnd?: number,
maybeStep?: number
export type ResolvedResult<T> = [error: null, value: T];
export type RejectedResult = [error: unknown, value: null];
export type Result<T> = ResolvedResult<T> | RejectedResult;
export function getResult<T>(promise: PromiseLike<T>): Promise<ResolvedResult<T> | RejectedResult> {
return Promise.resolve(promise)
.then(value => [null, value] as [null, T])
.catch(error => [error, null] as [unknown, null]);
}
import { RefObject, useEffect, useState } from 'react';
export function useLineCount(ref: RefObject<HTMLElement>): number {
const [lines, setLines] = useState(0);
useEffect(() => {
const resizeObserver = new ResizeObserver(entries => {
entries.forEach(entry => {
const elementHeight = (entry.target as HTMLElement).offsetHeight;
const lineHeight = parseInt(getComputedStyle(entry.target).lineHeight, 10);
import { useMemo } from "react";
import { Interpreter } from "xstate";
import { useService } from "@xstate/react";
export function useAllowedEvents(service: Interpreter<any>) {
const [state] = useService(service);
const allowedEvents = useMemo(
() =>
state.nextEvents.filter(
(event) => service.machine.transition(state, event).changed
import { useMemo } from "react";
import { Interpreter } from "xstate";
import { useService } from "@xstate/react";
export function useAllowedEvents(service: Interpreter<any>) {
const [state] = useService(service);
const allowedEvents = useMemo(
() =>
state.nextEvents.filter(
(event) => service.machine.transition(state, event).changed
import { EventObject, State, StateSchema, Typestate, createMachine, interpret } from 'xstate';
type MatchCase<
TContext,
TTypestate extends Typestate<TContext>,
TSV extends TTypestate['value'],
TResult
> = readonly [...TSV[], TResult];
// TODO:
if (!Symbol.observable) {
Symbol.observable = Symbol('observable')
}
export class Observable<T> {
readonly #subscriber: SubscriberFunction<T>;
constructor(subscriber : SubscriberFunction<T>) {
this.#subscriber = subscriber;
}
import { useState, useEffect, Dispatch, SetStateAction } from 'react';
import { createContainer } from 'react-tracked';
import { ActionFunction, EventObject, MachineOptions } from 'xstate';
function createUseRegister<V extends object, T>(key: keyof V, useUpdate: () => Dispatch<SetStateAction<V>>) {
return function useRegister(name: string, value: T) {
const setState = useUpdate();
useEffect(() => {
setState((options) => ({