Skip to content

Commit

Permalink
feat: implement tracking as per spec
Browse files Browse the repository at this point in the history
Signed-off-by: Todd Baert <todd.baert@dynatrace.com>
  • Loading branch information
toddbaert committed Sep 20, 2024
1 parent 970335e commit c7ae35a
Show file tree
Hide file tree
Showing 20 changed files with 112 additions and 15 deletions.
3 changes: 2 additions & 1 deletion packages/angular/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"cli": {
"schematicCollections": [
"@angular-eslint/schematics"
]
],
"analytics": false
}
}
2 changes: 2 additions & 0 deletions packages/server/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
import { Features } from '../evaluation';
import { ProviderStatus } from '../provider';
import { ProviderEvents } from '../events';
import { Tracking } from '../tracking';

export interface Client
extends EvaluationLifeCycle<Client>,
Features,
ManageContext<Client>,
ManageLogger<Client>,
Tracking,
Eventing<ProviderEvents> {
readonly metadata: ClientMetadata;
/**
Expand Down
5 changes: 5 additions & 0 deletions packages/server/src/client/internal/open-feature-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
HookContext,
JsonValue,
Logger,
OccurrenceDetails,
OpenFeatureError,
ProviderFatalError,
ProviderNotReadyError,
Expand Down Expand Up @@ -221,6 +222,10 @@ export class OpenFeatureClient implements Client {
return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', context, options);
}

track(occurrenceKey: string, context: EvaluationContext, occurrenceDetails: OccurrenceDetails): void {
return this._provider.track?.(occurrenceKey, context, occurrenceDetails);
}

private async evaluate<T extends FlagValue>(
flagKey: string,
resolver: (
Expand Down
1 change: 1 addition & 0 deletions packages/server/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ export * from './open-feature';
export * from './transaction-context';
export * from './events';
export * from './hooks';
export * from './tracking';
export * from '@openfeature/core';
18 changes: 17 additions & 1 deletion packages/server/src/provider/provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,12 @@
import { CommonProvider, EvaluationContext, JsonValue, Logger, ResolutionDetails, ServerProviderStatus } from '@openfeature/core';
import {
CommonProvider,
EvaluationContext,
JsonValue,
Logger,
OccurrenceDetails,
ResolutionDetails,
ServerProviderStatus,
} from '@openfeature/core';
import { Hook } from '../hooks';

export { ServerProviderStatus as ProviderStatus };
Expand Down Expand Up @@ -57,4 +65,12 @@ export interface Provider extends CommonProvider<ServerProviderStatus> {
context: EvaluationContext,
logger: Logger,
): Promise<ResolutionDetails<T>>;

/**
* Track a thing
* @param occurrenceKey
* @param context
* @param occurrenceDetails
*/
track?(occurrenceKey: string, context: EvaluationContext, occurrenceDetails: OccurrenceDetails): void;
}
1 change: 1 addition & 0 deletions packages/server/src/tracking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './tracking';
12 changes: 12 additions & 0 deletions packages/server/src/tracking/tracking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { EvaluationContext, OccurrenceDetails } from '@openfeature/core';

export interface Tracking {

/**
* Track a thing
* @param occurrenceKey
* @param context
* @param occurrenceDetails
*/
track(occurrenceKey: string, context: EvaluationContext, occurrenceDetails: OccurrenceDetails): void;
}
2 changes: 1 addition & 1 deletion packages/shared/src/evaluation/context.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { PrimitiveValue } from './evaluation';
import { PrimitiveValue } from '../types';

export type EvaluationContextValue =
| PrimitiveValue
Expand Down
11 changes: 2 additions & 9 deletions packages/shared/src/evaluation/evaluation.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
export type FlagValueType = 'boolean' | 'string' | 'number' | 'object';

export type PrimitiveValue = null | boolean | string | number;
export type JsonObject = { [key: string]: JsonValue };
export type JsonArray = JsonValue[];
import { JsonValue } from '../types/structure';

/**
* Represents a JSON node value.
*/
export type JsonValue = PrimitiveValue | JsonObject | JsonArray;
export type FlagValueType = 'boolean' | 'string' | 'number' | 'object';

/**
* Represents a JSON node value, or Date.
Expand Down
1 change: 1 addition & 0 deletions packages/shared/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ export * from './logger';
export * from './provider';
export * from './evaluation';
export * from './type-guards';
export * from './tracking';
export * from './open-feature';
1 change: 1 addition & 0 deletions packages/shared/src/tracking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './occurrence';
20 changes: 20 additions & 0 deletions packages/shared/src/tracking/occurrence.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { PrimitiveValue } from '../types';


export type OccurrenceValue =
| PrimitiveValue
| Date
| { [key: string]: OccurrenceValue }
| OccurrenceValue[];

/**
* A container for arbitrary contextual data that can be used as a basis for dynamic evaluation
*/
export type OccurrenceDetails = {
/**
* A string uniquely identifying the subject (end-user, or client service) of a flag evaluation.
* Providers may require this field for fractional flag evaluation, rules, or overrides targeting specific users.
* Such providers may behave unpredictably if a targeting key is not specified at flag resolution.
*/
value?: number;
} & Record<string, OccurrenceValue>;
3 changes: 2 additions & 1 deletion packages/shared/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './metadata';
export * from './paradigm';
export * from './paradigm';
export * from './structure';
7 changes: 7 additions & 0 deletions packages/shared/src/types/structure.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export type PrimitiveValue = null | boolean | string | number;
export type JsonObject = { [key: string]: JsonValue };
export type JsonArray = JsonValue[];
/**
* Represents a JSON node value.
*/
export type JsonValue = PrimitiveValue | JsonObject | JsonArray;
8 changes: 7 additions & 1 deletion packages/web/src/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@ import { ClientMetadata, EvaluationLifeCycle, Eventing, ManageLogger } from '@op
import { Features } from '../evaluation';
import { ProviderStatus } from '../provider';
import { ProviderEvents } from '../events';
import { Tracking } from '../tracking';

export interface Client extends EvaluationLifeCycle<Client>, Features, ManageLogger<Client>, Eventing<ProviderEvents> {
export interface Client
extends EvaluationLifeCycle<Client>,
Features,
ManageLogger<Client>,
Eventing<ProviderEvents>,
Tracking {
readonly metadata: ClientMetadata;
/**
* Returns the status of the associated provider.
Expand Down
9 changes: 9 additions & 0 deletions packages/web/src/client/internal/open-feature-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
HookContext,
JsonValue,
Logger,
OccurrenceDetails,
OpenFeatureError,
ProviderFatalError,
ProviderNotReadyError,
Expand Down Expand Up @@ -179,6 +180,14 @@ export class OpenFeatureClient implements Client {
return this.evaluate<T>(flagKey, this._provider.resolveObjectEvaluation, defaultValue, 'object', options);
}

track(occurrenceKey: string, occurrenceDetails: OccurrenceDetails): void {
const context = {
...OpenFeature.getContext(this?.options?.domain),
};

return this._provider.track?.(occurrenceKey, context, occurrenceDetails);
}

private evaluate<T extends FlagValue>(
flagKey: string,
resolver: (flagKey: string, defaultValue: T, context: EvaluationContext, logger: Logger) => ResolutionDetails<T>,
Expand Down
1 change: 1 addition & 0 deletions packages/web/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export * from './evaluation';
export * from './open-feature';
export * from './events';
export * from './hooks';
export * from './tracking';
export * from '@openfeature/core';
10 changes: 9 additions & 1 deletion packages/web/src/provider/provider.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ClientProviderStatus, CommonProvider, EvaluationContext, JsonValue, Logger, ResolutionDetails } from '@openfeature/core';
import { ClientProviderStatus, CommonProvider, EvaluationContext, JsonValue, Logger, OccurrenceDetails, ResolutionDetails } from '@openfeature/core';
import { Hook } from '../hooks';

export { ClientProviderStatus as ProviderStatus };
Expand Down Expand Up @@ -71,4 +71,12 @@ export interface Provider extends CommonProvider<ClientProviderStatus> {
context: EvaluationContext,
logger: Logger,
): ResolutionDetails<T>;

/**
* Track a thing
* @param occurrenceKey
* @param context
* @param occurrenceDetails
*/
track?(occurrenceKey: string, context: EvaluationContext, occurrenceDetails: OccurrenceDetails): void;
}
1 change: 1 addition & 0 deletions packages/web/src/tracking/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './tracking';
11 changes: 11 additions & 0 deletions packages/web/src/tracking/tracking.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { OccurrenceDetails } from '@openfeature/core';

export interface Tracking {

/**
* Track a thing
* @param occurrenceKey
* @param occurrenceDetails
*/
track(occurrenceKey: string, occurrenceDetails: OccurrenceDetails): void;
}

0 comments on commit c7ae35a

Please sign in to comment.