@objectiv/tracker-core
Version:
Core functionality for Objectiv JavaScript trackers
1,109 lines (1,085 loc) • 73.1 kB
TypeScript
import { AbstractLocationContext, AbstractGlobalContext, AbstractEvent, Contexts, EventAbstractDiscriminators, ApplicationContext, ContentContext, CookieIdContext, ExpandableContext, HttpContext, IdentityContext, InputContext, InputValueContext, LinkContext, LocaleContext, MarketingContext, MediaPlayerContext, NavigationContext, OverlayContext, PathContext, PressableContext, RootLocationContext, SessionContext, ApplicationLoadedEvent, FailureEvent, HiddenEvent, InputChangeEvent, InteractiveEvent, MediaEvent, MediaLoadEvent, MediaPauseEvent, MediaStartEvent, MediaStopEvent, NonInteractiveEvent, PressEvent, SuccessEvent, VisibleEvent, AbstractContext } from '@objectiv/schema';
/**
* An array of Location Contexts
*/
declare type LocationStack = AbstractLocationContext[];
/**
* An array of Global Contexts
*/
declare type GlobalContexts = AbstractGlobalContext[];
/**
* The configuration of the Contexts interface
*/
declare type ContextsConfig = {
location_stack?: LocationStack;
global_contexts?: GlobalContexts;
};
declare enum GlobalContextName {
ApplicationContext = "ApplicationContext",
CookieIdContext = "CookieIdContext",
HttpContext = "HttpContext",
IdentityContext = "IdentityContext",
InputValueContext = "InputValueContext",
LocaleContext = "LocaleContext",
MarketingContext = "MarketingContext",
PathContext = "PathContext",
SessionContext = "SessionContext"
}
declare type AnyGlobalContextName = 'ApplicationContext' | 'CookieIdContext' | 'HttpContext' | 'IdentityContext' | 'InputValueContext' | 'LocaleContext' | 'MarketingContext' | 'PathContext' | 'SessionContext';
declare enum LocationContextName {
ContentContext = "ContentContext",
ExpandableContext = "ExpandableContext",
InputContext = "InputContext",
LinkContext = "LinkContext",
MediaPlayerContext = "MediaPlayerContext",
NavigationContext = "NavigationContext",
OverlayContext = "OverlayContext",
PressableContext = "PressableContext",
RootLocationContext = "RootLocationContext"
}
declare type AnyLocationContextName = 'ContentContext' | 'ExpandableContext' | 'InputContext' | 'LinkContext' | 'MediaPlayerContext' | 'NavigationContext' | 'OverlayContext' | 'PressableContext' | 'RootLocationContext';
declare const ContextNames: Set<string>;
/**
* Tracker platforms
*/
declare enum TrackerPlatform {
ANGULAR = "ANGULAR",
CORE = "CORE",
BROWSER = "BROWSER",
REACT = "REACT",
REACT_NATIVE = "REACT_NATIVE"
}
/**
* TrackerEvents can be constructed with simply an Event `type` and, optionally, their Contexts.
* Contexts are entirely optional, although Collectors will mostly likely enforce minimal requirements around them.
* E.g. An interactive TrackerEvent without a Location Stack is probably not descriptive enough to be acceptable.
*/
declare type TrackerEventAttributes = Pick<AbstractEvent, '_type'> & ContextsConfig;
/**
* The configuration object accepted by TrackerEvent's constructor
* */
declare type TrackerEventConfig = Pick<AbstractEvent, '_type' | 'id' | 'time'> & ContextsConfig;
/**
* Our main TrackedEvent interface and basic implementation.
*/
declare class TrackerEvent implements Contexts {
readonly _type: string;
readonly id: string;
readonly time: number;
readonly location_stack: AbstractLocationContext[];
readonly global_contexts: AbstractGlobalContext[];
/**
* Configures the TrackerEvent instance via a TrackerEvent or TrackerEventConfig.
* Optionally one or more ContextConfig can be specified as additional parameters.
*
* ContextConfigs are used to configure location_stack and global_contexts. If multiple configurations have been
* provided they will be merged onto each other to produce a single location_stack and global_contexts.
*/
constructor({ _type, id, time, ...otherProps }: TrackerEventConfig, ...contextConfigs: ContextsConfig[]);
/**
* Custom JSON serializer that cleans up the internally properties we use internally to differentiate between
* Contexts and Event types and for validation. This ensures the Event we send to Collectors has only OSF properties.
*/
toJSON(): this & {
location_stack: ({} & AbstractLocationContext)[];
global_contexts: ({} & AbstractGlobalContext)[];
};
}
/**
* An Event ready to be validated.
*/
declare type EventToValidate = TrackerEvent & EventAbstractDiscriminators;
/**
* TrackerValidationRules always define a `validate` method.
*/
interface TrackerValidationLifecycleInterface {
/**
* Validation logic may be implemented via this method and may log issues to the console.
* Called after `enrich` and before the TrackerEvent is handed over to the TrackerTransport.
*/
validate?: (event: TrackerEvent) => void;
}
/**
* The TrackerValidationRuleConfig.
*/
declare type TrackerValidationRuleConfig = {
/**
* Optional. Allows adding further information to the logging prefix, e.g. 「objectiv:<logPrefix><ruleName>」<message>
*/
logPrefix?: string;
/**
* Optional. A predicated for discriminating which events are affected by this rule.
*/
eventMatches?: (event: EventToValidate) => boolean;
};
/**
* A ValidationRule must define its own `validationRuleName` and must define a `validate` callback.
*/
interface TrackerValidationRuleInterface extends Required<TrackerValidationLifecycleInterface> {
readonly validationRuleName: string;
readonly logPrefix?: string;
}
/**
* The TrackerValidationRule constructor interface.
*/
interface TrackerValidationRuleConstructor {
new (TrackerValidationRuleConfig: TrackerValidationRuleConfig): TrackerValidationRuleInterface;
}
/**
* Defines options shared between rules that perform Context validation.
*/
declare type ContextValidationRuleParameters<ContextType extends GlobalContextName | LocationContextName> = TrackerValidationRuleConfig & {
/**
* TrackerPlatform retrieved from the TrackerInstance. Used to retrieve platform-specific error messages.
*/
platform: TrackerPlatform;
/**
* The name of the Context to validate, e.g. `RootLocationContext`, `ApplicationContext, etc.
*/
contextName: ContextType;
/**
* Optional. Restricts whether the specified Context may be present multiple times.
*/
once?: boolean;
};
/**
* MissingGlobalContextValidationRule config object.
*/
declare type MissingGlobalContextValidationRuleParameters = Omit<ContextValidationRuleParameters<GlobalContextName>, 'once'>;
/**
* UniqueGlobalContextValidationRule config object.
*/
declare type UniqueGlobalContextValidationRuleParameters = Omit<ContextValidationRuleParameters<GlobalContextName>, 'once' | 'contextName'>;
/**
* GlobalContextValidationRule factory.
*/
declare type MissingGlobalContextValidationRuleFactory = (parameters: MissingGlobalContextValidationRuleParameters) => MissingGlobalContextValidationRuleParameters & TrackerValidationRuleInterface;
/**
* UniqueGlobalContextValidationRule factory.
*/
declare type UniqueGlobalContextValidationRuleFactory = (parameters: UniqueGlobalContextValidationRuleParameters) => UniqueGlobalContextValidationRuleParameters & TrackerValidationRuleInterface;
/**
* LocationStack order matters, the LocationContextValidationRule config supports specifying a required position.
*/
declare type LocationContextValidationRuleParameters = ContextValidationRuleParameters<LocationContextName> & {
/**
* Optional. Restricts in which position the specified LocationContext may be.
*/
position?: number;
};
/**
* GlobalContextValidationRule factory.
*/
declare type LocationContextValidationRuleFactory = (parameters: LocationContextValidationRuleParameters) => LocationContextValidationRuleParameters & TrackerValidationRuleInterface;
declare enum EventName {
ApplicationLoadedEvent = "ApplicationLoadedEvent",
FailureEvent = "FailureEvent",
HiddenEvent = "HiddenEvent",
InputChangeEvent = "InputChangeEvent",
InteractiveEvent = "InteractiveEvent",
MediaEvent = "MediaEvent",
MediaLoadEvent = "MediaLoadEvent",
MediaPauseEvent = "MediaPauseEvent",
MediaStartEvent = "MediaStartEvent",
MediaStopEvent = "MediaStopEvent",
NonInteractiveEvent = "NonInteractiveEvent",
PressEvent = "PressEvent",
SuccessEvent = "SuccessEvent",
VisibleEvent = "VisibleEvent"
}
declare type AnyEventName = 'ApplicationLoadedEvent' | 'FailureEvent' | 'HiddenEvent' | 'InputChangeEvent' | 'InteractiveEvent' | 'MediaEvent' | 'MediaLoadEvent' | 'MediaPauseEvent' | 'MediaStartEvent' | 'MediaStopEvent' | 'NonInteractiveEvent' | 'PressEvent' | 'SuccessEvent' | 'VisibleEvent';
/**
* Predicate that can be passed to `filter`. Receives a recordedEvent as parameter.
*/
declare type RecordedEventPredicate = (recordedEvent: RecordedEvent) => boolean;
/**
* RecordedEvents instances can filter the given RecordedEvents by event and/or their contexts.
*/
declare type RecordedEventsInterface = {
/**
* Holds a list of recorded events.
*/
events: RecordedEvent[];
/**
* Filters events by Event name (_type attribute). It supports querying by:
*
* - a single event name, e.g. `PressEvent`
* - a list of event names, e.g. [`PressEvent`, `ApplicationLoadedEvent`]
* - a predicate, for advanced operations, e.g. (event) => boolean
*
* `filter` returns a new instance of RecordedEvents for further chaining.
*/
filter(name: AnyEventName): RecordedEventsInterface;
filter(names: AnyEventName[]): RecordedEventsInterface;
filter(predicate: RecordedEventPredicate): RecordedEventsInterface;
/**
* Filters events by their LocationContext's name (_type attribute), name and id or just name.
* `withLocationContext` returns a new instance of RecordedEvents for further chaining.
*/
withLocationContext(name: AnyLocationContextName, id?: string): RecordedEventsInterface;
/**
* Filters events by their GlobalContext's name (_type attribute), name and id or just name.
* `withGlobalContext` returns a new instance of RecordedEvents for further chaining.
*/
withGlobalContext(name: AnyGlobalContextName, id?: string): RecordedEventsInterface;
};
/**
* A TypeScript friendly Object.keys
*/
declare const getObjectKeys: <T extends object>(obj: T) => (keyof T)[];
/**
* A TypeScript generic describing an array with at least one item of the given Type
*/
declare type NonEmptyArray<T> = [T, ...T[]];
/**
* A TypeScript utility type to make one specific property optional
*/
declare type Optional<Type, Key extends keyof Type> = Omit<Type, Key> & Partial<Pick<Type, Key>>;
/**
* A TypeScript NonEmptyArray guard
*/
declare function isNonEmptyArray<T>(array: T[]): array is NonEmptyArray<T>;
/**
* A UUID v4 generator
*/
declare const generateGUID: () => string;
/**
* Executes the given predicate every `intervalMs` for a maximum of `timeoutMs`.
* It resolves to `true` if predicated returns `true`. Resolves to false if `timeoutMs` is reached.
*/
declare const waitForPromise: ({ predicate, intervalMs, timeoutMs, }: {
predicate: Function;
intervalMs: number;
timeoutMs: number;
}) => Promise<boolean>;
/**
* Converts the given input to a standardized format to be used as identifier for Location Contexts.
* This may be used, among others, to infer a valid identifier from the title / label of a Button.
* If the given input is not a number or a string, or the normalization fails, it returns null.
*/
declare const makeId: (source: unknown, normalize?: boolean) => string | null;
/**
* Helper function to determine if we are in test mode by checking the Node environment.
*/
declare const isTestMode: () => boolean;
/**
* Helper function to determine if we are in development or test mode by checking the Node environment.
*/
declare const isDevMode: () => boolean;
/**
* Helper function to determine if we are in a browser - quite simplistically by checking the window object.
*/
declare const isBrowser: () => boolean;
/**
* All possible lifecycle methods of a TrackerPlugin.
*/
interface TrackerPluginLifecycleInterface {
/**
* Executed when the Tracker initializes.
* Useful to factor Contexts that will not change during this tracking session.
*/
initialize?: (tracker: TrackerInterface) => void;
/**
* Executed before the TrackerEvent is validated and handed over to the TrackerTransport.
* Useful to factor Contexts that may have changed from the last TrackerEvent tracking. Eg: URL, Time, User, etc
*/
enrich?: (contexts: Required<ContextsConfig>) => void;
}
/**
* A TrackerPlugin must define its own `pluginName` and may define TrackerPluginLifecycle callbacks.
* It also defines a method to determine if the plugin can be used. Similarly to the Transport interface, this can
* be used to check environment requirements, APIs availability, etc.
*/
interface TrackerPluginInterface extends TrackerPluginLifecycleInterface, TrackerValidationLifecycleInterface {
readonly pluginName: string;
/**
* Should return if the TrackerPlugin can be used. Eg: a browser based plugin may want to return `false` during SSR.
*/
isUsable(): boolean;
}
/**
* The TrackerPlugin constructor interface.
*/
interface TrackerPluginConstructor {
new (): TrackerPluginInterface;
}
/**
* Our Tracker Queue Store generic interface.
*/
interface TrackerQueueStoreInterface {
/**
* A name describing the Queue Store implementation for debugging purposes
*/
readonly queueStoreName: string;
/**
* How many TrackerEvents are in the store
*/
length: number;
/**
* Read Events from the store, if `size` is omitted all TrackerEvents will be returned
*/
read(size?: number, filterPredicate?: (event: TrackerEvent) => boolean): Promise<TrackerEvent[]>;
/**
* Write Events to the store
*/
write(...args: NonEmptyArray<TrackerEvent>): Promise<any>;
/**
* Delete TrackerEvents from the store by id
*/
delete(TrackerEventIds: string[]): Promise<any>;
/**
* Delete all TrackerEvents from the store
*/
clear(): Promise<any>;
}
/**
* The definition of the runner function. Gets executed every batchDelayMs to process the Queue.
*/
declare type TrackerQueueProcessFunction = (...args: NonEmptyArray<TrackerEvent>) => Promise<any>;
/**
* Our Tracker Events Queue generic interface.
*/
interface TrackerQueueInterface {
/**
* The TrackerQueueStore to use. Defaults to TrackerQueueMemoryStore
*/
readonly store: TrackerQueueStoreInterface;
/**
* How many events to dequeue at the same time. Defaults to 10;
*/
readonly batchSize: number;
/**
* How often to re-run and dequeue again, in ms. Defaults to 1000.
*/
readonly batchDelayMs: number;
/**
* How many batches to process simultaneously. Defaults to 4.
*/
readonly concurrency: number;
/**
* The function to execute every batchDelayMs. Must be set with `setProcessFunction` before calling `run`
*/
processFunction?: TrackerQueueProcessFunction;
/**
* A name describing the Queue implementation for debugging purposes
*/
readonly queueName: string;
/**
* Sets the processFunction to execute whenever run is called
*/
setProcessFunction(processFunction: TrackerQueueProcessFunction): void;
/**
* Adds one or more TrackerEvents to the Queue
*/
push(...args: NonEmptyArray<TrackerEvent>): Promise<any>;
/**
* Adds one or more TrackerEvents to the Queue
*/
readBatch(): Promise<TrackerEvent[]>;
/**
* Fetches a batch of Events from the Queue and executes the given `processFunction` with them.
*/
run(): Promise<any>;
/**
* Empties the Queue
*/
flush(): Promise<any>;
/**
* Returns whether all Events have been processed.
*/
isIdle(): boolean;
}
/**
* The configuration of the Tracker
*/
declare type TrackerConfig = ContextsConfig & {
/**
* Application ID. Used to generate ApplicationContext (global context).
*/
applicationId: string;
/**
* Optional. Function to generate unique identifiers used by the Tracker to set the `id` of TrackerEvents.
*
* Format
* The current format we use for these identifiers is Universally Unique Identifier version 4 (UUID v4).
*
* Default implementation
* The default implementation uses `v4` from the `uuid` js module. See: https://github.com/uuidjs/uuid.
*
* Why are unique identifiers so important?
* TrackerEvents must have globally unique identifiers, at the very least in the same session, for deduplication.
*
* This is because Trackers may send the same events multiple times to the Collector in several situations:
*
* - Tracker gets destroyed before receiving a response from the Collector.
* - Tracker gets destroyed before having the time to clean the persistent Queue.
* - Flaky connectivity may lead to timeouts and remote responses being lost, which results in retries.
*
* In general, Trackers will always re-send events when it's not 100% certain whether they were delivered or not.
*
* Unique identifiers are also essential across devices/platforms. E.g. web vs mobile, to ensure data may be
* correlated across them without collisions.
*
* What if the target platform doesn't have a GUID/UUID generator?
* On platforms that don't have a native method to generate a UUID/GUID but have native random generators, such as
* React Native, a polyfill may be used to gain access to the native random generators. These implementations
* usually expose the underlying system's SecureRandom (Android) or SecRandomCopyBytes (iOS).
* For example https://github.com/LinusU/react-native-get-random-values.
*
* What if the platform has no secure generator?
* Worst case scenario, the uuidv4 module included in Core Tracker can be used. It comes with a generator that uses
* Date.now() & Math.random as rng source. While not ideal, it's also not that bad: https://v8.dev/blog/math-random
*/
generateGUID?: () => string;
/**
* Optional. The platform of the Tracker Instance. This affects error logging. Defaults to Core.
*/
platform?: TrackerPlatform;
/**
* Optional. Unique identifier for the TrackerInstance. Defaults to the same value of `applicationId`.
*/
trackerId?: string;
/**
* Optional. TrackerQueue instance. Responsible for queueing and batching Events. Queuing occurs before Transport.
*/
queue?: TrackerQueueInterface;
/**
* Optional. TrackerTransport instance. Responsible for sending or storing Events. Transport occurs after Queueing.
*/
transport?: TrackerTransportInterface;
/**
* Optional. The collector endpoint URL.
*/
endpoint?: string;
/**
* Optional. Additional Plugins to add (or replace) to the default list of Plugins of the tracker.
*/
plugins?: TrackerPluginInterface[];
/**
* Optional. Defaults to true. Determines if the TrackerInstance.trackEvent will process Events or not.
*/
active?: boolean;
/**
* Optional. Defaults to false. Enabled anonymous tracking with the Collector. In anonymous mode:
* - The Collector will not generate nor set a Cookie header.
* - The Collector will anonymize all HttpContext attributes (remote_address, user_agent).
* - A volatile client session is generated by the Tracker. It will last only until the App is closed, or refreshed.
* - The tracker will send the new session id via SessionContext in the global contexts of all anonymous events.
*/
anonymous?: boolean;
};
/**
* The default list of Plugins of Core Tracker
*/
declare const makeCoreTrackerDefaultPluginsList: () => TrackerPluginInterface[];
/**
* The parameters object of Tracker.waitForQueue(parameters?: WaitForQueueParameters).
*/
declare type WaitForQueueParameters = {
intervalMs?: number;
timeoutMs?: number;
};
/**
* The `options` parameter of Tracker.trackEvent(event: TrackerEventConfig, options?: TrackEventOptions).
*/
declare type TrackEventOptions = {
waitForQueue?: true | WaitForQueueParameters;
flushQueue?: true | 'onTimeout';
};
/**
* TrackerInterface implements Contexts and TrackerConfig.
* Override properties that are initialized during constructions as required, such as platform, active and anonymous.
*/
declare type TrackerInterface = Contexts & TrackerConfig & {
platform: TrackerPlatform;
active: boolean;
anonymous: boolean;
};
/**
* Our basic platform-agnostic JavaScript Tracker interface and implementation
*/
declare class Tracker implements TrackerInterface {
readonly platform: TrackerPlatform;
readonly applicationId: string;
readonly trackerId: string;
readonly queue?: TrackerQueueInterface;
readonly transport?: TrackerTransportInterface;
readonly plugins: TrackerPluginInterface[];
readonly generateGUID: () => string;
readonly _endpoint?: string;
active: boolean;
anonymous: boolean;
readonly location_stack: AbstractLocationContext[];
readonly global_contexts: AbstractGlobalContext[];
/**
* Configures the Tracker instance via one TrackerConfig and optionally one or more ContextConfig.
*
* TrackerConfig is used to configure TrackerTransport and TrackerPlugins.
*
* ContextConfigs are used to configure location_stack and global_contexts. If multiple configurations have been
* provided they will be merged onto each other to produce a single location_stack and global_contexts.
*/
constructor(trackerConfig: TrackerConfig, ...contextConfigs: ContextsConfig[]);
/**
* Getter to compute the actual endpoint to use. Appends `/anonymous` to `_endpoint` when in anonymous mode.
*/
get endpoint(): string | undefined;
/**
* Executes all Plugins and Transport `initialize` callbacks and, if we have one, starts the Queue runner.
*/
initialize(): void;
/**
* Setter for the Tracker Instance `active` state, reruns the tracker's `initialize` if state changes.
*/
setActive(newActiveState: boolean): void;
/**
* Setter for the Tracker Instance `anonymous` state, reruns the tracker's `initialize` if state changes.
*/
setAnonymous(newAnonymousState: boolean): void;
/**
* Flushes the Queue
*/
flushQueue(): void;
/**
* Waits for Queue `isIdle` in an attempt to wait for it to finish its job.
* Resolves regardless if the Queue reaches an idle state or timeout is reached.
*/
waitForQueue(parameters?: WaitForQueueParameters): Promise<boolean>;
/**
* Merges Tracker Location and Global contexts, runs all Plugins and sends the Event via the TrackerTransport.
*/
trackEvent(event: TrackerEventAttributes, options?: TrackEventOptions): Promise<TrackerEvent>;
}
/**
* TrackerTransports can receive either Events ready to be processed or Event Promises.
*/
declare type TransportableEvent = TrackerEvent | Promise<TrackerEvent>;
declare const makeTransportSendError: () => Error;
declare const isTransportSendError: (error: Error) => boolean;
/**
* The TrackerTransport interface provides a single function to handle one or more TrackerEvents.
*
* TrackerTransport implementations may vary depending on platform. Eg: web: fetch, node: https module, etc
*
* Also, simpler implementations can synchronously send TrackerEvents right away to the Collector while more complex
* ones may leverage Queues, Workers and Storage for asynchronous sending, or batching.
*/
interface TrackerTransportInterface {
/**
* A name describing the Transport implementation for debugging purposes
*/
readonly transportName: string;
/**
* Should return if the TrackerTransport can be used. Most useful in combination with TransportSwitch.
*/
isUsable(): boolean;
/**
* Executed when the Tracker switches activation or anonymous modes.
*/
initialize?: (tracker: TrackerInterface) => void;
/**
* Process one or more TransportableEvent. Eg. Send, queue, store, etc
*/
handle(...args: NonEmptyArray<TransportableEvent>): Promise<any>;
}
/**
* A version of AbstractLocationContext without its discriminatory properties.
*/
declare type RecordedAbstractLocationContext = Omit<AbstractLocationContext, '__location_context' | '__instance_id'>;
/**
* A version of AbstractGlobalContext without its discriminatory properties.
*/
declare type RecordedAbstractGlobalContext = Omit<AbstractGlobalContext, '__global_context' | '__instance_id'>;
/**
* A predictable AbstractEvent. It has no `time`, a predictable identifier and no discriminatory properties.
* Its location_stack and global_contexts also don't have any discriminatory properties.
*/
declare type RecordedEvent = Omit<AbstractEvent, 'time' | 'location_stack' | 'global_contexts'> & {
location_stack: RecordedAbstractLocationContext[];
global_contexts: RecordedAbstractGlobalContext[];
};
/**
* The configuration options of EventRecorder.
*/
declare type EventRecorderConfig = {
/**
* When set to false it will cause EventRecorder to become unusable. Trackers will not automatically record events.
*/
enabled?: boolean;
/**
* Whether EventRecorder will start recording automatically. Default to true.
*/
autoStart?: boolean;
};
/**
* EventRecorder instances can store lists of TrackerEvents for snapshot-testing or other debugging purposes.
*/
declare type EventRecorderInterface = TrackerTransportInterface & Required<EventRecorderConfig> & {
/**
* When set to false it will cause EventRecorder to become unusable.
* Trackers will not automatically record events and errors will not be collected.
*/
enabled: boolean;
/**
* Whether EventRecorder is recording or not.
*/
recording: boolean;
/**
* A list of recorded error messages.
*/
errors: string[];
/**
* A list of recorded events wrapped in a RecordedEvents instance for easier querying.
*/
events: RecordedEventsInterface;
/**
* Allows reconfiguring EventRecorder.
*/
configure: (eventRecorderConfig?: EventRecorderConfig) => void;
/**
* Completely resets EventRecorder state.
*/
clear: () => void;
/**
* Starts recording events and errors.
*/
start: () => void;
/**
* Stops recording events and errors.
*/
stop: () => void;
/**
* Records an error.
*/
error: (errorMessage: string) => void;
};
/**
* LocationTree nodes have the same shape of LocationContext, but they can have a parent LocationNode themselves.
*/
declare type LocationNode = AbstractLocationContext & {
/**
* The parent LocationNode identifier.
*/
parentLocationId: string | null;
};
/**
* LocationTree is a global object providing a few utility methods to interact with the `locationNodes` global state.
* LocationContextWrapper makes sure to add new LocationNodes to the tree whenever a Location Wrapper is used.
*/
interface LocationTreeInterface {
/**
* Completely resets LocationTree state. Mainly useful while testing.
*/
clear: () => void;
/**
* Helper method to return a list of children of the given LocationNode
*/
children: (locationNode: LocationNode) => LocationNode[];
/**
* Helper method to log and register an error for the given locationId
*
* NOTE: Currently we support only `collision` issues. As more checks are implemented the type parameter may change.
*
* `collision` is optional and defaults to 'collision'.
*/
error: (locationId: string, message: string, type?: 'collision') => void;
/**
* Logs a readable version of the `locationNodes` state to the console.
*
* `depth` is optional and defaults to 0.
*/
log: (locationNode?: LocationNode, depth?: number) => void;
/**
* Checks the validity of the `locationNodes` state.
* Currently, we perform only Uniqueness Check: if identical branches are detected they will be logged to the console.
*
* Note: This method is invoked automatically when calling `LocationTree.add`.
*
* `locationStack` is optional and defaults to [].
* `locationPaths` is optional and defaults to new Set().
*/
validate: (locationNode?: LocationNode, locationStack?: AbstractLocationContext[], locationPaths?: Set<string>) => void;
/**
* Adds the given LocationContext to the `locationNodes` state, then invokes `LocationTree.validate` to report issues.
*
* Note: This method is invoked automatically by LocationContextWrapper.
* Note: This method automatically invokes `validate`.
*/
add: (locationContext: AbstractLocationContext, parentLocationContext: AbstractLocationContext | null) => void;
/**
* Removes the LocationNode corresponding to the given LocationContext from the LocationTree and errorCache.
* Performs also a recursive cleanup of orphaned nodes afterwards.
*
* Note: This method is invoked automatically by LocationContextWrapper.
*/
remove: (locationContext: AbstractLocationContext) => void;
}
/**
* A subset of the Console interface methods.
*/
declare type TrackerConsoleImplementation = Pick<Console, 'debug' | 'error' | 'group' | 'groupCollapsed' | 'groupEnd' | 'info' | 'log' | 'warn'>;
/**
* TrackerConsole is a simplified implementation of Console.
*/
declare type TrackerConsoleInterface = TrackerConsoleImplementation & {
implementation: TrackerConsoleImplementation;
setImplementation: (implementation: TrackerConsoleImplementation) => void;
};
/**
* DeveloperTools interface definition.
*/
interface TrackerDeveloperToolsInterface {
EventRecorder: EventRecorderInterface;
getLocationPath: (locationStack: LocationStack) => string;
LocationTree: LocationTreeInterface;
makeLocationContextValidationRule: LocationContextValidationRuleFactory;
makeMissingGlobalContextValidationRule: MissingGlobalContextValidationRuleFactory;
makeUniqueGlobalContextValidationRule: UniqueGlobalContextValidationRuleFactory;
OpenTaxonomyValidationPlugin: TrackerPluginInterface;
TrackerConsole: TrackerConsoleInterface;
}
/**
* The generic interface of the TrackerRepository
*/
interface TrackerRepositoryInterface<T extends Tracker> {
/**
* A Map of all Tracker instances by `trackerId`
*/
trackersMap: Map<string, T>;
/**
* The default Tracker instance that will be returned when invoking `getTracker` without `trackerId` parameter
*/
defaultTracker?: T;
/**
* Adds a new Tracker instance to the trackersMap
*/
add(newInstance: T): void;
/**
* Deletes Tracker instance from the trackersMap by `trackerId`
*/
delete(trackerId: string): void;
/**
* Get a Tracker instance from the trackersMap by `trackerId`
*/
get(trackerId?: string): T | undefined;
/**
* Changes the default Tracker instance by specifying a `trackerId`
*/
setDefault(trackerId: string): void;
/**
* Sets all Tracker instances as active
*/
activateAll(): void;
/**
* Sets all Tracker instances as inactive
*/
deactivateAll(): void;
/**
* Flushes all Tracker instances Queues
*/
flushAllQueues(): void;
/**
* Waits for the queues of all Trackers to be idle, or flushed
*/
waitForAllQueues(parameters?: WaitForQueueParameters): Promise<true>;
}
/**
* Globals interface definition.
*/
interface TrackerGlobalsInterface {
clientSessionId: string;
devTools?: TrackerDeveloperToolsInterface;
TrackerRepository: TrackerRepositoryInterface<any>;
versions: Map<string, string>;
}
/** Creates instance of ApplicationContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {ApplicationContext} - ApplicationContext: A GlobalContext describing in which app the event happens, like a website or iOS app.
*/
declare const makeApplicationContext: (props: {
id: string;
}) => ApplicationContext;
/** Creates instance of ContentContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {ContentContext} - ContentContext: A Location Context that describes a logical section of the UI that contains other Location Contexts.
* Enabling Data Science to analyze this section specifically.
*/
declare const makeContentContext: (props: {
id: string;
}) => ContentContext;
/** Creates instance of CookieIdContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.cookie_id - Unique identifier from the session cookie.
* @returns {CookieIdContext} - CookieIdContext: Global context with information needed to reconstruct a user session.
*/
declare const makeCookieIdContext: (props: {
id: string;
cookie_id: string;
}) => CookieIdContext;
/** Creates instance of ExpandableContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {ExpandableContext} - ExpandableContext: A Location Context that describes a section of the UI that can expand & collapse.
*/
declare const makeExpandableContext: (props: {
id: string;
}) => ExpandableContext;
/** Creates instance of HttpContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.referrer - Full URL to HTTP referrer of the current page.
* @param {string} props.user_agent - User-agent of the agent that sent the event.
* @param {string | null} props.remote_address - (public) IP address of the agent that sent the event.
* @returns {HttpContext} - HttpContext: A GlobalContext describing meta information about the agent that sent the event.
*/
declare const makeHttpContext: (props: {
id: string;
referrer: string;
user_agent: string;
remote_address?: string | null;
}) => HttpContext;
/** Creates instance of IdentityContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.value - The unique identifier for this user/group/entity within the scope defined by `id`.
* @returns {IdentityContext} - IdentityContext: A Global Context to track the identity of users across sessions, platforms, devices. Multiple can be present.
* The `id` field is used to specify the scope of identification e.g. backend, md5(email), supplier_cookie, etc.
* The `value` field should contain the unique identifier within that scope.
*/
declare const makeIdentityContext: (props: {
id: string;
value: string;
}) => IdentityContext;
/** Creates instance of InputContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {InputContext} - InputContext: A Location Context that describes an element that accepts user input, i.e. a form field.
*/
declare const makeInputContext: (props: {
id: string;
}) => InputContext;
/** Creates instance of InputValueContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.value - The value of the input element.
* @returns {InputValueContext} - InputValueContext: A GlobalContext containing the value of a single input element. Multiple can be present.
*/
declare const makeInputValueContext: (props: {
id: string;
value: string;
}) => InputValueContext;
/** Creates instance of LinkContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.href - URL (href) the link points to.
* @returns {LinkContext} - LinkContext: A PressableContext that contains an href.
*/
declare const makeLinkContext: (props: {
id: string;
href: string;
}) => LinkContext;
/** Creates instance of LocaleContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string | null} props.language_code - Case sensitive ISO 639-1 language code. E.g. en, nl, fr, de, it, etc.
* @param {string | null} props.country_code - Case sensitive ISO 3166-1 alpha-2 country code. E.g. US, NL, FR, DE, IT, etc.
* @returns {LocaleContext} - LocaleContext: A GlobalContext describing the users' language (ISO 639-1) and country (ISO 3166-1 alpha-2).
*/
declare const makeLocaleContext: (props: {
id: string;
language_code?: string | null;
country_code?: string | null;
}) => LocaleContext;
/** Creates instance of MarketingContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {string} props.source - Identifies the advertiser, site, publication, etc.
* @param {string} props.medium - Advertising or marketing medium: cpc, banner, email newsletter, etc.
* @param {string} props.campaign - Individual campaign name, slogan, promo code, etc.
* @param {string | null} props.term - [Optional] Search keywords.
* @param {string | null} props.content - [Optional] Used to differentiate similar content, or links within the same ad.
* @param {string | null} props.source_platform - [Optional] To differentiate similar content, or links within the same ad.
* @param {string | null} props.creative_format - [Optional] Identifies the creative used (e.g., skyscraper, banner, etc).
* @param {string | null} props.marketing_tactic - [Optional] Identifies the marketing tactic used (e.g., onboarding, retention, acquisition etc).
* @returns {MarketingContext} - MarketingContext: a context that captures marketing channel info, so users can do attribution, campaign
* effectiveness and other models.
*/
declare const makeMarketingContext: (props: {
id: string;
source: string;
medium: string;
campaign: string;
term?: string | null;
content?: string | null;
source_platform?: string | null;
creative_format?: string | null;
marketing_tactic?: string | null;
}) => MarketingContext;
/** Creates instance of MediaPlayerContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {MediaPlayerContext} - MediaPlayerContext: A Location Context that describes a section of the UI containing a media player.
*/
declare const makeMediaPlayerContext: (props: {
id: string;
}) => MediaPlayerContext;
/** Creates instance of NavigationContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {NavigationContext} - NavigationContext: A Location Context that describes a section of the UI containing navigational elements, for example a menu.
*/
declare const makeNavigationContext: (props: {
id: string;
}) => NavigationContext;
/** Creates instance of OverlayContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {OverlayContext} - OverlayContext: A Location Context that describes a section of the UI that represents an overlay, i.e. a Modal.
*/
declare const makeOverlayContext: (props: {
id: string;
}) => OverlayContext;
/** Creates instance of PathContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {PathContext} - PathContext: A GlobalContext describing the path where the user is when an event is sent.
*/
declare const makePathContext: (props: {
id: string;
}) => PathContext;
/** Creates instance of PressableContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {PressableContext} - PressableContext: An Location Context that describes an interactive element (like a link, button, icon),
* that the user can press and will trigger an Interactive Event.
*/
declare const makePressableContext: (props: {
id: string;
}) => PressableContext;
/** Creates instance of RootLocationContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @returns {RootLocationContext} - RootLocationContext: A Location Context that uniquely represents the top-level UI location of the user.
*/
declare const makeRootLocationContext: (props: {
id: string;
}) => RootLocationContext;
/** Creates instance of SessionContext
* @param {Object} props - factory properties
* @param {string} props.id - A unique string identifier to be combined with the Context Type (`_type`)
* for Context instance uniqueness.
* @param {number} props.hit_number - Hit counter relative to the current session, this event originated in.
* @returns {SessionContext} - SessionContext: A GlobalContext describing meta information about the current session.
*/
declare const makeSessionContext: (props: {
id: string;
hit_number: number;
}) => SessionContext;
/** Creates instance of ApplicationLoadedEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @returns {Omit<ApplicationLoadedEvent, 'id' | 'time'>} - ApplicationLoadedEvent: A NonInteractive event that is emitted after an application (eg. SPA) has finished loading.
*/
declare const makeApplicationLoadedEvent: (props?: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
}) => Omit<ApplicationLoadedEvent, 'id' | 'time'>;
/** Creates instance of FailureEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @param {string} props.message - Failure message.
* @returns {Omit<FailureEvent, 'id' | 'time'>} - FailureEvent: A NonInteractiveEvent that is sent when a user action results in a error,
* like an invalid email when sending a form.
*/
declare const makeFailureEvent: (props: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
message: string;
}) => Omit<FailureEvent, 'id' | 'time'>;
/** Creates instance of HiddenEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @returns {Omit<HiddenEvent, 'id' | 'time'>} - HiddenEvent: A NonInteractiveEvent that's emitted after a LocationContext has become invisible.
*/
declare const makeHiddenEvent: (props?: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
}) => Omit<HiddenEvent, 'id' | 'time'>;
/** Creates instance of InputChangeEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @returns {Omit<InputChangeEvent, 'id' | 'time'>} - InputChangeEvent: Event triggered when user input is modified.
*/
declare const makeInputChangeEvent: (props?: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
}) => Omit<InputChangeEvent, 'id' | 'time'>;
/** Creates instance of InteractiveEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @returns {Omit<InteractiveEvent, 'id' | 'time'>} - InteractiveEvent: The parent of Events that are the direct result of a user interaction, e.g. a button click.
*/
declare const makeInteractiveEvent: (props?: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
}) => Omit<InteractiveEvent, 'id' | 'time'>;
/** Creates instance of MediaEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event. They carry information that is not
* related to where the Event originated (location), such as device, platform or business data.
* @returns {Omit<MediaEvent, 'id' | 'time'>} - MediaEvent: The parent of non-interactive events that are triggered by a media player.
* It requires a MediaPlayerContext to detail the origin of the event.
*/
declare const makeMediaEvent: (props?: {
location_stack?: AbstractLocationContext[];
global_contexts?: AbstractGlobalContext[];
}) => Omit<MediaEvent, 'id' | 'time'>;
/** Creates instance of MediaLoadEvent
* @param {Object} props - factory properties
* @param {AbstractLocationContext[]} props.location_stack - The location stack is an ordered list (stack), that contains a hierarchy of location contexts that
* deterministically describes where an event took place from global to specific.
* The whole stack (list) is needed to exactly pinpoint where in the UI the event originated.
* @param {AbstractGlobalContext[]} props.global_contexts - Global contexts add global / general information about the event.