@mparticle/web-sdk 2.21.1 → 2.22.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.common.js +40 -34
- package/dist/mparticle.esm.js +40 -34
- package/dist/mparticle.js +250 -157
- package/package.json +3 -2
- package/src/apiClient.ts +8 -71
- package/src/configAPIClient.ts +19 -10
- package/src/consent.ts +6 -9
- package/src/constants.ts +1 -1
- package/src/forwarders.js +32 -21
- package/src/helpers.js +11 -6
- package/src/identity.js +27 -40
- package/src/kitFilterHelper.ts +47 -0
- package/src/mockBatchCreator.ts +2 -0
- package/src/mp-instance.js +0 -12
- package/src/mparticle-instance-manager.js +3 -0
- package/src/sdkRuntimeModels.ts +2 -1
- package/src/sideloadedKit.ts +124 -0
- package/src/store.ts +0 -7
- package/src/types.interfaces.ts +52 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mparticle/web-sdk",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.22.0",
|
|
4
4
|
"description": "mParticle core SDK for web applications",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"keywords": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"test:integrations:module": "npm run test:integrations:module:webpack && npm run test:integrations:module:rollup",
|
|
47
47
|
"test:integrations:module:webpack": "npm run build:webpack:module && npm run test:karma:webpack:module",
|
|
48
48
|
"test:integrations:module:rollup": "npm run build:rollup:module && npm run test:karma:rollup:module",
|
|
49
|
-
"test:requirejs": "npm run test:requirejs:before && npm run test:requirejs:after",
|
|
49
|
+
"test:requirejs": "npm run build && npm run test:requirejs:before && npm run test:requirejs:after",
|
|
50
50
|
"test:requirejs:before": "cross-env FILE_ORDER=before_mp karma start test/integrations/requirejs/karma.requirejs.config.js",
|
|
51
51
|
"test:requirejs:after": "cross-env FILE_ORDER=after_mp karma start test/integrations/requirejs/karma.requirejs.config.js",
|
|
52
52
|
"test:karma:webpack:cjs": "cross-env BUNDLER=webpack karma start test/integrations/cjs/karma.webpack.config.js",
|
|
@@ -108,6 +108,7 @@
|
|
|
108
108
|
"fetch-mock": "^7.5.1",
|
|
109
109
|
"gts": "^3.1.0",
|
|
110
110
|
"jest": "^29.5.0",
|
|
111
|
+
"jest-environment-jsdom": "^29.5.0",
|
|
111
112
|
"karma": "^6.3.2",
|
|
112
113
|
"karma-chai": "^0.1.0",
|
|
113
114
|
"karma-chrome-launcher": "^3.1.0",
|
package/src/apiClient.ts
CHANGED
|
@@ -8,17 +8,14 @@ import {
|
|
|
8
8
|
SDKEvent,
|
|
9
9
|
} from './sdkRuntimeModels';
|
|
10
10
|
import KitBlocker from './kitBlocking';
|
|
11
|
-
import { Dictionary, getRampNumber } from './utils';
|
|
11
|
+
import { Dictionary, getRampNumber, isEmpty } from './utils';
|
|
12
12
|
import { IUploadObject } from './serverModel';
|
|
13
13
|
|
|
14
|
-
const Messages = Constants.Messages;
|
|
15
|
-
|
|
16
14
|
export type ForwardingStatsData = Dictionary<any>;
|
|
17
15
|
|
|
18
16
|
export interface IAPIClient {
|
|
19
17
|
uploader: BatchUploader | null;
|
|
20
18
|
queueEventForBatchUpload: (event: SDKEvent) => void;
|
|
21
|
-
shouldEnableBatching: () => boolean;
|
|
22
19
|
processQueuedEvents: () => void;
|
|
23
20
|
appendUserInfoToEvents: (user: MParticleUser, events: SDKEvent[]) => void;
|
|
24
21
|
sendEventToServer: (event: SDKEvent, _options?: Dictionary<any>) => void;
|
|
@@ -55,22 +52,6 @@ export default function APIClient(
|
|
|
55
52
|
mpInstance._Persistence.update();
|
|
56
53
|
};
|
|
57
54
|
|
|
58
|
-
this.shouldEnableBatching = function() {
|
|
59
|
-
// Returns a string of a number that must be parsed
|
|
60
|
-
// Invalid strings will be parsed to NaN which is falsey
|
|
61
|
-
const eventsV3Percentage = parseInt(
|
|
62
|
-
mpInstance._Helpers.getFeatureFlag(Constants.FeatureFlags.EventsV3),
|
|
63
|
-
10
|
|
64
|
-
);
|
|
65
|
-
|
|
66
|
-
if (!eventsV3Percentage) {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const rampNumber = getRampNumber(mpInstance._Store.deviceId);
|
|
71
|
-
return eventsV3Percentage >= rampNumber;
|
|
72
|
-
};
|
|
73
|
-
|
|
74
55
|
this.processQueuedEvents = function() {
|
|
75
56
|
let mpid,
|
|
76
57
|
currentUser = mpInstance.Identity.getCurrentUser();
|
|
@@ -135,15 +116,15 @@ export default function APIClient(
|
|
|
135
116
|
|
|
136
117
|
this.processQueuedEvents();
|
|
137
118
|
|
|
138
|
-
if (event
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
119
|
+
if (isEmpty(event)) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (options.shouldUploadEvent) {
|
|
124
|
+
this.queueEventForBatchUpload(event);
|
|
144
125
|
}
|
|
145
126
|
|
|
146
|
-
if (event
|
|
127
|
+
if (event.EventName !== Types.MessageType.AppStateTransition) {
|
|
147
128
|
if (kitBlocker && kitBlocker.kitBlockingEnabled) {
|
|
148
129
|
event = kitBlocker.createBlockedEvent(event);
|
|
149
130
|
}
|
|
@@ -156,50 +137,6 @@ export default function APIClient(
|
|
|
156
137
|
}
|
|
157
138
|
};
|
|
158
139
|
|
|
159
|
-
this.sendSingleEventToServer = function(event) {
|
|
160
|
-
if (event.EventDataType === Types.MessageType.Media) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
163
|
-
let xhr,
|
|
164
|
-
xhrCallback = function() {
|
|
165
|
-
if (xhr.readyState === 4) {
|
|
166
|
-
mpInstance.Logger.verbose(
|
|
167
|
-
'Received ' + xhr.statusText + ' from server'
|
|
168
|
-
);
|
|
169
|
-
mpInstance._Persistence.update();
|
|
170
|
-
}
|
|
171
|
-
};
|
|
172
|
-
|
|
173
|
-
if (!event) {
|
|
174
|
-
mpInstance.Logger.error(Messages.ErrorMessages.EventEmpty);
|
|
175
|
-
return;
|
|
176
|
-
}
|
|
177
|
-
mpInstance.Logger.verbose(Messages.InformationMessages.SendHttp);
|
|
178
|
-
xhr = mpInstance._Helpers.createXHR(xhrCallback);
|
|
179
|
-
if (xhr) {
|
|
180
|
-
try {
|
|
181
|
-
xhr.open(
|
|
182
|
-
'post',
|
|
183
|
-
mpInstance._Helpers.createServiceUrl(
|
|
184
|
-
mpInstance._Store.SDKConfig.v2SecureServiceUrl,
|
|
185
|
-
mpInstance._Store.devToken
|
|
186
|
-
) + '/Events'
|
|
187
|
-
);
|
|
188
|
-
xhr.send(
|
|
189
|
-
JSON.stringify(
|
|
190
|
-
mpInstance._ServerModel.convertEventToV2DTO(
|
|
191
|
-
event as IUploadObject
|
|
192
|
-
)
|
|
193
|
-
)
|
|
194
|
-
);
|
|
195
|
-
} catch (e) {
|
|
196
|
-
mpInstance.Logger.error(
|
|
197
|
-
'Error sending event to mParticle servers. ' + e
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
};
|
|
202
|
-
|
|
203
140
|
this.sendBatchForwardingStatsToServer = function(forwardingStatsData, xhr) {
|
|
204
141
|
let url;
|
|
205
142
|
let data;
|
package/src/configAPIClient.ts
CHANGED
|
@@ -14,7 +14,7 @@ export type SDKCompleteInitCallback = (
|
|
|
14
14
|
mpInstance: MParticleWebSDK
|
|
15
15
|
) => void;
|
|
16
16
|
|
|
17
|
-
export interface IKitConfigs {
|
|
17
|
+
export interface IKitConfigs extends IKitFilterSettings {
|
|
18
18
|
name: string;
|
|
19
19
|
moduleId: number;
|
|
20
20
|
isDebug: boolean;
|
|
@@ -22,30 +22,39 @@ export interface IKitConfigs {
|
|
|
22
22
|
isDebugString: BooleanStringLowerCase;
|
|
23
23
|
hasDebugString: BooleanStringLowerCase;
|
|
24
24
|
settings: Dictionary;
|
|
25
|
+
eventSubscriptionId: number;
|
|
26
|
+
excludeAnonymousUser: boolean;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface IKitFilterSettings {
|
|
30
|
+
eventTypeFilters: number[];
|
|
31
|
+
eventNameFilters: number[];
|
|
25
32
|
screenNameFilters: number[];
|
|
26
33
|
screenAttributeFilters: number[];
|
|
27
34
|
userIdentityFilters: number[];
|
|
28
35
|
userAttributeFilters: number[];
|
|
29
|
-
eventNameFilters: number[];
|
|
30
|
-
eventTypeFilters: number[];
|
|
31
36
|
attributeFilters: number[];
|
|
32
|
-
filteringEventAttributeValue
|
|
33
|
-
filteringUserAttributeValue
|
|
34
|
-
filteringConsentRuleValues
|
|
37
|
+
filteringEventAttributeValue?: IFilteringEventAttributeValue;
|
|
38
|
+
filteringUserAttributeValue?: IFilteringUserAttributeValue;
|
|
39
|
+
filteringConsentRuleValues?: IFilteringConsentRuleValues;
|
|
35
40
|
consentRegulationFilters: number[];
|
|
36
41
|
consentRegulationPurposeFilters: number[];
|
|
37
42
|
messageTypeFilters: number[];
|
|
38
43
|
messageTypeStateFilters: number[];
|
|
39
|
-
eventSubscriptionId: number;
|
|
40
|
-
excludeAnonymousUser: boolean;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
export interface
|
|
46
|
+
export interface IFilteringEventAttributeValue {
|
|
44
47
|
eventAttributeName: string;
|
|
45
48
|
eventAttributeValue: string;
|
|
46
49
|
includeOnMatch: boolean
|
|
47
50
|
}
|
|
48
|
-
|
|
51
|
+
|
|
52
|
+
export interface IFilteringUserAttributeValue {
|
|
53
|
+
userAttributeName: string;
|
|
54
|
+
userAttributeValue: string;
|
|
55
|
+
includeOnMatch: boolean
|
|
56
|
+
}
|
|
57
|
+
export interface IFilteringConsentRuleValues {
|
|
49
58
|
includeOnMatch: boolean;
|
|
50
59
|
values: IConsentRuleValue[];
|
|
51
60
|
}
|
package/src/consent.ts
CHANGED
|
@@ -6,9 +6,10 @@ import {
|
|
|
6
6
|
} from '@mparticle/web-sdk';
|
|
7
7
|
import { MParticleUser, MParticleWebSDK } from './sdkRuntimeModels';
|
|
8
8
|
import { Dictionary, isObject } from './utils';
|
|
9
|
+
import KitFilterHelper from './kitFilterHelper';
|
|
10
|
+
import Constants from './constants';
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
export const CCPAPurpose = 'data_sale_opt_out' as const;
|
|
12
|
+
const { CCPAPurpose } = Constants;
|
|
12
13
|
|
|
13
14
|
export interface IMinifiedConsentJSONObject {
|
|
14
15
|
gdpr?: Dictionary<IPrivacyV2DTO>;
|
|
@@ -144,15 +145,13 @@ export default function Consent(this: IConsent, mpInstance: MParticleWebSDK) {
|
|
|
144
145
|
// GDPR - '1' + purpose name
|
|
145
146
|
// CCPA - '2data_sale_opt_out' (there is only 1 purpose of data_sale_opt_out for CCPA)
|
|
146
147
|
const GDPRConsentHashPrefix = '1';
|
|
147
|
-
const
|
|
148
|
+
const CCPAHashPrefix = '2';
|
|
148
149
|
|
|
149
150
|
const gdprConsentState = consentState.getGDPRConsentState();
|
|
150
151
|
if (gdprConsentState) {
|
|
151
152
|
for (const purpose in gdprConsentState) {
|
|
152
153
|
if (gdprConsentState.hasOwnProperty(purpose)) {
|
|
153
|
-
purposeHash =
|
|
154
|
-
.generateHash(GDPRConsentHashPrefix + purpose)
|
|
155
|
-
.toString();
|
|
154
|
+
purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(GDPRConsentHashPrefix, purpose);
|
|
156
155
|
purposeHashes[purposeHash] =
|
|
157
156
|
gdprConsentState[purpose].Consented;
|
|
158
157
|
}
|
|
@@ -160,9 +159,7 @@ export default function Consent(this: IConsent, mpInstance: MParticleWebSDK) {
|
|
|
160
159
|
}
|
|
161
160
|
const CCPAConsentState = consentState.getCCPAConsentState();
|
|
162
161
|
if (CCPAConsentState) {
|
|
163
|
-
purposeHash =
|
|
164
|
-
.generateHash(CCPAHashString)
|
|
165
|
-
.toString();
|
|
162
|
+
purposeHash = KitFilterHelper.hashConsentPurposeConditionalForwarding(CCPAHashPrefix, CCPAPurpose);
|
|
166
163
|
purposeHashes[purposeHash] = CCPAConsentState.Consented;
|
|
167
164
|
}
|
|
168
165
|
}
|
package/src/constants.ts
CHANGED
|
@@ -159,11 +159,11 @@ const Constants = {
|
|
|
159
159
|
},
|
|
160
160
|
FeatureFlags: {
|
|
161
161
|
ReportBatching: 'reportBatching',
|
|
162
|
-
EventsV3: 'eventsV3',
|
|
163
162
|
EventBatchingIntervalMillis: 'eventBatchingIntervalMillis',
|
|
164
163
|
OfflineStorage: 'offlineStorage',
|
|
165
164
|
},
|
|
166
165
|
DefaultInstance: 'default_instance',
|
|
166
|
+
CCPAPurpose: 'data_sale_opt_out'
|
|
167
167
|
} as const;
|
|
168
168
|
|
|
169
169
|
export default Constants;
|
package/src/forwarders.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Types from './types';
|
|
2
2
|
import filteredMparticleUser from './filteredMparticleUser';
|
|
3
3
|
import { isEmpty } from './utils';
|
|
4
|
+
import KitFilterHelper from './kitFilterHelper';
|
|
4
5
|
|
|
5
6
|
export default function Forwarders(mpInstance, kitBlocker) {
|
|
6
7
|
var self = this;
|
|
@@ -110,12 +111,12 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
110
111
|
) {
|
|
111
112
|
for (var attrName in userAttributes) {
|
|
112
113
|
if (userAttributes.hasOwnProperty(attrName)) {
|
|
113
|
-
attrHash =
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
valueHash =
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
attrHash = KitFilterHelper.hashAttributeConditionalForwarding(
|
|
115
|
+
attrName
|
|
116
|
+
);
|
|
117
|
+
valueHash = KitFilterHelper.hashAttributeConditionalForwarding(
|
|
118
|
+
userAttributes[attrName]
|
|
119
|
+
);
|
|
119
120
|
|
|
120
121
|
if (
|
|
121
122
|
attrHash === filterObject.userAttributeName &&
|
|
@@ -177,7 +178,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
177
178
|
if (
|
|
178
179
|
mpInstance._Helpers.inArray(
|
|
179
180
|
filterList,
|
|
180
|
-
|
|
181
|
+
KitFilterHelper.hashUserIdentity(
|
|
182
|
+
userIdentity.Type
|
|
183
|
+
)
|
|
181
184
|
)
|
|
182
185
|
) {
|
|
183
186
|
event.UserIdentities.splice(i, 1);
|
|
@@ -198,8 +201,10 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
198
201
|
|
|
199
202
|
for (var attrName in event.EventAttributes) {
|
|
200
203
|
if (event.EventAttributes.hasOwnProperty(attrName)) {
|
|
201
|
-
hash =
|
|
202
|
-
event.EventCategory
|
|
204
|
+
hash = KitFilterHelper.hashEventAttributeKey(
|
|
205
|
+
event.EventCategory,
|
|
206
|
+
event.EventName,
|
|
207
|
+
attrName
|
|
203
208
|
);
|
|
204
209
|
|
|
205
210
|
if (mpInstance._Helpers.inArray(filterList, hash)) {
|
|
@@ -227,10 +232,11 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
227
232
|
!mpInstance._Store.webviewBridgeEnabled &&
|
|
228
233
|
mpInstance._Store.activeForwarders
|
|
229
234
|
) {
|
|
230
|
-
hashedEventName =
|
|
231
|
-
event.
|
|
235
|
+
hashedEventName = KitFilterHelper.hashEventName(
|
|
236
|
+
event.EventName,
|
|
237
|
+
event.EventCategory
|
|
232
238
|
);
|
|
233
|
-
hashedEventType =
|
|
239
|
+
hashedEventType = KitFilterHelper.hashEventType(
|
|
234
240
|
event.EventCategory
|
|
235
241
|
);
|
|
236
242
|
|
|
@@ -261,9 +267,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
261
267
|
if (event.EventAttributes) {
|
|
262
268
|
for (var prop in event.EventAttributes) {
|
|
263
269
|
var hashedEventAttributeName;
|
|
264
|
-
hashedEventAttributeName =
|
|
265
|
-
|
|
266
|
-
|
|
270
|
+
hashedEventAttributeName = KitFilterHelper.hashAttributeConditionalForwarding(
|
|
271
|
+
prop
|
|
272
|
+
);
|
|
267
273
|
|
|
268
274
|
if (
|
|
269
275
|
hashedEventAttributeName ===
|
|
@@ -273,11 +279,9 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
273
279
|
) {
|
|
274
280
|
foundProp = {
|
|
275
281
|
name: hashedEventAttributeName,
|
|
276
|
-
value:
|
|
277
|
-
.
|
|
278
|
-
|
|
279
|
-
)
|
|
280
|
-
.toString(),
|
|
282
|
+
value: KitFilterHelper.hashAttributeConditionalForwarding(
|
|
283
|
+
event.EventAttributes[prop]
|
|
284
|
+
),
|
|
281
285
|
};
|
|
282
286
|
}
|
|
283
287
|
|
|
@@ -620,7 +624,14 @@ export default function Forwarders(mpInstance, kitBlocker) {
|
|
|
620
624
|
// which is typed { kits: Dictionary<constructor> }.
|
|
621
625
|
// The constructors are keyed by the name of the kit.
|
|
622
626
|
config.sideloadedKits.forEach(function(sideloadedKit) {
|
|
623
|
-
|
|
627
|
+
try {
|
|
628
|
+
sideloadedKit.kitInstance.register(sideloadedKits);
|
|
629
|
+
} catch (e) {
|
|
630
|
+
console.error(
|
|
631
|
+
'Error registering sideloaded kit ' +
|
|
632
|
+
sideloadedKit.kitInstance.name
|
|
633
|
+
);
|
|
634
|
+
}
|
|
624
635
|
});
|
|
625
636
|
|
|
626
637
|
// Then configure each kit
|
package/src/helpers.js
CHANGED
|
@@ -2,6 +2,7 @@ import Types from './types';
|
|
|
2
2
|
import Constants from './constants';
|
|
3
3
|
import * as utils from './utils';
|
|
4
4
|
import Validators from './validators';
|
|
5
|
+
import KitFilterHelper from './kitFilterHelper';
|
|
5
6
|
|
|
6
7
|
var StorageNames = Constants.StorageNames;
|
|
7
8
|
|
|
@@ -306,13 +307,13 @@ export default function Helpers(mpInstance) {
|
|
|
306
307
|
userIdentitiesObject,
|
|
307
308
|
filterList
|
|
308
309
|
) {
|
|
309
|
-
|
|
310
|
+
const filteredUserIdentities = {};
|
|
310
311
|
|
|
311
312
|
if (userIdentitiesObject && Object.keys(userIdentitiesObject).length) {
|
|
312
|
-
for (
|
|
313
|
+
for (const userIdentityName in userIdentitiesObject) {
|
|
313
314
|
if (userIdentitiesObject.hasOwnProperty(userIdentityName)) {
|
|
314
|
-
|
|
315
|
-
userIdentityName
|
|
315
|
+
const userIdentityType = KitFilterHelper.hashUserIdentity(
|
|
316
|
+
Types.IdentityType.getIdentityType(userIdentityName)
|
|
316
317
|
);
|
|
317
318
|
if (!self.inArray(filterList, userIdentityType)) {
|
|
318
319
|
filteredUserIdentities[userIdentityName] =
|
|
@@ -331,7 +332,9 @@ export default function Helpers(mpInstance) {
|
|
|
331
332
|
if (userAttributes && Object.keys(userAttributes).length) {
|
|
332
333
|
for (var userAttribute in userAttributes) {
|
|
333
334
|
if (userAttributes.hasOwnProperty(userAttribute)) {
|
|
334
|
-
|
|
335
|
+
const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
|
|
336
|
+
userAttribute
|
|
337
|
+
);
|
|
335
338
|
if (!self.inArray(filterList, hashedUserAttribute)) {
|
|
336
339
|
filteredUserAttributes[userAttribute] =
|
|
337
340
|
userAttributes[userAttribute];
|
|
@@ -344,7 +347,9 @@ export default function Helpers(mpInstance) {
|
|
|
344
347
|
};
|
|
345
348
|
|
|
346
349
|
this.isFilteredUserAttribute = function(userAttributeKey, filterList) {
|
|
347
|
-
const hashedUserAttribute =
|
|
350
|
+
const hashedUserAttribute = KitFilterHelper.hashUserAttribute(
|
|
351
|
+
userAttributeKey
|
|
352
|
+
);
|
|
348
353
|
return filterList && self.inArray(filterList, hashedUserAttribute);
|
|
349
354
|
};
|
|
350
355
|
|
package/src/identity.js
CHANGED
|
@@ -1058,42 +1058,36 @@ export default function Identity(mpInstance) {
|
|
|
1058
1058
|
mpInstance._Persistence.savePersistence(cookies, mpid);
|
|
1059
1059
|
}
|
|
1060
1060
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
previousUserAttributeValue[i] !==
|
|
1079
|
-
newValue[i]
|
|
1080
|
-
) {
|
|
1081
|
-
userAttributeChange = true;
|
|
1082
|
-
break;
|
|
1083
|
-
}
|
|
1061
|
+
// If the new attributeList length is different previous, then there is a change event.
|
|
1062
|
+
// Loop through new attributes list, see if they are all in the same index as previous user attributes list
|
|
1063
|
+
// If there are any changes, break, and immediately send a userAttributeChangeEvent with full array as a value
|
|
1064
|
+
if (
|
|
1065
|
+
!previousUserAttributeValue ||
|
|
1066
|
+
!Array.isArray(previousUserAttributeValue)
|
|
1067
|
+
) {
|
|
1068
|
+
userAttributeChange = true;
|
|
1069
|
+
} else if (
|
|
1070
|
+
newValue.length !== previousUserAttributeValue.length
|
|
1071
|
+
) {
|
|
1072
|
+
userAttributeChange = true;
|
|
1073
|
+
} else {
|
|
1074
|
+
for (var i = 0; i < newValue.length; i++) {
|
|
1075
|
+
if (previousUserAttributeValue[i] !== newValue[i]) {
|
|
1076
|
+
userAttributeChange = true;
|
|
1077
|
+
break;
|
|
1084
1078
|
}
|
|
1085
1079
|
}
|
|
1080
|
+
}
|
|
1086
1081
|
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
}
|
|
1082
|
+
if (userAttributeChange) {
|
|
1083
|
+
self.sendUserAttributeChangeEvent(
|
|
1084
|
+
key,
|
|
1085
|
+
newValue,
|
|
1086
|
+
previousUserAttributeValue,
|
|
1087
|
+
isNewAttribute,
|
|
1088
|
+
false,
|
|
1089
|
+
this
|
|
1090
|
+
);
|
|
1097
1091
|
}
|
|
1098
1092
|
|
|
1099
1093
|
mpInstance._Forwarders.initForwarders(
|
|
@@ -1716,10 +1710,6 @@ export default function Identity(mpInstance) {
|
|
|
1716
1710
|
) {
|
|
1717
1711
|
var currentUserInMemory, userIdentityChangeEvent;
|
|
1718
1712
|
|
|
1719
|
-
if (!mpInstance._APIClient.shouldEnableBatching()) {
|
|
1720
|
-
return;
|
|
1721
|
-
}
|
|
1722
|
-
|
|
1723
1713
|
if (!mpid) {
|
|
1724
1714
|
if (method !== 'modify') {
|
|
1725
1715
|
return;
|
|
@@ -1785,9 +1775,6 @@ export default function Identity(mpInstance) {
|
|
|
1785
1775
|
deleted,
|
|
1786
1776
|
user
|
|
1787
1777
|
) {
|
|
1788
|
-
if (!mpInstance._APIClient.shouldEnableBatching()) {
|
|
1789
|
-
return;
|
|
1790
|
-
}
|
|
1791
1778
|
var userAttributeChangeEvent = self.createUserAttributeChange(
|
|
1792
1779
|
attributeKey,
|
|
1793
1780
|
newUserAttributeValue,
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { generateHash } from "./utils";
|
|
2
|
+
// TODO: https://mparticle-eng.atlassian.net/browse/SQDSDKS-5381
|
|
3
|
+
import { EventTypeEnum, IdentityType } from "./types.interfaces";
|
|
4
|
+
import Constants from './constants';
|
|
5
|
+
|
|
6
|
+
export default class KitFilterHelper {
|
|
7
|
+
static hashEventType(eventType: EventTypeEnum): number {
|
|
8
|
+
return generateHash(eventType as unknown as string);
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
static hashEventName(eventName: string, eventType: EventTypeEnum): number {
|
|
12
|
+
return generateHash(eventType + eventName);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
static hashEventAttributeKey(eventType: EventTypeEnum, eventName: string, customAttributeName: string): number {
|
|
16
|
+
return generateHash(eventType + eventName + customAttributeName);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static hashUserAttribute(userAttributeKey: string): number {
|
|
20
|
+
return generateHash(userAttributeKey);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// User Identities are not actually hashed, this method is named this way to
|
|
24
|
+
// be consistent with the filter class. UserIdentityType is also a number
|
|
25
|
+
static hashUserIdentity(userIdentity: IdentityType): IdentityType {
|
|
26
|
+
return userIdentity;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
static hashConsentPurpose(prefix: string, purpose: string){
|
|
30
|
+
return generateHash(prefix + purpose)
|
|
31
|
+
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// The methods below are for conditional forwarding, a type of filter
|
|
35
|
+
// hashAttributeCondiitonalForwarding is used for both User and Event
|
|
36
|
+
// attribute keys and attribute values
|
|
37
|
+
// The backend returns the hashes as strings for conditional forwarding
|
|
38
|
+
// but returns "regular" filters as arrays of numbers
|
|
39
|
+
// See IFilteringEventAttributeValue in configApiClient.ts as an example
|
|
40
|
+
static hashAttributeConditionalForwarding(attribute: string): string {
|
|
41
|
+
return generateHash(attribute).toString();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
static hashConsentPurposeConditionalForwarding(prefix: string, purpose: string): string {
|
|
45
|
+
return this.hashConsentPurpose(prefix, purpose).toString();
|
|
46
|
+
}
|
|
47
|
+
}
|
package/src/mockBatchCreator.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { SDKEvent, BaseEvent, MParticleWebSDK } from './sdkRuntimeModels';
|
|
|
5
5
|
import { convertEvents } from './sdkToEventsApiConverter';
|
|
6
6
|
import * as EventsApi from '@mparticle/event-models';
|
|
7
7
|
import { Batch } from '@mparticle/event-models';
|
|
8
|
+
import { IMPSideloadedKit} from './sideloadedKit';
|
|
8
9
|
|
|
9
10
|
const mockFunction = function() {
|
|
10
11
|
return null;
|
|
@@ -31,6 +32,7 @@ export default class _BatchValidator {
|
|
|
31
32
|
},
|
|
32
33
|
_resetForTests: mockFunction,
|
|
33
34
|
_APIClient: null,
|
|
35
|
+
MPSideloadedKit: null,
|
|
34
36
|
_Consent: null,
|
|
35
37
|
_Forwarders: null,
|
|
36
38
|
_NativeSdkHelpers: null,
|
package/src/mp-instance.js
CHANGED
|
@@ -1288,18 +1288,6 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
|
|
|
1288
1288
|
mpInstance._APIClient = new APIClient(mpInstance, kitBlocker);
|
|
1289
1289
|
mpInstance._Forwarders = new Forwarders(mpInstance, kitBlocker);
|
|
1290
1290
|
if (config.flags) {
|
|
1291
|
-
if (config.flags.hasOwnProperty(Constants.FeatureFlags.EventsV3)) {
|
|
1292
|
-
// TODO: Remove this after 8/12/2022
|
|
1293
|
-
if (config.flags[Constants.FeatureFlags.EventsV3] !== '100') {
|
|
1294
|
-
var message =
|
|
1295
|
-
'mParticle will be enabling Event Batching for all customers on July 12, 2022. ' +
|
|
1296
|
-
'For more details, please see our docs: https://docs.mparticle.com/developers/sdk/web/getting-started/';
|
|
1297
|
-
mpInstance.Logger.warning(message);
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
mpInstance._Store.SDKConfig.flags[Constants.FeatureFlags.EventsV3] =
|
|
1301
|
-
config.flags[Constants.FeatureFlags.EventsV3];
|
|
1302
|
-
}
|
|
1303
1291
|
if (
|
|
1304
1292
|
config.flags.hasOwnProperty(
|
|
1305
1293
|
Constants.FeatureFlags.EventBatchingIntervalMillis
|
|
@@ -3,6 +3,7 @@ import Types from './types';
|
|
|
3
3
|
import Constants from './constants';
|
|
4
4
|
import mParticleInstance from './mp-instance.js';
|
|
5
5
|
import _BatchValidator from './mockBatchCreator';
|
|
6
|
+
import MPSideloadedKit from './sideloadedKit';
|
|
6
7
|
|
|
7
8
|
if (!Array.prototype.forEach) {
|
|
8
9
|
Array.prototype.forEach = Polyfill.forEach;
|
|
@@ -30,6 +31,8 @@ function mParticle() {
|
|
|
30
31
|
this.CommerceEventType = Types.CommerceEventType;
|
|
31
32
|
this.PromotionType = Types.PromotionActionType;
|
|
32
33
|
this.ProductActionType = Types.ProductActionType;
|
|
34
|
+
this.MPSideloadedKit = MPSideloadedKit;
|
|
35
|
+
|
|
33
36
|
if (typeof window !== 'undefined') {
|
|
34
37
|
this.isIOS =
|
|
35
38
|
window.mParticle && window.mParticle.isIOS
|
package/src/sdkRuntimeModels.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { IServerModel } from './serverModel';
|
|
|
8
8
|
import { IKitConfigs } from './configAPIClient';
|
|
9
9
|
import { SDKConsentApi, SDKConsentState } from './consent';
|
|
10
10
|
import { IPersistence } from './persistence.interfaces';
|
|
11
|
-
|
|
11
|
+
import { IMPSideloadedKit } from './sideloadedKit';
|
|
12
12
|
// TODO: Resolve this with version in @mparticle/web-sdk
|
|
13
13
|
export type SDKEventCustomFlags = Dictionary<any>;
|
|
14
14
|
|
|
@@ -130,6 +130,7 @@ export interface MParticleWebSDK {
|
|
|
130
130
|
addForwarder(mockForwarder: MPForwarder): void;
|
|
131
131
|
Identity: SDKIdentityApi;
|
|
132
132
|
Logger: SDKLoggerApi;
|
|
133
|
+
MPSideloadedKit: IMPSideloadedKit;
|
|
133
134
|
_APIClient: any; // TODO: Set up API Client
|
|
134
135
|
_Store: IStore;
|
|
135
136
|
_Forwarders: any;
|