abmp-npm 10.0.51 → 10.0.53

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "abmp-npm",
3
- "version": "10.0.51",
3
+ "version": "10.0.53",
4
4
  "main": "index.js",
5
5
  "scripts": {
6
6
  "check-cycles": "madge --circular .",
package/pages/Home.js CHANGED
@@ -366,7 +366,7 @@ const homePageOnReady = async ({
366
366
  isSearchingNearby: _$w('#nearBy').checked,
367
367
  preservePagination,
368
368
  });
369
- !preservePagination && (await updateUrlParams(filter, pagination));
369
+ // URL is updated inside search() with the filter actually used (avoids rapid select/deselect overwriting with live filter)
370
370
  return searchResults;
371
371
  }
372
372
 
@@ -1,9 +1,7 @@
1
1
  const { location: wixLocation, queryParams: wixQueryParams } = require('@wix/site-location');
2
2
  const { window: wixWindow, rendering } = require('@wix/site-window');
3
3
 
4
- const { DEFAULT_FILTER } = require('../consts.js');
5
-
6
- const { debouncedFunction } = require('./sharedUtils.js');
4
+ const { DEFAULT_FILTER, DEBOUNCE_DELAY } = require('../consts.js');
7
5
 
8
6
  function generateSearchId() {
9
7
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
@@ -15,6 +13,11 @@ function generateSearchId() {
15
13
 
16
14
  const createHomepageUtils = (_$w, filterProfiles) => {
17
15
  let currentSearchId = null;
16
+ let searchDebounceTimer = null;
17
+ let lastSearchFilter = null;
18
+ let lastSearchIsSearchingNearby = false;
19
+ let lastSearchPreservePagination = false;
20
+ let pendingSearchResolve = null;
18
21
 
19
22
  const getFiltersSelectors = filterName => ({
20
23
  checkBoxContainerSelector: _$w(`#${filterName}CheckBoxContainer`),
@@ -665,16 +668,14 @@ const createHomepageUtils = (_$w, filterProfiles) => {
665
668
  async function search({
666
669
  filter,
667
670
  pagination,
668
- debounceTimeout,
671
+ debounceTimeout: _debounceTimeout,
669
672
  timeoutType,
670
673
  isSearchingNearby,
671
674
  preservePagination = false,
672
675
  }) {
673
- const thisSearchId = generateSearchId();
674
- currentSearchId = thisSearchId;
675
-
676
676
  const multiStateBoxSelector = _$w('#resultsStateBox');
677
677
  const renderingEnv = await rendering.env();
678
+
678
679
  const initSearchResultsUI = () => {
679
680
  JSON.stringify(filter) === JSON.stringify(DEFAULT_FILTER)
680
681
  ? _$w('#resetFilter').hide()
@@ -685,72 +686,115 @@ const createHomepageUtils = (_$w, filterProfiles) => {
685
686
  _$w('#profileRepeater').data = [];
686
687
  console.log({ filter });
687
688
  };
688
- const runSearchAndUpdateUI = async (filter, isSearchingNearby) => {
689
- if (!isSearchingNearby) {
689
+
690
+ const runSearchAndUpdateUI = async (
691
+ filterToUse,
692
+ isSearchingNearbyToUse,
693
+ preservePaginationToUse
694
+ ) => {
695
+ if (!isSearchingNearbyToUse) {
690
696
  if (
691
697
  JSON.stringify({
692
- ...filter,
698
+ ...filterToUse,
693
699
  latitude: 0,
694
700
  longitude: 0,
695
701
  }) === JSON.stringify(DEFAULT_FILTER)
696
702
  ) {
697
703
  multiStateBoxSelector.changeState('noSearchCriteria');
704
+ await updateUrlParams(filterToUse, pagination);
698
705
  return [];
699
706
  }
700
707
  }
701
- const nonDebouncedFilterProfiles = async () => {
702
- try {
703
- const result = await filterProfiles({ filter, isSearchingNearby });
704
- return { success: true, response: result };
705
- } catch (error) {
706
- return { success: false, error };
707
- }
708
- };
709
- //Don't run setTimeout on SSR
710
- const funcPromise =
711
- renderingEnv === 'backend'
712
- ? () => nonDebouncedFilterProfiles()
713
- : () =>
714
- debouncedFunction({
715
- func: filterProfiles,
716
- debounceTimeout,
717
- timeoutType,
718
- args: { filter, isSearchingNearby },
719
- });
720
- const { success, response, error } = await funcPromise();
721
- if (thisSearchId !== currentSearchId) return [];
722
-
723
- if (!success) {
708
+ const thisSearchId = generateSearchId();
709
+ currentSearchId = thisSearchId;
710
+
711
+ let result;
712
+ try {
713
+ result = await filterProfiles({
714
+ filter: filterToUse,
715
+ isSearchingNearby: isSearchingNearbyToUse,
716
+ });
717
+ } catch (error) {
718
+ if (thisSearchId !== currentSearchId) return [];
724
719
  _$w('#numberOfResults').text = '';
725
720
  console.error('[search] failed with error:', error);
726
721
  multiStateBoxSelector.changeState('errorState');
722
+ await updateUrlParams(filterToUse, pagination);
727
723
  return [];
728
724
  }
725
+
726
+ if (thisSearchId !== currentSearchId) return [];
727
+
728
+ const response = result;
729
729
  const totalCount = response.items.length;
730
730
  if (!totalCount) {
731
731
  _$w('#numberOfResults').text = 'Showing 0 results';
732
732
  _$w('#noResultsMessage').text = `${
733
- filter.searchText && filter.searchText.length > 0
734
- ? `'${filter.searchText}' did not match any search. Please try again.`
733
+ filterToUse.searchText && filterToUse.searchText.length > 0
734
+ ? `'${filterToUse.searchText}' did not match any search. Please try again.`
735
735
  : 'No results found for the selected filters. Please adjust your filters and try again'
736
736
  }`;
737
737
  multiStateBoxSelector.changeState('noResultsState');
738
+ await updateUrlParams(filterToUse, pagination);
738
739
  return [];
739
740
  }
740
741
  console.log({ response });
741
742
  handleNumberOfResults(pagination, totalCount);
742
743
  _$w('#showingResult').show();
743
744
 
744
- if (!preservePagination || pagination.currentPage >= pagination.totalPages) {
745
+ if (!preservePaginationToUse || pagination.currentPage >= pagination.totalPages) {
745
746
  pagination.currentPage = 0;
746
747
  }
747
748
  pagination.totalPages = Math.ceil(totalCount / pagination.pageSize);
748
749
  paginateSearchResults(response.items, pagination);
749
750
  multiStateBoxSelector.changeState('resultsState');
751
+ await updateUrlParams(filterToUse, pagination);
750
752
  return response.items;
751
753
  };
754
+
755
+ // Always show loading as soon as user changes input
752
756
  initSearchResultsUI();
753
- return await runSearchAndUpdateUI(filter, isSearchingNearby);
757
+
758
+ // SSR: run immediately, no debounce
759
+ if (renderingEnv === 'backend') {
760
+ return await runSearchAndUpdateUI(filter, isSearchingNearby, preservePagination);
761
+ }
762
+
763
+ // Client: debounce the API call; loading is already shown above.
764
+ // Snapshot the filter so rapid clicks / URL sync can't mutate it before the debounced run.
765
+ lastSearchFilter = JSON.parse(JSON.stringify(filter));
766
+ lastSearchIsSearchingNearby = isSearchingNearby;
767
+ lastSearchPreservePagination = preservePagination;
768
+
769
+ if (pendingSearchResolve) {
770
+ pendingSearchResolve([]);
771
+ pendingSearchResolve = null;
772
+ }
773
+
774
+ if (searchDebounceTimer) {
775
+ clearTimeout(searchDebounceTimer);
776
+ searchDebounceTimer = null;
777
+ }
778
+
779
+ const delay = DEBOUNCE_DELAY[timeoutType] ?? 300;
780
+ return new Promise(resolve => {
781
+ pendingSearchResolve = resolve;
782
+ searchDebounceTimer = setTimeout(async () => {
783
+ searchDebounceTimer = null;
784
+ const filterToUse = lastSearchFilter;
785
+ const isSearchingNearbyToUse = lastSearchIsSearchingNearby;
786
+ const preservePaginationToUse = lastSearchPreservePagination;
787
+ const items = await runSearchAndUpdateUI(
788
+ filterToUse,
789
+ isSearchingNearbyToUse,
790
+ preservePaginationToUse
791
+ );
792
+ if (pendingSearchResolve) {
793
+ pendingSearchResolve(items);
794
+ pendingSearchResolve = null;
795
+ }
796
+ }, delay);
797
+ });
754
798
  }
755
799
 
756
800
  return {