ng-miam 10.5.11 → 10.6.1

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.
Files changed (34) hide show
  1. package/bundles/ng-miam.umd.js +289 -29
  2. package/bundles/ng-miam.umd.js.map +1 -1
  3. package/bundles/ng-miam.umd.min.js +1 -1
  4. package/bundles/ng-miam.umd.min.js.map +1 -1
  5. package/esm2015/lib/_services/basket-utils.service.js +17 -3
  6. package/esm2015/lib/_services/baskets.service.js +66 -26
  7. package/esm2015/lib/_services/context.service.js +4 -2
  8. package/esm2015/lib/_services/recipes.service.js +5 -2
  9. package/esm2015/lib/_types/builded/mealz-interface.js +1 -1
  10. package/esm2015/lib/_utils/attach-recipe-card-show-tracking.js +24 -0
  11. package/esm2015/lib/_utils/recipe-card-show-tracker.js +109 -0
  12. package/esm2015/lib/_utils/viewport-listener.js +47 -0
  13. package/esm2015/lib/environments/environment.js +2 -2
  14. package/esm2015/lib/environments/environment.prod.js +2 -2
  15. package/esm2015/lib/environments/version.js +2 -2
  16. package/fesm2015/ng-miam.js +265 -31
  17. package/fesm2015/ng-miam.js.map +1 -1
  18. package/lib/_services/basket-utils.service.d.ts +2 -0
  19. package/lib/_services/basket-utils.service.d.ts.map +1 -1
  20. package/lib/_services/baskets.service.d.ts +8 -0
  21. package/lib/_services/baskets.service.d.ts.map +1 -1
  22. package/lib/_services/context.service.d.ts.map +1 -1
  23. package/lib/_services/recipes.service.d.ts.map +1 -1
  24. package/lib/_types/builded/mealz-interface.d.ts +7 -0
  25. package/lib/_types/builded/mealz-interface.d.ts.map +1 -1
  26. package/lib/_utils/attach-recipe-card-show-tracking.d.ts +23 -0
  27. package/lib/_utils/attach-recipe-card-show-tracking.d.ts.map +1 -0
  28. package/lib/_utils/recipe-card-show-tracker.d.ts +24 -0
  29. package/lib/_utils/recipe-card-show-tracker.d.ts.map +1 -0
  30. package/lib/_utils/viewport-listener.d.ts +18 -0
  31. package/lib/_utils/viewport-listener.d.ts.map +1 -0
  32. package/lib/environments/version.d.ts +1 -1
  33. package/lib/environments/version.d.ts.map +1 -1
  34. package/package.json +1 -1
@@ -1640,12 +1640,208 @@
1640
1640
  env: 'prod',
1641
1641
  miamAPI: 'https://api.miam.tech',
1642
1642
  miamWeb: 'https://miam.tech',
1643
- mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.10/dist',
1643
+ mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.11/dist',
1644
1644
  mealzSsrApi: 'https://ssr-api.mealz.ai',
1645
1645
  lang: 'fr',
1646
1646
  analyticsEnabled: true // Only used in DEV mode
1647
1647
  };
1648
1648
 
1649
+ var WINDOW_SINGLETON_KEY = '__mealzRecipeCardShowTracker__';
1650
+ /**
1651
+ * Tracks recipe.show events and prevents duplicates (first show, or again after scroll).
1652
+ * Shared across SDK and Lit recipe cards via {@link WINDOW_SINGLETON_KEY} on window.
1653
+ */
1654
+ var RecipeCardShowTracker = /** @class */ (function () {
1655
+ function RecipeCardShowTracker() {
1656
+ var _this = this;
1657
+ this.trackedRecipes = new Map();
1658
+ this.hasScrolled = false;
1659
+ this.scrollListener = null;
1660
+ this.cleanupInterval = null;
1661
+ this.MAX_RECIPES = 1000;
1662
+ this.CLEANUP_INTERVAL = 5 * 60 * 1000;
1663
+ this.handlePageUnload = function () {
1664
+ _this.destroy();
1665
+ };
1666
+ this.setupScrollListener();
1667
+ this.startAutoCleanup();
1668
+ this.setupPageUnloadListener();
1669
+ }
1670
+ RecipeCardShowTracker.getInstance = function () {
1671
+ var w = typeof window !== 'undefined'
1672
+ ? window
1673
+ : undefined;
1674
+ var fromWindow = w === null || w === void 0 ? void 0 : w[WINDOW_SINGLETON_KEY];
1675
+ if (fromWindow) {
1676
+ RecipeCardShowTracker.instance = fromWindow;
1677
+ return fromWindow;
1678
+ }
1679
+ if (!RecipeCardShowTracker.instance) {
1680
+ RecipeCardShowTracker.instance = new RecipeCardShowTracker();
1681
+ if (w) {
1682
+ w[WINDOW_SINGLETON_KEY] = RecipeCardShowTracker.instance;
1683
+ }
1684
+ }
1685
+ return RecipeCardShowTracker.instance;
1686
+ };
1687
+ RecipeCardShowTracker.prototype.trackRecipeShow = function (recipeId, analyticsPath, categoryId) {
1688
+ var _a, _b;
1689
+ var now = Date.now();
1690
+ var lastShowTime = this.trackedRecipes.get(recipeId);
1691
+ var isFirstShow = !lastShowTime;
1692
+ var hasScrolledSinceLastShow = this.hasScrolled;
1693
+ if (!isFirstShow && !hasScrolledSinceLastShow) {
1694
+ return;
1695
+ }
1696
+ if (this.trackedRecipes.size >= this.MAX_RECIPES) {
1697
+ this.cleanOldRecipes();
1698
+ }
1699
+ this.trackedRecipes.set(recipeId, now);
1700
+ (_b = (_a = window.mealzInternal) === null || _a === void 0 ? void 0 : _a.analytics) === null || _b === void 0 ? void 0 : _b.sendEvent('recipe.show', analyticsPath, {
1701
+ recipe_id: recipeId,
1702
+ category_id: categoryId
1703
+ });
1704
+ };
1705
+ RecipeCardShowTracker.prototype.cleanOldRecipes = function () {
1706
+ var e_1, _c;
1707
+ var now = Date.now();
1708
+ var oneHourAgo = now - (60 * 60 * 1000);
1709
+ try {
1710
+ for (var _d = __values(this.trackedRecipes.entries()), _e = _d.next(); !_e.done; _e = _d.next()) {
1711
+ var _f = __read(_e.value, 2), recipeId = _f[0], timestamp = _f[1];
1712
+ if (timestamp < oneHourAgo) {
1713
+ this.trackedRecipes.delete(recipeId);
1714
+ }
1715
+ }
1716
+ }
1717
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
1718
+ finally {
1719
+ try {
1720
+ if (_e && !_e.done && (_c = _d.return)) _c.call(_d);
1721
+ }
1722
+ finally { if (e_1) throw e_1.error; }
1723
+ }
1724
+ };
1725
+ RecipeCardShowTracker.prototype.clearAllRecipes = function () {
1726
+ this.trackedRecipes.clear();
1727
+ };
1728
+ RecipeCardShowTracker.prototype.destroy = function () {
1729
+ if (this.scrollListener) {
1730
+ document.removeEventListener('scroll', this.scrollListener, true);
1731
+ this.scrollListener = null;
1732
+ }
1733
+ window.removeEventListener('beforeunload', this.handlePageUnload);
1734
+ if (this.cleanupInterval) {
1735
+ clearInterval(this.cleanupInterval);
1736
+ this.cleanupInterval = null;
1737
+ }
1738
+ this.trackedRecipes.clear();
1739
+ this.hasScrolled = false;
1740
+ RecipeCardShowTracker.instance = null;
1741
+ if (typeof window !== 'undefined') {
1742
+ delete window[WINDOW_SINGLETON_KEY];
1743
+ }
1744
+ };
1745
+ RecipeCardShowTracker.prototype.setupScrollListener = function () {
1746
+ var _this = this;
1747
+ var scrollTimeout;
1748
+ this.scrollListener = function () {
1749
+ _this.hasScrolled = true;
1750
+ clearTimeout(scrollTimeout);
1751
+ scrollTimeout = window.setTimeout(function () {
1752
+ _this.hasScrolled = false;
1753
+ }, 2000);
1754
+ };
1755
+ document.addEventListener('scroll', this.scrollListener, {
1756
+ passive: true,
1757
+ capture: true,
1758
+ });
1759
+ };
1760
+ RecipeCardShowTracker.prototype.startAutoCleanup = function () {
1761
+ var _this = this;
1762
+ this.cleanupInterval = window.setInterval(function () {
1763
+ _this.cleanOldRecipes();
1764
+ }, this.CLEANUP_INTERVAL);
1765
+ };
1766
+ RecipeCardShowTracker.prototype.setupPageUnloadListener = function () {
1767
+ window.addEventListener('beforeunload', this.handlePageUnload);
1768
+ };
1769
+ return RecipeCardShowTracker;
1770
+ }());
1771
+ RecipeCardShowTracker.instance = null;
1772
+
1773
+ var ViewportListenerParams = /** @class */ (function () {
1774
+ function ViewportListenerParams() {
1775
+ this.condition = true;
1776
+ this.threshold = 0;
1777
+ this.debounce = 0;
1778
+ }
1779
+ return ViewportListenerParams;
1780
+ }());
1781
+ var ViewportListener = /** @class */ (function () {
1782
+ function ViewportListener(element, callback, params) {
1783
+ var _this = this;
1784
+ if (params === void 0) { params = {}; }
1785
+ this.element = element;
1786
+ this.callback = callback;
1787
+ this.params = params;
1788
+ this.intersectionSubject = new rxjs.Subject();
1789
+ this.subscriptions = [];
1790
+ this.params = Object.assign(Object.assign({}, new ViewportListenerParams()), params);
1791
+ var options = {
1792
+ root: null,
1793
+ rootMargin: '0px',
1794
+ threshold: this.params.threshold
1795
+ };
1796
+ this.observer = new IntersectionObserver(function (entries) {
1797
+ entries.forEach(function (entry) { return _this.intersectionSubject.next(entry); });
1798
+ }, options);
1799
+ this.connect();
1800
+ }
1801
+ ViewportListener.prototype.connect = function () {
1802
+ var _this = this;
1803
+ this.subscriptions.push(this.intersectionSubject
1804
+ .pipe(operators.debounceTime(this.params.debounce))
1805
+ .subscribe(function (entry) { return _this.handleIntersection(entry); }));
1806
+ this.observer.observe(this.element);
1807
+ };
1808
+ ViewportListener.prototype.disconnect = function () {
1809
+ if (this.observer) {
1810
+ this.observer.disconnect();
1811
+ }
1812
+ this.intersectionSubject.complete();
1813
+ this.subscriptions.forEach(function (sub) { return sub.unsubscribe(); });
1814
+ };
1815
+ ViewportListener.prototype.handleIntersection = function (entry) {
1816
+ if (this.params.condition && entry.isIntersecting) {
1817
+ this.callback();
1818
+ }
1819
+ };
1820
+ return ViewportListener;
1821
+ }());
1822
+
1823
+ var RECIPE_CARD_SHOW_ANALYTICS_PATH = '/recipes';
1824
+ /** Same visibility rule as `mealz-recipe-card`: IntersectionObserver ratio ≥ this value. */
1825
+ var RECIPE_CARD_SHOW_VISIBILITY_THRESHOLD = 0.8;
1826
+ /** Same timing as `mealz-recipe-card`: debounce on intersection stream (ms). */
1827
+ var RECIPE_CARD_SHOW_DEBOUNCE_MS = 1000;
1828
+ /**
1829
+ * Same `recipe.show` pipeline as `mealz-recipe-card`: viewport visibility + deduped tracking.
1830
+ * Call `disconnect()` when the host node is removed (virtual lists, SPA navigation).
1831
+ */
1832
+ function attachRecipeCardShowTracking(options) {
1833
+ var element = options.element, recipeId = options.recipeId, _a = options.analyticsPath, analyticsPath = _a === void 0 ? RECIPE_CARD_SHOW_ANALYTICS_PATH : _a, _b = options.categoryId, categoryId = _b === void 0 ? '' : _b;
1834
+ var listener = new ViewportListener(element, function () {
1835
+ RecipeCardShowTracker.getInstance().trackRecipeShow(recipeId, analyticsPath, categoryId);
1836
+ }, {
1837
+ threshold: RECIPE_CARD_SHOW_VISIBILITY_THRESHOLD,
1838
+ debounce: RECIPE_CARD_SHOW_DEBOUNCE_MS
1839
+ });
1840
+ return {
1841
+ disconnect: function () { return listener.disconnect(); }
1842
+ };
1843
+ }
1844
+
1649
1845
  var Ingredient = /** @class */ (function (_super) {
1650
1846
  __extends(Ingredient, _super);
1651
1847
  function Ingredient() {
@@ -3452,7 +3648,7 @@
3452
3648
  EventJourney["EMPTY"] = "";
3453
3649
  })(EventJourney || (EventJourney = {}));
3454
3650
 
3455
- var VERSION = "10.5.11"; // TODO: replace by ##VERSION## and update it in the CI/CD
3651
+ var VERSION = "10.6.1"; // TODO: replace by ##VERSION## and update it in the CI/CD
3456
3652
 
3457
3653
  var ContextRegistryService = /** @class */ (function () {
3458
3654
  function ContextRegistryService() {
@@ -5577,7 +5773,10 @@
5577
5773
  RecipesService.prototype.getSuggestedRecipes = function () {
5578
5774
  var _this = this;
5579
5775
  var pref = this.buildfilterUrlFromPreferences();
5580
- var url = pref ? MIAM_API_HOST$2 + "recipes/suggest?" + pref.slice(1) : MIAM_API_HOST$2 + "recipes/suggest";
5776
+ var params = new URLSearchParams(pref ? pref.slice(1) : '');
5777
+ params.append('include', 'sponsors');
5778
+ params.append('fields[sponsors]', 'logo-url');
5779
+ var url = MIAM_API_HOST$2 + "recipes/suggest?" + params.toString();
5581
5780
  return this.http.get(url, {
5582
5781
  headers: {
5583
5782
  'Cache-Control': 'no-cache, no-store, must-revalidate',
@@ -6012,6 +6211,7 @@
6012
6211
  _this.basketPreviewIsCalculating$ = new rxjs.BehaviorSubject(true);
6013
6212
  _this.basketInitCalled = false;
6014
6213
  _this.recipesAdded = new i0.EventEmitter();
6214
+ _this.recipesAddFailed = new i0.EventEmitter();
6015
6215
  _this.confirming = new rxjs.BehaviorSubject(false);
6016
6216
  _this.currentlyAddingRecipes = [];
6017
6217
  _this.basketActionsQueue = new rxjs.BehaviorSubject([]);
@@ -6196,8 +6396,30 @@
6196
6396
  return this.basket$.pipe(operators.skipWhile(function (b) { return !b; }), operators.map(function (basket) { return basket.hasRecipe(recipeId); }));
6197
6397
  };
6198
6398
  BasketsService.prototype.guestsForRecipe = function (recipeId) {
6399
+ return this.resolveGuestsForRecipe(recipeId);
6400
+ };
6401
+ BasketsService.prototype.resolveGuestsForRecipe = function (recipeId) {
6402
+ var _a;
6403
+ var guestsFromBasket = (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
6404
+ if (Number.isFinite(guestsFromBasket)) {
6405
+ return guestsFromBasket;
6406
+ }
6407
+ var pendingRecipeAction = __spread(this.actionsBeingProcessed.value, this.basketActionsQueue.value).find(function (action) { return (action.type === BasketActionType.ADD_RECIPE || action.type === BasketActionType.ADD_RECIPE_LIGHT) &&
6408
+ action.params.recipeId === recipeId &&
6409
+ Number.isFinite(action.params.guests); });
6410
+ return pendingRecipeAction === null || pendingRecipeAction === void 0 ? void 0 : pendingRecipeAction.params.guests;
6411
+ };
6412
+ /**
6413
+ * Waits until the given recipe is in the basket before resolving.
6414
+ * Emits `true` when the recipe is confirmed in the basket, `false` when its addition failed,
6415
+ * so callers can avoid firing dependent requests (e.g. add-ingredient) against a recipe that was never created.
6416
+ */
6417
+ BasketsService.prototype.waitUntilRecipeInBasket = function (recipeId) {
6199
6418
  var _a;
6200
- return (_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.guestsForRecipe(recipeId);
6419
+ if (!recipeId || ((_a = this.basket$.value) === null || _a === void 0 ? void 0 : _a.hasRecipe(recipeId))) {
6420
+ return rxjs.of(true);
6421
+ }
6422
+ return rxjs.merge(this.basket$.pipe(operators.skipWhile(function (basket) { return !(basket === null || basket === void 0 ? void 0 : basket.hasRecipe(recipeId)); }), operators.take(1), operators.map(function () { return true; })), this.recipesAdded.pipe(operators.skipWhile(function (recipeIds) { return !recipeIds.includes(recipeId); }), operators.take(1), operators.map(function () { return true; })), this.recipesAddFailed.pipe(operators.skipWhile(function (recipeIds) { return !recipeIds.includes(recipeId); }), operators.take(1), operators.map(function () { return false; }))).pipe(operators.take(1));
6201
6423
  };
6202
6424
  BasketsService.prototype.showRecipeAddedToaster = function () {
6203
6425
  var _this = this;
@@ -6578,8 +6800,11 @@
6578
6800
  /** *************************************************** PROCESS THE ACTIONS QUEUE *************************************************** **/
6579
6801
  BasketsService.prototype.emptyActionsQueue = function () {
6580
6802
  var _this = this;
6581
- if (this.basketActionsQueue.value.length > 0) {
6803
+ if (this.basketActionsQueue.value.length > 0 && this.actionsBeingProcessed.value.length === 0) {
6582
6804
  var actionsToProcess_1 = this.nextActionsBatch();
6805
+ if (actionsToProcess_1.length === 0) {
6806
+ return;
6807
+ }
6583
6808
  this.actionsBeingProcessed.next(__spread(actionsToProcess_1));
6584
6809
  if (actionsToProcess_1.length > 0) {
6585
6810
  this.processActionsBatch(actionsToProcess_1).subscribe(function () {
@@ -6595,14 +6820,16 @@
6595
6820
  * @returns the next batch of actions to process
6596
6821
  */
6597
6822
  BasketsService.prototype.nextActionsBatch = function () {
6823
+ var _this = this;
6824
+ var pendingActions = this.basketActionsQueue.value.filter(function (action) { return !_this.actionsBeingProcessed.value.includes(action); });
6598
6825
  var batch = [];
6599
- var i = 0;
6600
- var currentAction = this.basketActionsQueue.value[i];
6826
+ var index = 0;
6827
+ var currentAction = pendingActions[index];
6601
6828
  var shouldForceStop = false;
6602
- while (this.basketActionsQueue.value[i] && this.basketActionsQueue.value[i].type === currentAction.type && !shouldForceStop) {
6603
- currentAction = this.basketActionsQueue.value[i];
6829
+ while (pendingActions[index] && pendingActions[index].type === currentAction.type && !shouldForceStop) {
6830
+ currentAction = pendingActions[index];
6604
6831
  shouldForceStop = this.addActionToBatchOrStopProcessingBatch(batch, currentAction);
6605
- i++;
6832
+ index++;
6606
6833
  }
6607
6834
  return batch;
6608
6835
  };
@@ -6727,6 +6954,10 @@
6727
6954
  return _this.http.post(postUrl, body).pipe(operators.switchMap(function (b) { var _a; return ((_a = b.data) === null || _a === void 0 ? void 0 : _a.id) ? _this.fillBasket(b) : rxjs.of(null); }), operators.tap(function () {
6728
6955
  _this.recipesAdded.emit(recipeIds.map(function (r) { return r.recipe_id; }));
6729
6956
  _this.currentlyAddingRecipes = _this.currentlyAddingRecipes.filter(function (id) { return !(_this.basket$.value.recipeInfos.find(function (i) { return i.id === id; })); });
6957
+ }), operators.catchError(function () {
6958
+ _this.currentlyAddingRecipes = _this.currentlyAddingRecipes.filter(function (recipeId) { return !recipeIds.some(function (candidate) { return candidate.recipe_id === recipeId; }); });
6959
+ _this.recipesAddFailed.emit(recipeIds.map(function (r) { return r.recipe_id; }));
6960
+ return rxjs.of(null);
6730
6961
  }));
6731
6962
  }), operators.catchError(function () { return rxjs.of(null); }));
6732
6963
  };
@@ -6786,23 +7017,32 @@
6786
7017
  */
6787
7018
  BasketsService.prototype.addItemsForIngredients = function (ingredientsToAdd) {
6788
7019
  var _this = this;
6789
- return this.waitForBasket.pipe(operators.switchMap(function (basket) {
6790
- var requests = ingredientsToAdd.map(function (action) {
6791
- var modifiedGuests = _this.guestsForRecipe(action.params.recipeId);
6792
- var patchUrl = environment$1.miamAPI + "/api/v1/baskets/" + basket.id + "/basket-entries/" + action.params.basketEntry.id + "/add-ingredient" +
6793
- ("?ingredient_id=" + action.params.ingredientId + "&selected_item_id=" + action.params.basketEntry.selectedItem.id) +
6794
- ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
6795
- return _this.http.patch(patchUrl, {});
6796
- });
6797
- return rxjs.forkJoin(requests);
6798
- }), operators.tap(function () {
6799
- // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
6800
- var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
6801
- ? 'item-replacement'
6802
- : 'meals-space-recipe-details';
6803
- _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
6804
- }), operators.switchMap(function () { return _this.reloadBasket(); }), operators.switchMap(function () { return rxjs.of(null); }), // Just to keep the return type as Observable<void> to match with the other methods
6805
- operators.catchError(function () { return rxjs.of(null); }));
7020
+ var _a;
7021
+ var recipeId = (_a = ingredientsToAdd[0]) === null || _a === void 0 ? void 0 : _a.params.recipeId;
7022
+ return this.waitUntilRecipeInBasket(recipeId).pipe(operators.switchMap(function (recipeIsInBasket) {
7023
+ // The parent recipe add failed: skip add-ingredient to avoid a request against a recipe that was never created
7024
+ // (which would leave the retailer basket updated while Mealz stays out of sync).
7025
+ if (!recipeIsInBasket) {
7026
+ return rxjs.of(null);
7027
+ }
7028
+ return _this.waitForBasket.pipe(operators.switchMap(function (basket) {
7029
+ var requests = ingredientsToAdd.map(function (action) {
7030
+ var modifiedGuests = _this.resolveGuestsForRecipe(action.params.recipeId);
7031
+ var patchUrl = environment$1.miamAPI + "/api/v1/baskets/" + basket.id + "/basket-entries/" + action.params.basketEntry.id + "/add-ingredient" +
7032
+ ("?ingredient_id=" + action.params.ingredientId + "&selected_item_id=" + action.params.basketEntry.selectedItem.id) +
7033
+ ("&guests=" + modifiedGuests + "&forced_quantity=" + action.params.basketEntry.quantity);
7034
+ return _this.http.patch(patchUrl, {});
7035
+ });
7036
+ return rxjs.forkJoin(requests);
7037
+ }), operators.tap(function () {
7038
+ // Determine journey: item-replacement if previousItem exists (indicates replacement), otherwise meals-space-recipe-details
7039
+ var journey = ingredientsToAdd.some(function (action) { return action.params.previousItem; })
7040
+ ? 'item-replacement'
7041
+ : 'meals-space-recipe-details';
7042
+ _this.analyticsService.sendAddProductsEvents(ingredientsToAdd, journey);
7043
+ }), operators.switchMap(function () { return _this.reloadBasket(); }), operators.switchMap(function () { return rxjs.of(null); }) // Just to keep the return type as Observable<void> to match with the other methods
7044
+ );
7045
+ }), operators.catchError(function () { return rxjs.of(null); }));
6806
7046
  };
6807
7047
  /**
6808
7048
  * Add items to the basket HTTP request.
@@ -8420,17 +8660,27 @@
8420
8660
 
8421
8661
  var BasketUtilsService = /** @class */ (function () {
8422
8662
  function BasketUtilsService(basketsService, recipesService, priceService, basketSynchroService, analyticsService, loadLitDrawerService) {
8663
+ var _this = this;
8423
8664
  this.basketsService = basketsService;
8424
8665
  this.recipesService = recipesService;
8425
8666
  this.priceService = priceService;
8426
8667
  this.basketSynchroService = basketSynchroService;
8427
8668
  this.analyticsService = analyticsService;
8428
8669
  this.loadLitDrawerService = loadLitDrawerService;
8670
+ this.removeRecipeJobs$ = new rxjs.Subject();
8429
8671
  this.recipesWithEntries = [];
8430
8672
  this.basketPreviewState$ = new rxjs.BehaviorSubject({
8431
8673
  isOpen: false,
8432
8674
  activeTabIndex: 0 // Default to the first tab (recipes)
8433
8675
  });
8676
+ this.removeRecipeJobs$.pipe(operators.concatMap(function (_a) {
8677
+ var recipeId = _a.recipeId, analyticsPath = _a.analyticsPath, result$ = _a.result$;
8678
+ return _this.removeRecipeInternal(recipeId, analyticsPath).pipe(operators.tap({
8679
+ next: function (value) { return result$.next(value); },
8680
+ error: function (error) { return result$.error(error); },
8681
+ complete: function () { return result$.complete(); }
8682
+ }), operators.catchError(function () { return rxjs.EMPTY; }));
8683
+ })).subscribe();
8434
8684
  }
8435
8685
  /**
8436
8686
  * Builds a preview of recipes in the basket, including their total price and total number of products per recipe.
@@ -8456,6 +8706,15 @@
8456
8706
  });
8457
8707
  };
8458
8708
  BasketUtilsService.prototype.removeRecipe = function (recipeId, analyticsPath) {
8709
+ var _this = this;
8710
+ return new rxjs.Observable(function (subscriber) {
8711
+ var result$ = new rxjs.Subject();
8712
+ var resultSubscription = result$.subscribe(subscriber);
8713
+ _this.removeRecipeJobs$.next({ recipeId: recipeId, analyticsPath: analyticsPath, result$: result$ });
8714
+ return function () { return resultSubscription.unsubscribe(); };
8715
+ });
8716
+ };
8717
+ BasketUtilsService.prototype.removeRecipeInternal = function (recipeId, analyticsPath) {
8459
8718
  var _this = this;
8460
8719
  return this.fetchDataToRemoveRecipe(recipeId).pipe(operators.switchMap(function (_a) {
8461
8720
  var recipe = _a.recipe, basketEntries = _a.basketEntries;
@@ -11184,7 +11443,8 @@
11184
11443
  _this.analyticsService.init(domain);
11185
11444
  },
11186
11445
  eventSent$: this.analyticsService.eventEmitter,
11187
- setAbTestKey: function (key) { return _this.analyticsService.setAbTestKey(key); }
11446
+ setAbTestKey: function (key) { return _this.analyticsService.setAbTestKey(key); },
11447
+ attachRecipeCardShowTracking: attachRecipeCardShowTracking
11188
11448
  },
11189
11449
  basket: {
11190
11450
  basketIsReady$: this.basketsService.basketStats$.pipe(operators.skipWhile(function (stats) { return !stats; }), operators.take(1), operators.map(function () { return true; })),
@@ -13194,7 +13454,7 @@
13194
13454
  env: 'prod',
13195
13455
  miamAPI: 'https://api.miam.tech',
13196
13456
  miamWeb: 'https://miam.tech',
13197
- mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.10/dist',
13457
+ mealzComponents: 'https://cdn.jsdelivr.net/npm/mealz-components@2.11/dist',
13198
13458
  mealzSsrApi: 'https://ssr-api.mealz.ai',
13199
13459
  lang: 'fr',
13200
13460
  analyticsEnabled: true // Only used in DEV mode