1/* cart telemetry: temporary/debuggable */ 2(function ($) { 3 const cfg = window.dbiCartTelemetry || {}; 4 const traceId = getTraceId(); 5 const basePayload = { 6 trace_id: traceId, 7 is_logged_in: !!cfg.isLoggedIn, 8 user_id: cfg.userId || null, 9 site_env: cfg.siteEnv || '', 10 }; 11 const ajaxTimers = new WeakMap(); 12 const trackable = [ 13 'wc-ajax=add_to_cart', 14 'wc-ajax=update_shipping_method', 15 'wc-ajax=update_cart', 16 'wc-ajax=apply_coupon', 17 'wc-ajax=remove_coupon', 18 'wc-ajax=remove_from_cart', 19 'wc-ajax=get_refreshed_fragments', 20 'get_refreshed_cart', 21 'sp_update_location_data', 22 ]; 23 24 function getTraceId() { 25 const key = 'dbi_cart_trace_id'; 26 const stored = localStorage.getItem(key); 27 if (stored) return stored; 28 if (cfg.traceId) { 29 localStorage.setItem(key, cfg.traceId); 30 return cfg.traceId; 31 } 32 const generated = Math.random().toString(16).slice(2, 18); 33 localStorage.setItem(key, generated); 34 return generated; 35 } 36 37 function shouldTrack(url) { 38 return trackable.some((part) => url && url.indexOf(part) !== -1); 39 } 40 41 function shorten(url) { 42 if (!url) return ''; 43 try { 44 const u = new URL(url, window.location.origin); 45 return u.pathname + u.search; 46 } catch (e) { 47 return url; 48 } 49 } 50 51 function getCartCookies() { 52 const cookies = document.cookie.split(';').map((v) => v.trim()); 53 const map = {}; 54 cookies.forEach((c) => { 55 const [k, ...rest] = c.split('='); 56 map[k] = rest.join('='); 57 }); 58 return { 59 cart_hash: map['woocommerce_cart_hash'] || null, 60 items_in_cart: map['woocommerce_items_in_cart'] || null, 61 session: Object.keys(map).find((k) => k.indexOf('wp_woocommerce_session_') === 0) || null, 62 }; 63 } 64 65 function record(action, payload = {}) { 66 const data = Object.assign({}, basePayload, getCartCookies(), payload, { action }); 67 if (window.newrelic && typeof window.newrelic.addPageAction === 'function') { 68 window.newrelic.addPageAction('CartEvent', data); 69 } 70 if (cfg.debug) { 71 console.debug('[CartTelemetry]', action, data); 72 } 73 } 74 75 $(document.body).on('added_to_cart', function (_e, fragments, cartHash) { 76 record('added_to_cart', { 77 cart_hash: cartHash || null, 78 fragment_keys: fragments ? Object.keys(fragments) : [], 79 }); 80 }); 81 82 $(document.body).on('removed_from_cart', function (_e, data) { 83 record('removed_from_cart', { 84 cart_item_key: data ? data.cart_item_key : null, 85 }); 86 }); 87 88 $(document.body).on('updated_cart_totals', function () { 89 record('updated_cart_totals'); 90 }); 91 92 $(document.body).on('wc_fragments_refreshed wc_fragment_refresh', function () { 93 record('wc_fragments_refresh'); 94 }); 95 96 $(document).on('dbiRefreshCart', function () { 97 record('dbiRefreshCart_trigger'); 98 }); 99 100 $(document).on('Searchanise.AddToCartSuccess', function () { 101 record('searchanise_add_to_cart'); 102 }); 103 104 $(document).ajaxSend(function (_evt, xhr, settings) { 105 if (!settings || !shouldTrack(settings.url)) { 106 return; 107 } 108 ajaxTimers.set(xhr, { start: performance.now(), url: settings.url }); 109 }); 110 111 $(document).ajaxComplete(function (_evt, xhr, settings) { 112 if (!ajaxTimers.has(xhr)) { 113 return; 114 } 115 const meta = ajaxTimers.get(xhr); 116 ajaxTimers.delete(xhr); 117 record('ajax_cart_call', { 118 url: shorten(meta.url || settings.url), 119 status: xhr.status, 120 duration_ms: Math.round(performance.now() - meta.start), 121 cf_cache_status: xhr.getResponseHeader('CF-Cache-Status') || null, 122 cache_control: xhr.getResponseHeader('Cache-Control') || null, 123 was_aborted: xhr.status === 0, 124 }); 125 }); 126 127 $(document).ajaxError(function (_evt, xhr, settings, error) { 128 if (!ajaxTimers.has(xhr) && !shouldTrack(settings?.url || '')) { 129 return; 130 } 131 const meta = ajaxTimers.get(xhr) || { start: performance.now(), url: settings?.url }; 132 ajaxTimers.delete(xhr); 133 record('ajax_cart_error', { 134 url: shorten(meta.url || settings?.url), 135 status: xhr ? xhr.status : null, 136 duration_ms: Math.round(performance.now() - meta.start), 137 message: error || null, 138 }); 139 }); 140})(jQuery); 141 142
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.