@configdirector/nuxt-sdk 1.7.0 → 1.8.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/README.md +34 -0
- package/dist/module.d.mts +26 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +12 -7
- package/dist/runtime/app/composables/useConfigDirectorClient.d.mts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorClient.d.ts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorClientHooks.d.mts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorClientHooks.d.ts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorContext.mjs +8 -3
- package/dist/runtime/nitro/plugin.d.mts +1 -1
- package/dist/runtime/nitro/plugin.d.ts +1 -1
- package/dist/runtime/nitro/plugin.mjs +149 -68
- package/dist/runtime/plugin.client.mjs +186 -84
- package/dist/runtime/plugin.server.mjs +8 -3
- package/dist/runtime/server/composables/useConfigDirectorClient.d.mts +1 -1
- package/dist/runtime/server/composables/useConfigDirectorClient.d.ts +1 -1
- package/dist/runtime/server/composables/useConfigDirectorServerHooks.d.mts +1 -1
- package/dist/runtime/server/composables/useConfigDirectorServerHooks.d.ts +1 -1
- package/dist/runtime/{types-C54FjC1D.d.mts → types-Bgx2-3dY.d.mts} +1 -0
- package/dist/runtime/{types-BPvGEzJY.d.mts → types-CvmjergQ.d.mts} +6 -2
- package/dist/testing.d.mts +352 -0
- package/dist/testing.mjs +1645 -0
- package/package.json +11 -4
|
@@ -512,7 +512,7 @@ const configTypesNotReadableAsString = new Set([
|
|
|
512
512
|
const parseConfigValue = (configState, defaultValue) => {
|
|
513
513
|
const value = configState.value;
|
|
514
514
|
const requestedType = getRequestedType(defaultValue);
|
|
515
|
-
if (value == null) return {
|
|
515
|
+
if (value == null || value === "") return {
|
|
516
516
|
parsedValue: defaultValue,
|
|
517
517
|
parsedValueId: void 0,
|
|
518
518
|
requestedType,
|
|
@@ -715,6 +715,22 @@ const parseUrl = (url) => {
|
|
|
715
715
|
}
|
|
716
716
|
};
|
|
717
717
|
//#endregion
|
|
718
|
+
//#region ../shared/src/transport/pollingInterval.ts
|
|
719
|
+
const resolvePollingInterval = (configuredSeconds, defaults) => {
|
|
720
|
+
if (configuredSeconds === void 0) return {
|
|
721
|
+
seconds: defaults.defaultSeconds,
|
|
722
|
+
warning: void 0
|
|
723
|
+
};
|
|
724
|
+
if (configuredSeconds >= defaults.minimumSeconds) return {
|
|
725
|
+
seconds: configuredSeconds,
|
|
726
|
+
warning: void 0
|
|
727
|
+
};
|
|
728
|
+
return {
|
|
729
|
+
seconds: defaults.minimumSeconds,
|
|
730
|
+
warning: `pollingInterval of ${configuredSeconds} seconds is below the minimum of ${defaults.minimumSeconds} seconds. Using ${defaults.minimumSeconds} seconds.`
|
|
731
|
+
};
|
|
732
|
+
};
|
|
733
|
+
//#endregion
|
|
718
734
|
//#region ../shared/src/instance-id.ts
|
|
719
735
|
const generateInstanceId = () => {
|
|
720
736
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") return crypto.randomUUID();
|
|
@@ -813,7 +829,6 @@ const resolveInstanceId = (logger) => {
|
|
|
813
829
|
var AbstractPollingTransport = class {
|
|
814
830
|
fatalError = false;
|
|
815
831
|
pollingInterval;
|
|
816
|
-
pollingIntervalSeconds = 60;
|
|
817
832
|
clearPollingInterval() {
|
|
818
833
|
clearInterval(this.pollingInterval);
|
|
819
834
|
}
|
|
@@ -883,6 +898,7 @@ const fetchWithTimeout = async (timeout, resource, options, logger) => {
|
|
|
883
898
|
//#endregion
|
|
884
899
|
//#region ../js-client-core/src/PollingTransport.ts
|
|
885
900
|
var PollingTransport = class extends AbstractPollingTransport {
|
|
901
|
+
pollingIntervalSeconds;
|
|
886
902
|
logger;
|
|
887
903
|
eventEmitter = new Emitter();
|
|
888
904
|
url;
|
|
@@ -893,9 +909,7 @@ var PollingTransport = class extends AbstractPollingTransport {
|
|
|
893
909
|
this.options = options;
|
|
894
910
|
this.logger = options.logger;
|
|
895
911
|
this.url = options.resolveUrl("client/polling/v1", options.baseUrl);
|
|
896
|
-
|
|
897
|
-
if (requestedInterval < 60) this.logger.warn(`[PollingTransport] pollingInterval of ${requestedInterval} seconds is below the minimum of 60 seconds. Using 60 seconds.`);
|
|
898
|
-
this.pollingIntervalSeconds = Math.max(requestedInterval, 60);
|
|
912
|
+
this.pollingIntervalSeconds = options.pollingInterval ?? 60;
|
|
899
913
|
}
|
|
900
914
|
async connect(context, timeout) {
|
|
901
915
|
this.clearPollingInterval();
|
|
@@ -977,6 +991,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
977
991
|
timeoutTimer;
|
|
978
992
|
ready = false;
|
|
979
993
|
initializing = false;
|
|
994
|
+
hasReceivedConfigSet = false;
|
|
980
995
|
readyPromise;
|
|
981
996
|
readyResolve;
|
|
982
997
|
currentContext;
|
|
@@ -990,45 +1005,30 @@ var DefaultConfigDirectorClient = class {
|
|
|
990
1005
|
const urlFactory = internalClientOptions?.urlFactory ?? defaultUrlFactory;
|
|
991
1006
|
const baseUrl = this.parseUrl(clientOptions?.connection?.url, urlFactory) ?? "https://client-sdk-api.configdirector.com";
|
|
992
1007
|
this.connectionMode = clientOptions?.connection?.mode ?? "streaming";
|
|
993
|
-
const transportConstructor = this.getTransportConstructor(this.connectionMode);
|
|
994
1008
|
this.telemetryClient = telemetryClient;
|
|
995
|
-
this.transport =
|
|
996
|
-
instanceId: this.instanceId,
|
|
997
|
-
clientSdkKey,
|
|
998
|
-
baseUrl,
|
|
999
|
-
resolveUrl: urlFactory,
|
|
1000
|
-
metaContext: {
|
|
1001
|
-
...clientOptions?.metadata,
|
|
1002
|
-
sdkName: sdkOptions.sdkName,
|
|
1003
|
-
sdkVersion: sdkOptions.sdkVersion,
|
|
1004
|
-
userAgent: readUserAgent(),
|
|
1005
|
-
host: readHost()
|
|
1006
|
-
},
|
|
1007
|
-
logger: this.logger,
|
|
1008
|
-
fetch: internalClientOptions?.fetch,
|
|
1009
|
-
connectionRetryDelay: internalClientOptions?.connectionRetryDelay ?? ((attempt) => {
|
|
1010
|
-
return Math.pow(2, Math.min(attempt, MAX_EXPONENTIAL_DELAY)) * 1e3;
|
|
1011
|
-
}),
|
|
1012
|
-
pollingInterval: clientOptions?.connection?.pollingInterval
|
|
1013
|
-
});
|
|
1009
|
+
this.transport = internalClientOptions?.transport ?? this.buildTransport(clientSdkKey, sdkOptions, baseUrl, urlFactory, clientOptions, internalClientOptions);
|
|
1014
1010
|
this.transport.on("configSetReceived", (configSet) => {
|
|
1011
|
+
this.hasReceivedConfigSet = true;
|
|
1015
1012
|
this.readyResolve?.();
|
|
1016
|
-
const
|
|
1017
|
-
if (!this.configSet || configSet.kind == "full")
|
|
1018
|
-
|
|
1019
|
-
this.
|
|
1020
|
-
|
|
1021
|
-
}
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1013
|
+
const removedKeys = this.findKeysRemovedBy(configSet);
|
|
1014
|
+
if (!this.configSet || configSet.kind == "full") this.configSet = configSet;
|
|
1015
|
+
else this.configSet.configs = {
|
|
1016
|
+
...this.configSet.configs,
|
|
1017
|
+
...configSet.configs
|
|
1018
|
+
};
|
|
1019
|
+
const keys = Object.keys(configSet.configs);
|
|
1020
|
+
this.emit("configsUpdated", {
|
|
1021
|
+
keys,
|
|
1022
|
+
removedKeys
|
|
1023
|
+
});
|
|
1024
|
+
this.updateWatchers([...keys, ...removedKeys]);
|
|
1025
|
+
this.logger.debug("[ConfigDirectorClient] ConfigSet updated from server:", {
|
|
1026
|
+
keys,
|
|
1027
|
+
removedKeys
|
|
1028
|
+
});
|
|
1030
1029
|
});
|
|
1031
1030
|
this.transport.on("connectionError", (error) => {
|
|
1031
|
+
this.initializing = false;
|
|
1032
1032
|
this.logger.error("[ConfigDirectorClient] The connection encountered an unrecoverable error and will not be retried. Configs will no longer receive updates.", error);
|
|
1033
1033
|
this.emit("connectionError", { error });
|
|
1034
1034
|
});
|
|
@@ -1043,6 +1043,36 @@ var DefaultConfigDirectorClient = class {
|
|
|
1043
1043
|
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
1044
1044
|
for (const h of handlers) if (typeof h === "function") this.on(event, h);
|
|
1045
1045
|
}
|
|
1046
|
+
resolvePollingIntervalForMode(configuredSeconds) {
|
|
1047
|
+
if (this.connectionMode !== "polling") return;
|
|
1048
|
+
const resolved = resolvePollingInterval(configuredSeconds, {
|
|
1049
|
+
defaultSeconds: 60,
|
|
1050
|
+
minimumSeconds: 30
|
|
1051
|
+
});
|
|
1052
|
+
if (resolved.warning) this.logger.warn(`[ConfigDirectorClient] ${resolved.warning}`);
|
|
1053
|
+
return resolved.seconds;
|
|
1054
|
+
}
|
|
1055
|
+
buildTransport(clientSdkKey, sdkOptions, baseUrl, urlFactory, clientOptions, internalClientOptions) {
|
|
1056
|
+
return new (this.getTransportConstructor(this.connectionMode))({
|
|
1057
|
+
instanceId: this.instanceId,
|
|
1058
|
+
clientSdkKey,
|
|
1059
|
+
baseUrl,
|
|
1060
|
+
resolveUrl: urlFactory,
|
|
1061
|
+
metaContext: {
|
|
1062
|
+
...clientOptions?.metadata,
|
|
1063
|
+
sdkName: sdkOptions.sdkName,
|
|
1064
|
+
sdkVersion: sdkOptions.sdkVersion,
|
|
1065
|
+
userAgent: readUserAgent(),
|
|
1066
|
+
host: readHost()
|
|
1067
|
+
},
|
|
1068
|
+
logger: this.logger,
|
|
1069
|
+
fetch: internalClientOptions?.fetch,
|
|
1070
|
+
connectionRetryDelay: internalClientOptions?.connectionRetryDelay ?? ((attempt) => {
|
|
1071
|
+
return Math.pow(2, Math.min(attempt, MAX_EXPONENTIAL_DELAY)) * 1e3;
|
|
1072
|
+
}),
|
|
1073
|
+
pollingInterval: this.resolvePollingIntervalForMode(clientOptions?.connection?.pollingInterval)
|
|
1074
|
+
});
|
|
1075
|
+
}
|
|
1046
1076
|
getTransportConstructor(connectionMode) {
|
|
1047
1077
|
switch (connectionMode) {
|
|
1048
1078
|
case "polling": return PollingTransport;
|
|
@@ -1050,7 +1080,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
1050
1080
|
}
|
|
1051
1081
|
}
|
|
1052
1082
|
async initialize(context) {
|
|
1053
|
-
this.initializing = true;
|
|
1083
|
+
if (!this.hasReceivedConfigSet) this.initializing = true;
|
|
1054
1084
|
await this.connectToTransport(context, "initialization");
|
|
1055
1085
|
}
|
|
1056
1086
|
async updateContext(context) {
|
|
@@ -1072,7 +1102,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
1072
1102
|
this.logger.debug("[ConfigDirectorClient] Received initial payload from the server, client is ready");
|
|
1073
1103
|
});
|
|
1074
1104
|
const startTime = (/* @__PURE__ */ new Date()).getTime();
|
|
1075
|
-
await this.transport.connect(context ?? {}, this.timeout);
|
|
1105
|
+
await this.transport.connect(context ?? {}, this.timeout, caller);
|
|
1076
1106
|
this.currentContext = context;
|
|
1077
1107
|
this.telemetryClient.updateContext(context);
|
|
1078
1108
|
this.emit("contextUpdated", { context });
|
|
@@ -1088,12 +1118,17 @@ var DefaultConfigDirectorClient = class {
|
|
|
1088
1118
|
this.logger.error(`[ConfigDirectorClient] An error occurred during ${caller}: `, error);
|
|
1089
1119
|
}
|
|
1090
1120
|
}
|
|
1091
|
-
|
|
1092
|
-
|
|
1121
|
+
findKeysRemovedBy(configSet) {
|
|
1122
|
+
if (!this.configSet || configSet.kind != "full") return [];
|
|
1123
|
+
return Object.keys(this.configSet.configs).filter((key) => !Object.prototype.hasOwnProperty.call(configSet.configs, key));
|
|
1124
|
+
}
|
|
1125
|
+
updateWatchers(configKeys) {
|
|
1126
|
+
configKeys.forEach((configKey) => this.updateWatchersForConfig(configKey));
|
|
1093
1127
|
}
|
|
1094
|
-
updateWatchersForConfig(
|
|
1095
|
-
this.
|
|
1096
|
-
|
|
1128
|
+
updateWatchersForConfig(configKey) {
|
|
1129
|
+
const configState = this.configSet?.configs[configKey];
|
|
1130
|
+
this.handlersMap.get(configKey)?.forEach((h) => {
|
|
1131
|
+
const value = this.getValueFromConfigState(configKey, configState, h.defaultValue);
|
|
1097
1132
|
h.handler(value);
|
|
1098
1133
|
});
|
|
1099
1134
|
}
|
|
@@ -1266,7 +1301,10 @@ const mapToTelemetryValue = (ev) => {
|
|
|
1266
1301
|
const DEFAULT_WORKER_CLOSE_TIMEOUT = 6e3;
|
|
1267
1302
|
var WebWorkerTelemetryClient = class {
|
|
1268
1303
|
logger;
|
|
1304
|
+
initializeMessage;
|
|
1269
1305
|
worker;
|
|
1306
|
+
pendingEvaluations = [];
|
|
1307
|
+
pendingEvaluationLimit;
|
|
1270
1308
|
closePromise;
|
|
1271
1309
|
closeResolve;
|
|
1272
1310
|
closeTimer;
|
|
@@ -1275,45 +1313,59 @@ var WebWorkerTelemetryClient = class {
|
|
|
1275
1313
|
constructor(options) {
|
|
1276
1314
|
this.logger = options.logger;
|
|
1277
1315
|
this.workerCloseTimeout = options.workerCloseTimeout ?? DEFAULT_WORKER_CLOSE_TIMEOUT;
|
|
1278
|
-
|
|
1316
|
+
this.pendingEvaluationLimit = options.evaluationQueueLimit ?? 1e3;
|
|
1317
|
+
this.initializeMessage = {
|
|
1279
1318
|
type: "Initialize",
|
|
1280
1319
|
payload: {
|
|
1281
1320
|
sdkKey: options.sdkKey,
|
|
1282
1321
|
sdkIdentity: options.sdkIdentity,
|
|
1283
1322
|
metaContext: options.metaContext,
|
|
1284
1323
|
baseUrl: options.baseUrl.toString(),
|
|
1285
|
-
evaluationQueueLimit:
|
|
1324
|
+
evaluationQueueLimit: this.pendingEvaluationLimit,
|
|
1286
1325
|
initialFlushIntervalDelay: options.initialFlushIntervalDelay ?? 5e3,
|
|
1287
1326
|
flushIntervalDelay: options.flushIntervalDelay ?? 3e4
|
|
1288
1327
|
}
|
|
1289
1328
|
};
|
|
1290
|
-
this.worker = 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.logger=e.logger,this.evaluationEventQueue=new s(e.evaluationQueueLimit??1e3),this.flushIntervalDelay=e.flushIntervalDelay??3e4;let t=e.initialFlushIntervalDelay??5e3;this.flushTimeout=setTimeout(()=>this.flushAndScheduleNext(),t)}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 extends c{constructor(e){super(e),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)}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)},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let d=(e,t)=>new URL(e,t?.toString()),f=(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`)},p=Math.ceil(128/Math.log2(62)),m=new TextEncoder,h=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,m.encode(e?.toString()??``));return f(new Uint8Array(t,0,16),p)},g,_=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),v=e=>{try{self.postMessage(e)}catch{self.postMessage(_(e.payload.level,e.payload.message))}},y={debug:function(e,...t){v(_(`debug`,e,t))},info:function(e,...t){v(_(`info`,e,t))},warn:function(e,...t){v(_(`warn`,e,t))},error:function(e,...t){v(_(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!g){y.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(y.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(g){y.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}g=new u({...t.payload,baseUrl:d(t.payload.baseUrl),urlFactory:d,valueIdGenerator:h,logger:y});break;case`EvaluatedConfigEvent`:g?.evaluatedConfig(t.payload);break;case`UpdateContext`:g?.updateContext(t.payload.context);break;case`Flush`:g?.forceFlush();break;case`Close`:(g?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"], { type: "application/javascript" })));
|
|
1291
|
-
this.worker.onmessage = (message) => {
|
|
1292
|
-
this.handleWorkerEvent(message.data);
|
|
1293
|
-
};
|
|
1294
|
-
this.worker.postMessage(initializeMessage);
|
|
1295
1329
|
this.visibilityHandler = () => {
|
|
1296
1330
|
if (document.visibilityState === "hidden") this.flush();
|
|
1297
1331
|
};
|
|
1332
|
+
}
|
|
1333
|
+
startWorker() {
|
|
1334
|
+
if (this.worker) return this.worker;
|
|
1335
|
+
const worker = 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 extends c{constructor(e){super(e),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)}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)},droppedEvents:{evaluatedConfig:e.droppedCount}})}};let d=(e,t)=>new URL(e,t?.toString()),f=(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`)},p=Math.ceil(128/Math.log2(62)),m=new TextEncoder,h=async e=>{if(typeof crypto>`u`||crypto.subtle==null)return;let t=await crypto.subtle.digest(`SHA-256`,m.encode(e?.toString()??``));return f(new Uint8Array(t,0,16),p)},g,_=(e,t,...n)=>({type:`Log`,payload:{level:e,message:t,args:n}}),v=e=>{try{self.postMessage(e)}catch{self.postMessage(_(e.payload.level,e.payload.message))}},y={debug:function(e,...t){v(_(`debug`,e,t))},info:function(e,...t){v(_(`info`,e,t))},warn:function(e,...t){v(_(`warn`,e,t))},error:function(e,...t){v(_(`error`,e,t))}};addEventListener(`message`,e=>{let t=e.data;if(t.type!=`Initialize`&&!g){y.info(`[TelemetryWorker] Ignoring ${t.type} because no collector is configured`);return}switch(y.debug(`[TelemetryWorker] Received '${t.type}' event:`,t),t.type){case`Initialize`:if(g){y.warn(`[TelemetryWorker] Received a duplicate Initialize event, ignoring it`);break}g=new u({...t.payload,baseUrl:d(t.payload.baseUrl),urlFactory:d,valueIdGenerator:h,logger:y}),g.start();break;case`EvaluatedConfigEvent`:g?.evaluatedConfig(t.payload);break;case`UpdateContext`:g?.updateContext(t.payload.context);break;case`Flush`:g?.forceFlush();break;case`Close`:(g?.close()??Promise.resolve()).then(()=>{self.postMessage({type:`Closed`}),self.close()});break}})})();"], { type: "application/javascript" })));
|
|
1336
|
+
worker.onmessage = (message) => {
|
|
1337
|
+
this.handleWorkerEvent(message.data);
|
|
1338
|
+
};
|
|
1339
|
+
worker.postMessage(this.initializeMessage);
|
|
1340
|
+
this.worker = worker;
|
|
1298
1341
|
try {
|
|
1299
1342
|
document.addEventListener("visibilitychange", this.visibilityHandler);
|
|
1300
1343
|
} catch (error) {
|
|
1301
1344
|
this.logger.warn("[TelemetryEventCollector] Could not configure 'visibilitychange' listener: ", error);
|
|
1302
1345
|
}
|
|
1346
|
+
for (const evaluation of this.pendingEvaluations) worker.postMessage(evaluation);
|
|
1347
|
+
this.pendingEvaluations.length = 0;
|
|
1348
|
+
return worker;
|
|
1303
1349
|
}
|
|
1304
1350
|
async updateContext(value) {
|
|
1351
|
+
if (this.closePromise) return;
|
|
1305
1352
|
const updateContextMessage = {
|
|
1306
1353
|
type: "UpdateContext",
|
|
1307
1354
|
payload: { context: value }
|
|
1308
1355
|
};
|
|
1309
|
-
this.
|
|
1356
|
+
this.startWorker().postMessage(updateContextMessage);
|
|
1310
1357
|
}
|
|
1311
1358
|
evaluatedConfig(event) {
|
|
1312
1359
|
const evaluatedConfigMessage = {
|
|
1313
1360
|
type: "EvaluatedConfigEvent",
|
|
1314
1361
|
payload: this.sanitizeEvaluatedConfigEvent(event)
|
|
1315
1362
|
};
|
|
1316
|
-
this.worker
|
|
1363
|
+
if (this.worker) {
|
|
1364
|
+
this.worker.postMessage(evaluatedConfigMessage);
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
if (this.pendingEvaluations.length >= this.pendingEvaluationLimit) this.pendingEvaluations.shift();
|
|
1368
|
+
this.pendingEvaluations.push(evaluatedConfigMessage);
|
|
1317
1369
|
}
|
|
1318
1370
|
sanitizeEvaluatedConfigEvent(event) {
|
|
1319
1371
|
return {
|
|
@@ -1352,13 +1404,19 @@ var WebWorkerTelemetryClient = class {
|
|
|
1352
1404
|
}
|
|
1353
1405
|
}
|
|
1354
1406
|
flush() {
|
|
1355
|
-
this.worker
|
|
1407
|
+
this.worker?.postMessage({ type: "Flush" });
|
|
1356
1408
|
}
|
|
1357
1409
|
close() {
|
|
1358
1410
|
if (this.closePromise) return this.closePromise;
|
|
1359
1411
|
return this.performClose();
|
|
1360
1412
|
}
|
|
1361
1413
|
performClose() {
|
|
1414
|
+
const worker = this.worker;
|
|
1415
|
+
if (!worker) {
|
|
1416
|
+
this.pendingEvaluations.length = 0;
|
|
1417
|
+
this.closePromise = Promise.resolve();
|
|
1418
|
+
return this.closePromise;
|
|
1419
|
+
}
|
|
1362
1420
|
try {
|
|
1363
1421
|
document.removeEventListener("visibilitychange", this.visibilityHandler);
|
|
1364
1422
|
} catch (error) {
|
|
@@ -1370,14 +1428,14 @@ var WebWorkerTelemetryClient = class {
|
|
|
1370
1428
|
this.logger.warn("[WebWorkerTelemetryClient] Timed out waiting for the telemetry worker to close. Terminating the worker.");
|
|
1371
1429
|
this.finishClose();
|
|
1372
1430
|
}, this.workerCloseTimeout);
|
|
1373
|
-
|
|
1431
|
+
worker.postMessage({ type: "Close" });
|
|
1374
1432
|
});
|
|
1375
1433
|
return this.closePromise;
|
|
1376
1434
|
}
|
|
1377
1435
|
finishClose() {
|
|
1378
1436
|
clearTimeout(this.closeTimer);
|
|
1379
1437
|
this.closeTimer = void 0;
|
|
1380
|
-
this.worker
|
|
1438
|
+
this.worker?.terminate();
|
|
1381
1439
|
this.closeResolve?.();
|
|
1382
1440
|
}
|
|
1383
1441
|
};
|
|
@@ -1430,6 +1488,35 @@ const createBrowserClient = (clientSdkKey, sdkOptions, clientOptions) => {
|
|
|
1430
1488
|
});
|
|
1431
1489
|
};
|
|
1432
1490
|
//#endregion
|
|
1491
|
+
//#region ../js-client-core/src/installedTestClient.ts
|
|
1492
|
+
const INSTALLED_TEST_CLIENT_SLOT = Symbol.for("@configdirector/installed-test-client");
|
|
1493
|
+
const readInstalledTestClient = () => globalThis[INSTALLED_TEST_CLIENT_SLOT];
|
|
1494
|
+
//#endregion
|
|
1495
|
+
//#region ../shared/src/deepEqual.ts
|
|
1496
|
+
const deepEqual = (left, right) => {
|
|
1497
|
+
if (Object.is(left, right)) return true;
|
|
1498
|
+
if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
|
|
1499
|
+
if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
|
|
1500
|
+
if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
|
|
1501
|
+
if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));
|
|
1502
|
+
if (!isPlainObject(left) || !isPlainObject(right)) return false;
|
|
1503
|
+
const leftKeys = Object.keys(left);
|
|
1504
|
+
const rightKeys = Object.keys(right);
|
|
1505
|
+
return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key]));
|
|
1506
|
+
};
|
|
1507
|
+
const isPlainObject = (value) => {
|
|
1508
|
+
const prototype = Object.getPrototypeOf(value);
|
|
1509
|
+
return prototype === Object.prototype || prototype === null;
|
|
1510
|
+
};
|
|
1511
|
+
//#endregion
|
|
1512
|
+
//#region ../js-client-core/src/mountAction.ts
|
|
1513
|
+
const decideMountAction = (client, context) => {
|
|
1514
|
+
if (client.isInitializing) return "none";
|
|
1515
|
+
if (!client.isReady) return "initialize";
|
|
1516
|
+
if (context !== void 0 && !deepEqual(context, client.context)) return "updateContext";
|
|
1517
|
+
return "none";
|
|
1518
|
+
};
|
|
1519
|
+
//#endregion
|
|
1433
1520
|
//#region src/runtime/app/composables/useConfigDirectorClient.ts
|
|
1434
1521
|
const useConfigDirectorClient = () => {
|
|
1435
1522
|
const { $configDirectorClient } = useNuxtApp();
|
|
@@ -1451,9 +1538,14 @@ const useConfigDirectorContext = () => {
|
|
|
1451
1538
|
state.value = rawContext;
|
|
1452
1539
|
if (oldContext != newContext) {
|
|
1453
1540
|
const timeout = getEffectiveTimeout(options?.timeoutMilliseconds);
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1541
|
+
let timer;
|
|
1542
|
+
try {
|
|
1543
|
+
await Promise.race([client.updateContext(rawContext), new Promise((resolve) => {
|
|
1544
|
+
timer = setTimeout(() => resolve(), timeout);
|
|
1545
|
+
})]);
|
|
1546
|
+
} finally {
|
|
1547
|
+
clearTimeout(timer);
|
|
1548
|
+
}
|
|
1457
1549
|
}
|
|
1458
1550
|
};
|
|
1459
1551
|
return {
|
|
@@ -1470,45 +1562,55 @@ const createDefaultLogger = (level) => {
|
|
|
1470
1562
|
};
|
|
1471
1563
|
//#endregion
|
|
1472
1564
|
//#region src/runtime/plugin.client.ts
|
|
1565
|
+
const DEFAULT_INITIALIZATION_TIMEOUT_MILLISECONDS = 2e3;
|
|
1473
1566
|
var plugin_client_default = defineNuxtPlugin((nuxtApp) => {
|
|
1474
1567
|
const runtimeConfig = useRuntimeConfig();
|
|
1475
1568
|
const logger = createDefaultLogger(runtimeConfig.public?.configdirector?.logLevel);
|
|
1476
|
-
|
|
1569
|
+
const installedTestClient = readInstalledTestClient();
|
|
1570
|
+
const client = installedTestClient ?? buildClient(runtimeConfig.public?.configdirector, logger);
|
|
1571
|
+
logger.debug(installedTestClient ? "Installed ConfigDirector Nuxt plugin with a test client" : "Installed ConfigDirector Nuxt plugin");
|
|
1572
|
+
const readyStatus = shallowRef(client.isReady ? "ready" : "loading");
|
|
1573
|
+
client.on("clientReady", () => {
|
|
1574
|
+
readyStatus.value = "ready";
|
|
1575
|
+
});
|
|
1576
|
+
nuxtApp.hooks.hook("app:created", async () => {
|
|
1577
|
+
const { context } = useConfigDirectorContext();
|
|
1578
|
+
const rawContext = toRaw(context.value);
|
|
1579
|
+
const mountAction = decideMountAction(client, rawContext);
|
|
1580
|
+
logger.debug(`Browser client mount action: ${mountAction}`);
|
|
1581
|
+
if (mountAction === "initialize") await client.initialize(rawContext);
|
|
1582
|
+
else if (mountAction === "updateContext" && rawContext !== void 0) await client.updateContext(rawContext);
|
|
1583
|
+
if (!client.isReady) readyStatus.value = "default";
|
|
1584
|
+
logger.debug(`Browser client mount action awaited, ready status: ${client.isReady}`);
|
|
1585
|
+
});
|
|
1586
|
+
return { provide: {
|
|
1587
|
+
configDirectorClient: client,
|
|
1588
|
+
configDirectorClientReadyStatus: readonly(readyStatus)
|
|
1589
|
+
} };
|
|
1590
|
+
});
|
|
1591
|
+
const buildClient = (configdirector, logger) => {
|
|
1592
|
+
if (!configdirector?.clientSdkKey) {
|
|
1477
1593
|
const message = "The ConfigDirector clientSdkKey must be configured for the plugin to initialize. You can provide it in nuxt.config.ts under 'runtimeConfig.public.configdirector.clientSdkKey' or as a runtime environment variable named NUXT_PUBLIC_CONFIGDIRECTOR_CLIENT_SDK_KEY";
|
|
1478
1594
|
logger.error(message);
|
|
1479
1595
|
throw new ConfigDirectorInitializationError(message);
|
|
1480
1596
|
}
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
const client = createBrowserClient(clientSdkKey, {
|
|
1597
|
+
const { clientSdkKey, appName, appVersion, baseUrl, connection } = configdirector;
|
|
1598
|
+
return createBrowserClient(clientSdkKey, {
|
|
1484
1599
|
sdkName: "nuxt-sdk",
|
|
1485
|
-
sdkVersion: "1.
|
|
1600
|
+
sdkVersion: "1.8.0"
|
|
1486
1601
|
}, {
|
|
1487
1602
|
metadata: {
|
|
1488
1603
|
appName,
|
|
1489
1604
|
appVersion
|
|
1490
1605
|
},
|
|
1491
1606
|
connection: {
|
|
1492
|
-
|
|
1493
|
-
|
|
1607
|
+
url: baseUrl || void 0,
|
|
1608
|
+
mode: connection?.mode || void 0,
|
|
1609
|
+
pollingInterval: connection?.pollingInterval || void 0,
|
|
1610
|
+
timeout: connection?.timeout || DEFAULT_INITIALIZATION_TIMEOUT_MILLISECONDS
|
|
1494
1611
|
},
|
|
1495
1612
|
logger
|
|
1496
1613
|
});
|
|
1497
|
-
|
|
1498
|
-
client.on("clientReady", () => {
|
|
1499
|
-
readyStatus.value = "ready";
|
|
1500
|
-
});
|
|
1501
|
-
nuxtApp.hooks.hook("app:created", async () => {
|
|
1502
|
-
logger.debug("Initializing browser client");
|
|
1503
|
-
const { context } = useConfigDirectorContext();
|
|
1504
|
-
await client.initialize(toRaw(context.value));
|
|
1505
|
-
if (!client.isReady) readyStatus.value = "default";
|
|
1506
|
-
logger.debug(`Browser client initialization awaited, ready status: ${client.isReady}`);
|
|
1507
|
-
});
|
|
1508
|
-
return { provide: {
|
|
1509
|
-
configDirectorClient: client,
|
|
1510
|
-
configDirectorClientReadyStatus: readonly(readyStatus)
|
|
1511
|
-
} };
|
|
1512
|
-
});
|
|
1614
|
+
};
|
|
1513
1615
|
//#endregion
|
|
1514
1616
|
export { plugin_client_default as default };
|
|
@@ -29,9 +29,14 @@ const useConfigDirectorContext = () => {
|
|
|
29
29
|
state.value = rawContext;
|
|
30
30
|
if (oldContext != newContext) {
|
|
31
31
|
const timeout = getEffectiveTimeout(options?.timeoutMilliseconds);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
let timer;
|
|
33
|
+
try {
|
|
34
|
+
await Promise.race([client.updateContext(rawContext), new Promise((resolve) => {
|
|
35
|
+
timer = setTimeout(() => resolve(), timeout);
|
|
36
|
+
})]);
|
|
37
|
+
} finally {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
}
|
|
35
40
|
}
|
|
36
41
|
};
|
|
37
42
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ConfigDirectorClient } from "../../types-
|
|
1
|
+
import { n as ConfigDirectorClient } from "../../types-Bgx2-3dY.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/server/composables/useConfigDirectorClient.d.ts
|
|
4
4
|
declare const useConfigDirectorClient: () => ConfigDirectorClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as ConfigDirectorClient } from "../../types-
|
|
1
|
+
import { n as ConfigDirectorClient } from "../../types-Bgx2-3dY.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/server/composables/useConfigDirectorClient.d.ts
|
|
4
4
|
declare const useConfigDirectorClient: () => ConfigDirectorClient;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ClientHooks } from "../../types-
|
|
1
|
+
import { t as ClientHooks } from "../../types-Bgx2-3dY.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/server/composables/useConfigDirectorServerHooks.d.ts
|
|
4
4
|
declare const useConfigDirectorServerHooks: (hooks: ClientHooks) => void;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as ClientHooks } from "../../types-
|
|
1
|
+
import { t as ClientHooks } from "../../types-Bgx2-3dY.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/server/composables/useConfigDirectorServerHooks.d.ts
|
|
4
4
|
declare const useConfigDirectorServerHooks: (hooks: ClientHooks) => void;
|
|
@@ -23,6 +23,7 @@ type HookHandler<TEvent extends keyof ClientEvents> = (payload: ClientEvents[TEv
|
|
|
23
23
|
type ClientEvents = {
|
|
24
24
|
configsUpdated: {
|
|
25
25
|
keys: string[];
|
|
26
|
+
removedKeys: string[];
|
|
26
27
|
};
|
|
27
28
|
clientReady: {
|
|
28
29
|
action: ClientConnectAction;
|
|
@@ -85,8 +86,11 @@ interface ConfigDirectorClient extends EventProvider<ClientEvents> {
|
|
|
85
86
|
*/
|
|
86
87
|
get isReady(): boolean;
|
|
87
88
|
/**
|
|
88
|
-
*
|
|
89
|
-
*
|
|
89
|
+
* Whether the client is trying to get its very first payload from the server. Upon client creation,
|
|
90
|
+
* it is `false`. It becomes `true` when `initialize` is called on a client that has never received a
|
|
91
|
+
* payload, stays `true` through timeouts and retries, and becomes `false` when the first payload
|
|
92
|
+
* arrives, when a fatal connection error stops the retries, or on `close`. `updateContext` and
|
|
93
|
+
* `resumeNetwork` never set it, and once a payload has been received it is never `true` again.
|
|
90
94
|
*/
|
|
91
95
|
get isInitializing(): boolean;
|
|
92
96
|
/**
|