@mparticle/web-sdk 2.25.3 → 2.26.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/mparticle.js CHANGED
@@ -608,7 +608,7 @@ var mParticle = (function () {
608
608
  Environment: Environment
609
609
  };
610
610
 
611
- var version = "2.25.3";
611
+ var version = "2.26.0";
612
612
 
613
613
  var Constants = {
614
614
  sdkVersion: version,
@@ -633,7 +633,8 @@ var mParticle = (function () {
633
633
  PromotionIdRequired: 'Promotion ID is required',
634
634
  BadAttribute: 'Attribute value cannot be object or array',
635
635
  BadKey: 'Key value cannot be object or array',
636
- BadLogPurchase: 'Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions'
636
+ BadLogPurchase: 'Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions',
637
+ AudienceAPINotEnabled: 'Your workspace is not enabled to retrieve user audiences.'
637
638
  },
638
639
  InformationMessages: {
639
640
  CookieSearch: 'Searching for cookie',
@@ -730,7 +731,8 @@ var mParticle = (function () {
730
731
  v3SecureServiceUrl: 'jssdks.mparticle.com/v3/JS/',
731
732
  configUrl: 'jssdkcdns.mparticle.com/JS/v2/',
732
733
  identityUrl: 'identity.mparticle.com/v1/',
733
- aliasUrl: 'jssdks.mparticle.com/v1/identity/'
734
+ aliasUrl: 'jssdks.mparticle.com/v1/identity/',
735
+ userAudienceUrl: 'nativesdks.mparticle.com/v1/'
734
736
  },
735
737
  Base64CookieKeys: {
736
738
  csm: 1,
@@ -764,7 +766,8 @@ var mParticle = (function () {
764
766
  EventBatchingIntervalMillis: 'eventBatchingIntervalMillis',
765
767
  OfflineStorage: 'offlineStorage',
766
768
  DirectUrlRouting: 'directURLRouting',
767
- CacheIdentity: 'cacheIdentity'
769
+ CacheIdentity: 'cacheIdentity',
770
+ AudienceAPI: 'audienceAPI'
768
771
  },
769
772
  DefaultInstance: 'default_instance',
770
773
  CCPAPurpose: 'data_sale_opt_out',
@@ -1988,6 +1991,76 @@ var mParticle = (function () {
1988
1991
  return SessionStorageVault;
1989
1992
  }(BaseVault);
1990
1993
 
1994
+ var AsyncUploader = /** @class */function () {
1995
+ function AsyncUploader(url) {
1996
+ this.url = url;
1997
+ }
1998
+ return AsyncUploader;
1999
+ }();
2000
+ var FetchUploader = /** @class */function (_super) {
2001
+ __extends(FetchUploader, _super);
2002
+ function FetchUploader() {
2003
+ return _super !== null && _super.apply(this, arguments) || this;
2004
+ }
2005
+ FetchUploader.prototype.upload = function (fetchPayload, _url) {
2006
+ return __awaiter(this, void 0, void 0, function () {
2007
+ var url;
2008
+ return __generator(this, function (_a) {
2009
+ switch (_a.label) {
2010
+ case 0:
2011
+ url = _url || this.url;
2012
+ return [4 /*yield*/, fetch(url, fetchPayload)];
2013
+ case 1:
2014
+ return [2 /*return*/, _a.sent()];
2015
+ }
2016
+ });
2017
+ });
2018
+ };
2019
+ return FetchUploader;
2020
+ }(AsyncUploader);
2021
+ var XHRUploader = /** @class */function (_super) {
2022
+ __extends(XHRUploader, _super);
2023
+ function XHRUploader() {
2024
+ return _super !== null && _super.apply(this, arguments) || this;
2025
+ }
2026
+ XHRUploader.prototype.upload = function (fetchPayload) {
2027
+ return __awaiter(this, void 0, void 0, function () {
2028
+ var response;
2029
+ return __generator(this, function (_a) {
2030
+ switch (_a.label) {
2031
+ case 0:
2032
+ return [4 /*yield*/, this.makeRequest(this.url, fetchPayload.body)];
2033
+ case 1:
2034
+ response = _a.sent();
2035
+ return [2 /*return*/, response];
2036
+ }
2037
+ });
2038
+ });
2039
+ };
2040
+ XHRUploader.prototype.makeRequest = function (url, data) {
2041
+ return __awaiter(this, void 0, void 0, function () {
2042
+ var xhr;
2043
+ return __generator(this, function (_a) {
2044
+ xhr = new XMLHttpRequest();
2045
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2046
+ xhr.onreadystatechange = function () {
2047
+ if (xhr.readyState !== 4) return;
2048
+ // Process the response
2049
+ if (xhr.status >= 200 && xhr.status < 300) {
2050
+ resolve(xhr);
2051
+ } else {
2052
+ reject(xhr);
2053
+ }
2054
+ };
2055
+ xhr.open('post', url);
2056
+ xhr.send(data);
2057
+ })];
2058
+ });
2059
+ });
2060
+ };
2061
+ return XHRUploader;
2062
+ }(AsyncUploader);
2063
+
1991
2064
  /**
1992
2065
  * BatchUploader contains all the logic to store/retrieve events and batches
1993
2066
  * to/from persistence, and upload batches to mParticle.
@@ -2050,6 +2123,7 @@ var mParticle = (function () {
2050
2123
  var _a = this.mpInstance,
2051
2124
  getFeatureFlag = _a._Helpers.getFeatureFlag,
2052
2125
  deviceId = _a._Store.deviceId;
2126
+ // https://go.mparticle.com/work/SQDSDKS-6317
2053
2127
  var offlineStorageFeatureFlagValue = getFeatureFlag(Constants.FeatureFlags.OfflineStorage);
2054
2128
  var offlineStoragePercentage = parseInt(offlineStorageFeatureFlagValue, 10);
2055
2129
  var rampNumber = getRampNumber(deviceId);
@@ -2313,81 +2387,13 @@ var mParticle = (function () {
2313
2387
  BatchUploader.MINIMUM_INTERVAL_MILLIS = 500;
2314
2388
  return BatchUploader;
2315
2389
  }();
2316
- var AsyncUploader = /** @class */function () {
2317
- function AsyncUploader(url) {
2318
- this.url = url;
2319
- }
2320
- return AsyncUploader;
2321
- }();
2322
- var FetchUploader = /** @class */function (_super) {
2323
- __extends(FetchUploader, _super);
2324
- function FetchUploader() {
2325
- return _super !== null && _super.apply(this, arguments) || this;
2326
- }
2327
- FetchUploader.prototype.upload = function (fetchPayload) {
2328
- return __awaiter(this, void 0, void 0, function () {
2329
- var response;
2330
- return __generator(this, function (_a) {
2331
- switch (_a.label) {
2332
- case 0:
2333
- return [4 /*yield*/, fetch(this.url, fetchPayload)];
2334
- case 1:
2335
- response = _a.sent();
2336
- return [2 /*return*/, response];
2337
- }
2338
- });
2339
- });
2340
- };
2341
- return FetchUploader;
2342
- }(AsyncUploader);
2343
- var XHRUploader = /** @class */function (_super) {
2344
- __extends(XHRUploader, _super);
2345
- function XHRUploader() {
2346
- return _super !== null && _super.apply(this, arguments) || this;
2347
- }
2348
- XHRUploader.prototype.upload = function (fetchPayload) {
2349
- return __awaiter(this, void 0, void 0, function () {
2350
- var response;
2351
- return __generator(this, function (_a) {
2352
- switch (_a.label) {
2353
- case 0:
2354
- return [4 /*yield*/, this.makeRequest(this.url, fetchPayload.body)];
2355
- case 1:
2356
- response = _a.sent();
2357
- return [2 /*return*/, response];
2358
- }
2359
- });
2360
- });
2361
- };
2362
- XHRUploader.prototype.makeRequest = function (url, data) {
2363
- return __awaiter(this, void 0, void 0, function () {
2364
- var xhr;
2365
- return __generator(this, function (_a) {
2366
- xhr = new XMLHttpRequest();
2367
- return [2 /*return*/, new Promise(function (resolve, reject) {
2368
- xhr.onreadystatechange = function () {
2369
- if (xhr.readyState !== 4) return;
2370
- // Process the response
2371
- if (xhr.status >= 200 && xhr.status < 300) {
2372
- resolve(xhr);
2373
- } else {
2374
- reject(xhr);
2375
- }
2376
- };
2377
- xhr.open('post', url);
2378
- xhr.send(data);
2379
- })];
2380
- });
2381
- });
2382
- };
2383
- return XHRUploader;
2384
- }(AsyncUploader);
2385
2390
 
2386
2391
  function APIClient(mpInstance, kitBlocker) {
2387
2392
  this.uploader = null;
2388
2393
  var self = this;
2389
2394
  this.queueEventForBatchUpload = function (event) {
2390
2395
  if (!this.uploader) {
2396
+ // https://go.mparticle.com/work/SQDSDKS-6317
2391
2397
  var millis = parseNumber(mpInstance._Helpers.getFeatureFlag(Constants.FeatureFlags.EventBatchingIntervalMillis));
2392
2398
  this.uploader = new BatchUploader(mpInstance, millis);
2393
2399
  }
@@ -3985,6 +3991,61 @@ var mParticle = (function () {
3985
3991
  _this.sessionAttributes = {};
3986
3992
  mpInstance._Persistence.update();
3987
3993
  };
3994
+ this.getFirstSeenTime = function (mpid) {
3995
+ if (!mpid) {
3996
+ return null;
3997
+ }
3998
+ if (_this.persistenceData && _this.persistenceData[mpid] && _this.persistenceData[mpid].fst) {
3999
+ return _this.persistenceData[mpid].fst;
4000
+ } else {
4001
+ return null;
4002
+ }
4003
+ };
4004
+ this.setFirstSeenTime = function (mpid, _time) {
4005
+ if (!mpid) {
4006
+ return;
4007
+ }
4008
+ var time = _time || new Date().getTime();
4009
+ if (_this.persistenceData) {
4010
+ if (!_this.persistenceData[mpid]) {
4011
+ _this.persistenceData[mpid] = {};
4012
+ }
4013
+ if (!_this.persistenceData[mpid].fst) {
4014
+ _this.persistenceData[mpid].fst = time;
4015
+ mpInstance._Persistence.savePersistence(_this.persistenceData);
4016
+ }
4017
+ }
4018
+ };
4019
+ this.getLastSeenTime = function (mpid) {
4020
+ if (!mpid) {
4021
+ return null;
4022
+ }
4023
+ // // https://go.mparticle.com/work/SQDSDKS-6315
4024
+ var currentUser = mpInstance.Identity.getCurrentUser();
4025
+ if (mpid === (currentUser === null || currentUser === void 0 ? void 0 : currentUser.getMPID())) {
4026
+ // if the mpid is the current user, its last seen time is the current time
4027
+ return new Date().getTime();
4028
+ } else if (_this.persistenceData && _this.persistenceData[mpid] && _this.persistenceData[mpid].lst) {
4029
+ return _this.persistenceData[mpid].lst;
4030
+ } else {
4031
+ return null;
4032
+ }
4033
+ };
4034
+ this.setLastSeenTime = function (mpid, _time) {
4035
+ if (!mpid) {
4036
+ return;
4037
+ }
4038
+ var time = _time || new Date().getTime();
4039
+ if (_this.persistenceData) {
4040
+ if (!_this.persistenceData[mpid]) {
4041
+ _this.persistenceData[mpid] = {};
4042
+ }
4043
+ if (!_this.persistenceData[mpid].lst) {
4044
+ _this.persistenceData[mpid].lst = time;
4045
+ mpInstance._Persistence.savePersistence(_this.persistenceData);
4046
+ }
4047
+ }
4048
+ };
3988
4049
  }
3989
4050
  function processFlags(config, SDKConfig) {
3990
4051
  var flags = {};
@@ -3993,7 +4054,8 @@ var mParticle = (function () {
3993
4054
  EventBatchingIntervalMillis = _a.EventBatchingIntervalMillis,
3994
4055
  OfflineStorage = _a.OfflineStorage,
3995
4056
  DirectUrlRouting = _a.DirectUrlRouting,
3996
- CacheIdentity = _a.CacheIdentity;
4057
+ CacheIdentity = _a.CacheIdentity,
4058
+ AudienceAPI = _a.AudienceAPI;
3997
4059
  if (!config.flags) {
3998
4060
  return {};
3999
4061
  }
@@ -4004,6 +4066,7 @@ var mParticle = (function () {
4004
4066
  flags[OfflineStorage] = config.flags[OfflineStorage] || '0';
4005
4067
  flags[DirectUrlRouting] = config.flags[DirectUrlRouting] === 'True';
4006
4068
  flags[CacheIdentity] = config.flags[CacheIdentity] === 'True';
4069
+ flags[AudienceAPI] = config.flags[AudienceAPI] === 'True';
4007
4070
  return flags;
4008
4071
  }
4009
4072
  function processBaseUrls(config, flags, apiKey) {
@@ -6272,8 +6335,76 @@ var mParticle = (function () {
6272
6335
  return false;
6273
6336
  };
6274
6337
 
6338
+ var AudienceManager = /** @class */function () {
6339
+ function AudienceManager(userAudienceUrl, apiKey, logger) {
6340
+ this.url = '';
6341
+ this.logger = logger;
6342
+ this.url = "https://".concat(userAudienceUrl).concat(apiKey, "/audience");
6343
+ this.userAudienceAPI = window.fetch ? new FetchUploader(this.url) : new XHRUploader(this.url);
6344
+ }
6345
+ AudienceManager.prototype.sendGetUserAudienceRequest = function (mpid, callback) {
6346
+ return __awaiter(this, void 0, void 0, function () {
6347
+ var fetchPayload, audienceURLWithMPID, userAudiencePromise, userAudienceMembershipsServerResponse, parsedUserAudienceMemberships, e_1;
6348
+ return __generator(this, function (_a) {
6349
+ switch (_a.label) {
6350
+ case 0:
6351
+ this.logger.verbose('Fetching user audiences from server');
6352
+ fetchPayload = {
6353
+ method: 'GET',
6354
+ headers: {
6355
+ Accept: '*/*'
6356
+ }
6357
+ };
6358
+ audienceURLWithMPID = "".concat(this.url, "?mpid=").concat(mpid);
6359
+ _a.label = 1;
6360
+ case 1:
6361
+ _a.trys.push([1, 6,, 7]);
6362
+ return [4 /*yield*/, this.userAudienceAPI.upload(fetchPayload, audienceURLWithMPID)];
6363
+ case 2:
6364
+ userAudiencePromise = _a.sent();
6365
+ if (!(userAudiencePromise.status >= 200 && userAudiencePromise.status < 300)) return [3 /*break*/, 4];
6366
+ this.logger.verbose("User Audiences successfully received");
6367
+ return [4 /*yield*/, userAudiencePromise.json()];
6368
+ case 3:
6369
+ userAudienceMembershipsServerResponse = _a.sent();
6370
+ parsedUserAudienceMemberships = {
6371
+ currentAudienceMemberships: userAudienceMembershipsServerResponse === null || userAudienceMembershipsServerResponse === void 0 ? void 0 : userAudienceMembershipsServerResponse.audience_memberships
6372
+ };
6373
+ try {
6374
+ callback(parsedUserAudienceMemberships);
6375
+ } catch (e) {
6376
+ throw new Error('Error invoking callback on user audience response.');
6377
+ }
6378
+ return [3 /*break*/, 5];
6379
+ case 4:
6380
+ if (userAudiencePromise.status === 401) {
6381
+ throw new Error('`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`');
6382
+ } else if (userAudiencePromise.status === 403) {
6383
+ throw new Error('`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`');
6384
+ } else {
6385
+ // In case there is an HTTP error we did not anticipate.
6386
+ throw new Error("Uncaught HTTP Error ".concat(userAudiencePromise.status, "."));
6387
+ }
6388
+ case 5:
6389
+ return [3 /*break*/, 7];
6390
+ case 6:
6391
+ e_1 = _a.sent();
6392
+ this.logger.error("Error retrieving audiences. ".concat(e_1));
6393
+ return [3 /*break*/, 7];
6394
+ case 7:
6395
+ return [2 /*return*/];
6396
+ }
6397
+ });
6398
+ });
6399
+ };
6400
+
6401
+ return AudienceManager;
6402
+ }();
6403
+
6275
6404
  var Messages$2 = Constants.Messages,
6276
- HTTPCodes$2 = Constants.HTTPCodes;
6405
+ HTTPCodes$2 = Constants.HTTPCodes,
6406
+ FeatureFlags = Constants.FeatureFlags;
6407
+ var ErrorMessages = Messages$2.ErrorMessages;
6277
6408
  var _Constants$IdentityMe = Constants.IdentityMethods,
6278
6409
  Identify = _Constants$IdentityMe.Identify,
6279
6410
  Modify$1 = _Constants$IdentityMe.Modify,
@@ -6282,6 +6413,7 @@ var mParticle = (function () {
6282
6413
  function Identity(mpInstance) {
6283
6414
  var self = this;
6284
6415
  this.idCache = null;
6416
+ this.audienceManager = null;
6285
6417
  this.checkIdentitySwap = function (previousMPID, currentMPID, currentSessionMPIDs) {
6286
6418
  if (previousMPID && currentMPID && previousMPID !== currentMPID) {
6287
6419
  var persistence = mpInstance._Persistence.getPersistence();
@@ -7037,6 +7169,22 @@ var mParticle = (function () {
7037
7169
  },
7038
7170
  getFirstSeenTime: function getFirstSeenTime() {
7039
7171
  return mpInstance._Persistence.getFirstSeenTime(mpid);
7172
+ },
7173
+ /**
7174
+ * Get user audiences
7175
+ * @method getuserAudiences
7176
+ * @param {Function} [callback] A callback function that is invoked when the user audience request completes
7177
+ */
7178
+ getUserAudiences: function getUserAudiences(callback) {
7179
+ // user audience API is feature flagged
7180
+ if (!mpInstance._Helpers.getFeatureFlag(FeatureFlags.AudienceAPI)) {
7181
+ mpInstance.Logger.error(ErrorMessages.AudienceAPINotEnabled);
7182
+ return;
7183
+ }
7184
+ if (self.audienceManager === null) {
7185
+ self.audienceManager = new AudienceManager(mpInstance._Store.SDKConfig.userAudienceUrl, mpInstance._Store.devToken, mpInstance.Logger, mpid);
7186
+ }
7187
+ self.audienceManager.sendGetUserAudienceRequest(mpid, callback);
7040
7188
  }
7041
7189
  };
7042
7190
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.25.3",
3
+ "version": "2.26.0",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
package/src/apiClient.ts CHANGED
@@ -38,9 +38,10 @@ export default function APIClient(
38
38
  const self = this;
39
39
  this.queueEventForBatchUpload = function(event: SDKEvent) {
40
40
  if (!this.uploader) {
41
+ // https://go.mparticle.com/work/SQDSDKS-6317
41
42
  const millis: number = parseNumber(mpInstance._Helpers.getFeatureFlag(
42
43
  Constants.FeatureFlags.EventBatchingIntervalMillis
43
- ));
44
+ ) as string);
44
45
  this.uploader = new BatchUploader(mpInstance, millis);
45
46
  }
46
47
  this.uploader.queueEvent(event);
@@ -0,0 +1,9 @@
1
+ export default class Audience {
2
+ public audience_id: number;
3
+
4
+ constructor(
5
+ audience_id: number,
6
+ ) {
7
+ this.audience_id = audience_id;
8
+ }
9
+ }
@@ -0,0 +1,88 @@
1
+ import { SDKLoggerApi } from './sdkRuntimeModels';
2
+ import {
3
+ FetchUploader,
4
+ XHRUploader,
5
+ AsyncUploader,
6
+ fetchPayload
7
+ } from './uploaders';
8
+ import Audience from './audience';
9
+
10
+ export interface IAudienceMembershipsServerResponse {
11
+ dt: 'cam'; // current audience memberships
12
+ ct: number; // timestamp
13
+ id: string;
14
+ audience_memberships: Audience[];
15
+ }
16
+
17
+ export interface IAudienceMemberships {
18
+ currentAudienceMemberships: Audience[];
19
+ }
20
+
21
+ export default class AudienceManager {
22
+ public url: string = '';
23
+ public userAudienceAPI: AsyncUploader;
24
+ public logger: SDKLoggerApi;
25
+
26
+ constructor(
27
+ userAudienceUrl: string,
28
+ apiKey: string,
29
+ logger: SDKLoggerApi,
30
+ ) {
31
+ this.logger = logger;
32
+ this.url = `https://${userAudienceUrl}${apiKey}/audience`;
33
+ this.userAudienceAPI = window.fetch
34
+ ? new FetchUploader(this.url)
35
+ : new XHRUploader(this.url);
36
+ }
37
+
38
+ public async sendGetUserAudienceRequest(mpid: string, callback: (userAudiences: IAudienceMemberships) => void) {
39
+ this.logger.verbose('Fetching user audiences from server');
40
+
41
+ const fetchPayload: fetchPayload = {
42
+ method: 'GET',
43
+ headers: {
44
+ Accept: '*/*',
45
+ },
46
+ };
47
+ const audienceURLWithMPID = `${this.url}?mpid=${mpid}`;
48
+
49
+ try {
50
+ const userAudiencePromise: Response = await this.userAudienceAPI.upload(
51
+ fetchPayload,
52
+ audienceURLWithMPID
53
+ );
54
+
55
+ if (
56
+ userAudiencePromise.status >= 200 &&
57
+ userAudiencePromise.status < 300
58
+ ) {
59
+ this.logger.verbose(`User Audiences successfully received`);
60
+
61
+ const userAudienceMembershipsServerResponse: IAudienceMembershipsServerResponse = await userAudiencePromise.json();
62
+ const parsedUserAudienceMemberships: IAudienceMemberships = {
63
+ currentAudienceMemberships: userAudienceMembershipsServerResponse?.audience_memberships
64
+ }
65
+
66
+ try {
67
+ callback(parsedUserAudienceMemberships);
68
+ } catch(e) {
69
+ throw new Error('Error invoking callback on user audience response.');
70
+ }
71
+
72
+ } else if (userAudiencePromise.status === 401) {
73
+ throw new Error('`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your API key.`');
74
+ } else if (userAudiencePromise.status === 403) {
75
+ throw new Error('`HTTP error status ${userAudiencePromise.status} while retrieving User Audiences - please verify your workspace is enabled for audiences.`');
76
+ } else {
77
+ // In case there is an HTTP error we did not anticipate.
78
+ throw new Error(
79
+ `Uncaught HTTP Error ${userAudiencePromise.status}.`
80
+ );
81
+ }
82
+ } catch (e) {
83
+ this.logger.error(
84
+ `Error retrieving audiences. ${e}`
85
+ );
86
+ }
87
+ }
88
+ }
@@ -10,6 +10,12 @@ import { convertEvents } from './sdkToEventsApiConverter';
10
10
  import Types from './types';
11
11
  import { getRampNumber, isEmpty } from './utils';
12
12
  import { SessionStorageVault, LocalStorageVault } from './vault';
13
+ import {
14
+ AsyncUploader,
15
+ FetchUploader,
16
+ XHRUploader,
17
+ fetchPayload
18
+ } from './uploaders';
13
19
 
14
20
  /**
15
21
  * BatchUploader contains all the logic to store/retrieve events and batches
@@ -108,11 +114,12 @@ export class BatchUploader {
108
114
  _Store: { deviceId },
109
115
  } = this.mpInstance;
110
116
 
111
- const offlineStorageFeatureFlagValue = getFeatureFlag(
117
+ // https://go.mparticle.com/work/SQDSDKS-6317
118
+ const offlineStorageFeatureFlagValue: string = getFeatureFlag(
112
119
  Constants.FeatureFlags.OfflineStorage
113
- );
120
+ ) as string;
114
121
 
115
- const offlineStoragePercentage = parseInt(
122
+ const offlineStoragePercentage: number = parseInt(
116
123
  offlineStorageFeatureFlagValue,
117
124
  10
118
125
  );
@@ -422,66 +429,4 @@ export class BatchUploader {
422
429
  }
423
430
  return null;
424
431
  }
425
- }
426
-
427
- abstract class AsyncUploader {
428
- url: string;
429
- public abstract upload(fetchPayload: fetchPayload): Promise<XHRResponse>;
430
-
431
- constructor(url: string) {
432
- this.url = url;
433
- }
434
- }
435
-
436
- class FetchUploader extends AsyncUploader {
437
- public async upload(fetchPayload: fetchPayload): Promise<XHRResponse> {
438
- const response: XHRResponse = await fetch(this.url, fetchPayload);
439
- return response;
440
- }
441
- }
442
-
443
- class XHRUploader extends AsyncUploader {
444
- public async upload(fetchPayload: fetchPayload): Promise<XHRResponse> {
445
- const response: XHRResponse = await this.makeRequest(
446
- this.url,
447
- fetchPayload.body
448
- );
449
- return response;
450
- }
451
-
452
- private async makeRequest(
453
- url: string,
454
- data: string
455
- ): Promise<XMLHttpRequest> {
456
- const xhr: XMLHttpRequest = new XMLHttpRequest();
457
- return new Promise((resolve, reject) => {
458
- xhr.onreadystatechange = () => {
459
- if (xhr.readyState !== 4) return;
460
-
461
- // Process the response
462
- if (xhr.status >= 200 && xhr.status < 300) {
463
- resolve(xhr);
464
- } else {
465
- reject(xhr);
466
- }
467
- };
468
-
469
- xhr.open('post', url);
470
- xhr.send(data);
471
- });
472
- }
473
- }
474
-
475
- interface XHRResponse {
476
- status: number;
477
- statusText?: string;
478
- }
479
-
480
- interface fetchPayload {
481
- method: string;
482
- headers: {
483
- Accept: string;
484
- 'Content-Type': string;
485
- };
486
- body: string;
487
- }
432
+ }
package/src/constants.ts CHANGED
@@ -26,6 +26,8 @@ const Constants = {
26
26
  BadKey: 'Key value cannot be object or array',
27
27
  BadLogPurchase:
28
28
  'Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions',
29
+ AudienceAPINotEnabled:
30
+ 'Your workspace is not enabled to retrieve user audiences.',
29
31
  },
30
32
  InformationMessages: {
31
33
  CookieSearch: 'Searching for cookie',
@@ -135,6 +137,7 @@ const Constants = {
135
137
  configUrl: 'jssdkcdns.mparticle.com/JS/v2/',
136
138
  identityUrl: 'identity.mparticle.com/v1/',
137
139
  aliasUrl: 'jssdks.mparticle.com/v1/identity/',
140
+ userAudienceUrl: 'nativesdks.mparticle.com/v1/',
138
141
  },
139
142
  Base64CookieKeys: {
140
143
  csm: 1,
@@ -170,6 +173,7 @@ const Constants = {
170
173
  OfflineStorage: 'offlineStorage',
171
174
  DirectUrlRouting: 'directURLRouting',
172
175
  CacheIdentity: 'cacheIdentity',
176
+ AudienceAPI: 'audienceAPI',
173
177
  },
174
178
  DefaultInstance: 'default_instance',
175
179
  CCPAPurpose: 'data_sale_opt_out',
package/src/identity.js CHANGED
@@ -5,15 +5,17 @@ import {
5
5
  createKnownIdentities,
6
6
  tryCacheIdentity,
7
7
  } from './identity-utils';
8
+ import AudienceManager from './audienceManager';
8
9
 
9
- var Messages = Constants.Messages,
10
- HTTPCodes = Constants.HTTPCodes;
10
+ const { Messages, HTTPCodes, FeatureFlags } = Constants;
11
+ const { ErrorMessages } = Messages;
11
12
 
12
13
  const { Identify, Modify, Login, Logout } = Constants.IdentityMethods;
13
14
 
14
15
  export default function Identity(mpInstance) {
15
16
  var self = this;
16
17
  this.idCache = null;
18
+ this.audienceManager = null;
17
19
 
18
20
  this.checkIdentitySwap = function(
19
21
  previousMPID,
@@ -1265,6 +1267,34 @@ export default function Identity(mpInstance) {
1265
1267
  getFirstSeenTime: function() {
1266
1268
  return mpInstance._Persistence.getFirstSeenTime(mpid);
1267
1269
  },
1270
+ /**
1271
+ * Get user audiences
1272
+ * @method getuserAudiences
1273
+ * @param {Function} [callback] A callback function that is invoked when the user audience request completes
1274
+ */
1275
+ getUserAudiences: function(callback) {
1276
+ // user audience API is feature flagged
1277
+ if (
1278
+ !mpInstance._Helpers.getFeatureFlag(
1279
+ FeatureFlags.AudienceAPI
1280
+ )
1281
+ ) {
1282
+ mpInstance.Logger.error(
1283
+ ErrorMessages.AudienceAPINotEnabled
1284
+ );
1285
+ return;
1286
+ }
1287
+ if (self.audienceManager === null) {
1288
+ self.audienceManager = new AudienceManager(
1289
+ mpInstance._Store.SDKConfig.userAudienceUrl,
1290
+ mpInstance._Store.devToken,
1291
+ mpInstance.Logger,
1292
+ mpid
1293
+ );
1294
+ }
1295
+
1296
+ self.audienceManager.sendGetUserAudienceRequest(mpid, callback);
1297
+ },
1268
1298
  };
1269
1299
  };
1270
1300