@coframe/sdk 1.1.7 → 1.1.9

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.
@@ -181,6 +181,12 @@ function getBrowserPlatform() {
181
181
  function getBrowserReferrer() {
182
182
  return document.referrer;
183
183
  }
184
+ function getScreenSize() {
185
+ return {
186
+ width: window.innerWidth,
187
+ height: window.innerHeight,
188
+ };
189
+ }
184
190
  function getBrowserHostname() {
185
191
  return window.location.hostname;
186
192
  }
@@ -926,7 +932,7 @@ function warnEventsNotSent() {
926
932
  }
927
933
  }
928
934
 
929
- const SDK_VERSION = '2.5.0';
935
+ const SDK_VERSION = '2.6.0';
930
936
  const queuedEvents = [];
931
937
  const queuedMonitoringEvents = [];
932
938
  const queuedSessions = [];
@@ -942,7 +948,7 @@ function queueEventForBatchedSending(coframe, data, flushImmediately = false) {
942
948
  flushQueuedEvents(coframe.projectId);
943
949
  }
944
950
  }
945
- function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, experimentsInfo, startTime, referrer, platform, languages, userAgent, url, storageInfo, gaSessionInfo, cfId, personalizationHeaders) {
951
+ function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, experimentsInfo, startTime, referrer, platform, languages, userAgent, url, storageInfo, gaSessionInfo, cfId, personalizationHeaders, sessionContext) {
946
952
  queuedSessions.push({
947
953
  org_id: orgId,
948
954
  project_id: projectId,
@@ -960,6 +966,7 @@ function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, exp
960
966
  session_metadata: JSON.stringify({
961
967
  url,
962
968
  storage_info: storageInfo,
969
+ ...sessionContext,
963
970
  }),
964
971
  ga_session_id: gaSessionInfo === null || gaSessionInfo === void 0 ? void 0 : gaSessionInfo.ga_session_id,
965
972
  ga_session_number: gaSessionInfo === null || gaSessionInfo === void 0 ? void 0 : gaSessionInfo.ga_session_number,
@@ -1028,20 +1035,9 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
1028
1035
  user_token: userToken,
1029
1036
  });
1030
1037
  }
1031
- function sendPageEngagementEvent(coframe, eventType, event, { isEngaged, projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, }) {
1038
+ function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
1032
1039
  var _a;
1033
1040
  const startTime = performance.now();
1034
- if (!isEngaged && eventType === 'click') {
1035
- isEngaged = true;
1036
- queueEvent(coframe, {
1037
- projectId,
1038
- sessionId,
1039
- eventType: 'session_start',
1040
- orgId,
1041
- userToken: userToken || '',
1042
- personalizationHeaders,
1043
- });
1044
- }
1045
1041
  const x = event.clientX + window.scrollX;
1046
1042
  const y = event.clientY + window.scrollY;
1047
1043
  const screenWidth = window.innerWidth;
@@ -2491,6 +2487,59 @@ async function getVariantsAndElements(personalizationHeaders, project, previewVa
2491
2487
  });
2492
2488
  }
2493
2489
 
2490
+ function buildSessionContext(isInitialApply) {
2491
+ const context = {};
2492
+ const viewport = getScreenSize();
2493
+ if (isReportedSize(viewport.width) && isReportedSize(viewport.height)) {
2494
+ context.viewport_width = viewport.width;
2495
+ context.viewport_height = viewport.height;
2496
+ }
2497
+ const visitCount = getCookie(VISIT_COUNT_COOKIE_KEY);
2498
+ if (/^[1-9]\d{0,14}$/.test(visitCount)) {
2499
+ context.visit_count = Number(visitCount);
2500
+ }
2501
+ try {
2502
+ context.navigation_type = getNavigationType(isInitialApply);
2503
+ }
2504
+ catch (_a) {
2505
+ }
2506
+ try {
2507
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2508
+ if (timezone) {
2509
+ context.timezone = timezone;
2510
+ }
2511
+ }
2512
+ catch (_b) {
2513
+ }
2514
+ return context;
2515
+ }
2516
+ function isReportedSize(size) {
2517
+ return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
2518
+ }
2519
+ function getNavigationType(isInitialApply) {
2520
+ var _a, _b;
2521
+ if (!isInitialApply) {
2522
+ return 'spa_navigation';
2523
+ }
2524
+ const nav = (_b = (_a = performance.getEntriesByType) === null || _a === void 0 ? void 0 : _a.call(performance, 'navigation')) === null || _b === void 0 ? void 0 : _b[0];
2525
+ if (nav) {
2526
+ if (nav.type === 'reload')
2527
+ return 'reload';
2528
+ if (nav.type === 'back_forward')
2529
+ return 'back_forward';
2530
+ return nav.type === 'navigate' ? 'initial_load' : undefined;
2531
+ }
2532
+ const legacy = performance.navigation;
2533
+ if (legacy) {
2534
+ if (legacy.type === 1)
2535
+ return 'reload';
2536
+ if (legacy.type === 2)
2537
+ return 'back_forward';
2538
+ return legacy.type === 0 ? 'initial_load' : undefined;
2539
+ }
2540
+ return undefined;
2541
+ }
2542
+
2494
2543
  const CACHE_TTL_MS = 60 * 1000;
2495
2544
  const cache = new Map();
2496
2545
  function getCachedFrames(url) {
@@ -2831,7 +2880,7 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
2831
2880
  patchHistoryMethod('replaceState');
2832
2881
  }
2833
2882
 
2834
- function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders) {
2883
+ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext) {
2835
2884
  const sessionPayload = [
2836
2885
  Coframe,
2837
2886
  Coframe.orgId,
@@ -2848,7 +2897,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
2848
2897
  getBrowserFignerprintInfo(),
2849
2898
  ];
2850
2899
  {
2851
- queueCreateSession(...sessionPayload, undefined, undefined, personalizationHeaders);
2900
+ queueCreateSession(...sessionPayload, undefined, undefined, personalizationHeaders, sessionContext);
2852
2901
  }
2853
2902
  queueEvent(Coframe, {
2854
2903
  projectId: Coframe.projectId,
@@ -3026,22 +3075,39 @@ const ENGAGED_SESSION_THRESHOLD = 10000;
3026
3075
  function setupListeners(Coframe, executionStartTime) {
3027
3076
  const experiencedCoframeIds = new Set();
3028
3077
  let isEngaged = false;
3029
- function measureEngagement() {
3030
- const timeSpent = Date.now() - (executionStartTime ? executionStartTime.getTime() : 0);
3031
- if (!isEngaged && timeSpent >= ENGAGED_SESSION_THRESHOLD) {
3032
- isEngaged = true;
3033
- queueEvent(Coframe, {
3034
- projectId: Coframe.projectId,
3035
- sessionId: Coframe.sessionId,
3036
- eventType: 'session_start',
3037
- orgId: Coframe.orgId,
3038
- userToken: Coframe.userToken,
3039
- personalizationHeaders: Coframe.personalizationHeaders,
3040
- });
3078
+ let engagementTimer = null;
3079
+ function markEngaged() {
3080
+ if (isEngaged)
3081
+ return;
3082
+ isEngaged = true;
3083
+ if (engagementTimer !== null) {
3084
+ clearTimeout(engagementTimer);
3085
+ engagementTimer = null;
3041
3086
  }
3042
- else {
3043
- setTimeout(measureEngagement, ENGAGED_SESSION_THRESHOLD - timeSpent);
3087
+ queueEvent(Coframe, {
3088
+ projectId: Coframe.projectId,
3089
+ sessionId: Coframe.sessionId,
3090
+ eventType: 'session_start',
3091
+ orgId: Coframe.orgId,
3092
+ userToken: Coframe.userToken,
3093
+ personalizationHeaders: Coframe.personalizationHeaders,
3094
+ });
3095
+ }
3096
+ function scheduleEngagementMeasurement() {
3097
+ if (isEngaged)
3098
+ return;
3099
+ const timeSpent = Date.now() - (executionStartTime ? executionStartTime.getTime() : 0);
3100
+ const remaining = ENGAGED_SESSION_THRESHOLD - timeSpent;
3101
+ if (remaining <= 0) {
3102
+ markEngaged();
3103
+ return;
3044
3104
  }
3105
+ if (engagementTimer !== null)
3106
+ return;
3107
+ engagementTimer = setTimeout(() => {
3108
+ engagementTimer = null;
3109
+ scheduleEngagementMeasurement();
3110
+ }, remaining);
3045
3111
  }
3046
3112
  function updateViewedVariants() {
3047
3113
  for (const variantElement of Coframe.variantsAndElements || []) {
@@ -3065,21 +3131,21 @@ function setupListeners(Coframe, executionStartTime) {
3065
3131
  }
3066
3132
  }
3067
3133
  }
3068
- document.addEventListener('visibilitychange', measureEngagement);
3069
- setTimeout(measureEngagement, ENGAGED_SESSION_THRESHOLD);
3134
+ document.addEventListener('visibilitychange', scheduleEngagementMeasurement);
3135
+ scheduleEngagementMeasurement();
3070
3136
  document.addEventListener('coframe:dom-renderer:complete', updateViewedVariants);
3071
3137
  document.addEventListener('scroll', updateViewedVariants);
3072
3138
  document.dispatchEvent(new CustomEvent('coframe:dom-renderer:complete', {}));
3073
- document.addEventListener('click', (event) => {
3139
+ const handleClick = (event) => {
3140
+ markEngaged();
3074
3141
  sendPageEngagementEvent(Coframe, 'click', event, {
3075
3142
  projectId: Coframe.projectId,
3076
- isEngaged,
3077
3143
  sessionId: Coframe.sessionId,
3078
- orgId: Coframe.orgId,
3079
3144
  userToken: Coframe.userToken,
3080
3145
  personalizationHeaders: Coframe.personalizationHeaders,
3081
3146
  });
3082
- }, true);
3147
+ };
3148
+ document.addEventListener('click', handleClick, true);
3083
3149
  const handleEventFlush = debounce((eventType) => {
3084
3150
  queueEvent(Coframe, {
3085
3151
  projectId: Coframe.projectId,
@@ -3278,6 +3344,7 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
3278
3344
  let isFirstApply = true;
3279
3345
  return async (pageUrl, pageProject) => {
3280
3346
  const sessionId = isFirstApply ? Coframe.sessionId : generateUUID();
3347
+ const sessionContext = buildSessionContext(isFirstApply);
3281
3348
  isFirstApply = false;
3282
3349
  Coframe.sessionId = sessionId;
3283
3350
  const preview = resolvePreview(pageUrl, previewVariantId, isSessionVariant);
@@ -3301,7 +3368,7 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
3301
3368
  else {
3302
3369
  replaceVariants(variantsAndElements, Coframe.orgId, Coframe.logger, config.nonce);
3303
3370
  }
3304
- startSession(Coframe, isCookiesEnabled, executionStartTime, personalizationHeaders);
3371
+ startSession(Coframe, isCookiesEnabled, executionStartTime, personalizationHeaders, sessionContext);
3305
3372
  analytics.resetBroadcasted();
3306
3373
  analytics.sendAnalytics();
3307
3374
  };
@@ -179,6 +179,12 @@ function getBrowserPlatform() {
179
179
  function getBrowserReferrer() {
180
180
  return document.referrer;
181
181
  }
182
+ function getScreenSize() {
183
+ return {
184
+ width: window.innerWidth,
185
+ height: window.innerHeight,
186
+ };
187
+ }
182
188
  function getBrowserHostname() {
183
189
  return window.location.hostname;
184
190
  }
@@ -924,7 +930,7 @@ function warnEventsNotSent() {
924
930
  }
925
931
  }
926
932
 
927
- const SDK_VERSION = '2.5.0';
933
+ const SDK_VERSION = '2.6.0';
928
934
  const queuedEvents = [];
929
935
  const queuedMonitoringEvents = [];
930
936
  const queuedSessions = [];
@@ -940,7 +946,7 @@ function queueEventForBatchedSending(coframe, data, flushImmediately = false) {
940
946
  flushQueuedEvents(coframe.projectId);
941
947
  }
942
948
  }
943
- function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, experimentsInfo, startTime, referrer, platform, languages, userAgent, url, storageInfo, gaSessionInfo, cfId, personalizationHeaders) {
949
+ function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, experimentsInfo, startTime, referrer, platform, languages, userAgent, url, storageInfo, gaSessionInfo, cfId, personalizationHeaders, sessionContext) {
944
950
  queuedSessions.push({
945
951
  org_id: orgId,
946
952
  project_id: projectId,
@@ -958,6 +964,7 @@ function queueCreateSession(coframe, orgId, projectId, sessionId, userToken, exp
958
964
  session_metadata: JSON.stringify({
959
965
  url,
960
966
  storage_info: storageInfo,
967
+ ...sessionContext,
961
968
  }),
962
969
  ga_session_id: gaSessionInfo === null || gaSessionInfo === void 0 ? void 0 : gaSessionInfo.ga_session_id,
963
970
  ga_session_number: gaSessionInfo === null || gaSessionInfo === void 0 ? void 0 : gaSessionInfo.ga_session_number,
@@ -1026,20 +1033,9 @@ function queueVariantViewEvent(coframe, { projectId, sessionId, orgId, userToken
1026
1033
  user_token: userToken,
1027
1034
  });
1028
1035
  }
1029
- function sendPageEngagementEvent(coframe, eventType, event, { isEngaged, projectId, sessionId, orgId, duration = 0, userToken, personalizationHeaders, }) {
1036
+ function sendPageEngagementEvent(coframe, eventType, event, { projectId, sessionId, duration = 0, userToken, personalizationHeaders, }) {
1030
1037
  var _a;
1031
1038
  const startTime = performance.now();
1032
- if (!isEngaged && eventType === 'click') {
1033
- isEngaged = true;
1034
- queueEvent(coframe, {
1035
- projectId,
1036
- sessionId,
1037
- eventType: 'session_start',
1038
- orgId,
1039
- userToken: userToken || '',
1040
- personalizationHeaders,
1041
- });
1042
- }
1043
1039
  const x = event.clientX + window.scrollX;
1044
1040
  const y = event.clientY + window.scrollY;
1045
1041
  const screenWidth = window.innerWidth;
@@ -2489,6 +2485,59 @@ async function getVariantsAndElements(personalizationHeaders, project, previewVa
2489
2485
  });
2490
2486
  }
2491
2487
 
2488
+ function buildSessionContext(isInitialApply) {
2489
+ const context = {};
2490
+ const viewport = getScreenSize();
2491
+ if (isReportedSize(viewport.width) && isReportedSize(viewport.height)) {
2492
+ context.viewport_width = viewport.width;
2493
+ context.viewport_height = viewport.height;
2494
+ }
2495
+ const visitCount = getCookie(VISIT_COUNT_COOKIE_KEY);
2496
+ if (/^[1-9]\d{0,14}$/.test(visitCount)) {
2497
+ context.visit_count = Number(visitCount);
2498
+ }
2499
+ try {
2500
+ context.navigation_type = getNavigationType(isInitialApply);
2501
+ }
2502
+ catch (_a) {
2503
+ }
2504
+ try {
2505
+ const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
2506
+ if (timezone) {
2507
+ context.timezone = timezone;
2508
+ }
2509
+ }
2510
+ catch (_b) {
2511
+ }
2512
+ return context;
2513
+ }
2514
+ function isReportedSize(size) {
2515
+ return (typeof size === 'number' && size > 0 && size !== Number.POSITIVE_INFINITY);
2516
+ }
2517
+ function getNavigationType(isInitialApply) {
2518
+ var _a, _b;
2519
+ if (!isInitialApply) {
2520
+ return 'spa_navigation';
2521
+ }
2522
+ const nav = (_b = (_a = performance.getEntriesByType) === null || _a === void 0 ? void 0 : _a.call(performance, 'navigation')) === null || _b === void 0 ? void 0 : _b[0];
2523
+ if (nav) {
2524
+ if (nav.type === 'reload')
2525
+ return 'reload';
2526
+ if (nav.type === 'back_forward')
2527
+ return 'back_forward';
2528
+ return nav.type === 'navigate' ? 'initial_load' : undefined;
2529
+ }
2530
+ const legacy = performance.navigation;
2531
+ if (legacy) {
2532
+ if (legacy.type === 1)
2533
+ return 'reload';
2534
+ if (legacy.type === 2)
2535
+ return 'back_forward';
2536
+ return legacy.type === 0 ? 'initial_load' : undefined;
2537
+ }
2538
+ return undefined;
2539
+ }
2540
+
2492
2541
  const CACHE_TTL_MS = 60 * 1000;
2493
2542
  const cache = new Map();
2494
2543
  function getCachedFrames(url) {
@@ -2829,7 +2878,7 @@ function observeUrlChanges(baseUrlMatch, onUrlChange) {
2829
2878
  patchHistoryMethod('replaceState');
2830
2879
  }
2831
2880
 
2832
- function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders) {
2881
+ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizationHeaders, sessionContext) {
2833
2882
  const sessionPayload = [
2834
2883
  Coframe,
2835
2884
  Coframe.orgId,
@@ -2846,7 +2895,7 @@ function startSession(Coframe, cookiesEnabled, executionStartTime, personalizati
2846
2895
  getBrowserFignerprintInfo(),
2847
2896
  ];
2848
2897
  {
2849
- queueCreateSession(...sessionPayload, undefined, undefined, personalizationHeaders);
2898
+ queueCreateSession(...sessionPayload, undefined, undefined, personalizationHeaders, sessionContext);
2850
2899
  }
2851
2900
  queueEvent(Coframe, {
2852
2901
  projectId: Coframe.projectId,
@@ -3024,22 +3073,39 @@ const ENGAGED_SESSION_THRESHOLD = 10000;
3024
3073
  function setupListeners(Coframe, executionStartTime) {
3025
3074
  const experiencedCoframeIds = new Set();
3026
3075
  let isEngaged = false;
3027
- function measureEngagement() {
3028
- const timeSpent = Date.now() - (executionStartTime ? executionStartTime.getTime() : 0);
3029
- if (!isEngaged && timeSpent >= ENGAGED_SESSION_THRESHOLD) {
3030
- isEngaged = true;
3031
- queueEvent(Coframe, {
3032
- projectId: Coframe.projectId,
3033
- sessionId: Coframe.sessionId,
3034
- eventType: 'session_start',
3035
- orgId: Coframe.orgId,
3036
- userToken: Coframe.userToken,
3037
- personalizationHeaders: Coframe.personalizationHeaders,
3038
- });
3076
+ let engagementTimer = null;
3077
+ function markEngaged() {
3078
+ if (isEngaged)
3079
+ return;
3080
+ isEngaged = true;
3081
+ if (engagementTimer !== null) {
3082
+ clearTimeout(engagementTimer);
3083
+ engagementTimer = null;
3039
3084
  }
3040
- else {
3041
- setTimeout(measureEngagement, ENGAGED_SESSION_THRESHOLD - timeSpent);
3085
+ queueEvent(Coframe, {
3086
+ projectId: Coframe.projectId,
3087
+ sessionId: Coframe.sessionId,
3088
+ eventType: 'session_start',
3089
+ orgId: Coframe.orgId,
3090
+ userToken: Coframe.userToken,
3091
+ personalizationHeaders: Coframe.personalizationHeaders,
3092
+ });
3093
+ }
3094
+ function scheduleEngagementMeasurement() {
3095
+ if (isEngaged)
3096
+ return;
3097
+ const timeSpent = Date.now() - (executionStartTime ? executionStartTime.getTime() : 0);
3098
+ const remaining = ENGAGED_SESSION_THRESHOLD - timeSpent;
3099
+ if (remaining <= 0) {
3100
+ markEngaged();
3101
+ return;
3042
3102
  }
3103
+ if (engagementTimer !== null)
3104
+ return;
3105
+ engagementTimer = setTimeout(() => {
3106
+ engagementTimer = null;
3107
+ scheduleEngagementMeasurement();
3108
+ }, remaining);
3043
3109
  }
3044
3110
  function updateViewedVariants() {
3045
3111
  for (const variantElement of Coframe.variantsAndElements || []) {
@@ -3063,21 +3129,21 @@ function setupListeners(Coframe, executionStartTime) {
3063
3129
  }
3064
3130
  }
3065
3131
  }
3066
- document.addEventListener('visibilitychange', measureEngagement);
3067
- setTimeout(measureEngagement, ENGAGED_SESSION_THRESHOLD);
3132
+ document.addEventListener('visibilitychange', scheduleEngagementMeasurement);
3133
+ scheduleEngagementMeasurement();
3068
3134
  document.addEventListener('coframe:dom-renderer:complete', updateViewedVariants);
3069
3135
  document.addEventListener('scroll', updateViewedVariants);
3070
3136
  document.dispatchEvent(new CustomEvent('coframe:dom-renderer:complete', {}));
3071
- document.addEventListener('click', (event) => {
3137
+ const handleClick = (event) => {
3138
+ markEngaged();
3072
3139
  sendPageEngagementEvent(Coframe, 'click', event, {
3073
3140
  projectId: Coframe.projectId,
3074
- isEngaged,
3075
3141
  sessionId: Coframe.sessionId,
3076
- orgId: Coframe.orgId,
3077
3142
  userToken: Coframe.userToken,
3078
3143
  personalizationHeaders: Coframe.personalizationHeaders,
3079
3144
  });
3080
- }, true);
3145
+ };
3146
+ document.addEventListener('click', handleClick, true);
3081
3147
  const handleEventFlush = debounce((eventType) => {
3082
3148
  queueEvent(Coframe, {
3083
3149
  projectId: Coframe.projectId,
@@ -3276,6 +3342,7 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
3276
3342
  let isFirstApply = true;
3277
3343
  return async (pageUrl, pageProject) => {
3278
3344
  const sessionId = isFirstApply ? Coframe.sessionId : generateUUID();
3345
+ const sessionContext = buildSessionContext(isFirstApply);
3279
3346
  isFirstApply = false;
3280
3347
  Coframe.sessionId = sessionId;
3281
3348
  const preview = resolvePreview(pageUrl, previewVariantId, isSessionVariant);
@@ -3299,7 +3366,7 @@ function createApplyVariants(Coframe, config, previewVariantId, isSessionVariant
3299
3366
  else {
3300
3367
  replaceVariants(variantsAndElements, Coframe.orgId, Coframe.logger, config.nonce);
3301
3368
  }
3302
- startSession(Coframe, isCookiesEnabled, executionStartTime, personalizationHeaders);
3369
+ startSession(Coframe, isCookiesEnabled, executionStartTime, personalizationHeaders, sessionContext);
3303
3370
  analytics.resetBroadcasted();
3304
3371
  analytics.sendAnalytics();
3305
3372
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coframe/sdk",
3
- "version": "1.1.7",
3
+ "version": "1.1.9",
4
4
  "description": "Coframe optimizes your website using generative AI to deliver maximum impact to your audience and allow your site to improve itself as you sleep. Learn more at coframe.com.",
5
5
  "main": "dist/pkg/cf.cjs.js",
6
6
  "module": "dist/pkg/cf.esm.mjs",
@@ -28,6 +28,7 @@
28
28
  "scripts": {
29
29
  "test:jest": "jest --maxWorkers=2",
30
30
  "test:playwright": "npx playwright test --retries=5 --reporter=list",
31
+ "test:package": "node ./tests/package/scripts/test-package.mjs",
31
32
  "test:browserstack:full": "jest --config jest.browserstack.config.js --suite=full",
32
33
  "test:browserstack:small": "jest --config jest.browserstack.config.js --suite=small",
33
34
  "test": "npm run test:jest && npm run test:playwright",