@tanstack/solid-query 4.11.0 → 4.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/build/lib/__tests__/QueryClientProvider.test.d.ts +1 -0
  2. package/build/lib/__tests__/createInfiniteQuery.test.d.ts +1 -0
  3. package/build/lib/__tests__/createMutation.test.d.ts +1 -0
  4. package/build/lib/__tests__/createQueries.test.d.ts +1 -0
  5. package/build/lib/__tests__/createQuery.test.d.ts +1 -0
  6. package/build/lib/__tests__/createQuery.types.test.d.ts +2 -0
  7. package/build/lib/__tests__/suspense.test.d.ts +1 -0
  8. package/build/lib/__tests__/transition.test.d.ts +1 -0
  9. package/build/lib/__tests__/useIsFetching.test.d.ts +1 -0
  10. package/build/lib/__tests__/useIsMutating.test.d.ts +1 -0
  11. package/build/lib/__tests__/utils.d.ts +27 -0
  12. package/build/lib/createBaseQuery.esm.js +18 -2
  13. package/build/lib/createBaseQuery.esm.js.map +1 -1
  14. package/build/lib/createBaseQuery.js +18 -2
  15. package/build/lib/createBaseQuery.js.map +1 -1
  16. package/build/lib/createBaseQuery.mjs +18 -2
  17. package/build/lib/createBaseQuery.mjs.map +1 -1
  18. package/build/solid/__tests__/QueryClientProvider.test.jsx +185 -0
  19. package/build/solid/__tests__/createInfiniteQuery.test.jsx +1440 -0
  20. package/build/solid/__tests__/createMutation.test.jsx +810 -0
  21. package/build/solid/__tests__/createQueries.test.jsx +958 -0
  22. package/build/solid/__tests__/createQuery.test.jsx +4553 -0
  23. package/build/solid/__tests__/createQuery.types.test.jsx +124 -0
  24. package/build/solid/__tests__/suspense.test.jsx +691 -0
  25. package/build/solid/__tests__/transition.test.jsx +39 -0
  26. package/build/solid/__tests__/useIsFetching.test.jsx +209 -0
  27. package/build/solid/__tests__/useIsMutating.test.jsx +216 -0
  28. package/build/solid/__tests__/utils.jsx +55 -0
  29. package/build/solid/createBaseQuery.js +14 -2
  30. package/build/umd/index.development.js +21 -5
  31. package/build/umd/index.development.js.map +1 -1
  32. package/build/umd/index.production.js +1 -1
  33. package/build/umd/index.production.js.map +1 -1
  34. package/package.json +5 -6
  35. package/src/__tests__/createQuery.test.tsx +15 -84
  36. package/src/__tests__/suspense.test.tsx +0 -46
  37. package/src/createBaseQuery.ts +14 -3
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import '@testing-library/jest-dom';
@@ -0,0 +1,2 @@
1
+ export declare type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false;
2
+ export declare type Expect<T extends true> = T;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,27 @@
1
+ /// <reference types="jest" />
2
+ /// <reference types="node" />
3
+ import type { QueryClientConfig } from '@tanstack/query-core';
4
+ import { QueryClient } from '@tanstack/query-core';
5
+ import type { ParentProps } from 'solid-js';
6
+ export declare function queryKey(): () => Array<string>;
7
+ export declare const Blink: (props: {
8
+ duration: number;
9
+ } & ParentProps) => import("solid-js").JSX.Element;
10
+ export declare function createQueryClient(config?: QueryClientConfig): QueryClient;
11
+ export declare function mockVisibilityState(value: DocumentVisibilityState): jest.SpyInstance<DocumentVisibilityState, []>;
12
+ export declare function mockNavigatorOnLine(value: boolean): jest.SpyInstance<boolean, []>;
13
+ export declare const mockLogger: {
14
+ log: jest.Mock<any, any>;
15
+ warn: jest.Mock<any, any>;
16
+ error: jest.Mock<any, any>;
17
+ };
18
+ export declare function sleep(timeout: number): Promise<void>;
19
+ export declare function setActTimeout(fn: () => void, ms?: number): NodeJS.Timeout;
20
+ /**
21
+ * Assert the parameter is of a specific type.
22
+ */
23
+ export declare function expectType<T>(_: T): void;
24
+ /**
25
+ * Assert the parameter is not typed as `any`
26
+ */
27
+ export declare function expectTypeNotAny<T>(_: 0 extends 1 & T ? never : T): void;
@@ -7,6 +7,7 @@ function createBaseQuery(options, Observer) {
7
7
  const queryClient = useQueryClient({
8
8
  context: options.context
9
9
  });
10
+ const emptyData = Symbol('empty');
10
11
  const defaultedOptions = queryClient.defaultQueryOptions(options);
11
12
  defaultedOptions._optimisticResults = 'optimistic';
12
13
  const observer = new Observer(queryClient, defaultedOptions);
@@ -18,6 +19,10 @@ function createBaseQuery(options, Observer) {
18
19
  }] = createResource(() => {
19
20
  return new Promise(resolve => {
20
21
  if (!(state.isFetching && state.isLoading)) {
22
+ if (unwrap(state.data) === emptyData) {
23
+ resolve(undefined);
24
+ }
25
+
21
26
  resolve(unwrap(state.data));
22
27
  }
23
28
  });
@@ -30,7 +35,18 @@ function createBaseQuery(options, Observer) {
30
35
  const unsubscribe = observer.subscribe(result => {
31
36
  taskQueue.push(() => {
32
37
  batch(() => {
33
- setState(unwrap(result));
38
+ const unwrappedResult = { ...unwrap(result)
39
+ };
40
+
41
+ if (unwrappedResult.data === undefined) {
42
+ // This is a hack to prevent Solid
43
+ // from deleting the data property when it is `undefined`
44
+ // ref: https://www.solidjs.com/docs/latest/api#updating-stores
45
+ // @ts-ignore
46
+ unwrappedResult.data = emptyData;
47
+ }
48
+
49
+ setState(unwrap(unwrappedResult));
34
50
  mutate(() => unwrap(result.data));
35
51
  refetch();
36
52
  });
@@ -62,7 +78,7 @@ function createBaseQuery(options, Observer) {
62
78
  }));
63
79
  const handler = {
64
80
  get(target, prop) {
65
- if (prop === 'data' && target.isLoading && target.isFetching) {
81
+ if (prop === 'data') {
66
82
  return dataResource();
67
83
  }
68
84
 
@@ -1 +1 @@
1
- {"version":3,"file":"createBaseQuery.esm.js","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n setState(unwrap(result))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data' && target.isLoading && target.isFetching) {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","batch","taskQueue","unsubscribe","subscribe","result","push","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":";;;;;AAgBO,SAASA,eAAT,CAOLC,OAPK,EAcLC,QAdK,EAe+B;EACpC,MAAMC,WAAW,GAAGC,cAAc,CAAC;IAAEC,OAAO,EAAEJ,OAAO,CAACI,OAAAA;AAAnB,GAAD,CAAlC,CAAA;AAEA,EAAA,MAAMC,gBAAgB,GAAGH,WAAW,CAACI,mBAAZ,CAAgCN,OAAhC,CAAzB,CAAA;EACAK,gBAAgB,CAACE,kBAAjB,GAAsC,YAAtC,CAAA;EACA,MAAMC,QAAQ,GAAG,IAAIP,QAAJ,CAAaC,WAAb,EAA0BG,gBAA1B,CAAjB,CAAA;AAEA,EAAA,MAAM,CAACI,KAAD,EAAQC,QAAR,CAAA,GAAoBC,WAAW;AAEnCH,EAAAA,QAAQ,CAACI,mBAAT,CAA6BP,gBAA7B,CAFmC,CAArC,CAAA;EAKA,MAAM,CAACQ,YAAD,EAAe;IAAEC,OAAF;AAAWC,IAAAA,MAAAA;GAA1B,CAAA,GAAsCC,cAAc,CACxD,MAAM;AACJ,IAAA,OAAO,IAAIC,OAAJ,CAAaC,OAAD,IAAa;MAC9B,IAAI,EAAET,KAAK,CAACU,UAAN,IAAoBV,KAAK,CAACW,SAA5B,CAAJ,EAA4C;AAC1CF,QAAAA,OAAO,CAACG,MAAM,CAACZ,KAAK,CAACa,IAAP,CAAP,CAAP,CAAA;AACD,OAAA;AACF,KAJM,CAAP,CAAA;AAKD,GAPuD,CAA1D,CAAA;AAUAC,EAAAA,KAAK,CAAC,MAAM;IACVR,MAAM,CAAC,MAAMM,MAAM,CAACZ,KAAK,CAACa,IAAP,CAAb,CAAN,CAAA;IACAR,OAAO,EAAA,CAAA;AACR,GAHI,CAAL,CAAA;EAKA,IAAIU,SAA4B,GAAG,EAAnC,CAAA;AAEA,EAAA,MAAMC,WAAW,GAAGjB,QAAQ,CAACkB,SAAT,CAAoBC,MAAD,IAAY;IACjDH,SAAS,CAACI,IAAV,CAAe,MAAM;AACnBL,MAAAA,KAAK,CAAC,MAAM;AACVb,QAAAA,QAAQ,CAACW,MAAM,CAACM,MAAD,CAAP,CAAR,CAAA;QACAZ,MAAM,CAAC,MAAMM,MAAM,CAACM,MAAM,CAACL,IAAR,CAAb,CAAN,CAAA;QACAR,OAAO,EAAA,CAAA;AACR,OAJI,CAAL,CAAA;KADF,CAAA,CAAA;AAQAe,IAAAA,cAAc,CAAC,MAAM;AACnB,MAAA,MAAMC,SAAS,GAAGN,SAAS,CAACO,GAAV,EAAlB,CAAA;;AACA,MAAA,IAAID,SAAJ,EAAe;QACbA,SAAS,EAAA,CAAA;AACV,OAAA;;AACDN,MAAAA,SAAS,GAAG,EAAZ,CAAA;AACD,KANa,CAAd,CAAA;AAOD,GAhBmB,CAApB,CAAA;AAkBAQ,EAAAA,SAAS,CAAC,MAAMP,WAAW,EAAlB,CAAT,CAAA;AAEAQ,EAAAA,OAAO,CAAC,MAAM;AACZzB,IAAAA,QAAQ,CAAC0B,UAAT,CAAoB7B,gBAApB,EAAsC;AAAE8B,MAAAA,SAAS,EAAE,KAAA;KAAnD,CAAA,CAAA;AACD,GAFM,CAAP,CAAA;AAIAC,EAAAA,cAAc,CAAC,MAAM;AACnB,IAAA,MAAMC,mBAAmB,GAAGnC,WAAW,CAACI,mBAAZ,CAAgCN,OAAhC,CAA5B,CAAA;IACAQ,QAAQ,CAAC0B,UAAT,CAAoBG,mBAApB,CAAA,CAAA;AACD,GAHa,CAAd,CAAA;EAKAD,cAAc,CACZE,EAAE,CACA,MAAM7B,KAAK,CAAC8B,MADZ,EAEA,MAAM;AACJ,IAAA,IACE9B,KAAK,CAAC+B,OAAN,IACA,CAAC/B,KAAK,CAACU,UADP,IAEAsB,gBAAgB,CAACjC,QAAQ,CAACR,OAAT,CAAiB0C,gBAAlB,EAAoC,CAClDjC,KAAK,CAACkC,KAD4C,EAElDnC,QAAQ,CAACoC,eAAT,EAFkD,CAApC,CAHlB,EAOE;MACA,MAAMnC,KAAK,CAACkC,KAAZ,CAAA;AACD,KAAA;AACF,GAbD,CADU,CAAd,CAAA;AAkBA,EAAA,MAAME,OAAO,GAAG;AACdC,IAAAA,GAAG,CACDC,MADC,EAEDC,IAFC,EAGI;MACL,IAAIA,IAAI,KAAK,MAAT,IAAmBD,MAAM,CAAC3B,SAA1B,IAAuC2B,MAAM,CAAC5B,UAAlD,EAA8D;AAC5D,QAAA,OAAON,YAAY,EAAnB,CAAA;AACD,OAAA;;AACD,MAAA,OAAOoC,OAAO,CAACH,GAAR,CAAYC,MAAZ,EAAoBC,IAApB,CAAP,CAAA;AACD,KAAA;;GATH,CAAA;AAYA,EAAA,OAAO,IAAIE,KAAJ,CAAUzC,KAAV,EAAiBoC,OAAjB,CAAP,CAAA;AACD;;;;"}
1
+ {"version":3,"file":"createBaseQuery.esm.js","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n const emptyData = Symbol('empty')\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n if (unwrap(state.data) === emptyData) {\n resolve(undefined)\n }\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n const unwrappedResult = { ...unwrap(result) }\n if (unwrappedResult.data === undefined) {\n // This is a hack to prevent Solid\n // from deleting the data property when it is `undefined`\n // ref: https://www.solidjs.com/docs/latest/api#updating-stores\n // @ts-ignore\n unwrappedResult.data = emptyData\n }\n setState(unwrap(unwrappedResult))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data') {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","emptyData","Symbol","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","undefined","batch","taskQueue","unsubscribe","subscribe","result","push","unwrappedResult","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":"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"}
@@ -11,6 +11,7 @@ function createBaseQuery(options, Observer) {
11
11
  const queryClient = QueryClientProvider.useQueryClient({
12
12
  context: options.context
13
13
  });
14
+ const emptyData = Symbol('empty');
14
15
  const defaultedOptions = queryClient.defaultQueryOptions(options);
15
16
  defaultedOptions._optimisticResults = 'optimistic';
16
17
  const observer = new Observer(queryClient, defaultedOptions);
@@ -22,6 +23,10 @@ function createBaseQuery(options, Observer) {
22
23
  }] = solidJs.createResource(() => {
23
24
  return new Promise(resolve => {
24
25
  if (!(state.isFetching && state.isLoading)) {
26
+ if (store.unwrap(state.data) === emptyData) {
27
+ resolve(undefined);
28
+ }
29
+
25
30
  resolve(store.unwrap(state.data));
26
31
  }
27
32
  });
@@ -34,7 +39,18 @@ function createBaseQuery(options, Observer) {
34
39
  const unsubscribe = observer.subscribe(result => {
35
40
  taskQueue.push(() => {
36
41
  solidJs.batch(() => {
37
- setState(store.unwrap(result));
42
+ const unwrappedResult = { ...store.unwrap(result)
43
+ };
44
+
45
+ if (unwrappedResult.data === undefined) {
46
+ // This is a hack to prevent Solid
47
+ // from deleting the data property when it is `undefined`
48
+ // ref: https://www.solidjs.com/docs/latest/api#updating-stores
49
+ // @ts-ignore
50
+ unwrappedResult.data = emptyData;
51
+ }
52
+
53
+ setState(store.unwrap(unwrappedResult));
38
54
  mutate(() => store.unwrap(result.data));
39
55
  refetch();
40
56
  });
@@ -66,7 +82,7 @@ function createBaseQuery(options, Observer) {
66
82
  }));
67
83
  const handler = {
68
84
  get(target, prop) {
69
- if (prop === 'data' && target.isLoading && target.isFetching) {
85
+ if (prop === 'data') {
70
86
  return dataResource();
71
87
  }
72
88
 
@@ -1 +1 @@
1
- {"version":3,"file":"createBaseQuery.js","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n setState(unwrap(result))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data' && target.isLoading && target.isFetching) {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","batch","taskQueue","unsubscribe","subscribe","result","push","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":"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"}
1
+ {"version":3,"file":"createBaseQuery.js","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n const emptyData = Symbol('empty')\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n if (unwrap(state.data) === emptyData) {\n resolve(undefined)\n }\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n const unwrappedResult = { ...unwrap(result) }\n if (unwrappedResult.data === undefined) {\n // This is a hack to prevent Solid\n // from deleting the data property when it is `undefined`\n // ref: https://www.solidjs.com/docs/latest/api#updating-stores\n // @ts-ignore\n unwrappedResult.data = emptyData\n }\n setState(unwrap(unwrappedResult))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data') {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","emptyData","Symbol","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","undefined","batch","taskQueue","unsubscribe","subscribe","result","push","unwrappedResult","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":"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"}
@@ -7,6 +7,7 @@ function createBaseQuery(options, Observer) {
7
7
  const queryClient = useQueryClient({
8
8
  context: options.context
9
9
  });
10
+ const emptyData = Symbol('empty');
10
11
  const defaultedOptions = queryClient.defaultQueryOptions(options);
11
12
  defaultedOptions._optimisticResults = 'optimistic';
12
13
  const observer = new Observer(queryClient, defaultedOptions);
@@ -18,6 +19,10 @@ function createBaseQuery(options, Observer) {
18
19
  }] = createResource(() => {
19
20
  return new Promise(resolve => {
20
21
  if (!(state.isFetching && state.isLoading)) {
22
+ if (unwrap(state.data) === emptyData) {
23
+ resolve(undefined);
24
+ }
25
+
21
26
  resolve(unwrap(state.data));
22
27
  }
23
28
  });
@@ -30,7 +35,18 @@ function createBaseQuery(options, Observer) {
30
35
  const unsubscribe = observer.subscribe(result => {
31
36
  taskQueue.push(() => {
32
37
  batch(() => {
33
- setState(unwrap(result));
38
+ const unwrappedResult = { ...unwrap(result)
39
+ };
40
+
41
+ if (unwrappedResult.data === undefined) {
42
+ // This is a hack to prevent Solid
43
+ // from deleting the data property when it is `undefined`
44
+ // ref: https://www.solidjs.com/docs/latest/api#updating-stores
45
+ // @ts-ignore
46
+ unwrappedResult.data = emptyData;
47
+ }
48
+
49
+ setState(unwrap(unwrappedResult));
34
50
  mutate(() => unwrap(result.data));
35
51
  refetch();
36
52
  });
@@ -62,7 +78,7 @@ function createBaseQuery(options, Observer) {
62
78
  }));
63
79
  const handler = {
64
80
  get(target, prop) {
65
- if (prop === 'data' && target.isLoading && target.isFetching) {
81
+ if (prop === 'data') {
66
82
  return dataResource();
67
83
  }
68
84
 
@@ -1 +1 @@
1
- {"version":3,"file":"createBaseQuery.mjs","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n setState(unwrap(result))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data' && target.isLoading && target.isFetching) {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","batch","taskQueue","unsubscribe","subscribe","result","push","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":"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"}
1
+ {"version":3,"file":"createBaseQuery.mjs","sources":["../../src/createBaseQuery.ts"],"sourcesContent":["import type { QueryObserver } from '@tanstack/query-core'\nimport type { QueryKey, QueryObserverResult } from '@tanstack/query-core'\nimport type { CreateBaseQueryOptions } from './types'\nimport { useQueryClient } from './QueryClientProvider'\nimport {\n onMount,\n onCleanup,\n createComputed,\n createResource,\n on,\n batch,\n} from 'solid-js'\nimport { createStore, unwrap } from 'solid-js/store'\nimport { shouldThrowError } from './utils'\n\n// Base Query Function that is used to create the query.\nexport function createBaseQuery<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey extends QueryKey,\n>(\n options: CreateBaseQueryOptions<\n TQueryFnData,\n TError,\n TData,\n TQueryData,\n TQueryKey\n >,\n Observer: typeof QueryObserver,\n): QueryObserverResult<TData, TError> {\n const queryClient = useQueryClient({ context: options.context })\n const emptyData = Symbol('empty')\n const defaultedOptions = queryClient.defaultQueryOptions(options)\n defaultedOptions._optimisticResults = 'optimistic'\n const observer = new Observer(queryClient, defaultedOptions)\n\n const [state, setState] = createStore<QueryObserverResult<TData, TError>>(\n // @ts-ignore\n observer.getOptimisticResult(defaultedOptions),\n )\n\n const [dataResource, { refetch, mutate }] = createResource<TData | undefined>(\n () => {\n return new Promise((resolve) => {\n if (!(state.isFetching && state.isLoading)) {\n if (unwrap(state.data) === emptyData) {\n resolve(undefined)\n }\n resolve(unwrap(state.data))\n }\n })\n },\n )\n\n batch(() => {\n mutate(() => unwrap(state.data))\n refetch()\n })\n\n let taskQueue: Array<() => void> = []\n\n const unsubscribe = observer.subscribe((result) => {\n taskQueue.push(() => {\n batch(() => {\n const unwrappedResult = { ...unwrap(result) }\n if (unwrappedResult.data === undefined) {\n // This is a hack to prevent Solid\n // from deleting the data property when it is `undefined`\n // ref: https://www.solidjs.com/docs/latest/api#updating-stores\n // @ts-ignore\n unwrappedResult.data = emptyData\n }\n setState(unwrap(unwrappedResult))\n mutate(() => unwrap(result.data))\n refetch()\n })\n })\n\n queueMicrotask(() => {\n const taskToRun = taskQueue.pop()\n if (taskToRun) {\n taskToRun()\n }\n taskQueue = []\n })\n })\n\n onCleanup(() => unsubscribe())\n\n onMount(() => {\n observer.setOptions(defaultedOptions, { listeners: false })\n })\n\n createComputed(() => {\n const newDefaultedOptions = queryClient.defaultQueryOptions(options)\n observer.setOptions(newDefaultedOptions)\n })\n\n createComputed(\n on(\n () => state.status,\n () => {\n if (\n state.isError &&\n !state.isFetching &&\n shouldThrowError(observer.options.useErrorBoundary, [\n state.error,\n observer.getCurrentQuery(),\n ])\n ) {\n throw state.error\n }\n },\n ),\n )\n\n const handler = {\n get(\n target: QueryObserverResult<TData, TError>,\n prop: keyof QueryObserverResult<TData, TError>,\n ): any {\n if (prop === 'data') {\n return dataResource()\n }\n return Reflect.get(target, prop)\n },\n }\n\n return new Proxy(state, handler) as QueryObserverResult<TData, TError>\n}\n"],"names":["createBaseQuery","options","Observer","queryClient","useQueryClient","context","emptyData","Symbol","defaultedOptions","defaultQueryOptions","_optimisticResults","observer","state","setState","createStore","getOptimisticResult","dataResource","refetch","mutate","createResource","Promise","resolve","isFetching","isLoading","unwrap","data","undefined","batch","taskQueue","unsubscribe","subscribe","result","push","unwrappedResult","queueMicrotask","taskToRun","pop","onCleanup","onMount","setOptions","listeners","createComputed","newDefaultedOptions","on","status","isError","shouldThrowError","useErrorBoundary","error","getCurrentQuery","handler","get","target","prop","Reflect","Proxy"],"mappings":"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"}
@@ -0,0 +1,185 @@
1
+ import { render, screen, waitFor } from 'solid-testing-library';
2
+ import { queryKey } from './utils';
3
+ import { QueryCache, QueryClient } from '@tanstack/query-core';
4
+ import { createContext, useContext } from 'solid-js';
5
+ import { renderToString } from 'solid-js/web';
6
+ import { createQuery, QueryClientProvider, useQueryClient } from '..';
7
+ import { createQueryClient, sleep } from './utils';
8
+ describe('QueryClientProvider', () => {
9
+ it('sets a specific cache for all queries to use', async () => {
10
+ const key = queryKey();
11
+ const queryCache = new QueryCache();
12
+ const queryClient = createQueryClient({ queryCache });
13
+ function Page() {
14
+ const query = createQuery(key, async () => {
15
+ await sleep(10);
16
+ return 'test';
17
+ });
18
+ return (<div>
19
+ <h1>{query.data}</h1>
20
+ </div>);
21
+ }
22
+ render(() => (<QueryClientProvider client={queryClient}>
23
+ <Page />
24
+ </QueryClientProvider>));
25
+ await waitFor(() => {
26
+ return screen.getByText('test');
27
+ });
28
+ expect(queryCache.find(key())).toBeDefined();
29
+ });
30
+ it('allows multiple caches to be partitioned', async () => {
31
+ const key1 = queryKey();
32
+ const key2 = queryKey();
33
+ const queryCache1 = new QueryCache();
34
+ const queryCache2 = new QueryCache();
35
+ const queryClient1 = createQueryClient({ queryCache: queryCache1 });
36
+ const queryClient2 = createQueryClient({ queryCache: queryCache2 });
37
+ function Page1() {
38
+ const query = createQuery(key1, async () => {
39
+ await sleep(10);
40
+ return 'test1';
41
+ });
42
+ return (<div>
43
+ <h1>{query.data}</h1>
44
+ </div>);
45
+ }
46
+ function Page2() {
47
+ const query = createQuery(key2, async () => {
48
+ await sleep(10);
49
+ return 'test2';
50
+ });
51
+ return (<div>
52
+ <h1>{query.data}</h1>
53
+ </div>);
54
+ }
55
+ render(() => (<>
56
+ <QueryClientProvider client={queryClient1}>
57
+ <Page1 />
58
+ </QueryClientProvider>
59
+ <QueryClientProvider client={queryClient2}>
60
+ <Page2 />
61
+ </QueryClientProvider>
62
+ </>));
63
+ await waitFor(() => screen.getByText('test1'));
64
+ await waitFor(() => screen.getByText('test2'));
65
+ expect(queryCache1.find(key1())).toBeDefined();
66
+ expect(queryCache1.find(key2())).not.toBeDefined();
67
+ expect(queryCache2.find(key1())).not.toBeDefined();
68
+ expect(queryCache2.find(key2())).toBeDefined();
69
+ });
70
+ it("uses defaultOptions for queries when they don't provide their own config", async () => {
71
+ const key = queryKey();
72
+ const queryCache = new QueryCache();
73
+ const queryClient = createQueryClient({
74
+ queryCache,
75
+ defaultOptions: {
76
+ queries: {
77
+ cacheTime: Infinity,
78
+ },
79
+ },
80
+ });
81
+ function Page() {
82
+ const query = createQuery(key, async () => {
83
+ await sleep(10);
84
+ return 'test';
85
+ });
86
+ return (<div>
87
+ <h1>{query.data}</h1>
88
+ </div>);
89
+ }
90
+ render(() => (<QueryClientProvider client={queryClient}>
91
+ <Page />
92
+ </QueryClientProvider>));
93
+ await waitFor(() => screen.getByText('test'));
94
+ expect(queryCache.find(key())).toBeDefined();
95
+ expect(queryCache.find(key())?.options.cacheTime).toBe(Infinity);
96
+ });
97
+ describe('with custom context', () => {
98
+ it('uses the correct context', async () => {
99
+ const key = queryKey();
100
+ const contextOuter = createContext(undefined);
101
+ const contextInner = createContext(undefined);
102
+ const queryCacheOuter = new QueryCache();
103
+ const queryClientOuter = new QueryClient({ queryCache: queryCacheOuter });
104
+ const queryCacheInner = new QueryCache();
105
+ const queryClientInner = new QueryClient({ queryCache: queryCacheInner });
106
+ const queryCacheInnerInner = new QueryCache();
107
+ const queryClientInnerInner = new QueryClient({
108
+ queryCache: queryCacheInnerInner,
109
+ });
110
+ function Page() {
111
+ const queryOuter = createQuery(key, async () => 'testOuter', {
112
+ context: contextOuter,
113
+ });
114
+ const queryInner = createQuery(key, async () => 'testInner', {
115
+ context: contextInner,
116
+ });
117
+ const queryInnerInner = createQuery(key, async () => 'testInnerInner');
118
+ return (<div>
119
+ <h1>
120
+ {queryOuter.data} {queryInner.data} {queryInnerInner.data}
121
+ </h1>
122
+ </div>);
123
+ }
124
+ // contextSharing should be ignored when passing a custom context.
125
+ const contextSharing = true;
126
+ render(() => (<QueryClientProvider client={queryClientOuter} context={contextOuter}>
127
+ <QueryClientProvider client={queryClientInner} context={contextInner}>
128
+ <QueryClientProvider client={queryClientInnerInner} contextSharing={contextSharing}>
129
+ <Page />
130
+ </QueryClientProvider>
131
+ </QueryClientProvider>
132
+ </QueryClientProvider>));
133
+ await waitFor(() => screen.getByText('testOuter testInner testInnerInner'));
134
+ });
135
+ });
136
+ describe('useQueryClient', () => {
137
+ it('should throw an error if no query client has been set', () => {
138
+ const consoleMock = jest
139
+ .spyOn(console, 'error')
140
+ .mockImplementation(() => undefined);
141
+ function Page() {
142
+ useQueryClient();
143
+ return null;
144
+ }
145
+ expect(() => render(() => <Page />)).toThrow('No QueryClient set, use QueryClientProvider to set one');
146
+ consoleMock.mockRestore();
147
+ });
148
+ it('should use window to get the context when contextSharing is true', () => {
149
+ const queryCache = new QueryCache();
150
+ const queryClient = createQueryClient({ queryCache });
151
+ let queryClientFromHook;
152
+ let queryClientFromWindow;
153
+ function Page() {
154
+ queryClientFromHook = useQueryClient();
155
+ queryClientFromWindow = useContext(window.SolidQueryClientContext);
156
+ return null;
157
+ }
158
+ render(() => (<QueryClientProvider client={queryClient} contextSharing={true}>
159
+ <Page />
160
+ </QueryClientProvider>));
161
+ expect(queryClientFromHook).toEqual(queryClient);
162
+ expect(queryClientFromWindow).toEqual(queryClient);
163
+ });
164
+ it.skip('should not use window to get the context when contextSharing is true and window does not exist', () => {
165
+ const queryCache = new QueryCache();
166
+ const queryClient = createQueryClient({ queryCache });
167
+ // Mock a non web browser environment
168
+ const windowSpy = jest
169
+ .spyOn(window, 'window', 'get')
170
+ .mockImplementation(undefined);
171
+ let queryClientFromHook;
172
+ function Page() {
173
+ queryClientFromHook = useQueryClient();
174
+ return null;
175
+ }
176
+ // TODO(lukemurray): fails because renderToString never calls Page
177
+ // probably an SSR-testing issue we need to fix.
178
+ renderToString(() => (<QueryClientProvider client={queryClient} contextSharing={true}>
179
+ <Page />
180
+ </QueryClientProvider>));
181
+ expect(queryClientFromHook).toEqual(queryClient);
182
+ windowSpy.mockRestore();
183
+ });
184
+ });
185
+ });