From c86d13e8b145dd184b4aa820821079ad04e4f9ff Mon Sep 17 00:00:00 2001 From: mparticle-automation Date: Mon, 28 Oct 2024 13:40:25 +0000 Subject: [PATCH 1/9] chore(build): Generate latest bundle [skip ci] --- dist/mparticle.common.js | 5 +++-- dist/mparticle.esm.js | 5 +++-- dist/mparticle.js | 6 ++++-- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/dist/mparticle.common.js b/dist/mparticle.common.js index fa7f78e8e..2f8475052 100644 --- a/dist/mparticle.common.js +++ b/dist/mparticle.common.js @@ -154,7 +154,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.30.1"; +var version = "2.30.2"; var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039 @@ -558,7 +558,8 @@ var d=a._Persistence.getPersistence();d&&!d.cu&&(a.Identity.identify(a._Store.SD if(g.gs.sid&&a._Store.sessionId!==g.gs.sid&&(a._Store.sessionId=g.gs.sid),null===(d=null===g||void 0===g?void 0:g.gs)||void 0===d?void 0:d.les){e=6e4*a._Store.SDKConfig.sessionTimeout;var h=new Date().getTime();f=h-g.gs.les,f Date: Mon, 28 Oct 2024 13:40:29 +0000 Subject: [PATCH 2/9] chore(release): 2.30.2 [skip ci] ## [2.30.2](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.1...v2.30.2) (2024-10-28) ### Bug Fixes * Support capturing click ids as custom flags in commerce events ([#939](https://github.com/mParticle/mparticle-web-sdk/issues/939)) ([6fb2476](https://github.com/mParticle/mparticle-web-sdk/commit/6fb2476aa617e9a861280c02d09c0d21555d510c)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fd598d53..a2b6e5cc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2.30.2](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.1...v2.30.2) (2024-10-28) + + +### Bug Fixes + +* Support capturing click ids as custom flags in commerce events ([#939](https://github.com/mParticle/mparticle-web-sdk/issues/939)) ([6fb2476](https://github.com/mParticle/mparticle-web-sdk/commit/6fb2476aa617e9a861280c02d09c0d21555d510c)) + # [2.30.1](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.0...v2.30.1) (2024-10-15) diff --git a/package-lock.json b/package-lock.json index 1c672263c..8cd3abda3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.1", + "version": "2.30.2", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@mparticle/web-sdk", - "version": "2.30.0", + "version": "2.30.2", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.23.2" diff --git a/package.json b/package.json index 4e969d712..dbb467bea 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.1", + "version": "2.30.2", "description": "mParticle core SDK for web applications", "license": "Apache-2.0", "keywords": [ From 7e65fbfebfb88c48ec84964ab08247b5499cbbf0 Mon Sep 17 00:00:00 2001 From: ericmschallock <106028728+ericmschallock@users.noreply.github.com> Date: Mon, 28 Oct 2024 07:53:42 -0800 Subject: [PATCH 3/9] docs: Update README.md (#937) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3d56ae001..cdb43789a 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Hello! This is the public repo of the mParticle Web SDK. We've built the mPartic ## Documentation -Fully detailed documentation and other information about mParticle web SDK can be found at our doc site [here](https://docs.mparticle.com/developers/sdk/web/getting-started) +Fully detailed documentation and other information about mParticle web SDK can be found at our doc site [here](https://docs.mparticle.com/developers/sdk/web/initialization/) ## Include and Initialize the SDK From ed56c8460c5b93d46971bd09315d31a4d73c18c5 Mon Sep 17 00:00:00 2001 From: mparticle-automation Date: Tue, 5 Nov 2024 14:09:35 +0000 Subject: [PATCH 4/9] chore(build): Generate latest bundle [skip ci] --- dist/mparticle.common.js | 2 +- dist/mparticle.esm.js | 2 +- dist/mparticle.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/mparticle.common.js b/dist/mparticle.common.js index 2f8475052..04c37c8f1 100644 --- a/dist/mparticle.common.js +++ b/dist/mparticle.common.js @@ -154,7 +154,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.30.2"; +var version = "2.30.3"; var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039 diff --git a/dist/mparticle.esm.js b/dist/mparticle.esm.js index 54639bd73..d6060d3fa 100644 --- a/dist/mparticle.esm.js +++ b/dist/mparticle.esm.js @@ -154,7 +154,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.30.2"; +var version = "2.30.3"; var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039 diff --git a/dist/mparticle.js b/dist/mparticle.js index 7d114c87b..d66402b02 100644 --- a/dist/mparticle.js +++ b/dist/mparticle.js @@ -393,7 +393,7 @@ var mParticle = (function () { return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; - var version = "2.30.2"; + var version = "2.30.3"; var Constants = { sdkVersion: version, From 261f33b8ef0a8be30c9bbad61439e7123c63e911 Mon Sep 17 00:00:00 2001 From: mparticle-automation Date: Tue, 5 Nov 2024 14:09:39 +0000 Subject: [PATCH 5/9] chore(release): 2.30.3 [skip ci] ## [2.30.3](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.2...v2.30.3) (2024-11-05) --- CHANGELOG.md | 2 ++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2b6e5cc8..cf541357d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## [2.30.3](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.2...v2.30.3) (2024-11-05) + ## [2.30.2](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.1...v2.30.2) (2024-10-28) diff --git a/package-lock.json b/package-lock.json index 8cd3abda3..6fe4624e7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.2", + "version": "2.30.3", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@mparticle/web-sdk", - "version": "2.30.2", + "version": "2.30.3", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.23.2" diff --git a/package.json b/package.json index dbb467bea..a0179caff 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.2", + "version": "2.30.3", "description": "mParticle core SDK for web applications", "license": "Apache-2.0", "keywords": [ From 678ccb7fd97e25e15bac572c3cb899a3af23b976 Mon Sep 17 00:00:00 2001 From: Alex S <49695018+alexs-mparticle@users.noreply.github.com> Date: Tue, 5 Nov 2024 10:33:27 -0500 Subject: [PATCH 6/9] fix: Move ready queue processing after identity request (#933) --- src/identity.js | 6 + src/mp-instance.js | 51 ++----- src/pre-init-utils.ts | 36 +++++ test/jest/pre-init-utils.spec.ts | 69 +++++++++ test/src/_test.index.ts | 2 +- test/src/config/utils.js | 4 +- test/src/tests-core-sdk.js | 38 ++--- test/src/tests-forwarders.js | 45 ++---- test/src/tests-helpers.js | 33 +++- test/src/tests-identities-attributes.ts | 153 ++++++++++++++++++- test/src/tests-identity.ts | 5 +- test/src/tests-mparticle-instance-manager.js | 2 +- test/src/tests-persistence.ts | 8 +- test/src/tests-queue-public-methods.js | 72 +++++---- 14 files changed, 377 insertions(+), 147 deletions(-) create mode 100644 src/pre-init-utils.ts create mode 100644 test/jest/pre-init-utils.spec.ts diff --git a/src/identity.js b/src/identity.js index 81e9299a9..3abebed7e 100644 --- a/src/identity.js +++ b/src/identity.js @@ -18,6 +18,7 @@ import { } from './utils'; import { hasMPIDAndUserLoginChanged, hasMPIDChanged } from './user-utils'; import { getNewIdentitiesByName } from './type-utils'; +import { processReadyQueue } from './pre-init-utils'; export default function Identity(mpInstance) { const { getFeatureFlag, extend } = mpInstance._Helpers; @@ -1679,6 +1680,11 @@ export default function Identity(mpInstance) { 'Error parsing JSON response from Identity server: ' + e ); } + mpInstance._Store.isInitialized = true; + + mpInstance._preInit.readyQueue = processReadyQueue( + mpInstance._preInit.readyQueue + ); }; // send a user identity change request on identify, login, logout, modify when any values change. diff --git a/src/mp-instance.js b/src/mp-instance.js index 39afdd0ee..1736ce1db 100644 --- a/src/mp-instance.js +++ b/src/mp-instance.js @@ -36,10 +36,11 @@ import Consent from './consent'; import KitBlocker from './kitBlocking'; import ConfigAPIClient from './configAPIClient'; import IdentityAPIClient from './identityApiClient'; -import { isEmpty, isFunction } from './utils'; +import { isFunction } from './utils'; import { LocalStorageVault } from './vault'; import { removeExpiredIdentityCacheDates } from './identity-utils'; import IntegrationCapture from './integrationCapture'; +import { processReadyQueue } from './pre-init-utils'; const { Messages, HTTPCodes, FeatureFlags } = Constants; const { ReportBatching, CaptureIntegrationSpecificIds } = FeatureFlags; @@ -1361,15 +1362,17 @@ function completeSDKInitialization(apiKey, config, mpInstance) { ); } - mpInstance._Store.isInitialized = true; + // We will continue to clear out the ready queue as part of the initial init flow + // if an identify request is unnecessary, such as if there is an existing session + if ( + (mpInstance._Store.mpid && !mpInstance._Store.identifyCalled) || + mpInstance._Store.webviewBridgeEnabled + ) { + mpInstance._Store.isInitialized = true; - // Call any functions that are waiting for the library to be initialized - try { mpInstance._preInit.readyQueue = processReadyQueue( mpInstance._preInit.readyQueue ); - } catch (error) { - mpInstance.Logger.error(error); } // https://go.mparticle.com/work/SQDSDKS-6040 @@ -1508,42 +1511,6 @@ function processIdentityCallback( } } -function processPreloadedItem(readyQueueItem) { - const args = readyQueueItem; - const method = args.splice(0, 1)[0]; - // if the first argument is a method on the base mParticle object, run it - if (mParticle[args[0]]) { - mParticle[method].apply(this, args); - // otherwise, the method is on either eCommerce or Identity objects, ie. "eCommerce.setCurrencyCode", "Identity.login" - } else { - const methodArray = method.split('.'); - try { - var computedMPFunction = mParticle; - for (let i = 0; i < methodArray.length; i++) { - const currentMethod = methodArray[i]; - computedMPFunction = computedMPFunction[currentMethod]; - } - computedMPFunction.apply(this, args); - } catch (e) { - throw new Error('Unable to compute proper mParticle function ' + e); - } - } -} - -function processReadyQueue(readyQueue) { - if (!isEmpty(readyQueue)) { - readyQueue.forEach(function(readyQueueItem) { - if (isFunction(readyQueueItem)) { - readyQueueItem(); - } else if (Array.isArray(readyQueueItem)) { - processPreloadedItem(readyQueueItem); - } - }); - } - // https://go.mparticle.com/work/SQDSDKS-6835 - return []; -} - function queueIfNotInitialized(func, self) { if (!self.isInitialized()) { self.ready(function() { diff --git a/src/pre-init-utils.ts b/src/pre-init-utils.ts new file mode 100644 index 000000000..05178088b --- /dev/null +++ b/src/pre-init-utils.ts @@ -0,0 +1,36 @@ +import { isEmpty, isFunction } from './utils'; + +export const processReadyQueue = (readyQueue): Function[] => { + if (!isEmpty(readyQueue)) { + readyQueue.forEach(readyQueueItem => { + if (isFunction(readyQueueItem)) { + readyQueueItem(); + } else if (Array.isArray(readyQueueItem)) { + processPreloadedItem(readyQueueItem); + } + }); + } + return []; +}; + +const processPreloadedItem = (readyQueueItem): void => { + const args = readyQueueItem; + const method = args.splice(0, 1)[0]; + + // if the first argument is a method on the base mParticle object, run it + if (typeof window !== 'undefined' && window.mParticle && window.mParticle[args[0]]) { + window.mParticle[method].apply(this, args); + // otherwise, the method is on either eCommerce or Identity objects, ie. "eCommerce.setCurrencyCode", "Identity.login" + } else { + const methodArray = method.split('.'); + try { + let computedMPFunction = window.mParticle; + for (const currentMethod of methodArray) { + computedMPFunction = computedMPFunction[currentMethod]; + } + ((computedMPFunction as unknown) as Function).apply(this, args); + } catch (e) { + throw new Error('Unable to compute proper mParticle function ' + e); + } + } +}; diff --git a/test/jest/pre-init-utils.spec.ts b/test/jest/pre-init-utils.spec.ts new file mode 100644 index 000000000..75255518f --- /dev/null +++ b/test/jest/pre-init-utils.spec.ts @@ -0,0 +1,69 @@ +import { processReadyQueue } from '../../src/pre-init-utils'; + +describe('pre-init-utils', () => { + describe('#processReadyQueue', () => { + it('should return an empty array if readyQueue is empty', () => { + const result = processReadyQueue([]); + expect(result).toEqual([]); + }); + + it('should process functions passed as arguments', () => { + const functionSpy = jest.fn(); + const readyQueue: Function[] = [functionSpy, functionSpy, functionSpy]; + const result = processReadyQueue(readyQueue); + expect(functionSpy).toHaveBeenCalledTimes(3); + expect(result).toEqual([]); + }); + + it('should process functions passed as arrays', () => { + const functionSpy = jest.fn(); + (window.mParticle as any) = { + fakeFunction: functionSpy, + }; + const readyQueue = [['fakeFunction']]; + processReadyQueue(readyQueue); + expect(functionSpy).toHaveBeenCalled(); + }); + + it('should process functions passed as arrays with arguments', () => { + const functionSpy = jest.fn(); + (window.mParticle as any) = { + fakeFunction: functionSpy, + args: () => {}, + }; + const readyQueue = [['fakeFunction', 'args']]; + processReadyQueue(readyQueue); + expect(functionSpy).toHaveBeenCalledWith('args'); + }); + + it('should process arrays passed as arguments with multiple methods', () => { + const functionSpy = jest.fn(); + (window.mParticle as any) = { + fakeFunction: { + anotherFakeFunction: functionSpy, + }, + }; + const readyQueue = [['fakeFunction.anotherFakeFunction', 'foo']]; + processReadyQueue(readyQueue); + expect(functionSpy).toHaveBeenCalledWith('foo'); + }); + + it('should process arrays passed as arguments with multiple methods and arguments', () => { + const functionSpy = jest.fn(); + const functionSpy2 = jest.fn(); + (window.mParticle as any) = { + fakeFunction: functionSpy, + anotherFakeFunction: functionSpy2, + }; + const readyQueue = [['fakeFunction', 'foo'], ['anotherFakeFunction', 'bar']]; + processReadyQueue(readyQueue); + expect(functionSpy).toHaveBeenCalledWith('foo'); + expect(functionSpy2).toHaveBeenCalledWith('bar'); + }); + + it('should throw an error if it cannot compute the proper mParticle function', () => { + const readyQueue = [['Identity.login']]; + expect(() => processReadyQueue(readyQueue)).toThrowError("Unable to compute proper mParticle function TypeError: Cannot read properties of undefined (reading 'login')"); + }); + }); +}); \ No newline at end of file diff --git a/test/src/_test.index.ts b/test/src/_test.index.ts index e847c974c..7cb1e5b00 100644 --- a/test/src/_test.index.ts +++ b/test/src/_test.index.ts @@ -10,8 +10,8 @@ import './tests-kit-blocking'; import './tests-event-logging'; import './tests-eCommerce'; import './tests-persistence'; -import './tests-forwarders'; import './tests-helpers'; +import './tests-forwarders'; import './tests-cookie-syncing'; import './tests-identities-attributes'; import './tests-native-sdk'; diff --git a/test/src/config/utils.js b/test/src/config/utils.js index 06b6476ad..ac1d3fb29 100644 --- a/test/src/config/utils.js +++ b/test/src/config/utils.js @@ -633,7 +633,8 @@ var pluses = /\+/g, }, hasIdentifyReturned = () => { return window.mParticle.Identity.getCurrentUser()?.getMPID() === testMPID; - }; + }, + hasIdentityCallInflightReturned = () => !mParticle.getInstance()?._Store?.identityCallInFlight; var TestsCore = { getLocalStorageProducts: getLocalStorageProducts, @@ -661,6 +662,7 @@ var TestsCore = { waitForCondition: waitForCondition, fetchMockSuccess: fetchMockSuccess, hasIdentifyReturned: hasIdentifyReturned, + hasIdentityCallInflightReturned, }; export default TestsCore; \ No newline at end of file diff --git a/test/src/tests-core-sdk.js b/test/src/tests-core-sdk.js index 7061838e2..d0f91dddc 100644 --- a/test/src/tests-core-sdk.js +++ b/test/src/tests-core-sdk.js @@ -1,3 +1,4 @@ +import { expect } from 'chai'; import Utils from './config/utils'; import Store from '../../src/store'; import Constants, { HTTP_ACCEPTED, HTTP_OK } from '../../src/constants'; @@ -11,7 +12,7 @@ const DefaultConfig = Constants.DefaultConfig, findEventFromRequest = Utils.findEventFromRequest, findBatch = Utils.findBatch; -const { waitForCondition, fetchMockSuccess, hasIdentifyReturned } = Utils; +const { waitForCondition, fetchMockSuccess, hasIdentifyReturned, hasIdentityCallInflightReturned } = Utils; describe('core SDK', function() { beforeEach(function() { @@ -121,7 +122,7 @@ describe('core SDK', function() { }); }); - it('should process ready queue when initialized', function(done) { + it('should process ready queue when initialized', async function() { let readyFuncCalled = false; mParticle._resetForTests(MPConfig); @@ -130,10 +131,9 @@ describe('core SDK', function() { readyFuncCalled = true; }); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); - Should(readyFuncCalled).equal(true); - - done(); + expect(readyFuncCalled).equal(true); }); it('should set app version on the payload', function(done) { @@ -150,14 +150,12 @@ describe('core SDK', function() { }) }); - it('should get app version', function(done) { + it('should get app version', async function() { + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setAppVersion('2.0'); const appVersion = mParticle.getAppVersion(); - - appVersion.should.equal('2.0'); - - done(); + expect(appVersion).to.equal('2.0'); }); it('should get environment setting when set to `production`', function(done) { @@ -1191,15 +1189,14 @@ describe('core SDK', function() { }); }); - it('should initialize without a config object passed to init', function(done) { + it('should initialize without a config object passed to init', async function() { // this instance occurs when self hosting and the user only passes an object into init mParticle._resetForTests(MPConfig); mParticle.init(apiKey); + await waitForCondition(hasIdentityCallInflightReturned); mParticle.getInstance()._Store.isInitialized.should.equal(true); - - done(); }); it('should generate hash both on the mparticle instance and the mparticle instance manager', function(done) { @@ -1262,18 +1259,17 @@ describe('core SDK', function() { done(); }); - it('should set a device id when calling setDeviceId', function(done) { + it('should set a device id when calling setDeviceId', async function() { mParticle._resetForTests(MPConfig); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); // this das should be the SDK auto generated one, which is 36 characters long mParticle.getDeviceId().length.should.equal(36); mParticle.setDeviceId('foo-guid'); mParticle.getDeviceId().should.equal('foo-guid'); - - done(); }); it('should set a device id when set on mParticle.config', function(done) { @@ -1310,34 +1306,32 @@ describe('core SDK', function() { done(); }); - it('should set the wrapper sdk info in Store when mParticle._setWrapperSDKInfo() method is called after init is called', function(done) { + it('should set the wrapper sdk info in Store when mParticle._setWrapperSDKInfo() method is called after init is called', async function() { mParticle._resetForTests(MPConfig); mParticle._setWrapperSDKInfo('flutter', '1.0.3'); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); mParticle.getInstance()._Store.wrapperSDKInfo.name.should.equal('flutter'); mParticle.getInstance()._Store.wrapperSDKInfo.version.should.equal('1.0.3'); mParticle.getInstance()._Store.wrapperSDKInfo.isInfoSet.should.equal(true); - - done(); }); - it('should not set the wrapper sdk info in Store after it has previously been set', function(done) { + it('should not set the wrapper sdk info in Store after it has previously been set', async function() { mParticle._resetForTests(MPConfig); mParticle._setWrapperSDKInfo('flutter', '1.0.3'); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); mParticle._setWrapperSDKInfo('none', '2.0.5'); mParticle.getInstance()._Store.wrapperSDKInfo.name.should.equal('flutter'); mParticle.getInstance()._Store.wrapperSDKInfo.version.should.equal('1.0.3'); mParticle.getInstance()._Store.wrapperSDKInfo.isInfoSet.should.equal(true); - - done(); }); describe('pod feature flag', function() { diff --git a/test/src/tests-forwarders.js b/test/src/tests-forwarders.js index d0411197b..6a2bdacc1 100644 --- a/test/src/tests-forwarders.js +++ b/test/src/tests-forwarders.js @@ -19,7 +19,9 @@ const { findEventFromRequest, setLocalStorage, forwarderDefaultConfiguration, MockForwarder, - MockSideloadedKit,hasIdentifyReturned + MockSideloadedKit, + hasIdentifyReturned, + hasIdentityCallInflightReturned, } = Utils; let mockServer; @@ -1116,7 +1118,7 @@ describe('forwarders', function() { done(); }); - it('should invoke forwarder opt out', function(done) { + it('should invoke forwarder opt out', async function() { mParticle._resetForTests(MPConfig); const mockForwarder = new MockForwarder(); @@ -1125,14 +1127,13 @@ describe('forwarders', function() { window.mParticle.config.kitConfigs.push(config1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setOptOut(true); window.MockForwarder1.instance.should.have.property( 'setOptOutCalled', true ); - - done(); }); it('should invoke forwarder setuserattribute', function(done) { @@ -2710,21 +2711,21 @@ describe('forwarders', function() { done(); }); - it('should set integration attributes on forwarders', function(done) { + it('should set integration attributes on forwarders', async function() { mParticle.init(apiKey, window.mParticle.config) + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setIntegrationAttribute(128, { MCID: 'abcdefg' }); const adobeIntegrationAttributes = mParticle.getIntegrationAttributes( 128 ); adobeIntegrationAttributes.MCID.should.equal('abcdefg'); - - done(); }); - it('should clear integration attributes when an empty object or a null is passed', function(done) { + it('should clear integration attributes when an empty object or a null is passed', async function() { mParticle.init(apiKey, window.mParticle.config) + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setIntegrationAttribute(128, { MCID: 'abcdefg' }); let adobeIntegrationAttributes = mParticle.getIntegrationAttributes( @@ -2743,12 +2744,11 @@ describe('forwarders', function() { mParticle.setIntegrationAttribute(128, null); adobeIntegrationAttributes = mParticle.getIntegrationAttributes(128); Object.keys(adobeIntegrationAttributes).length.should.equal(0); - - done(); }); - it('should set only strings as integration attributes', function(done) { + it('should set only strings as integration attributes', async function() { mParticle.init(apiKey, window.mParticle.config) + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setIntegrationAttribute(128, { MCID: 'abcdefg', @@ -2760,9 +2760,8 @@ describe('forwarders', function() { const adobeIntegrationAttributes = mParticle.getIntegrationAttributes( 128 ); - Object.keys(adobeIntegrationAttributes).length.should.equal(1); - done(); + Object.keys(adobeIntegrationAttributes).length.should.equal(1); }); it('should add integration delays to the integrationDelays object', function(done) { @@ -3074,7 +3073,7 @@ describe('forwarders', function() { // This will pass when we add mpInstance._Store.isInitialized = true; to mp-instance before `processIdentityCallback` - it('configures forwarders before events are logged via identify callback', function(done) { + it('configures forwarders before events are logged via identify callback', async function() { mParticle._resetForTests(MPConfig); window.mParticle.config.identifyRequest = { userIdentities: { @@ -3093,12 +3092,7 @@ describe('forwarders', function() { ); window.mParticle.config.rq = []; mParticle.init(apiKey, window.mParticle.config); - waitForCondition(() => { - return ( - window.mParticle.getInstance()?._Store?.identityCallInFlight === false - ); - }) - .then(() => { + await waitForCondition(hasIdentityCallInflightReturned); window.MockForwarder1.instance.should.have.property( 'processCalled', true @@ -3109,22 +3103,13 @@ describe('forwarders', function() { window.mParticle.config.rq = []; mParticle.init(apiKey, window.mParticle.config); - - waitForCondition(() => { - return ( - window.mParticle.getInstance()?._Store?.identityCallInFlight === false - ); - }) - .then(() => { + await waitForCondition(hasIdentityCallInflightReturned); window.MockForwarder1.instance.should.have.property( 'processCalled', true ); - done(); - }); - }); }); it('should retain preInit.forwarderConstructors, and reinitialize forwarders after calling reset, then init', function(done) { diff --git a/test/src/tests-helpers.js b/test/src/tests-helpers.js index 57a41cff0..632ffa2b0 100644 --- a/test/src/tests-helpers.js +++ b/test/src/tests-helpers.js @@ -1,9 +1,29 @@ -import { apiKey } from './config/constants'; +import { + urls, + apiKey, + testMPID, + mParticle, +} from './config/constants'; import sinon from 'sinon'; +import Utils from './config/utils'; + +const { waitForCondition, fetchMockSuccess, hasIdentityCallInflightReturned} = Utils; describe('helpers', function() { beforeEach(function() { + fetchMockSuccess(urls.events); + fetchMockSuccess(urls.identify, { + context: null, + matched_identities: { + device_application_stamp: 'my-das', + }, + is_ephemeral: true, + mpid: testMPID, + is_logged_in: false, + }); + mParticle.init(apiKey, window.mParticle.config); + }); it('should correctly validate an attribute value', function(done) { @@ -36,7 +56,8 @@ describe('helpers', function() { done(); }); - it('should return event name in warning when sanitizing invalid attributes', function(done) { + it('should return event name in warning when sanitizing invalid attributes', async function() { + await waitForCondition(hasIdentityCallInflightReturned); const bond = sinon.spy(mParticle.getInstance().Logger, 'warning'); mParticle.logEvent('eventName', mParticle.EventType.Location, {invalidValue: {}}); @@ -46,8 +67,6 @@ describe('helpers', function() { bond.getCalls()[0].args[0].should.eql( "For 'eventName', the corresponding attribute value of 'invalidValue' must be a string, number, boolean, or null." ); - - done(); }); it('should return product name in warning when sanitizing invalid attributes', function(done) { @@ -74,7 +93,9 @@ describe('helpers', function() { done(); }); - it('should return commerce event name in warning when sanitizing invalid attributes', function(done) { + it('should return commerce event name in warning when sanitizing invalid attributes', async function() { + await waitForCondition(hasIdentityCallInflightReturned); + const bond = sinon.spy(mParticle.getInstance().Logger, 'warning'); const product1 = mParticle.eCommerce.createProduct('prod1', 'prod1sku', 999); @@ -89,8 +110,6 @@ describe('helpers', function() { bond.getCalls()[0].args[0].should.eql( "For 'eCommerce - AddToCart', the corresponding attribute value of 'invalidValue' must be a string, number, boolean, or null." ); - - done(); }); it('should correctly validate an identity request with copyUserAttribute as a key using any identify method', function(done) { diff --git a/test/src/tests-identities-attributes.ts b/test/src/tests-identities-attributes.ts index 4b91bc703..af7c84a9e 100644 --- a/test/src/tests-identities-attributes.ts +++ b/test/src/tests-identities-attributes.ts @@ -1,4 +1,3 @@ -import sinon from 'sinon'; import { expect } from 'chai'; import fetchMock from 'fetch-mock/esm/client'; import { @@ -6,16 +5,17 @@ import { apiKey, testMPID, MPConfig, - MILLISECONDS_IN_ONE_DAY_PLUS_ONE_SECOND, } from './config/constants'; import Utils from './config/utils'; import { MParticleWebSDK } from '../../src/sdkRuntimeModels'; import { AllUserAttributes, UserAttributesValue } from '@mparticle/web-sdk'; import { UserAttributes } from '../../src/identity-user-interfaces'; -import { UserAttributeChangeEvent } from '@mparticle/event-models'; -const { waitForCondition, fetchMockSuccess, hasIdentifyReturned } = Utils; - +import { Batch, CustomEvent, UserAttributeChangeEvent } from '@mparticle/event-models'; const { + waitForCondition, + fetchMockSuccess, + hasIdentifyReturned, + hasIdentityCallInflightReturned, findEventFromRequest, findBatch, getLocalStorage, @@ -54,16 +54,30 @@ const BAD_USER_ATTRIBUTE_KEY_AS_ARRAY = ([ const BAD_USER_ATTRIBUTE_LIST_VALUE = (1234 as unknown) as UserAttributesValue[]; describe('identities and attributes', function() { + let beforeEachCallbackCalled = false; + let hasBeforeEachCallbackReturned; + beforeEach(function() { fetchMockSuccess(urls.identify, { mpid: testMPID, is_logged_in: false }); fetchMock.post(urls.events, 200); + + mParticle.config.identityCallback = function() { + // There are some tests that need to verify that the initial init + // call within the beforeEach method has completed before they + // can introduce a new identityCallback for their specific assertions. + beforeEachCallbackCalled = true; + }; + mParticle.init(apiKey, window.mParticle.config); + + hasBeforeEachCallbackReturned = () => beforeEachCallbackCalled; }); afterEach(function() { + beforeEachCallbackCalled = false; fetchMock.restore(); }); @@ -1223,6 +1237,135 @@ describe('identities and attributes', function() { }) }); + it('should order user identity change events before logging any events', async () => { + mParticle._resetForTests(MPConfig); + fetchMock.resetHistory(); + + // Clear out before each init call + await waitForCondition(hasBeforeEachCallbackReturned); + + window.mParticle.config.identifyRequest = { + userIdentities: { + email: 'initial@gmail.com', + }, + }; + + mParticle.init(apiKey, window.mParticle.config); + + await waitForCondition(hasIdentityCallInflightReturned); + + mParticle.logEvent('Test Event 1'); + mParticle.logEvent('Test Event 2'); + mParticle.logEvent('Test Event 3'); + + expect(fetchMock.calls().length).to.equal(7); + + const firstCall = fetchMock.calls()[0]; + expect(firstCall[0].split('/')[4]).to.equal('identify', 'First Call'); + + const secondCall = fetchMock.calls()[1]; + expect(secondCall[0].split('/')[6]).to.equal('events'); + const secondCallBody = JSON.parse(secondCall[1].body as unknown as string) as Batch; + expect(secondCallBody.events[0].event_type).to.equal('session_start', 'Second Call'); + + const thirdCall = fetchMock.calls()[2]; + expect(thirdCall[0].split('/')[6]).to.equal('events'); + const thirdCallBody = JSON.parse(thirdCall[1].body as unknown as string) as Batch; + expect(thirdCallBody.events[0].event_type).to.equal('application_state_transition', 'Third Call'); + + const fourthCall = fetchMock.calls()[3]; + expect(fourthCall[0].split('/')[6]).to.equal('events'); + const fourthCallBody = JSON.parse(fourthCall[1].body as unknown as string) as Batch; + expect(fourthCallBody.events[0].event_type).to.equal('user_identity_change', 'Fourth Call'); + + const fifthCall = fetchMock.calls()[4]; + expect(fifthCall[0].split('/')[6]).to.equal('events'); + const fifthCallBody = JSON.parse(fifthCall[1].body as unknown as string) as Batch; + const fifthCallEvent = fifthCallBody.events[0] as CustomEvent; + expect(fifthCallEvent.event_type).to.equal('custom_event', 'Fifth Call'); + expect(fifthCallEvent.data.event_name).to.equal('Test Event 1', 'Fifth Call'); + + const sixthCall = fetchMock.calls()[5]; + expect(sixthCall[0].split('/')[6]).to.equal('events'); + const sixthCallBody = JSON.parse(sixthCall[1].body as unknown as string) as Batch; + const sixthCallEvent = sixthCallBody.events[0] as CustomEvent; + expect(sixthCallBody.events[0].event_type).to.equal('custom_event', 'Sixth Call'); + expect(sixthCallEvent.data.event_name).to.equal('Test Event 2', 'Sixth Call'); + + const seventhEvent = fetchMock.calls()[6]; + expect(seventhEvent[0].split('/')[6]).to.equal('events'); + const seventhEventBody = JSON.parse(seventhEvent[1].body as unknown as string) as Batch; + const seventhEventEvent = seventhEventBody.events[0] as CustomEvent; + expect(seventhEventBody.events[0].event_type).to.equal('custom_event', 'Seventh Call'); + expect(seventhEventEvent.data.event_name).to.equal('Test Event 3', 'Seventh Call'); + }); + + it('should order user identity change events before logging any events that are in the ready queue', async () => { + + mParticle._resetForTests(MPConfig); + fetchMock.resetHistory(); + + // Clear out before each init call + await waitForCondition(hasBeforeEachCallbackReturned); + + window.mParticle.config.identifyRequest = { + userIdentities: { + email: 'initial@gmail.com', + }, + }; + + mParticle.init(apiKey, window.mParticle.config); + + mParticle.logEvent('Test Event 1'); + mParticle.logEvent('Test Event 2'); + mParticle.logEvent('Test Event 3'); + + expect(mParticle.getInstance()._preInit.readyQueue.length).to.equal(3); + + await waitForCondition(hasIdentityCallInflightReturned); + + expect(fetchMock.calls().length).to.equal(7); + + const firstCall = fetchMock.calls()[0]; + expect(firstCall[0].split('/')[4]).to.equal('identify', 'First Call'); + + const secondCall = fetchMock.calls()[1]; + expect(secondCall[0].split('/')[6]).to.equal('events'); + const secondCallBody = JSON.parse(secondCall[1].body as unknown as string) as Batch; + expect(secondCallBody.events[0].event_type).to.equal('session_start', 'Second Call'); + + const thirdCall = fetchMock.calls()[2]; + expect(thirdCall[0].split('/')[6]).to.equal('events'); + const thirdCallBody = JSON.parse(thirdCall[1].body as unknown as string) as Batch; + expect(thirdCallBody.events[0].event_type).to.equal('application_state_transition', 'Third Call'); + + const fourthCall = fetchMock.calls()[3]; + expect(fourthCall[0].split('/')[6]).to.equal('events'); + const fourthCallBody = JSON.parse(fourthCall[1].body as unknown as string) as Batch; + expect(fourthCallBody.events[0].event_type).to.equal('user_identity_change', 'Fourth Call'); + + const fifthCall = fetchMock.calls()[4]; + expect(fifthCall[0].split('/')[6]).to.equal('events'); + const fifthCallBody = JSON.parse(fifthCall[1].body as unknown as string) as Batch; + const fifthCallEvent = fifthCallBody.events[0] as CustomEvent; + expect(fifthCallEvent.event_type).to.equal('custom_event', 'Fifth Call'); + expect(fifthCallEvent.data.event_name).to.equal('Test Event 1', 'Fifth Call'); + + const sixthCall = fetchMock.calls()[5]; + expect(sixthCall[0].split('/')[6]).to.equal('events'); + const sixthCallBody = JSON.parse(sixthCall[1].body as unknown as string) as Batch; + const sixthCallEvent = sixthCallBody.events[0] as CustomEvent; + expect(sixthCallBody.events[0].event_type).to.equal('custom_event', 'Sixth Call'); + expect(sixthCallEvent.data.event_name).to.equal('Test Event 2', 'Sixth Call'); + + const seventhEvent = fetchMock.calls()[6]; + expect(seventhEvent[0].split('/')[6]).to.equal('events'); + const seventhEventBody = JSON.parse(seventhEvent[1].body as unknown as string) as Batch; + const seventhEventEvent = seventhEventBody.events[0] as CustomEvent; + expect(seventhEventBody.events[0].event_type).to.equal('custom_event', 'Seventh Call'); + expect(seventhEventEvent.data.event_name).to.equal('Test Event 3', 'Seventh Call'); + }); + it('should send historical UIs on batches when MPID changes', function(done) { mParticle._resetForTests(MPConfig); diff --git a/test/src/tests-identity.ts b/test/src/tests-identity.ts index b83893c16..b2ec0da92 100644 --- a/test/src/tests-identity.ts +++ b/test/src/tests-identity.ts @@ -39,6 +39,7 @@ const { setCookie, MockForwarder, waitForCondition, + hasIdentityCallInflightReturned, } = Utils; const { HTTPCodes } = Constants; @@ -93,7 +94,6 @@ describe('identity', function() { let hasIdentifyReturned; let hasLoginReturned; let hasLogOutReturned; - let hasIdentityCallInflightReturned; let beforeEachCallbackCalled = false; let hasBeforeEachCallbackReturned @@ -138,9 +138,6 @@ describe('identity', function() { ); }; - hasIdentityCallInflightReturned = () => - !mParticle.getInstance()?._Store?.identityCallInFlight; - hasBeforeEachCallbackReturned = () => beforeEachCallbackCalled; }); diff --git a/test/src/tests-mparticle-instance-manager.js b/test/src/tests-mparticle-instance-manager.js index 6b09ff637..694cc37d4 100644 --- a/test/src/tests-mparticle-instance-manager.js +++ b/test/src/tests-mparticle-instance-manager.js @@ -401,7 +401,7 @@ describe('mParticle instance manager', function() { 'apiKey3', 'purchase' ); - instance1Event.should.be.ok(); + Should(instance1Event).be.ok(); Should(instance2Event).not.be.ok(); Should(instance3Event).not.be.ok(); diff --git a/test/src/tests-persistence.ts b/test/src/tests-persistence.ts index ee8ca0a34..5408d6d74 100644 --- a/test/src/tests-persistence.ts +++ b/test/src/tests-persistence.ts @@ -29,7 +29,8 @@ const { findBatch, fetchMockSuccess, hasIdentifyReturned, - waitForCondition + waitForCondition, + hasIdentityCallInflightReturned, } = Utils; describe('persistence', () => { @@ -2048,18 +2049,17 @@ describe('persistence', () => { }); }); - it('should save to persistence a device id set with setDeviceId', done => { + it('should save to persistence a device id set with setDeviceId', async () => { mParticle._resetForTests(MPConfig); mParticle.init(apiKey, mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned); mParticle.setDeviceId('foo-guid'); mParticle .getInstance() ._Persistence.getLocalStorage() .gs.das.should.equal('foo-guid'); - - done(); }); it('should save to persistence a device id set via mParticle.config', done => { diff --git a/test/src/tests-queue-public-methods.js b/test/src/tests-queue-public-methods.js index 442fda645..c798fc6a9 100644 --- a/test/src/tests-queue-public-methods.js +++ b/test/src/tests-queue-public-methods.js @@ -1,23 +1,20 @@ -import sinon from 'sinon'; import { apiKey, MPConfig, testMPID, urls } from './config/constants'; import { SDKProductActionType } from '../../src/sdkRuntimeModels'; +import Utils from './config/utils'; + +const { waitForCondition, fetchMockSuccess, hasIdentityCallInflightReturned } = Utils; describe('Queue Public Methods', function () { - let mockServer; beforeEach(function () { - mockServer = sinon.createFakeServer(); - mockServer.respondImmediately = true; - - mockServer.respondWith(urls.identify, [ - 200, - {}, - JSON.stringify({ mpid: testMPID, is_logged_in: false }), - ]); + fetchMockSuccess(urls.events); + fetchMockSuccess(urls.identify, { + mpid: testMPID, + is_logged_in: false, + }); }); afterEach(function () { - mockServer.reset(); mParticle._resetForTests(MPConfig); }); @@ -29,12 +26,11 @@ describe('Queue Public Methods', function () { mParticle.getInstance().should.have.property('isInitialized'); }); - it('should return false if not yet initialized, and true after initialization', function () { + it('should return false if not yet initialized, and true after initialization', async function () { mParticle.isInitialized().should.equal(false); mParticle.getInstance().isInitialized().should.equal(false); - window.mParticle.init(apiKey, window.mParticle.config); - + await waitForCondition(hasIdentityCallInflightReturned) mParticle.isInitialized().should.equal(true); mParticle.getInstance().isInitialized().should.equal(true); }); @@ -47,11 +43,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setAppVersion('1.2.3'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -63,11 +60,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setAppName('Timmy'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -81,13 +79,14 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.ready(function () { console.log('fired ready function'); }); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -99,11 +98,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setPosition(10, 4); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -119,7 +119,7 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { const event = { name: 'test event', }; @@ -128,6 +128,7 @@ describe('Queue Public Methods', function () { mParticle.logBaseEvent(event); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -139,11 +140,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.logEvent('Test Event'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -155,11 +157,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.logError('test error', {}); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -171,11 +174,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.logPageView('test page view', {}); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -187,11 +191,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setOptOut(true); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -203,11 +208,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setIntegrationAttribute('12345', {}); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -219,19 +225,21 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.setSessionAttribute('foo', 'bar'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); describe('#isInitialized', function () { - it('returns true when Store is initialized', function () { + it('returns true when Store is initialized', async function () { mParticle.getInstance().isInitialized().should.be.false(); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance().isInitialized().should.be.true(); }); }); @@ -245,11 +253,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.eCommerce.setCurrencyCode('USD'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -262,12 +271,13 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { const product = window.mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999); mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.eCommerce.logProductAction(SDKProductActionType.Purchase, product); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -279,11 +289,12 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.eCommerce.logPromotion('Test'); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); @@ -297,13 +308,14 @@ describe('Queue Public Methods', function () { mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); }); - it('should process queue after initialization', function () { + it('should process queue after initialization', async function () { const product = window.mParticle.eCommerce.createProduct('iphone', 'iphoneSKU', 999); const impression = window.mParticle.eCommerce.createImpression('iphone impression', product); mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); mParticle.eCommerce.logImpression(impression); mParticle.getInstance()._preInit.readyQueue.length.should.equal(1); mParticle.init(apiKey, window.mParticle.config); + await waitForCondition(hasIdentityCallInflightReturned) mParticle.getInstance()._preInit.readyQueue.length.should.equal(0); }); }); From 92eeb54a035ae0b7599160300a65faf22536881f Mon Sep 17 00:00:00 2001 From: mparticle-automation Date: Tue, 5 Nov 2024 16:02:25 +0000 Subject: [PATCH 7/9] chore(build): Generate latest bundle [skip ci] --- dist/mparticle.common.js | 17 +++++---- dist/mparticle.esm.js | 17 +++++---- dist/mparticle.js | 82 ++++++++++++++++++++-------------------- 3 files changed, 60 insertions(+), 56 deletions(-) diff --git a/dist/mparticle.common.js b/dist/mparticle.common.js index 04c37c8f1..703c42b3d 100644 --- a/dist/mparticle.common.js +++ b/dist/mparticle.common.js @@ -154,7 +154,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e; }; -var version = "2.30.3"; +var version = "2.30.4"; var Constants={sdkVersion:version,sdkVendor:"mparticle",platform:"web",Messages:{DeprecationMessages:{MethodIsDeprecatedPostfix:"is a deprecated method and will be removed in future releases",AlternativeMethodPrefix:"Please use the alternate method:"},ErrorMessages:{NoToken:"A token must be specified.",EventNameInvalidType:"Event name must be a valid string value.",EventDataInvalidType:"Event data must be a valid object hash.",LoggingDisabled:"Event logging is currently disabled.",CookieParseError:"Could not parse cookie",EventEmpty:"Event object is null or undefined, cancelling send",APIRequestEmpty:"APIRequest is null or undefined, cancelling send",NoEventType:"Event type must be specified.",TransactionIdRequired:"Transaction ID is required",TransactionRequired:"A transaction attributes object is required",PromotionIdRequired:"Promotion ID is required",BadAttribute:"Attribute value cannot be object or array",BadKey:"Key value cannot be object or array",BadLogPurchase:"Transaction attributes and a product are both required to log a purchase, https://docs.mparticle.com/?javascript#measuring-transactions",AudienceAPINotEnabled:"Your workspace is not enabled to retrieve user audiences."},InformationMessages:{CookieSearch:"Searching for cookie",CookieFound:"Cookie found, parsing values",CookieNotFound:"Cookies not found",CookieSet:"Setting cookie",CookieSync:"Performing cookie sync",SendBegin:"Starting to send event",SendIdentityBegin:"Starting to send event to identity server",SendWindowsPhone:"Sending event to Windows Phone container",SendIOS:"Calling iOS path: ",SendAndroid:"Calling Android JS interface method: ",SendHttp:"Sending event to mParticle HTTP service",SendAliasHttp:"Sending alias request to mParticle HTTP service",SendIdentityHttp:"Sending event to mParticle HTTP service",StartingNewSession:"Starting new Session",StartingLogEvent:"Starting to log event",StartingLogOptOut:"Starting to log user opt in/out",StartingEndSession:"Starting to end session",StartingInitialization:"Starting to initialize",StartingLogCommerceEvent:"Starting to log commerce event",StartingAliasRequest:"Starting to Alias MPIDs",LoadingConfig:"Loading configuration options",AbandonLogEvent:"Cannot log event, logging disabled or developer token not set",AbandonAliasUsers:"Cannot Alias Users, logging disabled or developer token not set",AbandonStartSession:"Cannot start session, logging disabled or developer token not set",AbandonEndSession:"Cannot end session, logging disabled or developer token not set",NoSessionToEnd:"Cannot end session, no active session found"},ValidationMessages:{ModifyIdentityRequestUserIdentitiesPresent:"identityRequests to modify require userIdentities to be present. Request not sent to server. Please fix and try again",IdentityRequesetInvalidKey:"There is an invalid key on your identityRequest object. It can only contain a `userIdentities` object and a `onUserAlias` function. Request not sent to server. Please fix and try again.",OnUserAliasType:"The onUserAlias value must be a function.",UserIdentities:"The userIdentities key must be an object with keys of identityTypes and values of strings. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidKey:"There is an invalid identity key on your `userIdentities` object within the identityRequest. Request not sent to server. Please fix and try again.",UserIdentitiesInvalidValues:"All user identity values must be strings or null. Request not sent to server. Please fix and try again.",AliasMissingMpid:"Alias Request must contain both a destinationMpid and a sourceMpid",AliasNonUniqueMpid:"Alias Request's destinationMpid and sourceMpid must be unique",AliasMissingTime:"Alias Request must have both a startTime and an endTime",AliasStartBeforeEndTime:"Alias Request's endTime must be later than its startTime"}},NativeSdkPaths:{LogEvent:"logEvent",SetUserTag:"setUserTag",RemoveUserTag:"removeUserTag",SetUserAttribute:"setUserAttribute",RemoveUserAttribute:"removeUserAttribute",SetSessionAttribute:"setSessionAttribute",AddToCart:"addToCart",RemoveFromCart:"removeFromCart",ClearCart:"clearCart",LogOut:"logOut",SetUserAttributeList:"setUserAttributeList",RemoveAllUserAttributes:"removeAllUserAttributes",GetUserAttributesLists:"getUserAttributesLists",GetAllUserAttributes:"getAllUserAttributes",Identify:"identify",Logout:"logout",Login:"login",Modify:"modify",Alias:"aliasUsers",Upload:"upload"},StorageNames:{localStorageName:"mprtcl-api",localStorageNameV3:"mprtcl-v3",cookieName:"mprtcl-api",cookieNameV2:"mprtcl-v2",cookieNameV3:"mprtcl-v3",localStorageNameV4:"mprtcl-v4",localStorageProductsV4:"mprtcl-prodv4",cookieNameV4:"mprtcl-v4",currentStorageName:"mprtcl-v4",currentStorageProductsName:"mprtcl-prodv4"},DefaultConfig:{cookieDomain:null,cookieExpiration:365,logLevel:null,timeout:300,sessionTimeout:30,maxProducts:20,forwarderStatsTimeout:5e3,integrationDelayTimeout:5e3,maxCookieSize:3e3,aliasMaxWindow:90,uploadInterval:0// Maximum milliseconds in between batch uploads, below 500 will mean immediate upload. The server returns this as a string, but we are using it as a number internally },DefaultBaseUrls:{v1SecureServiceUrl:"jssdks.mparticle.com/v1/JS/",v2SecureServiceUrl:"jssdks.mparticle.com/v2/JS/",v3SecureServiceUrl:"jssdks.mparticle.com/v3/JS/",configUrl:"jssdkcdns.mparticle.com/JS/v2/",identityUrl:"identity.mparticle.com/v1/",aliasUrl:"jssdks.mparticle.com/v1/identity/",userAudienceUrl:"nativesdks.mparticle.com/v1/"},Base64CookieKeys:{csm:1,sa:1,ss:1,ua:1,ui:1,csd:1,ia:1,con:1},// https://go.mparticle.com/work/SQDSDKS-6039 @@ -1128,6 +1128,9 @@ throw new Error("Uncaught HTTP Error ".concat(e.status,"."));case 5:return [3/*b function hasMPIDAndUserLoginChanged(a,b){return !a||b.getMPID()!==a.getMPID()||a.isLoggedIn()!==b.isLoggedIn()}// https://go.mparticle.com/work/SQDSDKS-6504 function hasMPIDChanged(a,b){return !a||a.getMPID()&&b.mpid&&b.mpid!==a.getMPID()} +var _this=undefined;var processReadyQueue=function(a){return isEmpty(a)||a.forEach(function(a){isFunction(a)?a():Array.isArray(a)&&processPreloadedItem(a);}),[]};var processPreloadedItem=function(a){var b=a,c=b.splice(0,1)[0];// if the first argument is a method on the base mParticle object, run it +if("undefined"!=typeof window&&window.mParticle&&window.mParticle[b[0]])window.mParticle[c].apply(_this,b);else {var d=c.split(".");try{for(var e,f=window.mParticle,g=0,h=d;g Date: Tue, 5 Nov 2024 16:02:30 +0000 Subject: [PATCH 8/9] chore(release): 2.30.4 [skip ci] ## [2.30.4](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.3...v2.30.4) (2024-11-05) ### Bug Fixes * Move ready queue processing after identity request ([#933](https://github.com/mParticle/mparticle-web-sdk/issues/933)) ([678ccb7](https://github.com/mParticle/mparticle-web-sdk/commit/678ccb7fd97e25e15bac572c3cb899a3af23b976)) --- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf541357d..ace2ed075 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [2.30.4](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.3...v2.30.4) (2024-11-05) + + +### Bug Fixes + +* Move ready queue processing after identity request ([#933](https://github.com/mParticle/mparticle-web-sdk/issues/933)) ([678ccb7](https://github.com/mParticle/mparticle-web-sdk/commit/678ccb7fd97e25e15bac572c3cb899a3af23b976)) + ## [2.30.3](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.2...v2.30.3) (2024-11-05) ## [2.30.2](https://github.com/mParticle/mparticle-web-sdk/compare/v2.30.1...v2.30.2) (2024-10-28) diff --git a/package-lock.json b/package-lock.json index 6fe4624e7..eaee8a14d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.3", + "version": "2.30.4", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "@mparticle/web-sdk", - "version": "2.30.3", + "version": "2.30.4", "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.23.2" diff --git a/package.json b/package.json index a0179caff..fc4cdde34 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@mparticle/web-sdk", - "version": "2.30.3", + "version": "2.30.4", "description": "mParticle core SDK for web applications", "license": "Apache-2.0", "keywords": [ From 54114d69cc1e84482de0e189bc3bc5e6e9ee19f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 12 Nov 2024 19:26:13 +0000 Subject: [PATCH 9/9] chore(deps): bump cookie and socket.io Bumps [cookie](https://github.com/jshttp/cookie) and [socket.io](https://github.com/socketio/socket.io). These dependencies needed to be updated together. Updates `cookie` from 0.4.2 to 0.7.2 - [Release notes](https://github.com/jshttp/cookie/releases) - [Commits](https://github.com/jshttp/cookie/compare/v0.4.2...v0.7.2) Updates `socket.io` from 4.7.2 to 4.8.1 - [Release notes](https://github.com/socketio/socket.io/releases) - [Changelog](https://github.com/socketio/socket.io/blob/main/CHANGELOG.md) - [Commits](https://github.com/socketio/socket.io/compare/4.7.2...socket.io@4.8.1) --- updated-dependencies: - dependency-name: cookie dependency-type: indirect - dependency-name: socket.io dependency-type: indirect ... Signed-off-by: dependabot[bot] --- package-lock.json | 102 ++++++++++++++++------------------------------ 1 file changed, 36 insertions(+), 66 deletions(-) diff --git a/package-lock.json b/package-lock.json index eaee8a14d..3b2c83b3a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3723,9 +3723,9 @@ "dev": true }, "node_modules/@types/cors": { - "version": "2.8.15", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.15.tgz", - "integrity": "sha512-n91JxbNLD8eQIuXDIChAN1tCKNWCEgpceU9b7ZMbFA+P+Q4yIeh80jizFLEvolRPc1ES0VdwFlGv+kJTSirogw==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "dependencies": { "@types/node": "*" @@ -6731,9 +6731,9 @@ "dev": true }, "node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "engines": { "node": ">= 0.6" @@ -7850,9 +7850,9 @@ } }, "node_modules/engine.io": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz", - "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "dependencies": { "@types/cookie": "^0.4.1", @@ -7860,11 +7860,11 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" + "ws": "~8.17.1" }, "engines": { "node": ">=10.2.0" @@ -7913,27 +7913,6 @@ "node": ">=10.0.0" } }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/enhanced-resolve": { "version": "5.15.0", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", @@ -19921,16 +19900,16 @@ } }, "node_modules/socket.io": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", - "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" }, @@ -21770,9 +21749,9 @@ } }, "node_modules/ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "engines": { "node": ">=10.0.0" @@ -24594,9 +24573,9 @@ "dev": true }, "@types/cors": { - "version": "2.8.15", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.15.tgz", - "integrity": "sha512-n91JxbNLD8eQIuXDIChAN1tCKNWCEgpceU9b7ZMbFA+P+Q4yIeh80jizFLEvolRPc1ES0VdwFlGv+kJTSirogw==", + "version": "2.8.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", "dev": true, "requires": { "@types/node": "*" @@ -27053,9 +27032,9 @@ "dev": true }, "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true }, "core-js": { @@ -27893,9 +27872,9 @@ } }, "engine.io": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.3.tgz", - "integrity": "sha512-IML/R4eG/pUS5w7OfcDE0jKrljWS9nwnEfsxWCIJF5eO6AHo6+Hlv+lQbdlAYsiJPHzUthLm1RUjnBzWOs45cw==", + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.2.tgz", + "integrity": "sha512-gmNvsYi9C8iErnZdVcJnvCpSKbWTt1E8+JZo8b+daLninywUWi5NQ5STSHZ9rFjFO7imNcvb8Pc5pe/wMR5xEw==", "dev": true, "requires": { "@types/cookie": "^0.4.1", @@ -27903,20 +27882,11 @@ "@types/node": ">=10.0.0", "accepts": "~1.3.4", "base64id": "2.0.0", - "cookie": "~0.4.1", + "cookie": "~0.7.2", "cors": "~2.8.5", "debug": "~4.3.1", "engine.io-parser": "~5.2.1", - "ws": "~8.11.0" - }, - "dependencies": { - "ws": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", - "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", - "dev": true, - "requires": {} - } + "ws": "~8.17.1" } }, "engine.io-client": { @@ -36942,16 +36912,16 @@ "dev": true }, "socket.io": { - "version": "4.7.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.2.tgz", - "integrity": "sha512-bvKVS29/I5fl2FGLNHuXlQaUH/BlzX1IN6S+NKLNZpBsPZIDH+90eQmCs2Railn4YUiww4SzUedJ6+uzwFnKLw==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", "dev": true, "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "cors": "~2.8.5", "debug": "~4.3.2", - "engine.io": "~6.5.2", + "engine.io": "~6.6.0", "socket.io-adapter": "~2.5.2", "socket.io-parser": "~4.2.4" } @@ -38337,9 +38307,9 @@ } }, "ws": { - "version": "8.14.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.14.2.tgz", - "integrity": "sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==", + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", "dev": true, "requires": {} },