ChemPal Documentation - v1.15.1
    Preparing search index...
    • Subscribes to the search-lifecycle event bus and forwards it to PostHog, keeping analytics out of the search hook itself (the producers stay decoupled from consumers). Mirrors the useBadgeController hook.

      • SearchEvent.STARTED → search_query (with the search term)
      • SearchEvent.COMPLETED → search_results, or search_terminated when the stream only drained because the search was aborted
      • SearchEvent.ABORTED / SearchEvent.FAILED → search_terminated

      A search that ended early reports search_terminated instead of search_results, so the duration and result-count distributions on search_results describe complete runs only. Mount once, near the app root.

      Returns void

      Nothing.

      function App() {
      useSearchAnalytics();
      // ...
      }
      export function useSearchAnalytics(): void {
      useEffect(() => {
      // Remember the most recent started query so the terminal events (which carry
      // only the outcome) can attach the term to their event.
      let lastQuery = '';
      const unsubscribers = [
      onSearchEvent(SearchEvent.STARTED, ({ query }) => {
      lastQuery = query.trim();
      void trackEvent('search_query', { search_term: lastQuery });
      }),
      onSearchEvent(SearchEvent.COMPLETED, ({ abortReason, ...outcome }) => {
      const params = outcomeParams(outcome, lastQuery);
      if (abortReason === undefined) {
      void trackEvent('search_results', params);
      return;
      }
      void trackEvent('search_terminated', { ...params, reason: abortReason });
      }),
      onSearchEvent(SearchEvent.ABORTED, ({ reason, ...outcome }) => {
      void trackEvent('search_terminated', {
      ...outcomeParams(outcome, lastQuery),
      reason: reason ?? 'unknown',
      });
      }),
      onSearchEvent(SearchEvent.FAILED, ({ error, ...outcome }) => {
      void trackEvent('search_terminated', {
      ...outcomeParams(outcome, lastQuery),
      reason: 'error',
      ...(error ? { error_message: error } : {}),
      });
      }),
      ];
      return () => {
      for (const unsubscribe of unsubscribers) unsubscribe();
      };
      }, []);
      }