promoted-ts-client
Version:
A Typescript Client to contact Promoted APIs.
2 lines • 8.89 kB
JavaScript
var c=class{sampleRandom(e){return e>=1?!0:e<=0?!1:Math.random()<e}};var f=(t,e)=>{let r,n=new Promise((i,o)=>{r=setTimeout(()=>o(new Error("Timeout")),e)});return Promise.race([t,n]).then(i=>(clearTimeout(r),i))};var h=t=>Math.max(0,t?.offset??0),A=(t,e)=>{let r=t?.size??-1;return r<=0?e.length:r},d=class{applyPaging=(e,r,n)=>{let i=h(n),o=i-r,p=A(n,e),l=Math.min(p,e.length-o);if(l<=0)return[];let a=new Array(l);for(let u=0;u<l;u++){let s=e[o];a[u]={contentId:s.contentId,position:s.position??i},o++,i++}return a}};var y=(r=>(r[r.API=1]="API",r[r.SDK=2]="SDK",r))(y||{});var g=t=>{let e=[],r=P(t);r&&e.push(r);let n=S(t);return n&&e.push(n),e},P=t=>{let{experiment:e,request:r}=t;if(r.requestId)return new Error("Request.requestId should not be set");if(!r.userInfo)return new Error("Request.userInfo should be set");let{insertion:n}=r;for(let i of n??[]){if(i.requestId)return new Error("Insertion.requestId should not be set");if(i.insertionId)return new Error("Insertion.insertionId should not be set");if(!i.contentId)return new Error("Insertion.contentId should be set")}if(e){if(e.platformId)return new Error("Experiment.platformId should not be set");if(e.userInfo)return new Error("Experiment.userInfo should not be set");if(e.timing)return new Error("Experiment.timing should not be set")}},S=t=>{let{retrievalInsertionOffset:e,request:{paging:r}}=t,n=h(r);if(n<e)return new Error(`offset(${n}) should be >= retrievalInsertionOffset(${e}). offset should be the global position.`)},E=t=>{if(typeof t=="string")try{t=JSON.parse(t)}catch(o){throw new Error(`Invalid Delivery Response. Not valid JSON. Response=${t}. Error=${o}`)}let{error:e,requestId:r}=t;if(e)throw new Error(`Invalid Delivery Response. 'error' was encountered. Response=${JSON.stringify(t)}`);let{insertion:n,pagingInfo:i}=t;if(!r)throw new Error(`Invalid Delivery Response. Expected requestId. Response=${JSON.stringify(t)}`);if(n){if(!Array.isArray(n))throw new Error(`Invalid Delivery Response. Expected insertions as Array. Response=${JSON.stringify(t)}`)}else n=[];return i||(i={}),{requestId:r,insertion:n,pagingInfo:i}};var D="ts.13.1.0",M=250,k=3e3,B=1e3,Z=0,b=1,ee=2,L=4,te=0,T=1,re=2,ne=t=>{t.log().then(w,w)},w=()=>{},ie=t=>t.enabled===void 0||t.enabled?new R(t):new v,v=class{pager;constructor(){this.pager=new d}async deliver(e){let{request:r}=e,n=this.pager.applyPaging(r.insertion??[],e.retrievalInsertionOffset,r?.paging);return Promise.resolve({log:()=>Promise.resolve(void 0),responseInsertions:n,executionServer:2})}get enabled(){return!1}},R=class{deliveryClient;metricsClient;validateRequests;shadowTrafficDeliveryRate;blockingShadowTraffic;defaultRequestValues;handleError;uuid;deliveryTimeoutMillis;metricsTimeoutMillis;shouldApplyTreatment;sampler;pager;maxRequestInsertions;nowMillis;deliveryTimeoutWrapper;metricsTimeoutWrapper;constructor(e){if(this.pager=new d,this.deliveryClient=e.deliveryClient,this.metricsClient=e.metricsClient,this.validateRequests=e.validateRequests??!0,this.maxRequestInsertions=e.maxRequestInsertions??B,this.shadowTrafficDeliveryRate=e.shadowTrafficDeliveryRate??0,this.shadowTrafficDeliveryRate<0||this.shadowTrafficDeliveryRate>1)throw new RangeError("shadowTrafficDeliveryRate must be between 0 and 1");this.blockingShadowTraffic=e.blockingShadowTraffic??!1,this.sampler=e.sampler??new c;let{defaultRequestValues:{onlyLog:r}={}}=e;this.defaultRequestValues={onlyLog:r===void 0?!1:r},this.handleError=e.handleError,this.uuid=e.uuid,this.deliveryTimeoutMillis=e.deliveryTimeoutMillis??M,this.metricsTimeoutMillis=e.metricsTimeoutMillis??k,this.nowMillis=e.nowMillis??(()=>Date.now()),this.shouldApplyTreatment=e.shouldApplyTreatment??_,this.deliveryTimeoutWrapper=e.deliveryTimeoutWrapper??f,this.metricsTimeoutWrapper=e.metricsTimeoutWrapper??f}get enabled(){return!0}async deliver(e){let{onlyLog:r,request:n}=e;if(r=r??this.defaultRequestValues.onlyLog,this.validateRequests){let s=g(e);if(s)for(let m of s)this.handleError(m)}n=this.fillInRequestFields(n);let i=[],o;n.insertion||(n.insertion=[]),n.insertion.length>this.maxRequestInsertions&&(console.warn("Exceeded max request insertions, trimming"),n.insertion=n.insertion.slice(0,this.maxRequestInsertions));let p=!1,l=!1;if(!r)try{if(o=e.experiment,this.shouldApplyTreatment(o)){let s={...n,clientInfo:{trafficType:b,clientType:T,...n.clientInfo}};p=!0;let m=await this.callDelivery(s);l=!0,i=m.insertion}}catch(s){this.handleRequestError(s,"delivery",n.clientRequestId)}!p&&this.shouldSendAsShadowTraffic()&&(this.blockingShadowTraffic?await this.deliverBlockingShadowTraffic(n):this.deliverNonBlockingShadowTraffic(n));let a;if(!l){let s=this.uuid(),m={...n,requestId:s};i=this.pager.applyPaging(n.insertion,e.retrievalInsertionOffset,n.paging),O(i,this.uuid);let q={requestId:s,insertion:i,pagingInfo:{}};a=this.createSdkDeliveryLog(m,q)}let u=this.createLogRequest(n,a,o);return{log:this.createLogFn(u,n.clientRequestId),responseInsertions:i,executionServer:l?1:2,clientRequestId:n.clientRequestId,logRequest:u}}shouldSendAsShadowTraffic=()=>this.shadowTrafficDeliveryRate&&this.sampler.sampleRandom(this.shadowTrafficDeliveryRate);callDelivery=async e=>E(await this.deliveryTimeoutWrapper(this.deliveryClient(e),this.deliveryTimeoutMillis));deliverNonBlockingShadowTraffic=e=>{this.deliverBlockingShadowTraffic(e)};deliverBlockingShadowTraffic=async e=>{let r={...e,clientInfo:{trafficType:L,clientType:T,...e.clientInfo}};return this.callDelivery(r).then(()=>{}).catch(n=>this.handleRequestError(n,"shadow delivery",e.clientRequestId))};createLogRequest(e,r,n){if(r===void 0&&n===void 0)return;let i=N(e);return r&&(i.deliveryLog=[r],r.request&&F(r.request)),n&&(i.cohortMembership=[n]),i.clientInfo={clientType:T,trafficType:b,...i.clientInfo},i}createSdkDeliveryLog(e,r){return{request:e,response:r,execution:{executionServer:2,serverVersion:D}}}createLogFn(e,r){return async()=>{if(e===void 0)return Promise.resolve(void 0);try{await this.metricsTimeoutWrapper(this.metricsClient(e),this.metricsTimeoutMillis)}catch(n){this.handleRequestError(n,"metrics",r)}return Promise.resolve(void 0)}}fillInRequestFields=e=>{let r={...e.timing};return e={...e,timing:r},r.clientLogTimestamp||(r.clientLogTimestamp=this.nowMillis()),e.clientRequestId||(e.clientRequestId=this.uuid()),e};handleRequestError=(e,r,n)=>{let i=e.message??e.toString();this.handleError(new Error(`${i}; ${r}, clientRequestId=${n}`))}},O=(t,e)=>{t.forEach(r=>r.insertionId=e())},_=t=>{let e=t?.arm;return e===void 0||e!=="CONTROL"},N=t=>{let{platformId:e,userInfo:r,timing:n,clientInfo:i}=t;return{platformId:e,userInfo:r,timing:n,clientInfo:i}},F=t=>{delete t.platformId,delete t.userInfo,delete t.timing,delete t.clientInfo};var se=t=>{throw t},le=t=>console.error(t);var I=t=>{if(t.length===0)return 0;let e=0,r;for(let n=0;n<t.length;n++)r=t.charCodeAt(n),e=(e<<5)-e+r,e|=0;return e},x=(t,e)=>{let r=17;return r=r*31+t,r=r*31+e,r},C=(t,e)=>(t%e+e)%e;var de=(t,e,r,n)=>(n===void 0&&(n=1e3),U({cohortId:t,numActiveControlBuckets:e*n/100,numControlBuckets:n/2,numActiveTreatmentBuckets:r*n/100,numTreatmentBuckets:n/2})),U=t=>{if(!t.cohortId)throw"cohortId needs to be a non-empty string";if(t.numActiveControlBuckets<0)throw"numActiveControlBuckets needs to be non-negative";if(t.numActiveTreatmentBuckets<0)throw"numActiveTreatmentBuckets needs to be non-negative";if(t.numActiveControlBuckets>t.numControlBuckets)throw"numActiveControlBuckets needs to be <= numControlBuckets";if(t.numActiveTreatmentBuckets>t.numTreatmentBuckets)throw"numActiveTreatmentBuckets needs to be <= numTreatmentBuckets";return{...t,cohortIdHash:I(t.cohortId),numTotalBuckets:t.numControlBuckets+t.numTreatmentBuckets}},pe=(t,e)=>{let r=x(I(t),e.cohortIdHash),n=C(r,e.numTotalBuckets);if(n<e.numActiveControlBuckets)return{cohortId:e.cohortId,arm:"CONTROL"};let{numControlBuckets:i}=e;if(i<=n&&n<i+e.numActiveTreatmentBuckets)return{cohortId:e.cohortId,arm:"TREATMENT"}};var fe=(t,e)=>t.reduce((r,n)=>{let{contentId:i}=n;if(!i)console.warn("Encounter missing Insertion.contentId");else{let o=e[i];o&&r.push({...o,insertionId:n.insertionId})}return r},[]),he=(t,e)=>t.reduce((r,n)=>{let{contentId:i}=n;if(!i)console.warn("Encounter missing Insertion.contentId");else{let o=e[i];o&&r.push(o)}return r},[]);export{re as ClientType_PLATFORM_CLIENT,T as ClientType_PLATFORM_SERVER,te as ClientType_UNKNOWN_REQUEST_CLIENT,y as ExecutionServer,v as NoopPromotedClient,R as PromotedClientImpl,D as SERVER_VERSION,b as TrafficType_PRODUCTION,ee as TrafficType_REPLAY,L as TrafficType_SHADOW,Z as TrafficType_UNKNOWN_TRAFFIC_TYPE,x as combineHash,I as hashCode,ne as log,le as logOnError,C as mod,ie as newPromotedClient,w as noopFn,U as prepareTwoArmExperimentConfig,se as throwOnError,fe as toContents,he as toContentsWithoutInsertionId,de as twoArmExperimentConfig5050,pe as twoArmExperimentMembership};
//# sourceMappingURL=index.js.map