From 7664c0f0a861d9f0d6f1d657c7621d02f3e9b50a Mon Sep 17 00:00:00 2001 From: Alexandre Philibeaux Date: Tue, 8 Aug 2023 13:42:52 +0200 Subject: [PATCH] fix(growthbook): types --- .changeset/witty-carrots-impress.md | 5 ++ .../use-growthbook/src/AbTestProvider.tsx | 47 ++++++++++--------- .../src/__tests__/AbTestProvider.tsx | 14 ++++-- packages/use-growthbook/src/index.ts | 11 +++-- packages/use-growthbook/src/types.ts | 21 +++++---- .../use-growthbook/src/useAbTestAttributes.ts | 2 +- 6 files changed, 58 insertions(+), 42 deletions(-) create mode 100644 .changeset/witty-carrots-impress.md diff --git a/.changeset/witty-carrots-impress.md b/.changeset/witty-carrots-impress.md new file mode 100644 index 000000000..f22c957d4 --- /dev/null +++ b/.changeset/witty-carrots-impress.md @@ -0,0 +1,5 @@ +--- +'@scaleway/use-growthbook': patch +--- + +add loadfeature configuration into the providers and moove return function from null to void diff --git a/packages/use-growthbook/src/AbTestProvider.tsx b/packages/use-growthbook/src/AbTestProvider.tsx index 0dd815eeb..229b6c135 100644 --- a/packages/use-growthbook/src/AbTestProvider.tsx +++ b/packages/use-growthbook/src/AbTestProvider.tsx @@ -2,12 +2,10 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-expect-error TODO: remove once Growthbook is correctly typed and export import { GrowthBook, GrowthBookProvider } from '@growthbook/growthbook-react' -import type { ReactNode } from 'react' -import { useCallback, useEffect, useMemo } from 'react' -import type { GrowthBookType } from './types' +import { type ReactNode, useCallback, useEffect, useMemo } from 'react' +import type { Attributes, GrowthBookType, LoadConfig } from './types' export type ToolConfig = { apiHost: string @@ -18,57 +16,60 @@ export type ToolConfig = { export type TrackingCallback = ( experiment: { key: string }, result: { key: string }, -) => null +) => void + +// TODO: use type from growthbook when it's typed will be export correctly +// export type TrackingCallback = NonNullable export type AbTestProviderProps = { children: ReactNode - anonymousId: string config: ToolConfig trackingCallback: TrackingCallback - errorCallback: (error: string) => null + errorCallback: (error: Error | string) => void + attributes: Attributes + loadConfig?: LoadConfig } const getGrowthBookInstance = ({ config: { apiHost, clientKey, enableDevMode }, - anonymousId, + attributes, trackingCallback, }: { config: ToolConfig - anonymousId: string + attributes: Attributes trackingCallback: TrackingCallback }): GrowthBookType => new GrowthBook({ apiHost, clientKey, enableDevMode, - attributes: { - anonymousId, - userId: undefined, - organizationId: undefined, - organizationType: undefined, - }, + attributes, trackingCallback, }) + +const defaultLoadConfig = { + autoRefresh: false, + timeout: 500, +} + export const AbTestProvider = ({ children, config, - anonymousId, trackingCallback, errorCallback, + attributes, + loadConfig = defaultLoadConfig, }: AbTestProviderProps) => { const growthbook: GrowthBookType = useMemo( - () => getGrowthBookInstance({ config, anonymousId, trackingCallback }), - [trackingCallback, config, anonymousId], + () => getGrowthBookInstance({ config, attributes, trackingCallback }), + [trackingCallback, config, attributes], ) const loadFeature = useCallback(async () => { if (config.clientKey) { - await growthbook.loadFeatures({ - autoRefresh: false, - timeout: 500, - }) + await growthbook.loadFeatures(loadConfig) } - }, [growthbook, config]) + }, [growthbook, config, loadConfig]) useEffect(() => { loadFeature().catch(errorCallback) diff --git a/packages/use-growthbook/src/__tests__/AbTestProvider.tsx b/packages/use-growthbook/src/__tests__/AbTestProvider.tsx index 16c2efda8..573c08323 100644 --- a/packages/use-growthbook/src/__tests__/AbTestProvider.tsx +++ b/packages/use-growthbook/src/__tests__/AbTestProvider.tsx @@ -10,7 +10,7 @@ const mockGrowthBook = GrowthBook as jest.MockedClass describe('AbTestProvider', () => { let trackingCallback: TrackingCallback - let errorCallback: (error: string) => null + let errorCallback: (error: Error | string) => void beforeEach(() => { trackingCallback = jest.fn() @@ -19,16 +19,18 @@ describe('AbTestProvider', () => { it('should init GrowthBook once', () => { render( - Foo + Children , ) @@ -39,16 +41,18 @@ describe('AbTestProvider', () => { it('should not init GrowthBook when client key is not defined', () => { render( - Foo + Children , ) diff --git a/packages/use-growthbook/src/index.ts b/packages/use-growthbook/src/index.ts index 445b618dd..1feaa7ceb 100644 --- a/packages/use-growthbook/src/index.ts +++ b/packages/use-growthbook/src/index.ts @@ -1,8 +1,4 @@ -// eslint-disable-next-line @typescript-eslint/ban-ts-comment export { - FeatureString, - FeaturesReady, - IfFeatureEnabled, useExperiment, useFeature, withRunExperiment, @@ -10,5 +6,12 @@ export { useFeatureValue, // @ts-expect-error TODO: remove once Growthbook is correctly typed and export } from '@growthbook/growthbook-react' +export type { + FeatureString, + FeaturesReady, + IfFeatureEnabled, + Context, + // @ts-expect-error TODO: remove once Growthbook is correctly typed and export +} from '@growthbook/growthbook-react' export { useAbTestAttributes } from './useAbTestAttributes' export { AbTestProvider } from './AbTestProvider' diff --git a/packages/use-growthbook/src/types.ts b/packages/use-growthbook/src/types.ts index 259eae32e..88961ead8 100644 --- a/packages/use-growthbook/src/types.ts +++ b/packages/use-growthbook/src/types.ts @@ -1,14 +1,17 @@ -export type Attributes = Record +export type Attributes = Record + +/** + * @param {boolean} [autoRefresh] - false. + * @param {number} [timeout] - 500. + */ +export type LoadConfig = { + autoRefresh: boolean + timeout: number +} export type GrowthBookType = { new (...args: unknown[]): GrowthBookType getAttributes: () => Attributes - loadFeatures: ({ - autoRefresh, - timeout, - }: { - autoRefresh: boolean - timeout: number - }) => Promise - setAttributes: (attributes: Attributes) => null + loadFeatures: ({ autoRefresh, timeout }: LoadConfig) => Promise + setAttributes: (attributes: Attributes) => void } diff --git a/packages/use-growthbook/src/useAbTestAttributes.ts b/packages/use-growthbook/src/useAbTestAttributes.ts index 226b07a00..3cafb4319 100644 --- a/packages/use-growthbook/src/useAbTestAttributes.ts +++ b/packages/use-growthbook/src/useAbTestAttributes.ts @@ -8,7 +8,7 @@ import type { Attributes, GrowthBookType } from './types' export const useAbTestAttributes = (): [ Attributes, - (attributes: Attributes) => null | undefined, + (attributes: Attributes) => void, ] => { const growthBook = useGrowthBook() as GrowthBookType | null