Skip to content

Commit 8af9c04

Browse files
committed
chore(webapp): scope imperative route refs
1 parent 324b1ac commit 8af9c04

6 files changed

Lines changed: 13 additions & 0 deletions

File tree

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam._index/route.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ export default function Page() {
243243
const usefulLinksPanelRef = useRef<PanelHandle>(null);
244244
const fetcher = useFetcher();
245245
const fetcherRef = useRef(fetcher);
246+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
246247
fetcherRef.current = fetcher;
247248

248249
const toggleUsefulLinks = useCallback((show: boolean) => {

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.playground.$agentParam/route.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ function PlaygroundChat() {
207207
activeConversation?.clientData ? JSON.stringify(activeConversation.clientData, null, 2) : "{}"
208208
);
209209
const clientDataJsonRef = useRef(clientDataJson);
210+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
210211
clientDataJsonRef.current = clientDataJson;
211212
const [machine, setMachine] = useState<string | undefined>(undefined);
212213
const [tags, setTags] = useState<string[]>([]);
@@ -267,12 +268,14 @@ function PlaygroundChat() {
267268
// silently ignored on the first send. Mirror the `clientDataJsonRef`
268269
// pattern so the transport always calls the latest `startSession`.
269270
const startSessionRef = useRef(startSession);
271+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
270272
startSessionRef.current = startSession;
271273

272274
// Create TriggerChatTransport directly (not via useTriggerChatTransport hook
273275
// to avoid React version mismatch between SDK and webapp)
274276
const transportRef = useRef<TriggerChatTransport | null>(null);
275277
if (transportRef.current === null) {
278+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
276279
transportRef.current = new TriggerChatTransport({
277280
task: agent.slug,
278281
// The Remix action is idempotent on `(env, externalId)` and
@@ -301,6 +304,7 @@ function PlaygroundChat() {
301304
: {}),
302305
});
303306
}
307+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
304308
const transport = transportRef.current;
305309

306310
// Keep the transport's `defaultMetadata` in sync with the JSON editor.
@@ -351,6 +355,7 @@ function PlaygroundChat() {
351355
);
352356

353357
// useChat from AI SDK — handles message accumulation, streaming, stop
358+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
354359
const { messages, sendMessage, stop, status, error } = useChat({
355360
id: chatId,
356361
messages: initialMessages,
@@ -391,6 +396,7 @@ function PlaygroundChat() {
391396
inputRef.current?.focus();
392397
}, [isEmpty]);
393398

399+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
394400
const session = transport.getSession(chatId);
395401

396402
/* oxlint-disable react/react-compiler -- The transport and chat ID are stable for this component's lifetime. */
@@ -1171,6 +1177,7 @@ function usePlaygroundPendingMessages({
11711177
[status, transport, chatId, sendMessage, metadata]
11721178
);
11731179

1180+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
11741181
const pending: PendingMessageEntry[] = pendingMsgs.map((m) => ({
11751182
id: m.id,
11761183
text: m.parts[0]?.text ?? "",

apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs._index/useRunsLiveReload.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ export function useRunsLiveReload({
165165
const location = useLocation();
166166
const runsPollFetcher = useTypedFetcher<typeof liveRunsLoader>();
167167
const runsPollFetcherStateRef = useRef(runsPollFetcher.state);
168+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
168169
runsPollFetcherStateRef.current = runsPollFetcher.state;
169170

170171
const [visibleRuns, setVisibleRuns] = useState(runs);

apps/webapp/app/routes/resources.metric.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ export function MetricWidget({
207207
// Track the latest props so the submit callback always uses fresh values
208208
// without needing to be recreated (which would cause useInterval to re-register listeners).
209209
const propsRef = useRef(props);
210+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
210211
propsRef.current = props;
211212

212213
// Track visibility so we only fetch for on-screen widgets.
@@ -265,6 +266,7 @@ export function MetricWidget({
265266
});
266267
}, [isVisibleRef]);
267268
/* oxlint-enable react/react-compiler */
269+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
268270
submitRef.current = submit;
269271

270272
// Clean up on unmount

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.env.$envParam.waitpoints.$waitpointFriendlyId.complete/route.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ function CompleteManualWaitpointForm({ waitpoint }: { waitpoint: { id: string }
371371
<div className="max-h-[70vh] min-h-40 overflow-y-auto bg-background-deep scrollbar-thin scrollbar-track-transparent scrollbar-thumb-surface-control">
372372
<JSONEditor
373373
autoFocus
374+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
374375
defaultValue={currentJson.current}
375376
readOnly={false}
376377
basicSetup

apps/webapp/app/routes/resources.orgs.$organizationSlug.projects.$projectParam.schedules.new.natural-language.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export function AIGeneratedCronField({ onSuccess }: AIGeneratedCronFieldProps) {
5959
const fetcher = useFetcher<typeof action>();
6060
const [text, setText] = useState<string>("");
6161
const onSuccessRef = useRef(onSuccess);
62+
// oxlint-disable-next-line react/react-compiler -- This ref intentionally coordinates an imperative route integration outside React state.
6263
onSuccessRef.current = onSuccess;
6364
const organization = useOrganization();
6465
const project = useProject();

0 commit comments

Comments
 (0)