@ttt-productions/upload-ui 0.7.17 → 0.7.19

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 (43) hide show
  1. package/dist/index.d.ts.map +1 -1
  2. package/dist/index.js +0 -2
  3. package/dist/index.js.map +1 -1
  4. package/dist/react/guard/guarded-link.d.ts +0 -27
  5. package/dist/react/guard/guarded-link.d.ts.map +1 -1
  6. package/dist/react/guard/guarded-link.js.map +1 -1
  7. package/dist/react/guard/local-upload-guard-provider.d.ts +0 -81
  8. package/dist/react/guard/local-upload-guard-provider.d.ts.map +1 -1
  9. package/dist/react/guard/local-upload-guard-provider.js +3 -60
  10. package/dist/react/guard/local-upload-guard-provider.js.map +1 -1
  11. package/dist/react/guard/use-guarded-navigation.d.ts +0 -7
  12. package/dist/react/guard/use-guarded-navigation.d.ts.map +1 -1
  13. package/dist/react/guard/use-guarded-navigation.js +0 -28
  14. package/dist/react/guard/use-guarded-navigation.js.map +1 -1
  15. package/dist/react/tray/in-flight-uploads-provider.d.ts +1 -126
  16. package/dist/react/tray/in-flight-uploads-provider.d.ts.map +1 -1
  17. package/dist/react/tray/in-flight-uploads-provider.js +10 -133
  18. package/dist/react/tray/in-flight-uploads-provider.js.map +1 -1
  19. package/dist/react/tray/use-clear-upload-activity.d.ts +1 -26
  20. package/dist/react/tray/use-clear-upload-activity.d.ts.map +1 -1
  21. package/dist/react/tray/use-clear-upload-activity.js +2 -20
  22. package/dist/react/tray/use-clear-upload-activity.js.map +1 -1
  23. package/dist/react/tray/use-mark-upload-activity-seen.d.ts +0 -4
  24. package/dist/react/tray/use-mark-upload-activity-seen.d.ts.map +1 -1
  25. package/dist/react/tray/use-mark-upload-activity-seen.js +5 -25
  26. package/dist/react/tray/use-mark-upload-activity-seen.js.map +1 -1
  27. package/dist/react/tray/use-upload-processing.d.ts +0 -10
  28. package/dist/react/tray/use-upload-processing.d.ts.map +1 -1
  29. package/dist/react/tray/use-upload-processing.js +0 -18
  30. package/dist/react/tray/use-upload-processing.js.map +1 -1
  31. package/dist/react/upload/deferred-upload-form-shell.d.ts +1 -19
  32. package/dist/react/upload/deferred-upload-form-shell.d.ts.map +1 -1
  33. package/dist/react/upload/deferred-upload-form-shell.js +0 -1
  34. package/dist/react/upload/deferred-upload-form-shell.js.map +1 -1
  35. package/dist/react/upload/use-guarded-upload.d.ts +0 -29
  36. package/dist/react/upload/use-guarded-upload.d.ts.map +1 -1
  37. package/dist/react/upload/use-guarded-upload.js +0 -13
  38. package/dist/react/upload/use-guarded-upload.js.map +1 -1
  39. package/dist/upload-display.d.ts +0 -14
  40. package/dist/upload-display.d.ts.map +1 -1
  41. package/dist/upload-display.js +2 -5
  42. package/dist/upload-display.js.map +1 -1
  43. package/package.json +13 -6
@@ -1,45 +1,6 @@
1
- /**
2
- * Generic in-flight uploads provider.
3
- *
4
- * Provides a global Map of in-flight upload state by `pendingMediaId`, derived
5
- * from a Firestore listener over the consumer-supplied collection. On terminal
6
- * status transitions observed THIS SESSION, fires consumer-supplied success /
7
- * failure / rejection callbacks. Records monitoring breadcrumbs and parse
8
- * errors through the injected monitoring callback.
9
- *
10
- * EVERY app-specific value is supplied by the consumer:
11
- * - userId resolution
12
- * - Firestore `db` reference
13
- * - collection path
14
- * - listener time window (ms)
15
- * - parser/schema for raw Firestore doc → typed PendingMedia
16
- * - success copy per origin
17
- * - notification callback (cache invalidation, etc.)
18
- * - toast callback
19
- * - rejection callback (for the media-rejection dialog or equivalent)
20
- * - monitoring callback (breadcrumbs + captured errors)
21
- *
22
- * Read APIs:
23
- * - `useInFlightUploadsState()` — full Map.
24
- * - `useInFlightUpload(id)` — single doc, narrowable on status.
25
- * - `useUploadActivityState()` — tray-visible items, sorted newest-first.
26
- *
27
- * The package owns the deduplication, initial-snapshot suppression, and
28
- * non-terminal → terminal transition tracking. It does NOT own anything about
29
- * what a file-origin is or what message text appears in toasts.
30
- */
31
1
  import { type ReactNode } from 'react';
32
2
  import { PendingMediaStatusSchema, type PendingMediaNonTerminalStatus, type PendingMediaStatus } from '@ttt-productions/media-schemas';
33
- /** Generic pending-media status — media-schemas' one declaration. */
34
3
  export type InFlightUploadStatus = PendingMediaStatus;
35
- /**
36
- * Generic in-flight upload record. The provider keeps a Map<id, InFlightUpload>
37
- * built from each parsed PendingMedia. Consumers parameterize the `fileOrigin`
38
- * type via the parser's return type (the provider treats it as opaque).
39
- *
40
- * `TFileOrigin` defaults to `string` so unannotated consumers get a permissive
41
- * shape; consuming apps bind it to their own `FileOrigin` union at the call site.
42
- */
43
4
  export type InFlightUploadBase<TFileOrigin extends string = string> = {
44
5
  id: string;
45
6
  fileOrigin: TFileOrigin;
@@ -82,14 +43,6 @@ export type InFlightUploadRejected<TFileOrigin extends string = string> = InFlig
82
43
  uploadTraySeenBy?: string;
83
44
  };
84
45
  export type InFlightUpload<TFileOrigin extends string = string> = InFlightUploadActive<TFileOrigin> | InFlightUploadCompleted<TFileOrigin> | InFlightUploadFailed<TFileOrigin> | InFlightUploadRejected<TFileOrigin>;
85
- /**
86
- * Result of the consumer-supplied parser. The provider keeps the raw parsed
87
- * record for callbacks (so consumers can read domain events, target IDs, etc.)
88
- * AND derives the generic InFlightUpload from it for the public Map.
89
- *
90
- * The parser MUST throw if validation fails; the provider catches and routes
91
- * the error to the monitoring callback.
92
- */
93
46
  export type ParsedPendingMedia<TFileOrigin extends string = string> = {
94
47
  id: string;
95
48
  userId: string;
@@ -111,43 +64,17 @@ export type ParsedPendingMedia<TFileOrigin extends string = string> = {
111
64
  uploadTrayClearedBy?: string;
112
65
  uploadTraySeenAt?: number;
113
66
  uploadTraySeenBy?: string;
114
- /**
115
- * Opaque consumer-controlled domain-event payload, surfaced to the
116
- * `onUploadCompleted` and `onUploadRejected` callbacks for cache
117
- * invalidation. The provider does not interpret it.
118
- */
119
67
  domainEvents?: unknown;
120
68
  };
121
69
  export type InFlightUploadsAdapter<TFileOrigin extends string = string> = {
122
- /** Returns the current user's uid, or null if not signed in. */
123
70
  getCurrentUserId: () => string | null;
124
- /** Firestore database adapter (loose typing — `unknown` keeps zero firebase coupling at the type level). */
125
71
  db: unknown;
126
- /** Collection path holding pending-media docs (e.g. "pendingMedia"). */
127
72
  collectionPath: string;
128
- /** Listener window in milliseconds — only docs with `createdAt >= now - window` are tracked. */
129
73
  listenerWindowMs: number;
130
- /**
131
- * Parse a raw Firestore doc snapshot's `.data()` into the generic shape the
132
- * provider tracks. Throws on validation failure; the provider routes thrown
133
- * errors to `onMonitoringEvent`.
134
- */
135
74
  parsePendingMedia: (raw: unknown) => ParsedPendingMedia<TFileOrigin>;
136
- /** Called once per observed non-terminal → terminal completed transition. */
137
75
  onUploadCompleted: (parsed: ParsedPendingMedia<TFileOrigin>) => void;
138
- /** Called once per observed non-terminal → terminal failed transition. */
139
76
  onUploadFailed: (parsed: ParsedPendingMedia<TFileOrigin>) => void;
140
- /** Called once per observed non-terminal → terminal rejected transition. */
141
77
  onUploadRejected: (parsed: ParsedPendingMedia<TFileOrigin>) => void;
142
- /**
143
- * Monitoring callback. Receives:
144
- * - `breadcrumb`: informational, fired on every observed terminal transition.
145
- * - `parse-error`: when `parsePendingMedia` throws.
146
- * - `listener-error`: when the Firestore listener's error callback fires.
147
- *
148
- * Consumers wire this to Sentry, OpenTelemetry, or any other observability
149
- * provider. The provider does NOT import any monitoring SDK directly.
150
- */
151
78
  onMonitoringEvent: (event: InFlightUploadsMonitoringEvent<TFileOrigin>) => void;
152
79
  };
153
80
  export type InFlightUploadsMonitoringEvent<TFileOrigin extends string = string> = {
@@ -170,13 +97,6 @@ export type InFlightUploadsMonitoringEvent<TFileOrigin extends string = string>
170
97
  type: 'listener-error';
171
98
  error: unknown;
172
99
  };
173
- /**
174
- * Minimal subscription contract used by the provider. The default
175
- * implementation lives in `firestore-subscribe.ts` and uses the standard
176
- * `firebase/firestore` `onSnapshot` + `query` + `where` builders.
177
- *
178
- * Tests inject a fake to drive the listener without spinning up Firestore.
179
- */
180
100
  export type FirestoreSubscribeFn = (args: {
181
101
  db: unknown;
182
102
  collectionPath: string;
@@ -187,26 +107,11 @@ export type FirestoreSubscribeFn = (args: {
187
107
  }) => () => void;
188
108
  export type FirestoreLikeSnapshot = {
189
109
  docChanges: () => FirestoreLikeDocChange[];
190
- /**
191
- * Snapshot metadata. Present when the subscription is opened with
192
- * `{ includeMetadataChanges: true }` (the default firebase implementation does).
193
- * `fromCache === false` means a server-confirmed snapshot. Optional so injected
194
- * test fakes need not supply it (absent ⇒ treated as server-confirmed).
195
- */
196
110
  metadata?: {
197
111
  fromCache: boolean;
198
112
  };
199
113
  };
200
- /**
201
- * Metadata-derived liveness of the uploads listener, mirroring query-core's
202
- * `FirestoreSourceState`. Firestore serves cached snapshots offline WITHOUT
203
- * firing the error callback, so the Files tray source needs this to show a
204
- * degraded indicator instead of a false "all caught up":
205
- * - `connecting` — no server-confirmed snapshot yet.
206
- * - `live` — at least one server-confirmed snapshot (`fromCache === false`).
207
- * - `offline` — only cached data after having been live.
208
- * - `error` — the listener error callback fired.
209
- */
114
+ /** Firestore serves cached snapshots offline without firing the error callback, so liveness comes from metadata. */
210
115
  export type UploadsSourceState = 'connecting' | 'live' | 'offline' | 'error';
211
116
  export type FirestoreLikeDocChange = {
212
117
  type: 'added' | 'modified' | 'removed';
@@ -215,52 +120,22 @@ export type FirestoreLikeDocChange = {
215
120
  data: () => unknown;
216
121
  };
217
122
  };
218
- /** Restarting the uploads listener after it failed, and whether that restart is running. */
219
123
  export interface UploadsSourceRetry {
220
- /**
221
- * Tear the listener down and subscribe again on a fresh retry ladder. While the restart runs the
222
- * source state stays as it was (an `error` stays `error`), so a failure shown on it stays on
223
- * screen with its control pending.
224
- */
225
124
  retry: () => void;
226
- /** A `retry` is running: true until the restarted listener answers or its ladder fails again. */
227
125
  retrying: boolean;
228
126
  }
229
127
  export interface InFlightUploadsProviderProps<TFileOrigin extends string = string> {
230
128
  adapter: InFlightUploadsAdapter<TFileOrigin>;
231
- /** Firestore subscription function. Defaults to the firebase/firestore implementation. */
232
129
  subscribe?: FirestoreSubscribeFn;
233
130
  children: ReactNode;
234
131
  }
235
132
  export declare function InFlightUploadsProvider<TFileOrigin extends string = string>(props: InFlightUploadsProviderProps<TFileOrigin>): import("react").JSX.Element;
236
133
  export declare function useInFlightUploadsState<TFileOrigin extends string = string>(): Map<string, InFlightUpload<TFileOrigin>>;
237
134
  export declare function useInFlightUpload<TFileOrigin extends string = string>(id: string | null | undefined): InFlightUpload<TFileOrigin> | undefined;
238
- /**
239
- * Metadata-derived source state of the uploads listener
240
- * (`connecting | live | offline | error`). The Files tray uses this to show a
241
- * degraded indicator and never display "all caught up" while the source is
242
- * `offline`/`error`/`connecting`.
243
- */
244
135
  export declare function useUploadsSourceState(): UploadsSourceState;
245
- /**
246
- * The uploads listener's restart — the Try again of a failure shown on `useUploadsSourceState` —
247
- * and whether it is running.
248
- */
249
136
  export declare function useUploadsSourceRetry(): UploadsSourceRetry;
250
- /**
251
- * `true` for `completed` / `failed` / `rejected`. Used by tray UI to decide
252
- * whether a Clear action is available for an item.
253
- */
254
137
  export declare function isTerminalUpload<TFileOrigin extends string = string>(item: InFlightUpload<TFileOrigin>): item is Exclude<InFlightUpload<TFileOrigin>, {
255
138
  status: PendingMediaNonTerminalStatus;
256
139
  }>;
257
- /**
258
- * Tray-visible items. Includes every pending/processing upload, plus terminal
259
- * uploads that have NOT been cleared from the tray. Sorted newest-first by
260
- * createdAt.
261
- *
262
- * The public selector name in upload-ui is `useUploadActivityState`. The
263
- * mutation hook is `useClearUploadActivity` (in a separate file).
264
- */
265
140
  export declare function useUploadActivityState<TFileOrigin extends string = string>(): InFlightUpload<TFileOrigin>[];
266
141
  //# sourceMappingURL=in-flight-uploads-provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"in-flight-uploads-provider.d.ts","sourceRoot":"","sources":["../../../src/react/tray/in-flight-uploads-provider.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"in-flight-uploads-provider.d.ts","sourceRoot":"","sources":["../../../src/react/tray/in-flight-uploads-provider.tsx"],"names":[],"mappings":"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"}
@@ -1,7 +1,6 @@
1
1
  'use client';
2
2
  import { jsx as _jsx } from "react/jsx-runtime";
3
- // ─────────────────────────────────────────────────────────────────────────────
4
- // SANCTIONED EXCEPTION to ARCH-206 (packages read and write Firestore only
3
+ // SANCTIONED EXCEPTION to RULE-STD-ARCH-206 (packages read and write Firestore only
5
4
  // through @ttt-productions/query-core).
6
5
  //
7
6
  // WHY this provider reads Firestore directly instead of via a query-core hook:
@@ -17,41 +16,9 @@ import { jsx as _jsx } from "react/jsx-runtime";
17
16
  // Turbopack module identity (see defaultFirestoreSubscribe's comment).
18
17
  //
19
18
  // Do NOT "migrate" this onto query-core without preserving docChanges() semantics.
20
- // ─────────────────────────────────────────────────────────────────────────────
21
19
  import { collection, onSnapshot, query, where } from 'firebase/firestore';
22
- /**
23
- * Generic in-flight uploads provider.
24
- *
25
- * Provides a global Map of in-flight upload state by `pendingMediaId`, derived
26
- * from a Firestore listener over the consumer-supplied collection. On terminal
27
- * status transitions observed THIS SESSION, fires consumer-supplied success /
28
- * failure / rejection callbacks. Records monitoring breadcrumbs and parse
29
- * errors through the injected monitoring callback.
30
- *
31
- * EVERY app-specific value is supplied by the consumer:
32
- * - userId resolution
33
- * - Firestore `db` reference
34
- * - collection path
35
- * - listener time window (ms)
36
- * - parser/schema for raw Firestore doc → typed PendingMedia
37
- * - success copy per origin
38
- * - notification callback (cache invalidation, etc.)
39
- * - toast callback
40
- * - rejection callback (for the media-rejection dialog or equivalent)
41
- * - monitoring callback (breadcrumbs + captured errors)
42
- *
43
- * Read APIs:
44
- * - `useInFlightUploadsState()` — full Map.
45
- * - `useInFlightUpload(id)` — single doc, narrowable on status.
46
- * - `useUploadActivityState()` — tray-visible items, sorted newest-first.
47
- *
48
- * The package owns the deduplication, initial-snapshot suppression, and
49
- * non-terminal → terminal transition tracking. It does NOT own anything about
50
- * what a file-origin is or what message text appears in toasts.
51
- */
52
20
  import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from 'react';
53
21
  import { isPendingMediaNonTerminalStatus, isPendingMediaTerminalStatus, PendingMediaStatusSchema, } from '@ttt-productions/media-schemas';
54
- // Status values derive from media-schemas' one declaration.
55
22
  const STATUS = PendingMediaStatusSchema.enum;
56
23
  const InFlightUploadsContext = createContext(undefined);
57
24
  function fromParsed(parsed) {
@@ -91,7 +58,6 @@ function fromParsed(parsed) {
91
58
  uploadTraySeenBy: parsed.uploadTraySeenBy,
92
59
  };
93
60
  }
94
- // rejected
95
61
  return {
96
62
  ...base,
97
63
  status: STATUS.rejected,
@@ -101,10 +67,7 @@ function fromParsed(parsed) {
101
67
  violationId: parsed.violationId,
102
68
  uploadTrayClearedAt: parsed.uploadTrayClearedAt,
103
69
  uploadTrayClearedBy: parsed.uploadTrayClearedBy,
104
- // Carry the seen fields through on the `rejected` branch as `completed` /
105
- // `failed` do: without them a seen rejected upload relights the Files dot
106
- // forever, because the tray's unseen-terminal check never sees
107
- // `uploadTraySeenAt`.
70
+ // Without the seen fields a seen rejected upload relights the Files dot forever.
108
71
  uploadTraySeenAt: parsed.uploadTraySeenAt,
109
72
  uploadTraySeenBy: parsed.uploadTraySeenBy,
110
73
  };
@@ -115,36 +78,19 @@ export function InFlightUploadsProvider(props) {
115
78
  const [sourceState, setSourceState] = useState('connecting');
116
79
  const [restarts, setRestarts] = useState(0);
117
80
  const [retrying, setRetrying] = useState(false);
118
- /** Set by `retry` for the subscription the restart opens; that run keeps the source state. */
119
81
  const restartRequestedRef = useRef(false);
120
82
  const seenTerminalIdsRef = useRef(new Set());
121
83
  const statusByIdRef = useRef(new Map());
122
84
  const hasProcessedInitialSnapshotRef = useRef(false);
123
- /** The identity the dedup/tracking refs belong to — they outlive resubscribes
124
- * for the SAME user (auth-settling flaps) and reset only on a real identity
125
- * change. See the reset block in the subscription effect. */
126
85
  const trackedUserIdRef = useRef(null);
127
- // Stable refs for adapter callbacks — read from latest adapter inside effect.
128
86
  const adapterRef = useRef(adapter);
129
87
  useEffect(() => {
130
88
  adapterRef.current = adapter;
131
89
  });
132
90
  const userId = adapter.getCurrentUserId();
133
91
  useEffect(() => {
134
- // The uploads map and source state rebuild from every subscription's initial
135
- // snapshot, so they reset on every effect run. The terminal-dedup and
136
- // status-tracking refs are IDENTITY-scoped, not subscription-scoped: an
137
- // auth-settling flap (uid → null → same uid re-subscribes) must neither
138
- // re-fire terminals the previous subscription already fired (seen set
139
- // persists) nor lose the observed non-terminal statuses that let the new
140
- // subscription's initial listing detect a transition that completed during
141
- // the gap. A real identity change — including UID-A → UID-B with no
142
- // intermediate null user — starts clean; never rely on an intermediate
143
- // sign-out to clear refs between two authenticated UIDs.
144
- // A restart the person asked for keeps the source state it had (a failure stays a failure
145
- // until the restarted listener answers); every other run starts over as `connecting`.
146
- // A restart belongs to the identity it was asked for: one that lands with a sign-out or a switch
147
- // of account is an ordinary new subscription, which starts over.
92
+ // The dedup and tracking refs are identity-scoped: they survive a same-user resubscribe and reset
93
+ // on any identity change, UID-A to UID-B with no sign-out between included.
148
94
  let restarting = restartRequestedRef.current && userId !== null && userId === trackedUserIdRef.current;
149
95
  restartRequestedRef.current = false;
150
96
  setUploads(new Map());
@@ -194,12 +140,8 @@ export function InFlightUploadsProvider(props) {
194
140
  const currentIsTerminal = isPendingMediaTerminalStatus(currentStatus);
195
141
  const previousWasNonTerminal = isPendingMediaNonTerminalStatus(previousStatus);
196
142
  if (isInitialSnapshot) {
197
- // A subscription's first snapshot is a (re-)listing of current state,
198
- // not a live event: already-terminal docs stay suppressed so a page
199
- // refresh never re-toasts. ONE exception — this provider instance
200
- // tracked the doc as non-terminal before (same-identity resubscribe
201
- // gap; the tracking refs survive those), so the terminal listing IS
202
- // the transition, observed across the gap, and must fire.
143
+ // A first snapshot re-lists current state: its terminal docs fire only when this instance tracked
144
+ // them as non-terminal before.
203
145
  if (currentIsTerminal) {
204
146
  if (previousWasNonTerminal && !seenTerminalIdsRef.current.has(parsed.id)) {
205
147
  newlyTerminal.push(parsed);
@@ -208,23 +150,14 @@ export function InFlightUploadsProvider(props) {
208
150
  }
209
151
  }
210
152
  else if (currentIsTerminal && !seenTerminalIdsRef.current.has(parsed.id)) {
211
- // Any unseen terminal in a LIVE snapshot fires — including a doc whose
212
- // FIRST client-visible state is already terminal. A fast backend
213
- // outcome (moderation rejection in ~2s) can coalesce created→terminal
214
- // into one delivery, and the uploader is actively waiting on exactly
215
- // this callback; swallowing it silently loses a rejection dialog.
153
+ // A fast outcome can coalesce created and terminal into one delivery, so any unseen terminal fires.
216
154
  seenTerminalIdsRef.current.add(parsed.id);
217
155
  newlyTerminal.push(parsed);
218
156
  }
219
157
  statusByIdRef.current.set(parsed.id, currentStatus);
220
158
  }
221
159
  hasProcessedInitialSnapshotRef.current = true;
222
- // Metadata-derived source state: stay `connecting` until a server-confirmed
223
- // snapshot, `offline` if only cached data arrives after being live.
224
160
  const fromCache = snapshot.metadata?.fromCache ?? false;
225
- // A restart ends on the server's answer: a cached snapshot during it keeps the failure on screen
226
- // (the server may refuse again). Otherwise a snapshot after a failed listener comes from a new
227
- // subscription: not yet live, never offline.
228
161
  if (!(restarting && fromCache)) {
229
162
  setSourceState((prev) => fromCache
230
163
  ? prev === 'connecting' || prev === 'error'
@@ -273,13 +206,6 @@ export function InFlightUploadsProvider(props) {
273
206
  adapterRef.current.onUploadRejected(parsed);
274
207
  }
275
208
  }
276
- // Bounded RESUBSCRIBE on listener error: a cold-session race (e.g. Firestore
277
- // App Check enforcement rejecting the first attach before the token is
278
- // minted) must not kill the listener for the whole session — observed live:
279
- // one permission-denied at first login → sourceState 'error' forever, every
280
- // tray file status dead until reload. Retry on a short ladder; a snapshot
281
- // resets the ladder (healthy again); exhausting it goes terminal 'error'
282
- // (a real rules denial stays denied — retries are cheap and bounded).
283
209
  const RESUBSCRIBE_DELAYS_MS = [1_000, 3_000, 10_000, 30_000];
284
210
  let attempt = 0;
285
211
  let disposed = false;
@@ -292,7 +218,7 @@ export function InFlightUploadsProvider(props) {
292
218
  userId,
293
219
  windowStartMs,
294
220
  onSnapshot: (snapshot) => {
295
- attempt = 0; // healthy — future errors get a fresh ladder
221
+ attempt = 0;
296
222
  handleSnapshot(snapshot);
297
223
  },
298
224
  onError: (error) => {
@@ -322,8 +248,6 @@ export function InFlightUploadsProvider(props) {
322
248
  clearTimeout(retryTimer);
323
249
  unsubscribe?.();
324
250
  };
325
- // adapter is intentionally NOT in the deps array — adapter is read via
326
- // adapterRef on every snapshot, so identity changes don't re-subscribe.
327
251
  }, [userId, subscribe, restarts]);
328
252
  const retry = useCallback(() => {
329
253
  restartRequestedRef.current = true;
@@ -333,9 +257,6 @@ export function InFlightUploadsProvider(props) {
333
257
  const value = useMemo(() => ({ uploads, sourceState, retry, retrying }), [uploads, sourceState, retry, retrying]);
334
258
  return (_jsx(InFlightUploadsContext.Provider, { value: value, children: children }));
335
259
  }
336
- // =============================================================================
337
- // Read APIs
338
- // =============================================================================
339
260
  export function useInFlightUploadsState() {
340
261
  const ctx = useContext(InFlightUploadsContext);
341
262
  if (ctx === undefined) {
@@ -352,12 +273,6 @@ export function useInFlightUpload(id) {
352
273
  return undefined;
353
274
  return ctx.uploads.get(id);
354
275
  }
355
- /**
356
- * Metadata-derived source state of the uploads listener
357
- * (`connecting | live | offline | error`). The Files tray uses this to show a
358
- * degraded indicator and never display "all caught up" while the source is
359
- * `offline`/`error`/`connecting`.
360
- */
361
276
  export function useUploadsSourceState() {
362
277
  const ctx = useContext(InFlightUploadsContext);
363
278
  if (ctx === undefined) {
@@ -365,10 +280,6 @@ export function useUploadsSourceState() {
365
280
  }
366
281
  return ctx.sourceState;
367
282
  }
368
- /**
369
- * The uploads listener's restart — the Try again of a failure shown on `useUploadsSourceState` —
370
- * and whether it is running.
371
- */
372
283
  export function useUploadsSourceRetry() {
373
284
  const ctx = useContext(InFlightUploadsContext);
374
285
  if (ctx === undefined) {
@@ -376,24 +287,9 @@ export function useUploadsSourceRetry() {
376
287
  }
377
288
  return { retry: ctx.retry, retrying: ctx.retrying };
378
289
  }
379
- // =============================================================================
380
- // Tray helpers
381
- // =============================================================================
382
- /**
383
- * `true` for `completed` / `failed` / `rejected`. Used by tray UI to decide
384
- * whether a Clear action is available for an item.
385
- */
386
290
  export function isTerminalUpload(item) {
387
291
  return isPendingMediaTerminalStatus(item.status);
388
292
  }
389
- /**
390
- * Tray-visible items. Includes every pending/processing upload, plus terminal
391
- * uploads that have NOT been cleared from the tray. Sorted newest-first by
392
- * createdAt.
393
- *
394
- * The public selector name in upload-ui is `useUploadActivityState`. The
395
- * mutation hook is `useClearUploadActivity` (in a separate file).
396
- */
397
293
  export function useUploadActivityState() {
398
294
  const uploads = useInFlightUploadsState();
399
295
  return useMemo(() => {
@@ -406,29 +302,10 @@ export function useUploadActivityState() {
406
302
  .sort((a, b) => b.createdAt - a.createdAt);
407
303
  }, [uploads]);
408
304
  }
409
- // =============================================================================
410
- // Default Firestore subscription implementation
411
- // =============================================================================
412
- /**
413
- * Default Firestore subscription using the consumer's `firebase/firestore`
414
- * module instance (via static ESM import at the top of this file).
415
- *
416
- * Using static ESM import — NOT `require()` — is load-bearing. CommonJS
417
- * `require('firebase/firestore')` and ESM `import 'firebase/firestore'` resolve
418
- * to different module instances under Next.js + Turbopack. If the consumer
419
- * constructs `db` via ESM and we receive it here, but we then call
420
- * `collection()` from a CJS-loaded copy of firebase, the firebase runtime
421
- * does not recognize the db as a Firestore instance and throws
422
- * "Expected first argument to collection() to be a CollectionReference,
423
- * a DocumentReference or FirebaseFirestore".
424
- *
425
- * Consumers who want to skip the firebase code path entirely (tests, alt
426
- * backends) supply their own `subscribe` prop to `InFlightUploadsProvider`.
427
- */
305
+ // A static ESM import, never require(): under Next.js + Turbopack a CJS-loaded firebase/firestore
306
+ // is another module instance and rejects a db built through ESM.
428
307
  const defaultFirestoreSubscribe = (args) => {
429
308
  const q = query(collection(args.db, args.collectionPath), where('userId', '==', args.userId), where('createdAt', '>=', args.windowStartMs));
430
- // includeMetadataChanges so the provider can derive a `connecting|live|offline|error`
431
- // source state from `snapshot.metadata.fromCache` (the Files tray degraded indicator).
432
309
  return onSnapshot(q, { includeMetadataChanges: true }, args.onSnapshot, args.onError);
433
310
  };
434
311
  //# sourceMappingURL=in-flight-uploads-provider.js.map