Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clear-shrimps-see.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"solid-relay": patch
---

fix: stop caching queries that wasn't fetched
5 changes: 5 additions & 0 deletions .changeset/twenty-trains-wish.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"solid-relay": patch
---

fix: proper fragment subscription cleanup
17 changes: 9 additions & 8 deletions src/primitives/createFragment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,8 @@ import {
KeyTypeData,
} from "relay-runtime/lib/store/FragmentTypes";
import type { Accessor, Setter, Signal } from "solid-js";
import { batch, createResource, createSignal, untrack } from "solid-js";
import { batch, createEffect, createResource, createSignal, onCleanup, untrack } from "solid-js";
import { reconcile, type SetStoreFunction, unwrap } from "solid-js/store";
import { isServer } from "solid-js/web";
import { useRelayEnvironment } from "../RelayEnvironment";
import { createDataStore, type DataStore } from "../utils/dataStore";
import { cleanSnapshot } from "../utils/snapshot";
Expand Down Expand Up @@ -154,6 +153,14 @@ export function createFragmentInternal<
},
} satisfies Observer<FragmentState<unknown>>;
const [subscription, setSubscription] = createSignal<Subscription>();
createEffect(() => {
const sub = subscription();
if (sub) {
onCleanup(() => {
sub.unsubscribe();
});
}
});

const setResultQueue: unknown[][] = [];
let setResult: SetStoreFunction<FragmentResult<unknown>> = (...args: unknown[]) => {
Expand All @@ -164,7 +171,6 @@ export function createFragmentInternal<
const [resource] = createResource(
() => {
return batch(() => {
untrack(subscription)?.unsubscribe();
setSubscription(undefined);
setResult("pending", false);

Expand Down Expand Up @@ -203,11 +209,6 @@ export function createFragmentInternal<
},
}),
);
}).finally(() => {
if (isServer) {
subscription()?.unsubscribe();
setSubscription(undefined);
}
});
},
{
Expand Down
4 changes: 2 additions & 2 deletions src/primitives/createLazyLoadQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export function createLazyLoadQueryInternal<TQuery extends OperationType>(params
},
);

let entry: QueryCacheEntry = null;
let entry: QueryCacheEntry | undefined;
if (shouldFetch) {
const subscription = subscriptionTarget?.subscribe({});
let retainCount = 0;
Expand All @@ -237,9 +237,9 @@ export function createLazyLoadQueryInternal<TQuery extends OperationType>(params
};
},
};
cache.set(key, entry);
}

cache.set(key, entry);
return entry;
});

Expand Down
2 changes: 1 addition & 1 deletion src/queryCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import type { Resource } from "solid-js";
export type QueryCacheEntry = {
resource: Resource<unknown>;
retain: (environment: IEnvironment) => Disposable;
} | null;
};
Comment on lines 4 to +7
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

To support retaining queries even when they are not fetched (e.g., for store-only or store-or-network policies when data is already available), we should make the resource property optional in QueryCacheEntry. This allows us to cache and retain the query without needing to create a dummy resource.

Suggested change
export type QueryCacheEntry = {
resource: Resource<unknown>;
retain: (environment: IEnvironment) => Disposable;
} | null;
};
export type QueryCacheEntry = {
resource?: Resource<unknown>;
retain: (environment: IEnvironment) => Disposable;
};


const caches = new WeakMap<IEnvironment, Map<string, QueryCacheEntry>>();

Expand Down
Loading