@mparticle/web-sdk
Advanced tools
Comparing version 2.11.5 to 2.11.8
@@ -5,2 +5,16 @@ ## Releases | ||
#### 2.11.8 - 2020-03-16 | ||
- Don't set empty TransactionAttribute fields | ||
#### 2.11.7 - 2020-03-04 | ||
- Deprecate removeCCPAState in favor of removeCCPAConsentState | ||
- Feat - XHR Support for Batching | ||
#### 2.11.6 - 2020-02-26 | ||
- Migrate network tests from local Mockhttprequest to Sinon | ||
- Bugfix - Flush eventQueue after identity callback | ||
#### 2.11.5 - 2020-02-12 | ||
@@ -7,0 +21,0 @@ |
{ | ||
"name": "@mparticle/web-sdk", | ||
"version": "2.11.5", | ||
"version": "2.11.8", | ||
"description": "mParticle core SDK for web applications", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
@@ -22,6 +22,2 @@ import Constants from './constants'; | ||
this.shouldEnableBatching = function() { | ||
if (!window.fetch) { | ||
return false; | ||
} | ||
// Returns a string of a number that must be parsed | ||
@@ -124,3 +120,3 @@ // Invalid strings will be parsed to NaN which is falsey | ||
); | ||
self.parseEventResponse(xhr.responseText); | ||
mpInstance._Persistence.update(); | ||
} | ||
@@ -160,56 +156,2 @@ }; | ||
this.parseEventResponse = function(responseText) { | ||
var now = new Date(), | ||
settings, | ||
prop, | ||
fullProp; | ||
if (!responseText) { | ||
return; | ||
} | ||
try { | ||
mpInstance.Logger.verbose('Parsing response from server'); | ||
settings = JSON.parse(responseText); | ||
if (settings && settings.Store) { | ||
mpInstance.Logger.verbose( | ||
'Parsed store from response, updating local settings' | ||
); | ||
if (!mpInstance._Store.serverSettings) { | ||
mpInstance._Store.serverSettings = {}; | ||
} | ||
for (prop in settings.Store) { | ||
if (!settings.Store.hasOwnProperty(prop)) { | ||
continue; | ||
} | ||
fullProp = settings.Store[prop]; | ||
if (!fullProp.Value || new Date(fullProp.Expires) < now) { | ||
// This setting should be deleted from the local store if it exists | ||
if ( | ||
mpInstance._Store.serverSettings.hasOwnProperty( | ||
prop | ||
) | ||
) { | ||
delete mpInstance._Store.serverSettings[prop]; | ||
} | ||
} else { | ||
// This is a valid setting | ||
mpInstance._Store.serverSettings[prop] = fullProp; | ||
} | ||
} | ||
} | ||
mpInstance._Persistence.update(); | ||
} catch (e) { | ||
mpInstance.Logger.error( | ||
'Error parsing JSON response from server: ' + e.name | ||
); | ||
} | ||
}; | ||
this.sendAliasRequest = function(aliasRequest, callback) { | ||
@@ -216,0 +158,0 @@ var xhr, |
@@ -9,2 +9,3 @@ import { Batch } from '@mparticle/event-models'; | ||
import { convertEvents } from './sdkToEventsApiConverter'; | ||
import Types from './types'; | ||
@@ -43,3 +44,2 @@ export class BatchUploader { | ||
}, this.uploadIntervalMillis); | ||
this.addEventListeners(); | ||
@@ -50,8 +50,8 @@ } | ||
const _this = this; | ||
window.addEventListener('beforeunload', () => { | ||
window.onbeforeunload = () => { | ||
_this.prepareAndUpload(false, _this.isBeaconAvailable()); | ||
}); | ||
window.addEventListener('pagehide', () => { | ||
}; | ||
window.onpagehide = () => { | ||
_this.prepareAndUpload(false, _this.isBeaconAvailable()); | ||
}); | ||
}; | ||
} | ||
@@ -78,3 +78,7 @@ | ||
); | ||
if (!this.batchingEnabled) { | ||
if ( | ||
!this.batchingEnabled || | ||
Types.TriggerUploadType[event.EventDataType] | ||
) { | ||
this.prepareAndUpload(false, false); | ||
@@ -166,3 +170,3 @@ } | ||
this.pendingUploads = []; | ||
const remainingUploads = await this.upload( | ||
const remainingUploads: Batch[] = await this.upload( | ||
this.mpInstance.Logger, | ||
@@ -188,2 +192,3 @@ currentUploads, | ||
): Promise<Batch[]> { | ||
let uploader; | ||
if (!uploads || uploads.length < 1) { | ||
@@ -196,3 +201,3 @@ return null; | ||
for (let i = 0; i < uploads.length; i++) { | ||
const settings = { | ||
const fetchPayload: fetchPayload = { | ||
method: 'POST', | ||
@@ -205,14 +210,25 @@ headers: { | ||
}; | ||
try { | ||
if (useBeacon) { | ||
const blob = new Blob([settings.body], { | ||
type: 'text/plain;charset=UTF-8', | ||
}); | ||
navigator.sendBeacon(this.uploadUrl, blob); | ||
} else { | ||
logger.verbose( | ||
`Uploading request ID: ${uploads[i].source_request_id}` | ||
// beacon is only used on onbeforeunload onpagehide events | ||
if (useBeacon && this.isBeaconAvailable()) { | ||
let blob = new Blob([fetchPayload.body], { | ||
type: 'text/plain;charset=UTF-8', | ||
}); | ||
navigator.sendBeacon(this.uploadUrl, blob); | ||
} else { | ||
if (!uploader) { | ||
if (window.fetch) { | ||
uploader = new FetchUploader(this.uploadUrl, logger); | ||
} else { | ||
uploader = new XHRUploader(this.uploadUrl, logger); | ||
} | ||
} | ||
try { | ||
const response = await uploader.upload( | ||
fetchPayload, | ||
uploads, | ||
i | ||
); | ||
const response = await fetch(this.uploadUrl, settings); | ||
if (response.ok) { | ||
if (response.status >= 200 && response.status < 300) { | ||
logger.verbose( | ||
@@ -225,2 +241,5 @@ `Upload success for request ID: ${uploads[i].source_request_id}` | ||
) { | ||
logger.error( | ||
`HTTP error status ${response.status} received` | ||
); | ||
//server error, add back current events and try again later | ||
@@ -235,6 +254,8 @@ return uploads.slice(i, uploads.length); | ||
} | ||
} catch (e) { | ||
logger.error( | ||
`Error sending event to mParticle servers. ${e}` | ||
); | ||
return uploads.slice(i, uploads.length); | ||
} | ||
} catch (e) { | ||
logger.error(`Exception while uploading: ${e}`); | ||
return uploads.slice(i, uploads.length); | ||
} | ||
@@ -245,1 +266,74 @@ } | ||
} | ||
abstract class AsyncUploader { | ||
url: string; | ||
logger: SDKLoggerApi; | ||
constructor(url: string, logger: SDKLoggerApi) { | ||
this.url = url; | ||
this.logger = logger; | ||
} | ||
} | ||
class FetchUploader extends AsyncUploader { | ||
private async upload( | ||
fetchPayload: fetchPayload, | ||
uploads: Batch[], | ||
i: number | ||
) { | ||
const response: XHRResponse = await fetch(this.url, fetchPayload); | ||
return response; | ||
} | ||
} | ||
class XHRUploader extends AsyncUploader { | ||
private async upload( | ||
fetchPayload: fetchPayload, | ||
uploads: Batch[], | ||
i: number | ||
) { | ||
const response: XHRResponse = await this.makeRequest( | ||
this.url, | ||
this.logger, | ||
fetchPayload.body | ||
); | ||
return response; | ||
} | ||
private async makeRequest( | ||
url: string, | ||
logger: SDKLoggerApi, | ||
data: string | ||
): Promise<XMLHttpRequest> { | ||
const xhr: XMLHttpRequest = new XMLHttpRequest(); | ||
return new Promise((resolve, reject) => { | ||
xhr.onreadystatechange = () => { | ||
if (xhr.readyState !== 4) return; | ||
// Process the response | ||
if (xhr.status >= 200 && xhr.status < 300) { | ||
resolve(xhr); | ||
} else { | ||
reject(xhr); | ||
} | ||
}; | ||
xhr.open('post', url); | ||
xhr.send(data); | ||
}); | ||
} | ||
} | ||
interface XHRResponse { | ||
status: number; | ||
statusText?: string; | ||
} | ||
interface fetchPayload { | ||
method: string; | ||
headers: { | ||
Accept: string; | ||
'Content-Type': string; | ||
}; | ||
body: string; | ||
} |
@@ -294,5 +294,5 @@ export default function Consent(mpInstance) { | ||
* | ||
* @method removeCCPAState | ||
* @method removeCCPAConsentState | ||
*/ | ||
function removeCCPAState() { | ||
function removeCCPAConsentState() { | ||
delete ccpa[CCPAPurpose]; | ||
@@ -302,2 +302,9 @@ return this; | ||
function removeCCPAState() { | ||
mpInstance.Logger.warning( | ||
'removeCCPAState is deprecated and will be removed in a future release; use removeCCPAConsentState instead' | ||
); | ||
return removeCCPAConsentState(); | ||
} | ||
return { | ||
@@ -311,4 +318,5 @@ setGDPRConsentState: setGDPRConsentState, | ||
removeCCPAState: removeCCPAState, | ||
removeCCPAConsentState: removeCCPAConsentState, | ||
}; | ||
}; | ||
} |
var Constants = { | ||
sdkVersion: '2.11.5', | ||
sdkVersion: '2.11.8', | ||
sdkVendor: 'mparticle', | ||
@@ -98,2 +98,3 @@ platform: 'web', | ||
Alias: 'aliasUsers', | ||
Upload: 'upload', | ||
}, | ||
@@ -100,0 +101,0 @@ StorageNames: { |
@@ -12,8 +12,20 @@ import Types from './types'; | ||
) { | ||
productAction.TransactionId = transactionAttributes.Id; | ||
productAction.Affiliation = transactionAttributes.Affiliation; | ||
productAction.CouponCode = transactionAttributes.CouponCode; | ||
productAction.TotalAmount = transactionAttributes.Revenue; | ||
productAction.ShippingAmount = transactionAttributes.Shipping; | ||
productAction.TaxAmount = transactionAttributes.Tax; | ||
if (transactionAttributes.Id) { | ||
productAction.TransactionId = transactionAttributes.Id; | ||
} | ||
if (transactionAttributes.Affiliation) { | ||
productAction.Affiliation = transactionAttributes.Affiliation; | ||
} | ||
if (transactionAttributes.CouponCode) { | ||
productAction.CouponCode = transactionAttributes.CouponCode; | ||
} | ||
if (transactionAttributes.Revenue) { | ||
productAction.TotalAmount = transactionAttributes.Revenue; | ||
} | ||
if (transactionAttributes.Shipping) { | ||
productAction.ShippingAmount = transactionAttributes.Shipping; | ||
} | ||
if (transactionAttributes.Tax) { | ||
productAction.TaxAmount = transactionAttributes.Tax; | ||
} | ||
}; | ||
@@ -20,0 +32,0 @@ |
@@ -489,4 +489,18 @@ // | ||
}; | ||
/** | ||
* Forces an upload of the batch | ||
* @method upload | ||
*/ | ||
this.upload = function() { | ||
if (self._Helpers.canLog()) { | ||
if (self._Store.webviewBridgeEnabled) { | ||
self._NativeSdkHelpers.sendToNative( | ||
Constants.NativeSdkPaths.Upload | ||
); | ||
} else { | ||
self._APIClient.uploader.prepareAndUpload(false, false); | ||
} | ||
} | ||
}; | ||
/** | ||
* Invoke these methods on the mParticle.Consent object. | ||
@@ -493,0 +507,0 @@ * Example: mParticle.Consent.createConsentState() |
@@ -161,2 +161,5 @@ import Polyfill from './polyfill'; | ||
}; | ||
this.upload = function() { | ||
self.getInstance().upload(); | ||
}; | ||
this.eCommerce = { | ||
@@ -163,0 +166,0 @@ Cart: { |
@@ -184,2 +184,3 @@ import Constants from './constants'; | ||
); | ||
iOSBridgeMessageHandler.postMessage( | ||
@@ -186,0 +187,0 @@ JSON.stringify({ |
@@ -119,2 +119,7 @@ import * as EventsApi from '@mparticle/event-models'; | ||
ServerModel(); | ||
upload(); | ||
logEvent(eventName: string): void; | ||
eCommerce: any; | ||
logLevel: string; | ||
ProductActionType: SDKProductActionType; | ||
} | ||
@@ -125,2 +130,3 @@ | ||
appVersion?: string; | ||
flags?: { [key: string]: string | number }; | ||
appName?: string; | ||
@@ -127,0 +133,0 @@ logLevel?: string; |
@@ -16,2 +16,6 @@ var MessageType = { | ||
var TriggerUploadType = { | ||
[MessageType.Commerce]: 1, | ||
}; | ||
var EventType = { | ||
@@ -30,2 +34,4 @@ Unknown: 0, | ||
switch (id) { | ||
case EventType.Unknown: | ||
return 'Unknown'; | ||
case EventType.Navigation: | ||
@@ -320,2 +326,3 @@ return 'Navigation'; | ||
PromotionActionType: PromotionActionType, | ||
TriggerUploadType: TriggerUploadType, | ||
}; |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
1327219
24689