@configdirector/nuxt-sdk 1.2.0 → 1.3.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.d.mts +37 -0
- package/dist/module.json +1 -1
- package/dist/module.mjs +13 -7
- package/dist/runtime/nitro/middleware.d.mts +1 -1
- package/dist/runtime/nitro/middleware.d.ts +1 -1
- package/dist/runtime/nitro/middleware.mjs +5 -3
- package/dist/runtime/nitro/plugin.d.mts +1 -0
- package/dist/runtime/nitro/plugin.d.ts +1 -0
- package/dist/runtime/nitro/plugin.mjs +9 -4
- package/dist/runtime/plugin.client.mjs +103 -4
- package/package.json +1 -1
package/dist/module.d.mts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as _$_nuxt_schema0 from "@nuxt/schema";
|
|
2
2
|
import { LogLevel } from "consola";
|
|
3
3
|
|
|
4
|
+
//#region ../shared/src/types.d.ts
|
|
5
|
+
type ConnectionMode = "streaming" | "polling";
|
|
6
|
+
//#endregion
|
|
4
7
|
//#region src/module.d.ts
|
|
5
8
|
interface ConfigDirectorRuntimeConfig {
|
|
6
9
|
/**
|
|
@@ -23,6 +26,40 @@ interface ConfigDirectorRuntimeConfig {
|
|
|
23
26
|
* Can be set via the NUXT_CONFIGDIRECTOR_BASE_URL environment variable.
|
|
24
27
|
*/
|
|
25
28
|
baseUrl?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Connection options for the server SDK client used during SSR and in Nitro handlers.
|
|
31
|
+
*/
|
|
32
|
+
connection?: {
|
|
33
|
+
/**
|
|
34
|
+
* The connection mode, one of `streaming` (default) or `polling`. In `streaming` mode the
|
|
35
|
+
* connection stays open and receives config updates as they happen. In `polling` mode configs
|
|
36
|
+
* are fetched once during initialization and then again on every `pollingInterval`.
|
|
37
|
+
* Can be set via the NUXT_CONFIGDIRECTOR_CONNECTION_MODE environment variable.
|
|
38
|
+
*/
|
|
39
|
+
mode?: ConnectionMode;
|
|
40
|
+
/**
|
|
41
|
+
* The polling interval in seconds when `mode` is `polling`. Has no effect in `streaming` mode.
|
|
42
|
+
* When omitted (or `0`), the server SDK default is used.
|
|
43
|
+
* Can be set via the NUXT_CONFIGDIRECTOR_CONNECTION_POLLING_INTERVAL environment variable.
|
|
44
|
+
*/
|
|
45
|
+
pollingInterval?: number;
|
|
46
|
+
/**
|
|
47
|
+
* How long, in milliseconds, the server SDK client waits for its initial config payload. Requests
|
|
48
|
+
* that arrive before the payload is received are held until it arrives or this timeout elapses,
|
|
49
|
+
* after which they render with default values. When omitted (or `0`), the server SDK default is used.
|
|
50
|
+
* Can be set via the NUXT_CONFIGDIRECTOR_CONNECTION_TIMEOUT environment variable.
|
|
51
|
+
*/
|
|
52
|
+
timeout?: number;
|
|
53
|
+
};
|
|
54
|
+
/**
|
|
55
|
+
* Whether requests that arrive before the server SDK client received its initial config payload
|
|
56
|
+
* (for example right after the server starts) wait for it, for up to the connection `timeout`, before
|
|
57
|
+
* being handled. When disabled, such requests are handled immediately and evaluate configs to their
|
|
58
|
+
* default values until the payload arrives.
|
|
59
|
+
*
|
|
60
|
+
* Defaults to `true`. Can be set via the NUXT_CONFIGDIRECTOR_WAIT_FOR_INITIALIZATION environment variable.
|
|
61
|
+
*/
|
|
62
|
+
waitForInitialization?: boolean;
|
|
26
63
|
}
|
|
27
64
|
interface ConfigDirectorPublicRuntimeConfig {
|
|
28
65
|
/**
|
package/dist/module.json
CHANGED
package/dist/module.mjs
CHANGED
|
@@ -11,14 +11,20 @@ var module_default = defineNuxtModule({
|
|
|
11
11
|
setup(options, nuxt) {
|
|
12
12
|
const logger = useLogger("configdirector");
|
|
13
13
|
const resolver = createResolver(import.meta.url);
|
|
14
|
-
|
|
15
|
-
serverSdkKey: "",
|
|
16
|
-
logLevel: options.logLevel,
|
|
17
|
-
baseUrl: ""
|
|
18
|
-
} : {
|
|
14
|
+
const serverDefaults = {
|
|
19
15
|
serverSdkKey: "",
|
|
20
|
-
baseUrl: ""
|
|
21
|
-
|
|
16
|
+
baseUrl: "",
|
|
17
|
+
connection: {
|
|
18
|
+
mode: "streaming",
|
|
19
|
+
pollingInterval: 0,
|
|
20
|
+
timeout: 0
|
|
21
|
+
},
|
|
22
|
+
waitForInitialization: true
|
|
23
|
+
};
|
|
24
|
+
nuxt.options.runtimeConfig.configdirector = defu(nuxt.options.runtimeConfig.configdirector, options.logLevel !== void 0 ? {
|
|
25
|
+
...serverDefaults,
|
|
26
|
+
logLevel: options.logLevel
|
|
27
|
+
} : serverDefaults);
|
|
22
28
|
nuxt.options.runtimeConfig.public.configdirector = defu(nuxt.options.runtimeConfig.public.configdirector, options.logLevel !== void 0 ? {
|
|
23
29
|
clientSdkKey: "",
|
|
24
30
|
logLevel: options.logLevel,
|
|
@@ -2,7 +2,7 @@ import * as _$h3 from "h3";
|
|
|
2
2
|
import { ConfigDirectorClient } from "@configdirector/server-sdk";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/nitro/middleware.d.ts
|
|
5
|
-
declare const _default: _$h3.EventHandler<_$h3.EventHandlerRequest, void
|
|
5
|
+
declare const _default: _$h3.EventHandler<_$h3.EventHandlerRequest, Promise<void>>;
|
|
6
6
|
declare module "h3" {
|
|
7
7
|
interface H3EventContext {
|
|
8
8
|
configDirectorClient: ConfigDirectorClient;
|
|
@@ -2,7 +2,7 @@ import * as _$h3 from "h3";
|
|
|
2
2
|
import { ConfigDirectorClient } from "@configdirector/server-sdk";
|
|
3
3
|
|
|
4
4
|
//#region src/runtime/nitro/middleware.d.ts
|
|
5
|
-
declare const _default: _$h3.EventHandler<_$h3.EventHandlerRequest, void
|
|
5
|
+
declare const _default: _$h3.EventHandler<_$h3.EventHandlerRequest, Promise<void>>;
|
|
6
6
|
declare module "h3" {
|
|
7
7
|
interface H3EventContext {
|
|
8
8
|
configDirectorClient: ConfigDirectorClient;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { useNitroApp } from "nitropack/runtime";
|
|
1
|
+
import { useNitroApp, useRuntimeConfig } from "nitropack/runtime";
|
|
2
2
|
import { defineEventHandler } from "h3";
|
|
3
3
|
//#region src/runtime/nitro/middleware.ts
|
|
4
|
-
var middleware_default = defineEventHandler((event) => {
|
|
5
|
-
|
|
4
|
+
var middleware_default = defineEventHandler(async (event) => {
|
|
5
|
+
const nitroApp = useNitroApp();
|
|
6
|
+
if (useRuntimeConfig(event).configdirector.waitForInitialization) await nitroApp.configDirectorInitialization;
|
|
7
|
+
event.context.configDirectorClient = nitroApp.configDirectorClient;
|
|
6
8
|
});
|
|
7
9
|
//#endregion
|
|
8
10
|
export { middleware_default as default };
|
|
@@ -7967,16 +7967,21 @@ var plugin_default = defineNitroPlugin((nitroApp) => {
|
|
|
7967
7967
|
throw new ConfigDirectorInitializationError(message);
|
|
7968
7968
|
}
|
|
7969
7969
|
logger.debug("Initializing ConfigDirector Nitro plugin");
|
|
7970
|
-
const { serverSdkKey, baseUrl } = runtimeConfig.configdirector;
|
|
7970
|
+
const { serverSdkKey, baseUrl, connection } = runtimeConfig.configdirector;
|
|
7971
7971
|
const client = new DefaultConfigDirectorClient(serverSdkKey, {
|
|
7972
7972
|
sdkName: "nuxt-sdk",
|
|
7973
|
-
sdkVersion: "1.
|
|
7973
|
+
sdkVersion: "1.3.0"
|
|
7974
7974
|
}, {
|
|
7975
7975
|
logger,
|
|
7976
|
-
|
|
7976
|
+
connection: {
|
|
7977
|
+
url: baseUrl || void 0,
|
|
7978
|
+
mode: connection?.mode || void 0,
|
|
7979
|
+
pollingInterval: connection?.pollingInterval || void 0,
|
|
7980
|
+
timeout: connection?.timeout || void 0
|
|
7981
|
+
}
|
|
7977
7982
|
});
|
|
7978
7983
|
nitroApp.configDirectorClient = client;
|
|
7979
|
-
client.initialize();
|
|
7984
|
+
nitroApp.configDirectorInitialization = client.initialize();
|
|
7980
7985
|
});
|
|
7981
7986
|
//#endregion
|
|
7982
7987
|
export { plugin_default as default };
|
|
@@ -710,6 +710,91 @@ const generateInstanceId = () => {
|
|
|
710
710
|
});
|
|
711
711
|
};
|
|
712
712
|
//#endregion
|
|
713
|
+
//#region ../js-client-core/src/instance-id.ts
|
|
714
|
+
const STORAGE_KEY = "configdirector-sdk:instance-id";
|
|
715
|
+
const RECORD_VERSION = 1;
|
|
716
|
+
const MAX_AGE_MS = 360 * 60 * 1e3;
|
|
717
|
+
const CHECKSUM_SALT = "configdirector.instanceId.v1";
|
|
718
|
+
const UUID_V4_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
719
|
+
const fnv1a = (input, offsetBasis) => {
|
|
720
|
+
let hash = offsetBasis;
|
|
721
|
+
for (let i = 0; i < input.length; i++) {
|
|
722
|
+
hash ^= input.charCodeAt(i);
|
|
723
|
+
hash = Math.imul(hash, 16777619);
|
|
724
|
+
}
|
|
725
|
+
return hash >>> 0;
|
|
726
|
+
};
|
|
727
|
+
const checksumFor = (id, createdAt) => {
|
|
728
|
+
const payload = `${CHECKSUM_SALT}|${id}|${createdAt}`;
|
|
729
|
+
const low = fnv1a(payload, 2166136261);
|
|
730
|
+
return fnv1a(`${low}|${payload}`, 16777619).toString(16).padStart(8, "0") + low.toString(16).padStart(8, "0");
|
|
731
|
+
};
|
|
732
|
+
const getLocalStorage = () => {
|
|
733
|
+
try {
|
|
734
|
+
return globalThis.localStorage ?? void 0;
|
|
735
|
+
} catch {
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
738
|
+
};
|
|
739
|
+
const isUsableRecord = (record) => {
|
|
740
|
+
if (!record || typeof record !== "object") return false;
|
|
741
|
+
const { v, id, createdAt, checksum } = record;
|
|
742
|
+
if (v !== RECORD_VERSION || typeof id !== "string" || typeof checksum !== "string") return false;
|
|
743
|
+
if (typeof createdAt !== "number" || !Number.isInteger(createdAt) || createdAt <= 0) return false;
|
|
744
|
+
if (!UUID_V4_PATTERN.test(id)) return false;
|
|
745
|
+
return checksum === checksumFor(id, createdAt);
|
|
746
|
+
};
|
|
747
|
+
const readStoredInstanceId = (storage, logger) => {
|
|
748
|
+
let raw;
|
|
749
|
+
try {
|
|
750
|
+
raw = storage.getItem(STORAGE_KEY);
|
|
751
|
+
} catch (error) {
|
|
752
|
+
logger?.debug("[ConfigDirectorClient] Could not read the stored instance id, generating a new one", error);
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
755
|
+
if (!raw) return;
|
|
756
|
+
let record;
|
|
757
|
+
try {
|
|
758
|
+
record = JSON.parse(raw);
|
|
759
|
+
} catch {
|
|
760
|
+
logger?.debug("[ConfigDirectorClient] The stored instance id is not valid JSON, generating a new one");
|
|
761
|
+
return;
|
|
762
|
+
}
|
|
763
|
+
if (!isUsableRecord(record)) {
|
|
764
|
+
logger?.debug("[ConfigDirectorClient] The stored instance id failed validation, generating a new one");
|
|
765
|
+
return;
|
|
766
|
+
}
|
|
767
|
+
const age = Date.now() - record.createdAt;
|
|
768
|
+
if (age < 0 || age >= MAX_AGE_MS) {
|
|
769
|
+
logger?.debug("[ConfigDirectorClient] The stored instance id has expired, generating a new one");
|
|
770
|
+
return;
|
|
771
|
+
}
|
|
772
|
+
return record.id;
|
|
773
|
+
};
|
|
774
|
+
const storeInstanceId = (storage, id, logger) => {
|
|
775
|
+
const createdAt = Date.now();
|
|
776
|
+
const record = {
|
|
777
|
+
v: RECORD_VERSION,
|
|
778
|
+
id,
|
|
779
|
+
createdAt,
|
|
780
|
+
checksum: checksumFor(id, createdAt)
|
|
781
|
+
};
|
|
782
|
+
try {
|
|
783
|
+
storage.setItem(STORAGE_KEY, JSON.stringify(record));
|
|
784
|
+
} catch (error) {
|
|
785
|
+
logger?.debug("[ConfigDirectorClient] Could not persist the instance id", error);
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
const resolveInstanceId = (logger) => {
|
|
789
|
+
const storage = getLocalStorage();
|
|
790
|
+
if (!storage) return generateInstanceId();
|
|
791
|
+
const storedInstanceId = readStoredInstanceId(storage, logger);
|
|
792
|
+
if (storedInstanceId) return storedInstanceId;
|
|
793
|
+
const instanceId = generateInstanceId();
|
|
794
|
+
storeInstanceId(storage, instanceId, logger);
|
|
795
|
+
return instanceId;
|
|
796
|
+
};
|
|
797
|
+
//#endregion
|
|
713
798
|
//#region ../shared/src/transport/AbstractPollingTransport.ts
|
|
714
799
|
var AbstractPollingTransport = class {
|
|
715
800
|
fatalError = false;
|
|
@@ -794,7 +879,9 @@ var PollingTransport = class extends AbstractPollingTransport {
|
|
|
794
879
|
this.options = options;
|
|
795
880
|
this.logger = options.logger;
|
|
796
881
|
this.url = options.resolveUrl("client/polling/v1", options.baseUrl);
|
|
797
|
-
|
|
882
|
+
const requestedInterval = options.pollingInterval ?? 300;
|
|
883
|
+
if (requestedInterval < 60) this.logger.warn(`[PollingTransport] pollingInterval of ${requestedInterval} seconds is below the minimum of 60 seconds. Using 60 seconds.`);
|
|
884
|
+
this.pollingIntervalSeconds = Math.max(requestedInterval, 60);
|
|
798
885
|
}
|
|
799
886
|
async connect(context, timeout) {
|
|
800
887
|
this.clearPollingInterval();
|
|
@@ -852,6 +939,17 @@ var PollingTransport = class extends AbstractPollingTransport {
|
|
|
852
939
|
}
|
|
853
940
|
};
|
|
854
941
|
//#endregion
|
|
942
|
+
//#region ../js-client-core/src/browser-globals.ts
|
|
943
|
+
const read = (readValue) => {
|
|
944
|
+
try {
|
|
945
|
+
return readValue(globalThis);
|
|
946
|
+
} catch {
|
|
947
|
+
return;
|
|
948
|
+
}
|
|
949
|
+
};
|
|
950
|
+
const readUserAgent = () => read((globals) => globals.navigator?.userAgent);
|
|
951
|
+
const readHost = () => read((globals) => globals.location?.host);
|
|
952
|
+
//#endregion
|
|
855
953
|
//#region ../js-client-core/src/DefaultConfigDirectorClient.ts
|
|
856
954
|
const MAX_EXPONENTIAL_DELAY = 9;
|
|
857
955
|
var DefaultConfigDirectorClient = class {
|
|
@@ -871,8 +969,8 @@ var DefaultConfigDirectorClient = class {
|
|
|
871
969
|
connectionMode;
|
|
872
970
|
instanceId;
|
|
873
971
|
constructor(telemetryClient, clientSdkKey, sdkOptions, clientOptions, internalClientOptions) {
|
|
874
|
-
this.instanceId = generateInstanceId();
|
|
875
972
|
this.logger = clientOptions?.logger ?? createDefaultLogger$1();
|
|
973
|
+
this.instanceId = resolveInstanceId(this.logger);
|
|
876
974
|
this.timeout = clientOptions?.connection?.timeout ?? 3e3;
|
|
877
975
|
this.validateSdkKeyPresence(clientSdkKey);
|
|
878
976
|
const urlFactory = internalClientOptions?.urlFactory ?? defaultUrlFactory;
|
|
@@ -889,7 +987,8 @@ var DefaultConfigDirectorClient = class {
|
|
|
889
987
|
...clientOptions?.metadata,
|
|
890
988
|
sdkName: sdkOptions.sdkName,
|
|
891
989
|
sdkVersion: sdkOptions.sdkVersion,
|
|
892
|
-
userAgent:
|
|
990
|
+
userAgent: readUserAgent(),
|
|
991
|
+
host: readHost()
|
|
893
992
|
},
|
|
894
993
|
logger: this.logger,
|
|
895
994
|
fetch: internalClientOptions?.fetch,
|
|
@@ -1364,7 +1463,7 @@ var plugin_client_default = defineNuxtPlugin((nuxtApp) => {
|
|
|
1364
1463
|
const { clientSdkKey, appName, appVersion, baseUrl } = runtimeConfig.public.configdirector;
|
|
1365
1464
|
const client = createBrowserClient(clientSdkKey, {
|
|
1366
1465
|
sdkName: "nuxt-sdk",
|
|
1367
|
-
sdkVersion: "1.
|
|
1466
|
+
sdkVersion: "1.3.0"
|
|
1368
1467
|
}, {
|
|
1369
1468
|
metadata: {
|
|
1370
1469
|
appName,
|
package/package.json
CHANGED