@openreplay/tracker 18.1.0 → 18.1.2

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/dist/cjs/entry.js CHANGED
@@ -3312,6 +3312,25 @@ class Observer {
3312
3312
  }
3313
3313
  return;
3314
3314
  }
3315
+ // `open` alone can't tell showModal() (modal/top-layer) from show()/`<dialog open>`
3316
+ // (non-modal); emit the mode alongside it so the player replays the right call (see DOMManager).
3317
+ if (name === 'open' && hasTag(node, 'dialog')) {
3318
+ let mode;
3319
+ if (value === null) {
3320
+ mode = 'closed';
3321
+ }
3322
+ else {
3323
+ let isModal = false;
3324
+ try {
3325
+ isModal = node.matches('dialog:modal');
3326
+ }
3327
+ catch (e) {
3328
+ /* :modal pseudo-class unsupported on this browser */
3329
+ }
3330
+ mode = isModal ? 'modal' : 'nonmodal';
3331
+ }
3332
+ this.app.send(SetNodeAttribute(id, '__openreplay_dialog', mode));
3333
+ }
3315
3334
  if (name === 'src' ||
3316
3335
  name === 'srcset' ||
3317
3336
  name === 'integrity' ||
@@ -3920,6 +3939,8 @@ class TopObserver extends Observer {
3920
3939
  this.iframeObservers = new WeakMap();
3921
3940
  this.docObservers = new WeakMap();
3922
3941
  this.shadowRootObservers = new WeakMap();
3942
+ this.colorSchemeMQL = null;
3943
+ this.colorSchemeListener = null;
3923
3944
  this.app = params.app;
3924
3945
  this.options = opts;
3925
3946
  // IFrames
@@ -4014,9 +4035,36 @@ class TopObserver extends Observer {
4014
4035
  // it has no node_id here
4015
4036
  this.app.nodes.callNodeCallbacks(document, true);
4016
4037
  }, window.document.documentElement);
4038
+ // Send before `orloaded` so it lands in the initial visual batch (see sendColorScheme).
4039
+ this.sendColorScheme();
4017
4040
  // "DOM parsed" signal: observeRoot sent the full initial tree synchronously above.
4018
4041
  // The worker keys on this attribute (BatchWriter) to finalize the visual batch.
4019
4042
  this.app.send(SetNodeAttribute(0, 'orloaded', 'true'));
4043
+ if (IN_BROWSER && window.matchMedia) {
4044
+ this.colorSchemeMQL = window.matchMedia('(prefers-color-scheme: dark)');
4045
+ this.colorSchemeListener = this.app.safe(() => this.sendColorScheme());
4046
+ this.colorSchemeMQL.addEventListener?.('change', this.colorSchemeListener);
4047
+ }
4048
+ }
4049
+ /** Send resolved used color-scheme ('dark'|'light'|'normal') for the player to force on replay. */
4050
+ sendColorScheme() {
4051
+ if (!IN_BROWSER)
4052
+ return;
4053
+ const root = document.documentElement;
4054
+ let declared = getComputedStyle(root).colorScheme;
4055
+ if (!declared || declared === 'normal') {
4056
+ const meta = document.querySelector('meta[name="color-scheme" i]');
4057
+ const content = meta && meta.getAttribute('content');
4058
+ if (content)
4059
+ declared = content;
4060
+ }
4061
+ let used = 'normal';
4062
+ if (declared && declared !== 'normal') {
4063
+ const prefersDark = !!window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
4064
+ // resolve declared support against OS preference into the concrete used scheme
4065
+ used = declared.includes('dark') && (prefersDark || !declared.includes('light')) ? 'dark' : 'light';
4066
+ }
4067
+ this.app.send(SetNodeAttribute(0, '__openreplay_color_scheme', used));
4020
4068
  }
4021
4069
  crossdomainObserve(rootNodeId, frameOder, frameLevel) {
4022
4070
  const observer = this;
@@ -4036,6 +4084,11 @@ class TopObserver extends Observer {
4036
4084
  iframeObserver.syntheticObserve(rootNodeId, window.document);
4037
4085
  }
4038
4086
  disconnect() {
4087
+ if (this.colorSchemeMQL && this.colorSchemeListener) {
4088
+ this.colorSchemeMQL.removeEventListener?.('change', this.colorSchemeListener);
4089
+ }
4090
+ this.colorSchemeMQL = null;
4091
+ this.colorSchemeListener = null;
4039
4092
  this.iframeOffsets.clear();
4040
4093
  Element.prototype.attachShadow = attachShadowNativeFn;
4041
4094
  this.iframeObserversArr.forEach((observer) => observer.disconnect());
@@ -4311,7 +4364,7 @@ class App {
4311
4364
  this.stopCallbacks = [];
4312
4365
  this.commitCallbacks = [];
4313
4366
  this.activityState = ActivityState.NotActive;
4314
- this.version = '18.1.0'; // TODO: version compatability check inside each plugin.
4367
+ this.version = '18.1.2'; // TODO: version compatability check inside each plugin.
4315
4368
  this.socketMode = false;
4316
4369
  this.compressionThreshold = 24 * 1000;
4317
4370
  this.bc = null;
@@ -5066,12 +5119,14 @@ class App {
5066
5119
  if (ev.data.line === proto.resp) {
5067
5120
  const sessionToken = ev.data.token;
5068
5121
  this.session.setSessionToken(sessionToken, this.projectKey);
5122
+ this.adoptSessionVersion(ev.data.version);
5069
5123
  this.allowAppStart();
5070
5124
  }
5071
5125
  if (ev.data.line === proto.reg) {
5072
5126
  const sessionToken = ev.data.token;
5073
5127
  this.session.regenerateTabId();
5074
5128
  this.session.setSessionToken(sessionToken, this.projectKey);
5129
+ this.adoptSessionVersion(ev.data.version);
5075
5130
  this.allowAppStart();
5076
5131
  }
5077
5132
  if (ev.data.line === proto.ask) {
@@ -5080,6 +5135,7 @@ class App {
5080
5135
  this.bc.postMessage({
5081
5136
  line: ev.data.source === thisTab ? proto.reg : proto.resp,
5082
5137
  token,
5138
+ version: this.getSessionVersionHash(),
5083
5139
  source: thisTab,
5084
5140
  context: this.contextId,
5085
5141
  projectKey: this.projectKey,
@@ -5567,15 +5623,29 @@ class App {
5567
5623
  const PROTO_VERSION = '2';
5568
5624
  return `${PROTO_VERSION}x${this.version}`;
5569
5625
  }
5626
+ get sessionVersionKey() {
5627
+ return `${this.options.session_token_key}_version`;
5628
+ }
5629
+ storeSessionVersion(version) {
5630
+ this.sessionStorage.setItem(this.sessionVersionKey, version);
5631
+ }
5632
+ /** a tab adopting a session over BroadcastChannel inherits its version too */
5633
+ adoptSessionVersion(version) {
5634
+ if (version) {
5635
+ this.storeSessionVersion(version);
5636
+ }
5637
+ }
5570
5638
  checkSessionToken(forceNew) {
5571
5639
  const versionHash = this.getSessionVersionHash();
5572
5640
  const needReset = this.sessionStorage.getItem(this.options.session_reset_key) !== null;
5573
- let needNewSessionID = forceNew || needReset;
5641
+ let needNewSessionID = Boolean(forceNew || needReset);
5574
5642
  const sessionToken = this.session.getSessionToken(this.projectKey);
5575
5643
  if (sessionToken) {
5576
- const storedVersion = this.sessionStorage.getItem(`${this.options.session_token_key}_version`);
5577
- needNewSessionID = !storedVersion || storedVersion !== versionHash;
5578
- this.sessionStorage.setItem(`${this.options.session_token_key}_version`, versionHash);
5644
+ const storedVersion = this.sessionStorage.getItem(this.sessionVersionKey);
5645
+ if (!storedVersion || storedVersion !== versionHash) {
5646
+ needNewSessionID = true;
5647
+ }
5648
+ this.storeSessionVersion(versionHash);
5579
5649
  }
5580
5650
  return needNewSessionID || !sessionToken;
5581
5651
  }
@@ -5899,7 +5969,7 @@ class App {
5899
5969
  }
5900
5970
  this.delay = delay;
5901
5971
  this.session.setSessionToken(token, this.projectKey);
5902
- this.sessionStorage.setItem(`${this.options.session_token_key}_version`, this.getSessionVersionHash());
5972
+ this.storeSessionVersion(this.getSessionVersionHash());
5903
5973
  if (sessionToken && sessionToken !== token) {
5904
5974
  this.bc?.postMessage({
5905
5975
  type: proto.reset,
@@ -9724,7 +9794,7 @@ class ConstantProperties {
9724
9794
  user_id: this.user_id,
9725
9795
  distinct_id: this.deviceId,
9726
9796
  sdk_edition: 'web',
9727
- sdk_version: '18.1.0',
9797
+ sdk_version: '18.1.2',
9728
9798
  timezone: getUTCOffsetString(),
9729
9799
  search_engine: this.searchEngine,
9730
9800
  };
@@ -10465,7 +10535,7 @@ class API {
10465
10535
  this.signalStartIssue = (reason, missingApi) => {
10466
10536
  const doNotTrack = this.checkDoNotTrack();
10467
10537
  console.log("Tracker couldn't start due to:", JSON.stringify({
10468
- trackerVersion: '18.1.0',
10538
+ trackerVersion: '18.1.2',
10469
10539
  projectKey: this.options.projectKey,
10470
10540
  doNotTrack,
10471
10541
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,