abmp-npm 10.3.6 → 10.3.7

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.
@@ -1,5 +1,3 @@
1
- const axios = require('axios');
2
-
3
1
  const { COLLECTIONS } = require('../../public/consts');
4
2
  const { clearCollection } = require('../cms-data-methods');
5
3
  const { CONFIG_KEYS } = require('../consts');
@@ -12,9 +10,13 @@ const getInterests = async () => {
12
10
  getSiteConfigs(CONFIG_KEYS.INTERESTS_API_URL),
13
11
  getHeaders(),
14
12
  ]);
13
+ const fetchOptions = {
14
+ method: 'get',
15
+ headers: headers,
16
+ };
15
17
  try {
16
- const response = await axios.get(url, { headers });
17
- return response.data;
18
+ const response = await fetch(url, fetchOptions);
19
+ return await response.json();
18
20
  } catch (e) {
19
21
  console.error('Error getting interests:', e);
20
22
  throw e;
@@ -1,6 +1,5 @@
1
1
  const { createHmac } = require('crypto');
2
2
 
3
- const axios = require('axios');
4
3
  const { decode } = require('jwt-js-decode');
5
4
 
6
5
  const { CONFIG_KEYS, SSO_TOKEN_AUTH_API_URL } = require('../consts');
@@ -92,16 +91,17 @@ async function checkAndFetchSSO(token) {
92
91
  const SSO_TOKEN_AUTH_API_KEY = await getSecret('SSO_TOKEN_AUTH_API_KEY');
93
92
  const signature = createHmac('sha256', SSO_TOKEN_AUTH_API_KEY).update(token).digest('hex');
94
93
  const professionalassistcorpUrl = `${SSO_TOKEN_AUTH_API_URL}/eweb/SSOToken.ashx?token=${token}&Partner=Wix&Signature=${signature}`;
94
+ const options = {
95
+ method: 'get',
96
+ };
95
97
  try {
96
- const httpResponse = await axios.get(professionalassistcorpUrl, {
97
- transformResponse: [d => d],
98
- validateStatus: () => true,
99
- });
98
+ const httpResponse = await fetch(professionalassistcorpUrl, options);
100
99
  console.log('httpResponse status', httpResponse.status);
101
- if (httpResponse.status < 200 || httpResponse.status >= 300) {
100
+ if (!httpResponse.ok) {
102
101
  throw new Error('Fetch did not succeed with status: ' + httpResponse.status);
103
102
  }
104
- return httpResponse.data;
103
+ const responseToken = await httpResponse.text();
104
+ return responseToken;
105
105
  } catch (error) {
106
106
  console.error('Error in checkAndFetchSSO', error);
107
107
  return null;
@@ -1,5 +1,3 @@
1
- const axios = require('axios');
2
-
3
1
  const { PAC_API_URL, TEST_PAC_API_URL, BACKUP_API_URL } = require('./consts');
4
2
  const { getSecret } = require('./utils');
5
3
 
@@ -33,22 +31,24 @@ const fetchPACMembers = async ({ page, action, backupDate, isTestEnvironment })
33
31
  const url = `${baseUrl}/Members?${new URLSearchParams(queryParams).toString()}`;
34
32
  console.log(`Fetching PAC members from: ${url}`);
35
33
  const headers = await getHeaders();
36
- const response = await axios.get(url, {
37
- headers,
38
- validateStatus: () => true,
39
- });
40
- const responseType = response.headers['content-type'] || '';
34
+ const fetchOptions = {
35
+ method: 'get',
36
+ headers: headers,
37
+ };
38
+ const response = await fetch(url, fetchOptions);
39
+ const responseType = response.headers.get('content-type');
41
40
  if (!responseType.includes('application/json')) {
42
41
  const errorMessage = `[fetchPACMembers] got invalid responseType: ${responseType} for page ${page} and actionFilter ${action}`;
43
42
  console.error(errorMessage);
44
43
  throw new Error(errorMessage);
45
44
  }
46
- if (response.status >= 200 && response.status < 300) {
47
- return response.data;
45
+ if (response.ok) {
46
+ return response.json();
47
+ } else {
48
+ const errorMessage = `[fetchPACMembers] failed with status ${response.status} for page ${page} and actionFilter ${action}`;
49
+ console.error(errorMessage);
50
+ throw new Error(errorMessage);
48
51
  }
49
- const errorMessage = `[fetchPACMembers] failed with status ${response.status} for page ${page} and actionFilter ${action}`;
50
- console.error(errorMessage);
51
- throw new Error(errorMessage);
52
52
  };
53
53
 
54
54
  module.exports = { fetchPACMembers, getHeaders }; //TODO: remove getHeaders from exported methods once npm movement finishes
@@ -103,23 +103,23 @@ async function updateMemberRichContent(memberId) {
103
103
  content: htmlString,
104
104
  });
105
105
 
106
- const requestHeaders = {
107
- 'Content-Type': 'application/json',
108
- Cookie: 'XSRF-TOKEN=1753949844|p--a7HsuVjR4',
109
- Authorization: 'Bearer ' + (await getServerlessAuth()),
106
+ const requestOptions = {
107
+ method: 'post',
108
+ headers: {
109
+ 'Content-Type': 'application/json',
110
+ Cookie: 'XSRF-TOKEN=1753949844|p--a7HsuVjR4',
111
+ Authorization: 'Bearer ' + (await getServerlessAuth()),
112
+ },
113
+ body: raw,
110
114
  };
111
115
 
112
116
  try {
113
- const response = await axios.post(
117
+ const response = await fetch(
114
118
  'https://www.wixapis.com/data-sync/v1/abmp-content-converter',
115
- raw,
116
- {
117
- headers: requestHeaders,
118
- validateStatus: () => true,
119
- }
119
+ requestOptions
120
120
  );
121
- if (response.status >= 200 && response.status < 300) {
122
- const data = response.data;
121
+ if (response.ok) {
122
+ const data = await response.json();
123
123
  const updatedMember = {
124
124
  ...member,
125
125
  aboutYourSelf: data.richContent.richContent,
@@ -358,13 +358,9 @@ async function uploadMembersSitemap({ members, tokens, destinationFileName, site
358
358
 
359
359
  const url = `https://${host}${pathName}`;
360
360
  console.log('url', url);
361
- const res = await axios.put(url, body, {
362
- headers: reqOpts.headers,
363
- transformResponse: [d => d],
364
- validateStatus: () => true,
365
- });
366
- if (res.status < 200 || res.status >= 300) {
367
- const respText = res.data;
361
+ const res = await fetch(url, { method, headers: reqOpts.headers, body });
362
+ if (!res.ok) {
363
+ const respText = await res.text();
368
364
  console.log('Response body', respText);
369
365
  throw new Error(`S3 PUT failed ${res.status} ${res.statusText}: ${respText}`);
370
366
  }
@@ -395,13 +391,13 @@ async function stsPost(body, baseAccessKeyId, baseSecretAccessKey) {
395
391
  accessKeyId: baseAccessKeyId,
396
392
  secretAccessKey: baseSecretAccessKey,
397
393
  });
398
- const res = await axios.post(`https://${host}${path}`, body, {
394
+ const res = await fetch(`https://${host}${path}`, {
395
+ method,
399
396
  headers: reqOpts.headers,
400
- transformResponse: [d => d],
401
- validateStatus: () => true,
397
+ body,
402
398
  });
403
- const text = res.data;
404
- if (res.status < 200 || res.status >= 300) throw new Error(`STS ${res.status}: ${text}`);
399
+ const text = await res.text();
400
+ if (!res.ok) throw new Error(`STS ${res.status}: ${text}`);
405
401
 
406
402
  const accessKeyId = parseXmlVal(text, 'AccessKeyId');
407
403
  const secretAccessKey = parseXmlVal(text, 'SecretAccessKey');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmp-npm",
3
- "version": "10.3.6",
3
+ "version": "10.3.7",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "check-cycles": "madge --circular .",
package/pages/Home.js CHANGED
@@ -5,6 +5,7 @@ const { withWarmUpData } = require('psdev-utils/frontend');
5
5
 
6
6
  const { ADDRESS_STATUS_TYPES, DEFAULT_FILTER, DROPDOWN_OPTIONS } = require('../public/consts.js');
7
7
  const { createHomepageUtils } = require('../public/Utils/homePage.js');
8
+ const { logHomePageLoadPhase } = require('../public/Utils/homePageLoadTrace.js');
8
9
  const {
9
10
  getMainAddress,
10
11
  formatPracticeAreasForDisplay,
@@ -13,6 +14,8 @@ const {
13
14
  normalizeExternalUrl,
14
15
  } = require('../public/Utils/sharedUtils.js');
15
16
 
17
+ logHomePageLoadPhase('home_js_module_evaluated');
18
+
16
19
  let filter = JSON.parse(JSON.stringify(DEFAULT_FILTER));
17
20
  let dropDownOptions = JSON.parse(JSON.stringify(DROPDOWN_OPTIONS));
18
21
  let stateCityMap;
@@ -36,6 +39,7 @@ const homePageOnReady = async ({
36
39
  getNonCompiledFiltersOptions,
37
40
  filterProfiles,
38
41
  }) => {
42
+ logHomePageLoadPhase('wix_onready_handler_entered');
39
43
  const {
40
44
  getParamsMapping,
41
45
  handlePagination,
@@ -58,7 +62,9 @@ const homePageOnReady = async ({
58
62
  detectMobile();
59
63
  initPageUI();
60
64
  attachEventListeners();
65
+ logHomePageLoadPhase('before_handleUrlParams');
61
66
  await handleUrlParams();
67
+ logHomePageLoadPhase('after_handleUrlParams');
62
68
 
63
69
  async function detectMobile() {
64
70
  try {
@@ -288,7 +294,9 @@ const homePageOnReady = async ({
288
294
  }
289
295
 
290
296
  async function applyFilterToUI(isDefaultStateParams) {
297
+ logHomePageLoadPhase('applyFilterToUI_start', { isDefaultStateParams });
291
298
  const renderingEnv = await rendering.env();
299
+ logHomePageLoadPhase('applyFilterToUI_rendering_env', { env: renderingEnv });
292
300
  const setFilterFromParams = async (isInitializeValue = true) => {
293
301
  const params = await wixLocation.query();
294
302
  console.log('params inside setFilterFromParams ', params);
@@ -322,7 +330,9 @@ const homePageOnReady = async ({
322
330
  await setFilterFromParams(true);
323
331
  if (isDefaultStateParams) {
324
332
  console.log('default state set for nearby');
333
+ logHomePageLoadPhase('applyFilterToUI_default_path_fetch_and_nearby_start');
325
334
  await Promise.all([fetchFilterData(), nearByHandler(true)]);
335
+ logHomePageLoadPhase('applyFilterToUI_default_path_complete');
326
336
  return;
327
337
  }
328
338
  console.log('not default state');
@@ -341,12 +351,15 @@ const homePageOnReady = async ({
341
351
  : () => updateResults('filterTimeout', true);
342
352
  console.log('filter ..', filter);
343
353
  try {
354
+ logHomePageLoadPhase('applyFilterToUI_non_default_path_start');
344
355
  await Promise.all([
345
356
  fetchFilterData().then(() => setFilterFromParams(false)),
346
357
  //TODO: remove this workaround to fix issue with SSR showing invalid results
347
358
  renderingEnv === 'backend' ? Promise.resolve() : searchPromise(),
348
359
  ]);
360
+ logHomePageLoadPhase('applyFilterToUI_non_default_path_complete');
349
361
  } catch (error) {
362
+ logHomePageLoadPhase('applyFilterToUI_error', { message: String(error && error.message) });
350
363
  console.error('[applyFilterToUI] failed with error:', error);
351
364
  multiStateBoxSelector.changeState('errorState');
352
365
  }
@@ -425,6 +438,7 @@ const homePageOnReady = async ({
425
438
  }
426
439
  // NEAR BY FILTER
427
440
  async function nearByHandler(preservePagination = false) {
441
+ logHomePageLoadPhase('nearByHandler_start', { preservePagination });
428
442
  const isSearchingNearby = _$w('#nearBy').checked;
429
443
  const renderingEnv = await rendering.env();
430
444
  // 1. Disable nearby input while processing
@@ -438,6 +452,7 @@ const homePageOnReady = async ({
438
452
  filter = newFilter;
439
453
  console.log('filter inside nearByHandler', filter);
440
454
  if (!success) {
455
+ logHomePageLoadPhase('nearByHandler_geolocation_failed');
441
456
  if (renderingEnv !== 'backend') {
442
457
  //on Backend environment, geolocation API don't work, so makes no sense to change state for near by
443
458
  multiStateBoxSelector.changeState('nearByState');
@@ -452,6 +467,7 @@ const homePageOnReady = async ({
452
467
  // If location is not selected, change state to "resultsState"
453
468
  if (!isSearchingNearby) {
454
469
  if (await noSearchCriteria()) {
470
+ logHomePageLoadPhase('nearByHandler_no_search_criteria');
455
471
  multiStateBoxSelector.changeState('noSearchCriteria');
456
472
  // 4. Re-enable nearby input
457
473
  _$w('#nearBy').enable();
@@ -463,6 +479,7 @@ const homePageOnReady = async ({
463
479
 
464
480
  // 4. Re-enable nearby input when done
465
481
  _$w('#nearBy').enable();
482
+ logHomePageLoadPhase('nearByHandler_complete', { success: true });
466
483
  return true;
467
484
  }
468
485
 
@@ -470,6 +487,7 @@ const homePageOnReady = async ({
470
487
  // FETCH STATE/CITY/AREAS OF PRACTICE FROM BACKEND ONCE AND STORE IT
471
488
 
472
489
  async function fetchFilterData() {
490
+ logHomePageLoadPhase('fetchFilterData_start');
473
491
  let completeStateList, areasOfPracticesList, stateCityMapList;
474
492
  try {
475
493
  const { COMPILED_STATE_LIST, COMPILED_AREAS_OF_PRACTICES, COMPILED_STATE_CITY_MAP } =
@@ -510,6 +528,7 @@ const homePageOnReady = async ({
510
528
 
511
529
  // Update filter states after data is loaded
512
530
  updateFiltersState();
531
+ logHomePageLoadPhase('fetchFilterData_complete');
513
532
  }
514
533
 
515
534
  // CONSTRUCT DROPDOWN OPTIONS FOR STATE, CITY, AREA OF PRACTICES
@@ -3,8 +3,46 @@ const { window: wixWindow, rendering } = require('@wix/site-window');
3
3
 
4
4
  const { DEFAULT_FILTER } = require('../consts.js');
5
5
 
6
+ const { logHomePageLoadPhase } = require('./homePageLoadTrace.js');
6
7
  const { debouncedFunction } = require('./sharedUtils.js');
7
8
 
9
+ function isValidGeolocation(lat, lng) {
10
+ return Number.isFinite(lat) && Number.isFinite(lng) && (lat !== 0 || lng !== 0);
11
+ }
12
+
13
+ function applyGeolocationToFilter(filter, lat, lng, isSearchingNearby) {
14
+ return {
15
+ ...filter,
16
+ postalcode: isSearchingNearby ? null : filter.postalcode,
17
+ state: isSearchingNearby ? [] : filter.state,
18
+ city: isSearchingNearby ? [] : filter.city,
19
+ stateSearch: isSearchingNearby ? '' : filter.stateSearch,
20
+ citySearch: isSearchingNearby ? '' : filter.citySearch,
21
+ latitude: lat,
22
+ longitude: lng,
23
+ };
24
+ }
25
+
26
+ const GEOLOCATION_TIMEOUT_MS = 10000;
27
+
28
+ function getCurrentGeolocationWithTimeout(timeoutMs = GEOLOCATION_TIMEOUT_MS) {
29
+ return new Promise((resolve, reject) => {
30
+ const timer = setTimeout(() => {
31
+ reject(new Error(`Geolocation timed out after ${timeoutMs}ms`));
32
+ }, timeoutMs);
33
+ wixWindow
34
+ .getCurrentGeolocation()
35
+ .then(location => {
36
+ clearTimeout(timer);
37
+ resolve(location);
38
+ })
39
+ .catch(error => {
40
+ clearTimeout(timer);
41
+ reject(error);
42
+ });
43
+ });
44
+ }
45
+
8
46
  const createHomepageUtils = (_$w, filterProfiles) => {
9
47
  const getFiltersSelectors = filterName => ({
10
48
  checkBoxContainerSelector: _$w(`#${filterName}CheckBoxContainer`),
@@ -362,30 +400,34 @@ const createHomepageUtils = (_$w, filterProfiles) => {
362
400
  });
363
401
  }
364
402
  async function getAndSetUserLocation(isSearchingNearby, filter) {
365
- try {
366
- let location = {
367
- coords: {
368
- latitude: 0,
369
- longitude: 0,
370
- },
403
+ logHomePageLoadPhase('getAndSetUserLocation_start', { isSearchingNearby });
404
+
405
+ const { latitude: existingLat, longitude: existingLng } = filter;
406
+ if (isValidGeolocation(existingLat, existingLng)) {
407
+ return {
408
+ success: true,
409
+ filter: applyGeolocationToFilter(filter, existingLat, existingLng, isSearchingNearby),
371
410
  };
372
- location = await wixWindow.getCurrentGeolocation();
411
+ }
373
412
 
413
+ try {
414
+ logHomePageLoadPhase('getAndSetUserLocation_before_getCurrentGeolocation');
415
+ const location = await getCurrentGeolocationWithTimeout();
374
416
  console.log('location inside getAndSetUserLocation', location);
375
417
  const userLat = location.coords?.latitude ?? 0;
376
418
  const userLong = location.coords?.longitude ?? 0;
377
- filter = {
378
- ...filter,
379
- postalcode: isSearchingNearby ? null : filter.postalcode,
380
- state: isSearchingNearby ? [] : filter.state,
381
- city: isSearchingNearby ? [] : filter.city,
382
- stateSearch: isSearchingNearby ? '' : filter.stateSearch,
383
- citySearch: isSearchingNearby ? '' : filter.citySearch,
384
- latitude: userLat,
385
- longitude: userLong,
419
+ logHomePageLoadPhase('getAndSetUserLocation_success', {
420
+ lat: userLat,
421
+ lng: userLong,
422
+ });
423
+ return {
424
+ success: true,
425
+ filter: applyGeolocationToFilter(filter, userLat, userLong, isSearchingNearby),
386
426
  };
387
- return { success: true, filter };
388
427
  } catch (error) {
428
+ logHomePageLoadPhase('getAndSetUserLocation_error', {
429
+ message: String(error && error.message),
430
+ });
389
431
  console.warn('Failed to get user location in getAndSetUserLocation', error);
390
432
  return { success: false, filter };
391
433
  }
@@ -504,6 +546,7 @@ const createHomepageUtils = (_$w, filterProfiles) => {
504
546
  );
505
547
  }
506
548
  async function parseAndValidateQueryParams(filter, pagination) {
549
+ logHomePageLoadPhase('parseAndValidateQueryParams_start');
507
550
  const params = await wixLocation.query();
508
551
  const paramsMapping = getParamsMapping(filter, pagination);
509
552
  const {
@@ -515,6 +558,11 @@ const createHomepageUtils = (_$w, filterProfiles) => {
515
558
  const isSearchingNearby = params.nearby === 'true';
516
559
  const isNoParams = !withoutPreviewParams || Object.keys(withoutPreviewParams).length === 0;
517
560
  const { success, filter: newFilter } = await getAndSetUserLocation(isSearchingNearby, filter);
561
+ logHomePageLoadPhase('parseAndValidateQueryParams_after_geolocation', {
562
+ isNoParams,
563
+ isSearchingNearby,
564
+ success,
565
+ });
518
566
 
519
567
  // Auto-enable nearby if GPS permission granted on fresh page load
520
568
  if (
@@ -525,6 +573,7 @@ const createHomepageUtils = (_$w, filterProfiles) => {
525
573
  !isSearchingNearby
526
574
  ) {
527
575
  await wixQueryParams.add({ nearby: 'true', page: '1' });
576
+ logHomePageLoadPhase('parseAndValidateQueryParams_return', { branch: 'auto_nearby_url' });
528
577
  return { isDefaultStateParams: true, filter: newFilter };
529
578
  }
530
579
 
@@ -538,6 +587,7 @@ const createHomepageUtils = (_$w, filterProfiles) => {
538
587
  // });
539
588
  // Don't search yet - let the caller decide what to do
540
589
  // The search will be handled in applyFilterToUI
590
+ logHomePageLoadPhase('parseAndValidateQueryParams_return', { branch: 'default_no_params' });
541
591
  return { isDefaultStateParams: true, filter: newFilter };
542
592
  }
543
593
  let autoAdjustFilters = false;
@@ -577,6 +627,10 @@ const createHomepageUtils = (_$w, filterProfiles) => {
577
627
  withoutPreviewParams.page) ||
578
628
  (Object.keys(withoutPreviewParams).length === 1 && withoutPreviewParams.nearby);
579
629
  const isDefaultStateParams = isNoParams || isNearbyFilter;
630
+ logHomePageLoadPhase('parseAndValidateQueryParams_return', {
631
+ branch: 'with_query_params',
632
+ isDefaultStateParams,
633
+ });
580
634
  return { isDefaultStateParams, filter: newFilter };
581
635
  }
582
636
 
@@ -660,6 +714,7 @@ const createHomepageUtils = (_$w, filterProfiles) => {
660
714
  isSearchingNearby,
661
715
  preservePagination = false,
662
716
  }) {
717
+ logHomePageLoadPhase('search_start', { timeoutType, isSearchingNearby });
663
718
  const multiStateBoxSelector = _$w('#resultsStateBox');
664
719
  const renderingEnv = await rendering.env();
665
720
  const initSearchResultsUI = () => {
@@ -681,6 +736,7 @@ const createHomepageUtils = (_$w, filterProfiles) => {
681
736
  longitude: 0,
682
737
  }) === JSON.stringify(DEFAULT_FILTER)
683
738
  ) {
739
+ logHomePageLoadPhase('search_short_circuit_no_criteria');
684
740
  multiStateBoxSelector.changeState('noSearchCriteria');
685
741
  return [];
686
742
  }
@@ -704,14 +760,19 @@ const createHomepageUtils = (_$w, filterProfiles) => {
704
760
  timeoutType,
705
761
  args: { filter, isSearchingNearby },
706
762
  });
763
+ logHomePageLoadPhase('search_before_filterProfiles', { renderingEnv });
707
764
  const { success, response, error } = await funcPromise();
708
765
  if (!success) {
709
766
  _$w('#numberOfResults').text = '';
710
767
  console.error('[search] failed with error:', error);
768
+ logHomePageLoadPhase('search_filterProfiles_failed', {
769
+ message: String(error && error.message),
770
+ });
711
771
  multiStateBoxSelector.changeState('errorState');
712
772
  return [];
713
773
  }
714
774
  const totalCount = response.items.length;
775
+ logHomePageLoadPhase('search_filterProfiles_success', { totalCount });
715
776
  if (!totalCount) {
716
777
  _$w('#numberOfResults').text = 'Showing 0 results';
717
778
  _$w('#noResultsMessage').text = `${
@@ -0,0 +1,58 @@
1
+ /**
2
+ * One session per full page load. First log call creates `loadId` (send this to support for GCL search).
3
+ * Logs a plain object so DevTools shows an expandable tree; `loadId` is still easy to copy for GCL.
4
+ */
5
+
6
+ function randomSegment() {
7
+ return Math.random().toString(36).slice(2, 10);
8
+ }
9
+
10
+ function nowMs() {
11
+ if (typeof performance !== 'undefined' && typeof performance.now === 'function') {
12
+ return performance.now();
13
+ }
14
+ return Date.now();
15
+ }
16
+
17
+ let session = null;
18
+
19
+ function ensureSession() {
20
+ if (session) {
21
+ return session;
22
+ }
23
+ const t0 = nowMs();
24
+ session = {
25
+ loadId: `hpl_${Date.now()}_${randomSegment()}_${randomSegment()}`,
26
+ t0,
27
+ };
28
+ return session;
29
+ }
30
+
31
+ /**
32
+ * @param {string} phase
33
+ * @param {Record<string, unknown>} [detail]
34
+ */
35
+ function logHomePageLoadPhase(phase, detail) {
36
+ const s = ensureSession();
37
+ const elapsed = Math.round(nowMs() - s.t0);
38
+ const payload = {
39
+ type: 'HomePageLoad',
40
+ loadId: s.loadId,
41
+ phase,
42
+ elapsedSinceStartMs: elapsed,
43
+ wallTimeIso: new Date().toISOString(),
44
+ };
45
+ if (detail && typeof detail === 'object') {
46
+ payload.detail = detail;
47
+ }
48
+ console.log('[HomePageLoad]', payload);
49
+ }
50
+
51
+ function getHomePageLoadId() {
52
+ return ensureSession().loadId;
53
+ }
54
+
55
+ module.exports = {
56
+ logHomePageLoadPhase,
57
+ getHomePageLoadId,
58
+ };