Skip to content

Commit 9d1bfd9

Browse files
committed
fix: improve survey bundle size
1 parent 9b9c658 commit 9d1bfd9

File tree

4 files changed

+107
-135
lines changed

4 files changed

+107
-135
lines changed

src/entrypoints/surveys-preview.es.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
export { renderFeedbackWidgetPreview, renderSurveysPreview } from '../extensions/surveys'
2-
export { getNextSurveyStep } from '../posthog-surveys'
1+
export { getNextSurveyStep, renderFeedbackWidgetPreview, renderSurveysPreview } from '../extensions/surveys'

src/extensions/surveys.tsx

+104-12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,109 @@ const logger = createLogger('[Surveys]')
4444
const window = _window as Window & typeof globalThis
4545
const document = _document as Document
4646

47+
function getRatingBucketForResponseValue(responseValue: number, scale: number) {
48+
if (scale === 3) {
49+
if (responseValue < 1 || responseValue > 3) {
50+
throw new Error('The response must be in range 1-3')
51+
}
52+
53+
return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'
54+
} else if (scale === 5) {
55+
if (responseValue < 1 || responseValue > 5) {
56+
throw new Error('The response must be in range 1-5')
57+
}
58+
59+
return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'
60+
} else if (scale === 7) {
61+
if (responseValue < 1 || responseValue > 7) {
62+
throw new Error('The response must be in range 1-7')
63+
}
64+
65+
return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'
66+
} else if (scale === 10) {
67+
if (responseValue < 0 || responseValue > 10) {
68+
throw new Error('The response must be in range 0-10')
69+
}
70+
71+
return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'
72+
}
73+
74+
throw new Error('The scale must be one of: 3, 5, 7, 10')
75+
}
76+
77+
export function getNextSurveyStep(
78+
survey: Survey,
79+
currentQuestionIndex: number,
80+
response: string | string[] | number | null
81+
) {
82+
const question = survey.questions[currentQuestionIndex]
83+
const nextQuestionIndex = currentQuestionIndex + 1
84+
85+
if (!question.branching?.type) {
86+
if (currentQuestionIndex === survey.questions.length - 1) {
87+
return SurveyQuestionBranchingType.End
88+
}
89+
90+
return nextQuestionIndex
91+
}
92+
93+
if (question.branching.type === SurveyQuestionBranchingType.End) {
94+
return SurveyQuestionBranchingType.End
95+
} else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {
96+
if (Number.isInteger(question.branching.index)) {
97+
return question.branching.index
98+
}
99+
} else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {
100+
// Single choice
101+
if (question.type === SurveyQuestionType.SingleChoice) {
102+
// :KLUDGE: for now, look up the choiceIndex based on the response
103+
// TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method
104+
const selectedChoiceIndex = question.choices.indexOf(`${response}`)
105+
106+
if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {
107+
const nextStep = question.branching.responseValues[selectedChoiceIndex]
108+
109+
// Specific question
110+
if (Number.isInteger(nextStep)) {
111+
return nextStep
112+
}
113+
114+
if (nextStep === SurveyQuestionBranchingType.End) {
115+
return SurveyQuestionBranchingType.End
116+
}
117+
118+
return nextQuestionIndex
119+
}
120+
} else if (question.type === SurveyQuestionType.Rating) {
121+
if (typeof response !== 'number' || !Number.isInteger(response)) {
122+
throw new Error('The response type must be an integer')
123+
}
124+
125+
const ratingBucket = getRatingBucketForResponseValue(response, question.scale)
126+
127+
if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {
128+
const nextStep = question.branching.responseValues[ratingBucket]
129+
130+
// Specific question
131+
if (Number.isInteger(nextStep)) {
132+
return nextStep
133+
}
134+
135+
if (nextStep === SurveyQuestionBranchingType.End) {
136+
return SurveyQuestionBranchingType.End
137+
}
138+
139+
return nextQuestionIndex
140+
}
141+
}
142+
143+
return nextQuestionIndex
144+
}
145+
146+
logger.warn('Falling back to next question index due to unexpected branching type')
147+
return nextQuestionIndex
148+
}
149+
47150
export class SurveyManager {
48151
private posthog: PostHog
49152
private surveyInFocus: string | null
@@ -663,18 +766,7 @@ export function Questions({
663766

664767
setQuestionsResponses({ ...questionsResponses, [responseKey]: res })
665768

666-
// Old SDK, no branching
667-
if (!posthog.getNextSurveyStep) {
668-
const isLastDisplayedQuestion = displayQuestionIndex === survey.questions.length - 1
669-
if (isLastDisplayedQuestion) {
670-
sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)
671-
} else {
672-
setCurrentQuestionIndex(displayQuestionIndex + 1)
673-
}
674-
return
675-
}
676-
677-
const nextStep = posthog.getNextSurveyStep(survey, displayQuestionIndex, res)
769+
const nextStep = getNextSurveyStep(survey, displayQuestionIndex, res)
678770
if (nextStep === SurveyQuestionBranchingType.End) {
679771
sendSurveyEvent({ ...questionsResponses, [responseKey]: res }, survey, posthog)
680772
} else {

src/posthog-core.ts

+1-10
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ import { PageViewManager } from './page-view'
5252
import { PostHogSurveys } from './posthog-surveys'
5353
import { RateLimiter } from './rate-limiter'
5454
import { uuidv7 } from './uuidv7'
55-
import { Survey, SurveyCallback, SurveyQuestionBranchingType } from './posthog-surveys-types'
55+
import { SurveyCallback } from './posthog-surveys-types'
5656
import {
5757
isArray,
5858
isEmptyObject,
@@ -1341,15 +1341,6 @@ export class PostHog {
13411341
this.surveys.canRenderSurvey(surveyId)
13421342
}
13431343

1344-
/** Get the next step of the survey: a question index or `end` */
1345-
getNextSurveyStep(
1346-
survey: Survey,
1347-
currentQuestionIndex: number,
1348-
response: string | string[] | number | null
1349-
): number | SurveyQuestionBranchingType.End {
1350-
return this.surveys.getNextSurveyStep(survey, currentQuestionIndex, response)
1351-
}
1352-
13531344
/**
13541345
* Identify a user with a unique ID instead of a PostHog
13551346
* randomly generated distinct_id. If the method is never called,

src/posthog-surveys.ts

+1-111
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,7 @@
11
import { SURVEYS } from './constants'
22
import { getSurveySeenStorageKeys } from './extensions/surveys/surveys-utils'
33
import { PostHog } from './posthog-core'
4-
import {
5-
Survey,
6-
SurveyCallback,
7-
SurveyMatchType,
8-
SurveyQuestionBranchingType,
9-
SurveyQuestionType,
10-
} from './posthog-surveys-types'
4+
import { Survey, SurveyCallback, SurveyMatchType } from './posthog-surveys-types'
115
import { RemoteConfig } from './types'
126
import { Info } from './utils/event-utils'
137
import { assignableWindow, document, userAgent, window } from './utils/globals'
@@ -32,109 +26,6 @@ export const surveyValidationMap: Record<SurveyMatchType, (targets: string[], va
3226
is_not: (targets, value) => targets.every((target) => value !== target),
3327
}
3428

35-
function getRatingBucketForResponseValue(responseValue: number, scale: number) {
36-
if (scale === 3) {
37-
if (responseValue < 1 || responseValue > 3) {
38-
throw new Error('The response must be in range 1-3')
39-
}
40-
41-
return responseValue === 1 ? 'negative' : responseValue === 2 ? 'neutral' : 'positive'
42-
} else if (scale === 5) {
43-
if (responseValue < 1 || responseValue > 5) {
44-
throw new Error('The response must be in range 1-5')
45-
}
46-
47-
return responseValue <= 2 ? 'negative' : responseValue === 3 ? 'neutral' : 'positive'
48-
} else if (scale === 7) {
49-
if (responseValue < 1 || responseValue > 7) {
50-
throw new Error('The response must be in range 1-7')
51-
}
52-
53-
return responseValue <= 3 ? 'negative' : responseValue === 4 ? 'neutral' : 'positive'
54-
} else if (scale === 10) {
55-
if (responseValue < 0 || responseValue > 10) {
56-
throw new Error('The response must be in range 0-10')
57-
}
58-
59-
return responseValue <= 6 ? 'detractors' : responseValue <= 8 ? 'passives' : 'promoters'
60-
}
61-
62-
throw new Error('The scale must be one of: 3, 5, 7, 10')
63-
}
64-
65-
export function getNextSurveyStep(
66-
survey: Survey,
67-
currentQuestionIndex: number,
68-
response: string | string[] | number | null
69-
) {
70-
const question = survey.questions[currentQuestionIndex]
71-
const nextQuestionIndex = currentQuestionIndex + 1
72-
73-
if (!question.branching?.type) {
74-
if (currentQuestionIndex === survey.questions.length - 1) {
75-
return SurveyQuestionBranchingType.End
76-
}
77-
78-
return nextQuestionIndex
79-
}
80-
81-
if (question.branching.type === SurveyQuestionBranchingType.End) {
82-
return SurveyQuestionBranchingType.End
83-
} else if (question.branching.type === SurveyQuestionBranchingType.SpecificQuestion) {
84-
if (Number.isInteger(question.branching.index)) {
85-
return question.branching.index
86-
}
87-
} else if (question.branching.type === SurveyQuestionBranchingType.ResponseBased) {
88-
// Single choice
89-
if (question.type === SurveyQuestionType.SingleChoice) {
90-
// :KLUDGE: for now, look up the choiceIndex based on the response
91-
// TODO: once QuestionTypes.MultipleChoiceQuestion is refactored, pass the selected choiceIndex into this method
92-
const selectedChoiceIndex = question.choices.indexOf(`${response}`)
93-
94-
if (question.branching?.responseValues?.hasOwnProperty(selectedChoiceIndex)) {
95-
const nextStep = question.branching.responseValues[selectedChoiceIndex]
96-
97-
// Specific question
98-
if (Number.isInteger(nextStep)) {
99-
return nextStep
100-
}
101-
102-
if (nextStep === SurveyQuestionBranchingType.End) {
103-
return SurveyQuestionBranchingType.End
104-
}
105-
106-
return nextQuestionIndex
107-
}
108-
} else if (question.type === SurveyQuestionType.Rating) {
109-
if (typeof response !== 'number' || !Number.isInteger(response)) {
110-
throw new Error('The response type must be an integer')
111-
}
112-
113-
const ratingBucket = getRatingBucketForResponseValue(response, question.scale)
114-
115-
if (question.branching?.responseValues?.hasOwnProperty(ratingBucket)) {
116-
const nextStep = question.branching.responseValues[ratingBucket]
117-
118-
// Specific question
119-
if (Number.isInteger(nextStep)) {
120-
return nextStep
121-
}
122-
123-
if (nextStep === SurveyQuestionBranchingType.End) {
124-
return SurveyQuestionBranchingType.End
125-
}
126-
127-
return nextQuestionIndex
128-
}
129-
}
130-
131-
return nextQuestionIndex
132-
}
133-
134-
logger.warn('Falling back to next question index due to unexpected branching type')
135-
return nextQuestionIndex
136-
}
137-
13829
function defaultMatchType(matchType?: SurveyMatchType): SurveyMatchType {
13930
return matchType ?? 'icontains'
14031
}
@@ -375,7 +266,6 @@ export class PostHogSurveys {
375266
return this.instance.featureFlags.isFeatureEnabled(value)
376267
})
377268
}
378-
getNextSurveyStep = getNextSurveyStep
379269

380270
// this method is lazily loaded onto the window to avoid loading preact and other dependencies if surveys is not enabled
381271
private _canActivateRepeatedly(survey: Survey) {

0 commit comments

Comments
 (0)