Execute oxfmt (#1166)

Ran
pnpm oxfmt .

This should get the web repo aligned so that we can better enforce oxfmt going forward.
This commit is contained in:
Austin
2026-06-16 20:30:08 -04:00
committed by GitHub
parent c5690d1edb
commit d2cb51d489
378 changed files with 5548 additions and 1974 deletions
+19 -4
View File
@@ -8,7 +8,10 @@ export { MeshRegistryContext } from "./src/provider/MeshRegistryContext.ts";
export { useClient } from "./src/adapters/useClient.ts";
export { useClientById } from "./src/adapters/useClientById.ts";
export { useActiveClient } from "./src/adapters/useActiveClient.ts";
export { useMeshRegistry, useOptionalMeshRegistry } from "./src/adapters/useMeshRegistry.ts";
export {
useMeshRegistry,
useOptionalMeshRegistry,
} from "./src/adapters/useMeshRegistry.ts";
export { useSignal } from "./src/adapters/useSignal.ts";
export { useSignalValue } from "./src/adapters/useSignalValue.ts";
@@ -22,14 +25,26 @@ export { useDirectChat } from "./src/hooks/useDirectChat.ts";
export type { UseDirectChatResult } from "./src/hooks/useDirectChat.ts";
export { useDraft } from "./src/hooks/useDraft.ts";
export type { UseDraftResult } from "./src/hooks/useDraft.ts";
export { useHasNodeError, useNodeError, useNodeErrors } from "./src/hooks/useNodeError.ts";
export {
useHasNodeError,
useNodeError,
useNodeErrors,
} from "./src/hooks/useNodeError.ts";
export { useNodes } from "./src/hooks/useNodes.ts";
export { useNode } from "./src/hooks/useNode.ts";
export { useChannels, useChannel } from "./src/hooks/useChannels.ts";
export { useConfig, useIsRegionUnset, useModuleConfig } from "./src/hooks/useConfig.ts";
export {
useConfig,
useIsRegionUnset,
useModuleConfig,
} from "./src/hooks/useConfig.ts";
export { useConfigEditor } from "./src/hooks/useConfigEditor.ts";
export { useConnectionProgress } from "./src/hooks/useConnectionProgress.ts";
export { useTotalUnread, useUnreadByKey, useUnreadCount } from "./src/hooks/useUnread.ts";
export {
useTotalUnread,
useUnreadByKey,
useUnreadCount,
} from "./src/hooks/useUnread.ts";
export { useTelemetry } from "./src/hooks/useTelemetry.ts";
export type { UseTelemetryResult } from "./src/hooks/useTelemetry.ts";
export { usePosition } from "./src/hooks/usePosition.ts";
+37 -37
View File
@@ -2,51 +2,25 @@
"name": "@meshtastic/sdk-react",
"version": "1.0.0",
"description": "React hooks + provider for @meshtastic/sdk. Signal-backed reactive state exposed as idiomatic hooks.",
"exports": {
".": "./mod.ts"
},
"type": "module",
"main": "./dist/mod.js",
"module": "./dist/mod.js",
"types": "./dist/mod.d.ts",
"license": "GPL-3.0-only",
"repository": {
"type": "git",
"url": "git+https://github.com/meshtastic/web.git",
"directory": "packages/sdk-react"
},
"tsdown": {
"entry": "mod.ts",
"platform": "neutral",
"target": "esnext",
"dts": true,
"format": [
"esm"
],
"splitting": false,
"sourcemap": false,
"minify": false,
"treeshake": true,
"report": false,
"clean": true
},
"jsrInclude": [
"mod.ts",
"src",
"README.md",
"LICENSE"
],
"jsrExclude": [
"src/**/*.test.ts",
"src/**/*.test.tsx",
"tests"
],
"files": [
"package.json",
"README.md",
"LICENSE",
"dist"
],
"type": "module",
"main": "./dist/mod.js",
"module": "./dist/mod.js",
"types": "./dist/mod.d.ts",
"exports": {
".": "./mod.ts"
},
"scripts": {
"preinstall": "npx only-allow pnpm",
"prepack": "cp ../../LICENSE ./LICENSE",
@@ -59,14 +33,40 @@
"@meshtastic/sdk": "workspace:*",
"better-result": "^2.9.2"
},
"peerDependencies": {
"react": "^18 || ^19"
},
"devDependencies": {
"@testing-library/react": "^16.0.0",
"@types/react": "^19.2.17",
"jsdom": "^29.1.1",
"react": "^19.2.7",
"react-dom": "^19.2.7"
}
},
"peerDependencies": {
"react": "^18 || ^19"
},
"tsdown": {
"clean": true,
"dts": true,
"entry": "mod.ts",
"format": [
"esm"
],
"minify": false,
"platform": "neutral",
"report": false,
"sourcemap": false,
"splitting": false,
"target": "esnext",
"treeshake": true
},
"jsrExclude": [
"src/**/*.test.ts",
"src/**/*.test.tsx",
"tests"
],
"jsrInclude": [
"mod.ts",
"src",
"README.md",
"LICENSE"
]
}
+5 -1
View File
@@ -15,7 +15,11 @@ export function useClient(): MeshClient {
const direct = useContext(MeshContext);
const registry = useContext(MeshRegistryContext);
const active = useSignal(
registry?.active ?? { value: undefined, peek: () => undefined, subscribe: () => () => {} },
registry?.active ?? {
value: undefined,
peek: () => undefined,
subscribe: () => () => {},
},
);
const client = direct ?? active;
if (!client) {
@@ -5,7 +5,9 @@ import { MeshRegistryContext } from "../provider/MeshRegistryContext.ts";
export function useMeshRegistry(): MeshRegistry {
const registry = useContext(MeshRegistryContext);
if (!registry) {
throw new Error("useMeshRegistry must be called inside a <MeshRegistryProvider>.");
throw new Error(
"useMeshRegistry must be called inside a <MeshRegistryProvider>.",
);
}
return registry;
}
@@ -6,8 +6,14 @@ import { useCallback, useSyncExternalStore } from "react";
* returning. The selector should be stable; memoize it with `useCallback` in
* the caller when it closes over changing values.
*/
export function useSignalValue<T, U>(sig: ReadonlySignal<T>, select: (value: T) => U): U {
export function useSignalValue<T, U>(
sig: ReadonlySignal<T>,
select: (value: T) => U,
): U {
const getSnapshot = useCallback(() => select(sig.value), [sig, select]);
const getServerSnapshot = useCallback(() => select(sig.peek()), [sig, select]);
const getServerSnapshot = useCallback(
() => select(sig.peek()),
[sig, select],
);
return useSyncExternalStore(sig.subscribe, getSnapshot, getServerSnapshot);
}
+4 -1
View File
@@ -20,7 +20,10 @@ export function useChat(channel: ChannelNumber): UseChatResult {
const client = useClient();
const sig = useMemo(() => client.chat.messages(channel), [client, channel]);
const messages = useSignal(sig);
const send = useCallback((input: SendTextInput) => client.chat.send(input), [client]);
const send = useCallback(
(input: SendTextInput) => client.chat.send(input),
[client],
);
const loadOlder = useCallback(
(before: Date, limit?: number) => {
const conv: ConversationKey = { kind: "channel", channel };
+10 -2
View File
@@ -1,4 +1,9 @@
import type { ConversationKey, Message, SendTextError, SendTextInput } from "@meshtastic/sdk";
import type {
ConversationKey,
Message,
SendTextError,
SendTextInput,
} from "@meshtastic/sdk";
import type { ResultType } from "better-result";
import { useCallback, useMemo } from "react";
import { useClient } from "../adapters/useClient.ts";
@@ -20,7 +25,10 @@ export function useDirectChat(peer: number): UseDirectChatResult {
const client = useClient();
const sig = useMemo(() => client.chat.direct(peer), [client, peer]);
const messages = useSignal(sig);
const send = useCallback((input: SendTextInput) => client.chat.send(input), [client]);
const send = useCallback(
(input: SendTextInput) => client.chat.send(input),
[client],
);
const loadOlder = useCallback(
(before: Date, limit?: number) => {
const conv: ConversationKey = { kind: "direct", peer };
+8 -2
View File
@@ -15,13 +15,19 @@ export interface UseDraftResult {
*/
export function useDraft(conv: ConversationKey): UseDraftResult {
const client = useClient();
const sig = useMemo(() => client.chat.drafts.get(conv), [client, conv.kind, keyOf(conv)]);
const sig = useMemo(
() => client.chat.drafts.get(conv),
[client, conv.kind, keyOf(conv)],
);
const text = useSignal(sig);
const setText = useCallback(
(value: string) => client.chat.drafts.set(conv, value),
[client, conv],
);
const clear = useCallback(() => client.chat.drafts.clear(conv), [client, conv]);
const clear = useCallback(
() => client.chat.drafts.clear(conv),
[client, conv],
);
return { text, setText, clear };
}
@@ -5,11 +5,13 @@ import { useClient } from "../adapters/useClient.ts";
export function useFavoriteNode() {
const client = useClient();
const favorite = useCallback(
(nodeNum: number): Promise<ResultType<number, Error>> => client.nodes.favorite(nodeNum),
(nodeNum: number): Promise<ResultType<number, Error>> =>
client.nodes.favorite(nodeNum),
[client],
);
const unfavorite = useCallback(
(nodeNum: number): Promise<ResultType<number, Error>> => client.nodes.unfavorite(nodeNum),
(nodeNum: number): Promise<ResultType<number, Error>> =>
client.nodes.unfavorite(nodeNum),
[client],
);
return { favorite, unfavorite };
@@ -5,11 +5,13 @@ import { useClient } from "../adapters/useClient.ts";
export function useIgnoreNode() {
const client = useClient();
const ignore = useCallback(
(nodeNum: number): Promise<ResultType<number, Error>> => client.nodes.ignore(nodeNum),
(nodeNum: number): Promise<ResultType<number, Error>> =>
client.nodes.ignore(nodeNum),
[client],
);
const unignore = useCallback(
(nodeNum: number): Promise<ResultType<number, Error>> => client.nodes.unignore(nodeNum),
(nodeNum: number): Promise<ResultType<number, Error>> =>
client.nodes.unignore(nodeNum),
[client],
);
return { ignore, unignore };
+3 -1
View File
@@ -4,5 +4,7 @@ import { useSignalValue } from "../adapters/useSignalValue.ts";
export function useNode(nodeNum: number): Node | undefined {
const client = useClient();
return useSignalValue(client.nodes.list, (list) => list.find((n) => n.num === nodeNum));
return useSignalValue(client.nodes.list, (list) =>
list.find((n) => n.num === nodeNum),
);
}
+3 -1
View File
@@ -4,5 +4,7 @@ import { useSignalValue } from "../adapters/useSignalValue.ts";
export function usePosition(nodeNum: number): Position | undefined {
const client = useClient();
return useSignalValue(client.position.list, (list) => list.find((p) => p.nodeNum === nodeNum));
return useSignalValue(client.position.list, (list) =>
list.find((p) => p.nodeNum === nodeNum),
);
}
+8 -2
View File
@@ -10,8 +10,14 @@ export interface UseTelemetryResult {
export function useTelemetry(nodeNum: number): UseTelemetryResult {
const client = useClient();
const latestSig = useMemo(() => client.telemetry.latest(nodeNum), [client, nodeNum]);
const historySig = useMemo(() => client.telemetry.history(nodeNum), [client, nodeNum]);
const latestSig = useMemo(
() => client.telemetry.latest(nodeNum),
[client, nodeNum],
);
const historySig = useMemo(
() => client.telemetry.history(nodeNum),
[client, nodeNum],
);
const latest = useSignal(latestSig);
const history = useSignal(historySig);
return { latest, history };
@@ -1,4 +1,6 @@
import type { MeshRegistry } from "@meshtastic/sdk";
import { createContext } from "react";
export const MeshRegistryContext = createContext<MeshRegistry | undefined>(undefined);
export const MeshRegistryContext = createContext<MeshRegistry | undefined>(
undefined,
);
@@ -12,6 +12,13 @@ export interface MeshRegistryProviderProps {
* more than one connected device at a time. For single-client apps, prefer
* `<MeshProvider client={...}>`.
*/
export function MeshRegistryProvider({ registry, children }: MeshRegistryProviderProps) {
return <MeshRegistryContext.Provider value={registry}>{children}</MeshRegistryContext.Provider>;
export function MeshRegistryProvider({
registry,
children,
}: MeshRegistryProviderProps) {
return (
<MeshRegistryContext.Provider value={registry}>
{children}
</MeshRegistryContext.Provider>
);
}
@@ -4,7 +4,13 @@ import { ChannelNumber, MeshRegistry } from "@meshtastic/sdk";
import { createFakeTransport } from "@meshtastic/sdk/testing";
import { act, renderHook, waitFor } from "@testing-library/react";
import { describe, expect, it } from "vitest";
import { MeshRegistryProvider, useChannels, useMeshDevice, useNode, useNodes } from "../mod.ts";
import {
MeshRegistryProvider,
useChannels,
useMeshDevice,
useNode,
useNodes,
} from "../mod.ts";
function makeRegistry(deviceCount: number) {
const registry = new MeshRegistry();
@@ -21,7 +27,9 @@ describe("sdk-react under MeshRegistryProvider", () => {
it("useMeshDevice resolves through the registry's active client", async () => {
const { registry, handles } = makeRegistry(1);
const wrapper = ({ children }: { children: React.ReactNode }) => (
<MeshRegistryProvider registry={registry}>{children}</MeshRegistryProvider>
<MeshRegistryProvider registry={registry}>
{children}
</MeshRegistryProvider>
);
const { result } = renderHook(() => useMeshDevice(), { wrapper });
expect(result.current.myNodeNum).toBeUndefined();
@@ -36,7 +44,9 @@ describe("sdk-react under MeshRegistryProvider", () => {
it("useNodes lists nodes from the active client and updates on packets", async () => {
const { registry, handles } = makeRegistry(1);
const wrapper = ({ children }: { children: React.ReactNode }) => (
<MeshRegistryProvider registry={registry}>{children}</MeshRegistryProvider>
<MeshRegistryProvider registry={registry}>
{children}
</MeshRegistryProvider>
);
const { result } = renderHook(() => useNodes(), { wrapper });
expect(result.current).toEqual([]);
@@ -53,7 +63,9 @@ describe("sdk-react under MeshRegistryProvider", () => {
it("useNode selects by node number and re-renders on update", async () => {
const { registry, handles } = makeRegistry(1);
const wrapper = ({ children }: { children: React.ReactNode }) => (
<MeshRegistryProvider registry={registry}>{children}</MeshRegistryProvider>
<MeshRegistryProvider registry={registry}>
{children}
</MeshRegistryProvider>
);
const { result } = renderHook(() => useNode(11), { wrapper });
expect(result.current).toBeUndefined();
@@ -73,7 +85,9 @@ describe("sdk-react under MeshRegistryProvider", () => {
if (!client) throw new Error("expected an active client");
const wrapper = ({ children }: { children: React.ReactNode }) => (
<MeshRegistryProvider registry={registry}>{children}</MeshRegistryProvider>
<MeshRegistryProvider registry={registry}>
{children}
</MeshRegistryProvider>
);
const { result } = renderHook(() => useChannels(), { wrapper });
expect(result.current).toEqual([]);
@@ -95,7 +109,9 @@ describe("sdk-react under MeshRegistryProvider", () => {
const { registry, handles } = makeRegistry(2);
const wrapper = ({ children }: { children: React.ReactNode }) => (
<MeshRegistryProvider registry={registry}>{children}</MeshRegistryProvider>
<MeshRegistryProvider registry={registry}>
{children}
</MeshRegistryProvider>
);
const { result } = renderHook(() => useMeshDevice(), { wrapper });
+3 -1
View File
@@ -32,7 +32,9 @@ describe("sdk-react hooks", () => {
it("useChat surfaces inbound messages", async () => {
const { handle, wrapper } = setup();
const { result } = renderHook(() => useChat(ChannelNumber.Primary), { wrapper });
const { result } = renderHook(() => useChat(ChannelNumber.Primary), {
wrapper,
});
expect(result.current.messages).toEqual([]);
// Exhaustive integration coverage is in packages/sdk; this test ensures
// the hook wiring re-renders on a signal change.
+6 -1
View File
@@ -4,6 +4,11 @@ export default defineProject({
test: {
name: "@meshtastic/sdk-react",
environment: "jsdom",
include: ["src/**/*.test.ts", "src/**/*.test.tsx", "tests/**/*.test.ts", "tests/**/*.test.tsx"],
include: [
"src/**/*.test.ts",
"src/**/*.test.tsx",
"tests/**/*.test.ts",
"tests/**/*.test.tsx",
],
},
});