Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions packages/shared/sdk-client/src/LDClientImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
Hook,
LDClient,
LDClientIdentifyResult,
LDContextPartial,
LDIdentifyError,
LDIdentifyResult,
LDIdentifyShed,
Expand Down Expand Up @@ -245,7 +246,10 @@ export default class LDClientImpl implements LDClient, LDClientIdentifyResult {
*
* 3. A network error is encountered during initialization.
*/
async identify(pristineContext: LDContext, identifyOptions?: LDIdentifyOptions): Promise<void> {
async identify(
pristineContext: LDContextPartial,
identifyOptions?: LDIdentifyOptions,
): Promise<void> {
// In order to manage customization in the derived classes it is important that `identify` MUST be implemented in
// terms of `identifyResult`. So that the logic of the identification process can be extended in one place.
const result = await this.identifyResult(pristineContext, identifyOptions);
Expand All @@ -262,7 +266,7 @@ export default class LDClientImpl implements LDClient, LDClientIdentifyResult {
}

async identifyResult(
pristineContext: LDContext,
pristineContext: LDContextPartial,
identifyOptions?: LDIdentifyOptions,
): Promise<LDIdentifyResult> {
const identifyTimeout = identifyOptions?.timeout ?? DEFAULT_IDENTIFY_TIMEOUT_SECONDS;
Expand Down
5 changes: 3 additions & 2 deletions packages/shared/sdk-client/src/api/LDClient.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { LDContext, LDFlagSet, LDFlagValue, LDLogger } from '@launchdarkly/js-sdk-common';

import { Hook } from './integrations/Hooks';
import type { LDContextPartial } from './LDContext';
import { LDEvaluationDetail, LDEvaluationDetailTyped } from './LDEvaluationDetail';
import { LDIdentifyOptions } from './LDIdentifyOptions';
import { LDIdentifyResult } from './LDIdentifyResult';
Expand Down Expand Up @@ -112,7 +113,7 @@ export interface LDClient {
*
* 3. A network error is encountered during initialization.
*/
identify(context: LDContext, identifyOptions?: LDIdentifyOptions): Promise<void>;
identify(context: LDContextPartial, identifyOptions?: LDIdentifyOptions): Promise<void>;

/**
* Determines the json variation of a feature flag.
Expand Down Expand Up @@ -366,7 +367,7 @@ export interface LDClientIdentifyResult {
* The promise returned from this method will not be rejected.
*/
identifyResult(
context: LDContext,
context: LDContextPartial,
identifyOptions?: LDIdentifyOptions,
): Promise<LDIdentifyResult>;
}
25 changes: 25 additions & 0 deletions packages/shared/sdk-client/src/api/LDContext.ts
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this typing looks good for a multi-kind context, but not for a single kind context. In that this typing for a single kind would make key appear to be not an available option.

I wonder if we should just be using basically a copy of the single/multi context kinds with key correct specified as being optional. Then converting that for internal use?

Though, I suppose, it could be an Omit and then & { key?: string }. I want to make sure we have somewhat intelligible code completion though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or it could be type singleKindOptionalKey = Omit<LDSingleKindContextBase, 'key'> | LDSingleKindContextBase

Though again I am not sure how good the intellisense for that would be. Maybe fine.

Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import {
LDContextCommon,
LDSingleKindContext as LDSingleKindContextBase,
} from '@launchdarkly/js-sdk-common';

/**
* A single kind context without a key. When this type of context is used, the key will be generated by the SDK via
* the {@link ensureKey} function.
*/
type singleKindContextWithoutKey = Omit<LDSingleKindContextBase, 'key'>;

/**
* A multi kind context without a key. When this type of context is used, the keys will be generated by the SDK via
* the {@link ensureKey} function.
*/
interface multiKindContextWithoutKey {
kind: 'multi';
[kind: string]: 'multi' | LDContextCommon | Omit<LDContextCommon, 'key'>;
}

/**
* A partial context is a context that is missing a key. This is an acceptable form of context to identfy with as
* the key will be generated by the SDK via the {@link ensureKey} function.
*/
export type LDContextPartial = singleKindContextWithoutKey | multiKindContextWithoutKey;
1 change: 1 addition & 0 deletions packages/shared/sdk-client/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './LDIdentifyOptions';
export * from './LDInspection';
export * from './LDIdentifyResult';
export * from './LDPlugin';
export * from './LDContext';
6 changes: 5 additions & 1 deletion packages/shared/sdk-client/src/context/ensureKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
Platform,
} from '@launchdarkly/js-sdk-common';

import type { LDContextPartial } from '../api/LDContext';
import { getOrGenerateKey } from '../storage/getOrGenerateKey';
import { namespaceForAnonymousGeneratedContextKey } from '../storage/namespaceUtils';

Expand Down Expand Up @@ -63,7 +64,10 @@ const ensureKeyLegacy = async (c: LDUser, platform: Platform) => {
* @param context
* @param platform
*/
export const ensureKey = async (context: LDContext, platform: Platform): Promise<LDContext> => {
export const ensureKey = async (
context: LDContextPartial,
platform: Platform,
): Promise<LDContext> => {
const cloned = clone<LDContext>(context);

if (isSingleKind(cloned)) {
Expand Down