Skip to content

Commit

Permalink
feat: add onFlowUpdate option (#209)
Browse files Browse the repository at this point in the history
  • Loading branch information
VojtechVidra authored Oct 18, 2024
1 parent 338fb9a commit f68b761
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 1 deletion.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@
"husky": "^9.1.6",
"prettier": "^3.3.3"
},
"packageManager": "pnpm@9.6.0"
"packageManager": "pnpm@9.12.2"
}
22 changes: 22 additions & 0 deletions workspaces/js/src/core/flow-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { DebugEvent, Flow, FlowStep, FlowStepIndex, TrackingEvent } from ".
import { hash } from "../lib/hash";
import { isModalStep, isTooltipStep } from "../lib/step-type";
import { log } from "../lib/log";
import { getPathname } from "../lib/location";
import { render } from "./render";
import type { FlowsContext } from "./flows-context";

Expand Down Expand Up @@ -42,6 +43,7 @@ export class FlowState {
(i) => i.flowId === flowId,
);
if (!flowAlreadyRunning) void this.track({ type: "startFlow" });
this.onFlowUpdate();
this.enterStep();
}

Expand All @@ -62,9 +64,25 @@ export class FlowState {
stepIndex: this.step,
stepHash: this.currentStep ? await hash(JSON.stringify(this.currentStep)) : undefined,
flowHash: await hash(JSON.stringify(this.flow)),
stepId: this.currentStep?.stepId,
...props,
});
}
onFlowUpdate({ end }: { end?: boolean } = {}): void {
const prevStepIndex = this.stepHistory.at(-2);
const prevStep =
this.flow && prevStepIndex !== undefined
? getStep({ flow: this.flow, step: prevStepIndex })
: undefined;
const currentStep = this.currentStep;
this.flowsContext.onFlowUpdate?.({
flowId: this.flowId,
location: getPathname(),
currentStep: end ? undefined : currentStep,
prevStep: end ? currentStep : prevStep,
});
}

async debug(
props: Pick<DebugEvent, "type" | "referenceId" | "targetElement">,
): Promise<{ referenceId: string } | undefined> {
Expand Down Expand Up @@ -134,6 +152,7 @@ export class FlowState {

if (this.currentStep) this.flowsContext.onNextStep?.(this.currentStep);
void this.track({ type: "nextStep" });
this.onFlowUpdate();
return this;
}
get hasNextStep(): boolean {
Expand Down Expand Up @@ -166,6 +185,7 @@ export class FlowState {
this.stepHistory = this.stepHistory.slice(0, -1);
if (this.currentStep) this.flowsContext.onPrevStep?.(this.currentStep);
void this.track({ type: "prevStep" });
this.onFlowUpdate();
return this;
}
get hasPrevStep(): boolean {
Expand Down Expand Up @@ -206,13 +226,15 @@ export class FlowState {

cancel(): this {
void this.track({ type: "cancelFlow" });
this.onFlowUpdate({ end: true });
this.flowsContext.flowSeen(this.flowId);
this.unmount();
return this;
}

finish(): this {
void this.track({ type: "finishFlow" });
this.onFlowUpdate({ end: true });
this.flowsContext.flowSeen(this.flowId);
this.unmount();
return this;
Expand Down
3 changes: 3 additions & 0 deletions workspaces/js/src/core/flows-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import type {
DebugEvent,
IdentifyUserOptions,
SeenFlow,
OnFlowUpdate,
} from "../types";
import { log } from "../lib/log";
import { getPersistentState, setPersistentState } from "../lib/persistent-state";
Expand Down Expand Up @@ -95,6 +96,7 @@ export class FlowsContext {
flowsById?: Record<string, Flow>;
onNextStep?: (step: FlowStep) => void;
onPrevStep?: (step: FlowStep) => void;
onFlowUpdate?: OnFlowUpdate;
tracking?: Tracking;
debug?: Debug;
onSeenFlowsChange?: (seenFlows: SeenFlow[]) => void;
Expand All @@ -107,6 +109,7 @@ export class FlowsContext {
this.projectId = options.projectId;
this.onNextStep = options.onNextStep;
this.onPrevStep = options.onPrevStep;
this.onFlowUpdate = options.onFlowUpdate;
this.tracking = options.tracking;
this.debug = options._debug;
this.seenFlows = options.seenFlows ? [...options.seenFlows] : this.seenFlows;
Expand Down
32 changes: 32 additions & 0 deletions workspaces/js/src/types/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,37 @@ export interface TrackingEvent {
* - "/search?query=foo" - Query params are included
*/
location: string;
/**
* Current step ID.
*/
stepId?: string;
}
export type Tracking = (event: TrackingEvent) => void;

export interface OnFlowUpdateProps {
/**
* Previous step that user was on. Undefined if the flow has just started.
*/
prevStep?: FlowStep;
/**
* The current step that user is on. Undefined if the flow has ended.
*/
currentStep?: FlowStep;
/**
* The flow ID that the step belongs to.
*/
flowId: string;
/**
* Browser location
* @example
* - "/" - Root
* - "/checkout"
* - "/search?query=foo" - Query params are included
*/
location: string;
}
export type OnFlowUpdate = (props: OnFlowUpdateProps) => void;

export interface DebugEvent extends Omit<TrackingEvent, "type"> {
type: "tooltipError" | "invalidateTooltipError" | "invalidStepError";
/**
Expand Down Expand Up @@ -81,6 +109,10 @@ export interface FlowsOptions extends IdentifyUserOptions {
* Method to be called when the user goes back to a previous step.
*/
onPrevStep?: (step: FlowStep) => void;
/**
* Method to be called when a flow is started, ended or its step changes.
*/
onFlowUpdate?: OnFlowUpdate;
/**
* Method for integrating 3rd party tracking tools. When using Flows Cloud, this is automatically managed.
*/
Expand Down

0 comments on commit f68b761

Please sign in to comment.