ng-miam 10.5.11 → 10.6.0
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/bundles/ng-miam.umd.js +199 -2
- package/bundles/ng-miam.umd.js.map +1 -1
- package/bundles/ng-miam.umd.min.js +1 -1
- package/bundles/ng-miam.umd.min.js.map +1 -1
- package/esm2015/lib/_services/context.service.js +4 -2
- package/esm2015/lib/_types/builded/mealz-interface.js +1 -1
- package/esm2015/lib/_utils/attach-recipe-card-show-tracking.js +24 -0
- package/esm2015/lib/_utils/recipe-card-show-tracker.js +109 -0
- package/esm2015/lib/_utils/viewport-listener.js +47 -0
- package/esm2015/lib/environments/version.js +2 -2
- package/fesm2015/ng-miam.js +179 -2
- package/fesm2015/ng-miam.js.map +1 -1
- package/lib/_services/context.service.d.ts.map +1 -1
- package/lib/_types/builded/mealz-interface.d.ts +7 -0
- package/lib/_types/builded/mealz-interface.d.ts.map +1 -1
- package/lib/_utils/attach-recipe-card-show-tracking.d.ts +23 -0
- package/lib/_utils/attach-recipe-card-show-tracking.d.ts.map +1 -0
- package/lib/_utils/recipe-card-show-tracker.d.ts +24 -0
- package/lib/_utils/recipe-card-show-tracker.d.ts.map +1 -0
- package/lib/_utils/viewport-listener.d.ts +18 -0
- package/lib/_utils/viewport-listener.d.ts.map +1 -0
- package/lib/environments/version.d.ts +1 -1
- package/lib/environments/version.d.ts.map +1 -1
- package/package.json +1 -1
package/bundles/ng-miam.umd.js
CHANGED
|
@@ -1646,6 +1646,202 @@
|
|
|
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.
|
|
3651
|
+
var VERSION = "10.6.0"; // TODO: replace by ##VERSION## and update it in the CI/CD
|
|
3456
3652
|
|
|
3457
3653
|
var ContextRegistryService = /** @class */ (function () {
|
|
3458
3654
|
function ContextRegistryService() {
|
|
@@ -11184,7 +11380,8 @@
|
|
|
11184
11380
|
_this.analyticsService.init(domain);
|
|
11185
11381
|
},
|
|
11186
11382
|
eventSent$: this.analyticsService.eventEmitter,
|
|
11187
|
-
setAbTestKey: function (key) { return _this.analyticsService.setAbTestKey(key); }
|
|
11383
|
+
setAbTestKey: function (key) { return _this.analyticsService.setAbTestKey(key); },
|
|
11384
|
+
attachRecipeCardShowTracking: attachRecipeCardShowTracking
|
|
11188
11385
|
},
|
|
11189
11386
|
basket: {
|
|
11190
11387
|
basketIsReady$: this.basketsService.basketStats$.pipe(operators.skipWhile(function (stats) { return !stats; }), operators.take(1), operators.map(function () { return true; })),
|