()
| 1025 | * this preserves client state and just fetches fresh feature values. |
| 1026 | */ |
| 1027 | export async function refreshGrowthBookFeatures(): Promise<void> { |
| 1028 | if (!isGrowthBookEnabled()) { |
| 1029 | return |
| 1030 | } |
| 1031 | |
| 1032 | try { |
| 1033 | const growthBookClient = await initializeGrowthBook() |
| 1034 | if (!growthBookClient) { |
| 1035 | return |
| 1036 | } |
| 1037 | |
| 1038 | await growthBookClient.refreshFeatures() |
| 1039 | |
| 1040 | // Guard: if this client was replaced during the in-flight refresh |
| 1041 | // (e.g. refreshGrowthBookAfterAuthChange ran), skip processing the |
| 1042 | // stale payload. Mirrors the init-callback guard above. |
| 1043 | if (growthBookClient !== client) { |
| 1044 | if (process.env.USER_TYPE === 'ant') { |
| 1045 | logForDebugging( |
| 1046 | 'GrowthBook: Skipping refresh processing for replaced client', |
| 1047 | ) |
| 1048 | } |
| 1049 | return |
| 1050 | } |
| 1051 | |
| 1052 | // Rebuild remoteEvalFeatureValues from the refreshed payload so that |
| 1053 | // _BLOCKS_ON_INIT callers (e.g. getMaxVersion for the auto-update kill |
| 1054 | // switch) see fresh values, not the stale init-time snapshot. |
| 1055 | const hadFeatures = await processRemoteEvalPayload(growthBookClient) |
| 1056 | // Same re-check as init path: covers the setPayload yield inside |
| 1057 | // processRemoteEvalPayload (the guard above only covers refreshFeatures). |
| 1058 | if (growthBookClient !== client) return |
| 1059 | |
| 1060 | if (process.env.USER_TYPE === 'ant') { |
| 1061 | logForDebugging('GrowthBook: Light refresh completed') |
| 1062 | } |
| 1063 | |
| 1064 | // Gate on hadFeatures: if the payload was empty/malformed, |
| 1065 | // remoteEvalFeatureValues wasn't rebuilt — skip both the no-op disk |
| 1066 | // write and the spurious subscriber churn (clearCommandMemoizationCaches |
| 1067 | // + getCommands + 4× model re-renders). |
| 1068 | if (hadFeatures) { |
| 1069 | syncRemoteEvalToDisk() |
| 1070 | refreshed.emit() |
| 1071 | } |
| 1072 | } catch (error) { |
| 1073 | if (process.env.NODE_ENV === 'development') { |
| 1074 | throw error |
| 1075 | } |
| 1076 | logError(toError(error)) |
| 1077 | } |
| 1078 | } |
| 1079 | |
| 1080 | /** |
| 1081 | * Set up periodic refresh of GrowthBook features. |
no test coverage detected