From 104938f534407337fde0f3e4548e8027796159ac Mon Sep 17 00:00:00 2001 From: Alexandre Philibeaux Date: Mon, 21 Jul 2025 09:53:42 +0200 Subject: [PATCH] fix(analytics): add timeout option --- package.json | 1 + .../src/analytics/useAnalytics.tsx | 25 +++++----- pnpm-lock.yaml | 49 +++++++++++++++++++ pnpm-workspace.yaml | 1 + 4 files changed, 62 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 906f03c56..44e386f7e 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@rudderstack/analytics-js": "catalog:", "@scaleway/eslint-config-react": "workspace:*", "@scaleway/tsconfig": "workspace:*", + "@scaleway/use-segment": "catalog:", "@testing-library/jest-dom": "catalog:", "@testing-library/react": "catalog:", "@types/jest": "catalog:", diff --git a/packages/use-analytics/src/analytics/useAnalytics.tsx b/packages/use-analytics/src/analytics/useAnalytics.tsx index d1317d6d4..5ee9d31eb 100644 --- a/packages/use-analytics/src/analytics/useAnalytics.tsx +++ b/packages/use-analytics/src/analytics/useAnalytics.tsx @@ -6,14 +6,9 @@ import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect' import { destSDKBaseURL, pluginsSDKBaseURL } from '../constants' import type { CategoryKind } from '../types' import { defaultConsentOptions, defaultLoadOptions } from './constants' -import { trackLink } from './segments/trackLink' -import type { TrackLink } from './segments/trackLink' import { userMigrationsTraits } from './segments/userMigrationsTraits' -type Analytics = RudderAnalytics & { - trackLink: TrackLink -} - +type Analytics = RudderAnalytics export type { Analytics } export type OnEventError = (error: Error) => Promise | void @@ -51,7 +46,6 @@ export type AnalyticsProviderProps = { settings?: { writeKey: string cdnURL: string - timeout: number } loadOptions?: LoadOptions @@ -60,9 +54,10 @@ export type AnalyticsProviderProps = { */ shouldRenderOnlyWhenReady?: boolean /** - * used with shouldRenderOnlyWhenReady can blocked rendering until consent the first time. + * used with shouldRenderOnlyWhenReady can blocked rendering until consent the first time. You can also set a timeout to prevent blocking indefinitely. */ needConsent?: boolean + timeout?: number allowedConsents: CategoryKind[] deniedConsents: CategoryKind[] onError?: (err: Error) => void @@ -87,6 +82,7 @@ export function AnalyticsProvider({ deniedConsents, events, onLoaded, + timeout, }: AnalyticsProviderProps) { const [isAnalyticsReady, setIsAnalyticsReady] = useState(false) const [internalAnalytics, setAnalytics] = useState( @@ -96,9 +92,10 @@ export function AnalyticsProvider({ // This effect will unlock the case where we have a failure with the load of the analytics.load as rudderstack doesn't provider any solution for this case. useEffect(() => { let timer: ReturnType | undefined - if (!isAnalyticsReady && !internalAnalytics && settings?.timeout) { + if (!isAnalyticsReady && !internalAnalytics && timeout) { if (shouldRenderOnlyWhenReady) { - timer = setTimeout(() => setIsAnalyticsReady(true), settings.timeout) + timer = setTimeout(() => setIsAnalyticsReady(true), timeout) + onError?.(new Error('Analytics Setup Timeout')) } } @@ -110,7 +107,8 @@ export function AnalyticsProvider({ internalAnalytics, setIsAnalyticsReady, shouldRenderOnlyWhenReady, - settings?.timeout, + timeout, + onError, ]) const shouldLoad = useMemo(() => { @@ -150,12 +148,11 @@ export function AnalyticsProvider({ }) analytics.ready(() => { - // @ts-expect-error tracklink is added to the analytics setup to simplify migration from segment, should be remove. - setAnalytics({ ...analytics, trackLink: trackLink(analytics) }) + setAnalytics(analytics) setIsAnalyticsReady(true) }) } - }, [onError, settings, loadOptions, shouldLoad]) + }, [settings, loadOptions, shouldLoad]) const value = useMemo>(() => { const curiedEvents = Object.entries(events).reduce( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9cbd6554d..ae364e3ec 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -63,6 +63,9 @@ catalogs: '@rudderstack/analytics-js': specifier: 3.21.0 version: 3.21.0 + '@scaleway/use-segment': + specifier: 1.1.11 + version: 1.1.11 '@segment/analytics-next': specifier: 1.81.1 version: 1.81.1 @@ -269,6 +272,9 @@ importers: '@scaleway/tsconfig': specifier: workspace:* version: link:packages/tsconfig + '@scaleway/use-segment': + specifier: 'catalog:' + version: 1.1.11(react@19.1.0) '@testing-library/jest-dom': specifier: 'catalog:' version: 6.6.3 @@ -1971,12 +1977,24 @@ packages: '@rudderstack/analytics-js@3.21.0': resolution: {integrity: sha512-pj6ck9pHsgVW65R5BqzimDpUvEP0sM4GycJtqMoXV0tshDC6iG7Hp0p7OWoc/CljUSMSBmsg36xI+AauGQGn6A==} + '@scaleway/use-segment@1.1.11': + resolution: {integrity: sha512-Xs7oOwGf1zt4GbRqzvyEYKf7IYZmjWdFtuC94QdlO11XxpRruQ21JvC/Tw0BjoDfmzs0XJ8gXBwejHUBKMYZng==} + engines: {node: '>=20.x'} + peerDependencies: + react: 18.x || 19.x + + '@segment/analytics-core@1.8.1': + resolution: {integrity: sha512-EYcdBdhfi1pOYRX+Sf5orpzzYYFmDHTEu6+w0hjXpW5bWkWct+Nv6UJg1hF4sGDKEQjpZIinLTpQ4eioFM4KeQ==} + '@segment/analytics-core@1.8.2': resolution: {integrity: sha512-5FDy6l8chpzUfJcNlIcyqYQq4+JTUynlVoCeCUuVz+l+6W0PXg+ljKp34R4yLVCcY5VVZohuW+HH0VLWdwYVAg==} '@segment/analytics-generic-utils@1.2.0': resolution: {integrity: sha512-DfnW6mW3YQOLlDQQdR89k4EqfHb0g/3XvBXkovH1FstUN93eL1kfW9CsDcVQyH3bAC5ZsFyjA/o/1Q2j0QeoWw==} + '@segment/analytics-next@1.81.0': + resolution: {integrity: sha512-N267sNhJKGCviRAs/uQCC5TuP73WVDnd8xBDrsUHvM1J4qdDkSXT+KsoQbveQZV2fFUoLypuZ6nBP/MC5unTvg==} + '@segment/analytics-next@1.81.1': resolution: {integrity: sha512-nVHNhriViptjkp4004qBbvmnW9/3brjhBv2P5Cvcg7iWW41fBzUY8FbLi+8wkmSbycT9fH1pTM3TUxB6+h0Fcg==} @@ -6590,6 +6608,21 @@ snapshots: '@rudderstack/analytics-js@3.21.0': {} + '@scaleway/use-segment@1.1.11(react@19.1.0)': + dependencies: + '@segment/analytics-next': 1.81.0 + react: 19.1.0 + use-deep-compare-effect: 1.8.1(react@19.1.0) + transitivePeerDependencies: + - encoding + + '@segment/analytics-core@1.8.1': + dependencies: + '@lukeed/uuid': 2.0.1 + '@segment/analytics-generic-utils': 1.2.0 + dset: 3.1.4 + tslib: 2.8.1 + '@segment/analytics-core@1.8.2': dependencies: '@lukeed/uuid': 2.0.1 @@ -6601,6 +6634,22 @@ snapshots: dependencies: tslib: 2.8.1 + '@segment/analytics-next@1.81.0': + dependencies: + '@lukeed/uuid': 2.0.1 + '@segment/analytics-core': 1.8.1 + '@segment/analytics-generic-utils': 1.2.0 + '@segment/analytics-page-tools': 1.0.0 + '@segment/analytics.js-video-plugins': 0.2.1 + '@segment/facade': 3.4.10 + dset: 3.1.4 + js-cookie: 3.0.1 + node-fetch: 2.7.0 + tslib: 2.8.1 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + '@segment/analytics-next@1.81.1': dependencies: '@lukeed/uuid': 2.0.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3a826aa8f..75c79896e 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -21,6 +21,7 @@ catalog: '@formatjs/icu-messageformat-parser': 2.11.2 '@growthbook/growthbook-react': 1.6.0 '@rudderstack/analytics-js': 3.21.0 + '@scaleway/use-segment': 1.1.11 '@segment/analytics-next': 1.81.1 '@stylistic/eslint-plugin': 4.4.1 '@testing-library/jest-dom': 6.6.3