@scalebun/react-native 1.3.3 → 1.4.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.
Files changed (70) hide show
  1. package/dist/scalebun.full.js +62 -14
  2. package/dist/scalebun.full.js.map +1 -1
  3. package/dist/scalebun.slim.js +60 -13
  4. package/dist/scalebun.slim.js.map +1 -1
  5. package/lib/commonjs/analytics/EventTracker.js +5 -3
  6. package/lib/commonjs/analytics/EventTracker.js.map +1 -1
  7. package/lib/commonjs/analytics/eventLane.js +23 -0
  8. package/lib/commonjs/analytics/eventLane.js.map +1 -1
  9. package/lib/commonjs/core/constants/version.js +1 -1
  10. package/lib/commonjs/core/context/device.js +18 -0
  11. package/lib/commonjs/core/context/device.js.map +1 -1
  12. package/lib/commonjs/debug/bootstrap.js +2 -1
  13. package/lib/commonjs/debug/bootstrap.js.map +1 -1
  14. package/lib/commonjs/debug/transport.js +2 -1
  15. package/lib/commonjs/debug/transport.js.map +1 -1
  16. package/lib/commonjs/features/journey/journeyManager.js +2 -1
  17. package/lib/commonjs/features/journey/journeyManager.js.map +1 -1
  18. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js +27 -3
  19. package/lib/commonjs/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  20. package/lib/commonjs/features/performance/collectors/JsStallCollector.js +20 -1
  21. package/lib/commonjs/features/performance/collectors/JsStallCollector.js.map +1 -1
  22. package/lib/commonjs/public/ScaleBunFacade.js +10 -2
  23. package/lib/commonjs/public/ScaleBunFacade.js.map +1 -1
  24. package/lib/module/analytics/EventTracker.js +5 -3
  25. package/lib/module/analytics/EventTracker.js.map +1 -1
  26. package/lib/module/analytics/eventLane.js +22 -0
  27. package/lib/module/analytics/eventLane.js.map +1 -1
  28. package/lib/module/core/constants/version.js +1 -1
  29. package/lib/module/core/context/device.js +17 -0
  30. package/lib/module/core/context/device.js.map +1 -1
  31. package/lib/module/debug/bootstrap.js +2 -1
  32. package/lib/module/debug/bootstrap.js.map +1 -1
  33. package/lib/module/debug/transport.js +2 -1
  34. package/lib/module/debug/transport.js.map +1 -1
  35. package/lib/module/features/journey/journeyManager.js +2 -1
  36. package/lib/module/features/journey/journeyManager.js.map +1 -1
  37. package/lib/module/features/performance/collectors/FrameMetricsCollector.js +27 -3
  38. package/lib/module/features/performance/collectors/FrameMetricsCollector.js.map +1 -1
  39. package/lib/module/features/performance/collectors/JsStallCollector.js +20 -1
  40. package/lib/module/features/performance/collectors/JsStallCollector.js.map +1 -1
  41. package/lib/module/public/ScaleBunFacade.js +12 -4
  42. package/lib/module/public/ScaleBunFacade.js.map +1 -1
  43. package/lib/typescript/analytics/EventTracker.d.ts.map +1 -1
  44. package/lib/typescript/analytics/eventLane.d.ts +2 -0
  45. package/lib/typescript/analytics/eventLane.d.ts.map +1 -1
  46. package/lib/typescript/core/constants/version.d.ts +1 -1
  47. package/lib/typescript/core/context/device.d.ts +13 -0
  48. package/lib/typescript/core/context/device.d.ts.map +1 -1
  49. package/lib/typescript/debug/bootstrap.d.ts.map +1 -1
  50. package/lib/typescript/debug/transport.d.ts.map +1 -1
  51. package/lib/typescript/features/journey/journeyManager.d.ts.map +1 -1
  52. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts +14 -0
  53. package/lib/typescript/features/performance/collectors/FrameMetricsCollector.d.ts.map +1 -1
  54. package/lib/typescript/features/performance/collectors/JsStallCollector.d.ts +5 -0
  55. package/lib/typescript/features/performance/collectors/JsStallCollector.d.ts.map +1 -1
  56. package/lib/typescript/public/ScaleBunFacade.d.ts.map +1 -1
  57. package/lib/typescript/public/types.d.ts +1 -1
  58. package/lib/typescript/public/types.d.ts.map +1 -1
  59. package/package.json +1 -1
  60. package/src/analytics/EventTracker.ts +5 -3
  61. package/src/analytics/eventLane.ts +22 -0
  62. package/src/core/constants/version.ts +1 -1
  63. package/src/core/context/device.ts +17 -0
  64. package/src/debug/bootstrap.ts +2 -1
  65. package/src/debug/transport.ts +2 -1
  66. package/src/features/journey/journeyManager.ts +2 -1
  67. package/src/features/performance/collectors/FrameMetricsCollector.ts +32 -3
  68. package/src/features/performance/collectors/JsStallCollector.ts +20 -1
  69. package/src/public/ScaleBunFacade.ts +12 -4
  70. package/src/public/types.ts +1 -1
@@ -492,7 +492,7 @@ var SDK_VERSION;
492
492
  var init_version = __esm({
493
493
  "lib/module/core/constants/version.js"() {
494
494
  "use strict";
495
- SDK_VERSION = "1.3.3";
495
+ SDK_VERSION = "1.4.0";
496
496
  }
497
497
  });
498
498
 
@@ -542,6 +542,10 @@ function mergeDeviceContext(configured, detected = staticDeviceContext()) {
542
542
  ...detected
543
543
  };
544
544
  }
545
+ function resolveEventPlatform() {
546
+ const os = resolvePlatformOS();
547
+ return os === "ios" || os === "android" || os === "web" ? os : "react_native";
548
+ }
545
549
  var init_device = __esm({
546
550
  "lib/module/core/context/device.js"() {
547
551
  "use strict";
@@ -5421,7 +5425,7 @@ function enableDebug(config) {
5421
5425
  journeyEnabled: _journeyConfig.enabled,
5422
5426
  canScreenshot: true,
5423
5427
  navMode: _autoScreenDetector ? "auto" : "beacon",
5424
- sdkVersion: "1.0.0"
5428
+ sdkVersion: SDK_VERSION
5425
5429
  });
5426
5430
  __DEV__ && logger.debug("Emitted journey:debug_ready event to desktop");
5427
5431
  } catch {
@@ -5556,6 +5560,7 @@ var init_bootstrap = __esm({
5556
5560
  "use strict";
5557
5561
  import_transport = __toESM(require_devtools_stub());
5558
5562
  init_timings();
5563
+ init_version();
5559
5564
  import_stream = __toESM(require_devtools_stub());
5560
5565
  import_commands = __toESM(require_devtools_stub());
5561
5566
  init_internalLogger();
@@ -6061,7 +6066,9 @@ var init_EventTracker = __esm({
6061
6066
  "lib/module/analytics/EventTracker.js"() {
6062
6067
  "use strict";
6063
6068
  init_StorageBackend();
6069
+ init_device();
6064
6070
  init_deviceId();
6071
+ init_version();
6065
6072
  init_internalLogger();
6066
6073
  init_nativeCrashBridge();
6067
6074
  init_hmacSha256();
@@ -6090,7 +6097,7 @@ var init_EventTracker = __esm({
6090
6097
  constructor(config) {
6091
6098
  this.storage = createStorageBackend();
6092
6099
  this.cfg = {
6093
- platform: "react_native",
6100
+ platform: resolveEventPlatform(),
6094
6101
  flushIntervalMs: DEFAULT_FLUSH_MS,
6095
6102
  batchSize: DEFAULT_BATCH,
6096
6103
  autoLifecycleEvents: true,
@@ -6316,7 +6323,7 @@ var init_EventTracker = __esm({
6316
6323
  event_name: eventName,
6317
6324
  event_time: Date.now(),
6318
6325
  app_id: this.cfg.appId,
6319
- platform: this.cfg.platform ?? "react_native",
6326
+ platform: this.cfg.platform ?? resolveEventPlatform(),
6320
6327
  installation_id: this.installationId,
6321
6328
  anonymous_id: this.anonymousId,
6322
6329
  session_id: canonicalSessionId || this.sessionId,
@@ -6327,7 +6334,7 @@ var init_EventTracker = __esm({
6327
6334
  ...properties ?? {}
6328
6335
  },
6329
6336
  context: {
6330
- sdk_version: ctx.sdk_version ?? "0.1.0",
6337
+ sdk_version: ctx.sdk_version ?? SDK_VERSION,
6331
6338
  ...ctx
6332
6339
  }
6333
6340
  };
@@ -8053,6 +8060,7 @@ var init_journeyManager = __esm({
8053
8060
  "use strict";
8054
8061
  init_journeyTypes();
8055
8062
  init_gestureBuffer();
8063
+ init_version();
8056
8064
  init_gestureDetector();
8057
8065
  init_navDetector();
8058
8066
  init_screenshotHelper();
@@ -8409,7 +8417,7 @@ var init_journeyManager = __esm({
8409
8417
  journeyEnabled: this.config.enabled,
8410
8418
  canScreenshot: this.screenshotHelper.canCapture,
8411
8419
  navMode: this.navDetector.navMode,
8412
- sdkVersion: "0.1.0"
8420
+ sdkVersion: SDK_VERSION
8413
8421
  };
8414
8422
  this._emitEvent(JOURNEY_EVENTS.DEBUG_READY, payload);
8415
8423
  }
@@ -10491,7 +10499,7 @@ var PERF_SCHEMA_VERSION = 1;
10491
10499
 
10492
10500
  // lib/module/features/performance/collectors/JsStallCollector.js
10493
10501
  var MAX_STALL_RECORDS = 100;
10494
- var JsStallCollector = class {
10502
+ var JsStallCollector = class _JsStallCollector {
10495
10503
  pollTimer = null;
10496
10504
  reportTimer = null;
10497
10505
  lastTick = 0;
@@ -10501,6 +10509,11 @@ var JsStallCollector = class {
10501
10509
  maxStallMs = 0;
10502
10510
  totalStallMs = 0;
10503
10511
  recentStalls = [];
10512
+ /** Per-run caps on INDIVIDUAL stall events — see the emit site. Summaries are uncapped. */
10513
+ static EMITTED_STALLS_MAX = 200;
10514
+ static CRITICAL_OVERFLOW_MAX = 100;
10515
+ emittedStalls = 0;
10516
+ emittedCriticalOverflow = 0;
10504
10517
  constructor(config, onStall, onSummary, contextProvider) {
10505
10518
  this.config = config;
10506
10519
  this.onStall = onStall;
@@ -10561,6 +10574,13 @@ var JsStallCollector = class {
10561
10574
  }
10562
10575
  if (durationMs > 100) {
10563
10576
  const severity = this._classifySeverity(durationMs);
10577
+ if (this.emittedStalls >= _JsStallCollector.EMITTED_STALLS_MAX) {
10578
+ if (severity !== "critical") return;
10579
+ if (this.emittedCriticalOverflow >= _JsStallCollector.CRITICAL_OVERFLOW_MAX) return;
10580
+ this.emittedCriticalOverflow++;
10581
+ } else {
10582
+ this.emittedStalls++;
10583
+ }
10564
10584
  const event = {
10565
10585
  id: `stall-${timestamp}-${Math.random().toString(36).substring(2, 8)}`,
10566
10586
  type: "js_stall",
@@ -10948,13 +10968,27 @@ var AutoScreenLoadCollector = class {
10948
10968
 
10949
10969
  // lib/module/features/performance/collectors/FrameMetricsCollector.js
10950
10970
  var import_react_native12 = require("react-native");
10951
- var FrameMetricsCollector = class {
10971
+ var FrameMetricsCollector = class _FrameMetricsCollector {
10952
10972
  eventSubscription = null;
10953
10973
  running = false;
10954
10974
  /** AppState subscription — see `_installAppStateGate`. */
10955
10975
  appStateSubscription = null;
10956
10976
  /** True while the native sampler is actually running (i.e. armed AND foregrounded). */
10957
10977
  sampling = false;
10978
+ /** Timestamp of the last emitted window — drives the healthy-window heartbeat below. */
10979
+ lastEmitTs = 0;
10980
+ /**
10981
+ * HEALTHY windows emit at a heartbeat, not per report interval.
10982
+ *
10983
+ * The native sampler reports every `reportIntervalMs` (5 s), and every window became a stored
10984
+ * row — on a session hours long that is 720 rows/hour of "still 60 fps", which is how real
10985
+ * sessions hit the dashboard's 2,000-row display cap with nothing to say. A window that shows
10986
+ * ANY jank (dropped/frozen frames, meaningful slow-frame count, an FPS dip) always emits; a
10987
+ * healthy window emits only when the heartbeat has elapsed, keeping the FPS series alive for
10988
+ * the charts at 1/12th the volume. Capture cadence is unchanged — only identical-looking
10989
+ * healthy rows are elided, and the first window after ANY emit gap states the recovery.
10990
+ */
10991
+ static HEALTHY_HEARTBEAT_MS = 6e4;
10958
10992
  constructor(config, onFrameMetrics, contextProvider) {
10959
10993
  this.config = config;
10960
10994
  this.onFrameMetrics = onFrameMetrics;
@@ -11057,10 +11091,17 @@ var FrameMetricsCollector = class {
11057
11091
  const expectedFrames = Math.round(windowMs / 16.67);
11058
11092
  const actualFrames = Math.max(0, totalFrames - droppedFrames);
11059
11093
  const estimatedFps = expectedFrames > 0 ? Math.round(actualFrames / expectedFrames * 60) : 60;
11094
+ const clampedFps = Math.min(60, Math.max(0, estimatedFps));
11095
+ const now2 = Date.now();
11096
+ const healthy = droppedFrames === 0 && frozenFrames === 0 && slowFrames <= 2 && clampedFps >= 55;
11097
+ if (healthy && this.lastEmitTs !== 0 && now2 - this.lastEmitTs < _FrameMetricsCollector.HEALTHY_HEARTBEAT_MS) {
11098
+ return;
11099
+ }
11100
+ this.lastEmitTs = now2;
11060
11101
  const event = {
11061
- id: `frames-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`,
11102
+ id: `frames-${now2}-${Math.random().toString(36).substring(2, 8)}`,
11062
11103
  type: "frame_metrics",
11063
- timestamp: Date.now(),
11104
+ timestamp: now2,
11064
11105
  schemaVersion: PERF_SCHEMA_VERSION,
11065
11106
  context: this.contextProvider(),
11066
11107
  windowMs,
@@ -11068,7 +11109,7 @@ var FrameMetricsCollector = class {
11068
11109
  droppedFrames,
11069
11110
  slowFrames,
11070
11111
  frozenFrames,
11071
- estimatedFps: Math.min(60, Math.max(0, estimatedFps)),
11112
+ estimatedFps: clampedFps,
11072
11113
  maxFrameTimeMs
11073
11114
  };
11074
11115
  this.onFrameMetrics(event);
@@ -13813,6 +13854,10 @@ function isSessionLaneEvent(name) {
13813
13854
  function resolveEventLane(name) {
13814
13855
  return isSessionLaneEvent(name) ? "session" : "analytics";
13815
13856
  }
13857
+ var INTERNAL_ONLY_SIGNALS = /* @__PURE__ */ new Set(["$network_request"]);
13858
+ function isUploadedSessionEvent(name) {
13859
+ return !INTERNAL_ONLY_SIGNALS.has(name);
13860
+ }
13816
13861
 
13817
13862
  // lib/module/config/ConfigManager.js
13818
13863
  init_StorageBackend();
@@ -16296,7 +16341,8 @@ var ScaleBunFacade = class {
16296
16341
  appId,
16297
16342
  clientKey,
16298
16343
  apiBaseUrl,
16299
- platform: rawConfig?.platform ?? "react_native",
16344
+ // Auto-detected (Platform.OS) unless the integration overrides it — see resolveEventPlatform.
16345
+ platform: rawConfig?.platform ?? resolveEventPlatform(),
16300
16346
  appVersion: rawConfig?.appVersion,
16301
16347
  osVersion: rawConfig?.osVersion,
16302
16348
  autoLifecycleEvents: rawConfig?.autoLifecycleEvents !== false,
@@ -17106,7 +17152,8 @@ var ScaleBunFacade = class {
17106
17152
  __DEV__ && logger.debug("Tracking event:", name);
17107
17153
  engageSignals.emit(name, payload);
17108
17154
  const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
17109
- if (this._clientKey && adapter) {
17155
+ if (!isUploadedSessionEvent(name)) {
17156
+ } else if (this._clientKey && adapter) {
17110
17157
  adapter.trackEvent({
17111
17158
  eventId: generateEventId(),
17112
17159
  sessionId: adapter.analyticsSessionId ?? "",