refactor(web): migrate telemetry + diagnostics to createWebTelemetry/createWebDiagnostics

- telemetry.ts: 54 → 42 lines via createWebTelemetry() (keeps product-specific trackTimerEvent)
- diagnostics.ts: 53 → 22 lines via createWebDiagnostics()
- 394/394 web tests pass, typecheck clean
This commit is contained in:
saravanakumardb1 2026-03-20 18:54:11 -07:00
parent bc735dfdb9
commit f2450b6e2e
2 changed files with 26 additions and 69 deletions

View File

@ -3,51 +3,20 @@
// Polls platform-service for active debug sessions targeting this install. // Polls platform-service for active debug sessions targeting this install.
// Privacy: only captures console logs + JS errors when a session is active. // Privacy: only captures console logs + JS errors when a session is active.
import { DiagnosticsClient } from '@bytelyst/diagnostics-client'; import { createWebDiagnostics } from '@bytelyst/diagnostics-client';
import { getAuthClient, PRODUCT_ID, getBaseUrl } from './auth-api'; import { getAuthClient, PRODUCT_ID, getBaseUrl } from './auth-api';
function getOrCreateInstallId(): string { const { init: initDiagnostics, stop: stopDiagnostics } = createWebDiagnostics({
const key = `${PRODUCT_ID}_diag_install_id`; productId: PRODUCT_ID,
let id = localStorage.getItem(key); channel: 'pwa',
if (!id) { serverUrl: getBaseUrl(),
id = getAuthToken: () => {
typeof crypto?.randomUUID === 'function' const token = getAuthClient().getAccessToken();
? crypto.randomUUID() if (!token) throw new Error('unauthenticated');
: Math.random().toString(36).slice(2) + Date.now().toString(36); return token;
localStorage.setItem(key, id); },
} releaseChannel: 'beta',
return id; captureConsole: true,
} });
export function initDiagnostics(): void { export { initDiagnostics, stopDiagnostics };
if (typeof window === 'undefined') return;
DiagnosticsClient.getInstance({
productId: PRODUCT_ID,
anonymousInstallId: getOrCreateInstallId(),
platform: 'web',
channel: 'pwa',
osFamily: 'unknown',
appVersion: process.env.NEXT_PUBLIC_APP_VERSION ?? '0.1.0',
buildNumber: process.env.NEXT_PUBLIC_BUILD_NUMBER ?? '1',
releaseChannel: process.env.NEXT_PUBLIC_RELEASE_CHANNEL ?? 'beta',
serverUrl: getBaseUrl(),
getAuthToken: () => {
const token = getAuthClient().getAccessToken();
if (!token) throw new Error('unauthenticated');
return token;
},
captureConsole: true,
captureErrors: true,
captureNetwork: false,
pollIntervalMs: 30_000,
});
void DiagnosticsClient.getInstance().start();
}
export function stopDiagnostics(): void {
try {
DiagnosticsClient.getInstance().stop();
} catch {
// not initialized
}
}

View File

@ -2,26 +2,16 @@
// Delegates to @bytelyst/telemetry-client shared package. // Delegates to @bytelyst/telemetry-client shared package.
// Privacy: no PII, only action names + timing. // Privacy: no PII, only action names + timing.
import { createTelemetryClient, type TelemetryClient } from '@bytelyst/telemetry-client'; import { createWebTelemetry } from '@bytelyst/telemetry-client';
import { PRODUCT_ID } from './auth-api'; import { PRODUCT_ID } from './auth-api';
let _client: TelemetryClient | null = null; const webTelemetry = createWebTelemetry({
productId: PRODUCT_ID,
function getClient(): TelemetryClient { channel: 'pwa',
if (!_client) { baseUrl: process.env.NEXT_PUBLIC_PLATFORM_SERVICE_URL ?? 'https://api.chronomind.app',
_client = createTelemetryClient({ transport: 'beacon',
productId: PRODUCT_ID, releaseChannel: 'beta',
baseUrl: process.env.NEXT_PUBLIC_PLATFORM_SERVICE_URL ?? 'https://api.chronomind.app', });
platform: 'web',
channel: 'pwa',
transport: 'beacon',
appVersion: '0.1.0',
buildNumber: '1',
releaseChannel: 'beta',
});
}
return _client;
}
export function trackEvent( export function trackEvent(
eventType: 'debug' | 'info' | 'warn' | 'error', eventType: 'debug' | 'info' | 'warn' | 'error',
@ -34,21 +24,19 @@ export function trackEvent(
metrics?: Record<string, number>; metrics?: Record<string, number>;
} }
): void { ): void {
getClient().trackEvent(eventType, module, eventName, options); webTelemetry.client.trackEvent(eventType, module, eventName, options);
} }
export function trackTimerEvent(eventName: string, tags?: Record<string, string>, metrics?: Record<string, number>): void { export function trackTimerEvent(eventName: string, tags?: Record<string, string>, metrics?: Record<string, number>): void {
trackEvent('info', 'timers', eventName, { tags, metrics }); trackEvent('info', 'timers', eventName, { tags, metrics });
} }
export function trackPageView(path: string): void { export const { trackPageView } = webTelemetry;
trackEvent('info', 'navigation', 'page_view', { tags: { path } });
}
export function flush(): void { export function flush(): void {
getClient().flush(); webTelemetry.client.flush();
} }
export function initTelemetry(): void { export function initTelemetry(): void {
getClient().init(); webTelemetry.init();
} }