datadog-ux-utils
Version:
Datadog RUM focused UX & performance toolkit: API guards (retry, breaker, rate), React telemetry (error boundary, profiler, Suspense), web vitals & resource observers, offline queues.
3 lines (2 loc) • 4.56 kB
JavaScript
;const R=require("./datadog-DV4lp5AO.cjs"),p=require("@datadog/browser-rum"),m=require("./config-ByuBXTv9.cjs"),_={failureThreshold:5,cooldownMs:1e4,halfOpenMax:2},M=new Map;async function S(e,a,r={}){const t=A(e,r),o=Date.now();if(t.state==="open"){if(o<t.nextTry)throw b("open",e,t.nextTry);t.state="half",t.halfOpenInFlight=0}if(t.state==="half"&&t.halfOpenInFlight>=t.cfg.halfOpenMax)throw b("half-saturated",e,t.nextTry);t.state==="half"&&t.halfOpenInFlight++;try{const n=await a();return N(t,e),n}catch(n){throw F(t),n}finally{t.state==="half"&&t.halfOpenInFlight--}}function A(e,a){let r=M.get(e);return r||(r={state:"closed",failures:0,nextTry:0,halfOpenInFlight:0,cfg:{..._,...a}},M.set(e,r)),r}function N(e,a){e.failures=0,e.state!=="closed"&&(e.state="closed")}function F(e,a){e.failures++,(e.state==="half"||e.failures>=e.cfg.failureThreshold)&&(e.state="open",e.nextTry=Date.now()+e.cfg.cooldownMs,R.addAction("api_circuit_open",{cooldown_ms:e.cfg.cooldownMs}))}function b(e,a,r){const t=new Error(`Circuit ${e} for ${a} until ${new Date(r).toISOString()}`);return t.name="ApiCircuitOpenError",t}const T=async(e,a)=>{const r=m.getUxConfig(),t=performance.now();let o;try{o=await fetch(e,a);const n=performance.now()-t;return n>=r.apiSlowMs&&g("api_slow",{url:String(typeof e=="string"?e:e.toString()),method:a?.method??"GET",duration_ms:Math.round(n),status:o.status},r.actionSampleRate),o}catch(n){throw w(n,{where:"ddFetch",url:String(typeof e=="string"?e:e.toString())}),n}},D=async(e,a,r)=>{const t=m.getUxConfig(),o=performance.now();try{const n=await a,s=performance.now()-o;return s>=t.apiSlowMs&&g("promise_slow",{label:e,duration_ms:Math.round(s),...r},t.actionSampleRate),n}catch(n){throw w(n,{label:e,...r}),n}},g=(e,a,r)=>{Math.random()*100<r&&p.datadogRum.addAction(e,a)},w=(e,a)=>{p.datadogRum.addError(e,a)},l=new Map;function O(e,a,r){const{ttlMs:t,report:o}=C(r),n=Date.now(),s=l.get(e);if(s&&(s.state==="pending"||s.expireAt>n))return I(o,s.state,e,{age_ms:n-s.startedAt,ttl_ms:s.expireAt?s.expireAt-n:0}),s.promise;const d=n,i={promise:Promise.resolve().then(a),expireAt:n+(t>0?t:0),state:"pending",startedAt:d};return l.set(e,i),i.promise=i.promise.then(c=>(t>0?(i.state="cached",i.expireAt=Date.now()+t,i.promise=Promise.resolve(c),setTimeout(()=>{const u=l.get(e);u&&u.state==="cached"&&u.expireAt<=Date.now()&&l.delete(e)},t+25)):l.delete(e),c)).catch(c=>{throw l.delete(e),c}),i.promise}function z(e){e?l.delete(e):l.clear()}function E(){return l.size}function C(e){if(typeof e=="number")return{ttlMs:e,report:{enabled:!1,sampleRate:10,actionName:"api_dedupe_hit"}};const a=e?.ttlMs??0;let r=!1,t=10,o="api_dedupe_hit";return e?.report===!0?r=!0:typeof e?.report=="object"&&(r=!0,typeof e.report.sampleRate=="number"&&(t=P(e.report.sampleRate)),e.report.actionName&&(o=e.report.actionName)),{ttlMs:a,report:{enabled:r,sampleRate:t,actionName:o}}}function I(e,a,r,t){if(e.enabled&&!(Math.random()*100>=e.sampleRate))try{R.addAction(e.actionName,{key:r,kind:a,...t},e.sampleRate)}catch{}}function P(e){return Number.isNaN(e)?0:Math.max(0,Math.min(100,Math.round(e)))}const B=async(e,a)=>{const r=m.getUxConfig();if(!r.captureResponseSize)return e;try{const t=e.headers.get("content-length");let o=t?parseInt(t,10):NaN;Number.isFinite(o)||(o=(await e.clone().arrayBuffer()).byteLength);const n=Math.round(o/1024);n>=r.apiLargeKb&&p.datadogRum.addAction("api_large_payload",{url:a,size_kb:n,threshold_kb:r.apiLargeKb,status:e.status})}catch{}return e},j={retries:3,baseMs:200,maxMs:5e3,factor:2,jitter:!0,shouldRetry:()=>!0,report:!1};async function L(e,a,r){const{retries:t,baseMs:o,maxMs:n,factor:s,jitter:d,shouldRetry:i,report:c}={...j,...r},u=typeof c=="object"?{enabled:!0,sampleRate:c.sampleRate??10,actionName:c.actionName??"api_retry"}:c===!0?{enabled:!0,sampleRate:10,actionName:"api_retry"}:{enabled:!1,sampleRate:0,actionName:""};let f=0,y;for(;f<=t;)try{return f>0&&u.enabled&&q(u,e,f),await a()}catch(h){if(y=h,f>=t||!i(h,f))throw h;const x=U(o,s,f,n,d);await $(x),f++}throw y}function U(e,a,r,t,o){let n=Math.min(e*Math.pow(a,r),t);if(o){const s=Math.floor(Math.random()*e);n+=Math.random()<.5?-s:s,n=Math.max(0,n)}return n}function $(e){return new Promise(a=>setTimeout(a,e))}function q(e,a,r){e.enabled&&Math.random()*100>=e.sampleRate}exports.clearDedupe=z;exports.ddFetch=T;exports.dedupe=O;exports.dedupeSize=E;exports.maybeAction=g;exports.maybeError=w;exports.retry=L;exports.timePromise=D;exports.withResponseSizeCheck=B;exports.wrapWithBreaker=S;
//# sourceMappingURL=retry-BGWdGkEk.cjs.map