@mparticle/web-sdk 2.79.3 → 2.80.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,16 +1,23 @@
1
1
  import { IMParticleWebSDKInstance } from './mp-instance';
2
2
  import { BaseEvent } from './sdkRuntimeModels';
3
+ import { Dictionary } from './utils';
3
4
  type HistoryMethodName = 'pushState' | 'replaceState';
4
5
  type NavigationSource = HistoryMethodName | 'popstate';
5
6
  export declare const WIN_APV_KEY = "__mpApv__";
6
- interface IPageViewData {
7
+ export declare const ALLOWED_QUERY_PARAMS: string[];
8
+ interface IPageSnapshot {
9
+ path: string;
10
+ params: Dictionary<string>;
11
+ }
12
+ interface IPageViewData extends IPageSnapshot {
7
13
  hostname: string;
8
14
  title: string;
9
- path: string;
10
15
  }
11
- export declare const isNewPage: (lastPath: string | null, candidatePath: string) => boolean;
16
+ export declare const allowedQueryParams: (href: string) => Dictionary<string>;
17
+ export declare const pageKey: (page: IPageSnapshot) => string;
18
+ export declare const isNewPage: (lastKey: string | null, candidateKey: string) => boolean;
12
19
  export declare const supportsHistoryTracking: (win: Window | null) => boolean;
13
- export declare const buildPageViewEvent: (data: IPageViewData) => BaseEvent;
20
+ export declare const buildPageViewEvent: ({ params, hostname, title, path, }: IPageViewData) => BaseEvent;
14
21
  export declare const getActiveTracker: () => PageViewTracker | undefined;
15
22
  export declare const hasInitialPageViewFired: () => boolean;
16
23
  export declare const markInitialPageViewFired: () => void;
@@ -18,7 +25,7 @@ export declare const resetPageViewTracking: () => void;
18
25
  export declare const patchHistory: (onNavigate: (source: NavigationSource) => void, log: (message: string) => void) => (() => void) | null;
19
26
  export declare class PageViewTracker {
20
27
  private readonly mpInstance;
21
- private lastPath;
28
+ private lastPage;
22
29
  private active;
23
30
  private pendingNavigations;
24
31
  private undoHistoryPatch;
@@ -1,44 +1,3 @@
1
- export default function _Persistence(mpInstance: any): void;
2
- export default class _Persistence {
3
- constructor(mpInstance: any);
4
- useLocalStorage: () => any;
5
- initializeStorage: () => void;
6
- update: () => void;
7
- storeDataInMemory: (obj: any, currentMPID: any) => void;
8
- determineLocalStorageAvailability: (storage: any) => any;
9
- setLocalStorage: () => void;
10
- getLocalStorage: () => {};
11
- expireCookies: (cookieName: any) => void;
12
- getCookie: () => any;
13
- setCookie: () => void;
14
- reduceAndEncodePersistence: (persistence: any, expires: any, domain: any, maxCookieSize: any) => string;
15
- findPrevCookiesBasedOnUI: (identityApiData: any) => void;
16
- encodePersistence: (persistence: any) => string;
17
- decodePersistence: (persistence: any) => string;
18
- getCookieDomain: () => any;
19
- getDomain: (doc: any, locationHostname: any) => any;
20
- saveUserCookieSyncDatesToPersistence: (mpid: any, csd: any) => void;
21
- swapCurrentUser: (previousMPID: any, currentMPID: any, currentSessionMPIDs: any) => void;
22
- savePersistence: (persistence: any) => void;
23
- getPersistence: () => any;
24
- getFirstSeenTime: (mpid: any) => any;
25
- /**
26
- * set the "first seen" time for a user. the time will only be set once for a given
27
- * mpid after which subsequent calls will be ignored
28
- */
29
- setFirstSeenTime: (mpid: any, time: any) => void;
30
- /**
31
- * returns the "last seen" time for a user. If the mpid represents the current user, the
32
- * return value will always be the current time, otherwise it will be to stored "last seen"
33
- * time
34
- */
35
- getLastSeenTime: (mpid: any) => any;
36
- setLastSeenTime: (mpid: any, time: any) => void;
37
- getDeviceId: () => any;
38
- setDeviceId: (guid: any) => void;
39
- resetPersistence: () => void;
40
- forwardingStatsBatches: {
41
- uploadsTable: {};
42
- forwardingStatsEventQueue: any[];
43
- };
44
- }
1
+ import { IMParticleWebSDKInstance } from './mp-instance';
2
+ import { IPersistence } from './persistence.interfaces';
3
+ export default function _Persistence(this: IPersistence, mpInstance: IMParticleWebSDKInstance): void;
@@ -30,7 +30,7 @@ export interface IGlobalStoreV2MinifiedKeys {
30
30
  export interface IPersistenceMinified extends Dictionary {
31
31
  cu: MPID;
32
32
  gs: IGlobalStoreV2MinifiedKeys;
33
- l: boolean;
33
+ l: boolean | 0 | 1;
34
34
  }
35
35
  export interface IUserPersistenceMinified extends Dictionary {
36
36
  csd: CookieSyncDates;
@@ -45,8 +45,8 @@ export interface IPersistence {
45
45
  useLocalStorage(): boolean;
46
46
  initializeStorage(): void;
47
47
  update(): void;
48
- storeDataInMemory(obj: IPersistenceMinified, currentMPID: MPID): void;
49
- determineLocalStorageAvailability(storage: Storage): boolean;
48
+ storeDataInMemory(obj: IPersistenceMinified, currentMPID?: MPID): void;
49
+ determineLocalStorageAvailability(storage?: Storage): boolean;
50
50
  setLocalStorage(): void;
51
51
  getLocalStorage(): IPersistenceMinified | null;
52
52
  expireCookies(cookieName: string): void;
@@ -54,17 +54,17 @@ export interface IPersistence {
54
54
  setCookie(): void;
55
55
  reduceAndEncodePersistence(persistence: IPersistenceMinified, expires: string, domain: string, maxCookieSize: number): string;
56
56
  findPrevCookiesBasedOnUI(identityApiData: IdentityApiData): void;
57
- encodePersistence(persistence: IPersistenceMinified): string;
58
- decodePersistence(persistenceString: string): string;
57
+ encodePersistence(persistence: string): string;
58
+ decodePersistence(persistenceString: string | null): string | void;
59
59
  getCookieDomain(): string;
60
- getDomain(doc: string, locationHostname: string): string;
60
+ getDomain(doc: Document, locationHostname: string): string;
61
61
  saveUserCookieSyncDatesToPersistence(mpid: MPID, csd: CookieSyncDates): void;
62
62
  savePersistence(persistance: IPersistenceMinified): void;
63
- getPersistence(): IPersistenceMinified;
64
- getFirstSeenTime(mpid: MPID): string | null;
65
- setFirstSeenTime(mpid: MPID, time: number): void;
63
+ getPersistence(): IPersistenceMinified | null;
64
+ getFirstSeenTime(mpid: MPID): number | null;
65
+ setFirstSeenTime(mpid: MPID, time?: number): void;
66
66
  getLastSeenTime(mpid: MPID): number | null;
67
- setLastSeenTime(mpid: MPID, time: number): void;
67
+ setLastSeenTime(mpid: MPID, time?: number): void;
68
68
  getDeviceId(): string;
69
69
  setDeviceId(guid: string): void;
70
70
  resetPersistence(): void;
@@ -197,6 +197,7 @@ export interface IMParticleInstanceManager extends MParticleWebSDK {
197
197
  _BatchValidator: _BatchValidator;
198
198
  _instances: Dictionary<IMParticleWebSDKInstance>;
199
199
  _isTestEnv?: boolean;
200
+ _forceNoLocalStorage?: boolean;
200
201
  config: SDKInitConfig;
201
202
  isIOS?: boolean;
202
203
  MPSideloadedKit: typeof MPSideloadedKit;
@@ -29,6 +29,7 @@ export interface SDKConfig {
29
29
  kits: Dictionary<UnregisteredKit>;
30
30
  logLevel?: LogLevelType;
31
31
  cookieDomain?: string;
32
+ cookieExpiration?: number;
32
33
  maxCookieSize?: number | undefined;
33
34
  minWebviewBridgeVersion: 1 | 2 | undefined;
34
35
  identifyRequest: IdentifyRequest;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mparticle/web-sdk",
3
- "version": "2.79.3",
3
+ "version": "2.80.0",
4
4
  "description": "mParticle core SDK for web applications",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
package/src/events.ts CHANGED
@@ -20,7 +20,8 @@ import {
20
20
  SDKEventOptions,
21
21
  TransactionAttributes,
22
22
  } from '@mparticle/web-sdk';
23
- import { valueof } from './utils';
23
+ import { getHref, valueof } from './utils';
24
+ import { allowedQueryParams } from './pageViewTracker';
24
25
 
25
26
  interface DOMHandlerElement extends HTMLElement {
26
27
  href?: string;
@@ -144,11 +145,18 @@ export default function Events(
144
145
  self.logEvent({ messageType: Types.MessageType.AppStateTransition });
145
146
  };
146
147
 
148
+ // The auto page view for the landing page. The SPA navigations that follow it
149
+ // come from PageViewTracker instead, so both emitters attach the same
150
+ // allowlisted query params — and this is the one that matters for campaign
151
+ // attribution, since utm_*/gclid live on the entry URL.
147
152
  this.logPageView = function(): void {
148
153
  self.logEvent({
149
154
  messageType: Types.MessageType.PageView,
150
155
  name: 'PageView',
151
156
  data: {
157
+ // Params first so the core fields always win. See
158
+ // buildPageViewEvent, which does the same for SPA views.
159
+ ...allowedQueryParams(getHref()),
152
160
  hostname: window.location.hostname,
153
161
  title: window.document.title,
154
162
  },
@@ -1,6 +1,7 @@
1
1
  import { IMParticleWebSDKInstance } from './mp-instance';
2
2
  import { BaseEvent } from './sdkRuntimeModels';
3
3
  import { EventType, MessageType } from './types';
4
+ import { Dictionary, getHref, queryStringParser } from './utils';
4
5
 
5
6
  type HistoryStateMethod = History['pushState'];
6
7
  type HistoryMethodName = 'pushState' | 'replaceState';
@@ -41,14 +42,71 @@ type WindowWithApv = Window & {
41
42
  [WIN_APV_KEY]?: IApvState;
42
43
  };
43
44
 
44
- interface IPageViewData {
45
+ // The query params an auto page view may carry. An allowlist, not a denylist:
46
+ // partner URLs routinely hold order ids, email addresses and session tokens, and
47
+ // none of those should reach the event stream because someone forgot to exclude
48
+ // them. Anything absent from this list is dropped.
49
+ //
50
+ // SECURITY: `code`, `state` and `nonce` are the OAuth 2.0 / OIDC authorization
51
+ // code and the CSRF/replay tokens. They are credentials until redeemed, and
52
+ // attaching them here persists them in the event store and forwards them to
53
+ // every configured kit. They are on the list by explicit product decision —
54
+ // deleting that line is the whole of the fix if that decision is revisited.
55
+ export const ALLOWED_QUERY_PARAMS: string[] = [
56
+ // Campaign attribution
57
+ 'utm_source',
58
+ 'utm_medium',
59
+ 'utm_campaign',
60
+ 'utm_term',
61
+ 'utm_content',
62
+ 'utm_id',
63
+
64
+ // Ad-network click ids
65
+ 'gclid',
66
+ 'gbraid',
67
+ 'wbraid',
68
+ 'fbclid',
69
+ 'msclkid',
70
+ 'ttclid',
71
+ 'twclid',
72
+ 'li_fat_id',
73
+ 'dclid',
74
+
75
+ // OAuth / OIDC — see the SECURITY note above
76
+ 'client_id',
77
+ 'redirect_uri',
78
+ 'response_type',
79
+ 'scope',
80
+ 'state',
81
+ 'code',
82
+ 'nonce',
83
+
84
+ // Pagination and search
85
+ 'page',
86
+ 'limit',
87
+ 'offset',
88
+ 'cursor',
89
+ 'per_page',
90
+ 'q',
91
+ 'search',
92
+
93
+ // Referral
94
+ 'ref',
95
+ 'referrer',
96
+ ];
97
+
98
+ interface IPageSnapshot {
99
+ path: string;
100
+ params: Dictionary<string>;
101
+ }
102
+
103
+ interface IPageViewData extends IPageSnapshot {
45
104
  hostname: string;
46
105
  title: string;
47
- path: string;
48
106
  }
49
107
 
50
108
  interface IPendingNavigation {
51
- path: string;
109
+ page: IPageSnapshot;
52
110
  timeoutId: ReturnType<typeof setTimeout>;
53
111
  }
54
112
 
@@ -57,12 +115,46 @@ interface IPendingNavigation {
57
115
  // on their own, which is where the interesting rules live.
58
116
  // ---------------------------------------------------------------------------
59
117
 
60
- // Dedup keys on pathname only: a query-string- or hash-only change is the same
61
- // page and must not fire a view.
118
+ // Pulls the allowlisted query params off a URL. Delegates to the SDK's own
119
+ // parser, which lowercases keys (so `?UTM_Source=` and `?utm_source=` land on one
120
+ // attribute), drops empty values, and carries the fallback for browsers without
121
+ // URLSearchParams. Tolerates an empty href, so SSR yields no params rather than
122
+ // throwing.
123
+ export const allowedQueryParams = (href: string): Dictionary<string> =>
124
+ queryStringParser(href, ALLOWED_QUERY_PARAMS);
125
+
126
+ // The captured params, in allowlist order. Ordering comes from the constant
127
+ // rather than a sort: it is deterministic without needing a comparator, and it
128
+ // does not depend on the object's insertion order, so reordering the query string
129
+ // cannot produce a different key.
130
+ const capturedNames = (params: Dictionary<string>): string[] =>
131
+ ALLOWED_QUERY_PARAMS.filter(name => name in params);
132
+
133
+ // The dedup key: pathname plus the allowlisted params in a fixed order, so that
134
+ // reordering the query string is not a new page. Params outside the allowlist
135
+ // never make it into `page.params` and so cannot key a view — nor can the hash.
136
+ //
137
+ // Values are re-encoded because queryStringParser hands them back DECODED. A
138
+ // value holding the pair delimiters would otherwise serialize exactly like two
139
+ // separate params — `{q: 'a&search=b'}` and `{q: 'a', search: 'b'}` both becoming
140
+ // `q=a&search=b` — and dedup would treat a real navigation between them as the
141
+ // same page and drop the view. `q`, `search` and `redirect_uri` carry `&` and `=`
142
+ // routinely, so this is reachable rather than theoretical.
143
+ export const pageKey = (page: IPageSnapshot): string => {
144
+ const query = capturedNames(page.params)
145
+ .map(name => `${name}=${encodeURIComponent(page.params[name])}`)
146
+ .join('&');
147
+
148
+ return query ? `${page.path}?${query}` : page.path;
149
+ };
150
+
151
+ // Dedup keys on the pageKey above: a change to any captured param is a new page
152
+ // (`?page=2` is a distinct pagination view), while a hash-only change, or a
153
+ // change confined to params we do not capture, is the same page.
62
154
  export const isNewPage = (
63
- lastPath: string | null,
64
- candidatePath: string
65
- ): boolean => candidatePath !== lastPath;
155
+ lastKey: string | null,
156
+ candidateKey: string
157
+ ): boolean => candidateKey !== lastKey;
66
158
 
67
159
  export const supportsHistoryTracking = (win: Window | null): boolean =>
68
160
  !!win &&
@@ -71,11 +163,25 @@ export const supportsHistoryTracking = (win: Window | null): boolean =>
71
163
  typeof win.addEventListener === 'function';
72
164
 
73
165
  // Mirrors the event shape of the public mParticle.logPageView(), but carries the
74
- // path captured when the navigation was accepted rather than the live location.
75
- export const buildPageViewEvent = (data: IPageViewData): BaseEvent => ({
166
+ // path and query params captured when the navigation was accepted rather than the
167
+ // live location.
168
+ export const buildPageViewEvent = ({
169
+ params,
170
+ hostname,
171
+ title,
172
+ path,
173
+ }: IPageViewData): BaseEvent => ({
76
174
  messageType: MessageType.PageView,
77
175
  name: 'PageView',
78
- data: { ...data },
176
+ // Params spread first, then the core fields by name, so a core field always
177
+ // wins. No allowlist entry collides with hostname/title/path today; naming
178
+ // them here is what keeps a later addition from silently overwriting one.
179
+ data: {
180
+ ...params,
181
+ hostname,
182
+ title,
183
+ path,
184
+ },
79
185
  eventType: EventType.Unknown,
80
186
  });
81
187
 
@@ -160,7 +266,25 @@ const clearActiveTracker = (tracker: PageViewTracker): void => {
160
266
  }
161
267
  };
162
268
 
163
- const currentPathname = (): string => window.location.pathname;
269
+ const currentPage = (): IPageSnapshot => ({
270
+ path: window.location.pathname,
271
+ params: allowedQueryParams(getHref()),
272
+ });
273
+
274
+ // Log-safe description of a page: the path, plus the NAMES of the captured
275
+ // params. Values are deliberately omitted — verbose logging goes to the console,
276
+ // and session-replay tooling ships console output off-domain, which is not a
277
+ // place for an OAuth code or a consumer's search terms.
278
+ // Only reachable before init() assigns lastPage, which is ahead of any navigation
279
+ // handler being able to run, so this returns nothing rather than a sentinel.
280
+ const describePage = (page: IPageSnapshot | null): string => {
281
+ if (!page) {
282
+ return '';
283
+ }
284
+
285
+ const names = capturedNames(page.params);
286
+ return names.length ? `${page.path} (params: ${names.join()})` : page.path;
287
+ };
164
288
 
165
289
  // ---------------------------------------------------------------------------
166
290
  // History patching
@@ -250,7 +374,7 @@ export const patchHistory = (
250
374
  export class PageViewTracker {
251
375
  private readonly mpInstance: IMParticleWebSDKInstance;
252
376
 
253
- private lastPath: string | null = null;
377
+ private lastPage: IPageSnapshot | null = null;
254
378
  private active = false;
255
379
  private pendingNavigations: IPendingNavigation[] = [];
256
380
 
@@ -285,14 +409,14 @@ export class PageViewTracker {
285
409
  // dropped — a route change may have queued a deferred fire that has not
286
410
  // flushed yet, and dropping it loses a page view entirely.
287
411
  const active = getActiveTracker();
288
- let inheritedPaths = this.retire(active);
412
+ let inheritedPages = this.retire(active);
289
413
  if (this.active && active !== this) {
290
- inheritedPaths = inheritedPaths.concat(this.retire(this));
414
+ inheritedPages = inheritedPages.concat(this.retire(this));
291
415
  }
292
416
 
293
417
  this.active = true;
294
- this.lastPath = currentPathname();
295
- this.log(`[init] seeded lastPath: ${this.lastPath}`);
418
+ this.lastPage = currentPage();
419
+ this.log(`[init] seeded lastPage: ${describePage(this.lastPage)}`);
296
420
 
297
421
  this.undoHistoryPatch = patchHistory(
298
422
  source => this.safeHandleNavigation(source),
@@ -307,7 +431,7 @@ export class PageViewTracker {
307
431
  '[init] patched pushState/replaceState + listening for popstate'
308
432
  );
309
433
 
310
- inheritedPaths.forEach(path => this.scheduleFire(path));
434
+ inheritedPages.forEach(page => this.scheduleFire(page));
311
435
  }
312
436
 
313
437
  public teardown(): void {
@@ -330,10 +454,10 @@ export class PageViewTracker {
330
454
  clearActiveTracker(this);
331
455
  }
332
456
 
333
- // Stops the outgoing tracker and returns the paths it had queued so this
457
+ // Stops the outgoing tracker and returns the pages it had queued so this
334
458
  // tracker can re-schedule them once it is active. Private, but reachable
335
459
  // across instances: the handoff protocol stays internal to the class.
336
- private retire(outgoing: PageViewTracker | undefined): string[] {
460
+ private retire(outgoing: PageViewTracker | undefined): IPageSnapshot[] {
337
461
  if (!outgoing) {
338
462
  return [];
339
463
  }
@@ -344,17 +468,17 @@ export class PageViewTracker {
344
468
  : '[init] retiring a tracker from a previous module load — transferring pending navigations and tearing down'
345
469
  );
346
470
 
347
- const paths = outgoing.takePendingNavigations();
471
+ const pages = outgoing.takePendingNavigations();
348
472
  outgoing.teardown();
349
- return paths;
473
+ return pages;
350
474
  }
351
475
 
352
- // Cancels this tracker's deferred fires and hands back their captured paths.
353
- private takePendingNavigations(): string[] {
476
+ // Cancels this tracker's deferred fires and hands back their captured pages.
477
+ private takePendingNavigations(): IPageSnapshot[] {
354
478
  const pending = this.pendingNavigations;
355
479
  this.pendingNavigations = [];
356
- pending.forEach(p => clearTimeout(p.timeoutId));
357
- return pending.map(p => p.path);
480
+ pending.forEach(({ timeoutId }) => clearTimeout(timeoutId));
481
+ return pending.map(({ page }) => page);
358
482
  }
359
483
 
360
484
  private safeHandleNavigation(source: NavigationSource): void {
@@ -377,31 +501,39 @@ export class PageViewTracker {
377
501
  }
378
502
 
379
503
  private handleNavigation(source: NavigationSource): void {
380
- const candidatePath = currentPathname();
504
+ const candidate = currentPage();
505
+ const lastKey = this.lastPage ? pageKey(this.lastPage) : null;
381
506
 
382
507
  this.log(
383
- `[detect] navigation signal (source: ${source}, candidatePath: ${candidatePath}, lastPath: ${this.lastPath})`
508
+ `[detect] navigation signal (source: ${source}, candidate: ${describePage(
509
+ candidate
510
+ )}, last: ${describePage(this.lastPage)})`
384
511
  );
385
512
 
386
- if (!isNewPage(this.lastPath, candidatePath)) {
513
+ if (!isNewPage(lastKey, pageKey(candidate))) {
387
514
  this.log(
388
- `[dedupe] pathname unchanged, skipping (source: ${source}, path: ${candidatePath})`
515
+ `[dedupe] page unchanged, skipping (source: ${source}, page: ${describePage(
516
+ candidate
517
+ )})`
389
518
  );
390
519
  return;
391
520
  }
392
521
 
393
522
  this.log(
394
- `[accept] pathname changed, scheduling fire (source: ${source}, from: ${this.lastPath}, to: ${candidatePath})`
523
+ `[accept] page changed, scheduling fire (source: ${source}, from: ${describePage(
524
+ this.lastPage
525
+ )}, to: ${describePage(candidate)})`
395
526
  );
396
- this.lastPath = candidatePath;
397
- this.scheduleFire(candidatePath);
527
+ this.lastPage = candidate;
528
+ this.scheduleFire(candidate);
398
529
  }
399
530
 
400
531
  // Deferred by a macrotask so the router's post-navigation render commit has a
401
- // chance to update document.title before the event is built. The path is
402
- // snapshotted now because it is already settled, whereas a same-tick
403
- // navigation would overwrite window.location before the flush reads it.
404
- private scheduleFire(path: string): void {
532
+ // chance to update document.title before the event is built. The path and
533
+ // query params are snapshotted now because they are already settled, whereas a
534
+ // same-tick navigation would overwrite window.location before the flush reads
535
+ // it.
536
+ private scheduleFire(page: IPageSnapshot): void {
405
537
  const timeoutId = setTimeout(() => {
406
538
  this.pendingNavigations = this.pendingNavigations.filter(
407
539
  p => p.timeoutId !== timeoutId
@@ -415,22 +547,24 @@ export class PageViewTracker {
415
547
  }
416
548
 
417
549
  this.mpInstance._SessionManager.resetSessionTimer();
418
- this.firePageView(path);
550
+ this.firePageView(page);
419
551
  }, 0);
420
552
 
421
- this.pendingNavigations.push({ path, timeoutId });
553
+ this.pendingNavigations.push({ page, timeoutId });
422
554
  }
423
555
 
424
- private firePageView(path: string): void {
556
+ private firePageView(page: IPageSnapshot): void {
425
557
  const title = window.document.title;
426
558
  const event = buildPageViewEvent({
559
+ ...page,
427
560
  hostname: window.location.hostname,
428
561
  title,
429
- path,
430
562
  });
431
563
 
432
564
  this.log(
433
- `[fire] deferred flush -> _Events.logEvent(PageView) (path: ${path}, title: ${title})`
565
+ `[fire] deferred flush -> _Events.logEvent(PageView) (page: ${describePage(
566
+ page
567
+ )}, title: ${title})`
434
568
  );
435
569
 
436
570
  this.mpInstance._Events.logEvent(event);
@@ -43,7 +43,7 @@ export interface IGlobalStoreV2MinifiedKeys {
43
43
  export interface IPersistenceMinified extends Dictionary {
44
44
  cu: MPID; // Current User MPID
45
45
  gs: IGlobalStoreV2MinifiedKeys;
46
- l: boolean; // IsLoggedIn
46
+ l: boolean | 0 | 1; // IsLoggedIn
47
47
 
48
48
  // Persistence Minified can also store optional dictionaries with
49
49
  // an idex of MPID
@@ -99,8 +99,8 @@ export interface IPersistence {
99
99
  useLocalStorage(): boolean;
100
100
  initializeStorage(): void;
101
101
  update(): void;
102
- storeDataInMemory(obj: IPersistenceMinified, currentMPID: MPID): void;
103
- determineLocalStorageAvailability(storage: Storage): boolean;
102
+ storeDataInMemory(obj: IPersistenceMinified, currentMPID?: MPID): void;
103
+ determineLocalStorageAvailability(storage?: Storage): boolean;
104
104
  setLocalStorage(): void;
105
105
  getLocalStorage(): IPersistenceMinified | null;
106
106
  expireCookies(cookieName: string): void;
@@ -113,17 +113,17 @@ export interface IPersistence {
113
113
  maxCookieSize: number
114
114
  ): string;
115
115
  findPrevCookiesBasedOnUI(identityApiData: IdentityApiData): void;
116
- encodePersistence(persistence: IPersistenceMinified): string;
117
- decodePersistence(persistenceString: string): string;
116
+ encodePersistence(persistence: string): string;
117
+ decodePersistence(persistenceString: string | null): string | void;
118
118
  getCookieDomain(): string;
119
- getDomain(doc: string, locationHostname: string): string;
119
+ getDomain(doc: Document, locationHostname: string): string;
120
120
  saveUserCookieSyncDatesToPersistence(mpid: MPID, csd: CookieSyncDates): void;
121
121
  savePersistence(persistance: IPersistenceMinified): void;
122
- getPersistence(): IPersistenceMinified;
123
- getFirstSeenTime(mpid: MPID): string | null;
124
- setFirstSeenTime(mpid: MPID, time: number): void;
122
+ getPersistence(): IPersistenceMinified | null;
123
+ getFirstSeenTime(mpid: MPID): number | null;
124
+ setFirstSeenTime(mpid: MPID, time?: number): void;
125
125
  getLastSeenTime(mpid: MPID): number | null;
126
- setLastSeenTime(mpid: MPID, time: number): void;
126
+ setLastSeenTime(mpid: MPID, time?: number): void;
127
127
  getDeviceId(): string;
128
128
  setDeviceId(guid: string): void;
129
129
  resetPersistence(): void;