@duckduckgo/autoconsent 14.90.0 → 14.92.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/messages.ts CHANGED
@@ -1,7 +1,13 @@
1
1
  import { snippets } from './eval-snippets';
2
2
  import { Config, ConsentState, RuleBundle } from './types';
3
3
 
4
- export type BackgroundMessage = InitResponseMessage | EvalResponseMessage | OptOutMessage | OptInMessage | SelfTestMessage;
4
+ export type BackgroundMessage =
5
+ | InitResponseMessage
6
+ | EvalResponseMessage
7
+ | OptOutMessage
8
+ | OptInMessage
9
+ | SelfTestMessage
10
+ | MeasurePerformanceMessage;
5
11
 
6
12
  export type ContentScriptMessage =
7
13
  | InitMessage
@@ -130,3 +136,7 @@ export type DevtoolsInitMessage = {
130
136
  type: 'init';
131
137
  tabId: number;
132
138
  };
139
+
140
+ export type MeasurePerformanceMessage = {
141
+ type: 'measurePerformance';
142
+ };
package/lib/types.ts CHANGED
@@ -76,6 +76,7 @@ export type Config = {
76
76
  messages: boolean;
77
77
  waits: boolean;
78
78
  };
79
+ performanceLoggingEnabled: boolean;
79
80
  };
80
81
 
81
82
  export type LifecycleState =
@@ -109,6 +110,7 @@ export type ConsentState = {
109
110
  clicks: number; // Number of clicks the script has made.
110
111
  startTime: number; // The time the script started.
111
112
  endTime: number; // The time the script ended.
113
+ performance?: Record<string, number[]>;
112
114
  };
113
115
 
114
116
  export interface ButtonData {
package/lib/utils.ts CHANGED
@@ -93,6 +93,7 @@ export function normalizeConfig(providedConfig: any): Config {
93
93
  messages: false,
94
94
  waits: false,
95
95
  },
96
+ performanceLoggingEnabled: false,
96
97
  };
97
98
  const updatedConfig: Config = copyObject(defaultConfig);
98
99
  // filter out any unknown entries
package/lib/web.ts CHANGED
@@ -103,7 +103,6 @@ export default class AutoConsent {
103
103
  if (config.enableFilterList) {
104
104
  this.initializeFilterList();
105
105
  }
106
-
107
106
  this.rules = filterCMPs(this.rules, normalizedConfig);
108
107
 
109
108
  if (this.shouldPrehide) {
@@ -166,6 +165,8 @@ export default class AutoConsent {
166
165
  }
167
166
 
168
167
  parseDeclarativeRules(declarativeRules: RuleBundle) {
168
+ const perfEnabled = this.#config?.performanceLoggingEnabled;
169
+ perfEnabled && performance.mark('parseDeclarativeRulesStart');
169
170
  if (declarativeRules.consentomatic) {
170
171
  for (const [name, rule] of Object.entries(declarativeRules.consentomatic)) {
171
172
  this.addConsentomaticCMP(name, rule);
@@ -183,9 +184,11 @@ export default class AutoConsent {
183
184
  const rules = decodeRules(declarativeRules.compact);
184
185
  rules.forEach(this.addDeclarativeCMP.bind(this));
185
186
  } catch (e) {
186
- this.config.logs.errors && console.error(e);
187
+ this.#config?.logs.errors && console.error(e);
187
188
  }
188
189
  }
190
+ perfEnabled && performance.mark('parseDeclarativeRulesEnd');
191
+ perfEnabled && performance.measure('parseDeclarativeRules', 'parseDeclarativeRulesStart', 'parseDeclarativeRulesEnd');
189
192
  }
190
193
 
191
194
  addDeclarativeCMP(ruleset: AutoConsentCMPRule) {
@@ -210,6 +213,9 @@ export default class AutoConsent {
210
213
  this.updateState({ lifecycle: 'started' });
211
214
  const foundCmps = await this.findCmp(this.config.detectRetries);
212
215
  this.updateState({ detectedCmps: foundCmps.map((c) => c.name) });
216
+ if (this.config.performanceLoggingEnabled) {
217
+ this.updateState({ performance: this.measurePerformance() });
218
+ }
213
219
  if (foundCmps.length === 0) {
214
220
  logsConfig.lifecycle && console.log('no CMP found', location.href);
215
221
  if (this.shouldPrehide) {
@@ -298,7 +304,11 @@ export default class AutoConsent {
298
304
  ];
299
305
  const runDetectCmp = async (cmp: AutoCMP) => {
300
306
  try {
307
+ this.config.performanceLoggingEnabled && performance.mark(`detectCmp_${cmp.name}`);
301
308
  const result = await cmp.detectCmp();
309
+ this.config.performanceLoggingEnabled && performance.mark(`detectCmpEnd_${cmp.name}`);
310
+ this.config.performanceLoggingEnabled &&
311
+ performance.measure(`detectCmp_${cmp.name}`, `detectCmp_${cmp.name}`, `detectCmpEnd_${cmp.name}`);
302
312
  if (result) {
303
313
  logsConfig.lifecycle && console.log(`Found CMP: ${cmp.name} ${window.location.href}`);
304
314
  this.sendContentMessage({
@@ -323,7 +333,11 @@ export default class AutoConsent {
323
333
  `Trying ${stageName} rules`,
324
334
  ruleGroup.map((r) => r.name),
325
335
  );
336
+ this.config.performanceLoggingEnabled && performance.mark(`findCmpStage_${stageName}`);
326
337
  await Promise.all(ruleGroup.map(runDetectCmp));
338
+ this.config.performanceLoggingEnabled && performance.mark(`findCmpStageEnd_${stageName}`);
339
+ this.config.performanceLoggingEnabled &&
340
+ performance.measure(`findCmp_${stageName}`, `findCmpStage_${stageName}`, `findCmpStageEnd_${stageName}`);
327
341
 
328
342
  // exit early if we already found a CMP
329
343
  if (foundCMPs.length > 0) {
@@ -352,6 +366,7 @@ export default class AutoConsent {
352
366
 
353
367
  detectHeuristics() {
354
368
  if (this.config.enableHeuristicDetection) {
369
+ this.config.performanceLoggingEnabled && performance.mark('detectHeuristicsStart');
355
370
  const { patterns, snippets } = checkHeuristicPatterns(document.documentElement?.innerText || '');
356
371
  if (
357
372
  patterns.length > 0 &&
@@ -360,6 +375,9 @@ export default class AutoConsent {
360
375
  this.config.logs.lifecycle && console.log('Heuristic patterns found', patterns, snippets);
361
376
  this.updateState({ heuristicPatterns: patterns, heuristicSnippets: snippets }); // we don't care about previously found patterns
362
377
  }
378
+ this.config.performanceLoggingEnabled && performance.mark('detectHeuristicsEnd');
379
+ this.config.performanceLoggingEnabled &&
380
+ performance.measure('detectHeuristics', 'detectHeuristicsStart', 'detectHeuristicsEnd');
363
381
  }
364
382
  }
365
383
 
@@ -666,6 +684,36 @@ export default class AutoConsent {
666
684
  case 'evalResp':
667
685
  resolveEval(message.id, message.result);
668
686
  break;
687
+ case 'measurePerformance':
688
+ this.updateState({ performance: this.measurePerformance() });
689
+ break;
669
690
  }
670
691
  }
692
+
693
+ measurePerformance() {
694
+ const getRoundedPerformanceEntries = (name: string) => performance.getEntriesByName(name).map((m) => Number(m.duration.toFixed(3)));
695
+ return {
696
+ detectHeuristics: getRoundedPerformanceEntries('detectHeuristics'),
697
+ heuristicDetector: getRoundedPerformanceEntries('heuristicDetector'),
698
+ findCmpSiteSpecific: getRoundedPerformanceEntries('findCmp_site-specific'),
699
+ findCmpGeneric: getRoundedPerformanceEntries('findCmp_generic'),
700
+ findCmpHeuristic: getRoundedPerformanceEntries('findCmp_heuristic'),
701
+ parseDeclarativeRules: getRoundedPerformanceEntries('parseDeclarativeRules'),
702
+ };
703
+ }
704
+
705
+ measureDetailedRulePerformance() {
706
+ const cmpPerformance: Record<string, number> = performance
707
+ .getEntriesByType('measure')
708
+ .filter((m) => m.name.startsWith('detectCmp_'))
709
+ .reduce((acc, m) => {
710
+ const k = m.name.slice(10);
711
+ if (!acc[k]) {
712
+ acc[k] = 0;
713
+ }
714
+ acc[k] += m.duration;
715
+ return acc;
716
+ }, Object.create(null));
717
+ return cmpPerformance;
718
+ }
671
719
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@duckduckgo/autoconsent",
3
- "version": "14.90.0",
3
+ "version": "14.92.0",
4
4
  "description": "",
5
5
  "types": "./dist/types/web.d.ts",
6
6
  "exports": {
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "aytm",
3
+ "vendorUrl": "https://aytm.com/",
4
+ "runContext": {
5
+ "urlPattern": "^https?://(www\\.|)?aytm\\.com/"
6
+ },
7
+ "prehideSelectors": ["#cookie-consent"],
8
+ "detectCmp": [
9
+ {
10
+ "exists": "#cookie-consent[style*=\"max-height\"] #cookie-status-reject"
11
+ }
12
+ ],
13
+ "detectPopup": [
14
+ {
15
+ "visible": "#cookie-consent[style*=\"max-height\"] #cookie-status-reject"
16
+ }
17
+ ],
18
+ "optIn": [
19
+ {
20
+ "waitForThenClick": "#cookie-consent[style*=\"max-height\"] #cookie-status-agree"
21
+ }
22
+ ],
23
+ "optOut": [
24
+ {
25
+ "waitForThenClick": "#cookie-consent[style*=\"max-height\"] #cookie-status-reject"
26
+ }
27
+ ]
28
+ }
@@ -22,7 +22,12 @@
22
22
  }
23
23
  ],
24
24
  "optOut": [
25
- { "waitForThenClick": "#cookie-consent .cookie-consent__switch:not(.always_on)", "all": true },
25
+ {
26
+ "waitForThenClick": "#cookie-consent .cookie-consent__switch.active:not(.always_on)",
27
+ "all": true,
28
+ "timeout": 500,
29
+ "optional": true
30
+ },
26
31
  { "waitForThenClick": "#cookie-consent .cookie-selection__btn" }
27
32
  ],
28
33
  "test": [{ "cookieContains": "cookie_consent_essential=true" }, { "cookieContains": "cookie_consent_marketing=true", "negated": true }]
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "vivenu",
3
+ "vendorUrl": "https://vivenu.com",
4
+ "prehideSelectors": [],
5
+ "detectCmp": [
6
+ {
7
+ "exists": "[data-slot=\"dialog-content\"] a[href*=\"vivenu.com/dataprivacy\"]"
8
+ }
9
+ ],
10
+ "detectPopup": [
11
+ {
12
+ "visible": "[data-slot=\"dialog-content\"] a[href*=\"vivenu.com/dataprivacy\"]"
13
+ }
14
+ ],
15
+ "optIn": [
16
+ {
17
+ "waitForThenClick": "[data-slot=\"dialog-content\"]:has(a[href*=\"vivenu.com/dataprivacy\"]) button:nth-of-type(1)"
18
+ }
19
+ ],
20
+ "optOut": [
21
+ {
22
+ "waitForThenClick": "[data-slot=\"dialog-content\"]:has(a[href*=\"vivenu.com/dataprivacy\"]) button:nth-of-type(2)"
23
+ }
24
+ ],
25
+ "test": [
26
+ {
27
+ "visible": "[data-slot=\"dialog-content\"] a[href*=\"vivenu.com/dataprivacy\"]",
28
+ "check": "none"
29
+ }
30
+ ]
31
+ }