@configdirector/nextjs-sdk 1.10.0 → 1.12.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 (59) hide show
  1. package/dist/client/index.cjs +1 -1
  2. package/dist/client/index.d.cts +56 -11
  3. package/dist/client/index.d.cts.map +1 -1
  4. package/dist/client/index.d.mts +56 -11
  5. package/dist/client/index.d.mts.map +1 -1
  6. package/dist/client/index.mjs +1 -1
  7. package/dist/client/index.mjs.map +1 -1
  8. package/dist/client/installedTestClient-DQXrptJI.cjs +6 -0
  9. package/dist/client/installedTestClient-DbyOjKoY.mjs +7 -0
  10. package/dist/client/installedTestClient-DbyOjKoY.mjs.map +1 -0
  11. package/dist/client/testing.cjs +1 -1
  12. package/dist/client/testing.d.cts +5 -14
  13. package/dist/client/testing.d.cts.map +1 -1
  14. package/dist/client/testing.d.mts +5 -14
  15. package/dist/client/testing.d.mts.map +1 -1
  16. package/dist/client/testing.mjs +1 -1
  17. package/dist/client/testing.mjs.map +1 -1
  18. package/dist/client/{types-De4z0tu4.d.mts → types-Daqe9IQD.d.cts} +31 -7
  19. package/dist/client/types-Daqe9IQD.d.cts.map +1 -0
  20. package/dist/client/{types-Cz68hQ6f.d.cts → types-HCeqxOKy.d.mts} +31 -7
  21. package/dist/client/types-HCeqxOKy.d.mts.map +1 -0
  22. package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs +6 -0
  23. package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs.map +1 -0
  24. package/dist/server/DefaultConfigDirectorClient-oT53aH0F.cjs +5 -0
  25. package/dist/server/{types-BBEEMV5Y.d.cts → errors-BLPDhdq2.d.mts} +114 -42
  26. package/dist/server/errors-BLPDhdq2.d.mts.map +1 -0
  27. package/dist/server/{types-B_mGbQaa.d.mts → errors-DuJpJeVf.d.cts} +114 -42
  28. package/dist/server/errors-DuJpJeVf.d.cts.map +1 -0
  29. package/dist/server/index.cjs +1 -1
  30. package/dist/server/index.d.cts +54 -9
  31. package/dist/server/index.d.cts.map +1 -1
  32. package/dist/server/index.d.mts +54 -9
  33. package/dist/server/index.d.mts.map +1 -1
  34. package/dist/server/index.mjs +1 -1
  35. package/dist/server/index.mjs.map +1 -1
  36. package/dist/server/native-values-CfqV9hAq.mjs +2 -0
  37. package/dist/server/native-values-CfqV9hAq.mjs.map +1 -0
  38. package/dist/server/native-values-UCK4hh1Z.cjs +1 -0
  39. package/dist/server/testing.cjs +1 -1
  40. package/dist/server/testing.d.cts +5 -25
  41. package/dist/server/testing.d.cts.map +1 -1
  42. package/dist/server/testing.d.mts +5 -25
  43. package/dist/server/testing.d.mts.map +1 -1
  44. package/dist/server/testing.mjs +1 -1
  45. package/dist/server/testing.mjs.map +1 -1
  46. package/package.json +1 -1
  47. package/dist/client/installedTestClient-CW29YuQC.cjs +0 -6
  48. package/dist/client/installedTestClient-CpjJvHZD.mjs +0 -7
  49. package/dist/client/installedTestClient-CpjJvHZD.mjs.map +0 -1
  50. package/dist/client/types-Cz68hQ6f.d.cts.map +0 -1
  51. package/dist/client/types-De4z0tu4.d.mts.map +0 -1
  52. package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs +0 -6
  53. package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs.map +0 -1
  54. package/dist/server/DefaultConfigDirectorClient-CqXqwNpW.cjs +0 -5
  55. package/dist/server/errors-BGpFuqOO.mjs +0 -2
  56. package/dist/server/errors-BGpFuqOO.mjs.map +0 -1
  57. package/dist/server/errors-CCbuIqT8.cjs +0 -1
  58. package/dist/server/types-BBEEMV5Y.d.cts.map +0 -1
  59. package/dist/server/types-B_mGbQaa.d.mts.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-CW29YuQC.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.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)}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let i={clientSdkKey:this.sdkKey,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(i))return{success:!0,fatalError:!1};let a=await this.sendReport(i);return a.fatalError&&(this.executeRequests=!1),a}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=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),y=e=>{try{self.postMessage(e)}catch{self.postMessage(v(e.payload.level,e.payload.message))}},b={debug:function(e,...t){y(v(`debug`,e,t))},info:function(e,...t){y(v(`info`,e,t))},warn:function(e,...t){y(v(`warn`,e,t))},error:function(e,...t){y(v(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){b.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(b.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){b.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:b}),_.start();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.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}}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,t,n)=>{let r=n?.logger??c.s(),i=c.o(n?.connection?.url)??`https://client-sdk-api.configdirector.com`;return new c.r(new p({sdkKey:e,sdkIdentity:{sdkName:t.sdkName,sdkVersion:t.sdkVersion},metaContext:{appName:n?.metadata?.appName,appVersion:n?.metadata?.appVersion},logger:r,baseUrl:i,urlFactory:c.a,valueIdGenerator:_}),e,t,{...n,logger:r})};var y=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 b=(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)=>b(e,t[n]));if(!x(e)||!x(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)&&b(e[n],t[n]))},x=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},S=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!b(t,e.context)?`updateContext`:`none`:`initialize`,C=l.default.createContext({status:`loading`});var w=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const T=e=>c.s(e,new w),E=e=>`client`in e&&e.client!==void 0;var D=class extends l.Component{constructor(e){super(e);let t=E(e)?e.client:c.n();this.ownsClient=t===void 0,this.client=t,this.state=t?{client:t,status:t.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){let e=this.props;return v(e.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},{connection:{url:e.url,timeout:e.timeout,mode:e.mode,pollingInterval:e.pollingInterval},metadata:{appName:e.appName,appVersion:e.appVersion},logger:T(e.logLevel??`warn`),hooks:e.hooks})}async componentDidMount(){let e=this.client;this.ownsClient&&(e=this.buildClient(),this.client=e,this.setState({client:e})),e&&(this.handlers=new y(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),await this.connect(e,this.props.context))}async connect(e,t){switch(S(e,t)){case`initialize`:await e.initialize(t);break;case`updateContext`:this.setState({status:`loading`}),await e.updateContext(t);break;case`none`:return}this.client===e&&!e.isReady&&this.setState({status:`default`})}async componentDidUpdate(e){if(E(e)&&E(this.props)&&e.client!==this.props.client&&T(`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.`),!b(e.context,this.props.context)){let e=this.client;if(!e)return;this.setState({status:`loading`}),await e.updateContext(this.props.context??{}),this.client===e&&!e.isReady&&this.setState({status:`default`})}}componentWillUnmount(){this.handlers?.removeAll(),this.handlers=void 0,this.ownsClient&&this.client?.dispose(),this.client=void 0}render(){return(0,u.jsx)(C.Provider,{value:{...this.state,initialConfigs:this.props.initialConfigs},children:this.props.children})}},O=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const k=()=>new O(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),A=(e,t)=>{let n=(0,l.useContext)(C);if(!n)throw k();let r=n.initialConfigs?.[e];return{value:n.client?.isReady?n.client.getValue(e,t):r?c.c(r,t).parsedValue:t,readyStatus:n.status,loading:n.status===`loading`}},j=()=>{let e=(0,l.useContext)(C);if(!e)throw k();return{updateContext:async t=>{await e.client?.updateContext(t)}}},M=()=>{let e=(0,l.useContext)(C);if(!e?.client)throw k();return{client:e.client}},N=()=>{let e=(0,l.useContext)(C);if(!e)throw k();return{readyStatus:e.status,loading:e.status===`loading`}};exports.ConfigDirectorNextContextError=O,exports.ConfigDirectorProvider=D,exports.createConsoleLogger=T,exports.useClient=M,exports.useConfigDirectorStatus=N,exports.useConfigValue=A,exports.useContext=j;
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-DQXrptJI.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.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)}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let i={clientSdkKey:this.sdkKey,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(i))return{success:!0,fatalError:!1};let a=await this.sendReport(i);return a.fatalError&&(this.executeRequests=!1),a}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=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),y=e=>{try{self.postMessage(e)}catch{self.postMessage(v(e.payload.level,e.payload.message))}},b={debug:function(e,...t){y(v(`debug`,e,t))},info:function(e,...t){y(v(`info`,e,t))},warn:function(e,...t){y(v(`warn`,e,t))},error:function(e,...t){y(v(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){b.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(b.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){b.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:b}),_.start();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.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}}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=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),y=async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return c.i+v(new Uint8Array(t))},b=()=>typeof crypto<`u`&&crypto.subtle!=null,x=e=>{let t=c.o();if(!t||!b())return;let n=y(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}},S=(e,t,n)=>c.r.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i})=>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:_}),e,t,n,{platformCachingProvider:x});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.12.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 { a as ConfigDirectorLoggingLevel, c as ConnectionMode, i as ConfigDirectorLogger, n as ConfigDirectorClient, o as ConfigState, r as ConfigDirectorContext, s as ConfigValueType, t as ClientHooks } from "./types-Cz68hQ6f.cjs";
2
+ import { c as ConfigDirectorContext, d as ConfigState, f as ConfigValueType, i as OfflineValues, l as ConfigDirectorLogger, n as ConfigDirectorClient, p as ConnectionMode, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel } from "./types-Daqe9IQD.cjs";
3
3
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
4
4
  import { Component, PropsWithChildren } from "react";
5
5
 
@@ -10,13 +10,15 @@ interface ConfigDirectorContextData {
10
10
  updatedAt?: Date;
11
11
  status: ClientStatus;
12
12
  initialConfigs?: Record<string, ConfigState>;
13
+ updateContext: (context: ConfigDirectorContext) => Promise<void>;
13
14
  }
14
- type ConfigDirectorProviderState = Omit<ConfigDirectorContextData, "initialConfigs">;
15
+ type ConfigDirectorProviderState = Omit<ConfigDirectorContextData, "initialConfigs" | "updateContext">;
15
16
  type ConfigDirectorProviderOptions = {
16
17
  /**
17
- * Your ConfigDirector Client SDK key. This is a public value safe for the browser.
18
+ * Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
19
+ * unless `mode` is `offline`.
18
20
  */
19
- sdkKey: string;
21
+ sdkKey?: string;
20
22
  appName?: string;
21
23
  appVersion?: string;
22
24
  /**
@@ -28,11 +30,23 @@ type ConfigDirectorProviderOptions = {
28
30
  */
29
31
  timeout?: number;
30
32
  /**
31
- * The connection mode, one of `streaming` or `polling`. In `streaming` mode the connection stays
32
- * open and receives config updates as they happen. In `polling` mode configs are fetched once during
33
- * initialization and then again on every `pollingInterval`. Defaults to `streaming`.
33
+ * The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
34
+ * stays open and receives config updates as they happen. In `polling` mode configs are fetched once
35
+ * during initialization and then again on every `pollingInterval`. In `offline` mode the browser
36
+ * client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
37
+ * or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
38
+ *
39
+ * The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
40
+ * `offline` mode and you give neither prop.
34
41
  */
35
42
  mode?: ConnectionMode;
43
+ /**
44
+ * The values to serve in `offline` mode, keyed by config key. The config type of each value follows
45
+ * from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
46
+ * a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
47
+ * to initialize.
48
+ */
49
+ values?: OfflineValues;
36
50
  /**
37
51
  * The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
38
52
  * Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
@@ -43,6 +57,14 @@ type ConfigDirectorProviderOptions = {
43
57
  * Initial user context to evaluate targeting rules against.
44
58
  */
45
59
  context?: ConfigDirectorContext;
60
+ /**
61
+ * Holds the browser connection until the provider is given a context, through the `context` prop
62
+ * or through `updateContext` from the `useContext` hook. Until then nothing connects and nothing is
63
+ * sent, `useConfigDirectorStatus` reports `loading`, and the hooks serve `initialConfigs` or the
64
+ * in-code default values. The first context opens one connection carrying it; a page that never
65
+ * gives a context never connects. Defaults to `false`. Has no effect in `offline` mode.
66
+ */
67
+ deferInitialization?: boolean;
46
68
  /**
47
69
  * Log level for the console logger. Defaults to "warn".
48
70
  */
@@ -73,6 +95,12 @@ type ConfigDirectorClientProviderClientProps = {
73
95
  */
74
96
  client: ConfigDirectorClient;
75
97
  context?: ConfigDirectorContext;
98
+ /**
99
+ * Leaves a client that is neither ready nor initializing untouched until the provider is given a
100
+ * context, through the `context` prop or through `updateContext`; the first context initializes
101
+ * it. Defaults to `false`.
102
+ */
103
+ deferInitialization?: boolean;
76
104
  /**
77
105
  * Event handlers registered on the client while the provider is mounted, and removed when it
78
106
  * unmounts.
@@ -102,6 +130,11 @@ type ConfigDirectorClientProviderProps = ConfigDirectorProviderOptions | ConfigD
102
130
  * the server provider) any `sdkKey` sourced from `process.env` must use the `NEXT_PUBLIC_`
103
131
  * prefix — Next.js only exposes prefixed variables to code that runs in the browser.
104
132
  *
133
+ * The browser client starts after the effects of the provider's first render, including its
134
+ * children's, have run, with the latest context given by then: one given through `updateContext`
135
+ * during those effects, otherwise the `context` prop. A context equal to the one the provider
136
+ * already has, given through either, opens no new connection.
137
+ *
105
138
  * Given a `client` prop, or while a test client is installed from
106
139
  * `@configdirector/nextjs-sdk/client/testing`, the provider provides that client from its first
107
140
  * render instead of building one, and never disposes it.
@@ -109,11 +142,18 @@ type ConfigDirectorClientProviderProps = ConfigDirectorProviderOptions | ConfigD
109
142
  declare class ConfigDirectorProvider extends Component<PropsWithChildren<ConfigDirectorClientProviderProps>, ConfigDirectorProviderState> {
110
143
  private client;
111
144
  private readonly ownsClient;
145
+ private readonly waitsForFirstContext;
112
146
  private handlers;
147
+ private startupPhase;
148
+ private lastGivenContext;
113
149
  constructor(props: PropsWithChildren<ConfigDirectorClientProviderProps>);
114
150
  private buildClient;
115
- componentDidMount(): Promise<void>;
116
- private connect;
151
+ componentDidMount(): void;
152
+ private readonly startAfterFirstRenderEffects;
153
+ private startClient;
154
+ private updateClientContext;
155
+ private settleStatus;
156
+ private readonly receiveContext;
117
157
  componentDidUpdate(prevProps: PropsWithChildren<ConfigDirectorClientProviderProps>): Promise<void>;
118
158
  componentWillUnmount(): void;
119
159
  render(): _$react_jsx_runtime0.JSX.Element;
@@ -139,6 +179,11 @@ declare const useConfigValue: <T extends ConfigValueType>(key: string, defaultVa
139
179
  * Returns an `updateContext` function to update the user context on the browser client.
140
180
  * Triggers re-evaluation of all watched config values.
141
181
  *
182
+ * The function keeps one identity across renders, so it is safe in an effect's dependency list. A
183
+ * call made before the browser client has started, for example from a mount effect, becomes the
184
+ * context the client starts with, so the first connection carries it. A context equal to the one the
185
+ * provider already has opens no new connection.
186
+ *
142
187
  * Must be used inside a `<ConfigDirectorProvider>`.
143
188
  */
144
189
  declare const useContext: () => {
@@ -156,7 +201,7 @@ declare const useClient: () => {
156
201
  * Returns the current connection status of the browser client.
157
202
  *
158
203
  * - `"loading"` — client is initializing
159
- * - `"ready"` — client received configs from the server
204
+ * - `"ready"` — client received configs from the server, or loaded its offline values
160
205
  * - `"default"` — initialization timed out; hooks return default or initial values
161
206
  *
162
207
  * Must be used inside a `<ConfigDirectorProvider>`.
@@ -175,5 +220,5 @@ declare class ConfigDirectorNextContextError extends Error {
175
220
  constructor(message: string);
176
221
  }
177
222
  //#endregion
178
- export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigValueType, type ConnectionMode, 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 ConfigValueType, type ConnectionMode, type OfflineValue, type OfflineValues, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
179
224
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/client/types.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/hooks.tsx","../../src/client/logger.ts","../../src/client/errors.ts"],"mappings":";;;;;;KAWY,YAAA;AAAA,UAEK,yBAAA;EACf,MAAA,GAAS,oBAAA;EACT,SAAA,GAAY,IAAA;EACZ,MAAA,EAAQ,YAAA;EACR,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;AAAA,KAGtB,2BAAA,GAA8B,IAAA,CAAK,yBAAA;AAAA,KAEnC,6BAAA;;;;EAIV,MAAA;EACA,OAAA;EACA,UAAA;EAXuB;;;EAevB,GAAA;EAjBA;;;EAqBA,OAAA;EAnBA;;;;;EAyBA,IAAA,GAAO,cAAA;EAtB8B;;;;AAEvC;EA0BE,eAAA;;;;EAIA,OAAA,GAAU,qBAAA;EAMF;;;EAFR,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;EAhCR;;;;;;;;;;EA2CA,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,uCAAA;EAPiC;;AAO7C;;;;EAOE,MAAA,EAAQ,oBAAA;EACR,OAAA,GAAU,qBAAA;EASsB;;;;EAJhC,KAAA,GAAQ,WAAA;EANA;;;EAUR,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,iCAAA,GAAoC,6BAAA,GAAgC,uCAAA;;;;;;AAzFhF;;;;;AAEA;;;;;;;;cCsBa,sBAAA,SAA+B,SAAA,CAC1C,iBAAA,CAAkB,iCAAA,GAClB,2BAAA;EAAA,QAEQ,MAAA;EAAA,iBACS,UAAA;EAAA,QACT,QAAA;cAEI,KAAA,EAAO,iBAAA,CAAkB,iCAAA;EAAA,QAU7B,WAAA;EAmBO,iBAAA,CAAA,GAAqB,OAAA;EAAA,QAwBtB,OAAA;EAiBC,kBAAA,CACb,SAAA,EAAW,iBAAA,CAAkB,iCAAA,IAC5B,OAAA;EAiBM,oBAAA,CAAA;EASA,MAAA,CAAA,GAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;;;;;;ADlIjB;;;;;AAEA;;cEYa,cAAA,aAA4B,eAAA,EACvC,GAAA,UACA,YAAA,EAAc,CAAA;EACX,KAAA,EAAO,CAAA;EAAG,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;;;;;cA2B7B,UAAA;EAAmB,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;;;;;;cAiBtE,SAAA;UAIZ,oBAAA;AAAA;;;AFtDD;;;;;;;cEiEa,uBAAA;EAAgC,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;cC1E3D,mBAAA,GAAuB,KAAA,EAAO,0BAAA,KAA6B,oBAAA;;;cCb3D,8BAAA,SAAuC,KAAA;EAAA,SACzB,IAAA;cAEb,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../../src/client/types.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/hooks.tsx","../../src/client/logger.ts","../../src/client/errors.ts"],"mappings":";;;;;;KAaY,YAAA;AAAA,UAEK,yBAAA;EACf,MAAA,GAAS,oBAAA;EACT,SAAA,GAAY,IAAA;EACZ,MAAA,EAAQ,YAAA;EACR,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;AAAA,KAGzC,2BAAA,GAA8B,IAAA,CAAK,yBAAA;AAAA,KAEnC,6BAAA;EATD;;;;EAcT,MAAA;EACA,OAAA;EACA,UAAA;EAZ0D;;;EAgB1D,GAAA;EAnBA;;;EAuBA,OAAA;EArBA;;;;;;;;;AAIF;EA4BE,IAAA,GAAO,cAAA;;;;AA1BT;;;EAiCE,MAAA,GAAS,aAAA;EAAA;;;;;EAMT,eAAA;EA6BuB;;;EAzBvB,OAAA,GAAU,qBAAA;EApCV;;;;;;;EA4CA,mBAAA;EARA;;;EAYA,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;EAAR;;;;;;;AAkBF;;;EAPE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,uCAAA;EAOV;;;;;;EAAA,MAAA,EAAQ,oBAAA;EACR,OAAA,GAAU,qBAAA;EAeO;;;;AAOnB;EAhBE,mBAAA;;;;;EAKA,KAAA,GAAQ,WAAA;;AC/DV;;EDmEE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,iCAAA,GAAoC,6BAAA,GAAgC,uCAAA;;;;;;AArHhF;;;;;AAEA;;;;;;;;;;;;;cCyCa,sBAAA,SAA+B,SAAA,CAC1C,iBAAA,CAAkB,iCAAA,GAClB,2BAAA;EAAA,QAEQ,MAAA;EAAA,iBACS,UAAA;EAAA,iBACA,oBAAA;EAAA,QACT,QAAA;EAAA,QACA,YAAA;EAAA,QACA,gBAAA;cAEI,KAAA,EAAO,iBAAA,CAAkB,iCAAA;EAAA,QAY7B,WAAA;EAoBC,iBAAA,CAAA;EAAA,iBAuBQ,4BAAA;EAAA,QAQH,WAAA;EAAA,QAkBA,mBAAA;EAAA,QAMN,YAAA;EAAA,iBAMS,cAAA;EAmBF,kBAAA,CACb,SAAA,EAAW,iBAAA,CAAkB,iCAAA,IAC5B,OAAA;EAWM,oBAAA,CAAA;EAWA,MAAA,CAAA,GAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;;;;;;AD9LjB;;;;;AAEA;;cEUa,cAAA,aAA4B,eAAA,EACvC,GAAA,UACA,YAAA,EAAc,CAAA;EACX,KAAA,EAAO,CAAA;EAAG,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;;;;;;;;;;cAgC7B,UAAA;EAAmB,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;;;;;;cAYtE,SAAA;UAIZ,oBAAA;AAAA;;;;AFnDD;;;;;;cE8Da,uBAAA;EAAgC,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;cC1E3D,mBAAA,GAAuB,KAAA,EAAO,0BAAA,KAA6B,oBAAA;;;cCb3D,8BAAA,SAAuC,KAAA;EAAA,SACzB,IAAA;cAEb,OAAA;AAAA"}
@@ -1,5 +1,5 @@
1
1
 
2
- import { a as ConfigDirectorLoggingLevel, c as ConnectionMode, i as ConfigDirectorLogger, n as ConfigDirectorClient, o as ConfigState, r as ConfigDirectorContext, s as ConfigValueType, t as ClientHooks } from "./types-De4z0tu4.mjs";
2
+ import { c as ConfigDirectorContext, d as ConfigState, f as ConfigValueType, i as OfflineValues, l as ConfigDirectorLogger, n as ConfigDirectorClient, p as ConnectionMode, r as OfflineValue, t as ClientHooks, u as ConfigDirectorLoggingLevel } from "./types-HCeqxOKy.mjs";
3
3
  import { Component, PropsWithChildren } from "react";
4
4
  import * as _$react_jsx_runtime0 from "react/jsx-runtime";
5
5
 
@@ -10,13 +10,15 @@ interface ConfigDirectorContextData {
10
10
  updatedAt?: Date;
11
11
  status: ClientStatus;
12
12
  initialConfigs?: Record<string, ConfigState>;
13
+ updateContext: (context: ConfigDirectorContext) => Promise<void>;
13
14
  }
14
- type ConfigDirectorProviderState = Omit<ConfigDirectorContextData, "initialConfigs">;
15
+ type ConfigDirectorProviderState = Omit<ConfigDirectorContextData, "initialConfigs" | "updateContext">;
15
16
  type ConfigDirectorProviderOptions = {
16
17
  /**
17
- * Your ConfigDirector Client SDK key. This is a public value safe for the browser.
18
+ * Your ConfigDirector Client SDK key. This is a public value safe for the browser. Required
19
+ * unless `mode` is `offline`.
18
20
  */
19
- sdkKey: string;
21
+ sdkKey?: string;
20
22
  appName?: string;
21
23
  appVersion?: string;
22
24
  /**
@@ -28,11 +30,23 @@ type ConfigDirectorProviderOptions = {
28
30
  */
29
31
  timeout?: number;
30
32
  /**
31
- * The connection mode, one of `streaming` or `polling`. In `streaming` mode the connection stays
32
- * open and receives config updates as they happen. In `polling` mode configs are fetched once during
33
- * initialization and then again on every `pollingInterval`. Defaults to `streaming`.
33
+ * The connection mode, one of `streaming`, `polling` or `offline`. In `streaming` mode the connection
34
+ * stays open and receives config updates as they happen. In `polling` mode configs are fetched once
35
+ * during initialization and then again on every `pollingInterval`. In `offline` mode the browser
36
+ * client never connects to ConfigDirector and sends nothing: it serves `values` to every context,
37
+ * or the in-code default values when none are given, and needs no `sdkKey`. Defaults to `streaming`.
38
+ *
39
+ * The server `ConfigDirectorProvider` sets `offline` and `values` for you when `register()` ran in
40
+ * `offline` mode and you give neither prop.
34
41
  */
35
42
  mode?: ConnectionMode;
43
+ /**
44
+ * The values to serve in `offline` mode, keyed by config key. The config type of each value follows
45
+ * from the value: a boolean, an integral number (`integer`), any other number (`float`), a string, or
46
+ * a plain object or array (`json`). Can be given only in `offline` mode; otherwise the client fails
47
+ * to initialize.
48
+ */
49
+ values?: OfflineValues;
36
50
  /**
37
51
  * The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
38
52
  * Defaults to 60 seconds. A value below the minimum of 30 seconds is raised to 30 seconds and a
@@ -43,6 +57,14 @@ type ConfigDirectorProviderOptions = {
43
57
  * Initial user context to evaluate targeting rules against.
44
58
  */
45
59
  context?: ConfigDirectorContext;
60
+ /**
61
+ * Holds the browser connection until the provider is given a context, through the `context` prop
62
+ * or through `updateContext` from the `useContext` hook. Until then nothing connects and nothing is
63
+ * sent, `useConfigDirectorStatus` reports `loading`, and the hooks serve `initialConfigs` or the
64
+ * in-code default values. The first context opens one connection carrying it; a page that never
65
+ * gives a context never connects. Defaults to `false`. Has no effect in `offline` mode.
66
+ */
67
+ deferInitialization?: boolean;
46
68
  /**
47
69
  * Log level for the console logger. Defaults to "warn".
48
70
  */
@@ -73,6 +95,12 @@ type ConfigDirectorClientProviderClientProps = {
73
95
  */
74
96
  client: ConfigDirectorClient;
75
97
  context?: ConfigDirectorContext;
98
+ /**
99
+ * Leaves a client that is neither ready nor initializing untouched until the provider is given a
100
+ * context, through the `context` prop or through `updateContext`; the first context initializes
101
+ * it. Defaults to `false`.
102
+ */
103
+ deferInitialization?: boolean;
76
104
  /**
77
105
  * Event handlers registered on the client while the provider is mounted, and removed when it
78
106
  * unmounts.
@@ -102,6 +130,11 @@ type ConfigDirectorClientProviderProps = ConfigDirectorProviderOptions | ConfigD
102
130
  * the server provider) any `sdkKey` sourced from `process.env` must use the `NEXT_PUBLIC_`
103
131
  * prefix — Next.js only exposes prefixed variables to code that runs in the browser.
104
132
  *
133
+ * The browser client starts after the effects of the provider's first render, including its
134
+ * children's, have run, with the latest context given by then: one given through `updateContext`
135
+ * during those effects, otherwise the `context` prop. A context equal to the one the provider
136
+ * already has, given through either, opens no new connection.
137
+ *
105
138
  * Given a `client` prop, or while a test client is installed from
106
139
  * `@configdirector/nextjs-sdk/client/testing`, the provider provides that client from its first
107
140
  * render instead of building one, and never disposes it.
@@ -109,11 +142,18 @@ type ConfigDirectorClientProviderProps = ConfigDirectorProviderOptions | ConfigD
109
142
  declare class ConfigDirectorProvider extends Component<PropsWithChildren<ConfigDirectorClientProviderProps>, ConfigDirectorProviderState> {
110
143
  private client;
111
144
  private readonly ownsClient;
145
+ private readonly waitsForFirstContext;
112
146
  private handlers;
147
+ private startupPhase;
148
+ private lastGivenContext;
113
149
  constructor(props: PropsWithChildren<ConfigDirectorClientProviderProps>);
114
150
  private buildClient;
115
- componentDidMount(): Promise<void>;
116
- private connect;
151
+ componentDidMount(): void;
152
+ private readonly startAfterFirstRenderEffects;
153
+ private startClient;
154
+ private updateClientContext;
155
+ private settleStatus;
156
+ private readonly receiveContext;
117
157
  componentDidUpdate(prevProps: PropsWithChildren<ConfigDirectorClientProviderProps>): Promise<void>;
118
158
  componentWillUnmount(): void;
119
159
  render(): _$react_jsx_runtime0.JSX.Element;
@@ -139,6 +179,11 @@ declare const useConfigValue: <T extends ConfigValueType>(key: string, defaultVa
139
179
  * Returns an `updateContext` function to update the user context on the browser client.
140
180
  * Triggers re-evaluation of all watched config values.
141
181
  *
182
+ * The function keeps one identity across renders, so it is safe in an effect's dependency list. A
183
+ * call made before the browser client has started, for example from a mount effect, becomes the
184
+ * context the client starts with, so the first connection carries it. A context equal to the one the
185
+ * provider already has opens no new connection.
186
+ *
142
187
  * Must be used inside a `<ConfigDirectorProvider>`.
143
188
  */
144
189
  declare const useContext: () => {
@@ -156,7 +201,7 @@ declare const useClient: () => {
156
201
  * Returns the current connection status of the browser client.
157
202
  *
158
203
  * - `"loading"` — client is initializing
159
- * - `"ready"` — client received configs from the server
204
+ * - `"ready"` — client received configs from the server, or loaded its offline values
160
205
  * - `"default"` — initialization timed out; hooks return default or initial values
161
206
  *
162
207
  * Must be used inside a `<ConfigDirectorProvider>`.
@@ -175,5 +220,5 @@ declare class ConfigDirectorNextContextError extends Error {
175
220
  constructor(message: string);
176
221
  }
177
222
  //#endregion
178
- export { type ClientStatus, type ConfigDirectorClient, type ConfigDirectorClientProviderClientProps, type ConfigDirectorClientProviderProps, type ConfigDirectorContext, type ConfigDirectorLogger, type ConfigDirectorLoggingLevel, ConfigDirectorNextContextError, ConfigDirectorProvider, type ConfigDirectorProviderOptions, type ConfigValueType, type ConnectionMode, 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 ConfigValueType, type ConnectionMode, type OfflineValue, type OfflineValues, createConsoleLogger, useClient, useConfigDirectorStatus, useConfigValue, useContext };
179
224
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/client/types.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/hooks.tsx","../../src/client/logger.ts","../../src/client/errors.ts"],"mappings":";;;;;;KAWY,YAAA;AAAA,UAEK,yBAAA;EACf,MAAA,GAAS,oBAAA;EACT,SAAA,GAAY,IAAA;EACZ,MAAA,EAAQ,YAAA;EACR,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;AAAA,KAGtB,2BAAA,GAA8B,IAAA,CAAK,yBAAA;AAAA,KAEnC,6BAAA;;;;EAIV,MAAA;EACA,OAAA;EACA,UAAA;EAXuB;;;EAevB,GAAA;EAjBA;;;EAqBA,OAAA;EAnBA;;;;;EAyBA,IAAA,GAAO,cAAA;EAtB8B;;;;AAEvC;EA0BE,eAAA;;;;EAIA,OAAA,GAAU,qBAAA;EAMF;;;EAFR,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;EAhCR;;;;;;;;;;EA2CA,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,uCAAA;EAPiC;;AAO7C;;;;EAOE,MAAA,EAAQ,oBAAA;EACR,OAAA,GAAU,qBAAA;EASsB;;;;EAJhC,KAAA,GAAQ,WAAA;EANA;;;EAUR,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,iCAAA,GAAoC,6BAAA,GAAgC,uCAAA;;;;;;AAzFhF;;;;;AAEA;;;;;;;;cCsBa,sBAAA,SAA+B,SAAA,CAC1C,iBAAA,CAAkB,iCAAA,GAClB,2BAAA;EAAA,QAEQ,MAAA;EAAA,iBACS,UAAA;EAAA,QACT,QAAA;cAEI,KAAA,EAAO,iBAAA,CAAkB,iCAAA;EAAA,QAU7B,WAAA;EAmBO,iBAAA,CAAA,GAAqB,OAAA;EAAA,QAwBtB,OAAA;EAiBC,kBAAA,CACb,SAAA,EAAW,iBAAA,CAAkB,iCAAA,IAC5B,OAAA;EAiBM,oBAAA,CAAA;EASA,MAAA,CAAA,GAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;;;;;;ADlIjB;;;;;AAEA;;cEYa,cAAA,aAA4B,eAAA,EACvC,GAAA,UACA,YAAA,EAAc,CAAA;EACX,KAAA,EAAO,CAAA;EAAG,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;;;;;cA2B7B,UAAA;EAAmB,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;;;;;;cAiBtE,SAAA;UAIZ,oBAAA;AAAA;;;AFtDD;;;;;;;cEiEa,uBAAA;EAAgC,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;cC1E3D,mBAAA,GAAuB,KAAA,EAAO,0BAAA,KAA6B,oBAAA;;;cCb3D,8BAAA,SAAuC,KAAA;EAAA,SACzB,IAAA;cAEb,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/client/types.ts","../../src/client/ConfigDirectorProvider.tsx","../../src/client/hooks.tsx","../../src/client/logger.ts","../../src/client/errors.ts"],"mappings":";;;;;;KAaY,YAAA;AAAA,UAEK,yBAAA;EACf,MAAA,GAAS,oBAAA;EACT,SAAA,GAAY,IAAA;EACZ,MAAA,EAAQ,YAAA;EACR,cAAA,GAAiB,MAAA,SAAe,WAAA;EAChC,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;AAAA,KAGzC,2BAAA,GAA8B,IAAA,CAAK,yBAAA;AAAA,KAEnC,6BAAA;EATD;;;;EAcT,MAAA;EACA,OAAA;EACA,UAAA;EAZ0D;;;EAgB1D,GAAA;EAnBA;;;EAuBA,OAAA;EArBA;;;;;;;;;AAIF;EA4BE,IAAA,GAAO,cAAA;;;;AA1BT;;;EAiCE,MAAA,GAAS,aAAA;EAAA;;;;;EAMT,eAAA;EA6BuB;;;EAzBvB,OAAA,GAAU,qBAAA;EApCV;;;;;;;EA4CA,mBAAA;EARA;;;EAYA,QAAA,GAAW,0BAAA;EAEX,KAAA,GAAQ,WAAA;EAAR;;;;;;;AAkBF;;;EAPE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,uCAAA;EAOV;;;;;;EAAA,MAAA,EAAQ,oBAAA;EACR,OAAA,GAAU,qBAAA;EAeO;;;;AAOnB;EAhBE,mBAAA;;;;;EAKA,KAAA,GAAQ,WAAA;;AC/DV;;EDmEE,cAAA,GAAiB,MAAA,SAAe,WAAA;AAAA;;;;;KAOtB,iCAAA,GAAoC,6BAAA,GAAgC,uCAAA;;;;;;AArHhF;;;;;AAEA;;;;;;;;;;;;;cCyCa,sBAAA,SAA+B,SAAA,CAC1C,iBAAA,CAAkB,iCAAA,GAClB,2BAAA;EAAA,QAEQ,MAAA;EAAA,iBACS,UAAA;EAAA,iBACA,oBAAA;EAAA,QACT,QAAA;EAAA,QACA,YAAA;EAAA,QACA,gBAAA;cAEI,KAAA,EAAO,iBAAA,CAAkB,iCAAA;EAAA,QAY7B,WAAA;EAoBC,iBAAA,CAAA;EAAA,iBAuBQ,4BAAA;EAAA,QAQH,WAAA;EAAA,QAkBA,mBAAA;EAAA,QAMN,YAAA;EAAA,iBAMS,cAAA;EAmBF,kBAAA,CACb,SAAA,EAAW,iBAAA,CAAkB,iCAAA,IAC5B,OAAA;EAWM,oBAAA,CAAA;EAWA,MAAA,CAAA,GAAM,oBAAA,CAAA,GAAA,CAAA,OAAA;AAAA;;;;;;AD9LjB;;;;;AAEA;;cEUa,cAAA,aAA4B,eAAA,EACvC,GAAA,UACA,YAAA,EAAc,CAAA;EACX,KAAA,EAAO,CAAA;EAAG,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;;;;;;;;;;cAgC7B,UAAA;EAAmB,aAAA,GAAgB,OAAA,EAAS,qBAAA,KAA0B,OAAA;AAAA;;;;;;cAYtE,SAAA;UAIZ,oBAAA;AAAA;;;;AFnDD;;;;;;cE8Da,uBAAA;EAAgC,WAAA,EAAa,YAAA;EAAc,OAAA;AAAA;;;cC1E3D,mBAAA,GAAuB,KAAA,EAAO,0BAAA,KAA6B,oBAAA;;;cCb3D,8BAAA,SAAuC,KAAA;EAAA,SACzB,IAAA;cAEb,OAAA;AAAA"}
@@ -1,3 +1,3 @@
1
1
  "use client";
2
- import{a as e,c as t,i as n,l as r,n as i,o as a,r as o,s}from"./installedTestClient-CpjJvHZD.mjs";import c,{Component as l,useContext as u}from"react";import{jsx as d}from"react/jsx-runtime";const f=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 p=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}},m=class{constructor(e){var t,n,r,i;this.turnedOff=!1,this.pendingEvaluations=[],this.pendingInvalidContextSubmissions=new p,this.logger=e.logger,this.workerCloseTimeout=(t=e.workerCloseTimeout)==null?6e3:t,this.pendingEvaluationLimit=(n=e.evaluationQueueLimit)==null?1e3:n,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)}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let i={clientSdkKey:this.sdkKey,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(i))return{success:!0,fatalError:!1};let a=await this.sendReport(i);return a.fatalError&&(this.executeRequests=!1),a}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=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),y=e=>{try{self.postMessage(e)}catch{self.postMessage(v(e.payload.level,e.payload.message))}},b={debug:function(e,...t){y(v(`debug`,e,t))},info:function(e,...t){y(v(`info`,e,t))},warn:function(e,...t){y(v(`warn`,e,t))},error:function(e,...t){y(v(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){b.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(b.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){b.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:b}),_.start();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.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}}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 r(r({},e),{},{defaultValue:f({value:e.defaultValue,type:e.type}),evaluatedValue:f({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 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=>{var t;if(typeof crypto>`u`||crypto.subtle==null)return;let n=await crypto.subtle.digest(`SHA-256`,_.encode((t=e==null?void 0:e.toString())==null?``:t));return h(new Uint8Array(n,0,16),g)},y=(t,i,c)=>{var l,u,d,f,p;let h=(l=c==null?void 0:c.logger)==null?s():l,g=(u=a(c==null||(d=c.connection)==null?void 0:d.url))==null?n:u;return new o(new m({sdkKey:t,sdkIdentity:{sdkName:i.sdkName,sdkVersion:i.sdkVersion},metaContext:{appName:c==null||(f=c.metadata)==null?void 0:f.appName,appVersion:c==null||(p=c.metadata)==null?void 0:p.appVersion},logger:h,baseUrl:g,urlFactory:e,valueIdGenerator:v}),t,i,r(r({},c),{},{logger:h}))};var b=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 x=(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)=>x(e,t[n]));if(!S(e)||!S(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)&&x(e[n],t[n]))},S=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},C=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!x(t,e.context)?`updateContext`:`none`:`initialize`,w=c.createContext({status:`loading`});var T=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const E=e=>s(e,new T),D=e=>`client`in e&&e.client!==void 0;var O=class extends l{constructor(e){super(e);let t=D(e)?e.client:i();this.ownsClient=t===void 0,this.client=t,this.state=t?{client:t,status:t.isReady?`ready`:`loading`}:{status:`loading`}}buildClient(){var e;let t=this.props;return y(t.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.10.0`},{connection:{url:t.url,timeout:t.timeout,mode:t.mode,pollingInterval:t.pollingInterval},metadata:{appName:t.appName,appVersion:t.appVersion},logger:E((e=t.logLevel)==null?`warn`:e),hooks:t.hooks})}async componentDidMount(){var e=this;let t=e.client;e.ownsClient&&(t=e.buildClient(),e.client=t,e.setState({client:t})),t&&(e.handlers=new b(t),e.handlers.on(`configsUpdated`,()=>{e.setState({updatedAt:new Date})}),e.handlers.on(`clientReady`,()=>{e.setState({status:`ready`})}),e.ownsClient||e.handlers.registerHooks(e.props.hooks),await e.connect(t,e.props.context))}async connect(e,t){var n=this;switch(C(e,t)){case`initialize`:await e.initialize(t);break;case`updateContext`:n.setState({status:`loading`}),await e.updateContext(t);break;case`none`:return}n.client===e&&!e.isReady&&n.setState({status:`default`})}async componentDidUpdate(e){var t=this;if(D(e)&&D(t.props)&&e.client!==t.props.client&&E(`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.`),!x(e.context,t.props.context)){var n;let e=t.client;if(!e)return;t.setState({status:`loading`}),await e.updateContext((n=t.props.context)==null?{}:n),t.client===e&&!e.isReady&&t.setState({status:`default`})}}componentWillUnmount(){var e;if((e=this.handlers)==null||e.removeAll(),this.handlers=void 0,this.ownsClient){var t;(t=this.client)==null||t.dispose()}this.client=void 0}render(){return d(w.Provider,{value:r(r({},this.state),{},{initialConfigs:this.props.initialConfigs}),children:this.props.children})}},k=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const A=()=>new k(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),j=(e,n)=>{var r,i;let a=u(w);if(!a)throw A();let o=(r=a.initialConfigs)==null?void 0:r[e];return{value:(i=a.client)!=null&&i.isReady?a.client.getValue(e,n):o?t(o,n).parsedValue:n,readyStatus:a.status,loading:a.status===`loading`}},M=()=>{let e=u(w);if(!e)throw A();return{updateContext:async t=>{var n;await((n=e.client)==null?void 0:n.updateContext(t))}}},N=()=>{let e=u(w);if(!(e!=null&&e.client))throw A();return{client:e.client}},P=()=>{let e=u(w);if(!e)throw A();return{readyStatus:e.status,loading:e.status===`loading`}};export{k as ConfigDirectorNextContextError,O as ConfigDirectorProvider,E as createConsoleLogger,N as useClient,P as useConfigDirectorStatus,j as useConfigValue,M as useContext};
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-DbyOjKoY.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.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)}async report({context:e,discreteEvents:t,aggregatedEvents:n,droppedEvents:r}){if(!this.executeRequests)return{success:!1,fatalError:!0};let i={clientSdkKey:this.sdkKey,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(i))return{success:!0,fatalError:!1};let a=await this.sendReport(i);return a.fatalError&&(this.executeRequests=!1),a}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=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),y=e=>{try{self.postMessage(e)}catch{self.postMessage(v(e.payload.level,e.payload.message))}},b={debug:function(e,...t){y(v(`debug`,e,t))},info:function(e,...t){y(v(`info`,e,t))},warn:function(e,...t){y(v(`warn`,e,t))},error:function(e,...t){y(v(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!_){b.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(b.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(_){b.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}_=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,valueIdGenerator:g,logger:b}),_.start();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.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}}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=e=>Array.from(e,e=>e.toString(16).padStart(2,`0`)).join(``),C=async e=>{let t=await crypto.subtle.digest(`SHA-256`,new TextEncoder().encode(e));return n+S(new Uint8Array(t))},w=()=>typeof crypto<`u`&&crypto.subtle!=null,T=t=>{let n=a();if(!n||!w())return;let r=C(t);return{read:async()=>n.getItem(await r),write:async e=>n.setItem(await r,e),remove:async()=>n.removeItem(await r),sizeLimit:()=>e}},E=(e,t,n)=>o.from(({clientSdkKey:e,baseUrl:n,logger:r,metadata:i})=>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}),e,t,n,{platformCachingProvider:T});var D=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 O=(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)=>O(e,t[n]));if(!k(e)||!k(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)&&O(e[n],t[n]))},k=e=>{let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null},A=(e,t)=>e.isInitializing?`none`:e.isReady?t!==void 0&&!O(t,e.context)?`updateContext`:`none`:`initialize`,j=(e,t,n)=>{let r=A(e,t);return n&&r===`initialize`&&t===void 0?`waitForContext`:r},M={waitForContext:`waitingForContext`,initialize:`started`,updateContext:`started`,none:`started`},N=(e,t)=>({kind:M[e],client:t}),P=(e,t,n)=>{if(O(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}}},F=l.createContext({status:`loading`,updateContext:async()=>{}});var I=class{decorateMessage(e){return`[ConfigDirector:nextjs-sdk] ${e}`}};const L=e=>r(e,new I),R=e=>`client`in e&&e.client!==void 0,z=e=>e.isReady?`ready`:`default`,B=(e,t)=>{let n=t&&!R(e)&&e.mode===`offline`;return e.deferInitialization===!0&&!n},V=({run:e})=>(f(()=>{e()},[e]),null);var H=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=P(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=R(e)?e.client:i();this.ownsClient=n===void 0,this.waitsForFirstContext=B(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 E(t.sdkKey,{sdkName:`nextjs-sdk`,sdkVersion:`1.12.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:L((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 D(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=j(e,t,n.waitsForFirstContext);switch(n.startupPhase=N(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:z(e)})}async componentDidUpdate(e){var t=this;R(e)&&R(t.props)&&e.client!==t.props.client&&L(`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.`),O(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(F.Provider,{value:t(t({},this.state),{},{initialConfigs:this.props.initialConfigs,updateContext:this.receiveContext}),children:[this.props.children,p(V,{run:this.startAfterFirstRenderEffects})]})}},U=class e extends Error{constructor(t){super(t),this.name=`ConfigDirectorNextContextError`,Object.setPrototypeOf(this,e.prototype)}};const W=()=>new U(`The ConfigDirector client was not found in the React context. Make sure the component using this hook is inside a <ConfigDirectorProvider>.`),G=(e,t)=>{var n,r;let i=d(F);if(!i)throw W();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`}},K=()=>{let e=d(F);if(!e)throw W();return{updateContext:e.updateContext}},q=()=>{let e=d(F);if(!(e!=null&&e.client))throw W();return{client:e.client}},J=()=>{let e=d(F);if(!e)throw W();return{readyStatus:e.status,loading:e.status===`loading`}};export{U as ConfigDirectorNextContextError,H as ConfigDirectorProvider,L as createConsoleLogger,q as useClient,J as useConfigDirectorStatus,G as useConfigValue,K as useContext};
3
3
  //# sourceMappingURL=index.mjs.map