File size: 1,545 Bytes
fa9c65f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
export interface AccountAuthHandoffEffects {
  destroyEntitlementSubscription: () => void;
  resetEntitlementState: () => void;
  destroySubscriptionWatch: () => void;
  rebindConvexAuthForWatchHandoff: (
    isCurrent: () => boolean,
    attachWatches: () => void,
  ) => Promise<boolean>;
  initEntitlementSubscription: (
    userId: string,
    isCurrent: () => boolean,
  ) => void | Promise<void>;
  initSubscriptionWatch: (
    userId: string,
    isCurrent: () => boolean,
  ) => void | Promise<void>;
  cloudPrefsSignIn: (userId: string) => void | Promise<void>;
}

/**
 * Reset user-scoped client state and start the authenticated watch handoff.
 *
 * The rebind effect is deliberately invoked before cloud preferences. Its
 * production implementation invalidates the old Clerk token synchronously
 * before its first await, after which Convex and cloud prefs may safely share
 * the new account's in-flight token fetch.
 */
export function startAccountAuthHandoff(input: {
  userId: string;
  isCurrent: () => boolean;
  effects: AccountAuthHandoffEffects;
}): Promise<boolean> {
  const { userId, isCurrent, effects } = input;

  effects.destroyEntitlementSubscription();
  effects.resetEntitlementState();
  effects.destroySubscriptionWatch();

  const handoff = effects.rebindConvexAuthForWatchHandoff(
    isCurrent,
    () => {
      void effects.initEntitlementSubscription(userId, isCurrent);
      void effects.initSubscriptionWatch(userId, isCurrent);
    },
  );
  void effects.cloudPrefsSignIn(userId);
  return handoff;
}