This change ensures that each analytics service is initialized immediately after it is created. By calling the `initialize` method on the service, we ensure all necessary setup steps are performed. This prevents potential issues related to uninitialized service use.
98 lines
2.4 KiB
TypeScript
98 lines
2.4 KiB
TypeScript
import { NullAnalyticsService } from './null-analytics-service';
|
|
import type {
|
|
AnalyticsManager,
|
|
AnalyticsService,
|
|
CreateAnalyticsManagerOptions,
|
|
} from './types';
|
|
|
|
export function createAnalyticsManager<T extends string, Config extends object>(
|
|
options: CreateAnalyticsManagerOptions<T, Config>,
|
|
): AnalyticsManager {
|
|
const activeServices = new Map<T, AnalyticsService>();
|
|
|
|
const getActiveServices = (): AnalyticsService[] => {
|
|
if (activeServices.size === 0) {
|
|
console.debug(
|
|
'No active analytics services. Using NullAnalyticsService.',
|
|
);
|
|
|
|
return [NullAnalyticsService];
|
|
}
|
|
|
|
return Array.from(activeServices.values());
|
|
};
|
|
|
|
const registerActiveServices = (
|
|
options: CreateAnalyticsManagerOptions<T, Config>,
|
|
) => {
|
|
Object.keys(options.providers).forEach((provider) => {
|
|
const providerKey = provider as keyof typeof options.providers;
|
|
const factory = options.providers[providerKey];
|
|
|
|
if (!factory) {
|
|
console.warn(
|
|
`Analytics provider '${provider}' not registered. Skipping initialization.`,
|
|
);
|
|
|
|
return;
|
|
}
|
|
|
|
const service = factory();
|
|
activeServices.set(provider as T, service);
|
|
|
|
void service.initialize();
|
|
});
|
|
};
|
|
|
|
registerActiveServices(options);
|
|
|
|
return {
|
|
addProvider: (
|
|
provider: T,
|
|
config: Config,
|
|
) => {
|
|
const factory = options.providers[provider];
|
|
|
|
if (!factory) {
|
|
console.warn(
|
|
`Analytics provider '${provider}' not registered. Skipping initialization.`,
|
|
);
|
|
|
|
return Promise.resolve();
|
|
}
|
|
|
|
const service = factory(config);
|
|
activeServices.set(provider, service);
|
|
|
|
return service.initialize();
|
|
},
|
|
|
|
removeProvider: (provider: T) => {
|
|
activeServices.delete(provider);
|
|
},
|
|
|
|
identify: (userId: string, traits?: Record<string, string>) => {
|
|
return Promise.all(
|
|
getActiveServices().map((service) => service.identify(userId, traits)),
|
|
);
|
|
},
|
|
|
|
trackPageView: (url: string) => {
|
|
return Promise.all(
|
|
getActiveServices().map((service) => service.trackPageView(url)),
|
|
);
|
|
},
|
|
|
|
trackEvent: (
|
|
eventName: string,
|
|
eventProperties?: Record<string, string | string[]>,
|
|
) => {
|
|
return Promise.all(
|
|
getActiveServices().map((service) =>
|
|
service.trackEvent(eventName, eventProperties),
|
|
),
|
|
);
|
|
},
|
|
};
|
|
}
|