@veams/status-quo-query 0.2.0 → 0.4.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.
@@ -1,12 +1,14 @@
1
-
2
- > @veams/status-quo-query@0.1.0 build
3
- > npm-run-all compile
4
-
5
-
6
- > @veams/status-quo-query@0.1.0 compile
7
- > npm-run-all bundle:ts
8
-
9
-
10
- > @veams/status-quo-query@0.1.0 bundle:ts
11
- > tsc --project tsconfig.json
12
-
1
+
2
+ 
3
+ > @veams/status-quo-query@0.3.0 build
4
+ > npm-run-all compile
5
+
6
+
7
+ > @veams/status-quo-query@0.3.0 compile
8
+ > npm-run-all bundle:ts
9
+
10
+
11
+ > @veams/status-quo-query@0.3.0 bundle:ts
12
+ > tsc --project tsconfig.json
13
+
14
+ ⠙⠙⠙
package/README.md CHANGED
@@ -12,7 +12,7 @@ npm install @veams/status-quo-query @tanstack/query-core
12
12
 
13
13
  Root exports:
14
14
 
15
- - `setupQueryProvider`
15
+ - `setupQueryManager`
16
16
  - `setupQuery`
17
17
  - `setupMutation`
18
18
  - `isQueryLoading`
@@ -20,7 +20,7 @@ Root exports:
20
20
  - `QueryFetchStatus`
21
21
  - `QueryStatus`
22
22
  - `MutationStatus`
23
- - `CacheApi`
23
+ - `QueryManager`
24
24
  - `CreateQuery`
25
25
  - `CreateMutation`
26
26
  - `QueryService`
@@ -43,32 +43,32 @@ Subpath exports:
43
43
  ```ts
44
44
  import { QueryClient } from '@tanstack/query-core';
45
45
  import {
46
- setupQueryProvider,
46
+ setupQueryManager,
47
47
  } from '@veams/status-quo-query';
48
48
 
49
49
  const queryClient = new QueryClient();
50
- const cache = setupQueryProvider(queryClient);
50
+ const manager = setupQueryManager(queryClient);
51
51
 
52
- const userQuery = cache.createQuery(['user', 42], () => fetchUser(42), {
52
+ const userQuery = manager.createQuery(['user', 42], () => fetchUser(42), {
53
53
  enabled: false,
54
54
  });
55
55
  await userQuery.refetch();
56
56
  await userQuery.invalidate({ refetchType: 'none' });
57
57
 
58
- const updateUser = cache.createMutation((payload: UpdateUserPayload) => saveUser(payload));
58
+ const updateUser = manager.createMutation((payload: UpdateUserPayload) => saveUser(payload));
59
59
  await updateUser.mutate({ id: 42 });
60
60
 
61
- await cache.invalidateQueries({ queryKey: ['user'] });
62
- cache.setQueryData(['user', 42], (current) => current);
61
+ await manager.invalidateQueries({ queryKey: ['user'] });
62
+ manager.setQueryData(['user', 42], (current) => current);
63
63
  ```
64
64
 
65
65
  ## API
66
66
 
67
- ### `setupQueryProvider(queryClient)`
67
+ ### `setupQueryManager(queryClient)`
68
68
 
69
- Creates the package-level cache facade around an existing TanStack `QueryClient`.
69
+ Creates the package-level query manager facade around an existing TanStack `QueryClient`.
70
70
 
71
- Returns `CacheApi` with:
71
+ Returns `QueryManager` with:
72
72
 
73
73
  - `createQuery(queryKey, queryFn, options?)`
74
74
  - `createMutation(mutationFn, options?)`
@@ -81,7 +81,7 @@ Returns `CacheApi` with:
81
81
  - `setQueryData(...)`
82
82
  - `unsafe_getClient()`
83
83
 
84
- All cache methods forward directly to the corresponding `QueryClient` methods. `unsafe_getClient()` returns the raw TanStack client as an explicit escape hatch.
84
+ All manager methods forward directly to the corresponding `QueryClient` methods. `unsafe_getClient()` returns the raw TanStack client as an explicit escape hatch.
85
85
 
86
86
  ### `setupQuery(queryClient)`
87
87
 
@@ -170,4 +170,4 @@ Creates a `createMutation` factory bound to a `QueryClient`.
170
170
  - `getSnapshot()` always returns passive state only.
171
171
  - Commands live on the handle itself: `refetch`, `invalidate`, `mutate`, `reset`.
172
172
  - Raw TanStack observer and client access is explicit through `unsafe_getResult()` and `unsafe_getClient()`.
173
- - Cache-level operations live on `setupQueryProvider()`, not on individual snapshots.
173
+ - Manager-level operations live on `setupQueryManager()`, not on individual snapshots.
package/dist/index.js CHANGED
@@ -1,4 +1,7 @@
1
+ // Re-export all mutation-related types and functions.
1
2
  export * from './mutation';
3
+ // Re-export all query-related types and functions.
2
4
  export * from './query';
5
+ // Re-export all provider-related types and functions for cache management.
3
6
  export * from './provider';
4
7
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,cAAc,YAAY,CAAC;AAC3B,mDAAmD;AACnD,cAAc,SAAS,CAAC;AACxB,2EAA2E;AAC3E,cAAc,YAAY,CAAC"}
@@ -1,5 +1,8 @@
1
1
  import { type MutationFunction, type MutateOptions, type MutationObserverOptions, type MutationObserverResult, type MutationStatus as TanstackMutationStatus, type QueryClient } from '@tanstack/query-core';
2
2
  export type MutationStatus = TanstackMutationStatus;
3
+ /**
4
+ * Represents a stable snapshot of the mutation service's state.
5
+ */
3
6
  export interface MutationServiceSnapshot<TData = unknown, TError = Error, TVariables = void> {
4
7
  data: TData | undefined;
5
8
  error: TError | null;
@@ -10,6 +13,9 @@ export interface MutationServiceSnapshot<TData = unknown, TError = Error, TVaria
10
13
  isPending: boolean;
11
14
  isSuccess: boolean;
12
15
  }
16
+ /**
17
+ * Defines the public API for a mutation service.
18
+ */
13
19
  export interface MutationService<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown> {
14
20
  getSnapshot: () => MutationServiceSnapshot<TData, TError, TVariables>;
15
21
  subscribe: (listener: (snapshot: MutationServiceSnapshot<TData, TError, TVariables>) => void) => () => void;
@@ -17,8 +23,17 @@ export interface MutationService<TData = unknown, TError = Error, TVariables = v
17
23
  reset: () => void;
18
24
  unsafe_getResult: () => MutationObserverResult<TData, TError, TVariables, TOnMutateResult>;
19
25
  }
26
+ /**
27
+ * Configuration options for creating a mutation service, excluding the mutation function itself.
28
+ */
20
29
  export type MutationServiceOptions<TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown> = Omit<MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>, 'mutationFn'>;
30
+ /**
31
+ * Function signature for the mutation factory.
32
+ */
21
33
  export interface CreateMutation {
22
34
  <TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>(mutationFn: MutationFunction<TData, TVariables>, options?: MutationServiceOptions<TData, TError, TVariables, TOnMutateResult>): MutationService<TData, TError, TVariables, TOnMutateResult>;
23
35
  }
36
+ /**
37
+ * Prepares the mutation factory by binding it to a specific QueryClient instance.
38
+ */
24
39
  export declare function setupMutation(queryClient: QueryClient): CreateMutation;
package/dist/mutation.js CHANGED
@@ -1,22 +1,39 @@
1
- import { MutationObserver, } from '@tanstack/query-core';
1
+ import {
2
+ // Import MutationObserver to observe and manage mutations.
3
+ MutationObserver, } from '@tanstack/query-core';
4
+ /**
5
+ * Prepares the mutation factory by binding it to a specific QueryClient instance.
6
+ */
2
7
  export function setupMutation(queryClient) {
8
+ // Returns the actual factory function for creating individual mutation services.
3
9
  return function createMutation(mutationFn, options) {
10
+ // Create a new MutationObserver instance to manage this specific mutation's lifecycle.
4
11
  const observer = new MutationObserver(queryClient, {
5
12
  ...options,
6
13
  mutationFn,
7
14
  });
15
+ // Return the implementation of the MutationService interface.
8
16
  return {
17
+ // Map the current observer state to our service's snapshot format.
9
18
  getSnapshot: () => toMutationServiceSnapshot(observer.getCurrentResult()),
19
+ // Subscribe to observer changes and notify the listener with updated snapshots.
10
20
  subscribe: (listener) => observer.subscribe((result) => {
11
21
  listener(toMutationServiceSnapshot(result));
12
22
  }),
23
+ // Proxy the mutate call to the underlying observer.
13
24
  mutate: (variables, mutateOptions) => observer.mutate(variables, mutateOptions),
25
+ // Reset the underlying observer state.
14
26
  reset: () => observer.reset(),
27
+ // Provide direct access to the raw observer result when needed.
15
28
  unsafe_getResult: () => observer.getCurrentResult(),
16
29
  };
17
30
  };
18
31
  }
32
+ /**
33
+ * Internal helper to transform a raw Tanstack mutation result into our public snapshot format.
34
+ */
19
35
  function toMutationServiceSnapshot(result) {
36
+ // Extract and return the relevant fields for the UI or other services.
20
37
  return {
21
38
  data: result.data,
22
39
  error: result.error,
@@ -1 +1 @@
1
- {"version":3,"file":"mutation.js","sourceRoot":"","sources":["../src/mutation.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,gBAAgB,GAOjB,MAAM,sBAAsB,CAAC;AA+C9B,MAAM,UAAU,aAAa,CAAC,WAAwB;IACpD,OAAO,SAAS,cAAc,CAM5B,UAA+C,EAC/C,OAA4E;QAE5E,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CACnC,WAAW,EACX;YACE,GAAG,OAAO;YACV,UAAU;SACX,CACF,CAAC;QAEF,OAAO;YACL,WAAW,EAAE,GAAG,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YACzE,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5B,QAAQ,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9C,CAAC,CAAC;YACJ,MAAM,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;YAC/E,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE;YAC7B,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE;SACpD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,yBAAyB,CAChC,MAA0E;IAE1E,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"mutation.js","sourceRoot":"","sources":["../src/mutation.ts"],"names":[],"mappings":"AAAA,OAAO;AACL,2DAA2D;AAC3D,gBAAgB,GAajB,MAAM,sBAAsB,CAAC;AA2E9B;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,WAAwB;IACpD,iFAAiF;IACjF,OAAO,SAAS,cAAc,CAM5B,UAA+C,EAC/C,OAA4E;QAE5E,uFAAuF;QACvF,MAAM,QAAQ,GAAG,IAAI,gBAAgB,CACnC,WAAW,EACX;YACE,GAAG,OAAO;YACV,UAAU;SACX,CACF,CAAC;QAEF,8DAA8D;QAC9D,OAAO;YACL,mEAAmE;YACnE,WAAW,EAAE,GAAG,EAAE,CAAC,yBAAyB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YACzE,gFAAgF;YAChF,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5B,QAAQ,CAAC,yBAAyB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC9C,CAAC,CAAC;YACJ,oDAAoD;YACpD,MAAM,EAAE,CAAC,SAAS,EAAE,aAAa,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,EAAE,aAAa,CAAC;YAC/E,uCAAuC;YACvC,KAAK,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE;YAC7B,gEAAgE;YAChE,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE;SACpD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,yBAAyB,CAChC,MAA0E;IAE1E,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC"}
@@ -1,7 +1,10 @@
1
1
  import { type QueryClient } from '@tanstack/query-core';
2
2
  import { type CreateMutation } from './mutation';
3
3
  import { type CreateQuery } from './query';
4
- export interface CacheApi {
4
+ /**
5
+ * Defines the public API for the query manager facade.
6
+ */
7
+ export interface QueryManager {
5
8
  createMutation: CreateMutation;
6
9
  createQuery: CreateQuery;
7
10
  cancelQueries: QueryClient['cancelQueries'];
@@ -13,4 +16,7 @@ export interface CacheApi {
13
16
  setQueryData: QueryClient['setQueryData'];
14
17
  unsafe_getClient: () => QueryClient;
15
18
  }
16
- export declare function setupQueryProvider(queryClient: QueryClient): CacheApi;
19
+ /**
20
+ * Prepares the query manager facade by binding all actions to a specific QueryClient instance.
21
+ */
22
+ export declare function setupQueryManager(queryClient: QueryClient): QueryManager;
package/dist/provider.js CHANGED
@@ -1,16 +1,31 @@
1
+ // Import mutation and query setup functions and their factory types.
1
2
  import { setupMutation } from './mutation';
2
3
  import { setupQuery } from './query';
3
- export function setupQueryProvider(queryClient) {
4
+ /**
5
+ * Prepares the query manager facade by binding all actions to a specific QueryClient instance.
6
+ */
7
+ export function setupQueryManager(queryClient) {
8
+ // Return the implementation of the QueryManager interface.
4
9
  return {
10
+ // Bind mutation factory to this QueryClient.
5
11
  createMutation: setupMutation(queryClient),
12
+ // Bind query factory to this QueryClient.
6
13
  createQuery: setupQuery(queryClient),
14
+ // Proxy for canceling queries with this client context.
7
15
  cancelQueries: queryClient.cancelQueries.bind(queryClient),
16
+ // Proxy for retrieving query data with this client context.
8
17
  getQueryData: queryClient.getQueryData.bind(queryClient),
18
+ // Proxy for invalidating queries with this client context.
9
19
  invalidateQueries: queryClient.invalidateQueries.bind(queryClient),
20
+ // Proxy for refetching queries with this client context.
10
21
  refetchQueries: queryClient.refetchQueries.bind(queryClient),
22
+ // Proxy for removing queries with this client context.
11
23
  removeQueries: queryClient.removeQueries.bind(queryClient),
24
+ // Proxy for resetting queries with this client context.
12
25
  resetQueries: queryClient.resetQueries.bind(queryClient),
26
+ // Proxy for setting query data with this client context.
13
27
  setQueryData: queryClient.setQueryData.bind(queryClient),
28
+ // Provide an accessor for the raw client instance.
14
29
  unsafe_getClient: () => queryClient,
15
30
  };
16
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAoB,UAAU,EAAE,MAAM,SAAS,CAAC;AAevD,MAAM,UAAU,kBAAkB,CAAC,WAAwB;IACzD,OAAO;QACL,cAAc,EAAE,aAAa,CAAC,WAAW,CAAC;QAC1C,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC;QACpC,aAAa,EAAE,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1D,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,iBAAiB,EAAE,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAClE,cAAc,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5D,aAAa,EAAE,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1D,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,gBAAgB,EAAE,GAAG,EAAE,CAAC,WAAW;KACpC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAKA,qEAAqE;AACrE,OAAO,EAAuB,aAAa,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAoB,UAAU,EAAE,MAAM,SAAS,CAAC;AA4BvD;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAwB;IACxD,2DAA2D;IAC3D,OAAO;QACL,6CAA6C;QAC7C,cAAc,EAAE,aAAa,CAAC,WAAW,CAAC;QAC1C,0CAA0C;QAC1C,WAAW,EAAE,UAAU,CAAC,WAAW,CAAC;QACpC,wDAAwD;QACxD,aAAa,EAAE,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1D,4DAA4D;QAC5D,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,2DAA2D;QAC3D,iBAAiB,EAAE,WAAW,CAAC,iBAAiB,CAAC,IAAI,CAAC,WAAW,CAAC;QAClE,yDAAyD;QACzD,cAAc,EAAE,WAAW,CAAC,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC;QAC5D,uDAAuD;QACvD,aAAa,EAAE,WAAW,CAAC,aAAa,CAAC,IAAI,CAAC,WAAW,CAAC;QAC1D,wDAAwD;QACxD,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,yDAAyD;QACzD,YAAY,EAAE,WAAW,CAAC,YAAY,CAAC,IAAI,CAAC,WAAW,CAAC;QACxD,mDAAmD;QACnD,gBAAgB,EAAE,GAAG,EAAE,CAAC,WAAW;KACpC,CAAC;AACJ,CAAC"}
package/dist/query.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import { type FetchStatus, type InvalidateOptions, type InvalidateQueryFilters, type QueryClient, type QueryFunction, type QueryKey, type QueryObserverOptions, type QueryObserverResult, type RefetchOptions, type QueryStatus as TanstackQueryStatus } from '@tanstack/query-core';
2
2
  export type QueryFetchStatus = FetchStatus;
3
3
  export type QueryStatus = TanstackQueryStatus;
4
+ /**
5
+ * Represents a stable snapshot of the query service's state.
6
+ */
4
7
  export interface QueryServiceSnapshot<TData, TError> {
5
8
  data: TData | undefined;
6
9
  error: TError | null;
@@ -11,10 +14,16 @@ export interface QueryServiceSnapshot<TData, TError> {
11
14
  isPending: boolean;
12
15
  isSuccess: boolean;
13
16
  }
17
+ /**
18
+ * Defines a subset of query state containing only the status and fetch status.
19
+ */
14
20
  export interface QueryMetaState {
15
21
  fetchStatus: QueryFetchStatus;
16
22
  status: QueryStatus;
17
23
  }
24
+ /**
25
+ * Defines the public API for a query service.
26
+ */
18
27
  export interface QueryService<TData, TError> {
19
28
  getSnapshot: () => QueryServiceSnapshot<TData, TError>;
20
29
  subscribe: (listener: (snapshot: QueryServiceSnapshot<TData, TError>) => void) => () => void;
@@ -22,12 +31,30 @@ export interface QueryService<TData, TError> {
22
31
  invalidate: (options?: QueryInvalidateOptions) => Promise<void>;
23
32
  unsafe_getResult: () => QueryObserverResult<TData, TError>;
24
33
  }
34
+ /**
35
+ * Combines options for invalidation behavior and filtering.
36
+ */
25
37
  export interface QueryInvalidateOptions extends Pick<InvalidateOptions, 'cancelRefetch' | 'throwOnError'>, Pick<InvalidateQueryFilters, 'refetchType'> {
26
38
  }
39
+ /**
40
+ * Function signature for the query factory.
41
+ */
27
42
  export interface CreateQuery {
28
43
  <TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey>(queryKey: TQueryKey, queryFn: QueryFunction<TQueryFnData, TQueryKey>, options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>): QueryService<TData, TError>;
29
44
  }
45
+ /**
46
+ * Configuration options for creating a query service, excluding function and key.
47
+ */
30
48
  export type QueryServiceOptions<TQueryFnData = unknown, TError = Error, TData = TQueryFnData, TQueryData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> = Omit<QueryObserverOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>, 'queryFn' | 'queryKey'>;
49
+ /**
50
+ * Extracts and maps status and fetchStatus to our QueryMetaState interface.
51
+ */
31
52
  export declare function toQueryMetaState<TData, TError>(snapshot: Pick<QueryServiceSnapshot<TData, TError>, 'fetchStatus' | 'status'>): QueryMetaState;
53
+ /**
54
+ * Helper function to check if the query is in its initial loading state.
55
+ */
32
56
  export declare function isQueryLoading(query: QueryMetaState): boolean;
57
+ /**
58
+ * Prepares the query factory by binding it to a specific QueryClient instance.
59
+ */
33
60
  export declare function setupQuery(queryClient: QueryClient): CreateQuery;
package/dist/query.js CHANGED
@@ -1,36 +1,61 @@
1
- import { QueryObserver, } from '@tanstack/query-core';
1
+ import {
2
+ // Import QueryObserver to monitor and manage individual queries.
3
+ QueryObserver, } from '@tanstack/query-core';
4
+ /**
5
+ * Extracts and maps status and fetchStatus to our QueryMetaState interface.
6
+ */
2
7
  export function toQueryMetaState(snapshot) {
8
+ // Return a simplified state object for UI or other services.
3
9
  return {
4
10
  fetchStatus: snapshot.fetchStatus,
5
11
  status: snapshot.status,
6
12
  };
7
13
  }
14
+ /**
15
+ * Helper function to check if the query is in its initial loading state.
16
+ */
8
17
  export function isQueryLoading(query) {
18
+ // Returns true if the query is both pending and actively fetching.
9
19
  return query.status === 'pending' && query.fetchStatus === 'fetching';
10
20
  }
21
+ /**
22
+ * Prepares the query factory by binding it to a specific QueryClient instance.
23
+ */
11
24
  export function setupQuery(queryClient) {
25
+ // Returns the actual factory function for creating individual query services.
12
26
  return function createQuery(queryKey, queryFn, options) {
27
+ // Create a new QueryObserver instance to manage this specific query's lifecycle.
13
28
  const observer = new QueryObserver(queryClient, {
14
29
  ...options,
15
30
  queryFn,
16
31
  queryKey,
17
32
  });
33
+ // Return the implementation of the QueryService interface.
18
34
  return {
35
+ // Map the current observer state to our service's snapshot format.
19
36
  getSnapshot: () => toQueryServiceSnapshot(observer.getCurrentResult()),
37
+ // Subscribe to observer changes and notify the listener with updated snapshots.
20
38
  subscribe: (listener) => observer.subscribe((result) => {
21
39
  listener(toQueryServiceSnapshot(result));
22
40
  }),
41
+ // Proxy the refetch call and map the async result back to a snapshot.
23
42
  refetch: async (options) => toQueryServiceSnapshot(await observer.refetch(options)),
43
+ // Trigger a targeted invalidation using the query's key and custom options.
24
44
  invalidate: (options) => queryClient.invalidateQueries({
25
45
  exact: true,
26
46
  queryKey,
27
47
  ...(options?.refetchType === undefined ? {} : { refetchType: options.refetchType }),
28
48
  }, toInvalidateOptions(options)),
49
+ // Provide direct access to the raw observer result when needed.
29
50
  unsafe_getResult: () => observer.getCurrentResult(),
30
51
  };
31
52
  };
32
53
  }
54
+ /**
55
+ * Internal helper to transform a raw Tanstack query result into our public snapshot format.
56
+ */
33
57
  function toQueryServiceSnapshot(result) {
58
+ // Extract and return the relevant fields for the UI or other services.
34
59
  return {
35
60
  data: result.data,
36
61
  error: result.error,
@@ -42,14 +67,20 @@ function toQueryServiceSnapshot(result) {
42
67
  isSuccess: result.isSuccess,
43
68
  };
44
69
  }
70
+ /**
71
+ * Internal helper to safely transform our QueryInvalidateOptions to Tanstack InvalidateOptions.
72
+ */
45
73
  function toInvalidateOptions(options) {
74
+ // Return undefined if no options were provided.
46
75
  if (options === undefined) {
47
76
  return undefined;
48
77
  }
78
+ // Construct and filter the options object to avoid passing undefined values.
49
79
  const invalidateOptions = {
50
80
  ...(options.cancelRefetch === undefined ? {} : { cancelRefetch: options.cancelRefetch }),
51
81
  ...(options.throwOnError === undefined ? {} : { throwOnError: options.throwOnError }),
52
82
  };
83
+ // Return the resulting object if it contains any relevant properties.
53
84
  return Object.keys(invalidateOptions).length > 0 ? invalidateOptions : undefined;
54
85
  }
55
86
  //# sourceMappingURL=query.js.map
package/dist/query.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO,EAOL,aAAa,GAKd,MAAM,sBAAsB,CAAC;AA0D9B,MAAM,UAAU,gBAAgB,CAC9B,QAA6E;IAE7E,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC;AACxE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAwB;IACjD,OAAO,SAAS,WAAW,CAOzB,QAAmB,EACnB,OAA+C,EAC/C,OAAiF;QAEjF,MAAM,QAAQ,GAAG,IAAI,aAAa,CAChC,WAAW,EACX;YACE,GAAG,OAAO;YACV,OAAO;YACP,QAAQ;SACT,CACF,CAAC;QAEF,OAAO;YACL,WAAW,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YACtE,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5B,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC;YACJ,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnF,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CACtB,WAAW,CAAC,iBAAiB,CAC3B;gBACE,KAAK,EAAE,IAAI;gBACX,QAAQ;gBACR,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;aACpF,EACD,mBAAmB,CAAC,OAAO,CAAC,CAC7B;YACH,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE;SACpD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,SAAS,sBAAsB,CAC7B,MAA0C;IAE1C,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAgC;IAC3D,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,iBAAiB,GAAsB;QAC3C,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;KACtF,CAAC;IAEF,OAAO,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC"}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../src/query.ts"],"names":[],"mappings":"AAAA,OAAO;AAaL,iEAAiE;AACjE,aAAa,GASd,MAAM,sBAAsB,CAAC;AA6F9B;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,QAA6E;IAE7E,6DAA6D;IAC7D,OAAO;QACL,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,MAAM,EAAE,QAAQ,CAAC,MAAM;KACxB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,KAAqB;IAClD,mEAAmE;IACnE,OAAO,KAAK,CAAC,MAAM,KAAK,SAAS,IAAI,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,WAAwB;IACjD,8EAA8E;IAC9E,OAAO,SAAS,WAAW,CAOzB,QAAmB,EACnB,OAA+C,EAC/C,OAAiF;QAEjF,iFAAiF;QACjF,MAAM,QAAQ,GAAG,IAAI,aAAa,CAChC,WAAW,EACX;YACE,GAAG,OAAO;YACV,OAAO;YACP,QAAQ;SACT,CACF,CAAC;QAEF,2DAA2D;QAC3D,OAAO;YACL,mEAAmE;YACnE,WAAW,EAAE,GAAG,EAAE,CAAC,sBAAsB,CAAC,QAAQ,CAAC,gBAAgB,EAAE,CAAC;YACtE,gFAAgF;YAChF,SAAS,EAAE,CAAC,QAAQ,EAAE,EAAE,CACtB,QAAQ,CAAC,SAAS,CAAC,CAAC,MAAM,EAAE,EAAE;gBAC5B,QAAQ,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC3C,CAAC,CAAC;YACJ,sEAAsE;YACtE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CAAC,sBAAsB,CAAC,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACnF,4EAA4E;YAC5E,UAAU,EAAE,CAAC,OAAO,EAAE,EAAE,CACtB,WAAW,CAAC,iBAAiB,CAC3B;gBACE,KAAK,EAAE,IAAI;gBACX,QAAQ;gBACR,GAAG,CAAC,OAAO,EAAE,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,CAAC;aACpF,EACD,mBAAmB,CAAC,OAAO,CAAC,CAC7B;YACH,gEAAgE;YAChE,gBAAgB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,gBAAgB,EAAE;SACpD,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAC7B,MAA0C;IAE1C,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,WAAW,EAAE,MAAM,CAAC,WAAW;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,SAAS,mBAAmB,CAAC,OAAgC;IAC3D,gDAAgD;IAChD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,6EAA6E;IAC7E,MAAM,iBAAiB,GAAsB;QAC3C,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,aAAa,EAAE,CAAC;QACxF,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,OAAO,CAAC,YAAY,EAAE,CAAC;KACtF,CAAC;IAEF,sEAAsE;IACtE,OAAO,MAAM,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,SAAS,CAAC;AACnF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veams/status-quo-query",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "TanStack Query service layer for the VEAMS StatusQuo ecosystem.",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -1,27 +1,27 @@
1
1
  import { QueryClient } from '@tanstack/query-core';
2
2
 
3
- import { setupQueryProvider } from '../provider';
3
+ import { setupQueryManager } from '../provider';
4
4
 
5
- describe('Cache API', () => {
6
- it('exposes cache-level query client operations', async () => {
5
+ describe('Query Manager API', () => {
6
+ it('exposes manager-level query client operations', async () => {
7
7
  const queryClient = new QueryClient({ defaultOptions: { queries: { retry: 0 } } });
8
8
  const invalidateQueriesSpy = jest.spyOn(queryClient, 'invalidateQueries');
9
9
  const refetchQueriesSpy = jest.spyOn(queryClient, 'refetchQueries');
10
10
  const cancelQueriesSpy = jest.spyOn(queryClient, 'cancelQueries');
11
11
  const resetQueriesSpy = jest.spyOn(queryClient, 'resetQueries');
12
12
  const removeQueriesSpy = jest.spyOn(queryClient, 'removeQueries');
13
- const cache = setupQueryProvider(queryClient);
13
+ const manager = setupQueryManager(queryClient);
14
14
 
15
- cache.setQueryData<{ id: number }>(['user', 42], { id: 42 });
15
+ manager.setQueryData<{ id: number }>(['user', 42], { id: 42 });
16
16
 
17
- expect(cache.getQueryData<{ id: number }>(['user', 42])).toEqual({ id: 42 });
18
- expect(cache.unsafe_getClient()).toBe(queryClient);
17
+ expect(manager.getQueryData<{ id: number }>(['user', 42])).toEqual({ id: 42 });
18
+ expect(manager.unsafe_getClient()).toBe(queryClient);
19
19
 
20
- await cache.invalidateQueries({ queryKey: ['user'] });
21
- await cache.refetchQueries({ queryKey: ['user'] });
22
- await cache.cancelQueries({ queryKey: ['user'] });
23
- await cache.resetQueries({ queryKey: ['user'] });
24
- cache.removeQueries({ queryKey: ['user'] });
20
+ await manager.invalidateQueries({ queryKey: ['user'] });
21
+ await manager.refetchQueries({ queryKey: ['user'] });
22
+ await manager.cancelQueries({ queryKey: ['user'] });
23
+ await manager.resetQueries({ queryKey: ['user'] });
24
+ manager.removeQueries({ queryKey: ['user'] });
25
25
 
26
26
  expect(invalidateQueriesSpy).toHaveBeenCalledWith({ queryKey: ['user'] });
27
27
  expect(refetchQueriesSpy).toHaveBeenCalledWith({ queryKey: ['user'] });
package/src/index.ts CHANGED
@@ -1,3 +1,6 @@
1
+ // Re-export all mutation-related types and functions.
1
2
  export * from './mutation';
3
+ // Re-export all query-related types and functions.
2
4
  export * from './query';
5
+ // Re-export all provider-related types and functions for cache management.
3
6
  export * from './provider';
package/src/mutation.ts CHANGED
@@ -1,44 +1,74 @@
1
1
  import {
2
+ // Import MutationObserver to observe and manage mutations.
2
3
  MutationObserver,
4
+ // Import type for the mutation function itself.
3
5
  type MutationFunction,
6
+ // Import options for executing a mutation.
4
7
  type MutateOptions,
8
+ // Import configuration options for the mutation observer.
5
9
  type MutationObserverOptions,
10
+ // Import the shape of the result returned by the mutation observer.
6
11
  type MutationObserverResult,
12
+ // Import the status enum for mutations from Tanstack Query.
7
13
  type MutationStatus as TanstackMutationStatus,
14
+ // Import the central QueryClient to interact with the cache.
8
15
  type QueryClient,
9
16
  } from '@tanstack/query-core';
10
17
 
18
+ // Re-export MutationStatus for consistent naming within the service.
11
19
  export type MutationStatus = TanstackMutationStatus;
12
20
 
21
+ /**
22
+ * Represents a stable snapshot of the mutation service's state.
23
+ */
13
24
  export interface MutationServiceSnapshot<TData = unknown, TError = Error, TVariables = void> {
25
+ // The data returned from a successful mutation.
14
26
  data: TData | undefined;
27
+ // The error object if the mutation failed.
15
28
  error: TError | null;
29
+ // The current lifecycle status (idle, pending, success, error).
16
30
  status: MutationStatus;
31
+ // The variables used for the most recent mutation call.
17
32
  variables: TVariables | undefined;
33
+ // Convenience flag: true if the status is 'error'.
18
34
  isError: boolean;
35
+ // Convenience flag: true if the status is 'idle'.
19
36
  isIdle: boolean;
37
+ // Convenience flag: true if the status is 'pending'.
20
38
  isPending: boolean;
39
+ // Convenience flag: true if the status is 'success'.
21
40
  isSuccess: boolean;
22
41
  }
23
42
 
43
+ /**
44
+ * Defines the public API for a mutation service.
45
+ */
24
46
  export interface MutationService<
25
47
  TData = unknown,
26
48
  TError = Error,
27
49
  TVariables = void,
28
50
  TOnMutateResult = unknown,
29
51
  > {
52
+ // Returns the current state snapshot of the mutation.
30
53
  getSnapshot: () => MutationServiceSnapshot<TData, TError, TVariables>;
54
+ // Subscribes a listener to state changes; returns an unsubscribe function.
31
55
  subscribe: (
32
56
  listener: (snapshot: MutationServiceSnapshot<TData, TError, TVariables>) => void
33
57
  ) => () => void;
58
+ // Triggers the mutation with the given variables and optional lifecycle callbacks.
34
59
  mutate: (
35
60
  variables: TVariables,
36
61
  options?: MutateOptions<TData, TError, TVariables, TOnMutateResult>
37
62
  ) => Promise<TData>;
63
+ // Resets the mutation state back to its initial idle state.
38
64
  reset: () => void;
65
+ // Escape hatch: provides direct access to the underlying Tanstack Query observer result.
39
66
  unsafe_getResult: () => MutationObserverResult<TData, TError, TVariables, TOnMutateResult>;
40
67
  }
41
68
 
69
+ /**
70
+ * Configuration options for creating a mutation service, excluding the mutation function itself.
71
+ */
42
72
  export type MutationServiceOptions<
43
73
  TData = unknown,
44
74
  TError = Error,
@@ -46,14 +76,23 @@ export type MutationServiceOptions<
46
76
  TOnMutateResult = unknown,
47
77
  > = Omit<MutationObserverOptions<TData, TError, TVariables, TOnMutateResult>, 'mutationFn'>;
48
78
 
79
+ /**
80
+ * Function signature for the mutation factory.
81
+ */
49
82
  export interface CreateMutation {
50
83
  <TData = unknown, TError = Error, TVariables = void, TOnMutateResult = unknown>(
84
+ // The asynchronous function that performs the mutation.
51
85
  mutationFn: MutationFunction<TData, TVariables>,
86
+ // Optional configuration for behavior like retry or lifecycle hooks.
52
87
  options?: MutationServiceOptions<TData, TError, TVariables, TOnMutateResult>
53
88
  ): MutationService<TData, TError, TVariables, TOnMutateResult>;
54
89
  }
55
90
 
91
+ /**
92
+ * Prepares the mutation factory by binding it to a specific QueryClient instance.
93
+ */
56
94
  export function setupMutation(queryClient: QueryClient): CreateMutation {
95
+ // Returns the actual factory function for creating individual mutation services.
57
96
  return function createMutation<
58
97
  TData = unknown,
59
98
  TError = Error,
@@ -63,6 +102,7 @@ export function setupMutation(queryClient: QueryClient): CreateMutation {
63
102
  mutationFn: MutationFunction<TData, TVariables>,
64
103
  options?: MutationServiceOptions<TData, TError, TVariables, TOnMutateResult>
65
104
  ): MutationService<TData, TError, TVariables, TOnMutateResult> {
105
+ // Create a new MutationObserver instance to manage this specific mutation's lifecycle.
66
106
  const observer = new MutationObserver<TData, TError, TVariables, TOnMutateResult>(
67
107
  queryClient,
68
108
  {
@@ -71,22 +111,32 @@ export function setupMutation(queryClient: QueryClient): CreateMutation {
71
111
  }
72
112
  );
73
113
 
114
+ // Return the implementation of the MutationService interface.
74
115
  return {
116
+ // Map the current observer state to our service's snapshot format.
75
117
  getSnapshot: () => toMutationServiceSnapshot(observer.getCurrentResult()),
118
+ // Subscribe to observer changes and notify the listener with updated snapshots.
76
119
  subscribe: (listener) =>
77
120
  observer.subscribe((result) => {
78
121
  listener(toMutationServiceSnapshot(result));
79
122
  }),
123
+ // Proxy the mutate call to the underlying observer.
80
124
  mutate: (variables, mutateOptions) => observer.mutate(variables, mutateOptions),
125
+ // Reset the underlying observer state.
81
126
  reset: () => observer.reset(),
127
+ // Provide direct access to the raw observer result when needed.
82
128
  unsafe_getResult: () => observer.getCurrentResult(),
83
129
  };
84
130
  };
85
131
  }
86
132
 
133
+ /**
134
+ * Internal helper to transform a raw Tanstack mutation result into our public snapshot format.
135
+ */
87
136
  function toMutationServiceSnapshot<TData, TError, TVariables, TOnMutateResult>(
88
137
  result: MutationObserverResult<TData, TError, TVariables, TOnMutateResult>
89
138
  ): MutationServiceSnapshot<TData, TError, TVariables> {
139
+ // Extract and return the relevant fields for the UI or other services.
90
140
  return {
91
141
  data: result.data,
92
142
  error: result.error,
package/src/provider.ts CHANGED
@@ -1,34 +1,63 @@
1
1
  import {
2
+ // Import the central QueryClient to handle management and state management.
2
3
  type QueryClient,
3
4
  } from '@tanstack/query-core';
4
5
 
6
+ // Import mutation and query setup functions and their factory types.
5
7
  import { type CreateMutation, setupMutation } from './mutation';
6
8
  import { type CreateQuery, setupQuery } from './query';
7
9
 
8
- export interface CacheApi {
10
+ /**
11
+ * Defines the public API for the query manager facade.
12
+ */
13
+ export interface QueryManager {
14
+ // Factory for creating a mutation service within the context of this provider.
9
15
  createMutation: CreateMutation;
16
+ // Factory for creating a query service within the context of this provider.
10
17
  createQuery: CreateQuery;
18
+ // Cancels active queries for the specified filters.
11
19
  cancelQueries: QueryClient['cancelQueries'];
20
+ // Synchronously retrieves a snapshot of the current query data.
12
21
  getQueryData: QueryClient['getQueryData'];
22
+ // Marks queries as invalid to trigger a refetch if they are active.
13
23
  invalidateQueries: QueryClient['invalidateQueries'];
24
+ // Forces a refetch of queries matching the specified filters.
14
25
  refetchQueries: QueryClient['refetchQueries'];
26
+ // Removes queries from the management without canceling ongoing requests.
15
27
  removeQueries: QueryClient['removeQueries'];
28
+ // Resets queries to their initial state and refetches them.
16
29
  resetQueries: QueryClient['resetQueries'];
30
+ // Manually sets or updates data for a specific query in the manager.
17
31
  setQueryData: QueryClient['setQueryData'];
32
+ // Escape hatch: provides direct access to the underlying Tanstack QueryClient.
18
33
  unsafe_getClient: () => QueryClient;
19
34
  }
20
35
 
21
- export function setupQueryProvider(queryClient: QueryClient): CacheApi {
36
+ /**
37
+ * Prepares the query manager facade by binding all actions to a specific QueryClient instance.
38
+ */
39
+ export function setupQueryManager(queryClient: QueryClient): QueryManager {
40
+ // Return the implementation of the QueryManager interface.
22
41
  return {
42
+ // Bind mutation factory to this QueryClient.
23
43
  createMutation: setupMutation(queryClient),
44
+ // Bind query factory to this QueryClient.
24
45
  createQuery: setupQuery(queryClient),
46
+ // Proxy for canceling queries with this client context.
25
47
  cancelQueries: queryClient.cancelQueries.bind(queryClient),
48
+ // Proxy for retrieving query data with this client context.
26
49
  getQueryData: queryClient.getQueryData.bind(queryClient),
50
+ // Proxy for invalidating queries with this client context.
27
51
  invalidateQueries: queryClient.invalidateQueries.bind(queryClient),
52
+ // Proxy for refetching queries with this client context.
28
53
  refetchQueries: queryClient.refetchQueries.bind(queryClient),
54
+ // Proxy for removing queries with this client context.
29
55
  removeQueries: queryClient.removeQueries.bind(queryClient),
56
+ // Proxy for resetting queries with this client context.
30
57
  resetQueries: queryClient.resetQueries.bind(queryClient),
58
+ // Proxy for setting query data with this client context.
31
59
  setQueryData: queryClient.setQueryData.bind(queryClient),
60
+ // Provide an accessor for the raw client instance.
32
61
  unsafe_getClient: () => queryClient,
33
62
  };
34
63
  }
package/src/query.ts CHANGED
@@ -1,48 +1,88 @@
1
1
  import {
2
+ // Import the fetch status enum (idle, fetching, paused).
2
3
  type FetchStatus,
4
+ // Import options for invalidating queries from the cache.
3
5
  type InvalidateOptions,
6
+ // Import filters to target specific queries during invalidation.
4
7
  type InvalidateQueryFilters,
8
+ // Import the central QueryClient to interact with the cache.
5
9
  type QueryClient,
10
+ // Import the function signature for an individual query.
6
11
  type QueryFunction,
12
+ // Import the stable identifier for a specific query in the cache.
7
13
  type QueryKey,
14
+ // Import QueryObserver to monitor and manage individual queries.
8
15
  QueryObserver,
16
+ // Import configuration options for the query observer.
9
17
  type QueryObserverOptions,
18
+ // Import the result shape returned by the query observer.
10
19
  type QueryObserverResult,
20
+ // Import options for manually refetching a query.
11
21
  type RefetchOptions,
22
+ // Import the status enum for query results (pending, success, error).
12
23
  type QueryStatus as TanstackQueryStatus,
13
24
  } from '@tanstack/query-core';
14
25
 
26
+ // Re-export FetchStatus and QueryStatus for internal naming consistency.
15
27
  export type QueryFetchStatus = FetchStatus;
16
28
  export type QueryStatus = TanstackQueryStatus;
17
29
 
30
+ /**
31
+ * Represents a stable snapshot of the query service's state.
32
+ */
18
33
  export interface QueryServiceSnapshot<TData, TError> {
34
+ // The data retrieved from a successful query.
19
35
  data: TData | undefined;
36
+ // The error object if the query failed.
20
37
  error: TError | null;
38
+ // The current network fetch status (idle, fetching, paused).
21
39
  fetchStatus: QueryFetchStatus;
40
+ // The current lifecycle status of the query (pending, success, error).
22
41
  status: QueryStatus;
42
+ // Convenience flag: true if the status is 'error'.
23
43
  isError: boolean;
44
+ // Convenience flag: true if the query is currently fetching data.
24
45
  isFetching: boolean;
46
+ // Convenience flag: true if the query is in the pending state.
25
47
  isPending: boolean;
48
+ // Convenience flag: true if the status is 'success'.
26
49
  isSuccess: boolean;
27
50
  }
28
51
 
52
+ /**
53
+ * Defines a subset of query state containing only the status and fetch status.
54
+ */
29
55
  export interface QueryMetaState {
30
56
  fetchStatus: QueryFetchStatus;
31
57
  status: QueryStatus;
32
58
  }
33
59
 
60
+ /**
61
+ * Defines the public API for a query service.
62
+ */
34
63
  export interface QueryService<TData, TError> {
64
+ // Returns the current state snapshot of the query.
35
65
  getSnapshot: () => QueryServiceSnapshot<TData, TError>;
66
+ // Subscribes a listener to state changes; returns an unsubscribe function.
36
67
  subscribe: (listener: (snapshot: QueryServiceSnapshot<TData, TError>) => void) => () => void;
68
+ // Manually triggers a refetch of this query.
37
69
  refetch: (options?: RefetchOptions) => Promise<QueryServiceSnapshot<TData, TError>>;
70
+ // Marks this specific query as invalid in the cache to trigger a refetch if active.
38
71
  invalidate: (options?: QueryInvalidateOptions) => Promise<void>;
72
+ // Escape hatch: provides direct access to the underlying Tanstack Query observer result.
39
73
  unsafe_getResult: () => QueryObserverResult<TData, TError>;
40
74
  }
41
75
 
76
+ /**
77
+ * Combines options for invalidation behavior and filtering.
78
+ */
42
79
  export interface QueryInvalidateOptions
43
80
  extends Pick<InvalidateOptions, 'cancelRefetch' | 'throwOnError'>,
44
81
  Pick<InvalidateQueryFilters, 'refetchType'> {}
45
82
 
83
+ /**
84
+ * Function signature for the query factory.
85
+ */
46
86
  export interface CreateQuery {
47
87
  <
48
88
  TQueryFnData = unknown,
@@ -51,12 +91,18 @@ export interface CreateQuery {
51
91
  TQueryData = TQueryFnData,
52
92
  TQueryKey extends QueryKey = QueryKey,
53
93
  >(
94
+ // The key that uniquely identifies the query in the cache.
54
95
  queryKey: TQueryKey,
96
+ // The asynchronous function that performs the data fetch.
55
97
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
98
+ // Optional configuration for behavior like staleness, retry, and refetching.
56
99
  options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
57
100
  ): QueryService<TData, TError>;
58
101
  }
59
102
 
103
+ /**
104
+ * Configuration options for creating a query service, excluding function and key.
105
+ */
60
106
  export type QueryServiceOptions<
61
107
  TQueryFnData = unknown,
62
108
  TError = Error,
@@ -68,20 +114,32 @@ export type QueryServiceOptions<
68
114
  'queryFn' | 'queryKey'
69
115
  >;
70
116
 
117
+ /**
118
+ * Extracts and maps status and fetchStatus to our QueryMetaState interface.
119
+ */
71
120
  export function toQueryMetaState<TData, TError>(
72
121
  snapshot: Pick<QueryServiceSnapshot<TData, TError>, 'fetchStatus' | 'status'>
73
122
  ): QueryMetaState {
123
+ // Return a simplified state object for UI or other services.
74
124
  return {
75
125
  fetchStatus: snapshot.fetchStatus,
76
126
  status: snapshot.status,
77
127
  };
78
128
  }
79
129
 
130
+ /**
131
+ * Helper function to check if the query is in its initial loading state.
132
+ */
80
133
  export function isQueryLoading(query: QueryMetaState): boolean {
134
+ // Returns true if the query is both pending and actively fetching.
81
135
  return query.status === 'pending' && query.fetchStatus === 'fetching';
82
136
  }
83
137
 
138
+ /**
139
+ * Prepares the query factory by binding it to a specific QueryClient instance.
140
+ */
84
141
  export function setupQuery(queryClient: QueryClient): CreateQuery {
142
+ // Returns the actual factory function for creating individual query services.
85
143
  return function createQuery<
86
144
  TQueryFnData = unknown,
87
145
  TError = Error,
@@ -93,6 +151,7 @@ export function setupQuery(queryClient: QueryClient): CreateQuery {
93
151
  queryFn: QueryFunction<TQueryFnData, TQueryKey>,
94
152
  options?: QueryServiceOptions<TQueryFnData, TError, TData, TQueryData, TQueryKey>
95
153
  ): QueryService<TData, TError> {
154
+ // Create a new QueryObserver instance to manage this specific query's lifecycle.
96
155
  const observer = new QueryObserver<TQueryFnData, TError, TData, TQueryData, TQueryKey>(
97
156
  queryClient,
98
157
  {
@@ -102,13 +161,18 @@ export function setupQuery(queryClient: QueryClient): CreateQuery {
102
161
  }
103
162
  );
104
163
 
164
+ // Return the implementation of the QueryService interface.
105
165
  return {
166
+ // Map the current observer state to our service's snapshot format.
106
167
  getSnapshot: () => toQueryServiceSnapshot(observer.getCurrentResult()),
168
+ // Subscribe to observer changes and notify the listener with updated snapshots.
107
169
  subscribe: (listener) =>
108
170
  observer.subscribe((result) => {
109
171
  listener(toQueryServiceSnapshot(result));
110
172
  }),
173
+ // Proxy the refetch call and map the async result back to a snapshot.
111
174
  refetch: async (options) => toQueryServiceSnapshot(await observer.refetch(options)),
175
+ // Trigger a targeted invalidation using the query's key and custom options.
112
176
  invalidate: (options) =>
113
177
  queryClient.invalidateQueries(
114
178
  {
@@ -118,14 +182,19 @@ export function setupQuery(queryClient: QueryClient): CreateQuery {
118
182
  },
119
183
  toInvalidateOptions(options)
120
184
  ),
185
+ // Provide direct access to the raw observer result when needed.
121
186
  unsafe_getResult: () => observer.getCurrentResult(),
122
187
  };
123
188
  };
124
189
  }
125
190
 
191
+ /**
192
+ * Internal helper to transform a raw Tanstack query result into our public snapshot format.
193
+ */
126
194
  function toQueryServiceSnapshot<TData, TError>(
127
195
  result: QueryObserverResult<TData, TError>
128
196
  ): QueryServiceSnapshot<TData, TError> {
197
+ // Extract and return the relevant fields for the UI or other services.
129
198
  return {
130
199
  data: result.data,
131
200
  error: result.error,
@@ -138,15 +207,21 @@ function toQueryServiceSnapshot<TData, TError>(
138
207
  };
139
208
  }
140
209
 
210
+ /**
211
+ * Internal helper to safely transform our QueryInvalidateOptions to Tanstack InvalidateOptions.
212
+ */
141
213
  function toInvalidateOptions(options?: QueryInvalidateOptions): InvalidateOptions | undefined {
214
+ // Return undefined if no options were provided.
142
215
  if (options === undefined) {
143
216
  return undefined;
144
217
  }
145
218
 
219
+ // Construct and filter the options object to avoid passing undefined values.
146
220
  const invalidateOptions: InvalidateOptions = {
147
221
  ...(options.cancelRefetch === undefined ? {} : { cancelRefetch: options.cancelRefetch }),
148
222
  ...(options.throwOnError === undefined ? {} : { throwOnError: options.throwOnError }),
149
223
  };
150
224
 
225
+ // Return the resulting object if it contains any relevant properties.
151
226
  return Object.keys(invalidateOptions).length > 0 ? invalidateOptions : undefined;
152
227
  }