# v3.2.X

## JavaScript, Node, Deno V3.2.X

### Introduction

#### SDK overview

Welcome to the Flagship JavaScript / TypeScript / NodeJS & Deno SDK documentation!

The following article will guide you through the steps to get Flagship up and running on your JavaScript environment (client-side or server-side) using our library with preconfigured methods to implement the Decision API or Bucketing Mode.

#### SDK features

That SDK version helps you :

* Set a visitor ID
* Update visitor context
* Assign campaigns via the Decision API or via Bucketing Mode
* Get flag
* Manage visitor consent
* Use Experience Continuity
* Activate campaigns
* Send hits to our Universal Collect
* Manage visitor cache

### Prerequisites

| NodeJS                                                                                                                                                                         | Deno                                                                                                              |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| <p>- Your server/device must have an access to the internet.<br><br>\* <strong>Node.js</strong>: version 6.0.0 or later<br>\* <strong>NPM</strong>: version 3.0.0 or later</p> | <p>- Your server/device must have an access to the internet.<br><br>\* <strong>Deno</strong>: 1.10.3 or later</p> |

### Good to know

| NodeJS                                                                                                                                                                                                                                                                                                                       | Deno                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| <p>- Github repository: <a href="https://github.com/flagship-io/flagship-ts-sdk"><https://github.com/flagship-io/flagship-ts-sdk></a><br><br>\* <a href="https://bundlephobia.com/result?p=@flagship.io/js-sdk">Gzipped size: \~18.9kB</a><br>\* SDK runs on both Client and Server-side<br>\* Typescript code supported</p> | <p>- Github repository: <a href="https://github.com/flagship-io/flagship-ts-sdk"><https://github.com/flagship-io/flagship-ts-sdk></a><br><br>\* Deno land: <a href="https://deno.land/x/flagship_io_js_sdk"><https://deno.land/x/flagship_io_js_sdk></a></p> |

> 📘 Javascript SDK - Engine compatibility
>
> Our Javascript SDK is compatible with :
>
> * V8 Engine
> * Node.js runtime
> * Deno

### Getting Started

#### Installation

**NodeJS**

The SDK can be added as dependency via [NPM](https://www.npmjs.com/package/@flagship.io/js-sdk) or [YARN](https://yarn.pm/@flagship.io/js-sdk)

```shell
yarn add @flagship.io/js-sdk
```

```shell
npm install @flagship.io/js-sdk
```

**Deno**

Deno supports 2 methods:

* URLs for dependency management, so you just need to add the deno.land URL

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

* and [import maps](https://github.com/WICG/import-maps)

```json
{
   "imports": {
      "@flagship.io/js-sdk": "https://deno.land/x/flagship_io_js_sdk/mod.ts"
   }
}
```

| JavaScript & NodeJS                                                                                                                                                                                                                                      | Deno                                                                                                                                                                                                                                                                                          |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| To initialize and start the SDK, import the `Flagship` class from `@flagship.io/js-sdk` package then simply call the static function `start`. It should be better to call this function just once in the most appropriate location for your application. | To initialize and start the SDK, import the `Flagship` class from [flagship deno land repos](https://deno.land/x/flagship_io_js_sdk) then simply call the static function `start`. It should be better to call this function just once in the most appropriate location for your application. |

#### Initialization

The first step to use the SDK is to create an instance of Flagship that defines your Flagship account and targeted environment.\
Here's the simplest way to initialize Flagship, including the import :

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

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

// or

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

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

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

// or

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

**`start` function**

Start the flagship SDK and return the Flagship instance.

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

| Arguments | 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 configuration attribute |

#### Advanced Configuration

Here are all available settings you can set on the SDK.

Those settings can be setup only at the start function.

Here's the full pure example of usage :

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

Flagship.start("<ENV_ID>", "<API_KEY>", {
  decisionMode: DecisionMode.BUCKETING,
  fetchNow: false,
  timeout: 10,
  enableClientCache: true,
  logLevel: LogLevel.CRITICAL,
  logManager: sentryMiddleware,
  decisionApiUrl: 'https://example.com',
  pollingInterval: 100,
  hitDeduplicationTime: 0,
  trackingManagerConfig: {
      cacheStrategy: CacheStrategy.PERIODIC_CACHING,
      poolMaxSize: 10,
      batchIntervals: 100
    },
  initialBucketing: {},
  statusChangedCallback: function(status){
    console.log(status)
  },
  onBucketingSuccess: function(status, payload){
    console.log(status, payload)
  },
  onBucketingFail: function(error){
    console.log(error)
  },
  onBucketingUpdated: function(lastUpdate){
    console.log(lastUpdate)
  },
  onLog: (level, tag, message) => {
    console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
  }
});
```

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

Flagship.start("<ENV_ID>", "<API_KEY>", {
  decisionMode: DecisionMode.BUCKETING,
  fetchNow: false,
  timeout: 10,
  enableClientCache: true,
  logLevel: LogLevel.CRITICAL,
  logManager: sentryMiddleware,
  decisionApiUrl: 'https://example.com',
  pollingInterval: 100,
  activateDeduplicationTime: 0,
  hitDeduplicationTime: 0,
  trackingManagerConfig: {
      cacheStrategy: CacheStrategy.PERIODIC_CACHING,
      poolMaxSize: 10,
      batchIntervals: 100
    },
  initialBucketing: {},
  statusChangedCallback: function(status){
    console.log(status)
  },
  onBucketingSuccess: function(status, payload){
    console.log(status, payload)
  },
  onBucketingFail: function(error){
    console.log(error)
  },
  onBucketingUpdated: function(lastUpdate){
    console.log(lastUpdate)
  },
  onLog: (level, tag, message) => {
    console.log(`[${LogLevel[level]}] [${tag}] : ${message}`);
  }
});
```

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`                                      | Specify the SDK running mode. see `Decision Mode`                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| fetchNow                      | boolean                                                      | true                                                | If it's set to true, it will call automatically fetchFlags when creating a new `Visitor`                                                                                                                                                                                                                                                                                                                                                                                                                    |
| timeout                       | number                                                       | 2                                                   | <p>Specify timeout in seconds for api request.<br><strong>Note:</strong> timeout can't be lower than 0 second.</p>                                                                                                                                                                                                                                                                                                                                                                                          |
| enableClientCache             | boolean                                                      | false                                               | <p>Indicates whether enables or disables the client cache manager.<br>By enabling the client cache, it will allow you to keep cross sessions visitor experience.<br><strong>Note</strong>: The client cache is useful only when you do not specify a visitor id when creating a visitor. From there, you only need to be focus on handling the visitor context and whether he is authenticated or not. That's it.<br><strong>Note2</strong>: Not available on server side, this setting will be ignored</p> |
| logLevel                      | number                                                       | 9                                                   | <p>Set the maximum log level to display<br>see<code>LogLevel</code></p>                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| logManager                    | object                                                       | Defined                                             | <p>Specify a custom implementation of LogManager in order to receive logs from the SDK.<br><strong>Note:</strong> 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                                                       | 1                                                   | <p>Specify delay in seconds between two bucketing polling when SDK is running on Bucketing mode.<br><strong>Note:</strong> If 0 is given, it should poll only once at start time.</p>                                                                                                                                                                                                                                                                                                                       |
| hitDeduplicationTime          | number                                                       | 2.5                                                 | <p>You can specify a 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><strong>Note:</strong> If a value of 0 is given, no deduplication process will be used.</p>                                                                                                                                                                                                                            |
| initialBucketing              | object                                                       | undefined                                           | **Optional**\<br/>You can define an object containing the data received when fetching the bucketing endpoint. Providing this object will make bucketing ready to use and the first polling will immediately check for updates.                                                                                                                                                                                                                                                                              |
| visitorCacheImplementation    | object                                                       | Defined on client side and undefined on server side | **Optional**\<br/>Define an object that implement the interface `visitorCacheImplementation` interface to manage hits cache. see cache-manager                                                                                                                                                                                                                                                                                                                                                              |
| hitCacheImplementation        | object                                                       | Defined on client side and undefined on server side | **Optional**\<br/>You can define an object that implements the `IHitCacheImplementation`, to handle the visitor cache. see cache-manager                                                                                                                                                                                                                                                                                                                                                                    |
| disableCache                  | boolean                                                      | false                                               | if it's set to true, hit cache and visitor cache will be disabled otherwise will be enabled. see cache-manager                                                                                                                                                                                                                                                                                                                                                                                              |
| statusChangedCallback         | function(number):void                                        | undefined                                           | <p><strong>Optional</strong>\<br/>Define a callable in order to get callback when the SDK status has changed.<br>see arguments.</p>                                                                                                                                                                                                                                                                                                                                                                         |
| onBucketingSuccess            | function(object):void                                        | undefined                                           | <p><strong>Optional</strong>\<br/>Define a callable in order to get callback when the first bucketing polling succeed.<br>see arguments</p>                                                                                                                                                                                                                                                                                                                                                                 |
| onBucketingFail               | function(error):void                                         | undefined                                           | <p><strong>Optional</strong>\<br/>Define a callable to get callback when the first bucketing polling failed.<br>see arguments</p>                                                                                                                                                                                                                                                                                                                                                                           |
| onBucketingUpdated            | function(object):void                                        | undefined                                           | <p><strong>Optional</strong>\<br/>Define a callable to get callback each time bucketing data from Flagship has updated.<br>see arguments</p>                                                                                                                                                                                                                                                                                                                                                                |
| onUserExposure `deprecated`   | function(object):void                                        | undefined                                           | <p><strong>Optional</strong><br><br>Define a callable to get callback each time a Flag have been visitor exposed (activation hit has been sent) by SDK\<br/>see arguments<br><br>Note: <code>deprecated</code> use <code>onVisitorExposed</code> instead of</p>                                                                                                                                                                                                                                             |
| onLog                         | function(level: LogLevel, tag: string, message: string):void | undefined                                           | **Optional**\<br/>Define a callable to get a callback whenever the SDK needs to report a log\<br/>see arguments                                                                                                                                                                                                                                                                                                                                                                                             |
| trackingManagerConfig         | object                                                       | defined                                             | Define options to configure hit batching\<br/>trackingManagerConfig                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| onVisitorExposed              | function(object):void                                        | undefined                                           | <p><strong>Optional</strong>\<br/>Define a callable to get callback each time a Flag has been exposed to a visitor (When a flag has been seen by your visitor) and succeeded.<br><br>see arguments</p>                                                                                                                                                                                                                                                                                                      |
| fetchThirdPartyData           | boolean                                                      | false                                               | **Optional**\<br/>**Bucketing mode only**\<br/>If true, will fetch the visitor's segment from [universal data connector](https://developers.abtasty.com/docs/data/universal-data-connector) each time fetchFlags is called and append those segments in the visitor context                                                                                                                                                                                                                                 |
| nextFetchConfig               | object                                                       | { revalidate: 20 }                                  | **Optional**\<br/>In Next.js 13, you can define the time in seconds for storing SDK route cache before revalidation. [learn more](https://nextjs.org/docs/app/building-your-application/data-fetching/caching#per-request-caching)                                                                                                                                                                                                                                                                          |
| fetchFlagsBufferingTime       | number                                                       | 2                                                   | <p><strong>Optional</strong><br><br>You can specify a delay in seconds for fetch flags call buffering. This means that 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>Note:<br><br>\* If a value of 0 is given, no buffering process will be used.<br><br>- If visitor data has changed, the SDK bypass the buffering.</p>                                                          |
| disableDeveloperUsageTracking | boolean                                                      | false                                               | <p>The SDK will collect <code>usage data</code> to help us improve our product<br><br>if set true no <code>usage data</code> will be collected</p>                                                                                                                                                                                                                                                                                                                                                          |

**Decision Mode**

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

When the SDK operates in `API` mode, it uses our [Decision API](https://flagship.readme.io/docs/decision-mode) to manage campaign assignments and validate targeting. In this mode, each time a new Decision is needed, the SDK sends an HTTPS request to the API. This mode is enabled by default for all our SDKs.

**`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://flagship.readme.io/docs/bucketing)

**`BUCKETING_EDGE`Mode**

This mode is recommended in Edge environnements, the SDK must be initialized with the bucketing file and 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://flagship.readme.io/docs/case-study-how-to-use-flagship-in-serverless-edge-services)

`DecisionMode` is an enum defined decision type

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

//const mode = DecisionMode.DECISION_API;
const mode = DecisionMode.BUCKETING;

Flagship.start("<ENV_ID>", "<API_KEY>", {
  decisionMode:mode
});
```

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

//const mode = DecisionMode.DECISION_API;
const mode = DecisionMode.BUCKETING;

Flagship.start("<ENV_ID>", "<API_KEY>", {
  decisionMode:mode
});
```

| 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:level
});
```

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

const level = LogLevel.ERROR;

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

| 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>\* *Note: <em>only for log method</em>*\* see <code>LogLevel</code></p> |

Usage :

```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
});
```

```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,
});
```

**FlagshipStatus**

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

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

const status = FlagshipStatus.READY;
```

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

const status = FlagshipStatus.READY;
```

| Key              | Value | Type | Description                                                                                                             |
| ---------------- | ----- | ---- | ----------------------------------------------------------------------------------------------------------------------- |
| NOT\_INITIALIZED | 0     | int  | It is the default initial status. This status remains until the sdk has been initialized successfully.                  |
| STARTING         | 1     | int  | Flagship SDK is starting.                                                                                               |
| POLLING          | 2     | int  | Flagship SDK has been started successfully but is still polling campaigns.                                              |
| READY\_PANIC\_ON | 3     | int  | Flagship SDK is ready but is running in Panic mode: All features are disabled except the one which refresh this status. |
| READY            | 4     | int  | Flagship SDK is ready to use.                                                                                           |

<br>

**statusChangedCallback**

The `statusChangedCallback` function has one argument

| Argument | Type   | Description                            |
| -------- | ------ | -------------------------------------- |
| status   | number | Status of the SDK. see`FlagshipStatus` |

<br>

**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.                           |

<br>

**onBucketingFail**

The `onBucketingFail` function has one argument

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

<br>

**onBucketingUpdated**

The `onBucketingUpdated` function has one argument

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

**onUserExposure `deprecated`**

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

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

**UserExposureType shape**

```typescript
type UserExposureInfo = {
  flagData: {
    key: string
    value: unknown
    metadata: IFlagMetadata
  },
  visitorData: {
    visitorId: string
    anonymousId: string|null
    context: Record<string, string|number|boolean>
  }
 }
```

| Key/Property | Type   | Description                                                                                                   |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------- |
| flagData     | object | <p>\* *key*\*: flag key<br>\* *value*\*: flag value<br>\* *metadata*\*: Campaign information metadata see</p> |
| visitorData  | object | <p>\* *visitorId*\*: visitor id<br>\* *anonomousId*\*: anonymous id<br>\* *context*\*: visitor context</p>    |

<br>

**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 | This object represent the exposed flag.\<br/>(The flag that has triggered the exposure) |

**exposedVisitor** object shape

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

\
**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 |

<br>

Here is an example on how to use this callback:

[Example with Mixpanel integration](https://docs.developers.flagship.io/docs/integrate-with-mixpanel)\
[Example with Segment integration](https://docs.developers.flagship.io/docs/integrate-with-segmentcom)

Learn more about getting flags

<br>

**onLog**

The `onLog` function has 3 arguments

| Argument | Type   | Description                             |
| -------- | ------ | --------------------------------------- |
| level    | number | Get the log level. see `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}`);
  }
});
```

**trackingManagerConfig**

The SDK features a batching system for sending hits, which can be configured using three options: `CacheStrategy`, `PoolMaxSize`, and `BatchIntervals`. Using the TrackingManager’s batch processing reduces network traffic, prevents hit loss through caching, and resends any failed hits.

Hits are first added to an internal pool as they are emitted by visitors. The pool is then emptied by batching all hits and sending them when either the PoolMaxSize is reached or the BatchIntervals timer is triggered. If a batch fails, all hits within it are returned to the pool for future iteration and the cache is updated based on the selected cache strategy.

**Note:** At any time, when your app is about to **close** or **crash**, you should call `Flagship.close()` to batch and send all hits that are in the pool.

**options:**

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

<br>

**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 and added into the pool, then after batching and sending, it will also be flushed from database using IHitCacheImplementation.<br><br>\* *Note*\*: the SDK has a default cache implementation for browser using <code>localStorage</code><br>\* *Note*\*: recommended for client side applications<br><br>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>\* *Note*\*: recommended for server-side applications<br><br>see example using redis</p>                                                                                                                        |

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


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

<br>

> 📘
>
> * The `CONTINUOUS_CACHING strategy` (`recommended for client side apps`) should be used when your application is running in an environment where the probability of data loss is high.\
>   For example in a browser, a visitor can at any time reload the page and erase all data in memory.
>
> Keep in mind that this strategy can do a lot of database I/O depending on how many hits your visitor can send.
>
> * The `PERIODIC_CACHING strategy` (`recommended for server side apps`) should be used when your application sends a lot of hits and the probability of data loss is low.
>
> In this strategy, the number of I/Os in the database is low.

\ <br>

#### Other `Flagship` class methods

**`getStatus` function**

Return current status of Flagship SDK. see`FlagshipStatus`

* **`getStatus (): FlagshipStatus`**
* **`static getStatus (): FlagshipStatus`**

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

const fsInstance = Flagship.start("<ENV_ID>", "<API_KEY>");
const status = fsInstance.getStatus();

//or

const status = Flagship.getStatus();
```

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

const fsInstance = Flagship.start("<ENV_ID>", "<API_KEY>");
const status = fsInstance.getStatus();

//or

const status = Flagship.getStatus();
```

<br>

**`getConfig` function**

Return the current config used by the SDK. see configuration attribute

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

<br>

**`getVisitor` function**

Return the last visitor created and saved or return undefined if no visitor has been saved. see newVisitor.

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

\
\&#xNAN;**`close` function**

Most of the time you don't need to manually close the SDK, but when your application is about to terminate, you should call the `close` method of the Flagship class to avoid data loss.

When called, it will batch and send all hits that are in the pool before the application is closed

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

\ <br>

### Create a visitor

The `Visitor` instance is an object that contains everything related to your visitor, its data but also the Decision of Flagship.

By creating a new visitor, you be able to set all the data relevant for Flagship to take a Decision and know your visitor, this includes :

* Visitor ID
* Visitor Context
* GDPR Consent
* Authenticated or not (See Experience Continuity Feature)

The visitor context is a dataset (object) that defines your current visitor.\
This dataset is sent to Flagship for targeting purposes (use-case assignment) but also to enrich your reporting with Context Filters.\
You may have to sync with your team to know what data is useful for them to have into Flagship reporting.

By default, depending on `IFlagshipConfig`, this will automatically trigger a Decision of Flagship and will be available through the getFlag method

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

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

const fsVisitor = fsInstance.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});

// or 

const fsVisitor = Flagship.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});
```

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

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

const fsVisitor = fsInstance.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});

// or 

const fsVisitor = Flagship.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});
```

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

const fsInstance = Flagship.start("<ENV_ID>", "<API_KEY>", {
  fetchNow: false // Will no longer call the DecisionAPI right after creating a visitor
});

const fsVisitor = fsInstance.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});

// or 

const fsVisitor = Flagship.newVisitor({
  visitorId: "<VISITOR_ID>",
  context: {
   // <CONTEXT_KEY>: <CONTEXT_KEY>,
  }
});

// DO THINGS ...

await fsVisitor.fetchFlags() 
```

**Let's take an example:**\
if you want to enable a specific feature to all your `VIPs` visitor,\
you'll need to add this data as an attribute into the visitor context (key-value pair) in the visitor context: `isVIP: true`.\
Based on your targeting criteria defined in your use-case (`isVIP === true`), Flagship will take the Decision and show your feature to visitors that at least contains `isVIP` in their context and for which `isVIP` is equal to `true`.

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

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

const fsVisitor = fsInstance.newVisitor({
  visitorId: "<VISITOR_ID>",
  isAuthenticated: true,
  hasConsented: true,
  context: {
    isVIP: true,
    country: "NL",
    loginProvider: "Google"
  }
});
```

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

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

const fsVisitor = fsInstance.newVisitor({
  visitorId: "<VISITOR_ID>",
  isAuthenticated: true,
  hasConsented: true,
  context: {
    isVIP: true,
    country: "NL",
    loginProvider: "Google"
  }
});
```

**`newVisitor` function**

Creates and returns a new `Visitor` or `null` if the SDK hasn't started successfully.

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

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

This method has only one argument with the following shape:

| Key/Property     | Type                                                    | Default                                           | Description                                                                                                                                                                                                                                                                                                                             |
| ---------------- | ------------------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visitorId        | string                                                  | `undefined`                                       | <p>\* *<em>Optional</em>*\* - Unique visitor identifier.<br>\* *Note:*\* It will be generated if not set<br>\* *NOTE 2*\*: In client side if you do not specify a value, the id will be either automatically generated or will be the visitor id from previous session (if <code>enableClientCache</code> equals <code>true</code>.</p> |
| isAuthenticated  | boolean                                                 | `false`                                           | Specify if the visitor is authenticated or anonymous for Experience continuity.                                                                                                                                                                                                                                                         |
| hasConsented     | boolean                                                 | `true`                                            | Specify if visitor has consented for protected data usage.                                                                                                                                                                                                                                                                              |
| context          | object `{ [key: string]: string \| number \| boolean }` | `{}`                                              | Initial visitor context.                                                                                                                                                                                                                                                                                                                |
| isNewInstance    | boolean                                                 | `true` on server-side\<br/>`false` on client-side | <p>If true The newly created visitor instance won't be saved and will simply be returned otherwise the newly created visitor instance will be returned and saved into the Flagship instance.<br><br>\* *Note:*\* will be default true on server-side and false on client-side</p>                                                       |
| initialCampaigns | object                                                  | `undefined`                                       | \* \**Optional*\*\* - This is an object of the data received when fetching the Flagship decision API (decisionMode="API").\<br/> Providing this property avoid the SDK to have an empty cache during first initialization.                                                                                                              |
| initialFlagsData | array                                                   | `undefined`                                       | \* \**Optional*\*\* - This is a set of flag data provided to avoid the SDK to have an empty cache during the first initialization.                                                                                                                                                                                                      |

<br>

**Flag data shape:**

| Key\Property       | 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   |
| value              | any     | Value of flag                            |

<br>

> 🚧
>
> * When both initialCampaigns and initialFlags are provided, only initialFlags will be used.
> * 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**

### Updating the visitor context

<br>

The visitor context is a property dataset that defines the current visitor of your app. This dataset is sent and used as targeting criteria for campaign assignment.

The following method from the `Visitor` instance allows you to set new context values matching the given keys.

```typescript
//... import code

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

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

visitor.updateContext({ lastPurchaseDate: 1615384464 });
```

**`updateContext` function**

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`**

It has one argument :

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

<br>

**`context` property**

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

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

**`clearContext` function**

Clear the actual visitor context

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

> 🚧
>
> * 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**

#### update context with predefined keys of context

```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",
});
```

```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",
});
```

**Learn more** about predefined keys of context

\ <br>

### Managing visitor campaigns

<br>

#### Fetching Flags

The `fetchFlags()` method of the `Visitor` instance, according to **Decision Mode**, will either automatically call the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags,\
or check `bucketing file`, validate campaigns targeting the visitor, assign a variation and retrieve applicable flags

These flags are then stored in the SDK and updated asynchronously when `fetchFlags()` is called.

<br>

```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
});
```

<br>

**`fetchFlags` function**

In DecisionApi Mode this function calls the Flagship Decision API to run campaign assignments according to the current visitor context and retrieve applicable flags.

In bucketing Mode, it checks bucketing file, validates campaigns targeting the visitor, assigns a variation and retrieve applicable flags

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

<br>

#### Event listeners

The `Visitor` instance includes event listeners to help you handle the SDK.

| Event listener | Description                                                                                                                                                      |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ready          | <p>Once it's called, you are ready to use all features from the SDK.<br><strong>Note:</strong> It'll be called each time fetchFlags has updated stored flags</p> |

> ❗️
>
> Before using any function from `Visitor`, it is important to follow one of the 3 ways describe below to ensure everything is working properly and your visitor is up to date with campaigns assignment.

<br>

#### Getting flags

Once the campaign has been **assigned** and **fetched**, all the flags are stored in the SDK. You can retrieve them using the `fetchFlags` functions from the `Visitor` instance.

There are 3 ways to be ready to use your flags:

* With event listerner
* With await statement
* With then function

<br>

```typescript
//...import code

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

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

visitor.on("ready",  (error) => {
  if (error) {
    //do some stuff
    return;
  }

  //Get flag displayVipFeature
  const flag = visitor.getFlag("displayVipFeature", false);

  //do some stuff
});

visitor.fetchFlags();
```

```typescript
//...import code

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

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

await visitor.fetchFlags();

// Get flag displayVipFeature
const flag = visitor.getFlag("displayVipFeature", false);
```

```typescript
//...import code

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

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

visitor.fetchFlags().then(()=>{
  // Get flag displayVipFeature
  const flag = visitor.getFlag("displayVipFeature", false);
});
```

<br>

**`getFlag` function**

Return a Flag object by its key. If no flag match the given key an empty flag will be returned. Call exists() to check if the flag has been found.

* **`getFlag<T>(key:string, defaultValue: T):IFlag<T>`**

<br>

| Argument     | Type   | Description                 |
| ------------ | ------ | --------------------------- |
| key          | String | key associated to the flag. |
| defaultValue | T      | flag default value.         |

> 🚧
>
> * Default value must be one of the following type : `string`, `number`, `boolean`, `object`, `array` or `null`.
> * When the defaultValue is `null`, no type checking will be performed

<br>

#### Getting flags current values

**`getValue` function**

To retrieve flag current value, simply call getValue() method of the Flag object.

```typescript
//...import code

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

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

visitor.on("ready", (error) => {
  if (error) {
    //do some stuff
    return;
  }

  //Get flag displayVipFeature
  const flagValue = visitor.getFlag("displayVipFeature", false).getValue();

  //do some stuff
});

visitor.fetchFlags();
```

* **`getValue(visitorExposed : boolean) : T`** function

Returns the value from the assigned campaign variation or the Flag default value if the Flag does not exist, or if types are different.

| Parameter      | Type    | Default Value | Description                                                                                                                                                                                                                                                                         |
| -------------- | ------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| visitorExposed | Boolean | true          | Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting.\<br/>If needed it is possible to set this param to false and call `visitorExposed()` afterward when the visitor sees it. |

<br>

#### Getting flags campaigns metadata

**`metadata` property**

You may need to send campaign IDs or variation IDs to a third party for reporting and/or analytics purposes. It is possible to retrieve campaigns metadata for a specific Flag.

<br>

```typescript
//...import code

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

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

visitor.on("ready", (error) => {
  if (error) {
    //do some stuff
    return;
  }

  //Get flag displayVipFeature
  const campaignMetada = visitor.getFlag("displayVipFeature", false).metadata;

  //do some stuff
});

visitor.fetchFlags();
```

* **`metadata:IFlagMetadata`**

Return the campaign information metadata or an empty object if the Flag doesn't exist or if the default value type does not correspond to the Flag type in Flagship.

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

| Key\Property       | 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                            |

#### Report a Flag exposure

**`visitorExposed` function**

By default when the method getValue() is called, The SDK considers that the visitor have seen the effets of your Flag, unless you pass false to getValue(). In this case you will have to call visitorExposed().

There are two ways for exposing a visitor to a flag:

1. Pass an `visitorExposed=true` parameter to the **getValue()** method.
2. Use the following **visitorExposed()** method from the Flag instance.

<br>

```typescript
//...import code

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

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

visitor.on("ready", (error) => {
  if (error) {
    //do some stuff
    return;
  }

  //Get flag displayVipFeature
  const flag = visitor.getFlag("displayVipFeature", false);
  const value = flag.getValue(false);
  
  //Report a flag exposure
  flag.visitorExposed();

  //do some stuff
});

visitor.fetchFlags();
```

<br>

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

Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No visitor exposure will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

\ <br>

* **`userExposed(): Promise<void>`** `deprecated`

Tells Flagship the visitor have been exposed and have seen this flag. This will increment the visits for the current variation on your campaign reporting. No visitor exposure will be sent if the Flag doesn't exist or if the default value type do not correspond to the Flag type in Flagship.

> 🚧
>
> `userExposed` is deprecated, use `visitorExposed` instead

<br>

#### Check if a Flag exists

**`exists` function**

This method will return true if a Flag exists in Flagship

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

```typescript
//...import code

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

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

visitor.on("ready", (error) => {
  if (error) {
    //do some stuff
    return;
  }

  const isDisplayVipFeature = visitor.getFlag("displayVipFeature", false).exists();

  //do some stuff
});

visitor.fetchFlags();
```

\ <br>

### Managing visitor consent

The `Visitor` class provides a method to let you manage visitor consent for data privacy usage. When False, ***campaign activation*** and ***hits*** will be disabled.\
There are 2 ways to set visitor consent :

1. Set `hasConsented` key to true when creating a new visitor
2. Use `setConsent` method of visitor instance

<br>

```typescript
//... import code

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

const visitor = Flagship.newVisitor({
  visitorId: "your_visitor_id",
  hasConsented: true, // set hasConsented to true
  context: { isVip: true },
});

// or use setConsent method
visitor.setConsent(true);
```

<br>

**`setConsent` function**

Set if visitor has consented for protected data usage.

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

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

<br>

**`hasConsented` property**

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

* **`hasConsented: boolean`**

> 📘
>
> 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.

\ <br>

### Experience Continuity

Dealing with anonymous and logged-in visitors, Experience continuity allows you to maintain consistency between sessions and devices.

> 🚧
>
> Make sure that the Experience continuity option is enabled on the Flagship platform before using those methods.

#### Authenticate

There are 2 ways to authenticate a visitor:

1. Set key isAuthenticated to true when creating a new visitor
2. Use authenticate method of `Visitor` instance

Authenticate anonymous visitor

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

| Argument  | Type   | Default  | Description                          |
| --------- | ------ | -------- | ------------------------------------ |
| visitorId | string | required | id of the new authenticated visitor. |

> 🚧
>
> Because we have changed the visitor data, we have to call the **fetchFlags method** after calling this one to update the decision from Flagship.
>
> The targeting / Flags could be different for the visitor.

<br>

#### Unauthenticate

This function change authenticated Visitor to anonymous visitor

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

> 🚧
>
> Because we have changed the visitor datas, we have to call the **fetchFlags method** after calling this one to update the decision from Flagship.
>
> The targeting / Flags could be different for the visitor.

#### Code example

Let's assume basic scenario to understand how things work:

**1. Your visitor arrives on your app for the first time.**

We need to initialize the visitor but as we don't know anything about this visitor, we'll create a random visitor id or let the SDK do it for us. You can also specify some visitor context if necessary.

```typescript
const visitor = Flagship.newVisitor({
  context: { key: "value" }
});
```

Here we don't set visitorId property so the SDK has auto-created an id for our visitor.

Regardless of how it has been set, the actual visitor id will be what we call the **anonymous id**.

**2. Your visitor is signing in.**

To tell the SDK about this status modification, you'll have to call the authenticate function which takes the required visitor id as argument.

```typescript
// Example 
// You fetch the visitor_id from your DB
// let visitorId = db.getVisitorId();

visitor.authenticate(visitorId);

// Since your visitor has changed (is now logged-in)
// You have to check if the proper targeting and flags are set

visitor.fetchFlags()
```

The visitor is updated as authenticated, keeping the previous variations from campaigns that are still matched and thus gives you same flags as before being logged in.

> 📘
>
> Keep in mind that if the visitor also has its context changed, you might still have changes on flags as your visitor might target new campaigns.

**3. Your visitor decides to sign out.**

If you want to keep the same visitor experience, then you should do:

```typescript
visitor.unauthenticate();

// Since your visitor has changed (is now logged-out)
// You have to check if the proper targeting and flags are set

visitor.fetchFlags();
```

#### Final implementation example

```typescript
// Create a visitor 

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

// Call the authenticate function

visitor.authenticate(visitorId);

// Fetch the flags to update the visitor decision

visitor.fetchFlags();

// ... Do things ....

// If you want to unauthenticate the visitor 

visitor.unauthenticate();

// Fetch the flags to update the visitor decision

visitor.fetchFlags();
```

### Other visitor instance member

**`getFlagsDataArray` function**

Return an array of all flags data fetched for the current visitor.

* **`getFlagsDataArray():FlagDTO[]`**

<br>

**`getAllFlagsData` function**

The `getAllFlagsData` method returns a `Promise<object>` containing all the data for all the campaigns associated with the current visitor.

The object resolved by the promise has the same shape as the [Decision API response (normal mode)](https://flagship.readme.io/docs/decision-api#mode).

* **`getAllFlagsData(activate : boolean) : Promise<{ visitorId: string; campaigns: CampaignDTO[];}>`**

The function takes the following arguments:

| Attribute | Type    | Default | Description                                                                                                                                   |
| --------- | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| activate  | boolean | false   | Enables modifications while getting them. NOTE: If modifications have already been retrieved, the activation will be sent in another request. |

<br>

**`getFlagsDataForCampaign` function**

Useful to request the data for a specific campaign.

* **`getModificationsForCampaign(campaignId: string, activate: boolean): Promise<{visitorId: string; campaigns: CampaignDTO[];}>;`**

The function takes the following arguments:

| Attribute  | Type    | Default  | Description                                                                                                                                   |
| ---------- | ------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| campaignId | string  | Required | Identifies the campaign whose modifications you want to retrieve. \*\*[See description](https://flagship.readme.io/docs/glossary#campaign-id) |
| activate   | boolean | false    | Enables modifications while getting them. NOTE: If modifications have already been retrieved, the activation will be sent in another request. |

\ <br>

### Hit Tracking

<br>

This section helps you track your visitors in your application and learn how to build hits in order to feed your reports. For more information about our measurement protocol, read our [Universal Collect documentation](https://flagship.readme.io/docs/universal-collect-documentation).

There are five different types of Hits available:

* Page
* Screen
* Transaction
* Item
* Event

**HitType**

**They must all be built and sent with the following function from the`Visitor` instance:**

<br>

| Key         | type   | Value       | Description                         |
| ----------- | ------ | ----------- | ----------------------------------- |
| PAGE        | string | PAGEVIEW    | Visitor has seen a URL.             |
| SCREEN      | string | SCREENVIEW  | Visitor has seen a screen.          |
| TRANSACTION | string | TRANSACTION | Visitor has made a transaction.     |
| ITEM        | string | ITEM        | Item bought in a transaction.       |
| EVENT       | string | EVENT       | Visitor has made a specific action. |

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

const page = HitType.PAGE;
```

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

const page = HitType.PAGE;
```

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

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

const visitor = Flagship.newVisitor({
  visitorId: "your_visitor_id",
  hasConsented: true, // set hasConsented to true
  context: { isVip: true },
});

visitor.sendHit({
  type: HitType.PAGE,
  documentLocation: "https://localhost",
});

//or

visitor.sendHits([
  {
    type: HitType.PAGE,
    documentLocation: "https://localhost",
  },
  {
    type: HitType.SCREEN,
    documentLocation: "home",
  },
]);
```

<br>

```typescript
import { Flagship, HitType } 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",
  hasConsented: true, // set hasConsented to true
  context: { isVip: true },
});

visitor.sendHit({
  type: HitType.PAGE,
  documentLocation: "https://localhost",
});

//or

visitor.sendHits([
  {
    type: HitType.PAGE,
    documentLocation: "https://localhost",
  },
  {
    type: HitType.SCREEN,
    documentLocation: "home",
  },
]);
```

\
\&#xNAN;**`sendHit` function**

Send Hit to Flagship servers for reporting.

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

| Parameter | Type   | Default  | Description          |
| --------- | ------ | -------- | -------------------- |
| hit       | object | required | Hit to send. see Hit |

<br>

**`sendHits` function**

Send Hits to 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 |

\
Hit common optional parameters

<br>

```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",
});
```

```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",
});
```

<br>

<br>

#### Page

<br>

This hit should be sent each time a visitor arrives on a new page.

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

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

```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",
});
```

<br>

* A hit of type `Page` has this following structure:

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

#### Screen

<br>

This hit should be sent each time a visitor arrives on an interface on client side.

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

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

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

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

<br>

* A hit of type `Screen` has this following structure:

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

Transaction

<br>

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

```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",
});
```

```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",
});
```

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

| Key/Property   | Type                   | Default  | Description                                                                                                             |
| -------------- | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| type           | string (`TRANSACTION`) | required | Type of hit. see 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**                                            |
| totalRevenue   | float                  | optional | Specifies the total revenue associated with the transaction. This value should include 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

<br>

This hit is used to link an item with a transaction. It must be sent after the corresponding transaction hit.

```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",
});
```

```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",
});
```

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

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

<br>

> 📘
>
> The `Item` hit isn't available yet in the Flagship reporting view.

<br>

#### Event

This hit can be used for any event (e.g. Add To Cart click, newsletter subscription).

<br>

```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,
});
```

```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,
});
```

<br>

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

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

\ <br>

### Managing visitor cache

The aims of the cache management is the response to the following problematic:

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

In bucketing mode, the SDK will always keep visitor in variation where he was allocated first, in case of the customer or the dynamic allocation has changed the traffic allocation. Indeed in bucketing mode the assignation is made on local device so changing campaign allocation in the platform would make the visitors see different campaigns.

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

With the cache enabled, the SDK will try to retrieve the latest visitor data (campaign assignations) from the cache, also will save all the failed hits and visitorExposed in order to resend them later.

<br>

By default the Flagship JS SDK provide a default cache manager implementation on client side. It is possible to use your own cache manager by implementing the intefaces `IVisitorCacheImplementation` and `IHitCacheImplementation` through visitorCacheImplementation and hitCacheImplementation properties of 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 in order to handle it.

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

<br>

**`cacheVisitor` function**

This method is called when the SDK needs to cache visitor information in your database.

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

It has 2 arguments :

| Argument  | Type   | Description                                                           |
| --------- | ------ | --------------------------------------------------------------------- |
| visitorId | string | visitor ID                                                            |
| Data      | object | visitor data. The object follows the shape of type `VisitorCacheDTO`. |

<br>

**`lookupVisitor` function**

This method is called when the SDK needs to get the visitor information corresponding to visitor ID from your database.

It has to return an object of type `VisitorCacheDTO` which follows this shape see.

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

It has one argument :

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

**`flushVisitor` function**

This method is called when the SDK needs to erase the visitor information corresponding to visitor ID in your database.

It will be called every time `setConsent` get false.

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

It has one argument :

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

<br>

> 📘
>
> * `flushVisitor` method will be called every time `setConsent` get false.

<br>

**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 depending on 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>
}
```

<br>

**`cacheHit` function**

This method will be called to cache hits depending on cache strategy used.

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

It has 1 argument :

```
  <th style={{ textAlign: "left" }}>
    Type
  </th>

  <th style={{ textAlign: "left" }}>
    Description
  </th>
</tr>
```

```
  <td style={{ textAlign: "left" }}>
    object
  </td>

  <td style={{ textAlign: "left" }}>
    It's a key/value object where the :

    * key  is a unique ID for each hit
    * value is an object that follows the shape of type [`HitCacheDTO`](#hitCachedto).
  </td>
</tr>
```

| Argument |
| -------- |
| hits     |

<br>

**`lookupHits` function**

This method will be called to load all hits from your database and trying to send them again in the background.

It has to return an object where the key is a unique ID for each hit and the value is an object of type `HitCacheDTO` which follows this shape see.

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

<br>

**`flushHits` function**

This method will be called to erase all hits matching the unique Hits ID from your database.

**NOTE:** It will be called every time `setConsent` get false to erase all hits from database for visitor who set consent to false.

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

It has one argument :

| Argument | Type           | Description       |
| -------- | -------------- | ----------------- |
| hitKeys  | Array\<string> | Unique ID of hits |

<br>

**`flushAllHits` function**

This method will be called to erase all hits in your database without exception.

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

<br>

**HitCacheDTO**

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

<br>

> 📘
>
> * `flushHits` method will be called every time `setConsent` get false.
> * `Hits` older than 4H will be ignored during the resending process.

<br>

**`IHitCacheImplementation` implementation**

**localStorage**

Implementation of `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
  }
})
```

<br>

**Redis**

Implementation of `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
  }
})
```

\ <br>

### API reference

#### `Flagship` class

* start
* newVisitor
* getStatus
* getConfig
* getVisitor
* close

#### `Visitor` class

* updateContext
* context
* clearContext
* fetchFlags
* getFlagsDataArray
* getAllFlagsData
* getFlagsDataForCampaign
* Event listeners
* getFlag
* setConsent
* hasConsented
* Authenticate
* Unauthenticate
* sendHit
* sendHits

#### `Flag` class

* getValue
* metadata
* userexposed
* visitorexposed
* exists

<br>

### Appendix

#### 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.

You can overwrite these keys at any time. The keys-value pairs will be sent to the server in the visitor context and can be edited in the Persona section of the Flagship platform.

| SDK constant Name    | Description                                            | Context variable name   | Type       | Auto-set by SDK | Example         |
| -------------------- | ------------------------------------------------------ | ----------------------- | ---------- | --------------- | --------------- |
| DEVICE\_LOCALE       | Language of the device                                 | sdk\_deviceLanguage     | String     | No              | fra             |
| 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             | 2.0.0           |
| FLAGSHIP\_VISITOR    | Current visitor id (Reserved)                          | fs\_users               | String     | Yes             | visitor\_id     |

> 📘
>
> To overwrite the keys, use the `updateContext` method

<br>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.abtasty.com/server-side/sdks/js-sdk/archived-versions/archived-javascript-node-deno-v3-2-x.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
