@configdirector/nuxt-sdk 0.5.0 → 0.6.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/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=4.0.0"
6
6
  },
7
- "version": "0.5.0"
7
+ "version": "0.6.0"
8
8
  }
@@ -1009,11 +1009,12 @@ const defaultUrlFactory = (input, base) => new URL(input, base?.toString());
1009
1009
  const CONFIG_VALUE_MAX_LENGTH = 500;
1010
1010
  const sanitizeValue = (value, type) => {
1011
1011
  if (type === "json" || type == null && typeof value === "object") try {
1012
- return djb2Hash(JSON.stringify(value));
1012
+ return { digest: djb2Hash(JSON.stringify(value)) };
1013
1013
  } catch {
1014
- return value.toString().slice(0, CONFIG_VALUE_MAX_LENGTH);
1014
+ return { digest: value.toString() };
1015
1015
  }
1016
- return value.toString().slice(0, CONFIG_VALUE_MAX_LENGTH);
1016
+ if (value.toString().length > CONFIG_VALUE_MAX_LENGTH) return { digest: djb2Hash(value.toString()) };
1017
+ else return { value: value.toString() };
1017
1018
  };
1018
1019
  const djb2Hash = (data) => {
1019
1020
  return djb2(new TextEncoder().encode(data)).toString(16).padStart(8, "0");
@@ -1551,7 +1552,7 @@ var plugin_default = defineNitroPlugin((nitroApp) => {
1551
1552
  const { serverSdkKey, baseUrl } = runtimeConfig.configdirector;
1552
1553
  const client = new DefaultConfigDirectorClient(serverSdkKey, {
1553
1554
  sdkName: "nuxt-sdk",
1554
- sdkVersion: "0.5.0"
1555
+ sdkVersion: "0.6.0"
1555
1556
  }, {
1556
1557
  logger,
1557
1558
  ...baseUrl ? { connection: { url: baseUrl } } : {}
@@ -1034,11 +1034,12 @@ var DefaultConfigDirectorClient = class {
1034
1034
  const CONFIG_VALUE_MAX_LENGTH = 500;
1035
1035
  const sanitizeValue = (value, type) => {
1036
1036
  if (type === "json" || type == null && typeof value === "object") try {
1037
- return djb2Hash(JSON.stringify(value));
1037
+ return { digest: djb2Hash(JSON.stringify(value)) };
1038
1038
  } catch {
1039
- return value.toString().slice(0, CONFIG_VALUE_MAX_LENGTH);
1039
+ return { digest: value.toString() };
1040
1040
  }
1041
- return value.toString().slice(0, CONFIG_VALUE_MAX_LENGTH);
1041
+ if (value.toString().length > CONFIG_VALUE_MAX_LENGTH) return { digest: djb2Hash(value.toString()) };
1042
+ else return { value: value.toString() };
1042
1043
  };
1043
1044
  const djb2Hash = (data) => {
1044
1045
  return djb2(new TextEncoder().encode(data)).toString(16).padStart(8, "0");
@@ -1071,7 +1072,7 @@ var WebWorkerTelemetryClient = class {
1071
1072
  flushIntervalDelay: options.flushIntervalDelay ?? 3e4
1072
1073
  }
1073
1074
  };
1074
- this.worker = new Worker(URL.createObjectURL(new Blob(["(function(){let e=(e,n)=>{if(n===`json`||n==null&&typeof e==`object`)try{return t(JSON.stringify(e))}catch{return e.toString().slice(0,500)}return e.toString().slice(0,500)},t=e=>n(new TextEncoder().encode(e)).toString(16).padStart(8,`0`),n=e=>{let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+(e[n]??0),t>>>=0;return t},r=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},i=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},a=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}},o=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError;var s=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,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,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 r(e.discreteEvents)&&r(e.aggregatedEvents)&&i(e.droppedEvents)}async sendReport(e){try{let t=await a(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=o(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}},c=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}))}},l=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}},u=class{constructor(e){this.aggregator=new c,this.collectEvents=!0,this.logger=e.logger,this.evaluationEventQueue=new l(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4;let t=e.initialFlushIntervalDelay??5e3;this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),t)}sanitizeValue(t,n){return e(t,n)}async flushAndScheduleNext(){(await this.flush()).fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay)}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=this.evaluationEventQueue.takeSnapshot();return await this.reporter?.report({context:this._context,discreteEvents:{},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e)},droppedEvents:{evaluatedConfig:e.droppedCount}})}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout),await this.flush(),this.evaluationEventQueue.clear()}dispose(){this.close()}},d=class extends u{constructor(e){super(e),this.reporter=new s(e)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}};let f=(e,t)=>new URL(e,t?.toString()),p,m=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),h=e=>{try{self.postMessage(e)}catch{self.postMessage(m(e.payload.level,e.payload.message))}},g={debug:function(e,...t){h(m(`debug`,e,t))},info:function(e,...t){h(m(`info`,e,t))},warn:function(e,...t){h(m(`warn`,e,t))},error:function(e,...t){h(m(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!p){g.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(g.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:p=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,logger:g});break;case`EvaluatedConfigEvent`:p?.evaluatedConfig(t.payload);break;case`UpdateContext`:p?.updateContext(t.payload.context);break;case`Flush`:p?.forceFlush();break;case`Close`:(p?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"], { type: "application/javascript" })));
1075
+ this.worker = new Worker(URL.createObjectURL(new Blob(["(function(){let e=(e,n)=>{if(n===`json`||n==null&&typeof e==`object`)try{return{digest:t(JSON.stringify(e))}}catch{return{digest:e.toString()}}return e.toString().length>500?{digest:t(e.toString())}:{value:e.toString()}},t=e=>n(new TextEncoder().encode(e)).toString(16).padStart(8,`0`),n=e=>{let t=5381;for(let n=0;n<e.length;n++)t=(t<<5)+t+(e[n]??0),t>>>=0;return t},r=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},i=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},a=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}},o=e=>e?.name===`NotAllowedError`?!0:e instanceof TypeError;var s=class{constructor(e){this.executeRequests=!0,this.sdkKey=e.sdkKey,this.logger=e.logger,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,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 r(e.discreteEvents)&&r(e.aggregatedEvents)&&i(e.droppedEvents)}async sendReport(e){try{let t=await a(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=o(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}},c=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}))}},l=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}},u=class{constructor(e){this.aggregator=new c,this.collectEvents=!0,this.logger=e.logger,this.evaluationEventQueue=new l(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4;let t=e.initialFlushIntervalDelay??5e3;this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),t)}sanitizeValue(t,n){return e(t,n)}async flushAndScheduleNext(){(await this.flush()).fatalError?(this.collectEvents=!1,this.close(),this.logger.warn(`[TelemetryEventCollector] Received a fatal error from telemetry collection. No longer collecting events.`)):this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),this.flushIntervalDelay)}async flush(){if(!this.reporter)return{success:!1,fatalError:!1};let e=this.evaluationEventQueue.takeSnapshot();return await this.reporter?.report({context:this._context,discreteEvents:{},aggregatedEvents:{evaluatedConfig:this.aggregator.aggregate(e)},droppedEvents:{evaluatedConfig:e.droppedCount}})}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout),await this.flush(),this.evaluationEventQueue.clear()}dispose(){this.close()}},d=class extends u{constructor(e){super(e),this.reporter=new s(e)}async updateContext(e){this.cancelScheduledFlush(),await this.flush(),this._context=e,await this.flushAndScheduleNext()}evaluatedConfig(e){this.collectEvents&&this.evaluationEventQueue.push(e)}async forceFlush(){this.cancelScheduledFlush(),await this.flushAndScheduleNext()}};let f=(e,t)=>new URL(e,t?.toString()),p,m=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),h=e=>{try{self.postMessage(e)}catch{self.postMessage(m(e.payload.level,e.payload.message))}},g={debug:function(e,...t){h(m(`debug`,e,t))},info:function(e,...t){h(m(`info`,e,t))},warn:function(e,...t){h(m(`warn`,e,t))},error:function(e,...t){h(m(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!p){g.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(g.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:p=new d({...t.payload,baseUrl:f(t.payload.baseUrl),urlFactory:f,logger:g});break;case`EvaluatedConfigEvent`:p?.evaluatedConfig(t.payload);break;case`UpdateContext`:p?.updateContext(t.payload.context);break;case`Flush`:p?.forceFlush();break;case`Close`:(p?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"], { type: "application/javascript" })));
1075
1076
  this.worker.onmessage = (message) => {
1076
1077
  this.handleWorkerEvent(message.data);
1077
1078
  };
@@ -1211,7 +1212,7 @@ var plugin_client_default = defineNuxtPlugin((nuxtApp) => {
1211
1212
  const { clientSdkKey, appName, appVersion, baseUrl } = runtimeConfig.public.configdirector;
1212
1213
  const client = createBrowserClient(clientSdkKey, {
1213
1214
  sdkName: "nuxt-sdk",
1214
- sdkVersion: "0.5.0"
1215
+ sdkVersion: "0.6.0"
1215
1216
  }, {
1216
1217
  metadata: {
1217
1218
  appName,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@configdirector/nuxt-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Nuxt SDK for ConfigDirector. ConfigDirector is a remote configuration and feature flag service.",
5
5
  "license": "MIT",
6
6
  "author": "ConfigDirector",