@ttt-productions/query-core 0.13.2 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Bounded resubscribe ladder for realtime Firestore listeners.
3
+ *
4
+ * A subscription that dies on a `permission-denied` listener error never retries on
5
+ * its own. In practice this fires transiently mid-session: the App Check token
6
+ * expires ~1h in and the SDK's silent refresh mint can fail (e.g. the refresh hits
7
+ * the reCAPTCHA bot-score throttle), so an active `onSnapshot` errors with
8
+ * `permission-denied` even though the user is still authorized. Without a retry the
9
+ * widget stays permanently dead until a full reload.
10
+ *
11
+ * These delays (ms) are the backoff between resubscribe attempts. After the last
12
+ * one the error surfaces exactly as it did before. While the ladder runs the
13
+ * consumer keeps its last-known data and reads `sourceState: 'connecting'`; a
14
+ * healthy snapshot resets the ladder so a later blip gets a fresh window.
15
+ */
16
+ export declare const RESUBSCRIBE_DELAYS_MS: readonly [5000, 15000, 45000];
17
+ /**
18
+ * True for a Firestore `permission-denied` listener error — the only code the
19
+ * subscription hooks bounded-retry (a failed token refresh heals within seconds).
20
+ * Keys off the `FirestoreError.code`, never the message.
21
+ */
22
+ export declare function isPermissionDeniedError(error: unknown): boolean;
23
+ //# sourceMappingURL=resubscribe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resubscribe.d.ts","sourceRoot":"","sources":["../../../src/react/firestore/resubscribe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,qBAAqB,+BAAmC,CAAC;AAEtE;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/D"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Bounded resubscribe ladder for realtime Firestore listeners.
3
+ *
4
+ * A subscription that dies on a `permission-denied` listener error never retries on
5
+ * its own. In practice this fires transiently mid-session: the App Check token
6
+ * expires ~1h in and the SDK's silent refresh mint can fail (e.g. the refresh hits
7
+ * the reCAPTCHA bot-score throttle), so an active `onSnapshot` errors with
8
+ * `permission-denied` even though the user is still authorized. Without a retry the
9
+ * widget stays permanently dead until a full reload.
10
+ *
11
+ * These delays (ms) are the backoff between resubscribe attempts. After the last
12
+ * one the error surfaces exactly as it did before. While the ladder runs the
13
+ * consumer keeps its last-known data and reads `sourceState: 'connecting'`; a
14
+ * healthy snapshot resets the ladder so a later blip gets a fresh window.
15
+ */
16
+ export const RESUBSCRIBE_DELAYS_MS = [5_000, 15_000, 45_000];
17
+ /**
18
+ * True for a Firestore `permission-denied` listener error — the only code the
19
+ * subscription hooks bounded-retry (a failed token refresh heals within seconds).
20
+ * Keys off the `FirestoreError.code`, never the message.
21
+ */
22
+ export function isPermissionDeniedError(error) {
23
+ return error?.code === 'permission-denied';
24
+ }
25
+ //# sourceMappingURL=resubscribe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resubscribe.js","sourceRoot":"","sources":["../../../src/react/firestore/resubscribe.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,CAAU,CAAC;AAEtE;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAc;IACpD,OAAQ,KAA8C,EAAE,IAAI,KAAK,mBAAmB,CAAC;AACvF,CAAC"}
@@ -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,EAKL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EACV,0BAA0B,EAE1B,MAAM,EACN,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC5E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CA8FrF"}
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,EAKL,KAAK,YAAY,EAClB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,KAAK,EACV,0BAA0B,EAE1B,MAAM,EACN,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EAC5E,cAAc,EACd,QAAQ,EACR,WAAgB,EAChB,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,0BAA0B,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CA8HrF"}
@@ -3,6 +3,7 @@ import { useEffect, useState } 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
+ import { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';
6
7
  /**
7
8
  * Fetch all documents from a Firestore collection with optional realtime updates.
8
9
  * Use this for small collections where you need all documents at once.
@@ -40,28 +41,59 @@ export function useFirestoreCollection({ collectionPath, queryKey, constraints =
40
41
  return;
41
42
  setSubscriptionError(null);
42
43
  setSourceState('connecting');
43
- const collectionRef = collection(db, collectionPath);
44
- const q = constraints.length > 0
45
- ? query(collectionRef, ...constraints)
46
- : collectionRef;
47
- const unsubscribe = onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => {
48
- setSubscriptionError(null);
49
- const items = snapshot.docs.map((docSnap) => {
50
- const rawData = docSnap.data();
51
- const dataWithId = { id: docSnap.id, ...rawData };
52
- const data = select ? select(dataWithId) : dataWithId;
53
- return data;
44
+ // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session
45
+ // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the
46
+ // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are
47
+ // cleaned up on unmount so a pending retry never fires after teardown.
48
+ let currentUnsubscribe = null;
49
+ let retryTimer = null;
50
+ let attempt = 0;
51
+ let disposed = false;
52
+ const start = () => {
53
+ if (disposed)
54
+ return;
55
+ const collectionRef = collection(db, collectionPath);
56
+ const q = constraints.length > 0
57
+ ? query(collectionRef, ...constraints)
58
+ : collectionRef;
59
+ currentUnsubscribe = onSnapshot(q, { includeMetadataChanges: true }, (snapshot) => {
60
+ attempt = 0;
61
+ setSubscriptionError(null);
62
+ const items = snapshot.docs.map((docSnap) => {
63
+ const rawData = docSnap.data();
64
+ const dataWithId = { id: docSnap.id, ...rawData };
65
+ const data = select ? select(dataWithId) : dataWithId;
66
+ return data;
67
+ });
68
+ queryClient.setQueryData(queryKey, items);
69
+ const fromCache = snapshot.metadata?.fromCache ?? false;
70
+ setSourceState((prev) => (fromCache ? (prev === 'connecting' ? 'connecting' : 'offline') : 'live'));
71
+ }, (error) => {
72
+ // Heal a transient permission-denied by resubscribing on the backoff ladder,
73
+ // keeping the last-known data visible. Only surface the error once the ladder
74
+ // is exhausted; any other error surfaces immediately, as before.
75
+ if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {
76
+ currentUnsubscribe?.();
77
+ currentUnsubscribe = null;
78
+ const delay = RESUBSCRIBE_DELAYS_MS[attempt];
79
+ attempt += 1;
80
+ setSourceState('connecting');
81
+ retryTimer = setTimeout(start, delay);
82
+ return;
83
+ }
84
+ console.error('[useFirestoreCollection] Subscription error:', error);
85
+ setSubscriptionError(error);
86
+ setSourceState('error');
87
+ queryClient.setQueryData(queryKey, undefined);
54
88
  });
55
- queryClient.setQueryData(queryKey, items);
56
- const fromCache = snapshot.metadata?.fromCache ?? false;
57
- setSourceState((prev) => (fromCache ? (prev === 'connecting' ? 'connecting' : 'offline') : 'live'));
58
- }, (error) => {
59
- console.error('[useFirestoreCollection] Subscription error:', error);
60
- setSubscriptionError(error);
61
- setSourceState('error');
62
- queryClient.setQueryData(queryKey, undefined);
63
- });
64
- return () => unsubscribe();
89
+ };
90
+ start();
91
+ return () => {
92
+ disposed = true;
93
+ if (retryTimer)
94
+ clearTimeout(retryTimer);
95
+ currentUnsubscribe?.();
96
+ };
65
97
  // queryKey & constraints are tracked via their stringified forms above; select is intentionally
66
98
  // excluded so an inline caller function doesn't force a re-subscribe on every render.
67
99
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -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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"}
1
+ {"version":3,"file":"use-firestore-collection.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-collection.ts"],"names":[],"mappings":"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"}
@@ -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;AAEhF,OAAO,KAAK,EACV,mBAAmB,EAEnB,MAAM,EACN,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACrE,OAAO,EACP,QAAQ,EACR,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAwFnF"}
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;AAGhF,OAAO,KAAK,EACV,mBAAmB,EAEnB,MAAM,EACN,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,GAAG,YAAY,EAAE,EACrE,OAAO,EACP,QAAQ,EACR,OAAc,EACd,SAAiB,EACjB,SAAS,EACT,MAAM,EACN,MAAM,GACP,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG,eAAe,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,EAAE,KAAK,CAAC,CAAC,CAwHnF"}
@@ -3,6 +3,7 @@ import { useEffect, useState } 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
+ import { RESUBSCRIBE_DELAYS_MS, isPermissionDeniedError } from './resubscribe.js';
6
7
  /**
7
8
  * Fetch a single Firestore document with optional realtime updates.
8
9
  * * @example
@@ -41,28 +42,59 @@ export function useFirestoreDoc({ docPath, queryKey, enabled = true, subscribe =
41
42
  return;
42
43
  setSubscriptionError(null);
43
44
  setSourceState('connecting');
44
- const docRef = doc(db, docPath);
45
- const unsubscribe = onSnapshot(docRef, { includeMetadataChanges: true }, (snapshot) => {
46
- setSubscriptionError(null);
47
- if (snapshot.exists()) {
48
- const rawData = snapshot.data();
49
- // Include id in data passed to select, so it can be renamed/transformed
50
- const dataWithId = { id: snapshot.id, ...rawData };
51
- const data = select ? select(dataWithId) : dataWithId;
52
- queryClient.setQueryData(queryKey, data);
53
- }
54
- else {
55
- queryClient.setQueryData(queryKey, null);
56
- }
57
- const fromCache = snapshot.metadata?.fromCache ?? false;
58
- setSourceState((prev) => (fromCache ? (prev === 'connecting' ? 'connecting' : 'offline') : 'live'));
59
- }, (error) => {
60
- console.error('[useFirestoreDoc] Subscription error:', error);
61
- setSubscriptionError(error);
62
- setSourceState('error');
63
- queryClient.setQueryData(queryKey, undefined);
64
- });
65
- return () => unsubscribe();
45
+ // Bounded resubscribe: a transient `permission-denied` (e.g. a failed mid-session
46
+ // App Check token refresh) is retried on the RESUBSCRIBE_DELAYS_MS ladder before the
47
+ // error is surfaced. `attempt` resets on any healthy snapshot; `disposed`/timers are
48
+ // cleaned up on unmount so a pending retry never fires after teardown.
49
+ let currentUnsubscribe = null;
50
+ let retryTimer = null;
51
+ let attempt = 0;
52
+ let disposed = false;
53
+ const start = () => {
54
+ if (disposed)
55
+ return;
56
+ const docRef = doc(db, docPath);
57
+ currentUnsubscribe = onSnapshot(docRef, { includeMetadataChanges: true }, (snapshot) => {
58
+ attempt = 0;
59
+ setSubscriptionError(null);
60
+ if (snapshot.exists()) {
61
+ const rawData = snapshot.data();
62
+ // Include id in data passed to select, so it can be renamed/transformed
63
+ const dataWithId = { id: snapshot.id, ...rawData };
64
+ const data = select ? select(dataWithId) : dataWithId;
65
+ queryClient.setQueryData(queryKey, data);
66
+ }
67
+ else {
68
+ queryClient.setQueryData(queryKey, null);
69
+ }
70
+ const fromCache = snapshot.metadata?.fromCache ?? false;
71
+ setSourceState((prev) => (fromCache ? (prev === 'connecting' ? 'connecting' : 'offline') : 'live'));
72
+ }, (error) => {
73
+ // Heal a transient permission-denied by resubscribing on the backoff ladder,
74
+ // keeping the last-known data visible. Only surface the error once the ladder
75
+ // is exhausted; any other error surfaces immediately, as before.
76
+ if (isPermissionDeniedError(error) && attempt < RESUBSCRIBE_DELAYS_MS.length) {
77
+ currentUnsubscribe?.();
78
+ currentUnsubscribe = null;
79
+ const delay = RESUBSCRIBE_DELAYS_MS[attempt];
80
+ attempt += 1;
81
+ setSourceState('connecting');
82
+ retryTimer = setTimeout(start, delay);
83
+ return;
84
+ }
85
+ console.error('[useFirestoreDoc] Subscription error:', error);
86
+ setSubscriptionError(error);
87
+ setSourceState('error');
88
+ queryClient.setQueryData(queryKey, undefined);
89
+ });
90
+ };
91
+ start();
92
+ return () => {
93
+ disposed = true;
94
+ if (retryTimer)
95
+ clearTimeout(retryTimer);
96
+ currentUnsubscribe?.();
97
+ };
66
98
  // Note: select intentionally excluded to prevent re-subscribing on every render if the caller
67
99
  // passes an inline function. queryKey is tracked via queryKeyMemo above.
68
100
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -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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"}
1
+ {"version":3,"file":"use-firestore-doc.js","sourceRoot":"","sources":["../../../src/react/firestore/use-firestore-doc.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ttt-productions/query-core",
3
- "version": "0.13.2",
3
+ "version": "0.14.0",
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",