@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/lib/index.js CHANGED
@@ -3308,6 +3308,25 @@ class Observer {
3308
3308
  }
3309
3309
  return;
3310
3310
  }
3311
+ // `open` alone can't tell showModal() (modal/top-layer) from show()/`<dialog open>`
3312
+ // (non-modal); emit the mode alongside it so the player replays the right call (see DOMManager).
3313
+ if (name === 'open' && hasTag(node, 'dialog')) {
3314
+ let mode;
3315
+ if (value === null) {
3316
+ mode = 'closed';
3317
+ }
3318
+ else {
3319
+ let isModal = false;
3320
+ try {
3321
+ isModal = node.matches('dialog:modal');
3322
+ }
3323
+ catch (e) {
3324
+ /* :modal pseudo-class unsupported on this browser */
3325
+ }
3326
+ mode = isModal ? 'modal' : 'nonmodal';
3327
+ }
3328
+ this.app.send(SetNodeAttribute(id, '__openreplay_dialog', mode));
3329
+ }
3311
3330
  if (name === 'src' ||
3312
3331
  name === 'srcset' ||
3313
3332
  name === 'integrity' ||
@@ -3916,6 +3935,8 @@ class TopObserver extends Observer {
3916
3935
  this.iframeObservers = new WeakMap();
3917
3936
  this.docObservers = new WeakMap();
3918
3937
  this.shadowRootObservers = new WeakMap();
3938
+ this.colorSchemeMQL = null;
3939
+ this.colorSchemeListener = null;
3919
3940
  this.app = params.app;
3920
3941
  this.options = opts;
3921
3942
  // IFrames
@@ -4010,9 +4031,36 @@ class TopObserver extends Observer {
4010
4031
  // it has no node_id here
4011
4032
  this.app.nodes.callNodeCallbacks(document, true);
4012
4033
  }, window.document.documentElement);
4034
+ // Send before `orloaded` so it lands in the initial visual batch (see sendColorScheme).
4035
+ this.sendColorScheme();
4013
4036
  // "DOM parsed" signal: observeRoot sent the full initial tree synchronously above.
4014
4037
  // The worker keys on this attribute (BatchWriter) to finalize the visual batch.
4015
4038
  this.app.send(SetNodeAttribute(0, 'orloaded', 'true'));
4039
+ if (IN_BROWSER && window.matchMedia) {
4040
+ this.colorSchemeMQL = window.matchMedia('(prefers-color-scheme: dark)');
4041
+ this.colorSchemeListener = this.app.safe(() => this.sendColorScheme());
4042
+ this.colorSchemeMQL.addEventListener?.('change', this.colorSchemeListener);
4043
+ }
4044
+ }
4045
+ /** Send resolved used color-scheme ('dark'|'light'|'normal') for the player to force on replay. */
4046
+ sendColorScheme() {
4047
+ if (!IN_BROWSER)
4048
+ return;
4049
+ const root = document.documentElement;
4050
+ let declared = getComputedStyle(root).colorScheme;
4051
+ if (!declared || declared === 'normal') {
4052
+ const meta = document.querySelector('meta[name="color-scheme" i]');
4053
+ const content = meta && meta.getAttribute('content');
4054
+ if (content)
4055
+ declared = content;
4056
+ }
4057
+ let used = 'normal';
4058
+ if (declared && declared !== 'normal') {
4059
+ const prefersDark = !!window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
4060
+ // resolve declared support against OS preference into the concrete used scheme
4061
+ used = declared.includes('dark') && (prefersDark || !declared.includes('light')) ? 'dark' : 'light';
4062
+ }
4063
+ this.app.send(SetNodeAttribute(0, '__openreplay_color_scheme', used));
4016
4064
  }
4017
4065
  crossdomainObserve(rootNodeId, frameOder, frameLevel) {
4018
4066
  const observer = this;
@@ -4032,6 +4080,11 @@ class TopObserver extends Observer {
4032
4080
  iframeObserver.syntheticObserve(rootNodeId, window.document);
4033
4081
  }
4034
4082
  disconnect() {
4083
+ if (this.colorSchemeMQL && this.colorSchemeListener) {
4084
+ this.colorSchemeMQL.removeEventListener?.('change', this.colorSchemeListener);
4085
+ }
4086
+ this.colorSchemeMQL = null;
4087
+ this.colorSchemeListener = null;
4035
4088
  this.iframeOffsets.clear();
4036
4089
  Element.prototype.attachShadow = attachShadowNativeFn;
4037
4090
  this.iframeObserversArr.forEach((observer) => observer.disconnect());
@@ -4307,7 +4360,7 @@ class App {
4307
4360
  this.stopCallbacks = [];
4308
4361
  this.commitCallbacks = [];
4309
4362
  this.activityState = ActivityState.NotActive;
4310
- this.version = '18.1.0'; // TODO: version compatability check inside each plugin.
4363
+ this.version = '18.1.2'; // TODO: version compatability check inside each plugin.
4311
4364
  this.socketMode = false;
4312
4365
  this.compressionThreshold = 24 * 1000;
4313
4366
  this.bc = null;
@@ -5062,12 +5115,14 @@ class App {
5062
5115
  if (ev.data.line === proto.resp) {
5063
5116
  const sessionToken = ev.data.token;
5064
5117
  this.session.setSessionToken(sessionToken, this.projectKey);
5118
+ this.adoptSessionVersion(ev.data.version);
5065
5119
  this.allowAppStart();
5066
5120
  }
5067
5121
  if (ev.data.line === proto.reg) {
5068
5122
  const sessionToken = ev.data.token;
5069
5123
  this.session.regenerateTabId();
5070
5124
  this.session.setSessionToken(sessionToken, this.projectKey);
5125
+ this.adoptSessionVersion(ev.data.version);
5071
5126
  this.allowAppStart();
5072
5127
  }
5073
5128
  if (ev.data.line === proto.ask) {
@@ -5076,6 +5131,7 @@ class App {
5076
5131
  this.bc.postMessage({
5077
5132
  line: ev.data.source === thisTab ? proto.reg : proto.resp,
5078
5133
  token,
5134
+ version: this.getSessionVersionHash(),
5079
5135
  source: thisTab,
5080
5136
  context: this.contextId,
5081
5137
  projectKey: this.projectKey,
@@ -5563,15 +5619,29 @@ class App {
5563
5619
  const PROTO_VERSION = '2';
5564
5620
  return `${PROTO_VERSION}x${this.version}`;
5565
5621
  }
5622
+ get sessionVersionKey() {
5623
+ return `${this.options.session_token_key}_version`;
5624
+ }
5625
+ storeSessionVersion(version) {
5626
+ this.sessionStorage.setItem(this.sessionVersionKey, version);
5627
+ }
5628
+ /** a tab adopting a session over BroadcastChannel inherits its version too */
5629
+ adoptSessionVersion(version) {
5630
+ if (version) {
5631
+ this.storeSessionVersion(version);
5632
+ }
5633
+ }
5566
5634
  checkSessionToken(forceNew) {
5567
5635
  const versionHash = this.getSessionVersionHash();
5568
5636
  const needReset = this.sessionStorage.getItem(this.options.session_reset_key) !== null;
5569
- let needNewSessionID = forceNew || needReset;
5637
+ let needNewSessionID = Boolean(forceNew || needReset);
5570
5638
  const sessionToken = this.session.getSessionToken(this.projectKey);
5571
5639
  if (sessionToken) {
5572
- const storedVersion = this.sessionStorage.getItem(`${this.options.session_token_key}_version`);
5573
- needNewSessionID = !storedVersion || storedVersion !== versionHash;
5574
- this.sessionStorage.setItem(`${this.options.session_token_key}_version`, versionHash);
5640
+ const storedVersion = this.sessionStorage.getItem(this.sessionVersionKey);
5641
+ if (!storedVersion || storedVersion !== versionHash) {
5642
+ needNewSessionID = true;
5643
+ }
5644
+ this.storeSessionVersion(versionHash);
5575
5645
  }
5576
5646
  return needNewSessionID || !sessionToken;
5577
5647
  }
@@ -5895,7 +5965,7 @@ class App {
5895
5965
  }
5896
5966
  this.delay = delay;
5897
5967
  this.session.setSessionToken(token, this.projectKey);
5898
- this.sessionStorage.setItem(`${this.options.session_token_key}_version`, this.getSessionVersionHash());
5968
+ this.storeSessionVersion(this.getSessionVersionHash());
5899
5969
  if (sessionToken && sessionToken !== token) {
5900
5970
  this.bc?.postMessage({
5901
5971
  type: proto.reset,
@@ -9720,7 +9790,7 @@ class ConstantProperties {
9720
9790
  user_id: this.user_id,
9721
9791
  distinct_id: this.deviceId,
9722
9792
  sdk_edition: 'web',
9723
- sdk_version: '18.1.0',
9793
+ sdk_version: '18.1.2',
9724
9794
  timezone: getUTCOffsetString(),
9725
9795
  search_engine: this.searchEngine,
9726
9796
  };
@@ -10461,7 +10531,7 @@ class API {
10461
10531
  this.signalStartIssue = (reason, missingApi) => {
10462
10532
  const doNotTrack = this.checkDoNotTrack();
10463
10533
  console.log("Tracker couldn't start due to:", JSON.stringify({
10464
- trackerVersion: '18.1.0',
10534
+ trackerVersion: '18.1.2',
10465
10535
  projectKey: this.options.projectKey,
10466
10536
  doNotTrack,
10467
10537
  reason: missingApi.length ? `missing api: ${missingApi.join(',')}` : reason,