@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
@@ -489,7 +489,7 @@ var SDK_VERSION;
489
489
  var init_version = __esm({
490
490
  "lib/module/core/constants/version.js"() {
491
491
  "use strict";
492
- SDK_VERSION = "1.3.3";
492
+ SDK_VERSION = "1.4.0";
493
493
  }
494
494
  });
495
495
 
@@ -539,6 +539,10 @@ function mergeDeviceContext(configured, detected = staticDeviceContext()) {
539
539
  ...detected
540
540
  };
541
541
  }
542
+ function resolveEventPlatform() {
543
+ const os = resolvePlatformOS();
544
+ return os === "ios" || os === "android" || os === "web" ? os : "react_native";
545
+ }
542
546
  var init_device = __esm({
543
547
  "lib/module/core/context/device.js"() {
544
548
  "use strict";
@@ -1235,6 +1239,7 @@ var init_transport = __esm({
1235
1239
  "use strict";
1236
1240
  init_protocol2();
1237
1241
  init_timings();
1242
+ init_version();
1238
1243
  DebugTransport = class {
1239
1244
  ws = null;
1240
1245
  state = "disconnected";
@@ -1406,7 +1411,7 @@ var init_transport = __esm({
1406
1411
  timestamp: Date.now(),
1407
1412
  sequence: this.nextSequence(),
1408
1413
  payload: {
1409
- sdkVersion: "0.1.0",
1414
+ sdkVersion: SDK_VERSION,
1410
1415
  appName: this.config.appName,
1411
1416
  appVersion: this.config.appVersion,
1412
1417
  bundleId: this.config.bundleId,
@@ -7329,7 +7334,7 @@ var init_JsStallCollector = __esm({
7329
7334
  "use strict";
7330
7335
  init_models();
7331
7336
  MAX_STALL_RECORDS = 100;
7332
- JsStallCollector = class {
7337
+ JsStallCollector = class _JsStallCollector {
7333
7338
  pollTimer = null;
7334
7339
  reportTimer = null;
7335
7340
  lastTick = 0;
@@ -7339,6 +7344,11 @@ var init_JsStallCollector = __esm({
7339
7344
  maxStallMs = 0;
7340
7345
  totalStallMs = 0;
7341
7346
  recentStalls = [];
7347
+ /** Per-run caps on INDIVIDUAL stall events — see the emit site. Summaries are uncapped. */
7348
+ static EMITTED_STALLS_MAX = 200;
7349
+ static CRITICAL_OVERFLOW_MAX = 100;
7350
+ emittedStalls = 0;
7351
+ emittedCriticalOverflow = 0;
7342
7352
  constructor(config, onStall, onSummary, contextProvider) {
7343
7353
  this.config = config;
7344
7354
  this.onStall = onStall;
@@ -7399,6 +7409,13 @@ var init_JsStallCollector = __esm({
7399
7409
  }
7400
7410
  if (durationMs > 100) {
7401
7411
  const severity = this._classifySeverity(durationMs);
7412
+ if (this.emittedStalls >= _JsStallCollector.EMITTED_STALLS_MAX) {
7413
+ if (severity !== "critical") return;
7414
+ if (this.emittedCriticalOverflow >= _JsStallCollector.CRITICAL_OVERFLOW_MAX) return;
7415
+ this.emittedCriticalOverflow++;
7416
+ } else {
7417
+ this.emittedStalls++;
7418
+ }
7402
7419
  const event = {
7403
7420
  id: `stall-${timestamp}-${Math.random().toString(36).substring(2, 8)}`,
7404
7421
  type: "js_stall",
@@ -7835,13 +7852,27 @@ var init_FrameMetricsCollector = __esm({
7835
7852
  import_react_native9 = require("react-native");
7836
7853
  init_getNativePerformanceModule();
7837
7854
  init_models();
7838
- FrameMetricsCollector = class {
7855
+ FrameMetricsCollector = class _FrameMetricsCollector {
7839
7856
  eventSubscription = null;
7840
7857
  running = false;
7841
7858
  /** AppState subscription — see `_installAppStateGate`. */
7842
7859
  appStateSubscription = null;
7843
7860
  /** True while the native sampler is actually running (i.e. armed AND foregrounded). */
7844
7861
  sampling = false;
7862
+ /** Timestamp of the last emitted window — drives the healthy-window heartbeat below. */
7863
+ lastEmitTs = 0;
7864
+ /**
7865
+ * HEALTHY windows emit at a heartbeat, not per report interval.
7866
+ *
7867
+ * The native sampler reports every `reportIntervalMs` (5 s), and every window became a stored
7868
+ * row — on a session hours long that is 720 rows/hour of "still 60 fps", which is how real
7869
+ * sessions hit the dashboard's 2,000-row display cap with nothing to say. A window that shows
7870
+ * ANY jank (dropped/frozen frames, meaningful slow-frame count, an FPS dip) always emits; a
7871
+ * healthy window emits only when the heartbeat has elapsed, keeping the FPS series alive for
7872
+ * the charts at 1/12th the volume. Capture cadence is unchanged — only identical-looking
7873
+ * healthy rows are elided, and the first window after ANY emit gap states the recovery.
7874
+ */
7875
+ static HEALTHY_HEARTBEAT_MS = 6e4;
7845
7876
  constructor(config, onFrameMetrics, contextProvider) {
7846
7877
  this.config = config;
7847
7878
  this.onFrameMetrics = onFrameMetrics;
@@ -7944,10 +7975,17 @@ var init_FrameMetricsCollector = __esm({
7944
7975
  const expectedFrames = Math.round(windowMs / 16.67);
7945
7976
  const actualFrames = Math.max(0, totalFrames - droppedFrames);
7946
7977
  const estimatedFps = expectedFrames > 0 ? Math.round(actualFrames / expectedFrames * 60) : 60;
7978
+ const clampedFps = Math.min(60, Math.max(0, estimatedFps));
7979
+ const now2 = Date.now();
7980
+ const healthy = droppedFrames === 0 && frozenFrames === 0 && slowFrames <= 2 && clampedFps >= 55;
7981
+ if (healthy && this.lastEmitTs !== 0 && now2 - this.lastEmitTs < _FrameMetricsCollector.HEALTHY_HEARTBEAT_MS) {
7982
+ return;
7983
+ }
7984
+ this.lastEmitTs = now2;
7947
7985
  const event = {
7948
- id: `frames-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`,
7986
+ id: `frames-${now2}-${Math.random().toString(36).substring(2, 8)}`,
7949
7987
  type: "frame_metrics",
7950
- timestamp: Date.now(),
7988
+ timestamp: now2,
7951
7989
  schemaVersion: PERF_SCHEMA_VERSION,
7952
7990
  context: this.contextProvider(),
7953
7991
  windowMs,
@@ -7955,7 +7993,7 @@ var init_FrameMetricsCollector = __esm({
7955
7993
  droppedFrames,
7956
7994
  slowFrames,
7957
7995
  frozenFrames,
7958
- estimatedFps: Math.min(60, Math.max(0, estimatedFps)),
7996
+ estimatedFps: clampedFps,
7959
7997
  maxFrameTimeMs
7960
7998
  };
7961
7999
  this.onFrameMetrics(event);
@@ -10097,7 +10135,7 @@ function enableDebug(config) {
10097
10135
  journeyEnabled: _journeyConfig.enabled,
10098
10136
  canScreenshot: true,
10099
10137
  navMode: _autoScreenDetector ? "auto" : "beacon",
10100
- sdkVersion: "1.0.0"
10138
+ sdkVersion: SDK_VERSION
10101
10139
  });
10102
10140
  __DEV__ && logger.debug("Emitted journey:debug_ready event to desktop");
10103
10141
  } catch {
@@ -10232,6 +10270,7 @@ var init_bootstrap = __esm({
10232
10270
  "use strict";
10233
10271
  init_transport();
10234
10272
  init_timings();
10273
+ init_version();
10235
10274
  init_stream();
10236
10275
  init_commands();
10237
10276
  init_internalLogger();
@@ -10723,7 +10762,9 @@ var init_EventTracker = __esm({
10723
10762
  "lib/module/analytics/EventTracker.js"() {
10724
10763
  "use strict";
10725
10764
  init_StorageBackend();
10765
+ init_device();
10726
10766
  init_deviceId();
10767
+ init_version();
10727
10768
  init_internalLogger();
10728
10769
  init_nativeCrashBridge();
10729
10770
  init_hmacSha256();
@@ -10752,7 +10793,7 @@ var init_EventTracker = __esm({
10752
10793
  constructor(config) {
10753
10794
  this.storage = createStorageBackend();
10754
10795
  this.cfg = {
10755
- platform: "react_native",
10796
+ platform: resolveEventPlatform(),
10756
10797
  flushIntervalMs: DEFAULT_FLUSH_MS,
10757
10798
  batchSize: DEFAULT_BATCH,
10758
10799
  autoLifecycleEvents: true,
@@ -10978,7 +11019,7 @@ var init_EventTracker = __esm({
10978
11019
  event_name: eventName,
10979
11020
  event_time: Date.now(),
10980
11021
  app_id: this.cfg.appId,
10981
- platform: this.cfg.platform ?? "react_native",
11022
+ platform: this.cfg.platform ?? resolveEventPlatform(),
10982
11023
  installation_id: this.installationId,
10983
11024
  anonymous_id: this.anonymousId,
10984
11025
  session_id: canonicalSessionId || this.sessionId,
@@ -10989,7 +11030,7 @@ var init_EventTracker = __esm({
10989
11030
  ...properties ?? {}
10990
11031
  },
10991
11032
  context: {
10992
- sdk_version: ctx.sdk_version ?? "0.1.0",
11033
+ sdk_version: ctx.sdk_version ?? SDK_VERSION,
10993
11034
  ...ctx
10994
11035
  }
10995
11036
  };
@@ -12715,6 +12756,7 @@ var init_journeyManager = __esm({
12715
12756
  "use strict";
12716
12757
  init_journeyTypes();
12717
12758
  init_gestureBuffer();
12759
+ init_version();
12718
12760
  init_gestureDetector();
12719
12761
  init_navDetector();
12720
12762
  init_screenshotHelper();
@@ -13071,7 +13113,7 @@ var init_journeyManager = __esm({
13071
13113
  journeyEnabled: this.config.enabled,
13072
13114
  canScreenshot: this.screenshotHelper.canCapture,
13073
13115
  navMode: this.navDetector.navMode,
13074
- sdkVersion: "0.1.0"
13116
+ sdkVersion: SDK_VERSION
13075
13117
  };
13076
13118
  this._emitEvent(JOURNEY_EVENTS.DEBUG_READY, payload);
13077
13119
  }
@@ -17014,6 +17056,10 @@ function isSessionLaneEvent(name) {
17014
17056
  function resolveEventLane(name) {
17015
17057
  return isSessionLaneEvent(name) ? "session" : "analytics";
17016
17058
  }
17059
+ var INTERNAL_ONLY_SIGNALS = /* @__PURE__ */ new Set(["$network_request"]);
17060
+ function isUploadedSessionEvent(name) {
17061
+ return !INTERNAL_ONLY_SIGNALS.has(name);
17062
+ }
17017
17063
 
17018
17064
  // lib/module/config/ConfigManager.js
17019
17065
  init_StorageBackend();
@@ -19498,7 +19544,8 @@ var ScaleBunFacade = class {
19498
19544
  appId,
19499
19545
  clientKey,
19500
19546
  apiBaseUrl,
19501
- platform: rawConfig?.platform ?? "react_native",
19547
+ // Auto-detected (Platform.OS) unless the integration overrides it — see resolveEventPlatform.
19548
+ platform: rawConfig?.platform ?? resolveEventPlatform(),
19502
19549
  appVersion: rawConfig?.appVersion,
19503
19550
  osVersion: rawConfig?.osVersion,
19504
19551
  autoLifecycleEvents: rawConfig?.autoLifecycleEvents !== false,
@@ -20308,7 +20355,8 @@ var ScaleBunFacade = class {
20308
20355
  __DEV__ && logger.debug("Tracking event:", name);
20309
20356
  engageSignals.emit(name, payload);
20310
20357
  const adapter = SessionManager.getExistingInstance()?.getBackendTransport();
20311
- if (this._clientKey && adapter) {
20358
+ if (!isUploadedSessionEvent(name)) {
20359
+ } else if (this._clientKey && adapter) {
20312
20360
  adapter.trackEvent({
20313
20361
  eventId: generateEventId(),
20314
20362
  sessionId: adapter.analyticsSessionId ?? "",