@configdirector/nextjs-sdk 1.13.1 → 1.14.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.
Files changed (50) hide show
  1. package/dist/client/index.cjs +1 -1
  2. package/dist/client/index.d.cts +2 -2
  3. package/dist/client/index.d.mts +2 -2
  4. package/dist/client/index.mjs +1 -1
  5. package/dist/client/index.mjs.map +1 -1
  6. package/dist/client/installedTestClient-Bam5r_HR.cjs +6 -0
  7. package/dist/client/installedTestClient-CL4AQC58.mjs +7 -0
  8. package/dist/client/installedTestClient-CL4AQC58.mjs.map +1 -0
  9. package/dist/client/testing.cjs +1 -1
  10. package/dist/client/testing.d.cts +12 -3
  11. package/dist/client/testing.d.cts.map +1 -1
  12. package/dist/client/testing.d.mts +12 -3
  13. package/dist/client/testing.d.mts.map +1 -1
  14. package/dist/client/testing.mjs +1 -1
  15. package/dist/client/testing.mjs.map +1 -1
  16. package/dist/client/{types-CRVL6Yi2.d.cts → types-CdyMdj5l.d.mts} +75 -7
  17. package/dist/client/types-CdyMdj5l.d.mts.map +1 -0
  18. package/dist/client/{types-B4kvU3bh.d.mts → types-P8frfCGH.d.cts} +75 -7
  19. package/dist/client/types-P8frfCGH.d.cts.map +1 -0
  20. package/dist/server/DefaultConfigDirectorClient-LQ79aY-g.mjs +6 -0
  21. package/dist/server/DefaultConfigDirectorClient-LQ79aY-g.mjs.map +1 -0
  22. package/dist/server/DefaultConfigDirectorClient-VHa0AfMj.cjs +5 -0
  23. package/dist/server/{errors-Do5xWGgb.d.cts → errors-CkxBFyZy.d.cts} +76 -7
  24. package/dist/server/errors-CkxBFyZy.d.cts.map +1 -0
  25. package/dist/server/{errors-CxXHE84y.d.mts → errors-CsEeGYMl.d.mts} +76 -7
  26. package/dist/server/errors-CsEeGYMl.d.mts.map +1 -0
  27. package/dist/server/index.cjs +1 -1
  28. package/dist/server/index.d.cts +2 -2
  29. package/dist/server/index.d.cts.map +1 -1
  30. package/dist/server/index.d.mts +2 -2
  31. package/dist/server/index.d.mts.map +1 -1
  32. package/dist/server/index.mjs +1 -1
  33. package/dist/server/testing.cjs +1 -1
  34. package/dist/server/testing.d.cts +12 -3
  35. package/dist/server/testing.d.cts.map +1 -1
  36. package/dist/server/testing.d.mts +12 -3
  37. package/dist/server/testing.d.mts.map +1 -1
  38. package/dist/server/testing.mjs +1 -1
  39. package/dist/server/testing.mjs.map +1 -1
  40. package/package.json +1 -1
  41. package/dist/client/installedTestClient-BqVnonO8.mjs +0 -7
  42. package/dist/client/installedTestClient-BqVnonO8.mjs.map +0 -1
  43. package/dist/client/installedTestClient-DM_qeRk9.cjs +0 -6
  44. package/dist/client/types-B4kvU3bh.d.mts.map +0 -1
  45. package/dist/client/types-CRVL6Yi2.d.cts.map +0 -1
  46. package/dist/server/DefaultConfigDirectorClient-BfpJX-Ni.mjs +0 -6
  47. package/dist/server/DefaultConfigDirectorClient-BfpJX-Ni.mjs.map +0 -1
  48. package/dist/server/DefaultConfigDirectorClient-C4cOinqO.cjs +0 -5
  49. package/dist/server/errors-CxXHE84y.d.mts.map +0 -1
  50. package/dist/server/errors-Do5xWGgb.d.cts.map +0 -1
@@ -1,2 +1,2 @@
1
1
  "use client";
2
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./installedTestClient-DM_qeRk9.cjs`);let l=require(`react`);l=s(l);let u=require(`react/jsx-runtime`);const d=e=>{if(e.type===`json`||e.type==null&&typeof e.value==`object`){if(e.valueId)return{valueId:e.valueId,type:`json`};try{return{value:JSON.stringify(e.value),type:`json`}}catch{return{value:e.value.toString(),type:`json`}}}let t=e.value?.toString();return t&&t.length<=500?{value:t}:e.valueId?{valueId:e.valueId}:{value:t}};var f=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},p=class{constructor(e){this.turnedOff=!1,this.pendingEvaluations=[],this.pendingInvalidContextSubmissions=new f,this.logger=e.logger,this.workerCloseTimeout=e.workerCloseTimeout??6e3,this.pendingEvaluationLimit=e.evaluationQueueLimit??1e3,this.clientSession=e.clientSession,this.initializeMessage={type:`Initialize`,payload:{sdkKey:e.sdkKey,sdkIdentity:e.sdkIdentity,metaContext:e.metaContext,baseUrl:e.baseUrl.toString(),evaluationQueueLimit:this.pendingEvaluationLimit,initialFlushIntervalDelay:e.initialFlushIntervalDelay??5e3,flushIntervalDelay:e.flushIntervalDelay??3e4}},this.visibilityHandler=()=>{document.visibilityState===`hidden`&&this.flush()}}createWorkerOrTurnOff(){if(typeof Worker>`u`){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.`);return}try{return new Worker(URL.createObjectURL(new Blob(["(function(){let e=async(e,t)=>e.valueId?{valueId:e.valueId}:e.value?e.value.length<=500&&e.type!=`json`?{value:e.value}:{valueId:await t(e.value)}:e,t=e=>{let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]?.length??0)>0)return!1;return!0},n=e=>{if(!e)return!0;let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]??0)>0)return!1;return!0},r=async(e,t,n,r)=>{let i=new AbortController,a=setTimeout(()=>{r.debug(`[fetchWithTimeout] Reached timeout, aborting request`),i.abort()},e);try{let e=await fetch(typeof t==`string`||t instanceof Request?t:t.toString(),{...n,signal:i.signal});return clearTimeout(a),e}catch(e){throw r.warn(`[fetchWithTimeout] Fetch error: `,e),clearTimeout(a),e}},i=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError;var a=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,this.sdkIdentity=e.sdkIdentity,this.metaContext=e.metaContext,this.url=e.urlFactory(`client/telemetry/v1`,e.baseUrl),this.clientSession=e.clientSession}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let{instanceId:i}=await this.clientSession,a={clientSdkKey:this.sdkKey,instanceId:i,metaContext:{sdkName:this.sdkIdentity.sdkName,sdkVersion:this.sdkIdentity.sdkVersion,appName:this.metaContext.appName,appVersion:this.metaContext.appVersion},context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r};if(this.isReportEmpty(a))return{success:!0,fatalError:!1};let o=await this.sendReport(a);return o.fatalError&&(this.executeRequests=!1),o}isReportEmpty(e){return t(e.discreteEvents)&&t(e.aggregatedEvents)&&n(e.droppedEvents)}async sendReport(e){try{let t=await r(5e3,this.url,{method:`POST`,body:JSON.stringify(e),keepalive:!0},this.logger),n=this.isStatusFatal(t.status);return n&&this.logger.warn(`[EventReporter] Received a fatal status response (${t.status}) from the telemetry endpoint. No more telemetry data will be sent.`),{success:t.ok,fatalError:n}}catch(e){let t=i(e);return this.logger.warn(`[EventReporter] Error attempting to send telemetry data: ${e}`,{error:e}),{success:!1,fatalError:t}}}isStatusFatal(e){return!!e&&e>=400&&e<500&&e!=429}},o=class{aggregate(e){if(e.events.length==0)return[];let t=new Map;for(let n of e.events){let e=JSON.stringify(n),r=t.get(e)?.count||0;t.set(e,{event:n,count:r+1})}return Array.from(t).map(([,t])=>({startTime:e.startTime,endTime:e.endTime,count:t.count,event:t.event}))}},s=class{constructor(e){this._events=[],this._droppedEventCount=0,this.limit=e??1e3}get events(){return this._events}get reachedLimit(){return this._events.length>=this.limit}get droppedEventCount(){return this._droppedEventCount}push(...e){this.startTime||=new Date;let t=Math.max(0,e.length-this.limit),n=e.slice(t,e.length);if(this._droppedEventCount+=t,this._events.length+n.length>this.limit){let e=this._events.length+n.length-this.limit;this._events.splice(0,e),this._droppedEventCount+=e}return this._events.push(...n)}takeSnapshot(){let e=new Date,t=this.startTime??e,n=this._events.splice(0),r=this._droppedEventCount;return this.startTime=void 0,this._droppedEventCount=0,{startTime:t,endTime:e,events:n,droppedCount:r}}clear(){this._events=[],this.startTime=void 0,this._droppedEventCount=0}},c=class{constructor(e){this.aggregator=new o,this.collectEvents=!0,this.started=!1,this.logger=e.logger,this.evaluationEventQueue=new s(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4,this.initialFlushIntervalDelay=e.initialFlushIntervalDelay??5e3}start(){this.started||!this.collectEvents||(this.started=!0,this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.initialFlushIntervalDelay))}async flushAndScheduleNext(){if(!this.collectEvents)return;let e;try{e=await this.flush()}catch(t){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events: `,t),e={success:!1,fatalError:!1}}e.fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.collectEvents&&(this.cancelScheduledFlush(),this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay))}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout);try{await this.flush()}catch(e){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events during close: `,e)}this.evaluationEventQueue.clear()}dispose(){this.close()}},l=class{constructor(e){this.valueIdGenerator=e,this.valueIdGenerator=e}async process(t){let n=await Promise.all(t.events.map(async t=>({...t,defaultValue:await e(t.defaultValue,this.valueIdGenerator),evaluatedValue:await e(t.evaluatedValue,this.valueIdGenerator)})));return{...t,events:n}}},u=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},d=class extends c{constructor(e){super(e),this.invalidContextSubmissions=new u,this.reporter=new a(e),this.evaluationEventSnapshotPreprocessor=new l(e.valueIdGenerator)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}recordInvalidContext(e){this.invalidContextSubmissions.record(e)}absorbInvalidContextSubmissions(e){this.invalidContextSubmissions.absorb(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=await this.evaluationEventSnapshotPreprocessor.process(this.evaluationEventQueue.takeSnapshot());return await this.reporter?.report({context:this._context,discreteEvents:{},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e),invalidContext:this.invalidContextSubmissions.takeSnapshot()},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let f=(e,t)=>new URL(e,t?.toString()),p=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},m=Math.ceil(128/Math.log2(62)),h=new TextEncoder,g=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,h.encode(e?.toString()??``));return p(new Uint8Array(t,0,16),m)},_,v,y=new Promise(e=>{v=e}),b=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),x=e=>{try{self.postMessage(e)}catch{self.postMessage(b(e.payload.level,e.payload.message))}},S={debug:function(e,...t){x(b(`debug`,e,t))},info:function(e,...t){x(b(`info`,e,t))},warn:function(e,...t){x(b(`warn`,e,t))},error:function(e,...t){x(b(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){S.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(S.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){S.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:S,clientSession:y}),_.start();break;case`ClientSession`:v(t.payload);break;case`EvaluatedConfigEvent`:_?.evaluatedConfig(t.payload);break;case`InvalidContextSubmissions`:_?.absorbInvalidContextSubmissions(t.payload.entries);break;case`UpdateContext`:_?.updateContext(t.payload.context);break;case`Flush`:_?.forceFlush();break;case`Close`:(_?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"],{type:`application/javascript`})))}catch(e){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: `,e);return}}turnOff(e,...t){this.turnedOff=!0,this.pendingEvaluations.length=0,this.logger.warn(e,...t)}startWorker(){if(this.worker||this.turnedOff)return this.worker;let e=this.createWorkerOrTurnOff();if(e){e.onmessage=e=>{this.handleWorkerEvent(e.data)},e.postMessage(this.initializeMessage),this.forwardClientSession(e),this.worker=e;try{document.addEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[TelemetryEventCollector] Could not configure 'visibilitychange' listener: `,e)}for(let t of this.pendingEvaluations)e.postMessage(t);return this.pendingEvaluations.length=0,this.forwardInvalidContextSubmissions(e),e}}forwardClientSession(e){this.clientSession.then(t=>{let n={type:`ClientSession`,payload:t};e.postMessage(n)})}forwardInvalidContextSubmissions(e){if(!e)return;let t=this.pendingInvalidContextSubmissions.takeSnapshot();if(t.length===0)return;let n={type:`InvalidContextSubmissions`,payload:{entries:t}};e.postMessage(n)}async updateContext(e){if(this.closePromise)return;let t={type:`UpdateContext`,payload:{context:e}};this.startWorker()?.postMessage(t)}evaluatedConfig(e){if(this.turnedOff)return;let t={type:`EvaluatedConfigEvent`,payload:this.sanitizeEvaluatedConfigEvent(e)};if(this.worker){this.worker.postMessage(t);return}this.pendingEvaluations.length>=this.pendingEvaluationLimit&&this.pendingEvaluations.shift(),this.pendingEvaluations.push(t)}recordInvalidContext(e){this.pendingInvalidContextSubmissions.record(e),this.forwardInvalidContextSubmissions(this.worker)}sanitizeEvaluatedConfigEvent(e){return{...e,defaultValue:d({value:e.defaultValue,type:e.type}),evaluatedValue:d({value:e.evaluatedValue,valueId:e.evaluatedValueId,type:e.type})}}handleWorkerEvent(e){if(e.type===`Closed`){this.finishClose();return}if(!e.payload?.level||!e.payload?.message)return;let{level:t,message:n,args:r}=e.payload;switch(t){case`debug`:this.logger.debug(n,...r);break;case`info`:this.logger.info(n,...r);break;case`warn`:this.logger.warn(n,...r);break;case`error`:this.logger.error(n,...r);break}}flush(){this.worker?.postMessage({type:`Flush`})}close(){return this.closePromise?this.closePromise:this.performClose()}performClose(){let e=this.worker;if(!e)return this.pendingEvaluations.length=0,this.closePromise=Promise.resolve(),this.closePromise;try{document.removeEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: `,e)}return this.closePromise=new Promise(t=>{this.closeResolve=t,this.closeTimer=setTimeout(()=>{this.logger.warn(`[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.`),this.finishClose()},this.workerCloseTimeout),e.postMessage({type:`Close`})}),this.closePromise}finishClose(){clearTimeout(this.closeTimer),this.closeTimer=void 0,this.worker?.terminate(),this.closeResolve?.()}};const m=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},h=Math.ceil(128/Math.log2(62)),g=new TextEncoder,_=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,g.encode(e?.toString()??``));return m(new Uint8Array(t,0,16),h)},v=e=>{let t=c.o();if(!t)return;let n=e.then(e=>c.i+e);return{read:async()=>t.getItem(await n),write:async e=>t.setItem(await n,e),remove:async()=>t.removeItem(await n),sizeLimit:()=>c.a}},y=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),b=()=>{if(!(typeof crypto>`u`||crypto.subtle==null))return async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return y(new Uint8Array(t))}},x=(e,t,n)=>c.r.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i,clientSession:a})=>new p({sdkKey:e,sdkIdentity:{sdkName:t.sdkName,sdkVersion:t.sdkVersion},metaContext:{appName:i?.appName,appVersion:i?.appVersion},logger:r,baseUrl:n,urlFactory:c.s,valueIdGenerator:_,clientSession:a}),e,t,n,{sha256HexDigest:b(),platformCachingProvider:v});var S=class{constructor(e){this.client=e,this.registrations=[]}on(e,t){this.client.on(e,t),this.registrations.push({event:e,handler:t})}registerHooks(e){for(let[t,n]of Object.entries(e??{})){let e=Array.isArray(n)?n:[n];for(let n of e)typeof n==`function`&&this.on(t,n)}}removeAll(){for(let{event:e,handler:t}of this.registrations)this.client.off(e,t);this.registrations=[]}};const C=(e,t)=>{if(Object.is(e,t))return!0;if(typeof e!=`object`||typeof t!=`object`||e===null||t===null||Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>C(e,t[n]));if(!w(e)||!w(t))return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&C(e[n],t[n]))},w=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},T=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!C(t,e.context)?`updateContext`:`none`:`initialize`,E=(e,t,n)=>{let r=T(e,t);return n&&r===`initialize`&&t===void 0?`waitForContext`:r},D={waitForContext:`waitingForContext`,initialize:`started`,updateContext:`started`,none:`started`},O=(e,t)=>({kind:D[e],client:t}),k=(e,t,n)=>{if(C(n,t))return{action:`skipUnchanged`};switch(e.kind){case`beforeFirstRenderEffects`:return{action:`keepForStartup`};case`waitingForContext`:return{action:`startClient`,client:e.client};case`started`:return{action:`updateContext`,client:e.client}}},A=l.default.createContext({status:`loading`,updateContext:async()=>{}});var j=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const M=e=>c.l(e,new j),N=e=>`client`in e&&e.client!==void 0,P=e=>e.isReady?`ready`:`default`,F=(e,t)=>{let n=t&&!N(e)&&e.mode===`offline`;return e.deferInitialization===!0&&!n},I=({run:e})=>((0,l.useEffect)(()=>{e()},[e]),null);var L=class extends l.Component{constructor(e){super(e),this.startupPhase={kind:`beforeFirstRenderEffects`},this.startAfterFirstRenderEffects=()=>{let e=this.client;e&&this.startClient(e,this.lastGivenContext)},this.receiveContext=async e=>{let t=k(this.startupPhase,this.lastGivenContext,e);switch(t.action){case`skipUnchanged`:return;case`keepForStartup`:this.lastGivenContext=e;return;case`startClient`:this.lastGivenContext=e,await this.startClient(t.client,e);return;case`updateContext`:this.lastGivenContext=e,await this.updateClientContext(t.client,e??{});return}};let t=N(e)?e.client:c.n();this.ownsClient=t===void 0,this.waitsForFirstContext=F(e,this.ownsClient),this.client=t,this.lastGivenContext=e.context,this.state=t?{client:t,status:t.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){let e=this.props;return x(e.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.13.1`},{connection:{url:e.url,timeout:e.timeout,mode:e.mode,pollingInterval:e.pollingInterval,values:e.values},metadata:{appName:e.appName,appVersion:e.appVersion},logger:M(e.logLevel??`warn`),hooks:e.hooks})}componentDidMount(){let e=this.client;this.ownsClient&&(e=this.buildClient(),this.client=e,this.setState({client:e})),e&&(this.handlers=new S(e),this.handlers.on(`configsUpdated`,()=>{this.setState({updatedAt:new Date})}),this.handlers.on(`clientReady`,()=>{this.setState({status:`ready`})}),this.ownsClient||this.handlers.registerHooks(this.props.hooks))}async startClient(e,t){let n=E(e,t,this.waitsForFirstContext);switch(this.startupPhase=O(n,e),n){case`waitForContext`:return;case`initialize`:await e.initialize(t),this.settleStatus(e);return;case`updateContext`:await this.updateClientContext(e,t);return;case`none`:return}}async updateClientContext(e,t){this.setState({status:`loading`}),await e.updateContext(t),this.settleStatus(e)}settleStatus(e){this.client===e&&this.setState({status:P(e)})}async componentDidUpdate(e){N(e)&&N(this.props)&&e.client!==this.props.client&&M(`warn`).warn(`The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.`),C(e.context,this.props.context)||await this.receiveContext(this.props.context)}componentWillUnmount(){this.handlers?.removeAll(),this.handlers=void 0,this.startupPhase={kind:`beforeFirstRenderEffects`},this.lastGivenContext=this.props.context,this.ownsClient&&(this.client?.dispose(),this.client=void 0)}render(){return(0,u.jsxs)(A.Provider,{value:{...this.state,initialConfigs:this.props.initialConfigs,updateContext:this.receiveContext},children:[this.props.children,(0,u.jsx)(I,{run:this.startAfterFirstRenderEffects})]})}},R=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const z=()=>new R(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),B=(e,t)=>{let n=(0,l.useContext)(A);if(!n)throw z();let r=n.initialConfigs?.[e];return{value:n.client?.isReady?n.client.getValue(e,t):r?c.u(r,t).parsedValue:t,readyStatus:n.status,loading:n.status===`loading`}},V=()=>{let e=(0,l.useContext)(A);if(!e)throw z();return{updateContext:e.updateContext}},H=()=>{let e=(0,l.useContext)(A);if(!e?.client)throw z();return{client:e.client}},U=()=>{let e=(0,l.useContext)(A);if(!e)throw z();return{readyStatus:e.status,loading:e.status===`loading`}};exports.ConfigDirectorNextContextError=R,exports.ConfigDirectorProvider=L,exports.createConsoleLogger=M,exports.useClient=H,exports.useConfigDirectorStatus=U,exports.useConfigValue=B,exports.useContext=V;
2
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});var e=Object.create,t=Object.defineProperty,n=Object.getOwnPropertyDescriptor,r=Object.getOwnPropertyNames,i=Object.getPrototypeOf,a=Object.prototype.hasOwnProperty,o=(e,i,o,s)=>{if(i&&typeof i==`object`||typeof i==`function`)for(var c=r(i),l=0,u=c.length,d;l<u;l++)d=c[l],!a.call(e,d)&&d!==o&&t(e,d,{get:(e=>i[e]).bind(null,d),enumerable:!(s=n(i,d))||s.enumerable});return e},s=(n,r,a)=>(a=n==null?{}:e(i(n)),o(r||!n||!n.__esModule?t(a,`default`,{value:n,enumerable:!0}):a,n));const c=require(`./installedTestClient-Bam5r_HR.cjs`);let l=require(`react`);l=s(l);let u=require(`react/jsx-runtime`);const d=e=>{if(e.type===`json`||e.type==null&&typeof e.value==`object`){if(e.valueId)return{valueId:e.valueId,type:`json`};try{return{value:JSON.stringify(e.value),type:`json`}}catch{return{value:e.value.toString(),type:`json`}}}let t=e.value?.toString();return t&&t.length<=500?{value:t}:e.valueId?{valueId:e.valueId}:{value:t}};var f=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},p=class{constructor(){this.entries=[],this.warningsRaisedThisBatch=new Set}add(e){return this.warningsOfKeeping(e).filter(e=>this.isFirstThisBatch(e))}absorb(e){this.entries.push(...e)}takeBatch(){let e=this.entries;return this.clear(),e}clear(){this.entries=[],this.warningsRaisedThisBatch.clear()}warningsOfKeeping(e){switch(e.outcome){case`dropped`:return e.warnings;case`admitted`:return this.entries.length>=1e3?[`batch-already-full`]:(this.entries.push(e.entry),e.warnings)}}isFirstThisBatch(e){return this.warningsRaisedThisBatch.has(e)?!1:(this.warningsRaisedThisBatch.add(e),!0)}},m=class{constructor(e){this.turnedOff=!1,this.pendingEvaluations=[],this.pendingInvalidContextSubmissions=new f,this.pendingTrackedEvents=new p,this.logger=e.logger,this.workerCloseTimeout=e.workerCloseTimeout??6e3,this.pendingEvaluationLimit=e.evaluationQueueLimit??1e3,this.clientSession=e.clientSession,this.initializeMessage={type:`Initialize`,payload:{sdkKey:e.sdkKey,sdkIdentity:e.sdkIdentity,metaContext:e.metaContext,baseUrl:e.baseUrl.toString(),evaluationQueueLimit:this.pendingEvaluationLimit,initialFlushIntervalDelay:e.initialFlushIntervalDelay??5e3,flushIntervalDelay:e.flushIntervalDelay??3e4}},this.visibilityHandler=()=>{document.visibilityState===`hidden`&&this.flush()}}createWorkerOrTurnOff(){if(typeof Worker>`u`){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.`);return}try{return new Worker(URL.createObjectURL(new Blob(['(function(){let e=async(e,t)=>e.valueId?{valueId:e.valueId}:e.value?e.value.length<=500&&e.type!=`json`?{value:e.value}:{valueId:await t(e.value)}:e,t=e=>{let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]?.length??0)>0)return!1;return!0},n=e=>{if(!e)return!0;let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]??0)>0)return!1;return!0},r=async(e,t,n,r)=>{let i=new AbortController,a=setTimeout(()=>{r.debug(`[fetchWithTimeout] Reached timeout, aborting request`),i.abort()},e);try{let e=await fetch(typeof t==`string`||t instanceof Request?t:t.toString(),{...n,signal:i.signal});return clearTimeout(a),e}catch(e){throw r.warn(`[fetchWithTimeout] Fetch error: `,e),clearTimeout(a),e}},i=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError,a=e=>e>=55296&&e<=56319,o=e=>e>=56320&&e<=57343,s=e=>{let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r<=127?t+=1:r<=2047?t+=2:a(r)&&n+1<e.length&&o(e.charCodeAt(n+1))?(t+=4,n++):t+=3}return t};var c=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,this.sdkIdentity=e.sdkIdentity,this.metaContext=e.metaContext,this.url=e.urlFactory(`client/telemetry/v1`,e.baseUrl),this.clientSession=e.clientSession}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let{instanceId:i}=await this.clientSession,a={clientSdkKey:this.sdkKey,instanceId:i,metaContext:{sdkName:this.sdkIdentity.sdkName,sdkVersion:this.sdkIdentity.sdkVersion,appName:this.metaContext.appName,appVersion:this.metaContext.appVersion},context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r};if(this.isReportEmpty(a))return{success:!0,fatalError:!1};let o=await this.sendReport(a);return o.fatalError&&(this.executeRequests=!1),o}isReportEmpty(e){return t(e.discreteEvents)&&t(e.aggregatedEvents)&&n(e.droppedEvents)}async sendReport(e){try{let t=JSON.stringify(e),n=await r(5e3,this.url,{method:`POST`,body:t,keepalive:s(t)<=32768},this.logger),i=this.isStatusFatal(n.status);return i&&this.logger.warn(`[EventReporter] Received a fatal status response (${n.status}) from the telemetry endpoint. No more telemetry data will be sent.`),{success:n.ok,fatalError:i}}catch(e){let t=i(e);return this.logger.warn(`[EventReporter] Error attempting to send telemetry data: ${e}`,{error:e}),{success:!1,fatalError:t}}}isStatusFatal(e){return!!e&&e>=400&&e<500&&e!=429}},l=class{aggregate(e){if(e.events.length==0)return[];let t=new Map;for(let n of e.events){let e=JSON.stringify(n),r=t.get(e)?.count||0;t.set(e,{event:n,count:r+1})}return Array.from(t).map(([,t])=>({startTime:e.startTime,endTime:e.endTime,count:t.count,event:t.event}))}},u=class{constructor(e){this._events=[],this._droppedEventCount=0,this.limit=e??1e3}get events(){return this._events}get reachedLimit(){return this._events.length>=this.limit}get droppedEventCount(){return this._droppedEventCount}push(...e){this.startTime||=new Date;let t=Math.max(0,e.length-this.limit),n=e.slice(t,e.length);if(this._droppedEventCount+=t,this._events.length+n.length>this.limit){let e=this._events.length+n.length-this.limit;this._events.splice(0,e),this._droppedEventCount+=e}return this._events.push(...n)}takeSnapshot(){let e=new Date,t=this.startTime??e,n=this._events.splice(0),r=this._droppedEventCount;return this.startTime=void 0,this._droppedEventCount=0,{startTime:t,endTime:e,events:n,droppedCount:r}}clear(){this._events=[],this.startTime=void 0,this._droppedEventCount=0}};let d={"name-outside-the-character-limit":`[ConfigDirectorClient] A tracked event was not reported because its name does not have 1 to 150 characters.`,"value-not-a-finite-number":`[ConfigDirectorClient] A tracked event was reported without its value because the value is not a finite number.`,"details-not-reportable":`[ConfigDirectorClient] A tracked event was reported without its details because they are not an object, have more than 20 top-level keys, are larger than 1024 bytes as JSON, or cannot be written as JSON.`,"batch-already-full":`[ConfigDirectorClient] A tracked event was not reported because 1000 tracked events are already waiting for the next telemetry batch.`},f=(e,t)=>{for(let n of t)e.warn(`${d[n]} Further tracked events like it are not logged until the next telemetry batch is sent.`)};var p=class{constructor(){this.entries=[],this.warningsRaisedThisBatch=new Set}add(e){return this.warningsOfKeeping(e).filter(e=>this.isFirstThisBatch(e))}absorb(e){this.entries.push(...e)}takeBatch(){let e=this.entries;return this.clear(),e}clear(){this.entries=[],this.warningsRaisedThisBatch.clear()}warningsOfKeeping(e){switch(e.outcome){case`dropped`:return e.warnings;case`admitted`:return this.entries.length>=1e3?[`batch-already-full`]:(this.entries.push(e.entry),e.warnings)}}isFirstThisBatch(e){return this.warningsRaisedThisBatch.has(e)?!1:(this.warningsRaisedThisBatch.add(e),!0)}},m=class{constructor(e){this.aggregator=new l,this.trackedEventQueue=new p,this.collectEvents=!0,this.started=!1,this.logger=e.logger,this.evaluationEventQueue=new u(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4,this.initialFlushIntervalDelay=e.initialFlushIntervalDelay??5e3}start(){this.started||!this.collectEvents||(this.started=!0,this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.initialFlushIntervalDelay))}trackedEvent(e){this.collectEvents&&f(this.logger,this.trackedEventQueue.add(e))}async flushAndScheduleNext(){if(!this.collectEvents)return;let e;try{e=await this.flush()}catch(t){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events: `,t),e={success:!1,fatalError:!1}}e.fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.collectEvents&&(this.cancelScheduledFlush(),this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay))}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout);try{await this.flush()}catch(e){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events during close: `,e)}this.evaluationEventQueue.clear(),this.trackedEventQueue.clear()}dispose(){this.close()}},h=class{constructor(e){this.valueIdGenerator=e,this.valueIdGenerator=e}async process(t){let n=await Promise.all(t.events.map(async t=>({...t,defaultValue:await e(t.defaultValue,this.valueIdGenerator),evaluatedValue:await e(t.evaluatedValue,this.valueIdGenerator)})));return{...t,events:n}}},g=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},_=class extends m{constructor(e){super(e),this.invalidContextSubmissions=new g,this.reporter=new c(e),this.evaluationEventSnapshotPreprocessor=new h(e.valueIdGenerator)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}recordInvalidContext(e){this.invalidContextSubmissions.record(e)}absorbInvalidContextSubmissions(e){this.invalidContextSubmissions.absorb(e)}absorbTrackedEventEntries(e){this.trackedEventQueue.absorb(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=await this.evaluationEventSnapshotPreprocessor.process(this.evaluationEventQueue.takeSnapshot());return await this.reporter?.report({context:this._context,discreteEvents:{trackedEvents:this.trackedEventQueue.takeBatch()},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e),invalidContext:this.invalidContextSubmissions.takeSnapshot()},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let v=(e,t)=>new URL(e,t?.toString()),y=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},b=Math.ceil(128/Math.log2(62)),x=new TextEncoder,S=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,x.encode(e?.toString()??``));return y(new Uint8Array(t,0,16),b)},C,w,T=new Promise(e=>{w=e}),E=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),D=e=>{try{self.postMessage(e)}catch{self.postMessage(E(e.payload.level,e.payload.message))}},O={debug:function(e,...t){D(E(`debug`,e,t))},info:function(e,...t){D(E(`info`,e,t))},warn:function(e,...t){D(E(`warn`,e,t))},error:function(e,...t){D(E(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!C){O.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(O.debug(`[TelemetryWorker] Received \'${t.type}\' event:`,t),t.type){case`Initialize`:if(C){O.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}C=new _({...t.payload,baseUrl:v(t.payload.baseUrl),urlFactory:v,valueIdGenerator:S,logger:O,clientSession:T}),C.start();break;case`ClientSession`:w(t.payload);break;case`EvaluatedConfigEvent`:C?.evaluatedConfig(t.payload);break;case`InvalidContextSubmissions`:C?.absorbInvalidContextSubmissions(t.payload.entries);break;case`TrackedEvent`:C?.trackedEvent(t.payload);break;case`TrackedEventEntries`:C?.absorbTrackedEventEntries(t.payload.entries);break;case`UpdateContext`:C?.updateContext(t.payload.context);break;case`Flush`:C?.forceFlush();break;case`Close`:(C?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();'],{type:`application/javascript`})))}catch(e){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: `,e);return}}turnOff(e,...t){this.turnedOff=!0,this.pendingEvaluations.length=0,this.pendingTrackedEvents.clear(),this.logger.warn(e,...t)}startWorker(){if(this.worker||this.turnedOff)return this.worker;let e=this.createWorkerOrTurnOff();if(e){e.onmessage=e=>{this.handleWorkerEvent(e.data)},e.postMessage(this.initializeMessage),this.forwardClientSession(e),this.worker=e;try{document.addEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[TelemetryEventCollector] Could not configure 'visibilitychange' listener: `,e)}for(let t of this.pendingEvaluations)e.postMessage(t);return this.pendingEvaluations.length=0,this.forwardInvalidContextSubmissions(e),this.forwardPendingTrackedEvents(e),e}}forwardPendingTrackedEvents(e){let t=this.pendingTrackedEvents.takeBatch();if(t.length===0)return;let n={type:`TrackedEventEntries`,payload:{entries:t}};e.postMessage(n)}forwardClientSession(e){this.clientSession.then(t=>{let n={type:`ClientSession`,payload:t};e.postMessage(n)})}forwardInvalidContextSubmissions(e){if(!e)return;let t=this.pendingInvalidContextSubmissions.takeSnapshot();if(t.length===0)return;let n={type:`InvalidContextSubmissions`,payload:{entries:t}};e.postMessage(n)}async updateContext(e){if(this.closePromise)return;let t={type:`UpdateContext`,payload:{context:e}};this.startWorker()?.postMessage(t)}evaluatedConfig(e){if(this.turnedOff)return;let t={type:`EvaluatedConfigEvent`,payload:this.sanitizeEvaluatedConfigEvent(e)};if(this.worker){this.worker.postMessage(t);return}this.pendingEvaluations.length>=this.pendingEvaluationLimit&&this.pendingEvaluations.shift(),this.pendingEvaluations.push(t)}recordInvalidContext(e){this.pendingInvalidContextSubmissions.record(e),this.forwardInvalidContextSubmissions(this.worker)}trackedEvent(e){if(!(this.turnedOff||this.closePromise)){if(this.worker){let t={type:`TrackedEvent`,payload:e};this.worker.postMessage(t);return}c.g(this.logger,this.pendingTrackedEvents.add(e))}}sanitizeEvaluatedConfigEvent(e){return{...e,defaultValue:d({value:e.defaultValue,type:e.type}),evaluatedValue:d({value:e.evaluatedValue,valueId:e.evaluatedValueId,type:e.type})}}handleWorkerEvent(e){if(e.type===`Closed`){this.finishClose();return}if(!e.payload?.level||!e.payload?.message)return;let{level:t,message:n,args:r}=e.payload;switch(t){case`debug`:this.logger.debug(n,...r);break;case`info`:this.logger.info(n,...r);break;case`warn`:this.logger.warn(n,...r);break;case`error`:this.logger.error(n,...r);break}}flush(){this.worker?.postMessage({type:`Flush`})}close(){return this.closePromise?this.closePromise:this.performClose()}performClose(){let e=this.worker;if(!e)return this.pendingEvaluations.length=0,this.pendingTrackedEvents.clear(),this.closePromise=Promise.resolve(),this.closePromise;try{document.removeEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: `,e)}return this.closePromise=new Promise(t=>{this.closeResolve=t,this.closeTimer=setTimeout(()=>{this.logger.warn(`[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.`),this.finishClose()},this.workerCloseTimeout),e.postMessage({type:`Close`})}),this.closePromise}finishClose(){clearTimeout(this.closeTimer),this.closeTimer=void 0,this.worker?.terminate(),this.closeResolve?.()}};const h=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},g=Math.ceil(128/Math.log2(62)),_=new TextEncoder,v=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,_.encode(e?.toString()??``));return h(new Uint8Array(t,0,16),g)},y=e=>{let t=c.o();if(!t)return;let n=e.then(e=>c.i+e);return{read:async()=>t.getItem(await n),write:async e=>t.setItem(await n,e),remove:async()=>t.removeItem(await n),sizeLimit:()=>c.a}},b=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),x=()=>{if(!(typeof crypto>`u`||crypto.subtle==null))return async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return b(new Uint8Array(t))}},S=(e,t,n)=>c.r.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i,clientSession:a})=>new m({sdkKey:e,sdkIdentity:{sdkName:t.sdkName,sdkVersion:t.sdkVersion},metaContext:{appName:i?.appName,appVersion:i?.appVersion},logger:r,baseUrl:n,urlFactory:c.s,valueIdGenerator:v,clientSession:a}),e,t,n,{sha256HexDigest:x(),platformCachingProvider:y});var C=class{constructor(e){this.client=e,this.registrations=[]}on(e,t){this.client.on(e,t),this.registrations.push({event:e,handler:t})}registerHooks(e){for(let[t,n]of Object.entries(e??{})){let e=Array.isArray(n)?n:[n];for(let n of e)typeof n==`function`&&this.on(t,n)}}removeAll(){for(let{event:e,handler:t}of this.registrations)this.client.off(e,t);this.registrations=[]}};const w=(e,t)=>{if(Object.is(e,t))return!0;if(typeof e!=`object`||typeof t!=`object`||e===null||t===null||Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>w(e,t[n]));if(!T(e)||!T(t))return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&w(e[n],t[n]))},T=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},E=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!w(t,e.context)?`updateContext`:`none`:`initialize`,D=(e,t,n)=>{let r=E(e,t);return n&&r===`initialize`&&t===void 0?`waitForContext`:r},O={waitForContext:`waitingForContext`,initialize:`started`,updateContext:`started`,none:`started`},k=(e,t)=>({kind:O[e],client:t}),A=(e,t,n)=>{if(w(n,t))return{action:`skipUnchanged`};switch(e.kind){case`beforeFirstRenderEffects`:return{action:`keepForStartup`};case`waitingForContext`:return{action:`startClient`,client:e.client};case`started`:return{action:`updateContext`,client:e.client}}},j=l.default.createContext({status:`loading`,updateContext:async()=>{}});var M=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const N=e=>c.l(e,new M),P=e=>`client`in e&&e.client!==void 0,F=e=>e.isReady?`ready`:`default`,I=(e,t)=>{let n=t&&!P(e)&&e.mode===`offline`;return e.deferInitialization===!0&&!n},L=({run:e})=>((0,l.useEffect)(()=>{e()},[e]),null);var R=class extends l.Component{constructor(e){super(e),this.startupPhase={kind:`beforeFirstRenderEffects`},this.startAfterFirstRenderEffects=()=>{let e=this.client;e&&this.startClient(e,this.lastGivenContext)},this.receiveContext=async e=>{let t=A(this.startupPhase,this.lastGivenContext,e);switch(t.action){case`skipUnchanged`:return;case`keepForStartup`:this.lastGivenContext=e;return;case`startClient`:this.lastGivenContext=e,await this.startClient(t.client,e);return;case`updateContext`:this.lastGivenContext=e,await this.updateClientContext(t.client,e??{});return}};let t=P(e)?e.client:c.n();this.ownsClient=t===void 0,this.waitsForFirstContext=I(e,this.ownsClient),this.client=t,this.lastGivenContext=e.context,this.state=t?{client:t,status:t.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){let e=this.props;return S(e.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.14.0`},{connection:{url:e.url,timeout:e.timeout,mode:e.mode,pollingInterval:e.pollingInterval,values:e.values},metadata:{appName:e.appName,appVersion:e.appVersion},logger:N(e.logLevel??`warn`),hooks:e.hooks})}componentDidMount(){let e=this.client;this.ownsClient&&(e=this.buildClient(),this.client=e,this.setState({client:e})),e&&(this.handlers=new C(e),this.handlers.on(`configsUpdated`,()=>{this.setState({updatedAt:new Date})}),this.handlers.on(`clientReady`,()=>{this.setState({status:`ready`})}),this.ownsClient||this.handlers.registerHooks(this.props.hooks))}async startClient(e,t){let n=D(e,t,this.waitsForFirstContext);switch(this.startupPhase=k(n,e),n){case`waitForContext`:return;case`initialize`:await e.initialize(t),this.settleStatus(e);return;case`updateContext`:await this.updateClientContext(e,t);return;case`none`:return}}async updateClientContext(e,t){this.setState({status:`loading`}),await e.updateContext(t),this.settleStatus(e)}settleStatus(e){this.client===e&&this.setState({status:F(e)})}async componentDidUpdate(e){P(e)&&P(this.props)&&e.client!==this.props.client&&N(`warn`).warn(`The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.`),w(e.context,this.props.context)||await this.receiveContext(this.props.context)}componentWillUnmount(){this.handlers?.removeAll(),this.handlers=void 0,this.startupPhase={kind:`beforeFirstRenderEffects`},this.lastGivenContext=this.props.context,this.ownsClient&&(this.client?.dispose(),this.client=void 0)}render(){return(0,u.jsxs)(j.Provider,{value:{...this.state,initialConfigs:this.props.initialConfigs,updateContext:this.receiveContext},children:[this.props.children,(0,u.jsx)(L,{run:this.startAfterFirstRenderEffects})]})}},z=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const B=()=>new z(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),V=(e,t)=>{let n=(0,l.useContext)(j);if(!n)throw B();let r=n.initialConfigs?.[e];return{value:n.client?.isReady?n.client.getValue(e,t):r?c.u(r,t).parsedValue:t,readyStatus:n.status,loading:n.status===`loading`}},H=()=>{let e=(0,l.useContext)(j);if(!e)throw B();return{updateContext:e.updateContext}},U=()=>{let e=(0,l.useContext)(j);if(!e?.client)throw B();return{client:e.client}},W=()=>{let e=(0,l.useContext)(j);if(!e)throw B();return{readyStatus:e.status,loading:e.status===`loading`}};exports.ConfigDirectorNextContextError=z,exports.ConfigDirectorProvider=R,exports.createConsoleLogger=N,exports.useClient=U,exports.useConfigDirectorStatus=W,exports.useConfigValue=V,exports.useContext=H;
@@ -1,5 +1,5 @@
1
1
 
2
- import { c as ConfigDirectorContext, d as ConfigEvaluation, f as ConfigState, h as EvaluationReason, i as OfflineValues, l as ConfigDirectorLogger, m as ConnectionMode, n as ConfigDirectorClient, p as ConfigValueType, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel } from "./types-CRVL6Yi2.cjs";
2
+ import { b as Variation, c as ConfigDirectorContext, d as ConfigEvaluation, f as ConfigState, g as TrackOptions, h as EvaluationReason, i as OfflineValues, l as ConfigDirectorLogger, m as ConnectionMode, n as ConfigDirectorClient, p as ConfigValueType, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel, v as TrackedEventDetailValue, y as TrackedEventDetails } from "./types-P8frfCGH.cjs";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
  import { Component, PropsWithChildren } from "react";
5
5
 
@@ -220,5 +220,5 @@ declare class ConfigDirectorNextContextError extends Error {
220
220
  constructor(message: string);
221
221
  }
222
222
  //#endregion
223
- export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigEvaluation, type ConfigValueType, type ConnectionMode, type EvaluationReason, type OfflineValue, type OfflineValues, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
223
+ export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigEvaluation, type ConfigValueType, type ConnectionMode, type EvaluationReason, type OfflineValue, type OfflineValues, type TrackOptions, type TrackedEventDetailValue, type TrackedEventDetails, type Variation, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
224
224
  //# sourceMappingURL=index.d.cts.map
@@ -1,5 +1,5 @@
1
1
 
2
- import { c as ConfigDirectorContext, d as ConfigEvaluation, f as ConfigState, h as EvaluationReason, i as OfflineValues, l as ConfigDirectorLogger, m as ConnectionMode, n as ConfigDirectorClient, p as ConfigValueType, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel } from "./types-B4kvU3bh.mjs";
2
+ import { b as Variation, c as ConfigDirectorContext, d as ConfigEvaluation, f as ConfigState, g as TrackOptions, h as EvaluationReason, i as OfflineValues, l as ConfigDirectorLogger, m as ConnectionMode, n as ConfigDirectorClient, p as ConfigValueType, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel, v as TrackedEventDetailValue, y as TrackedEventDetails } from "./types-CdyMdj5l.mjs";
3
3
  import { Component, PropsWithChildren } from "react";
4
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
@@ -220,5 +220,5 @@ declare class ConfigDirectorNextContextError extends Error {
220
220
  constructor(message: string);
221
221
  }
222
222
  //#endregion
223
- export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigEvaluation, type ConfigValueType, type ConnectionMode, type EvaluationReason, type OfflineValue, type OfflineValues, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
223
+ export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigEvaluation, type ConfigValueType, type ConnectionMode, type EvaluationReason, type OfflineValue, type OfflineValues, type TrackOptions, type TrackedEventDetailValue, type TrackedEventDetails, type Variation, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
224
224
  //# sourceMappingURL=index.d.mts.map
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import{a as e,h as t,i as n,l as r,n as i,o as a,r as o,s,u as c}from"./installedTestClient-BqVnonO8.mjs";import l,{Component as u,useContext as d,useEffect as f}from"react";import{jsx as p,jsxs as m}from"react/jsx-runtime";const h=e=>{var t;if(e.type===`json`||e.type==null&&typeof e.value==`object`){if(e.valueId)return{valueId:e.valueId,type:`json`};try{return{value:JSON.stringify(e.value),type:`json`}}catch(t){return{value:e.value.toString(),type:`json`}}}let n=(t=e.value)==null?void 0:t.toString();return n&&n.length<=500?{value:n}:e.valueId?{valueId:e.valueId}:{value:n}};var g=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime!=null||(this.startTime=new Date),this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){var e;let t=new Date,n=(e=this.startTime)==null?t:e,r=(e,r)=>({startTime:n,endTime:t,count:e,event:{reason:`invalid-context-kind`,kindSample:r}}),i=Array.from(this.countsByKindSample,([e,t])=>r(t,e)),a=this.countBeyondSampleLimit>0?[...i,r(this.countBeyondSampleLimit)]:i;return this.clear(),a}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},_=class{constructor(e){var t,n,r,i;this.turnedOff=!1,this.pendingEvaluations=[],this.pendingInvalidContextSubmissions=new g,this.logger=e.logger,this.workerCloseTimeout=(t=e.workerCloseTimeout)==null?6e3:t,this.pendingEvaluationLimit=(n=e.evaluationQueueLimit)==null?1e3:n,this.clientSession=e.clientSession,this.initializeMessage={type:`Initialize`,payload:{sdkKey:e.sdkKey,sdkIdentity:e.sdkIdentity,metaContext:e.metaContext,baseUrl:e.baseUrl.toString(),evaluationQueueLimit:this.pendingEvaluationLimit,initialFlushIntervalDelay:(r=e.initialFlushIntervalDelay)==null?5e3:r,flushIntervalDelay:(i=e.flushIntervalDelay)==null?3e4:i}},this.visibilityHandler=()=>{document.visibilityState===`hidden`&&this.flush()}}createWorkerOrTurnOff(){if(typeof Worker>`u`){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.`);return}try{return new Worker(URL.createObjectURL(new Blob(["(function(){let e=async(e,t)=>e.valueId?{valueId:e.valueId}:e.value?e.value.length<=500&&e.type!=`json`?{value:e.value}:{valueId:await t(e.value)}:e,t=e=>{let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]?.length??0)>0)return!1;return!0},n=e=>{if(!e)return!0;let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]??0)>0)return!1;return!0},r=async(e,t,n,r)=>{let i=new AbortController,a=setTimeout(()=>{r.debug(`[fetchWithTimeout] Reached timeout, aborting request`),i.abort()},e);try{let e=await fetch(typeof t==`string`||t instanceof Request?t:t.toString(),{...n,signal:i.signal});return clearTimeout(a),e}catch(e){throw r.warn(`[fetchWithTimeout] Fetch error: `,e),clearTimeout(a),e}},i=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError;var a=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,this.sdkIdentity=e.sdkIdentity,this.metaContext=e.metaContext,this.url=e.urlFactory(`client/telemetry/v1`,e.baseUrl),this.clientSession=e.clientSession}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let{instanceId:i}=await this.clientSession,a={clientSdkKey:this.sdkKey,instanceId:i,metaContext:{sdkName:this.sdkIdentity.sdkName,sdkVersion:this.sdkIdentity.sdkVersion,appName:this.metaContext.appName,appVersion:this.metaContext.appVersion},context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r};if(this.isReportEmpty(a))return{success:!0,fatalError:!1};let o=await this.sendReport(a);return o.fatalError&&(this.executeRequests=!1),o}isReportEmpty(e){return t(e.discreteEvents)&&t(e.aggregatedEvents)&&n(e.droppedEvents)}async sendReport(e){try{let t=await r(5e3,this.url,{method:`POST`,body:JSON.stringify(e),keepalive:!0},this.logger),n=this.isStatusFatal(t.status);return n&&this.logger.warn(`[EventReporter] Received a fatal status response (${t.status}) from the telemetry endpoint. No more telemetry data will be sent.`),{success:t.ok,fatalError:n}}catch(e){let t=i(e);return this.logger.warn(`[EventReporter] Error attempting to send telemetry data: ${e}`,{error:e}),{success:!1,fatalError:t}}}isStatusFatal(e){return!!e&&e>=400&&e<500&&e!=429}},o=class{aggregate(e){if(e.events.length==0)return[];let t=new Map;for(let n of e.events){let e=JSON.stringify(n),r=t.get(e)?.count||0;t.set(e,{event:n,count:r+1})}return Array.from(t).map(([,t])=>({startTime:e.startTime,endTime:e.endTime,count:t.count,event:t.event}))}},s=class{constructor(e){this._events=[],this._droppedEventCount=0,this.limit=e??1e3}get events(){return this._events}get reachedLimit(){return this._events.length>=this.limit}get droppedEventCount(){return this._droppedEventCount}push(...e){this.startTime||=new Date;let t=Math.max(0,e.length-this.limit),n=e.slice(t,e.length);if(this._droppedEventCount+=t,this._events.length+n.length>this.limit){let e=this._events.length+n.length-this.limit;this._events.splice(0,e),this._droppedEventCount+=e}return this._events.push(...n)}takeSnapshot(){let e=new Date,t=this.startTime??e,n=this._events.splice(0),r=this._droppedEventCount;return this.startTime=void 0,this._droppedEventCount=0,{startTime:t,endTime:e,events:n,droppedCount:r}}clear(){this._events=[],this.startTime=void 0,this._droppedEventCount=0}},c=class{constructor(e){this.aggregator=new o,this.collectEvents=!0,this.started=!1,this.logger=e.logger,this.evaluationEventQueue=new s(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4,this.initialFlushIntervalDelay=e.initialFlushIntervalDelay??5e3}start(){this.started||!this.collectEvents||(this.started=!0,this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.initialFlushIntervalDelay))}async flushAndScheduleNext(){if(!this.collectEvents)return;let e;try{e=await this.flush()}catch(t){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events: `,t),e={success:!1,fatalError:!1}}e.fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.collectEvents&&(this.cancelScheduledFlush(),this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay))}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout);try{await this.flush()}catch(e){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events during close: `,e)}this.evaluationEventQueue.clear()}dispose(){this.close()}},l=class{constructor(e){this.valueIdGenerator=e,this.valueIdGenerator=e}async process(t){let n=await Promise.all(t.events.map(async t=>({...t,defaultValue:await e(t.defaultValue,this.valueIdGenerator),evaluatedValue:await e(t.evaluatedValue,this.valueIdGenerator)})));return{...t,events:n}}},u=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},d=class extends c{constructor(e){super(e),this.invalidContextSubmissions=new u,this.reporter=new a(e),this.evaluationEventSnapshotPreprocessor=new l(e.valueIdGenerator)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}recordInvalidContext(e){this.invalidContextSubmissions.record(e)}absorbInvalidContextSubmissions(e){this.invalidContextSubmissions.absorb(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=await this.evaluationEventSnapshotPreprocessor.process(this.evaluationEventQueue.takeSnapshot());return await this.reporter?.report({context:this._context,discreteEvents:{},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e),invalidContext:this.invalidContextSubmissions.takeSnapshot()},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let f=(e,t)=>new URL(e,t?.toString()),p=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},m=Math.ceil(128/Math.log2(62)),h=new TextEncoder,g=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,h.encode(e?.toString()??``));return p(new Uint8Array(t,0,16),m)},_,v,y=new Promise(e=>{v=e}),b=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),x=e=>{try{self.postMessage(e)}catch{self.postMessage(b(e.payload.level,e.payload.message))}},S={debug:function(e,...t){x(b(`debug`,e,t))},info:function(e,...t){x(b(`info`,e,t))},warn:function(e,...t){x(b(`warn`,e,t))},error:function(e,...t){x(b(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){S.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(S.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){S.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:S,clientSession:y}),_.start();break;case`ClientSession`:v(t.payload);break;case`EvaluatedConfigEvent`:_?.evaluatedConfig(t.payload);break;case`InvalidContextSubmissions`:_?.absorbInvalidContextSubmissions(t.payload.entries);break;case`UpdateContext`:_?.updateContext(t.payload.context);break;case`Flush`:_?.forceFlush();break;case`Close`:(_?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"],{type:`application/javascript`})))}catch(e){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: `,e);return}}turnOff(e,...t){this.turnedOff=!0,this.pendingEvaluations.length=0,this.logger.warn(e,...t)}startWorker(){if(this.worker||this.turnedOff)return this.worker;let e=this.createWorkerOrTurnOff();if(e){e.onmessage=e=>{this.handleWorkerEvent(e.data)},e.postMessage(this.initializeMessage),this.forwardClientSession(e),this.worker=e;try{document.addEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[TelemetryEventCollector] Could not configure 'visibilitychange' listener: `,e)}for(let t of this.pendingEvaluations)e.postMessage(t);return this.pendingEvaluations.length=0,this.forwardInvalidContextSubmissions(e),e}}forwardClientSession(e){this.clientSession.then(t=>{let n={type:`ClientSession`,payload:t};e.postMessage(n)})}forwardInvalidContextSubmissions(e){if(!e)return;let t=this.pendingInvalidContextSubmissions.takeSnapshot();if(t.length===0)return;let n={type:`InvalidContextSubmissions`,payload:{entries:t}};e.postMessage(n)}async updateContext(e){var t=this,n;if(t.closePromise)return;let r={type:`UpdateContext`,payload:{context:e}};(n=t.startWorker())==null||n.postMessage(r)}evaluatedConfig(e){if(this.turnedOff)return;let t={type:`EvaluatedConfigEvent`,payload:this.sanitizeEvaluatedConfigEvent(e)};if(this.worker){this.worker.postMessage(t);return}this.pendingEvaluations.length>=this.pendingEvaluationLimit&&this.pendingEvaluations.shift(),this.pendingEvaluations.push(t)}recordInvalidContext(e){this.pendingInvalidContextSubmissions.record(e),this.forwardInvalidContextSubmissions(this.worker)}sanitizeEvaluatedConfigEvent(e){return t(t({},e),{},{defaultValue:h({value:e.defaultValue,type:e.type}),evaluatedValue:h({value:e.evaluatedValue,valueId:e.evaluatedValueId,type:e.type})})}handleWorkerEvent(e){var t,n;if(e.type===`Closed`){this.finishClose();return}if(!((t=e.payload)!=null&&t.level)||!((n=e.payload)!=null&&n.message))return;let{level:r,message:i,args:a}=e.payload;switch(r){case`debug`:this.logger.debug(i,...a);break;case`info`:this.logger.info(i,...a);break;case`warn`:this.logger.warn(i,...a);break;case`error`:this.logger.error(i,...a);break}}flush(){var e;(e=this.worker)==null||e.postMessage({type:`Flush`})}close(){return this.closePromise?this.closePromise:this.performClose()}performClose(){let e=this.worker;if(!e)return this.pendingEvaluations.length=0,this.closePromise=Promise.resolve(),this.closePromise;try{document.removeEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: `,e)}return this.closePromise=new Promise(t=>{this.closeResolve=t,this.closeTimer=setTimeout(()=>{this.logger.warn(`[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.`),this.finishClose()},this.workerCloseTimeout),e.postMessage({type:`Close`})}),this.closePromise}finishClose(){var e,t;clearTimeout(this.closeTimer),this.closeTimer=void 0,(e=this.worker)==null||e.terminate(),(t=this.closeResolve)==null||t.call(this)}};const v=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},y=Math.ceil(128/Math.log2(62)),b=new TextEncoder,x=async e=>{var t;if(typeof crypto>`u`||crypto.subtle==null)return;let n=await crypto.subtle.digest(`SHA-256`,b.encode((t=e==null?void 0:e.toString())==null?``:t));return v(new Uint8Array(n,0,16),y)},S=t=>{let r=a();if(!r)return;let i=t.then(e=>n+e);return{read:async()=>r.getItem(await i),write:async e=>r.setItem(await i,e),remove:async()=>r.removeItem(await i),sizeLimit:()=>e}},C=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),w=()=>{if(!(typeof crypto>`u`||crypto.subtle==null))return async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return C(new Uint8Array(t))}},T=(e,t,n)=>o.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i,clientSession:a})=>new _({sdkKey:e,sdkIdentity:{sdkName:t.sdkName,sdkVersion:t.sdkVersion},metaContext:{appName:i==null?void 0:i.appName,appVersion:i==null?void 0:i.appVersion},logger:r,baseUrl:n,urlFactory:s,valueIdGenerator:x,clientSession:a}),e,t,n,{sha256HexDigest:w(),platformCachingProvider:S});var E=class{constructor(e){this.client=e,this.registrations=[]}on(e,t){this.client.on(e,t),this.registrations.push({event:e,handler:t})}registerHooks(e){for(let[t,n]of Object.entries(e==null?{}:e)){let e=Array.isArray(n)?n:[n];for(let n of e)typeof n==`function`&&this.on(t,n)}}removeAll(){for(let{event:e,handler:t}of this.registrations)this.client.off(e,t);this.registrations=[]}};const D=(e,t)=>{if(Object.is(e,t))return!0;if(typeof e!=`object`||typeof t!=`object`||e===null||t===null||Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>D(e,t[n]));if(!O(e)||!O(t))return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&D(e[n],t[n]))},O=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},k=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!D(t,e.context)?`updateContext`:`none`:`initialize`,A=(e,t,n)=>{let r=k(e,t);return n&&r===`initialize`&&t===void 0?`waitForContext`:r},j={waitForContext:`waitingForContext`,initialize:`started`,updateContext:`started`,none:`started`},M=(e,t)=>({kind:j[e],client:t}),N=(e,t,n)=>{if(D(n,t))return{action:`skipUnchanged`};switch(e.kind){case`beforeFirstRenderEffects`:return{action:`keepForStartup`};case`waitingForContext`:return{action:`startClient`,client:e.client};case`started`:return{action:`updateContext`,client:e.client}}},P=l.createContext({status:`loading`,updateContext:async()=>{}});var F=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const I=e=>r(e,new F),L=e=>`client`in e&&e.client!==void 0,R=e=>e.isReady?`ready`:`default`,z=(e,t)=>{let n=t&&!L(e)&&e.mode===`offline`;return e.deferInitialization===!0&&!n},B=({run:e})=>(f(()=>{e()},[e]),null);var V=class extends u{constructor(e){var t;super(e),t=this,this.startupPhase={kind:`beforeFirstRenderEffects`},this.startAfterFirstRenderEffects=()=>{let e=this.client;e&&this.startClient(e,this.lastGivenContext)},this.receiveContext=async e=>{let n=N(t.startupPhase,t.lastGivenContext,e);switch(n.action){case`skipUnchanged`:return;case`keepForStartup`:t.lastGivenContext=e;return;case`startClient`:t.lastGivenContext=e,await t.startClient(n.client,e);return;case`updateContext`:t.lastGivenContext=e,await t.updateClientContext(n.client,e==null?{}:e);return}};let n=L(e)?e.client:i();this.ownsClient=n===void 0,this.waitsForFirstContext=z(e,this.ownsClient),this.client=n,this.lastGivenContext=e.context,this.state=n?{client:n,status:n.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){var e;let t=this.props;return T(t.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.13.1`},{connection:{url:t.url,timeout:t.timeout,mode:t.mode,pollingInterval:t.pollingInterval,values:t.values},metadata:{appName:t.appName,appVersion:t.appVersion},logger:I((e=t.logLevel)==null?`warn`:e),hooks:t.hooks})}componentDidMount(){let e=this.client;this.ownsClient&&(e=this.buildClient(),this.client=e,this.setState({client:e})),e&&(this.handlers=new E(e),this.handlers.on(`configsUpdated`,()=>{this.setState({updatedAt:new Date})}),this.handlers.on(`clientReady`,()=>{this.setState({status:`ready`})}),this.ownsClient||this.handlers.registerHooks(this.props.hooks))}async startClient(e,t){var n=this;let r=A(e,t,n.waitsForFirstContext);switch(n.startupPhase=M(r,e),r){case`waitForContext`:return;case`initialize`:await e.initialize(t),n.settleStatus(e);return;case`updateContext`:await n.updateClientContext(e,t);return;case`none`:return}}async updateClientContext(e,t){var n=this;n.setState({status:`loading`}),await e.updateContext(t),n.settleStatus(e)}settleStatus(e){this.client===e&&this.setState({status:R(e)})}async componentDidUpdate(e){var t=this;L(e)&&L(t.props)&&e.client!==t.props.client&&I(`warn`).warn(`The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.`),D(e.context,t.props.context)||await t.receiveContext(t.props.context)}componentWillUnmount(){var e;if((e=this.handlers)==null||e.removeAll(),this.handlers=void 0,this.startupPhase={kind:`beforeFirstRenderEffects`},this.lastGivenContext=this.props.context,this.ownsClient){var t;(t=this.client)==null||t.dispose(),this.client=void 0}}render(){return m(P.Provider,{value:t(t({},this.state),{},{initialConfigs:this.props.initialConfigs,updateContext:this.receiveContext}),children:[this.props.children,p(B,{run:this.startAfterFirstRenderEffects})]})}},H=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const U=()=>new H(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),W=(e,t)=>{var n,r;let i=d(P);if(!i)throw U();let a=(n=i.initialConfigs)==null?void 0:n[e];return{value:(r=i.client)!=null&&r.isReady?i.client.getValue(e,t):a?c(a,t).parsedValue:t,readyStatus:i.status,loading:i.status===`loading`}},G=()=>{let e=d(P);if(!e)throw U();return{updateContext:e.updateContext}},K=()=>{let e=d(P);if(!(e!=null&&e.client))throw U();return{client:e.client}},q=()=>{let e=d(P);if(!e)throw U();return{readyStatus:e.status,loading:e.status===`loading`}};export{H as ConfigDirectorNextContextError,V as ConfigDirectorProvider,I as createConsoleLogger,K as useClient,q as useConfigDirectorStatus,W as useConfigValue,G as useContext};
2
+ import{a as e,g as t,i as n,l as r,n as i,o as a,r as o,s,u as c,v as l}from"./installedTestClient-CL4AQC58.mjs";import u,{Component as d,useContext as f,useEffect as p}from"react";import{jsx as m,jsxs as h}from"react/jsx-runtime";const g=e=>{var t;if(e.type===`json`||e.type==null&&typeof e.value==`object`){if(e.valueId)return{valueId:e.valueId,type:`json`};try{return{value:JSON.stringify(e.value),type:`json`}}catch(t){return{value:e.value.toString(),type:`json`}}}let n=(t=e.value)==null?void 0:t.toString();return n&&n.length<=500?{value:n}:e.valueId?{valueId:e.valueId}:{value:n}};var _=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime!=null||(this.startTime=new Date),this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){var e;let t=new Date,n=(e=this.startTime)==null?t:e,r=(e,r)=>({startTime:n,endTime:t,count:e,event:{reason:`invalid-context-kind`,kindSample:r}}),i=Array.from(this.countsByKindSample,([e,t])=>r(t,e)),a=this.countBeyondSampleLimit>0?[...i,r(this.countBeyondSampleLimit)]:i;return this.clear(),a}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},v=class{constructor(){this.entries=[],this.warningsRaisedThisBatch=new Set}add(e){return this.warningsOfKeeping(e).filter(e=>this.isFirstThisBatch(e))}absorb(e){this.entries.push(...e)}takeBatch(){let e=this.entries;return this.clear(),e}clear(){this.entries=[],this.warningsRaisedThisBatch.clear()}warningsOfKeeping(e){switch(e.outcome){case`dropped`:return e.warnings;case`admitted`:return this.entries.length>=1e3?[`batch-already-full`]:(this.entries.push(e.entry),e.warnings)}}isFirstThisBatch(e){return this.warningsRaisedThisBatch.has(e)?!1:(this.warningsRaisedThisBatch.add(e),!0)}},y=class{constructor(e){var t,n,r,i;this.turnedOff=!1,this.pendingEvaluations=[],this.pendingInvalidContextSubmissions=new _,this.pendingTrackedEvents=new v,this.logger=e.logger,this.workerCloseTimeout=(t=e.workerCloseTimeout)==null?6e3:t,this.pendingEvaluationLimit=(n=e.evaluationQueueLimit)==null?1e3:n,this.clientSession=e.clientSession,this.initializeMessage={type:`Initialize`,payload:{sdkKey:e.sdkKey,sdkIdentity:e.sdkIdentity,metaContext:e.metaContext,baseUrl:e.baseUrl.toString(),evaluationQueueLimit:this.pendingEvaluationLimit,initialFlushIntervalDelay:(r=e.initialFlushIntervalDelay)==null?5e3:r,flushIntervalDelay:(i=e.flushIntervalDelay)==null?3e4:i}},this.visibilityHandler=()=>{document.visibilityState===`hidden`&&this.flush()}}createWorkerOrTurnOff(){if(typeof Worker>`u`){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.`);return}try{return new Worker(URL.createObjectURL(new Blob(['(function(){let e=async(e,t)=>e.valueId?{valueId:e.valueId}:e.value?e.value.length<=500&&e.type!=`json`?{value:e.value}:{valueId:await t(e.value)}:e,t=e=>{let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]?.length??0)>0)return!1;return!0},n=e=>{if(!e)return!0;let t=Object.keys(e);if(t.length==0)return!0;for(let n of t)if((e[n]??0)>0)return!1;return!0},r=async(e,t,n,r)=>{let i=new AbortController,a=setTimeout(()=>{r.debug(`[fetchWithTimeout] Reached timeout, aborting request`),i.abort()},e);try{let e=await fetch(typeof t==`string`||t instanceof Request?t:t.toString(),{...n,signal:i.signal});return clearTimeout(a),e}catch(e){throw r.warn(`[fetchWithTimeout] Fetch error: `,e),clearTimeout(a),e}},i=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError,a=e=>e>=55296&&e<=56319,o=e=>e>=56320&&e<=57343,s=e=>{let t=0;for(let n=0;n<e.length;n++){let r=e.charCodeAt(n);r<=127?t+=1:r<=2047?t+=2:a(r)&&n+1<e.length&&o(e.charCodeAt(n+1))?(t+=4,n++):t+=3}return t};var c=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,this.sdkIdentity=e.sdkIdentity,this.metaContext=e.metaContext,this.url=e.urlFactory(`client/telemetry/v1`,e.baseUrl),this.clientSession=e.clientSession}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let{instanceId:i}=await this.clientSession,a={clientSdkKey:this.sdkKey,instanceId:i,metaContext:{sdkName:this.sdkIdentity.sdkName,sdkVersion:this.sdkIdentity.sdkVersion,appName:this.metaContext.appName,appVersion:this.metaContext.appVersion},context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r};if(this.isReportEmpty(a))return{success:!0,fatalError:!1};let o=await this.sendReport(a);return o.fatalError&&(this.executeRequests=!1),o}isReportEmpty(e){return t(e.discreteEvents)&&t(e.aggregatedEvents)&&n(e.droppedEvents)}async sendReport(e){try{let t=JSON.stringify(e),n=await r(5e3,this.url,{method:`POST`,body:t,keepalive:s(t)<=32768},this.logger),i=this.isStatusFatal(n.status);return i&&this.logger.warn(`[EventReporter] Received a fatal status response (${n.status}) from the telemetry endpoint. No more telemetry data will be sent.`),{success:n.ok,fatalError:i}}catch(e){let t=i(e);return this.logger.warn(`[EventReporter] Error attempting to send telemetry data: ${e}`,{error:e}),{success:!1,fatalError:t}}}isStatusFatal(e){return!!e&&e>=400&&e<500&&e!=429}},l=class{aggregate(e){if(e.events.length==0)return[];let t=new Map;for(let n of e.events){let e=JSON.stringify(n),r=t.get(e)?.count||0;t.set(e,{event:n,count:r+1})}return Array.from(t).map(([,t])=>({startTime:e.startTime,endTime:e.endTime,count:t.count,event:t.event}))}},u=class{constructor(e){this._events=[],this._droppedEventCount=0,this.limit=e??1e3}get events(){return this._events}get reachedLimit(){return this._events.length>=this.limit}get droppedEventCount(){return this._droppedEventCount}push(...e){this.startTime||=new Date;let t=Math.max(0,e.length-this.limit),n=e.slice(t,e.length);if(this._droppedEventCount+=t,this._events.length+n.length>this.limit){let e=this._events.length+n.length-this.limit;this._events.splice(0,e),this._droppedEventCount+=e}return this._events.push(...n)}takeSnapshot(){let e=new Date,t=this.startTime??e,n=this._events.splice(0),r=this._droppedEventCount;return this.startTime=void 0,this._droppedEventCount=0,{startTime:t,endTime:e,events:n,droppedCount:r}}clear(){this._events=[],this.startTime=void 0,this._droppedEventCount=0}};let d={"name-outside-the-character-limit":`[ConfigDirectorClient] A tracked event was not reported because its name does not have 1 to 150 characters.`,"value-not-a-finite-number":`[ConfigDirectorClient] A tracked event was reported without its value because the value is not a finite number.`,"details-not-reportable":`[ConfigDirectorClient] A tracked event was reported without its details because they are not an object, have more than 20 top-level keys, are larger than 1024 bytes as JSON, or cannot be written as JSON.`,"batch-already-full":`[ConfigDirectorClient] A tracked event was not reported because 1000 tracked events are already waiting for the next telemetry batch.`},f=(e,t)=>{for(let n of t)e.warn(`${d[n]} Further tracked events like it are not logged until the next telemetry batch is sent.`)};var p=class{constructor(){this.entries=[],this.warningsRaisedThisBatch=new Set}add(e){return this.warningsOfKeeping(e).filter(e=>this.isFirstThisBatch(e))}absorb(e){this.entries.push(...e)}takeBatch(){let e=this.entries;return this.clear(),e}clear(){this.entries=[],this.warningsRaisedThisBatch.clear()}warningsOfKeeping(e){switch(e.outcome){case`dropped`:return e.warnings;case`admitted`:return this.entries.length>=1e3?[`batch-already-full`]:(this.entries.push(e.entry),e.warnings)}}isFirstThisBatch(e){return this.warningsRaisedThisBatch.has(e)?!1:(this.warningsRaisedThisBatch.add(e),!0)}},m=class{constructor(e){this.aggregator=new l,this.trackedEventQueue=new p,this.collectEvents=!0,this.started=!1,this.logger=e.logger,this.evaluationEventQueue=new u(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4,this.initialFlushIntervalDelay=e.initialFlushIntervalDelay??5e3}start(){this.started||!this.collectEvents||(this.started=!0,this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.initialFlushIntervalDelay))}trackedEvent(e){this.collectEvents&&f(this.logger,this.trackedEventQueue.add(e))}async flushAndScheduleNext(){if(!this.collectEvents)return;let e;try{e=await this.flush()}catch(t){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events: `,t),e={success:!1,fatalError:!1}}e.fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.collectEvents&&(this.cancelScheduledFlush(),this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay))}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout);try{await this.flush()}catch(e){this.logger.warn(`[TelemetryEventCollector] Error flushing telemetry events during close: `,e)}this.evaluationEventQueue.clear(),this.trackedEventQueue.clear()}dispose(){this.close()}},h=class{constructor(e){this.valueIdGenerator=e,this.valueIdGenerator=e}async process(t){let n=await Promise.all(t.events.map(async t=>({...t,defaultValue:await e(t.defaultValue,this.valueIdGenerator),evaluatedValue:await e(t.evaluatedValue,this.valueIdGenerator)})));return{...t,events:n}}},g=class{constructor(){this.countsByKindSample=new Map,this.countBeyondSampleLimit=0}record(e){return this.startTime??=new Date,this.add(e,1)}absorb(e){for(let t of e)(this.startTime===void 0||t.startTime<this.startTime)&&(this.startTime=t.startTime),this.add(t.event.kindSample,t.count)}add(e,t){if(e!==void 0){let n=this.countsByKindSample.get(e);if(n!==void 0)return this.countsByKindSample.set(e,n+t),`known-kind-sample`;if(this.countsByKindSample.size<20)return this.countsByKindSample.set(e,t),`new-kind-sample`}let n=this.countBeyondSampleLimit===0;return this.countBeyondSampleLimit+=t,n?`first-beyond-sample-limit`:`beyond-sample-limit`}takeSnapshot(){let e=new Date,t=this.startTime??e,n=(n,r)=>({startTime:t,endTime:e,count:n,event:{reason:`invalid-context-kind`,kindSample:r}}),r=Array.from(this.countsByKindSample,([e,t])=>n(t,e)),i=this.countBeyondSampleLimit>0?[...r,n(this.countBeyondSampleLimit)]:r;return this.clear(),i}clear(){this.countsByKindSample.clear(),this.countBeyondSampleLimit=0,this.startTime=void 0}},_=class extends m{constructor(e){super(e),this.invalidContextSubmissions=new g,this.reporter=new c(e),this.evaluationEventSnapshotPreprocessor=new h(e.valueIdGenerator)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}recordInvalidContext(e){this.invalidContextSubmissions.record(e)}absorbInvalidContextSubmissions(e){this.invalidContextSubmissions.absorb(e)}absorbTrackedEventEntries(e){this.trackedEventQueue.absorb(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=await this.evaluationEventSnapshotPreprocessor.process(this.evaluationEventQueue.takeSnapshot());return await this.reporter?.report({context:this._context,discreteEvents:{trackedEvents:this.trackedEventQueue.takeBatch()},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e),invalidContext:this.invalidContextSubmissions.takeSnapshot()},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let v=(e,t)=>new URL(e,t?.toString()),y=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},b=Math.ceil(128/Math.log2(62)),x=new TextEncoder,S=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,x.encode(e?.toString()??``));return y(new Uint8Array(t,0,16),b)},C,w,T=new Promise(e=>{w=e}),E=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),D=e=>{try{self.postMessage(e)}catch{self.postMessage(E(e.payload.level,e.payload.message))}},O={debug:function(e,...t){D(E(`debug`,e,t))},info:function(e,...t){D(E(`info`,e,t))},warn:function(e,...t){D(E(`warn`,e,t))},error:function(e,...t){D(E(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!C){O.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(O.debug(`[TelemetryWorker] Received \'${t.type}\' event:`,t),t.type){case`Initialize`:if(C){O.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}C=new _({...t.payload,baseUrl:v(t.payload.baseUrl),urlFactory:v,valueIdGenerator:S,logger:O,clientSession:T}),C.start();break;case`ClientSession`:w(t.payload);break;case`EvaluatedConfigEvent`:C?.evaluatedConfig(t.payload);break;case`InvalidContextSubmissions`:C?.absorbInvalidContextSubmissions(t.payload.entries);break;case`TrackedEvent`:C?.trackedEvent(t.payload);break;case`TrackedEventEntries`:C?.absorbTrackedEventEntries(t.payload.entries);break;case`UpdateContext`:C?.updateContext(t.payload.context);break;case`Flush`:C?.forceFlush();break;case`Close`:(C?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();'],{type:`application/javascript`})))}catch(e){this.turnOff(`[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: `,e);return}}turnOff(e,...t){this.turnedOff=!0,this.pendingEvaluations.length=0,this.pendingTrackedEvents.clear(),this.logger.warn(e,...t)}startWorker(){if(this.worker||this.turnedOff)return this.worker;let e=this.createWorkerOrTurnOff();if(e){e.onmessage=e=>{this.handleWorkerEvent(e.data)},e.postMessage(this.initializeMessage),this.forwardClientSession(e),this.worker=e;try{document.addEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[TelemetryEventCollector] Could not configure 'visibilitychange' listener: `,e)}for(let t of this.pendingEvaluations)e.postMessage(t);return this.pendingEvaluations.length=0,this.forwardInvalidContextSubmissions(e),this.forwardPendingTrackedEvents(e),e}}forwardPendingTrackedEvents(e){let t=this.pendingTrackedEvents.takeBatch();if(t.length===0)return;let n={type:`TrackedEventEntries`,payload:{entries:t}};e.postMessage(n)}forwardClientSession(e){this.clientSession.then(t=>{let n={type:`ClientSession`,payload:t};e.postMessage(n)})}forwardInvalidContextSubmissions(e){if(!e)return;let t=this.pendingInvalidContextSubmissions.takeSnapshot();if(t.length===0)return;let n={type:`InvalidContextSubmissions`,payload:{entries:t}};e.postMessage(n)}async updateContext(e){var t=this,n;if(t.closePromise)return;let r={type:`UpdateContext`,payload:{context:e}};(n=t.startWorker())==null||n.postMessage(r)}evaluatedConfig(e){if(this.turnedOff)return;let t={type:`EvaluatedConfigEvent`,payload:this.sanitizeEvaluatedConfigEvent(e)};if(this.worker){this.worker.postMessage(t);return}this.pendingEvaluations.length>=this.pendingEvaluationLimit&&this.pendingEvaluations.shift(),this.pendingEvaluations.push(t)}recordInvalidContext(e){this.pendingInvalidContextSubmissions.record(e),this.forwardInvalidContextSubmissions(this.worker)}trackedEvent(e){if(!(this.turnedOff||this.closePromise)){if(this.worker){let t={type:`TrackedEvent`,payload:e};this.worker.postMessage(t);return}t(this.logger,this.pendingTrackedEvents.add(e))}}sanitizeEvaluatedConfigEvent(e){return l(l({},e),{},{defaultValue:g({value:e.defaultValue,type:e.type}),evaluatedValue:g({value:e.evaluatedValue,valueId:e.evaluatedValueId,type:e.type})})}handleWorkerEvent(e){var t,n;if(e.type===`Closed`){this.finishClose();return}if(!((t=e.payload)!=null&&t.level)||!((n=e.payload)!=null&&n.message))return;let{level:r,message:i,args:a}=e.payload;switch(r){case`debug`:this.logger.debug(i,...a);break;case`info`:this.logger.info(i,...a);break;case`warn`:this.logger.warn(i,...a);break;case`error`:this.logger.error(i,...a);break}}flush(){var e;(e=this.worker)==null||e.postMessage({type:`Flush`})}close(){return this.closePromise?this.closePromise:this.performClose()}performClose(){let e=this.worker;if(!e)return this.pendingEvaluations.length=0,this.pendingTrackedEvents.clear(),this.closePromise=Promise.resolve(),this.closePromise;try{document.removeEventListener(`visibilitychange`,this.visibilityHandler)}catch(e){this.logger.warn(`[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: `,e)}return this.closePromise=new Promise(t=>{this.closeResolve=t,this.closeTimer=setTimeout(()=>{this.logger.warn(`[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.`),this.finishClose()},this.workerCloseTimeout),e.postMessage({type:`Close`})}),this.closePromise}finishClose(){var e,t;clearTimeout(this.closeTimer),this.closeTimer=void 0,(e=this.worker)==null||e.terminate(),(t=this.closeResolve)==null||t.call(this)}};const b=(e,t)=>{let n=BigInt(0),r=BigInt(62),i=Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``),a=BigInt(`0x`+i),o=``;for(;a>n;)o=`0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`[Number(a%r)]+o,a/=r;return o.padStart(t,`0`)},x=Math.ceil(128/Math.log2(62)),S=new TextEncoder,C=async e=>{var t;if(typeof crypto>`u`||crypto.subtle==null)return;let n=await crypto.subtle.digest(`SHA-256`,S.encode((t=e==null?void 0:e.toString())==null?``:t));return b(new Uint8Array(n,0,16),x)},w=t=>{let r=a();if(!r)return;let i=t.then(e=>n+e);return{read:async()=>r.getItem(await i),write:async e=>r.setItem(await i,e),remove:async()=>r.removeItem(await i),sizeLimit:()=>e}},T=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),E=()=>{if(!(typeof crypto>`u`||crypto.subtle==null))return async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return T(new Uint8Array(t))}},D=(e,t,n)=>o.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i,clientSession:a})=>new y({sdkKey:e,sdkIdentity:{sdkName:t.sdkName,sdkVersion:t.sdkVersion},metaContext:{appName:i==null?void 0:i.appName,appVersion:i==null?void 0:i.appVersion},logger:r,baseUrl:n,urlFactory:s,valueIdGenerator:C,clientSession:a}),e,t,n,{sha256HexDigest:E(),platformCachingProvider:w});var O=class{constructor(e){this.client=e,this.registrations=[]}on(e,t){this.client.on(e,t),this.registrations.push({event:e,handler:t})}registerHooks(e){for(let[t,n]of Object.entries(e==null?{}:e)){let e=Array.isArray(n)?n:[n];for(let n of e)typeof n==`function`&&this.on(t,n)}}removeAll(){for(let{event:e,handler:t}of this.registrations)this.client.off(e,t);this.registrations=[]}};const k=(e,t)=>{if(Object.is(e,t))return!0;if(typeof e!=`object`||typeof t!=`object`||e===null||t===null||Object.getPrototypeOf(e)!==Object.getPrototypeOf(t))return!1;if(e instanceof Date&&t instanceof Date)return e.getTime()===t.getTime();if(Array.isArray(e)&&Array.isArray(t))return e.length===t.length&&e.every((e,n)=>k(e,t[n]));if(!A(e)||!A(t))return!1;let n=Object.keys(e),r=Object.keys(t);return n.length===r.length&&n.every(n=>Object.prototype.hasOwnProperty.call(t,n)&&k(e[n],t[n]))},A=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},j=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!k(t,e.context)?`updateContext`:`none`:`initialize`,M=(e,t,n)=>{let r=j(e,t);return n&&r===`initialize`&&t===void 0?`waitForContext`:r},N={waitForContext:`waitingForContext`,initialize:`started`,updateContext:`started`,none:`started`},P=(e,t)=>({kind:N[e],client:t}),F=(e,t,n)=>{if(k(n,t))return{action:`skipUnchanged`};switch(e.kind){case`beforeFirstRenderEffects`:return{action:`keepForStartup`};case`waitingForContext`:return{action:`startClient`,client:e.client};case`started`:return{action:`updateContext`,client:e.client}}},I=u.createContext({status:`loading`,updateContext:async()=>{}});var L=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const R=e=>r(e,new L),z=e=>`client`in e&&e.client!==void 0,B=e=>e.isReady?`ready`:`default`,V=(e,t)=>{let n=t&&!z(e)&&e.mode===`offline`;return e.deferInitialization===!0&&!n},H=({run:e})=>(p(()=>{e()},[e]),null);var U=class extends d{constructor(e){var t;super(e),t=this,this.startupPhase={kind:`beforeFirstRenderEffects`},this.startAfterFirstRenderEffects=()=>{let e=this.client;e&&this.startClient(e,this.lastGivenContext)},this.receiveContext=async e=>{let n=F(t.startupPhase,t.lastGivenContext,e);switch(n.action){case`skipUnchanged`:return;case`keepForStartup`:t.lastGivenContext=e;return;case`startClient`:t.lastGivenContext=e,await t.startClient(n.client,e);return;case`updateContext`:t.lastGivenContext=e,await t.updateClientContext(n.client,e==null?{}:e);return}};let n=z(e)?e.client:i();this.ownsClient=n===void 0,this.waitsForFirstContext=V(e,this.ownsClient),this.client=n,this.lastGivenContext=e.context,this.state=n?{client:n,status:n.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){var e;let t=this.props;return D(t.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.14.0`},{connection:{url:t.url,timeout:t.timeout,mode:t.mode,pollingInterval:t.pollingInterval,values:t.values},metadata:{appName:t.appName,appVersion:t.appVersion},logger:R((e=t.logLevel)==null?`warn`:e),hooks:t.hooks})}componentDidMount(){let e=this.client;this.ownsClient&&(e=this.buildClient(),this.client=e,this.setState({client:e})),e&&(this.handlers=new O(e),this.handlers.on(`configsUpdated`,()=>{this.setState({updatedAt:new Date})}),this.handlers.on(`clientReady`,()=>{this.setState({status:`ready`})}),this.ownsClient||this.handlers.registerHooks(this.props.hooks))}async startClient(e,t){var n=this;let r=M(e,t,n.waitsForFirstContext);switch(n.startupPhase=P(r,e),r){case`waitForContext`:return;case`initialize`:await e.initialize(t),n.settleStatus(e);return;case`updateContext`:await n.updateClientContext(e,t);return;case`none`:return}}async updateClientContext(e,t){var n=this;n.setState({status:`loading`}),await e.updateContext(t),n.settleStatus(e)}settleStatus(e){this.client===e&&this.setState({status:B(e)})}async componentDidUpdate(e){var t=this;z(e)&&z(t.props)&&e.client!==t.props.client&&R(`warn`).warn(`The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.`),k(e.context,t.props.context)||await t.receiveContext(t.props.context)}componentWillUnmount(){var e;if((e=this.handlers)==null||e.removeAll(),this.handlers=void 0,this.startupPhase={kind:`beforeFirstRenderEffects`},this.lastGivenContext=this.props.context,this.ownsClient){var t;(t=this.client)==null||t.dispose(),this.client=void 0}}render(){return h(I.Provider,{value:l(l({},this.state),{},{initialConfigs:this.props.initialConfigs,updateContext:this.receiveContext}),children:[this.props.children,m(H,{run:this.startAfterFirstRenderEffects})]})}},W=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const G=()=>new W(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),K=(e,t)=>{var n,r;let i=f(I);if(!i)throw G();let a=(n=i.initialConfigs)==null?void 0:n[e];return{value:(r=i.client)!=null&&r.isReady?i.client.getValue(e,t):a?c(a,t).parsedValue:t,readyStatus:i.status,loading:i.status===`loading`}},q=()=>{let e=f(I);if(!e)throw G();return{updateContext:e.updateContext}},J=()=>{let e=f(I);if(!(e!=null&&e.client))throw G();return{client:e.client}},Y=()=>{let e=f(I);if(!e)throw G();return{readyStatus:e.status,loading:e.status===`loading`}};export{W as ConfigDirectorNextContextError,U as ConfigDirectorProvider,R as createConsoleLogger,J as useClient,Y as useConfigDirectorStatus,K as useConfigValue,q as useContext};
3
3
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["createJsSdkLogger","useReactContext"],"sources":["../../../shared/src/telemetry/utils.ts","../../../shared/src/telemetry/InvalidContextSubmissions.ts","../../../js-browser-client/src/telemetry/WebWorkerTelemetryClient.ts","../../../shared/src/base62-encoder.ts","../../../shared/src/value-id.ts","../../../js-browser-client/src/telemetry/value-id-generator.ts","../../../js-browser-client/src/local-storage-caching-provider.ts","../../../js-browser-client/src/sha256-hex-digest.ts","../../../js-browser-client/src/BrowserConfigDirectorClient.ts","../../../js-client-core/src/clientHandlers.ts","../../../shared/src/deepEqual.ts","../../../js-client-core/src/mountAction.ts","../../src/client/client-startup.ts","../../src/client/context.tsx","../../src/client/logger.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/errors.ts","../../src/client/hooks.tsx"],"sourcesContent":["import type { ConfigType, ConfigValueType } from \"../types\";\nimport type { ValueIdGenerator, DroppedEvents } from \"./types\";\n\nconst CONFIG_VALUE_MAX_LENGTH = 500;\n\nexport type TelemetryValue = {\n value?: string;\n valueId?: string;\n type?: ConfigType;\n};\n\nexport type TelemetryEvaluationValue<TV extends ConfigValueType> = {\n value: TV;\n valueId?: string | null | undefined;\n type?: ConfigType;\n};\n\nexport const compactTelemetryValue = async (\n tv: TelemetryValue,\n valueIdGenerator: ValueIdGenerator,\n): Promise<TelemetryValue> => {\n if (tv.valueId) {\n return { valueId: tv.valueId };\n }\n if (tv.value) {\n if (tv.value.length <= CONFIG_VALUE_MAX_LENGTH && tv.type != \"json\") {\n return { value: tv.value };\n }\n\n return { valueId: await valueIdGenerator(tv.value) };\n }\n\n return tv;\n};\n\nexport const mapToTelemetryValue = <TV extends ConfigValueType>(\n ev: TelemetryEvaluationValue<TV>,\n): TelemetryValue => {\n if (ev.type === \"json\" || (ev.type == null && typeof ev.value === \"object\")) {\n if (ev.valueId) {\n return { valueId: ev.valueId, type: \"json\" };\n }\n try {\n const json = JSON.stringify(ev.value);\n return { value: json, type: \"json\" };\n } catch {\n return { value: ev.value.toString(), type: \"json\" };\n }\n }\n\n const stringValue = ev.value?.toString();\n if (stringValue && stringValue.length <= CONFIG_VALUE_MAX_LENGTH) {\n return { value: stringValue };\n }\n\n return ev.valueId ? { valueId: ev.valueId } : { value: stringValue };\n};\n\nexport const djb2Hash = (data: string): string => {\n const hash = djb2(new TextEncoder().encode(data));\n return hash.toString(16).padStart(8, \"0\");\n};\n\nconst djb2 = (bytes: Uint8Array): number => {\n let hash = 5381;\n for (let i = 0; i < bytes.length; i++) {\n hash = (hash << 5) + hash + (bytes[i] ?? 0);\n hash = hash >>> 0;\n }\n return hash;\n};\n\nexport const isEventListEmpty = <T extends Record<string | symbol, any[]>>(eventList: T): boolean => {\n const keys = Object.keys(eventList);\n if (keys.length == 0) {\n return true;\n }\n\n for (const key of keys) {\n if ((eventList[key]?.length ?? 0) > 0) {\n return false;\n }\n }\n\n return true;\n};\n\nexport const isDroppedEventsEmpty = (droppedEvents?: DroppedEvents): boolean => {\n if (!droppedEvents) {\n return true;\n }\n const keys = Object.keys(droppedEvents);\n if (keys.length == 0) {\n return true;\n }\n\n for (const key of keys) {\n if ((droppedEvents[key] ?? 0) > 0) {\n return false;\n }\n }\n\n return true;\n};\n","import type { InvalidContextEvent } from \"./telemetry-events\";\nimport type { AggregatedEvent } from \"./types\";\n\nexport const DISTINCT_KIND_SAMPLE_LIMIT = 20;\n\nexport type InvalidContextRecording =\n | \"new-kind-sample\"\n | \"known-kind-sample\"\n | \"first-beyond-sample-limit\"\n | \"beyond-sample-limit\";\n\nexport class InvalidContextSubmissions {\n private readonly countsByKindSample = new Map<string, number>();\n private countBeyondSampleLimit = 0;\n private startTime: Date | undefined;\n\n public record(kindSample: string): InvalidContextRecording {\n this.startTime ??= new Date();\n return this.add(kindSample, 1);\n }\n\n public absorb(entries: AggregatedEvent<InvalidContextEvent>[]): void {\n for (const entry of entries) {\n if (this.startTime === undefined || entry.startTime < this.startTime) {\n this.startTime = entry.startTime;\n }\n this.add(entry.event.kindSample, entry.count);\n }\n }\n\n private add(kindSample: string | undefined, count: number): InvalidContextRecording {\n if (kindSample !== undefined) {\n const knownCount = this.countsByKindSample.get(kindSample);\n if (knownCount !== undefined) {\n this.countsByKindSample.set(kindSample, knownCount + count);\n return \"known-kind-sample\";\n }\n if (this.countsByKindSample.size < DISTINCT_KIND_SAMPLE_LIMIT) {\n this.countsByKindSample.set(kindSample, count);\n return \"new-kind-sample\";\n }\n }\n const firstBeyondSampleLimit = this.countBeyondSampleLimit === 0;\n this.countBeyondSampleLimit += count;\n return firstBeyondSampleLimit ? \"first-beyond-sample-limit\" : \"beyond-sample-limit\";\n }\n\n public takeSnapshot(): AggregatedEvent<InvalidContextEvent>[] {\n const endTime = new Date();\n const startTime = this.startTime ?? endTime;\n const entryOf = (count: number, kindSample?: string): AggregatedEvent<InvalidContextEvent> => ({\n startTime,\n endTime,\n count,\n event: { reason: \"invalid-context-kind\", kindSample },\n });\n const sampledEntries = Array.from(this.countsByKindSample, ([kindSample, count]) =>\n entryOf(count, kindSample),\n );\n const entries =\n this.countBeyondSampleLimit > 0\n ? [...sampledEntries, entryOf(this.countBeyondSampleLimit)]\n : sampledEntries;\n this.clear();\n return entries;\n }\n\n private clear() {\n this.countsByKindSample.clear();\n this.countBeyondSampleLimit = 0;\n this.startTime = undefined;\n }\n}\n","import type {\n ClientSession,\n ConfigDirectorContext,\n ConfigDirectorLogger,\n ConfigValueType,\n} from \"@js-client-core/types\";\nimport type {\n ClientTelemetryEventCollectorOptions,\n TelemetryClient,\n EvaluatedConfigEvent,\n} from \"@js-client-core/telemetry\";\nimport type {\n TelemetryClientSessionEvent,\n TelemetryCloseEvent,\n TelemetryEvaluatedConfigEvent,\n TelemetryFlushEvent,\n TelemetryInitializeEvent,\n TelemetryInvalidContextSubmissionsEvent,\n TelemetryUpdateContextEvent,\n TelemetryWorkerResponseEvent,\n} from \"./types\";\nimport type { TelemetryValue } from \"@shared/telemetry/utils\";\nimport { mapToTelemetryValue } from \"@shared/telemetry/utils\";\nimport { InvalidContextSubmissions } from \"@shared/telemetry/InvalidContextSubmissions\";\n\nconst DEFAULT_WORKER_CLOSE_TIMEOUT = 6_000;\n\nexport type WebWorkerTelemetryClientOptions = ClientTelemetryEventCollectorOptions & {\n workerCloseTimeout?: number;\n};\n\nexport class WebWorkerTelemetryClient implements TelemetryClient {\n private readonly logger: ConfigDirectorLogger;\n private readonly initializeMessage: TelemetryInitializeEvent;\n private readonly clientSession: Promise<ClientSession>;\n private worker: Worker | undefined;\n private turnedOff = false;\n private readonly pendingEvaluations: TelemetryEvaluatedConfigEvent[] = [];\n private readonly pendingEvaluationLimit: number;\n private readonly pendingInvalidContextSubmissions = new InvalidContextSubmissions();\n private closePromise: Promise<void> | undefined;\n private closeResolve: (() => void) | undefined;\n private closeTimer: ReturnType<typeof setTimeout> | undefined;\n private readonly workerCloseTimeout: number;\n private readonly visibilityHandler: () => void;\n\n constructor(options: WebWorkerTelemetryClientOptions) {\n this.logger = options.logger;\n this.workerCloseTimeout = options.workerCloseTimeout ?? DEFAULT_WORKER_CLOSE_TIMEOUT;\n this.pendingEvaluationLimit = options.evaluationQueueLimit ?? 1_000;\n this.clientSession = options.clientSession;\n\n this.initializeMessage = {\n type: \"Initialize\",\n payload: {\n sdkKey: options.sdkKey,\n sdkIdentity: options.sdkIdentity,\n metaContext: options.metaContext,\n baseUrl: options.baseUrl.toString(),\n evaluationQueueLimit: this.pendingEvaluationLimit,\n initialFlushIntervalDelay: options.initialFlushIntervalDelay ?? 5_000,\n flushIntervalDelay: options.flushIntervalDelay ?? 30_000,\n },\n };\n\n this.visibilityHandler = () => {\n if (document.visibilityState === \"hidden\") {\n this.flush();\n }\n };\n }\n\n private createWorkerOrTurnOff(): Worker | undefined {\n if (typeof Worker === \"undefined\") {\n this.turnOff(\n \"[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.\",\n );\n return undefined;\n }\n try {\n return new Worker(new URL(\"./worker.ts\", import.meta.url), { type: \"module\" });\n } catch (error) {\n this.turnOff(\n \"[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: \",\n error,\n );\n return undefined;\n }\n }\n\n private turnOff(warning: string, ...details: unknown[]) {\n this.turnedOff = true;\n this.pendingEvaluations.length = 0;\n this.logger.warn(warning, ...details);\n }\n\n private startWorker(): Worker | undefined {\n if (this.worker || this.turnedOff) {\n return this.worker;\n }\n const worker = this.createWorkerOrTurnOff();\n if (!worker) {\n return undefined;\n }\n worker.onmessage = (message: MessageEvent<TelemetryWorkerResponseEvent>) => {\n this.handleWorkerEvent(message.data);\n };\n worker.postMessage(this.initializeMessage);\n this.forwardClientSession(worker);\n this.worker = worker;\n\n try {\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n } catch (error) {\n this.logger.warn(\"[TelemetryEventCollector] Could not configure 'visibilitychange' listener: \", error);\n }\n\n for (const evaluation of this.pendingEvaluations) {\n worker.postMessage(evaluation);\n }\n this.pendingEvaluations.length = 0;\n this.forwardInvalidContextSubmissions(worker);\n return worker;\n }\n\n private forwardClientSession(worker: Worker) {\n void this.clientSession.then((clientSession) => {\n const clientSessionMessage: TelemetryClientSessionEvent = {\n type: \"ClientSession\",\n payload: clientSession,\n };\n worker.postMessage(clientSessionMessage);\n });\n }\n\n private forwardInvalidContextSubmissions(worker: Worker | undefined) {\n if (!worker) {\n return;\n }\n const entries = this.pendingInvalidContextSubmissions.takeSnapshot();\n if (entries.length === 0) {\n return;\n }\n const submissionsMessage: TelemetryInvalidContextSubmissionsEvent = {\n type: \"InvalidContextSubmissions\",\n payload: { entries },\n };\n worker.postMessage(submissionsMessage);\n }\n\n public async updateContext(value: ConfigDirectorContext | undefined) {\n if (this.closePromise) {\n return;\n }\n const updateContextMessage: TelemetryUpdateContextEvent = {\n type: \"UpdateContext\",\n payload: {\n context: value,\n },\n };\n this.startWorker()?.postMessage(updateContextMessage);\n }\n\n public evaluatedConfig<T extends ConfigValueType>(event: EvaluatedConfigEvent<T>): void {\n if (this.turnedOff) {\n return;\n }\n const evaluatedConfigMessage: TelemetryEvaluatedConfigEvent = {\n type: \"EvaluatedConfigEvent\",\n payload: this.sanitizeEvaluatedConfigEvent(event),\n };\n if (this.worker) {\n this.worker.postMessage(evaluatedConfigMessage);\n return;\n }\n if (this.pendingEvaluations.length >= this.pendingEvaluationLimit) {\n this.pendingEvaluations.shift();\n }\n this.pendingEvaluations.push(evaluatedConfigMessage);\n }\n\n public recordInvalidContext(kindSample: string): void {\n this.pendingInvalidContextSubmissions.record(kindSample);\n this.forwardInvalidContextSubmissions(this.worker);\n }\n\n private sanitizeEvaluatedConfigEvent<T extends ConfigValueType>(\n event: EvaluatedConfigEvent<T>,\n ): EvaluatedConfigEvent<TelemetryValue> {\n return {\n ...event,\n defaultValue: mapToTelemetryValue({ value: event.defaultValue, type: event.type }),\n evaluatedValue: mapToTelemetryValue({\n value: event.evaluatedValue,\n valueId: event.evaluatedValueId,\n type: event.type,\n }),\n };\n }\n\n private handleWorkerEvent(event: TelemetryWorkerResponseEvent) {\n if (event.type === \"Closed\") {\n this.finishClose();\n return;\n }\n if (!event.payload?.level || !event.payload?.message) {\n return;\n }\n const { level, message, args } = event.payload;\n\n switch (level) {\n case \"debug\":\n this.logger.debug(message, ...args);\n break;\n case \"info\":\n this.logger.info(message, ...args);\n break;\n case \"warn\":\n this.logger.warn(message, ...args);\n break;\n case \"error\":\n this.logger.error(message, ...args);\n break;\n }\n }\n\n private flush() {\n const flushMessage: TelemetryFlushEvent = {\n type: \"Flush\",\n };\n this.worker?.postMessage(flushMessage);\n }\n\n public close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n\n return this.performClose();\n }\n\n private performClose(): Promise<void> {\n const worker = this.worker;\n if (!worker) {\n this.pendingEvaluations.length = 0;\n this.closePromise = Promise.resolve();\n return this.closePromise;\n }\n try {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n } catch (error) {\n this.logger.warn(\"[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: \", error);\n }\n this.closePromise = new Promise<void>((resolve) => {\n this.closeResolve = resolve;\n this.closeTimer = setTimeout(() => {\n this.logger.warn(\n \"[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.\",\n );\n this.finishClose();\n }, this.workerCloseTimeout);\n const closeMessage: TelemetryCloseEvent = { type: \"Close\" };\n worker.postMessage(closeMessage);\n });\n return this.closePromise;\n }\n\n private finishClose() {\n clearTimeout(this.closeTimer);\n this.closeTimer = undefined;\n this.worker?.terminate();\n this.closeResolve?.();\n }\n}\n","const BASE62 = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nexport const toBase62 = (buf: Uint8Array, length: number): string => {\n const ZERO = BigInt(0);\n const BASE = BigInt(62);\n const hex = Array.from(buf)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n let n = BigInt(\"0x\" + hex);\n let result = \"\";\n while (n > ZERO) {\n result = BASE62[Number(n % BASE)] + result;\n n /= BASE;\n }\n return result.padStart(length, \"0\");\n};\n","export const DIGEST_BYTES = 16;\nexport const BASE62_LENGTH = Math.ceil((DIGEST_BYTES * 8) / Math.log2(62));\n","import { toBase62 } from \"@shared/base62-encoder\";\nimport { DIGEST_BYTES, BASE62_LENGTH } from \"@shared/value-id\";\n\nconst encoder = new TextEncoder();\n\nexport const generateValueId = async (\n v: string | number | boolean | null | undefined,\n): Promise<string | undefined> => {\n if (typeof crypto === \"undefined\" || crypto.subtle == null) {\n return undefined;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encoder.encode(v?.toString() ?? \"\"));\n return toBase62(new Uint8Array(hashBuffer, 0, DIGEST_BYTES), BASE62_LENGTH);\n};\n","import type { CachingProvider } from \"@js-client-core/index\";\nimport { CACHED_VALUES_STORAGE_KEY_PREFIX, DEFAULT_CACHING_SIZE_LIMIT_BYTES } from \"@js-client-core/cached-values\";\nimport { localStorageIfAvailable } from \"@js-client-core/browser-globals\";\n\nexport const localStorageCachingProvider = (clientSdkKeyDigest: Promise<string>): CachingProvider | undefined => {\n const storage = localStorageIfAvailable();\n if (!storage) {\n return undefined;\n }\n const storageKey = clientSdkKeyDigest.then((digest) => CACHED_VALUES_STORAGE_KEY_PREFIX + digest);\n return {\n read: async () => storage.getItem(await storageKey),\n write: async (value) => storage.setItem(await storageKey, value),\n remove: async () => storage.removeItem(await storageKey),\n sizeLimit: () => DEFAULT_CACHING_SIZE_LIMIT_BYTES,\n };\n};\n","import type { Sha256HexDigest } from \"@js-client-core/types\";\n\nconst toHex = (bytes: Uint8Array): string =>\n Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n\nexport const sha256HexDigestIfAvailable = (): Sha256HexDigest | undefined => {\n if (typeof crypto === \"undefined\" || crypto.subtle == null) {\n return undefined;\n }\n return async (text) => {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return toHex(new Uint8Array(digest));\n };\n};\n","import {\n type ConfigDirectorClientOptions,\n type ConfigDirectorClient,\n type IdentifyingSdkOptions,\n type OfflineClientOptions,\n} from \"@js-client-core/index\";\nimport { WebWorkerTelemetryClient } from \"./telemetry/WebWorkerTelemetryClient\";\nimport { DefaultConfigDirectorClient } from \"@js-client-core/DefaultConfigDirectorClient\";\nimport { defaultUrlFactory } from \"@shared/url\";\nimport { generateValueId } from \"./telemetry/value-id-generator\";\nimport { localStorageCachingProvider } from \"./local-storage-caching-provider\";\nimport { sha256HexDigestIfAvailable } from \"./sha256-hex-digest\";\n\n/**\n * Creates a browser client. With a client SDK key it connects to ConfigDirector; with\n * {@link OfflineClientOptions} alone it runs in `offline` mode and serves `connection.values`. An\n * absent key with `clientOptions` is the same as the options alone when their mode is `offline`,\n * and fails like a missing key otherwise.\n */\nexport const createBrowserClient = (\n clientSdkKeyOrOptions: string | OfflineClientOptions | undefined,\n sdkOptions: IdentifyingSdkOptions,\n clientOptions?: ConfigDirectorClientOptions,\n): ConfigDirectorClient => {\n return DefaultConfigDirectorClient.from(\n ({ clientSdkKey, baseUrl, logger, metadata, clientSession }) =>\n new WebWorkerTelemetryClient({\n sdkKey: clientSdkKey,\n sdkIdentity: {\n sdkName: sdkOptions.sdkName,\n sdkVersion: sdkOptions.sdkVersion,\n },\n metaContext: {\n appName: metadata?.appName,\n appVersion: metadata?.appVersion,\n },\n logger,\n baseUrl,\n urlFactory: defaultUrlFactory,\n valueIdGenerator: generateValueId,\n clientSession,\n }),\n clientSdkKeyOrOptions,\n sdkOptions,\n clientOptions,\n { sha256HexDigest: sha256HexDigestIfAvailable(), platformCachingProvider: localStorageCachingProvider },\n );\n};\n","import type { ClientEvents, ClientHooks, ConfigDirectorClient } from \"./types\";\n\ntype Registration = { event: keyof ClientEvents; handler: (payload: any) => void };\n\nexport class ClientHandlers {\n private registrations: Registration[] = [];\n\n constructor(private readonly client: ConfigDirectorClient) {}\n\n public on<T extends keyof ClientEvents>(event: T, handler: (payload: ClientEvents[T]) => void) {\n this.client.on(event, handler);\n this.registrations.push({ event, handler });\n }\n\n public registerHooks(hooks: ClientHooks | undefined) {\n for (const [event, handlerOrHandlers] of Object.entries(hooks ?? {})) {\n const handlers = Array.isArray(handlerOrHandlers) ? handlerOrHandlers : [handlerOrHandlers];\n for (const handler of handlers) {\n if (typeof handler === \"function\") {\n this.on(event as keyof ClientEvents, handler as (payload: unknown) => void);\n }\n }\n }\n }\n\n public removeAll() {\n for (const { event, handler } of this.registrations) {\n this.client.off(event, handler);\n }\n this.registrations = [];\n }\n}\n","export const deepEqual = (left: unknown, right: unknown): boolean => {\n if (Object.is(left, right)) {\n return true;\n }\n if (typeof left !== \"object\" || typeof right !== \"object\" || left === null || right === null) {\n return false;\n }\n if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) {\n return false;\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() === right.getTime();\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));\n }\n if (!isPlainObject(left) || !isPlainObject(right)) {\n return false;\n }\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key]))\n );\n};\n\nconst isPlainObject = (value: object): value is Record<string, unknown> => {\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n","import type { ConfigDirectorClient, ConfigDirectorContext } from \"./types\";\nimport { deepEqual } from \"@shared/deepEqual\";\n\nexport type MountAction = \"initialize\" | \"updateContext\" | \"none\";\n\nexport const decideMountAction = (\n client: ConfigDirectorClient,\n context: ConfigDirectorContext | undefined,\n): MountAction => {\n if (client.isInitializing) {\n return \"none\";\n }\n if (!client.isReady) {\n return \"initialize\";\n }\n if (context !== undefined && !deepEqual(context, client.context)) {\n return \"updateContext\";\n }\n return \"none\";\n};\n","import type { ConfigDirectorClient, ConfigDirectorContext } from \"@js-browser-client/index\";\nimport { decideMountAction } from \"@js-client-core/mountAction\";\nimport type { MountAction } from \"@js-client-core/mountAction\";\nimport { deepEqual } from \"@shared/deepEqual\";\n\ntype StartupAction = MountAction | \"waitForContext\";\n\nexport const decideStartupAction = (\n client: ConfigDirectorClient,\n context: ConfigDirectorContext | undefined,\n waitsForFirstContext: boolean,\n): StartupAction => {\n const mountAction = decideMountAction(client, context);\n if (waitsForFirstContext && mountAction === \"initialize\" && context === undefined) {\n return \"waitForContext\";\n }\n return mountAction;\n};\n\nexport type StartupPhase =\n | { kind: \"beforeFirstRenderEffects\" }\n | { kind: \"waitingForContext\"; client: ConfigDirectorClient }\n | { kind: \"started\"; client: ConfigDirectorClient };\n\nconst startupPhaseKindAfter: { [A in StartupAction]: \"waitingForContext\" | \"started\" } = {\n waitForContext: \"waitingForContext\",\n initialize: \"started\",\n updateContext: \"started\",\n none: \"started\",\n};\n\nexport const startupPhaseAfter = (startupAction: StartupAction, client: ConfigDirectorClient): StartupPhase => ({\n kind: startupPhaseKindAfter[startupAction],\n client,\n});\n\ntype GivenContextAction =\n | { action: \"skipUnchanged\" }\n | { action: \"keepForStartup\" }\n | { action: \"startClient\"; client: ConfigDirectorClient }\n | { action: \"updateContext\"; client: ConfigDirectorClient };\n\nexport const decideGivenContextAction = (\n startupPhase: StartupPhase,\n lastGivenContext: ConfigDirectorContext | undefined,\n context: ConfigDirectorContext | undefined,\n): GivenContextAction => {\n if (deepEqual(context, lastGivenContext)) {\n return { action: \"skipUnchanged\" };\n }\n switch (startupPhase.kind) {\n case \"beforeFirstRenderEffects\":\n return { action: \"keepForStartup\" };\n case \"waitingForContext\":\n return { action: \"startClient\", client: startupPhase.client };\n case \"started\":\n return { action: \"updateContext\", client: startupPhase.client };\n }\n};\n","\"use client\";\n\nimport React from \"react\";\nimport type { ConfigDirectorContextData } from \"./types\";\n\nconst createReactContext = () =>\n React.createContext<ConfigDirectorContextData>({ status: \"loading\", updateContext: async () => {} });\nexport const reactContext = createReactContext();\n","import type {\n ConfigDirectorLogMessageDecorator,\n ConfigDirectorLoggingLevel,\n ConfigDirectorLogger,\n} from \"@js-browser-client/index\";\nimport { createDefaultLogger as createJsSdkLogger } from \"@js-browser-client/index\";\n\nclass LogMessageDecorator implements ConfigDirectorLogMessageDecorator {\n decorateMessage(message: string): string {\n return `[ConfigDirector:nextjs-sdk] ${message}`;\n }\n}\n\nexport const createConsoleLogger = (level: ConfigDirectorLoggingLevel): ConfigDirectorLogger => {\n return createJsSdkLogger(level, new LogMessageDecorator());\n};\n","\"use client\";\n\nimport { Component, useEffect, type PropsWithChildren } from \"react\";\nimport { createBrowserClient, type ConfigDirectorClient, type ConfigDirectorContext } from \"@js-browser-client/index\";\nimport { ClientHandlers } from \"@js-client-core/clientHandlers\";\nimport { readInstalledTestClient } from \"@js-client-core/installedTestClient\";\nimport { deepEqual } from \"@shared/deepEqual\";\nimport { decideGivenContextAction, decideStartupAction, startupPhaseAfter } from \"./client-startup\";\nimport type { StartupPhase } from \"./client-startup\";\nimport { reactContext } from \"./context\";\nimport { createConsoleLogger } from \"./logger\";\nimport type {\n ClientStatus,\n ConfigDirectorClientProviderProps,\n ConfigDirectorProviderOptions,\n ConfigDirectorProviderState,\n} from \"./types\";\n\nconst hasGivenClient = (props: ConfigDirectorClientProviderProps): props is { client: ConfigDirectorClient } =>\n \"client\" in props && props.client !== undefined;\n\nconst settledStatusOf = (client: ConfigDirectorClient): ClientStatus => (client.isReady ? \"ready\" : \"default\");\n\nconst decideWaitsForFirstContext = (props: ConfigDirectorClientProviderProps, ownsClient: boolean): boolean => {\n const runsOffline = ownsClient && !hasGivenClient(props) && props.mode === \"offline\";\n return props.deferInitialization === true && !runsOffline;\n};\n\nconst RunAfterFirstRenderEffects = ({ run }: { run: () => void }) => {\n useEffect(() => {\n run();\n }, [run]);\n return null;\n};\n\n/**\n * Initializes the ConfigDirector browser client and provides it to all descendant hooks.\n *\n * Place this in your root layout, wrapping your application. In most cases prefer the\n * `ConfigDirectorProvider` exported from `@configdirector/nextjs-sdk/server` — it is a React\n * Server Component that populates `initialConfigs` automatically, ensuring Client Components\n * render the correct values during SSR without any extra wiring.\n *\n * This component itself is a Client Component, so if you use it directly (rather than through\n * the server provider) any `sdkKey` sourced from `process.env` must use the `NEXT_PUBLIC_`\n * prefix — Next.js only exposes prefixed variables to code that runs in the browser.\n *\n * The browser client starts after the effects of the provider's first render, including its\n * children's, have run, with the latest context given by then: one given through `updateContext`\n * during those effects, otherwise the `context` prop. A context equal to the one the provider\n * already has, given through either, opens no new connection.\n *\n * Given a `client` prop, or while a test client is installed from\n * `@configdirector/nextjs-sdk/client/testing`, the provider provides that client from its first\n * render instead of building one, and never disposes it.\n */\nexport class ConfigDirectorProvider extends Component<\n PropsWithChildren<ConfigDirectorClientProviderProps>,\n ConfigDirectorProviderState\n> {\n private client: ConfigDirectorClient | undefined;\n private readonly ownsClient: boolean;\n private readonly waitsForFirstContext: boolean;\n private handlers: ClientHandlers | undefined;\n private startupPhase: StartupPhase = { kind: \"beforeFirstRenderEffects\" };\n private lastGivenContext: ConfigDirectorContext | undefined;\n\n constructor(props: PropsWithChildren<ConfigDirectorClientProviderProps>) {\n super(props);\n const givenClient = hasGivenClient(props) ? props.client : readInstalledTestClient();\n this.ownsClient = givenClient === undefined;\n this.waitsForFirstContext = decideWaitsForFirstContext(props, this.ownsClient);\n this.client = givenClient;\n this.lastGivenContext = props.context;\n this.state = givenClient\n ? { client: givenClient, status: givenClient.isReady ? \"ready\" : \"loading\" }\n : { status: \"loading\" };\n }\n\n private buildClient(): ConfigDirectorClient {\n const options = this.props as ConfigDirectorProviderOptions;\n return createBrowserClient(\n options.sdkKey,\n { sdkName: \"nextjs-sdk\", sdkVersion: \"__VERSION__\" },\n {\n connection: {\n url: options.url,\n timeout: options.timeout,\n mode: options.mode,\n pollingInterval: options.pollingInterval,\n values: options.values,\n },\n metadata: { appName: options.appName, appVersion: options.appVersion },\n logger: createConsoleLogger(options.logLevel ?? \"warn\"),\n hooks: options.hooks,\n },\n );\n }\n\n override componentDidMount(): void {\n let client = this.client;\n if (this.ownsClient) {\n client = this.buildClient();\n this.client = client;\n this.setState({ client });\n }\n if (!client) {\n return;\n }\n\n this.handlers = new ClientHandlers(client);\n this.handlers.on(\"configsUpdated\", () => {\n this.setState({ updatedAt: new Date() });\n });\n this.handlers.on(\"clientReady\", () => {\n this.setState({ status: \"ready\" });\n });\n if (!this.ownsClient) {\n this.handlers.registerHooks(this.props.hooks);\n }\n }\n\n private readonly startAfterFirstRenderEffects = (): void => {\n const client = this.client;\n if (!client) {\n return;\n }\n void this.startClient(client, this.lastGivenContext);\n };\n\n private async startClient(client: ConfigDirectorClient, context: ConfigDirectorContext | undefined): Promise<void> {\n const startupAction = decideStartupAction(client, context, this.waitsForFirstContext);\n this.startupPhase = startupPhaseAfter(startupAction, client);\n switch (startupAction) {\n case \"waitForContext\":\n return;\n case \"initialize\":\n await client.initialize(context);\n this.settleStatus(client);\n return;\n case \"updateContext\":\n await this.updateClientContext(client, context as ConfigDirectorContext);\n return;\n case \"none\":\n return;\n }\n }\n\n private async updateClientContext(client: ConfigDirectorClient, context: ConfigDirectorContext): Promise<void> {\n this.setState({ status: \"loading\" });\n await client.updateContext(context);\n this.settleStatus(client);\n }\n\n private settleStatus(client: ConfigDirectorClient): void {\n if (this.client === client) {\n this.setState({ status: settledStatusOf(client) });\n }\n }\n\n private readonly receiveContext = async (context: ConfigDirectorContext | undefined): Promise<void> => {\n const decision = decideGivenContextAction(this.startupPhase, this.lastGivenContext, context);\n switch (decision.action) {\n case \"skipUnchanged\":\n return;\n case \"keepForStartup\":\n this.lastGivenContext = context;\n return;\n case \"startClient\":\n this.lastGivenContext = context;\n await this.startClient(decision.client, context);\n return;\n case \"updateContext\":\n this.lastGivenContext = context;\n await this.updateClientContext(decision.client, context ?? {});\n return;\n }\n };\n\n override async componentDidUpdate(\n prevProps: PropsWithChildren<ConfigDirectorClientProviderProps>,\n ): Promise<void> {\n if (hasGivenClient(prevProps) && hasGivenClient(this.props) && prevProps.client !== this.props.client) {\n createConsoleLogger(\"warn\").warn(\n \"The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.\",\n );\n }\n if (!deepEqual(prevProps.context, this.props.context)) {\n await this.receiveContext(this.props.context);\n }\n }\n\n override componentWillUnmount(): void {\n this.handlers?.removeAll();\n this.handlers = undefined;\n this.startupPhase = { kind: \"beforeFirstRenderEffects\" };\n this.lastGivenContext = this.props.context;\n if (this.ownsClient) {\n this.client?.dispose();\n this.client = undefined;\n }\n }\n\n override render() {\n return (\n <reactContext.Provider\n value={{ ...this.state, initialConfigs: this.props.initialConfigs, updateContext: this.receiveContext }}>\n {this.props.children}\n <RunAfterFirstRenderEffects run={this.startAfterFirstRenderEffects} />\n </reactContext.Provider>\n );\n }\n}\n","export class ConfigDirectorNextContextError extends Error {\n public override readonly name: string = \"ConfigDirectorNextContextError\";\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, ConfigDirectorNextContextError.prototype);\n }\n}\n","\"use client\";\n\nimport { useContext as useReactContext } from \"react\";\nimport { reactContext } from \"./context\";\nimport type { ConfigDirectorContext, ConfigValueType } from \"@js-browser-client/index\";\nimport { parseConfigValue } from \"@shared/value-parser\";\nimport { ConfigDirectorNextContextError } from \"./errors\";\nimport type { ClientStatus } from \"./types\";\n\nconst noContextError = () =>\n new ConfigDirectorNextContextError(\n \"The ConfigDirector client was not found in the React context. \" +\n \"Make sure the component using this hook is inside a <ConfigDirectorProvider>.\",\n );\n\n/**\n * Returns the evaluated value of a config key.\n *\n * During SSR and before the browser client finishes initializing, returns the value from\n * `initialConfigs` (if provided to the provider) to avoid a flash of wrong content on hydration.\n * Once the browser client is ready, returns live-evaluated values and re-renders whenever configs\n * change.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useConfigValue = <T extends ConfigValueType>(\n key: string,\n defaultValue: T,\n): { value: T; readyStatus: ClientStatus; loading: boolean } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n\n // The client is undefined during SSR and briefly during the first client render before componentDidMount\n // fires. Fall through to initialConfigs in both cases so the rendered output matches the server HTML,\n // avoiding a hydration mismatch.\n const initialConfigState = configDirectorReactContext.initialConfigs?.[key];\n const value = configDirectorReactContext.client?.isReady\n ? configDirectorReactContext.client.getValue(key, defaultValue)\n : initialConfigState\n ? parseConfigValue(initialConfigState, defaultValue).parsedValue\n : defaultValue;\n\n return {\n value,\n readyStatus: configDirectorReactContext.status,\n loading: configDirectorReactContext.status === \"loading\",\n };\n};\n\n/**\n * Returns an `updateContext` function to update the user context on the browser client.\n * Triggers re-evaluation of all watched config values.\n *\n * The function keeps one identity across renders, so it is safe in an effect's dependency list. A\n * call made before the browser client has started, for example from a mount effect, becomes the\n * context the client starts with, so the first connection carries it. A context equal to the one the\n * provider already has opens no new connection.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useContext = (): { updateContext: (context: ConfigDirectorContext) => Promise<void> } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n\n return { updateContext: configDirectorReactContext.updateContext };\n};\n\n/**\n * Returns the raw browser client for advanced use cases.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useClient = () => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext?.client) throw noContextError();\n return { client: configDirectorReactContext.client };\n};\n\n/**\n * Returns the current connection status of the browser client.\n *\n * - `\"loading\"` — client is initializing\n * - `\"ready\"` — client received configs from the server, or loaded its offline values\n * - `\"default\"` — initialization timed out; hooks return default or initial values\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useConfigDirectorStatus = (): { readyStatus: ClientStatus; loading: boolean } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n return {\n readyStatus: configDirectorReactContext.status,\n loading: configDirectorReactContext.status === \"loading\",\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["createJsSdkLogger","useReactContext"],"sources":["../../../shared/src/telemetry/utils.ts","../../../shared/src/telemetry/InvalidContextSubmissions.ts","../../../shared/src/telemetry/TrackedEventQueue.ts","../../../js-browser-client/src/telemetry/WebWorkerTelemetryClient.ts","../../../shared/src/base62-encoder.ts","../../../shared/src/value-id.ts","../../../js-browser-client/src/telemetry/value-id-generator.ts","../../../js-browser-client/src/local-storage-caching-provider.ts","../../../js-browser-client/src/sha256-hex-digest.ts","../../../js-browser-client/src/BrowserConfigDirectorClient.ts","../../../js-client-core/src/clientHandlers.ts","../../../shared/src/deepEqual.ts","../../../js-client-core/src/mountAction.ts","../../src/client/client-startup.ts","../../src/client/context.tsx","../../src/client/logger.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/errors.ts","../../src/client/hooks.tsx"],"sourcesContent":["import type { ConfigType, ConfigValueType } from \"../types\";\nimport type { ValueIdGenerator, DroppedEvents } from \"./types\";\n\nconst CONFIG_VALUE_MAX_LENGTH = 500;\n\nexport type TelemetryValue = {\n value?: string;\n valueId?: string;\n type?: ConfigType;\n};\n\nexport type TelemetryEvaluationValue<TV extends ConfigValueType> = {\n value: TV;\n valueId?: string | null | undefined;\n type?: ConfigType;\n};\n\nexport const compactTelemetryValue = async (\n tv: TelemetryValue,\n valueIdGenerator: ValueIdGenerator,\n): Promise<TelemetryValue> => {\n if (tv.valueId) {\n return { valueId: tv.valueId };\n }\n if (tv.value) {\n if (tv.value.length <= CONFIG_VALUE_MAX_LENGTH && tv.type != \"json\") {\n return { value: tv.value };\n }\n\n return { valueId: await valueIdGenerator(tv.value) };\n }\n\n return tv;\n};\n\nexport const mapToTelemetryValue = <TV extends ConfigValueType>(\n ev: TelemetryEvaluationValue<TV>,\n): TelemetryValue => {\n if (ev.type === \"json\" || (ev.type == null && typeof ev.value === \"object\")) {\n if (ev.valueId) {\n return { valueId: ev.valueId, type: \"json\" };\n }\n try {\n const json = JSON.stringify(ev.value);\n return { value: json, type: \"json\" };\n } catch {\n return { value: ev.value.toString(), type: \"json\" };\n }\n }\n\n const stringValue = ev.value?.toString();\n if (stringValue && stringValue.length <= CONFIG_VALUE_MAX_LENGTH) {\n return { value: stringValue };\n }\n\n return ev.valueId ? { valueId: ev.valueId } : { value: stringValue };\n};\n\nexport const djb2Hash = (data: string): string => {\n const hash = djb2(new TextEncoder().encode(data));\n return hash.toString(16).padStart(8, \"0\");\n};\n\nconst djb2 = (bytes: Uint8Array): number => {\n let hash = 5381;\n for (let i = 0; i < bytes.length; i++) {\n hash = (hash << 5) + hash + (bytes[i] ?? 0);\n hash = hash >>> 0;\n }\n return hash;\n};\n\nexport const isEventListEmpty = <T extends Record<string | symbol, any[]>>(eventList: T): boolean => {\n const keys = Object.keys(eventList);\n if (keys.length == 0) {\n return true;\n }\n\n for (const key of keys) {\n if ((eventList[key]?.length ?? 0) > 0) {\n return false;\n }\n }\n\n return true;\n};\n\nexport const isDroppedEventsEmpty = (droppedEvents?: DroppedEvents): boolean => {\n if (!droppedEvents) {\n return true;\n }\n const keys = Object.keys(droppedEvents);\n if (keys.length == 0) {\n return true;\n }\n\n for (const key of keys) {\n if ((droppedEvents[key] ?? 0) > 0) {\n return false;\n }\n }\n\n return true;\n};\n","import type { InvalidContextEvent } from \"./telemetry-events\";\nimport type { AggregatedEvent } from \"./types\";\n\nexport const DISTINCT_KIND_SAMPLE_LIMIT = 20;\n\nexport type InvalidContextRecording =\n | \"new-kind-sample\"\n | \"known-kind-sample\"\n | \"first-beyond-sample-limit\"\n | \"beyond-sample-limit\";\n\nexport class InvalidContextSubmissions {\n private readonly countsByKindSample = new Map<string, number>();\n private countBeyondSampleLimit = 0;\n private startTime: Date | undefined;\n\n public record(kindSample: string): InvalidContextRecording {\n this.startTime ??= new Date();\n return this.add(kindSample, 1);\n }\n\n public absorb(entries: AggregatedEvent<InvalidContextEvent>[]): void {\n for (const entry of entries) {\n if (this.startTime === undefined || entry.startTime < this.startTime) {\n this.startTime = entry.startTime;\n }\n this.add(entry.event.kindSample, entry.count);\n }\n }\n\n private add(kindSample: string | undefined, count: number): InvalidContextRecording {\n if (kindSample !== undefined) {\n const knownCount = this.countsByKindSample.get(kindSample);\n if (knownCount !== undefined) {\n this.countsByKindSample.set(kindSample, knownCount + count);\n return \"known-kind-sample\";\n }\n if (this.countsByKindSample.size < DISTINCT_KIND_SAMPLE_LIMIT) {\n this.countsByKindSample.set(kindSample, count);\n return \"new-kind-sample\";\n }\n }\n const firstBeyondSampleLimit = this.countBeyondSampleLimit === 0;\n this.countBeyondSampleLimit += count;\n return firstBeyondSampleLimit ? \"first-beyond-sample-limit\" : \"beyond-sample-limit\";\n }\n\n public takeSnapshot(): AggregatedEvent<InvalidContextEvent>[] {\n const endTime = new Date();\n const startTime = this.startTime ?? endTime;\n const entryOf = (count: number, kindSample?: string): AggregatedEvent<InvalidContextEvent> => ({\n startTime,\n endTime,\n count,\n event: { reason: \"invalid-context-kind\", kindSample },\n });\n const sampledEntries = Array.from(this.countsByKindSample, ([kindSample, count]) =>\n entryOf(count, kindSample),\n );\n const entries =\n this.countBeyondSampleLimit > 0\n ? [...sampledEntries, entryOf(this.countBeyondSampleLimit)]\n : sampledEntries;\n this.clear();\n return entries;\n }\n\n private clear() {\n this.countsByKindSample.clear();\n this.countBeyondSampleLimit = 0;\n this.startTime = undefined;\n }\n}\n","import { TRACKED_EVENTS_PER_BATCH } from \"./tracked-events\";\nimport type { TrackedEventAdmission, TrackedEventEntry, TrackedEventWarning } from \"./tracked-events\";\n\nexport class TrackedEventQueue {\n private entries: TrackedEventEntry[] = [];\n private readonly warningsRaisedThisBatch = new Set<TrackedEventWarning>();\n\n public add(admission: TrackedEventAdmission): TrackedEventWarning[] {\n return this.warningsOfKeeping(admission).filter((warning) => this.isFirstThisBatch(warning));\n }\n\n public absorb(entries: TrackedEventEntry[]): void {\n this.entries.push(...entries);\n }\n\n public takeBatch(): TrackedEventEntry[] {\n const batch = this.entries;\n this.clear();\n return batch;\n }\n\n public clear(): void {\n this.entries = [];\n this.warningsRaisedThisBatch.clear();\n }\n\n private warningsOfKeeping(admission: TrackedEventAdmission): TrackedEventWarning[] {\n switch (admission.outcome) {\n case \"dropped\":\n return admission.warnings;\n case \"admitted\":\n if (this.entries.length >= TRACKED_EVENTS_PER_BATCH) {\n return [\"batch-already-full\"];\n }\n this.entries.push(admission.entry);\n return admission.warnings;\n }\n }\n\n private isFirstThisBatch(warning: TrackedEventWarning): boolean {\n if (this.warningsRaisedThisBatch.has(warning)) {\n return false;\n }\n this.warningsRaisedThisBatch.add(warning);\n return true;\n }\n}\n","import type {\n ClientSession,\n ConfigDirectorContext,\n ConfigDirectorLogger,\n ConfigValueType,\n} from \"@js-client-core/types\";\nimport type {\n ClientTelemetryEventCollectorOptions,\n TelemetryClient,\n EvaluatedConfigEvent,\n} from \"@js-client-core/telemetry\";\nimport type {\n TelemetryClientSessionEvent,\n TelemetryCloseEvent,\n TelemetryEvaluatedConfigEvent,\n TelemetryFlushEvent,\n TelemetryInitializeEvent,\n TelemetryInvalidContextSubmissionsEvent,\n TelemetryTrackedEventEntriesEvent,\n TelemetryTrackedEventEvent,\n TelemetryUpdateContextEvent,\n TelemetryWorkerResponseEvent,\n} from \"./types\";\nimport type { TelemetryValue } from \"@shared/telemetry/utils\";\nimport { mapToTelemetryValue } from \"@shared/telemetry/utils\";\nimport { InvalidContextSubmissions } from \"@shared/telemetry/InvalidContextSubmissions\";\nimport { TrackedEventQueue } from \"@shared/telemetry/TrackedEventQueue\";\nimport { logBatchWarnings } from \"@shared/telemetry/tracked-events\";\nimport type { TrackedEventAdmission } from \"@shared/telemetry/tracked-events\";\n\nconst DEFAULT_WORKER_CLOSE_TIMEOUT = 6_000;\n\nexport type WebWorkerTelemetryClientOptions = ClientTelemetryEventCollectorOptions & {\n workerCloseTimeout?: number;\n};\n\nexport class WebWorkerTelemetryClient implements TelemetryClient {\n private readonly logger: ConfigDirectorLogger;\n private readonly initializeMessage: TelemetryInitializeEvent;\n private readonly clientSession: Promise<ClientSession>;\n private worker: Worker | undefined;\n private turnedOff = false;\n private readonly pendingEvaluations: TelemetryEvaluatedConfigEvent[] = [];\n private readonly pendingEvaluationLimit: number;\n private readonly pendingInvalidContextSubmissions = new InvalidContextSubmissions();\n private readonly pendingTrackedEvents = new TrackedEventQueue();\n private closePromise: Promise<void> | undefined;\n private closeResolve: (() => void) | undefined;\n private closeTimer: ReturnType<typeof setTimeout> | undefined;\n private readonly workerCloseTimeout: number;\n private readonly visibilityHandler: () => void;\n\n constructor(options: WebWorkerTelemetryClientOptions) {\n this.logger = options.logger;\n this.workerCloseTimeout = options.workerCloseTimeout ?? DEFAULT_WORKER_CLOSE_TIMEOUT;\n this.pendingEvaluationLimit = options.evaluationQueueLimit ?? 1_000;\n this.clientSession = options.clientSession;\n\n this.initializeMessage = {\n type: \"Initialize\",\n payload: {\n sdkKey: options.sdkKey,\n sdkIdentity: options.sdkIdentity,\n metaContext: options.metaContext,\n baseUrl: options.baseUrl.toString(),\n evaluationQueueLimit: this.pendingEvaluationLimit,\n initialFlushIntervalDelay: options.initialFlushIntervalDelay ?? 5_000,\n flushIntervalDelay: options.flushIntervalDelay ?? 30_000,\n },\n };\n\n this.visibilityHandler = () => {\n if (document.visibilityState === \"hidden\") {\n this.flush();\n }\n };\n }\n\n private createWorkerOrTurnOff(): Worker | undefined {\n if (typeof Worker === \"undefined\") {\n this.turnOff(\n \"[WebWorkerTelemetryClient] Telemetry is off because Web Workers are not available in this environment.\",\n );\n return undefined;\n }\n try {\n return new Worker(new URL(\"./worker.ts\", import.meta.url), { type: \"module\" });\n } catch (error) {\n this.turnOff(\n \"[WebWorkerTelemetryClient] Telemetry is off because the telemetry Web Worker could not be created: \",\n error,\n );\n return undefined;\n }\n }\n\n private turnOff(warning: string, ...details: unknown[]) {\n this.turnedOff = true;\n this.pendingEvaluations.length = 0;\n this.pendingTrackedEvents.clear();\n this.logger.warn(warning, ...details);\n }\n\n private startWorker(): Worker | undefined {\n if (this.worker || this.turnedOff) {\n return this.worker;\n }\n const worker = this.createWorkerOrTurnOff();\n if (!worker) {\n return undefined;\n }\n worker.onmessage = (message: MessageEvent<TelemetryWorkerResponseEvent>) => {\n this.handleWorkerEvent(message.data);\n };\n worker.postMessage(this.initializeMessage);\n this.forwardClientSession(worker);\n this.worker = worker;\n\n try {\n document.addEventListener(\"visibilitychange\", this.visibilityHandler);\n } catch (error) {\n this.logger.warn(\"[TelemetryEventCollector] Could not configure 'visibilitychange' listener: \", error);\n }\n\n for (const evaluation of this.pendingEvaluations) {\n worker.postMessage(evaluation);\n }\n this.pendingEvaluations.length = 0;\n this.forwardInvalidContextSubmissions(worker);\n this.forwardPendingTrackedEvents(worker);\n return worker;\n }\n\n private forwardPendingTrackedEvents(worker: Worker) {\n const entries = this.pendingTrackedEvents.takeBatch();\n if (entries.length === 0) {\n return;\n }\n const entriesMessage: TelemetryTrackedEventEntriesEvent = {\n type: \"TrackedEventEntries\",\n payload: { entries },\n };\n worker.postMessage(entriesMessage);\n }\n\n private forwardClientSession(worker: Worker) {\n void this.clientSession.then((clientSession) => {\n const clientSessionMessage: TelemetryClientSessionEvent = {\n type: \"ClientSession\",\n payload: clientSession,\n };\n worker.postMessage(clientSessionMessage);\n });\n }\n\n private forwardInvalidContextSubmissions(worker: Worker | undefined) {\n if (!worker) {\n return;\n }\n const entries = this.pendingInvalidContextSubmissions.takeSnapshot();\n if (entries.length === 0) {\n return;\n }\n const submissionsMessage: TelemetryInvalidContextSubmissionsEvent = {\n type: \"InvalidContextSubmissions\",\n payload: { entries },\n };\n worker.postMessage(submissionsMessage);\n }\n\n public async updateContext(value: ConfigDirectorContext | undefined) {\n if (this.closePromise) {\n return;\n }\n const updateContextMessage: TelemetryUpdateContextEvent = {\n type: \"UpdateContext\",\n payload: {\n context: value,\n },\n };\n this.startWorker()?.postMessage(updateContextMessage);\n }\n\n public evaluatedConfig<T extends ConfigValueType>(event: EvaluatedConfigEvent<T>): void {\n if (this.turnedOff) {\n return;\n }\n const evaluatedConfigMessage: TelemetryEvaluatedConfigEvent = {\n type: \"EvaluatedConfigEvent\",\n payload: this.sanitizeEvaluatedConfigEvent(event),\n };\n if (this.worker) {\n this.worker.postMessage(evaluatedConfigMessage);\n return;\n }\n if (this.pendingEvaluations.length >= this.pendingEvaluationLimit) {\n this.pendingEvaluations.shift();\n }\n this.pendingEvaluations.push(evaluatedConfigMessage);\n }\n\n public recordInvalidContext(kindSample: string): void {\n this.pendingInvalidContextSubmissions.record(kindSample);\n this.forwardInvalidContextSubmissions(this.worker);\n }\n\n public trackedEvent(admission: TrackedEventAdmission): void {\n if (this.turnedOff || this.closePromise) {\n return;\n }\n if (this.worker) {\n const trackedEventMessage: TelemetryTrackedEventEvent = { type: \"TrackedEvent\", payload: admission };\n this.worker.postMessage(trackedEventMessage);\n return;\n }\n logBatchWarnings(this.logger, this.pendingTrackedEvents.add(admission));\n }\n\n private sanitizeEvaluatedConfigEvent<T extends ConfigValueType>(\n event: EvaluatedConfigEvent<T>,\n ): EvaluatedConfigEvent<TelemetryValue> {\n return {\n ...event,\n defaultValue: mapToTelemetryValue({ value: event.defaultValue, type: event.type }),\n evaluatedValue: mapToTelemetryValue({\n value: event.evaluatedValue,\n valueId: event.evaluatedValueId,\n type: event.type,\n }),\n };\n }\n\n private handleWorkerEvent(event: TelemetryWorkerResponseEvent) {\n if (event.type === \"Closed\") {\n this.finishClose();\n return;\n }\n if (!event.payload?.level || !event.payload?.message) {\n return;\n }\n const { level, message, args } = event.payload;\n\n switch (level) {\n case \"debug\":\n this.logger.debug(message, ...args);\n break;\n case \"info\":\n this.logger.info(message, ...args);\n break;\n case \"warn\":\n this.logger.warn(message, ...args);\n break;\n case \"error\":\n this.logger.error(message, ...args);\n break;\n }\n }\n\n private flush() {\n const flushMessage: TelemetryFlushEvent = {\n type: \"Flush\",\n };\n this.worker?.postMessage(flushMessage);\n }\n\n public close(): Promise<void> {\n if (this.closePromise) {\n return this.closePromise;\n }\n\n return this.performClose();\n }\n\n private performClose(): Promise<void> {\n const worker = this.worker;\n if (!worker) {\n this.pendingEvaluations.length = 0;\n this.pendingTrackedEvents.clear();\n this.closePromise = Promise.resolve();\n return this.closePromise;\n }\n try {\n document.removeEventListener(\"visibilitychange\", this.visibilityHandler);\n } catch (error) {\n this.logger.warn(\"[WebWorkerTelemetryClient] Could not remove 'visibilitychange' listener: \", error);\n }\n this.closePromise = new Promise<void>((resolve) => {\n this.closeResolve = resolve;\n this.closeTimer = setTimeout(() => {\n this.logger.warn(\n \"[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.\",\n );\n this.finishClose();\n }, this.workerCloseTimeout);\n const closeMessage: TelemetryCloseEvent = { type: \"Close\" };\n worker.postMessage(closeMessage);\n });\n return this.closePromise;\n }\n\n private finishClose() {\n clearTimeout(this.closeTimer);\n this.closeTimer = undefined;\n this.worker?.terminate();\n this.closeResolve?.();\n }\n}\n","const BASE62 = \"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz\";\n\nexport const toBase62 = (buf: Uint8Array, length: number): string => {\n const ZERO = BigInt(0);\n const BASE = BigInt(62);\n const hex = Array.from(buf)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n let n = BigInt(\"0x\" + hex);\n let result = \"\";\n while (n > ZERO) {\n result = BASE62[Number(n % BASE)] + result;\n n /= BASE;\n }\n return result.padStart(length, \"0\");\n};\n","export const DIGEST_BYTES = 16;\nexport const BASE62_LENGTH = Math.ceil((DIGEST_BYTES * 8) / Math.log2(62));\n","import { toBase62 } from \"@shared/base62-encoder\";\nimport { DIGEST_BYTES, BASE62_LENGTH } from \"@shared/value-id\";\n\nconst encoder = new TextEncoder();\n\nexport const generateValueId = async (\n v: string | number | boolean | null | undefined,\n): Promise<string | undefined> => {\n if (typeof crypto === \"undefined\" || crypto.subtle == null) {\n return undefined;\n }\n const hashBuffer = await crypto.subtle.digest(\"SHA-256\", encoder.encode(v?.toString() ?? \"\"));\n return toBase62(new Uint8Array(hashBuffer, 0, DIGEST_BYTES), BASE62_LENGTH);\n};\n","import type { CachingProvider } from \"@js-client-core/index\";\nimport { CACHED_VALUES_STORAGE_KEY_PREFIX, DEFAULT_CACHING_SIZE_LIMIT_BYTES } from \"@js-client-core/cached-values\";\nimport { localStorageIfAvailable } from \"@js-client-core/browser-globals\";\n\nexport const localStorageCachingProvider = (clientSdkKeyDigest: Promise<string>): CachingProvider | undefined => {\n const storage = localStorageIfAvailable();\n if (!storage) {\n return undefined;\n }\n const storageKey = clientSdkKeyDigest.then((digest) => CACHED_VALUES_STORAGE_KEY_PREFIX + digest);\n return {\n read: async () => storage.getItem(await storageKey),\n write: async (value) => storage.setItem(await storageKey, value),\n remove: async () => storage.removeItem(await storageKey),\n sizeLimit: () => DEFAULT_CACHING_SIZE_LIMIT_BYTES,\n };\n};\n","import type { Sha256HexDigest } from \"@js-client-core/types\";\n\nconst toHex = (bytes: Uint8Array): string =>\n Array.from(bytes, (byte) => byte.toString(16).padStart(2, \"0\")).join(\"\");\n\nexport const sha256HexDigestIfAvailable = (): Sha256HexDigest | undefined => {\n if (typeof crypto === \"undefined\" || crypto.subtle == null) {\n return undefined;\n }\n return async (text) => {\n const digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(text));\n return toHex(new Uint8Array(digest));\n };\n};\n","import {\n type ConfigDirectorClientOptions,\n type ConfigDirectorClient,\n type IdentifyingSdkOptions,\n type OfflineClientOptions,\n} from \"@js-client-core/index\";\nimport { WebWorkerTelemetryClient } from \"./telemetry/WebWorkerTelemetryClient\";\nimport { DefaultConfigDirectorClient } from \"@js-client-core/DefaultConfigDirectorClient\";\nimport { defaultUrlFactory } from \"@shared/url\";\nimport { generateValueId } from \"./telemetry/value-id-generator\";\nimport { localStorageCachingProvider } from \"./local-storage-caching-provider\";\nimport { sha256HexDigestIfAvailable } from \"./sha256-hex-digest\";\n\n/**\n * Creates a browser client. With a client SDK key it connects to ConfigDirector; with\n * {@link OfflineClientOptions} alone it runs in `offline` mode and serves `connection.values`. An\n * absent key with `clientOptions` is the same as the options alone when their mode is `offline`,\n * and fails like a missing key otherwise.\n */\nexport const createBrowserClient = (\n clientSdkKeyOrOptions: string | OfflineClientOptions | undefined,\n sdkOptions: IdentifyingSdkOptions,\n clientOptions?: ConfigDirectorClientOptions,\n): ConfigDirectorClient => {\n return DefaultConfigDirectorClient.from(\n ({ clientSdkKey, baseUrl, logger, metadata, clientSession }) =>\n new WebWorkerTelemetryClient({\n sdkKey: clientSdkKey,\n sdkIdentity: {\n sdkName: sdkOptions.sdkName,\n sdkVersion: sdkOptions.sdkVersion,\n },\n metaContext: {\n appName: metadata?.appName,\n appVersion: metadata?.appVersion,\n },\n logger,\n baseUrl,\n urlFactory: defaultUrlFactory,\n valueIdGenerator: generateValueId,\n clientSession,\n }),\n clientSdkKeyOrOptions,\n sdkOptions,\n clientOptions,\n { sha256HexDigest: sha256HexDigestIfAvailable(), platformCachingProvider: localStorageCachingProvider },\n );\n};\n","import type { ClientEvents, ClientHooks, ConfigDirectorClient } from \"./types\";\n\ntype Registration = { event: keyof ClientEvents; handler: (payload: any) => void };\n\nexport class ClientHandlers {\n private registrations: Registration[] = [];\n\n constructor(private readonly client: ConfigDirectorClient) {}\n\n public on<T extends keyof ClientEvents>(event: T, handler: (payload: ClientEvents[T]) => void) {\n this.client.on(event, handler);\n this.registrations.push({ event, handler });\n }\n\n public registerHooks(hooks: ClientHooks | undefined) {\n for (const [event, handlerOrHandlers] of Object.entries(hooks ?? {})) {\n const handlers = Array.isArray(handlerOrHandlers) ? handlerOrHandlers : [handlerOrHandlers];\n for (const handler of handlers) {\n if (typeof handler === \"function\") {\n this.on(event as keyof ClientEvents, handler as (payload: unknown) => void);\n }\n }\n }\n }\n\n public removeAll() {\n for (const { event, handler } of this.registrations) {\n this.client.off(event, handler);\n }\n this.registrations = [];\n }\n}\n","export const deepEqual = (left: unknown, right: unknown): boolean => {\n if (Object.is(left, right)) {\n return true;\n }\n if (typeof left !== \"object\" || typeof right !== \"object\" || left === null || right === null) {\n return false;\n }\n if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) {\n return false;\n }\n if (left instanceof Date && right instanceof Date) {\n return left.getTime() === right.getTime();\n }\n if (Array.isArray(left) && Array.isArray(right)) {\n return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));\n }\n if (!isPlainObject(left) || !isPlainObject(right)) {\n return false;\n }\n const leftKeys = Object.keys(left);\n const rightKeys = Object.keys(right);\n return (\n leftKeys.length === rightKeys.length &&\n leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key]))\n );\n};\n\nconst isPlainObject = (value: object): value is Record<string, unknown> => {\n const prototype = Object.getPrototypeOf(value);\n return prototype === Object.prototype || prototype === null;\n};\n","import type { ConfigDirectorClient, ConfigDirectorContext } from \"./types\";\nimport { deepEqual } from \"@shared/deepEqual\";\n\nexport type MountAction = \"initialize\" | \"updateContext\" | \"none\";\n\nexport const decideMountAction = (\n client: ConfigDirectorClient,\n context: ConfigDirectorContext | undefined,\n): MountAction => {\n if (client.isInitializing) {\n return \"none\";\n }\n if (!client.isReady) {\n return \"initialize\";\n }\n if (context !== undefined && !deepEqual(context, client.context)) {\n return \"updateContext\";\n }\n return \"none\";\n};\n","import type { ConfigDirectorClient, ConfigDirectorContext } from \"@js-browser-client/index\";\nimport { decideMountAction } from \"@js-client-core/mountAction\";\nimport type { MountAction } from \"@js-client-core/mountAction\";\nimport { deepEqual } from \"@shared/deepEqual\";\n\ntype StartupAction = MountAction | \"waitForContext\";\n\nexport const decideStartupAction = (\n client: ConfigDirectorClient,\n context: ConfigDirectorContext | undefined,\n waitsForFirstContext: boolean,\n): StartupAction => {\n const mountAction = decideMountAction(client, context);\n if (waitsForFirstContext && mountAction === \"initialize\" && context === undefined) {\n return \"waitForContext\";\n }\n return mountAction;\n};\n\nexport type StartupPhase =\n | { kind: \"beforeFirstRenderEffects\" }\n | { kind: \"waitingForContext\"; client: ConfigDirectorClient }\n | { kind: \"started\"; client: ConfigDirectorClient };\n\nconst startupPhaseKindAfter: { [A in StartupAction]: \"waitingForContext\" | \"started\" } = {\n waitForContext: \"waitingForContext\",\n initialize: \"started\",\n updateContext: \"started\",\n none: \"started\",\n};\n\nexport const startupPhaseAfter = (startupAction: StartupAction, client: ConfigDirectorClient): StartupPhase => ({\n kind: startupPhaseKindAfter[startupAction],\n client,\n});\n\ntype GivenContextAction =\n | { action: \"skipUnchanged\" }\n | { action: \"keepForStartup\" }\n | { action: \"startClient\"; client: ConfigDirectorClient }\n | { action: \"updateContext\"; client: ConfigDirectorClient };\n\nexport const decideGivenContextAction = (\n startupPhase: StartupPhase,\n lastGivenContext: ConfigDirectorContext | undefined,\n context: ConfigDirectorContext | undefined,\n): GivenContextAction => {\n if (deepEqual(context, lastGivenContext)) {\n return { action: \"skipUnchanged\" };\n }\n switch (startupPhase.kind) {\n case \"beforeFirstRenderEffects\":\n return { action: \"keepForStartup\" };\n case \"waitingForContext\":\n return { action: \"startClient\", client: startupPhase.client };\n case \"started\":\n return { action: \"updateContext\", client: startupPhase.client };\n }\n};\n","\"use client\";\n\nimport React from \"react\";\nimport type { ConfigDirectorContextData } from \"./types\";\n\nconst createReactContext = () =>\n React.createContext<ConfigDirectorContextData>({ status: \"loading\", updateContext: async () => {} });\nexport const reactContext = createReactContext();\n","import type {\n ConfigDirectorLogMessageDecorator,\n ConfigDirectorLoggingLevel,\n ConfigDirectorLogger,\n} from \"@js-browser-client/index\";\nimport { createDefaultLogger as createJsSdkLogger } from \"@js-browser-client/index\";\n\nclass LogMessageDecorator implements ConfigDirectorLogMessageDecorator {\n decorateMessage(message: string): string {\n return `[ConfigDirector:nextjs-sdk] ${message}`;\n }\n}\n\nexport const createConsoleLogger = (level: ConfigDirectorLoggingLevel): ConfigDirectorLogger => {\n return createJsSdkLogger(level, new LogMessageDecorator());\n};\n","\"use client\";\n\nimport { Component, useEffect, type PropsWithChildren } from \"react\";\nimport { createBrowserClient, type ConfigDirectorClient, type ConfigDirectorContext } from \"@js-browser-client/index\";\nimport { ClientHandlers } from \"@js-client-core/clientHandlers\";\nimport { readInstalledTestClient } from \"@js-client-core/installedTestClient\";\nimport { deepEqual } from \"@shared/deepEqual\";\nimport { decideGivenContextAction, decideStartupAction, startupPhaseAfter } from \"./client-startup\";\nimport type { StartupPhase } from \"./client-startup\";\nimport { reactContext } from \"./context\";\nimport { createConsoleLogger } from \"./logger\";\nimport type {\n ClientStatus,\n ConfigDirectorClientProviderProps,\n ConfigDirectorProviderOptions,\n ConfigDirectorProviderState,\n} from \"./types\";\n\nconst hasGivenClient = (props: ConfigDirectorClientProviderProps): props is { client: ConfigDirectorClient } =>\n \"client\" in props && props.client !== undefined;\n\nconst settledStatusOf = (client: ConfigDirectorClient): ClientStatus => (client.isReady ? \"ready\" : \"default\");\n\nconst decideWaitsForFirstContext = (props: ConfigDirectorClientProviderProps, ownsClient: boolean): boolean => {\n const runsOffline = ownsClient && !hasGivenClient(props) && props.mode === \"offline\";\n return props.deferInitialization === true && !runsOffline;\n};\n\nconst RunAfterFirstRenderEffects = ({ run }: { run: () => void }) => {\n useEffect(() => {\n run();\n }, [run]);\n return null;\n};\n\n/**\n * Initializes the ConfigDirector browser client and provides it to all descendant hooks.\n *\n * Place this in your root layout, wrapping your application. In most cases prefer the\n * `ConfigDirectorProvider` exported from `@configdirector/nextjs-sdk/server` — it is a React\n * Server Component that populates `initialConfigs` automatically, ensuring Client Components\n * render the correct values during SSR without any extra wiring.\n *\n * This component itself is a Client Component, so if you use it directly (rather than through\n * the server provider) any `sdkKey` sourced from `process.env` must use the `NEXT_PUBLIC_`\n * prefix — Next.js only exposes prefixed variables to code that runs in the browser.\n *\n * The browser client starts after the effects of the provider's first render, including its\n * children's, have run, with the latest context given by then: one given through `updateContext`\n * during those effects, otherwise the `context` prop. A context equal to the one the provider\n * already has, given through either, opens no new connection.\n *\n * Given a `client` prop, or while a test client is installed from\n * `@configdirector/nextjs-sdk/client/testing`, the provider provides that client from its first\n * render instead of building one, and never disposes it.\n */\nexport class ConfigDirectorProvider extends Component<\n PropsWithChildren<ConfigDirectorClientProviderProps>,\n ConfigDirectorProviderState\n> {\n private client: ConfigDirectorClient | undefined;\n private readonly ownsClient: boolean;\n private readonly waitsForFirstContext: boolean;\n private handlers: ClientHandlers | undefined;\n private startupPhase: StartupPhase = { kind: \"beforeFirstRenderEffects\" };\n private lastGivenContext: ConfigDirectorContext | undefined;\n\n constructor(props: PropsWithChildren<ConfigDirectorClientProviderProps>) {\n super(props);\n const givenClient = hasGivenClient(props) ? props.client : readInstalledTestClient();\n this.ownsClient = givenClient === undefined;\n this.waitsForFirstContext = decideWaitsForFirstContext(props, this.ownsClient);\n this.client = givenClient;\n this.lastGivenContext = props.context;\n this.state = givenClient\n ? { client: givenClient, status: givenClient.isReady ? \"ready\" : \"loading\" }\n : { status: \"loading\" };\n }\n\n private buildClient(): ConfigDirectorClient {\n const options = this.props as ConfigDirectorProviderOptions;\n return createBrowserClient(\n options.sdkKey,\n { sdkName: \"nextjs-sdk\", sdkVersion: \"__VERSION__\" },\n {\n connection: {\n url: options.url,\n timeout: options.timeout,\n mode: options.mode,\n pollingInterval: options.pollingInterval,\n values: options.values,\n },\n metadata: { appName: options.appName, appVersion: options.appVersion },\n logger: createConsoleLogger(options.logLevel ?? \"warn\"),\n hooks: options.hooks,\n },\n );\n }\n\n override componentDidMount(): void {\n let client = this.client;\n if (this.ownsClient) {\n client = this.buildClient();\n this.client = client;\n this.setState({ client });\n }\n if (!client) {\n return;\n }\n\n this.handlers = new ClientHandlers(client);\n this.handlers.on(\"configsUpdated\", () => {\n this.setState({ updatedAt: new Date() });\n });\n this.handlers.on(\"clientReady\", () => {\n this.setState({ status: \"ready\" });\n });\n if (!this.ownsClient) {\n this.handlers.registerHooks(this.props.hooks);\n }\n }\n\n private readonly startAfterFirstRenderEffects = (): void => {\n const client = this.client;\n if (!client) {\n return;\n }\n void this.startClient(client, this.lastGivenContext);\n };\n\n private async startClient(client: ConfigDirectorClient, context: ConfigDirectorContext | undefined): Promise<void> {\n const startupAction = decideStartupAction(client, context, this.waitsForFirstContext);\n this.startupPhase = startupPhaseAfter(startupAction, client);\n switch (startupAction) {\n case \"waitForContext\":\n return;\n case \"initialize\":\n await client.initialize(context);\n this.settleStatus(client);\n return;\n case \"updateContext\":\n await this.updateClientContext(client, context as ConfigDirectorContext);\n return;\n case \"none\":\n return;\n }\n }\n\n private async updateClientContext(client: ConfigDirectorClient, context: ConfigDirectorContext): Promise<void> {\n this.setState({ status: \"loading\" });\n await client.updateContext(context);\n this.settleStatus(client);\n }\n\n private settleStatus(client: ConfigDirectorClient): void {\n if (this.client === client) {\n this.setState({ status: settledStatusOf(client) });\n }\n }\n\n private readonly receiveContext = async (context: ConfigDirectorContext | undefined): Promise<void> => {\n const decision = decideGivenContextAction(this.startupPhase, this.lastGivenContext, context);\n switch (decision.action) {\n case \"skipUnchanged\":\n return;\n case \"keepForStartup\":\n this.lastGivenContext = context;\n return;\n case \"startClient\":\n this.lastGivenContext = context;\n await this.startClient(decision.client, context);\n return;\n case \"updateContext\":\n this.lastGivenContext = context;\n await this.updateClientContext(decision.client, context ?? {});\n return;\n }\n };\n\n override async componentDidUpdate(\n prevProps: PropsWithChildren<ConfigDirectorClientProviderProps>,\n ): Promise<void> {\n if (hasGivenClient(prevProps) && hasGivenClient(this.props) && prevProps.client !== this.props.client) {\n createConsoleLogger(\"warn\").warn(\n \"The client prop of ConfigDirectorProvider changed after it mounted and is ignored. Remount the provider, for example with a new key, to use another client.\",\n );\n }\n if (!deepEqual(prevProps.context, this.props.context)) {\n await this.receiveContext(this.props.context);\n }\n }\n\n override componentWillUnmount(): void {\n this.handlers?.removeAll();\n this.handlers = undefined;\n this.startupPhase = { kind: \"beforeFirstRenderEffects\" };\n this.lastGivenContext = this.props.context;\n if (this.ownsClient) {\n this.client?.dispose();\n this.client = undefined;\n }\n }\n\n override render() {\n return (\n <reactContext.Provider\n value={{ ...this.state, initialConfigs: this.props.initialConfigs, updateContext: this.receiveContext }}>\n {this.props.children}\n <RunAfterFirstRenderEffects run={this.startAfterFirstRenderEffects} />\n </reactContext.Provider>\n );\n }\n}\n","export class ConfigDirectorNextContextError extends Error {\n public override readonly name: string = \"ConfigDirectorNextContextError\";\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, ConfigDirectorNextContextError.prototype);\n }\n}\n","\"use client\";\n\nimport { useContext as useReactContext } from \"react\";\nimport { reactContext } from \"./context\";\nimport type { ConfigDirectorContext, ConfigValueType } from \"@js-browser-client/index\";\nimport { parseConfigValue } from \"@shared/value-parser\";\nimport { ConfigDirectorNextContextError } from \"./errors\";\nimport type { ClientStatus } from \"./types\";\n\nconst noContextError = () =>\n new ConfigDirectorNextContextError(\n \"The ConfigDirector client was not found in the React context. \" +\n \"Make sure the component using this hook is inside a <ConfigDirectorProvider>.\",\n );\n\n/**\n * Returns the evaluated value of a config key.\n *\n * During SSR and before the browser client finishes initializing, returns the value from\n * `initialConfigs` (if provided to the provider) to avoid a flash of wrong content on hydration.\n * Once the browser client is ready, returns live-evaluated values and re-renders whenever configs\n * change.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useConfigValue = <T extends ConfigValueType>(\n key: string,\n defaultValue: T,\n): { value: T; readyStatus: ClientStatus; loading: boolean } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n\n // The client is undefined during SSR and briefly during the first client render before componentDidMount\n // fires. Fall through to initialConfigs in both cases so the rendered output matches the server HTML,\n // avoiding a hydration mismatch.\n const initialConfigState = configDirectorReactContext.initialConfigs?.[key];\n const value = configDirectorReactContext.client?.isReady\n ? configDirectorReactContext.client.getValue(key, defaultValue)\n : initialConfigState\n ? parseConfigValue(initialConfigState, defaultValue).parsedValue\n : defaultValue;\n\n return {\n value,\n readyStatus: configDirectorReactContext.status,\n loading: configDirectorReactContext.status === \"loading\",\n };\n};\n\n/**\n * Returns an `updateContext` function to update the user context on the browser client.\n * Triggers re-evaluation of all watched config values.\n *\n * The function keeps one identity across renders, so it is safe in an effect's dependency list. A\n * call made before the browser client has started, for example from a mount effect, becomes the\n * context the client starts with, so the first connection carries it. A context equal to the one the\n * provider already has opens no new connection.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useContext = (): { updateContext: (context: ConfigDirectorContext) => Promise<void> } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n\n return { updateContext: configDirectorReactContext.updateContext };\n};\n\n/**\n * Returns the raw browser client for advanced use cases.\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useClient = () => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext?.client) throw noContextError();\n return { client: configDirectorReactContext.client };\n};\n\n/**\n * Returns the current connection status of the browser client.\n *\n * - `\"loading\"` — client is initializing\n * - `\"ready\"` — client received configs from the server, or loaded its offline values\n * - `\"default\"` — initialization timed out; hooks return default or initial values\n *\n * Must be used inside a `<ConfigDirectorProvider>`.\n */\nexport const useConfigDirectorStatus = (): { readyStatus: ClientStatus; loading: boolean } => {\n const configDirectorReactContext = useReactContext(reactContext);\n if (!configDirectorReactContext) throw noContextError();\n return {\n readyStatus: configDirectorReactContext.status,\n loading: configDirectorReactContext.status === \"loading\",\n };\n};\n"],"mappings":"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"}