Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@flagship.io/react-sdk",
"sideEffects": false,
"version": "5.2.2",
"version": "5.2.3",
"license": "Apache-2.0",
"description": "Flagship REACT SDK",
"main": "dist/src/index.js",
Expand Down Expand Up @@ -32,7 +32,7 @@
}
},
"dependencies": {
"@flagship.io/js-sdk": "^5.1.7",
"@flagship.io/js-sdk": "^5.2.0",
"encoding": "^0.1.13"
},
"peerDependencies": {
Expand Down
22 changes: 19 additions & 3 deletions src/FlagshipProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,16 @@ export function FlagshipProvider({
// eslint-disable-next-line @typescript-eslint/no-explicit-any
decisionMode: decisionMode as any,
fetchNow: configRef.current.fetchNow,
onSdkStatusChanged: (...args) => handleSdkStatusChangeRef.current(...args),
onSdkStatusChanged: (...args) =>
handleSdkStatusChangeRef.current(...args),
onBucketingUpdated: (...args) =>
handleBucketingUpdateRef.current(...args),
hitDeduplicationTime: configRef.current.hitDeduplicationTime,
language: configRef.current.language,
sdkVersion: configRef.current.sdkVersion,
...propsRef.current,
});
}, [envId, apiKey, decisionMode]);
}, [envId, apiKey, decisionMode, props.isQAModeEnabled]);

const updateFlagshipVisitor = useCallback((): void => {
if (
Expand Down Expand Up @@ -274,7 +275,12 @@ export function FlagshipProvider({

const handleDisplay = useMemo((): ReactNode => {
const isFirstInit = !flagshipState.visitor;
if (flagshipState.isInitializing && loadingComponent && isFirstInit && fetchNow) {
if (
flagshipState.isInitializing &&
loadingComponent &&
isFirstInit &&
fetchNow
) {
return <>{loadingComponent}</>;
}
return <>{children}</>;
Expand Down Expand Up @@ -303,6 +309,16 @@ export function FlagshipProvider({
INTERNAL_EVENTS.FsTriggerRendering,
handleForcedVariations,
);

globalThis.__abTastyOnTriggerRender__ = (arg: {
forcedReFetchFlags: boolean;
}) => {
const event = {
detail: arg,
} as CustomEvent<{ forcedReFetchFlags: boolean }>;
handleForcedVariations(event);
};

return () =>
window?.removeEventListener?.(
INTERNAL_EVENTS.FsTriggerRendering,
Expand Down
2 changes: 1 addition & 1 deletion src/sdkVersion.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
// Generated by genversion.
export const version = '5.2.2'
export const version = '5.2.3'
8 changes: 8 additions & 0 deletions src/type.local.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@



declare global {
var __abTastyOnTriggerRender__: ((arg:{forcedReFetchFlags:boolean})=>void)|undefined
}

export {};

Check warning on line 8 in src/type.local.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

export statement without specifiers is not allowed.

See more on https://sonarcloud.io/project/issues?id=flagship-io_flagship-react-sdk&issues=AZ0lFGlu7Lq6732f1ZTW&open=AZ0lFGlu7Lq6732f1ZTW&pullRequest=140
1 change: 1 addition & 0 deletions src/type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,3 +176,4 @@ export type UseFlagshipOutput = {
collectEAIEventsAsync(): Promise<void>;
};


105 changes: 105 additions & 0 deletions test/FlagshipProvider.integration.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -607,6 +607,111 @@
})
})

describe('globalThis.__abTastyOnTriggerRender__', () => {
it('should set globalThis.__abTastyOnTriggerRender__ on mount', async () => {
mockNewVisitor.mockReturnValue(createMockVisitor() as any)

render(
<FlagshipProvider
envId={envId}
apiKey={apiKey}
visitorData={createVisitorData()}
fetchNow={false}
>
<div>Test</div>
</FlagshipProvider>
)

await waitFor(() => {
expect(globalThis.__abTastyOnTriggerRender__).toBeDefined()
expect(typeof globalThis.__abTastyOnTriggerRender__).toBe('function')
})
})

it('should call fetchFlags when forcedReFetchFlags is true', async () => {
const fetchFlagsFn = jest.fn()
const mockVisitor = createMockVisitor({ fetchFlags: fetchFlagsFn })
mockNewVisitor.mockReturnValue(mockVisitor as any)

render(
<FlagshipProvider
envId={envId}
apiKey={apiKey}
visitorData={createVisitorData()}
fetchNow={false}
>
<div>Test</div>
</FlagshipProvider>
)

await waitFor(() => {
expect(mockNewVisitor).toHaveBeenCalled()
})

act(() => {
globalThis.__abTastyOnTriggerRender__!({ forcedReFetchFlags: true })
})

expect(fetchFlagsFn).toHaveBeenCalled()
})

it('should toggle forced variations when forcedReFetchFlags is false', async () => {
const fetchFlagsFn = jest.fn()
const mockVisitor = createMockVisitor({ fetchFlags: fetchFlagsFn })
mockNewVisitor.mockReturnValue(mockVisitor as any)

render(
<FlagshipProvider
envId={envId}
apiKey={apiKey}
visitorData={createVisitorData()}
fetchNow={false}
>
<div>Test</div>
</FlagshipProvider>
)

await waitFor(() => {
expect(mockNewVisitor).toHaveBeenCalled()
})

act(() => {
globalThis.__abTastyOnTriggerRender__?.({ forcedReFetchFlags: false })
})

expect(fetchFlagsFn).not.toHaveBeenCalled()
})

it('should clean up globalThis.__abTastyOnTriggerRender__ handler on unmount by removing event listener', async () => {
const removeEventListenerSpy = jest.spyOn(window, 'removeEventListener')

Check warning on line 686 in test/FlagshipProvider.integration.test.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `globalThis` over `window`.

See more on https://sonarcloud.io/project/issues?id=flagship-io_flagship-react-sdk&issues=AZ0lFGnk7Lq6732f1ZTX&open=AZ0lFGnk7Lq6732f1ZTX&pullRequest=140
mockNewVisitor.mockReturnValue(createMockVisitor() as any)

const { unmount } = render(
<FlagshipProvider
envId={envId}
apiKey={apiKey}
visitorData={createVisitorData()}
fetchNow={false}
>
<div>Test</div>
</FlagshipProvider>
)

await waitFor(() => {
expect(mockNewVisitor).toHaveBeenCalled()
})

unmount()

expect(removeEventListenerSpy).toHaveBeenCalledWith(
'FS_TRIGGER_RENDERING',
expect.any(Function)
)

removeEventListenerSpy.mockRestore()
})
})

describe('Context Deep Equality', () => {
it('should not recreate visitor when context reference changes but content is same', async () => {
const mockVisitor = createMockVisitor({ visitorId: 'visitor1' })
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1659,15 +1659,15 @@ __metadata:
languageName: node
linkType: hard

"@flagship.io/js-sdk@npm:^5.1.7":
version: 5.1.7
resolution: "@flagship.io/js-sdk@npm:5.1.7"
"@flagship.io/js-sdk@npm:^5.2.0":
version: 5.2.0
resolution: "@flagship.io/js-sdk@npm:5.2.0"
dependencies:
events: "npm:^3.3.0"
follow-redirects: "npm:^1.15.9"
node-abort-controller: "npm:^3.1.1"
node-fetch: "npm:^2.6.7"
checksum: 10c0/b8dedcb22bb1300f4b8c4495bbdadeb3be341c399ff66e9e8c2f31cd1eb946817fd079403dca84cd7ca3bb0af8499f2808ffde14f5317058ae9f81f614879a16
checksum: 10c0/cb11aebae792fb02dd892603f4b7cfe2f93ecf289578637095a2c68bab53a4c1e468f5bce8837af4b1696a6a2d0c12f2e3181417fe9f7cf7512f84fd8df0cd40
languageName: node
linkType: hard

Expand All @@ -1682,7 +1682,7 @@ __metadata:
"@babel/preset-react": "npm:^7.24.1"
"@babel/preset-typescript": "npm:^7.24.1"
"@eslint/js": "npm:^9.23.0"
"@flagship.io/js-sdk": "npm:^5.1.7"
"@flagship.io/js-sdk": "npm:^5.2.0"
"@testing-library/dom": "npm:^10.1.0"
"@testing-library/jest-dom": "npm:^6.4.2"
"@testing-library/react": "npm:^16.0.0"
Expand Down
Loading