@mparticle/web-sdk 2.79.2 → 2.79.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,8 +1,16 @@
1
- export default function filteredMparticleUser(mpid: any, forwarder: any, mpInstance: any, kitBlocker: any): {
2
- getUserIdentities: () => {
3
- userIdentities: {};
1
+ import { IMParticleWebSDKInstance } from './mp-instance';
2
+ import { MPID } from '@mparticle/web-sdk';
3
+ import { Dictionary } from './utils';
4
+ import KitBlocker from './kitBlocking';
5
+ import { MPForwarder } from './forwarders.interfaces';
6
+ export interface IFilteredMparticleUser {
7
+ getUserIdentities(): {
8
+ userIdentities: Dictionary<string>;
4
9
  };
5
- getMPID: () => any;
6
- getUserAttributesLists: (forwarder: any) => {};
7
- getAllUserAttributes: () => {};
8
- };
10
+ getMPID(): MPID;
11
+ getUserAttributesLists(forwarder: MPForwarder): Dictionary<string[]>;
12
+ getAllUserAttributes(): Dictionary;
13
+ }
14
+ export default function filteredMparticleUser(mpid: MPID, forwarder: MPForwarder | {
15
+ userAttributeFilters: number[];
16
+ }, mpInstance: IMParticleWebSDKInstance, kitBlocker?: KitBlocker): IFilteredMparticleUser;
@@ -1,5 +1,5 @@
1
- export default function forwardingStatsUploader(mpInstance: any): void;
2
- export default class forwardingStatsUploader {
3
- constructor(mpInstance: any);
4
- startForwardingStatsTimer: () => void;
1
+ import { IMParticleWebSDKInstance } from './mp-instance';
2
+ export interface IForwardingStatsUploader {
3
+ startForwardingStatsTimer(): void;
5
4
  }
5
+ export default function forwardingStatsUploader(this: IForwardingStatsUploader, mpInstance: IMParticleWebSDKInstance): void;
@@ -3,7 +3,7 @@ import { ICookieSyncManager } from './cookieSyncManager';
3
3
  import { ISessionManager } from './sessionManager';
4
4
  import { IStore } from './store';
5
5
  import { IServerModel } from './serverModel';
6
- import ForwardingStatsUploader from './forwardingStatsUploader';
6
+ import { IForwardingStatsUploader } from './forwardingStatsUploader';
7
7
  import { IConsent } from './consent';
8
8
  import IdentityAPIClient from './identityApiClient';
9
9
  import IntegrationCapture from './integrationCapture';
@@ -39,7 +39,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
39
39
  _Ecommerce: IECommerce;
40
40
  _Events: IEvents;
41
41
  _Forwarders: any;
42
- _ForwardingStatsUploader: ForwardingStatsUploader;
42
+ _ForwardingStatsUploader: IForwardingStatsUploader;
43
43
  _Helpers: SDKHelpersApi;
44
44
  _Identity: IIdentity;
45
45
  _IdentityAPIClient: typeof IdentityAPIClient;
@@ -62,6 +62,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
62
62
  captureTiming(metricName: string): any;
63
63
  processQueueOnIdentityFailure?: () => void;
64
64
  processQueueOnNoFunctional?: () => void;
65
+ uiwebviewBridgeName?: string;
65
66
  }
66
67
  /**
67
68
  * <p>All of the following methods can be called on the primary mParticle class. In version 2.10.0, we introduced <a href="https://docs.mparticle.com/developers/sdk/web/multiple-instances/">multiple instances</a>. If you are using multiple instances (self hosted environments only), you should call these methods on each instance.</p>
@@ -1,12 +1,3 @@
1
- export default function NativeSdkHelpers(mpInstance: any): void;
2
- export default class NativeSdkHelpers {
3
- constructor(mpInstance: any);
4
- initializeSessionAttributes: (apiKey: any) => void;
5
- isBridgeV2Available: (bridgeName: any) => boolean;
6
- isWebviewEnabled: (requiredWebviewBridgeName: any, minWebviewBridgeVersion: any) => any;
7
- isBridgeV1Available: () => boolean;
8
- sendToNative: (path: any, value: any) => void;
9
- sendViaBridgeV1: (path: any, value: any) => void;
10
- sendViaIframeToIOS: (path: any, value: any) => void;
11
- sendViaBridgeV2: (path: any, value: any, requiredWebviewBridgeName: any) => void;
12
- }
1
+ import { IMParticleWebSDKInstance } from './mp-instance';
2
+ import { INativeSdkHelpers } from './nativeSdkHelpers.interfaces';
3
+ export default function NativeSdkHelpers(this: INativeSdkHelpers, mpInstance: IMParticleWebSDKInstance): void;
@@ -1,3 +1,17 @@
1
+ export interface IWKScriptMessageHandler {
2
+ postMessage(message: string): void;
3
+ }
4
+ export interface IAndroidNativeBridge {
5
+ [methodName: string]: ((payload?: string) => void) | undefined;
6
+ }
7
+ declare global {
8
+ interface Window {
9
+ webkit?: {
10
+ messageHandlers?: Record<string, IWKScriptMessageHandler | undefined>;
11
+ };
12
+ mParticleAndroid?: IAndroidNativeBridge;
13
+ }
14
+ }
1
15
  export interface INativeSdkHelpers {
2
16
  initializeSessionAttributes: (apiKey: string) => void;
3
17
  isBridgeV2Available: (bridgeName: string) => boolean;
@@ -6,5 +20,5 @@ export interface INativeSdkHelpers {
6
20
  sendToNative: (path: string, value?: string) => void;
7
21
  sendViaBridgeV1: (path: string, value: string) => void;
8
22
  sendViaIframeToIOS: (path: string, value: string) => void;
9
- sendViaBridgeV2: (path: string, value: string, requiredWebviewBridgeName: boolean) => void;
23
+ sendViaBridgeV2: (path: string, value: string, requiredWebviewBridgeName: string) => void;
10
24
  }
@@ -1,34 +1,38 @@
1
1
  import { IMParticleWebSDKInstance } from './mp-instance';
2
- export declare const WIN_TRACKER_KEY = "__mpApvTracker__";
3
- export declare const WIN_INIT_PV_KEY: "__mpApvInitPVLogged__";
4
- export type WindowWithApvFlags = Window & {
5
- [WIN_TRACKER_KEY]?: PageViewTracker;
6
- [WIN_INIT_PV_KEY]?: boolean;
7
- };
2
+ import { BaseEvent } from './sdkRuntimeModels';
3
+ type HistoryMethodName = 'pushState' | 'replaceState';
4
+ type NavigationSource = HistoryMethodName | 'popstate';
5
+ export declare const WIN_APV_KEY = "__mpApv__";
6
+ interface IPageViewData {
7
+ hostname: string;
8
+ title: string;
9
+ path: string;
10
+ }
11
+ export declare const isNewPage: (lastPath: string | null, candidatePath: string) => boolean;
12
+ export declare const supportsHistoryTracking: (win: Window | null) => boolean;
13
+ export declare const buildPageViewEvent: (data: IPageViewData) => BaseEvent;
14
+ export declare const getActiveTracker: () => PageViewTracker | undefined;
15
+ export declare const hasInitialPageViewFired: () => boolean;
16
+ export declare const markInitialPageViewFired: () => void;
17
+ export declare const resetPageViewTracking: () => void;
18
+ export declare const patchHistory: (onNavigate: (source: NavigationSource) => void, log: (message: string) => void) => (() => void) | null;
8
19
  export declare class PageViewTracker {
9
- static hasInitialPageViewFired(): boolean;
10
- static markInitialPageViewFired(): void;
11
- static resetWindowState(instanceTracker?: PageViewTracker): void;
12
- mpInstance: IMParticleWebSDKInstance;
20
+ private readonly mpInstance;
13
21
  private lastPath;
14
- private _isActive;
15
- get isActive(): boolean;
22
+ private active;
16
23
  private pendingNavigations;
17
- private originalPushState;
18
- private originalReplaceState;
19
- private pushStateWrapper;
20
- private replaceStateWrapper;
24
+ private undoHistoryPatch;
21
25
  private popStateListener;
22
26
  constructor(mpInstance: IMParticleWebSDKInstance);
23
- private isSupportedEnvironment;
27
+ get isActive(): boolean;
24
28
  init(): void;
25
- private patchHistoryMethods;
26
- private addNavigationListeners;
29
+ teardown(): void;
30
+ private retire;
31
+ private takePendingNavigations;
27
32
  private safeHandleNavigation;
28
- private getCurrentKey;
29
33
  private handleNavigation;
34
+ private scheduleFire;
30
35
  private firePageView;
31
- takePendingNavigations(): string[];
32
- private restoreHistoryMethod;
33
- teardown(): void;
36
+ private log;
34
37
  }
38
+ export {};
@@ -204,6 +204,7 @@ export interface IMParticleInstanceManager extends MParticleWebSDK {
204
204
  sessionManager: Pick<ISessionManager, 'getSession'>;
205
205
  Store: IStore;
206
206
  getInstance(instanceName?: string): IMParticleWebSDKInstance;
207
+ uiwebviewBridgeName?: string;
207
208
  }
208
209
  export type BooleanStringLowerCase = 'false' | 'true';
209
210
  export type BooleanStringTitleCase = 'False' | 'True';
@@ -260,7 +261,7 @@ export interface SDKHelpersApi {
260
261
  createXHR?(cb: () => void): XMLHttpRequest;
261
262
  extend?(...args: any[]): any;
262
263
  findKeyInObject?(obj: any, key: string): string;
263
- parseNumber?(value: string | number): number;
264
+ parseNumber(value: string | number): number;
264
265
  generateUniqueId(): any;
265
266
  generateHash?(value: string): number;
266
267
  getFeatureFlag?(feature: string): boolean | string;
@@ -268,8 +269,8 @@ export interface SDKHelpersApi {
268
269
  parseStringOrNumber?(value: string | number): string | number | null;
269
270
  inArray?(items: any[], value: any): boolean;
270
271
  converted?(s: string): string;
271
- filterUserIdentitiesForForwarders?(userIdentities: Dictionary, filterList: number[]): Dictionary;
272
- filterUserAttributes?(userAttributes: Dictionary, filterList: number[]): Dictionary;
272
+ filterUserIdentitiesForForwarders(userIdentities: Dictionary, filterList: number[]): Dictionary;
273
+ filterUserAttributes(userAttributes: Dictionary, filterList: number[]): Dictionary;
273
274
  filterUserIdentities?(userIdentitiesObject: Dictionary<string>, filterList: number[]): ISDKUserIdentity[];
274
275
  invokeAliasCallback(aliasCallback: IAliasCallback, number: number, errorMessage?: string): void;
275
276
  isDelayedByIntegration?(delayedIntegrations: Dictionary<boolean>, timeoutStart: number, now: number): boolean;
@@ -124,6 +124,8 @@ export interface IStore {
124
124
  pixelConfigurations: IPixelConfiguration[];
125
125
  integrationDelayTimeoutStart: number;
126
126
  webviewBridgeEnabled?: boolean;
127
+ bridgeV1Available?: boolean;
128
+ bridgeV2Available?: boolean;
127
129
  wrapperSDKInfo: WrapperSDKInfo;
128
130
  roktAccountId: string | null;
129
131
  integrationName: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.79.2",
3
+ "version": "2.79.3",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
@@ -0,0 +1,160 @@
1
+ import Types from './types';
2
+ import { IMParticleWebSDKInstance } from './mp-instance';
3
+ import { MPID, UserIdentities } from '@mparticle/web-sdk';
4
+ import { Dictionary } from './utils';
5
+ import KitBlocker from './kitBlocking';
6
+ import { MPForwarder } from './forwarders.interfaces';
7
+
8
+ export interface IFilteredMparticleUser {
9
+ getUserIdentities(): { userIdentities: Dictionary<string> };
10
+ getMPID(): MPID;
11
+ getUserAttributesLists(forwarder: MPForwarder): Dictionary<string[]>;
12
+ getAllUserAttributes(): Dictionary;
13
+ }
14
+
15
+ function isAttributeKeyAllowed(
16
+ kitBlocker: KitBlocker | undefined,
17
+ key: string
18
+ ): boolean {
19
+ return !kitBlocker?.isAttributeKeyBlocked(key);
20
+ }
21
+
22
+ function isIdentityAllowed(
23
+ kitBlocker: KitBlocker | undefined,
24
+ identityName: string
25
+ ): boolean {
26
+ return !kitBlocker?.isIdentityBlocked(identityName);
27
+ }
28
+
29
+ function copyUserAttributeValue(value: unknown): unknown {
30
+ return Array.isArray(value) ? (value as string[]).slice() : value;
31
+ }
32
+
33
+ function buildUserAttributesCopy(
34
+ userAttributes?: Dictionary,
35
+ kitBlocker?: KitBlocker
36
+ ): Dictionary {
37
+ const userAttributesCopy: Dictionary = {};
38
+
39
+ if (!userAttributes) {
40
+ return userAttributesCopy;
41
+ }
42
+
43
+ for (const prop in userAttributes) {
44
+ if (
45
+ !userAttributes.hasOwnProperty(prop) ||
46
+ !isAttributeKeyAllowed(kitBlocker, prop)
47
+ ) {
48
+ continue;
49
+ }
50
+
51
+ userAttributesCopy[prop] = copyUserAttributeValue(
52
+ userAttributes[prop]
53
+ );
54
+ }
55
+
56
+ return userAttributesCopy;
57
+ }
58
+
59
+ function buildUserAttributeLists(
60
+ userAttributes: Dictionary,
61
+ kitBlocker?: KitBlocker
62
+ ): Dictionary<string[]> {
63
+ const userAttributesLists: Dictionary<string[]> = {};
64
+
65
+ for (const key in userAttributes) {
66
+ if (
67
+ !userAttributes.hasOwnProperty(key) ||
68
+ !Array.isArray(userAttributes[key]) ||
69
+ !isAttributeKeyAllowed(kitBlocker, key)
70
+ ) {
71
+ continue;
72
+ }
73
+
74
+ userAttributesLists[key] = userAttributes[key].slice();
75
+ }
76
+
77
+ return userAttributesLists;
78
+ }
79
+
80
+ function buildFilteredUserIdentities(
81
+ identities: UserIdentities,
82
+ kitBlocker: KitBlocker | undefined,
83
+ parseNumber: (value: string | number) => number
84
+ ): Dictionary<string> {
85
+ const currentUserIdentities: Dictionary<string> = {};
86
+ const identitiesByType = identities as Dictionary<string>;
87
+
88
+ for (const identityType in identitiesByType) {
89
+ if (!identitiesByType.hasOwnProperty(identityType)) {
90
+ continue;
91
+ }
92
+
93
+ const identityName = Types.IdentityType.getIdentityName(
94
+ parseNumber(identityType)
95
+ );
96
+
97
+ if (!isIdentityAllowed(kitBlocker, identityName)) {
98
+ continue;
99
+ }
100
+
101
+ currentUserIdentities[identityName] = identitiesByType[identityType];
102
+ }
103
+
104
+ return currentUserIdentities;
105
+ }
106
+
107
+ export default function filteredMparticleUser(
108
+ mpid: MPID,
109
+ forwarder: MPForwarder | { userAttributeFilters: number[] },
110
+ mpInstance: IMParticleWebSDKInstance,
111
+ kitBlocker?: KitBlocker
112
+ ): IFilteredMparticleUser {
113
+ function getAllUserAttributes(): Dictionary {
114
+ const userAttributesCopy = buildUserAttributesCopy(
115
+ mpInstance._Store.getUserAttributes(mpid),
116
+ kitBlocker
117
+ );
118
+
119
+ return mpInstance._Helpers.filterUserAttributes(
120
+ userAttributesCopy,
121
+ (forwarder as MPForwarder).userAttributeFilters
122
+ );
123
+ }
124
+
125
+ return {
126
+ getUserIdentities: function(): { userIdentities: Dictionary<string> } {
127
+ let currentUserIdentities = buildFilteredUserIdentities(
128
+ mpInstance._Store.getUserIdentities(mpid),
129
+ kitBlocker,
130
+ mpInstance._Helpers.parseNumber
131
+ );
132
+
133
+ currentUserIdentities = mpInstance._Helpers.filterUserIdentitiesForForwarders(
134
+ currentUserIdentities,
135
+ (forwarder as MPForwarder).userIdentityFilters
136
+ );
137
+
138
+ return {
139
+ userIdentities: currentUserIdentities,
140
+ };
141
+ },
142
+ getMPID: function(): MPID {
143
+ return mpid;
144
+ },
145
+ getUserAttributesLists: function(
146
+ forwarder: MPForwarder
147
+ ): Dictionary<string[]> {
148
+ const userAttributesLists = buildUserAttributeLists(
149
+ getAllUserAttributes(),
150
+ kitBlocker
151
+ );
152
+
153
+ return mpInstance._Helpers.filterUserAttributes(
154
+ userAttributesLists,
155
+ forwarder.userAttributeFilters
156
+ ) as Dictionary<string[]>;
157
+ },
158
+ getAllUserAttributes: getAllUserAttributes,
159
+ };
160
+ }
@@ -1,12 +1,25 @@
1
- export default function forwardingStatsUploader(mpInstance) {
2
- this.startForwardingStatsTimer = function() {
3
- mParticle._forwardingStatsTimer = setInterval(function() {
4
- prepareAndSendForwardingStatsBatch();
5
- }, mpInstance._Store.SDKConfig.forwarderStatsTimeout);
1
+ import { IMParticleWebSDKInstance } from './mp-instance';
2
+ import { Dictionary } from './utils';
3
+
4
+ export interface IForwardingStatsUploader {
5
+ startForwardingStatsTimer(): void;
6
+ }
7
+
8
+ export default function forwardingStatsUploader(
9
+ this: IForwardingStatsUploader,
10
+ mpInstance: IMParticleWebSDKInstance
11
+ ): void {
12
+ this.startForwardingStatsTimer = function(): void {
13
+ (window.mParticle as Dictionary)._forwardingStatsTimer = setInterval(
14
+ function() {
15
+ prepareAndSendForwardingStatsBatch();
16
+ },
17
+ (mpInstance._Store.SDKConfig as Dictionary).forwarderStatsTimeout
18
+ );
6
19
  };
7
20
 
8
- function prepareAndSendForwardingStatsBatch() {
9
- var forwarderQueue = mpInstance._Forwarders.getForwarderStatsQueue(),
21
+ function prepareAndSendForwardingStatsBatch(): void {
22
+ const forwarderQueue = mpInstance._Forwarders.getForwarderStatsQueue(),
10
23
  uploadsTable =
11
24
  mpInstance._Persistence.forwardingStatsBatches.uploadsTable,
12
25
  now = Date.now();
@@ -16,11 +29,11 @@ export default function forwardingStatsUploader(mpInstance) {
16
29
  mpInstance._Forwarders.setForwarderStatsQueue([]);
17
30
  }
18
31
 
19
- for (var date in uploadsTable) {
20
- (function(date) {
32
+ for (const date in uploadsTable) {
33
+ (function(date: string) {
21
34
  if (uploadsTable.hasOwnProperty(date)) {
22
35
  if (uploadsTable[date].uploading === false) {
23
- var xhrCallback = function() {
36
+ const xhrCallback = function(): void {
24
37
  if (xhr.readyState === 4) {
25
38
  if (xhr.status === 200 || xhr.status === 202) {
26
39
  mpInstance.Logger.verbose(
@@ -39,8 +52,8 @@ export default function forwardingStatsUploader(mpInstance) {
39
52
  }
40
53
  };
41
54
 
42
- var xhr = mpInstance._Helpers.createXHR(xhrCallback);
43
- var forwardingStatsData = uploadsTable[date].data;
55
+ const xhr = mpInstance._Helpers.createXHR(xhrCallback);
56
+ const forwardingStatsData = uploadsTable[date].data;
44
57
  uploadsTable[date].uploading = true;
45
58
  mpInstance._APIClient.sendBatchForwardingStatsToServer(
46
59
  forwardingStatsData,
@@ -30,7 +30,9 @@ import Persistence from './persistence';
30
30
  import Events from './events';
31
31
  import Forwarders from './forwarders';
32
32
  import ServerModel, { IServerModel } from './serverModel';
33
- import ForwardingStatsUploader from './forwardingStatsUploader';
33
+ import ForwardingStatsUploader, {
34
+ IForwardingStatsUploader,
35
+ } from './forwardingStatsUploader';
34
36
  import Identity from './identity';
35
37
  import Consent, { IConsent } from './consent';
36
38
  import KitBlocker from './kitBlocking';
@@ -57,7 +59,12 @@ import { LoggingDispatcher } from './reporting/loggingDispatcher';
57
59
  import { IErrorReportingService, ILoggingService } from './reporting/types';
58
60
  import { logDeprecatedMethodUsage } from './reporting/deprecatedMethodLogger';
59
61
  import { normalizeRoktLauncherOptions } from './roktLauncherOptions';
60
- import { PageViewTracker } from './pageViewTracker';
62
+ import {
63
+ hasInitialPageViewFired,
64
+ markInitialPageViewFired,
65
+ PageViewTracker,
66
+ resetPageViewTracking,
67
+ } from './pageViewTracker';
61
68
 
62
69
  export interface IErrorLogMessage {
63
70
  message?: string;
@@ -82,7 +89,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
82
89
  _Ecommerce: IECommerce;
83
90
  _Events: IEvents;
84
91
  _Forwarders: any; // https://go.mparticle.com/work/SQDSDKS-5767
85
- _ForwardingStatsUploader: ForwardingStatsUploader;
92
+ _ForwardingStatsUploader: IForwardingStatsUploader;
86
93
  _Helpers: SDKHelpersApi;
87
94
  _Identity: IIdentity;
88
95
  _IdentityAPIClient: typeof IdentityAPIClient;
@@ -105,6 +112,7 @@ export interface IMParticleWebSDKInstance extends MParticleWebSDK {
105
112
  captureTiming(metricName: string);
106
113
  processQueueOnIdentityFailure?: () => void;
107
114
  processQueueOnNoFunctional?: () => void;
115
+ uiwebviewBridgeName?: string;
108
116
  }
109
117
 
110
118
  const { Messages, HTTPCodes, FeatureFlags, CaptureIntegrationSpecificIdsV2Modes } = Constants;
@@ -298,12 +306,8 @@ export default function mParticleInstance(this: IMParticleWebSDKInstance, instan
298
306
  );
299
307
  instance._Events.stopTracking();
300
308
 
301
- const instanceTracker = instance._PageViewTracker;
302
- if (instanceTracker) {
303
- instanceTracker.teardown();
304
- instance._PageViewTracker = undefined;
305
- }
306
- PageViewTracker.resetWindowState(instanceTracker);
309
+ resetPageViewTracking();
310
+ instance._PageViewTracker = undefined;
307
311
 
308
312
  if (!keepPersistence) {
309
313
  instance._Persistence.resetPersistence();
@@ -1593,32 +1597,30 @@ function completeSDKInitialization(apiKey, config, mpInstance) {
1593
1597
  mpInstance._SessionManager.initialize();
1594
1598
  mpInstance._Events.logAST();
1595
1599
 
1596
- // Note: APV uses window-level singletons (WIN_TRACKER_KEY, WIN_INIT_PV_KEY)
1597
- // that assume a single active SDK instance. Multiple-instance support is
1598
- // out of scope
1600
+ // Note: APV state (the active tracker and the initial-page-view flag) is
1601
+ // window-scoped and assumes a single active SDK instance. Multiple-instance
1602
+ // support is out of scope.
1599
1603
  if (getFeatureFlag(AutoLogPageView)) {
1600
1604
  if (!mpInstance._PageViewTracker) {
1601
1605
  mpInstance.Logger.verbose(
1602
1606
  'mParticle APV: [sdk-init] creating new PageViewTracker for this instance'
1603
1607
  );
1604
1608
  mpInstance._PageViewTracker = new PageViewTracker(mpInstance);
1609
+ }
1605
1610
 
1606
- // Fire the initial page view once per page load (hard navigation).
1607
- // The flag survives module re-evaluation so repeated init() calls
1608
- // from SPA re-renders don't fire duplicate logPageView() events.
1609
- if (PageViewTracker.hasInitialPageViewFired()) {
1610
- mpInstance.Logger.verbose(
1611
- 'mParticle APV: [sdk-init] initial page view already logged this page load, skipping'
1612
- );
1613
- } else {
1614
- PageViewTracker.markInitialPageViewFired();
1615
- mpInstance._Events.logPageView();
1616
- }
1617
- } else {
1611
+ // The initial page view fires once per hard page load, not once per
1612
+ // init(): the window flag survives the module re-evaluation Next.js
1613
+ // performs on every SPA navigation, so repeated init() calls from SPA
1614
+ // re-renders don't fire duplicate logPageView() events.
1615
+ if (hasInitialPageViewFired()) {
1618
1616
  mpInstance.Logger.verbose(
1619
- 'mParticle APV: [sdk-init] tracker already on this instance, skipping logPageView'
1617
+ 'mParticle APV: [sdk-init] initial page view already logged this page load, skipping'
1620
1618
  );
1619
+ } else {
1620
+ markInitialPageViewFired();
1621
+ mpInstance._Events.logPageView();
1621
1622
  }
1623
+
1622
1624
  mpInstance._PageViewTracker.init();
1623
1625
  } else if (mpInstance._PageViewTracker) {
1624
1626
  // AutoLogPageView was disabled on re-init: tear down the active tracker
@@ -1,3 +1,23 @@
1
+ export interface IWKScriptMessageHandler {
2
+ postMessage(message: string): void;
3
+ }
4
+
5
+ export interface IAndroidNativeBridge {
6
+ [methodName: string]: ((payload?: string) => void) | undefined;
7
+ }
8
+
9
+ declare global {
10
+ interface Window {
11
+ webkit?: {
12
+ messageHandlers?: Record<
13
+ string,
14
+ IWKScriptMessageHandler | undefined
15
+ >;
16
+ };
17
+ mParticleAndroid?: IAndroidNativeBridge;
18
+ }
19
+ }
20
+
1
21
  export interface INativeSdkHelpers {
2
22
  initializeSessionAttributes: (apiKey: string) => void;
3
23
  isBridgeV2Available: (bridgeName: string) => boolean;
@@ -9,5 +29,5 @@ export interface INativeSdkHelpers {
9
29
  sendToNative: (path: string, value?: string) => void;
10
30
  sendViaBridgeV1: (path: string, value: string) => void;
11
31
  sendViaIframeToIOS: (path: string, value: string) => void;
12
- sendViaBridgeV2: (path: string, value: string, requiredWebviewBridgeName: boolean) => void;
32
+ sendViaBridgeV2: (path: string, value: string, requiredWebviewBridgeName: string) => void;
13
33
  }