@codeleap/query 5.8.7 → 5.8.9

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/query",
3
- "version": "5.8.7",
3
+ "version": "5.8.9",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -9,15 +9,15 @@
9
9
  "directory": "packages/query"
10
10
  },
11
11
  "devDependencies": {
12
- "@codeleap/config": "5.8.7",
13
- "@codeleap/types": "5.8.7",
12
+ "@codeleap/config": "5.8.9",
13
+ "@codeleap/types": "5.8.9",
14
14
  "ts-node-dev": "1.1.8"
15
15
  },
16
16
  "scripts": {
17
17
  "build": "echo 'No build needed'"
18
18
  },
19
19
  "peerDependencies": {
20
- "@codeleap/types": "5.8.7",
20
+ "@codeleap/types": "5.8.9",
21
21
  "typescript": "5.5.2",
22
22
  "@tanstack/react-query": "5.89.0"
23
23
  },
package/package.json.bak CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codeleap/query",
3
- "version": "5.8.7",
3
+ "version": "5.8.9",
4
4
  "main": "src/index.ts",
5
5
  "license": "UNLICENSED",
6
6
  "repository": {
@@ -2,6 +2,7 @@ import { InfiniteData } from '@tanstack/query-core'
2
2
  import { QueryKeys } from './QueryKeys'
3
3
  import { ItemPosition, ListPaginationResponse, PageParam, QueryClient, QueryItem, RemovedItemMap, WithTempId } from '../types'
4
4
  import deepEqual from 'fast-deep-equal'
5
+ import { TypeGuards } from '@codeleap/types'
5
6
 
6
7
  /**
7
8
  * Class for managing mutations and cache updates for React Query list data
@@ -129,10 +130,10 @@ export class Mutations<T extends QueryItem, F> {
129
130
  * }
130
131
  * ```
131
132
  */
132
- removeItem(itemId: QueryItem['id']): RemovedItemMap | null {
133
+ removeItem(itemId: QueryItem['id'], listFilters?: F): RemovedItemMap | null {
133
134
  this.queryKeys.removeRetrieveQueryData(itemId)
134
135
 
135
- const listQueries = this.queryKeys.getAllListQueries()
136
+ const listQueries = TypeGuards.isNil(listFilters) ? this.queryKeys.getAllListQueries() : [this.queryKeys.getListQuery(listFilters)]
136
137
 
137
138
  const removedItemMap: RemovedItemMap = []
138
139
 
@@ -1,7 +1,7 @@
1
1
  import { CancelOptions, InfiniteData, InvalidateOptions, InvalidateQueryFilters, Query, QueryFilters, QueryKey, RefetchOptions, RefetchQueryFilters } from '@tanstack/react-query'
2
2
  import { useMemo } from 'react'
3
3
  import { TypeGuards } from '@codeleap/types'
4
- import { ListPaginationResponse, ListSelector, PageParam, QueryClient, QueryItem } from '../types'
4
+ import { ListPaginationResponse, ListSelector, PageParam, QueryClient, QueryItem, RetrieveDataOptions } from '../types'
5
5
  import deepEqual from 'fast-deep-equal'
6
6
 
7
7
  /**
@@ -272,25 +272,57 @@ export class QueryKeys<T extends QueryItem, F> {
272
272
  }
273
273
 
274
274
  /**
275
- * Gets retrieve data from cache, with fallback to list data
276
- * @param id - The ID of the item to retrieve
277
- * @param onlyQueryData - If true, only returns data from the specific retrieve query, not from list data
278
- * @returns The item data or undefined if not found
275
+ * Retrieves item data from cache with intelligent fallback strategies
276
+ *
277
+ * @description Searches for an item using a multi-layered approach:
278
+ * 1. Direct cache lookup using retrieve query
279
+ * 2. Fallback to itemMap from list data (shallow search)
280
+ * 3. Deep search through all paginated list queries
281
+ *
282
+ * @param {QueryItem['id']} id - The unique identifier of the item to retrieve
283
+ * @param {RetrieveDataOptions} [options] - Configuration options for retrieval behavior
284
+ * @param {boolean} [options.onlyQueryData=false] - If true, only returns data from the specific retrieve query cache, ignoring list data fallbacks
285
+ * @param {boolean} [options.deepSearch=true] - If true, performs deep search through paginated queries when item not found in direct cache or itemMap
286
+ *
287
+ * @returns Item | undefined
279
288
  */
280
- getRetrieveData(id: QueryItem['id'], onlyQueryData = false): T | undefined {
289
+ getRetrieveData(id: QueryItem['id'], options: RetrieveDataOptions = {}): T | undefined {
290
+ const {
291
+ onlyQueryData = false,
292
+ deepSearch = false,
293
+ } = options
294
+
281
295
  if (TypeGuards.isNil(id)) return undefined
282
296
 
283
297
  const queryKey = this.keys.retrieve(id)
284
298
 
285
299
  const queryData = this.queryClient.getQueryData<T>(queryKey)
286
300
 
287
- if (!queryData?.id && !onlyQueryData) {
301
+ if (queryData?.id) return queryData
302
+
303
+ if (onlyQueryData) return undefined
304
+
305
+ if (!deepSearch) {
288
306
  const { itemMap } = this.getListData()
289
307
 
290
308
  return itemMap?.[id]
291
309
  }
292
310
 
293
- return queryData
311
+ const queries = this.getAllListQueries()
312
+
313
+ for (const query of queries) {
314
+ const pages = query.state.data?.pages
315
+ if (!pages?.length) continue
316
+
317
+ const item = pages
318
+ .filter(Boolean)
319
+ .flatMap(page => Array.isArray(page) ? page : [])
320
+ .find(item => item?.id === id)
321
+
322
+ if (item) return item
323
+ }
324
+
325
+ return undefined
294
326
  }
295
327
 
296
328
  /**
@@ -304,6 +336,14 @@ export class QueryKeys<T extends QueryItem, F> {
304
336
 
305
337
  return queries as Query<ListPaginationResponse<T>, Error, Omit<ListSelector<T>, 'allItems'>, QueryKey>[]
306
338
  }
339
+
340
+ getListQuery(listFilters?: F) {
341
+ const query = this.queryClient.getQueryCache().find({
342
+ queryKey: this.listKeyWithFilters(listFilters)
343
+ })
344
+
345
+ return query as Query<ListPaginationResponse<T>, Error, Omit<ListSelector<T>, 'allItems'>, QueryKey>
346
+ }
307
347
  }
308
348
 
309
349
  /**
@@ -1,4 +1,4 @@
1
- import { FetchQueryOptions, InfiniteData, MutationFunctionContext, QueryKey, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'
1
+ import { FetchInfiniteQueryOptions, FetchQueryOptions, InfiniteData, MutationFunctionContext, QueryKey, useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'
2
2
  import { useCallback } from 'react'
3
3
  import { createQueryKeys, QueryKeys } from './QueryKeys'
4
4
  import { createMutations, Mutations } from './Mutations'
@@ -485,4 +485,39 @@ export class QueryManager<T extends QueryItem, F> {
485
485
  queryFn: () => this.options.retrieveFn(id),
486
486
  })
487
487
  }
488
+
489
+ /**
490
+ * Prefetches a paginated list with filters for improved performance
491
+ * @param filters - Filter parameters to apply to the list query
492
+ * @param options - Prefetch options compatible with React Query's infinite queries
493
+ * @param options.initialOffset - Starting offset for pagination (default: 0)
494
+ * @returns Promise that resolves when prefetch is complete
495
+ *
496
+ * @description
497
+ * Use this method to preload paginated list data that users are likely to need soon.
498
+ *
499
+ * @example
500
+ * ```typescript
501
+ * const handle = () => {
502
+ * queryManager.prefetchList(
503
+ * { category: 'electronics' },
504
+ * { staleTime: 5 * 60 * 1000 }
505
+ * )
506
+ * }
507
+ *
508
+ * ```
509
+ */
510
+ prefetchList(
511
+ filters?: F,
512
+ options: Omit<FetchInfiniteQueryOptions<ListPaginationResponse<T>, Error, ListPaginationResponse<T>, QueryKey, number>, 'queryKey' | 'queryFn' | 'initialPageParam'> & { initialOffset?: number } = {}
513
+ ) {
514
+ const { initialOffset = 0, ...prefetchOptions } = options
515
+
516
+ return this.options.queryClient.prefetchInfiniteQuery({
517
+ ...prefetchOptions as any,
518
+ initialPageParam: initialOffset,
519
+ queryKey: this.queryKeys.listKeyWithFilters(filters),
520
+ queryFn: () => this.options.listFn(this.options.listLimit ?? 10, initialOffset, filters),
521
+ })
522
+ }
488
523
  }
@@ -5,3 +5,8 @@ export type RetrieveQueryOptions<T extends QueryItem> = Omit<
5
5
  UndefinedInitialDataOptions<T, Error, T, QueryKey>,
6
6
  'queryKey' | 'queryFn'
7
7
  >
8
+
9
+ export type RetrieveDataOptions = {
10
+ onlyQueryData?: boolean
11
+ deepSearch?: boolean
12
+ }