@brainfish-ai/web-tracker 0.0.31 → 0.0.33

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.
@@ -281,7 +281,7 @@ function createPacketDecoderStream(maxPayload, binaryType) {
281
281
  }
282
282
  });
283
283
  }
284
- const protocol$1 = 4;
284
+ const protocol = 4;
285
285
  function Emitter(obj) {
286
286
  if (obj) return mixin(obj);
287
287
  }
@@ -1259,7 +1259,7 @@ class SocketWithoutUpgrade extends Emitter {
1259
1259
  */
1260
1260
  createTransport(name) {
1261
1261
  const query = Object.assign({}, this.opts.query);
1262
- query.EIO = protocol$1;
1262
+ query.EIO = protocol;
1263
1263
  query.transport = name;
1264
1264
  if (this.id)
1265
1265
  query.sid = this.id;
@@ -1588,7 +1588,7 @@ class SocketWithoutUpgrade extends Emitter {
1588
1588
  }
1589
1589
  }
1590
1590
  }
1591
- SocketWithoutUpgrade.protocol = protocol$1;
1591
+ SocketWithoutUpgrade.protocol = protocol;
1592
1592
  class SocketWithUpgrade extends SocketWithoutUpgrade {
1593
1593
  constructor() {
1594
1594
  super(...arguments);
@@ -1860,7 +1860,6 @@ const RESERVED_EVENTS$1 = [
1860
1860
  "removeListener"
1861
1861
  // used by the Node.js EventEmitter
1862
1862
  ];
1863
- const protocol = 5;
1864
1863
  var PacketType;
1865
1864
  (function(PacketType2) {
1866
1865
  PacketType2[PacketType2["CONNECT"] = 0] = "CONNECT";
@@ -2111,8 +2110,7 @@ const parser$3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProp
2111
2110
  Encoder,
2112
2111
  get PacketType() {
2113
2112
  return PacketType;
2114
- },
2115
- protocol
2113
+ }
2116
2114
  }, Symbol.toStringTag, { value: "Module" }));
2117
2115
  function on$2(obj, ev, fn) {
2118
2116
  obj.on(ev, fn);
@@ -3391,7 +3389,7 @@ class HttpClient {
3391
3389
  responseData = {};
3392
3390
  }
3393
3391
  return responseData;
3394
- } catch (error) {
3392
+ } catch {
3395
3393
  }
3396
3394
  }
3397
3395
  }
@@ -3457,6 +3455,19 @@ class TTLSet {
3457
3455
  }
3458
3456
  }
3459
3457
  let latestIdentifyPayload = null;
3458
+ const BRAINFISH_IFRAME_SELECTOR = "#bf-iframe-container .trigger-iframe, #bf-search-bar-iframe-container .trigger-iframe";
3459
+ function getBrainfishIframes() {
3460
+ if (typeof document === "undefined") {
3461
+ return [];
3462
+ }
3463
+ return Array.from(document.querySelectorAll(BRAINFISH_IFRAME_SELECTOR));
3464
+ }
3465
+ function isTrustedBrainfishIframeSource(source) {
3466
+ if (!source) {
3467
+ return false;
3468
+ }
3469
+ return getBrainfishIframes().some((iframe) => iframe.contentWindow === source);
3470
+ }
3460
3471
  if (typeof window !== "undefined") {
3461
3472
  window.addEventListener("message", (event) => {
3462
3473
  const trustedOrigin = "https://agent.brainfi.sh";
@@ -3465,8 +3476,7 @@ if (typeof window !== "undefined") {
3465
3476
  }
3466
3477
  if (event.data?.type === "REQUEST_USER_IDENTITY") {
3467
3478
  if (latestIdentifyPayload && event.source) {
3468
- const iframe = document.querySelector("#bf-iframe-container .trigger-iframe");
3469
- if (!iframe || event.source !== iframe.contentWindow) {
3479
+ if (!isTrustedBrainfishIframeSource(event.source)) {
3470
3480
  console.warn("BrainfishWidgetWarn: Rejected REQUEST_USER_IDENTITY from untrusted iframe source:", event.origin);
3471
3481
  return;
3472
3482
  }
@@ -3635,8 +3645,7 @@ const _TrackerSdk = class _TrackerSdk {
3635
3645
  console.warn("BrainfishWidgetWarn: phone should be in E.164 format (e.g., +14155552671). Providing the correct format ensures accurate user identification.");
3636
3646
  }
3637
3647
  latestIdentifyPayload = payload;
3638
- const iframe = document.querySelector("#bf-iframe-container .trigger-iframe");
3639
- if (iframe) {
3648
+ getBrainfishIframes().forEach((iframe) => {
3640
3649
  const sendMessage = () => {
3641
3650
  if (iframe.contentWindow) {
3642
3651
  iframe.contentWindow.postMessage({
@@ -3649,7 +3658,7 @@ const _TrackerSdk = class _TrackerSdk {
3649
3658
  sendMessage();
3650
3659
  }
3651
3660
  iframe.addEventListener("load", sendMessage);
3652
- }
3661
+ });
3653
3662
  if (Object.keys(payload).length > 1) {
3654
3663
  return this.send({
3655
3664
  type: "user.identify",
@@ -3743,14 +3752,14 @@ const _TrackerSdk = class _TrackerSdk {
3743
3752
  }
3744
3753
  /**
3745
3754
  * Re-enables privacy-sensitive tracking features (recording, screenshots).
3746
- * Note: Full effect requires a page reload to restart recording.
3755
+ * Takes effect immediately; no page refresh required (web tracker attaches
3756
+ * listeners and starts recording when this is called).
3747
3757
  */
3748
3758
  enableTracking() {
3749
3759
  this.trackingDisabled = false;
3750
3760
  if (typeof window !== "undefined" && typeof localStorage !== "undefined") {
3751
3761
  localStorage.removeItem(_TrackerSdk.TRACKING_DISABLED_KEY);
3752
3762
  }
3753
- console.log("Brainfish tracking re-enabled. Refresh page for full effect.");
3754
3763
  }
3755
3764
  /**
3756
3765
  * Returns whether privacy-sensitive tracking is currently disabled.
@@ -24416,7 +24425,7 @@ class Recorder {
24416
24425
  };
24417
24426
  this.stop = null;
24418
24427
  }
24419
- static mockImplementation(arg0) {
24428
+ static mockImplementation(_arg0) {
24420
24429
  throw new Error("Method not implemented.");
24421
24430
  }
24422
24431
  start() {
@@ -24501,7 +24510,7 @@ class RecordingManager {
24501
24510
  }
24502
24511
  }
24503
24512
  if (this.isClick(event)) {
24504
- let clickedNode = record.mirror.getNode(event.data.id);
24513
+ const clickedNode = record.mirror.getNode(event.data.id);
24505
24514
  if (clickedNode && this.nodeIsInteresting(clickedNode)) {
24506
24515
  event["conversionData"] = {};
24507
24516
  event.conversionData.eventType = "click";
@@ -25005,7 +25014,7 @@ function canDiscover(recordingBlocklist, allowLocalhostRecording) {
25005
25014
  if (matchFn(currentPath)) {
25006
25015
  return false;
25007
25016
  }
25008
- } catch (e) {
25017
+ } catch {
25009
25018
  if (pattern === currentPath) {
25010
25019
  return false;
25011
25020
  }
@@ -25185,7 +25194,7 @@ function toCamelCase(str) {
25185
25194
  ($1) => $1.toUpperCase().replace("-", "").replace("_", "")
25186
25195
  );
25187
25196
  }
25188
- const VERSION = "0.0.31";
25197
+ const VERSION = "0.0.33";
25189
25198
  class Tracker extends TrackerSdk {
25190
25199
  constructor(options) {
25191
25200
  super({
@@ -25199,7 +25208,10 @@ class Tracker extends TrackerSdk {
25199
25208
  __publicField(this, "sessionManager", SessionManager.getInstance());
25200
25209
  __publicField(this, "recordingBlocklist", []);
25201
25210
  __publicField(this, "isRecordingActive", false);
25211
+ __publicField(this, "isRecordingInitializing", false);
25202
25212
  __publicField(this, "onFirstScreenViewTracked", null);
25213
+ __publicField(this, "outgoingLinksAttached", false);
25214
+ __publicField(this, "attributesAttached", false);
25203
25215
  this.options = options;
25204
25216
  this.agent = new Agent();
25205
25217
  this.recordingBlocklist = options.recordingOptions?.blocklist ?? options.recordingBlocklist ?? [];
@@ -25212,9 +25224,7 @@ class Tracker extends TrackerSdk {
25212
25224
  this.trackOutgoingLinks();
25213
25225
  }
25214
25226
  if (this.options.enableRecording && !trackingDisabled) {
25215
- this.onFirstScreenViewTracked = () => {
25216
- this.initializeRecordingWithSessionId();
25217
- };
25227
+ this.deferRecordingUntilFirstScreenView();
25218
25228
  }
25219
25229
  if (this.options.trackScreenViews) {
25220
25230
  this.trackScreenViews();
@@ -25232,9 +25242,10 @@ class Tracker extends TrackerSdk {
25232
25242
  return typeof document === "undefined";
25233
25243
  }
25234
25244
  trackOutgoingLinks() {
25235
- if (this.isServer()) {
25245
+ if (this.isServer() || this.outgoingLinksAttached) {
25236
25246
  return;
25237
25247
  }
25248
+ this.outgoingLinksAttached = true;
25238
25249
  document.addEventListener("click", (event) => {
25239
25250
  const target = event.target;
25240
25251
  const link = target.closest("a");
@@ -25279,9 +25290,10 @@ class Tracker extends TrackerSdk {
25279
25290
  }
25280
25291
  }
25281
25292
  trackAttributes() {
25282
- if (this.isServer()) {
25293
+ if (this.isServer() || this.attributesAttached) {
25283
25294
  return;
25284
25295
  }
25296
+ this.attributesAttached = true;
25285
25297
  document.addEventListener("click", (event) => {
25286
25298
  const target = event.target;
25287
25299
  const btn = target.closest("button");
@@ -25350,6 +25362,10 @@ class Tracker extends TrackerSdk {
25350
25362
  });
25351
25363
  }
25352
25364
  async initializeRecordingWithSessionId() {
25365
+ if (this.isRecordingInitializing) {
25366
+ return;
25367
+ }
25368
+ this.isRecordingInitializing = true;
25353
25369
  try {
25354
25370
  const sessionId = await super.getSessionId();
25355
25371
  if (this.isTrackingDisabled()) {
@@ -25369,6 +25385,8 @@ class Tracker extends TrackerSdk {
25369
25385
  }
25370
25386
  } catch (error) {
25371
25387
  console.warn("Error initializing ambient learning:", error);
25388
+ } finally {
25389
+ this.isRecordingInitializing = false;
25372
25390
  }
25373
25391
  }
25374
25392
  sendScreenViewEvent(props) {
@@ -25379,11 +25397,19 @@ class Tracker extends TrackerSdk {
25379
25397
  this.onFirstScreenViewTracked = null;
25380
25398
  }
25381
25399
  }
25400
+ deferRecordingUntilFirstScreenView() {
25401
+ if (this.options.enableRecording) {
25402
+ this.onFirstScreenViewTracked = () => {
25403
+ this.initializeRecordingWithSessionId();
25404
+ };
25405
+ }
25406
+ }
25382
25407
  /**
25383
25408
  * Disables privacy-sensitive tracking features and stops active recording.
25384
25409
  */
25385
25410
  disableTracking() {
25386
25411
  super.disableTracking();
25412
+ this.onFirstScreenViewTracked = null;
25387
25413
  console.log("Brainfish tracking has been disabled.");
25388
25414
  if (this.isRecordingActive) {
25389
25415
  this.agent.stop();
@@ -25392,11 +25418,28 @@ class Tracker extends TrackerSdk {
25392
25418
  }
25393
25419
  }
25394
25420
  /**
25395
- * Re-enables privacy-sensitive tracking features.
25396
- * Note: Full effect requires a page reload to restart recording and event listeners.
25421
+ * Re-enables privacy-sensitive tracking features (outgoing links, attributes, recording).
25422
+ * Takes effect immediately; no page refresh required.
25397
25423
  */
25398
25424
  enableTracking() {
25399
25425
  super.enableTracking();
25426
+ if (this.isServer()) {
25427
+ return;
25428
+ }
25429
+ if (this.options.trackOutgoingLinks && !this.outgoingLinksAttached) {
25430
+ this.trackOutgoingLinks();
25431
+ }
25432
+ if (this.options.trackAttributes && !this.attributesAttached) {
25433
+ this.trackAttributes();
25434
+ }
25435
+ if (this.options.enableRecording && !this.isRecordingActive && !this.isRecordingInitializing) {
25436
+ this.deferRecordingUntilFirstScreenView();
25437
+ if (this.options.trackScreenViews) {
25438
+ this.lastPath = "";
25439
+ this.screenView();
25440
+ }
25441
+ }
25442
+ console.log("Brainfish tracking re-enabled.");
25400
25443
  }
25401
25444
  }
25402
25445
  ((window2) => {
Binary file