feat(core): improve mixpanel (#7652)

move @affine/core/utils/mixpanel -> @affine/core/mixpanel

now you can debug mixpanel on browser devtool

![CleanShot 2024-07-30 at 17.32.48@2x.png](https://graphite-user-uploaded-assets-prod.s3.amazonaws.com/g3jz87HxbjOJpXV3FPT7/083c1286-39fd-4569-b4d2-e6e84cf2e797.png)
This commit is contained in:
EYHN
2024-07-30 13:22:16 +00:00
parent ea7066d02c
commit ab92efcfc0
58 changed files with 221 additions and 149 deletions
@@ -0,0 +1,23 @@
import type { PlanChangeStartedEvent } from './plan-change-started';
import type { PlanChangeSucceededEvent } from './plan-change-succeed';
export interface MixpanelEvents {
PlanChangeStarted: PlanChangeStartedEvent;
PlanChangeSucceeded: PlanChangeSucceededEvent;
OAuth: {
provider: string;
};
}
export interface GeneralMixpanelEvent {
// location
page?: string | null;
segment?: string | null;
module?: string | null;
control?: string | null;
// entity
type?: string | null;
category?: string | null;
id?: string | null;
}
@@ -0,0 +1,16 @@
import type { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
/**
* Before subscription plan changed
*/
export interface PlanChangeStartedEvent {
segment?: 'settings panel';
module?: 'pricing plan list' | 'billing subscription list';
control?:
| 'new subscription' // no subscription before
| 'cancel'
| 'paying' // resume: subscribed before
| 'plan cancel action';
type?: SubscriptionPlan;
category?: SubscriptionRecurring;
}
@@ -5,5 +5,5 @@ import type { PlanChangeStartedEvent } from './plan-change-started';
*/
export type PlanChangeSucceededEvent = Pick<
PlanChangeStartedEvent,
'control' | 'type' | 'category'
'control' | 'type' | 'category' | 'segment'
>;
+86 -5
View File
@@ -1,7 +1,88 @@
import type { PlanChangeStartedEvent } from './plan-change-started';
import type { PlanChangeSucceededEvent } from './plan-change-succeed';
import { DebugLogger } from '@affine/debug';
import type { OverridedMixpanel } from 'mixpanel-browser';
import mixpanelBrowser from 'mixpanel-browser';
export interface MixpanelEvents {
PlanChangeStarted: PlanChangeStartedEvent;
PlanChangeSucceeded: PlanChangeSucceededEvent;
import type { GeneralMixpanelEvent, MixpanelEvents } from './events';
const logger = new DebugLogger('mixpanel');
function createMixpanel() {
let mixpanel;
if (process.env.MIXPANEL_TOKEN) {
mixpanelBrowser.init(process.env.MIXPANEL_TOKEN || '', {
track_pageview: true,
persistence: 'localStorage',
api_host: 'https://telemetry.affine.run',
});
mixpanel = mixpanelBrowser;
} else {
mixpanel = new Proxy(
function () {} as unknown as OverridedMixpanel,
createProxyHandler()
);
}
const wrapped = {
reset() {
mixpanel.reset();
mixpanel.register({
appVersion: runtimeConfig.appVersion,
environment: runtimeConfig.appBuildType,
editorVersion: runtimeConfig.editorVersion,
isSelfHosted: Boolean(runtimeConfig.isSelfHosted),
isDesktop: environment.isDesktop,
});
},
track<
T extends string,
P extends (T extends keyof MixpanelEvents
? MixpanelEvents[T]
: Record<string, unknown>) &
GeneralMixpanelEvent,
>(event_name: T, properties?: P) {
logger.debug('track', event_name, properties);
mixpanel.track(event_name, properties);
},
opt_out_tracking() {
mixpanel.opt_out_tracking();
},
opt_in_tracking() {
mixpanel.opt_in_tracking();
},
has_opted_in_tracking() {
mixpanel.has_opted_in_tracking();
},
has_opted_out_tracking() {
mixpanel.has_opted_out_tracking();
},
identify(unique_id?: string) {
mixpanel.identify(unique_id);
},
get people() {
return mixpanel.people;
},
track_pageview(properties?: { location?: string }) {
logger.debug('track_pageview', properties);
mixpanel.track_pageview(properties);
},
};
wrapped.reset();
return wrapped;
}
export const mixpanel = createMixpanel();
function createProxyHandler() {
const handler = {
get: () => {
return new Proxy(
function () {} as unknown as OverridedMixpanel,
createProxyHandler()
);
},
apply: () => {},
} as ProxyHandler<OverridedMixpanel>;
return handler;
}
+19
View File
@@ -0,0 +1,19 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars, unused-imports/no-unused-imports
import * as mixpanel from 'mixpanel-browser';
import type { GeneralMixpanelEvent, MixpanelEvents } from './events';
declare module 'mixpanel-browser' {
export interface OverridedMixpanel {
track<
T extends string,
P extends (T extends keyof MixpanelEvents
? MixpanelEvents[T]
: Record<string, unknown>) &
GeneralMixpanelEvent,
>(
event_name: T,
properties?: P
): void;
}
}
@@ -1,15 +0,0 @@
import type { SubscriptionPlan, SubscriptionRecurring } from '@affine/graphql';
/**
* Before subscription plan changed
*/
export interface PlanChangeStartedEvent {
segment: 'settings panel';
module: 'pricing plan list' | 'billing subscription list';
control:
| 'new subscription' // no subscription before
| 'cancel'
| 'paying'; // resume: subscribed before
type: SubscriptionPlan;
category: SubscriptionRecurring;
}