Skip to content

Commit

Permalink
disable observable timeouts for suspense (#525)
Browse files Browse the repository at this point in the history
Co-authored-by: Jeff <3759507+jhuleatt@users.noreply.github.com>
  • Loading branch information
Mythie and jhuleatt committed Jun 27, 2023
1 parent 546fe9b commit 4329c43
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
10 changes: 8 additions & 2 deletions src/SuspenseSubject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export class SuspenseSubject<T> extends Subject<T> {
// @ts-expect-error: TODO: double check to see if this is an RXJS thing or if we should listen to TS
private _resolveFirstEmission: () => void;

constructor(innerObservable: Observable<T>, private _timeoutWindow: number) {
constructor(innerObservable: Observable<T>, private _timeoutWindow: number, private _suspenseEnabled: boolean) {
super();
this._firstEmission = new Promise<void>((resolve) => (this._resolveFirstEmission = resolve));
this._innerObservable = innerObservable.pipe(
Expand All @@ -38,7 +38,13 @@ export class SuspenseSubject<T> extends Subject<T> {

// set a timeout for resetting the cache, subscriptions will cancel the timeout
// and reschedule again on unsubscribe
this._timeoutHandler = setTimeout(this._reset.bind(this), this._timeoutWindow);
if (this._suspenseEnabled) {
// Noop if suspense is enabled
console.log('SuspenseSubject: Suspense is enabled');
this._timeoutHandler = setTimeout(() => {}, this._timeoutWindow);
} else {
this._timeoutHandler = setTimeout(this._reset.bind(this), this._timeoutWindow);
}
}

get hasValue(): boolean {
Expand Down
9 changes: 5 additions & 4 deletions src/useObservable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@ if (!(globalThis as any as ReactFireGlobals)._reactFirePreloadedObservables) {
// Starts listening to an Observable.
// Call this once you know you're going to render a
// child that will consume the observable
export function preloadObservable<T>(source: Observable<T>, id: string) {
export function preloadObservable<T>(source: Observable<T>, id: string, suspenseEnabled = false) {
if (preloadedObservables.has(id)) {
return preloadedObservables.get(id) as SuspenseSubject<T>;
} else {
const observable = new SuspenseSubject(source, DEFAULT_TIMEOUT);
const observable = new SuspenseSubject(source, DEFAULT_TIMEOUT, suspenseEnabled);
preloadedObservables.set(id, observable);
return observable;
}
Expand Down Expand Up @@ -97,12 +97,13 @@ export function useObservable<T = unknown>(observableId: string, source: Observa
if (!observableId) {
throw new Error('cannot call useObservable without an observableId');
}
const observable = preloadObservable(source, observableId);
const suspenseEnabled = useSuspenseEnabledFromConfigAndContext(config.suspense);

const observable = preloadObservable(source, observableId, suspenseEnabled);

// Suspend if suspense is enabled and no initial data exists
const hasInitialData = config.hasOwnProperty('initialData') || config.hasOwnProperty('startWithValue');
const hasData = observable.hasValue || hasInitialData;
const suspenseEnabled = useSuspenseEnabledFromConfigAndContext(config.suspense);
if (suspenseEnabled === true && !hasData) {
throw observable.firstEmission;
}
Expand Down

0 comments on commit 4329c43

Please sign in to comment.