@quonfig/react 0.0.13 → 0.0.14
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/CHANGELOG.md +7 -0
- package/dist/index.cjs +3 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.mjs +3 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.14 - 2026-05-19
|
|
4
|
+
|
|
5
|
+
- **Breaking (typing-level):** removed the `collectLoggerNames` prop from `<QuonfigProvider>`
|
|
6
|
+
(qfg-owyw). The underlying `@quonfig/javascript` option was removed in 0.0.17 (qfg-o2fk) — there
|
|
7
|
+
is no consumer for the per-logger telemetry on the server. TypeScript callers passing
|
|
8
|
+
`collectLoggerNames` to the provider will get a type error; drop the prop.
|
|
9
|
+
|
|
3
10
|
## 0.0.13 - 2026-05-10
|
|
4
11
|
|
|
5
12
|
- **chore: declare `engines.node` >=20.9.0 + pin CI floor (qfg-y7xh).** Adds an explicit
|
package/dist/index.cjs
CHANGED
|
@@ -113,8 +113,7 @@ function QuonfigProvider({
|
|
|
113
113
|
domain,
|
|
114
114
|
pollInterval,
|
|
115
115
|
afterEvaluationCallback = void 0,
|
|
116
|
-
collectEvaluationSummaries
|
|
117
|
-
collectLoggerNames
|
|
116
|
+
collectEvaluationSummaries
|
|
118
117
|
}) {
|
|
119
118
|
const normalizedLogger = React__default.default.useMemo(() => normalizeLogger(logger), [logger]);
|
|
120
119
|
const onError = React__default.default.useCallback(
|
|
@@ -137,8 +136,7 @@ function QuonfigProvider({
|
|
|
137
136
|
pollInterval,
|
|
138
137
|
onError,
|
|
139
138
|
afterEvaluationCallback,
|
|
140
|
-
collectEvaluationSummaries
|
|
141
|
-
collectLoggerNames
|
|
139
|
+
collectEvaluationSummaries
|
|
142
140
|
};
|
|
143
141
|
const mostRecentlyLoadingContextKey = React__default.default.useRef(void 0);
|
|
144
142
|
const [loading, setLoading] = React__default.default.useState(true);
|
|
@@ -183,8 +181,7 @@ function QuonfigProvider({
|
|
|
183
181
|
domain,
|
|
184
182
|
timeout,
|
|
185
183
|
afterEvaluationCallback,
|
|
186
|
-
collectEvaluationSummaries
|
|
187
|
-
collectLoggerNames
|
|
184
|
+
collectEvaluationSummaries
|
|
188
185
|
};
|
|
189
186
|
quonfigClient.init(initOptions).then(() => {
|
|
190
187
|
setLoadedContextKey(contextKey);
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/sdkLogger.ts","../src/QuonfigProvider.tsx","../src/QuonfigTestProvider.tsx"],"names":["React","quonfig","Quonfig","encodeContexts"],"mappings":"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","file":"index.cjs","sourcesContent":["// AUTO-GENERATED from package.json by scripts/generate-version.mjs — do not edit.\nexport default \"0.0.9\";\n","/**\n * Pluggable logger interface for SDK-internal warnings and errors.\n *\n * Shape mirrors @quonfig/node so the contract is uniform across the\n * TypeScript SDKs: `warn` and `error` are required; `debug` and `info` are\n * optional and become no-ops when the supplied logger does not implement\n * them.\n */\nexport interface Logger {\n debug?(message: string, ...args: unknown[]): void;\n info?(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport interface NormalizedLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst NOOP = (): void => {};\n\nconst PREFIX = \"[quonfig]\";\n\nfunction defaultSdkLogger(): NormalizedLogger {\n return {\n /* eslint-disable no-console */\n debug: (message, ...args) => console.debug(PREFIX, message, ...args),\n info: (message, ...args) => console.info(PREFIX, message, ...args),\n warn: (message, ...args) => console.warn(PREFIX, message, ...args),\n error: (message, ...args) => console.error(PREFIX, message, ...args),\n /* eslint-enable no-console */\n };\n}\n\nexport function normalizeLogger(logger: Logger | undefined): NormalizedLogger {\n if (!logger) return defaultSdkLogger();\n return {\n debug: logger.debug ? logger.debug.bind(logger) : NOOP,\n info: logger.info ? logger.info.bind(logger) : NOOP,\n warn: logger.warn.bind(logger),\n error: logger.error.bind(logger),\n };\n}\n","import React, { PropsWithChildren } from \"react\";\nimport {\n quonfig,\n type InitOptions,\n type ConfigValue,\n type Contexts,\n Quonfig,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Duration,\n encodeContexts,\n} from \"@quonfig/javascript\";\nimport reactSdkVersion from \"./version\";\nimport { normalizeLogger, type Logger, type NormalizedLogger } from \"./sdkLogger\";\n\n// qfg-lkpm.6: per-tree owner context. The value is the active Quonfig client\n// for this provider subtree. A null value means no Provider is above us, so\n// the next mount can claim the module-level singleton; a non-null value\n// signals \"you're nested, mint a fresh client\". This replaces the previous\n// module-level `globalQuonfigIsTaken` flag, which never reset and so leaked\n// state across test runs and (in principle) across SSR render trees.\nconst QuonfigClientContext = React.createContext<Quonfig | null>(null);\n\n// @quonfig/cli#generate will create interfaces into this namespace for React to consume\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface FrontEndConfigurationAccessor {}\n\nexport type TypedFrontEndConfigurationAccessor = keyof FrontEndConfigurationAccessor extends never\n ? Record<string, unknown>\n : {\n [TypedFlagKey in keyof FrontEndConfigurationAccessor]: FrontEndConfigurationAccessor[TypedFlagKey];\n };\n\ntype ClassMethods<T> = { [K in keyof T]: T[K] };\n\ntype QuonfigTypesafeClass<T = unknown> = new (\n // eslint-disable-next-line no-shadow\n quonfig: Quonfig\n) => T;\n\ntype SharedSettings = Partial<\n Pick<\n InitOptions,\n | \"sdkKey\"\n | \"apiUrls\"\n | \"domain\"\n | \"timeout\"\n | \"collectEvaluationSummaries\"\n | \"collectLoggerNames\"\n >\n> & {\n // Convenience alias for a single API URL — normalized to apiUrls=[apiUrl]\n // before being passed to the underlying SDK, which only accepts apiUrls.\n apiUrl?: string;\n // We need to redefine the afterEvaluationCallback type to ensure proper dynamic resolution of K\n afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n contexts: Contexts | undefined\n ) => void;\n pollInterval?: number;\n onError?: (error: Error) => void;\n};\n\nexport type BaseContext = {\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n getDuration: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => Duration | undefined;\n contextAttributes: Contexts;\n isEnabled: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => boolean;\n loading: boolean;\n quonfig: typeof quonfig;\n keys: (keyof TypedFrontEndConfigurationRaw)[];\n settings: SharedSettings;\n};\n\nexport type ProvidedContext = BaseContext & ClassMethods<QuonfigTypesafeClass>;\n\nexport const defaultContext: BaseContext = {\n get: (_key) => undefined,\n getDuration: (_key) => undefined,\n isEnabled: (_key) => false,\n keys: [],\n loading: true,\n contextAttributes: {},\n quonfig,\n settings: {},\n};\n\nexport const QuonfigContext = React.createContext<ProvidedContext>(\n defaultContext as ProvidedContext\n);\n\n// This is a factory function that creates a fully typed useQuonfig hook for a specific QuonfigTypesafe class\nexport function createQuonfigHook<T>(TypesafeClass: QuonfigTypesafeClass<T>) {\n return function useQuonfigHook(): BaseContext & T {\n const baseContext = React.useContext(QuonfigContext);\n\n // Memoize the typesafe instance to prevent unnecessary constructor calls\n const typesafeInstance = React.useMemo(() => {\n const instance = new TypesafeClass(baseContext.quonfig);\n\n // Copy baseContext properties to typesafeInstance except for `get` + `quonfig`\n Object.assign(instance as any, {\n getDuration: baseContext.getDuration,\n contextAttributes: baseContext.contextAttributes,\n isEnabled: baseContext.isEnabled,\n loading: baseContext.loading,\n keys: baseContext.keys,\n settings: baseContext.settings,\n });\n\n return instance;\n }, [baseContext]);\n\n return typesafeInstance as BaseContext & T;\n };\n}\n\n// Basic hook for general use - requires type parameter\nexport const useBaseQuonfig = () => React.useContext(QuonfigContext);\n\n// General hook that returns the context with any explicit type\nexport const useQuonfig = (): ProvidedContext => useBaseQuonfig() as unknown as ProvidedContext;\n\n// qfg-lkpm.6: per-key selector hook. Subscribes via the underlying client's\n// notify list rather than React context, so a flag mutation only re-renders\n// components whose selected key actually changed. `useQuonfig()` re-renders\n// on every dataVersion bump because the context value identity changes; this\n// hook bypasses that.\nexport function useFlag<K extends keyof TypedFrontEndConfigurationRaw>(\n key: K\n): TypedFrontEndConfigurationRaw[K];\nexport function useFlag(key: string): ConfigValue;\nexport function useFlag(key: string): ConfigValue {\n const client = React.useContext(QuonfigClientContext) ?? quonfig;\n const subscribe = React.useCallback(\n (onChange: () => void) => client.subscribe(onChange),\n [client]\n );\n const getSnapshot = React.useCallback(() => client.get(key), [client, key]);\n const getServerSnapshot = React.useCallback((): ConfigValue => undefined, []);\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n// qfg-lkpm.6: replacement for the old module-level `globalQuonfigIsTaken`\n// flag. A provider asks \"is there already a Quonfig client above me in the\n// React tree?\". If yes, mint a fresh client (multi-tenant nesting); if no,\n// claim the module singleton so non-React code that imports `quonfig`\n// directly sees the same instance.\nexport const useQuonfigClient = (): Quonfig => {\n const parentClient = React.useContext(QuonfigClientContext);\n // Mount-only: parent context is fixed for the lifetime of this provider.\n const parentClientRef = React.useRef(parentClient);\n return React.useMemo(() => (parentClientRef.current ? new Quonfig() : quonfig), []);\n};\n\nexport type QuonfigProviderProps = SharedSettings & {\n sdkKey: string;\n contextAttributes?: Contexts;\n initialFlags?: Record<string, unknown>;\n logger?: Logger;\n};\n\nconst getContextKey = (\n contextAttributes: Contexts,\n logger: NormalizedLogger,\n onError: (e: Error) => void\n): string => {\n try {\n if (Object.keys(contextAttributes).length === 0) {\n logger.warn(\n \"QuonfigProvider: You haven't passed any contextAttributes. See https://docs.quonfig.com/docs/sdks/react#using-context\"\n );\n }\n\n return encodeContexts(contextAttributes);\n } catch (e) {\n onError(e as Error);\n return \"\";\n }\n};\n\nfunction QuonfigProvider({\n sdkKey,\n contextAttributes = {},\n onError: userOnError,\n logger,\n initialFlags,\n children,\n timeout,\n apiUrl,\n apiUrls,\n domain,\n pollInterval,\n afterEvaluationCallback = undefined,\n collectEvaluationSummaries,\n collectLoggerNames,\n}: PropsWithChildren<QuonfigProviderProps>) {\n const normalizedLogger = React.useMemo(() => normalizeLogger(logger), [logger]);\n const onError = React.useCallback(\n (e: unknown) => {\n if (userOnError) {\n userOnError(e as Error);\n } else {\n const message = e instanceof Error ? e.message : String(e);\n normalizedLogger.error(message, e);\n }\n },\n [userOnError, normalizedLogger]\n );\n const settings = {\n sdkKey,\n apiUrl,\n apiUrls,\n domain,\n timeout,\n pollInterval,\n onError,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n collectLoggerNames,\n };\n\n // We use this state to prevent a double-init when useEffect fires due to\n // StrictMode\n const mostRecentlyLoadingContextKey = React.useRef<string | undefined>(undefined);\n // We use this state to pass the loading state to the Provider (updating\n // currentLoadingContextKey won't trigger an update)\n const [loading, setLoading] = React.useState(true);\n const [initialLoad, setInitialLoad] = React.useState(true);\n // Here we track the current identity so we can reload our config when it\n // changes\n const [loadedContextKey, setLoadedContextKey] = React.useState(\"\");\n\n const quonfigClient: Quonfig = useQuonfigClient();\n\n // qfg-daxq: re-render when the underlying client's in-memory config changes\n // (poll fetch, setConfig, hydrate). Without this the singleton mutates in\n // place and React never sees the update.\n const dataVersion = React.useSyncExternalStore(\n React.useCallback((onChange) => quonfigClient.subscribe(onChange), [quonfigClient]),\n React.useCallback(() => quonfigClient.dataVersion, [quonfigClient]),\n React.useCallback(() => 0, [])\n );\n\n const contextKey = getContextKey(contextAttributes, normalizedLogger, onError);\n\n if (initialFlags && initialLoad) {\n quonfigClient.hydrate(initialFlags);\n setInitialLoad(false);\n setLoadedContextKey(contextKey);\n setLoading(false);\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (pollInterval) {\n normalizedLogger.warn(\"Polling is not supported when hydrating flags via initialFlags\");\n }\n }\n\n React.useEffect(() => {\n setInitialLoad(false);\n\n if (mostRecentlyLoadingContextKey.current === contextKey) {\n return;\n }\n\n setLoading(true);\n try {\n if (mostRecentlyLoadingContextKey.current === undefined) {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (!sdkKey) {\n throw new Error(\"QuonfigProvider: sdkKey is required\");\n }\n\n quonfigClient.clientName = \"react\";\n quonfigClient.clientVersion = reactSdkVersion;\n\n const resolvedApiUrls = apiUrls ?? (apiUrl ? [apiUrl] : undefined);\n\n const initOptions: InitOptions = {\n context: contextAttributes,\n sdkKey,\n apiUrls: resolvedApiUrls,\n domain,\n timeout,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n collectLoggerNames,\n };\n\n quonfigClient\n .init(initOptions)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n\n if (pollInterval) {\n quonfigClient.poll({ frequencyInMs: pollInterval });\n }\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n } else {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n quonfigClient\n .updateContext(contextAttributes)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n }\n } catch (e) {\n setLoading(false);\n onError(e as Error);\n }\n }, [\n sdkKey,\n loadedContextKey,\n contextKey,\n loading,\n setLoading,\n onError,\n quonfigClient.instanceHash,\n ]);\n\n // qfg-2acr: drain telemetry + stop polling/telemetry timers when the\n // provider unmounts so route swaps don't leave the singleton polling\n // forever. Mount-only deps so context-attribute changes don't tear down\n // the SDK. In React StrictMode the synthetic unmount fires too — we\n // reset the init-guard ref so the next mount cleanly re-inits.\n React.useEffect(\n () => () => {\n quonfigClient.close().catch(() => {});\n mostRecentlyLoadingContextKey.current = undefined;\n },\n [quonfigClient]\n );\n\n const value = React.useMemo(() => {\n const baseContext: ProvidedContext = {\n isEnabled: quonfigClient.isEnabled.bind(quonfigClient),\n contextAttributes,\n get: quonfigClient.get.bind(quonfigClient),\n getDuration: quonfigClient.getDuration.bind(quonfigClient),\n keys: Object.keys(quonfigClient.extract()),\n quonfig: quonfigClient,\n loading,\n settings,\n };\n\n return baseContext;\n }, [loadedContextKey, loading, quonfigClient.instanceHash, settings, dataVersion]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigProvider, QuonfigClientContext, ConfigValue, SharedSettings, QuonfigTypesafeClass };\n","import React, { PropsWithChildren } from \"react\";\nimport {\n QuonfigContext,\n QuonfigClientContext,\n useQuonfigClient,\n ProvidedContext,\n} from \"./QuonfigProvider\";\n\nexport type QuonfigTestProviderProps = {\n config: Record<string, any>;\n sdkKey?: string;\n};\n\nfunction QuonfigTestProvider({\n sdkKey,\n config,\n children,\n}: PropsWithChildren<QuonfigTestProviderProps>) {\n const get = (key: string) => config[key];\n const getDuration = (key: string) => config[key];\n const isEnabled = (key: string) => !!get(key);\n\n const quonfigClient = useQuonfigClient();\n\n const value = React.useMemo(() => {\n quonfigClient.get = get;\n quonfigClient.getDuration = getDuration;\n quonfigClient.isEnabled = isEnabled;\n\n const baseContext: ProvidedContext = {\n isEnabled,\n contextAttributes: config.contextAttributes,\n get,\n getDuration,\n loading: false,\n quonfig: quonfigClient,\n keys: Object.keys(config),\n settings: { sdkKey: sdkKey ?? \"fake-sdk-key-via-the-test-provider\" },\n };\n\n return baseContext;\n }, [config, quonfigClient, sdkKey]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigTestProvider };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/sdkLogger.ts","../src/QuonfigProvider.tsx","../src/QuonfigTestProvider.tsx"],"names":["React","quonfig","Quonfig","encodeContexts"],"mappings":"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","file":"index.cjs","sourcesContent":["// AUTO-GENERATED from package.json by scripts/generate-version.mjs — do not edit.\nexport default \"0.0.9\";\n","/**\n * Pluggable logger interface for SDK-internal warnings and errors.\n *\n * Shape mirrors @quonfig/node so the contract is uniform across the\n * TypeScript SDKs: `warn` and `error` are required; `debug` and `info` are\n * optional and become no-ops when the supplied logger does not implement\n * them.\n */\nexport interface Logger {\n debug?(message: string, ...args: unknown[]): void;\n info?(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport interface NormalizedLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst NOOP = (): void => {};\n\nconst PREFIX = \"[quonfig]\";\n\nfunction defaultSdkLogger(): NormalizedLogger {\n return {\n /* eslint-disable no-console */\n debug: (message, ...args) => console.debug(PREFIX, message, ...args),\n info: (message, ...args) => console.info(PREFIX, message, ...args),\n warn: (message, ...args) => console.warn(PREFIX, message, ...args),\n error: (message, ...args) => console.error(PREFIX, message, ...args),\n /* eslint-enable no-console */\n };\n}\n\nexport function normalizeLogger(logger: Logger | undefined): NormalizedLogger {\n if (!logger) return defaultSdkLogger();\n return {\n debug: logger.debug ? logger.debug.bind(logger) : NOOP,\n info: logger.info ? logger.info.bind(logger) : NOOP,\n warn: logger.warn.bind(logger),\n error: logger.error.bind(logger),\n };\n}\n","import React, { PropsWithChildren } from \"react\";\nimport {\n quonfig,\n type InitOptions,\n type ConfigValue,\n type Contexts,\n Quonfig,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Duration,\n encodeContexts,\n} from \"@quonfig/javascript\";\nimport reactSdkVersion from \"./version\";\nimport { normalizeLogger, type Logger, type NormalizedLogger } from \"./sdkLogger\";\n\n// qfg-lkpm.6: per-tree owner context. The value is the active Quonfig client\n// for this provider subtree. A null value means no Provider is above us, so\n// the next mount can claim the module-level singleton; a non-null value\n// signals \"you're nested, mint a fresh client\". This replaces the previous\n// module-level `globalQuonfigIsTaken` flag, which never reset and so leaked\n// state across test runs and (in principle) across SSR render trees.\nconst QuonfigClientContext = React.createContext<Quonfig | null>(null);\n\n// @quonfig/cli#generate will create interfaces into this namespace for React to consume\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface FrontEndConfigurationAccessor {}\n\nexport type TypedFrontEndConfigurationAccessor = keyof FrontEndConfigurationAccessor extends never\n ? Record<string, unknown>\n : {\n [TypedFlagKey in keyof FrontEndConfigurationAccessor]: FrontEndConfigurationAccessor[TypedFlagKey];\n };\n\ntype ClassMethods<T> = { [K in keyof T]: T[K] };\n\ntype QuonfigTypesafeClass<T = unknown> = new (\n // eslint-disable-next-line no-shadow\n quonfig: Quonfig\n) => T;\n\ntype SharedSettings = Partial<\n Pick<InitOptions, \"sdkKey\" | \"apiUrls\" | \"domain\" | \"timeout\" | \"collectEvaluationSummaries\">\n> & {\n // Convenience alias for a single API URL — normalized to apiUrls=[apiUrl]\n // before being passed to the underlying SDK, which only accepts apiUrls.\n apiUrl?: string;\n // We need to redefine the afterEvaluationCallback type to ensure proper dynamic resolution of K\n afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n contexts: Contexts | undefined\n ) => void;\n pollInterval?: number;\n onError?: (error: Error) => void;\n};\n\nexport type BaseContext = {\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n getDuration: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => Duration | undefined;\n contextAttributes: Contexts;\n isEnabled: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => boolean;\n loading: boolean;\n quonfig: typeof quonfig;\n keys: (keyof TypedFrontEndConfigurationRaw)[];\n settings: SharedSettings;\n};\n\nexport type ProvidedContext = BaseContext & ClassMethods<QuonfigTypesafeClass>;\n\nexport const defaultContext: BaseContext = {\n get: (_key) => undefined,\n getDuration: (_key) => undefined,\n isEnabled: (_key) => false,\n keys: [],\n loading: true,\n contextAttributes: {},\n quonfig,\n settings: {},\n};\n\nexport const QuonfigContext = React.createContext<ProvidedContext>(\n defaultContext as ProvidedContext\n);\n\n// This is a factory function that creates a fully typed useQuonfig hook for a specific QuonfigTypesafe class\nexport function createQuonfigHook<T>(TypesafeClass: QuonfigTypesafeClass<T>) {\n return function useQuonfigHook(): BaseContext & T {\n const baseContext = React.useContext(QuonfigContext);\n\n // Memoize the typesafe instance to prevent unnecessary constructor calls\n const typesafeInstance = React.useMemo(() => {\n const instance = new TypesafeClass(baseContext.quonfig);\n\n // Copy baseContext properties to typesafeInstance except for `get` + `quonfig`\n Object.assign(instance as any, {\n getDuration: baseContext.getDuration,\n contextAttributes: baseContext.contextAttributes,\n isEnabled: baseContext.isEnabled,\n loading: baseContext.loading,\n keys: baseContext.keys,\n settings: baseContext.settings,\n });\n\n return instance;\n }, [baseContext]);\n\n return typesafeInstance as BaseContext & T;\n };\n}\n\n// Basic hook for general use - requires type parameter\nexport const useBaseQuonfig = () => React.useContext(QuonfigContext);\n\n// General hook that returns the context with any explicit type\nexport const useQuonfig = (): ProvidedContext => useBaseQuonfig() as unknown as ProvidedContext;\n\n// qfg-lkpm.6: per-key selector hook. Subscribes via the underlying client's\n// notify list rather than React context, so a flag mutation only re-renders\n// components whose selected key actually changed. `useQuonfig()` re-renders\n// on every dataVersion bump because the context value identity changes; this\n// hook bypasses that.\nexport function useFlag<K extends keyof TypedFrontEndConfigurationRaw>(\n key: K\n): TypedFrontEndConfigurationRaw[K];\nexport function useFlag(key: string): ConfigValue;\nexport function useFlag(key: string): ConfigValue {\n const client = React.useContext(QuonfigClientContext) ?? quonfig;\n const subscribe = React.useCallback(\n (onChange: () => void) => client.subscribe(onChange),\n [client]\n );\n const getSnapshot = React.useCallback(() => client.get(key), [client, key]);\n const getServerSnapshot = React.useCallback((): ConfigValue => undefined, []);\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n// qfg-lkpm.6: replacement for the old module-level `globalQuonfigIsTaken`\n// flag. A provider asks \"is there already a Quonfig client above me in the\n// React tree?\". If yes, mint a fresh client (multi-tenant nesting); if no,\n// claim the module singleton so non-React code that imports `quonfig`\n// directly sees the same instance.\nexport const useQuonfigClient = (): Quonfig => {\n const parentClient = React.useContext(QuonfigClientContext);\n // Mount-only: parent context is fixed for the lifetime of this provider.\n const parentClientRef = React.useRef(parentClient);\n return React.useMemo(() => (parentClientRef.current ? new Quonfig() : quonfig), []);\n};\n\nexport type QuonfigProviderProps = SharedSettings & {\n sdkKey: string;\n contextAttributes?: Contexts;\n initialFlags?: Record<string, unknown>;\n logger?: Logger;\n};\n\nconst getContextKey = (\n contextAttributes: Contexts,\n logger: NormalizedLogger,\n onError: (e: Error) => void\n): string => {\n try {\n if (Object.keys(contextAttributes).length === 0) {\n logger.warn(\n \"QuonfigProvider: You haven't passed any contextAttributes. See https://docs.quonfig.com/docs/sdks/react#using-context\"\n );\n }\n\n return encodeContexts(contextAttributes);\n } catch (e) {\n onError(e as Error);\n return \"\";\n }\n};\n\nfunction QuonfigProvider({\n sdkKey,\n contextAttributes = {},\n onError: userOnError,\n logger,\n initialFlags,\n children,\n timeout,\n apiUrl,\n apiUrls,\n domain,\n pollInterval,\n afterEvaluationCallback = undefined,\n collectEvaluationSummaries,\n}: PropsWithChildren<QuonfigProviderProps>) {\n const normalizedLogger = React.useMemo(() => normalizeLogger(logger), [logger]);\n const onError = React.useCallback(\n (e: unknown) => {\n if (userOnError) {\n userOnError(e as Error);\n } else {\n const message = e instanceof Error ? e.message : String(e);\n normalizedLogger.error(message, e);\n }\n },\n [userOnError, normalizedLogger]\n );\n const settings = {\n sdkKey,\n apiUrl,\n apiUrls,\n domain,\n timeout,\n pollInterval,\n onError,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n };\n\n // We use this state to prevent a double-init when useEffect fires due to\n // StrictMode\n const mostRecentlyLoadingContextKey = React.useRef<string | undefined>(undefined);\n // We use this state to pass the loading state to the Provider (updating\n // currentLoadingContextKey won't trigger an update)\n const [loading, setLoading] = React.useState(true);\n const [initialLoad, setInitialLoad] = React.useState(true);\n // Here we track the current identity so we can reload our config when it\n // changes\n const [loadedContextKey, setLoadedContextKey] = React.useState(\"\");\n\n const quonfigClient: Quonfig = useQuonfigClient();\n\n // qfg-daxq: re-render when the underlying client's in-memory config changes\n // (poll fetch, setConfig, hydrate). Without this the singleton mutates in\n // place and React never sees the update.\n const dataVersion = React.useSyncExternalStore(\n React.useCallback((onChange) => quonfigClient.subscribe(onChange), [quonfigClient]),\n React.useCallback(() => quonfigClient.dataVersion, [quonfigClient]),\n React.useCallback(() => 0, [])\n );\n\n const contextKey = getContextKey(contextAttributes, normalizedLogger, onError);\n\n if (initialFlags && initialLoad) {\n quonfigClient.hydrate(initialFlags);\n setInitialLoad(false);\n setLoadedContextKey(contextKey);\n setLoading(false);\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (pollInterval) {\n normalizedLogger.warn(\"Polling is not supported when hydrating flags via initialFlags\");\n }\n }\n\n React.useEffect(() => {\n setInitialLoad(false);\n\n if (mostRecentlyLoadingContextKey.current === contextKey) {\n return;\n }\n\n setLoading(true);\n try {\n if (mostRecentlyLoadingContextKey.current === undefined) {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (!sdkKey) {\n throw new Error(\"QuonfigProvider: sdkKey is required\");\n }\n\n quonfigClient.clientName = \"react\";\n quonfigClient.clientVersion = reactSdkVersion;\n\n const resolvedApiUrls = apiUrls ?? (apiUrl ? [apiUrl] : undefined);\n\n const initOptions: InitOptions = {\n context: contextAttributes,\n sdkKey,\n apiUrls: resolvedApiUrls,\n domain,\n timeout,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n };\n\n quonfigClient\n .init(initOptions)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n\n if (pollInterval) {\n quonfigClient.poll({ frequencyInMs: pollInterval });\n }\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n } else {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n quonfigClient\n .updateContext(contextAttributes)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n }\n } catch (e) {\n setLoading(false);\n onError(e as Error);\n }\n }, [\n sdkKey,\n loadedContextKey,\n contextKey,\n loading,\n setLoading,\n onError,\n quonfigClient.instanceHash,\n ]);\n\n // qfg-2acr: drain telemetry + stop polling/telemetry timers when the\n // provider unmounts so route swaps don't leave the singleton polling\n // forever. Mount-only deps so context-attribute changes don't tear down\n // the SDK. In React StrictMode the synthetic unmount fires too — we\n // reset the init-guard ref so the next mount cleanly re-inits.\n React.useEffect(\n () => () => {\n quonfigClient.close().catch(() => {});\n mostRecentlyLoadingContextKey.current = undefined;\n },\n [quonfigClient]\n );\n\n const value = React.useMemo(() => {\n const baseContext: ProvidedContext = {\n isEnabled: quonfigClient.isEnabled.bind(quonfigClient),\n contextAttributes,\n get: quonfigClient.get.bind(quonfigClient),\n getDuration: quonfigClient.getDuration.bind(quonfigClient),\n keys: Object.keys(quonfigClient.extract()),\n quonfig: quonfigClient,\n loading,\n settings,\n };\n\n return baseContext;\n }, [loadedContextKey, loading, quonfigClient.instanceHash, settings, dataVersion]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigProvider, QuonfigClientContext, ConfigValue, SharedSettings, QuonfigTypesafeClass };\n","import React, { PropsWithChildren } from \"react\";\nimport {\n QuonfigContext,\n QuonfigClientContext,\n useQuonfigClient,\n ProvidedContext,\n} from \"./QuonfigProvider\";\n\nexport type QuonfigTestProviderProps = {\n config: Record<string, any>;\n sdkKey?: string;\n};\n\nfunction QuonfigTestProvider({\n sdkKey,\n config,\n children,\n}: PropsWithChildren<QuonfigTestProviderProps>) {\n const get = (key: string) => config[key];\n const getDuration = (key: string) => config[key];\n const isEnabled = (key: string) => !!get(key);\n\n const quonfigClient = useQuonfigClient();\n\n const value = React.useMemo(() => {\n quonfigClient.get = get;\n quonfigClient.getDuration = getDuration;\n quonfigClient.isEnabled = isEnabled;\n\n const baseContext: ProvidedContext = {\n isEnabled,\n contextAttributes: config.contextAttributes,\n get,\n getDuration,\n loading: false,\n quonfig: quonfigClient,\n keys: Object.keys(config),\n settings: { sdkKey: sdkKey ?? \"fake-sdk-key-via-the-test-provider\" },\n };\n\n return baseContext;\n }, [config, quonfigClient, sdkKey]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigTestProvider };\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -26,7 +26,7 @@ type ClassMethods<T> = {
|
|
|
26
26
|
[K in keyof T]: T[K];
|
|
27
27
|
};
|
|
28
28
|
type QuonfigTypesafeClass<T = unknown> = new (quonfig: Quonfig) => T;
|
|
29
|
-
type SharedSettings = Partial<Pick<InitOptions, "sdkKey" | "apiUrls" | "domain" | "timeout" | "collectEvaluationSummaries"
|
|
29
|
+
type SharedSettings = Partial<Pick<InitOptions, "sdkKey" | "apiUrls" | "domain" | "timeout" | "collectEvaluationSummaries">> & {
|
|
30
30
|
apiUrl?: string;
|
|
31
31
|
afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(key: K, value: TypedFrontEndConfigurationRaw[K], contexts: Contexts | undefined) => void;
|
|
32
32
|
pollInterval?: number;
|
|
@@ -57,7 +57,7 @@ type QuonfigProviderProps = SharedSettings & {
|
|
|
57
57
|
initialFlags?: Record<string, unknown>;
|
|
58
58
|
logger?: Logger;
|
|
59
59
|
};
|
|
60
|
-
declare function QuonfigProvider({ sdkKey, contextAttributes, onError: userOnError, logger, initialFlags, children, timeout, apiUrl, apiUrls, domain, pollInterval, afterEvaluationCallback, collectEvaluationSummaries,
|
|
60
|
+
declare function QuonfigProvider({ sdkKey, contextAttributes, onError: userOnError, logger, initialFlags, children, timeout, apiUrl, apiUrls, domain, pollInterval, afterEvaluationCallback, collectEvaluationSummaries, }: PropsWithChildren<QuonfigProviderProps>): React.JSX.Element;
|
|
61
61
|
|
|
62
62
|
type QuonfigTestProviderProps = {
|
|
63
63
|
config: Record<string, any>;
|
package/dist/index.d.ts
CHANGED
|
@@ -26,7 +26,7 @@ type ClassMethods<T> = {
|
|
|
26
26
|
[K in keyof T]: T[K];
|
|
27
27
|
};
|
|
28
28
|
type QuonfigTypesafeClass<T = unknown> = new (quonfig: Quonfig) => T;
|
|
29
|
-
type SharedSettings = Partial<Pick<InitOptions, "sdkKey" | "apiUrls" | "domain" | "timeout" | "collectEvaluationSummaries"
|
|
29
|
+
type SharedSettings = Partial<Pick<InitOptions, "sdkKey" | "apiUrls" | "domain" | "timeout" | "collectEvaluationSummaries">> & {
|
|
30
30
|
apiUrl?: string;
|
|
31
31
|
afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(key: K, value: TypedFrontEndConfigurationRaw[K], contexts: Contexts | undefined) => void;
|
|
32
32
|
pollInterval?: number;
|
|
@@ -57,7 +57,7 @@ type QuonfigProviderProps = SharedSettings & {
|
|
|
57
57
|
initialFlags?: Record<string, unknown>;
|
|
58
58
|
logger?: Logger;
|
|
59
59
|
};
|
|
60
|
-
declare function QuonfigProvider({ sdkKey, contextAttributes, onError: userOnError, logger, initialFlags, children, timeout, apiUrl, apiUrls, domain, pollInterval, afterEvaluationCallback, collectEvaluationSummaries,
|
|
60
|
+
declare function QuonfigProvider({ sdkKey, contextAttributes, onError: userOnError, logger, initialFlags, children, timeout, apiUrl, apiUrls, domain, pollInterval, afterEvaluationCallback, collectEvaluationSummaries, }: PropsWithChildren<QuonfigProviderProps>): React.JSX.Element;
|
|
61
61
|
|
|
62
62
|
type QuonfigTestProviderProps = {
|
|
63
63
|
config: Record<string, any>;
|
package/dist/index.mjs
CHANGED
|
@@ -108,8 +108,7 @@ function QuonfigProvider({
|
|
|
108
108
|
domain,
|
|
109
109
|
pollInterval,
|
|
110
110
|
afterEvaluationCallback = void 0,
|
|
111
|
-
collectEvaluationSummaries
|
|
112
|
-
collectLoggerNames
|
|
111
|
+
collectEvaluationSummaries
|
|
113
112
|
}) {
|
|
114
113
|
const normalizedLogger = React.useMemo(() => normalizeLogger(logger), [logger]);
|
|
115
114
|
const onError = React.useCallback(
|
|
@@ -132,8 +131,7 @@ function QuonfigProvider({
|
|
|
132
131
|
pollInterval,
|
|
133
132
|
onError,
|
|
134
133
|
afterEvaluationCallback,
|
|
135
|
-
collectEvaluationSummaries
|
|
136
|
-
collectLoggerNames
|
|
134
|
+
collectEvaluationSummaries
|
|
137
135
|
};
|
|
138
136
|
const mostRecentlyLoadingContextKey = React.useRef(void 0);
|
|
139
137
|
const [loading, setLoading] = React.useState(true);
|
|
@@ -178,8 +176,7 @@ function QuonfigProvider({
|
|
|
178
176
|
domain,
|
|
179
177
|
timeout,
|
|
180
178
|
afterEvaluationCallback,
|
|
181
|
-
collectEvaluationSummaries
|
|
182
|
-
collectLoggerNames
|
|
179
|
+
collectEvaluationSummaries
|
|
183
180
|
};
|
|
184
181
|
quonfigClient.init(initOptions).then(() => {
|
|
185
182
|
setLoadedContextKey(contextKey);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts","../src/sdkLogger.ts","../src/QuonfigProvider.tsx","../src/QuonfigTestProvider.tsx"],"names":["React"],"mappings":"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","file":"index.mjs","sourcesContent":["// AUTO-GENERATED from package.json by scripts/generate-version.mjs — do not edit.\nexport default \"0.0.9\";\n","/**\n * Pluggable logger interface for SDK-internal warnings and errors.\n *\n * Shape mirrors @quonfig/node so the contract is uniform across the\n * TypeScript SDKs: `warn` and `error` are required; `debug` and `info` are\n * optional and become no-ops when the supplied logger does not implement\n * them.\n */\nexport interface Logger {\n debug?(message: string, ...args: unknown[]): void;\n info?(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport interface NormalizedLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst NOOP = (): void => {};\n\nconst PREFIX = \"[quonfig]\";\n\nfunction defaultSdkLogger(): NormalizedLogger {\n return {\n /* eslint-disable no-console */\n debug: (message, ...args) => console.debug(PREFIX, message, ...args),\n info: (message, ...args) => console.info(PREFIX, message, ...args),\n warn: (message, ...args) => console.warn(PREFIX, message, ...args),\n error: (message, ...args) => console.error(PREFIX, message, ...args),\n /* eslint-enable no-console */\n };\n}\n\nexport function normalizeLogger(logger: Logger | undefined): NormalizedLogger {\n if (!logger) return defaultSdkLogger();\n return {\n debug: logger.debug ? logger.debug.bind(logger) : NOOP,\n info: logger.info ? logger.info.bind(logger) : NOOP,\n warn: logger.warn.bind(logger),\n error: logger.error.bind(logger),\n };\n}\n","import React, { PropsWithChildren } from \"react\";\nimport {\n quonfig,\n type InitOptions,\n type ConfigValue,\n type Contexts,\n Quonfig,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Duration,\n encodeContexts,\n} from \"@quonfig/javascript\";\nimport reactSdkVersion from \"./version\";\nimport { normalizeLogger, type Logger, type NormalizedLogger } from \"./sdkLogger\";\n\n// qfg-lkpm.6: per-tree owner context. The value is the active Quonfig client\n// for this provider subtree. A null value means no Provider is above us, so\n// the next mount can claim the module-level singleton; a non-null value\n// signals \"you're nested, mint a fresh client\". This replaces the previous\n// module-level `globalQuonfigIsTaken` flag, which never reset and so leaked\n// state across test runs and (in principle) across SSR render trees.\nconst QuonfigClientContext = React.createContext<Quonfig | null>(null);\n\n// @quonfig/cli#generate will create interfaces into this namespace for React to consume\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface FrontEndConfigurationAccessor {}\n\nexport type TypedFrontEndConfigurationAccessor = keyof FrontEndConfigurationAccessor extends never\n ? Record<string, unknown>\n : {\n [TypedFlagKey in keyof FrontEndConfigurationAccessor]: FrontEndConfigurationAccessor[TypedFlagKey];\n };\n\ntype ClassMethods<T> = { [K in keyof T]: T[K] };\n\ntype QuonfigTypesafeClass<T = unknown> = new (\n // eslint-disable-next-line no-shadow\n quonfig: Quonfig\n) => T;\n\ntype SharedSettings = Partial<\n Pick<\n InitOptions,\n | \"sdkKey\"\n | \"apiUrls\"\n | \"domain\"\n | \"timeout\"\n | \"collectEvaluationSummaries\"\n | \"collectLoggerNames\"\n >\n> & {\n // Convenience alias for a single API URL — normalized to apiUrls=[apiUrl]\n // before being passed to the underlying SDK, which only accepts apiUrls.\n apiUrl?: string;\n // We need to redefine the afterEvaluationCallback type to ensure proper dynamic resolution of K\n afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n contexts: Contexts | undefined\n ) => void;\n pollInterval?: number;\n onError?: (error: Error) => void;\n};\n\nexport type BaseContext = {\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n getDuration: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => Duration | undefined;\n contextAttributes: Contexts;\n isEnabled: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => boolean;\n loading: boolean;\n quonfig: typeof quonfig;\n keys: (keyof TypedFrontEndConfigurationRaw)[];\n settings: SharedSettings;\n};\n\nexport type ProvidedContext = BaseContext & ClassMethods<QuonfigTypesafeClass>;\n\nexport const defaultContext: BaseContext = {\n get: (_key) => undefined,\n getDuration: (_key) => undefined,\n isEnabled: (_key) => false,\n keys: [],\n loading: true,\n contextAttributes: {},\n quonfig,\n settings: {},\n};\n\nexport const QuonfigContext = React.createContext<ProvidedContext>(\n defaultContext as ProvidedContext\n);\n\n// This is a factory function that creates a fully typed useQuonfig hook for a specific QuonfigTypesafe class\nexport function createQuonfigHook<T>(TypesafeClass: QuonfigTypesafeClass<T>) {\n return function useQuonfigHook(): BaseContext & T {\n const baseContext = React.useContext(QuonfigContext);\n\n // Memoize the typesafe instance to prevent unnecessary constructor calls\n const typesafeInstance = React.useMemo(() => {\n const instance = new TypesafeClass(baseContext.quonfig);\n\n // Copy baseContext properties to typesafeInstance except for `get` + `quonfig`\n Object.assign(instance as any, {\n getDuration: baseContext.getDuration,\n contextAttributes: baseContext.contextAttributes,\n isEnabled: baseContext.isEnabled,\n loading: baseContext.loading,\n keys: baseContext.keys,\n settings: baseContext.settings,\n });\n\n return instance;\n }, [baseContext]);\n\n return typesafeInstance as BaseContext & T;\n };\n}\n\n// Basic hook for general use - requires type parameter\nexport const useBaseQuonfig = () => React.useContext(QuonfigContext);\n\n// General hook that returns the context with any explicit type\nexport const useQuonfig = (): ProvidedContext => useBaseQuonfig() as unknown as ProvidedContext;\n\n// qfg-lkpm.6: per-key selector hook. Subscribes via the underlying client's\n// notify list rather than React context, so a flag mutation only re-renders\n// components whose selected key actually changed. `useQuonfig()` re-renders\n// on every dataVersion bump because the context value identity changes; this\n// hook bypasses that.\nexport function useFlag<K extends keyof TypedFrontEndConfigurationRaw>(\n key: K\n): TypedFrontEndConfigurationRaw[K];\nexport function useFlag(key: string): ConfigValue;\nexport function useFlag(key: string): ConfigValue {\n const client = React.useContext(QuonfigClientContext) ?? quonfig;\n const subscribe = React.useCallback(\n (onChange: () => void) => client.subscribe(onChange),\n [client]\n );\n const getSnapshot = React.useCallback(() => client.get(key), [client, key]);\n const getServerSnapshot = React.useCallback((): ConfigValue => undefined, []);\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n// qfg-lkpm.6: replacement for the old module-level `globalQuonfigIsTaken`\n// flag. A provider asks \"is there already a Quonfig client above me in the\n// React tree?\". If yes, mint a fresh client (multi-tenant nesting); if no,\n// claim the module singleton so non-React code that imports `quonfig`\n// directly sees the same instance.\nexport const useQuonfigClient = (): Quonfig => {\n const parentClient = React.useContext(QuonfigClientContext);\n // Mount-only: parent context is fixed for the lifetime of this provider.\n const parentClientRef = React.useRef(parentClient);\n return React.useMemo(() => (parentClientRef.current ? new Quonfig() : quonfig), []);\n};\n\nexport type QuonfigProviderProps = SharedSettings & {\n sdkKey: string;\n contextAttributes?: Contexts;\n initialFlags?: Record<string, unknown>;\n logger?: Logger;\n};\n\nconst getContextKey = (\n contextAttributes: Contexts,\n logger: NormalizedLogger,\n onError: (e: Error) => void\n): string => {\n try {\n if (Object.keys(contextAttributes).length === 0) {\n logger.warn(\n \"QuonfigProvider: You haven't passed any contextAttributes. See https://docs.quonfig.com/docs/sdks/react#using-context\"\n );\n }\n\n return encodeContexts(contextAttributes);\n } catch (e) {\n onError(e as Error);\n return \"\";\n }\n};\n\nfunction QuonfigProvider({\n sdkKey,\n contextAttributes = {},\n onError: userOnError,\n logger,\n initialFlags,\n children,\n timeout,\n apiUrl,\n apiUrls,\n domain,\n pollInterval,\n afterEvaluationCallback = undefined,\n collectEvaluationSummaries,\n collectLoggerNames,\n}: PropsWithChildren<QuonfigProviderProps>) {\n const normalizedLogger = React.useMemo(() => normalizeLogger(logger), [logger]);\n const onError = React.useCallback(\n (e: unknown) => {\n if (userOnError) {\n userOnError(e as Error);\n } else {\n const message = e instanceof Error ? e.message : String(e);\n normalizedLogger.error(message, e);\n }\n },\n [userOnError, normalizedLogger]\n );\n const settings = {\n sdkKey,\n apiUrl,\n apiUrls,\n domain,\n timeout,\n pollInterval,\n onError,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n collectLoggerNames,\n };\n\n // We use this state to prevent a double-init when useEffect fires due to\n // StrictMode\n const mostRecentlyLoadingContextKey = React.useRef<string | undefined>(undefined);\n // We use this state to pass the loading state to the Provider (updating\n // currentLoadingContextKey won't trigger an update)\n const [loading, setLoading] = React.useState(true);\n const [initialLoad, setInitialLoad] = React.useState(true);\n // Here we track the current identity so we can reload our config when it\n // changes\n const [loadedContextKey, setLoadedContextKey] = React.useState(\"\");\n\n const quonfigClient: Quonfig = useQuonfigClient();\n\n // qfg-daxq: re-render when the underlying client's in-memory config changes\n // (poll fetch, setConfig, hydrate). Without this the singleton mutates in\n // place and React never sees the update.\n const dataVersion = React.useSyncExternalStore(\n React.useCallback((onChange) => quonfigClient.subscribe(onChange), [quonfigClient]),\n React.useCallback(() => quonfigClient.dataVersion, [quonfigClient]),\n React.useCallback(() => 0, [])\n );\n\n const contextKey = getContextKey(contextAttributes, normalizedLogger, onError);\n\n if (initialFlags && initialLoad) {\n quonfigClient.hydrate(initialFlags);\n setInitialLoad(false);\n setLoadedContextKey(contextKey);\n setLoading(false);\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (pollInterval) {\n normalizedLogger.warn(\"Polling is not supported when hydrating flags via initialFlags\");\n }\n }\n\n React.useEffect(() => {\n setInitialLoad(false);\n\n if (mostRecentlyLoadingContextKey.current === contextKey) {\n return;\n }\n\n setLoading(true);\n try {\n if (mostRecentlyLoadingContextKey.current === undefined) {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (!sdkKey) {\n throw new Error(\"QuonfigProvider: sdkKey is required\");\n }\n\n quonfigClient.clientName = \"react\";\n quonfigClient.clientVersion = reactSdkVersion;\n\n const resolvedApiUrls = apiUrls ?? (apiUrl ? [apiUrl] : undefined);\n\n const initOptions: InitOptions = {\n context: contextAttributes,\n sdkKey,\n apiUrls: resolvedApiUrls,\n domain,\n timeout,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n collectLoggerNames,\n };\n\n quonfigClient\n .init(initOptions)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n\n if (pollInterval) {\n quonfigClient.poll({ frequencyInMs: pollInterval });\n }\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n } else {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n quonfigClient\n .updateContext(contextAttributes)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n }\n } catch (e) {\n setLoading(false);\n onError(e as Error);\n }\n }, [\n sdkKey,\n loadedContextKey,\n contextKey,\n loading,\n setLoading,\n onError,\n quonfigClient.instanceHash,\n ]);\n\n // qfg-2acr: drain telemetry + stop polling/telemetry timers when the\n // provider unmounts so route swaps don't leave the singleton polling\n // forever. Mount-only deps so context-attribute changes don't tear down\n // the SDK. In React StrictMode the synthetic unmount fires too — we\n // reset the init-guard ref so the next mount cleanly re-inits.\n React.useEffect(\n () => () => {\n quonfigClient.close().catch(() => {});\n mostRecentlyLoadingContextKey.current = undefined;\n },\n [quonfigClient]\n );\n\n const value = React.useMemo(() => {\n const baseContext: ProvidedContext = {\n isEnabled: quonfigClient.isEnabled.bind(quonfigClient),\n contextAttributes,\n get: quonfigClient.get.bind(quonfigClient),\n getDuration: quonfigClient.getDuration.bind(quonfigClient),\n keys: Object.keys(quonfigClient.extract()),\n quonfig: quonfigClient,\n loading,\n settings,\n };\n\n return baseContext;\n }, [loadedContextKey, loading, quonfigClient.instanceHash, settings, dataVersion]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigProvider, QuonfigClientContext, ConfigValue, SharedSettings, QuonfigTypesafeClass };\n","import React, { PropsWithChildren } from \"react\";\nimport {\n QuonfigContext,\n QuonfigClientContext,\n useQuonfigClient,\n ProvidedContext,\n} from \"./QuonfigProvider\";\n\nexport type QuonfigTestProviderProps = {\n config: Record<string, any>;\n sdkKey?: string;\n};\n\nfunction QuonfigTestProvider({\n sdkKey,\n config,\n children,\n}: PropsWithChildren<QuonfigTestProviderProps>) {\n const get = (key: string) => config[key];\n const getDuration = (key: string) => config[key];\n const isEnabled = (key: string) => !!get(key);\n\n const quonfigClient = useQuonfigClient();\n\n const value = React.useMemo(() => {\n quonfigClient.get = get;\n quonfigClient.getDuration = getDuration;\n quonfigClient.isEnabled = isEnabled;\n\n const baseContext: ProvidedContext = {\n isEnabled,\n contextAttributes: config.contextAttributes,\n get,\n getDuration,\n loading: false,\n quonfig: quonfigClient,\n keys: Object.keys(config),\n settings: { sdkKey: sdkKey ?? \"fake-sdk-key-via-the-test-provider\" },\n };\n\n return baseContext;\n }, [config, quonfigClient, sdkKey]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigTestProvider };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../src/sdkLogger.ts","../src/QuonfigProvider.tsx","../src/QuonfigTestProvider.tsx"],"names":["React"],"mappings":";;;;;;;AACA,IAAO,eAAA,GAAQ,OAAA;;;ACqBf,IAAM,OAAO,MAAY;AAAC,CAAA;AAE1B,IAAM,MAAA,GAAS,WAAA;AAEf,SAAS,gBAAA,GAAqC;AAC5C,EAAA,OAAO;AAAA;AAAA,IAEL,KAAA,EAAO,CAAC,OAAA,EAAA,GAAY,IAAA,KAAS,QAAQ,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,IACnE,IAAA,EAAM,CAAC,OAAA,EAAA,GAAY,IAAA,KAAS,QAAQ,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,IACjE,IAAA,EAAM,CAAC,OAAA,EAAA,GAAY,IAAA,KAAS,QAAQ,IAAA,CAAK,MAAA,EAAQ,OAAA,EAAS,GAAG,IAAI,CAAA;AAAA,IACjE,KAAA,EAAO,CAAC,OAAA,EAAA,GAAY,IAAA,KAAS,QAAQ,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,GAAG,IAAI;AAAA;AAAA,GAErE;AACF;AAEO,SAAS,gBAAgB,MAAA,EAA8C;AAC5E,EAAA,IAAI,CAAC,MAAA,EAAQ,OAAO,gBAAA,EAAiB;AACrC,EAAA,OAAO;AAAA,IACL,OAAO,MAAA,CAAO,KAAA,GAAQ,OAAO,KAAA,CAAM,IAAA,CAAK,MAAM,CAAA,GAAI,IAAA;AAAA,IAClD,MAAM,MAAA,CAAO,IAAA,GAAO,OAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA,GAAI,IAAA;AAAA,IAC/C,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,MAAM,CAAA;AAAA,IAC7B,KAAA,EAAO,MAAA,CAAO,KAAA,CAAM,IAAA,CAAK,MAAM;AAAA,GACjC;AACF;;;ACxBA,IAAM,oBAAA,GAAuB,KAAA,CAAM,aAAA,CAA8B,IAAI,CAAA;AAoE9D,IAAM,cAAA,GAA8B;AAAA,EACzC,GAAA,EAAK,CAAC,IAAA,KAAS,MAAA;AAAA,EACf,WAAA,EAAa,CAAC,IAAA,KAAS,MAAA;AAAA,EACvB,SAAA,EAAW,CAAC,IAAA,KAAS,KAAA;AAAA,EACrB,MAAM,EAAC;AAAA,EACP,OAAA,EAAS,IAAA;AAAA,EACT,mBAAmB,EAAC;AAAA,EACpB,OAAA;AAAA,EACA,UAAU;AACZ,CAAA;AAEO,IAAM,iBAAiB,KAAA,CAAM,aAAA;AAAA,EAClC;AACF,CAAA;AAGO,SAAS,kBAAqB,aAAA,EAAwC;AAC3E,EAAA,OAAO,SAAS,cAAA,GAAkC;AAChD,IAAA,MAAM,WAAA,GAAc,KAAA,CAAM,UAAA,CAAW,cAAc,CAAA;AAGnD,IAAA,MAAM,gBAAA,GAAmB,KAAA,CAAM,OAAA,CAAQ,MAAM;AAC3C,MAAA,MAAM,QAAA,GAAW,IAAI,aAAA,CAAc,WAAA,CAAY,OAAO,CAAA;AAGtD,MAAA,MAAA,CAAO,OAAO,QAAA,EAAiB;AAAA,QAC7B,aAAa,WAAA,CAAY,WAAA;AAAA,QACzB,mBAAmB,WAAA,CAAY,iBAAA;AAAA,QAC/B,WAAW,WAAA,CAAY,SAAA;AAAA,QACvB,SAAS,WAAA,CAAY,OAAA;AAAA,QACrB,MAAM,WAAA,CAAY,IAAA;AAAA,QAClB,UAAU,WAAA,CAAY;AAAA,OACvB,CAAA;AAED,MAAA,OAAO,QAAA;AAAA,IACT,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEhB,IAAA,OAAO,gBAAA;AAAA,EACT,CAAA;AACF;AAGO,IAAM,cAAA,GAAiB,MAAM,KAAA,CAAM,UAAA,CAAW,cAAc,CAAA;AAG5D,IAAM,UAAA,GAAa,MAAuB,cAAA;AAW1C,SAAS,QAAQ,GAAA,EAA0B;AAjJlD,EAAA,IAAA,EAAA;AAkJE,EAAA,MAAM,MAAA,GAAA,CAAS,EAAA,GAAA,KAAA,CAAM,UAAA,CAAW,oBAAoB,MAArC,IAAA,GAAA,EAAA,GAA0C,OAAA;AACzD,EAAA,MAAM,YAAY,KAAA,CAAM,WAAA;AAAA,IACtB,CAAC,QAAA,KAAyB,MAAA,CAAO,SAAA,CAAU,QAAQ,CAAA;AAAA,IACnD,CAAC,MAAM;AAAA,GACT;AACA,EAAA,MAAM,WAAA,GAAc,KAAA,CAAM,WAAA,CAAY,MAAM,MAAA,CAAO,GAAA,CAAI,GAAG,CAAA,EAAG,CAAC,MAAA,EAAQ,GAAG,CAAC,CAAA;AAC1E,EAAA,MAAM,oBAAoB,KAAA,CAAM,WAAA,CAAY,MAAmB,MAAA,EAAW,EAAE,CAAA;AAC5E,EAAA,OAAO,KAAA,CAAM,oBAAA,CAAqB,SAAA,EAAW,WAAA,EAAa,iBAAiB,CAAA;AAC7E;AAOO,IAAM,mBAAmB,MAAe;AAC7C,EAAA,MAAM,YAAA,GAAe,KAAA,CAAM,UAAA,CAAW,oBAAoB,CAAA;AAE1D,EAAA,MAAM,eAAA,GAAkB,KAAA,CAAM,MAAA,CAAO,YAAY,CAAA;AACjD,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,MAAO,eAAA,CAAgB,OAAA,GAAU,IAAI,OAAA,EAAQ,GAAI,OAAA,EAAU,EAAE,CAAA;AACpF,CAAA;AASA,IAAM,aAAA,GAAgB,CACpB,iBAAA,EACA,MAAA,EACA,OAAA,KACW;AACX,EAAA,IAAI;AACF,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,iBAAiB,CAAA,CAAE,WAAW,CAAA,EAAG;AAC/C,MAAA,MAAA,CAAO,IAAA;AAAA,QACL;AAAA,OACF;AAAA,IACF;AAEA,IAAA,OAAO,eAAe,iBAAiB,CAAA;AAAA,EACzC,SAAS,CAAA,EAAG;AACV,IAAA,OAAA,CAAQ,CAAU,CAAA;AAClB,IAAA,OAAO,EAAA;AAAA,EACT;AACF,CAAA;AAEA,SAAS,eAAA,CAAgB;AAAA,EACvB,MAAA;AAAA,EACA,oBAAoB,EAAC;AAAA,EACrB,OAAA,EAAS,WAAA;AAAA,EACT,MAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,OAAA;AAAA,EACA,MAAA;AAAA,EACA,YAAA;AAAA,EACA,uBAAA,GAA0B,MAAA;AAAA,EAC1B;AACF,CAAA,EAA4C;AAC1C,EAAA,MAAM,gBAAA,GAAmB,MAAM,OAAA,CAAQ,MAAM,gBAAgB,MAAM,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAC9E,EAAA,MAAM,UAAU,KAAA,CAAM,WAAA;AAAA,IACpB,CAAC,CAAA,KAAe;AACd,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,WAAA,CAAY,CAAU,CAAA;AAAA,MACxB,CAAA,MAAO;AACL,QAAA,MAAM,UAAU,CAAA,YAAa,KAAA,GAAQ,CAAA,CAAE,OAAA,GAAU,OAAO,CAAC,CAAA;AACzD,QAAA,gBAAA,CAAiB,KAAA,CAAM,SAAS,CAAC,CAAA;AAAA,MACnC;AAAA,IACF,CAAA;AAAA,IACA,CAAC,aAAa,gBAAgB;AAAA,GAChC;AACA,EAAA,MAAM,QAAA,GAAW;AAAA,IACf,MAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,MAAA;AAAA,IACA,OAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,uBAAA;AAAA,IACA;AAAA,GACF;AAIA,EAAA,MAAM,6BAAA,GAAgC,KAAA,CAAM,MAAA,CAA2B,MAAS,CAAA;AAGhF,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AACjD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,KAAA,CAAM,SAAS,IAAI,CAAA;AAGzD,EAAA,MAAM,CAAC,gBAAA,EAAkB,mBAAmB,CAAA,GAAI,KAAA,CAAM,SAAS,EAAE,CAAA;AAEjE,EAAA,MAAM,gBAAyB,gBAAA,EAAiB;AAKhD,EAAA,MAAM,cAAc,KAAA,CAAM,oBAAA;AAAA,IACxB,KAAA,CAAM,WAAA,CAAY,CAAC,QAAA,KAAa,aAAA,CAAc,UAAU,QAAQ,CAAA,EAAG,CAAC,aAAa,CAAC,CAAA;AAAA,IAClF,MAAM,WAAA,CAAY,MAAM,cAAc,WAAA,EAAa,CAAC,aAAa,CAAC,CAAA;AAAA,IAClE,KAAA,CAAM,WAAA,CAAY,MAAM,CAAA,EAAG,EAAE;AAAA,GAC/B;AAEA,EAAA,MAAM,UAAA,GAAa,aAAA,CAAc,iBAAA,EAAmB,gBAAA,EAAkB,OAAO,CAAA;AAE7E,EAAA,IAAI,gBAAgB,WAAA,EAAa;AAC/B,IAAA,aAAA,CAAc,QAAQ,YAAY,CAAA;AAClC,IAAA,cAAA,CAAe,KAAK,CAAA;AACpB,IAAA,mBAAA,CAAoB,UAAU,CAAA;AAC9B,IAAA,UAAA,CAAW,KAAK,CAAA;AAChB,IAAA,6BAAA,CAA8B,OAAA,GAAU,UAAA;AAExC,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,gBAAA,CAAiB,KAAK,gEAAgE,CAAA;AAAA,IACxF;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,UAAU,MAAM;AACpB,IAAA,cAAA,CAAe,KAAK,CAAA;AAEpB,IAAA,IAAI,6BAAA,CAA8B,YAAY,UAAA,EAAY;AACxD,MAAA;AAAA,IACF;AAEA,IAAA,UAAA,CAAW,IAAI,CAAA;AACf,IAAA,IAAI;AACF,MAAA,IAAI,6BAAA,CAA8B,YAAY,KAAA,CAAA,EAAW;AACvD,QAAA,6BAAA,CAA8B,OAAA,GAAU,UAAA;AAExC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,QACvD;AAEA,QAAA,aAAA,CAAc,UAAA,GAAa,OAAA;AAC3B,QAAA,aAAA,CAAc,aAAA,GAAgB,eAAA;AAE9B,QAAA,MAAM,eAAA,GAAkB,OAAA,IAAA,IAAA,GAAA,OAAA,GAAY,MAAA,GAAS,CAAC,MAAM,CAAA,GAAI,KAAA,CAAA;AAExD,QAAA,MAAM,WAAA,GAA2B;AAAA,UAC/B,OAAA,EAAS,iBAAA;AAAA,UACT,MAAA;AAAA,UACA,OAAA,EAAS,eAAA;AAAA,UACT,MAAA;AAAA,UACA,OAAA;AAAA,UACA,uBAAA;AAAA,UACA;AAAA,SACF;AAEA,QAAA,aAAA,CACG,IAAA,CAAK,WAAW,CAAA,CAChB,IAAA,CAAK,MAAM;AACV,UAAA,mBAAA,CAAoB,UAAU,CAAA;AAC9B,UAAA,UAAA,CAAW,KAAK,CAAA;AAEhB,UAAA,IAAI,YAAA,EAAc;AAChB,YAAA,aAAA,CAAc,IAAA,CAAK,EAAE,aAAA,EAAe,YAAA,EAAc,CAAA;AAAA,UACpD;AAAA,QACF,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,MAAA,KAAgB;AACtB,UAAA,UAAA,CAAW,KAAK,CAAA;AAChB,UAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,QAChB,CAAC,CAAA;AAAA,MACL,CAAA,MAAO;AACL,QAAA,6BAAA,CAA8B,OAAA,GAAU,UAAA;AAExC,QAAA,aAAA,CACG,aAAA,CAAc,iBAAiB,CAAA,CAC/B,IAAA,CAAK,MAAM;AACV,UAAA,mBAAA,CAAoB,UAAU,CAAA;AAC9B,UAAA,UAAA,CAAW,KAAK,CAAA;AAAA,QAClB,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,MAAA,KAAgB;AACtB,UAAA,UAAA,CAAW,KAAK,CAAA;AAChB,UAAA,OAAA,CAAQ,MAAM,CAAA;AAAA,QAChB,CAAC,CAAA;AAAA,MACL;AAAA,IACF,SAAS,CAAA,EAAG;AACV,MAAA,UAAA,CAAW,KAAK,CAAA;AAChB,MAAA,OAAA,CAAQ,CAAU,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG;AAAA,IACD,MAAA;AAAA,IACA,gBAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,UAAA;AAAA,IACA,OAAA;AAAA,IACA,aAAA,CAAc;AAAA,GACf,CAAA;AAOD,EAAA,KAAA,CAAM,SAAA;AAAA,IACJ,MAAM,MAAM;AACV,MAAA,aAAA,CAAc,KAAA,EAAM,CAAE,KAAA,CAAM,MAAM;AAAA,MAAC,CAAC,CAAA;AACpC,MAAA,6BAAA,CAA8B,OAAA,GAAU,MAAA;AAAA,IAC1C,CAAA;AAAA,IACA,CAAC,aAAa;AAAA,GAChB;AAEA,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,MAAM;AAChC,IAAA,MAAM,WAAA,GAA+B;AAAA,MACnC,SAAA,EAAW,aAAA,CAAc,SAAA,CAAU,IAAA,CAAK,aAAa,CAAA;AAAA,MACrD,iBAAA;AAAA,MACA,GAAA,EAAK,aAAA,CAAc,GAAA,CAAI,IAAA,CAAK,aAAa,CAAA;AAAA,MACzC,WAAA,EAAa,aAAA,CAAc,WAAA,CAAY,IAAA,CAAK,aAAa,CAAA;AAAA,MACzD,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,aAAA,CAAc,SAAS,CAAA;AAAA,MACzC,OAAA,EAAS,aAAA;AAAA,MACT,OAAA;AAAA,MACA;AAAA,KACF;AAEA,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,gBAAA,EAAkB,OAAA,EAAS,cAAc,YAAA,EAAc,QAAA,EAAU,WAAW,CAAC,CAAA;AAEjF,EAAA,uBACE,KAAA,CAAA,aAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,aAAA,EAAA,kBACpC,KAAA,CAAA,aAAA,CAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAA,EAAe,QAAS,CACnD,CAAA;AAEJ;AC1WA,SAAS,mBAAA,CAAoB;AAAA,EAC3B,MAAA;AAAA,EACA,MAAA;AAAA,EACA;AACF,CAAA,EAAgD;AAC9C,EAAA,MAAM,GAAA,GAAM,CAAC,GAAA,KAAgB,MAAA,CAAO,GAAG,CAAA;AACvC,EAAA,MAAM,WAAA,GAAc,CAAC,GAAA,KAAgB,MAAA,CAAO,GAAG,CAAA;AAC/C,EAAA,MAAM,YAAY,CAAC,GAAA,KAAgB,CAAC,CAAC,IAAI,GAAG,CAAA;AAE5C,EAAA,MAAM,gBAAgB,gBAAA,EAAiB;AAEvC,EAAA,MAAM,KAAA,GAAQA,KAAAA,CAAM,OAAA,CAAQ,MAAM;AAChC,IAAA,aAAA,CAAc,GAAA,GAAM,GAAA;AACpB,IAAA,aAAA,CAAc,WAAA,GAAc,WAAA;AAC5B,IAAA,aAAA,CAAc,SAAA,GAAY,SAAA;AAE1B,IAAA,MAAM,WAAA,GAA+B;AAAA,MACnC,SAAA;AAAA,MACA,mBAAmB,MAAA,CAAO,iBAAA;AAAA,MAC1B,GAAA;AAAA,MACA,WAAA;AAAA,MACA,OAAA,EAAS,KAAA;AAAA,MACT,OAAA,EAAS,aAAA;AAAA,MACT,IAAA,EAAM,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA;AAAA,MACxB,QAAA,EAAU,EAAE,MAAA,EAAQ,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,oCAAA;AAAqC,KACrE;AAEA,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAA,EAAQ,aAAA,EAAe,MAAM,CAAC,CAAA;AAElC,EAAA,uBACEA,KAAAA,CAAA,aAAA,CAAC,oBAAA,CAAqB,QAAA,EAArB,EAA8B,KAAA,EAAO,aAAA,EAAA,kBACpCA,KAAAA,CAAA,cAAC,cAAA,CAAe,QAAA,EAAf,EAAwB,KAAA,EAAA,EAAe,QAAS,CACnD,CAAA;AAEJ","file":"index.mjs","sourcesContent":["// AUTO-GENERATED from package.json by scripts/generate-version.mjs — do not edit.\nexport default \"0.0.9\";\n","/**\n * Pluggable logger interface for SDK-internal warnings and errors.\n *\n * Shape mirrors @quonfig/node so the contract is uniform across the\n * TypeScript SDKs: `warn` and `error` are required; `debug` and `info` are\n * optional and become no-ops when the supplied logger does not implement\n * them.\n */\nexport interface Logger {\n debug?(message: string, ...args: unknown[]): void;\n info?(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nexport interface NormalizedLogger {\n debug(message: string, ...args: unknown[]): void;\n info(message: string, ...args: unknown[]): void;\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst NOOP = (): void => {};\n\nconst PREFIX = \"[quonfig]\";\n\nfunction defaultSdkLogger(): NormalizedLogger {\n return {\n /* eslint-disable no-console */\n debug: (message, ...args) => console.debug(PREFIX, message, ...args),\n info: (message, ...args) => console.info(PREFIX, message, ...args),\n warn: (message, ...args) => console.warn(PREFIX, message, ...args),\n error: (message, ...args) => console.error(PREFIX, message, ...args),\n /* eslint-enable no-console */\n };\n}\n\nexport function normalizeLogger(logger: Logger | undefined): NormalizedLogger {\n if (!logger) return defaultSdkLogger();\n return {\n debug: logger.debug ? logger.debug.bind(logger) : NOOP,\n info: logger.info ? logger.info.bind(logger) : NOOP,\n warn: logger.warn.bind(logger),\n error: logger.error.bind(logger),\n };\n}\n","import React, { PropsWithChildren } from \"react\";\nimport {\n quonfig,\n type InitOptions,\n type ConfigValue,\n type Contexts,\n Quonfig,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Duration,\n encodeContexts,\n} from \"@quonfig/javascript\";\nimport reactSdkVersion from \"./version\";\nimport { normalizeLogger, type Logger, type NormalizedLogger } from \"./sdkLogger\";\n\n// qfg-lkpm.6: per-tree owner context. The value is the active Quonfig client\n// for this provider subtree. A null value means no Provider is above us, so\n// the next mount can claim the module-level singleton; a non-null value\n// signals \"you're nested, mint a fresh client\". This replaces the previous\n// module-level `globalQuonfigIsTaken` flag, which never reset and so leaked\n// state across test runs and (in principle) across SSR render trees.\nconst QuonfigClientContext = React.createContext<Quonfig | null>(null);\n\n// @quonfig/cli#generate will create interfaces into this namespace for React to consume\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport interface FrontEndConfigurationAccessor {}\n\nexport type TypedFrontEndConfigurationAccessor = keyof FrontEndConfigurationAccessor extends never\n ? Record<string, unknown>\n : {\n [TypedFlagKey in keyof FrontEndConfigurationAccessor]: FrontEndConfigurationAccessor[TypedFlagKey];\n };\n\ntype ClassMethods<T> = { [K in keyof T]: T[K] };\n\ntype QuonfigTypesafeClass<T = unknown> = new (\n // eslint-disable-next-line no-shadow\n quonfig: Quonfig\n) => T;\n\ntype SharedSettings = Partial<\n Pick<InitOptions, \"sdkKey\" | \"apiUrls\" | \"domain\" | \"timeout\" | \"collectEvaluationSummaries\">\n> & {\n // Convenience alias for a single API URL — normalized to apiUrls=[apiUrl]\n // before being passed to the underlying SDK, which only accepts apiUrls.\n apiUrl?: string;\n // We need to redefine the afterEvaluationCallback type to ensure proper dynamic resolution of K\n afterEvaluationCallback?: <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n contexts: Contexts | undefined\n ) => void;\n pollInterval?: number;\n onError?: (error: Error) => void;\n};\n\nexport type BaseContext = {\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n getDuration: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => Duration | undefined;\n contextAttributes: Contexts;\n isEnabled: <\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(\n key: K\n ) => boolean;\n loading: boolean;\n quonfig: typeof quonfig;\n keys: (keyof TypedFrontEndConfigurationRaw)[];\n settings: SharedSettings;\n};\n\nexport type ProvidedContext = BaseContext & ClassMethods<QuonfigTypesafeClass>;\n\nexport const defaultContext: BaseContext = {\n get: (_key) => undefined,\n getDuration: (_key) => undefined,\n isEnabled: (_key) => false,\n keys: [],\n loading: true,\n contextAttributes: {},\n quonfig,\n settings: {},\n};\n\nexport const QuonfigContext = React.createContext<ProvidedContext>(\n defaultContext as ProvidedContext\n);\n\n// This is a factory function that creates a fully typed useQuonfig hook for a specific QuonfigTypesafe class\nexport function createQuonfigHook<T>(TypesafeClass: QuonfigTypesafeClass<T>) {\n return function useQuonfigHook(): BaseContext & T {\n const baseContext = React.useContext(QuonfigContext);\n\n // Memoize the typesafe instance to prevent unnecessary constructor calls\n const typesafeInstance = React.useMemo(() => {\n const instance = new TypesafeClass(baseContext.quonfig);\n\n // Copy baseContext properties to typesafeInstance except for `get` + `quonfig`\n Object.assign(instance as any, {\n getDuration: baseContext.getDuration,\n contextAttributes: baseContext.contextAttributes,\n isEnabled: baseContext.isEnabled,\n loading: baseContext.loading,\n keys: baseContext.keys,\n settings: baseContext.settings,\n });\n\n return instance;\n }, [baseContext]);\n\n return typesafeInstance as BaseContext & T;\n };\n}\n\n// Basic hook for general use - requires type parameter\nexport const useBaseQuonfig = () => React.useContext(QuonfigContext);\n\n// General hook that returns the context with any explicit type\nexport const useQuonfig = (): ProvidedContext => useBaseQuonfig() as unknown as ProvidedContext;\n\n// qfg-lkpm.6: per-key selector hook. Subscribes via the underlying client's\n// notify list rather than React context, so a flag mutation only re-renders\n// components whose selected key actually changed. `useQuonfig()` re-renders\n// on every dataVersion bump because the context value identity changes; this\n// hook bypasses that.\nexport function useFlag<K extends keyof TypedFrontEndConfigurationRaw>(\n key: K\n): TypedFrontEndConfigurationRaw[K];\nexport function useFlag(key: string): ConfigValue;\nexport function useFlag(key: string): ConfigValue {\n const client = React.useContext(QuonfigClientContext) ?? quonfig;\n const subscribe = React.useCallback(\n (onChange: () => void) => client.subscribe(onChange),\n [client]\n );\n const getSnapshot = React.useCallback(() => client.get(key), [client, key]);\n const getServerSnapshot = React.useCallback((): ConfigValue => undefined, []);\n return React.useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);\n}\n\n// qfg-lkpm.6: replacement for the old module-level `globalQuonfigIsTaken`\n// flag. A provider asks \"is there already a Quonfig client above me in the\n// React tree?\". If yes, mint a fresh client (multi-tenant nesting); if no,\n// claim the module singleton so non-React code that imports `quonfig`\n// directly sees the same instance.\nexport const useQuonfigClient = (): Quonfig => {\n const parentClient = React.useContext(QuonfigClientContext);\n // Mount-only: parent context is fixed for the lifetime of this provider.\n const parentClientRef = React.useRef(parentClient);\n return React.useMemo(() => (parentClientRef.current ? new Quonfig() : quonfig), []);\n};\n\nexport type QuonfigProviderProps = SharedSettings & {\n sdkKey: string;\n contextAttributes?: Contexts;\n initialFlags?: Record<string, unknown>;\n logger?: Logger;\n};\n\nconst getContextKey = (\n contextAttributes: Contexts,\n logger: NormalizedLogger,\n onError: (e: Error) => void\n): string => {\n try {\n if (Object.keys(contextAttributes).length === 0) {\n logger.warn(\n \"QuonfigProvider: You haven't passed any contextAttributes. See https://docs.quonfig.com/docs/sdks/react#using-context\"\n );\n }\n\n return encodeContexts(contextAttributes);\n } catch (e) {\n onError(e as Error);\n return \"\";\n }\n};\n\nfunction QuonfigProvider({\n sdkKey,\n contextAttributes = {},\n onError: userOnError,\n logger,\n initialFlags,\n children,\n timeout,\n apiUrl,\n apiUrls,\n domain,\n pollInterval,\n afterEvaluationCallback = undefined,\n collectEvaluationSummaries,\n}: PropsWithChildren<QuonfigProviderProps>) {\n const normalizedLogger = React.useMemo(() => normalizeLogger(logger), [logger]);\n const onError = React.useCallback(\n (e: unknown) => {\n if (userOnError) {\n userOnError(e as Error);\n } else {\n const message = e instanceof Error ? e.message : String(e);\n normalizedLogger.error(message, e);\n }\n },\n [userOnError, normalizedLogger]\n );\n const settings = {\n sdkKey,\n apiUrl,\n apiUrls,\n domain,\n timeout,\n pollInterval,\n onError,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n };\n\n // We use this state to prevent a double-init when useEffect fires due to\n // StrictMode\n const mostRecentlyLoadingContextKey = React.useRef<string | undefined>(undefined);\n // We use this state to pass the loading state to the Provider (updating\n // currentLoadingContextKey won't trigger an update)\n const [loading, setLoading] = React.useState(true);\n const [initialLoad, setInitialLoad] = React.useState(true);\n // Here we track the current identity so we can reload our config when it\n // changes\n const [loadedContextKey, setLoadedContextKey] = React.useState(\"\");\n\n const quonfigClient: Quonfig = useQuonfigClient();\n\n // qfg-daxq: re-render when the underlying client's in-memory config changes\n // (poll fetch, setConfig, hydrate). Without this the singleton mutates in\n // place and React never sees the update.\n const dataVersion = React.useSyncExternalStore(\n React.useCallback((onChange) => quonfigClient.subscribe(onChange), [quonfigClient]),\n React.useCallback(() => quonfigClient.dataVersion, [quonfigClient]),\n React.useCallback(() => 0, [])\n );\n\n const contextKey = getContextKey(contextAttributes, normalizedLogger, onError);\n\n if (initialFlags && initialLoad) {\n quonfigClient.hydrate(initialFlags);\n setInitialLoad(false);\n setLoadedContextKey(contextKey);\n setLoading(false);\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (pollInterval) {\n normalizedLogger.warn(\"Polling is not supported when hydrating flags via initialFlags\");\n }\n }\n\n React.useEffect(() => {\n setInitialLoad(false);\n\n if (mostRecentlyLoadingContextKey.current === contextKey) {\n return;\n }\n\n setLoading(true);\n try {\n if (mostRecentlyLoadingContextKey.current === undefined) {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n if (!sdkKey) {\n throw new Error(\"QuonfigProvider: sdkKey is required\");\n }\n\n quonfigClient.clientName = \"react\";\n quonfigClient.clientVersion = reactSdkVersion;\n\n const resolvedApiUrls = apiUrls ?? (apiUrl ? [apiUrl] : undefined);\n\n const initOptions: InitOptions = {\n context: contextAttributes,\n sdkKey,\n apiUrls: resolvedApiUrls,\n domain,\n timeout,\n afterEvaluationCallback,\n collectEvaluationSummaries,\n };\n\n quonfigClient\n .init(initOptions)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n\n if (pollInterval) {\n quonfigClient.poll({ frequencyInMs: pollInterval });\n }\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n } else {\n mostRecentlyLoadingContextKey.current = contextKey;\n\n quonfigClient\n .updateContext(contextAttributes)\n .then(() => {\n setLoadedContextKey(contextKey);\n setLoading(false);\n })\n .catch((reason: any) => {\n setLoading(false);\n onError(reason);\n });\n }\n } catch (e) {\n setLoading(false);\n onError(e as Error);\n }\n }, [\n sdkKey,\n loadedContextKey,\n contextKey,\n loading,\n setLoading,\n onError,\n quonfigClient.instanceHash,\n ]);\n\n // qfg-2acr: drain telemetry + stop polling/telemetry timers when the\n // provider unmounts so route swaps don't leave the singleton polling\n // forever. Mount-only deps so context-attribute changes don't tear down\n // the SDK. In React StrictMode the synthetic unmount fires too — we\n // reset the init-guard ref so the next mount cleanly re-inits.\n React.useEffect(\n () => () => {\n quonfigClient.close().catch(() => {});\n mostRecentlyLoadingContextKey.current = undefined;\n },\n [quonfigClient]\n );\n\n const value = React.useMemo(() => {\n const baseContext: ProvidedContext = {\n isEnabled: quonfigClient.isEnabled.bind(quonfigClient),\n contextAttributes,\n get: quonfigClient.get.bind(quonfigClient),\n getDuration: quonfigClient.getDuration.bind(quonfigClient),\n keys: Object.keys(quonfigClient.extract()),\n quonfig: quonfigClient,\n loading,\n settings,\n };\n\n return baseContext;\n }, [loadedContextKey, loading, quonfigClient.instanceHash, settings, dataVersion]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigProvider, QuonfigClientContext, ConfigValue, SharedSettings, QuonfigTypesafeClass };\n","import React, { PropsWithChildren } from \"react\";\nimport {\n QuonfigContext,\n QuonfigClientContext,\n useQuonfigClient,\n ProvidedContext,\n} from \"./QuonfigProvider\";\n\nexport type QuonfigTestProviderProps = {\n config: Record<string, any>;\n sdkKey?: string;\n};\n\nfunction QuonfigTestProvider({\n sdkKey,\n config,\n children,\n}: PropsWithChildren<QuonfigTestProviderProps>) {\n const get = (key: string) => config[key];\n const getDuration = (key: string) => config[key];\n const isEnabled = (key: string) => !!get(key);\n\n const quonfigClient = useQuonfigClient();\n\n const value = React.useMemo(() => {\n quonfigClient.get = get;\n quonfigClient.getDuration = getDuration;\n quonfigClient.isEnabled = isEnabled;\n\n const baseContext: ProvidedContext = {\n isEnabled,\n contextAttributes: config.contextAttributes,\n get,\n getDuration,\n loading: false,\n quonfig: quonfigClient,\n keys: Object.keys(config),\n settings: { sdkKey: sdkKey ?? \"fake-sdk-key-via-the-test-provider\" },\n };\n\n return baseContext;\n }, [config, quonfigClient, sdkKey]);\n\n return (\n <QuonfigClientContext.Provider value={quonfigClient}>\n <QuonfigContext.Provider value={value}>{children}</QuonfigContext.Provider>\n </QuonfigClientContext.Provider>\n );\n}\n\nexport { QuonfigTestProvider };\n"]}
|
package/package.json
CHANGED