import { useEffect, RefObject } from "react";
const TABBABLE =
'a[href],button:not([disabled]),textarea:not([disabled]),input:not([disabled]),select:not([disabled]),[tabindex]:not([tabindex="-1"])';
export function useFocusTrap(
import { useState, useEffect } from 'react'
export function useDebounce<T>(value: T, delay: number = 500): T {
const [debouncedValue, setDebouncedValue] = useState<T>(value)
useEffect(() => {
import { createConsumer, Cable } from '@rails/actioncable'
let cable: Cable | null = null
export function getCable(): Cable {
if (!cable) {
import { readFileSync } from 'fs';
import { join } from 'path';
import Handlebars from 'handlebars';
import mjml2html from 'mjml';
import { htmlToText } from 'html-to-text';
import { useState, useMemo, useCallback } from 'react'
import { Post } from '@/types'
import { PostCard } from './PostCard'
interface FilteredPostsProps {
posts: Post[]
import { Injectable } from '@nestjs/common';
export interface RateLimitResult {
allowed: boolean;
remaining: number;
limit: number;
import { useEffect, useState, useRef } from 'react'
interface UseInViewOptions {
threshold?: number | number[]
rootMargin?: string
triggerOnce?: boolean
export class AppError extends Error {
public readonly statusCode: number;
public readonly code: string;
public readonly isOperational: boolean;
constructor(message: string, statusCode = 500, code = 'INTERNAL_ERROR', isOperational = true) {
export type CircuitState = "closed" | "open" | "half-open";
export interface CircuitBreakerOptions {
failureThreshold: number;
resetTimeout: number; // ms to wait in "open" before probing
onStateChange?: (from: CircuitState, to: CircuitState) => void;
import { ApplicationConfig } from '@angular/core';
import {
provideHttpClient,
withInterceptors,
} from '@angular/common/http';
import { retryInterceptor } from './retry.interceptor';
export type CheckResult = { name: string; status: 'up' | 'down'; durationMs: number; error?: string };
export type Check = () => Promise<void>;
function withTimeout(fn: Check, ms: number): Promise<void> {
return new Promise((resolve, reject) => {
const timer = setTimeout(() => reject(new Error(`timeout after ${ms}ms`)), ms);
import { useReducer } from 'react'
interface FormState {
values: Record<string, any>
errors: Record<string, string>
touched: Record<string, boolean>