@ttt-productions/query-core 0.14.22 → 0.14.24

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 (137) 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 +5 -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/callables/create-callables.d.ts +40 -0
  21. package/dist/react/callables/create-callables.d.ts.map +1 -0
  22. package/dist/react/callables/create-callables.js +101 -0
  23. package/dist/react/callables/create-callables.js.map +1 -0
  24. package/dist/react/defaults.d.ts +0 -4
  25. package/dist/react/defaults.d.ts.map +1 -1
  26. package/dist/react/defaults.js +2 -6
  27. package/dist/react/defaults.js.map +1 -1
  28. package/dist/react/domain-events/cache-invalidation.d.ts +0 -37
  29. package/dist/react/domain-events/cache-invalidation.d.ts.map +1 -1
  30. package/dist/react/domain-events/cache-invalidation.js +4 -53
  31. package/dist/react/domain-events/cache-invalidation.js.map +1 -1
  32. package/dist/react/domain-events/create-domain-event-invalidator.d.ts +0 -18
  33. package/dist/react/domain-events/create-domain-event-invalidator.d.ts.map +1 -1
  34. package/dist/react/domain-events/create-domain-event-invalidator.js +0 -5
  35. package/dist/react/domain-events/create-domain-event-invalidator.js.map +1 -1
  36. package/dist/react/firestore/absence-scheduler.d.ts +0 -28
  37. package/dist/react/firestore/absence-scheduler.d.ts.map +1 -1
  38. package/dist/react/firestore/absence-scheduler.js +1 -39
  39. package/dist/react/firestore/absence-scheduler.js.map +1 -1
  40. package/dist/react/firestore/batch-doc-loader.d.ts +0 -30
  41. package/dist/react/firestore/batch-doc-loader.d.ts.map +1 -1
  42. package/dist/react/firestore/batch-doc-loader.js +0 -34
  43. package/dist/react/firestore/batch-doc-loader.js.map +1 -1
  44. package/dist/react/firestore/context.d.ts +0 -19
  45. package/dist/react/firestore/context.d.ts.map +1 -1
  46. package/dist/react/firestore/context.js +0 -19
  47. package/dist/react/firestore/context.js.map +1 -1
  48. package/dist/react/firestore/doc-subscription-registry.d.ts +0 -23
  49. package/dist/react/firestore/doc-subscription-registry.d.ts.map +1 -1
  50. package/dist/react/firestore/doc-subscription-registry.js +5 -26
  51. package/dist/react/firestore/doc-subscription-registry.js.map +1 -1
  52. package/dist/react/firestore/infinite-helpers.d.ts +0 -12
  53. package/dist/react/firestore/infinite-helpers.d.ts.map +1 -1
  54. package/dist/react/firestore/infinite-helpers.js +0 -12
  55. package/dist/react/firestore/infinite-helpers.js.map +1 -1
  56. package/dist/react/firestore/resubscribe.d.ts +0 -20
  57. package/dist/react/firestore/resubscribe.d.ts.map +1 -1
  58. package/dist/react/firestore/resubscribe.js +0 -20
  59. package/dist/react/firestore/resubscribe.js.map +1 -1
  60. package/dist/react/firestore/subscription-status.d.ts +0 -29
  61. package/dist/react/firestore/subscription-status.d.ts.map +1 -1
  62. package/dist/react/firestore/subscription-status.js +1 -34
  63. package/dist/react/firestore/subscription-status.js.map +1 -1
  64. package/dist/react/firestore/types.d.ts +0 -64
  65. package/dist/react/firestore/types.d.ts.map +1 -1
  66. package/dist/react/firestore/types.js +0 -3
  67. package/dist/react/firestore/types.js.map +1 -1
  68. package/dist/react/firestore/use-firestore-collection.d.ts +0 -20
  69. package/dist/react/firestore/use-firestore-collection.d.ts.map +1 -1
  70. package/dist/react/firestore/use-firestore-collection.js +1 -35
  71. package/dist/react/firestore/use-firestore-collection.js.map +1 -1
  72. package/dist/react/firestore/use-firestore-count.d.ts +0 -15
  73. package/dist/react/firestore/use-firestore-count.d.ts.map +1 -1
  74. package/dist/react/firestore/use-firestore-count.js +0 -15
  75. package/dist/react/firestore/use-firestore-count.js.map +1 -1
  76. package/dist/react/firestore/use-firestore-doc.d.ts +0 -23
  77. package/dist/react/firestore/use-firestore-doc.d.ts.map +1 -1
  78. package/dist/react/firestore/use-firestore-doc.js +3 -40
  79. package/dist/react/firestore/use-firestore-doc.js.map +1 -1
  80. package/dist/react/firestore/use-firestore-infinite.d.ts +0 -29
  81. package/dist/react/firestore/use-firestore-infinite.d.ts.map +1 -1
  82. package/dist/react/firestore/use-firestore-infinite.js +0 -32
  83. package/dist/react/firestore/use-firestore-infinite.js.map +1 -1
  84. package/dist/react/firestore/use-firestore-live-infinite.d.ts +0 -34
  85. package/dist/react/firestore/use-firestore-live-infinite.d.ts.map +1 -1
  86. package/dist/react/firestore/use-firestore-live-infinite.js +1 -35
  87. package/dist/react/firestore/use-firestore-live-infinite.js.map +1 -1
  88. package/dist/react/firestore/use-firestore-mutations.d.ts.map +1 -1
  89. package/dist/react/firestore/use-firestore-mutations.js +6 -5
  90. package/dist/react/firestore/use-firestore-mutations.js.map +1 -1
  91. package/dist/react/firestore/use-firestore-paginated.d.ts +0 -30
  92. package/dist/react/firestore/use-firestore-paginated.d.ts.map +1 -1
  93. package/dist/react/firestore/use-firestore-paginated.js +2 -33
  94. package/dist/react/firestore/use-firestore-paginated.js.map +1 -1
  95. package/dist/react/firestore/useBatchFirestoreDocs.d.ts +1 -123
  96. package/dist/react/firestore/useBatchFirestoreDocs.d.ts.map +1 -1
  97. package/dist/react/firestore/useBatchFirestoreDocs.js +23 -64
  98. package/dist/react/firestore/useBatchFirestoreDocs.js.map +1 -1
  99. package/dist/react/index.d.ts +4 -0
  100. package/dist/react/index.d.ts.map +1 -1
  101. package/dist/react/index.js +2 -13
  102. package/dist/react/index.js.map +1 -1
  103. package/dist/react/pending-mutations.d.ts +1 -21
  104. package/dist/react/pending-mutations.d.ts.map +1 -1
  105. package/dist/react/pending-mutations.js +1 -32
  106. package/dist/react/pending-mutations.js.map +1 -1
  107. package/dist/react/provider.d.ts +0 -5
  108. package/dist/react/provider.d.ts.map +1 -1
  109. package/dist/react/provider.js +0 -4
  110. package/dist/react/provider.js.map +1 -1
  111. package/dist/react/query-client.d.ts +0 -4
  112. package/dist/react/query-client.d.ts.map +1 -1
  113. package/dist/react/query-client.js +0 -4
  114. package/dist/react/query-client.js.map +1 -1
  115. package/dist/react/search/types.d.ts +0 -12
  116. package/dist/react/search/types.d.ts.map +1 -1
  117. package/dist/react/search/types.js.map +1 -1
  118. package/dist/react/search/use-firestore-search.d.ts +0 -29
  119. package/dist/react/search/use-firestore-search.d.ts.map +1 -1
  120. package/dist/react/search/use-firestore-search.js +3 -41
  121. package/dist/react/search/use-firestore-search.js.map +1 -1
  122. package/dist/react/session-mutation.d.ts +27 -0
  123. package/dist/react/session-mutation.d.ts.map +1 -0
  124. package/dist/react/session-mutation.js +150 -0
  125. package/dist/react/session-mutation.js.map +1 -0
  126. package/dist/react/use-read-retry-state.d.ts +1 -21
  127. package/dist/react/use-read-retry-state.d.ts.map +1 -1
  128. package/dist/react/use-read-retry-state.js +2 -21
  129. package/dist/react/use-read-retry-state.js.map +1 -1
  130. package/dist/search/rule.d.ts +0 -6
  131. package/dist/search/rule.d.ts.map +1 -1
  132. package/dist/search/rule.js +0 -6
  133. package/dist/search/rule.js.map +1 -1
  134. package/dist/search/types.d.ts +1 -13
  135. package/dist/search/types.d.ts.map +1 -1
  136. package/dist/search/types.js.map +1 -1
  137. package/package.json +4 -4
@@ -0,0 +1,150 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useCallback, useContext, useInsertionEffect, useState, } from 'react';
4
+ import { useMutation, useQueryClient, } from '@tanstack/react-query';
5
+ export class MutationSessionEndedError extends Error {
6
+ name = 'AbortError';
7
+ constructor(options) {
8
+ super('The session that started this mutation has ended.', options);
9
+ }
10
+ }
11
+ const MutationSessionContext = createContext(null);
12
+ export function MutationSessionProvider({ currentUid, children }) {
13
+ const [store] = useState(() => ({
14
+ current: { uid: currentUid, generation: 0 },
15
+ }));
16
+ // Insertion effects run before any layout effect of the commit, so a child's layout effect
17
+ // never starts a mutation under the uid this commit ends.
18
+ useInsertionEffect(() => {
19
+ if (store.current.uid !== currentUid) {
20
+ store.current = { uid: currentUid, generation: store.current.generation + 1 };
21
+ }
22
+ }, [store, currentUid]);
23
+ return (_jsx(MutationSessionContext.Provider, { value: store, children: children }));
24
+ }
25
+ const ALWAYS_CURRENT = {
26
+ uid: null,
27
+ isCurrent: () => true,
28
+ assertCurrent: () => { },
29
+ };
30
+ function captureSession(store) {
31
+ if (!store)
32
+ return ALWAYS_CURRENT;
33
+ const { uid, generation } = store.current;
34
+ const isCurrent = () => store.current.generation === generation;
35
+ return {
36
+ uid,
37
+ isCurrent,
38
+ assertCurrent: () => {
39
+ if (!isCurrent())
40
+ throw new MutationSessionEndedError();
41
+ },
42
+ };
43
+ }
44
+ export function useMutationSessionCapture() {
45
+ const store = useContext(MutationSessionContext);
46
+ return useCallback(() => captureSession(store), [store]);
47
+ }
48
+ const runSessions = new WeakMap();
49
+ function runHasEnded(store, context) {
50
+ if (!store)
51
+ return false;
52
+ return !(runSessions.get(context)?.isCurrent() ?? false);
53
+ }
54
+ function retriesAfter(retry, failureCount, error) {
55
+ if (error instanceof MutationSessionEndedError)
56
+ return false;
57
+ if (typeof retry === 'function')
58
+ return retry(failureCount, error);
59
+ if (typeof retry === 'number')
60
+ return failureCount < retry;
61
+ return retry === true;
62
+ }
63
+ function throwsToBoundary(throwOnError, error) {
64
+ if (error instanceof MutationSessionEndedError)
65
+ return false;
66
+ if (typeof throwOnError === 'function')
67
+ return throwOnError(error);
68
+ return throwOnError === true;
69
+ }
70
+ function fenceCallOptions(session, options) {
71
+ if (!options)
72
+ return undefined;
73
+ const { onSuccess, onError, onSettled } = options;
74
+ return {
75
+ onSuccess: onSuccess
76
+ ? (...args) => {
77
+ if (session.isCurrent())
78
+ onSuccess(...args);
79
+ }
80
+ : undefined,
81
+ onError: onError
82
+ ? (error, ...rest) => {
83
+ if (!(error instanceof MutationSessionEndedError) && session.isCurrent()) {
84
+ onError(error, ...rest);
85
+ }
86
+ }
87
+ : undefined,
88
+ onSettled: onSettled
89
+ ? (data, error, ...rest) => {
90
+ if (!(error instanceof MutationSessionEndedError) && session.isCurrent()) {
91
+ onSettled(data, error, ...rest);
92
+ }
93
+ }
94
+ : undefined,
95
+ };
96
+ }
97
+ export function useSessionMutation(options) {
98
+ const store = useContext(MutationSessionContext);
99
+ const queryClient = useQueryClient();
100
+ const { mutationFn, onMutate, onSuccess, onError, onSettled, retry, throwOnError, ...rest } = options;
101
+ const defaults = queryClient.defaultMutationOptions({ mutationKey: options.mutationKey });
102
+ const baseRetry = (retry ?? defaults.retry);
103
+ const baseThrowOnError = (throwOnError ?? defaults.throwOnError);
104
+ const mutation = useMutation({
105
+ ...rest,
106
+ retry: (failureCount, error) => retriesAfter(baseRetry, failureCount, error),
107
+ throwOnError: (error) => throwsToBoundary(baseThrowOnError, error),
108
+ onMutate: (variables, context) => {
109
+ if (store)
110
+ runSessions.set(context, captureSession(store));
111
+ return onMutate?.(variables, context);
112
+ },
113
+ mutationFn: async (variables, context) => {
114
+ const session = store ? runSessions.get(context) : ALWAYS_CURRENT;
115
+ if (!session || !session.isCurrent())
116
+ throw new MutationSessionEndedError();
117
+ let data;
118
+ try {
119
+ data = await mutationFn(variables, { ...context, session });
120
+ }
121
+ catch (error) {
122
+ if (!session.isCurrent())
123
+ throw new MutationSessionEndedError({ cause: error });
124
+ throw error;
125
+ }
126
+ session.assertCurrent();
127
+ return data;
128
+ },
129
+ onSuccess: (data, variables, onMutateResult, context) => {
130
+ if (runHasEnded(store, context))
131
+ return;
132
+ return onSuccess?.(data, variables, onMutateResult, context);
133
+ },
134
+ onError: (error, variables, onMutateResult, context) => {
135
+ if (error instanceof MutationSessionEndedError || runHasEnded(store, context))
136
+ return;
137
+ return onError?.(error, variables, onMutateResult, context);
138
+ },
139
+ onSettled: (data, error, variables, onMutateResult, context) => {
140
+ if (error instanceof MutationSessionEndedError || runHasEnded(store, context))
141
+ return;
142
+ return onSettled?.(data, error, variables, onMutateResult, context);
143
+ },
144
+ });
145
+ const { mutate: rawMutate, mutateAsync: rawMutateAsync } = mutation;
146
+ const mutate = useCallback((variables, callOptions) => rawMutate(variables, fenceCallOptions(captureSession(store), callOptions)), [rawMutate, store]);
147
+ const mutateAsync = useCallback((variables, callOptions) => rawMutateAsync(variables, fenceCallOptions(captureSession(store), callOptions)), [rawMutateAsync, store]);
148
+ return { ...mutation, mutate, mutateAsync };
149
+ }
150
+ //# sourceMappingURL=session-mutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-mutation.js","sourceRoot":"","sources":["../../src/react/session-mutation.tsx"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport {\n createContext,\n useCallback,\n useContext,\n useInsertionEffect,\n useState,\n type ReactNode,\n} from 'react';\nimport {\n useMutation,\n useQueryClient,\n type DefaultError,\n type MutateOptions,\n type MutationFunctionContext,\n type UseMutationOptions,\n type UseMutationResult,\n} from '@tanstack/react-query';\n\nexport interface MutationSession {\n uid: string | null;\n isCurrent(): boolean;\n assertCurrent(): void;\n}\n\nexport type SessionMutationFunctionContext = MutationFunctionContext & {\n session: MutationSession;\n};\n\nexport type SessionMutationOptions<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n> = Omit<UseMutationOptions<TData, TError, TVariables, TOnMutateResult>, 'mutationFn'> & {\n mutationFn: (variables: TVariables, context: SessionMutationFunctionContext) => Promise<TData>;\n};\n\nexport class MutationSessionEndedError extends Error {\n override name = 'AbortError';\n\n constructor(options?: { cause?: unknown }) {\n super('The session that started this mutation has ended.', options);\n }\n}\n\ninterface SessionStore {\n current: { uid: string | null; generation: number };\n}\n\nconst MutationSessionContext = createContext<SessionStore | null>(null);\n\nexport interface MutationSessionProviderProps {\n currentUid: string | null;\n children?: ReactNode;\n}\n\nexport function MutationSessionProvider({ currentUid, children }: MutationSessionProviderProps) {\n const [store] = useState<SessionStore>(() => ({\n current: { uid: currentUid, generation: 0 },\n }));\n // Insertion effects run before any layout effect of the commit, so a child's layout effect\n // never starts a mutation under the uid this commit ends.\n useInsertionEffect(() => {\n if (store.current.uid !== currentUid) {\n store.current = { uid: currentUid, generation: store.current.generation + 1 };\n }\n }, [store, currentUid]);\n return (\n <MutationSessionContext.Provider value={store}>{children}</MutationSessionContext.Provider>\n );\n}\n\nconst ALWAYS_CURRENT: MutationSession = {\n uid: null,\n isCurrent: () => true,\n assertCurrent: () => {},\n};\n\nfunction captureSession(store: SessionStore | null): MutationSession {\n if (!store) return ALWAYS_CURRENT;\n const { uid, generation } = store.current;\n const isCurrent = () => store.current.generation === generation;\n return {\n uid,\n isCurrent,\n assertCurrent: () => {\n if (!isCurrent()) throw new MutationSessionEndedError();\n },\n };\n}\n\nexport function useMutationSessionCapture(): () => MutationSession {\n const store = useContext(MutationSessionContext);\n return useCallback(() => captureSession(store), [store]);\n}\n\nconst runSessions = new WeakMap<MutationFunctionContext, MutationSession>();\n\nfunction runHasEnded(store: SessionStore | null, context: MutationFunctionContext): boolean {\n if (!store) return false;\n return !(runSessions.get(context)?.isCurrent() ?? false);\n}\n\ntype Retry<TError> = UseMutationOptions<unknown, TError, unknown, unknown>['retry'];\ntype ThrowOnError<TError> = UseMutationOptions<unknown, TError, unknown, unknown>['throwOnError'];\n\nfunction retriesAfter<TError>(retry: Retry<TError>, failureCount: number, error: TError): boolean {\n if (error instanceof MutationSessionEndedError) return false;\n if (typeof retry === 'function') return retry(failureCount, error);\n if (typeof retry === 'number') return failureCount < retry;\n return retry === true;\n}\n\nfunction throwsToBoundary<TError>(throwOnError: ThrowOnError<TError>, error: TError): boolean {\n if (error instanceof MutationSessionEndedError) return false;\n if (typeof throwOnError === 'function') return throwOnError(error);\n return throwOnError === true;\n}\n\nfunction fenceCallOptions<TData, TError, TVariables, TOnMutateResult>(\n session: MutationSession,\n options: MutateOptions<TData, TError, TVariables, TOnMutateResult> | undefined,\n): MutateOptions<TData, TError, TVariables, TOnMutateResult> | undefined {\n if (!options) return undefined;\n const { onSuccess, onError, onSettled } = options;\n return {\n onSuccess: onSuccess\n ? (...args) => {\n if (session.isCurrent()) onSuccess(...args);\n }\n : undefined,\n onError: onError\n ? (error, ...rest) => {\n if (!(error instanceof MutationSessionEndedError) && session.isCurrent()) {\n onError(error, ...rest);\n }\n }\n : undefined,\n onSettled: onSettled\n ? (data, error, ...rest) => {\n if (!(error instanceof MutationSessionEndedError) && session.isCurrent()) {\n onSettled(data, error, ...rest);\n }\n }\n : undefined,\n };\n}\n\nexport function useSessionMutation<\n TData = unknown,\n TError = DefaultError,\n TVariables = void,\n TOnMutateResult = unknown,\n>(\n options: SessionMutationOptions<TData, TError, TVariables, TOnMutateResult>,\n): UseMutationResult<TData, TError, TVariables, TOnMutateResult> {\n const store = useContext(MutationSessionContext);\n const queryClient = useQueryClient();\n const { mutationFn, onMutate, onSuccess, onError, onSettled, retry, throwOnError, ...rest } =\n options;\n const defaults = queryClient.defaultMutationOptions<\n UseMutationOptions<unknown, TError, unknown, unknown>\n >({ mutationKey: options.mutationKey });\n const baseRetry = (retry ?? defaults.retry) as Retry<TError>;\n const baseThrowOnError = (throwOnError ?? defaults.throwOnError) as ThrowOnError<TError>;\n\n const mutation = useMutation<TData, TError, TVariables, TOnMutateResult>({\n ...rest,\n retry: (failureCount, error) => retriesAfter(baseRetry, failureCount, error),\n throwOnError: (error) => throwsToBoundary(baseThrowOnError, error),\n onMutate: (variables, context) => {\n if (store) runSessions.set(context, captureSession(store));\n return onMutate?.(variables, context) as TOnMutateResult | Promise<TOnMutateResult>;\n },\n mutationFn: async (variables, context) => {\n const session = store ? runSessions.get(context) : ALWAYS_CURRENT;\n if (!session || !session.isCurrent()) throw new MutationSessionEndedError();\n let data: TData;\n try {\n data = await mutationFn(variables, { ...context, session });\n } catch (error) {\n if (!session.isCurrent()) throw new MutationSessionEndedError({ cause: error });\n throw error;\n }\n session.assertCurrent();\n return data;\n },\n onSuccess: (data, variables, onMutateResult, context) => {\n if (runHasEnded(store, context)) return;\n return onSuccess?.(data, variables, onMutateResult, context);\n },\n onError: (error, variables, onMutateResult, context) => {\n if (error instanceof MutationSessionEndedError || runHasEnded(store, context)) return;\n return onError?.(error, variables, onMutateResult, context);\n },\n onSettled: (data, error, variables, onMutateResult, context) => {\n if (error instanceof MutationSessionEndedError || runHasEnded(store, context)) return;\n return onSettled?.(data, error, variables, onMutateResult, context);\n },\n });\n\n const { mutate: rawMutate, mutateAsync: rawMutateAsync } = mutation;\n const mutate = useCallback(\n (\n variables: TVariables,\n callOptions?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,\n ) => rawMutate(variables, fenceCallOptions(captureSession(store), callOptions)),\n [rawMutate, store],\n );\n const mutateAsync = useCallback(\n (\n variables: TVariables,\n callOptions?: MutateOptions<TData, TError, TVariables, TOnMutateResult>,\n ) => rawMutateAsync(variables, fenceCallOptions(captureSession(store), callOptions)),\n [rawMutateAsync, store],\n );\n return { ...mutation, mutate, mutateAsync } as UseMutationResult<\n TData,\n TError,\n TVariables,\n TOnMutateResult\n >;\n}\n"]}
@@ -1,40 +1,20 @@
1
1
  import { type QueryKey } from '@tanstack/react-query';
2
- /** The parts of a read's result the retry state is decided from. */
3
2
  export interface ReadRetrySource<TError = Error> {
4
3
  error: TError | null | undefined;
5
4
  isFetching: boolean;
6
5
  isLoading: boolean;
7
- /** A fetch waiting for the network counts as still running. */
8
6
  isPaused?: boolean;
9
7
  }
10
- /** A read's failure as its surface shows it, held on screen while a retry of it runs. */
11
8
  export interface ReadRetryState<TError = Error> {
12
- /** The read's failure: its current one, or the last one while a retry of it is running. */
13
9
  error: TError | null;
14
- /** A retry of the failed read is running. */
15
10
  isRetrying: boolean;
16
- /** The read has not answered yet and is not a retry of a failure. */
17
11
  isLoading: boolean;
18
12
  }
19
- /** One read a keyed retry state follows: its result and its identity. */
20
13
  export interface ReadRetryEntry<TError = Error> {
21
14
  source: ReadRetrySource<TError>;
22
15
  queryKey: QueryKey;
23
16
  }
24
- /**
25
- * The failure and retry state of each of several reads, in entry order — the keyed form of
26
- * `useReadRetryState` for a set whose size changes between renders (a `useQueries` list, a batch
27
- * of per-id reads). Each read's failure is held under its own `queryKey`, so one read's retry
28
- * never shows another's failure, and a read that leaves the set drops what it held.
29
- */
30
17
  export declare function useReadRetryStates<TError = Error>(entries: readonly ReadRetryEntry<TError>[]): ReadRetryState<TError>[];
31
- /**
32
- * The failure and retry state of one read. TanStack Query clears the `error` of a query that never
33
- * succeeded and puts it back to `pending` the moment a refetch of it starts, so a retry state built
34
- * from `isFetching && error` is never true for a failed first read, and its failure panel turns into
35
- * a loading state under the retry the person pressed. This holds the read's last failure until the
36
- * retry settles — an answer clears it, a new failure replaces it — and reports the retry as running
37
- * meanwhile. The failure belongs to `queryKey`: a read under another key never shows it.
38
- */
18
+ /** TanStack clears a never-succeeded query's `error` as its refetch starts, so the failure is held until the retry settles. */
39
19
  export declare function useReadRetryState<TError = Error>(source: ReadRetrySource<TError>, queryKey: QueryKey): ReadRetryState<TError>;
40
20
  //# sourceMappingURL=use-read-retry-state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"use-read-retry-state.d.ts","sourceRoot":"","sources":["../../src/react/use-read-retry-state.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE/D,oEAAoE;AACpE,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,KAAK;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,yFAAyF;AACzF,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,KAAK;IAC5C,2FAA2F;IAC3F,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6CAA6C;IAC7C,UAAU,EAAE,OAAO,CAAC;IACpB,qEAAqE;IACrE,SAAS,EAAE,OAAO,CAAC;CACpB;AAmBD,yEAAyE;AACzE,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,KAAK;IAC5C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AA0BD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAG,KAAK,EAC/C,OAAO,EAAE,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,GACzC,cAAc,CAAC,MAAM,CAAC,EAAE,CAa1B;AAUD;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAG,KAAK,EAC9C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAC/B,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,MAAM,CAAC,CAExB"}
1
+ {"version":3,"file":"use-read-retry-state.d.ts","sourceRoot":"","sources":["../../src/react/use-read-retry-state.ts"],"names":[],"mappings":"AAGA,OAAO,EAAW,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAE/D,MAAM,WAAW,eAAe,CAAC,MAAM,GAAG,KAAK;IAC7C,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACjC,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,KAAK;IAC5C,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAeD,MAAM,WAAW,cAAc,CAAC,MAAM,GAAG,KAAK;IAC5C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AAyBD,wBAAgB,kBAAkB,CAAC,MAAM,GAAG,KAAK,EAC/C,OAAO,EAAE,SAAS,cAAc,CAAC,MAAM,CAAC,EAAE,GACzC,cAAc,CAAC,MAAM,CAAC,EAAE,CAY1B;AAUD,+HAA+H;AAC/H,wBAAgB,iBAAiB,CAAC,MAAM,GAAG,KAAK,EAC9C,MAAM,EAAE,eAAe,CAAC,MAAM,CAAC,EAC/B,QAAQ,EAAE,QAAQ,GACjB,cAAc,CAAC,MAAM,CAAC,CAExB"}
@@ -1,11 +1,7 @@
1
1
  'use client';
2
2
  import { useState } from 'react';
3
3
  import { hashKey } from '@tanstack/react-query';
4
- /**
5
- * One failure is its name, message, and `code`, not its object: a composite source that builds its
6
- * error in render hands back a new object for the same failure every render, and holding each one
7
- * as new would set state on every render without end.
8
- */
4
+ /** A composite source builds a new error object every render, so a failure is compared by name, message, and `code`. */
9
5
  function sameFailure(a, b) {
10
6
  if (a === b)
11
7
  return true;
@@ -15,7 +11,6 @@ function sameFailure(a, b) {
15
11
  const y = b;
16
12
  return x.name === y.name && x.message === y.message && x.code === y.code;
17
13
  }
18
- /** The failure a read holds next, given what it held: its live failure, or the held one while it runs. */
19
14
  function nextHeldFailure(held, source) {
20
15
  const live = source.error ?? null;
21
16
  if (live !== null)
@@ -31,12 +26,6 @@ function toRetryState(source, held) {
31
26
  isLoading: error === null && source.isLoading,
32
27
  };
33
28
  }
34
- /**
35
- * The failure and retry state of each of several reads, in entry order — the keyed form of
36
- * `useReadRetryState` for a set whose size changes between renders (a `useQueries` list, a batch
37
- * of per-id reads). Each read's failure is held under its own `queryKey`, so one read's retry
38
- * never shows another's failure, and a read that leaves the set drops what it held.
39
- */
40
29
  export function useReadRetryStates(entries) {
41
30
  const [held, setHeld] = useState({});
42
31
  const next = {};
@@ -47,7 +36,6 @@ export function useReadRetryStates(entries) {
47
36
  next[identity] = failure;
48
37
  return toRetryState(source, failure);
49
38
  });
50
- // Render-phase adjustment: the held failures follow the reads without an effect's extra render.
51
39
  if (!sameHeld(held, next))
52
40
  setHeld(next);
53
41
  return states;
@@ -56,14 +44,7 @@ function sameHeld(a, b) {
56
44
  const keys = Object.keys(a);
57
45
  return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);
58
46
  }
59
- /**
60
- * The failure and retry state of one read. TanStack Query clears the `error` of a query that never
61
- * succeeded and puts it back to `pending` the moment a refetch of it starts, so a retry state built
62
- * from `isFetching && error` is never true for a failed first read, and its failure panel turns into
63
- * a loading state under the retry the person pressed. This holds the read's last failure until the
64
- * retry settles — an answer clears it, a new failure replaces it — and reports the retry as running
65
- * meanwhile. The failure belongs to `queryKey`: a read under another key never shows it.
66
- */
47
+ /** TanStack clears a never-succeeded query's `error` as its refetch starts, so the failure is held until the retry settles. */
67
48
  export function useReadRetryState(source, queryKey) {
68
49
  return useReadRetryStates([{ source, queryKey }])[0];
69
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"use-read-retry-state.js","sourceRoot":"","sources":["../../src/react/use-read-retry-state.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { hashKey, type QueryKey } from '@tanstack/react-query';\n\n/** The parts of a read's result the retry state is decided from. */\nexport interface ReadRetrySource<TError = Error> {\n error: TError | null | undefined;\n isFetching: boolean;\n isLoading: boolean;\n /** A fetch waiting for the network counts as still running. */\n isPaused?: boolean;\n}\n\n/** A read's failure as its surface shows it, held on screen while a retry of it runs. */\nexport interface ReadRetryState<TError = Error> {\n /** The read's failure: its current one, or the last one while a retry of it is running. */\n error: TError | null;\n /** A retry of the failed read is running. */\n isRetrying: boolean;\n /** The read has not answered yet and is not a retry of a failure. */\n isLoading: boolean;\n}\n\ninterface HeldFailure<TError> {\n error: TError;\n}\n\n/**\n * One failure is its name, message, and `code`, not its object: a composite source that builds its\n * error in render hands back a new object for the same failure every render, and holding each one\n * as new would set state on every render without end.\n */\nfunction sameFailure(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false;\n const x = a as { name?: unknown; message?: unknown; code?: unknown };\n const y = b as { name?: unknown; message?: unknown; code?: unknown };\n return x.name === y.name && x.message === y.message && x.code === y.code;\n}\n\n/** One read a keyed retry state follows: its result and its identity. */\nexport interface ReadRetryEntry<TError = Error> {\n source: ReadRetrySource<TError>;\n queryKey: QueryKey;\n}\n\n/** The failure a read holds next, given what it held: its live failure, or the held one while it runs. */\nfunction nextHeldFailure<TError>(\n held: HeldFailure<TError> | undefined,\n source: ReadRetrySource<TError>,\n): HeldFailure<TError> | undefined {\n const live = source.error ?? null;\n if (live !== null)\n return held !== undefined && sameFailure(held.error, live) ? held : { error: live };\n const running = source.isFetching || source.isPaused === true;\n return running ? held : undefined;\n}\n\nfunction toRetryState<TError>(\n source: ReadRetrySource<TError>,\n held: HeldFailure<TError> | undefined,\n): ReadRetryState<TError> {\n const error = source.error ?? held?.error ?? null;\n return {\n error,\n isRetrying: error !== null && (source.isFetching || source.isPaused === true),\n isLoading: error === null && source.isLoading,\n };\n}\n\n/**\n * The failure and retry state of each of several reads, in entry order — the keyed form of\n * `useReadRetryState` for a set whose size changes between renders (a `useQueries` list, a batch\n * of per-id reads). Each read's failure is held under its own `queryKey`, so one read's retry\n * never shows another's failure, and a read that leaves the set drops what it held.\n */\nexport function useReadRetryStates<TError = Error>(\n entries: readonly ReadRetryEntry<TError>[],\n): ReadRetryState<TError>[] {\n const [held, setHeld] = useState<Readonly<Record<string, HeldFailure<TError>>>>({});\n\n const next: Record<string, HeldFailure<TError>> = {};\n const states = entries.map(({ source, queryKey }) => {\n const identity = hashKey(queryKey);\n const failure = nextHeldFailure(held[identity], source);\n if (failure !== undefined) next[identity] = failure;\n return toRetryState(source, failure);\n });\n // Render-phase adjustment: the held failures follow the reads without an effect's extra render.\n if (!sameHeld(held, next)) setHeld(next);\n return states;\n}\n\nfunction sameHeld<TError>(\n a: Readonly<Record<string, HeldFailure<TError>>>,\n b: Readonly<Record<string, HeldFailure<TError>>>,\n): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);\n}\n\n/**\n * The failure and retry state of one read. TanStack Query clears the `error` of a query that never\n * succeeded and puts it back to `pending` the moment a refetch of it starts, so a retry state built\n * from `isFetching && error` is never true for a failed first read, and its failure panel turns into\n * a loading state under the retry the person pressed. This holds the read's last failure until the\n * retry settles — an answer clears it, a new failure replaces it — and reports the retry as running\n * meanwhile. The failure belongs to `queryKey`: a read under another key never shows it.\n */\nexport function useReadRetryState<TError = Error>(\n source: ReadRetrySource<TError>,\n queryKey: QueryKey,\n): ReadRetryState<TError> {\n return useReadRetryStates([{ source, queryKey }])[0]!;\n}\n"]}
1
+ {"version":3,"file":"use-read-retry-state.js","sourceRoot":"","sources":["../../src/react/use-read-retry-state.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useState } from 'react';\nimport { hashKey, type QueryKey } from '@tanstack/react-query';\n\nexport interface ReadRetrySource<TError = Error> {\n error: TError | null | undefined;\n isFetching: boolean;\n isLoading: boolean;\n isPaused?: boolean;\n}\n\nexport interface ReadRetryState<TError = Error> {\n error: TError | null;\n isRetrying: boolean;\n isLoading: boolean;\n}\n\ninterface HeldFailure<TError> {\n error: TError;\n}\n\n/** A composite source builds a new error object every render, so a failure is compared by name, message, and `code`. */\nfunction sameFailure(a: unknown, b: unknown): boolean {\n if (a === b) return true;\n if (typeof a !== 'object' || a === null || typeof b !== 'object' || b === null) return false;\n const x = a as { name?: unknown; message?: unknown; code?: unknown };\n const y = b as { name?: unknown; message?: unknown; code?: unknown };\n return x.name === y.name && x.message === y.message && x.code === y.code;\n}\n\nexport interface ReadRetryEntry<TError = Error> {\n source: ReadRetrySource<TError>;\n queryKey: QueryKey;\n}\n\nfunction nextHeldFailure<TError>(\n held: HeldFailure<TError> | undefined,\n source: ReadRetrySource<TError>,\n): HeldFailure<TError> | undefined {\n const live = source.error ?? null;\n if (live !== null)\n return held !== undefined && sameFailure(held.error, live) ? held : { error: live };\n const running = source.isFetching || source.isPaused === true;\n return running ? held : undefined;\n}\n\nfunction toRetryState<TError>(\n source: ReadRetrySource<TError>,\n held: HeldFailure<TError> | undefined,\n): ReadRetryState<TError> {\n const error = source.error ?? held?.error ?? null;\n return {\n error,\n isRetrying: error !== null && (source.isFetching || source.isPaused === true),\n isLoading: error === null && source.isLoading,\n };\n}\n\nexport function useReadRetryStates<TError = Error>(\n entries: readonly ReadRetryEntry<TError>[],\n): ReadRetryState<TError>[] {\n const [held, setHeld] = useState<Readonly<Record<string, HeldFailure<TError>>>>({});\n\n const next: Record<string, HeldFailure<TError>> = {};\n const states = entries.map(({ source, queryKey }) => {\n const identity = hashKey(queryKey);\n const failure = nextHeldFailure(held[identity], source);\n if (failure !== undefined) next[identity] = failure;\n return toRetryState(source, failure);\n });\n if (!sameHeld(held, next)) setHeld(next);\n return states;\n}\n\nfunction sameHeld<TError>(\n a: Readonly<Record<string, HeldFailure<TError>>>,\n b: Readonly<Record<string, HeldFailure<TError>>>,\n): boolean {\n const keys = Object.keys(a);\n return keys.length === Object.keys(b).length && keys.every((key) => a[key] === b[key]);\n}\n\n/** TanStack clears a never-succeeded query's `error` as its refetch starts, so the failure is held until the retry settles. */\nexport function useReadRetryState<TError = Error>(\n source: ReadRetrySource<TError>,\n queryKey: QueryKey,\n): ReadRetryState<TError> {\n return useReadRetryStates([{ source, queryKey }])[0]!;\n}\n"]}
@@ -1,10 +1,4 @@
1
- /** The fewest characters, counted on the normalized text, that `useFirestoreSearch` searches. */
2
1
  export declare const FIRESTORE_SEARCH_MIN_LENGTH = 3;
3
- /**
4
- * The text `useFirestoreSearch` reads for a typed text: lowercased, surrounding whitespace dropped.
5
- * Two typed texts with the same normalized text are the same search.
6
- */
7
2
  export declare function normalizeSearchText(text: string): string;
8
- /** Whether `useFirestoreSearch` searches this typed text (its normalized length reaches the minimum). */
9
3
  export declare function isSearchableText(text: string): boolean;
10
4
  //# sourceMappingURL=rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/search/rule.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,yGAAyG;AACzG,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
1
+ {"version":3,"file":"rule.d.ts","sourceRoot":"","sources":["../../src/search/rule.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,2BAA2B,IAAI,CAAC;AAE7C,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEtD"}
@@ -1,13 +1,7 @@
1
- /** The fewest characters, counted on the normalized text, that `useFirestoreSearch` searches. */
2
1
  export const FIRESTORE_SEARCH_MIN_LENGTH = 3;
3
- /**
4
- * The text `useFirestoreSearch` reads for a typed text: lowercased, surrounding whitespace dropped.
5
- * Two typed texts with the same normalized text are the same search.
6
- */
7
2
  export function normalizeSearchText(text) {
8
3
  return text.toLowerCase().trim();
9
4
  }
10
- /** Whether `useFirestoreSearch` searches this typed text (its normalized length reaches the minimum). */
11
5
  export function isSearchableText(text) {
12
6
  return normalizeSearchText(text).length >= FIRESTORE_SEARCH_MIN_LENGTH;
13
7
  }
@@ -1 +1 @@
1
- {"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/search/rule.ts"],"names":[],"mappings":"AAAA,iGAAiG;AACjG,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,2BAA2B,CAAC;AACzE,CAAC","sourcesContent":["/** The fewest characters, counted on the normalized text, that `useFirestoreSearch` searches. */\nexport const FIRESTORE_SEARCH_MIN_LENGTH = 3;\n\n/**\n * The text `useFirestoreSearch` reads for a typed text: lowercased, surrounding whitespace dropped.\n * Two typed texts with the same normalized text are the same search.\n */\nexport function normalizeSearchText(text: string): string {\n return text.toLowerCase().trim();\n}\n\n/** Whether `useFirestoreSearch` searches this typed text (its normalized length reaches the minimum). */\nexport function isSearchableText(text: string): boolean {\n return normalizeSearchText(text).length >= FIRESTORE_SEARCH_MIN_LENGTH;\n}\n"]}
1
+ {"version":3,"file":"rule.js","sourceRoot":"","sources":["../../src/search/rule.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC;AAE7C,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,OAAO,IAAI,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,OAAO,mBAAmB,CAAC,IAAI,CAAC,CAAC,MAAM,IAAI,2BAA2B,CAAC;AACzE,CAAC","sourcesContent":["export const FIRESTORE_SEARCH_MIN_LENGTH = 3;\n\nexport function normalizeSearchText(text: string): string {\n return text.toLowerCase().trim();\n}\n\nexport function isSearchableText(text: string): boolean {\n return normalizeSearchText(text).length >= FIRESTORE_SEARCH_MIN_LENGTH;\n}\n"]}
@@ -1,24 +1,12 @@
1
- /**
2
- * Equality filter applied before the prefix range in a Firestore search.
3
- * Each becomes a `where(field, '==', value)` constraint, ordered ahead of the
4
- * search field. The composite index must list these equality fields (ASC)
5
- * before the search field (ASC).
6
- */
1
+ /** The composite index must list these equality fields (ASC) before the search field (ASC). */
7
2
  export interface SearchEqualityFilter {
8
3
  field: string;
9
4
  value: unknown;
10
5
  }
11
- /**
12
- * Configuration for a Firestore search query
13
- */
14
6
  export interface FirestoreSearchConfig {
15
- /** Firestore collection path to search */
16
7
  collectionPath: string;
17
- /** Field name to search on (must be indexed and lowercase) */
18
8
  searchField: string;
19
- /** Maximum number of results to return */
20
9
  limit: number;
21
- /** Optional equality filters applied before the prefix range. */
22
10
  equalityFilters?: SearchEqualityFilter[];
23
11
  }
24
12
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,0CAA0C;IAC1C,cAAc,EAAE,MAAM,CAAC;IACvB,8DAA8D;IAC9D,WAAW,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,iEAAiE;IACjE,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAC1C"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"AAAA,+FAA+F;AAC/F,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,qBAAqB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,oBAAoB,EAAE,CAAC;CAC1C"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"","sourcesContent":["/**\n * Equality filter applied before the prefix range in a Firestore search.\n * Each becomes a `where(field, '==', value)` constraint, ordered ahead of the\n * search field. The composite index must list these equality fields (ASC)\n * before the search field (ASC).\n */\nexport interface SearchEqualityFilter {\n field: string;\n value: unknown;\n}\n\n/**\n * Configuration for a Firestore search query\n */\nexport interface FirestoreSearchConfig {\n /** Firestore collection path to search */\n collectionPath: string;\n /** Field name to search on (must be indexed and lowercase) */\n searchField: string;\n /** Maximum number of results to return */\n limit: number;\n /** Optional equality filters applied before the prefix range. */\n equalityFilters?: SearchEqualityFilter[];\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/search/types.ts"],"names":[],"mappings":"","sourcesContent":["/** The composite index must list these equality fields (ASC) before the search field (ASC). */\nexport interface SearchEqualityFilter {\n field: string;\n value: unknown;\n}\n\nexport interface FirestoreSearchConfig {\n collectionPath: string;\n searchField: string;\n limit: number;\n equalityFilters?: SearchEqualityFilter[];\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/query-core",
3
- "version": "0.14.22",
3
+ "version": "0.14.24",
4
4
  "description": "Shared TanStack Query (React Query) client defaults, query key helpers, and Firestore integration hooks for TTT Productions apps",
5
5
  "repository": {
6
6
  "type": "git",
@@ -40,7 +40,7 @@
40
40
  "prepublishOnly": "npm run clean && npm run build"
41
41
  },
42
42
  "peerDependencies": {
43
- "@tanstack/react-query": ">=5.0.0",
43
+ "@tanstack/react-query": ">=5.90.0",
44
44
  "firebase": ">=12.0.0",
45
45
  "react": ">=19.0.0",
46
46
  "react-dom": ">=19.0.0"
@@ -60,10 +60,10 @@
60
60
  }
61
61
  },
62
62
  "dependencies": {
63
- "@ttt-productions/firebase-helpers": "^0.12.13"
63
+ "@ttt-productions/firebase-helpers": "^0.12.16"
64
64
  },
65
65
  "devDependencies": {
66
- "@tanstack/react-query": "^5.0.0",
66
+ "@tanstack/react-query": "^5.90.0",
67
67
  "@types/react": "^19.0.0",
68
68
  "@types/react-dom": "^19.0.0",
69
69
  "firebase": "^12.14.0",