@ttt-productions/query-core 0.14.24 → 0.14.26

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 (34) hide show
  1. package/dist/react/callables/create-callables.d.ts +3 -4
  2. package/dist/react/callables/create-callables.d.ts.map +1 -1
  3. package/dist/react/callables/create-callables.js.map +1 -1
  4. package/dist/react/firestore/stable-inputs.d.ts +2 -0
  5. package/dist/react/firestore/stable-inputs.d.ts.map +1 -0
  6. package/dist/react/firestore/stable-inputs.js +11 -0
  7. package/dist/react/firestore/stable-inputs.js.map +1 -0
  8. package/dist/react/firestore/use-firestore-collection.d.ts.map +1 -1
  9. package/dist/react/firestore/use-firestore-collection.js +12 -8
  10. package/dist/react/firestore/use-firestore-collection.js.map +1 -1
  11. package/dist/react/firestore/use-firestore-doc.d.ts.map +1 -1
  12. package/dist/react/firestore/use-firestore-doc.js +10 -7
  13. package/dist/react/firestore/use-firestore-doc.js.map +1 -1
  14. package/dist/react/firestore/use-firestore-live-infinite.d.ts.map +1 -1
  15. package/dist/react/firestore/use-firestore-live-infinite.js +19 -5
  16. package/dist/react/firestore/use-firestore-live-infinite.js.map +1 -1
  17. package/dist/react/firestore/use-firestore-mutations.d.ts +6 -5
  18. package/dist/react/firestore/use-firestore-mutations.d.ts.map +1 -1
  19. package/dist/react/firestore/use-firestore-mutations.js.map +1 -1
  20. package/dist/react/firestore/use-firestore-paginated.d.ts.map +1 -1
  21. package/dist/react/firestore/use-firestore-paginated.js +8 -9
  22. package/dist/react/firestore/use-firestore-paginated.js.map +1 -1
  23. package/dist/react/firestore/useBatchFirestoreDocs.d.ts +2 -2
  24. package/dist/react/firestore/useBatchFirestoreDocs.d.ts.map +1 -1
  25. package/dist/react/firestore/useBatchFirestoreDocs.js +1 -0
  26. package/dist/react/firestore/useBatchFirestoreDocs.js.map +1 -1
  27. package/dist/react/index.d.ts +1 -1
  28. package/dist/react/index.d.ts.map +1 -1
  29. package/dist/react/index.js.map +1 -1
  30. package/dist/react/session-mutation.d.ts +17 -2
  31. package/dist/react/session-mutation.d.ts.map +1 -1
  32. package/dist/react/session-mutation.js +38 -13
  33. package/dist/react/session-mutation.js.map +1 -1
  34. package/package.json +2 -2
@@ -1,7 +1,6 @@
1
- import type { UseMutationResult } from '@tanstack/react-query';
2
1
  import type { ExpectedCallableAnswerCode } from '@ttt-productions/firebase-helpers';
3
2
  import { type FunctionsProvider } from '@ttt-productions/firebase-helpers/client';
4
- import { type SessionMutationOptions } from '../session-mutation.js';
3
+ import { type SessionMutationOptions, type SessionMutationResult } from '../session-mutation.js';
5
4
  export interface CallableErrorRouting {
6
5
  showErrorToast: boolean;
7
6
  answeredRefusals: readonly ExpectedCallableAnswerCode[];
@@ -28,10 +27,10 @@ export type ResumableOutcome<TResult> = TResult & {
28
27
  interruption: Error | null;
29
28
  };
30
29
  export interface Callables {
31
- createCallableHook<TInput, TResult>(functionName: string, declaration?: CallableDeclaration): <TOnMutateResult = unknown>(options?: CallableMutationOptions<TInput, TResult, TOnMutateResult>) => UseMutationResult<TResult, Error, TInput, TOnMutateResult>;
30
+ createCallableHook<TInput, TResult>(functionName: string, declaration?: CallableDeclaration): <TOnMutateResult = unknown>(options?: CallableMutationOptions<TInput, TResult, TOnMutateResult>) => SessionMutationResult<TResult, Error, TInput, TOnMutateResult>;
32
31
  createResumableCallableHook<TInput, TResult extends {
33
32
  complete: boolean;
34
- }>(functionName: string, merge: (earlier: TResult, later: TResult) => TResult, declaration?: CallableDeclaration): <TOnMutateResult = unknown>(options?: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult>) => UseMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>;
33
+ }>(functionName: string, merge: (earlier: TResult, later: TResult) => TResult, declaration?: CallableDeclaration): <TOnMutateResult = unknown>(options?: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult>) => SessionMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>;
35
34
  createCallableReader<TInput, TResult>(functionName: string, declaration?: CallableDeclaration): () => (input: TInput) => Promise<TResult>;
36
35
  createCallableInvoker<TInput, TResult>(functionName: string, declaration?: CallableDeclaration): () => (input: TInput) => Promise<TResult>;
37
36
  }
@@ -1 +1 @@
1
- {"version":3,"file":"create-callables.d.ts","sourceRoot":"","sources":["../../../src/react/callables/create-callables.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-callables.d.ts","sourceRoot":"","sources":["../../../src/react/callables/create-callables.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"create-callables.js","sourceRoot":"","sources":["../../../src/react/callables/create-callables.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { UseMutationResult } from '@tanstack/react-query';\nimport type { ExpectedCallableAnswerCode } from '@ttt-productions/firebase-helpers';\nimport {\n callCallable,\n isRecoveredFallbackReport,\n type FunctionsProvider,\n} from '@ttt-productions/firebase-helpers/client';\nimport {\n useMutationSessionCapture,\n useSessionMutation,\n type MutationSession,\n type SessionMutationOptions,\n} from '../session-mutation.js';\n\nexport interface CallableErrorRouting {\n showErrorToast: boolean;\n answeredRefusals: readonly ExpectedCallableAnswerCode[];\n isAnswerSurfacedByCaller?: (error: unknown) => boolean;\n}\n\nexport type CallableCaptureContext = Record<string, unknown>;\n\nexport interface CallablePolicy {\n getFunctions: FunctionsProvider;\n timeoutMs: number;\n resolveLimitedUseAppCheck: (requested: boolean) => boolean;\n captureFault: (error: unknown, context: CallableCaptureContext) => void;\n captureRecoveredFallback: (error: unknown, context: CallableCaptureContext) => void;\n onActionError: (error: unknown, routing: CallableErrorRouting) => void;\n}\n\nexport interface CallableDeclaration {\n limitedUseAppCheck?: true;\n}\n\ninterface CallableTransportOptions extends Partial<CallableErrorRouting> {\n captureFaults?: boolean;\n}\n\nexport type CallableMutationOptions<TInput, TResult, TOnMutateResult = unknown> = Omit<\n SessionMutationOptions<TResult, Error, TInput, TOnMutateResult>,\n 'mutationFn' | 'retry'\n> &\n Pick<\n CallableTransportOptions,\n 'showErrorToast' | 'answeredRefusals' | 'isAnswerSurfacedByCaller' | 'captureFaults'\n >;\n\nexport const MAX_RESUMABLE_CALLS = 12;\n\nexport type ResumableOutcome<TResult> = TResult & { interruption: Error | null };\n\nexport interface Callables {\n createCallableHook<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): <TOnMutateResult = unknown>(\n options?: CallableMutationOptions<TInput, TResult, TOnMutateResult>,\n ) => UseMutationResult<TResult, Error, TInput, TOnMutateResult>;\n createResumableCallableHook<TInput, TResult extends { complete: boolean }>(\n functionName: string,\n merge: (earlier: TResult, later: TResult) => TResult,\n declaration?: CallableDeclaration,\n ): <TOnMutateResult = unknown>(\n options?: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult>,\n ) => UseMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>;\n createCallableReader<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): () => (input: TInput) => Promise<TResult>;\n createCallableInvoker<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): () => (input: TInput) => Promise<TResult>;\n}\n\ntype CallableTransport = <TInput, TResult>(\n input: TInput,\n session: MutationSession,\n) => Promise<TResult>;\n\nexport function createCallables(policy: CallablePolicy): Callables {\n function useCallableTransport(\n functionName: string,\n declaration: CallableDeclaration,\n options: CallableTransportOptions,\n ): CallableTransport {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const limitedUseAppCheck = policy.resolveLimitedUseAppCheck(\n declaration.limitedUseAppCheck === true,\n );\n\n return useCallback(\n <TInput, TResult>(input: TInput, session: MutationSession) =>\n callCallable<TInput, TResult>(\n policy.getFunctions,\n functionName,\n input,\n {\n captureException: (error, context) => {\n if (optionsRef.current.captureFaults !== false) policy.captureFault(error, context);\n else if (isRecoveredFallbackReport(context))\n policy.captureRecoveredFallback(error, context);\n },\n onError: (error) => {\n if (!session.isCurrent()) return;\n const {\n showErrorToast = true,\n answeredRefusals = [],\n isAnswerSurfacedByCaller,\n } = optionsRef.current;\n policy.onActionError(error, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n });\n },\n },\n { timeoutMs: policy.timeoutMs, limitedUseAppCheck },\n ),\n [functionName, limitedUseAppCheck],\n );\n }\n\n function useSessionBoundCall<TInput, TResult>(\n call: CallableTransport,\n ): (input: TInput) => Promise<TResult> {\n const captureSession = useMutationSessionCapture();\n return useMemo(\n () => (input: TInput) => call<TInput, TResult>(input, captureSession()),\n [call, captureSession],\n );\n }\n\n return {\n createCallableHook<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallable<TOnMutateResult = unknown>(\n options: CallableMutationOptions<TInput, TResult, TOnMutateResult> = {},\n ): UseMutationResult<TResult, Error, TInput, TOnMutateResult> {\n const {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n ...mutationOptions\n } = options;\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n });\n // `retry: false` comes last so nothing overrides it: a deadline expiry is an unknown outcome,\n // and a retry after a committed first attempt writes twice.\n return useSessionMutation<TResult, Error, TInput, TOnMutateResult>({\n ...mutationOptions,\n retry: false,\n mutationFn: (input, { session }) => call<TInput, TResult>(input, session),\n });\n };\n },\n\n createResumableCallableHook<TInput, TResult extends { complete: boolean }>(\n functionName: string,\n merge: (earlier: TResult, later: TResult) => TResult,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedResumableCallable<TOnMutateResult = unknown>(\n options: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult> = {},\n ): UseMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult> {\n const {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n ...mutationOptions\n } = options;\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n });\n return useSessionMutation<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>({\n ...mutationOptions,\n retry: false,\n mutationFn: async (input, { session }): Promise<ResumableOutcome<TResult>> => {\n let progress = await call<TInput, TResult>(input, session);\n for (let calls = 1; !progress.complete && calls < MAX_RESUMABLE_CALLS; calls += 1) {\n session.assertCurrent();\n let later: TResult;\n try {\n later = await call<TInput, TResult>(input, session);\n } catch (error) {\n const interruption = error instanceof Error ? error : new Error(String(error));\n return { ...progress, complete: false, interruption };\n }\n progress = merge(progress, later);\n }\n return { ...progress, interruption: null };\n },\n });\n };\n },\n\n createCallableReader<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallableReader(): (input: TInput) => Promise<TResult> {\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast: false,\n captureFaults: false,\n });\n return useSessionBoundCall<TInput, TResult>(call);\n };\n },\n\n createCallableInvoker<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallableInvoker(): (input: TInput) => Promise<TResult> {\n const call = useCallableTransport(functionName, declaration, {});\n return useSessionBoundCall<TInput, TResult>(call);\n };\n },\n };\n}\n"]}
1
+ {"version":3,"file":"create-callables.js","sourceRoot":"","sources":["../../../src/react/callables/create-callables.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport { useCallback, useMemo, useRef } from 'react';\nimport type { ExpectedCallableAnswerCode } from '@ttt-productions/firebase-helpers';\nimport {\n callCallable,\n isRecoveredFallbackReport,\n type FunctionsProvider,\n} from '@ttt-productions/firebase-helpers/client';\nimport {\n useMutationSessionCapture,\n useSessionMutation,\n type MutationSession,\n type SessionMutationOptions,\n type SessionMutationResult,\n} from '../session-mutation.js';\n\nexport interface CallableErrorRouting {\n showErrorToast: boolean;\n answeredRefusals: readonly ExpectedCallableAnswerCode[];\n isAnswerSurfacedByCaller?: (error: unknown) => boolean;\n}\n\nexport type CallableCaptureContext = Record<string, unknown>;\n\nexport interface CallablePolicy {\n getFunctions: FunctionsProvider;\n timeoutMs: number;\n resolveLimitedUseAppCheck: (requested: boolean) => boolean;\n captureFault: (error: unknown, context: CallableCaptureContext) => void;\n captureRecoveredFallback: (error: unknown, context: CallableCaptureContext) => void;\n onActionError: (error: unknown, routing: CallableErrorRouting) => void;\n}\n\nexport interface CallableDeclaration {\n limitedUseAppCheck?: true;\n}\n\ninterface CallableTransportOptions extends Partial<CallableErrorRouting> {\n captureFaults?: boolean;\n}\n\nexport type CallableMutationOptions<TInput, TResult, TOnMutateResult = unknown> = Omit<\n SessionMutationOptions<TResult, Error, TInput, TOnMutateResult>,\n 'mutationFn' | 'retry'\n> &\n Pick<\n CallableTransportOptions,\n 'showErrorToast' | 'answeredRefusals' | 'isAnswerSurfacedByCaller' | 'captureFaults'\n >;\n\nexport const MAX_RESUMABLE_CALLS = 12;\n\nexport type ResumableOutcome<TResult> = TResult & { interruption: Error | null };\n\nexport interface Callables {\n createCallableHook<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): <TOnMutateResult = unknown>(\n options?: CallableMutationOptions<TInput, TResult, TOnMutateResult>,\n ) => SessionMutationResult<TResult, Error, TInput, TOnMutateResult>;\n createResumableCallableHook<TInput, TResult extends { complete: boolean }>(\n functionName: string,\n merge: (earlier: TResult, later: TResult) => TResult,\n declaration?: CallableDeclaration,\n ): <TOnMutateResult = unknown>(\n options?: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult>,\n ) => SessionMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>;\n createCallableReader<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): () => (input: TInput) => Promise<TResult>;\n createCallableInvoker<TInput, TResult>(\n functionName: string,\n declaration?: CallableDeclaration,\n ): () => (input: TInput) => Promise<TResult>;\n}\n\ntype CallableTransport = <TInput, TResult>(\n input: TInput,\n session: MutationSession,\n) => Promise<TResult>;\n\nexport function createCallables(policy: CallablePolicy): Callables {\n function useCallableTransport(\n functionName: string,\n declaration: CallableDeclaration,\n options: CallableTransportOptions,\n ): CallableTransport {\n const optionsRef = useRef(options);\n optionsRef.current = options;\n const limitedUseAppCheck = policy.resolveLimitedUseAppCheck(\n declaration.limitedUseAppCheck === true,\n );\n\n return useCallback(\n <TInput, TResult>(input: TInput, session: MutationSession) =>\n callCallable<TInput, TResult>(\n policy.getFunctions,\n functionName,\n input,\n {\n captureException: (error, context) => {\n if (optionsRef.current.captureFaults !== false) policy.captureFault(error, context);\n else if (isRecoveredFallbackReport(context))\n policy.captureRecoveredFallback(error, context);\n },\n onError: (error) => {\n if (!session.isCurrent()) return;\n const {\n showErrorToast = true,\n answeredRefusals = [],\n isAnswerSurfacedByCaller,\n } = optionsRef.current;\n policy.onActionError(error, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n });\n },\n },\n { timeoutMs: policy.timeoutMs, limitedUseAppCheck },\n ),\n [functionName, limitedUseAppCheck],\n );\n }\n\n function useSessionBoundCall<TInput, TResult>(\n call: CallableTransport,\n ): (input: TInput) => Promise<TResult> {\n const captureSession = useMutationSessionCapture();\n return useMemo(\n () => (input: TInput) => call<TInput, TResult>(input, captureSession()),\n [call, captureSession],\n );\n }\n\n return {\n createCallableHook<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallable<TOnMutateResult = unknown>(\n options: CallableMutationOptions<TInput, TResult, TOnMutateResult> = {},\n ): SessionMutationResult<TResult, Error, TInput, TOnMutateResult> {\n const {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n ...mutationOptions\n } = options;\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n });\n // `retry: false` comes last so nothing overrides it: a deadline expiry is an unknown outcome,\n // and a retry after a committed first attempt writes twice.\n return useSessionMutation<TResult, Error, TInput, TOnMutateResult>({\n ...mutationOptions,\n retry: false,\n mutationFn: (input, { session }) => call<TInput, TResult>(input, session),\n });\n };\n },\n\n createResumableCallableHook<TInput, TResult extends { complete: boolean }>(\n functionName: string,\n merge: (earlier: TResult, later: TResult) => TResult,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedResumableCallable<TOnMutateResult = unknown>(\n options: CallableMutationOptions<TInput, ResumableOutcome<TResult>, TOnMutateResult> = {},\n ): SessionMutationResult<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult> {\n const {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n ...mutationOptions\n } = options;\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast,\n answeredRefusals,\n isAnswerSurfacedByCaller,\n captureFaults,\n });\n return useSessionMutation<ResumableOutcome<TResult>, Error, TInput, TOnMutateResult>({\n ...mutationOptions,\n retry: false,\n mutationFn: async (input, { session }): Promise<ResumableOutcome<TResult>> => {\n let progress = await call<TInput, TResult>(input, session);\n for (let calls = 1; !progress.complete && calls < MAX_RESUMABLE_CALLS; calls += 1) {\n session.assertCurrent();\n let later: TResult;\n try {\n later = await call<TInput, TResult>(input, session);\n } catch (error) {\n const interruption = error instanceof Error ? error : new Error(String(error));\n return { ...progress, complete: false, interruption };\n }\n progress = merge(progress, later);\n }\n return { ...progress, interruption: null };\n },\n });\n };\n },\n\n createCallableReader<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallableReader(): (input: TInput) => Promise<TResult> {\n const call = useCallableTransport(functionName, declaration, {\n showErrorToast: false,\n captureFaults: false,\n });\n return useSessionBoundCall<TInput, TResult>(call);\n };\n },\n\n createCallableInvoker<TInput, TResult>(\n functionName: string,\n declaration: CallableDeclaration = {},\n ) {\n return function useNamedCallableInvoker(): (input: TInput) => Promise<TResult> {\n const call = useCallableTransport(functionName, declaration, {});\n return useSessionBoundCall<TInput, TResult>(call);\n };\n },\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare function useSerializedIdentity<T>(value: T, serialized: string): T;
2
+ //# sourceMappingURL=stable-inputs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-inputs.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/stable-inputs.ts"],"names":[],"mappings":"AAIA,wBAAgB,qBAAqB,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,CAAC,CAOxE"}
@@ -0,0 +1,11 @@
1
+ 'use client';
2
+ import { useState } from 'react';
3
+ export function useSerializedIdentity(value, serialized) {
4
+ const [held, setHeld] = useState({ serialized, value });
5
+ if (held.serialized !== serialized) {
6
+ setHeld({ serialized, value });
7
+ return value;
8
+ }
9
+ return held.value;
10
+ }
11
+ //# sourceMappingURL=stable-inputs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stable-inputs.js","sourceRoot":"","sources":["../../../src/react/firestore/stable-inputs.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC,MAAM,UAAU,qBAAqB,CAAI,KAAQ,EAAE,UAAkB;IACnE,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,IAAI,CAAC,UAAU,KAAK,UAAU,EAAE,CAAC;QACnC,OAAO,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC,KAAK,CAAC;AACpB,CAAC","sourcesContent":["'use client';\n\nimport { useState } from 'react';\n\nexport function useSerializedIdentity<T>(value: T, serialized: string): T {\n const [held, setHeld] = useState({ serialized, value });\n if (held.serialized !== serialized) {\n setHeld({ serialized, value });\n return value;\n }\n return held.value;\n}\n"]}
@@ -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,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"}
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;AAK/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,CA+GrF"}
@@ -1,15 +1,20 @@
1
1
  'use client';
2
- import { useEffect } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import { useQuery, useQueryClient } from '@tanstack/react-query';
4
4
  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
+ import { useSerializedIdentity } from './stable-inputs.js';
8
9
  export function useFirestoreCollection({ collectionPath, queryKey, constraints = [], enabled = true, subscribe = false, staleTime, gcTime, select, }) {
9
10
  const db = useFirestoreDb();
10
11
  const queryClient = useQueryClient();
11
12
  const constraintsMemo = JSON.stringify(constraints);
12
13
  const queryKeyMemo = JSON.stringify(queryKey);
14
+ const stableConstraints = useSerializedIdentity(constraints, constraintsMemo);
15
+ const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);
16
+ const selectRef = useRef(select);
17
+ selectRef.current = select;
13
18
  const subscription = useSubscriptionStatus(JSON.stringify([collectionPath, queryKeyMemo, constraintsMemo, enabled, subscribe]));
14
19
  const { reset: resetStatus, update: updateStatus, restarts } = subscription;
15
20
  useEffect(() => {
@@ -24,17 +29,17 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
24
29
  if (disposed)
25
30
  return;
26
31
  const collectionRef = collection(db, collectionPath);
27
- const q = constraints.length > 0 ? query(collectionRef, ...constraints) : collectionRef;
32
+ const q = stableConstraints.length > 0 ? query(collectionRef, ...stableConstraints) : collectionRef;
28
33
  currentUnsubscribe = onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => {
29
34
  attempt = 0;
30
35
  updateStatus({ error: null, restart: null });
31
36
  const items = snapshot.docs.map((docSnap) => {
32
37
  const rawData = docSnap.data();
33
38
  const dataWithId = { id: docSnap.id, ...rawData };
34
- const data = select ? select(dataWithId) : dataWithId;
39
+ const data = selectRef.current ? selectRef.current(dataWithId) : dataWithId;
35
40
  return data;
36
41
  });
37
- queryClient.setQueryData(queryKey, items);
42
+ queryClient.setQueryData(stableQueryKey, items);
38
43
  const fromCache = snapshot.metadata?.fromCache ?? false;
39
44
  updateStatus((prev) => ({
40
45
  sourceState: fromCache
@@ -55,7 +60,7 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
55
60
  }
56
61
  console.error('[useFirestoreCollection] Subscription error:', error);
57
62
  updateStatus({ error, sourceState: 'error', restart: null });
58
- queryClient.setQueryData(queryKey, undefined);
63
+ queryClient.setQueryData(stableQueryKey, undefined);
59
64
  });
60
65
  };
61
66
  start();
@@ -65,12 +70,11 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
65
70
  clearTimeout(retryTimer);
66
71
  currentUnsubscribe?.();
67
72
  };
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
69
73
  }, [
70
74
  db,
71
75
  collectionPath,
72
- queryKeyMemo,
73
- constraintsMemo,
76
+ stableQueryKey,
77
+ stableConstraints,
74
78
  enabled,
75
79
  subscribe,
76
80
  restarts,
@@ -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\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
+ {"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, useRef } 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 { useSerializedIdentity } from './stable-inputs.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 const stableConstraints = useSerializedIdentity(constraints, constraintsMemo);\n const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);\n const selectRef = useRef(select);\n selectRef.current = select;\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 =\n stableConstraints.length > 0 ? query(collectionRef, ...stableConstraints) : 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 = selectRef.current ? selectRef.current(dataWithId) : dataWithId;\n return data as WithId<T>;\n });\n queryClient.setQueryData(stableQueryKey, 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(stableQueryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n }, [\n db,\n collectionPath,\n stableQueryKey,\n stableConstraints,\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 +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,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"}
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;AAKhF,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,CA0GnF"}
@@ -1,14 +1,18 @@
1
1
  'use client';
2
- import { useEffect } from 'react';
2
+ import { useEffect, useRef } from 'react';
3
3
  import { useQuery, useQueryClient } from '@tanstack/react-query';
4
4
  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
+ import { useSerializedIdentity } from './stable-inputs.js';
8
9
  export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe = false, staleTime, gcTime, select, }) {
9
10
  const db = useFirestoreDb();
10
11
  const queryClient = useQueryClient();
11
12
  const queryKeyMemo = JSON.stringify(queryKey);
13
+ const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);
14
+ const selectRef = useRef(select);
15
+ selectRef.current = select;
12
16
  const subscription = useSubscriptionStatus(JSON.stringify([docPath, queryKeyMemo, enabled, subscribe]));
13
17
  const { reset: resetStatus, update: updateStatus, restarts } = subscription;
14
18
  useEffect(() => {
@@ -29,11 +33,11 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
29
33
  if (snapshot.exists()) {
30
34
  const rawData = snapshot.data();
31
35
  const dataWithId = { id: snapshot.id, ...rawData };
32
- const data = select ? select(dataWithId) : dataWithId;
33
- queryClient.setQueryData(queryKey, data);
36
+ const data = selectRef.current ? selectRef.current(dataWithId) : dataWithId;
37
+ queryClient.setQueryData(stableQueryKey, data);
34
38
  }
35
39
  else {
36
- queryClient.setQueryData(queryKey, null);
40
+ queryClient.setQueryData(stableQueryKey, null);
37
41
  }
38
42
  const fromCache = snapshot.metadata?.fromCache ?? false;
39
43
  updateStatus((prev) => ({
@@ -55,7 +59,7 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
55
59
  }
56
60
  console.error('[useFirestoreDoc] Subscription error:', error);
57
61
  updateStatus({ error, sourceState: 'error', restart: null });
58
- queryClient.setQueryData(queryKey, undefined);
62
+ queryClient.setQueryData(stableQueryKey, undefined);
59
63
  });
60
64
  };
61
65
  start();
@@ -65,11 +69,10 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
65
69
  clearTimeout(retryTimer);
66
70
  currentUnsubscribe?.();
67
71
  };
68
- // eslint-disable-next-line react-hooks/exhaustive-deps -- queryKey is tracked by queryKeyMemo; an inline select must not re-subscribe every render
69
72
  }, [
70
73
  db,
71
74
  docPath,
72
- queryKeyMemo,
75
+ stableQueryKey,
73
76
  enabled,
74
77
  subscribe,
75
78
  restarts,
@@ -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\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
+ {"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, useRef } 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 { useSerializedIdentity } from './stable-inputs.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 const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);\n const selectRef = useRef(select);\n selectRef.current = select;\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 = selectRef.current ? selectRef.current(dataWithId) : dataWithId;\n queryClient.setQueryData(stableQueryKey, data as WithId<T>);\n } else {\n queryClient.setQueryData(stableQueryKey, 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(stableQueryKey, undefined);\n },\n );\n };\n\n start();\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n currentUnsubscribe?.();\n };\n }, [\n db,\n docPath,\n stableQueryKey,\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 +1 @@
1
- {"version":3,"file":"use-firestore-live-infinite.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-live-infinite.ts"],"names":[],"mappings":"AAIA,OAAO,EASL,KAAK,YAAY,EAElB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAI/D,MAAM,WAAW,2BAA2B,CAAC,CAAC;IAC5C,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,oBAAoB,CAAC;IAClC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AA2BD,wBAAgB,wBAAwB,CAAC,CAAC,GAAG,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC1E,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,WAAgB,EAChB,QAAQ,EAAE,iBAAsB,EAChC,OAAc,EACd,MAAM,EACN,IAAY,GACb,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC,CAAC,CAAC,CA8PlE"}
1
+ {"version":3,"file":"use-firestore-live-infinite.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-live-infinite.ts"],"names":[],"mappings":"AAIA,OAAO,EASL,KAAK,YAAY,EAElB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,YAAY,CAAC;AAK/D,MAAM,WAAW,2BAA2B,CAAC,CAAC;IAC5C,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,oBAAoB,CAAC;IAClC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,QAAQ,EAAE,OAAO,CAAC;IAClB,eAAe,EAAE,OAAO,CAAC;IACzB,UAAU,EAAE,KAAK,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AA2BD,wBAAgB,wBAAwB,CAAC,CAAC,GAAG,YAAY,GAAG;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAAE,EAC1E,cAAc,EACd,QAAQ,EACR,YAAY,EACZ,WAAgB,EAChB,QAAQ,EAAE,iBAAsB,EAChC,OAAc,EACd,MAAM,EACN,IAAY,GACb,EAAE,4BAA4B,CAAC,CAAC,CAAC,GAAG,2BAA2B,CAAC,CAAC,CAAC,CA2QlE"}
@@ -4,6 +4,7 @@ import { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';
4
4
  import { collection, query, orderBy, limit, startAfter, endAt, getDocs, onSnapshot, } from 'firebase/firestore';
5
5
  import { useFirestoreDb } from './context.js';
6
6
  import { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';
7
+ import { useSerializedIdentity } from './stable-inputs.js';
7
8
  const MAX_PAGE_SIZE = 100;
8
9
  function freshWindow(identity) {
9
10
  return {
@@ -37,6 +38,8 @@ export function useFirestoreLiveInfinite({ collectionPath, queryKey, orderByFiel
37
38
  pageSize,
38
39
  enabled,
39
40
  ]);
41
+ const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);
42
+ const stableConstraints = useSerializedIdentity(constraints, constraintsMemo);
40
43
  const [windowState, setWindowState] = React.useState(() => freshWindow(identity));
41
44
  const windowRef = React.useRef(windowState);
42
45
  windowRef.current = windowState;
@@ -68,8 +71,8 @@ export function useFirestoreLiveInfinite({ collectionPath, queryKey, orderByFiel
68
71
  currentAnchor = anchor;
69
72
  const colRef = collection(db, collectionPath);
70
73
  const q = anchor
71
- ? query(colRef, ...constraints, orderBy(orderByField, 'desc'), endAt(anchor))
72
- : query(colRef, ...constraints, orderBy(orderByField, 'desc'), limit(pageSize + 1));
74
+ ? query(colRef, ...stableConstraints, orderBy(orderByField, 'desc'), endAt(anchor))
75
+ : query(colRef, ...stableConstraints, orderBy(orderByField, 'desc'), limit(pageSize + 1));
73
76
  let serverConfirmed = false;
74
77
  unsubscribe = onSnapshot(q, { includeMetadataChanges: true }, (snap) => {
75
78
  if (disposed)
@@ -135,7 +138,7 @@ export function useFirestoreLiveInfinite({ collectionPath, queryKey, orderByFiel
135
138
  console.error('[useFirestoreLiveInfinite] Subscription error:', error);
136
139
  if (isPermissionDeniedError(error)) {
137
140
  currentAnchor = null;
138
- queryClient.removeQueries({ queryKey: [...queryKey, 'older', identity] });
141
+ queryClient.removeQueries({ queryKey: [...stableQueryKey, 'older', identity] });
139
142
  update(() => ({ ...freshWindow(identity), sourceState: 'error', error }));
140
143
  return;
141
144
  }
@@ -149,8 +152,19 @@ export function useFirestoreLiveInfinite({ collectionPath, queryKey, orderByFiel
149
152
  clearTimeout(retryTimer);
150
153
  unsubscribe?.();
151
154
  };
152
- // eslint-disable-next-line react-hooks/exhaustive-deps -- identity carries every read input; constraints are read from the render that produced it
153
- }, [db, identity, retryNonce, toEntry, queryClient]);
155
+ }, [
156
+ db,
157
+ identity,
158
+ retryNonce,
159
+ toEntry,
160
+ queryClient,
161
+ enabled,
162
+ collectionPath,
163
+ stableConstraints,
164
+ orderByField,
165
+ pageSize,
166
+ stableQueryKey,
167
+ ]);
154
168
  const anchor = enabled ? current.anchor : null;
155
169
  const olderEnabled = anchor !== null && current.olderExists;
156
170
  const older = useInfiniteQuery({
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-live-infinite.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-live-infinite.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\nimport {\n collection,\n query,\n orderBy,\n limit,\n startAfter,\n endAt,\n getDocs,\n onSnapshot,\n type DocumentData,\n type QueryDocumentSnapshot,\n} from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport type { FirestoreSourceState } from '../../firestore/types.js';\nimport type { FirestoreLiveInfiniteOptions } from './types.js';\n\nconst MAX_PAGE_SIZE = 100;\n\nexport interface FirestoreLiveInfiniteResult<T> {\n items: T[];\n isInitialLoading: boolean;\n sourceState: FirestoreSourceState;\n error: Error | null;\n fetchOlder: () => Promise<void>;\n hasOlder: boolean;\n isFetchingOlder: boolean;\n olderError: Error | null;\n retry: () => void;\n}\n\ntype Entry<T> = { docId: string; item: T };\ntype Snap = QueryDocumentSnapshot<DocumentData>;\n\ninterface WindowState<T> {\n identity: string;\n ready: boolean;\n entries: Entry<T>[];\n anchor: Snap | null;\n olderExists: boolean;\n sourceState: FirestoreSourceState;\n error: Error | null;\n}\n\nfunction freshWindow<T>(identity: string): WindowState<T> {\n return {\n identity,\n ready: false,\n entries: [],\n anchor: null,\n olderExists: false,\n sourceState: 'connecting',\n error: null,\n };\n}\n\nexport function useFirestoreLiveInfinite<T = DocumentData & { id: string }>({\n collectionPath,\n queryKey,\n orderByField,\n constraints = [],\n pageSize: requestedPageSize = 20,\n enabled = true,\n select,\n sort = 'asc',\n}: FirestoreLiveInfiniteOptions<T>): FirestoreLiveInfiniteResult<T> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n const pageSize = Math.min(requestedPageSize, MAX_PAGE_SIZE);\n\n const selectRef = React.useRef(select);\n selectRef.current = select;\n\n const toEntry = React.useCallback((snap: Snap): Entry<T> => {\n const dataWithId: DocumentData & { id: string } = { id: snap.id, ...snap.data() };\n const item = selectRef.current ? selectRef.current(dataWithId) : (dataWithId as unknown as T);\n return { docId: snap.id, item };\n }, []);\n\n const queryKeyMemo = JSON.stringify(queryKey);\n const constraintsMemo = JSON.stringify(constraints);\n const identity = JSON.stringify([\n collectionPath,\n queryKeyMemo,\n orderByField,\n constraintsMemo,\n pageSize,\n enabled,\n ]);\n\n const [windowState, setWindowState] = React.useState<WindowState<T>>(() => freshWindow(identity));\n const windowRef = React.useRef(windowState);\n windowRef.current = windowState;\n const [retryNonce, setRetryNonce] = React.useState(0);\n\n const current: WindowState<T> =\n windowState.identity === identity ? windowState : freshWindow<T>(identity);\n\n React.useEffect(() => {\n if (!enabled) {\n setWindowState(freshWindow<T>(identity));\n return;\n }\n\n const prior = windowRef.current;\n const resumed = prior.identity === identity;\n setWindowState((prev) =>\n prev.identity === identity\n ? { ...prev, error: null, sourceState: 'connecting' }\n : freshWindow<T>(identity),\n );\n\n let disposed = false;\n let unsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let currentAnchor: Snap | null = resumed ? prior.anchor : null;\n\n const update = (fn: (prev: WindowState<T>) => WindowState<T>) => {\n if (disposed) return;\n setWindowState((prev) => (prev.identity === identity ? fn(prev) : prev));\n };\n\n const listen = (anchor: Snap | null) => {\n if (disposed) return;\n currentAnchor = anchor;\n const colRef = collection(db, collectionPath);\n const q = anchor\n ? query(colRef, ...constraints, orderBy(orderByField, 'desc'), endAt(anchor))\n : query(colRef, ...constraints, orderBy(orderByField, 'desc'), limit(pageSize + 1));\n let serverConfirmed = false;\n\n unsubscribe = onSnapshot(\n q,\n { includeMetadataChanges: true },\n (snap) => {\n if (disposed) return;\n attempt = 0;\n const docs = snap.docs as Snap[];\n const fromCache = snap.metadata?.fromCache ?? false;\n const nextSource = (prev: FirestoreSourceState): FirestoreSourceState => {\n if (!fromCache) return 'live';\n if (!serverConfirmed) return prev === 'error' ? 'connecting' : prev;\n return 'offline';\n };\n if (!fromCache) serverConfirmed = true;\n\n if (anchor) {\n update((prev) => ({\n ...prev,\n ready: true,\n entries: docs.map(toEntry),\n sourceState: nextSource(prev.sourceState),\n error: null,\n }));\n return;\n }\n\n const windowDocs = docs.slice(0, pageSize);\n if (fromCache || windowDocs.length === 0) {\n update((prev) => ({\n ...prev,\n ready: true,\n entries: windowDocs.map(toEntry),\n sourceState: nextSource(prev.sourceState),\n error: null,\n }));\n return;\n }\n\n const newAnchor = windowDocs[windowDocs.length - 1];\n update((prev) => ({\n ...prev,\n ready: true,\n entries: windowDocs.map(toEntry),\n anchor: newAnchor,\n olderExists: docs.length > pageSize,\n sourceState: 'live',\n error: null,\n }));\n unsubscribe?.();\n unsubscribe = null;\n listen(newAnchor);\n },\n (error) => {\n if (disposed) return;\n unsubscribe?.();\n unsubscribe = null;\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n update((prev) => ({ ...prev, sourceState: 'connecting' }));\n retryTimer = setTimeout(() => listen(currentAnchor), delay);\n return;\n }\n console.error('[useFirestoreLiveInfinite] Subscription error:', error);\n if (isPermissionDeniedError(error)) {\n currentAnchor = null;\n queryClient.removeQueries({ queryKey: [...queryKey, 'older', identity] });\n update(() => ({ ...freshWindow<T>(identity), sourceState: 'error', error }));\n return;\n }\n update((prev) => ({ ...prev, sourceState: 'error', error }));\n },\n );\n };\n\n listen(currentAnchor);\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n unsubscribe?.();\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps -- identity carries every read input; constraints are read from the render that produced it\n }, [db, identity, retryNonce, toEntry, queryClient]);\n\n const anchor = enabled ? current.anchor : null;\n const olderEnabled = anchor !== null && current.olderExists;\n\n const older = useInfiniteQuery({\n queryKey: [...queryKey, 'older', identity, anchor?.id ?? null],\n enabled: false,\n initialPageParam: undefined as Snap | undefined,\n queryFn: async ({ pageParam }) => {\n const cursor = pageParam ?? anchor;\n if (!cursor) {\n return { entries: [] as Entry<T>[], nextCursor: undefined as Snap | undefined };\n }\n const colRef = collection(db, collectionPath);\n const q = query(\n colRef,\n ...constraints,\n orderBy(orderByField, 'desc'),\n startAfter(cursor),\n limit(pageSize + 1),\n );\n const snap = await getDocs(q);\n const docs = snap.docs as Snap[];\n const page = docs.slice(0, pageSize);\n return {\n entries: page.map(toEntry),\n nextCursor: docs.length > pageSize ? page[page.length - 1] : undefined,\n };\n },\n getNextPageParam: (last) => last.nextCursor,\n });\n\n const {\n data: olderData,\n isFetching: olderFetching,\n isError: olderIsError,\n error: olderErr,\n hasNextPage: olderHasNext,\n fetchNextPage,\n refetch: refetchOlder,\n } = older;\n\n const olderPages = olderEnabled ? olderData?.pages : undefined;\n const hasOlder = olderEnabled && (olderPages ? Boolean(olderHasNext) : true);\n const olderError = olderEnabled && olderIsError ? olderErr : null;\n\n const fetchOlder = React.useCallback(async () => {\n if (!olderEnabled || olderFetching) return;\n if (!olderPages) {\n await refetchOlder();\n return;\n }\n if (olderHasNext) await fetchNextPage();\n }, [olderEnabled, olderFetching, olderPages, olderHasNext, refetchOlder, fetchNextPage]);\n\n const listenerFailed = enabled && current.error !== null;\n const retry = React.useCallback(() => {\n if (listenerFailed) {\n setWindowState((prev) =>\n prev.identity === identity ? { ...prev, error: null, sourceState: 'connecting' } : prev,\n );\n setRetryNonce((n) => n + 1);\n }\n if (olderError && !olderFetching) {\n if (olderPages) void fetchNextPage();\n else void refetchOlder();\n }\n }, [\n listenerFailed,\n identity,\n olderError,\n olderFetching,\n olderPages,\n fetchNextPage,\n refetchOlder,\n ]);\n\n const olderEntries = React.useMemo(\n () => (olderPages ?? []).flatMap((p) => p.entries),\n [olderPages],\n );\n\n const items = React.useMemo(() => {\n if (!enabled) return [];\n const liveIds = new Set(current.entries.map((entry) => entry.docId));\n const newestFirst = [\n ...current.entries.map((entry) => entry.item),\n ...olderEntries.filter((entry) => !liveIds.has(entry.docId)).map((entry) => entry.item),\n ];\n return sort === 'desc' ? newestFirst : newestFirst.reverse();\n }, [enabled, olderEntries, current.entries, sort]);\n\n return {\n items,\n isInitialLoading: enabled ? !current.ready && current.error === null : false,\n sourceState: current.sourceState,\n error: enabled ? current.error : null,\n fetchOlder,\n hasOlder,\n isFetchingOlder: olderEnabled && olderFetching,\n olderError,\n retry,\n };\n}\n"]}
1
+ {"version":3,"file":"use-firestore-live-infinite.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-live-infinite.ts"],"names":[],"mappings":"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","sourcesContent":["'use client';\n\nimport * as React from 'react';\nimport { useInfiniteQuery, useQueryClient } from '@tanstack/react-query';\nimport {\n collection,\n query,\n orderBy,\n limit,\n startAfter,\n endAt,\n getDocs,\n onSnapshot,\n type DocumentData,\n type QueryDocumentSnapshot,\n} from 'firebase/firestore';\nimport { useFirestoreDb } from './context.js';\nimport { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';\nimport type { FirestoreSourceState } from '../../firestore/types.js';\nimport type { FirestoreLiveInfiniteOptions } from './types.js';\nimport { useSerializedIdentity } from './stable-inputs.js';\n\nconst MAX_PAGE_SIZE = 100;\n\nexport interface FirestoreLiveInfiniteResult<T> {\n items: T[];\n isInitialLoading: boolean;\n sourceState: FirestoreSourceState;\n error: Error | null;\n fetchOlder: () => Promise<void>;\n hasOlder: boolean;\n isFetchingOlder: boolean;\n olderError: Error | null;\n retry: () => void;\n}\n\ntype Entry<T> = { docId: string; item: T };\ntype Snap = QueryDocumentSnapshot<DocumentData>;\n\ninterface WindowState<T> {\n identity: string;\n ready: boolean;\n entries: Entry<T>[];\n anchor: Snap | null;\n olderExists: boolean;\n sourceState: FirestoreSourceState;\n error: Error | null;\n}\n\nfunction freshWindow<T>(identity: string): WindowState<T> {\n return {\n identity,\n ready: false,\n entries: [],\n anchor: null,\n olderExists: false,\n sourceState: 'connecting',\n error: null,\n };\n}\n\nexport function useFirestoreLiveInfinite<T = DocumentData & { id: string }>({\n collectionPath,\n queryKey,\n orderByField,\n constraints = [],\n pageSize: requestedPageSize = 20,\n enabled = true,\n select,\n sort = 'asc',\n}: FirestoreLiveInfiniteOptions<T>): FirestoreLiveInfiniteResult<T> {\n const db = useFirestoreDb();\n const queryClient = useQueryClient();\n const pageSize = Math.min(requestedPageSize, MAX_PAGE_SIZE);\n\n const selectRef = React.useRef(select);\n selectRef.current = select;\n\n const toEntry = React.useCallback((snap: Snap): Entry<T> => {\n const dataWithId: DocumentData & { id: string } = { id: snap.id, ...snap.data() };\n const item = selectRef.current ? selectRef.current(dataWithId) : (dataWithId as unknown as T);\n return { docId: snap.id, item };\n }, []);\n\n const queryKeyMemo = JSON.stringify(queryKey);\n const constraintsMemo = JSON.stringify(constraints);\n const identity = JSON.stringify([\n collectionPath,\n queryKeyMemo,\n orderByField,\n constraintsMemo,\n pageSize,\n enabled,\n ]);\n const stableQueryKey = useSerializedIdentity(queryKey, queryKeyMemo);\n const stableConstraints = useSerializedIdentity(constraints, constraintsMemo);\n\n const [windowState, setWindowState] = React.useState<WindowState<T>>(() => freshWindow(identity));\n const windowRef = React.useRef(windowState);\n windowRef.current = windowState;\n const [retryNonce, setRetryNonce] = React.useState(0);\n\n const current: WindowState<T> =\n windowState.identity === identity ? windowState : freshWindow<T>(identity);\n\n React.useEffect(() => {\n if (!enabled) {\n setWindowState(freshWindow<T>(identity));\n return;\n }\n\n const prior = windowRef.current;\n const resumed = prior.identity === identity;\n setWindowState((prev) =>\n prev.identity === identity\n ? { ...prev, error: null, sourceState: 'connecting' }\n : freshWindow<T>(identity),\n );\n\n let disposed = false;\n let unsubscribe: (() => void) | null = null;\n let retryTimer: ReturnType<typeof setTimeout> | null = null;\n let attempt = 0;\n let currentAnchor: Snap | null = resumed ? prior.anchor : null;\n\n const update = (fn: (prev: WindowState<T>) => WindowState<T>) => {\n if (disposed) return;\n setWindowState((prev) => (prev.identity === identity ? fn(prev) : prev));\n };\n\n const listen = (anchor: Snap | null) => {\n if (disposed) return;\n currentAnchor = anchor;\n const colRef = collection(db, collectionPath);\n const q = anchor\n ? query(colRef, ...stableConstraints, orderBy(orderByField, 'desc'), endAt(anchor))\n : query(colRef, ...stableConstraints, orderBy(orderByField, 'desc'), limit(pageSize + 1));\n let serverConfirmed = false;\n\n unsubscribe = onSnapshot(\n q,\n { includeMetadataChanges: true },\n (snap) => {\n if (disposed) return;\n attempt = 0;\n const docs = snap.docs as Snap[];\n const fromCache = snap.metadata?.fromCache ?? false;\n const nextSource = (prev: FirestoreSourceState): FirestoreSourceState => {\n if (!fromCache) return 'live';\n if (!serverConfirmed) return prev === 'error' ? 'connecting' : prev;\n return 'offline';\n };\n if (!fromCache) serverConfirmed = true;\n\n if (anchor) {\n update((prev) => ({\n ...prev,\n ready: true,\n entries: docs.map(toEntry),\n sourceState: nextSource(prev.sourceState),\n error: null,\n }));\n return;\n }\n\n const windowDocs = docs.slice(0, pageSize);\n if (fromCache || windowDocs.length === 0) {\n update((prev) => ({\n ...prev,\n ready: true,\n entries: windowDocs.map(toEntry),\n sourceState: nextSource(prev.sourceState),\n error: null,\n }));\n return;\n }\n\n const newAnchor = windowDocs[windowDocs.length - 1];\n update((prev) => ({\n ...prev,\n ready: true,\n entries: windowDocs.map(toEntry),\n anchor: newAnchor,\n olderExists: docs.length > pageSize,\n sourceState: 'live',\n error: null,\n }));\n unsubscribe?.();\n unsubscribe = null;\n listen(newAnchor);\n },\n (error) => {\n if (disposed) return;\n unsubscribe?.();\n unsubscribe = null;\n if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {\n const delay = RESUBSCRIBE_DELAYS_MS[attempt];\n attempt += 1;\n update((prev) => ({ ...prev, sourceState: 'connecting' }));\n retryTimer = setTimeout(() => listen(currentAnchor), delay);\n return;\n }\n console.error('[useFirestoreLiveInfinite] Subscription error:', error);\n if (isPermissionDeniedError(error)) {\n currentAnchor = null;\n queryClient.removeQueries({ queryKey: [...stableQueryKey, 'older', identity] });\n update(() => ({ ...freshWindow<T>(identity), sourceState: 'error', error }));\n return;\n }\n update((prev) => ({ ...prev, sourceState: 'error', error }));\n },\n );\n };\n\n listen(currentAnchor);\n\n return () => {\n disposed = true;\n if (retryTimer) clearTimeout(retryTimer);\n unsubscribe?.();\n };\n }, [\n db,\n identity,\n retryNonce,\n toEntry,\n queryClient,\n enabled,\n collectionPath,\n stableConstraints,\n orderByField,\n pageSize,\n stableQueryKey,\n ]);\n\n const anchor = enabled ? current.anchor : null;\n const olderEnabled = anchor !== null && current.olderExists;\n\n const older = useInfiniteQuery({\n queryKey: [...queryKey, 'older', identity, anchor?.id ?? null],\n enabled: false,\n initialPageParam: undefined as Snap | undefined,\n queryFn: async ({ pageParam }) => {\n const cursor = pageParam ?? anchor;\n if (!cursor) {\n return { entries: [] as Entry<T>[], nextCursor: undefined as Snap | undefined };\n }\n const colRef = collection(db, collectionPath);\n const q = query(\n colRef,\n ...constraints,\n orderBy(orderByField, 'desc'),\n startAfter(cursor),\n limit(pageSize + 1),\n );\n const snap = await getDocs(q);\n const docs = snap.docs as Snap[];\n const page = docs.slice(0, pageSize);\n return {\n entries: page.map(toEntry),\n nextCursor: docs.length > pageSize ? page[page.length - 1] : undefined,\n };\n },\n getNextPageParam: (last) => last.nextCursor,\n });\n\n const {\n data: olderData,\n isFetching: olderFetching,\n isError: olderIsError,\n error: olderErr,\n hasNextPage: olderHasNext,\n fetchNextPage,\n refetch: refetchOlder,\n } = older;\n\n const olderPages = olderEnabled ? olderData?.pages : undefined;\n const hasOlder = olderEnabled && (olderPages ? Boolean(olderHasNext) : true);\n const olderError = olderEnabled && olderIsError ? olderErr : null;\n\n const fetchOlder = React.useCallback(async () => {\n if (!olderEnabled || olderFetching) return;\n if (!olderPages) {\n await refetchOlder();\n return;\n }\n if (olderHasNext) await fetchNextPage();\n }, [olderEnabled, olderFetching, olderPages, olderHasNext, refetchOlder, fetchNextPage]);\n\n const listenerFailed = enabled && current.error !== null;\n const retry = React.useCallback(() => {\n if (listenerFailed) {\n setWindowState((prev) =>\n prev.identity === identity ? { ...prev, error: null, sourceState: 'connecting' } : prev,\n );\n setRetryNonce((n) => n + 1);\n }\n if (olderError && !olderFetching) {\n if (olderPages) void fetchNextPage();\n else void refetchOlder();\n }\n }, [\n listenerFailed,\n identity,\n olderError,\n olderFetching,\n olderPages,\n fetchNextPage,\n refetchOlder,\n ]);\n\n const olderEntries = React.useMemo(\n () => (olderPages ?? []).flatMap((p) => p.entries),\n [olderPages],\n );\n\n const items = React.useMemo(() => {\n if (!enabled) return [];\n const liveIds = new Set(current.entries.map((entry) => entry.docId));\n const newestFirst = [\n ...current.entries.map((entry) => entry.item),\n ...olderEntries.filter((entry) => !liveIds.has(entry.docId)).map((entry) => entry.item),\n ];\n return sort === 'desc' ? newestFirst : newestFirst.reverse();\n }, [enabled, olderEntries, current.entries, sort]);\n\n return {\n items,\n isInitialLoading: enabled ? !current.ready && current.error === null : false,\n sourceState: current.sourceState,\n error: enabled ? current.error : null,\n fetchOlder,\n hasOlder,\n isFetchingOlder: olderEnabled && olderFetching,\n olderError,\n retry,\n };\n}\n"]}
@@ -1,17 +1,18 @@
1
- import { type QueryKey, type UseMutationResult } from '@tanstack/react-query';
1
+ import { type QueryKey } from '@tanstack/react-query';
2
2
  import { type DocumentData } from 'firebase/firestore';
3
+ import { type SessionMutationResult } from '../session-mutation.js';
3
4
  import type { FirestoreMutationOptions, FirestoreBatchOptions } from '../../firestore/types.js';
4
5
  import type { MutationOperation } from './types.js';
5
6
  interface SetResult<T> {
6
7
  id: string;
7
8
  data: T;
8
9
  }
9
- export declare function useFirestoreSet<T extends DocumentData>({ invalidateKeys, }?: Pick<FirestoreMutationOptions<T>, 'invalidateKeys'>): UseMutationResult<SetResult<T>, Error, {
10
+ export declare function useFirestoreSet<T extends DocumentData>({ invalidateKeys, }?: Pick<FirestoreMutationOptions<T>, 'invalidateKeys'>): SessionMutationResult<SetResult<T>, Error, {
10
11
  docPath: string;
11
12
  data: T;
12
13
  merge?: boolean;
13
14
  }>;
14
- export declare function useFirestoreUpdate<T extends DocumentData>({ invalidateKeys, optimistic, }?: FirestoreMutationOptions<T>): UseMutationResult<Partial<T>, Error, {
15
+ export declare function useFirestoreUpdate<T extends DocumentData>({ invalidateKeys, optimistic, }?: FirestoreMutationOptions<T>): SessionMutationResult<Partial<T>, Error, {
15
16
  docPath: string;
16
17
  data: Partial<T>;
17
18
  }, {
@@ -23,7 +24,7 @@ export declare function useFirestoreDelete<T = unknown>({ invalidateKeys, optimi
23
24
  queryKey: QueryKey;
24
25
  updater: (oldData: T | undefined, docPath: string) => T;
25
26
  };
26
- }): UseMutationResult<string, Error, {
27
+ }): SessionMutationResult<string, Error, {
27
28
  docPath: string;
28
29
  }, {
29
30
  previousData: T | undefined;
@@ -32,7 +33,7 @@ interface BatchResult {
32
33
  committed: number;
33
34
  batches: number;
34
35
  }
35
- export declare function useFirestoreBatch({ invalidateKeys, batchSize, }?: FirestoreBatchOptions): UseMutationResult<BatchResult, Error, {
36
+ export declare function useFirestoreBatch({ invalidateKeys, batchSize, }?: FirestoreBatchOptions): SessionMutationResult<BatchResult, Error, {
36
37
  operations: MutationOperation[];
37
38
  }>;
38
39
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"use-firestore-mutations.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-mutations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,KAAK,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC9F,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,UAAU,SAAS,CAAC,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;CACT;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,EACtD,cAAmB,GACpB,GAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAM,GAAG,iBAAiB,CAC7E,SAAS,CAAC,CAAC,CAAC,EACZ,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9C,CAwBA;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,YAAY,EAAE,EACzD,cAAmB,EACnB,UAAU,GACX,GAAE,wBAAwB,CAAC,CAAC,CAAM,GAAG,iBAAiB,CACrD,OAAO,CAAC,CAAC,CAAC,EACV,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,EACrC;IAAE,YAAY,EAAE,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,CAC5C,CAoCA;AAED,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9C,cAAmB,EACnB,UAAU,GACX,GAAE;IACD,cAAc,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,QAAQ,CAAC;QACnB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC;KACzD,CAAC;CACE,GAAG,iBAAiB,CACxB,MAAM,EACN,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EACnB;IAAE,YAAY,EAAE,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,CAC5C,CAkCA;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,cAAmB,EACnB,SAA8B,GAC/B,GAAE,qBAA0B,GAAG,iBAAiB,CAC/C,WAAW,EACX,KAAK,EACL;IAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAAE,CACpC,CAmDA"}
1
+ {"version":3,"file":"use-firestore-mutations.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-mutations.ts"],"names":[],"mappings":"AAEA,OAAO,EAAkB,KAAK,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACtE,OAAO,EAML,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAsB,KAAK,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AACxF,OAAO,KAAK,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAChG,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAIpD,UAAU,SAAS,CAAC,CAAC;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,CAAC,CAAC;CACT;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EAAE,EACtD,cAAmB,GACpB,GAAE,IAAI,CAAC,wBAAwB,CAAC,CAAC,CAAC,EAAE,gBAAgB,CAAM,GAAG,qBAAqB,CACjF,SAAS,CAAC,CAAC,CAAC,EACZ,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9C,CAwBA;AAED,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,YAAY,EAAE,EACzD,cAAmB,EACnB,UAAU,GACX,GAAE,wBAAwB,CAAC,CAAC,CAAM,GAAG,qBAAqB,CACzD,OAAO,CAAC,CAAC,CAAC,EACV,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,CAAA;CAAE,EACrC;IAAE,YAAY,EAAE,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,CAC5C,CAoCA;AAED,wBAAgB,kBAAkB,CAAC,CAAC,GAAG,OAAO,EAAE,EAC9C,cAAmB,EACnB,UAAU,GACX,GAAE;IACD,cAAc,CAAC,EAAE,SAAS,QAAQ,EAAE,CAAC;IACrC,UAAU,CAAC,EAAE;QACX,QAAQ,EAAE,QAAQ,CAAC;QACnB,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,SAAS,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC;KACzD,CAAC;CACE,GAAG,qBAAqB,CAC5B,MAAM,EACN,KAAK,EACL;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EACnB;IAAE,YAAY,EAAE,CAAC,GAAG,SAAS,CAAA;CAAE,GAAG,SAAS,CAC5C,CAkCA;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,cAAmB,EACnB,SAA8B,GAC/B,GAAE,qBAA0B,GAAG,qBAAqB,CACnD,WAAW,EACX,KAAK,EACL;IAAE,UAAU,EAAE,iBAAiB,EAAE,CAAA;CAAE,CACpC,CAmDA"}