@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.
- package/dist/client/index.cjs +1 -1
- package/dist/client/index.d.cts +56 -11
- package/dist/client/index.d.cts.map +1 -1
- package/dist/client/index.d.mts +56 -11
- package/dist/client/index.d.mts.map +1 -1
- package/dist/client/index.mjs +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/installedTestClient-DQXrptJI.cjs +6 -0
- package/dist/client/installedTestClient-DbyOjKoY.mjs +7 -0
- package/dist/client/installedTestClient-DbyOjKoY.mjs.map +1 -0
- package/dist/client/testing.cjs +1 -1
- package/dist/client/testing.d.cts +5 -14
- package/dist/client/testing.d.cts.map +1 -1
- package/dist/client/testing.d.mts +5 -14
- package/dist/client/testing.d.mts.map +1 -1
- package/dist/client/testing.mjs +1 -1
- package/dist/client/testing.mjs.map +1 -1
- package/dist/client/{types-De4z0tu4.d.mts → types-Daqe9IQD.d.cts} +31 -7
- package/dist/client/types-Daqe9IQD.d.cts.map +1 -0
- package/dist/client/{types-Cz68hQ6f.d.cts → types-HCeqxOKy.d.mts} +31 -7
- package/dist/client/types-HCeqxOKy.d.mts.map +1 -0
- package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs +6 -0
- package/dist/server/DefaultConfigDirectorClient-BplPvnEk.mjs.map +1 -0
- package/dist/server/DefaultConfigDirectorClient-oT53aH0F.cjs +5 -0
- package/dist/server/{types-BBEEMV5Y.d.cts → errors-BLPDhdq2.d.mts} +114 -42
- package/dist/server/errors-BLPDhdq2.d.mts.map +1 -0
- package/dist/server/{types-B_mGbQaa.d.mts → errors-DuJpJeVf.d.cts} +114 -42
- package/dist/server/errors-DuJpJeVf.d.cts.map +1 -0
- package/dist/server/index.cjs +1 -1
- package/dist/server/index.d.cts +54 -9
- package/dist/server/index.d.cts.map +1 -1
- package/dist/server/index.d.mts +54 -9
- package/dist/server/index.d.mts.map +1 -1
- package/dist/server/index.mjs +1 -1
- package/dist/server/index.mjs.map +1 -1
- package/dist/server/native-values-CfqV9hAq.mjs +2 -0
- package/dist/server/native-values-CfqV9hAq.mjs.map +1 -0
- package/dist/server/native-values-UCK4hh1Z.cjs +1 -0
- package/dist/server/testing.cjs +1 -1
- package/dist/server/testing.d.cts +5 -25
- package/dist/server/testing.d.cts.map +1 -1
- package/dist/server/testing.d.mts +5 -25
- package/dist/server/testing.d.mts.map +1 -1
- package/dist/server/testing.mjs +1 -1
- package/dist/server/testing.mjs.map +1 -1
- package/package.json +1 -1
- package/dist/client/installedTestClient-CW29YuQC.cjs +0 -6
- package/dist/client/installedTestClient-CpjJvHZD.mjs +0 -7
- package/dist/client/installedTestClient-CpjJvHZD.mjs.map +0 -1
- package/dist/client/types-Cz68hQ6f.d.cts.map +0 -1
- package/dist/client/types-De4z0tu4.d.mts.map +0 -1
- package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs +0 -6
- package/dist/server/DefaultConfigDirectorClient-BTTja_j3.mjs.map +0 -1
- package/dist/server/DefaultConfigDirectorClient-CqXqwNpW.cjs +0 -5
- package/dist/server/errors-BGpFuqOO.mjs +0 -2
- package/dist/server/errors-BGpFuqOO.mjs.map +0 -1
- package/dist/server/errors-CCbuIqT8.cjs +0 -1
- package/dist/server/types-BBEEMV5Y.d.cts.map +0 -1
- package/dist/server/types-B_mGbQaa.d.mts.map +0 -1
package/dist/client/index.cjs
CHANGED
|
@@ -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;
|
package/dist/client/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
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
|
|
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 `
|
|
32
|
-
* open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
33
|
-
* initialization and then again on every `pollingInterval`.
|
|
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():
|
|
116
|
-
private
|
|
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":";;;;;;
|
|
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"}
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
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
|
|
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 `
|
|
32
|
-
* open and receives config updates as they happen. In `polling` mode configs are fetched once
|
|
33
|
-
* initialization and then again on every `pollingInterval`.
|
|
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():
|
|
116
|
-
private
|
|
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":";;;;;;
|
|
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"}
|
package/dist/client/index.mjs
CHANGED
|
@@ -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
|