Skip to content

Commit

Permalink
feat: context sharing (#188)
Browse files Browse the repository at this point in the history
  • Loading branch information
DamianOsipiuk authored May 19, 2022
1 parent 33acbf6 commit 7228a72
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 8 deletions.
4 changes: 3 additions & 1 deletion examples/multi-page/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vue-query example</title>
</head>
<body>
<body style="display:flex;">
<div id="app"></div>
<br />
<div id="app2"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>
2 changes: 0 additions & 2 deletions examples/multi-page/src/Page.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ export default defineComponent({
cacheTime: 4000,
}
);
useQuery("todos2", todoFetcher);
useQuery("todos3", todoFetcher);
return { isLoading, isError, isFetching, data, error, refetch };
},
Expand Down
10 changes: 8 additions & 2 deletions examples/multi-page/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { createApp } from "vue";
import { VueQueryPlugin } from "vue-query";
import { VueQueryPlugin, VueQueryPluginOptions } from "vue-query";

import App from "./App.vue";

createApp(App).use(VueQueryPlugin).mount("#app");
createApp(App)
.use(VueQueryPlugin, { contextSharing: true } as VueQueryPluginOptions)
.mount("#app");
// Second app mounted here will share vue-query context with the first app - click refresh to refresh both apps state
createApp(App)
.use(VueQueryPlugin, { contextSharing: true } as VueQueryPluginOptions)
.mount("#app2");
1 change: 1 addition & 0 deletions jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const config: Config.InitialOptions = {
moduleNameMapper: {
"^vue-query": "<rootDir>/src/index.ts",
},
testEnvironment: "jsdom",
testPathIgnorePatterns: ["test-utils.ts"],
collectCoverage: true,
collectCoverageFrom: [
Expand Down
31 changes: 31 additions & 0 deletions src/vue/__tests__/vueQueryPlugin.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function getAppMock(withUnmountHook = false): TestApp {
describe("VueQueryPlugin", () => {
beforeEach(() => {
jest.clearAllMocks();
window.__VUE_QUERY_CONTEXT__ = undefined;
});

describe("devtools", () => {
Expand Down Expand Up @@ -307,4 +308,34 @@ describe("VueQueryPlugin", () => {
}
);
});

describe("when context sharing is enabled", () => {
test("should create context if it does not exist", () => {
const appMock = getAppMock();
VueQueryPlugin.install?.(appMock, { contextSharing: true });

expect(window.__VUE_QUERY_CONTEXT__).toBeTruthy();
});

test("should create context with options if it does not exist", () => {
const appMock = getAppMock();
VueQueryPlugin.install?.(appMock, {
contextSharing: true,
queryClientConfig: { defaultOptions: { queries: { staleTime: 5000 } } },
});

expect(
window.__VUE_QUERY_CONTEXT__?.getDefaultOptions().queries?.staleTime
).toEqual(5000);
});

test("should use existing context", () => {
const customClient = { mount: jest.fn() } as unknown as QueryClient;
window.__VUE_QUERY_CONTEXT__ = customClient;
const appMock = getAppMock();
VueQueryPlugin.install?.(appMock, { contextSharing: true });

expect(customClient.mount).toHaveBeenCalledTimes(1);
});
});
});
29 changes: 26 additions & 3 deletions src/vue/vueQueryPlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,12 @@ import { getClientKey } from "./utils";
import { setupDevtools } from "./devtools/devtools";
import { MaybeRefDeep } from "./types";

declare global {
interface Window {
__VUE_QUERY_CONTEXT__?: QueryClient;
}
}

export interface AdditionalClient {
queryClient: QueryClient;
queryClientKey: string;
Expand All @@ -15,12 +21,14 @@ interface ConfigOptions {
queryClientConfig?: MaybeRefDeep<QueryClientConfig>;
queryClientKey?: string;
additionalClients?: AdditionalClient[];
contextSharing?: boolean;
}

interface ClientOptions {
queryClient?: QueryClient;
queryClientKey?: string;
additionalClients?: AdditionalClient[];
contextSharing?: boolean;
}

export type VueQueryPluginOptions = ConfigOptions | ClientOptions;
Expand All @@ -33,9 +41,24 @@ export const VueQueryPlugin = {
if ("queryClient" in options && options.queryClient) {
client = options.queryClient;
} else {
const clientConfig =
"queryClientConfig" in options ? options.queryClientConfig : undefined;
client = new QueryClient(clientConfig);
if (options.contextSharing && typeof window !== "undefined") {
if (!window.__VUE_QUERY_CONTEXT__) {
const clientConfig =
"queryClientConfig" in options
? options.queryClientConfig
: undefined;
client = new QueryClient(clientConfig);
window.__VUE_QUERY_CONTEXT__ = client;
} else {
client = window.__VUE_QUERY_CONTEXT__;
}
} else {
const clientConfig =
"queryClientConfig" in options
? options.queryClientConfig
: undefined;
client = new QueryClient(clientConfig);
}
}

client.mount();
Expand Down

1 comment on commit 7228a72

@vercel
Copy link

@vercel vercel bot commented on 7228a72 May 19, 2022

Choose a reason for hiding this comment

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

Successfully deployed to the following URLs:

vue-query – ./

vue-query-damianosipiuk.vercel.app
vue-query-git-main-damianosipiuk.vercel.app
vue-query.vercel.app

Please sign in to comment.