@mparticle/web-sdk 2.33.1 → 2.35.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
@@ -203,7 +203,7 @@ var mParticle = (function () {
203
203
  Base64: Base64$1
204
204
  };
205
205
 
206
- var version = "2.33.1";
206
+ var version = "2.35.0";
207
207
 
208
208
  var Constants = {
209
209
  sdkVersion: version,
@@ -363,7 +363,8 @@ var mParticle = (function () {
363
363
  DirectUrlRouting: 'directURLRouting',
364
364
  CacheIdentity: 'cacheIdentity',
365
365
  AudienceAPI: 'audienceAPI',
366
- CaptureIntegrationSpecificIds: 'captureIntegrationSpecificIds'
366
+ CaptureIntegrationSpecificIds: 'captureIntegrationSpecificIds',
367
+ AstBackgroundEvents: 'astBackgroundEvents'
367
368
  },
368
369
  DefaultInstance: 'default_instance',
369
370
  CCPAPurpose: 'data_sale_opt_out',
@@ -1800,8 +1801,13 @@ var mParticle = (function () {
1800
1801
  }
1801
1802
  function convertAST(sdkEvent) {
1802
1803
  var commonEventData = convertBaseEventData(sdkEvent);
1804
+ // Determine the transition type based on IsBackgroundAST flag
1805
+ var _a = dist.ApplicationStateTransitionEventDataApplicationTransitionTypeEnum,
1806
+ applicationBackground = _a.applicationBackground,
1807
+ applicationInitialized = _a.applicationInitialized;
1808
+ var transitionType = sdkEvent.IsBackgroundAST ? applicationBackground : applicationInitialized;
1803
1809
  var astEventData = {
1804
- application_transition_type: dist.ApplicationStateTransitionEventDataApplicationTransitionTypeEnum.applicationInitialized,
1810
+ application_transition_type: transitionType,
1805
1811
  is_first_run: sdkEvent.IsFirstRun,
1806
1812
  is_upgrade: false,
1807
1813
  launch_referral: sdkEvent.LaunchReferral
@@ -2198,6 +2204,53 @@ var mParticle = (function () {
2198
2204
  return XHRUploader;
2199
2205
  }(AsyncUploader);
2200
2206
 
2207
+ function hasMPIDAndUserLoginChanged(previousUser, newUser) {
2208
+ return !previousUser || newUser.getMPID() !== previousUser.getMPID() || previousUser.isLoggedIn() !== newUser.isLoggedIn();
2209
+ }
2210
+ // https://go.mparticle.com/work/SQDSDKS-6504
2211
+ function hasMPIDChanged(prevUser, identityApiResult) {
2212
+ return !prevUser || prevUser.getMPID() && identityApiResult.mpid && identityApiResult.mpid !== prevUser.getMPID();
2213
+ }
2214
+ // https://go.mparticle.com/work/SQDSDKS-7136
2215
+ function appendUserInfo(user, event) {
2216
+ if (!event) {
2217
+ return;
2218
+ }
2219
+ if (!user) {
2220
+ event.MPID = null;
2221
+ event.ConsentState = null;
2222
+ event.UserAttributes = null;
2223
+ event.UserIdentities = null;
2224
+ return;
2225
+ }
2226
+ if (event.MPID && event.MPID === user.getMPID()) {
2227
+ return;
2228
+ }
2229
+ event.MPID = user.getMPID();
2230
+ event.ConsentState = user.getConsentState();
2231
+ event.UserAttributes = user.getAllUserAttributes();
2232
+ var userIdentities = user.getUserIdentities().userIdentities;
2233
+ var dtoUserIdentities = {};
2234
+ for (var identityKey in userIdentities) {
2235
+ var identityType = Types.IdentityType.getIdentityType(identityKey);
2236
+ if (identityType !== false) {
2237
+ dtoUserIdentities[identityType] = userIdentities[identityKey];
2238
+ }
2239
+ }
2240
+ var validUserIdentities = [];
2241
+ if (isObject(dtoUserIdentities)) {
2242
+ if (Object.keys(dtoUserIdentities).length) {
2243
+ for (var key in dtoUserIdentities) {
2244
+ var userIdentity = {};
2245
+ userIdentity.Identity = dtoUserIdentities[key];
2246
+ userIdentity.Type = parseNumber(key);
2247
+ validUserIdentities.push(userIdentity);
2248
+ }
2249
+ }
2250
+ }
2251
+ event.UserIdentities = validUserIdentities;
2252
+ }
2253
+
2201
2254
  /**
2202
2255
  * BatchUploader contains all the logic to store/retrieve events and batches
2203
2256
  * to/from persistence, and upload batches to mParticle.
@@ -2222,6 +2275,8 @@ var mParticle = (function () {
2222
2275
  function BatchUploader(mpInstance, uploadInterval) {
2223
2276
  var _a;
2224
2277
  this.offlineStorageEnabled = false;
2278
+ this.lastASTEventTime = 0;
2279
+ this.AST_DEBOUNCE_MS = 1000; // 1 second debounce
2225
2280
  this.mpInstance = mpInstance;
2226
2281
  this.uploadIntervalMillis = uploadInterval;
2227
2282
  this.batchingEnabled = uploadInterval >= BatchUploader.MINIMUM_INTERVAL_MILLIS;
@@ -2269,20 +2324,78 @@ var mParticle = (function () {
2269
2324
  // https://go.mparticle.com/work/SQDSDKS-5022
2270
2325
  return offlineStoragePercentage >= rampNumber;
2271
2326
  };
2327
+ // debounce AST just in case multiple events are fired in a short period of time due to browser differences
2328
+ BatchUploader.prototype.shouldDebounceAndUpdateLastASTTime = function () {
2329
+ var now = Date.now();
2330
+ if (now - this.lastASTEventTime < this.AST_DEBOUNCE_MS) {
2331
+ return true;
2332
+ }
2333
+ this.lastASTEventTime = now;
2334
+ return false;
2335
+ };
2336
+ // https://go.mparticle.com/work/SQDSDKS-7133
2337
+ BatchUploader.prototype.createBackgroundASTEvent = function () {
2338
+ var now = Date.now();
2339
+ var _a = this.mpInstance,
2340
+ _Store = _a._Store,
2341
+ Identity = _a.Identity,
2342
+ _timeOnSiteTimer = _a._timeOnSiteTimer,
2343
+ _Helpers = _a._Helpers;
2344
+ var sessionId = _Store.sessionId,
2345
+ deviceId = _Store.deviceId,
2346
+ sessionStartDate = _Store.sessionStartDate,
2347
+ SDKConfig = _Store.SDKConfig;
2348
+ var generateUniqueId = _Helpers.generateUniqueId;
2349
+ var getCurrentUser = Identity.getCurrentUser;
2350
+ var event = {
2351
+ AppName: SDKConfig.appName,
2352
+ AppVersion: SDKConfig.appVersion,
2353
+ Package: SDKConfig["package"],
2354
+ EventDataType: MessageType$1.AppStateTransition,
2355
+ Timestamp: now,
2356
+ SessionId: sessionId,
2357
+ DeviceId: deviceId,
2358
+ IsFirstRun: false,
2359
+ SourceMessageId: generateUniqueId(),
2360
+ SDKVersion: Constants.sdkVersion,
2361
+ CustomFlags: {},
2362
+ EventAttributes: {},
2363
+ SessionStartDate: (sessionStartDate === null || sessionStartDate === void 0 ? void 0 : sessionStartDate.getTime()) || now,
2364
+ Debug: SDKConfig.isDevelopmentMode,
2365
+ ActiveTimeOnSite: (_timeOnSiteTimer === null || _timeOnSiteTimer === void 0 ? void 0 : _timeOnSiteTimer.getTimeInForeground()) || 0,
2366
+ IsBackgroundAST: true
2367
+ };
2368
+ appendUserInfo(getCurrentUser(), event);
2369
+ return event;
2370
+ };
2272
2371
  // Adds listeners to be used trigger Navigator.sendBeacon if the browser
2273
2372
  // loses focus for any reason, such as closing browser tab or minimizing window
2274
2373
  BatchUploader.prototype.addEventListeners = function () {
2374
+ var _this_1 = this;
2275
2375
  var _this = this;
2376
+ var handleExit = function handleExit() {
2377
+ // Check for debounce before creating and queueing event
2378
+ var getFeatureFlag = _this_1.mpInstance._Helpers.getFeatureFlag;
2379
+ var AstBackgroundEvents = Constants.FeatureFlags.AstBackgroundEvents;
2380
+ if (getFeatureFlag(AstBackgroundEvents)) {
2381
+ if (_this.shouldDebounceAndUpdateLastASTTime()) {
2382
+ return;
2383
+ }
2384
+ // Add application state transition event to queue
2385
+ var event_1 = _this.createBackgroundASTEvent();
2386
+ _this.queueEvent(event_1);
2387
+ }
2388
+ // Then trigger the upload with beacon
2389
+ _this.prepareAndUpload(false, _this.isBeaconAvailable());
2390
+ };
2276
2391
  // visibility change is a document property, not window
2277
2392
  document.addEventListener('visibilitychange', function () {
2278
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
2279
- });
2280
- window.addEventListener('beforeunload', function () {
2281
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
2282
- });
2283
- window.addEventListener('pagehide', function () {
2284
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
2393
+ if (document.visibilityState === 'hidden') {
2394
+ handleExit();
2395
+ }
2285
2396
  });
2397
+ window.addEventListener('beforeunload', handleExit);
2398
+ window.addEventListener('pagehide', handleExit);
2286
2399
  };
2287
2400
  BatchUploader.prototype.isBeaconAvailable = function () {
2288
2401
  if (navigator.sendBeacon) {
@@ -2567,7 +2680,7 @@ var mParticle = (function () {
2567
2680
  this.appendUserInfoToEvents = function (user, events) {
2568
2681
  events.forEach(function (event) {
2569
2682
  if (!event.MPID) {
2570
- mpInstance._ServerModel.appendUserInfo(user, event);
2683
+ appendUserInfo(user, event);
2571
2684
  }
2572
2685
  });
2573
2686
  };
@@ -4355,7 +4468,8 @@ var mParticle = (function () {
4355
4468
  DirectUrlRouting = _a.DirectUrlRouting,
4356
4469
  CacheIdentity = _a.CacheIdentity,
4357
4470
  AudienceAPI = _a.AudienceAPI,
4358
- CaptureIntegrationSpecificIds = _a.CaptureIntegrationSpecificIds;
4471
+ CaptureIntegrationSpecificIds = _a.CaptureIntegrationSpecificIds,
4472
+ AstBackgroundEvents = _a.AstBackgroundEvents;
4359
4473
  if (!config.flags) {
4360
4474
  return {};
4361
4475
  }
@@ -4369,6 +4483,7 @@ var mParticle = (function () {
4369
4483
  flags[CacheIdentity] = config.flags[CacheIdentity] === 'True';
4370
4484
  flags[AudienceAPI] = config.flags[AudienceAPI] === 'True';
4371
4485
  flags[CaptureIntegrationSpecificIds] = config.flags[CaptureIntegrationSpecificIds] === 'True';
4486
+ flags[AstBackgroundEvents] = config.flags[AstBackgroundEvents] === 'True';
4372
4487
  return flags;
4373
4488
  }
4374
4489
  function processBaseUrls(config, flags, apiKey) {
@@ -6558,45 +6673,6 @@ var mParticle = (function () {
6558
6673
  }
6559
6674
  function ServerModel(mpInstance) {
6560
6675
  var self = this;
6561
- // TODO: Can we refactor this to not mutate the event?
6562
- this.appendUserInfo = function (user, event) {
6563
- if (!event) {
6564
- return;
6565
- }
6566
- if (!user) {
6567
- event.MPID = null;
6568
- event.ConsentState = null;
6569
- event.UserAttributes = null;
6570
- event.UserIdentities = null;
6571
- return;
6572
- }
6573
- if (event.MPID && event.MPID === user.getMPID()) {
6574
- return;
6575
- }
6576
- event.MPID = user.getMPID();
6577
- event.ConsentState = user.getConsentState();
6578
- event.UserAttributes = user.getAllUserAttributes();
6579
- var userIdentities = user.getUserIdentities().userIdentities;
6580
- var dtoUserIdentities = {};
6581
- for (var identityKey in userIdentities) {
6582
- var identityType = Types.IdentityType.getIdentityType(identityKey);
6583
- if (identityType !== false) {
6584
- dtoUserIdentities[identityType] = userIdentities[identityKey];
6585
- }
6586
- }
6587
- var validUserIdentities = [];
6588
- if (mpInstance._Helpers.isObject(dtoUserIdentities)) {
6589
- if (Object.keys(dtoUserIdentities).length) {
6590
- for (var key in dtoUserIdentities) {
6591
- var userIdentity = {};
6592
- userIdentity.Identity = dtoUserIdentities[key];
6593
- userIdentity.Type = mpInstance._Helpers.parseNumber(key);
6594
- validUserIdentities.push(userIdentity);
6595
- }
6596
- }
6597
- }
6598
- event.UserIdentities = validUserIdentities;
6599
- };
6600
6676
  this.convertToConsentStateV2DTO = function (state) {
6601
6677
  if (!state) {
6602
6678
  return null;
@@ -6713,7 +6789,7 @@ var mParticle = (function () {
6713
6789
  // FIXME: Remove duplicate occurence
6714
6790
  eventObject.CurrencyCode = mpInstance._Store.currencyCode;
6715
6791
  var currentUser = user || mpInstance.Identity.getCurrentUser();
6716
- self.appendUserInfo(currentUser, eventObject);
6792
+ appendUserInfo(currentUser, eventObject);
6717
6793
  if (event.messageType === Types.MessageType.SessionEnd) {
6718
6794
  eventObject.SessionLength = mpInstance._Store.dateLastEventSent.getTime() - mpInstance._Store.sessionStartDate.getTime();
6719
6795
  eventObject.currentSessionMPIDs = mpInstance._Store.currentSessionMPIDs;
@@ -7088,14 +7164,6 @@ var mParticle = (function () {
7088
7164
  return AudienceManager;
7089
7165
  }();
7090
7166
 
7091
- function hasMPIDAndUserLoginChanged(previousUser, newUser) {
7092
- return !previousUser || newUser.getMPID() !== previousUser.getMPID() || previousUser.isLoggedIn() !== newUser.isLoggedIn();
7093
- }
7094
- // https://go.mparticle.com/work/SQDSDKS-6504
7095
- function hasMPIDChanged(prevUser, identityApiResult) {
7096
- return !prevUser || prevUser.getMPID() && identityApiResult.mpid && identityApiResult.mpid !== prevUser.getMPID();
7097
- }
7098
-
7099
7167
  var _this = undefined;
7100
7168
  var processReadyQueue = function processReadyQueue(readyQueue) {
7101
7169
  if (!isEmpty(readyQueue)) {
@@ -9374,6 +9442,12 @@ var mParticle = (function () {
9374
9442
  _ttp: {
9375
9443
  mappedKey: 'tiktok_cookie_id',
9376
9444
  output: IntegrationOutputs.PARTNER_IDENTITIES
9445
+ },
9446
+ // Snapchat
9447
+ // https://businesshelp.snapchat.com/s/article/troubleshooting-click-id?language=en_US
9448
+ ScCid: {
9449
+ mappedKey: 'SnapchatConversions.ClickId',
9450
+ output: IntegrationOutputs.CUSTOM_FLAGS
9377
9451
  }
9378
9452
  };
9379
9453
  var IntegrationCapture = /** @class */function () {
@@ -9530,6 +9604,62 @@ var mParticle = (function () {
9530
9604
  return IntegrationCapture;
9531
9605
  }();
9532
9606
 
9607
+ var RoktManager = /** @class */function () {
9608
+ function RoktManager() {
9609
+ this.launcher = null;
9610
+ this.messageQueue = [];
9611
+ this.launcher = null;
9612
+ }
9613
+ RoktManager.prototype.attachLauncher = function (launcher) {
9614
+ this.setLauncher(launcher);
9615
+ this.processMessageQueue();
9616
+ };
9617
+ RoktManager.prototype.selectPlacements = function (options) {
9618
+ if (!this.launcher) {
9619
+ this.queueMessage({
9620
+ methodName: 'selectPlacements',
9621
+ payload: options
9622
+ });
9623
+ return Promise.resolve({});
9624
+ }
9625
+ try {
9626
+ return this.launcher.selectPlacements(options);
9627
+ } catch (error) {
9628
+ return Promise.reject(error instanceof Error ? error : new Error('Unknown error occurred'));
9629
+ }
9630
+ };
9631
+ RoktManager.prototype.processMessageQueue = function () {
9632
+ var _this = this;
9633
+ if (this.messageQueue.length > 0) {
9634
+ this.messageQueue.forEach(function (message) {
9635
+ return __awaiter(_this, void 0, void 0, function () {
9636
+ return __generator(this, function (_a) {
9637
+ switch (_a.label) {
9638
+ case 0:
9639
+ if (!(this.launcher && message.methodName in this.launcher)) return [3 /*break*/, 2];
9640
+ return [4 /*yield*/, this.launcher[message.methodName](message.payload)];
9641
+ case 1:
9642
+ _a.sent();
9643
+ _a.label = 2;
9644
+ case 2:
9645
+ return [2 /*return*/];
9646
+ }
9647
+ });
9648
+ });
9649
+ });
9650
+
9651
+ this.messageQueue = [];
9652
+ }
9653
+ };
9654
+ RoktManager.prototype.queueMessage = function (message) {
9655
+ this.messageQueue.push(message);
9656
+ };
9657
+ RoktManager.prototype.setLauncher = function (launcher) {
9658
+ this.launcher = launcher;
9659
+ };
9660
+ return RoktManager;
9661
+ }();
9662
+
9533
9663
  var Messages = Constants.Messages,
9534
9664
  HTTPCodes = Constants.HTTPCodes,
9535
9665
  FeatureFlags = Constants.FeatureFlags;
@@ -9569,6 +9699,7 @@ var mParticle = (function () {
9569
9699
  forwarderConstructors: []
9570
9700
  };
9571
9701
  this._IntegrationCapture = new IntegrationCapture();
9702
+ this._RoktManager = new RoktManager();
9572
9703
  // required for forwarders once they reference the mparticle instance
9573
9704
  this.IdentityType = IdentityType;
9574
9705
  this.EventType = EventType;
@@ -10842,7 +10973,7 @@ var mParticle = (function () {
10842
10973
  // Only leaving this here in case any clients are trying to access mParticle.Store, to prevent from throwing
10843
10974
  this.Store = {};
10844
10975
  this._instances = {};
10845
- this.IdentityType = Types.IdentityType;
10976
+ this.IdentityType = IdentityType;
10846
10977
  this.EventType = EventType;
10847
10978
  this.CommerceEventType = CommerceEventType;
10848
10979
  this.PromotionType = PromotionActionType;
@@ -10893,6 +11024,7 @@ var mParticle = (function () {
10893
11024
  return client;
10894
11025
  }
10895
11026
  };
11027
+ this.Rokt = self.getInstance()._RoktManager;
10896
11028
  this.getDeviceId = function () {
10897
11029
  return self.getInstance().getDeviceId();
10898
11030
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.33.1",
3
+ "version": "2.35.0",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
package/src/apiClient.ts CHANGED
@@ -9,6 +9,7 @@ import { MPForwarder } from './forwarders.interfaces';
9
9
  import { IMParticleUser, ISDKUserAttributes } from './identity-user-interfaces';
10
10
  import { AsyncUploader, FetchUploader, XHRUploader } from './uploaders';
11
11
  import { IMParticleWebSDKInstance } from './mp-instance';
12
+ import { appendUserInfo } from './user-utils';
12
13
 
13
14
  export interface IAPIClient {
14
15
  uploader: BatchUploader | null;
@@ -82,7 +83,7 @@ export default function APIClient(
82
83
  this.appendUserInfoToEvents = function(user, events) {
83
84
  events.forEach(function(event) {
84
85
  if (!event.MPID) {
85
- mpInstance._ServerModel.appendUserInfo(user, event);
86
+ appendUserInfo(user, event);
86
87
  }
87
88
  });
88
89
  };
@@ -2,7 +2,7 @@ import { Batch } from '@mparticle/event-models';
2
2
  import Constants from './constants';
3
3
  import { SDKEvent, SDKLoggerApi } from './sdkRuntimeModels';
4
4
  import { convertEvents } from './sdkToEventsApiConverter';
5
- import { MessageType } from './types';
5
+ import { MessageType, EventType } from './types';
6
6
  import { getRampNumber, isEmpty } from './utils';
7
7
  import { SessionStorageVault, LocalStorageVault } from './vault';
8
8
  import {
@@ -13,7 +13,7 @@ import {
13
13
  } from './uploaders';
14
14
  import { IMParticleUser } from './identity-user-interfaces';
15
15
  import { IMParticleWebSDKInstance } from './mp-instance';
16
-
16
+ import { appendUserInfo } from './user-utils';
17
17
  /**
18
18
  * BatchUploader contains all the logic to store/retrieve events and batches
19
19
  * to/from persistence, and upload batches to mParticle.
@@ -44,6 +44,8 @@ export class BatchUploader {
44
44
  private batchVault: LocalStorageVault<Batch[]>;
45
45
  private offlineStorageEnabled: boolean = false;
46
46
  private uploader: AsyncUploader;
47
+ private lastASTEventTime: number = 0;
48
+ private readonly AST_DEBOUNCE_MS: number = 1000; // 1 second debounce
47
49
 
48
50
  /**
49
51
  * Creates an instance of a BatchUploader
@@ -129,21 +131,79 @@ export class BatchUploader {
129
131
  return offlineStoragePercentage >= rampNumber;
130
132
  }
131
133
 
134
+ // debounce AST just in case multiple events are fired in a short period of time due to browser differences
135
+ private shouldDebounceAndUpdateLastASTTime(): boolean {
136
+ const now = Date.now();
137
+ if (now - this.lastASTEventTime < this.AST_DEBOUNCE_MS) {
138
+ return true;
139
+ }
140
+
141
+ this.lastASTEventTime = now;
142
+ return false;
143
+ }
144
+
145
+ // https://go.mparticle.com/work/SQDSDKS-7133
146
+ private createBackgroundASTEvent(): SDKEvent {
147
+ const now = Date.now();
148
+ const { _Store, Identity, _timeOnSiteTimer, _Helpers } = this.mpInstance;
149
+ const { sessionId, deviceId, sessionStartDate, SDKConfig } = _Store;
150
+ const { generateUniqueId } = _Helpers;
151
+ const { getCurrentUser } = Identity;
152
+
153
+ const event = {
154
+ AppName: SDKConfig.appName,
155
+ AppVersion: SDKConfig.appVersion,
156
+ Package: SDKConfig.package,
157
+ EventDataType: MessageType.AppStateTransition,
158
+ Timestamp: now,
159
+ SessionId: sessionId,
160
+ DeviceId: deviceId,
161
+ IsFirstRun: false,
162
+ SourceMessageId: generateUniqueId(),
163
+ SDKVersion: Constants.sdkVersion,
164
+ CustomFlags: {},
165
+ EventAttributes: {},
166
+ SessionStartDate: sessionStartDate?.getTime() || now,
167
+ Debug: SDKConfig.isDevelopmentMode,
168
+ ActiveTimeOnSite: _timeOnSiteTimer?.getTimeInForeground() || 0,
169
+ IsBackgroundAST: true
170
+ } as SDKEvent;
171
+
172
+ appendUserInfo(getCurrentUser(), event);
173
+ return event;
174
+ }
175
+
132
176
  // Adds listeners to be used trigger Navigator.sendBeacon if the browser
133
177
  // loses focus for any reason, such as closing browser tab or minimizing window
134
178
  private addEventListeners() {
135
179
  const _this = this;
136
180
 
181
+ const handleExit = () => {
182
+ // Check for debounce before creating and queueing event
183
+ const {
184
+ _Helpers: { getFeatureFlag },
185
+ } = this.mpInstance;
186
+ const { AstBackgroundEvents } = Constants.FeatureFlags;
187
+
188
+ if (getFeatureFlag(AstBackgroundEvents)) {
189
+ if (_this.shouldDebounceAndUpdateLastASTTime()) {
190
+ return;
191
+ }
192
+ // Add application state transition event to queue
193
+ const event = _this.createBackgroundASTEvent();
194
+ _this.queueEvent(event);
195
+ }
196
+ // Then trigger the upload with beacon
197
+ _this.prepareAndUpload(false, _this.isBeaconAvailable());
198
+ };
137
199
  // visibility change is a document property, not window
138
200
  document.addEventListener('visibilitychange', () => {
139
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
140
- });
141
- window.addEventListener('beforeunload', () => {
142
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
143
- });
144
- window.addEventListener('pagehide', () => {
145
- _this.prepareAndUpload(false, _this.isBeaconAvailable());
201
+ if (document.visibilityState === 'hidden') {
202
+ handleExit();
203
+ }
146
204
  });
205
+ window.addEventListener('beforeunload', handleExit);
206
+ window.addEventListener('pagehide', handleExit);
147
207
  }
148
208
 
149
209
  private isBeaconAvailable(): boolean {
@@ -387,6 +447,7 @@ export class BatchUploader {
387
447
  let blob = new Blob([fetchPayload.body], {
388
448
  type: 'text/plain;charset=UTF-8',
389
449
  });
450
+
390
451
  navigator.sendBeacon(this.uploadUrl, blob);
391
452
  } else {
392
453
  try {
package/src/constants.ts CHANGED
@@ -175,6 +175,7 @@ const Constants = {
175
175
  CacheIdentity: 'cacheIdentity',
176
176
  AudienceAPI: 'audienceAPI',
177
177
  CaptureIntegrationSpecificIds: 'captureIntegrationSpecificIds',
178
+ AstBackgroundEvents: 'astBackgroundEvents',
178
179
  },
179
180
  DefaultInstance: 'default_instance',
180
181
  CCPAPurpose: 'data_sale_opt_out',
@@ -1,6 +1,6 @@
1
1
  import { SDKEvent, SDKEventCustomFlags } from './sdkRuntimeModels';
2
2
  import { Dictionary } from './utils';
3
- import { IKitConfigs } from './configAPIClient';
3
+ import { IKitConfigs, IKitFilterSettings } from './configAPIClient';
4
4
  import { IdentityApiData } from '@mparticle/web-sdk';
5
5
  import {
6
6
  IMParticleUser,
@@ -8,28 +8,37 @@ import {
8
8
  UserAttributes,
9
9
  } from './identity-user-interfaces';
10
10
 
11
- // TODO: https://go.mparticle.com/work/SQDSDKS-6035
12
- export type Kit = Dictionary;
11
+ // TODO: https://go.mparticle.com/work/SQDSDKS-4475
13
12
  export type MPForwarder = Dictionary;
14
13
 
15
14
  // The state of the kit when accessed via window.KitName via CDN
16
15
  // or imported as an NPM package
17
16
  export interface UnregisteredKit {
18
- register(config): void;
17
+ constructor: () => void;
18
+ register(config: KitRegistrationConfig): void;
19
+ name: string;
20
+ suffix?: string;
19
21
  }
20
22
 
21
23
  // The state of the kit after being added to forwarderConstructors in the CDN
22
24
  // or after registered to SDKConfig.kits via NPM
23
25
  export interface RegisteredKit {
24
- constructor(): void;
25
- name: string;
26
- getId(): number;
26
+ constructor: () => void;
27
+
28
+ // Applies to sideloaded kits only
29
+ filters?: IKitFilterSettings;
30
+ }
31
+
32
+ // This is the subset of the SDKConfig.kits object that is used to register kits.
33
+ export interface KitRegistrationConfig {
34
+ kits: Dictionary<RegisteredKit>;
27
35
  }
28
36
 
29
37
  // The state of the kit after being configured. This is what the kit looks like when acted on.
30
38
  export interface ConfiguredKit
31
39
  extends Omit<IKitConfigs, 'isDebugString' | 'hasDebugString'> {
32
40
  common: Dictionary<unknown>;
41
+ id: number;
33
42
  init(
34
43
  settings: Dictionary<unknown>,
35
44
  service: forwardingStatsCallback,
@@ -45,22 +54,22 @@ export interface ConfiguredKit
45
54
  onIdentifyComplete(
46
55
  user: IMParticleUser,
47
56
  filteredIdentityRequest: IdentityApiData
48
- ): string | KitMappedMethodFailure;
57
+ ): string;
49
58
  onLoginComplete(
50
59
  user: IMParticleUser,
51
60
  filteredIdentityRequest: IdentityApiData
52
- ): string | KitMappedMethodFailure;
61
+ ): string;
53
62
  onLogoutComplete(
54
63
  user: IMParticleUser,
55
64
  filteredIdentityRequest: IdentityApiData
56
- ): string | KitMappedMethodFailure;
65
+ ): string;
57
66
  onModifyComplete(
58
67
  user: IMParticleUser,
59
68
  filteredIdentityRequest: IdentityApiData
60
- ): string | KitMappedMethodFailure;
61
- onUserIdentified(user: IMParticleUser): string | KitMappedMethodFailure;
69
+ ): string;
70
+ onUserIdentified(user: IMParticleUser): string;
62
71
  process(event: SDKEvent): string;
63
- setOptOut(isOptingOut: boolean): string | KitMappedMethodFailure;
72
+ setOptOut(isOptingOut: boolean): string;
64
73
  removeUserAttribute(key: string): string;
65
74
  setUserAttribute(key: string, value: string): string;
66
75
  setUserIdentity(id: UserIdentityId, type: UserIdentityType): void;
@@ -69,9 +78,6 @@ export interface ConfiguredKit
69
78
  isSandbox: boolean;
70
79
  hasSandbox: boolean;
71
80
  }
72
- export interface KitMappedMethodFailure {
73
- error: string;
74
- }
75
81
 
76
82
  export type UserIdentityId = string;
77
83
  export type UserIdentityType = number;
@@ -125,6 +125,13 @@ const integrationMapping: IntegrationIdMapping = {
125
125
  mappedKey: 'tiktok_cookie_id',
126
126
  output: IntegrationOutputs.PARTNER_IDENTITIES,
127
127
  },
128
+
129
+ // Snapchat
130
+ // https://businesshelp.snapchat.com/s/article/troubleshooting-click-id?language=en_US
131
+ ScCid: {
132
+ mappedKey: 'SnapchatConversions.ClickId',
133
+ output: IntegrationOutputs.CUSTOM_FLAGS,
134
+ },
128
135
  };
129
136
 
130
137
  export default class IntegrationCapture {
@@ -49,6 +49,7 @@ import { IECommerce } from './ecommerce.interfaces';
49
49
  import { INativeSdkHelpers } from './nativeSdkHelpers.interfaces';
50
50
  import { IPersistence } from './persistence.interfaces';
51
51
  import ForegroundTimer from './foregroundTimeTracker';
52
+ import RoktManager from './roktManager';
52
53
 
53
54
  export interface IErrorLogMessage {
54
55
  message?: string;
@@ -80,6 +81,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
80
81
  _IntegrationCapture: IntegrationCapture;
81
82
  _NativeSdkHelpers: INativeSdkHelpers;
82
83
  _Persistence: IPersistence;
84
+ _RoktManager: RoktManager;
83
85
  _SessionManager: ISessionManager;
84
86
  _ServerModel: IServerModel;
85
87
  _Store: IStore;
@@ -126,13 +128,14 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan
126
128
  forwarderConstructors: [],
127
129
  };
128
130
  this._IntegrationCapture = new IntegrationCapture();
131
+ this._RoktManager = new RoktManager();
129
132
 
130
133
  // required for forwarders once they reference the mparticle instance
131
134
  this.IdentityType = IdentityType;
132
- this.EventType = EventType as unknown as valueof<typeof EventType>;
133
- this.CommerceEventType = CommerceEventType as unknown as valueof<typeof CommerceEventType>;
134
- this.PromotionType = PromotionActionType as unknown as valueof<typeof PromotionActionType>;
135
- this.ProductActionType = ProductActionType as unknown as valueof<typeof ProductActionType>;
135
+ this.EventType = EventType;
136
+ this.CommerceEventType = CommerceEventType;
137
+ this.PromotionType = PromotionActionType;
138
+ this.ProductActionType = ProductActionType;
136
139
 
137
140
 
138
141
  this._Identity = new Identity(this);