Skip to content

Commit

Permalink
code split
Browse files Browse the repository at this point in the history
  • Loading branch information
abvthecity committed Dec 19, 2024
1 parent b6d31d5 commit 910430e
Show file tree
Hide file tree
Showing 16 changed files with 73 additions and 74 deletions.
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/amplitude.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { init, track } from "@amplitude/analytics-browser";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function AmplitudeScript({ apiKey }: { apiKey: string }): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/datadog-rum.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { datadogRum, type RumInitConfiguration } from "@datadog/browser-rum";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function DatadogRumScript(props: RumInitConfiguration): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/fathom.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as Fathom from "fathom-client";
import { ReactNode, useEffect } from "react";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function FathomScript({ siteId }: { siteId: string }): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/fullstory.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function FullstoryScript(props: { orgId: string }): ReactNode {
useSafeListenTrackEvents(({ event, properties }) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/ga.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Head from "next/head";
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

type GAParams = {
gaId: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/gtm.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Head from "next/head";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

type GTMParams = {
gtmId: string;
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/heap.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function HeapScript({ appId }: { appId: string }): ReactNode {
useSafeListenTrackEvents(({ event, properties }) => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/hotjar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import Hotjar from "@hotjar/browser";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function HotjarScript({ id, version }: { id: string; version: string }): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/intercom.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Script from "next/script";
import { ReactElement, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

// copied from @intercom/messenger-js-sdk
interface IntercomSettings {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/koala.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function KoalaScript({ apiKey }: { apiKey: string }): ReactNode {
const user = useFernUser();
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/logrocket.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import LogRocket from "logrocket";
import { ReactNode, useEffect } from "react";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function LogRocketScript({ appId }: { appId: string }): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/mixpanel.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import mixpanel from "mixpanel-browser";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function MixpanelScript({ token }: { token: string }): ReactNode {
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/posthog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import posthog, { type PostHog } from "posthog-js";
import { ReactNode, useEffect } from "react";
import { useApiRoute, useFernUser } from "../atoms";
import { useRouteChangeComplete } from "../hooks/useRouteChanged";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

/**
* Posthog natively allows us to define additional capture objects with distinct configs on the global instance,
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/app/src/analytics/segment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as snippet from "@segment/snippet";
import Script from "next/script";
import { ReactNode, useEffect } from "react";
import { useFernUser } from "../atoms";
import { useSafeListenTrackEvents } from "./track";
import { useSafeListenTrackEvents } from "./use-track";

export function SegmentScript(props: snippet.Options): ReactNode {
const user = useFernUser();
Expand Down
64 changes: 4 additions & 60 deletions packages/ui/app/src/analytics/track.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,17 @@
import { useEffect, useRef } from "react";
import { z } from "zod";

const TRACK_EVENT_NAME = "fern-docs-track-analytics";
const TrackEventSchema = z.object({
event: z.string(),
properties: z
.record(
z.union([
z.string(),
z.number(),
z.boolean(),
z.string().array().readonly(),
z.number().array().readonly(),
z.boolean().array().readonly(),
z.undefined(),
]),
)
.optional(),
internal: z.boolean().optional(),
});

type TrackEvent = z.infer<typeof TrackEventSchema>;

/**
* Track an event.
*
* @param event - The event name.
* @param properties - The event properties.
*/
export function track(event: string, properties?: TrackEvent["properties"]): void {
export function track(event: string, properties?: Record<string, unknown>): void {
if (typeof window === "undefined") {
return;
}

window.dispatchEvent(new CustomEvent<TrackEvent>(TRACK_EVENT_NAME, { detail: { event, properties } }));
window.dispatchEvent(new CustomEvent(TRACK_EVENT_NAME, { detail: { event, properties } }));
}

/**
Expand All @@ -42,44 +20,10 @@ export function track(event: string, properties?: TrackEvent["properties"]): voi
* @param event - The event name.
* @param properties - The event properties.
*/
export function trackInternal(event: string, properties?: TrackEvent["properties"]): void {
export function trackInternal(event: string, properties?: Record<string, unknown>): void {
if (typeof window === "undefined") {
return;
}

window.dispatchEvent(
new CustomEvent<TrackEvent>(TRACK_EVENT_NAME, { detail: { event, properties, internal: true } }),
);
}

/**
* Listen for track events, and emit them to analytics integrations.
*
* @param cb - The callback to emit the event to.
* @param allowInternal - Whether to allow internal events to be emitted. Defaults to false. Only use this for Fern's internal posthog instance.
*/
export function useSafeListenTrackEvents(cb: (detail: TrackEvent) => void, allowInternal = false): void {
const ref = useRef<(detail: TrackEvent) => void>(cb);

useEffect(() => {
ref.current = cb;
});

useEffect(() => {
const handler = (event: Event) => {
try {
if (event instanceof CustomEvent) {
const detail = TrackEventSchema.safeParse(event.detail);
if (detail.success && (allowInternal || !detail.data.internal)) {
ref.current(detail.data);
}
}
} catch (error) {
// eslint-disable-next-line no-console
console.warn("Error emitting track event", error, event);
}
};
window.addEventListener(TRACK_EVENT_NAME, handler);
return () => window.removeEventListener(TRACK_EVENT_NAME, handler);
}, [allowInternal]);
window.dispatchEvent(new CustomEvent(TRACK_EVENT_NAME, { detail: { event, properties, internal: true } }));
}
55 changes: 55 additions & 0 deletions packages/ui/app/src/analytics/use-track.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { useEffect, useRef } from "react";
import { z } from "zod";

const TRACK_EVENT_NAME = "fern-docs-track-analytics";
const TrackEventSchema = z.object({
event: z.string(),
properties: z
.record(
z.union([
z.string(),
z.number(),
z.boolean(),
z.string().array().readonly(),
z.number().array().readonly(),
z.boolean().array().readonly(),
z.undefined(),
]),
)
.optional(),
internal: z.boolean().optional(),
});

type TrackEvent = z.infer<typeof TrackEventSchema>;

/**
* Listen for track events, and emit them to analytics integrations.
*
* @param cb - The callback to emit the event to.
* @param allowInternal - Whether to allow internal events to be emitted. Defaults to false. Only use this for Fern's internal posthog instance.
*/
export function useSafeListenTrackEvents(cb: (detail: TrackEvent) => void, allowInternal = false): void {
const ref = useRef<(detail: TrackEvent) => void>(cb);

useEffect(() => {
ref.current = cb;
});

useEffect(() => {
const handler = (event: Event) => {
try {
if (event instanceof CustomEvent) {
const detail = TrackEventSchema.safeParse(event.detail);
if (detail.success && (allowInternal || !detail.data.internal)) {
ref.current(detail.data);
}
}
} catch (error) {
// eslint-disable-next-line no-console
console.warn("Error emitting track event", error, event);
}
};
window.addEventListener(TRACK_EVENT_NAME, handler);
return () => window.removeEventListener(TRACK_EVENT_NAME, handler);
}, [allowInternal]);
}

0 comments on commit 910430e

Please sign in to comment.