mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-09 01:20:09 +00:00
refactor: create userIdentityBus to decouple auth and telemetry
- Create src/platform/telemetry/userIdentityBus.ts with event hooks - MixpanelTelemetryProvider subscribes to userIdentityHook instead of importing useCurrentUser - firebaseAuthStore emits authEventHook instead of calling useTelemetry - telemetry/index.ts subscribes to authEventHook for tracking Part of Phase 1 circular dependency fixes. Amp-Thread-ID: https://ampcode.com/threads/T-019bfe05-7da5-736f-bff0-34743c003b34 Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -3,6 +3,7 @@ import { computed, watch } from 'vue'
|
||||
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { t } from '@/i18n'
|
||||
import { userIdentityHook } from '@/platform/telemetry/userIdentityBus'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
@@ -35,7 +36,14 @@ export const useCurrentUser = () => {
|
||||
})
|
||||
|
||||
const onUserResolved = (callback: (user: AuthUserInfo) => void) =>
|
||||
whenever(resolvedUserInfo, callback, { immediate: true })
|
||||
whenever(
|
||||
resolvedUserInfo,
|
||||
(user) => {
|
||||
void userIdentityHook.trigger({ userId: user.id })
|
||||
callback(user)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const onTokenRefreshed = (callback: () => void) =>
|
||||
whenever(() => authStore.tokenRefreshTrigger, callback)
|
||||
|
||||
@@ -18,6 +18,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
|
||||
import { MixpanelTelemetryProvider } from './providers/cloud/MixpanelTelemetryProvider'
|
||||
import type { TelemetryProvider } from './types'
|
||||
import { authEventHook } from './userIdentityBus'
|
||||
|
||||
// Singleton instance
|
||||
let _telemetryProvider: TelemetryProvider | null = null
|
||||
@@ -34,6 +35,13 @@ export function useTelemetry(): TelemetryProvider | null {
|
||||
// Use distribution check for tree-shaking
|
||||
if (isCloud) {
|
||||
_telemetryProvider = new MixpanelTelemetryProvider()
|
||||
|
||||
authEventHook.on(({ method, isNewUser }) => {
|
||||
_telemetryProvider?.trackAuth({
|
||||
method,
|
||||
is_new_user: isNewUser
|
||||
})
|
||||
})
|
||||
}
|
||||
// For OSS builds, _telemetryProvider stays null
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import type { OverridedMixpanel } from 'mixpanel-browser'
|
||||
import { watch } from 'vue'
|
||||
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import {
|
||||
checkForCompletedTopup as checkTopupUtil,
|
||||
clearTopupTracking as clearTopupUtil,
|
||||
@@ -46,6 +45,7 @@ import type {
|
||||
import { remoteConfig } from '@/platform/remoteConfig/remoteConfig'
|
||||
import type { RemoteConfig } from '@/platform/remoteConfig/types'
|
||||
import { TelemetryEvents } from '../../types'
|
||||
import { userIdentityHook } from '../../userIdentityBus'
|
||||
import { normalizeSurveyResponses } from '../../utils/surveyNormalization'
|
||||
|
||||
const DEFAULT_DISABLED_EVENTS = [
|
||||
@@ -119,10 +119,10 @@ export class MixpanelTelemetryProvider implements TelemetryProvider {
|
||||
persistence: 'cookie',
|
||||
loaded: () => {
|
||||
this.isInitialized = true
|
||||
this.flushEventQueue() // flush events that were queued while initializing
|
||||
useCurrentUser().onUserResolved((user) => {
|
||||
if (this.mixpanel && user.id) {
|
||||
this.mixpanel.identify(user.id)
|
||||
this.flushEventQueue()
|
||||
userIdentityHook.on(({ userId }) => {
|
||||
if (this.mixpanel && userId) {
|
||||
this.mixpanel.identify(userId)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
23
src/platform/telemetry/userIdentityBus.ts
Normal file
23
src/platform/telemetry/userIdentityBus.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { createEventHook } from '@vueuse/core'
|
||||
|
||||
export interface UserIdentity {
|
||||
userId: string
|
||||
}
|
||||
|
||||
export interface AuthEvent {
|
||||
event: 'login' | 'register' | 'logout'
|
||||
method: 'email' | 'google' | 'github'
|
||||
isNewUser: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Event hook for user identity changes.
|
||||
* Telemetry subscribes to this instead of importing useCurrentUser directly.
|
||||
*/
|
||||
export const userIdentityHook = createEventHook<UserIdentity>()
|
||||
|
||||
/**
|
||||
* Event hook for auth events (login, register, logout).
|
||||
* Telemetry subscribes to track auth events without auth importing telemetry.
|
||||
*/
|
||||
export const authEventHook = createEventHook<AuthEvent>()
|
||||
@@ -25,7 +25,7 @@ import { getComfyApiBaseUrl } from '@/config/comfyApi'
|
||||
import { t } from '@/i18n'
|
||||
import { WORKSPACE_STORAGE_KEYS } from '@/platform/auth/workspace/workspaceConstants'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
import { authEventHook } from '@/platform/telemetry/userIdentityBus'
|
||||
import { useDialogService } from '@/services/dialogService'
|
||||
import { useApiKeyAuthStore } from '@/stores/apiKeyAuthStore'
|
||||
import type { AuthHeader } from '@/types/authTypes'
|
||||
@@ -323,9 +323,10 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
)
|
||||
|
||||
if (isCloud) {
|
||||
useTelemetry()?.trackAuth({
|
||||
void authEventHook.trigger({
|
||||
event: 'login',
|
||||
method: 'email',
|
||||
is_new_user: false
|
||||
isNewUser: false
|
||||
})
|
||||
}
|
||||
|
||||
@@ -343,9 +344,10 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
)
|
||||
|
||||
if (isCloud) {
|
||||
useTelemetry()?.trackAuth({
|
||||
void authEventHook.trigger({
|
||||
event: 'register',
|
||||
method: 'email',
|
||||
is_new_user: true
|
||||
isNewUser: true
|
||||
})
|
||||
}
|
||||
|
||||
@@ -361,9 +363,10 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
if (isCloud) {
|
||||
const additionalUserInfo = getAdditionalUserInfo(result)
|
||||
const isNewUser = additionalUserInfo?.isNewUser ?? false
|
||||
useTelemetry()?.trackAuth({
|
||||
void authEventHook.trigger({
|
||||
event: isNewUser ? 'register' : 'login',
|
||||
method: 'google',
|
||||
is_new_user: isNewUser
|
||||
isNewUser
|
||||
})
|
||||
}
|
||||
|
||||
@@ -379,9 +382,10 @@ export const useFirebaseAuthStore = defineStore('firebaseAuth', () => {
|
||||
if (isCloud) {
|
||||
const additionalUserInfo = getAdditionalUserInfo(result)
|
||||
const isNewUser = additionalUserInfo?.isNewUser ?? false
|
||||
useTelemetry()?.trackAuth({
|
||||
void authEventHook.trigger({
|
||||
event: isNewUser ? 'register' : 'login',
|
||||
method: 'github',
|
||||
is_new_user: isNewUser
|
||||
isNewUser
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user