@configdirector/nuxt-sdk 0.8.0 → 0.9.1
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 +1 -1
- package/dist/module.mjs +9 -0
- 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 +6 -0
- package/dist/runtime/app/composables/useConfigDirectorClientHooks.d.ts +6 -0
- package/dist/runtime/app/composables/useConfigDirectorClientHooks.mjs +22 -0
- package/dist/runtime/app/composables/useConfigDirectorContext.d.mts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorContext.d.ts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorValue.d.mts +1 -1
- package/dist/runtime/app/composables/useConfigDirectorValue.d.ts +1 -1
- package/dist/runtime/nitro/plugin.d.mts +1 -1
- package/dist/runtime/nitro/plugin.d.ts +1 -1
- package/dist/runtime/nitro/plugin.mjs +39 -13
- package/dist/runtime/plugin.client.mjs +73 -10
- 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 +6 -0
- package/dist/runtime/server/composables/useConfigDirectorServerHooks.d.ts +6 -0
- package/dist/runtime/server/composables/useConfigDirectorServerHooks.mjs +14 -0
- package/dist/runtime/{types-DE44nrVT.d.mts → types-B4EK1B6g.d.mts} +12 -2
- package/dist/runtime/{types-BqdrorBY.d.mts → types-CHmsCChN.d.mts} +10 -1
- package/dist/runtime/{types-Ce8HdKnT.d.mts → types-CzmBIfqo.d.mts} +11 -2
- package/package.json +2 -2
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -37,6 +37,10 @@ var module_default = defineNuxtModule({
|
|
|
37
37
|
name: "useConfigDirectorClient",
|
|
38
38
|
as: "useConfigDirectorClient",
|
|
39
39
|
from: resolver.resolve("./runtime/server/composables/useConfigDirectorClient")
|
|
40
|
+
}, {
|
|
41
|
+
name: "useConfigDirectorServerHooks",
|
|
42
|
+
as: "useConfigDirectorServerHooks",
|
|
43
|
+
from: resolver.resolve("./runtime/server/composables/useConfigDirectorServerHooks")
|
|
40
44
|
}]);
|
|
41
45
|
addPlugin(resolver.resolve("./runtime/plugin.server"));
|
|
42
46
|
addPlugin(resolver.resolve("./runtime/plugin.client"));
|
|
@@ -60,6 +64,11 @@ var module_default = defineNuxtModule({
|
|
|
60
64
|
name: "useConfigDirectorValue",
|
|
61
65
|
as: "useConfigDirectorValue",
|
|
62
66
|
from: resolver.resolve("./runtime/app/composables/useConfigDirectorValue")
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: "useConfigDirectorClientHooks",
|
|
70
|
+
as: "useConfigDirectorClientHooks",
|
|
71
|
+
from: resolver.resolve("./runtime/app/composables/useConfigDirectorClientHooks")
|
|
63
72
|
}
|
|
64
73
|
]);
|
|
65
74
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { t as ClientHooks } from "../../types-B4EK1B6g.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/app/composables/useConfigDirectorClientHooks.d.ts
|
|
4
|
+
declare const useConfigDirectorClientHooks: (hooks: ClientHooks) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { useConfigDirectorClientHooks };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { t as ClientHooks } from "../../types-B4EK1B6g.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/app/composables/useConfigDirectorClientHooks.d.ts
|
|
4
|
+
declare const useConfigDirectorClientHooks: (hooks: ClientHooks) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { useConfigDirectorClientHooks };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { useNuxtApp } from "#app";
|
|
2
|
+
import { getCurrentInstance, onUnmounted } from "vue";
|
|
3
|
+
//#region src/runtime/app/composables/useConfigDirectorClientHooks.ts
|
|
4
|
+
const useConfigDirectorClientHooks = (hooks) => {
|
|
5
|
+
const { $configDirectorClient } = useNuxtApp();
|
|
6
|
+
const client = $configDirectorClient;
|
|
7
|
+
const hookEntries = Object.entries(hooks);
|
|
8
|
+
for (const [event, handler] of hookEntries) {
|
|
9
|
+
if (!handler) continue;
|
|
10
|
+
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
11
|
+
for (const h of handlers) client.on(event, h);
|
|
12
|
+
}
|
|
13
|
+
if (getCurrentInstance()) onUnmounted(() => {
|
|
14
|
+
for (const [event, handler] of hookEntries) {
|
|
15
|
+
if (!handler) continue;
|
|
16
|
+
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
17
|
+
for (const h of handlers) client.off(event, h);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
};
|
|
21
|
+
//#endregion
|
|
22
|
+
export { useConfigDirectorClientHooks };
|
|
@@ -2,6 +2,7 @@ import EventEmitter, { EventEmitter as EventEmitter$1 } from "node:events";
|
|
|
2
2
|
import { findByPointer } from "@jsonjoy.com/json-pointer";
|
|
3
3
|
import * as semver from "semver";
|
|
4
4
|
import { rapidhash } from "rapidhash-js";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
5
6
|
import { defineNitroPlugin, useRuntimeConfig } from "nitropack/runtime";
|
|
6
7
|
import { consola } from "consola";
|
|
7
8
|
//#region ../shared/src/errors.ts
|
|
@@ -862,7 +863,7 @@ const parseConfigValue = (configState, defaultValue) => {
|
|
|
862
863
|
usedDefault: false,
|
|
863
864
|
reason: "found-match"
|
|
864
865
|
};
|
|
865
|
-
if (typeof defaultValue === "boolean" && configState.type === "boolean") {
|
|
866
|
+
if (typeof defaultValue === "boolean" && (configState.type === "boolean" || configState.type === "string")) {
|
|
866
867
|
const boolValue = parseConfigBoolean(value);
|
|
867
868
|
const hasBoolean = typeof boolValue === "boolean";
|
|
868
869
|
return {
|
|
@@ -884,7 +885,7 @@ const parseConfigValue = (configState, defaultValue) => {
|
|
|
884
885
|
reason: hasNumber ? "found-match" : "invalid-number"
|
|
885
886
|
};
|
|
886
887
|
}
|
|
887
|
-
if (isNumericNativeType(typeof defaultValue) && (configState.type === "float" || configState.type === "enum")) {
|
|
888
|
+
if (isNumericNativeType(typeof defaultValue) && (configState.type === "float" || configState.type === "enum" || configState.type === "string")) {
|
|
888
889
|
const numValue = parseConfigFloat(value);
|
|
889
890
|
const hasNumber = typeof numValue === "number";
|
|
890
891
|
return {
|
|
@@ -1360,17 +1361,11 @@ const toBase62 = (buf, length) => {
|
|
|
1360
1361
|
}
|
|
1361
1362
|
return result.padStart(length, "0");
|
|
1362
1363
|
};
|
|
1364
|
+
const BASE62_LENGTH = Math.ceil(128 / Math.log2(62));
|
|
1363
1365
|
//#endregion
|
|
1364
|
-
//#region ../
|
|
1365
|
-
const DIGEST_BYTES = 16;
|
|
1366
|
-
const BASE62_LENGTH = Math.ceil(DIGEST_BYTES * 8 / Math.log2(62));
|
|
1367
|
-
const sha256 = async (value) => {
|
|
1368
|
-
const encoded = new TextEncoder().encode(value);
|
|
1369
|
-
const hashBuffer = await globalThis.crypto.subtle.digest("SHA-256", encoded);
|
|
1370
|
-
return new Uint8Array(hashBuffer).subarray(0, DIGEST_BYTES);
|
|
1371
|
-
};
|
|
1366
|
+
//#region ../js-server-sdk/src/telemetry/value-id-generator.ts
|
|
1372
1367
|
const generateValueId = async (v) => {
|
|
1373
|
-
return toBase62(
|
|
1368
|
+
return toBase62(createHash("sha256").update(v?.toString() ?? "").digest().subarray(0, 16), BASE62_LENGTH);
|
|
1374
1369
|
};
|
|
1375
1370
|
//#endregion
|
|
1376
1371
|
//#region ../js-server-sdk/src/DefaultConfigDirectorClient.ts
|
|
@@ -1395,6 +1390,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
1395
1390
|
this.logger = clientOptions?.logger ?? createDefaultLogger$1();
|
|
1396
1391
|
this.timeout = clientOptions?.connection?.timeout ?? 3e3;
|
|
1397
1392
|
this.metaContext = clientOptions?.metadata ?? {};
|
|
1393
|
+
this.validateSdkKeyPresence(serverSdkKey);
|
|
1398
1394
|
this.configEvaluator = new ConfigEvaluator(this.logger);
|
|
1399
1395
|
const baseUrl = this.parseUrl(clientOptions?.connection?.url) ?? defaultBaseUrl;
|
|
1400
1396
|
this.connectionMode = clientOptions?.connection?.mode ?? "streaming";
|
|
@@ -1438,6 +1434,14 @@ var DefaultConfigDirectorClient = class {
|
|
|
1438
1434
|
}
|
|
1439
1435
|
this.logger.debug(`[ConfigDirectorClient] ConfigSet updated from server with ${configKeys.length} key(s)`, { keys: configKeys });
|
|
1440
1436
|
});
|
|
1437
|
+
this.registerHandler("clientReady", clientOptions?.hooks?.clientReady);
|
|
1438
|
+
this.registerHandler("configEvaluated", clientOptions?.hooks?.configEvaluated);
|
|
1439
|
+
this.registerHandler("configsUpdated", clientOptions?.hooks?.configsUpdated);
|
|
1440
|
+
}
|
|
1441
|
+
registerHandler(event, handler) {
|
|
1442
|
+
if (!handler) return;
|
|
1443
|
+
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
1444
|
+
for (const h of handlers) if (typeof h === "function") this.on(event, h);
|
|
1441
1445
|
}
|
|
1442
1446
|
async initialize() {
|
|
1443
1447
|
try {
|
|
@@ -1526,10 +1530,19 @@ var DefaultConfigDirectorClient = class {
|
|
|
1526
1530
|
evaluationReason: parseResult.reason
|
|
1527
1531
|
}
|
|
1528
1532
|
});
|
|
1533
|
+
this.dispatchEvaluationEvent({
|
|
1534
|
+
key: configKey,
|
|
1535
|
+
value: parseResult.parsedValue,
|
|
1536
|
+
valueId: parseResult.parsedValueId ?? void 0,
|
|
1537
|
+
isDefaultValue: parseResult.usedDefault,
|
|
1538
|
+
reason: parseResult.reason,
|
|
1539
|
+
context
|
|
1540
|
+
});
|
|
1529
1541
|
this.logger.debug(`[ConfigDirectorClient] Evaluated '${configKey}' to '${parseResult.parsedValue}'`);
|
|
1530
1542
|
return parseResult.parsedValue;
|
|
1531
1543
|
} else {
|
|
1532
1544
|
this.logger.debug(`[ConfigDirectorClient] No config state found for '${configKey}', returning default value '${defaultValue}'`);
|
|
1545
|
+
const reason = this.isReady ? "config-state-missing" : "client-not-ready";
|
|
1533
1546
|
this.usageEventCollector.evaluatedConfig({
|
|
1534
1547
|
context,
|
|
1535
1548
|
evaluation: {
|
|
@@ -1538,12 +1551,22 @@ var DefaultConfigDirectorClient = class {
|
|
|
1538
1551
|
requestedType: getRequestedType(defaultValue),
|
|
1539
1552
|
evaluatedValue: defaultValue,
|
|
1540
1553
|
usedDefault: true,
|
|
1541
|
-
evaluationReason:
|
|
1554
|
+
evaluationReason: reason
|
|
1542
1555
|
}
|
|
1543
1556
|
});
|
|
1557
|
+
this.dispatchEvaluationEvent({
|
|
1558
|
+
key: configKey,
|
|
1559
|
+
value: defaultValue,
|
|
1560
|
+
isDefaultValue: true,
|
|
1561
|
+
reason,
|
|
1562
|
+
context
|
|
1563
|
+
});
|
|
1544
1564
|
return defaultValue;
|
|
1545
1565
|
}
|
|
1546
1566
|
}
|
|
1567
|
+
dispatchEvaluationEvent(event) {
|
|
1568
|
+
setTimeout(() => this.eventEmitter.emit("configEvaluated", { evaluation: event }), 0);
|
|
1569
|
+
}
|
|
1547
1570
|
parseUrl(url) {
|
|
1548
1571
|
if (!url) return;
|
|
1549
1572
|
try {
|
|
@@ -1552,6 +1575,9 @@ var DefaultConfigDirectorClient = class {
|
|
|
1552
1575
|
throw new ConfigDirectorValidationError(`Invalid base URL '${url}'. Parsing failed: ${error}`);
|
|
1553
1576
|
}
|
|
1554
1577
|
}
|
|
1578
|
+
validateSdkKeyPresence(sdkKey) {
|
|
1579
|
+
if (!sdkKey || sdkKey.trim().length == 0) throw new ConfigDirectorValidationError("No server SDK key was provided, the client cannot be instantiated without a valid server SDK key");
|
|
1580
|
+
}
|
|
1555
1581
|
validateDefaultValue(defaultValue) {
|
|
1556
1582
|
if (defaultValue === void 0 || defaultValue === null) throw new ConfigDirectorValidationError("Invalid default value. The default value for a config must be defined and non-null.");
|
|
1557
1583
|
if (typeof defaultValue === "function") throw new ConfigDirectorValidationError("Invalid default value. The default value for a config cannot be a function.");
|
|
@@ -1614,7 +1640,7 @@ var plugin_default = defineNitroPlugin((nitroApp) => {
|
|
|
1614
1640
|
const { serverSdkKey, baseUrl } = runtimeConfig.configdirector;
|
|
1615
1641
|
const client = new DefaultConfigDirectorClient(serverSdkKey, {
|
|
1616
1642
|
sdkName: "nuxt-sdk",
|
|
1617
|
-
sdkVersion: "0.
|
|
1643
|
+
sdkVersion: "0.9.1"
|
|
1618
1644
|
}, {
|
|
1619
1645
|
logger,
|
|
1620
1646
|
...baseUrl ? { connection: { url: baseUrl } } : {}
|
|
@@ -515,7 +515,7 @@ const parseConfigValue = (configState, defaultValue) => {
|
|
|
515
515
|
usedDefault: false,
|
|
516
516
|
reason: "found-match"
|
|
517
517
|
};
|
|
518
|
-
if (typeof defaultValue === "boolean" && configState.type === "boolean") {
|
|
518
|
+
if (typeof defaultValue === "boolean" && (configState.type === "boolean" || configState.type === "string")) {
|
|
519
519
|
const boolValue = parseConfigBoolean(value);
|
|
520
520
|
const hasBoolean = typeof boolValue === "boolean";
|
|
521
521
|
return {
|
|
@@ -537,7 +537,7 @@ const parseConfigValue = (configState, defaultValue) => {
|
|
|
537
537
|
reason: hasNumber ? "found-match" : "invalid-number"
|
|
538
538
|
};
|
|
539
539
|
}
|
|
540
|
-
if (isNumericNativeType(typeof defaultValue) && (configState.type === "float" || configState.type === "enum")) {
|
|
540
|
+
if (isNumericNativeType(typeof defaultValue) && (configState.type === "float" || configState.type === "enum" || configState.type === "string")) {
|
|
541
541
|
const numValue = parseConfigFloat(value);
|
|
542
542
|
const hasNumber = typeof numValue === "number";
|
|
543
543
|
return {
|
|
@@ -840,6 +840,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
840
840
|
this.instanceId = crypto.randomUUID();
|
|
841
841
|
this.logger = clientOptions?.logger ?? createDefaultLogger$1();
|
|
842
842
|
this.timeout = clientOptions?.connection?.timeout ?? 3e3;
|
|
843
|
+
this.validateSdkKeyPresence(clientSdkKey);
|
|
843
844
|
const urlFactory = internalClientOptions?.urlFactory ?? defaultUrlFactory;
|
|
844
845
|
const baseUrl = this.parseUrl(clientOptions?.connection?.url, urlFactory) ?? "https://client-sdk-api.configdirector.com";
|
|
845
846
|
this.connectionMode = clientOptions?.connection?.mode ?? "streaming";
|
|
@@ -868,18 +869,27 @@ var DefaultConfigDirectorClient = class {
|
|
|
868
869
|
const configKeys = Object.keys(configSet.configs);
|
|
869
870
|
if (!this.configSet || configSet.kind == "full") {
|
|
870
871
|
this.configSet = configSet;
|
|
871
|
-
this.
|
|
872
|
+
this.emit("configsUpdated", { keys: configKeys });
|
|
872
873
|
this.updateWatchers(configSet.configs);
|
|
873
874
|
} else {
|
|
874
875
|
this.configSet.configs = {
|
|
875
876
|
...this.configSet.configs,
|
|
876
877
|
...configSet.configs
|
|
877
878
|
};
|
|
878
|
-
this.
|
|
879
|
+
this.emit("configsUpdated", { keys: configKeys });
|
|
879
880
|
this.updateWatchers(configSet.configs);
|
|
880
881
|
}
|
|
881
882
|
this.logger.debug("[ConfigDirectorClient] ConfigSet updated from server:", { keys: configKeys });
|
|
882
883
|
});
|
|
884
|
+
this.registerHandler("clientReady", clientOptions?.hooks?.clientReady);
|
|
885
|
+
this.registerHandler("configEvaluated", clientOptions?.hooks?.configEvaluated);
|
|
886
|
+
this.registerHandler("configsUpdated", clientOptions?.hooks?.configsUpdated);
|
|
887
|
+
this.registerHandler("contextUpdated", clientOptions?.hooks?.contextUpdated);
|
|
888
|
+
}
|
|
889
|
+
registerHandler(event, handler) {
|
|
890
|
+
if (!handler) return;
|
|
891
|
+
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
892
|
+
for (const h of handlers) if (typeof h === "function") this.on(event, h);
|
|
883
893
|
}
|
|
884
894
|
getTransportConstructor(connectionMode) {
|
|
885
895
|
switch (connectionMode) {
|
|
@@ -906,14 +916,14 @@ var DefaultConfigDirectorClient = class {
|
|
|
906
916
|
}).then(() => {
|
|
907
917
|
this.ready = true;
|
|
908
918
|
this.initializing = false;
|
|
909
|
-
this.
|
|
919
|
+
this.emit("clientReady", { action: caller });
|
|
910
920
|
this.logger.debug("[ConfigDirectorClient] Received initial payload from the server, client is ready");
|
|
911
921
|
});
|
|
912
922
|
const startTime = (/* @__PURE__ */ new Date()).getTime();
|
|
913
923
|
await this.transport.connect(context ?? {}, this.timeout);
|
|
914
924
|
this.currentContext = context;
|
|
915
925
|
this.telemetryClient.updateContext(context);
|
|
916
|
-
this.
|
|
926
|
+
this.emit("contextUpdated", { context });
|
|
917
927
|
const elapsedTime = (/* @__PURE__ */ new Date()).getTime() - startTime;
|
|
918
928
|
const remainingTimeout = this.timeout - elapsedTime;
|
|
919
929
|
clearTimeout(this.timeoutTimer);
|
|
@@ -963,6 +973,7 @@ var DefaultConfigDirectorClient = class {
|
|
|
963
973
|
getValueFromConfigState(configKey, configState, defaultValue) {
|
|
964
974
|
if (!configState) {
|
|
965
975
|
this.logger.debug(`[ConfigDirectorClient] No config state found for '${configKey}', returning default value '${defaultValue}'`);
|
|
976
|
+
const reason = this.isReady ? "config-state-missing" : "client-not-ready";
|
|
966
977
|
this.telemetryClient.evaluatedConfig({
|
|
967
978
|
contextId: this.currentContext?.id,
|
|
968
979
|
key: configKey,
|
|
@@ -970,7 +981,14 @@ var DefaultConfigDirectorClient = class {
|
|
|
970
981
|
requestedType: getRequestedType(defaultValue),
|
|
971
982
|
evaluatedValue: defaultValue,
|
|
972
983
|
usedDefault: true,
|
|
973
|
-
evaluationReason:
|
|
984
|
+
evaluationReason: reason
|
|
985
|
+
});
|
|
986
|
+
this.dispatchEvaluationEvent({
|
|
987
|
+
key: configKey,
|
|
988
|
+
value: defaultValue,
|
|
989
|
+
isDefaultValue: true,
|
|
990
|
+
reason,
|
|
991
|
+
context: this.context
|
|
974
992
|
});
|
|
975
993
|
return defaultValue;
|
|
976
994
|
}
|
|
@@ -986,9 +1004,27 @@ var DefaultConfigDirectorClient = class {
|
|
|
986
1004
|
usedDefault: parseResult.usedDefault,
|
|
987
1005
|
evaluationReason: parseResult.reason
|
|
988
1006
|
});
|
|
1007
|
+
this.dispatchEvaluationEvent({
|
|
1008
|
+
key: configKey,
|
|
1009
|
+
value: parseResult.parsedValue,
|
|
1010
|
+
valueId: parseResult.parsedValueId ?? void 0,
|
|
1011
|
+
isDefaultValue: parseResult.usedDefault,
|
|
1012
|
+
reason: parseResult.reason,
|
|
1013
|
+
context: this.context
|
|
1014
|
+
});
|
|
989
1015
|
this.logger.debug(`[ConfigDirectorClient] Evaluated '${configKey}' to '${parseResult.parsedValue}'`);
|
|
990
1016
|
return parseResult.parsedValue;
|
|
991
1017
|
}
|
|
1018
|
+
dispatchEvaluationEvent(event) {
|
|
1019
|
+
setTimeout(() => this.emit("configEvaluated", { evaluation: event }), 0);
|
|
1020
|
+
}
|
|
1021
|
+
emit(name, payload) {
|
|
1022
|
+
try {
|
|
1023
|
+
this.eventEmitter.emit(name, payload);
|
|
1024
|
+
} catch (error) {
|
|
1025
|
+
this.logger.error(`[ConfigDirectorClient] Error executing event handlers for '${name}'`, error);
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
992
1028
|
parseUrl(url, urlFactory) {
|
|
993
1029
|
if (!url) return;
|
|
994
1030
|
try {
|
|
@@ -997,6 +1033,9 @@ var DefaultConfigDirectorClient = class {
|
|
|
997
1033
|
throw new ConfigDirectorValidationError(`Invalid base URL '${url}'. Parsing failed: ${error}`);
|
|
998
1034
|
}
|
|
999
1035
|
}
|
|
1036
|
+
validateSdkKeyPresence(sdkKey) {
|
|
1037
|
+
if (!sdkKey || sdkKey.trim().length == 0) throw new ConfigDirectorValidationError("No client SDK key was provided, the client cannot be instantiated without a valid client SDK key");
|
|
1038
|
+
}
|
|
1000
1039
|
validateDefaultValue(defaultValue) {
|
|
1001
1040
|
if (defaultValue === void 0 || defaultValue === null) throw new ConfigDirectorValidationError("Invalid default value. The default value for a config must be defined and non-null.");
|
|
1002
1041
|
if (typeof defaultValue === "function") throw new ConfigDirectorValidationError("Invalid default value. The default value for a config cannot be a function.");
|
|
@@ -1089,7 +1128,7 @@ var WebWorkerTelemetryClient = class {
|
|
|
1089
1128
|
flushIntervalDelay: options.flushIntervalDelay ?? 3e4
|
|
1090
1129
|
}
|
|
1091
1130
|
};
|
|
1092
|
-
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.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 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}},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(){(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)}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout),await this.flush(),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=async e=>{let t=
|
|
1131
|
+
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.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 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}},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(){(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)}cancelScheduledFlush(){clearTimeout(this.flushTimeout)}async close(){this.collectEvents=!1,clearTimeout(this.flushTimeout),await this.flush(),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=>{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`: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" })));
|
|
1093
1132
|
this.worker.onmessage = (message) => {
|
|
1094
1133
|
this.handleWorkerEvent(message.data);
|
|
1095
1134
|
};
|
|
@@ -1170,6 +1209,29 @@ var WebWorkerTelemetryClient = class {
|
|
|
1170
1209
|
}
|
|
1171
1210
|
};
|
|
1172
1211
|
//#endregion
|
|
1212
|
+
//#region ../shared/src/base62-encoder.ts
|
|
1213
|
+
const BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
1214
|
+
const toBase62 = (buf, length) => {
|
|
1215
|
+
const ZERO = BigInt(0);
|
|
1216
|
+
const BASE = BigInt(62);
|
|
1217
|
+
const hex = Array.from(buf).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1218
|
+
let n = BigInt("0x" + hex);
|
|
1219
|
+
let result = "";
|
|
1220
|
+
while (n > ZERO) {
|
|
1221
|
+
result = BASE62[Number(n % BASE)] + result;
|
|
1222
|
+
n /= BASE;
|
|
1223
|
+
}
|
|
1224
|
+
return result.padStart(length, "0");
|
|
1225
|
+
};
|
|
1226
|
+
const BASE62_LENGTH = Math.ceil(128 / Math.log2(62));
|
|
1227
|
+
//#endregion
|
|
1228
|
+
//#region ../js-browser-client/src/telemetry/value-id-generator.ts
|
|
1229
|
+
const encoder = new TextEncoder();
|
|
1230
|
+
const generateValueId = async (v) => {
|
|
1231
|
+
const hashBuffer = await crypto.subtle.digest("SHA-256", encoder.encode(v?.toString() ?? ""));
|
|
1232
|
+
return toBase62(new Uint8Array(hashBuffer, 0, 16), BASE62_LENGTH);
|
|
1233
|
+
};
|
|
1234
|
+
//#endregion
|
|
1173
1235
|
//#region ../js-browser-client/src/BrowserConfigDirectorClient.ts
|
|
1174
1236
|
const createBrowserClient = (clientSdkKey, sdkOptions, clientOptions) => {
|
|
1175
1237
|
const logger = clientOptions?.logger ?? createDefaultLogger$1();
|
|
@@ -1177,7 +1239,8 @@ const createBrowserClient = (clientSdkKey, sdkOptions, clientOptions) => {
|
|
|
1177
1239
|
sdkKey: clientSdkKey,
|
|
1178
1240
|
logger,
|
|
1179
1241
|
baseUrl: parseUrl(clientOptions?.connection?.url) ?? "https://client-sdk-api.configdirector.com",
|
|
1180
|
-
urlFactory: defaultUrlFactory
|
|
1242
|
+
urlFactory: defaultUrlFactory,
|
|
1243
|
+
valueIdGenerator: generateValueId
|
|
1181
1244
|
}), clientSdkKey, sdkOptions, {
|
|
1182
1245
|
...clientOptions,
|
|
1183
1246
|
logger
|
|
@@ -1236,7 +1299,7 @@ var plugin_client_default = defineNuxtPlugin((nuxtApp) => {
|
|
|
1236
1299
|
const { clientSdkKey, appName, appVersion, baseUrl } = runtimeConfig.public.configdirector;
|
|
1237
1300
|
const client = createBrowserClient(clientSdkKey, {
|
|
1238
1301
|
sdkName: "nuxt-sdk",
|
|
1239
|
-
sdkVersion: "0.
|
|
1302
|
+
sdkVersion: "0.9.1"
|
|
1240
1303
|
}, {
|
|
1241
1304
|
metadata: {
|
|
1242
1305
|
appName,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { n as ConfigDirectorClient } from "../../types-CzmBIfqo.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 {
|
|
1
|
+
import { n as ConfigDirectorClient } from "../../types-CzmBIfqo.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/runtime/server/composables/useConfigDirectorClient.d.ts
|
|
4
4
|
declare const useConfigDirectorClient: () => ConfigDirectorClient;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { t as ClientHooks } from "../../types-CzmBIfqo.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/server/composables/useConfigDirectorServerHooks.d.ts
|
|
4
|
+
declare const useConfigDirectorServerHooks: (hooks: ClientHooks) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { useConfigDirectorServerHooks };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { t as ClientHooks } from "../../types-CzmBIfqo.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/runtime/server/composables/useConfigDirectorServerHooks.d.ts
|
|
4
|
+
declare const useConfigDirectorServerHooks: (hooks: ClientHooks) => void;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { useConfigDirectorServerHooks };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { useNitroApp } from "nitropack/runtime";
|
|
2
|
+
//#region src/runtime/server/composables/useConfigDirectorServerHooks.ts
|
|
3
|
+
const useConfigDirectorServerHooks = (hooks) => {
|
|
4
|
+
const client = useNitroApp().configDirectorClient;
|
|
5
|
+
if (!client) throw new Error("The ConfigDirector Nitro plugin was not initialized");
|
|
6
|
+
const entries = Object.entries(hooks);
|
|
7
|
+
for (const [event, handler] of entries) {
|
|
8
|
+
if (!handler) continue;
|
|
9
|
+
const handlers = Array.isArray(handler) ? handler : [handler];
|
|
10
|
+
for (const h of handlers) client.on(event, h);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { useConfigDirectorServerHooks };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { i as ConfigValueType, n as ConfigEvaluation, t as ConfigDirectorContext } from "./types-CHmsCChN.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../js-client-core/src/Emitter.d.ts
|
|
4
4
|
type EventType = string | symbol;
|
|
@@ -11,7 +11,14 @@ interface EventProvider<TEventsRecord extends EventsRecord> {
|
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
13
|
//#region ../js-client-core/src/types.d.ts
|
|
14
|
+
type ClientHooks = {
|
|
15
|
+
clientReady?: HookHandler<"clientReady"> | HookHandler<"clientReady">[];
|
|
16
|
+
configsUpdated?: HookHandler<"configsUpdated"> | HookHandler<"configsUpdated">[];
|
|
17
|
+
contextUpdated?: HookHandler<"contextUpdated"> | HookHandler<"contextUpdated">[];
|
|
18
|
+
configEvaluated?: HookHandler<"configEvaluated"> | HookHandler<"configEvaluated">[];
|
|
19
|
+
};
|
|
14
20
|
type ClientConnectAction = "initialization" | "context update" | "network resume";
|
|
21
|
+
type HookHandler<TEvent extends keyof ClientEvents> = (payload: ClientEvents[TEvent]) => void;
|
|
15
22
|
type ClientEvents = {
|
|
16
23
|
configsUpdated: {
|
|
17
24
|
keys: string[];
|
|
@@ -22,6 +29,9 @@ type ClientEvents = {
|
|
|
22
29
|
contextUpdated: {
|
|
23
30
|
context: ConfigDirectorContext | undefined;
|
|
24
31
|
};
|
|
32
|
+
configEvaluated: {
|
|
33
|
+
evaluation: ConfigEvaluation;
|
|
34
|
+
};
|
|
25
35
|
};
|
|
26
36
|
type WatchHandler<T extends ConfigValueType> = (message: T) => void;
|
|
27
37
|
/**
|
|
@@ -132,4 +142,4 @@ interface ConfigDirectorClient extends EventProvider<ClientEvents> {
|
|
|
132
142
|
dispose(): void;
|
|
133
143
|
}
|
|
134
144
|
//#endregion
|
|
135
|
-
export { ConfigDirectorClient as t };
|
|
145
|
+
export { ConfigDirectorClient as n, ClientHooks as t };
|
|
@@ -12,6 +12,15 @@ type ConfigState = {
|
|
|
12
12
|
value: string | undefined | null;
|
|
13
13
|
valueId?: string | undefined | null;
|
|
14
14
|
};
|
|
15
|
+
type EvaluationReason = "found-match" | "config-state-missing" | "client-not-ready" | "type-mismatch" | "value-missing" | "invalid-number" | "invalid-json" | "invalid-boolean";
|
|
16
|
+
type ConfigEvaluation = {
|
|
17
|
+
key: string;
|
|
18
|
+
value: ConfigValueType;
|
|
19
|
+
valueId?: string;
|
|
20
|
+
isDefaultValue: boolean;
|
|
21
|
+
reason: EvaluationReason;
|
|
22
|
+
context?: ConfigDirectorContext;
|
|
23
|
+
};
|
|
15
24
|
/**
|
|
16
25
|
* The user's context to be sent to ConfigDirector. This context will be used for targeting
|
|
17
26
|
* rules evaluation.
|
|
@@ -48,4 +57,4 @@ type ConfigDirectorContext = {
|
|
|
48
57
|
anonymous?: boolean;
|
|
49
58
|
};
|
|
50
59
|
//#endregion
|
|
51
|
-
export {
|
|
60
|
+
export { ConfigValueType as i, ConfigEvaluation as n, ConfigState as r, ConfigDirectorContext as t };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as
|
|
1
|
+
import { i as ConfigValueType, n as ConfigEvaluation, r as ConfigState, t as ConfigDirectorContext } from "./types-CHmsCChN.mjs";
|
|
2
2
|
|
|
3
3
|
//#region ../js-server-sdk/src/types.d.ts
|
|
4
4
|
type ClientEvents = {
|
|
@@ -6,7 +6,16 @@ type ClientEvents = {
|
|
|
6
6
|
keys: string[];
|
|
7
7
|
};
|
|
8
8
|
clientReady: undefined;
|
|
9
|
+
configEvaluated: {
|
|
10
|
+
evaluation: ConfigEvaluation;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
type ClientHooks = {
|
|
14
|
+
clientReady?: HookHandler<"clientReady"> | HookHandler<"clientReady">[];
|
|
15
|
+
configsUpdated?: HookHandler<"configsUpdated"> | HookHandler<"configsUpdated">[];
|
|
16
|
+
configEvaluated?: HookHandler<"configEvaluated"> | HookHandler<"configEvaluated">[];
|
|
9
17
|
};
|
|
18
|
+
type HookHandler<TEvent extends keyof ClientEvents> = (payload: ClientEvents[TEvent]) => void;
|
|
10
19
|
type WatchHandler<T extends ConfigValueType> = (message: T) => void;
|
|
11
20
|
/**
|
|
12
21
|
* The ConfigDirector SDK client object.
|
|
@@ -93,4 +102,4 @@ interface ConfigDirectorClient {
|
|
|
93
102
|
dispose(): void;
|
|
94
103
|
}
|
|
95
104
|
//#endregion
|
|
96
|
-
export { ConfigDirectorClient as t };
|
|
105
|
+
export { ConfigDirectorClient as n, ClientHooks as t };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@configdirector/nuxt-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.1",
|
|
4
4
|
"description": "Nuxt SDK for ConfigDirector. ConfigDirector is a remote configuration and feature flag service.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "ConfigDirector",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
"@nuxt/test-utils": "^4.0.2",
|
|
63
63
|
"@types/node": "latest",
|
|
64
64
|
"changelogen": "^0.6.2",
|
|
65
|
-
"eslint": "^10.
|
|
65
|
+
"eslint": "^10.7.0",
|
|
66
66
|
"nuxt": "^4.4.8",
|
|
67
67
|
"playwright": "^1.60.0",
|
|
68
68
|
"rimraf": "^6.1.3",
|