From 956594b3f666de3eb9567f7b4855d69a6057d2d0 Mon Sep 17 00:00:00 2001 From: Nicky <31034418+nickybondarenko@users.noreply.github.com> Date: Wed, 14 Aug 2024 15:51:24 +0200 Subject: [PATCH] docs: add documentation to the SDK to resolve MD warnings (#177) --- api/openfeature-server-provider.api.md | 26 ++- api/openfeature-web-provider.api.md | 19 +-- api/react.api.md | 49 ++---- api/sdk.api.md | 161 +++--------------- .../src/ConfidenceServerProvider.ts | 13 +- .../src/factory.ts | 17 +- .../src/ConfidenceWebProvider.ts | 13 ++ .../openfeature-web-provider/src/factory.ts | 15 ++ packages/react/src/index.tsx | 66 ++++++- packages/sdk/src/Closer.ts | 10 ++ packages/sdk/src/Confidence.ts | 74 +++++++- packages/sdk/src/Trackable.ts | 13 ++ packages/sdk/src/Value.ts | 28 +++ packages/sdk/src/context.ts | 19 +++ packages/sdk/src/events.ts | 12 ++ packages/sdk/src/flags.ts | 34 ++++ packages/sdk/src/trackers/pageViews.ts | 4 + packages/sdk/src/trackers/visitorId.ts | 3 + packages/sdk/src/trackers/webVitals.ts | 2 +- packages/sdk/src/utils.ts | 1 + 20 files changed, 360 insertions(+), 219 deletions(-) diff --git a/api/openfeature-server-provider.api.md b/api/openfeature-server-provider.api.md index e0ccd7e1..ad582ed3 100644 --- a/api/openfeature-server-provider.api.md +++ b/api/openfeature-server-provider.api.md @@ -13,33 +13,29 @@ import { ProviderMetadata } from '@openfeature/server-sdk'; import { ProviderStatus } from '@openfeature/server-sdk'; import { ResolutionDetails } from '@openfeature/server-sdk'; -// Warning: (ae-missing-release-tag) "ConfidenceServerProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public +export type ConfidenceProviderFactoryOptions = { + region?: 'eu' | 'us'; + fetchImplementation?: typeof fetch; + clientSecret: string; + timeout: number; +}; + +// @public export class ConfidenceServerProvider implements Provider { constructor(client: FlagResolver); - // (undocumented) readonly metadata: ProviderMetadata; - // (undocumented) resolveBooleanEvaluation(flagKey: string, defaultValue: boolean, context: EvaluationContext): Promise>; - // (undocumented) resolveNumberEvaluation(flagKey: string, defaultValue: number, context: EvaluationContext): Promise>; - // (undocumented) resolveObjectEvaluation(flagKey: string, defaultValue: T, context: EvaluationContext): Promise>; - // (undocumented) resolveStringEvaluation(flagKey: string, defaultValue: string, context: EvaluationContext): Promise>; - // (undocumented) status: ProviderStatus; } -// Warning: (ae-forgotten-export) The symbol "ConfidenceProviderFactoryOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createConfidenceServerProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "createConfidenceServerProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function createConfidenceServerProvider(options: ConfidenceProviderFactoryOptions): Provider; -// @public (undocumented) +// @public export function createConfidenceServerProvider(confidence: Confidence): Provider; // (No @packageDocumentation comment for this package) diff --git a/api/openfeature-web-provider.api.md b/api/openfeature-web-provider.api.md index 6fb44955..b40e89c6 100644 --- a/api/openfeature-web-provider.api.md +++ b/api/openfeature-web-provider.api.md @@ -13,39 +13,26 @@ import { Provider } from '@openfeature/web-sdk'; import { ProviderMetadata } from '@openfeature/web-sdk'; import { ResolutionDetails } from '@openfeature/web-sdk'; -// Warning: (ae-missing-release-tag) "ConfidenceWebProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class ConfidenceWebProvider implements Provider { constructor(confidence: FlagResolver); - // (undocumented) readonly events: OpenFeatureEventEmitter; - // (undocumented) initialize(context?: EvaluationContext): Promise; - // (undocumented) readonly metadata: ProviderMetadata; - // (undocumented) onClose(): Promise; - // (undocumented) onContextChange(oldContext: EvaluationContext, newContext: EvaluationContext): Promise; - // (undocumented) resolveBooleanEvaluation(flagKey: string, defaultValue: boolean): ResolutionDetails; - // (undocumented) resolveNumberEvaluation(flagKey: string, defaultValue: number): ResolutionDetails; - // (undocumented) resolveObjectEvaluation(flagKey: string, defaultValue: T): ResolutionDetails; - // (undocumented) resolveStringEvaluation(flagKey: string, defaultValue: string): ResolutionDetails; } // Warning: (ae-forgotten-export) The symbol "ConfidenceWebProviderOptions" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "createConfidenceWebProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "createConfidenceWebProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export function createConfidenceWebProvider(options: ConfidenceWebProviderOptions): Provider; -// @public (undocumented) +// @public export function createConfidenceWebProvider(confidence: Confidence): Provider; // (No @packageDocumentation comment for this package) diff --git a/api/react.api.md b/api/react.api.md index 7f31cd21..b6093279 100644 --- a/api/react.api.md +++ b/api/react.api.md @@ -17,10 +17,7 @@ import { StateObserver } from '@spotify-confidence/sdk'; import { Trackable } from '@spotify-confidence/sdk'; import { Value } from '@spotify-confidence/sdk'; -// Warning: (ae-missing-release-tag) "ConfidenceProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "ConfidenceProvider" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type ConfidenceProvider = FC> & { @@ -29,75 +26,49 @@ export type ConfidenceProvider = FC>; }; -// @public (undocumented) +// @public export const ConfidenceProvider: ConfidenceProvider; -// Warning: (ae-missing-release-tag) "ConfidenceReact" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class ConfidenceReact implements EventSender, Trackable, FlagResolver { constructor(delegate: Confidence); - // (undocumented) clearContext({ transition }?: { transition?: boolean | undefined; }): void; - // (undocumented) get config(): Configuration; - // @internal (undocumented) + // @internal get contextState(): string; - // @internal (undocumented) + // @internal readonly delegate: Confidence; - // (undocumented) evaluateFlag(path: string, defaultValue: T): FlagEvaluation>; - // (undocumented) getContext(): Context; - // (undocumented) getFlag(path: string, defaultValue: T): Promise>; - // (undocumented) setContext(context: Context, { transition }?: { transition?: boolean | undefined; }): void; - // (undocumented) subscribe(onStateChange?: StateObserver | undefined): () => void; - // (undocumented) track(name: string, message?: Value.Struct): void; - // (undocumented) track(manager: Trackable.Manager): Closer; - // (undocumented) useContext(): Context; - // (undocumented) useEvaluateFlag(path: string, defaultValue: T): FlagEvaluation>; - // (undocumented) useFlag(path: string, defaultValue: T): Value.Widen; - // (undocumented) useWithContext(context: Context): ConfidenceReact; - // (undocumented) withContext(context: Context): ConfidenceReact; } -// Warning: (ae-missing-release-tag) "useConfidence" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const useConfidence: () => ConfidenceReact; -// Warning: (ae-missing-release-tag) "useConfidenceContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useConfidenceContext(confidence?: ConfidenceReact): Context; -// Warning: (ae-missing-release-tag) "useEvaluateFlag" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useEvaluateFlag(path: string, defaultValue: T, confidence?: ConfidenceReact): FlagEvaluation>; -// Warning: (ae-missing-release-tag) "useFlag" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useFlag(path: string, defaultValue: T, confidence?: ConfidenceReact): Value.Widen; -// Warning: (ae-missing-release-tag) "useWithContext" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function useWithContext(context: Context, parent?: ConfidenceReact): ConfidenceReact; // (No @packageDocumentation comment for this package) diff --git a/api/sdk.api.md b/api/sdk.api.md index fc20b70b..c99b8fbb 100644 --- a/api/sdk.api.md +++ b/api/sdk.api.md @@ -4,108 +4,68 @@ ```ts -// Warning: (ae-missing-release-tag) "Closer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "Closer" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export namespace Closer { - // (undocumented) export function combine(...closers: Closer[]): Closer; } -// @public (undocumented) +// @public export type Closer = () => void; -// Warning: (ae-missing-release-tag) "Confidence" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export class Confidence implements EventSender, Trackable, FlagResolver { constructor(config: Configuration, parent?: Confidence); - // (undocumented) clearContext(): void; - // (undocumented) readonly config: Configuration; // Warning: (ae-forgotten-export) The symbol "Subscribe" needs to be exported by the entry point index.d.ts // - // @internal (undocumented) + // @internal readonly contextChanges: Subscribe; - // (undocumented) static create({ clientSecret, region, timeout, environment, fetchImplementation, logger, }: ConfidenceOptions): Confidence; - // (undocumented) get environment(): string; - // (undocumented) evaluateFlag(path: string, defaultValue: T): FlagEvaluation>; - // (undocumented) get flagState(): State; - // (undocumented) getContext(): Context; - // (undocumented) getFlag(path: string, defaultValue: T): Promise>; // Warning: (ae-forgotten-export) The symbol "AccessiblePromise" needs to be exported by the entry point index.d.ts - // - // (undocumented) protected resolveFlags(): AccessiblePromise; - // (undocumented) setContext(context: Context): boolean; - // (undocumented) subscribe(onStateChange?: StateObserver): () => void; - // (undocumented) track(name: string, data?: EventData): void; - // (undocumented) track(manager: Trackable.Manager): Closer; - // (undocumented) withContext(context: Context): Confidence; } -// Warning: (ae-missing-release-tag) "ConfidenceOptions" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface ConfidenceOptions { - // (undocumented) clientSecret: string; - // (undocumented) environment: 'client' | 'backend'; // Warning: (ae-forgotten-export) The symbol "SimpleFetch" needs to be exported by the entry point index.d.ts - // - // (undocumented) fetchImplementation?: SimpleFetch; // Warning: (ae-forgotten-export) The symbol "Logger" needs to be exported by the entry point index.d.ts - // - // (undocumented) logger?: Logger; - // (undocumented) region?: 'eu' | 'us'; - // (undocumented) resolveUrl?: string; - // (undocumented) timeout: number; } -// Warning: (ae-missing-release-tag) "Configuration" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface Configuration { - // (undocumented) readonly environment: 'client' | 'backend'; // Warning: (ae-forgotten-export) The symbol "EventSenderEngine" needs to be exported by the entry point index.d.ts // - // @internal (undocumented) + // @internal readonly eventSenderEngine: EventSenderEngine; // Warning: (ae-forgotten-export) The symbol "FlagResolverClient" needs to be exported by the entry point index.d.ts // - // @internal (undocumented) + // @internal readonly flagResolverClient: FlagResolverClient; - // (undocumented) readonly logger: Logger; - // (undocumented) readonly timeout: number; } -// Warning: (ae-missing-release-tag) "Context" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface Context extends Value.Struct { - // (undocumented) page?: { path: string; referrer: string; @@ -113,194 +73,119 @@ export interface Context extends Value.Struct { title: string; url: string; }; - // (undocumented) targeting_key?: string; - // (undocumented) visitor_id?: string; } -// Warning: (ae-missing-release-tag) "Contextual" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface Contextual> { - // (undocumented) clearContext(): void; - // (undocumented) getContext(): Context; - // (undocumented) setContext(context: Context): void; - // (undocumented) withContext(context: Context): Self; } -// Warning: (ae-missing-release-tag) "EventData" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type EventData = Value.Struct & { context?: never; }; -// Warning: (ae-missing-release-tag) "EventSender" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface EventSender extends Contextual { - // (undocumented) track(name: string, data?: EventData): void; } -// Warning: (ae-missing-release-tag) "FlagEvaluation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "FlagEvaluation" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export namespace FlagEvaluation { - // (undocumented) export type ErrorCode = 'FLAG_NOT_FOUND' | 'TYPE_MISMATCH' | 'NOT_READY' | 'TIMEOUT' | 'GENERAL'; - // (undocumented) export interface Failed { - // (undocumented) readonly errorCode: ErrorCode; - // (undocumented) readonly errorMessage: string; - // (undocumented) readonly reason: 'ERROR'; - // (undocumented) readonly value: T; } - // (undocumented) export interface Matched { - // (undocumented) readonly reason: 'MATCH'; - // (undocumented) readonly value: T; - // (undocumented) readonly variant: string; } - // (undocumented) export type Resolved = Matched | Unmatched | Failed; - // (undocumented) export type Stale = Resolved & PromiseLike>; - // (undocumented) export interface Unmatched { - // (undocumented) readonly reason: 'UNSPECIFIED' | 'NO_SEGMENT_MATCH' | 'NO_TREATMENT_MATCH' | 'FLAG_ARCHIVED' | 'TARGETING_KEY_ERROR'; - // (undocumented) readonly value: T; } } -// @public (undocumented) +// @public export type FlagEvaluation = FlagEvaluation.Resolved | FlagEvaluation.Stale; -// Warning: (ae-missing-release-tag) "FlagResolver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export interface FlagResolver extends Contextual { - // (undocumented) evaluateFlag(path: string, defaultValue: T): FlagEvaluation>; - // (undocumented) getFlag(path: string, defaultValue: T): Promise>; - // (undocumented) subscribe(onStateChange?: StateObserver): () => void; } -// Warning: (ae-missing-release-tag) "pageViews" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export function pageViews(): Trackable.Manager; -// Warning: (ae-missing-release-tag) "State" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type State = 'NOT_READY' | 'READY' | 'STALE' | 'ERROR'; -// Warning: (ae-missing-release-tag) "StateObserver" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export type StateObserver = (state: State) => void; -// Warning: (ae-missing-release-tag) "Trackable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// Warning: (ae-missing-release-tag) "Trackable" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export namespace Trackable { - // (undocumented) export type Cleanup = void | Closer; - // (undocumented) export type Controller = Pick; - // (undocumented) export type Manager = (controller: Controller) => Cleanup; - // (undocumented) export function setup(controller: Controller, manager: Manager): Closer; } -// @public (undocumented) +// @public export interface Trackable { - // (undocumented) track(manager: Trackable.Manager): Closer; } -// Warning: (ae-missing-release-tag) "Value" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // Warning: (ae-missing-release-tag) "Value" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) // -// @public (undocumented) +// @public export namespace Value { - // (undocumented) export function assertType(expected: 'undefined', found: Value): asserts found is undefined; - // (undocumented) export function assertType(expected: 'string', found: Value): asserts found is string; - // (undocumented) export function assertType(expected: 'number', found: Value): asserts found is number; - // (undocumented) export function assertType(expected: 'boolean', found: Value): asserts found is boolean; - // (undocumented) export function assertType(expected: 'List', found: Value): asserts found is List; - // (undocumented) export function assertType(expected: 'Struct', found: Value): asserts found is Struct; - // (undocumented) export function assertValue(value: unknown): asserts value is Value; - // (undocumented) export function clone(value: T): T; - // (undocumented) export function deserialize(data: string): Value; - // (undocumented) export function equal(value1: Value, value2: Value): boolean; - // (undocumented) export function get(struct: Struct | undefined, path: string): Value; - // (undocumented) export function get(struct: Struct | undefined, ...steps: string[]): Value; - // (undocumented) export function getType(value: Value): TypeName; - // (undocumented) export function isList(value: Value): value is List; - // (undocumented) export function isStruct(value: Value): value is Struct; - // (undocumented) export type List = ReadonlyArray | ReadonlyArray | ReadonlyArray; - // (undocumented) export type Primitive = number | string | boolean; - // (undocumented) export function serialize(value: Value): string; - // (undocumented) export type Struct = { readonly [key: string]: Value; }; - // (undocumented) export type TypeName = 'number' | 'string' | 'boolean' | 'Struct' | 'List' | 'undefined'; - // (undocumented) export type Widen = T extends number ? number : T extends string ? string : T extends boolean ? boolean : T; } -// @public (undocumented) +// @public export type Value = Value.Primitive | Value.Struct | Value.List | undefined; -// Warning: (ae-missing-release-tag) "visitorIdentity" is part of the package's API, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) +// @public export const visitorIdentity: () => Trackable.Manager; -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The package "@spotify-confidence/sdk" does not have an export "Topic" -// Warning: (ae-unresolved-link) The @link reference could not be resolved: The reference is ambiguous because "track" has more than one declaration; you need to add a TSDoc member reference selector -// // @public export function webVitals({ lcp, inp, cls, ttfb, }?: WebVitalsOptions): Trackable.Manager; diff --git a/packages/openfeature-server-provider/src/ConfidenceServerProvider.ts b/packages/openfeature-server-provider/src/ConfidenceServerProvider.ts index cb2ddcf8..91e018ae 100644 --- a/packages/openfeature-server-provider/src/ConfidenceServerProvider.ts +++ b/packages/openfeature-server-provider/src/ConfidenceServerProvider.ts @@ -13,10 +13,16 @@ import { Context, FlagEvaluation, FlagResolver, Value } from '@spotify-confidenc type Mutable = { -readonly [K in keyof T]: T[K] }; +/** + * OpenFeature Provider for Confidence Server SDK + * @public + */ export class ConfidenceServerProvider implements Provider { + /** Static data about the provider */ readonly metadata: ProviderMetadata = { name: 'ConfidenceServerProvider', }; + /** Current status of the provider. Can be READY, NOT_READY, ERROR, STALE and FATAL. */ status: ProviderStatus = ProviderStatus.READY; private readonly confidence: FlagResolver; @@ -54,6 +60,7 @@ export class ConfidenceServerProvider implements Provider { return ErrorCode.GENERAL; } } + /** Resolves with an evaluation of a Boolean flag */ resolveBooleanEvaluation( flagKey: string, defaultValue: boolean, @@ -61,7 +68,7 @@ export class ConfidenceServerProvider implements Provider { ): Promise> { return this.fetchFlag(flagKey, defaultValue, context); } - + /** Resolves with an evaluation of a Numbers flag */ resolveNumberEvaluation( flagKey: string, defaultValue: number, @@ -69,7 +76,7 @@ export class ConfidenceServerProvider implements Provider { ): Promise> { return this.fetchFlag(flagKey, defaultValue, context); } - + /** Resolves with an evaluation of an Object flag */ resolveObjectEvaluation( flagKey: string, defaultValue: T, @@ -78,7 +85,7 @@ export class ConfidenceServerProvider implements Provider { Value.assertValue(defaultValue); return this.fetchFlag(flagKey, defaultValue, context); } - + /** Resolves with an evaluation of a String flag */ resolveStringEvaluation( flagKey: string, defaultValue: string, diff --git a/packages/openfeature-server-provider/src/factory.ts b/packages/openfeature-server-provider/src/factory.ts index 832084a5..c010bc72 100644 --- a/packages/openfeature-server-provider/src/factory.ts +++ b/packages/openfeature-server-provider/src/factory.ts @@ -2,15 +2,30 @@ import { Provider } from '@openfeature/server-sdk'; import { ConfidenceServerProvider } from './ConfidenceServerProvider'; import { Confidence } from '@spotify-confidence/sdk'; -type ConfidenceProviderFactoryOptions = { +/** + * Factory Options for Confidence Server Provider + * @public */ +export type ConfidenceProviderFactoryOptions = { region?: 'eu' | 'us'; fetchImplementation?: typeof fetch; clientSecret: string; timeout: number; }; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param options - Options for Confidence Provider + * @public */ export function createConfidenceServerProvider(options: ConfidenceProviderFactoryOptions): Provider; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param confidence - Confidence instance + * @public */ export function createConfidenceServerProvider(confidence: Confidence): Provider; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param confidenceOrOptions - Confidence instance or options for Confidence Provider + * @public */ export function createConfidenceServerProvider( confidenceOrOptions: Confidence | ConfidenceProviderFactoryOptions, ): Provider { diff --git a/packages/openfeature-web-provider/src/ConfidenceWebProvider.ts b/packages/openfeature-web-provider/src/ConfidenceWebProvider.ts index 4cc97d38..e0e08657 100644 --- a/packages/openfeature-web-provider/src/ConfidenceWebProvider.ts +++ b/packages/openfeature-web-provider/src/ConfidenceWebProvider.ts @@ -15,10 +15,16 @@ import { Value, Context, FlagResolver, FlagEvaluation } from '@spotify-confidenc type Mutable = { -readonly [K in keyof T]: T[K] }; +/** + * OpenFeature Provider for Confidence Web SDK + * @public + */ export class ConfidenceWebProvider implements Provider { + /** Static data about the provider */ readonly metadata: ProviderMetadata = { name: 'ConfidenceWebProvider', }; + /** Events can be used by developers to track lifecycle events */ readonly events = new OpenFeatureEventEmitter(); private unsubscribe?: () => void; @@ -28,6 +34,7 @@ export class ConfidenceWebProvider implements Provider { this.confidence = confidence; } + /** Initialize the Provider */ async initialize(context?: EvaluationContext): Promise { if (context) this.confidence.setContext(convertContext(context)); let isStale = false; @@ -46,11 +53,13 @@ export class ConfidenceWebProvider implements Provider { return this.expectReadyOrError(); } + /** Function called on closing of a Provider, handles unsubscribing from the Confidence SDK */ async onClose(): Promise { this.unsubscribe?.(); this.unsubscribe = undefined; } + /** Called on Confidence Context change */ async onContextChange(oldContext: EvaluationContext, newContext: EvaluationContext): Promise { const changes = contextChanges(oldContext, newContext); if (Object.keys(changes).length === 0) { @@ -98,20 +107,24 @@ export class ConfidenceWebProvider implements Provider { } } + /** Resolves with an evaluation of a Boolean flag */ resolveBooleanEvaluation(flagKey: string, defaultValue: boolean): ResolutionDetails { return this.evaluateFlag(flagKey, defaultValue); } + /** Resolves with an evaluation of a Number flag */ resolveNumberEvaluation(flagKey: string, defaultValue: number): ResolutionDetails { return this.evaluateFlag(flagKey, defaultValue); } + /** Resolves with an evaluation of an Object flag */ resolveObjectEvaluation(flagKey: string, defaultValue: T): ResolutionDetails { // this might throw but will be caught by OpenFeature Value.assertValue(defaultValue); return this.evaluateFlag(flagKey, defaultValue); } + /** Resolves with an evaluation of a String flag */ resolveStringEvaluation(flagKey: string, defaultValue: string): ResolutionDetails { return this.evaluateFlag(flagKey, defaultValue); } diff --git a/packages/openfeature-web-provider/src/factory.ts b/packages/openfeature-web-provider/src/factory.ts index ec6a9e1e..9a07acef 100644 --- a/packages/openfeature-web-provider/src/factory.ts +++ b/packages/openfeature-web-provider/src/factory.ts @@ -2,6 +2,9 @@ import { Provider } from '@openfeature/web-sdk'; import { ConfidenceWebProvider } from './ConfidenceWebProvider'; import { Confidence } from '@spotify-confidence/sdk'; +/** + * Factory Options for Confidence Web Provider + * @public */ export type ConfidenceWebProviderOptions = { region?: 'eu' | 'us'; fetchImplementation?: typeof fetch; @@ -9,8 +12,20 @@ export type ConfidenceWebProviderOptions = { timeout: number; }; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param options - Options for Confidence Provider + * @public */ export function createConfidenceWebProvider(options: ConfidenceWebProviderOptions): Provider; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param confidence - Confidence instance + * @public */ export function createConfidenceWebProvider(confidence: Confidence): Provider; +/** + * Creates an OpenFeature-adhering Confidence Provider + * @param confidenceOrOptions - Confidence instance or options for Confidence Provider + * @public */ export function createConfidenceWebProvider(confidenceOrOptions: Confidence | ConfidenceWebProviderOptions): Provider { if (confidenceOrOptions instanceof Confidence) { return new ConfidenceWebProvider(confidenceOrOptions); diff --git a/packages/react/src/index.tsx b/packages/react/src/index.tsx index 63d82d60..80d4bf4c 100644 --- a/packages/react/src/index.tsx +++ b/packages/react/src/index.tsx @@ -34,25 +34,43 @@ function isRendering(): boolean { } } +/** + * Confidence React instance + * @public + */ export class ConfidenceReact implements EventSender, Trackable, FlagResolver { - /** @internal */ + /** + * Confidence Delegate + * @internal */ readonly delegate: Confidence; constructor(delegate: Confidence) { this.delegate = delegate; } - + /** Return configurations of the Confidence instance */ get config(): Configuration { return this.delegate.config; } - /** @internal */ + /** + * Current serialized Context + * @internal */ get contextState(): string { return Value.serialize(this.delegate.getContext()); } + /** + * Tracks an event + * @param name - event name + * @param message - data to track */ track(name: string, message?: Value.Struct): void; + /** + * Tracks an event + * @param manager - trackable manager */ track(manager: Trackable.Manager): Closer; + /** + * Tracks an event + * @param nameOrManager - event name or Trackable Manager */ track(nameOrManager: string | Trackable.Manager, message?: Value.Struct): Closer | undefined { if (typeof nameOrManager === 'function') { return this.delegate.track(nameOrManager); @@ -60,10 +78,12 @@ export class ConfidenceReact implements EventSender, Trackable, FlagResolver { this.delegate.track(nameOrManager, message); return undefined; } + /** Returns context of the current Confidence instance */ getContext(): Context { this.assertContext('getContext', 'useContext'); return this.delegate.getContext(); } + /** Set Confidence context */ setContext(context: Context, { transition = true } = {}): void { if (transition) { startTransition(() => { @@ -74,9 +94,11 @@ export class ConfidenceReact implements EventSender, Trackable, FlagResolver { } } + /** Subscribe to flag changes in Confidence */ subscribe(onStateChange?: StateObserver | undefined): () => void { return this.delegate.subscribe(onStateChange); } + /** Clears context of current Confidence instance */ clearContext({ transition = true } = {}): void { if (transition) { startTransition(() => { @@ -87,14 +109,21 @@ export class ConfidenceReact implements EventSender, Trackable, FlagResolver { } } + /** + * Creates a new ConfidenceReact instance with context + * @param context - Confidence context + * @returns ConfidenceReact instance + */ withContext(context: Context): ConfidenceReact { this.assertContext('withContext', 'useWithContext'); return new ConfidenceReact(this.delegate.withContext(context)); } + /** Evaluates a flag */ evaluateFlag(path: string, defaultValue: T): FlagEvaluation> { this.assertContext('evaluateFlag', 'useEvaluateFlag'); return this.delegate.evaluateFlag(path, defaultValue); } + /** Returns flag value for a given flag */ getFlag(path: string, defaultValue: T): Promise> { this.assertContext('getFlag', 'useFlag'); return this.delegate.getFlag(path, defaultValue); @@ -102,18 +131,22 @@ export class ConfidenceReact implements EventSender, Trackable, FlagResolver { /* eslint-disable react-hooks/rules-of-hooks */ + /** Hook to access Context */ useContext(): Context { this.assertContext('useContext', 'getContext'); return useConfidenceContext(this); } + /** Hook to access the WithContext functionality. Returns a ConfidenceReact instance with the passed context. */ useWithContext(context: Context): ConfidenceReact { this.assertContext('useWithContext', 'withContext'); return useWithContext(context, this); } + /** Hook to use EvaluateFlag functionality */ useEvaluateFlag(path: string, defaultValue: T): FlagEvaluation> { this.assertContext('useEvaluateFlag', 'evaluateFlag'); return useEvaluateFlag(path, defaultValue, this); } + /** Hook to use getFlag functionality */ useFlag(path: string, defaultValue: T): Value.Widen { this.assertContext('useFlag', 'getFlag'); return useFlag(path, defaultValue, this); @@ -143,12 +176,24 @@ const WithContext: FC> = ({ context, chi return {children}; }; +/** + * Confidence Provider for React + * @public + */ export type ConfidenceProvider = FC> & { WithContext: FC>; }; +/** + * Confidence Provider for React + * @public + */ // eslint-disable-next-line @typescript-eslint/no-redeclare export const ConfidenceProvider: ConfidenceProvider = Object.assign(_ConfidenceProvider, { WithContext }); +/** + * Enables using Confidence + * @public + */ export const useConfidence = (): ConfidenceReact => { const confidenceReact = useContext(ConfidenceContext); if (!confidenceReact) @@ -156,6 +201,10 @@ export const useConfidence = (): ConfidenceReact => { return confidenceReact; }; +/** + * Use with given Confidence Context + * @public + */ // eslint-disable-next-line react-hooks/rules-of-hooks export function useWithContext(context: Context, parent = useConfidence()): ConfidenceReact { const child = useMemo( @@ -167,6 +216,10 @@ export function useWithContext(context: Context, parent = useConfidence()): Conf return child; } +/** + * Use Confidence Context + * @public + */ // this would be better named useContext, but would then collide with React.useContext // eslint-disable-next-line react-hooks/rules-of-hooks export function useConfidenceContext(confidence = useConfidence()): Context { @@ -177,6 +230,9 @@ export function useConfidenceContext(confidence = useConfidence()): Context { return confidence.delegate.getContext(); } +/** + * Use EvaluateFlag + * @public */ export function useEvaluateFlag( path: string, defaultValue: T, @@ -194,6 +250,10 @@ export function useEvaluateFlag( return evaluation; } +/** + * Use Flag + * @public + */ // eslint-disable-next-line react-hooks/rules-of-hooks export function useFlag(path: string, defaultValue: T, confidence = useConfidence()): Value.Widen { return useEvaluateFlag(path, defaultValue, confidence).value; diff --git a/packages/sdk/src/Closer.ts b/packages/sdk/src/Closer.ts index 5edca4c7..bf577c89 100644 --- a/packages/sdk/src/Closer.ts +++ b/packages/sdk/src/Closer.ts @@ -1,4 +1,9 @@ +/** + * Utility functions to manage Closer types + * @public + */ export namespace Closer { + /** Combine multiple closers */ export function combine(...closers: Closer[]): Closer { return () => { for (const closer of closers) { @@ -7,5 +12,10 @@ export namespace Closer { }; } } + +/** + * Utility functions to manage Closer types + * @public + */ // eslint-disable-next-line @typescript-eslint/no-redeclare export type Closer = () => void; diff --git a/packages/sdk/src/Confidence.ts b/packages/sdk/src/Confidence.ts index 5d8dc4e2..5f158149 100644 --- a/packages/sdk/src/Confidence.ts +++ b/packages/sdk/src/Confidence.ts @@ -19,33 +19,60 @@ import { SimpleFetch } from './types'; import { FlagResolution } from './FlagResolution'; import { AccessiblePromise } from './AccessiblePromise'; +/** + * Confidence options, to be used for easier initialization of Confidence + * @public + * */ export interface ConfidenceOptions { + /** Client secret, to be found in Confidence console*/ clientSecret: string; + /** Region in which Confidence will operate */ region?: 'eu' | 'us'; + /** Resolve URL */ resolveUrl?: string; + /** Environment: can be either client of backend */ environment: 'client' | 'backend'; + /** Fetch implementation */ fetchImplementation?: SimpleFetch; + /** Resolve timeout */ timeout: number; + /** Debug logger */ logger?: Logger; } +/** + * Confidence configuration + * @public + */ export interface Configuration { + /** Environment: can be either client of backend */ readonly environment: 'client' | 'backend'; + /** Debug logger */ readonly logger: Logger; + /** Resolve timeout */ readonly timeout: number; - /** @internal */ + /** Event Sender Engine + * @internal */ readonly eventSenderEngine: EventSenderEngine; - /** @internal */ + /** Flag Resolver Client + * @internal */ readonly flagResolverClient: FlagResolverClient; } +/** + * Class containing main Confidence APIs + * @public + */ export class Confidence implements EventSender, Trackable, FlagResolver { + /** Internal Confidence configurations */ readonly config: Configuration; private readonly parent?: Confidence; private _context: Map = new Map(); private contextChanged?: Observer; - /** @internal */ + /** + * Emits Closers on context change + * @internal */ readonly contextChanges: Subscribe; private currentFlags?: FlagResolution; @@ -89,6 +116,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { }); } + /** Returns currently used environment */ get environment(): string { return this.config.environment; } @@ -114,6 +142,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { } } + /** Returns context of the current Confidence instance */ getContext(): Context { const context: Record = {}; for (const [key, value] of this.contextEntries()) { @@ -122,6 +151,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return Object.freeze(context); } + /** Set Confidence context */ setContext(context: Context): boolean { const current = this.getContext(); const changedKeys: string[] = []; @@ -136,6 +166,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return changedKeys.length > 0; } + /** Clears context of current Confidence instance */ clearContext(): void { const oldContext = this.getContext(); this._context.clear(); @@ -147,6 +178,11 @@ export class Confidence implements EventSender, Trackable, FlagResolver { } } + /** + * Creates a new Confidence instance with context + * @param context - Confidence context + * @returns Confidence instance + */ withContext(context: Context): Confidence { const child = new Confidence(this.config, this); child.setContext(context); @@ -154,8 +190,22 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return child; } + /** + * Tracks an event + * @param name - event name + * @param data - data to track */ track(name: string, data?: EventData): void; + /** + * Sets up a Trackable.Manager to manage event tracking or context changes. + * @param manager - event manager + */ track(manager: Trackable.Manager): Closer; + /** + * Tracks an event + * @param nameOrManager - event name of event manager + * @param data - data to track + * @returns - Closer + */ track(nameOrManager: string | Trackable.Manager, data?: EventData): Closer | undefined { if (typeof nameOrManager === 'function') { return Trackable.setup(this, nameOrManager); @@ -164,6 +214,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return undefined; } + /** Resolves all flags in cache */ protected resolveFlags(): AccessiblePromise { const context = this.getContext(); if (!this.pendingFlags || !Value.equal(this.pendingFlags.context, context)) { @@ -191,6 +242,10 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return this.pendingFlags; } + /** + * Shows flag state + * @returns flag state - READY, NOT_READY, STALE or ERROR + */ get flagState(): State { if (this.currentFlags) { if (this.pendingFlags) return 'STALE'; @@ -199,6 +254,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return 'NOT_READY'; } + /** Subscribe to flag changes in Confidence */ subscribe(onStateChange: StateObserver = () => {}): () => void { const observer = changeObserver(onStateChange); const close = this.flagStateSubject(observer); @@ -218,6 +274,7 @@ export class Confidence implements EventSender, Trackable, FlagResolver { }).finally(close!); } + /** Evaluates a flag */ evaluateFlag(path: string, defaultValue: T): FlagEvaluation> { let evaluation: FlagEvaluation; // resolveFlags might update state synchronously @@ -244,10 +301,21 @@ export class Confidence implements EventSender, Trackable, FlagResolver { return evaluation as FlagEvaluation>; } + /** Returns flag value for a given flag */ async getFlag(path: string, defaultValue: T): Promise> { return (await this.evaluateFlag(path, defaultValue)).value; } + /** + * Creates a Confidence instance + * @param clientSecret - clientSecret found on the Confidence console + * @param region - region in which Confidence will operate + * @param timeout - timeout for flag resolves + * @param environment - can be either "client" or "backend" + * @param fetchImplementation - fetch implementation + * @param logger - debug logger + * @returns + */ static create({ clientSecret, region, diff --git a/packages/sdk/src/Trackable.ts b/packages/sdk/src/Trackable.ts index a770084a..8508fb54 100644 --- a/packages/sdk/src/Trackable.ts +++ b/packages/sdk/src/Trackable.ts @@ -3,9 +3,16 @@ import { Confidence } from './Confidence'; import { Context } from './context'; import { EventData } from './events'; +/** + * Namespace describing something to track + * @public + */ export namespace Trackable { + /** Trackable Controller */ export type Controller = Pick; + /** Trackable Cleanup */ export type Cleanup = void | Closer; + /** Trackable Manager */ export type Manager = (controller: Controller) => Cleanup; class RevocableController implements Controller { @@ -56,6 +63,7 @@ export namespace Trackable { } } + /** Setup of Trackable */ export function setup(controller: Controller, manager: Manager): Closer { const revocableController = new RevocableController(controller); const cleanup = manager(revocableController); @@ -69,6 +77,11 @@ export namespace Trackable { }; } } +/** + * Namespace describing something to track + * @public + */ export interface Trackable { + /** Tracks an event given a Trackable Manager */ track(manager: Trackable.Manager): Closer; } diff --git a/packages/sdk/src/Value.ts b/packages/sdk/src/Value.ts index 80328e49..6025568b 100644 --- a/packages/sdk/src/Value.ts +++ b/packages/sdk/src/Value.ts @@ -1,17 +1,26 @@ import { TypeMismatchError } from './error'; +/** + * Namespace that describes Values used in Confidence + * @public + */ export namespace Value { // TODO should lists be able to contain Structs? const LIST_ITEM_TYPES = new Set(['number', 'string', 'boolean']); + /** TypeName enum */ export type TypeName = 'number' | 'string' | 'boolean' | 'Struct' | 'List' | 'undefined'; // TODO add Date + /** Primitive types */ export type Primitive = number | string | boolean; + /** Struct in Confidence */ export type Struct = { readonly [key: string]: Value; }; + /** Readonly List */ export type List = ReadonlyArray | ReadonlyArray | ReadonlyArray; + /** Sets Confidence used Values to be implementations of primitive types */ export type Widen = T extends number ? number : T extends string @@ -20,6 +29,7 @@ export namespace Value { ? boolean : T; + /** Asserts a Value */ export function assertValue(value: unknown): asserts value is Value { switch (typeof value) { case 'bigint': @@ -52,6 +62,7 @@ export namespace Value { } } + /** Clones a Value */ export function clone(value: T): T { if (isStruct(value)) { const cloned: Record = {}; @@ -66,6 +77,7 @@ export namespace Value { return value; } + /** Asserts if two Values are equal */ export function equal(value1: Value, value2: Value): boolean { if (value1 === value2) return true; const type = getType(value1); @@ -97,6 +109,7 @@ export namespace Value { return true; } + /** Returns typename of given Value */ export function getType(value: Value): TypeName { const jsType = typeof value; switch (jsType) { @@ -112,20 +125,29 @@ export namespace Value { throw new TypeError(`Invalid Value type "${jsType}"`); } + /** Asserts that Value is a Struct */ export function isStruct(value: Value): value is Struct { return Value.getType(value) === 'Struct'; } + /** Asserts that Value is a List */ export function isList(value: Value): value is List { return Value.getType(value) === 'List'; } + /** Asserts that type of value is undefined */ export function assertType(expected: 'undefined', found: Value): asserts found is undefined; + /** Asserts that type of value is string */ export function assertType(expected: 'string', found: Value): asserts found is string; + /** Asserts that type of value is number */ export function assertType(expected: 'number', found: Value): asserts found is number; + /** Asserts that type of value is boolean */ export function assertType(expected: 'boolean', found: Value): asserts found is boolean; + /** Asserts that type of value is List */ export function assertType(expected: 'List', found: Value): asserts found is List; + /** Asserts that type of value is Struct */ export function assertType(expected: 'Struct', found: Value): asserts found is Struct; + /** Asserts that type of value is Value */ export function assertType(expected: TypeName, found: Value): asserts found is Value { const actual = Value.getType(found); if (expected !== actual) { @@ -133,8 +155,11 @@ export namespace Value { } } + /** Returns a Value given a Struct */ export function get(struct: Struct | undefined, path: string): Value; + /** Returns a Value given a Struct */ export function get(struct: Struct | undefined, ...steps: string[]): Value; + /** Returns a Value given a Struct */ export function get(struct: Struct | undefined, ...parts: string[]): Value { let value: Value = struct; const errorPath: string[] = []; @@ -150,12 +175,14 @@ export namespace Value { return value; } + /** Serializes value */ export function serialize(value: Value): string { const writer = new Writer(); writer.writeValue(value); return writer.data; } + /** Deserializes value */ export function deserialize(data: string): Value { const reader = new Reader(data); return reader.readValue(); @@ -321,5 +348,6 @@ export namespace Value { } } } +/** Confidence used Values */ // eslint-disable-next-line @typescript-eslint/no-redeclare export type Value = Value.Primitive | Value.Struct | Value.List | undefined; diff --git a/packages/sdk/src/context.ts b/packages/sdk/src/context.ts index e2495e36..cfcaa56b 100644 --- a/packages/sdk/src/context.ts +++ b/packages/sdk/src/context.ts @@ -1,15 +1,34 @@ import { Value } from './Value'; +/** + * Interface that describes a Contextual + * @public + */ export interface Contextual> { + /** Returns context of the current Confidence instance */ getContext(): Context; + /** Set Confidence context */ setContext(context: Context): void; + /** + * Creates a new Confidence instance with context + * @param context - Confidence context + * @returns Confidence instance + */ withContext(context: Context): Self; + /** Clears context of current Confidence instance */ clearContext(): void; } +/** + * Confidence context + * @public + */ export interface Context extends Value.Struct { + /** Visitor id */ visitor_id?: string; + /** Targeting key */ targeting_key?: string; + /** Page metadata */ page?: { path: string; referrer: string; diff --git a/packages/sdk/src/events.ts b/packages/sdk/src/events.ts index e266edc8..d01c6062 100644 --- a/packages/sdk/src/events.ts +++ b/packages/sdk/src/events.ts @@ -1,8 +1,20 @@ import { Value } from './Value'; import { Contextual } from './context'; +/** + * Event data + * @public + */ export type EventData = Value.Struct & { context?: never }; +/** + * EventSender interface + * @public + */ export interface EventSender extends Contextual { + /** + * Tracks an event + * @param name - event name + * @param data - data to track */ track(name: string, data?: EventData): void; } diff --git a/packages/sdk/src/flags.ts b/packages/sdk/src/flags.ts index 60510341..dbbef759 100644 --- a/packages/sdk/src/flags.ts +++ b/packages/sdk/src/flags.ts @@ -1,43 +1,77 @@ import { Contextual } from '.'; import { Value } from './Value'; +/** + * Flag evaluation identifiers + * @public + */ export namespace FlagEvaluation { + /** Error code thrown in case flag couldn't be correctly evaluated */ export type ErrorCode = 'FLAG_NOT_FOUND' | 'TYPE_MISMATCH' | 'NOT_READY' | 'TIMEOUT' | 'GENERAL'; + /** Flag evaluation case of Matched */ export interface Matched { + /** Matched reason */ readonly reason: 'MATCH'; + /** Flag value */ readonly value: T; + /** Flag variant */ readonly variant: string; } + /** Flag evaluation case of Unmatched */ export interface Unmatched { + /** Unmatched reason */ readonly reason: | 'UNSPECIFIED' | 'NO_SEGMENT_MATCH' | 'NO_TREATMENT_MATCH' | 'FLAG_ARCHIVED' | 'TARGETING_KEY_ERROR'; + /** Flag value */ readonly value: T; } + /** Flag evaluation case of Failed */ export interface Failed { + /** Failed reason */ readonly reason: 'ERROR'; + /** Flag value */ readonly value: T; + /** Error code */ readonly errorCode: ErrorCode; + /** Error message */ readonly errorMessage: string; } + /** Flag evaluation case of Resolved */ export type Resolved = Matched | Unmatched | Failed; + /** Flag evaluation case of Stale */ export type Stale = Resolved & PromiseLike>; } +/** Flag evaluation */ // eslint-disable-next-line @typescript-eslint/no-redeclare export type FlagEvaluation = FlagEvaluation.Resolved | FlagEvaluation.Stale; +/** + * Flags states + * @public + */ export type State = 'NOT_READY' | 'READY' | 'STALE' | 'ERROR'; +/** + * Flag state observer + * @public */ export type StateObserver = (state: State) => void; +/** + * Flag Resolver interface + * @public + */ export interface FlagResolver extends Contextual { + /** Subscribe to flag changes in Confidence */ subscribe(onStateChange?: StateObserver): () => void; + /** Evaluates a flag */ evaluateFlag(path: string, defaultValue: T): FlagEvaluation>; + /** Returns flag value for a given flag */ getFlag(path: string, defaultValue: T): Promise>; } diff --git a/packages/sdk/src/trackers/pageViews.ts b/packages/sdk/src/trackers/pageViews.ts index bfe44997..e7dc3a84 100644 --- a/packages/sdk/src/trackers/pageViews.ts +++ b/packages/sdk/src/trackers/pageViews.ts @@ -2,6 +2,10 @@ import { Closer } from '../Closer'; import { Trackable } from '../Trackable'; import { listenOn, spyOn } from '../utils'; +/** + * Tracks page views + * @public + */ export function pageViews(): Trackable.Manager { return controller => { let referrer: string = document.referrer; diff --git a/packages/sdk/src/trackers/visitorId.ts b/packages/sdk/src/trackers/visitorId.ts index a2f896c6..d99406c9 100644 --- a/packages/sdk/src/trackers/visitorId.ts +++ b/packages/sdk/src/trackers/visitorId.ts @@ -3,6 +3,9 @@ import { uuid, Cookie } from '../utils'; const COOKIE_NAME = 'cnfdVisitorId'; +/** + * Visitor Identity which can be used in Cookies + * @public */ export const visitorIdentity = (): Trackable.Manager => controller => { if (typeof document === 'undefined') return; let value = Cookie.get(COOKIE_NAME); diff --git a/packages/sdk/src/trackers/webVitals.ts b/packages/sdk/src/trackers/webVitals.ts index 5e4bbb0c..63333f33 100644 --- a/packages/sdk/src/trackers/webVitals.ts +++ b/packages/sdk/src/trackers/webVitals.ts @@ -46,7 +46,7 @@ export type WebVitalsOptions = { * Emit {@link https://web.dev/articles/vitals | Web Vitals} metric events. * * @param options - specifying which metrics to emit - * @returns a {@link Topic} to be used with {@link Confidence.track } + * @returns a Topic to be used with Confidence.track * @public */ export function webVitals({ diff --git a/packages/sdk/src/utils.ts b/packages/sdk/src/utils.ts index 4d75fa3c..8d30124b 100644 --- a/packages/sdk/src/utils.ts +++ b/packages/sdk/src/utils.ts @@ -12,6 +12,7 @@ export function spyOn>( ): CleanupFn { const t = target as any; const originalFn = t[fnName]; + // eslint-disable-next-line func-names t[fnName] = function (...args: any): any { try { return originalFn.call(this, ...args);