Skip to content

Commit c710238

Browse files
committed
dragonfruit
1 parent 3cd7dd8 commit c710238

File tree

2 files changed

+49
-12
lines changed

2 files changed

+49
-12
lines changed

packages/react-hooks/src/hooks/useRealtime.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
RealtimeRunSkipColumns,
99
} from "@trigger.dev/core/v3";
1010
import { useCallback, useEffect, useId, useRef, useState } from "react";
11-
import { KeyedMutator, useSWR } from "../utils/trigger-swr.js";
11+
import { KeyedMutator, useInternalSWR } from "../utils/trigger-swr.js";
1212
import { useApiClient, UseApiClientOptions } from "./useApiClient.js";
1313
import { createThrottledQueue } from "../utils/throttle.js";
1414

@@ -78,15 +78,15 @@ export function useRealtimeRun<TTask extends AnyTask>(
7878
const idKey = options?.id ?? hookId;
7979

8080
// Store the streams state in SWR, using the idKey as the key to share states.
81-
const { data: run, mutate: mutateRun } = useSWR<RealtimeRun<TTask>>([idKey, "run"], null);
81+
const { data: run, mutate: mutateRun } = useInternalSWR<RealtimeRun<TTask>>([idKey, "run"], null);
8282

83-
const { data: error = undefined, mutate: setError } = useSWR<undefined | Error>(
83+
const { data: error = undefined, mutate: setError } = useInternalSWR<undefined | Error>(
8484
[idKey, "error"],
8585
null
8686
);
8787

8888
// Add state to track when the subscription is complete
89-
const { data: isComplete = false, mutate: setIsComplete } = useSWR<boolean>(
89+
const { data: isComplete = false, mutate: setIsComplete } = useInternalSWR<boolean>(
9090
[idKey, "complete"],
9191
null
9292
);
@@ -224,7 +224,7 @@ export function useRealtimeRunWithStreams<
224224
const [initialStreamsFallback] = useState({} as StreamResults<TStreams>);
225225

226226
// Store the streams state in SWR, using the idKey as the key to share states.
227-
const { data: streams, mutate: mutateStreams } = useSWR<StreamResults<TStreams>>(
227+
const { data: streams, mutate: mutateStreams } = useInternalSWR<StreamResults<TStreams>>(
228228
[idKey, "streams"],
229229
null,
230230
{
@@ -239,15 +239,15 @@ export function useRealtimeRunWithStreams<
239239
}, [streams]);
240240

241241
// Store the streams state in SWR, using the idKey as the key to share states.
242-
const { data: run, mutate: mutateRun } = useSWR<RealtimeRun<TTask>>([idKey, "run"], null);
242+
const { data: run, mutate: mutateRun } = useInternalSWR<RealtimeRun<TTask>>([idKey, "run"], null);
243243

244244
// Add state to track when the subscription is complete
245-
const { data: isComplete = false, mutate: setIsComplete } = useSWR<boolean>(
245+
const { data: isComplete = false, mutate: setIsComplete } = useInternalSWR<boolean>(
246246
[idKey, "complete"],
247247
null
248248
);
249249

250-
const { data: error = undefined, mutate: setError } = useSWR<undefined | Error>(
250+
const { data: error = undefined, mutate: setError } = useInternalSWR<undefined | Error>(
251251
[idKey, "error"],
252252
null
253253
);
@@ -401,7 +401,7 @@ export function useRealtimeRunsWithTag<TTask extends AnyTask>(
401401
const idKey = options?.id ?? hookId;
402402

403403
// Store the streams state in SWR, using the idKey as the key to share states.
404-
const { data: runs, mutate: mutateRuns } = useSWR<RealtimeRun<TTask>[]>([idKey, "run"], null, {
404+
const { data: runs, mutate: mutateRuns } = useInternalSWR<RealtimeRun<TTask>[]>([idKey, "run"], null, {
405405
fallbackData: [],
406406
});
407407

@@ -411,7 +411,7 @@ export function useRealtimeRunsWithTag<TTask extends AnyTask>(
411411
runsRef.current = runs ?? [];
412412
}, [runs]);
413413

414-
const { data: error = undefined, mutate: setError } = useSWR<undefined | Error>(
414+
const { data: error = undefined, mutate: setError } = useInternalSWR<undefined | Error>(
415415
[idKey, "error"],
416416
null
417417
);
@@ -499,7 +499,7 @@ export function useRealtimeBatch<TTask extends AnyTask>(
499499
const idKey = options?.id ?? hookId;
500500

501501
// Store the streams state in SWR, using the idKey as the key to share states.
502-
const { data: runs, mutate: mutateRuns } = useSWR<RealtimeRun<TTask>[]>([idKey, "run"], null, {
502+
const { data: runs, mutate: mutateRuns } = useInternalSWR<RealtimeRun<TTask>[]>([idKey, "run"], null, {
503503
fallbackData: [],
504504
});
505505

@@ -509,7 +509,7 @@ export function useRealtimeBatch<TTask extends AnyTask>(
509509
runsRef.current = runs ?? [];
510510
}, [runs]);
511511

512-
const { data: error = undefined, mutate: setError } = useSWR<undefined | Error>(
512+
const { data: error = undefined, mutate: setError } = useInternalSWR<undefined | Error>(
513513
[idKey, "error"],
514514
null
515515
);

packages/react-hooks/src/utils/trigger-swr.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import { ApiRequestOptions } from "@trigger.dev/core/v3";
66
export * from "swr";
77
// eslint-disable-next-line import/export
88
export { default as useSWR, SWRConfig } from "swr";
9+
// Import the original useSWR separately for internal use
10+
import { default as useSWROriginal } from "swr";
911

1012
export type CommonTriggerHookOptions = {
1113
/**
@@ -24,3 +26,38 @@ export type CommonTriggerHookOptions = {
2426
/** Optional additional request configuration */
2527
requestOptions?: ApiRequestOptions;
2628
};
29+
30+
/**
31+
* Internal isolated useSWR hook that prevents global SWRConfig interference.
32+
* This should only be used by internal Trigger.dev hooks for state management.
33+
*
34+
* For realtime hooks, this ensures that:
35+
* 1. No global fetcher will be invoked accidentally
36+
* 2. Internal state management remains isolated
37+
* 3. Manual mutate() calls work as expected
38+
*
39+
* @param key - SWR key for caching
40+
* @param fetcher - Fetcher function (should be null for internal state management)
41+
* @param config - SWR configuration options
42+
* @returns SWR hook result with isolated configuration
43+
*/
44+
export function useInternalSWR<Data = any, Error = any>(
45+
key: any,
46+
fetcher: ((key: any) => Data | Promise<Data>) | null = null,
47+
config: any = {}
48+
) {
49+
// Always override fetcher to null and disable auto-revalidation for internal state management
50+
// This prevents global SWRConfig fetchers from being invoked
51+
const internalConfig = {
52+
// Disable automatic revalidation for internal state management
53+
revalidateOnFocus: false,
54+
revalidateOnReconnect: false,
55+
revalidateIfStale: false,
56+
// Override any config that might cause global interference
57+
...config,
58+
// Ensure fetcher remains null even if passed in config to prevent global fetcher usage
59+
fetcher: null,
60+
};
61+
62+
return useSWROriginal(key, fetcher, internalConfig);
63+
}

0 commit comments

Comments
 (0)