# Reference

## `Flagship` class

The `Flagship` class represents the SDK. It facilitates the initialization process and creation of new visitors.

### `start` methodc

Starts the flagship SDK and returns the [Flagship](#flagship-class) instance.

**`static start (envId: string, apiKey: string, config?: IFlagshipConfig): Promise<Flagship>`**

Arguments:

| Name   | Type   | Required     | Description                                                                |
| ------ | ------ | ------------ | -------------------------------------------------------------------------- |
| envId  | String | **Required** | Environment id provided by Flagship.                                       |
| apiKey | String | **Required** | Api authentication key provided by Flagship.                               |
| config | Object | **Optional** | Custom flagship configuration. [see SDK configuration](#sdk-configuration) |

Example:

{% tabs %}
{% tab title="Js / Node JS" %}

```javascript
import { Flagship } from "@flagship.io/js-sdk";

await Flagship.start("<ENV_ID>", "<API_KEY>");

// or

const fsInstance = await Flagship.start("<ENV_ID>", "<API_KEY>");
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { Flagship } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

await Flagship.start("<ENV_ID>", "<API_KEY>");

// or

const fsInstance = await Flagship.start("<ENV_ID>", "<API_KEY>");
```

{% endtab %}
{% endtabs %}

### `newVisitor` method

Creates and returns a new [`Visitor`](#visitor-class) instance

This method should always be called after the Flagship SDK has started.

**`static newVisitor (params: INewVisitor): Visitor`**

**`newVisitor (params: INewVisitor): Visitor`**

This method accepts only one argument with the following shape:

<table data-full-width="false"><thead><tr><th>Key</th><th>Type</th><th>Default</th><th>Description</th></tr></thead><tbody><tr><td>visitorId</td><td>string</td><td>undefined</td><td><p><em><strong>Optional</strong></em> Unique visitor identifier. If not set, it will be generated automatically.</p><p>In <strong>client-side</strong>, if not specified, the id will either be automatically generated or will be the visitor id from the previous session (if <code>reuseVisitorIds</code> is set to <code>true</code>).</p></td></tr><tr><td>hasConsented</td><td>boolean</td><td>false</td><td><em><strong>Required</strong></em><br>Specifies if the visitor has consented for personal data usage. When set to false, some features will be deactivated and the cache will be deactivated and cleared.</td></tr><tr><td>isAuthenticated</td><td>boolean</td><td>false</td><td>Specify if the visitor is authenticated or anonymous for Experience continuity.</td></tr><tr><td>context</td><td>object { [key: string]: string | number | boolean }</td><td>{}</td><td><p>The visitor context is a dataset key/value that defines the current visitor. It is sent to Flagship for targeting purposes (use-case assignment) and to enrich reporting with Context Filters.</p><p>Context keys must be strings, and the value types must be one of the following: number, boolean, or string.</p></td></tr><tr><td>shouldSaveInstance</td><td>boolean</td><td><code>false</code> on server-side<br><code>true</code> on client-side</td><td>Specifies whether the newly created visitor instance should be saved into Flagship instance.<br>If set to <strong>true</strong>, the newly created visitor instance will be saved into Flagship. If set to <strong>false</strong>, the newly created visitor instance will not be saved, but simply returned.</td></tr><tr><td>initialCampaigns</td><td>object</td><td>undefined</td><td><em><strong>Optional</strong></em><br>A <a href="https://docs.developers.flagship.io/docs/js-reference#serializedflagmetadata">set</a> of flag data provided to avoid the SDK from having an empty cache during the first initialization.</td></tr><tr><td>initialFlagsData</td><td>array</td><td>undefined</td><td><em><strong>Optional</strong></em><br>A <a href="https://docs.developers.flagship.io/docs/js-reference#serializedflagmetadata">set</a> of flag data provided to avoid the SDK from having an empty cache during the first initialization.</td></tr><tr><td>onFlagsStatusChanged</td><td>function(object):void</td><td>undefined</td><td><em><strong>Optional</strong></em><br>Callback function that will be called when the fetch flags status changes. <a href="https://docs.developers.flagship.io/docs/js-reference#onflagsstatuschanged">see arguments</a></td></tr></tbody></table>

{% hint style="info" %}
📘 Information

* When the property `fetchNow` in the configuration is set to `true`, the SDK will automatically fetch flag right after finishing creating the visitor.
* Visitor context keys must have a type of `string`
* Visitor context values must have a type of `string`, `boolean`, `number`
* Visitor context keys and values are **case sensitive**
* When both `initialCampaigns` and `initialFlags` are provided, the system will disregard `initialCampaigns` and only use `initialFlags`.
  {% endhint %}

#### onFlagsStatusChanged

The `onFlagsStatusChanged` function has one argument

| Argument | Type   | Description                                                |
| -------- | ------ | ---------------------------------------------------------- |
| status   | number | Status of the SDK. [see`FlagsStatus`](#flagsstatus-object) |

**FlagsStatus object**

`FlagsStatus` is an object representing the status of visitor fetch for flag data.

```typescript
type FlagsStatus = {
  /**
   * The new status of the flags fetch.
   */
  status: FSFetchStatus;
  /**
   * The reason for fetching Flags.
   */
  reason: FSFetchReasons;
};
```

| Key/Property | Type   | Description                                                    |
| ------------ | ------ | -------------------------------------------------------------- |
| status       | object | Enum representing the status of the flags in the Flagship SDK. |
| reason       | object | Enum representing the reasons for fetching Flags.              |

**FSFetchStatus** enum

`FSFetchStatus` is an enum representing the status of the flags in the visitor instance

| Key             | Type   | Description                                                                                                     |
| --------------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| FETCHED         | string | The flags have been successfully fetched from the API or re-evaluated in bucketing mode.                        |
| FETCH\_REQUIRED | string | The flags need to be re-fetched due to a change in context, or because the flags were loaded from cache or XPC. |
| NOT\_FOUND      | string | The flag was not found or does not exist.                                                                       |
| PANIC           | string | The SDK is in PANIC mode: All features are disabled except for the one to fetch flags.                          |

**FSFetchReasons** enum

`FSFetchReasons` is an enum representing the reasons for re-fetching Flags.

| Key               | Type   | Description                                                     |
| ----------------- | ------ | --------------------------------------------------------------- |
| AUTHENTICATE      | string | Indicates that the XPC method 'authenticate' has been called.   |
| FETCH\_ERROR      | string | Indicates that fetching flags has failed.                       |
| NONE              | string | Indicates that there is no specific reason for fetching flags.  |
| READ\_FROM\_CACHE | string | Indicates that flags have been fetched from the cache.          |
| UPDATE\_CONTEXT   | string | Indicates that a context has been updated or changed.           |
| UNAUTHENTICATE    | string | Indicates that the XPC method 'unauthenticate' has been called. |
| VISITOR\_CREATED  | string | Indicates that the visitor has been created.                    |

### `getStatus` method

Returns current status of Flagship SDK. [see`FSSdkStatus`](#fssdkstatus)

* **`getStatus (): FSSdkStatus`**
* **`static getStatus (): FSSdkStatus`**

### `getConfig` method

Returns the current config used by the SDK. [see configuration attribute](#sdk-configuration)

* **`getConfig (): IFlagshipConfig`**
* **`static getConfig (): IFlagshipConfig`**

### `getVisitor` method

Returns the last visitor created and saved or return undefined if no visitor has been saved. [see newVisitor](#newvisitor-method).

* **`getVisitor ():Visitor|undefined`**
* **`static getVisitor ():Visitor|undefined`**

### `close` method

This method batches and sends all collected hits. It should be called when your application (script) is about to `terminate` or `in the event of a crash` to ensures that all collected data is sent and not lost.

* **`close ():Promise<void>`**
* **`static close ():Promise<void>`**

\\

## SDK configuration

Below the details of every attribute you can set inside the SDK config object :

| Attribute                     | Type                                                         | Default                                             | Description                                                                                                                                                                                                                                                                                                                                                                                          |
| ----------------------------- | ------------------------------------------------------------ | --------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| decisionMode                  | `DECISION-API`\|`BUCKETING`\|`BUCKETING_EDGE`                | `DECISION-API`                                      | The SDK running mode. see `Decision Mode`                                                                                                                                                                                                                                                                                                                                                            |
| fetchNow                      | boolean                                                      | true                                                | Determines whether to automatically fetch flags data when creating a new `Visitor`.                                                                                                                                                                                                                                                                                                                  |
| timeout                       | number                                                       | 2                                                   | <p>The timeout in seconds for API requests.<br><br>Timeout can't be lower than 0 second.</p>                                                                                                                                                                                                                                                                                                         |
| reuseVisitorIds               | boolean                                                      | true                                                | <p><strong>client-side only</strong><br>If true, the SDK will save the visitor ID and/or anonymous ID and reuse it for the next session if <code>visitorId</code> is not set, to maintain cross-session visitor experience.</p>                                                                                                                                                                      |
| logLevel                      | number                                                       | 9                                                   | The maximum log level to display. see`LogLevel`                                                                                                                                                                                                                                                                                                                                                      |
| logManager                    | object                                                       | Defined                                             | <p>A custom implementation of the LogManager interface to receive logs from the SDK.<br><br>The object must fill Interface <code>IFlagshipLogManager</code></p>                                                                                                                                                                                                                                      |
| decisionApiUrl                | string                                                       | <https://decision.flagship.io/v2>                   | This setting can be useful if you need to simulate the API for tests such as end-to-end or if you want to move to an earlier version of the Flagship API.                                                                                                                                                                                                                                            |
| pollingInterval               | number                                                       | 5                                                   | <p><strong>Bucketing mode only</strong><br>The delay in seconds between two bucketing polling requests.<br><br>If 0 is given, it will only poll once at start time.</p>                                                                                                                                                                                                                              |
| hitDeduplicationTime          | number                                                       | 2.5                                                 | <p>The delay in seconds for hit deduplication. After a hit is sent, any future attempts to send the same hit will be blocked until the specified delay has expired.<br><br>If the value is 0, no deduplication process will be applied.</p>                                                                                                                                                          |
| initialBucketing              | object                                                       | undefined                                           | <p><strong>Optional</strong><br>An object containing the data received when fetching the bucketing endpoint.<br>Providing this object will make bucketing ready to use and the first polling will immediately check for updates.</p>                                                                                                                                                                 |
| visitorCacheImplementation    | object                                                       | Defined on client side and undefined on server side | <p><strong>Optional</strong><br>An object that implements the <code>visitorCacheImplementation</code> interface to handle the visitor cache. see cache management</p>                                                                                                                                                                                                                                |
| hitCacheImplementation        | object                                                       | Defined on client side and undefined on server side | <p><strong>Optional</strong><br>An object that implements the <code>IHitCacheImplementation</code> , interface to manage hits cache. see cache management</p>                                                                                                                                                                                                                                        |
| disableCache                  | boolean                                                      | false                                               | If set to true, hit cache and visitor cache will be disabled; otherwise, they will be enabled.. See cache management                                                                                                                                                                                                                                                                                 |
| onSdkStatusChanged            | function(number):void                                        | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called when the SDK status has changed. See arguments.</p>                                                                                                                                                                                                                                                                                 |
| onBucketingSuccess            | function(object):void                                        | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called when the first bucketing polling succeeds. See arguments</p>                                                                                                                                                                                                                                                                        |
| onBucketingFail               | function(error):void                                         | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called when the first bucketing polling fails. See arguments</p>                                                                                                                                                                                                                                                                           |
| onBucketingUpdated            | function(object):void                                        | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called each time bucketing data from Flagship has been updated. See arguments</p>                                                                                                                                                                                                                                                          |
| onLog                         | function(level: LogLevel, tag: string, message: string):void | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called whenever the SDK needs to report a log.<br>see arguments</p>                                                                                                                                                                                                                                                                        |
| trackingManagerConfig         | object                                                       | defined                                             | <p>Options to configure hit batching.<br>Tracking Manager Config</p>                                                                                                                                                                                                                                                                                                                                 |
| onVisitorExposed              | function(object):void                                        | undefined                                           | <p><strong>Optional</strong><br>A callback function to be called each time a flag is exposed to a visitor (i.e., when an activation hit is sent by the SDK).<br><br>see arguments</p>                                                                                                                                                                                                                |
| fetchThirdPartyData           | boolean                                                      | false                                               | <p><strong>Optional</strong><br><strong>Bucketing mode only</strong><br>If true, the SDK will fetch the visitor's segment from the <a href="https://developers.abtasty.com/docs/data/universal-data-connector">universal data connector</a> each time <code>fetchFlags</code> is called and append those segments in the visitor context.</p>                                                        |
| nextFetchConfig               | object                                                       | { revalidate: 20 }                                  | <p><strong>Optional</strong><br>In Next.js 13, you can define the time in seconds for storing SDK route cache before revalidation. <a href="https://nextjs.org/docs/app/building-your-application/data-fetching/caching#per-request-caching">learn more</a></p>                                                                                                                                      |
| fetchFlagsBufferingTime       | number                                                       | 2                                                   | <p><strong>Optional</strong><br>The delay in seconds for buffering fetch flags calls. After the SDK has fetched flags, they will be buffered for the specified delay. During this delay, any subsequent fetch flags calls will return the same flags.<br><br>If a value of 0 is given, no buffering process will be applied.<br><br>If visitor data has changed, the buffering will be bypassed.</p> |
| disableDeveloperUsageTracking | boolean                                                      | false                                               | Determines whether to disable the collection of analytics data.                                                                                                                                                                                                                                                                                                                                      |

Example:

```typescript
import { Flagship, DecisionMode, CacheStrategy, LogLevel } from "@flagship.io/js-sdk";
//For Deno: import { Flagship, DecisionMode, CacheStrategy, LogLevel } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

Flagship.start("<ENV_ID>", "<API_KEY>", {
  decisionMode: DecisionMode.BUCKETING,
  timeout: 10,
  reuseVisitorIds: true,
  logLevel: LogLevel.CRITICAL,
  trackingManagerConfig: {
      cacheStrategy: CacheStrategy.PERIODIC_CACHING,
      poolMaxSize: 10,
      batchIntervals: 100
  },
});
```

### Decision Mode

**`DECISION-API`Mode** (by default)

When the SDK is running in `DecisionApi` mode, the campaign assignments and targeting validation take place server-side in the flagship infrastructure. In this mode, each call to the [`fetchFlags`](#fetchflags-method) method to refresh the flags will make an HTTP request.

**`Bucketing`Mode**

In `Bucketing` mode, the SDK downloads all campaign configurations in a single bucketing file. This allows the SDK to compute variation assignments on the client-side. The bucketing file is cached and only re-downloaded when campaign configurations are updated in the Flagship interface. [**Learn more**](https://docs.abtasty.com/server-side/concepts/bucketing)

**`BUCKETING_EDGE`Mode**

This mode is recommended in Edge environnements, the SDK must be initialized with the bucketing file ,and the variation assignment is computed locally by the SDK.

There is no automatic batching process, so the `Flagship.close()` method must be called manually to batch and send all hits once collected. [**Learn more**](https://docs.abtasty.com/server-side/concepts/jamstack/case-study-how-to-use-flagship-in-serverless-edge-services)

`DecisionMode` is an enum defined decision type

| Key             | Value           | Type   | Description                      |
| --------------- | --------------- | ------ | -------------------------------- |
| DECISION\_API   | DECISION-API    | string | Flagship SDK mode Decision API   |
| BUCKETING       | BUCKETING       | string | Flagship SDK mode bucketing      |
| BUCKETING\_EDGE | BUCKETING\_EDGE | string | Flagship SDK mode bucketing edge |

### LogLevel

LogLevel is an enum defined the level of log to receive

```typescript
import { LogLevel } from "@flagship.io/js-sdk";

const level = LogLevel.ERROR;

Flagship.start("<ENV_ID>", "<API_KEY>", {
  logLevel: LogLevel.ERROR
});
```

| Key       | Value | Type | Description                               |
| --------- | ----- | ---- | ----------------------------------------- |
| NONE      | 0     | int  | Logging will be disabled.                 |
| EMERGENCY | 1     | int  | Only emergencies will be logged           |
| ALERT     | 2     | int  | Only alerts and above will be logged.     |
| CRITICAL  | 3     | int  | Only critical and above will be logged.   |
| ERROR     | 4     | int  | Only errors and above will be logged.     |
| WARNING   | 5     | int  | Only warnings and above will be logged.   |
| NOTICE    | 6     | int  | Only notices and above will be logged.    |
| INFO      | 7     | int  | Only info logs and above will be logged.  |
| DEBUG     | 8     | int  | Only debug logs and above will be logged. |
| ALL       | 9     | int  | Everything will be logged.                |

### IFlagshipLogManager

The aims of this Interface is to define methods that an object must have in order to receive Flagship SDK logs

```typescript
interface IFlagshipLogManager {
  emergency(message: string, tag: string): void;
  alert(message: string, tag: string): void;
  critical(message: string, tag: string): void;
  error(message: string, tag: string): void;
  warning(message: string, tag: string): void;
  notice(message: string, tag: string): void;
  info(message: string, tag: string): void;
  debug(message: string, tag: string): void;
  log(level: LogLevel, message: string, tag: string): void;
}
```

| Argument | Type   | Description                                                                             |
| -------- | ------ | --------------------------------------------------------------------------------------- |
| message  | string | Get a description of the log                                                            |
| tag      | string | Get the function that triggered the log                                                 |
| level    | number | <p>Get the log level.<br><br><em>only for log method</em> see <code>LogLevel</code></p> |

Usage :

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { LogLevel, Flagship } from "@flagship.io/js-sdk";

const customLog = {
  emergency(message, tag) {
    this.log(LogLevel.EMERGENCY, message, tag);
  },

  alert(message, tag) {
    this.log(LogLevel.ALERT, message, tag);
  },

  critical(message, tag) {
    this.log(LogLevel.CRITICAL, message, tag);
  },

  error(message, tag) {
    this.log(LogLevel.ERROR, message, tag);
  },

  warning(message, tag) {
    this.log(LogLevel.WARNING, message, tag);
  },

  notice(message, tag) {
    this.log(LogLevel.NOTICE, message, tag);
  },

  info(message, tag) {
    this.log(LogLevel.INFO, message, tag);
  },

  debug(message, tag) {
    this.log(LogLevel.DEBUG, message, tag);
  },

  log(level, message, tag) {
    console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
  },
};

Flagship.start("<ENV_ID>", "<API_KEY>", {
  logManager: customLog,
  logLevel: LogLevel.ALL
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { LogLevel, Flagship } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

const customLog = {
  emergency(message, tag) {
    this.log(LogLevel.EMERGENCY, message, tag);
  },

  alert(message, tag) {
    this.log(LogLevel.ALERT, message, tag);
  },

  critical(message, tag) {
    this.log(LogLevel.CRITICAL, message, tag);
  },

  error(message, tag) {
    this.log(LogLevel.ERROR, message, tag);
  },

  warning(message, tag) {
    this.log(LogLevel.WARNING, message, tag);
  },

  notice(message, tag) {
    this.log(LogLevel.NOTICE, message, tag);
  },

  info(message, tag) {
    this.log(LogLevel.INFO, message, tag);
  },

  debug(message, tag) {
    this.log(LogLevel.DEBUG, message, tag);
  },

  log(level, message, tag) {
    console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
  },
};

Flagship.start("your_env_id", "your_api_key", {
  logManager: customLog,
  logLevel: LogLevel.ALL,
  fetchNow: false,
  timeout: 2,
});
```

{% endtab %}
{% endtabs %}

### FSSdkStatus

`FSSdkStatus` is an enum defining the different status of Flagship SDK

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { FSSdkStatus } from "@flagship.io/js-sdk";

const status = FSSdkStatus.SDK_INITIALIZED;
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { FSSdkStatus } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

const status = FSSdkStatus.SDK_INITIALIZED;
```

{% endtab %}
{% endtabs %}

| Key                   | Value | Type | Description                                                                                                               |
| --------------------- | ----- | ---- | ------------------------------------------------------------------------------------------------------------------------- |
| SDK\_NOT\_INITIALIZED | 0     | int  | It is the default initial status. This status remains until the sdk has been initialized successfully.                    |
| SDK\_INITIALIZING     | 1     | int  | The SDK is currently initializing.                                                                                        |
| SDK\_PANIC            | 2     | int  | Flagship SDK is ready but is running in Panic mode: All features are disabled except the one which refreshes this status. |
| SDK\_INITIALIZED      | 3     | int  | The Initialization is done, and Flagship SDK is ready to use.                                                             |

### onSdkStatusChanged

The `onSdkStatusChanged` function has one argument

| Argument | Type   | Description                                         |
| -------- | ------ | --------------------------------------------------- |
| status   | number | Status of the SDK. [see`FSSdkStatus`](#fssdkstatus) |

### onBucketingSuccess

The `onBucketingSuccess` function has one argument with the following shape:

| Key/Property | Type   | Description                                                   |
| ------------ | ------ | ------------------------------------------------------------- |
| status       | number | String. Returns either 200 (fresh update) or 304 (no change). |
| payload      | object | The latest bucketing data received.                           |

### onBucketingFail

The `onBucketingFail` function has one argument

| Argument | Type   | Description                |
| -------- | ------ | -------------------------- |
| error    | object | Returns the error occurred |

### onBucketingUpdated

The `onBucketingUpdated` function has one argument

| Argument   | Type | Description                       |
| ---------- | ---- | --------------------------------- |
| lastUpdate | Date | Get the date of the latest update |

### OnVisitorExposed

In some cases, you'll need to send information about the exposure (When a flag has been seen by your visitor), like sending visitor and flag data to third parties.

To centralize it, we provide a callback in the configuration option of the SDK.

The `OnVisitorExposed` function has one argument with the following shape:

| Argument | Type             | Description                |
| -------- | ---------------- | -------------------------- |
| param    | OnVisitorExposed | Get data from exposed flag |

**OnVisitorExposed shape**

```typescript
type OnVisitorExposed ={
    exposedVisitor: {
      id: string
      anonymousId?:string|null
      context: Record<string, string|number|boolean>
  },
    fromFlag: {
      key: string
      value: unknown
      defaultValue: unknown
      metadata: IFlagMetadata
  }
}
```

| Key/Property   | Type   | Description                                                                                  |
| -------------- | ------ | -------------------------------------------------------------------------------------------- |
| exposedVisitor | object | This object represent the exposed visitor                                                    |
| fromFlag       | object | <p>This object represent the exposed flag.<br>(The flag that has triggered the exposure)</p> |

**exposedVisitor** object shape

| Key/Property | Type                                     | Description     |
| ------------ | ---------------------------------------- | --------------- |
| id           | string                                   | visitor id      |
| anonomousId  | string                                   | anonymous id    |
| context      | Record\<string, string\|number\|boolean> | visitor context |

**fromFlag** object shape

| Key/Property | Type          | Description                                                            |
| ------------ | ------------- | ---------------------------------------------------------------------- |
| key          | string        | flag key                                                               |
| value        | unknown       | flag value                                                             |
| defaultValue | unknown       | flag default value                                                     |
| metadata     | IFlagMetadata | Campaign information metadata [see](#getting-flags-campaigns-metadata) |

Here is an example on how to use this callback:

[Example with Mixpanel integration](https://docs.abtasty.com/server-side/integrations/analytics/integrate-with-mixpanel)\
[Example with Segment integration](https://docs.abtasty.com/server-side/integrations/analytics/integrate-with-segmentcom)

Learn more about [getting flags](#getting-flags)

### onLog

The `onLog` function has 3 arguments

| Argument | Type   | Description                                    |
| -------- | ------ | ---------------------------------------------- |
| level    | number | Get the log level. [see `LogLevel`](#loglevel) |
| tag      | string | Get the function that triggered the log        |
| message  | string | Get a description of the log                   |

```typescript
import { LogLevel, Flagship } from "@flagship.io/js-sdk";


Flagship.start("<ENV_ID>", "<API_KEY>", {
  logLevel: LogLevel.ALL,
  onLog: (level, tag, message) => {
    console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
  }
});
```

### Tracking Manager Config

Represents the configuration for the tracking manager.

The Tracking Manager’s batch processing reduces network traffic, prevents hit loss through caching, and resends any failed hits.

**options:**

| Key            | Type                    | Default value                                                                                                   | Description                                                                                                                                                                                                                                                                                       |
| -------------- | ----------------------- | --------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| cacheStrategy  | CacheStrategy \| number | <p><code>CONTINUOUS\_CACHING</code>: 0 for browser<br><code>PERIODIC\_CACHING</code>: 1 for nodeJs and Deno</p> | Define the strategy that will be used for hit caching see cacheStrategy                                                                                                                                                                                                                           |
| poolMaxSize    | number                  | <p><code>10</code> for browser<br><code>100</code> for nodeJs and Deno</p>                                      | <p>Define the minimum number of hits the pool must reach to automatically batch all hits in the pool and send them.<br><br>This value must be greater than 5; otherwise, the default value will be used.<br><br>Note: Having a large <code>poolMaxSize</code> can lead to performance issues.</p> |
| batchIntervals | number                  | <p><code>5s</code> for browser<br><code>10s</code> for nodeJs and Deno</p>                                      | <p>Define a regular interval in seconds to trigger the batch process.<br><br>The process will batch all hits from the pool whether the <code>poolMaxSize</code> is reached or not.<br><br>The value must be between 1 second and 10800s (3 hours). Otherwise default value will be applied.</p>   |

#### CacheStrategy

`cacheStrategy` is an enum defining the different caching strategies

| Key                 | Type   | Value | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| ------------------- | ------ | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CONTINUOUS\_CACHING | number | 0     | <p>When a hit is emitted, it will first be cached in database using IHitCacheImplementation, added into the pool, then after batching and sending, it will be flushed from database using IHitCacheImplementation.<br><br>It is Recommended for <code>client side applications</code> and should be used when your application is running in an environment where the probability of data loss is high.<br><br>The SDK has a default cache implementation for browser using <code>localStorage</code>.<br><br>Keep in mind that this strategy can do a lot of database I/O depending on how many hits your visitor can send. see example using localStorage.</p> |
| PERIODIC\_CACHING   | number | 1     | <p>When a hit is emitted, it will be added into the pool, then after batching and sending, all database hits will be flushed, then the entire pool will be cached using IHitCacheImplementation for both actions.<br><br>It is recommended for server-side applications and should be used when your application sends a lot of hits and the probability of data loss is low.<br><br>The number of I/Os in the database is low. see example using redis</p>                                                                                                                                                                                                      |

Example:

```typescript
import { CacheStrategy, Flagship } from "@flagship.io/js-sdk";


Flagship.start(ENV_ID, API_KEY, {
    trackingManagerConfig: {
      cacheStrategy: CacheStrategy.PERIODIC_CACHING,
      poolMaxSize: 10,
      batchIntervals: 100
    }
 })
```

## `Visitor` class

The `Visitor` class represents a unique user within your application. It aids in managing the visitor's data and fetching the corresponding flags for the visitor from the [Flagship platform](https://app.flagship.io/login) .

### `visitorId` property

The unique visitor identifier.

* **`visitorId: string`**

### `anonymousId` property

The anonymous visitor identifier.

* **`anonymousId: string | null`**

### `flagsStatus` property

The fetch status of the flags. [see`FlagsStatus`](#fetchflagsstatus-object)

* **`flagsStatus: FlagsStatus`**

### `hasConsented` property

Return True if the visitor has consented for private data usage, otherwise, it returns False.

* **`hasConsented: boolean`**

### `context` property

This property returns all the visitor's current context as an object

* **`get context () : Record<string, string | number | boolean>`**

### `setConsent` method

Set if visitor has consented for protected data usage.

* **`setConsent(hasConsented: boolean): void`**

Argument:

| Name         | Type    | Default  | Description                                                                               |
| ------------ | ------- | -------- | ----------------------------------------------------------------------------------------- |
| hasConsented | boolean | required | Set visitor consent for private data usage. When false some features will be deactivated. |

{% hint style="info" %}
📘 Information

When a visitor sets consent to false, the data collection features (visitorExposed and sendHit) will be deactivated for them and all hits related to the visitor will be flushed from the pool and the cache.
{% endhint %}

### `updateContext` method

Update the visitor context values, matching the given keys, used for targeting.\
\
A new context value associated with this key will be created if there is no previous matching value.

* **`public updateContext(context: Record<string, string | number | boolean>): void`**

Argument:

| Name    | Type   | Description            |
| ------- | ------ | ---------------------- |
| context | object | A Set of keys, values. |

### `clearContext` method

Clear the actual visitor context

* **`clearContext(): void`**

{% hint style="info" %}
📘 Information

* Visitor context keys must have a type of `string`
* Visitor context values must have a type of `string`, `bool`, `numeric`
* Visitor context keys and values are **case sensitive**
  {% endhint %}

### Context with predefined keys of context

Here's an example of how to use these predefined keys to update the visitor context in both Node.js and Deno environments:

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { Flagship, DEVICE_LOCALE, OS_NAME } from "@flagship.io/js-sdk";

Flagship.start("your_env_id", "your_api_key");

const visitor = Flagship.newVisitor({
  visitorId: "your_visitor_id",
  context: { age: 31, isVip: true },
});

visitor.updateContext({
  [DEVICE_LOCALE]: "fr",
  [OS_NAME]: "Ubuntu",
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { Flagship, DEVICE_LOCALE, OS_NAME } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

Flagship.start("your_env_id", "your_api_key");

const visitor = Flagship.newVisitor({
  visitorId: "your_visitor_id",
  context: { age: 31, isVip: true },
});

visitor.updateContext({
  [DEVICE_LOCALE]: "fr",
  [OS_NAME]: "Ubuntu",
});
```

{% endtab %}
{% endtabs %}

[Here](#predefined-visitor-context-keys) is the List of all predefined context keys.

### `fetchFlags` method

Invokes the `decision API` or refers to the `bucketing file` to refresh all campaign flags based on the visitor's context.

* **`fetchFlags(): Promise<void>`**

Example:

```typescript
//... import code

Flagship.start("your_env_id", "your_api_key");

const visitor = Flagship.newVisitor({
  visitorId: "your_visitor_id",
  context: { key: "value" },
});

visitor.fetchFlags().then(() => {
  //ready to use all features from the SDK
});
```

### Event listeners

The [`Visitor`](#visitor-class) instance includes event listeners to help you handle the SDK.

| Event listener | Description                                                                                                         |
| -------------- | ------------------------------------------------------------------------------------------------------------------- |
| ready          | is triggered each time the [fetchFlags](doc:javascript-reference#fetchflags-method) method completes its execution. |

### `getFlag` method

Return a [Flag](#flag-class) object by its key. If no flag matches the given key, an empty flag will be returned. the `exists()` method of the [Flag](#flag-class) object can be called to check if the flag has been found.

* **`getFlag(key:string):IFlag`**

Arguments:

| Name | Type   | Description                     |
| ---- | ------ | ------------------------------- |
| key  | String | The key associated to the flag. |

### `authenticate` method

Authenticate anonymous visitor.

* **`authenticate(visitorId: string): void`**

Argument:

| Name      | Type   | Default  | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| visitorId | string | required | Id of the new authenticated visitor. |

{% hint style="info" %}
📘 Information

* It is recommended calling the [**fetchFlags**](#fetchflags) method just after authenticating a visitor as the visitor data has changed.
* The visitor targeting / Flags could change based on this new data.
  {% endhint %}

### `unauthenticate` method

This method changes authenticated Visitor to anonymous visitor.

* **`unauthenticate(): void`**

{% hint style="info" %}
📘 Information

* It is recommended calling the [**fetchFlags**](#fetchflags) method just after the visitor has become anonymous as the visitor data has changed.
* The visitor targeting / Flags could change based on this new data.
  {% endhint %}

### `getFlags` method

Returns a [collection](#ifsflagcollection) of all flags fetched for the visitor.

* **`getFlags(): IFSFlagCollection`**

### `sendHit` method

This method sends a single Hit to the Flagship servers for reporting.

* **`sendHit (hit: IHit): Promise<void>`**

| Parameter | Type   | Default  | Description                   |
| --------- | ------ | -------- | ----------------------------- |
| hit       | object | required | Hit to send. [see Hit](#page) |

### `sendHits` method

This function sends multiple Hits to the Flagship servers for reporting.

* **`sendHits (hits: IHit[]): Promise<void>`**

| Parameter | Type           | Default  | Description                            |
| --------- | -------------- | -------- | -------------------------------------- |
| hit       | Array\<object> | required | A set of Hit to send. [see Hit](#page) |

### `collectEAIEventsAsync` method

Starts Collecting Emotion AI events for the visitor.

* **`collectEAIEventsAsync(): Promise<void>`**

\\

## `IFSFlag` interface

This interface represents a flag in the `Flagship SDK`. It helps you retrieve the flag value, access flag metadata, expose the flag, verify the flag's existence, and get the flag status with the following API:

### `metadata` property

It returns an object that implements the [IFSFlagMetadata](#ifsflagmetadata-interface) interface, which contains the metadata of the campaign’s flag. If the flag doesn’t exist, it returns an empty object.

* **`metadata:IFSFlagMetadata`**

### `status` property

Return the flag status.

* **`status: FSFlagStatus`**

`FSFlagStatus` is an enum representing the status of the flag

| Key             | Type   | Description                                                                                                     |
| --------------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| FETCHED         | string | The flags have been successfully fetched from the API or re-evaluated in bucketing mode.                        |
| FETCH\_REQUIRED | string | The flags need to be re-fetched due to a change in context, or because the flags were loaded from cache or XPC. |
| NOT\_FOUND      | string | The flag was not found or does not exist.                                                                       |
| PANIC           | string | The SDK is in PANIC mode: All features are disabled except for the one to fetch flags.                          |

### `getValue` method

Returns the value of the flag if the flag exists and the type of the default value matches the flag type value, otherwise it returns the default value.

* **`getValue<T>(defaultValue: T, visitorExposed : boolean) : T`**

Argument:

| Name           | Type    | Default Value | Description                                                                                                                                                                                                                                                                                               |
| -------------- | ------- | ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| defaultValue   | T       | `Required`    | **Required** The default value of the flag.                                                                                                                                                                                                                                                               |
| visitorExposed | Boolean | true          | <p>Indicates to Flagship that the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting.<br><br>It is possible to set this param to false and call <code>visitorExposed()</code> afterward when the visitor sees it.</p> |

Example:

```typescript
//other code

const flag = visitor.getFlag("displayVipFeature")

console.log("flag value:", flag.getValue(false))

```

{% hint style="info" %}
📘 Information

* The default value must be one of the following type : `string`, `number`, `boolean`, `object`, `array` or `null`.
* When the default value is `null`, no type checking will be performed
  {% endhint %}

### `visitorExposed` method

Notifies Flagship that the visitor has been exposed to and seen this flag.

* **`visitorExposed(): Promise<void>`**

### `exists` method

This method checks if the flag exists.

* **`exists(): boolean`**

\\

## `IFSFlagCollection` interface

It represents a collection of flags.

### `size` property

Gets the number of flags in the collection.

* **`readonly size: number`**

### `get` method

It returns the [flag](#ifsflag-interface) associated with the specified key, or an empty if the key is not found.

* **`get(key: string): IFSFlag`**

Arguments:

| Name | Type   | Description                     |
| ---- | ------ | ------------------------------- |
| key  | String | The key associated to the flag. |

### `has` method

Checks if the collection contains a flag with the specified key.

* **`has(key: string): boolean`**

Arguments:

| Name | Type   | Description                     |
| ---- | ------ | ------------------------------- |
| key  | String | The key associated to the flag. |

### `keys` method

Gets the keys of all flags in the collection.

* **`keys(): Set<string>`**

### `filter` method

It filters the collection based on a predicate function and returns A new [IFSFlagCollection](#ifsflagcollection-interface) containing the flags that satisfy the predicate.

* **`filter(predicate: (value: IFSFlag, key: string, collection: IFSFlagCollection) => boolean): IFSFlagCollection;`**

Arguments:

| Name      | Type     | Description                                           |
| --------- | -------- | ----------------------------------------------------- |
| predicate | function | The predicate function used to filter the collection. |

### `exposeAll` method

Exposes all flags in the collection.

* **`exposeAll(): Promise<void>`**

### `getMetadata` method

A map containing the [metadata](#ifsflagmetadata-interface) for all [flags](#ifsflag-interface) in the collection.

* **`getMetadata(): Map<string, IFSFlagMetadata>;`**

### `toJSON` method

Serializes the [metadata](#ifsflagmetadata-interface) for all flags in the collection.

* **`toJSON(): SerializedFlagMetadata[]`**

### `forEach` method

Iterates over each flag in the collection.

* **`forEach (callbackfn: (value: IFSFlag, key: string, collection: IFSFlagCollection) => void): void`**

\\

## `IFSFlagMetadata` interface

```typescript
interface IFSFlagMetadata{
    campaignId:string
  	campaignName:string
    variationGroupId:string
  	variationGroupName:string
    variationId: string
  	variationName:string
    isReference: boolean
    campaignType: string
    slug?:string|null
}
```

| Key                | Type    | Description                              |
| ------------------ | ------- | ---------------------------------------- |
| campaignId         | string  | Campaign ID                              |
| campaignName       | string  | Campaign name                            |
| variationGroupId   | string  | Variation group ID                       |
| variationGroupName | string  | Variation group Name                     |
| variationId        | string  | The variation ID assigned to the visitor |
| variationName      | string  | Variation name                           |
| isReference        | boolean | Specify if its the reference variation   |
| campaignType       | string  | campaign type                            |
| slug               | string  | campaign slug                            |

\\

## SerializedFlagMetadata

| Key                | Type    | Description                              |
| ------------------ | ------- | ---------------------------------------- |
| key                | string  | Flag name                                |
| campaignId         | string  | Campaign ID                              |
| campaignName       | string  | Campaign name                            |
| slug               | string  | campaign slug                            |
| campaignType       | string  | campaign type                            |
| variationGroupId   | string  | Variation group ID                       |
| variationGroupName | string  | Variation group name                     |
| variationId        | string  | The variation ID assigned to the visitor |
| variationName      | string  | Variation name                           |
| isReference        | boolean | Specify if its the reference variation   |
| hex                | string  | Reserved for Flagship                    |

\\

## Hit Tracking

This section guides you on how to track visitors in your application and learn how to build hits to feed your reports. For more details about our measurement protocol, refer to our [Universal Collect documentation](https://docs.abtasty.com/server-side/concepts/universal-collect-1).

There are five different types of Hits:

* Page
* Screen
* Transaction
* Item
* Event

### HitType

{% tabs %}
{% tab title="JS & NodeJS " %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

const page = HitType.PAGE;
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

const page = HitType.PAGE;
```

{% endtab %}
{% endtabs %}

| Key         | type   | Value       | Description                                         |
| ----------- | ------ | ----------- | --------------------------------------------------- |
| PAGE        | string | PAGEVIEW    | Indicates a URL viewed by a visitor.                |
| SCREEN      | string | SCREENVIEW  | Indicates a screen viewed by a visitor.             |
| TRANSACTION | string | TRANSACTION | Indicates a transaction made by a visitor.          |
| ITEM        | string | ITEM        | Represents an item purchased in a transaction.      |
| EVENT       | string | EVENT       | Indicates a specific action performed by a visitor. |

### Common Optional Parameters for Hits

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.PAGE,
  documentLocation: "https://localhost",
  userIp: "127.0.0.1",
  screenResolution: "800X600",
  locale: "fr",
  sessionNumber: "1234",
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.PAGE,
  documentLocation: "https://localhost",
  userIp: "127.0.0.1",
  screenResolution: "800X600",
  locale: "fr",
  sessionNumber: "1234",
});
```

{% endtab %}
{% endtabs %}

| Parameter        | Type   | Description                     |
| ---------------- | ------ | ------------------------------- |
| userIp           | String | (Optional) Visitor's IP address |
| screenResolution | string | (Optional) Screen resolution.   |
| locale           | String | (Optional) Visitor's language   |
| sessionNumber    | string | (Optional) Session number       |

### Page hit

This hit should be sent each time a visitor navigates to a new page.

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.PAGE, //or "PAGEVIEW"
  documentLocation: "https://www.my_domain_com/my_page",
});
```

{% endtab %}

{% tab title="Node" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.PAGE, //or "PAGEVIEW"
  documentLocation: "https://www.my_domain_com/my_page",
});
```

{% endtab %}
{% endtabs %}

A Page type hit has the following structure:

| Key/Property     | Type                | Default  | Description                          |
| ---------------- | ------------------- | -------- | ------------------------------------ |
| type             | string (`PAGEVIEW`) | required | type of hit. [see HitType](#hittype) |
| documentLocation | String              | required | Valid url.                           |

### Screen hit

This hit should be sent each time a visitor navigates to a new interface on the client side.

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.SCREEN, //or "SCREENVIEW"
  documentLocation: "home_screen",
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.SCREEN, //or "SCREENVIEW"
  documentLocation: "home_screen",
});
```

{% endtab %}
{% endtabs %}

A `Screen` type hit has the following structure:

| Key/Property     | Type                  | Default  | Description                          |
| ---------------- | --------------------- | -------- | ------------------------------------ |
| type             | string (`SCREENVIEW`) | required | Type of hit. [see HitType](#hittype) |
| documentLocation | String                | required | Name of screen.                      |

### Transaction hit

This hit should be sent when a visitor completes a Transaction.

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.TRANSACTION, //or "TRANSACTION"
  transactionId: "#12345",
  affiliation: "affiliation",
  taxes: 19.99,
  currency: "USD",
  couponCode: "code",
  itemCount: 1,
  shippingMethod: "road",
  shippingCosts: 5,
  paymentMethod: "credit_card",
  totalRevenue: "199.99",
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.TRANSACTION, //or "TRANSACTION"
  transactionId: "#12345",
  affiliation: "affiliation",
  taxes: 19.99,
  currency: "USD",
  couponCode: "code",
  itemCount: 1,
  shippingMethod: "road",
  shippingCosts: 5,
  paymentMethod: "credit_card",
  totalRevenue: "199.99",
});
```

{% endtab %}
{% endtabs %}

A hit of type `TRANSACTION` has this following structure:

| Key/Property   | Type                   | Default  | Description                                                                                                                                                  |
| -------------- | ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| type           | string (`TRANSACTION`) | required | Type of hit. [see HitType](#hittype)                                                                                                                         |
| transactionId  | String                 | required | Unique identifier for your transaction.                                                                                                                      |
| affiliation    | String                 | required | The name of the KPI that you will have inside your reporting. [**Learn more**](https://github.com/flagship-io/Gitbook/blob/main/docs/glossary/README.md#kpi) |
| totalRevenue   | float                  | optional | The total revenue associated with the transaction, including any shipping and/or tax amounts.                                                                |
| shippingCosts  | float                  | optional | The total shipping cost of your transaction.                                                                                                                 |
| shippingMethod | String                 | optional | The shipping method for your transaction.                                                                                                                    |
| taxes          | float                  | optional | Specifies the total amount of taxes in your transaction.                                                                                                     |
| currency       | String                 | optional | Specifies the currency of your transaction. NOTE: This value should be a valid ISO 4217 currency code.                                                       |
| paymentMethod  | String                 | optional | Specifies the payment method used for your transaction.                                                                                                      |
| itemCount      | int                    | optional | Specifies the number of items in your transaction.                                                                                                           |
| couponCode     | String                 | optional | Specifies the coupon code used by the customer in your transaction.                                                                                          |

### Item hit

This hit is used to associate an item with a transaction. It should be sent following the corresponding transaction hit.

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.ITEM, //or "ITEM"
  transactionId: "#12345",
  productName: "product",
  productSku: "sku123",
  itemPrice: 199.99,
  itemQuantity: 1,
  itemCategory: "test",
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.ITEM, //or "ITEM"
  transactionId: "#12345",
  productName: "product",
  productSku: "sku123",
  itemPrice: 199.99,
  itemQuantity: 1,
  itemCategory: "test",
});
```

{% endtab %}
{% endtabs %}

A hit of type `ITEM` has this following structure:

| Key/Property  | Type            | Default  | Description                              |
| ------------- | --------------- | -------- | ---------------------------------------- |
| type          | string (`ITEM`) | required | Type of hit. [see HitType](#hittype)     |
| transactionId | String          | required | Unique identifier for your transaction.  |
| productName   | String          | required | Name of your item.                       |
| productSku    | String          | required | SKU or item code.                        |
| itemCategory  | String          | optional | Category to which the item belongs.      |
| itemPrice     | float           | optional | Price for a single item/unit.            |
| itemQuantity  | int             | optional | Specifies the number of items purchased. |

{% hint style="info" %}
📘 Information

The `Item` hit is not currently available in the Flagship reporting view.
{% endhint %}

### Event hit

This hit can be used to track any event, such as a click on 'Add To Cart' or a newsletter subscription.

{% tabs %}
{% tab title="JS & NodeJS" %}

```typescript
import { HitType, EventCategory } from "@flagship.io/js-sdk";

visitor.sendHit({
  type: HitType.EVENT, //or "EVENT"
  category: EventCategory.USER_ENGAGEMENT, // or EventCategory.ACTION_TRACKING
  action: "click",
  label: "label",
  value: 100,
});
```

{% endtab %}

{% tab title="Deno" %}

```typescript
import { HitType, EventCategory } from "https://deno.land/x/flagship_io_js_sdk/mod.ts";

visitor.sendHit({
  type: HitType.EVENT, //or "EVENT"
  category: EventCategory.USER_ENGAGEMENT, // or EventCategory.ACTION_TRACKING
  label: "label",
  value: 100,
});
```

{% endtab %}
{% endtabs %}

An `EVENT` type hit has the following structure:

| Key/Property | Type             | Default  | Description                                                                                                                                                               |
| ------------ | ---------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| type         | string (`EVENT`) | required | Type of hit. see HitType                                                                                                                                                  |
| category     | string           | required | <p>Category of your event.<br><br><strong>NOTE:</strong> This value must be either <code>User Engagement</code> or <code>Action Tracking</code>.</p>                      |
| action       | string           | required | Event name, which will also serve as the KPI in your reporting. **Learn more**                                                                                            |
| label        | string           | optional | Additional description of your event.                                                                                                                                     |
| value        | integer          | optional | <p>Can be used to evaluate visitor interactions with individual site objects or content items.<br><br><em>NOTE:</em> this value must be non-negative and not a float.</p> |

## Cache management

The purpose of cache management is to address the following issues:

* **Re-allocation in bucketing mode :**

In bucketing mode, the SDK ensures that a visitor remains in the variation where they were initially allocated, even if the customer or dynamic allocation changes the traffic allocation. This is because in bucketing mode, the assignment is made on the local device, so changing campaign allocation on the platform could cause visitors to see different campaigns.

* **Handle offline mode on client side :**

When the cache is enabled, the SDK attempts to retrieve the latest visitor data (campaign assignments) from the cache. It also saves all failed hits and visitor exposures to resend them later.

By default, the Flagship JS SDK provides a default cache manager implementation on the client side. However, you can use your own cache manager by implementing the `IVisitorCacheImplementation` and `IHitCacheImplementation` interfaces through the visitorCacheImplementation and hitCacheImplementation properties of the [configuration](#sdk-configuration).

### Visitor Cache

The visitor cache is used to store the visitor data in a database through the `IVisitorCacheImplementation` interface which defines the methods that an object must implement to manager it.

```typescript
interface IVisitorCacheImplementation {
    cacheVisitor(visitorId: string, data: VisitorCacheDTO):Promise<void>
    lookupVisitor(visitorId: string): Promise<VisitorCacheDTO>
    flushVisitor(visitorId: string): Promise<void>
}
```

#### `cacheVisitor` method

This method is invoked when the SDK needs to store visitor information in your database.

* **`public cacheVisitor(visitorId: string, data: object):Promise<void>`**

It accepts 2 arguments :

| Argument  | Type   | Description                                                                                              |
| --------- | ------ | -------------------------------------------------------------------------------------------------------- |
| visitorId | string | The ID of the visitor                                                                                    |
| Data      | object | The visitor data. The object adheres to the structure of the [`VisitorCacheDTO`](#visitorcachedto) type. |

#### `lookupVisitor` method

This method is invoked when the SDK needs to retrieve visitor information associated with a specific visitor ID from your database.

It should return an object of type `VisitorCacheDTO` that adheres to this structure [see](#visitorcachedto).

* **`public lookupVisitor(visitorId: string): Promise<object>`**

It accepts one argument :

| Argument  | Type   | Description |
| --------- | ------ | ----------- |
| visitorId | string | visitor ID  |

#### `flushVisitor` method

This method is invoked when the SDK needs to delete the visitor information associated with a specific visitor ID from your database.

It is invoked every time [`setConsent`](#setconsent-function) is set to false.

* **`public flushVisitor(visitorId: string): Promise<void>`**

It accepts one argument :

| Argument  | Type   | Description           |
| --------- | ------ | --------------------- |
| visitorId | string | The ID of the visitor |

{% hint style="info" %}
📘 Information

* `flushVisitor` method is called every time [`setConsent`](#setconsent-function) is set to false.
  {% endhint %}

#### VisitorCacheDTO

```typescript
type VisitorCacheDTO = {
  version: number;
  data: {
    visitorId: string;
    anonymousId: string | null;
    consent?: boolean;
    context?: Record<string, boolean|number|string>;
    assignmentsHistory?: Record<string, string>;
    campaigns?: Array<{
      campaignId: string;
      variationGroupId: string;
      variationId: string;
      isReference?: boolean;
      type: string;
      activated?: boolean;
      flags?: Record<string, unknown>;
    }>;
  };
};
```

### Hit Cache

The hit cache is used to store hits in your database based on the strategy used through the `IHitCacheImplementation` interface which defines the methods that an object must implement to handle it.

```typescript
interface IHitCacheImplementation {
    cacheHit(hits: Record<string, HitCacheDTO>):Promise<void>
    lookupHits():Promise<Record<string, HitCacheDTO>>
    flushHits(hitKeys: string[]): Promise<void>
    flushAllHits(): Promise<void>
}
```

#### `cacheHit` method

This method is invoked to store hits based on the strategy used.

* **`public cacheHit(hits: Record<string, HitCacheDTO>):Promise<void>`**

It accepts 1 argument :

| Argument | Type   | Description                                                                                                                                                                                          |
| -------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| hits     | object | <p>This is a key/value object where:<br><br>• <strong>key</strong> is a unique ID for each hit<br>• <strong>value</strong> is an object that follows the shape of type <code>HitCacheDTO</code>.</p> |

#### `lookupHits` method

This method is invoked to load all hits from your database and attempt to send them in the background.

It should return an object where the key is a unique ID for each hit, and the value is an object of type `HitCacheDTO` that adheres to this structure [see](#hitCachedto).

* **`public lookupHits():Promise<Record<string, HitCacheDTO>>`**

#### `flushHits` method

This method is invoked to delete all hits that match the unique hit IDs from your database.

**NOTE:** It is called every time [`setConsent`](#setconsent-function) is set to false, erasing all of the visitor's hits from the database.

* **`public flushHits(hitKeys: string[]): Promise<void>`**

It accepts one argument :

| Argument | Type      | Description       |
| -------- | --------- | ----------------- |
| hitKeys  | string\[] | Unique ID of hits |

#### `flushAllHits` function

This method is invoked to delete all hits from your database without exception.

* **`public flushAllHits(): Promise<void>`**

#### HitCacheDTO

```typescript
type HitCacheLookupDTO = {
  version: number;
  data: {
    visitorId: string;
    anonymousId: string | null;
    type: HitType | "ACTIVATE";
    time: number;
    content?: Record<string, unknown>;
  };
};
```

{% hint style="info" %}
📘

* The `flushHits` method is called every time [`setConsent`](#setconsent-function) is set to false.
* `Hits` older than 4H will be ignored during the resending process.
  {% endhint %}

### `IHitCacheImplementation` implementation

#### localStorage

This is an implementation of the `IHitCacheImplementation` interface using `localStorage`.

```typescript
import { Flagship, CacheStrategy } from "@flagship.io/js-sdk";

const FS_HIT_PREFIX = 'FS_DEFAULT_HIT_CACHE'


const hitCacheImplementation = {
  cacheHit (hits) {
    const localDatabaseJson = localStorage.getItem(FS_HIT_PREFIX) || '{}'
    const localDatabase = JSON.parse(localDatabaseJson)

    const newLocalDatabase = {
      ...localDatabase,
      ...hits
    }

    localStorage.setItem(FS_HIT_PREFIX, JSON.stringify(newLocalDatabase))
    return Promise.resolve()
  },
  lookupHits () {
    const localDatabaseJson = localStorage.getItem(FS_HIT_PREFIX) || '{}'
    const localDatabase = JSON.parse(localDatabaseJson)
    return Promise.resolve(localDatabase)
  },
  flushHits (hitKeys) {
    const localDatabaseJson = localStorage.getItem(FS_HIT_PREFIX) || '{}'
    const localDatabase = JSON.parse(localDatabaseJson)

    hitKeys.forEach(key => {
      delete localDatabase[key]
    })

    localStorage.setItem(FS_HIT_PREFIX, JSON.stringify(localDatabase))
    return Promise.resolve()
  },
  flushAllHits () {
    localStorage.removeItem(FS_HIT_PREFIX)
    return Promise.resolve()
  }
}

Flagship.start(ENV_ID, API_KEY, {
  hitCacheImplementation: hitCacheImplementation,
  trackingManagerConfig: {
    batchIntervals: 5,
    poolMaxSize: 10,
    cacheStrategy: CacheStrategy.CONTINUOUS_CACHING
  }
})
```

#### Redis

This is an implementation of the `IHitCacheImplementation` interface using `redis`.

```javascript
import { Flagship, CacheStrategy } from "@flagship.io/js-sdk";
import Redis from 'ioredis'

function hitCacheImplementation (host, port, dbIndex) {
  const redis = new Redis({
    host,
    port
  })

  redis.select(dbIndex)

  return {

    async cacheHit (hits) {
      const multi = redis.multi()
      Object.entries(hits).forEach(([key, value]) => {
        multi.set(key, JSON.stringify(value))
      })
      await multi.exec()
    },
    async lookupHits () {
      const hits:Record<string, HitCacheDTO> = {}
      const keys = await redis.keys('*')
      if (!keys.length) {
        return hits
      }
      const redisData = await redis.mget(keys)

      redisData.forEach((value, index) => {
        if (!value) {
          return
        }
        hits[keys[index]] = JSON.parse(value)
      })
      return hits
    },
    async flushHits (hitKeys) {
      await redis.del(hitKeys)
    },

    async flushAllHits () {
      const keys = await redis.keys('*')
      if (!keys.length) {
        return
      }
      await redis.del(keys)
    }
  }
}

Flagship.start(ENV_ID, API_KEY, {
  hitCacheImplementation:hitCacheImplementation('127.0.0.1', '6379', 2),
  trackingManagerConfig: {
    batchIntervals: 10,
    poolMaxSize: 100,
    cacheStrategy: CacheStrategy.PERIODIC_CACHING
  }
})
```

In the LocalStorage implementation, the `localStorage` web API is used to store, retrieve, and delete hits. In the Redis implementation, the `ioredis` library is used to interact with a Redis database for the same purposes. Both implementations are passed to the `Flagship.start` method as part of the configuration object.

\\

## Predefined visitor context keys

The Flagship SDK contains predefined visitor context keys.

The keys marked as **Yes** in the **Auto-set by SDK** column will be automatically set, while the ones marked as **No** need to be set by customer.

All possible predefined keys are listed below:

| SDK constant Name    | Description                                            | Context variable name   | Type       | Auto-set by SDK | Example         |
| -------------------- | ------------------------------------------------------ | ----------------------- | ---------- | --------------- | --------------- |
| DEVICE\_LOCALE       | Language of the device                                 | sdk\_deviceLanguage     | String     | No              | fr              |
| DEVICE\_TYPE         | Type of the device                                     | sdk\_deviceType         | DeviceType | No              | Mobile          |
| DEVICE\_MODEL        | Model of the device                                    | sdk\_deviceModel        | String     | No              | samsung E1200   |
| LOCATION\_CITY       | City geolocation                                       | sdk\_city               | String     | No              | toulouse        |
| LOCATION\_REGION     | Region geolocation                                     | sdk\_region             | String     | No              | occitanie       |
| LOCATION\_COUNTRY    | Country geolocation                                    | sdk\_country            | String     | No              | France          |
| LOCATION\_LAT        | Current Latitude                                       | sdk\_lat                | Double     | No              | 43.623647       |
| LOCATION\_LONG       | Current Longitude                                      | sdk\_long               | Double     | No              | 1.445397        |
| OS\_NAME             | Name of the OS                                         | sdk\_osName             | String     | YES             | ubuntu / centos |
| OS\_VERSION\_NAME    | Version name of the OS                                 | sdk\_osVersionName      | String     | No              | 9.0.0           |
| OS\_VERSION\_CODE    | Version code of the OS                                 | sdk\_osVersionCode      | Number     | No              | 24              |
| CARRIER\_NAME        | Name of the carrier or mobile virtual network operator | sdk\_carrierName        | String     | No              | free            |
| INTERNET\_CONNECTION | What is the internet connection                        | sdk\_internetConnection | String     | No              | 5g              |
| APP\_VERSION\_NAME   | Version name of the app                                | sdk\_versionName        | String     | No              | 1.1.2-beta      |
| APP\_VERSION\_CODE   | Version code of the app                                | sdk\_versionCode        | Number     | No              | 40              |
| INTERFACE\_NAME      | Name of the interface                                  | sdk\_interfaceName      | String     | No              | ProductPage     |
| FLAGSHIP\_CLIENT     | Flagship SDK client (Reserved)                         | fs\_client              | String     | Yes             | TS              |
| FLAGSHIP\_VERSION    | Version of the Flagship SDK (Reserved)                 | fs\_version             | String     | Yes             | 4.0.0           |
| FLAGSHIP\_VISITOR    | Current visitor id (Reserved)                          | fs\_users               | String     | Yes             | visitor\_id     |

{% hint style="info" %}
📘 Information

To overwrite the keys, use the [`updateContext`](#updatecontext-method) method
{% endhint %}
