Files
yaak/src-web/hooks/useRequestEditor.tsx
Gregory Schier 44a331929f Enable type-aware linting and replace biome-ignore with oxlint-disable
- Enable typeAware option and no-explicit-any (error) in vite.config.ts
- Ignore generated binding files from linting
- Convert all 96 biome-ignore comments to oxlint-disable equivalents
- Add suppression comments for 3 previously uncovered any usages

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 08:24:45 -07:00

86 lines
2.2 KiB
TypeScript

import EventEmitter from 'eventemitter3';
import { atom, useAtom } from 'jotai';
import type { DependencyList } from 'react';
import { useCallback, useEffect } from 'react';
type EventDataMap = {
'request_params.focus_value': string;
'request_pane.focus_tab': undefined;
};
export function useRequestEditorEvent<
Event extends keyof EventDataMap,
Data extends EventDataMap[Event],
>(event: Event, fn: (data: Data) => void, deps?: DependencyList) {
useEffect(() => {
emitter.on(event, fn);
return () => {
emitter.off(event, fn);
};
// oxlint-disable-next-line react-hooks/exhaustive-deps -- We're handing deps manually
}, deps);
}
export const urlKeyAtom = atom<string>(Math.random().toString());
export const urlParamsKeyAtom = atom<string>(Math.random().toString());
export function useRequestEditor() {
const [urlParametersKey, setUrlParametersKey] = useAtom(urlParamsKeyAtom);
const [urlKey, setUrlKey] = useAtom(urlKeyAtom);
const focusParamsTab = useCallback(() => {
emitter.emit('request_pane.focus_tab', undefined);
}, []);
const focusParamValue = useCallback(
(name: string) => {
focusParamsTab();
requestAnimationFrame(() => emitter.emit('request_params.focus_value', name));
},
[focusParamsTab],
);
const forceUrlRefresh = useCallback(() => setUrlKey(Math.random().toString()), [setUrlKey]);
const forceParamsRefresh = useCallback(
() => setUrlParametersKey(Math.random().toString()),
[setUrlParametersKey],
);
return [
{
urlParametersKey,
urlKey,
},
{
focusParamValue,
focusParamsTab,
forceParamsRefresh,
forceUrlRefresh,
},
] as const;
}
const emitter = new (class RequestEditorEventEmitter {
#emitter: EventEmitter = new EventEmitter();
emit<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
event: Event,
data: Data,
) {
this.#emitter.emit(event, data);
}
on<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
event: Event,
fn: (data: Data) => void,
) {
this.#emitter.on(event, fn);
}
off<Event extends keyof EventDataMap, Data extends EventDataMap[Event]>(
event: Event,
fn: (data: Data) => void,
) {
this.#emitter.off(event, fn);
}
})();