@configdirector/nuxt-sdk 1.11.1 → 1.12.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.
Files changed (29) hide show
  1. package/dist/module.d.mts +13 -0
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +2 -1
  4. package/dist/runtime/app/composables/useConfigDirectorClient.d.mts +1 -1
  5. package/dist/runtime/app/composables/useConfigDirectorClient.d.ts +1 -1
  6. package/dist/runtime/app/composables/useConfigDirectorClientHooks.d.mts +1 -1
  7. package/dist/runtime/app/composables/useConfigDirectorClientHooks.d.ts +1 -1
  8. package/dist/runtime/app/composables/useConfigDirectorContext.d.mts +1 -1
  9. package/dist/runtime/app/composables/useConfigDirectorContext.d.ts +1 -1
  10. package/dist/runtime/app/composables/useConfigDirectorContext.mjs +41 -2
  11. package/dist/runtime/app/composables/useConfigDirectorValue.d.mts +1 -1
  12. package/dist/runtime/app/composables/useConfigDirectorValue.d.ts +1 -1
  13. package/dist/runtime/{native-values-BV2k_xR2.d.mts → native-values-ChQdi7c7.d.mts} +6 -4
  14. package/dist/runtime/nitro/offline-values.d.mts +1 -1
  15. package/dist/runtime/nitro/offline-values.d.ts +1 -1
  16. package/dist/runtime/nitro/plugin.d.mts +2 -2
  17. package/dist/runtime/nitro/plugin.d.ts +2 -2
  18. package/dist/runtime/nitro/plugin.mjs +1 -1
  19. package/dist/runtime/plugin.client.mjs +403 -73
  20. package/dist/runtime/plugin.server.mjs +46 -2
  21. package/dist/runtime/server/composables/useConfigDirectorServerClient.d.mts +1 -1
  22. package/dist/runtime/server/composables/useConfigDirectorServerClient.d.ts +1 -1
  23. package/dist/runtime/server/composables/useConfigDirectorServerHooks.d.mts +1 -1
  24. package/dist/runtime/server/composables/useConfigDirectorServerHooks.d.ts +1 -1
  25. package/dist/runtime/{types-CS7AMNWe.d.mts → types-BoDJiQsr.d.mts} +1 -1
  26. package/dist/runtime/{types-Dt3bENKf.d.mts → types-CuzrFq9I.d.mts} +3 -1
  27. package/dist/testing.d.mts +7 -4
  28. package/dist/testing.mjs +280 -31
  29. package/package.json +2 -2
package/dist/module.d.mts CHANGED
@@ -173,6 +173,19 @@ interface ConfigDirectorPublicRuntimeConfig {
173
173
  */
174
174
  timeout?: number;
175
175
  };
176
+ /**
177
+ * Whether the browser client waits for its first context before it connects. With it on, the client
178
+ * opens no connection and `useConfigDirectorStatus` reports `loading` until the app calls
179
+ * `updateContext` from `useConfigDirectorContext`; that first call starts the client with the context
180
+ * it was given. A context set during server-side rendering starts the client when the app is created,
181
+ * as with the option off. Turn it on when the app knows its context only after startup, such as with
182
+ * `ssr: false` or a context fetched in the browser, so the first connection carries the context
183
+ * instead of a connection with no context, whose visitor counts as a monthly active user on its own.
184
+ * It has no effect in `offline` mode, where the client is ready at once.
185
+ *
186
+ * Defaults to `false`. Can be set via the NUXT_PUBLIC_CONFIGDIRECTOR_DEFER_INITIALIZATION environment variable.
187
+ */
188
+ deferInitialization?: boolean;
176
189
  /**
177
190
  * The connection mode the server runs in, written by the module on every request so the browser
178
191
  * knows whether to follow the server into `offline` mode. Not an option: any value set here is
package/dist/module.json CHANGED
@@ -4,5 +4,5 @@
4
4
  "compatibility": {
5
5
  "nuxt": ">=4.0.0"
6
6
  },
7
- "version": "1.11.1"
7
+ "version": "1.12.1"
8
8
  }
package/dist/module.mjs CHANGED
@@ -36,7 +36,8 @@ var module_default = defineNuxtModule({
36
36
  mode: "",
37
37
  pollingInterval: 0,
38
38
  timeout: 0
39
- }
39
+ },
40
+ deferInitialization: false
40
41
  };
41
42
  nuxt.options.runtimeConfig.public.configdirector = defu(nuxt.options.runtimeConfig.public.configdirector, options.logLevel !== void 0 ? {
42
43
  ...publicDefaults,
@@ -1,4 +1,4 @@
1
- import { n as ConfigDirectorClient } from "../../types-Dt3bENKf.mjs";
1
+ import { n as ConfigDirectorClient } from "../../types-CuzrFq9I.mjs";
2
2
 
3
3
  //#region src/runtime/app/composables/useConfigDirectorClient.d.ts
4
4
  declare const useConfigDirectorClient: () => {
@@ -1,4 +1,4 @@
1
- import { n as ConfigDirectorClient } from "../../types-Dt3bENKf.mjs";
1
+ import { n as ConfigDirectorClient } from "../../types-CuzrFq9I.mjs";
2
2
 
3
3
  //#region src/runtime/app/composables/useConfigDirectorClient.d.ts
4
4
  declare const useConfigDirectorClient: () => {
@@ -1,4 +1,4 @@
1
- import { t as ClientHooks } from "../../types-Dt3bENKf.mjs";
1
+ import { t as ClientHooks } from "../../types-CuzrFq9I.mjs";
2
2
 
3
3
  //#region src/runtime/app/composables/useConfigDirectorClientHooks.d.ts
4
4
  declare const useConfigDirectorClientHooks: (hooks: ClientHooks) => void;
@@ -1,4 +1,4 @@
1
- import { t as ClientHooks } from "../../types-Dt3bENKf.mjs";
1
+ import { t as ClientHooks } from "../../types-CuzrFq9I.mjs";
2
2
 
3
3
  //#region src/runtime/app/composables/useConfigDirectorClientHooks.d.ts
4
4
  declare const useConfigDirectorClientHooks: (hooks: ClientHooks) => void;
@@ -1,4 +1,4 @@
1
- import { n as ConfigDirectorContext } from "../../native-values-BV2k_xR2.mjs";
1
+ import { n as ConfigDirectorContext } from "../../native-values-ChQdi7c7.mjs";
2
2
  import { Ref } from "vue";
3
3
 
4
4
  //#region src/runtime/app/composables/useConfigDirectorContext.d.ts
@@ -1,4 +1,4 @@
1
- import { n as ConfigDirectorContext } from "../../native-values-BV2k_xR2.mjs";
1
+ import { n as ConfigDirectorContext } from "../../native-values-ChQdi7c7.mjs";
2
2
  import { Ref } from "vue";
3
3
 
4
4
  //#region src/runtime/app/composables/useConfigDirectorContext.d.ts
@@ -1,7 +1,38 @@
1
1
  import { useConfigDirectorClient } from "./useConfigDirectorClient.mjs";
2
2
  import { n as admittedContextOrNone } from "../../context-kind-D6YBNij2.mjs";
3
- import { useState } from "#app";
3
+ import { useNuxtApp, useState } from "#app";
4
4
  import { readonly, toRaw } from "vue";
5
+ //#region ../shared/src/deepEqual.ts
6
+ const deepEqual = (left, right) => {
7
+ if (Object.is(left, right)) return true;
8
+ if (typeof left !== "object" || typeof right !== "object" || left === null || right === null) return false;
9
+ if (Object.getPrototypeOf(left) !== Object.getPrototypeOf(right)) return false;
10
+ if (left instanceof Date && right instanceof Date) return left.getTime() === right.getTime();
11
+ if (Array.isArray(left) && Array.isArray(right)) return left.length === right.length && left.every((item, index) => deepEqual(item, right[index]));
12
+ if (!isPlainObject(left) || !isPlainObject(right)) return false;
13
+ const leftKeys = Object.keys(left);
14
+ const rightKeys = Object.keys(right);
15
+ return leftKeys.length === rightKeys.length && leftKeys.every((key) => Object.prototype.hasOwnProperty.call(right, key) && deepEqual(left[key], right[key]));
16
+ };
17
+ const isPlainObject = (value) => {
18
+ const prototype = Object.getPrototypeOf(value);
19
+ return prototype === Object.prototype || prototype === null;
20
+ };
21
+ //#endregion
22
+ //#region ../js-client-core/src/mountAction.ts
23
+ const decideMountAction = (client, context) => {
24
+ if (client.isInitializing) return "none";
25
+ if (!client.isReady) return "initialize";
26
+ if (context !== void 0 && !deepEqual(context, client.context)) return "updateContext";
27
+ return "none";
28
+ };
29
+ //#endregion
30
+ //#region src/runtime/client-startup.ts
31
+ const decideContextUpdateAction = (client, context, waitsForFirstContext) => {
32
+ if (waitsForFirstContext && decideMountAction(client, context) === "initialize") return "startClient";
33
+ return "updateContext";
34
+ };
35
+ //#endregion
5
36
  //#region src/runtime/app/composables/useConfigDirectorContext.ts
6
37
  const DEFAULT_TIMEOUT = 3e3;
7
38
  const getEffectiveTimeout = (option) => {
@@ -10,6 +41,14 @@ const getEffectiveTimeout = (option) => {
10
41
  const useConfigDirectorContext = () => {
11
42
  const state = useState("configdirector-context");
12
43
  const { client } = useConfigDirectorClient();
44
+ const { $configDirectorClientStartup } = useNuxtApp();
45
+ const startup = $configDirectorClientStartup;
46
+ const handContextToClient = (rawContext) => {
47
+ switch (decideContextUpdateAction(client, rawContext, startup.waitsForFirstContext)) {
48
+ case "startClient": return startup.start(rawContext);
49
+ case "updateContext": return client.updateContext(rawContext);
50
+ }
51
+ };
13
52
  const updateContext = async (context, options) => {
14
53
  const rawContext = toRaw(context);
15
54
  const oldContext = JSON.stringify(state.value);
@@ -19,7 +58,7 @@ const useConfigDirectorContext = () => {
19
58
  const timeout = getEffectiveTimeout(options?.timeoutMilliseconds);
20
59
  let timer;
21
60
  try {
22
- await Promise.race([client.updateContext(rawContext), new Promise((resolve) => {
61
+ await Promise.race([handContextToClient(rawContext), new Promise((resolve) => {
23
62
  timer = setTimeout(() => resolve(), timeout);
24
63
  })]);
25
64
  } finally {
@@ -1,4 +1,4 @@
1
- import { a as ConfigValueType } from "../../native-values-BV2k_xR2.mjs";
1
+ import { a as ConfigValueType } from "../../native-values-ChQdi7c7.mjs";
2
2
  import { t as ClientStatus } from "../../types-C30VJ25l.mjs";
3
3
  import { DeepReadonly, Ref, ShallowRef } from "vue";
4
4
 
@@ -1,4 +1,4 @@
1
- import { a as ConfigValueType } from "../../native-values-BV2k_xR2.mjs";
1
+ import { a as ConfigValueType } from "../../native-values-ChQdi7c7.mjs";
2
2
  import { t as ClientStatus } from "../../types-C30VJ25l.mjs";
3
3
  import { DeepReadonly, Ref, ShallowRef } from "vue";
4
4
 
@@ -12,7 +12,7 @@ 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";
15
+ type EvaluationReason = "found-match" | "config-state-missing" | "client-not-ready" | "type-mismatch" | "value-missing" | "invalid-number" | "invalid-json" | "invalid-boolean" | "cached";
16
16
  type ConfigEvaluation = {
17
17
  key: string;
18
18
  value: ConfigValueType;
@@ -31,9 +31,11 @@ type ConfigDirectorContext = {
31
31
  * The context's identifier. This should be a value that uniquely identifies the user or other
32
32
  * entity among contexts of the same {@link kind}.
33
33
  * In the case of anonymous users, you could generate a UUID or alternatively not provide
34
- * the {@link id} and the SDK will generate a random UUID. However, keep in mind that this
35
- * value is used for segmenting contexts in percentage rollouts, and changes to the {@link id}
36
- * could result in the context being assigned to a different percentile.
34
+ * the {@link id}. In a client SDK, ConfigDirector then derives an identifier from an ID the SDK
35
+ * stores for the app install or the website, so it stays the same until the app is uninstalled
36
+ * or the site's data is cleared. However, keep in mind that this value is used for segmenting
37
+ * contexts in percentage rollouts, and changes to the {@link id} could result in the context
38
+ * being assigned to a different percentile.
37
39
  */
38
40
  id?: string;
39
41
  /**
@@ -1,4 +1,4 @@
1
- import { t as NativeValues } from "../native-values-BV2k_xR2.mjs";
1
+ import { t as NativeValues } from "../native-values-ChQdi7c7.mjs";
2
2
  import * as _$h3 from "h3";
3
3
 
4
4
  //#region src/runtime/nitro/offline-values.d.ts
@@ -1,4 +1,4 @@
1
- import { t as NativeValues } from "../native-values-BV2k_xR2.mjs";
1
+ import { t as NativeValues } from "../native-values-ChQdi7c7.mjs";
2
2
  import * as _$h3 from "h3";
3
3
 
4
4
  //#region src/runtime/nitro/offline-values.d.ts
@@ -1,5 +1,5 @@
1
- import { o as ConnectionMode } from "../native-values-BV2k_xR2.mjs";
2
- import { n as ConfigDirectorClient } from "../types-CS7AMNWe.mjs";
1
+ import { o as ConnectionMode } from "../native-values-ChQdi7c7.mjs";
2
+ import { n as ConfigDirectorClient } from "../types-BoDJiQsr.mjs";
3
3
  import * as _$nitropack from "nitropack";
4
4
 
5
5
  //#region src/runtime/nitro/plugin.d.ts
@@ -1,5 +1,5 @@
1
- import { o as ConnectionMode } from "../native-values-BV2k_xR2.mjs";
2
- import { n as ConfigDirectorClient } from "../types-CS7AMNWe.mjs";
1
+ import { o as ConnectionMode } from "../native-values-ChQdi7c7.mjs";
2
+ import { n as ConfigDirectorClient } from "../types-BoDJiQsr.mjs";
3
3
  import * as _$nitropack from "nitropack";
4
4
 
5
5
  //#region src/runtime/nitro/plugin.d.ts
@@ -8452,7 +8452,7 @@ var plugin_default = defineNitroPlugin((nitroApp) => {
8452
8452
  logger.debug("Initializing ConfigDirector Nitro plugin");
8453
8453
  const client = new DefaultConfigDirectorClient(serverSdkKey || void 0, {
8454
8454
  sdkName: "nuxt-sdk",
8455
- sdkVersion: "1.11.1"
8455
+ sdkVersion: "1.12.1"
8456
8456
  }, {
8457
8457
  logger,
8458
8458
  connection: {