@lifeaz/lors-helper 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/main.d.ts +159 -3
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +218 -9
- package/package.json +3 -3
- package/src/main.ts +466 -11
package/README.md
CHANGED
package/dist/main.d.ts
CHANGED
|
@@ -516,6 +516,7 @@ export declare const CartSchema: z.ZodObject<{
|
|
|
516
516
|
locale: z.ZodUnion<readonly [z.ZodLiteral<"fr">, z.ZodLiteral<"en">, z.ZodLiteral<"nl">, z.ZodLiteral<"de">, z.ZodLiteral<"it">, z.ZodLiteral<"es">, z.ZodLiteral<"pt">, z.ZodLiteral<"pl">]>;
|
|
517
517
|
vatNumber: z.ZodNullable<z.ZodString>;
|
|
518
518
|
multiAddressesCallback: z.ZodBoolean;
|
|
519
|
+
simulated: z.ZodDefault<z.ZodBoolean>;
|
|
519
520
|
partnerId: z.ZodNullable<z.ZodCustom<UUID, UUID>>;
|
|
520
521
|
createdAt: z.ZodCustom<Dayjs, Dayjs>;
|
|
521
522
|
updatedAt: z.ZodCustom<Dayjs, Dayjs>;
|
|
@@ -818,8 +819,8 @@ export type MvtDevice = '_Mobile_' | '_Tablet_' | '_Desktop_';
|
|
|
818
819
|
export declare const MvtDeviceSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Mobile_">, z.ZodLiteral<"_Tablet_">, z.ZodLiteral<"_Desktop_">]>;
|
|
819
820
|
export type MvtNodeKind = '_And_' | '_Or_' | '_Not_' | '_Leaf_';
|
|
820
821
|
export declare const MvtNodeKindSchema: z.ZodUnion<readonly [z.ZodLiteral<"_And_">, z.ZodLiteral<"_Or_">, z.ZodLiteral<"_Not_">, z.ZodLiteral<"_Leaf_">]>;
|
|
821
|
-
export type MvtOperator = '_Device_In_' | '_Lang_In_' | '_Country_In_' | '_Profile_In_' | '_Partner_In_' | '_Partner_Absent_' | '_Campaign_Seen_' | '_Campaign_Not_Seen_' | '_Visitor_Is_New_' | '_Visitor_Is_Returning_' | '_Utm_Source_In_' | '_Utm_Medium_In_' | '_Utm_Campaign_In_' | '_Referrer_Matches_' | '_Path_Matches_' | '_Has_Cart_' | '_Hour_Of_Day_Between_' | '_Day_Of_Week_In_';
|
|
822
|
-
export declare const MvtOperatorSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Device_In_">, z.ZodLiteral<"_Lang_In_">, z.ZodLiteral<"_Country_In_">, z.ZodLiteral<"_Profile_In_">, z.ZodLiteral<"_Partner_In_">, z.ZodLiteral<"_Partner_Absent_">, z.ZodLiteral<"_Campaign_Seen_">, z.ZodLiteral<"_Campaign_Not_Seen_">, z.ZodLiteral<"_Visitor_Is_New_">, z.ZodLiteral<"_Visitor_Is_Returning_">, z.ZodLiteral<"_Utm_Source_In_">, z.ZodLiteral<"_Utm_Medium_In_">, z.ZodLiteral<"_Utm_Campaign_In_">, z.ZodLiteral<"_Referrer_Matches_">, z.ZodLiteral<"_Path_Matches_">, z.ZodLiteral<"_Has_Cart_">, z.ZodLiteral<"_Hour_Of_Day_Between_">, z.ZodLiteral<"_Day_Of_Week_In_">]>;
|
|
822
|
+
export type MvtOperator = '_Device_In_' | '_Lang_In_' | '_Country_In_' | '_Profile_In_' | '_Partner_In_' | '_Partner_Absent_' | '_Campaign_Seen_' | '_Campaign_Not_Seen_' | '_Visitor_Is_New_' | '_Visitor_Is_Returning_' | '_Utm_Source_In_' | '_Utm_Medium_In_' | '_Utm_Campaign_In_' | '_Referrer_Matches_' | '_Path_Matches_' | '_Has_Cart_' | '_Hour_Of_Day_Between_' | '_Day_Of_Week_In_' | '_Query_Param_Matches_' | '_Screen_Width_Between_' | '_Visits_At_Least_' | '_Logged_In_' | '_Logged_Out_' | '_Is_Weekend_' | '_Date_Between_';
|
|
823
|
+
export declare const MvtOperatorSchema: z.ZodUnion<readonly [z.ZodLiteral<"_Device_In_">, z.ZodLiteral<"_Lang_In_">, z.ZodLiteral<"_Country_In_">, z.ZodLiteral<"_Profile_In_">, z.ZodLiteral<"_Partner_In_">, z.ZodLiteral<"_Partner_Absent_">, z.ZodLiteral<"_Campaign_Seen_">, z.ZodLiteral<"_Campaign_Not_Seen_">, z.ZodLiteral<"_Visitor_Is_New_">, z.ZodLiteral<"_Visitor_Is_Returning_">, z.ZodLiteral<"_Utm_Source_In_">, z.ZodLiteral<"_Utm_Medium_In_">, z.ZodLiteral<"_Utm_Campaign_In_">, z.ZodLiteral<"_Referrer_Matches_">, z.ZodLiteral<"_Path_Matches_">, z.ZodLiteral<"_Has_Cart_">, z.ZodLiteral<"_Hour_Of_Day_Between_">, z.ZodLiteral<"_Day_Of_Week_In_">, z.ZodLiteral<"_Query_Param_Matches_">, z.ZodLiteral<"_Screen_Width_Between_">, z.ZodLiteral<"_Visits_At_Least_">, z.ZodLiteral<"_Logged_In_">, z.ZodLiteral<"_Logged_Out_">, z.ZodLiteral<"_Is_Weekend_">, z.ZodLiteral<"_Date_Between_">]>;
|
|
823
824
|
export declare const MVT_NULLARY_OPERATORS: readonly MvtOperator[];
|
|
824
825
|
export type MvtOverrideOp = 'set' | 'merge' | 'remove' | 'reorder' | 'insert' | 'patch';
|
|
825
826
|
export declare const MvtOverrideOpSchema: z.ZodUnion<readonly [z.ZodLiteral<"set">, z.ZodLiteral<"merge">, z.ZodLiteral<"remove">, z.ZodLiteral<"reorder">, z.ZodLiteral<"insert">, z.ZodLiteral<"patch">]>;
|
|
@@ -857,8 +858,19 @@ export declare const MvtVariantSchema: z.ZodObject<{
|
|
|
857
858
|
equals: z.ZodString;
|
|
858
859
|
}, z.core.$strip>>;
|
|
859
860
|
}, z.core.$strip>>;
|
|
861
|
+
audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
|
|
862
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
863
|
+
color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
864
|
+
description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
860
865
|
}, z.core.$strip>;
|
|
861
866
|
export type MvtVariant = z.infer<typeof MvtVariantSchema>;
|
|
867
|
+
export type MvtAllocationMode = '_Targeted_' | '_Weighted_' | '_Unreachable_';
|
|
868
|
+
export interface MvtAllocationRow {
|
|
869
|
+
key: string;
|
|
870
|
+
mode: MvtAllocationMode;
|
|
871
|
+
weight: number;
|
|
872
|
+
sharePct: number;
|
|
873
|
+
}
|
|
862
874
|
export declare const MvtExperimentSchema: z.ZodObject<{
|
|
863
875
|
id: z.ZodCustom<UUID, UUID>;
|
|
864
876
|
key: z.ZodString;
|
|
@@ -891,6 +903,10 @@ export declare const MvtExperimentSchema: z.ZodObject<{
|
|
|
891
903
|
equals: z.ZodString;
|
|
892
904
|
}, z.core.$strip>>;
|
|
893
905
|
}, z.core.$strip>>;
|
|
906
|
+
audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
|
|
907
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
908
|
+
color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
909
|
+
description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
894
910
|
}, z.core.$strip>>;
|
|
895
911
|
}, z.core.$strip>;
|
|
896
912
|
export type MvtExperiment = z.infer<typeof MvtExperimentSchema>;
|
|
@@ -929,6 +945,10 @@ export declare const MvtConfigSchema: z.ZodObject<{
|
|
|
929
945
|
equals: z.ZodString;
|
|
930
946
|
}, z.core.$strip>>;
|
|
931
947
|
}, z.core.$strip>>;
|
|
948
|
+
audience: z.ZodDefault<z.ZodNullable<z.ZodType<MvtAudienceNode, unknown, z.core.$ZodTypeInternals<MvtAudienceNode, unknown>>>>;
|
|
949
|
+
order: z.ZodDefault<z.ZodNumber>;
|
|
950
|
+
color: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
951
|
+
description: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
932
952
|
}, z.core.$strip>>;
|
|
933
953
|
}, z.core.$strip>>;
|
|
934
954
|
}, z.core.$strip>;
|
|
@@ -951,7 +971,14 @@ export interface MvtContext {
|
|
|
951
971
|
hasCart: boolean;
|
|
952
972
|
firstSeenAt: number;
|
|
953
973
|
now: number;
|
|
974
|
+
query: Record<string, string>;
|
|
975
|
+
screenWidth: number;
|
|
976
|
+
visits: number;
|
|
977
|
+
loggedIn: boolean;
|
|
954
978
|
}
|
|
979
|
+
export declare function mvtNormalizeContext(context: Partial<MvtContext> & {
|
|
980
|
+
unitId: string;
|
|
981
|
+
}): MvtContext;
|
|
955
982
|
export interface MvtDecision {
|
|
956
983
|
experimentKey: string;
|
|
957
984
|
experimentId: UUID;
|
|
@@ -963,7 +990,8 @@ export interface MvtDecision {
|
|
|
963
990
|
export declare function mvtHash(input: string): number;
|
|
964
991
|
export declare function mvtBucket(salt: string, unitId: string, namespace?: string): number;
|
|
965
992
|
export declare function mvtIsEligibleForTraffic(experiment: MvtExperiment, unitId: string): boolean;
|
|
966
|
-
export declare function mvtPickVariant(experiment: MvtExperiment, unitId: string): MvtVariant | null;
|
|
993
|
+
export declare function mvtPickVariant(experiment: MvtExperiment, unitId: string, context?: MvtContext): MvtVariant | null;
|
|
994
|
+
export declare function mvtDistribution(variants: readonly MvtVariant[]): MvtAllocationRow[];
|
|
967
995
|
export declare function mvtEvaluateAudience(node: MvtAudienceNode | null, context: MvtContext): boolean;
|
|
968
996
|
export declare function mvtIsWithinWindow(experiment: MvtExperiment, now: number): boolean;
|
|
969
997
|
export declare function mvtIsLive(experiment: MvtExperiment, now: number): boolean;
|
|
@@ -989,6 +1017,37 @@ export interface MvtSlotDefinition {
|
|
|
989
1017
|
itemKey?: string;
|
|
990
1018
|
schema: z.ZodType<unknown>;
|
|
991
1019
|
}
|
|
1020
|
+
export declare const MvtAnchorPatchSchema: z.ZodObject<{
|
|
1021
|
+
hidden: z.ZodOptional<z.ZodBoolean>;
|
|
1022
|
+
order: z.ZodOptional<z.ZodNumber>;
|
|
1023
|
+
text: z.ZodOptional<z.ZodRecord<z.ZodUnion<readonly [z.ZodLiteral<"fr">, z.ZodLiteral<"en">, z.ZodLiteral<"nl">, z.ZodLiteral<"de">, z.ZodLiteral<"it">, z.ZodLiteral<"es">, z.ZodLiteral<"pt">, z.ZodLiteral<"pl">]> & z.core.$partial, z.ZodString>>;
|
|
1024
|
+
href: z.ZodOptional<z.ZodString>;
|
|
1025
|
+
route: z.ZodOptional<z.ZodString>;
|
|
1026
|
+
image: z.ZodOptional<z.ZodString>;
|
|
1027
|
+
style: z.ZodOptional<z.ZodObject<{
|
|
1028
|
+
background: z.ZodOptional<z.ZodString>;
|
|
1029
|
+
color: z.ZodOptional<z.ZodString>;
|
|
1030
|
+
borderColor: z.ZodOptional<z.ZodString>;
|
|
1031
|
+
borderRadius: z.ZodOptional<z.ZodNumber>;
|
|
1032
|
+
fontSize: z.ZodOptional<z.ZodNumber>;
|
|
1033
|
+
fontWeight: z.ZodOptional<z.ZodEnum<{
|
|
1034
|
+
300: "300";
|
|
1035
|
+
400: "400";
|
|
1036
|
+
500: "500";
|
|
1037
|
+
600: "600";
|
|
1038
|
+
700: "700";
|
|
1039
|
+
800: "800";
|
|
1040
|
+
}>>;
|
|
1041
|
+
align: z.ZodOptional<z.ZodEnum<{
|
|
1042
|
+
left: "left";
|
|
1043
|
+
center: "center";
|
|
1044
|
+
right: "right";
|
|
1045
|
+
}>>;
|
|
1046
|
+
paddingY: z.ZodOptional<z.ZodNumber>;
|
|
1047
|
+
paddingX: z.ZodOptional<z.ZodNumber>;
|
|
1048
|
+
}, z.core.$strip>>;
|
|
1049
|
+
}, z.core.$strip>;
|
|
1050
|
+
export type MvtAnchorPatch = z.infer<typeof MvtAnchorPatchSchema>;
|
|
992
1051
|
export declare const MVT_SLOTS: readonly MvtSlotDefinition[];
|
|
993
1052
|
export declare function mvtSlot(key: string): MvtSlotDefinition | null;
|
|
994
1053
|
export declare function mvtSlotsForScope(scope: MvtScope): MvtSlotDefinition[];
|
|
@@ -999,4 +1058,101 @@ export interface MvtOverrideIssue {
|
|
|
999
1058
|
}
|
|
1000
1059
|
export declare function mvtValidateOverrides(overrides: MvtOverride[]): MvtOverrideIssue[];
|
|
1001
1060
|
export declare function mvtApplyOverride<T>(base: T, override: MvtOverride): T;
|
|
1061
|
+
export declare const MVT_ANCHOR_ATTRIBUTE = "data-mvt-anchor";
|
|
1062
|
+
export declare function mvtAnchorsSlot(scope: MvtScope): string;
|
|
1063
|
+
export declare function mvtMergeAnchorPatch(base: MvtAnchorPatch | undefined, next: MvtAnchorPatch | undefined): MvtAnchorPatch;
|
|
1064
|
+
export declare function mvtAnchorStyle(patch: MvtAnchorPatch | null | undefined): Record<string, string>;
|
|
1065
|
+
export declare const MVT_STUDIO_PROTOCOL = 2;
|
|
1066
|
+
export type MvtStudioAnchorRole = 'section' | 'cta' | 'text' | 'image' | 'block';
|
|
1067
|
+
export interface MvtStudioAnchor {
|
|
1068
|
+
id: string;
|
|
1069
|
+
label: string;
|
|
1070
|
+
role: MvtStudioAnchorRole;
|
|
1071
|
+
parentId: string | null;
|
|
1072
|
+
order: number;
|
|
1073
|
+
text: string | null;
|
|
1074
|
+
movable: boolean;
|
|
1075
|
+
hideable: boolean;
|
|
1076
|
+
rect: {
|
|
1077
|
+
top: number;
|
|
1078
|
+
left: number;
|
|
1079
|
+
width: number;
|
|
1080
|
+
height: number;
|
|
1081
|
+
};
|
|
1082
|
+
}
|
|
1083
|
+
export interface MvtStudioLink {
|
|
1084
|
+
path: string;
|
|
1085
|
+
label: string;
|
|
1086
|
+
kind: 'link' | 'step';
|
|
1087
|
+
reachable: boolean;
|
|
1088
|
+
}
|
|
1089
|
+
export interface MvtStudioCart {
|
|
1090
|
+
reference: string;
|
|
1091
|
+
secret: string;
|
|
1092
|
+
step: string;
|
|
1093
|
+
simulated: true;
|
|
1094
|
+
}
|
|
1095
|
+
export type MvtStudioRequest = {
|
|
1096
|
+
protocol: number;
|
|
1097
|
+
type: 'studio:hello';
|
|
1098
|
+
} | {
|
|
1099
|
+
protocol: number;
|
|
1100
|
+
type: 'studio:scan';
|
|
1101
|
+
} | {
|
|
1102
|
+
protocol: number;
|
|
1103
|
+
type: 'studio:select';
|
|
1104
|
+
anchorId: string | null;
|
|
1105
|
+
} | {
|
|
1106
|
+
protocol: number;
|
|
1107
|
+
type: 'studio:apply';
|
|
1108
|
+
anchors: Record<string, MvtAnchorPatch>;
|
|
1109
|
+
lang: string;
|
|
1110
|
+
} | {
|
|
1111
|
+
protocol: number;
|
|
1112
|
+
type: 'studio:mode';
|
|
1113
|
+
picking: boolean;
|
|
1114
|
+
} | {
|
|
1115
|
+
protocol: number;
|
|
1116
|
+
type: 'studio:navigate';
|
|
1117
|
+
path: string;
|
|
1118
|
+
} | {
|
|
1119
|
+
protocol: number;
|
|
1120
|
+
type: 'studio:links';
|
|
1121
|
+
} | {
|
|
1122
|
+
protocol: number;
|
|
1123
|
+
type: 'studio:cart';
|
|
1124
|
+
cart: MvtStudioCart;
|
|
1125
|
+
};
|
|
1126
|
+
export type MvtStudioEvent = {
|
|
1127
|
+
protocol: number;
|
|
1128
|
+
type: 'studio:ready';
|
|
1129
|
+
scope: MvtScope;
|
|
1130
|
+
path: string;
|
|
1131
|
+
langs: string[];
|
|
1132
|
+
} | {
|
|
1133
|
+
protocol: number;
|
|
1134
|
+
type: 'studio:anchors';
|
|
1135
|
+
anchors: MvtStudioAnchor[];
|
|
1136
|
+
path: string;
|
|
1137
|
+
} | {
|
|
1138
|
+
protocol: number;
|
|
1139
|
+
type: 'studio:picked';
|
|
1140
|
+
anchor: MvtStudioAnchor;
|
|
1141
|
+
} | {
|
|
1142
|
+
protocol: number;
|
|
1143
|
+
type: 'studio:navigated';
|
|
1144
|
+
path: string;
|
|
1145
|
+
} | {
|
|
1146
|
+
protocol: number;
|
|
1147
|
+
type: 'studio:links';
|
|
1148
|
+
links: MvtStudioLink[];
|
|
1149
|
+
path: string;
|
|
1150
|
+
} | {
|
|
1151
|
+
protocol: number;
|
|
1152
|
+
type: 'studio:cart';
|
|
1153
|
+
cart: MvtStudioCart | null;
|
|
1154
|
+
};
|
|
1155
|
+
export declare function mvtCollectLinks(root: ParentNode, origin: string): MvtStudioLink[];
|
|
1156
|
+
export declare function mvtIsStudioEvent(data: unknown): data is MvtStudioEvent;
|
|
1157
|
+
export declare function mvtIsStudioRequest(data: unknown): data is MvtStudioRequest;
|
|
1002
1158
|
//# sourceMappingURL=main.d.ts.map
|
package/dist/main.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":"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"}
|
package/dist/main.js
CHANGED
|
@@ -272,6 +272,7 @@ export const CartSchema = z.object({
|
|
|
272
272
|
locale: LangSchema,
|
|
273
273
|
vatNumber: z.string().nullable(),
|
|
274
274
|
multiAddressesCallback: z.boolean(),
|
|
275
|
+
simulated: z.boolean().default(false),
|
|
275
276
|
partnerId: uuidSchema.nullable(),
|
|
276
277
|
createdAt: dayjsSchema,
|
|
277
278
|
updatedAt: dayjsSchema,
|
|
@@ -493,12 +494,22 @@ export const MvtOperatorSchema = z.union([
|
|
|
493
494
|
z.literal('_Has_Cart_'),
|
|
494
495
|
z.literal('_Hour_Of_Day_Between_'),
|
|
495
496
|
z.literal('_Day_Of_Week_In_'),
|
|
497
|
+
z.literal('_Query_Param_Matches_'),
|
|
498
|
+
z.literal('_Screen_Width_Between_'),
|
|
499
|
+
z.literal('_Visits_At_Least_'),
|
|
500
|
+
z.literal('_Logged_In_'),
|
|
501
|
+
z.literal('_Logged_Out_'),
|
|
502
|
+
z.literal('_Is_Weekend_'),
|
|
503
|
+
z.literal('_Date_Between_'),
|
|
496
504
|
]);
|
|
497
505
|
export const MVT_NULLARY_OPERATORS = [
|
|
498
506
|
'_Partner_Absent_',
|
|
499
507
|
'_Visitor_Is_New_',
|
|
500
508
|
'_Visitor_Is_Returning_',
|
|
501
509
|
'_Has_Cart_',
|
|
510
|
+
'_Logged_In_',
|
|
511
|
+
'_Logged_Out_',
|
|
512
|
+
'_Is_Weekend_',
|
|
502
513
|
];
|
|
503
514
|
export const MvtOverrideOpSchema = z.union([z.literal('set'), z.literal('merge'), z.literal('remove'), z.literal('reorder'), z.literal('insert'), z.literal('patch')]);
|
|
504
515
|
export const MvtOverrideSchema = z.object({
|
|
@@ -521,6 +532,10 @@ export const MvtVariantSchema = z.object({
|
|
|
521
532
|
weight: z.number().int().nonnegative(),
|
|
522
533
|
control: z.boolean(),
|
|
523
534
|
overrides: z.array(MvtOverrideSchema),
|
|
535
|
+
audience: MvtAudienceNodeSchema.nullable().default(null),
|
|
536
|
+
order: z.number().int().default(0),
|
|
537
|
+
color: z.string().nullable().default(null),
|
|
538
|
+
description: z.string().nullable().default(null),
|
|
524
539
|
});
|
|
525
540
|
export const MvtExperimentSchema = z.object({
|
|
526
541
|
id: uuidSchema,
|
|
@@ -545,6 +560,27 @@ export const MvtConfigSchema = z.object({
|
|
|
545
560
|
enabled: z.boolean(),
|
|
546
561
|
experiments: z.array(MvtExperimentSchema),
|
|
547
562
|
});
|
|
563
|
+
export function mvtNormalizeContext(context) {
|
|
564
|
+
return {
|
|
565
|
+
device: '_Desktop_',
|
|
566
|
+
lang: 'fr',
|
|
567
|
+
country: null,
|
|
568
|
+
profile: null,
|
|
569
|
+
partner: null,
|
|
570
|
+
seen: {},
|
|
571
|
+
utm: { source: null, medium: null, campaign: null },
|
|
572
|
+
referrer: null,
|
|
573
|
+
path: '/',
|
|
574
|
+
hasCart: false,
|
|
575
|
+
firstSeenAt: Date.now(),
|
|
576
|
+
now: Date.now(),
|
|
577
|
+
query: {},
|
|
578
|
+
screenWidth: 0,
|
|
579
|
+
visits: 1,
|
|
580
|
+
loggedIn: false,
|
|
581
|
+
...context,
|
|
582
|
+
};
|
|
583
|
+
}
|
|
548
584
|
const MVT_RETURNING_AFTER_MS = 30 * 60 * 1000;
|
|
549
585
|
export function mvtHash(input) {
|
|
550
586
|
let hash = 0x811c9dc5;
|
|
@@ -564,19 +600,42 @@ export function mvtIsEligibleForTraffic(experiment, unitId) {
|
|
|
564
600
|
return false;
|
|
565
601
|
return mvtBucket(experiment.salt, unitId, 'traffic') < experiment.trafficPct * 100;
|
|
566
602
|
}
|
|
567
|
-
export function mvtPickVariant(experiment, unitId) {
|
|
568
|
-
const
|
|
569
|
-
|
|
570
|
-
|
|
603
|
+
export function mvtPickVariant(experiment, unitId, context) {
|
|
604
|
+
const targeted = experiment.variants
|
|
605
|
+
.filter(variant => !!variant.audience)
|
|
606
|
+
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.key.localeCompare(b.key));
|
|
607
|
+
if (context)
|
|
608
|
+
for (const variant of targeted)
|
|
609
|
+
if (mvtEvaluateAudience(variant.audience ?? null, context))
|
|
610
|
+
return variant;
|
|
611
|
+
const pool = experiment.variants.filter(variant => !variant.audience).sort((a, b) => a.key.localeCompare(b.key));
|
|
612
|
+
const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
|
|
613
|
+
if (!pool.length || total <= 0)
|
|
571
614
|
return null;
|
|
572
615
|
const target = (mvtBucket(experiment.salt, unitId) / 10000) * total;
|
|
573
616
|
let cursor = 0;
|
|
574
|
-
for (const variant of
|
|
617
|
+
for (const variant of pool) {
|
|
575
618
|
cursor += Math.max(variant.weight, 0);
|
|
576
619
|
if (target < cursor)
|
|
577
620
|
return variant;
|
|
578
621
|
}
|
|
579
|
-
return
|
|
622
|
+
return pool[pool.length - 1];
|
|
623
|
+
}
|
|
624
|
+
export function mvtDistribution(variants) {
|
|
625
|
+
const pool = variants.filter(variant => !variant.audience);
|
|
626
|
+
const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
|
|
627
|
+
return variants.map(variant => {
|
|
628
|
+
if (variant.audience)
|
|
629
|
+
return { key: variant.key, mode: '_Targeted_', weight: variant.weight, sharePct: 0 };
|
|
630
|
+
if (total <= 0 || variant.weight <= 0)
|
|
631
|
+
return { key: variant.key, mode: '_Unreachable_', weight: variant.weight, sharePct: 0 };
|
|
632
|
+
return {
|
|
633
|
+
key: variant.key,
|
|
634
|
+
mode: '_Weighted_',
|
|
635
|
+
weight: variant.weight,
|
|
636
|
+
sharePct: Math.round((Math.max(variant.weight, 0) / total) * 1000) / 10,
|
|
637
|
+
};
|
|
638
|
+
});
|
|
580
639
|
}
|
|
581
640
|
function mvtMatchesPattern(value, patterns) {
|
|
582
641
|
if (value === null)
|
|
@@ -621,6 +680,35 @@ function mvtEvaluateLeaf(operator, values, context) {
|
|
|
621
680
|
return from <= to ? hour >= from && hour <= to : hour >= from || hour <= to;
|
|
622
681
|
}
|
|
623
682
|
case '_Day_Of_Week_In_': return values.map(Number).includes(new Date(context.now).getDay());
|
|
683
|
+
case '_Logged_In_': return context.loggedIn;
|
|
684
|
+
case '_Logged_Out_': return !context.loggedIn;
|
|
685
|
+
case '_Is_Weekend_': return [0, 6].includes(new Date(context.now).getDay());
|
|
686
|
+
case '_Visits_At_Least_': return context.visits >= Number(values[0] ?? 1);
|
|
687
|
+
case '_Query_Param_Matches_': {
|
|
688
|
+
return values.some(raw => {
|
|
689
|
+
const separator = raw.indexOf('=');
|
|
690
|
+
const name = (separator < 0 ? raw : raw.slice(0, separator)).trim().toLowerCase();
|
|
691
|
+
const expected = separator < 0 ? null : raw.slice(separator + 1);
|
|
692
|
+
const actual = context.query[name];
|
|
693
|
+
if (actual === undefined)
|
|
694
|
+
return false;
|
|
695
|
+
if (expected === null)
|
|
696
|
+
return true;
|
|
697
|
+
return mvtMatchesPattern(actual, [expected]);
|
|
698
|
+
});
|
|
699
|
+
}
|
|
700
|
+
case '_Screen_Width_Between_': {
|
|
701
|
+
const from = Number(values[0] ?? 0);
|
|
702
|
+
const to = Number(values[1] ?? Number.MAX_SAFE_INTEGER);
|
|
703
|
+
return context.screenWidth >= from && context.screenWidth <= to;
|
|
704
|
+
}
|
|
705
|
+
case '_Date_Between_': {
|
|
706
|
+
const from = values[0] ? Date.parse(values[0]) : Number.NEGATIVE_INFINITY;
|
|
707
|
+
const to = values[1] ? Date.parse(values[1]) : Number.POSITIVE_INFINITY;
|
|
708
|
+
if (Number.isNaN(from) || Number.isNaN(to))
|
|
709
|
+
return false;
|
|
710
|
+
return context.now >= from && context.now <= to;
|
|
711
|
+
}
|
|
624
712
|
default: return false;
|
|
625
713
|
}
|
|
626
714
|
}
|
|
@@ -667,7 +755,7 @@ export function mvtResolve(config, context, forced = {}) {
|
|
|
667
755
|
continue;
|
|
668
756
|
if (!mvtIsEligibleForTraffic(experiment, context.unitId))
|
|
669
757
|
continue;
|
|
670
|
-
const variant = mvtPickVariant(experiment, context.unitId);
|
|
758
|
+
const variant = mvtPickVariant(experiment, context.unitId, context);
|
|
671
759
|
if (!variant)
|
|
672
760
|
continue;
|
|
673
761
|
if (experiment.exclusionGroup)
|
|
@@ -686,8 +774,36 @@ function mvtToDecision(experiment, variant) {
|
|
|
686
774
|
overrides: variant.overrides,
|
|
687
775
|
};
|
|
688
776
|
}
|
|
689
|
-
const i18nTextSchema = z.
|
|
777
|
+
const i18nTextSchema = z.partialRecord(LangSchema, z.string());
|
|
690
778
|
const colorSchema = z.string().regex(/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i);
|
|
779
|
+
export const MvtAnchorPatchSchema = z.object({
|
|
780
|
+
hidden: z.boolean().optional(),
|
|
781
|
+
order: z.number().int().min(-999).max(999).optional(),
|
|
782
|
+
text: i18nTextSchema.optional(),
|
|
783
|
+
href: z.string().max(2048).optional(),
|
|
784
|
+
route: z.string().max(512).optional(),
|
|
785
|
+
image: z.string().max(2048).optional(),
|
|
786
|
+
style: z.object({
|
|
787
|
+
background: colorSchema.optional(),
|
|
788
|
+
color: colorSchema.optional(),
|
|
789
|
+
borderColor: colorSchema.optional(),
|
|
790
|
+
borderRadius: z.number().int().min(0).max(96).optional(),
|
|
791
|
+
fontSize: z.number().int().min(8).max(96).optional(),
|
|
792
|
+
fontWeight: z.enum(['300', '400', '500', '600', '700', '800']).optional(),
|
|
793
|
+
align: z.enum(['left', 'center', 'right']).optional(),
|
|
794
|
+
paddingY: z.number().int().min(0).max(160).optional(),
|
|
795
|
+
paddingX: z.number().int().min(0).max(160).optional(),
|
|
796
|
+
}).optional(),
|
|
797
|
+
});
|
|
798
|
+
const anchorsSchema = z.record(z.string(), MvtAnchorPatchSchema);
|
|
799
|
+
const ANCHOR_FIELDS = [
|
|
800
|
+
{ key: 'hidden', label: 'Hidden', kind: 'boolean' },
|
|
801
|
+
{ key: 'order', label: 'Position', kind: 'number' },
|
|
802
|
+
{ key: 'text', label: 'Text', kind: 'i18n' },
|
|
803
|
+
{ key: 'href', label: 'External link', kind: 'text' },
|
|
804
|
+
{ key: 'route', label: 'Internal route', kind: 'text' },
|
|
805
|
+
{ key: 'image', label: 'Image', kind: 'image' },
|
|
806
|
+
];
|
|
691
807
|
function slot(definition) {
|
|
692
808
|
return definition;
|
|
693
809
|
}
|
|
@@ -809,6 +925,18 @@ export const MVT_SLOTS = [
|
|
|
809
925
|
],
|
|
810
926
|
schema: z.object({ mobile: z.boolean().optional(), tablet: z.boolean().optional(), desktop: z.boolean().optional() }),
|
|
811
927
|
}),
|
|
928
|
+
slot({
|
|
929
|
+
key: 'storefront.anchors', scope: '_Storefront_', area: 'Studio', label: 'Anchored elements',
|
|
930
|
+
hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
|
|
931
|
+
kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
|
|
932
|
+
schema: anchorsSchema,
|
|
933
|
+
}),
|
|
934
|
+
slot({
|
|
935
|
+
key: 'checkout.anchors', scope: '_Checkout_', area: 'Studio', label: 'Anchored elements',
|
|
936
|
+
hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
|
|
937
|
+
kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
|
|
938
|
+
schema: anchorsSchema,
|
|
939
|
+
}),
|
|
812
940
|
];
|
|
813
941
|
const MVT_SLOTS_BY_KEY = new Map(MVT_SLOTS.map(s => [s.key, s]));
|
|
814
942
|
export function mvtSlot(key) {
|
|
@@ -832,8 +960,12 @@ export function mvtValidateOverrides(overrides) {
|
|
|
832
960
|
if (override.op === 'remove' || override.op === 'reorder')
|
|
833
961
|
return;
|
|
834
962
|
if (override.op === 'merge' || override.op === 'patch' || override.op === 'insert') {
|
|
835
|
-
if (override.value === undefined)
|
|
963
|
+
if (override.value === undefined) {
|
|
836
964
|
issues.push({ index, slot: override.slot, reason: 'missing_value' });
|
|
965
|
+
return;
|
|
966
|
+
}
|
|
967
|
+
if (definition.kind === 'record' && !definition.schema.safeParse(override.value).success)
|
|
968
|
+
issues.push({ index, slot: override.slot, reason: 'invalid_value' });
|
|
837
969
|
return;
|
|
838
970
|
}
|
|
839
971
|
if (!definition.schema.safeParse(override.value).success)
|
|
@@ -898,3 +1030,80 @@ export function mvtApplyOverride(base, override) {
|
|
|
898
1030
|
return base;
|
|
899
1031
|
}
|
|
900
1032
|
}
|
|
1033
|
+
export const MVT_ANCHOR_ATTRIBUTE = 'data-mvt-anchor';
|
|
1034
|
+
export function mvtAnchorsSlot(scope) {
|
|
1035
|
+
return scope === '_Checkout_' ? 'checkout.anchors' : 'storefront.anchors';
|
|
1036
|
+
}
|
|
1037
|
+
export function mvtMergeAnchorPatch(base, next) {
|
|
1038
|
+
if (!base)
|
|
1039
|
+
return next ?? {};
|
|
1040
|
+
if (!next)
|
|
1041
|
+
return base;
|
|
1042
|
+
return {
|
|
1043
|
+
...base,
|
|
1044
|
+
...next,
|
|
1045
|
+
text: next.text || base.text ? { ...(base.text ?? {}), ...(next.text ?? {}) } : undefined,
|
|
1046
|
+
style: next.style || base.style ? { ...(base.style ?? {}), ...(next.style ?? {}) } : undefined,
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
export function mvtAnchorStyle(patch) {
|
|
1050
|
+
const style = patch?.style;
|
|
1051
|
+
if (!style)
|
|
1052
|
+
return {};
|
|
1053
|
+
const out = {};
|
|
1054
|
+
if (style.background)
|
|
1055
|
+
out['background-color'] = style.background;
|
|
1056
|
+
if (style.color)
|
|
1057
|
+
out['color'] = style.color;
|
|
1058
|
+
if (style.borderColor)
|
|
1059
|
+
out['border-color'] = style.borderColor;
|
|
1060
|
+
if (style.borderRadius !== undefined)
|
|
1061
|
+
out['border-radius'] = `${style.borderRadius}px`;
|
|
1062
|
+
if (style.fontSize !== undefined)
|
|
1063
|
+
out['font-size'] = `${style.fontSize}px`;
|
|
1064
|
+
if (style.fontWeight)
|
|
1065
|
+
out['font-weight'] = style.fontWeight;
|
|
1066
|
+
if (style.align)
|
|
1067
|
+
out['text-align'] = style.align;
|
|
1068
|
+
if (style.paddingY !== undefined)
|
|
1069
|
+
out['padding-block'] = `${style.paddingY}px`;
|
|
1070
|
+
if (style.paddingX !== undefined)
|
|
1071
|
+
out['padding-inline'] = `${style.paddingX}px`;
|
|
1072
|
+
return out;
|
|
1073
|
+
}
|
|
1074
|
+
export const MVT_STUDIO_PROTOCOL = 2;
|
|
1075
|
+
export function mvtCollectLinks(root, origin) {
|
|
1076
|
+
const seen = new Set();
|
|
1077
|
+
const links = [];
|
|
1078
|
+
for (const element of Array.from(root.querySelectorAll('a[href]'))) {
|
|
1079
|
+
const anchor = element;
|
|
1080
|
+
if (anchor.hasAttribute('download') || anchor.target === '_blank')
|
|
1081
|
+
continue;
|
|
1082
|
+
let url;
|
|
1083
|
+
try {
|
|
1084
|
+
url = new URL(anchor.getAttribute('href') ?? '', origin);
|
|
1085
|
+
}
|
|
1086
|
+
catch {
|
|
1087
|
+
continue;
|
|
1088
|
+
}
|
|
1089
|
+
if (url.origin !== origin)
|
|
1090
|
+
continue;
|
|
1091
|
+
if (!url.pathname.startsWith('/'))
|
|
1092
|
+
continue;
|
|
1093
|
+
if (seen.has(url.pathname))
|
|
1094
|
+
continue;
|
|
1095
|
+
seen.add(url.pathname);
|
|
1096
|
+
const label = (anchor.textContent ?? '').replace(/\s+/g, ' ').trim();
|
|
1097
|
+
links.push({ path: url.pathname, label: label || url.pathname, kind: 'link', reachable: true });
|
|
1098
|
+
}
|
|
1099
|
+
return links.sort((a, b) => a.label.localeCompare(b.label));
|
|
1100
|
+
}
|
|
1101
|
+
export function mvtIsStudioEvent(data) {
|
|
1102
|
+
if (!data || typeof data !== 'object')
|
|
1103
|
+
return false;
|
|
1104
|
+
const message = data;
|
|
1105
|
+
return message.protocol === MVT_STUDIO_PROTOCOL && typeof message.type === 'string' && message.type.startsWith('studio:');
|
|
1106
|
+
}
|
|
1107
|
+
export function mvtIsStudioRequest(data) {
|
|
1108
|
+
return mvtIsStudioEvent(data);
|
|
1109
|
+
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lifeaz/lors-helper",
|
|
3
3
|
"description": "Lifeaz Online Retail Storefront Helper",
|
|
4
|
-
"version": "1.1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"files": [
|
|
7
7
|
"dist",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"lifeaz": {
|
|
52
52
|
"version": {
|
|
53
53
|
"short": 1,
|
|
54
|
-
"full": "1.1.
|
|
55
|
-
"code": "
|
|
54
|
+
"full": "1.1.2-b37",
|
|
55
|
+
"code": "101020037"
|
|
56
56
|
}
|
|
57
57
|
}
|
|
58
58
|
}
|
package/src/main.ts
CHANGED
|
@@ -407,6 +407,14 @@ export const CartSchema = z.object({
|
|
|
407
407
|
locale: LangSchema,
|
|
408
408
|
vatNumber: z.string().nullable(),
|
|
409
409
|
multiAddressesCallback: z.boolean(),
|
|
410
|
+
/**
|
|
411
|
+
* True for a basket the MVT studio minted so an operator can edit the funnel from inside it.
|
|
412
|
+
*
|
|
413
|
+
* Defaulted rather than required, so a release that predates the column - or any caller that
|
|
414
|
+
* simply does not set it - produces a real cart. The safe value is the one you get by saying
|
|
415
|
+
* nothing.
|
|
416
|
+
*/
|
|
417
|
+
simulated: z.boolean().default(false),
|
|
410
418
|
partnerId: uuidSchema.nullable(),
|
|
411
419
|
createdAt: dayjsSchema,
|
|
412
420
|
updatedAt: dayjsSchema,
|
|
@@ -696,7 +704,14 @@ export type MvtOperator =
|
|
|
696
704
|
| '_Path_Matches_'
|
|
697
705
|
| '_Has_Cart_'
|
|
698
706
|
| '_Hour_Of_Day_Between_'
|
|
699
|
-
| '_Day_Of_Week_In_'
|
|
707
|
+
| '_Day_Of_Week_In_'
|
|
708
|
+
| '_Query_Param_Matches_'
|
|
709
|
+
| '_Screen_Width_Between_'
|
|
710
|
+
| '_Visits_At_Least_'
|
|
711
|
+
| '_Logged_In_'
|
|
712
|
+
| '_Logged_Out_'
|
|
713
|
+
| '_Is_Weekend_'
|
|
714
|
+
| '_Date_Between_';
|
|
700
715
|
|
|
701
716
|
export const MvtOperatorSchema = z.union([
|
|
702
717
|
z.literal('_Device_In_'),
|
|
@@ -717,6 +732,13 @@ export const MvtOperatorSchema = z.union([
|
|
|
717
732
|
z.literal('_Has_Cart_'),
|
|
718
733
|
z.literal('_Hour_Of_Day_Between_'),
|
|
719
734
|
z.literal('_Day_Of_Week_In_'),
|
|
735
|
+
z.literal('_Query_Param_Matches_'),
|
|
736
|
+
z.literal('_Screen_Width_Between_'),
|
|
737
|
+
z.literal('_Visits_At_Least_'),
|
|
738
|
+
z.literal('_Logged_In_'),
|
|
739
|
+
z.literal('_Logged_Out_'),
|
|
740
|
+
z.literal('_Is_Weekend_'),
|
|
741
|
+
z.literal('_Date_Between_'),
|
|
720
742
|
]);
|
|
721
743
|
|
|
722
744
|
/**
|
|
@@ -729,6 +751,9 @@ export const MVT_NULLARY_OPERATORS: readonly MvtOperator[] = [
|
|
|
729
751
|
'_Visitor_Is_New_',
|
|
730
752
|
'_Visitor_Is_Returning_',
|
|
731
753
|
'_Has_Cart_',
|
|
754
|
+
'_Logged_In_',
|
|
755
|
+
'_Logged_Out_',
|
|
756
|
+
'_Is_Weekend_',
|
|
732
757
|
];
|
|
733
758
|
|
|
734
759
|
export type MvtOverrideOp = 'set' | 'merge' | 'remove' | 'reorder' | 'insert' | 'patch';
|
|
@@ -764,9 +789,36 @@ export const MvtVariantSchema = z.object({
|
|
|
764
789
|
weight: z.number().int().nonnegative(),
|
|
765
790
|
control: z.boolean(),
|
|
766
791
|
overrides: z.array(MvtOverrideSchema),
|
|
792
|
+
/**
|
|
793
|
+
* Optional sub-targeting. A variant carrying one stops being a share of the split and becomes
|
|
794
|
+
* a rule: every unit matching it lands here, whatever the weights say. See mvtPickVariant.
|
|
795
|
+
*/
|
|
796
|
+
audience: MvtAudienceNodeSchema.nullable().default(null),
|
|
797
|
+
/** Evaluation order of the targeted variants. The first match wins, so this is the tie-break. */
|
|
798
|
+
order: z.number().int().default(0),
|
|
799
|
+
/** Purely cosmetic, so one arm keeps the same colour across the split bar, the studio and the results. */
|
|
800
|
+
color: z.string().nullable().default(null),
|
|
801
|
+
description: z.string().nullable().default(null),
|
|
767
802
|
});
|
|
768
803
|
export type MvtVariant = z.infer<typeof MvtVariantSchema>;
|
|
769
804
|
|
|
805
|
+
/**
|
|
806
|
+
* How one variant ends up receiving traffic, resolved from the variant set as a whole.
|
|
807
|
+
*
|
|
808
|
+
* `_Targeted_` variants are claimed by their own conditions and take no part in the weighted
|
|
809
|
+
* draw; `_Weighted_` ones share whatever is left. Computed in one place because the operator is
|
|
810
|
+
* shown this and the evaluator obeys it, and the two disagreeing would be the worst outcome.
|
|
811
|
+
*/
|
|
812
|
+
export type MvtAllocationMode = '_Targeted_' | '_Weighted_' | '_Unreachable_';
|
|
813
|
+
|
|
814
|
+
export interface MvtAllocationRow {
|
|
815
|
+
key: string;
|
|
816
|
+
mode: MvtAllocationMode;
|
|
817
|
+
weight: number;
|
|
818
|
+
/** Share of the units that reach the weighted draw. Zero for a targeted variant, whose share depends on the audience rather than on a number. */
|
|
819
|
+
sharePct: number;
|
|
820
|
+
}
|
|
821
|
+
|
|
770
822
|
export const MvtExperimentSchema = z.object({
|
|
771
823
|
id: uuidSchema,
|
|
772
824
|
key: z.string().min(1),
|
|
@@ -815,6 +867,42 @@ export interface MvtContext {
|
|
|
815
867
|
hasCart: boolean;
|
|
816
868
|
firstSeenAt: number;
|
|
817
869
|
now: number;
|
|
870
|
+
/** Query string of the landing URL, lowercased keys. Reads as a targeting dimension of its own so an ad link can pin an arm without an UTM convention. */
|
|
871
|
+
query: Record<string, string>;
|
|
872
|
+
/** Viewport width in CSS pixels. Coarser than the device buckets, for the tests where the breakpoint itself is the subject. */
|
|
873
|
+
screenWidth: number;
|
|
874
|
+
/** Sessions this unit has opened, this one included. */
|
|
875
|
+
visits: number;
|
|
876
|
+
loggedIn: boolean;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
/**
|
|
880
|
+
* Fill in the dimensions an older caller does not provide.
|
|
881
|
+
*
|
|
882
|
+
* The context grew, and a front built against the previous shape must not start failing every
|
|
883
|
+
* leaf that reads a new field. Defaults are chosen so an absent dimension excludes rather than
|
|
884
|
+
* includes: a condition on something the caller cannot observe should not match everybody.
|
|
885
|
+
*/
|
|
886
|
+
export function mvtNormalizeContext(context: Partial<MvtContext> & { unitId: string }): MvtContext {
|
|
887
|
+
return {
|
|
888
|
+
device: '_Desktop_',
|
|
889
|
+
lang: 'fr',
|
|
890
|
+
country: null,
|
|
891
|
+
profile: null,
|
|
892
|
+
partner: null,
|
|
893
|
+
seen: {},
|
|
894
|
+
utm: { source: null, medium: null, campaign: null },
|
|
895
|
+
referrer: null,
|
|
896
|
+
path: '/',
|
|
897
|
+
hasCart: false,
|
|
898
|
+
firstSeenAt: Date.now(),
|
|
899
|
+
now: Date.now(),
|
|
900
|
+
query: {},
|
|
901
|
+
screenWidth: 0,
|
|
902
|
+
visits: 1,
|
|
903
|
+
loggedIn: false,
|
|
904
|
+
...context,
|
|
905
|
+
};
|
|
818
906
|
}
|
|
819
907
|
|
|
820
908
|
export interface MvtDecision {
|
|
@@ -866,22 +954,61 @@ export function mvtIsEligibleForTraffic(experiment: MvtExperiment, unitId: strin
|
|
|
866
954
|
* so that the mapping from bucket range to variant depends only on the weights themselves and not
|
|
867
955
|
* on the order rows happened to come back from the database.
|
|
868
956
|
*/
|
|
869
|
-
export function mvtPickVariant(experiment: MvtExperiment, unitId: string): MvtVariant | null {
|
|
870
|
-
const
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
957
|
+
export function mvtPickVariant(experiment: MvtExperiment, unitId: string, context?: MvtContext): MvtVariant | null {
|
|
958
|
+
const targeted = experiment.variants
|
|
959
|
+
.filter(variant => !!variant.audience)
|
|
960
|
+
.sort((a, b) => (a.order ?? 0) - (b.order ?? 0) || a.key.localeCompare(b.key));
|
|
961
|
+
|
|
962
|
+
// Targeted arms are rules, not shares: the first whose own conditions hold claims the unit
|
|
963
|
+
// outright. Evaluated before the draw so that "everyone on mobile sees B" means exactly that
|
|
964
|
+
// rather than "mobile visitors have a better chance of seeing B", which is what a weight
|
|
965
|
+
// nudged by hand would have produced and what an operator would have had to verify by eye.
|
|
966
|
+
if (context)
|
|
967
|
+
for (const variant of targeted)
|
|
968
|
+
if (mvtEvaluateAudience(variant.audience ?? null, context)) return variant;
|
|
969
|
+
|
|
970
|
+
const pool = experiment.variants.filter(variant => !variant.audience).sort((a, b) => a.key.localeCompare(b.key));
|
|
971
|
+
const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
|
|
972
|
+
|
|
973
|
+
// Every arm targeted and none of them matching leaves nobody to fall back on. The unit is
|
|
974
|
+
// left out of the experiment entirely rather than pushed onto an arm whose conditions it
|
|
975
|
+
// failed, which would silently make the targeting a lie.
|
|
976
|
+
if (!pool.length || total <= 0) return null;
|
|
874
977
|
|
|
875
978
|
const target = (mvtBucket(experiment.salt, unitId) / 10000) * total;
|
|
876
979
|
let cursor = 0;
|
|
877
980
|
|
|
878
|
-
for (const variant of
|
|
981
|
+
for (const variant of pool) {
|
|
879
982
|
cursor += Math.max(variant.weight, 0);
|
|
880
983
|
|
|
881
984
|
if (target < cursor) return variant;
|
|
882
985
|
}
|
|
883
986
|
|
|
884
|
-
return
|
|
987
|
+
return pool[pool.length - 1];
|
|
988
|
+
}
|
|
989
|
+
|
|
990
|
+
/**
|
|
991
|
+
* How the split actually resolves, for the operator rather than the evaluator.
|
|
992
|
+
*
|
|
993
|
+
* Weights are relative and targeted arms are outside the draw entirely, so the number an operator
|
|
994
|
+
* typed and the share it buys are rarely the same. Computing that here, from the same rules the
|
|
995
|
+
* bucketing obeys, is what lets the interface show a split bar that cannot drift from the truth.
|
|
996
|
+
*/
|
|
997
|
+
export function mvtDistribution(variants: readonly MvtVariant[]): MvtAllocationRow[] {
|
|
998
|
+
const pool = variants.filter(variant => !variant.audience);
|
|
999
|
+
const total = pool.reduce((sum, v) => sum + Math.max(v.weight, 0), 0);
|
|
1000
|
+
|
|
1001
|
+
return variants.map(variant => {
|
|
1002
|
+
if (variant.audience) return { key: variant.key, mode: '_Targeted_' as const, weight: variant.weight, sharePct: 0 };
|
|
1003
|
+
if (total <= 0 || variant.weight <= 0) return { key: variant.key, mode: '_Unreachable_' as const, weight: variant.weight, sharePct: 0 };
|
|
1004
|
+
|
|
1005
|
+
return {
|
|
1006
|
+
key: variant.key,
|
|
1007
|
+
mode: '_Weighted_' as const,
|
|
1008
|
+
weight: variant.weight,
|
|
1009
|
+
sharePct: Math.round((Math.max(variant.weight, 0) / total) * 1000) / 10,
|
|
1010
|
+
};
|
|
1011
|
+
});
|
|
885
1012
|
}
|
|
886
1013
|
|
|
887
1014
|
function mvtMatchesPattern(value: string | null, patterns: string[]): boolean {
|
|
@@ -929,6 +1056,47 @@ function mvtEvaluateLeaf(operator: MvtOperator, values: string[], context: MvtCo
|
|
|
929
1056
|
return from <= to ? hour >= from && hour <= to : hour >= from || hour <= to;
|
|
930
1057
|
}
|
|
931
1058
|
case '_Day_Of_Week_In_': return values.map(Number).includes(new Date(context.now).getDay());
|
|
1059
|
+
case '_Logged_In_': return context.loggedIn;
|
|
1060
|
+
case '_Logged_Out_': return !context.loggedIn;
|
|
1061
|
+
case '_Is_Weekend_': return [0, 6].includes(new Date(context.now).getDay());
|
|
1062
|
+
case '_Visits_At_Least_': return context.visits >= Number(values[0] ?? 1);
|
|
1063
|
+
|
|
1064
|
+
// Written "name=value", or "name" on its own to test for presence. The value side goes
|
|
1065
|
+
// through the same wildcard matcher as the UTM leaves, so utm-like conventions carried in
|
|
1066
|
+
// a bespoke parameter behave the way an operator already expects them to.
|
|
1067
|
+
case '_Query_Param_Matches_': {
|
|
1068
|
+
return values.some(raw => {
|
|
1069
|
+
const separator = raw.indexOf('=');
|
|
1070
|
+
const name = (separator < 0 ? raw : raw.slice(0, separator)).trim().toLowerCase();
|
|
1071
|
+
const expected = separator < 0 ? null : raw.slice(separator + 1);
|
|
1072
|
+
const actual = context.query[name];
|
|
1073
|
+
|
|
1074
|
+
if (actual === undefined) return false;
|
|
1075
|
+
if (expected === null) return true;
|
|
1076
|
+
|
|
1077
|
+
return mvtMatchesPattern(actual, [expected]);
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
|
|
1081
|
+
case '_Screen_Width_Between_': {
|
|
1082
|
+
const from = Number(values[0] ?? 0);
|
|
1083
|
+
const to = Number(values[1] ?? Number.MAX_SAFE_INTEGER);
|
|
1084
|
+
|
|
1085
|
+
return context.screenWidth >= from && context.screenWidth <= to;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
// Bounds are wall-clock dates, and either may be left out for an open-ended window. This
|
|
1089
|
+
// is not the experiment's own schedule: it is for the tests whose point is a date, such
|
|
1090
|
+
// as a variant that only exists over a sale weekend.
|
|
1091
|
+
case '_Date_Between_': {
|
|
1092
|
+
const from = values[0] ? Date.parse(values[0]) : Number.NEGATIVE_INFINITY;
|
|
1093
|
+
const to = values[1] ? Date.parse(values[1]) : Number.POSITIVE_INFINITY;
|
|
1094
|
+
|
|
1095
|
+
if (Number.isNaN(from) || Number.isNaN(to)) return false;
|
|
1096
|
+
|
|
1097
|
+
return context.now >= from && context.now <= to;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
932
1100
|
default: return false;
|
|
933
1101
|
}
|
|
934
1102
|
}
|
|
@@ -995,7 +1163,7 @@ export function mvtResolve(config: MvtConfig, context: MvtContext, forced: Recor
|
|
|
995
1163
|
if (!mvtEvaluateAudience(experiment.audience, context)) continue;
|
|
996
1164
|
if (!mvtIsEligibleForTraffic(experiment, context.unitId)) continue;
|
|
997
1165
|
|
|
998
|
-
const variant = mvtPickVariant(experiment, context.unitId);
|
|
1166
|
+
const variant = mvtPickVariant(experiment, context.unitId, context);
|
|
999
1167
|
|
|
1000
1168
|
if (!variant) continue;
|
|
1001
1169
|
if (experiment.exclusionGroup) claimed.add(experiment.exclusionGroup);
|
|
@@ -1058,9 +1226,62 @@ export interface MvtSlotDefinition {
|
|
|
1058
1226
|
schema: z.ZodType<unknown>;
|
|
1059
1227
|
}
|
|
1060
1228
|
|
|
1061
|
-
|
|
1229
|
+
/**
|
|
1230
|
+
* A piece of copy, written in whichever languages the operator filled in.
|
|
1231
|
+
*
|
|
1232
|
+
* Partial on purpose, and it has to be said in the schema rather than left to convention: zod
|
|
1233
|
+
* treats a record keyed by a closed set as exhaustive, so `z.record` here would refuse a French-
|
|
1234
|
+
* only override at write time - which is the normal case, since a language left empty is
|
|
1235
|
+
* documented everywhere as keeping the untouched original rather than blanking it.
|
|
1236
|
+
*/
|
|
1237
|
+
const i18nTextSchema = z.partialRecord(LangSchema, z.string());
|
|
1062
1238
|
const colorSchema = z.string().regex(/^#([0-9a-f]{3}|[0-9a-f]{6}|[0-9a-f]{8})$/i);
|
|
1063
1239
|
|
|
1240
|
+
/**
|
|
1241
|
+
* What a test may do to one anchored element.
|
|
1242
|
+
*
|
|
1243
|
+
* This is the whole vocabulary of the visual editor, and it is deliberately short. Hide it, move
|
|
1244
|
+
* it, reword it, repoint it, restyle it within a closed set of properties. Nothing here can
|
|
1245
|
+
* inject markup or a script, so an override authored by clicking around a page carries the same
|
|
1246
|
+
* blast radius as one typed into the registry editor, which is what makes the studio safe to
|
|
1247
|
+
* hand to somebody who is not going to read a diff.
|
|
1248
|
+
*
|
|
1249
|
+
* Every field is optional and absence means untouched, so the patches stay small and two editing
|
|
1250
|
+
* sessions on the same element compose instead of overwriting one another.
|
|
1251
|
+
*/
|
|
1252
|
+
export const MvtAnchorPatchSchema = z.object({
|
|
1253
|
+
hidden: z.boolean().optional(),
|
|
1254
|
+
/** Position among its siblings. Lower comes first; anchors without one keep their place. */
|
|
1255
|
+
order: z.number().int().min(-999).max(999).optional(),
|
|
1256
|
+
text: i18nTextSchema.optional(),
|
|
1257
|
+
href: z.string().max(2048).optional(),
|
|
1258
|
+
route: z.string().max(512).optional(),
|
|
1259
|
+
image: z.string().max(2048).optional(),
|
|
1260
|
+
style: z.object({
|
|
1261
|
+
background: colorSchema.optional(),
|
|
1262
|
+
color: colorSchema.optional(),
|
|
1263
|
+
borderColor: colorSchema.optional(),
|
|
1264
|
+
borderRadius: z.number().int().min(0).max(96).optional(),
|
|
1265
|
+
fontSize: z.number().int().min(8).max(96).optional(),
|
|
1266
|
+
fontWeight: z.enum(['300', '400', '500', '600', '700', '800']).optional(),
|
|
1267
|
+
align: z.enum(['left', 'center', 'right']).optional(),
|
|
1268
|
+
paddingY: z.number().int().min(0).max(160).optional(),
|
|
1269
|
+
paddingX: z.number().int().min(0).max(160).optional(),
|
|
1270
|
+
}).optional(),
|
|
1271
|
+
});
|
|
1272
|
+
export type MvtAnchorPatch = z.infer<typeof MvtAnchorPatchSchema>;
|
|
1273
|
+
|
|
1274
|
+
const anchorsSchema = z.record(z.string(), MvtAnchorPatchSchema);
|
|
1275
|
+
|
|
1276
|
+
const ANCHOR_FIELDS: readonly MvtSlotField[] = [
|
|
1277
|
+
{ key: 'hidden', label: 'Hidden', kind: 'boolean' },
|
|
1278
|
+
{ key: 'order', label: 'Position', kind: 'number' },
|
|
1279
|
+
{ key: 'text', label: 'Text', kind: 'i18n' },
|
|
1280
|
+
{ key: 'href', label: 'External link', kind: 'text' },
|
|
1281
|
+
{ key: 'route', label: 'Internal route', kind: 'text' },
|
|
1282
|
+
{ key: 'image', label: 'Image', kind: 'image' },
|
|
1283
|
+
];
|
|
1284
|
+
|
|
1064
1285
|
function slot(definition: MvtSlotDefinition): MvtSlotDefinition {
|
|
1065
1286
|
return definition;
|
|
1066
1287
|
}
|
|
@@ -1200,6 +1421,19 @@ export const MVT_SLOTS: readonly MvtSlotDefinition[] = [
|
|
|
1200
1421
|
],
|
|
1201
1422
|
schema: z.object({ mobile: z.boolean().optional(), tablet: z.boolean().optional(), desktop: z.boolean().optional() }),
|
|
1202
1423
|
}),
|
|
1424
|
+
|
|
1425
|
+
slot({
|
|
1426
|
+
key: 'storefront.anchors', scope: '_Storefront_', area: 'Studio', label: 'Anchored elements',
|
|
1427
|
+
hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
|
|
1428
|
+
kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
|
|
1429
|
+
schema: anchorsSchema,
|
|
1430
|
+
}),
|
|
1431
|
+
slot({
|
|
1432
|
+
key: 'checkout.anchors', scope: '_Checkout_', area: 'Studio', label: 'Anchored elements',
|
|
1433
|
+
hint: 'Everything the visual editor writes: elements hidden, moved, reworded or restyled by clicking on the page itself.',
|
|
1434
|
+
kind: 'record', entryKind: 'object', ops: ['merge', 'set'], fields: ANCHOR_FIELDS, itemKey: 'anchor',
|
|
1435
|
+
schema: anchorsSchema,
|
|
1436
|
+
}),
|
|
1203
1437
|
] as const;
|
|
1204
1438
|
|
|
1205
1439
|
const MVT_SLOTS_BY_KEY: ReadonlyMap<string, MvtSlotDefinition> = new Map(MVT_SLOTS.map(s => [s.key, s]));
|
|
@@ -1246,7 +1480,18 @@ export function mvtValidateOverrides(overrides: MvtOverride[]): MvtOverrideIssue
|
|
|
1246
1480
|
if (override.op === 'remove' || override.op === 'reorder') return;
|
|
1247
1481
|
|
|
1248
1482
|
if (override.op === 'merge' || override.op === 'patch' || override.op === 'insert') {
|
|
1249
|
-
if (override.value === undefined)
|
|
1483
|
+
if (override.value === undefined) {
|
|
1484
|
+
issues.push({ index, slot: override.slot, reason: 'missing_value' });
|
|
1485
|
+
|
|
1486
|
+
return;
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// A merge onto a record is still a record of the same entries, so the full schema
|
|
1490
|
+
// applies and catches a malformed anchor patch here rather than in a customer's
|
|
1491
|
+
// browser. A merge onto a fixed-shape object is a partial by definition, and running
|
|
1492
|
+
// the whole schema over it would refuse every legitimate single-field edit.
|
|
1493
|
+
if (definition.kind === 'record' && !definition.schema.safeParse(override.value).success)
|
|
1494
|
+
issues.push({ index, slot: override.slot, reason: 'invalid_value' });
|
|
1250
1495
|
|
|
1251
1496
|
return;
|
|
1252
1497
|
}
|
|
@@ -1331,3 +1576,213 @@ export function mvtApplyOverride<T>(base: T, override: MvtOverride): T {
|
|
|
1331
1576
|
return base;
|
|
1332
1577
|
}
|
|
1333
1578
|
}
|
|
1579
|
+
|
|
1580
|
+
// -----------------------------------------------------------------------------
|
|
1581
|
+
// Anchors
|
|
1582
|
+
// -----------------------------------------------------------------------------
|
|
1583
|
+
|
|
1584
|
+
export const MVT_ANCHOR_ATTRIBUTE = 'data-mvt-anchor';
|
|
1585
|
+
|
|
1586
|
+
/**
|
|
1587
|
+
* The anchors slot for one scope.
|
|
1588
|
+
*
|
|
1589
|
+
* Kept as a lookup rather than a naming convention the call sites repeat, because the studio, the
|
|
1590
|
+
* API validator and the two fronts all have to agree on it, and a typo in any of the four would
|
|
1591
|
+
* produce an override that validates and does nothing.
|
|
1592
|
+
*/
|
|
1593
|
+
export function mvtAnchorsSlot(scope: MvtScope): string {
|
|
1594
|
+
return scope === '_Checkout_' ? 'checkout.anchors' : 'storefront.anchors';
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
/**
|
|
1598
|
+
* Fold a stack of anchor patches into one.
|
|
1599
|
+
*
|
|
1600
|
+
* Later patches win field by field rather than wholesale: two overrides touching the same element,
|
|
1601
|
+
* one hiding it and one rewording it, both have to survive, or the operator has to remember which
|
|
1602
|
+
* of their own edits cancelled which.
|
|
1603
|
+
*/
|
|
1604
|
+
export function mvtMergeAnchorPatch(base: MvtAnchorPatch | undefined, next: MvtAnchorPatch | undefined): MvtAnchorPatch {
|
|
1605
|
+
if (!base) return next ?? {};
|
|
1606
|
+
if (!next) return base;
|
|
1607
|
+
|
|
1608
|
+
return {
|
|
1609
|
+
...base,
|
|
1610
|
+
...next,
|
|
1611
|
+
text: next.text || base.text ? { ...(base.text ?? {}), ...(next.text ?? {}) } : undefined,
|
|
1612
|
+
style: next.style || base.style ? { ...(base.style ?? {}), ...(next.style ?? {}) } : undefined,
|
|
1613
|
+
};
|
|
1614
|
+
}
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* The inline style an anchor patch asks for, as a plain property bag.
|
|
1618
|
+
*
|
|
1619
|
+
* Only the closed set the patch schema allows can come out of here, which is the point: a front
|
|
1620
|
+
* applying this is not evaluating anything an operator wrote, it is reading a handful of numbers
|
|
1621
|
+
* and colours that have already been validated twice.
|
|
1622
|
+
*/
|
|
1623
|
+
export function mvtAnchorStyle(patch: MvtAnchorPatch | null | undefined): Record<string, string> {
|
|
1624
|
+
const style = patch?.style;
|
|
1625
|
+
|
|
1626
|
+
if (!style) return {};
|
|
1627
|
+
|
|
1628
|
+
const out: Record<string, string> = {};
|
|
1629
|
+
|
|
1630
|
+
if (style.background) out['background-color'] = style.background;
|
|
1631
|
+
if (style.color) out['color'] = style.color;
|
|
1632
|
+
if (style.borderColor) out['border-color'] = style.borderColor;
|
|
1633
|
+
if (style.borderRadius !== undefined) out['border-radius'] = `${style.borderRadius}px`;
|
|
1634
|
+
if (style.fontSize !== undefined) out['font-size'] = `${style.fontSize}px`;
|
|
1635
|
+
if (style.fontWeight) out['font-weight'] = style.fontWeight;
|
|
1636
|
+
if (style.align) out['text-align'] = style.align;
|
|
1637
|
+
if (style.paddingY !== undefined) out['padding-block'] = `${style.paddingY}px`;
|
|
1638
|
+
if (style.paddingX !== undefined) out['padding-inline'] = `${style.paddingX}px`;
|
|
1639
|
+
|
|
1640
|
+
return out;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
// -----------------------------------------------------------------------------
|
|
1644
|
+
// Studio bridge
|
|
1645
|
+
// -----------------------------------------------------------------------------
|
|
1646
|
+
|
|
1647
|
+
/**
|
|
1648
|
+
* The message vocabulary between the Tools studio and the front rendered inside its frame.
|
|
1649
|
+
*
|
|
1650
|
+
* A separate protocol rather than a preview link with more query parameters, because the studio
|
|
1651
|
+
* has to do two things a link cannot: read back what is actually on the page - the anchors, their
|
|
1652
|
+
* labels, their nesting - and apply an edit without a reload, so that changing a colour is a
|
|
1653
|
+
* colour changing rather than a page blinking.
|
|
1654
|
+
*
|
|
1655
|
+
* Every message carries the protocol version. A front and a Tools release drift apart eventually,
|
|
1656
|
+
* and a version mismatch has to degrade to a plain preview rather than to an editor whose clicks
|
|
1657
|
+
* quietly do nothing.
|
|
1658
|
+
*/
|
|
1659
|
+
export const MVT_STUDIO_PROTOCOL = 2;
|
|
1660
|
+
|
|
1661
|
+
export type MvtStudioAnchorRole = 'section' | 'cta' | 'text' | 'image' | 'block';
|
|
1662
|
+
|
|
1663
|
+
export interface MvtStudioAnchor {
|
|
1664
|
+
/** Stable identifier written into the markup by the front, never derived from the DOM position. */
|
|
1665
|
+
id: string;
|
|
1666
|
+
label: string;
|
|
1667
|
+
role: MvtStudioAnchorRole;
|
|
1668
|
+
/** The anchor this one sits inside, for the studio's tree. Null at the top level. */
|
|
1669
|
+
parentId: string | null;
|
|
1670
|
+
order: number;
|
|
1671
|
+
/** What the untouched page shows today, so the editor opens on the real copy rather than an empty field. */
|
|
1672
|
+
text: string | null;
|
|
1673
|
+
movable: boolean;
|
|
1674
|
+
hideable: boolean;
|
|
1675
|
+
rect: { top: number; left: number; width: number; height: number };
|
|
1676
|
+
}
|
|
1677
|
+
|
|
1678
|
+
/**
|
|
1679
|
+
* Somewhere the studio can go next.
|
|
1680
|
+
*
|
|
1681
|
+
* The editor used to reach other pages through a free-text path field, which asked an operator to
|
|
1682
|
+
* already know the route they wanted and silently rendered a 404 inside the frame when they were
|
|
1683
|
+
* one character out. The front knows its own routes, so it says what they are.
|
|
1684
|
+
*
|
|
1685
|
+
* `kind` separates what the page happens to link to from what the front declares it can reach.
|
|
1686
|
+
* A storefront only has links; the checkout has steps that exist whether or not the current page
|
|
1687
|
+
* links to them, and an operator editing the payment step should not have to walk the funnel to
|
|
1688
|
+
* get there.
|
|
1689
|
+
*/
|
|
1690
|
+
export interface MvtStudioLink {
|
|
1691
|
+
path: string;
|
|
1692
|
+
label: string;
|
|
1693
|
+
kind: 'link' | 'step';
|
|
1694
|
+
/** Steps the cart has not unlocked yet are offered but marked, rather than hidden. */
|
|
1695
|
+
reachable: boolean;
|
|
1696
|
+
}
|
|
1697
|
+
|
|
1698
|
+
/**
|
|
1699
|
+
* The simulated basket the checkout studio runs on.
|
|
1700
|
+
*
|
|
1701
|
+
* Editing the funnel means being inside it, and being inside it means holding a cart. Minting one
|
|
1702
|
+
* by hand through the real onboarding flow every time is what made the checkout scope effectively
|
|
1703
|
+
* uneditable.
|
|
1704
|
+
*/
|
|
1705
|
+
export interface MvtStudioCart {
|
|
1706
|
+
reference: string;
|
|
1707
|
+
secret: string;
|
|
1708
|
+
/** Where the simulated cart currently sits, so the studio can offer the steps behind it. */
|
|
1709
|
+
step: string;
|
|
1710
|
+
simulated: true;
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1713
|
+
/** Tools to front. */
|
|
1714
|
+
export type MvtStudioRequest =
|
|
1715
|
+
| { protocol: number; type: 'studio:hello' }
|
|
1716
|
+
| { protocol: number; type: 'studio:scan' }
|
|
1717
|
+
| { protocol: number; type: 'studio:select'; anchorId: string | null }
|
|
1718
|
+
| { protocol: number; type: 'studio:apply'; anchors: Record<string, MvtAnchorPatch>; lang: string }
|
|
1719
|
+
| { protocol: number; type: 'studio:mode'; picking: boolean }
|
|
1720
|
+
| { protocol: number; type: 'studio:navigate'; path: string }
|
|
1721
|
+
| { protocol: number; type: 'studio:links' }
|
|
1722
|
+
| { protocol: number; type: 'studio:cart'; cart: MvtStudioCart };
|
|
1723
|
+
|
|
1724
|
+
/** Front to Tools. */
|
|
1725
|
+
export type MvtStudioEvent =
|
|
1726
|
+
| { protocol: number; type: 'studio:ready'; scope: MvtScope; path: string; langs: string[] }
|
|
1727
|
+
| { protocol: number; type: 'studio:anchors'; anchors: MvtStudioAnchor[]; path: string }
|
|
1728
|
+
| { protocol: number; type: 'studio:picked'; anchor: MvtStudioAnchor }
|
|
1729
|
+
| { protocol: number; type: 'studio:navigated'; path: string }
|
|
1730
|
+
| { protocol: number; type: 'studio:links'; links: MvtStudioLink[]; path: string }
|
|
1731
|
+
| { protocol: number; type: 'studio:cart'; cart: MvtStudioCart | null };
|
|
1732
|
+
|
|
1733
|
+
/**
|
|
1734
|
+
* Collect the navigable links of the page the front is currently showing.
|
|
1735
|
+
*
|
|
1736
|
+
* Shared rather than written twice, because the filtering is where this gets subtle and getting it
|
|
1737
|
+
* wrong in one front and not the other produces a link list that behaves differently depending on
|
|
1738
|
+
* which scope is being edited.
|
|
1739
|
+
*
|
|
1740
|
+
* Only same-origin, non-anchor, non-download links survive. An external link would navigate the
|
|
1741
|
+
* frame off the front entirely, taking the preview token with it and leaving the studio talking to
|
|
1742
|
+
* a page that has never heard of it; an in-page anchor is not a destination.
|
|
1743
|
+
*/
|
|
1744
|
+
export function mvtCollectLinks(root: ParentNode, origin: string): MvtStudioLink[] {
|
|
1745
|
+
const seen = new Set<string>();
|
|
1746
|
+
const links: MvtStudioLink[] = [];
|
|
1747
|
+
|
|
1748
|
+
for (const element of Array.from(root.querySelectorAll('a[href]'))) {
|
|
1749
|
+
const anchor = element as HTMLAnchorElement;
|
|
1750
|
+
|
|
1751
|
+
if (anchor.hasAttribute('download') || anchor.target === '_blank') continue;
|
|
1752
|
+
|
|
1753
|
+
let url: URL;
|
|
1754
|
+
|
|
1755
|
+
try {
|
|
1756
|
+
url = new URL(anchor.getAttribute('href') ?? '', origin);
|
|
1757
|
+
} catch {
|
|
1758
|
+
continue;
|
|
1759
|
+
}
|
|
1760
|
+
|
|
1761
|
+
if (url.origin !== origin) continue;
|
|
1762
|
+
if (!url.pathname.startsWith('/')) continue;
|
|
1763
|
+
if (seen.has(url.pathname)) continue;
|
|
1764
|
+
|
|
1765
|
+
seen.add(url.pathname);
|
|
1766
|
+
|
|
1767
|
+
// The visible text, collapsed. An operator picks a destination by the words they can see
|
|
1768
|
+
// on the page, not by its route, and a label carrying the whitespace of a three-line
|
|
1769
|
+
// menu entry is unreadable in a dropdown.
|
|
1770
|
+
const label = (anchor.textContent ?? '').replace(/\s+/g, ' ').trim();
|
|
1771
|
+
|
|
1772
|
+
links.push({ path: url.pathname, label: label || url.pathname, kind: 'link', reachable: true });
|
|
1773
|
+
}
|
|
1774
|
+
|
|
1775
|
+
return links.sort((a, b) => a.label.localeCompare(b.label));
|
|
1776
|
+
}
|
|
1777
|
+
|
|
1778
|
+
export function mvtIsStudioEvent(data: unknown): data is MvtStudioEvent {
|
|
1779
|
+
if (!data || typeof data !== 'object') return false;
|
|
1780
|
+
|
|
1781
|
+
const message = data as Partial<MvtStudioEvent>;
|
|
1782
|
+
|
|
1783
|
+
return message.protocol === MVT_STUDIO_PROTOCOL && typeof message.type === 'string' && message.type.startsWith('studio:');
|
|
1784
|
+
}
|
|
1785
|
+
|
|
1786
|
+
export function mvtIsStudioRequest(data: unknown): data is MvtStudioRequest {
|
|
1787
|
+
return mvtIsStudioEvent(data);
|
|
1788
|
+
}
|