@ttt-productions/query-core 0.14.22 → 0.14.23

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 (125) hide show
  1. package/README.md +6 -6
  2. package/dist/defaults.d.ts +0 -15
  3. package/dist/defaults.d.ts.map +1 -1
  4. package/dist/defaults.js +0 -15
  5. package/dist/defaults.js.map +1 -1
  6. package/dist/firestore/types.d.ts +1 -49
  7. package/dist/firestore/types.d.ts.map +1 -1
  8. package/dist/firestore/types.js.map +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +0 -1
  11. package/dist/index.js.map +1 -1
  12. package/dist/keys.d.ts +0 -22
  13. package/dist/keys.d.ts.map +1 -1
  14. package/dist/keys.js +0 -4
  15. package/dist/keys.js.map +1 -1
  16. package/dist/react/cache-helpers.d.ts +0 -32
  17. package/dist/react/cache-helpers.d.ts.map +1 -1
  18. package/dist/react/cache-helpers.js +0 -28
  19. package/dist/react/cache-helpers.js.map +1 -1
  20. package/dist/react/defaults.d.ts +0 -4
  21. package/dist/react/defaults.d.ts.map +1 -1
  22. package/dist/react/defaults.js +2 -6
  23. package/dist/react/defaults.js.map +1 -1
  24. package/dist/react/domain-events/cache-invalidation.d.ts +0 -37
  25. package/dist/react/domain-events/cache-invalidation.d.ts.map +1 -1
  26. package/dist/react/domain-events/cache-invalidation.js +4 -53
  27. package/dist/react/domain-events/cache-invalidation.js.map +1 -1
  28. package/dist/react/domain-events/create-domain-event-invalidator.d.ts +0 -18
  29. package/dist/react/domain-events/create-domain-event-invalidator.d.ts.map +1 -1
  30. package/dist/react/domain-events/create-domain-event-invalidator.js +0 -5
  31. package/dist/react/domain-events/create-domain-event-invalidator.js.map +1 -1
  32. package/dist/react/firestore/absence-scheduler.d.ts +0 -28
  33. package/dist/react/firestore/absence-scheduler.d.ts.map +1 -1
  34. package/dist/react/firestore/absence-scheduler.js +1 -39
  35. package/dist/react/firestore/absence-scheduler.js.map +1 -1
  36. package/dist/react/firestore/batch-doc-loader.d.ts +0 -30
  37. package/dist/react/firestore/batch-doc-loader.d.ts.map +1 -1
  38. package/dist/react/firestore/batch-doc-loader.js +0 -34
  39. package/dist/react/firestore/batch-doc-loader.js.map +1 -1
  40. package/dist/react/firestore/context.d.ts +0 -19
  41. package/dist/react/firestore/context.d.ts.map +1 -1
  42. package/dist/react/firestore/context.js +0 -19
  43. package/dist/react/firestore/context.js.map +1 -1
  44. package/dist/react/firestore/doc-subscription-registry.d.ts +0 -23
  45. package/dist/react/firestore/doc-subscription-registry.d.ts.map +1 -1
  46. package/dist/react/firestore/doc-subscription-registry.js +0 -25
  47. package/dist/react/firestore/doc-subscription-registry.js.map +1 -1
  48. package/dist/react/firestore/infinite-helpers.d.ts +0 -12
  49. package/dist/react/firestore/infinite-helpers.d.ts.map +1 -1
  50. package/dist/react/firestore/infinite-helpers.js +0 -12
  51. package/dist/react/firestore/infinite-helpers.js.map +1 -1
  52. package/dist/react/firestore/resubscribe.d.ts +0 -20
  53. package/dist/react/firestore/resubscribe.d.ts.map +1 -1
  54. package/dist/react/firestore/resubscribe.js +0 -20
  55. package/dist/react/firestore/resubscribe.js.map +1 -1
  56. package/dist/react/firestore/subscription-status.d.ts +0 -29
  57. package/dist/react/firestore/subscription-status.d.ts.map +1 -1
  58. package/dist/react/firestore/subscription-status.js +1 -34
  59. package/dist/react/firestore/subscription-status.js.map +1 -1
  60. package/dist/react/firestore/types.d.ts +0 -64
  61. package/dist/react/firestore/types.d.ts.map +1 -1
  62. package/dist/react/firestore/types.js +0 -3
  63. package/dist/react/firestore/types.js.map +1 -1
  64. package/dist/react/firestore/use-firestore-collection.d.ts +0 -20
  65. package/dist/react/firestore/use-firestore-collection.d.ts.map +1 -1
  66. package/dist/react/firestore/use-firestore-collection.js +1 -35
  67. package/dist/react/firestore/use-firestore-collection.js.map +1 -1
  68. package/dist/react/firestore/use-firestore-count.d.ts +0 -15
  69. package/dist/react/firestore/use-firestore-count.d.ts.map +1 -1
  70. package/dist/react/firestore/use-firestore-count.js +0 -15
  71. package/dist/react/firestore/use-firestore-count.js.map +1 -1
  72. package/dist/react/firestore/use-firestore-doc.d.ts +0 -23
  73. package/dist/react/firestore/use-firestore-doc.d.ts.map +1 -1
  74. package/dist/react/firestore/use-firestore-doc.js +3 -40
  75. package/dist/react/firestore/use-firestore-doc.js.map +1 -1
  76. package/dist/react/firestore/use-firestore-infinite.d.ts +0 -29
  77. package/dist/react/firestore/use-firestore-infinite.d.ts.map +1 -1
  78. package/dist/react/firestore/use-firestore-infinite.js +0 -32
  79. package/dist/react/firestore/use-firestore-infinite.js.map +1 -1
  80. package/dist/react/firestore/use-firestore-live-infinite.d.ts +0 -34
  81. package/dist/react/firestore/use-firestore-live-infinite.d.ts.map +1 -1
  82. package/dist/react/firestore/use-firestore-live-infinite.js +1 -35
  83. package/dist/react/firestore/use-firestore-live-infinite.js.map +1 -1
  84. package/dist/react/firestore/use-firestore-paginated.d.ts +0 -30
  85. package/dist/react/firestore/use-firestore-paginated.d.ts.map +1 -1
  86. package/dist/react/firestore/use-firestore-paginated.js +2 -33
  87. package/dist/react/firestore/use-firestore-paginated.js.map +1 -1
  88. package/dist/react/firestore/useBatchFirestoreDocs.d.ts +1 -123
  89. package/dist/react/firestore/useBatchFirestoreDocs.d.ts.map +1 -1
  90. package/dist/react/firestore/useBatchFirestoreDocs.js +5 -58
  91. package/dist/react/firestore/useBatchFirestoreDocs.js.map +1 -1
  92. package/dist/react/index.d.ts.map +1 -1
  93. package/dist/react/index.js +0 -13
  94. package/dist/react/index.js.map +1 -1
  95. package/dist/react/pending-mutations.d.ts +1 -21
  96. package/dist/react/pending-mutations.d.ts.map +1 -1
  97. package/dist/react/pending-mutations.js +1 -32
  98. package/dist/react/pending-mutations.js.map +1 -1
  99. package/dist/react/provider.d.ts +0 -5
  100. package/dist/react/provider.d.ts.map +1 -1
  101. package/dist/react/provider.js +0 -4
  102. package/dist/react/provider.js.map +1 -1
  103. package/dist/react/query-client.d.ts +0 -4
  104. package/dist/react/query-client.d.ts.map +1 -1
  105. package/dist/react/query-client.js +0 -4
  106. package/dist/react/query-client.js.map +1 -1
  107. package/dist/react/search/types.d.ts +0 -12
  108. package/dist/react/search/types.d.ts.map +1 -1
  109. package/dist/react/search/types.js.map +1 -1
  110. package/dist/react/search/use-firestore-search.d.ts +0 -29
  111. package/dist/react/search/use-firestore-search.d.ts.map +1 -1
  112. package/dist/react/search/use-firestore-search.js +3 -41
  113. package/dist/react/search/use-firestore-search.js.map +1 -1
  114. package/dist/react/use-read-retry-state.d.ts +1 -21
  115. package/dist/react/use-read-retry-state.d.ts.map +1 -1
  116. package/dist/react/use-read-retry-state.js +2 -21
  117. package/dist/react/use-read-retry-state.js.map +1 -1
  118. package/dist/search/rule.d.ts +0 -6
  119. package/dist/search/rule.d.ts.map +1 -1
  120. package/dist/search/rule.js +0 -6
  121. package/dist/search/rule.js.map +1 -1
  122. package/dist/search/types.d.ts +1 -13
  123. package/dist/search/types.d.ts.map +1 -1
  124. package/dist/search/types.js.map +1 -1
  125. package/package.json +2 -2
@@ -1,133 +1,69 @@
1
1
  import type { DocumentData, DocumentSnapshot, QueryDocumentSnapshot, QueryConstraint } from 'firebase/firestore';
2
2
  import type { WithId, FirestoreBaseOptions } from '../../firestore/types.js';
3
- /**
4
- * Extract document data with ID from a QueryDocumentSnapshot.
5
- */
6
3
  export declare function docWithId<T extends DocumentData>(snap: QueryDocumentSnapshot<T>): WithId<T>;
7
- /**
8
- * Options for single document queries.
9
- */
10
4
  export interface FirestoreDocOptions<T> extends FirestoreBaseOptions {
11
- /** Full document path (e.g., 'users/abc123') */
12
5
  docPath: string;
13
- /** Enable realtime updates via onSnapshot (default: false) */
14
6
  subscribe?: boolean;
15
- /** Transform function applied to document data. Receives data WITH id included. */
16
7
  select?: (data: DocumentData & {
17
8
  id: string;
18
9
  }) => T;
19
10
  }
20
- /**
21
- * Options for collection queries.
22
- */
23
11
  export interface FirestoreCollectionOptions<T> extends FirestoreBaseOptions {
24
- /** Collection path (e.g., 'users' or 'entities/abc/members') */
25
12
  collectionPath: string;
26
- /** Firestore query constraints (where, orderBy, etc.) */
27
13
  constraints?: QueryConstraint[];
28
- /** Enable realtime updates via onSnapshot (default: false) */
29
14
  subscribe?: boolean;
30
- /** Transform function applied to each document. Receives data WITH id included. */
31
15
  select?: (data: DocumentData & {
32
16
  id: string;
33
17
  }) => T;
34
18
  }
35
- /**
36
- * Options for infinite scroll queries.
37
- */
38
19
  export interface FirestoreInfiniteOptions<T> extends FirestoreBaseOptions {
39
- /** Collection path */
40
20
  collectionPath: string;
41
- /** Firestore query constraints (where, orderBy - required for pagination) */
42
21
  constraints?: QueryConstraint[];
43
- /** Number of items per page (default: 20) */
44
22
  pageSize?: number;
45
- /** Transform function applied to each document. Receives data WITH id included. */
46
23
  select?: (data: DocumentData & {
47
24
  id: string;
48
25
  }) => T;
49
26
  }
50
- /**
51
- * Options for paginated queries with page numbers.
52
- */
53
27
  export interface FirestorePaginatedOptions<T> extends FirestoreBaseOptions {
54
- /** Collection path */
55
28
  collectionPath: string;
56
- /** Firestore query constraints */
57
29
  constraints?: QueryConstraint[];
58
- /** Number of items per page (default: 10) */
59
30
  pageSize?: number;
60
- /** Initial page number (default: 1) */
61
31
  initialPage?: number;
62
- /** Re-read the displayed page every `refetchInterval` ms while it is mounted (omit for none). */
63
32
  refetchInterval?: number;
64
- /** Transform function applied to each document. Receives data WITH id included. */
65
33
  select?: (data: DocumentData & {
66
34
  id: string;
67
35
  }) => T;
68
36
  }
69
- /**
70
- * Options for count() aggregation queries.
71
- */
72
37
  export interface FirestoreCountOptions extends FirestoreBaseOptions {
73
- /** Collection path */
74
38
  collectionPath: string;
75
- /** Firestore query constraints (where, etc.) applied before counting */
76
39
  constraints?: QueryConstraint[];
77
- /** Polling interval in ms (omit for no polling) */
78
40
  refetchInterval?: number;
79
41
  }
80
- /**
81
- * Options for a live newest-window + cursor-bridged older-pages list
82
- * (e.g. chat messages, live comment threads, live activity feeds). The newest
83
- * page is a realtime onSnapshot window; older pages load on demand via getDocs,
84
- * seeded from the window's oldest document so there is no gap or re-read.
85
- */
86
42
  export interface FirestoreLiveInfiniteOptions<T = DocumentData & {
87
43
  id: string;
88
44
  }> {
89
- /** Collection path (slash-joined for nested paths, e.g. 'chats/t1/messages'). */
90
45
  collectionPath: string;
91
- /** React Query cache key. The older-pages query is keyed under `[...queryKey, 'older']`. */
92
46
  queryKey: readonly unknown[];
93
- /** Field both the live window and older pages order by (descending under the hood). */
94
47
  orderByField: string;
95
- /** Equality/filter constraints. Do NOT pass orderBy/limit/startAfter — the hook adds those. */
96
48
  constraints?: QueryConstraint[];
97
- /** Items per page / live-window size (default 20, capped at 100). */
98
49
  pageSize?: number;
99
- /** When false, no listener is opened and no pages are fetched. */
100
50
  enabled?: boolean;
101
- /** Map each raw doc (id included) to the item shape. Default: identity (WithId). */
102
51
  select?: (data: DocumentData & {
103
52
  id: string;
104
53
  }) => T;
105
- /** Output ordering of the merged list, by `orderByField` as Firestore orders it. Default 'asc' (oldest → newest). */
106
54
  sort?: 'asc' | 'desc';
107
55
  }
108
- /**
109
- * Result page for infinite queries.
110
- */
111
56
  export interface InfinitePage<T> {
112
57
  items: WithId<T>[];
113
58
  lastDoc: DocumentSnapshot | null;
114
59
  size: number;
115
60
  }
116
- /**
117
- * One page's cache entry for `useFirestorePaginated`, stored at `[...queryKey, 'page', n]`:
118
- * the page's rows, its last row (the next page's cursor; `null` for an empty page), and
119
- * whether a further page exists (read with a one-row look-ahead), and the id of the row it
120
- * was read after (`null` for page 1), checked against the previous page's cursor.
121
- */
122
61
  export interface PaginatedPage<T> {
123
62
  items: T[];
124
63
  cursor: DocumentSnapshot | null;
125
64
  hasMore: boolean;
126
65
  after: string | null;
127
66
  }
128
- /**
129
- * Mutation operation types for batch mutations.
130
- */
131
67
  export type MutationOperation = {
132
68
  type: 'set';
133
69
  docPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/types.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,3 @@
1
- /**
2
- * Extract document data with ID from a QueryDocumentSnapshot.
3
- */
4
1
  export function docWithId(snap) {
5
2
  return { id: snap.id, ...snap.data() };
6
3
  }
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/react/firestore/types.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,UAAU,SAAS,CAAyB,IAA8B;IAC9E,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AACzC,CAAC","sourcesContent":["import type {\n DocumentData,\n DocumentSnapshot,\n QueryDocumentSnapshot,\n QueryConstraint,\n} from 'firebase/firestore';\nimport type { WithId, FirestoreBaseOptions } from '../../firestore/types.js';\n\n/**\n * Extract document data with ID from a QueryDocumentSnapshot.\n */\nexport function docWithId<T extends DocumentData>(snap: QueryDocumentSnapshot<T>): WithId<T> {\n return { id: snap.id, ...snap.data() };\n}\n\n/**\n * Options for single document queries.\n */\nexport interface FirestoreDocOptions<T> extends FirestoreBaseOptions {\n /** Full document path (e.g., 'users/abc123') */\n docPath: string;\n /** Enable realtime updates via onSnapshot (default: false) */\n subscribe?: boolean;\n /** Transform function applied to document data. Receives data WITH id included. */\n select?: (data: DocumentData & { id: string }) => T;\n}\n\n/**\n * Options for collection queries.\n */\nexport interface FirestoreCollectionOptions<T> extends FirestoreBaseOptions {\n /** Collection path (e.g., 'users' or 'entities/abc/members') */\n collectionPath: string;\n /** Firestore query constraints (where, orderBy, etc.) */\n constraints?: QueryConstraint[];\n /** Enable realtime updates via onSnapshot (default: false) */\n subscribe?: boolean;\n /** Transform function applied to each document. Receives data WITH id included. */\n select?: (data: DocumentData & { id: string }) => T;\n}\n\n/**\n * Options for infinite scroll queries.\n */\nexport interface FirestoreInfiniteOptions<T> extends FirestoreBaseOptions {\n /** Collection path */\n collectionPath: string;\n /** Firestore query constraints (where, orderBy - required for pagination) */\n constraints?: QueryConstraint[];\n /** Number of items per page (default: 20) */\n pageSize?: number;\n /** Transform function applied to each document. Receives data WITH id included. */\n select?: (data: DocumentData & { id: string }) => T;\n}\n\n/**\n * Options for paginated queries with page numbers.\n */\nexport interface FirestorePaginatedOptions<T> extends FirestoreBaseOptions {\n /** Collection path */\n collectionPath: string;\n /** Firestore query constraints */\n constraints?: QueryConstraint[];\n /** Number of items per page (default: 10) */\n pageSize?: number;\n /** Initial page number (default: 1) */\n initialPage?: number;\n /** Re-read the displayed page every `refetchInterval` ms while it is mounted (omit for none). */\n refetchInterval?: number;\n /** Transform function applied to each document. Receives data WITH id included. */\n select?: (data: DocumentData & { id: string }) => T;\n}\n\n/**\n * Options for count() aggregation queries.\n */\nexport interface FirestoreCountOptions extends FirestoreBaseOptions {\n /** Collection path */\n collectionPath: string;\n /** Firestore query constraints (where, etc.) applied before counting */\n constraints?: QueryConstraint[];\n /** Polling interval in ms (omit for no polling) */\n refetchInterval?: number;\n}\n\n/**\n * Options for a live newest-window + cursor-bridged older-pages list\n * (e.g. chat messages, live comment threads, live activity feeds). The newest\n * page is a realtime onSnapshot window; older pages load on demand via getDocs,\n * seeded from the window's oldest document so there is no gap or re-read.\n */\nexport interface FirestoreLiveInfiniteOptions<T = DocumentData & { id: string }> {\n /** Collection path (slash-joined for nested paths, e.g. 'chats/t1/messages'). */\n collectionPath: string;\n /** React Query cache key. The older-pages query is keyed under `[...queryKey, 'older']`. */\n queryKey: readonly unknown[];\n /** Field both the live window and older pages order by (descending under the hood). */\n orderByField: string;\n /** Equality/filter constraints. Do NOT pass orderBy/limit/startAfter — the hook adds those. */\n constraints?: QueryConstraint[];\n /** Items per page / live-window size (default 20, capped at 100). */\n pageSize?: number;\n /** When false, no listener is opened and no pages are fetched. */\n enabled?: boolean;\n /** Map each raw doc (id included) to the item shape. Default: identity (WithId). */\n select?: (data: DocumentData & { id: string }) => T;\n /** Output ordering of the merged list, by `orderByField` as Firestore orders it. Default 'asc' (oldest → newest). */\n sort?: 'asc' | 'desc';\n}\n\n/**\n * Result page for infinite queries.\n */\nexport interface InfinitePage<T> {\n items: WithId<T>[];\n lastDoc: DocumentSnapshot | null;\n size: number;\n}\n\n/**\n * One page's cache entry for `useFirestorePaginated`, stored at `[...queryKey, 'page', n]`:\n * the page's rows, its last row (the next page's cursor; `null` for an empty page), and\n * whether a further page exists (read with a one-row look-ahead), and the id of the row it\n * was read after (`null` for page 1), checked against the previous page's cursor.\n */\nexport interface PaginatedPage<T> {\n items: T[];\n cursor: DocumentSnapshot | null;\n hasMore: boolean;\n after: string | null;\n}\n\n/**\n * Mutation operation types for batch mutations.\n */\nexport type MutationOperation =\n | { type: 'set'; docPath: string; data: DocumentData; merge?: boolean }\n | { type: 'update'; docPath: string; data: DocumentData }\n | { type: 'delete'; docPath: string };\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/react/firestore/types.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,SAAS,CAAyB,IAA8B;IAC9E,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;AACzC,CAAC","sourcesContent":["import type {\n DocumentData,\n DocumentSnapshot,\n QueryDocumentSnapshot,\n QueryConstraint,\n} from 'firebase/firestore';\nimport type { WithId, FirestoreBaseOptions } from '../../firestore/types.js';\n\nexport function docWithId<T extends DocumentData>(snap: QueryDocumentSnapshot<T>): WithId<T> {\n return { id: snap.id, ...snap.data() };\n}\n\nexport interface FirestoreDocOptions<T> extends FirestoreBaseOptions {\n docPath: string;\n subscribe?: boolean;\n select?: (data: DocumentData & { id: string }) => T;\n}\n\nexport interface FirestoreCollectionOptions<T> extends FirestoreBaseOptions {\n collectionPath: string;\n constraints?: QueryConstraint[];\n subscribe?: boolean;\n select?: (data: DocumentData & { id: string }) => T;\n}\n\nexport interface FirestoreInfiniteOptions<T> extends FirestoreBaseOptions {\n collectionPath: string;\n constraints?: QueryConstraint[];\n pageSize?: number;\n select?: (data: DocumentData & { id: string }) => T;\n}\n\nexport interface FirestorePaginatedOptions<T> extends FirestoreBaseOptions {\n collectionPath: string;\n constraints?: QueryConstraint[];\n pageSize?: number;\n initialPage?: number;\n refetchInterval?: number;\n select?: (data: DocumentData & { id: string }) => T;\n}\n\nexport interface FirestoreCountOptions extends FirestoreBaseOptions {\n collectionPath: string;\n constraints?: QueryConstraint[];\n refetchInterval?: number;\n}\n\nexport interface FirestoreLiveInfiniteOptions<T = DocumentData & { id: string }> {\n collectionPath: string;\n queryKey: readonly unknown[];\n orderByField: string;\n constraints?: QueryConstraint[];\n pageSize?: number;\n enabled?: boolean;\n select?: (data: DocumentData & { id: string }) => T;\n sort?: 'asc' | 'desc';\n}\n\nexport interface InfinitePage<T> {\n items: WithId<T>[];\n lastDoc: DocumentSnapshot | null;\n size: number;\n}\n\nexport interface PaginatedPage<T> {\n items: T[];\n cursor: DocumentSnapshot | null;\n hasMore: boolean;\n after: string | null;\n}\n\nexport type MutationOperation =\n | { type: 'set'; docPath: string; data: DocumentData; merge?: boolean }\n | { type: 'update'; docPath: string; data: DocumentData }\n | { type: 'delete'; docPath: string };\n"]}
@@ -2,25 +2,5 @@ import { type UseQueryResult } from '@tanstack/react-query';
2
2
  import { type DocumentData } from 'firebase/firestore';
3
3
  import type { WithId, WithSourceState } from '../../firestore/types.js';
4
4
  import type { FirestoreCollectionOptions } from './types.js';
5
- /**
6
- * Fetch all documents from a Firestore collection with optional realtime updates.
7
- * Use this for small collections where you need all documents at once.
8
- * For large collections, use useFirestoreInfinite or useFirestorePaginated.
9
- * * @example
10
- * ```tsx
11
- * // Fetch all channels in an entity
12
- * const { data: channels } = useFirestoreCollection<Channel>({
13
- * collectionPath: `entities/${entityId}/channels`,
14
- * queryKey: ['channels', entityId],
15
- * constraints: [orderBy('createdAt', 'asc')],
16
- * });
17
- * * // With realtime updates
18
- * const { data: members } = useFirestoreCollection<Member>({
19
- * collectionPath: `entities/${entityId}/members`,
20
- * queryKey: ['members', entityId],
21
- * subscribe: true,
22
- * });
23
- * ```
24
- */
25
5
  export declare function useFirestoreCollection<T extends DocumentData = DocumentData>({ collectionPath, queryKey, constraints, enabled, subscribe, staleTime, gcTime, select, }: FirestoreCollectionOptions<T>): WithSourceState<UseQueryResult<WithId<T>[], Error>>;
26
6
  //# sourceMappingURL=use-firestore-collection.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-collection.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-collection.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAA0C,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI/F,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC5E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAyHrF"}
1
+ {"version":3,"file":"use-firestore-collection.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-collection.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAA0C,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAI/F,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAC;AAE7D,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC5E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CA2GrF"}
@@ -5,45 +5,17 @@ import { collection, query, getDocs, onSnapshot } from 'firebase/firestore';
5
5
  import { useFirestoreDb } from './context.js';
6
6
  import { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';
7
7
  import { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';
8
- /**
9
- * Fetch all documents from a Firestore collection with optional realtime updates.
10
- * Use this for small collections where you need all documents at once.
11
- * For large collections, use useFirestoreInfinite or useFirestorePaginated.
12
- * * @example
13
- * ```tsx
14
- * // Fetch all channels in an entity
15
- * const { data: channels } = useFirestoreCollection<Channel>({
16
- * collectionPath: `entities/${entityId}/channels`,
17
- * queryKey: ['channels', entityId],
18
- * constraints: [orderBy('createdAt', 'asc')],
19
- * });
20
- * * // With realtime updates
21
- * const { data: members } = useFirestoreCollection<Member>({
22
- * collectionPath: `entities/${entityId}/members`,
23
- * queryKey: ['members', entityId],
24
- * subscribe: true,
25
- * });
26
- * ```
27
- */
28
8
  export function useFirestoreCollection({ collectionPath, queryKey, constraints = [], enabled = true, subscribe = false, staleTime, gcTime, select, }) {
29
9
  const db = useFirestoreDb();
30
10
  const queryClient = useQueryClient();
31
- // STABILIZE DEPENDENCIES:
32
- // We stringify these because [where('a', '==', 'b')] !== [where('a', '==', 'b')] in JS.
33
11
  const constraintsMemo = JSON.stringify(constraints);
34
12
  const queryKeyMemo = JSON.stringify(queryKey);
35
- // Listener errors can't surface through useQuery (the queryFn is disabled while
36
- // subscribed), so they're tracked per subscription identity and merged into the result.
37
13
  const subscription = useSubscriptionStatus(JSON.stringify([collectionPath, queryKeyMemo, constraintsMemo, enabled, subscribe]));
38
14
  const { reset: resetStatus, update: updateStatus, restarts } = subscription;
39
15
  useEffect(() => {
40
16
  if (!subscribe || !enabled)
41
17
  return;
42
18
  resetStatus();
43
- // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session
44
- // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the
45
- // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are
46
- // cleaned up on unmount so a pending retry never fires after teardown.
47
19
  let currentUnsubscribe = null;
48
20
  let retryTimer = null;
49
21
  let attempt = 0;
@@ -72,9 +44,6 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
72
44
  : 'live',
73
45
  }));
74
46
  }, (error) => {
75
- // Heal a transient permission-denied by resubscribing on the backoff ladder,
76
- // keeping the last-known data visible. Only surface the error once the ladder
77
- // is exhausted; any other error surfaces immediately, as before.
78
47
  if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {
79
48
  currentUnsubscribe?.();
80
49
  currentUnsubscribe = null;
@@ -96,9 +65,7 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
96
65
  clearTimeout(retryTimer);
97
66
  currentUnsubscribe?.();
98
67
  };
99
- // queryKey & constraints are tracked via their stringified forms above; select is intentionally
100
- // excluded so an inline caller function doesn't force a re-subscribe on every render.
101
- // eslint-disable-next-line react-hooks/exhaustive-deps
68
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- queryKey and constraints are tracked by their serialized forms; an inline select must not re-subscribe every render
102
69
  }, [
103
70
  db,
104
71
  collectionPath,
@@ -119,7 +86,6 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
119
86
  const snapshot = await getDocs(q);
120
87
  return snapshot.docs.map((docSnap) => {
121
88
  const rawData = docSnap.data();
122
- // Include id in data passed to select, so it can be renamed/transformed
123
89
  const dataWithId = { id: docSnap.id, ...rawData };
124
90
  const data = select ? select(dataWithId) : dataWithId;
125
91
  return data;
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-collection.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-collection.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';\nimport { collection, query, getDocs, onSnapshot, type DocumentData } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';\nimport type { WithId, WithSourceState } from '../../firestore/types.js';\nimport type { FirestoreCollectionOptions } from './types.js';\n\n/**\n * Fetch all documents from a Firestore collection with optional realtime updates.\n * Use this for small collections where you need all documents at once.\n * For large collections, use useFirestoreInfinite or useFirestorePaginated.\n * * @example\n * ```tsx\n * // Fetch all channels in an entity\n * const { data: channels } = useFirestoreCollection<Channel>({\n * collectionPath: `entities/${entityId}/channels`,\n * queryKey: ['channels', entityId],\n * constraints: [orderBy('createdAt', 'asc')],\n * });\n * * // With realtime updates\n * const { data: members } = useFirestoreCollection<Member>({\n * collectionPath: `entities/${entityId}/members`,\n * queryKey: ['members', entityId],\n * subscribe: true,\n * });\n * ```\n */\nexport function useFirestoreCollection<T extends DocumentData = DocumentData>({\n collectionPath,\n queryKey,\n constraints = [],\n enabled = true,\n subscribe = false,\n staleTime,\n gcTime,\n select,\n}: FirestoreCollectionOptions<T>): WithSourceState<UseQueryResult<WithId<T>[], Error>> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n\n // STABILIZE DEPENDENCIES:\n // We stringify these because [where('a', '==', 'b')] !== [where('a', '==', 'b')] in JS.\n const constraintsMemo = JSON.stringify(constraints);\n const queryKeyMemo = JSON.stringify(queryKey);\n\n // Listener errors can't surface through useQuery (the queryFn is disabled while\n // subscribed), so they're tracked per subscription identity and merged into the result.\n const subscription = useSubscriptionStatus(\n JSON.stringify([collectionPath, queryKeyMemo, constraintsMemo, enabled, subscribe]),\n );\n const { reset: resetStatus, update: updateStatus, restarts } = subscription;\n\n useEffect(() => {\n if (!subscribe || !enabled) return;\n\n resetStatus();\n\n // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session\n // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the\n // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are\n // cleaned up on unmount so a pending retry never fires after teardown.\n let currentUnsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let disposed = false;\n\n const start = () => {\n if (disposed) return;\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n\n currentUnsubscribe = onSnapshot(\n q,\n { includeMetadataChanges: true },\n (snapshot) => {\n attempt = 0;\n updateStatus({ error: null, restart: null });\n const items = snapshot.docs.map((docSnap) => {\n const rawData = docSnap.data();\n const dataWithId = { id: docSnap.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n });\n queryClient.setQueryData(queryKey, items);\n const fromCache = snapshot.metadata?.fromCache ?? false;\n updateStatus((prev) => ({\n sourceState: fromCache\n ? prev.sourceState === 'connecting'\n ? 'connecting'\n : 'offline'\n : 'live',\n }));\n },\n (error) => {\n // Heal a transient permission-denied by resubscribing on the backoff ladder,\n // keeping the last-known data visible. Only surface the error once the ladder\n // is exhausted; any other error surfaces immediately, as before.\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n currentUnsubscribe?.();\n currentUnsubscribe = null;\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n updateStatus({ sourceState: 'connecting' });\n retryTimer = setTimeout(start, delay);\n return;\n }\n console.error('[useFirestoreCollection] Subscription error:', error);\n updateStatus({ error, sourceState: 'error', restart: null });\n queryClient.setQueryData(queryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n // queryKey & constraints are tracked via their stringified forms above; select is intentionally\n // excluded so an inline caller function doesn't force a re-subscribe on every render.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n db,\n collectionPath,\n queryKeyMemo,\n constraintsMemo,\n enabled,\n subscribe,\n restarts,\n queryClient,\n resetStatus,\n updateStatus,\n ]);\n\n const queryResult = useQuery({\n queryKey,\n queryFn: async (): Promise<WithId<T>[]> => {\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((docSnap) => {\n const rawData = docSnap.data();\n // Include id in data passed to select, so it can be renamed/transformed\n const dataWithId = { id: docSnap.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n });\n },\n enabled: enabled && !subscribe,\n staleTime: subscribe ? Infinity : staleTime,\n gcTime,\n });\n\n return useSubscribedResult(queryResult, subscribe, enabled, subscription);\n}\n"]}
1
+ {"version":3,"file":"use-firestore-collection.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-collection.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';\nimport { collection, query, getDocs, onSnapshot, type DocumentData } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';\nimport type { WithId, WithSourceState } from '../../firestore/types.js';\nimport type { FirestoreCollectionOptions } from './types.js';\n\nexport function useFirestoreCollection<T extends DocumentData = DocumentData>({\n collectionPath,\n queryKey,\n constraints = [],\n enabled = true,\n subscribe = false,\n staleTime,\n gcTime,\n select,\n}: FirestoreCollectionOptions<T>): WithSourceState<UseQueryResult<WithId<T>[], Error>> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n\n const constraintsMemo = JSON.stringify(constraints);\n const queryKeyMemo = JSON.stringify(queryKey);\n\n const subscription = useSubscriptionStatus(\n JSON.stringify([collectionPath, queryKeyMemo, constraintsMemo, enabled, subscribe]),\n );\n const { reset: resetStatus, update: updateStatus, restarts } = subscription;\n\n useEffect(() => {\n if (!subscribe || !enabled) return;\n\n resetStatus();\n\n let currentUnsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let disposed = false;\n\n const start = () => {\n if (disposed) return;\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n\n currentUnsubscribe = onSnapshot(\n q,\n { includeMetadataChanges: true },\n (snapshot) => {\n attempt = 0;\n updateStatus({ error: null, restart: null });\n const items = snapshot.docs.map((docSnap) => {\n const rawData = docSnap.data();\n const dataWithId = { id: docSnap.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n });\n queryClient.setQueryData(queryKey, items);\n const fromCache = snapshot.metadata?.fromCache ?? false;\n updateStatus((prev) => ({\n sourceState: fromCache\n ? prev.sourceState === 'connecting'\n ? 'connecting'\n : 'offline'\n : 'live',\n }));\n },\n (error) => {\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n currentUnsubscribe?.();\n currentUnsubscribe = null;\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n updateStatus({ sourceState: 'connecting' });\n retryTimer = setTimeout(start, delay);\n return;\n }\n console.error('[useFirestoreCollection] Subscription error:', error);\n updateStatus({ error, sourceState: 'error', restart: null });\n queryClient.setQueryData(queryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- queryKey and constraints are tracked by their serialized forms; an inline select must not re-subscribe every render\n }, [\n db,\n collectionPath,\n queryKeyMemo,\n constraintsMemo,\n enabled,\n subscribe,\n restarts,\n queryClient,\n resetStatus,\n updateStatus,\n ]);\n\n const queryResult = useQuery({\n queryKey,\n queryFn: async (): Promise<WithId<T>[]> => {\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n\n const snapshot = await getDocs(q);\n return snapshot.docs.map((docSnap) => {\n const rawData = docSnap.data();\n const dataWithId = { id: docSnap.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n });\n },\n enabled: enabled && !subscribe,\n staleTime: subscribe ? Infinity : staleTime,\n gcTime,\n });\n\n return useSubscribedResult(queryResult, subscribe, enabled, subscription);\n}\n"]}
@@ -1,19 +1,4 @@
1
1
  import { type UseQueryResult } from '@tanstack/react-query';
2
2
  import type { FirestoreCountOptions } from './types.js';
3
- /**
4
- * Count documents in a Firestore collection via a server-side `count()`
5
- * aggregation (cheap — it does not read the matching documents). Optional
6
- * polling via `refetchInterval`.
7
- *
8
- * @example
9
- * ```tsx
10
- * const { data: count } = useFirestoreCount({
11
- * collectionPath: 'activeUserNotifications',
12
- * queryKey: ['notifications', 'unread-count', userId],
13
- * constraints: [where('targetUserId', '==', userId), where('seenAt', '==', 0)],
14
- * refetchInterval: 30_000,
15
- * });
16
- * ```
17
- */
18
3
  export declare function useFirestoreCount({ collectionPath, queryKey, constraints, enabled, staleTime, gcTime, refetchInterval, }: FirestoreCountOptions): UseQueryResult<number, Error>;
19
4
  //# sourceMappingURL=use-firestore-count.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-count.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-count.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAS,EACT,MAAM,EACN,eAAe,GAChB,EAAE,qBAAqB,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAgBvD"}
1
+ {"version":3,"file":"use-firestore-count.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-count.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAGtE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAExD,wBAAgB,iBAAiB,CAAC,EAChC,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAS,EACT,MAAM,EACN,eAAe,GAChB,EAAE,qBAAqB,GAAG,cAAc,CAAC,MAAM,EAAE,KAAK,CAAC,CAgBvD"}
@@ -2,21 +2,6 @@
2
2
  import { useQuery } from '@tanstack/react-query';
3
3
  import { collection, query, getCountFromServer } from 'firebase/firestore';
4
4
  import { useFirestoreDb } from './context.js';
5
- /**
6
- * Count documents in a Firestore collection via a server-side `count()`
7
- * aggregation (cheap — it does not read the matching documents). Optional
8
- * polling via `refetchInterval`.
9
- *
10
- * @example
11
- * ```tsx
12
- * const { data: count } = useFirestoreCount({
13
- * collectionPath: 'activeUserNotifications',
14
- * queryKey: ['notifications', 'unread-count', userId],
15
- * constraints: [where('targetUserId', '==', userId), where('seenAt', '==', 0)],
16
- * refetchInterval: 30_000,
17
- * });
18
- * ```
19
- */
20
5
  export function useFirestoreCount({ collectionPath, queryKey, constraints = [], enabled = true, staleTime, gcTime, refetchInterval, }) {
21
6
  const db = useFirestoreDb();
22
7
  return useQuery({
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-count.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-count.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAuB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAChC,cAAc,EACd,QAAQ,EACR,WAAW,GAAG,EAAE,EAChB,OAAO,GAAG,IAAI,EACd,SAAS,EACT,MAAM,EACN,eAAe,GACO;IACtB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5B,OAAO,QAAQ,CAAC;QACd,QAAQ;QACR,OAAO,EAAE,KAAK,IAAqB,EAAE;YACnC,MAAM,aAAa,GAAG,UAAU,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACrD,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;YACxF,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAC7C,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QAC/B,CAAC;QACD,OAAO;QACP,SAAS;QACT,MAAM;QACN,eAAe;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["'use client';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport { collection, query, getCountFromServer } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport type { FirestoreCountOptions } from './types.js';\n\n/**\n * Count documents in a Firestore collection via a server-side `count()`\n * aggregation (cheap — it does not read the matching documents). Optional\n * polling via `refetchInterval`.\n *\n * @example\n * ```tsx\n * const { data: count } = useFirestoreCount({\n * collectionPath: 'activeUserNotifications',\n * queryKey: ['notifications', 'unread-count', userId],\n * constraints: [where('targetUserId', '==', userId), where('seenAt', '==', 0)],\n * refetchInterval: 30_000,\n * });\n * ```\n */\nexport function useFirestoreCount({\n collectionPath,\n queryKey,\n constraints = [],\n enabled = true,\n staleTime,\n gcTime,\n refetchInterval,\n}: FirestoreCountOptions): UseQueryResult<number, Error> {\n const db = useFirestoreDb();\n\n return useQuery({\n queryKey,\n queryFn: async (): Promise<number> => {\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n const snapshot = await getCountFromServer(q);\n return snapshot.data().count;\n },\n enabled,\n staleTime,\n gcTime,\n refetchInterval,\n });\n}\n"]}
1
+ {"version":3,"file":"use-firestore-count.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-count.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAuB,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,UAAU,iBAAiB,CAAC,EAChC,cAAc,EACd,QAAQ,EACR,WAAW,GAAG,EAAE,EAChB,OAAO,GAAG,IAAI,EACd,SAAS,EACT,MAAM,EACN,eAAe,GACO;IACtB,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC;IAE5B,OAAO,QAAQ,CAAC;QACd,QAAQ;QACR,OAAO,EAAE,KAAK,IAAqB,EAAE;YACnC,MAAM,aAAa,GAAG,UAAU,CAAC,EAAE,EAAE,cAAc,CAAC,CAAC;YACrD,MAAM,CAAC,GAAG,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC;YACxF,MAAM,QAAQ,GAAG,MAAM,kBAAkB,CAAC,CAAC,CAAC,CAAC;YAC7C,OAAO,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;QAC/B,CAAC;QACD,OAAO;QACP,SAAS;QACT,MAAM;QACN,eAAe;KAChB,CAAC,CAAC;AACL,CAAC","sourcesContent":["'use client';\n\nimport { useQuery, type UseQueryResult } from '@tanstack/react-query';\nimport { collection, query, getCountFromServer } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport type { FirestoreCountOptions } from './types.js';\n\nexport function useFirestoreCount({\n collectionPath,\n queryKey,\n constraints = [],\n enabled = true,\n staleTime,\n gcTime,\n refetchInterval,\n}: FirestoreCountOptions): UseQueryResult<number, Error> {\n const db = useFirestoreDb();\n\n return useQuery({\n queryKey,\n queryFn: async (): Promise<number> => {\n const collectionRef = collection(db, collectionPath);\n const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;\n const snapshot = await getCountFromServer(q);\n return snapshot.data().count;\n },\n enabled,\n staleTime,\n gcTime,\n refetchInterval,\n });\n}\n"]}
@@ -2,28 +2,5 @@ import { type UseQueryResult } from '@tanstack/react-query';
2
2
  import { type DocumentData } from 'firebase/firestore';
3
3
  import type { WithId, WithSourceState } from '../../firestore/types.js';
4
4
  import type { FirestoreDocOptions } from './types.js';
5
- /**
6
- * Fetch a single Firestore document with optional realtime updates.
7
- * * @example
8
- * ```tsx
9
- * // Simple fetch
10
- * const { data: user } = useFirestoreDoc<User>({
11
- * docPath: `users/${userId}`,
12
- * queryKey: ['user', userId],
13
- * });
14
- * * // With realtime updates
15
- * const { data: entity } = useFirestoreDoc<Entity>({
16
- * docPath: `entities/${entityId}`,
17
- * queryKey: ['entity', entityId],
18
- * subscribe: true,
19
- * });
20
- * * // Conditional fetch
21
- * const { data: profile } = useFirestoreDoc<Profile>({
22
- * docPath: `profiles/${userId}`,
23
- * queryKey: ['profile', userId],
24
- * enabled: !!userId,
25
- * });
26
- * ```
27
- */
28
5
  export declare function useFirestoreDoc<T extends DocumentData = DocumentData>({ docPath, queryKey, enabled, subscribe, staleTime, gcTime, select, }: FirestoreDocOptions<T>): WithSourceState<UseQueryResult<WithId<T> | null, Error>>;
29
6
  //# sourceMappingURL=use-firestore-doc.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-doc.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-doc.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIhF,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACrE,OAAO,EACP,QAAQ,EACR,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAsHnF"}
1
+ {"version":3,"file":"use-firestore-doc.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-doc.ts"],"names":[],"mappings":"AAGA,OAAO,EAA4B,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAA2B,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAIhF,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACrE,OAAO,EACP,QAAQ,EACR,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAwGnF"}
@@ -5,46 +5,16 @@ import { doc, getDoc, onSnapshot } from 'firebase/firestore';
5
5
  import { useFirestoreDb } from './context.js';
6
6
  import { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';
7
7
  import { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';
8
- /**
9
- * Fetch a single Firestore document with optional realtime updates.
10
- * * @example
11
- * ```tsx
12
- * // Simple fetch
13
- * const { data: user } = useFirestoreDoc<User>({
14
- * docPath: `users/${userId}`,
15
- * queryKey: ['user', userId],
16
- * });
17
- * * // With realtime updates
18
- * const { data: entity } = useFirestoreDoc<Entity>({
19
- * docPath: `entities/${entityId}`,
20
- * queryKey: ['entity', entityId],
21
- * subscribe: true,
22
- * });
23
- * * // Conditional fetch
24
- * const { data: profile } = useFirestoreDoc<Profile>({
25
- * docPath: `profiles/${userId}`,
26
- * queryKey: ['profile', userId],
27
- * enabled: !!userId,
28
- * });
29
- * ```
30
- */
31
8
  export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe = false, staleTime, gcTime, select, }) {
32
9
  const db = useFirestoreDb();
33
10
  const queryClient = useQueryClient();
34
11
  const queryKeyMemo = JSON.stringify(queryKey);
35
- // Listener errors can't surface through useQuery (the queryFn is disabled while
36
- // subscribed), so they're tracked per subscription identity and merged into the result.
37
12
  const subscription = useSubscriptionStatus(JSON.stringify([docPath, queryKeyMemo, enabled, subscribe]));
38
13
  const { reset: resetStatus, update: updateStatus, restarts } = subscription;
39
- // Set up realtime subscription
40
14
  useEffect(() => {
41
15
  if (!subscribe || !enabled)
42
16
  return;
43
17
  resetStatus();
44
- // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session
45
- // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the
46
- // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are
47
- // cleaned up on unmount so a pending retry never fires after teardown.
48
18
  let currentUnsubscribe = null;
49
19
  let retryTimer = null;
50
20
  let attempt = 0;
@@ -58,7 +28,6 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
58
28
  updateStatus({ error: null, restart: null });
59
29
  if (snapshot.exists()) {
60
30
  const rawData = snapshot.data();
61
- // Include id in data passed to select, so it can be renamed/transformed
62
31
  const dataWithId = { id: snapshot.id, ...rawData };
63
32
  const data = select ? select(dataWithId) : dataWithId;
64
33
  queryClient.setQueryData(queryKey, data);
@@ -75,9 +44,6 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
75
44
  : 'live',
76
45
  }));
77
46
  }, (error) => {
78
- // Heal a transient permission-denied by resubscribing on the backoff ladder,
79
- // keeping the last-known data visible. Only surface the error once the ladder
80
- // is exhausted; any other error surfaces immediately, as before.
81
47
  if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {
82
48
  currentUnsubscribe?.();
83
49
  currentUnsubscribe = null;
@@ -99,9 +65,7 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
99
65
  clearTimeout(retryTimer);
100
66
  currentUnsubscribe?.();
101
67
  };
102
- // Note: select intentionally excluded to prevent re-subscribing on every render if the caller
103
- // passes an inline function. queryKey is tracked via queryKeyMemo above.
104
- // eslint-disable-next-line react-hooks/exhaustive-deps
68
+ // eslint-disable-next-line react-hooks/exhaustive-deps -- queryKey is tracked by queryKeyMemo; an inline select must not re-subscribe every render
105
69
  }, [
106
70
  db,
107
71
  docPath,
@@ -122,13 +86,12 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
122
86
  return null;
123
87
  }
124
88
  const rawData = snapshot.data();
125
- // Include id in data passed to select, so it can be renamed/transformed
126
89
  const dataWithId = { id: snapshot.id, ...rawData };
127
90
  const data = select ? select(dataWithId) : dataWithId;
128
91
  return data;
129
92
  },
130
- enabled: enabled && !subscribe, // Don't fetch if subscribing (snapshot handles it)
131
- staleTime: subscribe ? Infinity : staleTime, // Realtime data is always fresh
93
+ enabled: enabled && !subscribe,
94
+ staleTime: subscribe ? Infinity : staleTime,
132
95
  gcTime,
133
96
  });
134
97
  return useSubscribedResult(query, subscribe, enabled, subscription);
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-doc.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-doc.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';\nimport { doc, getDoc, onSnapshot, type DocumentData } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';\nimport type { WithId, WithSourceState } from '../../firestore/types.js';\nimport type { FirestoreDocOptions } from './types.js';\n\n/**\n * Fetch a single Firestore document with optional realtime updates.\n * * @example\n * ```tsx\n * // Simple fetch\n * const { data: user } = useFirestoreDoc<User>({\n * docPath: `users/${userId}`,\n * queryKey: ['user', userId],\n * });\n * * // With realtime updates\n * const { data: entity } = useFirestoreDoc<Entity>({\n * docPath: `entities/${entityId}`,\n * queryKey: ['entity', entityId],\n * subscribe: true,\n * });\n * * // Conditional fetch\n * const { data: profile } = useFirestoreDoc<Profile>({\n * docPath: `profiles/${userId}`,\n * queryKey: ['profile', userId],\n * enabled: !!userId,\n * });\n * ```\n */\nexport function useFirestoreDoc<T extends DocumentData = DocumentData>({\n docPath,\n queryKey,\n enabled = true,\n subscribe = false,\n staleTime,\n gcTime,\n select,\n}: FirestoreDocOptions<T>): WithSourceState<UseQueryResult<WithId<T> | null, Error>> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n const queryKeyMemo = JSON.stringify(queryKey);\n\n // Listener errors can't surface through useQuery (the queryFn is disabled while\n // subscribed), so they're tracked per subscription identity and merged into the result.\n const subscription = useSubscriptionStatus(\n JSON.stringify([docPath, queryKeyMemo, enabled, subscribe]),\n );\n const { reset: resetStatus, update: updateStatus, restarts } = subscription;\n\n // Set up realtime subscription\n useEffect(() => {\n if (!subscribe || !enabled) return;\n\n resetStatus();\n\n // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session\n // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the\n // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are\n // cleaned up on unmount so a pending retry never fires after teardown.\n let currentUnsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let disposed = false;\n\n const start = () => {\n if (disposed) return;\n const docRef = doc(db, docPath);\n currentUnsubscribe = onSnapshot(\n docRef,\n { includeMetadataChanges: true },\n (snapshot) => {\n attempt = 0;\n updateStatus({ error: null, restart: null });\n if (snapshot.exists()) {\n const rawData = snapshot.data();\n // Include id in data passed to select, so it can be renamed/transformed\n const dataWithId = { id: snapshot.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n queryClient.setQueryData(queryKey, data as WithId<T>);\n } else {\n queryClient.setQueryData(queryKey, null);\n }\n const fromCache = snapshot.metadata?.fromCache ?? false;\n updateStatus((prev) => ({\n sourceState: fromCache\n ? prev.sourceState === 'connecting'\n ? 'connecting'\n : 'offline'\n : 'live',\n }));\n },\n (error) => {\n // Heal a transient permission-denied by resubscribing on the backoff ladder,\n // keeping the last-known data visible. Only surface the error once the ladder\n // is exhausted; any other error surfaces immediately, as before.\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n currentUnsubscribe?.();\n currentUnsubscribe = null;\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n updateStatus({ sourceState: 'connecting' });\n retryTimer = setTimeout(start, delay);\n return;\n }\n console.error('[useFirestoreDoc] Subscription error:', error);\n updateStatus({ error, sourceState: 'error', restart: null });\n queryClient.setQueryData(queryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n // Note: select intentionally excluded to prevent re-subscribing on every render if the caller\n // passes an inline function. queryKey is tracked via queryKeyMemo above.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [\n db,\n docPath,\n queryKeyMemo,\n enabled,\n subscribe,\n restarts,\n queryClient,\n resetStatus,\n updateStatus,\n ]);\n\n const query = useQuery({\n queryKey,\n queryFn: async (): Promise<WithId<T> | null> => {\n const docRef = doc(db, docPath);\n const snapshot = await getDoc(docRef);\n\n if (!snapshot.exists()) {\n return null;\n }\n\n const rawData = snapshot.data();\n // Include id in data passed to select, so it can be renamed/transformed\n const dataWithId = { id: snapshot.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n },\n enabled: enabled && !subscribe, // Don't fetch if subscribing (snapshot handles it)\n staleTime: subscribe ? Infinity : staleTime, // Realtime data is always fresh\n gcTime,\n });\n\n return useSubscribedResult(query, subscribe, enabled, subscription);\n}\n"]}
1
+ {"version":3,"file":"use-firestore-doc.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-doc.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useEffect } from 'react';\nimport { useQuery, useQueryClient, type UseQueryResult } from '@tanstack/react-query';\nimport { doc, getDoc, onSnapshot, type DocumentData } from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport { useSubscribedResult, useSubscriptionStatus } from './subscription-status.js';\nimport type { WithId, WithSourceState } from '../../firestore/types.js';\nimport type { FirestoreDocOptions } from './types.js';\n\nexport function useFirestoreDoc<T extends DocumentData = DocumentData>({\n docPath,\n queryKey,\n enabled = true,\n subscribe = false,\n staleTime,\n gcTime,\n select,\n}: FirestoreDocOptions<T>): WithSourceState<UseQueryResult<WithId<T> | null, Error>> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n const queryKeyMemo = JSON.stringify(queryKey);\n\n const subscription = useSubscriptionStatus(\n JSON.stringify([docPath, queryKeyMemo, enabled, subscribe]),\n );\n const { reset: resetStatus, update: updateStatus, restarts } = subscription;\n\n useEffect(() => {\n if (!subscribe || !enabled) return;\n\n resetStatus();\n\n let currentUnsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let disposed = false;\n\n const start = () => {\n if (disposed) return;\n const docRef = doc(db, docPath);\n currentUnsubscribe = onSnapshot(\n docRef,\n { includeMetadataChanges: true },\n (snapshot) => {\n attempt = 0;\n updateStatus({ error: null, restart: null });\n if (snapshot.exists()) {\n const rawData = snapshot.data();\n const dataWithId = { id: snapshot.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n queryClient.setQueryData(queryKey, data as WithId<T>);\n } else {\n queryClient.setQueryData(queryKey, null);\n }\n const fromCache = snapshot.metadata?.fromCache ?? false;\n updateStatus((prev) => ({\n sourceState: fromCache\n ? prev.sourceState === 'connecting'\n ? 'connecting'\n : 'offline'\n : 'live',\n }));\n },\n (error) => {\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n currentUnsubscribe?.();\n currentUnsubscribe = null;\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n updateStatus({ sourceState: 'connecting' });\n retryTimer = setTimeout(start, delay);\n return;\n }\n console.error('[useFirestoreDoc] Subscription error:', error);\n updateStatus({ error, sourceState: 'error', restart: null });\n queryClient.setQueryData(queryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- queryKey is tracked by queryKeyMemo; an inline select must not re-subscribe every render\n }, [\n db,\n docPath,\n queryKeyMemo,\n enabled,\n subscribe,\n restarts,\n queryClient,\n resetStatus,\n updateStatus,\n ]);\n\n const query = useQuery({\n queryKey,\n queryFn: async (): Promise<WithId<T> | null> => {\n const docRef = doc(db, docPath);\n const snapshot = await getDoc(docRef);\n\n if (!snapshot.exists()) {\n return null;\n }\n\n const rawData = snapshot.data();\n const dataWithId = { id: snapshot.id, ...rawData };\n const data = select ? select(dataWithId) : dataWithId;\n return data as WithId<T>;\n },\n enabled: enabled && !subscribe,\n staleTime: subscribe ? Infinity : staleTime,\n gcTime,\n });\n\n return useSubscribedResult(query, subscribe, enabled, subscription);\n}\n"]}
@@ -1,35 +1,6 @@
1
1
  import { type UseInfiniteQueryResult } from '@tanstack/react-query';
2
2
  import { type DocumentData, type DocumentSnapshot } from 'firebase/firestore';
3
3
  import type { FirestoreInfiniteOptions, InfinitePage } from './types.js';
4
- /**
5
- * Infinite scroll pagination for Firestore collections.
6
- * Automatically handles cursor-based pagination with React Query.
7
- *
8
- * @example
9
- * ```tsx
10
- * const {
11
- * data,
12
- * fetchNextPage,
13
- * hasNextPage,
14
- * isFetchingNextPage,
15
- * isLoading,
16
- * } = useFirestoreInfinite<Post>({
17
- * collectionPath: 'posts',
18
- * queryKey: ['posts', 'feed'],
19
- * constraints: [
20
- * where('status', '==', 'published'),
21
- * orderBy('createdAt', 'desc'),
22
- * ],
23
- * pageSize: 20,
24
- * });
25
- *
26
- * // Flatten pages for rendering
27
- * const posts = data?.pages.flatMap(page => page.items) ?? [];
28
- *
29
- * // Load more on scroll
30
- * <InfiniteScroll onLoadMore={fetchNextPage} hasMore={hasNextPage} />
31
- * ```
32
- */
33
4
  export declare function useFirestoreInfinite<T extends DocumentData = DocumentData>({ collectionPath, queryKey, constraints, pageSize, enabled, staleTime, gcTime, select, }: FirestoreInfiniteOptions<T>): UseInfiniteQueryResult<{
34
5
  pages: InfinitePage<T>[];
35
6
  pageParams: (DocumentSnapshot | null)[];
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-infinite.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-infinite.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIzE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC1E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,QAA4B,EAC5B,OAAc,EACd,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,sBAAsB,CACrD;IAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,CAAA;CAAE,EACrE,KAAK,CACN,CA0CA"}
1
+ {"version":3,"file":"use-firestore-infinite.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-infinite.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoB,KAAK,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAML,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAIzE,wBAAgB,oBAAoB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC1E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,QAA4B,EAC5B,OAAc,EACd,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,wBAAwB,CAAC,CAAC,CAAC,GAAG,sBAAsB,CACrD;IAAE,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;IAAC,UAAU,EAAE,CAAC,gBAAgB,GAAG,IAAI,CAAC,EAAE,CAAA;CAAE,EACrE,KAAK,CACN,CAuCA"}